@astrosheep/keiyaku 4.6.3 → 4.6.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 (193) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +47 -11
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/references/automation.md +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +8 -9
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +37 -25
  6. package/build/src/akuma/akuma-observe.d.ts +18 -15
  7. package/build/src/akuma/akuma-observe.js +75 -16
  8. package/build/src/akuma/akuma-wait.d.ts +4 -3
  9. package/build/src/akuma/akuma-wait.js +75 -53
  10. package/build/src/akuma/akuma.d.ts +6 -4
  11. package/build/src/akuma/akuma.js +4 -0
  12. package/build/src/akuma/call-initial-tell.d.ts +2 -2
  13. package/build/src/akuma/call-initial-tell.js +1 -1
  14. package/build/src/akuma/call-request.d.ts +2 -2
  15. package/build/src/akuma/heart/index.d.ts +7 -2
  16. package/build/src/akuma/heart/index.js +50 -5
  17. package/build/src/akuma/heart/tells.d.ts +33 -2
  18. package/build/src/akuma/heart/tells.js +24 -18
  19. package/build/src/akuma/heart/timeline.d.ts +23 -1
  20. package/build/src/akuma/heart/timeline.js +28 -21
  21. package/build/src/akuma/projection.d.ts +10 -10
  22. package/build/src/akuma/providers/pi/index.js +72 -39
  23. package/build/src/akuma/selection-observation.d.ts +20 -20
  24. package/build/src/akuma-body.js +1 -0
  25. package/build/src/alias/index.d.ts +0 -1
  26. package/build/src/alias/index.js +0 -4
  27. package/build/src/body/amend.d.ts +0 -4
  28. package/build/src/body/amend.js +0 -3
  29. package/build/src/body/region.d.ts +0 -1
  30. package/build/src/body/region.js +0 -3
  31. package/build/src/body/verification.d.ts +0 -1
  32. package/build/src/cli/commands/akuma-grammar.js +23 -66
  33. package/build/src/cli/commands/akuma.js +17 -30
  34. package/build/src/cli/commands/contract-grammar.d.ts +14 -1
  35. package/build/src/cli/commands/contract-grammar.js +54 -21
  36. package/build/src/cli/commands/contract-help.d.ts +9 -8
  37. package/build/src/cli/commands/contract-help.js +14 -7
  38. package/build/src/cli/commands/contract.js +57 -117
  39. package/build/src/cli/commands/install.d.ts +5 -5
  40. package/build/src/cli/commands/install.js +1 -4
  41. package/build/src/cli/commands/task-grammar.js +10 -66
  42. package/build/src/cli/commands/task.d.ts +0 -1
  43. package/build/src/cli/commands/task.js +34 -53
  44. package/build/src/cli/coordinates.d.ts +1 -2
  45. package/build/src/cli/coordinates.js +1 -4
  46. package/build/src/cli/parse.d.ts +2 -3
  47. package/build/src/cli/parse.js +24 -66
  48. package/build/src/cli/render/akuma.d.ts +3 -16
  49. package/build/src/cli/render/akuma.js +1 -13
  50. package/build/src/cli/render/audit.js +1 -1
  51. package/build/src/cli/render/contract.js +34 -32
  52. package/build/src/cli/render/kanshi-akuma.d.ts +8 -2
  53. package/build/src/cli/render/kanshi-akuma.js +14 -7
  54. package/build/src/cli/render/kanshi.d.ts +3 -1
  55. package/build/src/cli/render/kanshi.js +44 -32
  56. package/build/src/cli/render/receipt.js +6 -1
  57. package/build/src/cli/render/task.d.ts +1 -1
  58. package/build/src/cli/render/task.js +3 -27
  59. package/build/src/cli/render/terminal.d.ts +6 -2
  60. package/build/src/cli/render/terminal.js +8 -2
  61. package/build/src/cli/runtime.js +3 -16
  62. package/build/src/cli/scan.d.ts +26 -0
  63. package/build/src/cli/scan.js +82 -0
  64. package/build/src/cli/streams.d.ts +5 -0
  65. package/build/src/cli/streams.js +11 -0
  66. package/build/src/contract-worktree.js +38 -21
  67. package/build/src/core/facts/codec.d.ts +1 -2
  68. package/build/src/core/facts/codec.js +5 -11
  69. package/build/src/core/facts/types.d.ts +16 -2
  70. package/build/src/core/facts/types.js +15 -0
  71. package/build/src/core/verbs/abandon.js +3 -9
  72. package/build/src/core/verbs/amend.js +2 -9
  73. package/build/src/core/verbs/arc.js +6 -13
  74. package/build/src/core/verbs/attestation.js +2 -9
  75. package/build/src/core/verbs/bind.js +2 -9
  76. package/build/src/core/verbs/deliver.js +2 -9
  77. package/build/src/core/verbs/placement.d.ts +1 -1
  78. package/build/src/core/verbs/placement.js +2 -9
  79. package/build/src/core/verbs/reintegrate.d.ts +1 -1
  80. package/build/src/core/verbs/reintegrate.js +2 -9
  81. package/build/src/dispatch/index.d.ts +2 -2
  82. package/build/src/dispatch/index.js +33 -11
  83. package/build/src/git/hooks.d.ts +2 -4
  84. package/build/src/git/hooks.js +0 -12
  85. package/build/src/git/integration.d.ts +5 -3
  86. package/build/src/git/integration.js +36 -25
  87. package/build/src/git/nuke.js +4 -4
  88. package/build/src/git/observe.d.ts +4 -4
  89. package/build/src/git/observe.js +5 -5
  90. package/build/src/git/process.d.ts +1 -4
  91. package/build/src/git/process.js +1 -11
  92. package/build/src/git/read-observation.js +1 -1
  93. package/build/src/git/reconcile.d.ts +1 -1
  94. package/build/src/git/reconcile.js +15 -13
  95. package/build/src/git/repository.d.ts +2 -6
  96. package/build/src/git/repository.js +18 -31
  97. package/build/src/git/scratch.d.ts +6 -6
  98. package/build/src/git/scratch.js +110 -46
  99. package/build/src/git/target-placement.d.ts +5 -5
  100. package/build/src/git/target-placement.js +18 -33
  101. package/build/src/git/tender.d.ts +6 -2
  102. package/build/src/git/tender.js +19 -12
  103. package/build/src/git/terminal-reconcile.js +24 -13
  104. package/build/src/git/terminal-seal.d.ts +2 -5
  105. package/build/src/git/terminal-seal.js +5 -3
  106. package/build/src/git/workspace.d.ts +17 -13
  107. package/build/src/git/workspace.js +58 -41
  108. package/build/src/kanshi/index.d.ts +2 -2
  109. package/build/src/kanshi/index.js +1 -1
  110. package/build/src/kanshi/read.d.ts +8 -1
  111. package/build/src/kanshi/read.js +72 -7
  112. package/build/src/kanshi/report.d.ts +12 -0
  113. package/build/src/library/akuma-creation.d.ts +4 -4
  114. package/build/src/library/bind.d.ts +1 -63
  115. package/build/src/library/bind.js +3 -9
  116. package/build/src/library/contract-creation.js +2 -30
  117. package/build/src/library/contract-execution.d.ts +0 -1
  118. package/build/src/library/contract-execution.js +9 -34
  119. package/build/src/library/contract-operations.d.ts +5 -1
  120. package/build/src/library/contract-operations.js +7 -3
  121. package/build/src/library/contract-types.d.ts +1 -1
  122. package/build/src/library/delivery.d.ts +91 -93
  123. package/build/src/library/delivery.js +2 -1
  124. package/build/src/library/input.d.ts +0 -2
  125. package/build/src/library/input.js +0 -4
  126. package/build/src/library/invocation.d.ts +0 -1
  127. package/build/src/library/invocation.js +3 -25
  128. package/build/src/library/outcome.d.ts +651 -602
  129. package/build/src/library/outcome.js +4 -4
  130. package/build/src/library/reconcile.d.ts +6 -0
  131. package/build/src/library/reconcile.js +31 -1
  132. package/build/src/library/repo.d.ts +0 -1
  133. package/build/src/library/selection.d.ts +1 -10
  134. package/build/src/library/selection.js +14 -15
  135. package/build/src/protocol/abandon.d.ts +1 -1
  136. package/build/src/protocol/abandon.js +3 -10
  137. package/build/src/protocol/amend.js +2 -5
  138. package/build/src/protocol/arc.d.ts +1 -1
  139. package/build/src/protocol/arc.js +2 -9
  140. package/build/src/protocol/attempt.d.ts +3 -20
  141. package/build/src/protocol/attempt.js +6 -5
  142. package/build/src/protocol/audit.d.ts +1 -0
  143. package/build/src/protocol/audit.js +10 -11
  144. package/build/src/protocol/completion.d.ts +129 -55
  145. package/build/src/protocol/completion.js +62 -73
  146. package/build/src/protocol/deliver.d.ts +7 -5
  147. package/build/src/protocol/deliver.js +74 -44
  148. package/build/src/protocol/execution-observation.d.ts +2 -4
  149. package/build/src/protocol/execution-observation.js +3 -7
  150. package/build/src/protocol/intent.d.ts +1 -1
  151. package/build/src/protocol/intent.js +1 -0
  152. package/build/src/protocol/operations.d.ts +24 -12
  153. package/build/src/protocol/operations.js +36 -15
  154. package/build/src/protocol/placement.d.ts +2 -1
  155. package/build/src/protocol/placement.js +21 -5
  156. package/build/src/protocol/progress.d.ts +1 -1
  157. package/build/src/protocol/read/status.js +58 -41
  158. package/build/src/protocol/reintegrate.d.ts +1 -1
  159. package/build/src/protocol/reintegrate.js +10 -19
  160. package/build/src/protocol/review.d.ts +3 -28
  161. package/build/src/protocol/review.js +10 -37
  162. package/build/src/protocol/run.d.ts +19 -7
  163. package/build/src/protocol/run.js +19 -9
  164. package/build/src/runtime/proc/windows-launch.exe +0 -0
  165. package/build/src/settlement/holder.d.ts +2 -4
  166. package/build/src/settlement/holder.js +3 -6
  167. package/build/src/task/board.d.ts +6 -0
  168. package/build/src/task/board.js +30 -1
  169. package/build/src/task/catalog.js +1 -4
  170. package/build/src/task/compose.d.ts +0 -1
  171. package/build/src/task/compose.js +0 -1
  172. package/build/src/task/context.d.ts +0 -1
  173. package/build/src/task/context.js +0 -3
  174. package/build/src/task/created-observation.d.ts +5 -1
  175. package/build/src/task/created-observation.js +12 -5
  176. package/build/src/task/index.d.ts +1 -1
  177. package/build/src/task/index.js +7 -6
  178. package/build/src/task/input.d.ts +0 -6
  179. package/build/src/task/input.js +2 -14
  180. package/build/src/task/mutation.d.ts +3 -4
  181. package/build/src/task/mutation.js +11 -39
  182. package/build/src/task/operations.d.ts +2 -7
  183. package/build/src/task/operations.js +37 -49
  184. package/build/src/task/query.d.ts +0 -1
  185. package/build/src/task/query.js +1 -4
  186. package/build/src/task/store.d.ts +0 -2
  187. package/build/src/task/store.js +27 -11
  188. package/build/src/verification/declaration.js +3 -2
  189. package/build/src/verification/execution.d.ts +3 -2
  190. package/build/src/verification/execution.js +10 -6
  191. package/build/src/workspace-place.d.ts +0 -1
  192. package/build/src/workspace-place.js +0 -11
  193. package/package.json +7 -3
