@astrosheep/keiyaku 4.1.0 → 4.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
  5. package/build/src/akuma/akuma-errors.d.ts +6 -0
  6. package/build/src/akuma/akuma-errors.js +9 -0
  7. package/build/src/akuma/akuma-handle.d.ts +39 -0
  8. package/build/src/akuma/akuma-handle.js +263 -0
  9. package/build/src/akuma/akuma-observe.d.ts +19 -0
  10. package/build/src/akuma/akuma-observe.js +74 -0
  11. package/build/src/akuma/akuma-product-symbols.d.ts +1 -0
  12. package/build/src/akuma/akuma-product-symbols.js +1 -0
  13. package/build/src/akuma/akuma-product.d.ts +18 -0
  14. package/build/src/akuma/akuma-product.js +154 -0
  15. package/build/src/akuma/akuma.d.ts +37 -81
  16. package/build/src/akuma/akuma.js +39 -447
  17. package/build/src/akuma/allowed.d.ts +1 -0
  18. package/build/src/akuma/allowed.js +6 -0
  19. package/build/src/akuma/archetype.js +8 -5
  20. package/build/src/akuma/body-supervisor.d.ts +26 -0
  21. package/build/src/akuma/body-supervisor.js +89 -0
  22. package/build/src/akuma/body.d.ts +45 -4
  23. package/build/src/akuma/body.js +145 -35
  24. package/build/src/akuma/coordinate.js +17 -7
  25. package/build/src/akuma/heart/facts.js +1 -1
  26. package/build/src/akuma/heart/index.d.ts +1 -1
  27. package/build/src/akuma/heart/index.js +2 -4
  28. package/build/src/akuma/heart/request-authority.js +4 -4
  29. package/build/src/akuma/heart/request-rows.js +27 -16
  30. package/build/src/akuma/heart/rows.js +79 -41
  31. package/build/src/akuma/heart/soul.js +1 -1
  32. package/build/src/akuma/heart/storage.d.ts +1 -0
  33. package/build/src/akuma/heart/storage.js +76 -11
  34. package/build/src/akuma/heart/tells.js +35 -18
  35. package/build/src/akuma/heart/timeline.js +19 -11
  36. package/build/src/akuma/identity.d.ts +1 -0
  37. package/build/src/akuma/identity.js +1 -0
  38. package/build/src/akuma/index.d.ts +3 -3
  39. package/build/src/akuma/index.js +1 -1
  40. package/build/src/akuma/nuke.js +106 -14
  41. package/build/src/akuma/projection-read.d.ts +17 -0
  42. package/build/src/akuma/projection-read.js +135 -0
  43. package/build/src/akuma/projection.d.ts +1 -16
  44. package/build/src/akuma/projection.js +77 -154
  45. package/build/src/akuma/provider-recipe.js +11 -5
  46. package/build/src/akuma/provider.js +105 -62
  47. package/build/src/akuma/providers/acp/config.js +5 -6
  48. package/build/src/akuma/providers/acp/core.js +17 -10
  49. package/build/src/akuma/providers/acp/events.js +38 -29
  50. package/build/src/akuma/providers/acp/index.js +13 -9
  51. package/build/src/akuma/providers/claude/events.js +8 -12
  52. package/build/src/akuma/providers/claude/index.d.ts +1 -0
  53. package/build/src/akuma/providers/claude/index.js +55 -26
  54. package/build/src/akuma/providers/claude/input.js +6 -2
  55. package/build/src/akuma/providers/codex-app-server/events.js +61 -36
  56. package/build/src/akuma/providers/codex-app-server/index.js +25 -13
  57. package/build/src/akuma/providers/grok-build/index.js +22 -25
  58. package/build/src/akuma/providers/index.js +2 -18
  59. package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
  60. package/build/src/akuma/providers/opencode-sdk/index.js +26 -17
  61. package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
  62. package/build/src/akuma/providers/pi/events.js +26 -19
  63. package/build/src/akuma/providers/pi/index.js +58 -40
  64. package/build/src/akuma/publication.js +9 -9
  65. package/build/src/akuma/request-execution.d.ts +6 -0
  66. package/build/src/akuma/request-execution.js +86 -0
  67. package/build/src/akuma/request-serve.d.ts +12 -1
  68. package/build/src/akuma/request-serve.js +19 -122
  69. package/build/src/akuma/request-wire.d.ts +2 -2
  70. package/build/src/akuma/request-wire.js +75 -102
  71. package/build/src/akuma/requests.js +2 -2
  72. package/build/src/akuma/{body-turn.d.ts → turn-drive.d.ts} +2 -25
  73. package/build/src/akuma/{body-turn.js → turn-drive.js} +20 -103
  74. package/build/src/akuma-body.js +6 -5
  75. package/build/src/body/amend.d.ts +4 -1
  76. package/build/src/body/amend.js +14 -6
  77. package/build/src/body/decode.js +2 -4
  78. package/build/src/body/envelope.js +2 -4
  79. package/build/src/body/region.d.ts +1 -2
  80. package/build/src/body/region.js +2 -70
  81. package/build/src/body/render.js +17 -12
  82. package/build/src/body/shape.js +1 -7
  83. package/build/src/cli/accepted.d.ts +1 -1
  84. package/build/src/cli/accepted.js +8 -1
  85. package/build/src/cli/commands/akuma-invoke.js +18 -6
  86. package/build/src/cli/commands/akuma.d.ts +0 -6
  87. package/build/src/cli/commands/akuma.js +11 -24
  88. package/build/src/cli/commands/amend.d.ts +2 -2
  89. package/build/src/cli/commands/amend.js +2 -4
  90. package/build/src/cli/commands/bind.d.ts +4 -4
  91. package/build/src/cli/commands/bind.js +16 -6
  92. package/build/src/cli/commands/contract-invoke.d.ts +25 -0
  93. package/build/src/cli/commands/contract-invoke.js +193 -0
  94. package/build/src/cli/commands/contract.d.ts +109 -10
  95. package/build/src/cli/commands/contract.js +339 -16
  96. package/build/src/cli/commands/install.d.ts +1 -1
  97. package/build/src/cli/commands/install.js +23 -15
  98. package/build/src/cli/commands/task-invoke.js +187 -67
  99. package/build/src/cli/commands/task-query.js +48 -24
  100. package/build/src/cli/commands/task.js +150 -38
  101. package/build/src/cli/coordinates.js +2 -4
  102. package/build/src/cli/invoke.js +92 -208
  103. package/build/src/cli/main.js +4 -2
  104. package/build/src/cli/parse.d.ts +3 -90
  105. package/build/src/cli/parse.js +27 -233
  106. package/build/src/cli/render/akuma-activity.d.ts +38 -0
  107. package/build/src/cli/render/akuma-activity.js +362 -0
  108. package/build/src/cli/render/akuma-tool-command.js +6 -7
  109. package/build/src/cli/render/akuma-tool.js +10 -8
  110. package/build/src/cli/render/akuma.d.ts +1 -1
  111. package/build/src/cli/render/akuma.js +61 -353
  112. package/build/src/cli/render/audit.js +5 -15
  113. package/build/src/cli/render/board.d.ts +1 -0
  114. package/build/src/cli/render/board.js +17 -0
  115. package/build/src/cli/render/catalog.js +81 -8
  116. package/build/src/cli/render/contract-history.d.ts +2 -0
  117. package/build/src/cli/render/contract-history.js +83 -0
  118. package/build/src/cli/render/contract-observation.d.ts +10 -0
  119. package/build/src/cli/render/contract-observation.js +58 -0
  120. package/build/src/cli/render/contract.d.ts +1 -2
  121. package/build/src/cli/render/contract.js +41 -142
  122. package/build/src/cli/render/kanshi.js +239 -215
  123. package/build/src/cli/render/receipt.js +2 -9
  124. package/build/src/cli/render/refusal.js +10 -15
  125. package/build/src/cli/render/region.js +22 -6
  126. package/build/src/cli/render/settings.js +4 -4
  127. package/build/src/cli/render/task.js +34 -14
  128. package/build/src/cli/render/terminal.js +16 -5
  129. package/build/src/cli/result.d.ts +3 -3
  130. package/build/src/cli/runtime.d.ts +6 -1
  131. package/build/src/cli/runtime.js +84 -63
  132. package/build/src/cli/selectors.js +2 -4
  133. package/build/src/cli/usage.js +6 -5
  134. package/build/src/contract-worktree.d.ts +1 -23
  135. package/build/src/contract-worktree.js +79 -155
  136. package/build/src/coordination/durable-file.js +7 -3
  137. package/build/src/coordination/sqlite-transaction-lock.js +29 -12
  138. package/build/src/core/facts/codec.js +7 -3
  139. package/build/src/core/facts/types.d.ts +1 -1
  140. package/build/src/core/subject.js +16 -9
  141. package/build/src/core/verbs/abandon.d.ts +1 -1
  142. package/build/src/core/verbs/abandon.js +1 -1
  143. package/build/src/core/verbs/amend.d.ts +1 -1
  144. package/build/src/core/verbs/amend.js +7 -7
  145. package/build/src/core/verbs/attestation.js +4 -1
  146. package/build/src/core/verbs/bind.d.ts +1 -1
  147. package/build/src/core/verbs/bind.js +1 -1
  148. package/build/src/core/verbs/placement.d.ts +1 -1
  149. package/build/src/core/verbs/placement.js +10 -8
  150. package/build/src/dispatch/index.js +8 -6
  151. package/build/src/duration.js +5 -1
  152. package/build/src/git/admission.js +5 -3
  153. package/build/src/git/hooks.d.ts +8 -0
  154. package/build/src/git/hooks.js +63 -14
  155. package/build/src/git/identity.js +1 -4
  156. package/build/src/git/integration.d.ts +2 -3
  157. package/build/src/git/integration.js +32 -39
  158. package/build/src/git/nuke.d.ts +1 -1
  159. package/build/src/git/nuke.js +110 -57
  160. package/build/src/git/observe.d.ts +13 -1
  161. package/build/src/git/observe.js +51 -44
  162. package/build/src/git/process.js +4 -2
  163. package/build/src/git/read-observation.js +10 -8
  164. package/build/src/git/reconcile.d.ts +22 -2
  165. package/build/src/git/reconcile.js +38 -274
  166. package/build/src/git/repository.d.ts +2 -0
  167. package/build/src/git/repository.js +13 -22
  168. package/build/src/git/scratch.d.ts +8 -5
  169. package/build/src/git/scratch.js +29 -2
  170. package/build/src/git/target-placement.d.ts +9 -10
  171. package/build/src/git/target-placement.js +59 -62
  172. package/build/src/git/tender.js +13 -46
  173. package/build/src/git/terminal-reconcile.d.ts +21 -0
  174. package/build/src/git/terminal-reconcile.js +278 -0
  175. package/build/src/git/terminal-seal.js +15 -12
  176. package/build/src/git/tree.js +5 -2
  177. package/build/src/git/workspace.d.ts +24 -2
  178. package/build/src/git/workspace.js +120 -16
  179. package/build/src/identity/coordinates.js +3 -1
  180. package/build/src/identity/selector.js +6 -3
  181. package/build/src/kanshi/fleet.d.ts +6 -0
  182. package/build/src/kanshi/fleet.js +27 -0
  183. package/build/src/kanshi/index.d.ts +1 -1
  184. package/build/src/kanshi/read.js +60 -48
  185. package/build/src/kanshi/report.d.ts +11 -23
  186. package/build/src/kanshi/select.js +25 -24
  187. package/build/src/library/address.d.ts +2 -1
  188. package/build/src/library/address.js +7 -8
  189. package/build/src/library/akuma-creation.js +20 -12
  190. package/build/src/library/audit.d.ts +0 -1
  191. package/build/src/library/audit.js +1 -2
  192. package/build/src/library/bind.d.ts +53 -5
  193. package/build/src/library/bind.js +98 -22
  194. package/build/src/library/catalog.d.ts +1 -0
  195. package/build/src/library/catalog.js +6 -3
  196. package/build/src/library/configuration.js +3 -1
  197. package/build/src/library/continuation.d.ts +15 -4
  198. package/build/src/library/continuation.js +24 -16
  199. package/build/src/library/contract-bind.d.ts +26 -0
  200. package/build/src/library/contract-bind.js +106 -0
  201. package/build/src/library/contract-operations.d.ts +77 -0
  202. package/build/src/library/contract-operations.js +130 -0
  203. package/build/src/library/contract-types.d.ts +95 -0
  204. package/build/src/library/contract-types.js +1 -0
  205. package/build/src/library/contract.d.ts +19 -154
  206. package/build/src/library/contract.js +46 -261
  207. package/build/src/library/fleet.d.ts +1 -1
  208. package/build/src/library/fleet.js +19 -11
  209. package/build/src/library/input.d.ts +2 -0
  210. package/build/src/library/input.js +14 -0
  211. package/build/src/library/keiyaku.d.ts +8 -7
  212. package/build/src/library/keiyaku.js +3 -3
  213. package/build/src/library/nuke.js +14 -5
  214. package/build/src/library/reconcile.d.ts +9 -4
  215. package/build/src/library/reconcile.js +30 -24
  216. package/build/src/library/refusal.d.ts +13 -5
  217. package/build/src/library/refusal.js +7 -0
  218. package/build/src/library/region.d.ts +8 -7
  219. package/build/src/library/region.js +31 -11
  220. package/build/src/library/repo.js +2 -2
  221. package/build/src/markdown/lex.js +9 -2
  222. package/build/src/markdown/parse.js +11 -7
  223. package/build/src/markdown/query.js +4 -2
  224. package/build/src/protocol/amend.js +3 -1
  225. package/build/src/protocol/attempt.d.ts +7 -3
  226. package/build/src/protocol/attempt.js +9 -5
  227. package/build/src/protocol/audit.d.ts +1 -1
  228. package/build/src/protocol/audit.js +4 -14
  229. package/build/src/protocol/bind.d.ts +19 -6
  230. package/build/src/protocol/bind.js +28 -13
  231. package/build/src/protocol/completion.d.ts +0 -1
  232. package/build/src/protocol/completion.js +1 -3
  233. package/build/src/protocol/deliver.d.ts +1 -3
  234. package/build/src/protocol/deliver.js +15 -39
  235. package/build/src/protocol/intent.d.ts +1 -0
  236. package/build/src/protocol/intent.js +9 -7
  237. package/build/src/protocol/operations.d.ts +3 -7
  238. package/build/src/protocol/operations.js +5 -3
  239. package/build/src/protocol/placement.d.ts +0 -1
  240. package/build/src/protocol/placement.js +6 -6
  241. package/build/src/protocol/read/observation.d.ts +11 -0
  242. package/build/src/protocol/read/observation.js +37 -0
  243. package/build/src/protocol/read/status.d.ts +23 -12
  244. package/build/src/protocol/read/status.js +90 -72
  245. package/build/src/protocol/reconcile.d.ts +1 -0
  246. package/build/src/protocol/reconcile.js +2 -3
  247. package/build/src/protocol/reintegrate.js +1 -1
  248. package/build/src/protocol/review.d.ts +0 -1
  249. package/build/src/protocol/review.js +15 -22
  250. package/build/src/protocol/run.d.ts +1 -0
  251. package/build/src/protocol/run.js +4 -5
  252. package/build/src/runtime/proc/launch.d.ts +33 -0
  253. package/build/src/runtime/proc/launch.js +98 -0
  254. package/build/src/runtime/proc/line-rpc.js +9 -3
  255. package/build/src/runtime/proc/run.d.ts +12 -6
  256. package/build/src/runtime/proc/run.js +78 -21
  257. package/build/src/runtime/proc/stdio.js +7 -10
  258. package/build/src/settings.js +6 -2
  259. package/build/src/settlement/holder.js +13 -10
  260. package/build/src/settlement/settle.js +39 -6
  261. package/build/src/task/board.js +12 -6
  262. package/build/src/task/compose.js +85 -22
  263. package/build/src/task/context.js +21 -8
  264. package/build/src/task/document.js +46 -10
  265. package/build/src/task/identity.js +5 -2
  266. package/build/src/task/index.d.ts +0 -1
  267. package/build/src/task/index.js +119 -34
  268. package/build/src/task/input.js +29 -7
  269. package/build/src/task/mutation.js +61 -19
  270. package/build/src/task/operations.d.ts +6 -1
  271. package/build/src/task/operations.js +83 -29
  272. package/build/src/task/query.js +55 -26
  273. package/build/src/task/store.d.ts +3 -1
  274. package/build/src/task/store.js +81 -17
  275. package/build/src/verification/execution.js +14 -11
  276. package/build/src/workspace-place.js +19 -7
  277. package/build/src/world.js +16 -6
  278. package/package.json +8 -3
