@gajae-code/coding-agent 0.11.5 → 0.11.7

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.
Files changed (138) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/types/capability/index.d.ts +10 -20
  3. package/dist/types/capability/types.d.ts +3 -0
  4. package/dist/types/commands/daemon.d.ts +2 -2
  5. package/dist/types/commands/sdk.d.ts +20 -2
  6. package/dist/types/config/keybindings.d.ts +1 -1
  7. package/dist/types/config/settings-schema.d.ts +67 -7
  8. package/dist/types/eval/py/runner-artifact.d.ts +8 -0
  9. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +5 -5
  10. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +20 -0
  11. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +19 -5
  12. package/dist/types/main.d.ts +24 -1
  13. package/dist/types/modes/components/btw-panel.d.ts +1 -0
  14. package/dist/types/modes/components/model-selector.d.ts +2 -0
  15. package/dist/types/modes/components/tool-status-header.d.ts +1 -0
  16. package/dist/types/modes/controllers/btw-controller.d.ts +5 -0
  17. package/dist/types/modes/interactive-mode.d.ts +2 -0
  18. package/dist/types/modes/types.d.ts +1 -0
  19. package/dist/types/runtime-mcp/content-limits.d.ts +7 -0
  20. package/dist/types/sdk/bus/chat-daemon-control.d.ts +4 -0
  21. package/dist/types/sdk/bus/index.d.ts +1 -1
  22. package/dist/types/sdk/bus/lifecycle-commands.d.ts +5 -4
  23. package/dist/types/sdk/bus/notification-service.d.ts +34 -0
  24. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +13 -3
  25. package/dist/types/sdk/bus/telegram-daemon.d.ts +61 -3
  26. package/dist/types/sdk/bus/topic-registry.d.ts +88 -2
  27. package/dist/types/sdk/client/discovery.d.ts +2 -0
  28. package/dist/types/sdk/client/liveness.d.ts +7 -0
  29. package/dist/types/sdk/transport/auth-preface.d.ts +9 -0
  30. package/dist/types/sdk/transport/index.d.ts +12 -0
  31. package/dist/types/sdk/transport/relay.d.ts +43 -0
  32. package/dist/types/sdk/transport/serve-cli.d.ts +4 -0
  33. package/dist/types/sdk/transport/socket.d.ts +7 -0
  34. package/dist/types/sdk/transport/stdio.d.ts +3 -0
  35. package/dist/types/session/agent-session.d.ts +28 -5
  36. package/dist/types/session/btw-contract.d.ts +16 -0
  37. package/dist/types/session/internal/managed-session-scope.d.ts +21 -7
  38. package/dist/types/session/internal/managed-session-storage.d.ts +10 -8
  39. package/dist/types/session/session-manager.d.ts +35 -4
  40. package/dist/types/session/yield-queue.d.ts +8 -0
  41. package/dist/types/setup/credential-import.d.ts +5 -1
  42. package/dist/types/setup/provider-onboarding.d.ts +2 -0
  43. package/dist/types/ssh/utils.d.ts +1 -0
  44. package/dist/types/task/discovery.d.ts +3 -1
  45. package/dist/types/tools/fetch.d.ts +5 -8
  46. package/dist/types/tools/image-gen.d.ts +16 -0
  47. package/dist/types/tools/skill-discovery.d.ts +7 -0
  48. package/dist/types/tools/sqlite-reader.d.ts +7 -0
  49. package/dist/types/utils/shell-snapshot.d.ts +12 -0
  50. package/dist/types/web/insane/bridge.d.ts +1 -0
  51. package/dist/types/web/insane/url-guard.d.ts +17 -0
  52. package/package.json +8 -8
  53. package/scripts/generate-sdk-operation-inventory.ts +3 -0
  54. package/src/capability/index.ts +50 -42
  55. package/src/capability/types.ts +3 -0
  56. package/src/cli/setup-cli.ts +10 -4
  57. package/src/cli.ts +34 -9
  58. package/src/commands/daemon.ts +22 -5
  59. package/src/commands/sdk.ts +42 -9
  60. package/src/config/keybindings.ts +1 -1
  61. package/src/config/model-profiles.ts +18 -0
  62. package/src/config/settings-schema.ts +71 -7
  63. package/src/defaults/gjc/skills/ultragoal/SKILL.md +42 -1
  64. package/src/discovery/ssh.ts +12 -1
  65. package/src/eval/py/kernel.ts +1 -21
  66. package/src/eval/py/runner-artifact.ts +84 -0
  67. package/src/extensibility/plugins/marketplace/fetcher.ts +191 -7
  68. package/src/gjc-runtime/ultragoal-guard.ts +88 -10
  69. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +103 -0
  70. package/src/gjc-runtime/ultragoal-runtime.ts +275 -12
  71. package/src/gjc-runtime/workflow-manifest.generated.json +58 -0
  72. package/src/gjc-runtime/workflow-manifest.ts +23 -0
  73. package/src/internal-urls/docs-index.generated.ts +9 -8
  74. package/src/internal-urls/local-protocol.ts +32 -6
  75. package/src/main.ts +87 -28
  76. package/src/modes/action-registry.ts +1 -1
  77. package/src/modes/components/btw-panel.ts +82 -16
  78. package/src/modes/components/model-selector.ts +31 -3
  79. package/src/modes/components/tool-status-header.ts +6 -1
  80. package/src/modes/controllers/btw-controller.ts +119 -36
  81. package/src/modes/controllers/command-controller.ts +15 -0
  82. package/src/modes/controllers/extension-ui-controller.ts +14 -2
  83. package/src/modes/controllers/input-controller.ts +31 -0
  84. package/src/modes/controllers/selector-controller.ts +106 -12
  85. package/src/modes/interactive-mode.ts +16 -7
  86. package/src/modes/runtime-init.ts +16 -2
  87. package/src/modes/types.ts +1 -0
  88. package/src/prompts/system/btw-user.md +3 -8
  89. package/src/prompts/tools/skill-discovery.md +1 -0
  90. package/src/runtime-mcp/client.ts +41 -55
  91. package/src/runtime-mcp/content-limits.ts +71 -0
  92. package/src/runtime-mcp/json-rpc.ts +23 -9
  93. package/src/runtime-mcp/transports/http.ts +50 -16
  94. package/src/sdk/bus/chat-daemon-control.ts +20 -7
  95. package/src/sdk/bus/index.ts +8 -7
  96. package/src/sdk/bus/lifecycle-commands.ts +16 -7
  97. package/src/sdk/bus/notification-service.ts +41 -18
  98. package/src/sdk/bus/telegram-daemon-contract.ts +13 -3
  99. package/src/sdk/bus/telegram-daemon-control.ts +26 -8
  100. package/src/sdk/bus/telegram-daemon.ts +1736 -338
  101. package/src/sdk/bus/topic-registry.ts +451 -12
  102. package/src/sdk/client/discovery.ts +19 -3
  103. package/src/sdk/client/liveness.ts +49 -0
  104. package/src/sdk/host/control/dispatch.ts +14 -5
  105. package/src/sdk/protocol/operation-inventory.generated.json +29 -0
  106. package/src/sdk/session.ts +29 -5
  107. package/src/sdk/transport/auth-preface.ts +82 -0
  108. package/src/sdk/transport/index.ts +18 -0
  109. package/src/sdk/transport/relay.ts +252 -0
  110. package/src/sdk/transport/serve-cli.ts +105 -0
  111. package/src/sdk/transport/socket.ts +197 -0
  112. package/src/sdk/transport/stdio.ts +17 -0
  113. package/src/session/agent-session.ts +1212 -768
  114. package/src/session/blob-store.ts +19 -6
  115. package/src/session/btw-contract.ts +59 -0
  116. package/src/session/internal/managed-session-scope.ts +313 -57
  117. package/src/session/internal/managed-session-storage.ts +146 -35
  118. package/src/session/session-manager.ts +385 -85
  119. package/src/session/yield-queue.ts +20 -0
  120. package/src/setup/credential-import.ts +28 -3
  121. package/src/setup/provider-onboarding.ts +30 -1
  122. package/src/setup/provider-presets.json +2 -1
  123. package/src/slash-commands/builtin-registry.ts +37 -1
  124. package/src/ssh/utils.ts +14 -0
  125. package/src/task/discovery.ts +8 -2
  126. package/src/tools/ask-answer-registry.ts +15 -1
  127. package/src/tools/ask.ts +1 -1
  128. package/src/tools/fetch.ts +13 -131
  129. package/src/tools/image-gen.ts +301 -20
  130. package/src/tools/read.ts +2 -0
  131. package/src/tools/skill-discovery.ts +39 -3
  132. package/src/tools/sqlite-reader.ts +63 -5
  133. package/src/utils/pasted-image-path.ts +15 -6
  134. package/src/utils/shell-snapshot.ts +173 -63
  135. package/src/web/insane/bridge.ts +5 -1
  136. package/src/web/insane/url-guard.ts +138 -27
  137. package/src/web/scrapers/types.ts +19 -49
  138. package/src/web/scrapers/utils.ts +12 -26
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.11.7] - 2026-07-22
6
+ ### Added
7
+
8
+ - `/btw` now opens an ephemeral multi-turn side chat: plain text continues the side thread until Esc returns to the main chat, while visible text-only context stays outside the main transcript and session observability/debug hooks and is scrubbed synchronously on close or abort.
9
+ - Added `statusLine.showActionHints` (default: `true`) to hide contextual action hints while retaining configured status-line segments.
10
+ - `skill_discovery` empty results now carry a `notice` when discovery config caused the emptiness — naming the exact disabled setting (`skills.enabled`, `skills.enablePiProject`, or `skills.enablePiUser`) and the `gjc config set` command to enable it. Previously a disabled config was indistinguishable from "no skills exist", silently hiding freshly written user/project skills.
11
+
12
+ ### Fixed
13
+
14
+ - Ordinary `ask` calls now normalize a provider-emitted `deepInterview: null` placeholder instead of misclassifying it as malformed Round-0 intent recovery data and rejecting it before coercion.
15
+ - Documented that custom OpenAI-compatible models omit vision by default: when `input` is unset, GJC treats the model as text-only and strips images with `[image omitted: model does not support vision]`. Vision backends must set `input: [text, image]` in `models.yml`.
16
+ - Restored `/models` preset landing navigation after the Image Generation row and made compaction/pruning regression fixtures use an explicit 200K context boundary instead of a mutable provider descriptor default.
17
+ - Fixed Windows legacy session artifact migration by using native directory identity size, a traversable detached-path alias, and writable file handles for final durability sync.
18
+ - `gjc setup credentials` now auto-imports only OAuth credentials with a finite expiry strictly in the future. Expired or malformed-expiry discoveries remain visible as non-importable records, and existing imported credentials remain recoverable through `/login`.
19
+ - Resumed managed sessions now complete the verified legacy `local://` artifact migration before synchronous path resolution, preserving legacy scratch files instead of failing startup with a migration-order error.
20
+ - Corrected Telegram's uncertain lifecycle guidance so create, close, and resume commands describe their own possible outcome; close and resume no longer display the create-only duplicate-start warning.
21
+
22
+ ## [0.11.5] - 2026-07-20
23
+ ### Fixed
24
+
25
+ - Internal transcript PageUp/PageDown now keeps moving through tool-output and other non-semantic rows instead of intermittently becoming a no-op after scrolling through anchored conversation content.
26
+
5
27
  ## [0.11.5] - 2026-07-20
