@astrosheep/keiyaku 4.1.0 → 4.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
  5. package/build/src/akuma/akuma-errors.d.ts +6 -0
  6. package/build/src/akuma/akuma-errors.js +9 -0
  7. package/build/src/akuma/akuma-handle.d.ts +39 -0
  8. package/build/src/akuma/akuma-handle.js +263 -0
  9. package/build/src/akuma/akuma-observe.d.ts +19 -0
  10. package/build/src/akuma/akuma-observe.js +74 -0
  11. package/build/src/akuma/akuma-product-symbols.d.ts +1 -0
  12. package/build/src/akuma/akuma-product-symbols.js +1 -0
  13. package/build/src/akuma/akuma-product.d.ts +18 -0
  14. package/build/src/akuma/akuma-product.js +154 -0
  15. package/build/src/akuma/akuma.d.ts +37 -81
  16. package/build/src/akuma/akuma.js +39 -447
  17. package/build/src/akuma/allowed.d.ts +1 -0
  18. package/build/src/akuma/allowed.js +6 -0
  19. package/build/src/akuma/archetype.js +8 -5
  20. package/build/src/akuma/body-supervisor.d.ts +26 -0
  21. package/build/src/akuma/body-supervisor.js +89 -0
  22. package/build/src/akuma/body.d.ts +45 -4
  23. package/build/src/akuma/body.js +145 -35
  24. package/build/src/akuma/coordinate.js +17 -7
  25. package/build/src/akuma/heart/facts.js +1 -1
  26. package/build/src/akuma/heart/index.d.ts +1 -1
  27. package/build/src/akuma/heart/index.js +2 -4
  28. package/build/src/akuma/heart/request-authority.js +4 -4
  29. package/build/src/akuma/heart/request-rows.js +27 -16
  30. package/build/src/akuma/heart/rows.js +79 -41
  31. package/build/src/akuma/heart/soul.js +1 -1
  32. package/build/src/akuma/heart/storage.d.ts +1 -0
  33. package/build/src/akuma/heart/storage.js +76 -11
  34. package/build/src/akuma/heart/tells.js +35 -18
  35. package/build/src/akuma/heart/timeline.js +19 -11
  36. package/build/src/akuma/identity.d.ts +1 -0
  37. package/build/src/akuma/identity.js +1 -0
  38. package/build/src/akuma/index.d.ts +3 -3
  39. package/build/src/akuma/index.js +1 -1
  40. package/build/src/akuma/nuke.js +106 -14
  41. package/build/src/akuma/projection-read.d.ts +17 -0
  42. package/build/src/akuma/projection-read.js +135 -0
  43. package/build/src/akuma/projection.d.ts +1 -16
  44. package/build/src/akuma/projection.js +77 -154
  45. package/build/src/akuma/provider-recipe.js +11 -5
  46. package/build/src/akuma/provider.js +105 -62
  47. package/build/src/akuma/providers/acp/config.js +5 -6
  48. package/build/src/akuma/providers/acp/core.js +17 -10
  49. package/build/src/akuma/providers/acp/events.js +38 -29
  50. package/build/src/akuma/providers/acp/index.js +13 -9
  51. package/build/src/akuma/providers/claude/events.js +8 -12
  52. package/build/src/akuma/providers/claude/index.d.ts +1 -0
  53. package/build/src/akuma/providers/claude/index.js +55 -26
  54. package/build/src/akuma/providers/claude/input.js +6 -2
  55. package/build/src/akuma/providers/codex-app-server/events.js +61 -36
  56. package/build/src/akuma/providers/codex-app-server/index.js +25 -13
  57. package/build/src/akuma/providers/grok-build/index.js +22 -25
  58. package/build/src/akuma/providers/index.js +2 -18
  59. package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
  60. package/build/src/akuma/providers/opencode-sdk/index.js +26 -17
  61. package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
  62. package/build/src/akuma/providers/pi/events.js +26 -19
  63. package/build/src/akuma/providers/pi/index.js +58 -40
  64. package/build/src/akuma/publication.js +9 -9
  65. package/build/src/akuma/request-execution.d.ts +6 -0
  66. package/build/src/akuma/request-execution.js +86 -0
  67. package/build/src/akuma/request-serve.d.ts +12 -1
  68. package/build/src/akuma/request-serve.js +19 -122
  69. package/build/src/akuma/request-wire.d.ts +2 -2
  70. package/build/src/akuma/request-wire.js +75 -102
  71. package/build/src/akuma/requests.js +2 -2
  72. package/build/src/akuma/{body-turn.d.ts → turn-drive.d.ts} +2 -25
  73. package/build/src/akuma/{body-turn.js → turn-drive.js} +20 -103
  74. package/build/src/akuma-body.js +6 -5
  75. package/build/src/body/amend.d.ts +4 -1
  76. package/build/src/body/amend.js +14 -6
  77. package/build/src/body/decode.js +2 -4
  78. package/build/src/body/envelope.js +2 -4
  79. package/build/src/body/region.d.ts +1 -2
  80. package/build/src/body/region.js +2 -70
  81. package/build/src/body/render.js +17 -12
  82. package/build/src/body/shape.js +1 -7
  83. package/build/src/cli/accepted.d.ts +1 -1
  84. package/build/src/cli/accepted.js +8 -1
  85. package/build/src/cli/commands/akuma-invoke.js +18 -6
  86. package/build/src/cli/commands/akuma.d.ts +0 -6
  87. package/build/src/cli/commands/akuma.js +11 -24
  88. package/build/src/cli/commands/amend.d.ts +2 -2
  89. package/build/src/cli/commands/amend.js +2 -4
  90. package/build/src/cli/commands/bind.d.ts +4 -4
  91. package/build/src/cli/commands/bind.js +16 -6
  92. package/build/src/cli/commands/contract-invoke.d.ts +25 -0
  93. package/build/src/cli/commands/contract-invoke.js +193 -0
  94. package/build/src/cli/commands/contract.d.ts +109 -10
  95. package/build/src/cli/commands/contract.js +339 -16
  96. package/build/src/cli/commands/install.d.ts +1 -1
  97. package/build/src/cli/commands/install.js +23 -15
  98. package/build/src/cli/commands/task-invoke.js +187 -67
  99. package/build/src/cli/commands/task-query.js +48 -24
  100. package/build/src/cli/commands/task.js +150 -38
  101. package/build/src/cli/coordinates.js +2 -4
  102. package/build/src/cli/invoke.js +92 -208
  103. package/build/src/cli/main.js +4 -2
  104. package/build/src/cli/parse.d.ts +3 -90
  105. package/build/src/cli/parse.js +27 -233
  106. package/build/src/cli/render/akuma-activity.d.ts +38 -0
  107. package/build/src/cli/render/akuma-activity.js +362 -0
  108. package/build/src/cli/render/akuma-tool-command.js +6 -7
  109. package/build/src/cli/render/akuma-tool.js +10 -8
  110. package/build/src/cli/render/akuma.d.ts +1 -1
  111. package/build/src/cli/render/akuma.js +61 -353
  112. package/build/src/cli/render/audit.js +5 -15
  113. package/build/src/cli/render/board.d.ts +1 -0
  114. package/build/src/cli/render/board.js +17 -0
  115. package/build/src/cli/render/catalog.js +81 -8
  116. package/build/src/cli/render/contract-history.d.ts +2 -0
  117. package/build/src/cli/render/contract-history.js +83 -0
  118. package/build/src/cli/render/contract-observation.d.ts +10 -0
  119. package/build/src/cli/render/contract-observation.js +58 -0
  120. package/build/src/cli/render/contract.d.ts +1 -2
  121. package/build/src/cli/render/contract.js +41 -142
  122. package/build/src/cli/render/kanshi.js +239 -215
  123. package/build/src/cli/render/receipt.js +2 -9
  124. package/build/src/cli/render/refusal.js +10 -15
  125. package/build/src/cli/render/region.js +22 -6
  126. package/build/src/cli/render/settings.js +4 -4
  127. package/build/src/cli/render/task.js +34 -14
  128. package/build/src/cli/render/terminal.js +16 -5
  129. package/build/src/cli/result.d.ts +3 -3
  130. package/build/src/cli/runtime.d.ts +6 -1
  131. package/build/src/cli/runtime.js +84 -63
  132. package/build/src/cli/selectors.js +2 -4
  133. package/build/src/cli/usage.js +6 -5
  134. package/build/src/contract-worktree.d.ts +1 -23
  135. package/build/src/contract-worktree.js +79 -155
  136. package/build/src/coordination/durable-file.js +7 -3
  137. package/build/src/coordination/sqlite-transaction-lock.js +29 -12
  138. package/build/src/core/facts/codec.js +7 -3
  139. package/build/src/core/facts/types.d.ts +1 -1
  140. package/build/src/core/subject.js +16 -9
  141. package/build/src/core/verbs/abandon.d.ts +1 -1
  142. package/build/src/core/verbs/abandon.js +1 -1
  143. package/build/src/core/verbs/amend.d.ts +1 -1
  144. package/build/src/core/verbs/amend.js +7 -7
  145. package/build/src/core/verbs/attestation.js +4 -1
  146. package/build/src/core/verbs/bind.d.ts +1 -1
  147. package/build/src/core/verbs/bind.js +1 -1
  148. package/build/src/core/verbs/placement.d.ts +1 -1
  149. package/build/src/core/verbs/placement.js +10 -8
  150. package/build/src/dispatch/index.js +8 -6
  151. package/build/src/duration.js +5 -1
  152. package/build/src/git/admission.js +5 -3
  153. package/build/src/git/hooks.d.ts +8 -0
  154. package/build/src/git/hooks.js +63 -14
  155. package/build/src/git/identity.js +1 -4
  156. package/build/src/git/integration.d.ts +2 -3
  157. package/build/src/git/integration.js +32 -39
  158. package/build/src/git/nuke.d.ts +1 -1
  159. package/build/src/git/nuke.js +110 -57
  160. package/build/src/git/observe.d.ts +13 -1
  161. package/build/src/git/observe.js +51 -44
  162. package/build/src/git/process.js +4 -2
  163. package/build/src/git/read-observation.js +10 -8
  164. package/build/src/git/reconcile.d.ts +22 -2
  165. package/build/src/git/reconcile.js +38 -274
  166. package/build/src/git/repository.d.ts +2 -0
  167. package/build/src/git/repository.js +13 -22
  168. package/build/src/git/scratch.d.ts +8 -5
  169. package/build/src/git/scratch.js +29 -2
  170. package/build/src/git/target-placement.d.ts +9 -10
  171. package/build/src/git/target-placement.js +59 -62
  172. package/build/src/git/tender.js +13 -46
  173. package/build/src/git/terminal-reconcile.d.ts +21 -0
  174. package/build/src/git/terminal-reconcile.js +278 -0
  175. package/build/src/git/terminal-seal.js +15 -12
  176. package/build/src/git/tree.js +5 -2
  177. package/build/src/git/workspace.d.ts +24 -2
  178. package/build/src/git/workspace.js +120 -16
  179. package/build/src/identity/coordinates.js +3 -1
  180. package/build/src/identity/selector.js +6 -3
  181. package/build/src/kanshi/fleet.d.ts +6 -0
  182. package/build/src/kanshi/fleet.js +27 -0
  183. package/build/src/kanshi/index.d.ts +1 -1
  184. package/build/src/kanshi/read.js +60 -48
  185. package/build/src/kanshi/report.d.ts +11 -23
  186. package/build/src/kanshi/select.js +25 -24
  187. package/build/src/library/address.d.ts +2 -1
  188. package/build/src/library/address.js +7 -8
  189. package/build/src/library/akuma-creation.js +20 -12
  190. package/build/src/library/audit.d.ts +0 -1
  191. package/build/src/library/audit.js +1 -2
  192. package/build/src/library/bind.d.ts +53 -5
  193. package/build/src/library/bind.js +98 -22
  194. package/build/src/library/catalog.d.ts +1 -0
  195. package/build/src/library/catalog.js +6 -3
  196. package/build/src/library/configuration.js +3 -1
  197. package/build/src/library/continuation.d.ts +15 -4
  198. package/build/src/library/continuation.js +24 -16
  199. package/build/src/library/contract-bind.d.ts +26 -0
  200. package/build/src/library/contract-bind.js +106 -0
  201. package/build/src/library/contract-operations.d.ts +77 -0
  202. package/build/src/library/contract-operations.js +130 -0
  203. package/build/src/library/contract-types.d.ts +95 -0
  204. package/build/src/library/contract-types.js +1 -0
  205. package/build/src/library/contract.d.ts +19 -154
  206. package/build/src/library/contract.js +46 -261
  207. package/build/src/library/fleet.d.ts +1 -1
  208. package/build/src/library/fleet.js +19 -11
  209. package/build/src/library/input.d.ts +2 -0
  210. package/build/src/library/input.js +14 -0
  211. package/build/src/library/keiyaku.d.ts +8 -7
  212. package/build/src/library/keiyaku.js +3 -3
  213. package/build/src/library/nuke.js +14 -5
  214. package/build/src/library/reconcile.d.ts +9 -4
  215. package/build/src/library/reconcile.js +30 -24
  216. package/build/src/library/refusal.d.ts +13 -5
  217. package/build/src/library/refusal.js +7 -0
  218. package/build/src/library/region.d.ts +8 -7
  219. package/build/src/library/region.js +31 -11
  220. package/build/src/library/repo.js +2 -2
  221. package/build/src/markdown/lex.js +9 -2
  222. package/build/src/markdown/parse.js +11 -7
  223. package/build/src/markdown/query.js +4 -2
  224. package/build/src/protocol/amend.js +3 -1
  225. package/build/src/protocol/attempt.d.ts +7 -3
  226. package/build/src/protocol/attempt.js +9 -5
  227. package/build/src/protocol/audit.d.ts +1 -1
  228. package/build/src/protocol/audit.js +4 -14
  229. package/build/src/protocol/bind.d.ts +19 -6
  230. package/build/src/protocol/bind.js +28 -13
  231. package/build/src/protocol/completion.d.ts +0 -1
  232. package/build/src/protocol/completion.js +1 -3
  233. package/build/src/protocol/deliver.d.ts +1 -3
  234. package/build/src/protocol/deliver.js +15 -39
  235. package/build/src/protocol/intent.d.ts +1 -0
  236. package/build/src/protocol/intent.js +9 -7
  237. package/build/src/protocol/operations.d.ts +3 -7
  238. package/build/src/protocol/operations.js +5 -3
  239. package/build/src/protocol/placement.d.ts +0 -1
  240. package/build/src/protocol/placement.js +6 -6
  241. package/build/src/protocol/read/observation.d.ts +11 -0
  242. package/build/src/protocol/read/observation.js +37 -0
  243. package/build/src/protocol/read/status.d.ts +23 -12
  244. package/build/src/protocol/read/status.js +90 -72
  245. package/build/src/protocol/reconcile.d.ts +1 -0
  246. package/build/src/protocol/reconcile.js +2 -3
  247. package/build/src/protocol/reintegrate.js +1 -1
  248. package/build/src/protocol/review.d.ts +0 -1
  249. package/build/src/protocol/review.js +15 -22
  250. package/build/src/protocol/run.d.ts +1 -0
  251. package/build/src/protocol/run.js +4 -5
  252. package/build/src/runtime/proc/launch.d.ts +33 -0
  253. package/build/src/runtime/proc/launch.js +98 -0
  254. package/build/src/runtime/proc/line-rpc.js +9 -3
  255. package/build/src/runtime/proc/run.d.ts +12 -6
  256. package/build/src/runtime/proc/run.js +78 -21
  257. package/build/src/runtime/proc/stdio.js +7 -10
  258. package/build/src/settings.js +6 -2
  259. package/build/src/settlement/holder.js +13 -10
  260. package/build/src/settlement/settle.js +39 -6
  261. package/build/src/task/board.js +12 -6
  262. package/build/src/task/compose.js +85 -22
  263. package/build/src/task/context.js +21 -8
  264. package/build/src/task/document.js +46 -10
  265. package/build/src/task/identity.js +5 -2
  266. package/build/src/task/index.d.ts +0 -1
  267. package/build/src/task/index.js +119 -34
  268. package/build/src/task/input.js +29 -7
  269. package/build/src/task/mutation.js +61 -19
  270. package/build/src/task/operations.d.ts +6 -1
  271. package/build/src/task/operations.js +83 -29
  272. package/build/src/task/query.js +55 -26
  273. package/build/src/task/store.d.ts +3 -1
  274. package/build/src/task/store.js +81 -17
  275. package/build/src/verification/execution.js +14 -11
  276. package/build/src/workspace-place.js +19 -7
  277. package/build/src/world.js +16 -6
  278. package/package.json +8 -3
