@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.
Files changed (163) hide show
  1. package/CHANGELOG.md +41 -1
  2. package/dist/types/async/job-manager.d.ts +32 -1
  3. package/dist/types/browser-backend.d.ts +12 -0
  4. package/dist/types/cli/update-cli.d.ts +1 -0
  5. package/dist/types/commands/sdk.d.ts +2 -0
  6. package/dist/types/config/billing-path.d.ts +25 -0
  7. package/dist/types/config/config-schema-version.d.ts +13 -1
  8. package/dist/types/config/model-registry.d.ts +16 -0
  9. package/dist/types/config/settings-schema.d.ts +17 -7
  10. package/dist/types/extensibility/extensions/types.d.ts +8 -3
  11. package/dist/types/gjc-runtime/launch-worktree.d.ts +25 -1
  12. package/dist/types/gjc-runtime/session-state-lock.d.ts +22 -0
  13. package/dist/types/main.d.ts +1 -0
  14. package/dist/types/modes/acp/acp-agent.d.ts +21 -21
  15. package/dist/types/modes/components/model-selector.d.ts +4 -0
  16. package/dist/types/modes/components/session-selector.d.ts +1 -1
  17. package/dist/types/modes/components/sessions-dashboard.d.ts +2 -1
  18. package/dist/types/modes/interactive-mode.d.ts +16 -2
  19. package/dist/types/modes/theme/theme.d.ts +2 -1
  20. package/dist/types/modes/types.d.ts +2 -0
  21. package/dist/types/sdk/broker/broker.d.ts +2 -1
  22. package/dist/types/sdk/broker/ensure.d.ts +3 -0
  23. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +6 -0
  24. package/dist/types/sdk/broker/lifecycle.d.ts +14 -0
  25. package/dist/types/sdk/broker/startup-budget.d.ts +52 -0
  26. package/dist/types/sdk/broker/state-version.d.ts +17 -0
  27. package/dist/types/sdk/bus/discord-daemon.d.ts +1 -1
  28. package/dist/types/sdk/bus/index.d.ts +3 -1
  29. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +1 -1
  30. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +1 -1
  31. package/dist/types/sdk/bus/slack-conversation.d.ts +1 -1
  32. package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
  33. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
  34. package/dist/types/sdk/cli/rows.d.ts +8 -2
  35. package/dist/types/sdk/cli/session-cli.d.ts +2 -1
  36. package/dist/types/sdk/host/events.d.ts +1 -0
  37. package/dist/types/sdk/host/query/cursor.d.ts +4 -2
  38. package/dist/types/sdk/host/query/handlers.d.ts +1 -0
  39. package/dist/types/sdk/host/query/revision-store.d.ts +1 -0
  40. package/dist/types/sdk/host/session-runtime.d.ts +18 -17
  41. package/dist/types/sdk/lifecycle-session.d.ts +1 -1
  42. package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -5
  43. package/dist/types/sdk/receipt-state.d.ts +2 -0
  44. package/dist/types/sdk/router/session-router.d.ts +4 -0
  45. package/dist/types/sdk/turn-result.d.ts +6 -0
  46. package/dist/types/session/agent-session.d.ts +47 -7
  47. package/dist/types/session/fold-coordinator.d.ts +29 -2
  48. package/dist/types/session/session-manager.d.ts +14 -2
  49. package/dist/types/tools/ask.d.ts +1 -0
  50. package/dist/types/tools/bash.d.ts +12 -0
  51. package/dist/types/tools/browser/launch.d.ts +10 -0
  52. package/dist/types/tools/browser/registry.d.ts +8 -0
  53. package/dist/types/tools/index.d.ts +6 -10
  54. package/dist/types/tools/job.d.ts +3 -1
  55. package/dist/types/utils/external-editor.d.ts +7 -0
  56. package/examples/extensions/README.md +1 -1
  57. package/examples/extensions/pirate.ts +7 -4
  58. package/package.json +7 -7
  59. package/scripts/generate-sdk-operation-inventory.ts +7 -1
  60. package/src/async/job-manager.ts +107 -9
  61. package/src/browser-backend.ts +29 -0
  62. package/src/cli/plugin-cli.ts +29 -0
  63. package/src/cli/update-cli.ts +63 -12
  64. package/src/commands/sdk.ts +22 -7
  65. package/src/config/billing-path.ts +42 -0
  66. package/src/config/config-schema-version.ts +18 -1
  67. package/src/config/model-preset-registry.ts +177 -18
  68. package/src/config/model-registry.ts +268 -42
  69. package/src/config/settings-schema.ts +19 -7
  70. package/src/config/settings.ts +46 -15
  71. package/src/coordinator-mcp/projection-scan.ts +6 -6
  72. package/src/coordinator-mcp/server.ts +21 -1
  73. package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
  74. package/src/extensibility/extensions/runner.ts +27 -0
  75. package/src/extensibility/extensions/types.ts +8 -3
  76. package/src/extensibility/gjc-plugins/installer.ts +51 -11
  77. package/src/extensibility/runtime-skill-discovery.ts +110 -3
  78. package/src/extensibility/skills.ts +22 -12
  79. package/src/gjc-runtime/launch-worktree.ts +285 -4
  80. package/src/gjc-runtime/session-state-lock.ts +154 -28
  81. package/src/gjc-runtime/session-state-sidecar.ts +10 -17
  82. package/src/gjc-runtime/tmux-owner-isolation.ts +16 -1
  83. package/src/internal-urls/docs-index.generated.ts +10 -10
  84. package/src/main.ts +4 -1
  85. package/src/modes/acp/acp-agent.ts +5 -5
  86. package/src/modes/components/model-selector.ts +76 -8
  87. package/src/modes/components/session-selector.ts +23 -15
  88. package/src/modes/components/sessions-dashboard.ts +8 -5
  89. package/src/modes/controllers/command-controller.ts +1 -1
  90. package/src/modes/controllers/event-controller.ts +30 -4
  91. package/src/modes/controllers/extension-ui-controller.ts +13 -13
  92. package/src/modes/controllers/input-controller.ts +2 -2
  93. package/src/modes/controllers/selector-controller.ts +10 -3
  94. package/src/modes/interactive-mode.ts +36 -12
  95. package/src/modes/prompt-action-autocomplete.ts +30 -4
  96. package/src/modes/runtime-init.ts +12 -9
  97. package/src/modes/theme/theme.ts +5 -0
  98. package/src/modes/types.ts +2 -0
  99. package/src/modes/utils/ui-helpers.ts +22 -3
  100. package/src/prompts/agent-fragments/browser-aside.md +22 -0
  101. package/src/prompts/tools/ask.md +1 -1
  102. package/src/prompts/tools/bash.md +1 -0
  103. package/src/prompts/tools/job.md +1 -1
  104. package/src/sdk/acp/adapter.ts +5 -0
  105. package/src/sdk/broker/broker.ts +10 -1
  106. package/src/sdk/broker/ensure.ts +76 -3
  107. package/src/sdk/broker/lifecycle-ledger.ts +6 -0
  108. package/src/sdk/broker/lifecycle.ts +254 -34
  109. package/src/sdk/broker/spawn-substrate.ts +45 -2
  110. package/src/sdk/broker/startup-budget.ts +144 -2
  111. package/src/sdk/broker/state-version.ts +17 -0
  112. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  113. package/src/sdk/bus/chat-daemon-runtime.ts +111 -24
  114. package/src/sdk/bus/discord-daemon.ts +50 -10
  115. package/src/sdk/bus/index.ts +33 -3
  116. package/src/sdk/bus/kind-aware-reconciliation.ts +296 -48
  117. package/src/sdk/bus/lifecycle-commands.ts +4 -0
  118. package/src/sdk/bus/notification-service.ts +22 -5
  119. package/src/sdk/bus/prompt-reconciliation.ts +7 -2
  120. package/src/sdk/bus/reconciliation-store.ts +55 -31
  121. package/src/sdk/bus/slack-conversation.ts +1 -1
  122. package/src/sdk/bus/slack-daemon.ts +72 -38
  123. package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
  124. package/src/sdk/cli/rows.ts +30 -7
  125. package/src/sdk/cli/session-cli.ts +33 -21
  126. package/src/sdk/host/control/dispatch.ts +2 -2
  127. package/src/sdk/host/events.ts +1 -0
  128. package/src/sdk/host/host.ts +2 -0
  129. package/src/sdk/host/query/cursor.ts +52 -7
  130. package/src/sdk/host/query/handlers.ts +33 -12
  131. package/src/sdk/host/query/revision-store.ts +12 -0
  132. package/src/sdk/host/session-runtime.test.ts +463 -8
  133. package/src/sdk/host/session-runtime.ts +383 -54
  134. package/src/sdk/host/surface-policy.ts +3 -3
  135. package/src/sdk/lifecycle-session.ts +7 -2
  136. package/src/sdk/prompt-deadline-manager.ts +2 -1
  137. package/src/sdk/protocol/operation-inventory.generated.json +54 -3
  138. package/src/sdk/protocol/operation-registry.ts +1 -1
  139. package/src/sdk/receipt-state.ts +10 -0
  140. package/src/sdk/router/session-router.ts +152 -59
  141. package/src/sdk/session.ts +60 -41
  142. package/src/sdk/turn-result.ts +22 -0
  143. package/src/session/agent-session.ts +1033 -260
  144. package/src/session/fold-coordinator.ts +40 -3
  145. package/src/session/session-manager.ts +517 -77
  146. package/src/slash-commands/builtin-registry.ts +41 -0
  147. package/src/task/executor.ts +9 -4
  148. package/src/tools/ask-contract.test.ts +64 -0
  149. package/src/tools/ask-contract.ts +36 -1
  150. package/src/tools/ask.ts +10 -8
  151. package/src/tools/bash-interactive.ts +11 -2
  152. package/src/tools/bash.ts +156 -33
  153. package/src/tools/browser/launch.ts +37 -0
  154. package/src/tools/browser/registry.ts +99 -9
  155. package/src/tools/cron.ts +6 -4
  156. package/src/tools/descriptors.test.ts +15 -0
  157. package/src/tools/descriptors.ts +5 -1
  158. package/src/tools/index.ts +6 -6
  159. package/src/tools/job.ts +4 -1
  160. package/src/tools/monitor.ts +12 -9
  161. package/src/tools/resolve.ts +30 -10
  162. package/src/tools/tool-catalog.generated.ts +2 -2
  163. package/src/utils/external-editor.ts +72 -1
