@astrosheep/keiyaku 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/README.md +133 -8
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +13 -5
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -32
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +134 -0
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +262 -46
  12. package/build/src/akuma/abort.d.ts +2 -0
  13. package/build/src/akuma/abort.js +50 -0
  14. package/build/src/akuma/akuma.d.ts +50 -33
  15. package/build/src/akuma/akuma.js +175 -127
  16. package/build/src/akuma/archetype.d.ts +14 -5
  17. package/build/src/akuma/archetype.js +85 -39
  18. package/build/src/akuma/body.d.ts +3 -5
  19. package/build/src/akuma/body.js +490 -183
  20. package/build/src/akuma/coordinate.d.ts +9 -0
  21. package/build/src/akuma/coordinate.js +22 -0
  22. package/build/src/akuma/heart/facts.d.ts +88 -45
  23. package/build/src/akuma/heart/facts.js +19 -8
  24. package/build/src/akuma/heart/index.d.ts +64 -55
  25. package/build/src/akuma/heart/index.js +172 -252
  26. package/build/src/akuma/heart/rows.d.ts +38 -83
  27. package/build/src/akuma/heart/rows.js +117 -155
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +61 -22
  30. package/build/src/akuma/heart/soul.d.ts +8 -0
  31. package/build/src/akuma/heart/soul.js +136 -0
  32. package/build/src/akuma/heart/storage.d.ts +47 -0
  33. package/build/src/akuma/heart/storage.js +224 -0
  34. package/build/src/akuma/heart/tells.d.ts +12 -0
  35. package/build/src/akuma/heart/tells.js +79 -0
  36. package/build/src/akuma/heart/timeline.d.ts +15 -0
  37. package/build/src/akuma/heart/timeline.js +86 -0
  38. package/build/src/akuma/identity.d.ts +2 -2
  39. package/build/src/akuma/identity.js +9 -9
  40. package/build/src/akuma/index.d.ts +10 -3
  41. package/build/src/akuma/index.js +7 -1
  42. package/build/src/akuma/projection.d.ts +176 -0
  43. package/build/src/akuma/projection.js +256 -0
  44. package/build/src/akuma/provider-recipe.d.ts +24 -0
  45. package/build/src/akuma/provider-recipe.js +100 -0
  46. package/build/src/akuma/provider.d.ts +67 -13
  47. package/build/src/akuma/provider.js +172 -105
  48. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  49. package/build/src/akuma/providers/acp/core.js +159 -0
  50. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  51. package/build/src/akuma/providers/acp/events.js +73 -0
  52. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  53. package/build/src/akuma/providers/acp/index.js +94 -0
  54. package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
  55. package/build/src/akuma/providers/claude/events.js +238 -0
  56. package/build/src/akuma/providers/claude/index.d.ts +47 -0
  57. package/build/src/akuma/providers/claude/index.js +279 -0
  58. package/build/src/akuma/providers/claude/input.d.ts +13 -0
  59. package/build/src/akuma/providers/claude/input.js +109 -0
  60. package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
  61. package/build/src/akuma/providers/codex-app-server/events.js +15 -12
  62. package/build/src/akuma/providers/codex-app-server/index.d.ts +15 -13
  63. package/build/src/akuma/providers/codex-app-server/index.js +77 -33
  64. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  65. package/build/src/akuma/providers/grok-build/index.js +70 -0
  66. package/build/src/akuma/providers/index.d.ts +5 -3
  67. package/build/src/akuma/providers/index.js +35 -56
  68. package/build/src/akuma/providers/opencode-sdk/events.d.ts +54 -0
  69. package/build/src/akuma/providers/opencode-sdk/events.js +235 -0
  70. package/build/src/akuma/providers/opencode-sdk/index.d.ts +33 -0
  71. package/build/src/akuma/providers/opencode-sdk/index.js +308 -0
  72. package/build/src/akuma/providers/opencode-sdk/session.d.ts +26 -0
  73. package/build/src/akuma/providers/opencode-sdk/session.js +63 -0
  74. package/build/src/akuma/providers/pi/events.d.ts +33 -0
  75. package/build/src/akuma/providers/pi/events.js +166 -0
  76. package/build/src/akuma/providers/pi/index.d.ts +11 -0
  77. package/build/src/akuma/providers/pi/index.js +191 -0
  78. package/build/src/akuma/publication.d.ts +3 -3
  79. package/build/src/akuma/publication.js +28 -40
  80. package/build/src/akuma/requests.d.ts +9 -6
  81. package/build/src/akuma/requests.js +95 -65
  82. package/build/src/alias/index.d.ts +4 -3
  83. package/build/src/alias/index.js +12 -13
  84. package/build/src/body/decode.js +7 -1
  85. package/build/src/body/region.d.ts +2 -0
  86. package/build/src/body/region.js +77 -7
  87. package/build/src/body/render.js +2 -1
  88. package/build/src/body/shape.js +7 -1
  89. package/build/src/body/verification.js +19 -4
  90. package/build/src/cli/accepted.d.ts +18 -12
  91. package/build/src/cli/accepted.js +73 -34
  92. package/build/src/cli/actor.js +3 -3
  93. package/build/src/cli/commands/akuma-invoke.d.ts +44 -19
  94. package/build/src/cli/commands/akuma-invoke.js +101 -52
  95. package/build/src/cli/commands/akuma.d.ts +27 -9
  96. package/build/src/cli/commands/akuma.js +151 -80
  97. package/build/src/cli/commands/contract.d.ts +155 -0
  98. package/build/src/cli/commands/contract.js +20 -0
  99. package/build/src/cli/commands/install.js +2 -0
  100. package/build/src/cli/commands/task-invoke.d.ts +19 -4
  101. package/build/src/cli/commands/task-invoke.js +65 -17
  102. package/build/src/cli/commands/task-query.d.ts +5 -0
  103. package/build/src/cli/commands/task-query.js +247 -0
  104. package/build/src/cli/commands/task.d.ts +3 -1
  105. package/build/src/cli/commands/task.js +52 -14
  106. package/build/src/cli/coordinates.d.ts +18 -0
  107. package/build/src/cli/coordinates.js +120 -0
  108. package/build/src/cli/draft.d.ts +8 -0
  109. package/build/src/cli/draft.js +96 -0
  110. package/build/src/cli/invoke.d.ts +9 -3
  111. package/build/src/cli/invoke.js +287 -108
  112. package/build/src/cli/main.js +54 -7
  113. package/build/src/cli/parse.d.ts +21 -117
  114. package/build/src/cli/parse.js +79 -84
  115. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  116. package/build/src/cli/render/akuma-tool-command.js +144 -0
  117. package/build/src/cli/render/akuma-tool.d.ts +4 -2
  118. package/build/src/cli/render/akuma-tool.js +35 -5
  119. package/build/src/cli/render/akuma.d.ts +3 -1
  120. package/build/src/cli/render/akuma.js +247 -212
  121. package/build/src/cli/render/audit.d.ts +3 -0
  122. package/build/src/cli/render/audit.js +104 -0
  123. package/build/src/cli/render/catalog.d.ts +2 -0
  124. package/build/src/cli/render/catalog.js +16 -0
  125. package/build/src/cli/render/contract.d.ts +3 -3
  126. package/build/src/cli/render/contract.js +200 -54
  127. package/build/src/cli/render/kanshi.js +272 -129
  128. package/build/src/cli/render/receipt.d.ts +19 -0
  129. package/build/src/cli/render/receipt.js +106 -0
  130. package/build/src/cli/render/refusal.d.ts +16 -2
  131. package/build/src/cli/render/refusal.js +88 -3
  132. package/build/src/cli/render/region.d.ts +2 -0
  133. package/build/src/cli/render/region.js +17 -0
  134. package/build/src/cli/render/task.d.ts +2 -1
  135. package/build/src/cli/render/task.js +223 -60
  136. package/build/src/cli/render/terminal.d.ts +20 -0
  137. package/build/src/cli/render/terminal.js +121 -0
  138. package/build/src/cli/render/text.js +11 -3
  139. package/build/src/cli/result.d.ts +126 -19
  140. package/build/src/cli/usage.d.ts +1 -0
  141. package/build/src/cli/usage.js +3 -0
  142. package/build/src/contract-worktree.d.ts +44 -0
  143. package/build/src/contract-worktree.js +251 -0
  144. package/build/src/coordination/durable-file.d.ts +5 -1
  145. package/build/src/coordination/durable-file.js +57 -10
  146. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  147. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  148. package/build/src/core/facts/codec.js +23 -4
  149. package/build/src/core/facts/eligibility.d.ts +1 -10
  150. package/build/src/core/facts/eligibility.js +0 -49
  151. package/build/src/core/facts/fold.js +1 -6
  152. package/build/src/core/facts/gate.d.ts +1 -0
  153. package/build/src/core/facts/gate.js +1 -0
  154. package/build/src/core/facts/observation.d.ts +3 -0
  155. package/build/src/core/facts/observation.js +12 -0
  156. package/build/src/core/facts/types.d.ts +10 -3
  157. package/build/src/core/subject.js +2 -2
  158. package/build/src/core/verbs/amend.d.ts +1 -1
  159. package/build/src/core/verbs/amend.js +3 -18
  160. package/build/src/core/verbs/bind.js +2 -16
  161. package/build/src/core/verbs/deliver.d.ts +1 -1
  162. package/build/src/core/verbs/deliver.js +14 -4
  163. package/build/src/core/verbs/placement.d.ts +1 -1
  164. package/build/src/core/verbs/placement.js +7 -9
  165. package/build/src/dispatch/index.d.ts +5 -3
  166. package/build/src/dispatch/index.js +30 -21
  167. package/build/src/duration.d.ts +10 -0
  168. package/build/src/duration.js +22 -0
  169. package/build/src/git/admission.d.ts +2 -2
  170. package/build/src/git/admission.js +33 -23
  171. package/build/src/git/hooks.d.ts +15 -0
  172. package/build/src/git/hooks.js +70 -18
  173. package/build/src/git/identity.d.ts +5 -1
  174. package/build/src/git/identity.js +23 -4
  175. package/build/src/git/integration.d.ts +48 -0
  176. package/build/src/git/integration.js +250 -0
  177. package/build/src/git/observe.d.ts +29 -15
  178. package/build/src/git/observe.js +185 -76
  179. package/build/src/git/read-observation.d.ts +41 -0
  180. package/build/src/git/read-observation.js +361 -0
  181. package/build/src/git/reconcile.d.ts +17 -5
  182. package/build/src/git/reconcile.js +305 -109
  183. package/build/src/git/repository.d.ts +41 -18
  184. package/build/src/git/repository.js +220 -114
  185. package/build/src/git/scratch.d.ts +17 -0
  186. package/build/src/git/scratch.js +73 -0
  187. package/build/src/git/target-placement.d.ts +92 -0
  188. package/build/src/git/target-placement.js +375 -0
  189. package/build/src/git/tender.d.ts +49 -0
  190. package/build/src/git/tender.js +63 -0
  191. package/build/src/git/terminal-seal.d.ts +24 -0
  192. package/build/src/git/terminal-seal.js +89 -0
  193. package/build/src/git/tree.d.ts +2 -2
  194. package/build/src/git/tree.js +4 -0
  195. package/build/src/git/workspace.d.ts +53 -0
  196. package/build/src/git/workspace.js +139 -0
  197. package/build/src/identity/selector.d.ts +6 -0
  198. package/build/src/identity/selector.js +19 -0
  199. package/build/src/index.d.ts +4 -2
  200. package/build/src/index.js +2 -1
  201. package/build/src/kanshi/index.d.ts +2 -2
  202. package/build/src/kanshi/index.js +1 -1
  203. package/build/src/kanshi/read.d.ts +7 -3
  204. package/build/src/kanshi/read.js +245 -45
  205. package/build/src/kanshi/report.d.ts +81 -6
  206. package/build/src/kanshi/select.d.ts +5 -0
  207. package/build/src/kanshi/select.js +33 -1
  208. package/build/src/library/address.d.ts +57 -0
  209. package/build/src/library/address.js +165 -0
  210. package/build/src/library/akuma-creation.d.ts +16 -7
  211. package/build/src/library/akuma-creation.js +96 -22
  212. package/build/src/library/audit.d.ts +18 -0
  213. package/build/src/library/audit.js +44 -0
  214. package/build/src/library/bind.d.ts +21 -0
  215. package/build/src/library/bind.js +56 -0
  216. package/build/src/library/catalog.d.ts +58 -0
  217. package/build/src/library/catalog.js +69 -0
  218. package/build/src/library/configuration.d.ts +6 -15
  219. package/build/src/library/configuration.js +14 -17
  220. package/build/src/library/contract.d.ts +23 -49
  221. package/build/src/library/contract.js +171 -185
  222. package/build/src/library/delivery.d.ts +24 -0
  223. package/build/src/library/delivery.js +21 -0
  224. package/build/src/library/fleet.d.ts +65 -0
  225. package/build/src/library/fleet.js +153 -0
  226. package/build/src/library/input.d.ts +3 -0
  227. package/build/src/library/input.js +19 -0
  228. package/build/src/library/keiyaku.d.ts +18 -3
  229. package/build/src/library/keiyaku.js +12 -1
  230. package/build/src/library/mutation.d.ts +39 -0
  231. package/build/src/library/mutation.js +37 -0
  232. package/build/src/library/reconcile.d.ts +29 -0
  233. package/build/src/library/reconcile.js +179 -0
  234. package/build/src/library/refusal.d.ts +21 -0
  235. package/build/src/library/refusal.js +29 -0
  236. package/build/src/library/region.d.ts +14 -1
  237. package/build/src/library/region.js +18 -4
  238. package/build/src/library/repo.d.ts +4 -13
  239. package/build/src/library/repo.js +14 -24
  240. package/build/src/protocol/attempt.d.ts +16 -3
  241. package/build/src/protocol/attempt.js +41 -10
  242. package/build/src/protocol/bind.d.ts +9 -2
  243. package/build/src/protocol/bind.js +48 -40
  244. package/build/src/protocol/intent.d.ts +57 -20
  245. package/build/src/protocol/intent.js +55 -79
  246. package/build/src/protocol/operations.d.ts +152 -43
  247. package/build/src/protocol/operations.js +482 -166
  248. package/build/src/protocol/outcome.d.ts +14 -3
  249. package/build/src/protocol/outcome.js +11 -3
  250. package/build/src/protocol/placement.d.ts +41 -0
  251. package/build/src/protocol/placement.js +147 -0
  252. package/build/src/protocol/read/documents.d.ts +2 -2
  253. package/build/src/protocol/read/documents.js +4 -4
  254. package/build/src/protocol/read/status.d.ts +18 -5
  255. package/build/src/protocol/read/status.js +73 -13
  256. package/build/src/protocol/run.d.ts +49 -7
  257. package/build/src/protocol/run.js +53 -25
  258. package/build/src/runtime/proc/line-rpc.d.ts +4 -8
  259. package/build/src/runtime/proc/line-rpc.js +22 -28
  260. package/build/src/runtime/proc/run.d.ts +23 -21
  261. package/build/src/runtime/proc/run.js +123 -89
  262. package/build/src/runtime/proc/stdio.d.ts +18 -0
  263. package/build/src/runtime/proc/stdio.js +58 -0
  264. package/build/src/settings.d.ts +7 -1
  265. package/build/src/settings.js +32 -17
  266. package/build/src/settlement/fence.d.ts +5 -0
  267. package/build/src/settlement/fence.js +14 -0
  268. package/build/src/settlement/holder.d.ts +35 -4
  269. package/build/src/settlement/holder.js +127 -28
  270. package/build/src/settlement/settle.d.ts +9 -1
  271. package/build/src/settlement/settle.js +74 -37
  272. package/build/src/task/board.d.ts +23 -5
  273. package/build/src/task/board.js +17 -10
  274. package/build/src/task/compose.d.ts +2 -2
  275. package/build/src/task/compose.js +18 -10
  276. package/build/src/task/context.d.ts +3 -3
  277. package/build/src/task/context.js +15 -20
  278. package/build/src/task/document.d.ts +2 -1
  279. package/build/src/task/document.js +15 -5
  280. package/build/src/task/index.d.ts +27 -15
  281. package/build/src/task/index.js +57 -35
  282. package/build/src/task/operations.d.ts +38 -13
  283. package/build/src/task/operations.js +80 -46
  284. package/build/src/task/query.d.ts +67 -0
  285. package/build/src/task/query.js +279 -0
  286. package/build/src/task/store.d.ts +5 -7
  287. package/build/src/task/store.js +43 -28
  288. package/build/src/verification/declaration.d.ts +1 -0
  289. package/build/src/verification/execution.d.ts +51 -0
  290. package/build/src/verification/execution.js +108 -0
  291. package/build/src/workspace-place.d.ts +41 -0
  292. package/build/src/workspace-place.js +386 -0
  293. package/build/src/world.d.ts +24 -0
  294. package/build/src/world.js +136 -0
  295. package/package.json +8 -4
  296. package/build/src/akuma/activity.d.ts +0 -66
  297. package/build/src/akuma/activity.js +0 -139
  298. package/build/src/akuma/providers/claude.js +0 -305
  299. package/build/src/context-root.d.ts +0 -4
  300. package/build/src/context-root.js +0 -15
  301. package/build/src/git/delivery.d.ts +0 -20
  302. package/build/src/git/delivery.js +0 -109
  303. package/build/src/git/verification.d.ts +0 -14
  304. package/build/src/git/verification.js +0 -56
  305. package/build/src/protocol/read/audit.d.ts +0 -25
  306. package/build/src/protocol/read/audit.js +0 -39
  307. package/build/src/verification/producer.d.ts +0 -23
  308. package/build/src/verification/producer.js +0 -54
