Changeset 0.21.3 (#89)

This commit is contained in:
2026-03-01 18:20:01 +00:00
parent c5159538ce
commit bbbbe65bfa
10 changed files with 1098 additions and 23 deletions

View File

@@ -300,28 +300,36 @@ tools. The editor extension defines `read_file`, `write_file`,
## 6. Surfaces (Modes)
*Implemented in v0.21.3.*
A "mode" is an extension that registers a **surface** — a UI region that
replaces or augments the default chat area.
replaces or augments the default chat area. The surface system preserves
DOM state across mode switches (critical for CM6 editor instances).
### 6.1 Surface Regions
The following `data-surface-region` attributes are present in `index.html`:
```
┌─────────────────────────────────────────────┐
│ sidebar-top │ surface-header │
│ │ (model-bar) │
│ mode-selector │ │
│ (auto-shown │ surface-main │
│ when ≥2 │ (chatMessages) │
│ surfaces) │ │
│ │ │
│ sidebar-nav │
│ (mode selector) │ surface-main
│ │ (chat, editor, article, │
│ sidebar-content │ cluster, ...) │
│ (context panel) │ │
│ sidebar-content │ surface-footer
│ (search+chats) (input-area)
│ │ │
│ sidebar-bottom │ surface-footer
│ │ (input area) │
│ sidebar-bottom │
└─────────────────────────────────────────────┘
```
### 6.2 Surface Registration
**Manifest-based** (planned — extension loader integration):
```json
{
"surfaces": [
@@ -336,11 +344,16 @@ replaces or augments the default chat area.
}
```
**Imperative** (implemented):
```js
Extensions.register({
id: 'editor-mode',
init(ctx) {
ctx.surfaces.register('editor', {
label: 'Editor',
icon: 'code',
regions: ['surface-main', 'surface-footer', 'sidebar-content'],
activate() {
ctx.ui.replace('surface-main', this.renderEditor());
ctx.ui.replace('surface-footer', this.renderEditorInput());
@@ -356,12 +369,35 @@ Extensions.register({
});
```
**Region management API** (on `ctx.ui`):
- `ctx.ui.replace(regionId, element)` — saves current children to a
`DocumentFragment` (detached, not destroyed), inserts new element.
- `ctx.ui.restore(regionId)` — re-attaches saved children.
This is critical for CM6 — editor instances survive mode switches because
their DOM nodes are detached (preserving internal state) rather than removed.
**Surface management API** (on `ctx.surfaces`):
- `ctx.surfaces.register(id, opts)` — register a new surface
- `ctx.surfaces.unregister(id)` — unregister (switches to chat if active)
- `ctx.surfaces.activate(id)` — switch to a surface
- `ctx.surfaces.getCurrent()` — returns active surface id
### 6.3 Mode Selector
When extensions register surfaces, a mode selector appears in the sidebar.
Clicking a mode calls `activate()` on that surface and `deactivate()` on
the current one. The bus event `surface.activated` fires so other
extensions can react.
When extensions register surfaces, a mode selector appears in the sidebar
(`#modeSelectorWrap`) below the brand/new-chat area. Clicking a mode calls
`activate()` on that surface and `deactivate()` on the current one.
Events fired:
```js
Events.on('surface.activated', ({ surface, previous }) => { ... });
Events.on('surface.deactivated', ({ surface }) => { ... });
Events.on('surface.registered', ({ surface }) => { ... });
Events.on('surface.unregistered', ({ surface }) => { ... });
```
### 6.4 Core Surface