@astrosheep/keiyaku 2.8.4 → 2.9.0

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 (229) hide show
  1. package/README.md +35 -15
  2. package/build/.tsbuildinfo +1 -1
  3. package/build/agents/{call-terms_v2.js → call-terms.js} +12 -8
  4. package/build/agents/harness/control-types.js +1 -0
  5. package/build/agents/harness/execution-handle.js +23 -3
  6. package/build/agents/harness/index.js +6 -607
  7. package/build/agents/harness/outcome.js +141 -0
  8. package/build/agents/harness/projection.js +310 -0
  9. package/build/agents/harness/router.js +201 -0
  10. package/build/agents/harness/runtime.js +2 -1
  11. package/build/agents/{launch-snapshot_v2.js → launch-snapshot/model.js} +69 -74
  12. package/build/agents/launch-snapshot/resolve.js +72 -0
  13. package/build/agents/opencode-sdk.js +24 -3
  14. package/build/agents/providers/{claude-agent-sdk.js → claude-agent-sdk/adapter.js} +46 -368
  15. package/build/agents/providers/claude-agent-sdk/events.js +218 -0
  16. package/build/agents/providers/claude-agent-sdk/session.js +158 -0
  17. package/build/agents/providers/codex-app-server/adapter.js +347 -0
  18. package/build/agents/providers/codex-app-server/events.js +352 -0
  19. package/build/agents/providers/codex-app-server/session.js +266 -0
  20. package/build/agents/providers/codex-sdk.js +23 -5
  21. package/build/agents/providers/opencode-sdk/adapter.js +344 -0
  22. package/build/agents/providers/opencode-sdk/events.js +354 -0
  23. package/build/agents/providers/opencode-sdk/session.js +180 -0
  24. package/build/agents/providers/pi/adapter.js +269 -0
  25. package/build/agents/providers/pi/checkpoint.js +41 -0
  26. package/build/agents/providers/pi/events.js +282 -0
  27. package/build/agents/{selector_v2.js → selector.js} +8 -6
  28. package/build/cli/commands/akuma/akuma/handler.js +4 -0
  29. package/build/cli/commands/akuma/akuma/meta.js +16 -0
  30. package/build/cli/commands/akuma/catalog.js +8 -0
  31. package/build/cli/commands/akuma/list/handler.js +15 -0
  32. package/build/cli/commands/akuma/list/meta-ls.js +9 -0
  33. package/build/cli/commands/akuma/view/handler.js +34 -0
  34. package/build/cli/commands/akuma/view/meta.js +8 -0
  35. package/build/cli/commands/akuma.js +1 -1
  36. package/build/cli/commands/contract/amend/handler.js +10 -0
  37. package/build/cli/commands/contract/amend/meta.js +12 -0
  38. package/build/cli/commands/contract/arc/handler.js +9 -0
  39. package/build/cli/commands/contract/arc/meta.js +26 -0
  40. package/build/cli/commands/contract/bind/handler.js +23 -0
  41. package/build/cli/commands/contract/bind/meta.js +30 -0
  42. package/build/cli/commands/contract/catalog.js +16 -0
  43. package/build/cli/commands/contract/forfeit/handler.js +13 -0
  44. package/build/cli/commands/contract/forfeit/meta.js +12 -0
  45. package/build/cli/commands/contract/log/handler.js +12 -0
  46. package/build/cli/commands/contract/log/meta.js +12 -0
  47. package/build/cli/commands/contract/petition/handler.js +26 -0
  48. package/build/cli/commands/contract/petition/meta.js +23 -0
  49. package/build/cli/commands/contract/renew/handler.js +10 -0
  50. package/build/cli/commands/contract/renew/meta.js +17 -0
  51. package/build/cli/commands/projection/call/handler.js +39 -0
  52. package/build/cli/commands/projection/call/meta.js +9 -0
  53. package/build/cli/commands/projection/catalog.js +14 -0
  54. package/build/cli/commands/projection/kill/handler.js +35 -0
  55. package/build/cli/commands/projection/kill/meta.js +11 -0
  56. package/build/cli/commands/projection/revive/handler.js +53 -0
  57. package/build/cli/commands/projection/revive/meta.js +9 -0
  58. package/build/cli/commands/projection/status/handler.js +23 -0
  59. package/build/cli/commands/projection/status/meta.js +9 -0
  60. package/build/cli/commands/projection/tell/handler.js +34 -0
  61. package/build/cli/commands/projection/tell/meta.js +9 -0
  62. package/build/cli/commands/projection/wait/handler.js +21 -0
  63. package/build/cli/commands/projection/wait/meta.js +11 -0
  64. package/build/cli/commands/registry.js +100 -0
  65. package/build/cli/commands/shared.js +71 -0
  66. package/build/cli/commands/skills/catalog.js +6 -0
  67. package/build/cli/commands/skills/install/handler.js +10 -0
  68. package/build/cli/commands/skills/install/meta.js +9 -0
  69. package/build/cli/commands/skills/skills/handler.js +4 -0
  70. package/build/cli/commands/skills/skills/meta.js +10 -0
  71. package/build/cli/commands/system/catalog.js +8 -0
  72. package/build/cli/commands/system/completion/handler.js +10 -0
  73. package/build/cli/commands/system/completion/meta.js +9 -0
  74. package/build/cli/commands/system/dump-env/handler.js +3 -0
  75. package/build/cli/commands/system/dump-env/meta.js +10 -0
  76. package/build/cli/commands/system/guide/handler.js +4 -0
  77. package/build/cli/commands/system/guide/meta.js +9 -0
  78. package/build/cli/commands/task/add/handler.js +21 -0
  79. package/build/cli/commands/task/add/meta.js +8 -0
  80. package/build/cli/commands/task/catalog.js +22 -0
  81. package/build/cli/commands/task/doctor/handler.js +4 -0
  82. package/build/cli/commands/task/doctor/meta.js +8 -0
  83. package/build/cli/commands/task/done/handler.js +17 -0
  84. package/build/cli/commands/task/done/meta.js +8 -0
  85. package/build/cli/commands/task/drop/handler.js +6 -0
  86. package/build/cli/commands/task/drop/meta.js +8 -0
  87. package/build/cli/commands/task/ls/handler.js +13 -0
  88. package/build/cli/commands/task/ls/meta.js +8 -0
  89. package/build/cli/commands/task/shared.js +131 -0
  90. package/build/cli/commands/task/start/handler.js +6 -0
  91. package/build/cli/commands/task/start/meta.js +8 -0
  92. package/build/cli/commands/task/stop/handler.js +17 -0
  93. package/build/cli/commands/task/stop/meta.js +8 -0
  94. package/build/cli/commands/task/task/handler.js +5 -0
  95. package/build/cli/commands/task/task/meta.js +11 -0
  96. package/build/cli/commands/task/update/handler.js +18 -0
  97. package/build/cli/commands/task/update/meta.js +8 -0
  98. package/build/cli/commands/task/view/handler.js +14 -0
  99. package/build/cli/commands/task/view/meta.js +8 -0
  100. package/build/cli/completion.js +26 -27
  101. package/build/cli/flags.js +79 -2
  102. package/build/cli/help.js +27 -49
  103. package/build/cli/index.js +121 -374
  104. package/build/cli/output-stream-error-policy.js +17 -0
  105. package/build/cli/parse.js +159 -72
  106. package/build/cli/projection-address.js +5 -0
  107. package/build/cli/render/arc.js +1 -1
  108. package/build/cli/render/errors.js +4 -3
  109. package/build/cli/render/format.js +14 -0
  110. package/build/cli/render/kanshi.js +106 -0
  111. package/build/cli/render/petition.js +24 -1
  112. package/build/cli/render/projection-activity.js +5 -1
  113. package/build/cli/render/shared.js +2 -2
  114. package/build/cli/render/status.js +79 -13
  115. package/build/cli/render/task.js +113 -0
  116. package/build/cli/render/wait.js +23 -3
  117. package/build/cli/types.js +1 -1
  118. package/build/config/{akuma-loader_v2.js → akuma-loader.js} +2 -2
  119. package/build/config/env.js +9 -4
  120. package/build/config/settings/disease.js +26 -0
  121. package/build/config/settings/knobs.js +8 -0
  122. package/build/config/settings/loader.js +244 -0
  123. package/build/config/settings/schema.js +276 -0
  124. package/build/core/addressing.js +1 -1
  125. package/build/core/amend.js +3 -3
  126. package/build/core/arc.js +5 -4
  127. package/build/core/bind-workspace.js +123 -0
  128. package/build/core/bind.js +75 -155
  129. package/build/core/call/call.js +224 -0
  130. package/build/core/call/context.js +238 -0
  131. package/build/core/call/execution.js +217 -0
  132. package/build/core/call/prompt.js +42 -0
  133. package/build/core/call/reference.js +24 -0
  134. package/build/core/call-persist.js +1 -1
  135. package/build/core/claim-delivery.js +247 -0
  136. package/build/core/claim.js +39 -277
  137. package/build/core/context.js +2 -1
  138. package/build/core/{render.js → contract-view.js} +12 -140
  139. package/build/core/draft.js +107 -9
  140. package/build/core/entry.js +9 -1
  141. package/build/core/execution-coordinate.js +4 -20
  142. package/build/core/execution-pact.js +16 -31
  143. package/build/core/forfeit.js +35 -22
  144. package/build/core/hints.js +2 -2
  145. package/build/core/log.js +2 -2
  146. package/build/core/petition-claim-gates.js +8 -6
  147. package/build/core/petition-preview.js +97 -0
  148. package/build/core/petition-run.js +3 -2
  149. package/build/core/petition.js +39 -26
  150. package/build/core/projection/generation/database.js +306 -0
  151. package/build/core/projection/generation/identity.js +84 -0
  152. package/build/core/projection/generation/model.js +201 -0
  153. package/build/core/projection/generation/store.js +73 -0
  154. package/build/core/projection/generation/transitions.js +258 -0
  155. package/build/core/projection/heart.js +0 -307
  156. package/build/core/projection/tell/database.js +109 -0
  157. package/build/core/projection/tell/model.js +97 -0
  158. package/build/core/{projection-tells.js → projection/tell/store.js} +3 -158
  159. package/build/core/projection-activity.js +23 -2
  160. package/build/core/projection-core.js +2 -1
  161. package/build/core/projection-execution-observer.js +259 -0
  162. package/build/core/projection-generation-continuation.js +1 -1
  163. package/build/core/projection-generation-execution.js +90 -20
  164. package/build/core/projection-generation-launcher.js +1 -1
  165. package/build/core/projection-generation-runner.js +198 -4
  166. package/build/core/projection-identity.js +1 -1
  167. package/build/core/projection-kill.js +50 -17
  168. package/build/core/projection-life-observer.js +1 -1
  169. package/build/core/projection-life-protocol.js +10 -0
  170. package/build/core/projection-mint.js +1 -1
  171. package/build/core/projection-status.js +45 -32
  172. package/build/core/projection-wait.js +12 -2
  173. package/build/core/projection-wake.js +5 -2
  174. package/build/core/{queue_v2.js → queue.js} +2 -1
  175. package/build/core/registry.js +1 -1
  176. package/build/core/renew.js +7 -7
  177. package/build/core/response-artifact-catalog-sqlite.js +112 -0
  178. package/build/core/response-artifact-catalog.js +7 -0
  179. package/build/core/seal.js +44 -16
  180. package/build/core/status/board.js +286 -0
  181. package/build/core/status/drift.js +99 -0
  182. package/build/core/status/lifecycle.js +84 -0
  183. package/build/core/status/reconciliation.js +131 -0
  184. package/build/core/stored-agent-event.js +28 -4
  185. package/build/core/target-ref.js +10 -0
  186. package/build/core/task/board.js +175 -0
  187. package/build/core/task/commands.js +211 -0
  188. package/build/core/task/document.js +189 -0
  189. package/build/core/task/model.js +1 -0
  190. package/build/core/task/settlement-git.js +207 -0
  191. package/build/core/task/settlement-policy.js +82 -0
  192. package/build/core/task/source-board.js +84 -0
  193. package/build/core/task/source-model.js +1 -0
  194. package/build/core/task/validation.js +44 -0
  195. package/build/core/task-contract.js +224 -0
  196. package/build/core/task-doctor.js +14 -0
  197. package/build/core/task-git-actor.js +38 -0
  198. package/build/core/task-git-runtime.js +34 -0
  199. package/build/core/task-git-store.js +375 -0
  200. package/build/core/task-repository.js +1 -0
  201. package/build/core/task-store-repository.js +86 -0
  202. package/build/core/task-store.js +1 -0
  203. package/build/core/task-worktree.js +51 -0
  204. package/build/core/task.js +4 -0
  205. package/build/core/transcripts.js +138 -56
  206. package/build/core/validation.js +17 -0
  207. package/build/core/verdict.js +2 -2
  208. package/build/core/worktree-path.js +24 -6
  209. package/build/flow-error.js +3 -2
  210. package/build/generated/version.js +1 -1
  211. package/build/git/commits.js +3 -0
  212. package/build/git/diff/parsers.js +0 -94
  213. package/build/index.js +2 -0
  214. package/build/keiyaku-constants.js +2 -0
  215. package/build/keiyaku.js +4 -3
  216. package/package.json +3 -2
  217. package/skills/keiyaku/SKILL.md +1 -1
  218. package/skills/keiyaku-akuma/SKILL.md +11 -6
  219. package/build/agents/harness/pump.js +0 -158
  220. package/build/agents/providers/codex-app-server.js +0 -864
  221. package/build/agents/providers/opencode-sdk.js +0 -363
  222. package/build/agents/providers/pi.js +0 -557
  223. package/build/config/settings.js +0 -533
  224. package/build/core/call.js +0 -686
  225. package/build/core/projection/generation.js +0 -412
  226. package/build/core/projection/identity.js +0 -81
  227. package/build/core/projection/mint.js +0 -174
  228. package/build/core/projection-generation-store.js +0 -707
  229. package/build/core/status.js +0 -539
@@ -1,608 +1,7 @@
1
- import { randomUUID } from "node:crypto";
2
- import { FlowError } from "../../flow-error.js";
3
- import { StringTailBuffer } from "../string-tail-buffer.js";
4
- import { SUBAGENT_SESSION_VERSION, subagentSessionEnvelopeSchema, } from "../session.js";
5
- import { startClaudeAgentSdk, claudeSessionSchema, } from "../providers/claude-agent-sdk.js";
6
- import { startCodexAppServer, codexAppServerSessionSchema, } from "../providers/codex-app-server.js";
7
- import { startCodexSdk, codexThreadSchema, } from "../providers/codex-sdk.js";
8
- import { startOpencode, opencodeSessionSchema, } from "../providers/opencode-sdk.js";
9
- import { startPi, piSessionSchema, } from "../providers/pi.js";
10
- import { SubagentFailure, } from "../types.js";
11
- import { createEventChannel } from "./event-channel.js";
12
- import { overflowMarkerFromDropped } from "./execution-handle.js";
13
- import { buildSyncCheckpointCallback, createReplayRunStartGate, markReplayCompleted, pumpSupervisor, snapshotReplayPrompt } from "./pump.js";
14
- import { createAbortError, renderCapturedText } from "./runtime.js";
15
- import { demoteSubmittedTellsForReplay, listTellIds, markTellSubmitted } from "../../core/projection-core.js";
16
1
  export { activityEventBodySchema, AGENT_EVENT_TEXT_MAX_CHARS, AGENT_UNKNOWN_PAYLOAD_MAX_CHARS, } from "./events.js";
