Skip to content

Proposal: optional harness plugin and three small host APIs #150

Open

Description

@BIackFIame

This follows the feedback on #132, #134, #135 and #137. Nothing here touches core. A first version of the plugin that uses only the existing plugin APIs is working locally (phase 1 below); before publishing it and before proposing any host API, I would like agreement on the flow and on the three APIs. Related core PRs: #147, #148, #133, #136, #149.

Principles

  • Nothing new on default surfaces: HOME, dock, launch dialog, Agents settings and the empty-canvas menu stay as they are on main.
  • One optional plugin (the existing assistant plugin, extended), installed from Settings → Plugins with the normal manifest/permission review and native-code trust.
  • Automatic by default: the orchestrator decides how many agents to start, the plugin picks models and accounts, and changes made by a subagent in a worktree are reviewed when it finishes.
  • The person sees something only when a decision is needed: a secret request, a loop, a budget limit, or a finished review. These use the existing attention panel and system notifications.
  • Flows never start without a preview of roles and tasks.
  • The host keeps all validation, trust, credentials and redaction. A plugin recommendation never grants access.
  • Usage counting reuses the usage history from feat(usage): add quota history and session estimates #138; the plugin does not read provider logs itself.

1. Scenarios

A. Large task, no setup. The person starts an Orchestrator as usual and describes the task. The orchestrator calls the plugin's route tool for each subagent and gets provider, model and account. It then uses core spawn_agent. Nothing is asked unless a rule below fires.

B. Review without asking. A subagent working in a worktree environment finishes. The plugin starts a reviewer that sees only the diff. When the verdict is ready, one attention entry appears. Open review shows the changes in the review dialog accepted in #133, with Accept/Reject still requiring a click.

C. Something needs a person. An agent repeats the same failing command, or its task reaches the token budget the person set. One attention entry appears with at most two actions, for example Stop agent / Ignore. Nothing else changes on screen.

2. What the person sees

Card menu (existing cardActions, shown only while the plugin is enabled and trusted):

Orchestrator card ⋯     Agent card ⋯
  …existing items…        …existing items…
  Plan from flow…         Report
  Task board

Plugin canvas card (canvas-app, opened by Plan from flow…, standard 54px header and summary below 0.5×):

[header]  Flow: Executor and reviewer            (built-in, localized)
  What it does: one agent implements, one reviews the diff.
  Roles      Provider/model (auto)     Tasks
  executor   codex / gpt-5             implement parser
  reviewer   claude / sonnet           review diff
  Permissions are unchanged: each agent uses the launch profile you chose.
                                   [Cancel]  [Start]

