@gajae-code/coding-agent 0.11.1 → 0.11.3
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 +64 -0
- package/dist/types/cli/config-cli.d.ts +11 -1
- package/dist/types/cli/launch-disposition.d.ts +23 -0
- package/dist/types/cli/notify-cli.d.ts +1 -0
- package/dist/types/cli/session-picker.d.ts +2 -1
- package/dist/types/cli/setup-cli.d.ts +1 -1
- package/dist/types/commands/mcp-serve.d.ts +33 -0
- package/dist/types/commands/mcp.d.ts +1 -1
- package/dist/types/commands/notify.d.ts +0 -2
- package/dist/types/commands/sdk.d.ts +1 -1
- package/dist/types/config/atomic-yaml-patch.d.ts +18 -0
- package/dist/types/config/file-lock.d.ts +14 -4
- package/dist/types/config/keybindings.d.ts +42 -1
- package/dist/types/config/model-auth.d.ts +3 -0
- package/dist/types/config/model-bindings-applier.d.ts +13 -0
- package/dist/types/config/model-discovery-manager.d.ts +49 -0
- package/dist/types/config/model-equivalence.d.ts +20 -0
- package/dist/types/config/model-registry.d.ts +16 -15
- package/dist/types/config/model-resolver.d.ts +28 -18
- package/dist/types/config/models-config-schema.d.ts +11 -0
- package/dist/types/config/settings-schema.d.ts +141 -11
- package/dist/types/config/settings.d.ts +14 -11
- package/dist/types/coordinator-mcp/policy.d.ts +5 -0
- package/dist/types/coordinator-mcp/question-gate-codec.d.ts +129 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +356 -0
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/discovery/helpers.d.ts +0 -6
- package/dist/types/edit/index.d.ts +3 -0
- package/dist/types/eval/py/env.d.ts +9 -0
- package/dist/types/extensibility/extensions/loader.d.ts +2 -1
- package/dist/types/extensibility/extensions/runner.d.ts +2 -2
- package/dist/types/extensibility/extensions/types.d.ts +34 -3
- package/dist/types/extensibility/hooks/runner.d.ts +1 -1
- package/dist/types/extensibility/shared-events.d.ts +2 -0
- package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +10 -1
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +44 -0
- package/dist/types/gjc-runtime/goal-mode-request.d.ts +11 -1
- package/dist/types/gjc-runtime/launch-worktree.d.ts +4 -2
- package/dist/types/gjc-runtime/linux-proc.d.ts +29 -0
- package/dist/types/gjc-runtime/session-resolution.d.ts +2 -2
- package/dist/types/gjc-runtime/state-migrations.d.ts +1 -1
- package/dist/types/gjc-runtime/state-writer.d.ts +2 -1
- package/dist/types/gjc-runtime/team-launch.d.ts +59 -0
- package/dist/types/gjc-runtime/team-notify.d.ts +45 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +29 -121
- package/dist/types/gjc-runtime/team-store.d.ts +160 -0
- package/dist/types/gjc-runtime/team-workers.d.ts +78 -0
- package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +8 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +13 -0
- package/dist/types/gjc-runtime/ultragoal-evidence.d.ts +38 -0
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +7 -0
- package/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +23 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +55 -33
- package/dist/types/gjc-runtime/workflow-cli-common.d.ts +8 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -0
- package/dist/types/goals/continuation-timeout-guard.d.ts +22 -0
- package/dist/types/goals/runtime.d.ts +1 -0
- package/dist/types/goals/state.d.ts +8 -0
- package/dist/types/harness-control-plane/lifecycle-reconciliation.d.ts +17 -0
- package/dist/types/harness-control-plane/phase-rollup.d.ts +4 -7
- package/dist/types/harness-control-plane/receipt-ingest.d.ts +5 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/state.d.ts +11 -4
- package/dist/types/lsp/lspmux.d.ts +5 -3
- package/dist/types/lsp/path-trust.d.ts +1 -0
- package/dist/types/main.d.ts +4 -2
- package/dist/types/memories/storage.d.ts +1 -0
- package/dist/types/modes/action-registry.d.ts +29 -0
- package/dist/types/modes/components/chrome.d.ts +14 -0
- package/dist/types/modes/components/command-palette.d.ts +27 -0
- package/dist/types/modes/components/custom-provider-wizard.d.ts +1 -0
- package/dist/types/modes/components/index.d.ts +2 -1
- package/dist/types/modes/components/pet-selector.d.ts +1 -1
- package/dist/types/modes/components/plan-preview-overlay.d.ts +43 -0
- package/dist/types/modes/components/queue-mode-selector.d.ts +1 -1
- package/dist/types/modes/components/queue-pane.d.ts +12 -0
- package/dist/types/modes/components/read-tool-group.d.ts +6 -0
- package/dist/types/modes/components/session-observer-overlay.d.ts +3 -4
- package/dist/types/modes/components/sessions-dashboard.d.ts +32 -0
- package/dist/types/modes/components/settings-selector.d.ts +1 -1
- package/dist/types/modes/components/show-images-selector.d.ts +1 -1
- package/dist/types/modes/components/status-line/types.d.ts +1 -1
- package/dist/types/modes/components/status-line.d.ts +1 -94
- package/dist/types/modes/components/tasks-pane.d.ts +15 -0
- package/dist/types/modes/components/theme-selector.d.ts +1 -1
- package/dist/types/modes/components/tool-execution.d.ts +15 -0
- package/dist/types/modes/components/tool-status-header.d.ts +111 -0
- package/dist/types/modes/components/transcript-viewer-overlay.d.ts +42 -0
- package/dist/types/modes/controllers/goal-mode-controller.d.ts +62 -0
- package/dist/types/modes/controllers/input-controller.d.ts +8 -1
- package/dist/types/modes/controllers/mode-gate.d.ts +8 -0
- package/dist/types/modes/controllers/plan-mode-controller.d.ts +65 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +15 -3
- package/dist/types/modes/controllers/stt-controller.d.ts +26 -0
- package/dist/types/modes/interactive-mode.d.ts +19 -17
- package/dist/types/modes/jobs-observer.d.ts +2 -0
- package/dist/types/modes/prompt-action-autocomplete.d.ts +4 -0
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -11
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +20 -2
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +31 -0
- package/dist/types/modes/tasks-aggregator.d.ts +39 -0
- package/dist/types/modes/transcript-item-registry.d.ts +60 -0
- package/dist/types/modes/types.d.ts +20 -13
- package/dist/types/modes/utils/ui-helpers.d.ts +2 -2
- package/dist/types/runtime-mcp/manager.d.ts +1 -1
- package/dist/types/sdk/broker/broker.d.ts +78 -12
- package/dist/types/sdk/broker/lifecycle-codec.d.ts +4 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +15 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +6 -2
- package/dist/types/sdk/broker/process-incarnation.d.ts +2 -0
- package/dist/types/sdk/broker/session-index.d.ts +0 -1
- package/dist/types/sdk/broker/state-version.d.ts +2 -0
- package/dist/types/sdk/bus/chat-effect-journal.d.ts +1 -0
- package/dist/types/sdk/bus/config-commands.d.ts +1 -1
- package/dist/types/sdk/bus/config.d.ts +11 -0
- package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
- package/dist/types/sdk/bus/html-format.d.ts +3 -2
- package/dist/types/sdk/bus/index.d.ts +29 -0
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
- package/dist/types/sdk/bus/notification-service.d.ts +20 -0
- package/dist/types/sdk/bus/rate-limit-pool.d.ts +13 -2
- package/dist/types/sdk/bus/recent-activity.d.ts +21 -12
- package/dist/types/sdk/bus/rich-document.d.ts +7 -0
- package/dist/types/sdk/bus/rich-render.d.ts +18 -41
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -4
- package/dist/types/sdk/bus/telegram-daemon.d.ts +46 -3
- package/dist/types/sdk/bus/threaded-inbound.d.ts +1 -1
- package/dist/types/sdk/bus/threaded-render.d.ts +13 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +24 -2
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/host/host.d.ts +2 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/session-directory.d.ts +56 -0
- package/dist/types/sdk/session.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +82 -47
- package/dist/types/session/agent-storage.d.ts +7 -0
- package/dist/types/session/fallback-chain-controller.d.ts +10 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +102 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +38 -0
- package/dist/types/session/messages.d.ts +16 -0
- package/dist/types/session/session-manager-internal.d.ts +14 -0
- package/dist/types/session/session-manager.d.ts +82 -12
- package/dist/types/session/session-storage.d.ts +43 -3
- package/dist/types/session/volatile-context-pruning.d.ts +15 -0
- package/dist/types/skill-state/{deep-interview-mutation-guard.d.ts → workflow-mutation-guard.d.ts} +24 -8
- package/dist/types/skill-state/workflow-state-contract.d.ts +1 -3
- package/dist/types/slash-commands/builtin-registry.d.ts +4 -1
- package/dist/types/system-prompt.d.ts +2 -11
- package/dist/types/task/executor.d.ts +3 -1
- package/dist/types/thinking.d.ts +7 -0
- package/dist/types/tool-discovery/tool-index.d.ts +1 -50
- package/dist/types/tools/ask.d.ts +64 -2
- package/dist/types/tools/bash.d.ts +3 -0
- package/dist/types/tools/browser/dead-tab-recovery.d.ts +24 -0
- package/dist/types/tools/browser/tab-supervisor.d.ts +21 -0
- package/dist/types/tools/cron.d.ts +2 -0
- package/dist/types/tools/fetch.d.ts +1 -0
- package/dist/types/tools/index.d.ts +30 -15
- package/dist/types/tools/output-meta.d.ts +1 -0
- package/dist/types/tools/read.d.ts +5 -0
- package/dist/types/tools/search-tool-bm25.d.ts +3 -4
- package/dist/types/tools/subagent.d.ts +1 -0
- package/dist/types/utils/event-bus.d.ts +1 -1
- package/dist/types/utils/file-mentions.d.ts +3 -3
- package/dist/types/web/search/index.d.ts +3 -1
- package/package.json +21 -9
- package/scripts/build-sdk-package-smoke.ts +34 -1
- package/scripts/generate-hotkeys-docs.ts +74 -0
- package/scripts/generate-sdk-operation-inventory.ts +64 -20
- package/scripts/verify-gjc-sdk-canonicalization.ts +182 -2
- package/src/async/job-manager.ts +49 -6
- package/src/cli/config-cli.ts +75 -2
- package/src/cli/launch-disposition.ts +42 -0
- package/src/cli/notify-cli.ts +92 -26
- package/src/cli/session-picker.ts +20 -3
- package/src/cli/setup-cli.ts +1 -1
- package/src/cli.ts +1 -1
- package/src/commands/config.ts +1 -1
- package/src/commands/harness.ts +34 -106
- package/src/commands/launch.ts +6 -4
- package/src/commands/mcp-serve.ts +85 -8
- package/src/commands/mcp.ts +2 -2
- package/src/commands/notify.ts +8 -4
- package/src/commands/sdk.ts +61 -40
- package/src/commands/ultragoal.ts +4 -1
- package/src/config/atomic-yaml-patch.ts +80 -13
- package/src/config/file-lock.ts +105 -43
- package/src/config/keybindings.ts +64 -20
- package/src/config/model-auth.ts +9 -0
- package/src/config/model-bindings-applier.ts +139 -0
- package/src/config/model-discovery-manager.ts +224 -0
- package/src/config/model-equivalence.ts +66 -0
- package/src/config/model-registry.ts +169 -302
- package/src/config/model-resolver.ts +361 -369
- package/src/config/models-config-schema.ts +5 -4
- package/src/config/settings-schema.ts +214 -12
- package/src/config/settings.ts +458 -482
- package/src/coordinator-mcp/policy.ts +76 -11
- package/src/coordinator-mcp/question-gate-codec.ts +274 -0
- package/src/coordinator-mcp/question-state.ts +778 -0
- package/src/coordinator-mcp/server.ts +1702 -238
- package/src/debug/index.ts +1 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +13 -1
- package/src/defaults/gjc/skills/team/SKILL.md +16 -0
- package/src/discovery/helpers.ts +1 -50
- package/src/edit/index.ts +64 -0
- package/src/eval/py/env.ts +26 -0
- package/src/eval/py/kernel.ts +5 -3
- package/src/extensibility/extensions/loader.ts +9 -1
- package/src/extensibility/extensions/runner.ts +12 -3
- package/src/extensibility/extensions/types.ts +39 -1
- package/src/extensibility/gjc-plugins/installer.ts +16 -16
- package/src/extensibility/hooks/runner.ts +2 -2
- package/src/extensibility/runtime-skill-discovery.ts +33 -13
- package/src/extensibility/shared-events.ts +2 -0
- package/src/gjc-runtime/deep-interview-recorder.ts +63 -3
- package/src/gjc-runtime/deep-interview-runtime.ts +76 -27
- package/src/gjc-runtime/deep-interview-state.ts +317 -5
- package/src/gjc-runtime/goal-mode-request.ts +55 -8
- package/src/gjc-runtime/launch-tmux.ts +2 -5
- package/src/gjc-runtime/launch-worktree.ts +5 -5
- package/src/gjc-runtime/linux-proc.ts +71 -0
- package/src/gjc-runtime/ralplan-runtime.ts +74 -90
- package/src/gjc-runtime/session-resolution.ts +18 -3
- package/src/gjc-runtime/session-state-sidecar.ts +6 -107
- package/src/gjc-runtime/state-migrations.ts +1 -1
- package/src/gjc-runtime/state-runtime.ts +327 -249
- package/src/gjc-runtime/state-writer.ts +36 -40
- package/src/gjc-runtime/team-launch.ts +319 -0
- package/src/gjc-runtime/team-notify.ts +326 -0
- package/src/gjc-runtime/team-runtime.ts +1099 -1482
- package/src/gjc-runtime/team-store.ts +828 -0
- package/src/gjc-runtime/team-workers.ts +962 -0
- package/src/gjc-runtime/tmux-owner-isolation-cli.ts +2 -11
- package/src/gjc-runtime/tmux-owner-isolation.ts +14 -9
- package/src/gjc-runtime/tmux-sessions.ts +4 -21
- package/src/gjc-runtime/ultragoal-change-set.ts +172 -0
- package/src/gjc-runtime/ultragoal-evidence.ts +874 -0
- package/src/gjc-runtime/ultragoal-guard.ts +29 -5
- package/src/gjc-runtime/ultragoal-pipeline.ts +306 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +84 -1311
- package/src/gjc-runtime/workflow-cli-common.ts +30 -0
- package/src/gjc-runtime/workflow-manifest.generated.json +58 -0
- package/src/gjc-runtime/workflow-manifest.ts +18 -0
- package/src/goals/continuation-timeout-guard.ts +79 -0
- package/src/goals/runtime.ts +7 -5
- package/src/goals/state.ts +18 -0
- package/src/harness-control-plane/lifecycle-reconciliation.ts +64 -0
- package/src/harness-control-plane/phase-rollup.ts +4 -7
- package/src/harness-control-plane/receipt-ingest.ts +5 -0
- package/src/harness-control-plane/receipt-spool.ts +51 -7
- package/src/harness-control-plane/session-lease.ts +12 -130
- package/src/hindsight/backend.ts +26 -27
- package/src/hindsight/state.ts +101 -32
- package/src/hooks/skill-state.ts +17 -11
- package/src/internal-urls/docs-index.generated.ts +21 -18
- package/src/lsp/client.ts +1 -1
- package/src/lsp/config.ts +145 -26
- package/src/lsp/index.ts +1 -1
- package/src/lsp/lspmux.ts +39 -10
- package/src/lsp/path-trust.ts +81 -0
- package/src/main.ts +127 -30
- package/src/memories/index.ts +1 -0
- package/src/memories/storage.ts +6 -2
- package/src/modes/action-registry.ts +165 -0
- package/src/modes/components/chrome.ts +40 -0
- package/src/modes/components/command-palette.ts +168 -0
- package/src/modes/components/custom-editor.ts +1 -1
- package/src/modes/components/custom-provider-wizard.ts +51 -14
- package/src/modes/components/index.ts +2 -1
- package/src/modes/components/pet-selector.ts +11 -17
- package/src/modes/components/plan-preview-overlay.ts +295 -0
- package/src/modes/components/queue-mode-selector.ts +10 -27
- package/src/modes/components/queue-pane.ts +79 -0
- package/src/modes/components/read-tool-group.ts +13 -0
- package/src/modes/components/session-observer-overlay.ts +207 -772
- package/src/modes/components/sessions-dashboard.ts +181 -0
- package/src/modes/components/settings-selector.ts +1 -1
- package/src/modes/components/show-images-selector.ts +10 -24
- package/src/modes/components/status-line/types.ts +1 -1
- package/src/modes/components/status-line.ts +1 -969
- package/src/modes/components/tasks-pane.ts +73 -0
- package/src/modes/components/theme-selector.ts +11 -31
- package/src/modes/components/tool-execution.ts +22 -0
- package/src/modes/components/tool-status-header.ts +1056 -0
- package/src/modes/components/transcript-viewer-overlay.ts +384 -0
- package/src/modes/controllers/btw-controller.ts +1 -0
- package/src/modes/controllers/event-controller.ts +3 -2
- package/src/modes/controllers/extension-ui-controller.ts +24 -1
- package/src/modes/controllers/goal-mode-controller.ts +474 -0
- package/src/modes/controllers/input-controller.ts +764 -229
- package/src/modes/controllers/mode-gate.ts +24 -0
- package/src/modes/controllers/plan-mode-controller.ts +517 -0
- package/src/modes/controllers/selector-controller.ts +225 -10
- package/src/modes/controllers/stt-controller.ts +125 -0
- package/src/modes/interactive-mode.ts +289 -1150
- package/src/modes/jobs-observer.ts +3 -0
- package/src/modes/prompt-action-autocomplete.ts +7 -0
- package/src/modes/runtime-init.ts +8 -0
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +31 -106
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +71 -16
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +177 -0
- package/src/modes/tasks-aggregator.ts +199 -0
- package/src/modes/transcript-item-registry.ts +229 -0
- package/src/modes/types.ts +45 -18
- package/src/modes/utils/ui-helpers.ts +17 -9
- package/src/prompts/agent-fragments/ralplan-persistence.md +6 -0
- package/src/prompts/agent-fragments/restricted-bash.md +1 -0
- package/src/prompts/agents/architect.md +2 -8
- package/src/prompts/agents/critic.md +2 -8
- package/src/prompts/agents/executor.md +3 -0
- package/src/prompts/agents/planner.md +4 -12
- package/src/prompts/system/custom-system-prompt.md +1 -23
- package/src/prompts/system/plan-mode-approved.md +8 -0
- package/src/prompts/system/system-prompt.md +17 -96
- package/src/prompts/tools/bash.md +4 -4
- package/src/prompts/tools/browser.md +15 -52
- package/src/prompts/tools/find.md +2 -2
- package/src/prompts/tools/hashline.md +13 -55
- package/src/prompts/tools/read.md +3 -6
- package/src/prompts/tools/search-tool-bm25.md +0 -2
- package/src/prompts/tools/search.md +2 -4
- package/src/prompts/tools/skill-discovery.md +1 -2
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-mcp/manager.ts +1 -1
- package/src/sdk/broker/broker.ts +206 -78
- package/src/sdk/broker/discovery.ts +1 -1
- package/src/sdk/broker/ensure.ts +3 -1
- package/src/sdk/broker/lifecycle-codec.ts +11 -0
- package/src/sdk/broker/lifecycle-ledger.ts +371 -74
- package/src/sdk/broker/lifecycle.ts +1399 -142
- package/src/sdk/broker/process-incarnation.ts +5 -13
- package/src/sdk/broker/session-index.ts +145 -56
- package/src/sdk/broker/state-version.ts +21 -0
- package/src/sdk/broker/transport.ts +1 -1
- package/src/sdk/bus/chat-daemon-cli.ts +2 -0
- package/src/sdk/bus/chat-daemon-control.ts +8 -28
- package/src/sdk/bus/chat-effect-journal.ts +10 -2
- package/src/sdk/bus/config-commands.ts +5 -4
- package/src/sdk/bus/config.ts +98 -0
- package/src/sdk/bus/conversation-store.ts +5 -29
- package/src/sdk/bus/daemon-paths.ts +2 -0
- package/src/sdk/bus/html-format.ts +20 -3
- package/src/sdk/bus/index.ts +782 -94
- package/src/sdk/bus/lifecycle-control-runtime.ts +91 -33
- package/src/sdk/bus/natives-augment.d.ts +26 -1
- package/src/sdk/bus/notification-service.ts +168 -20
- package/src/sdk/bus/rate-limit-pool.ts +58 -14
- package/src/sdk/bus/recent-activity.ts +188 -74
- package/src/sdk/bus/rich-document.ts +258 -0
- package/src/sdk/bus/rich-render.ts +62 -70
- package/src/sdk/bus/telegram-daemon-cli.ts +15 -59
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -4
- package/src/sdk/bus/telegram-daemon.ts +1389 -237
- package/src/sdk/bus/threaded-inbound.ts +8 -3
- package/src/sdk/bus/threaded-render.ts +57 -1
- package/src/sdk/bus/topic-registry.ts +120 -13
- package/src/sdk/host/control/dispatch.ts +14 -2
- package/src/sdk/host/control/operations.ts +6 -1
- package/src/sdk/host/host.ts +44 -2
- package/src/sdk/host/query/handlers.ts +20 -22
- package/src/sdk/host/query/revision-store.ts +80 -57
- package/src/sdk/index.ts +1 -0
- package/src/sdk/protocol/operation-inventory.generated.json +943 -1907
- package/src/sdk/session-directory.ts +141 -0
- package/src/sdk/session.ts +462 -480
- package/src/session/agent-session.ts +1700 -583
- package/src/session/agent-storage.ts +18 -0
- package/src/session/cache-economics.ts +25 -8
- package/src/session/fallback-chain-controller.ts +53 -3
- package/src/session/internal/managed-session-scope.ts +2226 -0
- package/src/session/internal/managed-session-storage.ts +453 -0
- package/src/session/messages.ts +91 -2
- package/src/session/session-manager-internal.ts +33 -0
- package/src/session/session-manager.ts +1112 -333
- package/src/session/session-storage.ts +444 -39
- package/src/session/volatile-context-pruning.ts +78 -0
- package/src/setup/credential-auto-import.ts +2 -1
- package/src/setup/hermes/templates/operator-instructions.v1.md +1 -1
- package/src/setup/provider-onboarding.ts +36 -61
- package/src/setup/provider-presets.json +5 -0
- package/src/skill-state/active-state.ts +3 -13
- package/src/skill-state/{deep-interview-mutation-guard.ts → workflow-mutation-guard.ts} +47 -29
- package/src/skill-state/workflow-state-contract.ts +6 -41
- package/src/slash-commands/builtin-registry.ts +46 -11
- package/src/system-prompt.ts +37 -44
- package/src/task/agents.ts +19 -1
- package/src/task/executor.ts +90 -6
- package/src/task/index.ts +36 -21
- package/src/thinking.ts +21 -6
- package/src/tool-discovery/tool-index.ts +2 -134
- package/src/tools/ask.ts +157 -21
- package/src/tools/ast-edit.ts +1 -1
- package/src/tools/bash.ts +38 -0
- package/src/tools/browser/dead-tab-recovery.ts +78 -0
- package/src/tools/browser/tab-supervisor.ts +282 -36
- package/src/tools/computer.ts +10 -3
- package/src/tools/cron.ts +30 -16
- package/src/tools/eval.ts +1 -2
- package/src/tools/fetch.ts +11 -4
- package/src/tools/index.ts +76 -24
- package/src/tools/output-meta.ts +19 -7
- package/src/tools/read.ts +219 -64
- package/src/tools/resource-gc.ts +2 -2
- package/src/tools/search-tool-bm25.ts +11 -74
- package/src/tools/subagent.ts +43 -2
- package/src/utils/event-bus.ts +9 -4
- package/src/utils/file-mentions.ts +4 -4
- package/src/web/search/index.ts +3 -3
- package/dist/types/discovery/plugin-dir-roots.d.ts +0 -15
- package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +0 -7
- package/src/discovery/plugin-dir-roots.ts +0 -28
- package/src/runtime-mcp/discoverable-tool-metadata.ts +0 -25
|
@@ -7,6 +7,7 @@ export type DiscoverableToolSource = "builtin" | "mcp" | "extension" | "custom";
|
|
|
7
7
|
export interface DiscoverableTool {
|
|
8
8
|
name: string;
|
|
9
9
|
label: string;
|
|
10
|
+
description: string;
|
|
10
11
|
/** Short BM25 corpus entry; falls back to description first 200 chars */
|
|
11
12
|
summary: string;
|
|
12
13
|
source: DiscoverableToolSource;
|
|
@@ -44,47 +45,6 @@ export interface DiscoverableToolSearchResult {
|
|
|
44
45
|
score: number;
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
// ─── Legacy MCP-typed aliases (back-compat) ──────────────────────────────────
|
|
48
|
-
|
|
49
|
-
/** @deprecated Use DiscoverableTool with source === "mcp" */
|
|
50
|
-
export type DiscoverableMCPTool = Pick<
|
|
51
|
-
DiscoverableTool,
|
|
52
|
-
"name" | "label" | "schemaKeys" | "serverName" | "mcpToolName"
|
|
53
|
-
> & { description: string };
|
|
54
|
-
|
|
55
|
-
/** @deprecated Use DiscoverableToolServerSummary */
|
|
56
|
-
export type DiscoverableMCPToolServerSummary = DiscoverableToolServerSummary;
|
|
57
|
-
|
|
58
|
-
/** @deprecated Use DiscoverableToolSummary */
|
|
59
|
-
export type DiscoverableMCPToolSummary = DiscoverableToolSummary;
|
|
60
|
-
|
|
61
|
-
/** Tool object stored on legacy MCP index documents. Carries both legacy `description` and the
|
|
62
|
-
* generic `summary`/`source` so the legacy index is structurally assignable to
|
|
63
|
-
* DiscoverableToolSearchIndex (search functions read termFrequencies, not the tool fields). */
|
|
64
|
-
export type DiscoverableMCPSearchTool = DiscoverableTool & { description: string };
|
|
65
|
-
|
|
66
|
-
/** @deprecated Use DiscoverableToolSearchDocument */
|
|
67
|
-
export interface DiscoverableMCPSearchDocument {
|
|
68
|
-
tool: DiscoverableMCPSearchTool;
|
|
69
|
-
termFrequencies: Map<string, number>;
|
|
70
|
-
length: number;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** @deprecated Use DiscoverableToolSearchIndex.
|
|
74
|
-
* Documents on this index expose `tool.description` (legacy MCP shape) while still being
|
|
75
|
-
* searchable via `searchDiscoverableTools`. */
|
|
76
|
-
export interface DiscoverableMCPSearchIndex {
|
|
77
|
-
documents: DiscoverableMCPSearchDocument[];
|
|
78
|
-
averageLength: number;
|
|
79
|
-
documentFrequencies: Map<string, number>;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** @deprecated Use DiscoverableToolSearchResult */
|
|
83
|
-
export interface DiscoverableMCPSearchResult {
|
|
84
|
-
tool: DiscoverableMCPSearchTool;
|
|
85
|
-
score: number;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
48
|
// ─── BM25 Constants ───────────────────────────────────────────────────────────
|
|
89
49
|
|
|
90
50
|
const BM25_K1 = 1.2;
|
|
@@ -194,6 +154,7 @@ export function getDiscoverableTool(
|
|
|
194
154
|
return {
|
|
195
155
|
name: tool.name,
|
|
196
156
|
label: typeof toolRecord.label === "string" ? toolRecord.label : tool.name,
|
|
157
|
+
description: rawDescription,
|
|
197
158
|
summary,
|
|
198
159
|
source,
|
|
199
160
|
serverName: typeof toolRecord.mcpServerName === "string" ? toolRecord.mcpServerName : undefined,
|
|
@@ -305,96 +266,3 @@ export function searchDiscoverableTools(
|
|
|
305
266
|
.sort((left, right) => right.score - left.score || left.tool.name.localeCompare(right.tool.name))
|
|
306
267
|
.slice(0, limit);
|
|
307
268
|
}
|
|
308
|
-
|
|
309
|
-
// ─── Legacy MCP-specific shims (back-compat wrappers) ────────────────────────
|
|
310
|
-
|
|
311
|
-
/** @deprecated Use getDiscoverableTool */
|
|
312
|
-
export function getDiscoverableMCPTool(tool: AgentTool): DiscoverableMCPTool | null {
|
|
313
|
-
const toolRecord = tool as AgentTool & {
|
|
314
|
-
label?: string;
|
|
315
|
-
description?: string;
|
|
316
|
-
mcpServerName?: string;
|
|
317
|
-
mcpToolName?: string;
|
|
318
|
-
parameters?: unknown;
|
|
319
|
-
};
|
|
320
|
-
if (!isMCPBridgeTool(toolRecord)) return null;
|
|
321
|
-
return {
|
|
322
|
-
name: tool.name,
|
|
323
|
-
label: typeof toolRecord.label === "string" ? toolRecord.label : tool.name,
|
|
324
|
-
description: typeof toolRecord.description === "string" ? toolRecord.description : "",
|
|
325
|
-
serverName: typeof toolRecord.mcpServerName === "string" ? toolRecord.mcpServerName : undefined,
|
|
326
|
-
mcpToolName: typeof toolRecord.mcpToolName === "string" ? toolRecord.mcpToolName : undefined,
|
|
327
|
-
schemaKeys: getSchemaPropertyKeys(toolRecord.parameters),
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/** @deprecated Use collectDiscoverableTools with source filter */
|
|
332
|
-
export function collectDiscoverableMCPTools(tools: Iterable<AgentTool>): DiscoverableMCPTool[] {
|
|
333
|
-
const discoverable: DiscoverableMCPTool[] = [];
|
|
334
|
-
for (const tool of tools) {
|
|
335
|
-
const metadata = getDiscoverableMCPTool(tool);
|
|
336
|
-
if (metadata) {
|
|
337
|
-
discoverable.push(metadata);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return discoverable;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/** @deprecated Use selectDiscoverableToolNamesByServer */
|
|
344
|
-
export function selectDiscoverableMCPToolNamesByServer(
|
|
345
|
-
tools: Iterable<DiscoverableMCPTool>,
|
|
346
|
-
serverNames: ReadonlySet<string>,
|
|
347
|
-
): string[] {
|
|
348
|
-
if (serverNames.size === 0) return [];
|
|
349
|
-
return Array.from(tools)
|
|
350
|
-
.filter(tool => tool.serverName !== undefined && serverNames.has(tool.serverName))
|
|
351
|
-
.map(tool => tool.name);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/** @deprecated Use summarizeDiscoverableTools */
|
|
355
|
-
export function summarizeDiscoverableMCPTools(tools: DiscoverableMCPTool[]): DiscoverableMCPToolSummary {
|
|
356
|
-
const serverToolCounts = new Map<string, number>();
|
|
357
|
-
for (const tool of tools) {
|
|
358
|
-
if (!tool.serverName) continue;
|
|
359
|
-
serverToolCounts.set(tool.serverName, (serverToolCounts.get(tool.serverName) ?? 0) + 1);
|
|
360
|
-
}
|
|
361
|
-
const servers = Array.from(serverToolCounts.entries())
|
|
362
|
-
.sort(([left], [right]) => left.localeCompare(right))
|
|
363
|
-
.map(([name, toolCount]) => ({ name, toolCount }));
|
|
364
|
-
return {
|
|
365
|
-
servers,
|
|
366
|
-
toolCount: tools.length,
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/** @deprecated Use buildDiscoverableToolSearchIndex.
|
|
371
|
-
* Builds an index whose documents preserve the legacy `description` field on each tool while
|
|
372
|
-
* also carrying the generic `summary` (set from `description`) so the index remains usable
|
|
373
|
-
* with `searchDiscoverableTools`. */
|
|
374
|
-
export function buildDiscoverableMCPSearchIndex(tools: Iterable<DiscoverableMCPTool>): DiscoverableMCPSearchIndex {
|
|
375
|
-
const adapted: DiscoverableMCPSearchTool[] = Array.from(tools).map(t => ({
|
|
376
|
-
name: t.name,
|
|
377
|
-
label: t.label,
|
|
378
|
-
description: t.description,
|
|
379
|
-
summary: t.description,
|
|
380
|
-
source: "mcp" as DiscoverableToolSource,
|
|
381
|
-
serverName: t.serverName,
|
|
382
|
-
mcpToolName: t.mcpToolName,
|
|
383
|
-
schemaKeys: t.schemaKeys,
|
|
384
|
-
}));
|
|
385
|
-
const generic = buildDiscoverableToolSearchIndex(adapted);
|
|
386
|
-
// Documents reference `adapted` tools (with `description`), so the cast is sound.
|
|
387
|
-
return generic as unknown as DiscoverableMCPSearchIndex;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/** @deprecated Use searchDiscoverableTools */
|
|
391
|
-
export function searchDiscoverableMCPTools(
|
|
392
|
-
index: DiscoverableMCPSearchIndex | DiscoverableToolSearchIndex,
|
|
393
|
-
query: string,
|
|
394
|
-
limit: number,
|
|
395
|
-
): DiscoverableMCPSearchResult[] {
|
|
396
|
-
return searchDiscoverableTools(index as DiscoverableToolSearchIndex, query, limit) as DiscoverableMCPSearchResult[];
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
/** @deprecated Use formatDiscoverableToolServerSummary */
|
|
400
|
-
export const formatDiscoverableMCPToolServerSummary = formatDiscoverableToolServerSummary;
|
package/src/tools/ask.ts
CHANGED
|
@@ -66,29 +66,130 @@ const OptionItem = z.object({
|
|
|
66
66
|
label: z.string().describe("display label"),
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
+
const DeepInterviewIntentItem = z
|
|
70
|
+
.object({
|
|
71
|
+
id: z.string().regex(/^(artifact|surface|integration|constraint):[a-z0-9][a-z0-9._/-]{0,127}$/),
|
|
72
|
+
category: z.enum(["artifact", "surface", "integration", "constraint"]),
|
|
73
|
+
statement: z.string().min(1).max(1_000),
|
|
74
|
+
})
|
|
75
|
+
.strict()
|
|
76
|
+
.superRefine((value, context) => {
|
|
77
|
+
if (!value.id.startsWith(`${value.category}:`))
|
|
78
|
+
context.addIssue({ code: "custom", message: "intent ID must use its category prefix", path: ["id"] });
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const DeepInterviewIntentContract = z
|
|
82
|
+
.object({
|
|
83
|
+
items: z.array(DeepInterviewIntentItem).min(1).max(64),
|
|
84
|
+
confirmation_options: z.array(z.string().min(1).max(200)).min(1).max(5),
|
|
85
|
+
})
|
|
86
|
+
.strict();
|
|
87
|
+
|
|
88
|
+
const DeepInterviewIntentReview = z
|
|
89
|
+
.object({
|
|
90
|
+
observed_items: z.array(DeepInterviewIntentItem).min(1).max(64),
|
|
91
|
+
supporting_substitutions: z
|
|
92
|
+
.array(
|
|
93
|
+
z
|
|
94
|
+
.object({
|
|
95
|
+
removed_id: z
|
|
96
|
+
.string()
|
|
97
|
+
.regex(/^(artifact|surface|integration|constraint):[a-z0-9][a-z0-9._/-]{0,127}$/),
|
|
98
|
+
replacement_ids: z
|
|
99
|
+
.array(z.string().regex(/^(artifact|surface|integration|constraint):[a-z0-9][a-z0-9._/-]{0,127}$/))
|
|
100
|
+
.min(1)
|
|
101
|
+
.max(64),
|
|
102
|
+
rationale: z.string().min(1).max(500),
|
|
103
|
+
})
|
|
104
|
+
.strict(),
|
|
105
|
+
)
|
|
106
|
+
.max(64),
|
|
107
|
+
approval_options: z.array(z.string().min(1).max(200)).min(1).max(5),
|
|
108
|
+
})
|
|
109
|
+
.strict();
|
|
110
|
+
|
|
69
111
|
/** Optional structured deep-interview round metadata; when present the round is recorded automatically. */
|
|
70
|
-
const DeepInterviewMeta = z
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
112
|
+
const DeepInterviewMeta = z
|
|
113
|
+
.object({
|
|
114
|
+
round_id: z.string().max(128).describe("stable optional round identity").optional(),
|
|
115
|
+
round: z.number().int().nonnegative().describe("round number"),
|
|
116
|
+
component: z.string().min(1).max(128).describe("targeted topology component"),
|
|
117
|
+
dimension: z.string().min(1).max(128).describe("targeted clarity dimension"),
|
|
118
|
+
ambiguity: z.number().min(0).max(1).describe("ambiguity at ask time (0..1)"),
|
|
119
|
+
intent_contract: DeepInterviewIntentContract.describe("Round-0 locked intent contract").optional(),
|
|
120
|
+
intent_review: DeepInterviewIntentReview.describe("Locked-intent reduction review").optional(),
|
|
121
|
+
})
|
|
122
|
+
.strict()
|
|
123
|
+
.superRefine((value, context) => {
|
|
124
|
+
if (
|
|
125
|
+
value.intent_contract &&
|
|
126
|
+
(value.round !== 0 || value.component !== "review-topology" || value.dimension !== "topology")
|
|
127
|
+
)
|
|
128
|
+
context.addIssue({
|
|
129
|
+
code: "custom",
|
|
130
|
+
message: "intent_contract requires Round 0 review-topology metadata",
|
|
131
|
+
path: ["intent_contract"],
|
|
132
|
+
});
|
|
133
|
+
if (value.intent_review && value.round === 0)
|
|
134
|
+
context.addIssue({
|
|
135
|
+
code: "custom",
|
|
136
|
+
message: "intent_review requires a post-Round-0 answer",
|
|
137
|
+
path: ["intent_review"],
|
|
138
|
+
});
|
|
139
|
+
if (value.intent_contract && value.intent_review)
|
|
140
|
+
context.addIssue({ code: "custom", message: "intent_contract and intent_review are mutually exclusive" });
|
|
141
|
+
});
|
|
77
142
|
|
|
78
143
|
const WorkflowGateMeta = z.object({
|
|
79
144
|
stage: z.enum(["deep-interview", "ralplan", "ultragoal"]).describe("workflow gate stage"),
|
|
80
145
|
kind: z.enum(["question", "approval", "execution"]).describe("workflow gate kind"),
|
|
81
146
|
});
|
|
82
147
|
|
|
83
|
-
const QuestionItem = z
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
148
|
+
const QuestionItem = z
|
|
149
|
+
.object({
|
|
150
|
+
id: z.string().describe("question id"),
|
|
151
|
+
question: z.string().describe("question text"),
|
|
152
|
+
options: z.array(OptionItem).describe("available options"),
|
|
153
|
+
multi: z.boolean().describe("allow multiple selections").optional(),
|
|
154
|
+
recommended: z.number().describe("recommended option index").optional(),
|
|
155
|
+
deepInterview: DeepInterviewMeta.describe("optional deep-interview round metadata").optional(),
|
|
156
|
+
workflowGate: WorkflowGateMeta.describe("optional workflow gate stage/kind override").optional(),
|
|
157
|
+
})
|
|
158
|
+
.superRefine((value, context) => {
|
|
159
|
+
const labels = new Set(value.options.map(option => option.label));
|
|
160
|
+
if ((value.deepInterview?.intent_contract || value.deepInterview?.intent_review) && value.multi === true)
|
|
161
|
+
context.addIssue({ code: "custom", message: "intent gates must be single-select", path: ["multi"] });
|
|
162
|
+
const confirmationOptions = value.deepInterview?.intent_contract?.confirmation_options ?? [];
|
|
163
|
+
if (new Set(confirmationOptions).size !== confirmationOptions.length)
|
|
164
|
+
context.addIssue({
|
|
165
|
+
code: "custom",
|
|
166
|
+
message: "intent confirmation options must be unique",
|
|
167
|
+
path: ["deepInterview", "intent_contract"],
|
|
168
|
+
});
|
|
169
|
+
const approvalOptions = value.deepInterview?.intent_review?.approval_options ?? [];
|
|
170
|
+
if (new Set(approvalOptions).size !== approvalOptions.length)
|
|
171
|
+
context.addIssue({
|
|
172
|
+
code: "custom",
|
|
173
|
+
message: "intent approval options must be unique",
|
|
174
|
+
path: ["deepInterview", "intent_review"],
|
|
175
|
+
});
|
|
176
|
+
for (const label of value.deepInterview?.intent_contract?.confirmation_options ?? []) {
|
|
177
|
+
if (!labels.has(label))
|
|
178
|
+
context.addIssue({
|
|
179
|
+
code: "custom",
|
|
180
|
+
message: "intent confirmation option must be displayed",
|
|
181
|
+
path: ["deepInterview", "intent_contract"],
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
for (const label of value.deepInterview?.intent_review?.approval_options ?? []) {
|
|
185
|
+
if (!labels.has(label))
|
|
186
|
+
context.addIssue({
|
|
187
|
+
code: "custom",
|
|
188
|
+
message: "intent approval option must be displayed",
|
|
189
|
+
path: ["deepInterview", "intent_review"],
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
92
193
|
|
|
93
194
|
export const askSchema = z.object({
|
|
94
195
|
questions: z.array(QuestionItem).min(1).describe("questions to ask"),
|
|
@@ -133,7 +234,11 @@ function errorMessage(error: unknown): string {
|
|
|
133
234
|
return error instanceof Error ? error.message : String(error);
|
|
134
235
|
}
|
|
135
236
|
|
|
136
|
-
async function awaitDeepInterviewRecorderPersistence(persistence: Promise<void
|
|
237
|
+
async function awaitDeepInterviewRecorderPersistence(persistence: Promise<void>, required: boolean): Promise<void> {
|
|
238
|
+
if (required) {
|
|
239
|
+
await persistence;
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
137
242
|
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
138
243
|
try {
|
|
139
244
|
await Promise.race([
|
|
@@ -147,6 +252,7 @@ async function awaitDeepInterviewRecorderPersistence(persistence: Promise<void>)
|
|
|
147
252
|
]);
|
|
148
253
|
} catch (error) {
|
|
149
254
|
logger.warn(`ask: deep-interview round recording failed: ${errorMessage(error)}`);
|
|
255
|
+
if (required) throw error;
|
|
150
256
|
} finally {
|
|
151
257
|
if (timeout) clearTimeout(timeout);
|
|
152
258
|
}
|
|
@@ -293,6 +399,7 @@ interface AskSingleQuestionOptions {
|
|
|
293
399
|
scrollTitleRows?: number;
|
|
294
400
|
otherOptionLabel?: string;
|
|
295
401
|
clarificationOptionLabel?: string;
|
|
402
|
+
autoSelectOnTimeout?: boolean;
|
|
296
403
|
onRemoteState?: (state: {
|
|
297
404
|
interaction: "selector" | "custom_editor" | "clarification_editor";
|
|
298
405
|
selectedCount: number;
|
|
@@ -334,7 +441,15 @@ async function askSingleQuestion(
|
|
|
334
441
|
multi: boolean,
|
|
335
442
|
options: AskSingleQuestionOptions = {},
|
|
336
443
|
): Promise<SelectionResult> {
|
|
337
|
-
const {
|
|
444
|
+
const {
|
|
445
|
+
recommended,
|
|
446
|
+
timeout,
|
|
447
|
+
signal,
|
|
448
|
+
initialSelection,
|
|
449
|
+
navigation,
|
|
450
|
+
scrollTitleRows,
|
|
451
|
+
autoSelectOnTimeout = true,
|
|
452
|
+
} = options;
|
|
338
453
|
const doneLabel = getDoneOptionLabel();
|
|
339
454
|
const otherOptionLabel = options.otherOptionLabel ?? OTHER_OPTION;
|
|
340
455
|
const clarificationOptionLabel = options.clarificationOptionLabel;
|
|
@@ -632,12 +747,23 @@ async function askSingleQuestion(
|
|
|
632
747
|
selectedOptions = [];
|
|
633
748
|
}
|
|
634
749
|
}
|
|
750
|
+
if (timedOut && !autoSelectOnTimeout) {
|
|
751
|
+
return {
|
|
752
|
+
selectedOptions: [],
|
|
753
|
+
customInput: undefined,
|
|
754
|
+
timedOut,
|
|
755
|
+
...(navigation?.allowForward ? { navigation: "forward" as const } : {}),
|
|
756
|
+
};
|
|
757
|
+
}
|
|
635
758
|
if (navigation?.allowForward) {
|
|
636
759
|
return { selectedOptions, customInput, timedOut, navigation: "forward" };
|
|
637
760
|
}
|
|
638
761
|
}
|
|
639
762
|
|
|
640
|
-
if (timedOut &&
|
|
763
|
+
if (timedOut && !autoSelectOnTimeout) {
|
|
764
|
+
return { selectedOptions: [], customInput: undefined, timedOut };
|
|
765
|
+
}
|
|
766
|
+
if (timedOut && selectedOptions.length === 0 && customInput === undefined && autoSelectOnTimeout) {
|
|
641
767
|
selectedOptions = getAutoSelectionOnTimeout(optionLabels, recommended);
|
|
642
768
|
}
|
|
643
769
|
|
|
@@ -724,11 +850,14 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
|
724
850
|
ambiguity: meta.ambiguity,
|
|
725
851
|
selectedOptions,
|
|
726
852
|
customInput,
|
|
853
|
+
intent_contract: meta.intent_contract,
|
|
854
|
+
intent_review: meta.intent_review,
|
|
727
855
|
},
|
|
728
856
|
{ sessionId },
|
|
729
857
|
).then(async () => {
|
|
730
858
|
await syncDeepInterviewRecorderHud(cwd, statePath, sessionId);
|
|
731
859
|
}),
|
|
860
|
+
meta.intent_contract !== undefined || meta.intent_review !== undefined,
|
|
732
861
|
);
|
|
733
862
|
}
|
|
734
863
|
|
|
@@ -1061,6 +1190,7 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
|
1061
1190
|
navigation: options?.navigation,
|
|
1062
1191
|
scrollTitleRows: isDeepInterviewQuestion ? DEEP_INTERVIEW_SELECTOR_SCROLL_TITLE_ROWS : undefined,
|
|
1063
1192
|
otherOptionLabel,
|
|
1193
|
+
autoSelectOnTimeout: !q.deepInterview?.intent_contract && !q.deepInterview?.intent_review,
|
|
1064
1194
|
clarificationOptionLabel,
|
|
1065
1195
|
onRemoteState: state => {
|
|
1066
1196
|
activeRemoteRequest = {
|
|
@@ -1145,7 +1275,10 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
|
1145
1275
|
context?.abort();
|
|
1146
1276
|
throw new ToolAbortError("Ask tool was cancelled by the user");
|
|
1147
1277
|
}
|
|
1148
|
-
if (
|
|
1278
|
+
if (
|
|
1279
|
+
clarificationQuestion === undefined &&
|
|
1280
|
+
!(timedOut && (q.deepInterview?.intent_contract || q.deepInterview?.intent_review))
|
|
1281
|
+
) {
|
|
1149
1282
|
await this.#recordDeepInterviewRound(q, selectedOptions, customInput);
|
|
1150
1283
|
}
|
|
1151
1284
|
const details: AskToolDetails = {
|
|
@@ -1223,7 +1356,10 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
|
1223
1356
|
clarificationQuestion,
|
|
1224
1357
|
};
|
|
1225
1358
|
|
|
1226
|
-
if (
|
|
1359
|
+
if (
|
|
1360
|
+
clarificationQuestion === undefined &&
|
|
1361
|
+
!(timedOut && (q.deepInterview?.intent_contract || q.deepInterview?.intent_review))
|
|
1362
|
+
) {
|
|
1227
1363
|
await this.#recordDeepInterviewRound(q, selectedOptions, customInput);
|
|
1228
1364
|
}
|
|
1229
1365
|
|
package/src/tools/ast-edit.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
|
9
9
|
import { computeLineHash, HL_BODY_SEP } from "../hashline/hash";
|
|
10
10
|
import type { Theme } from "../modes/theme/theme";
|
|
11
11
|
import astEditDescription from "../prompts/tools/ast-edit.md" with { type: "text" };
|
|
12
|
-
import { assertWorkflowMutationRawPathsAllowed } from "../skill-state/
|
|
12
|
+
import { assertWorkflowMutationRawPathsAllowed } from "../skill-state/workflow-mutation-guard";
|
|
13
13
|
import { Ellipsis, fileHyperlink, renderStatusLine, renderTreeList, truncateToWidth } from "../tui";
|
|
14
14
|
import { resolveFileDisplayMode } from "../utils/file-display-mode";
|
|
15
15
|
import type { ToolSession } from ".";
|
package/src/tools/bash.ts
CHANGED
|
@@ -99,6 +99,43 @@ export interface BashToolDetails {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/** Project only a bare executable name; commands and their output are never notification-safe. */
|
|
103
|
+
export function summarizeBashToolActivity(kind: "args" | "result", value: unknown): string | undefined {
|
|
104
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
|
|
105
|
+
const record = value as Record<string, unknown>;
|
|
106
|
+
if (kind === "args") {
|
|
107
|
+
const command = record.command;
|
|
108
|
+
if (typeof command !== "string") return undefined;
|
|
109
|
+
const program = command.trim().match(/^([A-Za-z][A-Za-z0-9_.+-]*)\b/)?.[1];
|
|
110
|
+
if (
|
|
111
|
+
!program ||
|
|
112
|
+
program.length > 80 ||
|
|
113
|
+
/(?:api[-_ ]?key|access[-_ ]?token|bearer|secret|password|\b(?:sk|pk|rk)-)/i.test(program)
|
|
114
|
+
) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
return program;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const output =
|
|
121
|
+
typeof record.output === "string"
|
|
122
|
+
? record.output
|
|
123
|
+
: Array.isArray(record.content)
|
|
124
|
+
? record.content
|
|
125
|
+
.filter(
|
|
126
|
+
(block): block is { type: unknown; text: unknown } =>
|
|
127
|
+
typeof block === "object" && block !== null && "type" in block && "text" in block,
|
|
128
|
+
)
|
|
129
|
+
.filter(block => block.type === "text" && typeof block.text === "string")
|
|
130
|
+
.map(block => block.text as string)
|
|
131
|
+
.join("\n")
|
|
132
|
+
: undefined;
|
|
133
|
+
if (output === undefined) return undefined;
|
|
134
|
+
const exitCode = typeof record.exitCode === "number" ? `exit=${record.exitCode}` : "completed";
|
|
135
|
+
const lines = output.length === 0 ? 0 : output.split("\n").length;
|
|
136
|
+
return `${exitCode}, ${lines} lines, ${Buffer.byteLength(output, "utf-8")} bytes`;
|
|
137
|
+
}
|
|
138
|
+
|
|
102
139
|
export interface BashToolOptions {}
|
|
103
140
|
|
|
104
141
|
type ManagedBashJobCompletion =
|
|
@@ -248,6 +285,7 @@ export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
|
|
|
248
285
|
readonly parameters: BashToolSchema;
|
|
249
286
|
readonly concurrency = "exclusive";
|
|
250
287
|
readonly strict = true;
|
|
288
|
+
readonly safeSummary = summarizeBashToolActivity;
|
|
251
289
|
readonly #asyncEnabled: boolean;
|
|
252
290
|
readonly #autoBackgroundEnabled: boolean;
|
|
253
291
|
readonly #autoBackgroundThresholdMs: number;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export type DeadTabRecoveryConsumeStatus = "consumed" | "expired_or_missing" | "owner_mismatch";
|
|
2
|
+
|
|
3
|
+
export interface DeadTabRecoveryConsumeResult<T> {
|
|
4
|
+
status: DeadTabRecoveryConsumeStatus;
|
|
5
|
+
descriptor?: T;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface StoredDescriptor<T> {
|
|
9
|
+
descriptor: T;
|
|
10
|
+
ownerId: string | undefined;
|
|
11
|
+
expiresAt: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface DeadTabRecoveryDeps {
|
|
15
|
+
now(): number;
|
|
16
|
+
onPeek(): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const DEFAULT_TTL_MS = 30_000;
|
|
20
|
+
const descriptors = new Map<string, StoredDescriptor<unknown>>();
|
|
21
|
+
let deps: DeadTabRecoveryDeps = { now: () => Date.now(), onPeek: () => {} };
|
|
22
|
+
|
|
23
|
+
/** Store a short-lived immutable recovery descriptor for a dead tab worker. */
|
|
24
|
+
export function registerDeadTabRecovery<T extends object>(
|
|
25
|
+
name: string,
|
|
26
|
+
ownerId: string | undefined,
|
|
27
|
+
descriptor: T,
|
|
28
|
+
ttlMs = DEFAULT_TTL_MS,
|
|
29
|
+
): void {
|
|
30
|
+
descriptors.set(name, { descriptor: Object.freeze(descriptor), ownerId, expiresAt: deps.now() + ttlMs });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Check whether a recovery descriptor may be consumed by this owner. The test hook is
|
|
35
|
+
* intentionally synchronous: recovery must not yield between this check and consume.
|
|
36
|
+
*/
|
|
37
|
+
export function peekDeadTabRecovery<T>(name: string, ownerId: string | undefined): DeadTabRecoveryConsumeResult<T> {
|
|
38
|
+
const stored = descriptors.get(name);
|
|
39
|
+
const result: DeadTabRecoveryConsumeResult<T> =
|
|
40
|
+
!stored || stored.expiresAt <= deps.now()
|
|
41
|
+
? { status: "expired_or_missing" }
|
|
42
|
+
: stored.ownerId !== ownerId
|
|
43
|
+
? { status: "owner_mismatch" }
|
|
44
|
+
: { status: "consumed", descriptor: stored.descriptor as T };
|
|
45
|
+
deps.onPeek();
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Consume only a live descriptor belonging to the expected owner. */
|
|
50
|
+
export function consumeDeadTabRecovery<T>(name: string, ownerId: string | undefined): DeadTabRecoveryConsumeResult<T> {
|
|
51
|
+
const stored = descriptors.get(name);
|
|
52
|
+
if (!stored || stored.expiresAt <= deps.now()) {
|
|
53
|
+
if (stored) descriptors.delete(name);
|
|
54
|
+
return { status: "expired_or_missing" };
|
|
55
|
+
}
|
|
56
|
+
if (stored.ownerId !== ownerId) return { status: "owner_mismatch" };
|
|
57
|
+
descriptors.delete(name);
|
|
58
|
+
return { status: "consumed", descriptor: stored.descriptor as T };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function discardDeadTabRecovery(name: string): void {
|
|
62
|
+
descriptors.delete(name);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Whether an unconsumed descriptor remains live at the supplied policy clock. */
|
|
66
|
+
export function isDeadTabRecoveryLive(name: string, now: number): boolean {
|
|
67
|
+
const stored = descriptors.get(name);
|
|
68
|
+
return stored !== undefined && stored.expiresAt > now;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function __setDeadTabRecoveryDepsForTest(overrides: Partial<DeadTabRecoveryDeps>): void {
|
|
72
|
+
deps = { ...deps, ...overrides };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function __resetDeadTabRecoveryForTest(): void {
|
|
76
|
+
descriptors.clear();
|
|
77
|
+
deps = { now: () => Date.now(), onPeek: () => {} };
|
|
78
|
+
}
|