@astrosheep/keiyaku 4.1.0 → 4.1.2

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 (278) hide show
  1. package/README.md +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
  5. package/build/src/akuma/akuma-errors.d.ts +6 -0
  6. package/build/src/akuma/akuma-errors.js +9 -0
  7. package/build/src/akuma/akuma-handle.d.ts +39 -0
  8. package/build/src/akuma/akuma-handle.js +263 -0
  9. package/build/src/akuma/akuma-observe.d.ts +19 -0
  10. package/build/src/akuma/akuma-observe.js +74 -0
  11. package/build/src/akuma/akuma-product-symbols.d.ts +1 -0
  12. package/build/src/akuma/akuma-product-symbols.js +1 -0
  13. package/build/src/akuma/akuma-product.d.ts +18 -0
  14. package/build/src/akuma/akuma-product.js +154 -0
  15. package/build/src/akuma/akuma.d.ts +37 -81
  16. package/build/src/akuma/akuma.js +39 -447
  17. package/build/src/akuma/allowed.d.ts +1 -0
  18. package/build/src/akuma/allowed.js +6 -0
  19. package/build/src/akuma/archetype.js +8 -5
  20. package/build/src/akuma/body-supervisor.d.ts +26 -0
  21. package/build/src/akuma/body-supervisor.js +89 -0
  22. package/build/src/akuma/body.d.ts +45 -4
  23. package/build/src/akuma/body.js +145 -35
  24. package/build/src/akuma/coordinate.js +17 -7
  25. package/build/src/akuma/heart/facts.js +1 -1
  26. package/build/src/akuma/heart/index.d.ts +1 -1
  27. package/build/src/akuma/heart/index.js +2 -4
  28. package/build/src/akuma/heart/request-authority.js +4 -4
  29. package/build/src/akuma/heart/request-rows.js +27 -16
  30. package/build/src/akuma/heart/rows.js +79 -41
  31. package/build/src/akuma/heart/soul.js +1 -1
  32. package/build/src/akuma/heart/storage.d.ts +1 -0
  33. package/build/src/akuma/heart/storage.js +76 -11
  34. package/build/src/akuma/heart/tells.js +35 -18
  35. package/build/src/akuma/heart/timeline.js +19 -11
  36. package/build/src/akuma/identity.d.ts +1 -0
  37. package/build/src/akuma/identity.js +1 -0
  38. package/build/src/akuma/index.d.ts +3 -3
  39. package/build/src/akuma/index.js +1 -1
  40. package/build/src/akuma/nuke.js +106 -14
  41. package/build/src/akuma/projection-read.d.ts +17 -0
  42. package/build/src/akuma/projection-read.js +135 -0
  43. package/build/src/akuma/projection.d.ts +1 -16
  44. package/build/src/akuma/projection.js +77 -154
  45. package/build/src/akuma/provider-recipe.js +11 -5
  46. package/build/src/akuma/provider.js +105 -62
  47. package/build/src/akuma/providers/acp/config.js +5 -6
  48. package/build/src/akuma/providers/acp/core.js +17 -10
  49. package/build/src/akuma/providers/acp/events.js +38 -29
  50. package/build/src/akuma/providers/acp/index.js +13 -9
  51. package/build/src/akuma/providers/claude/events.js +8 -12
  52. package/build/src/akuma/providers/claude/index.d.ts +1 -0
  53. package/build/src/akuma/providers/claude/index.js +55 -26
  54. package/build/src/akuma/providers/claude/input.js +6 -2
  55. package/build/src/akuma/providers/codex-app-server/events.js +61 -36
  56. package/build/src/akuma/providers/codex-app-server/index.js +25 -13
  57. package/build/src/akuma/providers/grok-build/index.js +22 -25
  58. package/build/src/akuma/providers/index.js +2 -18
  59. package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
  60. package/build/src/akuma/providers/opencode-sdk/index.js +26 -17
  61. package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
  62. package/build/src/akuma/providers/pi/events.js +26 -19
  63. package/build/src/akuma/providers/pi/index.js +58 -40
  64. package/build/src/akuma/publication.js +9 -9
  65. package/build/src/akuma/request-execution.d.ts +6 -0
  66. package/build/src/akuma/request-execution.js +86 -0
  67. package/build/src/akuma/request-serve.d.ts +12 -1
  68. package/build/src/akuma/request-serve.js +19 -122
  69. package/build/src/akuma/request-wire.d.ts +2 -2
  70. package/build/src/akuma/request-wire.js +75 -102
  71. package/build/src/akuma/requests.js +2 -2
  72. package/build/src/akuma/{body-turn.d.ts → turn-drive.d.ts} +2 -25
  73. package/build/src/akuma/{body-turn.js → turn-drive.js} +20 -103
  74. package/build/src/akuma-body.js +6 -5
  75. package/build/src/body/amend.d.ts +4 -1
  76. package/build/src/body/amend.js +14 -6
  77. package/build/src/body/decode.js +2 -4
  78. package/build/src/body/envelope.js +2 -4
  79. package/build/src/body/region.d.ts +1 -2
  80. package/build/src/body/region.js +2 -70
  81. package/build/src/body/render.js +17 -12
  82. package/build/src/body/shape.js +1 -7
  83. package/build/src/cli/accepted.d.ts +1 -1
  84. package/build/src/cli/accepted.js +8 -1
  85. package/build/src/cli/commands/akuma-invoke.js +18 -6
  86. package/build/src/cli/commands/akuma.d.ts +0 -6
  87. package/build/src/cli/commands/akuma.js +11 -24
  88. package/build/src/cli/commands/amend.d.ts +2 -2
  89. package/build/src/cli/commands/amend.js +2 -4
  90. package/build/src/cli/commands/bind.d.ts +4 -4
  91. package/build/src/cli/commands/bind.js +16 -6
  92. package/build/src/cli/commands/contract-invoke.d.ts +25 -0
  93. package/build/src/cli/commands/contract-invoke.js +193 -0
  94. package/build/src/cli/commands/contract.d.ts +109 -10
  95. package/build/src/cli/commands/contract.js +339 -16
  96. package/build/src/cli/commands/install.d.ts +1 -1
  97. package/build/src/cli/commands/install.js +23 -15
  98. package/build/src/cli/commands/task-invoke.js +187 -67
  99. package/build/src/cli/commands/task-query.js +48 -24
  100. package/build/src/cli/commands/task.js +150 -38
  101. package/build/src/cli/coordinates.js +2 -4
  102. package/build/src/cli/invoke.js +92 -208
  103. package/build/src/cli/main.js +4 -2
  104. package/build/src/cli/parse.d.ts +3 -90
  105. package/build/src/cli/parse.js +27 -233
  106. package/build/src/cli/render/akuma-activity.d.ts +38 -0
  107. package/build/src/cli/render/akuma-activity.js +362 -0
  108. package/build/src/cli/render/akuma-tool-command.js +6 -7
  109. package/build/src/cli/render/akuma-tool.js +10 -8
  110. package/build/src/cli/render/akuma.d.ts +1 -1
  111. package/build/src/cli/render/akuma.js +61 -353
  112. package/build/src/cli/render/audit.js +5 -15
  113. package/build/src/cli/render/board.d.ts +1 -0
  114. package/build/src/cli/render/board.js +17 -0
  115. package/build/src/cli/render/catalog.js +81 -8
  116. package/build/src/cli/render/contract-history.d.ts +2 -0
  117. package/build/src/cli/render/contract-history.js +83 -0
  118. package/build/src/cli/render/contract-observation.d.ts +10 -0
  119. package/build/src/cli/render/contract-observation.js +58 -0
  120. package/build/src/cli/render/contract.d.ts +1 -2
  121. package/build/src/cli/render/contract.js +41 -142
  122. package/build/src/cli/render/kanshi.js +239 -215
  123. package/build/src/cli/render/receipt.js +2 -9
  124. package/build/src/cli/render/refusal.js +10 -15
  125. package/build/src/cli/render/region.js +22 -6
  126. package/build/src/cli/render/settings.js +4 -4
  127. package/build/src/cli/render/task.js +34 -14
  128. package/build/src/cli/render/terminal.js +16 -5
  129. package/build/src/cli/result.d.ts +3 -3
  130. package/build/src/cli/runtime.d.ts +6 -1
  131. package/build/src/cli/runtime.js +84 -63
  132. package/build/src/cli/selectors.js +2 -4
  133. package/build/src/cli/usage.js +6 -5
  134. package/build/src/contract-worktree.d.ts +1 -23
  135. package/build/src/contract-worktree.js +79 -155
  136. package/build/src/coordination/durable-file.js +7 -3
  137. package/build/src/coordination/sqlite-transaction-lock.js +29 -12
  138. package/build/src/core/facts/codec.js +7 -3
  139. package/build/src/core/facts/types.d.ts +1 -1
  140. package/build/src/core/subject.js +16 -9
  141. package/build/src/core/verbs/abandon.d.ts +1 -1
  142. package/build/src/core/verbs/abandon.js +1 -1
  143. package/build/src/core/verbs/amend.d.ts +1 -1
  144. package/build/src/core/verbs/amend.js +7 -7
  145. package/build/src/core/verbs/attestation.js +4 -1
  146. package/build/src/core/verbs/bind.d.ts +1 -1
  147. package/build/src/core/verbs/bind.js +1 -1
  148. package/build/src/core/verbs/placement.d.ts +1 -1
  149. package/build/src/core/verbs/placement.js +10 -8
  150. package/build/src/dispatch/index.js +8 -6
  151. package/build/src/duration.js +5 -1
  152. package/build/src/git/admission.js +5 -3
  153. package/build/src/git/hooks.d.ts +8 -0
  154. package/build/src/git/hooks.js +63 -14
  155. package/build/src/git/identity.js +1 -4
  156. package/build/src/git/integration.d.ts +2 -3
  157. package/build/src/git/integration.js +32 -39
  158. package/build/src/git/nuke.d.ts +1 -1
  159. package/build/src/git/nuke.js +110 -57
  160. package/build/src/git/observe.d.ts +13 -1
  161. package/build/src/git/observe.js +51 -44
  162. package/build/src/git/process.js +4 -2
  163. package/build/src/git/read-observation.js +10 -8
  164. package/build/src/git/reconcile.d.ts +22 -2
  165. package/build/src/git/reconcile.js +38 -274
  166. package/build/src/git/repository.d.ts +2 -0
  167. package/build/src/git/repository.js +13 -22
  168. package/build/src/git/scratch.d.ts +8 -5
  169. package/build/src/git/scratch.js +29 -2
  170. package/build/src/git/target-placement.d.ts +9 -10
  171. package/build/src/git/target-placement.js +59 -62
  172. package/build/src/git/tender.js +13 -46
  173. package/build/src/git/terminal-reconcile.d.ts +21 -0
  174. package/build/src/git/terminal-reconcile.js +278 -0
  175. package/build/src/git/terminal-seal.js +15 -12
  176. package/build/src/git/tree.js +5 -2
  177. package/build/src/git/workspace.d.ts +24 -2
  178. package/build/src/git/workspace.js +120 -16
  179. package/build/src/identity/coordinates.js +3 -1
  180. package/build/src/identity/selector.js +6 -3
  181. package/build/src/kanshi/fleet.d.ts +6 -0
  182. package/build/src/kanshi/fleet.js +27 -0
  183. package/build/src/kanshi/index.d.ts +1 -1
  184. package/build/src/kanshi/read.js +60 -48
  185. package/build/src/kanshi/report.d.ts +11 -23
  186. package/build/src/kanshi/select.js +25 -24
  187. package/build/src/library/address.d.ts +2 -1
  188. package/build/src/library/address.js +7 -8
  189. package/build/src/library/akuma-creation.js +20 -12
  190. package/build/src/library/audit.d.ts +0 -1
  191. package/build/src/library/audit.js +1 -2
  192. package/build/src/library/bind.d.ts +53 -5
  193. package/build/src/library/bind.js +98 -22
  194. package/build/src/library/catalog.d.ts +1 -0
  195. package/build/src/library/catalog.js +6 -3
  196. package/build/src/library/configuration.js +3 -1
  197. package/build/src/library/continuation.d.ts +15 -4
  198. package/build/src/library/continuation.js +24 -16
  199. package/build/src/library/contract-bind.d.ts +26 -0
  200. package/build/src/library/contract-bind.js +106 -0
  201. package/build/src/library/contract-operations.d.ts +77 -0
  202. package/build/src/library/contract-operations.js +130 -0
  203. package/build/src/library/contract-types.d.ts +95 -0
  204. package/build/src/library/contract-types.js +1 -0
  205. package/build/src/library/contract.d.ts +19 -154
  206. package/build/src/library/contract.js +46 -261
  207. package/build/src/library/fleet.d.ts +1 -1
  208. package/build/src/library/fleet.js +19 -11
  209. package/build/src/library/input.d.ts +2 -0
  210. package/build/src/library/input.js +14 -0
  211. package/build/src/library/keiyaku.d.ts +8 -7
  212. package/build/src/library/keiyaku.js +3 -3
  213. package/build/src/library/nuke.js +14 -5
  214. package/build/src/library/reconcile.d.ts +9 -4
  215. package/build/src/library/reconcile.js +30 -24
  216. package/build/src/library/refusal.d.ts +13 -5
  217. package/build/src/library/refusal.js +7 -0
  218. package/build/src/library/region.d.ts +8 -7
  219. package/build/src/library/region.js +31 -11
  220. package/build/src/library/repo.js +2 -2
  221. package/build/src/markdown/lex.js +9 -2
  222. package/build/src/markdown/parse.js +11 -7
  223. package/build/src/markdown/query.js +4 -2
  224. package/build/src/protocol/amend.js +3 -1
  225. package/build/src/protocol/attempt.d.ts +7 -3
  226. package/build/src/protocol/attempt.js +9 -5
  227. package/build/src/protocol/audit.d.ts +1 -1
  228. package/build/src/protocol/audit.js +4 -14
  229. package/build/src/protocol/bind.d.ts +19 -6
  230. package/build/src/protocol/bind.js +28 -13
  231. package/build/src/protocol/completion.d.ts +0 -1
  232. package/build/src/protocol/completion.js +1 -3
  233. package/build/src/protocol/deliver.d.ts +1 -3
  234. package/build/src/protocol/deliver.js +15 -39
  235. package/build/src/protocol/intent.d.ts +1 -0
  236. package/build/src/protocol/intent.js +9 -7
  237. package/build/src/protocol/operations.d.ts +3 -7
  238. package/build/src/protocol/operations.js +5 -3
  239. package/build/src/protocol/placement.d.ts +0 -1
  240. package/build/src/protocol/placement.js +6 -6
  241. package/build/src/protocol/read/observation.d.ts +11 -0
  242. package/build/src/protocol/read/observation.js +37 -0
  243. package/build/src/protocol/read/status.d.ts +23 -12
  244. package/build/src/protocol/read/status.js +90 -72
  245. package/build/src/protocol/reconcile.d.ts +1 -0
  246. package/build/src/protocol/reconcile.js +2 -3
  247. package/build/src/protocol/reintegrate.js +1 -1
  248. package/build/src/protocol/review.d.ts +0 -1
  249. package/build/src/protocol/review.js +15 -22
  250. package/build/src/protocol/run.d.ts +1 -0
  251. package/build/src/protocol/run.js +4 -5
  252. package/build/src/runtime/proc/launch.d.ts +33 -0
  253. package/build/src/runtime/proc/launch.js +98 -0
  254. package/build/src/runtime/proc/line-rpc.js +9 -3
  255. package/build/src/runtime/proc/run.d.ts +12 -6
  256. package/build/src/runtime/proc/run.js +78 -21
  257. package/build/src/runtime/proc/stdio.js +7 -10
  258. package/build/src/settings.js +6 -2
  259. package/build/src/settlement/holder.js +13 -10
  260. package/build/src/settlement/settle.js +39 -6
  261. package/build/src/task/board.js +12 -6
  262. package/build/src/task/compose.js +85 -22
  263. package/build/src/task/context.js +21 -8
  264. package/build/src/task/document.js +46 -10
  265. package/build/src/task/identity.js +5 -2
  266. package/build/src/task/index.d.ts +0 -1
  267. package/build/src/task/index.js +119 -34
  268. package/build/src/task/input.js +29 -7
  269. package/build/src/task/mutation.js +61 -19
  270. package/build/src/task/operations.d.ts +6 -1
  271. package/build/src/task/operations.js +83 -29
  272. package/build/src/task/query.js +55 -26
  273. package/build/src/task/store.d.ts +3 -1
  274. package/build/src/task/store.js +81 -17
  275. package/build/src/verification/execution.js +14 -11
  276. package/build/src/workspace-place.js +19 -7
  277. package/build/src/world.js +16 -6
  278. package/package.json +8 -3
