@xingular/harness 1.0.0 → 1.2.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.
- package/CHANGELOG.md +46 -5
- package/README.md +75 -21
- package/dist/cli.js +17421 -8711
- package/dist/sdk/accounts/accounts.d.ts +27 -3
- package/dist/sdk/accounts/accounts.js +78 -24
- package/dist/sdk/accounts/secrets.d.ts +12 -0
- package/dist/sdk/accounts/secrets.js +114 -7
- package/dist/sdk/accounts/store.d.ts +26 -1
- package/dist/sdk/accounts/store.js +1 -1
- package/dist/sdk/agents/builtin.d.ts +2 -0
- package/dist/sdk/agents/builtin.js +48 -0
- package/dist/sdk/agents/narrow.d.ts +13 -0
- package/dist/sdk/agents/narrow.js +29 -0
- package/dist/sdk/agents/planResearch.d.ts +5 -0
- package/dist/sdk/agents/planResearch.js +19 -0
- package/dist/sdk/agents/profiles.d.ts +81 -0
- package/dist/sdk/agents/profiles.js +226 -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 +871 -0
- package/dist/sdk/annotations/part.d.ts +10 -0
- package/dist/sdk/annotations/part.js +155 -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 +167 -0
- package/dist/sdk/annotations/store.js +394 -0
- package/dist/sdk/browser/backend.d.ts +16 -0
- package/dist/sdk/browser/backend.js +17 -0
- package/dist/sdk/browser/contracts.d.ts +19 -0
- package/dist/sdk/browser/contracts.js +116 -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/browser/tools.d.ts +1 -4
- package/dist/sdk/browser/tools.js +14 -91
- package/dist/sdk/cli.js +24 -15
- package/dist/sdk/commands/list.d.ts +3 -0
- package/dist/sdk/commands/list.js +75 -0
- package/dist/sdk/commands/registry.d.ts +250 -0
- package/dist/sdk/commands/registry.js +47 -0
- package/dist/sdk/commands/routes.d.ts +16 -0
- package/dist/sdk/commands/routes.js +33 -0
- package/dist/sdk/core/bus.js +1 -1
- package/dist/sdk/core/commandBudget.d.ts +23 -0
- package/dist/sdk/core/commandBudget.js +57 -0
- package/dist/sdk/core/env.d.ts +1 -1
- package/dist/sdk/core/env.js +1 -1
- package/dist/sdk/core/index.js +17 -1
- package/dist/sdk/core/interactiveProfile.d.ts +46 -0
- package/dist/sdk/core/interactiveProfile.js +143 -0
- package/dist/sdk/core/workspace.d.ts +13 -0
- package/dist/sdk/core/workspace.js +88 -0
- package/dist/sdk/core/workspaceBashTool.d.ts +4 -0
- package/dist/sdk/core/workspaceBashTool.js +36 -0
- package/dist/sdk/core/workspaceSandbox.d.ts +31 -0
- package/dist/sdk/core/workspaceSandbox.js +320 -0
- package/dist/sdk/core/workspaceWriteOperations.d.ts +22 -0
- package/dist/sdk/core/workspaceWriteOperations.js +206 -0
- package/dist/sdk/doctor/serverMethods.d.ts +3 -0
- package/dist/sdk/doctor/serverMethods.js +8 -0
- package/dist/sdk/doctor/types.d.ts +2 -2
- package/dist/sdk/harness.d.ts +22 -0
- package/dist/sdk/harness.js +84 -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 +16 -1
- package/dist/sdk/index.js +10 -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/pi/runtime.d.ts +2 -1
- package/dist/sdk/pi/runtime.js +2 -2
- package/dist/sdk/plugins/builtin.d.ts +1 -0
- package/dist/sdk/plugins/builtin.js +145 -33
- package/dist/sdk/plugins/builtinRegistry.d.ts +60 -0
- package/dist/sdk/plugins/builtinRegistry.js +71 -0
- package/dist/sdk/plugins/catalogue.js +2 -1
- package/dist/sdk/plugins/cli.d.ts +1 -1
- package/dist/sdk/plugins/cli.js +4 -3
- package/dist/sdk/plugins/commandPrefix.d.ts +8 -0
- package/dist/sdk/plugins/commandPrefix.js +21 -0
- package/dist/sdk/plugins/firstParty.d.ts +1 -1
- package/dist/sdk/plugins/firstParty.js +8 -2
- package/dist/sdk/plugins/inventory.js +4 -3
- package/dist/sdk/plugins/manifest.d.ts +2 -0
- package/dist/sdk/plugins/manifest.js +2 -1
- package/dist/sdk/plugins/surfaces.d.ts +5 -0
- package/dist/sdk/plugins/surfaces.js +11 -0
- package/dist/sdk/plugins/types.d.ts +15 -0
- package/dist/sdk/prompt/compile.d.ts +19 -2
- package/dist/sdk/prompt/compile.js +79 -26
- package/dist/sdk/prompt/standard.d.ts +17 -0
- package/dist/sdk/prompt/standard.js +21 -0
- 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 +27 -86
- package/dist/sdk/server/params.d.ts +4 -0
- package/dist/sdk/server/params.js +11 -0
- package/dist/sdk/server/remote.js +36 -11
- package/dist/sdk/sessions/compactionCheckpoint.d.ts +11 -0
- package/dist/sdk/sessions/compactionCheckpoint.js +79 -0
- package/dist/sdk/sessions/continuation.d.ts +3 -0
- package/dist/sdk/sessions/continuation.js +5 -1
- package/dist/sdk/sessions/contracts.d.ts +185 -0
- package/dist/sdk/sessions/contracts.js +101 -4
- package/dist/sdk/sessions/control.d.ts +72 -0
- package/dist/sdk/sessions/control.js +158 -0
- package/dist/sdk/sessions/initialBash.d.ts +7 -0
- package/dist/sdk/sessions/initialBash.js +7 -0
- package/dist/sdk/sessions/planMode.d.ts +18 -4
- package/dist/sdk/sessions/planMode.js +82 -16
- package/dist/sdk/sessions/reasoningSummaries.d.ts +2 -2
- package/dist/sdk/sessions/reasoningSummaries.js +3 -3
- package/dist/sdk/sessions/registry.d.ts +2 -1
- package/dist/sdk/sessions/registry.js +6 -3
- package/dist/sdk/sessions/runIndex.js +7 -7
- package/dist/sdk/sessions/runStore.d.ts +14 -0
- package/dist/sdk/sessions/runStore.js +38 -1
- package/dist/sdk/sessions/runner.d.ts +40 -2
- package/dist/sdk/sessions/runner.js +163 -15
- package/dist/sdk/sessions/sessions.d.ts +40 -8
- package/dist/sdk/sessions/sessions.js +279 -27
- 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 +22 -2
- package/dist/sdk/sessions/subagentService.js +93 -16
- package/dist/sdk/sessions/subagents.d.ts +9 -1
- package/dist/sdk/sessions/subagents.js +19 -0
- package/dist/sdk/sessions/workSlice.d.ts +103 -0
- package/dist/sdk/sessions/workSlice.js +297 -0
- package/dist/sdk/sessions/workspaceBoundary.d.ts +15 -0
- package/dist/sdk/sessions/workspaceBoundary.js +46 -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 +187 -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 +15 -1
- package/dist/sdk/terminal/controller.js +67 -8
- package/dist/sdk/terminal/opentui/subagentsWidget.d.ts +28 -0
- package/dist/sdk/terminal/opentui/subagentsWidget.js +52 -0
- package/dist/sdk/terminal/opentui/theme.d.ts +43 -0
- package/dist/sdk/terminal/opentui/theme.js +87 -0
- package/dist/sdk/terminal/piExtension.d.ts +6 -1
- package/dist/sdk/terminal/piExtension.js +169 -84
- package/dist/sdk/terminal/socket.d.ts +6 -3
- package/dist/sdk/terminal/socket.js +40 -9
- package/dist/sdk/terminal/standalone.d.ts +9 -0
- package/dist/sdk/terminal/standalone.js +118 -19
- package/dist/sdk/terminal/subagentMonitor.d.ts +47 -0
- package/dist/sdk/terminal/subagentMonitor.js +152 -0
- package/dist/sdk/terminal/terminals.d.ts +60 -7
- package/dist/sdk/terminal/terminals.js +598 -47
- 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 +7 -1
- package/dist/sdk/terminal/tui/commandPages.js +57 -6
- package/dist/sdk/terminal/tui/commands.d.ts +10 -4
- package/dist/sdk/terminal/tui/commands.js +269 -65
- 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/list.d.ts +14 -1
- package/dist/sdk/terminal/tui/list.js +96 -14
- 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 +27 -7
- 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/pluginsPage.d.ts +0 -5
- package/dist/sdk/terminal/tui/pages/pluginsPage.js +9 -3
- 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 +24 -0
- package/dist/sdk/terminal/tui/pages/subagentsPage.js +152 -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/usagePage.d.ts +43 -0
- package/dist/sdk/terminal/tui/pages/usagePage.js +370 -0
- 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/piAdapter.d.ts +1 -2
- package/dist/sdk/terminal/tui/piAdapter.js +3 -5
- 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 +16 -0
- package/dist/sdk/terminal/tui/pluginCommands.js +31 -0
- package/dist/sdk/terminal/tui/questions.d.ts +2 -0
- package/dist/sdk/terminal/tui/runtime.js +27 -5
- package/dist/sdk/terminal/tui/sessionPicker.d.ts +40 -0
- package/dist/sdk/terminal/tui/sessionPicker.js +141 -0
- 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 +3 -2
- package/dist/sdk/tools/checkpoint.d.ts +27 -0
- package/dist/sdk/tools/checkpoint.js +154 -0
- package/dist/sdk/tools/getCapabilities.d.ts +31 -0
- package/dist/sdk/tools/getCapabilities.js +34 -0
- package/dist/sdk/tools/harnessTools.d.ts +2 -0
- package/dist/sdk/tools/harnessTools.js +1 -1
- package/dist/sdk/tools/spawnSubagent.js +14 -4
- package/dist/sdk/usage/analytics.d.ts +20 -0
- package/dist/sdk/usage/analytics.js +151 -0
- package/dist/sdk/usage/ledger.d.ts +38 -0
- package/dist/sdk/usage/ledger.js +142 -0
- package/dist/sdk/usage/limits/adapters.d.ts +11 -0
- package/dist/sdk/usage/limits/adapters.js +349 -0
- package/dist/sdk/usage/limits/capture.d.ts +8 -0
- package/dist/sdk/usage/limits/capture.js +47 -0
- package/dist/sdk/usage/limits/http.d.ts +12 -0
- package/dist/sdk/usage/limits/http.js +51 -0
- package/dist/sdk/usage/limits/normalize.d.ts +15 -0
- package/dist/sdk/usage/limits/normalize.js +211 -0
- package/dist/sdk/usage/limits/service.d.ts +30 -0
- package/dist/sdk/usage/limits/service.js +176 -0
- package/dist/sdk/usage/limits/types.d.ts +65 -0
- package/dist/sdk/usage/limits/types.js +1 -0
- package/dist/sdk/usage/serverMethods.d.ts +3 -0
- package/dist/sdk/usage/serverMethods.js +22 -0
- package/dist/sdk/usage/service.d.ts +32 -0
- package/dist/sdk/usage/service.js +66 -0
- package/dist/sdk/usage/settings.d.ts +7 -0
- package/dist/sdk/usage/settings.js +28 -0
- package/dist/sdk/usage/types.d.ts +60 -0
- package/dist/sdk/usage/types.js +4 -0
- 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 +16456 -5966
- package/dist/terminal-pi.js +1579 -573
- package/docs/README.md +22 -2
- package/docs/architecture/00-overview.md +28 -16
- package/docs/architecture/02-sessions-and-runs.md +184 -25
- package/docs/architecture/03-variants.md +10 -2
- package/docs/architecture/04-prompt.md +65 -7
- package/docs/architecture/06-plugins-and-capabilities.md +57 -4
- package/docs/architecture/07-tools-and-gate.md +112 -17
- package/docs/architecture/08-memory-and-history.md +4 -2
- package/docs/architecture/09-accounts-and-connectors.md +39 -1
- package/docs/architecture/10-server-protocol.md +168 -4
- package/docs/architecture/11-terminal.md +251 -8
- package/docs/architecture/12-storage.md +45 -3
- package/docs/architecture/13-world-tools.md +49 -6
- package/docs/architecture/14-surfaces-and-parity.md +136 -0
- package/docs/architecture/README.md +17 -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 +131 -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/PROP-0031-plugin-command-owner-namespaces.md +54 -0
- package/docs/architecture/proposals/PROP-0032-planning-quality.md +196 -0
- package/docs/architecture/proposals/PROP-0033-compaction-plan-checkpoints.md +75 -0
- package/docs/architecture/proposals/PROP-0034-conversation-fast-mode.md +120 -0
- package/docs/architecture/proposals/PROP-0035-retain-subagent-status.md +47 -0
- package/docs/architecture/proposals/PROP-0036-first-class-harness-commands.md +59 -0
- package/docs/architecture/proposals/PROP-0037-workspace-write-boundary.md +63 -0
- package/docs/architecture/proposals/PROP-0038-annotate-open-shadow-roots.md +73 -0
- package/docs/architecture/proposals/PROP-0039-workspace-boundary-hardening.md +139 -0
- package/docs/architecture/proposals/PROP-0040-one-launch-path.md +87 -0
- package/docs/architecture/proposals/PROP-0041-bounded-work-slices.md +247 -0
- package/docs/architecture/proposals/PROP-0042-usage-and-provider-limits.md +127 -0
- package/docs/architecture/proposals/PROP-0043-read-only-plan-bash.md +74 -0
- package/docs/architecture/proposals/README.md +39 -0
- package/docs/decisions/ADR-0001-owned-terminal.md +1 -1
- 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/decisions/ADR-0031-plugin-command-owner-namespaces.md +37 -0
- package/docs/decisions/ADR-0032-compaction-run-checkpoints.md +33 -0
- package/docs/decisions/ADR-0033-plan-mode-research-delegation.md +47 -0
- package/docs/decisions/ADR-0034-first-class-harness-terminal-commands.md +25 -0
- package/docs/decisions/ADR-0035-one-launch-path.md +40 -0
- package/docs/decisions/ADR-0036-workspace-write-operation-boundary.md +54 -0
- package/docs/decisions/ADR-0037-usage-ledger-and-provider-limits.md +44 -0
- package/docs/decisions/ADR-0038-plan-bash-os-read-only.md +29 -0
- package/docs/doctor.md +10 -4
- package/docs/experiments/EXP-0003-performance-audit/data/session-runtime-replication.json +420 -0
- package/docs/experiments/EXP-0003-performance-audit/data/session-runtime.json +420 -0
- package/docs/experiments/EXP-0003-performance-audit/data/terminal-compact.json +376 -0
- package/docs/experiments/EXP-0003-performance-audit/data/terminal-history.json +422 -0
- package/docs/experiments/EXP-0003-performance-audit/data/terminal-question.json +95 -0
- package/docs/experiments/EXP-0003-performance-audit/data/terminal-wide.json +1036 -0
- package/docs/experiments/EXP-0003-performance-audit/plan.md +109 -0
- package/docs/experiments/EXP-0003-performance-audit/results.md +151 -0
- package/docs/features/README.md +26 -0
- package/docs/features/interfaces/README.md +1 -1
- package/docs/future-work.md +48 -0
- package/docs/handoff-2026-10-25-app-parity-and-solo-tabs.md +202 -0
- package/docs/parity.md +134 -0
- package/docs/releases/1.0.0.md +2 -2
- package/docs/releases/1.1.1.md +28 -0
- package/docs/releases/1.2.0.md +49 -0
- package/docs/releases/4.0.0.md +47 -0
- package/docs/releases/README.md +37 -27
- package/docs/study/00-index.md +8 -0
- package/docs/study/STUDY-0003-long-horizon-runs.md +210 -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 +386 -113
- package/package.json +6 -5
|
@@ -5,28 +5,51 @@ import { appendFileSync } from 'node:fs';
|
|
|
5
5
|
import { homedir } from 'node:os';
|
|
6
6
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
7
7
|
import { setLogSink } from "../core/bus.js";
|
|
8
|
+
import { DEFAULT_PRODUCT_NAME } from "../core/env.js";
|
|
9
|
+
import { interactiveProfileSecretStore, resolveInteractiveProfile } from "../core/interactiveProfile.js";
|
|
8
10
|
import { createHarness } from "../harness.js";
|
|
11
|
+
import { seedVariant } from "../variant/seed.js";
|
|
12
|
+
import * as variantStore from "../variant/store.js";
|
|
9
13
|
export function standaloneArguments(argv) {
|
|
10
14
|
const command = argv[0];
|
|
11
|
-
if (!command || command.startsWith('
|
|
15
|
+
if (!command || command.startsWith('-'))
|
|
12
16
|
return argv;
|
|
13
17
|
return command === 'terminal' ? argv.slice(1) : null;
|
|
14
18
|
}
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const paths = {
|
|
18
|
-
dataRoot: join(root, 'data'),
|
|
19
|
-
stateDir: join(root, 'state')
|
|
20
|
-
};
|
|
19
|
+
function resolveStandaloneOptions(argv, home = homedir(), cwd = process.cwd()) {
|
|
20
|
+
const overrides = {};
|
|
21
21
|
const given = new Set();
|
|
22
|
+
let worktree;
|
|
23
|
+
let variant;
|
|
22
24
|
for (let index = 0; index < argv.length; index += 1) {
|
|
23
25
|
const argument = argv[index];
|
|
26
|
+
if (argument === '--worktree' || argument === '-w') {
|
|
27
|
+
const name = argv[index + 1];
|
|
28
|
+
if (name && !name.startsWith('-')) {
|
|
29
|
+
worktree = name;
|
|
30
|
+
index += 1;
|
|
31
|
+
}
|
|
32
|
+
else
|
|
33
|
+
worktree = true;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (argument === '--variant') {
|
|
37
|
+
const scope = argv[index + 1];
|
|
38
|
+
if (!scope || scope.startsWith('-'))
|
|
39
|
+
throw new Error('--variant needs a variant scope.');
|
|
40
|
+
variant = scope;
|
|
41
|
+
index += 1;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
24
44
|
if (argument !== '--data' && argument !== '--state')
|
|
25
45
|
throw new Error(`Unknown standalone option: ${argument}`);
|
|
26
46
|
const value = argv[index + 1];
|
|
27
47
|
if (!value || value.startsWith('--'))
|
|
28
48
|
throw new Error(`${argument} needs a directory path.`);
|
|
29
|
-
|
|
49
|
+
if (argument === '--data')
|
|
50
|
+
overrides.dataRoot = resolve(cwd, value);
|
|
51
|
+
else
|
|
52
|
+
overrides.stateDir = resolve(cwd, value);
|
|
30
53
|
given.add(argument);
|
|
31
54
|
index += 1;
|
|
32
55
|
}
|
|
@@ -35,7 +58,49 @@ export function parseStandaloneOptions(argv, home = homedir(), cwd = process.cwd
|
|
|
35
58
|
if (!isAbsolute(home) && !(given.has('--data') && given.has('--state'))) {
|
|
36
59
|
throw new Error(`The home folder "${home}" is not an absolute path, so the default data and state folders cannot be placed. Set HOME to your home folder, or pass --data and --state with absolute folders.`);
|
|
37
60
|
}
|
|
38
|
-
|
|
61
|
+
// `npm run dev` passes these roots explicitly. Keep its profile and credentials separate from
|
|
62
|
+
// the installed interactive profile, even when that production profile selects a host store.
|
|
63
|
+
const devRoot = isAbsolute(home) ? join(home, '.xingular-harness-dev') : null;
|
|
64
|
+
const devData = devRoot ? join(devRoot, 'data') : null;
|
|
65
|
+
const devState = devRoot ? join(devRoot, 'state') : null;
|
|
66
|
+
const development = !!devRoot && (overrides.dataRoot === devData || overrides.stateDir === devState);
|
|
67
|
+
const resolvedProfile = isAbsolute(home)
|
|
68
|
+
? resolveInteractiveProfile({
|
|
69
|
+
home,
|
|
70
|
+
...(development ? {
|
|
71
|
+
configPath: join(devRoot, 'profile.json'),
|
|
72
|
+
legacyDefaults: {
|
|
73
|
+
dataRoot: devData,
|
|
74
|
+
stateDir: devState,
|
|
75
|
+
defaultVariantScope: 'default',
|
|
76
|
+
secretBackend: { kind: 'file', path: join(devState, 'secrets.json') }
|
|
77
|
+
}
|
|
78
|
+
} : {}),
|
|
79
|
+
overrides
|
|
80
|
+
})
|
|
81
|
+
: {
|
|
82
|
+
version: 1,
|
|
83
|
+
dataRoot: overrides.dataRoot,
|
|
84
|
+
stateDir: overrides.stateDir,
|
|
85
|
+
defaultVariantScope: 'default',
|
|
86
|
+
secretBackend: { kind: 'file', path: join(overrides.stateDir, 'secrets.json') }
|
|
87
|
+
};
|
|
88
|
+
// The standalone development launch has no host adapter and must not use the App's Keychain.
|
|
89
|
+
const profile = development
|
|
90
|
+
? { ...resolvedProfile, secretBackend: { kind: 'file', path: join(resolvedProfile.stateDir, 'secrets.json') } }
|
|
91
|
+
: resolvedProfile;
|
|
92
|
+
return {
|
|
93
|
+
profile,
|
|
94
|
+
paths: {
|
|
95
|
+
dataRoot: profile.dataRoot,
|
|
96
|
+
stateDir: profile.stateDir,
|
|
97
|
+
...(worktree !== undefined ? { worktree } : {}),
|
|
98
|
+
...(variant !== undefined ? { variant } : {})
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function parseStandaloneOptions(argv, home = homedir(), cwd = process.cwd()) {
|
|
103
|
+
return resolveStandaloneOptions(argv, home, cwd).paths;
|
|
39
104
|
}
|
|
40
105
|
function processEnvironment(overrides) {
|
|
41
106
|
const environment = { ...process.env };
|
|
@@ -99,14 +164,33 @@ function spawnFrontend(launch, cwd, spawn = nodeSpawn) {
|
|
|
99
164
|
child.once('exit', (code, signal) => finish(() => resolveExit(exitCode(code, signal))));
|
|
100
165
|
});
|
|
101
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* `--worktree`: the named worktree of the repository in `cwd`, or a new managed one. Older managed
|
|
169
|
+
* worktrees beyond the kept number are pruned (unsaved work is kept as a snapshot).
|
|
170
|
+
*/
|
|
171
|
+
async function enterWorktree(harness, cwd, wanted) {
|
|
172
|
+
const name = wanted === true ? undefined : wanted;
|
|
173
|
+
const existing = name ? (await harness.worktrees.list(cwd)).find((record) => record.name === name) : undefined;
|
|
174
|
+
if (existing)
|
|
175
|
+
return existing;
|
|
176
|
+
const created = await harness.worktrees.create({ repo: cwd, ...(name ? { name } : {}) });
|
|
177
|
+
process.stdout.write(`Working in worktree ${created.worktree.name} (${created.worktree.path}).\n`);
|
|
178
|
+
if (created.setup.state === 'untrusted')
|
|
179
|
+
process.stdout.write('This repository has a setup script you have not trusted; read .xharness/worktree-setup, then run: xagent worktree trust-setup\n');
|
|
180
|
+
if (created.setup.state === 'failed')
|
|
181
|
+
process.stdout.write(`The worktree setup script failed; see ${created.setup.log}.\n`);
|
|
182
|
+
await harness.worktrees.prune({ repo: cwd }).catch(() => undefined);
|
|
183
|
+
return created.worktree;
|
|
184
|
+
}
|
|
102
185
|
export async function runStandaloneTerminal(argv, dependencies = {}) {
|
|
103
186
|
if (!(dependencies.stdinIsTTY ?? process.stdin.isTTY) || !(dependencies.stdoutIsTTY ?? process.stdout.isTTY)) {
|
|
104
|
-
throw new Error('The interactive Harness terminal needs a TTY. Run it from a terminal, or use `
|
|
187
|
+
throw new Error('The interactive Harness terminal needs a TTY. Run it from a terminal, or use `xagent serve` for a host process.');
|
|
105
188
|
}
|
|
106
|
-
|
|
107
|
-
const paths =
|
|
189
|
+
let cwd = resolve(dependencies.cwd ?? process.cwd());
|
|
190
|
+
const { paths, profile } = resolveStandaloneOptions(argv, dependencies.home, cwd);
|
|
191
|
+
const secrets = await interactiveProfileSecretStore(profile, dependencies.hostSecretStore);
|
|
108
192
|
const makeHarness = dependencies.createHarness ?? createHarness;
|
|
109
|
-
const harness = makeHarness({ dataRoot: paths.dataRoot, stateDir: paths.stateDir, productName:
|
|
193
|
+
const harness = makeHarness({ dataRoot: paths.dataRoot, stateDir: paths.stateDir, productName: DEFAULT_PRODUCT_NAME, secrets });
|
|
110
194
|
const newSessionId = dependencies.createSessionId ?? randomUUID;
|
|
111
195
|
let current = { sessionId: newSessionId(), accountId: null, nativeSessionId: null };
|
|
112
196
|
// The frontend draws on this terminal, so the host's diagnostics go to a file the person can read instead.
|
|
@@ -121,19 +205,34 @@ export async function runStandaloneTerminal(argv, dependencies = {}) {
|
|
|
121
205
|
});
|
|
122
206
|
try {
|
|
123
207
|
await harness.ready;
|
|
208
|
+
const variantScope = paths.variant ?? profile.defaultVariantScope;
|
|
209
|
+
if (variantScope === profile.defaultVariantScope && !variantStore.head(paths.dataRoot, variantScope)) {
|
|
210
|
+
variantStore.seed(paths.dataRoot, variantScope, seedVariant(paths.dataRoot, {}), 'interactive profile default');
|
|
211
|
+
}
|
|
124
212
|
if (harness.accounts.overview().accounts.length === 0)
|
|
125
213
|
harness.accounts.create('Default', 'subscription');
|
|
126
|
-
|
|
127
|
-
|
|
214
|
+
let worktreeId = null;
|
|
215
|
+
if (paths.worktree) {
|
|
216
|
+
const worktree = await enterWorktree(harness, cwd, paths.worktree);
|
|
217
|
+
cwd = worktree.path;
|
|
218
|
+
worktreeId = worktree.id;
|
|
219
|
+
}
|
|
128
220
|
for (;;) {
|
|
129
|
-
const
|
|
221
|
+
const sessionFolder = join(paths.dataRoot, 'sessions', 'terminal', createHash('sha256').update(cwd).digest('hex'));
|
|
222
|
+
const launch = await harness.terminals.prepare({ ...current, cwd, sessionFolder, variant: { scope: variantScope }, ...(worktreeId ? { run: { worktreeId } } : {}) });
|
|
130
223
|
const code = await spawnFrontend(launch, cwd, dependencies.spawn);
|
|
131
|
-
// `/accounts`
|
|
224
|
+
// `/accounts` and `/worktree` ask for a switch and end the frontend. An account switch resumes
|
|
225
|
+
// the conversation; a folder switch starts a new one there.
|
|
132
226
|
const next = harness.terminals.takeRelaunch(current.sessionId);
|
|
133
227
|
if (!next)
|
|
134
228
|
return code;
|
|
135
|
-
|
|
136
|
-
|
|
229
|
+
if (next.cwd) {
|
|
230
|
+
process.stdout.write(`Opening ${next.cwd}.\n`);
|
|
231
|
+
cwd = next.cwd;
|
|
232
|
+
worktreeId = next.worktreeId ?? null;
|
|
233
|
+
}
|
|
234
|
+
else
|
|
235
|
+
process.stdout.write(`Switching this session to account ${harness.accounts.find(next.accountId).label}.\n`);
|
|
137
236
|
await harness.terminals.dispose(current.sessionId);
|
|
138
237
|
current = { sessionId: newSessionId(), accountId: next.accountId, nativeSessionId: next.nativeSessionId };
|
|
139
238
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type RunEvent, type RunStatus, type UsagePayload } from "../sessions/contracts.js";
|
|
2
|
+
import type { Effort } from "../sessions/runner.js";
|
|
3
|
+
/** The agent profile a child started from, as the roster shows it (PROP-0029). */
|
|
4
|
+
export interface TerminalSubagentProfile {
|
|
5
|
+
name: string;
|
|
6
|
+
color: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TerminalSubagentRun {
|
|
9
|
+
id: string;
|
|
10
|
+
parentRunId: string | null;
|
|
11
|
+
relation: 'subagent';
|
|
12
|
+
/** The short name the parent gave the child (PROP-0030). */
|
|
13
|
+
title: string;
|
|
14
|
+
goal: string | null;
|
|
15
|
+
status: RunStatus;
|
|
16
|
+
startedAt: string;
|
|
17
|
+
endedAt: string | null;
|
|
18
|
+
profile?: TerminalSubagentProfile | null;
|
|
19
|
+
/** The pinned account's display label; subagents never switch accounts. */
|
|
20
|
+
accountLabel?: string | null;
|
|
21
|
+
/** Effective launch selection, superseded by provider-reported usage when available. */
|
|
22
|
+
model?: string | null;
|
|
23
|
+
effort?: Effort | null;
|
|
24
|
+
}
|
|
25
|
+
export type TerminalSubagentUsage = Partial<Pick<UsagePayload, 'provider' | 'model' | 'inputTokens' | 'outputTokens' | 'cacheReadTokens' | 'cacheWriteTokens' | 'reasoningTokens' | 'costUsd' | 'costSource' | 'requests' | 'contextTokens' | 'contextWindow'>>;
|
|
26
|
+
export interface TerminalSubagentActivity extends TerminalSubagentRun {
|
|
27
|
+
activity: string;
|
|
28
|
+
/** Cumulative run usage only; provider reasoning summaries and request details stay private. */
|
|
29
|
+
usage: TerminalSubagentUsage | null;
|
|
30
|
+
/** How far the child's own checklist is: counts only, never the items. */
|
|
31
|
+
checklist: {
|
|
32
|
+
done: number;
|
|
33
|
+
total: number;
|
|
34
|
+
} | null;
|
|
35
|
+
}
|
|
36
|
+
export declare const ACTIVE_SUBAGENT_STATUSES: Set<"queued" | "running" | "waiting_for_approval" | "waiting_for_input" | "interrupted" | "completed" | "failed">;
|
|
37
|
+
export declare function terminalSubagentDuration(activity: TerminalSubagentRun, now?: number): string;
|
|
38
|
+
export declare function terminalSubagentTone(status: RunStatus): 'success' | 'warning' | 'error' | 'muted';
|
|
39
|
+
/** Volatile, read-only activity projection for the latest terminal parent run. */
|
|
40
|
+
export declare class SubagentMonitor {
|
|
41
|
+
private parentRunId;
|
|
42
|
+
private readonly activities;
|
|
43
|
+
begin(parentRunId: string): void;
|
|
44
|
+
observe(parentRunId: string, run: TerminalSubagentRun, event: RunEvent): void;
|
|
45
|
+
snapshot(parentRunId: string): TerminalSubagentActivity[];
|
|
46
|
+
clear(parentRunId?: string): void;
|
|
47
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { usagePayloadSchema } from "../sessions/contracts.js";
|
|
2
|
+
export const ACTIVE_SUBAGENT_STATUSES = new Set(['queued', 'running', 'waiting_for_approval', 'waiting_for_input']);
|
|
3
|
+
export function terminalSubagentDuration(activity, now = Date.now()) {
|
|
4
|
+
const start = Date.parse(activity.startedAt);
|
|
5
|
+
const end = activity.endedAt ? Date.parse(activity.endedAt) : now;
|
|
6
|
+
if (!Number.isFinite(start) || !Number.isFinite(end))
|
|
7
|
+
return '—';
|
|
8
|
+
const seconds = Math.max(0, Math.floor((end - start) / 1000));
|
|
9
|
+
if (seconds < 60)
|
|
10
|
+
return `${seconds}s`;
|
|
11
|
+
const minutes = Math.floor(seconds / 60);
|
|
12
|
+
if (minutes < 60)
|
|
13
|
+
return `${minutes}:${String(seconds % 60).padStart(2, '0')}`;
|
|
14
|
+
return `${Math.floor(minutes / 60)}h${String(minutes % 60).padStart(2, '0')}m`;
|
|
15
|
+
}
|
|
16
|
+
export function terminalSubagentTone(status) {
|
|
17
|
+
if (status === 'completed')
|
|
18
|
+
return 'success';
|
|
19
|
+
if (status === 'failed')
|
|
20
|
+
return 'error';
|
|
21
|
+
if (ACTIVE_SUBAGENT_STATUSES.has(status))
|
|
22
|
+
return 'warning';
|
|
23
|
+
return 'muted';
|
|
24
|
+
}
|
|
25
|
+
function statusActivity(status) {
|
|
26
|
+
switch (status) {
|
|
27
|
+
case 'queued': return 'Queued';
|
|
28
|
+
case 'waiting_for_approval': return 'Waiting for approval';
|
|
29
|
+
case 'waiting_for_input': return 'Waiting for input';
|
|
30
|
+
case 'completed': return 'Completed';
|
|
31
|
+
case 'failed': return 'Failed';
|
|
32
|
+
case 'interrupted': return 'Interrupted';
|
|
33
|
+
case 'running': return 'Working';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function payloadOf(event) {
|
|
37
|
+
return event.payload && typeof event.payload === 'object' ? event.payload : {};
|
|
38
|
+
}
|
|
39
|
+
function stringOf(value) {
|
|
40
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
41
|
+
}
|
|
42
|
+
function latestTool(tools) {
|
|
43
|
+
return [...tools.values()].sort((left, right) => right.sequence - left.sequence)[0]?.text;
|
|
44
|
+
}
|
|
45
|
+
/** Volatile, read-only activity projection for the latest terminal parent run. */
|
|
46
|
+
export class SubagentMonitor {
|
|
47
|
+
parentRunId = null;
|
|
48
|
+
activities = new Map();
|
|
49
|
+
begin(parentRunId) {
|
|
50
|
+
this.parentRunId = parentRunId;
|
|
51
|
+
this.activities.clear();
|
|
52
|
+
}
|
|
53
|
+
observe(parentRunId, run, event) {
|
|
54
|
+
if (this.parentRunId !== parentRunId || run.relation !== 'subagent')
|
|
55
|
+
return;
|
|
56
|
+
const row = this.activities.get(run.id) ?? {
|
|
57
|
+
id: run.id,
|
|
58
|
+
parentRunId: run.parentRunId,
|
|
59
|
+
relation: run.relation,
|
|
60
|
+
title: run.title,
|
|
61
|
+
goal: run.goal,
|
|
62
|
+
status: run.status,
|
|
63
|
+
startedAt: run.startedAt,
|
|
64
|
+
endedAt: run.endedAt,
|
|
65
|
+
activity: statusActivity(run.status),
|
|
66
|
+
checklist: null,
|
|
67
|
+
profile: run.profile ?? null,
|
|
68
|
+
accountLabel: run.accountLabel ?? null,
|
|
69
|
+
model: run.model ?? null,
|
|
70
|
+
effort: run.effort ?? null,
|
|
71
|
+
usage: null,
|
|
72
|
+
tools: new Map(),
|
|
73
|
+
lastTool: null
|
|
74
|
+
};
|
|
75
|
+
row.parentRunId = run.parentRunId;
|
|
76
|
+
if (run.profile !== undefined)
|
|
77
|
+
row.profile = run.profile;
|
|
78
|
+
if (run.accountLabel !== undefined)
|
|
79
|
+
row.accountLabel = run.accountLabel;
|
|
80
|
+
if (run.model !== undefined && !row.usage?.model)
|
|
81
|
+
row.model = run.model;
|
|
82
|
+
if (run.effort !== undefined)
|
|
83
|
+
row.effort = run.effort;
|
|
84
|
+
row.title = run.title;
|
|
85
|
+
row.goal = run.goal;
|
|
86
|
+
row.status = run.status;
|
|
87
|
+
row.startedAt = run.startedAt;
|
|
88
|
+
row.endedAt = run.endedAt;
|
|
89
|
+
const payload = payloadOf(event);
|
|
90
|
+
if (event.type === 'tool.started') {
|
|
91
|
+
const toolCallId = stringOf(payload.toolCallId);
|
|
92
|
+
const name = stringOf(payload.name) ?? 'Tool';
|
|
93
|
+
if (toolCallId)
|
|
94
|
+
row.tools.set(toolCallId, { sequence: event.sequence, text: name });
|
|
95
|
+
}
|
|
96
|
+
else if (event.type === 'tool.completed') {
|
|
97
|
+
const toolCallId = stringOf(payload.toolCallId);
|
|
98
|
+
const tool = toolCallId ? row.tools.get(toolCallId) : undefined;
|
|
99
|
+
if (tool && (!row.lastTool || tool.sequence >= row.lastTool.sequence))
|
|
100
|
+
row.lastTool = tool;
|
|
101
|
+
if (toolCallId)
|
|
102
|
+
row.tools.delete(toolCallId);
|
|
103
|
+
}
|
|
104
|
+
else if (event.type === 'message.delta') {
|
|
105
|
+
row.lastTool = null;
|
|
106
|
+
row.activity = 'Responding';
|
|
107
|
+
}
|
|
108
|
+
else if (event.type === 'usage.updated') {
|
|
109
|
+
const parsed = usagePayloadSchema.safeParse(payload);
|
|
110
|
+
if (parsed.success) {
|
|
111
|
+
const usage = parsed.data;
|
|
112
|
+
row.usage = {
|
|
113
|
+
...(usage.provider === undefined ? {} : { provider: usage.provider }),
|
|
114
|
+
...(usage.model === undefined ? {} : { model: usage.model }),
|
|
115
|
+
...(usage.inputTokens === undefined ? {} : { inputTokens: usage.inputTokens }),
|
|
116
|
+
...(usage.outputTokens === undefined ? {} : { outputTokens: usage.outputTokens }),
|
|
117
|
+
...(usage.cacheReadTokens === undefined ? {} : { cacheReadTokens: usage.cacheReadTokens }),
|
|
118
|
+
...(usage.cacheWriteTokens === undefined ? {} : { cacheWriteTokens: usage.cacheWriteTokens }),
|
|
119
|
+
...(usage.reasoningTokens === undefined ? {} : { reasoningTokens: usage.reasoningTokens }),
|
|
120
|
+
...(usage.costUsd === undefined ? {} : { costUsd: usage.costUsd }),
|
|
121
|
+
...(usage.costSource === undefined ? {} : { costSource: usage.costSource }),
|
|
122
|
+
...(usage.requests === undefined ? {} : { requests: usage.requests }),
|
|
123
|
+
...(usage.contextTokens === undefined ? {} : { contextTokens: usage.contextTokens }),
|
|
124
|
+
...(usage.contextWindow === undefined ? {} : { contextWindow: usage.contextWindow })
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if (event.type === 'checklist.updated') {
|
|
129
|
+
const items = Array.isArray(payload.items) ? payload.items : [];
|
|
130
|
+
row.checklist = items.length ? { done: items.filter(item => item?.status === 'completed').length, total: items.length } : null;
|
|
131
|
+
}
|
|
132
|
+
if (run.status !== 'running')
|
|
133
|
+
row.tools.clear();
|
|
134
|
+
row.activity = run.status === 'running'
|
|
135
|
+
? latestTool(row.tools) ?? row.lastTool?.text ?? (event.type === 'message.delta' ? 'Responding' : 'Working')
|
|
136
|
+
: statusActivity(run.status);
|
|
137
|
+
this.activities.set(run.id, row);
|
|
138
|
+
}
|
|
139
|
+
snapshot(parentRunId) {
|
|
140
|
+
if (this.parentRunId !== parentRunId)
|
|
141
|
+
return [];
|
|
142
|
+
return [...this.activities.values()]
|
|
143
|
+
.sort((left, right) => left.startedAt.localeCompare(right.startedAt) || left.id.localeCompare(right.id))
|
|
144
|
+
.map(({ tools: _tools, lastTool: _lastTool, ...activity }) => activity);
|
|
145
|
+
}
|
|
146
|
+
clear(parentRunId) {
|
|
147
|
+
if (parentRunId && this.parentRunId !== parentRunId)
|
|
148
|
+
return;
|
|
149
|
+
this.parentRunId = null;
|
|
150
|
+
this.activities.clear();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CapabilitySet } from "../capabilities/types.js";
|
|
2
2
|
import type { Subagents } from "../sessions/subagentService.js";
|
|
3
|
+
import type { SideQuestions } from "../sessions/sideQuestions.js";
|
|
3
4
|
import { type SubagentOptions } from "../sessions/subagents.js";
|
|
4
5
|
import type { Accounts } from "../accounts/accounts.js";
|
|
5
6
|
import type { Approvals } from "../sessions/approvals.js";
|
|
@@ -18,11 +19,16 @@ import type { RunRecord } from "../sessions/contracts.js";
|
|
|
18
19
|
import type { ToolPolicy } from "../sessions/policy.js";
|
|
19
20
|
import type { RunRegistry } from "../sessions/registry.js";
|
|
20
21
|
import type { World } from "../world/world.js";
|
|
22
|
+
import type { Worktrees } from "../worktrees/service.js";
|
|
23
|
+
import type { AnnotationCapture } from "../annotations/capture.js";
|
|
24
|
+
import type { NoteDeliveries } from "../annotations/delivery.js";
|
|
25
|
+
import type { Usage } from "../usage/service.js";
|
|
26
|
+
import type { UsageLimits } from "../usage/limits/service.js";
|
|
21
27
|
/** The files a terminal session needs on disk, outside this process. */
|
|
22
28
|
export interface TerminalAssets {
|
|
23
29
|
/** The Node binary that runs the commands. */
|
|
24
30
|
node: string;
|
|
25
|
-
/** The built `
|
|
31
|
+
/** The built `xagent` command (`dist/cli.js`). */
|
|
26
32
|
cli: string;
|
|
27
33
|
/** The built Pi extension (`dist/terminal-pi.js`). */
|
|
28
34
|
piExtension: string;
|
|
@@ -52,6 +58,15 @@ export interface TerminalPrepareInput {
|
|
|
52
58
|
/** Fields copied onto each run this session records. */
|
|
53
59
|
run?: Partial<Pick<RunRecord, 'mode' | 'worktreeId'>>;
|
|
54
60
|
}
|
|
61
|
+
/** What a session asked to restart as: another account, or another folder (a worktree or the main checkout). */
|
|
62
|
+
export interface TerminalRelaunch {
|
|
63
|
+
accountId: string;
|
|
64
|
+
nativeSessionId: string | null;
|
|
65
|
+
/** Restart in this folder, as a new conversation there. */
|
|
66
|
+
cwd?: string;
|
|
67
|
+
/** The managed worktree the new folder belongs to; null for the main checkout. */
|
|
68
|
+
worktreeId?: string | null;
|
|
69
|
+
}
|
|
55
70
|
export interface TerminalLaunch {
|
|
56
71
|
program: string;
|
|
57
72
|
args: string[];
|
|
@@ -65,6 +80,8 @@ export interface TerminalsOptions {
|
|
|
65
80
|
/** Which plugin code in variants a person trusted. */
|
|
66
81
|
trust?: VariantTrust | null;
|
|
67
82
|
subagents?: Subagents;
|
|
83
|
+
/** Shared tool-free side-question runs. */
|
|
84
|
+
sideQuestions?: SideQuestions;
|
|
68
85
|
resolveCapabilities?: (caller: CallerContext, tools: readonly string[], cwd: string) => Promise<CapabilitySet>;
|
|
69
86
|
env: HarnessEnv;
|
|
70
87
|
stateDir: string;
|
|
@@ -82,6 +99,16 @@ export interface TerminalsOptions {
|
|
|
82
99
|
assets?: TerminalAssets;
|
|
83
100
|
/** Web, browser and computer tools, offered when their plugins are on. */
|
|
84
101
|
world?: World;
|
|
102
|
+
/** Managed worktrees: a session naming one works in it and holds it while it lives. */
|
|
103
|
+
worktrees?: Worktrees;
|
|
104
|
+
/** The visible browser a person captures page notes in. */
|
|
105
|
+
noteCapture?: AnnotationCapture;
|
|
106
|
+
/** Page notes on their way to a session (PROP-0018). */
|
|
107
|
+
pageNotes?: NoteDeliveries;
|
|
108
|
+
/** Usage analytics over the derived ledger (`/usage:analysis`). */
|
|
109
|
+
usage?: Usage;
|
|
110
|
+
/** Provider plan windows, balances and rate limits (`/usage:limit`). */
|
|
111
|
+
usageLimits?: UsageLimits;
|
|
85
112
|
}
|
|
86
113
|
/** What `/plugins` in a terminal can do. Each takes the session's folder, account and project. */
|
|
87
114
|
export interface PluginControl {
|
|
@@ -98,6 +125,12 @@ export interface PluginControl {
|
|
|
98
125
|
pluginId: string;
|
|
99
126
|
settings: Record<string, unknown>;
|
|
100
127
|
}): Promise<Plugin[]>;
|
|
128
|
+
install?(params: PluginScope & {
|
|
129
|
+
source: string;
|
|
130
|
+
}): Promise<Plugin[]>;
|
|
131
|
+
remove?(params: PluginScope & {
|
|
132
|
+
pluginId: string;
|
|
133
|
+
}): Promise<Plugin[]>;
|
|
101
134
|
}
|
|
102
135
|
export declare class Terminals {
|
|
103
136
|
private readonly options;
|
|
@@ -110,15 +143,27 @@ export declare class Terminals {
|
|
|
110
143
|
private readonly worldReadOnly;
|
|
111
144
|
private readonly socket;
|
|
112
145
|
private readonly assets;
|
|
113
|
-
/** A session's `/accounts` switch, taken once its Pi process has ended. */
|
|
146
|
+
/** A session's `/accounts` or `/worktree` switch, taken once its Pi process has ended. */
|
|
114
147
|
private readonly relaunches;
|
|
148
|
+
/** The managed worktree each live session holds. */
|
|
149
|
+
private readonly worktreeLeases;
|
|
150
|
+
/** Each child's profile name and colour, looked up once per child run. */
|
|
151
|
+
private readonly childProfiles;
|
|
152
|
+
private subagentProfile;
|
|
115
153
|
constructor(options: TerminalsOptions);
|
|
116
154
|
/** The commands a terminal session finds on PATH. Rewritten only when they change. */
|
|
117
155
|
private ensureCommands;
|
|
118
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* The harness's own History, Wiki and skill tools, then the broker's, then the world tools whose
|
|
158
|
+
* plugins are on for this session: the same tools a structured session has (INV-PAR-1).
|
|
159
|
+
*/
|
|
119
160
|
private tools;
|
|
161
|
+
private readonly ownNames;
|
|
162
|
+
private ownTools;
|
|
120
163
|
/** The world tools a new session will have, named in its instructions. */
|
|
121
164
|
private worldToolNames;
|
|
165
|
+
/** The harness's own History, Wiki and skill tools a new session will have. */
|
|
166
|
+
private ownToolNames;
|
|
122
167
|
/** Whether a world tool's plugin is switched on for a session's folder, account and project. */
|
|
123
168
|
private worldOn;
|
|
124
169
|
private appsCall;
|
|
@@ -133,20 +178,28 @@ export declare class Terminals {
|
|
|
133
178
|
* or removing an account is a person's choice, never the model's shell command.
|
|
134
179
|
*/
|
|
135
180
|
private accountsCall;
|
|
181
|
+
/** `/agents`: the agent profiles this session's folder can use (PROP-0029). */
|
|
182
|
+
private agentsCall;
|
|
183
|
+
/** `/worktree`: the managed worktrees of the repository this session works in. */
|
|
184
|
+
private worktreesCall;
|
|
185
|
+
/** `/usage:analysis` and `/usage:limit`: usage for this session's own account, project or session. */
|
|
186
|
+
private usageCall;
|
|
187
|
+
/** `/annotate:notes` and `/annotate:`: Web annotations and their visible capture browser. */
|
|
188
|
+
private annotationsCall;
|
|
136
189
|
/** The account a session asked to switch to. Taken once, after its Pi process has ended and before `dispose`. */
|
|
137
|
-
takeRelaunch(sessionId: string):
|
|
138
|
-
accountId: string;
|
|
139
|
-
nativeSessionId: string | null;
|
|
140
|
-
} | null;
|
|
190
|
+
takeRelaunch(sessionId: string): TerminalRelaunch | null;
|
|
141
191
|
private live;
|
|
142
192
|
private historyDir;
|
|
143
193
|
private runRecord;
|
|
144
194
|
/** The run a native turn reports into: the one reserved by `send`, or a new one for what the person typed. */
|
|
145
195
|
private begin;
|
|
146
196
|
private decide;
|
|
197
|
+
private workspaceEscape;
|
|
198
|
+
private workspaceBoundaryBypass;
|
|
147
199
|
private subagentsCall;
|
|
148
200
|
private componentsCall;
|
|
149
201
|
private trajectoryCall;
|
|
202
|
+
private sideQuestionCall;
|
|
150
203
|
/** The only terminal frontend: the Bun-run OpenTUI application. */
|
|
151
204
|
private frontendCommand;
|
|
152
205
|
/**
|