@@ -1,90 +1,8 @@
1
1
  import { abortableDelay } from "./abort.js";
2
2
  import { appendActivity, beginTurn, breakBody, heartExists, readHeart, recordSession, recordTellDeliveries, recordTellReceipt, } from "./heart/index.js";
3
- import { encodeAgentEvent, } from "./provider.js";
4
- import { BodyRequestPump, } from "./request-serve.js";
5
- const BODY_CONTROL_OBSERVATION_MS = 100;
6
- export const CONTROL_RESPONSE_MS = 1_000;
7
- export class BodySupervisor {
8
- paths;
9
- bodySequence;
10
- leash;
11
- signal;
12
- controller = new AbortController();
13
- finished = new AbortController();
14
- observer;
15
- waiter;
16
- observation;
17
- stopping;
18
- constructor(paths, bodySequence, leash, observation) {
19
- this.paths = paths;
20
- this.bodySequence = bodySequence;
21
- this.leash = leash;
22
- this.signal = this.controller.signal;
23
- this.observation = observation;
24
- this.observer = this.observe();
25
- }
26
- static async open(paths, bodySequence, leash) {
27
- return new BodySupervisor(paths, bodySequence, leash, await readHeart(paths));
28
- }
29
- get reason() { return this.stopping; }
30
- current() { return this.observation; }
31
- async recordHung(diagnostic, at) {
32
- await this.leash.recordBodyHung(this.paths, { sequence: this.bodySequence, diagnostic, at });
33
- }
34
- async refresh() {
35
- this.publish(await readHeart(this.paths));
36
- return this.observation;
37
- }
38
- next(after) {
39
- if (this.observation !== after)
40
- return Promise.resolve(this.observation);
41
- return new Promise((resolve) => { this.waiter = resolve; });
42
- }
43
- cancel(reason) {
44
- if (this.stopping !== undefined)
45
- return;
46
- this.stopping = reason;
47
- this.controller.abort(new Error(reason === "control"
48
- ? "Akuma Body interrupted by durable control"
49
- : "Akuma Heart disappeared"));
50
- this.waiter?.(this.observation);
51
- this.waiter = undefined;
52
- }
53
- async close() {
54
- this.finished.abort();
55
- await this.observer;
56
- this.waiter = undefined;
57
- }
58
- publish(snapshot) {
59
- this.observation = snapshot;
60
- this.waiter?.(snapshot);
61
- this.waiter = undefined;
62
- }
63
- async observe() {
64
- for (;;) {
65
- const snapshot = this.observation;
66
- if (!await heartExists(this.paths))
67
- return this.cancel("heart-gone");
68
- if (snapshot.stop?.bodySequence === this.bodySequence || snapshot.pause?.bodySequence === this.bodySequence) {
69
- return this.cancel("control");
70
- }
71
- try {
72
- await abortableDelay(BODY_CONTROL_OBSERVATION_MS, this.finished.signal);
73
- }
74
- catch {
75
- return;
76
- }
77
- try {
78
- await this.refresh();
79
- }
80
- catch (error) {
81
- if (await heartExists(this.paths))
82
- throw error;
83
- return this.cancel("heart-gone");
84
- }
85
- }
86
- }
87
- }
3
+ import { encodeAgentEvent } from "./provider.js";
4
+ import { BodyRequestPump } from "./request-serve.js";
5
+ import { CONTROL_RESPONSE_MS } from "./body-supervisor.js";
88
6
  function serializeEffects() {
89
7
  let tail = Promise.resolve();
90
8
  let failed = false;
@@ -119,18 +37,16 @@ async function failedTurnSetup(input, turnSequence, requests, cancelDrive, error
119
37
  try {
120
38
  await requests.close();
121
39
  }
122
- catch { /* Preserve the setup or pump failure. */ }
40
+ catch {
41
+ /* Preserve the setup or pump failure. */
42
+ }
123
43
  input.supervisor.signal.removeEventListener("abort", cancelDrive);
124
44
  if (input.supervisor.signal.aborted) {
125
45
  if (input.supervisor.reason === "heart-gone")
126
46
  throw error;
127
47
  return { kind: "stopped" };
128
48
  }
129
- return {
130
- kind: "failed",
131
- turnSequence,
132
- diagnostic: error instanceof Error ? error.message : String(error),
133
- };
49
+ return { kind: "failed", turnSequence, diagnostic: error instanceof Error ? error.message : String(error) };
134
50
  }
135
51
  async function writeProviderEvent(input, active, event) {
136
52
  if (input.supervisor.signal.aborted)
@@ -145,11 +61,7 @@ async function writeProviderEvent(input, active, event) {
145
61
  admittedAt: at,
146
62
  });
147
63
  }
