Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
4f5b717
fix(isolation): treat Kimi Code's KIMI_CODE_HOME as Kimi's own home
BIackFIame Oct 22, 2026
ed4f2b4
fix(runtime): give Grok and Kimi cards in a contributed home their st…
BIackFIame Oct 22, 2026
60714a7
fix(opencode): bring a subagent's shell ask to the person, never to i…
BIackFIame Oct 22, 2026
78ff159
fix(orchestration): an orchestrator's control connection never answer…
BIackFIame Oct 22, 2026
dc63889
fix(ui): scale the card menu, hints panel and plugin settings with th…
BIackFIame Oct 22, 2026
1518cd5
fix(i18n): finish the Russian canvas hints and format their key caps …
BIackFIame Oct 22, 2026
5560f89
fix(github): report a timed-out profile request as a failed sign-in
BIackFIame Oct 22, 2026
200b697
fix(github): retry HTTP 429/5xx token answers that carry an OAuth err…
BIackFIame Oct 22, 2026
028b5d0
test: wait for the click's navigation in the engine-tabs click test
BIackFIame Oct 22, 2026
93cc2bb
test: ignore the checkout path in the session store's secret-word check
BIackFIame Oct 22, 2026
47b5535
fix(agents): keep ambient admin keys from agents and credentials from…
BIackFIame Oct 22, 2026
fc434b3
fix(opencode): send OpenCode's file tools to decisions in Claude Code…
BIackFIame Oct 22, 2026
ff5358c
fix(ui): say what is used and what is left in HOME limit rows
BIackFIame Oct 25, 2026
3690281
fix(plugins): say when a plugin's native code or module is off, with …
BIackFIame Oct 25, 2026
b06a15c
fix(github): cancel device sign-in and report denied, expired and fai…
BIackFIame Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions agent/orchestrator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A session started from CanvasTTY's launcher with the **Orchestrator** role has t

1. `list_providers`: which agents CanvasTTY can launch here. Each entry's `id` is the exact `spawn_agent.provider` value; prefer entries that are `available` with `signIn: "ok"` (`unknown` only means CanvasTTY has not checked yet). When plugins offer launch options (for example an accounts plugin's `list_routes` tool), the answer names that tool.
2. `spawn_agent` once per part of the task: a known `provider` id, an absolute `cwd` and a self-contained prompt. An unknown provider is refused with a pointer back to `list_providers`. **If the person names a model, pass it as `model`** in the format `list_providers` gives for that provider (`model.format`; OpenCode takes `provider/model`, for example `zai-coding-plan/glm-5.3-flash`, and `model.known` lists what `opencode models` reported); without `model` the CLI uses its own default. `effort` sets the reasoning effort where the CLI has one (`efforts`). Without `profile` the subagent gets your own launch profile, or the next lower one its CLI has (never more than yours, never YOLO); `list_providers` shows each provider's `profiles`. `cwd` must be this project's folder or a folder inside it. A refusal says why (a folder outside the project, a profile above yours, a limit the person set): change the request, do not retry it.
3. `wait_for_agent` for each subagent (`timeoutSeconds` up to 600; call it again after `timeout`) instead of polling. `needs_approval` means the person must answer a prompt in that card: never answer it yourself.
3. `wait_for_agent` for each subagent (`timeoutSeconds` up to 600; call it again after `timeout`) instead of polling. `needs_approval` means the person must answer a prompt in that card (`output` shows it, for example a shell command): never answer it yourself, and `send_to_agent` is refused meanwhile. Tell the person what it asks, then call `wait_for_agent` again: it waits for their answer.
4. `get_agent_result` to read what the subagent produced; check the actual files before reporting success.

Do not explore the filesystem, `PATH` or config folders (for example `~/.local/bin` or `~/.config/<cli>`) looking for agents or their configuration: `list_providers` is what CanvasTTY can launch, and delegation goes through `spawn_agent`.
Expand All @@ -32,10 +32,10 @@ Use the bundled `canvastty-control.mjs` CLI with a running CanvasTTY instance wh

Run `providers` first to see which providers are installed and signed in. If the person names a model, add `--model <id>` (OpenCode: `provider/model`); `--effort <level>` works for Codex, Claude and Grok.

