@gajae-code/coding-agent 0.16.4 → 0.16.6

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 (198) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/types/capability/types.d.ts +4 -0
  3. package/dist/types/cli/customize-doctor.d.ts +22 -0
  4. package/dist/types/config/file-lock.d.ts +31 -3
  5. package/dist/types/coordinator-mcp/question-state.d.ts +7 -0
  6. package/dist/types/coordinator-mcp/server.d.ts +7 -0
  7. package/dist/types/discovery/helpers.d.ts +33 -0
  8. package/dist/types/exec/bash-executor.d.ts +17 -1
  9. package/dist/types/exec/bash-shell-guardian.d.ts +15 -0
  10. package/dist/types/exec/bash-shell-runtime-entry.d.ts +2 -0
  11. package/dist/types/exec/bash-shell-signals.d.ts +2 -0
  12. package/dist/types/exec/bash-shell-supervisor-entry.d.ts +1 -0
  13. package/dist/types/exec/bash-shell-supervisor.d.ts +10 -0
  14. package/dist/types/exec/bash-shell-worker-entry.d.ts +2 -0
  15. package/dist/types/exec/bash-shell-worker-protocol.d.ts +63 -0
  16. package/dist/types/exec/bash-shell-worker.d.ts +1 -0
  17. package/dist/types/exec/isolated-shell.d.ts +19 -0
  18. package/dist/types/extensibility/extensions/function-hooks-internal.d.ts +9 -0
  19. package/dist/types/extensibility/extensions/function-hooks.d.ts +169 -0
  20. package/dist/types/extensibility/extensions/index.d.ts +1 -0
  21. package/dist/types/extensibility/extensions/runner.d.ts +46 -6
  22. package/dist/types/extensibility/extensions/types.d.ts +16 -0
  23. package/dist/types/extensibility/extensions/wrapper.d.ts +3 -1
  24. package/dist/types/extensibility/gjc-plugins/constrained-hooks.d.ts +35 -2
  25. package/dist/types/extensibility/gjc-plugins/types.d.ts +25 -0
  26. package/dist/types/extensibility/hooks/types.d.ts +4 -0
  27. package/dist/types/extensibility/runtime-skill-discovery.d.ts +4 -1
  28. package/dist/types/extensibility/skill-management.d.ts +9 -4
  29. package/dist/types/extensibility/skills.d.ts +2 -0
  30. package/dist/types/gjc-runtime/empty-delete-gc.d.ts +4 -1
  31. package/dist/types/gjc-runtime/linux-proc.d.ts +2 -0
  32. package/dist/types/gjc-runtime/session-state-lock.d.ts +12 -0
  33. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +41 -3
  34. package/dist/types/gjc-runtime/ultragoal-succession.d.ts +251 -0
  35. package/dist/types/modes/components/bash-execution.d.ts +1 -0
  36. package/dist/types/modes/components/execution-shared.d.ts +1 -0
  37. package/dist/types/modes/interactive-mode.d.ts +2 -0
  38. package/dist/types/modes/types.d.ts +6 -0
  39. package/dist/types/sdk/broker/ensure.d.ts +32 -0
  40. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +0 -1
  41. package/dist/types/sdk/broker/lifecycle.d.ts +6 -0
  42. package/dist/types/sdk/broker/startup-failure.d.ts +4 -1
  43. package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -0
  44. package/dist/types/sdk/bus/chat-effect-journal.d.ts +17 -2
  45. package/dist/types/sdk/bus/conversation-store.d.ts +11 -0
  46. package/dist/types/sdk/bus/lifecycle-commands.d.ts +8 -8
  47. package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
  48. package/dist/types/sdk/bus/topic-registry.d.ts +8 -0
  49. package/dist/types/sdk/client/client.d.ts +6 -0
  50. package/dist/types/sdk/host/host.d.ts +3 -1
  51. package/dist/types/sdk/host/session-runtime.d.ts +4 -2
  52. package/dist/types/sdk/lifecycle/service.d.ts +1 -0
  53. package/dist/types/sdk/router/session-router.d.ts +10 -2
  54. package/dist/types/sdk/session.d.ts +5 -1
  55. package/dist/types/session/agent-session.d.ts +2 -0
  56. package/dist/types/session/fallback-chain-controller.d.ts +15 -0
  57. package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
  58. package/dist/types/session/messages.d.ts +1 -0
  59. package/dist/types/session/session-manager.d.ts +3 -1
  60. package/dist/types/setup/paseo/announce.d.ts +4 -3
  61. package/dist/types/skill-state/canonical-skills.d.ts +4 -0
  62. package/dist/types/system-prompt.d.ts +8 -0
  63. package/dist/types/task/executor.d.ts +3 -0
  64. package/dist/types/tools/bash.d.ts +1 -0
  65. package/dist/types/tools/github-cache.d.ts +2 -1
  66. package/dist/types/tools/index.d.ts +2 -0
  67. package/package.json +9 -7
  68. package/scripts/generate-sdk-operation-inventory.ts +2 -0
  69. package/src/capability/index.ts +14 -2
  70. package/src/capability/types.ts +4 -0
  71. package/src/cli/customize-doctor.ts +155 -12
  72. package/src/cli.ts +22 -0
  73. package/src/commands/sdk.ts +74 -31
  74. package/src/config/file-lock-gc.ts +40 -2
  75. package/src/config/file-lock.ts +198 -14
  76. package/src/config/model-preset-registry.ts +115 -16
  77. package/src/config/model-registry.ts +16 -12
  78. package/src/coordinator-mcp/question-state.ts +33 -2
  79. package/src/coordinator-mcp/server.ts +477 -101
  80. package/src/crash/sanitize.ts +1 -1
  81. package/src/defaults/gjc/skills/ultragoal/SKILL.md +22 -0
  82. package/src/discovery/builtin.ts +50 -62
  83. package/src/discovery/helpers.ts +297 -32
  84. package/src/exec/bash-executor.ts +330 -50
  85. package/src/exec/bash-shell-guardian.ts +388 -0
  86. package/src/exec/bash-shell-runtime-entry.ts +5 -0
  87. package/src/exec/bash-shell-signals.ts +29 -0
  88. package/src/exec/bash-shell-supervisor-entry.ts +3 -0
  89. package/src/exec/bash-shell-supervisor.ts +359 -0
  90. package/src/exec/bash-shell-worker-entry.ts +5 -0
  91. package/src/exec/bash-shell-worker-protocol.ts +36 -0
  92. package/src/exec/bash-shell-worker.ts +116 -0
  93. package/src/exec/isolated-shell.ts +393 -0
  94. package/src/extensibility/extensions/function-hooks-internal.ts +73 -0
  95. package/src/extensibility/extensions/function-hooks.ts +959 -0
  96. package/src/extensibility/extensions/index.ts +22 -0
  97. package/src/extensibility/extensions/loader.ts +53 -2
  98. package/src/extensibility/extensions/runner.ts +895 -264
  99. package/src/extensibility/extensions/types.ts +42 -0
  100. package/src/extensibility/extensions/wrapper.ts +56 -15
  101. package/src/extensibility/gjc-plugins/compiler.ts +20 -2
  102. package/src/extensibility/gjc-plugins/constrained-hooks.ts +321 -23
  103. package/src/extensibility/gjc-plugins/registry.ts +113 -1
  104. package/src/extensibility/gjc-plugins/runtime-quarantine.ts +20 -2
  105. package/src/extensibility/gjc-plugins/schema.ts +121 -4
  106. package/src/extensibility/gjc-plugins/types.ts +25 -0
  107. package/src/extensibility/hooks/loader.ts +133 -16
  108. package/src/extensibility/hooks/types.ts +28 -0
  109. package/src/extensibility/runtime-skill-discovery.ts +80 -47
  110. package/src/extensibility/skill-management.ts +200 -52
  111. package/src/extensibility/skills.ts +29 -9
  112. package/src/gjc-runtime/empty-delete-gc.ts +94 -4
  113. package/src/gjc-runtime/gc-runtime.ts +29 -0
  114. package/src/gjc-runtime/linux-proc.ts +14 -0
  115. package/src/gjc-runtime/session-state-lock.ts +51 -8
  116. package/src/gjc-runtime/session-state-sidecar.ts +27 -11
  117. package/src/gjc-runtime/state-writer.ts +30 -29
  118. package/src/gjc-runtime/ultragoal-runtime.ts +189 -47
  119. package/src/gjc-runtime/ultragoal-succession.ts +1667 -0
  120. package/src/gjc-runtime/workflow-manifest.generated.json +52 -1
  121. package/src/gjc-runtime/workflow-manifest.ts +16 -0
  122. package/src/harness-control-plane/session-lease.ts +2 -2
  123. package/src/internal-urls/docs-index.generated.ts +6 -6
  124. package/src/lsp/config.ts +10 -3
  125. package/src/lsp/index.ts +1 -1
  126. package/src/lsp/path-trust.ts +69 -14
  127. package/src/main.ts +6 -1
  128. package/src/modes/acp/acp-agent.ts +16 -3
  129. package/src/modes/components/bash-execution.ts +4 -1
  130. package/src/modes/components/execution-shared.ts +4 -1
  131. package/src/modes/components/session-observer-overlay.ts +1 -1
  132. package/src/modes/components/tool-status-header.ts +3 -1
  133. package/src/modes/controllers/command-controller.ts +1 -0
  134. package/src/modes/controllers/event-controller.ts +3 -2
  135. package/src/modes/controllers/extension-ui-controller.ts +1 -0
  136. package/src/modes/controllers/input-controller.ts +6 -3
  137. package/src/modes/interactive-mode.ts +6 -5
  138. package/src/modes/print-mode.ts +5 -1
  139. package/src/modes/prompt-action-autocomplete.ts +54 -27
  140. package/src/modes/runtime-init.ts +2 -0
  141. package/src/modes/types.ts +16 -3
  142. package/src/modes/utils/ui-helpers.ts +1 -0
  143. package/src/prompts/tools/subagent.md +1 -0
  144. package/src/runtime-mcp/manager.ts +20 -2
  145. package/src/runtime-mcp/pool.test.ts +20 -11
  146. package/src/sdk/broker/broker.ts +119 -28
  147. package/src/sdk/broker/ensure.ts +248 -41
  148. package/src/sdk/broker/lifecycle-ledger.ts +7 -17
  149. package/src/sdk/broker/lifecycle.ts +56 -6
  150. package/src/sdk/broker/startup-failure.ts +15 -6
  151. package/src/sdk/bus/chat-daemon-control.ts +3 -1
  152. package/src/sdk/bus/chat-daemon-runtime.ts +35 -5
  153. package/src/sdk/bus/chat-effect-journal.ts +132 -7
  154. package/src/sdk/bus/conversation-store.ts +29 -0
  155. package/src/sdk/bus/lifecycle-commands.ts +17 -11
  156. package/src/sdk/bus/slack-conversation.ts +1 -0
  157. package/src/sdk/bus/slack-daemon.ts +387 -48
  158. package/src/sdk/bus/telegram-daemon.ts +16 -2
  159. package/src/sdk/bus/topic-registry.ts +19 -0
  160. package/src/sdk/cli/master-cli.ts +1 -1
  161. package/src/sdk/cli/session-cli.ts +2 -2
  162. package/src/sdk/client/client.ts +66 -17
  163. package/src/sdk/host/host.ts +29 -9
  164. package/src/sdk/host/query/revision-store.ts +19 -13
  165. package/src/sdk/host/reverse-leases.ts +7 -4
  166. package/src/sdk/host/session-runtime.test.ts +50 -8
  167. package/src/sdk/host/session-runtime.ts +158 -51
  168. package/src/sdk/lifecycle/service.ts +4 -0
  169. package/src/sdk/protocol/operation-inventory.generated.json +11 -0
  170. package/src/sdk/router/session-router.ts +89 -38
  171. package/src/sdk/session.ts +155 -26
  172. package/src/sdk/transport/relay.ts +35 -13
  173. package/src/session/agent-session.ts +117 -52
  174. package/src/session/fallback-chain-controller.ts +38 -0
  175. package/src/session/internal/managed-session-storage.ts +19 -5
  176. package/src/session/messages.ts +5 -0
  177. package/src/session/session-manager.ts +29 -5
  178. package/src/session-import/redact.ts +5 -1
  179. package/src/setup/paseo/announce.ts +49 -43
  180. package/src/setup/paseo/setup-deps.ts +1 -1
  181. package/src/skill-state/canonical-skills.ts +12 -0
  182. package/src/skills/skills.test.ts +41 -21
  183. package/src/system-prompt.ts +25 -3
  184. package/src/task/executor.ts +5 -0
  185. package/src/task/index.ts +4 -0
  186. package/src/tools/bash.ts +28 -11
  187. package/src/tools/gh.ts +26 -3
  188. package/src/tools/github-cache.ts +68 -16
  189. package/src/tools/index.ts +2 -0
  190. package/src/tools/job.ts +13 -2
  191. package/src/tools/read.ts +14 -2
  192. package/src/tools/render-utils.ts +1 -3
  193. package/src/tools/resource-gc.ts +28 -8
  194. package/src/tools/skill-discovery.ts +5 -0
  195. package/src/tools/skill.ts +15 -0
  196. package/src/tools/subagent.ts +3 -2
  197. package/src/tools/tool-catalog.generated.ts +2 -2
  198. package/src/tools/ultragoal-ask-guard.ts +2 -2
