@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,5 +1,6 @@
1
1
  import type { AkuId } from "../identity.js";
2
2
  import type { ResumeCoordinate } from "../coordinate.js";
3
+ import type { ProviderExecution, ProviderOptions, ReadonlyRestraint } from "../provider-recipe.js";
3
4
  export type { ResumeCoordinate } from "../coordinate.js";
4
5
  export type Confinement = Readonly<{
5
6
  kind: "unconfined";
@@ -7,20 +8,6 @@ export type Confinement = Readonly<{
7
8
  kind: "declared";
8
9
  writableRoots: readonly string[];
9
10
  }>;
10
- export type ProviderOptions = Readonly<{
11
- model?: string;
12
- effort?: string;
13
- access?: "read" | "write" | "auto";
14
- network?: "disabled" | "enabled";
15
- systemPrompt?: string;
16
- }>;
17
- export type ProviderExecution = Readonly<{
18
- name: string;
19
- kind: "claude-agent-sdk" | "codex-app-server" | "opencode-sdk" | "pi";
20
- executable?: string;
21
- config?: Readonly<Record<string, unknown>>;
22
- env?: Readonly<Record<string, string>>;
23
- }>;
24
11
  export type AkumaOrigin = Readonly<{
25
12
  kind: "direct";
26
13
  }> | Readonly<{
@@ -38,22 +25,21 @@ export type Soul = Readonly<{
38
25
  description?: string;
39
26
  provider: ProviderExecution;
40
27
  options: ProviderOptions;
28
+ readonly?: ReadonlyRestraint;
41
29
  cwd: string;
42
30
  origin: AkumaOrigin;
43
31
  confinement: Confinement;
44
32
  createdAt: string;
45
33
  }>;
46
- export type RequestRecipe = Pick<Soul, "description" | "provider" | "options" | "confinement">;
47
- export type Collar = Readonly<{
48
- pid: number;
49
- processGroup: number;
50
- spawnedAt: string;
51
- }>;
34
+ export type RequestRecipe = Pick<Soul, "description" | "provider" | "options" | "readonly" | "confinement">;
52
35
  export type BodyEnd = "exited" | "broke-off" | "put-down";
53
36
  export type BodyFact = Readonly<{
54
37
  sequence: number;
55
- collar: Collar;
56
38
  leashTakenAt: string;
39
+ hung?: Readonly<{
40
+ diagnostic: string;
41
+ at: string;
42
+ }>;
57
43
  end?: BodyEnd;
58
44
  endedAt?: string;
59
45
  }>;
@@ -74,7 +60,7 @@ export type ForkPoint = Readonly<{
74
60
  }>;
75
61
  export type TurnOutcome = Readonly<{
76
62
  kind: "answered";
77
- historyId: string;
63
+ historyId?: string;
78
64
  session: ResumeCoordinate;
79
65
  answer: string;
80
66
  }> | Readonly<{
@@ -166,7 +152,7 @@ export type RequestFact = RequestInput & Readonly<{
166
152
  state: "voided";
167
153
  evidence: string;
168
154
  }>);
169
- export type KillEvidence = "killed" | "already-killed" | "alive-after-sigkill" | "unavailable";
155
+ export type KillEvidence = "killed" | "already-killed" | "already-stopped" | "hung" | "untidy" | "unavailable";
170
156
  export type KillFact = Readonly<{
171
157
  sequence: number;
172
158
  bodySequence: number;
@@ -177,26 +163,31 @@ export type StopFact = Readonly<{
177
163
  bodySequence: number;
178
164
  requestedAt: string;
179
165
  }>;
166
+ export type PauseFact = Readonly<{
167
+ bodySequence: number;
168
+ requestedAt: string;
169
+ }>;
180
170
  export type SealFact = Readonly<{
181
171
  evidence: string;
182
172
  at: string;
183
173
  }>;
184
174
  export type LeashProbe = "held" | "free";
185
- export type CollarProbe = Readonly<{
186
- kind: "gone";
187
- end: BodyEnd | null;
188
- }> | Readonly<{
189
- kind: "alive";
190
- }> | Readonly<{
191
- kind: "unverifiable";
192
- diagnostic: string;
193
- }>;
194
- export type AkumaLife = "running" | "asleep" | "stranded" | "headless" | "killed";
175
+ export type AkumaLife = "running" | "asleep" | "stranded" | "hung" | "untidy" | "killed";
195
176
  export type HeartSnapshot = Readonly<{
196
177
  soul: Soul | null;
197
178
  latestBody: BodyFact | null;
198
179
  latestSession: SessionFact | null;
199
180
  pending: readonly TellFact[];
200
181
  latestKill: KillFact | null;
182
+ stop: StopFact | null;
183
+ pause: PauseFact | null;
184
+ }>;
185
+ export declare function life(input: Readonly<{
186
+ leash: LeashProbe;
187
+ body: BodyFact | null;
188
+ kill: KillFact | null;
189
+ }>): AkumaLife;
190
+ export declare function lifeAt(current: AkumaLife, body: BodyFact | null, kill: KillFact | null, createdAt: string): string | null;
191
+ export type SoulRow = Readonly<{
192
+ soul_json: string;
201
193
  }>;
202
- export declare function life(leashProbe: LeashProbe, collarProbe: CollarProbe, latestBody: BodyFact | null, latestKill: KillFact | null): AkumaLife;
@@ -1,9 +1,20 @@
1
- export function life(leashProbe, collarProbe, latestBody, latestKill) {
2
- if (leashProbe === "held")
3
- return "running";
4
- if (collarProbe.kind !== "gone")
5
- return "headless";
6
- if (latestBody !== null && latestKill?.bodySequence === latestBody.sequence)
1
+ export function life(input) {
2
+ if (input.leash === "held")
3
+ return input.body?.hung === undefined ? "running" : "hung";
4
+ if (input.body === null || input.body.end === undefined)
5
+ return "untidy";
6
+ if (input.kill?.bodySequence === input.body.sequence)
7
7
  return "killed";
8
- return collarProbe.end === "exited" ? "asleep" : "stranded";
8
+ return input.body.end === "exited" ? "asleep" : "stranded";
9
+ }
10
+ export function lifeAt(current, body, kill, createdAt) {
11
+ if (current === "running")
12
+ return body?.leashTakenAt ?? null;
13
+ if (current === "hung")
14
+ return body?.hung?.at ?? null;
15
+ if (current === "killed")
16
+ return kill?.at ?? null;
17
+ if (current === "asleep")
18
+ return body?.endedAt ?? createdAt;
19
+ return current === "stranded" ? body?.endedAt ?? null : null;
9
20
  }
@@ -1,25 +1,21 @@
1
1
  import type { AkuId, AkumaPaths } from "../identity.js";
2
- import type { BodyEnd, BodyFact, Collar, ForkPoint, HeartSnapshot, KillFact, RequestFact, RequestInput, SealFact, SessionFact, Soul, TellDeliveryInput, TellFact, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact } from "./facts.js";
2
+ import type { BodyEnd, BodyFact, ForkPoint, HeartSnapshot, KillFact, RequestFact, RequestInput, SealFact, SessionFact, Soul, TellDeliveryInput, TellFact, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact } from "./facts.js";
3
3
  export type { CallFact } from "./facts.js";
4
4
  import type { ActivityFact } from "./rows.js";
5
5
  import { type ActivityFactSlice } from "./timeline.js";
6
- export { HeldAkumaLeash, initializeHeart, probeLeash } from "./storage.js";
7
- export { life } from "./facts.js";
8
- export type { AkumaLife, AkumaOrigin, BodyEnd, BodyFact, Collar, CollarProbe, Confinement, HeartSnapshot, ForkPoint, KillEvidence, KillFact, LeashProbe, ProviderOptions, ProviderExecution, RequestFact, RequestInput, RequestRecipe, SealFact, SessionFact, Soul, StopFact, TellFact, TellDelivery, TellDeliveryInput, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact, } from "./facts.js";
6
+ export { HeartAbsentError, HeldAkumaLeash, initializeHeart, isHeartAbsent, probeLeash } from "./storage.js";
7
+ export { life, lifeAt } from "./facts.js";
8
+ export type { AkumaLife, AkumaOrigin, BodyEnd, BodyFact, Confinement, HeartSnapshot, ForkPoint, KillEvidence, KillFact, LeashProbe, PauseFact, RequestFact, RequestInput, RequestRecipe, SealFact, SessionFact, Soul, StopFact, TellFact, TellDelivery, TellDeliveryInput, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact, } from "./facts.js";
9
9
  export type { ResumeCoordinate } from "../coordinate.js";
10
- export declare function readSoul(paths: AkumaPaths): Soul | null;
11
- export declare function heartExists(paths: AkumaPaths): boolean;
12
- export declare function readSeal(paths: AkumaPaths): SealFact | null;
13
- export declare function recordBody(paths: AkumaPaths, input: Readonly<{
14
- collar: Collar;
15
- leashTakenAt: string;
16
- }>): BodyFact;
17
- export declare function recordSession(paths: AkumaPaths, input: Omit<SessionFact, "sequence">): SessionFact;
10
+ export declare function readSoul(paths: AkumaPaths): Promise<Soul | null>;
11
+ export declare function heartExists(paths: AkumaPaths): Promise<boolean>;
12
+ export declare function readSeal(paths: AkumaPaths): Promise<SealFact | null>;
13
+ export declare function recordSession(paths: AkumaPaths, input: Omit<SessionFact, "sequence">): Promise<SessionFact>;
18
14
  export declare function appendActivity(paths: AkumaPaths, input: Readonly<{
19
15
  turnSequence: number;
20
16
  event: unknown;
21
17
  at: string;
22
- }>): number;
18
+ }>): Promise<number>;
23
19
  export type ActivitySliceInput = Readonly<{
24
20
  before?: number;
25
21
  since?: number;
@@ -28,63 +24,64 @@ export type ActivitySliceInput = Readonly<{
28
24
  export type ActivitySlice = ActivityFactSlice;
29
25
  export type { ActivityFact };
30
26
  export type { TimelineFact } from "./timeline.js";
31
- export declare function activitySlice(paths: AkumaPaths, input?: ActivitySliceInput): ActivitySlice;
32
- export declare function recordTell(paths: AkumaPaths, tell: Omit<TellFact, "sequence" | "state" | "deliveries">): Readonly<{
27
+ export declare function activitySlice(paths: AkumaPaths, input?: ActivitySliceInput): Promise<ActivitySlice>;
28
+ export declare function recordTell(paths: AkumaPaths, tell: Omit<TellFact, "sequence" | "state" | "deliveries">): Promise<Readonly<{
33
29
  kind: "not-born";
34
30
  } | {
35
31
  kind: "recorded";
36
32
  tell: TellFact;
37
- }>;
38
- export declare function recordTellDeliveries(paths: AkumaPaths, inputs: readonly TellDeliveryInput[]): void;
39
- export declare function recordTellReceipt(paths: AkumaPaths, input: TellReceiptInput): void;
33
+ }>>;
34
+ export declare function recordTellDeliveries(paths: AkumaPaths, inputs: readonly TellDeliveryInput[]): Promise<void>;
35
+ export declare function recordTellReceipt(paths: AkumaPaths, input: TellReceiptInput): Promise<void>;
40
36
  export declare function admitRequest(paths: AkumaPaths, input: RequestInput & Readonly<{
41
37
  admittedAt: string;
42
- }>): RequestFact;
43
- export declare function reserveRequest(paths: AkumaPaths, id: string, child: AkuId): RequestFact;
44
- export declare function serveRequest(paths: AkumaPaths, id: string, child: AkuId): RequestFact;
45
- export declare function refuseRequest(paths: AkumaPaths, id: string, diagnostic: string): RequestFact;
46
- export declare function voidRequest(paths: AkumaPaths, id: string, evidence: string): RequestFact;
47
- export declare function readRequest(paths: AkumaPaths, id: string): RequestFact | null;
48
- export declare function readNonterminalRequests(paths: AkumaPaths): readonly RequestFact[];
49
- export declare function readKill(paths: AkumaPaths, bodySequence: number): KillFact | null;
50
- export declare function requestStop(paths: AkumaPaths, at: string): Readonly<{
38
+ }>): Promise<RequestFact>;
39
+ export declare function reserveRequest(paths: AkumaPaths, id: string, child: AkuId): Promise<RequestFact>;
40
+ export declare function serveRequest(paths: AkumaPaths, id: string, child: AkuId): Promise<RequestFact>;
41
+ export declare function refuseRequest(paths: AkumaPaths, id: string, diagnostic: string): Promise<RequestFact>;
42
+ export declare function voidRequest(paths: AkumaPaths, id: string, evidence: string): Promise<RequestFact>;
43
+ export declare function readRequest(paths: AkumaPaths, id: string): Promise<RequestFact | null>;
44
+ export declare function readNonterminalRequests(paths: AkumaPaths): Promise<readonly RequestFact[]>;
45
+ export declare function readKill(paths: AkumaPaths, bodySequence: number): Promise<KillFact | null>;
46
+ export declare function requestStop(paths: AkumaPaths, at: string): Promise<Readonly<{
51
47
  kind: "requested";
52
48
  body: BodyFact;
53
49
  }> | Readonly<{
54
- kind: "already-killed";
50
+ kind: "already-killed" | "already-stopped";
55
51
  body: BodyFact;
56
- }>;
57
- export declare function requestPause(paths: AkumaPaths, at: string): Readonly<{
52
+ }>>;
53
+ export declare function requestPause(paths: AkumaPaths, at: string): Promise<Readonly<{
58
54
  kind: "not-born";
59
55
  } | {
60
56
  kind: "requested";
61
- }>;
62
- export declare function stopRequested(paths: AkumaPaths, bodySequence?: number): boolean;
63
- export declare function pauseRequested(paths: AkumaPaths): boolean;
57
+ body: BodyFact;
58
+ }>>;
59
+ export declare function stopRequested(paths: AkumaPaths, bodySequence?: number): Promise<boolean>;
60
+ export declare function pauseRequested(paths: AkumaPaths, bodySequence?: number): Promise<boolean>;
64
61
  export declare function breakBody(paths: AkumaPaths, input: Readonly<{
65
62
  sequence: number;
66
63
  end: Exclude<BodyEnd, "exited">;
67
64
  at: string;
68
- }>): void;
65
+ }>): Promise<void>;
69
66
  export declare function beginTurn(paths: AkumaPaths, input: Readonly<{
70
67
  bodySequence: number;
71
68
  startedAt: string;
72
69
  call?: string;
73
- }>): TurnStartFact;
70
+ }>): Promise<TurnStartFact>;
74
71
  export declare function endTurn(paths: AkumaPaths, input: Readonly<{
75
72
  turnSequence: number;
76
73
  outcome: TurnOutcome;
77
74
  completedAt: string;
78
- }>): TurnEndFact;
75
+ }>): Promise<TurnEndFact>;
79
76
  export declare function finishBodyIfIdle(paths: AkumaPaths, input: Readonly<{
80
77
  sequence: number;
81
78
  at: string;
82
- }>): Readonly<{
83
- kind: "finished";
79
+ }>): Promise<Readonly<{
80
+ kind: "controlled" | "finished";
84
81
  } | {
85
82
  kind: "pending";
86
83
  tells: readonly string[];
87
- }>;
88
- export declare function readHeart(paths: AkumaPaths): HeartSnapshot;
89
- export declare function readLastAnsweredTurn(paths: AkumaPaths): TurnFact | null;
90
- export declare function readForkPoint(paths: AkumaPaths, historyId: string): ForkPoint | null;
84
+ }>>;
85
+ export declare function readHeart(paths: AkumaPaths): Promise<HeartSnapshot>;
86
+ export declare function readLastAnsweredTurn(paths: AkumaPaths): Promise<TurnFact | null>;
87
+ export declare function readForkPoint(paths: AkumaPaths, historyId: string): Promise<ForkPoint | null>;
@@ -1,43 +1,57 @@
1
- import { existsSync } from "node:fs";
2
- import { answeredTurnFact, endBodyFact, finishBodyFact, insertActivityFact, insertBodyFact, insertTurnEndFact, insertTurnStartFact, insertPauseControl, insertRequestFact, insertSessionFact, insertStopControl, killFactForBody, latestBodyFact, latestKillFact, latestSessionFact, lastAnsweredTurnFact, nonterminalRequestFacts, pauseExists, requestFact, sessionFactForCoordinate, soulFact, stopFact, updateRequestRefused, updateRequestReserved, updateRequestServed, updateRequestVoided, } from "./rows.js";
1
+ import { answeredTurnFact, endBodyFact, finishBodyFact, insertActivityFact, insertTurnEndFact, insertTurnStartFact, insertPauseControl, insertRequestFact, insertSessionFact, insertStopControl, killFactForBody, latestBodyFact, latestKillFact, latestSessionFact, lastAnsweredTurnFact, nonterminalRequestFacts, pauseFact, requestFact, sessionFactForCoordinate, stopFact, updateRequestRefused, updateRequestReserved, updateRequestServed, updateRequestVoided, } from "./rows.js";
3
2
  import { insertTellDeliveryFact, insertTellFact, insertTellReceiptFact, pendingTellFacts, tellFact, tellIdsForFence, } from "./tells.js";