17
- export function call(terms) {
18
- return createProjection(terms);
19
- }
20
- export function revive(terms) {
21
- return createProjection(terms, terms);
22
- }
23
- function mintOutcome(draft) {
24
- return draft;
25
- }
26
- export function restoreOutcome(record) {
27
- return { ...record };
28
- }
29
- function createProjection(terms, reviveTerms) {
30
- switch (terms.provider) {
31
- case "pi":
32
- case "claude-agent-sdk":
33
- case "codex-app-server":
34
- return createSteerableProjection(terms, reviveTerms);
35
- case "codex-sdk":
36
- case "opencode-sdk":
37
- return createReplayProjection(terms, reviveTerms);
38
- default:
39
- return assertNever(terms);
40
- }
41
- }
42
- function createSteerableProjection(terms, reviveTerms) {
43
- const shared = createProjectionState(terms, reviveTerms);
44
- const pendingTells = [];
45
- let flushActive = false;
46
- const flushPendingTells = async () => {
47
- const initialEnqueue = shared.live?.enqueue;
48
- if (flushActive || shared.terminal || !initialEnqueue)
49
- return;
50
- flushActive = true;
51
- try {
52
- while (!shared.terminal && pendingTells.length > 0) {
53
- const enqueue = shared.live?.enqueue;
54
- if (!enqueue)
55
- break;
56
- const nextTell = pendingTells.shift();
57
- if (!nextTell)
58
- break;
59
- await enqueue(nextTell);
60
- }
61
- }
62
- finally {
63
- flushActive = false;
64
- if (!shared.terminal && pendingTells.length > 0 && shared.live?.enqueue) {
65
- void flushPendingTells();
66
- }
67
- }
68
- };
69
- shared.onLive = (live) => {
70
- shared.live = live;
71
- void flushPendingTells();
72
- };
73
- const outcome = settleProjection(shared);
74
- return {
75
- mode: "steerable",
76
- get id() {
77
- return shared.id;
78
- },
79
- get events() {
80
- return shared.publicEvents.iterable;
81
- },
82
- get outcome() {
83
- return outcome;
84
- },
85
- tell(tell) {
86
- if (shared.terminal)
87
- return;
88
- pendingTells.push(tell);
89
- void flushPendingTells();
90
- },
91
- recallTells() {
92
- return pendingTells.splice(0, pendingTells.length);
93
- },
94
- dismiss() {
95
- dismissProjection(shared);
96
- },
97
- };
98
- }
99
- function createReplayProjection(terms, reviveTerms) {
100
- const shared = createProjectionState(terms, reviveTerms);
101
- shared.onLive = (live) => {
102
- shared.live = live;
103
- };
104
- const outcome = settleProjection(shared);
105
- return {
106
- mode: "replay",
107
- get id() {
108
- return shared.id;
109
- },
110
- get events() {
111
- return shared.publicEvents.iterable;
112
- },
113
- get outcome() {
114
- return outcome;
115
- },
116
- dismiss() {
117
- dismissProjection(shared);
118
- },
119
- };
120
- }
121
- function createProjectionState(terms, reviveTerms) {
122
- const shared = {
123
- id: randomUUID(),
124
- terms,
125
- reviveTerms,
126
- publicEvents: createEventChannel({
127
- createOverflowMarker: overflowMarkerFromDropped,
128
- }),
129
- lifecycleAbort: new AbortController(),
130
- dismissed: false,
131
- externallyAborted: false,
132
- terminal: false,
133
- onLive() { },
134
- };
135
- if (terms.signal) {
136
- const listener = () => {
137
- shared.externallyAborted = true;
138
- if (!shared.lifecycleAbort.signal.aborted) {
139
- shared.lifecycleAbort.abort(terms.signal?.reason);
140
- }
141
- };
142
- terms.signal.addEventListener("abort", listener, { once: true });
143
- if (terms.signal.aborted) {
144
- listener();
145
- }
146
- }
147
- return shared;
148
- }
149
- function dismissProjection(shared) {
150
- if (shared.dismissed || shared.terminal)
151
- return;
152
- shared.dismissed = true;
153
- if (!shared.lifecycleAbort.signal.aborted) {
154
- shared.lifecycleAbort.abort(createAbortError(`${shared.terms.provider} exec dismissed`));
155
- }
156
- requestAbort(shared.live);
157
- }
158
- function requestAbort(live) {
159
- if (!live)
160
- return;
161
- void Promise.resolve()
162
- .then(() => live.abort())
163
- .catch(() => undefined);
164
- }
165
- async function settleProjection(shared) {
166
- const state = {
167
- outputBuffer: new StringTailBuffer(shared.terms.maxCaptureChars),
168
- diagnosticsBuffer: new StringTailBuffer(shared.terms.maxCaptureChars),
169
- warnings: [],
170
- };
171
- let idleTimedOut = false;
172
- let abortRequested = false;
173
- let idleTimeout;
174
- const refreshIdleTimeout = () => {
175
- if (idleTimeout)
176
- clearTimeout(idleTimeout);
177
- idleTimeout = setTimeout(() => {
178
- idleTimedOut = true;
179
- shared.lifecycleAbort.abort(createAbortError(`${shared.terms.provider} exec idle timed out`));
180
- }, shared.terms.idleTimeoutMs);
181
- idleTimeout.unref?.();
182
- };
183
- refreshIdleTimeout();
184
- const requestLiveAbort = () => {
185
- if (abortRequested)
186
- return;
187
- abortRequested = true;
188
- requestAbort(shared.live);
189
- };
190
- shared.lifecycleAbort.signal.addEventListener("abort", requestLiveAbort, { once: true });
191
- try {
192
- if (shared.terms.projectionDir) {
193
- const executionId = shared.terms.projectionExecutionId;
194
- if (!executionId)
195
- throw new FlowError("INTERNAL_STATE", "projection execution id is required in supervisor mode");
196
- demoteSubmittedTellsForReplay(shared.terms.projectionDir, executionId);
197
- }
198
- const launchTellFence = shared.terms.projectionTellFence;
199
- const tellFence = launchTellFence === undefined
200
- ? []
201
- : Array.isArray(launchTellFence) && launchTellFence.every((tellId) => typeof tellId === "string")
202
- ? launchTellFence
203
- : (() => { throw new FlowError("INTERNAL_STATE", "generation launch has an invalid tellFence"); })();
204
- const launchSnapshot = shared.terms.projectionDir && shared.terms.projectionExecutionId
205
- ? snapshotReplayPrompt(shared.terms.projectionDir, shared.terms.prompt, tellFence, shared.terms.projectionExecutionId,
206
- // Session resume already holds launch history. Only fenced tells are
207
- // new operator input; re-blasting the original prompt reasserts stale
208
- // allowlists and breaks resting continuation.
209
- { sessionContinuation: shared.reviveTerms !== undefined })
210
- : undefined;
211
- const launchTerms = launchSnapshot
212
- ? shared.terms.provider === "codex-sdk" && launchSnapshot.effort
213
- ? { ...shared.terms, prompt: launchSnapshot.prompt, threadOptions: { ...shared.terms.threadOptions, modelReasoningEffort: launchSnapshot.effort } }
214
- : { ...shared.terms, prompt: launchSnapshot.prompt }
215
- : shared.terms;
216
- // A constructed driver is not an SDK run acknowledgement. Tier-2 has no
217
- // live steer surface, so the first provider event is the earliest harness
218
- // observable start; a successful no-event completion is the only fallback.
219
- const replayStartGate = launchSnapshot && shared.terms.provider !== "codex-app-server" && shared.terms.projectionDir && shared.terms.projectionExecutionId
220
- ? createReplayRunStartGate(shared.terms.projectionDir, shared.terms.projectionExecutionId, launchSnapshot.tellIds)
221
- : undefined;
222
- const live = await startLiveProjection(launchTerms, shared.lifecycleAbort.signal, shared.reviveTerms, launchSnapshot?.tellIds, refreshIdleTimeout);
223
- shared.onLive(live);
224
- if (shared.lifecycleAbort.signal.aborted) {
225
- requestLiveAbort();
226
- }
227
- const projectionDir = shared.terms.projectionDir;
228
- if (projectionDir) {
229
- const executionId = shared.terms.projectionExecutionId;
230
- if (!executionId) {
231
- throw new Error("projection execution id is required in supervisor mode");
232
- }
233
- // Supervisor mode: persist events, checkpoint, and claim heart-backed tells.
234
- await pumpSupervisor(live, projectionDir, executionId, shared.publicEvents, {
235
- onEvent: (event) => {
236
- replayStartGate?.observeProviderEvent();
237
- refreshIdleTimeout();
238
- processEvent(state, event);
239
- },
240
- });
241
- }
242
- else {
243
- // Legacy mode: direct event loop without supervisor pump.
244
- for await (const event of live.events) {
245
- replayStartGate?.observeProviderEvent();
246
- refreshIdleTimeout();
247
- shared.publicEvents.push(event);
248
- processEvent(state, event);
249
- }
250
- }
251
- const completionResult = await live.completion.then((value) => ({ ok: true, value }), (error) => ({ ok: false, error }));
252
- const completionOutcome = completionResult.ok ? completionResult.value : undefined;
253
- if (state.failEvent) {
254
- return failFromFailEvent(shared, state, state.failEvent);
255
- }
256
- if (!completionResult.ok) {
257
- return classifyFailure(shared, state, completionResult.error, idleTimedOut);
258
- }
259
- if (shared.lifecycleAbort.signal.aborted) {
260
- return classifyFailure(shared, state, shared.lifecycleAbort.signal.reason, idleTimedOut);
261
- }
262
- if (!state.doneEvent && !completionOutcome) {
263
- return failWithError(shared, state, {
264
- code: "SUBAGENT_EXEC_ERROR",
265
- message: `${shared.terms.provider} exec ended before completion`,
266
- timeoutMs: null,
267
- exitCode: null,
268
- }, state.finalMessageCandidate);
269
- }
270
- const finalMessage = state.doneEvent?.finalMessage ??
271
- completionOutcome?.finalMessage ??
272
- state.finalMessageCandidate ??
273
- renderCapturedText(state.outputBuffer).trim();
274
- const session = state.doneEvent?.session ?? completionOutcome?.session;
275
- if (!session) {
276
- return failWithError(shared, state, {
277
- code: "SUBAGENT_EXEC_ERROR",
278
- message: `${shared.terms.provider} exec ended without a session handle`,
279
- timeoutMs: null,
280
- exitCode: null,
281
- }, finalMessage);
282
- }
283
- // A provider may complete successfully without emitting any observable
284
- // events. Its successful completion is still a real run start.
285
- replayStartGate?.observeSuccessfulCompletion();
286
- if (launchSnapshot && shared.terms.projectionDir && shared.terms.projectionExecutionId) {
287
- markReplayCompleted(shared.terms.projectionDir, shared.terms.projectionExecutionId);
288
- }
289
- return mintOutcome({
290
- status: "completed",
291
- finalMessage,
292
- output: renderCapturedText(state.outputBuffer),
293
- diagnostics: renderCapturedText(state.diagnosticsBuffer),
294
- session,
295
- warnings: [...state.warnings],
296
- });
297
- }
298
- catch (error) {
299
- if (error instanceof FlowError) {
300
- throw error;
301
- }
302
- return classifyFailure(shared, state, error, idleTimedOut);
303
- }
304
- finally {
305
- if (idleTimeout)
306
- clearTimeout(idleTimeout);
307
- shared.lifecycleAbort.signal.removeEventListener("abort", requestLiveAbort);
308
- shared.terminal = true;
309
- shared.publicEvents.close();
310
- }
311
- }
312
- function processEvent(state, event) {
313
- switch (event.type) {
314
- case "diagnostic":
315
- state.diagnosticsBuffer.append(event.text);
316
- return;
317
- case "message":
318
- state.finalMessageCandidate = event.text;
319
- return;
320
- case "warning":
321
- state.warnings.push(event.warning);
322
- return;
323
- case "done":
324
- state.doneEvent = event;
325
- state.session = event.session;
326
- if (event.finalMessage !== undefined) {
327
- state.finalMessageCandidate = event.finalMessage;
328
- }
329
- return;
330
- case "fail":
331
- state.failEvent = event;
332
- if (event.diagnostics) {
333
- state.diagnosticsBuffer.append(event.diagnostics);
334
- }
335
- return;
336
- case "activity":
337
- case "unknown":
338
- case "turn":
339
- case "usage":
340
- case "thought":
341
- case "plan":
342
- case "truncation":
343
- return;
344
- }
345
- }
346
- function failFromFailEvent(shared, state, failEvent) {
347
- const code = failEvent.code === "PROJECTION_STATE_ERROR" || failEvent.code === undefined
348
- ? "SUBAGENT_EXEC_ERROR"
349
- : failEvent.code;
350
- const diagnostics = failEvent.code === "PROJECTION_STATE_ERROR"
351
- ? [renderCapturedText(state.diagnosticsBuffer), "PROJECTION_STATE_ERROR"].filter(Boolean).join("\n")
352
- : renderCapturedText(state.diagnosticsBuffer);
353
- return failWithError(shared, state, {
354
- code,
355
- message: failEvent.message,
356
- timeoutMs: null,
357
- exitCode: failEvent.exitCode ?? null,
358
- }, state.finalMessageCandidate, failEvent.diagnostics ?? diagnostics);
359
- }
360
- function classifyFailure(shared, state, error, idleTimedOut) {
361
- if (shared.dismissed || shared.externallyAborted) {
362
- return mintOutcome({
363
- status: "dismissed",
364
- finalMessage: state.finalMessageCandidate ?? "",
365
- output: renderCapturedText(state.outputBuffer),
366
- diagnostics: renderCapturedText(state.diagnosticsBuffer),
367
- session: state.session ?? fallbackSession(shared),
368
- warnings: [...state.warnings],
369
- });
370
- }
371
- if (idleTimedOut) {
372
- return failWithError(shared, state, {
373
- code: "SUBAGENT_TIMEOUT",
374
- message: `${shared.terms.provider} exec idle timed out`,
375
- timeoutMs: shared.terms.idleTimeoutMs,
376
- exitCode: null,
377
- }, state.finalMessageCandidate);
378
- }
379
- if (error instanceof SubagentFailure) {
380
- return failWithError(shared, state, {
381
- code: error.code,
382
- message: error.message,
383
- timeoutMs: error.timeoutMs,
384
- exitCode: error.exitCode,
385
- }, state.finalMessageCandidate ?? error.message, error.diagnostics || renderCapturedText(state.diagnosticsBuffer), error.output || renderCapturedText(state.outputBuffer));
386
- }
387
- const message = error instanceof Error ? error.message : `Unknown ${shared.terms.provider} exec error`;
388
- appendThrownMessage(state.diagnosticsBuffer, message);
389
- return failWithError(shared, state, {
390
- code: "SUBAGENT_EXEC_ERROR",
391
- message,
392
- timeoutMs: null,
393
- exitCode: null,
394
- }, state.finalMessageCandidate ?? message);
395
- }
396
- function failWithError(shared, state, error, finalMessage, diagnostics = renderCapturedText(state.diagnosticsBuffer), output = renderCapturedText(state.outputBuffer)) {
397
- return mintOutcome({
398
- status: "failed",
399
- error,
400
- finalMessage: finalMessage ?? error.message,
401
- output,
402
- diagnostics,
403
- session: state.session ?? fallbackSession(shared),
404
- warnings: [...state.warnings],
405
- });
406
- }
407
- function fallbackSession(shared) {
408
- return shared.reviveTerms?.session ?? {
409
- provider: shared.terms.provider,
410
- version: SUBAGENT_SESSION_VERSION,
411
- handle: null,
412
- };
413
- }
414
- function appendThrownMessage(buffer, message) {
415
- if (message.length === 0)
416
- return;
417
- const snapshot = buffer.snapshot().text;
418
- if (snapshot.length > 0 && !snapshot.endsWith("\n")) {
419
- buffer.append("\n");
420
- }
421
- buffer.append(message);
422
- }
423
- function admitResumeShape(provider, schema, session, resumePath) {
424
- const envelopeResult = subagentSessionEnvelopeSchema.safeParse(session);
425
- if (!envelopeResult.success) {
426
- throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' includes an invalid session envelope.`);
427
- }
428
- if (session.provider !== provider) {
429
- throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' was created with provider '${session.provider}', but the selected subagent resolves to '${provider}'. Cross-provider resume is not supported.`);
430
- }
431
- if (session.version !== SUBAGENT_SESSION_VERSION) {
432
- throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' uses unsupported session version '${session.version}' for provider '${session.provider}'.`);
433
- }
434
- const shapeResult = schema.safeParse(session.handle);
435
- if (!shapeResult.success) {
436
- throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' includes an invalid session handle for provider '${session.provider}'.`);
437
- }
438
- return shapeResult.data;
439
- }
440
- async function startLiveProjection(terms, signal, reviveTerms, initialTellIds = [], onIngress) {
441
- const projectionCheckpoint = terms.projectionDir && terms.projectionExecutionId
442
- ? buildSyncCheckpointCallback(terms.projectionDir, terms.projectionExecutionId)
443
- : undefined;
444
- let appServerInitialFencePending = terms.provider === "codex-app-server" && initialTellIds.length > 0;
445
- const onSyncCheckpoint = terms.projectionDir
446
- ? (control, checkpoint) => {
447
- if (appServerInitialFencePending && terms.projectionExecutionId) {
448
- for (const tellId of initialTellIds) {
449
- if (listTellIds(terms.projectionDir, "inflight").includes(tellId)) {
450
- markTellSubmitted(terms.projectionDir, tellId, { executionId: terms.projectionExecutionId, fence: checkpoint.fence });
451
- }
452
- }
453
- appServerInitialFencePending = false;
454
- return;
455
- }
456
- projectionCheckpoint?.(control, checkpoint);
457
- }
458
- : "onCheckpoint" in terms
459
- ? terms.onCheckpoint
460
- : undefined;
461
- switch (terms.provider) {
462
- case "pi": {
463
- if (reviveTerms) {
464
- const session = admitResumeShape("pi", piSessionSchema, reviveTerms.session, reviveTerms.resumePath);
465
- return startPi(terms.prompt, terms.workdir, {
466
- model: terms.model,
467
- thinkingLevel: terms.thinkingLevel,
468
- signal,
469
- sessionFile: session.sessionFile,
470
- appendSystemPromptOverride: terms.appendSystemPromptOverride,
471
- onSyncCheckpoint,
472
- onEvidence: terms.onEvidence,
473
- onIngress,
474
- initialTurn: terms.initialTurn,
475
- });
476
- }
477
- return startPi(terms.prompt, terms.workdir, {
478
- model: terms.model,
479
- thinkingLevel: terms.thinkingLevel,
480
- signal,
481
- appendSystemPromptOverride: terms.appendSystemPromptOverride,
482
- onSyncCheckpoint,
483
- onEvidence: terms.onEvidence,
484
- onIngress,
485
- initialTurn: terms.initialTurn,
486
- });
487
- }
488
- case "claude-agent-sdk": {
489
- const claudeOptions = {
490
- model: terms.model,
491
- executable: terms.executable,
492
- effort: terms.effort,
493
- signal,
494
- permissionMode: terms.permissionMode,
495
- settingSources: terms.settingSources,
496
- allowDangerouslySkipPermissions: terms.allowDangerouslySkipPermissions,
497
- disallowedTools: terms.disallowedTools,
498
- systemPrompt: terms.systemPrompt,
499
- onSyncCheckpoint,
500
- onEvidence: terms.onEvidence,
501
- onIngress,
502
- initialTurn: terms.initialTurn,
503
- };
504
- if (reviveTerms) {
505
- const session = admitResumeShape("claude-agent-sdk", claudeSessionSchema, reviveTerms.session, reviveTerms.resumePath);
506
- return startClaudeAgentSdk(terms.prompt, terms.workdir, {
507
- ...claudeOptions,
508
- sessionId: session.sessionId,
509
- });
510
- }
511
- return startClaudeAgentSdk(terms.prompt, terms.workdir, claudeOptions);
512
- }
513
- case "codex-app-server": {
514
- if (reviveTerms) {
515
- const session = admitResumeShape("codex-app-server", codexAppServerSessionSchema, reviveTerms.session, reviveTerms.resumePath);
516
- return startCodexAppServer(terms.prompt, terms.workdir, {
517
- model: terms.model,
518
- effort: terms.effort,
519
- profile: terms.profile,
520
- config: terms.config,
521
- sandboxPolicy: terms.sandboxPolicy,
522
- approvalPolicy: terms.approvalPolicy,
523
- executable: terms.executable,
524
- signal,
525
- threadId: session.threadId,
526
- codexHome: session.codexHome,
527
- developerInstructions: terms.developerInstructions,
528
- onSyncCheckpoint,
529
- onEvidence: terms.onEvidence,
530
- onIngress,
531
- initialTurn: terms.initialTurn,
532
- });
533
- }
534
- return startCodexAppServer(terms.prompt, terms.workdir, {
535
- model: terms.model,
536
- effort: terms.effort,
537
- profile: terms.profile,
538
- config: terms.config,
539
- sandboxPolicy: terms.sandboxPolicy,
540
- approvalPolicy: terms.approvalPolicy,
541
- executable: terms.executable,
542
- signal,
543
- developerInstructions: terms.developerInstructions,
544
- onSyncCheckpoint,
545
- onEvidence: terms.onEvidence,
546
- onIngress,
547
- initialTurn: terms.initialTurn,
548
- });
549
- }
550
- case "codex-sdk": {
551
- if (reviveTerms) {
552
- const session = admitResumeShape("codex-sdk", codexThreadSchema, reviveTerms.session, reviveTerms.resumePath);
553
- return startCodexSdk(terms.prompt, terms.workdir, {
554
- model: terms.model,
555
- profile: terms.profile,
556
- config: terms.config,
557
- threadOptions: terms.threadOptions,
558
- executable: terms.executable,
559
- signal,
560
- threadId: session.threadId,
561
- onEvidence: terms.onEvidence,
562
- onIngress,
563
- initialTurn: terms.initialTurn,
564
- });
565
- }
566
- return startCodexSdk(terms.prompt, terms.workdir, {
567
- model: terms.model,
568
- profile: terms.profile,
569
- config: terms.config,
570
- threadOptions: terms.threadOptions,
571
- executable: terms.executable,
572
- signal,
573
- onEvidence: terms.onEvidence,
574
- onIngress,
575
- initialTurn: terms.initialTurn,
576
- });
577
- }
578
- case "opencode-sdk": {
579
- if (reviveTerms) {
580
- const session = admitResumeShape("opencode-sdk", opencodeSessionSchema, reviveTerms.session, reviveTerms.resumePath);
581
- return startOpencode(terms.prompt, terms.workdir, {
582
- model: terms.model,
583
- effort: terms.effort,
584
- executable: terms.executable,
585
- signal,
586
- sessionId: session.sessionId,
587
- onEvidence: terms.onEvidence,
588
- onIngress,
589
- initialTurn: terms.initialTurn,
590
- });
591
- }
592
- return startOpencode(terms.prompt, terms.workdir, {
593
- model: terms.model,
594
- effort: terms.effort,
595
- executable: terms.executable,
596
- signal,
597
- onEvidence: terms.onEvidence,
598
- onIngress,
599
- initialTurn: terms.initialTurn,
600
- });
601
- }
602
- default:
603
- return assertNever(terms);
604
- }
605
- }
606
- function assertNever(_value) {
607
- throw new Error("Unhandled provider");
608
- }
2
+ export { EXEC_EVENT_BUFFER_HARD_CAP } from "./event-channel.js";
3
+ export { createAbortError } from "./runtime.js";
4
+ export { restoreOutcome } from "./outcome.js";
5
+ export { call, revive } from "./projection.js";
6
+ export { SubagentFailure } from "../types.js";
7
+ export { SUBAGENT_SESSION_VERSION, subagentSessionEnvelopeSchema, } from "../session.js";