@astrosheep/keiyaku 4.0.1 → 4.0.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 (245) hide show
  1. package/README.md +137 -5
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
  9. package/build/src/akuma/abort.d.ts +2 -0
  10. package/build/src/akuma/abort.js +50 -0
  11. package/build/src/akuma/akuma.d.ts +23 -14
  12. package/build/src/akuma/akuma.js +120 -104
  13. package/build/src/akuma/archetype.d.ts +7 -6
  14. package/build/src/akuma/archetype.js +68 -41
  15. package/build/src/akuma/body.d.ts +3 -5
  16. package/build/src/akuma/body.js +408 -213
  17. package/build/src/akuma/heart/facts.d.ts +25 -34
  18. package/build/src/akuma/heart/facts.js +18 -7
  19. package/build/src/akuma/heart/index.d.ts +39 -42
  20. package/build/src/akuma/heart/index.js +134 -93
  21. package/build/src/akuma/heart/rows.d.ts +9 -31
  22. package/build/src/akuma/heart/rows.js +26 -44
  23. package/build/src/akuma/heart/schema.d.ts +1 -1
  24. package/build/src/akuma/heart/schema.js +7 -15
  25. package/build/src/akuma/heart/soul.d.ts +8 -0
  26. package/build/src/akuma/heart/soul.js +136 -0
  27. package/build/src/akuma/heart/storage.d.ts +28 -14
  28. package/build/src/akuma/heart/storage.js +86 -26
  29. package/build/src/akuma/identity.d.ts +2 -2
  30. package/build/src/akuma/identity.js +9 -9
  31. package/build/src/akuma/index.d.ts +6 -1
  32. package/build/src/akuma/index.js +6 -0
  33. package/build/src/akuma/projection.d.ts +117 -38
  34. package/build/src/akuma/projection.js +208 -97
  35. package/build/src/akuma/provider-recipe.d.ts +24 -0
  36. package/build/src/akuma/provider-recipe.js +100 -0
  37. package/build/src/akuma/provider.d.ts +12 -4
  38. package/build/src/akuma/provider.js +117 -70
  39. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  40. package/build/src/akuma/providers/acp/core.js +159 -0
  41. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  42. package/build/src/akuma/providers/acp/events.js +73 -0
  43. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  44. package/build/src/akuma/providers/acp/index.js +94 -0
  45. package/build/src/akuma/providers/claude/events.js +66 -13
  46. package/build/src/akuma/providers/claude/index.d.ts +2 -1
  47. package/build/src/akuma/providers/claude/index.js +35 -21
  48. package/build/src/akuma/providers/codex-app-server/events.js +4 -1
  49. package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
  50. package/build/src/akuma/providers/codex-app-server/index.js +24 -31
  51. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  52. package/build/src/akuma/providers/grok-build/index.js +70 -0
  53. package/build/src/akuma/providers/index.d.ts +5 -3
  54. package/build/src/akuma/providers/index.js +24 -59
  55. package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
  56. package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
  57. package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
  58. package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
  59. package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
  60. package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
  61. package/build/src/akuma/providers/pi/events.js +49 -11
  62. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  63. package/build/src/akuma/providers/pi/index.js +50 -21
  64. package/build/src/akuma/publication.d.ts +3 -3
  65. package/build/src/akuma/publication.js +28 -40
  66. package/build/src/akuma/requests.d.ts +9 -7
  67. package/build/src/akuma/requests.js +92 -65
  68. package/build/src/alias/index.d.ts +2 -2
  69. package/build/src/alias/index.js +10 -10
  70. package/build/src/body/decode.js +7 -1
  71. package/build/src/body/region.d.ts +2 -0
  72. package/build/src/body/region.js +77 -7
  73. package/build/src/cli/accepted.d.ts +17 -13
  74. package/build/src/cli/accepted.js +72 -34
  75. package/build/src/cli/actor.js +3 -3
  76. package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
  77. package/build/src/cli/commands/akuma-invoke.js +14 -9
  78. package/build/src/cli/commands/akuma.d.ts +13 -3
  79. package/build/src/cli/commands/akuma.js +67 -34
  80. package/build/src/cli/commands/contract.d.ts +18 -5
  81. package/build/src/cli/commands/contract.js +9 -3
  82. package/build/src/cli/commands/task-invoke.d.ts +17 -4
  83. package/build/src/cli/commands/task-invoke.js +43 -20
  84. package/build/src/cli/commands/task-query.d.ts +5 -0
  85. package/build/src/cli/commands/task-query.js +247 -0
  86. package/build/src/cli/commands/task.d.ts +3 -1
  87. package/build/src/cli/commands/task.js +51 -13
  88. package/build/src/cli/coordinates.d.ts +18 -0
  89. package/build/src/cli/coordinates.js +120 -0
  90. package/build/src/cli/draft.d.ts +8 -0
  91. package/build/src/cli/draft.js +96 -0
  92. package/build/src/cli/invoke.d.ts +4 -3
  93. package/build/src/cli/invoke.js +160 -179
  94. package/build/src/cli/main.js +34 -6
  95. package/build/src/cli/parse.d.ts +9 -2
  96. package/build/src/cli/parse.js +29 -7
  97. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  98. package/build/src/cli/render/akuma-tool-command.js +144 -0
  99. package/build/src/cli/render/akuma-tool.d.ts +2 -2
  100. package/build/src/cli/render/akuma-tool.js +30 -4
  101. package/build/src/cli/render/akuma.d.ts +1 -0
  102. package/build/src/cli/render/akuma.js +211 -116
  103. package/build/src/cli/render/audit.d.ts +3 -0
  104. package/build/src/cli/render/audit.js +104 -0
  105. package/build/src/cli/render/contract.d.ts +3 -3
  106. package/build/src/cli/render/contract.js +192 -79
  107. package/build/src/cli/render/kanshi.js +263 -168
  108. package/build/src/cli/render/receipt.d.ts +19 -0
  109. package/build/src/cli/render/receipt.js +106 -0
  110. package/build/src/cli/render/refusal.d.ts +16 -2
  111. package/build/src/cli/render/refusal.js +88 -20
  112. package/build/src/cli/render/region.d.ts +2 -0
  113. package/build/src/cli/render/region.js +17 -0
  114. package/build/src/cli/render/task.d.ts +2 -1
  115. package/build/src/cli/render/task.js +223 -60
  116. package/build/src/cli/render/terminal.d.ts +7 -0
  117. package/build/src/cli/render/terminal.js +46 -0
  118. package/build/src/cli/render/text.js +6 -3
  119. package/build/src/cli/result.d.ts +115 -20
  120. package/build/src/cli/usage.d.ts +1 -0
  121. package/build/src/cli/usage.js +3 -0
  122. package/build/src/contract-worktree.d.ts +6 -5
  123. package/build/src/contract-worktree.js +95 -57
  124. package/build/src/coordination/durable-file.d.ts +4 -3
  125. package/build/src/coordination/durable-file.js +29 -25
  126. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  127. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  128. package/build/src/core/facts/fold.js +1 -6
  129. package/build/src/core/facts/gate.d.ts +1 -0
  130. package/build/src/core/facts/gate.js +1 -0
  131. package/build/src/core/verbs/amend.d.ts +1 -1
  132. package/build/src/core/verbs/amend.js +0 -11
  133. package/build/src/core/verbs/deliver.d.ts +1 -1
  134. package/build/src/core/verbs/deliver.js +1 -7
  135. package/build/src/core/verbs/placement.d.ts +1 -1
  136. package/build/src/core/verbs/placement.js +4 -1
  137. package/build/src/dispatch/index.d.ts +2 -2
  138. package/build/src/dispatch/index.js +17 -17
  139. package/build/src/git/admission.d.ts +1 -1
  140. package/build/src/git/admission.js +11 -11
  141. package/build/src/git/hooks.js +13 -13
  142. package/build/src/git/integration.d.ts +14 -15
  143. package/build/src/git/integration.js +80 -44
  144. package/build/src/git/observe.d.ts +5 -3
  145. package/build/src/git/observe.js +18 -12
  146. package/build/src/git/read-observation.js +9 -9
  147. package/build/src/git/reconcile.d.ts +2 -0
  148. package/build/src/git/reconcile.js +138 -95
  149. package/build/src/git/repository.d.ts +27 -19
  150. package/build/src/git/repository.js +155 -83
  151. package/build/src/git/scratch.d.ts +7 -3
  152. package/build/src/git/scratch.js +44 -37
  153. package/build/src/git/target-placement.d.ts +40 -4
  154. package/build/src/git/target-placement.js +221 -101
  155. package/build/src/git/tender.d.ts +6 -5
  156. package/build/src/git/tender.js +24 -43
  157. package/build/src/git/terminal-seal.d.ts +1 -1
  158. package/build/src/git/terminal-seal.js +7 -5
  159. package/build/src/git/workspace.d.ts +36 -4
  160. package/build/src/git/workspace.js +53 -18
  161. package/build/src/identity/selector.js +1 -1
  162. package/build/src/index.d.ts +3 -3
  163. package/build/src/index.js +1 -1
  164. package/build/src/kanshi/index.d.ts +2 -2
  165. package/build/src/kanshi/index.js +1 -1
  166. package/build/src/kanshi/read.d.ts +2 -1
  167. package/build/src/kanshi/read.js +118 -27
  168. package/build/src/kanshi/report.d.ts +50 -0
  169. package/build/src/kanshi/select.d.ts +5 -0
  170. package/build/src/kanshi/select.js +32 -0
  171. package/build/src/library/address.d.ts +12 -3
  172. package/build/src/library/address.js +77 -46
  173. package/build/src/library/akuma-creation.d.ts +6 -1
  174. package/build/src/library/akuma-creation.js +86 -13
  175. package/build/src/library/audit.d.ts +18 -0
  176. package/build/src/library/audit.js +44 -0
  177. package/build/src/library/bind.js +4 -4
  178. package/build/src/library/catalog.d.ts +1 -1
  179. package/build/src/library/catalog.js +5 -8
  180. package/build/src/library/contract.d.ts +5 -6
  181. package/build/src/library/contract.js +11 -35
  182. package/build/src/library/delivery.d.ts +2 -1
  183. package/build/src/library/fleet.d.ts +2 -2
  184. package/build/src/library/fleet.js +35 -71
  185. package/build/src/library/keiyaku.d.ts +3 -2
  186. package/build/src/library/keiyaku.js +1 -0
  187. package/build/src/library/mutation.d.ts +7 -6
  188. package/build/src/library/mutation.js +23 -25
  189. package/build/src/library/reconcile.d.ts +29 -0
  190. package/build/src/library/reconcile.js +179 -0
  191. package/build/src/library/region.d.ts +12 -0
  192. package/build/src/library/region.js +15 -1
  193. package/build/src/library/repo.d.ts +4 -16
  194. package/build/src/library/repo.js +13 -38
  195. package/build/src/protocol/attempt.js +6 -6
  196. package/build/src/protocol/bind.js +4 -4
  197. package/build/src/protocol/intent.d.ts +15 -2
  198. package/build/src/protocol/intent.js +21 -6
  199. package/build/src/protocol/operations.d.ts +73 -22
  200. package/build/src/protocol/operations.js +292 -88
  201. package/build/src/protocol/outcome.d.ts +9 -3
  202. package/build/src/protocol/outcome.js +3 -1
  203. package/build/src/protocol/placement.d.ts +15 -4
  204. package/build/src/protocol/placement.js +58 -25
  205. package/build/src/protocol/read/status.d.ts +8 -1
  206. package/build/src/protocol/read/status.js +61 -14
  207. package/build/src/runtime/proc/line-rpc.d.ts +3 -8
  208. package/build/src/runtime/proc/line-rpc.js +16 -43
  209. package/build/src/runtime/proc/run.d.ts +15 -29
  210. package/build/src/runtime/proc/run.js +113 -105
  211. package/build/src/runtime/proc/stdio.d.ts +18 -0
  212. package/build/src/runtime/proc/stdio.js +58 -0
  213. package/build/src/settings.d.ts +2 -2
  214. package/build/src/settings.js +8 -8
  215. package/build/src/settlement/fence.d.ts +0 -4
  216. package/build/src/settlement/fence.js +0 -9
  217. package/build/src/settlement/holder.d.ts +11 -1
  218. package/build/src/settlement/holder.js +25 -0
  219. package/build/src/settlement/settle.d.ts +1 -1
  220. package/build/src/settlement/settle.js +52 -89
  221. package/build/src/task/board.d.ts +3 -3
  222. package/build/src/task/board.js +6 -9
  223. package/build/src/task/compose.d.ts +1 -1
  224. package/build/src/task/compose.js +18 -10
  225. package/build/src/task/context.d.ts +3 -3
  226. package/build/src/task/context.js +14 -14
  227. package/build/src/task/document.d.ts +2 -1
  228. package/build/src/task/document.js +15 -5
  229. package/build/src/task/index.d.ts +19 -7
  230. package/build/src/task/index.js +42 -23
  231. package/build/src/task/operations.d.ts +15 -9
  232. package/build/src/task/operations.js +78 -48
  233. package/build/src/task/query.d.ts +67 -0
  234. package/build/src/task/query.js +279 -0
  235. package/build/src/task/store.d.ts +2 -2
  236. package/build/src/task/store.js +40 -25
  237. package/build/src/verification/execution.d.ts +4 -2
  238. package/build/src/verification/execution.js +9 -5
  239. package/build/src/workspace-place.d.ts +41 -0
  240. package/build/src/workspace-place.js +386 -0
  241. package/build/src/world.d.ts +13 -2
  242. package/build/src/world.js +81 -48
  243. package/package.json +3 -2
  244. package/build/src/protocol/read/audit.d.ts +0 -31
  245. package/build/src/protocol/read/audit.js +0 -55
