@astrosheep/keiyaku 4.6.4 → 4.6.7

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 (247) hide show
  1. package/README.md +7 -0
  2. package/build/{integrations/marketplace → plugins}/.agents/plugins/marketplace.json +1 -1
  3. package/build/plugins/.claude-plugin/marketplace.json +5 -0
  4. package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/.claude-plugin/plugin.json +1 -1
  5. package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-akuma/SKILL.md +43 -8
  6. package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-bind/SKILL.md +7 -8
  7. package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-workflow/SKILL.md +3 -3
  8. package/build/{integrations/marketplace/plugins/keiyaku → plugins/codex}/.codex-plugin/plugin.json +1 -1
  9. package/build/plugins/codex/skills/keiyaku/SKILL.md +44 -0
  10. package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +130 -0
  11. package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +269 -0
  12. package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +65 -0
  13. package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +216 -0
  14. package/build/plugins/codex/skills/keiyaku-bind/agents/openai.yaml +4 -0
  15. package/build/plugins/codex/skills/keiyaku-task/SKILL.md +104 -0
  16. package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +129 -0
  17. package/build/plugins/opencode/package.json +6 -0
  18. package/build/plugins/opencode/skills/keiyaku/SKILL.md +44 -0
  19. package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +130 -0
  20. package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +269 -0
  21. package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +65 -0
  22. package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +216 -0
  23. package/build/plugins/opencode/skills/keiyaku-bind/agents/openai.yaml +4 -0
  24. package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +104 -0
  25. package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +129 -0
  26. package/build/skills/keiyaku/SKILL.md +44 -0
  27. package/build/skills/keiyaku-akuma/SKILL.md +130 -0
  28. package/build/skills/keiyaku-akuma/references/automation.md +269 -0
  29. package/build/skills/keiyaku-babysit/SKILL.md +65 -0
  30. package/build/skills/keiyaku-bind/SKILL.md +216 -0
  31. package/build/skills/keiyaku-bind/agents/openai.yaml +4 -0
  32. package/build/skills/keiyaku-task/SKILL.md +104 -0
  33. package/build/skills/keiyaku-workflow/SKILL.md +129 -0
  34. package/build/src/akuma/akuma-instance.js +7 -5
  35. package/build/src/akuma/akuma-observe.d.ts +22 -15
  36. package/build/src/akuma/akuma-observe.js +87 -16
  37. package/build/src/akuma/akuma-owner.d.ts +3 -2
  38. package/build/src/akuma/akuma-owner.js +28 -10
  39. package/build/src/akuma/akuma-selection-execution.d.ts +3 -1
  40. package/build/src/akuma/akuma-selection-execution.js +2 -1
  41. package/build/src/akuma/akuma-wait.d.ts +6 -4
  42. package/build/src/akuma/akuma-wait.js +78 -53
  43. package/build/src/akuma/akuma.d.ts +6 -4
  44. package/build/src/akuma/akuma.js +4 -0
  45. package/build/src/akuma/body.d.ts +1 -0
  46. package/build/src/akuma/body.js +12 -23
  47. package/build/src/akuma/call-initial-tell.d.ts +2 -2
  48. package/build/src/akuma/call-initial-tell.js +1 -1
  49. package/build/src/akuma/call-request.d.ts +2 -2
  50. package/build/src/akuma/heart/index.d.ts +7 -2
  51. package/build/src/akuma/heart/index.js +50 -5
  52. package/build/src/akuma/heart/tells.d.ts +33 -2
  53. package/build/src/akuma/heart/tells.js +24 -18
  54. package/build/src/akuma/heart/timeline.d.ts +23 -1
  55. package/build/src/akuma/heart/timeline.js +28 -21
  56. package/build/src/akuma/projection.d.ts +10 -10
  57. package/build/src/akuma/providers/pi/index.js +72 -39
  58. package/build/src/akuma/selection-observation.d.ts +20 -20
  59. package/build/src/akuma/selection-owner-port.d.ts +1 -1
  60. package/build/src/akuma/selection-owner-port.js +16 -5
  61. package/build/src/akuma/selection-request.d.ts +2 -0
  62. package/build/src/akuma/selection-request.js +2 -1
  63. package/build/src/akuma-body.js +5 -2
  64. package/build/src/alias/index.d.ts +0 -1
  65. package/build/src/alias/index.js +0 -4
  66. package/build/src/body/amend.d.ts +0 -4
  67. package/build/src/body/amend.js +0 -3
  68. package/build/src/body/region.d.ts +0 -1
  69. package/build/src/body/region.js +0 -3
  70. package/build/src/body/verification.d.ts +0 -1
  71. package/build/src/cli/commands/akuma-grammar.js +23 -66
  72. package/build/src/cli/commands/akuma.js +23 -42
  73. package/build/src/cli/commands/contract-grammar.d.ts +14 -1
  74. package/build/src/cli/commands/contract-grammar.js +54 -21
  75. package/build/src/cli/commands/contract-help.d.ts +9 -8
  76. package/build/src/cli/commands/contract-help.js +14 -7
  77. package/build/src/cli/commands/contract.js +57 -117
  78. package/build/src/cli/commands/install.d.ts +5 -5
  79. package/build/src/cli/commands/install.js +4 -7
  80. package/build/src/cli/commands/task-grammar.js +10 -66
  81. package/build/src/cli/commands/task.d.ts +0 -1
  82. package/build/src/cli/commands/task.js +34 -53
  83. package/build/src/cli/coordinates.d.ts +1 -2
  84. package/build/src/cli/coordinates.js +1 -4
  85. package/build/src/cli/parse.d.ts +2 -3
  86. package/build/src/cli/parse.js +24 -66
  87. package/build/src/cli/render/akuma.d.ts +3 -16
  88. package/build/src/cli/render/akuma.js +1 -13
  89. package/build/src/cli/render/audit.js +1 -1
  90. package/build/src/cli/render/contract.js +34 -32
  91. package/build/src/cli/render/kanshi-akuma.d.ts +8 -2
  92. package/build/src/cli/render/kanshi-akuma.js +14 -7
  93. package/build/src/cli/render/kanshi.d.ts +3 -1
  94. package/build/src/cli/render/kanshi.js +44 -32
  95. package/build/src/cli/render/receipt.js +6 -1
  96. package/build/src/cli/render/task.d.ts +1 -1
  97. package/build/src/cli/render/task.js +3 -27
  98. package/build/src/cli/render/terminal.d.ts +6 -2
  99. package/build/src/cli/render/terminal.js +8 -2
  100. package/build/src/cli/runtime.js +3 -16
  101. package/build/src/cli/scan.d.ts +26 -0
  102. package/build/src/cli/scan.js +82 -0
  103. package/build/src/cli/streams.d.ts +5 -0
  104. package/build/src/cli/streams.js +11 -0
  105. package/build/src/contract-worktree.js +38 -21
  106. package/build/src/core/facts/codec.d.ts +1 -2
  107. package/build/src/core/facts/codec.js +5 -11
  108. package/build/src/core/facts/types.d.ts +16 -2
  109. package/build/src/core/facts/types.js +15 -0
  110. package/build/src/core/verbs/abandon.js +3 -9
  111. package/build/src/core/verbs/amend.js +2 -9
  112. package/build/src/core/verbs/arc.js +6 -13
  113. package/build/src/core/verbs/attestation.js +2 -9
  114. package/build/src/core/verbs/bind.js +2 -9
  115. package/build/src/core/verbs/deliver.js +2 -9
  116. package/build/src/core/verbs/placement.d.ts +1 -1
  117. package/build/src/core/verbs/placement.js +2 -9
  118. package/build/src/core/verbs/reintegrate.d.ts +1 -1
  119. package/build/src/core/verbs/reintegrate.js +2 -9
  120. package/build/src/dispatch/index.d.ts +2 -2
  121. package/build/src/dispatch/index.js +33 -11
  122. package/build/src/git/hooks.d.ts +2 -4
  123. package/build/src/git/hooks.js +0 -12
  124. package/build/src/git/integration.d.ts +5 -3
  125. package/build/src/git/integration.js +36 -25
  126. package/build/src/git/nuke.js +4 -4
  127. package/build/src/git/observe.d.ts +4 -4
  128. package/build/src/git/observe.js +5 -5
  129. package/build/src/git/process.d.ts +1 -4
  130. package/build/src/git/process.js +1 -11
  131. package/build/src/git/read-observation.js +1 -1
  132. package/build/src/git/reconcile.d.ts +1 -1
  133. package/build/src/git/reconcile.js +15 -13
  134. package/build/src/git/repository.d.ts +2 -6
  135. package/build/src/git/repository.js +18 -31
  136. package/build/src/git/scratch.d.ts +6 -6
  137. package/build/src/git/scratch.js +110 -46
  138. package/build/src/git/target-placement.d.ts +5 -5
  139. package/build/src/git/target-placement.js +18 -33
  140. package/build/src/git/tender.d.ts +6 -2
  141. package/build/src/git/tender.js +19 -12
  142. package/build/src/git/terminal-reconcile.js +24 -13
  143. package/build/src/git/terminal-seal.d.ts +2 -5
  144. package/build/src/git/terminal-seal.js +5 -3
  145. package/build/src/git/workspace.d.ts +17 -13
  146. package/build/src/git/workspace.js +58 -41
  147. package/build/src/kanshi/index.d.ts +2 -2
  148. package/build/src/kanshi/index.js +1 -1
  149. package/build/src/kanshi/read.d.ts +8 -1
  150. package/build/src/kanshi/read.js +72 -7
  151. package/build/src/kanshi/report.d.ts +12 -0
  152. package/build/src/library/akuma-creation.d.ts +4 -4
  153. package/build/src/library/akuma-creation.js +21 -19
  154. package/build/src/library/bind.d.ts +1 -63
  155. package/build/src/library/bind.js +3 -9
  156. package/build/src/library/contract-creation.js +2 -30
  157. package/build/src/library/contract-execution.d.ts +0 -1
  158. package/build/src/library/contract-execution.js +9 -34
  159. package/build/src/library/contract-operations.d.ts +5 -1
  160. package/build/src/library/contract-operations.js +7 -3
  161. package/build/src/library/contract-types.d.ts +1 -1
  162. package/build/src/library/delivery.d.ts +91 -93
  163. package/build/src/library/delivery.js +2 -1
  164. package/build/src/library/input.d.ts +0 -2
  165. package/build/src/library/input.js +0 -4
  166. package/build/src/library/invocation.d.ts +0 -1
  167. package/build/src/library/invocation.js +3 -25
  168. package/build/src/library/outcome.d.ts +651 -602
  169. package/build/src/library/outcome.js +4 -4
  170. package/build/src/library/reconcile.d.ts +6 -0
  171. package/build/src/library/reconcile.js +31 -1
  172. package/build/src/library/repo.d.ts +0 -1
  173. package/build/src/library/selection.d.ts +1 -10
  174. package/build/src/library/selection.js +19 -17
  175. package/build/src/plugin/akuma-signals.d.ts +10 -11
  176. package/build/src/plugin/akuma-signals.js +36 -20
  177. package/build/src/plugin/public.d.ts +5 -0
  178. package/build/src/plugin/runtime.d.ts +1 -0
  179. package/build/src/plugin/runtime.js +34 -23
  180. package/build/src/protocol/abandon.d.ts +1 -1
  181. package/build/src/protocol/abandon.js +3 -10
  182. package/build/src/protocol/amend.js +2 -5
  183. package/build/src/protocol/arc.d.ts +1 -1
  184. package/build/src/protocol/arc.js +2 -9
  185. package/build/src/protocol/attempt.d.ts +3 -20
  186. package/build/src/protocol/attempt.js +6 -5
  187. package/build/src/protocol/audit.d.ts +1 -0
  188. package/build/src/protocol/audit.js +10 -11
  189. package/build/src/protocol/completion.d.ts +129 -55
  190. package/build/src/protocol/completion.js +62 -73
  191. package/build/src/protocol/deliver.d.ts +7 -5
  192. package/build/src/protocol/deliver.js +74 -44
  193. package/build/src/protocol/execution-observation.d.ts +2 -4
  194. package/build/src/protocol/execution-observation.js +3 -7
  195. package/build/src/protocol/intent.d.ts +1 -1
  196. package/build/src/protocol/intent.js +1 -0
  197. package/build/src/protocol/operations.d.ts +24 -12
  198. package/build/src/protocol/operations.js +36 -15
  199. package/build/src/protocol/placement.d.ts +2 -1
  200. package/build/src/protocol/placement.js +21 -5
  201. package/build/src/protocol/progress.d.ts +1 -1
  202. package/build/src/protocol/read/status.js +58 -41
  203. package/build/src/protocol/reintegrate.d.ts +1 -1
  204. package/build/src/protocol/reintegrate.js +10 -19
  205. package/build/src/protocol/review.d.ts +3 -28
  206. package/build/src/protocol/review.js +10 -37
  207. package/build/src/protocol/run.d.ts +19 -7
  208. package/build/src/protocol/run.js +19 -9
  209. package/build/src/runtime/proc/windows-launch.exe +0 -0
  210. package/build/src/settlement/holder.d.ts +2 -4
  211. package/build/src/settlement/holder.js +3 -6
  212. package/build/src/task/board.d.ts +6 -0
  213. package/build/src/task/board.js +30 -1
  214. package/build/src/task/catalog.js +1 -4
  215. package/build/src/task/compose.d.ts +0 -1
  216. package/build/src/task/compose.js +0 -1
  217. package/build/src/task/context.d.ts +0 -1
  218. package/build/src/task/context.js +0 -3
  219. package/build/src/task/created-observation.d.ts +5 -1
  220. package/build/src/task/created-observation.js +12 -5
  221. package/build/src/task/index.d.ts +1 -1
  222. package/build/src/task/index.js +7 -6
  223. package/build/src/task/input.d.ts +0 -6
  224. package/build/src/task/input.js +2 -14
  225. package/build/src/task/mutation.d.ts +3 -4
  226. package/build/src/task/mutation.js +11 -39
  227. package/build/src/task/operations.d.ts +2 -7
  228. package/build/src/task/operations.js +37 -49
  229. package/build/src/task/query.d.ts +0 -1
  230. package/build/src/task/query.js +1 -4
  231. package/build/src/task/store.d.ts +0 -2
  232. package/build/src/task/store.js +27 -11
  233. package/build/src/verification/declaration.js +3 -2
  234. package/build/src/verification/execution.d.ts +3 -2
  235. package/build/src/verification/execution.js +10 -6
  236. package/build/src/workspace-place.d.ts +0 -1
  237. package/build/src/workspace-place.js +0 -11
  238. package/package.json +13 -9
  239. package/build/integrations/marketplace/.claude-plugin/marketplace.json +0 -5
  240. package/build/integrations/marketplace/plugins/keiyaku/package.json +0 -17
  241. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku/SKILL.md +0 -0
  242. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-akuma/references/automation.md +0 -0
  243. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-babysit/SKILL.md +0 -0
  244. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-bind/agents/openai.yaml +0 -0
  245. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-task/SKILL.md +0 -0
  246. /package/build/{integrations/marketplace/plugins/keiyaku/opencode.js → plugins/opencode/index.js} +0 -0
  247. /package/build/{integrations → plugins}/pi/keiyaku.ts +0 -0