6
28
  ### Changed
7
29
  - Telegram live-message streaming now defaults on for configured Telegram notifications through one durable global preference, supports live in-session preference refresh without weakening redaction, and keeps Discord and Slack finalized-only; process environment overrides remain available.
@@ -10,14 +32,25 @@
10
32
  - Session files now use v5 authority records. Do not roll back to a v4 writer after v5 session data has been created: v4 writers cannot preserve independent MCP and discovered-built-in selections.
11
33
 
12
34
  ### Fixed
35
+ - SQLite `read` raw queries now accept exactly one explicit `SELECT` statement, reject comments and statement tails before opening the database, recheck the invariant at execution, and enable SQLite query-only mode as defense in depth.
36
+ - Direct HTTP(S) marketplace catalogs now use connection-bound public-address validation, bounded redirects, and a 2 MiB response limit before parsing or caching.
37
+ - Bounded MCP list pagination by cursor-cycle, page-count, and item-count limits while preserving abort and cache behavior.
38
+ - Shell environment snapshots now use one process-private temporary root with exclusive private files, trusted cache validation, and whole-root shutdown cleanup instead of a predictable shared directory.
39
+ - Python kernel startup now materializes its bundled runner in one process-private temporary directory with exclusive file creation instead of consulting a predictable shared cache path.
40
+ - SSH command construction and discovery now reject malformed destinations with unsafe prefixes or control characters while preserving normal host, address, username, and alias forms.
13
41
  - Fixed the `subagent` tool's `resume` action silently swallowing manager failures. Resume outcomes other than `context_unavailable`/`not_found` (`no_runner`, `resume_failed`, `owner_shutdown_in_progress`, …) were dropped and the stale terminal subagent snapshot was returned as if the resume had succeeded, so ralplan's re-review loop believed the persisted Planner had resumed when it had not and never fell back correctly. The resume action now surfaces every non-ok reason (matching the `steer` branch), and the task resume runner marks a resumed subprocess that aborted or exited non-zero as a `failed` job (carrying its rendered failure summary) instead of reporting it `completed`.
