@astrosheep/keiyaku 4.0.4 → 4.0.6

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 (233) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +15 -7
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -3
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +24 -4
  8. package/build/src/akuma/akuma.d.ts +2 -1
  9. package/build/src/akuma/akuma.js +27 -9
  10. package/build/src/akuma/allowed.d.ts +1 -1
  11. package/build/src/akuma/allowed.js +3 -10
  12. package/build/src/akuma/archetype.d.ts +3 -1
  13. package/build/src/akuma/archetype.js +11 -6
  14. package/build/src/akuma/body-turn.d.ts +64 -0
  15. package/build/src/akuma/body-turn.js +449 -0
  16. package/build/src/akuma/body.d.ts +4 -5
  17. package/build/src/akuma/body.js +9 -414
  18. package/build/src/akuma/heart/facts.d.ts +37 -9
  19. package/build/src/akuma/heart/facts.js +3 -1
  20. package/build/src/akuma/heart/index.d.ts +4 -13
  21. package/build/src/akuma/heart/index.js +14 -135
  22. package/build/src/akuma/heart/request-authority.d.ts +12 -0
  23. package/build/src/akuma/heart/request-authority.js +119 -0
  24. package/build/src/akuma/heart/request-rows.d.ts +16 -0
  25. package/build/src/akuma/heart/request-rows.js +88 -0
  26. package/build/src/akuma/heart/rows.d.ts +1 -28
  27. package/build/src/akuma/heart/rows.js +4 -138
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +11 -3
  30. package/build/src/akuma/heart/soul.js +0 -36
  31. package/build/src/akuma/heart/timeline.d.ts +1 -0
  32. package/build/src/akuma/heart/timeline.js +19 -0
  33. package/build/src/akuma/index.d.ts +1 -1
  34. package/build/src/akuma/nuke.d.ts +2 -0
  35. package/build/src/akuma/nuke.js +152 -0
  36. package/build/src/akuma/provider-recipe.js +1 -11
  37. package/build/src/akuma/provider.d.ts +4 -7
  38. package/build/src/akuma/providers/acp/config.d.ts +8 -0
  39. package/build/src/akuma/providers/acp/config.js +37 -0
  40. package/build/src/akuma/providers/acp/core.js +12 -2
  41. package/build/src/akuma/providers/acp/index.d.ts +1 -8
  42. package/build/src/akuma/providers/acp/index.js +2 -38
  43. package/build/src/akuma/providers/claude/index.d.ts +0 -4
  44. package/build/src/akuma/providers/claude/index.js +12 -3
  45. package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
  46. package/build/src/akuma/providers/codex-app-server/index.js +5 -2
  47. package/build/src/akuma/providers/grok-build/index.js +1 -2
  48. package/build/src/akuma/providers/index.d.ts +3 -2
  49. package/build/src/akuma/providers/index.js +36 -36
  50. package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
  51. package/build/src/akuma/providers/opencode-sdk/index.js +14 -4
  52. package/build/src/akuma/providers/opencode-sdk/session.d.ts +2 -2
  53. package/build/src/akuma/providers/opencode-sdk/session.js +2 -2
  54. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  55. package/build/src/akuma/providers/pi/index.js +29 -6
  56. package/build/src/akuma/request-serve.d.ts +88 -0
  57. package/build/src/akuma/request-serve.js +484 -0
  58. package/build/src/akuma/request-wire.d.ts +125 -0
  59. package/build/src/akuma/request-wire.js +383 -0
  60. package/build/src/akuma/requests.d.ts +28 -94
  61. package/build/src/akuma/requests.js +52 -562
  62. package/build/src/akuma-body.d.ts +7 -0
  63. package/build/src/akuma-body.js +69 -2
  64. package/build/src/alias/index.d.ts +1 -0
  65. package/build/src/alias/index.js +34 -1
  66. package/build/src/body/arc.js +4 -29
  67. package/build/src/body/decode.js +5 -39
  68. package/build/src/body/envelope.d.ts +7 -0
  69. package/build/src/body/envelope.js +37 -0
  70. package/build/src/cli/accepted.js +21 -9
  71. package/build/src/cli/commands/akuma-invoke.js +1 -0
  72. package/build/src/cli/commands/akuma.d.ts +1 -0
  73. package/build/src/cli/commands/akuma.js +13 -10
  74. package/build/src/cli/commands/contract.d.ts +28 -17
  75. package/build/src/cli/commands/contract.js +23 -17
  76. package/build/src/cli/commands/install.d.ts +2 -2
  77. package/build/src/cli/commands/install.js +6 -6
  78. package/build/src/cli/commands/nuke.d.ts +10 -0
  79. package/build/src/cli/commands/nuke.js +20 -0
  80. package/build/src/cli/commands/task-invoke.d.ts +15 -0
  81. package/build/src/cli/commands/task-invoke.js +144 -24
  82. package/build/src/cli/commands/task-query.d.ts +2 -2
  83. package/build/src/cli/commands/task-query.js +1 -2
  84. package/build/src/cli/commands/task.js +22 -22
  85. package/build/src/cli/coordinates.d.ts +6 -2
  86. package/build/src/cli/coordinates.js +12 -56
  87. package/build/src/cli/invoke.d.ts +5 -4
  88. package/build/src/cli/invoke.js +112 -58
  89. package/build/src/cli/main.d.ts +0 -2
  90. package/build/src/cli/main.js +4 -140
  91. package/build/src/cli/parse.d.ts +17 -4
  92. package/build/src/cli/parse.js +93 -15
  93. package/build/src/cli/render/akuma.js +111 -53
  94. package/build/src/cli/render/audit.js +2 -6
  95. package/build/src/cli/render/contract.js +61 -20
  96. package/build/src/cli/render/kanshi.js +15 -5
  97. package/build/src/cli/render/nuke.d.ts +3 -0
  98. package/build/src/cli/render/nuke.js +8 -0
  99. package/build/src/cli/render/receipt.js +28 -1
  100. package/build/src/cli/render/refusal.d.ts +2 -1
  101. package/build/src/cli/render/refusal.js +31 -0
  102. package/build/src/cli/render/terminal.d.ts +0 -2
  103. package/build/src/cli/render/terminal.js +0 -29
  104. package/build/src/cli/render/text.js +6 -1
  105. package/build/src/cli/result.d.ts +36 -9
  106. package/build/src/cli/runtime.d.ts +2 -0
  107. package/build/src/cli/runtime.js +140 -0
  108. package/build/src/cli/usage.d.ts +0 -2
  109. package/build/src/cli/usage.js +0 -4
  110. package/build/src/contract-worktree.d.ts +29 -14
  111. package/build/src/contract-worktree.js +131 -70
  112. package/build/src/core/facts/codec.js +9 -0
  113. package/build/src/core/facts/fold.js +13 -1
  114. package/build/src/core/facts/types.d.ts +8 -1
  115. package/build/src/core/subject.js +4 -3
  116. package/build/src/core/verbs/placement.d.ts +9 -1
  117. package/build/src/core/verbs/placement.js +24 -6
  118. package/build/src/core/verbs/reintegrate.d.ts +13 -0
  119. package/build/src/core/verbs/reintegrate.js +24 -0
  120. package/build/src/dispatch/index.d.ts +1 -1
  121. package/build/src/git/admission.d.ts +2 -1
  122. package/build/src/git/hooks.d.ts +2 -0
  123. package/build/src/git/hooks.js +34 -1
  124. package/build/src/git/integration.d.ts +9 -2
  125. package/build/src/git/integration.js +92 -1
  126. package/build/src/git/nuke.d.ts +2 -0
  127. package/build/src/git/nuke.js +97 -0
  128. package/build/src/git/observe.d.ts +2 -1
  129. package/build/src/git/observe.js +6 -5
  130. package/build/src/git/process.d.ts +28 -0
  131. package/build/src/git/process.js +94 -0
  132. package/build/src/git/read-observation.d.ts +2 -1
  133. package/build/src/git/read-observation.js +3 -2
  134. package/build/src/git/reconcile.d.ts +4 -1
  135. package/build/src/git/reconcile.js +42 -8
  136. package/build/src/git/repository.d.ts +2 -29
  137. package/build/src/git/repository.js +7 -118
  138. package/build/src/git/scratch.d.ts +1 -1
  139. package/build/src/git/scratch.js +1 -1
  140. package/build/src/git/target-placement.d.ts +3 -2
  141. package/build/src/git/target-placement.js +15 -14
  142. package/build/src/git/tender.d.ts +2 -1
  143. package/build/src/git/tender.js +4 -3
  144. package/build/src/git/terminal-seal.d.ts +2 -2
  145. package/build/src/git/terminal-seal.js +3 -6
  146. package/build/src/git/workspace.d.ts +4 -1
  147. package/build/src/git/workspace.js +1 -1
  148. package/build/src/index.d.ts +1 -2
  149. package/build/src/index.js +1 -1
  150. package/build/src/kanshi/read.js +5 -1
  151. package/build/src/library/address.js +7 -1
  152. package/build/src/library/akuma-creation.d.ts +1 -0
  153. package/build/src/library/akuma-creation.js +8 -1
  154. package/build/src/library/audit.d.ts +3 -1
  155. package/build/src/library/audit.js +2 -1
  156. package/build/src/library/bind.d.ts +2 -1
  157. package/build/src/library/bind.js +1 -1
  158. package/build/src/library/configuration.d.ts +1 -1
  159. package/build/src/library/configuration.js +52 -18
  160. package/build/src/library/contract.d.ts +59 -4
  161. package/build/src/library/contract.js +195 -34
  162. package/build/src/library/delivery.d.ts +4 -2
  163. package/build/src/library/fleet.d.ts +27 -7
  164. package/build/src/library/fleet.js +79 -39
  165. package/build/src/library/input.d.ts +0 -1
  166. package/build/src/library/input.js +0 -5
  167. package/build/src/library/keiyaku.d.ts +6 -2
  168. package/build/src/library/keiyaku.js +2 -0
  169. package/build/src/library/mutation.d.ts +3 -1
  170. package/build/src/library/mutation.js +3 -0
  171. package/build/src/library/nuke.d.ts +14 -0
  172. package/build/src/library/nuke.js +54 -0
  173. package/build/src/library/reconcile.d.ts +2 -1
  174. package/build/src/library/reconcile.js +8 -3
  175. package/build/src/library/refusal.d.ts +10 -1
  176. package/build/src/library/region.d.ts +1 -1
  177. package/build/src/library/repo.d.ts +4 -1
  178. package/build/src/library/repo.js +10 -4
  179. package/build/src/protocol/abandon.d.ts +9 -0
  180. package/build/src/protocol/abandon.js +15 -0
  181. package/build/src/protocol/amend.d.ts +16 -0
  182. package/build/src/protocol/amend.js +77 -0
  183. package/build/src/protocol/arc.d.ts +6 -0
  184. package/build/src/protocol/arc.js +12 -0
  185. package/build/src/protocol/attempt.d.ts +2 -1
  186. package/build/src/protocol/audit.d.ts +53 -0
  187. package/build/src/protocol/audit.js +147 -0
  188. package/build/src/protocol/bind.d.ts +1 -1
  189. package/build/src/protocol/completion.d.ts +42 -0
  190. package/build/src/protocol/completion.js +183 -0
  191. package/build/src/protocol/deliver.d.ts +49 -0
  192. package/build/src/protocol/deliver.js +261 -0
  193. package/build/src/protocol/intent.d.ts +2 -1
  194. package/build/src/protocol/intent.js +8 -2
  195. package/build/src/protocol/operations.d.ts +93 -202
  196. package/build/src/protocol/operations.js +23 -642
  197. package/build/src/protocol/placement.d.ts +12 -13
  198. package/build/src/protocol/placement.js +8 -19
  199. package/build/src/protocol/read/status.d.ts +17 -5
  200. package/build/src/protocol/read/status.js +57 -13
  201. package/build/src/protocol/reconcile.d.ts +35 -0
  202. package/build/src/protocol/reconcile.js +41 -0
  203. package/build/src/protocol/reintegrate.d.ts +31 -0
  204. package/build/src/protocol/reintegrate.js +74 -0
  205. package/build/src/protocol/review.d.ts +34 -0
  206. package/build/src/protocol/review.js +156 -0
  207. package/build/src/protocol/run.d.ts +1 -1
  208. package/build/src/runtime/proc/run.js +9 -5
  209. package/build/src/settlement/fence.d.ts +3 -1
  210. package/build/src/settlement/fence.js +24 -0
  211. package/build/src/settlement/holder.d.ts +1 -1
  212. package/build/src/settlement/settle.d.ts +1 -1
  213. package/build/src/settlement/settle.js +1 -2
  214. package/build/src/task/board.d.ts +0 -1
  215. package/build/src/task/board.js +0 -3
  216. package/build/src/task/compose.d.ts +2 -2
  217. package/build/src/task/compose.js +13 -11
  218. package/build/src/task/context.d.ts +14 -2
  219. package/build/src/task/context.js +30 -7
  220. package/build/src/task/index.d.ts +7 -6
  221. package/build/src/task/index.js +17 -145
  222. package/build/src/task/input.d.ts +18 -0
  223. package/build/src/task/input.js +189 -0
  224. package/build/src/task/mutation.d.ts +44 -0
  225. package/build/src/task/mutation.js +93 -0
  226. package/build/src/task/operations.d.ts +14 -6
  227. package/build/src/task/operations.js +57 -57
  228. package/build/src/task/store.d.ts +1 -0
  229. package/build/src/task/store.js +91 -3
  230. package/build/src/verification/execution.d.ts +1 -1
  231. package/build/src/workspace-place.d.ts +3 -4
  232. package/build/src/workspace-place.js +26 -15
  233. package/package.json +3 -3
