@pknx/waterfall-cli 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/bin/waterfall.mjs +14 -0
- package/lib/cli/agent/agent-message.ts +71 -0
- package/lib/cli/agent/agent-translators.ts +145 -0
- package/lib/cli/agent/backend-invoke.ts +133 -0
- package/lib/cli/agent/backends.ts +100 -0
- package/lib/cli/agent/global-prompts.ts +55 -0
- package/lib/cli/commands/bug-start.ts +115 -0
- package/lib/cli/commands/comment-add.ts +47 -0
- package/lib/cli/commands/cr-all.ts +18 -0
- package/lib/cli/commands/cr-finish.ts +176 -0
- package/lib/cli/commands/cr-start.ts +105 -0
- package/lib/cli/commands/cr-to-rq.ts +18 -0
- package/lib/cli/commands/export-pdf.ts +193 -0
- package/lib/cli/commands/horizontal/horizontal.ts +232 -0
- package/lib/cli/commands/horizontal-create.ts +34 -0
- package/lib/cli/commands/horizontal-update.ts +32 -0
- package/lib/cli/commands/join-hint.ts +4 -0
- package/lib/cli/commands/registry.ts +59 -0
- package/lib/cli/commands/resolve-operator-hint.ts +120 -0
- package/lib/cli/commands/rq-all.ts +18 -0
- package/lib/cli/commands/rq-to-uc.ts +18 -0
- package/lib/cli/commands/story-close.ts +124 -0
- package/lib/cli/commands/sync-work-items.ts +59 -0
- package/lib/cli/commands/sys-start.ts +96 -0
- package/lib/cli/commands/test-all.ts +18 -0
- package/lib/cli/commands/test-to-story.ts +18 -0
- package/lib/cli/commands/types.ts +33 -0
- package/lib/cli/commands/uc-all.ts +18 -0
- package/lib/cli/commands/uc-to-story.ts +18 -0
- package/lib/cli/commands/uc-to-test.ts +18 -0
- package/lib/cli/comments/item-comments.ts +285 -0
- package/lib/cli/config/dot-waterfall.ts +404 -0
- package/lib/cli/config/global-cli.ts +21 -0
- package/lib/cli/config/sync-work-item-config.ts +34 -0
- package/lib/cli/core/cli-help-spec.ts +833 -0
- package/lib/cli/core/cli-log.ts +124 -0
- package/lib/cli/core/exec-file.ts +8 -0
- package/lib/cli/core/prompt-map.ts +64 -0
- package/lib/cli/core/slug.ts +44 -0
- package/lib/cli/entry.ts +4 -0
- package/lib/cli/export/collect-md.ts +41 -0
- package/lib/cli/export/export-items.ts +104 -0
- package/lib/cli/export/export-pdf-path.ts +88 -0
- package/lib/cli/export/merge-md.ts +37 -0
- package/lib/cli/export/mermaid-run.ts +104 -0
- package/lib/cli/export/pandoc-pdf.ts +90 -0
- package/lib/cli/export/pdf-bundled-worker.mjs +73 -0
- package/lib/cli/export/pdf-bundled.ts +36 -0
- package/lib/cli/git/cr-agent-context.ts +62 -0
- package/lib/cli/git/git-branch-guards.ts +60 -0
- package/lib/cli/git/git-cli-mock.ts +191 -0
- package/lib/cli/git/git-cli.ts +24 -0
- package/lib/cli/main.ts +434 -0
- package/lib/cli/paths.ts +9 -0
- package/lib/cli/project/pom-json.ts +55 -0
- package/lib/cli/spec/spec-init.ts +216 -0
- package/lib/cli/spec/spec-root.ts +93 -0
- package/lib/cli/sync/apply-remote-comments.ts +87 -0
- package/lib/cli/sync/attachment-category.ts +43 -0
- package/lib/cli/sync/diff-work-items.ts +113 -0
- package/lib/cli/sync/materialize-remote-bugs.ts +66 -0
- package/lib/cli/sync/provider-types.ts +43 -0
- package/lib/cli/sync/providers/direct-provider.ts +27 -0
- package/lib/cli/sync/providers/jira-provider.ts +34 -0
- package/lib/cli/sync/providers/registry.ts +26 -0
- package/lib/cli/sync/run-sync-work-items.ts +202 -0
- package/lib/cli/sync/spec-work-items.ts +226 -0
- package/lib/cli/sync/sync-hint-json.ts +163 -0
- package/lib/cli/sync/work-item-meta.ts +117 -0
- package/lib/cli/work-items/infer-bug-sys.ts +147 -0
- package/lib/cli/work-items/remote-bug-import-scaffold.ts +32 -0
- package/lib/cli/work-items/write-bug-to-spec.ts +158 -0
- package/package.json +54 -0
- package/prompts/commands/bug-start.md +46 -0
- package/prompts/commands/cr-finish.md +44 -0
- package/prompts/commands/cr-start.md +65 -0
- package/prompts/commands/cr-to-rq.md +62 -0
- package/prompts/commands/horizontal-create.md +27 -0
- package/prompts/commands/horizontal-update.md +39 -0
- package/prompts/commands/rq-to-uc.md +62 -0
- package/prompts/commands/story-close-all.md +34 -0
- package/prompts/commands/story-close.md +44 -0
- package/prompts/commands/sync-bugs-refine-imports.md +33 -0
- package/prompts/commands/sys-start.md +63 -0
- package/prompts/commands/test-to-story.md +64 -0
- package/prompts/commands/uc-to-story.md +85 -0
- package/prompts/commands/uc-to-test.md +58 -0
- package/prompts/global/before-changing-spec.md +62 -0
- package/prompts/global/content-requirements-vs-use-cases.md +116 -0
- package/prompts/global/cursor-overview.md +31 -0
- package/prompts/global/git-usage.md +46 -0
- package/prompts/global/horizontal-structure.md +75 -0
- package/prompts/global/workflows-index.md +59 -0
- package/prompts/items/bug-document-structure.md +23 -0
- package/prompts/items/cr-document-structure.md +45 -0
- package/prompts/items/rq-theme-document-structure.md +36 -0
- package/prompts/items/story-document-structure.md +49 -0
- package/prompts/items/sys-document-structure.md +36 -0
- package/prompts/items/tst-document-structure.md +55 -0
- package/prompts/items/uc-document-structure.md +38 -0
- package/spec-template/README.md +11 -0
- package/spec-template/full/doc/spec-structure.md +16 -0
- package/spec-template/full/prompts/before-changing-spec.md +7 -0
- package/spec-template/full/prompts/workflows.md +25 -0
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
import { CLI_JSON_DOT_WATERFALL } from "../config/dot-waterfall.js";
|
|
2
|
+
import {
|
|
3
|
+
OPERATOR_HINT_JSON,
|
|
4
|
+
OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
5
|
+
} from "../commands/resolve-operator-hint";
|
|
6
|
+
|
|
7
|
+
export const CLI_HELP_SCHEMA_VERSION = 1;
|
|
8
|
+
|
|
9
|
+
export type CliGlobalOptionSpec = {
|
|
10
|
+
long: string;
|
|
11
|
+
short?: string;
|
|
12
|
+
metavar?: string;
|
|
13
|
+
type: "string" | "boolean" | "enum";
|
|
14
|
+
enumValues?: string[];
|
|
15
|
+
description: string;
|
|
16
|
+
default?: string;
|
|
17
|
+
env?: string;
|
|
18
|
+
dotWaterfallKey?: string;
|
|
19
|
+
notes?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type CliPositionalSpec = {
|
|
23
|
+
name: string;
|
|
24
|
+
required: boolean;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type CliCommandOptionSpec = {
|
|
29
|
+
long: string;
|
|
30
|
+
short?: string;
|
|
31
|
+
type: "boolean" | "string";
|
|
32
|
+
description: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type CliCommandSpec = {
|
|
36
|
+
id: string;
|
|
37
|
+
/** Fixed argv prefix after global options, e.g. \`["cr", "to", "rq"]\`. */
|
|
38
|
+
argvPrefix: string[];
|
|
39
|
+
usage: string;
|
|
40
|
+
/**
|
|
41
|
+
* Example one-liner with \`waterfall\` prefix (realistic args; global flags optional).
|
|
42
|
+
* Emitted as \`example\` in \`help -o json\`; \`cliForm\` there matches \`usage\` (typed argv, no dotted id).
|
|
43
|
+
*/
|
|
44
|
+
example: string;
|
|
45
|
+
summary: string;
|
|
46
|
+
kind:
|
|
47
|
+
| "meta"
|
|
48
|
+
| "scaffold"
|
|
49
|
+
| "git-branch"
|
|
50
|
+
| "git-mutate"
|
|
51
|
+
| "agent-prompt"
|
|
52
|
+
| "orchestrate"
|
|
53
|
+
| "export"
|
|
54
|
+
| "sync";
|
|
55
|
+
requiresSpecRoot: boolean;
|
|
56
|
+
positionals?: CliPositionalSpec[];
|
|
57
|
+
commandOptions?: CliCommandOptionSpec[];
|
|
58
|
+
/** Shipped workflow markdown under the CLI \`prompts/\` tree (agent-prompt / orchestrate). */
|
|
59
|
+
promptFile?: string;
|
|
60
|
+
orchestrationSteps?: string[];
|
|
61
|
+
/**
|
|
62
|
+
* Required git branch in the resolved spec repo when `requiresSpecRoot` is true,
|
|
63
|
+
* or N/A wording for meta/scaffold commands (see `git-branch-guards.ts`).
|
|
64
|
+
*/
|
|
65
|
+
branchRequirement: string;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/** No spec checkout — \`help\`, etc. */
|
|
69
|
+
export const CLI_HELP_BRANCH_NONE =
|
|
70
|
+
"No spec-root git branch check (this command does not resolve a waterfall-spec checkout).";
|
|
71
|
+
|
|
72
|
+
/** \`spec init\` — works on a target directory, not an existing resolved spec root. */
|
|
73
|
+
export const CLI_HELP_BRANCH_SCAFFOLD =
|
|
74
|
+
"No spec-root resolution; initializes DIR (may create git there on develop). After that, follow CURSOR.md branch rules in the new tree.";
|
|
75
|
+
|
|
76
|
+
/** \`cr start\`, \`story close\` — \`assertBranchDevelop\`. */
|
|
77
|
+
export const CLI_HELP_BRANCH_DEVELOP =
|
|
78
|
+
'Spec repo: current git branch must be "develop".';
|
|
79
|
+
|
|
80
|
+
/** Lifecycle agents, orchestration, \`sys start\`, \`bug start\`, horizontals, \`cr finish\` — \`assertBranchForCrScopedCommand\`. */
|
|
81
|
+
export const CLI_HELP_BRANCH_FEATURE_CR =
|
|
82
|
+
"Spec repo: current git branch must match feature/CR-<digits>-… (change-request branch; use waterfall cr start from develop).";
|
|
83
|
+
|
|
84
|
+
export const GLOBAL_OPTIONS: CliGlobalOptionSpec[] = [
|
|
85
|
+
{
|
|
86
|
+
long: "spec-root",
|
|
87
|
+
metavar: "PATH",
|
|
88
|
+
type: "string",
|
|
89
|
+
description:
|
|
90
|
+
"Override waterfall-spec repository root (absolute or relative to cwd).",
|
|
91
|
+
env: "WATERFALL_SPEC_ROOT",
|
|
92
|
+
dotWaterfallKey: "spec_root",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
long: "backend",
|
|
96
|
+
metavar: "ID",
|
|
97
|
+
type: "enum",
|
|
98
|
+
enumValues: ["cline-ollama", "cursor", "claude-code"],
|
|
99
|
+
description: "Agent backend for prompt commands.",
|
|
100
|
+
default: "cline-ollama",
|
|
101
|
+
env: "WATERFALL_BACKEND",
|
|
102
|
+
dotWaterfallKey: "backend",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
long: "dry-run",
|
|
106
|
+
type: "boolean",
|
|
107
|
+
description:
|
|
108
|
+
"Print planned agent invocation only (default for lifecycle prompt commands unless overridden).",
|
|
109
|
+
dotWaterfallKey: "dry_run",
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
long: "execute-agent",
|
|
113
|
+
type: "boolean",
|
|
114
|
+
description:
|
|
115
|
+
"Invoke the real backend (cline / agent|cursor / claude); implies not dry-run.",
|
|
116
|
+
dotWaterfallKey: "execute_agent",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
long: "log-level",
|
|
120
|
+
metavar: "L",
|
|
121
|
+
type: "enum",
|
|
122
|
+
enumValues: ["silent", "normal", "verbose"],
|
|
123
|
+
description: "CLI tracing verbosity for agent planning / invoke.",
|
|
124
|
+
env: "WATERFALL_LOG_LEVEL",
|
|
125
|
+
dotWaterfallKey: "level",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
long: "quiet",
|
|
129
|
+
type: "boolean",
|
|
130
|
+
description: "Same as --log-level silent (subprocess output unchanged).",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
long: "prompt-delivery",
|
|
134
|
+
metavar: "M",
|
|
135
|
+
type: "enum",
|
|
136
|
+
enumValues: ["embed", "reference"],
|
|
137
|
+
description:
|
|
138
|
+
"embed: inline workflow markdown in the agent message; reference: filesystem paths only.",
|
|
139
|
+
default: "embed",
|
|
140
|
+
dotWaterfallKey: "prompt_delivery",
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
/** Commands and special forms handled by \`main.ts\` / registry (order matches dispatch). */
|
|
145
|
+
export const COMMAND_SPECS: CliCommandSpec[] = [
|
|
146
|
+
{
|
|
147
|
+
id: "help",
|
|
148
|
+
argvPrefix: ["help"],
|
|
149
|
+
usage: "help [-o json | --output json]",
|
|
150
|
+
example: "waterfall help -o json",
|
|
151
|
+
summary: "Print usage text or machine-readable CLI spec as JSON.",
|
|
152
|
+
kind: "meta",
|
|
153
|
+
requiresSpecRoot: false,
|
|
154
|
+
branchRequirement: CLI_HELP_BRANCH_NONE,
|
|
155
|
+
commandOptions: [
|
|
156
|
+
{
|
|
157
|
+
long: "output",
|
|
158
|
+
short: "o",
|
|
159
|
+
type: "string",
|
|
160
|
+
description: 'Output format; use "json" for the CLI command/options spec.',
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
id: "spec.init",
|
|
166
|
+
argvPrefix: ["spec", "init"],
|
|
167
|
+
usage: 'spec init --title TITLE [--full] [DIR]',
|
|
168
|
+
example: 'waterfall spec init --title "My product" --full ./my-waterfall-spec',
|
|
169
|
+
summary:
|
|
170
|
+
"Create a new spec directory: pom.json (project title + future metadata), layout, number.json, CURSOR.md, git on develop.",
|
|
171
|
+
kind: "scaffold",
|
|
172
|
+
requiresSpecRoot: false,
|
|
173
|
+
branchRequirement: CLI_HELP_BRANCH_SCAFFOLD,
|
|
174
|
+
commandOptions: [
|
|
175
|
+
{
|
|
176
|
+
long: "title",
|
|
177
|
+
metavar: "TITLE",
|
|
178
|
+
type: "string",
|
|
179
|
+
description:
|
|
180
|
+
"Required. Project name written to pom.json at the init root (also used as export pdf document title when that tree is the spec).",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
long: "full",
|
|
184
|
+
type: "boolean",
|
|
185
|
+
description:
|
|
186
|
+
"Copy regeneratable prompts/ + doc/ from spec-template/full and extend CURSOR.md.",
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
positionals: [
|
|
190
|
+
{
|
|
191
|
+
name: "DIR",
|
|
192
|
+
required: false,
|
|
193
|
+
description: "Target directory (default: .).",
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: "sync.stories",
|
|
199
|
+
argvPrefix: ["sync", "stories"],
|
|
200
|
+
usage: "sync stories [--dump-spec] [<hint…>]",
|
|
201
|
+
example: "waterfall sync stories --dump-spec",
|
|
202
|
+
summary:
|
|
203
|
+
"Load STORY-* from technical/ into canonical work-item JSON (comments from `STORY-NNN.comments.json` + tracker; compared by author `email` + `createdAt` + display `user` + body). Spec-side attachments are **other files in the same folder** as STORY-NNN.md (not the .md itself). Configure via .waterfall `sync_story_*` (`sync_story_leading=waterfall|remote`, default waterfall). On mismatches the leading side is canonical for state/title/comments/attachments for **reporting**. **Comments on disk** are always overwritten from the remote snapshot for each id present in both spec and remote (`{STORY}-NNN.comments.json`). --dump-spec prints spec-side meta only (ignores hint). Optional hint after flags: same resolution as operator hints (inline argv, `-` stdin, `@PATH`); provider `direct` requires JSON in the `--dump-spec` shape for the remote side. With `direct`, stdout ends with pretty-printed JSON (`source`: `waterfall-direct-out`) after every run (pipe to seed the next `@PATH` hint).",
|
|
204
|
+
kind: "sync",
|
|
205
|
+
requiresSpecRoot: true,
|
|
206
|
+
branchRequirement: CLI_HELP_BRANCH_NONE,
|
|
207
|
+
commandOptions: [
|
|
208
|
+
{
|
|
209
|
+
long: "dump-spec",
|
|
210
|
+
type: "boolean",
|
|
211
|
+
description:
|
|
212
|
+
"Emit waterfall-spec work-item meta JSON to stdout (no .waterfall sync_story_* required).",
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
positionals: [
|
|
216
|
+
{
|
|
217
|
+
name: "hint",
|
|
218
|
+
required: false,
|
|
219
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
id: "sync.bugs",
|
|
225
|
+
argvPrefix: ["sync", "bugs"],
|
|
226
|
+
usage: "sync bugs [--dump-spec] [<hint…>]",
|
|
227
|
+
example: "waterfall sync bugs --dump-spec",
|
|
228
|
+
summary:
|
|
229
|
+
"Same as sync stories for BUG-* (`BUG-NNN.comments.json` + tracker comments; folder file attachments) using sync_bug_* keys (`sync_bug_leading` defaults to remote). With `sync_bug_leading=remote`, remote-only bug ids are created under `technical/SYS-NNN-*/BUG-NNN-slug/` with **Draft steering (remote import)** for the agent; **SYS** comes from remote `sysId` when set, else the only `SYS-*` folder, else keyword overlap vs SYS/STORY folder names (ties → set `sysId` in the hint). After materialize + comments, runs `prompts/commands/sync-bugs-refine-imports.md` (dry-run or `--execute-agent`). Optional hint, `direct` provider, and `waterfall-direct-out` stdout after each run behave like sync stories.",
|
|
230
|
+
kind: "sync",
|
|
231
|
+
requiresSpecRoot: true,
|
|
232
|
+
branchRequirement: CLI_HELP_BRANCH_NONE,
|
|
233
|
+
commandOptions: [
|
|
234
|
+
{
|
|
235
|
+
long: "dump-spec",
|
|
236
|
+
type: "boolean",
|
|
237
|
+
description:
|
|
238
|
+
"Emit waterfall-spec BUG work-item meta JSON to stdout (no sync_bug_* required).",
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
positionals: [
|
|
242
|
+
{
|
|
243
|
+
name: "hint",
|
|
244
|
+
required: false,
|
|
245
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
id: "export.pdf",
|
|
251
|
+
argvPrefix: ["export", "pdf"],
|
|
252
|
+
usage:
|
|
253
|
+
"export pdf [--items LIST | --items=LIST] [-o PATH | --output PATH]",
|
|
254
|
+
example: "waterfall export pdf --items CR,RQ,UC,HOR,TST",
|
|
255
|
+
summary:
|
|
256
|
+
"Merge selected spec markdown into one document, render fenced Mermaid diagrams to PNG via bundled @mermaid-js/mermaid-cli (mmdc), then produce PDF with pandoc-wasm (Markdown→HTML) and puppeteer (HTML→PDF, Chromium bundled). Requires a clean git working tree at the spec root. --items is a comma-separated list of artifact codes (CR,RQ,UC,SYS,STORY,BUG,HOR,TST,CURSOR); default CR,RQ,UC,HOR,TST excludes CURSOR.md, prompts/, doc/, docs/, SYS/STORY/BUG bodies, etc. Document title (PDF metadata and top heading): non-empty string \"title\" from pom.json, found by walking up from the spec root until pom.json exists (see spec init --title). Default output: <spec-root>/docs/<basename>-<tag|short-hash>.pdf. Optional -o overrides the output file path. use_native_pandoc=true in .waterfall uses system pandoc (WATERFALL_PANDOC_ARGS).",
|
|
257
|
+
kind: "export",
|
|
258
|
+
requiresSpecRoot: true,
|
|
259
|
+
branchRequirement: CLI_HELP_BRANCH_NONE,
|
|
260
|
+
commandOptions: [
|
|
261
|
+
{
|
|
262
|
+
long: "items",
|
|
263
|
+
type: "string",
|
|
264
|
+
description:
|
|
265
|
+
"Comma-separated codes: CR,RQ,UC,SYS,STORY,BUG,HOR,TST,CURSOR. Default CR,RQ,UC,HOR,TST. Forms: --items LIST, --items=LIST, -items=LIST.",
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
long: "output",
|
|
269
|
+
short: "o",
|
|
270
|
+
type: "string",
|
|
271
|
+
description:
|
|
272
|
+
"Output PDF path (default: <spec-root>/docs/<basename>-<tag|hash>.pdf). Relative to cwd.",
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
id: "cr.start",
|
|
278
|
+
argvPrefix: ["cr", "start"],
|
|
279
|
+
usage: "cr start <description>",
|
|
280
|
+
example: 'waterfall cr start "Payment retry handling"',
|
|
281
|
+
summary:
|
|
282
|
+
"On develop: new feature/CR-* branch, scaffold CR-NNN.md + bump number.json (commit), then agent prompt cr-start.md to synthesize Summary/Proposed change (--execute-agent or dry-run).",
|
|
283
|
+
kind: "git-branch",
|
|
284
|
+
requiresSpecRoot: true,
|
|
285
|
+
branchRequirement: CLI_HELP_BRANCH_DEVELOP,
|
|
286
|
+
promptFile: "prompts/commands/cr-start.md",
|
|
287
|
+
positionals: [
|
|
288
|
+
{
|
|
289
|
+
name: "description",
|
|
290
|
+
required: true,
|
|
291
|
+
description: `CR title / slug source. ${OPERATOR_HINT_POSITIONAL_DESCRIPTION}`,
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
id: "sys.start",
|
|
297
|
+
argvPrefix: ["sys", "start"],
|
|
298
|
+
usage: "sys start <description>",
|
|
299
|
+
example: 'waterfall sys start "Authentication subsystem"',
|
|
300
|
+
summary:
|
|
301
|
+
"On a CR branch: scaffold SYS-NNN.md + bump number.json (commit), then agent prompt sys-start.md to synthesize Purpose (--execute-agent or dry-run).",
|
|
302
|
+
kind: "git-mutate",
|
|
303
|
+
requiresSpecRoot: true,
|
|
304
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
305
|
+
promptFile: "prompts/commands/sys-start.md",
|
|
306
|
+
positionals: [
|
|
307
|
+
{
|
|
308
|
+
name: "description",
|
|
309
|
+
required: true,
|
|
310
|
+
description: `Subsystem title / slug source. ${OPERATOR_HINT_POSITIONAL_DESCRIPTION}`,
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
id: "bug.start",
|
|
316
|
+
argvPrefix: ["bug", "start"],
|
|
317
|
+
usage: "bug start SYS-NNN <hint>",
|
|
318
|
+
example: 'waterfall bug start SYS-001 "Cart total rounds incorrectly"',
|
|
319
|
+
summary:
|
|
320
|
+
"On a CR branch: scaffold BUG-NNN.md under the matching SYS folder + bump number.json (commit), then agent prompt bug-start.md to synthesize Summary (--execute-agent or dry-run).",
|
|
321
|
+
kind: "git-mutate",
|
|
322
|
+
requiresSpecRoot: true,
|
|
323
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
324
|
+
promptFile: "prompts/commands/bug-start.md",
|
|
325
|
+
positionals: [
|
|
326
|
+
{
|
|
327
|
+
name: "sysId",
|
|
328
|
+
required: true,
|
|
329
|
+
description: "Parent subsystem id (SYS-NNN); must match an existing technical/SYS-NNN-* folder.",
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: "hint",
|
|
333
|
+
required: true,
|
|
334
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
335
|
+
},
|
|
336
|
+
],
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
id: "horizontal.create",
|
|
340
|
+
argvPrefix: ["horizontal", "create"],
|
|
341
|
+
usage: "horizontal create story <name-slug> <purpose>",
|
|
342
|
+
example:
|
|
343
|
+
'waterfall horizontal create story database-model "Shared schema for orders"',
|
|
344
|
+
summary:
|
|
345
|
+
"On a CR branch: scaffold HOR-NNN.md + bump next.HOR (commit), then agent prompt horizontal-create.md to synthesize Purpose (--execute-agent or dry-run).",
|
|
346
|
+
kind: "git-mutate",
|
|
347
|
+
requiresSpecRoot: true,
|
|
348
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
349
|
+
promptFile: "prompts/commands/horizontal-create.md",
|
|
350
|
+
positionals: [
|
|
351
|
+
{
|
|
352
|
+
name: "anchor",
|
|
353
|
+
required: true,
|
|
354
|
+
description: "Anchor item type (e.g. story).",
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: "name-slug",
|
|
358
|
+
required: true,
|
|
359
|
+
description: "Horizontal name slug (e.g. database-model).",
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: "purpose",
|
|
363
|
+
required: true,
|
|
364
|
+
description: `Purpose text. ${OPERATOR_HINT_POSITIONAL_DESCRIPTION}`,
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
id: "horizontal.update",
|
|
370
|
+
argvPrefix: ["horizontal", "update"],
|
|
371
|
+
usage: "horizontal update HOR-NNN [<hint>]",
|
|
372
|
+
example: "waterfall horizontal update HOR-001",
|
|
373
|
+
summary:
|
|
374
|
+
"On a CR branch: run git diff develop...HEAD for scope; agent prompt horizontal-update (does not edit HOR file mechanically).",
|
|
375
|
+
kind: "agent-prompt",
|
|
376
|
+
requiresSpecRoot: true,
|
|
377
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
378
|
+
promptFile: "prompts/commands/horizontal-update.md",
|
|
379
|
+
positionals: [
|
|
380
|
+
{
|
|
381
|
+
name: "HOR-NNN",
|
|
382
|
+
required: true,
|
|
383
|
+
description: "Horizontal id (HOR-001 or 001).",
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
name: "hint",
|
|
387
|
+
required: false,
|
|
388
|
+
description: `Optional operator hint. ${OPERATOR_HINT_POSITIONAL_DESCRIPTION}`,
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
id: "cr.finish",
|
|
394
|
+
argvPrefix: ["cr", "finish"],
|
|
395
|
+
usage: "cr finish",
|
|
396
|
+
example: "waterfall cr finish",
|
|
397
|
+
summary:
|
|
398
|
+
"On CR branch: validate diff vs develop, merge into develop, checkout develop.",
|
|
399
|
+
kind: "git-mutate",
|
|
400
|
+
requiresSpecRoot: true,
|
|
401
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
402
|
+
promptFile: "prompts/commands/cr-finish.md",
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
id: "cr.to-rq",
|
|
406
|
+
argvPrefix: ["cr", "to", "rq"],
|
|
407
|
+
usage: "cr to rq <hint>",
|
|
408
|
+
example: 'waterfall cr to rq "Triage scope for API errors"',
|
|
409
|
+
summary: "Agent: CR → RQ triage (cr-to-rq).",
|
|
410
|
+
kind: "agent-prompt",
|
|
411
|
+
requiresSpecRoot: true,
|
|
412
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
413
|
+
promptFile: "prompts/commands/cr-to-rq.md",
|
|
414
|
+
positionals: [
|
|
415
|
+
{
|
|
416
|
+
name: "hint",
|
|
417
|
+
required: true,
|
|
418
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
419
|
+
},
|
|
420
|
+
],
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
id: "rq.to-uc",
|
|
424
|
+
argvPrefix: ["rq", "to", "uc"],
|
|
425
|
+
usage: "rq to uc <hint>",
|
|
426
|
+
example: 'waterfall rq to uc "Split admin vs customer flows"',
|
|
427
|
+
summary: "Agent: RQ → UC (rq-to-uc).",
|
|
428
|
+
kind: "agent-prompt",
|
|
429
|
+
requiresSpecRoot: true,
|
|
430
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
431
|
+
promptFile: "prompts/commands/rq-to-uc.md",
|
|
432
|
+
positionals: [
|
|
433
|
+
{
|
|
434
|
+
name: "hint",
|
|
435
|
+
required: true,
|
|
436
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
437
|
+
},
|
|
438
|
+
],
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
id: "uc.to-story",
|
|
442
|
+
argvPrefix: ["uc", "to", "story"],
|
|
443
|
+
usage: "uc to story <hint>",
|
|
444
|
+
example: 'waterfall uc to story "Checkout happy path"',
|
|
445
|
+
summary: "Agent: UC → story (uc-to-story).",
|
|
446
|
+
kind: "agent-prompt",
|
|
447
|
+
requiresSpecRoot: true,
|
|
448
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
449
|
+
promptFile: "prompts/commands/uc-to-story.md",
|
|
450
|
+
positionals: [
|
|
451
|
+
{
|
|
452
|
+
name: "hint",
|
|
453
|
+
required: true,
|
|
454
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
455
|
+
},
|
|
456
|
+
],
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
id: "uc.to-test",
|
|
460
|
+
argvPrefix: ["uc", "to", "test"],
|
|
461
|
+
usage: "uc to test <hint>",
|
|
462
|
+
example: 'waterfall uc to test "Gherkin for returns and refunds"',
|
|
463
|
+
summary: "Agent: UC → test (uc-to-test).",
|
|
464
|
+
kind: "agent-prompt",
|
|
465
|
+
requiresSpecRoot: true,
|
|
466
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
467
|
+
promptFile: "prompts/commands/uc-to-test.md",
|
|
468
|
+
positionals: [
|
|
469
|
+
{
|
|
470
|
+
name: "hint",
|
|
471
|
+
required: true,
|
|
472
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
473
|
+
},
|
|
474
|
+
],
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
id: "test.to-story",
|
|
478
|
+
argvPrefix: ["test", "to", "story"],
|
|
479
|
+
usage: "test to story <hint>",
|
|
480
|
+
example: 'waterfall test to story "Align tests with STORY-002"',
|
|
481
|
+
summary: "Agent: test → story (test-to-story).",
|
|
482
|
+
kind: "agent-prompt",
|
|
483
|
+
requiresSpecRoot: true,
|
|
484
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
485
|
+
promptFile: "prompts/commands/test-to-story.md",
|
|
486
|
+
positionals: [
|
|
487
|
+
{
|
|
488
|
+
name: "hint",
|
|
489
|
+
required: true,
|
|
490
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
491
|
+
},
|
|
492
|
+
],
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
id: "cr.all",
|
|
496
|
+
argvPrefix: ["cr", "all"],
|
|
497
|
+
usage: "cr all [<hint>]",
|
|
498
|
+
example: 'waterfall cr all "Run full chain from new CR"',
|
|
499
|
+
summary: "Orchestrate cr → rq → rq→uc → uc→story → uc→test → test→story.",
|
|
500
|
+
kind: "orchestrate",
|
|
501
|
+
requiresSpecRoot: true,
|
|
502
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
503
|
+
positionals: [
|
|
504
|
+
{
|
|
505
|
+
name: "hint",
|
|
506
|
+
required: false,
|
|
507
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
508
|
+
},
|
|
509
|
+
],
|
|
510
|
+
orchestrationSteps: [
|
|
511
|
+
"cr-to-rq",
|
|
512
|
+
"rq-to-uc",
|
|
513
|
+
"uc-to-story",
|
|
514
|
+
"uc-to-test",
|
|
515
|
+
"test-to-story",
|
|
516
|
+
],
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
id: "rq.all",
|
|
520
|
+
argvPrefix: ["rq", "all"],
|
|
521
|
+
usage: "rq all [<hint>]",
|
|
522
|
+
example: 'waterfall rq all "Continue from requirements"',
|
|
523
|
+
summary: "Orchestrate rq→uc → uc→story → uc→test → test→story.",
|
|
524
|
+
kind: "orchestrate",
|
|
525
|
+
requiresSpecRoot: true,
|
|
526
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
527
|
+
positionals: [
|
|
528
|
+
{
|
|
529
|
+
name: "hint",
|
|
530
|
+
required: false,
|
|
531
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
532
|
+
},
|
|
533
|
+
],
|
|
534
|
+
orchestrationSteps: [
|
|
535
|
+
"rq-to-uc",
|
|
536
|
+
"uc-to-story",
|
|
537
|
+
"uc-to-test",
|
|
538
|
+
"test-to-story",
|
|
539
|
+
],
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
id: "uc.all",
|
|
543
|
+
argvPrefix: ["uc", "all"],
|
|
544
|
+
usage: "uc all [<hint>]",
|
|
545
|
+
example: 'waterfall uc all "Stories and tests from use cases"',
|
|
546
|
+
summary: "Orchestrate uc→story → uc→test → test→story.",
|
|
547
|
+
kind: "orchestrate",
|
|
548
|
+
requiresSpecRoot: true,
|
|
549
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
550
|
+
positionals: [
|
|
551
|
+
{
|
|
552
|
+
name: "hint",
|
|
553
|
+
required: false,
|
|
554
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
555
|
+
},
|
|
556
|
+
],
|
|
557
|
+
orchestrationSteps: ["uc-to-story", "uc-to-test", "test-to-story"],
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
id: "test.all",
|
|
561
|
+
argvPrefix: ["test", "all"],
|
|
562
|
+
usage: "test all [<hint>]",
|
|
563
|
+
example: 'waterfall test all "Propagate test specs to stories"',
|
|
564
|
+
summary: "Orchestrate test→story only.",
|
|
565
|
+
kind: "orchestrate",
|
|
566
|
+
requiresSpecRoot: true,
|
|
567
|
+
branchRequirement: CLI_HELP_BRANCH_FEATURE_CR,
|
|
568
|
+
positionals: [
|
|
569
|
+
{
|
|
570
|
+
name: "hint",
|
|
571
|
+
required: false,
|
|
572
|
+
description: OPERATOR_HINT_POSITIONAL_DESCRIPTION,
|
|
573
|
+
},
|
|
574
|
+
],
|
|
575
|
+
orchestrationSteps: ["test-to-story"],
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
id: "comment.add",
|
|
579
|
+
argvPrefix: ["comment", "add"],
|
|
580
|
+
usage: "comment add <ITEM-ID> <email> <display-name> <hint…>",
|
|
581
|
+
example:
|
|
582
|
+
'waterfall comment add STORY-001 dev@acme.com Reviewer "Align with API review notes"',
|
|
583
|
+
summary:
|
|
584
|
+
"On develop: append a remark for any spec item with a canonical `{ITEM-ID}.md` (CR,RQ,UC,SYS,STORY,BUG,HOR,TST + NNN). Stored as `{ITEM-ID}.comments.json` beside that markdown; author identity is `email`, display name is `from`. State OPEN + ISO timestamps; RESOLVED|REJECTED by editing the file.",
|
|
585
|
+
kind: "git-mutate",
|
|
586
|
+
requiresSpecRoot: true,
|
|
587
|
+
branchRequirement: CLI_HELP_BRANCH_DEVELOP,
|
|
588
|
+
positionals: [
|
|
589
|
+
{
|
|
590
|
+
name: "item",
|
|
591
|
+
required: true,
|
|
592
|
+
description:
|
|
593
|
+
"CR|RQ|UC|SYS|STORY|BUG|HOR|TST-NNN — must match exactly one `{ITEM}.md` under the spec root.",
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
name: "email",
|
|
597
|
+
required: true,
|
|
598
|
+
description: "Author identifier for sync (same person as display name).",
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
name: "display-name",
|
|
602
|
+
required: true,
|
|
603
|
+
description: "Short display label stored as `from`.",
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
name: "hint",
|
|
607
|
+
required: true,
|
|
608
|
+
description: "Remark text (remaining argv joined with spaces).",
|
|
609
|
+
},
|
|
610
|
+
],
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
id: "story.close",
|
|
614
|
+
argvPrefix: ["story", "close"],
|
|
615
|
+
usage: "story close STORY-NNN | story close all",
|
|
616
|
+
example: "waterfall story close STORY-001",
|
|
617
|
+
summary:
|
|
618
|
+
"On develop: close one story folder (rename with _) or note for close all.",
|
|
619
|
+
kind: "git-mutate",
|
|
620
|
+
requiresSpecRoot: true,
|
|
621
|
+
branchRequirement: CLI_HELP_BRANCH_DEVELOP,
|
|
622
|
+
positionals: [
|
|
623
|
+
{
|
|
624
|
+
name: "STORY-NNN|all",
|
|
625
|
+
required: true,
|
|
626
|
+
description: "Story id or all (all may be restricted in implementation).",
|
|
627
|
+
},
|
|
628
|
+
],
|
|
629
|
+
},
|
|
630
|
+
];
|
|
631
|
+
|
|
632
|
+
export type CliEnvironmentVariableSpec = {
|
|
633
|
+
name: string;
|
|
634
|
+
description: string;
|
|
635
|
+
/** Typical values or format (when not obvious from description). */
|
|
636
|
+
valueDescription?: string;
|
|
637
|
+
cliFlag?: string;
|
|
638
|
+
dotWaterfallKey?: string;
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
export type CliEnvironmentCategorySpec = {
|
|
642
|
+
id: string;
|
|
643
|
+
title: string;
|
|
644
|
+
description?: string;
|
|
645
|
+
variables: CliEnvironmentVariableSpec[];
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
export type CliHelpJsonEnvironment = {
|
|
649
|
+
description: string;
|
|
650
|
+
precedenceNote: string;
|
|
651
|
+
categories: CliEnvironmentCategorySpec[];
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* All env vars referenced by waterfall-cli (read in code or documented for operators).
|
|
656
|
+
* WATERFALL_* settings mirror {@link GLOBAL_OPTIONS} where \`env\` is set.
|
|
657
|
+
*/
|
|
658
|
+
export function buildCliHelpEnvironment(): CliHelpJsonEnvironment {
|
|
659
|
+
const fromGlobals: CliEnvironmentVariableSpec[] = GLOBAL_OPTIONS.filter(
|
|
660
|
+
(o): o is CliGlobalOptionSpec & { env: string } => Boolean(o.env),
|
|
661
|
+
).map((o) => ({
|
|
662
|
+
name: o.env,
|
|
663
|
+
description: o.description,
|
|
664
|
+
valueDescription: o.enumValues?.join(" | "),
|
|
665
|
+
cliFlag: `--${o.long}`,
|
|
666
|
+
dotWaterfallKey: o.dotWaterfallKey,
|
|
667
|
+
}));
|
|
668
|
+
|
|
669
|
+
return {
|
|
670
|
+
description:
|
|
671
|
+
"Environment variables read by waterfall-cli or inherited by agent backend processes.",
|
|
672
|
+
precedenceNote:
|
|
673
|
+
"For CLI settings mirrored by flags, precedence is: argv > WATERFALL_* env > .waterfall > defaults (see config.precedence).",
|
|
674
|
+
categories: [
|
|
675
|
+
{
|
|
676
|
+
id: "waterfall-cli",
|
|
677
|
+
title: "Waterfall CLI (WATERFALL_*)",
|
|
678
|
+
variables: [
|
|
679
|
+
...fromGlobals,
|
|
680
|
+
{
|
|
681
|
+
name: "WATERFALL_MMDC",
|
|
682
|
+
description:
|
|
683
|
+
"Absolute path to the Mermaid CLI binary (`mmdc`) for `waterfall export pdf`; overrides PATH and npx fallback.",
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
name: "WATERFALL_PANDOC",
|
|
687
|
+
description:
|
|
688
|
+
"Absolute path to the `pandoc` binary when `use_native_pandoc=true`; overrides PATH and built-in Homebrew guesses.",
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
name: "WATERFALL_PANDOC_PDF_ENGINE",
|
|
692
|
+
description:
|
|
693
|
+
"When `use_native_pandoc=true`: LaTeX engine for Pandoc (default `xelatex`, for Unicode in specs). Override e.g. `pdflatex` or `lualatex` if needed.",
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
name: "WATERFALL_PANDOC_ARGS",
|
|
697
|
+
description:
|
|
698
|
+
"When `use_native_pandoc=true` in .waterfall: extra arguments (space-separated) after input markdown, `-o` PDF path, TOC, and `--pdf-engine` (so you can append another `--pdf-engine` to override).",
|
|
699
|
+
},
|
|
700
|
+
],
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
id: "cline",
|
|
704
|
+
title: "Cline backend",
|
|
705
|
+
description:
|
|
706
|
+
"Read when invoking the cline-ollama backend (--backend cline-ollama).",
|
|
707
|
+
variables: [
|
|
708
|
+
{
|
|
709
|
+
name: "WATERFALL_CLINE_MODEL",
|
|
710
|
+
description:
|
|
711
|
+
"Optional model id passed to the Cline CLI as -m when set.",
|
|
712
|
+
valueDescription: "e.g. llama3.2:latest",
|
|
713
|
+
},
|
|
714
|
+
],
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
id: "agent-inherit",
|
|
718
|
+
title: "Agent subprocess environment",
|
|
719
|
+
description:
|
|
720
|
+
"Cursor, Claude Code, and Cline run with the current process environment. Set provider keys and endpoints per each tool’s docs. UPPER_SNAKE keys from ~/.waterfall / .waterfall are merged into process.env when unset; see dotWaterfall.environmentPassthrough (examples: ANTHROPIC_API_KEY, CURSOR_API_KEY, OLLAMA_HOST).",
|
|
721
|
+
variables: [],
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
id: "testing",
|
|
725
|
+
title: "Testing / internal",
|
|
726
|
+
description:
|
|
727
|
+
"Used by the waterfall-cli Vitest suite; operators do not need these.",
|
|
728
|
+
variables: [
|
|
729
|
+
{
|
|
730
|
+
name: "WATERFALL_TEST_HOME",
|
|
731
|
+
description:
|
|
732
|
+
"When set, used as the home directory for resolving ~/.waterfall.",
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
name: "VITEST",
|
|
736
|
+
description:
|
|
737
|
+
'When "true", skips auto-creating ~/.waterfall during tests and adjusts git helpers.',
|
|
738
|
+
},
|
|
739
|
+
],
|
|
740
|
+
},
|
|
741
|
+
],
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
export type CliHelpJsonCommand = CliCommandSpec & {
|
|
746
|
+
/** Typed argv after global options (spaces, not dotted \`id\`). Same text as \`usage\`. */
|
|
747
|
+
cliForm: string;
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
export type CliHelpJson = {
|
|
751
|
+
schemaVersion: number;
|
|
752
|
+
name: string;
|
|
753
|
+
title: string;
|
|
754
|
+
globalOptions: CliGlobalOptionSpec[];
|
|
755
|
+
config: {
|
|
756
|
+
files: string[];
|
|
757
|
+
precedence: string;
|
|
758
|
+
notes: string[];
|
|
759
|
+
};
|
|
760
|
+
/** Detailed \`.waterfall\` / \`~/.waterfall\` syntax and keys (see \`parseDotWaterfallContent\`). */
|
|
761
|
+
dotWaterfall: typeof CLI_JSON_DOT_WATERFALL;
|
|
762
|
+
/** Env vars read by the CLI or relevant to agent subprocesses (see \`buildCliHelpEnvironment\`). */
|
|
763
|
+
environment: CliHelpJsonEnvironment;
|
|
764
|
+
/** How operator hints are resolved (inline, stdin, file); see \`resolveOperatorHint\`. */
|
|
765
|
+
operatorHint: typeof OPERATOR_HINT_JSON;
|
|
766
|
+
specResolution: string[];
|
|
767
|
+
commands: CliHelpJsonCommand[];
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
export function buildCliHelpJson(): CliHelpJson {
|
|
771
|
+
return {
|
|
772
|
+
schemaVersion: CLI_HELP_SCHEMA_VERSION,
|
|
773
|
+
name: "waterfall",
|
|
774
|
+
title: "Waterfall CLI — waterfall-spec workflows",
|
|
775
|
+
globalOptions: GLOBAL_OPTIONS,
|
|
776
|
+
config: {
|
|
777
|
+
files: [".waterfall (cwd)", "~/.waterfall"],
|
|
778
|
+
precedence:
|
|
779
|
+
"flags > WATERFALL_* env > ./.waterfall > ~/.waterfall > defaults",
|
|
780
|
+
notes: [
|
|
781
|
+
"~/.waterfall is created on first run when missing (commented examples).",
|
|
782
|
+
"Log/tracing: WATERFALL_LOG_LEVEL or level= in .waterfall.",
|
|
783
|
+
],
|
|
784
|
+
},
|
|
785
|
+
dotWaterfall: CLI_JSON_DOT_WATERFALL,
|
|
786
|
+
environment: buildCliHelpEnvironment(),
|
|
787
|
+
operatorHint: OPERATOR_HINT_JSON,
|
|
788
|
+
specResolution: [
|
|
789
|
+
"--spec-root",
|
|
790
|
+
"WATERFALL_SPEC_ROOT",
|
|
791
|
+
"./.waterfall and ~/.waterfall spec_root",
|
|
792
|
+
"waterfall.json waterfallSpecRelativePath (walk up from cwd)",
|
|
793
|
+
"walk up to directory containing CURSOR.md",
|
|
794
|
+
],
|
|
795
|
+
commands: COMMAND_SPECS.map((c) => ({
|
|
796
|
+
...c,
|
|
797
|
+
cliForm: c.usage,
|
|
798
|
+
})),
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
export function formatCliHelpJson(): string {
|
|
803
|
+
return `${JSON.stringify(buildCliHelpJson(), null, 2)}\n`;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Parse \`help\` argv after the \`help\` token: \`help\`, \`help -o json\`, etc.
|
|
808
|
+
*/
|
|
809
|
+
export function parseHelpFormat(rest: string[]): {
|
|
810
|
+
format: "text" | "json";
|
|
811
|
+
} {
|
|
812
|
+
if (rest.length <= 1) return { format: "text" };
|
|
813
|
+
let format: "text" | "json" = "text";
|
|
814
|
+
for (let i = 1; i < rest.length; i++) {
|
|
815
|
+
const a = rest[i]!;
|
|
816
|
+
if (a === "-o" || a === "--output") {
|
|
817
|
+
const v = rest[++i];
|
|
818
|
+
if (!v) {
|
|
819
|
+
throw new Error(`${a} requires an argument (use json)`);
|
|
820
|
+
}
|
|
821
|
+
if (v.toLowerCase() === "json") {
|
|
822
|
+
format = "json";
|
|
823
|
+
} else {
|
|
824
|
+
throw new Error(
|
|
825
|
+
`Invalid output format "${v}" (use: waterfall help -o json)`,
|
|
826
|
+
);
|
|
827
|
+
}
|
|
828
|
+
continue;
|
|
829
|
+
}
|
|
830
|
+
throw new Error(`Unknown help option: ${a} (try: waterfall help -o json)`);
|
|
831
|
+
}
|
|
832
|
+
return { format };
|
|
833
|
+
}
|