@astrosheep/keiyaku 4.6.7 → 4.6.9

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 (336) hide show
  1. package/README.md +46 -16
  2. package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
  3. package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
  4. package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
  5. package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
  6. package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
  7. package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
  8. package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
  9. package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
  10. package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
  11. package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
  12. package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
  13. package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
  14. package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
  15. package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
  16. package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
  17. package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
  18. package/build/plugins/opencode/index.js +1 -1
  19. package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
  20. package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
  21. package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
  22. package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
  23. package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
  24. package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
  25. package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
  26. package/build/plugins/pi/keiyaku.ts +0 -5
  27. package/build/skills/keiyaku/SKILL.md +5 -6
  28. package/build/skills/keiyaku-akuma/SKILL.md +1 -1
  29. package/build/skills/keiyaku-akuma/references/automation.md +8 -8
  30. package/build/skills/keiyaku-babysit/SKILL.md +1 -1
  31. package/build/skills/keiyaku-bind/SKILL.md +9 -9
  32. package/build/skills/keiyaku-debt/SKILL.md +91 -0
  33. package/build/skills/keiyaku-workflow/SKILL.md +2 -2
  34. package/build/src/akuma/akuma-call.d.ts +2 -0
  35. package/build/src/akuma/akuma-call.js +8 -2
  36. package/build/src/akuma/akuma-instance.d.ts +14 -1
  37. package/build/src/akuma/akuma-instance.js +37 -7
  38. package/build/src/akuma/akuma-observe.d.ts +33 -8
  39. package/build/src/akuma/akuma-observe.js +89 -63
  40. package/build/src/akuma/akuma-owner.d.ts +14 -2
  41. package/build/src/akuma/akuma-owner.js +49 -35
  42. package/build/src/akuma/akuma-selection-execution.js +9 -1
  43. package/build/src/akuma/akuma-stream.d.ts +22 -0
  44. package/build/src/akuma/akuma-stream.js +116 -0
  45. package/build/src/akuma/akuma-wait.d.ts +1 -40
  46. package/build/src/akuma/akuma-wait.js +23 -84
  47. package/build/src/akuma/akuma.d.ts +52 -16
  48. package/build/src/akuma/akuma.js +10 -10
  49. package/build/src/akuma/allowed.d.ts +7 -12
  50. package/build/src/akuma/allowed.js +13 -4
  51. package/build/src/akuma/archetype.d.ts +7 -15
  52. package/build/src/akuma/archetype.js +36 -35
  53. package/build/src/akuma/body-supervisor.d.ts +5 -5
  54. package/build/src/akuma/body-supervisor.js +22 -20
  55. package/build/src/akuma/body.d.ts +5 -3
  56. package/build/src/akuma/body.js +57 -8
  57. package/build/src/akuma/call-request.d.ts +30 -32
  58. package/build/src/akuma/call-request.js +10 -3
  59. package/build/src/akuma/caller.d.ts +39 -0
  60. package/build/src/akuma/caller.js +36 -0
  61. package/build/src/akuma/dispatch-association.d.ts +0 -1
  62. package/build/src/akuma/dispatch-association.js +0 -3
  63. package/build/src/akuma/heart/activity-schema.d.ts +12 -0
  64. package/build/src/akuma/heart/activity-schema.js +6 -0
  65. package/build/src/akuma/heart/facts.d.ts +16 -12
  66. package/build/src/akuma/heart/facts.js +8 -0
  67. package/build/src/akuma/heart/index.d.ts +61 -9
  68. package/build/src/akuma/heart/index.js +89 -24
  69. package/build/src/akuma/heart/rows.d.ts +3 -3
  70. package/build/src/akuma/heart/rows.js +5 -3
  71. package/build/src/akuma/heart/soul.d.ts +10 -1
  72. package/build/src/akuma/heart/soul.js +34 -24
  73. package/build/src/akuma/heart/storage.d.ts +20 -0
  74. package/build/src/akuma/heart/storage.js +62 -3
  75. package/build/src/akuma/heart/timeline.d.ts +7 -0
  76. package/build/src/akuma/heart/timeline.js +10 -0
  77. package/build/src/akuma/identity.d.ts +0 -1
  78. package/build/src/akuma/identity.js +2 -5
  79. package/build/src/akuma/index.d.ts +6 -2
  80. package/build/src/akuma/index.js +1 -0
  81. package/build/src/akuma/nuke.js +6 -28
  82. package/build/src/akuma/projection.d.ts +25 -11
  83. package/build/src/akuma/projection.js +24 -7
  84. package/build/src/akuma/provider-recipe.d.ts +18 -6
  85. package/build/src/akuma/provider-recipe.js +24 -1
  86. package/build/src/akuma/provider.d.ts +31 -10
  87. package/build/src/akuma/provider.js +105 -14
  88. package/build/src/akuma/providers/acp/events.js +29 -19
  89. package/build/src/akuma/providers/acp/index.js +2 -3
  90. package/build/src/akuma/providers/claude/events.js +110 -69
  91. package/build/src/akuma/providers/claude/index.d.ts +2 -2
  92. package/build/src/akuma/providers/claude/index.js +4 -8
  93. package/build/src/akuma/providers/codex-app-server/events.js +17 -2
  94. package/build/src/akuma/providers/codex-app-server/index.js +17 -11
  95. package/build/src/akuma/providers/decode.d.ts +33 -0
  96. package/build/src/akuma/providers/decode.js +65 -0
  97. package/build/src/akuma/providers/execution-environment.d.ts +2 -1
  98. package/build/src/akuma/providers/execution-environment.js +3 -0
  99. package/build/src/akuma/providers/grok-build/index.js +16 -48
  100. package/build/src/akuma/providers/index.js +2 -0
  101. package/build/src/akuma/providers/lifecycle.d.ts +9 -0
  102. package/build/src/akuma/providers/lifecycle.js +10 -0
  103. package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
  104. package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
  105. package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
  106. package/build/src/akuma/providers/opencode-sdk/events.js +146 -296
  107. package/build/src/akuma/providers/opencode-sdk/index.js +270 -431
  108. package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
  109. package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
  110. package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
  111. package/build/src/akuma/providers/opencode-sdk/session.js +75 -84
  112. package/build/src/akuma/providers/paseo/events.d.ts +33 -0
  113. package/build/src/akuma/providers/paseo/events.js +204 -0
  114. package/build/src/akuma/providers/paseo/index.d.ts +9 -0
  115. package/build/src/akuma/providers/paseo/index.js +357 -0
  116. package/build/src/akuma/providers/pi/events.d.ts +2 -0
  117. package/build/src/akuma/providers/pi/events.js +36 -38
  118. package/build/src/akuma/providers/pi/index.js +21 -35
  119. package/build/src/akuma/publication.d.ts +2 -0
  120. package/build/src/akuma/publication.js +5 -0
  121. package/build/src/akuma/request-lifecycle.d.ts +4 -2
  122. package/build/src/akuma/request-lifecycle.js +27 -12
  123. package/build/src/akuma/request-rendezvous.js +38 -55
  124. package/build/src/akuma/request-serve.d.ts +1 -1
  125. package/build/src/akuma/request-serve.js +77 -113
  126. package/build/src/akuma/requests.d.ts +3 -1
  127. package/build/src/akuma/requests.js +32 -0
  128. package/build/src/akuma/selection-observation.d.ts +129 -53
  129. package/build/src/akuma/selection-observation.js +3 -9
  130. package/build/src/akuma/turn-drive.d.ts +3 -0
  131. package/build/src/akuma/turn-drive.js +28 -10
  132. package/build/src/akuma-body.js +12 -22
  133. package/build/src/cli/akuma-caller.d.ts +3 -0
  134. package/build/src/cli/akuma-caller.js +31 -0
  135. package/build/src/cli/commands/akuma-grammar.js +10 -16
  136. package/build/src/cli/commands/akuma.js +25 -55
  137. package/build/src/cli/commands/contract-grammar.d.ts +9 -7
  138. package/build/src/cli/commands/contract-grammar.js +40 -47
  139. package/build/src/cli/commands/contract-help.d.ts +17 -7
  140. package/build/src/cli/commands/contract-help.js +50 -11
  141. package/build/src/cli/commands/contract.js +34 -63
  142. package/build/src/cli/commands/debt-grammar.d.ts +19 -0
  143. package/build/src/cli/commands/debt-grammar.js +323 -0
  144. package/build/src/cli/commands/debt-query.d.ts +5 -0
  145. package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
  146. package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
  147. package/build/src/cli/commands/{task.js → debt.js} +87 -164
  148. package/build/src/cli/coordinates.d.ts +1 -1
  149. package/build/src/cli/coordinates.js +1 -1
  150. package/build/src/cli/parse.d.ts +5 -5
  151. package/build/src/cli/parse.js +17 -16
  152. package/build/src/cli/render/akuma-activity.d.ts +11 -83
  153. package/build/src/cli/render/akuma-activity.js +20 -382
  154. package/build/src/cli/render/catalog.d.ts +4 -7
  155. package/build/src/cli/render/catalog.js +5 -5
  156. package/build/src/cli/render/contract-history.js +3 -6
  157. package/build/src/cli/render/contract.js +17 -52
  158. package/build/src/cli/render/debt.d.ts +28 -0
  159. package/build/src/cli/render/{task.js → debt.js} +55 -133
  160. package/build/src/cli/render/kanshi.js +28 -28
  161. package/build/src/cli/render/marks.d.ts +5 -5
  162. package/build/src/cli/render/marks.js +4 -10
  163. package/build/src/cli/render/nuke.js +1 -1
  164. package/build/src/cli/render/receipt.js +3 -10
  165. package/build/src/cli/runtime.d.ts +1 -1
  166. package/build/src/cli/runtime.js +14 -20
  167. package/build/src/cli/scan.d.ts +1 -1
  168. package/build/src/cli/selectors.d.ts +3 -6
  169. package/build/src/cli/selectors.js +22 -53
  170. package/build/src/cli/usage.d.ts +1 -1
  171. package/build/src/cli/usage.js +4 -4
  172. package/build/src/contract-worktree.js +3 -3
  173. package/build/src/debt/board.d.ts +160 -0
  174. package/build/src/{task → debt}/board.js +89 -89
  175. package/build/src/debt/catalog.d.ts +11 -0
  176. package/build/src/debt/catalog.js +59 -0
  177. package/build/src/{task → debt}/context.d.ts +1 -1
  178. package/build/src/{task → debt}/context.js +1 -1
  179. package/build/src/{task → debt}/created-observation.d.ts +6 -10
  180. package/build/src/{task → debt}/created-observation.js +7 -7
  181. package/build/src/debt/document.d.ts +37 -0
  182. package/build/src/{task → debt}/document.js +37 -37
  183. package/build/src/debt/identity.d.ts +21 -0
  184. package/build/src/{task → debt}/identity.js +35 -35
  185. package/build/src/debt/index.d.ts +111 -0
  186. package/build/src/debt/index.js +203 -0
  187. package/build/src/{task → debt}/input.d.ts +8 -8
  188. package/build/src/{task → debt}/input.js +21 -21
  189. package/build/src/debt/lifecycle-operations.d.ts +6 -0
  190. package/build/src/{task → debt}/lifecycle-operations.js +27 -31
  191. package/build/src/debt/mutation-result.d.ts +981 -0
  192. package/build/src/debt/mutation-result.js +109 -0
  193. package/build/src/debt/mutation.d.ts +424 -0
  194. package/build/src/debt/mutation.js +223 -0
  195. package/build/src/debt/operation-types.d.ts +71 -0
  196. package/build/src/debt/operations.d.ts +28 -0
  197. package/build/src/{task → debt}/operations.js +59 -60
  198. package/build/src/debt/query.d.ts +76 -0
  199. package/build/src/{task → debt}/query.js +55 -55
  200. package/build/src/{task → debt}/store.d.ts +13 -13
  201. package/build/src/{task → debt}/store.js +58 -49
  202. package/build/src/debt/view.d.ts +4 -0
  203. package/build/src/debt/view.js +7 -0
  204. package/build/src/dispatch/index.d.ts +3 -3
  205. package/build/src/dispatch/index.js +1 -2
  206. package/build/src/git/observe.d.ts +6 -2
  207. package/build/src/git/observe.js +6 -2
  208. package/build/src/identity/coordinates.d.ts +1 -1
  209. package/build/src/index.d.ts +17 -17
  210. package/build/src/index.js +11 -11
  211. package/build/src/kanshi/index.d.ts +2 -2
  212. package/build/src/kanshi/read.js +54 -39
  213. package/build/src/kanshi/report.d.ts +7 -7
  214. package/build/src/kanshi/select.js +4 -4
  215. package/build/src/library/address.js +2 -4
  216. package/build/src/library/akuma-creation.d.ts +5 -1
  217. package/build/src/library/akuma-creation.js +27 -47
  218. package/build/src/library/akumas.d.ts +7 -7
  219. package/build/src/library/akumas.js +13 -9
  220. package/build/src/library/bind.d.ts +17 -17
  221. package/build/src/library/bind.js +16 -12
  222. package/build/src/library/contract-address.d.ts +9 -0
  223. package/build/src/library/contract-address.js +71 -0
  224. package/build/src/library/contract-composition.d.ts +4 -7
  225. package/build/src/library/contract-composition.js +6 -18
  226. package/build/src/library/contract-creation.d.ts +3 -5
  227. package/build/src/library/contract-creation.js +24 -22
  228. package/build/src/library/contract-execution.js +21 -26
  229. package/build/src/library/contract-outcomes.d.ts +2 -14
  230. package/build/src/library/contract-outcomes.js +2 -13
  231. package/build/src/library/contract-types.d.ts +38 -4
  232. package/build/src/library/delivery.d.ts +0 -2
  233. package/build/src/library/delivery.js +2 -5
  234. package/build/src/library/input.d.ts +2 -2
  235. package/build/src/library/input.js +5 -5
  236. package/build/src/library/invocation.js +2 -2
  237. package/build/src/library/keiyaku.d.ts +0 -5
  238. package/build/src/library/keiyaku.js +6 -12
  239. package/build/src/library/nuke.js +3 -3
  240. package/build/src/library/outcome.d.ts +626 -625
  241. package/build/src/library/outcome.js +13 -3
  242. package/build/src/library/reconcile.js +8 -16
  243. package/build/src/library/refusal.d.ts +2 -2
  244. package/build/src/library/repo.d.ts +3 -2
  245. package/build/src/library/repo.js +10 -5
  246. package/build/src/library/selection.d.ts +5 -8
  247. package/build/src/library/selection.js +22 -73
  248. package/build/src/plugin/akuma-signals.d.ts +2 -0
  249. package/build/src/plugin/akuma-signals.js +4 -0
  250. package/build/src/plugin/public.d.ts +32 -2
  251. package/build/src/plugin/runtime.js +5 -3
  252. package/build/src/protocol/amend.js +3 -2
  253. package/build/src/protocol/attempt.js +3 -8
  254. package/build/src/protocol/bind.d.ts +2 -2
  255. package/build/src/protocol/bind.js +1 -1
  256. package/build/src/protocol/deliver.js +3 -3
  257. package/build/src/protocol/operations.d.ts +1 -3
  258. package/build/src/protocol/operations.js +0 -8
  259. package/build/src/protocol/outcome.d.ts +1 -2
  260. package/build/src/protocol/outcome.js +1 -13
  261. package/build/src/protocol/placement.js +3 -10
  262. package/build/src/protocol/read/status.js +31 -70
  263. package/build/src/protocol/reintegrate.js +3 -10
  264. package/build/src/protocol/review.js +3 -3
  265. package/build/src/protocol/run.d.ts +5 -1
  266. package/build/src/protocol/run.js +3 -3
  267. package/build/src/runtime/proc/windows-launch.exe +0 -0
  268. package/build/src/settlement/fence.d.ts +3 -3
  269. package/build/src/settlement/fence.js +4 -4
  270. package/build/src/settlement/holder.d.ts +16 -16
  271. package/build/src/settlement/holder.js +69 -63
  272. package/build/src/settlement/settle.d.ts +5 -5
  273. package/build/src/settlement/settle.js +53 -53
  274. package/package.json +19 -9
  275. package/plugins/paseo/plugin/index.server.ts +17 -0
  276. package/plugins/paseo/plugin/paseo-plugin.json +4 -0
  277. package/plugins/paseo/plugin/server/attach.ts +52 -0
  278. package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
  279. package/plugins/paseo/plugin/server/message.ts +60 -0
  280. package/plugins/paseo/plugin/server/mirror.ts +193 -0
  281. package/plugins/paseo/plugin/server/model.ts +14 -0
  282. package/plugins/paseo/plugin/server/provider.ts +276 -0
  283. package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
  284. package/plugins/paseo/plugin/server/sdk.ts +289 -0
  285. package/plugins/paseo/plugin/server/stop.ts +26 -0
  286. package/plugins/paseo/plugin/server/transport.ts +35 -0
  287. package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
  288. package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
  289. package/plugins/paseo/plugin/tsconfig.json +6 -0
  290. package/plugins/pi/keiyaku.ts +57 -0
  291. package/skills/keiyaku/SKILL.md +43 -0
  292. package/skills/keiyaku-akuma/SKILL.md +130 -0
  293. package/skills/keiyaku-akuma/references/automation.md +269 -0
  294. package/skills/keiyaku-babysit/SKILL.md +65 -0
  295. package/skills/keiyaku-bind/SKILL.md +216 -0
  296. package/skills/keiyaku-bind/agents/openai.yaml +4 -0
  297. package/skills/keiyaku-debt/SKILL.md +91 -0
  298. package/skills/keiyaku-workflow/SKILL.md +129 -0
  299. package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
  300. package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
  301. package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
  302. package/build/skills/keiyaku-task/SKILL.md +0 -104
  303. package/build/src/cli/commands/amend.d.ts +0 -12
  304. package/build/src/cli/commands/amend.js +0 -10
  305. package/build/src/cli/commands/bind.d.ts +0 -11
  306. package/build/src/cli/commands/bind.js +0 -23
  307. package/build/src/cli/commands/task-grammar.d.ts +0 -19
  308. package/build/src/cli/commands/task-grammar.js +0 -384
  309. package/build/src/cli/commands/task-query.d.ts +0 -5
  310. package/build/src/cli/render/task.d.ts +0 -41
  311. package/build/src/dispatch/association.d.ts +0 -1
  312. package/build/src/dispatch/association.js +0 -1
  313. package/build/src/task/board.d.ts +0 -168
  314. package/build/src/task/catalog.d.ts +0 -11
  315. package/build/src/task/catalog.js +0 -59
  316. package/build/src/task/compose-language.d.ts +0 -57
  317. package/build/src/task/compose-language.js +0 -364
  318. package/build/src/task/compose-parser.d.ts +0 -32
  319. package/build/src/task/compose-parser.js +0 -180
  320. package/build/src/task/compose.d.ts +0 -16
  321. package/build/src/task/compose.js +0 -189
  322. package/build/src/task/document.d.ts +0 -39
  323. package/build/src/task/identity.d.ts +0 -21
  324. package/build/src/task/index.d.ts +0 -138
  325. package/build/src/task/index.js +0 -269
  326. package/build/src/task/lifecycle-operations.d.ts +0 -6
  327. package/build/src/task/mutation-result.d.ts +0 -1726
  328. package/build/src/task/mutation-result.js +0 -198
  329. package/build/src/task/mutation.d.ts +0 -590
  330. package/build/src/task/mutation.js +0 -262
  331. package/build/src/task/operation-types.d.ts +0 -71
  332. package/build/src/task/operations.d.ts +0 -28
  333. package/build/src/task/query.d.ts +0 -76
  334. package/build/src/task/view.d.ts +0 -4
  335. package/build/src/task/view.js +0 -7
  336. /package/build/src/{task → debt}/operation-types.js +0 -0
