@astrosheep/keiyaku 2.9.3 → 2.9.5

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 (282) hide show
  1. package/build/.tsbuildinfo +1 -1
  2. package/build/agents/call-terms.js +14 -94
  3. package/build/agents/harness/activity-values.js +16 -0
  4. package/build/agents/harness/event-persistence.js +218 -0
  5. package/build/agents/harness/execution-handle.js +26 -222
  6. package/build/agents/harness/index.js +3 -1
  7. package/build/agents/harness/outcome.js +68 -5
  8. package/build/agents/harness/projection.js +179 -124
  9. package/build/agents/harness/provider-adapter.js +58 -0
  10. package/build/agents/harness/router.js +11 -187
  11. package/build/agents/harness/runtime.js +17 -4
  12. package/build/agents/harness/session.js +15 -0
  13. package/build/agents/launch-snapshot/model.js +15 -236
  14. package/build/agents/launch-snapshot/parse-helpers.js +114 -0
  15. package/build/agents/launch-snapshot/resolve.js +17 -43
  16. package/build/agents/opencode-sdk.js +45 -12
  17. package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
  18. package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
  19. package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
  20. package/build/agents/providers/codex-app-server/adapter.js +82 -53
  21. package/build/agents/providers/codex-app-server/events.js +90 -11
  22. package/build/agents/providers/codex-app-server/identity.js +1 -0
  23. package/build/agents/providers/codex-app-server/policy.js +29 -0
  24. package/build/agents/providers/codex-app-server/registration.js +248 -0
  25. package/build/agents/providers/codex-app-server/session-schema.js +6 -0
  26. package/build/agents/providers/codex-app-server/session.js +23 -17
  27. package/build/agents/providers/codex-app-server/terms.js +1 -0
  28. package/build/agents/providers/opencode-sdk/adapter.js +94 -50
  29. package/build/agents/providers/opencode-sdk/events.js +8 -4
  30. package/build/agents/providers/opencode-sdk/registration.js +135 -0
  31. package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
  32. package/build/agents/providers/opencode-sdk/session.js +21 -14
  33. package/build/agents/providers/opencode-sdk/terms.js +1 -0
  34. package/build/agents/providers/pi/adapter.js +36 -30
  35. package/build/agents/providers/pi/events.js +4 -3
  36. package/build/agents/providers/pi/registration.js +145 -0
  37. package/build/agents/providers/pi/session-schema.js +6 -0
  38. package/build/agents/providers/pi/terms.js +1 -0
  39. package/build/agents/providers/registration.js +7 -0
  40. package/build/agents/providers/registry.js +76 -0
  41. package/build/agents/selector.js +2 -29
  42. package/build/agents/types.js +10 -0
  43. package/build/artifact-directories.js +22 -0
  44. package/build/cli/commands/akuma/akuma/handler.js +1 -1
  45. package/build/cli/commands/akuma/akuma/meta.js +1 -1
  46. package/build/cli/commands/akuma/list/meta-ls.js +1 -1
  47. package/build/cli/commands/akuma/view/handler.js +5 -4
  48. package/build/cli/commands/akuma/view/meta.js +1 -1
  49. package/build/cli/commands/akuma.js +6 -0
  50. package/build/cli/commands/contract/amend/handler.js +8 -2
  51. package/build/cli/commands/contract/amend/meta.js +4 -4
  52. package/build/cli/commands/contract/arc/handler.js +8 -2
  53. package/build/cli/commands/contract/arc/meta.js +4 -4
  54. package/build/cli/commands/contract/audit/handler.js +16 -0
  55. package/build/cli/commands/contract/audit/meta.js +16 -0
  56. package/build/cli/commands/contract/bind/handler.js +4 -3
  57. package/build/cli/commands/contract/bind/meta.js +44 -8
  58. package/build/cli/commands/contract/catalog.js +2 -0
  59. package/build/cli/commands/contract/forfeit/handler.js +4 -4
  60. package/build/cli/commands/contract/forfeit/meta.js +1 -1
  61. package/build/cli/commands/contract/log/handler.js +3 -3
  62. package/build/cli/commands/contract/log/meta.js +1 -1
  63. package/build/cli/commands/contract/petition/handler.js +5 -8
  64. package/build/cli/commands/contract/petition/meta.js +6 -6
  65. package/build/cli/commands/contract/renew/handler.js +20 -6
  66. package/build/cli/commands/contract/renew/meta.js +6 -5
  67. package/build/cli/commands/metadata.js +59 -0
  68. package/build/cli/commands/projection/call/handler.js +6 -5
  69. package/build/cli/commands/projection/call/meta.js +4 -1
  70. package/build/cli/commands/projection/kill/handler.js +16 -32
  71. package/build/cli/commands/projection/kill/meta.js +1 -1
  72. package/build/cli/commands/projection/revive/meta.js +4 -1
  73. package/build/cli/commands/projection/shared.js +28 -0
  74. package/build/cli/commands/projection/status/handler.js +1 -1
  75. package/build/cli/commands/projection/status/meta.js +1 -1
  76. package/build/cli/commands/projection/tell/handler.js +14 -30
  77. package/build/cli/commands/projection/tell/meta.js +4 -1
  78. package/build/cli/commands/projection/wait/handler.js +45 -22
  79. package/build/cli/commands/projection/wait/meta.js +8 -3
  80. package/build/cli/commands/registry.js +2 -54
  81. package/build/cli/commands/shared.js +10 -7
  82. package/build/cli/commands/skills/install/handler.js +2 -5
  83. package/build/cli/commands/skills/install/meta.js +1 -1
  84. package/build/cli/commands/skills/skills/handler.js +1 -1
  85. package/build/cli/commands/skills/skills/meta.js +1 -1
  86. package/build/cli/commands/system/completion/meta.js +1 -1
  87. package/build/cli/commands/system/dump-env/meta.js +1 -1
  88. package/build/cli/commands/system/guide/meta.js +1 -1
  89. package/build/cli/commands/task/add/handler.js +7 -15
  90. package/build/cli/commands/task/add/meta.js +4 -1
  91. package/build/cli/commands/task/catalog.js +2 -2
  92. package/build/cli/commands/task/doctor/meta.js +1 -1
  93. package/build/cli/commands/task/done/handler.js +4 -8
  94. package/build/cli/commands/task/done/meta.js +1 -1
  95. package/build/cli/commands/task/drop/handler.js +3 -6
  96. package/build/cli/commands/task/drop/meta.js +1 -1
  97. package/build/cli/commands/task/ls/handler.js +12 -8
  98. package/build/cli/commands/task/ls/meta.js +3 -3
  99. package/build/cli/commands/task/shared.js +14 -4
  100. package/build/cli/commands/task/{view → show}/handler.js +7 -8
  101. package/build/cli/commands/task/show/meta.js +8 -0
  102. package/build/cli/commands/task/start/handler.js +3 -6
  103. package/build/cli/commands/task/start/meta.js +1 -1
  104. package/build/cli/commands/task/stop/handler.js +4 -8
  105. package/build/cli/commands/task/stop/meta.js +1 -1
  106. package/build/cli/commands/task/task/handler.js +1 -1
  107. package/build/cli/commands/task/task/meta.js +1 -1
  108. package/build/cli/commands/task/update/handler.js +6 -11
  109. package/build/cli/commands/task/update/meta.js +4 -1
  110. package/build/cli/completion.js +1 -1
  111. package/build/cli/flags.js +37 -6
  112. package/build/cli/help.js +7 -14
  113. package/build/cli/index.js +112 -154
  114. package/build/cli/missing-subcommand.js +7 -0
  115. package/build/cli/output-stream-error-policy.js +19 -5
  116. package/build/cli/parse-flags.js +33 -7
  117. package/build/cli/parse-metadata.js +3 -9
  118. package/build/cli/parse-selectors.js +2 -1
  119. package/build/cli/parse.js +35 -5
  120. package/build/cli/projection-address.js +12 -12
  121. package/build/cli/render/address.js +41 -37
  122. package/build/cli/render/arc.js +24 -12
  123. package/build/cli/render/audit.js +121 -0
  124. package/build/cli/render/call.js +11 -5
  125. package/build/cli/render/errors.js +36 -1
  126. package/build/cli/render/format.js +4 -0
  127. package/build/cli/render/kanshi.js +6 -12
  128. package/build/cli/render/kill.js +9 -0
  129. package/build/cli/render/misc.js +58 -13
  130. package/build/cli/render/petition.js +20 -15
  131. package/build/cli/render/projection-activity.js +15 -6
  132. package/build/cli/render/shared.js +60 -21
  133. package/build/cli/render/skills.js +10 -0
  134. package/build/cli/render/status.js +56 -23
  135. package/build/cli/render/success-response.js +78 -0
  136. package/build/cli/render/task.js +66 -57
  137. package/build/cli/render/tell.js +5 -0
  138. package/build/cli/render/terminal-failure.js +63 -0
  139. package/build/cli/render/types.js +1 -0
  140. package/build/cli/render/wait.js +68 -38
  141. package/build/cli/types.js +1 -1
  142. package/build/config/akuma-loader.js +0 -5
  143. package/build/config/env-keys.js +3 -1
  144. package/build/config/env.js +3 -0
  145. package/build/config/provider-policy-ownership.js +3 -32
  146. package/build/config/settings/disease.js +8 -1
  147. package/build/config/settings/loader.js +11 -3
  148. package/build/config/settings/provider-instance-fields.js +51 -0
  149. package/build/config/settings/schema.js +6 -176
  150. package/build/core/addressing.js +66 -16
  151. package/build/core/amend.js +61 -18
  152. package/build/core/arc.js +33 -73
  153. package/build/core/audit.js +650 -0
  154. package/build/core/bind.js +82 -35
  155. package/build/core/call/call.js +15 -9
  156. package/build/core/call/context.js +6 -51
  157. package/build/core/call/execution.js +22 -22
  158. package/build/core/call/prompt.js +14 -1
  159. package/build/core/command-markdown.js +45 -0
  160. package/build/core/context.js +13 -7
  161. package/build/core/contract-view.js +22 -6
  162. package/build/core/draft.js +139 -19
  163. package/build/core/entry.js +3 -4
  164. package/build/core/forfeit.js +5 -2
  165. package/build/core/hints.js +1 -75
  166. package/build/core/identifier-slug.js +66 -0
  167. package/build/core/ids.js +25 -11
  168. package/build/core/ledger.js +20 -68
  169. package/build/core/markdown/lex.js +2 -1
  170. package/build/core/markdown/parser.js +0 -68
  171. package/build/core/markdown/render.js +68 -0
  172. package/build/core/markdown/sections.js +2 -1
  173. package/build/core/outcome-base.js +4 -0
  174. package/build/core/projection/generation/database.js +41 -52
  175. package/build/core/projection/generation/model.js +63 -2
  176. package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
  177. package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +36 -53
  178. package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
  179. package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +9 -7
  180. package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
  181. package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +19 -3
  182. package/build/core/projection/generation/store.js +3 -3
  183. package/build/core/projection/generation/transitions.js +19 -3
  184. package/build/core/projection/index.js +27 -0
  185. package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
  186. package/build/core/{projection-alias.js → projection/projection-alias.js} +13 -13
  187. package/build/core/projection/projection-coordinate.js +61 -0
  188. package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
  189. package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +37 -78
  190. package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
  191. package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
  192. package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +16 -2
  193. package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
  194. package/build/core/{projection-status.js → projection/projection-status.js} +163 -45
  195. package/build/core/projection/projection-terminal-failure.js +106 -0
  196. package/build/core/projection/projection-wait.js +275 -0
  197. package/build/core/projection/projection-wake.js +227 -0
  198. package/build/core/provider-loader-ports.js +4 -0
  199. package/build/core/ref-log.js +65 -40
  200. package/build/core/registry.js +63 -10
  201. package/build/core/renew-session.js +128 -0
  202. package/build/core/renew.js +448 -102
  203. package/build/core/scope.js +272 -68
  204. package/build/core/seal.js +165 -40
  205. package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +8 -8
  206. package/build/core/{claim.js → settlement/claim.js} +32 -8
  207. package/build/core/settlement/index.js +19 -0
  208. package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +24 -49
  209. package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
  210. package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
  211. package/build/core/settlement/petition-io.js +1 -0
  212. package/build/core/{petition-preview.js → settlement/petition-preview.js} +2 -2
  213. package/build/core/{petition.js → settlement/petition.js} +21 -12
  214. package/build/core/settlement/queue-read-model.js +143 -0
  215. package/build/core/settlement/queue-seat-allocation.js +156 -0
  216. package/build/core/settlement/queue.js +6 -0
  217. package/build/core/settlement/settlement.js +288 -0
  218. package/build/core/{verdict.js → settlement/verdict.js} +9 -37
  219. package/build/core/settlement/verification.js +59 -0
  220. package/build/core/status/board.js +62 -41
  221. package/build/core/status/ledger-batch.js +158 -0
  222. package/build/core/status/reconciliation.js +10 -4
  223. package/build/core/stored-agent-event.js +6 -2
  224. package/build/core/task/board.js +41 -4
  225. package/build/core/task/commands.js +45 -28
  226. package/build/core/task/document.js +5 -0
  227. package/build/core/task/index.js +12 -0
  228. package/build/core/task/model.js +8 -1
  229. package/build/core/task/query.js +172 -0
  230. package/build/core/task/settlement-git.js +265 -74
  231. package/build/core/task/settlement-policy.js +67 -29
  232. package/build/core/task/source-board.js +1 -0
  233. package/build/core/task/task-contract.js +444 -0
  234. package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
  235. package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
  236. package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
  237. package/build/core/{task-git-store.js → task/task-git-store.js} +90 -19
  238. package/build/core/task/task-repository.js +1 -0
  239. package/build/core/{task-store-repository.js → task/task-store-repository.js} +6 -4
  240. package/build/core/task/task-store.js +1 -0
  241. package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
  242. package/build/core/task/task.js +7 -0
  243. package/build/core/task/tree.js +37 -0
  244. package/build/core/task/validation.js +5 -2
  245. package/build/core/transcripts.js +15 -3
  246. package/build/core/worktree-path.js +43 -28
  247. package/build/flow-error.js +83 -39
  248. package/build/fs/path-coordinate.js +16 -0
  249. package/build/generated/version.js +3 -2
  250. package/build/git/branches.js +2 -1
  251. package/build/git/core.js +106 -2
  252. package/build/git/diff/parsers.js +23 -13
  253. package/build/git/diff/structured.js +127 -0
  254. package/build/git/path-coordinate.js +17 -0
  255. package/build/git/refs.js +57 -0
  256. package/build/git/streaming-batch.js +301 -0
  257. package/build/git/worktree.js +65 -0
  258. package/build/index.js +9 -9
  259. package/build/keiyaku.js +2 -36
  260. package/build/telemetry/logger.js +4 -2
  261. package/package.json +4 -10
  262. package/skills/keiyaku/SKILL.md +5 -4
  263. package/skills/keiyaku-akuma/SKILL.md +25 -11
  264. package/skills/keiyaku-task/SKILL.md +17 -8
  265. package/skills/keiyaku-workflow/SKILL.md +58 -9
  266. package/build/agents/providers/codex-sdk.js +0 -329
  267. package/build/cli/commands/task/view/meta.js +0 -8
  268. package/build/core/command-io.js +0 -174
  269. package/build/core/path-coordinate.js +0 -27
  270. package/build/core/petition-claim.js +0 -117
  271. package/build/core/petition-run.js +0 -83
  272. package/build/core/projection-coordinate.js +0 -63
  273. package/build/core/projection-wait.js +0 -165
  274. package/build/core/projection-wake.js +0 -136
  275. package/build/core/queue.js +0 -343
  276. package/build/core/task-contract.js +0 -237
  277. package/build/core/task.js +0 -4
  278. /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
  279. /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
  280. /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
  281. /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
  282. /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