148
- await appendActivity(input.paths, {
149
- turnSequence: active.turnSequence,
150
- event: encodeAgentEvent(event),
151
- at,
152
- });
64
+ await appendActivity(input.paths, { turnSequence: active.turnSequence, event: encodeAgentEvent(event), at });
153
65
  }
154
66
  async function startTurnDrive(input) {
155
67
  const { cwd, options, session } = await turnRecipe(input.paths, input.soul);
@@ -206,7 +118,7 @@ async function startTurnDrive(input) {
206
118
  }
207
119
  return { kind: "stopped" };
208
120
  }
209
- if (input.launchTells.length > 0) {
121
+ if (input.launchTells.length > 0)
210
122
  await recordTellDeliveries(input.paths, input.launchTells.map((tell) => ({
211
123
  tellId: tell.id,
212
124
  route: "launch",
@@ -214,7 +126,6 @@ async function startTurnDrive(input) {
214
126
  fence: selected.admission.fence,
215
127
  deliveredAt: input.now(),
216
128
  })));
217
- }
218
129
  void selected.completion.then(() => requests.stopAdmission());
219
130
  return {
220
131
  turnSequence: turn.sequence,
@@ -255,7 +166,9 @@ async function retireProviderCustody(input, turnSequence, drive) {
255
166
  at,
256
167
  });
257
168
  }