@@ -1,29 +1,27 @@
1
+ import { akumaBirthSchema } from "./caller.js";
1
2
  import { readdir, stat } from "node:fs/promises";
2
3
  import { z } from "zod";
3
4
  import { boundedListLimit, projectBoundedList } from "../bounded-list.js";
4
5
  import { rosterListRow } from "./akuma-observe.js";
5
6
  import { AkumaOwner } from "./akuma-owner.js";
6
7
  import { allowedActionsSchema } from "./allowed.js";
7
- import { listArchetypes as readArchetypes } from "./archetype.js";
8
- import { akuIdFromDirectoryName, akumaIdSchema, akumaPaths, akumaRunRoot, archetypeName, } from "./identity.js";
8
+ import { akuIdFromDirectoryName, akumaIdSchema, akumaPaths, akumaRunRoot, } from "./identity.js";
9
+ import { validateAkumaName } from "../identity/normalize.js";
9
10
  import { activitySnapshotSchema } from "./projection.js";
10
11
  import { PAGE_POOL_SIZE, boundedMap } from "./read-pool.js";
11
12
  export const akumaStatusSchema = z
12
13
  .object({
13
14
  id: akumaIdSchema,
15
+ birth: akumaBirthSchema,
14
16
  life: z.enum(["running", "asleep", "stranded", "hung", "untidy", "killed"]),
15
17
  cwd: z.string().optional(),
18
+ provider: z.string().optional(),
19
+ model: z.string().optional(),
16
20
  allowed: allowedActionsSchema,
17
21
  timeline: activitySnapshotSchema,
18
22
  strandedReason: z.literal("resume-unsupported").optional(),
19
23
  })