`--provider` accepts codex, claude, qwen, kimi, opencode, hermes, grok, omp and pi; each worker uses that provider's own normal/YOLO launch flags. The create response includes `capabilities`: only Codex workers have `result: true` (captured final answer) and `menus: true` (startup/approval menus that `choose`/`dismiss` can act on). For other providers, `result` ends as `no_result` and menus must be resolved by the user; treat their `screen` text as the only evidence. From the person's own terminal CLI creation defaults to YOLO, using the provider's full-access, no-approval launch flag; inside an Orchestrator session it defaults to that session's profile. It does not change global provider settings. `--profile normal` is available when the user requests their ordinary configured profile; do not silently replace their selected permissions.
`--provider` accepts codex, claude, qwen, kimi, opencode, hermes, grok, omp and pi; each worker uses that provider's own normal/YOLO launch flags. The create response includes `capabilities`: only Codex workers have `result: true` (captured final answer) and `menus: true` (startup menus that `choose`/`dismiss` can act on). For other providers, `result` ends as `no_result` and menus must be resolved by the user; treat their `screen` text as the only evidence. From the person's own terminal CLI creation defaults to YOLO, using the provider's full-access, no-approval launch flag; inside an Orchestrator session it defaults to that session's profile. It does not change global provider settings. `--profile normal` is available when the user requests their ordinary configured profile; do not silently replace their selected permissions.
4. Save the returned session ID and request ID. Verify provider, profile, cwd and launch status. A returned ID or an idle status alone does not prove a working agent.
5. Inspect `screen <id>` until the worker is at an empty composer (verified automatically for Codex; for other providers judge from the screen text). Trust, authentication, permission menus and startup failures are not task prompts. Do not submit a task to dismiss them.
6. Resolve only reviewed, authorized menu actions: `choose <id> --choice <observed-number> --revision <interaction.revision>`. For an idle menu offering Escape, `dismiss <id> --revision <screen.revision>` closes it. A stale revision requires another inspection. In particular, inspect new or changed lifecycle hooks before trusting them; YOLO does not imply approval of unknown hooks. Verify the next screen after each choice.
6. An approval or permission prompt (`status` is `needs_approval`, or Codex asks to run a command, apply edits or grant access) is the person's to answer, never yours: inside an Orchestrator session `choose`, `dismiss` and `send` are refused with `NEEDS_PERSON` meanwhile. Tell the person what it asks, then check `status` again. Resolve only reviewed, authorized startup menu actions: `choose <id> --choice <observed-number> --revision <interaction.revision>`. For an idle menu offering Escape, `dismiss <id> --revision <screen.revision>` closes it. A stale revision requires another inspection. In particular, inspect new or changed lifecycle hooks before trusting them; YOLO does not imply approval of unknown hooks. Verify the next screen after each choice.

## Run and verify

