@pstdio/workbench 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +100 -88
  2. package/dist/context-key-service-W4QEfVdN.js +1031 -0
  3. package/dist/context-key-service-W4QEfVdN.js.map +1 -0
  4. package/dist/extensions.d.ts +739 -275
  5. package/dist/extensions.js +891 -699
  6. package/dist/extensions.js.map +1 -1
  7. package/dist/file-renderer-view-DrrhYnb_.js.map +1 -1
  8. package/dist/index.d.ts +746 -448
  9. package/dist/index.js +2974 -60
  10. package/dist/index.js.map +1 -1
  11. package/dist/layout-types-DMoZz38-.js +100 -0
  12. package/dist/layout-types-DMoZz38-.js.map +1 -0
  13. package/dist/react.d.ts +735 -231
  14. package/dist/react.js +3562 -2584
  15. package/dist/react.js.map +1 -1
  16. package/dist/storage.d.ts +109 -14
  17. package/dist/storage.js +142 -47
  18. package/dist/storage.js.map +1 -1
  19. package/dist/surface-map-C1pOTUmF.js +52 -0
  20. package/dist/surface-map-C1pOTUmF.js.map +1 -0
  21. package/dist/testing.d.ts +685 -198
  22. package/dist/testing.js +46 -34
  23. package/dist/testing.js.map +1 -1
  24. package/dist/webview-runtime.js +5 -1
  25. package/dist/webview-runtime.js.map +1 -1
  26. package/dist/workbench-menu-paths-B_QJzcNU.js +12 -0
  27. package/dist/workbench-menu-paths-B_QJzcNU.js.map +1 -0
  28. package/package.json +6 -7
  29. package/dist/context-key-service-C--cHa0B.js +0 -447
  30. package/dist/context-key-service-C--cHa0B.js.map +0 -1
  31. package/dist/core.d.ts +0 -1885
  32. package/dist/core.js +0 -64
  33. package/dist/core.js.map +0 -1
  34. package/dist/surface-reconcile-DkRf01ro.js +0 -260
  35. package/dist/surface-reconcile-DkRf01ro.js.map +0 -1
  36. package/dist/workbench-core-DFpwi8Lo.js +0 -2264
  37. package/dist/workbench-core-DFpwi8Lo.js.map +0 -1
  38. package/dist/workbench-menu-paths-CQVH6z4_.js +0 -11
  39. package/dist/workbench-menu-paths-CQVH6z4_.js.map +0 -1
package/README.md CHANGED
@@ -6,54 +6,54 @@
6
6
 
7
7
  - **Core**: the headless workbench model created by `createWorkbenchCore()`. It owns registries, controllers, and shared state.
8
8
  - **Workbench**: the React shell rendered by `Workbench`. It reads the core and turns registered contributions into visible UI.
