@gajae-code/coding-agent 0.12.0 → 0.12.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 (223) hide show
  1. package/CHANGELOG.md +82 -1
  2. package/dist/types/async/job-manager.d.ts +17 -3
  3. package/dist/types/config/settings-schema.d.ts +54 -0
  4. package/dist/types/exa/mcp-client.d.ts +10 -1
  5. package/dist/types/exec/bash-executor.d.ts +45 -12
  6. package/dist/types/extensibility/extensions/types.d.ts +16 -2
  7. package/dist/types/extensibility/gjc-plugins/index.d.ts +12 -2
  8. package/dist/types/extensibility/gjc-plugins/installer.d.ts +63 -7
  9. package/dist/types/extensibility/gjc-plugins/lifecycle-reconciliation.d.ts +55 -0
  10. package/dist/types/extensibility/gjc-plugins/lifecycle.d.ts +64 -0
  11. package/dist/types/extensibility/gjc-plugins/runtime-quarantine.d.ts +67 -0
  12. package/dist/types/extensibility/gjc-plugins/session-validation.d.ts +3 -1
  13. package/dist/types/extensibility/gjc-plugins/types.d.ts +124 -0
  14. package/dist/types/gjc-runtime/launch-tmux.d.ts +1 -0
  15. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +18 -0
  16. package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
  17. package/dist/types/gjc-runtime/team-runtime.d.ts +25 -0
  18. package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +43 -0
  19. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +10 -0
  20. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +31 -80
  21. package/dist/types/modes/acp/acp-agent.d.ts +2 -19
  22. package/dist/types/modes/components/gjc-bundle-settings.d.ts +34 -0
  23. package/dist/types/modes/components/notifications-settings-editor.d.ts +1 -0
  24. package/dist/types/modes/components/session-observer-overlay.d.ts +18 -0
  25. package/dist/types/modes/components/settings-selector.d.ts +9 -0
  26. package/dist/types/modes/components/status-line/gh.d.ts +5 -0
  27. package/dist/types/modes/components/transcript-viewer-overlay.d.ts +18 -1
  28. package/dist/types/reminders/star-reminder.d.ts +3 -13
  29. package/dist/types/runtime-mcp/manager.d.ts +1 -0
  30. package/dist/types/sdk/acp/adapter.d.ts +3 -1
  31. package/dist/types/sdk/broker/transport.d.ts +2 -0
  32. package/dist/types/sdk/bus/attachment-registry.d.ts +1 -0
  33. package/dist/types/sdk/bus/chat-daemon-control.d.ts +4 -1
  34. package/dist/types/sdk/bus/config.d.ts +6 -2
  35. package/dist/types/sdk/bus/index.d.ts +29 -0
  36. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +8 -1
  37. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
  38. package/dist/types/sdk/bus/reconciliation-store.d.ts +7 -3
  39. package/dist/types/sdk/bus/rich-draft.d.ts +1 -0
  40. package/dist/types/sdk/bus/rich-render.d.ts +2 -0
  41. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +165 -0
  42. package/dist/types/sdk/bus/telegram-cli.d.ts +12 -0
  43. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +11 -4
  44. package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -1
  45. package/dist/types/sdk/bus/telegram-reference.d.ts +11 -1
  46. package/dist/types/sdk/bus/threaded-render.d.ts +3 -2
  47. package/dist/types/sdk/bus/topic-registry.d.ts +11 -1
  48. package/dist/types/sdk/host/query/revision-store.d.ts +2 -0
  49. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  50. package/dist/types/sdk/prompt-status.d.ts +23 -3
  51. package/dist/types/sdk/session.d.ts +6 -0
  52. package/dist/types/session/agent-session.d.ts +38 -2
  53. package/dist/types/session/artifacts.d.ts +8 -0
  54. package/dist/types/session/blob-store.d.ts +57 -4
  55. package/dist/types/session/internal/managed-session-storage.d.ts +8 -1
  56. package/dist/types/session/session-manager.d.ts +23 -6
  57. package/dist/types/session/session-storage.d.ts +4 -0
  58. package/dist/types/session/streaming-output.d.ts +36 -7
  59. package/dist/types/setup/credential-import.d.ts +12 -0
  60. package/dist/types/skill-state/active-state.d.ts +12 -0
  61. package/dist/types/skill-state/workflow-hud.d.ts +6 -0
  62. package/dist/types/task/executor.d.ts +3 -2
  63. package/dist/types/task/index.d.ts +3 -1
  64. package/dist/types/task/provider-retry-status.d.ts +8 -0
  65. package/dist/types/task/receipt.d.ts +7 -1
  66. package/dist/types/task/types.d.ts +23 -0
  67. package/dist/types/tools/ask-answer-registry.d.ts +2 -2
  68. package/dist/types/tools/bash-interactive.d.ts +4 -1
  69. package/dist/types/tools/bash.d.ts +3 -1
  70. package/dist/types/tools/image-gen.d.ts +4 -0
  71. package/dist/types/tools/index.d.ts +4 -0
  72. package/dist/types/tools/output-meta.d.ts +23 -2
  73. package/dist/types/tools/path-utils.d.ts +1 -0
  74. package/dist/types/tools/read.d.ts +0 -6
  75. package/dist/types/tools/review.d.ts +5 -7
  76. package/dist/types/tools/subagent.d.ts +2 -0
  77. package/dist/types/utils/gh.d.ts +13 -0
  78. package/dist/types/utils/image-resize.d.ts +1 -0
  79. package/dist/types/web/search/providers/kimi.d.ts +2 -0
  80. package/dist/types/web/search/providers/searxng.d.ts +7 -0
  81. package/dist/types/web/search/providers/xai.d.ts +2 -0
  82. package/package.json +10 -8
  83. package/scripts/acp-conformance-agent.ts +218 -0
  84. package/scripts/capture-gjc-bundle-settings.ts +306 -0
  85. package/scripts/generate-sdk-operation-inventory.ts +3 -0
  86. package/scripts/resident-memory-bench.ts +1341 -0
  87. package/scripts/run-acp-conformance.ts +285 -0
  88. package/src/async/job-manager.ts +78 -20
  89. package/src/cli/fast-help.ts +1 -1
  90. package/src/cli/plugin-cli.ts +176 -18
  91. package/src/commands/team.ts +19 -1
  92. package/src/config/file-lock.ts +11 -2
  93. package/src/config/settings-schema.ts +51 -0
  94. package/src/coordinator-mcp/question-gate-codec.ts +1 -1
  95. package/src/coordinator-mcp/server.ts +5 -12
  96. package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -0
  97. package/src/defaults/gjc/skills/ralplan/SKILL.md +19 -16
  98. package/src/defaults/gjc/skills/team/SKILL.md +2 -0
  99. package/src/defaults/gjc/skills/ultragoal/SKILL.md +37 -24
  100. package/src/defaults/gjc/skills/ultragoal/validation-batch-contracts.md +12 -0
  101. package/src/defaults/gjc-defaults.ts +4 -4
  102. package/src/exa/mcp-client.ts +12 -3
  103. package/src/exec/bash-executor.ts +144 -27
  104. package/src/extensibility/extensions/runner.ts +15 -0
  105. package/src/extensibility/extensions/types.ts +18 -1
  106. package/src/extensibility/gjc-plugins/constrained-hooks.ts +8 -2
  107. package/src/extensibility/gjc-plugins/index.ts +19 -2
  108. package/src/extensibility/gjc-plugins/installer.ts +189 -50
  109. package/src/extensibility/gjc-plugins/lifecycle-reconciliation.ts +199 -0
  110. package/src/extensibility/gjc-plugins/lifecycle.ts +626 -0
  111. package/src/extensibility/gjc-plugins/observability.ts +3 -3
  112. package/src/extensibility/gjc-plugins/prompt-appendix.ts +5 -1
  113. package/src/extensibility/gjc-plugins/runtime-adapters.ts +12 -2
  114. package/src/extensibility/gjc-plugins/runtime-quarantine.ts +121 -0
  115. package/src/extensibility/gjc-plugins/schema.ts +84 -12
  116. package/src/extensibility/gjc-plugins/session-validation.ts +9 -3
  117. package/src/extensibility/gjc-plugins/types.ts +141 -0
  118. package/src/extensibility/gjc-plugins/validation.ts +9 -0
  119. package/src/gjc-runtime/launch-tmux.ts +25 -6
  120. package/src/gjc-runtime/managed-owner-admission.ts +1 -1
  121. package/src/gjc-runtime/ralplan-runtime.ts +411 -17
  122. package/src/gjc-runtime/team-launch.ts +8 -0
  123. package/src/gjc-runtime/team-runtime.ts +140 -32
  124. package/src/gjc-runtime/team-worker-heartbeat.ts +149 -0
  125. package/src/gjc-runtime/tmux-owner-isolation.ts +10 -0
  126. package/src/gjc-runtime/tmux-sessions.ts +58 -13
  127. package/src/gjc-runtime/ultragoal-runtime.ts +401 -611
  128. package/src/gjc-runtime/workflow-manifest.generated.json +8 -99
  129. package/src/gjc-runtime/workflow-manifest.ts +4 -68
  130. package/src/internal-urls/docs-index.generated.ts +15 -15
  131. package/src/modes/DESIGN.md +51 -0
  132. package/src/modes/acp/acp-agent.ts +298 -186
  133. package/src/modes/components/gjc-bundle-settings.ts +508 -0
  134. package/src/modes/components/notifications-settings-editor.ts +12 -1
  135. package/src/modes/components/oauth-selector.ts +68 -30
  136. package/src/modes/components/session-observer-overlay.ts +305 -86
  137. package/src/modes/components/settings-selector.ts +56 -5
  138. package/src/modes/components/status-line/gh.ts +16 -0
  139. package/src/modes/components/tool-status-header.ts +3 -14
  140. package/src/modes/components/transcript-viewer-overlay.ts +99 -24
  141. package/src/modes/controllers/command-controller.ts +4 -0
  142. package/src/modes/controllers/extension-ui-controller.ts +7 -0
  143. package/src/modes/controllers/selector-controller.ts +45 -0
  144. package/src/modes/runtime-init.ts +3 -0
  145. package/src/prompts/agent-fragments/ralplan-persistence.md +4 -3
  146. package/src/prompts/system/eager-todo.md +8 -4
  147. package/src/prompts/system/system-prompt.md +11 -4
  148. package/src/prompts/tools/bash.md +5 -5
  149. package/src/prompts/tools/search-tool-bm25.md +5 -0
  150. package/src/prompts/tools/task.md +1 -1
  151. package/src/reminders/star-reminder.ts +4 -42
  152. package/src/runtime-mcp/manager.ts +19 -4
  153. package/src/sdk/acp/adapter.ts +22 -6
  154. package/src/sdk/broker/transport.ts +35 -3
  155. package/src/sdk/bus/attachment-registry.ts +5 -1
  156. package/src/sdk/bus/chat-daemon-cli.ts +4 -39
  157. package/src/sdk/bus/chat-daemon-control.ts +6 -3
  158. package/src/sdk/bus/config.ts +18 -2
  159. package/src/sdk/bus/index.ts +661 -126
  160. package/src/sdk/bus/kind-aware-reconciliation.ts +148 -73
  161. package/src/sdk/bus/lifecycle-commands.ts +4 -1
  162. package/src/sdk/bus/lifecycle-control-runtime.ts +403 -88
  163. package/src/sdk/bus/reconciliation-store.ts +95 -16
  164. package/src/sdk/bus/rich-draft.ts +1 -1
  165. package/src/sdk/bus/rich-render.ts +2 -2
  166. package/src/sdk/bus/telegram-adoption-intent.ts +574 -0
  167. package/src/sdk/bus/telegram-cli.ts +33 -8
  168. package/src/sdk/bus/telegram-daemon-cli.ts +1 -0
  169. package/src/sdk/bus/telegram-daemon-contract.ts +11 -4
  170. package/src/sdk/bus/telegram-daemon.ts +916 -23
  171. package/src/sdk/bus/telegram-reference.ts +40 -3
  172. package/src/sdk/bus/threaded-render.ts +48 -3
  173. package/src/sdk/bus/topic-registry.ts +20 -0
  174. package/src/sdk/host/query/revision-store.ts +36 -2
  175. package/src/sdk/host/reverse-leases.ts +44 -7
  176. package/src/sdk/prompt-status.ts +16 -3
  177. package/src/sdk/protocol/operation-inventory.generated.json +22 -0
  178. package/src/sdk/session.ts +88 -9
  179. package/src/session/agent-session.ts +822 -172
  180. package/src/session/artifacts.ts +22 -0
  181. package/src/session/auth-broker-config.ts +10 -3
  182. package/src/session/blob-store.ts +915 -24
  183. package/src/session/internal/managed-session-scope.ts +44 -6
  184. package/src/session/internal/managed-session-storage.ts +48 -6
  185. package/src/session/session-manager.ts +1614 -435
  186. package/src/session/session-storage.ts +9 -1
  187. package/src/session/streaming-output.ts +238 -68
  188. package/src/setup/credential-import.ts +75 -13
  189. package/src/skill-state/active-state.ts +32 -0
  190. package/src/skill-state/workflow-hud.ts +17 -0
  191. package/src/skill-state/workflow-mutation-guard.ts +496 -2
  192. package/src/task/executor.ts +122 -39
  193. package/src/task/index.ts +23 -14
  194. package/src/task/provider-retry-status.ts +16 -0
  195. package/src/task/receipt.ts +23 -7
  196. package/src/task/render.ts +6 -2
  197. package/src/task/types.ts +108 -0
  198. package/src/tools/ask-answer-registry.ts +12 -6
  199. package/src/tools/ask.ts +86 -55
  200. package/src/tools/ast-edit.ts +1 -0
  201. package/src/tools/ast-grep.ts +1 -0
  202. package/src/tools/bash-interactive.ts +8 -3
  203. package/src/tools/bash.ts +503 -60
  204. package/src/tools/find.ts +1 -0
  205. package/src/tools/image-gen.ts +29 -5
  206. package/src/tools/index.ts +4 -0
  207. package/src/tools/output-meta.ts +108 -14
  208. package/src/tools/path-utils.ts +3 -2
  209. package/src/tools/read.ts +18 -0
  210. package/src/tools/review.ts +5 -7
  211. package/src/tools/search.ts +1 -0
  212. package/src/tools/subagent-render.ts +6 -2
  213. package/src/tools/subagent.ts +6 -0
  214. package/src/tools/telegram-send.ts +6 -3
  215. package/src/utils/gh.ts +39 -0
  216. package/src/utils/image-resize.ts +3 -0
  217. package/src/web/search/providers/anthropic.ts +4 -4
  218. package/src/web/search/providers/kimi.ts +15 -5
  219. package/src/web/search/providers/searxng.ts +47 -4
  220. package/src/web/search/providers/xai.ts +7 -2
  221. package/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +0 -23
  222. package/src/defaults/gjc/skills/ultragoal/pipeline-validation-contracts.md +0 -30
  223. package/src/gjc-runtime/ultragoal-pipeline.ts +0 -306