User flows from .canvastty/flows/*.yaml are marked "From this project". Their text is shown as written.

Plugin settings page (settingsContribution, reached from the plugin's Settings action in Settings → Plugins). It has four rows in the SettingGroup row grammar (label and help on the left, one control on the right):

Command review        [Strict | Warn | Off]
Automatic review      [on/off]   reviews worktree subagents when they finish
Task budget           [ empty = no limit ]  tokens
Model choice          [Automatic | Ask before start]

Attention entries (needs proposal A; until then only card badges):

Review ready · "parser" · 2 findings          [Open review] [Dismiss]
Possible loop · "tests" · same command ×5     [Stop agent]  [Ignore]
Budget reached · "refactor" · 200k tokens     [Allow +50k]  [Stop task]
Secret requested · "release" · GITHUB_TOKEN   [Allow once]  [Deny]

Card badges (existing cards.setBadge, at most two per card, only when there is a signal): review: 2, budget 80%, loop?, 3/5 tasks.

All built-in strings come from the plugin in en/ru using initialize.locale and the context locale. This includes badges, tool descriptions and action titles. The pages take the palette from context. One open question for you: would you accept a host stylesheet with tokens and --ui-scale for plugin pages, so they do not copy values?

3. Feature → existing API

Feature Existing API on main
Model and account choice agent tool route (tools:agents, orchestrator role) → core spawn_agent model + accounts plugin account (delegable launch option)
Team size orchestrator's own decision; flow_plan tool only suggests roles
Flow preview and start service reads <cwd>/.canvastty/flows; canvas-app; card action filtered to orchestrator role; approved plan returned to the orchestrator through the flow_status tool
Task board agent tools task_* (orchestrator + subagent roles), plugin storage, badge
Automatic review sessions:events (exited/idle + environment ref) → sessions.create reviewer in a confining environment kind with only the diff → review_submit tool → card action result review (#133 dialog)
Command review, data classes decide (decision:provide) + launch policy + dataClass launch field; settings only on the plugin page
Budget enforcement decide deny "budget reached" + launch policy refusing new spawns
Loop detection (before the call) fingerprints from the plugin's own decide calls
Continue after quota accounts plugin card action (exists)
Agents on a server environments plugin ssh-host (exists)

Missing: raising attention entries, per-session token usage and tool outcomes, and restarting a subagent in its card.

4. Missing host APIs (three separate PRs)

A. attention:raise: plugin entries in the attention panel

  • Contract: attention.raise {key, sessionId?, kind: "info"|"needs-input"|"warning", title ≤60, body ≤240, actions ≤2 [{id, title}]} → {id}; attention.clear {key}. A click sends canvastty.attention.action {key, actionId}. The text is plain and masked by the host.
  • Shown in the existing panel and system notifications according to the existing General/Appearance settings. No new settings. Rate limit of about 6 per minute per plugin.
  • Permission: install-time "can show items in your attention panel".
  • Revocation: entries are cleared on disable, uninstall, untrust or update. A missing service means the action is dropped and the entry closes.

B. sessions:activity + usage:read: read-only facts

  • usage.session {sessionId} → the SessionTokenUsage union already proposed in docs/metrics-and-telemetry.md, filled from the feat(usage): add quota history and session estimates #138 usage history. No account scope and no quota history.
  • Event canvastty.sessions.event type tool: {sessionId, turnId, at, name, resultClass: success|error|denied|unknown, actionHash, errorHash?}. The hashes are HMAC with a per-plugin host key. There is no prompt, response or output text.
  • parentSessionId and role are added to canvastty.launch.prepare so the launch policy can apply budgets per task.
  • Disabled or not granted: nothing is sent, and PostToolUse hooks are not installed for it.

C. sessions:delegate: restart a subagent in its card

  • sessions.restart {sessionId, resume?} → {started}. Only for subagents of the orchestrator that called the plugin tool, where the host checks the parent; or for the card where the person clicked the plugin's action. It uses the normal launch pipeline, so refusals appear on the card.
  • sessions.create {role: "orchestrator"} for a flow started from the preview.
  • Permission: install-time "can restart agents your orchestrator gives it".
  • Revocation: the grant ends when the parent exits, the card closes, or the plugin is disabled or untrusted. Calls are idempotent; on timeout the card stays as it was.
  • This also delivers an approved secret: it goes through the plugin's launch secretEnv on restart, so the value never passes through tool output.

5. Not proposed

  • The D0–D3 / execution-destination editor in core Agents settings.
  • A flow picker in the launch dialog.
  • The session inspector dashboard (timeline, usage, report and notification tabs).
  • Core model: "auto" / model:route, or plugin ids hard-coded in core.
  • Separate usage or cost tracking and pricing tables (feat(usage): add quota history and session estimates #138 covers this), terminal output history, process pause (SIGSTOP), and canvas edges or "Gather" between cards.

6. Phases (smallest first)

  1. feat: a worktree per subagent, a combined change review and rollback points #133 rebuilt on main (already accepted). Separately, narrow core bug fixes without UI.
  2. Plugin on existing APIs only: route, flow preview, task tools, automatic review into the feat: a worktree per subagent, a combined change review and rollback points #133 dialog, command review, settings page. Signals appear as badges only.
  3. Proposal A, then attention entries in the plugin.
  4. Proposal B, then budgets and loop detection after the call.
  5. Proposal C, only if retry in place and secret approval are still needed after phase 3.

Each phase ships Linux light/dark screenshots, a screenshot at --ui-scale ≠ 1, and Russian UI checks.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions