@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
@@ -22,7 +22,8 @@ function refusalIdentity(refusal, addressed) {
22
22
  }
23
23
  function refusalHead(kind, identity, details) {
24
24
  return [kind, identity === undefined ? undefined : `contractId=${identity}`, ...details]
25
- .filter((part) => part !== undefined).join(" ");
25
+ .filter((part) => part !== undefined)
26
+ .join(" ");
26
27
  }
27
28
  function renderDirtyRefusal(refusal, indent, columns, identity) {
28
29
  const lines = [];
@@ -71,28 +72,22 @@ export function renderRefusalFacts(refusal, indent, columns, addressed) {
71
72
  return lines;
72
73
  }
73
74
  if (refusal.kind === "merge-state-present") {
74
- return renderOpaqueBlock(refusalHead(refusal.kind, identity, [
75
- `workspace=${refusal.workspace.kind}`,
76
- `path=${refusal.workspace.path}`,
77
- ]), indent, columns);
75
+ return renderOpaqueBlock(refusalHead(refusal.kind, identity, [`workspace=${refusal.workspace.kind}`, `path=${refusal.workspace.path}`]), indent, columns);
78
76
  }
79
77
  if (refusal.kind === "integration-unsupported") {
80
78
  return renderOpaqueBlock(refusalHead(refusal.kind, identity, [`requiredGit=${refusal.requiredGit}`]), indent, columns);
81
79
  }
82
80
  if (refusal.kind === "checkout-not-followable") {
83
- const lines = [...renderOpaqueBlock(refusalHead(refusal.kind, identity, [`target=${refusal.target}`, `path=${refusal.path}`, `reason=${refusal.reason}`]), indent, columns)];
81
+ const lines = [
82
+ ...renderOpaqueBlock(refusalHead(refusal.kind, identity, [
83
+ `target=${refusal.target}`,
84
+ `path=${refusal.path}`,
85
+ `reason=${refusal.reason}`,
86
+ ]), indent, columns),
87
+ ];
84
88
  lines.push(...collectionLines("paths", refusal.paths, indent, columns));
85
89
  return lines;
86
90
  }
87
- if (refusal.kind === "workspace-not-on-target") {
88
- return renderOpaqueBlock(refusalHead(refusal.kind, identity, [`target=${refusal.target}`, `branch=${refusal.branch}`]), indent, columns);
89
- }
90
- if (refusal.kind === "here-target-mismatch") {
91
- return renderOpaqueBlock(`here-target-mismatch target=${refusal.target} branch=${refusal.branch}`, indent, columns);
92
- }
93
- if (refusal.kind === "here-worktree-appointed") {
94
- return renderOpaqueBlock(refusalHead(refusal.kind, undefined, [refusal.contract === undefined ? "" : `contract=${refusal.contract}`, `path=${refusal.path}`]), indent, columns);
95
- }
96
91
  return renderOpaqueBlock(refusalHead(refusal.kind, identity, []), indent, columns);
97
92
  }
