@astrosheep/keiyaku 2.9.12 → 2.9.13

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 (212) hide show
  1. package/README.md +22 -18
  2. package/build/.tsbuildinfo +1 -1
  3. package/build/agents/call-terms.js +1 -0
  4. package/build/agents/providers/claude-agent-sdk/adapter.js +2 -2
  5. package/build/cli/commands/akuma/akuma/handler.js +2 -1
  6. package/build/cli/commands/akuma/akuma/meta.js +4 -3
  7. package/build/cli/commands/akuma/catalog.js +2 -0
  8. package/build/cli/commands/akuma/list/handler.js +1 -1
  9. package/build/cli/commands/akuma/list/meta-list.js +12 -0
  10. package/build/cli/commands/akuma/list/meta-ls.js +2 -2
  11. package/build/cli/commands/akuma.js +5 -0
  12. package/build/cli/commands/contract/amend/meta.js +4 -3
  13. package/build/cli/commands/contract/arc/meta.js +2 -0
  14. package/build/cli/commands/contract/audit/handler.js +28 -2
  15. package/build/cli/commands/contract/audit/meta.js +4 -3
  16. package/build/cli/commands/contract/petition/handler.js +2 -1
  17. package/build/cli/commands/contract/petition/meta.js +2 -2
  18. package/build/cli/commands/contract/renew/handler.js +44 -3
  19. package/build/cli/commands/contract/renew/meta.js +5 -4
  20. package/build/cli/commands/metadata.js +12 -9
  21. package/build/cli/commands/projection/call/handler.js +1 -1
  22. package/build/cli/commands/projection/call/meta.js +1 -1
  23. package/build/cli/commands/projection/catalog.js +2 -2
  24. package/build/cli/commands/projection/{revive → fork}/handler.js +10 -5
  25. package/build/cli/commands/projection/fork/meta.js +12 -0
  26. package/build/cli/commands/projection/history/handler.js +46 -2
  27. package/build/cli/commands/projection/history/meta.js +3 -3
  28. package/build/cli/commands/projection/kill/meta.js +2 -2
  29. package/build/cli/commands/projection/status/handler.js +29 -13
  30. package/build/cli/commands/projection/status/meta.js +14 -3
  31. package/build/cli/commands/projection/tell/handler.js +8 -4
  32. package/build/cli/commands/projection/tell/meta.js +1 -1
  33. package/build/cli/commands/projection/wait/handler.js +45 -20
  34. package/build/cli/commands/projection/wait/meta.js +1 -1
  35. package/build/cli/commands/shared.js +1 -1
  36. package/build/cli/commands/system/catalog.js +2 -0
  37. package/build/cli/commands/task/add/handler.js +28 -12
  38. package/build/cli/commands/task/add/meta.js +18 -6
  39. package/build/cli/commands/task/catalog.js +2 -0
  40. package/build/cli/commands/task/compose/handler.js +2 -2
  41. package/build/cli/commands/task/compose/meta.js +2 -2
  42. package/build/cli/commands/task/doctor/handler.js +2 -3
  43. package/build/cli/commands/task/doctor/meta.js +2 -2
  44. package/build/cli/commands/task/done/meta.js +2 -2
  45. package/build/cli/commands/task/drop/handler.js +7 -2
  46. package/build/cli/commands/task/drop/meta.js +6 -3
  47. package/build/cli/commands/task/hold/meta.js +2 -2
  48. package/build/cli/commands/task/log/meta.js +2 -2
  49. package/build/cli/commands/task/ls/meta.js +2 -2
  50. package/build/cli/commands/task/note/handler.js +6 -0
  51. package/build/cli/commands/task/note/meta.js +11 -0
  52. package/build/cli/commands/task/resume/meta.js +2 -2
  53. package/build/cli/commands/task/shared.js +29 -15
  54. package/build/cli/commands/task/show/meta.js +2 -2
  55. package/build/cli/commands/task/start/meta.js +2 -2
  56. package/build/cli/commands/task/stop/meta.js +2 -2
  57. package/build/cli/commands/task/update/meta.js +3 -2
  58. package/build/cli/commands/verification/handler.js +43 -0
  59. package/build/cli/commands/verification/meta.js +13 -0
  60. package/build/cli/completion.js +16 -13
  61. package/build/cli/flags.js +43 -11
  62. package/build/cli/help.js +29 -30
  63. package/build/cli/index.js +6 -5
  64. package/build/cli/parse-flags.js +39 -0
  65. package/build/cli/parse-metadata.js +5 -2
  66. package/build/cli/parse-selectors.js +18 -0
  67. package/build/cli/parse.js +21 -8
  68. package/build/cli/render/arc.js +12 -3
  69. package/build/cli/render/audit.js +2 -2
  70. package/build/cli/render/call.js +4 -4
  71. package/build/cli/render/kanshi.js +122 -85
  72. package/build/cli/render/misc.js +2 -2
  73. package/build/cli/render/petition.js +16 -1
  74. package/build/cli/render/projection-history.js +17 -4
  75. package/build/cli/render/shared.js +5 -5
  76. package/build/cli/render/status-indicator.js +47 -0
  77. package/build/cli/render/status.js +106 -76
  78. package/build/cli/render/success-response.js +20 -5
  79. package/build/cli/render/task.js +6 -5
  80. package/build/cli/render/tell.js +10 -4
  81. package/build/cli/render/tool-command-normalization.js +137 -0
  82. package/build/cli/render/tool-presentation.js +2 -1
  83. package/build/cli/render/verification.js +23 -0
  84. package/build/cli/render/wait.js +101 -33
  85. package/build/cli/types.js +2 -1
  86. package/build/config/akuma-loader.js +21 -1
  87. package/build/config/settings/knobs.js +7 -1
  88. package/build/config/settings/schema.js +10 -5
  89. package/build/core/amend.js +102 -17
  90. package/build/core/arc.js +4 -4
  91. package/build/core/audit/candidate.js +10 -18
  92. package/build/core/audit/coordinates.js +12 -17
  93. package/build/core/audit/evidence.js +6 -4
  94. package/build/core/audit/facade.js +3 -3
  95. package/build/core/audit/report.js +1 -1
  96. package/build/core/bind-reconciliation.js +42 -23
  97. package/build/core/bind.js +182 -81
  98. package/build/core/call/call.js +6 -7
  99. package/build/core/call/context.js +43 -30
  100. package/build/core/call/execution.js +21 -6
  101. package/build/core/call/prompt.js +11 -42
  102. package/build/core/contract-carrier-runtime.js +209 -105
  103. package/build/core/contract-carrier.js +156 -73
  104. package/build/core/contract-view.js +42 -5
  105. package/build/core/contract.js +2 -1
  106. package/build/core/derived-replay.js +168 -35
  107. package/build/core/draft.js +9 -5
  108. package/build/core/forfeit.js +1 -1
  109. package/build/core/lifecycle-history.js +13 -0
  110. package/build/core/lifecycle-recovery.js +32 -27
  111. package/build/core/lifecycle-runner.js +14 -14
  112. package/build/core/log.js +1 -1
  113. package/build/core/outcome-base.js +2 -2
  114. package/build/core/projection/akuma-name.js +43 -0
  115. package/build/core/projection/generation/database.js +141 -79
  116. package/build/core/projection/generation/ledger.js +91 -0
  117. package/build/core/projection/generation/model.js +18 -13
  118. package/build/core/projection/generation/projection-generation-continuation.js +1 -1
  119. package/build/core/projection/generation/projection-generation-doorbell.js +88 -0
  120. package/build/core/projection/generation/projection-generation-execution.js +24 -0
  121. package/build/core/projection/generation/projection-generation-identity.js +4 -0
  122. package/build/core/projection/generation/projection-generation-launcher.js +72 -138
  123. package/build/core/projection/generation/projection-generation-process.js +16 -15
  124. package/build/core/projection/generation/projection-generation-runner.js +125 -79
  125. package/build/core/projection/generation/projection-generation-runtime.js +10 -61
  126. package/build/core/projection/generation/protocol.js +68 -0
  127. package/build/core/projection/generation/store.js +17 -7
  128. package/build/core/projection/generation/transitions.js +14 -14
  129. package/build/core/projection/index.js +5 -5
  130. package/build/core/projection/projection-core.js +6 -2
  131. package/build/core/projection/projection-execution-observer.js +1 -1
  132. package/build/core/projection/projection-history.js +7 -7
  133. package/build/core/projection/projection-kill.js +15 -6
  134. package/build/core/projection/projection-life-observer.js +8 -8
  135. package/build/core/projection/projection-mint.js +6 -8
  136. package/build/core/projection/projection-status-observation.js +77 -8
  137. package/build/core/projection/projection-status.js +151 -4
  138. package/build/core/projection/projection-wait.js +46 -27
  139. package/build/core/projection/projection-wake.js +27 -89
  140. package/build/core/projection/tell/launch-store.js +1 -1
  141. package/build/core/projection/tell/store.js +1 -1
  142. package/build/core/renew-build.js +204 -74
  143. package/build/core/renew-plan.js +34 -9
  144. package/build/core/renew-rewrite.js +56 -15
  145. package/build/core/renew.js +39 -35
  146. package/build/core/repository-ledger/accepted-fold-read.js +6 -3
  147. package/build/core/repository-ledger/codec.js +11 -5
  148. package/build/core/repository-ledger/current-state-store.js +13 -16
  149. package/build/core/repository-ledger/fold-repository.js +5 -6
  150. package/build/core/repository-ledger/identity.js +60 -0
  151. package/build/core/repository-ledger/inventory.js +3 -3
  152. package/build/core/repository-ledger/read-model.js +54 -6
  153. package/build/core/repository-ledger/write-transaction.js +9 -4
  154. package/build/core/run-control/connection-bound-close.js +41 -0
  155. package/build/core/run-control/detached-lease-bootstrap.js +208 -0
  156. package/build/core/run-control/detached-process.js +14 -0
  157. package/build/core/run-control/index.js +6 -0
  158. package/build/core/{process-group.js → run-control/process-tree.js} +1 -1
  159. package/build/core/run-control/runner-lease.js +172 -0
  160. package/build/core/{sqlite-process-lifetime-lock.js → run-control/sqlite-process-lifetime-lock.js} +4 -24
  161. package/build/core/seal.js +44 -32
  162. package/build/core/settlement/claim-delivery.js +22 -9
  163. package/build/core/settlement/claim.js +8 -6
  164. package/build/core/settlement/petition-claim-gates.js +9 -8
  165. package/build/core/settlement/petition-head-guard.js +5 -6
  166. package/build/core/settlement/petition-preview.js +21 -5
  167. package/build/core/settlement/petition.js +51 -17
  168. package/build/core/settlement/settlement.js +20 -15
  169. package/build/core/settlement/verdict.js +2 -2
  170. package/build/core/settlement/verification.js +492 -364
  171. package/build/core/status/board.js +184 -75
  172. package/build/core/status/drift.js +8 -10
  173. package/build/core/task/board.js +1 -0
  174. package/build/core/task/commands.js +25 -0
  175. package/build/core/task/compose.js +3 -2
  176. package/build/core/task/document.js +102 -39
  177. package/build/core/task/index.js +3 -3
  178. package/build/core/task/settlement-git.js +1 -4
  179. package/build/core/task/settlement-policy.js +27 -14
  180. package/build/core/task/source-board.js +1 -0
  181. package/build/core/task/task-bind-preparation.js +59 -9
  182. package/build/core/task/task-contract.js +2 -2
  183. package/build/core/task/task-store-repository.js +1 -0
  184. package/build/core/task/task.js +2 -2
  185. package/build/core/transcripts.js +4 -4
  186. package/build/core/verification-declaration.js +95 -0
  187. package/build/core/worktree-bootstrap.js +1 -1
  188. package/build/core/worktree-path.js +7 -11
  189. package/build/flow-error.js +9 -1
  190. package/build/generated/version.js +2 -2
  191. package/build/git/branches.js +41 -70
  192. package/build/git/commits.js +92 -21
  193. package/build/git/core.js +9 -161
  194. package/build/git/diff/preview.js +4 -4
  195. package/build/git/diff/read.js +4 -4
  196. package/build/git/diff/structured.js +5 -5
  197. package/build/git/process.js +229 -0
  198. package/build/git/refs.js +30 -5
  199. package/build/git/staging.js +39 -115
  200. package/build/git/streaming-batch.js +9 -16
  201. package/build/git/worktree.js +104 -91
  202. package/build/index.js +7 -0
  203. package/package.json +1 -1
  204. package/skills/keiyaku-akuma/SKILL.md +21 -20
  205. package/skills/keiyaku-task/SKILL.md +38 -4
  206. package/skills/keiyaku-workflow/SKILL.md +51 -11
  207. package/build/cli/commands/projection/revive/meta.js +0 -12
  208. package/build/core/projection/projection-life-protocol.js +0 -115
  209. package/build/core/projection/projection-runner-lock.js +0 -211
  210. package/build/core/projection/tell/database.js +0 -127
  211. package/build/core/settlement/verification-coordination.js +0 -305
  212. package/build/core/settlement/verification-supervisor.js +0 -275