42
+ - Daemon timeout flags now reject missing, malformed, non-positive, fractional, whitespace-containing, and unsafe integer values before daemon command side effects instead of partially parsing them.
14
43
  - Hardened standalone HTML session exports so session identifiers, provider/model labels, and embedded raster images remain confined to their intended HTML contexts; malformed image payloads are omitted.
44
+ - Restored legacy `gjc coordinator-mcp` and root `gjc --team --team-size <n>` routing to their native MCP and team commands, with strict team-size validation that prevents malformed legacy flags from selecting team lifecycle actions.
45
+ - Fixed the `subagent` tool's `resume` action silently swallowing manager failures. Resume outcomes other than `context_unavailable`/`not_found` (`no_runner`, `resume_failed`, `owner_shutdown_in_progress`, …) were dropped and the stale terminal subagent snapshot was returned as if the resume had succeeded, so ralplan's re-review loop believed the persisted Planner had resumed when it had not and never fell back correctly. The resume action now surfaces every non-ok reason (matching the `steer` branch), and the task resume runner marks a resumed subprocess that aborted or exited non-zero as a `failed` job (preserving its error text) instead of reporting it `completed`.
46
+ - OpenRouter image generation now retrieves provider-returned HTTP(S) images only through connection-bound public-address validation, revalidates bounded redirects, and enforces image content-type and byte limits before buffering.
15
47
  - Fixed the `subagent` tool's `resume` failing immediately for a persisted ralplan Planner. A subagent that finishes by calling `yield` (or is torn down right after a tool executes) left the saved session ending on an assistant `toolCall` with no matching `toolResult`; replaying that history on resume produced an invalid provider request (a `tool_use` not followed by a `tool_result`) that failed the resumed turn at once. Resumed transcripts now reconcile any trailing unpaired tool call with a synthesized placeholder result before the first resumed prompt. Additionally, a failed/no-op resume leg no longer overwrites the prior run's success output artifact with an empty file.
16
48
  - Fixed persisted subagent resumes being rejected before session reconstruction with `Session is inside managed storage but is not an authorized managed candidate`. Child session files intentionally live inside their parent session's artifact directory and are not top-level resume-picker candidates; the task resume path now explicitly opens the exact internally registered child session directory while retaining strict candidate validation for user-selected managed sessions.
17
49
  - Managed session resume scans now read only a bounded no-follow header prefix from foreign workspace transcripts, while fully recapturing and revalidating owned candidates before granting migration, receipt, or deletion authority.
18
50
  - Secret obfuscation now uses authenticated process-local placeholders that remain stable within a running process and opaque after restart.
19
51
  - Workspace-wide LSP diagnostics now fail closed instead of launching build or typecheck subprocesses outside execution-tool authorization; concrete-file and glob diagnostics remain available.
20
52
  - Clean, side-effect-free canonical provider stream first-event and next-event watchdog failures now retry on bare single-model legacy sessions; explicit legacy disable, managed fallback, and fail-closed structured, non-watchdog, or unsafe attempts are unchanged.
