@gajae-code/coding-agent 0.11.0 → 0.11.2
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 +63 -1
- package/dist/types/async/job-manager.d.ts +46 -7
- package/dist/types/cli/config-cli.d.ts +11 -1
- 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 +56 -1
- 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-receipt-freshness.d.ts +11 -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 +3 -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/command-controller.d.ts +2 -2
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -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 +21 -19
- package/dist/types/modes/jobs-observer.d.ts +2 -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 +21 -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 +22 -15
- 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/ensure.d.ts +9 -0
- 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/discord-daemon.d.ts +5 -0
- package/dist/types/sdk/bus/html-format.d.ts +3 -2
- package/dist/types/sdk/bus/index.d.ts +27 -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 +69 -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/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 +3 -0
- package/dist/types/tools/search-tool-bm25.d.ts +3 -4
- package/dist/types/tools/subagent-render.d.ts +1 -0
- package/dist/types/tools/subagent.d.ts +6 -1
- package/dist/types/utils/event-bus.d.ts +1 -1
- package/dist/types/web/search/index.d.ts +3 -1
- package/package.json +21 -9
- package/scripts/build-sdk-package-smoke.ts +39 -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 +455 -69
- package/src/cli/config-cli.ts +75 -2
- 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 +159 -2
- 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 +320 -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 +83 -12
- package/src/gjc-runtime/ultragoal-pipeline.ts +306 -0
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +102 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +156 -1319
- 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 +28 -8
- 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/command-controller.ts +9 -15
- package/src/modes/controllers/event-controller.ts +3 -2
- package/src/modes/controllers/extension-ui-controller.ts +72 -25
- 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 +302 -1151
- package/src/modes/jobs-observer.ts +3 -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 +78 -19
- 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 +47 -20
- 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 +21 -2
- package/src/sdk/broker/ensure.ts +85 -25
- 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 +14 -4
- 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/discord-daemon.ts +25 -8
- package/src/sdk/bus/html-format.ts +20 -3
- package/src/sdk/bus/index.ts +834 -113
- package/src/sdk/bus/lifecycle-control-runtime.ts +91 -33
- package/src/sdk/bus/native-runtime-compatibility.ts +1 -1
- 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 +1491 -247
- 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 +31 -1
- 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 +458 -479
- package/src/session/agent-session.ts +1901 -637
- 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 +62 -37
- 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 +13 -5
- package/src/tools/read.ts +37 -1
- package/src/tools/resource-gc.ts +2 -2
- package/src/tools/search-tool-bm25.ts +11 -74
- package/src/tools/subagent-render.ts +19 -8
- package/src/tools/subagent.ts +84 -32
- package/src/utils/event-bus.ts +9 -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
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type { AsyncJob, AsyncJobManager, SubagentRecord } from "../async/job-manager";
|
|
2
|
+
import type { CronJobView, JobsObserver } from "./jobs-observer";
|
|
3
|
+
import type { ObservableSession, SessionObserverRegistry } from "./session-observer-registry";
|
|
4
|
+
|
|
5
|
+
export type TaskStatus = "running" | "waiting" | "done" | "failed" | "cancelled";
|
|
6
|
+
export type TaskKind = "bash" | "subagent" | "cron";
|
|
7
|
+
|
|
8
|
+
export interface TaskRow {
|
|
9
|
+
id: string;
|
|
10
|
+
kind: TaskKind;
|
|
11
|
+
label: string;
|
|
12
|
+
status: TaskStatus;
|
|
13
|
+
startedAt: number;
|
|
14
|
+
resumable?: boolean;
|
|
15
|
+
monitorOutputLines?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TasksSnapshot {
|
|
19
|
+
rows: TaskRow[];
|
|
20
|
+
worstState: TaskStatus | "none";
|
|
21
|
+
failedUnacknowledged: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const EMPTY_TASKS_SNAPSHOT: TasksSnapshot = { rows: [], worstState: "none", failedUnacknowledged: false };
|
|
25
|
+
|
|
26
|
+
const ASYNC_STATUS: Record<AsyncJob["status"], TaskStatus> = {
|
|
27
|
+
running: "running",
|
|
28
|
+
paused: "waiting",
|
|
29
|
+
completed: "done",
|
|
30
|
+
failed: "failed",
|
|
31
|
+
cancelled: "cancelled",
|
|
32
|
+
};
|
|
33
|
+
const SESSION_STATUS: Record<ObservableSession["status"], TaskStatus> = {
|
|
34
|
+
active: "running",
|
|
35
|
+
completed: "done",
|
|
36
|
+
failed: "failed",
|
|
37
|
+
aborted: "cancelled",
|
|
38
|
+
};
|
|
39
|
+
const SUBAGENT_STATUS: Record<SubagentRecord["status"], TaskStatus> = {
|
|
40
|
+
running: "running",
|
|
41
|
+
queued: "waiting",
|
|
42
|
+
paused: "waiting",
|
|
43
|
+
completed: "done",
|
|
44
|
+
failed: "failed",
|
|
45
|
+
cancelled: "cancelled",
|
|
46
|
+
};
|
|
47
|
+
const STATUS_RANK: Record<TaskStatus, number> = { done: 1, cancelled: 2, waiting: 3, running: 4, failed: 5 };
|
|
48
|
+
|
|
49
|
+
const MAX_TERMINAL_HISTORY_ROWS = 100;
|
|
50
|
+
|
|
51
|
+
export function mapAsyncJobStatus(status: AsyncJob["status"]): TaskStatus {
|
|
52
|
+
return ASYNC_STATUS[status];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function mapSessionStatus(status: ObservableSession["status"]): TaskStatus {
|
|
56
|
+
return SESSION_STATUS[status];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function mapSubagentStatus(status: SubagentRecord["status"]): TaskStatus {
|
|
60
|
+
return SUBAGENT_STATUS[status];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function mapCronStatus(cron: Pick<CronJobView, "firing">): TaskStatus {
|
|
64
|
+
return cron.firing ? "running" : "waiting";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Joins manager jobs, monitor/cron views, and live session metadata. Stable
|
|
68
|
+
* subagent records are canonical for lifecycle state; the registry contributes
|
|
69
|
+
* only the current display label and timestamp. */
|
|
70
|
+
export class TasksAggregator {
|
|
71
|
+
readonly #listeners = new Set<() => void>();
|
|
72
|
+
readonly #unsubscribers: Array<() => void> = [];
|
|
73
|
+
#snapshot: TasksSnapshot = EMPTY_TASKS_SNAPSHOT;
|
|
74
|
+
#scheduled = false;
|
|
75
|
+
#disposed = false;
|
|
76
|
+
|
|
77
|
+
constructor(
|
|
78
|
+
readonly manager: AsyncJobManager,
|
|
79
|
+
readonly jobsObserver: JobsObserver,
|
|
80
|
+
readonly sessions: SessionObserverRegistry,
|
|
81
|
+
readonly ownerId?: string,
|
|
82
|
+
) {
|
|
83
|
+
this.#unsubscribers.push(manager.onChange(() => this.#changed()));
|
|
84
|
+
this.#unsubscribers.push(jobsObserver.onChange(() => this.#changed()));
|
|
85
|
+
this.#unsubscribers.push(sessions.onChange(() => this.#changed()));
|
|
86
|
+
this.#recompute();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
onChange(cb: () => void): () => void {
|
|
90
|
+
this.#listeners.add(cb);
|
|
91
|
+
return () => this.#listeners.delete(cb);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
getSnapshot(): TasksSnapshot {
|
|
95
|
+
return this.#snapshot;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
acknowledgeFailures(): void {
|
|
99
|
+
this.jobsObserver.acknowledgeFailures();
|
|
100
|
+
this.#recompute();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#changed(): void {
|
|
104
|
+
if (this.#disposed) return;
|
|
105
|
+
this.#recompute();
|
|
106
|
+
if (this.#scheduled) return;
|
|
107
|
+
this.#scheduled = true;
|
|
108
|
+
queueMicrotask(() => {
|
|
109
|
+
this.#scheduled = false;
|
|
110
|
+
if (!this.#disposed) for (const listener of this.#listeners) listener();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
#recompute(): void {
|
|
115
|
+
const rows: TaskRow[] = [];
|
|
116
|
+
const filter = this.ownerId ? { ownerId: this.ownerId } : undefined;
|
|
117
|
+
const jobs = this.manager.getAllJobs(filter);
|
|
118
|
+
const monitorIds = new Set(this.jobsObserver.getSnapshot().monitors.map(monitor => monitor.id));
|
|
119
|
+
for (const job of jobs) {
|
|
120
|
+
// A subagent task is represented by its stable control-plane record.
|
|
121
|
+
if (job.metadata?.subagent) continue;
|
|
122
|
+
if (job.type !== "bash") continue;
|
|
123
|
+
rows.push({
|
|
124
|
+
id: `bash:${job.id}`,
|
|
125
|
+
kind: "bash",
|
|
126
|
+
label: job.label,
|
|
127
|
+
status: ASYNC_STATUS[job.status],
|
|
128
|
+
startedAt: job.startTime,
|
|
129
|
+
monitorOutputLines: monitorIds.has(job.id)
|
|
130
|
+
? lineCount(this.jobsObserver.getMonitorOutput(job.id))
|
|
131
|
+
: undefined,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const records = new Map(this.manager.getSubagentRecords(filter).map(record => [record.subagentId, record]));
|
|
136
|
+
const liveIds = new Set<string>();
|
|
137
|
+
for (const session of this.sessions.getSessions()) {
|
|
138
|
+
if (session.kind !== "subagent") continue;
|
|
139
|
+
liveIds.add(session.id);
|
|
140
|
+
const record = records.get(session.id);
|
|
141
|
+
rows.push({
|
|
142
|
+
id: `subagent:${session.id}`,
|
|
143
|
+
kind: "subagent",
|
|
144
|
+
label: session.label,
|
|
145
|
+
status: record ? SUBAGENT_STATUS[record.status] : SESSION_STATUS[session.status],
|
|
146
|
+
startedAt: session.lastUpdate,
|
|
147
|
+
resumable: record?.resumable,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
for (const record of records.values()) {
|
|
151
|
+
if (liveIds.has(record.subagentId)) continue;
|
|
152
|
+
rows.push({
|
|
153
|
+
id: `subagent:${record.subagentId}`,
|
|
154
|
+
kind: "subagent",
|
|
155
|
+
label: record.subagentId,
|
|
156
|
+
status: SUBAGENT_STATUS[record.status],
|
|
157
|
+
startedAt: record.queued?.createdAt ?? 0,
|
|
158
|
+
resumable: record.resumable,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
for (const cron of this.jobsObserver.getSnapshot().crons) rows.push(cronRow(cron));
|
|
162
|
+
rows.sort((a, b) => b.startedAt - a.startedAt || a.id.localeCompare(b.id));
|
|
163
|
+
let terminalRows = 0;
|
|
164
|
+
const boundedRows = rows.filter(row => {
|
|
165
|
+
if (row.status !== "done" && row.status !== "failed" && row.status !== "cancelled") return true;
|
|
166
|
+
terminalRows++;
|
|
167
|
+
return terminalRows <= MAX_TERMINAL_HISTORY_ROWS;
|
|
168
|
+
});
|
|
169
|
+
const failedUnacknowledged = this.jobsObserver.getSnapshot().failedUnacknowledged;
|
|
170
|
+
const worstState = failedUnacknowledged
|
|
171
|
+
? "failed"
|
|
172
|
+
: boundedRows.reduce<TasksSnapshot["worstState"]>(
|
|
173
|
+
(worst, row) => (worst === "none" || STATUS_RANK[row.status] > STATUS_RANK[worst] ? row.status : worst),
|
|
174
|
+
"none",
|
|
175
|
+
);
|
|
176
|
+
this.#snapshot = { rows: boundedRows, worstState, failedUnacknowledged };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
dispose(): void {
|
|
180
|
+
this.#disposed = true;
|
|
181
|
+
for (const unsubscribe of this.#unsubscribers) unsubscribe();
|
|
182
|
+
this.#unsubscribers.length = 0;
|
|
183
|
+
this.#listeners.clear();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function cronRow(cron: CronJobView): TaskRow {
|
|
188
|
+
return {
|
|
189
|
+
id: `cron:${cron.id}`,
|
|
190
|
+
kind: "cron",
|
|
191
|
+
label: cron.humanSchedule,
|
|
192
|
+
status: cron.firing ? "running" : "waiting",
|
|
193
|
+
startedAt: cron.createdAt,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function lineCount(output: string): number {
|
|
198
|
+
return output.length === 0 ? 0 : output.split("\n").length;
|
|
199
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
export type TranscriptItemKind = "user" | "assistant-text" | "assistant-thinking" | "tool" | "read-group" | "custom";
|
|
2
|
+
|
|
3
|
+
export type TranscriptItemCapabilities = {
|
|
4
|
+
copyable: boolean;
|
|
5
|
+
foldable: boolean;
|
|
6
|
+
rawViewable: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type TranscriptSourcePayload = {
|
|
10
|
+
text: string;
|
|
11
|
+
metadata: Readonly<Record<string, unknown>>;
|
|
12
|
+
source: unknown;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type TranscriptItem = {
|
|
16
|
+
id: string;
|
|
17
|
+
kind: TranscriptItemKind;
|
|
18
|
+
source: unknown;
|
|
19
|
+
getPayload?: (source: unknown) => TranscriptSourcePayload;
|
|
20
|
+
capabilities?: Partial<TranscriptItemCapabilities>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type RegisterTranscriptItem = Omit<TranscriptItem, "id"> & { id?: string };
|
|
24
|
+
|
|
25
|
+
export type StreamingItemOptions = Omit<RegisterTranscriptItem, "id" | "kind"> & {
|
|
26
|
+
promptGeneration: number | string;
|
|
27
|
+
messageOrdinal: number;
|
|
28
|
+
kind?: "assistant-text" | "assistant-thinking";
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const DEFAULT_CAPABILITIES: Record<TranscriptItemKind, TranscriptItemCapabilities> = {
|
|
32
|
+
user: { copyable: true, foldable: false, rawViewable: true },
|
|
33
|
+
"assistant-text": { copyable: true, foldable: false, rawViewable: true },
|
|
34
|
+
"assistant-thinking": { copyable: true, foldable: true, rawViewable: true },
|
|
35
|
+
tool: { copyable: true, foldable: true, rawViewable: true },
|
|
36
|
+
"read-group": { copyable: true, foldable: true, rawViewable: true },
|
|
37
|
+
custom: { copyable: true, foldable: false, rawViewable: true },
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** Stable transcript identities shared by the inline and overlay projections. */
|
|
41
|
+
export const transcriptItemId = {
|
|
42
|
+
entry: (entryId: string): string => `entry:${entryId}`,
|
|
43
|
+
assistantContent: (entryId: string, contentIndex: number): string => `entry:${entryId}:content:${contentIndex}`,
|
|
44
|
+
tool: (toolCallId: string): string => `tool:${toolCallId}`,
|
|
45
|
+
readGroup: (groupId: string): string => `read-group:${groupId}`,
|
|
46
|
+
custom: (customId: string): string => `custom:${customId}`,
|
|
47
|
+
stream: (promptGeneration: number | string, messageOrdinal: number): string =>
|
|
48
|
+
`stream:${promptGeneration}:${messageOrdinal}`,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function defaultPayload(source: unknown): TranscriptSourcePayload {
|
|
52
|
+
if (typeof source === "string") return { text: source, metadata: {}, source };
|
|
53
|
+
if (!source || typeof source !== "object") return { text: "", metadata: {}, source };
|
|
54
|
+
|
|
55
|
+
const record = source as Record<string, unknown>;
|
|
56
|
+
const text = typeof record.text === "string" ? record.text : extractContentText(record.content);
|
|
57
|
+
const metadata = Object.fromEntries(Object.entries(record).filter(([key]) => key !== "text" && key !== "content"));
|
|
58
|
+
return { text, metadata, source };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function extractContentText(content: unknown): string {
|
|
62
|
+
if (typeof content === "string") return content;
|
|
63
|
+
if (!Array.isArray(content)) return "";
|
|
64
|
+
return content
|
|
65
|
+
.map(item => {
|
|
66
|
+
if (!item || typeof item !== "object") return "";
|
|
67
|
+
const record = item as Record<string, unknown>;
|
|
68
|
+
if (typeof record.text === "string") return record.text;
|
|
69
|
+
if (typeof record.thinking === "string") return record.thinking;
|
|
70
|
+
return "";
|
|
71
|
+
})
|
|
72
|
+
.join("");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A session-local index of transcript projection items. It deliberately stores only
|
|
77
|
+
* structural sources, allowing interactive mode to supply live streaming objects
|
|
78
|
+
* and persisted session records without importing either implementation here.
|
|
79
|
+
*/
|
|
80
|
+
export class TranscriptItemRegistry {
|
|
81
|
+
#items = new Map<string, TranscriptItem>();
|
|
82
|
+
#aliases = new Map<string, string>();
|
|
83
|
+
#sessionId: string | undefined;
|
|
84
|
+
|
|
85
|
+
get sessionId(): string | undefined {
|
|
86
|
+
return this.#sessionId;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Ordered snapshot for read-only transcript projections. */
|
|
90
|
+
items(): readonly TranscriptItem[] {
|
|
91
|
+
return [...this.#items.values()];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
register(item: RegisterTranscriptItem): string {
|
|
95
|
+
const id = item.id ?? this.#idForKind(item.kind, item.source);
|
|
96
|
+
if (this.#items.has(id)) throw new Error(`Transcript item already registered: ${id}`);
|
|
97
|
+
this.#items.set(id, { ...item, id });
|
|
98
|
+
return id;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
replace(id: string, item: Omit<TranscriptItem, "id">): boolean {
|
|
102
|
+
const canonicalId = this.#resolveId(id);
|
|
103
|
+
if (!canonicalId || !this.#items.has(canonicalId)) return false;
|
|
104
|
+
this.#items.set(canonicalId, { ...item, id: canonicalId });
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
startStream(options: StreamingItemOptions): string {
|
|
109
|
+
const id = transcriptItemId.stream(options.promptGeneration, options.messageOrdinal);
|
|
110
|
+
if (this.#items.has(id) || this.#aliases.has(id)) throw new Error(`Transcript stream already registered: ${id}`);
|
|
111
|
+
this.#items.set(id, { ...options, id, kind: options.kind ?? "assistant-text" });
|
|
112
|
+
return id;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Reconciles one exact live stream with its persisted canonical item. */
|
|
116
|
+
endStream(streamId: string, item: RegisterTranscriptItem): string | undefined {
|
|
117
|
+
if (!streamId.startsWith("stream:") || !this.#items.has(streamId)) return undefined;
|
|
118
|
+
const canonicalId = item.id ?? this.#idForKind(item.kind, item.source);
|
|
119
|
+
if (canonicalId !== streamId && this.#items.has(canonicalId)) return undefined;
|
|
120
|
+
if (canonicalId === streamId) {
|
|
121
|
+
this.#items.set(streamId, { ...item, id: streamId });
|
|
122
|
+
return streamId;
|
|
123
|
+
}
|
|
124
|
+
this.#items.set(canonicalId, { ...item, id: canonicalId });
|
|
125
|
+
this.#items.delete(streamId);
|
|
126
|
+
this.#aliases.set(streamId, canonicalId);
|
|
127
|
+
return canonicalId;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
retireStream(id: string): boolean {
|
|
131
|
+
if (!id.startsWith("stream:") || !this.#items.delete(id)) return false;
|
|
132
|
+
this.#aliases.delete(id);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
coalesceReadGroup(groupId: string, source: unknown, toolCallIds: readonly string[] = []): string {
|
|
137
|
+
const id = transcriptItemId.readGroup(groupId);
|
|
138
|
+
this.#items.set(id, {
|
|
139
|
+
id,
|
|
140
|
+
kind: "read-group",
|
|
141
|
+
source,
|
|
142
|
+
getPayload: value => {
|
|
143
|
+
const payload = defaultPayload(value);
|
|
144
|
+
return { ...payload, metadata: { ...payload.metadata, groupId, toolCallIds } };
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
return id;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
rebuild(items: readonly RegisterTranscriptItem[]): void {
|
|
151
|
+
this.#items.clear();
|
|
152
|
+
this.#aliases.clear();
|
|
153
|
+
for (const item of items) this.register(item);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
evict(id: string): boolean {
|
|
157
|
+
const canonicalId = this.#resolveId(id);
|
|
158
|
+
if (!canonicalId || !this.#items.delete(canonicalId)) return false;
|
|
159
|
+
for (const [alias, target] of this.#aliases) {
|
|
160
|
+
if (target === canonicalId) this.#aliases.delete(alias);
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
switchSession(sessionId: string): void {
|
|
166
|
+
if (this.#sessionId === sessionId) return;
|
|
167
|
+
this.#sessionId = sessionId;
|
|
168
|
+
this.#items.clear();
|
|
169
|
+
this.#aliases.clear();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
resolveSourcePayload(id: string): TranscriptSourcePayload | undefined {
|
|
173
|
+
const canonicalId = this.#resolveId(id);
|
|
174
|
+
const item = canonicalId ? this.#items.get(canonicalId) : undefined;
|
|
175
|
+
if (!item) return undefined;
|
|
176
|
+
return (item.getPayload ?? defaultPayload)(item.source);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
capabilities(id: string): TranscriptItemCapabilities | undefined {
|
|
180
|
+
const canonicalId = this.#resolveId(id);
|
|
181
|
+
const item = canonicalId ? this.#items.get(canonicalId) : undefined;
|
|
182
|
+
if (!item) return undefined;
|
|
183
|
+
return { ...DEFAULT_CAPABILITIES[item.kind], ...item.capabilities };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
has(id: string): boolean {
|
|
187
|
+
const canonicalId = this.#resolveId(id);
|
|
188
|
+
return canonicalId !== undefined && this.#items.has(canonicalId);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
canonicalId(id: string): string | undefined {
|
|
192
|
+
return this.#resolveId(id);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
#resolveId(id: string): string | undefined {
|
|
196
|
+
let resolved = id;
|
|
197
|
+
const seen = new Set<string>();
|
|
198
|
+
while (this.#aliases.has(resolved) && !seen.has(resolved)) {
|
|
199
|
+
seen.add(resolved);
|
|
200
|
+
resolved = this.#aliases.get(resolved)!;
|
|
201
|
+
}
|
|
202
|
+
return this.#items.has(resolved) ? resolved : undefined;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
#idForKind(kind: TranscriptItemKind, source: unknown): string {
|
|
206
|
+
const record = source && typeof source === "object" ? (source as Record<string, unknown>) : {};
|
|
207
|
+
switch (kind) {
|
|
208
|
+
case "user":
|
|
209
|
+
if (typeof record.entryId === "string") return transcriptItemId.entry(record.entryId);
|
|
210
|
+
break;
|
|
211
|
+
case "assistant-text":
|
|
212
|
+
case "assistant-thinking":
|
|
213
|
+
if (typeof record.entryId === "string" && typeof record.contentIndex === "number") {
|
|
214
|
+
return transcriptItemId.assistantContent(record.entryId, record.contentIndex);
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
case "tool":
|
|
218
|
+
if (typeof record.toolCallId === "string") return transcriptItemId.tool(record.toolCallId);
|
|
219
|
+
break;
|
|
220
|
+
case "read-group":
|
|
221
|
+
if (typeof record.groupId === "string") return transcriptItemId.readGroup(record.groupId);
|
|
222
|
+
break;
|
|
223
|
+
case "custom":
|
|
224
|
+
if (typeof record.id === "string") return transcriptItemId.custom(record.id);
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
throw new Error(`Transcript item ${kind} requires an explicit id or canonical source identity.`);
|
|
228
|
+
}
|
|
229
|
+
}
|
package/src/modes/types.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentMessage } from "@gajae-code/agent-core";
|
|
2
2
|
import type { CompactionOutcome } from "@gajae-code/agent-core/compaction";
|
|
3
3
|
import type { AssistantMessage, ImageContent, Message, UsageReport } from "@gajae-code/ai";
|
|
4
|
-
import type { Component, Container, EditorTheme, Loader, Spacer, Text, TUI } from "@gajae-code/tui";
|
|
4
|
+
import type { Component, Container, EditorTheme, Loader, SlashCommand, Spacer, Text, TUI } from "@gajae-code/tui";
|
|
5
5
|
import type { KeybindingsManager } from "../config/keybindings";
|
|
6
6
|
import type { Settings } from "../config/settings";
|
|
7
7
|
import type {
|
|
@@ -12,7 +12,6 @@ import type {
|
|
|
12
12
|
} from "../extensibility/extensions";
|
|
13
13
|
import type { CompactOptions } from "../extensibility/extensions/types";
|
|
14
14
|
import type { Skill } from "../extensibility/skills";
|
|
15
|
-
import type { PlanApprovalDetails } from "../plan-mode/approved-plan";
|
|
16
15
|
import type { MCPManager } from "../runtime-mcp";
|
|
17
16
|
import type { NotificationSessionReconcileResult, NotificationSessionStatus } from "../sdk/bus/session-control";
|
|
18
17
|
import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
|
|
@@ -22,14 +21,15 @@ import type { CredentialAutoImportOptions } from "../setup/credential-auto-impor
|
|
|
22
21
|
import type { LspStartupServerInfo } from "../tools";
|
|
23
22
|
import type { AssistantMessageComponent } from "./components/assistant-message";
|
|
24
23
|
import type { BashExecutionComponent } from "./components/bash-execution";
|
|
24
|
+
import type { CommandPaletteAction } from "./components/command-palette";
|
|
25
25
|
import type { CustomEditor } from "./components/custom-editor";
|
|
26
26
|
import type { EvalExecutionComponent } from "./components/eval-execution";
|
|
27
27
|
import type { PetMode } from "./components/gajae-pet-widget";
|
|
28
28
|
import type { HookEditorComponent } from "./components/hook-editor";
|
|
29
29
|
import type { HookInputComponent } from "./components/hook-input";
|
|
30
30
|
import type { HookSelectorComponent } from "./components/hook-selector";
|
|
31
|
-
import type { StatusLineComponent } from "./components/status-line";
|
|
32
31
|
import type { ToolExecutionHandle } from "./components/tool-execution";
|
|
32
|
+
import type { StatusLineComponent } from "./components/tool-status-header";
|
|
33
33
|
import type { IrcObservationLedger } from "./irc-observation-ledger";
|
|
34
34
|
import type { OAuthManualInputManager } from "./oauth-manual-input";
|
|
35
35
|
import type { Theme } from "./theme/theme";
|
|
@@ -51,6 +51,17 @@ export type SubmittedUserInput = {
|
|
|
51
51
|
started: boolean;
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
+
export type ComposerSubmissionOptions = Readonly<{
|
|
55
|
+
ownsComposer: boolean;
|
|
56
|
+
editor: CustomEditor;
|
|
57
|
+
}>;
|
|
58
|
+
|
|
59
|
+
export function canApplyComposerSubmission(
|
|
60
|
+
options: ComposerSubmissionOptions | undefined,
|
|
61
|
+
editor: CustomEditor,
|
|
62
|
+
): boolean {
|
|
63
|
+
return options === undefined || (options.ownsComposer && editor === options.editor);
|
|
64
|
+
}
|
|
54
65
|
export type TodoStatus = "pending" | "in_progress" | "completed" | "abandoned";
|
|
55
66
|
|
|
56
67
|
export type TodoItem = {
|
|
@@ -109,10 +120,6 @@ export interface InteractiveModeContext {
|
|
|
109
120
|
isBashNoContext: boolean;
|
|
110
121
|
toolOutputExpanded: boolean;
|
|
111
122
|
todoExpanded: boolean;
|
|
112
|
-
planModeEnabled: boolean;
|
|
113
|
-
goalModeEnabled: boolean;
|
|
114
|
-
goalModePaused: boolean;
|
|
115
|
-
planModePlanFilePath?: string;
|
|
116
123
|
hideThinkingBlock: boolean;
|
|
117
124
|
pendingImages: ImageContent[];
|
|
118
125
|
compactionQueuedMessages: CompactionQueuedMessage[];
|
|
@@ -174,10 +181,9 @@ export interface InteractiveModeContext {
|
|
|
174
181
|
showNewVersionNotification(newVersion: string): void;
|
|
175
182
|
clearEditor(): void;
|
|
176
183
|
updatePendingMessagesDisplay(): void;
|
|
177
|
-
queueCompactionMessage(text: string, mode: "steer" | "followUp"): void;
|
|
184
|
+
queueCompactionMessage(text: string, mode: "steer" | "followUp", options?: ComposerSubmissionOptions): void;
|
|
178
185
|
flushCompactionQueue(options?: { willRetry?: boolean }): Promise<void>;
|
|
179
186
|
flushPendingBashComponents(): void;
|
|
180
|
-
flushPendingModelSwitch(): Promise<void>;
|
|
181
187
|
setWorkingMessage(message?: string): void;
|
|
182
188
|
applyPendingWorkingMessage(): void;
|
|
183
189
|
ensureLoadingAnimation(): void;
|
|
@@ -196,12 +202,15 @@ export interface InteractiveModeContext {
|
|
|
196
202
|
commitPetPreviewMode(mode: PetMode): boolean;
|
|
197
203
|
/** Re-mount the composer (pet-aware) after an overlay/selector closes. */
|
|
198
204
|
restoreComposer(): void;
|
|
199
|
-
startPendingSubmission(
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
+
startPendingSubmission(
|
|
206
|
+
input: {
|
|
207
|
+
text: string;
|
|
208
|
+
images?: ImageContent[];
|
|
209
|
+
customType?: string;
|
|
210
|
+
display?: boolean;
|
|
211
|
+
},
|
|
212
|
+
options?: ComposerSubmissionOptions,
|
|
213
|
+
): SubmittedUserInput;
|
|
205
214
|
cancelPendingSubmission(): boolean;
|
|
206
215
|
markPendingSubmissionStarted(input: SubmittedUserInput): boolean;
|
|
207
216
|
finishPendingSubmission(input: SubmittedUserInput): void;
|
|
@@ -263,9 +272,9 @@ export interface InteractiveModeContext {
|
|
|
263
272
|
handleContextCommand(): void;
|
|
264
273
|
handleDumpCommand(): void;
|
|
265
274
|
handleDebugTranscriptCommand(): Promise<void>;
|
|
266
|
-
handleClearCommand(): Promise<
|
|
275
|
+
handleClearCommand(): Promise<boolean>;
|
|
267
276
|
handleContextClearCommand(): Promise<void>;
|
|
268
|
-
handleDropCommand(): Promise<
|
|
277
|
+
handleDropCommand(): Promise<boolean>;
|
|
269
278
|
handleForkCommand(): Promise<void>;
|
|
270
279
|
handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
|
|
271
280
|
handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
|
|
@@ -282,10 +291,18 @@ export interface InteractiveModeContext {
|
|
|
282
291
|
customInstructionsOrOptions?: string | CompactOptions,
|
|
283
292
|
isAuto?: boolean,
|
|
284
293
|
): Promise<CompactionOutcome>;
|
|
294
|
+
|
|
285
295
|
openInBrowser(urlOrPath: string): void;
|
|
296
|
+
/** Resolved source of truth for slash autocomplete and command palette entries. */
|
|
297
|
+
getSlashCommands?(): readonly SlashCommand[];
|
|
286
298
|
refreshSlashCommandState(cwd?: string): Promise<void>;
|
|
287
299
|
|
|
288
300
|
// Selector handling
|
|
301
|
+
showCommandPalette(
|
|
302
|
+
commands: SlashCommand[],
|
|
303
|
+
actions: CommandPaletteAction[],
|
|
304
|
+
executeSlashCommand: (name: string) => Promise<void>,
|
|
305
|
+
): void;
|
|
289
306
|
showSettingsSelector(): void;
|
|
290
307
|
showThemeSelector(): void;
|
|
291
308
|
showPetSelector(): void;
|
|
@@ -299,6 +316,7 @@ export interface InteractiveModeContext {
|
|
|
299
316
|
showUserMessageSelector(): void;
|
|
300
317
|
showTreeSelector(): void;
|
|
301
318
|
showSessionSelector(): void;
|
|
319
|
+
showSessionsDashboard(): void;
|
|
302
320
|
handleResumeSession(sessionPath: string): Promise<void>;
|
|
303
321
|
handleSessionDeleteCommand(): Promise<void>;
|
|
304
322
|
showOAuthSelector(mode: "login" | "logout", providerId?: string, options?: OAuthSelectorOptions): Promise<void>;
|
|
@@ -306,6 +324,10 @@ export interface InteractiveModeContext {
|
|
|
306
324
|
showDebugSelector(): void;
|
|
307
325
|
showSessionObserver(): void;
|
|
308
326
|
showJobsOverlay(): void;
|
|
327
|
+
showTasksPane(): void;
|
|
328
|
+
showTranscriptViewer(): void;
|
|
329
|
+
isTranscriptViewerOpen(): boolean;
|
|
330
|
+
refreshTranscriptViewer(): void;
|
|
309
331
|
resetObserverRegistry(): void;
|
|
310
332
|
|
|
311
333
|
// Input handling
|
|
@@ -325,9 +347,6 @@ export interface InteractiveModeContext {
|
|
|
325
347
|
toggleThinkingBlockVisibility(): void;
|
|
326
348
|
openExternalEditor(): void;
|
|
327
349
|
registerExtensionShortcuts(): void;
|
|
328
|
-
handlePlanModeCommand(initialPrompt?: string): Promise<void>;
|
|
329
|
-
handleGoalModeCommand(rest?: string): Promise<void>;
|
|
330
|
-
handlePlanApproval(details: PlanApprovalDetails): Promise<void>;
|
|
331
350
|
|
|
332
351
|
// Hook UI methods
|
|
333
352
|
initHooksAndCustomTools(): Promise<void>;
|
|
@@ -335,6 +354,14 @@ export interface InteractiveModeContext {
|
|
|
335
354
|
reason: "start" | "switch" | "branch" | "tree" | "shutdown",
|
|
336
355
|
previousSessionFile?: string,
|
|
337
356
|
): Promise<void>;
|
|
357
|
+
planModeController: Pick<
|
|
358
|
+
import("./controllers/plan-mode-controller").PlanModeController,
|
|
359
|
+
"enabled" | "paused" | "planFilePath" | "handleCommand" | "handleApproval" | "flushPendingModelSwitch"
|
|
360
|
+
>;
|
|
361
|
+
goalModeController: Pick<
|
|
362
|
+
import("./controllers/goal-mode-controller").GoalModeController,
|
|
363
|
+
"enabled" | "paused" | "handleCommand"
|
|
364
|
+
>;
|
|
338
365
|
setHookWidget(key: string, content: ExtensionWidgetContent, options?: ExtensionWidgetOptions): void;
|
|
339
366
|
setHookStatus(key: string, text: string | undefined): void;
|
|
340
367
|
showHookSelector(
|
|
@@ -20,11 +20,13 @@ import { SkillMessageComponent } from "../../modes/components/skill-message";
|
|
|
20
20
|
import { ToolExecutionComponent } from "../../modes/components/tool-execution";
|
|
21
21
|
import { UserMessageComponent } from "../../modes/components/user-message";
|
|
22
22
|
import { theme } from "../../modes/theme/theme";
|
|
23
|
-
import
|
|
24
|
-
CompactionQueuedMessage,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
import {
|
|
24
|
+
type CompactionQueuedMessage,
|
|
25
|
+
type ComposerSubmissionOptions,
|
|
26
|
+
canApplyComposerSubmission,
|
|
27
|
+
type InteractiveModeContext,
|
|
28
|
+
type IrcArrivalSnapshot,
|
|
29
|
+
type TranscriptRebuildPolicy,
|
|
28
30
|
} from "../../modes/types";
|
|
29
31
|
import {
|
|
30
32
|
type CustomMessage,
|
|
@@ -290,7 +292,11 @@ export class UiHelpers {
|
|
|
290
292
|
const semanticId = getSessionMessageViewportAnchorId(message);
|
|
291
293
|
if (semanticId) return semanticId;
|
|
292
294
|
const entryId = getSessionMessageEntryId(message);
|
|
293
|
-
if (entryId)
|
|
295
|
+
if (entryId) {
|
|
296
|
+
const id = `user:entry:${entryId}`;
|
|
297
|
+
associateSessionMessageViewportAnchorId(message, id);
|
|
298
|
+
return id;
|
|
299
|
+
}
|
|
294
300
|
const base = `user:local:${message.timestamp}:${stableSemanticIdPart(JSON.stringify(message.content))}`;
|
|
295
301
|
const id = this.#viewportAnchorOccurrenceId(message, base);
|
|
296
302
|
associateSessionMessageViewportAnchorId(message, id);
|
|
@@ -916,14 +922,16 @@ export class UiHelpers {
|
|
|
916
922
|
}
|
|
917
923
|
}
|
|
918
924
|
|
|
919
|
-
queueCompactionMessage(text: string, mode: "steer" | "followUp"): void {
|
|
925
|
+
queueCompactionMessage(text: string, mode: "steer" | "followUp", options?: ComposerSubmissionOptions): void {
|
|
920
926
|
const entry: CompactionQueuedMessage = { text, mode };
|
|
921
927
|
if (mode === "followUp") {
|
|
922
928
|
entry.followUpQueuePolicy = "sequential";
|
|
923
929
|
}
|
|
924
930
|
this.ctx.compactionQueuedMessages.push(entry);
|
|
925
|
-
this.ctx.editor
|
|
926
|
-
|
|
931
|
+
if (canApplyComposerSubmission(options, this.ctx.editor)) {
|
|
932
|
+
this.ctx.editor.addToHistory(text);
|
|
933
|
+
this.ctx.editor.setText("");
|
|
934
|
+
}
|
|
927
935
|
this.ctx.updatePendingMessagesDisplay();
|
|
928
936
|
this.ctx.showStatus("Queued message for after compaction");
|
|
929
937
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Persistence (ralplan runs only):
|
|
2
|
+
- Only when the assignment references a ralplan stage or `stage_n`, persist the full artifact through:
|
|
3
|
+
|
|
4
|
+
gjc ralplan --write --stage {{stage}} --stage_n <N> --artifact-env GJC_RALPLAN_ARTIFACT --json
|
|
5
|
+
|
|
6
|
+
Use the assignment-provided `stage_n`; on a duplicate-write error retry with the incremented N. Return the write receipt (`run_id`, `path`, `sha256`, `stage`, `stage_n`) and the role's compact verdict only. Otherwise, do not call `gjc ralplan --write`; return the full result in `yield.result.data`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
- Exception: restricted `bash` is only for sanctioned GJC workflow persistence (`gjc ralplan --write ...`) and GJC workflow state commands (`gjc state ...`). Pass artifacts through `GJC_RALPLAN_ARTIFACT` with `--artifact-env GJC_RALPLAN_ARTIFACT`; never use bash for product-source writes or general shell work.
|
|
@@ -27,7 +27,7 @@ You may receive a forked parent-conversation snapshot as background. Your read-o
|
|
|
27
27
|
|
|
28
28
|
<constraints>
|
|
29
29
|
- Read-only: never write, edit, format, commit, push, or mutate files.
|
|
30
|
-
|
|
30
|
+
{{restrictedBash}}
|
|
31
31
|
- Never approve code or plans you have not grounded in inspected files.
|
|
32
32
|
- Never give generic advice detached from this codebase.
|
|
33
33
|
- Never approve CRITICAL or HIGH severity issues.
|
|
@@ -94,11 +94,5 @@ Table or bullets comparing viable options when relevant.
|
|
|
94
94
|
Structured findings:
|
|
95
95
|
- Report every issue through `report_finding` as you confirm it, mapping severity CRITICAL → P0, HIGH → P1, MEDIUM → P2, LOW → P3. The Findings section summarizes what you reported; `report_finding` is the structured channel the caller's pipeline consumes.
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
- Only when your assignment is part of an active ralplan run (the assignment references a ralplan stage or `stage_n`), persist the full review through the restricted bash CLI:
|
|
99
|
-
|
|
100
|
-
gjc ralplan --write --stage architect --stage_n <N> --artifact-env GJC_RALPLAN_ARTIFACT --json
|
|
101
|
-
|
|
102
|
-
Use the assignment-provided `stage_n`; if a duplicate-write error occurs, retry with the incremented N. Then return ONLY the write receipt (`run_id`, `path`, `sha256`, `stage`, `stage_n`) plus compact verdict (Architectural Status + Code Review Recommendation) in `yield.result.data`. Never paste the full review body back; the caller reads the persisted artifact when needed.
|
|
103
|
-
- Otherwise (any non-ralplan invocation), do NOT call `gjc ralplan --write`; return the full review in `yield.result.data` instead.
|
|
97
|
+
{{ralplanPersistence}}
|
|
104
98
|
</output_contract>
|