@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
|
@@ -9,6 +9,8 @@ const packageName = "@gajae-code/coding-agent";
|
|
|
9
9
|
const aiPackageDir = path.resolve(packageDir, "../ai");
|
|
10
10
|
const bridgeClientPackageDir = path.resolve(packageDir, "../bridge-client");
|
|
11
11
|
const tuiPackageDir = path.resolve(packageDir, "../tui");
|
|
12
|
+
const nativesPackageDir = path.resolve(packageDir, "../natives");
|
|
13
|
+
const linuxX64PackageDir = path.resolve(packageDir, "../natives-linux-x64");
|
|
12
14
|
const manifestsDir = path.join(packageDir, "test/manifests");
|
|
13
15
|
const baselinePath = path.join(manifestsDir, "sdk-public-surface-v1.json");
|
|
14
16
|
const generatedPath = path.join(manifestsDir, "sdk-public-surface.generated.json");
|
|
@@ -30,18 +32,35 @@ function assertExport(module: Record<string, unknown>, name: string, subpath: st
|
|
|
30
32
|
async function runSmoke(): Promise<Surface> {
|
|
31
33
|
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "gjc-sdk-package-smoke-"));
|
|
32
34
|
try {
|
|
35
|
+
const stagedLinuxX64Dir = path.join(tempDir, "natives-linux-x64");
|
|
36
|
+
await fs.cp(linuxX64PackageDir, stagedLinuxX64Dir, { recursive: true });
|
|
37
|
+
const stagedNativeDir = path.join(stagedLinuxX64Dir, "native");
|
|
38
|
+
await fs.mkdir(stagedNativeDir, { recursive: true });
|
|
39
|
+
for (const entry of await fs.readdir(path.join(nativesPackageDir, "native"))) {
|
|
40
|
+
if (entry.startsWith("pi_natives.linux-x64") && entry.endsWith(".node")) {
|
|
41
|
+
await fs.copyFile(path.join(nativesPackageDir, "native", entry), path.join(stagedNativeDir, entry));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
33
44
|
const aiTarball = run(["bun", "pm", "pack", "--destination", tempDir, "--quiet"], aiPackageDir);
|
|
34
45
|
const bridgeClientTarball = run(
|
|
35
46
|
["bun", "pm", "pack", "--destination", tempDir, "--quiet"],
|
|
36
47
|
bridgeClientPackageDir,
|
|
37
48
|
);
|
|
38
49
|
const tuiTarball = run(["bun", "pm", "pack", "--destination", tempDir, "--quiet"], tuiPackageDir);
|
|
50
|
+
const nativesTarball = run(["bun", "pm", "pack", "--destination", tempDir, "--quiet"], nativesPackageDir);
|
|
51
|
+
const linuxX64Tarball = run(["bun", "pm", "pack", "--destination", tempDir, "--quiet"], stagedLinuxX64Dir);
|
|
39
52
|
const codingAgentTarball = run(["bun", "pm", "pack", "--destination", tempDir, "--quiet"], packageDir);
|
|
40
53
|
const aiTarballPath = path.isAbsolute(aiTarball) ? aiTarball : path.join(aiPackageDir, aiTarball);
|
|
41
54
|
const bridgeClientTarballPath = path.isAbsolute(bridgeClientTarball)
|
|
42
55
|
? bridgeClientTarball
|
|
43
56
|
: path.join(bridgeClientPackageDir, bridgeClientTarball);
|
|
44
57
|
const tuiTarballPath = path.isAbsolute(tuiTarball) ? tuiTarball : path.join(tuiPackageDir, tuiTarball);
|
|
58
|
+
const nativesTarballPath = path.isAbsolute(nativesTarball)
|
|
59
|
+
? nativesTarball
|
|
60
|
+
: path.join(nativesPackageDir, nativesTarball);
|
|
61
|
+
const linuxX64TarballPath = path.isAbsolute(linuxX64Tarball)
|
|
62
|
+
? linuxX64Tarball
|
|
63
|
+
: path.join(stagedLinuxX64Dir, linuxX64Tarball);
|
|
45
64
|
const codingAgentTarballPath = path.isAbsolute(codingAgentTarball)
|
|
46
65
|
? codingAgentTarball
|
|
47
66
|
: path.join(packageDir, codingAgentTarball);
|
|
@@ -56,11 +75,15 @@ async function runSmoke(): Promise<Surface> {
|
|
|
56
75
|
"@gajae-code/bridge-client": `file:${bridgeClientTarballPath}`,
|
|
57
76
|
[packageName]: `file:${codingAgentTarballPath}`,
|
|
58
77
|
"@gajae-code/tui": `file:${tuiTarballPath}`,
|
|
78
|
+
"@gajae-code/natives": `file:${nativesTarballPath}`,
|
|
79
|
+
"@gajae-code/natives-linux-x64": `file:${linuxX64TarballPath}`,
|
|
59
80
|
},
|
|
60
81
|
overrides: {
|
|
61
82
|
"@gajae-code/ai": `file:${aiTarballPath}`,
|
|
62
83
|
"@gajae-code/bridge-client": `file:${bridgeClientTarballPath}`,
|
|
63
84
|
"@gajae-code/tui": `file:${tuiTarballPath}`,
|
|
85
|
+
"@gajae-code/natives": `file:${nativesTarballPath}`,
|
|
86
|
+
"@gajae-code/natives-linux-x64": `file:${linuxX64TarballPath}`,
|
|
64
87
|
},
|
|
65
88
|
},
|
|
66
89
|
null,
|
|
@@ -70,10 +93,20 @@ async function runSmoke(): Promise<Surface> {
|
|
|
70
93
|
// Install the matching packed workspace artifacts so the smoke test exercises the
|
|
71
94
|
// release dependency boundary without falling back to an older registry package.
|
|
72
95
|
run(["bun", "install", "--ignore-scripts"], tempDir);
|
|
96
|
+
const installedPackage = JSON.parse(
|
|
97
|
+
await fs.readFile(path.join(tempDir, "node_modules", packageName, "package.json"), "utf8"),
|
|
98
|
+
) as { exports?: Record<string, unknown> };
|
|
99
|
+
if (installedPackage.exports?.["./session/internal/*"] !== null) {
|
|
100
|
+
throw new Error("packed package must explicitly block ./session/internal/*");
|
|
101
|
+
}
|
|
73
102
|
const probePath = path.join(tempDir, "probe.ts");
|
|
74
103
|
await fs.writeFile(
|
|
75
104
|
probePath,
|
|
76
|
-
`import * as root from ${JSON.stringify(packageName)};\nimport * as sdk from ${JSON.stringify(`${packageName}/sdk`)};\nimport * as bus from ${JSON.stringify(`${packageName}/sdk/bus`)};\
|
|
105
|
+
`import * as fs from "node:fs/promises";\nimport * as path from "node:path";\nimport * as root from ${JSON.stringify(packageName)};\nimport * as sdk from ${JSON.stringify(`${packageName}/sdk`)};\nimport * as bus from ${JSON.stringify(`${packageName}/sdk/bus`)};\nconst required = [[root, "createAgentSession", "root"], [root, "SESSION_DIRECTORY_API_VERSION", "root"], [root, "resolveManagedSessionScope", "root"], [root, "listManagedSessionCandidates", "root"], [sdk, "createAgentSession", "sdk"], [bus, "createNotificationsExtension", "sdk/bus"], [sdk, "SdkClient", "sdk"], [sdk, "SESSION_DIRECTORY_API_VERSION", "sdk"], [sdk, "resolveManagedSessionScope", "sdk"], [sdk, "listManagedSessionCandidates", "sdk"]] as const;\nfor (const [module, name, subpath] of required) if (!(name in module)) throw new Error(subpath + " missing " + name);\nconst sandbox = path.join(process.cwd(), "managed-listing-smoke");\nconst cwd = path.join(sandbox, "workspace", "a-b", "c");\nconst agentDir = path.join(sandbox, "agent");\nconst sessionsRoot = path.join(agentDir, "sessions");\nawait fs.mkdir(cwd, { recursive: true });\nconst resolved = await sdk.resolveManagedSessionScope({ cwd, agentDir, sessionsRoot });\nif (resolved.kind !== "resolved") throw new Error("packed resolver failed: " + resolved.message);\nawait fs.mkdir(resolved.scope.directoryPath, { recursive: true, mode: 0o700 });\nawait fs.chmod(sessionsRoot, 0o700);\nawait fs.chmod(resolved.scope.directoryPath, 0o700);\nawait fs.writeFile(path.join(resolved.scope.directoryPath, ".gjc-managed-session-scope.v2.json"), JSON.stringify({ schemaVersion: 1, layoutVersion: 2, identityVersion: 1, platform: process.platform === "win32" ? "win32" : "posix", canonicalPath: resolved.scope.canonicalCwd, identityDigest: resolved.scope.directoryName.slice(3) }) + "\\n", { mode: 0o600 });\nconst transcriptPath = path.join(resolved.scope.directoryPath, "packed-session.jsonl");\nawait fs.writeFile(transcriptPath, JSON.stringify({ type: "session", id: "packed-session", cwd }) + "\\n", { mode: 0o600 });\nconst snapshot = async () => Promise.all((await fs.readdir(sandbox, { recursive: true })).sort().map(async name => { const pathname = path.join(sandbox, name); const stat = await fs.lstat(pathname); return [name, stat.mode, stat.size, stat.mtimeMs, stat.isFile() ? await fs.readFile(pathname, "utf8") : null]; }));\nconst before = JSON.stringify(await snapshot());\nconst listing = await sdk.listManagedSessionCandidates({ scope: resolved.scope });\nif (listing.kind !== "complete" || listing.owned.length !== 1 || listing.owned[0]?.sessionId !== "packed-session") throw new Error("packed readonly listing failed: " + JSON.stringify(listing));\nconst after = JSON.stringify(await snapshot());\nif (after !== before) throw new Error("packed readonly listing mutated the filesystem");\nconst privateSubpath = ${JSON.stringify(`${packageName}/session/internal/managed-session-scope`)};\ntry { await import(privateSubpath); throw new Error("private managed-session scope subpath resolved"); } catch (error) {\n\tif (error instanceof Error && error.message === "private managed-session scope subpath resolved") throw error;\n\tconst message = String(error);\n\tconst exportsRejected = /Package subpath .* is not defined by "exports"/.test(message);\n\tconst bunRejected = message.startsWith("ResolveMessage: Cannot find module '" + privateSubpath + "' from '") && message.endsWith("/probe.ts'");\n\tif (!exportsRejected && !bunRejected) throw new Error("private managed-session scope failed for an unexpected reason: " + message);\n}\nprocess.stdout.write(JSON.stringify({ root: Object.keys(root).sort(), sdk: Object.keys(sdk).sort() }));\n`,
|
|
106
|
+
);
|
|
107
|
+
await fs.appendFile(
|
|
108
|
+
probePath,
|
|
109
|
+
`\nconst rootBefore = JSON.stringify(await snapshot());\nconst rootListing = await root.listManagedSessionCandidates({ scope: resolved.scope });\nif (rootListing.kind !== "complete" || rootListing.owned.length !== listing.owned.length || rootListing.owned[0]?.sessionId !== listing.owned[0]?.sessionId || rootListing.owned[0]?.path !== listing.owned[0]?.path) throw new Error("packed root readonly listing diverged from SDK listing");\nconst rootAfter = JSON.stringify(await snapshot());\nif (rootAfter !== rootBefore) throw new Error("packed root readonly listing mutated the filesystem");\nconst bridgeClient = await import("@gajae-code/bridge-client");\nif (sdk.SdkClient !== bridgeClient.SdkClient) throw new Error("SdkClient class identity differs between sdk and bridge-client");\n`,
|
|
77
110
|
);
|
|
78
111
|
const surface = JSON.parse(run(["bun", "run", probePath], tempDir)) as Surface;
|
|
79
112
|
assertExport(Object.fromEntries(surface.root.map(name => [name, true])), "createAgentSession", "root");
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
defaultClipboardPasteImageKeysForPlatform,
|
|
5
|
+
defaultMessageQueueKeysForPlatform,
|
|
6
|
+
KEYBINDINGS,
|
|
7
|
+
} from "../src/config/keybindings";
|
|
8
|
+
|
|
9
|
+
import { APP_ACTION_METADATA } from "../src/modes/action-registry";
|
|
10
|
+
|
|
11
|
+
const DOC_PATH = path.resolve(import.meta.dir, "../../../docs/keybindings.md");
|
|
12
|
+
const SECTION_START = "### Application context (`app.*`)";
|
|
13
|
+
const SECTION_END = "### Global engine context (`tui.global.*`)";
|
|
14
|
+
|
|
15
|
+
const DOCUMENTATION_PLATFORMS = ["darwin", "win32", "linux"] as const;
|
|
16
|
+
|
|
17
|
+
function defaultKeys(
|
|
18
|
+
value: (typeof KEYBINDINGS)[keyof typeof KEYBINDINGS],
|
|
19
|
+
bindingId: keyof typeof KEYBINDINGS,
|
|
20
|
+
): string {
|
|
21
|
+
const defaultsByPlatform = DOCUMENTATION_PLATFORMS.map(platform => {
|
|
22
|
+
switch (bindingId) {
|
|
23
|
+
case "app.message.queue":
|
|
24
|
+
return defaultMessageQueueKeysForPlatform(platform);
|
|
25
|
+
case "app.clipboard.pasteImage":
|
|
26
|
+
return defaultClipboardPasteImageKeysForPlatform(platform);
|
|
27
|
+
default: {
|
|
28
|
+
const keys = value.defaultKeys;
|
|
29
|
+
return (Array.isArray(keys) ? keys : [keys]).join(", ") || "_(none)_";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const groups = new Map<string, string[]>();
|
|
34
|
+
for (const [index, keys] of defaultsByPlatform.entries()) {
|
|
35
|
+
const platform = DOCUMENTATION_PLATFORMS[index]!;
|
|
36
|
+
groups.set(keys, [...(groups.get(keys) ?? []), platform]);
|
|
37
|
+
}
|
|
38
|
+
return groups.size === 1
|
|
39
|
+
? defaultsByPlatform[0]!
|
|
40
|
+
: [...groups].map(([keys, platforms]) => `${keys} (${platforms.join("/")})`).join(" / ");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Canonical application-action table shared by docs and drift tests. */
|
|
44
|
+
export function generateHotkeysDocsTable(): string {
|
|
45
|
+
return [
|
|
46
|
+
"| Action ID | Default | Domains |",
|
|
47
|
+
"| --- | --- | --- |",
|
|
48
|
+
...APP_ACTION_METADATA.map(action => {
|
|
49
|
+
const binding = KEYBINDINGS[action.bindingId ?? action.id];
|
|
50
|
+
return `| \`${action.id}\` | ${defaultKeys(binding, action.bindingId ?? action.id)} | ${action.domains.join(", ")} |`;
|
|
51
|
+
}),
|
|
52
|
+
].join("\n");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function generateKeybindingsDocument(source = readFileSync(DOC_PATH, "utf8")): string {
|
|
56
|
+
const start = source.indexOf(SECTION_START);
|
|
57
|
+
const end = source.indexOf(SECTION_END);
|
|
58
|
+
if (start < 0 || end < 0 || end <= start) throw new Error("Application keybinding section not found");
|
|
59
|
+
return `${source.slice(0, start)}${SECTION_START}\n\n${generateHotkeysDocsTable()}\n\n${source.slice(end)}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (import.meta.main) {
|
|
63
|
+
const expected = generateKeybindingsDocument();
|
|
64
|
+
if (process.argv.includes("--check")) {
|
|
65
|
+
if (readFileSync(DOC_PATH, "utf8") !== expected) {
|
|
66
|
+
console.error(
|
|
67
|
+
`${path.relative(process.cwd(), DOC_PATH)} is out of date; run bun scripts/generate-hotkeys-docs.ts`,
|
|
68
|
+
);
|
|
69
|
+
process.exitCode = 1;
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
writeFileSync(DOC_PATH, expected);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -32,6 +32,8 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
32
32
|
"slash_command:notify":
|
|
33
33
|
"interactive diagnostics command; session on/off delegate to the notifications extension, not an SDK ingress seam",
|
|
34
34
|
"slash_command:pet": "visual/local-only command, not a user-facing SDK control seam",
|
|
35
|
+
"slash_command:transcript": "visual/local-only transcript viewer, not a user-facing SDK control seam",
|
|
36
|
+
"slash_command:sessions": "visual/local-only sessions dashboard, not a user-facing SDK control seam",
|
|
35
37
|
"agent_session:constructor": "internal accessor/plumbing, not a user-facing control seam",
|
|
36
38
|
"agent_session:nextToolChoice": "internal accessor/plumbing, not a user-facing control seam",
|
|
37
39
|
"agent_session:setForcedToolChoice": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -50,6 +52,9 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
50
52
|
"agent_session:estimateMidRunContextTokensForTests": "test-only estimator seam, not a user-facing SDK control seam",
|
|
51
53
|
"agent_session:activeMidRunBarrierCountForTests": "read-only test seam, not a user-facing SDK control seam",
|
|
52
54
|
"agent_session:activeMidRunMaintenanceCountForTests": "read-only test seam, not a user-facing SDK control seam",
|
|
55
|
+
"agent_session:getPendingNextTurnMessagesForTests": "read-only test seam, not a user-facing SDK control seam",
|
|
56
|
+
"agent_session:setCancelAndSubmitAbortOutcomeProviderForTests":
|
|
57
|
+
"test-only cancellation seam, not a user-facing SDK control seam",
|
|
53
58
|
"agent_session:getAgentId": "internal accessor/plumbing, not a user-facing control seam",
|
|
54
59
|
"agent_session:emitNotice": "internal accessor/plumbing, not a user-facing control seam",
|
|
55
60
|
"agent_session:subscribe": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -57,6 +62,8 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
57
62
|
"agent_session:closeWriterStrict": "internal ACP lifecycle teardown plumbing, not a user-facing control seam",
|
|
58
63
|
"agent_session:disposeChildSubprocesses": "internal accessor/plumbing, not a user-facing control seam",
|
|
59
64
|
"agent_session:waitForIdle": "internal accessor/plumbing, not a user-facing control seam",
|
|
65
|
+
"agent_session:awaitPendingContextTransformations":
|
|
66
|
+
"internal context-transformation lifecycle barrier, not a user-facing SDK control seam",
|
|
60
67
|
"agent_session:drainAsyncJobDeliveriesForAcp": "internal accessor/plumbing, not a user-facing control seam",
|
|
61
68
|
"agent_session:getAsyncDeliveryStateForAcp":
|
|
62
69
|
"internal ACP lifecycle quiescence plumbing, not a user-facing control seam",
|
|
@@ -66,10 +73,7 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
66
73
|
"agent_session:hasForegroundBashBackgroundRequestHandler":
|
|
67
74
|
"internal accessor/plumbing, not a user-facing control seam",
|
|
68
75
|
"agent_session:requestForegroundBashBackground": "internal accessor/plumbing, not a user-facing control seam",
|
|
69
|
-
"agent_session:isMCPDiscoveryEnabled": "internal accessor/plumbing, not a user-facing control seam",
|
|
70
|
-
"agent_session:getDiscoverableMCPSearchIndex": "internal accessor/plumbing, not a user-facing control seam",
|
|
71
76
|
"agent_session:getSelectedMCPToolNames": "internal accessor/plumbing, not a user-facing control seam",
|
|
72
|
-
"agent_session:activateDiscoveredMCPTools": "internal accessor/plumbing, not a user-facing control seam",
|
|
73
77
|
"agent_session:isToolDiscoveryEnabled": "internal accessor/plumbing, not a user-facing control seam",
|
|
74
78
|
"agent_session:getDiscoverableToolSearchIndex": "internal accessor/plumbing, not a user-facing control seam",
|
|
75
79
|
"agent_session:getSelectedDiscoveredToolNames": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -85,6 +89,7 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
85
89
|
"agent_session:setPlanModeState": "internal accessor/plumbing, not a user-facing control seam",
|
|
86
90
|
"agent_session:getGoalModeState": "internal accessor/plumbing, not a user-facing control seam",
|
|
87
91
|
"agent_session:setGoalModeState": "internal accessor/plumbing, not a user-facing control seam",
|
|
92
|
+
"agent_session:setSdkPlanModeHandler": "internal host lifecycle plumbing for mode.plan.set",
|
|
88
93
|
"agent_session:getWorkflowGateEmitter": "internal accessor/plumbing, not a user-facing control seam",
|
|
89
94
|
"agent_session:getAskAnswerSource": "internal accessor/plumbing, not a user-facing control seam",
|
|
90
95
|
"agent_session:setWorkflowGateEmitter": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -105,6 +110,7 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
105
110
|
"agent_session:purgeQueuedCustomMessages": "internal accessor/plumbing, not a user-facing control seam",
|
|
106
111
|
"agent_session:clearQueue": "internal accessor/plumbing, not a user-facing control seam",
|
|
107
112
|
"agent_session:popLastQueuedMessage": "internal accessor/plumbing, not a user-facing control seam",
|
|
113
|
+
"agent_session:cancelAndSubmit": "interactive queue transaction plumbing, not an independent SDK control seam",
|
|
108
114
|
"agent_session:applyCompactionPostAppendForTests": "internal accessor/plumbing, not a user-facing control seam",
|
|
109
115
|
"agent_session:continuePersistedHistory": "internal startup lifecycle plumbing, not a user-facing control seam",
|
|
110
116
|
"agent_session:setActiveModelProfile": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -126,6 +132,7 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
126
132
|
"agent_session:fetchUsageReportsForControl":
|
|
127
133
|
"internal Telegram control wrapper over the reviewed usage.get seam, not an independent public SDK operation",
|
|
128
134
|
"agent_session:cycleRoleModels": "internal accessor/plumbing, not a user-facing control seam",
|
|
135
|
+
"agent_session:getRoleModelCycleCandidateCount": "internal role-model display accessor, not a user-facing SDK seam",
|
|
129
136
|
"agent_session:isFastModeEnabled": "internal accessor/plumbing, not a user-facing control seam",
|
|
130
137
|
"agent_session:isFastForProvider": "internal accessor/plumbing, not a user-facing control seam",
|
|
131
138
|
"agent_session:isFastForSubagentProvider": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -221,7 +228,6 @@ const SEAM_TO_SDK: Readonly<Record<string, string>> = {
|
|
|
221
228
|
"agent_session:setTodoPhases": "todo.replace",
|
|
222
229
|
"agent_session:getQueuedMessageEntries": "queue.messages.list",
|
|
223
230
|
"agent_session:getAllToolNames": "tools.list",
|
|
224
|
-
"agent_session:getDiscoverableMCPTools": "tools.list",
|
|
225
231
|
"agent_session:getDiscoverableTools": "tools.list",
|
|
226
232
|
"agent_session:sendUserMessage": "turn.steer",
|
|
227
233
|
"agent_session:reload": "runtime.reload",
|
|
@@ -270,17 +276,30 @@ export interface SourceSeam {
|
|
|
270
276
|
sourceFile: string;
|
|
271
277
|
sourceKind: SourceKind;
|
|
272
278
|
}
|
|
273
|
-
interface
|
|
279
|
+
interface IncludedInventoryRecord {
|
|
274
280
|
sourceId: string;
|
|
275
281
|
sourceFile: string;
|
|
276
282
|
sourceKind: SourceKind;
|
|
277
|
-
decision: "include"
|
|
278
|
-
|
|
279
|
-
sdkId?: string;
|
|
283
|
+
decision: "include";
|
|
284
|
+
sdkId: string;
|
|
280
285
|
adapterMappings: Operation["adapterDispositions"];
|
|
281
286
|
testIds: string[];
|
|
282
287
|
}
|
|
283
288
|
|
|
289
|
+
interface ExcludedInventoryRecord {
|
|
290
|
+
sourceId: string;
|
|
291
|
+
sourceFile: string;
|
|
292
|
+
sourceKind: SourceKind;
|
|
293
|
+
decision: "exclude";
|
|
294
|
+
rationale: string;
|
|
295
|
+
exclusionMetadata: {
|
|
296
|
+
adapterMappings: "not_applicable";
|
|
297
|
+
testIds: "not_applicable";
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
type InventoryRecord = IncludedInventoryRecord | ExcludedInventoryRecord;
|
|
302
|
+
|
|
284
303
|
function repoPath(file: string): string {
|
|
285
304
|
return path.relative(repoRoot, file).split(path.sep).join("/");
|
|
286
305
|
}
|
|
@@ -291,7 +310,10 @@ function collectCaseSeams(source: string, prefix: string): string[] {
|
|
|
291
310
|
}
|
|
292
311
|
|
|
293
312
|
export function scanSlashCommands(sourceText: string): string[] {
|
|
294
|
-
const
|
|
313
|
+
const anchor = "const BUILTIN_SLASH_COMMAND_REGISTRY";
|
|
314
|
+
const anchorIndex = sourceText.indexOf(anchor);
|
|
315
|
+
if (anchorIndex === -1) throw new Error(`SDK operation inventory scanner: required anchor ${anchor} was not found.`);
|
|
316
|
+
const builtinRegistry = sourceText.slice(anchorIndex);
|
|
295
317
|
return [...builtinRegistry.matchAll(/^\t\tname:\s*["']([^"']+)["']/gm)].map(match => `slash_command:${match[1]}`);
|
|
296
318
|
}
|
|
297
319
|
|
|
@@ -664,14 +686,17 @@ export function scanAgentSessionMethods(sourceText: string): string[] {
|
|
|
664
686
|
for (let bodyIndex = index + 2; bodyIndex < tokens.length; bodyIndex++) {
|
|
665
687
|
if (tokens[bodyIndex]!.text === "<") angleDepth++;
|
|
666
688
|
else if (tokens[bodyIndex]!.text === ">" && angleDepth > 0) angleDepth--;
|
|
689
|
+
else if (tokens[bodyIndex]!.text === ";" && angleDepth === 0) break;
|
|
667
690
|
else if (tokens[bodyIndex]!.text === "{" && angleDepth === 0) {
|
|
668
691
|
bodyStart = bodyIndex;
|
|
669
692
|
break;
|
|
670
693
|
}
|
|
671
694
|
}
|
|
672
|
-
if (bodyStart === undefined)
|
|
695
|
+
if (bodyStart === undefined)
|
|
696
|
+
throw new Error("SDK operation inventory scanner: AgentSession class is missing its opening body delimiter.");
|
|
673
697
|
const bodyEnd = matchingToken(tokens, bodyStart, "{", "}");
|
|
674
|
-
if (bodyEnd === undefined)
|
|
698
|
+
if (bodyEnd === undefined)
|
|
699
|
+
throw new Error("SDK operation inventory scanner: AgentSession class body is unbalanced.");
|
|
675
700
|
|
|
676
701
|
const methods: string[] = [];
|
|
677
702
|
for (let memberStart = bodyStart + 1; memberStart < bodyEnd; ) {
|
|
@@ -685,7 +710,7 @@ export function scanAgentSessionMethods(sourceText: string): string[] {
|
|
|
685
710
|
}
|
|
686
711
|
return methods;
|
|
687
712
|
}
|
|
688
|
-
|
|
713
|
+
throw new Error("SDK operation inventory scanner: required AgentSession class declaration was not found.");
|
|
689
714
|
}
|
|
690
715
|
|
|
691
716
|
export function scanAcpMethods(sourceText: string): string[] {
|
|
@@ -776,14 +801,24 @@ function generatedRecords(seams: Awaited<ReturnType<typeof scanSeams>>): Invento
|
|
|
776
801
|
const sdkId = SEAM_TO_SDK[seam.sourceId];
|
|
777
802
|
const rationale = lockedExclusion(seam.sourceId);
|
|
778
803
|
if (!sdkId && !rationale) continue;
|
|
779
|
-
|
|
780
|
-
|
|
804
|
+
if (!sdkId) {
|
|
805
|
+
if (!rationale) continue;
|
|
806
|
+
records.push({
|
|
807
|
+
...seam,
|
|
808
|
+
decision: "exclude",
|
|
809
|
+
rationale,
|
|
810
|
+
exclusionMetadata: { adapterMappings: "not_applicable", testIds: "not_applicable" },
|
|
811
|
+
});
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
814
|
+
const operation = OPERATIONS.find(candidate => candidate.sdkId === sdkId);
|
|
815
|
+
if (!operation) throw new Error(`SEAM_TO_SDK maps ${seam.sourceId} to unknown SDK ID: ${sdkId}`);
|
|
781
816
|
records.push({
|
|
782
817
|
...seam,
|
|
783
|
-
decision:
|
|
784
|
-
|
|
785
|
-
adapterMappings: operation
|
|
786
|
-
testIds: operation
|
|
818
|
+
decision: "include",
|
|
819
|
+
sdkId,
|
|
820
|
+
adapterMappings: operation.adapterDispositions,
|
|
821
|
+
testIds: operation.testIds,
|
|
787
822
|
});
|
|
788
823
|
}
|
|
789
824
|
return records;
|
|
@@ -804,8 +839,17 @@ function validateRegistry(records: InventoryRecord[]): string[] {
|
|
|
804
839
|
if (operation.testIds.length === 0) errors.push(`${operation.id} is missing test IDs.`);
|
|
805
840
|
}
|
|
806
841
|
for (const record of records) {
|
|
807
|
-
if (record.decision === "exclude"
|
|
808
|
-
errors.push(`${record.sourceId} exclusion lacks a locked rationale.`);
|
|
842
|
+
if (record.decision === "exclude") {
|
|
843
|
+
if (!record.rationale) errors.push(`${record.sourceId} exclusion lacks a locked rationale.`);
|
|
844
|
+
if (
|
|
845
|
+
record.exclusionMetadata.adapterMappings !== "not_applicable" ||
|
|
846
|
+
record.exclusionMetadata.testIds !== "not_applicable"
|
|
847
|
+
)
|
|
848
|
+
errors.push(
|
|
849
|
+
`${record.sourceId} exclusion metadata must mark adapter mappings and test IDs as not applicable.`,
|
|
850
|
+
);
|
|
851
|
+
continue;
|
|
852
|
+
}
|
|
809
853
|
if (ADAPTERS.some(adapter => !record.adapterMappings[adapter]))
|
|
810
854
|
errors.push(`${record.sourceId} is missing adapter mappings.`);
|
|
811
855
|
if (record.testIds.length === 0) errors.push(`${record.sourceId} is missing test IDs.`);
|
|
@@ -981,6 +981,7 @@ function isSource(file: string): boolean {
|
|
|
981
981
|
}
|
|
982
982
|
|
|
983
983
|
const teamRuntimeTmuxPath = "packages/coding-agent/src/gjc-runtime/team-runtime.ts";
|
|
984
|
+
const teamWorkersTmuxPath = "packages/coding-agent/src/gjc-runtime/team-workers.ts";
|
|
984
985
|
|
|
985
986
|
const coordinatorMcpRoot = "packages/coding-agent/src/coordinator-mcp/server.ts";
|
|
986
987
|
function isPublishedGjcSessionShellHelper(file: string): boolean {
|
|
@@ -1427,6 +1428,16 @@ function exactTeamRuntimeSendKeysRanges(contents: string): ShellRange[] {
|
|
|
1427
1428
|
/Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*paneId\s*,\s*workerCommand\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
|
|
1428
1429
|
),
|
|
1429
1430
|
];
|
|
1431
|
+
const continuationPromptMatches = [
|
|
1432
|
+
...contents.matchAll(
|
|
1433
|
+
/(?:const\s+GJC_TEAM_CONTINUATION_PROMPT\s*=\s*["']Continue only your current claimed GJC team task\. Re-read current GJC team state; do not replay prior output; report status\.["']\s*;|import\s*\{[\s\S]{0,1000}?\bGJC_TEAM_CONTINUATION_PROMPT\b[\s\S]{0,1000}?\}\s*from\s*["']\.\/team-workers["']\s*;)/g,
|
|
1434
|
+
),
|
|
1435
|
+
];
|
|
1436
|
+
const continuationMatches = [
|
|
1437
|
+
...contents.matchAll(
|
|
1438
|
+
/const\s+args\s*=\s*Object\.freeze\(\s*\[\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*GJC_TEAM_CONTINUATION_PROMPT\s*,\s*["'];["']\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*["']Enter["']\s*,?\s*\]\s*\)\s*;\s*const\s+dispatch\s*=\s*gjcTeamRuntimeTestSeams\?\.continuationTmuxDispatch\s*\?\s*gjcTeamRuntimeTestSeams\.continuationTmuxDispatch\(config\.tmux_command\s*,\s*args\)\s*:\s*Bun\.spawnSync\(\[config\.tmux_command\s*,\s*\.\.\.args\]\s*,\s*\{\s*stdout\s*:\s*["']ignore["']\s*,\s*stderr\s*:\s*["']ignore["']\s*,\s*timeout\s*:\s*GJC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS\s*,?\s*\}\s*\)\s*;/g,
|
|
1439
|
+
),
|
|
1440
|
+
];
|
|
1430
1441
|
const enterMatches = [
|
|
1431
1442
|
...contents.matchAll(
|
|
1432
1443
|
/const\s+sendKeys\s*=\s*Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*paneId\s*,\s*["']Enter["']\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
|
|
@@ -1449,6 +1460,8 @@ function exactTeamRuntimeSendKeysRanges(contents: string): ShellRange[] {
|
|
|
1449
1460
|
guardMatches.length !== 1 ||
|
|
1450
1461
|
payloadMatches.length !== 1 ||
|
|
1451
1462
|
enterMatches.length !== 1 ||
|
|
1463
|
+
continuationPromptMatches.length !== 1 ||
|
|
1464
|
+
continuationMatches.length !== 1 ||
|
|
1452
1465
|
fallbackPredicateMatches.length !== 1 ||
|
|
1453
1466
|
useFallbackMatches.length !== 1 ||
|
|
1454
1467
|
splitWorkerCommandMatches.length !== 1
|
|
@@ -1468,18 +1481,43 @@ function exactTeamRuntimeSendKeysRanges(contents: string): ShellRange[] {
|
|
|
1468
1481
|
const guard = guardMatches[0];
|
|
1469
1482
|
const openingBrace = (guard.index ?? 0) + guard[0].lastIndexOf("{");
|
|
1470
1483
|
const range = braceBlockRange(contents, openingBrace);
|
|
1471
|
-
|
|
1484
|
+
const continuationFunction =
|
|
1485
|
+
/async\s+function\s+continueStalledGjcTeamWorkers\s*\([^)]*\)\s*:\s*Promise<void>\s*\{/.exec(contents);
|
|
1486
|
+
const monitorFence = /await\s+withGjcTeamTaskMutation\([\s\S]{0,500}?async\s+capability\s*=>\s*\{/.exec(contents);
|
|
1487
|
+
if (!range || !continuationFunction || !monitorFence) return [];
|
|
1488
|
+
const continuationOpeningBrace = (continuationFunction.index ?? 0) + continuationFunction[0].lastIndexOf("{");
|
|
1489
|
+
const continuationRange = braceBlockRange(contents, continuationOpeningBrace);
|
|
1490
|
+
const monitorOpeningBrace = (monitorFence.index ?? 0) + monitorFence[0].lastIndexOf("{");
|
|
1491
|
+
const monitorRange = braceBlockRange(contents, monitorOpeningBrace);
|
|
1492
|
+
if (!continuationRange || !monitorRange) return [];
|
|
1493
|
+
const monitorBody = contents.slice(monitorRange.start, monitorRange.end);
|
|
1494
|
+
const continuationCall = /await\s+continueStalledGjcTeamWorkers\s*\(/.exec(monitorBody);
|
|
1495
|
+
const reconciliationCall = /await\s+reconcileGjcTeamStaleClaimsUnlocked\s*\(/.exec(monitorBody);
|
|
1496
|
+
const continuationStart = continuationMatches[0].index ?? 0;
|
|
1497
|
+
const finalValidationStart = contents.lastIndexOf("const revalidationReason =", continuationStart);
|
|
1498
|
+
const skippedBranch = finalValidationStart === -1 ? "" : contents.slice(finalValidationStart, continuationStart);
|
|
1472
1499
|
if (
|
|
1473
1500
|
payloadStart < range.start ||
|
|
1474
1501
|
payloadStart >= range.end ||
|
|
1475
1502
|
enterStart < range.start ||
|
|
1476
1503
|
enterStart >= range.end ||
|
|
1477
|
-
contents.indexOf("void sendKeys.exitCode;", enterStart) >= range.end
|
|
1504
|
+
contents.indexOf("void sendKeys.exitCode;", enterStart) >= range.end ||
|
|
1505
|
+
continuationStart < continuationRange.start ||
|
|
1506
|
+
continuationStart >= continuationRange.end ||
|
|
1507
|
+
finalValidationStart < continuationRange.start ||
|
|
1508
|
+
!continuationCall ||
|
|
1509
|
+
!reconciliationCall ||
|
|
1510
|
+
(continuationCall.index ?? 0) >= (reconciliationCall.index ?? 0) ||
|
|
1511
|
+
!/if\s*\(\s*revalidationReason\s*\)[\s\S]*?return\s*;/.test(skippedBranch)
|
|
1478
1512
|
)
|
|
1479
1513
|
return [];
|
|
1480
1514
|
return [
|
|
1481
1515
|
{ start: payloadStart, end: payloadStart + payloadMatches[0][0].length },
|
|
1482
1516
|
{ start: enterStart, end: enterStart + enterMatches[0][0].length },
|
|
1517
|
+
{
|
|
1518
|
+
start: continuationMatches[0].index ?? 0,
|
|
1519
|
+
end: (continuationMatches[0].index ?? 0) + continuationMatches[0][0].length,
|
|
1520
|
+
},
|
|
1483
1521
|
];
|
|
1484
1522
|
}
|
|
1485
1523
|
|
|
@@ -1504,6 +1542,7 @@ function isTypeOnlyTmuxPrimitiveOccurrence(contents: string, occurrence: TmuxPri
|
|
|
1504
1542
|
}
|
|
1505
1543
|
|
|
1506
1544
|
function tmuxMachineBusViolations(file: string, contents: string): string[] {
|
|
1545
|
+
if (isGeneratedDocumentationIndex(file)) return [];
|
|
1507
1546
|
const allowedTeamFallbackRanges = file === teamRuntimeTmuxPath ? exactTeamRuntimeSendKeysRanges(contents) : [];
|
|
1508
1547
|
const violations: string[] = [];
|
|
1509
1548
|
for (const occurrence of tmuxPrimitiveOccurrences(contents)) {
|
|
@@ -1890,6 +1929,15 @@ async function scan(): Promise<string[]> {
|
|
|
1890
1929
|
} else {
|
|
1891
1930
|
violations.push(...tmuxMachineBusViolations(file, contents));
|
|
1892
1931
|
}
|
|
1932
|
+
if (
|
|
1933
|
+
file === teamWorkersTmuxPath &&
|
|
1934
|
+
!/^export const GJC_TEAM_CONTINUATION_PROMPT =\n\t"Continue only your current claimed GJC team task\. Re-read current GJC team state; do not replay prior output; report status\.";$/m.test(
|
|
1935
|
+
contents,
|
|
1936
|
+
)
|
|
1937
|
+
)
|
|
1938
|
+
violations.push(
|
|
1939
|
+
`${file}: stalled-worker continuation prompt must remain the exact source-controlled literal`,
|
|
1940
|
+
);
|
|
1893
1941
|
}
|
|
1894
1942
|
if (file === coordinatorMcpRoot) {
|
|
1895
1943
|
for (const pattern of coordinatorDirectAuthorityPatterns) {
|
|
@@ -3067,6 +3115,9 @@ fi
|
|
|
3067
3115
|
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3068
3116
|
);
|
|
3069
3117
|
const canonicalTeamRuntimeSendKeysFixture = `
|
|
3118
|
+
async function continueStalledGjcTeamWorkers(): Promise<void> {
|
|
3119
|
+
const revalidationReason = null;
|
|
3120
|
+
if (revalidationReason) return;
|
|
3070
3121
|
function shouldDispatchWorkerWithSendKeys(tmuxCommand: string, platform: NodeJS.Platform = process.platform): boolean {
|
|
3071
3122
|
return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux";
|
|
3072
3123
|
}
|
|
@@ -3083,11 +3134,100 @@ if (useSendKeysFallback) {
|
|
|
3083
3134
|
});
|
|
3084
3135
|
void sendKeys.exitCode;
|
|
3085
3136
|
}
|
|
3137
|
+
const GJC_TEAM_CONTINUATION_PROMPT = "Continue only your current claimed GJC team task. Re-read current GJC team state; do not replay prior output; report status.";
|
|
3138
|
+
const GJC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS = 5_000;
|
|
3139
|
+
const args = Object.freeze([
|
|
3140
|
+
"send-keys",
|
|
3141
|
+
"-l",
|
|
3142
|
+
"-t",
|
|
3143
|
+
worker.pane_id,
|
|
3144
|
+
GJC_TEAM_CONTINUATION_PROMPT,
|
|
3145
|
+
";",
|
|
3146
|
+
"send-keys",
|
|
3147
|
+
"-t",
|
|
3148
|
+
worker.pane_id,
|
|
3149
|
+
"Enter",
|
|
3150
|
+
]);
|
|
3151
|
+
|
|
3152
|
+
const dispatch = gjcTeamRuntimeTestSeams?.continuationTmuxDispatch
|
|
3153
|
+
? gjcTeamRuntimeTestSeams.continuationTmuxDispatch(config.tmux_command, args)
|
|
3154
|
+
: Bun.spawnSync([config.tmux_command, ...args], {
|
|
3155
|
+
stdout: "ignore",
|
|
3156
|
+
stderr: "ignore",
|
|
3157
|
+
timeout: GJC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS,
|
|
3158
|
+
});
|
|
3159
|
+
}
|
|
3160
|
+
async function monitorGjcTeam(): Promise<void> {
|
|
3161
|
+
await withGjcTeamTaskMutation(taskStore(dir), async capability => {
|
|
3162
|
+
await continueStalledGjcTeamWorkers();
|
|
3163
|
+
await reconcileGjcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);
|
|
3164
|
+
});
|
|
3165
|
+
}
|
|
3086
3166
|
`;
|
|
3087
3167
|
await runSelfTestFixture(
|
|
3088
3168
|
{ "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture },
|
|
3089
3169
|
0,
|
|
3090
3170
|
);
|
|
3171
|
+
await runSelfTestFixture(
|
|
3172
|
+
{
|
|
3173
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3174
|
+
"async function continueStalledGjcTeamWorkers(): Promise<void>",
|
|
3175
|
+
"async function relocatedContinuation(): Promise<void>",
|
|
3176
|
+
),
|
|
3177
|
+
},
|
|
3178
|
+
1,
|
|
3179
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3180
|
+
);
|
|
3181
|
+
await runSelfTestFixture(
|
|
3182
|
+
{
|
|
3183
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3184
|
+
"if (revalidationReason) return;",
|
|
3185
|
+
"if (revalidationReason) {}",
|
|
3186
|
+
),
|
|
3187
|
+
},
|
|
3188
|
+
1,
|
|
3189
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3190
|
+
);
|
|
3191
|
+
await runSelfTestFixture(
|
|
3192
|
+
{
|
|
3193
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3194
|
+
"await continueStalledGjcTeamWorkers();",
|
|
3195
|
+
"",
|
|
3196
|
+
),
|
|
3197
|
+
},
|
|
3198
|
+
1,
|
|
3199
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3200
|
+
);
|
|
3201
|
+
await runSelfTestFixture(
|
|
3202
|
+
{
|
|
3203
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3204
|
+
"await continueStalledGjcTeamWorkers();\n\t\tawait reconcileGjcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);",
|
|
3205
|
+
"await reconcileGjcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);\n\t\tawait continueStalledGjcTeamWorkers();",
|
|
3206
|
+
),
|
|
3207
|
+
},
|
|
3208
|
+
1,
|
|
3209
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3210
|
+
);
|
|
3211
|
+
await runSelfTestFixture(
|
|
3212
|
+
{
|
|
3213
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3214
|
+
"const dispatch =",
|
|
3215
|
+
'args.push("forged");\nconst dispatch =',
|
|
3216
|
+
),
|
|
3217
|
+
},
|
|
3218
|
+
1,
|
|
3219
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3220
|
+
);
|
|
3221
|
+
await runSelfTestFixture(
|
|
3222
|
+
{
|
|
3223
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3224
|
+
"report status.",
|
|
3225
|
+
"report injected status.",
|
|
3226
|
+
),
|
|
3227
|
+
},
|
|
3228
|
+
1,
|
|
3229
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3230
|
+
);
|
|
3091
3231
|
await runSelfTestFixture(
|
|
3092
3232
|
{
|
|
3093
3233
|
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
@@ -3115,6 +3255,46 @@ if (useSendKeysFallback) {
|
|
|
3115
3255
|
1,
|
|
3116
3256
|
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3117
3257
|
);
|
|
3258
|
+
await runSelfTestFixture(
|
|
3259
|
+
{
|
|
3260
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replaceAll(
|
|
3261
|
+
"worker.pane_id",
|
|
3262
|
+
'"%99"',
|
|
3263
|
+
),
|
|
3264
|
+
},
|
|
3265
|
+
1,
|
|
3266
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3267
|
+
);
|
|
3268
|
+
await runSelfTestFixture(
|
|
3269
|
+
{
|
|
3270
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3271
|
+
'GJC_TEAM_CONTINUATION_PROMPT,\n\t";",',
|
|
3272
|
+
"`$" + "{GJC_TEAM_CONTINUATION_PROMPT}" + '`,\n\t";",',
|
|
3273
|
+
),
|
|
3274
|
+
},
|
|
3275
|
+
1,
|
|
3276
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3277
|
+
);
|
|
3278
|
+
await runSelfTestFixture(
|
|
3279
|
+
{
|
|
3280
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3281
|
+
'"send-keys",\n\t"-l",\n\t"-t",\n\tworker.pane_id,\n\tGJC_TEAM_CONTINUATION_PROMPT,\n\t";",\n\t"send-keys",\n\t"-t",\n\tworker.pane_id,\n\t"Enter",',
|
|
3282
|
+
'"send-keys", "-t", worker.pane_id, "Enter", ";", "send-keys", "-l", "-t", worker.pane_id, GJC_TEAM_CONTINUATION_PROMPT,',
|
|
3283
|
+
),
|
|
3284
|
+
},
|
|
3285
|
+
1,
|
|
3286
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3287
|
+
);
|
|
3288
|
+
await runSelfTestFixture(
|
|
3289
|
+
{
|
|
3290
|
+
"packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
|
|
3291
|
+
"Bun.spawnSync([config.tmux_command, ...args]",
|
|
3292
|
+
'Bun.spawnSync([config.tmux_command, "run-shell", ...args]',
|
|
3293
|
+
),
|
|
3294
|
+
},
|
|
3295
|
+
1,
|
|
3296
|
+
"tmux send-keys content injection is outside sanctioned process lifecycle",
|
|
3297
|
+
);
|
|
3118
3298
|
await runSelfTestFixture(
|
|
3119
3299
|
{
|
|
3120
3300
|
"packages/coding-agent/src/coordinator-mcp/server.ts":
|