+ {/* Pinned beside the group header row, so content above the list never covers it. */}
+
+
+
+
+
+
+
{/* Index keeps group subtrees mounted when the group arrays are
rebuilt, so store updates cannot recreate rows mid-gesture. */}
diff --git a/packages/gui-plugins/README.md b/packages/gui-plugins/README.md
index d3a685c55af..deb491cd28d 100644
--- a/packages/gui-plugins/README.md
+++ b/packages/gui-plugins/README.md
@@ -252,28 +252,32 @@ SDK icon fields take an `IconName` from `@opencode/plugin/gui`: the names of the
### Registries
-| Registry | Process | What an item is |
-| ---------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| [`Command`](../plugin/src/gui/registries.ts) | window | A palette command with an optional keybind and slash command |
-| [`MenuItem`](../plugin/src/gui/registries.ts) | window | An item of a host menu: the side panel + menu, Add server, a server row |
-| [`Panel`](../plugin/src/gui/registries.ts) | window | Tabs in the session's side region |
-| [`SettingsPage`](../plugin/src/gui/registries.ts) | window | A settings page, a section on a host page, or rows in a host section |
-| [`Server`](../plugin/src/gui/registries.ts) | window | A source of servers, such as SSH hosts |
-| [`LinkHandler`](../plugin/src/gui/registries.ts) | window | Opens local links, such as file paths in messages, and says whether their target exists |
-| [`TitlebarItem`](../plugin/src/gui/registries.ts) | window | A pill in the titlebar or the tabs footer |
-| [`ComposerPill`](../plugin/src/gui/registries.ts) | window | A pill in the row above a session's composer, optionally opening a menu of rows or a popover of your own content |
-| [`CodeBlock`](../plugin/src/gui/registries.ts) | window | Your UI in place of the highlighted code of complete fenced code blocks of the languages you list, such as a diagram or a table |
-| [`CodeBlockAction`](../plugin/src/gui/registries.ts) | window | A button beside the Copy button of complete fenced code blocks of the languages you list, such as "Run in terminal" |
-| [`Slot`](../plugin/src/gui/registries.ts) | window | Content for `window.bottom`, `session.header`, `session.location.menu`, `session.panel.end`; built-ins also fill `session.location.workspace`, `session.location.branch.menu` and `session.location.path.menu` through `BuiltinSlot` |
-| [`Style`](../plugin/src/gui/registries.ts) | window | CSS imported with `?inline` |
-| [`Theme`](../plugin/src/gui/registries.ts) | window | A color theme in the app's theme file format, listed in Settings › Appearance › Theme |
-| [`MenubarItem`](../plugin/src/gui/main.ts) | main | An item of the native app menu |
+| Registry | Process | What an item is |
+| ---------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [`Command`](../plugin/src/gui/registries.ts) | window | A palette command with an optional keybind and slash command |
+| [`MenuItem`](../plugin/src/gui/registries.ts) | window | An item of a host menu: the side panel + menu, Add server, a server row |
+| [`Panel`](../plugin/src/gui/registries.ts) | window | Tabs in the session's side region |
+| [`SettingsPage`](../plugin/src/gui/registries.ts) | window | A settings page, a section on a host page, or rows in a host section |
+| [`Server`](../plugin/src/gui/registries.ts) | window | A source of servers, such as SSH hosts |
+| [`LinkHandler`](../plugin/src/gui/registries.ts) | window | Opens local links, such as file paths in messages, and says whether their target exists |
+| [`TitlebarItem`](../plugin/src/gui/registries.ts) | window | A pill in the titlebar or the tabs footer |
+| [`ComposerPill`](../plugin/src/gui/registries.ts) | window | A pill in the row above a session's composer, optionally opening a menu of rows or a popover of your own content |
+| [`CodeBlock`](../plugin/src/gui/registries.ts) | window | Your UI in place of the highlighted code of complete fenced code blocks of the languages you list, such as a diagram or a table |
+| [`CodeBlockAction`](../plugin/src/gui/registries.ts) | window | A button beside the Copy button of complete fenced code blocks of the languages you list, such as "Run in terminal" |
+| [`Slot`](../plugin/src/gui/registries.ts) | window | Content for `window.bottom`, `session.header`, `session.location.menu`, `session.panel.end`, `home.main`; built-ins also fill `session.location.workspace`, `session.location.branch.menu` and `session.location.path.menu` through `BuiltinSlot` |
+| [`Style`](../plugin/src/gui/registries.ts) | window | CSS imported with `?inline` |
+| [`Theme`](../plugin/src/gui/registries.ts) | window | A color theme in the app's theme file format, listed in Settings › Appearance › Theme |
+| [`MenubarItem`](../plugin/src/gui/main.ts) | main | An item of the native app menu |
`session.location.menu` contributes items after the project menu's location details. It receives the owning `screen`,
the live `session`, and `shown`; keep data subscriptions active only while `shown` is true. Loading headers without an
owning screen show the host's location details without this slot. Render its rows with `ctx.ui.MenuItem`,
`ctx.ui.MenuSub`, `ctx.ui.MenuGroup` and `ctx.ui.MenuSeparator`, so they navigate and close like the host's rows.
+`home.main` renders in Home's main column, between the session search and the session list, before any session is
+open. It receives no `screen` or `session`: only the `server` Home shows (a `ServerRef.id` for `ctx.servers.get`) and
+the project `directory` it filters to, undefined for every project. It takes no room while nothing renders into it.
+
`session.location.branch.menu` (built-ins only, through `BuiltinSlot`) contributes items after Copy branch name in
the branch submenu, with the same `screen`, live `session`, and project-menu `shown` context. It renders only when a
branch name and owning screen are available. Use it for actions on the branch's working directory, such as opening
diff --git a/packages/plugin/src/gui/registries.ts b/packages/plugin/src/gui/registries.ts
index 09481f4dabf..bb4e19b1cff 100644
--- a/packages/plugin/src/gui/registries.ts
+++ b/packages/plugin/src/gui/registries.ts
@@ -897,6 +897,21 @@ export interface SlotMap {
/** The routed session; a new object when another session is routed. */
readonly session: MountedSession
}
+ /**
+ * Home's main column, between the session search and the session list, before any session is open: onboarding, a
+ * dashboard card, help or a status summary. It renders while Home shows a server's sessions, whether they load, fail
+ * or are empty. It spans the column's width at every window size and scrolls away with the list. Contributions stack in `order` with a small gap, and the slot takes no room while none renders anything.
+ * The fields are reactive getters: read them where you use them.
+ */
+ readonly "home.main": {
+ /**
+ * The `ServerRef.id` of the server Home shows; read its ref with `ctx.servers.get`. Changes without a remount when
+ * the user picks another server.
+ */
+ readonly server: string
+ /** The root directory of the project Home filters its sessions to; undefined while Home lists every project. */
+ readonly directory: string | undefined
+ }
}
/** Content for one of the host's slots, typed by `at`. */
diff --git a/services/www/src/docs/content/build/plugins/gui/index.mdx b/services/www/src/docs/content/build/plugins/gui/index.mdx
index 4adbbfacd92..73fac726fa4 100644
--- a/services/www/src/docs/content/build/plugins/gui/index.mdx
+++ b/services/www/src/docs/content/build/plugins/gui/index.mdx
@@ -996,7 +996,7 @@ interface SettingEntry {
### Slots
-`Slot` renders UI into one of four window slots.
+`Slot` renders UI into one of the window's slots.
```tsx
import { Slot } from "@opencode/plugin/gui"
@@ -1013,6 +1013,7 @@ ctx.add(Slot, {
`false`.
- `session.location.menu` adds items to the project menu, after its location details.
- `session.panel.end` holds actions at the trailing end of the side region's tab strip.
+- `home.main` is Home's main column, between the session search and the session list. It takes no room while empty.
- `order` sorts the items in one slot.
`session.location.menu` receives `shown`, which is `true` while the project menu is open. Subscribe to location data
@@ -1035,6 +1036,16 @@ ctx.add(Slot, {
})
```
+`home.main` shows content before a session is open, such as onboarding or a dashboard card. It receives the `server`
+Home shows, as a `ServerRef.id`, and the project `directory` it filters to, or `undefined` for every project:
+
+```tsx
+ctx.add(Slot, {
+ at: "home.main",
+ render: (input) => ,
+})
+```
+
#### Reference
```ts
@@ -1047,6 +1058,7 @@ interface SlotMap {
"session.header": { screen: SessionScreen; session: MountedSession; active: boolean }
"session.location.menu": { screen: SessionScreen; session: MountedSession; shown: boolean }
"session.panel.end": { screen: SessionScreen; session: MountedSession }
+ "home.main": { server: string; directory: string | undefined }
}
```