@@ -0,0 +1,251 @@
1
+ import { type RepositoryBinding } from "./repository-binding";
2
+ import { type UltragoalCommandResult, type UltragoalGjcGoalMode, type UltragoalGoalStatus, type UltragoalPlan } from "./ultragoal-runtime";
3
+ export declare const ULTRAGOAL_SUCCESSION_OPERATION_SCHEMA: "gjc.ultragoal_succession_operation.v1";
4
+ export declare const ULTRAGOAL_SUCCESSION_OFFER_SCHEMA: "gjc.ultragoal_succession_offer.v1";
5
+ export declare const ULTRAGOAL_SUCCESSION_FENCE_SCHEMA: "gjc.ultragoal_succession_fence.v1";
6
+ export declare const ULTRAGOAL_SUCCESSION_ADOPTION_SCHEMA: "gjc.ultragoal_succession_adoption.v1";
7
+ export declare const ULTRAGOAL_SUCCESSION_CLAIM_SCHEMA: "gjc.ultragoal_succession_claim.v1";
8
+ export declare const SUCCESSION_ADOPTED_EVENT: "succession_adopted";
9
+ export type UltragoalSuccessionErrorCode = "source_plan_missing" | "source_not_quiescent" | "invalid_selection" | "unsafe_target" | "authorization_required" | "divergent_operation" | "goal_handed_off" | "adoption_unpublished" | "publication_conflict" | "published_plan_missing" | "fence_missing" | "fence_mismatch" | "source_changed" | "offer_untrusted" | "offer_path_escape" | "target_mismatch" | "target_occupied" | "duplicate_adoption";
10
+ export declare class UltragoalSuccessionError extends Error {
11
+ readonly code: UltragoalSuccessionErrorCode;
12
+ constructor(code: UltragoalSuccessionErrorCode, message: string);
13
+ }
14
+ export interface UltragoalSuccessionArtifactDigests {
15
+ briefSha256: string;
16
+ goalsSha256: string;
17
+ ledgerSha256: string;
18
+ }
19
+ export interface UltragoalSuccessionCarriedGoal {
20
+ sourceGoalId: string;
21
+ title: string;
22
+ /** The source objective, verbatim. Never a summary. */
23
+ objective: string;
24
+ /** Historical provenance only; never a receipt. */
25
+ sourceStatusAtOffer: UltragoalGoalStatus;
26
+ unresolvedObligations: string[];
27
+ /**
28
+ * Source dependency groups this goal belonged to, carried as an obligation
29
+ * with explicit id mapping. The group's *metadata* (batch hashes, receipts)
30
+ * is deliberately not carried — that would be inherited validation authority.
31
+ * What is carried is the requirement that these goals be validated together.
32
+ */
33
+ dependencyGroups: UltragoalSuccessionDependencyGroup[];
34
+ }
35
+ export type UltragoalSuccessionDependencyGroupKind = "validation-batch" | "review-blocker";
36
+ export interface UltragoalSuccessionDependencyGroup {
37
+ kind: UltragoalSuccessionDependencyGroupKind;
38
+ groupId: string;
39
+ memberSourceGoalIds: string[];
40
+ /** For validation batches: the source goal that closed the batch. */
41
+ finalSourceGoalId?: string;
42
+ }
43
+ /**
44
+ * Per-selected-goal snapshot of exactly what was offered.
45
+ *
46
+ * Admission compares *this*, not whole-file equality. The fence deliberately
47
+ * leaves unselected goals schedulable, so ordinary source progress moves
48
+ * `goals.json`/`ledger.jsonl` bytes; requiring whole-file equality would
49
+ * permanently strand the selected work through drift that never touched it
50
+ * (issue #5353 review item 3). Whole-file digests remain recorded as provenance
51
+ * and any observed drift is written into the adoption record.
52
+ */
53
+ export interface UltragoalSuccessionSelectionSnapshot {
54
+ /** The brief carries global constraints, so it must not change. */
55
+ briefSha256: string;
56
+ goals: Array<{
57
+ sourceGoalId: string;
58
+ recordSha256: string;
59
+ obligationsSha256: string;
60
+ }>;
61
+ snapshotSha256: string;
62
+ }
63
+ export interface UltragoalSuccessionOffer {
64
+ schema: typeof ULTRAGOAL_SUCCESSION_OFFER_SCHEMA;
65
+ operationId: string;
66
+ createdAt: string;
67
+ source: {
68
+ sessionId: string;
69
+ repository: RepositoryBinding;
70
+ /** Whole-file digests at offer time. Provenance; not the admission test. */
71
+ artifacts: UltragoalSuccessionArtifactDigests;
72
+ /** The authoritative admission test for "did the offered work change". */
73
+ selectionSnapshot: UltragoalSuccessionSelectionSnapshot;
74
+ gjcGoalMode: UltragoalGjcGoalMode;
75
+ };
76
+ target: {
77
+ repository: RepositoryBinding;
78
+ };
79
+ selection: {
80
+ goalIds: string[];
81
+ };
82
+ carryover: {
83
+ /** The source brief, verbatim. */
84
+ brief: string;
85
+ goals: UltragoalSuccessionCarriedGoal[];
86
+ };
87
+ authorization: {
88
+ statement: string;
89
+ authorizedBy: string;
90
+ };
91
+ provenanceNotice: string;
92
+ }
93
+ export interface UltragoalSuccessionFence {
94
+ schema: typeof ULTRAGOAL_SUCCESSION_FENCE_SCHEMA;
95
+ operationId: string;
96
+ createdAt: string;
97
+ sourceSessionId: string;
98
+ sourceRepository: RepositoryBinding;
99
+ targetRepository: RepositoryBinding;
100
+ selectedGoalIds: string[];
101
+ sourceArtifacts: UltragoalSuccessionArtifactDigests;
102
+ offerPath: string;
103
+ offerSha256: string;
104
+ }
105
+ export interface UltragoalSuccessionGoalMapping {
106
+ sourceGoalId: string;
107
+ targetGoalId: string;
108
+ }
109
+ export interface UltragoalSuccessionAdoption {
110
+ schema: typeof ULTRAGOAL_SUCCESSION_ADOPTION_SCHEMA;
111
+ operationId: string;
112
+ status: "pending" | "published";
113
+ claimedAt: string;
114
+ publishedAt?: string;
115
+ targetSessionId: string;
116
+ targetRepository: RepositoryBinding;
117
+ source: {
118
+ sessionId: string;
119
+ repository: RepositoryBinding;
120
+ artifacts: UltragoalSuccessionArtifactDigests;
121
+ /** Whole-file digests observed at adoption; may differ from the offer. */
122
+ artifactsAtAdoption: UltragoalSuccessionArtifactDigests;
123
+ /** Whole-file drift on goals the offer did not select, recorded honestly. */
124
+ unselectedDrift: string[];
125
+ verifiedAt: string;
126
+ };
127
+ goalMap: UltragoalSuccessionGoalMapping[];
128
+ /**
129
+ * Content digest of the plan this operation is entitled to publish, recorded
130
+ * before publication. A pending replay may only proceed when the target plan
131
+ * is absent or matches this exactly; anything else is someone else's work.
132
+ */
133
+ expectedPlanDigest: string;
134
+ /** Pinned so the published plan is a deterministic function of the claim. */
135
+ plannedAt: string;
136
+ offerPath: string;
137
+ offerSha256: string;
138
+ fencePath: string;
139
+ claimPath: string;
140
+ authorization: {
141
+ statement: string;
142
+ authorizedBy: string;
143
+ };
144
+ provenanceNotice: string;
145
+ }
146
+ /**
147
+ * Repository-wide adoption claim.
148
+ *
149
+ * The session-scoped adoption record cannot be the exclusion primitive: two
150
+ * simultaneous sessions in one repository each create their own file and both
151
+ * win. This claim is a single O_EXCL file per operation for the whole
152
+ * repository, so exclusion is atomic rather than scan-then-write.
153
+ */
154
+ export interface UltragoalSuccessionRepositoryClaim {
155
+ schema: typeof ULTRAGOAL_SUCCESSION_CLAIM_SCHEMA;
156
+ operationId: string;
157
+ targetSessionId: string;
158
+ targetWorktreeRoot: string;
159
+ targetCommonDir: string | null;
160
+ claimedAt: string;
161
+ }
162
+ export declare function ultragoalSuccessionDir(cwd: string, sessionId: string): string;
163
+ export declare function ultragoalSuccessionFencePath(cwd: string, sessionId: string): string;
164
+ export declare function ultragoalSuccessionAdoptionPath(cwd: string, sessionId: string): string;
165
+ export declare function ultragoalSuccessionOfferPath(cwd: string, sessionId: string, operationId: string): string;
166
+ /**
167
+ * Repository-wide (deliberately NOT session-scoped) adoption claim.
168
+ *
169
+ * Session directories cannot express "this repository has already adopted this
170
+ * operation", so the exclusion primitive lives beside them under the shared
171
+ * ultragoal root that `getUltragoalPaths` already uses for session-less state.
172
+ */
173
+ export declare function ultragoalSuccessionClaimPath(cwd: string, operationId: string): string;
174
+ /** Read the durable outgoing ownership fence for a source session, if any. */
175
+ export declare function readUltragoalSuccessionFence(cwd: string, sessionId: string): Promise<UltragoalSuccessionFence | null>;
176
+ /** Read the durable adoption claim for a target session, if any. */
177
+ export declare function readUltragoalSuccessionAdoption(cwd: string, sessionId: string): Promise<UltragoalSuccessionAdoption | null>;
178
+ /**
179
+ * Source admission guard: a goal that has been handed off to a successor run is
180
+ * no longer this run's to schedule or checkpoint.
181
+ *
182
+ * Goals outside the fenced selection stay fully schedulable — the fence defines
183
+ * one owner per goal, not a freeze of the whole source run.
184
+ */
185
+ export declare function assertUltragoalGoalNotFenced(cwd: string, sessionId: string | null | undefined, goalId: string): Promise<void>;
186
+ /**
187
+ * Target admission guard: an adoption that has not finished publishing does not
188
+ * yet own anything.
189
+ *
190
+ * Publication writes `goals.json` before it marks the claim published, so a
191
+ * crash leaves a *visible plan with an unpublished claim*. A visible plan is not
192
+ * admission evidence — the claim is. Without this, the target executes goals
193
+ * whose adoption was never completed, and the run's own completion receipts
194
+ * would rest on a transaction that never committed.
195
+ *
196
+ * Callers must invoke this before any mutation so a refusal leaves `goals.json`
197
+ * and `ledger.jsonl` untouched.
198
+ */
199
+ export declare function assertUltragoalAdoptionPublished(cwd: string, sessionId: string | null | undefined): Promise<void>;
200
+ export interface UltragoalSuccessionOfferInput {
201
+ cwd: string;
202
+ sessionId?: string | null;
203
+ targetRepositoryPath: string;
204
+ goalIds: readonly string[];
205
+ authorization: string;
206
+ authorizedBy: string;
207
+ }
208
+ export interface UltragoalSuccessionOfferResult {
209
+ operationId: string;
210
+ offerPath: string;
211
+ fencePath: string;
212
+ offer: UltragoalSuccessionOffer;
213
+ /** True when an identical prior operation was reconciled instead of re-recorded. */
214
+ reconciled: boolean;
215
+ }
216
+ /**
217
+ * Record an explicit successor offer and fence the selected goals off from the
218
+ * source run. Writes nothing to the source brief, goals or ledger.
219
+ */
220
+ export declare function offerUltragoalSuccession(input: UltragoalSuccessionOfferInput): Promise<UltragoalSuccessionOfferResult>;
221
+ export interface UltragoalSuccessionAdoptInput {
222
+ cwd: string;
223
+ sessionId?: string | null;
224
+ offerPath: string;
225
+ gjcGoalMode?: UltragoalGjcGoalMode;
226
+ }
227
+ export interface UltragoalSuccessionAdoptResult {
228
+ operationId: string;
229
+ adoptionPath: string;
230
+ plan: UltragoalPlan;
231
+ goalMap: UltragoalSuccessionGoalMapping[];
232
+ reconciled: boolean;
233
+ }
234
+ /**
235
+ * Adopt an explicit successor offer into this repository/session.
236
+ *
237
+ * Fails closed on a forged or stale offer, a changed source, a missing source
238
+ * fence, an unnamed target, an occupied target, and any duplicate or divergent
239
+ * adoption anywhere in this repository. A retry reconciles the exact recorded
240
+ * operation or fails closed; it never resumes a different one.
241
+ */
242
+ export declare function adoptUltragoalSuccession(input: UltragoalSuccessionAdoptInput): Promise<UltragoalSuccessionAdoptResult>;
243
+ /**
244
+ * `gjc ultragoal succession <offer|adopt|status>`.
245
+ *
246
+ * Kept out of `RECONCILE_COMMANDS` on purpose: the reconcile pass appends a
247
+ * `reconcile_failed` ledger row on failure, which would move the very source
248
+ * digests this feature records. The target's workflow state and HUD reconcile on
249
+ * the next ordinary `gjc ultragoal status`.
250
+ */
251
+ export declare function runUltragoalSuccessionCommand(args: readonly string[], cwd: string): Promise<UltragoalCommandResult>;
@@ -15,6 +15,7 @@ export declare class BashExecutionComponent extends Container {
15
15
  appendOutput(chunk: string): void;
16
16
  setComplete(exitCode: number | undefined, cancelled: boolean, options?: {
17
17
  output?: string;
18
+ signal?: string;
18
19
  truncation?: TruncationMeta;
19
20
  }): void;
20
21
  render(width: number): string[];
@@ -34,6 +34,7 @@ export declare function createCollapsedPreview(previewText: string, previewLines
34
34
  export declare function buildStatusFooter(opts: {
35
35
  status: ExecutionStatus;
36
36
  exitCode: number | undefined;
37
+ signal?: string;
37
38
  truncation: TruncationMeta | undefined;
38
39
  hiddenLineCount: number;
39
40
  /** Suppress the "… N more lines" hint (used when sixel passthrough renders the full output). */
@@ -198,6 +198,8 @@ export declare class InteractiveMode implements InteractiveModeContext {
198
198
  beginOAuthUrlForCopy(url: string): () => void;
199
199
  hasOAuthUrlForCopy(): boolean;
200
200
  copyOAuthUrl(): Promise<void>;
201
+ /** Clear the status display without settling the foreground run during maintenance/retry. */
202
+ clearLoadingAnimation(): void;
201
203
  syncActivityIndicator(): void;
202
204
  ensureLoadingAnimation(): void;
203
205
  stopLoadingAnimation(options?: ActivityIndicatorStopOptions): void;
@@ -57,6 +57,11 @@ export type ActivityIndicatorStopOptions = Readonly<{
57
57
  /** The terminal event is authoritative even if the session's streaming flag has not settled yet. */
58
58
  foregroundSettled?: boolean;
59
59
  }>;
60
+ export declare function clearInteractiveActivityIndicator(ctx: {
61
+ loadingAnimation?: Loader;
62
+ statusContainer?: PartialActivityStatusContainer;
63
+ clearLoadingAnimation?: () => void;
64
+ }): void;
60
65
  export declare function stopInteractiveActivityIndicator(ctx: {
61
66
  loadingAnimation?: Loader;
62
67
  statusContainer?: PartialActivityStatusContainer;
@@ -190,6 +195,7 @@ export interface InteractiveModeContext {
190
195
  setWorkingMessage(message?: string): void;
191
196
  applyPendingWorkingMessage(): void;
192
197
  ensureLoadingAnimation(): void;
198
+ clearLoadingAnimation(): void;
193
199
  syncActivityIndicator(): void;
194
200
  suspendActivityIndicator(): () => void;
195
201
  stopLoadingAnimation(options?: ActivityIndicatorStopOptions): void;
@@ -1,7 +1,9 @@
1
1
  import { type ChildProcess } from "node:child_process";
2
2
  import type { FileHandle } from "node:fs/promises";
3
+ import { type FileLockOptions } from "../../config/file-lock";
3
4
  import { type BrokerDiscovery } from "./discovery";
4
5
  import { type SdkInternalSpawnCommand } from "./runtime";
6
+ export declare function isBrokerGenerationCompatible(discovery: BrokerDiscovery | null): boolean;
5
7
  export interface EnsureBrokerSettings {
6
8
  agentDir: string;
7
9
  heartbeatTtlMs?: number;
@@ -12,6 +14,27 @@ export interface EnsureBrokerSettings {
12
14
  */
13
15
  env?: NodeJS.ProcessEnv;
14
16
  }
17
+ type SpawnLockOptions = Pick<FileLockOptions, "retries" | "retryDelayMs" | "signal">;
18
+ declare function readBrokerDiscoveryBeforeDeadline(agentDir: string, heartbeatTtlMs: number | undefined, deadline: number): Promise<BrokerDiscovery | null>;
19
+ /**
20
+ * Cross-process single-flight for the detached broker spawn (#5198).
21
+ *
22
+ * `ensureInFlight` only dedupes within one process. Every CLI invocation is
23
+ * its own process, so N concurrent invocations that all miss discovery each
24
+ * spawn a broker; the losers of the runtime's ownership lock then leave
25
+ * quarantine tombstones behind and the next start fails with
26
+ * `quarantine_collision`. The spawn itself must be exclusive across process
27
+ * death and PID reuse, so it uses the shared identity-bound file-lock protocol:
28
+ * complete owner metadata is published atomically, stale removal is bound to
29
+ * the exact directory generation, and ownership includes the OS incarnation.
30
+ */
31
+ declare function acquireSpawnLock(agentDir: string, options?: SpawnLockOptions): Promise<() => Promise<void>>;
32
+ /**
33
+ * Child-owned fence for the interval from bootstrap through discovery publication.
34
+ * The parent-held spawn lock prevents ordinary stampedes; this second fence keeps
35
+ * startup single-flight if that detached child's launcher dies and its lock is reclaimed.
36
+ */
37
+ export declare function withBrokerStartupLock<T>(agentDir: string, operation: (deadline: number) => Promise<T>): Promise<T>;
15
38
  /**
16
39
  * Tail of the detached broker's stderr folded into a discovery failure.
17
40
  *
@@ -62,6 +85,12 @@ interface ReapTiming {
62
85
  killVerifyMs: number;
63
86
  }
64
87
  type BrokerOwnerIdentity = Pick<BrokerDiscovery, "ownerId" | "pid" | "incarnation">;
88
+ /** Start client teardown, but never await it past the retirement operation's absolute deadline. */
89
+ export declare function closeBrokerClientBeforeDeadline(client: {
90
+ close(): Promise<void>;
91
+ }, deadline: number): Promise<void>;
92
+ /** Reconcile an observed broker generation before entering a startup critical section. */
93
+ export declare function reconcileBrokerGenerationForStartup(settings: EnsureBrokerSettings, deadline?: number): Promise<BrokerDiscovery | undefined>;
65
94
  /** Starts the detached broker entrypoint when discovery has no live owner. */
66
95
  export declare function ensureBroker(settings: EnsureBrokerSettings): Promise<BrokerDiscovery>;
67
96
  /** Starts one fresh fixture broker and returns its sole exact-child close lease. */
@@ -73,6 +102,9 @@ export declare function startFixtureBrokerWithLeaseForTest(settings: EnsureBroke
73
102
  */
74
103
  export declare function startFixtureBrokerCommandWithLeaseForTest(command: FixtureBrokerCommand): StartedFixtureBrokerCommand;
75
104
  /** Test hook: returns a stop handle for the detached broker this process spawned. */
105
+ export declare const acquireSpawnLockForTest: typeof acquireSpawnLock;
106
+ /** Test hook: proves discovery reads honor their enclosing absolute deadline. */
107
+ export declare const readBrokerDiscoveryBeforeDeadlineForTest: typeof readBrokerDiscoveryBeforeDeadline;
76
108
  export declare function brokerOwnerForTest(agentDir: string): BrokerOwner | undefined;
77
109
  /** Test hook: verifies the complete broker owner identity used during stale retirement. */
78
110
  export declare function brokerOwnerIdentityMatchesForTest(left: BrokerOwnerIdentity | null, right: BrokerOwnerIdentity): boolean;
@@ -78,7 +78,6 @@ export interface LifecycleLedgerEntry {
78
78
  unresolvedCleanupResponseDigest?: string;
79
79
  uncertainCleanupSessionId?: string;
80
80
  uncertainCleanupSessionIds?: string[];
81
- uncertainCleanupAllSessions?: true;
82
81
  ts: number;
83
82
  }
84
83
  export type BeginResult = {
@@ -173,14 +173,20 @@ export declare function observeProcessForTest(pid: number, expectedIncarnation:
173
173
  * deliberately left untouched.
174
174
  */
175
175
  export declare function reapDeadLifecycleMarkers(root: string, limit?: number): Promise<number>;
176
+ export declare function writeEffectMarker(root: string, id: string, marker: EffectMarker): Promise<void>;
176
177
  /** The child writes this only after its endpoint and semantic ready event are both live. */
177
178
  export declare function writeSessionLifecycleReady(root: string, id: string, effectMarker: string): Promise<void>;
178
179
  export interface LifecycleTranscriptEvidence {
179
180
  digest: string;
180
181
  identity: SessionLifecycleTranscriptIdentity;
181
182
  }
183
+ type LifecycleFailureArtifact = EffectMarker & SdkStartupFailure & {
184
+ rollback: SdkStartupRollbackResult;
185
+ transcript?: LifecycleTranscriptEvidence;
186
+ };
182
187
  /** Writes bounded startup diagnostics. The child stamps its own pid; the broker may stamp a proven child identity. */
183
188
  export declare function writeSessionLifecycleFailure(root: string, id: string, effectMarker: string, failure: SdkStartupFailure, rollback: SdkStartupRollbackResult, transcript?: LifecycleTranscriptEvidence, ownerIncarnation?: string, ownerPid?: number): Promise<void>;
189
+ export declare function readSessionLifecycleFailure(root: string, id: string, expected: EffectMarker): Promise<LifecycleFailureArtifact | undefined>;
184
190
  export declare function readSessionLifecycleFailureForTest(root: string, id: string, expected: {
185
191
  pid: number;
186
192
  effectMarker: string;
@@ -1,5 +1,5 @@
1
1
  export interface BrokerStartupFailureMarker {
2
- version: 1;
2
+ version: 2;
3
3
  reason: string;
4
4
  exitCode: number | null;
5
5
  signal: string | null;
@@ -13,6 +13,8 @@ export interface BrokerStartupFailureMarker {
13
13
  * failure.
14
14
  */
15
15
  pid: number;
16
+ /** Kernel-derived identity for the exact process incarnation that wrote the marker. */
17
+ incarnation: string;
16
18
  }
17
19
  export declare function brokerStartupFailurePath(agentDir: string): string;
18
20
  /**
@@ -26,6 +28,7 @@ export declare function writeBrokerStartupFailureMarker(agentDir: string, failur
26
28
  exitCode: number | null;
27
29
  signal: string | null;
28
30
  pid: number;
31
+ incarnation?: string;
29
32
  }): Promise<void>;
30
33
  /** Reads a bounded startup-failure marker; `undefined` when absent or malformed. */
31
34
  export declare function readBrokerStartupFailureMarker(agentDir: string): Promise<BrokerStartupFailureMarker | undefined>;
@@ -105,6 +105,8 @@ export type ChatDaemonAction = "stop" | "reload";
105
105
  * Discord generation 72 / Slack generation 75 serialize same-generation
106
106
  * successor attachment admission behind predecessor provider retirement, so a
107
107
  * pre-upgrade owner cannot retain the queue race fixed by #5120.
108
+ * Slack generation 80 persists and fences the inbound SDK dispatch boundary so
109
+ * crashes, recovery, and attachment retirement cannot replay ambiguous work.
108
110
  */
109
111
  export declare const CHAT_DAEMON_GENERATIONS: Readonly<Record<ChatDaemonKind, number>>;
110
112
  export declare function chatDaemonGeneration(kind: ChatDaemonKind): number;
@@ -2,7 +2,7 @@ import { type ConversationRecord, type ConversationStoreFs } from "./conversatio
2
2
  export declare const CHAT_EFFECT_JOURNAL_VERSION = 1;
3
3
  export declare const MAX_TERMINAL_CHAT_EFFECTS = 128;
4
4
  export declare function chatEffectJournalPath(agentDir: string, transport: "discord" | "slack"): string;
5
- export type ChatEffectState = "pending" | "leased" | "accepted" | "uncertain" | "terminal";
5
+ export type ChatEffectState = "pending" | "leased" | "dispatching" | "accepted" | "uncertain" | "terminal";
6
6
  /** Provider receipts are identifiers/status only. Never put request or response bodies here. */
7
7
  export interface ChatEffectReceipt {
8
8
  provider?: string;
@@ -77,9 +77,24 @@ export declare class ChatEffectJournal {
77
77
  enqueueAndClaim<TPayload>(input: EnqueueChatEffect<TPayload>, owner: string, leaseMs: number): Promise<ChatEffect<TPayload> | undefined>;
78
78
  claim<TPayload = unknown>(id: string, owner: string, leaseMs: number): Promise<ChatEffect<TPayload> | undefined>;
79
79
  renew<TPayload = unknown>(id: string, lease: ChatEffectLease, leaseMs: number): Promise<ChatEffect<TPayload> | undefined>;
80
+ markDispatching<TPayload = unknown>(id: string, lease: ChatEffectLease): Promise<ChatEffect<TPayload> | undefined>;
81
+ ownsDispatching(id: string, lease: ChatEffectLease): Promise<boolean>;
82
+ /** Hold the durable dispatching lease until the synchronous SDK prewire boundary. */
83
+ dispatchWithLeaseFence<R>(id: string, lease: ChatEffectLease, dispatch: () => Promise<R>, dispatched: Promise<void>): Promise<{
84
+ value: R;
85
+ } | undefined>;
86
+ recoverDispatchingAsUncertain<TPayload = unknown>(id: string, options?: {
87
+ onlyIfExpired?: boolean;
88
+ }): Promise<ChatEffect<TPayload> | undefined>;
80
89
  /** Persists provider progress without releasing the owner/epoch fence. */
81
90
  recordReceipt<TPayload = unknown>(id: string, lease: ChatEffectLease, receipt: ChatEffectReceipt): Promise<ChatEffect<TPayload> | undefined>;
82
- record<TPayload = unknown>(id: string, lease: ChatEffectLease, state: Exclude<ChatEffectState, "pending" | "leased">, receipt?: ChatEffectReceipt): Promise<ChatEffect<TPayload> | undefined>;
91
+ record<TPayload = unknown>(id: string, lease: ChatEffectLease, state: "accepted" | "uncertain" | "terminal", receipt?: ChatEffectReceipt): Promise<ChatEffect<TPayload> | undefined>;
83
92
  /** Irreversibly rejects an effect whose mapping never accepted its authority. */
84
93
  terminalize(id: string, receipt: ChatEffectReceipt, lease?: ChatEffectLease): Promise<ChatEffect | undefined>;
94
+ /**
95
+ * Terminalize only a decided effect. The uncertainty check and state change
96
+ * share one store transaction so a concurrent sender cannot publish an
97
+ * ambiguity tombstone between a caller's read and stale cleanup.
98
+ */
99
+ terminalizeDecided(id: string, receipt: ChatEffectReceipt, lease?: ChatEffectLease): Promise<ChatEffect | undefined>;
85
100
  }
@@ -88,4 +88,15 @@ export declare class ConversationStore<T extends ConversationRecord> {
88
88
  * other writer uses.
89
89
  */
90
90
  transactWithSnapshot(key: string, update: (current: T | undefined, conversations: Readonly<Record<string, T>>) => T | undefined | Promise<T | undefined>): Promise<T | undefined>;
91
+ /**
92
+ * Hold the cross-process mapping lock until a prepared dispatch either reaches
93
+ * its synchronous wire boundary or fails before sending. The result may remain
94
+ * pending after the lock is released while the remote response is awaited.
95
+ */
96
+ dispatchWithSnapshotFence<R>(key: string, prepare: (current: T | undefined, conversations: Readonly<Record<string, T>>) => {
97
+ result: Promise<R>;
98
+ dispatched: Promise<void>;
99
+ } | undefined): Promise<{
100
+ value: R;
101
+ } | undefined>;
91
102
  }
@@ -1,5 +1,11 @@
1
1
  import type { SessionCloseTarget, SessionCreateTarget, SessionLifecycleResponse, SessionResumeTarget } from "./index";
2
2
  export type LifecycleCommandVerb = "session_create" | "session_close" | "session_resume";
3
+ export interface LifecycleCommandContext {
4
+ chatType?: string;
5
+ botUsername?: string;
6
+ /** Session durably associated with the Telegram topic containing the command. */
7
+ threadSessionId?: string;
8
+ }
3
9
  /** A parsed, validated lifecycle command (transport identity added by caller). */
4
10
  export type ParsedLifecycleCommand = {
5
11
  kind: "create";
@@ -27,10 +33,7 @@ export type ParsedLifecycleCommand = {
27
33
  /** True when the text begins with any /session_* token, regardless of addressability. */
28
34
  export declare function isLifecycleCommandLikeText(text: string | undefined): boolean;
29
35
  /** True when the text begins an addressable /session_* command (cheap pre-gate). */
30
- export declare function isLifecycleCommandText(text: string | undefined, ctx?: {
31
- chatType?: string;
32
- botUsername?: string;
33
- }): boolean;
36
+ export declare function isLifecycleCommandText(text: string | undefined, ctx?: LifecycleCommandContext): boolean;
34
37
  /**
35
38
  * Parse a paired-chat message into a lifecycle command. Returns `none` for
36
39
  * non-lifecycle text, `usage`/`reject` for malformed input (no side effect), or
@@ -39,10 +42,7 @@ export declare function isLifecycleCommandText(text: string | undefined, ctx?: {
39
42
  * The caller MUST have already enforced paired-chat authorization; this function
40
43
  * performs grammar + target validation only.
41
44
  */
42
- export declare function parseLifecycleCommand(text: string | undefined, ctx?: {
43
- chatType?: string;
44
- botUsername?: string;
45
- }): ParsedLifecycleCommand;
45
+ export declare function parseLifecycleCommand(text: string | undefined, ctx?: LifecycleCommandContext): ParsedLifecycleCommand;
46
46
  /** The canonical usage text (exported for the daemon's help replies). */
47
47
  export declare function lifecycleUsage(): string;
48
48
  /**
@@ -30,7 +30,7 @@ export interface SlackNotificationDaemonOptions {
30
30
  resolveAttachment: (sessionId: string) => Promise<SessionAttachment | null>;
31
31
  /** Exact Router proof for adopting an existing root. */
32
32
  resolveBindingAuthority?: (sessionId: string) => Promise<SlackBindingAuthority | undefined>;
33
- onCommand?: (sessionId: string, content: string, attachment: SessionAttachment, idempotencyKey: string) => Promise<boolean>;
33
+ onCommand?: (sessionId: string, content: string, attachment: SessionAttachment, idempotencyKey: string, beforeDispatch: () => void, dispatchFence: <T>(dispatch: () => Promise<T>) => Promise<T>) => Promise<boolean>;
34
34
  }
35
35
  /**
36
36
  * Slack Socket Mode notification daemon. Accepted inbound SDK effects are
@@ -206,6 +206,14 @@ export declare class TopicRegistry {
206
206
  private rebuildInboundRoutes;
207
207
  /** Resolve the owning session for a topic id (for fail-closed inbound routing). */
208
208
  sessionForTopic(topicId: string): string | undefined;
209
+ /**
210
+ * Resolve a durable topic association for explicit lifecycle controls.
211
+ *
212
+ * Unlike inbound message routing, this may return an inactive session so a
213
+ * user can resume it from its old topic. Ambiguous, malformed, cross-chat,
214
+ * and quarantined records fail closed.
215
+ */
216
+ sessionForLifecycleTopic(topicId: string, chatId: string): string | undefined;
209
217
  /** All session ids with a persisted topic record. */
210
218
  sessionIds(): string[];
211
219
  /** The existing topic record for a session, if any. */
@@ -12,6 +12,10 @@ export declare class SdkClientError extends Error {
12
12
  readonly reconnect?: SdkReconnectExhaustedDetails;
13
13
  constructor(code: SdkErrorCode, message: string, details?: unknown, reconnect?: SdkReconnectExhaustedDetails);
14
14
  }
15
+ /** A prepared transport operation failed before any wire handoff. */
16
+ export declare class SdkPreparedDispatchError extends SdkClientError {
17
+ constructor(error: SdkClientError);
18
+ }
15
19
  export type SdkReconnectTerminationReason = "attempts_exhausted" | "deadline" | "cancelled";
16
20
  /**
17
21
  * Reconnect-cycle termination diagnostics. `attemptsConsumed` counts retry slots,
@@ -66,6 +70,8 @@ export interface SdkRequestOptions {
66
70
  * alter that settlement.
67
71
  */
68
72
  onDispatch?: SdkDispatchHandler;
73
+ /** Internal prepared-dispatch mode: fail pre-send instead of reconnecting. */
74
+ connectedOnly?: boolean;
69
75
  }
70
76
  export type SdkFrame = Record<string, unknown>;
71
77
  /**
@@ -117,6 +117,8 @@ export declare class SessionSdkHost {
117
117
  * publishing a second readiness signal.
118
118
  */
119
119
  activate(expectedGeneration?: number): Promise<SessionActivationOutcome>;
120
- stop(): Promise<"stopped" | "already">;
120
+ stop(options?: {
121
+ allowLockContention?: boolean;
122
+ }): Promise<"stopped" | "already">;
121
123
  registerWithBroker(writer: BrokerIndexWriter): Promise<void>;
122
124
  }
@@ -189,7 +189,7 @@ export declare class SessionSdkSessionRuntime {
189
189
  * asked for. Delivery failure is ignored: a disconnected consumer must never
190
190
  * disturb the turn producing the content.
191
191
  */
192
- sendFrameTo(connectionIds: Iterable<string>, frame: SdkFrame): void;
192
+ sendFrameTo(connectionId: string, frame: SdkFrame): void;
193
193
  publish(frame: SdkFrame): void;
194
194
  startHost(): Promise<"started" | "already">;
195
195
  startTransport(): Promise<{
@@ -198,7 +198,9 @@ export declare class SessionSdkSessionRuntime {
198
198
  start(): Promise<{
199
199
  url: string;
200
200
  }>;
201
- stop(): Promise<void>;
201
+ stop(options?: {
202
+ allowLockContention?: boolean;
203
+ }): Promise<void>;
202
204
  registerWithBroker(writer: BrokerIndexWriter): Promise<void>;
203
205
  }
204
206
  /** Narrow extension-facing factory for the SDK-only session path. */
@@ -137,6 +137,7 @@ export interface SessionLifecycleSessionResult {
137
137
  readonly sessionId: string;
138
138
  readonly cwd?: string;
139
139
  readonly endpointGeneration?: number;
140
+ readonly endpointIncarnation?: string;
140
141
  readonly reused?: boolean;
141
142
  readonly note?: string;
142
143
  }
@@ -2,6 +2,7 @@ import { type SessionIndex } from "../broker/session-index";
2
2
  import { type SdkDispatchContext, type SdkDispatchHandler } from "../client/client";
3
3
  import { type ActivatedPreparedSession } from "../session-activation";
4
4
  export interface SessionEndpointIdentity {
5
+ readonly dev: bigint;
5
6
  readonly mtimeMs: number;
6
7
  readonly mtimeNs: bigint;
7
8
  readonly ctimeNs: bigint;
@@ -32,7 +33,10 @@ export interface SessionAttachment {
32
33
  readonly connectionId?: string;
33
34
  readonly generation: number;
34
35
  isCurrent(): boolean;
35
- send(frame: Record<string, unknown>): unknown;
36
+ send(frame: Record<string, unknown>, options?: {
37
+ beforeDispatch?: () => void;
38
+ dispatchFence?: (dispatch: () => Promise<void>) => Promise<void>;
39
+ }): unknown;
36
40
  /**
37
41
  * Idempotent provider-lease heartbeat send that skips the pre-send authority
38
42
  * reconcile (#4689).
@@ -106,6 +110,7 @@ export interface SessionRouterClient {
106
110
  connect?(): Promise<void>;
107
111
  request(frame: Record<string, unknown>, options?: {
108
112
  timeoutMs?: number;
113
+ connectedOnly?: boolean;
109
114
  /** Synchronous pre-send observer; a throw aborts the dispatch before the wire. */
110
115
  beforeDispatch?: (context: SdkDispatchContext) => void;
111
116
  /** Synchronous post-send boundary observer for transport-close-aware consumers. */
@@ -208,6 +213,7 @@ export declare class SessionRouter {
208
213
  timeoutMs?: number;
209
214
  beforeDispatch?: (context: SdkDispatchContext) => void;
210
215
  onDispatch?: SdkDispatchHandler;
216
+ dispatchFence?: (dispatch: () => Promise<Record<string, unknown>>) => Promise<Record<string, unknown>>;
211
217
  }): Promise<Record<string, unknown>>;
212
218
  /** Resolves the exact provider-neutral binding authority for operator adoption. */
213
219
  bindingAuthority(sessionId: string): Promise<{
@@ -224,5 +230,7 @@ export declare class SessionRouter {
224
230
  /** Activates a prepared session through one Router-owned, one-shot SDK client. */
225
231
  activatePreparedSession(sessionId: string): Promise<ActivatedPreparedSession>;
226
232
  /** Lists saved sessions through Router-owned Broker discovery without exposing credentials or mutation authority. */
227
- listBrokerSessions(input: Record<string, unknown>, idempotencyKey: string): Promise<Record<string, unknown>>;
233
+ listBrokerSessions(input: Record<string, unknown>, idempotencyKey: string, options?: {
234
+ beforeDispatch?: (context: SdkDispatchContext) => void;
235
+ }, dispatchFence?: (dispatch: () => Promise<Record<string, unknown>>) => Promise<Record<string, unknown>>): Promise<Record<string, unknown>>;
228
236
  }