@@ -85,8 +85,13 @@ function targetFacts(row) {
85
85
  }
86
86
  function workspaceState(row) {
87
87
  const observation = row.workspaceObservation;
88
+ if (row.workspace === "here" && observation.kind === "failed") {
89
+ return `workspace here · failed · ${observation.diagnostic}`;
90
+ }
88
91
  if (row.workspace === "here")
89
92
  return `workspace here · ${observation.kind}`;
93
+ if (observation.kind === "failed")
94
+ return `worktree unavailable · ${observation.diagnostic}`;
90
95
  if (observation.kind === "unappointed")
91
96
  return "worktree unappointed";
92
97
  if (observation.kind === "unavailable")
@@ -106,7 +111,7 @@ function showWorkspacePath(row, hot) {
106
111
  return false;
107
112
  if (row.workspaceObservation.kind === "unappointed")
108
113
  return false;
109
- if (row.workspaceObservation.kind !== "clean")
114
+ if (row.workspaceObservation.kind !== "clean" && row.workspaceObservation.kind !== "failed")
110
115
  return true;
111
116
  return hot;
112
117
  }
@@ -219,13 +224,15 @@ function renderContractRow(row, report, context, selection) {
219
224
  const compact = !hot && selection !== "contract";
220
225
  const title = row.title ?? "title unavailable";
221
226
  const phase = `${row.phase} · ${formatAge(row.phaseAt, report.observedAt)}`;
227
+ const journal = `journal ${formatAge(row.lastJournalAt, report.observedAt)}`;
222
228
  const lines = [identityLine(contractMark(row), row.id)];
223
- lines.push(...plumbFacts(compact ? [title, phase, ...targetFacts(row)] : [title], context.columns));
229
+ lines.push(...plumbFacts(compact ? [title, phase, journal, ...targetFacts(row)] : [title], context.columns));
224
230
  if (!compact)
225
- lines.push(...plumbFacts([phase, ...targetFacts(row)], context.columns));
231
+ lines.push(...plumbFacts([phase, journal, ...targetFacts(row)], context.columns));
226
232
  lines.push(...plumbFacts([workspaceState(row)], context.columns));
227
233
  if (showWorkspacePath(row, hot || selection === "contract")
228
234
  && row.workspaceObservation.kind !== "unappointed"
235
+ && row.workspaceObservation.kind !== "failed"
229
236
  && row.workspaceObservation.location.kind === "worktree") {
230
237
  lines.push(plumbPath(row.workspaceObservation.location.path));
231
238
  }
@@ -320,9 +327,12 @@ function renderAkuma(report, context) {
320
327
  lines.push(identityLine(akumaMark(row.life), row.id, akumaLabel(row)));
321
328
  const lifeAt = "lifeAt" in row ? row.lifeAt : null;
322
329
  const life = `${row.life} · ${formatAge(lifeAt, report.observedAt)}`;
330
+ const activity = "lastActivityAt" in row && row.lastActivityAt !== null
331
+ ? [`activity ${formatAge(row.lastActivityAt, report.observedAt)}`]
332
+ : [];
323
333
  const key = row.life === "stranded" && "strandedReason" in row && row.strandedReason === "resume-unsupported"
324
- ? [life, "resume unsupported"]
325
- : [life];
334
+ ? [life, ...activity, "resume unsupported"]
335
+ : [life, ...activity];
326
336
  const relation = row.contract === undefined
327
337
  ? ["unbound"]
328
338
  : [endpointFact(row.contract.id, row.contract.observed)];
@@ -0,0 +1,3 @@
1
+ import type { NukeResult } from "../../index.js";
2
+ export declare function renderNukeText(result: NukeResult): string;
3
+ export declare function nukeExitCode(result: NukeResult): number;
@@ -0,0 +1,8 @@
1
+ export function renderNukeText(result) {
2
+ return result.kind === "success"
3
+ ? `nuke success ${result.world}`
4
+ : `nuke failed ${result.world}\n${result.diagnostic}`;
5
+ }
6
+ export function nukeExitCode(result) {
7
+ return result.kind === "failed" ? 2 : 0;
8
+ }
@@ -59,6 +59,32 @@ export function reuseLines(reuse, columns) {
59
59
  return [];
60
60
  return renderOpaqueBlock(`reuse verification ${reuse.entry} ${reuse.verdict}`, " ", columns);
61
61
  }
62
+ function prerequisiteRows(stop, columns) {
63
+ if (!("refusal" in stop) || stop.refusal?.kind !== "prerequisites-unsatisfied")
64
+ return [];
65
+ const lines = [];
66
+ for (const prerequisite of stop.refusal.unmet) {
67
+ receiptRow(lines, " ", "prerequisite", [
68
+ { text: prerequisite.contractId, opaque: true },
69
+ { text: "·" },
70
+ { text: prerequisite.state },
71
+ ], columns);
72
+ }
73
+ return lines;
74
+ }
75
+ function targetMovedDetail(stop) {
76
+ if ("integratedAt" in stop) {
77
+ return [
78
+ { text: stop.target, opaque: true },
79
+ { text: `${stop.integratedAt} -> ${stop.observed}`, opaque: true },
80
+ { text: `attempts=${stop.attempts}` },
81
+ ];
82
+ }
83
+ return [
84
+ { text: stop.target, opaque: true },
85
+ { text: `${stop.expected} -> ${stop.observed}`, opaque: true },
86
+ ];
87
+ }
62
88
  export function stopLines(label, stop, columns, addressed) {
63
89
  const detail = [];
64
90
  if ("refusal" in stop && stop.refusal !== undefined) {
@@ -76,12 +102,13 @@ export function stopLines(label, stop, columns, addressed) {
76
102
  detail.push({ text: `command=${stop.command}` }, { text: hookFailureSummary(stop.detail), opaque: true });
77
103
  }
78
104
  else if (stop.failure === "target-moved") {
79
- detail.push({ text: stop.target, opaque: true }, { text: `${stop.expected} -> ${stop.observed}`, opaque: true });
105
+ detail.push(...targetMovedDetail(stop));
80
106
  }
81
107
  }
82
108
  const lines = [];
83
109
  const state = label === "verification" ? "failed" : "blocked";
84
110
  receiptRow(lines, "!", label, [{ text: state }, { text: "·" }, ...detail], columns);
111
+ lines.push(...prerequisiteRows(stop, columns));
85
112
  if ("failure" in stop && stop.failure === "environment-failure" && "command" in stop) {
86
113
  appendHookPayload(lines, stop.detail);
87
114
  }
@@ -1,5 +1,5 @@
1
1
  import type { BindDraftReceipt, RefusedResult } from "../result.js";
2
- import type { KeiyakuRefusal } from "../../index.js";
2
+ import type { IntegrationConflictMaterialized, KeiyakuRefusal } from "../../index.js";
3
3
  import { type TextRenderContext } from "./terminal.js";
4
4
  type DirtyWithOption = Extract<KeiyakuRefusal, {
5
5
  kind: "dirty-workspace";
@@ -12,5 +12,6 @@ type DirtyWithOption = Extract<KeiyakuRefusal, {
12
12
  export type RenderableRefusal = KeiyakuRefusal | DirtyWithOption;
13
13
  export declare function renderRefusalFacts(refusal: RenderableRefusal, indent: string, columns: number, addressed?: string): readonly string[];
14
14
  export declare function renderRefusal(result: RefusedResult, context?: TextRenderContext): string;
15
+ export declare function renderConflictMaterialized(result: IntegrationConflictMaterialized, context?: TextRenderContext): string;
15
16
  export declare function renderBindDraftReceipt(receipt: BindDraftReceipt): string;
16
17
  export {};
@@ -38,6 +38,18 @@ function renderDirtyRefusal(refusal, indent, columns, identity) {
38
38
  }
39
39
  export function renderRefusalFacts(refusal, indent, columns, addressed) {
40
40
  const identity = refusalIdentity(refusal, addressed);
41
+ if (refusal.kind === "nuke-confirmation-mismatch") {
42
+ return [
43
+ ...renderOpaqueBlock(`nuke confirmation mismatch world=${refusal.world} confirmation=${refusal.confirmation}`, indent, columns),
44
+ ...renderOpaqueBlock(`keiyaku nuke --confirm ${refusal.world}`, indent, columns),
45
+ ];
46
+ }
47
+ if (refusal.kind === "nuke-confirmation-required") {
48
+ return [
49
+ ...renderOpaqueBlock(`nuke confirmation required world=${refusal.world}`, indent, columns),
50
+ ...renderOpaqueBlock(`keiyaku nuke --confirm ${refusal.world}`, indent, columns),
51
+ ];
52
+ }
41
53
  if (refusal.kind === "dirty-workspace")
42
54
  return renderDirtyRefusal(refusal, indent, columns, identity);
43
55
  if (refusal.kind === "integration-failed") {
@@ -46,8 +58,18 @@ export function renderRefusalFacts(refusal, indent, columns, addressed) {
46
58
  ];
47
59
  if (refusal.conflictPaths !== undefined)
48
60
  lines.push(...collectionLines("conflictPaths", refusal.conflictPaths, indent, columns));
61
+ if ("recovery" in refusal && refusal.recovery !== undefined) {
62
+ wrap(lines, `recovery materialize conflicts · ${refusal.recovery.materialize}`, indent, columns);
63
+ wrap(lines, `recovery continue after resolve and commit · ${refusal.recovery.continue}`, indent, columns);
64
+ }
49
65
  return lines;
50
66
  }
67
+ if (refusal.kind === "merge-state-present") {
68
+ return renderOpaqueBlock(refusalHead(refusal.kind, identity, [
69
+ `workspace=${refusal.workspace.kind}`,
70
+ `path=${refusal.workspace.path}`,
71
+ ]), indent, columns);
72
+ }
51
73
  if (refusal.kind === "integration-unsupported") {
52
74
  return renderOpaqueBlock(refusalHead(refusal.kind, identity, [`requiredGit=${refusal.requiredGit}`]), indent, columns);
53
75
  }
@@ -81,6 +103,15 @@ export function renderRefusal(result, context) {
81
103
  const output = lines.join("\n");
82
104
  return result.draft === undefined ? output : `${output}\n${renderBindDraftReceipt(result.draft)}`;
83
105
  }
106
+ export function renderConflictMaterialized(result, context) {
107
+ const columns = context?.columns ?? 80;
108
+ const indent = " ";
109
+ return [
110
+ ...renderOpaqueBlock(`integration-conflict-materialized targetHead=${result.targetHead}`, "", columns),
111
+ ...collectionLines("conflictPaths", result.conflictPaths, indent, columns),
112
+ ...renderOpaqueBlock(`workspace ${result.workspace.kind} ${result.workspace.path}`, indent, columns),
113
+ ].join("\n");
114
+ }
84
115
  export function renderBindDraftReceipt(receipt) {
85
116
  return [
86
117
  ...(receipt.path === undefined ? [] : [`draft preserved: ${receipt.path}`]),
@@ -23,8 +23,6 @@ export declare function renderBoundedTextBlock(value: string, input: Readonly<{
23
23
  truncated?: boolean;
24
24
  }>): readonly string[];
25
25
  export declare function safeText(value: string): string;
26
- export declare function renderFacts(primary: string, facts: readonly string[], columns: number): readonly string[];
27
26
  export declare function renderTextBlock(value: string, indent: string, columns: number): readonly string[];
28
27
  export declare function renderOpaqueBlock(value: string, indent: string, columns: number): readonly string[];
29
- export declare function renderVoiceRuler(left: string, right: string, columns: number): string;
30
28
  export declare function tone(value: string, kind: "dim" | "alert", color: boolean): string;
@@ -110,28 +110,6 @@ export function renderBoundedTextBlock(value, input) {
110
110
  export function safeText(value) {
111
111
  return value.replaceAll(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu, (character) => /\s/u.test(character) ? " " : "�");
112
112
  }
113
- export function renderFacts(primary, facts, columns) {
114
- const head = safeText(primary);
115
- const clean = facts.map(safeText);
116
- if (clean.length === 0)
117
- return [head];
118
- const inline = `${head} ${clean.join(" · ")}`;
119
- if (displayColumns(inline) <= columns)
120
- return [inline];
121
- const lines = [head];
122
- let current = " ";
123
- for (const fact of clean) {
124
- const candidate = current === " " ? `${current}${fact}` : `${current} · ${fact}`;
125
- if (current !== " " && displayColumns(candidate) > columns) {
126
- lines.push(current);
127
- current = ` ${fact}`;
128
- }
129
- else
130
- current = candidate;
131
- }
132
- lines.push(current);
133
- return lines;
134
- }
135
113
  export function renderTextBlock(value, indent, columns) {
136
114
  const words = safeText(value).trim().split(/\s+/u).filter((word) => word.length > 0);
137
115
  if (words.length === 0)
@@ -183,13 +161,6 @@ export function renderOpaqueBlock(value, indent, columns) {
183
161
  }
184
162
  return lines;
185
163
  }
186
- export function renderVoiceRuler(left, right, columns) {
187
- const width = Math.max(20, Math.min(80, columns));
188
- const occupied = displayColumns(left) + displayColumns(right) + 2;
189
- if (occupied >= width)
190
- return `${left}\n${"─".repeat(Math.max(1, width - displayColumns(right) - 1))} ${right}`;
191
- return `${left} ${"─".repeat(width - occupied)} ${right}`;
192
- }
193
164
  export function tone(value, kind, color) {
194
165
  if (!color)
195
166
  return value;
@@ -1,8 +1,9 @@
1
1
  import { renderObservation } from "./board.js";
2
2
  import { renderAccepted, renderContractHistory, renderRetry } from "./contract.js";
3
3
  import { renderKanshiText } from "./kanshi.js";
4
- import { renderRefusal } from "./refusal.js";
4
+ import { renderConflictMaterialized, renderRefusal } from "./refusal.js";
5
5
  import { renderCatalogText } from "./catalog.js";
6
+ import { renderNukeText } from "./nuke.js";
6
7
  import { renderRegionText } from "./region.js";
7
8
  export function renderText(result, context) {
8
9
  if (result.kind === "guidance")
@@ -15,11 +16,15 @@ export function renderText(result, context) {
15
16
  return renderContractHistory(result.history);
16
17
  if (result.kind === "region")
17
18
  return renderRegionText(result.region);
19
+ if (result.kind === "nuke")
20
+ return renderNukeText(result.result);
18
21
  if (result.kind === "accepted")
19
22
  return renderAccepted(result, context);
20
23
  if (result.kind === "refused")
21
24
  return renderRefusal(result, context);
22
25
  if (result.kind === "retry")
23
26
  return renderRetry(result, context);
27
+ if (result.kind === "integration-conflict-materialized")
28
+ return renderConflictMaterialized(result, context);
24
29
  return renderObservation(result);
25
30
  }
@@ -1,8 +1,9 @@
1
- import type { AuditReport, ContractHistory, ContractId, Fact, MutationResult, PlacementStop, ReconcileReport, Review, VerificationReuse, VerificationStop } from "../index.js";
1
+ import type { AuditReport, ContractHistory, ContractId, Delivery, Fact, IntegrationConflictMaterialized, MutationResult, PlacementStop, ReconcileReport, Review, VerificationReuse, VerificationStop } from "../index.js";
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
5
  import type { RegionObservation } from "../library/region.js";
6
+ import type { NukeResult } from "../index.js";
6
7
  export type BindDraftReceipt = Readonly<{
7
8
  path: string;
8
9
  warning?: string;
@@ -11,11 +12,19 @@ export type BindDraftReceipt = Readonly<{
11
12
  warning: string;
12
13
  }>;
13
14
  export type Effect = ReconcileReport["effects"][number];
14
- export type AcceptedFact = Readonly<{
15
+ type AcceptedFactEnvelope = Readonly<{
15
16
  contract: ContractId;
16
17
  entry: string;
17
- kind: Fact["kind"];
18
18
  }>;
19
+ export type AcceptedFact = (AcceptedFactEnvelope & Readonly<{
20
+ kind: Exclude<Fact["kind"], "reintegrated">;
21
+ data?: never;
22
+ }>) | (AcceptedFactEnvelope & Readonly<{
23
+ kind: "reintegrated";
24
+ data: Extract<Fact, {
25
+ kind: "reintegrated";
26
+ }>["data"];
27
+ }>);
19
28
  export type Lag = ReconcileReport["lag"][number];
20
29
  type MutationEnvelope = Pick<MutationResult<unknown>, "head" | "effects" | "settlement">;
21
30
  export type AcceptedEnvelope = Readonly<{
@@ -31,8 +40,10 @@ export type AcceptedBindResult = AcceptedEnvelope & Readonly<{
31
40
  verb: "bind";
32
41
  workspace: "worktree" | "here";
33
42
  target: string | null;
43
+ completion?: never;
34
44
  verification?: never;
35
45
  verificationReuse?: never;
46
+ verificationSummary?: never;
36
47
  placement?: never;
37
48
  cleanup?: never;
38
49
  leak?: never;
@@ -47,8 +58,10 @@ export type AcceptedAmendResult = AcceptedEnvelope & Readonly<{
47
58
  verb: "amend";
48
59
  diff: string;
49
60
  target?: never;
61
+ completion?: never;
50
62
  verification?: never;
51
63
  verificationReuse?: never;
64
+ verificationSummary?: never;
52
65
  placement?: never;
53
66
  cleanup?: never;
54
67
  leak?: never;
@@ -61,9 +74,11 @@ export type AcceptedAmendResult = AcceptedEnvelope & Readonly<{
61
74
  }> & RegionObservation;
62
75
  export type AcceptedDeliverResult = AcceptedEnvelope & Readonly<{
63
76
  verb: "deliver";
77
+ completion?: Delivery["completion"];
64
78
  verificationVerdict?: "satisfied" | "unsatisfied";
65
79
  verification?: VerificationStop;
66
80
  verificationReuse?: VerificationReuse;
81
+ verificationSummary?: string;
67
82
  placement?: PlacementStop;
68
83
  cleanup?: MutationResult<unknown>["cleanup"];
69
84
  leak?: MutationResult<unknown>["leak"];
@@ -80,18 +95,20 @@ export type AcceptedDeliverResult = AcceptedEnvelope & Readonly<{
80
95
  export type AcceptedReviewResult = AcceptedEnvelope & Readonly<{
81
96
  verb: "review";
82
97
  verdict: "satisfied" | "unsatisfied";
98
+ completion?: Delivery["completion"];
99
+ verificationVerdict?: "satisfied" | "unsatisfied";
100
+ verification?: VerificationStop;
101
+ verificationReuse?: VerificationReuse;
102
+ verificationSummary?: string;
83
103
  placement?: PlacementStop;
84
104
  workspace?: Review["workspace"];
105
+ cleanup?: MutationResult<unknown>["cleanup"];
106
+ leak?: MutationResult<unknown>["leak"];
85
107
  target?: never;
86
- verification?: never;
87
- verificationReuse?: never;
88
- cleanup?: never;
89
- leak?: never;
90
108
  overlaps?: never;
91
109
  overlapFailure?: never;
92
110
  report?: never;
93
111
  diff?: never;
94
- verificationVerdict?: never;
95
112
  chapter?: never;
96
113
  note?: never;
97
114
  }>;
@@ -102,8 +119,10 @@ export type AcceptedArcResult = AcceptedEnvelope & Readonly<{
102
119
  title: string;
103
120
  }>;
104
121
  target?: never;
122
+ completion?: never;
105
123
  verification?: never;
106
124
  verificationReuse?: never;
125
+ verificationSummary?: never;
107
126
  placement?: never;
108
127
  cleanup?: never;
109
128
  leak?: never;
@@ -120,8 +139,10 @@ export type AcceptedAbandonResult = AcceptedEnvelope & Readonly<{
120
139
  verb: "abandon";
121
140
  note?: string;
122
141
  target?: never;
142
+ completion?: never;
123
143
  verification?: never;
124
144
  verificationReuse?: never;
145
+ verificationSummary?: never;
125
146
  placement?: never;
126
147
  cleanup?: never;
127
148
  leak?: never;
@@ -140,8 +161,10 @@ export type AcceptedAuditResult = AcceptedEnvelope & Readonly<{
140
161
  cleanup?: MutationResult<unknown>["cleanup"];
141
162
  leak?: MutationResult<unknown>["leak"];
142
163
  target?: never;
164
+ completion?: never;
143
165
  verification?: never;
144
166
  verificationReuse?: never;
167
+ verificationSummary?: never;
145
168
  placement?: never;
146
169
  overlaps?: never;
147
170
  overlapFailure?: never;
@@ -193,5 +216,9 @@ export type ContractHistoryResult = Readonly<{
193
216
  kind: "contract-history";
194
217
  history: ContractHistory;
195
218
  }>;
196
- export type InvocationResult = AcceptedResult | RefusedResult | RetryResult | ObservationResult | GuidanceResult | StatusResult | RegionResult | CatalogResult | ContractHistoryResult;
219
+ export type NukeInvocationResult = Readonly<{
220
+ kind: "nuke";
221
+ result: NukeResult;
222
+ }>;
223
+ export type InvocationResult = AcceptedResult | RefusedResult | RetryResult | ObservationResult | GuidanceResult | StatusResult | RegionResult | CatalogResult | ContractHistoryResult | NukeInvocationResult | IntegrationConflictMaterialized;
197
224
  export {};
@@ -0,0 +1,2 @@
1
+ import type { ParsedExecution } from "./parse.js";
2
+ export declare function runCliCommand(invocation: ParsedExecution): Promise<number>;
@@ -0,0 +1,140 @@
1
+ import { isParsedAkumaCommand } from "./commands/akuma.js";
2
+ import { CliUsageError } from "./parse.js";
3
+ function invocationStart(command) {
4
+ if (command.output === "json")
5
+ return undefined;
6
+ if (command.command === "bind")
7
+ return "⧖ preparing keiyaku";
8
+ if (command.command === "deliver")
9
+ return "⧖ delivering";
10
+ if (command.command === "audit")
11
+ return "⧖ auditing";
12
+ if (command.command === "reconcile")
13
+ return "⧖ reconciling";
14
+ return command.command === "install" ? "⧖ installing skills" : undefined;
15
+ }
16
+ async function writeTask(command, result) {
17
+ const { renderTaskIncompleteDiagnostic, renderTaskText, taskExitCode } = await import("./render/task.js");
18
+ const context = {
19
+ columns: process.stdout.isTTY === true && Number.isInteger(process.stdout.columns) ? process.stdout.columns : 80,
20
+ color: false,
21
+ };
22
+ 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") {
25
+ const diagnostic = renderTaskIncompleteDiagnostic(result);
26
+ if (diagnostic.length > 0)
27
+ process.stderr.write(`${diagnostic}\n`);
28
+ process.stdout.write(result.draft);
29
+ }
30
+ else
31
+ process.stdout.write(`${renderTaskText(command, result, context)}\n`);
32
+ return taskExitCode(result);
33
+ }
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, {
37
+ columns: process.stdout.isTTY === true && Number.isInteger(process.stdout.columns) ? process.stdout.columns : 80,
38
+ 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`);
42
+ return akumaExitCode(result);
43
+ }
44
+ async function writeResult(command, result) {
45
+ if (command.command === "install") {
46
+ const { installExitCode, renderInstallText } = await import("./commands/install.js");
47
+ const value = result;
48
+ process.stdout.write(`${command.output === "json" ? JSON.stringify(value) : renderInstallText(value)}\n`);
49
+ return installExitCode(value);
50
+ }
51
+ if (command.command === "task")
52
+ return await writeTask(command, result);
53
+ if (command.command === "settings") {
54
+ const { renderSettingsText, settingsJsonValue } = await import("./render/settings.js");
55
+ 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`);
64
+ return 0;
65
+ }
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")
70
+ return await writeAkuma(command, result);
71
+ 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
+ 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;
105
+ }
106
+ 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`);
109
+ return 1;
110
+ }
111
+ export async function runCliCommand(invocation) {
112
+ const command = invocation.command;
113
+ try {
114
+ const start = invocationStart(command);
115
+ const { invoke } = await import("./invoke.js");
116
+ const result = await invoke(invocation, {
117
+ cwd: process.cwd(),
118
+ ...(start === undefined ? {} : { onOperationStart: () => { process.stderr.write(`${start}\n`); } }),
119
+ });
120
+ return await writeResult(command, result);
121
+ }
122
+ catch (error) {
123
+ if (command.command !== "install") {
124
+ const { AkumaWorldScopeError } = await import("../library/address.js");
125
+ if (error instanceof AkumaWorldScopeError)
126
+ return writeWorldScopeRefusal(error, command.output);
127
+ }
128
+ if (command.command === "bind") {
129
+ const { BindDraftError } = await import("./draft.js");
130
+ if (error instanceof BindDraftError) {
131
+ process.stderr.write(`${error.original instanceof Error ? error.original.message : String(error.original)}\n`);
132
+ const { renderBindDraftReceipt } = await import("./render/refusal.js");
133
+ process.stderr.write(`${renderBindDraftReceipt(error.draft)}\n`);
134
+ return error.original instanceof CliUsageError ? 1 : 3;
135
+ }
136
+ }
137
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
138
+ return error instanceof CliUsageError ? 1 : 3;
139
+ }
140
+ }
@@ -3,7 +3,5 @@ export declare class CliUsageError extends Error {
3
3
  readonly projection?: string | undefined;
4
4
  constructor(diagnostic: string, projection?: string | undefined);
5
5
  }
6
- export declare const JSON_AUTOMATION_HELP = "--json is only for automation script input/output and should not be used for daily interactive use.";
7
- export declare function withJsonAutomationHelp(help: string): string;
8
6
  export declare function isBlankInput(value: string): boolean;
9
7
  export declare function usageLine(usage: string): string;
@@ -8,10 +8,6 @@ export class CliUsageError extends Error {
8
8
  this.name = "CliUsageError";
9
9
  }
10
10
  }
11
- export const JSON_AUTOMATION_HELP = "--json is only for automation script input/output and should not be used for daily interactive use.";
12
- export function withJsonAutomationHelp(help) {
13
- return help.includes("--json") ? `${help}\n\n${JSON_AUTOMATION_HELP}` : help;
14
- }
15
11
  export function isBlankInput(value) {
16
12
  return value.trim().length === 0;
17
13
  }
@@ -1,7 +1,28 @@
1
1
  import { type DerivedFileAction } from "./coordination/durable-file.js";
2
2
  import { type ContractId, type ContractState } from "./core/facts/types.js";
3
- import { type GitRepository } from "./git/repository.js";
3
+ import { type GitRepository } from "./git/process.js";
4
4
  import { type PlaceRegister } from "./workspace-place.js";
5
+ export type ContractAppointment = Readonly<{
6
+ kind: "absent";
7
+ path: string;
8
+ }> | Readonly<{
9
+ kind: "appointed";
10
+ path: string;
11
+ contract: ContractId;
12
+ }> | Readonly<{
13
+ kind: "invalid";
14
+ path: string;
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
+ }>;
5
26
  export declare function renderContractGuidance(state: ContractState): string;
6
27
  export type ContractFileEffect = Readonly<{
7
28
  kind: "contract-file";
@@ -18,18 +39,9 @@ export type ContractWorktreeResult = Readonly<{
18
39
  effects: readonly ContractFileEffect[];
19
40
  lag: readonly ContractFileLag[];
20
41
  }>;
21
- export type ContractAppointment = Readonly<{
22
- kind: "absent";
23
- path: string;
24
- }> | Readonly<{
25
- kind: "appointed";
26
- path: string;
27
- contract: ContractId;
28
- }> | Readonly<{
29
- kind: "invalid";
30
- path: string;
31
- }>;
32
42
  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>;
33
45
  export type ContractReservation = Readonly<{
34
46
  kind: "reserved";
35
47
  path: string;
@@ -40,5 +52,8 @@ export type ContractReservation = Readonly<{
40
52
  export declare function reserveContractWorktree(repository: GitRepository, contract: ContractId): Promise<ContractReservation>;
41
53
  export declare function withContractWorktreeAppointment<T>(repository: GitRepository, action: () => T | Promise<T>): Promise<T>;
42
54
  export declare function releaseContractWorktree(repository: GitRepository, contract: ContractId): Promise<void>;
43
- export declare function removeContractWorktreeAppointment(repository: GitRepository, contract: ContractId): Promise<void>;
44
- export declare function projectContractWorktree(repository: GitRepository, state: ContractState | null, register?: PlaceRegister): Promise<ContractWorktreeResult>;
55
+ /** Remove matching here appointments and their exact generated support from registered worktrees. */
56
+ export declare function nukeHereAppointments(repository: GitRepository): Promise<void>;
57
+ /** Validate the existing Contract-worktree coordination lock before releasing it. */
58
+ export declare function nukeContractWorktreeLock(repository: GitRepository): Promise<void>;
59
+ export declare function projectContractWorktree(repository: GitRepository, state: ContractState | null, register?: PlaceRegister, onConflict?: (diagnostic: string) => never): Promise<ContractWorktreeResult>;