53
+ - Remote MCP HTTP and SSE responses now enforce finite content and message budgets before parsing or dispatch.
21
54
  - Added fail-closed managed tmux owner SIGABRT recovery: exact-child supervisor receipts and pre-CLI admission now bind replacement ownership, strict durable Ultragoal/transcript evidence reconciles terminal child yields over stale nonterminal runtime state, recovery hydration remains write-free until an ownership fence, and hostile identity, corruption, concurrency, and path boundaries preserve dirty product files (#2681).
22
55
  - Restored non-root startup on Synology and other Linux container filesystems that definitively report POSIX ACL storage unsupported for managed session paths; explicit `--session-dir` semantics and all owner, mode, type, symlink, identity, and scope-binding checks remain unchanged and fail closed (#2687).
23
56
  - Preserved access to legal SQLite table names beginning with `sqlite` but not reserved `sqlite_`.
@@ -59,6 +92,10 @@
59
92
  - SDK host shutdown now retries a failed broker unregister instead of short-circuiting with a stale broker-index entry, while retained startup-cleanup owner-release failures remain isolated from the red extension-error path (#2625).
60
93
  - Non-TTY launches now fail fast when stdin is empty and automatically use print mode for positional prompts and `@file` inputs, preventing orphaned interactive TUI processes (#2507).
61
94
 
95
+ ### Fixed
96
+
97
+ - The command palette now labels `app.session.fork` as “Branch from message,” matching its user-message selector and `AgentSession.branch()` behavior while preserving the existing action ID for keybinding compatibility.
98
+
62
99
  ## [0.11.2] - 2026-07-19
63
100
 
64
101
  ### Changed
@@ -17,26 +17,16 @@ export declare function loadCapability<T>(capabilityId: string, options?: LoadOp
17
17
  * Call this once on startup to enable persistent provider state.
18
18
  */
19
19
  export declare function initializeWithSettings(activeSettings: Settings): void;
20
- /**
21
- * Disable a provider globally (across all capabilities).
22
- */
23
- export declare function disableProvider(providerId: string): void;
24
- /**
25
- * Enable a previously disabled provider.
26
- */
27
- export declare function enableProvider(providerId: string): void;
28
- /**
29
- * Check if a provider is enabled.
30
- */
31
- export declare function isProviderEnabled(providerId: string): boolean;
32
- /**
33
- * Get list of all disabled provider IDs.
34
- */
35
- export declare function getDisabledProviders(): string[];
36
- /**
37
- * Set disabled providers from a list (replaces current set).
38
- */
39
- export declare function setDisabledProviders(providerIds: string[]): void;
20
+ /** Disable a provider for the supplied session settings. */
21
+ export declare function disableProvider(providerId: string, activeSettings?: Settings): void;
22
+ /** Enable a provider for the supplied session settings. */
23
+ export declare function enableProvider(providerId: string, activeSettings?: Settings): void;
24
+ /** Check whether a provider is enabled by the supplied session settings. */
25
+ export declare function isProviderEnabled(providerId: string, activeSettings?: Settings | undefined): boolean;
26
+ /** Get disabled providers from the supplied session settings. */
27
+ export declare function getDisabledProviders(activeSettings?: Settings | undefined): string[];
28
+ /** Replace disabled providers for the supplied session settings. */
29
+ export declare function setDisabledProviders(providerIds: string[], activeSettings?: Settings): void;
40
30
  /**
41
31
  * Get a capability definition (for introspection).
42
32
  */
@@ -5,6 +5,7 @@
5
5
  * paths like `.gjc`, `.gemini`, or `.vscode`, they simply ask for `load("mcps")`
6
6
  * and get back a unified array of MCP servers.
7
7
  */
8
+ import type { Settings } from "../config/settings";
8
9
  /**
9
10
  * Context passed to every provider loader.
10
11
  */
@@ -64,6 +65,8 @@ export interface LoadOptions {
64
65
  includeDisabled?: boolean;
65
66
  /** Explicit disabled extension IDs to apply instead of settings. */
66
67
  disabledExtensions?: string[];
68
+ /** Session settings whose provider policy applies to this load. */
69
+ settings?: Settings;
67
70
  }
68
71
  /**
69
72
  * Source metadata attached to every loaded item.
@@ -31,10 +31,10 @@ export default class Daemon extends Command {
31
31
  force: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
32
32
  description: string;
33
33
  };
34
- "graceful-timeout-ms": import("@gajae-code/utils/cli").FlagDescriptor<"integer"> & {
34
+ "graceful-timeout-ms": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
35
35
  description: string;
36
36
  };
37
- "kill-timeout-ms": import("@gajae-code/utils/cli").FlagDescriptor<"integer"> & {
37
+ "kill-timeout-ms": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
38
38
  description: string;
39
39
  };
40
40
  "spawn-if-stopped": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
@@ -15,17 +15,35 @@ export declare function runSessionHost(timing?: {
15
15
  cwd?: string;
16
16
  processIncarnation?: (pid: number) => string | undefined;
17
17
  }): Promise<void>;
18
+ export type SdkInternalArgv = {
19
+ action: "broker-internal";
20
+ agentDir: string;
21
+ } | {
22
+ action: "session-host-internal";
23
+ };
24
+ /** Parses the exact private argv contracts used by SDK child-process spawns. */
25
+ export declare function parseSdkInternalArgv(argv: readonly string[]): SdkInternalArgv;
18
26
  export default class Sdk extends Command {
19
27
  static description: string;
20
28
  static hidden: boolean;
29
+ static delegateHelp: boolean;
21
30
  static args: {
22
31
  action: import("@gajae-code/utils/cli").ArgDescriptor & {
23
- required: true;
32
+ required: false;
24
33
  options: string[];
25
34
  };
26
35
  };
27
36
  static flags: {
28
- "agent-dir": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
37
+ stdio: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
38
+ description: string;
39
+ };
40
+ socket: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
41
+ description: string;
42
+ };
43
+ session: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
44
+ description: string;
45
+ };
46
+ "pending-ceiling": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
29
47
  description: string;
30
48
  };
31
49
  };
@@ -279,7 +279,7 @@ export declare const KEYBINDINGS: {
279
279
  };
280
280
  readonly "app.session.fork": {
281
281
  readonly defaultKeys: [];
282
- readonly description: "Fork session";
282
+ readonly description: "Branch from message";
283
283
  };
284
284
  readonly "app.session.resume": {
285
285
  readonly defaultKeys: [];
@@ -937,6 +937,15 @@ export declare const SETTINGS_SCHEMA: {
937
937
  readonly type: "boolean";
938
938
  readonly default: true;
939
939
  };
940
+ readonly "statusLine.showActionHints": {
941
+ readonly type: "boolean";
942
+ readonly default: true;
943
+ readonly ui: {
944
+ readonly tab: "appearance";
945
+ readonly label: "Status Line Action Hints";
946
+ readonly description: "Show contextual keyboard shortcuts in the status line";
947
+ };
948
+ };
940
949
  readonly "statusLine.leftSegments": {
941
950
  readonly type: "array";
942
951
  readonly default: StatusLineSegmentId[];
@@ -1880,7 +1889,16 @@ export declare const SETTINGS_SCHEMA: {
1880
1889
  readonly ui: {
1881
1890
  readonly tab: "context";
1882
1891
  readonly label: "Save Handoff Docs";
1883
- readonly description: "Save generated handoff documents to markdown files for the auto-handoff flow";
1892
+ readonly description: "Save auto-triggered handoff documents as session artifacts (resolvable artifact:// URIs); manual /handoff does not save";
1893
+ };
1894
+ };
1895
+ readonly "compaction.handoffPromptExtension": {
1896
+ readonly type: "string";
1897
+ readonly default: "";
1898
+ readonly ui: {
1899
+ readonly tab: "context";
1900
+ readonly label: "Handoff Prompt Extension";
1901
+ readonly description: "Extra guidance appended to the default handoff-generation prompt for both manual /handoff and auto-handoff. It supplements, and never replaces, the built-in safety- and continuity-critical instructions.";
1884
1902
  };
1885
1903
  };
1886
1904
  readonly "compaction.remoteEnabled": {
@@ -2906,8 +2924,8 @@ export declare const SETTINGS_SCHEMA: {
2906
2924
  readonly default: false;
2907
2925
  readonly ui: {
2908
2926
  readonly tab: "tools";
2909
- readonly label: "Insane Search Fallback";
2910
- readonly description: "Opt in to the vendored insane-search escalation for blocked public URL reads (403/WAF/JS-gated). Off by default. Requires preinstalled python3 + curl_cffi (and node + playwright/stealth for the browser phase); changes network posture by enabling TLS/browser impersonation for public pages.";
2927
+ readonly label: "Insane Search Fallback (Compatibility)";
2928
+ readonly description: "Compatibility-only preference. Remote renderer fallback stays disabled because it cannot preserve validated per-hop network routing.";
2911
2929
  };
2912
2930
  };
2913
2931
  readonly "github.enabled": {
@@ -3768,12 +3786,12 @@ export declare const SETTINGS_SCHEMA: {
3768
3786
  };
3769
3787
  readonly "providers.image": {
3770
3788
  readonly type: "enum";
3771
- readonly values: readonly ["auto", "openai", "gemini", "openrouter", "antigravity"];
3789
+ readonly values: readonly ["auto", "openai", "gemini", "openrouter", "antigravity", "custom"];
3772
3790
  readonly default: "auto";
3773
3791
  readonly ui: {
3774
3792
  readonly tab: "providers";
3775
- readonly label: "Image Provider";
3776
- readonly description: "Provider for image generation tool";
3793
+ readonly label: "Image Generation";
3794
+ readonly description: "Provider and model for image generation tool";
3777
3795
  readonly options: readonly [{
3778
3796
  readonly value: "auto";
3779
3797
  readonly label: "Auto";
@@ -3781,7 +3799,7 @@ export declare const SETTINGS_SCHEMA: {
3781
3799
  }, {
3782
3800
  readonly value: "openai";
3783
3801
  readonly label: "OpenAI";
3784
- readonly description: "Uses the active GPT Responses/Codex model";
3802
+ readonly description: "Uses gpt-image-2 via OpenAI Responses/Codex";
3785
3803
  }, {
3786
3804
  readonly value: "gemini";
3787
3805
  readonly label: "Gemini";
@@ -3794,9 +3812,49 @@ export declare const SETTINGS_SCHEMA: {
3794
3812
  readonly value: "antigravity";
3795
3813
  readonly label: "Antigravity";
3796
3814
  readonly description: "Requires login with google-antigravity";
3815
+ }, {
3816
+ readonly value: "custom";
3817
+ readonly label: "Custom";
3818
+ readonly description: "OpenAI-compatible endpoint (set providers.imageCustomUrl)";
3797
3819
  }];
3798
3820
  };
3799
3821
  };
3822
+ readonly "providers.imageModel": {
3823
+ readonly type: "string";
3824
+ readonly default: undefined;
3825
+ readonly ui: {
3826
+ readonly tab: "providers";
3827
+ readonly label: "Image Model";
3828
+ readonly description: "Override the default image generation model for the selected provider";
3829
+ };
3830
+ };
3831
+ readonly "providers.imageCustomUrl": {
3832
+ readonly type: "string";
3833
+ readonly default: undefined;
3834
+ readonly ui: {
3835
+ readonly tab: "providers";
3836
+ readonly label: "Image Custom URL";
3837
+ readonly description: "Base URL for custom OpenAI-compatible image endpoint";
3838
+ };
3839
+ };
3840
+ readonly "providers.imageCustomKey": {
3841
+ readonly type: "string";
3842
+ readonly default: undefined;
3843
+ readonly ui: {
3844
+ readonly tab: "providers";
3845
+ readonly label: "Image Custom API Key";
3846
+ readonly description: "API key for custom OpenAI-compatible image endpoint";
3847
+ };
3848
+ };
3849
+ readonly "providers.imageCustomKeyEnv": {
3850
+ readonly type: "string";
3851
+ readonly default: undefined;
3852
+ readonly ui: {
3853
+ readonly tab: "providers";
3854
+ readonly label: "Image Custom API Key Env";
3855
+ readonly description: "Environment variable name holding the API key for custom image endpoint";
3856
+ };
3857
+ };
3800
3858
  readonly "providers.kimiApiFormat": {
3801
3859
  readonly type: "enum";
3802
3860
  readonly values: readonly ["openai", "anthropic"];
@@ -4046,6 +4104,7 @@ export interface CompactionSettings {
4046
4104
  reserveTokens: number;
4047
4105
  keepRecentTokens: number;
4048
4106
  handoffSaveToDisk: boolean;
4107
+ handoffPromptExtension: string;
4049
4108
  autoContinue: boolean;
4050
4109
  remoteEnabled: boolean;
4051
4110
  remoteEndpoint: string | undefined;
@@ -4121,6 +4180,7 @@ export interface StatusLineSettings {
4121
4180
  maxRows: number;
4122
4181
  showHookStatus: boolean;
4123
4182
  showSkillHud: boolean;
4183
+ showActionHints: boolean;
4124
4184
  leftSegments: StatusLineSegmentId[];
4125
4185
  rightSegments: StatusLineSegmentId[];
4126
4186
  segmentOptions: Record<string, unknown>;
@@ -0,0 +1,8 @@
1
+ export interface RunnerScriptCache {
2
+ ensureRunnerScript(): Promise<string>;
3
+ cleanup(): Promise<void>;
4
+ }
5
+ export declare function createRunnerScriptCache(tempRoot: string): RunnerScriptCache;
6
+ /** @internal Test-only initializer for isolated artifact assertions. */
7
+ export declare function createRunnerScriptInitializer(tempRoot: string): () => Promise<string>;
8
+ export declare const ensureRunnerScript: () => Promise<string>;
@@ -1,5 +1,5 @@
1
1
  import { type UltragoalGoal, type UltragoalLedgerEvent, type UltragoalNudgeSurface, type UltragoalPlan, type UltragoalReceiptKind } from "./ultragoal-runtime";
2
- export type UltragoalGuardState = "inactive" | "unrelated_goal" | "active_verified_complete" | "active_missing_receipt" | "active_stale_receipt" | "active_missing_final_receipt" | "active_dirty_quality_gate" | "active_review_blocked_unrecorded" | "active_review_blocked_recorded" | "unreadable_fail_closed";
2
+ export type UltragoalGuardState = "inactive" | "unrelated_goal" | "active_verified_complete" | "active_missing_receipt" | "active_stale_receipt" | "active_missing_final_receipt" | "active_dirty_quality_gate" | "active_review_blocked_unrecorded" | "active_review_blocked_recorded" | "active_missing_critic_verdict" | "unreadable_fail_closed";
3
3
  export interface UltragoalGuardDiagnostic {
4
4
  state: UltragoalGuardState;
5
5
  message: string;
@@ -78,10 +78,10 @@ export interface UltragoalPauseBlockDiagnostic {
78
78
  }
79
79
  /**
80
80
  * While an Ultragoal run is active, `goal({"op":"pause"})` is only allowed when the
81
- * current durable Ultragoal state is readable and the latest durable ledger event
82
- * classifies the current blocker as `human_blocked`. Resolvable blockers must be
83
- * worked, not parked. Reads fail closed so unreadable durable state or ledger data
84
- * blocks pause rather than silently allowing a give-up.
81
+ * current durable Ultragoal state is readable, the latest `blocker_classified`
82
+ * event is `human_blocked`, and a later fresh clean pause terminal critic verdict is bound to
83
+ * that exact classification. Reads fail closed so unreadable durable state or
84
+ * ledger data blocks pause rather than silently allowing a give-up.
85
85
  */
86
86
  export declare function isUltragoalPauseBlocked(cwd: string): Promise<UltragoalPauseBlockDiagnostic>;
87
87
  export declare function assertUltragoalPauseAllowed(cwd: string): Promise<void>;
@@ -1,10 +1,30 @@
1
1
  import type { UltragoalCompletionVerification, UltragoalGoal, UltragoalGoalStatus, UltragoalLedgerEvent, UltragoalPlan, UltragoalReceiptKind } from "./ultragoal-runtime";
2
+ export declare const CRITIC_VERDICT_EVENT = "critic_verdict";
3
+ export declare const CRITIC_GATE_HARD_STOP_EVENT = "critic_gate_hard_stop";
4
+ export declare const CRITIC_GATE_OVERRIDE_EVENT = "critic_gate_override";
5
+ export declare const TERMINAL_CRITIC_CEILING = 5;
6
+ export type CriticVerdict = "OKAY" | "ITERATE" | "REJECT";
2
7
  export type UltragoalReceiptFreshnessDiagnostic = {
3
8
  state: "inactive" | "unrelated_goal" | "active_verified_complete" | "active_missing_receipt" | "active_stale_receipt" | "active_missing_final_receipt" | "active_dirty_quality_gate" | "active_review_blocked_unrecorded" | "active_review_blocked_recorded" | "unreadable_fail_closed";
4
9
  message: string;
5
10
  goalId?: string;
6
11
  };
7
12
  export declare function requiredUltragoalGoals(plan: UltragoalPlan): UltragoalGoal[];
13
+ /** Hash the current required-goal set for terminal critic verdict freshness. */
14
+ export declare function computeCriticVerdictPlanGeneration(plan: UltragoalPlan): string;
15
+ export declare function isCleanPauseCriticVerdictShape(candidate: UltragoalLedgerEvent, planGeneration: string, classificationEventId: string): boolean;
16
+ export declare function isCleanPauseCriticVerdict(event: UltragoalLedgerEvent, opts: {
17
+ planGeneration: string;
18
+ classificationEventId: string;
19
+ }): boolean;
20
+ export declare function findCleanPauseCriticVerdict(plan: UltragoalPlan, ledger: readonly UltragoalLedgerEvent[], classificationEventId: string): UltragoalLedgerEvent | null;
21
+ /** Pure: count all ledger `critic_verdict` rows for an exact plan generation. */
22
+ export declare function countTerminalCriticVerdicts(ledger: readonly UltragoalLedgerEvent[], planGeneration: string): number;
23
+ /** Pure: count every non-OKAY terminal critic verdict recorded for this run. */
24
+ export declare function countNonOkayTerminalCriticVerdicts(ledger: readonly UltragoalLedgerEvent[], _legacyPlanGeneration?: string): number;
25
+ export declare function terminalCriticHardStopReached(ledger: readonly UltragoalLedgerEvent[], _legacyPlanGeneration?: string): boolean;
26
+ export declare function terminalCriticGateOverridden(ledger: readonly UltragoalLedgerEvent[]): boolean;
27
+ export declare function terminalCriticCeilingReached(ledger: readonly UltragoalLedgerEvent[], _legacyPlanGeneration?: string): boolean;
8
28
  export declare function receiptRelevantGoals(plan: UltragoalPlan, goal: UltragoalGoal, receiptKind: UltragoalReceiptKind): UltragoalGoal[];
9
29
  export declare function computeUltragoalPlanGeneration(input: {
10
30
  plan: UltragoalPlan;
@@ -1,5 +1,6 @@
1
1
  import type { WorkflowHudSummary } from "../skill-state/active-state";
2
- export { computeUltragoalPlanGeneration, receiptRelevantGoals } from "./ultragoal-receipt-freshness";
2
+ import { type CriticVerdict } from "./ultragoal-receipt-freshness";
3
+ export { CRITIC_GATE_HARD_STOP_EVENT, CRITIC_GATE_OVERRIDE_EVENT, CRITIC_VERDICT_EVENT, type CriticVerdict, computeUltragoalPlanGeneration, countTerminalCriticVerdicts, receiptRelevantGoals, TERMINAL_CRITIC_CEILING, terminalCriticCeilingReached, terminalCriticGateOverridden, } from "./ultragoal-receipt-freshness";
3
4
  export { captureUltragoalRecoverySnapshot, parseStrictTerminalTranscript, persistUltragoalRecoveryDecision, planUltragoalOwnerLossRecovery, type UltragoalOwnerLossReceipt, type UltragoalRecoveryBinding, type UltragoalRecoveryDecision, type UltragoalRecoverySnapshot, validateOwnerLossBinding, validateRawUltragoalEvidence, validateRecoveryAdmission, validateRecoveryPath, } from "./ultragoal-owner-loss-recovery";
4
5
  export type UltragoalGjcGoalMode = "aggregate" | "per-story";
5
6
  export type UltragoalGoalStatus = "pending" | "active" | "complete" | "failed" | "blocked" | "review_blocked" | "superseded";
@@ -401,10 +402,10 @@ export declare function recordUltragoalReviewBlockers(input: {
401
402
  }): Promise<UltragoalPlan>;
402
403
  export type UltragoalBlockerClassification = "human_blocked" | "resolvable";
403
404
  /**
404
- * Record an audited blocker triage classification in the durable ledger. A
405
- * `human_blocked` classification is the only thing that authorizes
406
- * `goal({"op":"pause"})` while an Ultragoal run is active; `resolvable` is an
407
- * audit note and never unblocks pause.
405
+ * Record an audited blocker triage classification in the durable ledger. Pause
406
+ * requires the latest `blocker_classified` event to be `human_blocked` and a
407
+ * later clean pause terminal critic verdict bound to that classification; `resolvable`
408
+ * is an audit note and never unblocks pause.
408
409
  */
409
410
  export declare function recordUltragoalBlockerClassification(input: {
410
411
  cwd: string;
@@ -412,6 +413,19 @@ export declare function recordUltragoalBlockerClassification(input: {
412
413
  evidence: string;
413
414
  goalId?: string;
414
415
  }): Promise<UltragoalLedgerEvent>;
416
+ export declare function recordUltragoalCriticVerdict(input: {
417
+ cwd: string;
418
+ terminus: "completion" | "pause";
419
+ verdict: CriticVerdict;
420
+ evidence: string;
421
+ blockers?: string[];
422
+ goalId?: string;
423
+ classificationEventId?: string;
424
+ }): Promise<UltragoalLedgerEvent>;
425
+ export declare function recordUltragoalCriticGateOverride(input: {
426
+ cwd: string;
427
+ evidence: string;
428
+ }): Promise<UltragoalLedgerEvent>;
415
429
  type UltragoalReviewContractStrength = "strong" | "thin-derived";
416
430
  interface UltragoalReviewFinding extends JsonObject {
417
431
  severity: "blocker";
@@ -85,11 +85,15 @@ interface InteractiveModeFactoryOptions {
85
85
  }
86
86
  type CreateInteractiveMode = (options: InteractiveModeFactoryOptions) => InteractiveMode;
87
87
  type ResumePickerTerminalCheck = () => boolean;
88
- type ListForResumePickerReadOnly = (cwd: string, sessionDir?: string) => Promise<SessionInfo[]>;
88
+ type ListForResumePickerReadOnly = (cwd: string, sessionDir?: string, storage?: undefined) => Promise<SessionInfo[]>;
89
+ type ListManagedForResumePickerReadOnly = (cwd: string, managedAgentDir?: string, storage?: undefined) => Promise<SessionInfo[]>;
90
+ type ResolveManagedAgentDirForScope = (cwd: string) => string;
89
91
  type SelectResumeSession = (sessions: SessionInfo[]) => Promise<SessionSelectionResult>;
90
92
  type OpenExistingSessionStrict = (identity: ResumeSessionIdentity, destination: SessionDestination, storage?: undefined, migrationPolicy?: SessionDirectoryMigrationPolicy) => Promise<StrictSessionOpenResult>;
91
93
  export declare const BARE_RESUME_CONFLICT_ERROR = "--resume without a session cannot be combined with --continue, --fork, or --no-session.";
92
94
  export declare const BARE_RESUME_INTERACTIVE_ERROR = "--resume requires an interactive terminal; use --resume <id>.";
95
+ /** Resolves only the managed agent root needed for pre-consent picker inventory. */
96
+ export declare function resolveManagedAgentDirForScope(_cwd: string): string;
93
97
  export declare const BARE_RESUME_OPEN_ERROR = "Could not open the selected session. Use --resume <id>.";
94
98
  export declare function runInteractiveMode(session: AgentSession, version: string, changelogMarkdown: string | undefined, notifs: (InteractiveModeNotify | null)[], startupUpdate: StartupUpdateOrchestrator, initialMessages: string[], setExtensionUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void, lspServers: LspStartupServerInfo[] | undefined, mcpManager: MCPManager | undefined, eventBus?: EventBus, initialMessage?: string, initialImages?: ImageContent[], createInteractiveMode?: CreateInteractiveMode, resumeAction?: "continue-tail" | "open-idle"): Promise<void>;
95
99
  declare function getChangelogForDisplay(parsed: Args): Promise<string | undefined>;
@@ -125,11 +129,30 @@ export interface RunRootCommandDependencies {
125
129
  runPrintMode?: RunPrintMode;
126
130
  isResumePickerTerminal?: ResumePickerTerminalCheck;
127
131
  listForResumePickerReadOnly?: ListForResumePickerReadOnly;
132
+ listManagedForResumePickerReadOnly?: ListManagedForResumePickerReadOnly;
133
+ resolveManagedAgentDirForScope?: ResolveManagedAgentDirForScope;
128
134
  selectResumeSession?: SelectResumeSession;
129
135
  openExistingSessionStrict?: OpenExistingSessionStrict;
130
136
  initializeSettings?: typeof Settings.init;
131
137
  loadSettingsForScope?: typeof Settings.loadForScope;
132
138
  }
139
+ export interface ModelRoleOverrides {
140
+ smol?: string;
141
+ slow?: string;
142
+ plan?: string;
143
+ }
144
+ /**
145
+ * Resolve the ephemeral `smol`/`slow`/`plan` model-role overrides.
146
+ *
147
+ * Precedence per role is CLI flag > documented `GJC_*_MODEL` > legacy
148
+ * `PI_*_MODEL`, matching the repo-wide GJC-first/PI-fallback convention.
149
+ * Resolution reads the process environment via `$pickenv`, which trims values
150
+ * and treats empty/whitespace as unset; it is deliberately kept separate from
151
+ * credential env resolution (`$credentialEnv`/`$pickCredentialEnv`). The
152
+ * function is pure and stateless, so it reads fresh each call and a later
153
+ * invocation never inherits an earlier one's values.
154
+ */
155
+ export declare function resolveModelRoleOverrides(parsed: Pick<Args, "smol" | "slow" | "plan">): ModelRoleOverrides;
133
156
  export declare function runRootCommand(parsed: Args, rawArgs: string[], deps?: RunRootCommandDependencies): Promise<void>;
134
157
  export declare function main(args: string[]): Promise<void>;
135
158
  export {};
@@ -6,6 +6,7 @@ interface BtwPanelComponentOptions {
6
6
  export declare class BtwPanelComponent extends Container {
7
7
  #private;
8
8
  constructor(options: BtwPanelComponentOptions);
9
+ beginTurn(question: string): void;
9
10
  appendText(delta: string): void;
10
11
  setAnswer(text: string): void;
11
12
  markComplete(): void;
@@ -26,6 +26,8 @@ export type ModelSelectorSelection = {
26
26
  } | {
27
27
  kind: "deleteProfile";
28
28
  profileName: string;
29
+ } | {
30
+ kind: "imageGeneration";
29
31
  };
30
32
  type RoleSelectCallback = (selection: ModelSelectorSelection) => void | Promise<void>;
31
33
  /**
@@ -38,6 +38,7 @@ export interface StatusLineSettings {
38
38
  previewHighlightSegment?: StatusLineSegmentId;
39
39
  showHookStatus?: boolean;
40
40
  showSkillHud?: boolean;
41
+ showActionHints?: boolean;
41
42
  sessionAccent?: boolean;
42
43
  maxRows?: number;
43
44
  }
@@ -1,10 +1,15 @@
1
1
  import type { InteractiveModeContext } from "../types";
2
+ type BtwFollowUpResult = "accepted" | "busy" | "closed" | "rejected";
2
3
  export declare class BtwController {
3
4
  #private;
4
5
  private readonly ctx;
5
6
  constructor(ctx: InteractiveModeContext);
6
7
  hasActiveRequest(): boolean;
8
+ hasOpenPanel(): boolean;
9
+ isTurnInFlight(): boolean;
7
10
  handleEscape(): boolean;
8
11
  dispose(): void;
9
12
  start(question: string): Promise<void>;
13
+ submitFollowUp(question: string): Promise<BtwFollowUpResult>;
10
14
  }
15
+ export {};
@@ -50,6 +50,7 @@ export interface InteractiveModeOptions {
50
50
  /** Additional initial messages to queue */
51
51
  initialMessages?: string[];
52
52
  }
53
+ export declare function selectShutdownDraft(editorText: string, hasActiveBtw: boolean): string;
53
54
  export declare class InteractiveMode implements InteractiveModeContext {
54
55
  #private;
55
56
  session: AgentSession;
@@ -261,6 +262,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
261
262
  handleImagePaste(): Promise<boolean>;
262
263
  handleBtwCommand(question: string): Promise<void>;
263
264
  hasActiveBtw(): boolean;
265
+ handleBtwFollowUp(question: string): Promise<"accepted" | "busy" | "closed" | "rejected">;
264
266
  handleBtwEscape(): boolean;
265
267
  cycleThinkingLevel(): void;
266
268
  cycleRoleModel(options?: {
@@ -295,6 +295,7 @@ export interface InteractiveModeContext {
295
295
  handleBackgroundCommand(): void;
296
296
  handleImagePaste(): Promise<boolean>;
297
297
  handleBtwCommand(question: string): Promise<void>;
298
+ handleBtwFollowUp(question: string): Promise<"accepted" | "busy" | "closed" | "rejected">;
298
299
  hasActiveBtw(): boolean;
299
300
  handleBtwEscape(): boolean;
300
301
  cycleThinkingLevel(): void;
@@ -0,0 +1,7 @@
1
+ export declare const MCP_MAX_CONTENT_BYTES: number;
2
+ export declare const MCP_MAX_ERROR_BYTES: number;
3
+ export declare const MCP_MAX_SSE_REQUEST_MESSAGES = 1024;
4
+ export declare const MCP_MAX_SSE_BATCH_MESSAGES = 1024;
5
+ export declare const MCP_HTTP_TIMEOUT_MS = 30000;
6
+ export declare function cancelMCPStream(stream: ReadableStream<Uint8Array> | null): void;
7
+ export declare function readMCPResponseText(response: Response, limit: number, truncate?: boolean, signal?: AbortSignal): Promise<string>;
@@ -6,6 +6,10 @@ export type ChatDaemonAction = "stop" | "reload";
6
6
  * Operational generations of the Discord/Slack daemon lifecycle contracts.
7
7
  * These are intentionally separate from per-session endpoint generations.
8
8
  * Generation 6 carries the retained managed filesystem authority boundary.
9
+ * Generation 7 restores macOS daemon signaling (kill(2) with a start-time
10
+ * incarnation recheck) so a live/hung owner can be replaced without an external
11
+ * `kill -9`. Generation 8 adopts Windows expected-identity ACL verification and
12
+ * repair for shared native authority.
9
13
  */
10
14
  export declare const CHAT_DAEMON_GENERATIONS: Readonly<Record<ChatDaemonKind, number>>;
11
15
  export declare function chatDaemonGeneration(kind: ChatDaemonKind): number;
@@ -494,7 +494,7 @@ export declare function createNotificationsExtension(api: ExtensionAPI, options?
494
494
  /** Whether this host mode can own the root SDK endpoint. Default: true. */
495
495
  sdkHostModeSupported?: boolean;
496
496
  onSdkRequest?: (kind: "control" | "query", connectionId: string, frame: Record<string, unknown>) => void;
497
- runEphemeralTurn?: (promptText: string, signal: AbortSignal) => Promise<{
497
+ runBtwTurn?: (question: string, signal: AbortSignal) => Promise<{
498
498
  replyText: string;
499
499
  }>;
500
500
  /** Observes settlement of optional session-branch startup after reconciliation completes. */
@@ -62,8 +62,9 @@ export declare function normalizeLifecyclePath(value: string): string | undefine
62
62
  /**
63
63
  * Map a lifecycle response/error to a user-facing Telegram message (G010).
64
64
  *
65
- * Only derives text from sessionId, mode, reason, a safe message, and candidate
66
- * {sessionId,path} — never a token or prompt. Each error reason gets tailored,
67
- * actionable copy; an "in progress" pending response is surfaced distinctly.
65
+ * Only derives text from sessionId, mode, reason, a safe message, the originating
66
+ * lifecycle verb, and candidate {sessionId,path} — never a token or prompt. Each
67
+ * error reason gets tailored, actionable copy; an "in progress" pending response
68
+ * is surfaced distinctly.
68
69
  */
69
- export declare function formatLifecycleOutcome(r: SessionLifecycleResponse): string;
70
+ export declare function formatLifecycleOutcome(r: SessionLifecycleResponse, verb?: LifecycleCommandVerb): string;