@@ -1,6 +1,8 @@
1
1
  import type { AkumaInvocationResult } from "../commands/akuma-invoke.js";
2
2
  import type { ParsedCommand } from "../parse.js";
3
- export declare function renderAkumaText(command: ParsedCommand, result: AkumaInvocationResult): string;
3
+ import { type TextRenderContext } from "./terminal.js";
4
+ export declare function akumaRawAnswer(result: AkumaInvocationResult): string | undefined;
5
+ export declare function renderAkumaText(command: ParsedCommand, result: AkumaInvocationResult, context?: TextRenderContext): string;
4
6
  export declare function akumaExitCode(result: AkumaInvocationResult): number;
5
7
  export declare function akumaJsonValue(command: ParsedCommand, result: AkumaInvocationResult): unknown;
6
8
  export declare function renderAkumaJson(command: ParsedCommand, result: AkumaInvocationResult): string;
@@ -1,253 +1,288 @@
1
1
  import { toolRepr } from "./akuma-tool.js";
2
- import { safeText } from "./terminal.js";
3
- const GUTTER_MS = 60_000;
4
- const LABEL_WIDTH = 8;
5
- function mark(life) {
6
- switch (life) {
7
- case "running": return "●";
8
- case "dead": return "×";
9
- case "asleep": return "○";
10
- case "stranded":
11
- case "headless": return "!";
12
- }
2
+ import { displayColumns, renderBoundedTextBlock, safeText, truncateMiddleDisplayText } from "./terminal.js";
3
+ const DEFAULT_CONTEXT = { columns: 80, color: false };
4
+ const OPENING_STROKE = "─────";
5
+ const TIME_WIDTH = 5;
6
+ const VERB_WIDTH = 6;
7
+ function identity(id, alias) {
8
+ return `${id}${alias === undefined ? "" : ` (${alias})`}`;
9
+ }
10
+ function associatedIdentity(id, alias, contractId) {
11
+ return `${identity(id, alias)}${contractId === undefined ? "" : ` [${contractId}]`}`;
12
+ }
13
+ function snapshotHeading(id, alias, contractId) {
14
+ return [
15
+ OPENING_STROKE,
16
+ identity(id, alias),
17
+ ...(contractId === undefined ? [] : [`└─ ${contractId}`]),
18
+ ];
13
19
  }
14
- function ruler(parts) {
15
- const prefix = `── ${parts.join(" ── ")} `;
16
- return `${prefix}${"─".repeat(Math.max(1, 64 - prefix.length))}`;
20
+ function lifeLabel(life) {
21
+ if (life === "running")
22
+ return "● running";
23
+ if (life === "asleep")
24
+ return "○ asleep";
25
+ if (life === "killed")
26
+ return "× killed";
27
+ return `? ${life}`;
17
28
  }
18
29
  function clock(at) {
19
- if (at === undefined)
20
- return "";
21
30
  const date = new Date(at);
22
- if (!Number.isFinite(date.getTime()))
23
- return "";
24
- return `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
25
- }
26
- function renderSpine(items) {
27
- let lastPrintedAt;
28
- return items.map((item) => {
29
- const timestamp = item.at === undefined ? undefined : Date.parse(item.at);
30
- const printable = timestamp !== undefined && Number.isFinite(timestamp)
31
- && (lastPrintedAt === undefined || timestamp - lastPrintedAt >= GUTTER_MS);
32
- if (printable)
33
- lastPrintedAt = timestamp;
34
- const time = printable ? clock(item.at) : "";
35
- const index = item.index === undefined ? "" : String(item.index).padStart(4, " ");
36
- const gutter = `${index}${index.length === 0 ? "" : " "}${time.padStart(5, " ")}`;
37
- return `${gutter} │ ${item.label.padEnd(LABEL_WIDTH, " ")} ${item.text}`.trimEnd();
38
- });
31
+ return Number.isFinite(date.getTime()) ? `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}` : "unknown";
39
32
  }
40
- function activityItem(row) {
33
+ function label(row) {
41
34
  if (row.kind === "said")
42
- return { at: row.at, label: "say", text: row.text };
35
+ return "say";
43
36
  if (row.kind === "thought")
44
- return { at: row.at, label: "thought", text: row.text };
37
+ return "think";
45
38
  if (row.kind === "note")
46
- return { at: row.at, label: "note", text: row.text };
47
- const repr = toolRepr(row);
48
- return {
49
- at: row.at,
50
- label: repr.label,
51
- text: repr.text,
52
- };
53
- }
54
- function pendingItems(status) {
55
- return status.activity.pendingTells.map((tell) => ({ label: "⧗ tell", text: JSON.stringify(tell.body) }));
56
- }
57
- function outcomeItems(status) {
58
- if (status.answer !== undefined) {
59
- return [{
60
- ...(status.outcomeAt === undefined ? {} : { at: status.outcomeAt }),
61
- label: "✓",
62
- text: `answered · keiyaku history ${status.answerHistoryId ?? ""} --last`.trim(),
63
- }];
39
+ return "note";
40
+ if (row.kind === "call")
41
+ return "call";
42
+ if (row.kind === "tell")
43
+ return "tell";
44
+ if (row.kind === "outcome")
45
+ return row.outcome.kind === "answered" ? "say" : "error";
46
+ if (row.kind === "turn")
47
+ return "call";
48
+ return toolRepr(row).label;
49
+ }
50
+ function mark(row) {
51
+ if (row.kind === "outcome")
52
+ return row.outcome.kind === "answered" ? "✓" : "!";
53
+ if (row.kind === "tell" && row.state === "pending")
54
+ return "⧗";
55
+ if (row.kind === "tool") {
56
+ if (row.state === "active")
57
+ return "⧖";
58
+ if (row.state === "unsettled")
59
+ return "?";
60
+ return row.state.status === "ok" ? "✓" : "!";
64
61
  }
65
- if (status.failure !== undefined) {
66
- return [{
67
- ...(status.outcomeAt === undefined ? {} : { at: status.outcomeAt }),
68
- label: "!",
69
- text: `failed · ${status.failure}`,
70
- }];
62
+ return "·";
63
+ }
64
+ function rowText(row) {
65
+ if (row.kind === "said" || row.kind === "thought" || row.kind === "note" || row.kind === "call" || row.kind === "tell") {
66
+ return { text: row.text, lines: row.kind === "said" || row.kind === "thought" ? 2 : row.kind === "tell" || row.kind === "call" ? 1 : 2 };
71
67
  }
72
- return [];
68
+ if (row.kind === "outcome")
69
+ return row.outcome.kind === "answered"
70
+ ? { text: row.outcome.answer, lines: 3 }
71
+ : { text: row.outcome.diagnostic, lines: 2 };
72
+ if (row.kind === "turn")
73
+ return { text: "", lines: 1 };
74
+ const repr = toolRepr(row);
75
+ return { text: repr.text, lines: 2, ...(repr.overflow === "middle-ellipsis" ? { middle: true } : {}), ...(repr.suffix === undefined ? {} : { suffix: repr.suffix }) };
73
76
  }
74
- function statusItems(status) {
75
- return [
76
- ...status.activity.rows.map(activityItem),
77
- ...pendingItems(status),
78
- ...outcomeItems(status),
79
- ];
77
+ function eventPrefix(glyph, verb, time) {
78
+ const gutter = time === undefined ? " ".repeat(TIME_WIDTH) : time.padEnd(TIME_WIDTH);
79
+ return `${gutter} ${glyph} ${verb.padEnd(VERB_WIDTH)} `;
80
80
  }
81
- function omission(status) {
82
- return status.activity.omitted === 0
83
- ? []
84
- : [` ⋮ +${status.activity.omitted}`];
81
+ function continuationPrefix() {
82
+ return eventPrefix("│", "");
85
83
  }
86
- function statusText(status, facts = []) {
87
- return [
88
- ruler([`${mark(status.life)} ${status.id}`]),
89
- ...facts,
90
- ...omission(status),
91
- ...renderSpine(statusItems(status)),
92
- ].join("\n");
93
- }
94
- function historyItems(history) {
95
- const activity = history.rows.map((row) => ({ ...activityItem(row), index: row.sequence }));
96
- const boundaries = history.turns.map((turn) => turn.outcome.kind === "answered"
97
- ? { at: turn.completedAt, label: "✓", text: `answered · keiyaku history ${turn.outcome.historyId} --last` }
98
- : { at: turn.completedAt, label: "!", text: `failed · ${turn.outcome.diagnostic}` });
99
- return [...activity, ...boundaries].sort((left, right) => {
100
- const leftAt = left.at === undefined ? Number.POSITIVE_INFINITY : Date.parse(left.at);
101
- const rightAt = right.at === undefined ? Number.POSITIVE_INFINITY : Date.parse(right.at);
102
- return (Number.isFinite(leftAt) ? leftAt : Number.POSITIVE_INFINITY)
103
- - (Number.isFinite(rightAt) ? rightAt : Number.POSITIVE_INFINITY);
84
+ function quotedBody(row) {
85
+ return row.kind === "said" || row.kind === "thought" || row.kind === "tell"
86
+ || (row.kind === "outcome" && row.outcome.kind === "answered");
87
+ }
88
+ function quoteLines(lines, prefix) {
89
+ const prefixWidth = prefix.length;
90
+ return lines.map((line) => {
91
+ const body = line.slice(prefixWidth);
92
+ if (body.length === 0)
93
+ return line;
94
+ return `${line.slice(0, prefixWidth)}“${body}”`;
104
95
  });
105
96
  }
106
- function historyText(command, result) {
107
- if (command.last)
108
- return result.answer ?? "";
109
- const history = result.history;
110
- const scope = command.before === undefined && command.since === undefined
111
- ? "history"
112
- : `history ── ${command.before === undefined ? `since ${command.since}` : `before ${command.before}`}`;
113
- const lines = [ruler([result.akuma, scope])];
114
- const first = history.rows[0]?.sequence;
115
- const last = history.rows.at(-1)?.sequence;
116
- if (history.hasEarlier && first !== undefined) {
117
- lines.push(` ⋮ ${history.omitted} earlier · keiyaku history ${result.akuma} --before ${first}`);
118
- }
119
- else if (history.historyLost) {
120
- lines.push(" ⋮ earlier history no longer kept");
121
- }
122
- if (history.hasLater && last !== undefined) {
123
- lines.push(` ⋮ more · keiyaku history ${result.akuma} --since ${last}`);
97
+ function renderMiddleEllipsis(first, text, suffix, columns) {
98
+ const prefixWidth = displayColumns(first);
99
+ const remaining = columns - prefixWidth;
100
+ const suffixWidth = displayColumns(suffix);
101
+ const withSuffix = remaining - suffixWidth;
102
+ // `$ ` + one head char + ellipsis + tail; cue and ellipsis alone are not a subject.
103
+ const showSuffix = suffix.length > 0 && withSuffix >= 6;
104
+ return `${first}${truncateMiddleDisplayText(text, Math.max(0, showSuffix ? withSuffix : remaining))}${showSuffix ? suffix : ""}`;
105
+ }
106
+ function renderRow(row, context, history, first) {
107
+ const value = rowText(row);
108
+ const quoted = quotedBody(row);
109
+ const quoteWidth = quoted ? 2 : 0;
110
+ if (value.middle === true) {
111
+ return [renderMiddleEllipsis(first, value.text, value.suffix ?? "", context.columns - quoteWidth)];
124
112
  }
125
- if (command.since !== undefined && history.rows.length === 0) {
126
- lines.push(` ⋮ no activity since ${command.since}`);
113
+ const lines = renderBoundedTextBlock(value.text, {
114
+ first,
115
+ continuation: continuationPrefix(),
116
+ columns: context.columns - quoteWidth,
117
+ lines: history ? Number.MAX_SAFE_INTEGER : value.lines,
118
+ ...("truncated" in row && row.truncated === true ? { truncated: true } : {}),
119
+ });
120
+ return quoted ? quoteLines(lines, first) : lines;
121
+ }
122
+ function groupedEntries(entries, context, history = false) {
123
+ const lines = [];
124
+ let previousClock;
125
+ for (const entry of entries) {
126
+ if (entry.kind === "gap") {
127
+ lines.push(`${" ".repeat(TIME_WIDTH)} ⋮ ${entry.count} omitted`);
128
+ continue;
129
+ }
130
+ const row = entry.row;
131
+ const at = clock(row.at);
132
+ const changed = previousClock === undefined || at !== previousClock;
133
+ lines.push(...renderRow(row, context, history, eventPrefix(mark(row), label(row), changed ? at : undefined)));
134
+ previousClock = at;
127
135
  }
128
- lines.push(...renderSpine(historyItems(history)));
129
- return lines.join("\n");
136
+ return lines;
130
137
  }
131
- function waitText(status) {
132
- if (status.life === "running")
133
- return statusText(status);
134
- if (status.answer !== undefined)
135
- return status.answer;
136
- if (status.failure !== undefined)
137
- return `failure ${status.failure}`;
138
- return statusText(status);
138
+ function groupedRows(rows, context, history = false) {
139
+ return groupedEntries(rows.filter((row) => row.kind !== "turn").map((row) => ({ kind: "row", row })), context, history);
139
140
  }
140
- function wakeFailure(receipt) {
141
- return typeof receipt.wake === "string" ? null : `wake failed: ${safeText(receipt.wake.diagnostic)}`;
141
+ function snapshotText(view, context, options = {}) {
142
+ const snapshot = view.status.timeline;
143
+ const activity = snapshot.kind === "idle" && snapshot.outcome !== undefined
144
+ ? groupedRows([
145
+ ...snapshot.entries.filter((entry) => entry.kind === "row").map((entry) => entry.row),
146
+ snapshot.outcome,
147
+ ].sort((left, right) => left.sequence - right.sequence), context)
148
+ : groupedEntries(snapshot.entries, context);
149
+ const facts = [
150
+ ...(view.status.readonly?.enforcement === "none" ? [`! ${safeText(view.status.readonly.diagnostic)}`] : []),
151
+ ...(options.facts ?? []),
152
+ ];
153
+ const footer = options.showLife === false ? [] : [` ${lifeLabel(view.status.life)}`];
154
+ return [...snapshotHeading(view.status.id, options.alias, view.contractId), ...facts, ...activity, ...footer].join("\n");
142
155
  }
143
- function tellText(status, receipt) {
144
- const failure = wakeFailure(receipt);
145
- return failure === null ? statusText(status) : `${statusText(status)}\n${failure}`;
156
+ function historyText(command, result, context) {
157
+ if (command.last)
158
+ return result.mode === "last" ? result.answer : "no answer retained";
159
+ if (result.mode !== "page")
160
+ throw new Error("history result lacks page");
161
+ const contractId = result.historyResult.contractId;
162
+ return [...snapshotHeading(result.akuma, result.alias, contractId), ...groupedRows(result.history.rows, context, true)].join("\n");
163
+ }
164
+ function tellText(result, context) {
165
+ const facts = typeof result.result.tell.wake === "string" ? [] : [`! error ${safeText(result.result.tell.wake.diagnostic)}`];
166
+ return snapshotText(result.result.observation, context, { ...(result.alias === undefined ? {} : { alias: result.alias }), facts, showLife: false });
146
167
  }
147
168
  function dispatchLines(stage) {
148
- if (stage.kind === "none")
169
+ if (stage.kind === "none" || stage.kind === "dispatched")
149
170
  return [];
150
- if (stage.kind === "dispatched")
151
- return [`dispatch ${stage.dispatch.contractId}`];
152
- const failure = stage.failure;
153
- if (failure.kind === "conflict") {
154
- return [`dispatch failed conflict ${failure.current.contractId}`];
155
- }
156
- if (failure.kind === "contention")
171
+ if (stage.failure.kind === "conflict")
172
+ return [`dispatch failed conflict ${stage.failure.current.contractId}`];
173
+ if (stage.failure.kind === "contention")
157
174
  return ["dispatch failed contention"];
158
- return [`dispatch failed ${failure.kind} ${safeText(failure.diagnostic)}`];
159
- }
160
- function callText(result) {
161
- const called = result.result;
162
- const stages = [...dispatchLines(called.dispatch)];
163
- if (called.alias.kind === "aliased")
164
- stages.push(`alias ${called.alias.alias.alias}`);
165
- else if (called.alias.kind === "failed") {
166
- stages.push(`alias failed ${called.alias.failure.kind} ${safeText(called.alias.failure.diagnostic)}`);
175
+ return [`dispatch failed ${stage.failure.kind} ${safeText(stage.failure.diagnostic)}`];
176
+ }
177
+ function callFailed(result) {
178
+ return result.dispatch.kind === "failed"
179
+ || result.alias.kind === "failed"
180
+ || result.readonly?.enforcement === "none";
181
+ }
182
+ function statusAnswer(view) {
183
+ if (view.status.life !== "asleep")
184
+ return undefined;
185
+ if (view.status.readonly?.enforcement === "none")
186
+ return undefined;
187
+ const timeline = view.status.timeline;
188
+ if (timeline.kind !== "idle" || timeline.outcome?.outcome.kind !== "answered")
189
+ return undefined;
190
+ return timeline.outcome.outcome.answer;
191
+ }
192
+ export function akumaRawAnswer(result) {
193
+ if (result.action === "call") {
194
+ if (callFailed(result.result) || result.result.observation.kind !== "observed")
195
+ return undefined;
196
+ return statusAnswer({ status: result.result.observation.status });
167
197
  }
168
- if (called.observation.kind === "detached")
169
- return [called.akuma, ...stages].join("\n");
170
- if (called.observation.kind === "failed") {
171
- return [
172
- called.akuma,
173
- ...stages,
174
- `wait failed ${called.observation.failure.kind} ${safeText(called.observation.failure.diagnostic)}`,
175
- ].join("\n");
198
+ if (result.action === "wait" && result.result.statuses.length === 1)
199
+ return statusAnswer(result.result.statuses[0]);
200
+ return undefined;
201
+ }
202
+ function executionCwdLine(result) {
203
+ return result.execution.source === "contract-worktree" ? [`cwd ${result.execution.cwd}`] : [];
204
+ }
205
+ function callText(result, context) {
206
+ const alias = result.result.alias.kind === "aliased" ? result.result.alias.alias.alias : undefined;
207
+ const contractId = result.result.dispatch.kind === "dispatched" ? result.result.dispatch.dispatch.contractId : undefined;
208
+ const facts = [...dispatchLines(result.result.dispatch)];
209
+ const restraint = result.result.readonly?.enforcement === "none" ? [`! ${safeText(result.result.readonly.diagnostic)}`] : [];
210
+ if (result.result.alias.kind === "failed")
211
+ facts.push(`alias failed ${result.result.alias.failure.kind} ${safeText(result.result.alias.failure.diagnostic)}`);
212
+ const cwd = executionCwdLine(result.result);
213
+ if (result.result.observation.kind === "detached") {
214
+ const lines = [...snapshotHeading(result.result.akuma, alias, contractId), ...cwd, ...restraint, ...facts];
215
+ if (!callFailed(result.result)) {
216
+ const selector = result.result.alias.kind === "aliased" ? result.result.alias.alias.alias : result.result.akuma;
217
+ lines.push(`$ keiyaku -C ${result.world} wait ${selector} --timeout 5m`);
218
+ }
219
+ return lines.join("\n");
176
220
  }
177
- const status = called.observation.status;
178
- if (status.answer !== undefined || status.failure !== undefined) {
179
- return [called.akuma, ...stages, waitText(status)].join("\n");
221
+ if (result.result.observation.kind === "failed") {
222
+ return [...snapshotHeading(result.result.akuma, alias, contractId), ...cwd, ...restraint, ...facts, `! error ${safeText(result.result.observation.failure.diagnostic)}`].join("\n");
180
223
  }
181
- return statusText(status, stages);
224
+ return snapshotText({ status: result.result.observation.status, ...(contractId === undefined ? {} : { contractId }) }, context, {
225
+ ...(alias === undefined ? {} : { alias }),
226
+ facts: [...cwd, ...facts],
227
+ });
182
228
  }
183
- export function renderAkumaText(command, result) {
229
+ export function renderAkumaText(command, result, context = DEFAULT_CONTEXT) {
230
+ const answer = akumaRawAnswer(result);
231
+ if (answer !== undefined) {
232
+ if (result.action !== "call")
233
+ return answer;
234
+ const cwd = executionCwdLine(result.result);
235
+ return cwd.length === 0 ? answer : `${cwd.join("\n")}\n${answer}`;
236
+ }
184
237
  switch (result.action) {
185
- case "call": return callText(result);
186
- case "status": return statusText(result.status);
187
- case "wait": return waitText(result.status);
188
- case "tell": return tellText(result.status, result.receipt);
189
- case "interrupt": {
190
- const receipt = result.receipt;
191
- if (receipt.kind === "dead")
192
- return `${result.akuma} interrupt dead`;
193
- if (receipt.kind === "unstoppable")
194
- return `${result.akuma} interrupt unstoppable ${receipt.evidence}`;
195
- if ("kind" in receipt.tell)
196
- return `${result.akuma} interrupted ${receipt.putDown} · tell refused: dead`;
197
- const failure = wakeFailure(receipt.tell);
198
- return `${result.akuma} interrupted ${receipt.putDown}${failure === null ? "" : ` · ${failure}`}`;
199
- }
200
- case "history": return historyText(command, result);
238
+ case "call": return callText(result, context);
239
+ case "status": return snapshotText(result.status, context, { ...(result.alias === undefined ? {} : { alias: result.alias }) });
240
+ case "wait": return result.result.statuses.map((status) => snapshotText(status, context, { ...(result.alias === undefined ? {} : { alias: result.alias }) })).join("\n\n");
241
+ case "tell": return result.mode === "ordinary" ? tellText(result, context) : snapshotText(result.result.observation, context, { ...(result.alias === undefined ? {} : { alias: result.alias }), showLife: false });
242
+ case "history": return historyText(command, result, context);
201
243
  case "fork": {
202
- const receipt = result.receipt;
203
- if (receipt.kind === "forked")
204
- return [receipt.child, ...dispatchLines(receipt.dispatch)].join("\n");
205
- if (receipt.kind === "provider-cannot-fork")
206
- return `${receipt.provider} cannot fork`;
207
- if (receipt.kind === "unknown-history")
208
- return `${receipt.at} has no matching retained answered turn`;
209
- if (receipt.kind === "fork-failed")
210
- return receipt.diagnostic;
211
- return `session ${receipt.childSession.sessionId}\n${receipt.diagnostic}`;
244
+ if (result.receipt.kind !== "forked")
245
+ return result.receipt.kind === "unknown-history" ? `${result.receipt.at} has no matching retained answered turn` : result.receipt.kind === "provider-cannot-fork" ? `${result.receipt.provider} cannot fork` : result.receipt.diagnostic;
246
+ const contractId = result.receipt.dispatch.kind === "dispatched" ? result.receipt.dispatch.dispatch.contractId : undefined;
247
+ return associatedIdentity(result.receipt.child, undefined, contractId);
212
248
  }
213
- case "kill": return `${result.id} ${result.evidence}`;
249
+ case "kill": return result.result.results.map((member) => snapshotText(member.observation, context, { facts: [`kill ${member.evidence}`], ...(result.alias === undefined ? {} : { alias: result.alias }) })).join("\n\n");
214
250
  }
215
251
  }
216
- export function akumaExitCode(result) {
217
- if (result.action === "call"
218
- && (result.result.dispatch.kind === "failed"
219
- || result.result.alias.kind === "failed"
220
- || result.result.observation.kind === "failed"))
221
- return 2;
222
- if (result.action === "kill" && (result.evidence === "unavailable" || result.evidence === "alive-after-sigkill"))
223
- return 1;
224
- if (result.action === "tell" && typeof result.receipt.wake !== "string")
252
+ function callExitCode(result) {
253
+ if (result.result.dispatch.kind === "failed" || result.result.alias.kind === "failed" || result.result.observation.kind === "failed")
225
254
  return 2;
226
- if (result.action === "interrupt") {
227
- if (result.receipt.kind !== "interrupted" || "kind" in result.receipt.tell)
228
- return 1;
229
- if (typeof result.receipt.tell.wake !== "string")
230
- return 2;
231
- }
232
- if (result.action === "fork") {
233
- if (result.receipt.kind === "forked")
234
- return result.receipt.dispatch.kind === "failed" ? 2 : 0;
235
- return result.receipt.kind === "upstream-forked" ? 2 : 1;
255
+ if (result.result.observation.kind !== "observed")
256
+ return 0;
257
+ const timeline = result.result.observation.status.timeline;
258
+ return timeline.kind === "idle" && timeline.outcome?.outcome.kind === "failed" ? 2 : 0;
259
+ }
260
+ function killExitCode(result) {
261
+ return result.result.results.some((member) => member.evidence === "unavailable" || member.evidence === "hung" || member.evidence === "untidy") ? 1 : 0;
262
+ }
263
+ function tellExitCode(result) {
264
+ if (result.mode === "ordinary")
265
+ return typeof result.result.tell.wake === "string" ? 0 : 2;
266
+ return result.result.receipt.kind === "interrupted" ? 0 : 1;
267
+ }
268
+ function forkExitCode(result) {
269
+ return result.receipt.kind === "forked" ? 0 : result.receipt.kind === "upstream-forked" ? 2 : 1;
270
+ }
271
+ export function akumaExitCode(result) {
272
+ switch (result.action) {
273
+ case "call": return callExitCode(result);
274
+ case "kill": return killExitCode(result);
275
+ case "tell": return tellExitCode(result);
276
+ case "fork": return forkExitCode(result);
277
+ default: return 0;
236
278
  }
237
- return 0;
238
279
  }
239
280
  export function akumaJsonValue(command, result) {
240
- if (result.action === "call")
241
- return result.result;
242
- if (result.action === "fork")
243
- return result.receipt;
244
- if (result.action === "status" || result.action === "wait")
245
- return result.status;
246
- if (result.action === "tell")
247
- return { receipt: result.receipt, status: result.status };
248
- if (result.action === "history")
249
- return command.command === "history" && command.last ? result.answer ?? "" : result.history;
250
- return result;
281
+ if (result.action === "call" || result.action === "fork" || result.action === "status" || result.action === "wait" || result.action === "tell" || result.action === "kill")
282
+ return result.action === "status" ? result.status : result.action === "wait" ? result.result : result.action === "tell" ? result.result : result.action === "kill" ? result.result : result.action === "call" ? result.result : result.receipt;
283
+ if (command.command !== "history")
284
+ throw new Error("history result requires the history command");
285
+ return result.historyResult;
251
286
  }
252
287
  export function renderAkumaJson(command, result) {
253
288
  return JSON.stringify(akumaJsonValue(command, result));
@@ -0,0 +1,3 @@
1
+ import type { AcceptedAuditResult } from "../result.js";
2
+ import { type TextRenderContext } from "./terminal.js";
3
+ export declare function renderAcceptedAudit(result: AcceptedAuditResult, context?: TextRenderContext): string;
@@ -0,0 +1,104 @@
1
+ import { cleanupLines, leakLines, outcomeLines, receiptPayload, receiptRow, stopLines, } from "./receipt.js";
2
+ import { renderRefusalFacts } from "./refusal.js";
3
+ import { gitShortStat, renderBoundedTextBlock, renderOpaqueBlock, } from "./terminal.js";
4
+ const CHILD = " ";
5
+ function workspaceEvidence(workspace, columns) {
6
+ return renderOpaqueBlock(`workspace ${workspace.kind} ${workspace.path}`, CHILD, columns);
7
+ }
8
+ function candidateLines(report, columns, addressed) {
9
+ const candidate = report.candidate;
10
+ const lines = [];
11
+ if (candidate.kind === "blocked") {
12
+ receiptRow(lines, "!", "candidate", [{ text: "blocked" }], columns);
13
+ lines.push(...renderRefusalFacts(candidate.refusal, CHILD, columns, addressed));
14
+ return lines;
15
+ }
16
+ const identity = candidate.identity;
17
+ receiptRow(lines, "✓", "candidate", [{ text: "ready" }], columns);
18
+ lines.push(...renderOpaqueBlock(`tender=${identity.tenderSnapshot}`, CHILD, columns));
19
+ lines.push(...renderOpaqueBlock(`integration=${identity.integration.snapshot}`, CHILD, columns));
20
+ lines.push(...renderOpaqueBlock(`change=${identity.integration.changeId}`, CHILD, columns));
21
+ lines.push(...workspaceEvidence(candidate.workspace, columns));
22
+ lines.push(...renderOpaqueBlock(gitShortStat(candidate.scope), CHILD, columns));
23
+ if (candidate.scope.paths !== undefined) {
24
+ for (const path of candidate.scope.paths) {
25
+ lines.push(...renderOpaqueBlock(path, CHILD, columns));
26
+ }
27
+ }
28
+ if (report.delivery !== undefined) {
29
+ lines.push(...renderOpaqueBlock(`delivery change=${report.delivery.changeId} ${report.delivery.relation}`, CHILD, columns));
30
+ }
31
+ if (candidate.diff !== undefined)
32
+ receiptPayload(lines, "diff", candidate.diff);
33
+ return lines;
34
+ }
35
+ function verificationLines(verification, columns, addressed) {
36
+ const lines = [];
37
+ if (verification.kind === "not-run") {
38
+ receiptRow(lines, "·", "verification", [{ text: "not-run" }], columns);
39
+ return lines;
40
+ }
41
+ if (verification.kind === "stopped") {
42
+ return stopLines("verification", verification.stop, columns, addressed);
43
+ }
44
+ receiptRow(lines, verification.kind === "satisfied" ? "✓" : "!", "verification", [
45
+ { text: verification.kind },
46
+ { text: `${verification.passed} of ${verification.total}` },
47
+ ], columns);
48
+ if (verification.summary !== undefined) {
49
+ lines.push(...renderBoundedTextBlock(verification.summary, {
50
+ first: `${CHILD}summary `,
51
+ continuation: CHILD,
52
+ columns,
53
+ }));
54
+ }
55
+ return lines;
56
+ }
57
+ function targetLines(target, columns, addressed) {
58
+ const lines = [];
59
+ if (target.kind === "not-observed") {
60
+ receiptRow(lines, "·", "target", [{ text: "not-observed" }], columns);
61
+ return lines;
62
+ }
63
+ if (target.kind === "placeable") {
64
+ receiptRow(lines, "✓", "target", [
65
+ { text: "placeable" },
66
+ { text: target.ref, opaque: true },
67
+ { text: target.head, opaque: true },
68
+ ], columns);
69
+ return lines;
70
+ }
71
+ if (target.kind === "moved") {
72
+ receiptRow(lines, "!", "target", [
73
+ { text: "moved" },
74
+ { text: target.ref, opaque: true },
75
+ { text: `${target.expected} -> ${target.observed}`, opaque: true },
76
+ ], columns);
77
+ return lines;
78
+ }
79
+ if (target.kind === "failed") {
80
+ receiptRow(lines, "!", "target", [{ text: "failed" }], columns);
81
+ receiptPayload(lines, "diagnostic", target.diagnostic);
82
+ return lines;
83
+ }
84
+ receiptRow(lines, "!", "target", [{ text: "refused" }], columns);
85
+ lines.push(...renderRefusalFacts(target.refusal, CHILD, columns, addressed));
86
+ return lines;
87
+ }
88
+ function obligationLines(result, columns) {
89
+ return [
90
+ ...(result.cleanup === undefined ? [] : cleanupLines(result.cleanup, columns)),
91
+ ...(result.leak === undefined ? [] : leakLines(result.leak, columns)),
92
+ ];
93
+ }
94
+ export function renderAcceptedAudit(result, context) {
95
+ const report = result.report;
96
+ const columns = context?.columns ?? 80;
97
+ return [
98
+ ...outcomeLines("✓", result.verb, "accepted", result.contract, columns),
99
+ ...candidateLines(report, columns, result.contract),
100
+ ...verificationLines(report.verification, columns, result.contract),
101
+ ...targetLines(report.target, columns, result.contract),
102
+ ...obligationLines(result, columns),
103
+ ].join("\n");
104
+ }
@@ -0,0 +1,2 @@
1
+ import type { Catalog } from "../../index.js";
2
+ export declare function renderCatalogText(catalog: Catalog): string;