@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,5 +1,6 @@
1
1
  import { resolveActor } from "./actor.js";
2
2
  import { isParsedAkumaCommand } from "./commands/akuma.js";
3
+ import { invokeContractMutation } from "./commands/contract-invoke.js";
3
4
  import { assertExplicitRepoUse, CliUsageError, renderCommandUsage, } from "./parse.js";
4
5
  import { isBlankInput } from "./usage.js";
5
6
  async function readStdin() {
@@ -11,6 +12,9 @@ async function readStdin() {
11
12
  function selectedStdinDiagnostic(command) {
12
13
  switch (command.command) {
13
14
  case "bind":
15
+ if (command.forkOf !== undefined)
16
+ return undefined;
17
+ return `${command.command} requires a nonblank stdin document`;
14
18
  case "arc":
15
19
  return `${command.command} requires a nonblank stdin document`;
16
20
  case "amend":
@@ -22,12 +26,18 @@ function selectedStdinDiagnostic(command) {
22
26
  return command.prompt.kind === "stdin" ? `${command.command} requires a nonblank prompt` : undefined;
23
27
  case "task":
24
28
  switch (command.stdin) {
25
- case "document": return "task add requires a nonblank stdin document";
26
- case "compose": return "task compose requires a nonblank stdin document";
27
- case "body": return "task update --body requires a nonblank value";
28
- case "append": return "task update --append requires a nonblank value";
29
- case "note": return "task update --note requires a nonblank value";
30
- default: return undefined;
29
+ case "document":
30
+ return "task add requires a nonblank stdin document";
31
+ case "compose":
32
+ return "task compose requires a nonblank stdin document";
33
+ case "body":
34
+ return "task update --body requires a nonblank value";
35
+ case "append":
36
+ return "task update --append requires a nonblank value";
37
+ case "note":
38
+ return "task update --note requires a nonblank value";
39
+ default:
40
+ return undefined;
31
41
  }
32
42
  default:
33
43
  return undefined;
@@ -56,14 +66,6 @@ function consumeSettings(run, ErrorType) {
56
66
  throw error;
57
67
  }
58
68
  }
59
- async function selectedGates(value, names) {
60
- const { gatesFrom, SettingsError } = await import("../library/configuration.js");
61
- return consumeSettings(() => gatesFrom({ settings: value, ...(names === undefined ? {} : { names }) }), SettingsError);
62
- }
63
- async function selectedGitPolicy(value) {
64
- const { requireBranchesToBeUpToDateFrom, SettingsError } = await import("../library/configuration.js");
65
- return consumeSettings(() => requireBranchesToBeUpToDateFrom({ settings: value }), SettingsError);
66
- }
67
69
  function actorFromEdge(actor, environment) {
68
70
  let resolved;
69
71
  try {
@@ -90,156 +92,12 @@ async function selectContract(repo, selector, scope) {
90
92
  const id = resolveContextualContract(await Keiyaku.list({ repo }), selector, scope);
91
93
  return contractFromInput(repo, id);
92
94
  }
93
- async function bindDraftReceipt(establishWorld, markdown) {
94
- const { preserveBindDraft } = await import("./draft.js");
95
- try {
96
- return preserveBindDraft(await establishWorld(), markdown);
97
- }
98
- catch (error) {
99
- return { warning: `bind draft could not be preserved: ${error instanceof Error ? error.message : String(error)}` };
100
- }
101
- }
102
- async function invokeBind({ parsed, repo, edge, configuration, hooks, establishWorld }) {
103
- const markdown = await edge.readStdin();
104
- const gates = await selectedGates(configuration, parsed.gates);
105
- const actor = actorFromEdge(parsed.actor, edge.environment);
106
- const { bindFromCommand } = await import("./commands/bind.js");
107
- const { acceptedBind, resultFromMutationCall } = await import("./accepted.js");
108
- try {
109
- const result = await resultFromMutationCall("bind", () => bindFromCommand({
110
- command: parsed,
111
- repo,
112
- markdown,
113
- gates,
114
- ...(actor === undefined ? {} : { actor }),
115
- hooks,
116
- }), (accepted) => {
117
- const bound = accepted.facts.find((fact) => fact.kind === "bind");
118
- if (bound === undefined || bound.kind !== "bind")
119
- throw new Error("accepted bind is missing its bind fact");
120
- return acceptedBind(accepted, bound.data.coordinates);
121
- });
122
- if (result.kind !== "refused")
123
- return result;
124
- return { ...result, draft: await bindDraftReceipt(establishWorld, markdown) };
125
- }
126
- catch (error) {
127
- if (!(error instanceof TypeError))
128
- throw error;
129
- const { BindDraftError } = await import("./draft.js");
130
- throw new BindDraftError(error, await bindDraftReceipt(establishWorld, markdown));
131
- }
132
- }
133
- function deliverRefusal(refusal) {
134
- if (typeof refusal !== "object" || refusal === null || !("kind" in refusal) || refusal.kind !== "dirty-workspace") {
135
- return refusal;
136
- }
137
- const submodules = "submodules" in refusal && Array.isArray(refusal.submodules) ? refusal.submodules : [];
138
- return { ...refusal, option: { flag: "--include-dirty", available: submodules.length === 0 } };
139
- }
140
- async function invokeDeliver(parsed, seat, requireBranchesToBeUpToDate) {
141
- const { acceptedDeliver } = await import("./accepted.js");
142
- try {
143
- const delivered = await seat.contract.deliver({
144
- ...(seat.actor === undefined ? {} : { actor: seat.actor }),
145
- ...(parsed.message === undefined ? {} : { message: parsed.message }),
146
- requireBranchesToBeUpToDate,
147
- includeDirty: parsed.includeDirty,
148
- materializeConflict: parsed.materializeConflict,
149
- hooks: seat.hooks,
150
- });
151
- if (!("facts" in delivered))
152
- return delivered;
153
- return acceptedDeliver(delivered, seat.id);
154
- }
155
- catch (error) {
156
- const { KeiyakuRefused, KeiyakuRetry } = await import("../library/keiyaku.js");
157
- if (error instanceof KeiyakuRefused) {
158
- return { kind: "refused", verb: "deliver", contract: seat.id, refusal: deliverRefusal(error.refusal) };
159
- }
160
- if (error instanceof KeiyakuRetry) {
161
- return { kind: "retry", verb: "deliver", contract: seat.id, detail: error.reason };
162
- }
163
- throw error;
164
- }
165
- }
166
- async function invokeReview(parsed, seat, readStdin) {
167
- const summary = parsed.summaryFromStdin === true ? await readStdin() : parsed.summary;
168
- const { acceptedReview, resultFromMutationCall } = await import("./accepted.js");
169
- return resultFromMutationCall("review", () => seat.contract.review({
170
- verdict: parsed.verdict,
171
- ...(seat.actor === undefined ? {} : { actor: seat.actor }),
172
- ...(summary === undefined ? {} : { summary }),
173
- hooks: seat.hooks,
174
- }), (result) => acceptedReview(result, seat.id), { coordinate: seat.id });
175
- }
176
- async function invokeAudit(parsed, seat, requireBranchesToBeUpToDate) {
177
- const { acceptedAudit, resultFromMutationCall } = await import("./accepted.js");
178
- return resultFromMutationCall("audit", () => seat.contract.audit({
179
- ...(seat.actor === undefined ? {} : { actor: seat.actor }),
180
- includeDirty: parsed.includeDirty,
181
- showDiff: parsed.showDiff,
182
- requireBranchesToBeUpToDate,
183
- hooks: seat.hooks,
184
- }), (result) => acceptedAudit(result, seat.id), { coordinate: seat.id });
185
- }
186
- async function existingSeat({ parsed, repo, edge, scope, hooks }) {
187
- const { id, contract } = await selectContract(repo, parsed.contract, scope);
188
- const actor = actorFromEdge(parsed.actor, edge.environment);
189
- return { contract, id, ...(actor === undefined ? {} : { actor }), hooks };
190
- }
191
- async function invokeExisting(input) {
192
- const { parsed, repo, edge, configuration, hooks } = input;
193
- const seat = await existingSeat(input);
194
- const { id, contract, actor } = seat;
195
- switch (parsed.command) {
196
- case "amend": {
197
- const markdown = parsed.stdin === true ? await edge.readStdin() : undefined;
198
- const gates = parsed.gates === undefined
199
- ? undefined
200
- : await selectedGates(configuration, parsed.gates);
201
- const { amendFromCommand } = await import("./commands/amend.js");
202
- const { acceptedAmend, resultFromMutationCall } = await import("./accepted.js");
203
- return resultFromMutationCall("amend", () => amendFromCommand({
204
- command: parsed,
205
- repo,
206
- contract,
207
- ...(markdown === undefined ? {} : { markdown }),
208
- gates,
209
- ...(actor === undefined ? {} : { actor }),
210
- hooks,
211
- }), (result) => acceptedAmend(result, id), { coordinate: id });
212
- }
213
- case "deliver":
214
- return invokeDeliver(parsed, seat, await selectedGitPolicy(configuration));
215
- case "review":
216
- return invokeReview(parsed, seat, edge.readStdin);
217
- case "arc": {
218
- const markdown = await edge.readStdin();
219
- const { acceptedArc, resultFromMutationCall } = await import("./accepted.js");
220
- return resultFromMutationCall("arc", () => contract.arc({
221
- markdown,
222
- ...(actor === undefined ? {} : { actor }),
223
- hooks,
224
- }), (result) => acceptedArc(result, id), { coordinate: id });
225
- }
226
- case "abandon": {
227
- const { acceptedAbandon, resultFromMutationCall } = await import("./accepted.js");
228
- return resultFromMutationCall("abandon", () => contract.abandon({
229
- ...(actor === undefined ? {} : { actor }),
230
- ...(parsed.note === undefined ? {} : { note: parsed.note }),
231
- hooks,
232
- }), (result) => acceptedAbandon(result, id), { coordinate: id });
233
- }
234
- case "audit":
235
- return invokeAudit(parsed, seat, await selectedGitPolicy(configuration));
236
- default:
237
- return parsed;
238
- }
239
- }
240
95
  async function invokeAkumaFromEdge(parsed, input) {
241
96
  try {
242
- const { path, statedCwd, repo, home, configuration, edge } = input;
97
+ const { statedCwd, repo, edge } = input;
98
+ const path = await akumaWorldFor(parsed, input.located, input.candidate, input.establish);
99
+ const home = parsed.command === "call" ? input.home : undefined;
100
+ const configuration = parsed.command === "call" ? await settingsAt(path, home) : undefined;
243
101
  if (parsed.command === "call" && parsed.contract !== undefined && repo === undefined) {
244
102
  throw new Error("call with Contract requires a resolved Repo");
245
103
  }
@@ -252,7 +110,7 @@ async function invokeAkumaFromEdge(parsed, input) {
252
110
  ...(statedCwd === undefined ? {} : { statedCwd }),
253
111
  ...(home === undefined ? {} : { home }),
254
112
  ...(configuration === undefined ? {} : { settings: configuration }),
255
- ...(contract === undefined ? repo === undefined ? {} : { repo } : { contract }),
113
+ ...(contract === undefined ? (repo === undefined ? {} : { repo }) : { contract }),
256
114
  readStdin: edge.readStdin,
257
115
  });
258
116
  }
@@ -266,7 +124,7 @@ async function invokeAkumaFromEdge(parsed, input) {
266
124
  }
267
125
  }
268
126
  async function akumaWorldFor(parsed, located, candidate, establish) {
269
- const world = parsed.command === "call" ? candidate ?? await establish() : located;
127
+ const world = parsed.command === "call" ? (candidate ?? (await establish())) : located;
270
128
  if (world === null)
271
129
  throw new CliUsageError("no Keiyaku world contains the invocation cwd");
272
130
  return world;
@@ -323,7 +181,13 @@ async function invokeStatus(parsed, world, repo) {
323
181
  throw new CliUsageError("no Keiyaku world contains the invocation cwd");
324
182
  return (await import("./commands/akuma-invoke.js")).invokeAkumaStatus(world, address.id, parsed.contract, repo);
325
183
  }
326
- return { kind: "status", report: selectKanshi({ report: observation.report, contract: address.id }), selection: "contract" };
184
+ if (repo === undefined)
185
+ throw new CliUsageError("cannot select a contract while the Contract world is absent");
186
+ return {
187
+ kind: "status",
188
+ report: await kanshi({ world, repo, contract: address.id }),
189
+ selection: "contract",
190
+ };
327
191
  }
328
192
  catch (error) {
329
193
  if (error instanceof TypeError)
@@ -359,24 +223,34 @@ async function invokeRegion(parsed, world, repo) {
359
223
  throw error;
360
224
  }
361
225
  };
226
+ if (parsed.paths !== undefined) {
227
+ const report = await read({ kind: "path", patterns: parsed.paths });
228
+ return { kind: "region", region: report.region ?? { kind: "absent" } };
229
+ }
362
230
  if (parsed.contract === undefined) {
363
- const selection = parsed.path !== undefined
364
- ? { kind: "path", path: parsed.path }
365
- : parsed.overlap ? { kind: "overlap" } : { kind: "declarations" };
366
- const report = await read(selection);
231
+ const report = await read({ kind: "declarations" });
367
232
  return { kind: "region", region: report.region ?? { kind: "absent" } };
368
233
  }
369
234
  const report = await read({ kind: "declarations" });
370
235
  const { resolveKanshiContract } = await import("./selectors.js");
371
236
  const contract = resolveKanshiContract(report, parsed.contract);
372
- if (report.contracts.kind !== "present" || report.contracts.value.rows.every((row) => row.id !== contract || row.disposition !== "active")) {
237
+ if (report.contracts.kind !== "present" ||
238
+ report.contracts.value.rows.every((row) => row.id !== contract || row.disposition !== "active")) {
373
239
  throw new CliUsageError(`unknown contract selector: ${parsed.contract}`);
374
240
  }
375
241
  if (report.region?.kind !== "present" || report.region.value.kind !== "declarations") {
376
242
  return { kind: "region", region: report.region ?? { kind: "absent" } };
377
243
  }
378
- const selection = parsed.overlap ? { kind: "overlap", contract } : { kind: "contract", contract };
379
- return { kind: "region", region: { kind: "present", value: selectRegion({ declarations: report.region.value.declarations, selection }) } };
244
+ return {
245
+ kind: "region",
246
+ region: {
247
+ kind: "present",
248
+ value: selectRegion({
249
+ declarations: report.region.value.declarations,
250
+ selection: { kind: "contract", contract },
251
+ }),
252
+ },
253
+ };
380
254
  }
381
255
  async function invokeContractHistory(repo, contract) {
382
256
  if (repo === undefined)
@@ -396,34 +270,45 @@ async function invokeContractHistory(repo, contract) {
396
270
  throw error;
397
271
  }
398
272
  }
399
- // eslint-disable-next-line complexity -- command dispatch keeps the CLI's existing boundary in one place.
400
- async function invokeParsed(invocation, runtime) {
401
- const environment = runtime.environment ?? process.env;
402
- const gitPath = gitPathFromEdge(environment);
273
+ async function invokeForwardedContractMutation(parsed, repo, edge, scope, establishWorld) {
274
+ const { EMPTY_WORKTREE_HOOKS } = await import("../library/configuration.js");
275
+ return invokeContractMutation({
276
+ parsed,
277
+ repo,
278
+ edge,
279
+ scope,
280
+ hooks: EMPTY_WORKTREE_HOOKS,
281
+ establishWorld,
282
+ forwarded: true,
283
+ });
284
+ }
285
+ async function resolveInvocationCoordinates(invocation, runtime) {
286
+ const environment = runtime.environment ?? process.env, gitPath = gitPathFromEdge(environment);
403
287
  const { resolveCliCoordinates } = await import("./coordinates.js");
404
- const coordinates = await resolveCliCoordinates({
288
+ return resolveCliCoordinates({
405
289
  ...(runtime.cwd === undefined ? {} : { processCwd: runtime.cwd }),
406
290
  ...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
407
291
  ...(invocation.repo === undefined ? {} : { repo: invocation.repo }),
408
292
  ...(gitPath === undefined ? {} : { gitPath }),
409
293
  command: invocation.command,
410
294
  });
295
+ }
296
+ // eslint-disable-next-line complexity -- command dispatch keeps the CLI's existing boundary in one place.
297
+ async function invokeParsed(invocation, runtime) {
298
+ const environment = runtime.environment ?? process.env;
299
+ const coordinates = await resolveInvocationCoordinates(invocation, runtime);
411
300
  const { cwd, cwdSource, repo, world, candidateWorld, establishWorld, taskContext } = coordinates;
412
- const edge = {
413
- environment: runtime.environment ?? process.env,
414
- readStdin: runtime.readStdin ?? readStdin,
415
- };
301
+ const edge = { environment, readStdin: runtime.readStdin ?? readStdin };
416
302
  const parsed = invocation.command;
417
303
  const mapped = edge.environment.KEIYAKU_HOME?.trim();
418
304
  const home = mapped === undefined || mapped.length === 0 ? undefined : mapped;
419
- if (parsed.command === "settings") {
305
+ if (parsed.command === "settings")
420
306
  return { kind: "settings", value: await settingsAt(world ?? undefined, home) };
421
- }
422
- if (parsed.command === "nuke") {
307
+ if (parsed.command === "nuke")
423
308
  return await (await import("./commands/nuke.js")).invokeNuke(parsed, world);
424
- }
425
309
  if (parsed.command === "task") {
426
- const actor = runtime.actor ?? actorFromEdge(typeof parsed.flags.actor === "string" ? parsed.flags.actor : undefined, edge.environment);
310
+ const actor = runtime.actor ??
311
+ actorFromEdge(typeof parsed.flags.actor === "string" ? parsed.flags.actor : undefined, edge.environment);
427
312
  return await (await import("./commands/task-invoke.js")).invokeTaskFromEdge({
428
313
  parsed,
429
314
  world,
@@ -436,14 +321,13 @@ async function invokeParsed(invocation, runtime) {
436
321
  if (parsed.command === "history" && "contract" in parsed)
437
322
  return await invokeContractHistory(repo, parsed.contract);
438
323
  if (isParsedAkumaCommand(parsed)) {
439
- const akumaWorld = await akumaWorldFor(parsed, world, candidateWorld, coordinates.establishWorld);
440
- const configuration = parsed.command === "call" ? await settingsAt(akumaWorld, home) : undefined;
441
324
  return await invokeAkumaFromEdge(parsed, {
442
- path: akumaWorld,
325
+ located: world,
326
+ candidate: candidateWorld,
327
+ establish: coordinates.establishWorld,
443
328
  ...(cwdSource === "input" ? { statedCwd: cwd } : {}),
444
329
  ...(repo === undefined ? {} : { repo }),
445
- ...(parsed.command === "call" && home !== undefined ? { home } : {}),
446
- ...(configuration === undefined ? {} : { configuration }),
330
+ ...(home === undefined ? {} : { home }),
447
331
  edge,
448
332
  });
449
333
  }
@@ -456,12 +340,9 @@ async function invokeParsed(invocation, runtime) {
456
340
  if (parsed.command === "region")
457
341
  return invokeRegion(parsed, world, repo);
458
342
  const scope = cwd;
459
- if ((parsed.command === "deliver" || parsed.command === "review") && (await import("../akuma/requests.js")).injectedBodyRequests() !== null) {
460
- const { EMPTY_WORKTREE_HOOKS } = await import("../library/configuration.js");
461
- const seat = await existingSeat({ parsed, repo, edge, scope, hooks: EMPTY_WORKTREE_HOOKS });
462
- return parsed.command === "deliver"
463
- ? await invokeDeliver(parsed, seat, false)
464
- : await invokeReview(parsed, seat, edge.readStdin);
343
+ if ((parsed.command === "deliver" || parsed.command === "review") &&
344
+ (await import("../akuma/requests.js")).injectedBodyRequests() !== null) {
345
+ return invokeForwardedContractMutation(parsed, repo, edge, scope, establishWorld);
465
346
  }
466
347
  const configuration = await settingsAt(world ?? undefined, home);
467
348
  const { worktreeHooksFrom, SettingsError } = await import("../library/configuration.js");
@@ -470,19 +351,22 @@ async function invokeParsed(invocation, runtime) {
470
351
  const selected = await selectContract(repo, parsed.contract, scope);
471
352
  return { kind: "guidance", contract: selected.id, guidance: await selected.contract.guidance() };
472
353
  }
473
- switch (parsed.command) {
474
- case "reconcile": {
475
- if (parsed.contract === undefined) {
476
- return { kind: "observation", command: "reconcile", ...await repo.reconcile({ hooks, retryHooks: parsed.retryHooks }) };
477
- }
478
- const { contract } = await selectContract(repo, parsed.contract, scope);
479
- return { kind: "observation", command: "reconcile", ...await contract.reconcile({ hooks, retryHooks: parsed.retryHooks }) };
354
+ if (parsed.command === "reconcile") {
355
+ if (parsed.contract === undefined) {
356
+ return {
357
+ kind: "observation",
358
+ command: "reconcile",
359
+ report: await repo.reconcile({ hooks, retryHooks: parsed.retryHooks }),
360
+ };
480
361
  }
481
- case "bind":
482
- return invokeBind({ parsed, repo, edge, configuration, hooks, establishWorld });
483
- default:
484
- return invokeExisting({ parsed, repo, edge, scope, configuration, hooks });
362
+ const { contract } = await selectContract(repo, parsed.contract, scope);
363
+ return {
364
+ kind: "observation",
365
+ command: "reconcile",
366
+ ...(await contract.reconcile({ hooks, retryHooks: parsed.retryHooks })),
367
+ };
485
368
  }
369
+ return invokeContractMutation({ parsed, repo, edge, scope, configuration, hooks, establishWorld });
486
370
  }
487
371
  function withResolvedTaskActor(command, runtime) {
488
372
  if (command.command !== "task" || (command.action !== "add" && command.action !== "compose"))
@@ -3,13 +3,15 @@ export async function main(argv = process.argv.slice(2)) {
3
3
  try {
4
4
  const parsed = parseArgv(argv);
5
5
  if ("help" in parsed) {
6
- process.stdout.write(`${renderHelp(parsed.help)}\n`);
6
+ const help = renderHelp(parsed.help);
7
+ process.stdout.write(help.endsWith("\n") ? help : `${help}\n`);
7
8
  return 0;
8
9
  }
9
10
  return await (await import("./runtime.js")).runCliCommand(parsed);
10
11
  }
11
12
  catch (error) {
12
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
13
+ const diagnostic = error instanceof Error ? error.message : String(error);
14
+ process.stderr.write(diagnostic.endsWith("\n") ? diagnostic : `${diagnostic}\n`);
13
15
  return error instanceof CliUsageError ? 1 : 3;
14
16
  }
15
17
  }
@@ -1,101 +1,14 @@
1
1
  import { type ParsedTaskCommand, type TaskAction } from "./commands/task.js";
2
2
  import { type AkumaAction, type ParsedAkumaCommand } from "./commands/akuma.js";
3
- import type { CatalogQuery } from "../library/catalog.js";
4
3
  import { type ParsedInstallCommand } from "./commands/install.js";
5
- import { type ContractCommand as Command } from "./commands/contract.js";
4
+ import { type ContractCommand as Command, type ParsedAbandon, type ParsedAmend, type ParsedArc, type ParsedAudit, type ParsedBind, type ParsedDeliver, type ParsedLs, type ParsedNuke, type ParsedReconcile, type ParsedRegion, type ParsedReview, type ParsedSettings, type ParsedShow, type ParsedStatus } from "./commands/contract.js";
6
5
  export { CliUsageError } from "./usage.js";
6
+ export { renderContractHelp } from "./commands/contract.js";
7
7
  export type { Command };
8
8
  export declare function renderRootHelp(): string;
9
- export declare function renderContractHelp(command: Command): string;
10
9
  export declare function renderCommandUsage(command: ParsedCommand): string;
11
10
  export declare function renderHelp(coordinate: CliHelpCoordinate): string;
12
- type Output = Readonly<{
13
- output: "text" | "json";
14
- }>;
15
- type Actor = Readonly<{
16
- actor?: string;
17
- }>;
18
- export type ParsedBind = Output & Actor & Readonly<{
19
- command: "bind";
20
- task?: string;
21
- target?: string;
22
- workspace?: "here";
23
- after?: readonly string[];
24
- gates?: readonly string[];
25
- }>;
26
- export type ParsedAmend = Output & Actor & Readonly<{
27
- command: "amend";
28
- contract?: string;
29
- after?: readonly string[];
30
- clearAfter?: true;
31
- gates?: readonly string[];
32
- stdin?: true;
33
- }>;
34
- export type ParsedDeliver = Output & Actor & Readonly<{
35
- command: "deliver";
36
- contract?: string;
37
- message?: string;
38
- includeDirty: boolean;
39
- materializeConflict: boolean;
40
- }>;
41
- export type ParsedReview = Output & Actor & Readonly<{
42
- command: "review";
43
- contract?: string;
44
- verdict: "satisfied" | "unsatisfied";
45
- summary?: string;
46
- summaryFromStdin?: true;
47
- }>;
48
- export type ParsedArc = Output & Actor & Readonly<{
49
- command: "arc";
50
- contract?: string;
51
- }>;
52
- export type ParsedAbandon = Output & Actor & Readonly<{
53
- command: "abandon";
54
- contract?: string;
55
- note?: string;
56
- }>;
57
- type ParsedStatus = Output & (Readonly<{
58
- command: "status";
59
- contract?: string;
60
- akuma?: never;
61
- }> | Readonly<{
62
- command: "status";
63
- contract: string;
64
- akuma: true;
65
- }>);
66
- export type ParsedLs = Output & Readonly<{
67
- command: "ls";
68
- query: CatalogQuery;
69
- }>;
70
- export type ParsedAudit = Output & Readonly<{
71
- command: "audit";
72
- contract?: string;
73
- includeDirty: boolean;
74
- showDiff: boolean;
75
- actor?: string;
76
- }>;
77
- type ParsedReconcile = Output & Readonly<{
78
- command: "reconcile";
79
- contract?: string;
80
- retryHooks: boolean;
81
- }>;
82
- export type ParsedNuke = Output & Readonly<{
83
- command: "nuke";
84
- confirm?: string;
85
- }>;
86
- export type ParsedSettings = Output & Readonly<{
87
- command: "settings";
88
- }>;
89
- export type ParsedRegion = Output & Readonly<{
90
- command: "region";
91
- contract?: string;
92
- overlap: boolean;
93
- path?: string;
94
- }>;
95
- export type ParsedCommand = ParsedBind | ParsedAmend | ParsedDeliver | ParsedReview | ParsedArc | ParsedAbandon | ParsedStatus | (Output & Readonly<{
96
- command: "show";
97
- contract?: string;
98
- }>) | ParsedLs | ParsedAudit | ParsedReconcile | ParsedNuke | ParsedSettings | ParsedRegion | ParsedInstallCommand | ParsedAkumaCommand | ParsedTaskCommand;
11
+ export type ParsedCommand = ParsedBind | ParsedAmend | ParsedDeliver | ParsedReview | ParsedArc | ParsedAbandon | ParsedStatus | ParsedShow | ParsedLs | ParsedAudit | ParsedReconcile | ParsedNuke | ParsedSettings | ParsedRegion | ParsedInstallCommand | ParsedAkumaCommand | ParsedTaskCommand;
99
12
  export type CliHelpCoordinate = Readonly<{
100
13
  kind: "root";
101
14
  }> | Readonly<{