@gajae-code/coding-agent 0.17.1 → 0.17.4
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 +266 -0
- package/dist/types/async/job-manager.d.ts +7 -6
- 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 +24 -0
- package/dist/types/config/file-lock.d.ts +10 -1
- package/dist/types/config/model-profile-activation.d.ts +63 -4
- package/dist/types/config/model-registry.d.ts +20 -2
- package/dist/types/config/settings-schema.d.ts +11 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
- package/dist/types/coordinator-mcp/server.d.ts +3 -0
- package/dist/types/daemon/operator-contract.d.ts +5 -1
- package/dist/types/eval/js/worker-protocol.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/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/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 +22 -0
- package/dist/types/modes/acp/acp-agent.d.ts +94 -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/thinking-selector.d.ts +2 -1
- 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/manager.d.ts +56 -0
- 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/acp/adapter.d.ts +27 -0
- package/dist/types/sdk/acp/final-text.d.ts +8 -0
- package/dist/types/sdk/broker/broker.d.ts +13 -2
- package/dist/types/sdk/broker/ensure.d.ts +46 -1
- package/dist/types/sdk/broker/identity.d.ts +3 -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/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 +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 +3 -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 +83 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +38 -1
- package/dist/types/sdk/prompt-failure.d.ts +30 -1
- package/dist/types/sdk/prompt-status.d.ts +8 -0
- package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
- package/dist/types/sdk/router/replay-retention-gap-cache.d.ts +13 -0
- package/dist/types/sdk/router/session-router.d.ts +2 -0
- 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 +73 -2
- package/dist/types/sdk/transport/stdio.d.ts +5 -1
- package/dist/types/session/agent-session.d.ts +168 -21
- 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/thinking.d.ts +3 -1
- package/dist/types/tools/bash.d.ts +37 -11
- package/dist/types/tools/job.d.ts +1 -1
- package/dist/types/tools/steer-fold.d.ts +31 -0
- package/dist/types/utils/git.d.ts +28 -2
- package/dist/types/utils/mupdf-embedded.d.ts +2 -0
- package/dist/types/utils/mupdf-wasm-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 +60 -9
- 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 +535 -0
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +9 -1
- package/src/cli/skills-cli.ts +46 -2
- package/src/cli.ts +61 -1
- package/src/commands/daemon.ts +65 -69
- package/src/commands/sdk.ts +232 -100
- package/src/commands/setup.ts +2 -0
- package/src/commands/skills.ts +11 -0
- package/src/config/autorouting-tier-map.ts +16 -0
- package/src/config/file-lock.ts +199 -68
- package/src/config/model-profile-activation.ts +406 -53
- package/src/config/model-registry.ts +204 -25
- 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 +175 -8
- package/src/coordinator-mcp/server.ts +528 -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/debug/report-bundle.ts +114 -24
- 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/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/runtime-skill-discovery.ts +61 -3
- package/src/extensibility/shared-events.ts +3 -1
- package/src/gjc-runtime/managed-owner-admission.ts +67 -50
- package/src/gjc-runtime/session-state-lock.ts +165 -24
- package/src/gjc-runtime/ultragoal-succession.ts +31 -3
- package/src/internal-urls/docs-index.generated.ts +21 -19
- 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 +123 -55
- package/src/modes/acp/acp-agent.ts +593 -47
- package/src/modes/acp/acp-event-mapper.ts +9 -0
- package/src/modes/acp/startup-provenance.ts +59 -0
- package/src/modes/components/custom-provider-wizard.ts +308 -7
- package/src/modes/components/model-selector.ts +31 -15
- package/src/modes/components/oauth-selector.ts +9 -0
- package/src/modes/components/session-selector.ts +47 -4
- package/src/modes/components/status-line/segments.ts +6 -1
- package/src/modes/components/thinking-selector.ts +7 -3
- 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/selector-controller.ts +177 -18
- 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/manager.ts +689 -55
- 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 +90 -9
- package/src/sdk/acp/final-text.ts +19 -2
- package/src/sdk/broker/broker.ts +378 -52
- package/src/sdk/broker/ensure.ts +97 -19
- package/src/sdk/broker/identity.ts +9 -1
- package/src/sdk/broker/lifecycle-ledger.ts +95 -31
- package/src/sdk/broker/lifecycle.ts +690 -141
- package/src/sdk/broker/runtime.ts +1 -1
- package/src/sdk/broker/session-index.ts +97 -4
- package/src/sdk/broker/spawn-authority.ts +35 -7
- package/src/sdk/broker/stderr-drainer.ts +59 -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 +721 -84
- package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
- package/src/sdk/bus/telegram-daemon-contract.ts +3 -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 +687 -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 +636 -9
- package/src/sdk/host/session-runtime.ts +499 -118
- 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/prompt-deadline-flush.ts +334 -0
- package/src/sdk/prompt-deadline-manager.ts +136 -4
- package/src/sdk/prompt-failure.ts +43 -1
- package/src/sdk/prompt-status.ts +8 -0
- package/src/sdk/prompt-tool-boundary.ts +121 -0
- package/src/sdk/protocol/operation-inventory.generated.json +106 -0
- package/src/sdk/router/replay-retention-gap-cache.ts +27 -0
- package/src/sdk/router/session-router.ts +31 -4
- package/src/sdk/session.ts +194 -16
- package/src/sdk/startup-capability.ts +1 -1
- package/src/sdk/transport/relay.ts +71 -6
- package/src/sdk/transport/serve-cli.ts +494 -49
- package/src/sdk/transport/socket.ts +12 -11
- package/src/sdk/transport/stdio.ts +7 -3
- package/src/session/agent-session.ts +2437 -400
- 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 +58 -18
- package/src/session/internal/managed-session-storage.ts +304 -11
- package/src/session/session-manager.ts +382 -44
- package/src/session/session-work-lease.ts +34 -0
- package/src/session-import/codex.ts +12 -3
- package/src/setup/model-onboarding-guidance.ts +1 -1
- package/src/setup/provider-onboarding.ts +397 -24
- package/src/slash-commands/builtin-registry.ts +258 -14
- package/src/task/index.ts +14 -2
- package/src/thinking.ts +21 -2
- package/src/tools/bash.ts +98 -78
- package/src/tools/fetch.ts +119 -20
- 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/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-wasm-embedded.ts +3 -0
- package/src/utils/mupdf-wasm.ts +24 -2
- package/src/utils/mupdf.ts +129 -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
|
@@ -24,6 +24,7 @@ import type {
|
|
|
24
24
|
WorkflowGateOption,
|
|
25
25
|
WorkflowGateQueryRecord,
|
|
26
26
|
WorkflowGateResolution,
|
|
27
|
+
WorkflowGateResolutionDiagnostic,
|
|
27
28
|
WorkflowGateResponse,
|
|
28
29
|
WorkflowGateValidationError,
|
|
29
30
|
WorkflowStage,
|
|
@@ -35,6 +36,9 @@ export type PersistedResolutionOrigin =
|
|
|
35
36
|
| { kind: "generic"; channel: "sdk" | "other" }
|
|
36
37
|
| { kind: "telegram_notification"; interactionActionId: string };
|
|
37
38
|
|
|
39
|
+
/** Keep accepted diagnostics below the coordinator's cumulative Q12 snapshot cap. */
|
|
40
|
+
export const MAX_ACCEPTED_WORKFLOW_GATE_QUERY_RECORDS = 32;
|
|
41
|
+
|
|
38
42
|
export type PersistedAckPolicy =
|
|
39
43
|
| { kind: "none"; reason: "non_telegram" | "semantic_noncommit" | "legacy_unproven" }
|
|
40
44
|
| {
|
|
@@ -152,7 +156,7 @@ export class BrokerWorkflowGateEmitter implements WorkflowGateEmitter {
|
|
|
152
156
|
readonly #emitterHooks: Pick<BrokerHooks, "advance">;
|
|
153
157
|
#runtimeTurnProvider: (() => string | undefined) | undefined;
|
|
154
158
|
|
|
155
|
-
constructor(runId: string, store: GateStore, emitterHooks: Pick<BrokerHooks, "advance"> = {}) {
|
|
159
|
+
constructor(runId: string, store: GateStore, emitterHooks: Pick<BrokerHooks, "advance" | "continuationLost"> = {}) {
|
|
156
160
|
this.#runId = runId;
|
|
157
161
|
this.#store = store;
|
|
158
162
|
this.#emitterHooks = emitterHooks;
|
|
@@ -164,6 +168,7 @@ export class BrokerWorkflowGateEmitter implements WorkflowGateEmitter {
|
|
|
164
168
|
completeAccepted: record => this.#completeAccepted(record),
|
|
165
169
|
finalizeAccepted: record => this.#finalizeAccepted(record),
|
|
166
170
|
terminalizeAccepted: record => this.#terminalizeAccepted(record),
|
|
171
|
+
continuationLost: record => emitterHooks.continuationLost?.(record),
|
|
167
172
|
});
|
|
168
173
|
}
|
|
169
174
|
|
|
@@ -1147,6 +1152,8 @@ export type GateAuditEvent =
|
|
|
1147
1152
|
| { event: "gate_response_accepted"; gate_id: string; answer_hash: string }
|
|
1148
1153
|
| { event: "gate_response_rejected"; gate_id: string; answer_hash: string }
|
|
1149
1154
|
| { event: "gate_response_idempotent_replay"; gate_id: string }
|
|
1155
|
+
/** An idempotent replay refused because this runtime cannot prove the continuation ran. */
|
|
1156
|
+
| { event: "gate_response_replay_unproven"; gate_id: string }
|
|
1150
1157
|
| { event: "gate_response_idempotency_conflict"; gate_id: string }
|
|
1151
1158
|
| { event: "gate_response_already_resolved"; gate_id: string }
|
|
1152
1159
|
| { event: "gate_response_unknown_gate"; gate_id: string }
|
|
@@ -1171,6 +1178,8 @@ export interface BrokerHooks {
|
|
|
1171
1178
|
terminalizeAccepted?(record: PersistedGate): WorkflowGateTerminalProof | Promise<WorkflowGateTerminalProof>;
|
|
1172
1179
|
/** Runs only after a successful advance has been durably marked advanced. */
|
|
1173
1180
|
completeAccepted?(record: PersistedGate): void | Promise<void>;
|
|
1181
|
+
/** Notifies the owning runtime when the accepted answer cannot reach its continuation. */
|
|
1182
|
+
continuationLost?(record: PersistedGate): void;
|
|
1174
1183
|
/** Append-only audit sink. */
|
|
1175
1184
|
audit?(event: GateAuditEvent): void;
|
|
1176
1185
|
}
|
|
@@ -1222,6 +1231,14 @@ export class WorkflowGateBroker {
|
|
|
1222
1231
|
private readonly gateLocks = new Map<string, Promise<void>>();
|
|
1223
1232
|
private readonly continuations = new Map<string, GateContinuation>();
|
|
1224
1233
|
readonly #terminalProofs = new Map<string, WorkflowGateTerminalProof>();
|
|
1234
|
+
/**
|
|
1235
|
+
* Gates whose `completeAccepted` hook threw after `advanced:true` was already
|
|
1236
|
+
* committed, so the durable record claims completion the continuation never
|
|
1237
|
+
* received. In-memory by design: the stranded turn belongs to this process's
|
|
1238
|
+
* waiter, so a restart cannot resolve it either way and must not inherit a
|
|
1239
|
+
* claim it cannot honor (#5599).
|
|
1240
|
+
*/
|
|
1241
|
+
readonly #continuationLost = new Set<string>();
|
|
1225
1242
|
|
|
1226
1243
|
private async withGateLock<T>(gateId: string, operation: () => Promise<T>): Promise<T> {
|
|
1227
1244
|
const previous = this.gateLocks.get(gateId) ?? Promise.resolve();
|
|
@@ -1282,6 +1299,34 @@ export class WorkflowGateBroker {
|
|
|
1282
1299
|
`idempotency_conflict: gate ${response.gate_id} resolved with a different body`,
|
|
1283
1300
|
);
|
|
1284
1301
|
if (response.idempotency_key !== undefined && sameKey && sameBody) {
|
|
1302
|
+
// A record whose `completeAccepted` threw is durably indistinguishable from a
|
|
1303
|
+
// genuinely completed one: `advanced:true` is committed before the waiter is
|
|
1304
|
+
// resolved, so the shape below matches either way. Reporting `completed` there
|
|
1305
|
+
// told `resolveSdkWorkflowGate`'s catch path to return a successful resolution
|
|
1306
|
+
// for a turn whose continuation was never resolved — `ok:true status:"accepted"`
|
|
1307
|
+
// with an empty pending-gate list and a prompt stuck `in_flight` forever, with
|
|
1308
|
+
// no recovery path because `recover()` skips advanced records (#5599).
|
|
1309
|
+
//
|
|
1310
|
+
// Downgrading to `accepted_incomplete` routes it through the existing
|
|
1311
|
+
// recover-then-recheck branch and, when that cannot resolve it, surfaces the
|
|
1312
|
+
// documented `terminal_uncertain` instead of a false success.
|
|
1313
|
+
//
|
|
1314
|
+
// TWO conditions, because the loss cannot be persisted: an `accepted` record
|
|
1315
|
+
// may not carry a `lifecycle` and a `quarantined` one must be `advanced:false`,
|
|
1316
|
+
// so the durable shape has nowhere to record it.
|
|
1317
|
+
//
|
|
1318
|
+
// 1. This runtime saw the hook throw.
|
|
1319
|
+
if (this.#continuationLost.has(response.gate_id)) return { kind: "accepted_incomplete" };
|
|
1320
|
+
// 2. The record belongs to a PREVIOUS runtime. A continuation waiter is
|
|
1321
|
+
// process-local and cannot survive a restart, so this process can never
|
|
1322
|
+
// prove the prior turn was resolved — and the in-memory set above is empty
|
|
1323
|
+
// after a restart, which is exactly how the first fix still handed back a
|
|
1324
|
+
// false `completed` on a cross-restart idempotent retry (#5599 review).
|
|
1325
|
+
// Fail closed instead. The cost is telling a retry "uncertain" about a gate
|
|
1326
|
+
// that did complete under the dead runtime; that is the honest answer
|
|
1327
|
+
// regardless, because the turn it belonged to died with that process and no
|
|
1328
|
+
// retry can continue it.
|
|
1329
|
+
if (record.ownerInstanceId !== this.instanceId) return { kind: "accepted_incomplete" };
|
|
1285
1330
|
if (record.terminalized === true && record.advanced === true && record.resolution)
|
|
1286
1331
|
return { kind: "completed", resolution: record.resolution };
|
|
1287
1332
|
return { kind: "accepted_incomplete" };
|
|
@@ -1311,6 +1356,17 @@ export class WorkflowGateBroker {
|
|
|
1311
1356
|
return this.continuations.get(gateId)?.isLive(gateId) === true;
|
|
1312
1357
|
}
|
|
1313
1358
|
|
|
1359
|
+
private recordContinuationLoss(gateId: string): void {
|
|
1360
|
+
this.#continuationLost.add(gateId);
|
|
1361
|
+
const lost = this.store.get(gateId);
|
|
1362
|
+
if (!lost) return;
|
|
1363
|
+
try {
|
|
1364
|
+
this.hooks.continuationLost?.(lost);
|
|
1365
|
+
} catch {
|
|
1366
|
+
// A settlement notification must never replace the original resolution error.
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1314
1370
|
hasRecoverableAcceptedGate(): boolean {
|
|
1315
1371
|
return this.store
|
|
1316
1372
|
.list()
|
|
@@ -1395,8 +1451,10 @@ export class WorkflowGateBroker {
|
|
|
1395
1451
|
.filter(
|
|
1396
1452
|
(
|
|
1397
1453
|
record,
|
|
1398
|
-
): record is PersistedGate & {
|
|
1399
|
-
|
|
1454
|
+
): record is PersistedGate & {
|
|
1455
|
+
status: "quarantined";
|
|
1456
|
+
lifecycle: WorkflowGateDiagnostic["lifecycle"];
|
|
1457
|
+
} => record.status === "quarantined" && record.lifecycle !== undefined,
|
|
1400
1458
|
)
|
|
1401
1459
|
.sort(
|
|
1402
1460
|
(left, right) =>
|
|
@@ -1408,6 +1466,7 @@ export class WorkflowGateBroker {
|
|
|
1408
1466
|
id: `diagnostic:${record.gate.gate_id}`,
|
|
1409
1467
|
tag: "quarantined",
|
|
1410
1468
|
lifecycle: record.lifecycle,
|
|
1469
|
+
answer_recorded: Object.hasOwn(record, "answer"),
|
|
1411
1470
|
}));
|
|
1412
1471
|
}
|
|
1413
1472
|
|
|
@@ -1421,8 +1480,38 @@ export class WorkflowGateBroker {
|
|
|
1421
1480
|
this.hasLiveContinuation(record.gate.gate_id),
|
|
1422
1481
|
)
|
|
1423
1482
|
.sort(compareGates)
|
|
1424
|
-
.map(record => ({
|
|
1425
|
-
|
|
1483
|
+
.map(record => ({
|
|
1484
|
+
...record.gate,
|
|
1485
|
+
id: `pending:${record.gate.gate_id}`,
|
|
1486
|
+
tag: "pending" as const,
|
|
1487
|
+
answer_recorded: false as const,
|
|
1488
|
+
}));
|
|
1489
|
+
const accepted: WorkflowGateResolutionDiagnostic[] = this.store
|
|
1490
|
+
.list()
|
|
1491
|
+
.filter((record): record is PersistedGate & { status: "accepted" } => record.status === "accepted")
|
|
1492
|
+
.sort(
|
|
1493
|
+
(left, right) =>
|
|
1494
|
+
(right.resolution?.resolved_at ?? "").localeCompare(left.resolution?.resolved_at ?? "") ||
|
|
1495
|
+
right.gate.gate_id.localeCompare(left.gate.gate_id),
|
|
1496
|
+
)
|
|
1497
|
+
.slice(0, MAX_ACCEPTED_WORKFLOW_GATE_QUERY_RECORDS)
|
|
1498
|
+
.map(record => ({
|
|
1499
|
+
...record.gate,
|
|
1500
|
+
id: `diagnostic:${record.gate.gate_id}`,
|
|
1501
|
+
tag: "accepted" as const,
|
|
1502
|
+
answer_recorded: true as const,
|
|
1503
|
+
resolved_at: record.resolution?.resolved_at ?? record.gate.created_at,
|
|
1504
|
+
post_accept_disposition: this.#continuationLost.has(record.gate.gate_id)
|
|
1505
|
+
? "continuation_lost"
|
|
1506
|
+
: record.advanced
|
|
1507
|
+
? record.ownerInstanceId === this.instanceId
|
|
1508
|
+
? "advanced"
|
|
1509
|
+
: "unknown"
|
|
1510
|
+
: record.terminalized === true
|
|
1511
|
+
? "terminalized"
|
|
1512
|
+
: "accepted",
|
|
1513
|
+
}));
|
|
1514
|
+
return [...pending, ...accepted, ...this.listGateDiagnostics()];
|
|
1426
1515
|
}
|
|
1427
1516
|
|
|
1428
1517
|
/** Open and emit a gate. The pending record is persisted BEFORE emission. */
|
|
@@ -1516,6 +1605,17 @@ export class WorkflowGateBroker {
|
|
|
1516
1605
|
const sameBody = record.responseHash === responseHash;
|
|
1517
1606
|
const sameKey = record.idempotencyKey === response.idempotency_key;
|
|
1518
1607
|
if (response.idempotency_key !== undefined && sameKey && sameBody) {
|
|
1608
|
+
// Same provenance rule as `lookupCompletedResolution`: an idempotent replay must
|
|
1609
|
+
// not hand back an accepted resolution for a continuation this runtime cannot
|
|
1610
|
+
// prove was resolved. Without this, a direct `resolveGate()` retry bypassed the
|
|
1611
|
+
// lookup entirely and reproduced the original false success (#5599 review).
|
|
1612
|
+
if (this.#continuationLost.has(response.gate_id) || record.ownerInstanceId !== this.instanceId) {
|
|
1613
|
+
this.hooks.audit?.({ event: "gate_response_replay_unproven", gate_id: response.gate_id });
|
|
1614
|
+
throw new WorkflowGateBrokerError(
|
|
1615
|
+
"unknown_gate",
|
|
1616
|
+
`accepted gate ${response.gate_id} cannot be replayed: this runtime cannot prove its continuation was resolved`,
|
|
1617
|
+
);
|
|
1618
|
+
}
|
|
1519
1619
|
this.hooks.audit?.({ event: "gate_response_idempotent_replay", gate_id: response.gate_id });
|
|
1520
1620
|
return record.resolution as WorkflowGateResolution;
|
|
1521
1621
|
}
|
|
@@ -1609,7 +1709,16 @@ export class WorkflowGateBroker {
|
|
|
1609
1709
|
`accepted gate ${response.gate_id} lost its continuation before advance completed`,
|
|
1610
1710
|
);
|
|
1611
1711
|
this.store.put({ ...latest, advanced: true });
|
|
1612
|
-
|
|
1712
|
+
// `advanced:true` is already durable, so a throw here cannot be undone — but it
|
|
1713
|
+
// must not be reported as a completed resolution either. Mark the loss before
|
|
1714
|
+
// rethrowing so `lookupCompletedResolution` stops claiming completion for a
|
|
1715
|
+
// continuation that was never resolved (#5599).
|
|
1716
|
+
try {
|
|
1717
|
+
await this.hooks.completeAccepted?.(this.store.get(response.gate_id) as PersistedGate);
|
|
1718
|
+
} catch (error) {
|
|
1719
|
+
this.recordContinuationLoss(response.gate_id);
|
|
1720
|
+
throw error;
|
|
1721
|
+
}
|
|
1613
1722
|
this.continuations.get(response.gate_id)?.release?.(response.gate_id);
|
|
1614
1723
|
this.continuations.delete(response.gate_id);
|
|
1615
1724
|
return resolution;
|
|
@@ -1659,7 +1768,15 @@ export class WorkflowGateBroker {
|
|
|
1659
1768
|
if (latest?.status !== "accepted" || latest.advanced || !this.hasLiveContinuation(listed.gate.gate_id))
|
|
1660
1769
|
return;
|
|
1661
1770
|
this.store.put({ ...latest, advanced: true });
|
|
1662
|
-
|
|
1771
|
+
// Same durable-commit-then-resolve ordering as `resolve()`; mark the
|
|
1772
|
+
// loss so a recovery attempt cannot leave behind a record that claims
|
|
1773
|
+
// completion its continuation never received (#5599).
|
|
1774
|
+
try {
|
|
1775
|
+
await this.hooks.completeAccepted?.(this.store.get(latest.gate.gate_id) as PersistedGate);
|
|
1776
|
+
} catch (error) {
|
|
1777
|
+
this.recordContinuationLoss(latest.gate.gate_id);
|
|
1778
|
+
throw error;
|
|
1779
|
+
}
|
|
1663
1780
|
this.continuations.get(latest.gate.gate_id)?.release?.(latest.gate.gate_id);
|
|
1664
1781
|
this.continuations.delete(latest.gate.gate_id);
|
|
1665
1782
|
this.hooks.audit?.({ event: "gate_advance_recovered", gate_id: latest.gate.gate_id });
|
|
@@ -375,12 +375,26 @@ export interface WorkflowGateDiagnostic extends WorkflowGate {
|
|
|
375
375
|
id: string;
|
|
376
376
|
tag: "quarantined";
|
|
377
377
|
lifecycle: WorkflowGateLifecycle;
|
|
378
|
+
/** Whether the durable broker retained an answer for this gate. */
|
|
379
|
+
answer_recorded: boolean;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/** Durable acceptance evidence for a gate that is no longer pending. */
|
|
383
|
+
export interface WorkflowGateResolutionDiagnostic extends WorkflowGate {
|
|
384
|
+
id: string;
|
|
385
|
+
tag: "accepted";
|
|
386
|
+
/** True when the accepted record contains the answer body. */
|
|
387
|
+
answer_recorded: true;
|
|
388
|
+
resolved_at: string;
|
|
389
|
+
/** Single post-accept disposition; raw answers and derived answer values stay private. */
|
|
390
|
+
post_accept_disposition: "accepted" | "terminalized" | "advanced" | "continuation_lost" | "unknown";
|
|
378
391
|
}
|
|
379
392
|
|
|
380
393
|
/** Stable Q12 row preserving the root WorkflowGate shape. */
|
|
381
394
|
export type WorkflowGateQueryRecord =
|
|
382
|
-
| (WorkflowGate & { id: string; tag: "pending"; lifecycle?: undefined })
|
|
383
|
-
| WorkflowGateDiagnostic
|
|
395
|
+
| (WorkflowGate & { id: string; tag: "pending"; lifecycle?: undefined; answer_recorded: false })
|
|
396
|
+
| WorkflowGateDiagnostic
|
|
397
|
+
| WorkflowGateResolutionDiagnostic;
|
|
384
398
|
|
|
385
399
|
/** Inbound: the agent's answer to a workflow gate. */
|
|
386
400
|
export interface WorkflowGateResponse {
|
package/src/modes/types.ts
CHANGED
|
@@ -409,7 +409,7 @@ export interface InteractiveModeContext {
|
|
|
409
409
|
handleHandoffCommand(customInstructions?: string): Promise<void>;
|
|
410
410
|
handleContributionPrepCommand(customInstructions?: string): Promise<void>;
|
|
411
411
|
handleMoveCommand(targetPath: string): Promise<void>;
|
|
412
|
-
handleRenameCommand(title
|
|
412
|
+
handleRenameCommand(title?: string): Promise<void>;
|
|
413
413
|
handleMemoryCommand(text: string): Promise<void>;
|
|
414
414
|
handleSTTToggle(): Promise<void>;
|
|
415
415
|
executeCompaction(
|
|
@@ -490,7 +490,7 @@ export interface InteractiveModeContext {
|
|
|
490
490
|
>;
|
|
491
491
|
goalModeController: Pick<
|
|
492
492
|
import("./controllers/goal-mode-controller").GoalModeController,
|
|
493
|
-
"enabled" | "paused" | "handleCommand"
|
|
493
|
+
"enabled" | "paused" | "handleCommand" | "cancelContinuation" | "scheduleContinuation"
|
|
494
494
|
>;
|
|
495
495
|
setHookWidget(key: string, content: ExtensionWidgetContent, options?: ExtensionWidgetOptions): void;
|
|
496
496
|
setHookStatus(key: string, text: string | undefined): void;
|
|
@@ -5,6 +5,7 @@ Routing:
|
|
|
5
5
|
- Every task that requires a rendered page, authenticated/private browser state, live tabs, browser UI, screenshots, downloads behind cookies, history, saved credentials, or profile data MUST use Bash to invoke the installed Aside CLI.
|
|
6
6
|
- Default to `aside repl '<JavaScript>'` for deterministic Playwright inspection and actions, even when the answer is unknown but the procedure is discoverable from `snapshot(page, { interactive: true })`.
|
|
7
7
|
- Use `aside exec '<prompt>'` only for runtime judgment, source-heavy research, browser-history search, MFA or opaque password autofill, approval/notification waits, long monitoring, multi-site synthesis, routines, or work worth a second model. Continue with `aside exec --session <id> '<follow-up>'`. Use `--account`, `--model`, `--provider`, `--speed`, or `--effort` only when the task requires overriding user defaults.
|
|
8
|
+
- Declare every Aside invocation on the Bash call itself with the structured `activity` argument: `{"kind":"browser","provider":"aside","mode":"repl"}` for `aside repl`, and `{"kind":"browser","provider":"aside","mode":"exec"}` for `aside exec` including `--session <id>` follow-ups. The declaration names the operation, not the command spelling: send it unchanged across wrappers, env prefixes, absolute CLI paths, quoting, and multiline commands, and omit it on Bash calls that do not invoke Aside.
|
|
8
9
|
- Cookie-free public HTTP content that does not require rendered or authenticated browser state may use GJC `read` directly.
|
|
9
10
|
|
|
10
11
|
Deterministic procedure:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Generate a 3-6 word title for a coding session from the user
|
|
1
|
+
Generate a 3-6 word title for a coding session from the supplied user message or conversation digest. If multiple messages are supplied, identify the primary/current task from the digest, weighting the newest substantive message highest; do not assume the first message is the task. If one message is supplied, capture its main task or topic.
|
|
2
2
|
Output ONLY the title. No quotes or trailing punctuation.
|
|
@@ -17,7 +17,7 @@ Executes bash command in shell session for terminal operations like git, bun, ca
|
|
|
17
17
|
- Use `async: true` for long-running commands when you don't need immediate output; the call returns a background job ID and the result is delivered automatically as a follow-up.
|
|
18
18
|
{{/if}}
|
|
19
19
|
{{#if foregroundFoldEnabled}}
|
|
20
|
-
- In the interactive TUI, the user can press the fold chord twice (default `Alt+Shift+B`, plus `Cmd+B` on macOS; remappable via the `app.tool.backgroundFold` keybinding) while a foreground command is still running to fold it into a background job. All three command surfaces fold: managed non-PTY bash, editor/ACP client-terminal commands, and PTY-mode commands. A folded command keeps its original timeout and is never killed or restarted by folding; a folded PTY continues output-only, so it stops accepting input. The turn then ends cleanly and a later turn resumes automatically with the command's result, so the interrupted task is finished rather than abandoned. `task`/`subagent` waits are deliberately NOT foldable. Do not instruct users to use raw shell `Ctrl+Z`/`bg` inside the GJC TUI; ownership and output routing are not safe there.
|
|
20
|
+
- In the interactive TUI, the user can press the fold chord twice (default `Alt+Shift+B`, plus `Cmd+B` on macOS; remappable via the `app.tool.backgroundFold` keybinding) while a foreground command is still running to fold it into a background job. All three command surfaces fold: managed non-PTY bash, editor/ACP client-terminal commands, and PTY-mode commands. A folded command keeps its original timeout and is never killed or restarted by folding; a folded PTY continues output-only, so it stops accepting input. The turn then ends cleanly and a later turn resumes automatically with the command's result, so the interrupted task is finished rather than abandoned. The `job` tool's own await uses the same steer-fold behavior and grace window; `task`/`subagent` waits are deliberately NOT foldable. Do not instruct users to use raw shell `Ctrl+Z`/`bg` inside the GJC TUI; ownership and output routing are not safe there.
|
|
21
21
|
- A user steer folds the same way: when the user sends a message while a foreground command has already run for at least 2 seconds, the command is folded into a background job and this call returns the background-start result plus the line `Folded into background job <id> because a user steer arrived; the command keeps running with its original timeout and its result will wake a later turn.` The steer is then delivered at this tool boundary, so handle it next; do not re-run the folded command. Steers that arrive within the first 2 seconds let the command finish normally. This applies only while `busyPromptMode` is `steer`; `toolInterruptPolicy` is not a gate, since a fold never kills the command.
|
|
22
22
|
{{/if}}
|
|
23
23
|
</instruction>
|
package/src/prompts/tools/job.md
CHANGED
|
@@ -2,7 +2,7 @@ Inspects, waits, or cancels async jobs.
|
|
|
2
2
|
|
|
3
3
|
Background job results are delivered automatically when complete. Jobs that back task subagents should be controlled via the `subagent` tool when it is available; use `job` for non-subagent jobs (async bash, monitors) and as a compatibility fallback. Running job output stays quiet by default to avoid flooding the conversation; use `tail` when you explicitly want to show/reopen retained output. Reach for this tool only when you need to inspect or intervene.
|
|
4
4
|
|
|
5
|
-
In the interactive TUI, a running foreground command can be folded into a background job by pressing the fold chord twice (default `Alt+Shift+B`, plus `Cmd+B` on macOS; remappable via `app.tool.backgroundFold`), or automatically when the user sends a steer after the command has run for at least 2 seconds (with `busyPromptMode=steer` (`toolInterruptPolicy` is not a gate)). This covers managed non-PTY bash, editor/ACP client-terminal commands, and PTY-mode commands. A folded job keeps its original deadline, is never killed or restarted by folding, and its result wakes a later turn automatically; a folded PTY continues output-only and no longer accepts input. Job listings expose `foldReason` (`steer`, `chord`, `timer`, or `sdk_control`) beside `backgrounded` so you can tell why a job left the foreground. `task`/`subagent` waits are not foldable. Raw shell `Ctrl+Z`/`bg` is not the supported path inside GJC because it bypasses job ownership and output-routing contracts.
|
|
5
|
+
In the interactive TUI, a running foreground command can be folded into a background job by pressing the fold chord twice (default `Alt+Shift+B`, plus `Cmd+B` on macOS; remappable via `app.tool.backgroundFold`), or automatically when the user sends a steer after the command has run for at least 2 seconds (with `busyPromptMode=steer` (`toolInterruptPolicy` is not a gate)). This covers managed non-PTY bash, editor/ACP client-terminal commands, and PTY-mode commands. A folded job keeps its original deadline, is never killed or restarted by folding, and its result wakes a later turn automatically; a folded PTY continues output-only and no longer accepts input. A `job` await also folds after the same 2-second grace window when a steer arrives, returning immediately with the still-running job id(s) while those jobs keep their original deadlines and wake a later turn with their results. Job listings expose `foldReason` (`steer`, `chord`, `timer`, or `sdk_control`) beside `backgrounded` so you can tell why a job left the foreground. `task`/`subagent` waits are not foldable. Raw shell `Ctrl+Z`/`bg` is not the supported path inside GJC because it bypasses job ownership and output-routing contracts.
|
|
6
6
|
|
|
7
7
|
# Operations
|
|
8
8
|
|
|
@@ -73,6 +73,8 @@ For `.sqlite`, `.sqlite3`, `.db`, `.db3`:
|
|
|
73
73
|
|
|
74
74
|
`agent://<id>`, `artifact://<id>`, `rule://<name>`, and `local://<name>.md` resolve transparently and accept the same line selectors as filesystem paths. Use `artifact://<id>` to recover full output that a previous bash/eval/tool result spilled or truncated.
|
|
75
75
|
|
|
76
|
+
Bundled skills have no filesystem home, so the skill tool and skill discovery report them as `embedded:gjc/skills/<name>/SKILL.md`; read that identifier verbatim. Bundled skill fragments, when surfaced, likewise use `embedded:gjc/skill-fragments/...` identifiers.
|
|
77
|
+
|
|
76
78
|
<critical>
|
|
77
79
|
- Always include `path`; never call `read` with `{}`.
|
|
78
80
|
- For line ranges, append the selector to `path`.
|
|
@@ -42,7 +42,42 @@ describe("network prewarm runtime service", () => {
|
|
|
42
42
|
const runtime = await service.get("legacy-startup");
|
|
43
43
|
runtime.preconnect("https://example.test");
|
|
44
44
|
|
|
45
|
-
expect(calls).toEqual(["https://example.test"]);
|
|
45
|
+
expect(calls).toEqual(["https://example.test:443/"]);
|
|
46
|
+
await service.dispose();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("normalizes a portless HTTPS model host before preconnect", async () => {
|
|
50
|
+
const calls: string[] = [];
|
|
51
|
+
const fetchWithPreconnect = Object.assign(async () => new Response("ok"), {
|
|
52
|
+
preconnect: (url: string) => {
|
|
53
|
+
calls.push(url);
|
|
54
|
+
},
|
|
55
|
+
}) as typeof fetch & { preconnect: (url: string) => void };
|
|
56
|
+
globalThis.fetch = fetchWithPreconnect;
|
|
57
|
+
|
|
58
|
+
const service = createNetworkPrewarmService(Settings.isolated());
|
|
59
|
+
const runtime = await service.get("portless-https");
|
|
60
|
+
runtime.preconnect("https://api.anthropic.com/v1/messages");
|
|
61
|
+
|
|
62
|
+
expect(calls).toEqual(["https://api.anthropic.com:443/v1/messages"]);
|
|
63
|
+
await service.dispose();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("falls back to Bun's accepted TCP form when default-port HTTPS is rejected", async () => {
|
|
67
|
+
const calls: string[] = [];
|
|
68
|
+
const fetchWithPreconnect = Object.assign(async () => new Response("ok"), {
|
|
69
|
+
preconnect: (url: string) => {
|
|
70
|
+
calls.push(url);
|
|
71
|
+
if (url.startsWith("https://")) throw new TypeError("Invalid port");
|
|
72
|
+
},
|
|
73
|
+
}) as typeof fetch & { preconnect: (url: string) => void };
|
|
74
|
+
globalThis.fetch = fetchWithPreconnect;
|
|
75
|
+
|
|
76
|
+
const service = createNetworkPrewarmService(Settings.isolated());
|
|
77
|
+
const runtime = await service.get("bun-1.4.0");
|
|
78
|
+
runtime.preconnect("https://api.anthropic.com");
|
|
79
|
+
|
|
80
|
+
expect(calls).toEqual(["https://api.anthropic.com:443/", "http://api.anthropic.com:443/"]);
|
|
46
81
|
await service.dispose();
|
|
47
82
|
});
|
|
48
83
|
});
|
|
@@ -4,6 +4,24 @@ import { createLazyService, type LazyService } from "./lazy-service";
|
|
|
4
4
|
|
|
5
5
|
type FetchWithPreconnect = typeof fetch & { preconnect?: (url: string) => void };
|
|
6
6
|
|
|
7
|
+
function withDefaultPort(baseUrl: string): { normalized: string; fallback?: string } {
|
|
8
|
+
try {
|
|
9
|
+
const parsed = new URL(baseUrl);
|
|
10
|
+
if (parsed.port || parsed.protocol !== "https:") return { normalized: baseUrl };
|
|
11
|
+
const port = "443";
|
|
12
|
+
const path = `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
13
|
+
const authority = parsed.host;
|
|
14
|
+
const normalized = `${parsed.protocol}//${authority}:${port}${path}`;
|
|
15
|
+
// Bun 1.4.0 rejects the default port after WHATWG URL normalization. Its
|
|
16
|
+
// HTTP-form URL still reaches the same port and keeps the TCP warmup alive
|
|
17
|
+
// until the runtime accepts the canonical HTTPS form.
|
|
18
|
+
const fallback = parsed.protocol === "https:" ? `http://${authority}:${port}${path}` : undefined;
|
|
19
|
+
return { normalized, fallback };
|
|
20
|
+
} catch {
|
|
21
|
+
return { normalized: baseUrl };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
7
25
|
/** Runtime network prewarm and first-request latency diagnostics. */
|
|
8
26
|
export interface NetworkPrewarmRuntime {
|
|
9
27
|
enabled: boolean;
|
|
@@ -30,11 +48,18 @@ export function createNetworkPrewarmService(settings: Settings): LazyService<Net
|
|
|
30
48
|
if (!enabled || !baseUrl) return;
|
|
31
49
|
const preconnect = (globalThis.fetch as FetchWithPreconnect).preconnect;
|
|
32
50
|
if (typeof preconnect !== "function") return;
|
|
51
|
+
const { normalized, fallback } = withDefaultPort(baseUrl);
|
|
33
52
|
try {
|
|
34
|
-
preconnect(
|
|
53
|
+
preconnect(normalized);
|
|
35
54
|
} catch (error) {
|
|
36
|
-
|
|
37
|
-
|
|
55
|
+
if (fallback) {
|
|
56
|
+
try {
|
|
57
|
+
preconnect(fallback);
|
|
58
|
+
return;
|
|
59
|
+
} catch {
|
|
60
|
+
// Fall through to the best-effort diagnostic below.
|
|
61
|
+
}
|
|
62
|
+
}
|
|
38
63
|
logger.debug("Model-host preconnect failed", {
|
|
39
64
|
baseUrl,
|
|
40
65
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -436,6 +436,7 @@ type ResourceDisposer = () => void | Promise<void>;
|
|
|
436
436
|
|
|
437
437
|
const resourceOwners = new Map<string, ResourceDisposer>();
|
|
438
438
|
let resourcePostmortemRegistered = false;
|
|
439
|
+
let activeResourceOwnerDisposals = 0;
|
|
439
440
|
|
|
440
441
|
function ensureResourcePostmortem(): void {
|
|
441
442
|
if (resourcePostmortemRegistered) return;
|
|
@@ -477,23 +478,33 @@ export function resourceOwnerCount(): number {
|
|
|
477
478
|
return resourceOwners.size;
|
|
478
479
|
}
|
|
479
480
|
|
|
481
|
+
/** True while a process-level resource-owner sweep is in progress. */
|
|
482
|
+
export function isResourceOwnerDisposalActive(): boolean {
|
|
483
|
+
return activeResourceOwnerDisposals > 0;
|
|
484
|
+
}
|
|
485
|
+
|
|
480
486
|
/**
|
|
481
487
|
* Run and clear every registered resource disposer. Attempts all disposers even
|
|
482
488
|
* if some throw, then surfaces the failures as an `AggregateError` so callers
|
|
483
489
|
* can distinguish "all closed" from "a resource may still be alive".
|
|
484
490
|
*/
|
|
485
491
|
export async function disposeAllResourceOwners(): Promise<void> {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
492
|
+
activeResourceOwnerDisposals += 1;
|
|
493
|
+
try {
|
|
494
|
+
const disposers = [...resourceOwners.values()];
|
|
495
|
+
resourceOwners.clear();
|
|
496
|
+
const errors: unknown[] = [];
|
|
497
|
+
for (const disposer of disposers) {
|
|
498
|
+
try {
|
|
499
|
+
await disposer();
|
|
500
|
+
} catch (err) {
|
|
501
|
+
errors.push(err);
|
|
502
|
+
}
|
|
494
503
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
504
|
+
if (errors.length > 0) {
|
|
505
|
+
throw new AggregateError(errors, `${errors.length} resource disposer(s) failed during teardown`);
|
|
506
|
+
}
|
|
507
|
+
} finally {
|
|
508
|
+
activeResourceOwnerDisposals -= 1;
|
|
498
509
|
}
|
|
499
510
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Uses the capability system to load MCP servers from multiple sources.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { getMCPConfigPath } from "@gajae-code/utils";
|
|
7
|
+
import { getMCPConfigPath, logger } from "@gajae-code/utils";
|
|
8
8
|
import { mcpCapability } from "../capability/mcp";
|
|
9
9
|
import type { SourceMeta } from "../capability/types";
|
|
10
10
|
import type { Settings } from "../config/settings";
|
|
@@ -16,6 +16,14 @@ import { canonicalizeMCPEndpoint } from "./pool-key";
|
|
|
16
16
|
import { isMCPProtocolPreference } from "./protocol";
|
|
17
17
|
import type { MCPServerConfig } from "./types";
|
|
18
18
|
|
|
19
|
+
function logSkippedServer(name: string, reason: string): void {
|
|
20
|
+
logger.warn("Skipping MCP autoload registration", {
|
|
21
|
+
path: `mcp:${name}`,
|
|
22
|
+
serverName: name,
|
|
23
|
+
reason,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
19
27
|
/** Options for loading MCP configs */
|
|
20
28
|
export interface LoadMCPConfigsOptions {
|
|
21
29
|
/** Owning session settings for capability filtering. */
|
|
@@ -174,9 +182,16 @@ export async function loadAllMCPConfigs(cwd: string, options?: LoadMCPConfigsOpt
|
|
|
174
182
|
for (const server of servers) {
|
|
175
183
|
const config = convertToLegacyConfig(server);
|
|
176
184
|
if (config.enabled === false || disabledServers.has(server.name)) {
|
|
185
|
+
if (!exactConfig) {
|
|
186
|
+
logSkippedServer(
|
|
187
|
+
server.name,
|
|
188
|
+
config.enabled === false ? "registration is disabled" : "server is listed in disabledServers",
|
|
189
|
+
);
|
|
190
|
+
}
|
|
177
191
|
continue;
|
|
178
192
|
}
|
|
179
193
|
if (autoloadOnly && config.autoload === false) {
|
|
194
|
+
if (!exactConfig) logSkippedServer(server.name, "autoload is disabled for this registration");
|
|
180
195
|
continue;
|
|
181
196
|
}
|
|
182
197
|
configs[server.name] = config;
|