@@ -6,7 +6,7 @@ export type SymbolPreset = "unicode" | "nerd" | "ascii";
6
6
  /**
7
7
  * All available symbol keys organized by category.
8
8
  */
9
- export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.folder" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.agents" | "icon.cache" | "icon.input" | "icon.output" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "thinking.max" | "checkbox.checked" | "checkbox.unchecked" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.editing" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers";
9
+ export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.folder" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.agents" | "icon.cache" | "icon.input" | "icon.output" | "icon.host" | "icon.session" | "icon.star" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "thinking.max" | "checkbox.checked" | "checkbox.unchecked" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.editing" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers";
10
10
  export type SpinnerType = "status" | "activity";
11
11
  export declare const THEME_COLOR_KEYS: readonly ["accent", "border", "borderAccent", "borderMuted", "success", "error", "warning", "muted", "dim", "text", "thinkingText", "selectedBg", "userMessageBg", "userMessageText", "customMessageBg", "customMessageText", "customMessageLabel", "toolPendingBg", "toolSuccessBg", "toolErrorBg", "toolTitle", "toolOutput", "mdHeading", "mdLink", "mdLinkUrl", "mdCode", "mdCodeBlock", "mdCodeBlockBorder", "mdQuote", "mdQuoteBorder", "mdHr", "mdListBullet", "toolDiffAdded", "toolDiffRemoved", "toolDiffContext", "syntaxComment", "syntaxKeyword", "syntaxFunction", "syntaxVariable", "syntaxString", "syntaxNumber", "syntaxType", "syntaxOperator", "syntaxPunctuation", "thinkingOff", "thinkingMinimal", "thinkingLow", "thinkingMedium", "thinkingHigh", "thinkingXhigh", "bashMode", "pythonMode", "statusLineBg", "statusLineSep", "statusLineModel", "statusLinePath", "statusLineGitClean", "statusLineGitDirty", "statusLineContext", "statusLineSpend", "statusLineStaged", "statusLineDirty", "statusLineUntracked", "statusLineOutput", "statusLineCost", "statusLineSubagents"];