258
- catch { /* Undisposed provider custody still owns the leash. */ }
169
+ catch {
170
+ /* Undisposed provider custody still owns the leash. */
171
+ }
259
172
  }
260
173
  await breakBody(input.paths, { sequence: input.bodySequence, end: "broke-off", at: input.now() });
261
174
  return { kind: "hung" };
@@ -291,14 +204,16 @@ async function submitPendingLiveTells(writers, pending, attempted, tellLive) {
291
204
  const submission = await tellLive({ id: tell.id, text: tell.body });
292
205
  if (!mayWrite() || submission.kind === "turn-ended")
293
206
  return "turn-ended";
294
- await recordTellDeliveries(input.paths, [{
207
+ await recordTellDeliveries(input.paths, [
208
+ {
295
209
  tellId: tell.id,
296
210
  route: "live",
297
211
  turnSequence,
298
212
  fence: submission.fence,
299
213
  receipt: drive.receipts === undefined ? "unavailable" : "required",
300
214
  deliveredAt: input.now(),
301
- }]);
215
+ },
216
+ ]);
302
217
  return "accepted";
303
218
  });
304
219
  if (outcome === "turn-ended")
@@ -400,7 +315,9 @@ async function consumeTurnDrive(input, active) {
400
315
  try {
401
316
  await requests.close();
402
317
  }
403
- catch { /* Preserve the first pump failure. */ }
318
+ catch {
319
+ /* Preserve the first pump failure. */
320
+ }
404
321
  active.releaseDriveSignal();
405
322
  if (retirement.kind === "hung")
406
323
  return retirement;
@@ -416,7 +333,7 @@ export async function driveTurn(input) {
416
333
  active = started;
417
334
  }
418
335
  catch (error) {
419
- if (!await heartExists(input.paths)) {
336
+ if (!(await heartExists(input.paths))) {
420
337
  input.supervisor.cancel("heart-gone");
421
338
  return { kind: "stopped" };
422
339
  }
@@ -1,8 +1,8 @@
1
- import { runAkumaBody } from "./akuma/body.js";
1
+ import { LEASH_HELD_EXIT, runAkumaBody } from "./akuma/body.js";
2
2
  import { worldRootForAkumaPaths } from "./akuma/identity.js";
3
- import { executeKillAkuma, executeTellAkuma, executeWaitAkuma, } from "./library/fleet.js";
4
- import { requireBranchesToBeUpToDateFrom, worktreeHooksFrom, } from "./library/configuration.js";
5
- import { executeForwardedDeliver, executeForwardedReview, } from "./library/contract.js";
3
+ import { executeKillAkuma, executeTellAkuma, executeWaitAkuma } from "./library/fleet.js";
4
+ import { requireBranchesToBeUpToDateFrom, worktreeHooksFrom } from "./library/configuration.js";
5
+ import { executeForwardedDeliver, executeForwardedReview } from "./library/contract.js";
6
6
  import { Repo } from "./library/repo.js";
7
7
  import { settings } from "./settings.js";
8
8
  import { executeTaskMutation } from "./task/mutation.js";
@@ -95,4 +95,5 @@ const configuration = {
95
95
  ...(mappedHome === undefined || mappedHome.length === 0 ? {} : { home: mappedHome }),
96
96
  ...(mappedGitPath === undefined ? {} : { gitPath: mappedGitPath }),
97
97
  };
98
- await runAkumaBody(launch, upstreamFor(launch, configuration));
98
+ if ((await runAkumaBody(launch, upstreamFor(launch, configuration))) === "held")
99
+ process.exitCode = LEASH_HELD_EXIT;
@@ -1,2 +1,5 @@
1
1
  import type { DecodedContractDocument } from "./types.js";
2
- export declare function applyAmendDocument(source: string, current: DecodedContractDocument): string;
2
+ export declare function applyAmendDocument(source: string, current: DecodedContractDocument): Readonly<{
3
+ document: string;
4
+ changedSections: ReadonlySet<string>;
5
+ }>;
@@ -1,6 +1,6 @@
1
1
  import { decodeVerificationDeclarations, VerificationDocumentError } from "./verification.js";
2
2
  import { parseToAST } from "../markdown/parse.js";
3
- import { directChildren, indexDocument, indexedHeadings, normalizeTitle, rawSlice, sectionContent } from "../markdown/query.js";
3
+ import { directChildren, indexDocument, indexedHeadings, normalizeTitle, rawSlice, sectionContent, } from "../markdown/query.js";
4
4
  import { decodeRegion, RegionDocumentError } from "./region.js";
5
5
  import { contractSectionName, RESERVED_SECTIONS } from "./shape.js";
6
6
  import { renderAmendedContractBody } from "./render.js";
@@ -11,8 +11,7 @@ function nonblank(document, node) {
11
11
  return rawSlice(document, node.span).trim().length > 0;
12
12
  }
13
13
  function sections(document) {
14
- return indexedHeadings(indexDocument(document), { level: 2 })
15
- .filter((node) => node.type === "section");
14
+ return indexedHeadings(indexDocument(document), { level: 2 }).filter((node) => node.type === "section");
16
15
  }
17
16
  function operationSections(document) {
18
17
  if (document.frontmatter !== undefined)
@@ -59,7 +58,10 @@ function criteria(document, section) {
59
58
  if (title.length === 0 || seen.has(key))
60
59
  refusal("criteria operation contains duplicate or empty titles");
61
60
  seen.add(key);
62
- const body = rawSlice(document, { start: heading.span.end, end: headings[index + 1]?.span.start ?? section.span.end });
61
+ const body = rawSlice(document, {
62
+ start: heading.span.end,
63
+ end: headings[index + 1]?.span.start ?? section.span.end,
64
+ });
63
65
  if (body.trim().length === 0)
64
66
  refusal(`criterion '${title}' operation body is empty`);
65
67
  return { title, body };
@@ -201,7 +203,10 @@ function applyAppend(body, operation, document) {
201
203
  if (index < 0)
202
204
  refusal(`unknown extension '${operation.target}'`);
203
205
  const extension = body.extensions[index];
204
- body.extensions[index] = { ...extension, content: appendText(extension.content, prose(document, operation.section, "extension")) };
206
+ body.extensions[index] = {
207
+ ...extension,
208
+ content: appendText(extension.content, prose(document, operation.section, "extension")),
209
+ };
205
210
  }
206
211
  function applyReplace(body, operation, document) {
207
212
  const target = contractSectionName(operation.target);
@@ -276,5 +281,8 @@ function apply(source, current) {
276
281
  }
277
282
  export function applyAmendDocument(source, current) {
278
283
  const result = apply(source, current);
279
- return renderAmendedContractBody(current.document.bytes, result.body, result.changed);
284
+ return {
285
+ document: renderAmendedContractBody(current.document.bytes, result.body, result.changed),
286
+ changedSections: result.changed,
287
+ };
280
288
  }
@@ -1,6 +1,6 @@
1
1
  import { mintDocumentKey, mintDocumentSegmentKey } from "./keys.js";
2
2
  import { decodeDocumentEnvelope } from "./envelope.js";
3
- import { directChildren, normalizeTitle, rawSlice, sectionContent, } from "../markdown/query.js";
3
+ import { directChildren, normalizeTitle, rawSlice, sectionContent } from "../markdown/query.js";
4
4
  import { CONTRACT_SECTIONS, RESERVED_SECTIONS } from "./shape.js";
5
5
  import { decodeRegion, RegionDocumentError } from "./region.js";
6
6
  import { decodeVerificationDeclarations, VerificationDocumentError } from "./verification.js";
@@ -103,9 +103,7 @@ export function decodeContractDocument(source) {
103
103
  ...body,
104
104
  document: { bytes: source, key: mintDocumentKey(source) },
105
105
  segments,
106
- verificationSegment: verificationSection === undefined
107
- ? null
108
- : mintDocumentSegmentKey(document.source, verificationSection.span),
106
+ verificationSegment: verificationSection === undefined ? null : mintDocumentSegmentKey(document.source, verificationSection.span),
109
107
  };
110
108
  }
111
109
  export function verificationDefinition(document) {
@@ -7,15 +7,13 @@ function nonblankRaw(document, node) {
7
7
  return rawSlice(document, node.span).trim().length > 0;
8
8
  }
9
9
  function topLevelSections(document) {
10
- return indexedHeadings(indexDocument(document), { level: 2 })
11
- .filter((node) => node.type === "section");
10
+ return indexedHeadings(indexDocument(document), { level: 2 }).filter((node) => node.type === "section");
12
11
  }
13
12
  export function decodeDocumentEnvelope(source, kind) {
14
13
  const document = parseToAST(source);
15
14
  if (document.frontmatter !== undefined)
16
15
  refusal(`${kind} document may not contain frontmatter`);
17
- const titles = indexedHeadings(indexDocument(document), { level: 1 })
18
- .filter((node) => node.type === "section");
16
+ const titles = indexedHeadings(indexDocument(document), { level: 1 }).filter((node) => node.type === "section");
19
17
  if (titles.length !== 1)
20
18
  refusal(`${kind} document requires exactly one H1 title`);
21
19
  const title = titles[0];
@@ -2,7 +2,6 @@ import type { DocumentNode, SectionNode } from "../markdown/types.js";
2
2
  export declare class RegionDocumentError extends Error {
3
3
  constructor(message: string);
4
4
  }
5
- export declare function assertCanonicalRegionPath(path: string): void;
5
+ export declare function assertRegionPattern(pattern: string): string;
6
6
  export declare function decodeRegion(document: DocumentNode, section: SectionNode): readonly string[];
7
7
  export declare function regionsOverlap(mine: readonly string[], theirs: readonly string[]): readonly [string, string][];
8
- export declare function regionPatternsMatchPath(patterns: readonly string[], path: string): readonly string[];
@@ -39,68 +39,8 @@ function compileRegionPattern(pattern) {
39
39
  const canonical = directory ? [...segments.slice(0, -1), "**"] : segments;
40
40
  return { source, segments: canonical.map((segment) => compileSegment(segment, pattern)) };
41
41
  }
42
- export function assertCanonicalRegionPath(path) {
43
- if (path.length === 0 || /[\r\n\0]/u.test(path) || path.startsWith("/") || path.endsWith("/")) {
44
- refusal(`Region path '${path}' must be a canonical repository-relative path`);
45
- }
46
- if (path.split("/").some((segment) => segment.length === 0 || segment === "." || segment === "..")) {
47
- refusal(`Region path '${path}' must be a canonical repository-relative path`);
48
- }
49
- }
50
- function segmentMatchesPath(pattern, path) {
51
- const queue = [[0, 0]];
52
- const visited = new Set();
53
- let cursor = 0;
54
- while (cursor < queue.length) {
55
- const [patternIndex, pathIndex] = queue[cursor++];
56
- const key = `${patternIndex}:${pathIndex}`;
57
- if (visited.has(key))
58
- continue;
59
- visited.add(key);
60
- if (patternIndex === pattern.length && pathIndex === path.length)
61
- return true;
62
- const character = pattern[patternIndex];
63
- if (character === "*") {
64
- queue.push([patternIndex + 1, pathIndex]);
65
- if (pathIndex < path.length)
66
- queue.push([patternIndex, pathIndex + 1]);
67
- continue;
68
- }
69
- if (character === "?") {
70
- if (pathIndex < path.length)
71
- queue.push([patternIndex + 1, pathIndex + 1]);
72
- continue;
73
- }
74
- if (character !== undefined && character === path[pathIndex])
75
- queue.push([patternIndex + 1, pathIndex + 1]);
76
- }
77
- return false;
78
- }
79
- function patternMatchesPath(pattern, path) {
80
- const queue = [[0, 0]];
81
- const visited = new Set();
82
- let cursor = 0;
83
- while (cursor < queue.length) {
84
- const [patternIndex, pathIndex] = queue[cursor++];
85
- const key = `${patternIndex}:${pathIndex}`;
86
- if (visited.has(key))
87
- continue;
88
- visited.add(key);
89
- if (patternIndex === pattern.length && pathIndex === path.length)
90
- return true;
91
- const segment = pattern[patternIndex];
92
- if (segment?.kind === "deep") {
93
- queue.push([patternIndex + 1, pathIndex]);
94
- if (pathIndex < path.length)
95
- queue.push([patternIndex, pathIndex + 1]);
96
- continue;
97
- }
98
- if (segment === undefined || path[pathIndex] === undefined)
99
- continue;
100
- if (segmentMatchesPath(segment.characters, Array.from(path[pathIndex])))
101
- queue.push([patternIndex + 1, pathIndex + 1]);
102
- }
103
- return false;
42
+ export function assertRegionPattern(pattern) {
43
+ return compileRegionPattern(pattern).source;
104
44
  }
105
45
  function segmentTransition(characters, index) {
106
46
  const character = characters[index];
@@ -199,11 +139,3 @@ export function regionsOverlap(mine, theirs) {
199
139
  }
200
140
  return overlaps;
201
141
  }
202
- export function regionPatternsMatchPath(patterns, path) {
203
- assertCanonicalRegionPath(path);
204
- const pathSegments = path.split("/");
205
- return patterns
206
- .map((pattern) => compileRegionPattern(pattern))
207
- .filter((pattern) => patternMatchesPath(pattern.segments, pathSegments))
208
- .map((pattern) => pattern.source);
209
- }
@@ -38,7 +38,9 @@ function arcSection(arc) {
38
38
  ].join("\n\n");
39
39
  }
40
40
  export function renderContractBody(body, currentArc) {
41
- const criteria = body.criteria.map((criterion) => `### ${criterion.title}\n\n${content(criterion.body)}`).join("\n\n");
41
+ const criteria = body.criteria
42
+ .map((criterion) => `### ${criterion.title}\n\n${content(criterion.body)}`)
43
+ .join("\n\n");
42
44
  const verification = body.verification.map(verificationFence).join("\n\n");
43
45
  return [
44
46
  `# ${body.title}`,
@@ -50,25 +52,28 @@ export function renderContractBody(body, currentArc) {
50
52
  ...(verification.length === 0 ? [] : [section(CONTRACT_SECTIONS.verification.title, verification)]),
51
53
  ...body.extensions.map((extension) => section(extension.title, extension.content)),
52
54
  ...(currentArc === undefined ? [] : [arcSection(currentArc)]),
53
- ].join("\n\n").concat("\n");
55
+ ]
56
+ .join("\n\n")
57
+ .concat("\n");
54
58
  }
55
59
  function sections(document) {
56
- return indexedHeadings(indexDocument(document), { level: 2 })
57
- .filter((node) => node.type === "section");
60
+ return indexedHeadings(indexDocument(document), { level: 2 }).filter((node) => node.type === "section");
58
61
  }
59
62
  export function renderAmendedContractBody(currentSource, body, changedSections) {
60
63
  const current = parseToAST(currentSource);
61
64
  const renderedSource = renderContractBody(body);
62
65
  const rendered = parseToAST(renderedSource);
63
66
  const currentSections = sections(current);
64
- const preserved = new Map(currentSections.map((node) => [
65
- normalizeTitle(node.title),
66
- rawSlice(current, node.span),
67
- ]));
67
+ const preserved = new Map(currentSections.map((node) => [normalizeTitle(node.title), rawSlice(current, node.span)]));
68
68
  const first = currentSections[0];
69
69
  const prefix = first === undefined ? currentSource : currentSource.slice(0, first.span.start);
70
- return prefix + sections(rendered).map((node) => {
71
- const name = normalizeTitle(node.title);
72
- return changedSections.has(name) ? rawSlice(rendered, node.span) : preserved.get(name) ?? rawSlice(rendered, node.span);
73
- }).join("");
70
+ return (prefix +
71
+ sections(rendered)
72
+ .map((node) => {
73
+ const name = normalizeTitle(node.title);
74
+ return changedSections.has(name)
75
+ ? rawSlice(rendered, node.span)
76
+ : (preserved.get(name) ?? rawSlice(rendered, node.span));
77
+ })
78
+ .join(""));
74
79
  }
@@ -6,13 +6,7 @@ export const CONTRACT_SECTIONS = {
6
6
  criteria: { title: "Criteria", required: true },
7
7
  verification: { title: "Verification", required: false },
8
8
  };
9
- export const RESERVED_SECTIONS = new Set([
10
- "gates",
11
- "pipeline",
12
- "after",
13
- "arc",
14
- "fulfillment",
15
- ]);
9
+ export const RESERVED_SECTIONS = new Set(["gates", "pipeline", "after", "arc", "fulfillment"]);
16
10
  export function contractSectionName(title) {
17
11
  for (const name of Object.keys(CONTRACT_SECTIONS)) {
18
12
  if (CONTRACT_SECTIONS[name].title === title)
@@ -6,7 +6,7 @@ type MutationCallOptions = Readonly<{
6
6
  projectRefusal?: (refusal: unknown) => unknown;
7
7
  }>;
8
8
  export declare function acceptedBind(result: BindResult, coordinates: Readonly<{
9
- workspace: "worktree" | "here";
9
+ workspace: "worktree";
10
10
  target?: string;
11
11
  }>): AcceptedBindResult;
12
12
  export declare function acceptedAmend(result: AmendResult, coordinate: ContractId): AcceptedAmendResult;
@@ -27,6 +27,13 @@ function acceptedRegion(result) {
27
27
  return { overlapFailure: result.overlapFailure };
28
28
  return { overlaps: result.overlaps };
29
29
  }
30
+ function acceptedAmendRegion(result) {
31
+ if (result.overlapFailure !== undefined)
32
+ return { overlapFailure: result.overlapFailure };
33
+ if (result.overlaps !== undefined)
34
+ return { overlaps: result.overlaps };
35
+ return {};
36
+ }
30
37
  export function acceptedBind(result, coordinates) {
31
38
  return {
32
39
  ...acceptedEnvelope(result, undefined),
@@ -41,7 +48,7 @@ export function acceptedAmend(result, coordinate) {
41
48
  ...acceptedEnvelope(result, coordinate),
42
49
  verb: "amend",
43
50
  diff: result.documentDiff,
44
- ...acceptedRegion(result),
51
+ ...acceptedAmendRegion(result),
45
52
  };
46
53
  }
47
54
  export function acceptedDeliver(result, coordinate) {
@@ -30,7 +30,14 @@ async function invokeTell(command, input) {
30
30
  ...(input.repo === undefined ? {} : { repo: input.repo }),
31
31
  });
32
32
  const alias = inputAlias(command.akuma);
33
- return { kind: "akuma", action: "tell", mode: "interrupt", result, body, ...(alias === undefined ? {} : { alias }) };
33
+ return {
34
+ kind: "akuma",
35
+ action: "tell",
36
+ mode: "interrupt",
37
+ result,
38
+ body,
39
+ ...(alias === undefined ? {} : { alias }),
40
+ };
34
41
  }
35
42
  const result = await Keiyaku.tell({
36
43
  path: input.path,
@@ -109,11 +116,16 @@ export async function invokeAkuma(command, input) {
109
116
  });
110
117
  return { kind: "akuma", action: "call", result, world: input.path };
111
118
  }
112
- case "wait": return await invokeWait(command, input);
113
- case "tell": return await invokeTell(command, input);
114
- case "history": return await invokeHistory(command, input);
115
- case "fork": return await invokeFork(command, input);
116
- case "kill": return await invokeKill(command, input);
119
+ case "wait":
120
+ return await invokeWait(command, input);
121
+ case "tell":
122
+ return await invokeTell(command, input);
123
+ case "history":
124
+ return await invokeHistory(command, input);
125
+ case "fork":
126
+ return await invokeFork(command, input);
127
+ case "kill":
128
+ return await invokeKill(command, input);
117
129
  }
118
130
  }
119
131
  export async function invokeAkumaStatus(path, akuma, alias, repo) {
@@ -60,11 +60,5 @@ export declare function isParsedAkumaCommand(command: Readonly<{
60
60
  export declare function renderAkumaRootRows(): readonly string[];
61
61
  export declare function renderAkumaHelp(action: AkumaAction): string;
62
62
  export declare function renderAkumaUsage(action: AkumaAction): string;
63
- export declare function parseAkumaCatalogPath(value: string): Readonly<{
64
- kind: "archetypes";
65
- } | {
66
- kind: "akuma";
67
- archetype?: string;
68
- }> | null;
69
63
  export declare function parseAkumaCommand(argv: readonly string[]): ParsedAkumaCommand;
70
64
  export {};
@@ -1,5 +1,5 @@
1
1
  import { CliUsageError, isBlankInput, usageLine } from "../usage.js";
2
- import { archetypeName, parseAkuId } from "../../akuma/identity.js";
2
+ import { parseAkuId } from "../../akuma/identity.js";
3
3
  import { parseDuration as decodeDuration } from "../../duration.js";
4
4
  import { parseAkumaAlias, parseAkumaGlob } from "../../identity/selector.js";
5
5
  import { decodeAllowedActions } from "../../akuma/allowed.js";
@@ -19,12 +19,12 @@ const AKUMA_COMMAND_SPECS = {
19
19
  usage: "call <akuma-name> [--contract <kei/...>] [--alias @name] [--readonly] [--allowed <product.action>]... [--wait <duration> | -d | --detach] (<prompt> | -)",
20
20
  purpose: "Birth an Akuma from <akuma-name> with one prompt.",
21
21
  details: [
22
- "Give <prompt> as one argument, or use final - to read stdin.",
22
+ "Give <prompt> as one argument, or use - to read stdin.",
23
23
  "Default: --wait 5m. An explicit --wait replaces that duration; -d and --detach return after birth.",
24
24
  "--contract dispatches the born Akuma to that Contract.",
25
25
  "--alias assigns the world-local @name selector to the born Akuma.",
26
26
  "--readonly adds the one-way read-only birth restriction.",
27
- "Repeated --allowed replaces the Archetype list; --allowed none selects an empty list.",
27
+ "Repeated --allowed adds actions to the Archetype defaults.",
28
28
  "With --contract, Dispatch succeeds first. If @name exists, the alias then moves.",
29
29
  ].join("\n"),
30
30
  },
@@ -42,7 +42,7 @@ const AKUMA_COMMAND_SPECS = {
42
42
  usage: "tell <aku/...|@alias> [--interrupt] (<prompt> | -)",
43
43
  purpose: "Send one prompt to an existing Akuma and wake it.",
44
44
  details: [
45
- "Give <prompt> as one argument, or use final - to read stdin.",
45
+ "Give <prompt> as one argument, or use - to read stdin.",
46
46
  "--interrupt ends the current Body before recording the prompt and waking its successor.",
47
47
  ].join("\n"),
48
48
  },
@@ -84,16 +84,6 @@ export function renderAkumaHelp(action) {
84
84
  export function renderAkumaUsage(action) {
85
85
  return usageLine(AKUMA_COMMAND_SPECS[action].usage);
86
86
  }
87
- export function parseAkumaCatalogPath(value) {
88
- if (value === "aku" || value === "aku/")
89
- return { kind: "archetypes" };
90
- if (value === "aku/*/*")
91
- return { kind: "akuma" };
92
- const match = /^aku\/([^/]+)\/?$/u.exec(value);
93
- if (match === null)
94
- return null;
95
- return { kind: "akuma", archetype: archetypeName(match[1]) };
96
- }
97
87
  function stringFlag(value, diagnostic, fail) {
98
88
  if (typeof value !== "string")
99
89
  fail(diagnostic);
@@ -127,9 +117,7 @@ function scanNamedOption(input, flags, fail) {
127
117
  }
128
118
  if (isBlankInput(value))
129
119
  fail(`${token} requires a nonblank value`);
130
- flags[name] = kind === "repeatable"
131
- ? [...(Array.isArray(flags[name]) ? flags[name] : []), value]
132
- : value;
120
+ flags[name] = kind === "repeatable" ? [...(Array.isArray(flags[name]) ? flags[name] : []), value] : value;
133
121
  return input.index + 1;
134
122
  }
135
123
  function scanAkuma(action, argv, fail) {
@@ -140,8 +128,10 @@ function scanAkuma(action, argv, fail) {
140
128
  for (let index = 1; index < argv.length; index += 1) {
141
129
  const token = argv[index];
142
130
  if (token === "-") {
143
- if (stdin || index !== argv.length - 1 || !spec.stdin)
131
+ if (!spec.stdin)
144
132
  fail(`stdin marker '-' is not valid for ${action}`);
133
+ if (stdin)
134
+ fail("stdin marker '-' may appear only once");
145
135
  stdin = true;
146
136
  }
147
137
  else if (token === "-d") {
@@ -273,11 +263,6 @@ function parseAllowedFlag(raw, fail) {
273
263
  if (!Array.isArray(raw))
274
264
  fail("--allowed requires a value");
275
265
  const selected = raw;
276
- if (selected.includes("none")) {
277
- if (selected.length !== 1)
278
- fail("--allowed none cannot be combined with another value");
279
- return [];
280
- }
281
266
  try {
282
267
  return decodeAllowedActions(selected, "--allowed");
283
268
  }
@@ -319,7 +304,9 @@ export function parseAkumaCommand(argv) {
319
304
  throw new CliUsageError(`unknown command: ${candidate ?? ""}`);
320
305
  const action = candidate;
321
306
  const spec = AKUMA_COMMAND_SPECS[action];
322
- const fail = (message) => { throw new CliUsageError(message, renderAkumaUsage(action)); };
307
+ const fail = (message) => {
308
+ throw new CliUsageError(message, renderAkumaUsage(action));
309
+ };
323
310
  const { flags, positionals, stdin } = scanAkuma(action, argv, fail);
324
311
  const output = flags.json === true ? "json" : "text";
325
312
  if (action === "call" || action === "tell") {
@@ -1,5 +1,5 @@
1
1
  import { type ActorId, type Gate, type Keiyaku, type Repo, type WorktreeHooks } from "../../index.js";
2
- import type { ParsedAmend } from "../parse.js";
2
+ import type { ParsedAmend } from "./contract.js";
3
3
  type AmendCommandInput = Readonly<{
4
4
  command: ParsedAmend;
5
5
  repo: Repo;
@@ -9,5 +9,5 @@ type AmendCommandInput = Readonly<{
9
9
  actor?: ActorId;
10
10
  hooks?: WorktreeHooks;
11
11
  }>;
12
- export declare function amendFromCommand({ command, repo, contract, markdown, gates, actor, hooks }: AmendCommandInput): ReturnType<Keiyaku["amend"]>;
12
+ export declare function amendFromCommand({ command, repo, contract, markdown, gates, actor, hooks, }: AmendCommandInput): ReturnType<Keiyaku["amend"]>;
13
13
  export {};