@@ -14,7 +14,13 @@ function resumeCoordinate(value) {
14
14
  return coordinate;
15
15
  }
16
16
  export function encodeSessionRow(session) {
17
- return [session.provider, encodeResumeCoordinate(session.coordinate), session.cwd, json(session.options), session.admittedAt];
17
+ return [
18
+ session.provider,
19
+ encodeResumeCoordinate(session.coordinate),
20
+ session.cwd,
21
+ json(session.options),
22
+ session.admittedAt,
23
+ ];
18
24
  }
19
25
  export function encodeResumeCoordinate(coordinate) {
20
26
  return json(encodeCoordinate(coordinate));
@@ -82,7 +88,8 @@ export function sealExists(database) {
82
88
  return database.prepare("SELECT singleton FROM seal WHERE singleton = 1").get() !== undefined;
83
89
  }
84
90
  export function insertSealFact(database, input) {
85
- database.prepare("INSERT OR IGNORE INTO seal(singleton, evidence, at) VALUES (1, ?, ?)")
91
+ database
92
+ .prepare("INSERT OR IGNORE INTO seal(singleton, evidence, at) VALUES (1, ?, ?)")
86
93
  .run(input.evidence, input.at);
87
94
  }
88
95
  export function deletePauseControl(database) {
@@ -103,25 +110,30 @@ export function insertBodyFact(database, input) {
103
110
  return Number(result.lastInsertRowid);
104
111
  }
105
112
  export function insertSessionFact(database, input) {
106
- const result = database.prepare(`INSERT INTO sessions(provider, coordinate_json, cwd, options_json, admitted_at)
107
- VALUES (?, ?, ?, ?, ?)`).run(...encodeSessionRow(input));
113
+ const result = database
114
+ .prepare(`INSERT INTO sessions(provider, coordinate_json, cwd, options_json, admitted_at)
115
+ VALUES (?, ?, ?, ?, ?)`)
116
+ .run(...encodeSessionRow(input));
108
117
  return Number(result.lastInsertRowid);
109
118
  }
110
119
  export function insertActivityFact(database, input) {
111
120
  const sequence = Number(database.prepare("INSERT INTO timeline(kind) VALUES ('activity')").run().lastInsertRowid);
112
- database.prepare("INSERT INTO activity(sequence, turn_sequence, event_json, at) VALUES (?, ?, ?, ?)")
121
+ database
122
+ .prepare("INSERT INTO activity(sequence, turn_sequence, event_json, at) VALUES (?, ?, ?, ?)")
113
123
  .run(sequence, input.turnSequence, encodeActivityEvent(input.event), input.at);
114
124
  return sequence;
115
125
  }
116
126
  export function insertStopControl(database, bodySequence, at) {
117
- database.prepare("INSERT OR IGNORE INTO control(kind, value_json, at) VALUES ('stop', ?, ?)")
127
+ database
128
+ .prepare("INSERT OR IGNORE INTO control(kind, value_json, at) VALUES ('stop', ?, ?)")
118
129
  .run(json({ bodySequence }), at);
119
130
  }
120
131
  export function insertPauseControl(database, at) {
121
132
  const body = latestBodyFact(database);
122
133
  if (body === null)
123
134
  throw new Error("Akuma has no Body to interrupt");
124
- database.prepare("INSERT OR IGNORE INTO control(kind, value_json, at) VALUES ('pause', ?, ?)")
135
+ database
136
+ .prepare("INSERT OR IGNORE INTO control(kind, value_json, at) VALUES ('pause', ?, ?)")
125
137
  .run(json({ bodySequence: body.sequence }), at);
126
138
  }
127
139
  export function stopFact(database) {
@@ -145,15 +157,18 @@ export function pauseFact(database) {
145
157
  return { bodySequence: value.bodySequence, requestedAt: row.at };
146
158
  }
147
159
  export function insertKillFact(database, bodySequence, at) {
148
- database.prepare("INSERT OR IGNORE INTO kills(body_sequence, evidence, at) VALUES (?, 'killed', ?)")
160
+ database
161
+ .prepare("INSERT OR IGNORE INTO kills(body_sequence, evidence, at) VALUES (?, 'killed', ?)")
149
162
  .run(bodySequence, at);
150
163
  }
151
164
  export function endBodyFact(database, input) {
152
- database.prepare("UPDATE bodies SET end = ?, ended_at = ? WHERE sequence = ? AND end IS NULL")
165
+ database
166
+ .prepare("UPDATE bodies SET end = ?, ended_at = ? WHERE sequence = ? AND end IS NULL")
153
167
  .run(input.end, input.at, input.sequence);
154
168
  }
155
169
  export function markBodyHung(database, input) {
156
- const result = database.prepare(`UPDATE bodies SET hung_diagnostic = ?, hung_at = ?
170
+ const result = database
171
+ .prepare(`UPDATE bodies SET hung_diagnostic = ?, hung_at = ?
157
172
  WHERE sequence = ? AND hung_diagnostic IS NULL`)
158
173
  .run(input.diagnostic, input.at, input.sequence);
159
174
  if (result.changes !== 1)
@@ -161,11 +176,13 @@ export function markBodyHung(database, input) {
161
176
  }
162
177
  export function insertTurnStartFact(database, input) {
163
178
  const sequence = Number(database.prepare("INSERT INTO timeline(kind) VALUES ('turn-start')").run().lastInsertRowid);
164
- database.prepare("INSERT INTO turns(sequence, body_sequence, started_at) VALUES (?, ?, ?)")
179
+ database
180
+ .prepare("INSERT INTO turns(sequence, body_sequence, started_at) VALUES (?, ?, ?)")
165
181
  .run(sequence, input.bodySequence, input.startedAt);
166
182
  if (input.call !== undefined) {
167
183
  const callSequence = Number(database.prepare("INSERT INTO timeline(kind) VALUES ('call')").run().lastInsertRowid);
168
- database.prepare("INSERT INTO calls(sequence, turn_sequence, body, at) VALUES (?, ?, ?, ?)")
184
+ database
185
+ .prepare("INSERT INTO calls(sequence, turn_sequence, body, at) VALUES (?, ?, ?, ?)")
169
186
  .run(callSequence, sequence, input.call, input.startedAt);
170
187
  }
171
188
  return { kind: "turn-start", sequence, bodySequence: input.bodySequence, startedAt: input.startedAt };
@@ -173,62 +190,83 @@ export function insertTurnStartFact(database, input) {
173
190
  export function insertTurnEndFact(database, input) {
174
191
  const sequence = Number(database.prepare("INSERT INTO timeline(kind) VALUES ('turn-end')").run().lastInsertRowid);
175
192
  const result = input.outcome.kind === "answered"
176
- ? database.prepare(`UPDATE turns SET end_sequence = ?, outcome = 'answered', history_id = ?,
177
- session_json = ?, answer = ?, completed_at = ? WHERE sequence = ? AND end_sequence IS NULL`).run(sequence, input.outcome.historyId ?? null, encodeResumeCoordinate(input.outcome.session), input.outcome.answer, input.completedAt, input.turnSequence)
178
- : database.prepare(`UPDATE turns SET end_sequence = ?, outcome = 'failed', diagnostic = ?, completed_at = ?
179
- WHERE sequence = ? AND end_sequence IS NULL`).run(sequence, input.outcome.diagnostic, input.completedAt, input.turnSequence);
193
+ ? database
194
+ .prepare(`UPDATE turns SET end_sequence = ?, outcome = 'answered', history_id = ?,
195
+ session_json = ?, answer = ?, completed_at = ? WHERE sequence = ? AND end_sequence IS NULL`)
196
+ .run(sequence, input.outcome.historyId ?? null, encodeResumeCoordinate(input.outcome.session), input.outcome.answer, input.completedAt, input.turnSequence)
197
+ : database
198
+ .prepare(`UPDATE turns SET end_sequence = ?, outcome = 'failed', diagnostic = ?, completed_at = ?
199
+ WHERE sequence = ? AND end_sequence IS NULL`)
200
+ .run(sequence, input.outcome.diagnostic, input.completedAt, input.turnSequence);
180
201
  if (result.changes !== 1)
181
202
  throw new Error(`Akuma Turn ${input.turnSequence} is not open`);
182
203
  return { ...input, kind: "turn-end", sequence };
183
204
  }
184
205
  export function finishBodyFact(database, input) {
185
- database.prepare("UPDATE bodies SET end = 'exited', ended_at = ? WHERE sequence = ? AND end IS NULL")
206
+ database
207
+ .prepare("UPDATE bodies SET end = 'exited', ended_at = ? WHERE sequence = ? AND end IS NULL")
186
208
  .run(input.at, input.sequence);
187
209
  }
188
210
  export function latestBodyFact(database) {
189
- const row = database.prepare(`SELECT sequence, leash_taken_at, hung_diagnostic, hung_at, end, ended_at
190
- FROM bodies ORDER BY sequence DESC LIMIT 1`).get();
211
+ const row = database
212
+ .prepare(`SELECT sequence, leash_taken_at, hung_diagnostic, hung_at, end, ended_at
213
+ FROM bodies ORDER BY sequence DESC LIMIT 1`)
214
+ .get();
191
215
  return row === undefined ? null : decodeBodyRow(row);
192
216
  }
193
217
  export function latestSessionFact(database) {
194
- const row = database.prepare(`SELECT sequence, provider, coordinate_json, cwd, options_json, admitted_at
195
- FROM sessions ORDER BY sequence DESC LIMIT 1`).get();
218
+ const row = database
219
+ .prepare(`SELECT sequence, provider, coordinate_json, cwd, options_json, admitted_at
220
+ FROM sessions ORDER BY sequence DESC LIMIT 1`)
221
+ .get();
196
222
  return row === undefined ? null : decodeSessionRow(row);
197
223
  }
198
224
  export function sessionFactForCoordinate(database, coordinate) {
199
- const row = database.prepare(`SELECT sequence, provider, coordinate_json, cwd, options_json, admitted_at
225
+ const row = database
226
+ .prepare(`SELECT sequence, provider, coordinate_json, cwd, options_json, admitted_at
200
227
  FROM sessions WHERE coordinate_json = ? ORDER BY sequence DESC LIMIT 1`)
201
228
  .get(encodeResumeCoordinate(coordinate));
202
229
  return row === undefined ? null : decodeSessionRow(row);
203
230
  }
204
231
  export function latestKillFact(database) {
205
- const row = database.prepare(`SELECT sequence, body_sequence, evidence, at
206
- FROM kills ORDER BY sequence DESC LIMIT 1`).get();
207
- return row === undefined ? null : {
208
- sequence: row.sequence,
209
- bodySequence: row.body_sequence,
210
- evidence: row.evidence,
211
- at: row.at,
212
- };
232
+ const row = database
233
+ .prepare(`SELECT sequence, body_sequence, evidence, at
234
+ FROM kills ORDER BY sequence DESC LIMIT 1`)
235
+ .get();
236
+ return row === undefined
237
+ ? null
238
+ : {
239
+ sequence: row.sequence,
240
+ bodySequence: row.body_sequence,
241
+ evidence: row.evidence,
242
+ at: row.at,
243
+ };
213
244
  }
214
245
  export function killFactForBody(database, bodySequence) {
215
- const row = database.prepare(`SELECT sequence, body_sequence, evidence, at
216
- FROM kills WHERE body_sequence = ?`).get(bodySequence);
217
- return row === undefined ? null : {
218
- sequence: row.sequence,
219
- bodySequence: row.body_sequence,
220
- evidence: row.evidence,
221
- at: row.at,
222
- };
246
+ const row = database
247
+ .prepare(`SELECT sequence, body_sequence, evidence, at
248
+ FROM kills WHERE body_sequence = ?`)
249
+ .get(bodySequence);
250
+ return row === undefined
251
+ ? null
252
+ : {
253
+ sequence: row.sequence,
254
+ bodySequence: row.body_sequence,
255
+ evidence: row.evidence,
256
+ at: row.at,
257
+ };
223
258
  }
224
259
  export function lastAnsweredTurnFact(database) {
225
- const row = database.prepare(`SELECT sequence, body_sequence, started_at, end_sequence, outcome, history_id,
260
+ const row = database
261
+ .prepare(`SELECT sequence, body_sequence, started_at, end_sequence, outcome, history_id,
226
262
  session_json, answer, diagnostic, completed_at FROM turns WHERE outcome = 'answered' ORDER BY end_sequence DESC LIMIT 1`)
227
263
  .get();
228
264
  return row === undefined ? null : decodeTurnRow(row);
229
265
  }
230
266
  export function answeredTurnFact(database, historyId) {
231
- const row = database.prepare(`SELECT sequence, body_sequence, started_at, end_sequence, outcome, history_id,
232
- session_json, answer, diagnostic, completed_at FROM turns WHERE outcome = 'answered' AND history_id = ?`).get(historyId);
267
+ const row = database
268
+ .prepare(`SELECT sequence, body_sequence, started_at, end_sequence, outcome, history_id,
269
+ session_json, answer, diagnostic, completed_at FROM turns WHERE outcome = 'answered' AND history_id = ?`)
270
+ .get(historyId);
233
271
  return row === undefined ? null : decodeTurnRow(row);
234
272
  }
@@ -1,5 +1,5 @@
1
1
  import { parseAkuId } from "../identity.js";
2
- import { decodeProviderOptions, decodeProviderRecipe, decodeReadonlyRestraint, } from "../provider-recipe.js";
2
+ import { decodeProviderOptions, decodeProviderRecipe, decodeReadonlyRestraint } from "../provider-recipe.js";
3
3
  import { effectiveAllowedActions } from "../allowed.js";
4
4
  function record(value) {
5
5
  return value !== null && typeof value === "object" && !Array.isArray(value)
@@ -2,6 +2,7 @@ import { DatabaseSync } from "node:sqlite";
2
2
  import type { AkumaPaths } from "../identity.js";
3
3
  import type { BodyFact, LeashProbe, SessionFact, Soul, StopFact, TellFact } from "./facts.js";
4
4
  import { sealFact } from "./rows.js";
5
+ export declare function watchHeart(paths: AkumaPaths, signal: AbortSignal): Promise<AsyncGenerator<void>>;
5
6
  export declare class HeartAbsentError extends Error {
6
7
  readonly path: string;
7
8
  constructor(path: string, options?: ErrorOptions);
@@ -1,5 +1,7 @@
1
1
  import { DatabaseSync } from "node:sqlite";
2
+ import { watch as watchDirectory } from "node:fs";
2
3
  import { lstat } from "node:fs/promises";
4
+ import { basename, dirname } from "node:path";
3
5
  import { pathToFileURL } from "node:url";
4
6
  import { HEART_SCHEMA, LEASH_SCHEMA, assertHeartSchemaVersion, assertLeashSchemaVersion } from "./schema.js";
5
7
  import { deletePauseControl, deleteStopControl, insertBodyFact, insertKillFact, insertSealFact, insertSessionFact, killFactForBody, latestBodyFact, latestKillFact, markBodyHung, sealExists, sealFact, stopFact, } from "./rows.js";
@@ -8,6 +10,58 @@ import { pruneActivityFacts } from "./timeline.js";
8
10
  import { insertSoulFact, soulFact } from "./soul.js";
9
11
  const ACTIVITY_LIMIT = 5_000;
10
12
  const SQLITE_CANTOPEN = 14;
13
+ export async function watchHeart(paths, signal) {
14
+ const heart = basename(paths.heart);
15
+ const changes = [];
16
+ let failure;
17
+ let wake;
18
+ // fs.watch opens the directory synchronously. Its throw is therefore the
19
+ // observer's ready/failure boundary, before a waker can spawn a child.
20
+ const watcher = watchDirectory(dirname(paths.heart), { signal }, (_event, filename) => {
21
+ const name = filename?.toString();
22
+ if (name === undefined || name === heart || name === `${heart}-wal`) {
23
+ changes.push(undefined);
24
+ wake?.();
25
+ }
26
+ });
27
+ watcher.on("error", (error) => {
28
+ failure = error;
29
+ wake?.();
30
+ });
31
+ const abort = () => {
32
+ wake?.();
33
+ watcher.close();
34
+ };
35
+ signal.addEventListener("abort", abort, { once: true });
36
+ return (async function* () {
37
+ try {
38
+ for (;;) {
39
+ if (changes.length > 0) {
40
+ changes.shift();
41
+ yield;
42
+ continue;
43
+ }
44
+ if (failure !== undefined)
45
+ throw failure;
46
+ if (signal.aborted)
47
+ return;
48
+ await new Promise((resolve) => {
49
+ wake = resolve;
50
+ });
51
+ wake = undefined;
52
+ }
53
+ }
54
+ catch (error) {
55
+ if (signal.aborted && error.name === "AbortError")
56
+ return;
57
+ throw error;
58
+ }
59
+ finally {
60
+ signal.removeEventListener("abort", abort);
61
+ watcher.close();
62
+ }
63
+ })();
64
+ }
11
65
  export class HeartAbsentError extends Error {
12
66
  path;
13
67
  constructor(path, options) {
@@ -22,16 +76,17 @@ export function isHeartAbsent(error) {
22
76
  function isBusy(error) {
23
77
  const value = error;
24
78
  const message = String(value?.message ?? "").toLowerCase();
25
- return value?.code === "ERR_SQLITE_BUSY" || value?.code === "ERR_SQLITE_LOCKED"
26
- || value?.errcode === 5 || message.includes("database is locked") || message.includes("database is busy");
79
+ return (value?.code === "ERR_SQLITE_BUSY" ||
80
+ value?.code === "ERR_SQLITE_LOCKED" ||
81
+ value?.errcode === 5 ||
82
+ message.includes("database is locked") ||
83
+ message.includes("database is busy"));
27
84
  }
28
85
  async function openExistingDatabase(path, timeout) {
29
86
  const uri = pathToFileURL(path);
30
87
  uri.searchParams.set("mode", "rw");
31
88
  try {
32
- return timeout === undefined
33
- ? new DatabaseSync(uri.href)
34
- : new DatabaseSync(uri.href, { timeout });
89
+ return timeout === undefined ? new DatabaseSync(uri.href) : new DatabaseSync(uri.href, { timeout });
35
90
  }
36
91
  catch (error) {
37
92
  if (error.errcode === SQLITE_CANTOPEN) {
@@ -80,7 +135,9 @@ export function transaction(database, body) {
80
135
  try {
81
136
  database.exec("ROLLBACK");
82
137
  }
83
- catch { /* preserve the adjudication failure */ }
138
+ catch {
139
+ /* preserve the adjudication failure */
140
+ }
84
141
  throw error;
85
142
  }
86
143
  }
@@ -95,7 +152,9 @@ export function readTransaction(database, body) {
95
152
  try {
96
153
  database.exec("ROLLBACK");
97
154
  }
98
- catch { /* preserve the original failure */ }
155
+ catch {
156
+ /* preserve the original failure */
157
+ }
99
158
  throw error;
100
159
  }
101
160
  }
@@ -153,7 +212,7 @@ export class HeldAkumaLeash {
153
212
  async sealIfUnborn(paths, input) {
154
213
  if (sealExists(this.database))
155
214
  return "sealed";
156
- if (await withHeart(paths, (heart) => soulFact(heart)) !== null)
215
+ if ((await withHeart(paths, (heart) => soulFact(heart))) !== null)
157
216
  return "born";
158
217
  insertSealFact(this.database, input);
159
218
  this.database.exec("COMMIT");
@@ -164,8 +223,12 @@ export class HeldAkumaLeash {
164
223
  readSeal() {
165
224
  return sealFact(this.database);
166
225
  }
167
- async clearPause(paths) { await withHeart(paths, deletePauseControl); }
168
- async clearStop(paths) { await withHeart(paths, deleteStopControl); }
226
+ async clearPause(paths) {
227
+ await withHeart(paths, deletePauseControl);
228
+ }
229
+ async clearStop(paths) {
230
+ await withHeart(paths, deleteStopControl);
231
+ }
169
232
  async recordBody(paths, input) {
170
233
  if (this.closed || this.bodySequence !== undefined)
171
234
  throw new Error("Akuma leash cannot start another Body");
@@ -186,7 +249,9 @@ export class HeldAkumaLeash {
186
249
  if (expectedBodySequence === undefined)
187
250
  return null;
188
251
  const existing = killFactForBody(heart, expectedBodySequence);
189
- return existing === null ? null : { target: { bodySequence: expectedBodySequence, requestedAt: existing.at }, result: "already-killed" };
252
+ return existing === null
253
+ ? null
254
+ : { target: { bodySequence: expectedBodySequence, requestedAt: existing.at }, result: "already-killed" };
190
255
  }
191
256
  if (expectedBodySequence !== undefined && target.bodySequence !== expectedBodySequence) {
192
257
  throw new Error("Akuma stop target changed while kill was in progress");
@@ -15,8 +15,10 @@ export const pendingTellSequencesSql = `SELECT tells.sequence FROM tells WHERE $
15
15
  export const pendingTellProtectionSql = `SELECT d.turn_sequence FROM tell_deliveries d
16
16
  JOIN tells ON tells.id = d.tell_id WHERE ${tellStateSql} = 'pending'`;
17
17
  function tellDeliveries(database, id) {
18
- const rows = database.prepare(`SELECT turn_sequence, route, receipt, delivered_at FROM tell_deliveries
19
- WHERE tell_id = ? ORDER BY sequence`).all(id);
18
+ const rows = database
19
+ .prepare(`SELECT turn_sequence, route, receipt, delivered_at FROM tell_deliveries
20
+ WHERE tell_id = ? ORDER BY sequence`)
21
+ .all(id);
20
22
  return rows.map((row) => row.receipt == null
21
23
  ? { turnSequence: row.turn_sequence, route: row.route, deliveredAt: row.delivered_at }
22
24
  : { turnSequence: row.turn_sequence, route: row.route, receipt: row.receipt, deliveredAt: row.delivered_at });
@@ -33,47 +35,62 @@ function decodeTellRow(database, row) {
33
35
  };
34
36
  }
35
37
  export function decodeTellAtSequence(database, sequence) {
36
- const row = database.prepare(`SELECT sequence, id, body, recorded_at, ${tellStateSql} AS state
37
- FROM tells WHERE sequence = ?`).get(sequence);
38
+ const row = database
39
+ .prepare(`SELECT sequence, id, body, recorded_at, ${tellStateSql} AS state
40
+ FROM tells WHERE sequence = ?`)
41
+ .get(sequence);
38
42
  if (row === undefined)
39
43
  throw new Error(`Akuma timeline references missing tell ${sequence}`);
40
44
  return decodeTellRow(database, row);
41
45
  }
42
46
  export function insertTellFact(database, tell) {
43
47
  const sequence = Number(database.prepare("INSERT INTO timeline(kind) VALUES ('tell')").run().lastInsertRowid);
44
- database.prepare("INSERT INTO tells(id, sequence, body, recorded_at) VALUES (?, ?, ?, ?)")
48
+ database
49
+ .prepare("INSERT INTO tells(id, sequence, body, recorded_at) VALUES (?, ?, ?, ?)")
45
50
  .run(tell.id, sequence, tell.body, tell.recordedAt);
46
51
  return sequence;
47
52
  }
48
53
  export function tellFact(database, id) {
49
- const row = database.prepare(`SELECT sequence, id, body, recorded_at, ${tellStateSql} AS state
50
- FROM tells WHERE id = ?`).get(id);
54
+ const row = database
55
+ .prepare(`SELECT sequence, id, body, recorded_at, ${tellStateSql} AS state
56
+ FROM tells WHERE id = ?`)
57
+ .get(id);
51
58
  return row === undefined ? null : decodeTellRow(database, row);
52
59
  }
53
60
  export function insertTellDeliveryFact(database, input) {
54
- const result = database.prepare(`INSERT OR IGNORE INTO tell_deliveries(
61
+ const result = database
62
+ .prepare(`INSERT OR IGNORE INTO tell_deliveries(
55
63
  tell_id, route, turn_sequence, fence, receipt, delivered_at
56
- ) VALUES (?, ?, ?, ?, ?, ?)`).run(input.tellId, input.route, input.turnSequence, input.fence, input.route === "live" ? input.receipt : null, input.deliveredAt);
57
- const row = database.prepare(`SELECT route, receipt FROM tell_deliveries
64
+ ) VALUES (?, ?, ?, ?, ?, ?)`)
65
+ .run(input.tellId, input.route, input.turnSequence, input.fence, input.route === "live" ? input.receipt : null, input.deliveredAt);
66
+ const row = database
67
+ .prepare(`SELECT route, receipt FROM tell_deliveries
58
68
  WHERE tell_id = ? AND turn_sequence = ? AND fence = ?`)
59
69
  .get(input.tellId, input.turnSequence, input.fence);
60
- if (row === undefined || (result.changes === 0
61
- && (row.route !== input.route || row.receipt !== (input.route === "live" ? input.receipt : null)))) {
70
+ if (row === undefined ||
71
+ (result.changes === 0 &&
72
+ (row.route !== input.route || row.receipt !== (input.route === "live" ? input.receipt : null)))) {
62
73
  throw new Error(`tell delivery ${input.tellId} has conflicting evidence`);
63
74
  }
64
75
  }
65
76
  export function insertTellReceiptFact(database, input) {
66
- database.prepare(`INSERT OR IGNORE INTO tell_receipts(
77
+ database
78
+ .prepare(`INSERT OR IGNORE INTO tell_receipts(
67
79
  evidence, tell_id, turn_sequence, fence, kind, received_at
68
- ) VALUES (?, ?, ?, ?, ?, ?)`).run(input.evidence, input.evidence === "exact" ? input.tellId : null, input.evidence === "fence" ? input.turnSequence : null, input.evidence === "fence" ? input.fence : null, input.kind, input.receivedAt);
80
+ ) VALUES (?, ?, ?, ?, ?, ?)`)
81
+ .run(input.evidence, input.evidence === "exact" ? input.tellId : null, input.evidence === "fence" ? input.turnSequence : null, input.evidence === "fence" ? input.fence : null, input.kind, input.receivedAt);
69
82
  }
70
83
  export function tellIdsForFence(database, turnSequence, fence) {
71
- return database.prepare(`SELECT tell_id FROM tell_deliveries
84
+ return database
85
+ .prepare(`SELECT tell_id FROM tell_deliveries
72
86
  WHERE turn_sequence = ? AND fence = ? ORDER BY sequence`)
73
- .all(turnSequence, fence).map((row) => row.tell_id);
87
+ .all(turnSequence, fence)
88
+ .map((row) => row.tell_id);
74
89
  }
75
90
  export function pendingTellFacts(database) {
76
- const rows = database.prepare(`SELECT sequence, id, body, recorded_at, ${tellStateSql} AS state FROM tells
77
- WHERE ${tellStateSql} = 'pending' ORDER BY sequence`).all();
91
+ const rows = database
92
+ .prepare(`SELECT sequence, id, body, recorded_at, ${tellStateSql} AS state FROM tells
93
+ WHERE ${tellStateSql} = 'pending' ORDER BY sequence`)
94
+ .all();
78
95
  return rows.map((row) => decodeTellRow(database, row));
79
96
  }
@@ -1,7 +1,8 @@
1
1
  import { decodeActivityRow, decodeCallRow, decodeTurnRow, } from "./rows.js";
2
2
  import { decodeTellAtSequence, pendingTellProtectionSql, pendingTellSequencesSql } from "./tells.js";
3
3
  export function lastActivityAt(database) {
4
- const row = database.prepare(`SELECT CASE timeline.kind
4
+ const row = database
5
+ .prepare(`SELECT CASE timeline.kind
5
6
  WHEN 'turn-start' THEN started_turn.started_at
6
7
  WHEN 'call' THEN calls.at
7
8
  WHEN 'activity' THEN activity.at
@@ -14,7 +15,8 @@ export function lastActivityAt(database) {
14
15
  LEFT JOIN activity ON timeline.kind = 'activity' AND activity.sequence = timeline.sequence
15
16
  LEFT JOIN tells ON timeline.kind = 'tell' AND tells.sequence = timeline.sequence
16
17
  LEFT JOIN turns AS ended_turn ON timeline.kind = 'turn-end' AND ended_turn.end_sequence = timeline.sequence
17
- ORDER BY timeline.sequence DESC LIMIT 1`).get();
18
+ ORDER BY timeline.sequence DESC LIMIT 1`)
19
+ .get();
18
20
  if (row === undefined || row.at === null)
19
21
  return null;
20
22
  return row.at;
@@ -23,11 +25,13 @@ export function pruneActivityFacts(database, limit) {
23
25
  const count = database.prepare("SELECT COUNT(*) AS count FROM timeline").get();
24
26
  if (count.count <= limit + 500)
25
27
  return;
26
- const cutoff = database.prepare(`SELECT sequence FROM timeline ORDER BY sequence DESC LIMIT 1 OFFSET ?`)
28
+ const cutoff = database
29
+ .prepare(`SELECT sequence FROM timeline ORDER BY sequence DESC LIMIT 1 OFFSET ?`)
27
30
  .get(limit - 1);
28
31
  if (cutoff === undefined)
29
32
  return;
30
- database.prepare(`WITH protected_turns(sequence) AS (
33
+ database
34
+ .prepare(`WITH protected_turns(sequence) AS (
31
35
  SELECT sequence FROM turns WHERE end_sequence IS NULL
32
36
  UNION SELECT turn_sequence FROM calls WHERE sequence >= ?
33
37
  UNION SELECT turn_sequence FROM activity WHERE sequence >= ?
@@ -43,7 +47,8 @@ export function pruneActivityFacts(database, limit) {
43
47
  .run(cutoff.sequence, cutoff.sequence, cutoff.sequence, cutoff.sequence);
44
48
  }
45
49
  function turn(database, sequence) {
46
- const row = database.prepare(`SELECT sequence, body_sequence, started_at, end_sequence, outcome,
50
+ const row = database
51
+ .prepare(`SELECT sequence, body_sequence, started_at, end_sequence, outcome,
47
52
  history_id, session_json, answer, diagnostic, completed_at FROM turns WHERE sequence = ?`)
48
53
  .get(sequence);
49
54
  if (row === undefined)
@@ -51,7 +56,8 @@ function turn(database, sequence) {
51
56
  return decodeTurnRow(row);
52
57
  }
53
58
  function turnStart(database, sequence) {
54
- const row = database.prepare("SELECT sequence, body_sequence, started_at FROM turns WHERE sequence = ?")
59
+ const row = database
60
+ .prepare("SELECT sequence, body_sequence, started_at FROM turns WHERE sequence = ?")
55
61
  .get(sequence);
56
62
  if (row === undefined)
57
63
  throw new Error(`Akuma timeline references missing Turn ${sequence}`);
@@ -68,14 +74,16 @@ function decodeTimelineRow(database, row) {
68
74
  return fact;
69
75
  }
70
76
  if (row.kind === "call") {
71
- const value = database.prepare("SELECT sequence, turn_sequence, body, at FROM calls WHERE sequence = ?")
77
+ const value = database
78
+ .prepare("SELECT sequence, turn_sequence, body, at FROM calls WHERE sequence = ?")
72
79
  .get(row.sequence);
73
80
  if (value === undefined)
74
81
  throw new Error(`Akuma timeline references missing call ${row.sequence}`);
75
82
  return decodeCallRow(value);
76
83
  }
77
84
  if (row.kind === "activity") {
78
- const value = database.prepare("SELECT sequence, turn_sequence, event_json, at FROM activity WHERE sequence = ?")
85
+ const value = database
86
+ .prepare("SELECT sequence, turn_sequence, event_json, at FROM activity WHERE sequence = ?")
79
87
  .get(row.sequence);
80
88
  if (value === undefined)
81
89
  throw new Error(`Akuma timeline references missing activity ${row.sequence}`);
@@ -84,9 +92,9 @@ function decodeTimelineRow(database, row) {
84
92
  return decodeTellAtSequence(database, row.sequence);
85
93
  }
86
94
  export function activityFactSlice(database) {
87
- const bounds = database.prepare("SELECT MIN(sequence) AS lowest, MAX(sequence) AS highest FROM timeline")
88
- .get();
89
- const rows = database.prepare("SELECT sequence, kind FROM timeline ORDER BY sequence")
95
+ const bounds = database.prepare("SELECT MIN(sequence) AS lowest, MAX(sequence) AS highest FROM timeline").get();
96
+ const rows = database
97
+ .prepare("SELECT sequence, kind FROM timeline ORDER BY sequence")
90
98
  .all();
91
99
  return {
92
100
  rows: rows.map((row) => decodeTimelineRow(database, row)),
@@ -7,6 +7,7 @@ export type AkumaPaths = Readonly<{
7
7
  heart: string;
8
8
  leash: string;
9
9
  log: string;
10
+ requests: string;
10
11
  }>;
11
12
  export type AllocatedAkuma = Readonly<{
12
13
  id: AkuId;
@@ -39,6 +39,7 @@ export function akumaPaths(input) {
39
39
  heart: join(directory, "heart.db"),
40
40
  leash: join(directory, "leash.db"),
41
41
  log: join(directory, "stdio.log"),
42
+ requests: join(directory, "requests"),
42
43
  };
43
44
  }
44
45
  export function akuIdFromDirectoryName(name) {
@@ -1,6 +1,6 @@
1
1
  import { type AkuId } from "./identity.js";
2
2
  import type { WorldRoot } from "../world.js";
3
- export { Akuma, AkumaHandle, AkumaNotBornError } from "./akuma.js";
3
+ export { Akuma, AkumaHandle, AkumaNotBornError, defaultWaitComplete } from "./akuma.js";
4
4
  export type { AkumaCallInput } from "./akuma.js";
5
5
  export { ALLOWED_ACTIONS } from "./allowed.js";
6
6
  export type { AllowedAction, AllowedActions } from "./allowed.js";
@@ -9,9 +9,9 @@ export declare function probeBornAkuma(worldPath: WorldRoot, id: AkuId): Promise
9
9
  export { AkumaArchetypeError, listArchetypeDefinitions, listArchetypes } from "./archetype.js";
10
10
  export type { ArchetypeCatalogRow } from "./archetype.js";
11
11
  export { AkumaBodyRequestError } from "./requests.js";
12
- export type { AkumaList, AkumaListInput, AkumaListRow, AkumaStatus, ActivityHistory, ActivityRow, ActivitySnapshot, ActivitySnapshotEntry, ForkReceipt, InterruptReceipt, TellResult, UnbornAkumaListRow, } from "./akuma.js";
12
+ export type { AkumaList, AkumaListInput, AkumaListRow, AkumaStatus, ActivityHistory, ActivityRow, ActivitySnapshot, ActivitySnapshotEntry, ForkReceipt, InterruptReceipt, TellResult, TellWake, UnbornAkumaListRow, } from "./akuma.js";
13
13
  export type { ActiveToolRow, ClosedTurn, ClosedTurnRow, CompletedToolRow, HistoryCursor, HistoryPage, IdleSnapshotRow, OpenSnapshotRow, OpenTurn, OpenTurnRow, OutcomeRow, ReportedFileChange, RetainedWindow, Snapshot, SnapshotRow, TellRow, TurnLedger, TurnOutcome, TurnStartRow, UnsettledToolRow, } from "./akuma.js";
14
14
  export type { AgentEvent, ToolCall, ToolEvent, ToolResult } from "./provider.js";
15
15
  export type { AkuId } from "./identity.js";
16
- export type { KillEvidence, ResumeCoordinate, TurnFact, } from "./heart/index.js";
16
+ export type { KillEvidence, ResumeCoordinate, TurnFact } from "./heart/index.js";
17
17
  export type { ProviderOptions, ReadonlyRestraint } from "./provider-recipe.js";
@@ -1,6 +1,6 @@
1
1
  import { readSoul } from "./heart/index.js";
2
2
  import { pathsForAkuId } from "./identity.js";
3
- export { Akuma, AkumaHandle, AkumaNotBornError } from "./akuma.js";
3
+ export { Akuma, AkumaHandle, AkumaNotBornError, defaultWaitComplete } from "./akuma.js";
4
4
  export { ALLOWED_ACTIONS } from "./allowed.js";
5
5
  export async function probeBornAkuma(worldPath, id) {
6
6
  const soul = await readSoul(pathsForAkuId(worldPath, id));