@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
package/src/sdk/broker/broker.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import type { NativeDirectoryTreeSnapshot } from "@gajae-code/natives";
|
|
5
|
+
import {
|
|
6
|
+
type DirectoryMigrationPolicy,
|
|
7
|
+
listManagedSessionCandidates,
|
|
8
|
+
resolveManagedSessionScope,
|
|
9
|
+
} from "../session-directory";
|
|
5
10
|
import {
|
|
6
11
|
BROKER_HEARTBEAT_TTL_MS,
|
|
7
12
|
type BrokerDiscovery,
|
|
@@ -9,6 +14,7 @@ import {
|
|
|
9
14
|
brokerProcessIncarnation,
|
|
10
15
|
isPidAlive,
|
|
11
16
|
newBrokerToken,
|
|
17
|
+
type RedactedBrokerDiscovery,
|
|
12
18
|
readBrokerDiscovery,
|
|
13
19
|
redactBrokerDiscovery,
|
|
14
20
|
writeBrokerDiscovery,
|
|
@@ -20,6 +26,7 @@ import {
|
|
|
20
26
|
type LifecycleDurableEffectsReceipt,
|
|
21
27
|
LifecycleLedger,
|
|
22
28
|
type LifecycleStartupFailureReceipt,
|
|
29
|
+
type LifecycleState,
|
|
23
30
|
} from "./lifecycle-ledger";
|
|
24
31
|
import { type IndexedSession, SessionIndex } from "./session-index";
|
|
25
32
|
import { BrokerTransport } from "./transport";
|
|
@@ -29,7 +36,18 @@ export interface BrokerSettings {
|
|
|
29
36
|
packageGeneration?: string;
|
|
30
37
|
port?: number;
|
|
31
38
|
heartbeatTtlMs?: number;
|
|
39
|
+
/** Broker-owned migration policy. Client lifecycle frames cannot select it. */
|
|
40
|
+
resolveDirectoryMigration?: (_cwd: string) => Promise<DirectoryMigrationPolicy>;
|
|
32
41
|
}
|
|
42
|
+
|
|
43
|
+
type ResolvedBrokerSettings = {
|
|
44
|
+
agentDir: string;
|
|
45
|
+
packageGeneration: string;
|
|
46
|
+
port: number;
|
|
47
|
+
heartbeatTtlMs: number;
|
|
48
|
+
resolveDirectoryMigration: (_cwd: string) => Promise<DirectoryMigrationPolicy>;
|
|
49
|
+
};
|
|
50
|
+
|
|
33
51
|
export type BrokerErrorCode =
|
|
34
52
|
| "idempotency_conflict"
|
|
35
53
|
| "terminal_uncertain"
|
|
@@ -46,10 +64,73 @@ export type BrokerErrorCode =
|
|
|
46
64
|
| "cleanup_pending"
|
|
47
65
|
| (string & {});
|
|
48
66
|
|
|
67
|
+
export type BrokerCleanupIdentity = {
|
|
68
|
+
dev: string;
|
|
69
|
+
ino: string;
|
|
70
|
+
size: number;
|
|
71
|
+
mtimeNs: string;
|
|
72
|
+
sha256: string;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** Exact retry evidence; detached paths are managed-receipt references, never caller authority. */
|
|
76
|
+
export type BrokerLifecycleCleanupFile = {
|
|
77
|
+
/** Original lifecycle-owned path, retained only for exact identity validation. */
|
|
78
|
+
path: string;
|
|
79
|
+
identity: BrokerCleanupIdentity;
|
|
80
|
+
/** Monotonic append-only cleanup attempt. */
|
|
81
|
+
attempt?: number;
|
|
82
|
+
/** Immutable no-replace quarantine destination persisted before native detach. */
|
|
83
|
+
plannedPath: string;
|
|
84
|
+
/** Native-returned detached path, persisted after a failed post-detach cleanup. */
|
|
85
|
+
detachedPath?: string;
|
|
86
|
+
/** Append-only terminal proof for this exact artifact; completed entries are never retried. */
|
|
87
|
+
completed?: true;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/** Durable root-tree authority for broker artifact cleanup. */
|
|
91
|
+
export type BrokerArtifactTree = {
|
|
92
|
+
identity: BrokerCleanupIdentity;
|
|
93
|
+
snapshot: NativeDirectoryTreeSnapshot;
|
|
94
|
+
plannedPath: string;
|
|
95
|
+
detachedPath?: string;
|
|
96
|
+
completed?: true;
|
|
97
|
+
};
|
|
98
|
+
|
|
49
99
|
export type BrokerCleanupEvidence = {
|
|
50
|
-
phase: "artifacts" | "transcript" | "metadata";
|
|
51
|
-
|
|
52
|
-
|
|
100
|
+
phase: "artifacts" | "transcript" | "metadata" | "lifecycle";
|
|
101
|
+
/** Ledger-bound deletion target; never reconstructed from a retry request. */
|
|
102
|
+
sessionsRoot?: string;
|
|
103
|
+
transcriptPath?: string;
|
|
104
|
+
cwd?: string;
|
|
105
|
+
metadataRoot?: string;
|
|
106
|
+
sessionId?: string;
|
|
107
|
+
artifactsIdentity?: BrokerCleanupIdentity;
|
|
108
|
+
transcriptIdentity?: BrokerCleanupIdentity;
|
|
109
|
+
/** Identity-bound lifecycle metadata marker retained when exact cleanup is deferred. */
|
|
110
|
+
metadataIdentity?: BrokerCleanupIdentity;
|
|
111
|
+
metadataPath?: string;
|
|
112
|
+
/** Monotonic append-only cleanup attempt. */
|
|
113
|
+
metadataAttempt?: number;
|
|
114
|
+
/** No-replace quarantine destination persisted before lifecycle metadata detach. */
|
|
115
|
+
plannedMetadataPath?: string;
|
|
116
|
+
/** Native-returned metadata quarantine path retained until identity-bound reconciliation succeeds. */
|
|
117
|
+
detachedMetadataPath?: string;
|
|
118
|
+
/** Append-only terminal proof for lifecycle metadata cleanup. */
|
|
119
|
+
metadataCompleted?: true;
|
|
120
|
+
detachedArtifactsPath?: string;
|
|
121
|
+
detachedTranscriptPath?: string;
|
|
122
|
+
/** Durable proof that artifact cleanup completed before transcript mutation. */
|
|
123
|
+
artifactsRemoved?: boolean;
|
|
124
|
+
/** Preauthorized no-replace artifact quarantine path persisted before detach. */
|
|
125
|
+
plannedArtifactsPath?: string;
|
|
126
|
+
/** Identity-bound artifact tree authority persisted before broker detach and replayed exactly. */
|
|
127
|
+
artifactTree?: BrokerArtifactTree;
|
|
128
|
+
/** Preauthorized no-replace transcript quarantine path persisted before detach. */
|
|
129
|
+
plannedTranscriptPath?: string;
|
|
130
|
+
/** Fully identity-bound startup-failure cleanup plan, persisted before any detach. */
|
|
131
|
+
lifecycleFiles?: BrokerLifecycleCleanupFile[];
|
|
132
|
+
/** Delete metadata receipts authorize only the canonical marker/ready sibling pair. */
|
|
133
|
+
lifecycleDeleteMetadata?: true;
|
|
53
134
|
};
|
|
54
135
|
export type BrokerResponse =
|
|
55
136
|
| { ok: true; result?: unknown; indexSeq?: number }
|
|
@@ -67,6 +148,16 @@ export type BrokerResponse =
|
|
|
67
148
|
};
|
|
68
149
|
const error = (code: BrokerErrorCode, message: string): BrokerResponse => ({ ok: false, error: { code, message } });
|
|
69
150
|
|
|
151
|
+
function isCleanupPending(response: BrokerResponse): boolean {
|
|
152
|
+
return !response.ok && response.error.code === "cleanup_pending" && response.error.cleanup !== undefined;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function lifecycleResponseState(response: BrokerResponse): LifecycleState {
|
|
156
|
+
if (response.ok) return "terminal_ok";
|
|
157
|
+
if (isCleanupPending(response)) return "effect_started";
|
|
158
|
+
return response.error.code === "terminal_uncertain" ? "terminal_uncertain" : "terminal_error";
|
|
159
|
+
}
|
|
160
|
+
|
|
70
161
|
type InputNormalization = { input: Record<string, unknown> } | BrokerResponse;
|
|
71
162
|
|
|
72
163
|
function isBrokerResponse(value: InputNormalization): value is BrokerResponse {
|
|
@@ -106,6 +197,8 @@ function normalizeBrokerInput(operation: string, input: Record<string, unknown>)
|
|
|
106
197
|
normalized.sourceSessionId = source.value;
|
|
107
198
|
delete normalized.sourceId;
|
|
108
199
|
}
|
|
200
|
+
if (input.directoryMigration !== undefined)
|
|
201
|
+
return error("invalid_input", "directoryMigration is broker-managed and cannot be selected by clients.");
|
|
109
202
|
|
|
110
203
|
if (operation === "session.list") {
|
|
111
204
|
const resolved = input.resolveSessionId;
|
|
@@ -272,7 +365,7 @@ type BrokerLockSnapshot = {
|
|
|
272
365
|
const terminalPersistenceHooksForTest = new WeakMap<Broker, () => void>();
|
|
273
366
|
|
|
274
367
|
export class Broker {
|
|
275
|
-
readonly settings:
|
|
368
|
+
readonly settings: ResolvedBrokerSettings;
|
|
276
369
|
readonly index: SessionIndex;
|
|
277
370
|
readonly ledger: LifecycleLedger;
|
|
278
371
|
discovery: BrokerDiscovery | null = null;
|
|
@@ -281,10 +374,16 @@ export class Broker {
|
|
|
281
374
|
#chains = new Map<string, Promise<void>>();
|
|
282
375
|
#stopping = false;
|
|
283
376
|
#transport: BrokerTransport | null = null;
|
|
284
|
-
#heartbeatTimer:
|
|
377
|
+
#heartbeatTimer: NodeJS.Timeout | null = null;
|
|
285
378
|
#heartbeatWrite: Promise<void> = Promise.resolve();
|
|
286
379
|
constructor(settings: BrokerSettings) {
|
|
287
|
-
this.settings = {
|
|
380
|
+
this.settings = {
|
|
381
|
+
agentDir: settings.agentDir,
|
|
382
|
+
packageGeneration: settings.packageGeneration ?? "unknown",
|
|
383
|
+
port: settings.port ?? 0,
|
|
384
|
+
heartbeatTtlMs: settings.heartbeatTtlMs ?? BROKER_HEARTBEAT_TTL_MS,
|
|
385
|
+
resolveDirectoryMigration: settings.resolveDirectoryMigration ?? (async () => "copy-retain"),
|
|
386
|
+
};
|
|
288
387
|
this.index = new SessionIndex(settings.agentDir);
|
|
289
388
|
this.ledger = new LifecycleLedger(settings.agentDir);
|
|
290
389
|
this.#lock = path.join(settings.agentDir, "sdk", "broker.lock");
|
|
@@ -379,13 +478,20 @@ export class Broker {
|
|
|
379
478
|
throw e;
|
|
380
479
|
}
|
|
381
480
|
}
|
|
481
|
+
async #releaseOwnedLock(): Promise<void> {
|
|
482
|
+
try {
|
|
483
|
+
const lock = await this.#readLock();
|
|
484
|
+
if (lock?.ownerId !== this.#owner) return;
|
|
485
|
+
await fs.unlink(this.#lockRecordPath());
|
|
486
|
+
await fs.rmdir(this.#lock);
|
|
487
|
+
} catch (error) {
|
|
488
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
382
492
|
async start(): Promise<BrokerDiscovery> {
|
|
383
493
|
this.#stopping = false;
|
|
384
|
-
await Promise.all([
|
|
385
|
-
this.index.assertSupportedStateVersions(),
|
|
386
|
-
this.ledger.assertSupportedStateVersions(),
|
|
387
|
-
readBrokerDiscovery(this.settings.agentDir),
|
|
388
|
-
]);
|
|
494
|
+
await Promise.all([this.ledger.assertSupportedStateVersions(), readBrokerDiscovery(this.settings.agentDir)]);
|
|
389
495
|
await fs.mkdir(path.dirname(this.#lock), { recursive: true, mode: 0o700 });
|
|
390
496
|
for (;;) {
|
|
391
497
|
try {
|
|
@@ -415,39 +521,47 @@ export class Broker {
|
|
|
415
521
|
}
|
|
416
522
|
await this.#reclaimStaleLock(snapshot);
|
|
417
523
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
524
|
+
try {
|
|
525
|
+
await this.index.open();
|
|
526
|
+
await this.ledger.open();
|
|
527
|
+
const now = Date.now();
|
|
528
|
+
const incarnation = brokerProcessIncarnation(process.pid);
|
|
529
|
+
if (!incarnation) throw new Error("Broker process incarnation is unavailable.");
|
|
530
|
+
const token = newBrokerToken();
|
|
531
|
+
this.#transport = new BrokerTransport(this, token, this.settings.port);
|
|
532
|
+
const port = await this.#transport.start();
|
|
533
|
+
this.discovery = {
|
|
534
|
+
version: 1,
|
|
535
|
+
protocolVersion: 3,
|
|
536
|
+
packageGeneration: this.settings.packageGeneration,
|
|
537
|
+
ownerId: this.#owner,
|
|
538
|
+
pid: process.pid,
|
|
539
|
+
incarnation,
|
|
540
|
+
host: "127.0.0.1",
|
|
541
|
+
port,
|
|
542
|
+
url: `ws://127.0.0.1:${port}`,
|
|
543
|
+
token,
|
|
544
|
+
startedAt: now,
|
|
545
|
+
heartbeatAt: now,
|
|
546
|
+
};
|
|
547
|
+
await writeBrokerDiscovery(this.settings.agentDir, this.discovery);
|
|
548
|
+
this.#heartbeatTimer = setInterval(
|
|
549
|
+
() => void this.heartbeat(),
|
|
550
|
+
Math.max(1, Math.floor(this.settings.heartbeatTtlMs / 3)),
|
|
551
|
+
);
|
|
552
|
+
return this.discovery;
|
|
553
|
+
} catch (error) {
|
|
554
|
+
await this.#transport?.stop();
|
|
555
|
+
this.#transport = null;
|
|
556
|
+
this.discovery = null;
|
|
557
|
+
await this.#releaseOwnedLock();
|
|
558
|
+
throw error;
|
|
559
|
+
}
|
|
446
560
|
}
|
|
447
561
|
get ownsDiscovery(): boolean {
|
|
448
562
|
return this.discovery?.ownerId === this.#owner;
|
|
449
563
|
}
|
|
450
|
-
status():
|
|
564
|
+
status(): RedactedBrokerDiscovery | null {
|
|
451
565
|
return this.discovery ? redactBrokerDiscovery(this.discovery) : null;
|
|
452
566
|
}
|
|
453
567
|
async heartbeat(): Promise<void> {
|
|
@@ -476,15 +590,7 @@ export class Broker {
|
|
|
476
590
|
} catch (e) {
|
|
477
591
|
if ((e as NodeJS.ErrnoException).code !== "ENOENT") throw e;
|
|
478
592
|
}
|
|
479
|
-
|
|
480
|
-
const lock = await this.#readLock();
|
|
481
|
-
if (lock?.ownerId === this.#owner) {
|
|
482
|
-
await fs.unlink(this.#lockRecordPath());
|
|
483
|
-
await fs.rmdir(this.#lock);
|
|
484
|
-
}
|
|
485
|
-
} catch (e) {
|
|
486
|
-
if ((e as NodeJS.ErrnoException).code !== "ENOENT") throw e;
|
|
487
|
-
}
|
|
593
|
+
await this.#releaseOwnedLock();
|
|
488
594
|
}
|
|
489
595
|
this.discovery = null;
|
|
490
596
|
}
|
|
@@ -543,15 +649,21 @@ export class Broker {
|
|
|
543
649
|
const resolveSessionId = typeof input.resolveSessionId === "string" ? input.resolveSessionId : undefined;
|
|
544
650
|
const cwd = typeof input.cwd === "string" ? input.cwd : undefined;
|
|
545
651
|
if (resolveSessionId && cwd) {
|
|
546
|
-
const
|
|
547
|
-
const
|
|
652
|
+
const scope = await resolveManagedSessionScope({ cwd, agentDir: this.settings.agentDir });
|
|
653
|
+
const listed =
|
|
654
|
+
scope.kind === "resolved" ? await listManagedSessionCandidates({ scope: scope.scope }) : undefined;
|
|
655
|
+
const matches =
|
|
656
|
+
listed?.kind === "complete"
|
|
657
|
+
? listed.owned.filter(candidate => candidate.sessionId === resolveSessionId)
|
|
658
|
+
: [];
|
|
659
|
+
const match = matches.length === 1 ? matches[0] : undefined;
|
|
548
660
|
return {
|
|
549
661
|
ok: true,
|
|
550
662
|
result: {
|
|
551
663
|
...result,
|
|
552
664
|
savedSession:
|
|
553
|
-
match && match.
|
|
554
|
-
? { id: match.
|
|
665
|
+
match && match.sessionId === resolveSessionId
|
|
666
|
+
? { id: match.sessionId, path: match.path }
|
|
555
667
|
: undefined,
|
|
556
668
|
},
|
|
557
669
|
indexSeq: result.indexSeq,
|
|
@@ -575,37 +687,53 @@ export class Broker {
|
|
|
575
687
|
);
|
|
576
688
|
await prev;
|
|
577
689
|
try {
|
|
690
|
+
const beforeBegin = this.ledger.get(identity);
|
|
578
691
|
const begun = await this.ledger.begin(identity, requestHash);
|
|
579
|
-
if (begun.kind === "replay")
|
|
692
|
+
if (begun.kind === "replay") {
|
|
693
|
+
const replay = begun.entry.response as BrokerResponse;
|
|
694
|
+
if (!(!replay.ok && replay.error.cleanup)) return replay;
|
|
695
|
+
const cleanup = replay.error.cleanup;
|
|
696
|
+
const outcome = await executeLifecycle(this, operation, input, identity, cleanup);
|
|
697
|
+
const response = outcome.response;
|
|
698
|
+
await this.ledger.transition(identity, lifecycleResponseState(response), {
|
|
699
|
+
response,
|
|
700
|
+
responseDigest: createHash("sha256").update(canonicalJson(response)).digest("hex"),
|
|
701
|
+
...(outcome.durableEffects ? { durableEffects: outcome.durableEffects } : {}),
|
|
702
|
+
...(outcome.startupFailure ? { startupFailure: outcome.startupFailure } : {}),
|
|
703
|
+
});
|
|
704
|
+
return response;
|
|
705
|
+
}
|
|
580
706
|
if (begun.kind === "idempotency_conflict")
|
|
581
707
|
return error("idempotency_conflict", "idempotency key was used with a different request");
|
|
582
|
-
if (begun.kind === "terminal_uncertain")
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
await this.ledger.transition(
|
|
590
|
-
identity,
|
|
591
|
-
response.ok
|
|
592
|
-
? "terminal_ok"
|
|
593
|
-
: response.error.code === "terminal_uncertain"
|
|
594
|
-
? "terminal_uncertain"
|
|
595
|
-
: "terminal_error",
|
|
596
|
-
{
|
|
597
|
-
resultSessionId:
|
|
598
|
-
response.ok && typeof (response.result as { sessionId?: unknown } | undefined)?.sessionId === "string"
|
|
599
|
-
? (response.result as { sessionId: string }).sessionId
|
|
600
|
-
: undefined,
|
|
708
|
+
if (begun.kind === "terminal_uncertain") {
|
|
709
|
+
const replay = (begun.entry.response ?? beforeBegin?.response) as BrokerResponse | undefined;
|
|
710
|
+
if (!replay || replay.ok || !replay.error.cleanup)
|
|
711
|
+
return replay ?? error("terminal_uncertain", "prior lifecycle operation outcome is uncertain");
|
|
712
|
+
const outcome = await executeLifecycle(this, operation, input, identity, replay.error.cleanup);
|
|
713
|
+
const response = outcome.response;
|
|
714
|
+
await this.ledger.transition(identity, lifecycleResponseState(response), {
|
|
601
715
|
response,
|
|
602
716
|
responseDigest: createHash("sha256").update(canonicalJson(response)).digest("hex"),
|
|
603
717
|
...(outcome.durableEffects ? { durableEffects: outcome.durableEffects } : {}),
|
|
604
718
|
...(outcome.startupFailure ? { startupFailure: outcome.startupFailure } : {}),
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
719
|
+
});
|
|
720
|
+
return response;
|
|
721
|
+
}
|
|
722
|
+
if (begun.kind === "in_progress") return error("broker_restarting", "lifecycle operation is in progress");
|
|
723
|
+
const outcome = await executeLifecycle(this, operation, input, identity);
|
|
724
|
+
const response = outcome.response;
|
|
725
|
+
await this.ledger.transition(identity, lifecycleResponseState(response), {
|
|
726
|
+
resultSessionId:
|
|
727
|
+
response.ok && typeof (response.result as { sessionId?: unknown } | undefined)?.sessionId === "string"
|
|
728
|
+
? (response.result as { sessionId: string }).sessionId
|
|
729
|
+
: undefined,
|
|
730
|
+
response,
|
|
731
|
+
responseDigest: createHash("sha256").update(canonicalJson(response)).digest("hex"),
|
|
732
|
+
...(outcome.durableEffects ? { durableEffects: outcome.durableEffects } : {}),
|
|
733
|
+
...(outcome.startupFailure ? { startupFailure: outcome.startupFailure } : {}),
|
|
734
|
+
});
|
|
735
|
+
if (isCleanupPending(response)) return response;
|
|
736
|
+
const persisted = await this.ledger.readTerminal(identity, requestHash);
|
|
609
737
|
const expectedResponseDigest = createHash("sha256").update(canonicalJson(response)).digest("hex");
|
|
610
738
|
const persistenceVerified =
|
|
611
739
|
persisted?.responseDigest === expectedResponseDigest &&
|
package/src/sdk/broker/ensure.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface EnsureBrokerSettings {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
const DISCOVERY_TIMEOUT_MS = 10_000;
|
|
16
|
+
const FIXTURE_DISCOVERY_TIMEOUT_MS = 30_000;
|
|
16
17
|
// Bounded grace windows for reaping a spawned broker on failure, mirroring the
|
|
17
18
|
// owned-process teardown convention (SIGTERM -> grace -> SIGKILL -> hard cap).
|
|
18
19
|
const REAP_GRACEFUL_MS = 2_000;
|
|
@@ -215,7 +216,8 @@ async function ensureBrokerOnce(settings: EnsureBrokerSettings, initiator: Ensur
|
|
|
215
216
|
spawnError = error;
|
|
216
217
|
});
|
|
217
218
|
const owner = registerBrokerOwner(settings.agentDir, child);
|
|
218
|
-
const
|
|
219
|
+
const discoveryTimeoutMs = initiator === "fixture-lease" ? FIXTURE_DISCOVERY_TIMEOUT_MS : DISCOVERY_TIMEOUT_MS;
|
|
220
|
+
const deadline = Date.now() + discoveryTimeoutMs;
|
|
219
221
|
let discoveryError: unknown;
|
|
220
222
|
while (Date.now() < deadline) {
|
|
221
223
|
if (spawnError || child.exitCode !== null || child.signalCode !== null) break;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const lifecycleUtf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
2
|
+
|
|
3
|
+
/** Decodes persisted lifecycle bytes without replacement characters before JSON parsing. */
|
|
4
|
+
export function decodeLifecycleUtf8(bytes: Uint8Array): string {
|
|
5
|
+
return lifecycleUtf8Decoder.decode(bytes);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Parses persisted lifecycle JSON only after fatal UTF-8 decoding. */
|
|
9
|
+
export function parseLifecycleJson(bytes: Uint8Array): unknown {
|
|
10
|
+
return JSON.parse(decodeLifecycleUtf8(bytes));
|
|
11
|
+
}
|