@@ -1,13 +1,12 @@
1
1
  import { CliUsageError, isBlankInput } from "../usage.js";
2
2
  import { parseTaskNamespaceSelector } from "../../task/catalog.js";
3
- import { taskRowViewLimit, tasksWithExecution, } from "../../task/index.js";
3
+ import { tasksWithExecution, taskRowViewLimit, } from "../../task/index.js";
4
4
  import { taskCompositionNamespaceHeader } from "../../task/compose-language.js";
5
- import { resolveTaskNamespaceContext, writeTaskNamespaceContext } from "../../task/context.js";
6
- import { displayContext, writeJson, writeStderr, writeStdout } from "../streams.js";
7
- import { renderTaskCompose, renderTaskContext, renderTaskDoctor, renderTaskFailure, renderTaskIncompleteDiagnostic, renderTaskLifecycle, renderTaskList, renderTaskMutation, renderTaskShow, renderTaskTree, renderTaskUpdate, taskExitCode, } from "../render/task.js";
5
+ import { installNamespaceContext, resolveTaskNamespaceContext } from "../../task/context.js";
6
+ import { displayContext, emit, writeJson, writeStderr, writeStdout } from "../streams.js";
7
+ import { renderDoctor, renderTaskCompose, renderTaskContext, renderTaskFailure, renderTaskIncompleteDiagnostic, renderTaskLifecycle, renderTaskList, renderTaskMutation, renderTaskShow, renderTaskTree, renderTaskUpdate, taskExitCode, } from "../render/task.js";
8
8
  import { actorFromEdge } from "../actor.js";