@@ -5,17 +5,19 @@ import { compileBindDraftFlags } from "../core/draft.js";
5
5
  import { handleCliError } from "./render/errors.js";
6
6
  import { FLAG_SPECS } from "./flags.js";
7
7
  import { renderCliCommandHelp as renderCliCommandHelpText, renderCliHelp as renderCliHelpText, } from "./help.js";
8
- import { commandUsesPromptInput, isCallCommand, isPetitionDryRunInvocation, parseCliArgs } from "./parse.js";
9
- import { getCommandMetadata, loadCommandHandler } from "./commands/registry.js";
10
- import { repositoryCoordinateFromAddress } from "./commands/shared.js";
8
+ import { isPetitionDryRunInvocation, parseCliArgs } from "./parse.js";
9
+ import { getCommandMetadata } from "./commands/metadata.js";
10
+ import { loadCommandHandler } from "./commands/registry.js";
11
11
  import { shellQuote } from "./render/format.js";
12
- import { formatCallNextAction } from "./render/shared.js";
13
- import { renderResolvedAddressReceipt } from "./render/address.js";
12
+ import { writeSuccessResponse } from "./render/success-response.js";
13
+ import { writeCliOutput } from "./output-stream-error-policy.js";
14
14
  function commandRequiresStdin(command) {
15
- return getCommandMetadata(command).stdin === "required";
15
+ const stdin = getCommandMetadata(command).stdin;
16
+ return stdin.mode === "document" && stdin.selector.required;
16
17
  }
