@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
|
@@ -155,7 +155,12 @@ import {
|
|
|
155
155
|
MODEL_ONBOARDING_PROVIDER_PRESET_COMMAND,
|
|
156
156
|
MODEL_ONBOARDING_SETUP_COMMAND,
|
|
157
157
|
} from "../../setup/model-onboarding-guidance";
|
|
158
|
-
import {
|
|
158
|
+
import {
|
|
159
|
+
addApiCompatibleProvider,
|
|
160
|
+
formatProviderSetupResult,
|
|
161
|
+
probeOpenAIModelsList,
|
|
162
|
+
reloadAndRefreshDiscoveryCatalog,
|
|
163
|
+
} from "../../setup/provider-onboarding";
|
|
159
164
|
import { getThinkingLevelMetadata } from "../../thinking";
|
|
160
165
|
import {
|
|
161
166
|
isConfigurableSearchProviderId,
|
|
@@ -1821,15 +1826,48 @@ export class SelectorController {
|
|
|
1821
1826
|
this.showSelector(done => {
|
|
1822
1827
|
let wizard: CustomProviderWizardComponent;
|
|
1823
1828
|
const submit = async (input: CustomProviderWizardSubmit): Promise<void> => {
|
|
1829
|
+
// Component-owned generation: revision or cancel after submit
|
|
1830
|
+
// start invalidates this attempt. Both completion branches
|
|
1831
|
+
// check it so a stale refresh cannot report success or
|
|
1832
|
+
// rerender over inputs the user has since revised.
|
|
1833
|
+
const generation = wizard.currentSubmitGeneration();
|
|
1834
|
+
const isCurrentSubmission = (): boolean => wizard.isSubmitCurrent(generation);
|
|
1824
1835
|
try {
|
|
1825
|
-
const result = await addApiCompatibleProvider(
|
|
1826
|
-
|
|
1836
|
+
const result = await addApiCompatibleProvider({
|
|
1837
|
+
...input,
|
|
1838
|
+
authStorage: this.ctx.session.modelRegistry.authStorage,
|
|
1839
|
+
});
|
|
1840
|
+
let recoveryHint: string | null = null;
|
|
1841
|
+
if (result.discoveryEnabled && !result.preset) {
|
|
1842
|
+
// A discovery-only add has no static models and no cache yet,
|
|
1843
|
+
// so an offline reload alone leaves an empty catalog. Refresh
|
|
1844
|
+
// only the new provider online; a hint is surfaced instead
|
|
1845
|
+
// of unconditional success when it stays unavailable.
|
|
1846
|
+
recoveryHint = await reloadAndRefreshDiscoveryCatalog(
|
|
1847
|
+
this.ctx.session.modelRegistry,
|
|
1848
|
+
result.providerId,
|
|
1849
|
+
this.ctx.session.credentialSessionId,
|
|
1850
|
+
);
|
|
1851
|
+
} else {
|
|
1852
|
+
await this.ctx.session.modelRegistry.refresh("offline", this.ctx.session.credentialSessionId);
|
|
1853
|
+
}
|
|
1827
1854
|
await this.ctx.notifyConfigChanged?.();
|
|
1828
|
-
|
|
1855
|
+
// A late settle after Esc-cancel or a mid-submit revision
|
|
1856
|
+
// must not drive completion UI: done() restores the
|
|
1857
|
+
// composer and could close a selector the user opened
|
|
1858
|
+
// after dismissal, and a stale refresh must not report
|
|
1859
|
+
// success over revised inputs.
|
|
1860
|
+
if (!isCurrentSubmission()) return;
|
|
1861
|
+
this.ctx.showStatus(
|
|
1862
|
+
recoveryHint
|
|
1863
|
+
? `${formatProviderSetupResult(result)}\n${recoveryHint}`
|
|
1864
|
+
: formatProviderSetupResult(result),
|
|
1865
|
+
);
|
|
1829
1866
|
wizard.complete();
|
|
1830
1867
|
done();
|
|
1831
1868
|
this.ctx.ui.requestRender();
|
|
1832
1869
|
} catch (err) {
|
|
1870
|
+
if (!isCurrentSubmission()) return;
|
|
1833
1871
|
const message = err instanceof Error ? err.message : String(err);
|
|
1834
1872
|
wizard.setSubmitError(`Provider setup failed: ${message}`);
|
|
1835
1873
|
}
|
|
@@ -1843,6 +1881,9 @@ export class SelectorController {
|
|
|
1843
1881
|
this.ctx.ui.requestRender();
|
|
1844
1882
|
},
|
|
1845
1883
|
() => this.ctx.ui.requestRender(),
|
|
1884
|
+
{
|
|
1885
|
+
discoverModels: async request => probeOpenAIModelsList(request),
|
|
1886
|
+
},
|
|
1846
1887
|
);
|
|
1847
1888
|
return { component: wizard, focus: wizard };
|
|
1848
1889
|
});
|
|
@@ -3070,36 +3111,138 @@ export class SelectorController {
|
|
|
3070
3111
|
});
|
|
3071
3112
|
}
|
|
3072
3113
|
|
|
3073
|
-
|
|
3074
|
-
|
|
3114
|
+
#forkBusyReason(): string | undefined {
|
|
3115
|
+
if (this.ctx.session.isStreaming) {
|
|
3116
|
+
return "Wait for the current response to finish or abort it before forking.";
|
|
3117
|
+
}
|
|
3118
|
+
if (this.ctx.session.isCompacting) {
|
|
3119
|
+
return "Wait for compaction to finish or abort it before forking.";
|
|
3120
|
+
}
|
|
3121
|
+
if (this.ctx.hasPendingSubmission()) {
|
|
3122
|
+
return "Wait for the pending message to be submitted or cancel it before forking.";
|
|
3123
|
+
}
|
|
3124
|
+
if (this.ctx.bashComponent || this.ctx.pythonComponent) {
|
|
3125
|
+
return "Wait for the foreground command to finish or cancel it before forking.";
|
|
3126
|
+
}
|
|
3127
|
+
return undefined;
|
|
3128
|
+
}
|
|
3075
3129
|
|
|
3130
|
+
showUserMessageSelector(onCommitted?: () => void): void {
|
|
3131
|
+
const openedSessionId = this.ctx.sessionManager.getSessionId();
|
|
3132
|
+
const openedSessionFile = this.ctx.sessionManager.getSessionFile();
|
|
3133
|
+
if (!openedSessionFile) {
|
|
3134
|
+
this.ctx.showError("Fork requires a persisted session");
|
|
3135
|
+
return;
|
|
3136
|
+
}
|
|
3137
|
+
const busyReason = this.#forkBusyReason();
|
|
3138
|
+
if (busyReason) {
|
|
3139
|
+
this.ctx.showWarning(busyReason);
|
|
3140
|
+
return;
|
|
3141
|
+
}
|
|
3142
|
+
|
|
3143
|
+
const userMessages = this.ctx.session.getUserMessagesForBranching();
|
|
3076
3144
|
if (userMessages.length === 0) {
|
|
3077
3145
|
this.ctx.showStatus("No messages to branch from");
|
|
3078
3146
|
return;
|
|
3079
3147
|
}
|
|
3080
3148
|
|
|
3149
|
+
this.ctx.goalModeController.cancelContinuation();
|
|
3150
|
+
// Close the side-chat composer before the picker takes ownership, including
|
|
3151
|
+
// paths that cancel, fail, or stop while branch() is pending.
|
|
3152
|
+
if (this.ctx.hasActiveBtw()) this.ctx.handleBtwEscape();
|
|
3153
|
+
|
|
3081
3154
|
this.showSelector(done => {
|
|
3155
|
+
let selectionInFlight = false;
|
|
3156
|
+
const closeWithoutBranch = (message: string, error = false): void => {
|
|
3157
|
+
done();
|
|
3158
|
+
if (error) {
|
|
3159
|
+
this.ctx.showError(message);
|
|
3160
|
+
} else {
|
|
3161
|
+
this.ctx.showStatus(message);
|
|
3162
|
+
}
|
|
3163
|
+
this.ctx.goalModeController.scheduleContinuation();
|
|
3164
|
+
this.ctx.ui.requestRender();
|
|
3165
|
+
};
|
|
3082
3166
|
const selector = new UserMessageSelectorComponent(
|
|
3083
3167
|
userMessages.map(m => ({ id: m.entryId, text: m.text })),
|
|
3084
3168
|
async entryId => {
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
this.ctx.
|
|
3169
|
+
if (selectionInFlight) return;
|
|
3170
|
+
selectionInFlight = true;
|
|
3171
|
+
|
|
3172
|
+
if (
|
|
3173
|
+
this.ctx.sessionManager.getSessionId() !== openedSessionId ||
|
|
3174
|
+
this.ctx.sessionManager.getSessionFile() !== openedSessionFile
|
|
3175
|
+
) {
|
|
3176
|
+
closeWithoutBranch("Fork cancelled because the active session changed", true);
|
|
3177
|
+
return;
|
|
3178
|
+
}
|
|
3179
|
+
const busyReason = this.#forkBusyReason();
|
|
3180
|
+
if (busyReason) {
|
|
3181
|
+
closeWithoutBranch(busyReason);
|
|
3090
3182
|
return;
|
|
3091
3183
|
}
|
|
3092
|
-
this.ctx.resetIrcSidebarSession();
|
|
3093
3184
|
|
|
3094
|
-
|
|
3095
|
-
|
|
3185
|
+
let selectedText = userMessages.find(message => message.entryId === entryId)!.text;
|
|
3186
|
+
let branchFailure: unknown;
|
|
3187
|
+
try {
|
|
3188
|
+
const result = await this.ctx.session.branch(entryId);
|
|
3189
|
+
if (this.ctx.isStopped?.()) return;
|
|
3190
|
+
if (result.cancelled) {
|
|
3191
|
+
closeWithoutBranch("Fork cancelled");
|
|
3192
|
+
return;
|
|
3193
|
+
}
|
|
3194
|
+
selectedText = result.selectedText;
|
|
3195
|
+
} catch (error) {
|
|
3196
|
+
if (this.ctx.isStopped?.()) return;
|
|
3197
|
+
const committed =
|
|
3198
|
+
this.ctx.sessionManager.getSessionId() !== openedSessionId ||
|
|
3199
|
+
this.ctx.sessionManager.getSessionFile() !== openedSessionFile;
|
|
3200
|
+
if (!committed) {
|
|
3201
|
+
closeWithoutBranch(`Fork failed: ${error instanceof Error ? error.message : String(error)}`, true);
|
|
3202
|
+
return;
|
|
3203
|
+
}
|
|
3204
|
+
// The successor is already durable. Never describe this as a
|
|
3205
|
+
// cancelled transition or roll it back to the parent's UI.
|
|
3206
|
+
branchFailure = error;
|
|
3207
|
+
}
|
|
3208
|
+
|
|
3209
|
+
try {
|
|
3210
|
+
onCommitted?.();
|
|
3211
|
+
} catch (error) {
|
|
3212
|
+
branchFailure ??= error;
|
|
3213
|
+
}
|
|
3214
|
+
try {
|
|
3215
|
+
this.ctx.resetIrcSidebarSession();
|
|
3216
|
+
this.ctx.resetObserverRegistry();
|
|
3217
|
+
this.#refreshSessionTerminalTitle();
|
|
3218
|
+
this.ctx.statusLine.invalidate();
|
|
3219
|
+
this.ctx.statusLine.setSessionStartTime(Date.now());
|
|
3220
|
+
this.ctx.updateEditorTopBorder();
|
|
3221
|
+
this.ctx.updateEditorBorderColor();
|
|
3222
|
+
this.ctx.rebuildInitialMessages("replace-identity");
|
|
3223
|
+
await this.ctx.reloadTodos();
|
|
3224
|
+
} catch (error) {
|
|
3225
|
+
branchFailure ??= error;
|
|
3226
|
+
}
|
|
3227
|
+
if (this.ctx.isStopped?.()) return;
|
|
3228
|
+
this.ctx.editor.setText(selectedText);
|
|
3096
3229
|
done();
|
|
3097
|
-
|
|
3230
|
+
if (branchFailure !== undefined) {
|
|
3231
|
+
this.ctx.showError(
|
|
3232
|
+
`Fork created, but session setup failed: ${branchFailure instanceof Error ? branchFailure.message : String(branchFailure)}`,
|
|
3233
|
+
);
|
|
3234
|
+
} else {
|
|
3235
|
+
this.ctx.showStatus("Forked to a new session; edit the selected prompt to continue");
|
|
3236
|
+
}
|
|
3237
|
+
// Do not schedule goal continuation over the selected prompt draft.
|
|
3238
|
+
this.ctx.ui.requestRender();
|
|
3098
3239
|
},
|
|
3099
3240
|
() => {
|
|
3100
3241
|
done();
|
|
3242
|
+
this.ctx.goalModeController.scheduleContinuation();
|
|
3101
3243
|
this.ctx.ui.requestRender();
|
|
3102
3244
|
},
|
|
3245
|
+
() => this.ctx.ui.terminal.rows,
|
|
3103
3246
|
);
|
|
3104
3247
|
return { component: selector, focus: selector.getMessageList() };
|
|
3105
3248
|
});
|
|
@@ -3274,6 +3417,9 @@ export class SelectorController {
|
|
|
3274
3417
|
});
|
|
3275
3418
|
}
|
|
3276
3419
|
},
|
|
3420
|
+
undefined,
|
|
3421
|
+
undefined,
|
|
3422
|
+
(session, starred) => this.ctx.sessionManager.setSessionStarredForPicker(session, starred),
|
|
3277
3423
|
);
|
|
3278
3424
|
selector.setOnRequestRender(() => this.ctx.ui.requestRender());
|
|
3279
3425
|
return { component: selector, focus: selector };
|
|
@@ -2265,10 +2265,24 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
2265
2265
|
}
|
|
2266
2266
|
|
|
2267
2267
|
#prepareSessionSwitch(cleanupPreviousSessionUi?: () => void): void {
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2268
|
+
const errors: unknown[] = [];
|
|
2269
|
+
try {
|
|
2270
|
+
this.#btwController.dispose();
|
|
2271
|
+
} catch (error) {
|
|
2272
|
+
errors.push(error);
|
|
2273
|
+
}
|
|
2274
|
+
try {
|
|
2275
|
+
if (cleanupPreviousSessionUi) cleanupPreviousSessionUi();
|
|
2276
|
+
else this.#extensionUiController.clearExtensionTerminalInputListeners();
|
|
2277
|
+
} catch (error) {
|
|
2278
|
+
errors.push(error);
|
|
2279
|
+
}
|
|
2280
|
+
try {
|
|
2281
|
+
this.#planModeController.clearReview();
|
|
2282
|
+
} catch (error) {
|
|
2283
|
+
errors.push(error);
|
|
2284
|
+
}
|
|
2285
|
+
if (errors.length > 0) throw new AggregateError(errors, "Previous session UI cleanup failed");
|
|
2272
2286
|
}
|
|
2273
2287
|
|
|
2274
2288
|
async handleClearCommand(): Promise<boolean> {
|
|
@@ -2291,7 +2305,6 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
2291
2305
|
}
|
|
2292
2306
|
|
|
2293
2307
|
handleForkCommand(): Promise<void> {
|
|
2294
|
-
this.#btwController.dispose();
|
|
2295
2308
|
return this.#commandController.handleForkCommand();
|
|
2296
2309
|
}
|
|
2297
2310
|
|
|
@@ -2299,7 +2312,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
2299
2312
|
return this.#commandController.handleMoveCommand(targetPath);
|
|
2300
2313
|
}
|
|
2301
2314
|
|
|
2302
|
-
handleRenameCommand(title
|
|
2315
|
+
handleRenameCommand(title?: string): Promise<void> {
|
|
2303
2316
|
return this.#commandController.handleRenameCommand(title);
|
|
2304
2317
|
}
|
|
2305
2318
|
|
|
@@ -2564,7 +2577,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
2564
2577
|
}
|
|
2565
2578
|
|
|
2566
2579
|
showUserMessageSelector(): void {
|
|
2567
|
-
this.#
|
|
2580
|
+
const cleanupPreviousSessionUi = this.#extensionUiController.captureSessionUiCleanup();
|
|
2581
|
+
this.#selectorController.showUserMessageSelector(() => this.#prepareSessionSwitch(cleanupPreviousSessionUi));
|
|
2568
2582
|
}
|
|
2569
2583
|
|
|
2570
2584
|
showTreeSelector(): void {
|
|
@@ -123,6 +123,7 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
123
123
|
getCredentialSessionId: () => session.credentialSessionId,
|
|
124
124
|
isIdle: () => !session.isStreaming,
|
|
125
125
|
getActivePromptHandle: () => session.activePromptHandle,
|
|
126
|
+
getSessionWorkLease: () => session.sessionWorkLease,
|
|
126
127
|
abort: () => session.abort(),
|
|
127
128
|
abortPromptAndWait: (handle, abortOptions) => session.abortPromptAndWait(handle, abortOptions),
|
|
128
129
|
hasPendingMessages: () => session.queuedMessageCount > 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`.
|