@gajae-code/coding-agent 0.18.11 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +760 -0
- package/dist/types/async/job-manager.d.ts +7 -3
- package/dist/types/async/result-formatting.d.ts +2 -0
- package/dist/types/autoresearch/git.d.ts +1 -1
- package/dist/types/capability/fs.d.ts +2 -2
- package/dist/types/capability/rule.d.ts +7 -2
- package/dist/types/cli/accounts-cli.d.ts +2 -2
- package/dist/types/cli/append-system-prompt.d.ts +6 -0
- package/dist/types/cli/args.d.ts +7 -2
- package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
- package/dist/types/cli/customize-doctor.d.ts +4 -3
- package/dist/types/cli/doctor/install-repairs.d.ts +4 -1
- package/dist/types/cli/install-activation.d.ts +10 -4
- package/dist/types/cli/public-command-errors.d.ts +2 -0
- package/dist/types/cli/root-flags.d.ts +0 -12
- package/dist/types/cli/update-cli.d.ts +21 -3
- package/dist/types/cli-main.d.ts +0 -6
- package/dist/types/cli-ordinary.d.ts +2 -2
- package/dist/types/commands/accounts.d.ts +2 -1
- package/dist/types/commands/launch.d.ts +0 -6
- package/dist/types/commands/migrate.d.ts +1 -1
- package/dist/types/commands/sdk.d.ts +13 -0
- package/dist/types/commit/changelog/index.d.ts +1 -0
- package/dist/types/commit/map-reduce/index.d.ts +4 -4
- package/dist/types/config/autorouting-tier-map.d.ts +53 -1
- package/dist/types/config/config-hot-reload-trust.d.ts +12 -0
- package/dist/types/config/config-hot-reload.d.ts +44 -0
- package/dist/types/config/file-lock.d.ts +52 -3
- package/dist/types/config/model-discovery-manager.d.ts +2 -0
- package/dist/types/config/model-profile-activation.d.ts +79 -9
- package/dist/types/config/model-registry.d.ts +72 -8
- package/dist/types/config/model-resolver.d.ts +7 -4
- package/dist/types/config/models-config-schema.d.ts +10 -0
- package/dist/types/config/settings-schema.d.ts +57 -4
- package/dist/types/config/settings.d.ts +33 -1
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/customization/import.d.ts +2 -0
- package/dist/types/customization/types.d.ts +1 -1
- package/dist/types/dap/config.d.ts +8 -4
- package/dist/types/dap/session.d.ts +11 -2
- package/dist/types/debug/system-info.d.ts +6 -1
- package/dist/types/discovery/helpers.d.ts +7 -2
- package/dist/types/discovery/mcp-compat.d.ts +3 -1
- package/dist/types/edit/index.d.ts +5 -0
- package/dist/types/edit/modes/patch.d.ts +14 -0
- package/dist/types/edit/modes/replace.d.ts +3 -0
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +12 -0
- package/dist/types/export/ttsr.d.ts +19 -0
- package/dist/types/extensibility/extensions/types.d.ts +5 -1
- package/dist/types/extensibility/slash-commands.d.ts +1 -0
- package/dist/types/gjc-runtime/managed-owner-admission.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +0 -2
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/content.d.ts +5 -6
- package/dist/types/internal-urls/types.d.ts +2 -0
- package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
- package/dist/types/main.d.ts +23 -18
- package/dist/types/migrate/action-planner.d.ts +10 -1
- package/dist/types/migrate/adapters/codex.d.ts +2 -1
- package/dist/types/migrate/adapters/index.d.ts +42 -1
- package/dist/types/migrate/executor.d.ts +3 -1
- package/dist/types/migrate/hook-module.d.ts +23 -0
- package/dist/types/migrate/report.d.ts +2 -1
- package/dist/types/migrate/types.d.ts +82 -3
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +43 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -0
- package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/utils/host-status.d.ts +15 -11
- package/dist/types/runtime-mcp/content-limits.d.ts +4 -0
- package/dist/types/runtime-mcp/manager.d.ts +7 -0
- package/dist/types/runtime-mcp/plugin-mcp-name-filter.d.ts +22 -0
- package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
- package/dist/types/runtime-mcp/tool-bridge.d.ts +4 -0
- package/dist/types/sdk/broker/broker-exit.d.ts +3 -3
- package/dist/types/sdk/broker/broker.d.ts +29 -2
- package/dist/types/sdk/broker/daemon-entry.d.ts +11 -1
- package/dist/types/sdk/broker/doctor-restart.d.ts +1 -1
- package/dist/types/sdk/broker/ensure.d.ts +141 -9
- package/dist/types/sdk/broker/hop.d.ts +45 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +18 -10
- package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
- package/dist/types/sdk/broker/lock-host-identity.d.ts +5 -0
- package/dist/types/sdk/broker/session-index.d.ts +6 -1
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +44 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
- package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
- package/dist/types/sdk/cli/session-cli.d.ts +0 -1
- package/dist/types/sdk/host/control/operations.d.ts +5 -1
- package/dist/types/sdk/host/events.d.ts +4 -0
- package/dist/types/sdk/host/host.d.ts +2 -1
- package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
- package/dist/types/sdk/host/session-runtime.d.ts +40 -8
- package/dist/types/sdk/host/surface-policy.d.ts +2 -1
- package/dist/types/sdk/lifecycle/service.d.ts +12 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +42 -4
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -0
- package/dist/types/sdk/prompt-status.d.ts +11 -4
- package/dist/types/sdk/protocol/adapter-validation.d.ts +10 -4
- package/dist/types/sdk/reconciliation-extensions.d.ts +1 -1
- package/dist/types/sdk/session-list.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +107 -9
- package/dist/types/session/internal/managed-session-scope.d.ts +2 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +1 -1
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -1
- package/dist/types/session/messages.d.ts +5 -1
- package/dist/types/session/session-manager.d.ts +29 -3
- package/dist/types/session/startup-auth-config.d.ts +24 -2
- package/dist/types/session/streaming-output.d.ts +11 -0
- package/dist/types/session/terminal-abort.d.ts +3 -1
- package/dist/types/session-import/service.d.ts +1 -1
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +20 -4
- package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
- package/dist/types/slash-commands/helpers/provider-auth-status.d.ts +8 -0
- package/dist/types/ssh/ssh-executor.d.ts +8 -1
- package/dist/types/system-prompt.d.ts +3 -2
- package/dist/types/task/executor.d.ts +19 -2
- package/dist/types/task/role-body.d.ts +11 -0
- package/dist/types/tools/ast-edit-write-path.d.ts +10 -0
- package/dist/types/tools/atomic-file-write.d.ts +9 -7
- package/dist/types/tools/awaiting-input.d.ts +28 -0
- package/dist/types/tools/bash-allowed-prefixes.d.ts +17 -0
- package/dist/types/tools/bash-skill-urls.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +7 -0
- package/dist/types/tools/descriptors.d.ts +15 -2
- package/dist/types/tools/fetch.d.ts +7 -1
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/irc.d.ts +5 -3
- package/dist/types/tools/python.d.ts +1 -1
- package/dist/types/tools/report-issue.d.ts +41 -0
- package/dist/types/tools/subagent.d.ts +23 -0
- package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/utils/file-mentions.d.ts +5 -0
- package/dist/types/utils/image-limits.d.ts +7 -0
- package/dist/types/utils/image-loading.d.ts +0 -1
- package/dist/types/utils/open.d.ts +0 -1
- package/dist/types/utils/pasted-image-loading.d.ts +1 -5
- package/dist/types/utils/prompt-suggestion.d.ts +2 -2
- package/dist/types/utils/shell-snapshot.d.ts +2 -0
- package/dist/types/utils/title-generator.d.ts +13 -3
- package/dist/types/web/scrapers/types.d.ts +8 -1
- package/dist/types/web/search/providers/codex.d.ts +6 -7
- package/dist/types/web/search/providers/insane.d.ts +7 -1
- package/dist/types/web/search/providers/searxng.d.ts +5 -0
- package/package.json +10 -9
- package/scripts/acp-conformance-agent.ts +12 -2
- package/scripts/build-binary.ts +2 -1
- package/scripts/capture-subagent-compact-panel-showcase.ts +105 -0
- package/scripts/generate-docs-index.ts +8 -1
- package/scripts/generate-sdk-operation-inventory.ts +38 -4
- package/src/async/job-manager.ts +356 -56
- package/src/async/result-formatting.ts +40 -0
- package/src/autoresearch/git.ts +9 -2
- package/src/autoresearch/prompts/prompt-setup.md +1 -1
- package/src/capability/fs.ts +58 -22
- package/src/capability/index.ts +2 -2
- package/src/capability/rule.ts +11 -2
- package/src/cli/accounts-cli.ts +176 -8
- package/src/cli/append-system-prompt.ts +12 -0
- package/src/cli/args.ts +11 -7
- package/src/cli/auth-broker-cli.ts +21 -11
- package/src/cli/customize-doctor-precedence.ts +31 -0
- package/src/cli/customize-doctor.ts +49 -39
- package/src/cli/doctor/install-repairs.ts +35 -5
- package/src/cli/fast-help.ts +1 -3
- package/src/cli/install-activation.ts +47 -4
- package/src/cli/migrate-cli.ts +19 -6
- package/src/cli/public-command-errors.ts +6 -0
- package/src/cli/root-flags.ts +2 -4
- package/src/cli/stats-cli.ts +9 -5
- package/src/cli/update-cli.ts +471 -13
- package/src/cli-ordinary.ts +7 -2
- package/src/commands/accounts.ts +10 -5
- package/src/commands/harness.ts +25 -15
- package/src/commands/migrate.ts +3 -3
- package/src/commands/sdk.ts +277 -50
- package/src/commands/ultragoal.ts +16 -8
- package/src/commit/agentic/agent.ts +6 -6
- package/src/commit/analysis/conventional.ts +14 -5
- package/src/commit/changelog/index.ts +39 -1
- package/src/commit/map-reduce/index.ts +7 -7
- package/src/commit/message.ts +10 -3
- package/src/commit/pipeline.ts +12 -12
- package/src/config/autorouting-tier-map.ts +50 -1
- package/src/config/config-file.ts +106 -3
- package/src/config/config-hot-reload-trust.ts +148 -0
- package/src/config/config-hot-reload.ts +742 -0
- package/src/config/file-lock.ts +1615 -328
- package/src/config/keybindings.ts +154 -7
- package/src/config/model-bindings-applier.ts +85 -47
- package/src/config/model-discovery-manager.ts +10 -0
- package/src/config/model-profile-activation.ts +889 -148
- package/src/config/model-registry.ts +1706 -205
- package/src/config/model-resolver.ts +52 -22
- package/src/config/models-config-schema.ts +6 -0
- package/src/config/settings-schema.ts +73 -4
- package/src/config/settings.ts +460 -24
- package/src/coordinator-mcp/policy.ts +26 -1
- package/src/coordinator-mcp/server.ts +37 -2
- package/src/crash/sanitize.ts +7 -1
- package/src/customization/import.ts +279 -8
- package/src/customization/inventory.ts +24 -8
- package/src/customization/types.ts +1 -0
- package/src/dap/client.ts +3 -2
- package/src/dap/config.ts +31 -11
- package/src/dap/defaults.json +1 -1
- package/src/dap/session.ts +161 -36
- package/src/debug/crash-diagnostics.ts +89 -6
- package/src/debug/report-bundle.ts +90 -2
- package/src/debug/system-info.ts +8 -3
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +21 -7
- package/src/discovery/agents-md.ts +1 -1
- package/src/discovery/builtin.ts +4 -3
- package/src/discovery/helpers.ts +25 -16
- package/src/discovery/mcp-compat.ts +120 -17
- package/src/edit/apply-patch/index.ts +12 -1
- package/src/edit/index.ts +204 -22
- package/src/edit/modes/patch.ts +214 -8
- package/src/edit/modes/replace.ts +136 -0
- package/src/eval/js/context-manager.ts +29 -3
- package/src/eval/js/worker-entry.ts +51 -18
- package/src/eval/py/executor.ts +14 -4
- package/src/eval/py/runner.py +144 -5
- package/src/eval/py/runtime.ts +44 -4
- package/src/exec/bash-executor.ts +81 -4
- package/src/exec/bash-shell-guardian.ts +4 -1
- package/src/exec/bash-shell-supervisor.ts +8 -4
- package/src/exec/isolated-shell.ts +5 -1
- package/src/exec/non-interactive-env.ts +0 -1
- package/src/export/html/index.ts +86 -6
- package/src/export/ttsr.ts +176 -1
- package/src/extensibility/custom-tools/wrapper.ts +3 -1
- package/src/extensibility/extensions/loader.ts +10 -1
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
- package/src/extensibility/extensions/types.ts +5 -1
- package/src/extensibility/hooks/loader.ts +10 -2
- package/src/extensibility/plugins/marketplace/fetcher.ts +2 -2
- package/src/extensibility/plugins/marketplace/manager.ts +36 -10
- package/src/extensibility/slash-commands.ts +5 -0
- package/src/gjc-runtime/gc-runtime.ts +37 -7
- package/src/gjc-runtime/launch-tmux.ts +30 -15
- package/src/gjc-runtime/launch-worktree.test.ts +148 -0
- package/src/gjc-runtime/launch-worktree.ts +101 -14
- package/src/gjc-runtime/managed-owner-admission.ts +46 -2
- package/src/gjc-runtime/ralplan-current-final.ts +294 -0
- package/src/gjc-runtime/ralplan-runtime.ts +95 -1
- package/src/gjc-runtime/session-resolution.ts +38 -6
- package/src/gjc-runtime/session-state-lock.ts +59 -14
- package/src/gjc-runtime/state-runtime.ts +23 -19
- package/src/gjc-runtime/state-writer.ts +109 -5
- package/src/gjc-runtime/tmux-sessions.ts +93 -13
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
- package/src/gjc-runtime/ultragoal-guard.ts +9 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
- package/src/harness-control-plane/finalize.ts +11 -0
- package/src/harness-control-plane/receipt-spool.ts +105 -28
- package/src/harness-control-plane/storage.ts +124 -6
- package/src/hindsight/content.ts +116 -16
- package/src/hindsight/mental-models.ts +22 -10
- package/src/hindsight/state.ts +7 -4
- package/src/hooks/native-skill-hook.ts +17 -12
- package/src/internal-urls/artifact-protocol.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +23 -22
- package/src/internal-urls/local-protocol.ts +167 -8
- package/src/internal-urls/types.ts +2 -0
- package/src/lsp/client.ts +2 -1
- package/src/lsp/clients/biome-client.ts +2 -0
- package/src/lsp/clients/swiftlint-client.ts +2 -0
- package/src/lsp/index.ts +29 -0
- package/src/lsp/workspace-path.ts +23 -0
- package/src/main.ts +330 -92
- package/src/memories/index.ts +25 -2
- package/src/migrate/action-planner.ts +574 -2
- package/src/migrate/adapters/claude-code.ts +162 -5
- package/src/migrate/adapters/codex.ts +77 -7
- package/src/migrate/adapters/index.ts +258 -5
- package/src/migrate/adapters/opencode.ts +10 -1
- package/src/migrate/executor.ts +222 -7
- package/src/migrate/hook-module.ts +193 -0
- package/src/migrate/report.ts +63 -2
- package/src/migrate/types.ts +84 -4
- package/src/modes/DESIGN.md +51 -0
- package/src/modes/acp/acp-agent.ts +10 -1
- package/src/modes/acp/permission-mode.ts +18 -1
- package/src/modes/components/agent-dashboard.ts +20 -4
- package/src/modes/components/assistant-message.ts +55 -1
- package/src/modes/components/customization/customization-dashboard.ts +7 -0
- package/src/modes/components/customization/import-wizard.ts +29 -3
- package/src/modes/components/model-selector.ts +157 -103
- package/src/modes/components/settings-selector.ts +103 -37
- package/src/modes/components/welcome.ts +3 -1
- package/src/modes/controllers/command-controller.ts +300 -9
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/extension-ui-controller.ts +31 -1
- package/src/modes/controllers/goal-mode-controller.ts +79 -10
- package/src/modes/controllers/input-controller.ts +2 -0
- package/src/modes/controllers/plan-mode-controller.ts +66 -11
- package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
- package/src/modes/controllers/selector-controller.ts +76 -7
- package/src/modes/interactive-mode.ts +123 -4
- package/src/modes/prompt-suggestion-controller.ts +1 -1
- package/src/modes/runtime-init.ts +5 -1
- package/src/modes/theme/theme.ts +15 -0
- package/src/modes/utils/host-status.ts +21 -10
- package/src/prompts/agent-fragments/browser-aside.md +2 -2
- package/src/prompts/system/irc-incoming.md +3 -1
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/irc.md +1 -1
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/report-issue.md +13 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-credential-selector.ts +2 -2
- package/src/runtime-mcp/content-limits.ts +7 -0
- package/src/runtime-mcp/manager-pool.test.ts +5 -4
- package/src/runtime-mcp/manager.ts +40 -3
- package/src/runtime-mcp/oauth-flow.ts +32 -6
- package/src/runtime-mcp/plugin-mcp-name-filter.ts +62 -0
- package/src/runtime-mcp/project-host-values.ts +12 -8
- package/src/runtime-mcp/render.ts +16 -1
- package/src/runtime-mcp/tool-bridge.ts +194 -21
- package/src/runtime-mcp/transports/stdio.ts +2 -1
- package/src/sdk/broker/broker-exit.ts +10 -5
- package/src/sdk/broker/broker.ts +484 -85
- package/src/sdk/broker/daemon-entry.ts +338 -116
- package/src/sdk/broker/doctor-restart.ts +2 -1
- package/src/sdk/broker/ensure.ts +1214 -268
- package/src/sdk/broker/hop.ts +286 -0
- package/src/sdk/broker/lifecycle-ledger.ts +38 -11
- package/src/sdk/broker/lifecycle.ts +102 -6
- package/src/sdk/broker/lock-host-identity.ts +29 -0
- package/src/sdk/broker/session-index.ts +91 -16
- package/src/sdk/broker/transport.ts +17 -1
- package/src/sdk/bus/chat-command-policy.ts +16 -3
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/index.ts +460 -35
- package/src/sdk/bus/reconciliation-store.ts +201 -8
- package/src/sdk/bus/session-control.ts +2 -0
- package/src/sdk/bus/slack-daemon.ts +105 -9
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -2
- package/src/sdk/bus/threaded-render.ts +20 -1
- package/src/sdk/cli/session-cli.ts +23 -6
- package/src/sdk/host/control/dispatch.ts +13 -1
- package/src/sdk/host/control/operations.ts +10 -1
- package/src/sdk/host/events.ts +67 -4
- package/src/sdk/host/host.ts +8 -2
- package/src/sdk/host/prompt-image-upload.ts +438 -0
- package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
- package/src/sdk/host/session-runtime.test.ts +1737 -129
- package/src/sdk/host/session-runtime.ts +684 -83
- package/src/sdk/host/surface-policy.ts +4 -0
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
- package/src/sdk/host/websocket-transport.ts +19 -7
- package/src/sdk/lifecycle/service.ts +15 -1
- package/src/sdk/prompt-deadline-flush.ts +78 -5
- package/src/sdk/prompt-deadline-manager.ts +68 -14
- package/src/sdk/prompt-status.ts +6 -4
- package/src/sdk/protocol/adapter-validation.ts +81 -12
- package/src/sdk/protocol/operation-inventory.generated.json +261 -2
- package/src/sdk/protocol/operation-registry.ts +33 -3
- package/src/sdk/reconciliation-extensions.ts +1 -0
- package/src/sdk/session-list.ts +1 -0
- package/src/sdk/session.ts +237 -97
- package/src/session/agent-session.ts +2726 -479
- package/src/session/history-storage.ts +182 -12
- package/src/session/internal/managed-session-scope.ts +173 -57
- package/src/session/internal/managed-session-storage.ts +85 -12
- package/src/session/internal/native-publish-outcome.ts +5 -1
- package/src/session/messages.ts +47 -6
- package/src/session/session-manager.ts +326 -19
- package/src/session/startup-auth-config.ts +116 -8
- package/src/session/streaming-output.ts +262 -4
- package/src/session/terminal-abort.ts +14 -2
- package/src/session-import/redact.ts +53 -2
- package/src/session-import/service.ts +1 -0
- package/src/skill-state/workflow-mutation-guard.ts +2145 -206
- package/src/slash-commands/builtin-registry.ts +21 -6
- package/src/slash-commands/helpers/credential-switch.ts +10 -5
- package/src/slash-commands/helpers/mcp.ts +11 -3
- package/src/slash-commands/helpers/provider-auth-status.ts +456 -0
- package/src/ssh/ssh-executor.ts +9 -2
- package/src/stt/recorder.ts +26 -9
- package/src/system-prompt.ts +61 -16
- package/src/task/executor.ts +115 -20
- package/src/task/index.ts +389 -175
- package/src/task/role-body.ts +84 -0
- package/src/task/token-log-mode.test.ts +162 -0
- package/src/task/token-log.ts +91 -2
- package/src/tools/archive-reader.ts +650 -37
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-edit-write-path.ts +64 -0
- package/src/tools/ast-edit.ts +18 -1
- package/src/tools/ast-grep.ts +7 -2
- package/src/tools/atomic-file-write.ts +46 -15
- package/src/tools/auto-generated-guard.ts +15 -3
- package/src/tools/awaiting-input.ts +114 -0
- package/src/tools/bash-allowed-prefixes.ts +214 -6
- package/src/tools/bash-interactive.ts +14 -2
- package/src/tools/bash-skill-urls.ts +58 -5
- package/src/tools/bash.ts +113 -26
- package/src/tools/browser/tab-worker.ts +39 -13
- package/src/tools/browser.ts +17 -7
- package/src/tools/cron.ts +10 -1
- package/src/tools/debug.ts +16 -8
- package/src/tools/descriptors.test.ts +44 -0
- package/src/tools/descriptors.ts +50 -6
- package/src/tools/eval.ts +15 -0
- package/src/tools/fetch.ts +93 -4
- package/src/tools/gh.ts +27 -12
- package/src/tools/image-gen.ts +20 -6
- package/src/tools/index.ts +2 -0
- package/src/tools/irc.ts +5 -3
- package/src/tools/monitor.ts +9 -1
- package/src/tools/output-meta.ts +74 -5
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +26 -37
- package/src/tools/recipe/runner.ts +23 -12
- package/src/tools/render-utils.ts +2 -2
- package/src/tools/report-issue.ts +184 -0
- package/src/tools/search.ts +3 -2
- package/src/tools/ssh.ts +274 -8
- package/src/tools/subagent-render.ts +114 -12
- package/src/tools/subagent.ts +118 -5
- package/src/tools/tmux-self-injection-guard.ts +3301 -122
- package/src/tools/todo-write.ts +41 -3
- package/src/tools/tool-catalog.generated.ts +32 -4
- package/src/tools/ultragoal-ask-guard.ts +13 -1
- package/src/tools/write.ts +42 -3
- package/src/tui/tree-list.ts +15 -1
- package/src/utils/commit-message-generator.ts +12 -4
- package/src/utils/external-editor.ts +21 -7
- package/src/utils/file-mentions.ts +75 -7
- package/src/utils/git.ts +38 -7
- package/src/utils/image-limits.ts +8 -0
- package/src/utils/image-loading.ts +1 -1
- package/src/utils/open.ts +73 -4
- package/src/utils/pasted-image-loading.ts +9 -8
- package/src/utils/prompt-suggestion.ts +5 -4
- package/src/utils/shell-snapshot.ts +9 -1
- package/src/utils/title-generator.ts +72 -22
- package/src/web/scrapers/index.ts +3 -1
- package/src/web/scrapers/types.ts +8 -0
- package/src/web/scrapers/youtube.ts +3 -2
- package/src/web/search/index.ts +2 -1
- package/src/web/search/providers/codex.ts +29 -32
- package/src/web/search/providers/insane.ts +91 -28
- package/src/web/search/providers/searxng.ts +62 -10
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import type * as childProcess from "node:child_process";
|
|
2
|
+
import { FileLockAcquireError } from "../../config/file-lock";
|
|
3
|
+
import {
|
|
4
|
+
type BrokerDiscovery,
|
|
5
|
+
type BrokerRestartIntentWithIdentity,
|
|
6
|
+
brokerProcessIncarnation,
|
|
7
|
+
readBrokerDiscovery,
|
|
8
|
+
readBrokerRestartIntent,
|
|
9
|
+
} from "./discovery";
|
|
10
|
+
import {
|
|
11
|
+
type BrokerLaunchHandoff,
|
|
12
|
+
type BrokerLaunchResult,
|
|
13
|
+
launchBrokerViaHop,
|
|
14
|
+
launchBrokerViaPosixTrampoline,
|
|
15
|
+
reapFailedBrokerLaunch,
|
|
16
|
+
resolveBrokerLaunchMode,
|
|
17
|
+
withBrokerStartupLock,
|
|
18
|
+
} from "./ensure";
|
|
19
|
+
import { observeProcessIncarnation } from "./process-incarnation";
|
|
5
20
|
import { resolveSdkInternalSpawnCommand } from "./runtime";
|
|
6
21
|
|
|
7
22
|
export interface AuthorizedBrokerSuccessorOptions {
|
|
@@ -14,7 +29,14 @@ export interface AuthorizedBrokerSuccessorOptions {
|
|
|
14
29
|
/** Typed outcome of a successor-launch attempt; never an opaque thrown message. */
|
|
15
30
|
export type AuthorizedBrokerSuccessorResult =
|
|
16
31
|
| { kind: "adopted"; discovery: BrokerDiscovery }
|
|
17
|
-
| {
|
|
32
|
+
| {
|
|
33
|
+
kind: "spawned";
|
|
34
|
+
child: childProcess.ChildProcess;
|
|
35
|
+
realBrokerPid: number | undefined;
|
|
36
|
+
realBrokerIncarnation: string | undefined;
|
|
37
|
+
handoff: BrokerLaunchHandoff | undefined;
|
|
38
|
+
discovery: BrokerDiscovery;
|
|
39
|
+
}
|
|
18
40
|
| {
|
|
19
41
|
kind: "refused";
|
|
20
42
|
reason:
|
|
@@ -22,12 +44,74 @@ export type AuthorizedBrokerSuccessorResult =
|
|
|
22
44
|
| "intent_not_committed"
|
|
23
45
|
| "spawn_failed"
|
|
24
46
|
| "spawn_exited_before_publication"
|
|
25
|
-
| "publication_timeout"
|
|
47
|
+
| "publication_timeout"
|
|
48
|
+
| "startup_lock_unavailable";
|
|
26
49
|
detail?: string;
|
|
27
50
|
};
|
|
28
51
|
|
|
52
|
+
type BrokerSuccessorSpawnOutcome =
|
|
53
|
+
| Exclude<AuthorizedBrokerSuccessorResult, { kind: "spawned" }>
|
|
54
|
+
| { kind: "retry" }
|
|
55
|
+
| {
|
|
56
|
+
kind: "spawned";
|
|
57
|
+
child: childProcess.ChildProcess;
|
|
58
|
+
realBrokerPid: number | undefined;
|
|
59
|
+
realBrokerIncarnation: string | undefined;
|
|
60
|
+
handoff: BrokerLaunchHandoff | undefined;
|
|
61
|
+
};
|
|
62
|
+
|
|
29
63
|
const SUCCESSOR_SPAWN_POLL_MS = 25;
|
|
30
64
|
|
|
65
|
+
class BrokerSuccessorDeadlineError extends Error {}
|
|
66
|
+
|
|
67
|
+
async function readBeforeBrokerDeadline<T>(read: Promise<T>, deadlineAt: number, message: string): Promise<T> {
|
|
68
|
+
const remainingMs = deadlineAt - Date.now();
|
|
69
|
+
if (remainingMs <= 0) throw new BrokerSuccessorDeadlineError(message);
|
|
70
|
+
const timeout = Promise.withResolvers<T>();
|
|
71
|
+
const timer = setTimeout(() => timeout.reject(new BrokerSuccessorDeadlineError(message)), remainingMs);
|
|
72
|
+
try {
|
|
73
|
+
return await Promise.race([read, timeout.promise]);
|
|
74
|
+
} finally {
|
|
75
|
+
clearTimeout(timer);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function refuseFailedBrokerLaunch(
|
|
80
|
+
launched: BrokerLaunchResult,
|
|
81
|
+
): Promise<Extract<AuthorizedBrokerSuccessorResult, { kind: "refused" }>> {
|
|
82
|
+
const child: childProcess.ChildProcess = launched.process;
|
|
83
|
+
if (!launched.handoff) child.unref();
|
|
84
|
+
let detail = launched.error?.message ?? "Broker launch failed.";
|
|
85
|
+
try {
|
|
86
|
+
await reapFailedBrokerLaunch(launched);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const cleanupDetail = error instanceof Error ? error.message : String(error);
|
|
89
|
+
detail = `${detail}; retry cleanup failed: ${cleanupDetail}`;
|
|
90
|
+
}
|
|
91
|
+
return { kind: "refused", reason: "spawn_failed", detail };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function refuseUnpublishedBrokerSuccessor(
|
|
95
|
+
child: childProcess.ChildProcess,
|
|
96
|
+
realBrokerPid: number | undefined,
|
|
97
|
+
realBrokerIncarnation: string | undefined,
|
|
98
|
+
handoff: BrokerLaunchResult["handoff"],
|
|
99
|
+
reason: "spawn_exited_before_publication" | "publication_timeout",
|
|
100
|
+
): Promise<Extract<AuthorizedBrokerSuccessorResult, { kind: "refused" }>> {
|
|
101
|
+
let detail: string | undefined;
|
|
102
|
+
try {
|
|
103
|
+
await reapFailedBrokerLaunch({
|
|
104
|
+
process: child,
|
|
105
|
+
realBrokerPid,
|
|
106
|
+
realBrokerIncarnation,
|
|
107
|
+
handoff,
|
|
108
|
+
});
|
|
109
|
+
} catch (error) {
|
|
110
|
+
detail = `Broker successor cleanup failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
111
|
+
}
|
|
112
|
+
return { kind: "refused", reason, ...(detail === undefined ? {} : { detail }) };
|
|
113
|
+
}
|
|
114
|
+
|
|
31
115
|
/**
|
|
32
116
|
* Launches (or adopts) exactly one authorized successor for `requestId`.
|
|
33
117
|
*
|
|
@@ -43,132 +127,270 @@ const SUCCESSOR_SPAWN_POLL_MS = 25;
|
|
|
43
127
|
export async function launchAuthorizedBrokerSuccessor(
|
|
44
128
|
options: AuthorizedBrokerSuccessorOptions,
|
|
45
129
|
): Promise<AuthorizedBrokerSuccessorResult> {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const intent = await readBrokerRestartIntent(options.agentDir);
|
|
55
|
-
if (intent?.phase !== "committed" || intent.requestId !== options.requestId)
|
|
56
|
-
return { kind: "refused" as const, reason: "intent_not_committed" as const };
|
|
57
|
-
const existing = await readBrokerDiscovery(options.agentDir);
|
|
58
|
-
if (
|
|
59
|
-
existing &&
|
|
60
|
-
existing.packageGeneration === options.packageGeneration &&
|
|
61
|
-
existing.restartRequestId === options.requestId
|
|
62
|
-
)
|
|
63
|
-
return { kind: "adopted" as const, discovery: existing };
|
|
64
|
-
const command = resolveSdkInternalSpawnCommand(
|
|
65
|
-
process.platform === "win32" ? "broker-internal" : "broker-trampoline-internal",
|
|
66
|
-
);
|
|
67
|
-
let child: ChildProcess;
|
|
68
|
-
const isTrampoline = process.platform !== "win32";
|
|
130
|
+
let spawnOutcome: BrokerSuccessorSpawnOutcome;
|
|
131
|
+
let successorDeadlineAt = options.deadlineAt;
|
|
132
|
+
let startupLockFailure: FileLockAcquireError | undefined;
|
|
133
|
+
for (;;) {
|
|
134
|
+
if (Date.now() >= successorDeadlineAt)
|
|
135
|
+
return startupLockFailure
|
|
136
|
+
? { kind: "refused", reason: "startup_lock_unavailable", detail: startupLockFailure.message }
|
|
137
|
+
: { kind: "refused", reason: "deadline_elapsed" };
|
|
69
138
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
139
|
+
spawnOutcome = await withBrokerStartupLock(
|
|
140
|
+
options.agentDir,
|
|
141
|
+
async deadline => {
|
|
142
|
+
const operationDeadlineAt = Math.min(deadline, successorDeadlineAt);
|
|
143
|
+
const deadlineOutcome = (): BrokerSuccessorSpawnOutcome =>
|
|
144
|
+
operationDeadlineAt < successorDeadlineAt && Date.now() < successorDeadlineAt
|
|
145
|
+
? { kind: "retry" }
|
|
146
|
+
: { kind: "refused", reason: "deadline_elapsed" };
|
|
147
|
+
if (Date.now() >= operationDeadlineAt) return deadlineOutcome();
|
|
148
|
+
// A matching published owner proves this request already succeeded; the
|
|
149
|
+
// broker may have cleared its committed intent after publication.
|
|
150
|
+
let existing: BrokerDiscovery | null;
|
|
151
|
+
try {
|
|
152
|
+
existing = await readBeforeBrokerDeadline(
|
|
153
|
+
readBrokerDiscovery(options.agentDir),
|
|
154
|
+
operationDeadlineAt,
|
|
155
|
+
"Timed out reading broker discovery before successor expiry.",
|
|
156
|
+
);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
if (error instanceof BrokerSuccessorDeadlineError) return deadlineOutcome();
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
161
|
+
if (Date.now() >= operationDeadlineAt) return deadlineOutcome();
|
|
162
|
+
if (
|
|
163
|
+
existing &&
|
|
164
|
+
existing.packageGeneration === options.packageGeneration &&
|
|
165
|
+
existing.restartRequestId === options.requestId
|
|
166
|
+
)
|
|
167
|
+
return { kind: "adopted" as const, discovery: existing };
|
|
168
|
+
// Only a durably COMMITTED intent for this exact requestId authorizes a
|
|
169
|
+
// new spawn. Re-read it on every lock attempt so a retry cannot use stale
|
|
170
|
+
// authorization or launch a duplicate successor.
|
|
171
|
+
let intent: BrokerRestartIntentWithIdentity | null;
|
|
172
|
+
try {
|
|
173
|
+
intent = await readBeforeBrokerDeadline(
|
|
174
|
+
readBrokerRestartIntent(options.agentDir),
|
|
175
|
+
operationDeadlineAt,
|
|
176
|
+
"Timed out validating the successor restart intent.",
|
|
177
|
+
);
|
|
178
|
+
} catch (error) {
|
|
179
|
+
if (error instanceof BrokerSuccessorDeadlineError) return deadlineOutcome();
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
if (Date.now() >= operationDeadlineAt) return deadlineOutcome();
|
|
183
|
+
if (intent?.phase !== "committed" || intent.requestId !== options.requestId)
|
|
184
|
+
return { kind: "refused" as const, reason: "intent_not_committed" as const };
|
|
185
|
+
if (intent.expiresAt <= Date.now())
|
|
186
|
+
return { kind: "refused" as const, reason: "deadline_elapsed" as const };
|
|
187
|
+
successorDeadlineAt = Math.min(successorDeadlineAt, intent.expiresAt);
|
|
188
|
+
if (Date.now() >= successorDeadlineAt)
|
|
189
|
+
return { kind: "refused" as const, reason: "deadline_elapsed" as const };
|
|
190
|
+
const command = resolveSdkInternalSpawnCommand("broker-internal");
|
|
191
|
+
try {
|
|
192
|
+
const env = {
|
|
193
|
+
...command.env,
|
|
194
|
+
GJC_BROKER_RESTART_REQUEST: options.requestId,
|
|
195
|
+
GJC_BROKER_RESTART_DEADLINE: String(intent.expiresAt),
|
|
196
|
+
};
|
|
197
|
+
const launchMode = resolveBrokerLaunchMode(process.platform, "discovery");
|
|
198
|
+
if (launchMode === "direct") throw new Error("Broker successor launch cannot use a fixture child.");
|
|
199
|
+
const timeoutMs = Math.max(0, Math.min(deadline, successorDeadlineAt) - Date.now());
|
|
200
|
+
const launched =
|
|
201
|
+
launchMode === "windows-hop"
|
|
202
|
+
? await launchBrokerViaHop(
|
|
203
|
+
{
|
|
204
|
+
command: {
|
|
205
|
+
file: command.file,
|
|
206
|
+
args: [...command.args, "--agent-dir", options.agentDir],
|
|
207
|
+
},
|
|
208
|
+
...(command.kind === "bun-source" ? { cwd: command.cwd } : {}),
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
env,
|
|
212
|
+
cwd: command.kind === "bun-source" ? command.cwd : undefined,
|
|
213
|
+
timeoutMs,
|
|
214
|
+
},
|
|
215
|
+
)
|
|
216
|
+
: await launchBrokerViaPosixTrampoline(options.agentDir, {
|
|
217
|
+
env,
|
|
218
|
+
...(command.kind === "bun-source" ? { cwd: command.cwd } : {}),
|
|
219
|
+
timeoutMs,
|
|
220
|
+
retainChildUntilPublication: launchMode === "darwin-trampoline",
|
|
221
|
+
});
|
|
222
|
+
if (launched.error) return await refuseFailedBrokerLaunch(launched);
|
|
223
|
+
if (launched.realBrokerPid === undefined || launched.realBrokerIncarnation === undefined)
|
|
224
|
+
return await refuseFailedBrokerLaunch({
|
|
225
|
+
...launched,
|
|
226
|
+
error: new Error("Broker launcher returned no verified process identity."),
|
|
227
|
+
});
|
|
228
|
+
const child: childProcess.ChildProcess = launched.process;
|
|
229
|
+
if (!launched.handoff) child.unref();
|
|
230
|
+
return {
|
|
231
|
+
kind: "spawned" as const,
|
|
232
|
+
child,
|
|
233
|
+
realBrokerPid: launched.realBrokerPid,
|
|
234
|
+
realBrokerIncarnation: launched.realBrokerIncarnation,
|
|
235
|
+
handoff: launched.handoff,
|
|
236
|
+
};
|
|
237
|
+
} catch (spawnError) {
|
|
238
|
+
return {
|
|
239
|
+
kind: "refused" as const,
|
|
240
|
+
reason: "spawn_failed" as const,
|
|
241
|
+
detail: spawnError instanceof Error ? spawnError.message : String(spawnError),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
{ deadlineAt: options.deadlineAt },
|
|
246
|
+
);
|
|
247
|
+
startupLockFailure = undefined;
|
|
248
|
+
if (spawnOutcome.kind === "retry") {
|
|
249
|
+
// The validation read exhausted this short lock operation, not the
|
|
250
|
+
// committed lease. The lock has been released; revalidate under a fresh
|
|
251
|
+
// operation window while the request is still authorized.
|
|
252
|
+
const remainingMs = successorDeadlineAt - Date.now();
|
|
253
|
+
if (remainingMs > 0) await Bun.sleep(Math.min(SUCCESSOR_SPAWN_POLL_MS, remainingMs));
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
} catch (lockError) {
|
|
258
|
+
if (!(lockError instanceof FileLockAcquireError)) throw lockError;
|
|
259
|
+
startupLockFailure = lockError;
|
|
260
|
+
if (Date.now() >= successorDeadlineAt)
|
|
261
|
+
return { kind: "refused", reason: "startup_lock_unavailable", detail: lockError.message };
|
|
262
|
+
await Bun.sleep(Math.min(50, options.deadlineAt - Date.now()));
|
|
82
263
|
}
|
|
83
|
-
|
|
84
|
-
let trampolineOutput = "";
|
|
85
|
-
let trampolineOutputEnded = !isTrampoline;
|
|
86
|
-
if (child.stdout)
|
|
87
|
-
child.stdout
|
|
88
|
-
.setEncoding("utf8")
|
|
89
|
-
.on("data", chunk => (trampolineOutput += chunk))
|
|
90
|
-
.once("end", () => (trampolineOutputEnded = true));
|
|
91
|
-
child.once("error", childError => {
|
|
92
|
-
spawnError = childError;
|
|
93
|
-
});
|
|
94
|
-
child.unref();
|
|
95
|
-
return {
|
|
96
|
-
kind: "spawned" as const,
|
|
97
|
-
child,
|
|
98
|
-
isTrampoline,
|
|
99
|
-
trampolineOutput: () => trampolineOutput,
|
|
100
|
-
trampolineOutputEnded: () => trampolineOutputEnded,
|
|
101
|
-
spawnError: () => spawnError,
|
|
102
|
-
};
|
|
103
|
-
});
|
|
264
|
+
}
|
|
104
265
|
if (spawnOutcome.kind !== "spawned") return spawnOutcome;
|
|
105
266
|
const { child } = spawnOutcome;
|
|
106
|
-
|
|
107
|
-
let
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
trampolineExitCode = code;
|
|
114
|
-
trampolineSignal = signal;
|
|
115
|
-
trampolineExited = true;
|
|
116
|
-
});
|
|
117
|
-
if (spawnOutcome.isTrampoline && (child.exitCode !== null || child.signalCode !== null)) {
|
|
118
|
-
trampolineExitCode = child.exitCode;
|
|
119
|
-
trampolineSignal = child.signalCode;
|
|
120
|
-
trampolineExited = true;
|
|
121
|
-
}
|
|
122
|
-
const until = Math.min(Date.now() + Math.max(1, options.deadlineAt - Date.now()), options.deadlineAt);
|
|
267
|
+
const realBrokerPid = spawnOutcome.realBrokerPid ?? child.pid;
|
|
268
|
+
let expectedBrokerIncarnation =
|
|
269
|
+
spawnOutcome.realBrokerIncarnation ??
|
|
270
|
+
(realBrokerPid !== undefined && realBrokerPid === child.pid
|
|
271
|
+
? brokerProcessIncarnation(realBrokerPid)
|
|
272
|
+
: undefined);
|
|
273
|
+
const until = Math.min(Date.now() + Math.max(1, successorDeadlineAt - Date.now()), successorDeadlineAt);
|
|
123
274
|
for (;;) {
|
|
124
|
-
if (
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (successorPid) {
|
|
148
|
-
const observed = observeProcessIncarnation(successorPid);
|
|
275
|
+
if (Date.now() >= until)
|
|
276
|
+
return await refuseUnpublishedBrokerSuccessor(
|
|
277
|
+
child,
|
|
278
|
+
realBrokerPid,
|
|
279
|
+
expectedBrokerIncarnation,
|
|
280
|
+
spawnOutcome.handoff,
|
|
281
|
+
"publication_timeout",
|
|
282
|
+
);
|
|
283
|
+
// On Darwin the trampoline remains alive until publication; elsewhere the
|
|
284
|
+
// launcher exits after handoff. The broker identity remains authoritative.
|
|
285
|
+
const failedSpawn = child.signalCode !== null || (child.exitCode !== null && child.exitCode !== 0);
|
|
286
|
+
if (failedSpawn)
|
|
287
|
+
return await refuseUnpublishedBrokerSuccessor(
|
|
288
|
+
child,
|
|
289
|
+
realBrokerPid,
|
|
290
|
+
expectedBrokerIncarnation,
|
|
291
|
+
spawnOutcome.handoff,
|
|
292
|
+
"spawn_exited_before_publication",
|
|
293
|
+
);
|
|
294
|
+
if (realBrokerPid !== undefined) {
|
|
295
|
+
const observation = observeProcessIncarnation(realBrokerPid);
|
|
149
296
|
if (
|
|
150
|
-
|
|
151
|
-
(
|
|
297
|
+
observation.status === "absent" ||
|
|
298
|
+
(observation.status === "present" &&
|
|
299
|
+
expectedBrokerIncarnation !== undefined &&
|
|
300
|
+
observation.incarnation !== expectedBrokerIncarnation)
|
|
152
301
|
)
|
|
153
|
-
return
|
|
302
|
+
return await refuseUnpublishedBrokerSuccessor(
|
|
303
|
+
child,
|
|
304
|
+
realBrokerPid,
|
|
305
|
+
expectedBrokerIncarnation,
|
|
306
|
+
spawnOutcome.handoff,
|
|
307
|
+
"spawn_exited_before_publication",
|
|
308
|
+
);
|
|
309
|
+
if (
|
|
310
|
+
observation.status === "present" &&
|
|
311
|
+
expectedBrokerIncarnation === undefined &&
|
|
312
|
+
realBrokerPid === child.pid
|
|
313
|
+
) {
|
|
314
|
+
expectedBrokerIncarnation = observation.incarnation;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
let discovered: BrokerDiscovery | null;
|
|
318
|
+
try {
|
|
319
|
+
discovered = await readBeforeBrokerDeadline(
|
|
320
|
+
readBrokerDiscovery(options.agentDir),
|
|
321
|
+
until,
|
|
322
|
+
"Timed out waiting for broker discovery before successor expiry.",
|
|
323
|
+
);
|
|
324
|
+
} catch (error) {
|
|
325
|
+
if (!(error instanceof BrokerSuccessorDeadlineError)) throw error;
|
|
326
|
+
return await refuseUnpublishedBrokerSuccessor(
|
|
327
|
+
child,
|
|
328
|
+
realBrokerPid,
|
|
329
|
+
expectedBrokerIncarnation,
|
|
330
|
+
spawnOutcome.handoff,
|
|
331
|
+
"publication_timeout",
|
|
332
|
+
);
|
|
154
333
|
}
|
|
155
|
-
if (spawnOutcome.isTrampoline && trampolineExited && spawnOutcome.trampolineOutputEnded() && !successorPid)
|
|
156
|
-
return { kind: "refused", reason: "spawn_exited_before_publication" };
|
|
157
|
-
if (spawnOutcome.isTrampoline && trampolineExited && (trampolineSignal !== null || trampolineExitCode !== 0))
|
|
158
|
-
return { kind: "refused", reason: "spawn_exited_before_publication" };
|
|
159
|
-
const discovered = await readBrokerDiscovery(options.agentDir);
|
|
160
334
|
if (
|
|
161
335
|
discovered &&
|
|
336
|
+
discovered.pid === realBrokerPid &&
|
|
337
|
+
discovered.incarnation === expectedBrokerIncarnation &&
|
|
162
338
|
discovered.packageGeneration === options.packageGeneration &&
|
|
163
339
|
discovered.restartRequestId === options.requestId
|
|
164
|
-
)
|
|
165
|
-
if (
|
|
166
|
-
return
|
|
167
|
-
|
|
340
|
+
) {
|
|
341
|
+
if (Date.now() >= until)
|
|
342
|
+
return await refuseUnpublishedBrokerSuccessor(
|
|
343
|
+
child,
|
|
344
|
+
realBrokerPid,
|
|
345
|
+
expectedBrokerIncarnation,
|
|
346
|
+
spawnOutcome.handoff,
|
|
347
|
+
"publication_timeout",
|
|
348
|
+
);
|
|
349
|
+
try {
|
|
350
|
+
await spawnOutcome.handoff?.release();
|
|
351
|
+
} catch (error) {
|
|
352
|
+
const refusal = await refuseUnpublishedBrokerSuccessor(
|
|
353
|
+
child,
|
|
354
|
+
realBrokerPid,
|
|
355
|
+
expectedBrokerIncarnation,
|
|
356
|
+
spawnOutcome.handoff,
|
|
357
|
+
"spawn_exited_before_publication",
|
|
358
|
+
);
|
|
359
|
+
return {
|
|
360
|
+
...refusal,
|
|
361
|
+
detail: `Broker successor release failed: ${error instanceof Error ? error.message : String(error)}${
|
|
362
|
+
refusal.detail ? `; ${refusal.detail}` : ""
|
|
363
|
+
}`,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
kind: "spawned" as const,
|
|
368
|
+
child,
|
|
369
|
+
realBrokerPid,
|
|
370
|
+
realBrokerIncarnation: expectedBrokerIncarnation,
|
|
371
|
+
handoff: spawnOutcome.handoff,
|
|
372
|
+
discovery: discovered,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
if (Date.now() >= until)
|
|
376
|
+
return await refuseUnpublishedBrokerSuccessor(
|
|
377
|
+
child,
|
|
378
|
+
realBrokerPid,
|
|
379
|
+
expectedBrokerIncarnation,
|
|
380
|
+
spawnOutcome.handoff,
|
|
381
|
+
"publication_timeout",
|
|
382
|
+
);
|
|
168
383
|
await Bun.sleep(SUCCESSOR_SPAWN_POLL_MS);
|
|
169
384
|
}
|
|
170
385
|
}
|
|
171
386
|
|
|
387
|
+
/** Test hook: retries exact cleanup before mapping a launch error to refusal. */
|
|
388
|
+
export function refuseFailedBrokerLaunchForTest(
|
|
389
|
+
launched: BrokerLaunchResult,
|
|
390
|
+
): Promise<Extract<AuthorizedBrokerSuccessorResult, { kind: "refused" }>> {
|
|
391
|
+
return refuseFailedBrokerLaunch(launched);
|
|
392
|
+
}
|
|
393
|
+
|
|
172
394
|
/**
|
|
173
395
|
* Positive OS-confirmed absence of the exact prior owner, distinguished from
|
|
174
396
|
* every merely-inconclusive outcome (permission denial, PID reuse ambiguity,
|