17
18
  function commandAcceptsOptionalStdin(command) {
18
- return getCommandMetadata(command).stdin === "optional";
19
+ const stdin = getCommandMetadata(command).stdin;
20
+ return stdin.mode === "document" && !stdin.selector.required;
19
21
  }
20
22
  function commandSavesFailedStdin(command) {
21
23
  return (commandRequiresStdin(command) || commandAcceptsOptionalStdin(command)) && command !== "call";
@@ -59,13 +61,15 @@ function prepareBindInput(stdin, flags) {
59
61
  throw new FlowError("EMPTY_PARAM", "--dry-run requires --place, --objective, --scope, and --checks");
60
62
  }
61
63
  if (!nonblankStdin) {
64
+ // --task may supply name/objective defaults; core merges and reports missing sections.
65
+ if (flags.bindTaskIds !== undefined && flags.bindTaskIds.length > 0) {
66
+ return "";
67
+ }
62
68
  throw new FlowError("EMPTY_PARAM", `No Markdown input received on stdin.\n\nExample:\n ${usageExample("bind")}`);
63
69
  }
64
70
  return stdin;
65
71
  }
66
72
  async function readStdin() {
67
- if (process.stdin.isTTY)
68
- return "";
69
73
  let data = "";
70
74
  process.stdin.setEncoding("utf-8");
71
75
  for await (const chunk of process.stdin)
@@ -80,77 +84,6 @@ function makeAbortSignal() {
80
84
  function responseText(response) {
81
85
  return response.text;
82
86
  }
83
- function responseData(response) {
84
- const payload = response.payload;
85
- if (!payload || typeof payload !== "object" || Array.isArray(payload) || "error" in payload)
86
- return {};
87
- return payload;
88
- }
89
- function isCallProjectionFacts(value) {
90
- if (value === null || typeof value !== "object" || Array.isArray(value))
91
- return false;
92
- const facts = value;
93
- return typeof facts.id === "string"
94
- && (facts.phase === "active" || facts.phase === "done" || facts.phase === "failed"
95
- || facts.phase === "dismissed" || facts.phase === "lost" || facts.phase === "quiescent");
96
- }
97
- function conversationalFooter(response) {
98
- const data = responseData(response);
99
- const lines = [];
100
- if (response.address) {
101
- const projection = data.projection;
102
- const projectionFacts = isCallProjectionFacts(projection) ? projection : undefined;
103
- const receiptArtifactId = typeof data.revivedArtifactId === "string"
104
- ? data.revivedArtifactId
105
- : typeof data.artifactId === "string" ? data.artifactId : undefined;
106
- lines.push(renderResolvedAddressReceipt(response.address, { artifactId: receiptArtifactId, projectionId: projectionFacts?.id }));
107
- }
108
- const responsePath = typeof data.responsePath === "string" ? data.responsePath : undefined;
109
- const agent = typeof data.agent === "string" ? data.agent : undefined;
110
- const meta = data.meta && typeof data.meta === "object" && !Array.isArray(data.meta) ? data.meta : undefined;
111
- const warnings = Array.isArray(meta?.warnings) ? meta.warnings.filter((warning) => typeof warning === "string") : [];
112
- if (responsePath) {
113
- lines.push(`Saved to ${responsePath}.`);
114
- }
115
- if (agent) {
116
- lines.push(`Akuma: ${agent}`);
117
- }
118
- if (warnings.length > 0) {
119
- lines.push("Warnings:", ...warnings.map((warning) => `- ${warning}`));
120
- }
121
- if (typeof data.summary === "string") {
122
- const projection = data.projection;
123
- const projectionFacts = isCallProjectionFacts(projection) ? projection : undefined;
124
- const artifactId = typeof data.artifactId === "string" ? data.artifactId : undefined;
125
- lines.push(formatCallNextAction({
126
- projection: projectionFacts,
127
- artifactId,
128
- repositoryCoordinate: repositoryCoordinateFromAddress(response.address),
129
- }));
130
- }
131
- return lines.join("\n");
132
- }
133
- function writeSuccessResponse(command, flags, response) {
134
- // Plain tell is always silent; tell --wait owns the ordinary wait response.
135
- if (command === "tell" && flags.timeoutMs === undefined)
136
- return;
137
- if (command === "bind" && flags.dryRun) {
138
- // Canonical Markdown already ends with exactly one newline.
139
- process.stdout.write(responseText(response));
140
- return;
141
- }
142
- if (command !== "revive") {
143
- process.stdout.write(`${responseText(response)}\n`);
144
- return;
145
- }
146
- const data = responseData(response);
147
- const answer = typeof data.summary === "string" ? data.summary.trim() : responseText(response).trim();
148
- const footer = conversationalFooter(response);
149
- process.stdout.write(`${answer}\n`);
150
- if (footer) {
151
- process.stderr.write(`${footer}\n`);
152
- }
153
- }
154
87
  async function saveFailedStdin(input) {
155
88
  if (!input.content.trim())
156
89
  return undefined;
@@ -160,12 +93,49 @@ async function saveFailedStdin(input) {
160
93
  content: input.content,
161
94
  });
162
95
  }
163
- function retryHint(command, draftPath, cwd, cwdFlag) {
164
- if (!cwdFlag) {
165
- return `Retry: keiyaku ${command} < ${shellQuote(draftPath)}`;
96
+ /**
97
+ * Rebuild bind flags for a failed-stdin retry in deterministic shell-safe order.
98
+ * Order follows bind usage/parse authority: cwd, repo, after, exclusive,
99
+ * draft-only, task. Domain-flag bind does not save stdin, so place/objective/
100
+ * scope/checks are not reconstructed. --dry-run never reaches this path.
101
+ */
102
+ function bindRetryFlagTokens(flags) {
103
+ const tokens = [];
104
+ if (flags.cwd !== undefined) {
105
+ tokens.push("--cwd", shellQuote(flags.cwd));
106
+ }
107
+ if (flags.repo !== undefined) {
108
+ tokens.push("--repo", shellQuote(flags.repo));
109
+ }
110
+ for (const after of flags.after ?? []) {
111
+ tokens.push("--after", shellQuote(after));
112
+ }
113
+ if (flags.exclusive === true) {
114
+ tokens.push("--exclusive");
115
+ }
116
+ if (flags.draftOnly === true) {
117
+ tokens.push("--draft-only");
118
+ }
119
+ if (flags.bindTaskIds !== undefined) {
120
+ for (const taskId of flags.bindTaskIds) {
121
+ tokens.push("--task", shellQuote(taskId));
122
+ }
166
123
  }
167
- const absoluteDraftPath = path.resolve(cwd, draftPath);
168
- return `Retry: keiyaku ${command} --cwd ${shellQuote(cwdFlag)} < ${shellQuote(absoluteDraftPath)}`;
124
+ return tokens;
125
+ }
126
+ function retryHint(input) {
127
+ const draftArg = input.flags.cwd === undefined
128
+ ? shellQuote(input.draftPath)
129
+ : shellQuote(path.resolve(input.cwd, input.draftPath));
130
+ if (input.command === "bind") {
131
+ const flagTokens = bindRetryFlagTokens(input.flags);
132
+ const flagPart = flagTokens.length > 0 ? ` ${flagTokens.join(" ")}` : "";
133
+ return `Retry: keiyaku bind${flagPart} - < ${draftArg}`;
134
+ }
135
+ if (input.flags.cwd === undefined) {
136
+ return `Retry: keiyaku ${input.command} - < ${shellQuote(input.draftPath)}`;
137
+ }
138
+ return `Retry: keiyaku ${input.command} --cwd ${shellQuote(input.flags.cwd)} - < ${draftArg}`;
169
139
  }
170
140
  async function printFailure(error, cwd) {
171
141
  const response = await handleCliError({
@@ -173,14 +143,14 @@ async function printFailure(error, cwd) {
173
143
  cwd,
174
144
  logLabel: "cli",
175
145
  });
176
- process.stderr.write(`${responseText(response)}\n`);
146
+ await writeCliOutput(process.stderr, `${responseText(response)}\n`);
177
147
  }
178
148
  function failureExitCode(error) {
179
149
  return error instanceof Error && error.name === "AbortError" ? 130 : 1;
180
150
  }
181
151
  async function handleFailureAfterStdin(input) {
182
152
  if (input.response) {
183
- process.stderr.write(`${responseText(input.response)}\n`);
153
+ await writeCliOutput(process.stderr, `${responseText(input.response)}\n`);
184
154
  }
185
155
  else {
186
156
  await printFailure(input.error ?? new Error("Unknown CLI failure"), input.cwd);
@@ -195,11 +165,16 @@ async function handleFailureAfterStdin(input) {
195
165
  content: input.stdin,
196
166
  });
197
167
  if (draftPath) {
198
- process.stderr.write(`\nSaved stdin input to ${draftPath}.\n${retryHint(input.command, draftPath, input.cwd, input.cwdFlag)}\n`);
168
+ await writeCliOutput(process.stderr, `\nSaved stdin input to ${draftPath}.\n${retryHint({
169
+ command: input.command,
170
+ draftPath,
171
+ cwd: input.cwd,
172
+ flags: input.flags,
173
+ })}\n`);
199
174
  }
200
175
  }
201
176
  catch (draftError) {
202
- process.stderr.write(`\nFailed to save stdin input: ${asMessage(draftError)}\n`);
177
+ await writeCliOutput(process.stderr, `\nFailed to save stdin input: ${asMessage(draftError)}\n`);
203
178
  }
204
179
  return 1;
205
180
  }
@@ -208,38 +183,42 @@ async function runResponse(command, flags, stdin, positional) {
208
183
  const handler = await loadCommandHandler(command);
209
184
  return await handler(stdin, flags, signal, positional);
210
185
  }
211
- function bodyToken(command, positional) {
212
- if (isCallCommand(command))
213
- return positional[0];
214
- if (command === "tell")
215
- return positional[1];
216
- if (command === "revive")
217
- return positional[1];
218
- return undefined;
219
- }
220
- async function readBodyInput(command, positional, cwd) {
221
- if (!commandUsesPromptInput(command))
222
- return undefined;
223
- const token = bodyToken(command, positional);
224
- if (token === undefined) {
225
- if (command === "revive")
226
- return "";
227
- await printFailure(new FlowError("EMPTY_PARAM", `${command} body cannot be empty`), cwd);
228
- return undefined;
229
- }
230
- if (token !== "-") {
231
- if (!token.trim()) {
232
- await printFailure(new FlowError("EMPTY_PARAM", `${command} body cannot be empty`), cwd);
233
- return undefined;
234
- }
235
- return token;
236
- }
237
- const stdin = await readStdin();
238
- if (!stdin.trim()) {
239
- await printFailure(new FlowError("EMPTY_PARAM", `${command} body cannot be empty`), cwd);
186
+ function selectedArgument(parsed) {
187
+ const stdin = getCommandMetadata(parsed.command).stdin;
188
+ if (stdin.selector === undefined)
240
189
  return undefined;
241
- }
242
- return stdin;
190
+ if (stdin.selector.kind === "positional") {
191
+ return { token: parsed.positional[stdin.selector.index], replace: () => parsed.flags };
192
+ }
193
+ const flagName = stdin.selector.name;
194
+ return {
195
+ token: parsed.flags[flagName],
196
+ replace: (value) => ({ ...parsed.flags, [flagName]: value }),
197
+ };
198
+ }
199
+ async function resolveCliInput(parsed) {
200
+ const stdinMeta = getCommandMetadata(parsed.command).stdin;
201
+ const selected = selectedArgument(parsed);
202
+ const token = selected?.token;
203
+ const selectsStdin = token === "-";
204
+ if (selectsStdin && process.stdin.isTTY) {
205
+ throw new FlowError("EMPTY_PARAM", `${parsed.command} literal '-' requires piped stdin`);
206
+ }
207
+ const piped = selectsStdin ? await readStdin() : "";
208
+ const input = selectsStdin ? piped : token ?? "";
209
+ if (stdinMeta.selector?.required && token === undefined) {
210
+ const message = stdinMeta.mode === "document"
211
+ ? `${parsed.command} requires literal '-' to read Markdown from stdin`
212
+ : `${parsed.command} body cannot be empty`;
213
+ throw new FlowError("EMPTY_PARAM", message);
214
+ }
215
+ if (token !== undefined && stdinMeta.selector?.rejectBlank && !input.trim()) {
216
+ const message = stdinMeta.mode === "document"
217
+ ? `No Markdown input received on stdin.\n\nExample:\n ${usageExample(parsed.command)}`
218
+ : `${parsed.command} body cannot be empty`;
219
+ throw new FlowError("EMPTY_PARAM", message);
220
+ }
221
+ return { stdin: input, flags: selected?.replace(input) ?? parsed.flags };
243
222
  }
244
223
  function usageExample(command) {
245
224
  const meta = getCommandMetadata(command);
@@ -255,40 +234,19 @@ export async function runCliCommand(tokens) {
255
234
  return isPetitionDryRunInvocation(tokens) ? 2 : 1;
256
235
  }
257
236
  if (parsed.helpRequested) {
258
- process.stdout.write(`${renderCliCommandHelp(resolveCliHelpCommand(parsed.command))}\n`);
237
+ await writeCliOutput(process.stdout, `${renderCliCommandHelp(resolveCliHelpCommand(parsed.command))}\n`);
259
238
  return 0;
260
239
  }
261
240
  const cwd = parsed.flags.cwd ?? process.cwd();
262
- let stdin = "";
263
- if (parsed.command === "task add") {
264
- if (parsed.positional[0] === "-")
265
- stdin = await readStdin();
266
- if (!(parsed.positional[0] === "-" ? stdin : parsed.positional[0]).trim()) {
267
- await printFailure(new FlowError("EMPTY_PARAM", "task add input cannot be blank"), cwd);
268
- return 1;
269
- }
270
- }
271
- else if (parsed.command === "task update" && parsed.flags.taskBody === "-") {
272
- stdin = await readStdin();
273
- }
274
- else if (commandRequiresStdin(parsed.command)) {
275
- stdin = await readStdin();
276
- if (!stdin.trim()) {
277
- await printFailure(new FlowError("EMPTY_PARAM", `No Markdown input received on stdin.\n\nExample:\n ${usageExample(parsed.command)}`), cwd);
278
- return 1;
279
- }
280
- }
281
- else if (commandAcceptsOptionalStdin(parsed.command)) {
282
- // Optional stdin: bind prepares domain flags or blank-stdin errors itself;
283
- // petition lets an empty body reach the oath gate as OATH_MISSING.
284
- stdin = await readStdin();
241
+ let stdin;
242
+ try {
243
+ const resolved = await resolveCliInput(parsed);
244
+ stdin = resolved.stdin;
245
+ parsed = { ...parsed, flags: resolved.flags };
285
246
  }
286
- else {
287
- const body = await readBodyInput(parsed.command, parsed.positional, cwd);
288
- if (body === undefined && commandUsesPromptInput(parsed.command)) {
289
- return 1;
290
- }
291
- stdin = body ?? "";
247
+ catch (error) {
248
+ await printFailure(error, cwd);
249
+ return 1;
292
250
  }
293
251
  // Bind dry-run must compile and return before repository/cwd resolution or filesystem effects.
294
252
  if (parsed.command === "bind") {
@@ -309,9 +267,9 @@ export async function runCliCommand(tokens) {
309
267
  return await handleFailureAfterStdin({
310
268
  error,
311
269
  cwd,
312
- cwdFlag: parsed.flags.cwd,
313
270
  command: parsed.command,
314
271
  stdin,
272
+ flags: parsed.flags,
315
273
  saveStdin: !(parsed.command === "bind" && hasBindDomainFlags(parsed.flags)),
316
274
  });
317
275
  }
@@ -322,20 +280,20 @@ export async function runCliCommand(tokens) {
322
280
  }
323
281
  const success = !response.payload || !("error" in response.payload);
324
282
  if (success) {
325
- writeSuccessResponse(parsed.command, parsed.flags, response);
283
+ await writeSuccessResponse(parsed.command, parsed.flags, response);
326
284
  return response.exitCode ?? 0;
327
285
  }
328
286
  if (commandRequiresStdin(parsed.command) || (parsed.command === "bind" && !parsed.flags.dryRun)) {
329
287
  return await handleFailureAfterStdin({
330
288
  response,
331
289
  cwd,
332
- cwdFlag: parsed.flags.cwd,
333
290
  command: parsed.command,
334
291
  stdin,
292
+ flags: parsed.flags,
335
293
  saveStdin: !(parsed.command === "bind" && hasBindDomainFlags(parsed.flags)),
336
294
  });
337
295
  }
338
- process.stderr.write(`${responseText(response)}\n`);
296
+ await writeCliOutput(process.stderr, `${responseText(response)}\n`);
339
297
  return 1;
340
298
  }
341
299
  export function renderCliCommandHelp(command) {
@@ -0,0 +1,7 @@
1
+ import { FlowError } from "../flow-error.js";
2
+ export function formatSubcommandList(subcommands) {
3
+ return subcommands.length < 2 ? (subcommands[0] ?? "") : `${subcommands.slice(0, -1).join(", ")} or ${subcommands.at(-1)}`;
4
+ }
5
+ export function missingSubcommandError(name, subcommands) {
6
+ return new FlowError("EMPTY_PARAM", `${name} requires subcommand: ${formatSubcommandList(subcommands)}`);
7
+ }
@@ -1,3 +1,21 @@
1
+ export function isBrokenPipeError(error) {
2
+ return (typeof error === "object" &&
3
+ error !== null &&
4
+ "code" in error &&
5
+ error.code === "EPIPE");
6
+ }
7
+ /** Resolve only after Node reports that this chunk has been flushed. */
8
+ export function writeCliOutput(stream, chunk) {
9
+ return new Promise((resolve, reject) => {
10
+ stream.write(chunk, (error) => {
11
+ if (error && !isBrokenPipeError(error)) {
12
+ reject(error);
13
+ return;
14
+ }
15
+ resolve();
16
+ });
17
+ });
18
+ }
1
19
  /**
2
20
  * Install a process-level broken-pipe policy on each supplied stream.
3
21
  * EPIPE is silent; every other emitted value is rethrown unchanged.
@@ -5,12 +23,8 @@
5
23
  export function installCliOutputStreamErrorPolicy(...streams) {
6
24
  for (const stream of streams) {
7
25
  stream.on("error", (error) => {
8
- if (typeof error === "object" &&
9
- error !== null &&
10
- "code" in error &&
11
- error.code === "EPIPE") {
26
+ if (isBrokenPipeError(error))
12
27
  return;
13
- }
14
28
  throw error;
15
29
  });
16
30
  }
@@ -1,5 +1,5 @@
1
1
  import { FlowError } from "../flow-error.js";
2
- import { getCommandMetadata } from "./commands/registry.js";
2
+ import { getCommandMetadata } from "./commands/metadata.js";
3
3
  import { BOOLEAN_FLAGS, CONTROL_FLAGS, SHORT_FLAG_ALIASES, VALUE_FLAGS, } from "./flags.js";
4
4
  import { normalizeContractAddress, parseWaitTimeout } from "./parse-metadata.js";
5
5
  function allowedFlagsForParse(command) {
@@ -85,10 +85,7 @@ export function assignFlag(flags, name, value) {
85
85
  flags.bindChecks = String(value);
86
86
  return;
87
87
  case "task":
88
- if (flags.bindTaskId !== undefined) {
89
- throw new FlowError("EMPTY_PARAM", "option --task may only be specified once");
90
- }
91
- flags.bindTaskId = String(value);
88
+ flags.bindTaskIds = [...(flags.bindTaskIds ?? []), String(value)];
92
89
  return;
93
90
  case "after":
94
91
  flags.after = [...(flags.after ?? []), String(value)];
@@ -102,8 +99,17 @@ export function assignFlag(flags, name, value) {
102
99
  case "dry-run":
103
100
  flags.dryRun = Boolean(value);
104
101
  return;
105
- case "waive":
106
- flags.waivePaths = [...(flags.waivePaths ?? []), String(value)];
102
+ case "append-scope":
103
+ flags.appendScope = [...(flags.appendScope ?? []), String(value)];
104
+ return;
105
+ case "resolve":
106
+ flags.renewResolve = Boolean(value);
107
+ return;
108
+ case "continue":
109
+ flags.renewContinue = Boolean(value);
110
+ return;
111
+ case "abort":
112
+ flags.renewAbort = Boolean(value);
107
113
  return;
108
114
  case "shell":
109
115
  flags.shell = String(value);
@@ -120,6 +126,9 @@ export function assignFlag(flags, name, value) {
120
126
  case "all":
121
127
  flags.all = Boolean(value);
122
128
  return;
129
+ case "any":
130
+ flags.any = Boolean(value);
131
+ return;
123
132
  case "target":
124
133
  if (flags.target !== undefined) {
125
134
  throw new FlowError("EMPTY_PARAM", "option --target may only be specified once");
@@ -129,9 +138,26 @@ export function assignFlag(flags, name, value) {
129
138
  case "json":
130
139
  flags.json = Boolean(value);
131
140
  return;
141
+ case "diff-budget": {
142
+ const parsed = Number(String(value));
143
+ if (!Number.isSafeInteger(parsed) || parsed < 0) {
144
+ throw new FlowError("EMPTY_PARAM", "option --diff-budget requires a non-negative safe integer byte count");
145
+ }
146
+ flags.auditDiffBudgetBytes = parsed;
147
+ return;
148
+ }
132
149
  case "done":
133
150
  flags.done = Boolean(value);
134
151
  return;
152
+ case "filter":
153
+ flags.taskFilters = [...(flags.taskFilters ?? []), String(value)];
154
+ return;
155
+ case "sort":
156
+ if (flags.taskSort !== undefined) {
157
+ throw new FlowError("EMPTY_PARAM", "option --sort may only be specified once");
158
+ }
159
+ flags.taskSort = String(value);
160
+ return;
135
161
  case "pri": {
136
162
  const raw = String(value);
137
163
  if (!/^[0-3]$/.test(raw)) {
@@ -1,6 +1,6 @@
1
1
  import { FlowError } from "../flow-error.js";
2
2
  import { HELP_FLAGS, SHORT_FLAG_ALIASES, VALUE_FLAGS } from "./flags.js";
3
- import { commandParseOrder, getCommandMetadata } from "./commands/registry.js";
3
+ import { commandParseOrder } from "./commands/metadata.js";
4
4
  import { TASK_SUBCOMMANDS } from "./types.js";
5
5
  export function normalizeContractAddress(raw) {
6
6
  const value = raw.startsWith("@") ? raw.slice(1) : raw;
@@ -42,9 +42,6 @@ export function isPetitionDryRunInvocation(tokens) {
42
42
  }
43
43
  return false;
44
44
  }
45
- export function commandUsesPromptInput(command) {
46
- return isCallCommand(command) || command === "tell" || command === "revive";
47
- }
48
45
  export function parseWaitTimeout(value) {
49
46
  const matched = /^(?<amount>[1-9][0-9]*)(?<unit>[smh])$/.exec(value);
50
47
  if (!matched?.groups) {
@@ -75,7 +72,7 @@ export function commandPositionalRange(command) {
75
72
  return { min: 1, max: 2, label: "<ARTIFACT> [BODY|-]" };
76
73
  }
77
74
  if (command === "wait") {
78
- return { min: 1, max: 1, label: "<projection-address>" };
75
+ return { min: 0, max: Number.MAX_SAFE_INTEGER, label: "<projection-address>" };
79
76
  }
80
77
  if (command === "kill") {
81
78
  return { min: 1, max: 1, label: "<projection-address>" };
@@ -86,7 +83,7 @@ export function commandPositionalRange(command) {
86
83
  if (command === "task add") {
87
84
  return { min: 1, max: 1, label: "<BODY|->" };
88
85
  }
89
- if (command === "task view" || command === "task start" || command === "task drop") {
86
+ if (command === "task show" || command === "task start" || command === "task drop") {
90
87
  return { min: 1, max: 1, label: "<ID>" };
91
88
  }
92
89
  if (command === "task update") {
@@ -97,9 +94,6 @@ export function commandPositionalRange(command) {
97
94
  }
98
95
  return { min: 0, max: 0 };
99
96
  }
100
- export function commandRequiresStdin(command) {
101
- return getCommandMetadata(command).stdin === "required";
102
- }
103
97
  export function resolveCommand(tokens) {
104
98
  if (tokens[0] === "petition" && (tokens[1] === "claim" || tokens[1] === "forfeit")) {
105
99
  throw new FlowError("UNKNOWN_COMMAND", `unknown command: petition ${tokens[1]}`);
@@ -12,6 +12,7 @@ const COMMISSION_SELECTOR_COMMANDS = new Set([
12
12
  "renew",
13
13
  "petition",
14
14
  "forfeit",
15
+ "audit",
15
16
  ]);
16
17
  function formatSelectorList(items) {
17
18
  if (items.length <= 1) {
@@ -56,7 +57,7 @@ export function assertProjectionSelectorPresent(command, flags, atTokens, contra
56
57
  ? atTokens[0] ?? `@${flags.contractId}`
57
58
  : `--contract ${contractFlagRaws[0] ?? flags.contractId}`;
58
59
  const message = `${command} requires a projection id or alias; ${selectorSpelling} only limits projection lookup, so add the projection address`;
59
- if (command === "wait" && restLength + payloadLength === 0) {
60
+ if (command === "wait" && restLength + payloadLength === 0 && !flags.any && !flags.all) {
60
61
  throw new FlowError("EMPTY_PARAM", message);
61
62
  }
62
63
  if (command === "tell" && restLength === 0) {
@@ -2,10 +2,12 @@ import { FlowError } from "../flow-error.js";
2
2
  import { agentNameSchema } from "../config/settings/schema.js";
3
3
  import { isResponseArtifactId } from "../core/response-artifact-id.js";
4
4
  import { HELP_FLAGS } from "./flags.js";
5
+ import { getCommandMetadata } from "./commands/metadata.js";
5
6
  import { assertAllowedFlag, assignFlag, BOOLEAN_FLAGS, CONTROL_FLAGS, parseFlagName, readValueFlag, SHORT_FLAG_ALIASES, VALUE_FLAGS, } from "./parse-flags.js";
6
- import { commandPositionalRange, commandRequiresStdin, isCallCommand, resolveCommand, splitAtLiteralBoundary, TASK_SUBCOMMANDS, } from "./parse-metadata.js";
7
+ import { commandPositionalRange, isCallCommand, resolveCommand, splitAtLiteralBoundary, TASK_SUBCOMMANDS, } from "./parse-metadata.js";
7
8
  import { applyCommissionSelector, assertCommissionSelectorAllowed, assertProjectionSelectorPresent, } from "./parse-selectors.js";
8
- export { commandPositionalRange, commandUsesPromptInput, isCallCommand, isPetitionDryRunInvocation, normalizeContractAddress, parseWaitTimeout, } from "./parse-metadata.js";
9
+ import { WAIT_SET_SELECTION_ERROR } from "./commands/projection/wait/meta.js";
10
+ export { commandPositionalRange, isCallCommand, isPetitionDryRunInvocation, normalizeContractAddress, parseWaitTimeout, } from "./parse-metadata.js";
9
11
  export function parseCliArgs(tokens) {
10
12
  const { head, payload } = splitAtLiteralBoundary(tokens);
11
13
  const flags = {};
@@ -120,6 +122,9 @@ export function parseCliArgs(tokens) {
120
122
  if (command === "task ls" && flags.all && flags.done) {
121
123
  throw new FlowError("EMPTY_PARAM", "task ls cannot combine --all and --done");
122
124
  }
125
+ if (command === "wait" && flags.any && flags.all) {
126
+ throw new FlowError("EMPTY_PARAM", WAIT_SET_SELECTION_ERROR);
127
+ }
123
128
  if (command === "task update" && flags.taskParent !== undefined && flags.taskNoParent) {
124
129
  throw new FlowError("EMPTY_PARAM", "task update cannot combine --parent and --no-parent");
125
130
  }
@@ -131,9 +136,29 @@ export function parseCliArgs(tokens) {
131
136
  if (command === "petition" && flags.json && !flags.dryRun) {
132
137
  throw new FlowError("EMPTY_PARAM", "petition --json requires --dry-run");
133
138
  }
139
+ if (command === "petition" && flags.dryRun && (flags.appendScope?.length ?? 0) > 0) {
140
+ throw new FlowError("EMPTY_PARAM", "petition --dry-run does not accept --append-scope");
141
+ }
142
+ if (command === "renew") {
143
+ const recoveryModes = [flags.renewResolve, flags.renewContinue, flags.renewAbort].filter(Boolean).length;
144
+ if (recoveryModes > 1) {
145
+ throw new FlowError("EMPTY_PARAM", "renew accepts only one of --resolve, --continue, or --abort");
146
+ }
147
+ if (flags.renewAbort && (flags.appendScope?.length ?? 0) > 0) {
148
+ throw new FlowError("EMPTY_PARAM", "renew --abort does not accept --append-scope");
149
+ }
150
+ }
134
151
  assertCommissionSelectorAllowed(command, flags);
135
152
  assertProjectionSelectorPresent(command, flags, atTokens, contractFlagRaws, rest.length, payload.length);
136
153
  const positional = [...rest, ...payload];
154
+ if (command === "wait") {
155
+ if (positional.length === 0 && !flags.contractId) {
156
+ throw new FlowError("EMPTY_PARAM", "wait requires <projection-address>");
157
+ }
158
+ if (positional.length > 1 && !flags.any && !flags.all) {
159
+ throw new FlowError("EMPTY_PARAM", WAIT_SET_SELECTION_ERROR);
160
+ }
161
+ }
137
162
  if (isCallCommand(command)) {
138
163
  if (flags.akuma) {
139
164
  if (positional.length > 1) {
@@ -163,9 +188,14 @@ export function parseCliArgs(tokens) {
163
188
  if (positional.length < positionalRange.min) {
164
189
  throw new FlowError("EMPTY_PARAM", `${command} requires ${positionalRange.label ?? "an argument"}`);
165
190
  }
166
- if (positional.length > positionalRange.max) {
167
- const message = commandRequiresStdin(command)
168
- ? `${command} reads Markdown from stdin; file path arguments are not supported`
191
+ const stdin = getCommandMetadata(command).stdin;
192
+ const documentStdinSelector = stdin.mode === "document"
193
+ && stdin.selector.kind === "positional"
194
+ && positional.length === stdin.selector.index + 1
195
+ && positional[stdin.selector.index] === "-";
196
+ if (positional.length > positionalRange.max && !documentStdinSelector) {
197
+ const message = stdin.mode === "document"
198
+ ? `${command} reads Markdown only through literal '-'; file path arguments are not supported`
169
199
  : `${command} does not accept positional arguments`;
170
200
  throw new FlowError("EMPTY_PARAM", message);
171
201
  }