9
- - **Module**: an owner for related contributions. Modules register against the core and their contributions are disposed together. See [Contribution Ownership](../../.pstdio/docs/references/workbench/contribution-ownership.md).
10
- - **Registry**: a typed collection of contributions, such as widgets, tree views, commands, menus, resources, and renderers.
9
+ - **Module**: an owner for related contributions. Modules register against the core and their contributions are disposed together. See [Contribution Ownership](https://github.com/pufflyai/prompt-studio/blob/main/.pstdio/docs/references/workbench/contribution-ownership.md).
10
+ - **Registry**: a typed collection of contributions, such as Panels, tree views, commands, menus, resources, and renderers.
11
11
  - **Contribution**: a declarative unit registered by a module. Contributions describe what exists; the workbench decides how to render or route them.
12
12
  - **Controller**: a stateful workbench service, such as breadcrumbs, panels, focus, history, command palette, or the session panel.
13
- - **Area**: a named layout target where widgets can be placed. The workbench owns the chrome around each area.
13
+ - **Region**: a named layout target where Panels can be placed. The workbench owns the chrome around each region.
14
14
  - **Resource**: a typed reference to something the workbench can open or navigate to.
15
15
 
16
16
  ## Contributions
17
17
 
18
- Contributions are the workbench extension points. A module contributes capabilities into the core; the React workbench renders the current state from those contributions. Contributions are grouped by role: layout, views, resources, navigation, and supporting plumbing. Ownership metadata is documented in [Contribution Ownership](../../.pstdio/docs/references/workbench/contribution-ownership.md).
18
+ Contributions are the workbench extension points. A module contributes capabilities into the core; the React workbench renders the current state from those contributions. Contributions are grouped by role: layout, views, resources, navigation, and supporting plumbing. Ownership metadata is documented in [Contribution Ownership](https://github.com/pufflyai/prompt-studio/blob/main/.pstdio/docs/references/workbench/contribution-ownership.md).
19
19
 
20
20
  ## Public Entry Points
21
21
 
22
- - `pstdio-workbench/core` exports the headless workbench core, registries, controllers, and contribution types.
23
- - `pstdio-workbench/react` exports the React shell, view hosts, shared hooks, and `WorkbenchModuleHost` for syncing a dynamic module list into a core.
24
- - `pstdio-workbench/storage` exports local-storage-backed layout and panel persistence adapters for hosts that want browser persistence with a namespace and scope.
22
+ - `@pstdio/workbench` exports the headless workbench core, registries, controllers, and contribution types.
23
+ - `@pstdio/workbench/react` exports the React shell, view hosts, shared hooks, and `WorkbenchModuleHost` for syncing a dynamic module list into a core.
24
+ - `@pstdio/workbench/storage` exports local-storage-backed layout and panel persistence adapters for hosts that want browser persistence with a namespace and scope.
25
25
 
26
26
  ## 🏁 Layout Contributions
27
27
 
28
- Layout contributions are the glue between an area and a view. They declare where a renderer appears in the shell, what config it receives, and how its placements behave — without owning any UI themselves.
28
+ Layout contributions are the glue between a region and a view. They declare where a renderer appears in the shell, what config it receives, and how its placements behave — without owning any UI themselves.
29
29
 
30
- ### Widgets
30
+ ### Panels
31
31
 
32
- Pin a renderer to an area as a panel, editor, dashboard, inspector, status item, or overlay. Widgets declare an `area`, `title`, `rendererId`, optional `resourceKinds`, optional sizing and collapsibility, and renderer-owned `config`. They do not contain render code — the shell looks the `rendererId` up in the renderer registry.
32
+ Pin a renderer to a region as a panel, editor, dashboard, inspector, status item, or overlay. Panels declare a `region`, `title`, `rendererId`, optional `resourceKinds`, optional sizing and collapsibility, and renderer-owned `config`. They do not contain render code — the shell looks the `rendererId` up in the renderer registry.
33
33
 
34
- - Register with `layout.registerWidget()`
35
- - Set `singleton: true` for one placement total, such as a tree, sidebar, or status view.
36
- - Non-singleton widgets default to `reuse: "resource"`: one placement per resource URI, with no-resource opens reusing the widget placement.
34
+ - Register with `layout.registerPanel()`
35
+ - Set `singleton: true` for one placement total, such as a tree, sidenav, or status view.
36
+ - Non-singleton Panels default to `reuse: "resource"`: one placement per resource URI, with no-resource opens reusing the Panel placement.
37
37
  - Set `reuse: "none"` for scratch, untitled, or transient views where every open should create a new placement.
38
38
 
39
39
  #### Examples
40
40
 
41
- - [`hello-world`](src/examples/hello-world/module.tsx) — minimal widget pinned to `main`.
42
- - [`foundation`](src/examples/foundation/module.tsx) — widgets in five different areas all backed by one shared renderer.
41
+ - [`hello-world`](src/examples/hello-world/module.tsx) — minimal Panel pinned to `main`.
42
+ - [`foundation`](src/examples/foundation/module.tsx) — Panels in five different regions all backed by one shared renderer.
43
43
 
44
44
  ### Placeholders
45
45
 
46
- Empty state for areas after every widget in that area closes. Placeholders render through a `rendererId`, can provide area sizing hints, and do not create tabs, placements, or persisted layout entries.
46
+ Empty state for regions after every Panel in that region closes. Placeholders render through a `rendererId`, can provide region sizing hints, and do not create tabs, placements, or persisted layout entries.
47
47
 
48
48
  - Register with `layout.registerPlaceholder()`
49
49
 
50
50
  #### Examples
51
51
 
52
- - [`hello-world`](src/examples/hello-world/module.tsx) — placeholder shown in `main` when the welcome widget is closed.
52
+ - [`hello-world`](src/examples/hello-world/module.tsx) — placeholder shown in `main` when the welcome Panel is closed.
53
53
 
54
54
  ### Menu items
55
55
 
56
- Surface commands in the command palette, area headers, tree context menus, or custom menu paths. Menu items reference existing commands, can be ordered and grouped, and can be gated by context expressions through command/menu metadata.
56
+ Surface commands in the command palette, region headers, tree context menus, or custom menu paths. Menu items reference existing commands, can be ordered and grouped, and can be gated by context expressions through command/menu metadata.
57
57
 
58
58
  - Register with `layout.registerMenuItem(path, item)`
59
59
 
@@ -70,21 +70,21 @@ View contributions are the UI itself — code that turns a placement, a tree nod
70
70
 
71
71
  ### Renderers
72
72
 
73
- The React or bridge implementation for a widget or placeholder. Renderers turn a placement, resource, config, and workbench context into UI. A widget contributes only a `rendererId`, so the same renderer can back many widgets and a renderer can be supplied by a different layer than its widget.
73
+ The React or bridge implementation for a Panel or placeholder. Renderers turn a placement, resource, config, and workbench context into UI. A Panel contributes only a `rendererId`, so the same renderer can back many Panels and a renderer can be supplied by a different layer than its Panel.
74
74
 
75
75
  - Register with `renderers.registerRenderer()`
76
- - Set `keepAlive: true` on the registration to share one persistent subtree across every widget that points at the same `rendererId`. The subtree is mounted once into a stable host that is reparented between widget slots via DOM moves; React state, focus, scroll, and in-flight effects survive area transitions. Kept-alive renderers receive no per-widget input from `render()`; read the active claim with `useWorkbenchClaim()` from `pstdio-workbench/react`.
76
+ - Set `keepAlive: true` on the registration to share one persistent subtree across every Panel that points at the same `rendererId`. The subtree is mounted once into a stable host that is reparented between Panel slots via DOM moves; React state, focus, scroll, and in-flight effects survive region transitions. Kept-alive renderers receive no per-Panel input from `render()`; read the active claim with `useWorkbenchClaim()` from `@pstdio/workbench/react`.
77
77
 
78
78
  #### Examples
79
79
 
80
- - [`hello-world`](src/examples/hello-world/module.tsx) — one renderer per widget, plus a placeholder renderer.
81
- - [`foundation`](src/examples/foundation/module.tsx) — one renderer reused across five widgets in different areas via `config`.
80
+ - [`hello-world`](src/examples/hello-world/module.tsx) — one renderer per Panel, plus a placeholder renderer.
81
+ - [`foundation`](src/examples/foundation/module.tsx) — one renderer reused across five Panels in different regions via `config`.
82
82
  - [`renderer-types`](src/examples/renderer-types/module.tsx) — React and bridge renderers registered side by side.
83
- - [`keep-alive`](src/examples/keep-alive/module.tsx) — keep-alive renderer shared by an attached panel and a floating bubble widget.
83
+ - [`keep-alive`](src/examples/keep-alive/module.tsx) — keep-alive renderer shared by attached and floating Side Panel presentations.
84
84
 
85
85
  ### Tree Renderers
86
86
 
87
- A tree-shaped renderer for side-panel navigation, outlines, resource lists, and contextual hierarchies. Tree renderers expose body sections (`getBody`), optional footer nodes (`getFooter`), and lazy children (`getChildren`); nodes can carry resources, descriptions, inline actions, context menus, and `contextValue`. Placement is left to widgets — a tree renderer auto-registers a widget renderer with the same id, so `layout.registerWidget({ rendererId: <tree id> })` plus `layout.openWidget(<tree id>)` puts the tree in any tree-hosting area.
87
+ A tree-shaped renderer for side-panel navigation, outlines, resource lists, and contextual hierarchies. Tree renderers expose body sections (`getBody`), optional footer nodes (`getFooter`), and lazy children (`getChildren`); nodes can carry resources, descriptions, inline actions, context menus, and `contextValue`. Placement is left to Panels — a tree renderer auto-registers a Panel renderer with the same id, so `layout.registerPanel({ rendererId: <tree id> })` plus `layout.openPanel(<tree id>)` puts the tree in any tree-hosting region.
88
88
 
89
89
  - Register with `renderers.registerTreeRenderer()`
90
90
 
@@ -93,37 +93,50 @@ A tree-shaped renderer for side-panel navigation, outlines, resource lists, and
93
93
  - [`dashboard`](src/examples/dashboard/modules/shell/project-nav.ts) — primary tree with resource-backed nodes, footer entries, and context menus.
94
94
  - [`dynamic-modules`](src/examples/dynamic-modules/modules/explorer-module.tsx) — tree contributed by a module that can be added and removed at runtime.
95
95
 
96
- ### Data Renderers
96
+ ### Kanban Renderers
97
97
 
98
- A Notion/Linear-style data workspace registered as a renderer. Data renderers contribute the schema (tag definitions, grouping/ordering/display options, filter categories), the rows via `executeQuery(state)` (which receives current settings + filters so backends can push filter/sort/pagination down), and row-mutation callbacks. Like tree renderers, a data renderer auto-registers a widget renderer with the same id, so the workspace is placed via `layout.registerWidget({ rendererId: <data renderer id> })` and opened with `layout.openWidget(...)`.
98
+ A Notion/Linear-style data workspace registered as a renderer. Kanban renderers contribute the schema (tag definitions, grouping/ordering/display options, filter categories), the rows via `executeQuery(state)` (which receives current settings + filters so backends can push filter/sort/pagination down), and row-mutation callbacks. Like tree renderers, a kanban renderer auto-registers a Panel renderer with the same id, so the workspace is placed via `layout.registerPanel({ rendererId: <kanban renderer id> })` and opened with `layout.openPanel(...)`.
99
99
 
100
- - Register with `renderers.registerDataRenderer()`
100
+ - Register with `renderers.registerKanbanRenderer()`
101
101
 
102
102
  #### Examples
103
103
 
104
- - [`data-renderer`](src/examples/data-renderer/module.tsx) — focused showcase: schema, mock rows, and renderer-owned controls.
104
+ - [`kanban-renderer`](src/examples/kanban-renderer/module.tsx) — focused showcase: schema, mock rows, and renderer-owned controls.
105
105
  - [`dashboard`](src/examples/dashboard/modules/tickets/collections/ticket-data.ts) — ticket workspace integrated into the dashboard shell.
106
106
 
107
+ ### Data Table Renderers
108
+
109
+ A dense, query-driven table backed by `@pstdio/ui/data-table`. Data table renderers keep row ids and resources outside visible values, support declarative column labels, descriptions, icons, statistics and cell renderers, and use the table's local filtering, sorting, column controls, and pagination. They auto-register a Panel renderer with the same id and can be placed in any workbench region.
110
+
111
+ - Register with `renderers.registerDataTableRenderer()`
112
+ - Refresh with `renderers.refreshDataTableRenderer()` or provide a contribution subscription
113
+ - Extensions contribute `dataTableRenderers` and place them explicitly with `panels.<id>.dataTableRenderer`
114
+
115
+ #### Examples
116
+
117
+ - [`data-table-renderer`](src/examples/data-table-renderer/module.tsx) — service-health table with statistics, color scales, friendly JSON, navigation, and row actions.
118
+
107
119
  ### Breadcrumb (TODO: make it a renderer as well)
108
120
 
109
- `<WorkbenchBreadcrumbView workbench={workbench} />` is the React view that turns the breadcrumb controller state into a rendered trail. It subscribes to `workbench.breadcrumbs.store`, builds `BreadcrumbItem`s from the controller items, and returns `null` when the trail is empty. The default `Workbench` top header renders it automatically; embed it directly when a host renders custom chrome (a main-area header, a tab strip, an embedded panel). Modules drive the trail through `ctx.breadcrumbs.setItems(...)` from resource openers — each call replaces the trail, so the opener fully controls what is shown.
121
+ `<WorkbenchBreadcrumbView workbench={workbench} />` is the React view that turns the breadcrumb controller state into a rendered trail. It subscribes to `workbench.breadcrumbs.store`, builds `BreadcrumbItem`s from the controller items, and returns `null` when the trail is empty. The default `Workbench` renders it in the persistent Nav Chrome; a custom `nav` Panel replaces only that trail area. Panel headers do not own breadcrumbs. Resource navigation drives the trail through `ctx.breadcrumbs.setItems(...)`; each call replaces the trail.
110
122
 
111
- - Render with `<WorkbenchBreadcrumbView workbench={workbench} />` from `pstdio-workbench/react`
112
- - Drive items with `workbench.breadcrumbs.setItems([...])` (typically from a resource opener)
123
+ - Render with `<WorkbenchBreadcrumbView workbench={workbench} />` from `@pstdio/workbench/react`
124
+ - Drive items with `workbench.breadcrumbs.setItems([...])` from the resource navigation controller
125
+ - Set `indicator: "session-status"` when a breadcrumb should show the resource's session completion status
113
126
 
114
127
  #### Examples
115
128
 
116
- - [`dashboard`](src/examples/dashboard/modules/shell/components/dashboard-main-header.tsx) — custom main-area header that places the view alongside workspace controls.
117
- - [`onboarding`](src/examples/onboarding/breadcrumb-module.tsx) — three-level trail set from a page opener.
129
+ - [`dashboard`](src/examples/dashboard/modules/shell/components/dashboard-main-header.tsx) — custom Main Panel header that places the view alongside workspace controls.
130
+ - [`onboarding`](src/examples/onboarding/breadcrumb-module.tsx) — three-level trail synchronized with page navigation.
118
131
 
119
132
  ---
120
133
 
121
- A typical surface combines both layers: a **renderer** supplies the UI, a **widget** places it in an area with optional `config`, and `layout.openWidget()` creates the placement the user actually sees. Pick the narrowest contribution that matches what you are adding:
134
+ A typical surface combines both layers: a **renderer** supplies the UI, a **Panel** places it in a region with optional `config`, and `layout.openPanel()` creates the placement the user actually sees. Pick the narrowest contribution that matches what you are adding:
122
135
 
123
- - Add a **widget** to claim a spot in an area for a renderer.
124
- - Add a **renderer** to supply the React or bridge UI for a widget or placeholder.
125
- - Add a **tree renderer** for navigable hierarchy and resource discovery, and place it with a widget.
126
- - Add a **placeholder** for area-level empty state, not for normal content.
136
+ - Add a **Panel** to claim a spot in a region for a renderer.
137
+ - Add a **renderer** to supply the React or bridge UI for a Panel or placeholder.
138
+ - Add a **tree renderer** for navigable hierarchy and resource discovery, and place it with a Panel.
139
+ - Add a **placeholder** for region-level empty state, not for normal content.
127
140
 
128
141
  ## 🗂️ Resource Contributions
129
142
 
@@ -131,26 +144,26 @@ Resource contributions define typed objects the workbench can open, route, or re
131
144
 
132
145
  ### Resource kinds
133
146
 
134
- Declare typed things the workbench can open. Resource refs carry `kind`, `uri`, optional `id`, labels, icons, and metadata. Resource kinds make navigation, openers, and history speak the same language.
147
+ Declare typed things the workbench can open. Resource refs carry `kind`, `uri`, optional `id`, labels, icons, and metadata. Resource kinds make navigation, presenters, and history speak the same language.
135
148
 
136
149
  - Register with `resources.registerKind()`
137
- - Use the standard icon names for common resources: project `folder-root`, workspace `computer`, worktree `git-pull-request-draft`, ticket `component`, data renderer `square-kanban`, settings `settings`.
150
+ - Use the standard icon names for common resources: project `folder-root`, workspace `computer`, worktree `git-pull-request-draft`, ticket `component`, kanban renderer `square-kanban`, settings `settings`.
138
151
 
139
152
  #### Examples
140
153
 
141
154
  - [`renderer-types`](src/examples/renderer-types/module.tsx) — single-kind module.
142
155
  - [`navigation`](src/examples/navigation/module.tsx) — multiple kinds participating in routing.
143
156
 
144
- ### Resource openers
157
+ ### Resource presenters
145
158
 
146
- Route a resource to a widget placement. Openers declare `canOpen(resource)` and `open(resource, input)`. `openResource()` uses the highest-priority opener, so keep default openers broad and alternate views narrow.
159
+ Map a Resource to the Panel instance that presents it. Presenters declare `canOpen(resource)` and return a Panel from `open(resource, input)`. `openResource()` uses the highest-priority presenter, then establishes the returned Panel as the active Location. Direct `layout.openPanel()` calls display supporting Panels without navigating.
147
160
 
148
- - Register with `resources.registerOpener()`
161
+ - Register with `resources.registerPresenter()`
149
162
 
150
163
  #### Examples
151
164
 
152
- - [`renderer-types`](src/examples/renderer-types/module.tsx) — opener routing one resource kind to one of two widgets.
153
- - [`navigation`](src/examples/navigation/module.tsx) — openers used by parsed navigation targets.
165
+ - [`renderer-types`](src/examples/renderer-types/module.tsx) — presenter routing one resource kind to one of two Panels.
166
+ - [`navigation`](src/examples/navigation/module.tsx) — presenters used by parsed navigation targets.
154
167
 
155
168
  ### Resource providers
156
169
 
@@ -160,7 +173,7 @@ Look up resources by kind, uri, or search input. Providers let features resolve
160
173
 
161
174
  #### Examples
162
175
 
163
- - [`dashboard`](src/examples/dashboard/modules/dashboard.tsx) — provider behind the ticket DataView.
176
+ - [`dashboard`](src/examples/dashboard/modules/dashboard.tsx) — provider behind the ticket KanbanView.
164
177
 
165
178
  ## 🧭 Navigation Contributions
166
179
 
@@ -184,7 +197,7 @@ Custom dispatch behavior for navigation targets. Navigators let modules extend h
184
197
 
185
198
  ## Other Contributions
186
199
 
187
- Supporting contributions make view, layout, resource, and navigation contributions useful. They define actions, persistence, scoping, and preferences without directly owning a workbench area.
200
+ Supporting contributions make view, layout, resource, and navigation contributions useful. They define actions, persistence, scoping, and preferences without directly owning a workbench region.
188
201
 
189
202
  ### Commands
190
203
 
@@ -194,7 +207,7 @@ Any executable workbench action. Commands are the primitive behind menus, keybin
194
207
 
195
208
  #### Examples
196
209
 
197
- - [`hello-world`](src/examples/hello-world/module.tsx) — command that opens a widget.
210
+ - [`hello-world`](src/examples/hello-world/module.tsx) — command that opens a Panel.
198
211
  - [`renderer-types`](src/examples/renderer-types/module.tsx) — commands opening different placements.
199
212
 
200
213
  ### Keybindings
@@ -261,7 +274,7 @@ The React workbench owns the shared `@pstdio/ui` theme preference system through
261
274
 
262
275
  ### Terminal
263
276
 
264
- Terminals are a host-owned workbench surface, not extension-composed chrome. `workbench.terminal` (a core controller) owns the session registry; hosts inject how sessions actually open with `workbench.terminal.setSessionOpener(...)` — a real PTY transport in production, `createScriptedTerminalBridge` from `@pstdio/ui/terminal` in stories and the extension testbench. `createWorkbenchTerminalModule()` registers the terminal panel in the `secondary` area plus the `workbench.terminal.open` command; the panel renders the shared `Terminal` component from `@pstdio/ui/terminal`. Closing the panel kills its session; disposing the controller kills every live session.
277
+ Terminals are a host-owned workbench surface, not extension-composed chrome. `workbench.terminal` (a core controller) owns the session registry; hosts inject how sessions actually open with `workbench.terminal.setSessionOpener(...)` — a real PTY transport in production, `createScriptedTerminalBridge` from `@pstdio/ui/terminal` in stories and the extension testbench. `createWorkbenchTerminalModule()` registers the terminal panel in the `secondary` region plus the `workbench.terminal.open` command; the panel renders the shared `Terminal` component from `@pstdio/ui/terminal`. Closing the panel kills its session; disposing the controller kills every live session.
265
278
 
266
279
  Extension webviews never receive PTY handles. A webview that declares the `terminal.session` capability talks to the same session registry through serializable operations (`open`/`write`/`resize`/`kill`/`subscribe`), with output and exit events pushed over the bridge's host-event channel — `createTerminalSessionBridge(host)` from `@pstdio/sdk/extensions` wraps that protocol into a bridge the `Terminal` component accepts.
267
280
 
@@ -272,7 +285,7 @@ Extension webviews never receive PTY handles. A webview that declares the `termi
272
285
 
273
286
  ---
274
287
 
275
- Register related contributions inside one **workbench module** so they share ownership and disposal. For example, a ticket collection module usually contributes a resource kind, resource opener, widget, renderer, tree renderer, commands, and menu items together.
288
+ Register related contributions inside one **workbench module** so they share ownership and disposal. For example, a ticket collection module usually contributes a resource kind, resource presenter, Panel, renderer, tree renderer, commands, and menu items together.
276
289
 
277
290
  ## Core
278
291
 
@@ -282,62 +295,61 @@ A host normally creates one core, registers modules into it, and renders `<Workb
282
295
  ## Nomenclature
283
296
 
284
297
  - **Workbench core**: the headless object created by `createWorkbenchCore()`. It owns the registries, controllers, and shared workbench state.
285
- - **Registry**: a typed collection of contributions. The workbench has registries for commands, keybindings, resources, layout (widgets, placeholders, menu items), renderers (widget renderers and tree renderers), modes, navigation, notifications, and preferences.
298
+ - **Registry**: a typed collection of contributions. The workbench has registries for commands, keybindings, resources, layout (Panels, placeholders, menu items), renderers (Panel renderers and tree renderers), modes, navigation, notifications, and preferences.
286
299
  - **Controller**: a stateful slice of workbench UX exposed alongside the registries — breadcrumbs, command palette open/close state, focus, history, side-panel open/close state, and session-panel mode.
287
- - **Contribution**: a declarative unit added to a registry, such as a command, menu item, resource kind, widget, renderer, tree renderer, mode, or DataView.
288
- - **Workbench module**: contribution owner registered with `workbench.registerModule(module)` and removed with `workbench.unregisterModule(moduleId)`. Module disposables are tracked and disposed together. See [Contribution Ownership](../../.pstdio/docs/references/workbench/contribution-ownership.md).
300
+ - **Contribution**: a declarative unit added to a registry, such as a command, menu item, resource kind, Panel, renderer, tree renderer, mode, or KanbanView.
301
+ - **Workbench module**: contribution owner registered with `workbench.registerModule(module)` and removed with `workbench.unregisterModule(moduleId)`. Module disposables are tracked and disposed together. See [Contribution Ownership](https://github.com/pufflyai/prompt-studio/blob/main/.pstdio/docs/references/workbench/contribution-ownership.md).
289
302
  - **Runtime extension**: extension metadata from `pstdio-extensions` that a host maps into workbench modules at the trust boundary.
290
- - **Workbench**: the React frame rendered by `Workbench`. It arranges the workbench areas, command palette, side panels, and session panel from the workbench core only.
291
- - **Area**: a named layout target. See the Areas Overview table below.
292
- - **Widget contribution**: a registered view definition in the layout registry. Widgets declare an area, a `rendererId`, and optional renderer-owned `config`.
293
- - **Widget placement**: an opened instance of a widget contribution in an area. Placements track active widget, resource URI, title, pinned/closable flags, and placement ownership.
294
- - **Tree renderer contribution**: a tree-shaped renderer registered under `renderers`. Provides `getBody` (sectioned body), optional `getFooter` (flat footer node list), and `getChildren` (lazy children). Auto-registers a widget renderer with the same id so widgets place trees through `layout.registerWidget`.
295
- - **Data renderer contribution**: a data-workspace renderer registered under `renderers`. Provides a schema, `executeQuery(state)` rows, and row-mutation callbacks. Auto-registers a widget renderer with the same id so widgets place the workspace through `layout.registerWidget`. The presentational layer is `<DataRenderer>` from `@pstdio/ui`.
296
- - **Placeholder**: an empty-state contribution rendered only when an area has no widget placements. Placeholders do not appear in tabs.
297
- - **Renderer**: code that turns a widget placement into UI. The widget host looks up `rendererId` in `workbench.renderers` and inserts the returned React node.
303
+ - **Workbench**: the React frame rendered by `Workbench`. It arranges the workbench regions, command palette, panels, and session surface from the workbench core only.
304
+ - **Region**: a named layout target. See the Regions Overview table below.
305
+ - **Panel contribution**: a registered view definition in the layout registry. Panels declare a region, a `rendererId`, and optional renderer-owned `config`.
306
+ - **Panel placement**: an opened instance of a Panel contribution in a region. Placements track active Panel, resource URI, title, pinned/closable flags, and placement ownership.
307
+ - **Tree renderer contribution**: a tree-shaped renderer registered under `renderers`. Provides `getBody` (sectioned body), optional `getFooter` (flat footer node list), and `getChildren` (lazy children). Auto-registers a Panel renderer with the same id so Panels place trees through `layout.registerPanel`.
308
+ - **Kanban renderer contribution**: a data-workspace renderer registered under `renderers`. Provides a schema, `executeQuery(state)` rows, and row-mutation callbacks. Auto-registers a Panel renderer with the same id so Panels place the workspace through `layout.registerPanel`. The presentational layer is `<KanbanRenderer>` from `@pstdio/ui`.
309
+ - **Data table renderer contribution**: a dense table renderer registered under `renderers`. Provides query rows, optional column descriptors, navigation, and row actions. Extensions place it through a native view; the presentational layer is `<DataTable>` from `@pstdio/ui/data-table`.
310
+ - **Placeholder**: an empty-state contribution rendered only when a region has no Panel placements. Placeholders do not appear in tabs.
311
+ - **Renderer**: code that turns a Panel placement into UI. The Panel host looks up `rendererId` in `workbench.renderers` and inserts the returned React node.
298
312
  - **Resource**: a typed object reference with `kind`, `id`, `uri`, and label metadata.
299
- - **Resource opener**: routing logic that maps a resource to a widget placement.
313
+ - **Resource presenter**: routing logic that maps a resource to a Panel placement.
300
314
  - **Command**: an executable action registered in the command registry. Errors raised during execution emit `workbench.commands.onDidExecuteError`.
301
- - **Menu path**: a stable location where commands are surfaced, such as the command palette, an area header, or a tree node context menu.
315
+ - **Menu path**: a stable location where commands are surfaced, such as the command palette, a region header, or a tree node context menu.
302
316
  - **Keybinding**: a keyboard shortcut bound to a command, optionally gated by a context expression.
303
317
  - **Context key**: boolean or scalar workbench state used by commands, menus, and keybindings to decide when they are active.
304
318
  - **Preference schema**: typed settings contributed by workbench modules or runtime extensions.
305
319
  - **Mode**: a named bundle of temporary contributions activated through `workbench.modes`. Switching modes disposes the previous mode's activation result.
306
320
  - **Tree view section**: a group of nodes inside a tree renderer's `getBody`, with an optional label, optional collapsible flag, and inline actions.
307
321
  - **Notification**: a transient workbench message emitted by workbench modules or extensions. Notifications can include command-backed actions and are rendered as workbench toast chrome.
308
- - **Session panel**: the assistant surface controlled by `workbench.sessionPanel`. It can be `attached`, `bubble`, or `closed`, and is rendered from the `floating` area.
322
+ - **Side Panel**: the project-owned carry surface controlled by `workbench.sidePanel`. It can be `attached`, `floating`, or `closed` while preserving one live host and its resource binding.
309
323
 
310
- ## Areas Overview
324
+ ## Regions Overview
311
325
 
312
- Workbench areas are named layout targets used by widget contributions. They describe where a widget belongs in the workbench; the workbench decides the exact chrome, tabs, resize handles, and visibility behavior.
326
+ Workbench regions are named layout targets used by Panel contributions. They describe where a Panel belongs in the workbench; the workbench decides the exact chrome, tabs, resize handles, and visibility behavior.
313
327
 
314
- Use `layout.registerPlaceholder()` for an area empty state that should render only after all widgets in that area close. Placeholders are not widget placements, so they do not affect tab lists.
328
+ Use `layout.registerPlaceholder()` for a region empty state that should render only after all Panels in that region close. Placeholders are not Panel placements, so they do not affect tab lists.
315
329
 
316
- Most panels are paired with a `<panel>-header` area that the workbench renders directly above the panel. Widgets placed in a header area use a bottom border by default. Set `headerBorderBottom: false` on a widget contribution to let that widget own the header separation.
330
+ Panels with tabs are paired with a `<panel>-header` region that the workbench renders directly above the panel. Panels placed in a header region use a bottom border by default. Set `headerBorderBottom: false` on a Panel contribution to let that Panel own the header separation.
317
331
 
318
- | Area | Workbench location | Typical use |
319
- | -------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------ |
320
- | `top` | Top of the workbench, right of `activityBar` and `left` | Breadcrumbs, active context, compact global controls, left-panel reopen action |
321
- | `activityBar` | Narrow rail on the far left | Top-level mode or workspace switching |
322
- | `left-header` | Header above `left` | Project brand, primary navigation header actions |
323
- | `left` | Primary left side panel | Navigation trees, registries, project outlines, resource lists |
324
- | `main-header` | Header above `main`, `main-left`, `main-right` | Active editor context, compact main controls, panel reopen actions |
325
- | `main-left-header` | Header above `main-left` | Secondary navigation header |
326
- | `main-left` | Resizable panel to the left of `main` | Per-mode navigation trees (settings, document outlines) |
327
- | `main` | Central content region | Editors, detail pages, dashboards, primary resource views |
328
- | `main-right-header` | Header above `main-right` | Inspector controls, contextual filters |
329
- | `main-right` | Resizable panel to the right of `main` | Inspectors, properties, contextual details |
330
- | `main-bottom-header` | Header above `main-bottom` | Tab strips, log filters |
331
- | `main-bottom` | Resizable panel below `main`, `main-left`, `main-right` | Diagnostics, activity, logs, terminals, background task output |
332
- | `status` | Bottom status strip | Compact state, counters, sync status, environment indicators |
333
- | `overlay` | Layer above the workbench | Modal flows, blocking prompts, transient overlays |
334
- | `floating-header` | Header of the session panel | Session-panel title, mode toggle |
335
- | `floating` | Session panel surface | Assistant or session UI, either attached or floating |
332
+ | Region | Workbench location | Typical use |
333
+ | ------------------ | -------------------------------------------- | ------------------------------------------------------------- |
334
+ | `nav` | Nav Chrome across the resource-owned column | Project selector, breadcrumbs, history, resource actions, region controls |
335
+ | `activity` | Optional rail on the leading edge | Top-level mode or workspace switching |
336
+ | `sidenav-header` | Optional header above `sidenav` | Sidenav-local controls that must sit above its scrolling content |
337
+ | `sidenav` | Leading Sidenav | Navigation trees, registries, outlines, resource lists |
338
+ | `main-header` | Header above the Main Panel | Main Panel tabs and controls |
339
+ | `main-left-menu` | Menu inside the Main Panel's leading edge | Contextual navigation and document outlines |
340
+ | `main` | Central Main Panel | Editors, detail pages, dashboards, primary resource views |
341
+ | `main-right-menu` | Menu inside the Main Panel's trailing edge | Inspectors, properties, and contextual details |
342
+ | `secondary-header` | Header above the Secondary Panel | Tabs, add-panel controls, and collapsed-menu controls |
343
+ | `secondary` | Secondary Panel below the Main Panel | Diagnostics, activity, logs, terminals, background task output |
344
+ | `side-header` | Header above the Side Panel | Session tabs and Side Panel controls |
345
+ | `side` | Full-height Side Panel | Assistant sessions and independent secondary workflows |
346
+ | `status` | Full-width Status Bar at the viewport bottom | Compact state, counters, sync status, environment indicators |
347
+ | `overlay` | Layer above the workbench | Modal flows, blocking prompts, transient overlays |
336
348
 
337
- The command palette, toast notifications, and resize handles are workbench chrome, not workbench areas. Use the `AreaMap` Storybook story to see the current area placement rendered through the real `Workbench`.
349
+ The command palette, toast notifications, and resize handles are workbench chrome, not workbench regions. Use the `RegionMap` Storybook story to see the current region placement rendered through the real `Workbench`.
338
350
 
339
351
  ## Header Actions
340
352
 
341
- Each area header renders command-backed actions from two menu paths derived from `headerLeadingMenuPath(area)` and `headerTrailingMenuPath(area)`. The top header reuses these paths under `workbenchTopHeaderLeadingMenuPath` and `workbenchTopHeaderTrailingMenuPath`. Workbench modules can register commands and add menu actions to those paths to expose compact header controls while keeping breadcrumbs and the `top` area as workbench-owned chrome.
353
+ Each region header renders command-backed actions from two menu paths derived from `headerLeadingMenuPath(region)` and `headerTrailingMenuPath(region)`. Nav Chrome reuses these paths under `workbenchTopHeaderLeadingMenuPath` and `workbenchTopHeaderTrailingMenuPath`. It keeps history, the breadcrumb trail, the trailing breadcrumb-action slot, and Sidenav/Secondary/Side visibility controls mounted in that order. Workbench modules can register commands and add menu actions to those paths without moving navigation into a Panel Header.
342
354
 
343
355
  Runtime extensions should only target documented public slots through descriptors; hosts map those descriptors into workbench modules instead of giving extension packages direct workbench access.