@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
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { parseProposedPlan, planModeTools } from "../../sessions/planMode.js";
|
|
1
|
+
export { normalModeTools, parseProposedPlan, planModeTools, QUESTION_TOOL_NAMES } from "../../sessions/planMode.js";
|
|
2
2
|
export type { ProposedPlan } from "../../sessions/planMode.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// The terminal's plan mode uses the session's read-only tool set.
|
|
2
|
-
export { parseProposedPlan, planModeTools } from "../../sessions/planMode.js";
|
|
2
|
+
export { normalModeTools, parseProposedPlan, planModeTools, QUESTION_TOOL_NAMES } from "../../sessions/planMode.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AnnotateStart } from "./pages/annotatePage.js";
|
|
2
|
+
import type { CommandPageId } from "./commandPages.js";
|
|
3
|
+
import type { TerminalCommandHost } from "./commands.js";
|
|
4
|
+
import { parseAnnotate } from "./annotateCommand.js";
|
|
5
|
+
type PageOptions = {
|
|
6
|
+
runId?: string;
|
|
7
|
+
url?: string;
|
|
8
|
+
annotate?: AnnotateStart;
|
|
9
|
+
usageTab?: 'analysis' | 'limit';
|
|
10
|
+
usagePeriod?: 'today' | '7d' | '30d' | 'all';
|
|
11
|
+
};
|
|
12
|
+
type OpenPage = (id: CommandPageId, options?: PageOptions) => Promise<void>;
|
|
13
|
+
type Handler = (argument: string) => Promise<void>;
|
|
14
|
+
/** Terminal adapters for commands declared by Harness-owned feature plugins. */
|
|
15
|
+
export declare function createBuiltinPluginCommandHandlers(host: TerminalCommandHost, openPage: OpenPage): Map<string, Handler>;
|
|
16
|
+
export { parseAnnotate };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { BUILTIN_PLUGIN_REGISTRY } from "../../plugins/builtin.js";
|
|
2
|
+
import { parseAnnotate } from "./annotateCommand.js";
|
|
3
|
+
/** Terminal adapters for commands declared by Harness-owned feature plugins. */
|
|
4
|
+
export function createBuiltinPluginCommandHandlers(host, openPage) {
|
|
5
|
+
const handlers = new Map([
|
|
6
|
+
['annotations:notes', async () => openPage('notes')],
|
|
7
|
+
['annotations:annotate', async (argument) => {
|
|
8
|
+
const start = parseAnnotate(argument);
|
|
9
|
+
if (typeof start === 'string')
|
|
10
|
+
host.ui.notify(start, 'error');
|
|
11
|
+
else
|
|
12
|
+
await openPage('annotate', { annotate: start });
|
|
13
|
+
}],
|
|
14
|
+
['usage:analysis', async (argument) => {
|
|
15
|
+
const period = argument.trim().toLowerCase();
|
|
16
|
+
if (period && !['today', '7d', '30d', 'all'].includes(period)) {
|
|
17
|
+
host.ui.notify('Use /usage:analysis today, 7d, 30d or all.', 'error');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
await openPage('usage', { usageTab: 'analysis', ...(period ? { usagePeriod: period } : {}) });
|
|
21
|
+
}],
|
|
22
|
+
['usage:limit', async () => openPage('usage', { usageTab: 'limit' })]
|
|
23
|
+
]);
|
|
24
|
+
const commands = BUILTIN_PLUGIN_REGISTRY.commands();
|
|
25
|
+
for (const command of commands) {
|
|
26
|
+
if (!handlers.has(`${command.pluginId}:${command.name}`))
|
|
27
|
+
throw new Error(`No terminal handler for built-in plugin command ${command.pluginId}:${command.name}.`);
|
|
28
|
+
}
|
|
29
|
+
return handlers;
|
|
30
|
+
}
|
|
31
|
+
export { parseAnnotate };
|
|
@@ -4,10 +4,12 @@ export interface TerminalQuestion {
|
|
|
4
4
|
requestId: string;
|
|
5
5
|
question?: string;
|
|
6
6
|
summary?: string;
|
|
7
|
+
uiSketch?: true;
|
|
7
8
|
options: {
|
|
8
9
|
label: string;
|
|
9
10
|
description?: string;
|
|
10
11
|
recommended?: boolean;
|
|
12
|
+
sketch?: string;
|
|
11
13
|
}[];
|
|
12
14
|
multiSelect?: boolean;
|
|
13
15
|
allowText?: boolean;
|
|
@@ -2,8 +2,10 @@ import { createAgentSession, createAgentSessionRuntime, DefaultResourceLoader, M
|
|
|
2
2
|
import { closeSync, existsSync, openSync, readSync, realpathSync } from 'node:fs';
|
|
3
3
|
import { isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
4
4
|
import terminalExtension from "../piExtension.js";
|
|
5
|
-
import { planModeTools } from "./planMode.js";
|
|
5
|
+
import { normalModeTools, planModeTools, QUESTION_TOOL_NAMES } from "./planMode.js";
|
|
6
6
|
import { claimTerminalControl, controlCall } from "../control.js";
|
|
7
|
+
import { observeProviderResponses } from "../../usage/limits/capture.js";
|
|
8
|
+
import { limitHeaders } from "../../usage/limits/normalize.js";
|
|
7
9
|
import { loadPiAdapter } from "./piAdapter.js";
|
|
8
10
|
import { loadPi } from "../../pi/runtime.js";
|
|
9
11
|
import { sessionUiContext } from "./sessionUi.js";
|
|
@@ -101,8 +103,16 @@ export async function createTerminalRuntime(args, host) {
|
|
|
101
103
|
const identity = await controlCall('accounts.session').catch(() => null);
|
|
102
104
|
const account = identity && typeof identity.accountId === 'string' && typeof identity.label === 'string'
|
|
103
105
|
? Object.freeze({ accountId: identity.accountId, label: identity.label }) : null;
|
|
104
|
-
|
|
106
|
+
await loadPiAdapter();
|
|
105
107
|
const modelRuntime = await ModelRuntime.create({ authPath: join(agentDir, 'auth.json'), modelsPath: join(agentDir, 'models.json') });
|
|
108
|
+
// This process makes the model requests, so it is where response headers are seen. Only the
|
|
109
|
+
// limit-bearing headers cross the socket, and the parent throttles what it stores.
|
|
110
|
+
observeProviderResponses(modelRuntime, (provider, response) => {
|
|
111
|
+
const headers = limitHeaders(response.headers);
|
|
112
|
+
if (!Object.keys(headers).length)
|
|
113
|
+
return;
|
|
114
|
+
void controlCall('terminal.usage.headers', { provider, status: response.status, headers }).catch(() => undefined);
|
|
115
|
+
});
|
|
106
116
|
const listeners = new Set();
|
|
107
117
|
const changes = new Set();
|
|
108
118
|
const beforeChanges = new Set();
|
|
@@ -157,11 +167,21 @@ export async function createTerminalRuntime(args, host) {
|
|
|
157
167
|
additionalSkillPaths: prepared.skills, additionalPromptTemplatePaths: prepared.prompts,
|
|
158
168
|
additionalThemePaths: prepared.themes,
|
|
159
169
|
extensionFactories: [
|
|
160
|
-
...adapter.builtins,
|
|
161
170
|
{ name: 'harness-terminal-bridge', factory: pi => terminalExtension(pi, planRun, () => native.session), hidden: true },
|
|
162
171
|
// A model picked in the terminal reaches Pi as this event. A restore is not a pick.
|
|
163
172
|
{ name: 'harness-mode-choices', factory: pi => { pi.on('model_select', event => { if (event.source !== 'restore')
|
|
164
|
-
void modeChoices.record(recordingMode(), { model: `${event.model.provider}/${event.model.id}` }); }); }, hidden: true }
|
|
173
|
+
void modeChoices.record(recordingMode(), { model: `${event.model.provider}/${event.model.id}` }); }); }, hidden: true },
|
|
174
|
+
// The bridge registers parent capabilities when delegation is available. Runs without
|
|
175
|
+
// delegation still need the same frozen snapshot, after the bridge has begun the run.
|
|
176
|
+
{ name: 'harness-run-capabilities', factory: pi => {
|
|
177
|
+
pi.on('before_agent_start', async () => {
|
|
178
|
+
if (!pi.getAllTools().some(tool => tool.name === 'spawn_subagent')) {
|
|
179
|
+
const snapshot = await controlCall('terminal.subagents.register', { tools: pi.getActiveTools(), plan: planRun.active });
|
|
180
|
+
if (Array.isArray(snapshot.connectors))
|
|
181
|
+
planRun.connectors = snapshot.connectors;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}, hidden: true }
|
|
165
185
|
],
|
|
166
186
|
appendSystemPromptOverride: (base) => [...base, ...prepared.appendSystemPrompt]
|
|
167
187
|
});
|
|
@@ -197,6 +217,7 @@ export async function createTerminalRuntime(args, host) {
|
|
|
197
217
|
...(selected?.model ? { model: selected.model } : {}),
|
|
198
218
|
...(thinkingLevel ? { thinkingLevel } : {})
|
|
199
219
|
});
|
|
220
|
+
created.session.setActiveToolsByName(normalModeTools(created.session.getActiveToolNames()));
|
|
200
221
|
const services = { cwd, agentDir, modelRuntime, settingsManager, resourceLoader, diagnostics: [] };
|
|
201
222
|
host.resources?.(services);
|
|
202
223
|
return { ...created, services, diagnostics: services.diagnostics };
|
|
@@ -296,7 +317,8 @@ export async function createTerminalRuntime(args, host) {
|
|
|
296
317
|
if (!session.isIdle)
|
|
297
318
|
throw new Error('A plan request must wait until the current response settles.');
|
|
298
319
|
const originalTools = session.getActiveToolNames();
|
|
299
|
-
const
|
|
320
|
+
const registeredQuestions = session.getAllTools().map(tool => tool.name).filter(name => QUESTION_TOOL_NAMES.has(name));
|
|
321
|
+
const allowedTools = planModeTools(originalTools, [], registeredQuestions);
|
|
300
322
|
// The session's own model and effort come back once the plan is done.
|
|
301
323
|
const previous = { model: session.model, effort: session.thinkingLevel };
|
|
302
324
|
planRun.allowedTools = new Set(allowedTools);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SessionInfo, Theme } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { type TuiMouseEventResult } from '@earendil-works/pi-tui';
|
|
3
|
+
import type { TerminalPage } from "./page.js";
|
|
4
|
+
import type { TerminalMouseInput } from "./mouse.js";
|
|
5
|
+
export declare function formatSessionRelativeTime(value: Date, now?: number): string;
|
|
6
|
+
export declare function formatSessionSize(bytes: number | undefined): string;
|
|
7
|
+
export interface ResumeSessionsPageOptions {
|
|
8
|
+
theme: () => Theme;
|
|
9
|
+
cwd(): string;
|
|
10
|
+
branch(): string | null;
|
|
11
|
+
listSessions(signal: AbortSignal): Promise<SessionInfo[]>;
|
|
12
|
+
select(path: string): void;
|
|
13
|
+
cancel(): void;
|
|
14
|
+
changed(): void;
|
|
15
|
+
}
|
|
16
|
+
export declare class ResumeSessionsPage implements TerminalPage {
|
|
17
|
+
private readonly options;
|
|
18
|
+
readonly presentation: "fullscreen";
|
|
19
|
+
private readonly list;
|
|
20
|
+
private loading;
|
|
21
|
+
private loaded;
|
|
22
|
+
private disposed;
|
|
23
|
+
private error;
|
|
24
|
+
private abort?;
|
|
25
|
+
constructor(options: ResumeSessionsPageOptions);
|
|
26
|
+
get focused(): boolean;
|
|
27
|
+
set focused(value: boolean);
|
|
28
|
+
tabs(): {
|
|
29
|
+
id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
}[];
|
|
32
|
+
activeTab(): string;
|
|
33
|
+
hint(): string;
|
|
34
|
+
activate(): void;
|
|
35
|
+
dispose(): void;
|
|
36
|
+
private load;
|
|
37
|
+
handleInput(data: string): boolean;
|
|
38
|
+
handleMouse(event: TerminalMouseInput): TuiMouseEventResult | undefined;
|
|
39
|
+
render(width: number, rows: number): string[];
|
|
40
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { stat } from 'node:fs/promises';
|
|
2
|
+
import { stripTerminalSequences } from '@earendil-works/pi-tui';
|
|
3
|
+
import { displayProjectName, singleLine } from "./status.js";
|
|
4
|
+
import { FilterList } from "./list.js";
|
|
5
|
+
const RELATIVE_TIME = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
|
|
6
|
+
const TIME_UNITS = [
|
|
7
|
+
[365 * 24 * 60 * 60 * 1000, 'year'],
|
|
8
|
+
[30 * 24 * 60 * 60 * 1000, 'month'],
|
|
9
|
+
[7 * 24 * 60 * 60 * 1000, 'week'],
|
|
10
|
+
[24 * 60 * 60 * 1000, 'day'],
|
|
11
|
+
[60 * 60 * 1000, 'hour'],
|
|
12
|
+
[60 * 1000, 'minute'],
|
|
13
|
+
[1000, 'second']
|
|
14
|
+
];
|
|
15
|
+
export function formatSessionRelativeTime(value, now = Date.now()) {
|
|
16
|
+
const delta = value.getTime() - now;
|
|
17
|
+
if (!Number.isFinite(delta))
|
|
18
|
+
return 'unknown time';
|
|
19
|
+
const absolute = Math.abs(delta);
|
|
20
|
+
const unit = TIME_UNITS.find(([size]) => absolute >= size);
|
|
21
|
+
return unit ? RELATIVE_TIME.format(Math.round(delta / unit[0]), unit[1]) : RELATIVE_TIME.format(0, 'second');
|
|
22
|
+
}
|
|
23
|
+
export function formatSessionSize(bytes) {
|
|
24
|
+
if (typeof bytes !== 'number' || !Number.isFinite(bytes) || bytes < 0)
|
|
25
|
+
return '—';
|
|
26
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
27
|
+
let size = bytes;
|
|
28
|
+
let unit = 0;
|
|
29
|
+
while (size >= 1024 && unit < units.length - 1) {
|
|
30
|
+
size /= 1024;
|
|
31
|
+
unit += 1;
|
|
32
|
+
}
|
|
33
|
+
return `${unit === 0 ? Math.round(size) : size.toFixed(1)}${units[unit]}`;
|
|
34
|
+
}
|
|
35
|
+
function safe(value) {
|
|
36
|
+
return stripTerminalSequences(value).replace(/[\x00-\x08\x0b-\x1f\x7f]/g, ' ');
|
|
37
|
+
}
|
|
38
|
+
export class ResumeSessionsPage {
|
|
39
|
+
options;
|
|
40
|
+
presentation = 'fullscreen';
|
|
41
|
+
list;
|
|
42
|
+
loading = false;
|
|
43
|
+
loaded = false;
|
|
44
|
+
disposed = false;
|
|
45
|
+
error;
|
|
46
|
+
abort;
|
|
47
|
+
constructor(options) {
|
|
48
|
+
this.options = options;
|
|
49
|
+
this.list = new FilterList({
|
|
50
|
+
theme: options.theme,
|
|
51
|
+
search: 'always',
|
|
52
|
+
rowGap: 1,
|
|
53
|
+
noun: ['session', 'sessions'],
|
|
54
|
+
empty: 'No saved sessions in this project',
|
|
55
|
+
onCancel: options.cancel,
|
|
56
|
+
onActivate: row => { if (row.data)
|
|
57
|
+
options.select(row.data); }
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
get focused() { return this.list.focused; }
|
|
61
|
+
set focused(value) { this.list.focused = value; }
|
|
62
|
+
tabs() { return [{ id: 'sessions', title: 'Resume session' }]; }
|
|
63
|
+
activeTab() { return 'sessions'; }
|
|
64
|
+
hint() { return '↑/↓ select · type to search · Enter resume'; }
|
|
65
|
+
activate() {
|
|
66
|
+
if (this.loaded || this.loading || this.disposed)
|
|
67
|
+
return;
|
|
68
|
+
this.abort = new AbortController();
|
|
69
|
+
void this.load(this.abort.signal);
|
|
70
|
+
}
|
|
71
|
+
dispose() {
|
|
72
|
+
this.disposed = true;
|
|
73
|
+
this.abort?.abort();
|
|
74
|
+
}
|
|
75
|
+
async load(signal) {
|
|
76
|
+
this.loading = true;
|
|
77
|
+
this.options.changed();
|
|
78
|
+
try {
|
|
79
|
+
const sessions = await this.options.listSessions(signal);
|
|
80
|
+
const branch = singleLine(this.options.branch() ?? '') || '—';
|
|
81
|
+
const rows = await Promise.all(sessions.map(async (session) => {
|
|
82
|
+
let bytes;
|
|
83
|
+
try {
|
|
84
|
+
bytes = (await stat(session.path)).size;
|
|
85
|
+
}
|
|
86
|
+
catch { /* A removed or unreadable file remains selectable and shows an unknown size. */ }
|
|
87
|
+
const title = session.name?.trim() || session.firstMessage.trim() || session.id;
|
|
88
|
+
const project = displayProjectName(session.cwd || this.options.cwd());
|
|
89
|
+
const modified = formatSessionRelativeTime(session.modified);
|
|
90
|
+
const subtitle = `${modified} · ${project}:${branch} · ${formatSessionSize(bytes)}`;
|
|
91
|
+
return {
|
|
92
|
+
id: session.path,
|
|
93
|
+
label: singleLine(title),
|
|
94
|
+
subtitle,
|
|
95
|
+
searchText: `${title} ${session.firstMessage} ${session.id} ${subtitle}`,
|
|
96
|
+
data: session.path
|
|
97
|
+
};
|
|
98
|
+
}));
|
|
99
|
+
if (this.disposed || signal.aborted)
|
|
100
|
+
return;
|
|
101
|
+
this.list.setRows(rows);
|
|
102
|
+
this.error = undefined;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (!this.disposed && !signal.aborted)
|
|
106
|
+
this.error = error instanceof Error ? error.message : String(error);
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
this.loaded = true;
|
|
110
|
+
this.loading = false;
|
|
111
|
+
if (!this.disposed)
|
|
112
|
+
this.options.changed();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
handleInput(data) {
|
|
116
|
+
if (!this.list.handleInput(data))
|
|
117
|
+
return false;
|
|
118
|
+
this.options.changed();
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
handleMouse(event) {
|
|
122
|
+
if (event.type === 'move')
|
|
123
|
+
return { handled: true, render: false };
|
|
124
|
+
if (event.type === 'wheel')
|
|
125
|
+
return undefined;
|
|
126
|
+
const result = this.list.handleMouse(event);
|
|
127
|
+
if (result?.render)
|
|
128
|
+
this.options.changed();
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
render(width, rows) {
|
|
132
|
+
if (width < 1 || rows < 1)
|
|
133
|
+
return [];
|
|
134
|
+
const theme = this.options.theme();
|
|
135
|
+
if (this.error)
|
|
136
|
+
return [theme.fg('error', `Could not read saved sessions: ${safe(this.error)}`)];
|
|
137
|
+
if (this.loading || !this.loaded)
|
|
138
|
+
return [theme.fg('dim', 'Loading saved sessions…')];
|
|
139
|
+
return this.list.render(width, rows);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -3,10 +3,12 @@ import type { TerminalSettingItem } from "./pages/settingsPage.js";
|
|
|
3
3
|
export interface SettingsModelHost {
|
|
4
4
|
session(): AgentSession;
|
|
5
5
|
ui: ExtensionUIContext;
|
|
6
|
+
control<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
|
|
6
7
|
hotkeys?(): string;
|
|
7
8
|
refresh(): void;
|
|
8
9
|
}
|
|
9
10
|
export declare function createSettingsModel(host: SettingsModelHost): {
|
|
10
11
|
items: () => TerminalSettingItem[];
|
|
11
12
|
apply: (id: string) => Promise<void>;
|
|
13
|
+
load: () => Promise<void>;
|
|
12
14
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
const
|
|
1
|
+
const PRIVATE_ACCESS_ID = 'browser.allowPrivate';
|
|
2
|
+
const GROUP_ORDER = ['Theme', 'Display', 'Images', 'Thinking', 'Recovery', 'Editor', 'Queues', 'Commands', 'Terminal', 'Keyboard', 'Compaction', 'Network'];
|
|
2
3
|
export function createSettingsModel(host) {
|
|
4
|
+
let browserSettings = null;
|
|
3
5
|
const booleans = (session) => {
|
|
4
6
|
const settings = session.settingsManager;
|
|
5
7
|
return [
|
|
@@ -40,9 +42,37 @@ export function createSettingsModel(host) {
|
|
|
40
42
|
const split = option.indexOf(':');
|
|
41
43
|
return { id: String(index), tab: locations[index][0], group: locations[index][1], label: split < 0 ? option : option.slice(0, split), value: split < 0 ? '' : option.slice(split + 1).trim(), description: descriptions[index] };
|
|
42
44
|
});
|
|
45
|
+
if (browserSettings)
|
|
46
|
+
result.push({
|
|
47
|
+
id: PRIVATE_ACCESS_ID,
|
|
48
|
+
tab: 'Browser',
|
|
49
|
+
group: 'Network',
|
|
50
|
+
label: 'Private address access',
|
|
51
|
+
value: browserSettings.allowPrivate ? 'On' : 'Off',
|
|
52
|
+
description: 'This device-wide setting affects agent browsing and annotation capture. When on, pages can reach localhost and private networks.'
|
|
53
|
+
});
|
|
43
54
|
return result.sort((a, b) => GROUP_ORDER.indexOf(a.group) - GROUP_ORDER.indexOf(b.group));
|
|
44
55
|
}
|
|
56
|
+
async function load() {
|
|
57
|
+
const config = await host.control('terminal.browser.config');
|
|
58
|
+
if (!config || typeof config.allowPrivate !== 'boolean')
|
|
59
|
+
throw new Error('The Harness returned invalid browser settings.');
|
|
60
|
+
browserSettings = { allowPrivate: config.allowPrivate };
|
|
61
|
+
}
|
|
45
62
|
async function apply(id) {
|
|
63
|
+
if (id === PRIVATE_ACCESS_ID) {
|
|
64
|
+
if (!browserSettings)
|
|
65
|
+
return;
|
|
66
|
+
const allowPrivate = !browserSettings.allowPrivate;
|
|
67
|
+
if (allowPrivate && !await host.ui.confirm('Allow private network addresses?', 'This device-wide setting lets pages opened by agent browsing and annotation capture reach localhost and private networks.'))
|
|
68
|
+
return;
|
|
69
|
+
const saved = await host.control('terminal.browser.configure', { allowPrivate });
|
|
70
|
+
if (!saved || typeof saved.allowPrivate !== 'boolean')
|
|
71
|
+
throw new Error('The Harness returned invalid browser settings.');
|
|
72
|
+
browserSettings = { allowPrivate: saved.allowPrivate };
|
|
73
|
+
host.refresh();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
46
76
|
const session = host.session();
|
|
47
77
|
const index = Number(id);
|
|
48
78
|
const switches = booleans(session);
|
|
@@ -80,5 +110,5 @@ export function createSettingsModel(host) {
|
|
|
80
110
|
host.ui.notify(host.hotkeys?.() ?? 'Use /help for commands. Keyboard bindings are managed by the terminal application.', 'info');
|
|
81
111
|
host.refresh();
|
|
82
112
|
}
|
|
83
|
-
return { items, apply };
|
|
113
|
+
return { items, apply, load };
|
|
84
114
|
}
|
|
@@ -1,29 +1,20 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { Theme } from '@earendil-works/pi-coding-agent';
|
|
2
2
|
import { type Component } from '@earendil-works/pi-tui';
|
|
3
|
-
|
|
4
|
-
export declare const ANSWER_ROWS = 8;
|
|
5
|
-
/**
|
|
6
|
-
* A bounded plain-text excerpt of the main conversation: the last few user and assistant turns, the
|
|
7
|
-
* tools an assistant turn called by name, and whether the reply is still running. Hidden reasoning,
|
|
8
|
-
* tool inputs and results, and images are left out.
|
|
9
|
-
*/
|
|
10
|
-
export declare function sideQuestionSnapshot(messages: readonly unknown[], running: boolean): string;
|
|
11
|
-
/** What the controller needs from a session; a Pi `AgentSession` satisfies it through `createSideSession`. */
|
|
12
|
-
export interface SideSession {
|
|
13
|
-
prompt(text: string): Promise<void>;
|
|
14
|
-
abort(): Promise<void>;
|
|
15
|
-
subscribe(listener: () => void): () => void;
|
|
16
|
-
answer(): string;
|
|
17
|
-
/** Why the provider ended the turn in error, if it did. */
|
|
18
|
-
failure(): string | undefined;
|
|
19
|
-
dispose(): void;
|
|
20
|
-
}
|
|
21
|
-
/** A separate in-memory session on the same account and model, with no tools, extensions, skills or project files. */
|
|
22
|
-
export declare function createSideSession(services: AgentSessionServices, main: AgentSession): Promise<SideSession>;
|
|
3
|
+
import type { SideQuestionContext, SideQuestionRead } from "../../sessions/sideQuestions.js";
|
|
23
4
|
export type SideState = 'thinking' | 'answered' | 'failed';
|
|
5
|
+
type SideQuestionStart = {
|
|
6
|
+
runId: string;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
nativeSessionId: string | null;
|
|
9
|
+
};
|
|
10
|
+
/** Visible native history and tool activity, with hidden reasoning and image bytes omitted. */
|
|
11
|
+
export declare function sideQuestionSnapshot(messages: readonly unknown[], running: boolean): string;
|
|
24
12
|
export interface SideQuestionOptions {
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
context(): SideQuestionContext;
|
|
14
|
+
start(question: string, context: SideQuestionContext): Promise<SideQuestionStart>;
|
|
15
|
+
read(runId: string, afterSequence: number): Promise<SideQuestionRead>;
|
|
16
|
+
interrupt(runId: string): Promise<unknown>;
|
|
17
|
+
copyText(text: string): Promise<void>;
|
|
27
18
|
theme(): Theme;
|
|
28
19
|
/** Puts the dock above the composer, or takes it away. */
|
|
29
20
|
mount(dock: Component | undefined): void;
|
|
@@ -31,23 +22,32 @@ export interface SideQuestionOptions {
|
|
|
31
22
|
}
|
|
32
23
|
export declare class SideQuestion {
|
|
33
24
|
private readonly options;
|
|
34
|
-
private
|
|
35
|
-
private unsubscribe;
|
|
25
|
+
private runId;
|
|
36
26
|
private generation;
|
|
27
|
+
private pollTimer;
|
|
37
28
|
private question;
|
|
38
29
|
private answerText;
|
|
39
30
|
private error;
|
|
40
31
|
private current;
|
|
41
32
|
private startedAt;
|
|
33
|
+
private afterSequence;
|
|
34
|
+
private answerOffset;
|
|
42
35
|
private readonly dock;
|
|
43
36
|
constructor(options: SideQuestionOptions);
|
|
44
37
|
get visible(): boolean;
|
|
45
38
|
get state(): SideState | undefined;
|
|
39
|
+
get answer(): string;
|
|
46
40
|
/** Asks one question, replacing any earlier one. Empty text dismisses. */
|
|
47
41
|
ask(question: string): Promise<void>;
|
|
42
|
+
/** Scrolls the answer while it is longer than the dock. */
|
|
43
|
+
scroll(direction: 'up' | 'down'): void;
|
|
44
|
+
/** Copies the whole side answer, including any lines outside the dock. */
|
|
45
|
+
copyAnswer(): Promise<void>;
|
|
48
46
|
/** Interrupts a running side question and removes the dock. */
|
|
49
47
|
dismiss(): Promise<void>;
|
|
48
|
+
private poll;
|
|
50
49
|
private release;
|
|
51
|
-
/** The dock:
|
|
50
|
+
/** The dock: question, a scrollable answer window, and a hint for browsing or copying. */
|
|
52
51
|
private render;
|
|
53
52
|
}
|
|
53
|
+
export {};
|