@gajae-code/coding-agent 0.11.7 → 0.11.8

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 (180) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/types/cli/args.d.ts +0 -2
  3. package/dist/types/config/keybindings.d.ts +33 -3
  4. package/dist/types/config/model-profile-activation.d.ts +4 -3
  5. package/dist/types/config/model-profile-contract.d.ts +38 -0
  6. package/dist/types/config/settings-schema.d.ts +15 -2
  7. package/dist/types/edit/modes/patch.d.ts +13 -0
  8. package/dist/types/edit/path-mutation-lock.d.ts +15 -0
  9. package/dist/types/eval/py/executor.d.ts +1 -1
  10. package/dist/types/eval/py/tool-bridge.d.ts +1 -2
  11. package/dist/types/gjc-runtime/repository-binding.d.ts +63 -0
  12. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +1 -0
  13. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +24 -0
  14. package/dist/types/main.d.ts +8 -0
  15. package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +2 -1
  16. package/dist/types/modes/components/tool-status-header.d.ts +3 -2
  17. package/dist/types/modes/components/welcome.d.ts +2 -0
  18. package/dist/types/modes/controllers/command-controller.d.ts +2 -0
  19. package/dist/types/modes/controllers/selector-controller.d.ts +2 -1
  20. package/dist/types/modes/interactive-mode.d.ts +5 -2
  21. package/dist/types/modes/prompt-action-autocomplete.d.ts +6 -1
  22. package/dist/types/modes/prompt-suggestion-controller.d.ts +35 -0
  23. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +2 -2
  24. package/dist/types/modes/types.d.ts +3 -0
  25. package/dist/types/modes/utils/hotkeys-markdown.d.ts +2 -1
  26. package/dist/types/runtime-mcp/manager.d.ts +1 -1
  27. package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -5
  28. package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +14 -0
  29. package/dist/types/sdk/broker/broker.d.ts +2 -0
  30. package/dist/types/sdk/broker/lifecycle.d.ts +6 -0
  31. package/dist/types/sdk/bus/chat-daemon-control.d.ts +5 -1
  32. package/dist/types/sdk/bus/config-commands.d.ts +2 -2
  33. package/dist/types/sdk/bus/config.d.ts +2 -0
  34. package/dist/types/sdk/bus/conversation-store.d.ts +1 -0
  35. package/dist/types/sdk/bus/index.d.ts +25 -0
  36. package/dist/types/sdk/bus/notification-orchestration.d.ts +1 -0
  37. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +105 -0
  38. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +13 -3
  39. package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -1
  40. package/dist/types/sdk/bus/telegram-daemon.d.ts +128 -1
  41. package/dist/types/sdk/bus/telegram-reference.d.ts +2 -0
  42. package/dist/types/sdk/host/control/operations.d.ts +1 -1
  43. package/dist/types/sdk/host/host.d.ts +1 -1
  44. package/dist/types/sdk/host/query/handlers.d.ts +9 -0
  45. package/dist/types/sdk/index.d.ts +2 -0
  46. package/dist/types/sdk/prompt-status.d.ts +88 -0
  47. package/dist/types/sdk/session-directory.d.ts +1 -1
  48. package/dist/types/sdk/startup-capability.d.ts +3 -0
  49. package/dist/types/session/agent-session.d.ts +2 -0
  50. package/dist/types/session/internal/managed-session-scope.d.ts +11 -2
  51. package/dist/types/session/internal/managed-session-storage.d.ts +17 -2
  52. package/dist/types/session/internal/native-publish-outcome.d.ts +48 -0
  53. package/dist/types/session/session-storage.d.ts +18 -0
  54. package/dist/types/task/index.d.ts +3 -1
  55. package/dist/types/task/receipt.d.ts +2 -0
  56. package/dist/types/task/types.d.ts +94 -0
  57. package/dist/types/tools/ask.d.ts +454 -174
  58. package/dist/types/tools/image-gen.d.ts +47 -1
  59. package/dist/types/tools/index.d.ts +4 -0
  60. package/dist/types/utils/prompt-suggestion.d.ts +33 -0
  61. package/package.json +8 -8
  62. package/scripts/capture-platform-shortcut-labels-showcase.ts +342 -0
  63. package/scripts/dogfood-repository-binding.ts +209 -0
  64. package/scripts/generate-sdk-operation-inventory.ts +2 -0
  65. package/scripts/run-test-manifest.ts +4 -4
  66. package/src/cli/args.ts +2 -92
  67. package/src/cli/notify-cli.ts +5 -38
  68. package/src/cli.ts +18 -0
  69. package/src/commands/sdk.ts +2 -2
  70. package/src/config/keybindings.ts +157 -24
  71. package/src/config/model-profile-activation.ts +7 -18
  72. package/src/config/model-profile-contract.ts +161 -0
  73. package/src/config/model-registry.ts +11 -1
  74. package/src/config/settings-schema.ts +17 -2
  75. package/src/coordinator-mcp/model-preset.ts +21 -74
  76. package/src/defaults/gjc/skills/deep-interview/SKILL.md +2 -2
  77. package/src/defaults/gjc/skills/ralplan/SKILL.md +3 -1
  78. package/src/edit/index.ts +3 -6
  79. package/src/edit/modes/patch.ts +38 -1
  80. package/src/edit/modes/replace.ts +42 -0
  81. package/src/edit/path-mutation-lock.ts +112 -0
  82. package/src/eval/py/executor.ts +30 -11
  83. package/src/eval/py/prelude.py +2 -2
  84. package/src/eval/py/tool-bridge.ts +34 -18
  85. package/src/extensibility/gjc-plugins/runtime-adapters.ts +2 -1
  86. package/src/gjc-runtime/launch-tmux.ts +1 -1
  87. package/src/gjc-runtime/managed-owner-supervisor.ts +83 -4
  88. package/src/gjc-runtime/ralplan-runtime.ts +75 -3
  89. package/src/gjc-runtime/repository-binding.ts +267 -0
  90. package/src/gjc-runtime/session-state-sidecar.ts +25 -9
  91. package/src/gjc-runtime/tmux-owner-isolation.ts +2 -1
  92. package/src/gjc-runtime/tmux-sessions.ts +45 -6
  93. package/src/gjc-runtime/ultragoal-guard.ts +5 -5
  94. package/src/gjc-runtime/ultragoal-runtime.ts +181 -19
  95. package/src/internal-urls/docs-index.generated.ts +6 -5
  96. package/src/internal-urls/local-protocol.ts +33 -16
  97. package/src/internal-urls/mcp-protocol.ts +73 -11
  98. package/src/main.ts +25 -10
  99. package/src/modes/DESIGN.md +5 -0
  100. package/src/modes/acp/acp-agent.ts +50 -16
  101. package/src/modes/components/model-selector.ts +42 -8
  102. package/src/modes/components/plan-preview-overlay.ts +1 -1
  103. package/src/modes/components/runtime-mcp-add-wizard.ts +5 -0
  104. package/src/modes/components/tool-status-header.ts +20 -4
  105. package/src/modes/components/welcome.ts +22 -18
  106. package/src/modes/controllers/command-controller.ts +97 -54
  107. package/src/modes/controllers/event-controller.ts +10 -0
  108. package/src/modes/controllers/input-controller.ts +7 -2
  109. package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -6
  110. package/src/modes/controllers/selector-controller.ts +46 -54
  111. package/src/modes/interactive-mode.ts +41 -27
  112. package/src/modes/prompt-action-autocomplete.ts +32 -13
  113. package/src/modes/prompt-suggestion-controller.ts +96 -0
  114. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +2 -2
  115. package/src/modes/types.ts +3 -0
  116. package/src/modes/utils/hotkeys-markdown.ts +64 -36
  117. package/src/modes/utils/ui-helpers.ts +5 -3
  118. package/src/prompts/agents/architect.md +0 -1
  119. package/src/prompts/agents/critic.md +0 -1
  120. package/src/prompts/system/prompt-suggestion-system.md +32 -0
  121. package/src/prompts/system/system-prompt.md +6 -4
  122. package/src/prompts/tools/cron.md +3 -1
  123. package/src/runtime-mcp/manager.ts +51 -53
  124. package/src/runtime-mcp/oauth-flow.ts +0 -72
  125. package/src/runtime-mcp/plugin-network-boundary.ts +101 -0
  126. package/src/runtime-mcp/transports/http.ts +13 -6
  127. package/src/sdk/broker/broker.ts +34 -20
  128. package/src/sdk/broker/lifecycle.ts +185 -36
  129. package/src/sdk/bus/chat-daemon-control.ts +18 -5
  130. package/src/sdk/bus/config-commands.ts +2 -2
  131. package/src/sdk/bus/config.ts +9 -1
  132. package/src/sdk/bus/conversation-store.ts +40 -6
  133. package/src/sdk/bus/index.ts +240 -65
  134. package/src/sdk/bus/lifecycle-commands.ts +47 -3
  135. package/src/sdk/bus/lifecycle-control-runtime.ts +11 -2
  136. package/src/sdk/bus/lifecycle-orchestrator.ts +32 -1
  137. package/src/sdk/bus/notification-orchestration.ts +12 -0
  138. package/src/sdk/bus/notification-service.ts +27 -2
  139. package/src/sdk/bus/prompt-reconciliation.ts +239 -0
  140. package/src/sdk/bus/recent-activity.ts +90 -26
  141. package/src/sdk/bus/telegram-daemon-contract.ts +13 -3
  142. package/src/sdk/bus/telegram-daemon-control.ts +145 -33
  143. package/src/sdk/bus/telegram-daemon.ts +835 -110
  144. package/src/sdk/bus/telegram-reference.ts +20 -2
  145. package/src/sdk/cli/session-cli.ts +15 -2
  146. package/src/sdk/host/control/dispatch.ts +1 -1
  147. package/src/sdk/host/control/operations.ts +1 -1
  148. package/src/sdk/host/host.ts +2 -6
  149. package/src/sdk/host/query/handlers.ts +70 -5
  150. package/src/sdk/index.ts +12 -0
  151. package/src/sdk/prompt-status.ts +97 -0
  152. package/src/sdk/protocol/operation-inventory.generated.json +47 -0
  153. package/src/sdk/protocol/operation-registry.ts +18 -4
  154. package/src/sdk/session-directory.ts +5 -1
  155. package/src/sdk/session.ts +2 -0
  156. package/src/sdk/startup-capability.ts +9 -1
  157. package/src/session/agent-session.ts +52 -5
  158. package/src/session/blob-store.ts +7 -2
  159. package/src/session/internal/managed-session-scope.ts +854 -84
  160. package/src/session/internal/managed-session-storage.ts +251 -199
  161. package/src/session/internal/native-publish-outcome.ts +266 -0
  162. package/src/session/session-manager.ts +310 -327
  163. package/src/session/session-storage.ts +128 -11
  164. package/src/task/gjc-command.ts +2 -2
  165. package/src/task/index.ts +121 -15
  166. package/src/task/receipt.ts +3 -0
  167. package/src/task/types.ts +34 -3
  168. package/src/tools/ask.ts +198 -88
  169. package/src/tools/ast-edit.ts +2 -2
  170. package/src/tools/bash-pty-selection.ts +2 -2
  171. package/src/tools/browser/screenshot-format.ts +6 -1
  172. package/src/tools/cron.ts +1 -1
  173. package/src/tools/image-gen.ts +178 -6
  174. package/src/tools/index.ts +4 -0
  175. package/src/tools/render-utils.ts +7 -1
  176. package/src/utils/edit-mode.ts +2 -2
  177. package/src/utils/prompt-suggestion.ts +265 -0
  178. package/src/utils/sixel.ts +3 -3
  179. package/src/web/insane/url-guard.ts +3 -1
  180. package/src/web/scrapers/docs-rs.ts +30 -5
