@gajae-code/coding-agent 0.16.0 → 0.16.1
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 +41 -1
- package/dist/types/async/job-manager.d.ts +32 -1
- package/dist/types/browser-backend.d.ts +12 -0
- package/dist/types/cli/update-cli.d.ts +1 -0
- package/dist/types/commands/sdk.d.ts +2 -0
- package/dist/types/config/billing-path.d.ts +25 -0
- package/dist/types/config/config-schema-version.d.ts +13 -1
- package/dist/types/config/model-registry.d.ts +16 -0
- package/dist/types/config/settings-schema.d.ts +17 -7
- package/dist/types/extensibility/extensions/types.d.ts +8 -3
- package/dist/types/gjc-runtime/launch-worktree.d.ts +25 -1
- package/dist/types/gjc-runtime/session-state-lock.d.ts +22 -0
- package/dist/types/main.d.ts +1 -0
- package/dist/types/modes/acp/acp-agent.d.ts +21 -21
- package/dist/types/modes/components/model-selector.d.ts +4 -0
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/components/sessions-dashboard.d.ts +2 -1
- package/dist/types/modes/interactive-mode.d.ts +16 -2
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +2 -1
- package/dist/types/sdk/broker/ensure.d.ts +3 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +6 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +14 -0
- package/dist/types/sdk/broker/startup-budget.d.ts +52 -0
- package/dist/types/sdk/broker/state-version.d.ts +17 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/index.d.ts +3 -1
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +1 -1
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +1 -1
- package/dist/types/sdk/bus/slack-conversation.d.ts +1 -1
- package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/cli/rows.d.ts +8 -2
- package/dist/types/sdk/cli/session-cli.d.ts +2 -1
- package/dist/types/sdk/host/events.d.ts +1 -0
- package/dist/types/sdk/host/query/cursor.d.ts +4 -2
- package/dist/types/sdk/host/query/handlers.d.ts +1 -0
- package/dist/types/sdk/host/query/revision-store.d.ts +1 -0
- package/dist/types/sdk/host/session-runtime.d.ts +18 -17
- package/dist/types/sdk/lifecycle-session.d.ts +1 -1
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -5
- package/dist/types/sdk/receipt-state.d.ts +2 -0
- package/dist/types/sdk/router/session-router.d.ts +4 -0
- package/dist/types/sdk/turn-result.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +47 -7
- package/dist/types/session/fold-coordinator.d.ts +29 -2
- package/dist/types/session/session-manager.d.ts +14 -2
- package/dist/types/tools/ask.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +12 -0
- package/dist/types/tools/browser/launch.d.ts +10 -0
- package/dist/types/tools/browser/registry.d.ts +8 -0
- package/dist/types/tools/index.d.ts +6 -10
- package/dist/types/tools/job.d.ts +3 -1
- package/dist/types/utils/external-editor.d.ts +7 -0
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/pirate.ts +7 -4
- package/package.json +7 -7
- package/scripts/generate-sdk-operation-inventory.ts +7 -1
- package/src/async/job-manager.ts +107 -9
- package/src/browser-backend.ts +29 -0
- package/src/cli/plugin-cli.ts +29 -0
- package/src/cli/update-cli.ts +63 -12
- package/src/commands/sdk.ts +22 -7
- package/src/config/billing-path.ts +42 -0
- package/src/config/config-schema-version.ts +18 -1
- package/src/config/model-preset-registry.ts +177 -18
- package/src/config/model-registry.ts +268 -42
- package/src/config/settings-schema.ts +19 -7
- package/src/config/settings.ts +46 -15
- package/src/coordinator-mcp/projection-scan.ts +6 -6
- package/src/coordinator-mcp/server.ts +21 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/extensibility/extensions/runner.ts +27 -0
- package/src/extensibility/extensions/types.ts +8 -3
- package/src/extensibility/gjc-plugins/installer.ts +51 -11
- package/src/extensibility/runtime-skill-discovery.ts +110 -3
- package/src/extensibility/skills.ts +22 -12
- package/src/gjc-runtime/launch-worktree.ts +285 -4
- package/src/gjc-runtime/session-state-lock.ts +154 -28
- package/src/gjc-runtime/session-state-sidecar.ts +10 -17
- package/src/gjc-runtime/tmux-owner-isolation.ts +16 -1
- package/src/internal-urls/docs-index.generated.ts +10 -10
- package/src/main.ts +4 -1
- package/src/modes/acp/acp-agent.ts +5 -5
- package/src/modes/components/model-selector.ts +76 -8
- package/src/modes/components/session-selector.ts +23 -15
- package/src/modes/components/sessions-dashboard.ts +8 -5
- package/src/modes/controllers/command-controller.ts +1 -1
- package/src/modes/controllers/event-controller.ts +30 -4
- package/src/modes/controllers/extension-ui-controller.ts +13 -13
- package/src/modes/controllers/input-controller.ts +2 -2
- package/src/modes/controllers/selector-controller.ts +10 -3
- package/src/modes/interactive-mode.ts +36 -12
- package/src/modes/prompt-action-autocomplete.ts +30 -4
- package/src/modes/runtime-init.ts +12 -9
- package/src/modes/theme/theme.ts +5 -0
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/ui-helpers.ts +22 -3
- package/src/prompts/agent-fragments/browser-aside.md +22 -0
- package/src/prompts/tools/ask.md +1 -1
- package/src/prompts/tools/bash.md +1 -0
- package/src/prompts/tools/job.md +1 -1
- package/src/sdk/acp/adapter.ts +5 -0
- package/src/sdk/broker/broker.ts +10 -1
- package/src/sdk/broker/ensure.ts +76 -3
- package/src/sdk/broker/lifecycle-ledger.ts +6 -0
- package/src/sdk/broker/lifecycle.ts +254 -34
- package/src/sdk/broker/spawn-substrate.ts +45 -2
- package/src/sdk/broker/startup-budget.ts +144 -2
- package/src/sdk/broker/state-version.ts +17 -0
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +111 -24
- package/src/sdk/bus/discord-daemon.ts +50 -10
- package/src/sdk/bus/index.ts +33 -3
- package/src/sdk/bus/kind-aware-reconciliation.ts +296 -48
- package/src/sdk/bus/lifecycle-commands.ts +4 -0
- package/src/sdk/bus/notification-service.ts +22 -5
- package/src/sdk/bus/prompt-reconciliation.ts +7 -2
- package/src/sdk/bus/reconciliation-store.ts +55 -31
- package/src/sdk/bus/slack-conversation.ts +1 -1
- package/src/sdk/bus/slack-daemon.ts +72 -38
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/cli/rows.ts +30 -7
- package/src/sdk/cli/session-cli.ts +33 -21
- package/src/sdk/host/control/dispatch.ts +2 -2
- package/src/sdk/host/events.ts +1 -0
- package/src/sdk/host/host.ts +2 -0
- package/src/sdk/host/query/cursor.ts +52 -7
- package/src/sdk/host/query/handlers.ts +33 -12
- package/src/sdk/host/query/revision-store.ts +12 -0
- package/src/sdk/host/session-runtime.test.ts +463 -8
- package/src/sdk/host/session-runtime.ts +383 -54
- package/src/sdk/host/surface-policy.ts +3 -3
- package/src/sdk/lifecycle-session.ts +7 -2
- package/src/sdk/prompt-deadline-manager.ts +2 -1
- package/src/sdk/protocol/operation-inventory.generated.json +54 -3
- package/src/sdk/protocol/operation-registry.ts +1 -1
- package/src/sdk/receipt-state.ts +10 -0
- package/src/sdk/router/session-router.ts +152 -59
- package/src/sdk/session.ts +60 -41
- package/src/sdk/turn-result.ts +22 -0
- package/src/session/agent-session.ts +1033 -260
- package/src/session/fold-coordinator.ts +40 -3
- package/src/session/session-manager.ts +517 -77
- package/src/slash-commands/builtin-registry.ts +41 -0
- package/src/task/executor.ts +9 -4
- package/src/tools/ask-contract.test.ts +64 -0
- package/src/tools/ask-contract.ts +36 -1
- package/src/tools/ask.ts +10 -8
- package/src/tools/bash-interactive.ts +11 -2
- package/src/tools/bash.ts +156 -33
- package/src/tools/browser/launch.ts +37 -0
- package/src/tools/browser/registry.ts +99 -9
- package/src/tools/cron.ts +6 -4
- package/src/tools/descriptors.test.ts +15 -0
- package/src/tools/descriptors.ts +5 -1
- package/src/tools/index.ts +6 -6
- package/src/tools/job.ts +4 -1
- package/src/tools/monitor.ts +12 -9
- package/src/tools/resolve.ts +30 -10
- package/src/tools/tool-catalog.generated.ts +2 -2
- package/src/utils/external-editor.ts +72 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.16.1] - 2026-09-03
|
|
6
|
+
|
|
7
|
+
- Broker-launched SDK sessions now activate an already-cached default model profile before refreshing provider catalogs in the background, preventing redundant online discovery from consuming the fixed semantic-readiness window while preserving strict refresh fallback when cached profile resolution fails.
|
|
8
|
+
- Native Windows external editors now launch executable commands directly instead of through `cmd.exe`, preventing the shell handoff from swallowing the first editor keystroke; `.cmd` and `.bat` editor commands retain shell execution.
|
|
9
|
+
- Slack Socket Mode now accepts real `event_callback` payloads, routes ordinary active-thread text as new user turns when no ask is pending, keeps idle notifications non-replyable, deduplicates distinct messages without treating shared `event_context` metadata as event identity, and scopes deterministic root message IDs to the configured workspace and channel.
|
|
10
|
+
- Ask now rejects standalone custom-input pseudo-option labels such as `Other (type your own)`, `custom input`, and `직접 입력` while preserving genuine labels that merely contain those words; single-option asks no longer publish a recommended marker, including through workflow-gate/SDK question projection.
|
|
11
|
+
- Session-state lock acquisition now retries immediately after positively proving and identity-reclaiming a dead transition owner, so forced exits no longer add a retry delay to the next resume while unproven or live claims retain the bounded backoff path.
|
|
12
|
+
- Coordinator persist failures now include typed lock-cause fields and use a per-document, per-failure-class 30-second warn window; proven-refused local model discovery is debug-level, and `session_closed` delivery failures route by attached-client count.
|
|
13
|
+
- `gjc update` now identifies the active Linux libc instead of treating an optional installed musl loader as proof that a glibc-based Ubuntu host runs musl.
|
|
14
|
+
- The interactive TUI now warns when a turn ends with `stopReason: "length"` before producing any visible text or tool call — a reasoning model whose thinking alone consumed the budget — instead of returning to the prompt with no explanation, and the completion notification for that turn no longer reports success. Other surfaces (SDK, ACP, print mode, telemetry) already reported this state; no length-specific automatic continuation is added and existing continuation policies are unchanged.
|
|
15
|
+
- Sessions can now be marked with `/star` and `/unstar`; starred sessions persist in append-only metadata, display a `★` in resume and read-only dashboard views, and sort ahead of unstarred sessions without changing deletion or retention behavior.
|
|
16
|
+
- Steering is now admitted only into a live agent run. A steer submitted when no run is live — after a turn ended, during the post-prompt unwind window where the session still reports streaming, while another prompt is in preflight, or while an abort is unwinding — is no longer parked in the Agent steering queue where it was invisible to the queue display and consumed by whichever unrelated later prompt polled it first (appearing turn after turn, or being drained silently by the first Esc). The session now routes such a steer as a sequential follow-up owned by the next turn and auto-continues into it, so `session.steer()`, `prompt(..., { streamingBehavior: "steer" })`, `sendUserMessage(..., { deliverAs: "steer" })`, `sendCustomMessage(..., { deliverAs: "steer" })`, and SDK `turn.steer` all behave identically. A steer-behavior prompt submitted while another prompt is still acquiring session admission is queued against that prompt's turn instead of being rejected with `busy` and lost.
|
|
17
|
+
- The `interruptMode` setting is renamed to `toolInterruptPolicy` with values `abort_tools` (was `immediate`, default) and `finish_tools` (was `wait`); existing config files are migrated once (config schema version 2). The setting only decides whether a steer aborts the tools still running in the current batch and never changes when a steer is consumed — the previous label implied queue semantics it never had. The ACP config option, its SDK control operation (`queue.interrupt_mode.set` → `queue.tool_interrupt_policy.set`, `setQueueMode("tool_interrupt", ...)`), and `AgentSession.setToolInterruptPolicy()` follow the rename. `ToolSession.steer` is removed: the `cron`, `monitor`, and `resolve` tools deliver through `sendCustomMessage` (`deliverAs: "steer"` for the resolve reminder), so no tool pushes onto the Agent queue directly. Composer-submitted steers request sequential delivery (`steerQueuePolicy: "sequential"`) so they still arrive one at a time under `steeringMode: "all"`.
|
|
18
|
+
- Steering a run leaves unconsumed when it ends is now settled in one place. The session consumes the run's `agent_end.disownedSteering` once: a user interrupt (Esc) and a natural end re-route it as sequential follow-ups of the next turn (queue and pending display together), a terminal abort drops everything except client steers admitted after the abort's admission snapshot (which are re-routed the same way and rearmed as a fresh turn), and every other abort cause (teardown, session switch, compaction, handoff, tool abort) drops it and settles its SDK submission with a removal disposition. This replaces the three cause-specific recovery patches (user-interrupt rearm, terminal-abort steering purge, and steering rearm) that each reasoned about the Agent queue separately. `cancelAndSubmit` now keeps the aborted turn's steers as steers of the new turn — restored into the new run once it is accepted — instead of re-labelling them as follow-ups that drained turn after turn; with a selected queue entry the unselected messages still become follow-ups and their pending display now mirrors that.
|
|
19
|
+
- Rerouted steering preserves its queue policy: `toolInterruptPolicy: "finish_tools"` with `steeringMode: "all"` keeps one ordered successor-turn cohort across run disown and abort unwind, while composer submissions explicitly marked sequential still deliver one per turn.
|
|
20
|
+
- A user steer admitted into a live run now folds a running foreground `bash` call (managed non-PTY, ACP client-terminal, and PTY) into a background job once the command has run for a fixed 2 s grace window (`STEER_FOLD_GRACE_MS`), mirroring how a steer ends a subagent await: the call returns the chord-fold background-start result plus `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 same run consumes the steer at the tool boundary, and the job's completion wakes a later turn. Steers inside the grace window let the command finish; `busyPromptMode=queue` or `toolInterruptPolicy=finish_tools` never fold; Esc still aborts. Every fold (steer, chord, auto-background timer, `bash.background`) publishes one replayable `bash_folded` SDK event and exposes `foldReason` in job snapshots.
|
|
21
|
+
- The TUI activity indicator itemizes running background work by kind (`Working… · 2 subagents, 1 background bash, 1 monitor` / `Background: 2 subagents, 1 background bash, 1 monitor…`) instead of a single `N background task(s)` count.
|
|
22
|
+
- Explicit static `vllm` and `sglang` providers no longer acquire the generic custom-provider `/v1/models` auto-discovery lane; their configured catalog remains authoritative unless `discovery` is explicitly enabled.
|
|
23
|
+
- Coordinator projection scans now use identity-bracketed directory authority on macOS instead of failing every scan as unsupported, while root and candidate replacement races remain fail-closed.
|
|
24
|
+
- The `/model` selector no longer stalls the UI thread on open, model selection, provider-tab switch, and every catalog change for credentialed users. Each `refresh("offline")` re-ran the built-in-discovery freshness filter across the whole cached catalog (thousands of models) while recomputing per model values that only vary per provider — `#getProviderEvidenceGeneration` (an AuthStorage lookup) and `#getProviderBaseUrlForDiscovery` + endpoint normalization (URL parsing). That provider-keyed work is now memoized once per provider per refresh, so on the bundled catalog with credentials `refresh("offline")` drops from ~40ms to ~15ms per interaction with identical freshness results. Complements the earlier batch canonical-selection fix.
|
|
25
|
+
- Skill slash commands now autocomplete from subsequent whitespace-delimited tokens, including later prompt lines and case-insensitive `/Skill:` prefixes, while runtime invocation matching uses the same case-insensitive canonical recognition and case-variant skill discovery preserves project-over-user precedence.
|
|
26
|
+
- `/model` preset authentication refreshes now resolve each repeated role selector once per refresh instead of once per profile assignment, avoiding synchronous UI stalls as the preset catalog grows.
|
|
27
|
+
- Interactive startup no longer re-verifies the signed model preset registry once per subsystem. A launch read the accepted registry four times, and each read verified every cached generation in both the primary and backup state copies from several recovery angles, re-running Ed25519 verification, Zod schema parsing, canonical-JSON re-serialization, and the confusable-identity walk over the same documents. On a 2.5MB accepted state (4278 presets, 58 profiles) that cost about 3.0s of the pre-paint startup path. Verification results are now memoized per generation, the already-schema-parsed documents are no longer re-parsed to derive an identical value, and an accepted-registry read is reused for as long as the state, backup, and control files hash unchanged, so any write or tampering by any process is still verified from scratch. Measured startup drops from ~5.5s to ~1.9s.
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Added `browser.backend` (`native` | `aside`, default `native`) to select the browser surface offered to the model. Operators who drive a real logged-in browser through the Aside CLI had no way to keep the model off the built-in Puppeteer `browser` tool short of `browser.enabled: false`, which also dropped every hint about the replacement surface, so the model would still reach for headless Chromium or invent a browser MCP. With `aside`, the built-in `browser` tool is neither active nor discoverable (`descriptors.ts` availability gate) and the system prompt gains a `<browser-backend>` block (`prompts/agent-fragments/browser-aside.md`, threaded from the session settings through `buildSystemPrompt`) that requires browser work to run through Bash as direct `aside repl` / `aside exec` invocations with the attach-verify-snapshot discipline. Nothing is spawned, supervised, or registered by GJC: no MCP server, no in-process Aside driver, no fallback to native when the CLI is missing. `native` is byte-for-byte the previous behavior, and `browser.enabled` keeps its meaning for the native backend.
|
|
31
|
+
- Interactive OAuth account selection now handles a stale or missing pinned credential in place, preserving the session and actionable `/login` or AUTO guidance instead of creating an unhandled rejection and crash record.
|
|
32
|
+
- Custom OpenAI-compatible providers in `models.yml` now auto-populate `/model` from their live `/v1/models` catalog without a manual `discovery:` block, and auto-classify each discovered model's wire API family. Any custom provider with a `baseUrl` and an OpenAI-family `api` (either provider-level, or the dominant OpenAI-family `api` among its statically-configured models) gets an implicit optional `openai-models-list` discovery lane, so a subscription-style gateway (e.g. CLIProxyAPI) shows its full model list with zero extra config and degrades to the configured static models when the endpoint has no `/v1/models`. During discovery each model's API type is inferred from the OpenAI `owned_by` owner (`anthropic` → `anthropic-messages`, `openai` → OpenAI) and then the model id (`claude-*` → `anthropic-messages`, `gpt-*`/`o1`/`codex`/… → OpenAI); OpenAI-family models keep the provider's configured OpenAI transport (`openai-responses` vs `openai-completions`) rather than being forced to chat-completions, an explicit `discovery.apiByModelPrefix` still wins, and an inconclusive model falls back to the provider default api.
|
|
33
|
+
- Named-worktree SDK session.create now gives git worktree add/reuse and workspace install independent 30s budgets instead of charging them against the child 10s semantic-readiness clock. Prep timeouts stay typed and terminal (`worktree_preparation_timeout` / `dependency_preparation_timeout`); Coordinator and ACP preserve those codes instead of collapsing them to `unavailable` or `broker_compensation_unobserved`. Ordinary no-worktree sessions stay 10s/21s.
|
|
34
|
+
- SDK session-index scan/replay now explicitly documents and regression-tests the
|
|
35
|
+
v4 compatibility boundary: supported v4 session-index events and snapshots are
|
|
36
|
+
accepted at every entry surface (scan, replay, tail, append, repair), future
|
|
37
|
+
versions stay fail-closed with data-preserving quarantine, and the generic
|
|
38
|
+
SDK-state guard (`maximum supported version is 1`) is documented as never
|
|
39
|
+
applying to session-index rows so the #5181 crash class cannot recur.
|
|
40
|
+
|
|
41
|
+
- GJC plugin TAR/TGZ installs now bound archive input and aggregate gzip expansion before extraction, preventing compressed bundles from exhausting memory while preserving valid concatenated gzip members.
|
|
42
|
+
|
|
5
43
|
## [0.16.0] - 2026-09-02
|
|
6
44
|
|
|
7
45
|
- Added master mode (`gjc --master [--scope repo|pwd|global]`) with authenticated, broker-authoritative child orchestration: `gjc sdk spawn` creates task-seeded children, scoped `gjc sdk search` discovers broker-visible sessions with paginated results, and locator v2 session rows carry canonical cwd, worktree-root, and state-root identity.
|
|
@@ -18,7 +56,6 @@
|
|
|
18
56
|
|
|
19
57
|
- A runtime-state marker recorded against a different workspace path now reports that mismatch instead of claiming the file is unreadable, and a terminal, not-live marker that travelled into the current workspace with its session directory is adopted rather than refused. Live, non-terminal, and out-of-workspace markers are still refused untouched.
|
|
20
58
|
- An unavailable provider-qualified `modelRoles.default` selection now reports the requested model instead of silently starting on another provider's baseline. This keeps signed-registry omissions and failed catalog admission actionable rather than routing requests to an unrelated retired model. (#5144)
|
|
21
|
-
|
|
22
59
|
- Headless SDK substrate close now reports success when exact teardown observes the recorded process gone even if cleanup unlinks the durable proof first; live or identity-ambiguous substrates still report `substrate_mismatch`. (#5130)
|
|
23
60
|
|
|
24
61
|
- Windows session-state locks now drain late terminal reconciliation writes before disposal returns and safely reclaim valid dead transition claims during resume. (#5102)
|
|
@@ -32,6 +69,8 @@
|
|
|
32
69
|
|
|
33
70
|
### Fixed
|
|
34
71
|
|
|
72
|
+
- The shipped pirate extension example now appends its instructions through the supported `systemPrompt` result, and unsupported `before_agent_start` result fields emit a bounded diagnostic instead of being silently ignored.
|
|
73
|
+
|
|
35
74
|
- File locks now use a descriptor-relative exclusive directory-publication fallback
|
|
36
75
|
when a filesystem returns `EINVAL` for `renameat2(RENAME_NOREPLACE)` (for example
|
|
37
76
|
WSL2 DrvFs), so `edit` and terminal persistence no longer surface `Failed to publish
|
|
@@ -53,6 +92,7 @@
|
|
|
53
92
|
- Concurrent coordinator mutations sharing one idempotency key now join the same in-process flight before taking the durable key lock, so a slow accepted prompt cannot make its retry time out as unavailable. Conflicting in-flight requests still fail closed, completed responses remain durably replayable, and different keys remain isolated. (#5110)
|
|
54
93
|
- Custom providers declaring `transport: pi-native` in `models.yml` now actually dispatch through the auth-gateway native endpoint. The provider-level transport was silently dropped for models.yml-declared models, so requests went to `<baseUrl>/chat/completions` and the gateway answered 404; and the pi-native client now serializes only wire-safe tool fields, so runtime tool state carrying fs-stat BigInts no longer aborts request serialization with `JSON.stringify cannot serialize BigInt`.
|
|
55
94
|
- ACP prompts now settle immediately on correlated explicit failure outcomes without waiting for a later `agent_end`; generic error-only `agent_failed` events remain additive diagnostics until an authoritative terminal, while late duplicates and unrelated correlations stay isolated. (#5107)
|
|
95
|
+
- Session disposal no longer waits behind an abort-ignoring tool's prompt admission or cwd read lease before reaching its bounded Agent abort. Disposal now fences new prompt and cwd-move admissions without draining unbounded reader work, while preserving cwd moves admitted before teardown and suppressing late run events. (#5100)
|
|
56
96
|
|
|
57
97
|
- Managed-session file identities now use one canonical unsigned 64-bit representation across stat/native boundaries and replacement cleanup receipts. Native Windows file IDs surfaced as signed negative bigints no longer create double-hyphen receipt names that block persistence or reopen; already-written signed receipt names and interrupted pending receipts are recovered only through the existing identity-bound, fail-closed reconciliation paths. (#5095)
|
|
58
98
|
|
|
@@ -43,9 +43,23 @@ export interface AsyncJob {
|
|
|
43
43
|
* incrementing a completed job's timer.
|
|
44
44
|
*/
|
|
45
45
|
export declare function jobElapsedMs(job: Pick<AsyncJob, "startTime" | "endTime">, now?: number): number;
|
|
46
|
+
/**
|
|
47
|
+
* Why a foreground wait left the foreground. Every fold path names its
|
|
48
|
+
* trigger so job snapshots and SDK clients can tell a user steer from the
|
|
49
|
+
* chord, the auto-background timer, or the explicit `bash.background` control.
|
|
50
|
+
*/
|
|
51
|
+
export type FoldReason = "steer" | "chord" | "timer" | "sdk_control";
|
|
52
|
+
/** A fold observed by the manager; published to SDK clients as `bash_folded`. */
|
|
53
|
+
export interface JobFoldEvent {
|
|
54
|
+
jobId: string;
|
|
55
|
+
generation: string;
|
|
56
|
+
reason: FoldReason;
|
|
57
|
+
}
|
|
46
58
|
export interface AsyncJobMetadata {
|
|
47
59
|
/** Set once a foreground wait has been folded, so surfacing can show folded work. */
|
|
48
60
|
backgrounded?: boolean;
|
|
61
|
+
/** Why a foreground wait was folded; absent for jobs started directly in the background (`async: true`). */
|
|
62
|
+
foldReason?: FoldReason;
|
|
49
63
|
subagent?: {
|
|
50
64
|
id: string;
|
|
51
65
|
agent: string;
|
|
@@ -197,6 +211,8 @@ export interface AsyncJobSnapshotEntry {
|
|
|
197
211
|
status: AsyncJob["status"];
|
|
198
212
|
generation: string;
|
|
199
213
|
backgrounded: boolean;
|
|
214
|
+
/** Present when `backgrounded` was set by a fold; absent for direct background starts. */
|
|
215
|
+
foldReason?: FoldReason;
|
|
200
216
|
deliveryState: JobDeliveryState;
|
|
201
217
|
}
|
|
202
218
|
/** Scalar delivery-failure evidence that may outlive its AsyncJob record. */
|
|
@@ -546,11 +562,25 @@ export declare class AsyncJobManager {
|
|
|
546
562
|
timeoutMs?: number;
|
|
547
563
|
}): Promise<boolean>;
|
|
548
564
|
getLastDisposeDiagnostics(): AsyncJobDisposeDiagnostics;
|
|
565
|
+
/**
|
|
566
|
+
* Subscribe to fold events. Fires once per successful `markBackgrounded`
|
|
567
|
+
* transition (never on the idempotent repeat), so a subscriber can publish
|
|
568
|
+
* exactly one `bash_folded` frame per fold. Listener errors are isolated.
|
|
569
|
+
*/
|
|
570
|
+
onFold(cb: (event: JobFoldEvent) => void): () => void;
|
|
571
|
+
/**
|
|
572
|
+
* Mark a job that was launched directly in the background (`bash` with
|
|
573
|
+
* `async: true`). It never had a foreground wait, so this is not a fold: no
|
|
574
|
+
* `foldReason` is recorded and no fold listener fires.
|
|
575
|
+
*/
|
|
576
|
+
markStartedInBackground(jobId: string, generation: string): boolean;
|
|
549
577
|
/**
|
|
550
578
|
* Mark a running job as backgrounded (folded out of its foreground call).
|
|
551
579
|
* Read by getJobsSnapshot so folded work stays visible; safe to call twice.
|
|
580
|
+
* The first transition records `reason` and notifies fold listeners; a
|
|
581
|
+
* repeat keeps the original reason and emits nothing.
|
|
552
582
|
*/
|
|
553
|
-
markBackgrounded(jobId: string, generation: string): boolean;
|
|
583
|
+
markBackgrounded(jobId: string, generation: string, reason: FoldReason): boolean;
|
|
554
584
|
waitForAll(): Promise<void>;
|
|
555
585
|
drainDeliveries(options?: {
|
|
556
586
|
timeoutMs?: number;
|
|
@@ -559,5 +589,6 @@ export declare class AsyncJobManager {
|
|
|
559
589
|
dispose(options?: {
|
|
560
590
|
timeoutMs?: number;
|
|
561
591
|
}): Promise<boolean>;
|
|
592
|
+
awaitRetainedDisposalCompletion(): Promise<void>;
|
|
562
593
|
isDeliverySuppressed(jobId: string, generation?: string): boolean;
|
|
563
594
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type BrowserBackendId = "native" | "aside";
|
|
2
|
+
export interface BrowserBackend {
|
|
3
|
+
readonly id: BrowserBackendId;
|
|
4
|
+
readonly exposesBuiltinTool: boolean;
|
|
5
|
+
readonly developerInstructions?: string;
|
|
6
|
+
}
|
|
7
|
+
interface BrowserBackendSettingsSource {
|
|
8
|
+
get(key: string): unknown;
|
|
9
|
+
}
|
|
10
|
+
/** Resolve the configured browser backend. Aside is strictly opt-in. */
|
|
11
|
+
export declare function resolveBrowserBackend(settings: BrowserBackendSettingsSource): BrowserBackend;
|
|
12
|
+
export {};
|
|
@@ -150,6 +150,7 @@ export interface BinaryUpdateFlow {
|
|
|
150
150
|
* possibly-truncated binary.
|
|
151
151
|
*/
|
|
152
152
|
export declare function runBinaryUpdateFlow(targetPath: string, url: string, expectedVersion: string, flow: BinaryUpdateFlow): Promise<InstalledVersionVerification>;
|
|
153
|
+
export declare function assertSupportedLinuxLibcForTest(glibcVersionRuntime: string | undefined, muslLoaderPresent: boolean): void;
|
|
153
154
|
/**
|
|
154
155
|
* Run the update command.
|
|
155
156
|
*/
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from "@gajae-code/utils/cli";
|
|
2
2
|
import type { Args as ParsedArgs } from "../cli/args";
|
|
3
|
+
import { applyStartupModelProfiles } from "../main";
|
|
3
4
|
import { type SessionLifecycleLaunchRequest } from "../sdk/broker/lifecycle";
|
|
4
5
|
import { SessionManager } from "../session/session-manager";
|
|
5
6
|
export declare function lifecycleArgs(request: SessionLifecycleLaunchRequest, cwd: string, agentDir: string): Promise<ParsedArgs>;
|
|
@@ -109,6 +110,7 @@ export declare function runSessionHost(timing?: {
|
|
|
109
110
|
sleep?: (ms: number) => Promise<void>;
|
|
110
111
|
cwd?: string;
|
|
111
112
|
processIncarnation?: (pid: number) => string | undefined;
|
|
113
|
+
applyStartupModelProfiles?: typeof applyStartupModelProfiles;
|
|
112
114
|
}): Promise<void>;
|
|
113
115
|
export type SdkInternalArgv = {
|
|
114
116
|
action: "broker-internal";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Billing path for a resolved binding's credential source — audit-reversible.
|
|
3
|
+
* Derived from (model.api, credential-provenance) where the binding actually
|
|
4
|
+
* resolves credentials, not from a provider-name allowlist.
|
|
5
|
+
*/
|
|
6
|
+
import type { Api } from "@gajae-code/ai/core";
|
|
7
|
+
import type { EffectiveProviderAuth } from "./provider-selection-policy";
|
|
8
|
+
/**
|
|
9
|
+
* Label shown in the selector row + active-model line. Only the category is
|
|
10
|
+
* disclosed (never the key material or project id).
|
|
11
|
+
*/
|
|
12
|
+
export type BillingPathKind = "metered-api" | "cloud-project" | "bundled";
|
|
13
|
+
export interface BillingPath {
|
|
14
|
+
kind: BillingPathKind;
|
|
15
|
+
/** Stable per-credential-source key for one-time notice dismissal. */
|
|
16
|
+
dismissKey: string;
|
|
17
|
+
label: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Derive from the concrete binding (api + credential provenance).
|
|
21
|
+
* - oauth/keyless/unknown => bundled (plan/proxied/kNoAuth-like)
|
|
22
|
+
* - key + cloud-project api (google-vertex / bedrock) => cloud-project
|
|
23
|
+
* - key + any other api (including custom OpenAI-compatible) => metered-api
|
|
24
|
+
*/
|
|
25
|
+
export declare function deriveBillingPath(provider: string, api: Api | string | undefined, effectiveAuth: EffectiveProviderAuth): BillingPath | undefined;
|
|
@@ -7,4 +7,16 @@
|
|
|
7
7
|
* this dependency-light module so the resolver can import it without pulling in
|
|
8
8
|
* the TUI/AI-heavy settings schema.
|
|
9
9
|
*/
|
|
10
|
-
export declare const CONFIG_SCHEMA_VERSION =
|
|
10
|
+
export declare const CONFIG_SCHEMA_VERSION = 2;
|
|
11
|
+
/**
|
|
12
|
+
* Normalize a durable `configSchemaVersion` marker into a comparable version.
|
|
13
|
+
*
|
|
14
|
+
* Every version decision (future-schema detection, migration-pending state, and
|
|
15
|
+
* the ordered migration registry) must read the SAME normalized value: a
|
|
16
|
+
* malformed marker read as a future schema by one guard and as unmigrated by
|
|
17
|
+
* the next would skip legacy migrations while still re-running v0 transforms.
|
|
18
|
+
* A finite malformed value floors to the nearest completed version; a
|
|
19
|
+
* non-finite or non-numeric one carries no version information and normalizes
|
|
20
|
+
* to 0 (fully unmigrated). `undefined` stays `undefined` (no marker written).
|
|
21
|
+
*/
|
|
22
|
+
export declare function normalizeConfigSchemaVersion(value: unknown): number | undefined;
|
|
@@ -4,6 +4,7 @@ import { type ThemeColor } from "../modes/theme/theme";
|
|
|
4
4
|
import { type ActiveProviderDescriptor } from "../sdk/providers";
|
|
5
5
|
import type { AuthStorage } from "../session/auth-storage";
|
|
6
6
|
import type { ActiveSearchModelContext, WebSearchMode } from "../web/search/types";
|
|
7
|
+
import { type BillingPath } from "./billing-path";
|
|
7
8
|
import { ConfigError, ConfigFile } from "./config-file";
|
|
8
9
|
import { isAuthenticated, kNoAuth } from "./model-auth";
|
|
9
10
|
import { type ConfiguredModelBindings } from "./model-bindings-applier";
|
|
@@ -15,9 +16,16 @@ import { type ModelProfileDefinition } from "./model-profiles";
|
|
|
15
16
|
import { GJC_MODEL_ASSIGNMENT_TARGET_IDS, type ModelProfileConfig } from "./models-config-schema";
|
|
16
17
|
import { type EffectiveProviderAuth } from "./provider-selection-policy";
|
|
17
18
|
import { type Settings } from "./settings";
|
|
19
|
+
export type { BillingPath, BillingPathKind } from "./billing-path";
|
|
18
20
|
export type { EffectiveProviderAuth, ProviderSelectionPolicy } from "./provider-selection-policy";
|
|
19
21
|
export type { CanonicalModelIndex, CanonicalModelRecord, CanonicalModelVariant, ModelEquivalenceConfig };
|
|
20
22
|
export { isAuthenticated, kNoAuth };
|
|
23
|
+
/**
|
|
24
|
+
* A loopback discovery endpoint that is proven to have no listener is the normal state of
|
|
25
|
+
* a machine without a local model server. Structured transport evidence is required when
|
|
26
|
+
* available; DNS, routing, proxy, TLS, and HTTP failures remain warnings.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isQuietLocalDiscoveryFailure(baseUrl: string, _warning: string, evidence?: unknown): boolean;
|
|
21
29
|
export type ModelRole = "default";
|
|
22
30
|
export interface ModelRoleInfo {
|
|
23
31
|
tag?: string;
|
|
@@ -466,6 +474,14 @@ export declare class ModelRegistry {
|
|
|
466
474
|
* unknown/keyless providers fall back to non-OAuth.
|
|
467
475
|
*/
|
|
468
476
|
getEffectiveProviderAuth(provider: string, sessionId?: string): EffectiveProviderAuth;
|
|
477
|
+
/**
|
|
478
|
+
* Billing path for a resolved binding — derived at the point the binding
|
|
479
|
+
* resolves credentials (model.api + credential provenance). Not a
|
|
480
|
+
* provider-name allowlist: a custom OpenAI-compatible provider bound
|
|
481
|
+
* to a metered gateway is "metered-api" exactly like a first-party
|
|
482
|
+
* key. Only the billing category is ever disclosed.
|
|
483
|
+
*/
|
|
484
|
+
getBillingPath(model: Model<Api>, sessionId?: string): BillingPath | undefined;
|
|
469
485
|
/**
|
|
470
486
|
* Forget a session's remembered canonical variant so the next resolution
|
|
471
487
|
* for that session re-ranks from scratch (explicit reselection
|
|
@@ -1738,14 +1738,14 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
1738
1738
|
readonly description: "How to drain follow-up messages after a turn completes";
|
|
1739
1739
|
};
|
|
1740
1740
|
};
|
|
1741
|
-
readonly
|
|
1741
|
+
readonly toolInterruptPolicy: {
|
|
1742
1742
|
readonly type: "enum";
|
|
1743
|
-
readonly values: readonly ["
|
|
1744
|
-
readonly default: "
|
|
1743
|
+
readonly values: readonly ["abort_tools", "finish_tools"];
|
|
1744
|
+
readonly default: "abort_tools";
|
|
1745
1745
|
readonly ui: {
|
|
1746
1746
|
readonly tab: "interaction";
|
|
1747
|
-
readonly label: "Interrupt
|
|
1748
|
-
readonly description: "
|
|
1747
|
+
readonly label: "Tool Interrupt Policy";
|
|
1748
|
+
readonly description: "Whether a steering message aborts the tools still running in the current batch (abort_tools) or lets them finish first (finish_tools). Never changes when a steer is consumed: it is always picked up at the next tool/turn boundary either way.";
|
|
1749
1749
|
};
|
|
1750
1750
|
};
|
|
1751
1751
|
readonly busyPromptMode: {
|
|
@@ -3442,6 +3442,16 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
3442
3442
|
readonly description: "Enable the browser tool (Ulixee Hero)";
|
|
3443
3443
|
};
|
|
3444
3444
|
};
|
|
3445
|
+
readonly "browser.backend": {
|
|
3446
|
+
readonly type: "enum";
|
|
3447
|
+
readonly values: readonly ["native", "aside"];
|
|
3448
|
+
readonly default: "native";
|
|
3449
|
+
readonly ui: {
|
|
3450
|
+
readonly tab: "tools";
|
|
3451
|
+
readonly label: "Browser Backend";
|
|
3452
|
+
readonly description: "Browser surface offered to the model. 'native' exposes the built-in Puppeteer browser tool. 'aside' hides it and requires every browser task to run through the Aside CLI in your live logged-in browser (requires the Aside CLI).";
|
|
3453
|
+
};
|
|
3454
|
+
};
|
|
3445
3455
|
readonly "browser.headless": {
|
|
3446
3456
|
readonly type: "boolean";
|
|
3447
3457
|
readonly default: true;
|
|
@@ -3467,7 +3477,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
3467
3477
|
readonly ui: {
|
|
3468
3478
|
readonly tab: "tools";
|
|
3469
3479
|
readonly label: "Profile reuse posture";
|
|
3470
|
-
readonly description: "'auto' (default): when a usable real Chrome profile is available, the browser tool uses an isolated copy of it (cookies/session/cache) for stronger stealth, warns, and falls back to synthetic. 'opt-in': stay synthetic unless a real profile is explicitly requested.";
|
|
3480
|
+
readonly description: "'auto' (default): when a usable real Chrome profile is available, the browser tool uses an isolated copy of it (cookies/session/cache) for stronger stealth, warns, and falls back to synthetic. 'opt-in': stay synthetic unless a real profile is explicitly requested. On macOS, cookie decryption is brand-specific (Chrome Safe Storage vs Chromium Safe Storage Keychain); a Chrome profile copied into bundled Chromium decrypts to garbage, so auto reuses the profile only when the headless executable can decrypt it — detected system Chrome/Chromium or PUPPETEER_EXECUTABLE_PATH — otherwise it falls back to synthetic with a warning.";
|
|
3471
3481
|
};
|
|
3472
3482
|
};
|
|
3473
3483
|
readonly "browser.geo.timezone": {
|
|
@@ -4547,7 +4557,7 @@ export declare function getPathsForTab(tab: SettingTab): SettingPath[];
|
|
|
4547
4557
|
export declare function getType(path: SettingPath): SettingDef["type"];
|
|
4548
4558
|
/** Get enum values for an enum setting */
|
|
4549
4559
|
export declare function getEnumValues(path: SettingPath): readonly string[] | undefined;
|
|
4550
|
-
export { CONFIG_SCHEMA_VERSION } from "./config-schema-version";
|
|
4560
|
+
export { CONFIG_SCHEMA_VERSION, normalizeConfigSchemaVersion } from "./config-schema-version";
|
|
4551
4561
|
export type SettingsSchemaIssue = {
|
|
4552
4562
|
path: string;
|
|
4553
4563
|
kind: "unknown" | "invalid" | "coerced" | "pending-migration";
|
|
@@ -14,6 +14,7 @@ import type { Api, AssistantMessageEvent, AssistantMessageEventStream, Context,
|
|
|
14
14
|
import type { OAuthCredentials, OAuthLoginCallbacks } from "@gajae-code/ai/utils/oauth/types";
|
|
15
15
|
import type * as piCodingAgent from "@gajae-code/coding-agent";
|
|
16
16
|
import type { AutocompleteItem, Component, EditorTheme, KeyId, TUI } from "@gajae-code/tui";
|
|
17
|
+
import type { JobFoldEvent } from "../../async/job-manager";
|
|
17
18
|
import type { KeybindingsManager } from "../../config/keybindings";
|
|
18
19
|
import type { ModelRegistry } from "../../config/model-registry";
|
|
19
20
|
import type { ModelSelectorValue } from "../../config/model-selector-value";
|
|
@@ -319,7 +320,7 @@ export interface ExtensionContext {
|
|
|
319
320
|
/** Run a control-surface mutation inside the session admission boundary. */
|
|
320
321
|
withSdkControlMutation?<T>(body: () => Promise<T>): Promise<T>;
|
|
321
322
|
cycleThinkingLevel(): ThinkingLevel | undefined;
|
|
322
|
-
setQueueMode(kind: "steering" | "follow_up" | "
|
|
323
|
+
setQueueMode(kind: "steering" | "follow_up" | "tool_interrupt", mode: unknown): boolean;
|
|
323
324
|
getSkillState(): unknown;
|
|
324
325
|
getConfigItems(): unknown;
|
|
325
326
|
getBranchCandidates(): unknown;
|
|
@@ -333,6 +334,8 @@ export interface ExtensionContext {
|
|
|
333
334
|
totalBytes: number;
|
|
334
335
|
} | undefined>;
|
|
335
336
|
getJobs(): unknown;
|
|
337
|
+
/** Subscribe to foreground-wait folds (`bash_folded`). Returns an unsubscribe function. */
|
|
338
|
+
onJobFold?(listener: (event: JobFoldEvent) => void): () => void;
|
|
336
339
|
/** Typed skill and mode controls exposed to the SDK host. */
|
|
337
340
|
invokeSkill?(name: string, args?: string, options?: {
|
|
338
341
|
onPreflightAccepted?: () => void;
|
|
@@ -722,7 +725,7 @@ export interface UserPythonEventResult {
|
|
|
722
725
|
export type { ToolResultEventResult } from "../shared-events";
|
|
723
726
|
export interface BeforeAgentStartEventResult {
|
|
724
727
|
message?: Pick<CustomMessage, "customType" | "content" | "display" | "details" | "attribution">;
|
|
725
|
-
/** Replace the system prompt for this turn.
|
|
728
|
+
/** Replace the system prompt for this turn. To append, spread event.systemPrompt into the returned array. */
|
|
726
729
|
systemPrompt?: string[];
|
|
727
730
|
}
|
|
728
731
|
export type { SessionBeforeBranchResult, SessionBeforeCompactResult, SessionBeforeSwitchResult, SessionBeforeTreeResult, SessionCompactingResult, } from "../shared-events";
|
|
@@ -1138,7 +1141,7 @@ export interface ExtensionContextActions {
|
|
|
1138
1141
|
getActiveModelProfile?: () => string | undefined;
|
|
1139
1142
|
withSdkControlMutation?: <T>(body: () => Promise<T>) => Promise<T>;
|
|
1140
1143
|
cycleThinkingLevel?: () => ThinkingLevel | undefined;
|
|
1141
|
-
setQueueMode?: (kind: "steering" | "follow_up" | "
|
|
1144
|
+
setQueueMode?: (kind: "steering" | "follow_up" | "tool_interrupt", mode: unknown) => boolean;
|
|
1142
1145
|
getSkillState?: () => unknown;
|
|
1143
1146
|
getConfigItems?: () => unknown;
|
|
1144
1147
|
getBranchCandidates?: () => unknown;
|
|
@@ -1152,6 +1155,8 @@ export interface ExtensionContextActions {
|
|
|
1152
1155
|
totalBytes: number;
|
|
1153
1156
|
} | undefined>;
|
|
1154
1157
|
getJobs?: () => unknown;
|
|
1158
|
+
/** Subscribe to foreground-wait folds so the SDK host can publish `bash_folded`. Returns an unsubscribe. */
|
|
1159
|
+
onJobFold?: (listener: (event: JobFoldEvent) => void) => () => void;
|
|
1155
1160
|
setSdkPermissionProvider?: (provider: ((toolCall: ClientBridgePermissionToolCall, options: ClientBridgePermissionOption[], signal?: AbortSignal) => Promise<ClientBridgePermissionOutcome>) | undefined) => void;
|
|
1156
1161
|
setSdkClientBridge?: (bridge: ClientBridge | undefined) => void;
|
|
1157
1162
|
sdkControl?: (operation: string, input: Record<string, unknown>) => unknown | Promise<unknown>;
|
|
@@ -28,6 +28,19 @@ export interface GjcLaunchWorktreeResult extends GjcLaunchWorktreePlan {
|
|
|
28
28
|
createdBranch: boolean;
|
|
29
29
|
dirty?: boolean;
|
|
30
30
|
}
|
|
31
|
+
export interface LaunchWorktreeAbortOptions {
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
deadlineAt?: number;
|
|
34
|
+
now?: () => number;
|
|
35
|
+
}
|
|
36
|
+
export declare class WorktreePreparationTimeoutError extends Error {
|
|
37
|
+
readonly code = "worktree_preparation_timeout";
|
|
38
|
+
constructor(message?: string);
|
|
39
|
+
}
|
|
40
|
+
export declare class DependencyPreparationTimeoutError extends Error {
|
|
41
|
+
readonly code = "dependency_preparation_timeout";
|
|
42
|
+
constructor(message?: string);
|
|
43
|
+
}
|
|
31
44
|
/**
|
|
32
45
|
* Pure core of {@link resolveWorktreeBucket}, exported for tests.
|
|
33
46
|
*
|
|
@@ -41,11 +54,17 @@ export declare function planLaunchWorktree(cwd: string, mode: GjcLaunchWorktreeM
|
|
|
41
54
|
};
|
|
42
55
|
export declare function ensureLaunchWorktree(plan: GjcLaunchWorktreePlan | {
|
|
43
56
|
enabled: false;
|
|
44
|
-
}): GjcLaunchWorktreeResult | {
|
|
57
|
+
}, options?: LaunchWorktreeAbortOptions): GjcLaunchWorktreeResult | {
|
|
45
58
|
enabled: false;
|
|
46
59
|
};
|
|
60
|
+
export declare function ensureLaunchWorktreeCancellable(plan: GjcLaunchWorktreePlan | {
|
|
61
|
+
enabled: false;
|
|
62
|
+
}, options?: LaunchWorktreeAbortOptions): Promise<GjcLaunchWorktreeResult | {
|
|
63
|
+
enabled: false;
|
|
64
|
+
}>;
|
|
47
65
|
/** Workspace worktrees must own their complete lockfile-resolved dependency graph (#4620). */
|
|
48
66
|
export declare function ensureReusableNodeModules(sourceRoot: string, worktreePath: string): "symlink" | "present" | "missing";
|
|
67
|
+
export declare function ensureReusableNodeModulesCancellable(sourceRoot: string, worktreePath: string, options?: LaunchWorktreeAbortOptions): Promise<"symlink" | "present" | "missing">;
|
|
49
68
|
/** Result of {@link prepareLaunchWorktree}: the effective working directory, remaining args, and resolved worktree plan. */
|
|
50
69
|
export interface PreparedLaunchWorktree {
|
|
51
70
|
cwd: string;
|
|
@@ -55,3 +74,8 @@ export interface PreparedLaunchWorktree {
|
|
|
55
74
|
};
|
|
56
75
|
}
|
|
57
76
|
export declare function prepareLaunchWorktree(cwd: string, args: string[]): PreparedLaunchWorktree;
|
|
77
|
+
export declare function removeOwnedLaunchWorktree(plan: GjcLaunchWorktreePlan, receipt: {
|
|
78
|
+
created: boolean;
|
|
79
|
+
reused: boolean;
|
|
80
|
+
createdBranch: boolean;
|
|
81
|
+
}): void;
|
|
@@ -83,6 +83,8 @@ export declare const SessionStateLockTestHooks: {
|
|
|
83
83
|
forcedQuarantineName?: string;
|
|
84
84
|
/** @internal Observes bounded acquisition retries without changing their timing. */
|
|
85
85
|
afterAcquireContention?: (lockFile: string, attempt: number, elapsedMs: number) => void;
|
|
86
|
+
/** @internal Runs after transition mkdir contention and before stale-claim inspection. */
|
|
87
|
+
afterTransitionClaimContention?: (transitionDir: string) => void | Promise<void>;
|
|
86
88
|
};
|
|
87
89
|
/** Raised when the lock could not be acquired; callers map it to their own refusal. */
|
|
88
90
|
export type SessionStateLockUnavailableReason = "acquire_timeout" | "legacy_directory_owner_unprovenanced" | "lock_initialization_failed" | "lock_inspection_failed" | "lock_owner_live_or_unverifiable" | "lock_owner_record_fresh" | "lock_owner_record_unprovenanced" | "lock_release_failed" | "transition_claim_timeout" | "unsafe_lock_path_type";
|
|
@@ -100,6 +102,26 @@ export declare class SessionStateLockUnavailableError extends Error {
|
|
|
100
102
|
readonly elapsedMs?: number;
|
|
101
103
|
constructor(causeOrDetails?: unknown | SessionStateLockUnavailableDetails);
|
|
102
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Log fields describing a persist failure: the error text plus, when a session state
|
|
107
|
+
* lock refusal sits anywhere in the cause chain, its typed `reason` and `lockPath`.
|
|
108
|
+
* Wrapping errors (`PreviousRuntimeStateReadError`, `AggregateError`) are searched
|
|
109
|
+
* so the actionable detail is never buried behind a generic message.
|
|
110
|
+
*/
|
|
111
|
+
export declare function sessionStateLockFailureFields(error: unknown): {
|
|
112
|
+
error: string;
|
|
113
|
+
reason?: SessionStateLockUnavailableReason;
|
|
114
|
+
lockPath?: string;
|
|
115
|
+
};
|
|
116
|
+
export declare const PERSIST_FAILURE_WARN_WINDOW_MS = 30000;
|
|
117
|
+
/**
|
|
118
|
+
* Whether a persist failure should be logged at warn level. The first failure for each
|
|
119
|
+
* document and stable failure class in a 30s window warns; repeats are the caller's cue
|
|
120
|
+
* to log at debug instead.
|
|
121
|
+
*/
|
|
122
|
+
export declare function shouldWarnPersistFailure(key: string, error: unknown, now?: number): boolean;
|
|
123
|
+
/** @internal Test seam: forget every persist-failure warn window. */
|
|
124
|
+
export declare function resetPersistFailureWarnWindows(): void;
|
|
103
125
|
/**
|
|
104
126
|
* The identity-bound deletion primitives this lock is built on.
|
|
105
127
|
*
|
package/dist/types/main.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ type StartupModelProfileArgs = {
|
|
|
58
58
|
startupModel?: CreateAgentSessionOptions["model"];
|
|
59
59
|
startupThinkingLevel?: CreateAgentSessionOptions["thinkingLevel"];
|
|
60
60
|
preferCachedModels?: boolean;
|
|
61
|
+
preferCachedDefaultProfile?: boolean;
|
|
61
62
|
};
|
|
62
63
|
export declare function applyStartupModelProfiles(args: StartupModelProfileArgs): Promise<void>;
|
|
63
64
|
export declare function applyStartupModelProfilesOrExit(args: StartupModelProfileArgs): Promise<void>;
|
|
@@ -123,11 +123,11 @@ export declare function acpSessionStateFromConfig(query: unknown, modelCatalogQu
|
|
|
123
123
|
readonly value: "one-at-a-time";
|
|
124
124
|
readonly name: "One at a time";
|
|
125
125
|
} | {
|
|
126
|
-
readonly value: "
|
|
127
|
-
readonly name: "
|
|
126
|
+
readonly value: "abort_tools";
|
|
127
|
+
readonly name: "Abort running tools";
|
|
128
128
|
} | {
|
|
129
|
-
readonly value: "
|
|
130
|
-
readonly name: "
|
|
129
|
+
readonly value: "finish_tools";
|
|
130
|
+
readonly name: "Finish running tools";
|
|
131
131
|
})[];
|
|
132
132
|
} | {
|
|
133
133
|
id: "thinking";
|
|
@@ -151,11 +151,11 @@ export declare function acpSessionStateFromConfig(query: unknown, modelCatalogQu
|
|
|
151
151
|
readonly value: "one-at-a-time";
|
|
152
152
|
readonly name: "One at a time";
|
|
153
153
|
} | {
|
|
154
|
-
readonly value: "
|
|
155
|
-
readonly name: "
|
|
154
|
+
readonly value: "abort_tools";
|
|
155
|
+
readonly name: "Abort running tools";
|
|
156
156
|
} | {
|
|
157
|
-
readonly value: "
|
|
158
|
-
readonly name: "
|
|
157
|
+
readonly value: "finish_tools";
|
|
158
|
+
readonly name: "Finish running tools";
|
|
159
159
|
})[];
|
|
160
160
|
} | {
|
|
161
161
|
id: "steeringMode";
|
|
@@ -178,11 +178,11 @@ export declare function acpSessionStateFromConfig(query: unknown, modelCatalogQu
|
|
|
178
178
|
readonly value: "one-at-a-time";
|
|
179
179
|
readonly name: "One at a time";
|
|
180
180
|
} | {
|
|
181
|
-
readonly value: "
|
|
182
|
-
readonly name: "
|
|
181
|
+
readonly value: "abort_tools";
|
|
182
|
+
readonly name: "Abort running tools";
|
|
183
183
|
} | {
|
|
184
|
-
readonly value: "
|
|
185
|
-
readonly name: "
|
|
184
|
+
readonly value: "finish_tools";
|
|
185
|
+
readonly name: "Finish running tools";
|
|
186
186
|
})[];
|
|
187
187
|
} | {
|
|
188
188
|
id: "followUpMode";
|
|
@@ -205,14 +205,14 @@ export declare function acpSessionStateFromConfig(query: unknown, modelCatalogQu
|
|
|
205
205
|
readonly value: "one-at-a-time";
|
|
206
206
|
readonly name: "One at a time";
|
|
207
207
|
} | {
|
|
208
|
-
readonly value: "
|
|
209
|
-
readonly name: "
|
|
208
|
+
readonly value: "abort_tools";
|
|
209
|
+
readonly name: "Abort running tools";
|
|
210
210
|
} | {
|
|
211
|
-
readonly value: "
|
|
212
|
-
readonly name: "
|
|
211
|
+
readonly value: "finish_tools";
|
|
212
|
+
readonly name: "Finish running tools";
|
|
213
213
|
})[];
|
|
214
214
|
} | {
|
|
215
|
-
id: "
|
|
215
|
+
id: "toolInterruptPolicy";
|
|
216
216
|
name: string;
|
|
217
217
|
type: "select";
|
|
218
218
|
currentValue: string;
|
|
@@ -232,11 +232,11 @@ export declare function acpSessionStateFromConfig(query: unknown, modelCatalogQu
|
|
|
232
232
|
readonly value: "one-at-a-time";
|
|
233
233
|
readonly name: "One at a time";
|
|
234
234
|
} | {
|
|
235
|
-
readonly value: "
|
|
236
|
-
readonly name: "
|
|
235
|
+
readonly value: "abort_tools";
|
|
236
|
+
readonly name: "Abort running tools";
|
|
237
237
|
} | {
|
|
238
|
-
readonly value: "
|
|
239
|
-
readonly name: "
|
|
238
|
+
readonly value: "finish_tools";
|
|
239
|
+
readonly name: "Finish running tools";
|
|
240
240
|
})[];
|
|
241
241
|
})[];
|
|
242
242
|
modes: {
|
|
@@ -58,6 +58,10 @@ export declare class ModelSelectorComponent extends Container {
|
|
|
58
58
|
smartRoutingPreview?: (draft: AutoroutingSetup) => SmartRoutingPreview;
|
|
59
59
|
/** Open the smart-routing panel directly instead of the preset landing. */
|
|
60
60
|
smartRoutingOnly?: boolean;
|
|
61
|
+
/** Test seam: synchronous persisted-dismissal check to avoid async render churn. */
|
|
62
|
+
isBillingDismissed?: (key: string) => boolean;
|
|
63
|
+
/** Test seam: record that a billing notice was shown/dismissed. */
|
|
64
|
+
markBillingDismissed?: (key: string) => void;
|
|
61
65
|
});
|
|
62
66
|
dispose(): void;
|
|
63
67
|
refreshRoleAssignments(options?: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Component, Container } from "@gajae-code/tui";
|
|
2
|
-
import type
|
|
2
|
+
import { type ResumeSessionIdentity, type ResumeTailInspection, type SessionInfo } from "../../session/session-manager";
|
|
3
3
|
export interface SelectedSession {
|
|
4
4
|
kind: "selected";
|
|
5
5
|
path: string;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Container } from "@gajae-code/tui";
|
|
2
|
-
import type
|
|
2
|
+
import { type SessionInfo } from "../../session/session-manager";
|
|
3
3
|
export type SessionLiveness = "active" | "stale" | "unknown";
|
|
4
4
|
export interface DashboardSession {
|
|
5
5
|
id: string;
|
|
6
6
|
cwd: string;
|
|
7
7
|
title: string;
|
|
8
|
+
starred: boolean;
|
|
8
9
|
modified: Date;
|
|
9
10
|
messageCount: number;
|
|
10
11
|
messageCountIsEstimate?: boolean;
|
|
@@ -9,7 +9,7 @@ import type { ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetConte
|
|
|
9
9
|
import type { CompactOptions } from "../extensibility/extensions/types";
|
|
10
10
|
import { type Skill } from "../extensibility/skills";
|
|
11
11
|
import type { NotificationSessionReconcileResult, NotificationSessionStatus } from "../sdk/bus/session-control";
|
|
12
|
-
import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
|
|
12
|
+
import type { AgentSession, AgentSessionEvent, AsyncJobSnapshotItem } from "../session/agent-session";
|
|
13
13
|
import type { HistoryStorage } from "../session/history-storage";
|
|
14
14
|
import type { SessionContext, SessionManager } from "../session/session-manager";
|
|
15
15
|
import type { LspStartupServerInfo } from "../tools";
|
|
@@ -42,7 +42,21 @@ export declare function getComposerPlaceholder(keybindings: Pick<KeybindingsMana
|
|
|
42
42
|
readonly busyPromptMode: "steer" | "queue";
|
|
43
43
|
readonly showActionHints: boolean;
|
|
44
44
|
}): string;
|
|
45
|
-
|
|
45
|
+
/** Running background work split into the three kinds the activity indicator names. */
|
|
46
|
+
export interface BackgroundActivityTally {
|
|
47
|
+
subagents: number;
|
|
48
|
+
backgroundBash: number;
|
|
49
|
+
monitors: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Classify running jobs for the activity indicator using the three locked
|
|
53
|
+
* predicates: subagents are `task` jobs carrying subagent metadata, monitors
|
|
54
|
+
* are flagged by `metadata.monitor`, and background bash is a `bash` job that
|
|
55
|
+
* is not a monitor. A running job matching none of them (a task job without
|
|
56
|
+
* subagent metadata) is outside this indicator and is not counted.
|
|
57
|
+
*/
|
|
58
|
+
export declare function tallyBackgroundActivity(running: readonly AsyncJobSnapshotItem[]): BackgroundActivityTally;
|
|
59
|
+
export declare function resolveActivityIndicatorMessage(foregroundActive: boolean, activity: BackgroundActivityTally, foregroundMessage: string): string | undefined;
|
|
46
60
|
export declare function getWelcomeTranscriptReservedRows(chatContainer: Container, width: number): number;
|
|
47
61
|
export type WelcomeBannerSettingMode = "auto" | "unicode" | "square" | "ascii";
|
|
48
62
|
export declare function resolveWelcomeLogoMode(mode: WelcomeBannerSettingMode, env?: Record<string, string | undefined>, platform?: NodeJS.Platform): WelcomeLogoMode;
|