@@ -1,11 +1,12 @@
1
+ export const TASK_UPDATE_EXPLICIT_CHANGE_ERROR = "task update requires an explicit change: --title, --body TEXT or --body -, --append TEXT|-, --pri, --needs/--drop-needs, --parent/--no-parent, --from, --supersedes/--drop-supersedes, or --relates-to/--drop-relates-to";
1
2
  export const meta = {
2
3
  command: "task update",
3
4
  summary: "Update task facts",
4
- usage: ["keiyaku task update [-C|--cwd DIR] COORDINATE [--title TEXT] [--body TEXT|-|--append TEXT|-] [--pri 0-3] [--needs COORDINATE] [--drop-needs COORDINATE] [--parent COORDINATE|--no-parent] [--from COORDINATE] [--supersedes COORDINATE] [--drop-supersedes COORDINATE] [--relates-to COORDINATE] [--drop-relates-to COORDINATE] [--json]"],
5
+ usage: ["keiyaku task update [-C|--cwd DIR] [--contract ADDR] COORDINATE [--title TEXT] [--body TEXT|-|--append TEXT|-] [--pri 0-3] [--needs COORDINATE] [--drop-needs COORDINATE] [--parent COORDINATE|--no-parent] [--from COORDINATE] [--supersedes COORDINATE] [--drop-supersedes COORDINATE] [--relates-to COORDINATE] [--drop-relates-to COORDINATE] [--json]"],
5
6
  stdin: {
6
7
  mode: "argument",
7
8
  selector: { kind: "flag", names: ["taskBody", "taskAppend"], required: false, rejectBlank: false },
8
9
  },
9
- flags: ["cwd", "title", "body", "append", "pri", "needs", "drop-needs", "parent", "no-parent", "from", "supersedes", "drop-supersedes", "relates-to", "drop-relates-to", "json"],
10
+ flags: ["cwd", "contract", "title", "body", "append", "pri", "needs", "drop-needs", "parent", "no-parent", "from", "supersedes", "drop-supersedes", "relates-to", "drop-relates-to", "json"],
10
11
  purpose: "Change mutable task facts.",
11
12
  };