20
24
  .strict();
21
- export function parseAkumaStatus(value) {
22
- return akumaStatusSchema.parse(value);
23
- }
24
- export async function listAkumaArchetypes(path, input = {}) {
25
- return readArchetypes({ project: path, ...(input.home === undefined ? {} : { home: input.home }) });
26
- }
27
25
  function activityAt(row) {
28
26
  if (!("lifeAt" in row))
29
27
  return null;
@@ -59,7 +57,8 @@ async function mtimeBound(paths) {
59
57
  };
60
58
  return Math.max(await read(paths.heart), await read(`${paths.heart}-wal`));
61
59
  }
62
- async function knownAkuma(path, selected) {
60
+ /** Enumerate the recognized Akuma directories under this World's run root. */
61
+ export async function knownAkuma(path, selected) {
63
62
  const runRoot = akumaRunRoot(path);
64
63
  let names;
65
64
  try {
@@ -80,6 +79,7 @@ async function knownAkuma(path, selected) {
80
79
  physical = akuIdFromDirectoryName(name);
81
80
  }
82
81
  catch {
82
+ // The run root can contain bytes not produced by Keiyaku. Preserve them.
83
83
  continue;
84
84
  }
85
85
  if (selected !== undefined && physical.archetype !== selected)
@@ -109,7 +109,7 @@ function rosterArchetype(input, allowLimit) {
109
109
  const unknown = Object.keys(input).find((key) => !allowed.includes(key));
110
110
  if (unknown !== undefined)
111
111
  throw new TypeError(`Akuma list input has unknown field: ${unknown}`);
112
- return input.archetype === undefined ? undefined : archetypeName(input.archetype);
112
+ return input.archetype === undefined ? undefined : validateAkumaName(input.archetype);
113
113
  }
114
114
  /**
115
115
  * The bounded recent-activity roster: native membership, semantic order and
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- export declare const ALLOWED_ACTIONS: readonly ["akuma.call", "akuma.kill", "akuma.tell", "contract.audit", "contract.deliver", "contract.review", "task.add", "task.addDocument", "task.compose", "task.done", "task.drop", "task.hold", "task.resume", "task.start", "task.stop", "task.update"];
2
+ export declare const ALLOWED_ACTIONS: readonly ["akuma.call", "akuma.kill", "akuma.tell", "contract.audit", "contract.deliver", "contract.review", "debt.add", "debt.addDocument", "debt.done", "debt.drop", "debt.update"];
3
3
  export type AllowedAction = (typeof ALLOWED_ACTIONS)[number];
4
4
  export type AllowedActions = readonly AllowedAction[];
5
5
  export declare const DEFAULT_ALLOWED_ACTIONS: AllowedActions;
@@ -7,23 +7,18 @@ export declare function isAllowedAction(value: unknown): value is AllowedAction;
7
7
  export declare function decodeAllowedActions(value: unknown, label?: string): AllowedActions;
8
8
  /** Public codecs retain the Soul's canonical, duplicate-free action membership. */
9
9
  export declare const allowedActionsSchema: z.ZodPipe<z.ZodArray<z.ZodEnum<{
10
- "task.add": "task.add";
11
- "task.addDocument": "task.addDocument";
12
- "task.compose": "task.compose";
13
- "task.done": "task.done";
14
- "task.drop": "task.drop";
15
- "task.hold": "task.hold";
16
- "task.resume": "task.resume";
17
- "task.start": "task.start";
18
- "task.stop": "task.stop";
19
- "task.update": "task.update";
10
+ "debt.add": "debt.add";
11
+ "debt.addDocument": "debt.addDocument";
12
+ "debt.done": "debt.done";
13
+ "debt.drop": "debt.drop";
14
+ "debt.update": "debt.update";
20
15
  "akuma.call": "akuma.call";
21
16
  "akuma.kill": "akuma.kill";
22
17
  "akuma.tell": "akuma.tell";
23
18
  "contract.audit": "contract.audit";
24
19
  "contract.deliver": "contract.deliver";
25
20
  "contract.review": "contract.review";
26
- }>>, z.ZodTransform<AllowedActions, ("task.add" | "task.addDocument" | "task.compose" | "task.done" | "task.drop" | "task.hold" | "task.resume" | "task.start" | "task.stop" | "task.update" | "akuma.call" | "akuma.kill" | "akuma.tell" | "contract.audit" | "contract.deliver" | "contract.review")[]>>;
21
+ }>>, z.ZodTransform<AllowedActions, ("debt.add" | "debt.addDocument" | "debt.done" | "debt.drop" | "debt.update" | "akuma.call" | "akuma.kill" | "akuma.tell" | "contract.audit" | "contract.deliver" | "contract.review")[]>>;
27
22
  export declare function historicalAllowedActions(value: unknown): AllowedActions;
28
23
  export declare function unionAllowedActions(base: AllowedActions, additions: AllowedActions): AllowedActions;
29
24
  export declare function clipAllowedActions(requested: AllowedActions, parent: AllowedActions): AllowedActions;
@@ -1,4 +1,4 @@
1
- import { TASK_MUTATION_ACTIONS } from "../task/mutation.js";
1
+ import { DEBT_MUTATION_ACTIONS } from "../debt/mutation.js";
2
2
  import { z } from "zod";
3
3
  const AKUMA_MUTATION_ACTIONS = Object.freeze(["akuma.call", "akuma.kill", "akuma.tell"]);
4
4
  export const ALLOWED_ACTIONS = Object.freeze([
@@ -6,13 +6,13 @@ export const ALLOWED_ACTIONS = Object.freeze([
6
6
  "contract.audit",
7
7
  "contract.deliver",
8
8
  "contract.review",
9
- ...TASK_MUTATION_ACTIONS,
9
+ ...DEBT_MUTATION_ACTIONS,
10
10
  ]);
11
11
  export const DEFAULT_ALLOWED_ACTIONS = Object.freeze([
12
12
  ...AKUMA_MUTATION_ACTIONS,
13
13
  "contract.audit",
14
14
  "contract.deliver",
15
- ...TASK_MUTATION_ACTIONS,
15
+ ...DEBT_MUTATION_ACTIONS,
16
16
  ]);
17
17
  const ALLOWED_ACTION_SET = new Set(ALLOWED_ACTIONS);
18
18
  export function isAllowedAction(value) {
@@ -42,7 +42,16 @@ export const allowedActionsSchema = z.array(z.enum(ALLOWED_ACTIONS)).transform((
42
42
  }
43
43
  });
44
44
  export function historicalAllowedActions(value) {
45
- return value === undefined ? ALLOWED_ACTIONS : decodeAllowedActions(value);
45
+ if (value === undefined)
46
+ return ALLOWED_ACTIONS;
47
+ if (!Array.isArray(value))
48
+ return decodeAllowedActions(value);
49
+ // Persisted permissions retain the same surviving capabilities after rename;
50
+ // removed planning/progress operations confer no replacement permission.
51
+ const retired = new Set(["task.compose", "task.start", "task.stop", "task.hold", "task.resume"]);
52
+ return decodeAllowedActions(value
53
+ .filter((action) => !retired.has(action))
54
+ .map((action) => typeof action === "string" && action.startsWith("task.") ? `debt.${action.slice("task.".length)}` : action));
46
55
  }
47
56
  export function unionAllowedActions(base, additions) {
48
57
  const merged = new Set(base);
@@ -1,6 +1,5 @@
1
1
  import { type BoundedList } from "../bounded-list.js";
2
2
  import type { Settings } from "../settings.js";
3
- import type { ProviderAdapter } from "./provider.js";
4
3
  import { type ProviderExecution, type ProviderOptions } from "./provider-recipe.js";
5
4
  import { type AllowedActions } from "./allowed.js";
6
5
  type DecodedArchetype = Readonly<{
@@ -17,11 +16,12 @@ export type ArchetypeCatalogRow = Readonly<{
17
16
  model?: string;
18
17
  description?: string;
19
18
  }>;
20
- type ArchetypeDefinition = DecodedArchetype & Readonly<{
21
- adapter: ProviderAdapter;
22
- }>;
23
- type AdmittedArchetype = Omit<ArchetypeDefinition, "provider"> & Readonly<{
24
- provider: ProviderExecution;
19
+ export type ArchetypeCatalog = BoundedList<ArchetypeCatalogRow>;
20
+ /** One closed catalogue request: omitted project means no project scope, never ambient discovery. */
21
+ export type ArchetypeCatalogInput = Readonly<{
22
+ project?: string;
23
+ home?: string;
24
+ limit?: number;
25
25
  }>;
26
26
  /** One loaded archetype whose provider owner has decoded its execution but not yet admitted its options. */
27
27
  type PreparedArchetype = Omit<DecodedArchetype, "provider"> & Readonly<{
@@ -39,9 +39,7 @@ type ArchetypeCoordinates = Readonly<{
39
39
  home?: string;
40
40
  }>;
41
41
  export declare function listArchetypes(input?: ArchetypeCoordinates): Promise<readonly string[]>;
42
- export declare function listArchetypeDefinitions(input?: ArchetypeCoordinates & Readonly<{
43
- limit?: number;
44
- }>): Promise<BoundedList<ArchetypeCatalogRow>>;
42
+ export declare function listArchetypeDefinitions(input?: ArchetypeCatalogInput): Promise<ArchetypeCatalog>;
45
43
  /** Resolve one archetype and decode its provider execution, leaving option admission to the caller. */
46
44
  export declare function loadPreparedArchetype(input: Readonly<{
47
45
  name: string;
@@ -49,10 +47,4 @@ export declare function loadPreparedArchetype(input: Readonly<{
49
47
  home?: string;
50
48
  settings: Settings;
51
49
  }>): Promise<PreparedArchetype>;
52
- export declare function loadArchetype(input: Readonly<{
53
- name: string;
54
- project?: string;
55
- home?: string;
56
- settings: Settings;
57
- }>): Promise<AdmittedArchetype>;
58
50
  export {};
@@ -1,11 +1,10 @@
1
1
  import { readFile, readdir } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
- import { join } from "node:path";
3
+ import { isAbsolute, join } from "node:path";
4
4
  import { parseDocument } from "yaml";
5
5
  import { boundedListLimit } from "../bounded-list.js";
6
- import { archetypeName } from "./identity.js";
6
+ import { validateAkumaName } from "../identity/normalize.js";
7
7
  import { decodeProviderOptions, decodeProviderRecipe, } from "./provider-recipe.js";
8
- import { resolveProviderExecution } from "./providers/index.js";
9
8
  import { DEFAULT_ALLOWED_ACTIONS, decodeAllowedActions } from "./allowed.js";
10
9
  export class AkumaArchetypeError extends Error {
11
10
  archetype;
@@ -37,7 +36,7 @@ async function pathsInDirectory(directory) {
37
36
  return [];
38
37
  const name = entry.name.slice(0, -3);
39
38
  try {
40
- return [{ name: archetypeName(name), path: join(directory, entry.name) }];
39
+ return [{ name: validateAkumaName(name), path: join(directory, entry.name) }];
41
40
  }
42
41
  catch {
43
42
  return [];
@@ -127,7 +126,7 @@ function parseArchetypeFrontmatter(markdown) {
127
126
  function decodeArchetypeFields(values) {
128
127
  const provider = archetypeField(values, "provider");
129
128
  const baseValue = archetypeField(values, "base");
130
- const base = baseValue === undefined ? undefined : archetypeName(baseValue);
129
+ const base = baseValue === undefined ? undefined : validateAkumaName(baseValue);
131
130
  const model = archetypeField(values, "model");
132
131
  const effort = archetypeField(values, "effort");
133
132
  const network = archetypeEnum(values, "network", ["disabled", "enabled"]);
@@ -237,14 +236,41 @@ async function resolveArchetype(name, input, source, chain = []) {
237
236
  const missingChain = chain.length === 0 ? chain : [...chain, name];
238
237
  throw archetypeError(name, searched, "was not found", missingChain, chain.length === 0 ? "use `keiyaku ls aku/` to list available Akuma" : undefined);
239
238
  }
239
+ function catalogueCoordinate(value, field) {
240
+ if (value === undefined)
241
+ return undefined;
242
+ if (typeof value !== "string" || value.trim().length === 0) {
243
+ throw new TypeError(`Akuma catalogue ${field} must be a nonblank string`);
244
+ }
245
+ if (!isAbsolute(value))
246
+ throw new TypeError(`Akuma catalogue ${field} must be absolute: ${value}`);
247
+ return value;
248
+ }
249
+ /** Malformed caller input fails here, before any filesystem observation. */
250
+ function catalogueInput(value) {
251
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
252
+ throw new TypeError("Akuma catalogue input must be an object");
253
+ }
254
+ const input = value;
255
+ const unknown = Object.keys(input).find((key) => !["project", "home", "limit"].includes(key));
256
+ if (unknown !== undefined)
257
+ throw new TypeError(`Akuma catalogue input has unknown field: ${unknown}`);
258
+ const project = catalogueCoordinate(input.project, "project");
259
+ const home = catalogueCoordinate(input.home, "home");
260
+ return {
261
+ ...(project === undefined ? {} : { project }),
262
+ ...(home === undefined ? {} : { home }),
263
+ ...(input.limit === undefined ? {} : { limit: boundedListLimit(input.limit) }),
264
+ };
265
+ }
240
266
  export async function listArchetypeDefinitions(input = {}) {
241
267
  // Reads still run concurrently, but the reported failure is the first invalid
242
268
  // definition in catalog byte order, not whichever read happened to finish first.
243
- const limit = input.limit === undefined ? undefined : boundedListLimit(input.limit);
244
- const all = await archetypePaths(input);
269
+ const { limit, ...coordinates } = catalogueInput(input);
270
+ const all = await archetypePaths(coordinates);
245
271
  const settled = await Promise.allSettled(all.map(async ({ name, path }) => {
246
272
  try {
247
- return await resolveArchetype(name, input, undefined);
273
+ return await resolveArchetype(name, coordinates, undefined);
248
274
  }
249
275
  catch (error) {
250
276
  if (error instanceof AkumaArchetypeError)
@@ -307,6 +333,7 @@ const BUILTIN_EXECUTIONS = {
307
333
  executable: "kimi",
308
334
  config: { argvBefore: ["acp"], argvAfter: [], modelConfigId: "model", effortConfigId: "thinking" },
309
335
  },
336
+ paseo: { kind: "paseo" },
310
337
  pi: { kind: "pi" },
311
338
  "grok-build": {
312
339
  kind: "grok-build",
@@ -325,32 +352,9 @@ function providerExecution(settings, name) {
325
352
  return decodeProviderRecipe({ name, ...builtin });
326
353
  throw new TypeError(`unknown provider ${name}`);
327
354
  }
328
- async function admitArchetype(archetype) {
329
- let selected;
330
- try {
331
- selected = await resolveProviderExecution(archetype.provider);
332
- }
333
- catch (error) {
334
- if (error instanceof TypeError)
335
- throw new AkumaArchetypeError(archetype.name, [archetype.path], `uses ${error.message}`);
336
- throw error;
337
- }
338
- const execution = selected.execution;
339
- const adapter = selected.adapter;
340
- const admission = adapter.admitOptions(archetype.options);
341
- if (admission.kind === "refused") {
342
- throw new AkumaArchetypeError(archetype.name, [archetype.path], `is unsupported: ${admission.diagnostic}`);
343
- }
344
- return Object.freeze({
345
- ...archetype,
346
- provider: execution,
347
- adapter,
348
- options: admission.options,
349
- });
350
- }
351
355
  /** Resolve one archetype and decode its provider execution, leaving option admission to the caller. */
352
356
  export async function loadPreparedArchetype(input) {
353
- const name = archetypeName(input.name);
357
+ const name = validateAkumaName(input.name);
354
358
  const definition = await resolveArchetype(name, input, undefined);
355
359
  let provider;
356
360
  try {
@@ -363,6 +367,3 @@ export async function loadPreparedArchetype(input) {
363
367
  }
364
368
  return Object.freeze({ ...definition, provider });
365
369
  }
366
- export async function loadArchetype(input) {
367
- return await admitArchetype(await loadPreparedArchetype(input));
368
- }
@@ -1,10 +1,11 @@
1
- import { type HeartSnapshot, type HeldAkumaLeash } from "./heart/index.js";
1
+ import { type BodyControlSnapshot, type HeldAkumaLeash } from "./heart/index.js";
2
2
  import type { AkumaPaths } from "./identity.js";
3
3
  export declare const CONTROL_RESPONSE_MS = 1000;
4
4
  export declare class BodySupervisor {
5
5
  private readonly paths;
6
6
  private readonly bodySequence;
7
7
  private readonly leash;
8
+ private readonly reader;
8
9
  readonly signal: AbortSignal;
9
10
  private readonly controller;
10
11
  private readonly finished;
@@ -15,12 +16,11 @@ export declare class BodySupervisor {
15
16
  private constructor();
16
17
  static open(paths: AkumaPaths, bodySequence: number, leash: HeldAkumaLeash): Promise<BodySupervisor>;
17
18
  get reason(): "control" | "heart-gone" | undefined;
18
- current(): HeartSnapshot;
19
+ current(): BodyControlSnapshot;
19
20
  recordHung(diagnostic: string, at: string): Promise<void>;
20
- refresh(): Promise<HeartSnapshot>;
21
- next(after: HeartSnapshot): Promise<HeartSnapshot>;
21
+ refresh(): Promise<BodyControlSnapshot>;
22
+ next(after: BodyControlSnapshot): Promise<BodyControlSnapshot>;
22
23
  cancel(reason: "control" | "heart-gone"): void;
23
24
  close(): Promise<void>;
24
- private publish;
25
25
  private observe;
26
26
  }
@@ -1,11 +1,13 @@
1
1
  import { abortableDelay } from "./abort.js";
2
- import { heartExists, readHeart } from "./heart/index.js";
2
+ import { isDeepStrictEqual } from "node:util";
3
+ import { createBodyHeartReader } from "./heart/index.js";
3
4
  const BODY_CONTROL_OBSERVATION_MS = 100;
4
5
  export const CONTROL_RESPONSE_MS = 1_000;
5
6
  export class BodySupervisor {
6
7
  paths;
7
8
  bodySequence;
8
9
  leash;
10
+ reader;
9
11
  signal;
10
12
  controller = new AbortController();
11
13
  finished = new AbortController();
@@ -13,16 +15,18 @@ export class BodySupervisor {
13
15
  waiter;
14
16
  observation;
15
17
  stopping;
16
- constructor(paths, bodySequence, leash, observation) {
18
+ constructor(paths, bodySequence, leash, reader, observation) {
17
19
  this.paths = paths;
18
20
  this.bodySequence = bodySequence;
19
21
  this.leash = leash;
22
+ this.reader = reader;
20
23
  this.signal = this.controller.signal;
21
24
  this.observation = observation;
22
25
  this.observer = this.observe();
23
26
  }
24
27
  static async open(paths, bodySequence, leash) {
25
- return new BodySupervisor(paths, bodySequence, leash, await readHeart(paths));
28
+ const reader = createBodyHeartReader(paths);
29
+ return new BodySupervisor(paths, bodySequence, leash, reader, await reader.read());
26
30
  }
27
31
  get reason() {
28
32
  return this.stopping;
@@ -34,7 +38,12 @@ export class BodySupervisor {
34
38
  await this.leash.recordBodyHung(this.paths, { sequence: this.bodySequence, diagnostic, at });
35
39
  }
36
40
  async refresh() {
37
- this.publish(await readHeart(this.paths));
41
+ const snapshot = await this.reader.read();
42
+ if (!isDeepStrictEqual(snapshot, this.observation)) {
43
+ this.observation = snapshot;
44
+ this.waiter?.(snapshot);
45
+ this.waiter = undefined;
46
+ }
38
47
  return this.observation;
39
48
  }
40
49
  next(after) {
@@ -54,18 +63,18 @@ export class BodySupervisor {
54
63
  }
55
64
  async close() {
56
65
  this.finished.abort();
57
- await this.observer;
58
- this.waiter = undefined;
59
- }
60
- publish(snapshot) {
61
- this.observation = snapshot;
62
- this.waiter?.(snapshot);
63
- this.waiter = undefined;
66
+ try {
67
+ await this.observer;
68
+ }
69
+ finally {
70
+ this.reader.clear();
71
+ this.waiter = undefined;
72
+ }
64
73
  }
65
74
  async observe() {
66
75
  for (;;) {
67
76
  const snapshot = this.observation;
68
- if (!(await heartExists(this.paths)))
77
+ if (snapshot.soul === null)
69
78
  return this.cancel("heart-gone");
70
79
  if (snapshot.stop?.bodySequence === this.bodySequence || snapshot.pause?.bodySequence === this.bodySequence) {
71
80
  return this.cancel("control");
@@ -76,14 +85,7 @@ export class BodySupervisor {
76
85
  catch {
77
86
  return;
78
87
  }
79
- try {
80
- await this.refresh();
81
- }
82
- catch (error) {
83
- if (await heartExists(this.paths))
84
- throw error;
85
- return this.cancel("heart-gone");
86
- }
88
+ await this.refresh();
87
89
  }
88
90
  }
89
91
  }
@@ -25,6 +25,7 @@ export declare const bodyLaunchSchema: z.ZodObject<{
25
25
  options: import("./provider-recipe.js").ProviderOptions;
26
26
  cwd: string;
27
27
  origin: import("./heart/facts.js").AkumaOrigin;
28
+ caller?: import("./caller.js").AkumaCaller;
28
29
  allowed: import("./allowed.js").AllowedActions;
29
30
  createdAt: string;
30
31
  }>, "createdAt">, unknown>>>;
@@ -55,11 +56,11 @@ export declare const bodyLaunchSchema: z.ZodObject<{
55
56
  }>>;
56
57
  systemPrompt: z.ZodOptional<z.ZodString>;
57
58
  systemPromptMode: z.ZodOptional<z.ZodEnum<{
58
- append: "append";
59
59
  replace: "replace";
60
+ append: "append";
60
61
  }>>;
61
62
  }, z.core.$strip>, z.ZodTransform<Readonly<{
62
- systemPromptMode?: "append" | "replace";
63
+ systemPromptMode?: "replace" | "append";
63
64
  systemPrompt?: string;
64
65
  network?: "disabled" | "enabled";
65
66
  effort?: string;
@@ -69,12 +70,13 @@ export declare const bodyLaunchSchema: z.ZodObject<{
69
70
  effort?: string | undefined;
70
71
  network?: "disabled" | "enabled" | undefined;
71
72
  systemPrompt?: string | undefined;
72
- systemPromptMode?: "append" | "replace" | undefined;
73
+ systemPromptMode?: "replace" | "append" | undefined;
73
74
  }>>;
74
75
  admittedAt: z.ZodString;
75
76
  }, z.core.$strict>>;
76
77
  initialBody: z.ZodOptional<z.ZodString>;
77
78
  initiator: z.ZodOptional<z.ZodString>;
79
+ birthInitiator: z.ZodOptional<z.ZodString>;
78
80
  initialSchemaJson: z.ZodOptional<z.ZodString>;
79
81
  refuseIfHeld: z.ZodOptional<z.ZodBoolean>;
80
82
  completion: z.ZodOptional<z.ZodObject<{
@@ -1,3 +1,4 @@
1
+ import { projectAkumaBirth } from "./caller.js";
1
2
  import { z } from "zod";
2
3
  import { decodeSoulSeed } from "./heart/soul.js";
3
4
  import { sessionAdmissionSchema } from "./heart/rows.js";
@@ -35,6 +36,7 @@ export const bodyLaunchSchema = z
35
36
  birthSession: sessionAdmissionSchema.optional(),
36
37
  initialBody: z.string().optional(),
37
38
  initiator: z.string().optional(),
39
+ birthInitiator: z.string().optional(),
38
40
  initialSchemaJson: z.string().optional(),
39
41
  refuseIfHeld: z.boolean().optional(),
40
42
  completion: z.object({ contractId: z.string().optional() }).strict().optional(),
@@ -74,17 +76,18 @@ async function takeLeash(paths, refuseIfHeld = false) {
74
76
  async function bornSoul(launch, leash, now) {
75
77
  const before = await readHeart(launch.paths);
76
78
  if (before.soul !== null)
77
- return before.soul;
79
+ return { soul: before.soul, created: false };
78
80
  if (launch.seed === undefined)
79
81
  throw new Error("Akuma wake has no born soul");
80
82
  const candidate = { ...launch.seed, createdAt: now };
81
- if ((await leash.birth(launch.paths, candidate, launch.birthSession)) === "sealed")
83
+ const result = await leash.birth(launch.paths, candidate, launch.birthSession);
84
+ if (result === "sealed")
82
85
  return null;
83
86
  const born = (await readHeart(launch.paths)).soul;
84
87
  if (born === null || born.id !== candidate.id) {
85
88
  throw new Error("Akuma birth identity does not match its directory");
86
89
  }
87
- return born;
90
+ return { soul: born, created: result === "born" };
88
91
  }
89
92
  async function launchCwd(launch) {
90
93
  if (launch.seed !== undefined)
@@ -233,14 +236,18 @@ export async function bodyProcessInput(launch, bodyModuleUrl = import.meta.url)
233
236
  return {
234
237
  argv: source ? [executable, "--import", import.meta.resolve("tsx"), entry, encoded] : [executable, entry, encoded],
235
238
  cwd: await launchCwd(launch),
236
- env: akumaExecutionEnvironment(process.env, { KEIYAKU_ACTOR_ID: actorId }),
239
+ env: akumaExecutionEnvironment(process.env, {
240
+ KEIYAKU_ACTOR_ID: actorId,
241
+ KEIYAKU_ACTOR_WORLD: worldRootForAkumaPaths(launch.paths),
242
+ }),
237
243
  log: launch.paths.log,
238
244
  };
239
245
  }
240
246
  async function prepareBodyExecution(launch, leash, runtime, adapter) {
241
- const soul = await bornSoul(launch, leash, runtime.now());
242
- if (soul === null)
247
+ const birth = await bornSoul(launch, leash, runtime.now());
248
+ if (birth === null)
243
249
  return null;
250
+ const { soul } = birth;
244
251
  if (launch.seed === undefined && launch.initialBody === undefined) {
245
252
  const [heart, requests] = await Promise.all([readHeart(launch.paths), readNonterminalRequests(launch.paths)]);
246
253
  if (heart.pending.length === 0 && requests.length === 0)
@@ -249,7 +256,7 @@ async function prepareBodyExecution(launch, leash, runtime, adapter) {
249
256
  const selected = adapter ?? (await resolveProviderExecution(soul.provider)).adapter;
250
257
  if (!(await prepareBodyStart(launch.paths, leash)))
251
258
  return null;
252
- return { soul, adapter: selected };
259
+ return { ...birth, adapter: selected };
253
260
  }
254
261
  async function runPreparedBody(input) {
255
262
  let pendingTellDisposition;
@@ -306,6 +313,29 @@ async function recoverBodyRequests(input) {
306
313
  }
307
314
  return false;
308
315
  }
316
+ function turnStartedEmitter(launch, soul, world) {
317
+ const reportDiagnostic = (message) => {
318
+ void recordPluginDiagnostic(launch.paths, "turn started", message);
319
+ };
320
+ return {
321
+ async emit(turnSequence) {
322
+ try {
323
+ const turn = await readTurn(launch.paths, turnSequence);
324
+ if (turn === null)
325
+ throw new Error(`Committed Turn ${turnSequence} is missing from Heart`);
326
+ await emitPluginSignal({ world, reportDiagnostic }, {
327
+ kind: "akuma.turn-started",
328
+ akumaId: soul.id,
329
+ turnSequence,
330
+ ...(turn.initiator === undefined ? {} : { initiator: turn.initiator }),
331
+ });
332
+ }
333
+ catch (error) {
334
+ await recordPluginDiagnostic(launch.paths, "turn started", error);
335
+ }
336
+ },
337
+ };
338
+ }
309
339
  function turnOutcomeEmitter(launch, soul, world) {
310
340
  const reportDiagnostic = (message) => {
311
341
  void recordPluginDiagnostic(launch.paths, "turn outcome", message);
@@ -376,7 +406,7 @@ async function admitInitialCallTell(runtime, input) {
376
406
  });
377
407
  }
378
408
  async function runBodyTurns(input) {
379
- const { launch, soul, adapter, bodySequence, supervisor, runtime, turnOutcome } = input;
409
+ const { launch, soul, adapter, bodySequence, supervisor, runtime, turnStarted, turnOutcome } = input;
380
410
  let initial = launch.initialBody;
381
411
  for (;;) {
382
412
  const launchTells = drainPendingTells(supervisor.current().pending, await readOpenBoundTurns(launch.paths, bodySequence));
@@ -411,6 +441,7 @@ async function runBodyTurns(input) {
411
441
  world: runtime.world,
412
442
  externalCommands: runtime.externalCommands,
413
443
  now: runtime.now,
444
+ turnStarted,
414
445
  });
415
446
  if (result.kind === "hung") {
416
447
  await failOpenBoundTurnsIfPresent(launch.paths, bodySequence, "Body hung with open bound Turns", runtime.now());
@@ -559,15 +590,32 @@ export async function driveAkumaBody(launch, adapter, runtimeInput = {}) {
559
590
  let pendingTellDisposition = undefined;
560
591
  let bodySequence;
561
592
  let emitBodyEnd;
593
+ let emitTurnStarted;
562
594
  let emitTurnOutcome;
563
595
  try {
564
596
  const prepared = await prepareBodyExecution(launch, leash, runtime, adapter);
565
597
  if (prepared === null)
566
598
  return;
567
599
  emitBodyEnd = bodyEndEmitter(launch, prepared.soul, world);
600
+ emitTurnStarted = turnStartedEmitter(launch, prepared.soul, world);
568
601
  emitTurnOutcome = turnOutcomeEmitter(launch, prepared.soul, world);
569
602
  const body = await leash.recordBody(launch.paths, { leashTakenAt: runtime.now() });
570
603
  bodySequence = body.sequence;
604
+ if (prepared.created) {
605
+ await emitPluginSignal({
606
+ world,
607
+ reportDiagnostic: (message) => {
608
+ void recordPluginDiagnostic(launch.paths, "birth", message);
609
+ },
610
+ }, {
611
+ kind: "akuma.born",
612
+ akumaId: prepared.soul.id,
613
+ bodySequence: body.sequence,
614
+ ...projectAkumaBirth(prepared.soul),
615
+ ...(launch.birthInitiator === undefined ? {} : { initiator: launch.birthInitiator }),
616
+ ...(launch.completion?.contractId === undefined ? {} : { contractId: launch.completion.contractId }),
617
+ });
618
+ }
571
619
  const supervisor = await BodySupervisor.open(launch.paths, body.sequence, leash);
572
620
  pendingTellDisposition = await runPreparedBody({
573
621
  launch,
@@ -576,6 +624,7 @@ export async function driveAkumaBody(launch, adapter, runtimeInput = {}) {
576
624
  bodySequence: body.sequence,
577
625
  supervisor,
578
626
  runtime,
627
+ turnStarted: emitTurnStarted,
579
628
  turnOutcome: emitTurnOutcome,
580
629
  });
581
630
  }