9
9
  import { taskQuerySelection } from "../../task/query.js";
10
- export { renderTaskHelp } from "./task-grammar.js";
11
10
  function value(command, name) {
12
11
  const item = command.flags[name];
13
12
  return typeof item === "string" ? item : undefined;
@@ -59,17 +58,6 @@ function taskStdinDiagnostic(command) {
59
58
  return undefined;
60
59
  }
61
60
  }
62
- /**
63
- * The shared output primitive: one native answer, its matching rendered text, and the native exit
64
- * classifier's verdict. JSON writes the untouched native value; text writes the rendered lines.
65
- */
66
- function emitTask(output, result, project, code) {
67
- if (output === "json")
68
- writeJson(result);
69
- else
70
- writeStdout(project());
71
- return code;
72
- }
73
61
  async function invokeAdd(input) {
74
62
  const { tasks, command, current = [] } = input;
75
63
  const selectedNamespace = namespace(value(command, "namespace")) ?? current;
@@ -137,17 +125,14 @@ async function runShow(command, tasks) {
137
125
  details.push(await tasks.task({ id }).read());
138
126
  const missing = details.findIndex((detail) => detail === null);
139
127
  const code = missing >= 0 ? 1 : 0;
140
- if (command.output === "json") {
141
- writeJson(handles.length === 1 ? details[0] : details);
142
- return code;
143
- }
128
+ const projected = handles.length === 1 ? details[0] : details;
144
129
  if (missing >= 0) {
145
130
  const refusal = { kind: "refused", refusal: { kind: "task-missing", taskId: handles[missing] } };
146
- return emitTask(command.output, refusal, () => renderTaskShow(refusal, displayContext()), code);
131
+ return emit(command.output, projected, () => renderTaskShow(refusal, displayContext()), code);
147
132
  }
148
133
  const found = details.filter((detail) => detail !== null);
149
134
  const result = found.length === 1 ? found[0] : found;
150
- return emitTask(command.output, result, () => renderTaskShow(result, displayContext()), code);
135
+ return emit(command.output, projected, () => renderTaskShow(result, displayContext()), code);
151
136
  }
152
137
  /** Presentation-only list scope the leaf acquired, never part of the native answer. */
153
138
  function listPresentation(command) {
@@ -169,7 +154,7 @@ async function runRead(input) {
169
154
  : { namespace: explicitListNamespace(command) }),
170
155
  ...(limit(command) === undefined ? {} : { limit: limit(command) }),
171
156
  });
172
- return emitTask(command.output, result, () => renderTaskList("ls", scope, result, displayContext()), taskExitCode(result));
157
+ return emit(command.output, result, () => renderTaskList("ls", scope, result, displayContext()), taskExitCode(result));
173
158
  }