@@ -0,0 +1,43 @@
1
+ import { readVerificationRun, requestVerificationRunCancellation, VerificationRunUnknownError, VerificationRunWaitTimeoutError, waitForVerificationRun, } from "../../../core/settlement/verification.js";
2
+ import { FlowError } from "../../../flow-error.js";
3
+ import { renderVerificationCli, verificationCancelModel, verificationStatusModel, verificationWaitModel, verificationWaitTimeoutModel, } from "../../render/verification.js";
4
+ import { projectDirectory } from "../shared.js";
5
+ export const handler = async (_stdin, flags, signal, positional) => {
6
+ const [operation, runId, ...extra] = positional;
7
+ if (!operation || !runId || extra.length > 0) {
8
+ throw new FlowError("EMPTY_PARAM", "verification requires wait, status, or cancel followed by one VerificationRun id");
9
+ }
10
+ // Honor --repo through the shared repository-resolution primitive.
11
+ const root = await projectDirectory(flags, "verification");
12
+ const json = flags.json === true;
13
+ if (operation === "wait") {
14
+ try {
15
+ // Observation only: timeout/abort end wait without requesting cancellation.
16
+ const terminal = await waitForVerificationRun({ root, runId, timeoutMs: flags.timeoutMs, signal });
17
+ return renderVerificationCli(verificationWaitModel(runId, terminal), json);
18
+ }
19
+ catch (error) {
20
+ if (error instanceof VerificationRunUnknownError) {
21
+ throw new FlowError("UNKNOWN_ADDRESS", error.message);
22
+ }
23
+ if (!(error instanceof VerificationRunWaitTimeoutError))
24
+ throw error;
25
+ return renderVerificationCli(verificationWaitTimeoutModel(runId), json);
26
+ }
27
+ }
28
+ if (operation === "status") {
29
+ const run = readVerificationRun(root, runId);
30
+ if (!run)
31
+ throw new FlowError("UNKNOWN_ADDRESS", `verification run '${runId}' does not exist`);
32
+ return renderVerificationCli(verificationStatusModel(run), json);
33
+ }
34
+ if (operation === "cancel") {
35
+ // Explicit cancel is the only mutating verification CLI path.
36
+ if (!readVerificationRun(root, runId)) {
37
+ throw new FlowError("UNKNOWN_ADDRESS", `verification run '${runId}' does not exist`);
38
+ }
39
+ const accepted = requestVerificationRunCancellation(root, runId);
40
+ return renderVerificationCli(verificationCancelModel(runId, accepted), json);
41
+ }
42
+ throw new FlowError("INVALID_USAGE", "verification operation must be wait, status, or cancel");
43
+ };
@@ -0,0 +1,13 @@
1
+ export const meta = {
2
+ command: "verification",
3
+ summary: "Observe or cancel one durable VerificationRun",
4
+ usage: [
5
+ "keiyaku verification wait RUN_ID [-C|--cwd DIR] [--repo DIR] [--timeout DURATION] [--json]",
6
+ "keiyaku verification cancel RUN_ID [-C|--cwd DIR] [--repo DIR] [--json]",
7
+ "keiyaku verification status RUN_ID [-C|--cwd DIR] [--repo DIR] [--json]",
8
+ ],
9
+ stdin: { mode: "argument" },
10
+ flags: ["cwd", "repo", "timeout", "json"],
11
+ purpose: "Rejoin, inspect, or request cancellation of an addressable VerificationRun without inspecting runtime SQLite directly.",
12
+ completionRank: 11,
13
+ };
@@ -19,8 +19,8 @@ function topLevelCommands() {
19
19
  function subcommandsFor(parent) {
20
20
  return [...(getCommandMetadata(parent).subcommands ?? [])];
21
21
  }
22
- function topLevelOptionsFor(command) {
23
- const metadata = allCommandMetadata().find((meta) => meta.command === command && !command.includes(" "));
22
+ function optionsForCommandContext(context) {
23
+ const metadata = allCommandMetadata().find((meta) => meta.command === context);
24
24
  return metadata ? metadata.flags.map((flag) => `--${flag}`) : [];
25
25
  }
26
26
  function filterPrefix(items, word) {
@@ -40,22 +40,24 @@ export async function renderCompletionCandidates(input) {
40
40
  if (word.startsWith("@")) {
41
41
  return (await contractAddressCandidates(input.cwd, word)).join("\n");
42
42
  }
43
- if (input.previous === "call") {
43
+ const previous = input.previous ?? "";
44
+ const previousWord = previous.split(/\s+/).at(-1) ?? "";
45
+ if (previous === "call") {
44
46
  return filterPrefix([...(await akumaCandidates(input.cwd, word)), "--alias"], word).join("\n");
45
47
  }
46
- if (input.previous === "akuma") {
48
+ if (previous === "akuma") {
47
49
  return filterPrefix(subcommandsFor("akuma"), word).join("\n");
48
50
  }
49
- if (input.previous === "skills") {
51
+ if (previous === "skills") {
50
52
  return filterPrefix(subcommandsFor("skills"), word).join("\n");
51
53
  }
52
- if (input.previous === "task") {
54
+ if (previous === "task") {
53
55
  return filterPrefix(subcommandsFor("task"), word).join("\n");
54
56
  }
55
- if (input.previous === "--filter") {
57
+ if (previousWord === "--filter") {
56
58
  return filterPrefix([TASK_FILTER_COMPLETION], word).join("\n");
57
59
  }
58
- const options = input.previous ? topLevelOptionsFor(input.previous) : [];
60
+ const options = previous ? optionsForCommandContext(previous) : [];
59
61
  if (options.length > 0) {
60
62
  return filterPrefix(options, word).join("\n");
61
63
  }
@@ -66,8 +68,9 @@ export function renderCompletionScript(shell = "bash") {
66
68
  return [
67
69
  "#compdef keiyaku",
68
70
  "_keiyaku() {",
69
- " local -a candidates",
70
- " candidates=(${(f)\"$(keiyaku completion --complete --word=\"${words[CURRENT]}\" --previous=\"${words[CURRENT-1]}\" 2>/dev/null)\"})",
71
+ " local -a candidates context",
72
+ " context=\"${(j: :)words[2,CURRENT-1]}\"",
73
+ " candidates=(${(f)\"$(keiyaku completion --complete --word=\"${words[CURRENT]}\" --previous=\"${context}\" 2>/dev/null)\"})",
71
74
  " compadd -- $candidates",
72
75
  "}",
73
76
  "_keiyaku \"$@\"",
@@ -75,13 +78,13 @@ export function renderCompletionScript(shell = "bash") {
75
78
  }
76
79
  return [
77
80
  "_keiyaku_completion() {",
78
- " local cur prev",
81
+ " local cur context",
79
82
  " cur=\"${COMP_WORDS[COMP_CWORD]}\"",
80
- " prev=\"${COMP_WORDS[COMP_CWORD-1]}\"",
83
+ " context=\"${COMP_WORDS[*]:1:$((COMP_CWORD - 1))}\"",
81
84
  " COMPREPLY=()",
82
85
  " while IFS= read -r candidate; do",
83
86
  " COMPREPLY+=(\"$candidate\")",
84
- " done < <(keiyaku completion --complete --word=\"$cur\" --previous=\"$prev\" 2>/dev/null)",
87
+ " done < <(keiyaku completion --complete --word=\"$cur\" --previous=\"$context\" 2>/dev/null)",
85
88
  "}",
86
89
  "complete -F _keiyaku_completion keiyaku",
87
90
  ].join("\n");
@@ -47,6 +47,11 @@ export const FLAG_SPECS = {
47
47
  placeholder: "DURATION",
48
48
  description: "Wait at most a positive duration such as 45s, 5m, or 2h (maximum 24h).",
49
49
  },
50
+ entry: {
51
+ kind: "value",
52
+ placeholder: "N",
53
+ description: "Select one zero-based retained history entry from an addressed projection.",
54
+ },
50
55
  any: {
51
56
  kind: "boolean",
52
57
  description: "For a projection set, return when the first observed member reaches a terminal state.",
@@ -58,7 +63,7 @@ export const FLAG_SPECS = {
58
63
  },
59
64
  incognito: {
60
65
  kind: "boolean",
61
- description: "Do not persist response history and do not allow revive.",
66
+ description: "Do not persist response history and do not allow fork.",
62
67
  },
63
68
  bare: {
64
69
  kind: "boolean",
@@ -151,6 +156,10 @@ export const FLAG_SPECS = {
151
156
  kind: "boolean",
152
157
  description: "Renew onto the current target before petitioning.",
153
158
  },
159
+ audit: {
160
+ kind: "boolean",
161
+ description: "Run the ordinary read-only audit after a completed renew.",
162
+ },
154
163
  continue: {
155
164
  kind: "boolean",
156
165
  description: "Continue from the derived renew conflict scratch.",
@@ -191,11 +200,29 @@ export const FLAG_SPECS = {
191
200
  kind: "boolean",
192
201
  description: "Render structured data as JSON.",
193
202
  },
203
+ limit: {
204
+ kind: "value",
205
+ placeholder: "COUNT",
206
+ description: "Limit terminal rows in the Akuma roster.",
207
+ },
208
+ offset: {
209
+ kind: "value",
210
+ placeholder: "COUNT",
211
+ description: "Skip terminal rows in the Akuma roster.",
212
+ },
213
+ raw: {
214
+ kind: "boolean",
215
+ description: "Include retained raw event bodies when inspecting one history entry.",
216
+ },
194
217
  "diff-budget": {
195
218
  kind: "value",
196
219
  placeholder: "BYTES",
197
220
  description: "Set the audit raw-diff presentation budget in bytes.",
198
221
  },
222
+ "skip-diff-body": {
223
+ kind: "boolean",
224
+ description: "Suppress raw diff hunk bodies from the human audit presentation without changing audit evidence or checks.",
225
+ },
199
226
  done: {
200
227
  kind: "boolean",
201
228
  description: "Show terminal tasks.",
@@ -213,51 +240,51 @@ export const FLAG_SPECS = {
213
240
  pri: {
214
241
  kind: "value",
215
242
  placeholder: "0-3",
216
- description: "Set task priority from 0 through 3.",
243
+ description: "Set task priority: 0 (highest) through 3 (lowest).",
217
244
  },
218
245
  needs: {
219
246
  kind: "value",
220
247
  placeholder: "ID",
221
- description: "Add a task dependency. May be repeated.",
248
+ description: "Order execution: this task needs another task first. May be repeated.",
222
249
  },
223
250
  "drop-needs": {
224
251
  kind: "value",
225
252
  placeholder: "ID",
226
- description: "Remove a task dependency. May be repeated.",
253
+ description: "Remove an execution-ordering dependency. May be repeated.",
227
254
  },
228
255
  parent: {
229
256
  kind: "value",
230
257
  placeholder: "ID",
231
- description: "Set the parent task.",
258
+ description: "Organize task hierarchy under a parent task.",
232
259
  },
233
260
  "no-parent": {
234
261
  kind: "boolean",
235
- description: "Clear the parent task.",
262
+ description: "Clear the hierarchy parent task.",
236
263
  },
237
264
  from: {
238
265
  kind: "value",
239
266
  placeholder: "ID",
240
- description: "Add a discovery-lineage task. May be repeated.",
267
+ description: "Record work discovered while doing another task. May be repeated.",
241
268
  },
242
269
  supersedes: {
243
270
  kind: "value",
244
271
  placeholder: "ID",
245
- description: "Record that this task supersedes another task. May be repeated.",
272
+ description: "Record that this task replaces another task. May be repeated.",
246
273
  },
247
274
  "drop-supersedes": {
248
275
  kind: "value",
249
276
  placeholder: "ID",
250
- description: "Remove a supersedes relation. May be repeated.",
277
+ description: "Remove a replacement relation. May be repeated.",
251
278
  },
252
279
  "relates-to": {
253
280
  kind: "value",
254
281
  placeholder: "ID",
255
- description: "Record related work. May be repeated.",
282
+ description: "Record a thematic relation without ordering or replacement. May be repeated.",
256
283
  },
257
284
  "drop-relates-to": {
258
285
  kind: "value",
259
286
  placeholder: "ID",
260
- description: "Remove a related-work relation. May be repeated.",
287
+ description: "Remove a thematic relation. May be repeated.",
261
288
  },
262
289
  title: {
263
290
  kind: "value",
@@ -274,6 +301,11 @@ export const FLAG_SPECS = {
274
301
  placeholder: "TEXT|-",
275
302
  description: "Append a Markdown paragraph to the task body; literal - reads stdin.",
276
303
  },
304
+ note: {
305
+ kind: "value",
306
+ placeholder: "TEXT|-",
307
+ description: "Append an immutable task note; literal - reads stdin.",
308
+ },
277
309
  };
278
310
  export const CONTROL_FLAGS = new Set(Object.keys(FLAG_SPECS));
279
311
  export const VALUE_FLAGS = new Set(Object.entries(FLAG_SPECS)
package/build/cli/help.js CHANGED
@@ -25,7 +25,7 @@ export function renderCliCommandHelp(_command, spec, flagSpecs) {
25
25
  section(lines, "Purpose:", [spec.purpose]);
26
26
  section(lines, "Subcommands:", spec.subcommands);
27
27
  section(lines, "Input:", spec.input);
28
- section(lines, "Options:", spec.flags.map((name) => `${flagUsage(name, flagSpecs)} ${spec.flagDescriptions?.[name] ?? flagSpecs[name]?.description ?? ""}`));
28
+ section(lines, "Options:", spec.flags.map((name) => `${spec.flagUsages?.[name] ?? flagUsage(name, flagSpecs)} ${spec.flagDescriptions?.[name] ?? flagSpecs[name]?.description ?? ""}`));
29
29
  section(lines, "Notes:", spec.notes);
30
30
  section(lines, "Examples:", spec.examples);
31
31
  return lines.join("\n").trimEnd();
@@ -39,27 +39,27 @@ export function renderCliHelp(version) {
39
39
  " keiyaku @<commission> <command> [flags]",
40
40
  "",
41
41
  "Flow:",
42
- " bind -> delivery work -> petition",
43
- " optional: arc -> delivery work -> arc; renew on base drift",
42
+ " bind -> make and commit changes -> petition",
43
+ " optional: arc -> make and commit changes -> arc; renew when the target moves",
44
44
  "",
45
45
  "Commands:",
46
- " bind Create a contract ledger and workspace files.",
47
- " arc Optional iteration; seals current intent first.",
48
- " renew Rewrite delivery onto the current base and seal it.",
49
- " call Start an Akuma helper session.",
50
- " wait Wait for an akuma projection.",
51
- " revive Revive an Akuma helper session.",
52
- " tell Send intent to an Akuma projection.",
53
- " kill Stop the current Akuma generation.",
54
- " log Render a contract ledger.",
55
- " akuma Inspect helper profiles.",
46
+ " bind Create a contract and its workspace.",
47
+ " arc Seal the current stage and begin another.",
48
+ " renew Refresh committed changes onto the contract target.",
49
+ " call Start an Akuma projection.",
50
+ " wait Wait for a projection.",
51
+ " fork Start a projection from a response artifact.",
52
+ " tell Send a message to a projection.",
53
+ " kill Stop a projection's active run.",
54
+ " log Show a contract history.",
55
+ " akuma Inspect available Akuma definitions.",
56
56
  " skills Install bundled official skills.",
57
57
  " amend Record an amendment.",
58
- " petition Run settlement processing.",
59
- " forfeit Forfeit an addressed contract.",
58
+ " petition Ask Keiyaku to settle a contract.",
59
+ " forfeit End a contract without claiming it.",
60
60
  " guide Print workflow guidance.",
61
61
  " completion Print shell completion.",
62
- " status Render the Kanshi board.",
62
+ " status Show contracts, tasks, and projections that need attention.",
63
63
  " task Manage lightweight repository tasks.",
64
64
  " dump-env Print the environment template.",
65
65
  "",
@@ -67,12 +67,12 @@ export function renderCliHelp(version) {
67
67
  " <> means required; [] means optional.",
68
68
  " bind, arc, amend, and petition read document stdin only when literal `-` selects it.",
69
69
  " call and tell require literal BODY or `-`; literal `-` selects stdin.",
70
- " revive accepts an artifact plus optional BODY or `-`; unselected stdin is ignored.",
70
+ " fork accepts an artifact plus optional BODY or `-`; unselected stdin is ignored.",
71
71
  "",
72
72
  "Configuration:",
73
- " Akuma profiles <KEIYAKU_HOME>/akuma/*.md or .keiyaku/akuma/*.md",
73
+ " Akuma definitions <KEIYAKU_HOME>/akuma/*.md or .keiyaku/akuma/*.md",
74
74
  " Settings <KEIYAKU_HOME>/settings.json or .keiyaku/settings.json",
75
- " Inspect keiyaku akuma ls | keiyaku akuma show NAME",
75
+ " Inspect keiyaku akuma list | keiyaku akuma show NAME",
76
76
  " Environment keiyaku dump-env",
77
77
  " Full format README Configuration",
78
78
  ].join("\n");
@@ -81,18 +81,17 @@ export function buildKeiyakuGuide(version) {
81
81
  return [
82
82
  `# Keiyaku Guide (v${version})`,
83
83
  "",
84
- "## Workflow",
85
- "`bind -> delivery work -> petition`",
86
- "optional: `arc -> delivery work -> arc`; renew on base drift",
84
+ "A task is a planning item: it does not create a workspace or start work.",
85
+ "A contract is one bounded delivery with its own workspace. It begins bound and ends claimed when settlement lands it, or forfeited when it is ended without a claim.",
86
+ "An Akuma is a callable worker definition. A projection is one run of an Akuma.",
87
87
  "",
88
- "- `bind` supplies derived default intent a0.",
89
- "- `arc` is an optional iteration boundary, not admission; the first explicit arc seals a0, and later arcs seal the previous open explicit arc.",
90
- "- `renew` seals the current a0 or open explicit arc after a successful refresh onto the default branch.",
91
- "- `petition` seals the current a0 or open explicit arc and starts settlement.",
92
- "- After an explicit arc closes, loose commits require another arc before renew or petition.",
93
- "- `call` and `revive` provide helper execution without changing the ledger lifecycle.",
94
- "- `skills install` installs the bundled official Keiyaku skills into supported agent skill directories; force permits replacement of foreign collisions.",
95
- "- `status` is read-only and reports next actions, drift, queue state, and projections.",
88
+ "`bind -> make and commit changes -> petition`",
89
+ "",
90
+ "Binding a contract establishes its first delivery stage. A `seal` records that stage's committed changes and scope at a lifecycle boundary.",
91
+ "`arc` is an optional boundary: it seals the current stage and opens the next. Use arcs only for successive stages of one contract and one final settlement; they do not create separately claimable work.",
92
+ "When the contract target moves, `renew` refreshes the committed changes onto it and seals the refreshed current stage.",
93
+ "`petition` seals the current stage, runs the contract's settlement checks, and claims the contract only when they pass. If a settlement gate fails, the contract is not claimed; address the reported problem and petition again.",
94
+ "Use separate tasks and contracts for work with separate acceptance, ownership, or waiting needs. `status` shows the work that needs attention.",
96
95
  ].join("\n");
97
96
  }
98
97
  export function commandMetadata(command) {
@@ -220,9 +220,6 @@ async function resolveCliInput(parsed) {
220
220
  const selected = selectedArgument(parsed);
221
221
  const token = selected?.token;
222
222
  const selectsStdin = token === "-";
223
- if (selectsStdin && process.stdin.isTTY) {
224
- throw new FlowError("INVALID_USAGE", `${parsed.command} literal '-' requires piped stdin`);
225
- }
226
223
  const piped = selectsStdin ? await readStdin() : "";
227
224
  const input = selectsStdin ? piped : token ?? "";
228
225
  if (stdinMeta.selector?.required && token === undefined) {
@@ -235,8 +232,12 @@ async function resolveCliInput(parsed) {
235
232
  const message = stdinMeta.mode === "document"
236
233
  ? `No Markdown input received on stdin.\n\nExample:\n ${usageExample(parsed.command)}`
237
234
  : selectsStdin
238
- ? `${parsed.command} received no body on stdin`
239
- : `${parsed.command} body cannot be empty`;
235
+ ? parsed.command === "task add"
236
+ ? "task add received no task document on stdin"
237
+ : `${parsed.command} received no body on stdin`
238
+ : parsed.command === "task add"
239
+ ? "task add title cannot be empty"
240
+ : `${parsed.command} body cannot be empty`;
240
241
  throw new FlowError(selectsStdin ? "STDIN_EMPTY" : "EMPTY_PARAM", message);
241
242
  }
242
243
  return { stdin: input, flags: selected?.replace(input) ?? parsed.flags, selectsStdin };
@@ -126,6 +126,9 @@ export function assignFlag(flags, name, value) {
126
126
  case "renew":
127
127
  flags.renewBeforePetition = Boolean(value);
128
128
  return;
129
+ case "audit":
130
+ flags.renewAudit = Boolean(value);
131
+ return;
129
132
  case "continue":
130
133
  flags.renewContinue = Boolean(value);
131
134
  return;
@@ -167,6 +170,9 @@ export function assignFlag(flags, name, value) {
167
170
  flags.auditDiffBudgetBytes = parsed;
168
171
  return;
169
172
  }
173
+ case "skip-diff-body":
174
+ flags.auditSkipDiffBody = Boolean(value);
175
+ return;
170
176
  case "done":
171
177
  flags.done = Boolean(value);
172
178
  return;
@@ -179,6 +185,33 @@ export function assignFlag(flags, name, value) {
179
185
  }
180
186
  flags.taskSort = String(value);
181
187
  return;
188
+ case "limit": {
189
+ const parsed = Number(String(value));
190
+ if (!Number.isSafeInteger(parsed) || parsed < 1) {
191
+ throw new FlowError("INVALID_USAGE", "option --limit requires a positive safe integer entry count");
192
+ }
193
+ flags.historyLimit = parsed;
194
+ return;
195
+ }
196
+ case "offset": {
197
+ const parsed = Number(String(value));
198
+ if (!Number.isSafeInteger(parsed) || parsed < 0) {
199
+ throw new FlowError("INVALID_USAGE", "option --offset requires a non-negative safe integer entry count");
200
+ }
201
+ flags.historyOffset = parsed;
202
+ return;
203
+ }
204
+ case "entry": {
205
+ const parsed = Number(String(value));
206
+ if (!Number.isSafeInteger(parsed) || parsed < 0) {
207
+ throw new FlowError("INVALID_USAGE", "option --entry requires a non-negative safe integer retained entry index");
208
+ }
209
+ flags.historyEntry = parsed;
210
+ return;
211
+ }
212
+ case "raw":
213
+ flags.historyRaw = Boolean(value);
214
+ return;
182
215
  case "pri": {
183
216
  const raw = String(value);
184
217
  if (!/^[0-3]$/.test(raw)) {
@@ -238,6 +271,12 @@ export function assignFlag(flags, name, value) {
238
271
  }
239
272
  flags.taskAppend = String(value);
240
273
  return;
274
+ case "note":
275
+ if (flags.taskNote !== undefined) {
276
+ throw new FlowError("INVALID_USAGE", "option --note may only be specified once");
277
+ }
278
+ flags.taskNote = String(value);
279
+ return;
241
280
  default:
242
281
  throw new FlowError("UNKNOWN_OPTION", `unknown option: --${name}`);
243
282
  }
@@ -68,7 +68,7 @@ export function commandPositionalRange(command) {
68
68
  if (command === "tell") {
69
69
  return { min: 2, max: 2, label: "<PROJECTION> <BODY|->" };
70
70
  }
71
- if (command === "revive") {
71
+ if (command === "fork") {
72
72
  return { min: 1, max: 2, label: "<ARTIFACT> [BODY|-]" };
73
73
  }
74
74
  if (command === "wait") {
@@ -84,7 +84,7 @@ export function commandPositionalRange(command) {
84
84
  return { min: 0, max: 1, label: "[projection|alias|rsp]" };
85
85
  }
86
86
  if (command === "task add") {
87
- return { min: 1, max: 1, label: "<BODY|->" };
87
+ return { min: 1, max: 1, label: "<TITLE|->" };
88
88
  }
89
89
  if (command === "task compose") {
90
90
  return { min: 0, max: 0 };
@@ -92,6 +92,9 @@ export function commandPositionalRange(command) {
92
92
  if (command === "task show" || command === "task log" || command === "task start" || command === "task hold" || command === "task resume" || command === "task drop") {
93
93
  return { min: 1, max: 1, label: "<ID>" };
94
94
  }
95
+ if (command === "task note") {
96
+ return { min: 2, max: 2, label: "<ID> <TEXT|->" };
97
+ }
95
98
  if (command === "task update") {
96
99
  return { min: 1, max: 1, label: "<ID>" };
97
100
  }
@@ -14,6 +14,21 @@ const COMMISSION_SELECTOR_COMMANDS = new Set([
14
14
  "petition",
15
15
  "forfeit",
16
16
  "audit",
17
+ "status",
18
+ "task add",
19
+ "task compose",
20
+ "task show",
21
+ "task ls",
22
+ "task log",
23
+ "task start",
24
+ "task stop",
25
+ "task hold",
26
+ "task resume",
27
+ "task done",
28
+ "task note",
29
+ "task drop",
30
+ "task update",
31
+ "task doctor",
17
32
  ]);
18
33
  function formatSelectorList(items) {
19
34
  if (items.length <= 1) {
@@ -49,6 +64,9 @@ export function assertCommissionSelectorAllowed(command, flags) {
49
64
  throw new FlowError("INVALID_USAGE", `contract address @${flags.contractId} is not valid for ${command}`);
50
65
  }
51
66
  export function assertProjectionSelectorPresent(command, flags, atTokens, contractFlagRaws, restLength, payloadLength) {
67
+ if (command === "status" && flags.contractId !== undefined && restLength + payloadLength > 0) {
68
+ throw new FlowError("INVALID_USAGE", `status accepts either one projection id or one commission selector; ${flags.contractAddressSource === "at-address" ? atTokens[0] ?? `@${flags.contractId}` : `--contract ${contractFlagRaws[0] ?? flags.contractId}`} cannot be combined with a projection id`);
69
+ }
52
70
  if ((command !== "wait" && command !== "tell") || flags.contractId === undefined) {
53
71
  return;
54
72
  }
@@ -4,10 +4,13 @@ import { isResponseArtifactId } from "../core/response-artifact-id.js";
4
4
  import { isCommissionId } from "../core/ids.js";
5
5
  import { HELP_FLAGS } from "./flags.js";
6
6
  import { getCommandMetadata } from "./commands/metadata.js";
7
+ import { AKUMA_SUBCOMMANDS } from "./types.js";
7
8
  import { assertAllowedFlag, assignFlag, BOOLEAN_FLAGS, CONTROL_FLAGS, parseFlagName, readValueFlag, SHORT_FLAG_ALIASES, VALUE_FLAGS, } from "./parse-flags.js";
8
9
  import { commandPositionalRange, isCallCommand, resolveCommand, splitAtLiteralBoundary, TASK_SUBCOMMANDS, } from "./parse-metadata.js";
9
10
  import { applyCommissionSelector, assertCommissionSelectorAllowed, assertProjectionSelectorPresent, } from "./parse-selectors.js";
10
11
  import { WAIT_SET_SELECTION_ERROR } from "./commands/projection/wait/meta.js";
12
+ import { TASK_ADD_INPUT_SHAPE_ERROR } from "./commands/task/add/meta.js";
13
+ import { TASK_UPDATE_EXPLICIT_CHANGE_ERROR } from "./commands/task/update/meta.js";
11
14
  export { commandPositionalRange, isCallCommand, isPetitionDryRunInvocation, normalizeContractAddress, parseWaitTimeout, } from "./parse-metadata.js";
12
15
  export function parseCliArgs(tokens) {
13
16
  const { head, payload } = splitAtLiteralBoundary(tokens);
@@ -64,6 +67,14 @@ export function parseCliArgs(tokens) {
64
67
  throw new FlowError("UNKNOWN_OPTION", `unknown option: --${name}`);
65
68
  }
66
69
  seenFlagNames.add(name);
70
+ // `--akuma` is a status-only collection selector. Elsewhere it remains
71
+ // the existing value-taking launch option.
72
+ if (name === "akuma" && head.includes("status")) {
73
+ if (eq !== -1)
74
+ throw new FlowError("INVALID_USAGE", "option --akuma does not accept a value for status");
75
+ flags.akumaRoster = true;
76
+ continue;
77
+ }
67
78
  if (VALUE_FLAGS.has(name)) {
68
79
  const { value, nextIndex } = readValueFlag(name, token, eq, head, index);
69
80
  index = nextIndex;
@@ -103,7 +114,7 @@ export function parseCliArgs(tokens) {
103
114
  };
104
115
  }
105
116
  if (command === "akuma") {
106
- throw new FlowError("EMPTY_PARAM", "akuma requires subcommand: ls or show");
117
+ throw new FlowError("EMPTY_PARAM", `akuma requires subcommand: ${AKUMA_SUBCOMMANDS.slice(0, -1).join(", ")} or ${AKUMA_SUBCOMMANDS.at(-1)}`);
107
118
  }
108
119
  if (command === "skills") {
109
120
  throw new FlowError("EMPTY_PARAM", "skills requires subcommand: install");
@@ -144,14 +155,11 @@ export function parseCliArgs(tokens) {
144
155
  && flags.taskParent === undefined && !flags.taskNoParent && flags.taskFrom === undefined
145
156
  && flags.taskSupersedes === undefined && flags.taskDropSupersedes === undefined
146
157
  && flags.taskRelatesTo === undefined && flags.taskDropRelatesTo === undefined) {
147
- throw new FlowError("EMPTY_PARAM", "task update requires at least one change");
158
+ throw new FlowError("INVALID_USAGE", TASK_UPDATE_EXPLICIT_CHANGE_ERROR);
148
159
  }
149
160
  if (command === "petition" && flags.json && !flags.dryRun) {
150
161
  throw new FlowError("INVALID_USAGE", "petition --json requires --dry-run");
151
162
  }
152
- if (command === "petition" && flags.dryRun && (flags.appendScope?.length ?? 0) > 0) {
153
- throw new FlowError("INVALID_USAGE", "petition --dry-run does not accept --append-scope");
154
- }
155
163
  if (command === "renew") {
156
164
  const recoveryModes = [flags.renewContinue, flags.renewAbort].filter(Boolean).length;
157
165
  if (recoveryModes > 1) {
@@ -164,6 +172,9 @@ export function parseCliArgs(tokens) {
164
172
  assertCommissionSelectorAllowed(command, flags);
165
173
  assertProjectionSelectorPresent(command, flags, atTokens, contractFlagRaws, rest.length, payload.length);
166
174
  const positional = [...rest, ...payload];
175
+ if (command === "amend" && flags.appendScope && positional.length > 0 && positional[0] !== "-") {
176
+ throw new FlowError("INVALID_USAGE", "amend accepts Markdown only through literal '-' and --append-scope never reads unselected stdin");
177
+ }
167
178
  if (command === "bind" && flags.contractId !== undefined) {
168
179
  if (!isCommissionId(flags.contractId)) {
169
180
  throw new FlowError("UNKNOWN_ADDRESS", `bind replay requires a full canonical contract id; got ${flags.contractId}`);
@@ -228,9 +239,11 @@ export function parseCliArgs(tokens) {
228
239
  && positional.length === stdin.selector.index + 1
229
240
  && positional[stdin.selector.index] === "-";
230
241
  if (positional.length > positionalRange.max && !documentStdinSelector) {
231
- const message = stdin.mode === "document"
232
- ? `${command} reads Markdown only through literal '-'; file path arguments are not supported`
233
- : `${command} does not accept positional arguments`;
242
+ const message = command === "task add"
243
+ ? TASK_ADD_INPUT_SHAPE_ERROR
244
+ : stdin.mode === "document"
245
+ ? `${command} reads Markdown only through literal '-'; file path arguments are not supported`
246
+ : `${command} does not accept positional arguments`;
234
247
  throw new FlowError("INVALID_USAGE", message);
235
248
  }
236
249
  return { command, flags, positional };