@@ -1,21 +1,24 @@
1
1
  import { createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager, } from "@earendil-works/pi-coding-agent";
2
+ import { abortable } from "../../abort.js";
2
3
  import { AgentEventChannel } from "../../provider.js";
3
4
  import { piTerminalFailure, translatePiEvent } from "./events.js";
4
5
  const PI_THINKING_LEVELS = new Set(["minimal", "low", "medium", "high", "xhigh", "max"]);
5
6
  const MODEL_PATTERN = /^[^/\s]+\/[^/\s]+$/u;
6
7
  function diagnostic(error) { return error instanceof Error ? error.message : String(error); }
7
8
  function admitPiOptions(options) {
8
- if (options.access !== undefined)
9
- return { kind: "refused", diagnostic: "Pi provider does not support the Archetype access option" };
10
9
  if (options.network !== undefined)
11
- return { kind: "refused", diagnostic: "Pi provider does not support the Archetype network option" };
10
+ return { kind: "refused", diagnostic: "Pi provider does not support the network option" };
12
11
  if (options.model !== undefined && !MODEL_PATTERN.test(options.model)) {
13
12
  return { kind: "refused", diagnostic: "Pi provider model must use <provider>/<id>" };
14
13
  }
15
14
  if (options.effort !== undefined && !PI_THINKING_LEVELS.has(options.effort)) {
16
15
  return { kind: "refused", diagnostic: "Pi provider effort must be minimal, low, medium, high, xhigh, or max" };
17
16
  }
18
- return { kind: "admitted", options: Object.freeze({ ...options }) };
17
+ return {
18
+ kind: "admitted",
19
+ options: Object.freeze({ ...options }),
20
+ ...(options.readonly === undefined ? {} : { readonly: { enforcement: "native" } }),
21
+ };
19
22
  }