4
3
  import { activityFactSlice, pruneActivityFacts, } from "./timeline.js";
5
- import { readSealFromLeash, transaction, withHeart } from "./storage.js";
6
- export { HeldAkumaLeash, initializeHeart, probeLeash } from "./storage.js";
7
- export { life } from "./facts.js";
4
+ import { isHeartAbsent, readSealFromLeash, transaction, withHeart } from "./storage.js";
5
+ import { soulFact } from "./soul.js";
6
+ export { HeartAbsentError, HeldAkumaLeash, initializeHeart, isHeartAbsent, probeLeash } from "./storage.js";
7
+ export { life, lifeAt } from "./facts.js";
8
8
  const ACTIVITY_LIMIT = 5_000;
9
- export function readSoul(paths) {
10
- if (!existsSync(paths.heart))
11
- return null;
12
- return withHeart(paths, soulFact);
13
- }
14
- export function heartExists(paths) { return existsSync(paths.heart); }
15
- export function readSeal(paths) {
16
- if (!existsSync(paths.leash))
17
- return null;
18
- return readSealFromLeash(paths);
19
- }
20
- export function recordBody(paths, input) {
21
- return withHeart(paths, (heart) => {
22
- return { sequence: insertBodyFact(heart, input), collar: input.collar, leashTakenAt: input.leashTakenAt };
23
- });
9
+ export async function readSoul(paths) {
10
+ try {
11
+ return await withHeart(paths, soulFact);
12
+ }
13
+ catch (error) {
14
+ if (isHeartAbsent(error))
15
+ return null;
16
+ throw error;
17
+ }
18
+ }
19
+ export async function heartExists(paths) {
20
+ try {
21
+ return await withHeart(paths, () => true);
22
+ }
23
+ catch (error) {
24
+ if (isHeartAbsent(error))
25
+ return false;
26
+ throw error;
27
+ }
28
+ }
29
+ export async function readSeal(paths) {
30
+ try {
31
+ return await readSealFromLeash(paths);
32
+ }
33
+ catch (error) {
34
+ if (isHeartAbsent(error))
35
+ return null;
36
+ throw error;
37
+ }
24
38
  }
25
- export function recordSession(paths, input) {
26
- return withHeart(paths, (heart) => ({ sequence: insertSessionFact(heart, input), ...input }));
39
+ export async function recordSession(paths, input) {
40
+ return await withHeart(paths, (heart) => ({ sequence: insertSessionFact(heart, input), ...input }));
27
41
  }
28
- export function appendActivity(paths, input) {
29
- return withHeart(paths, (heart) => transaction(heart, () => {
42
+ export async function appendActivity(paths, input) {
43
+ return await withHeart(paths, (heart) => transaction(heart, () => {
30
44
  const sequence = insertActivityFact(heart, input);
31
45
  pruneActivityFacts(heart, ACTIVITY_LIMIT);
32
46
  return sequence;
33
47
  }));
34
48
  }
35
- export function activitySlice(paths, input = {}) {
49
+ export async function activitySlice(paths, input = {}) {
36
50
  const limit = input.limit ?? ACTIVITY_LIMIT;
37
- return withHeart(paths, (heart) => activityFactSlice(heart, { ...input, limit }));
51
+ return await withHeart(paths, (heart) => activityFactSlice(heart, { ...input, limit }));
38
52
  }
39
- export function recordTell(paths, tell) {
40
- return withHeart(paths, (heart) => transaction(heart, () => {
53
+ export async function recordTell(paths, tell) {
54
+ return await withHeart(paths, (heart) => transaction(heart, () => {
41
55
  if (soulFact(heart) === null)
42
56
  return { kind: "not-born" };
43
57
  const sequence = insertTellFact(heart, tell);
@@ -45,8 +59,8 @@ export function recordTell(paths, tell) {
45
59
  return { kind: "recorded", tell: { sequence, ...tell, state: "pending", deliveries: [] } };
46
60
  }));
47
61
  }
48
- export function recordTellDeliveries(paths, inputs) {
49
- withHeart(paths, (heart) => transaction(heart, () => {
62
+ export async function recordTellDeliveries(paths, inputs) {
63
+ await withHeart(paths, (heart) => transaction(heart, () => {
50
64
  for (const input of inputs) {
51
65
  const current = tellFact(heart, input.tellId);
52
66
  if (current === null)
@@ -57,8 +71,8 @@ export function recordTellDeliveries(paths, inputs) {
57
71
  pruneActivityFacts(heart, ACTIVITY_LIMIT);
58
72
  }));
59
73
  }
60
- export function recordTellReceipt(paths, input) {
61
- withHeart(paths, (heart) => transaction(heart, () => {
74
+ export async function recordTellReceipt(paths, input) {
75
+ await withHeart(paths, (heart) => transaction(heart, () => {
62
76
  const tellIds = input.evidence === "exact"
63
77
  ? [input.tellId]
64
78
  : tellIdsForFence(heart, input.turnSequence, input.fence);
@@ -76,8 +90,8 @@ function sameRequestInput(fact, input) {
76
90
  && fact.world === input.world
77
91
  && JSON.stringify(fact.recipe) === JSON.stringify(input.recipe);
78
92
  }
79
- export function admitRequest(paths, input) {
80
- return withHeart(paths, (heart) => transaction(heart, () => {
93
+ export async function admitRequest(paths, input) {
94
+ return await withHeart(paths, (heart) => transaction(heart, () => {
81
95
  insertRequestFact(heart, input);
82
96
  const fact = requestFact(heart, input.id);
83
97
  if (fact === null)
@@ -87,8 +101,8 @@ export function admitRequest(paths, input) {
87
101
  return fact;
88
102
  }));
89
103
  }
90
- export function reserveRequest(paths, id, child) {
91
- return withHeart(paths, (heart) => transaction(heart, () => {
104
+ export async function reserveRequest(paths, id, child) {
105
+ return await withHeart(paths, (heart) => transaction(heart, () => {
92
106
  const before = requestFact(heart, id);
93
107
  if (before === null)
94
108
  throw new Error(`unknown Akuma request ${id}`);
@@ -100,8 +114,8 @@ export function reserveRequest(paths, id, child) {
100
114
  return requestFact(heart, id);
101
115
  }));
102
116
  }
103
- export function serveRequest(paths, id, child) {
104
- return withHeart(paths, (heart) => transaction(heart, () => {
117
+ export async function serveRequest(paths, id, child) {
118
+ return await withHeart(paths, (heart) => transaction(heart, () => {
105
119
  const before = requestFact(heart, id);
106
120
  if (before === null)
107
121
  throw new Error(`unknown Akuma request ${id}`);
@@ -113,8 +127,8 @@ export function serveRequest(paths, id, child) {
113
127
  return requestFact(heart, id);
114
128
  }));
115
129
  }
116
- export function refuseRequest(paths, id, diagnostic) {
117
- return withHeart(paths, (heart) => transaction(heart, () => {
130
+ export async function refuseRequest(paths, id, diagnostic) {
131
+ return await withHeart(paths, (heart) => transaction(heart, () => {
118
132
  const before = requestFact(heart, id);
119
133
  if (before === null)
120
134
  throw new Error(`unknown Akuma request ${id}`);
@@ -126,8 +140,8 @@ export function refuseRequest(paths, id, diagnostic) {
126
140
  return requestFact(heart, id);
127
141
  }));
128
142
  }
129
- export function voidRequest(paths, id, evidence) {
130
- return withHeart(paths, (heart) => transaction(heart, () => {
143
+ export async function voidRequest(paths, id, evidence) {
144
+ return await withHeart(paths, (heart) => transaction(heart, () => {
131
145
  const before = requestFact(heart, id);
132
146
  if (before === null)
133
147
  throw new Error(`unknown Akuma request ${id}`);
@@ -139,22 +153,24 @@ export function voidRequest(paths, id, evidence) {
139
153
  return requestFact(heart, id);
140
154
  }));
141
155
  }
142
- export function readRequest(paths, id) {
143
- return withHeart(paths, (heart) => requestFact(heart, id));
156
+ export async function readRequest(paths, id) {
157
+ return await withHeart(paths, (heart) => requestFact(heart, id));
144
158
  }
145
- export function readNonterminalRequests(paths) {
146
- return withHeart(paths, nonterminalRequestFacts);
159
+ export async function readNonterminalRequests(paths) {
160
+ return await withHeart(paths, nonterminalRequestFacts);
147
161
  }
148
- export function readKill(paths, bodySequence) {
149
- return withHeart(paths, (heart) => killFactForBody(heart, bodySequence));
162
+ export async function readKill(paths, bodySequence) {
163
+ return await withHeart(paths, (heart) => killFactForBody(heart, bodySequence));
150
164
  }
151
- export function requestStop(paths, at) {
152
- return withHeart(paths, (heart) => transaction(heart, () => {
165
+ export async function requestStop(paths, at) {
166
+ return await withHeart(paths, (heart) => transaction(heart, () => {
153
167
  const body = latestBodyFact(heart);
154
168
  if (body === null)
155
169
  throw new Error("Akuma has no Body to kill");
156
170
  if (latestKillFact(heart)?.bodySequence === body.sequence)
157
171
  return { kind: "already-killed", body };
172
+ if (body.end !== undefined)
173
+ return { kind: "already-stopped", body };
158
174
  const existing = stopFact(heart);
159
175
  if (existing !== null && existing.bodySequence !== body.sequence) {
160
176
  throw new Error("Akuma stop target is not the latest Body");
@@ -163,40 +179,52 @@ export function requestStop(paths, at) {
163
179
  return { kind: "requested", body };
164
180
  }));
165
181
  }
166
- export function requestPause(paths, at) {
167
- return withHeart(paths, (heart) => transaction(heart, () => {
182
+ export async function requestPause(paths, at) {
183
+ return await withHeart(paths, (heart) => transaction(heart, () => {
168
184
  if (soulFact(heart) === null)
169
185
  return { kind: "not-born" };
186
+ const body = latestBodyFact(heart);
187
+ if (body === null)
188
+ throw new Error("Akuma has no Body to interrupt");
170
189
  insertPauseControl(heart, at);
171
- return { kind: "requested" };
190
+ return { kind: "requested", body };
172
191
  }));
173
192
  }
174
- export function stopRequested(paths, bodySequence) {
175
- return withHeart(paths, (heart) => {
193
+ export async function stopRequested(paths, bodySequence) {
194
+ return await withHeart(paths, (heart) => {
176
195
  const target = stopFact(heart);
177
196
  return target !== null && (bodySequence === undefined || target.bodySequence === bodySequence);
178
197
  });
179
198
  }
180
- export function pauseRequested(paths) { return withHeart(paths, pauseExists); }
181
- export function breakBody(paths, input) {
182
- withHeart(paths, (heart) => endBodyFact(heart, input));
199
+ export async function pauseRequested(paths, bodySequence) {
200
+ return await withHeart(paths, (heart) => {
201
+ const target = pauseFact(heart);
202
+ return target !== null && (bodySequence === undefined || target.bodySequence === bodySequence);
203
+ });
204
+ }
205
+ export async function breakBody(paths, input) {
206
+ await withHeart(paths, (heart) => endBodyFact(heart, input));
183
207
  }
184
- export function beginTurn(paths, input) {
185
- return withHeart(paths, (heart) => transaction(heart, () => {
208
+ export async function beginTurn(paths, input) {
209
+ return await withHeart(paths, (heart) => transaction(heart, () => {
186
210
  const fact = insertTurnStartFact(heart, input);
187
211
  pruneActivityFacts(heart, ACTIVITY_LIMIT);
188
212
  return fact;
189
213
  }));
190
214
  }
191
- export function endTurn(paths, input) {
192
- return withHeart(paths, (heart) => transaction(heart, () => {
215
+ export async function endTurn(paths, input) {
216
+ return await withHeart(paths, (heart) => transaction(heart, () => {
193
217
  const fact = insertTurnEndFact(heart, { kind: "turn-end", ...input });
194
218
  pruneActivityFacts(heart, ACTIVITY_LIMIT);
195
219
  return fact;
196
220
  }));
197
221
  }
198
- export function finishBodyIfIdle(paths, input) {
199
- return withHeart(paths, (heart) => transaction(heart, () => {
222
+ export async function finishBodyIfIdle(paths, input) {
223
+ return await withHeart(paths, (heart) => transaction(heart, () => {
224
+ if (stopFact(heart)?.bodySequence === input.sequence || pauseFact(heart)?.bodySequence === input.sequence) {
225
+ endBodyFact(heart, { ...input, end: "put-down" });
226
+ return { kind: "controlled" };
227
+ }
200
228
  const pending = pendingTellFacts(heart);
201
229
  if (pending.length > 0)
202
230
  return { kind: "pending", tells: pending.map((tell) => tell.id) };
@@ -204,37 +232,50 @@ export function finishBodyIfIdle(paths, input) {
204
232
  return { kind: "finished" };
205
233
  }));
206
234
  }
207
- export function readHeart(paths) {
208
- if (!existsSync(paths.heart)) {
209
- return { soul: null, latestBody: null, latestSession: null, pending: [], latestKill: null };
235
+ export async function readHeart(paths) {
236
+ try {
237
+ return await withHeart(paths, (heart) => ({
238
+ soul: soulFact(heart),
239
+ latestBody: latestBodyFact(heart),
240
+ latestSession: latestSessionFact(heart),
241
+ pending: pendingTellFacts(heart),
242
+ latestKill: latestKillFact(heart),
243
+ stop: stopFact(heart),
244
+ pause: pauseFact(heart),
245
+ }));
246
+ }
247
+ catch (error) {
248
+ if (isHeartAbsent(error)) {
249
+ return { soul: null, latestBody: null, latestSession: null, pending: [], latestKill: null, stop: null, pause: null };
250
+ }
251
+ throw error;
210
252
  }
211
- return withHeart(paths, (heart) => ({
212
- soul: soulFact(heart),
213
- latestBody: latestBodyFact(heart),
214
- latestSession: latestSessionFact(heart),
215
- pending: pendingTellFacts(heart),
216
- latestKill: latestKillFact(heart),
217
- }));
218
253
  }
219
- export function readLastAnsweredTurn(paths) {
220
- return withHeart(paths, lastAnsweredTurnFact);
254
+ export async function readLastAnsweredTurn(paths) {
255
+ return await withHeart(paths, lastAnsweredTurnFact);
221
256
  }
222
- export function readForkPoint(paths, historyId) {
223
- if (!existsSync(paths.heart))
224
- return null;
225
- return withHeart(paths, (heart) => {
226
- const turn = answeredTurnFact(heart, historyId);
227
- if (turn?.end?.outcome.kind !== "answered")
257
+ export async function readForkPoint(paths, historyId) {
258
+ try {
259
+ return await withHeart(paths, (heart) => {
260
+ const turn = answeredTurnFact(heart, historyId);
261
+ const outcome = turn?.end?.outcome;
262
+ if (outcome?.kind !== "answered" || outcome.historyId === undefined)
263
+ return null;
264
+ const recipe = sessionFactForCoordinate(heart, outcome.session);
265
+ if (recipe === null)
266
+ throw new Error(`Akuma fork point ${historyId} has no session recipe`);
267
+ return {
268
+ historyId: outcome.historyId,
269
+ session: outcome.session,
270
+ provider: recipe.provider,
271
+ cwd: recipe.cwd,
272
+ options: recipe.options,
273
+ };
274
+ });
275
+ }
276
+ catch (error) {
277
+ if (isHeartAbsent(error))
228
278
  return null;
229
- const recipe = sessionFactForCoordinate(heart, turn.end.outcome.session);
230
- if (recipe === null)
231
- throw new Error(`Akuma fork point ${historyId} has no session recipe`);
232
- return {
233
- historyId: turn.end.outcome.historyId,
234
- session: turn.end.outcome.session,
235
- provider: recipe.provider,
236
- cwd: recipe.cwd,
237
- options: recipe.options,
238
- };
239
- });
279
+ throw error;
280
+ }
240
281
  }