@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
|
@@ -9,6 +9,9 @@ export const fileName = (name) => name.replace(/[^A-Za-z0-9._-]/g, '_').replace(
|
|
|
9
9
|
export const VIEWPORT = { width: 1280, height: 800 };
|
|
10
10
|
export const ACTION_TIMEOUT_MS = 15_000;
|
|
11
11
|
export const NAVIGATION_TIMEOUT_MS = 30_000;
|
|
12
|
+
function isClosedBrowserError(error) {
|
|
13
|
+
return error instanceof Error && /Target page, context or browser has been closed|browser has been closed|context has been closed/i.test(error.message);
|
|
14
|
+
}
|
|
12
15
|
export const launchBrowser = async ({ profileDir, downloads, config }) => {
|
|
13
16
|
const { chromium } = await import('playwright-core');
|
|
14
17
|
if (config.cdpUrl) {
|
|
@@ -87,17 +90,20 @@ export class BrowserSession {
|
|
|
87
90
|
this.context = launched.context;
|
|
88
91
|
this.browser = launched.browser;
|
|
89
92
|
this.attached = launched.attached;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
const context = launched.context;
|
|
94
|
+
context.on('close', () => this.forget(context));
|
|
95
|
+
launched.browser?.on('disconnected', () => this.forget(context));
|
|
96
|
+
context.setDefaultTimeout(ACTION_TIMEOUT_MS);
|
|
97
|
+
context.setDefaultNavigationTimeout(NAVIGATION_TIMEOUT_MS);
|
|
98
|
+
await context.route('**/*', async (route) => {
|
|
93
99
|
const refusal = await this.options.network.refusal(route.request().url());
|
|
94
100
|
if (refusal)
|
|
95
101
|
await route.abort('blockedbyclient');
|
|
96
102
|
else
|
|
97
103
|
await route.continue();
|
|
98
104
|
});
|
|
99
|
-
|
|
100
|
-
for (const page of
|
|
105
|
+
context.on('page', (page) => this.adopt(page));
|
|
106
|
+
for (const page of context.pages())
|
|
101
107
|
this.adopt(page);
|
|
102
108
|
})();
|
|
103
109
|
try {
|
|
@@ -132,6 +138,15 @@ export class BrowserSession {
|
|
|
132
138
|
});
|
|
133
139
|
return tab;
|
|
134
140
|
}
|
|
141
|
+
forget(context) {
|
|
142
|
+
if (this.context !== context)
|
|
143
|
+
return;
|
|
144
|
+
this.context = null;
|
|
145
|
+
this.browser = null;
|
|
146
|
+
this.attached = false;
|
|
147
|
+
this.tabs.clear();
|
|
148
|
+
this.current = null;
|
|
149
|
+
}
|
|
135
150
|
/** A tab by id, or the current one, starting the browser and opening a first tab when needed. */
|
|
136
151
|
async tab(id) {
|
|
137
152
|
await this.start();
|
|
@@ -146,10 +161,31 @@ export class BrowserSession {
|
|
|
146
161
|
return this.open();
|
|
147
162
|
}
|
|
148
163
|
async open() {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
164
|
+
let lastClosedError;
|
|
165
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
166
|
+
await this.start();
|
|
167
|
+
const context = this.context;
|
|
168
|
+
if (!context)
|
|
169
|
+
continue;
|
|
170
|
+
try {
|
|
171
|
+
const page = await context.newPage();
|
|
172
|
+
if (this.context !== context) {
|
|
173
|
+
await page.close().catch(() => undefined);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const tab = this.adopt(page);
|
|
177
|
+
this.current = tab.id;
|
|
178
|
+
return tab;
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
if (attempt !== 0 || !isClosedBrowserError(error))
|
|
182
|
+
throw error;
|
|
183
|
+
lastClosedError = error;
|
|
184
|
+
this.forget(context);
|
|
185
|
+
await context.close().catch(() => undefined);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
throw lastClosedError ?? new Error('The browser closed while opening a page.');
|
|
153
189
|
}
|
|
154
190
|
select(id) {
|
|
155
191
|
const tab = this.tabs.get(id);
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import type { ToolSpec } from "../tools/types.js";
|
|
2
2
|
import type { WorldContext } from "../world/world.js";
|
|
3
3
|
import type { BrowserSession } from "./session.js";
|
|
4
|
-
|
|
5
|
-
export declare const SNAPSHOT_LINES = 500;
|
|
6
|
-
export declare const SNAPSHOT_CHARS = 40000;
|
|
7
|
-
export declare const BROWSER_TOOL_NAMES: readonly ["browser_navigate", "browser_snapshot", "browser_read", "browser_screenshot", "browser_click", "browser_type", "browser_select", "browser_press", "browser_scroll", "browser_wait", "browser_tabs"];
|
|
4
|
+
export { BROWSER_TOOL_NAMES, SNAPSHOT_LINES, SNAPSHOT_CHARS } from "./contracts.js";
|
|
8
5
|
export declare function browserTools(context: WorldContext, session: () => BrowserSession): ToolSpec[];
|
|
@@ -2,15 +2,12 @@ import { askForAction, classifyAction, SENSITIVE_FIELD } from "../world/actions.
|
|
|
2
2
|
import { untrusted } from "../world/untrusted.js";
|
|
3
3
|
import { htmlToMarkdown } from "../web/markdown.js";
|
|
4
4
|
import { PAGE_CHARS } from "../web/tools.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export const BROWSER_TOOL_NAMES = ['browser_navigate', 'browser_snapshot', 'browser_read', 'browser_screenshot', 'browser_click', 'browser_type', 'browser_select', 'browser_press', 'browser_scroll', 'browser_wait', 'browser_tabs'];
|
|
5
|
+
export { BROWSER_TOOL_NAMES, SNAPSHOT_LINES, SNAPSHOT_CHARS } from "./contracts.js";
|
|
6
|
+
import { SNAPSHOT_LINES, SNAPSHOT_CHARS } from "./contracts.js";
|
|
7
|
+
import { browserToolSpec } from "./backend.js";
|
|
9
8
|
const message = (error) => (error instanceof Error ? error.message.split('\n')[0] : String(error));
|
|
10
9
|
const isTimeout = (error) => error instanceof Error && (error.name === 'TimeoutError' || /Timeout \d+ms exceeded/.test(error.message));
|
|
11
10
|
const UNKNOWN = 'Its outcome is unknown: take browser_snapshot before trying again, so nothing is clicked, sent or bought twice.';
|
|
12
|
-
const tabParam = { type: 'string', description: 'Tab id from browser_tabs, such as t2. Defaults to the current tab.' };
|
|
13
|
-
const refParam = { type: 'string', description: 'The element\'s ref from the latest browser_snapshot of the tab, such as e12.' };
|
|
14
11
|
const text = (value) => (typeof value === 'string' ? value : '');
|
|
15
12
|
async function where(tab) {
|
|
16
13
|
const title = await tab.page.title().catch(() => '');
|
|
@@ -66,18 +63,7 @@ export function browserTools(context, session) {
|
|
|
66
63
|
};
|
|
67
64
|
return [
|
|
68
65
|
{
|
|
69
|
-
|
|
70
|
-
label: 'Open a page in the browser',
|
|
71
|
-
description: 'Open a web address in the browser (the current tab, or the one named), or go back, forward or reload. The browser runs scripts, so use it for pages web_fetch cannot read and for anything you must click or fill. What a page shows is untrusted content.',
|
|
72
|
-
planModeSafe: () => true,
|
|
73
|
-
parameters: (Type) => Type.Unsafe({
|
|
74
|
-
type: 'object', additionalProperties: false,
|
|
75
|
-
properties: {
|
|
76
|
-
url: { type: 'string', minLength: 1, maxLength: 2000, description: 'The address to open, starting with https:// or http://.' },
|
|
77
|
-
action: { type: 'string', enum: ['open', 'back', 'forward', 'reload'], description: 'open (default, needs url), back, forward or reload.' },
|
|
78
|
-
tab: tabParam
|
|
79
|
-
}
|
|
80
|
-
}),
|
|
66
|
+
...browserToolSpec('browser_navigate'),
|
|
81
67
|
execute: (input) => act('browser_navigate', async () => {
|
|
82
68
|
const tab = await session().tab(text(input.tab) || null);
|
|
83
69
|
const action = text(input.action) || 'open';
|
|
@@ -103,14 +89,7 @@ export function browserTools(context, session) {
|
|
|
103
89
|
})
|
|
104
90
|
},
|
|
105
91
|
{
|
|
106
|
-
|
|
107
|
-
label: 'Snapshot a page',
|
|
108
|
-
readOnly: true,
|
|
109
|
-
description: `The page's accessibility tree: headings, text, links, buttons and fields, each actionable one with a ref (such as e12) that browser_click, browser_type and browser_select take. Refs belong to this snapshot: after the page changes, take a new one. At most ${SNAPSHOT_LINES} lines; pass depth to see less.`,
|
|
110
|
-
parameters: (Type) => Type.Unsafe({
|
|
111
|
-
type: 'object', additionalProperties: false,
|
|
112
|
-
properties: { tab: tabParam, depth: { type: 'integer', minimum: 1, maximum: 40, description: 'Only this many levels of the tree.' } }
|
|
113
|
-
}),
|
|
92
|
+
...browserToolSpec('browser_snapshot'),
|
|
114
93
|
execute: (input) => act('browser_snapshot', async () => {
|
|
115
94
|
const tab = await session().tab(text(input.tab) || null);
|
|
116
95
|
const depth = Number(input.depth);
|
|
@@ -131,14 +110,7 @@ export function browserTools(context, session) {
|
|
|
131
110
|
})
|
|
132
111
|
},
|
|
133
112
|
{
|
|
134
|
-
|
|
135
|
-
label: 'Read a page as text',
|
|
136
|
-
readOnly: true,
|
|
137
|
-
description: `The visible text of the tab's page as Markdown, after its scripts ran. Up to ${PAGE_CHARS.toLocaleString('en-US')} characters; pass offset to read on.`,
|
|
138
|
-
parameters: (Type) => Type.Unsafe({
|
|
139
|
-
type: 'object', additionalProperties: false,
|
|
140
|
-
properties: { tab: tabParam, offset: { type: 'integer', minimum: 0, description: 'Character to start from.' } }
|
|
141
|
-
}),
|
|
113
|
+
...browserToolSpec('browser_read'),
|
|
142
114
|
execute: (input) => act('browser_read', async () => {
|
|
143
115
|
const tab = await session().tab(text(input.tab) || null);
|
|
144
116
|
const { title, text: markdown } = htmlToMarkdown(await tab.page.content());
|
|
@@ -149,11 +121,7 @@ export function browserTools(context, session) {
|
|
|
149
121
|
})
|
|
150
122
|
},
|
|
151
123
|
{
|
|
152
|
-
|
|
153
|
-
label: 'Screenshot a page',
|
|
154
|
-
readOnly: true,
|
|
155
|
-
description: 'A picture of what the tab shows (1280×800), or of one element by ref. Use it when layout or images matter; a snapshot is cheaper for finding what to click.',
|
|
156
|
-
parameters: (Type) => Type.Unsafe({ type: 'object', additionalProperties: false, properties: { tab: tabParam, ref: refParam } }),
|
|
124
|
+
...browserToolSpec('browser_screenshot'),
|
|
157
125
|
execute: (input) => act('browser_screenshot', async () => {
|
|
158
126
|
const tab = await session().tab(text(input.tab) || null);
|
|
159
127
|
const ref = text(input.ref);
|
|
@@ -162,13 +130,7 @@ export function browserTools(context, session) {
|
|
|
162
130
|
})
|
|
163
131
|
},
|
|
164
132
|
{
|
|
165
|
-
|
|
166
|
-
label: 'Click on a page',
|
|
167
|
-
description: 'Click an element by its ref. A click that would send, buy, delete, change an account or grant access asks the user first.',
|
|
168
|
-
parameters: (Type) => Type.Unsafe({
|
|
169
|
-
type: 'object', additionalProperties: false, required: ['ref'],
|
|
170
|
-
properties: { ref: refParam, tab: tabParam, double: { type: 'boolean', description: 'Double-click.' }, button: { type: 'string', enum: ['left', 'right', 'middle'] } }
|
|
171
|
-
}),
|
|
133
|
+
...browserToolSpec('browser_click'),
|
|
172
134
|
execute: async (input) => attendedOnly(context, 'browser_click') ?? act('browser_click', async () => {
|
|
173
135
|
const tab = await session().tab(text(input.tab) || null);
|
|
174
136
|
const { locator, line } = element(tab, text(input.ref));
|
|
@@ -184,13 +146,7 @@ export function browserTools(context, session) {
|
|
|
184
146
|
})
|
|
185
147
|
},
|
|
186
148
|
{
|
|
187
|
-
|
|
188
|
-
label: 'Type into a page',
|
|
189
|
-
description: 'Type text into a field by its ref, replacing what is there; submit presses Enter afterwards. Password, card and one-time-code fields are refused: ask the user to fill those. Submitting a form that sends, buys or deletes asks the user first.',
|
|
190
|
-
parameters: (Type) => Type.Unsafe({
|
|
191
|
-
type: 'object', additionalProperties: false, required: ['ref', 'text'],
|
|
192
|
-
properties: { ref: refParam, text: { type: 'string', maxLength: 20_000 }, submit: { type: 'boolean', description: 'Press Enter after typing.' }, tab: tabParam }
|
|
193
|
-
}),
|
|
149
|
+
...browserToolSpec('browser_type'),
|
|
194
150
|
execute: async (input) => attendedOnly(context, 'browser_type') ?? act('browser_type', async () => {
|
|
195
151
|
const tab = await session().tab(text(input.tab) || null);
|
|
196
152
|
const { locator, line } = element(tab, text(input.ref));
|
|
@@ -209,13 +165,7 @@ export function browserTools(context, session) {
|
|
|
209
165
|
})
|
|
210
166
|
},
|
|
211
167
|
{
|
|
212
|
-
|
|
213
|
-
label: 'Choose in a list',
|
|
214
|
-
description: 'Choose one or more options of a drop-down list by its ref, by the options\' labels or values.',
|
|
215
|
-
parameters: (Type) => Type.Unsafe({
|
|
216
|
-
type: 'object', additionalProperties: false, required: ['ref', 'values'],
|
|
217
|
-
properties: { ref: refParam, values: { type: 'array', minItems: 1, items: { type: 'string' } }, tab: tabParam }
|
|
218
|
-
}),
|
|
168
|
+
...browserToolSpec('browser_select'),
|
|
219
169
|
execute: async (input) => attendedOnly(context, 'browser_select') ?? act('browser_select', async () => {
|
|
220
170
|
const tab = await session().tab(text(input.tab) || null);
|
|
221
171
|
const { locator, line } = element(tab, text(input.ref));
|
|
@@ -225,13 +175,7 @@ export function browserTools(context, session) {
|
|
|
225
175
|
})
|
|
226
176
|
},
|
|
227
177
|
{
|
|
228
|
-
|
|
229
|
-
label: 'Press a key on a page',
|
|
230
|
-
description: 'Press a key or a combination in the tab, such as Enter, Escape, Tab, ArrowDown or Control+A. Enter in a message box asks the user first.',
|
|
231
|
-
parameters: (Type) => Type.Unsafe({
|
|
232
|
-
type: 'object', additionalProperties: false, required: ['key'],
|
|
233
|
-
properties: { key: { type: 'string', minLength: 1, maxLength: 60 }, tab: tabParam }
|
|
234
|
-
}),
|
|
178
|
+
...browserToolSpec('browser_press'),
|
|
235
179
|
execute: async (input) => attendedOnly(context, 'browser_press') ?? act('browser_press', async () => {
|
|
236
180
|
const tab = await session().tab(text(input.tab) || null);
|
|
237
181
|
const key = text(input.key).trim();
|
|
@@ -254,14 +198,7 @@ export function browserTools(context, session) {
|
|
|
254
198
|
})
|
|
255
199
|
},
|
|
256
200
|
{
|
|
257
|
-
|
|
258
|
-
label: 'Scroll a page',
|
|
259
|
-
readOnly: true,
|
|
260
|
-
description: 'Scroll the tab up or down by about a screen, or bring an element (by ref) into view.',
|
|
261
|
-
parameters: (Type) => Type.Unsafe({
|
|
262
|
-
type: 'object', additionalProperties: false,
|
|
263
|
-
properties: { direction: { type: 'string', enum: ['up', 'down'] }, ref: refParam, tab: tabParam }
|
|
264
|
-
}),
|
|
201
|
+
...browserToolSpec('browser_scroll'),
|
|
265
202
|
execute: (input) => act('browser_scroll', async () => {
|
|
266
203
|
const tab = await session().tab(text(input.tab) || null);
|
|
267
204
|
if (text(input.ref))
|
|
@@ -272,14 +209,7 @@ export function browserTools(context, session) {
|
|
|
272
209
|
})
|
|
273
210
|
},
|
|
274
211
|
{
|
|
275
|
-
|
|
276
|
-
label: 'Wait on a page',
|
|
277
|
-
readOnly: true,
|
|
278
|
-
description: 'Wait until some text appears in the tab (up to 30 seconds), or for a number of milliseconds (up to 10,000).',
|
|
279
|
-
parameters: (Type) => Type.Unsafe({
|
|
280
|
-
type: 'object', additionalProperties: false,
|
|
281
|
-
properties: { text: { type: 'string', minLength: 1, maxLength: 200 }, ms: { type: 'integer', minimum: 1, maximum: 10_000 }, tab: tabParam }
|
|
282
|
-
}),
|
|
212
|
+
...browserToolSpec('browser_wait'),
|
|
283
213
|
execute: (input) => act('browser_wait', async () => {
|
|
284
214
|
const tab = await session().tab(text(input.tab) || null);
|
|
285
215
|
if (text(input.text)) {
|
|
@@ -291,14 +221,7 @@ export function browserTools(context, session) {
|
|
|
291
221
|
})
|
|
292
222
|
},
|
|
293
223
|
{
|
|
294
|
-
|
|
295
|
-
label: 'Browser tabs',
|
|
296
|
-
description: 'List the tabs, open a new one (optionally at an address), switch to one, or close one.',
|
|
297
|
-
planModeSafe: (input) => input.op !== 'close',
|
|
298
|
-
parameters: (Type) => Type.Unsafe({
|
|
299
|
-
type: 'object', additionalProperties: false, required: ['op'],
|
|
300
|
-
properties: { op: { type: 'string', enum: ['list', 'new', 'switch', 'close'] }, tab: tabParam, url: { type: 'string', maxLength: 2000 } }
|
|
301
|
-
}),
|
|
224
|
+
...browserToolSpec('browser_tabs'),
|
|
302
225
|
execute: (input) => act('browser_tabs', async () => {
|
|
303
226
|
const browser = session();
|
|
304
227
|
if (input.op === 'new') {
|
package/dist/sdk/cli.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// The `
|
|
2
|
+
// The `xagent` command.
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
4
|
+
// xagent serve --state <dir> [--data <dir>] [--name <product>] [--builtins <dir>]…
|
|
5
|
+
// [--host-secrets] [--host-policy] [--host-tools] [--host-directory]
|
|
6
6
|
// Serves the harness to a host process over stdin/stdout (newline-delimited JSON).
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
7
|
+
// xagent wiki <command> Project notes, skills and history, from inside a terminal session.
|
|
8
|
+
// xagent refine <command> Refine a variant from evidence (refine demo needs no model).
|
|
9
|
+
// xagent mcp <command> Connected apps, from inside a terminal session.
|
|
10
|
+
// xagent plugins <command> List, install, switch and trust plugins.
|
|
11
|
+
// xagent web <command> Search keys for web_search.
|
|
12
|
+
// xagent browser <command> How the agent's browser runs.
|
|
13
|
+
// xagent worktree <command> Managed git worktrees of the repository you are in.
|
|
13
14
|
import { resolve } from 'node:path';
|
|
14
15
|
import manifest from "../../package.json" with { type: 'json' };
|
|
15
16
|
import { log } from "./core/bus.js";
|
|
@@ -23,8 +24,9 @@ import { RpcPeer, stdioTransport } from "./server/rpc.js";
|
|
|
23
24
|
import { attach } from "./server/serve.js";
|
|
24
25
|
import { runAppsCli, runWikiCli } from "./terminal/cli.js";
|
|
25
26
|
import { runStandaloneTerminal, standaloneArguments } from "./terminal/standalone.js";
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
import { runWorktreeCli } from "./worktrees/cli.js";
|
|
28
|
+
const USAGE = `Usage: xagent [--data <dir>] [--state <dir>]
|
|
29
|
+
xagent <terminal | serve | wiki | mcp | plugins | hub | refine | web | browser | worktree> [arguments]
|
|
28
30
|
|
|
29
31
|
--version Print the package version
|
|
30
32
|
(no command) Start the interactive Harness terminal
|
|
@@ -39,12 +41,17 @@ const USAGE = `Usage: xharness [--data <dir>] [--state <dir>]
|
|
|
39
41
|
refine <command> Refine a harness from evidence (refine demo, refine run)
|
|
40
42
|
web <command> Search keys for the web tools (web help)
|
|
41
43
|
browser <command> How the agent's browser runs (browser help)
|
|
44
|
+
worktree <command> Managed git worktrees (worktree help)
|
|
42
45
|
|
|
43
46
|
Standalone terminal options:
|
|
44
|
-
--data <dir> Data directory (
|
|
45
|
-
npm run dev
|
|
46
|
-
--state <dir> State directory (
|
|
47
|
-
npm run dev
|
|
47
|
+
--data <dir> Data directory (interactive profile default; otherwise
|
|
48
|
+
~/.xingular-harness/data; npm run dev passes its own data root)
|
|
49
|
+
--state <dir> State directory (interactive profile default; otherwise
|
|
50
|
+
~/.xingular-harness/state; npm run dev passes its own state directory)
|
|
51
|
+
--worktree [name], -w [name]
|
|
52
|
+
Start in a new managed worktree of this repository, or in
|
|
53
|
+
the named one
|
|
54
|
+
--variant <scope> Run on this variant scope's head (default: interactive profile scope)
|
|
48
55
|
`;
|
|
49
56
|
function flags(argv) {
|
|
50
57
|
const values = {};
|
|
@@ -133,6 +140,8 @@ async function main() {
|
|
|
133
140
|
return runWebCli(rest);
|
|
134
141
|
if (command === 'browser')
|
|
135
142
|
return runBrowserCli(rest);
|
|
143
|
+
if (command === 'worktree')
|
|
144
|
+
return runWorktreeCli(rest);
|
|
136
145
|
process.stdout.write(USAGE);
|
|
137
146
|
return command ? 2 : 0;
|
|
138
147
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// `commands.list`: every slash command a front end offers for one scope, from one source. The
|
|
2
|
+
// terminal palette and a host's menu both read it, so they never keep their own lists.
|
|
3
|
+
import { BUILTIN_PLUGIN_REGISTRY } from "../plugins/builtin.js";
|
|
4
|
+
import { pluginCommandPrefix } from "../plugins/commandPrefix.js";
|
|
5
|
+
import { CORE_COMMANDS } from "./registry.js";
|
|
6
|
+
import { commandRoutes, promptCommandAvailable } from "./routes.js";
|
|
7
|
+
export function listCommands(plugins) {
|
|
8
|
+
const out = new Map();
|
|
9
|
+
const taken = new Set();
|
|
10
|
+
for (const command of CORE_COMMANDS) {
|
|
11
|
+
const aliases = 'aliases' in command ? [...command.aliases] : [];
|
|
12
|
+
out.set(command.name, {
|
|
13
|
+
name: command.name,
|
|
14
|
+
...(aliases.length ? { aliases } : {}),
|
|
15
|
+
...('args' in command ? { args: command.args } : {}),
|
|
16
|
+
description: command.description,
|
|
17
|
+
group: command.group,
|
|
18
|
+
source: 'core',
|
|
19
|
+
kind: command.kind
|
|
20
|
+
});
|
|
21
|
+
taken.add(command.name);
|
|
22
|
+
aliases.forEach((alias) => taken.add(alias));
|
|
23
|
+
}
|
|
24
|
+
for (const command of BUILTIN_PLUGIN_REGISTRY.commands()) {
|
|
25
|
+
const name = `${command.prefix}:${command.name}`;
|
|
26
|
+
out.set(name, { name, description: command.description, group: 'Plugins', source: 'plugin', owner: command.pluginId });
|
|
27
|
+
}
|
|
28
|
+
for (const module of BUILTIN_PLUGIN_REGISTRY.modules) {
|
|
29
|
+
const prefix = module.commandPrefix ?? module.descriptor.id;
|
|
30
|
+
const fallback = BUILTIN_PLUGIN_REGISTRY.defaultCommand(prefix);
|
|
31
|
+
if (fallback)
|
|
32
|
+
out.set(`${prefix}:`, { name: `${prefix}:`, description: fallback.description, group: 'Plugins', source: 'plugin', owner: module.descriptor.id });
|
|
33
|
+
}
|
|
34
|
+
const extensions = [];
|
|
35
|
+
const extensionCommandNames = new Set();
|
|
36
|
+
for (const plugin of plugins) {
|
|
37
|
+
for (const contribution of plugin.contributions) {
|
|
38
|
+
if (contribution.kind !== 'code' || contribution.state !== 'on' || !contribution.path || !contribution.registered)
|
|
39
|
+
continue;
|
|
40
|
+
contribution.registered.commands.forEach(name => extensionCommandNames.add(name));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
for (const plugin of plugins) {
|
|
44
|
+
for (const contribution of plugin.contributions) {
|
|
45
|
+
if (contribution.state !== 'on')
|
|
46
|
+
continue;
|
|
47
|
+
if (contribution.kind === 'code' && contribution.registered && contribution.path) {
|
|
48
|
+
const packageRoot = (plugin.source === 'package' || plugin.id.startsWith('package:')) ? plugin.path : null;
|
|
49
|
+
const prefix = pluginCommandPrefix(packageRoot
|
|
50
|
+
? { path: contribution.path, origin: 'package', baseDir: packageRoot }
|
|
51
|
+
: { path: contribution.path });
|
|
52
|
+
for (const command of contribution.registered.commands) {
|
|
53
|
+
const name = `${prefix}:${command}`;
|
|
54
|
+
extensions.push({ prefix, name: command, owner: packageRoot ? `package:${packageRoot}` : `extension:${contribution.path}`, path: contribution.path,
|
|
55
|
+
listed: { name, group: 'Plugins', source: 'extension', owner: plugin.id } });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Catalogue entries without a path are observed extension commands, not templates.
|
|
59
|
+
if (contribution.kind === 'command' && contribution.path && promptCommandAvailable(contribution.name, taken, extensionCommandNames) && !out.has(contribution.name)) {
|
|
60
|
+
out.set(contribution.name, { name: contribution.name, description: contribution.description, group: 'Prompts', source: 'prompt', owner: plugin.id });
|
|
61
|
+
}
|
|
62
|
+
if (contribution.kind === 'skill') {
|
|
63
|
+
const name = `skill:${contribution.name}`;
|
|
64
|
+
if (!out.has(name))
|
|
65
|
+
out.set(name, { name, description: contribution.description, group: 'Skills', source: 'skill', owner: plugin.id });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const indexed = commandRoutes(extensions);
|
|
70
|
+
for (const [name, routes] of indexed.routes) {
|
|
71
|
+
if (routes.length === 1 && !indexed.conflictingPrefixes.has(routes[0].prefix) && !out.has(name))
|
|
72
|
+
out.set(name, routes[0].listed);
|
|
73
|
+
}
|
|
74
|
+
return [...out.values()];
|
|
75
|
+
}
|