@@ -0,0 +1,362 @@
1
+ import { defaultWaitComplete } from "../../akuma/index.js";
2
+ import { toolRepr } from "./akuma-tool.js";
3
+ import { displayColumns, renderBoundedTextBlock, safeText, truncateMiddleDisplayText, } from "./terminal.js";
4
+ export const DEFAULT_CONTEXT = { columns: 80, color: false };
5
+ const SNAPSHOT_RULER = "────────────";
6
+ const TIME_WIDTH = 5;
7
+ const VERB_WIDTH = 6;
8
+ function identity(id, alias) {
9
+ return `${id}${alias === undefined ? "" : ` (${alias})`}`;
10
+ }
11
+ function associatedContractId(contract) {
12
+ return contract.kind === "associated" ? contract.contractId : undefined;
13
+ }
14
+ export function associatedIdentity(id, alias, contract) {
15
+ const contractId = contract === undefined ? undefined : associatedContractId(contract);
16
+ return `${identity(id, alias)}${contractId === undefined ? "" : ` [${contractId}]`}`;
17
+ }
18
+ export function snapshotHeading(id, alias, contract) {
19
+ const contractId = contract === undefined ? undefined : associatedContractId(contract);
20
+ return [identity(id, alias), SNAPSHOT_RULER, ...(contractId === undefined ? [] : [`└─ ${contractId}`])];
21
+ }
22
+ function answeredHeading(id, alias) {
23
+ return [`✓ came back ${identity(id, alias)}`, SNAPSHOT_RULER].join("\n");
24
+ }
25
+ function contractFacts(contract) {
26
+ return contract.kind === "failed" ? [`! contract failed ${safeText(contract.diagnostic)}`] : [];
27
+ }
28
+ function unobservedText(id, diagnostic) {
29
+ return `! ${id} unobserved: ${safeText(diagnostic)}`;
30
+ }
31
+ function lifeLabel(life) {
32
+ if (life === "running")
33
+ return "● STILL RUNNING";
34
+ if (life === "asleep")
35
+ return "✓ came back";
36
+ if (life === "killed")
37
+ return "× killed";
38
+ return `? ${life}`;
39
+ }
40
+ function pendingWithoutLiveBody(status) {
41
+ if (status.life === "running")
42
+ return 0;
43
+ return status.timeline.entries.reduce((count, entry) => count + (entry.kind === "row" && entry.row.kind === "tell" && entry.row.state === "pending" ? 1 : 0), 0);
44
+ }
45
+ function clock(at) {
46
+ const date = new Date(at);
47
+ return Number.isFinite(date.getTime())
48
+ ? `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`
49
+ : "unknown";
50
+ }
51
+ function label(row) {
52
+ if (row.kind === "said")
53
+ return "say";
54
+ if (row.kind === "thought")
55
+ return "think";
56
+ if (row.kind === "note")
57
+ return "note";
58
+ if (row.kind === "call")
59
+ return "call";
60
+ if (row.kind === "tell")
61
+ return "tell";
62
+ if (row.kind === "outcome")
63
+ return row.outcome.kind === "answered" ? "say" : "error";
64
+ if (row.kind === "turn")
65
+ return "call";
66
+ return toolRepr(row).label;
67
+ }
68
+ function mark(row) {
69
+ if (row.kind === "outcome")
70
+ return row.outcome.kind === "answered" ? "✓" : "!";
71
+ if (row.kind === "tell" && row.state === "pending")
72
+ return "⧗";
73
+ if (row.kind === "tool") {
74
+ if (row.state === "active")
75
+ return "⧖";
76
+ if (row.state === "unsettled")
77
+ return "?";
78
+ return row.state.status === "ok" ? "✓" : "!";
79
+ }
80
+ return "│";
81
+ }
82
+ function rowText(row) {
83
+ if (row.kind === "said" ||
84
+ row.kind === "thought" ||
85
+ row.kind === "note" ||
86
+ row.kind === "call" ||
87
+ row.kind === "tell") {
88
+ return {
89
+ text: row.text,
90
+ lines: row.kind === "said" || row.kind === "thought" ? 2 : row.kind === "tell" || row.kind === "call" ? 1 : 2,
91
+ };
92
+ }
93
+ if (row.kind === "outcome")
94
+ return row.outcome.kind === "answered"
95
+ ? { text: row.outcome.answer, lines: 3 }
96
+ : { text: row.outcome.diagnostic, lines: 2 };
97
+ if (row.kind === "turn")
98
+ return { text: "", lines: 1 };
99
+ const repr = toolRepr(row);
100
+ return {
101
+ text: repr.text,
102
+ lines: 2,
103
+ ...(repr.overflow === "middle-ellipsis" ? { middle: true } : {}),
104
+ ...(repr.suffix === undefined ? {} : { suffix: repr.suffix }),
105
+ };
106
+ }
107
+ function eventPrefix(glyph, verb, time) {
108
+ const gutter = time === undefined ? " ".repeat(TIME_WIDTH) : time.padEnd(TIME_WIDTH);
109
+ return `${gutter} ${glyph} ${verb.padEnd(VERB_WIDTH)} `;
110
+ }
111
+ function continuationPrefix() {
112
+ return eventPrefix("│", "");
113
+ }
114
+ function quotedBody(row) {
115
+ return (row.kind === "said" ||
116
+ row.kind === "thought" ||
117
+ row.kind === "tell" ||
118
+ (row.kind === "outcome" && row.outcome.kind === "answered"));
119
+ }
120
+ function quoteLines(lines, prefix) {
121
+ const prefixWidth = prefix.length;
122
+ return lines.map((line) => {
123
+ const body = line.slice(prefixWidth);
124
+ if (body.length === 0)
125
+ return line;
126
+ return `${line.slice(0, prefixWidth)}“${body}”`;
127
+ });
128
+ }
129
+ function renderMiddleEllipsis(first, text, suffix, columns) {
130
+ const prefixWidth = displayColumns(first);
131
+ const remaining = columns - prefixWidth;
132
+ const suffixWidth = displayColumns(suffix);
133
+ const withSuffix = remaining - suffixWidth;
134
+ // `$ ` + one head char + ellipsis + tail; cue and ellipsis alone are not a subject.
135
+ const showSuffix = suffix.length > 0 && withSuffix >= 6;
136
+ return `${first}${truncateMiddleDisplayText(text, Math.max(0, showSuffix ? withSuffix : remaining))}${showSuffix ? suffix : ""}`;
137
+ }
138
+ function renderRow(row, context, history, first) {
139
+ const value = rowText(row);
140
+ const quoted = quotedBody(row);
141
+ const quoteWidth = quoted ? 2 : 0;
142
+ if (value.middle === true) {
143
+ return [renderMiddleEllipsis(first, value.text, value.suffix ?? "", context.columns - quoteWidth)];
144
+ }
145
+ const lines = renderBoundedTextBlock(value.text, {
146
+ first,
147
+ continuation: continuationPrefix(),
148
+ columns: context.columns - quoteWidth,
149
+ lines: history ? Number.MAX_SAFE_INTEGER : value.lines,
150
+ ...("truncated" in row && row.truncated === true ? { truncated: true } : {}),
151
+ });
152
+ return quoted ? quoteLines(lines, first) : lines;
153
+ }
154
+ function groupedEntries(entries, context, history = false) {
155
+ const lines = [];
156
+ let previousClock;
157
+ for (const entry of entries) {
158
+ if (entry.kind === "gap") {
159
+ lines.push(`${" ".repeat(TIME_WIDTH)} ⋮ ${entry.count} omitted`);
160
+ continue;
161
+ }
162
+ const row = entry.row;
163
+ const at = clock(row.at);
164
+ const changed = previousClock === undefined || at !== previousClock;
165
+ lines.push(...renderRow(row, context, history, eventPrefix(mark(row), label(row), changed ? at : undefined)));
166
+ previousClock = at;
167
+ }
168
+ return lines;
169
+ }
170
+ function groupedRows(rows, context, history = false) {
171
+ return groupedEntries(rows.filter((row) => row.kind !== "turn").map((row) => ({ kind: "row", row })), context, history);
172
+ }
173
+ function taskDispositionMark(disposition) {
174
+ if (disposition === "done")
175
+ return "✓";
176
+ if (disposition === "drop")
177
+ return "×";
178
+ if (disposition === "on_hold")
179
+ return "⧗";
180
+ if (disposition === "in_progress")
181
+ return "●";
182
+ return disposition === "blocked" ? "‖" : "○";
183
+ }
184
+ function changeStat(group) {
185
+ let added = 0;
186
+ let removed = 0;
187
+ for (const change of group) {
188
+ if (change.diffstat === undefined)
189
+ return "+? -?";
190
+ added += change.diffstat.added;
191
+ removed += change.diffstat.removed;
192
+ }
193
+ return `+${added} -${removed}`;
194
+ }
195
+ function groupedChangeRows(changes) {
196
+ const groups = [];
197
+ const seen = new Map();
198
+ for (const change of changes) {
199
+ const index = seen.get(change.path);
200
+ if (index === undefined) {
201
+ seen.set(change.path, groups.length);
202
+ groups.push([change]);
203
+ }
204
+ else
205
+ groups[index].push(change);
206
+ }
207
+ return groups.map((group) => ({ path: group[0].path, stat: changeStat(group) }));
208
+ }
209
+ function renderReportedChangeLines(snapshot) {
210
+ const rows = groupedChangeRows(snapshot.reportedChanges);
211
+ const width = rows.reduce((max, row) => Math.max(max, row.stat.length), 0);
212
+ return [
213
+ `changes ${snapshot.reportedChanges.length + snapshot.reportedChangesOmitted}`,
214
+ ...rows.map((row) => ` ${row.stat.padEnd(width)} ${safeText(row.path)}`),
215
+ ...(snapshot.reportedChangesOmitted > 0 ? [` ⋮ ${snapshot.reportedChangesOmitted} earlier changes`] : []),
216
+ ];
217
+ }
218
+ function renderTaskRow(row, columns) {
219
+ const prefix = ` ${taskDispositionMark(row.disposition)} ${row.id} · `;
220
+ const body = `${safeText(row.title)} · ${row.disposition} · P${row.priority}`;
221
+ const inline = `${prefix}${body}`;
222
+ if (displayColumns(inline) <= columns)
223
+ return [inline];
224
+ return renderBoundedTextBlock(body, {
225
+ first: prefix,
226
+ continuation: " ",
227
+ columns,
228
+ lines: Number.MAX_SAFE_INTEGER,
229
+ });
230
+ }
231
+ function renderTaskContextLines(created, columns) {
232
+ if (created === undefined)
233
+ return [];
234
+ if (created.kind === "failed")
235
+ return [`! tasks failed ${safeText(created.diagnostic)}`];
236
+ return [`tasks ${created.rows.length}`, ...created.rows.flatMap((row) => renderTaskRow(row, columns))];
237
+ }
238
+ function answerContextLines(observation, columns) {
239
+ return [
240
+ ...renderTaskContextLines(observation.createdTasks, columns),
241
+ ...renderReportedChangeLines(observation.status.timeline),
242
+ ];
243
+ }
244
+ function answeredBlock(observation, answer, alias, columns) {
245
+ const context = answerContextLines(observation, columns).join("\n");
246
+ if (context.length === 0)
247
+ return `${answeredHeading(observation.status.id, alias)}\n${answer}`;
248
+ const separator = answer.endsWith("\n") ? "\n" : "\n\n";
249
+ return `${answeredHeading(observation.status.id, alias)}\n${answer}${separator}${context}`;
250
+ }
251
+ function snapshotCore(view, context, options) {
252
+ const snapshot = view.status.timeline;
253
+ const activity = snapshot.kind === "idle" && snapshot.outcome !== undefined
254
+ ? groupedRows([
255
+ ...snapshot.entries.filter((entry) => entry.kind === "row").map((entry) => entry.row),
256
+ snapshot.outcome,
257
+ ].sort((left, right) => left.sequence - right.sequence), context)
258
+ : groupedEntries(snapshot.entries, context);
259
+ const facts = [
260
+ ...(view.status.readonly?.enforcement === "none" ? [`! ${safeText(view.status.readonly.diagnostic)}`] : []),
261
+ ...contractFacts(view.contract),
262
+ ...(options.facts ?? []),
263
+ ];
264
+ const pending = pendingWithoutLiveBody(view.status);
265
+ return {
266
+ activity,
267
+ lines: [
268
+ ...snapshotHeading(view.status.id, options.alias, view.contract),
269
+ ...facts,
270
+ ...activity,
271
+ ...(pending === 0 ? [] : [`pending ${pending} tells · no live body`]),
272
+ ],
273
+ };
274
+ }
275
+ export function snapshotText(view, context, options = {}) {
276
+ const core = snapshotCore(view, context, options);
277
+ const taskContext = renderTaskContextLines(view.createdTasks, context.columns);
278
+ return [
279
+ ...core.lines,
280
+ ...(core.activity.length > 0 && taskContext.length > 0 ? [""] : []),
281
+ ...taskContext,
282
+ ...renderReportedChangeLines(view.status.timeline),
283
+ "",
284
+ lifeLabel(view.status.life),
285
+ ].join("\n");
286
+ }
287
+ function mutationSnapshotText(view, context, options = {}) {
288
+ const core = snapshotCore(view, context, options);
289
+ return [...core.lines, ...(options.showLife === false ? [] : ["", lifeLabel(view.status.life)])].join("\n");
290
+ }
291
+ export function mutationObservationStageText(id, observation, context, options = {}) {
292
+ if (observation.kind === "unobserved")
293
+ return unobservedText(id, observation.diagnostic);
294
+ return mutationSnapshotText(observation, context, options);
295
+ }
296
+ export function statusAnswer(view) {
297
+ if (!defaultWaitComplete(view.status))
298
+ return undefined;
299
+ if (view.status.life !== "asleep")
300
+ return undefined;
301
+ if (view.status.readonly?.enforcement === "none")
302
+ return undefined;
303
+ const timeline = view.status.timeline;
304
+ if (timeline.kind !== "idle" || timeline.outcome?.outcome.kind !== "answered")
305
+ return undefined;
306
+ return timeline.outcome.outcome.answer;
307
+ }
308
+ function answerCallFailed(result) {
309
+ return result.dispatch.kind === "failed" || result.alias.kind === "failed" || result.readonly?.enforcement === "none";
310
+ }
311
+ export function akumaRawAnswer(result) {
312
+ if (result.action === "call") {
313
+ if (answerCallFailed(result.result) || result.result.observation.kind !== "observed")
314
+ return undefined;
315
+ return statusAnswer({ status: result.result.observation.status });
316
+ }
317
+ if (result.action === "wait" && result.result.observations.length === 1)
318
+ return statusAnswer(result.result.observations[0]);
319
+ return undefined;
320
+ }
321
+ export function waitText(result, context) {
322
+ const alias = result.alias;
323
+ const total = result.result.observations.length + result.result.unobserved.length;
324
+ const done = result.result.observations.filter((observation) => defaultWaitComplete(observation.status)).length;
325
+ const blocks = [
326
+ ...result.result.observations.map((observation) => {
327
+ const answer = statusAnswer(observation);
328
+ if (answer !== undefined)
329
+ return answeredBlock(observation, answer, alias, context.columns);
330
+ return snapshotText(observation, context, { ...(alias === undefined ? {} : { alias }) });
331
+ }),
332
+ ...result.result.unobserved.map((member) => unobservedText(member.id, member.diagnostic)),
333
+ ];
334
+ if (total <= 1)
335
+ return blocks.join("\n\n");
336
+ return [...blocks, `${done} of ${total} done`].join("\n\n");
337
+ }
338
+ export function historyText(command, result, context) {
339
+ if (command.last)
340
+ return result.mode === "last" ? result.answer : "no answer retained";
341
+ if (result.mode !== "page")
342
+ throw new Error("history result lacks page");
343
+ return [
344
+ ...snapshotHeading(result.akuma, result.alias, result.historyResult.contract),
345
+ ...groupedRows(result.history.rows, context, true),
346
+ ].join("\n");
347
+ }
348
+ export function tellText(result, context) {
349
+ const wake = result.result.tell.wake;
350
+ const facts = wake.kind === "failed"
351
+ ? [
352
+ `! wake failed · ${safeText(wake.diagnostic)}${wake.child === undefined ? "" : ` · log ${wake.child.log.path} ${wake.child.log.from}..${wake.child.log.to}`}`,
353
+ ]
354
+ : wake.kind === "pursuing"
355
+ ? []
356
+ : [`wake ${wake.kind}`];
357
+ return mutationObservationStageText(result.result.akuma, result.result.observation, context, {
358
+ ...(result.alias === undefined ? {} : { alias: result.alias }),
359
+ facts,
360
+ showLife: false,
361
+ });
362
+ }
@@ -4,7 +4,7 @@
4
4
  */