@@ -62,6 +62,7 @@ export interface TelegramDaemonFs {
62
62
  dev?: number;
63
63
  ino?: number;
64
64
  ctimeMs?: number;
65
+ isDirectory?: () => boolean;
65
66
  }>;
66
67
  readEndpointFile?(path: string): Promise<NotificationEndpointFile>;
67
68
  exactUnlink?(path: string, identity: NotificationEndpointFileIdentity): Promise<NotificationExactUnlinkResult>;
@@ -722,6 +723,8 @@ export interface TelegramDaemonOptions {
722
723
  enabled: boolean;
723
724
  };
724
725
  idleTimeoutMs?: number;
726
+ /** TTL for durable topic-adoption intents (default 10 minutes). Observed, not a fixed contract. */
727
+ adoptionIntentTtlMs?: number;
725
728
  scanIntervalMs?: number;
726
729
  pid?: number;
727
730
  /** Liveness probe for skipping dead-PID endpoint records in {@link TelegramNotificationDaemon.scanRoots}. */
@@ -758,6 +761,8 @@ export interface TelegramDaemonOptions {
758
761
  toolActivity?: {
759
762
  enabled: boolean;
760
763
  };
764
+ /** Controls which Telegram sends play an audible notification. Defaults to all. */
765
+ sound?: "all" | "important" | "none";
761
766
  /**
762
767
  * Per-session Telegram forum-topic naming. `nameTemplate` supports the
763
768
  * `{repo}`, `{branch}`, and `{title}` placeholders; unset preserves the
@@ -958,7 +963,7 @@ export declare class TelegramNotificationDaemon {
958
963
  private reserveSeenUpdateId;
959
964
  private releaseSeenUpdateId;
960
965
  scanRoots(): Promise<void>;
961
- connectSession(sessionId: string, url: string, token: string): void;
966
+ connectSession(sessionId: string, url: string, token: string): SessionSocket;
962
967
  /**
963
968
  * Start ack-based liveness for a session whose server advertised the
964
969
  * `client_ping_pong` capability. Each interval drops the session when no pong
@@ -1030,6 +1035,16 @@ export declare class TelegramNotificationDaemon {
1030
1035
  private deleteTopic;
1031
1036
  private persistTopics;
1032
1037
  loadTopics(): Promise<void>;
1038
+ /**
1039
+ * Rehydrate durable adoption intents after restart, then reconcile: a
1040
+ * non-expired sidecar whose target session already has a committed topic
1041
+ * record is a stale leftover (commit succeeded but sidecar cleanup failed)
1042
+ * and is removed safely without touching the user topic.
1043
+ */
1044
+ loadAdoptionIntents(): Promise<void>;
1045
+ /** Periodic sweep of expired adoption-intent sidecars (files only; no Telegram API). */
1046
+ private startAdoptionSweepTimer;
1047
+ private stopAdoptionSweepTimer;
1033
1048
  /** Retry crash-interrupted topic deletes; only a definite Telegram result clears the durable fence. */
1034
1049
  private reconcilePendingTopicDeletes;
1035
1050
  /** Download one Telegram file with the Bot API's 20 MiB ceiling and one end-to-end deadline. */
@@ -1117,6 +1132,15 @@ export declare class TelegramNotificationDaemon {
1117
1132
  handleSessionMessage(session: SessionSocket, msg: any): Promise<void>;
1118
1133
  private answerCallbackQueryBestEffort;
1119
1134
  private sendStaleGuidance;
1135
+ /**
1136
+ * Consume a user-created forum topic (`forum_topic_created` service message)
1137
+ * before edited/text routing. Authenticates the chat, user, privacy, and
1138
+ * lifecycle state; offers home, recent folders, or explicit path entry. The
1139
+ * selected path (or an exact `/session_create path <dir>`) creates a session
1140
+ * that adopts this topic — never a duplicate topic. Non-routable durable
1141
+ * intents prevent duplicate creation across concurrent first frames.
1142
+ */
1143
+ private handleForumTopicCreatedUpdate;
1120
1144
  /** Consume Telegram forum-topic rename service messages before text routing. */
1121
1145
  private handleForumTopicEdited;
1122
1146
  private processTelegramUpdate;
@@ -85,8 +85,17 @@ export declare function buildActionMarkdown(action: {
85
85
  recommendedIndex?: unknown;
86
86
  summary?: string;
87
87
  }): string;
88
+ export type TelegramNotificationSound = "all" | "important" | "none";
89
+ export type TelegramDeliveryLane = "ask" | "idle" | "live" | "finalized";
90
+ /**
91
+ * Resolve Telegram's optional silent-delivery flag. `finalChunk` silences
92
+ * non-final actionable chunks under the `important` policy; `undefined`
93
+ * intentionally omits the field so Telegram uses its normal audible delivery
94
+ * behavior.
95
+ */
96
+ export declare function telegramDisableNotification(sound: TelegramNotificationSound | undefined, lane: TelegramDeliveryLane, finalChunk?: boolean): true | undefined;
88
97
  /** Send Telegram HTML text chunks sequentially so long messages preserve order. */
89
- export declare function sendTelegramHtmlChunks(send: TelegramSend, chatId: string, text: string, inlineKeyboard?: InlineButton[][]): Promise<void>;
98
+ export declare function sendTelegramHtmlChunks(send: TelegramSend, chatId: string, text: string, inlineKeyboard?: InlineButton[][], sound?: TelegramNotificationSound, lane?: TelegramDeliveryLane): Promise<void>;
90
99
  /** A protocol `reply` frame the client should send to the server. */
91
100
  export interface ReplyFrame {
92
101
  type: "reply";
@@ -128,6 +137,7 @@ export interface TelegramReferenceOptions {
128
137
  endpointFile: string;
129
138
  apiBase?: string;
130
139
  fetchImpl?: typeof fetch;
140
+ sound?: TelegramNotificationSound;
131
141
  }
132
142
  /**
133
143
  * Run the reference bridge until the WebSocket closes. Sends `action_needed` to
@@ -14,13 +14,13 @@ export interface ThreadedSend {
14
14
  method: "sendMessage" | "sendPhoto" | "sendDocument";
15
15
  /** Rate-limit lane for prioritisation/fairness. */
16
16
  lane: RateLimitLane;
17
- /** Message text (sendMessage) or photo caption (sendPhoto). */
17
+ /** Message text (sendMessage) or media caption (sendPhoto/sendDocument). */
18
18
  text?: string;
19
19
  /** Base64 image bytes for sendPhoto. */
20
20
  photoBase64?: string;
21
21
  /** Base64 file bytes for sendDocument. */
22
22
  documentBase64?: string;
23
- /** Image MIME type for sendPhoto. */
23
+ /** Uploaded media MIME type. */
24
24
  mime?: string;
25
25
  /** Suggested document filename. */
26
26
  fileName?: string;
@@ -83,6 +83,7 @@ interface ThreadedFrame {
83
83
  status?: unknown;
84
84
  message?: unknown;
85
85
  }
86
+ export declare function supportsTelegramPhotoUpload(mime: string | undefined): boolean;
86
87
  /** Format the one-time identity header as pinned bullets. */
87
88
  export declare function formatIdentityHeader(frame: {
88
89
  repo?: unknown;
@@ -42,6 +42,8 @@ export interface TopicRecord {
42
42
  creationLeaseEpoch?: number;
43
43
  /** An uncertain delete fences future creation and inbound routing. */
44
44
  authorityState?: "active" | "delete_pending";
45
+ /** Provenance for topics created by the user and adopted by GJC. Missing means daemon-created. */
46
+ topicOrigin?: "user_created";
45
47
  /** Telegram chat and endpoint authority last proven to use this topic. */
46
48
  chatId?: string;
47
49
  /** Canonical endpoint tuple (URL + token) that currently holds the lease. */
@@ -129,6 +131,14 @@ export declare class TopicRegistry {
129
131
  authorityEpoch(sessionId: string): number;
130
132
  /** Whether this session has an active, unambiguous topic authority. */
131
133
  isActiveUnambiguous(sessionId: string): boolean;
134
+ /**
135
+ * Pure read-only availability check for user-topic adoption. Rejects invalid
136
+ * ids and any id already committed, delete-pending/fenced, staged, or
137
+ * ambiguous, without mutating maps, epochs, or persistence. Used inside the
138
+ * {@link getOrCreateTopic} create callback to fail-closed before adopting a
139
+ * user-created topic id.
140
+ */
141
+ isTopicIdAvailable(topicId: string): boolean;
132
142
  /**
133
143
  * Resolve endpoint authority for identity-less replay. An endpoint may bootstrap
134
144
  * only when no committed, staged, or pre-create claim can own it; malformed
@@ -153,7 +163,7 @@ export declare class TopicRegistry {
153
163
  * Return the existing active topic for `sessionId`, or create one via
154
164
  * `create` (called only on first use).
155
165
  */
156
- getOrCreateTopic(sessionId: string, create: () => Promise<unknown>, now?: () => number, name?: string, binding?: TopicEndpointBinding, commit?: () => Promise<void>, transientClaimant?: object): Promise<TopicRecord>;
166
+ getOrCreateTopic(sessionId: string, create: () => Promise<unknown>, now?: () => number, name?: string, binding?: TopicEndpointBinding, commit?: () => Promise<void>, transientClaimant?: object, topicOrigin?: TopicRecord["topicOrigin"]): Promise<TopicRecord>;
157
167
  /** Mark the identity header as sent for a session. Idempotent. */
158
168
  markIdentitySent(sessionId: string): void;
159
169
  /** Whether the identity header still needs sending for this session. */
@@ -1,3 +1,5 @@
1
+ /** Test seam: spill directories currently tracked for postmortem cleanup. */
2
+ export declare function trackedSpillDirectoriesForTest(): string[];
1
3
  export declare const MAX_REVISIONS_PER_RESOURCE = 8;
2
4
  export declare const MAX_PINNED_REVISIONS = 128;
3
5
  export declare const MAX_MEMORY_BYTES: number;
@@ -33,7 +33,7 @@ export declare class ReverseLeaseRuntime {
33
33
  heartbeat(connectionId: string, leaseId: string): ProviderLease;
34
34
  release(connectionId: string, leaseId: string, handoffTo?: string): ProviderLease;
35
35
  disconnect(connectionId: string): void;
36
- request(capability: string, method: string, payload: unknown): Promise<unknown>;
36
+ request(capability: string, method: string, payload: unknown, signal?: AbortSignal): Promise<unknown>;
37
37
  respond(connectionId: string, id: string, leaseId: string, result: unknown, error?: {
38
38
  code: string;
39
39
  message: string;
@@ -17,8 +17,10 @@
17
17
  * prior outcome unknown — callers MUST NOT reuse a clientRef as a retry
18
18
  * mechanism and MUST treat `unknown` as uncertainty, not proof of
19
19
  * non-execution.
20
- * - The durability floor is the live session process: after restart or
21
- * retained-record eviction, a lookup honestly reports `unknown`.
20
+ * - Prompt records survive process restart: an active prompt is finalized from its
21
+ * durable pending outcome, or as `prompt_failed` when it has none. Only skill
22
+ * records settle as `process_restart`, and a lookup reports `unknown` only after
23
+ * retained-record TTL/capacity eviction.
22
24
  * - Q26 tracks prompts accepted through the SDK control surface (which always
23
25
  * carries a requesting connection); submissions without a delivery owner are
24
26
  * outside the reconciliation contract and hold no reservation.
@@ -34,8 +36,24 @@ export interface TurnPromptInput {
34
36
  images?: TurnPromptImageInput[];
35
37
  clientRef?: string;
36
38
  }
37
- /** Terminal outcome is preserved exactly; active records never age into terminal. */
39
+ /**
40
+ * Terminal outcome is preserved exactly; active records never age into terminal. A
41
+ * prompt that is active at process restart is finalized from its durable pending
42
+ * outcome (or `prompt_failed` when it has none), so it never reports as unknown.
43
+ */
38
44
  export type PromptReconciliationStatus = "accepted" | "in_flight" | "terminal_ok" | "failed";
45
+ export type SdkPromptStopReason = "end_turn" | "max_tokens" | "max_turn_requests" | "refusal" | "cancelled";
46
+ export type SdkPromptFailureCode = "prompt_failed" | "prompt_deadline_exceeded";
47
+ export type SdkPromptTerminalOutcome = {
48
+ kind: "stopped";
49
+ reason: SdkPromptStopReason;
50
+ provenance: "agent" | "client_cancel";
51
+ } | {
52
+ kind: "failed";
53
+ code: SdkPromptFailureCode;
54
+ message: string;
55
+ provenance: "agent_failed" | "deadline";
56
+ };
39
57
  /** Exactly one selector per lookup. */
40
58
  export type TurnPromptStatusSelector = {
41
59
  clientRef: string;
@@ -63,6 +81,7 @@ export interface TurnPromptReconciliationTerminalOk extends TurnPromptReconcilia
63
81
  startedAt?: number;
64
82
  /** Epoch milliseconds of the terminal transition. */
65
83
  terminalAt: number;
84
+ outcome?: SdkPromptTerminalOutcome;
66
85
  }
67
86
  export interface TurnPromptReconciliationFailed extends TurnPromptReconciliationIdentity {
68
87
  status: "failed";
@@ -73,6 +92,7 @@ export interface TurnPromptReconciliationFailed extends TurnPromptReconciliation
73
92
  code: string;
74
93
  message: string;
75
94
  };
95
+ outcome?: SdkPromptTerminalOutcome;
76
96
  }
77
97
  export interface TurnPromptReconciliationUnknown {
78
98
  status: "unknown";
@@ -12,6 +12,7 @@ import type { CustomCommandsLoadResult } from "../extensibility/custom-commands"
12
12
  import type { CustomTool } from "../extensibility/custom-tools/types";
13
13
  import { type ExtensionFactory, type ExtensionUIContext, type LoadExtensionsResult, type ToolDefinition } from "../extensibility/extensions";
14
14
  import { type ConstrainedPluginHook } from "../extensibility/gjc-plugins/constrained-hooks";
15
+ import { type GjcRuntimeSnapshotProvider } from "../extensibility/gjc-plugins/runtime-quarantine";
15
16
  import { type Skill, type SkillWarning } from "../extensibility/skills";
16
17
  import type { FileSlashCommand } from "../extensibility/slash-commands";
17
18
  import type { HindsightSessionState } from "../hindsight/state";
@@ -207,6 +208,11 @@ export interface CreateAgentSessionResult {
207
208
  lspServers?: LspStartupServerInfo[];
208
209
  /** Shared event bus for tool/extension communication */
209
210
  eventBus: EventBus;
211
+ /**
212
+ * Read-only view of GJC bundle runtime evidence for the activation generation
213
+ * this session published. Undefined when no GJC bundles participated.
214
+ */
215
+ gjcRuntimeSnapshot?: GjcRuntimeSnapshotProvider;
210
216
  }
211
217
  export type { PromptTemplate } from "../config/prompt-templates";
212
218
  export { Settings, type SkillsSettings } from "../config/settings";
@@ -12,7 +12,7 @@
12
12
  *
13
13
  * Modes use this class and add their own I/O layer on top.
14
14
  */
15
- import { type Agent, type AgentContext, type AgentEvent, type AgentLoopConfig, type AgentMessage, type AgentState, type AgentTool, type MidRunMaintenanceOutcome, type StablePrefixSnapshot, ThinkingLevel } from "@gajae-code/agent-core";
15
+ import { type Agent, type AgentContext, type AgentEvent, type AgentLoopConfig, type AgentMessage, type AgentState, type AgentTool, type MidRunMaintenanceOutcome, type RunSettlementProof, type StablePrefixSnapshot, ThinkingLevel } from "@gajae-code/agent-core";
16
16
  import { type CompactionResult, type EmergencyCompactionSample } from "@gajae-code/agent-core/compaction";
17
17
  import type { AssistantMessage, Effort, ImageContent, Message, MessageAttribution, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, TextContent, ToolCall, ToolChoice, Usage, UsageReport } from "@gajae-code/ai";
18
18
  import { type BtwTextExchange } from "./btw-contract";
@@ -75,16 +75,18 @@ import { type PromptTemplate } from "../config/prompt-templates";
75
75
  import type { Settings, SkillsSettings } from "../config/settings";
76
76
  import { RawSseDebugBuffer } from "../debug/raw-sse-buffer";
77
77
  import { type PythonResult } from "../eval/py/executor";
78
- import { type BashResult } from "../exec/bash-executor";
78
+ import { type BashArtifactSaveResult, type BashResult } from "../exec/bash-executor";
79
79
  import type { TtsrManager } from "../export/ttsr";
80
80
  import type { LoadedCustomCommand } from "../extensibility/custom-commands";
81
81
  import type { CustomTool } from "../extensibility/custom-tools/types";
82
82
  import type { ExtensionRunner } from "../extensibility/extensions";
83
83
  import type { CompactOptions, ContextUsage, ExtensionTranscriptEntry } from "../extensibility/extensions/types";
84
+ import type { GjcRuntimeSnapshotProvider } from "../extensibility/gjc-plugins/runtime-quarantine";
84
85
  import type { SessionSwitchEvent } from "../extensibility/shared-events";
85
86
  import { type Skill, type SkillWarning } from "../extensibility/skills";
86
87
  import { type FileSlashCommand } from "../extensibility/slash-commands";
87
88
  import { type MemoryGuardClaimsLease } from "../gjc-runtime/memory-guard-owner-claims";
89
+ import { GjcTeamWorkerHeartbeatReporter } from "../gjc-runtime/team-worker-heartbeat";
88
90
  import { GoalRuntime } from "../goals/runtime";
89
91
  import type { Goal, GoalModeState } from "../goals/state";
90
92
  import type { HindsightSessionState } from "../hindsight/state";
@@ -208,6 +210,11 @@ export interface AgentSessionConfig {
208
210
  workerIntegrationRequest?: (signal: AbortSignal) => Promise<void>;
209
211
  /** Bound terminal worker-integration settlement for embedded hosts and deterministic lifecycle tests. */
210
212
  workerIntegrationTimeoutMs?: number;
213
+ /**
214
+ * Override the runtime-owned `gjc team` worker heartbeat reporter. Defaults to a
215
+ * reporter derived from the team worker environment, or none outside a worker pane.
216
+ */
217
+ teamWorkerHeartbeatReporter?: GjcTeamWorkerHeartbeatReporter;
211
218
  /** Loaded skills (already discovered by SDK) */
212
219
  skills?: Skill[];
213
220
  /** Skill loading warnings (already captured by SDK) */
@@ -466,6 +473,11 @@ interface EphemeralTurnResult {
466
473
  replyText: string;
467
474
  assistantMessage: AssistantMessage;
468
475
  }
476
+ export interface AgentBashArtifactStore {
477
+ saveArtifact(content: string, toolType: string): Promise<string | undefined>;
478
+ getArtifactPath(id: string): Promise<string | null>;
479
+ }
480
+ export declare function saveAgentBashOriginalArtifact(store: AgentBashArtifactStore, originalText: string): Promise<BashArtifactSaveResult>;
469
481
  type IrcRosterClaim = {
470
482
  token: symbol;
471
483
  signature: string;
@@ -786,6 +798,8 @@ export declare class AgentSession {
786
798
  * to avoid racing against the delivery turn.
787
799
  */
788
800
  get hasPostPromptWork(): boolean;
801
+ /** Stable resource ownership identifier for the active prompt run. */
802
+ get activePromptHandle(): string | undefined;
789
803
  /** All messages including custom types like BashExecutionMessage */
790
804
  get messages(): AgentMessage[];
791
805
  get transcriptPromptGeneration(): number;
@@ -980,6 +994,12 @@ export declare class AgentSession {
980
994
  cause?: "user_interrupt" | "new_session" | "session_switch" | "compaction" | "handoff" | "tool_abort" | "internal";
981
995
  silent?: boolean;
982
996
  }): Promise<void>;
997
+ /**
998
+ * Abort a specific active prompt and prove whether its tracked resources settled.
999
+ */
1000
+ abortPromptAndWait(handle: string, options: {
1001
+ graceMs: number;
1002
+ }): Promise<RunSettlementProof>;
983
1003
  /** Atomically interrupt the active run and make text the next prompt. */
984
1004
  cancelAndSubmit(text: string, options?: {
985
1005
  queuedEntryId?: string;
@@ -1048,6 +1068,13 @@ export declare class AgentSession {
1048
1068
  * instead of promoting a transient runtime model to the resume default.
1049
1069
  */
1050
1070
  getSessionDefaultModelSelector(): string | undefined;
1071
+ /**
1072
+ * Resolve the model that `modelRoles.default` currently points to, independent
1073
+ * of whatever model this session's log last recorded. Used by the TUI resume
1074
+ * flow's `session.resumeModelBehavior: "ask"` prompt to offer the currently
1075
+ * configured default as an alternative to the session's saved model.
1076
+ */
1077
+ resolveConfiguredDefaultModel(): Model | undefined;
1051
1078
  /**
1052
1079
  * Re-assert the session resume default ("provider/id") in the session log
1053
1080
  * WITHOUT touching the live runtime model. Appends a `model_change` with
@@ -1157,6 +1184,15 @@ export declare class AgentSession {
1157
1184
  * Get available thinking levels for current model.
1158
1185
  */
1159
1186
  getAvailableThinkingLevels(): ReadonlyArray<Effort>;
1187
+ /**
1188
+ * Runtime evidence published for the current GJC bundle activation
1189
+ * generation, set once by `createAgentSession` after every producer has run.
1190
+ * Undefined until that publication happens, so consumers report runtime
1191
+ * status as unavailable rather than falsely clear.
1192
+ */
1193
+ gjcRuntimeSnapshot?: GjcRuntimeSnapshotProvider;
1194
+ /** Activation generation a published snapshot must match to be merged. */
1195
+ gjcActivationGeneration?: number;
1160
1196
  /**
1161
1197
  * Set steering mode.
1162
1198
  * Saves to settings.
@@ -45,6 +45,14 @@ export declare class ArtifactManager {
45
45
  replaceNamedBytes(filename: string, bytes: Uint8Array): Promise<void>;
46
46
  publishManagedOutputGeneration(selectorFilename: string, outputFilenamePrefix: string, outputBytes: Uint8Array, metadataBytes: Uint8Array): Promise<void>;
47
47
  publishNamedNoReplace(filename: string, bytes: Uint8Array): Promise<void>;
48
+ /**
49
+ * Best-effort removal of a previously published named artifact. Used to roll
50
+ * back staged publications when a transactional operation (e.g. gated
51
+ * maintenance pruning) is rejected after publication succeeded. Returns false
52
+ * when the artifact could not be removed so callers can log the failure
53
+ * instead of silently treating the rollback as complete.
54
+ */
55
+ removeNamedBestEffort(filename: string): Promise<boolean>;
48
56
  /**
49
57
  * Atomically allocate next artifact ID.
50
58
  * IDs are sequential within the session.
@@ -1,3 +1,9 @@
1
+ declare const TAKE_BLOB_BUFFER_OWNERSHIP: unique symbol;
2
+ /** Limits for a single best-effort resident-cache garbage-collection pass. */
3
+ export interface ResidentCacheGcSweepOptions {
4
+ readonly maxDirectories?: number;
5
+ readonly maxDurationMs?: number;
6
+ }
1
7
  export interface BlobPutResult {
2
8
  hash: string;
3
9
  path: string;
@@ -11,6 +17,28 @@ export declare class BlobCorruptError extends Error {
11
17
  readonly path: string;
12
18
  constructor(hash: string, path: string);
13
19
  }
20
+ /**
21
+ * A resident-cache path or blob failed the owner-only verification contract.
22
+ * SessionManager catches this error to demote the entire resident store to
23
+ * memory before retrying the triggering write.
24
+ */
25
+ export declare class ResidentCacheTrustError extends Error {
26
+ readonly reason: string;
27
+ readonly path: string;
28
+ constructor(reason: string, path: string, options?: ErrorOptions);
29
+ }
30
+ /**
31
+ * Best-effort cleanup of abandoned resident-cache instances. The root is
32
+ * re-verified before scanning, work is bounded, and all failures fail closed.
33
+ */
34
+ export declare function sweepResidentCacheRoot(root: string, options?: ResidentCacheGcSweepOptions): Promise<void>;
35
+ /**
36
+ * Create a private resident-cache instance directory beneath a trusted profile
37
+ * root. The cache-owned root and nonce instance are both verified owner-only
38
+ * directories; callers must use {@link EphemeralBlobStore.adoptVerifiedDir}
39
+ * rather than the destructive EphemeralBlobStore constructor.
40
+ */
41
+ export declare function openVerifiedResidentCacheInstanceDir(root: string): string;
14
42
  /**
15
43
  * Content-addressed blob store for externalizing large binary data (images) from session JSONL files.
16
44
  *
@@ -31,7 +59,13 @@ export declare class BlobStore {
31
59
  * cannot afford the microtask hops of the async version (e.g. OOM-safe session writes).
32
60
  * Returns once the bytes are in the kernel page cache.
33
61
  */
34
- putSync(data: Buffer): BlobPutResult;
62
+ putSync(data: Buffer, _ownership?: typeof TAKE_BLOB_BUFFER_OWNERSHIP): BlobPutResult;
63
+ /**
64
+ * Store a buffer that the caller will not mutate after this call returns.
65
+ * Resident-cache implementations may retain that private buffer without an
66
+ * additional defensive copy.
67
+ */
68
+ putOwnedSync(data: Buffer): BlobPutResult;
35
69
  /**
36
70
  * Durably install binary data as an immutable content-addressed blob.
37
71
  *
@@ -51,19 +85,37 @@ export declare class BlobStore {
51
85
  /** Check if a blob exists. */
52
86
  has(hash: string): Promise<boolean>;
53
87
  }
88
+ interface EphemeralBlobStoreOptions {
89
+ readonly adoptVerifiedDir?: boolean;
90
+ }
91
+ /** Resident-cache directories still tracked by this process. Test seam. */
92
+ export declare function trackedResidentCacheDirsForTest(): string[];
54
93
  export declare class EphemeralBlobStore extends BlobStore {
55
94
  #private;
56
- constructor(dir: string);
57
- putSync(data: Buffer): BlobPutResult;
95
+ constructor(dir: string, options?: EphemeralBlobStoreOptions);
96
+ /**
97
+ * Adopt a directory returned by {@link openVerifiedResidentCacheInstanceDir}
98
+ * without the ordinary constructor's destructive remove-and-recreate path.
99
+ */
100
+ static adoptVerifiedDir(dir: string): EphemeralBlobStore;
101
+ put(data: Buffer): Promise<BlobPutResult>;
102
+ putSync(data: Buffer, ownership?: typeof TAKE_BLOB_BUFFER_OWNERSHIP): BlobPutResult;
58
103
  putImmutableSync(data: Buffer): CheckedBlobPutResult;
104
+ get(hash: string): Promise<Buffer | null>;
59
105
  getSync(hash: string): Buffer | null;
106
+ /** Return a trusted in-memory copy without reopening an invalidated cache path. */
107
+ getBufferedSync(hash: string): Buffer | null;
60
108
  getCheckedSync(hash: string): Buffer | null;
61
109
  clear(): void;
62
110
  dispose(): void;
63
111
  }
112
+ export interface MemoryBlobStoreOptions {
113
+ /** A canonical store owns every reference in its session's resident entries. */
114
+ readonly ownership?: "cache" | "canonical";
115
+ }
64
116
  export declare class MemoryBlobStore extends BlobStore {
65
117
  #private;
66
- constructor();
118
+ constructor(options?: MemoryBlobStoreOptions);
67
119
  put(data: Buffer): Promise<BlobPutResult>;
68
120
  putSync(data: Buffer): BlobPutResult;
69
121
  putImmutableSync(data: Buffer): CheckedBlobPutResult;
@@ -158,3 +210,4 @@ export declare function resolveResidentImageDataSync(blobStore: BlobStore, data:
158
210
  sessionId?: string;
159
211
  sessionFile?: string;
160
212
  }): string;
213
+ export {};
@@ -51,19 +51,26 @@ export declare function retainManagedDirectoryAuthority(root: ManagedDirectoryRo
51
51
  ino: bigint;
52
52
  }): RecoveryFsRoot | undefined;
53
53
  export declare function assertManagedDirectoryRoot(root: ManagedDirectoryRoot): void;
54
+ export declare function managedSecurityFailureClassification(error: unknown): string | undefined;
54
55
  /** Internal retained-root capability for one managed descendant subtree. */
55
56
  export declare class ManagedSessionDescendantStore {
56
57
  #private;
57
58
  constructor(root: ManagedDirectoryRoot, baseDir: string, retained?: {
58
59
  authority: RecoveryFsRoot;
59
60
  authorityBaseDir: string;
60
- }, policy?: ManagedSessionSecurityPolicy);
61
+ }, policy?: ManagedSessionSecurityPolicy, profileAgentDir?: string);
61
62
  get dir(): string;
62
63
  get rootAuthority(): ManagedDirectoryRoot;
63
64
  get subtreeRootAuthority(): ManagedDirectoryRoot;
64
65
  get securityPolicy(): ManagedSessionSecurityPolicy;
66
+ get profileAgentDir(): string;
65
67
  deriveSubtree(relativePath: string): ManagedSessionDescendantStore;
66
68
  retainAuthority(): RecoveryFsRoot | undefined;
69
+ /**
70
+ * Release an authority this store opened itself. Retained authorities are owned by
71
+ * the security context that supplied them and are never closed here. Idempotent.
72
+ */
73
+ close(): void;
67
74
  assertBound(): void;
68
75
  verifyRootSecurity(): void;
69
76
  ensureDirectory(relativePath?: string): ManagedDirectoryRoot;
@@ -72,11 +72,16 @@ export interface SessionManagerObservabilityStats {
72
72
  coldSpillReadCount: number;
73
73
  residentTextReadCount: number;
74
74
  residentImageReadCount: number;
75
+ residentCacheAdoptFallbackCount: number;
76
+ residentCacheTrustRejectCount: number;
77
+ residentCacheWin32FallbackCount: number;
78
+ residentCacheDegradedReason?: string;
75
79
  publicMaterializerCallCount: number;
76
80
  getEntryMaterializerCallCount: number;
77
81
  getBranchMaterializerCallCount: number;
78
82
  getEntriesMaterializerCallCount: number;
79
83
  materializedEntriesCachePopulateCount: number;
84
+ materializedCacheDemotedCount: number;
80
85
  pathOnlyContextBuildCount: number;
81
86
  }
82
87
  export interface SessionMessageEntry extends SessionEntryBase {
@@ -506,12 +511,17 @@ export type SessionDestination = {
506
511
  readonly directory: string;
507
512
  };
508
513
  export type SessionDestinationInput = string | SessionDestination | undefined;
509
- interface ForkArtifactPublication {
514
+ type ForkArtifactPublication = {
515
+ readonly kind: "managed";
510
516
  readonly snapshot: native.NativeDirectoryTreeSnapshot;
511
517
  readonly store: ManagedSessionDescendantStore;
512
518
  readonly cleanupStore: ManagedSessionDescendantStore;
513
519
  readonly cleanupRelativePath: string;
514
- }
520
+ } | {
521
+ readonly kind: "explicit";
522
+ readonly artifactsDir: string;
523
+ readonly snapshot: native.NativeDirectoryTreeSnapshot;
524
+ };
515
525
  /** Exported for testing */
516
526
  export declare function loadEntriesFromFile(filePath: string, storage?: SessionStorage): Promise<FileEntry[]>;
517
527
  declare class RecentSessionInfo {
@@ -596,6 +606,13 @@ interface SessionManagerStateSnapshot {
596
606
  fileEntries: FileEntry[];
597
607
  materializedFileEntries: FileEntry[];
598
608
  }
609
+ /** Benchmark-derived cap for strong materialized session snapshots. */
610
+ export declare const MATERIALIZED_CACHE_MAX_BYTES: number;
611
+ /** Test-only cache retention and transition seams; these are intentionally not user settings. */
612
+ export declare const SessionManagerTestHooks: {
613
+ materializedCacheMaxBytesOverride?: number;
614
+ beforeResidentTransitionIndexBuild?: () => void;
615
+ };
599
616
  export declare class SessionManager {
600
617
  #private;
601
618
  private cwd;
@@ -614,7 +631,7 @@ export declare class SessionManager {
614
631
  putBlob(data: Buffer): Promise<BlobPutResult>;
615
632
  captureState(): SessionManagerStateSnapshot;
616
633
  restoreState(snapshot: SessionManagerStateSnapshot): void;
617
- /** Switch to a different session file (used for resume and branching) */
634
+ /** Switch to a different session file (used for resume and branching). */
618
635
  setSessionFile(sessionFile: string): Promise<void>;
619
636
  /** Start a new session. Closes any existing writer first. */
620
637
  newSession(options?: NewSessionOptions): Promise<string | undefined>;
@@ -652,9 +669,9 @@ export declare class SessionManager {
652
669
  * managed logical authorization. This is only for discarding an UNCOMMITTED
653
670
  * successor that a transaction (e.g. handoff) created via `newSession()` but
654
671
  * never durably authorized — such a session has no managed candidate listing
655
- * yet, so `dropSession` would refuse it and leak its resident-cache/artifact
656
- * root. Bounded to this manager's configured session root and refuses to touch
657
- * the active session; tolerates missing files.
672
+ * yet, so `dropSession` would refuse it and leak its artifact root. Bounded to
673
+ * this manager's configured session root and refuses to touch the active session;
674
+ * tolerates missing files.
658
675
  */
659
676
  discardUncommittedSession(sessionPath: string): Promise<void>;
660
677
  /**
@@ -61,6 +61,8 @@ export interface SessionStorageWriterOpenOptions {
61
61
  export interface ManagedSessionSecurityContext {
62
62
  readonly kind: "managed";
63
63
  readonly agentDir: string;
64
+ /** Logical profile root for process-local caches; distinct from managed pathname authority. */
65
+ readonly profileAgentDir: string;
64
66
  readonly sessionsRoot: string;
65
67
  readonly sessionDir: string;
66
68
  readonly rootAuthority: ManagedDirectoryRoot;
@@ -69,6 +71,8 @@ export interface ManagedSessionSecurityContext {
69
71
  /** @internal Create the only accepted managed writer authority object. */
70
72
  export declare function createManagedSessionSecurityContext(input: {
71
73
  agentDir: string;
74
+ /** Optional for compatibility with existing authority-only callers. */
75
+ profileAgentDir?: string;
72
76
  sessionsRoot: string;
73
77
  sessionDir: string;
74
78
  rootAuthority: ManagedDirectoryRoot;
@@ -3,6 +3,29 @@ export declare const DEFAULT_MAX_LINES = 3000;
3
3
  export declare const DEFAULT_MAX_BYTES: number;
4
4
  export declare const DEFAULT_MAX_COLUMN = 1024;
5
5
  export declare const DEFAULT_ARTIFACT_MAX_BYTES: number;
6
+ /**
7
+ * Terminal publisher used when managed artifact storage exposes an ID but no
8
+ * writable pathname. The sink supplies raw content retained up to its artifact
9
+ * hard cap; `omittedBytes` is the source-byte count already omitted by that cap.
10
+ * A successful publisher may report additional omitted bytes (for example, a
11
+ * downstream storage cap); those counts are added to the sink summary. Failed
12
+ * and unavailable results are surfaced through the bounded artifact diagnostic
13
+ * without exposing an unresolvable artifact URL.
14
+ */
15
+ export type TerminalArtifactPublishResult = {
16
+ status: "published";
17
+ artifactId: string;
18
+ omittedBytes?: number;
19
+ } | {
20
+ status: "unavailable";
21
+ } | {
22
+ status: "failed";
23
+ diagnostic: string;
24
+ };
25
+ export type TerminalArtifactPublisher = (content: string, info: {
26
+ totalBytes: number;
27
+ omittedBytes: number;
28
+ }) => Promise<TerminalArtifactPublishResult>;
6
29
  export interface OutputSummary {
7
30
  output: string;
8
31
  truncated: boolean;
@@ -18,10 +41,12 @@ export interface OutputSummary {
18
41
  columnDroppedBytes?: number;
19
42
  /** Number of distinct lines that hit the per-line column cap. */
20
43
  columnTruncatedLines?: number;
21
- /** Artifact ID for internal URL access (artifact://<id>) when truncated */
44
+ /** Artifact ID for internal URL access (artifact://<id>) when output was persisted. */
22
45
  artifactId?: string;
23
46
  /** Bytes omitted from artifact storage after the artifact hard cap was reached. */
24
47
  artifactTruncatedBytes?: number;
48
+ /** Bounded diagnostic when artifact writer or terminal publisher creation, write, finalization, or publication failed. */
49
+ artifactFailureDiagnostic?: string;
25
50
  }
26
51
  export interface OutputSinkOptions {
27
52
  /**
@@ -30,6 +55,12 @@ export interface OutputSinkOptions {
30
55
  */
31
56
  artifactPath?: string;
32
57
  artifactId?: string;
58
+ /**
59
+ * Optional terminal publisher for managed artifact stores that do not expose a
60
+ * writable path. It is invoked only when visible spill/truncation requires an
61
+ * artifact, and receives raw content bounded by `artifactMaxBytes`.
62
+ */
63
+ artifactPublisher?: TerminalArtifactPublisher;
33
64
  /** Tail buffer budget (bytes). Default DEFAULT_MAX_BYTES. */
34
65
  spillThreshold?: number;
35
66
  /**
@@ -241,12 +272,10 @@ export declare class OutputSink {
241
272
  * minimizer rewrites the captured output after the raw bytes have already
242
273
  * been streamed.
243
274
  *
244
- * After this call the buffer is authoritative: streaming counters realign
245
- * to the replacement, the retained head window is cleared, and head
246
- * retention is disabled so subsequent `push()` calls append directly to the
247
- * tail buffer instead of repopulating the (now meaningless) head window
248
- * — which would otherwise reorder content and trip the middle-elision
249
- * branch in `dump()` against stale totals.
275
+ * After this call the replacement is authoritative: counters reflect its full
276
+ * size, the configured head+tail byte windows are retained with UTF-8-safe
277
+ * boundaries, and future head accumulation is disabled so later `push()` calls
278
+ * append directly to the tail without reordering the replacement.
250
279
  */
251
280
  replace(text: string): void;
252
281
  dump(notice?: string): Promise<OutputSummary>;