@gajae-code/coding-agent 0.17.2 → 0.17.5
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 +267 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/github-release.d.ts +17 -0
- package/dist/types/cli/public-command-entry.d.ts +56 -0
- package/dist/types/cli/public-command-errors.d.ts +126 -0
- package/dist/types/cli/public-command-evidence.d.ts +99 -0
- package/dist/types/cli/public-command-help.d.ts +65 -0
- package/dist/types/cli/public-command-registry.d.ts +69 -0
- package/dist/types/cli/session-picker.d.ts +1 -1
- package/dist/types/cli/setup-cli.d.ts +1 -0
- package/dist/types/cli/skills-cli.d.ts +5 -0
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +4 -50
- package/dist/types/commands/sdk.d.ts +20 -37
- package/dist/types/commands/setup.d.ts +3 -0
- package/dist/types/commands/skills.d.ts +9 -0
- package/dist/types/config/autorouting-tier-map.d.ts +1049 -3
- package/dist/types/config/file-lock.d.ts +13 -3
- package/dist/types/config/model-profile-activation.d.ts +45 -1
- package/dist/types/config/model-registry.d.ts +14 -3
- package/dist/types/config/model-resolver.d.ts +1 -1
- package/dist/types/config/settings-schema.d.ts +11 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
- package/dist/types/daemon/operator-contract.d.ts +5 -1
- package/dist/types/eval/js/worker-protocol.d.ts +2 -0
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/types.d.ts +12 -0
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +4 -0
- package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +11 -2
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +18 -0
- package/dist/types/extensibility/shared-events.d.ts +3 -1
- package/dist/types/gjc-runtime/session-state-lock.d.ts +61 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
- package/dist/types/harness-control-plane/control-endpoint.d.ts +4 -1
- package/dist/types/harness-control-plane/finalize.d.ts +14 -3
- package/dist/types/internal-urls/embedded-protocol.d.ts +9 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/parse.d.ts +9 -1
- package/dist/types/main.d.ts +23 -1
- package/dist/types/modes/acp/acp-agent.d.ts +55 -1
- package/dist/types/modes/acp/startup-provenance.d.ts +16 -0
- package/dist/types/modes/components/custom-provider-wizard.d.ts +19 -1
- package/dist/types/modes/components/session-selector.d.ts +5 -2
- package/dist/types/modes/components/user-message-selector.d.ts +5 -2
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +11 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +14 -1
- package/dist/types/modes/types.d.ts +2 -2
- package/dist/types/runtime/process-lifecycle.d.ts +2 -0
- package/dist/types/runtime-mcp/loader.d.ts +2 -0
- package/dist/types/runtime-mcp/manager.d.ts +69 -6
- package/dist/types/runtime-mcp/pool.d.ts +17 -0
- package/dist/types/runtime-mcp/redaction.d.ts +20 -0
- package/dist/types/runtime-mcp/startup-policy.d.ts +6 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +9 -0
- package/dist/types/runtime-mcp/transports/http.d.ts +11 -0
- package/dist/types/sdk/broker/broker.d.ts +17 -4
- package/dist/types/sdk/broker/ensure.d.ts +3 -0
- package/dist/types/sdk/broker/identity.d.ts +5 -1
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +23 -3
- package/dist/types/sdk/broker/lifecycle.d.ts +15 -8
- package/dist/types/sdk/broker/managed-task-dag.d.ts +1335 -0
- package/dist/types/sdk/broker/managed-task-verification.d.ts +37 -0
- package/dist/types/sdk/broker/runtime.d.ts +1 -1
- package/dist/types/sdk/broker/session-index.d.ts +22 -3
- package/dist/types/sdk/broker/spawn-authority.d.ts +12 -0
- package/dist/types/sdk/broker/startup-failure.d.ts +4 -0
- package/dist/types/sdk/broker/stderr-drainer.d.ts +13 -0
- package/dist/types/sdk/bus/index.d.ts +19 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +5 -0
- package/dist/types/sdk/cli/master-cli.d.ts +6 -10
- package/dist/types/sdk/cli/rows.d.ts +19 -1
- package/dist/types/sdk/cli/session-cli.d.ts +22 -5
- package/dist/types/sdk/client/client.d.ts +2 -0
- package/dist/types/sdk/guides/cli.d.ts +3 -4
- package/dist/types/sdk/guides/verify.d.ts +2 -0
- package/dist/types/sdk/host/host.d.ts +9 -0
- package/dist/types/sdk/host/session-runtime.d.ts +31 -0
- package/dist/types/sdk/host/types.d.ts +10 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +85 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +37 -0
- package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
- package/dist/types/sdk/router/session-router.d.ts +2 -0
- package/dist/types/sdk/session.d.ts +3 -3
- package/dist/types/sdk/startup-capability.d.ts +2 -0
- package/dist/types/sdk/transport/relay.d.ts +1 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +48 -4
- package/dist/types/sdk/transport/stdio.d.ts +5 -1
- package/dist/types/session/agent-session.d.ts +175 -23
- package/dist/types/session/fallback-chain-controller.d.ts +6 -6
- package/dist/types/session/fold-coordinator.d.ts +17 -3
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -1
- package/dist/types/session/session-manager.d.ts +64 -1
- package/dist/types/session/session-work-lease.d.ts +14 -0
- package/dist/types/setup/model-onboarding-guidance.d.ts +1 -1
- package/dist/types/setup/provider-onboarding.d.ts +81 -1
- package/dist/types/task/types.d.ts +2 -0
- package/dist/types/tools/bash-interactive.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +37 -11
- package/dist/types/tools/fetch.d.ts +10 -1
- package/dist/types/tools/job.d.ts +1 -1
- package/dist/types/tools/steer-fold.d.ts +31 -0
- package/dist/types/tools/subagent.d.ts +8 -1
- package/dist/types/utils/git.d.ts +28 -2
- package/dist/types/utils/mupdf-embedded.d.ts +2 -0
- package/dist/types/utils/mupdf.d.ts +4 -0
- package/dist/types/utils/session-title-generation.d.ts +6 -0
- package/dist/types/utils/title-generator.d.ts +11 -2
- package/dist/types/web/scrapers/types.d.ts +3 -0
- package/package.json +18 -10
- package/scripts/build-binary.ts +9 -3
- package/scripts/compile-args.ts +0 -9
- package/scripts/embed-mupdf.ts +52 -0
- package/scripts/generate-sdk-operation-inventory.ts +31 -1
- package/scripts/vendor-markit.ts +196 -0
- package/src/async/job-manager.ts +22 -1
- package/src/cli/daemon-cli.ts +53 -18
- package/src/cli/github-release.ts +87 -5
- package/src/cli/mcp-cli.ts +38 -4
- package/src/cli/public-command-entry.ts +450 -0
- package/src/cli/public-command-errors.ts +581 -0
- package/src/cli/public-command-evidence.ts +717 -0
- package/src/cli/public-command-help.ts +360 -0
- package/src/cli/public-command-registry.ts +541 -0
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +10 -1
- package/src/cli/skills-cli.ts +46 -2
- package/src/cli/stats-cli.ts +11 -1
- package/src/cli.ts +61 -1
- package/src/commands/daemon.ts +65 -69
- package/src/commands/sdk.ts +175 -117
- package/src/commands/setup.ts +2 -0
- package/src/commands/skills.ts +11 -0
- package/src/config/autorouting-tier-map.ts +543 -3
- package/src/config/file-lock.ts +206 -65
- package/src/config/model-discovery-manager.ts +4 -4
- package/src/config/model-profile-activation.ts +417 -66
- package/src/config/model-registry.ts +254 -36
- package/src/config/model-resolver.ts +6 -1
- package/src/config/settings-schema.ts +26 -2
- package/src/coordinator-mcp/policy.ts +10 -5
- package/src/coordinator-mcp/question-gate-codec.ts +17 -0
- package/src/coordinator-mcp/question-state.ts +179 -9
- package/src/coordinator-mcp/server.ts +521 -87
- package/src/coordinator-mcp/session-reaper.ts +6 -4
- package/src/crash/record-loader.ts +6 -2
- package/src/daemon/operator-contract.ts +26 -12
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
- package/src/eval/js/context-manager.ts +8 -8
- package/src/eval/js/worker-core.ts +9 -4
- package/src/eval/js/worker-protocol.ts +2 -0
- package/src/exec/bash-executor.ts +3 -0
- package/src/extensibility/extensions/runner.ts +52 -4
- package/src/extensibility/extensions/types.ts +10 -0
- package/src/extensibility/gjc-plugins/registry.ts +196 -37
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +46 -8
- package/src/extensibility/runtime-skill-discovery.ts +61 -3
- package/src/extensibility/shared-events.ts +3 -1
- package/src/gjc-runtime/session-state-lock.ts +165 -24
- package/src/gjc-runtime/state-writer.ts +317 -6
- package/src/gjc-runtime/ultragoal-succession.ts +31 -3
- package/src/harness-control-plane/control-endpoint.ts +24 -6
- package/src/harness-control-plane/finalize.ts +312 -25
- package/src/harness-control-plane/owner.ts +323 -89
- package/src/internal-urls/docs-index.generated.ts +23 -20
- package/src/internal-urls/embedded-protocol.ts +83 -0
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/parse.ts +21 -1
- package/src/internal-urls/router.ts +4 -2
- package/src/main.ts +192 -74
- package/src/modes/acp/acp-agent.ts +973 -56
- package/src/modes/acp/startup-provenance.ts +59 -0
- package/src/modes/components/custom-provider-wizard.ts +308 -7
- package/src/modes/components/gjc-bundle-settings.ts +21 -1
- package/src/modes/components/oauth-selector.ts +9 -0
- package/src/modes/components/session-selector.ts +47 -4
- package/src/modes/components/tool-status-header.ts +72 -6
- package/src/modes/components/user-message-selector.ts +57 -15
- package/src/modes/controllers/command-controller.ts +58 -32
- package/src/modes/controllers/extension-ui-controller.ts +33 -7
- package/src/modes/controllers/input-controller.ts +4 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +161 -15
- package/src/modes/interactive-mode.ts +21 -7
- package/src/modes/runtime-init.ts +1 -0
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +124 -7
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +16 -2
- package/src/modes/types.ts +2 -2
- package/src/prompts/agent-fragments/browser-aside.md +1 -0
- package/src/prompts/system/title-system.md +1 -1
- package/src/prompts/tools/bash.md +1 -1
- package/src/prompts/tools/job.md +1 -1
- package/src/prompts/tools/read.md +2 -0
- package/src/runtime/network-prewarm-service.test.ts +36 -1
- package/src/runtime/network-prewarm-service.ts +28 -3
- package/src/runtime/process-lifecycle.ts +22 -11
- package/src/runtime-mcp/config.ts +16 -1
- package/src/runtime-mcp/loader.ts +6 -3
- package/src/runtime-mcp/manager.ts +845 -109
- package/src/runtime-mcp/pool.test.ts +31 -0
- package/src/runtime-mcp/pool.ts +304 -28
- package/src/runtime-mcp/redaction.ts +42 -0
- package/src/runtime-mcp/startup-policy.ts +7 -0
- package/src/runtime-mcp/tool-bridge.ts +71 -0
- package/src/runtime-mcp/transports/http.ts +108 -25
- package/src/sdk/acp/adapter.ts +27 -8
- package/src/sdk/broker/broker.ts +1431 -198
- package/src/sdk/broker/ensure.ts +21 -3
- package/src/sdk/broker/identity.ts +22 -1
- package/src/sdk/broker/lifecycle-ledger.ts +95 -31
- package/src/sdk/broker/lifecycle.ts +690 -141
- package/src/sdk/broker/managed-task-dag.ts +1927 -0
- package/src/sdk/broker/managed-task-verification.ts +642 -0
- package/src/sdk/broker/runtime.ts +1 -1
- package/src/sdk/broker/session-index.ts +97 -4
- package/src/sdk/broker/spawn-authority.ts +175 -14
- package/src/sdk/broker/startup-failure.ts +80 -1
- package/src/sdk/broker/stderr-drainer.ts +59 -0
- package/src/sdk/broker/transport.ts +1 -0
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
- package/src/sdk/bus/index.ts +707 -81
- package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
- package/src/sdk/bus/telegram-daemon-contract.ts +7 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -3
- package/src/sdk/cli/master-cli.ts +47 -36
- package/src/sdk/cli/rows.ts +30 -7
- package/src/sdk/cli/session-cli.ts +705 -184
- package/src/sdk/client/client.ts +18 -0
- package/src/sdk/guides/catalog.ts +2 -2
- package/src/sdk/guides/cli.ts +20 -62
- package/src/sdk/guides/verify.ts +14 -0
- package/src/sdk/host/host.ts +49 -5
- package/src/sdk/host/session-runtime.test.ts +184 -2
- package/src/sdk/host/session-runtime.ts +322 -101
- package/src/sdk/host/types.ts +12 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +84 -0
- package/src/sdk/host/websocket-transport.ts +40 -6
- package/src/sdk/index.ts +11 -0
- package/src/sdk/lifecycle/service.ts +2 -0
- package/src/sdk/prompt-deadline-flush.ts +356 -0
- package/src/sdk/prompt-deadline-manager.ts +133 -1
- package/src/sdk/prompt-tool-boundary.ts +121 -0
- package/src/sdk/protocol/operation-inventory.generated.json +106 -0
- package/src/sdk/router/session-router.ts +9 -1
- package/src/sdk/session.ts +763 -116
- package/src/sdk/startup-capability.ts +1 -1
- package/src/sdk/transport/relay.ts +71 -6
- package/src/sdk/transport/serve-cli.ts +397 -42
- package/src/sdk/transport/socket.ts +12 -11
- package/src/sdk/transport/stdio.ts +7 -3
- package/src/session/agent-session.ts +2472 -407
- package/src/session/fallback-chain-controller.ts +6 -7
- package/src/session/fold-coordinator.ts +24 -5
- package/src/session/internal/managed-session-scope.ts +68 -18
- package/src/session/internal/managed-session-storage.ts +334 -12
- package/src/session/session-manager.ts +382 -44
- package/src/session/session-work-lease.ts +34 -0
- package/src/setup/model-onboarding-guidance.ts +1 -1
- package/src/setup/provider-onboarding.ts +397 -24
- package/src/setup/provider-presets.json +2 -1
- package/src/slash-commands/builtin-registry.ts +259 -15
- package/src/task/executor.ts +46 -17
- package/src/task/index.ts +14 -2
- package/src/task/types.ts +2 -0
- package/src/tools/bash-interactive.ts +2 -0
- package/src/tools/bash.ts +118 -78
- package/src/tools/fetch.ts +140 -25
- package/src/tools/job.ts +151 -25
- package/src/tools/output-meta.ts +15 -2
- package/src/tools/path-utils.ts +27 -3
- package/src/tools/read.ts +3 -3
- package/src/tools/steer-fold.ts +107 -0
- package/src/tools/subagent-render.ts +24 -1
- package/src/tools/subagent.ts +27 -1
- package/src/tools/tool-catalog.generated.ts +29 -2
- package/src/tools/tool-errors.ts +4 -0
- package/src/utils/git.ts +53 -3
- package/src/utils/markit.ts +55 -41
- package/src/utils/mupdf-assets.d.ts +4 -0
- package/src/utils/mupdf-embedded.ts +4 -0
- package/src/utils/mupdf.ts +136 -0
- package/src/utils/session-title-generation.ts +29 -0
- package/src/utils/title-generator.ts +46 -2
- package/src/web/scrapers/types.ts +24 -3
- package/vendor/markit-ai/LICENSE +21 -0
- package/vendor/markit-ai/MANIFEST.json +412 -0
- package/vendor/markit-ai/dist/commands/config.d.ts +4 -0
- package/vendor/markit-ai/dist/commands/config.js +139 -0
- package/vendor/markit-ai/dist/commands/convert.d.ts +6 -0
- package/vendor/markit-ai/dist/commands/convert.js +113 -0
- package/vendor/markit-ai/dist/commands/formats.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/formats.js +92 -0
- package/vendor/markit-ai/dist/commands/init.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/init.js +29 -0
- package/vendor/markit-ai/dist/commands/onboard.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/onboard.js +61 -0
- package/vendor/markit-ai/dist/commands/plugin.d.ts +4 -0
- package/vendor/markit-ai/dist/commands/plugin.js +58 -0
- package/vendor/markit-ai/dist/config.d.ts +26 -0
- package/vendor/markit-ai/dist/config.js +42 -0
- package/vendor/markit-ai/dist/converters/audio.d.ts +7 -0
- package/vendor/markit-ai/dist/converters/audio.js +104 -0
- package/vendor/markit-ai/dist/converters/csv.d.ts +7 -0
- package/vendor/markit-ai/dist/converters/csv.js +83 -0
- package/vendor/markit-ai/dist/converters/docx.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/docx.js +57 -0
- package/vendor/markit-ai/dist/converters/epub.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/epub.js +128 -0
- package/vendor/markit-ai/dist/converters/github.d.ts +18 -0
- package/vendor/markit-ai/dist/converters/github.js +148 -0
- package/vendor/markit-ai/dist/converters/html.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/html.js +30 -0
- package/vendor/markit-ai/dist/converters/image.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/image.js +124 -0
- package/vendor/markit-ai/dist/converters/ipynb.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/ipynb.js +75 -0
- package/vendor/markit-ai/dist/converters/iwork.d.ts +20 -0
- package/vendor/markit-ai/dist/converters/iwork.js +391 -0
- package/vendor/markit-ai/dist/converters/json.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/json.js +21 -0
- package/vendor/markit-ai/dist/converters/pdf/columns.d.ts +35 -0
- package/vendor/markit-ai/dist/converters/pdf/columns.js +93 -0
- package/vendor/markit-ai/dist/converters/pdf/extract.d.ts +19 -0
- package/vendor/markit-ai/dist/converters/pdf/extract.js +514 -0
- package/vendor/markit-ai/dist/converters/pdf/grid.d.ts +25 -0
- package/vendor/markit-ai/dist/converters/pdf/grid.js +795 -0
- package/vendor/markit-ai/dist/converters/pdf/headers.d.ts +24 -0
- package/vendor/markit-ai/dist/converters/pdf/headers.js +108 -0
- package/vendor/markit-ai/dist/converters/pdf/index.d.ts +19 -0
- package/vendor/markit-ai/dist/converters/pdf/index.js +136 -0
- package/vendor/markit-ai/dist/converters/pdf/mupdf-loader.js +9 -0
- package/vendor/markit-ai/dist/converters/pdf/render.d.ts +24 -0
- package/vendor/markit-ai/dist/converters/pdf/render.js +513 -0
- package/vendor/markit-ai/dist/converters/pdf/types.d.ts +75 -0
- package/vendor/markit-ai/dist/converters/pdf/types.js +1 -0
- package/vendor/markit-ai/dist/converters/plain-text.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/plain-text.js +87 -0
- package/vendor/markit-ai/dist/converters/pptx.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/pptx.js +289 -0
- package/vendor/markit-ai/dist/converters/rss.d.ts +11 -0
- package/vendor/markit-ai/dist/converters/rss.js +138 -0
- package/vendor/markit-ai/dist/converters/wikipedia.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/wikipedia.js +33 -0
- package/vendor/markit-ai/dist/converters/xlsx.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/xlsx.js +147 -0
- package/vendor/markit-ai/dist/converters/xml.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/xml.js +18 -0
- package/vendor/markit-ai/dist/converters/yaml.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/yaml.js +17 -0
- package/vendor/markit-ai/dist/converters/zip.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/zip.js +57 -0
- package/vendor/markit-ai/dist/index.d.ts +30 -0
- package/vendor/markit-ai/dist/index.js +26 -0
- package/vendor/markit-ai/dist/main.d.ts +2 -0
- package/vendor/markit-ai/dist/main.js +191 -0
- package/vendor/markit-ai/dist/markit.d.ts +45 -0
- package/vendor/markit-ai/dist/markit.js +267 -0
- package/vendor/markit-ai/dist/plugins/api.d.ts +7 -0
- package/vendor/markit-ai/dist/plugins/api.js +42 -0
- package/vendor/markit-ai/dist/plugins/index.d.ts +4 -0
- package/vendor/markit-ai/dist/plugins/index.js +3 -0
- package/vendor/markit-ai/dist/plugins/installer.d.ts +25 -0
- package/vendor/markit-ai/dist/plugins/installer.js +176 -0
- package/vendor/markit-ai/dist/plugins/loader.d.ts +6 -0
- package/vendor/markit-ai/dist/plugins/loader.js +61 -0
- package/vendor/markit-ai/dist/plugins/types.d.ts +25 -0
- package/vendor/markit-ai/dist/plugins/types.js +1 -0
- package/vendor/markit-ai/dist/providers/anthropic.d.ts +2 -0
- package/vendor/markit-ai/dist/providers/anthropic.js +47 -0
- package/vendor/markit-ai/dist/providers/index.d.ts +21 -0
- package/vendor/markit-ai/dist/providers/index.js +56 -0
- package/vendor/markit-ai/dist/providers/openai.d.ts +2 -0
- package/vendor/markit-ai/dist/providers/openai.js +76 -0
- package/vendor/markit-ai/dist/providers/types.d.ts +26 -0
- package/vendor/markit-ai/dist/providers/types.js +1 -0
- package/vendor/markit-ai/dist/types.d.ts +36 -0
- package/vendor/markit-ai/dist/types.js +1 -0
- package/vendor/markit-ai/dist/utils/exit-codes.d.ts +4 -0
- package/vendor/markit-ai/dist/utils/exit-codes.js +4 -0
- package/vendor/markit-ai/dist/utils/output.d.ts +22 -0
- package/vendor/markit-ai/dist/utils/output.js +31 -0
- package/vendor/markit-ai/dist/utils/turndown.d.ts +8 -0
- package/vendor/markit-ai/dist/utils/turndown.js +70 -0
- package/vendor/markit-ai/package.json +74 -0
- package/vendor/markit-ai.patch +49 -0
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
1
2
|
import { getAgentDir } from "@gajae-code/utils";
|
|
2
3
|
import { CliParseError } from "@gajae-code/utils/cli";
|
|
4
|
+
import {
|
|
5
|
+
normalizePublicCommandFailure,
|
|
6
|
+
type PublicCommandDiagnosticCode,
|
|
7
|
+
PublicCommandFailure,
|
|
8
|
+
} from "../../cli/public-command-errors";
|
|
9
|
+
import { normalizeBrokerInput } from "../broker/broker";
|
|
3
10
|
import type { BrokerDiscovery } from "../broker/discovery";
|
|
11
|
+
import { lifecycleRequestTimeoutMs } from "../broker/startup-budget";
|
|
4
12
|
import { readSdkBrokerDiscovery, SdkClient, SdkClientError, SdkDiscoveryError } from "../client";
|
|
5
13
|
import { SessionListTraversalError, sessionListPageFromResponse, traverseSessionList } from "../session-list";
|
|
14
|
+
import type { ServeHandle } from "./index";
|
|
6
15
|
import { DEFAULT_PENDING_CEILING_BYTES, MIN_PENDING_CEILING_BYTES, startSocketServe, startStdioServe } from "./index";
|
|
7
16
|
|
|
8
17
|
type ServeMode = { kind: "stdio" } | { kind: "socket"; socketPath: string };
|
|
@@ -13,16 +22,21 @@ interface ServeArguments {
|
|
|
13
22
|
pendingCeiling?: string;
|
|
14
23
|
}
|
|
15
24
|
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Usage failures keep a static, allowlisted reason instead of the parser's raw text:
|
|
27
|
+
* the concrete diagnostic is what makes an unknown flag or a missing operand
|
|
28
|
+
* actionable, and it never echoes caller argv back into output or the evidence store.
|
|
29
|
+
*/
|
|
30
|
+
function usageError(diagnostic: PublicCommandDiagnosticCode): never {
|
|
31
|
+
throw new PublicCommandFailure({ kind: "usage", proof: "pre-effect", diagnostics: [diagnostic] });
|
|
18
32
|
}
|
|
19
33
|
|
|
20
34
|
/**
|
|
21
35
|
* A `gjc sdk serve` operational failure with a stable machine-readable code and a
|
|
22
36
|
* documented exit code, mirroring `SdkSessionCliError`. Usage errors keep their own
|
|
23
|
-
*
|
|
37
|
+
* public failure envelope; this type covers only failures an embedder must branch on.
|
|
24
38
|
*/
|
|
25
|
-
export class SdkServeError extends
|
|
39
|
+
export class SdkServeError extends PublicCommandFailure {
|
|
26
40
|
/**
|
|
27
41
|
* Diagnostics for a broker-teardown failure that happened alongside this primary
|
|
28
42
|
* failure. It rides beside `details` rather than inside it because `details`
|
|
@@ -36,8 +50,65 @@ export class SdkServeError extends Error {
|
|
|
36
50
|
readonly exitCode: 1,
|
|
37
51
|
readonly details?: unknown,
|
|
38
52
|
) {
|
|
39
|
-
super(
|
|
53
|
+
super(sdkServeFailureInput(code));
|
|
40
54
|
this.name = "SdkServeError";
|
|
55
|
+
this.message = message;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function sdkServeFailureInput(code: string): {
|
|
60
|
+
kind:
|
|
61
|
+
| "usage"
|
|
62
|
+
| "invalid_json"
|
|
63
|
+
| "unavailable"
|
|
64
|
+
| "broker_unavailable"
|
|
65
|
+
| "endpoint_stale"
|
|
66
|
+
| "broker_restarting"
|
|
67
|
+
| "authorization_denied"
|
|
68
|
+
| "timeout"
|
|
69
|
+
| "wait_timeout"
|
|
70
|
+
| "uncertain_after_send"
|
|
71
|
+
| "daemon_unhealthy"
|
|
72
|
+
| "daemon_stale"
|
|
73
|
+
| "daemon_mixed"
|
|
74
|
+
| "operation_failed"
|
|
75
|
+
| "internal";
|
|
76
|
+
proof?: "pre-send" | "pre-effect" | "accepted" | "completed" | "sent" | "unknown";
|
|
77
|
+
} {
|
|
78
|
+
switch (code) {
|
|
79
|
+
case "broker_restarting":
|
|
80
|
+
return { kind: "broker_restarting", proof: "pre-effect" };
|
|
81
|
+
case "broker_unavailable":
|
|
82
|
+
case "broker_discovery_unreadable":
|
|
83
|
+
return { kind: "broker_unavailable", proof: "pre-effect" };
|
|
84
|
+
case "endpoint_stale":
|
|
85
|
+
return { kind: "endpoint_stale", proof: "pre-effect" };
|
|
86
|
+
case "authorization_denied":
|
|
87
|
+
case "unauthorized":
|
|
88
|
+
case "forbidden":
|
|
89
|
+
case "master_context_required":
|
|
90
|
+
case "adapter_operation_prohibited":
|
|
91
|
+
case "endpoint_credential_forbidden":
|
|
92
|
+
return { kind: "authorization_denied", proof: "pre-effect" };
|
|
93
|
+
case "timeout":
|
|
94
|
+
return { kind: "timeout", proof: "unknown" };
|
|
95
|
+
case "uncertain_after_send":
|
|
96
|
+
return { kind: "uncertain_after_send", proof: "sent" };
|
|
97
|
+
case "usage":
|
|
98
|
+
case "invalid_input":
|
|
99
|
+
case "invalid_json":
|
|
100
|
+
return { kind: "usage", proof: "pre-effect" };
|
|
101
|
+
case "unavailable":
|
|
102
|
+
case "unsupported_platform":
|
|
103
|
+
case "not_found":
|
|
104
|
+
case "ambiguous_session":
|
|
105
|
+
return { kind: "unavailable", proof: "pre-effect" };
|
|
106
|
+
case "no_live_endpoint":
|
|
107
|
+
return { kind: "endpoint_stale", proof: "pre-effect" };
|
|
108
|
+
case "multiple_live_endpoints":
|
|
109
|
+
return { kind: "usage", proof: "pre-effect" };
|
|
110
|
+
default:
|
|
111
|
+
return { kind: "operation_failed" };
|
|
41
112
|
}
|
|
42
113
|
}
|
|
43
114
|
|
|
@@ -91,7 +162,10 @@ async function brokerCloseFailure(broker: SdkClient): Promise<Error | undefined>
|
|
|
91
162
|
*/
|
|
92
163
|
export function resolveServeOutcome(primary: Error | undefined, cleanup: Error | undefined): Error | undefined {
|
|
93
164
|
if (primary) {
|
|
94
|
-
if (cleanup && primary instanceof SdkServeError)
|
|
165
|
+
if (cleanup && primary instanceof SdkServeError) {
|
|
166
|
+
primary.cleanupError = cleanupDiagnostics(cleanup);
|
|
167
|
+
primary.input.diagnostics = [...(primary.input.diagnostics ?? []), "broker_cleanup_failed"];
|
|
168
|
+
}
|
|
95
169
|
return primary;
|
|
96
170
|
}
|
|
97
171
|
if (!cleanup) return undefined;
|
|
@@ -99,9 +173,9 @@ export function resolveServeOutcome(primary: Error | undefined, cleanup: Error |
|
|
|
99
173
|
return new SdkServeError("serve_cleanup_failed", `SDK broker cleanup failed: ${cleanup.message}`, 1, diagnostics);
|
|
100
174
|
}
|
|
101
175
|
|
|
102
|
-
function readFlagValue(argv: string[], index: number
|
|
176
|
+
function readFlagValue(argv: string[], index: number): string {
|
|
103
177
|
const value = argv[index + 1];
|
|
104
|
-
if (value === undefined || value.startsWith("-")) usageError(
|
|
178
|
+
if (value === undefined || value.startsWith("-")) usageError("usage_missing_value");
|
|
105
179
|
return value;
|
|
106
180
|
}
|
|
107
181
|
|
|
@@ -113,29 +187,29 @@ function parseServeArguments(argv: string[]): ServeArguments {
|
|
|
113
187
|
for (let index = 0; index < argv.length; index++) {
|
|
114
188
|
switch (argv[index]) {
|
|
115
189
|
case "--stdio":
|
|
116
|
-
if (stdio) usageError("
|
|
190
|
+
if (stdio) usageError("usage_duplicate_option");
|
|
117
191
|
stdio = true;
|
|
118
192
|
break;
|
|
119
193
|
case "--socket":
|
|
120
|
-
if (socketPath !== undefined) usageError("
|
|
121
|
-
socketPath = readFlagValue(argv, index
|
|
194
|
+
if (socketPath !== undefined) usageError("usage_duplicate_option");
|
|
195
|
+
socketPath = readFlagValue(argv, index);
|
|
122
196
|
index++;
|
|
123
197
|
break;
|
|
124
198
|
case "--session":
|
|
125
|
-
if (sessionId !== undefined) usageError("
|
|
126
|
-
sessionId = readFlagValue(argv, index
|
|
199
|
+
if (sessionId !== undefined) usageError("usage_duplicate_option");
|
|
200
|
+
sessionId = readFlagValue(argv, index);
|
|
127
201
|
index++;
|
|
128
202
|
break;
|
|
129
203
|
case "--pending-ceiling":
|
|
130
|
-
if (pendingCeiling !== undefined) usageError("
|
|
131
|
-
pendingCeiling = readFlagValue(argv, index
|
|
204
|
+
if (pendingCeiling !== undefined) usageError("usage_duplicate_option");
|
|
205
|
+
pendingCeiling = readFlagValue(argv, index);
|
|
132
206
|
index++;
|
|
133
207
|
break;
|
|
134
208
|
default:
|
|
135
|
-
usageError(
|
|
209
|
+
usageError("usage_unknown_argument");
|
|
136
210
|
}
|
|
137
211
|
}
|
|
138
|
-
if (stdio === (socketPath !== undefined)) usageError("
|
|
212
|
+
if (stdio === (socketPath !== undefined)) usageError("usage_transport_exclusive");
|
|
139
213
|
return { mode: stdio ? { kind: "stdio" } : { kind: "socket", socketPath: socketPath! }, sessionId, pendingCeiling };
|
|
140
214
|
}
|
|
141
215
|
|
|
@@ -143,14 +217,32 @@ function parseServeArguments(argv: string[]): ServeArguments {
|
|
|
143
217
|
export function resolveServePendingCeiling(flagValue: string | undefined, envValue: string | undefined): number {
|
|
144
218
|
const value = flagValue ?? envValue;
|
|
145
219
|
if (value === undefined) return DEFAULT_PENDING_CEILING_BYTES;
|
|
146
|
-
if (!/^\d+$/.test(value)) usageError("
|
|
220
|
+
if (!/^\d+$/.test(value)) usageError("usage_invalid_option_value");
|
|
147
221
|
const ceiling = Number(value);
|
|
148
|
-
if (!Number.isSafeInteger(ceiling) || ceiling < MIN_PENDING_CEILING_BYTES)
|
|
149
|
-
usageError(`--pending-ceiling must be an integer of at least ${MIN_PENDING_CEILING_BYTES}`);
|
|
222
|
+
if (!Number.isSafeInteger(ceiling) || ceiling < MIN_PENDING_CEILING_BYTES) usageError("usage_invalid_option_value");
|
|
150
223
|
return ceiling;
|
|
151
224
|
}
|
|
152
225
|
|
|
153
|
-
type
|
|
226
|
+
type BrokerTranscriptIdentity = {
|
|
227
|
+
dev: string;
|
|
228
|
+
ino: string;
|
|
229
|
+
size: number;
|
|
230
|
+
mtimeMs: number;
|
|
231
|
+
mtimeNs: string;
|
|
232
|
+
sha256: string;
|
|
233
|
+
};
|
|
234
|
+
type BrokerSavedSession = { id: string; path: string; identity: BrokerTranscriptIdentity };
|
|
235
|
+
type BrokerSessionLocator = { cwd: string; worktreeRoot: string | null; stateRoot: string };
|
|
236
|
+
type BrokerSessionRow = {
|
|
237
|
+
sessionId: string;
|
|
238
|
+
live: boolean;
|
|
239
|
+
ambiguous: boolean;
|
|
240
|
+
terminal?: boolean;
|
|
241
|
+
hostUnregisteredReason?: "process_exited" | "detached_idle";
|
|
242
|
+
terminalUncertain?: boolean;
|
|
243
|
+
locator?: BrokerSessionLocator;
|
|
244
|
+
savedSession?: BrokerSavedSession;
|
|
245
|
+
};
|
|
154
246
|
|
|
155
247
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
156
248
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -167,54 +259,277 @@ function brokerResult(value: unknown): Record<string, unknown> {
|
|
|
167
259
|
return isRecord(value) && isRecord(value.result) ? value.result : {};
|
|
168
260
|
}
|
|
169
261
|
|
|
170
|
-
function
|
|
262
|
+
function brokerSessionLocator(value: unknown): BrokerSessionLocator | undefined {
|
|
263
|
+
if (!isRecord(value)) return undefined;
|
|
264
|
+
const { cwd, worktreeRoot, stateRoot } = value;
|
|
265
|
+
return typeof cwd === "string" &&
|
|
266
|
+
cwd.length > 0 &&
|
|
267
|
+
(worktreeRoot === null || typeof worktreeRoot === "string") &&
|
|
268
|
+
typeof stateRoot === "string" &&
|
|
269
|
+
stateRoot.length > 0
|
|
270
|
+
? { cwd, worktreeRoot, stateRoot }
|
|
271
|
+
: undefined;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function brokerSavedSession(value: unknown): BrokerSavedSession | undefined {
|
|
275
|
+
if (!isRecord(value) || typeof value.id !== "string" || !value.id || typeof value.path !== "string" || !value.path)
|
|
276
|
+
return undefined;
|
|
277
|
+
if (!isRecord(value.identity)) return undefined;
|
|
278
|
+
const { dev, ino, size, mtimeMs, mtimeNs, sha256 } = value.identity;
|
|
279
|
+
if (
|
|
280
|
+
typeof dev !== "string" ||
|
|
281
|
+
!/^[0-9]+$/.test(dev) ||
|
|
282
|
+
typeof ino !== "string" ||
|
|
283
|
+
!/^[0-9]+$/.test(ino) ||
|
|
284
|
+
typeof size !== "number" ||
|
|
285
|
+
!Number.isSafeInteger(size) ||
|
|
286
|
+
size < 0 ||
|
|
287
|
+
typeof mtimeMs !== "number" ||
|
|
288
|
+
!Number.isFinite(mtimeMs) ||
|
|
289
|
+
mtimeMs < 0 ||
|
|
290
|
+
typeof mtimeNs !== "string" ||
|
|
291
|
+
!/^[0-9]+$/.test(mtimeNs) ||
|
|
292
|
+
typeof sha256 !== "string" ||
|
|
293
|
+
!/^[a-f0-9]{64}$/.test(sha256)
|
|
294
|
+
)
|
|
295
|
+
return undefined;
|
|
296
|
+
return { id: value.id, path: value.path, identity: { dev, ino, size, mtimeMs, mtimeNs, sha256 } };
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function brokerSessionRows(sessions: readonly unknown[], savedSession?: unknown): BrokerSessionRow[] {
|
|
300
|
+
const pageSavedSession = brokerSavedSession(savedSession);
|
|
171
301
|
return sessions.flatMap(item => {
|
|
172
302
|
if (!isRecord(item) || typeof item.sessionId !== "string" || !item.sessionId) return [];
|
|
173
|
-
|
|
303
|
+
const locator = brokerSessionLocator(item.locator);
|
|
304
|
+
const saved = pageSavedSession?.id === item.sessionId ? pageSavedSession : brokerSavedSession(item.savedSession);
|
|
305
|
+
const hostUnregisteredReason =
|
|
306
|
+
item.hostUnregisteredReason === "process_exited" || item.hostUnregisteredReason === "detached_idle"
|
|
307
|
+
? item.hostUnregisteredReason
|
|
308
|
+
: undefined;
|
|
309
|
+
const terminalUncertain = item.terminalUncertain === true || item.terminal_uncertain === true;
|
|
310
|
+
return [
|
|
311
|
+
{
|
|
312
|
+
sessionId: item.sessionId,
|
|
313
|
+
live: item.live === true,
|
|
314
|
+
ambiguous: item.ambiguous === true,
|
|
315
|
+
...(item.terminal === true ? { terminal: true } : {}),
|
|
316
|
+
...(hostUnregisteredReason === undefined ? {} : { hostUnregisteredReason }),
|
|
317
|
+
...(terminalUncertain ? { terminalUncertain: true } : {}),
|
|
318
|
+
...(locator === undefined ? {} : { locator }),
|
|
319
|
+
...(saved === undefined ? {} : { savedSession: saved }),
|
|
320
|
+
},
|
|
321
|
+
];
|
|
174
322
|
});
|
|
175
323
|
}
|
|
176
324
|
|
|
177
325
|
/** Exhausts strict broker `session.list` pages into one full session snapshot. */
|
|
178
|
-
export async function listBrokerSessions(
|
|
326
|
+
export async function listBrokerSessions(
|
|
327
|
+
broker: Pick<SdkClient, "global">,
|
|
328
|
+
explicitSessionId?: string,
|
|
329
|
+
cwd?: string,
|
|
330
|
+
): Promise<BrokerSessionRow[]> {
|
|
179
331
|
try {
|
|
180
332
|
const pages = await traverseSessionList(
|
|
181
|
-
{
|
|
333
|
+
{
|
|
334
|
+
...(explicitSessionId ? { resolveSessionId: explicitSessionId } : {}),
|
|
335
|
+
...(cwd === undefined ? {} : { cwd }),
|
|
336
|
+
},
|
|
182
337
|
async input => await broker.global("session.list", input),
|
|
183
338
|
response => {
|
|
184
339
|
brokerResult(response);
|
|
185
340
|
return sessionListPageFromResponse(response);
|
|
186
341
|
},
|
|
187
342
|
);
|
|
188
|
-
return pages.flatMap(page =>
|
|
343
|
+
return pages.flatMap(page =>
|
|
344
|
+
brokerSessionRows(page.sessions, isRecord(page.page) ? page.page.savedSession : undefined),
|
|
345
|
+
);
|
|
189
346
|
} catch (error) {
|
|
190
347
|
if (error instanceof SessionListTraversalError) throw new SdkClientError("protocol_error", error.message);
|
|
191
348
|
throw error;
|
|
192
349
|
}
|
|
193
350
|
}
|
|
194
351
|
|
|
352
|
+
function endpointStaleError(sessionId: string): Error {
|
|
353
|
+
// A typed error, because `toServeError` only passes `SdkServeError` through: a plain
|
|
354
|
+
// Error here is rewritten to `serve_failed`, which hides the one code that tells a
|
|
355
|
+
// caller recovery was attempted and the endpoint is still not live.
|
|
356
|
+
return new SdkServeError("endpoint_stale", `session ${sessionId} endpoint is not live`, 1);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
async function recoverBrokerSession(broker: SdkClient, row: BrokerSessionRow, sessionId: string): Promise<void> {
|
|
360
|
+
const locator = row.locator;
|
|
361
|
+
const authority =
|
|
362
|
+
row.savedSession?.id === sessionId
|
|
363
|
+
? row.savedSession
|
|
364
|
+
: locator === undefined
|
|
365
|
+
? undefined
|
|
366
|
+
: (await listBrokerSessions(broker, sessionId, locator.cwd)).find(
|
|
367
|
+
candidate => candidate.sessionId === sessionId,
|
|
368
|
+
)?.savedSession;
|
|
369
|
+
if (locator === undefined || authority?.id !== sessionId) throw endpointStaleError(sessionId);
|
|
370
|
+
const normalized = normalizeBrokerInput("session.resume", { sessionId, cwd: locator.cwd });
|
|
371
|
+
if (!("input" in normalized)) {
|
|
372
|
+
brokerResult(normalized);
|
|
373
|
+
throw endpointStaleError(sessionId);
|
|
374
|
+
}
|
|
375
|
+
const input = {
|
|
376
|
+
...normalized.input,
|
|
377
|
+
sessionPath: authority.path,
|
|
378
|
+
sessionIdentity: authority.identity,
|
|
379
|
+
};
|
|
380
|
+
const timeoutMs = lifecycleRequestTimeoutMs("session.resume", input);
|
|
381
|
+
brokerResult(
|
|
382
|
+
await broker.global("session.resume", input, {
|
|
383
|
+
idempotencyKey: crypto.randomUUID(),
|
|
384
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
385
|
+
}),
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/** Resolves an explicit or automatic serve target, reattaching one stale explicit session at most once. */
|
|
390
|
+
export async function resolveServeSession(broker: SdkClient, explicitSessionId?: string): Promise<string> {
|
|
391
|
+
const sessions = await listBrokerSessions(broker, explicitSessionId);
|
|
392
|
+
if (explicitSessionId !== undefined) {
|
|
393
|
+
const row = sessions.find(session => session.sessionId === explicitSessionId);
|
|
394
|
+
// An indexed, unambiguous row that is not live is the recoverable
|
|
395
|
+
// self-reap case (#5633). Every other targeting outcome — unindexed,
|
|
396
|
+
// ambiguous, no explicit id — stays the selector's to report, so this
|
|
397
|
+
// decision does not depend on the selector's error text.
|
|
398
|
+
// Recovery requires durable retirement provenance. A non-live row without a terminal
|
|
399
|
+
// retirement event may only have stale heartbeat evidence, which does not prove that the
|
|
400
|
+
// previous host exited and must not authorize a second host for the same transcript.
|
|
401
|
+
if (
|
|
402
|
+
row !== undefined &&
|
|
403
|
+
!row.ambiguous &&
|
|
404
|
+
!row.terminalUncertain &&
|
|
405
|
+
!row.live &&
|
|
406
|
+
row.terminal === true &&
|
|
407
|
+
(row.hostUnregisteredReason === "process_exited" || row.hostUnregisteredReason === "detached_idle")
|
|
408
|
+
) {
|
|
409
|
+
await recoverBrokerSession(broker, row, explicitSessionId);
|
|
410
|
+
return selectBrokerSession(await listBrokerSessions(broker, explicitSessionId), explicitSessionId);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return selectBrokerSession(sessions, explicitSessionId);
|
|
414
|
+
}
|
|
415
|
+
|
|
195
416
|
/** Selects the session to serve through broker `session.list` truth (C10); exported for tests. */
|
|
196
417
|
export function selectBrokerSession(sessions: BrokerSessionRow[], explicitSessionId: string | undefined): string {
|
|
197
418
|
if (explicitSessionId !== undefined) {
|
|
198
419
|
const row = sessions.find(session => session.sessionId === explicitSessionId);
|
|
199
420
|
if (!row) throw new SdkServeError("not_found", `session ${explicitSessionId} is not indexed by the broker`, 1);
|
|
200
421
|
if (row.ambiguous) throw new SdkServeError("ambiguous_session", "session id maps to more than one state root", 1);
|
|
422
|
+
if (row.terminalUncertain)
|
|
423
|
+
throw new SdkServeError("terminal_uncertain", `session ${explicitSessionId} ownership is uncertain`, 1);
|
|
201
424
|
if (!row.live) throw new SdkServeError("endpoint_stale", `session ${explicitSessionId} endpoint is not live`, 1);
|
|
202
425
|
return row.sessionId;
|
|
203
426
|
}
|
|
204
|
-
const live = sessions.filter(session => session.live && !session.ambiguous);
|
|
427
|
+
const live = sessions.filter(session => session.live && !session.ambiguous && !session.terminalUncertain);
|
|
205
428
|
if (live.length === 0) throw new SdkServeError("no_live_endpoint", "no live session endpoint", 1);
|
|
206
429
|
if (live.length > 1)
|
|
207
430
|
throw new SdkServeError("multiple_live_endpoints", "more than one live session; specify --session <id>", 1);
|
|
208
431
|
return live[0]!.sessionId;
|
|
209
432
|
}
|
|
210
433
|
|
|
434
|
+
/** Only SDK-owned error codes carry classification authority at preflight. */
|
|
435
|
+
function servePreflightFailure(error: unknown): PublicCommandFailure {
|
|
436
|
+
if (!(error instanceof SdkClientError)) return normalizePublicCommandFailure(error);
|
|
437
|
+
switch (error.code) {
|
|
438
|
+
case "broker_restarting":
|
|
439
|
+
return new PublicCommandFailure({ kind: "broker_restarting", proof: "pre-effect" });
|
|
440
|
+
case "broker_unavailable":
|
|
441
|
+
return new PublicCommandFailure({ kind: "broker_unavailable", proof: "pre-effect" });
|
|
442
|
+
case "endpoint_stale":
|
|
443
|
+
return new PublicCommandFailure({ kind: "endpoint_stale", proof: "pre-effect" });
|
|
444
|
+
case "authorization_denied":
|
|
445
|
+
case "unauthorized":
|
|
446
|
+
case "forbidden":
|
|
447
|
+
case "master_context_required":
|
|
448
|
+
case "adapter_operation_prohibited":
|
|
449
|
+
case "endpoint_credential_forbidden":
|
|
450
|
+
return new PublicCommandFailure({ kind: "authorization_denied", proof: "pre-effect" });
|
|
451
|
+
case "timeout":
|
|
452
|
+
return new PublicCommandFailure({ kind: "timeout", proof: "unknown" });
|
|
453
|
+
case "unavailable":
|
|
454
|
+
return new PublicCommandFailure({ kind: "unavailable", proof: "unknown" });
|
|
455
|
+
case "uncertain_after_send":
|
|
456
|
+
return new PublicCommandFailure({ kind: "uncertain_after_send", proof: "sent" });
|
|
457
|
+
default:
|
|
458
|
+
return normalizePublicCommandFailure(error);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/** Bounded dependency seam for preflight tests; production keeps the same transport factories. */
|
|
463
|
+
export interface SdkServeDependencies {
|
|
464
|
+
readDiscovery: (agentDir: string) => Promise<{ url: string; token: string } | null>;
|
|
465
|
+
connect: (url: string, token: string) => Promise<Pick<SdkClient, "global" | "close">>;
|
|
466
|
+
startStdio: typeof startStdioServe;
|
|
467
|
+
startSocket: typeof startSocketServe;
|
|
468
|
+
}
|
|
469
|
+
|
|
211
470
|
/**
|
|
212
471
|
* Attaches a stdio or Unix-socket relay to one live SDK session endpoint.
|
|
213
472
|
* Session targeting is broker-bound (C10): `session.list` resolves the session
|
|
214
473
|
* and `session.get_endpoint` mints the exact credential — never a direct
|
|
215
474
|
* endpoint-file read. A missing or unreachable broker fails closed.
|
|
216
475
|
*/
|
|
217
|
-
export async function runSdkServe(argv: string[]): Promise<void> {
|
|
476
|
+
export async function runSdkServe(argv: string[], dependencies?: SdkServeDependencies): Promise<void> {
|
|
477
|
+
if (dependencies !== undefined) {
|
|
478
|
+
await runSdkServePublic(argv, dependencies);
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
await runSdkServeTyped(argv);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/** Public-boundary adapter used by dependency-injected preflight tests and the CLI scanner. */
|
|
485
|
+
async function runSdkServePublic(argv: string[], dependencies: SdkServeDependencies): Promise<void> {
|
|
486
|
+
let broker: Pick<SdkClient, "global" | "close"> | undefined;
|
|
487
|
+
let transport: ServeHandle | undefined;
|
|
488
|
+
try {
|
|
489
|
+
const parsed = parseServeArguments(argv);
|
|
490
|
+
if (parsed.mode.kind === "socket" && process.platform === "win32")
|
|
491
|
+
throw new PublicCommandFailure({ kind: "unavailable", proof: "pre-effect" });
|
|
492
|
+
const pendingCeilingBytes = resolveServePendingCeiling(
|
|
493
|
+
parsed.pendingCeiling,
|
|
494
|
+
process.env.GJC_SDK_SERVE_PENDING_CEILING_BYTES,
|
|
495
|
+
);
|
|
496
|
+
const discovery = await dependencies.readDiscovery(getAgentDir());
|
|
497
|
+
if (!discovery) throw new PublicCommandFailure({ kind: "broker_unavailable", proof: "pre-effect" });
|
|
498
|
+
try {
|
|
499
|
+
broker = await dependencies.connect(discovery.url, discovery.token);
|
|
500
|
+
} catch (error) {
|
|
501
|
+
if (error instanceof SdkClientError || error instanceof PublicCommandFailure) throw error;
|
|
502
|
+
throw new PublicCommandFailure({ kind: "broker_unavailable", proof: "pre-effect" });
|
|
503
|
+
}
|
|
504
|
+
const sessionId = selectBrokerSession(await listBrokerSessions(broker, parsed.sessionId), parsed.sessionId);
|
|
505
|
+
const endpoint = brokerResult(await broker.global("session.get_endpoint", { sessionId }));
|
|
506
|
+
const url = typeof endpoint.url === "string" && endpoint.url ? endpoint.url : undefined;
|
|
507
|
+
const token = typeof endpoint.token === "string" ? endpoint.token : "";
|
|
508
|
+
// An endpoint without its minted credential cannot authenticate any relayed
|
|
509
|
+
// client, so starting the listener would advertise a serve that always fails.
|
|
510
|
+
if (!url || !token) throw new PublicCommandFailure({ kind: "unavailable", proof: "pre-effect" });
|
|
511
|
+
const options = { url, token, pendingCeilingBytes };
|
|
512
|
+
transport =
|
|
513
|
+
parsed.mode.kind === "stdio"
|
|
514
|
+
? await dependencies.startStdio(options)
|
|
515
|
+
: await dependencies.startSocket({ ...options, socketPath: parsed.mode.socketPath });
|
|
516
|
+
} catch (error) {
|
|
517
|
+
// No transport handle has transferred ownership. Cleanup diagnostics are
|
|
518
|
+
// attached to the original failure instance, never substituted for it, and
|
|
519
|
+
// broker credentials never reach a raw error.
|
|
520
|
+
const failure = servePreflightFailure(error);
|
|
521
|
+
try {
|
|
522
|
+
await broker?.close();
|
|
523
|
+
} catch {
|
|
524
|
+
failure.input.diagnostics = [...(failure.input.diagnostics ?? []), "broker_cleanup_failed"];
|
|
525
|
+
}
|
|
526
|
+
throw failure;
|
|
527
|
+
}
|
|
528
|
+
await ownSdkServeTransport(transport!, () => broker!.close());
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/** Native serve path: operational failures remain typed for direct SDK embedders. */
|
|
532
|
+
async function runSdkServeTyped(argv: string[]): Promise<void> {
|
|
218
533
|
const parsed = parseServeArguments(argv);
|
|
219
534
|
if (parsed.mode.kind === "socket" && process.platform === "win32")
|
|
220
535
|
throw new SdkServeError("unsupported_platform", "--socket is unavailable on Windows.", 1);
|
|
@@ -231,8 +546,9 @@ export async function runSdkServe(argv: string[]): Promise<void> {
|
|
|
231
546
|
throw new SdkServeError("broker_unavailable", "SDK broker is not reachable", 1);
|
|
232
547
|
}
|
|
233
548
|
let primary: Error | undefined;
|
|
549
|
+
let transport: ServeHandle | undefined;
|
|
234
550
|
try {
|
|
235
|
-
const sessionId =
|
|
551
|
+
const sessionId = await resolveServeSession(broker, parsed.sessionId);
|
|
236
552
|
const endpoint = brokerResult(await broker.global("session.get_endpoint", { sessionId }));
|
|
237
553
|
const url = typeof endpoint.url === "string" && endpoint.url ? endpoint.url : undefined;
|
|
238
554
|
const token = typeof endpoint.token === "string" && endpoint.token ? endpoint.token : undefined;
|
|
@@ -241,26 +557,65 @@ export async function runSdkServe(argv: string[]): Promise<void> {
|
|
|
241
557
|
// connection failure and this stable malformed-endpoint code is lost.
|
|
242
558
|
if (!url || !token) throw new SdkServeError("unavailable", "broker returned an invalid endpoint record", 1);
|
|
243
559
|
const options = { url, token, pendingCeilingBytes };
|
|
244
|
-
|
|
560
|
+
transport =
|
|
245
561
|
parsed.mode.kind === "stdio"
|
|
246
562
|
? await startStdioServe(options)
|
|
247
563
|
: await startSocketServe({ ...options, socketPath: parsed.mode.socketPath });
|
|
248
|
-
const stop = () => {
|
|
249
|
-
void handle.close();
|
|
250
|
-
};
|
|
251
|
-
process.once("SIGINT", stop);
|
|
252
|
-
process.once("SIGTERM", stop);
|
|
253
|
-
try {
|
|
254
|
-
await handle.done;
|
|
255
|
-
} finally {
|
|
256
|
-
process.removeListener("SIGINT", stop);
|
|
257
|
-
process.removeListener("SIGTERM", stop);
|
|
258
|
-
}
|
|
259
564
|
} catch (error) {
|
|
260
565
|
primary = toServeError(error);
|
|
261
566
|
}
|
|
567
|
+
if (transport) {
|
|
568
|
+
// Once the relay owns stdout, post-start failures must never cross back into
|
|
569
|
+
// the public command renderer. That boundary writes JSON to stdout, which is
|
|
570
|
+
// the stdio frame channel; the transport owner reports only a fixed stderr
|
|
571
|
+
// diagnostic and exit status instead.
|
|
572
|
+
await ownSdkServeTransport(transport, () => broker.close());
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
262
575
|
// Teardown always runs, but never through a `finally` throw: a rejected
|
|
263
|
-
//
|
|
576
|
+
// broker.close() there would replace the typed failure with its own.
|
|
264
577
|
const failure = resolveServeOutcome(primary, await brokerCloseFailure(broker));
|
|
265
578
|
if (failure) throw failure;
|
|
266
579
|
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Acquiring a ServeHandle transfers output/termination ownership to transport.
|
|
583
|
+
* This boundary never rejects into the ordinary public command writer, even
|
|
584
|
+
* when no frame has been written. Raw relay framing remains transport-owned.
|
|
585
|
+
*/
|
|
586
|
+
export async function ownSdkServeTransport(handle: ServeHandle, closeBroker: () => Promise<void>): Promise<void> {
|
|
587
|
+
let failed = false;
|
|
588
|
+
const reportFailure = (): void => {
|
|
589
|
+
process.exitCode = 1;
|
|
590
|
+
if (failed) return;
|
|
591
|
+
failed = true;
|
|
592
|
+
try {
|
|
593
|
+
process.stderr.write(`${JSON.stringify({ type: "transport_error", code: "serve_failed" })}\n`);
|
|
594
|
+
} catch {
|
|
595
|
+
// A broken diagnostic stream cannot transfer ownership back to the CLI.
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
const stop = (): void => {
|
|
599
|
+
void handle.close().catch(reportFailure);
|
|
600
|
+
};
|
|
601
|
+
try {
|
|
602
|
+
process.once("SIGINT", stop);
|
|
603
|
+
process.once("SIGTERM", stop);
|
|
604
|
+
await handle.done;
|
|
605
|
+
} catch {
|
|
606
|
+
reportFailure();
|
|
607
|
+
} finally {
|
|
608
|
+
process.removeListener("SIGINT", stop);
|
|
609
|
+
process.removeListener("SIGTERM", stop);
|
|
610
|
+
try {
|
|
611
|
+
await handle.close();
|
|
612
|
+
} catch {
|
|
613
|
+
reportFailure();
|
|
614
|
+
}
|
|
615
|
+
try {
|
|
616
|
+
await closeBroker();
|
|
617
|
+
} catch {
|
|
618
|
+
reportFailure();
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
@@ -177,20 +177,21 @@ export async function startSocketServe(
|
|
|
177
177
|
void task;
|
|
178
178
|
});
|
|
179
179
|
server.on("error", error => void close(error).catch(() => undefined));
|
|
180
|
-
await new Promise<void>((resolve, reject) => {
|
|
181
|
-
server?.once("error", reject);
|
|
182
|
-
server?.listen(options.socketPath, () => resolve());
|
|
183
|
-
});
|
|
184
|
-
const bound = await fs.lstat(options.socketPath);
|
|
185
|
-
if (!bound.isSocket()) {
|
|
186
|
-
await close();
|
|
187
|
-
throw socketFailure("socket_bind_failed");
|
|
188
|
-
}
|
|
189
|
-
ownedIdentity = { dev: bound.dev, ino: bound.ino };
|
|
190
180
|
try {
|
|
181
|
+
await new Promise<void>((resolve, reject) => {
|
|
182
|
+
server?.once("error", reject);
|
|
183
|
+
server?.listen(options.socketPath, () => resolve());
|
|
184
|
+
});
|
|
185
|
+
const bound = await fs.lstat(options.socketPath);
|
|
186
|
+
if (!bound.isSocket()) throw socketFailure("socket_bind_failed");
|
|
187
|
+
ownedIdentity = { dev: bound.dev, ino: bound.ino };
|
|
191
188
|
await fs.chmod(options.socketPath, 0o600);
|
|
192
189
|
} catch (error) {
|
|
193
|
-
|
|
190
|
+
try {
|
|
191
|
+
await close();
|
|
192
|
+
} catch (cleanupError) {
|
|
193
|
+
throw new AggregateError([error, cleanupError], "socket_serve_startup_cleanup_failed", { cause: error });
|
|
194
|
+
}
|
|
194
195
|
throw error;
|
|
195
196
|
}
|
|
196
197
|
return { close, done: done.promise };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Readable, Writable } from "node:stream";
|
|
1
2
|
import type { ServeHandle, ServeOptions } from "./index";
|
|
2
3
|
import { startRelayPair } from "./relay";
|
|
3
4
|
|
|
@@ -6,11 +7,14 @@ function writeDiagnostic(value: unknown): void {
|
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
/** Serves one parent-owned JSONL connection over the process standard streams. */
|
|
9
|
-
export async function startStdioServe(
|
|
10
|
+
export async function startStdioServe(
|
|
11
|
+
options: ServeOptions,
|
|
12
|
+
streams: { readonly input?: Readable; readonly output?: Writable } = {},
|
|
13
|
+
): Promise<ServeHandle> {
|
|
10
14
|
const pair = await startRelayPair({
|
|
11
15
|
...options,
|
|
12
|
-
downstream: process.stdin,
|
|
13
|
-
downstreamSink: process.stdout,
|
|
16
|
+
downstream: streams.input ?? process.stdin,
|
|
17
|
+
downstreamSink: streams.output ?? process.stdout,
|
|
14
18
|
onTransportError: writeDiagnostic,
|
|
15
19
|
});
|
|
16
20
|
return { close: pair.close, done: pair.done };
|