5
5
  const HORIZONTAL_WHITESPACE = new Set([" ", "\t"]);
6
6
  const UNSUPPORTED_UNQUOTED = new Set(["$", "`", "|", "&", ";", "<", ">", "(", ")"]);
7
- const DOUBLE_QUOTE_ESCAPES = new Set(["\"", "\\", "$", "`"]);
7
+ const DOUBLE_QUOTE_ESCAPES = new Set(['"', "\\", "$", "`"]);
8
8
  const POWERSHELL_OPTION_FLAGS = new Set(["-nologo", "-noprofile"]);
9
9
  const POWERSHELL_COMMAND_FLAGS = new Set(["-command", "-c"]);
10
10
  const SCAN_FAIL = { ok: false };
@@ -23,13 +23,12 @@ function executableName(value) {
23
23
  }
24
24
  function isBashOrZsh(value) {
25
25
  const name = executableName(value);
26
- return (value === "bash" || value === "zsh" || isAbsoluteExecutable(value))
27
- && (name === "bash" || name === "zsh");
26
+ return (value === "bash" || value === "zsh" || isAbsoluteExecutable(value)) && (name === "bash" || name === "zsh");
28
27
  }
29
28
  function isPowerShell(value) {
30
29
  const name = executableName(value);
31
- return (value.toLowerCase() === "powershell" || value.toLowerCase() === "pwsh" || isAbsoluteExecutable(value))
32
- && (name === "powershell" || name === "powershell.exe" || name === "pwsh" || name === "pwsh.exe");
30
+ return ((value.toLowerCase() === "powershell" || value.toLowerCase() === "pwsh" || isAbsoluteExecutable(value)) &&
31
+ (name === "powershell" || name === "powershell.exe" || name === "pwsh" || name === "pwsh.exe"));
33
32
  }