@@ -4,6 +4,7 @@ import type { DaemonRuntimeInfo } from "../../daemon/control-types";
4
4
  import { HEARTBEAT_TTL_MS } from "./daemon-paths";
5
5
  import { type DaemonTransitionLock, type NotificationEndpointFile, type NotificationEndpointFileIdentity, type NotificationExactUnlinkResult } from "./notification-service";
6
6
  import { type DaemonProcessReference } from "./telegram-daemon-control";
7
+ import { type TelegramSetupPreflight } from "./telegram-setup";
7
8
  export { DAEMON_GENERATION, NOTIFICATION_PROTOCOL_VERSION } from "./telegram-daemon-contract";
8
9
  import { type ControlServerLike, type LifecycleControlServerFactory } from "./lifecycle-control-runtime";
9
10
  import type { OrchestratorDeps } from "./lifecycle-orchestrator";
@@ -55,6 +56,10 @@ export interface TelegramDaemonFs {
55
56
  chmod(path: string, mode: number): Promise<void>;
56
57
  stat?(path: string): Promise<{
57
58
  mtimeMs: number;
59
+ size?: number;
60
+ dev?: number;
61
+ ino?: number;
62
+ ctimeMs?: number;
58
63
  }>;
59
64
  readEndpointFile?(path: string): Promise<NotificationEndpointFile>;
60
65
  exactUnlink?(path: string, identity: NotificationEndpointFileIdentity): Promise<NotificationExactUnlinkResult>;
@@ -102,6 +107,21 @@ export declare const ASK_SELECTED_ACK_CAPABILITY = "ask_selected_ack_v1";
102
107
  export declare const ASK_CONTROLS_CAPABILITY = "ask_controls_v1";
103
108
  /** Capability required for tool lifecycle and reasoning-summary frames. */
104
109
  export declare const TOOL_ACTIVITY_CAPABILITY = "tool_activity_v1";
110
+ /**
111
+ * File-lock options whose acquisition budget covers the full reload-reservation
112
+ * critical section: the in-lock freshness poll plus the controller's
113
+ * graceful+kill+readiness sequence, with headroom. A contender must be able to
114
+ * wait out a legitimate slow reload and then attach, never fail startup.
115
+ */
116
+ export declare function reloadReservationLockOptions(input: {
117
+ freshnessWaitMs: number;
118
+ readinessTimeoutMs: number;
119
+ retryDelayMs?: number;
120
+ }): {
121
+ staleMs: number;
122
+ retries: number;
123
+ retryDelayMs: number;
124
+ };
105
125
  export declare const BTW_QUESTION_MAX_UNICODE_SCALARS = 4096;
106
126
  export declare const BTW_QUESTION_MAX_UTF8_BYTES = 16384;
107
127
  export declare function endpointAuthorityDigest(url: string, token: string, connectionIdentity?: string): string;
@@ -137,12 +157,22 @@ type LegacyOwnershipLockMetadata = {
137
157
  incarnation?: string;
138
158
  startedAt: number;
139
159
  };
160
+ type V010OwnershipLockMetadata = {
161
+ size: 0;
162
+ mtimeMs?: number;
163
+ dev?: number;
164
+ ino?: number;
165
+ ctimeMs?: number;
166
+ };
140
167
  type OwnershipLockRead = {
141
168
  kind: "missing";
142
169
  } | {
143
170
  kind: "malformed";
144
171
  raw: string;
145
172
  mtimeMs?: number;
173
+ } | {
174
+ kind: "v010";
175
+ metadata: V010OwnershipLockMetadata;
146
176
  } | {
147
177
  kind: "legacy";
148
178
  metadata: LegacyOwnershipLockMetadata;
@@ -188,7 +218,84 @@ export declare function unregisterNotificationRoot(input: {
188
218
  sessionId: string;
189
219
  fs?: TelegramDaemonFs;
190
220
  }): Promise<UnregisterNotificationRootResult>;
221
+ /**
222
+ * Leak artifact prefixes left when native exact-unlink cleanup is retained
223
+ * (#2956). Nothing previously reaped these; they accumulate in the notifications
224
+ * directory across ownership transitions.
225
+ */
226
+ export declare const NOTIFICATION_LEAK_ARTIFACT_PREFIXES: readonly [".gjc-delete-daemon-transition-", ".gjc-exact-unlink-placeholder-", ".gjc-delete-notification-endpoint-"];
227
+ /** Grace window before a leak artifact is reaped (covers in-flight unlinks). */
228
+ export declare const NOTIFICATION_LEAK_ARTIFACT_GRACE_MS: number;
229
+ /** True when a path is permanently gone (not a transient I/O blip). */
230
+ export declare function isPermanentMissingPathError(error: unknown): boolean;
231
+ export declare function isNotificationLeakArtifactName(name: string): boolean;
232
+ /**
233
+ * Drop permanently missing scan roots from the durable registry under the roots
234
+ * lock. Session map entries that pointed only at those roots are removed too.
235
+ */
236
+ export declare function pruneMissingNotificationRoots(input: {
237
+ settings: Settings;
238
+ fs?: TelegramDaemonFs;
239
+ /** When set, only these roots are considered; otherwise every registered root is probed. */
240
+ candidates?: readonly string[];
241
+ }): Promise<{
242
+ pruned: string[];
243
+ remaining: number;
244
+ }>;
245
+ /**
246
+ * Reap retained exact-unlink / ownership-transition quarantine files older than
247
+ * the grace window from the notifications directory.
248
+ */
249
+ export declare function reapStaleNotificationArtifacts(input: {
250
+ settings: Settings;
251
+ fs?: TelegramDaemonFs;
252
+ now?: () => number;
253
+ graceMs?: number;
254
+ }): Promise<{
255
+ removed: string[];
256
+ skipped: number;
257
+ }>;
258
+ /**
259
+ * Startup / ownership self-heal: prune dead roots and reap leak artifacts so
260
+ * `gjc daemon reload` recovers a degraded install without manual surgery (#2956).
261
+ */
262
+ export declare function healTelegramDaemonNotificationState(input: {
263
+ settings: Settings;
264
+ fs?: TelegramDaemonFs;
265
+ now?: () => number;
266
+ graceMs?: number;
267
+ }): Promise<{
268
+ prunedRoots: string[];
269
+ removedArtifacts: string[];
270
+ }>;
191
271
  export declare function hasSafeDaemonStateShape(state: unknown): state is DaemonState;
272
+ type ParentDaemonStateBase = Omit<DaemonState, "incarnation" | "acquisitionId" | "ownershipPhase" | "generation" | "launcherPid"> & {
273
+ incarnation?: undefined;
274
+ acquisitionId?: undefined;
275
+ ownershipPhase?: undefined;
276
+ generation?: unknown;
277
+ launcherPid?: undefined;
278
+ };
279
+ type GenerationAbsentParentDaemonState = Omit<ParentDaemonStateBase, "generation"> & {
280
+ generation?: undefined;
281
+ };
282
+ type Generation3ReleaseDaemonState = Omit<ParentDaemonStateBase, "generation"> & {
283
+ generation: 3;
284
+ };
285
+ export type LegacyParentDaemonState = GenerationAbsentParentDaemonState | Generation3ReleaseDaemonState;
286
+ export interface AttestedLegacyDaemonOwner {
287
+ state: LegacyParentDaemonState;
288
+ incarnation: string;
289
+ }
290
+ /** Revalidate the exact two-observation legacy proof immediately before signaling. */
291
+ export declare function readAttestedLegacyDaemonOwner(input: {
292
+ settings: Settings;
293
+ fs?: TelegramDaemonFs;
294
+ now?: () => number;
295
+ pidIncarnation?: (pid: number) => string | undefined;
296
+ tokenFingerprint: string;
297
+ chatId: string;
298
+ }): Promise<AttestedLegacyDaemonOwner | undefined>;
192
299
  /** True for a physically live owner with this configuration, including legacy generations. */
193
300
  export declare function isPhysicalMatchingOwner(input: {
194
301
  state: DaemonState | undefined;
@@ -197,7 +304,7 @@ export declare function isPhysicalMatchingOwner(input: {
197
304
  pidAlive: (pid: number) => boolean;
198
305
  pidIncarnation?: (pid: number) => string | undefined;
199
306
  }): boolean;
200
- /** True only for a signalable legacy owner or this generation's ready bound child. */
307
+ /** True only for a fully-provenanced modern owner outside the generation-3 parent schema. */
201
308
  export declare function isSignalableMatchingOwner(input: {
202
309
  state: DaemonState | undefined;
203
310
  tokenFingerprint: string;
@@ -246,6 +353,7 @@ export declare function acquireDaemonOwnership(input: {
246
353
  provisional?: boolean;
247
354
  reason?: "identity_mismatch";
248
355
  reloadRequired?: boolean;
356
+ legacyReloadRequired?: boolean;
249
357
  }>;
250
358
  export declare function renewDaemonHeartbeat(input: {
251
359
  settings: Settings;
@@ -322,6 +430,8 @@ export declare function confirmTelegramDaemonSpawn(input: {
322
430
  sleep?: (ms: number) => Promise<void>;
323
431
  waitStepMs?: number;
324
432
  timeoutMs?: number;
433
+ /** Retain an unproven no-PID child lease during a successor handoff. */
434
+ preserveOnUnprovenChildExit?: boolean;
325
435
  }): Promise<boolean>;
326
436
  export declare function releaseDaemonOwnership(input: {
327
437
  settings: Settings;
@@ -339,6 +449,22 @@ export declare function releaseDaemonOwnership(input: {
339
449
  export declare function readDaemonState(settings: Pick<Settings, "getAgentDir">, fs?: TelegramDaemonFs): Promise<DaemonState | undefined>;
340
450
  /** Read the persisted notification roots list. */
341
451
  export declare function readDaemonRoots(settings: Pick<Settings, "getAgentDir">, fs?: TelegramDaemonFs): Promise<string[]>;
452
+ /** Injectable readers for {@link resolveTelegramSetupPreflight}, defaulting to the real OS/state probes. */
453
+ export interface ResolveTelegramSetupPreflightDeps {
454
+ readDaemonState?: (settings: Settings) => Promise<DaemonState | undefined>;
455
+ pidAlive?: (pid: number) => boolean;
456
+ pidIncarnation?: (pid: number) => string | undefined;
457
+ }
458
+ /**
459
+ * Build the Telegram setup preflight from persisted daemon state. The daemon is
460
+ * reported live ONLY when its PID is alive AND its current process incarnation
461
+ * still matches the persisted incarnation. Skipping the incarnation check makes
462
+ * a stale state file whose PID has been recycled by an unrelated process
463
+ * masquerade as a live owner, which wrongly blocks discovery pairing. Both the
464
+ * `notify setup` CLI and the /settings Notifications tab share this resolver so
465
+ * pairing behaves identically on both surfaces.
466
+ */
467
+ export declare function resolveTelegramSetupPreflight(settings: Settings, deps?: ResolveTelegramSetupPreflightDeps): Promise<TelegramSetupPreflight>;
342
468
  export interface TelegramSpawnOwnerInput {
343
469
  settings: Settings;
344
470
  roots?: string[];
@@ -363,6 +489,7 @@ export type TelegramSpawnOwnerResult = {
363
489
  runtime: DaemonRuntimeInfo;
364
490
  warnings: string[];
365
491
  reloadRequired?: boolean;
492
+ legacyReloadRequired?: boolean;
366
493
  } | {
367
494
  result: "blocked";
368
495
  runtime: DaemonRuntimeInfo;
@@ -73,6 +73,7 @@ export declare function buildActionMessage(action: {
73
73
  id: string;
74
74
  question?: string;
75
75
  options?: string[];
76
+ recommendedIndex?: unknown;
76
77
  controls?: readonly TelegramActionControl[];
77
78
  summary?: string;
78
79
  }): RenderedMessage;
@@ -81,6 +82,7 @@ export declare function buildActionMarkdown(action: {
81
82
  kind: "ask" | "idle";
82
83
  question?: string;
83
84
  options?: string[];
85
+ recommendedIndex?: unknown;
84
86
  summary?: string;
85
87
  }): string;
86
88
  /** Send Telegram HTML text chunks sequentially so long messages preserve order. */
@@ -5,7 +5,7 @@ export type ControlInput = Record<string, unknown>;
5
5
  * AgentSession and its controllers without exposing those concrete types here.
6
6
  */
7
7
  export interface ControlSurface {
8
- prompt(text: string, images?: ControlValue): Promise<ControlValue> | ControlValue;
8
+ prompt(text: string, images?: ControlValue, clientRef?: string): Promise<ControlValue> | ControlValue;
9
9
  steer(text: string): Promise<ControlValue> | ControlValue;
10
10
  followUp(text: string): Promise<ControlValue> | ControlValue;
11
11
  abort(): Promise<ControlValue> | ControlValue;
@@ -13,7 +13,7 @@ export interface SessionSdkHostOptions extends HostEndpointAdapters {
13
13
  onProviderDefinitionsRemoved?: (capability: string) => void;
14
14
  onReverseCancel?: (requestId: string, reason: "provider_disconnected" | "lease_released") => void;
15
15
  /** Best-effort capabilities mirrored from the native transport for out-of-band consumers. */
16
- connectionCapabilities?: (connectionId: string) => ReadonlySet<string>;
16
+ connectionCapabilities?: (connectionId: string) => ReadonlySet<string> | undefined;
17
17
  }
18
18
  /** SDK hosting is independent of notification configuration. Only root sessions host an endpoint. */
19
19
  export declare function shouldHostSdk(_settings: unknown, isTopLevel: boolean, env?: NodeJS.ProcessEnv): boolean;
@@ -31,6 +31,14 @@ export interface SessionSurface {
31
31
  totalBytes: number;
32
32
  } | undefined>;
33
33
  getJobs(): unknown | Promise<unknown>;
34
+ /** Q26 keyed lookup of a submitted prompt's authoritative reconciliation status. */
35
+ getPromptStatus?(selector: {
36
+ commandId?: string;
37
+ turnId?: string;
38
+ clientRef?: string;
39
+ }): unknown | Promise<unknown>;
40
+ /** Q27 effective model-profile catalog from the live session registry. */
41
+ getModelProfiles?(): unknown[] | Promise<unknown[]>;
34
42
  /** Query rows backed by the session's installed binding map. */
35
43
  installedQueries?: ReadonlySet<string>;
36
44
  }
@@ -57,6 +65,7 @@ export interface QueryResponse {
57
65
  code: string;
58
66
  message: string;
59
67
  restartQuery?: boolean;
68
+ details?: unknown;
60
69
  };
61
70
  }
62
71
  export declare class QueryHandlers {
@@ -1,7 +1,9 @@
1
+ export { MODEL_PROFILE_DISCOVERY_QUERY, MODEL_PROFILE_ERROR_DETAIL_MAX_BYTES, type ModelProfileCatalogItem, type ModelProfileErrorCode, type ModelProfileErrorDetails, ModelProfileRegistryError, type ModelProfileRegistryErrorDetails, type UnknownModelProfileDetails, UnknownModelProfileError, } from "../config/model-profile-contract";
1
2
  export * as bus from "./bus";
2
3
  export * from "./client";
3
4
  export * as host from "./host";
4
5
  export * as mcp from "./mcp";
5
6
  export type { Q10CurrentThinkingLevel, Q10Model, Q10SettableThinkingLevel, Q10ThinkingCapabilities, Q10ThinkingEffort, Q10ThinkingMode, } from "./models";
7
+ export * from "./prompt-status";
6
8
  export * from "./session";
7
9
  export * from "./session-directory";
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Public DTO contract for Q26 `turn.prompt_status` and the `clientRef`
3
+ * correlation field on `turn.prompt`.
4
+ *
5
+ * Semantics:
6
+ * - `turn.prompt` remains ordered and non-idempotent. An envelope
7
+ * `idempotencyKey` is ignored for replay/conflict purposes on ordered
8
+ * operations (no replay cache, no `idempotency_conflict`).
9
+ * - `clientRef` is a caller-chosen correlation key (trimmed, non-empty,
10
+ * 1..PROMPT_CLIENT_REF_MAX_LENGTH chars; one fresh value per logical prompt)
11
+ * mapped to the generated commandId/turnId at preflight acceptance so a
12
+ * caller can reconcile after a lost acknowledgement frame.
13
+ * - The clientRef index is scoped to one live session runtime: identical refs
14
+ * may coexist in different sessions, lookups never cross sessions, a ref
15
+ * conflicts only while its record is retained (`client_ref_conflict`), and
16
+ * after terminal TTL/capacity eviction a ref may be admitted again with the
17
+ * prior outcome unknown — callers MUST NOT reuse a clientRef as a retry
18
+ * mechanism and MUST treat `unknown` as uncertainty, not proof of
19
+ * non-execution.
20
+ * - The durability floor is the live session process: after restart or
21
+ * retained-record eviction, a lookup honestly reports `unknown`.
22
+ * - Q26 tracks prompts accepted through the SDK control surface (which always
23
+ * carries a requesting connection); submissions without a delivery owner are
24
+ * outside the reconciliation contract and hold no reservation.
25
+ */
26
+ export declare const PROMPT_CLIENT_REF_MAX_LENGTH = 128;
27
+ export interface TurnPromptImageInput {
28
+ data: string;
29
+ mimeType?: string;
30
+ }
31
+ /** Public input contract for ordered `turn.prompt`. */
32
+ export interface TurnPromptInput {
33
+ text: string;
34
+ images?: TurnPromptImageInput[];
35
+ clientRef?: string;
36
+ }
37
+ /** Terminal outcome is preserved exactly; active records never age into terminal. */
38
+ export type PromptReconciliationStatus = "accepted" | "in_flight" | "terminal_ok" | "failed";
39
+ /** Exactly one selector per lookup. */
40
+ export type TurnPromptStatusSelector = {
41
+ clientRef: string;
42
+ } | {
43
+ commandId: string;
44
+ turnId: string;
45
+ };
46
+ interface TurnPromptReconciliationIdentity {
47
+ commandId: string;
48
+ turnId: string;
49
+ clientRef?: string;
50
+ /** Epoch milliseconds of preflight acceptance. */
51
+ acceptedAt: number;
52
+ }
53
+ export interface TurnPromptReconciliationAccepted extends TurnPromptReconciliationIdentity {
54
+ status: "accepted";
55
+ }
56
+ export interface TurnPromptReconciliationInFlight extends TurnPromptReconciliationIdentity {
57
+ status: "in_flight";
58
+ /** Epoch milliseconds of the agent_start transition. */
59
+ startedAt: number;
60
+ }
61
+ export interface TurnPromptReconciliationTerminalOk extends TurnPromptReconciliationIdentity {
62
+ status: "terminal_ok";
63
+ startedAt?: number;
64
+ /** Epoch milliseconds of the terminal transition. */
65
+ terminalAt: number;
66
+ }
67
+ export interface TurnPromptReconciliationFailed extends TurnPromptReconciliationIdentity {
68
+ status: "failed";
69
+ startedAt?: number;
70
+ terminalAt: number;
71
+ /** Bounded, sanitized failure detail (code safe-token ≤64, message ≤512). */
72
+ error: {
73
+ code: string;
74
+ message: string;
75
+ };
76
+ }
77
+ export interface TurnPromptReconciliationUnknown {
78
+ status: "unknown";
79
+ }
80
+ export type TurnPromptReconciliation = TurnPromptReconciliationAccepted | TurnPromptReconciliationInFlight | TurnPromptReconciliationTerminalOk | TurnPromptReconciliationFailed | TurnPromptReconciliationUnknown;
81
+ /** Result of a successful `turn.prompt` preflight acknowledgement. */
82
+ export interface TurnPromptAcceptedResult {
83
+ commandId: string;
84
+ turnId: string;
85
+ accepted: true;
86
+ clientRef?: string;
87
+ }
88
+ export {};
@@ -20,7 +20,7 @@ export type ResolveManagedSessionScopeResult = {
20
20
  scope: ManagedSessionScope;
21
21
  } | {
22
22
  kind: "error";
23
- code: "cwd_missing" | "cwd_not_directory" | "identity_unavailable" | "network_unsupported" | "sessions_root_unavailable" | "binding_conflict" | "binding_invalid";
23
+ code: "cwd_missing" | "cwd_not_directory" | "identity_unavailable" | "network_unsupported" | "sessions_root_unavailable" | "binding_conflict" | "binding_invalid" | "atomic_unavailable" | "durability_not_provable" | "durability_failed" | "invalid_request";
24
24
  message: string;
25
25
  };
26
26
  export interface LogicalSessionCandidate {
@@ -1,9 +1,12 @@
1
+ import { type ModelProfileErrorCode, type ModelProfileErrorDetails } from "../config/model-profile-contract";
1
2
  export type SdkStartupPhase = "registration" | "startup";
2
3
  export type SdkStartupReason = "disabled" | "ineligible" | "factory_absent" | "runner_absent" | "pending" | "failed";
3
4
  export interface SdkStartupFailure {
4
5
  phase: SdkStartupPhase;
5
6
  reason: SdkStartupReason;
6
7
  message: string;
8
+ code?: ModelProfileErrorCode;
9
+ details?: ModelProfileErrorDetails;
7
10
  }
8
11
  export type SdkStartupResult = {
9
12
  status: "started";
@@ -542,6 +542,8 @@ export declare class AgentSession {
542
542
  * recorded or the mode-state file is missing/unreadable; callers should
543
543
  * treat undefined as a non-terminal phase (refuses to chain). */
544
544
  getActiveSkillPhase(): string | undefined;
545
+ /** Provider-facing ask metadata must expose only the active deep-interview phase. */
546
+ getDeepInterviewAskStage(): "topology" | "post-topology" | undefined;
545
547
  /** Peek the in-flight directive's invocation handler for use by the resolve tool. */
546
548
  peekQueueInvoker(): ((input: unknown) => Promise<unknown> | unknown) | undefined;
547
549
  peekStandingResolveHandler(): ((input: unknown) => Promise<unknown> | unknown) | undefined;
@@ -33,7 +33,7 @@ export declare function managedDirectoryIdentityForScope(scope: ManagedScope): {
33
33
  };
34
34
  export declare function managedRootForScope(scope: ManagedScope): ManagedDirectoryRoot;
35
35
  export type ManagedMigrationPolicy = "copy-retain" | "disabled";
36
- export type ManagedScopeErrorCode = "cwd_missing" | "cwd_not_directory" | "identity_unavailable" | "network_unsupported" | "sessions_root_unavailable" | "binding_conflict" | "binding_invalid";
36
+ export type ManagedScopeErrorCode = "cwd_missing" | "cwd_not_directory" | "identity_unavailable" | "network_unsupported" | "sessions_root_unavailable" | "binding_conflict" | "binding_invalid" | "atomic_unavailable" | "invalid_request" | "durability_failed" | "durability_not_provable";
37
37
  export type ManagedScopeResolution = {
38
38
  kind: "resolved";
39
39
  scope: ManagedScope;
@@ -41,6 +41,10 @@ export type ManagedScopeResolution = {
41
41
  kind: "error";
42
42
  code: ManagedScopeErrorCode;
43
43
  message: string;
44
+ cause?: {
45
+ readonly classification: string;
46
+ readonly diagnostic?: string;
47
+ };
44
48
  };
45
49
  export interface ManagedCandidate {
46
50
  sessionId: string;
@@ -63,7 +67,7 @@ export type ManagedCandidateListing = {
63
67
  code: "scan_failed" | "unsafe_root" | "invalid_candidate";
64
68
  message: string;
65
69
  };
66
- export type ManagedOpenFailure = "migration_busy" | "binding_conflict" | "binding_invalid" | "destination_conflict" | "source_changed" | "unsafe_artifacts" | "durability_failed" | "migration_retired" | "legacy_migration_disabled" | "managed_storage_unsupported";
70
+ export type ManagedOpenFailure = "migration_busy" | "binding_conflict" | "binding_invalid" | "destination_conflict" | "source_changed" | "unsafe_artifacts" | "durability_failed" | "atomic_unavailable" | "invalid_request" | "durability_not_provable" | "migration_retired" | "legacy_migration_disabled" | "managed_storage_unsupported";
67
71
  export type ManagedOpenCandidateResult = {
68
72
  kind: "opened";
69
73
  path: string;
@@ -80,6 +84,11 @@ export type ManagedDeleteCandidateResult = {
80
84
  } | {
81
85
  kind: "already_deleted";
82
86
  tombstonePath: string;
87
+ } | {
88
+ kind: "cleanup_pending";
89
+ tombstonePath: string;
90
+ phase: "artifacts" | "transcript";
91
+ message: string;
83
92
  } | {
84
93
  kind: "error";
85
94
  code: ManagedOpenFailure;
@@ -1,10 +1,18 @@
1
1
  import { type NativeDirectoryTreeSnapshot, type NativeOwnerOnlySecurityResult, type RecoveryFsRoot } from "@gajae-code/natives";
2
+ import { type NativePublishOutcome } from "./native-publish-outcome";
2
3
  export declare const MANAGED_ARTIFACT_MAX_DEPTH = 32;
3
4
  export declare const MANAGED_ARTIFACT_MAX_FILES = 10000;
4
5
  export declare const MANAGED_ARTIFACT_MAX_FILE_BYTES: number;
5
6
  export declare const MANAGED_ARTIFACT_MAX_TOTAL_BYTES: number;
7
+ export declare class ManagedPublishError extends Error {
8
+ readonly classification: "destination_conflict" | "atomic_unavailable" | "invalid_request" | "durability_not_provable" | "identity_mismatch" | "io_error" | "durability_failed";
9
+ readonly diagnostic: string;
10
+ constructor(classification: ManagedPublishError["classification"], outcome: NativePublishOutcome);
11
+ }
12
+ /** Cleanup is safe only when the native move reports that it did not commit. */
13
+ export declare function mayCleanManagedTreeStaging(error: unknown): boolean;
6
14
  export type ManagedSessionSecurityPolicy = "default" | "windows-existing-verify-first";
7
- export type ManagedStorageFailure = "migration_busy" | "binding_conflict" | "binding_invalid" | "destination_conflict" | "source_changed" | "unsafe_artifacts" | "durability_failed" | "migration_retired" | "managed_storage_unsupported";
15
+ export type ManagedStorageFailure = "migration_busy" | "binding_conflict" | "binding_invalid" | "destination_conflict" | "source_changed" | "unsafe_artifacts" | "durability_failed" | "atomic_unavailable" | "durability_not_provable" | "migration_retired" | "managed_storage_unsupported";
8
16
  export interface ManagedStorageLock {
9
17
  path: string;
10
18
  attemptId: string;
@@ -29,6 +37,13 @@ export interface ManagedDirectoryRoot {
29
37
  readonly dev: bigint;
30
38
  readonly ino: bigint;
31
39
  }
40
+ /**
41
+ * Establish the first managed directory beneath a potentially shared ancestor.
42
+ * The ancestor is used only to create the managed chain; every component from
43
+ * `configuredRoot` downward is independently type, symlink, owner, mode, and
44
+ * ACL checked. This deliberately does not impose owner-only policy on `/tmp`.
45
+ */
46
+ export declare function prepareManagedDirectoryRoot(configuredRoot: string, policy?: ManagedSessionSecurityPolicy): ManagedDirectoryRoot;
32
47
  export declare function managedDirectoryRoot(configuredRoot: string): ManagedDirectoryRoot;
33
48
  export declare function retainManagedDirectoryAuthority(root: ManagedDirectoryRoot, directory: string, expected?: {
34
49
  dev: bigint;
@@ -68,7 +83,7 @@ export declare class ManagedSessionDescendantStore {
68
83
  captureTree(relativePath: string): NativeDirectoryTreeSnapshot;
69
84
  /** Copy an exact captured tree into an absent managed destination. */
70
85
  importTree(sourceRelativePath: string, destinationRelativePath: string, snapshot: NativeDirectoryTreeSnapshot): Promise<void>;
71
- moveTreeNoReplace(sourceRelativePath: string, destinationRelativePath: string, expected: NativeDirectoryTreeSnapshot): void;
86
+ moveTreeNoReplace(sourceRelativePath: string, destinationRelativePath: string, expected: NativeDirectoryTreeSnapshot): NativeDirectoryTreeSnapshot;
72
87
  removeTreeExpected(relativePath: string, expected: NativeDirectoryTreeSnapshot): void;
73
88
  fsyncTree(): NativeDirectoryTreeSnapshot;
74
89
  }
@@ -0,0 +1,48 @@
1
+ export type NativePublishMutationState = "not_committed" | "committed" | "unknown";
2
+ export type NativePublishDurabilityState = "not_attempted" | "proven" | "not_provable";
3
+ export type NativePublishReason = "none" | "destination_exists" | "atomic_unavailable" | "cross_device" | "permission_denied" | "io_failure" | "interrupted" | "invalid_request" | "identity_violation" | "durability_not_provable" | "unknown";
4
+ export type NativePublishOperation = "direct_rename" | "retained_file" | "retained_tree";
5
+ export type NativePublishPrimitive = "renameat2_noreplace" | "renameatx_np_excl" | "windows_rename_noreplace" | "unsupported" | "unknown";
6
+ export type NativePublishPhase = "preflight" | "file_sync" | "rename" | "source_parent_sync" | "destination_parent_sync" | "terminal_identity" | "complete" | "unknown";
7
+ type SyncFailure = {
8
+ phase: Exclude<NativePublishPhase, "preflight" | "file_sync" | "rename" | "complete" | "unknown">;
9
+ parentRole: "source" | "destination" | "shared" | "staged_file";
10
+ osCode?: number;
11
+ kind: "unsupported" | "io" | "permission" | "other";
12
+ };
13
+ type PublishDiagnostic = {
14
+ schemaVersion: 1;
15
+ collectionState: "complete" | "partial" | "unavailable";
16
+ osCode?: number;
17
+ syncFailures?: readonly SyncFailure[];
18
+ };
19
+ export type NativePublishIdentity = {
20
+ readonly dev: string;
21
+ readonly ino: string;
22
+ readonly size: string;
23
+ readonly mtimeNs: string;
24
+ readonly ctimeNs: string;
25
+ readonly sha256?: string;
26
+ };
27
+ export type NativePublishOutcome = {
28
+ readonly ok: boolean;
29
+ readonly code?: string;
30
+ readonly identity?: NativePublishIdentity;
31
+ readonly mutationState: NativePublishMutationState;
32
+ readonly durabilityState: NativePublishDurabilityState;
33
+ readonly reason: NativePublishReason;
34
+ readonly primitive: NativePublishPrimitive;
35
+ readonly phase: NativePublishPhase;
36
+ readonly diagnostic: PublishDiagnostic;
37
+ };
38
+ /**
39
+ * Treat incompatible native results as an unknown mutation; never infer safety from legacy fields.
40
+ * Retained descriptor operations have a stricter contract than direct rename: a reported success
41
+ * includes the terminal identity and all required durability evidence.
42
+ */
43
+ export declare function classifyNativePublishOutcome(value: unknown, operation?: NativePublishOperation): NativePublishOutcome;
44
+ /** Only a fully validated pre-mutation result permits exact cleanup of current staging. */
45
+ export declare function mayCleanCurrentStaging(outcome: NativePublishOutcome): boolean;
46
+ /** Stable, bounded text for startup errors. Native paths and messages are intentionally excluded. */
47
+ export declare function formatNativePublishDiagnostic(outcome: NativePublishOutcome): string;
48
+ export {};
@@ -184,6 +184,18 @@ export interface VerifiedSessionDeleteTarget {
184
184
  detachedArtifactsPath?: string;
185
185
  /** Identity-bound quarantine path retained when transcript unlink deferred cleanup. */
186
186
  detachedTranscriptPath?: string;
187
+ /** Native-retained publisher successor observed during transcript cleanup. */
188
+ retainedTranscriptSuccessorPath?: string;
189
+ /** Native-retained exchange placeholder observed during transcript cleanup. */
190
+ retainedTranscriptPlaceholderPath?: string;
191
+ /** Native-retained transcript entry whose identity could not be verified. */
192
+ retainedTranscriptUnknownPath?: string;
193
+ /** Native-retained publisher successor observed during cleanup. */
194
+ retainedArtifactsSuccessorPath?: string;
195
+ /** Native-retained exchange placeholder observed during cleanup. */
196
+ retainedArtifactsPlaceholderPath?: string;
197
+ /** Native-retained entry whose identity could not be verified. */
198
+ retainedArtifactsUnknownPath?: string;
187
199
  /** Caller-published, no-replace quarantine pathname for the next artifact detach. */
188
200
  plannedArtifactsPath?: string;
189
201
  /** Caller-published, no-replace quarantine pathname for the next transcript detach. */
@@ -215,6 +227,9 @@ export type VerifiedSessionDeleteResult = {
215
227
  artifactsTree: NativeDirectoryTreeSnapshot;
216
228
  /** Transcript identity (unchanged) for retry binding. */
217
229
  transcriptIdentity: SessionStorageFileIdentity;
230
+ retainedSuccessorPath?: string;
231
+ retainedPlaceholderPath?: string;
232
+ retainedUnknownPath?: string;
218
233
  } | {
219
234
  kind: "cleanup_pending";
220
235
  phase: "transcript";
@@ -223,6 +238,9 @@ export type VerifiedSessionDeleteResult = {
223
238
  transcriptIdentity: SessionStorageFileIdentity;
224
239
  /** Optional identity-bound transcript quarantine path for restart cleanup. */
225
240
  detachedTranscriptPath?: string;
241
+ retainedSuccessorPath?: string;
242
+ retainedPlaceholderPath?: string;
243
+ retainedUnknownPath?: string;
226
244
  };
227
245
  type NativeDirectoryTreeEntry = {
228
246
  relativePath: string;
@@ -36,7 +36,9 @@ export declare class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskT
36
36
  get description(): string;
37
37
  private constructor();
38
38
  /**
39
- * Create a TaskTool instance with async agent discovery.
39
+ * Create a TaskTool instance.
40
+ * Repository authority is captured from session cwd *before* agent discovery so
41
+ * multi-repo workspaces fail closed prior to context/discovery (#2901).
40
42
  */
41
43
  static create(session: ToolSession): Promise<TaskTool>;
42
44
  execute(_toolCallId: string, rawParams: unknown, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback<TaskToolDetails>): Promise<AgentToolResult<TaskToolDetails>>;
@@ -59,6 +59,8 @@ export interface TaskResultReceipt {
59
59
  extractedToolCounts?: Record<string, number>;
60
60
  forkContext?: SingleResult["forkContext"];
61
61
  forkContextAdvisory?: SingleResult["forkContextAdvisory"];
62
+ /** Resolved repository identity for this delegated lane (#2901). */
63
+ repositoryBinding?: SingleResult["repositoryBinding"];
62
64
  roi?: TaskRoi;
63
65
  }
64
66
  /**