@gajae-code/coding-agent 0.18.11 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +760 -0
- package/dist/types/async/job-manager.d.ts +7 -3
- package/dist/types/async/result-formatting.d.ts +2 -0
- package/dist/types/autoresearch/git.d.ts +1 -1
- package/dist/types/capability/fs.d.ts +2 -2
- package/dist/types/capability/rule.d.ts +7 -2
- package/dist/types/cli/accounts-cli.d.ts +2 -2
- package/dist/types/cli/append-system-prompt.d.ts +6 -0
- package/dist/types/cli/args.d.ts +7 -2
- package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
- package/dist/types/cli/customize-doctor.d.ts +4 -3
- package/dist/types/cli/doctor/install-repairs.d.ts +4 -1
- package/dist/types/cli/install-activation.d.ts +10 -4
- package/dist/types/cli/public-command-errors.d.ts +2 -0
- package/dist/types/cli/root-flags.d.ts +0 -12
- package/dist/types/cli/update-cli.d.ts +21 -3
- package/dist/types/cli-main.d.ts +0 -6
- package/dist/types/cli-ordinary.d.ts +2 -2
- package/dist/types/commands/accounts.d.ts +2 -1
- package/dist/types/commands/launch.d.ts +0 -6
- package/dist/types/commands/migrate.d.ts +1 -1
- package/dist/types/commands/sdk.d.ts +13 -0
- package/dist/types/commit/changelog/index.d.ts +1 -0
- package/dist/types/commit/map-reduce/index.d.ts +4 -4
- package/dist/types/config/autorouting-tier-map.d.ts +53 -1
- package/dist/types/config/config-hot-reload-trust.d.ts +12 -0
- package/dist/types/config/config-hot-reload.d.ts +44 -0
- package/dist/types/config/file-lock.d.ts +52 -3
- package/dist/types/config/model-discovery-manager.d.ts +2 -0
- package/dist/types/config/model-profile-activation.d.ts +79 -9
- package/dist/types/config/model-registry.d.ts +72 -8
- package/dist/types/config/model-resolver.d.ts +7 -4
- package/dist/types/config/models-config-schema.d.ts +10 -0
- package/dist/types/config/settings-schema.d.ts +57 -4
- package/dist/types/config/settings.d.ts +33 -1
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/customization/import.d.ts +2 -0
- package/dist/types/customization/types.d.ts +1 -1
- package/dist/types/dap/config.d.ts +8 -4
- package/dist/types/dap/session.d.ts +11 -2
- package/dist/types/debug/system-info.d.ts +6 -1
- package/dist/types/discovery/helpers.d.ts +7 -2
- package/dist/types/discovery/mcp-compat.d.ts +3 -1
- package/dist/types/edit/index.d.ts +5 -0
- package/dist/types/edit/modes/patch.d.ts +14 -0
- package/dist/types/edit/modes/replace.d.ts +3 -0
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +12 -0
- package/dist/types/export/ttsr.d.ts +19 -0
- package/dist/types/extensibility/extensions/types.d.ts +5 -1
- package/dist/types/extensibility/slash-commands.d.ts +1 -0
- package/dist/types/gjc-runtime/managed-owner-admission.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +0 -2
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/content.d.ts +5 -6
- package/dist/types/internal-urls/types.d.ts +2 -0
- package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
- package/dist/types/main.d.ts +23 -18
- package/dist/types/migrate/action-planner.d.ts +10 -1
- package/dist/types/migrate/adapters/codex.d.ts +2 -1
- package/dist/types/migrate/adapters/index.d.ts +42 -1
- package/dist/types/migrate/executor.d.ts +3 -1
- package/dist/types/migrate/hook-module.d.ts +23 -0
- package/dist/types/migrate/report.d.ts +2 -1
- package/dist/types/migrate/types.d.ts +82 -3
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +43 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -0
- package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/utils/host-status.d.ts +15 -11
- package/dist/types/runtime-mcp/content-limits.d.ts +4 -0
- package/dist/types/runtime-mcp/manager.d.ts +7 -0
- package/dist/types/runtime-mcp/plugin-mcp-name-filter.d.ts +22 -0
- package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
- package/dist/types/runtime-mcp/tool-bridge.d.ts +4 -0
- package/dist/types/sdk/broker/broker-exit.d.ts +3 -3
- package/dist/types/sdk/broker/broker.d.ts +29 -2
- package/dist/types/sdk/broker/daemon-entry.d.ts +11 -1
- package/dist/types/sdk/broker/doctor-restart.d.ts +1 -1
- package/dist/types/sdk/broker/ensure.d.ts +141 -9
- package/dist/types/sdk/broker/hop.d.ts +45 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +18 -10
- package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
- package/dist/types/sdk/broker/lock-host-identity.d.ts +5 -0
- package/dist/types/sdk/broker/session-index.d.ts +6 -1
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +44 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
- package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
- package/dist/types/sdk/cli/session-cli.d.ts +0 -1
- package/dist/types/sdk/host/control/operations.d.ts +5 -1
- package/dist/types/sdk/host/events.d.ts +4 -0
- package/dist/types/sdk/host/host.d.ts +2 -1
- package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
- package/dist/types/sdk/host/session-runtime.d.ts +40 -8
- package/dist/types/sdk/host/surface-policy.d.ts +2 -1
- package/dist/types/sdk/lifecycle/service.d.ts +12 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +42 -4
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -0
- package/dist/types/sdk/prompt-status.d.ts +11 -4
- package/dist/types/sdk/protocol/adapter-validation.d.ts +10 -4
- package/dist/types/sdk/reconciliation-extensions.d.ts +1 -1
- package/dist/types/sdk/session-list.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +107 -9
- package/dist/types/session/internal/managed-session-scope.d.ts +2 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +1 -1
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -1
- package/dist/types/session/messages.d.ts +5 -1
- package/dist/types/session/session-manager.d.ts +29 -3
- package/dist/types/session/startup-auth-config.d.ts +24 -2
- package/dist/types/session/streaming-output.d.ts +11 -0
- package/dist/types/session/terminal-abort.d.ts +3 -1
- package/dist/types/session-import/service.d.ts +1 -1
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +20 -4
- package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
- package/dist/types/slash-commands/helpers/provider-auth-status.d.ts +8 -0
- package/dist/types/ssh/ssh-executor.d.ts +8 -1
- package/dist/types/system-prompt.d.ts +3 -2
- package/dist/types/task/executor.d.ts +19 -2
- package/dist/types/task/role-body.d.ts +11 -0
- package/dist/types/tools/ast-edit-write-path.d.ts +10 -0
- package/dist/types/tools/atomic-file-write.d.ts +9 -7
- package/dist/types/tools/awaiting-input.d.ts +28 -0
- package/dist/types/tools/bash-allowed-prefixes.d.ts +17 -0
- package/dist/types/tools/bash-skill-urls.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +7 -0
- package/dist/types/tools/descriptors.d.ts +15 -2
- package/dist/types/tools/fetch.d.ts +7 -1
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/irc.d.ts +5 -3
- package/dist/types/tools/python.d.ts +1 -1
- package/dist/types/tools/report-issue.d.ts +41 -0
- package/dist/types/tools/subagent.d.ts +23 -0
- package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/utils/file-mentions.d.ts +5 -0
- package/dist/types/utils/image-limits.d.ts +7 -0
- package/dist/types/utils/image-loading.d.ts +0 -1
- package/dist/types/utils/open.d.ts +0 -1
- package/dist/types/utils/pasted-image-loading.d.ts +1 -5
- package/dist/types/utils/prompt-suggestion.d.ts +2 -2
- package/dist/types/utils/shell-snapshot.d.ts +2 -0
- package/dist/types/utils/title-generator.d.ts +13 -3
- package/dist/types/web/scrapers/types.d.ts +8 -1
- package/dist/types/web/search/providers/codex.d.ts +6 -7
- package/dist/types/web/search/providers/insane.d.ts +7 -1
- package/dist/types/web/search/providers/searxng.d.ts +5 -0
- package/package.json +10 -9
- package/scripts/acp-conformance-agent.ts +12 -2
- package/scripts/build-binary.ts +2 -1
- package/scripts/capture-subagent-compact-panel-showcase.ts +105 -0
- package/scripts/generate-docs-index.ts +8 -1
- package/scripts/generate-sdk-operation-inventory.ts +38 -4
- package/src/async/job-manager.ts +356 -56
- package/src/async/result-formatting.ts +40 -0
- package/src/autoresearch/git.ts +9 -2
- package/src/autoresearch/prompts/prompt-setup.md +1 -1
- package/src/capability/fs.ts +58 -22
- package/src/capability/index.ts +2 -2
- package/src/capability/rule.ts +11 -2
- package/src/cli/accounts-cli.ts +176 -8
- package/src/cli/append-system-prompt.ts +12 -0
- package/src/cli/args.ts +11 -7
- package/src/cli/auth-broker-cli.ts +21 -11
- package/src/cli/customize-doctor-precedence.ts +31 -0
- package/src/cli/customize-doctor.ts +49 -39
- package/src/cli/doctor/install-repairs.ts +35 -5
- package/src/cli/fast-help.ts +1 -3
- package/src/cli/install-activation.ts +47 -4
- package/src/cli/migrate-cli.ts +19 -6
- package/src/cli/public-command-errors.ts +6 -0
- package/src/cli/root-flags.ts +2 -4
- package/src/cli/stats-cli.ts +9 -5
- package/src/cli/update-cli.ts +471 -13
- package/src/cli-ordinary.ts +7 -2
- package/src/commands/accounts.ts +10 -5
- package/src/commands/harness.ts +25 -15
- package/src/commands/migrate.ts +3 -3
- package/src/commands/sdk.ts +277 -50
- package/src/commands/ultragoal.ts +16 -8
- package/src/commit/agentic/agent.ts +6 -6
- package/src/commit/analysis/conventional.ts +14 -5
- package/src/commit/changelog/index.ts +39 -1
- package/src/commit/map-reduce/index.ts +7 -7
- package/src/commit/message.ts +10 -3
- package/src/commit/pipeline.ts +12 -12
- package/src/config/autorouting-tier-map.ts +50 -1
- package/src/config/config-file.ts +106 -3
- package/src/config/config-hot-reload-trust.ts +148 -0
- package/src/config/config-hot-reload.ts +742 -0
- package/src/config/file-lock.ts +1615 -328
- package/src/config/keybindings.ts +154 -7
- package/src/config/model-bindings-applier.ts +85 -47
- package/src/config/model-discovery-manager.ts +10 -0
- package/src/config/model-profile-activation.ts +889 -148
- package/src/config/model-registry.ts +1706 -205
- package/src/config/model-resolver.ts +52 -22
- package/src/config/models-config-schema.ts +6 -0
- package/src/config/settings-schema.ts +73 -4
- package/src/config/settings.ts +460 -24
- package/src/coordinator-mcp/policy.ts +26 -1
- package/src/coordinator-mcp/server.ts +37 -2
- package/src/crash/sanitize.ts +7 -1
- package/src/customization/import.ts +279 -8
- package/src/customization/inventory.ts +24 -8
- package/src/customization/types.ts +1 -0
- package/src/dap/client.ts +3 -2
- package/src/dap/config.ts +31 -11
- package/src/dap/defaults.json +1 -1
- package/src/dap/session.ts +161 -36
- package/src/debug/crash-diagnostics.ts +89 -6
- package/src/debug/report-bundle.ts +90 -2
- package/src/debug/system-info.ts +8 -3
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +21 -7
- package/src/discovery/agents-md.ts +1 -1
- package/src/discovery/builtin.ts +4 -3
- package/src/discovery/helpers.ts +25 -16
- package/src/discovery/mcp-compat.ts +120 -17
- package/src/edit/apply-patch/index.ts +12 -1
- package/src/edit/index.ts +204 -22
- package/src/edit/modes/patch.ts +214 -8
- package/src/edit/modes/replace.ts +136 -0
- package/src/eval/js/context-manager.ts +29 -3
- package/src/eval/js/worker-entry.ts +51 -18
- package/src/eval/py/executor.ts +14 -4
- package/src/eval/py/runner.py +144 -5
- package/src/eval/py/runtime.ts +44 -4
- package/src/exec/bash-executor.ts +81 -4
- package/src/exec/bash-shell-guardian.ts +4 -1
- package/src/exec/bash-shell-supervisor.ts +8 -4
- package/src/exec/isolated-shell.ts +5 -1
- package/src/exec/non-interactive-env.ts +0 -1
- package/src/export/html/index.ts +86 -6
- package/src/export/ttsr.ts +176 -1
- package/src/extensibility/custom-tools/wrapper.ts +3 -1
- package/src/extensibility/extensions/loader.ts +10 -1
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
- package/src/extensibility/extensions/types.ts +5 -1
- package/src/extensibility/hooks/loader.ts +10 -2
- package/src/extensibility/plugins/marketplace/fetcher.ts +2 -2
- package/src/extensibility/plugins/marketplace/manager.ts +36 -10
- package/src/extensibility/slash-commands.ts +5 -0
- package/src/gjc-runtime/gc-runtime.ts +37 -7
- package/src/gjc-runtime/launch-tmux.ts +30 -15
- package/src/gjc-runtime/launch-worktree.test.ts +148 -0
- package/src/gjc-runtime/launch-worktree.ts +101 -14
- package/src/gjc-runtime/managed-owner-admission.ts +46 -2
- package/src/gjc-runtime/ralplan-current-final.ts +294 -0
- package/src/gjc-runtime/ralplan-runtime.ts +95 -1
- package/src/gjc-runtime/session-resolution.ts +38 -6
- package/src/gjc-runtime/session-state-lock.ts +59 -14
- package/src/gjc-runtime/state-runtime.ts +23 -19
- package/src/gjc-runtime/state-writer.ts +109 -5
- package/src/gjc-runtime/tmux-sessions.ts +93 -13
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
- package/src/gjc-runtime/ultragoal-guard.ts +9 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
- package/src/harness-control-plane/finalize.ts +11 -0
- package/src/harness-control-plane/receipt-spool.ts +105 -28
- package/src/harness-control-plane/storage.ts +124 -6
- package/src/hindsight/content.ts +116 -16
- package/src/hindsight/mental-models.ts +22 -10
- package/src/hindsight/state.ts +7 -4
- package/src/hooks/native-skill-hook.ts +17 -12
- package/src/internal-urls/artifact-protocol.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +23 -22
- package/src/internal-urls/local-protocol.ts +167 -8
- package/src/internal-urls/types.ts +2 -0
- package/src/lsp/client.ts +2 -1
- package/src/lsp/clients/biome-client.ts +2 -0
- package/src/lsp/clients/swiftlint-client.ts +2 -0
- package/src/lsp/index.ts +29 -0
- package/src/lsp/workspace-path.ts +23 -0
- package/src/main.ts +330 -92
- package/src/memories/index.ts +25 -2
- package/src/migrate/action-planner.ts +574 -2
- package/src/migrate/adapters/claude-code.ts +162 -5
- package/src/migrate/adapters/codex.ts +77 -7
- package/src/migrate/adapters/index.ts +258 -5
- package/src/migrate/adapters/opencode.ts +10 -1
- package/src/migrate/executor.ts +222 -7
- package/src/migrate/hook-module.ts +193 -0
- package/src/migrate/report.ts +63 -2
- package/src/migrate/types.ts +84 -4
- package/src/modes/DESIGN.md +51 -0
- package/src/modes/acp/acp-agent.ts +10 -1
- package/src/modes/acp/permission-mode.ts +18 -1
- package/src/modes/components/agent-dashboard.ts +20 -4
- package/src/modes/components/assistant-message.ts +55 -1
- package/src/modes/components/customization/customization-dashboard.ts +7 -0
- package/src/modes/components/customization/import-wizard.ts +29 -3
- package/src/modes/components/model-selector.ts +157 -103
- package/src/modes/components/settings-selector.ts +103 -37
- package/src/modes/components/welcome.ts +3 -1
- package/src/modes/controllers/command-controller.ts +300 -9
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/extension-ui-controller.ts +31 -1
- package/src/modes/controllers/goal-mode-controller.ts +79 -10
- package/src/modes/controllers/input-controller.ts +2 -0
- package/src/modes/controllers/plan-mode-controller.ts +66 -11
- package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
- package/src/modes/controllers/selector-controller.ts +76 -7
- package/src/modes/interactive-mode.ts +123 -4
- package/src/modes/prompt-suggestion-controller.ts +1 -1
- package/src/modes/runtime-init.ts +5 -1
- package/src/modes/theme/theme.ts +15 -0
- package/src/modes/utils/host-status.ts +21 -10
- package/src/prompts/agent-fragments/browser-aside.md +2 -2
- package/src/prompts/system/irc-incoming.md +3 -1
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/irc.md +1 -1
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/report-issue.md +13 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-credential-selector.ts +2 -2
- package/src/runtime-mcp/content-limits.ts +7 -0
- package/src/runtime-mcp/manager-pool.test.ts +5 -4
- package/src/runtime-mcp/manager.ts +40 -3
- package/src/runtime-mcp/oauth-flow.ts +32 -6
- package/src/runtime-mcp/plugin-mcp-name-filter.ts +62 -0
- package/src/runtime-mcp/project-host-values.ts +12 -8
- package/src/runtime-mcp/render.ts +16 -1
- package/src/runtime-mcp/tool-bridge.ts +194 -21
- package/src/runtime-mcp/transports/stdio.ts +2 -1
- package/src/sdk/broker/broker-exit.ts +10 -5
- package/src/sdk/broker/broker.ts +484 -85
- package/src/sdk/broker/daemon-entry.ts +338 -116
- package/src/sdk/broker/doctor-restart.ts +2 -1
- package/src/sdk/broker/ensure.ts +1214 -268
- package/src/sdk/broker/hop.ts +286 -0
- package/src/sdk/broker/lifecycle-ledger.ts +38 -11
- package/src/sdk/broker/lifecycle.ts +102 -6
- package/src/sdk/broker/lock-host-identity.ts +29 -0
- package/src/sdk/broker/session-index.ts +91 -16
- package/src/sdk/broker/transport.ts +17 -1
- package/src/sdk/bus/chat-command-policy.ts +16 -3
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/index.ts +460 -35
- package/src/sdk/bus/reconciliation-store.ts +201 -8
- package/src/sdk/bus/session-control.ts +2 -0
- package/src/sdk/bus/slack-daemon.ts +105 -9
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -2
- package/src/sdk/bus/threaded-render.ts +20 -1
- package/src/sdk/cli/session-cli.ts +23 -6
- package/src/sdk/host/control/dispatch.ts +13 -1
- package/src/sdk/host/control/operations.ts +10 -1
- package/src/sdk/host/events.ts +67 -4
- package/src/sdk/host/host.ts +8 -2
- package/src/sdk/host/prompt-image-upload.ts +438 -0
- package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
- package/src/sdk/host/session-runtime.test.ts +1737 -129
- package/src/sdk/host/session-runtime.ts +684 -83
- package/src/sdk/host/surface-policy.ts +4 -0
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
- package/src/sdk/host/websocket-transport.ts +19 -7
- package/src/sdk/lifecycle/service.ts +15 -1
- package/src/sdk/prompt-deadline-flush.ts +78 -5
- package/src/sdk/prompt-deadline-manager.ts +68 -14
- package/src/sdk/prompt-status.ts +6 -4
- package/src/sdk/protocol/adapter-validation.ts +81 -12
- package/src/sdk/protocol/operation-inventory.generated.json +261 -2
- package/src/sdk/protocol/operation-registry.ts +33 -3
- package/src/sdk/reconciliation-extensions.ts +1 -0
- package/src/sdk/session-list.ts +1 -0
- package/src/sdk/session.ts +237 -97
- package/src/session/agent-session.ts +2726 -479
- package/src/session/history-storage.ts +182 -12
- package/src/session/internal/managed-session-scope.ts +173 -57
- package/src/session/internal/managed-session-storage.ts +85 -12
- package/src/session/internal/native-publish-outcome.ts +5 -1
- package/src/session/messages.ts +47 -6
- package/src/session/session-manager.ts +326 -19
- package/src/session/startup-auth-config.ts +116 -8
- package/src/session/streaming-output.ts +262 -4
- package/src/session/terminal-abort.ts +14 -2
- package/src/session-import/redact.ts +53 -2
- package/src/session-import/service.ts +1 -0
- package/src/skill-state/workflow-mutation-guard.ts +2145 -206
- package/src/slash-commands/builtin-registry.ts +21 -6
- package/src/slash-commands/helpers/credential-switch.ts +10 -5
- package/src/slash-commands/helpers/mcp.ts +11 -3
- package/src/slash-commands/helpers/provider-auth-status.ts +456 -0
- package/src/ssh/ssh-executor.ts +9 -2
- package/src/stt/recorder.ts +26 -9
- package/src/system-prompt.ts +61 -16
- package/src/task/executor.ts +115 -20
- package/src/task/index.ts +389 -175
- package/src/task/role-body.ts +84 -0
- package/src/task/token-log-mode.test.ts +162 -0
- package/src/task/token-log.ts +91 -2
- package/src/tools/archive-reader.ts +650 -37
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-edit-write-path.ts +64 -0
- package/src/tools/ast-edit.ts +18 -1
- package/src/tools/ast-grep.ts +7 -2
- package/src/tools/atomic-file-write.ts +46 -15
- package/src/tools/auto-generated-guard.ts +15 -3
- package/src/tools/awaiting-input.ts +114 -0
- package/src/tools/bash-allowed-prefixes.ts +214 -6
- package/src/tools/bash-interactive.ts +14 -2
- package/src/tools/bash-skill-urls.ts +58 -5
- package/src/tools/bash.ts +113 -26
- package/src/tools/browser/tab-worker.ts +39 -13
- package/src/tools/browser.ts +17 -7
- package/src/tools/cron.ts +10 -1
- package/src/tools/debug.ts +16 -8
- package/src/tools/descriptors.test.ts +44 -0
- package/src/tools/descriptors.ts +50 -6
- package/src/tools/eval.ts +15 -0
- package/src/tools/fetch.ts +93 -4
- package/src/tools/gh.ts +27 -12
- package/src/tools/image-gen.ts +20 -6
- package/src/tools/index.ts +2 -0
- package/src/tools/irc.ts +5 -3
- package/src/tools/monitor.ts +9 -1
- package/src/tools/output-meta.ts +74 -5
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +26 -37
- package/src/tools/recipe/runner.ts +23 -12
- package/src/tools/render-utils.ts +2 -2
- package/src/tools/report-issue.ts +184 -0
- package/src/tools/search.ts +3 -2
- package/src/tools/ssh.ts +274 -8
- package/src/tools/subagent-render.ts +114 -12
- package/src/tools/subagent.ts +118 -5
- package/src/tools/tmux-self-injection-guard.ts +3301 -122
- package/src/tools/todo-write.ts +41 -3
- package/src/tools/tool-catalog.generated.ts +32 -4
- package/src/tools/ultragoal-ask-guard.ts +13 -1
- package/src/tools/write.ts +42 -3
- package/src/tui/tree-list.ts +15 -1
- package/src/utils/commit-message-generator.ts +12 -4
- package/src/utils/external-editor.ts +21 -7
- package/src/utils/file-mentions.ts +75 -7
- package/src/utils/git.ts +38 -7
- package/src/utils/image-limits.ts +8 -0
- package/src/utils/image-loading.ts +1 -1
- package/src/utils/open.ts +73 -4
- package/src/utils/pasted-image-loading.ts +9 -8
- package/src/utils/prompt-suggestion.ts +5 -4
- package/src/utils/shell-snapshot.ts +9 -1
- package/src/utils/title-generator.ts +72 -22
- package/src/web/scrapers/index.ts +3 -1
- package/src/web/scrapers/types.ts +8 -0
- package/src/web/scrapers/youtube.ts +3 -2
- package/src/web/search/index.ts +2 -1
- package/src/web/search/providers/codex.ts +29 -32
- package/src/web/search/providers/insane.ts +91 -28
- package/src/web/search/providers/searxng.ts +62 -10
|
@@ -80,6 +80,7 @@ export interface SdkSurfacePolicy {
|
|
|
80
80
|
export interface SdkSurfacePolicyOptions {
|
|
81
81
|
bindings: Iterable<string>;
|
|
82
82
|
workflowGateAvailable: boolean;
|
|
83
|
+
imageUploadsAvailable?: boolean;
|
|
83
84
|
isBindingInstalled?: (binding: string) => boolean;
|
|
84
85
|
}
|
|
85
86
|
|
|
@@ -96,6 +97,7 @@ export function createSdkSurfacePolicy(options: SdkSurfacePolicyOptions): SdkSur
|
|
|
96
97
|
operation.kind === kind &&
|
|
97
98
|
!BROKER_LIFECYCLE_CONTROL_OPERATIONS.has(operation.sdkId) &&
|
|
98
99
|
!UNINSTALLED_CONTROL_OPERATIONS.has(operation.sdkId) &&
|
|
100
|
+
(!operation.sdkId.startsWith("turn.image.") || options.imageUploadsAvailable === true) &&
|
|
99
101
|
(!WORKFLOW_GATE_CONTROL_OPERATIONS.has(operation.sdkId) || options.workflowGateAvailable) &&
|
|
100
102
|
(!required[operation.sdkId] || hasBinding(required[operation.sdkId]!)),
|
|
101
103
|
).map(operation => operation.sdkId),
|
|
@@ -129,11 +131,13 @@ export function createSdkCapabilities(
|
|
|
129
131
|
export function createSdkSurfacePolicyForContext(
|
|
130
132
|
ctx: ExtensionContext,
|
|
131
133
|
workflowGateAvailable = false,
|
|
134
|
+
imageUploadsAvailable = false,
|
|
132
135
|
): SdkSurfacePolicy {
|
|
133
136
|
const bindings = ctx.sdkBindings?.() ?? [];
|
|
134
137
|
return createSdkSurfacePolicy({
|
|
135
138
|
bindings,
|
|
136
139
|
workflowGateAvailable,
|
|
140
|
+
imageUploadsAvailable,
|
|
137
141
|
isBindingInstalled: binding => typeof (ctx as unknown as Record<string, unknown>)[binding] === "function",
|
|
138
142
|
});
|
|
139
143
|
}
|
|
@@ -3,6 +3,7 @@ import * as fs from "node:fs/promises";
|
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { SdkClient } from "../client/client";
|
|
6
|
+
import { SESSION_HOST_OBSERVER_CAPABILITY, TURN_STREAM_CAPABILITY } from "./host";
|
|
6
7
|
import { SessionSdkSessionRuntime, type SessionSdkTransport } from "./session-runtime";
|
|
7
8
|
import { createSdkWebSocketTransport, type SdkWebSocketTransportDependencies } from "./websocket-transport";
|
|
8
9
|
|
|
@@ -29,6 +30,28 @@ async function probeWebSocketEndpoint(url: string, token: string): Promise<void>
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
async function waitForFrame(
|
|
34
|
+
frames: readonly Record<string, unknown>[],
|
|
35
|
+
predicate: (frame: Record<string, unknown>) => boolean,
|
|
36
|
+
label: string,
|
|
37
|
+
): Promise<Record<string, unknown>> {
|
|
38
|
+
const deadline = Date.now() + 5_000;
|
|
39
|
+
while (true) {
|
|
40
|
+
const frame = frames.find(predicate);
|
|
41
|
+
if (frame) return frame;
|
|
42
|
+
if (Date.now() >= deadline) throw new Error(`Timed out waiting for ${label}`);
|
|
43
|
+
await Bun.sleep(5);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function waitFor(predicate: () => boolean, label: string): Promise<void> {
|
|
48
|
+
const deadline = Date.now() + 5_000;
|
|
49
|
+
while (!predicate()) {
|
|
50
|
+
if (Date.now() >= deadline) throw new Error(`Timed out waiting for ${label}`);
|
|
51
|
+
await Bun.sleep(5);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
32
55
|
describe("SDK WebSocket transport lifecycle", () => {
|
|
33
56
|
test("concurrent start calls share one endpoint and one server", async () => {
|
|
34
57
|
const stateRoot = await tempStateRoot();
|
|
@@ -193,7 +216,72 @@ describe("SDK WebSocket transport lifecycle", () => {
|
|
|
193
216
|
await fs.rm(stateRoot, { recursive: true, force: true });
|
|
194
217
|
}
|
|
195
218
|
});
|
|
196
|
-
test("
|
|
219
|
+
test("loopback replay preserves replay-first, split, and subset capability negotiation", async () => {
|
|
220
|
+
const stateRoot = await tempStateRoot();
|
|
221
|
+
const transport = await createSdkWebSocketTransport({
|
|
222
|
+
sessionId: "loopback-split-capabilities",
|
|
223
|
+
stateRoot,
|
|
224
|
+
token: "token",
|
|
225
|
+
});
|
|
226
|
+
const runtime = new SessionSdkSessionRuntime({ transport });
|
|
227
|
+
const frames: Record<string, unknown>[] = [];
|
|
228
|
+
let socket: WebSocket | undefined;
|
|
229
|
+
const required = [TURN_STREAM_CAPABILITY, SESSION_HOST_OBSERVER_CAPABILITY];
|
|
230
|
+
try {
|
|
231
|
+
const endpoint = await runtime.start();
|
|
232
|
+
socket = new WebSocket(`${endpoint.url}?token=token`);
|
|
233
|
+
socket.addEventListener("message", event => {
|
|
234
|
+
frames.push(JSON.parse(String((event as MessageEvent).data)) as Record<string, unknown>);
|
|
235
|
+
});
|
|
236
|
+
await waitForFrame(frames, frame => frame.type === "hello", "server hello");
|
|
237
|
+
socket.send(
|
|
238
|
+
JSON.stringify({
|
|
239
|
+
type: "event_replay",
|
|
240
|
+
id: "replay-before-hello",
|
|
241
|
+
sinceSeq: 0,
|
|
242
|
+
capabilities: [],
|
|
243
|
+
}),
|
|
244
|
+
);
|
|
245
|
+
await waitForFrame(
|
|
246
|
+
frames,
|
|
247
|
+
frame => frame.type === "event_replay_result" && frame.id === "replay-before-hello",
|
|
248
|
+
"replay before hello",
|
|
249
|
+
);
|
|
250
|
+
socket.send(JSON.stringify({ type: "hello", protocolVersion: 3, capabilities: [TURN_STREAM_CAPABILITY] }));
|
|
251
|
+
await waitFor(
|
|
252
|
+
() => runtime.connectionIdsWithCapabilities([TURN_STREAM_CAPABILITY]).length === 1,
|
|
253
|
+
"hello after replay",
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
const replayIds = ["observer-addition", "observer-subset", "observer-empty"];
|
|
257
|
+
for (const [index, capabilities] of [
|
|
258
|
+
[SESSION_HOST_OBSERVER_CAPABILITY],
|
|
259
|
+
[SESSION_HOST_OBSERVER_CAPABILITY],
|
|
260
|
+
[],
|
|
261
|
+
].entries()) {
|
|
262
|
+
const id = replayIds[index]!;
|
|
263
|
+
socket.send(JSON.stringify({ type: "event_replay", id, sinceSeq: 0, capabilities }));
|
|
264
|
+
await waitForFrame(frames, frame => frame.type === "event_replay_result" && frame.id === id, id);
|
|
265
|
+
expect(runtime.connectionIdsWithCapabilities(required)).toHaveLength(1);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
runtime.sendFrameToCapabilities(required, {
|
|
269
|
+
type: "event",
|
|
270
|
+
kind: "tool_activity",
|
|
271
|
+
payload: { phase: "started" },
|
|
272
|
+
});
|
|
273
|
+
await waitForFrame(
|
|
274
|
+
frames,
|
|
275
|
+
frame => frame.type === "event" && frame.kind === "tool_activity",
|
|
276
|
+
"live observer event",
|
|
277
|
+
);
|
|
278
|
+
} finally {
|
|
279
|
+
socket?.close();
|
|
280
|
+
await runtime.stop().catch(() => undefined);
|
|
281
|
+
await fs.rm(stateRoot, { recursive: true, force: true });
|
|
282
|
+
}
|
|
283
|
+
}, 30_000);
|
|
284
|
+
test("event replay keeps tool activity gated without tool_activity_v2", async () => {
|
|
197
285
|
const stateRoot = await tempStateRoot();
|
|
198
286
|
const transport = await createSdkWebSocketTransport({
|
|
199
287
|
sessionId: "replay-capability-claim",
|
|
@@ -223,7 +311,7 @@ describe("SDK WebSocket transport lifecycle", () => {
|
|
|
223
311
|
id: "forged-capability-claim",
|
|
224
312
|
sinceGeneration: 1,
|
|
225
313
|
sinceSeq: 0,
|
|
226
|
-
capabilities: [
|
|
314
|
+
capabilities: [SESSION_HOST_OBSERVER_CAPABILITY],
|
|
227
315
|
}),
|
|
228
316
|
);
|
|
229
317
|
const frame = await replay;
|
|
@@ -3,6 +3,7 @@ import * as fs from "node:fs/promises";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { exactUnlink, type NativeExactFileIdentity } from "@gajae-code/natives";
|
|
5
5
|
import {
|
|
6
|
+
AWAITING_INPUT_CAPABILITY,
|
|
6
7
|
canDeliverSdkEvent,
|
|
7
8
|
SESSION_HOST_OBSERVER_CAPABILITY,
|
|
8
9
|
TOOL_ACTIVITY_CAPABILITY,
|
|
@@ -167,6 +168,9 @@ export async function createSdkWebSocketTransport(
|
|
|
167
168
|
if (!socket) throw new Error("SDK connection is no longer available.");
|
|
168
169
|
socket.send(JSON.stringify(frame));
|
|
169
170
|
},
|
|
171
|
+
isConnectionOpen(connectionId) {
|
|
172
|
+
return sockets.has(connectionId);
|
|
173
|
+
},
|
|
170
174
|
start: async () => {
|
|
171
175
|
if (stopPromise) await stopPromise;
|
|
172
176
|
if (startPromise) return await startPromise;
|
|
@@ -203,6 +207,7 @@ export async function createSdkWebSocketTransport(
|
|
|
203
207
|
protocolVersion: 3,
|
|
204
208
|
connectionId: socket.data.connectionId,
|
|
205
209
|
capabilities: [
|
|
210
|
+
AWAITING_INPUT_CAPABILITY,
|
|
206
211
|
TOOL_ACTIVITY_CAPABILITY,
|
|
207
212
|
TURN_STREAM_CAPABILITY,
|
|
208
213
|
SESSION_HOST_OBSERVER_CAPABILITY,
|
|
@@ -226,16 +231,23 @@ export async function createSdkWebSocketTransport(
|
|
|
226
231
|
);
|
|
227
232
|
return;
|
|
228
233
|
}
|
|
229
|
-
|
|
234
|
+
const isInitialHello =
|
|
230
235
|
frame.type === "hello" &&
|
|
231
236
|
frame.protocolVersion === 3 &&
|
|
232
|
-
(
|
|
233
|
-
|
|
237
|
+
!helloReceived.has(socket.data.connectionId);
|
|
238
|
+
if (
|
|
239
|
+
(isInitialHello || frame.type === "event_replay") &&
|
|
240
|
+
(frame.capabilities === undefined ||
|
|
241
|
+
(Array.isArray(frame.capabilities) &&
|
|
242
|
+
frame.capabilities.every((value: unknown) => typeof value === "string")))
|
|
234
243
|
) {
|
|
235
|
-
const capabilities =
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
244
|
+
const capabilities = [
|
|
245
|
+
...new Set([
|
|
246
|
+
...(negotiatedCapabilities.get(socket.data.connectionId) ?? []),
|
|
247
|
+
...((frame.capabilities as string[] | undefined) ?? []),
|
|
248
|
+
]),
|
|
249
|
+
];
|
|
250
|
+
if (isInitialHello) helloReceived.add(socket.data.connectionId);
|
|
239
251
|
negotiatedCapabilities.set(socket.data.connectionId, new Set(capabilities));
|
|
240
252
|
capabilitiesHandler?.(socket.data.connectionId, capabilities);
|
|
241
253
|
}
|
|
@@ -101,6 +101,10 @@ export type SessionCreateTarget = SessionLifecycleCoordinatorTarget & {
|
|
|
101
101
|
readonly body?: string;
|
|
102
102
|
readonly modelPreset?: string;
|
|
103
103
|
readonly mcpServers?: readonly Record<string, unknown>[];
|
|
104
|
+
/** Per-session environment for the hosted session; `GJC_*` names are reserved (#6735). */
|
|
105
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
106
|
+
/** Inherited broker environment names removed from the hosted session (#6735). */
|
|
107
|
+
readonly unsetEnv?: readonly string[];
|
|
104
108
|
readonly worktree?: SessionLifecycleWorktreeTarget;
|
|
105
109
|
readonly readiness?: "immediate" | "deferred";
|
|
106
110
|
readonly readinessTimeoutMs?: number;
|
|
@@ -115,6 +119,10 @@ export type SessionForkTarget = SessionLifecycleCoordinatorTarget & {
|
|
|
115
119
|
readonly body?: string;
|
|
116
120
|
readonly modelPreset?: string;
|
|
117
121
|
readonly mcpServers?: readonly Record<string, unknown>[];
|
|
122
|
+
/** Per-session environment for the hosted session; `GJC_*` names are reserved (#6735). */
|
|
123
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
124
|
+
/** Inherited broker environment names removed from the hosted session (#6735). */
|
|
125
|
+
readonly unsetEnv?: readonly string[];
|
|
118
126
|
readonly worktree?: SessionLifecycleWorktreeTarget;
|
|
119
127
|
readonly readinessTimeoutMs?: number;
|
|
120
128
|
};
|
|
@@ -128,6 +136,10 @@ export type SessionResumeTarget = SessionLifecycleCoordinatorTarget & {
|
|
|
128
136
|
readonly body?: string;
|
|
129
137
|
readonly modelPreset?: string;
|
|
130
138
|
readonly mcpServers?: readonly Record<string, unknown>[];
|
|
139
|
+
/** Per-session environment for the hosted session; `GJC_*` names are reserved (#6735). */
|
|
140
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
141
|
+
/** Inherited broker environment names removed from the hosted session (#6735). */
|
|
142
|
+
readonly unsetEnv?: readonly string[];
|
|
131
143
|
readonly worktree?: SessionLifecycleWorktreeTarget;
|
|
132
144
|
readonly readinessTimeoutMs?: number;
|
|
133
145
|
};
|
|
@@ -550,7 +562,7 @@ export function validateSessionLifecycleMutationRequest(request: unknown): Sessi
|
|
|
550
562
|
}
|
|
551
563
|
|
|
552
564
|
function certaintyForBrokerCode(code: string): SessionLifecycleCertainty {
|
|
553
|
-
if (code === "terminal_uncertain") return "uncertain";
|
|
565
|
+
if (code === "terminal_uncertain" || code === "legacy_lifecycle_ambiguous") return "uncertain";
|
|
554
566
|
if (code === "cleanup_pending") return "cleanup_pending";
|
|
555
567
|
if (RETRYABLE_BROKER_ERRORS.has(code)) return "retryable";
|
|
556
568
|
return "terminal";
|
|
@@ -686,6 +698,7 @@ const savedSessionScopeDetailCodes = new Set([
|
|
|
686
698
|
"migration_busy",
|
|
687
699
|
"atomic_unavailable",
|
|
688
700
|
"invalid_request",
|
|
701
|
+
"permission_denied",
|
|
689
702
|
"durability_failed",
|
|
690
703
|
"durability_not_provable",
|
|
691
704
|
"capacity_exceeded",
|
|
@@ -700,6 +713,7 @@ const savedSessionCandidateDetailCodes = new Set([
|
|
|
700
713
|
"cwd_not_utf8",
|
|
701
714
|
"cwd_network_unsupported",
|
|
702
715
|
"cwd_identity_unavailable",
|
|
716
|
+
"permission_denied",
|
|
703
717
|
"cwd_io_error",
|
|
704
718
|
]);
|
|
705
719
|
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
* WHERE it runs. `sdk.flushWorktreeOnDeadline` still defaults to on, but the
|
|
45
45
|
* implicit default applies only in a LINKED worktree (`gitDir !== commonDir`) —
|
|
46
46
|
* what agent/paseo sessions run in, and the #5583 field report. In the user's
|
|
47
|
-
* primary checkout an autosave needs an explicit opt-in
|
|
47
|
+
* primary checkout an autosave needs an explicit opt-in from the user/global
|
|
48
|
+
* config or a runtime override. A project `.gjc` file is not that opt-in.
|
|
48
49
|
*/
|
|
49
50
|
|
|
50
51
|
import * as fsp from "node:fs/promises";
|
|
@@ -66,9 +67,10 @@ export interface PromptDeadlineFlushOptions {
|
|
|
66
67
|
/** Active session's agent directory, used to keep volatile broker state out of the WIP commit. */
|
|
67
68
|
readonly agentDir?: string;
|
|
68
69
|
/**
|
|
69
|
-
* Whether the caller resolved `sdk.flushWorktreeOnDeadline` to `true` from
|
|
70
|
-
*
|
|
71
|
-
*
|
|
70
|
+
* Whether the caller resolved `sdk.flushWorktreeOnDeadline` to `true` from the
|
|
71
|
+
* user/global config or a runtime override, rather than from the schema
|
|
72
|
+
* default or a project `.gjc` file. Only that opt-in may autosave outside a
|
|
73
|
+
* linked worktree.
|
|
72
74
|
*/
|
|
73
75
|
readonly explicitOptIn?: boolean;
|
|
74
76
|
/**
|
|
@@ -162,6 +164,76 @@ function isLinkedWorktree(repository: git.GitRepository): boolean {
|
|
|
162
164
|
return path.resolve(repository.gitDir) !== path.resolve(repository.commonDir);
|
|
163
165
|
}
|
|
164
166
|
|
|
167
|
+
const DEADLINE_FLUSH_SETTING = "sdk.flushWorktreeOnDeadline";
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* The settings view both deadline hosts already hold. `get` is the merged value
|
|
171
|
+
* (global, then project, then runtime override, otherwise the schema default).
|
|
172
|
+
* `getGlobal` and `getOverride` are the layers a project file cannot write.
|
|
173
|
+
*/
|
|
174
|
+
export interface DeadlineFlushSettings {
|
|
175
|
+
get(path: typeof DEADLINE_FLUSH_SETTING): unknown;
|
|
176
|
+
getAgentDir?(): string | undefined;
|
|
177
|
+
getGlobal?(path: typeof DEADLINE_FLUSH_SETTING): unknown;
|
|
178
|
+
getOverride?(path: typeof DEADLINE_FLUSH_SETTING): unknown;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* True only when the user wrote `sdk.flushWorktreeOnDeadline: true` in a runtime
|
|
183
|
+
* override or the global config. The schema default and a project `.gjc` file
|
|
184
|
+
* do not count: `Settings.has()` sees the merged view, so a repo-shipped `true`
|
|
185
|
+
* would otherwise open the primary-checkout gate.
|
|
186
|
+
*/
|
|
187
|
+
export function explicitDeadlineFlushOptIn(settings: DeadlineFlushSettings | undefined): boolean {
|
|
188
|
+
if (!settings) return false;
|
|
189
|
+
if (typeof settings.getOverride === "function") {
|
|
190
|
+
const override = settings.getOverride(DEADLINE_FLUSH_SETTING);
|
|
191
|
+
if (override !== undefined) return override === true;
|
|
192
|
+
}
|
|
193
|
+
if (typeof settings.getGlobal === "function") return settings.getGlobal(DEADLINE_FLUSH_SETTING) === true;
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Whether this deadline must not autosave.
|
|
199
|
+
*
|
|
200
|
+
* A runtime override wins, then the user/global value. A project file cannot
|
|
201
|
+
* cancel either one. A project `false` still opts out when the user has not
|
|
202
|
+
* written the key.
|
|
203
|
+
*/
|
|
204
|
+
export function deadlineFlushSuppressed(settings: DeadlineFlushSettings | undefined): boolean {
|
|
205
|
+
if (!settings) return false;
|
|
206
|
+
if (typeof settings.getOverride === "function") {
|
|
207
|
+
const override = settings.getOverride(DEADLINE_FLUSH_SETTING);
|
|
208
|
+
if (override === false) return true;
|
|
209
|
+
if (override === true) return false;
|
|
210
|
+
}
|
|
211
|
+
if (typeof settings.getGlobal === "function") {
|
|
212
|
+
const globalValue = settings.getGlobal(DEADLINE_FLUSH_SETTING);
|
|
213
|
+
if (globalValue === false) return true;
|
|
214
|
+
if (globalValue === true) return false;
|
|
215
|
+
}
|
|
216
|
+
return settings.get(DEADLINE_FLUSH_SETTING) === false;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Deadline-host entry for the worktree autosave. Both the session runtime and
|
|
221
|
+
* the notification bus call this so the opt-in decision cannot drift.
|
|
222
|
+
*/
|
|
223
|
+
export async function autosaveWorktreeOnPromptDeadline(
|
|
224
|
+
cwd: string,
|
|
225
|
+
settings: DeadlineFlushSettings | undefined,
|
|
226
|
+
options?: { readonly isCurrent?: () => boolean; readonly signal?: AbortSignal },
|
|
227
|
+
): Promise<PromptDeadlineFlushResult | undefined> {
|
|
228
|
+
if (deadlineFlushSuppressed(settings)) return undefined;
|
|
229
|
+
return flushWorktreeOnPromptDeadline(cwd, {
|
|
230
|
+
agentDir: settings?.getAgentDir?.(),
|
|
231
|
+
explicitOptIn: explicitDeadlineFlushOptIn(settings),
|
|
232
|
+
isCurrent: options?.isCurrent,
|
|
233
|
+
signal: options?.signal,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
165
237
|
/**
|
|
166
238
|
* Commit any uncommitted work in the worktree owning `cwd`.
|
|
167
239
|
*
|
|
@@ -195,7 +267,8 @@ export async function flushWorktreeOnPromptDeadline(
|
|
|
195
267
|
if (!explicitOptIn && !isLinkedWorktree(repository)) {
|
|
196
268
|
logger.debug(
|
|
197
269
|
`sdk: prompt deadline worktree autosave skipped; ${worktreeRoot} is a primary checkout the session does ` +
|
|
198
|
-
`not own. Set sdk.flushWorktreeOnDeadline to true to
|
|
270
|
+
`not own. Set sdk.flushWorktreeOnDeadline to true in the user config or a runtime override to ` +
|
|
271
|
+
`autosave here anyway.`,
|
|
199
272
|
);
|
|
200
273
|
return undefined;
|
|
201
274
|
}
|
|
@@ -103,10 +103,18 @@ export class PromptDeadlineManager {
|
|
|
103
103
|
readonly #uncertaintyRecoveryPending = new Set<string>();
|
|
104
104
|
readonly #expiring = new Set<string>();
|
|
105
105
|
readonly #deadlineAttempts = new Set<string>();
|
|
106
|
+
/**
|
|
107
|
+
* The next deadline came due while `#expire` was still inside an await
|
|
108
|
+
* (tool-boundary grace or the bounded flush). The in-flight pass owns the
|
|
109
|
+
* single-flight slot, so the timer callback only records the follow-up and
|
|
110
|
+
* `#onDeadline` runs it after this pass returns.
|
|
111
|
+
*/
|
|
112
|
+
readonly #deadlineFollowUps = new Set<string>();
|
|
106
113
|
readonly #pendingTerminalTransitions = new Set<string>();
|
|
107
114
|
readonly #deadlineDeferredTerminalTransitions = new Set<string>();
|
|
108
115
|
readonly #deadlineTerminalizationConfirmed = new Set<string>();
|
|
109
116
|
readonly #terminalPublicationPending = new Map<string, SdkPromptTerminalOutcome>();
|
|
117
|
+
readonly #toolsStillPendingOnLastCheck = new Set<string>();
|
|
110
118
|
readonly #deadlineStartCleanup = new Map<string, () => void>();
|
|
111
119
|
readonly #pendingTerminalFailureReasons = new Map<
|
|
112
120
|
string,
|
|
@@ -187,7 +195,11 @@ export class PromptDeadlineManager {
|
|
|
187
195
|
}
|
|
188
196
|
|
|
189
197
|
/** Run the durability hook under the shared bound; see `runBoundedDeadlineFlush`. */
|
|
190
|
-
async #runDeadlineFlush(
|
|
198
|
+
async #runDeadlineFlush(
|
|
199
|
+
correlation: InvocationCorrelation,
|
|
200
|
+
lease: PromptDeadlineLease,
|
|
201
|
+
generation: number,
|
|
202
|
+
): Promise<void> {
|
|
191
203
|
const hook = this.#onDeadlineExceeded;
|
|
192
204
|
if (hook === undefined) return;
|
|
193
205
|
const key = leaseKey(correlation);
|
|
@@ -195,7 +207,9 @@ export class PromptDeadlineManager {
|
|
|
195
207
|
signal =>
|
|
196
208
|
hook(correlation, signal, () => {
|
|
197
209
|
const current = this.#leases.get(key);
|
|
198
|
-
return
|
|
210
|
+
return (
|
|
211
|
+
current === lease && current.generation === generation && this.#now() >= promptDeadlineAt(current)
|
|
212
|
+
);
|
|
199
213
|
}),
|
|
200
214
|
this.#deadlineFlushTimeoutMs,
|
|
201
215
|
);
|
|
@@ -239,12 +253,24 @@ export class PromptDeadlineManager {
|
|
|
239
253
|
}
|
|
240
254
|
|
|
241
255
|
async #onDeadline(key: string): Promise<void> {
|
|
242
|
-
if (this.#deadlineAttempts.has(key))
|
|
256
|
+
if (this.#deadlineAttempts.has(key)) {
|
|
257
|
+
this.#deadlineFollowUps.add(key);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
243
260
|
this.#deadlineAttempts.add(key);
|
|
244
261
|
try {
|
|
245
|
-
|
|
262
|
+
do {
|
|
263
|
+
this.#deadlineFollowUps.delete(key);
|
|
264
|
+
await this.#expire(key);
|
|
265
|
+
} while (this.#deadlineFollowUps.has(key));
|
|
246
266
|
} finally {
|
|
247
267
|
this.#deadlineAttempts.delete(key);
|
|
268
|
+
if (this.#deadlineFollowUps.has(key)) {
|
|
269
|
+
this.#deadlineFollowUps.delete(key);
|
|
270
|
+
queueMicrotask(() => {
|
|
271
|
+
void this.#onDeadline(key);
|
|
272
|
+
});
|
|
273
|
+
}
|
|
248
274
|
}
|
|
249
275
|
}
|
|
250
276
|
|
|
@@ -385,7 +411,9 @@ export class PromptDeadlineManager {
|
|
|
385
411
|
terminalization =
|
|
386
412
|
(await this.#onDeadlineTerminalization?.(correlation, () => {
|
|
387
413
|
const current = this.#leases.get(key);
|
|
388
|
-
return
|
|
414
|
+
return (
|
|
415
|
+
current === lease && current.generation === generation && this.#now() >= promptDeadlineAt(current)
|
|
416
|
+
);
|
|
389
417
|
})) ?? "settled";
|
|
390
418
|
} catch {
|
|
391
419
|
terminalization = "uncertain";
|
|
@@ -410,7 +438,7 @@ export class PromptDeadlineManager {
|
|
|
410
438
|
// The claim above remains the durable pending marker throughout both
|
|
411
439
|
// bounded operations, so restart recovery never reports unsaved work as
|
|
412
440
|
// finished.
|
|
413
|
-
await this.#runDeadlineFlush(correlation, lease);
|
|
441
|
+
await this.#runDeadlineFlush(correlation, lease, generation);
|
|
414
442
|
// Fence again AFTER the flush (#5623 review round 2): progress can land
|
|
415
443
|
// while the bounded git operation runs and renews the lease.
|
|
416
444
|
if (this.#backOffIfSuperseded(key, lease, generation)) return;
|
|
@@ -532,14 +560,19 @@ export class PromptDeadlineManager {
|
|
|
532
560
|
/**
|
|
533
561
|
* After an awaited reconciliation call, verify the captured lease is still
|
|
534
562
|
* authoritative. Fresh attributable progress during the await advances the
|
|
535
|
-
* lease generation and its deadline
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
563
|
+
* lease generation and its deadline. A tool-boundary wait or a flush can
|
|
564
|
+
* outlive that renewed lease, so a generation mismatch is stale even when
|
|
565
|
+
* the new deadline is already due — the time check alone would let this
|
|
566
|
+
* pass publish with the generation it captured, the publisher would refuse,
|
|
567
|
+
* and uncertainty recovery would refuse to re-anchor the same mismatch.
|
|
568
|
+
* Cancel this expiry instance (release the expiration fence, clear any
|
|
569
|
+
* retry budget, and reschedule the deadline) and report it so the caller
|
|
570
|
+
* stops. The follow-up expiry captures the current generation. A cleared
|
|
571
|
+
* or re-accepted lease is stale by identity too.
|
|
539
572
|
*/
|
|
540
|
-
#backOffIfSuperseded(key: string, lease: PromptDeadlineLease,
|
|
573
|
+
#backOffIfSuperseded(key: string, lease: PromptDeadlineLease, generation: number): boolean {
|
|
541
574
|
const current = this.#leases.get(key);
|
|
542
|
-
if (current !== lease || this.#now() < promptDeadlineAt(current)) {
|
|
575
|
+
if (current !== lease || current.generation !== generation || this.#now() < promptDeadlineAt(current)) {
|
|
543
576
|
this.#expiring.delete(key);
|
|
544
577
|
this.#expiryRetries.delete(key);
|
|
545
578
|
if (current) this.#schedule(key);
|
|
@@ -578,13 +611,32 @@ export class PromptDeadlineManager {
|
|
|
578
611
|
this.clear(correlation);
|
|
579
612
|
}
|
|
580
613
|
|
|
581
|
-
#scheduleTerminalPublicationRetry(key: string): void {
|
|
614
|
+
#scheduleTerminalPublicationRetry(key: string, delayMs?: number): void {
|
|
582
615
|
this.#clearTimer(key);
|
|
583
|
-
|
|
616
|
+
// Use immediate retry (0ms) if tools were pending on last check;
|
|
617
|
+
// otherwise use normal retry delay. This allows quick detection when tools drain.
|
|
618
|
+
const effectiveDelayMs =
|
|
619
|
+
delayMs ?? (this.#toolsStillPendingOnLastCheck.has(key) ? 0 : UNCERTAINTY_RETRY_DELAY_MS);
|
|
620
|
+
const timer = setTimeout(() => void this.#onDeadline(key), effectiveDelayMs);
|
|
584
621
|
(timer as unknown as { unref?: () => void }).unref?.();
|
|
585
622
|
this.#timers.set(key, timer);
|
|
586
623
|
}
|
|
587
624
|
|
|
625
|
+
/** Notify about termination check results to adjust retry strategy. */
|
|
626
|
+
notifyTerminationResult(
|
|
627
|
+
correlation: InvocationCorrelation,
|
|
628
|
+
_result: PromptDeadlineTerminalization,
|
|
629
|
+
reason: string,
|
|
630
|
+
): void {
|
|
631
|
+
const key = leaseKey(correlation);
|
|
632
|
+
if (reason.includes("tools-still-pending")) {
|
|
633
|
+
this.#toolsStillPendingOnLastCheck.add(key);
|
|
634
|
+
} else {
|
|
635
|
+
// Tools have settled or are no longer relevant
|
|
636
|
+
this.#toolsStillPendingOnLastCheck.delete(key);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
588
640
|
#retry(key: string): void {
|
|
589
641
|
const attempts = (this.#expiryRetries.get(key) ?? 0) + 1;
|
|
590
642
|
this.#expiryRetries.set(key, attempts);
|
|
@@ -817,6 +869,7 @@ export class PromptDeadlineManager {
|
|
|
817
869
|
this.#terminalPublicationPending.delete(key);
|
|
818
870
|
this.#pendingTerminalFailureReasons.delete(key);
|
|
819
871
|
this.#pendingTerminalEvidence.delete(key);
|
|
872
|
+
this.#toolsStillPendingOnLastCheck.delete(key);
|
|
820
873
|
}
|
|
821
874
|
|
|
822
875
|
clearAll(): void {
|
|
@@ -839,6 +892,7 @@ export class PromptDeadlineManager {
|
|
|
839
892
|
this.#terminalPublicationPending.clear();
|
|
840
893
|
this.#pendingTerminalFailureReasons.clear();
|
|
841
894
|
this.#pendingTerminalEvidence.clear();
|
|
895
|
+
this.#toolsStillPendingOnLastCheck.clear();
|
|
842
896
|
}
|
|
843
897
|
|
|
844
898
|
/** For tests: current deadline or undefined if no lease. */
|
package/src/sdk/prompt-status.ts
CHANGED
|
@@ -40,12 +40,14 @@ export interface TurnPromptImageInput {
|
|
|
40
40
|
mimeType?: string;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
/** Public input contract for ordered `turn.prompt
|
|
44
|
-
export
|
|
43
|
+
/** Public input contract for ordered `turn.prompt`; direct and staged images cannot be mixed. */
|
|
44
|
+
export type TurnPromptInput = {
|
|
45
45
|
text: string;
|
|
46
|
-
images?: TurnPromptImageInput[];
|
|
47
46
|
clientRef?: string;
|
|
48
|
-
}
|
|
47
|
+
} & (
|
|
48
|
+
| { images?: TurnPromptImageInput[]; stagedImages?: never }
|
|
49
|
+
| { images?: never; stagedImages: Array<{ id: string }> }
|
|
50
|
+
);
|
|
49
51
|
|
|
50
52
|
/**
|
|
51
53
|
* Terminal outcome is preserved exactly; active records never age into terminal. An
|