12
12
  export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "thinkingText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "bashMode" | "pythonMode" | "statusLineSep" | "statusLineModel" | "statusLinePath" | "statusLineGitClean" | "statusLineGitDirty" | "statusLineContext" | "statusLineSpend" | "statusLineStaged" | "statusLineDirty" | "statusLineUntracked" | "statusLineOutput" | "statusLineCost" | "statusLineSubagents";
@@ -128,6 +128,7 @@ export declare class Theme {
128
128
  output: string;
129
129
  host: string;
130
130
  session: string;
131
+ star: string;
131
132
  package: string;
132
133
  warning: string;
133
134
  rewind: string;
@@ -35,6 +35,8 @@ export type CompactionQueuedMessage = {
35
35
  text: string;
36
36
  mode: "steer" | "followUp";
37
37
  followUpQueuePolicy?: "sequential";
38
+ /** Composer steers stay one per poll even under `steeringMode: "all"`. */
39
+ steerQueuePolicy?: "sequential";
38
40
  };
39
41
  export type SubmittedUserInput = {
40
42
  text: string;
@@ -35,7 +35,8 @@ type ResolvedBrokerSettings = {
35
35
  spawnPromptLayer?: SpawnPromptLayer;
36
36
  masterOrphanGraceMs: number;
37
37
  };
38
- export type BrokerErrorCode = "idempotency_conflict" | "terminal_uncertain" | "broker_restarting" | "unavailable" | "endpoint_stale" | "resource_gone" | "invalid_input" | "spawn_failed" | "ready_then_exited" | "endpoint_unreadable" | "startup_admission_timeout" | "startup_admission_refused" | "readiness_timeout" | "close_refused" | "not_found" | "live_session" | "cleanup_pending" | (string & {});
38
+ export declare function resolveBrokerPackageGeneration(): string;
39
+ export type BrokerErrorCode = "idempotency_conflict" | "terminal_uncertain" | "broker_restarting" | "unavailable" | "endpoint_stale" | "resource_gone" | "invalid_input" | "spawn_failed" | "ready_then_exited" | "endpoint_unreadable" | "startup_admission_timeout" | "startup_admission_refused" | "readiness_timeout" | "worktree_preparation_timeout" | "dependency_preparation_timeout" | "worktree_in_use" | "incarnation_unavailable" | "close_refused" | "not_found" | "live_session" | "cleanup_pending" | (string & {});
39
40
  export type BrokerCleanupIdentity = {
40
41
  dev: string;
41
42
  ino: string;
@@ -61,6 +61,7 @@ interface ReapTiming {
61
61
  gracefulMs: number;
62
62
  killVerifyMs: number;
63
63
  }
64
+ type BrokerOwnerIdentity = Pick<BrokerDiscovery, "ownerId" | "pid" | "incarnation">;
64
65
  /** Starts the detached broker entrypoint when discovery has no live owner. */
65
66
  export declare function ensureBroker(settings: EnsureBrokerSettings): Promise<BrokerDiscovery>;
66
67
  /** Starts one fresh fixture broker and returns its sole exact-child close lease. */
@@ -73,6 +74,8 @@ export declare function startFixtureBrokerWithLeaseForTest(settings: EnsureBroke
73
74
  export declare function startFixtureBrokerCommandWithLeaseForTest(command: FixtureBrokerCommand): StartedFixtureBrokerCommand;
74
75
  /** Test hook: returns a stop handle for the detached broker this process spawned. */
75
76
  export declare function brokerOwnerForTest(agentDir: string): BrokerOwner | undefined;
77
+ /** Test hook: verifies the complete broker owner identity used during stale retirement. */
78
+ export declare function brokerOwnerIdentityMatchesForTest(left: BrokerOwnerIdentity | null, right: BrokerOwnerIdentity): boolean;
76
79
  /** Test hook: drives the detached-broker reap on a controllable child surface. */
77
80
  export declare function reapSpawnedBrokerForTest(child: ChildProcess, timing?: ReapTiming): Promise<void>;
78
81
  /** Test hook: resolves the complete broker environment without spawning. */
@@ -43,6 +43,7 @@ export interface LifecycleDurableEffectsReceipt {
43
43
  cwdDigest: string;
44
44
  created: boolean;
45
45
  reused: boolean;
46
+ createdBranch: boolean;
46
47
  branchDigest?: string;
47
48
  };
48
49
  transcript?: {
@@ -50,6 +51,11 @@ export interface LifecycleDurableEffectsReceipt {
50
51
  contentDigest: string;
51
52
  };
52
53
  startup?: LifecycleStartupFailureReceipt;
54
+ timings?: {
55
+ worktreePreparationMs?: number;
56
+ dependencyPreparationMs?: number;
57
+ spawnAuthorizedAtOffsetMs?: number;
58
+ };
53
59
  digest?: string;
54
60
  }
55
61
  export interface LifecycleLedgerEntry {
@@ -1,4 +1,5 @@
1
1
  import { type ChildProcess } from "node:child_process";
2
+ import { type GjcLaunchWorktreePlan } from "../../gjc-runtime/launch-worktree";
2
3
  import type { SessionLifecycleMcpServer } from "../acp/mcp";
3
4
  import { type SdkStartupFailure, type SdkStartupRollbackResult } from "../startup-capability";
4
5
  import type { Broker, BrokerCleanupEvidence, BrokerResponse } from "./broker";
@@ -26,10 +27,22 @@ type LifecycleCommand = SdkInternalSpawnCommand | {
26
27
  args: string[];
27
28
  };
28
29
  type LifecycleCommandResolver = () => LifecycleCommand;
30
+ type EnsureLaunchWorktreeForTest = (plan: GjcLaunchWorktreePlan, opts: {
31
+ signal: AbortSignal;
32
+ deadlineAt: number;
33
+ }) => Promise<SessionLifecycleWorktreeReceipt & {
34
+ createdBranch: boolean;
35
+ }>;
36
+ type EnsureReusableNodeModulesForTest = (sourceRoot: string, worktreePath: string, opts: {
37
+ signal: AbortSignal;
38
+ deadlineAt: number;
39
+ }) => Promise<"symlink" | "present" | "missing">;
29
40
  /** Test-only hook for simulating a crash immediately after one exact lifecycle detach. */
30
41
  export declare function setLifecycleCleanupHookForTest(broker: Broker, hook: (() => void) | undefined): void;
31
42
  export declare function setLifecycleCommandResolverForTest(broker: Broker, resolver: LifecycleCommandResolver | undefined): void;
32
43
  export declare function setLifecycleTimingForTest(broker: Broker, timing: LifecycleTiming | undefined): void;
44
+ export declare function setEnsureLaunchWorktreeForTest(_broker: Broker | undefined, fn?: EnsureLaunchWorktreeForTest | undefined): void;
45
+ export declare function setEnsureReusableNodeModulesForTest(_broker: Broker | undefined, fn?: EnsureReusableNodeModulesForTest | undefined): void;
33
46
  /** Deterministic platform seam for Windows-only ready-then-exit tolerance. */
34
47
  export declare function setLifecycleHostPlatformForTest(platform: NodeJS.Platform | undefined): void;
35
48
  export declare function readyThenExitToleranceEnabledForTest(): boolean;
@@ -45,6 +58,7 @@ export interface SessionLifecycleWorktreeReceipt {
45
58
  cwd: string;
46
59
  created: boolean;
47
60
  reused: boolean;
61
+ createdBranch: boolean;
48
62
  branch?: string;
49
63
  }
50
64
  export interface SessionLifecycleTranscriptIdentity {
@@ -2,8 +2,16 @@
2
2
  export declare const DEFAULT_READINESS_TIMEOUT_MS = 10000;
3
3
  export declare const MIN_READINESS_TIMEOUT_MS = 4000;
4
4
  export declare const MAX_READINESS_TIMEOUT_MS = 60000;
5
+ /** Bounded git worktree add/reuse window; independent of child semantic readiness. */
6
+ export declare const DEFAULT_WORKTREE_PREPARATION_TIMEOUT_MS = 30000;
7
+ export declare const MIN_PREPARATION_TIMEOUT_MS = 1000;
8
+ export declare const MAX_PREPARATION_TIMEOUT_MS = 120000;
9
+ /** Bounded workspace install window; independent of child semantic readiness. */
10
+ export declare const DEFAULT_DEPENDENCY_PREPARATION_TIMEOUT_MS = 30000;
5
11
  export declare function isValidReadinessTimeoutMs(value: unknown): value is number;
12
+ export declare function isValidPreparationTimeoutMs(value: unknown): value is number;
6
13
  export declare const READINESS_TIMEOUT_INVALID_MESSAGE = "readinessTimeoutMs must be an integer between 4000 and 60000.";
14
+ export declare const PREPARATION_TIMEOUT_INVALID_MESSAGE = "worktreePreparationTimeoutMs and dependencyPreparationTimeoutMs must be integers between 1000 and 120000.";
7
15
  /**
8
16
  * Sleep until the duration elapses or the caller cancels the wait. Queue admission
9
17
  * uses this so a granted or refused waiter does not retain its cutoff timer for the
@@ -40,5 +48,49 @@ export declare function lifecycleStartupBudgetMs(requestedReadinessTimeoutMs: nu
40
48
  * rather than left unextended: the broker queues it for exactly as long as one that
41
49
  * asked, so the common path would otherwise fail client-side while the broker runs
42
50
  * the startup to a durably persisted terminal result.
51
+ *
52
+ * Worktree launches add independent preparation budgets so git add / install cannot
53
+ * cut the caller while the broker still owns the request. One-arg
54
+ * {@link lifecycleStartupBudgetMs} stays queue+readiness for no-worktree callers.
43
55
  */
44
56
  export declare function lifecycleRequestTimeoutMs(operation: string, input: Record<string, unknown>): number | undefined;
57
+ /**
58
+ * True when this request will run named or detached worktree preparation.
59
+ * Coordinator nests the selector at `target.worktree`; Direct/lifecycle service
60
+ * put `worktree` on the mutation target itself; broker serialization also
61
+ * accepts `{ worktree: { name } }` without `enabled`.
62
+ */
63
+ export declare function lifecycleRequestHasWorktree(input: Record<string, unknown>): boolean;
64
+ /**
65
+ * Sum of worktree and dependency preparation budgets, or 0 when the request
66
+ * has no worktree. Returns `undefined` when an explicit prep field is present
67
+ * but invalid so callers fail closed instead of silently dropping prep time.
68
+ */
69
+ export declare function preparationBudgetMs(input: Record<string, unknown>): number | undefined;
70
+ export interface LifecycleOuterDeadlines {
71
+ admittedAt: number;
72
+ worktreePrepTimeoutMs: number;
73
+ dependencyPrepTimeoutMs: number;
74
+ requestedReadinessTimeoutMs: number;
75
+ worktreePreparationDeadlineAt: number;
76
+ lifecycleCleanupDeadlineAt: number;
77
+ }
78
+ /**
79
+ * Whole-request outer deadlines for a worktree launch. Child semantic readiness
80
+ * is still derived later at prepSucceededAt. Dependency start is sequential:
81
+ * callers clip remaining dep budget against `lifecycleCleanupDeadlineAt`
82
+ * after worktreeDoneAt.
83
+ */
84
+ export declare function deriveLifecycleOuterDeadlines(input: {
85
+ admittedAt: number;
86
+ worktreePrepTimeoutMs: number;
87
+ dependencyPrepTimeoutMs: number;
88
+ requestedReadinessTimeoutMs: number;
89
+ }): LifecycleOuterDeadlines;
90
+ export declare function readPreparationTimeouts(input: Record<string, unknown>): {
91
+ ok: true;
92
+ worktreePrepTimeoutMs: number;
93
+ dependencyPrepTimeoutMs: number;
94
+ } | {
95
+ ok: false;
96
+ };
@@ -1,6 +1,16 @@
1
1
  export declare const SDK_STATE_VERSION = 1;
2
2
  export declare const SESSION_INDEX_SNAPSHOT_VERSION = 4;
3
3
  export declare const SESSION_INDEX_EVENT_VERSION = 4;
4
+ /**
5
+ * Thrown when a persisted SDK state file carries a version this build does not
6
+ * support. `assertSupportedStateVersion` fences only generic SDK state (broker
7
+ * discovery, lifecycle-ledger rows, guide cache meta) whose current format is
8
+ * exactly `SDK_STATE_VERSION`. Session-index files carry their own versions
9
+ * (see `assertSupportedSessionIndexEventVersion` and
10
+ * `assertSupportedSnapshotVersion`) and MUST NOT be validated with the generic
11
+ * guard — a supported v4 index row would crash with "maximum supported version
12
+ * is 1" (#5181).
13
+ */
4
14
  export declare class UnsupportedStateVersionError extends Error {
5
15
  readonly file: string;
6
16
  readonly version: number;
@@ -8,6 +18,13 @@ export declare class UnsupportedStateVersionError extends Error {
8
18
  readonly code = "unsupported_state_version";
9
19
  constructor(file: string, version: number, maximumSupportedVersion?: number);
10
20
  }
21
+ /**
22
+ * Generic SDK-state fence: rejects any version above `SDK_STATE_VERSION`.
23
+ * ONLY for generic state whose current format is exactly `SDK_STATE_VERSION`
24
+ * (broker discovery `broker.json`, lifecycle-ledger rows, guide cache meta).
25
+ * Never validate session-index rows or snapshots with this guard — they have
26
+ * dedicated version fences and currently accept v4 (#5181).
27
+ */
11
28
  export declare function assertSupportedStateVersion(file: string, value: unknown): void;
12
29
  /** Rejects session-index events outside the known legacy and current formats. */
13
30
  export declare function assertSupportedSessionIndexEventVersion(file: string, value: unknown): void;
@@ -47,7 +47,7 @@ export declare class DiscordNotificationDaemon {
47
47
  /** Posts a safe command outcome to the active mapped conversation. */
48
48
  postCommandResult(sessionId: string, content: string): Promise<boolean>;
49
49
  close(sessionId: string, endpointGeneration?: number): Promise<void>;
50
- recoverCleanup(sessionId: string, endpointGeneration: number): Promise<void>;
50
+ recoverCleanup(sessionId: string, endpointGeneration: number, authorityId?: string): Promise<boolean>;
51
51
  retireAttachment(sessionId: string, endpointGeneration: number): Promise<void>;
52
52
  archive(sessionId: string): Promise<void>;
53
53
  resume(sessionId: string, endpointGeneration: number, attachmentAuthorityId?: string): Promise<DiscordConversation | undefined>;
@@ -116,7 +116,7 @@ export interface SessionResumeResponseFrame {
116
116
  sessionId: string;
117
117
  mode: ResumeMode;
118
118
  }
119
- export type LifecycleErrorReason = "unauthorized" | "rate_limited" | "duplicate_conflict" | "invalid_target" | "ambiguous_target" | "spawn_failed" | "discovery_timeout" | "readiness_timeout" | "close_refused" | "not_found" | "terminal_uncertain" | "unsupported_platform";
119
+ export type LifecycleErrorReason = "unauthorized" | "rate_limited" | "duplicate_conflict" | "invalid_target" | "ambiguous_target" | "spawn_failed" | "discovery_timeout" | "readiness_timeout" | "worktree_preparation_timeout" | "dependency_preparation_timeout" | "close_refused" | "not_found" | "terminal_uncertain" | "unsupported_platform";
120
120
  export interface ResumeCandidate {
121
121
  sessionId: string;
122
122
  path?: string;
@@ -310,6 +310,8 @@ interface SessionRuntime {
310
310
  disposeGateTerminalController: () => void;
311
311
  disposeAckRecoveryParticipant: () => void;
312
312
  disposeGateEmitterListener: () => void;
313
+ /** Deregisters this session's job-fold listener (`bash_folded`). */
314
+ disposeFoldListener: () => void;
313
315
  /** Aborts and fences side turns while notification delivery is disabled. */
314
316
  disableEphemeralTurns: () => void;
315
317
  waitForGateResolutionQuiescence: () => Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import type { PromptReconciliationStatus, SdkPromptTerminalOutcome, TurnPromptReconciliation } from "../prompt-status";
2
- import type { ReceiptState } from "../receipt-state";
2
+ import { type ReceiptState } from "../receipt-state";
3
3
  import { type TurnResultContent, type TurnResultPage } from "../turn-result";
4
4
  import { type PromptCorrelation } from "./prompt-reconciliation";
5
5
  import type { DurableReconciliationRecord, ReconciliationKind, ReconciliationStore } from "./reconciliation-store";
@@ -23,7 +23,7 @@
23
23
  */
24
24
  import { PROMPT_FAILURE_CODE_MAX, sanitizePromptFailure } from "../prompt-failure";
25
25
  import type { SdkPromptTerminalOutcome } from "../prompt-status";
26
- import type { ReceiptState } from "../receipt-state";
26
+ import { type ReceiptState } from "../receipt-state";
27
27
  export { PROMPT_FAILURE_CODE_MAX, sanitizePromptFailure };
28
28
  export declare const PROMPT_RECONCILIATION_ACTIVE_CAPACITY = 128;
29
29
  export declare const PROMPT_RECONCILIATION_TERMINAL_CAPACITY = 256;
@@ -5,7 +5,7 @@ export interface SlackInboundDispatchReceipt {
5
5
  interactionId: string;
6
6
  retryKey: string;
7
7
  eventContext?: string;
8
- kind: "action" | "command";
8
+ kind: "action" | "command" | "message";
9
9
  actionId?: string;
10
10
  /** The endpoint generation and SDK effect captured before Socket Mode ACK. */
11
11
  endpointGeneration: number;
@@ -69,7 +69,7 @@ export declare class SlackNotificationDaemon {
69
69
  postCommandResult(sessionId: string, content: string): Promise<boolean>;
70
70
  resolveAction(sessionId: string, actionId: string): Promise<void>;
71
71
  close(sessionId: string, marker?: string, endpointGeneration?: number): Promise<boolean>;
72
- recoverCleanup(sessionId: string, endpointGeneration: number): Promise<void>;
72
+ recoverCleanup(sessionId: string, endpointGeneration: number, authorityId?: string): Promise<boolean>;
73
73
  retireAttachment(sessionId: string, endpointGeneration: number): Promise<void>;
74
74
  resume(sessionId: string, body: string, endpointGeneration?: number, publicationId?: string): Promise<SlackConversation>;
75
75
  findSession(sessionId: string, includeInactive: boolean): Promise<{
@@ -286,7 +286,7 @@ export declare const SDK_LIFECYCLE_ROUTER_PROTOCOL_VERSION = 1;
286
286
  * killing a session's mirroring after one transient rejection and must be
287
287
  * replaced across this upgrade.
288
288
  */
289
- export declare const DAEMON_GENERATION = 180;
289
+ export declare const DAEMON_GENERATION = 181;
290
290
  /**
291
291
  * Serving-compatibility boundary for daemon lifecycle requests. Epoch 7
292
292
  * requires durable publication receipts and acknowledged attachment dispatch,
@@ -40,24 +40,29 @@ export interface SdkSessionRowV1 {
40
40
  /** True when the same sessionId maps to more than one stateRoot (cross-repo duplicate). */
41
41
  ambiguous?: boolean;
42
42
  }
43
- export interface SdkCheckpointRecordV1 {
43
+ export interface SdkRingPositionV1 {
44
44
  revision: number;
45
45
  generation: number;
46
46
  seq: number;
47
47
  }
48
+ export interface SdkCheckpointRecordV1 extends SdkRingPositionV1 {
49
+ idle: boolean;
50
+ }
48
51
  export interface SdkRetentionGapV1 {
49
52
  code: "retention_gap";
50
53
  missing?: {
51
54
  from: number;
52
55
  to: number;
53
56
  };
54
- resync?: SdkCheckpointRecordV1;
57
+ resync?: SdkRingPositionV1;
55
58
  }
56
59
  /** One tail item: a retained transcript entry or a live event-ring event. */
57
60
  export interface SdkTailItemV1 {
58
61
  /** "transcript" for retained transcript entries, otherwise the event-ring kind. */
59
62
  kind: string;
60
63
  id?: string;
64
+ /** Durable revision at emission; (revision,generation,seq) is unique per session. generation:seq alone is revision-local. */
65
+ revision?: number;
61
66
  generation?: number;
62
67
  seq?: number;
63
68
  payload: unknown;
@@ -85,6 +90,7 @@ export declare function toRetentionGapV1(value: unknown): SdkRetentionGapV1 | un
85
90
  /** Projects a transcript entry or ring event into a tail item with dedupe keys. */
86
91
  export declare function toTailItemV1(value: unknown, fallback: {
87
92
  kind: string;
93
+ revision?: number;
88
94
  generation?: number;
89
95
  seq?: number;
90
96
  }): SdkTailItemV1;
@@ -67,7 +67,8 @@ export declare function parseSessionListScope(value: string | undefined): SdkSes
67
67
  /**
68
68
  * Resolves the list selection from `--repo` (default: process cwd) under the
69
69
  * effective scope. Outside Git, `repo`/`worktree` fail typed and actionable —
70
- * they never broaden to `all`; `cwd` remains an exact canonical match.
70
+ * they never broaden to `all`; `cwd` remains an exact canonical match, and
71
+ * `all` ignores the selection entirely so it works outside any checkout.
71
72
  */
72
73
  export declare function resolveSessionListSelection(scope: SdkSessionListScope, repoArg: string | undefined): Promise<SdkSessionListSelection>;
73
74
  /**
@@ -1,6 +1,7 @@
1
1
  import type { SdkFrame } from "./types";
2
2
  export interface EventFrame extends SdkFrame {
3
3
  type: "event";
4
+ revision?: number;
4
5
  generation: number;
5
6
  seq: number;
6
7
  }
@@ -15,6 +15,7 @@ export interface CursorEnvelope {
15
15
  issuedAt?: number;
16
16
  /** TTL metadata minted by `CursorRegistry.grant`: wall-clock ms when the cursor expires. */
17
17
  expiresAt?: number;
18
+ purpose?: "checkpoint";
18
19
  position: unknown;
19
20
  direction: string;
20
21
  pageShape: unknown;
@@ -46,6 +47,7 @@ export interface CursorQueryContext {
46
47
  resourceId?: string;
47
48
  direction: string;
48
49
  pageShape: unknown;
50
+ purpose?: "checkpoint";
49
51
  }
50
52
  export declare class CursorError extends Error {
51
53
  readonly code: "cursor_expired" | "invalid_cursor" | "invalid_input" | "resource_gone" | "snapshot_capacity_exceeded";
@@ -64,13 +66,13 @@ export declare class CursorRegistry {
64
66
  private readonly now;
65
67
  constructor(sessionToken: string | Uint8Array, revisions: RevisionStore, now?: () => number);
66
68
  grant(connectionId: string, envelope: CursorEnvelope, resourceKind: string, resourceId: string): Promise<string>;
67
- exchange(cursor: string, connectionId: string, expected: CursorQueryContext, resourceKind: string, resourceId: string): Promise<{
69
+ exchange(cursor: string, connectionId: string, expected: CursorQueryContext, _resourceKind: string, resourceId: string): Promise<{
68
70
  cursor: string;
69
71
  envelope: CursorEnvelope;
70
72
  }>;
71
73
  consume(cursor: string, connectionId: string, expected: CursorQueryContext): CursorEnvelope;
72
74
  release(cursor: string): void;
73
75
  close(): void;
74
- sweep(): void;
76
+ sweep(exceptCursor?: string, at?: number): void;
75
77
  get size(): number;
76
78
  }
@@ -105,6 +105,7 @@ export interface SdkCheckpointRecord {
105
105
  revision: number;
106
106
  generation: number;
107
107
  seq: number;
108
+ idle: boolean;
108
109
  }
109
110
  export declare function isCheckpointRecord(value: unknown): value is SdkCheckpointRecord;
110
111
  export declare class QueryHandlers {
@@ -55,6 +55,7 @@ export declare class RevisionStore {
55
55
  offset: number;
56
56
  } | undefined>;
57
57
  pin(cursorId: string, resourceKind: string, resourceId: string, id: string): Promise<void>;
58
+ transferPin(sourceCursorId: string, replacementCursorId: string): void;
58
59
  unpin(cursorId: string): void;
59
60
  sweep(): void;
60
61
  close(): Promise<void>;
@@ -1,6 +1,8 @@
1
1
  import { type Settings } from "../../config/settings";
2
2
  import type { ExtensionAPI, ExtensionContext } from "../../extensibility/extensions";
3
3
  import { type MasterRoleAttestationV2, SessionIndex, type SessionLocatorV2 } from "../broker/session-index";
4
+ import type { SdkPromptTerminalOutcome } from "../prompt-status";
5
+ import { type ReceiptState } from "../receipt-state";
4
6
  import { type TurnResultContent } from "../turn-result";
5
7
  import { SessionSdkHost, type SessionSdkHostOptions } from "./host";
6
8
  import { type SessionSurface } from "./query";
@@ -58,6 +60,8 @@ export interface SdkOnlyInvocationRecord extends InvocationCorrelation {
58
60
  code: string;
59
61
  message: string;
60
62
  };
63
+ content?: TurnResultContent;
64
+ receiptState?: Exclude<ReceiptState, "absent">;
61
65
  outcome?: unknown;
62
66
  pendingOutcome?: unknown;
63
67
  skillName?: string;
@@ -207,6 +211,8 @@ export interface CreateSdkSessionRuntimeOptions {
207
211
  onLifecycleDrainTimeoutForTests?: () => void;
208
212
  /** Test-only observation of bounded failure-diagnostic deduplication state. */
209
213
  onFailureDiagnosticKeyCountForTests?: (count: number) => void;
214
+ /** Test-only observation after a resolved invocation completion is reconciled. */
215
+ onInvocationCompletionReconciledForTests?: (kind: InvocationKind, correlation: InvocationCorrelation) => void;
210
216
  }
211
217
  export interface InvocationCorrelation {
212
218
  commandId: string;
@@ -214,6 +220,14 @@ export interface InvocationCorrelation {
214
220
  }
215
221
  export type InvocationKind = "prompt" | "skill" | "steer";
216
222
  type InvocationStatus = "accepted" | "in_flight" | "terminal_ok" | "failed" | "uncertain";
223
+ type InvocationOutcome = SdkPromptTerminalOutcome;
224
+ type InvocationOutcomeInput = {
225
+ kind: string;
226
+ reason?: unknown;
227
+ code?: unknown;
228
+ message?: unknown;
229
+ provenance?: unknown;
230
+ };
217
231
  export interface InvocationReconciliation {
218
232
  /** Shared v2 reconciliation owner; present for durable terminal admission. */
219
233
  readonly store?: SdkOnlyReconciliationStore;
@@ -224,11 +238,7 @@ export interface InvocationReconciliation {
224
238
  type: "agent_start" | "agent_end";
225
239
  content?: TurnResultContent;
226
240
  hasActivity?: boolean;
227
- outcome?: {
228
- kind: "stopped";
229
- reason: "cancelled";
230
- provenance: "client_cancel";
231
- };
241
+ outcome?: InvocationOutcome;
232
242
  } | {
233
243
  type: "agent_failed";
234
244
  error: unknown;
@@ -251,18 +261,8 @@ export interface InvocationReconciliation {
251
261
  deadlineMaxAt?: number;
252
262
  }>;
253
263
  hydrate(): Promise<void>;
254
- claimPendingOutcome(kind: InvocationKind, correlation: InvocationCorrelation, outcome: {
255
- kind: string;
256
- code: string;
257
- message: string;
258
- provenance?: string;
259
- }): Promise<unknown>;
260
- finalizeOutcome(kind: InvocationKind, correlation: InvocationCorrelation, outcome?: {
261
- kind: string;
262
- code: string;
263
- message: string;
264
- provenance?: string;
265
- }, arg4?: (() => boolean) | {
264
+ claimPendingOutcome(kind: InvocationKind, correlation: InvocationCorrelation, outcome: InvocationOutcomeInput): Promise<InvocationOutcome>;
265
+ finalizeOutcome(kind: InvocationKind, correlation: InvocationCorrelation, outcome?: InvocationOutcomeInput, arg4?: (() => boolean) | {
266
266
  code: string;
267
267
  message: string;
268
268
  }, arg5?: unknown, arg6?: {
@@ -303,6 +303,7 @@ export interface SdkSurfaceFactoryOptions {
303
303
  clientRef?: string;
304
304
  }) => unknown;
305
305
  hostTools?: boolean | (() => boolean);
306
+ getRuntimeHost?: () => SessionSdkHost | undefined;
306
307
  }
307
308
  /** Shared policy, capability, and query-surface factory for every SDK transport. */
308
309
  export interface SdkSurfaceFactory {
@@ -1,4 +1,4 @@
1
- import type { AgentSession } from "../session/agent-session";
1
+ import { type AgentSession } from "../session/agent-session";
2
2
  import { type CreateAgentSessionOptions } from "./session";
3
3
  import { SdkStartupCapability, type SdkStartupFailure, SdkStartupRollbackTracker } from "./startup-capability";
4
4
  export type CreateLifecycleAgentSessionResult = {
@@ -1,5 +1,6 @@
1
1
  import type { KindAwareReconciliation } from "./bus/kind-aware-reconciliation";
2
2
  import type { InvocationCorrelation, InvocationReconciliation } from "./host/session-runtime";
3
+ import type { SdkPromptTerminalOutcome } from "./prompt-status";
3
4
  import type { TurnResultContent } from "./turn-result";
4
5
  type DeadlineReconciliation = InvocationReconciliation | KindAwareReconciliation;
5
6
  export type PromptDeadlineOutcome = {
@@ -11,11 +12,7 @@ export type PromptDeadlineOutcome = {
11
12
  export interface PromptTerminalTransitionEvidence {
12
13
  content?: TurnResultContent;
13
14
  hasActivity?: boolean;
14
- outcome?: {
15
- kind: "stopped";
16
- reason: "cancelled";
17
- provenance: "client_cancel";
18
- };
15
+ outcome?: SdkPromptTerminalOutcome;
19
16
  }
20
17
  export declare class PromptDeadlineManager {
21
18
  #private;
@@ -14,4 +14,6 @@ export interface TerminalReceiptState {
14
14
  }
15
15
  export declare function reportableReceipt({ text, artifactPath }: ReceiptSource): boolean;
16
16
  export declare function receiptStateForTerminal(source: ReceiptSource): Extract<ReceiptState, "present" | "missing">;
17
+ /** Terminal receipt evidence is monotonic: present > missing > unknown. */
18
+ export declare function reduceReceiptState(existing: Exclude<ReceiptState, "absent"> | undefined, incoming: Exclude<ReceiptState, "absent"> | undefined): Exclude<ReceiptState, "absent"> | undefined;
17
19
  export declare function reduceTerminalReceiptState(input: TerminalReceiptInput): TerminalReceiptState;
@@ -117,10 +117,12 @@ export interface SessionRouterClient {
117
117
  send(frame: Record<string, unknown>): void;
118
118
  }
119
119
  /** One frame after the caller's envelope/payload identity correlation. */
120
+ /** One frame after the caller's envelope/payload identity correlation. */
120
121
  export interface SessionRouterFrame {
121
122
  readonly body: Record<string, unknown>;
122
123
  readonly name: string | undefined;
123
124
  readonly sessionId: string | undefined;
125
+ readonly revision?: number;
124
126
  readonly generation: number | undefined;
125
127
  readonly commandId?: string;
126
128
  readonly turnId?: string;
@@ -144,6 +146,8 @@ export interface SessionRouterDeps {
144
146
  onAttachment?: (attachment: SessionAttachment) => Promise<void> | void;
145
147
  /** Called only after the opaque capability becomes externally current. */
146
148
  onAttachmentReady?: (attachment: SessionAttachment) => Promise<void> | void;
149
+ /** Called before deferred replay may perform provider-facing mutations. */
150
+ onReplayReady?: () => Promise<void> | void;
147
151
  /** Called when the Broker index no longer reports an attached session as live. */
148
152
  onSessionRemoved?: (attachment: SessionAttachment, reason?: "removed" | "replaced" | "replaced_same_generation") => Promise<void> | void;
149
153
  /** Narrow provider surface for notification consumers such as Telegram. */
@@ -22,6 +22,7 @@ export interface TurnResultError {
22
22
  code: string;
23
23
  message: string;
24
24
  }
25
+ export type TurnResultReceiptState = "absent" | "present" | "missing" | "unknown";
25
26
  export interface TurnResultPage {
26
27
  status: TurnResultStatus;
27
28
  kind?: "prompt" | "skill";
@@ -31,7 +32,12 @@ export interface TurnResultPage {
31
32
  acceptedAt?: number;
32
33
  startedAt?: number;
33
34
  terminalAt?: number;
35
+ receiptState?: TurnResultReceiptState;
36
+ outcome?: unknown;
34
37
  content?: TurnResultContent;
35
38
  error?: TurnResultError;
36
39
  }
37
40
  export declare function sanitizeTurnResultContent(text: unknown): TurnResultContent | undefined;
41
+ export declare function reportableTurnResultContent(content: TurnResultContent | undefined): boolean;
42
+ /** First reportable invocation-owned content wins; blank evidence remains replaceable. */
43
+ export declare function reduceTurnResultContent(existing: TurnResultContent | undefined, incoming: TurnResultContent | undefined): TurnResultContent | undefined;