Expand Down
2 changes: 1 addition & 1 deletion docs/UI_CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ This contract preserves the approved MVP concept and prevents feature ownership
- An authenticated connection or heartbeat alone never shows agent presence. A branded badge appears only after that agent actually issues a browser command, and its cursor appears only after a real pointer position exists. Claude uses `#D97757`, Codex `#10A37F`, Qwen `#6D44E8`, Kimi `#7C5CFC`, OpenCode `#5A5858`, Hermes `#D6A700`, and an unknown provider `#7A8291`. Browser Settings separately controls indicator visibility without revoking browser access; the agent-access kill switch revokes the connection itself.
- With window snapping enabled, drag and resize use a hidden `10px` grid and a `10px` magnetic threshold for neighboring edges, centers, and a consistent `20px` gap.
- One trusted context dispatcher owns right-clicks on the canvas. Truly empty canvas offers region creation, a sticky note, the Settings-configured launcher submenu, Browser, and Settings. Holding RMB on empty canvas also opens the configurable radial quick launcher: moving toward an action and releasing activates it, while a stationary right-click continues to open the standard empty-canvas menu. Region and note right-clicks remain context-specific. A region offers rename, color, a note at the pressed point, and region-only deletion. A note frame offers edit, bring-to-front, and deletion. Terminal, Browser, plugin, textarea/input, and contenteditable surfaces keep their native context menus; middle-button panning is unchanged. `Cmd/Ctrl+K` opens a searchable palette over live sessions and the same global creation/launch actions. Regions persist independently of terminal restore, render behind HOME and windows, resize from every edge/corner, and move every terminal, plugin, Browser, or note whose complete bounds were inside the region at drag start. Attached contents follow the region continuously during the gesture and persist once at pointer release; deleting a region never deletes its contents. Sticky notes persist bounded text and geometry, snap like other windows, and resize from every edge/corner. General Settings exposes independent **Save colored regions after exit** and **Save notes after exit** controls. Both default on to preserve existing profiles. Turning either off removes only that collection from disk persistence without deleting its live canvas objects; turning it back on saves the current collection, while leaving it off starts the next launch with that collection empty.
- Context menus, region editors, the radial launcher, and the command palette use official Lucide/provider assets and shared application color tokens. Their dimensions follow root `--ui-scale`. Appearance owns the `0.85–1.25` scale in `0.05` steps and the sage/lilac/night system palette; the scale changes UI chrome rather than canvas zoom or terminal font size. Agents owns the independent context-menu and radial-launcher subsets and their safe reset defaults.
- Context menus, region editors, the radial launcher, and the command palette use official Lucide/provider assets and shared application color tokens. Their dimensions follow root `--ui-scale`, as do the terminal card options menu and the canvas shortcut-hints panel. Appearance owns the `0.85–1.25` scale in `0.05` steps and the sage/lilac/night system palette; the scale changes UI chrome rather than canvas zoom or terminal font size. Agents owns the independent context-menu and radial-launcher subsets and their safe reset defaults.
- Settings uses the approved two-pane modal grammar: a persistent icon-labelled sidebar for all seven sections, a separate current-section header, and a scrollable content pane. Settings must not fall back to the legacy light slide-over with one horizontal segmented tab strip. Simple settings use compact copy/control rows; all Settings chrome reads the active system tokens, official Lucide assets, and root `--ui-scale`.
- General Settings places the macOS/Windows/Linux/Custom keyboard preset after language, followed by an expandable Keyboard shortcuts section for canvas, terminal, Codex editor and canvas navigation bindings. Recording a shortcut selects Custom; choosing a named preset replaces bindings. Optional commands can be disabled, while submit, newline and whole-draft selection remain bound. Canvas and terminal bindings update immediately; native Codex editor bindings apply to new or restarted cards. Focused terminal and text inputs retain ownership of canvas keyboard shortcuts on every platform.
- Empty-canvas drag and middle-button drag pan the canvas. On fresh profiles ordinary scroll over empty canvas pans on both axes; pinch and `Cmd/Ctrl + scroll` zoom around the pointer. **Use scroll wheel to zoom** restores historical ordinary-wheel zoom and is enabled by migration for existing profiles. Only a focused input widget interrupts canvas wheel/pinch, except the HOME session list keeps ordinary local scrolling without a focus precondition; unfocused or non-focusable widgets otherwise leave those events to the canvas. **Wheel/pinch capture over widgets** has Off, On, and Key modes: Off preserves local ownership, On always transfers only wheel/pinch to the canvas, and Key transfers only wheel/pinch while its binding is held. Key and full-navigation bindings accept modifier chords or Mouse3/Mouse4/Mouse5. A focused live Browser page therefore scrolls normally in Off or released-Key mode; unfocused Browser content, On, an active Key binding, the full override, pinch, and `Cmd/Ctrl + scroll` are canvas-owned. The owner selected for a Browser wheel sequence is held until 250 ms of wheel inactivity. Browser summaries and placeholders are always canvas-owned. Fresh profiles use Key with `Command` on macOS or `Ctrl` elsewhere. A separate configurable **Canvas navigation override** (default `Option` on macOS and `Alt` elsewhere) transfers wheel/pinch and drag while held. While full override is held all canvas surfaces show `grab`; an owned drag shows `grabbing` until pointer up/cancel even after the binding is released.
Expand Down
Loading
Loading