@astrosheep/keiyaku 4.0.0 → 4.0.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 (241) hide show
  1. package/README.md +2 -9
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +11 -3
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +9 -6
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +94 -0
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +162 -45
  12. package/build/src/akuma/akuma.d.ts +33 -25
  13. package/build/src/akuma/akuma.js +93 -61
  14. package/build/src/akuma/archetype.d.ts +8 -0
  15. package/build/src/akuma/archetype.js +28 -9
  16. package/build/src/akuma/body.js +196 -84
  17. package/build/src/akuma/coordinate.d.ts +9 -0
  18. package/build/src/akuma/coordinate.js +22 -0
  19. package/build/src/akuma/heart/facts.d.ts +67 -15
  20. package/build/src/akuma/heart/facts.js +3 -3
  21. package/build/src/akuma/heart/index.d.ts +41 -29
  22. package/build/src/akuma/heart/index.js +72 -193
  23. package/build/src/akuma/heart/rows.d.ts +30 -53
  24. package/build/src/akuma/heart/rows.js +91 -111
  25. package/build/src/akuma/heart/schema.d.ts +1 -1
  26. package/build/src/akuma/heart/schema.js +55 -8
  27. package/build/src/akuma/heart/storage.d.ts +33 -0
  28. package/build/src/akuma/heart/storage.js +164 -0
  29. package/build/src/akuma/heart/tells.d.ts +12 -0
  30. package/build/src/akuma/heart/tells.js +79 -0
  31. package/build/src/akuma/heart/timeline.d.ts +15 -0
  32. package/build/src/akuma/heart/timeline.js +86 -0
  33. package/build/src/akuma/index.d.ts +4 -2
  34. package/build/src/akuma/index.js +1 -1
  35. package/build/src/akuma/projection.d.ts +97 -0
  36. package/build/src/akuma/projection.js +145 -0
  37. package/build/src/akuma/provider.d.ts +57 -11
  38. package/build/src/akuma/provider.js +57 -37
  39. package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
  40. package/build/src/akuma/providers/claude/events.js +185 -0
  41. package/build/src/akuma/providers/claude/index.d.ts +46 -0
  42. package/build/src/akuma/providers/claude/index.js +265 -0
  43. package/build/src/akuma/providers/claude/input.d.ts +13 -0
  44. package/build/src/akuma/providers/claude/input.js +109 -0
  45. package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
  46. package/build/src/akuma/providers/codex-app-server/events.js +12 -12
  47. package/build/src/akuma/providers/codex-app-server/index.d.ts +13 -11
  48. package/build/src/akuma/providers/codex-app-server/index.js +73 -22
  49. package/build/src/akuma/providers/index.js +22 -8
  50. package/build/src/akuma/providers/opencode-sdk/events.d.ts +48 -0
  51. package/build/src/akuma/providers/opencode-sdk/events.js +116 -0
  52. package/build/src/akuma/providers/opencode-sdk/index.d.ts +32 -0
  53. package/build/src/akuma/providers/opencode-sdk/index.js +203 -0
  54. package/build/src/akuma/providers/opencode-sdk/session.d.ts +41 -0
  55. package/build/src/akuma/providers/opencode-sdk/session.js +62 -0
  56. package/build/src/akuma/providers/pi/events.d.ts +33 -0
  57. package/build/src/akuma/providers/pi/events.js +128 -0
  58. package/build/src/akuma/providers/pi/index.d.ts +11 -0
  59. package/build/src/akuma/providers/pi/index.js +162 -0
  60. package/build/src/akuma/requests.d.ts +1 -0
  61. package/build/src/akuma/requests.js +5 -2
  62. package/build/src/alias/index.d.ts +4 -3
  63. package/build/src/alias/index.js +2 -3
  64. package/build/src/body/render.js +2 -1
  65. package/build/src/body/shape.js +7 -1
  66. package/build/src/body/verification.js +19 -4
  67. package/build/src/cli/accepted.d.ts +2 -0
  68. package/build/src/cli/accepted.js +2 -1
  69. package/build/src/cli/commands/akuma-invoke.d.ts +42 -18
  70. package/build/src/cli/commands/akuma-invoke.js +94 -50
  71. package/build/src/cli/commands/akuma.d.ts +15 -7
  72. package/build/src/cli/commands/akuma.js +94 -56
  73. package/build/src/cli/commands/contract.d.ts +142 -0
  74. package/build/src/cli/commands/contract.js +14 -0
  75. package/build/src/cli/commands/install.js +2 -0
  76. package/build/src/cli/commands/task-invoke.d.ts +3 -1
  77. package/build/src/cli/commands/task-invoke.js +27 -2
  78. package/build/src/cli/commands/task.js +2 -2
  79. package/build/src/cli/invoke.d.ts +6 -1
  80. package/build/src/cli/invoke.js +241 -43
  81. package/build/src/cli/main.js +20 -1
  82. package/build/src/cli/parse.d.ts +13 -116
  83. package/build/src/cli/parse.js +51 -78
  84. package/build/src/cli/render/akuma-tool.d.ts +2 -0
  85. package/build/src/cli/render/akuma-tool.js +6 -2
  86. package/build/src/cli/render/akuma.d.ts +2 -1
  87. package/build/src/cli/render/akuma.js +157 -217
  88. package/build/src/cli/render/catalog.d.ts +2 -0
  89. package/build/src/cli/render/catalog.js +16 -0
  90. package/build/src/cli/render/contract.d.ts +1 -1
  91. package/build/src/cli/render/contract.js +38 -5
  92. package/build/src/cli/render/kanshi.js +53 -5
  93. package/build/src/cli/render/refusal.js +17 -0
  94. package/build/src/cli/render/terminal.d.ts +13 -0
  95. package/build/src/cli/render/terminal.js +75 -0
  96. package/build/src/cli/render/text.js +5 -0
  97. package/build/src/cli/result.d.ts +15 -3
  98. package/build/src/contract-worktree.d.ts +43 -0
  99. package/build/src/contract-worktree.js +213 -0
  100. package/build/src/coordination/durable-file.d.ts +3 -0
  101. package/build/src/coordination/durable-file.js +44 -1
  102. package/build/src/core/facts/codec.js +23 -4
  103. package/build/src/core/facts/eligibility.d.ts +1 -10
  104. package/build/src/core/facts/eligibility.js +0 -49
  105. package/build/src/core/facts/observation.d.ts +3 -0
  106. package/build/src/core/facts/observation.js +12 -0
  107. package/build/src/core/facts/types.d.ts +10 -3
  108. package/build/src/core/subject.js +2 -2
  109. package/build/src/core/verbs/amend.js +12 -16
  110. package/build/src/core/verbs/bind.js +2 -16
  111. package/build/src/core/verbs/deliver.js +20 -4
  112. package/build/src/core/verbs/placement.js +3 -8
  113. package/build/src/dispatch/index.d.ts +3 -1
  114. package/build/src/dispatch/index.js +14 -5
  115. package/build/src/duration.d.ts +10 -0
  116. package/build/src/duration.js +22 -0
  117. package/build/src/git/admission.d.ts +2 -2
  118. package/build/src/git/admission.js +26 -16
  119. package/build/src/git/hooks.d.ts +15 -0
  120. package/build/src/git/hooks.js +57 -5
  121. package/build/src/git/identity.d.ts +5 -1
  122. package/build/src/git/identity.js +23 -4
  123. package/build/src/git/integration.d.ts +49 -0
  124. package/build/src/git/integration.js +214 -0
  125. package/build/src/git/observe.d.ts +25 -13
  126. package/build/src/git/observe.js +175 -72
  127. package/build/src/git/read-observation.d.ts +41 -0
  128. package/build/src/git/read-observation.js +361 -0
  129. package/build/src/git/reconcile.d.ts +15 -5
  130. package/build/src/git/reconcile.js +238 -85
  131. package/build/src/git/repository.d.ts +19 -4
  132. package/build/src/git/repository.js +77 -43
  133. package/build/src/git/scratch.d.ts +13 -0
  134. package/build/src/git/scratch.js +66 -0
  135. package/build/src/git/target-placement.d.ts +56 -0
  136. package/build/src/git/target-placement.js +255 -0
  137. package/build/src/git/tender.d.ts +48 -0
  138. package/build/src/git/tender.js +82 -0
  139. package/build/src/git/terminal-seal.d.ts +24 -0
  140. package/build/src/git/terminal-seal.js +87 -0
  141. package/build/src/git/tree.d.ts +2 -2
  142. package/build/src/git/tree.js +4 -0
  143. package/build/src/git/workspace.d.ts +21 -0
  144. package/build/src/git/workspace.js +104 -0
  145. package/build/src/identity/selector.d.ts +6 -0
  146. package/build/src/identity/selector.js +19 -0
  147. package/build/src/index.d.ts +4 -2
  148. package/build/src/index.js +2 -1
  149. package/build/src/kanshi/index.d.ts +1 -1
  150. package/build/src/kanshi/read.d.ts +5 -2
  151. package/build/src/kanshi/read.js +154 -45
  152. package/build/src/kanshi/report.d.ts +31 -6
  153. package/build/src/kanshi/select.js +1 -1
  154. package/build/src/library/address.d.ts +48 -0
  155. package/build/src/library/address.js +134 -0
  156. package/build/src/library/akuma-creation.d.ts +10 -6
  157. package/build/src/library/akuma-creation.js +12 -11
  158. package/build/src/library/bind.d.ts +21 -0
  159. package/build/src/library/bind.js +56 -0
  160. package/build/src/library/catalog.d.ts +58 -0
  161. package/build/src/library/catalog.js +72 -0
  162. package/build/src/library/configuration.d.ts +6 -15
  163. package/build/src/library/configuration.js +14 -17
  164. package/build/src/library/contract.d.ts +21 -46
  165. package/build/src/library/contract.js +193 -183
  166. package/build/src/library/delivery.d.ts +23 -0
  167. package/build/src/library/delivery.js +21 -0
  168. package/build/src/library/fleet.d.ts +65 -0
  169. package/build/src/library/fleet.js +189 -0
  170. package/build/src/library/input.d.ts +3 -0
  171. package/build/src/library/input.js +19 -0
  172. package/build/src/library/keiyaku.d.ts +16 -2
  173. package/build/src/library/keiyaku.js +11 -1
  174. package/build/src/library/mutation.d.ts +38 -0
  175. package/build/src/library/mutation.js +39 -0
  176. package/build/src/library/refusal.d.ts +21 -0
  177. package/build/src/library/refusal.js +29 -0
  178. package/build/src/library/region.d.ts +2 -1
  179. package/build/src/library/region.js +3 -3
  180. package/build/src/library/repo.d.ts +4 -1
  181. package/build/src/library/repo.js +31 -16
  182. package/build/src/protocol/attempt.d.ts +16 -3
  183. package/build/src/protocol/attempt.js +39 -8
  184. package/build/src/protocol/bind.d.ts +9 -2
  185. package/build/src/protocol/bind.js +47 -39
  186. package/build/src/protocol/intent.d.ts +42 -18
  187. package/build/src/protocol/intent.js +36 -75
  188. package/build/src/protocol/operations.d.ts +93 -35
  189. package/build/src/protocol/operations.js +235 -123
  190. package/build/src/protocol/outcome.d.ts +7 -2
  191. package/build/src/protocol/outcome.js +9 -3
  192. package/build/src/protocol/placement.d.ts +30 -0
  193. package/build/src/protocol/placement.js +114 -0
  194. package/build/src/protocol/read/audit.d.ts +9 -3
  195. package/build/src/protocol/read/audit.js +25 -9
  196. package/build/src/protocol/read/documents.d.ts +2 -2
  197. package/build/src/protocol/read/documents.js +4 -4
  198. package/build/src/protocol/read/status.d.ts +11 -5
  199. package/build/src/protocol/read/status.js +28 -15
  200. package/build/src/protocol/run.d.ts +49 -7
  201. package/build/src/protocol/run.js +53 -25
  202. package/build/src/runtime/proc/line-rpc.d.ts +1 -0
  203. package/build/src/runtime/proc/line-rpc.js +21 -0
  204. package/build/src/runtime/proc/run.d.ts +18 -2
  205. package/build/src/runtime/proc/run.js +34 -8
  206. package/build/src/settings.d.ts +6 -0
  207. package/build/src/settings.js +29 -14
  208. package/build/src/settlement/fence.d.ts +9 -0
  209. package/build/src/settlement/fence.js +23 -0
  210. package/build/src/settlement/holder.d.ts +25 -4
  211. package/build/src/settlement/holder.js +102 -28
  212. package/build/src/settlement/settle.d.ts +8 -0
  213. package/build/src/settlement/settle.js +102 -28
  214. package/build/src/task/board.d.ts +20 -2
  215. package/build/src/task/board.js +11 -1
  216. package/build/src/task/compose.d.ts +2 -2
  217. package/build/src/task/compose.js +2 -2
  218. package/build/src/task/context.js +2 -7
  219. package/build/src/task/index.d.ts +9 -9
  220. package/build/src/task/index.js +15 -12
  221. package/build/src/task/operations.d.ts +31 -12
  222. package/build/src/task/operations.js +8 -4
  223. package/build/src/task/store.d.ts +4 -6
  224. package/build/src/task/store.js +3 -3
  225. package/build/src/verification/declaration.d.ts +1 -0
  226. package/build/src/verification/execution.d.ts +49 -0
  227. package/build/src/verification/execution.js +104 -0
  228. package/build/src/world.d.ts +13 -0
  229. package/build/src/world.js +103 -0
  230. package/package.json +7 -4
  231. package/build/src/akuma/activity.d.ts +0 -66
  232. package/build/src/akuma/activity.js +0 -139
  233. package/build/src/akuma/providers/claude.js +0 -305
  234. package/build/src/context-root.d.ts +0 -4
  235. package/build/src/context-root.js +0 -15
  236. package/build/src/git/delivery.d.ts +0 -20
  237. package/build/src/git/delivery.js +0 -109
  238. package/build/src/git/verification.d.ts +0 -14
  239. package/build/src/git/verification.js +0 -56
  240. package/build/src/verification/producer.d.ts +0 -23
  241. package/build/src/verification/producer.js +0 -54