174
159
  case "ready": {
175
160
  const result = await tasks.ready({
@@ -177,7 +162,7 @@ async function runRead(input) {
177
162
  ...(value(command, "parent") === undefined ? {} : { parent: value(command, "parent") }),
178
163
  ...(limit(command) === undefined ? {} : { limit: limit(command) }),
179
164
  });
180
- return emitTask(command.output, result, () => renderTaskList("ready", scope, result, displayContext()), taskExitCode(result));
165
+ return emit(command.output, result, () => renderTaskList("ready", scope, result, displayContext()), taskExitCode(result));
181
166
  }
182
167
  case "blocked": {
183
168
  const result = await tasks.blocked({
@@ -185,7 +170,7 @@ async function runRead(input) {
185
170
  ...(value(command, "parent") === undefined ? {} : { parent: value(command, "parent") }),
186
171
  ...(limit(command) === undefined ? {} : { limit: limit(command) }),
187
172
  });
188
- return emitTask(command.output, result, () => renderTaskList("blocked", scope, result, displayContext()), taskExitCode(result));
173
+ return emit(command.output, result, () => renderTaskList("blocked", scope, result, displayContext()), taskExitCode(result));
189
174
  }
190
175
  case "query": {
191
176
  const result = await tasks.query({
@@ -194,15 +179,15 @@ async function runRead(input) {
194
179
  ...(value(command, "sort") === undefined ? {} : { sort: value(command, "sort") }),
195
180
  ...(limit(command) === undefined ? {} : { limit: limit(command) }),
196
181
  });
197
- return emitTask(command.output, result, () => renderTaskList("query", scope, result, displayContext()), taskExitCode(result));
182
+ return emit(command.output, result, () => renderTaskList("query", scope, result, displayContext()), taskExitCode(result));
198
183
  }
199
184
  case "tree": {
200
185
  const result = await tasks.task({ id }).tree();
201
- return emitTask(command.output, result, () => renderTaskTree(result, displayContext()), taskExitCode(result));
186
+ return emit(command.output, result, () => renderTaskTree(result, displayContext()), taskExitCode(result));
202
187
  }
203
188
  case "doctor": {
204
189
  const result = await tasks.doctor();
205
- return emitTask(command.output, result, () => renderTaskDoctor(result), taskExitCode(result));
190
+ return emit(command.output, result, () => renderDoctor(result), taskExitCode(result));
206
191
  }
207
192
  default:
208
193
  throw new Error(`task action is not a read: ${command.action}`);
@@ -231,26 +216,22 @@ function missingWorld(command) {
231
216
  return 1;
232
217
  }
233
218
  const refusal = missingTask(command.positionals[0]);
234
- return emitTask(output, refusal, () => renderTaskShow(refusal, displayContext()), 1);
219
+ return emit(output, refusal, () => renderTaskShow(refusal, displayContext()), 1);
235
220
  }
236
221
  if (isWorldObservationAction(command) || (command.action === "compose" && command.flags.plan === true)) {
237
- if (output === "json")
238
- writeJson({ kind: "absent" });
239
- else
240
- writeStdout("task world absent");
241
- return 1;
222
+ return emit(output, { kind: "absent" }, () => "task world absent", 1);
242
223
  }
243
224
  if (command.action === "context") {
244
225
  const result = { kind: "accepted", value: { namespace: [], source: "default-root" } };
245
- return emitTask(output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
226
+ return emit(output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
246
227
  }
247
228
  if (command.action === "tree") {
248
229
  const result = missingTask(command.positionals[0]);
249
- return emitTask(output, result, () => renderTaskTree(result, displayContext()), taskExitCode(result));
230
+ return emit(output, result, () => renderTaskTree(result, displayContext()), taskExitCode(result));
250
231
  }
251
232
  if (command.action === "update") {
252
233
  const result = missingTask(command.positionals[0]);
253
- return emitTask(output, result, () => renderTaskUpdate(result, displayContext()), taskExitCode(result));
234
+ return emit(output, result, () => renderTaskUpdate(result, displayContext()), taskExitCode(result));
254
235
  }
255
236
  if (command.action === "start" ||
256
237
  command.action === "stop" ||
@@ -258,18 +239,18 @@ function missingWorld(command) {
258
239
  command.action === "resume") {
259
240
  if (command.positionals.length === 1) {
260
241
  const result = missingTask(command.positionals[0]);
261
- return emitTask(output, result, () => renderTaskMutation(command.action, result, displayContext()), taskExitCode(result));
242
+ return emit(output, result, () => renderTaskMutation(command.action, result, displayContext()), taskExitCode(result));
262
243
  }
263
244
  const result = {
264
245
  items: command.positionals.map((id) => ({ id: id, outcome: missingTask(id) })),
265
246
  };
266
- return emitTask(output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
247
+ return emit(output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
267
248
  }
268
249
  if (command.action === "done" || command.action === "drop") {
269
250
  const result = {
270
251
  items: command.positionals.map((id) => ({ id: id, outcome: missingTask(id) })),
271
252
  };
272
- return emitTask(output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
253
+ return emit(output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
273
254
  }
274
255
  throw new Error(`task action has no missing-world answer: ${command.action}`);
275
256
  }
@@ -300,7 +281,7 @@ async function runBatchLifecycle(tasks, command, verb) {
300
281
  ids: command.positionals,
301
282
  ...(note === undefined ? {} : { note }),
302
283
  });
303
- return emitTask(command.output, result, () => renderTaskLifecycle(verb, result, displayContext()), taskExitCode(result));
284
+ return emit(command.output, result, () => renderTaskLifecycle(verb, result, displayContext()), taskExitCode(result));
304
285
  }
305
286
  async function runMutation(input) {
306
287
  const { tasks, command, current, stdin, composeMarkdown, composeNamespace } = input;
@@ -309,17 +290,17 @@ async function runMutation(input) {
309
290
  switch (command.action) {
310
291
  case "add": {
311
292
  const result = await invokeAdd(input);
312
- return emitTask(command.output, result, () => renderTaskMutation("add", result, displayContext()), taskExitCode(result));
293
+ return emit(command.output, result, () => renderTaskMutation("add", result, displayContext()), taskExitCode(result));
313
294
  }
314
295
  case "update": {
315
296
  const result = await invokeUpdate(input);
316
- return emitTask(command.output, result, () => renderTaskUpdate(result, displayContext()), taskExitCode(result));
297
+ return emit(command.output, result, () => renderTaskUpdate(result, displayContext()), taskExitCode(result));
317
298
  }
318
299
  case "start":
319
300
  case "stop":
320
301
  case "resume": {
321
302
  const result = await invokeLifecycle(tasks, command.positionals, command.positionals[0], command.action);
322
- return emitTask(command.output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
303
+ return emit(command.output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
323
304
  }
324
305
  case "hold":
325
306
  case "done":
@@ -328,20 +309,20 @@ async function runMutation(input) {
328
309
  case "context": {
329
310
  const selected = namespace(command.positionals[0]);
330
311
  if (selected !== undefined) {
331
- await writeTaskNamespaceContext(input.context.writeRoot ?? input.context.directory, selected);
312
+ await installNamespaceContext(input.context.writeRoot ?? input.context.directory, selected);
332
313
  const resolved = await resolveTaskNamespaceContext(input.context);
333
314
  if (typeof resolved === "object" && "kind" in resolved) {
334
315
  const result = { kind: "refused", refusal: resolved };
335
- return emitTask(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
316
+ return emit(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
336
317
  }
337
318
  const result = { kind: "accepted", value: resolved };
338
- return emitTask(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
319
+ return emit(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
339
320
  }
340
321
  const result = {
341
322
  kind: "accepted",
342
323
  value: { namespace: current ?? [], source: "default-root" },
343
324
  };
344
- return emitTask(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
325
+ return emit(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
345
326
  }
346
327
  case "compose": {
347
328
  const result = await tasks.compose({
@@ -376,14 +357,14 @@ function refuseNamespace(command, refusal) {
376
357
  case "blocked":
377
358
  case "query": {
378
359
  const action = command.action;
379
- return emitTask(command.output, result, () => renderTaskList(action, listPresentation(command), result, displayContext()), taskExitCode(result));
360
+ return emit(command.output, result, () => renderTaskList(action, listPresentation(command), result, displayContext()), taskExitCode(result));
380
361
  }
381
362
  case "add":
382
- return emitTask(command.output, result, () => renderTaskMutation("add", result, displayContext()), taskExitCode(result));
363
+ return emit(command.output, result, () => renderTaskMutation("add", result, displayContext()), taskExitCode(result));
383
364
  case "context":
384
- return emitTask(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
365
+ return emit(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
385
366
  case "compose":
386
- return emitTask(command.output, result, () => renderTaskFailure("compose", result, displayContext()), taskExitCode(result));
367
+ return emit(command.output, result, () => renderTaskFailure("compose", result, displayContext()), taskExitCode(result));
387
368
  default:
388
369
  throw new Error(`task action has no namespace refusal: ${command.action}`);
389
370
  }
@@ -425,7 +406,7 @@ export async function runTaskCommand(command, coordinates, runtime) {
425
406
  current = resolved.namespace;
426
407
  if (command.action === "context" && command.positionals.length === 0) {
427
408
  const result = { kind: "accepted", value: resolved };
428
- return emitTask(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
409
+ return emit(command.output, result, () => renderTaskContext(result, displayContext()), taskExitCode(result));
429
410
  }
430
411
  }
431
412
  if (command.action === "show")
@@ -15,7 +15,7 @@ export type CliCoordinates = Readonly<{
15
15
  }>;
16
16
  establishWorld: () => Promise<WorldRoot>;
17
17
  }>;
18
- export type CliCoordinateInput = Readonly<{
18
+ type CliCoordinateInput = Readonly<{
19
19
  processCwd?: string;
20
20
  cwd?: string;
21
21
  repo?: string;
@@ -35,7 +35,6 @@ export declare const cliCoordinateDiscovery: {
35
35
  }>>;
36
36
  resolve(input: CliCoordinateInput): Promise<CliCoordinates>;
37
37
  };
38
- export declare function resolveCliCoordinates(input: CliCoordinateInput): Promise<CliCoordinates>;
39
38
  type InvocationCoordinatesInput = Readonly<{
40
39
  processCwd?: string;
41
40
  cwd?: string;
@@ -103,9 +103,6 @@ async function resolveWorld(cwd, repo) {
103
103
  throw error;
104
104
  }
105
105
  }
106
- export async function resolveCliCoordinates(input) {
107
- return cliCoordinateDiscovery.resolve(input);
108
- }
109
106
  /** One explicit Git executable override from the process edge; a blank value is usage, not absence. */
110
107
  function gitPathFromEdge(environment) {
111
108
  const value = environment.KEIYAKU_GIT_PATH;
@@ -118,7 +115,7 @@ function gitPathFromEdge(environment) {
118
115
  /** The one process-edge coordinate resolution: explicit filesystem inputs plus the command's Repo policy. */
119
116
  export async function resolveInvocationCoordinates(invocation, environment) {
120
117
  const gitPath = gitPathFromEdge(environment);
121
- return resolveCliCoordinates({
118
+ return cliCoordinateDiscovery.resolve({
122
119
  ...(invocation.processCwd === undefined ? {} : { processCwd: invocation.processCwd }),
123
120
  ...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
124
121
  ...(invocation.repo === undefined ? {} : { repo: invocation.repo }),
@@ -6,13 +6,12 @@ import { type ContractCommand as Command } from "./commands/contract-help.js";
6
6
  import { type CliUsageGuide } from "./usage.js";
7
7
  export { CliUsageError } from "./usage.js";
8
8
  export type { CliUsageGuide } from "./usage.js";
9
- export { renderContractHelp } from "./commands/contract-help.js";
10
9
  export type { Command };
11
10
  export declare function renderRootHelp(columns?: number): string;
12
11
  export declare function usageGuideForCommand(command: ParsedCommand): CliUsageGuide;
13
12
  export declare function renderHelp(coordinate: CliHelpCoordinate, columns?: number): string;
14
13
  export type ParsedCommand = ParsedBind | ParsedAmend | ParsedDeliver | ParsedReview | ParsedArc | ParsedAbandon | ParsedStatus | ParsedLs | ParsedAudit | ParsedReconcile | ParsedNuke | ParsedSettings | ParsedRegion | ParsedInstallCommand | ParsedAkumaCommand | ParsedTaskCommand;
15
- export type CliHelpCoordinate = Readonly<{
14
+ type CliHelpCoordinate = Readonly<{
16
15
  kind: "root";
17
16
  }> | Readonly<{
18
17
  kind: "contract";
@@ -37,7 +36,7 @@ export type ParsedInvocation = Readonly<{
37
36
  version: true;
38
37
  }>;
39
38
  type RepoUse = "none" | "optional" | "required";
40
- export type CommandRepoPolicy = Readonly<{
39
+ type CommandRepoPolicy = Readonly<{
41
40
  use: RepoUse;
42
41
  acceptsExplicit: boolean;
43
42
  }>;
@@ -4,9 +4,9 @@ import { INSTALL_ROOT_PURPOSE, INSTALL_USAGE, parseInstallCommand, renderInstall
4
4
  import { parseContractCommand, } from "./commands/contract-grammar.js";
5
5
  import { CONTRACT_COMMAND_SPECS, renderContractHelp as renderContractHelpForOwner, } from "./commands/contract-help.js";
6
6
  import { renderOpaqueBlock, renderTextBlock } from "./render/terminal.js";
7
+ import { scanArgs } from "./scan.js";
7
8
  import { CliUsageError, commandGuide, isBlankInput, ROOT_USAGE_GUIDE, unknownCommandGuide, } from "./usage.js";
8
9
  export { CliUsageError } from "./usage.js";
9
- export { renderContractHelp } from "./commands/contract-help.js";
10
10
  const ROOT_USAGE = [
11
11
  "usage keiyaku <command> [options]",
12
12
  " keiyaku <command> --help shows that command's complete usage",
@@ -140,63 +140,14 @@ export function assertExplicitRepoUse(command, repo) {
140
140
  function refuse(command, message) {
141
141
  throw new CliUsageError(message, commandGuide(command, CONTRACT_COMMAND_SPECS[command].usage));
142
142
  }
143
- function scanStdin(command, state) {
144
- if (state.stdin)
145
- refuse(command, "stdin marker '-' may appear only once");
146
- if (CONTRACT_COMMAND_SPECS[command].stdin === "none")
147
- refuse(command, `${command} reads no stdin`);
148
- state.stdin = true;
149
- }
150
- function scanOption(command, argv, state, index) {
151
- const token = argv[index];
152
- const name = token.slice(2);
153
- const spec = CONTRACT_COMMAND_SPECS[command];
154
- const kind = spec.flags[name];
155
- if (kind === undefined)
156
- refuse(command, `option ${token} is not valid for ${command}`);
157
- if (state.flags[name] !== undefined && kind !== "repeat-value")
158
- refuse(command, `duplicate option: ${token}`);
159
- if (kind === "boolean") {
160
- state.flags[name] = true;
161
- return index;
162
- }
163
- const value = argv[index + 1];
164
- if (value === undefined || value.startsWith("--"))
165
- refuse(command, `${token} requires a value`);
166
- if (kind !== "raw-value" && value === "-") {
167
- refuse(command, `${token} requires a value`);
168
- }
169
- if (kind !== "raw-value" && isBlankInput(value))
170
- refuse(command, `${token} requires a nonblank value`);
171
- if (kind === "repeat-value") {
172
- const values = state.flags[name];
173
- state.flags[name] = [...(Array.isArray(values) ? values : values === undefined ? [] : [values]), value];
174
- }
175
- else {
176
- state.flags[name] = value;
177
- }
178
- return index + 1;
179
- }
180
- function scanContractTokens(command, argv, state) {
181
- let positionalOnly = false;
182
- for (let index = 1; index < argv.length; index += 1) {
183
- const token = argv[index];
184
- if (!positionalOnly && token === "--") {
185
- positionalOnly = true;
186
- continue;
187
- }
188
- if (!positionalOnly && token === "-") {
189
- scanStdin(command, state);
190
- continue;
191
- }
192
- if (!positionalOnly && token.startsWith("--")) {
193
- index = scanOption(command, argv, state, index);
194
- continue;
195
- }
196
- if (isBlankInput(token))
197
- refuse(command, `${command} requires a nonblank value`);
198
- state.positionals.push(token);
199
- }
143
+ /** The contract surfaces' one scan spec: `-` carries the edge's own stdin input. */
144
+ function contractScanSpec(command, spec) {
145
+ return {
146
+ subject: command,
147
+ flags: spec.flags,
148
+ ...(spec.stdin === "none" ? {} : { stdin: "input" }),
149
+ stdinRefusal: `${command} reads no stdin`,
150
+ };
200
151
  }
201
152
  function scanArgv(argv) {
202
153
  const candidate = argv[0];
@@ -205,20 +156,27 @@ function scanArgv(argv) {
205
156
  }
206
157
  const command = candidate;
207
158
  const spec = CONTRACT_COMMAND_SPECS[command];
208
- const state = { flags: {}, positionals: [], stdin: false };
209
- scanContractTokens(command, argv, state);
210
- if (spec.positional === "none" && state.positionals.length > 0) {
159
+ const scanned = scanArgs(argv, contractScanSpec(command, spec), (message) => refuse(command, message));
160
+ const stdin = scanned.stdin !== undefined;
161
+ if (spec.positional === "none" && scanned.positionals.length > 0) {
211
162
  refuse(command, `${command} accepts no contract`);
212
163
  }
213
- if (spec.positional === "optional" && state.positionals.length > 1 && command !== "status") {
164
+ if (spec.positional === "optional" && scanned.positionals.length > 1 && command !== "status") {
214
165
  refuse(command, `${command} accepts at most one contract`);
215
166
  }
216
- if (spec.stdin === "required" && !state.stdin) {
167
+ if (spec.stdin === "required" && !stdin) {
217
168
  refuse(command, `${command} requires stdin`);
218
169
  }
219
- const output = state.flags.json === true ? "json" : "text";
220
- const actor = typeof state.flags.actor === "string" ? state.flags.actor : undefined;
221
- return { command, ...state, output, ...(actor === undefined ? {} : { actor }) };
170
+ const output = scanned.flags.json === true ? "json" : "text";
171
+ const actor = typeof scanned.flags.actor === "string" ? scanned.flags.actor : undefined;
172
+ return {
173
+ command,
174
+ flags: scanned.flags,
175
+ positionals: scanned.positionals,
176
+ stdin,
177
+ output,
178
+ ...(actor === undefined ? {} : { actor }),
179
+ };
222
180
  }
223
181
  function invocationOptions(argv) {
224
182
  let cwd;
@@ -1,13 +1,13 @@
1
1
  import type { LiveStatusObservation } from "../../akuma/akuma-observe.js";
2
2
  import type { TellResult } from "../../akuma/body.js";
3
3
  import type { AkuId } from "../../akuma/identity.js";
4
- import type { AkumaAskResult, AkumaKillResult, AkumaObservation, AkumaTellResult, AkumaWaitResult } from "../../akuma/selection-observation.js";
4
+ import type { AkumaAskResult, AkumaKillResult, AkumaTellResult } from "../../akuma/selection-observation.js";
5
5
  import type { CallWaitHead, ForkResult } from "../../index.js";
6
6
  import type { CallResult } from "../../library/akuma-creation.js";
7
7
  import type { AkumaHistoryResult } from "../../library/selection.js";
8
8
  import { type ObservedCallHead } from "./akuma-activity.js";
9
9
  import { type TextRenderContext } from "./terminal.js";
10
- export type AskProgress = Readonly<{
10
+ type AskProgress = Readonly<{
11
11
  admitted: (tell: TellResult, id: AkuId) => readonly string[];
12
12
  observe: (observation: LiveStatusObservation) => readonly string[];
13
13
  frame: () => readonly string[];
@@ -21,20 +21,6 @@ export declare function callObservationHead(input: Readonly<{
21
21
  akuma: string;
22
22
  }> & CallWaitHead): ObservedCallHead;
23
23
  export declare function renderCallText(result: CallResult, streamed: boolean, context: TextRenderContext): string;
24
- export declare function renderWaitText(result: AkumaWaitResult, presentation: Readonly<{
25
- alias?: string;
26
- startedAt?: number;
27
- selection?: readonly import("./akuma-activity.js").WaitSelectedIdentity[];
28
- }>, context?: TextRenderContext): string;
29
- export declare function renderStatusText(status: AkumaObservation, alias: string | undefined, context?: TextRenderContext): string;
30
- export declare function renderTellText(result: AkumaTellResult, alias: string | undefined, context?: TextRenderContext, options?: Readonly<{
31
- identity?: boolean;
32
- }>): string;
33
- export declare function renderHistoryText(result: AkumaHistoryResult, presentation: Readonly<{
34
- alias?: string;
35
- id?: string;
36
- last?: boolean;
37
- }>, context?: TextRenderContext): string;
38
24
  export declare function renderForkText(receipt: ForkResult): string;
39
25
  export declare function renderKillText(result: AkumaKillResult, alias: string | undefined, context: TextRenderContext): string;
40
26
  export declare function callExitCode(result: CallResult): number;
@@ -43,3 +29,4 @@ export declare function tellExitCode(result: AkumaTellResult): number;
43
29
  export declare function askExitCode(result: AkumaAskResult): number;
44
30
  export declare function forkExitCode(receipt: ForkResult): number;
45
31
  export declare function historyExitCode(result: AkumaHistoryResult, id: string | undefined): number;
32
+ export {};
@@ -1,4 +1,4 @@
1
- import { DEFAULT_CONTEXT, associatedIdentity, historyText, inputWaitStream, killResultText, snapshotHeading, snapshotText, tellText, waitText, } from "./akuma-activity.js";
1
+ import { associatedIdentity, inputWaitStream, killResultText, snapshotHeading, tellText, } from "./akuma-activity.js";
2
2
  import { safeText } from "./terminal.js";
3
3
  export function askProgressStream(akuma, alias, context) {
4
4
  let target = akuma;
@@ -94,18 +94,6 @@ export function renderCallText(result, streamed, context) {
94
94
  ...(inputObservation.completedAt === undefined ? {} : { completedAt: inputObservation.completedAt }),
95
95
  });
96
96
  }
97
- export function renderWaitText(result, presentation, context = DEFAULT_CONTEXT) {
98
- return waitText(result, presentation, context);
99
- }
100
- export function renderStatusText(status, alias, context = DEFAULT_CONTEXT) {
101
- return snapshotText(status, context, ...(alias === undefined ? [{}] : [{ alias }]));
102
- }
103
- export function renderTellText(result, alias, context = DEFAULT_CONTEXT, options = {}) {
104
- return tellText(result, alias, context, options);
105
- }
106
- export function renderHistoryText(result, presentation, context = DEFAULT_CONTEXT) {
107
- return historyText(result, presentation, context);
108
- }
109
97
  export function renderForkText(receipt) {
110
98
  if (receipt.kind !== "forked") {
111
99
  if (receipt.kind === "unknown-history")
@@ -110,7 +110,7 @@ function targetLines(report, columns, addressed, abbreviations) {
110
110
  }
111
111
  function obligationLines(result, columns) {
112
112
  return [
113
- ...executionCleanupLines(effectCleanup(result.effects).filter((issue) => issue.kind !== "worktree-leak"), columns, result.contract),
113
+ ...executionCleanupLines(effectCleanup(result.effects), columns, result.contract),
114
114
  ...executionStopLines(effectExecutionStops(result.effects), columns),
115
115
  ];
116
116
  }
@@ -187,7 +187,7 @@ function acceptedLagRows(result, columns) {
187
187
  receiptRow(obligations, "!", "settlement owner", [{ text: contract, opaque: true }], columns);
188
188
  pushBlock(obligations, settlementLagRows(lag, columns));
189
189
  }
190
- pushBlock(obligations, executionCleanupLines(effectCleanup(result.effects).filter((issue) => issue.kind !== "worktree-leak"), columns, result.contract));
190
+ pushBlock(obligations, executionCleanupLines(effectCleanup(result.effects), columns, result.contract));
191
191
  pushBlock(obligations, executionStopLines(effectExecutionStops(result.effects), columns));
192
192
  return obligations;
193
193
  }
@@ -205,21 +205,6 @@ function recordBlock(result, columns) {
205
205
  const rows = [...acceptedRecord(result, columns), ...acceptedLagRows(result, columns)];
206
206
  return rows;
207
207
  }
208
- function nonGatingVerificationLines(result, columns) {
209
- const lines = [];
210
- const verification = result.value.completion?.verification;
211
- if (verification === undefined || verification.verdict !== "unsatisfied")
212
- return lines;
213
- receiptRow(lines, "!", "verification", [
214
- ...(verification.mode === "reused" ? [{ text: "reused" }] : []),
215
- { text: "unsatisfied" },
216
- { text: "· not required by Contract gates" },
217
- ], columns);
218
- if (result.value.verificationSummary !== undefined) {
219
- receiptPayload(lines, " summary", result.value.verificationSummary);
220
- }
221
- return lines;
222
- }
223
208
  /** A terminal command names the worktree it retired, or the retained worktree it failed to remove. */
224
209
  function worktreeRetirementLines(result, columns) {
225
210
  const lines = [];
@@ -281,15 +266,15 @@ function completedPlacementLines(result, columns) {
281
266
  { text: completion.target, opaque: true },
282
267
  ], columns);
283
268
  }
284
- if (completion.verification?.verdict === "satisfied") {
269
+ const verification = result.value.verification;
270
+ if (verification?.kind !== "stopped" && verification?.verdict === "satisfied") {
285
271
  receiptRow(lines, " ", "integration result", [
286
272
  {
287
- text: `${displayGitId(completion.integration, abbreviations)} · verification ${completion.verification.mode === "reused" ? "reused " : ""}satisfied`,
273
+ text: `${displayGitId(completion.integration, abbreviations)} · verification ${verification.kind === "reused" ? "reused " : ""}satisfied`,
288
274
  },
289
275
  ], columns);
290
276
  }
291
277
  lines.push(...landedChangesLines(completion.scope, columns));
292
- lines.push(...nonGatingVerificationLines(result, columns));
293
278
  // Placement admission always admits the claim entry beside the movement, so a completed placement is accepted.
294
279
  receiptRow(lines, "✓", lifecycleWord("claimed"), [], columns);
295
280
  return lines;
@@ -372,33 +357,50 @@ function deliverIdentityLines(result, abbreviations, columns, kept) {
372
357
  receiptRow(lines, " ", "candidate", [{ text: `${displayGitId(result.value.tenderSnapshot, abbreviations)}${kept ? " · kept" : ""}`, opaque: true }], columns);
373
358
  if (result.value.integration !== undefined && !/^0{40}$/u.test(result.value.integration.changeId))
374
359
  receiptRow(lines, " ", "content identity", [{ text: displayGitId(result.value.integration.changeId, abbreviations), opaque: true }], columns);
360
+ if (result.value.contentChange !== undefined)
361
+ receiptRow(lines, " ", "candidate-content-changed", [
362
+ { text: `previous ${displayGitId(result.value.contentChange.previousChange, abbreviations)}`, opaque: true },
363
+ { text: `current ${displayGitId(result.value.contentChange.currentChange, abbreviations)}`, opaque: true },
364
+ ], columns);
365
+ if (result.value.note !== undefined)
366
+ receiptPayload(lines, "note", result.value.note);
367
+ const reusedIntegration = result.value.leading.reusedIntegration;
368
+ if (reusedIntegration !== undefined)
369
+ receiptRow(lines, " ", "integration", [{ text: `${displayGitId(reusedIntegration, abbreviations)} reused · commit message kept from first delivery` }], columns);
375
370
  return lines;
376
371
  }
372
+ function deliveryIdentityAbbreviations(value, verificationSnapshot) {
373
+ return abbreviateGitIds([
374
+ value.tenderSnapshot ?? "",
375
+ value.integration?.changeId ?? "",
376
+ value.integration.snapshot,
377
+ value.contentChange?.previousChange ?? "",
378
+ value.contentChange?.currentChange ?? "",
379
+ verificationSnapshot ?? "",
380
+ value.completion?.predecessor ?? "",
381
+ value.completion?.integration ?? "",
382
+ ]);
383
+ }
377
384
  function renderAcceptedDeliver(result, columns) {
378
385
  const complete = result.value.completion !== undefined;
386
+ const verification = result.value.verification;
387
+ const subject = verification?.kind === "stopped" ? undefined : verification;
379
388
  const lines = titleLines("✓", "delivered", result.contract, columns);
380
- const abbreviations = abbreviateGitIds([
381
- result.value.tenderSnapshot ?? "",
382
- result.value.integration?.changeId ?? "",
383
- result.value.verificationSubject?.snapshot ?? "",
384
- result.value.completion?.predecessor ?? "",
385
- result.value.completion?.integration ?? "",
386
- ]);
389
+ const abbreviations = deliveryIdentityAbbreviations(result.value, subject?.snapshot);
387
390
  lines.push(...deliverIdentityLines(result, abbreviations, columns, !complete));
388
391
  if (complete)
389
392
  lines.push(...completedPlacementLines(result, columns));
390
393
  else {
391
- const subject = result.value.verificationSubject;
392
394
  if (subject !== undefined)
393
395
  receiptRow(lines, " ", "integration result", [
394
396
  {
395
- text: `${displayGitId(subject.snapshot, abbreviations)} · verification ${subject.mode === "reused" ? "reused " : ""}${subject.verdict}`,
397
+ text: `${displayGitId(subject.snapshot, abbreviations)} · verification ${subject.kind === "reused" ? "reused " : ""}${subject.verdict}`,
396
398
  },
397
399
  ], columns);
398
400
  lines.push(...movementLines(result, columns));
399
401
  }
400
- if (result.value.verification !== undefined)
401
- lines.push(...stopLines(result.value.verification, columns, result.contract));
402
+ if (verification?.kind === "stopped")
403
+ lines.push(...stopLines(verification.stop, columns, result.contract));
402
404
  if (!complete && result.value.placement !== undefined)
403
405
  lines.push(...stopLines(result.value.placement, columns, result.contract));
404
406
  lines.push(...continuationLines(result, columns), ...(complete ? obligationLines(result, columns) : recordBlock(result, columns)), ...worktreeRetirementLines(result, columns), ...gatesAwaitLines(result.value.placement));
@@ -407,8 +409,8 @@ function renderAcceptedDeliver(result, columns) {
407
409
  function renderAcceptedReview(result, columns) {
408
410
  const lines = titleLines("✓", `review ${attestationVerdict(result.facts)}`, result.contract, columns);
409
411
  lines.push(...completedPlacementLines(result, columns));
410
- if (result.value.verification !== undefined) {
411
- lines.push(...stopLines(result.value.verification, columns, result.contract));
412
+ if (result.value.verification?.kind === "stopped") {
413
+ lines.push(...stopLines(result.value.verification.stop, columns, result.contract));
412
414
  }
413
415
  if (result.value.placement !== undefined) {
414
416
  lines.push(...stopLines(result.value.placement, columns, result.contract));
@@ -1,7 +1,13 @@
1
- import type { KanshiReport } from "../../kanshi/index.js";
1
+ import type { AkumaKanshiWorld, KanshiReport, Section } from "../../kanshi/index.js";
2
2
  import { type TextRenderContext } from "./terminal.js";
3
3
  declare const NARROW_COLUMNS = 72;
4
4
  declare function endpointFact(id: string, observed: string | undefined): string;
5
+ /**
6
+ * One Akuma board section. The World board omits an empty section because its other
7
+ * sections already say what the World holds; a category board states that emptiness
8
+ * itself, since it is the whole answer.
9
+ */
10
+ declare function renderAkumaBoard(section: Section<AkumaKanshiWorld>, observedAt: string, context: TextRenderContext, emptyRows: readonly string[]): readonly string[];
5
11
  declare function renderAkuma(report: KanshiReport, context: TextRenderContext): readonly string[];
6
12
  declare function formatAge(source: string | null | undefined, observedAt: string): string;
7
- export { endpointFact, formatAge, NARROW_COLUMNS, renderAkuma };
13
+ export { endpointFact, formatAge, NARROW_COLUMNS, renderAkuma, renderAkumaBoard };