@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
package/src/cli/mcp-cli.ts
CHANGED
|
@@ -19,7 +19,13 @@ import {
|
|
|
19
19
|
resolveScopeMCPConfigPath,
|
|
20
20
|
upsertScopeMCPServer,
|
|
21
21
|
} from "../runtime-mcp/scope-config";
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
type AutoloadStatus,
|
|
24
|
+
computeAutoloadStatus,
|
|
25
|
+
DEFAULT_MCP_STARTUP_WAIT_MS,
|
|
26
|
+
MAX_MCP_STARTUP_WAIT_MS,
|
|
27
|
+
MCP_STARTUP_WAIT_GRACE_MS,
|
|
28
|
+
} from "../runtime-mcp/startup-policy";
|
|
23
29
|
import type { MCPServerConfig } from "../runtime-mcp/types";
|
|
24
30
|
|
|
25
31
|
export type MCPAction = "add" | "list" | "remove";
|
|
@@ -64,6 +70,8 @@ interface RuntimeServerEntry extends RedactedServerEntry {
|
|
|
64
70
|
runtimeStatus: AutoloadStatus;
|
|
65
71
|
/** Human-readable explanation of the runtime status. */
|
|
66
72
|
runtimeNote: string;
|
|
73
|
+
/** Actionable guidance when startup can disconnect an untimed registration. */
|
|
74
|
+
startupDiagnostic?: string;
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
const REDACTED = "<redacted>";
|
|
@@ -90,6 +98,18 @@ function autoloadStatusNote(status: AutoloadStatus): string {
|
|
|
90
98
|
}
|
|
91
99
|
}
|
|
92
100
|
|
|
101
|
+
function startupDiagnostic(config: MCPServerConfig, status: AutoloadStatus): string | undefined {
|
|
102
|
+
if (status !== "autoload") return undefined;
|
|
103
|
+
const timeout = config.timeout;
|
|
104
|
+
if (typeof timeout === "number" && Number.isFinite(timeout) && timeout > 0) return undefined;
|
|
105
|
+
return (
|
|
106
|
+
`No per-server timeout is declared. Ordinary standalone sessions wait ${DEFAULT_MCP_STARTUP_WAIT_MS}ms when no ` +
|
|
107
|
+
`registration declares a positive timeout; otherwise the batch wait uses the largest declared timeout plus ` +
|
|
108
|
+
`${MCP_STARTUP_WAIT_GRACE_MS}ms grace, capped at ${MAX_MCP_STARTUP_WAIT_MS}ms. Unfinished connections are ` +
|
|
109
|
+
"disconnected; add --timeout <ms> when registering slower servers."
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
93
113
|
function resolvePath(args: MCPCommandArgs): ScopedPath {
|
|
94
114
|
const scope: MCPConfigScope = args.flags.project ? "project" : "user";
|
|
95
115
|
return { scope, path: resolveScopeMCPConfigPath(scope, args.cwd ?? getProjectDir()) };
|
|
@@ -243,8 +263,14 @@ export function redactMCPServerConfig(config: MCPServerConfig): MCPServerConfig
|
|
|
243
263
|
function withRuntimeDisclosure<T extends object>(
|
|
244
264
|
value: T,
|
|
245
265
|
status: AutoloadStatus,
|
|
266
|
+
diagnostic?: string,
|
|
246
267
|
): T & { runtimeStatus: AutoloadStatus; runtimeNote: string } {
|
|
247
|
-
return {
|
|
268
|
+
return {
|
|
269
|
+
...value,
|
|
270
|
+
runtimeStatus: status,
|
|
271
|
+
runtimeNote: autoloadStatusNote(status),
|
|
272
|
+
...(diagnostic === undefined ? {} : { startupDiagnostic: diagnostic }),
|
|
273
|
+
};
|
|
248
274
|
}
|
|
249
275
|
|
|
250
276
|
async function collectEntries(scoped: ScopedPath, cwd?: string): Promise<RuntimeServerEntry[]> {
|
|
@@ -257,12 +283,14 @@ async function collectEntries(scoped: ScopedPath, cwd?: string): Promise<Runtime
|
|
|
257
283
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
258
284
|
.map(([name, serverConfig]) => {
|
|
259
285
|
const runtimeStatus = computeAutoloadStatus(name, serverConfig, disabledSet);
|
|
286
|
+
const diagnostic = startupDiagnostic(serverConfig, runtimeStatus);
|
|
260
287
|
return {
|
|
261
288
|
name,
|
|
262
289
|
scope: scoped.scope,
|
|
263
290
|
path: scoped.path,
|
|
264
291
|
runtimeStatus,
|
|
265
292
|
runtimeNote: autoloadStatusNote(runtimeStatus),
|
|
293
|
+
...(diagnostic === undefined ? {} : { startupDiagnostic: diagnostic }),
|
|
266
294
|
config: redactMCPServerConfig(serverConfig),
|
|
267
295
|
};
|
|
268
296
|
});
|
|
@@ -297,9 +325,11 @@ async function runAdd(args: MCPCommandArgs, scoped: ScopedPath): Promise<void> {
|
|
|
297
325
|
},
|
|
298
326
|
args.cwd,
|
|
299
327
|
);
|
|
300
|
-
const
|
|
328
|
+
const disclosedConfig = result.status === "skipped" ? (storedConfig.mcpServers?.[args.name] ?? config) : config;
|
|
329
|
+
const redacted = redactMCPServerConfig(disclosedConfig);
|
|
301
330
|
const disabled = new Set(storedConfig.disabledServers ?? (await readScopeDisabledServers(scoped.scope, args.cwd)));
|
|
302
|
-
const runtimeStatus = computeAutoloadStatus(args.name,
|
|
331
|
+
const runtimeStatus = computeAutoloadStatus(args.name, disclosedConfig, disabled);
|
|
332
|
+
const diagnostic = startupDiagnostic(disclosedConfig, runtimeStatus);
|
|
303
333
|
if (args.flags.json) {
|
|
304
334
|
writeJson(
|
|
305
335
|
withRuntimeDisclosure(
|
|
@@ -312,6 +342,7 @@ async function runAdd(args: MCPCommandArgs, scoped: ScopedPath): Promise<void> {
|
|
|
312
342
|
config: redacted,
|
|
313
343
|
},
|
|
314
344
|
runtimeStatus,
|
|
345
|
+
diagnostic,
|
|
315
346
|
),
|
|
316
347
|
);
|
|
317
348
|
return;
|
|
@@ -321,12 +352,14 @@ async function runAdd(args: MCPCommandArgs, scoped: ScopedPath): Promise<void> {
|
|
|
321
352
|
`MCP server "${args.name}" already exists in ${scoped.scope} config. Pass --force to overwrite. ` +
|
|
322
353
|
`Runtime: ${autoloadStatusNote(runtimeStatus)}\n`,
|
|
323
354
|
);
|
|
355
|
+
if (diagnostic) process.stdout.write(`Startup: ${diagnostic}\n`);
|
|
324
356
|
return;
|
|
325
357
|
}
|
|
326
358
|
process.stdout.write(
|
|
327
359
|
`MCP server "${args.name}" ${result.status} in ${scoped.scope} config: ${scoped.path}\n` +
|
|
328
360
|
`Runtime: ${autoloadStatusNote(runtimeStatus)}\n`,
|
|
329
361
|
);
|
|
362
|
+
if (diagnostic) process.stdout.write(`Startup: ${diagnostic}\n`);
|
|
330
363
|
}
|
|
331
364
|
|
|
332
365
|
async function runList(args: MCPCommandArgs, scoped: ScopedPath): Promise<void> {
|
|
@@ -348,6 +381,7 @@ async function runList(args: MCPCommandArgs, scoped: ScopedPath): Promise<void>
|
|
|
348
381
|
for (const entry of entries) {
|
|
349
382
|
process.stdout.write(`${renderDetails(entry)}\n`);
|
|
350
383
|
process.stdout.write(`Runtime: ${entry.runtimeNote}\n`);
|
|
384
|
+
if (entry.startupDiagnostic) process.stdout.write(`Startup: ${entry.startupDiagnostic}\n`);
|
|
351
385
|
}
|
|
352
386
|
}
|
|
353
387
|
|
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { CliParseError, type CommandCtor, type CommandEntryContext } from "@gajae-code/utils/cli";
|
|
3
|
+
import { getAgentDir } from "@gajae-code/utils/dirs";
|
|
4
|
+
import {
|
|
5
|
+
PublicCommandFailure,
|
|
6
|
+
renderPublicCommandFailure,
|
|
7
|
+
renderPublicEvidenceUnavailable,
|
|
8
|
+
} from "./public-command-errors";
|
|
9
|
+
import { EVIDENCE_LIMITS, type EvidencePage, readCommandEvidence } from "./public-command-evidence";
|
|
10
|
+
import { PublicHelpError, renderPublicCommandHelp } from "./public-command-help";
|
|
11
|
+
import {
|
|
12
|
+
getPublicCommand,
|
|
13
|
+
type PublicCommandDescriptor,
|
|
14
|
+
type PublicCommandFamily,
|
|
15
|
+
type PublicFlagDescriptor,
|
|
16
|
+
type PublicHelpSection,
|
|
17
|
+
} from "./public-command-registry";
|
|
18
|
+
|
|
19
|
+
export type PublicUsageIssueCode =
|
|
20
|
+
| "unknown-path"
|
|
21
|
+
| "unknown-flag"
|
|
22
|
+
| "missing-value"
|
|
23
|
+
| "invalid-value"
|
|
24
|
+
| "duplicate-flag"
|
|
25
|
+
| "missing-flag"
|
|
26
|
+
| "missing-argument"
|
|
27
|
+
| "unexpected-argument"
|
|
28
|
+
| "conflict"
|
|
29
|
+
| "requires"
|
|
30
|
+
| "exclusive";
|
|
31
|
+
/** Only descriptor-owned names and static messages are safe for output. Never include argv values. */
|
|
32
|
+
export interface PublicUsageIssue {
|
|
33
|
+
code: PublicUsageIssueCode;
|
|
34
|
+
message: string;
|
|
35
|
+
field?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface PublicHelpOptions {
|
|
38
|
+
section: PublicHelpSection;
|
|
39
|
+
page: number;
|
|
40
|
+
revision?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface PublicRetrievalOptions {
|
|
43
|
+
id: string;
|
|
44
|
+
sha256: string;
|
|
45
|
+
page: number;
|
|
46
|
+
agentDir?: string;
|
|
47
|
+
}
|
|
48
|
+
interface PublicScanBase {
|
|
49
|
+
descriptor: PublicCommandDescriptor;
|
|
50
|
+
mode: "text" | "json";
|
|
51
|
+
args: Record<string, string | string[] | undefined>;
|
|
52
|
+
flags: Record<string, unknown>;
|
|
53
|
+
/** Family-relative argv, retaining child paths and operation tokens in their original order. */
|
|
54
|
+
operationArgv: string[];
|
|
55
|
+
help: PublicHelpOptions;
|
|
56
|
+
retrieval?: PublicRetrievalOptions;
|
|
57
|
+
}
|
|
58
|
+
export type PublicCommandScan = PublicScanBase &
|
|
59
|
+
({ kind: "usage"; issues: PublicUsageIssue[] } | { kind: "help" | "retrieval" | "operation"; issues: [] });
|
|
60
|
+
|
|
61
|
+
function validValue(value: string, flag: PublicFlagDescriptor): boolean {
|
|
62
|
+
if (flag.options && !flag.options.includes(value)) return false;
|
|
63
|
+
if (flag.kind === "integer" && (!/^-?\d+$/.test(value) || !Number.isSafeInteger(Number(value)))) return false;
|
|
64
|
+
switch (flag.validation) {
|
|
65
|
+
case "sha256":
|
|
66
|
+
return /^[a-f0-9]{64}$/.test(value);
|
|
67
|
+
case "error-id":
|
|
68
|
+
return /^[a-f0-9]{32}$/.test(value);
|
|
69
|
+
case "positive-safe-integer":
|
|
70
|
+
return /^\d+$/.test(value) && Number.isSafeInteger(Number(value)) && Number(value) > 0;
|
|
71
|
+
case "search-limit":
|
|
72
|
+
return /^\d+$/.test(value) && Number(value) >= 1 && Number(value) <= 100;
|
|
73
|
+
case "pending-ceiling":
|
|
74
|
+
return /^\d+$/.test(value) && Number.isSafeInteger(Number(value)) && Number(value) >= 262144;
|
|
75
|
+
default:
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Inert, descriptor-driven scanner. argv excludes the already resolved family token. */
|
|
81
|
+
export function scanPublicCommand(family: PublicCommandFamily, argv: readonly string[]): PublicCommandScan {
|
|
82
|
+
let descriptor = getPublicCommand([family])!;
|
|
83
|
+
const flags: Record<string, unknown> = {};
|
|
84
|
+
const args: PublicScanBase["args"] = {};
|
|
85
|
+
const seen = new Set<string>();
|
|
86
|
+
const operationArgv: string[] = [];
|
|
87
|
+
const positionals: string[] = [];
|
|
88
|
+
const issues: PublicUsageIssue[] = [];
|
|
89
|
+
let mode: PublicScanBase["mode"] = "text";
|
|
90
|
+
let helpRequested = false;
|
|
91
|
+
let retrievalRequested = false;
|
|
92
|
+
let ended = false;
|
|
93
|
+
let pathClosed = false;
|
|
94
|
+
const issue = (code: PublicUsageIssueCode, message: string, field?: string) => {
|
|
95
|
+
if (!issues.some(item => item.code === code && item.field === field))
|
|
96
|
+
issues.push({ code, message, ...(field ? { field } : {}) });
|
|
97
|
+
};
|
|
98
|
+
if (
|
|
99
|
+
family === "daemon" &&
|
|
100
|
+
(argv[0] === "discord-internal" || argv[0] === "slack-internal") &&
|
|
101
|
+
!isDaemonInternalArgv(argv)
|
|
102
|
+
)
|
|
103
|
+
issue("unknown-path", "Private daemon worker arguments are invalid.");
|
|
104
|
+
const consumeFlag = (name: string, flag: PublicFlagDescriptor, value: string | undefined, inline: boolean): void => {
|
|
105
|
+
if (seen.has(name) && (flag.boundary || descriptor.command.join(" ") === "sdk serve") && !flag.multiple)
|
|
106
|
+
issue("duplicate-flag", "Option must occur only once.", name);
|
|
107
|
+
seen.add(name);
|
|
108
|
+
if (flag.boundary === "retrieval") retrievalRequested = true;
|
|
109
|
+
if (flag.kind === "boolean") {
|
|
110
|
+
if (inline) {
|
|
111
|
+
issue("invalid-value", "Boolean option does not accept an operand.", name);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
flags[name] = true;
|
|
115
|
+
if (name === "json") mode = "json";
|
|
116
|
+
if (name === "help") helpRequested = true;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (value === undefined) {
|
|
120
|
+
issue("missing-value", "Option requires an operand.", name);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (inline && flag.valueSyntax === "separate")
|
|
124
|
+
issue("invalid-value", "Option requires a separate operand.", name);
|
|
125
|
+
if (!validValue(value, flag)) issue("invalid-value", "Option operand is invalid.", name);
|
|
126
|
+
const parsed = flag.kind === "integer" ? Number(value) : value;
|
|
127
|
+
flags[name] = flag.multiple
|
|
128
|
+
? [...(Array.isArray(flags[name]) ? (flags[name] as unknown[]) : []), parsed]
|
|
129
|
+
: parsed;
|
|
130
|
+
};
|
|
131
|
+
for (let index = 0; index < argv.length; index++) {
|
|
132
|
+
const token = argv[index]!;
|
|
133
|
+
if (!ended && token === "--") {
|
|
134
|
+
ended = true;
|
|
135
|
+
pathClosed = true;
|
|
136
|
+
operationArgv.push(token);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (!ended && token.startsWith("-") && token !== "-") {
|
|
140
|
+
const start = index;
|
|
141
|
+
let keep = false;
|
|
142
|
+
const long = token.startsWith("--");
|
|
143
|
+
const equals = long ? token.indexOf("=") : -1;
|
|
144
|
+
const names = long ? [token.slice(2, equals < 0 ? undefined : equals)] : token.slice(1).split("");
|
|
145
|
+
const shortOperationTokens: string[] = [];
|
|
146
|
+
for (let shortIndex = 0; shortIndex < names.length; shortIndex++) {
|
|
147
|
+
const rawName = names[shortIndex]!;
|
|
148
|
+
const name = long
|
|
149
|
+
? rawName
|
|
150
|
+
: Object.keys(descriptor.flags).find(key => descriptor.flags[key]!.char === rawName);
|
|
151
|
+
const flag =
|
|
152
|
+
name === undefined
|
|
153
|
+
? undefined
|
|
154
|
+
: Object.hasOwn(descriptor.flags, name)
|
|
155
|
+
? descriptor.flags[name]
|
|
156
|
+
: undefined;
|
|
157
|
+
if (!name || !flag) {
|
|
158
|
+
issue("unknown-flag", "Unknown option for this command.");
|
|
159
|
+
keep = true;
|
|
160
|
+
if (!long) shortOperationTokens.push(`-${rawName}`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (!flag.boundary) keep = true;
|
|
164
|
+
let inline = long && equals >= 0;
|
|
165
|
+
let value = inline ? token.slice(equals + 1) : undefined;
|
|
166
|
+
if (flag.kind !== "boolean") {
|
|
167
|
+
if (!long && shortIndex + 1 < names.length) {
|
|
168
|
+
inline = true;
|
|
169
|
+
value = names.slice(shortIndex + 1).join("");
|
|
170
|
+
shortIndex = names.length;
|
|
171
|
+
}
|
|
172
|
+
if (
|
|
173
|
+
!inline &&
|
|
174
|
+
argv[index + 1] !== undefined &&
|
|
175
|
+
(argv[index + 1] === "-" || !argv[index + 1]!.startsWith("-"))
|
|
176
|
+
)
|
|
177
|
+
value = argv[++index];
|
|
178
|
+
}
|
|
179
|
+
consumeFlag(name, flag, value, inline);
|
|
180
|
+
if (!long && !flag.boundary) {
|
|
181
|
+
shortOperationTokens.push(`-${rawName}${inline ? (value ?? "") : ""}`);
|
|
182
|
+
if (!inline && value !== undefined) shortOperationTokens.push(value);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (keep) {
|
|
186
|
+
// Split short clusters so boundary characters cannot reach the operation parser.
|
|
187
|
+
if (!long) operationArgv.push(...shortOperationTokens);
|
|
188
|
+
else operationArgv.push(...argv.slice(start, index + 1));
|
|
189
|
+
}
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (!pathClosed && descriptor.children.includes(token)) {
|
|
193
|
+
descriptor = getPublicCommand([...descriptor.command, token])!;
|
|
194
|
+
operationArgv.push(token);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
pathClosed = true;
|
|
198
|
+
positionals.push(token);
|
|
199
|
+
operationArgv.push(token);
|
|
200
|
+
if (descriptor.children.length && !descriptor.defaultChild) issue("unknown-path", "Unknown command path.");
|
|
201
|
+
}
|
|
202
|
+
for (const [name, flag] of Object.entries(descriptor.flags)) {
|
|
203
|
+
if (flags[name] === undefined && flag.default !== undefined) flags[name] = flag.default;
|
|
204
|
+
if (!helpRequested && !retrievalRequested && flag.required && !seen.has(name))
|
|
205
|
+
issue("missing-flag", "Required option is missing.", name);
|
|
206
|
+
if (!seen.has(name)) continue;
|
|
207
|
+
for (const required of flag.requires ?? [])
|
|
208
|
+
if (!seen.has(required)) issue("requires", "Option requires another option.", name);
|
|
209
|
+
for (const conflict of flag.conflicts ?? [])
|
|
210
|
+
if (seen.has(conflict)) issue("conflict", "Options are mutually exclusive.", name);
|
|
211
|
+
}
|
|
212
|
+
let positionalIndex = 0;
|
|
213
|
+
for (const [name, arg] of Object.entries(descriptor.args)) {
|
|
214
|
+
const values = arg.multiple
|
|
215
|
+
? positionals.slice(positionalIndex)
|
|
216
|
+
: positionals.slice(positionalIndex, positionalIndex + 1);
|
|
217
|
+
positionalIndex += values.length;
|
|
218
|
+
args[name] = arg.multiple ? (values.length ? values : undefined) : values[0];
|
|
219
|
+
if (!helpRequested && !retrievalRequested && arg.required && !values.length)
|
|
220
|
+
issue("missing-argument", "Required argument is missing.", name);
|
|
221
|
+
// Daemon kind choices are help metadata; runtime owns unknown-kind exit 1.
|
|
222
|
+
if (
|
|
223
|
+
!(descriptor.command[0] === "daemon" && name === "kind") &&
|
|
224
|
+
arg.options &&
|
|
225
|
+
values.some(value => !arg.options!.includes(value))
|
|
226
|
+
)
|
|
227
|
+
issue("invalid-value", "Argument value is invalid.", name);
|
|
228
|
+
}
|
|
229
|
+
if (positionalIndex < positionals.length && !issues.some(item => item.code === "unknown-path"))
|
|
230
|
+
issue("unexpected-argument", "Unexpected argument for this command.");
|
|
231
|
+
if (!helpRequested && !retrievalRequested) {
|
|
232
|
+
if (descriptor.children.length && !descriptor.defaultChild && !positionals.length)
|
|
233
|
+
issue("unknown-path", "A child command is required.");
|
|
234
|
+
for (const group of descriptor.exactlyOneOf ?? [])
|
|
235
|
+
if (group.filter(name => seen.has(name)).length !== 1)
|
|
236
|
+
issue("exclusive", "Exactly one transport option is required.");
|
|
237
|
+
}
|
|
238
|
+
if (retrievalRequested && (descriptor.command.length !== 1 || helpRequested || operationArgv.length > 0))
|
|
239
|
+
issue("exclusive", "Evidence retrieval is exclusive with help and operations.");
|
|
240
|
+
// Root selectors consumed before a child must still be rejected on that child.
|
|
241
|
+
for (const name of seen)
|
|
242
|
+
if (!Object.hasOwn(descriptor.flags, name)) issue("unknown-flag", "Option is not available on this command.");
|
|
243
|
+
const help: PublicHelpOptions = {
|
|
244
|
+
section: (flags["help-section"] ?? "overview") as PublicHelpSection,
|
|
245
|
+
page: Number(flags["help-page"] ?? 1),
|
|
246
|
+
...(typeof flags["help-revision"] === "string" ? { revision: flags["help-revision"] } : {}),
|
|
247
|
+
};
|
|
248
|
+
const retrieval = retrievalRequested
|
|
249
|
+
? {
|
|
250
|
+
id: String(flags["error-ref"] ?? ""),
|
|
251
|
+
sha256: String(flags["error-sha256"] ?? ""),
|
|
252
|
+
page: Number(flags["error-page"] ?? 1),
|
|
253
|
+
...(typeof flags["error-agent-dir"] === "string" ? { agentDir: flags["error-agent-dir"] } : {}),
|
|
254
|
+
}
|
|
255
|
+
: undefined;
|
|
256
|
+
const base: PublicScanBase = {
|
|
257
|
+
descriptor,
|
|
258
|
+
mode,
|
|
259
|
+
args,
|
|
260
|
+
flags,
|
|
261
|
+
operationArgv,
|
|
262
|
+
help,
|
|
263
|
+
...(retrieval ? { retrieval } : {}),
|
|
264
|
+
};
|
|
265
|
+
if (issues.length) return { ...base, kind: "usage", issues };
|
|
266
|
+
return { ...base, kind: retrievalRequested ? "retrieval" : helpRequested ? "help" : "operation", issues: [] };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export interface PublicCommandDispatchContext extends CommandEntryContext {
|
|
270
|
+
command: PublicCommandFamily;
|
|
271
|
+
load: () => Promise<CommandCtor>;
|
|
272
|
+
/** Only operations may initialize settings, transports, themes or runtime globals. */
|
|
273
|
+
setup?: (report: (diagnostic: { code: "macos_nofile_limit_low"; successStderr: string }) => void) => Promise<void>;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export function isSafeSdkInternalAgentDir(value: string): boolean {
|
|
277
|
+
return (
|
|
278
|
+
value.length > 0 &&
|
|
279
|
+
value.length <= 4096 &&
|
|
280
|
+
path.isAbsolute(value) &&
|
|
281
|
+
!value.startsWith("-") &&
|
|
282
|
+
!/[\x00-\x1f\x7f-\x9f\u2028\u2029]/u.test(value)
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** Mirrors commands/sdk.ts parseSdkInternalArgv without eagerly loading its runtime. */
|
|
287
|
+
export function isSdkInternalArgv(argv: readonly string[]): boolean {
|
|
288
|
+
return (
|
|
289
|
+
(argv[0] === "session-host-internal" && argv.length === 1) ||
|
|
290
|
+
(argv[0] === "broker-internal" &&
|
|
291
|
+
argv.length === 3 &&
|
|
292
|
+
argv[1] === "--agent-dir" &&
|
|
293
|
+
typeof argv[2] === "string" &&
|
|
294
|
+
isSafeSdkInternalAgentDir(argv[2]))
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** Mirrors the exact private argv emitted by chat-daemon controller spawns. */
|
|
299
|
+
export function isDaemonInternalArgv(argv: readonly string[]): boolean {
|
|
300
|
+
const ownerId = argv[2];
|
|
301
|
+
return (
|
|
302
|
+
argv.length === 5 &&
|
|
303
|
+
(argv[0] === "discord-internal" || argv[0] === "slack-internal") &&
|
|
304
|
+
argv[1] === "--owner-id" &&
|
|
305
|
+
typeof ownerId === "string" &&
|
|
306
|
+
ownerId.length > 0 &&
|
|
307
|
+
ownerId.length <= 1024 &&
|
|
308
|
+
!ownerId.startsWith("-") &&
|
|
309
|
+
!/[\x00-\x1f\x7f-\x9f\u2028\u2029]/u.test(ownerId) &&
|
|
310
|
+
argv[3] === "--agent-dir" &&
|
|
311
|
+
typeof argv[4] === "string" &&
|
|
312
|
+
isSafeSdkInternalAgentDir(argv[4])
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function evidencePageOutput(page: EvidencePage, json: boolean): string {
|
|
317
|
+
if (json) return `${JSON.stringify(page)}\n`;
|
|
318
|
+
// JSON-quoted fields keep control characters out of terminal output and preserve exact locators.
|
|
319
|
+
return `${[
|
|
320
|
+
`Command error evidence ${JSON.stringify(page.id)}`,
|
|
321
|
+
`SHA256: ${page.sha256}`,
|
|
322
|
+
`Expires: ${page.expiresAt}`,
|
|
323
|
+
`Page: ${page.page}; complete: ${page.complete}`,
|
|
324
|
+
...page.fragments.map(fragment => `Fragment: ${JSON.stringify(fragment)}`),
|
|
325
|
+
`Next: ${JSON.stringify(page.next).replace(/[\u007f-\u009f\u2028\u2029]/g, char => `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`)}`,
|
|
326
|
+
].join("\n")}\n`;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/** Single family boundary, shared by early bootstrap routing and registered utility dispatch. */
|
|
330
|
+
export async function dispatchPublicCommand(
|
|
331
|
+
argv: readonly string[],
|
|
332
|
+
context: PublicCommandDispatchContext,
|
|
333
|
+
): Promise<void> {
|
|
334
|
+
// Exact private spawn contracts retain the original runtime and error ownership.
|
|
335
|
+
// Malformed worker-like input still belongs to the safe public usage boundary.
|
|
336
|
+
if (context.command === "sdk" && isSdkInternalArgv(argv)) {
|
|
337
|
+
await context.setup?.(diagnostic => {
|
|
338
|
+
process.stderr.write(diagnostic.successStderr);
|
|
339
|
+
});
|
|
340
|
+
const Cmd = await context.load();
|
|
341
|
+
await new Cmd([...argv], {
|
|
342
|
+
bin: context.bin,
|
|
343
|
+
version: context.version,
|
|
344
|
+
commands: new Map([[context.command, Cmd]]),
|
|
345
|
+
}).run();
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (context.command === "daemon" && isDaemonInternalArgv(argv)) {
|
|
349
|
+
const Cmd = await context.load();
|
|
350
|
+
await new Cmd([...argv], {
|
|
351
|
+
bin: context.bin,
|
|
352
|
+
version: context.version,
|
|
353
|
+
commands: new Map([[context.command, Cmd]]),
|
|
354
|
+
}).run();
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const scan = scanPublicCommand(context.command, argv);
|
|
358
|
+
const json = scan.mode === "json";
|
|
359
|
+
const options = { command: scan.descriptor.command, json };
|
|
360
|
+
let agentDir: string | undefined;
|
|
361
|
+
const scopeAgentDir = typeof scan.flags["agent-dir"] === "string" ? scan.flags["agent-dir"] : undefined;
|
|
362
|
+
let successStderr = "";
|
|
363
|
+
let noFileWarning = false;
|
|
364
|
+
const emit = (result: { stdout: string; stderr: string; exitCode: number }) => {
|
|
365
|
+
if (result.stdout) process.stdout.write(result.stdout);
|
|
366
|
+
if (result.stderr) process.stderr.write(result.stderr);
|
|
367
|
+
process.exitCode = result.exitCode;
|
|
368
|
+
};
|
|
369
|
+
try {
|
|
370
|
+
if (scan.kind === "usage") throw new PublicCommandFailure({ kind: "usage", proof: "pre-effect" });
|
|
371
|
+
if (scan.kind === "help") {
|
|
372
|
+
process.stdout.write(renderPublicCommandHelp(scan.descriptor.command, { ...scan.help, json }).output);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
if (scan.kind === "retrieval") {
|
|
376
|
+
const retrieval = scan.retrieval!;
|
|
377
|
+
const result = await readCommandEvidence({
|
|
378
|
+
family: context.command,
|
|
379
|
+
agentDir: retrieval.agentDir ?? getAgentDir(),
|
|
380
|
+
scopeAgentDir: retrieval.agentDir,
|
|
381
|
+
json,
|
|
382
|
+
id: retrieval.id,
|
|
383
|
+
sha256: retrieval.sha256,
|
|
384
|
+
page: retrieval.page,
|
|
385
|
+
});
|
|
386
|
+
if (result.status === "unavailable") {
|
|
387
|
+
if (result.reason === "invalid_request")
|
|
388
|
+
emit(
|
|
389
|
+
await renderPublicCommandFailure(
|
|
390
|
+
new PublicCommandFailure({ kind: "usage", proof: "pre-effect" }),
|
|
391
|
+
options,
|
|
392
|
+
),
|
|
393
|
+
);
|
|
394
|
+
else emit(renderPublicEvidenceUnavailable(result, options));
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
const output = evidencePageOutput(result.page, json);
|
|
398
|
+
if (Buffer.byteLength(output) > EVIDENCE_LIMITS.responseBytes) {
|
|
399
|
+
emit(renderPublicEvidenceUnavailable({ reason: "locator_too_large", requiredBytes: null }, options));
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
process.stdout.write(output);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
agentDir = scopeAgentDir ?? getAgentDir();
|
|
406
|
+
await context.setup?.(diagnostic => {
|
|
407
|
+
noFileWarning = true;
|
|
408
|
+
if (successStderr) return;
|
|
409
|
+
successStderr = diagnostic.successStderr;
|
|
410
|
+
});
|
|
411
|
+
const Cmd = await context.load();
|
|
412
|
+
const operationArgv = [...scan.operationArgv];
|
|
413
|
+
// Families whose runtime must observe the boundary `--json` flag: daemon and
|
|
414
|
+
// sdk spawn/search select their successful output mode with it, and sdk
|
|
415
|
+
// session forwards it to its JSON-aware runner. The boundary scanner always
|
|
416
|
+
// consumes `--json`, so it is re-inserted here for exactly those families.
|
|
417
|
+
const familyObservesJson =
|
|
418
|
+
context.command === "daemon" ||
|
|
419
|
+
(scan.descriptor.command[0] === "sdk" &&
|
|
420
|
+
["spawn", "search", "session"].includes(scan.descriptor.command[1] ?? ""));
|
|
421
|
+
// Insert before --, never after it where the operation parser would see a positional.
|
|
422
|
+
if (json && familyObservesJson) {
|
|
423
|
+
const delimiter = operationArgv.indexOf("--");
|
|
424
|
+
operationArgv.splice(delimiter < 0 ? operationArgv.length : delimiter, 0, "--json");
|
|
425
|
+
}
|
|
426
|
+
await new Cmd(operationArgv, {
|
|
427
|
+
bin: context.bin,
|
|
428
|
+
version: context.version,
|
|
429
|
+
commands: new Map([[context.command, Cmd]]),
|
|
430
|
+
}).run();
|
|
431
|
+
if (successStderr) process.stderr.write(successStderr);
|
|
432
|
+
} catch (error) {
|
|
433
|
+
if (scan.kind === "retrieval") {
|
|
434
|
+
emit(renderPublicEvidenceUnavailable({ reason: "io_error", requiredBytes: null }, options));
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const failure =
|
|
438
|
+
error instanceof CliParseError || (error instanceof PublicHelpError && error.exitCode === 2)
|
|
439
|
+
? new PublicCommandFailure({ kind: "usage", proof: "pre-effect" })
|
|
440
|
+
: error;
|
|
441
|
+
emit(
|
|
442
|
+
await renderPublicCommandFailure(failure, {
|
|
443
|
+
...options,
|
|
444
|
+
agentDir,
|
|
445
|
+
scopeAgentDir,
|
|
446
|
+
diagnostics: noFileWarning ? ["macos_nofile_limit_low"] : [],
|
|
447
|
+
}),
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
}
|