@xingular/harness 1.0.0 → 1.1.1
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.
- package/CHANGELOG.md +33 -5
- package/README.md +70 -19
- package/dist/cli.js +10321 -5785
- package/dist/sdk/agents/builtin.d.ts +2 -0
- package/dist/sdk/agents/builtin.js +34 -0
- package/dist/sdk/agents/narrow.d.ts +13 -0
- package/dist/sdk/agents/narrow.js +29 -0
- package/dist/sdk/agents/profiles.d.ts +80 -0
- package/dist/sdk/agents/profiles.js +221 -0
- package/dist/sdk/annotations/bridge.d.ts +42 -0
- package/dist/sdk/annotations/bridge.js +264 -0
- package/dist/sdk/annotations/capture.d.ts +116 -0
- package/dist/sdk/annotations/capture.js +308 -0
- package/dist/sdk/annotations/delivery.d.ts +72 -0
- package/dist/sdk/annotations/delivery.js +130 -0
- package/dist/sdk/annotations/inspect.d.ts +10 -0
- package/dist/sdk/annotations/inspect.js +33 -0
- package/dist/sdk/annotations/isolated.d.ts +6 -0
- package/dist/sdk/annotations/isolated.js +51 -0
- package/dist/sdk/annotations/pageScript.d.ts +28 -0
- package/dist/sdk/annotations/pageScript.js +570 -0
- package/dist/sdk/annotations/part.d.ts +10 -0
- package/dist/sdk/annotations/part.js +144 -0
- package/dist/sdk/annotations/queue.d.ts +4 -0
- package/dist/sdk/annotations/queue.js +40 -0
- package/dist/sdk/annotations/serverMethods.d.ts +3 -0
- package/dist/sdk/annotations/serverMethods.js +62 -0
- package/dist/sdk/annotations/store.d.ts +160 -0
- package/dist/sdk/annotations/store.js +386 -0
- package/dist/sdk/browser/index.d.ts +14 -3
- package/dist/sdk/browser/index.js +11 -4
- package/dist/sdk/browser/serverMethods.d.ts +3 -0
- package/dist/sdk/browser/serverMethods.js +7 -0
- package/dist/sdk/browser/session.d.ts +1 -0
- package/dist/sdk/browser/session.js +45 -9
- package/dist/sdk/cli.js +19 -11
- package/dist/sdk/core/bus.js +1 -1
- package/dist/sdk/core/env.d.ts +1 -1
- package/dist/sdk/core/env.js +1 -1
- package/dist/sdk/doctor/serverMethods.d.ts +3 -0
- package/dist/sdk/doctor/serverMethods.js +8 -0
- package/dist/sdk/harness.d.ts +15 -0
- package/dist/sdk/harness.js +44 -5
- package/dist/sdk/history/recall.js +8 -8
- package/dist/sdk/history/serverMethods.d.ts +3 -0
- package/dist/sdk/history/serverMethods.js +8 -0
- package/dist/sdk/hub/cli.d.ts +1 -1
- package/dist/sdk/hub/cli.js +1 -1
- package/dist/sdk/hub/schema.d.ts +1 -1
- package/dist/sdk/hub/serverMethods.d.ts +3 -0
- package/dist/sdk/hub/serverMethods.js +11 -0
- package/dist/sdk/index.d.ts +10 -0
- package/dist/sdk/index.js +7 -0
- package/dist/sdk/mcp/connections.js +14 -7
- package/dist/sdk/mcp/serverMethods.d.ts +3 -0
- package/dist/sdk/mcp/serverMethods.js +22 -0
- package/dist/sdk/plugins/builtin.d.ts +1 -0
- package/dist/sdk/plugins/builtin.js +128 -33
- package/dist/sdk/plugins/builtinRegistry.d.ts +53 -0
- package/dist/sdk/plugins/builtinRegistry.js +49 -0
- package/dist/sdk/plugins/cli.d.ts +1 -1
- package/dist/sdk/plugins/cli.js +4 -3
- package/dist/sdk/prompt/compile.d.ts +5 -2
- package/dist/sdk/prompt/compile.js +25 -8
- package/dist/sdk/refine/cli.d.ts +1 -1
- package/dist/sdk/refine/cli.js +2 -2
- package/dist/sdk/refine/serverMethods.d.ts +3 -0
- package/dist/sdk/refine/serverMethods.js +20 -0
- package/dist/sdk/server/methods.js +9 -86
- package/dist/sdk/server/params.d.ts +4 -0
- package/dist/sdk/server/params.js +11 -0
- package/dist/sdk/sessions/contracts.d.ts +17 -0
- package/dist/sdk/sessions/contracts.js +42 -3
- package/dist/sdk/sessions/planMode.d.ts +5 -2
- package/dist/sdk/sessions/planMode.js +12 -3
- package/dist/sdk/sessions/reasoningSummaries.d.ts +2 -2
- package/dist/sdk/sessions/reasoningSummaries.js +3 -3
- package/dist/sdk/sessions/registry.d.ts +1 -0
- package/dist/sdk/sessions/registry.js +4 -1
- package/dist/sdk/sessions/runIndex.js +7 -7
- package/dist/sdk/sessions/runStore.js +3 -1
- package/dist/sdk/sessions/runner.js +2 -2
- package/dist/sdk/sessions/sessions.d.ts +17 -5
- package/dist/sdk/sessions/sessions.js +79 -12
- package/dist/sdk/sessions/sideQuestionServerMethods.d.ts +3 -0
- package/dist/sdk/sessions/sideQuestionServerMethods.js +19 -0
- package/dist/sdk/sessions/sideQuestions.d.ts +66 -0
- package/dist/sdk/sessions/sideQuestions.js +290 -0
- package/dist/sdk/sessions/subagentServerMethods.d.ts +3 -0
- package/dist/sdk/sessions/subagentServerMethods.js +41 -0
- package/dist/sdk/sessions/subagentService.d.ts +13 -2
- package/dist/sdk/sessions/subagentService.js +34 -16
- package/dist/sdk/sessions/subagents.d.ts +9 -1
- package/dist/sdk/sessions/subagents.js +19 -0
- package/dist/sdk/terminal/browser.d.ts +62 -0
- package/dist/sdk/terminal/browser.js +41 -0
- package/dist/sdk/terminal/browserControl.d.ts +29 -0
- package/dist/sdk/terminal/browserControl.js +186 -0
- package/dist/sdk/terminal/commandHelp.d.ts +17 -0
- package/dist/sdk/terminal/commandHelp.js +20 -0
- package/dist/sdk/terminal/controller.d.ts +7 -1
- package/dist/sdk/terminal/controller.js +34 -2
- package/dist/sdk/terminal/opentui/subagentsWidget.d.ts +28 -0
- package/dist/sdk/terminal/opentui/subagentsWidget.js +52 -0
- package/dist/sdk/terminal/piExtension.js +33 -48
- package/dist/sdk/terminal/socket.d.ts +6 -3
- package/dist/sdk/terminal/socket.js +40 -9
- package/dist/sdk/terminal/standalone.d.ts +2 -0
- package/dist/sdk/terminal/standalone.js +50 -10
- package/dist/sdk/terminal/subagentMonitor.d.ts +38 -0
- package/dist/sdk/terminal/subagentMonitor.js +121 -0
- package/dist/sdk/terminal/terminals.d.ts +42 -6
- package/dist/sdk/terminal/terminals.js +359 -18
- package/dist/sdk/terminal/trajectory.js +2 -2
- package/dist/sdk/terminal/tui/annotateCommand.d.ts +3 -0
- package/dist/sdk/terminal/tui/annotateCommand.js +22 -0
- package/dist/sdk/terminal/tui/commandPages.d.ts +5 -1
- package/dist/sdk/terminal/tui/commandPages.js +54 -6
- package/dist/sdk/terminal/tui/commands.d.ts +8 -4
- package/dist/sdk/terminal/tui/commands.js +181 -58
- package/dist/sdk/terminal/tui/dialogGeometry.d.ts +2 -2
- package/dist/sdk/terminal/tui/dialogGeometry.js +4 -2
- package/dist/sdk/terminal/tui/dialogs.d.ts +6 -1
- package/dist/sdk/terminal/tui/dialogs.js +9 -2
- package/dist/sdk/terminal/tui/modelPicker.js +1 -6
- package/dist/sdk/terminal/tui/page.d.ts +3 -0
- package/dist/sdk/terminal/tui/pageOverlay.js +17 -6
- package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +26 -4
- package/dist/sdk/terminal/tui/pages/accountsPage.js +264 -36
- package/dist/sdk/terminal/tui/pages/agentsPage.d.ts +74 -0
- package/dist/sdk/terminal/tui/pages/agentsPage.js +190 -0
- package/dist/sdk/terminal/tui/pages/annotatePage.d.ts +94 -0
- package/dist/sdk/terminal/tui/pages/annotatePage.js +341 -0
- package/dist/sdk/terminal/tui/pages/browserPage.d.ts +87 -0
- package/dist/sdk/terminal/tui/pages/browserPage.js +738 -0
- package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +2 -0
- package/dist/sdk/terminal/tui/pages/doctorPage.js +103 -15
- package/dist/sdk/terminal/tui/pages/notesPage.d.ts +75 -0
- package/dist/sdk/terminal/tui/pages/notesPage.js +201 -0
- package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +8 -0
- package/dist/sdk/terminal/tui/pages/settingsPage.js +16 -1
- package/dist/sdk/terminal/tui/pages/subagentsPage.d.ts +23 -0
- package/dist/sdk/terminal/tui/pages/subagentsPage.js +70 -0
- package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +12 -5
- package/dist/sdk/terminal/tui/pages/trajectoryPage.js +156 -83
- package/dist/sdk/terminal/tui/pages/worktreesPage.d.ts +72 -0
- package/dist/sdk/terminal/tui/pages/worktreesPage.js +203 -0
- package/dist/sdk/terminal/tui/planMode.d.ts +1 -1
- package/dist/sdk/terminal/tui/planMode.js +1 -1
- package/dist/sdk/terminal/tui/pluginCommands.d.ts +14 -0
- package/dist/sdk/terminal/tui/pluginCommands.js +27 -0
- package/dist/sdk/terminal/tui/questions.d.ts +2 -0
- package/dist/sdk/terminal/tui/runtime.js +4 -2
- package/dist/sdk/terminal/tui/settingsModel.d.ts +2 -0
- package/dist/sdk/terminal/tui/settingsModel.js +32 -2
- package/dist/sdk/terminal/tui/sideQuestion.d.ts +26 -26
- package/dist/sdk/terminal/tui/sideQuestion.js +131 -98
- package/dist/sdk/terminal/tui/ui.d.ts +2 -0
- package/dist/sdk/terminal/tui/ui.js +1 -0
- package/dist/sdk/tools/askUser.js +26 -8
- package/dist/sdk/tools/checklist.js +2 -2
- package/dist/sdk/tools/harnessTools.d.ts +2 -0
- package/dist/sdk/tools/harnessTools.js +1 -1
- package/dist/sdk/tools/spawnSubagent.js +13 -4
- package/dist/sdk/web/part.d.ts +10 -0
- package/dist/sdk/web/part.js +6 -0
- package/dist/sdk/web/serverMethods.d.ts +3 -0
- package/dist/sdk/web/serverMethods.js +7 -0
- package/dist/sdk/wiki/serverMethods.d.ts +3 -0
- package/dist/sdk/wiki/serverMethods.js +26 -0
- package/dist/sdk/worktrees/cli.d.ts +11 -0
- package/dist/sdk/worktrees/cli.js +146 -0
- package/dist/sdk/worktrees/copy.d.ts +9 -0
- package/dist/sdk/worktrees/copy.js +111 -0
- package/dist/sdk/worktrees/git.d.ts +16 -0
- package/dist/sdk/worktrees/git.js +81 -0
- package/dist/sdk/worktrees/serverMethods.d.ts +3 -0
- package/dist/sdk/worktrees/serverMethods.js +30 -0
- package/dist/sdk/worktrees/service.d.ts +73 -0
- package/dist/sdk/worktrees/service.js +483 -0
- package/dist/sdk/worktrees/setup.d.ts +23 -0
- package/dist/sdk/worktrees/setup.js +65 -0
- package/dist/sdk/worktrees/types.d.ts +91 -0
- package/dist/sdk/worktrees/types.js +1 -0
- package/dist/sdk/world/cli.d.ts +2 -2
- package/dist/sdk/world/cli.js +6 -6
- package/dist/sdk/world/world.d.ts +3 -1
- package/dist/sdk/world/world.js +8 -9
- package/dist/terminal-opentui.js +14540 -7374
- package/dist/terminal-pi.js +285 -666
- package/docs/README.md +22 -2
- package/docs/architecture/00-overview.md +28 -16
- package/docs/architecture/02-sessions-and-runs.md +72 -15
- package/docs/architecture/03-variants.md +10 -2
- package/docs/architecture/04-prompt.md +26 -6
- package/docs/architecture/06-plugins-and-capabilities.md +39 -3
- package/docs/architecture/07-tools-and-gate.md +21 -6
- package/docs/architecture/09-accounts-and-connectors.md +8 -0
- package/docs/architecture/10-server-protocol.md +111 -2
- package/docs/architecture/11-terminal.md +185 -5
- package/docs/architecture/12-storage.md +15 -1
- package/docs/architecture/13-world-tools.md +28 -6
- package/docs/architecture/14-surfaces-and-parity.md +89 -0
- package/docs/architecture/README.md +15 -4
- package/docs/architecture/proposals/PROP-0006-run-checklist.md +4 -2
- package/docs/architecture/proposals/PROP-0013-resource-browser.md +58 -0
- package/docs/architecture/proposals/PROP-0014-fullscreen-browser-tabs.md +58 -0
- package/docs/architecture/proposals/PROP-0015-one-capability-surface.md +88 -0
- package/docs/architecture/proposals/PROP-0016-managed-worktrees.md +156 -0
- package/docs/architecture/proposals/PROP-0017-page-annotations.md +127 -0
- package/docs/architecture/proposals/PROP-0018-annotation-queue-and-app-targets.md +179 -0
- package/docs/architecture/proposals/PROP-0019-contextual-side-questions.md +122 -0
- package/docs/architecture/proposals/PROP-0020-builtin-feature-plugins.md +105 -0
- package/docs/architecture/proposals/PROP-0021-command-namespaces-and-duplicates.md +99 -0
- package/docs/architecture/proposals/PROP-0022-plan-only-questions.md +102 -0
- package/docs/architecture/proposals/PROP-0023-xagent-cli-name.md +61 -0
- package/docs/architecture/proposals/PROP-0024-question-sketch-previews.md +130 -0
- package/docs/architecture/proposals/PROP-0025-contextual-question-wireframes.md +49 -0
- package/docs/architecture/proposals/PROP-0026-connected-sketch-display.md +94 -0
- package/docs/architecture/proposals/PROP-0027-xingular-agent-product-identity.md +60 -0
- package/docs/architecture/proposals/PROP-0028-normalize-question-wireframes.md +55 -0
- package/docs/architecture/proposals/PROP-0029-agent-profiles.md +124 -0
- package/docs/architecture/proposals/PROP-0030-subagent-title.md +86 -0
- package/docs/architecture/proposals/README.md +25 -0
- package/docs/decisions/ADR-0009-xharness-command.md +6 -5
- package/docs/decisions/ADR-0014-public-release-baseline.md +3 -2
- package/docs/decisions/ADR-0015-resource-browser.md +28 -0
- package/docs/decisions/ADR-0016-fullscreen-browser-tabs.md +31 -0
- package/docs/decisions/ADR-0017-one-capability-surface.md +34 -0
- package/docs/decisions/ADR-0018-builtin-feature-plugins.md +35 -0
- package/docs/decisions/ADR-0019-managed-git-worktrees.md +31 -0
- package/docs/decisions/ADR-0020-page-annotations.md +37 -0
- package/docs/decisions/ADR-0021-required-command-namespaces.md +40 -0
- package/docs/decisions/ADR-0022-plan-only-question-tools.md +34 -0
- package/docs/decisions/ADR-0023-contextual-side-question-runs.md +35 -0
- package/docs/decisions/ADR-0024-xagent-command.md +40 -0
- package/docs/decisions/ADR-0025-question-choice-sketches.md +49 -0
- package/docs/decisions/ADR-0026-contextual-question-wireframes.md +58 -0
- package/docs/decisions/ADR-0027-connected-sketch-display.md +60 -0
- package/docs/decisions/ADR-0028-xingular-agent-product-identity.md +56 -0
- package/docs/decisions/ADR-0029-normalized-question-wireframe-borders.md +33 -0
- package/docs/decisions/ADR-0030-agent-profiles.md +43 -0
- package/docs/doctor.md +10 -4
- package/docs/features/README.md +26 -0
- package/docs/features/interfaces/README.md +1 -1
- package/docs/future-work.md +48 -0
- package/docs/parity.md +78 -0
- package/docs/releases/1.0.0.md +2 -2
- package/docs/releases/4.0.0.md +46 -0
- package/docs/releases/README.md +20 -15
- package/docs/study/00-index.md +5 -0
- package/docs/study/autonomous-engineering-sources.md +277 -0
- package/docs/study/autonomy-sources.md +147 -0
- package/docs/study/proactive-autonomy.md +408 -0
- package/docs/study/tui-resource-browser.md +78 -0
- package/docs/terminal-tui.md +325 -93
- package/package.json +3 -3
|
@@ -12,7 +12,7 @@ to the host for the extension points the host supplies.
|
|
|
12
12
|
| Type / function | Module | Role |
|
|
13
13
|
|---|---|---|
|
|
14
14
|
| `RpcPeer`, `Transport`, `stdioTransport`, `PROTOCOL_VERSION` | `server/rpc.ts` | Framing, requests, replies, host calls. |
|
|
15
|
-
| `methods(harness)` | `server/methods.ts` |
|
|
15
|
+
| `methods(harness)` | `server/methods.ts` | Merges Foundation handlers with built-in plugin handlers from `BuiltinPluginRegistry` and rejects overlapping ownership. |
|
|
16
16
|
| `serve`, `attach` | `server/serve.ts` | Registers the table, forwards events and notices. |
|
|
17
17
|
| `remoteSecrets`, remote policy, directory, tools | `server/remote.ts` | Extension points supplied by the host over the protocol. |
|
|
18
18
|
| CLI `serve` | `src/cli.ts` | `serve --state <dir> --data <dir> --name <product> [--builtins <dir>] [--host-secrets] [--host-policy] [--host-tools] [--host-directory]`. |
|
|
@@ -27,9 +27,13 @@ harness → host { v: 1, id, call, params } host → harness { v: 1
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
- stdout carries only protocol lines; diagnostics go to stderr.
|
|
30
|
+
- Run events use the validated, persisted payload schemas in page 02. `question.requested` may carry
|
|
31
|
+
the optional bounded ASCII sketch metadata described there; the server relays it without changing
|
|
32
|
+
answer payloads or the protocol framing (PROP-0024).
|
|
30
33
|
- `harness.methods` lists every method. Groups in the table: `accounts`, `harnesses`, `runs`,
|
|
31
34
|
`connections`, `plugins`, `wiki`, `refine`, `capabilities`, `hub`, `terminal`, `approvals`,
|
|
32
|
-
`harness`, `subagents`, `sessions`, `library`, `recall`, `context
|
|
35
|
+
`harness`, `subagents`, `agents`, `sessions`, `sideQuestions`, `library`, `recall`, `context`,
|
|
36
|
+
`worktrees`, `annotations`.
|
|
33
37
|
- Host calls (only with the matching `--host-*` flag): `secrets.get|set|delete`,
|
|
34
38
|
`policy.scope|authorize|approval|connections`, `tools.call`. The host registers tools with
|
|
35
39
|
`tools.register` and names with `directory.set`, and describes its parts with
|
|
@@ -37,6 +41,12 @@ harness → host { v: 1, id, call, params } host → harness { v: 1
|
|
|
37
41
|
- `refine.start` takes `{ task, k?, mode?, improver?, executor?, baseVersion?, retainWorkspaces?, id? }`;
|
|
38
42
|
`refine.candidates` returns each execution with `workspace: string | null` (page 05, PROP-0002, PROP-0003).
|
|
39
43
|
- `runs.checklist { runId }` returns the run's latest checklist, `[]` when it wrote none (PROP-0006).
|
|
44
|
+
- `agents.list { cwd? }` returns `{ profiles, problems }`; `agents.get { cwd?, name }` one profile;
|
|
45
|
+
`agents.create { cwd?, name, scope: 'global' | 'project', from? }` writes the template or a copy
|
|
46
|
+
and refuses an existing file; `agents.remove { cwd?, name, scope }` deletes a person's own file.
|
|
47
|
+
`subagents.spawn` takes `agent` as a profile name and returns `agent` and `unavailableTools`
|
|
48
|
+
(PROP-0029). It takes an optional `title` (at most six words); without one the child's title is
|
|
49
|
+
the first line of its brief (PROP-0030).
|
|
40
50
|
- `runs.continuation { runId, sessionDir? }` returns a `Continuation`, and `sessions.run` accepts
|
|
41
51
|
`continueFrom` (page 02, PROP-0007). `harness.status` reports `recovery.interruptedRunIds`.
|
|
42
52
|
- Errors carry a stable `code`, a message and an optional hint (`core/errors.ts`).
|
|
@@ -56,6 +66,10 @@ harness → host { v: 1, id, call, params } host → harness { v: 1
|
|
|
56
66
|
variants, the Wiki, the prompt, connected apps, a recorded session, a plugin hook and the
|
|
57
67
|
refinement demo. The App's sidecar tests parse every reply with its schemas and must pass too.
|
|
58
68
|
|
|
69
|
+
Built-in feature modules may contribute handlers through `BuiltinPluginRegistry`, but the
|
|
70
|
+
`methods(harness)` result remains the public contract. Plugin module ownership does not rename
|
|
71
|
+
methods or change their params, result shapes or authorization paths (PROP-0020).
|
|
72
|
+
|
|
59
73
|
## Source map
|
|
60
74
|
|
|
61
75
|
`src/server/*.ts`, `src/cli.ts`, `src/core/errors.ts`, `scripts/prove-standalone.mjs`.
|
|
@@ -78,7 +92,102 @@ account/model, findings, and available live-check notices. Findings distinguish
|
|
|
78
92
|
`live` and statuses `pass`, `warning`, `fail`, `disabled`, `blocked`, `unverified`. Schemas and
|
|
79
93
|
Node types are exported. Jobs are in-memory until shutdown; real live-run records remain.
|
|
80
94
|
|
|
95
|
+
## Side questions (PROP-0019)
|
|
96
|
+
|
|
97
|
+
| Method | Input | Reply |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `sideQuestions.start` | `{ question, cwd, caller, context?: { instructions?, transcript?, references? }, parentRunId?, parentSessionId?, accountId?, model?, effort?, runId?, sessionId? }` | `{ runId, sessionId, nativeSessionId }` |
|
|
100
|
+
| `sideQuestions.read` | `{ runId, sessionId, afterSequence? }` | `{ run: RunRecord, events: RunEvent[] }` |
|
|
101
|
+
| `sideQuestions.interrupt` | `{ runId, sessionId }` | `{ runId }` |
|
|
102
|
+
|
|
103
|
+
The Harness builds bounded context from the parent's persisted effective prompt and public events
|
|
104
|
+
plus the surface's visible transcript. Read and interrupt require the side run's session id. The
|
|
105
|
+
standalone terminal exposes the same operations through control-key-protected
|
|
106
|
+
`terminal.sideQuestions.*` calls; its caller identity, account and working folder come from terminal
|
|
107
|
+
preparation, not client-supplied values.
|
|
108
|
+
|
|
81
109
|
Remote `tools.register` may include `diagnostics: [{ id, category, title, tools, probe?: { notice,
|
|
82
110
|
tool, input, contains } }]`. The host answers `tools.diagnose({ id, context })` with `{ status,
|
|
83
111
|
evidence, remedy? }` for local inspection. A probe is a declared registered tool call through
|
|
84
112
|
the gate, with an expected response marker; it cannot supply arbitrary executable code.
|
|
113
|
+
|
|
114
|
+
## Private terminal resource controls (PROP-0013)
|
|
115
|
+
|
|
116
|
+
These methods are session-socket controls, not additions to the public host RPC table. All
|
|
117
|
+
require the claimed terminal control key; account, working directory and variant pin come
|
|
118
|
+
from preparation, never from the request.
|
|
119
|
+
|
|
120
|
+
| Method | Input | Reply |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| `terminal.browser.config` | `{}` | `{ allowPrivate }`, the device-local private-address setting |
|
|
123
|
+
| `terminal.browser.configure` | `{ allowPrivate: boolean }` | `{ allowPrivate }`, updated setting |
|
|
124
|
+
| `terminal.browser.snapshot` | `{ refresh?: boolean }` | `BrowserSnapshot`: resources, plugins, safe connection records, pinned/latest variant identity and Hub overview |
|
|
125
|
+
| `terminal.browser.read` | `{ id, latest?: boolean }` | `{ content }`, bounded enumerated resource content |
|
|
126
|
+
| `terminal.browser.importSkill` | `{ path }` | `{}`, validated bounded local bundle imported into the existing library |
|
|
127
|
+
| `terminal.browser.hubPreview` | `{ id, version, offset? }` | Existing `HubPreviewPage` |
|
|
128
|
+
| `terminal.browser.hubDocument` | `{ id, version }` | Existing verified installed document |
|
|
129
|
+
| `terminal.browser.connections.appClients` | `{}` | Existing available application OAuth catalog IDs |
|
|
130
|
+
| `terminal.browser.connections.save` | `{ input: ConnectionInput }` | Existing safe `Connection` record |
|
|
131
|
+
| `terminal.browser.connections.test\|signIn\|signOut\|remove` | `{ id }` | Existing connection service result |
|
|
132
|
+
|
|
133
|
+
Protected `plugins.install { source }` and `plugins.remove { pluginId }` delegate to the package
|
|
134
|
+
service. Optional matching callbacks extend `PluginControl`; hosts without them receive a clear
|
|
135
|
+
unsupported-operation error. No protocol version or persisted schema changes.
|
|
136
|
+
|
|
137
|
+
## Worktrees (PROP-0016)
|
|
138
|
+
|
|
139
|
+
| Method | Input | Reply |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| `worktrees.list` | `{ repo? }` | active `WorktreeRecord[]` (of the repository `repo` is in) |
|
|
142
|
+
| `worktrees.removed` | `{ repo? }` | removed records that `restore` can bring back |
|
|
143
|
+
| `worktrees.status` | `{ id }` | `WorktreeStatus`: exists, head, changed paths, commits since it started |
|
|
144
|
+
| `worktrees.create` | `{ repo, name?, baseRef?, branch?, kind?, carryChanges?, setup? }` | `{ worktree, carried, included, setup }` |
|
|
145
|
+
| `worktrees.branch` | `{ id, name }` | the record, on branch `<prefix><name>` |
|
|
146
|
+
| `worktrees.handoff` | `{ id, direction: "toSource" \| "toWorktree", move? }` | `{ direction, patched, copied, stash }` |
|
|
147
|
+
| `worktrees.remove` | `{ id, force? }` | `{ worktree, snapshot }` |
|
|
148
|
+
| `worktrees.restore` | `{ id }` | the record |
|
|
149
|
+
| `worktrees.prune` | `{ repo?, keep? }` | `{ removed, failed }` |
|
|
150
|
+
| `worktrees.adopt` | `{ path }` | the record (kind `permanent`, origin `adopted`) |
|
|
151
|
+
| `worktrees.setup.trust` | `{ repo, hash }` | `{}` |
|
|
152
|
+
|
|
153
|
+
Errors: `not_a_repository`, `repository_empty`, `worktree_exists`, `branch_exists`,
|
|
154
|
+
`worktree_in_use`, `worktree_has_work`, `worktree_removed`, `worktree_missing`, `not_a_worktree`,
|
|
155
|
+
`handoff_target_dirty`, `handoff_conflict`, `git_failed`, `git_unavailable`. The terminal reaches the
|
|
156
|
+
same service through `terminal.worktrees.*` routes, which need the control key (`INV-TUI-4`).
|
|
157
|
+
|
|
158
|
+
## Page notes (PROP-0017)
|
|
159
|
+
|
|
160
|
+
| Method | Input | Reply |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| `annotations.list` | `{ url?, query?, status?, offset?, limit? }` | `{ notes, total }`, newest first |
|
|
163
|
+
| `annotations.read` | `{ id }` | `Note` |
|
|
164
|
+
| `annotations.create` | `{ source, target, body, tags? }` | `Note` (private) |
|
|
165
|
+
| `annotations.update` | `{ id, expectedVersion, patch: { body?, tags?, status?, target? } }` | `Note` |
|
|
166
|
+
| `annotations.delete` | `{ id, expectedVersion }` | `{}` |
|
|
167
|
+
| `annotations.share` | `{ id, principal: { sessionId } \| { agentId }, binding? }` | `Note` |
|
|
168
|
+
| `annotations.unshare` | `{ id, principal }` | `Note` |
|
|
169
|
+
| `annotations.revokeBinding` | `{ binding }` | `{ revoked }` |
|
|
170
|
+
| `annotations.import` | `{ notes }` | `{ imported, skipped }` (ids kept) |
|
|
171
|
+
| `annotations.pageScript` | `{}` | `{ script }`: the page helper, with `__ARGS__` for one operation |
|
|
172
|
+
| `annotations.queue` | `{ id, sessionId, expectedVersion?, autoSend? }` | `Note`, shared with the session and queued (PROP-0018) |
|
|
173
|
+
| `annotations.dequeue` / `annotations.confirm` | `{ id, expectedVersion? }` | `Note` |
|
|
174
|
+
| `annotations.queued` | `{ sessionId }` | `{ notes }`, oldest first |
|
|
175
|
+
| `annotations.createAndAct` | `{ note, action: save \| queue \| send, sessionId?, trusted? }` | `{ note, send }`; an untrusted send waits for `confirm` |
|
|
176
|
+
| `annotations.compose` | `{ sessionId, ids? }` | `{ text, ids }`: one instruction for a host's own `sessions.run` |
|
|
177
|
+
| `annotations.delivered` | `{ ids, sessionId, runId }` | `{ notes }`, marked sent |
|
|
178
|
+
| `annotations.send` | `{ sessionId, ids? }` | `{ state: sent \| busy \| host \| empty, … }` |
|
|
179
|
+
| `annotations.capture.attach` | `{ key, kind: web \| cdp \| bridge, endpoint?, name? }` | `{ kind, app, windows, bridge? }` |
|
|
180
|
+
| `annotations.capture.target` | `{ key }` | `{ kind, app, inspecting, windows }` |
|
|
181
|
+
| `annotations.capture.selectWindow` | `{ key, window }` | `{}` |
|
|
182
|
+
| `annotations.capture.open` | `{ key, url? }` | `{ url, title }` |
|
|
183
|
+
| `annotations.capture.inspect` / `stopInspect` | `{ key }` | `{ captureId }` / `{}` |
|
|
184
|
+
| `annotations.capture.next` | `{ key, sessionId?, surface? }` | `{ active, trusted, app, note, send, message, … }` |
|
|
185
|
+
| `annotations.capture.release` | `{ key }` | `{}` |
|
|
186
|
+
| `annotations.bridge.start` | `{}` | `{ port, token, scriptUrl, snippet }` |
|
|
187
|
+
|
|
188
|
+
Notices: `annotations.changed { sessionId, ids }` after any queue, send or fix;
|
|
189
|
+
`annotations.ready { sessionId, ids }` when a host session's waiting notes should be sent now.
|
|
190
|
+
|
|
191
|
+
Errors: `version_conflict`, `not_found`, `annotation_limit`, `invalid_request`, `invalid_data`. The
|
|
192
|
+
terminal reaches the same store through `terminal.annotations.*`, which shares only with its own
|
|
193
|
+
session and needs the control key (`INV-TUI-4`).
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
The harness owns a generic interactive terminal application (`
|
|
5
|
+
The harness owns a generic interactive terminal application (`xagent`) over a
|
|
6
6
|
persistent Pi session on a variant. It is the standalone way to use the harness, and an
|
|
7
7
|
embedding application can host it in its own PTY. Detail, screen layout and verification evidence
|
|
8
8
|
are in [`../terminal-tui.md`](../terminal-tui.md); this page states the binding parts.
|
|
@@ -24,20 +24,42 @@ Harness parent: account + compiled context + trusted resources + run writer
|
|
|
24
24
|
| launch specification / session socket
|
|
25
25
|
Harness terminal child (Bun): OpenTUI application + persistent Pi AgentSessionRuntime
|
|
26
26
|
| typed native events / plugin UI callbacks
|
|
27
|
-
Screen: transcript above the composer, centred
|
|
27
|
+
Screen: transcript above the composer, centred dialogs, full-screen resource browser
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
## Contracts
|
|
31
31
|
|
|
32
|
-
- The published executable is `
|
|
32
|
+
- The published executable is `xagent`; `xharness` is not retained as a compatibility alias. With no command, `xagent` starts the interactive terminal. `terminal` remains an explicit alias, and `serve` remains the host-facing RPC path.
|
|
33
33
|
- `TerminalAssets` is `{ node, cli, piExtension, openTui }`. The command is Bun with
|
|
34
34
|
`--conditions=browser` and `dist/terminal-opentui.js`; no global `pi` is needed.
|
|
35
35
|
- The `piExtension` path is the final prepared extension argument; the runtime loads it as the
|
|
36
36
|
final trusted inline factory.
|
|
37
37
|
- The terminal compiles its prompt once (`compile` + `render`) and keeps that pack; each run
|
|
38
38
|
records a copy (page 04).
|
|
39
|
+
- Normal mode keeps `ask_user` and `ask_user_question` out of the active tool set. A plan request
|
|
40
|
+
enables the registered question tools alongside its read-only set and restores the normal set on
|
|
41
|
+
success, failure or interruption. See page 02 and the [terminal guide](../terminal-tui.md).
|
|
39
42
|
- Standalone defaults: `~/.xingular-harness/{data,state}`; `npm run dev` uses
|
|
40
43
|
`~/.xingular-harness-dev/{data,state}`.
|
|
44
|
+
- An empty conversation shows a centered welcome using `env.productName` (default `Xingular Agent`):
|
|
45
|
+
the first letter of a multiword name is the orange block mark and its remaining words are letter-spaced
|
|
46
|
+
in blue. The welcome adds a greeting, tagline and `/help` hint without replacing the composer or
|
|
47
|
+
status bar. Explicit host product names use the same generic formatting.
|
|
48
|
+
- `xagent --worktree [name]` (`-w`) starts in a new managed worktree of the current repository,
|
|
49
|
+
or in the named one, and prunes older managed worktrees (PROP-0016). A session that names a
|
|
50
|
+
worktree holds it for its whole life. `/worktree` switches folders by asking the host to restart
|
|
51
|
+
the frontend there (`TerminalRelaunch.cwd`), as a new conversation: Pi keeps one history per
|
|
52
|
+
working folder.
|
|
53
|
+
- Slash-command aliases share one registry entry: `/session (resume)` switches saved sessions,
|
|
54
|
+
`/history (tree)` navigates branches in the current session, and `/btw (side)` asks a side
|
|
55
|
+
question through the Harness `SideQuestions` service. It uses the same account/model/effort,
|
|
56
|
+
mirrors the main run's redacted prompt and public evidence, starts a separate tool-free run, and
|
|
57
|
+
leaves the main conversation untouched. The dock streams, scrolls and copies the complete answer.
|
|
58
|
+
Aliases remain callable and searchable, but help and palette show only the canonical
|
|
59
|
+
entry. Commands owned by required built-in plugins and core terminal commands are unprefixed.
|
|
60
|
+
Optional built-in plugin and Pi extension commands use `/plugin:<command>`. A bare command or
|
|
61
|
+
prompt owns its name; a colliding `/plugin:<command>` is omitted and rejected with a hint to use
|
|
62
|
+
the bare command. Prompt templates and `/skill:<name>` otherwise keep their existing forms.
|
|
41
63
|
|
|
42
64
|
## Invariants
|
|
43
65
|
|
|
@@ -50,18 +72,29 @@ Screen: transcript above the composer, centred page dialogs
|
|
|
50
72
|
their existing layers. The terminal adds no second path for any of them; its runs are written
|
|
51
73
|
through the controller and the run store.
|
|
52
74
|
- **INV-TUI-4** Changes made through the session socket (`plugins.attach|detach|trust|untrust|configure`,
|
|
53
|
-
`accounts.*`, Hub installs
|
|
75
|
+
`accounts.*`, Hub installs, `terminal.browser.*`, `terminal.worktrees.*`,
|
|
76
|
+
`terminal.annotations.*`, `terminal.sideQuestions.*`) require the control key the trusted terminal process claimed once
|
|
54
77
|
(`control.claim`). The session's shell can read the session token, so the token alone is never
|
|
55
78
|
enough.
|
|
56
79
|
- **INV-TUI-5** Every resource reload revalidates the original trusted selection; changed or
|
|
57
80
|
revoked code needs review and a fresh terminal.
|
|
58
81
|
- **INV-TUI-6** `sessions.run` stays the embedding and unattended path. The terminal keeps a
|
|
59
82
|
persistent child instead of opening a session per turn.
|
|
83
|
+
- **INV-TUI-7** Required built-in plugin commands use their unprefixed names; optional built-in
|
|
84
|
+
plugin commands and Pi extension commands use `/plugin:<command>`. Completions and help show each
|
|
85
|
+
command in its canonical namespace. Bare core commands, aliases, required built-in commands and
|
|
86
|
+
loaded prompts reserve their names; a colliding prefixed command is hidden and rejected with a hint
|
|
87
|
+
to use the bare command. Duplicate extension names are rejected with owner diagnostics. Old
|
|
88
|
+
prefixed forms of required built-in commands are not aliases.
|
|
60
89
|
|
|
61
90
|
## Source map
|
|
62
91
|
|
|
63
92
|
`src/terminal/**`. Decisions: ADR-0001, [ADR-0004](../decisions/ADR-0004-fullscreen-terminal-layout.md)
|
|
64
|
-
(superseded), ADR-0006
|
|
93
|
+
(superseded), ADR-0006, [ADR-0021](../decisions/ADR-0021-required-command-namespaces.md),
|
|
94
|
+
[ADR-0024](../decisions/ADR-0024-xagent-command.md),
|
|
95
|
+
[ADR-0027](../decisions/ADR-0027-connected-sketch-display.md),
|
|
96
|
+
[ADR-0028](../decisions/ADR-0028-xingular-agent-product-identity.md). Experiments:
|
|
97
|
+
EXP-0001, EXP-0002 in `../experiments/`.
|
|
65
98
|
|
|
66
99
|
## Session name in the working line (PROP-0010)
|
|
67
100
|
|
|
@@ -79,3 +112,150 @@ truncate at the right edge. Manual `/name` and existing long names remain suppor
|
|
|
79
112
|
Live checks opens an explicit selection followed by account/model, destination, cost and isolation
|
|
80
113
|
confirmation. The page polls structured reports, retains findings after cancellation, and cancels
|
|
81
114
|
on close. No command text is sent to the conversation model. See [Doctor](../doctor.md).
|
|
115
|
+
|
|
116
|
+
## Resource browser (PROP-0013)
|
|
117
|
+
|
|
118
|
+
`/harness` owns shared navigation for Foundation, Variant, Skills, Plugins, Connections, Tools
|
|
119
|
+
and Library. `/skills`, `/plugins`, `/connections` (`/mcp`), `/tools`, `/hub` and `/components`
|
|
120
|
+
are shortcuts into that browser. Current availability comes from the live resource loader and
|
|
121
|
+
active tool registry, independently of saved configuration and the latest variant head.
|
|
122
|
+
|
|
123
|
+
Every `terminal.browser.*` call requires the private control key, including bounded resource
|
|
124
|
+
inspection, local imports, connection management and browser settings. Package install/remove use protected
|
|
125
|
+
`plugins.install|remove`. These are adapters to the existing services, not another loader,
|
|
126
|
+
attachment store, gate or secret store. Browsing neither executes plugin code nor connects MCP.
|
|
127
|
+
The browser uses the full terminal with persistent section tabs (PROP-0014); wide screens keep
|
|
128
|
+
inventory beside details, actions and content, while compact screens keep inline details under
|
|
129
|
+
the same tabs. Other command pages remain centered except `/settings` and `/accounts`, which use
|
|
130
|
+
full-screen page layouts. Accounts keeps Accounts/Pools tabs, search and account-service operations.
|
|
131
|
+
Wide terminals show selected-account details beside the list; Enter or a primary click opens grouped
|
|
132
|
+
actions in that inspector. Compact terminals replace the list with a full-page account detail view
|
|
133
|
+
and its grouped actions. Enter opens the selected account; Escape returns to the list while
|
|
134
|
+
preserving its section, query and selection across navigation and resizing. Tab/Shift+Tab moves focus
|
|
135
|
+
between tabs, the list and (when open) actions; Left/Right changes a focused tab and Up/Down moves
|
|
136
|
+
the focused list or action list. Account actions retain their Session, Account, Sign-in and Remove
|
|
137
|
+
groups; pool actions remain grouped under Manage and Remove. See the
|
|
138
|
+
[terminal guide](../terminal-tui.md#blocks-and-pages) for layout and interaction.
|
|
139
|
+
|
|
140
|
+
`/settings` is a full-screen page with category tabs, search, settings list and the device-local
|
|
141
|
+
Browser tab for `allowPrivate`. Enabling private address access requires confirmation and allows both
|
|
142
|
+
agent browsing and annotation capture to reach localhost and private networks. It is off by default.
|
|
143
|
+
|
|
144
|
+
## Worktrees command (PROP-0016)
|
|
145
|
+
|
|
146
|
+
`/worktree` opens a page of the managed worktrees of the repository the session works in: make a
|
|
147
|
+
managed or permanent worktree, switch the terminal to one (or back to the main checkout), create a
|
|
148
|
+
branch on a detached one, hand changes off in either direction, remove one (with a snapshot when it
|
|
149
|
+
holds work, never the one this terminal uses), restore a removed one, prune older ones, and trust
|
|
150
|
+
the repository's setup script. The page calls `terminal.worktrees.*` routes, which use the same
|
|
151
|
+
`Worktrees` service as the `worktrees.*` server methods. `xagent worktree <command>` offers the
|
|
152
|
+
same actions from a shell.
|
|
153
|
+
|
|
154
|
+
## Question dock
|
|
155
|
+
|
|
156
|
+
Pending questions appear in a flat block above the composer, with a tab for each 1–2 word question
|
|
157
|
+
label above its title. Tabs can be clicked; Left/Right also switch questions and preserve staged
|
|
158
|
+
answers. The header has no pager or collapse control, and the dock stays expanded until the answer
|
|
159
|
+
is submitted or Escape cancels the pending question. While it is active, the chat composer and its
|
|
160
|
+
lower status bar are hidden. `n` opens a note for the focused selected choice; Tab and Shift+Tab
|
|
161
|
+
navigate existing note fields, the free-text answer and the action without creating notes. Notes
|
|
162
|
+
and the “Something else” answer wrap across lines. Choice recommendations remain visual only and
|
|
163
|
+
never preselect an answer.
|
|
164
|
+
|
|
165
|
+
Every choice uses one shared measured layout: a marker gutter, a one-third label cell, a two-cell
|
|
166
|
+
gap, and the remaining description cell. Column boundaries align across all rows at every terminal
|
|
167
|
+
width, including compact widths. Text wraps within its cell; a missing description keeps its cell
|
|
168
|
+
and columns never stack. Recommendation text uses `(Rec.)` when the label column is fewer than 14
|
|
169
|
+
cells. Below 60 terminal columns, the dock uses a compact hint.
|
|
170
|
+
|
|
171
|
+
The dock body has bounded height and vertical scrolling; question tabs and answer/action controls
|
|
172
|
+
stay outside that scrolling region. PageUp/PageDown scroll the body and Ctrl+Home/End jump to its
|
|
173
|
+
beginning/end while the dock is active, rather than scrolling the transcript. Focused choices and
|
|
174
|
+
note fields are brought into view. Ordinary arrows retain question/choice navigation; Shift+arrows
|
|
175
|
+
pan the sketch horizontally or vertically.
|
|
176
|
+
|
|
177
|
+
When a question sets `uiSketch: true`, one shared border-only monospace preview below the choices
|
|
178
|
+
shows the hovered or focused choice's ASCII wireframe, with no visible caption or extra left rule.
|
|
179
|
+
Sketch source supports up to 80 columns by 24 lines (page 02) and remains literal ASCII in
|
|
180
|
+
persistence. The terminal uses a bounded structural display projection: recognized ASCII table-border
|
|
181
|
+
rows—including a title between horizontal runs—and enclosed vertical table edges become connected
|
|
182
|
+
box-drawing glyphs, while internal framed tables retain their original widths and positions. For a
|
|
183
|
+
high-confidence frame with matched `+` corners, missing or slightly displaced side edges may be
|
|
184
|
+
filled or moved only through whitespace to the established boundary columns; interior text is never
|
|
185
|
+
moved or overwritten, and conflicting or ambiguous rows remain literal. Bare standalone hyphen
|
|
186
|
+
divider rows expand to `max(panel viewport width, original sketch widest line)` and join the outer
|
|
187
|
+
single-line preview frame with `├` and `┤`. This is not a global `+|-` substitution: prose, content
|
|
188
|
+
operators, ordinary pipes and unrecognized rows remain literal. Source sketches and all persisted
|
|
189
|
+
whitespace remain unchanged; only the display projection adjusts recognized boundary cells.
|
|
190
|
+
|
|
191
|
+
There is no wrapping, reflow, truncation or markup interpretation. A bounded two-axis viewport makes
|
|
192
|
+
all overflow reachable by panning. Moving focus changes the preview without changing the staged
|
|
193
|
+
answer. Projected glyphs and expanded dividers never enter persisted events or answers; the wire
|
|
194
|
+
contract is unchanged. See [PROP-0025](proposals/PROP-0025-contextual-question-wireframes.md),
|
|
195
|
+
[ADR-0026](../decisions/ADR-0026-contextual-question-wireframes.md) and the approved display amendment
|
|
196
|
+
[PROP-0026](proposals/PROP-0026-connected-sketch-display.md) /
|
|
197
|
+
[ADR-0027](../decisions/ADR-0027-connected-sketch-display.md), and
|
|
198
|
+
[PROP-0028](proposals/PROP-0028-normalize-question-wireframes.md) /
|
|
199
|
+
[ADR-0029](../decisions/ADR-0029-normalized-question-wireframe-borders.md). Isolated production
|
|
200
|
+
PTY verification is retained in `docs/evidence/terminal-wireframe-normalization/`; it establishes
|
|
201
|
+
cell topology for bounded fixtures, not every emulator/font or live-model sketch quality.
|
|
202
|
+
|
|
203
|
+
## Page notes commands (PROP-0017)
|
|
204
|
+
|
|
205
|
+
`/plugin:notes` lists the page notes kept in the data root, with search, and offers reveal, edit, resolve or
|
|
206
|
+
reopen, share with this session or stop sharing, and delete. `/plugin:annotate [url]` starts a new note: it
|
|
207
|
+
opens a visible capture browser (its own window and profile, separate from the agent's browser), and
|
|
208
|
+
the person notes the whole page, selects text, or clicks an element there, then confirms in the
|
|
209
|
+
terminal. A note is private until shared; this session's agent then reads it with `page_notes_list`
|
|
210
|
+
and `page_notes_read`.
|
|
211
|
+
|
|
212
|
+
`/plugin:annotate` is the annotate pane (PROP-0018): a full-screen page beside the window being inspected.
|
|
213
|
+
|
|
214
|
+
- **Ways to start it:**
|
|
215
|
+
- `/plugin:annotate [url]`: the browser window
|
|
216
|
+
- `/plugin:annotate --app <DevTools address | port> [name]`: an app's own windows over its DevTools port
|
|
217
|
+
- `/plugin:annotate --bridge [name]`: app windows that load the page bridge script, which the pane shows
|
|
218
|
+
- **The inspector** (`i`) outlines components on hover. A click or a text drag opens a popover in the page with Create annotation, Ask agent to fix, and Proceed now.
|
|
219
|
+
- **Sections:** Queue, Sent and fixed (with the agent's summary), and Saved.
|
|
220
|
+
- **Other keys:** `s` sends the queue as one run of this session, confirming notes that came from a page-world script first; `x` takes a note out of the queue; `t` picks a window.
|
|
221
|
+
- **Routes:** `terminal.annotations.target|attach|windows|selectWindow|inspect|stopInspect|next|queue|dequeue|confirm|send` act only on this terminal's session and need the control key.
|
|
222
|
+
|
|
223
|
+
## Checklist (PROP-0006, PAR-001)
|
|
224
|
+
|
|
225
|
+
Terminal sessions register the shared `checklist_write` tool. The extension validates each list
|
|
226
|
+
with the same tool code and sends it as `checklist` telemetry; the controller emits it as
|
|
227
|
+
`checklist.updated` on the active run, so `runs.checklist` and continuation read terminal runs too.
|
|
228
|
+
The gate treats it as read-only, plan mode allows it, and terminal children inherit it. The
|
|
229
|
+
transcript shows each write as a checklist block (`✓` done, `●` in progress (warning yellow), `○` pending) under a
|
|
230
|
+
`Checklist · n of m done` header instead of a tool row; a failed or malformed call stays a tool row.
|
|
231
|
+
|
|
232
|
+
## Subagent activity monitor
|
|
233
|
+
|
|
234
|
+
During an active parent run, the terminal polls a private read-only monitor once per second. It
|
|
235
|
+
projects the flat set of child and nested-child runs with task, status, elapsed time, the latest
|
|
236
|
+
tool name, the child's agent profile (name and colour, PROP-0029), the title the parent gave it
|
|
237
|
+
(PROP-0030), and counts from the child's own checklist. The child's own `session_name` is not
|
|
238
|
+
projected; it names the child's session, not its row. Tool summaries, other
|
|
239
|
+
arguments, output and checklist item text never enter the monitor. The latest completed tool name
|
|
240
|
+
remains visible across one-second snapshots until new tool or response activity replaces it. The
|
|
241
|
+
monitor exposes no controls to steer or stop children.
|
|
242
|
+
|
|
243
|
+
The live rows sit under the status line, after one blank row, with no heading. Each row reads, in
|
|
244
|
+
order: the status mark (`○` queued, a running row that shows the working spinner's frame in the profile's colour (warning for a copy of the parent), `●` waiting in the accent,
|
|
245
|
+
`✓` done, `✕` failed, `!` stopped), the profile name in its colour (`subagent`, muted, for a copy
|
|
246
|
+
of the parent), the title the parent gave the child (PROP-0030), and `n of m tasks` when the child
|
|
247
|
+
keeps a checklist. Active rows come first, at most three, then `+N more · /subagents`; a narrow
|
|
248
|
+
terminal cuts the title first. `/subagents` opens the searchable full roster with the same fields.
|
|
249
|
+
Finished rows remain until the parent run settles. The projection is volatile and scoped to that
|
|
250
|
+
parent run; it is not a persisted event or public server method.
|
|
251
|
+
|
|
252
|
+
## Agent profiles (PROP-0029)
|
|
253
|
+
|
|
254
|
+
`/agents` opens the Agents page over `terminal.agents.list|create|remove`, which call the same
|
|
255
|
+
`agents/profiles.ts` functions as `agents.*`. It lists built-in, global, project and variant
|
|
256
|
+
profiles, and files that cannot be read. The detail pane shows the colour, description, tools,
|
|
257
|
+
plugins, variant, model, effort, file and instructions. Enter on a row offers: for a person's own
|
|
258
|
+
profile, edit (opens the file in `$VISUAL`/`$EDITOR` with the renderer suspended), copy and delete
|
|
259
|
+
(confirmed); for a built-in or variant profile, copy. New profile asks for a name and a place
|
|
260
|
+
(project or global), writes the template and opens it. The terminal passes its pinned variant to
|
|
261
|
+
`Subagents.register`, so the variant's c5 names are profiles there too.
|
|
@@ -16,6 +16,7 @@ index.
|
|
|
16
16
|
refine/<id>/ summary.json, task.json, variants/, rollouts/, sessions/, context/, selection/, reflection/, improver/, or matrix.json + suite.json for evaluation matrices (05)
|
|
17
17
|
rollouts/<label>/workspace/ only when started with retainWorkspaces
|
|
18
18
|
library/<scope>/<area>/ INDEX.md, variants/<task>/{variant/, EXPERIENCE.md} (05)
|
|
19
|
+
annotations/<id>.json page notes (13, PROP-0017)
|
|
19
20
|
wiki/ home.md, library/ (library/lessons/ from the lessons plugin), projects/<slug>/ (08)
|
|
20
21
|
reflection/improver/lesson-<run id>/ a reflection's native history and reply (08)
|
|
21
22
|
wiki-history/ earlier versions of notes (08)
|
|
@@ -26,6 +27,7 @@ index.
|
|
|
26
27
|
hub/ installed documents and provenance (09)
|
|
27
28
|
runs/<id>/ run.json, events.jsonl, owner.json, subagents.json, context.json, caller.json, capabilities.json, mcp-context.json (02)
|
|
28
29
|
config/ plugin-attachments.json and settings the harness reads (06)
|
|
30
|
+
agents/<name>.md a person's global agent profiles; agents/profiles.ts owns it (02, PROP-0029)
|
|
29
31
|
index.sqlite derived index (FTS5) (08)
|
|
30
32
|
projects.json read only: the application owns it
|
|
31
33
|
|
|
@@ -36,10 +38,20 @@ index.
|
|
|
36
38
|
plugin-trust.json, variant-plugin-trust.json, plugin-registered.json, plugin-hooks.json (03, 06)
|
|
37
39
|
connections.json connected apps, no secrets (09)
|
|
38
40
|
hub/catalog.json catalog cache (09)
|
|
39
|
-
run/
|
|
41
|
+
run/ terminal commands, and one session socket per Harness process,
|
|
42
|
+
harness-<pid>-<random>.sock; files of ended processes are pruned (11)
|
|
43
|
+
worktrees.json managed worktree registry (02, PROP-0016)
|
|
44
|
+
worktrees/<repo>/<name>/ managed worktree checkouts; worktrees/logs/ setup output (PROP-0016)
|
|
45
|
+
worktree-setup-trust.json trusted setup-script hashes, owner-only (PROP-0016)
|
|
46
|
+
browser/ isolated browser settings and profiles (13)
|
|
47
|
+
notes-bridge.json the page bridge's port and token, kept so an app's script tag stays valid (13, PROP-0018)
|
|
40
48
|
harness.log standalone terminal diagnostics
|
|
41
49
|
```
|
|
42
50
|
|
|
51
|
+
Side-question runs use the ordinary `runs/<id>/` records. Their temporary Pi native history is
|
|
52
|
+
created under the operating system temporary directory and removed when the run ends; it is not
|
|
53
|
+
retained in the data root or state directory.
|
|
54
|
+
|
|
43
55
|
## Invariants
|
|
44
56
|
|
|
45
57
|
- **INV-STO-1** Device-local state (credentials, approvals, trust, connections, sockets) is never
|
|
@@ -50,6 +62,8 @@ index.
|
|
|
50
62
|
through that module's functions. A new top-level folder or a new file in `runs/<id>/` is an
|
|
51
63
|
architecture change.
|
|
52
64
|
- **INV-STO-4** `projects.json` belongs to the application; the harness only reads it.
|
|
65
|
+
Project agent profiles live in the repository at `<project>/.xingular/agents/<name>.md`; the
|
|
66
|
+
harness writes them only through `agents.create` and `agents.remove` (PROP-0029).
|
|
53
67
|
- **INV-STO-5** Migrations of stored data are one-way and safe: the old data is backed up or left
|
|
54
68
|
as it was when a migration fails, and the failure is reported in `Recovery.migrationError`.
|
|
55
69
|
- **INV-STO-6** Writes of shared JSON files are atomic (`core/fs.ts::atomicWrite`, `writeJson`).
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# 13 World tools
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
The Foundation owns the generic isolated browser engine, per-session contexts and profiles,
|
|
4
|
+
network policy, and lifecycle. Built-in World plugins contribute the user-facing web search/page
|
|
5
|
+
tools, browser tools and annotations through the existing tool-provider surface. Every tool passes
|
|
6
|
+
the same capability and policy gate. Web requests use the public-address guard; browser requests
|
|
7
|
+
use the device-local private-address setting. Read page content is untrusted. Sending, purchasing,
|
|
8
|
+
deleting, changing accounts and granting access require explicit human approval. Sensitive fields
|
|
9
|
+
are not filled by the agent.
|
|
8
10
|
|
|
9
11
|
The App owns its shared WebKit browser UI, private/shared tab policy, selected-file uploads,
|
|
10
12
|
windows and the native computer bridge. These application objects do not enter the Harness.
|
|
@@ -16,8 +18,28 @@ synthetic page. Their input runs only after live-check confirmation, and their r
|
|
|
16
18
|
released on completion, timeout or cancellation. Computer interaction needs a host-provided
|
|
17
19
|
isolated surface; without one it is blocked.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
Plugin ownership and the Foundation boundary are recorded in PROP-0012, ADR-0014 and PROP-0020.
|
|
22
|
+
World providers are assembled through `BuiltinPluginRegistry`; no eighth extension point is added.
|
|
20
23
|
|
|
21
24
|
An embedding host may set `browser: false` to disable the generic backend and its plugin
|
|
22
25
|
descriptor before supplying its own browser tool provider. The App uses this option for its
|
|
23
26
|
shared-tab browser, so matching tool names never silently select the wrong backend.
|
|
27
|
+
|
|
28
|
+
## Page notes (PROP-0017)
|
|
29
|
+
|
|
30
|
+
The `annotations` world part offers `page_notes_list` and `page_notes_read`, read-only, to SDK and
|
|
31
|
+
terminal sessions. It is separate from the browser part, so a host that sets `browser: false` keeps
|
|
32
|
+
it. A tool returns only notes a person shared with the calling session or agent; quoted page text
|
|
33
|
+
and element names are marked untrusted. Capture happens in a visible capture browser in the
|
|
34
|
+
terminal, or in a host's own web view running the same page helper (`annotations.pageScript`).
|
|
35
|
+
|
|
36
|
+
**Inspector, queue and app targets (PROP-0018).**
|
|
37
|
+
|
|
38
|
+
- **Inspector.** In the page helper's inspector, hovering outlines a component and a click (or a drag over text) opens a comment popover inside the page, with three choices: save, queue for the agent, or send now.
|
|
39
|
+
- A queued note is shared with its session.
|
|
40
|
+
- `annotations/delivery.ts` sends a batch as one instruction, and sends notes the person asked for while the session was busy when its run ends.
|
|
41
|
+
- The agent reports a fix with `page_notes_mark_fixed`, the only page-note tool that writes. It never resolves a note or changes grants.
|
|
42
|
+
- **Targets.** Besides the browser window, capture can use an app's own windows:
|
|
43
|
+
- **DevTools port:** an app started with a DevTools port, on a loopback address only. It uses the app's existing windows, routes nothing, and never closes the app.
|
|
44
|
+
- **Page bridge:** a loopback server whose script an app loads while it is developed (`annotations/bridge.ts`), for web views without a DevTools port.
|
|
45
|
+
- **Trust.** In Chromium targets the helper runs in an isolated script world, so the page cannot forge a comment. A send from the bridge, or from a host web view without isolation, waits for the person to confirm it.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# 14 Surfaces and parity
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
The harness has more than one front end: its own standalone terminal (`xagent`, page 11) and
|
|
6
|
+
every application that embeds it. This page fixes how capabilities relate to those front ends, so
|
|
7
|
+
that a person can do the same work in the terminal and in a host, and so that a reader knows that
|
|
8
|
+
a capability is Harness work even when a request names a host.
|
|
9
|
+
|
|
10
|
+
A *capability* is something a person or a model can do: start a session, approve a call, work in
|
|
11
|
+
a worktree, annotate a page, inspect a run. A *surface* is how one front end presents it: a
|
|
12
|
+
terminal command or page, a host screen.
|
|
13
|
+
|
|
14
|
+
## Components
|
|
15
|
+
|
|
16
|
+
| Kind | What it is | Example |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| Foundation service | A member of `Harness` with server methods | `sessions`, `accounts`, `apps`, `worktrees` (PROP-0016), agent profiles (`agents.*`, PROP-0029) |
|
|
19
|
+
| Built-in feature plugin | A module in `BuiltinPluginRegistry` (`plugins/builtin.ts`) that may supply a `WorldPart`, server methods and terminal commands | web tools, browser tools, annotations, worktrees |
|
|
20
|
+
| First-party plugin | A descriptor in the registry (`plugins/builtin.ts`) | lessons, checklist |
|
|
21
|
+
| Terminal surface | A command, page or dialog in `terminal/` | `/plan`, `/doctor`, the resource browser |
|
|
22
|
+
| Host surface | A host screen built on the same methods and tools | the App's chat, Capability and Harness screens |
|
|
23
|
+
| Host-backed backend | An operating-system object only a host has, behind a generic Harness contract | the App's WebKit tabs, macOS computer bridge, keychain |
|
|
24
|
+
| Host-only surface | Presentation a terminal cannot show (INV-PAR-4) | reserved: interactive agent output ("OpenUI") |
|
|
25
|
+
|
|
26
|
+
## Contracts
|
|
27
|
+
|
|
28
|
+
- A capability is reachable through server methods (page 10) and, where a model uses it, through a
|
|
29
|
+
tool that passes the gate (page 07). Both front ends use the same methods; neither has a private
|
|
30
|
+
path to Harness state.
|
|
31
|
+
- Required built-in plugin commands and Foundation commands use unprefixed names. Optional built-in
|
|
32
|
+
plugin commands and Pi extension commands use `/plugin:<command>`. A bare command, alias or loaded
|
|
33
|
+
prompt owns its name; a colliding prefixed command is hidden and rejected. Built-in plugin
|
|
34
|
+
categories are documented in page 06 and are not public plugin metadata.
|
|
35
|
+
- A capability may be limited to a run mode when Harness resolves the callable set; the register
|
|
36
|
+
records that restriction for both surfaces. `ask_user` is available only in attended plan runs,
|
|
37
|
+
and the terminal's `ask_user_question` alias follows the same restriction.
|
|
38
|
+
- Question choice sketches use one optional validated event contract: up to 80 printable ASCII
|
|
39
|
+
columns by 24 LF-separated lines (1,943 bytes maximum; page 02). Both surfaces use the same
|
|
40
|
+
literal ASCII source, persisted unchanged, in one shared preview with access to overflow; neither
|
|
41
|
+
changes the answer payload (PROP-0025, ADR-0026; originally PROP-0024). The terminal may project
|
|
42
|
+
recognized ASCII table-border rows—including title-bearing rules—and enclosed vertical table
|
|
43
|
+
edges into connected box-drawing glyphs, retaining internal framed table widths. For a
|
|
44
|
+
high-confidence frame, it may fill a missing boundary cell or realign a displaced edge only
|
|
45
|
+
through whitespace to matched corner columns; interior text and ambiguous rows remain unchanged
|
|
46
|
+
(PROP-0028, ADR-0029). Bare standalone hyphen dividers expand to the larger of viewport width and
|
|
47
|
+
original sketch widest line and join the outer single-line frame with `├` and `┤` (PROP-0026,
|
|
48
|
+
ADR-0027). Prose, content operators and ordinary pipes are not globally substituted. Hosts may
|
|
49
|
+
retain literal ASCII previews: equivalent capability does not require identical structural
|
|
50
|
+
typography. No schema, validation-bound, persistence or answer-payload change follows from these
|
|
51
|
+
display amendments. Terminal geometry, scrolling and projection boundaries follow page 11; hosts
|
|
52
|
+
may use native presentation without narrowing accepted metadata. Existing hosts with the old
|
|
53
|
+
bounds must update before accepting larger sketches. Acceptance of the expanded contract on both
|
|
54
|
+
surfaces is tracked in the parity register. Isolated production PTY evidence verifies bounded
|
|
55
|
+
fixture topology, not every emulator/font or live-model sketch quality.
|
|
56
|
+
- Side questions use one Harness service on both surfaces. Each caller supplies its visible
|
|
57
|
+
transcript projection; Harness adds the parent run's effective prompt and public events, then
|
|
58
|
+
starts an independent tool-free run.
|
|
59
|
+
- The register of capabilities and their surfaces is [`docs/parity.md`](../parity.md). It is
|
|
60
|
+
descriptive; the invariants below are binding.
|
|
61
|
+
- A host keeps its own register of host-only surfaces. The Harness names no host surface.
|
|
62
|
+
|
|
63
|
+
## Invariants
|
|
64
|
+
|
|
65
|
+
- **INV-PAR-1** Every capability a person can use in a host is a Harness capability: a foundation
|
|
66
|
+
service, a world part or a first-party plugin, reachable through server methods. The standalone
|
|
67
|
+
terminal surfaces it. A host is a presentation of it.
|
|
68
|
+
- **INV-PAR-2** A capability is complete only when its terminal surface and its host surface both
|
|
69
|
+
pass acceptance. It lands in the Harness first, together with its terminal surface; the host
|
|
70
|
+
surface follows.
|
|
71
|
+
- **INV-PAR-3** A host-backed capability needs an operating-system object only a host has. The
|
|
72
|
+
Harness defines the generic contract and a terminal fallback (for example the headed isolated
|
|
73
|
+
browser for page annotations). Without a fallback, the terminal shows the capability as
|
|
74
|
+
unavailable, with the reason, in `/doctor` and `/tools`.
|
|
75
|
+
- **INV-PAR-4** A host-only surface owns no capability. Its actions are Harness methods or tools,
|
|
76
|
+
its data lives in Harness records, the terminal renders a text fallback, and each one is listed
|
|
77
|
+
in the host's register by an owner decision. A generic rich-output event kind for such surfaces
|
|
78
|
+
needs its own proposal; the name is reserved and nothing is designed.
|
|
79
|
+
|
|
80
|
+
## Data
|
|
81
|
+
|
|
82
|
+
None of its own. Each capability stores its data as its own page says.
|
|
83
|
+
|
|
84
|
+
## Source map
|
|
85
|
+
|
|
86
|
+
`src/harness.ts` (services), `src/world/world.ts` (world parts), `src/plugins/builtin.ts`
|
|
87
|
+
(first-party descriptors), `src/terminal/` (terminal surfaces), `src/server/methods.ts` (methods).
|
|
88
|
+
Decision: [PROP-0015](proposals/PROP-0015-one-capability-surface.md),
|
|
89
|
+
[ADR-0017](../decisions/ADR-0017-one-capability-surface.md).
|