34
33
  function scanSingleQuoted(command, index) {
35
34
  const end = command.indexOf("'", index + 1);
@@ -46,7 +45,7 @@ function scanDoubleQuoted(command, index) {
46
45
  let value = "";
47
46
  while (cursor < command.length) {
48
47
  const quoted = command[cursor];
49
- if (quoted === "\"")
48
+ if (quoted === '"')
50
49
  return scanned(cursor + 1, value);
51
50
  if (quoted === "$" || quoted === "`")
52
51
  return SCAN_FAIL;
@@ -75,7 +74,7 @@ function scanTokenSegment(command, index) {
75
74
  return SCAN_FAIL;
76
75
  if (character === "'")
77
76
  return scanSingleQuoted(command, index);
78
- if (character === "\"")
77
+ if (character === '"')
79
78
  return scanDoubleQuoted(command, index);
80
79
  if (character === "\\")
81
80
  return scanUnquotedEscape(command, index);
@@ -16,7 +16,9 @@ function result(row) {
16
16
  if (row.state === "active" || row.state === "unsettled")
17
17
  return undefined;
18
18
  const disposition = row.state.exitCode !== undefined
19
- ? row.state.exitCode === 0 ? "ok" : `exit ${row.state.exitCode}`
19
+ ? row.state.exitCode === 0
20
+ ? "ok"
21
+ : `exit ${row.state.exitCode}`
20
22
  : row.state.status;
21
23
  const parts = [
22
24
  ...(row.call.kind === "run" && row.durationMs !== undefined ? [duration(row.durationMs)] : []),
@@ -54,12 +56,8 @@ function fileChange(call) {
54
56
  const first = call.changes[0];
55
57
  if (first === undefined)
56
58
  return { label: "edit", text: "files" };
57
- const label = call.changes.length === 1
58
- ? first.op === "add" ? "write" : first.op === "delete" ? "delete" : "edit"
59
- : "edit";
60
- const subject = call.changes.length === 1
61
- ? oneLine(first.path)
62
- : `${call.changes.length} files · ${oneLine(first.path)} ...`;
59
+ const label = call.changes.length === 1 ? (first.op === "add" ? "write" : first.op === "delete" ? "delete" : "edit") : "edit";
60
+ const subject = call.changes.length === 1 ? oneLine(first.path) : `${call.changes.length} files · ${oneLine(first.path)} ...`;
63
61
  const complete = call.changes.every((change) => change.diffstat !== undefined);
64
62
  if (!complete)
65
63
  return { label, text: subject };
@@ -74,7 +72,11 @@ export function toolRepr(row) {
74
72
  let core;
75
73
  switch (row.call.kind) {
76
74
  case "run":
77
- core = { label: "run", text: `$ ${oneLine(normalizeToolCommand(row.call.command))}`, overflow: "middle-ellipsis" };
75
+ core = {
76
+ label: "run",
77
+ text: `$ ${oneLine(normalizeToolCommand(row.call.command))}`,
78
+ overflow: "middle-ellipsis",
79
+ };
78
80
  break;
79
81
  case "read":
80
82
  core = { label: "read", text: readText(row.call) };
@@ -1,7 +1,7 @@
1
1
  import type { AkumaInvocationResult } from "../commands/akuma-invoke.js";
2
2
  import type { ParsedCommand } from "../parse.js";
3
3
  import { type TextRenderContext } from "./terminal.js";
4
- export declare function akumaRawAnswer(result: AkumaInvocationResult): string | undefined;
4
+ export { akumaRawAnswer } from "./akuma-activity.js";
5
5
  export declare function renderAkumaText(command: ParsedCommand, result: AkumaInvocationResult, context?: TextRenderContext): string;
6
6
  export declare function akumaExitCode(result: AkumaInvocationResult): number;
7
7
  export declare function akumaJsonValue(result: AkumaInvocationResult): unknown;