@@ -0,0 +1,265 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { AgentEventChannel, } from "../../provider.js";
3
+ import { emitClaudeMessage, } from "./events.js";
4
+ import { claudeUserMessage, createClaudeInput, isClaudeTurnEnded } from "./input.js";
5
+ export { CLAUDE_MESSAGE_DISPOSITIONS, CLAUDE_SYSTEM_DISPOSITIONS } from "./events.js";
6
+ class ReceiptChannel {
7
+ queued = [];
8
+ waiters = [];
9
+ ended = false;
10
+ emit(receipt) {
11
+ if (this.ended)
12
+ throw new Error("Claude receipt stream already ended");
13
+ const waiter = this.waiters.shift();
14
+ if (waiter === undefined)
15
+ this.queued.push(receipt);
16
+ else
17
+ waiter.resolve({ done: false, value: receipt });
18
+ }
19
+ end() {
20
+ if (this.ended)
21
+ return;
22
+ this.ended = true;
23
+ for (const waiter of this.waiters.splice(0))
24
+ waiter.resolve({ done: true, value: undefined });
25
+ }
26
+ [Symbol.asyncIterator]() {
27
+ return {
28
+ next: () => {
29
+ const receipt = this.queued.shift();
30
+ if (receipt !== undefined)
31
+ return Promise.resolve({ done: false, value: receipt });
32
+ if (this.ended)
33
+ return Promise.resolve({ done: true, value: undefined });
34
+ return new Promise((resolve) => this.waiters.push({ resolve }));
35
+ },
36
+ };
37
+ }
38
+ }
39
+ function admitClaudeOptions(options) {
40
+ if (options.network !== undefined) {
41
+ return { kind: "refused", diagnostic: "Claude provider does not support the Archetype network option" };
42
+ }
43
+ return { kind: "admitted", options: Object.freeze({ ...options }) };
44
+ }
45
+ function permissionMode(access) {
46
+ if (access === "read")
47
+ return "plan";
48
+ if (access === "write")
49
+ return "acceptEdits";
50
+ return "bypassPermissions";
51
+ }
52
+ function claudeSessionId(coordinate) {
53
+ if (!("sessionId" in coordinate) || coordinate.sessionId === undefined) {
54
+ throw new Error("Claude resume requires sessionId");
55
+ }
56
+ return coordinate.sessionId;
57
+ }
58
+ function claudeQueryOptions(input, execution, abortController) {
59
+ const access = permissionMode(input.options.access);
60
+ return {
61
+ cwd: input.cwd,
62
+ abortController,
63
+ ...(execution.executable === undefined ? {} : { pathToClaudeCodeExecutable: execution.executable }),
64
+ ...(execution.env === undefined ? {} : { env: { ...process.env, ...execution.env } }),
65
+ permissionMode: access,
66
+ ...(access === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {}),
67
+ settingSources: ["user", "project", "local"],
68
+ ...(input.options.model === undefined ? {} : { model: input.options.model }),
69
+ ...(input.options.effort === undefined ? {} : { effort: input.options.effort }),
70
+ ...(input.options.systemPrompt === undefined || input.options.systemPrompt.length === 0 ? {} : {
71
+ systemPrompt: { type: "preset", preset: "claude_code", append: input.options.systemPrompt },
72
+ }),
73
+ ...(input.session.kind === "fresh" ? {} : { resume: claudeSessionId(input.session.coordinate) }),
74
+ };
75
+ }
76
+ async function forkClaude(load, execution, input) {
77
+ const sessionId = claudeSessionId(input.session);
78
+ if (execution.env !== undefined)
79
+ throw new Error("Claude fork cannot apply the frozen provider environment");
80
+ const sdk = await load();
81
+ if (sdk.forkSession === undefined)
82
+ throw new Error("Claude SDK does not expose forkSession");
83
+ const forked = await sdk.forkSession(sessionId, { dir: input.cwd, upToMessageId: input.at });
84
+ if (forked.sessionId.trim().length === 0)
85
+ throw new Error("Claude fork returned an empty child session id");
86
+ if (forked.sessionId === sessionId)
87
+ throw new Error("Claude fork reused the source session id");
88
+ return { session: { sessionId: forked.sessionId } };
89
+ }
90
+ function launchText(input) {
91
+ return [input.body, ...input.launchTells.map((tell) => tell.text)]
92
+ .filter((part) => part.length > 0).join("\n\n");
93
+ }
94
+ function successfulResult(message, historyId) {
95
+ return historyId === undefined
96
+ ? { kind: "failed", diagnostic: "Claude query succeeded without an assistant history id" }
97
+ : { kind: "answered", answer: message.subtype === "success" ? message.result : "", historyId };
98
+ }
99
+ function finishClaudeInput(input, terminal) {
100
+ if (terminal?.kind === "answered")
101
+ input.end();
102
+ else
103
+ input.close();
104
+ }
105
+ function observeClaudeQuery(context) {
106
+ const { query, input, events, receipts, accepted, state } = context;
107
+ const observation = { tools: new Map() };
108
+ let admit;
109
+ let rejectAdmission;
110
+ const admission = new Promise((resolve, reject) => { admit = resolve; rejectAdmission = reject; });
111
+ let settle;
112
+ const completion = new Promise((resolve) => { settle = resolve; });
113
+ let checkpoint = 0, ended = false;
114
+ const settleReceipts = () => {
115
+ if (ended && state.openSubmissions === 0 && accepted.every((tell) => tell.visible))
116
+ receipts.end();
117
+ };
118
+ const flushReceipts = () => {
119
+ for (let index = 0; index < accepted.length;) {
120
+ const tell = accepted[index];
121
+ if (!tell.visible || tell.afterCheckpoint >= checkpoint) {
122
+ index += 1;
123
+ continue;
124
+ }
125
+ accepted.splice(index, 1);
126
+ receipts.emit({ evidence: "exact", tellId: tell.id, kind: "consumed" });
127
+ }
128
+ closeWhenIdle();
129
+ settleReceipts();
130
+ };
131
+ const closeWhenIdle = () => {
132
+ if (state.openSubmissions === 0 && accepted.length === 0 && input.pending === 0)
133
+ input.close();
134
+ };
135
+ void (async () => {
136
+ let admitted = false;
137
+ let terminal = null;
138
+ let historyId;
139
+ try {
140
+ for await (const message of query) {
141
+ if (!admitted && "session_id" in message && typeof message.session_id === "string") {
142
+ admitted = true;
143
+ events.emit({ type: "session", coordinate: { sessionId: message.session_id } });
144
+ admit();
145
+ }
146
+ emitClaudeMessage(message, events, observation);
147
+ if (message.type === "assistant" && message.parent_tool_use_id === null
148
+ && typeof message.uuid === "string" && message.uuid.length > 0)
149
+ historyId = message.uuid;
150
+ if (message.type !== "result")
151
+ continue;
152
+ if (message.subtype === "success") {
153
+ terminal = successfulResult(message, historyId);
154
+ checkpoint += 1;
155
+ flushReceipts();
156
+ queueMicrotask(closeWhenIdle);
157
+ }
158
+ else {
159
+ terminal = { kind: "failed", diagnostic: message.errors.join("; ") || message.subtype };
160
+ input.close();
161
+ }
162
+ }
163
+ ended = true;
164
+ const result = terminal ?? { kind: "failed", diagnostic: "Claude query ended without a result" };
165
+ if (!admitted)
166
+ rejectAdmission(new Error(result.kind === "failed" ? result.diagnostic : "Claude query ended before session admission"));
167
+ settle(result);
168
+ }
169
+ catch (error) {
170
+ ended = true;
171
+ input.fail(error);
172
+ const failure = error instanceof Error ? error : new Error(String(error));
173
+ if (!admitted)
174
+ rejectAdmission(failure);
175
+ settle({ kind: "failed", diagnostic: failure.message });
176
+ }
177
+ finally {
178
+ finishClaudeInput(input, terminal);
179
+ events.end();
180
+ settleReceipts();
181
+ }
182
+ })();
183
+ return {
184
+ admission,
185
+ completion,
186
+ get ended() { return ended; },
187
+ get checkpoint() { return checkpoint; },
188
+ flushReceipts,
189
+ settleReceipts,
190
+ };
191
+ }
192
+ async function driveClaude(load, execution, drive) {
193
+ if (drive.session.kind === "resume")
194
+ claudeSessionId(drive.session.coordinate);
195
+ const sdk = await load();
196
+ const events = new AgentEventChannel();
197
+ const receipts = new ReceiptChannel();
198
+ const input = createClaudeInput();
199
+ const abortController = new AbortController();
200
+ const run = randomUUID();
201
+ const accepted = [];
202
+ let submission = 0;
203
+ let openSubmissions = 0;
204
+ const launchAcknowledged = input.push(claudeUserMessage(launchText(drive)));
205
+ const query = sdk.query({
206
+ prompt: input.iterable,
207
+ options: claudeQueryOptions(drive, execution, abortController),
208
+ });
209
+ const observed = observeClaudeQuery({
210
+ query, input, events, receipts, accepted,
211
+ state: { get openSubmissions() { return openSubmissions; } },
212
+ });
213
+ await Promise.all([launchAcknowledged, observed.admission]);
214
+ return {
215
+ admission: { fence: `claude:${run}:0` },
216
+ events,
217
+ receipts,
218
+ completion: observed.completion,
219
+ tell(tell) {
220
+ if (observed.ended || input.closed)
221
+ return Promise.resolve({ kind: "turn-ended" });
222
+ openSubmissions += 1;
223
+ const ordinal = ++submission;
224
+ return new Promise((resolve, reject) => {
225
+ const pending = { id: tell.id, afterCheckpoint: 0, visible: false };
226
+ void input.push(claudeUserMessage(tell.text), () => {
227
+ pending.afterCheckpoint = observed.checkpoint;
228
+ accepted.push(pending);
229
+ }).then(() => {
230
+ openSubmissions -= 1;
231
+ resolve({ kind: "accepted", fence: `claude:${run}:${ordinal}` });
232
+ queueMicrotask(() => {
233
+ pending.visible = true;
234
+ observed.flushReceipts();
235
+ observed.settleReceipts();
236
+ });
237
+ }, (error) => {
238
+ openSubmissions -= 1;
239
+ if (isClaudeTurnEnded(error))
240
+ resolve({ kind: "turn-ended" });
241
+ else
242
+ reject(error);
243
+ observed.settleReceipts();
244
+ });
245
+ });
246
+ },
247
+ async abort() {
248
+ const error = new Error("Claude query aborted");
249
+ abortController.abort(error);
250
+ input.fail(error);
251
+ query.close();
252
+ await observed.completion;
253
+ },
254
+ };
255
+ }
256
+ export function createClaudeProvider(load, execution = {}) {
257
+ return {
258
+ confinement: () => ({ kind: "unconfined" }),
259
+ admitOptions: admitClaudeOptions,
260
+ fork: (input) => forkClaude(load, execution, input),
261
+ start: (input) => driveClaude(load, execution, input),
262
+ resume: (input) => driveClaude(load, execution, input),
263
+ };
264
+ }
265
+ export const claudeProvider = createClaudeProvider(async () => await import("@anthropic-ai/claude-agent-sdk"));
@@ -0,0 +1,13 @@
1
+ import type { SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
2
+ export declare function isClaudeTurnEnded(error: unknown): boolean;
3
+ export type ClaudeInput = Readonly<{
4
+ iterable: AsyncIterable<SDKUserMessage>;
5
+ get closed(): boolean;
6
+ get pending(): number;
7
+ push(message: SDKUserMessage, onPulled?: () => void): Promise<void>;
8
+ end(): void;
9
+ close(): void;
10
+ fail(error: unknown): void;
11
+ }>;
12
+ export declare function claudeUserMessage(text: string): SDKUserMessage;
13
+ export declare function createClaudeInput(): ClaudeInput;
@@ -0,0 +1,109 @@
1
+ function deferred() {
2
+ let resolve;
3
+ let reject;
4
+ const promise = new Promise((accept, refuse) => {
5
+ resolve = accept;
6
+ reject = refuse;
7
+ });
8
+ return { promise, resolve, reject };
9
+ }
10
+ function ended() {
11
+ return new Error("Claude input ended before the SDK acknowledged the message");
12
+ }
13
+ const turnEnded = Symbol("claude-turn-ended");
14
+ class ClaudeTurnEndedError extends Error {
15
+ [turnEnded] = true;
16
+ }
17
+ function turnEndedError() {
18
+ return new ClaudeTurnEndedError("Claude query ended before the SDK acknowledged the message");
19
+ }
20
+ export function isClaudeTurnEnded(error) {
21
+ return typeof error === "object" && error !== null && error[turnEnded] === true;
22
+ }
23
+ export function claudeUserMessage(text) {
24
+ return {
25
+ type: "user",
26
+ message: { role: "user", content: text },
27
+ parent_tool_use_id: null,
28
+ };
29
+ }
30
+ export function createClaudeInput() {
31
+ const queue = [];
32
+ const waiters = [];
33
+ let previous;
34
+ let failure;
35
+ let closed = false;
36
+ const acknowledgePrevious = () => {
37
+ previous?.onPulled?.();
38
+ previous?.pulled.resolve();
39
+ previous = undefined;
40
+ };
41
+ const take = (entry) => {
42
+ previous = entry;
43
+ return { done: false, value: entry.message };
44
+ };
45
+ const rejectUnresolved = (error) => {
46
+ previous?.pulled.reject(error);
47
+ previous = undefined;
48
+ for (const entry of queue.splice(0))
49
+ entry.pulled.reject(error);
50
+ };
51
+ return {
52
+ get closed() { return closed; },
53
+ get pending() { return queue.length + (previous === undefined ? 0 : 1); },
54
+ push(message, onPulled) {
55
+ if (closed)
56
+ return Promise.reject(failure ?? ended());
57
+ const entry = { message, pulled: deferred(), ...(onPulled === undefined ? {} : { onPulled }) };
58
+ const waiter = waiters.shift();
59
+ if (waiter === undefined)
60
+ queue.push(entry);
61
+ else
62
+ waiter.resolve(take(entry));
63
+ return entry.pulled.promise;
64
+ },
65
+ end() {
66
+ if (closed)
67
+ return;
68
+ closed = true;
69
+ rejectUnresolved(turnEndedError());
70
+ for (const waiter of waiters.splice(0))
71
+ waiter.resolve({ done: true, value: undefined });
72
+ },
73
+ close() {
74
+ if (closed)
75
+ return;
76
+ closed = true;
77
+ const error = ended();
78
+ rejectUnresolved(error);
79
+ for (const waiter of waiters.splice(0))
80
+ waiter.resolve({ done: true, value: undefined });
81
+ },
82
+ fail(error) {
83
+ if (closed)
84
+ return;
85
+ closed = true;
86
+ failure = error;
87
+ rejectUnresolved(error);
88
+ for (const waiter of waiters.splice(0))
89
+ waiter.reject(error);
90
+ },
91
+ iterable: {
92
+ [Symbol.asyncIterator]() {
93
+ return {
94
+ next() {
95
+ acknowledgePrevious();
96
+ const entry = queue.shift();
97
+ if (entry !== undefined)
98
+ return Promise.resolve(take(entry));
99
+ if (failure !== undefined)
100
+ return Promise.reject(failure);
101
+ if (closed)
102
+ return Promise.resolve({ done: true, value: undefined });
103
+ return new Promise((resolve, reject) => waiters.push({ resolve, reject }));
104
+ },
105
+ };
106
+ },
107
+ },
108
+ };
109
+ }
@@ -3,7 +3,7 @@ import { AgentEventChannel, type ToolCall, type TurnResult } from "../../provide
3
3
  export type CodexTurnState = {
4
4
  threadId?: string;
5
5
  turnId?: string;
6
- answers: string[];
6
+ lastAnswer?: string;
7
7
  error?: string;
8
8
  settled: boolean;
9
9
  tools: Map<string, Readonly<{
@@ -1,4 +1,4 @@
1
- import { boundedEventText, boundedThoughtText, noteEvent, unknownEvent, } from "../../provider.js";
1
+ import { noteEvent, unknownEvent, } from "../../provider.js";
2
2
  export const CODEX_NOTIFICATION_DISPOSITIONS = {
3
3
  "account/login/completed": "drop",
4
4
  "account/rateLimits/updated": "drop",
@@ -160,7 +160,7 @@ function itemChanges(item) {
160
160
  const diffstat = typeof change?.diff === "string" ? diffstatFromUnifiedPatch(change.diff) : undefined;
161
161
  return [{
162
162
  op,
163
- path: boundedEventText(path),
163
+ path,
164
164
  ...(diffstat === undefined ? {} : { diffstat }),
165
165
  }];
166
166
  });
@@ -179,20 +179,20 @@ function reasoningSummary(item) {
179
179
  }
180
180
  function itemToolCall(item, kind) {
181
181
  if (kind === "commandExecution") {
182
- return { kind: "run", command: boundedEventText(codexText(item.command) ?? "command") };
182
+ return { kind: "run", command: codexText(item.command) ?? "command" };
183
183
  }
184
184
  if (kind === "imageView") {
185
185
  const path = codexText(item.path);
186
- return path === undefined ? { kind: "other", display: "image view" } : { kind: "read", path: boundedEventText(path) };
186
+ return path === undefined ? { kind: "other", display: "image view" } : { kind: "read", path };
187
187
  }
188
188
  if (kind === "webSearch") {
189
- return { kind: "search", query: boundedEventText(codexText(item.query) ?? "web search") };
189
+ return { kind: "search", query: codexText(item.query) ?? "web search" };
190
190
  }
191
191
  if (kind === "fileChange") {
192
192
  const changes = itemChanges(item);
193
193
  return changes.length === 0 ? { kind: "other", display: "fileChange" } : { kind: "fileChange", changes };
194
194
  }
195
- return { kind: "other", display: boundedEventText(itemToolName(item, kind)) };
195
+ return { kind: "other", display: itemToolName(item, kind) };
196
196
  }
197
197
  function itemToolResult(item) {
198
198
  const error = codexObject(item.error);
@@ -202,7 +202,7 @@ function itemToolResult(item) {
202
202
  const exitCode = typeof item.exitCode === "number" && Number.isSafeInteger(item.exitCode) ? item.exitCode : undefined;
203
203
  return {
204
204
  status: failed || (exitCode !== undefined && exitCode !== 0) ? "error" : "ok",
205
- ...(detail === undefined ? {} : { message: boundedEventText(detail) }),
205
+ ...(detail === undefined ? {} : { message: detail }),
206
206
  ...(exitCode === undefined ? {} : { exitCode }),
207
207
  };
208
208
  }
@@ -216,10 +216,10 @@ function emitItem(item, completed, events, state) {
216
216
  if (disposition === "assistant") {
217
217
  if (!completed)
218
218
  return;
219
- const message = codexText(item.text);
219
+ const message = typeof item.text === "string" ? item.text : undefined;
220
220
  if (message !== undefined) {
221
- state.answers.push(message);
222
- events.emit({ type: "assistant", text: boundedEventText(message) });
221
+ state.lastAnswer = message;
222
+ events.emit({ type: "assistant", text: message });
223
223
  }
224
224
  return;
225
225
  }
@@ -233,7 +233,7 @@ function emitItem(item, completed, events, state) {
233
233
  return;
234
234
  const summary = reasoningSummary(item);
235
235
  if (summary !== undefined)
236
- events.emit({ type: "thought", text: boundedThoughtText(summary) });
236
+ events.emit({ type: "thought", text: summary });
237
237
  return;
238
238
  }
239
239
  if (disposition === "note") {
@@ -300,7 +300,7 @@ function terminalResult(params, state) {
300
300
  return { kind: "failed", diagnostic: "codex app-server completed a different turn" };
301
301
  }
302
302
  return status === "completed"
303
- ? { kind: "answered", answer: state.answers.join("\n\n"), historyId: completedId }
303
+ ? { kind: "answered", answer: state.lastAnswer ?? "", historyId: completedId }
304
304
  : { kind: "failed", diagnostic: turnError(turn?.error) ?? state.error ?? `codex app-server turn ended ${status}` };
305
305
  }
306
306
  export function codexNotificationResult(notification, state, events) {
@@ -1,4 +1,4 @@
1
- import { type Drive, type ProviderAdapter, type ProviderOptions } from "../../provider.js";
1
+ import { type Session, type ProviderAdapter, type ProviderOptions } from "../../provider.js";
2
2
  import type { ProviderExecution } from "../../heart/index.js";
3
3
  export { CODEX_ITEM_DISPOSITIONS, CODEX_NOTIFICATION_DISPOSITIONS } from "./events.js";
4
4
  export declare function createCodexAppServerProvider(input?: string | ProviderExecution): ProviderAdapter;
@@ -9,19 +9,21 @@ export declare const codexAppServerProvider: Readonly<{
9
9
  }>): import("../../heart/facts.js").Confinement;
10
10
  admitOptions(options: ProviderOptions): import("../../provider.js").ProviderOptionAdmission;
11
11
  fork?(input: Readonly<{
12
- session: import("../../provider.js").ResumeCoordinate;
12
+ session: import("../../coordinate.js").ResumeCoordinate;
13
13
  at: string;
14
14
  cwd: string;
15
15
  }>): Promise<Readonly<{
16
- session: import("../../provider.js").ResumeCoordinate;
16
+ session: import("../../coordinate.js").ResumeCoordinate;
17
17
  }>>;
18
- start(input: Readonly<{
19
- prompt: string;
20
- cwd: string;
21
- options: ProviderOptions;
22
- session?: import("../../provider.js").ResumeCoordinate;
23
- requests?: Readonly<{
24
- dir: string;
18
+ start(input: import("../../provider.js").DriveInput & Readonly<{
19
+ session: Readonly<{
20
+ kind: "fresh";
21
+ }>;
22
+ }>): Promise<Session>;
23
+ resume?(input: import("../../provider.js").DriveInput & Readonly<{
24
+ session: Readonly<{
25
+ kind: "resume";
26
+ coordinate: import("../../coordinate.js").ResumeCoordinate;
25
27
  }>;
26
- }>): Promise<Drive>;
28
+ }>): Promise<Session>;
27
29
  }>;