98
93
  export function renderRefusal(result, context) {
@@ -1,16 +1,32 @@
1
+ function overlapBlocks(overlaps) {
2
+ return overlaps.flatMap((overlap) => {
3
+ const count = overlap.patterns.length;
4
+ return [
5
+ `overlap ${overlap.contract} ${count} ${count === 1 ? "pair" : "pairs"}`,
6
+ ...overlap.patterns.map((pattern) => ` ${pattern.mine} ~ ${pattern.theirs}`),
7
+ ];
8
+ });
9
+ }
1
10
  function rows(section) {
2
11
  if (section.kind === "absent")
3
12
  return [];
4
13
  if (section.kind === "failed")
5
14
  return [`region failed ${section.failure.message}`];
6
15
  const value = section.value;
7
- if (value.kind === "declarations")
16
+ if (value.kind === "declarations") {
17
+ if (value.declarations.length === 0)
18
+ return ["no active Region declarations"];
8
19
  return value.declarations.map((declaration) => `region ${declaration.contract} ${declaration.patterns.join(" ")}`);
9
- if (value.kind === "contract")
10
- return [`region ${value.declaration.contract} ${value.declaration.patterns.join(" ")}`];
11
- if (value.kind === "path")
12
- return value.matches.map((match) => `path ${value.path} ${match.contract} ${match.pattern}`);
13
- return value.intersections.flatMap((intersection) => intersection.patterns.map((pattern) => `overlap ${intersection.left} ${pattern.left} ~ ${intersection.right} ${pattern.right}`));
20
+ }
21
+ if (value.kind === "contract") {
22
+ const header = `region ${value.declaration.contract} ${value.declaration.patterns.join(" ")}`;
23
+ if (value.overlaps.length === 0)
24
+ return [header, "no overlap with active declarations"];
25
+ return [header, ...overlapBlocks(value.overlaps)];
26
+ }
27
+ if (value.overlaps.length === 0)
28
+ return [`no active Region declares: ${value.patterns.join(" ")}`];
29
+ return [...overlapBlocks(value.overlaps)];
14
30
  }
15
31
  export function renderRegionText(section) {
16
32
  return rows(section).join("\n");
@@ -1,11 +1,11 @@
1
1
  function namespaceNames(value) {
2
- return [...new Set([value.scopes.user, value.scopes.project].flatMap((scope) => scope.kind === "read" ? scope.namespaces : []))].sort();
2
+ return [
3
+ ...new Set([value.scopes.user, value.scopes.project].flatMap((scope) => (scope.kind === "read" ? scope.namespaces : []))),
4
+ ].sort();
3
5
  }
4
6
  function scope(name, value) {
5
7
  const path = value.path === undefined ? "" : ` ${value.path}`;
6
- return value.kind === "failed"
7
- ? `${name} failed${path} ${value.diagnostic}`
8
- : `${name} ${value.kind}${path}`;
8
+ return value.kind === "failed" ? `${name} failed${path} ${value.diagnostic}` : `${name} ${value.kind}${path}`;
9
9
  }
10
10
  export function settingsJsonValue(value) {
11
11
  return {
@@ -2,9 +2,10 @@ import { outcomeLines, receiptPayload } from "./receipt.js";
2
2
  import { displayColumns, renderTextBlock, safeText } from "./terminal.js";
3
3
  const DEFAULT_CONTEXT = { columns: 80, color: false };
4
4
  function isWorldObservation(result) {
5
- return typeof result === "object" && result !== null
6
- && "kind" in result
7
- && (result.kind === "present" || result.kind === "absent" || result.kind === "failed");
5
+ return (typeof result === "object" &&
6
+ result !== null &&
7
+ "kind" in result &&
8
+ (result.kind === "present" || result.kind === "absent" || result.kind === "failed"));
8
9
  }
9
10
  function markFor(word) {
10
11
  if (word === "in_progress")
@@ -25,7 +26,9 @@ function priorityText(priority) {
25
26
  return priority === null ? "P?" : `P${priority}`;
26
27
  }
27
28
  function scanUnit(id, priority, word) {
28
- return word === undefined ? `${markFor("ready")} ${id} · ${priorityText(priority)}` : `${markFor(word)} ${id} · ${priorityText(priority)} ${word}`;
29
+ return word === undefined
30
+ ? `${markFor("ready")} ${id} · ${priorityText(priority)}`
31
+ : `${markFor(word)} ${id} · ${priorityText(priority)} ${word}`;
29
32
  }
30
33
  function entityLines(entity, columns, indent = "") {
31
34
  const scan = `${indent}${scanUnit(entity.id, entity.priority, entity.word)}${entity.facts === undefined ? "" : ` · ${entity.facts}`}`;
@@ -38,7 +41,12 @@ function entityLines(entity, columns, indent = "") {
38
41
  return [`${scan} —`, ...renderTextBlock(title, `${indent} `, columns)];
39
42
  }
40
43
  function stateEntity(task) {
41
- return { id: task.id, priority: "priority" in task && task.priority !== undefined ? task.priority : null, word: task.state, title: task.title };
44
+ return {
45
+ id: task.id,
46
+ priority: "priority" in task && task.priority !== undefined ? task.priority : null,
47
+ word: task.state,
48
+ title: task.title,
49
+ };
42
50
  }
43
51
  function projectRefusal(refusal) {
44
52
  if (refusal.kind === "task-missing")
@@ -110,7 +118,9 @@ function renderListRow(item, columns, omitDisposition) {
110
118
  }
111
119
  return lines;
112
120
  }
113
- function shellQuote(value) { return `'${value.replaceAll("'", "'\\''")}'`; }
121
+ function shellQuote(value) {
122
+ return `'${value.replaceAll("'", "'\\''")}'`;
123
+ }
114
124
  function recoveryCommand(command, total) {
115
125
  const parts = ["keiyaku", "task", command.action];
116
126
  if (command.action === "ls") {
@@ -136,9 +146,17 @@ function renderRows(command, result, columns) {
136
146
  return renderFailure(command.action, result, columns);
137
147
  const view = command.action === "ls" ? "tasks" : command.action;
138
148
  const footer = result.value.truncated
139
- ? ["", ` + ${result.value.total - result.value.returned} more not shown`, ` ${recoveryCommand(command, result.value.total)}`]
149
+ ? [
150
+ "",
151
+ ` + ${result.value.total - result.value.returned} more not shown`,
152
+ ` ${recoveryCommand(command, result.value.total)}`,
153
+ ]
140
154
  : [];
141
- return [pageHeading(view, result.value), ...result.value.rows.flatMap((item) => renderListRow(item, columns, command.action === "ready")), ...footer].join("\n");
155
+ return [
156
+ pageHeading(view, result.value),
157
+ ...result.value.rows.flatMap((item) => renderListRow(item, columns, command.action === "ready")),
158
+ ...footer,
159
+ ].join("\n");
142
160
  }
143
161
  function renderShowDetail(result, columns) {
144
162
  const task = result.task;
@@ -199,10 +217,7 @@ function renderDoctor(report) {
199
217
  return [`${report.issues.length} ${noun}`, ...report.issues.map(doctorIssue)].join("\n");
200
218
  }
201
219
  function renderAcceptedMutation(verb, task, columns, documentDiff) {
202
- const lines = [
203
- ...outcomeLines("✓", verb, "accepted", task.id, columns),
204
- ...entityLines(stateEntity(task), columns),
205
- ];
220
+ const lines = [...outcomeLines("✓", verb, "accepted", task.id, columns), ...entityLines(stateEntity(task), columns)];
206
221
  if (documentDiff !== undefined)
207
222
  receiptPayload(lines, "diff", documentDiff);
208
223
  return lines.join("\n");
@@ -266,12 +281,17 @@ export function renderTaskText(command, result, context = DEFAULT_CONTEXT) {
266
281
  function renderTaskValue(command, result, columns) {
267
282
  if (command.action === "show")
268
283
  return renderShow(result, columns);
269
- if (command.action === "ls" || command.action === "ready" || command.action === "blocked" || command.action === "query") {
284
+ if (command.action === "ls" ||
285
+ command.action === "ready" ||
286
+ command.action === "blocked" ||
287
+ command.action === "query") {
270
288
  return renderRows(command, result, columns);
271
289
  }
272
290
  if (command.action === "tree") {
273
291
  const tree = result;
274
- return tree.kind === "accepted" ? treeLines(tree.value, columns).join("\n") : renderFailure(command.action, tree, columns);
292
+ return tree.kind === "accepted"
293
+ ? treeLines(tree.value, columns).join("\n")
294
+ : renderFailure(command.action, tree, columns);
275
295
  }
276
296
  if (command.action === "doctor")
277
297
  return renderDoctor(result);
@@ -13,9 +13,17 @@ export function gitShortStat(stat) {
13
13
  }
14
14
  const GRAPHEMES = new Intl.Segmenter("und", { granularity: "grapheme" });
15
15
  const WIDE_RANGES = [
16
- [0x1100, 0x115f], [0x2329, 0x232a], [0x2e80, 0xa4cf], [0xac00, 0xd7a3],
17
- [0xf900, 0xfaff], [0xfe10, 0xfe19], [0xfe30, 0xfe6f], [0xff00, 0xff60],
18
- [0xffe0, 0xffe6], [0x1f300, 0x1faff], [0x20000, 0x3fffd],
16
+ [0x1100, 0x115f],
17
+ [0x2329, 0x232a],
18
+ [0x2e80, 0xa4cf],
19
+ [0xac00, 0xd7a3],
20
+ [0xf900, 0xfaff],
21
+ [0xfe10, 0xfe19],
22
+ [0xfe30, 0xfe6f],
23
+ [0xff00, 0xff60],
24
+ [0xffe0, 0xffe6],
25
+ [0x1f300, 0x1faff],
26
+ [0x20000, 0x3fffd],
19
27
  ];
20
28
  function characterColumns(character) {
21
29
  const point = character.codePointAt(0);
@@ -108,10 +116,13 @@ export function renderBoundedTextBlock(value, input) {
108
116
  return lines.length === 0 ? [input.first.trimEnd()] : lines;
109
117
  }
110
118
  export function safeText(value) {
111
- return value.replaceAll(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu, (character) => /\s/u.test(character) ? " " : "�");
119
+ return value.replaceAll(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu, (character) => (/\s/u.test(character) ? " " : "�"));
112
120
  }
113
121
  export function renderTextBlock(value, indent, columns) {
114
- const words = safeText(value).trim().split(/\s+/u).filter((word) => word.length > 0);
122
+ const words = safeText(value)
123
+ .trim()
124
+ .split(/\s+/u)
125
+ .filter((word) => word.length > 0);
115
126
  if (words.length === 0)
116
127
  return [indent];
117
128
  const lines = [];
@@ -2,7 +2,7 @@ import type { AuditReport, ContractHistory, ContractId, ContinuationReport, Deli
2
2
  import type { KanshiReport } from "../kanshi/index.js";
3
3
  import type { RegionRead, Section } from "../kanshi/index.js";
4
4
  import type { Catalog } from "../index.js";
5
- import type { RegionObservation } from "../library/region.js";
5
+ import type { AmendRegionObservation, RegionObservation } from "../library/region.js";
6
6
  import type { NukeResult } from "../index.js";
7
7
  export type BindDraftReceipt = Readonly<{
8
8
  path: string;
@@ -38,7 +38,7 @@ export type AcceptedEnvelope = Readonly<{
38
38
  }>;
39
39
  export type AcceptedBindResult = AcceptedEnvelope & Readonly<{
40
40
  verb: "bind";
41
- workspace: "worktree" | "here";
41
+ workspace: "worktree";
42
42
  target: string | null;
43
43
  completion?: never;
44
44
  verification?: never;
@@ -73,7 +73,7 @@ export type AcceptedAmendResult = AcceptedEnvelope & Readonly<{
73
73
  verdict?: never;
74
74
  chapter?: never;
75
75
  note?: never;
76
- }> & RegionObservation;
76
+ }> & AmendRegionObservation;
77
77
  export type AcceptedDeliverResult = AcceptedEnvelope & Readonly<{
78
78
  verb: "deliver";
79
79
  completion?: Delivery["completion"];
@@ -1,2 +1,7 @@
1
- import type { ParsedExecution } from "./parse.js";
1
+ import type { TaskInvocationResult } from "./commands/task-invoke.js";
2
+ import type { ParsedCommand, ParsedExecution } from "./parse.js";
3
+ export declare function invocationStart(command: ParsedCommand): string | undefined;
4
+ export declare function writeTask(command: Extract<ParsedCommand, {
5
+ command: "task";
6
+ }>, result: TaskInvocationResult): Promise<number>;
2
7
  export declare function runCliCommand(invocation: ParsedExecution): Promise<number>;
@@ -1,6 +1,6 @@
1
1
  import { isParsedAkumaCommand } from "./commands/akuma.js";
2
2
  import { CliUsageError } from "./parse.js";
3
- function invocationStart(command) {
3
+ export function invocationStart(command) {
4
4
  if (command.output === "json")
5
5
  return undefined;
6
6
  if (command.command === "bind")
@@ -13,39 +13,90 @@ function invocationStart(command) {
13
13
  return "⧖ reconciling";
14
14
  return command.command === "install" ? "⧖ installing skills" : undefined;
15
15
  }
16
- async function writeTask(command, result) {
16
+ function writeCliStream(stream, body) {
17
+ stream.write(body.endsWith("\n") ? body : `${body}\n`);
18
+ }
19
+ export async function writeTask(command, result) {
17
20
  const { renderTaskIncompleteDiagnostic, renderTaskText, taskExitCode } = await import("./render/task.js");
18
21
  const context = {
19
22
  columns: process.stdout.isTTY === true && Number.isInteger(process.stdout.columns) ? process.stdout.columns : 80,
20
23
  color: false,
21
24
  };
22
25
  if (command.output === "json")
23
- process.stdout.write(`${JSON.stringify(result)}\n`);
24
- else if (command.action === "compose" && typeof result === "object" && result !== null && "kind" in result && result.kind === "incomplete") {
26
+ writeCliStream(process.stdout, JSON.stringify(result));
27
+ else if (command.action === "compose" &&
28
+ typeof result === "object" &&
29
+ result !== null &&
30
+ "kind" in result &&
31
+ result.kind === "incomplete") {
25
32
  const diagnostic = renderTaskIncompleteDiagnostic(result);
26
33
  if (diagnostic.length > 0)
27
- process.stderr.write(`${diagnostic}\n`);
34
+ writeCliStream(process.stderr, diagnostic);
28
35
  process.stdout.write(result.draft);
29
36
  }
30
37
  else
31
- process.stdout.write(`${renderTaskText(command, result, context)}\n`);
38
+ writeCliStream(process.stdout, renderTaskText(command, result, context));
32
39
  return taskExitCode(result);
33
40
  }
34
- async function writeAkuma(command, result) {
35
- const { renderAkumaJson, akumaExitCode, akumaRawAnswer, renderAkumaText } = await import("./render/akuma.js");
36
- const output = command.output === "json" ? renderAkumaJson(result) : renderAkumaText(command, result, {
41
+ function displayContext() {
42
+ return {
37
43
  columns: process.stdout.isTTY === true && Number.isInteger(process.stdout.columns) ? process.stdout.columns : 80,
38
44
  color: process.stdout.isTTY === true && process.env.NO_COLOR === undefined,
39
- });
40
- const raw = command.output === "text" && ((command.command === "history" && command.last) || akumaRawAnswer(result) !== undefined);
41
- process.stdout.write(raw ? output : `${output}\n`);
45
+ };
46
+ }
47
+ async function writeAkuma(command, result) {
48
+ const { renderAkumaJson, akumaExitCode, akumaRawAnswer, renderAkumaText } = await import("./render/akuma.js");
49
+ const output = command.output === "json" ? renderAkumaJson(result) : renderAkumaText(command, result, displayContext());
50
+ const exact = command.output === "text" &&
51
+ (akumaRawAnswer(result) !== undefined ||
52
+ (command.command === "history" && command.last && result.action === "history" && result.mode === "last"));
53
+ if (exact)
54
+ process.stdout.write(output);
55
+ else
56
+ writeCliStream(process.stdout, output);
42
57
  return akumaExitCode(result);
43
58
  }
59
+ function isAkumaOutput(command, result) {
60
+ if (isParsedAkumaCommand(command))
61
+ return true;
62
+ return (command.command === "status" &&
63
+ typeof result === "object" &&
64
+ result !== null &&
65
+ "kind" in result &&
66
+ result.kind === "akuma");
67
+ }
68
+ function invocationJson(result) {
69
+ switch (result.kind) {
70
+ case "guidance":
71
+ return { contract: result.contract, guidance: result.guidance };
72
+ case "catalog":
73
+ return result.catalog;
74
+ case "nuke":
75
+ return result.result;
76
+ case "region":
77
+ return result.region;
78
+ case "contract-history":
79
+ return result.history;
80
+ case "status":
81
+ return result.report;
82
+ default:
83
+ return result;
84
+ }
85
+ }
86
+ async function invocationExitCode(result) {
87
+ if (result.kind === "nuke")
88
+ return (await import("./render/nuke.js")).nukeExitCode(result.result);
89
+ if (result.kind === "observation") {
90
+ const { worldObservationFailureText } = await import("./render/board.js");
91
+ return worldObservationFailureText(result) === undefined ? 0 : 1;
92
+ }
93
+ return result.kind === "refused" ? 1 : result.kind === "retry" ? 2 : 0;
94
+ }
44
95
  async function writeResult(command, result) {
45
96
  if (command.command === "install") {
46
97
  const { installExitCode, renderInstallText } = await import("./commands/install.js");
47
98
  const value = result;
48
- process.stdout.write(`${command.output === "json" ? JSON.stringify(value) : renderInstallText(value)}\n`);
99
+ writeCliStream(process.stdout, command.output === "json" ? JSON.stringify(value) : renderInstallText(value));
49
100
  return installExitCode(value);
50
101
  }
51
102
  if (command.command === "task")
@@ -53,59 +104,23 @@ async function writeResult(command, result) {
53
104
  if (command.command === "settings") {
54
105
  const { renderSettingsText, settingsJsonValue } = await import("./render/settings.js");
55
106
  const value = result.value;
56
- process.stdout.write(`${command.output === "json" ? JSON.stringify(settingsJsonValue(value)) : renderSettingsText(value)}\n`);
57
- return 0;
58
- }
59
- if (typeof result === "object" && result !== null && "kind" in result && result.kind === "contract-history") {
60
- const { renderText } = await import("./render/text.js");
61
- const history = result.history;
62
- const output = command.output === "json" ? JSON.stringify(history) : renderText(result);
63
- process.stdout.write(`${output}\n`);
107
+ writeCliStream(process.stdout, command.output === "json" ? JSON.stringify(settingsJsonValue(value)) : renderSettingsText(value));
64
108
  return 0;
65
109
  }
66
- const akumaResult = typeof result === "object" && result !== null && "kind" in result && result.kind === "akuma";
67
- if (isParsedAkumaCommand(command))
68
- return await writeAkuma(command, result);
69
- if (akumaResult && command.command === "status")
110
+ if (isAkumaOutput(command, result))
70
111
  return await writeAkuma(command, result);
71
112
  const contractResult = result;
72
- if (contractResult.kind === "guidance") {
73
- if (command.output === "json")
74
- process.stdout.write(`${JSON.stringify({ contract: contractResult.contract, guidance: contractResult.guidance })}\n`);
75
- else
76
- process.stdout.write(contractResult.guidance.endsWith("\n") ? contractResult.guidance : `${contractResult.guidance}\n`);
77
- return 0;
78
- }
79
- if (contractResult.kind === "catalog") {
80
- const { renderCatalogText } = await import("./render/catalog.js");
81
- process.stdout.write(`${command.output === "json" ? JSON.stringify(contractResult.catalog) : renderCatalogText(contractResult.catalog)}\n`);
82
- return 0;
83
- }
84
- if (contractResult.kind === "nuke") {
85
- const { nukeExitCode } = await import("./render/nuke.js");
86
- const { renderText } = await import("./render/text.js");
87
- const output = command.output === "json" ? JSON.stringify(contractResult.result) : renderText(contractResult);
88
- process.stdout.write(`${output}\n`);
89
- return nukeExitCode(contractResult.result);
90
- }
91
- if (contractResult.kind === "region") {
92
- const { renderText } = await import("./render/text.js");
93
- process.stdout.write(`${command.output === "json" ? JSON.stringify(contractResult.region) : renderText(contractResult)}\n`);
94
- return 0;
95
- }
96
113
  const { renderText } = await import("./render/text.js");
97
- const output = command.output === "json"
98
- ? JSON.stringify(contractResult.kind === "status" ? contractResult.report : contractResult)
99
- : renderText(contractResult, {
100
- columns: process.stdout.isTTY === true && Number.isInteger(process.stdout.columns) ? process.stdout.columns : 80,
101
- color: process.stdout.isTTY === true && process.env.NO_COLOR === undefined,
102
- });
103
- process.stdout.write(`${output}\n`);
104
- return contractResult.kind === "refused" ? 1 : contractResult.kind === "retry" ? 2 : 0;
114
+ const json = command.output === "json";
115
+ const body = json ? JSON.stringify(invocationJson(contractResult)) : renderText(contractResult, displayContext());
116
+ writeCliStream(process.stdout, body);
117
+ return invocationExitCode(contractResult);
105
118
  }
106
119
  function writeWorldScopeRefusal(error, output) {
107
- const body = output === "json" ? JSON.stringify(error.refusal) : `${error.refusal.kind} ${error.refusal.world} ${error.refusal.ids.join(" ")}`;
108
- process.stderr.write(`${body}\n`);
120
+ const body = output === "json"
121
+ ? JSON.stringify(error.refusal)
122
+ : `${error.refusal.kind} ${error.refusal.world} ${error.refusal.ids.join(" ")}`;
123
+ writeCliStream(process.stderr, body);
109
124
  return 1;
110
125
  }
111
126
  export async function runCliCommand(invocation) {
@@ -115,7 +130,13 @@ export async function runCliCommand(invocation) {
115
130
  const { invoke } = await import("./invoke.js");
116
131
  const result = await invoke(invocation, {
117
132
  cwd: process.cwd(),
118
- ...(start === undefined ? {} : { onOperationStart: () => { process.stderr.write(`${start}\n`); } }),
133
+ ...(start === undefined
134
+ ? {}
135
+ : {
136
+ onOperationStart: () => {
137
+ writeCliStream(process.stderr, start);
138
+ },
139
+ }),
119
140
  });
120
141
  return await writeResult(command, result);
121
142
  }
@@ -128,13 +149,13 @@ export async function runCliCommand(invocation) {
128
149
  if (command.command === "bind") {
129
150
  const { BindDraftError } = await import("./draft.js");
130
151
  if (error instanceof BindDraftError) {
131
- process.stderr.write(`${error.original instanceof Error ? error.original.message : String(error.original)}\n`);
152
+ writeCliStream(process.stderr, error.original instanceof Error ? error.original.message : String(error.original));
132
153
  const { renderBindDraftReceipt } = await import("./render/refusal.js");
133
- process.stderr.write(`${renderBindDraftReceipt(error.draft)}\n`);
154
+ writeCliStream(process.stderr, renderBindDraftReceipt(error.draft));
134
155
  return error.original instanceof CliUsageError ? 1 : 3;
135
156
  }
136
157
  }
137
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
158
+ writeCliStream(process.stderr, error instanceof Error ? error.message : String(error));
138
159
  return error instanceof CliUsageError ? 1 : 3;
139
160
  }
140
161
  }
@@ -25,8 +25,7 @@ function resolveShortContract(rows, selector) {
25
25
  if (selector.startsWith("@kei/"))
26
26
  selectorError(`redundant short contract selector: ${selector}`);
27
27
  const short = selector.slice(1);
28
- const candidates = activeManagedCandidates(rows)
29
- .filter((candidate) => candidate.id.slice("kei/".length) === short);
28
+ const candidates = activeManagedCandidates(rows).filter((candidate) => candidate.id.slice("kei/".length) === short);
30
29
  if (candidates.length === 0)
31
30
  selectorError(`unknown contract selector: ${selector}`);
32
31
  if (candidates.length !== 1)
@@ -34,8 +33,7 @@ function resolveShortContract(rows, selector) {
34
33
  return candidates[0].id;
35
34
  }
36
35
  function resolveOmittedContract(board, scope) {
37
- const candidates = activeManagedCandidates(board.rows)
38
- .filter((candidate) => resolve(scope) === resolve(candidate.worktreePath));
36
+ const candidates = activeManagedCandidates(board.rows).filter((candidate) => resolve(scope) === resolve(candidate.worktreePath));
39
37
  if (candidates.length === 0) {
40
38
  selectorError("an explicit full or @ contract selector is required outside a managed worktree");
41
39
  }
@@ -12,11 +12,12 @@ export function isBlankInput(value) {
12
12
  return value.trim().length === 0;
13
13
  }
14
14
  export function usageLine(usage) {
15
- return usage.split("\n").map((line, index) => {
15
+ return usage
16
+ .split("\n")
17
+ .map((line, index) => {
16
18
  if (index === 0)
17
19
  return `usage: keiyaku ${line}`;
18
- return line.startsWith("task ")
19
- ? ` keiyaku ${line}`
20
- : ` ${line.trimStart()}`;
21
- }).join("\n");
20
+ return line.startsWith("task ") ? ` keiyaku ${line}` : ` ${line.trimStart()}`;
21
+ })
22
+ .join("\n");
22
23
  }
@@ -13,16 +13,6 @@ export type ContractAppointment = Readonly<{
13
13
  kind: "invalid";
14
14
  path: string;
15
15
  }>;
16
- export type HereContractWorkspaceObservation = Readonly<{
17
- kind: "appointed";
18
- path: string;
19
- }> | Readonly<{
20
- kind: "unappointed";
21
- }> | Readonly<{
22
- kind: "failed";
23
- diagnostic: string;
24
- cause?: "duplicate" | "observation";
25
- }>;
26
16
  export declare function renderContractGuidance(state: ContractState): string;
27
17
  export type ContractFileEffect = Readonly<{
28
18
  kind: "contract-file";
@@ -40,18 +30,6 @@ export type ContractWorktreeResult = Readonly<{
40
30
  lag: readonly ContractFileLag[];
41
31
  }>;
42
32
  export declare function readContractAppointment(repository: GitRepository): Promise<ContractAppointment>;
43
- /** Fold existing here appointments over all registered worktrees for one Contract. */
44
- export declare function resolveHereContractWorkspace(repository: GitRepository, contract: ContractId): Promise<HereContractWorkspaceObservation>;
45
- export type ContractReservation = Readonly<{
46
- kind: "reserved";
47
- path: string;
48
- }> | Exclude<ContractAppointment, Readonly<{
49
- kind: "absent";
50
- path: string;
51
- }>>;
52
- export declare function reserveContractWorktree(repository: GitRepository, contract: ContractId): Promise<ContractReservation>;
53
33
  export declare function withContractWorktreeAppointment<T>(repository: GitRepository, action: () => T | Promise<T>): Promise<T>;
54
34
  export declare function releaseContractWorktree(repository: GitRepository, contract: ContractId): Promise<void>;
55
- /** Remove matching here appointments and their exact generated support from registered worktrees. */
56
- export declare function nukeHereAppointments(repository: GitRepository): Promise<void>;
57
- export declare function projectContractWorktree(repository: GitRepository, state: ContractState | null, register?: PlaceRegister, onConflict?: (diagnostic: string) => never): Promise<ContractWorktreeResult>;
35
+ export declare function projectContractWorktree(repository: GitRepository, state: ContractState | null, register?: PlaceRegister, _onConflict?: (diagnostic: string) => never): Promise<ContractWorktreeResult>;