@@ -44,7 +44,7 @@ export type ParsedDeliver = Output & Readonly<{
44
44
  materializeConflict: boolean;
45
45
  overwrite: boolean;
46
46
  }>;
47
- export type ParsedReview = Output & Readonly<{
47
+ export type ParsedReview = Output & Actor & Readonly<{
48
48
  command: "review";
49
49
  contract?: string;
50
50
  verdict: "satisfied" | "unsatisfied";
@@ -66,11 +66,23 @@ export type ParsedStatus = Output & (Readonly<{
66
66
  selectors?: readonly string[];
67
67
  akuma?: never;
68
68
  guidance?: true;
69
+ category?: never;
70
+ limit?: never;
69
71
  }> | Readonly<{
70
72
  command: "status";
71
73
  contract: string;
72
74
  akuma: true;
73
75
  guidance?: never;
76
+ category?: never;
77
+ limit?: never;
78
+ }> | Readonly<{
79
+ command: "status";
80
+ category: StatusCategory;
81
+ limit?: number;
82
+ contract?: never;
83
+ selectors?: never;
84
+ akuma?: never;
85
+ guidance?: never;
74
86
  }>);
75
87
  export type ParsedLs = Output & Readonly<{
76
88
  command: "ls";
@@ -108,5 +120,6 @@ export type ParsedContractParts = Readonly<{
108
120
  actor?: string;
109
121
  }>;
110
122
  export type ParsedContractCommand = ParsedBind | ParsedAmend | ParsedDeliver | ParsedReview | ParsedArc | ParsedAbandon | ParsedStatus | ParsedLs | ParsedAudit | ParsedReconcile | ParsedNuke | ParsedSettings | ParsedRegion;
123
+ export type StatusCategory = "akuma" | "contract";
111
124
  export declare function parseContractCommand(parts: ParsedContractParts): ParsedContractCommand;
112
125
  export {};
@@ -123,32 +123,65 @@ function parseReview(parts) {
123
123
  verdict: parts.flags.satisfied === true ? "satisfied" : "unsatisfied",
124
124
  ...(summary === undefined ? {} : { summary }),
125
125
  ...(parts.stdin ? { summaryFromStdin: true } : {}),
126
+ ...(parts.actor === undefined ? {} : { actor: parts.actor }),
126
127
  output: parts.output,
127
128
  };
128
129
  }
129
- function parseStatus(parts) {
130
- const guidance = parts.flags.guidance === true;
131
- if (guidance) {
132
- const selected = parts.positionals[0];
133
- if (parts.positionals.length > 1)
134
- refuse("status", "--guidance accepts at most one Contract selector");
135
- if (selected?.startsWith("aku/") === true)
136
- refuse("status", "--guidance cannot select an Akuma");
137
- return {
138
- command: "status",
139
- ...(selected === undefined ? {} : { contract: selected }),
140
- guidance: true,
141
- output: parts.output,
142
- };
130
+ // Only these fixed category forms are status selectors.
131
+ const STATUS_CATEGORY_SELECTORS = new Map([
132
+ ["aku", "akuma"],
133
+ ["aku/", "akuma"],
134
+ ["aku/*", "akuma"],
135
+ ["kei", "contract"],
136
+ ["kei/", "contract"],
137
+ ["kei/*", "contract"],
138
+ ]);
139
+ function rejectStatusGlobs(positionals) {
140
+ for (const selector of positionals) {
141
+ if (!STATUS_CATEGORY_SELECTORS.has(selector) && !selector.startsWith("@") && /[*?\[\]]/u.test(selector))
142
+ refuse("status", `unsupported status glob: ${selector}`);
143
143
  }
144
+ }
145
+ function parseStatusGuidance(parts, limit) {
146
+ if (limit !== undefined)
147
+ refuse("status", "--limit is not valid with --guidance");
148
+ const selected = parts.positionals[0];
149
+ if (selected !== undefined && STATUS_CATEGORY_SELECTORS.has(selected))
150
+ refuse("status", "--guidance cannot select a category");
151
+ if (parts.positionals.length > 1)
152
+ refuse("status", "--guidance accepts at most one Contract selector");
153
+ if (selected?.startsWith("aku/") === true)
154
+ refuse("status", "--guidance cannot select an Akuma");
155
+ if (selected !== undefined && !selected.startsWith("@") && /[*?\[\]]/u.test(selected))
156
+ refuse("status", `unsupported status glob: ${selected}`);
157
+ return {
158
+ command: "status",
159
+ ...(selected === undefined ? {} : { contract: selected }),
160
+ guidance: true,
161
+ output: parts.output,
162
+ };
163
+ }
164
+ function parseStatus(parts) {
165
+ const limit = listLimit(parts, "status");
166
+ if (parts.flags.guidance === true)
167
+ return parseStatusGuidance(parts, limit);
168
+ rejectStatusGlobs(parts.positionals);
144
169
  if (parts.positionals.length > 1) {
170
+ if (limit !== undefined)
171
+ refuse("status", "--limit is valid only for one category selector");
172
+ if (parts.positionals.some((selector) => STATUS_CATEGORY_SELECTORS.has(selector)))
173
+ refuse("status", "a category selector cannot combine with other selectors");
145
174
  return { command: "status", selectors: parts.positionals, output: parts.output };
146
175
  }
147
- const contract = parts.positionals[0];
148
- if (contract?.startsWith("aku/") === true) {
149
- return { command: "status", contract, akuma: true, output: parts.output };
150
- }
151
- return { command: "status", ...(contract === undefined ? {} : { contract }), output: parts.output };
176
+ const selected = parts.positionals[0];
177
+ const category = selected === undefined ? undefined : STATUS_CATEGORY_SELECTORS.get(selected);
178
+ if (category !== undefined)
179
+ return { command: "status", category, ...(limit === undefined ? {} : { limit }), output: parts.output };
180
+ if (limit !== undefined)
181
+ refuse("status", "--limit is valid only for a category selector");
182
+ if (selected?.startsWith("aku/") === true)
183
+ return { command: "status", contract: selected, akuma: true, output: parts.output };
184
+ return { command: "status", ...(selected === undefined ? {} : { contract: selected }), output: parts.output };
152
185
  }
153
186
  function parseRegion(parts) {
154
187
  const contract = parts.positionals[0];
@@ -172,10 +205,10 @@ function akumaCatalogQuery(query, parts) {
172
205
  ...(limit === undefined ? {} : { limit: Number(limit) }),
173
206
  };
174
207
  }
175
- function listLimit(parts) {
208
+ function listLimit(parts, command = "ls") {
176
209
  const limit = optionalFlag(parts.flags, "limit");
177
210
  if (limit !== undefined && (!/^[1-9][0-9]*$/u.test(limit) || !Number.isSafeInteger(Number(limit))))
178
- refuse("ls", "--limit requires a positive safe integer");
211
+ refuse(command, "--limit requires a positive safe integer");
179
212
  return limit === undefined ? undefined : Number(limit);
180
213
  }
181
214
  function taskCatalogQuery(path, limit) {
@@ -1,8 +1,8 @@
1
- type ContractFlagKind = "boolean" | "value" | "raw-value" | "repeat-value";
1
+ import type { ScanFlagKind } from "../scan.js";
2
2
  export type ContractCommandSpec = Readonly<{
3
3
  positional: "none" | "optional";
4
4
  stdin: "none" | "optional" | "required";
5
- flags: Readonly<Record<string, ContractFlagKind>>;
5
+ flags: Readonly<Record<string, ScanFlagKind>>;
6
6
  usage: string;
7
7
  purpose: string;
8
8
  details?: string;
@@ -15,7 +15,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
15
15
  readonly actor: "value";
16
16
  readonly task: "value";
17
17
  readonly target: "value";
18
- readonly after: "repeat-value";
18
+ readonly after: "repeat";
19
19
  readonly gates: "raw-value";
20
20
  readonly "fork-of": "value";
21
21
  readonly json: "boolean";
@@ -29,7 +29,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
29
29
  readonly stdin: "optional";
30
30
  readonly flags: {
31
31
  readonly actor: "value";
32
- readonly after: "repeat-value";
32
+ readonly after: "repeat";
33
33
  readonly "clear-after": "boolean";
34
34
  readonly gates: "raw-value";
35
35
  readonly json: "boolean";
@@ -56,12 +56,13 @@ export declare const CONTRACT_COMMAND_SPECS: {
56
56
  readonly positional: "optional";
57
57
  readonly stdin: "optional";
58
58
  readonly flags: {
59
+ readonly actor: "value";
59
60
  readonly satisfied: "boolean";
60
61
  readonly unsatisfied: "boolean";
61
62
  readonly summary: "value";
62
63
  readonly json: "boolean";
63
64
  };
64
- readonly usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -)";
65
+ readonly usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>]";
65
66
  readonly purpose: "Record whether a Contract meets its acceptance criteria.";
66
67
  readonly details: string;
67
68
  };
@@ -92,9 +93,10 @@ export declare const CONTRACT_COMMAND_SPECS: {
92
93
  readonly stdin: "none";
93
94
  readonly flags: {
94
95
  readonly guidance: "boolean";
96
+ readonly limit: "value";
95
97
  readonly json: "boolean";
96
98
  };
97
- readonly usage: "status [<contract>|@name|<aku/...>]...\nstatus --guidance [<contract>|@<contract>]";
99
+ readonly usage: "status [<contract>|@name|<aku/...>]...\nstatus (aku|aku/|aku/*) [--limit <count>]\nstatus (kei|kei/|kei/*) [--limit <count>]\nstatus --guidance [<contract>|@<contract>]";
98
100
  readonly purpose: "Show the world overview or selected Contract and Akuma status.";
99
101
  readonly details: string;
100
102
  };
@@ -156,7 +158,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
156
158
  readonly positional: "optional";
157
159
  readonly stdin: "none";
158
160
  readonly flags: {
159
- readonly path: "repeat-value";
161
+ readonly path: "repeat";
160
162
  readonly json: "boolean";
161
163
  };
162
164
  readonly usage: "region [<contract>]\nregion --path <pattern> [--path <pattern> ...]";
@@ -166,4 +168,3 @@ export declare const CONTRACT_COMMAND_SPECS: {
166
168
  };
167
169
  export type ContractCommand = keyof typeof CONTRACT_COMMAND_SPECS;
168
170
  export declare function renderContractHelp(command: ContractCommand): string;
169
- export {};
@@ -7,7 +7,7 @@ export const CONTRACT_COMMAND_SPECS = {
7
7
  actor: "value",
8
8
  task: "value",
9
9
  target: "value",
10
- after: "repeat-value",
10
+ after: "repeat",
11
11
  gates: "raw-value",
12
12
  "fork-of": "value",
13
13
  json: "boolean",
@@ -47,6 +47,7 @@ export const CONTRACT_COMMAND_SPECS = {
47
47
  "A pattern containing whitespace binds with a warning. A fence carries no",
48
48
  "info string or exactly 'txt'.",
49
49
  "",
50
+ "Verification runs only with the verified gate; without it the section is inert text.",
50
51
  "Verification uses one or more closed bash, zsh, or pwsh fences. Its fence",
51
52
  "may add timeout=<integer><ms|s|m|h>; the section contains no other prose.",
52
53
  "Unknown ## sections are retained as extensions; reserved section names are refused.",
@@ -55,7 +56,7 @@ export const CONTRACT_COMMAND_SPECS = {
55
56
  amend: {
56
57
  positional: "optional",
57
58
  stdin: "optional",
58
- flags: { actor: "value", after: "repeat-value", "clear-after": "boolean", gates: "raw-value", json: "boolean" },
59
+ flags: { actor: "value", after: "repeat", "clear-after": "boolean", gates: "raw-value", json: "boolean" },
59
60
  usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name,...>] [--actor <actor>] [-]",
60
61
  purpose: "Change a Contract's document, prerequisites, or acceptance gates.",
61
62
  details: [
@@ -91,6 +92,7 @@ export const CONTRACT_COMMAND_SPECS = {
91
92
  purpose: "Submit work for a Contract and integrate it when its requirements are met.",
92
93
  details: [
93
94
  "The Contract, not the current Arc, sets what delivery must satisfy. An Arc records progress; it does not narrow acceptance.",
95
+ "With the verified gate, delivery runs Verification or reuses current satisfied evidence.",
94
96
  "Verification, integration, and cleanup progress appears on stderr; stdout contains one final result.",
95
97
  "By default, delivery uses HEAD. --include-dirty includes all non-ignored worktree changes, staged or not; it leaves your branch and index unchanged, so staging or committing is unnecessary.",
96
98
  "Repeating delivery with unchanged work resumes unfinished verification or integration. Changed work replaces the candidate.",
@@ -107,8 +109,8 @@ export const CONTRACT_COMMAND_SPECS = {
107
109
  review: {
108
110
  positional: "optional",
109
111
  stdin: "optional",
110
- flags: { satisfied: "boolean", unsatisfied: "boolean", summary: "value", json: "boolean" },
111
- usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -)",
112
+ flags: { actor: "value", satisfied: "boolean", unsatisfied: "boolean", summary: "value", json: "boolean" },
113
+ usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>]",
112
114
  purpose: "Record whether a Contract meets its acceptance criteria.",
113
115
  details: [
114
116
  "A review checks the whole Contract, not just one Arc. After delivery it checks the candidate; before delivery it checks the current Contract and worktree, but cannot integrate.",
@@ -141,12 +143,16 @@ export const CONTRACT_COMMAND_SPECS = {
141
143
  status: {
142
144
  positional: "optional",
143
145
  stdin: "none",
144
- flags: { guidance: "boolean", json: "boolean" },
145
- usage: "status [<contract>|@name|<aku/...>]...\nstatus --guidance [<contract>|@<contract>]",
146
+ flags: { guidance: "boolean", limit: "value", json: "boolean" },
147
+ usage: "status [<contract>|@name|<aku/...>]...\nstatus (aku|aku/|aku/*) [--limit <count>]\nstatus (kei|kei/|kei/*) [--limit <count>]\nstatus --guidance [<contract>|@<contract>]",
146
148
  purpose: "Show the world overview or selected Contract and Akuma status.",
147
149
  details: [
148
150
  "Akuma entries show the directory each Akuma was started in.",
149
151
  "",
152
+ "aku, aku/, and aku/* show the recent Akuma board; kei, kei/, and kei/* show the",
153
+ "recent active Contract board. --limit bounds the board to that many recent rows",
154
+ "(default 10). The Contract category requires a Repo; the Akuma category does not.",
155
+ "",
150
156
  "--guidance reads one Contract's guidance instead of status. It accepts one Contract",
151
157
  "selector or the installed Contract selection context, and refuses an Akuma, plural,",
152
158
  "or world selection before the read.",
@@ -173,6 +179,7 @@ export const CONTRACT_COMMAND_SPECS = {
173
179
  details: [
174
180
  "--include-dirty checks all non-ignored worktree changes, staged or not.",
175
181
  "--show-diff includes the proposed candidate diff when one can be prepared.",
182
+ "Verification runs only with the verified gate; without it the section is inert text.",
176
183
  "Content identity names the change's content hash, never a commit; it survives rebase and Git cannot look it up.",
177
184
  "Progress appears on stderr; stdout contains one final result.",
178
185
  ].join("\n"),
@@ -203,7 +210,7 @@ export const CONTRACT_COMMAND_SPECS = {
203
210
  region: {
204
211
  positional: "optional",
205
212
  stdin: "none",
206
- flags: { path: "repeat-value", json: "boolean" },
213
+ flags: { path: "repeat", json: "boolean" },
207
214
  usage: "region [<contract>]\nregion --path <pattern> [--path <pattern> ...]",
208
215
  purpose: "Show declared Contract write patterns — all, one Contract's, or those overlapping given paths.",
209
216
  details: "Check overlap before starting parallel work.",
@@ -1,7 +1,7 @@
1
1
  import { listArchetypeDefinitions } from "../../akuma/archetype.js";
2
2
  import { executionChannel } from "../../akuma/requests.js";
3
3
  import { Akumas, Keiyaku, KeiyakuError, nuke } from "../../index.js";
4
- import { kanshi, observeKanshi, selectKanshi, selectRegion } from "../../kanshi/index.js";
4
+ import { kanshi, kanshiCategory, observeKanshi, selectKanshi, selectRegion } from "../../kanshi/index.js";
5
5
  import { resolveNamedAddress } from "../../library/address.js";
6
6
  import { composeContractLibrary, observeKeiyaku } from "../../library/contract-composition.js";
7
7
  import { validateArcMarkdown, validateContractMarkdown } from "../../library/input.js";
@@ -14,14 +14,14 @@ import { BindDraftError, preserveBindDraft } from "../draft.js";
14
14
  import { snapshotText } from "../render/akuma-activity.js";
15
15
  import { renderAkumaCatalogue, renderArchetypeCatalogue, renderContractCatalogue, renderTaskCatalogue, } from "../render/catalog.js";
16
16
  import { renderAccepted, renderContractHistory, renderRetry } from "../render/contract.js";
17
- import { renderKanshiText } from "../render/kanshi.js";
17
+ import { renderKanshiCategoryText, renderKanshiText } from "../render/kanshi.js";
18
18
  import { nukeExitCode, renderNukeText } from "../render/nuke.js";
19
19
  import { reconcileHasFailure, renderReconcile } from "../render/reconcile.js";
20
20
  import { renderConflictMaterialized, renderRefusal } from "../render/refusal.js";
21
21
  import { renderRegionText } from "../render/region.js";
22
22
  import { renderSettingsText, settingsJsonValue } from "../render/settings.js";
23
23
  import { canonicalContractSelector, contractFromInput, resolveContractId, resolveKanshiContract, } from "../selectors.js";
24
- import { displayContext, writeJson, writeStdout } from "../streams.js";
24
+ import { displayContext, emit, writeJson, writeStdout } from "../streams.js";
25
25
  import { CliUsageError, isBlankInput } from "../usage.js";
26
26
  import { amendFromCommand } from "./amend.js";
27
27
  import { bindFromCommand } from "./bind.js";
@@ -120,11 +120,8 @@ function renderContractAnswer(answer, project, context) {
120
120
  }
121
121
  }
122
122
  async function finishContractAnswer(answer, output, project) {
123
- if (output === "json")
124
- writeJson(answer);
125
- else
126
- writeStdout(renderContractAnswer(answer, project, displayContext()));
127
- return contractExitCode(answer);
123
+ const text = () => renderContractAnswer(answer, project, displayContext());
124
+ return emit(output, answer, text, contractExitCode(answer));
128
125
  }
129
126
  async function selectedContract(repo, selector, scope) {
130
127
  const id = await resolveContractId(repo, selector, scope);
@@ -187,11 +184,8 @@ async function runBind(command, input, library) {
187
184
  if (answer.kind !== "refused")
188
185
  return await finishContractAnswer(answer, command.output);
189
186
  const draft = await bindDraftReceipt(coordinates.establishWorld, markdown);
190
- if (command.output === "json")
191
- writeJson(answer);
192
- else
193
- writeStdout(renderRefusal(refusedInvocation(answer), draft, displayContext()));
194
- return 1;
187
+ const text = () => renderRefusal(refusedInvocation(answer), draft, displayContext());
188
+ return emit(command.output, answer, text, 1);
195
189
  }
196
190
  catch (error) {
197
191
  if (error instanceof Error && "executionReceipt" in error)
@@ -247,6 +241,7 @@ async function runReview(command, runtime, seat) {
247
241
  answer = await seat.contract.review({
248
242
  verdict: command.verdict,
249
243
  ...(summary === undefined ? {} : { summary }),
244
+ ...(seat.actor === undefined ? {} : { actor: seat.actor }),
250
245
  ...(runtime.signal === undefined ? {} : { signal: runtime.signal }),
251
246
  }, { ...(driver === undefined ? {} : { observe: driver.observe }) });
252
247
  }
@@ -265,11 +260,8 @@ async function runArc(command, runtime, seat) {
265
260
  if (!(error instanceof TypeError) && !(error instanceof KeiyakuError && error.category === "invalid-input"))
266
261
  throw error;
267
262
  const refusal = { kind: "invalid-document", diagnostic: error.message };
268
- if (command.output === "json")
269
- writeJson({ kind: "refused", operation: "arc", contract: seat.id, refusal });
270
- else
271
- writeStdout(renderRefusal({ operation: "arc", contract: seat.id, refusal }, undefined, displayContext()));
272
- return 1;
263
+ const refused = { kind: "refused", operation: "arc", contract: seat.id, refusal };
264
+ return emit(command.output, refused, () => renderRefusal(refused, undefined, displayContext()), 1);
273
265
  }
274
266
  const answer = await seat.contract.arc({
275
267
  markdown,
@@ -325,11 +317,7 @@ function statusRefusal(operation, contract) {
325
317
  }
326
318
  async function runSettings(coordinates, home, output) {
327
319
  const value = await settingsAt(coordinates.world ?? undefined, home);
328
- if (output === "json")
329
- writeJson(settingsJsonValue(value));
330
- else
331
- writeStdout(renderSettingsText(value, displayContext().columns));
332
- return 0;
320
+ return emit(output, settingsJsonValue(value), () => renderSettingsText(value, displayContext().columns), 0);
333
321
  }
334
322
  async function runNuke(command, coordinates) {
335
323
  if (coordinates.world === null)
@@ -338,11 +326,7 @@ async function runNuke(command, coordinates) {
338
326
  world: coordinates.world,
339
327
  ...(command.confirm === undefined ? {} : { confirm: command.confirm }),
340
328
  });
341
- if (command.output === "json")
342
- writeJson(result);
343
- else
344
- writeStdout(renderNukeText(result));
345
- return nukeExitCode(result);
329
+ return emit(command.output, result, () => renderNukeText(result), nukeExitCode(result));
346
330
  }
347
331
  async function runLs(command, coordinates, home) {
348
332
  const query = command.query;
@@ -351,11 +335,7 @@ async function runLs(command, coordinates, home) {
351
335
  repo: requiredRepo(coordinates),
352
336
  ...(query.limit === undefined ? {} : { limit: query.limit }),
353
337
  });
354
- if (command.output === "json")
355
- writeJson(list);
356
- else
357
- writeStdout(renderContractCatalogue(list));
358
- return 0;
338
+ return emit(command.output, list, () => renderContractCatalogue(list), 0);
359
339
  }
360
340
  if (query.kind === "archetypes") {
361
341
  const list = await listArchetypeDefinitions({
@@ -363,11 +343,7 @@ async function runLs(command, coordinates, home) {
363
343
  ...(query.limit === undefined ? {} : { limit: query.limit }),
364
344
  ...(home === undefined ? {} : { home }),
365
345
  });
366
- if (command.output === "json")
367
- writeJson(list);
368
- else
369
- writeStdout(renderArchetypeCatalogue(list));
370
- return 0;
346
+ return emit(command.output, list, () => renderArchetypeCatalogue(list), 0);
371
347
  }
372
348
  if (coordinates.world === null)
373
349
  throw new CliUsageError("no Keiyaku world contains the invocation cwd");
@@ -379,21 +355,13 @@ async function runLs(command, coordinates, home) {
379
355
  });
380
356
  if (listed.kind !== "accepted")
381
357
  throw new Error("Task list did not return an accepted observation");
382
- if (command.output === "json")
383
- writeJson(listed);
384
- else
385
- writeStdout(renderTaskCatalogue(listed.value, query.namespace ?? []));
386
- return 0;
358
+ return emit(command.output, listed, () => renderTaskCatalogue(listed.value, query.namespace ?? []), 0);
387
359
  }
388
360
  const listed = await Akumas.of(coordinates.world).list({
389
361
  ...(query.archetype === undefined ? {} : { archetype: query.archetype }),
390
362
  ...(query.limit === undefined ? {} : { limit: query.limit }),
391
363
  });
392
- if (command.output === "json")
393
- writeJson(listed);
394
- else
395
- writeStdout(renderAkumaCatalogue(listed, query.archetype ?? null));
396
- return 0;
364
+ return emit(command.output, listed, () => renderAkumaCatalogue(listed, query.archetype ?? null), 0);
397
365
  }
398
366
  async function readAkumaStatus(akuma, alias, coordinates) {
399
367
  if (coordinates.world === null)
@@ -437,17 +405,10 @@ async function runStatusGuidance(command, coordinates) {
437
405
  const selected = await selectedContract(repo, command.contract, coordinates.cwd);
438
406
  const guidance = await selected.contract.guidance();
439
407
  if (guidance === null) {
440
- if (command.output === "json")
441
- writeJson(null);
442
- else
443
- writeStdout(renderRefusal(statusRefusal("status", selected.id), undefined, displayContext()));
444
- return 1;
408
+ const refusal = statusRefusal("status", selected.id);
409
+ return emit(command.output, null, () => renderRefusal(refusal, undefined, displayContext()), 1);
445
410
  }
446
- if (command.output === "json")
447
- writeJson(guidance);
448
- else
449
- writeStdout(guidance);
450
- return 0;
411
+ return emit(command.output, guidance, () => guidance, 0);
451
412
  }
452
413
  async function runStatusSelection(command, coordinates) {
453
414
  const selectors = command.selectors;
@@ -474,63 +435,43 @@ async function runStatusSelection(command, coordinates) {
474
435
  if (command.output === "text")
475
436
  blocks.push(resolved.project());
476
437
  }
477
- if (command.output === "json")
478
- writeJson(values);
479
- else
480
- writeStdout(blocks.join("\n\n"));
481
- return 0;
438
+ return emit(command.output, values, () => blocks.join("\n\n"), 0);
482
439
  }
483
- async function runStatus(command, coordinates) {
484
- if (command.guidance === true)
485
- return await runStatusGuidance(command, coordinates);
486
- if ("selectors" in command && command.selectors !== undefined)
487
- return await runStatusSelection({ ...command, selectors: command.selectors }, coordinates);
488
- if (command.akuma === true && command.contract !== undefined) {
489
- const resolved = await readAkumaStatus(command.contract, undefined, coordinates);
490
- if (command.output === "json")
491
- writeJson(resolved.value);
492
- else
493
- writeStdout(resolved.project());
494
- return 0;
495
- }
440
+ async function runStatusCategory(command, coordinates) {
441
+ if (command.category === "contract")
442
+ requiredRepo(coordinates);
443
+ const report = await kanshiCategory({
444
+ world: coordinates.world,
445
+ ...(coordinates.repo === undefined ? {} : { repo: coordinates.repo }),
446
+ category: command.category,
447
+ ...(command.limit === undefined ? {} : { limit: command.limit }),
448
+ });
449
+ return emit(command.output, report, () => renderKanshiCategoryText(report, displayContext()), 0);
450
+ }
451
+ async function runStatusIdentity(command, coordinates) {
496
452
  if (command.contract === undefined) {
497
453
  const report = await kanshi({
498
454
  world: coordinates.world,
499
455
  ...(coordinates.repo === undefined ? {} : { repo: coordinates.repo }),
500
456
  });
501
- if (command.output === "json")
502
- writeJson(report);
503
- else
504
- writeStdout(renderKanshiText(report, displayContext(), "world"));
505
- return 0;
457
+ return emit(command.output, report, () => renderKanshiText(report, displayContext(), "world"), 0);
506
458
  }
507
459
  if (command.contract.startsWith("@")) {
508
460
  const resolved = await namedStatus(command.contract, coordinates, await observeKanshi({
509
461
  world: coordinates.world,
510
462
  ...(coordinates.repo === undefined ? {} : { repo: coordinates.repo }),
511
463
  }));
512
- if (command.output === "json")
513
- writeJson(resolved.value);
514
- else
515
- writeStdout(resolved.project());
516
- return 0;
464
+ return emit(command.output, resolved.value, () => resolved.project(), 0);
517
465
  }
518
466
  if (command.contract.startsWith("kei/")) {
519
467
  const repo = requiredRepo(coordinates);
520
468
  const contract = canonicalContractSelector(command.contract);
521
469
  const report = await kanshi({ world: coordinates.world, repo, contract });
522
470
  if (report.contracts.kind === "present" && report.contracts.value.rows.length === 0) {
523
- if (command.output === "json")
524
- writeJson(statusRefusal("status", contract).refusal);
525
- else
526
- writeStdout(renderRefusal(statusRefusal("status", contract), undefined, displayContext()));
527
- return 1;
471
+ const refusal = statusRefusal("status", contract);
472
+ return emit(command.output, refusal.refusal, () => renderRefusal(refusal, undefined, displayContext()), 1);
528
473
  }
529
- if (command.output === "json")
530
- writeJson(report);
531
- else
532
- writeStdout(renderKanshiText(report, displayContext(), "contract"));
533
- return 0;
474
+ return emit(command.output, report, () => renderKanshiText(report, displayContext(), "contract"), 0);
534
475
  }
535
476
  const report = await kanshi({
536
477
  world: coordinates.world,
@@ -538,28 +479,31 @@ async function runStatus(command, coordinates) {
538
479
  });
539
480
  const contract = resolveKanshiContract(report, command.contract);
540
481
  const selected = selectKanshi({ report, contract });
541
- if (command.output === "json")
542
- writeJson(selected);
543
- else
544
- writeStdout(renderKanshiText(selected, displayContext(), "contract"));
545
- return 0;
482
+ return emit(command.output, selected, () => renderKanshiText(selected, displayContext(), "contract"), 0);
483
+ }
484
+ async function runStatus(command, coordinates) {
485
+ if (command.guidance === true)
486
+ return await runStatusGuidance(command, coordinates);
487
+ if (command.category !== undefined)
488
+ return await runStatusCategory(command, coordinates);
489
+ if ("selectors" in command && command.selectors !== undefined)
490
+ return await runStatusSelection({ ...command, selectors: command.selectors }, coordinates);
491
+ if (command.akuma === true && command.contract !== undefined) {
492
+ const resolved = await readAkumaStatus(command.contract, undefined, coordinates);
493
+ return emit(command.output, resolved.value, () => resolved.project(), 0);
494
+ }
495
+ return await runStatusIdentity(command, coordinates);
546
496
  }
547
497
  async function runRegion(command, coordinates) {
548
498
  const repo = requiredRepo(coordinates);
549
- const emit = (section) => {
550
- if (command.output === "json")
551
- writeJson(section);
552
- else
553
- writeStdout(renderRegionText(section));
554
- return 0;
555
- };
499
+ const emitSection = (section) => emit(command.output, section, () => renderRegionText(section), 0);
556
500
  if (command.paths !== undefined) {
557
501
  const report = await kanshi({ world: coordinates.world, repo, region: { kind: "path", patterns: command.paths } });
558
- return emit(report.region ?? { kind: "absent" });
502
+ return emitSection(report.region ?? { kind: "absent" });
559
503
  }
560
504
  const report = await kanshi({ world: coordinates.world, repo, region: { kind: "declarations" } });
561
505
  if (command.contract === undefined)
562
- return emit(report.region ?? { kind: "absent" });
506
+ return emitSection(report.region ?? { kind: "absent" });
563
507
  const contract = resolveKanshiContract(report, command.contract);
564
508
  const observed = await observeKeiyaku({ repo, id: contract });
565
509
  if (observed.kind === "missing" || observed.row.phase === "claimed" || observed.row.phase === "abandoned") {
@@ -574,8 +518,8 @@ async function runRegion(command, coordinates) {
574
518
  return 1;
575
519
  }
576
520
  if (report.region?.kind !== "present" || report.region.value.kind !== "declarations")
577
- return emit(report.region ?? { kind: "absent" });
578
- return emit({
521
+ return emitSection(report.region ?? { kind: "absent" });
522
+ return emitSection({
579
523
  kind: "present",
580
524
  value: selectRegion({
581
525
  declarations: report.region.value.declarations,
@@ -595,11 +539,7 @@ export async function runContractHistoryCommand(command, coordinates) {
595
539
  writeStdout(renderRefusal({ operation: "history", contract: selected.id, refusal }, undefined, displayContext()));
596
540
  return 1;
597
541
  }
598
- if (command.output === "json")
599
- writeJson(history);
600
- else
601
- writeStdout(renderContractHistory(history, { full: command.full }));
602
- return 0;
542
+ return emit(command.output, history, () => renderContractHistory(history, { full: command.full }), 0);
603
543
  }
604
544
  async function runReconcile(command, coordinates, execution, home) {
605
545
  const repo = requiredRepo(coordinates);
@@ -1,12 +1,12 @@
1
1
  import type { ProcessInput, ProcessOutcome } from "../../runtime/proc/run.js";
2
- export declare const HARNESS_NAMES: readonly ["codex", "claude", "opencode", "pi"];
3
- export type HarnessName = (typeof HARNESS_NAMES)[number];
2
+ declare const HARNESS_NAMES: readonly ["codex", "claude", "opencode", "pi"];
3
+ type HarnessName = (typeof HARNESS_NAMES)[number];
4
4
  export type ParsedInstallCommand = Readonly<{
5
5
  command: "install";
6
6
  harnesses: readonly HarnessName[];
7
7
  output: "text" | "json";
8
8
  }>;
9
- export type HarnessInstallResult = Readonly<{
9
+ type HarnessInstallResult = Readonly<{
10
10
  harness: HarnessName;
11
11
  status: "installed" | "failed";
12
12
  diagnostic?: string;
@@ -15,12 +15,12 @@ export type InstallInvocationResult = Readonly<{
15
15
  kind: "install";
16
16
  results: readonly HarnessInstallResult[];
17
17
  }>;
18
- export type InstallRunner = (input: ProcessInput) => Promise<ProcessOutcome>;
18
+ type InstallRunner = (input: ProcessInput) => Promise<ProcessOutcome>;
19
19
  export declare const INSTALL_USAGE = "install <codex|claude|opencode|pi>\ninstall --all";
20
20
  export declare const INSTALL_ROOT_PURPOSE = "Install the Keiyaku plugin into a supported coding harness.";
21
21
  export declare function parseInstallCommand(argv: readonly string[]): ParsedInstallCommand;
22
22
  export declare function renderInstallHelp(): string;
23
- export declare function installAssetsRoot(): string;
24
23
  export declare function installHarnesses(harnesses: readonly HarnessName[], environment: NodeJS.ProcessEnv, runner?: InstallRunner): Promise<InstallInvocationResult>;
25
24
  export declare function renderInstallText(result: InstallInvocationResult): string;
26
25
  export declare function installExitCode(result: InstallInvocationResult): number;
26
+ export {};