20
23
  async function piCreateOptions(sdk, input) {
21
24
  let model;
@@ -44,11 +47,20 @@ async function piCreateOptions(sdk, input) {
44
47
  ...(model === undefined || modelRuntime === undefined ? {} : { model, modelRuntime }),
45
48
  ...(resourceLoader === undefined ? {} : { resourceLoader }),
46
49
  ...(input.options.effort === undefined ? {} : { thinkingLevel: input.options.effort }),
50
+ ...(input.options.readonly === undefined ? {} : { tools: ["read", "grep", "find", "ls"] }),
47
51
  };
48
52
  }
49
- async function drivePi(sdk, input) {
50
- const created = await sdk.createAgentSession(await piCreateOptions(sdk, input));
53
+ async function createPiSession(sdk, input, signal) {
54
+ const setup = piCreateOptions(sdk, input).then(async (options) => await sdk.createAgentSession(options));
55
+ return await abortable(setup, signal, (created) => created.session.dispose());
56
+ }
57
+ async function drivePi(sdk, input, signal) {
58
+ const created = await createPiSession(sdk, input, signal);
51
59
  const native = created.session;
60
+ if (signal.aborted) {
61
+ native.dispose();
62
+ signal.throwIfAborted();
63
+ }
52
64
  if (native.sessionFile === undefined || native.sessionFile.trim().length === 0) {
53
65
  native.dispose();
54
66
  throw new Error("Pi session admitted without sessionFile");
@@ -58,6 +70,7 @@ async function drivePi(sdk, input) {
58
70
  let terminalFailure = null;
59
71
  let disposed = false;
60
72
  let abortRequest;
73
+ let aborting = false;
61
74
  let settled = false;
62
75
  const dispose = () => {
63
76
  if (disposed)
@@ -94,6 +107,10 @@ async function drivePi(sdk, input) {
94
107
  void (async () => {
95
108
  try {
96
109
  await native.prompt([input.body, ...input.launchTells.map((tell) => tell.text)].join("\n\n"));
110
+ if (aborting) {
111
+ settle({ kind: "failed", diagnostic: "Pi session aborted" });
112
+ return;
113
+ }
97
114
  if (terminalFailure !== null) {
98
115
  settle({ kind: "failed", diagnostic: terminalFailure });
99
116
  return;
@@ -103,22 +120,29 @@ async function drivePi(sdk, input) {
103
120
  return;
104
121
  }
105
122
  const historyId = native.sessionManager.getLeafId();
106
- settle(historyId === null
107
- ? { kind: "failed", diagnostic: "Pi completed without a forkable history entry" }
108
- : { kind: "answered", answer: state.answer, historyId });
123
+ settle({
124
+ kind: "answered",
125
+ answer: state.answer,
126
+ ...(historyId === null ? {} : { historyId }),
127
+ });
109
128
  }
110
129
  catch (error) {
111
- settle({ kind: "failed", diagnostic: diagnostic(error) });
130
+ settle(aborting
131
+ ? { kind: "failed", diagnostic: "Pi session aborted" }
132
+ : { kind: "failed", diagnostic: diagnostic(error) });
112
133
  }
113
134
  })();
114
135
  return {
115
136
  admission: { fence: native.sessionId }, events, completion,
116
137
  abort: () => {
117
138
  abortRequest ??= (async () => {
139
+ if (settled)
140
+ return;
141
+ aborting = true;
118
142
  try {
119
- void native.abort().catch(() => undefined);
143
+ await native.abort();
120
144
  }
121
- catch { /* best effort: local settlement already owns lifecycle */ }
145
+ catch { /* prompt settlement still proves local cleanup */ }
122
146
  settle({ kind: "failed", diagnostic: "Pi session aborted" });
123
147
  })();
124
148
  return abortRequest;
@@ -140,19 +164,24 @@ async function forkPi(sdk, input) {
140
164
  }
141
165
  const defaultSdk = { createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager };
142
166
  export function createPiProvider(execution = { name: "pi", kind: "pi" }, load = async () => defaultSdk) {
167
+ if (execution.executable !== undefined || execution.config !== undefined) {
168
+ throw new TypeError("Pi provider does not support executable or config");
169
+ }
170
+ if (execution.env !== undefined && Object.keys(execution.env).length > 0) {
171
+ throw new TypeError("env injection not supported for provider pi");
172
+ }
173
+ const drive = async (input) => {
174
+ const signal = input.signal ?? new AbortController().signal;
175
+ signal.throwIfAborted();
176
+ return drivePi(await abortable(load(), signal), input, signal);
177
+ };
143
178
  return {
144
179
  confinement: ({ cwd }) => ({ kind: "declared", writableRoots: [cwd] }),
145
- admitOptions(options) {
146
- if (execution.executable !== undefined || execution.config !== undefined)
147
- return { kind: "refused", diagnostic: "Pi provider does not support executable or config" };
148
- if (execution.env !== undefined && Object.keys(execution.env).length > 0)
149
- return { kind: "refused", diagnostic: "env injection not supported for provider pi" };
150
- return admitPiOptions(options);
151
- },
152
- start: async (input) => drivePi(await load(), input),
180
+ admitOptions: admitPiOptions,
181
+ start: drive,
153
182
  resume: async (input) => {
154
183
  piSessionFile(input.session.coordinate);
155
- return drivePi(await load(), input);
184
+ return drive(input);
156
185
  },
157
186
  fork: async (input) => {
158
187
  piSessionFile(input.session);
@@ -1,10 +1,10 @@
1
1
  import { type AllocatedAkuma } from "./identity.js";
2
- import { type ProcessCollar } from "../runtime/proc/run.js";
3
2
  export declare const BIRTH_TIMEOUT_MS = 5000;
4
3
  export declare function publishAkuma(input: Readonly<{
5
4
  worldPath: string;
6
5
  archetype: string;
7
6
  awaitAsleep?: boolean;
8
- reserve?(allocated: AllocatedAkuma): void;
9
- launch(allocated: AllocatedAkuma): Promise<ProcessCollar>;
7
+ reserve?(allocated: AllocatedAkuma): Promise<void>;
8
+ launch(allocated: AllocatedAkuma): Promise<void>;
9
+ signal?: AbortSignal;
10
10
  }>): Promise<AllocatedAkuma>;
@@ -1,84 +1,69 @@
1
1
  import { HeldAkumaLeash, initializeHeart, readHeart, readSoul, } from "./heart/index.js";
2
2
  import { allocateAkumaDirectory, } from "./identity.js";
3
- import { probeProcessTree } from "../runtime/proc/run.js";
3
+ import { abortableDelay } from "./abort.js";
4
4
  const POLL_MS = 25;
5
5
  export const BIRTH_TIMEOUT_MS = 5_000;
6
- function wait(milliseconds) {
7
- return new Promise((resolve) => setTimeout(resolve, milliseconds));
8
- }
9
6
  function diagnostic(error) {
10
7
  return error instanceof Error ? error.message : String(error);
11
8
  }
12
- function settleTimedOutBirth(paths) {
13
- const leash = HeldAkumaLeash.try(paths);
9
+ async function settleTimedOutBirth(paths) {
10
+ const leash = await HeldAkumaLeash.try(paths);
14
11
  if (leash === null)
15
12
  return null;
16
- const result = leash.sealIfUnborn(paths, { evidence: "call-timeout", at: new Date().toISOString() });
13
+ const result = await leash.sealIfUnborn(paths, { evidence: "call-timeout", at: new Date().toISOString() });
17
14
  if (result === "sealed")
18
15
  throw new Error("Akuma body failed before birth");
19
16
  leash.release();
20
- const soul = readSoul(paths);
17
+ const soul = await readSoul(paths);
21
18
  if (soul === null)
22
19
  throw new Error("Akuma birth settled without a soul");
23
20
  return soul;
24
21
  }
25
- async function awaitBirth(paths) {
22
+ async function awaitBirth(paths, signal) {
26
23
  const deadline = performance.now() + BIRTH_TIMEOUT_MS;
27
24
  for (;;) {
28
- const soul = readSoul(paths);
25
+ signal?.throwIfAborted();
26
+ const soul = await readSoul(paths);
29
27
  if (soul !== null)
30
28
  return soul;
31
29
  if (performance.now() >= deadline) {
32
- const settled = settleTimedOutBirth(paths);
30
+ const settled = await settleTimedOutBirth(paths);
33
31
  if (settled !== null)
34
32
  return settled;
35
33
  }
36
- await wait(POLL_MS);
34
+ await abortableDelay(POLL_MS, signal);
37
35
  }
38
36
  }
39
37
  async function takeLeashUntil(paths, deadline) {
40
38
  for (;;) {
41
- const leash = HeldAkumaLeash.try(paths);
39
+ const leash = await HeldAkumaLeash.try(paths);
42
40
  if (leash !== null)
43
41
  return leash;
44
42
  if (performance.now() >= deadline)
45
43
  return null;
46
- await wait(POLL_MS);
44
+ await abortableDelay(POLL_MS);
47
45
  }
48
46
  }
49
- async function awaitAsleepBirth(paths, collar) {
47
+ async function awaitAsleepBirth(paths) {
50
48
  const leash = await takeLeashUntil(paths, performance.now() + BIRTH_TIMEOUT_MS);
51
49
  if (leash === null)
52
50
  throw new Error("Forked Akuma did not finish its birth body");
53
51
  try {
54
- if (readHeart(paths).latestBody?.end !== "exited") {
52
+ if ((await readHeart(paths)).latestBody?.end !== "exited") {
55
53
  throw new Error("Forked Akuma birth body did not exit cleanly");
56
54
  }
57
55
  }
58
56
  finally {
59
57
  leash.release();
60
58
  }
61
- const deadline = performance.now() + BIRTH_TIMEOUT_MS;
62
- for (;;) {
63
- const probe = probeProcessTree(collar);
64
- if (probe.kind === "gone")
65
- return;
66
- if (performance.now() >= deadline) {
67
- if (probe.kind === "unverifiable") {
68
- throw new Error(`Forked Akuma birth collar is unverifiable: ${probe.diagnostic}`);
69
- }
70
- throw new Error("Forked Akuma birth process did not exit");
71
- }
72
- await wait(POLL_MS);
73
- }
74
59
  }
75
- function sealLocalFailure(allocated, error) {
60
+ async function sealLocalFailure(allocated, error) {
76
61
  try {
77
- const leash = HeldAkumaLeash.try(allocated.paths);
62
+ const leash = await HeldAkumaLeash.try(allocated.paths);
78
63
  if (leash === null)
79
64
  return;
80
65
  try {
81
- leash.sealIfUnborn(allocated.paths, { evidence: diagnostic(error), at: new Date().toISOString() });
66
+ await leash.sealIfUnborn(allocated.paths, { evidence: diagnostic(error), at: new Date().toISOString() });
82
67
  }
83
68
  finally {
84
69
  leash.release();
@@ -87,21 +72,24 @@ function sealLocalFailure(allocated, error) {
87
72
  catch { /* the original local publication failure remains authoritative */ }
88
73
  }
89
74
  export async function publishAkuma(input) {
90
- const allocated = allocateAkumaDirectory({ worldRoot: input.worldPath, archetype: input.archetype });
91
- let collar;
75
+ input.signal?.throwIfAborted();
76
+ const allocated = await allocateAkumaDirectory({ worldRoot: input.worldPath, archetype: input.archetype });
92
77
  try {
93
- initializeHeart(allocated.paths);
94
- input.reserve?.(allocated);
95
- collar = await input.launch(allocated);
78
+ await initializeHeart(allocated.paths);
79
+ input.signal?.throwIfAborted();
80
+ await input.reserve?.(allocated);
81
+ input.signal?.throwIfAborted();
82
+ await input.launch(allocated);
83
+ input.signal?.throwIfAborted();
96
84
  }
97
85
  catch (error) {
98
- sealLocalFailure(allocated, error);
86
+ await sealLocalFailure(allocated, error);
99
87
  throw error;
100
88
  }
101
- const soul = await awaitBirth(allocated.paths);
89
+ const soul = await awaitBirth(allocated.paths, input.signal);
102
90
  if (soul.id !== allocated.id)
103
91
  throw new Error("Akuma birth returned a different identity");
104
92
  if (input.awaitAsleep === true)
105
- await awaitAsleepBirth(allocated.paths, collar);
93
+ await awaitAsleepBirth(allocated.paths);
106
94
  return allocated;
107
95
  }
@@ -1,6 +1,5 @@
1
1
  import { type RequestRecipe, type Soul } from "./heart/index.js";
2
2
  import { type AkuId, type AkumaPaths } from "./identity.js";
3
- import type { ProcessCollar } from "../runtime/proc/run.js";
4
3
  type RequestClaim = Readonly<{
5
4
  id: string;
6
5
  world: string;
@@ -28,20 +27,23 @@ export declare class BodyRequestPump {
28
27
  private readonly input;
29
28
  readonly directory: string;
30
29
  readonly failure: Promise<never>;
31
- private closed;
30
+ private readonly closeSignal;
32
31
  private readonly handled;
33
32
  private readonly running;
34
- constructor(input: Readonly<{
33
+ private readonly cancelAdmission;
34
+ private constructor();
35
+ static open(input: Readonly<{
35
36
  paths: AkumaPaths;
36
37
  parent: Soul;
37
38
  bodySequence: number;
38
39
  now(): string;
39
- spawn(launch: RequestChildLaunch): Promise<ProcessCollar>;
40
- }>);
40
+ spawn(launch: RequestChildLaunch): Promise<void>;
41
+ signal: AbortSignal;
42
+ }>): Promise<BodyRequestPump>;
41
43
  private run;
42
44
  close(): Promise<void>;
43
45
  stopAdmission(): void;
44
46
  }
45
- export declare function clearBodyRequestTransport(paths: AkumaPaths): void;
46
- export declare function settleBodyRequests(paths: AkumaPaths, parent: Soul, now: () => string): Promise<"settled" | "pending">;
47
+ export declare function clearBodyRequestTransport(paths: AkumaPaths): Promise<void>;
48
+ export declare function settleBodyRequests(paths: AkumaPaths, parent: Soul, now: () => string, signal?: AbortSignal): Promise<"settled" | "pending">;
47
49
  export {};