@esneiderbravo/speclaw 2.0.7 → 2.0.9
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/README.md +37 -8
- package/dist/cli/commands/cortex.js +4 -0
- package/dist/cli/commands/index-build.js +2 -15
- package/dist/cli/commands/init.js +11 -3
- package/dist/cli/commands/lawbook.js +2 -0
- package/dist/cli/commands/laws.js +149 -19
- package/dist/cli/commands/update.js +93 -24
- package/dist/cli/index.js +24 -66
- package/dist/cli/lib/help.js +489 -0
- package/dist/cli/lib/self-update.js +107 -0
- package/dist/cli/lib/update-check.js +17 -10
- package/dist/modules/cortex/brief.js +3 -1
- package/dist/modules/cortex/harness.js +56 -7
- package/dist/modules/cortex/paths.js +39 -0
- package/dist/modules/cortex/register.js +6 -3
- package/dist/modules/cortex/status.js +200 -0
- package/dist/modules/foundation/compile-laws.js +23 -6
- package/dist/modules/foundation/doctor.js +11 -1
- package/dist/modules/foundation/lock.js +224 -20
- package/dist/modules/foundation/scaffold.js +24 -8
- package/dist/modules/lawbook/assets/agents/archiver.md +5 -2
- package/dist/modules/lawbook/assets/commands/cortex.md +2 -0
- package/dist/modules/lawbook/assets/skills/cortex/steps/01-load-or-start.md +27 -0
- package/dist/modules/lawbook/assets/skills/cortex/steps/02-dispatch-loop.md +19 -1
- package/dist/modules/lawbook/assets/skills/cortex/steps/03-complete.md +3 -1
- package/dist/modules/lawbook/change-tool.js +4 -1
- package/dist/modules/lawbook/engine.js +24 -2
- package/dist/shared/agents.js +56 -7
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2,71 +2,7 @@
|
|
|
2
2
|
import { parseFlags } from "./lib/args.js";
|
|
3
3
|
import { ui, header } from "./lib/ui.js";
|
|
4
4
|
import { maybeNotifyUpdate } from "./lib/update-check.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Usage: speclaw <command> [options]
|
|
8
|
-
|
|
9
|
-
Install globally so the command is always available:
|
|
10
|
-
npm i -g @esneiderbravo/speclaw
|
|
11
|
-
|
|
12
|
-
Setup
|
|
13
|
-
init Interactive setup: pick agents, scaffold, index, get the prompt
|
|
14
|
-
(--minimal omits setup/lifecycle MCP tools)
|
|
15
|
-
update Apply project migrations (advisory if a newer binary exists)
|
|
16
|
-
(--check reports version only; --minimal persists minimal exposure)
|
|
17
|
-
agent list Show which agents are configured
|
|
18
|
-
agent add <id> Configure another agent later (symlinks + MCP)
|
|
19
|
-
|
|
20
|
-
Compass (code intelligence — the same surface agents use via MCP)
|
|
21
|
-
index (Re)build the local code graph (--force / --prune / --json)
|
|
22
|
-
session-start Silent, fail-safe refresh of an existing index (SessionStart hook)
|
|
23
|
-
watch Keep the index fresh on file changes
|
|
24
|
-
explore <node> A node's source + callers/callees
|
|
25
|
-
search <query> Hybrid find (BM25+vector+name); --focus --max-tokens --explain
|
|
26
|
-
recall "<query>" Hybrid find with concept weights; same flags as search
|
|
27
|
-
impact <node> Blast radius (grouped by module; --flat / --json)
|
|
28
|
-
affected-tests Tests affected by a change (--file / --from-diff / --json)
|
|
29
|
-
diff-context Change context for a diff (--file / --rev / --worktree / --json)
|
|
30
|
-
hotspots Rank files by recent churn × AST complexity (--json / --sort)
|
|
31
|
-
coupling <file> Temporal co-change partners for a file (--json)
|
|
32
|
-
trace <from> <to> A call path between two nodes
|
|
33
|
-
visualize [node] Interactive HTML graph → .speclaw/graph.html
|
|
34
|
-
|
|
35
|
-
Cortex (One brain. Many agents. — multi-agent loop)
|
|
36
|
-
cortex <op> status|start|advance|rework|brief — drive harness.json (--change)
|
|
37
|
-
|
|
38
|
-
Lawbook (spec-driven workflow)
|
|
39
|
-
quick <name> Scaffold a level-0 change (record.md + reports)
|
|
40
|
-
lawbook init Create the lawbook/ workspace
|
|
41
|
-
lawbook list Active/archived changes and capabilities
|
|
42
|
-
lawbook level <mode> Propose/set/promote/explain ceremony level (--json)
|
|
43
|
-
lawbook draft <name> Scaffold a feature change (--level N, --capability C, --json)
|
|
44
|
-
lawbook draft --bug <c> Scaffold a bug change (bugfix.md + reports)
|
|
45
|
-
lawbook investigate Rank bug suspects from graph (--symptom / --stack-trace, --json)
|
|
46
|
-
lawbook validate <c> Validate a change's artifacts
|
|
47
|
-
lawbook sync <c> Promote delta specs to canonical
|
|
48
|
-
lawbook archive <c> Finalize and archive a change
|
|
49
|
-
lawbook harness <op> Deprecated alias for \`speclaw cortex\` (compat)
|
|
50
|
-
|
|
51
|
-
Other
|
|
52
|
-
doctor Verify the installation (--json, --offline, --strict)
|
|
53
|
-
budget Measure always-on context cost (tools, skills, instructions)
|
|
54
|
-
coverage Requirement → impl → test coverage (--json, --tap, --adopt, --write)
|
|
55
|
-
drift Spec↔code drift (--json, --reseal, --reverse, --fail-on)
|
|
56
|
-
owners Compile team.owners → .github/CODEOWNERS (--write / --check / --diff)
|
|
57
|
-
telemetry status Confirm speclaw ships no telemetry
|
|
58
|
-
check Evaluate an action against the laws (hooks call this; --dry-run to preview)
|
|
59
|
-
laws verify Verify the deterministic dependency/graph laws against the index
|
|
60
|
-
laws compile Compile laws into agent rule dialects (AGENTS / Claude / Cursor / …)
|
|
61
|
-
laws import Import third-party rules as draft laws (--from rulesync)
|
|
62
|
-
laws lock Create/refresh committed speclaw.lock digests for rule files
|
|
63
|
-
laws accept <path> Interactively accept a changed rule-file digest (TTY only)
|
|
64
|
-
laws scan Scan rule/skill files for prompt-injection patterns
|
|
65
|
-
verify Verify laws + integrity for CI: exit codes, --sarif, --json, --strict-engines
|
|
66
|
-
mcp Start the MCP server (used by your agent's config)
|
|
67
|
-
help Show this help
|
|
68
|
-
--version Print the installed speclaw version
|
|
69
|
-
`;
|
|
5
|
+
import { GLOBAL_HELP as HELP, helpFor, knownCommands, wantsHelp } from "./lib/help.js";
|
|
70
6
|
// Commands that open with the one-line branded header. These are the
|
|
71
7
|
// interactive, human-facing commands whose stdout is prose. Deliberately
|
|
72
8
|
// excluded: `version`/`--version`/`-v` (bare scriptable value), the Compass
|
|
@@ -107,6 +43,9 @@ function maybeHeader(cmd, flags) {
|
|
|
107
43
|
return;
|
|
108
44
|
if (!HEADER_COMMANDS.has(cmd))
|
|
109
45
|
return;
|
|
46
|
+
// A self-update child re-runs `update`; the parent already printed the header.
|
|
47
|
+
if (cmd === "update" && process.env.SPECLAW_SELF_UPDATED)
|
|
48
|
+
return;
|
|
110
49
|
if (cmd === "budget" && flags.json)
|
|
111
50
|
return;
|
|
112
51
|
if (cmd === "doctor" && flags.json)
|
|
@@ -129,8 +68,16 @@ function maybeHeader(cmd, flags) {
|
|
|
129
68
|
return;
|
|
130
69
|
header();
|
|
131
70
|
}
|
|
71
|
+
// The dispatcher's known commands come from the help registry, so a command
|
|
72
|
+
// without usage text is rejected here before it can ship.
|
|
73
|
+
const KNOWN_COMMANDS = knownCommands();
|
|
132
74
|
/** Run the handler for a single command. Returns when the command completes. */
|
|
133
75
|
async function dispatch(cmd, flags) {
|
|
76
|
+
if (cmd !== undefined && !KNOWN_COMMANDS.has(cmd)) {
|
|
77
|
+
ui.err(`Unknown command: ${cmd}`);
|
|
78
|
+
console.log(HELP);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
134
81
|
switch (cmd) {
|
|
135
82
|
case undefined:
|
|
136
83
|
case "help":
|
|
@@ -201,9 +148,20 @@ async function dispatch(cmd, flags) {
|
|
|
201
148
|
process.exit(1);
|
|
202
149
|
}
|
|
203
150
|
}
|
|
204
|
-
/**
|
|
151
|
+
/**
|
|
152
|
+
* Parse argv, run the command, then surface an update notice if one is due.
|
|
153
|
+
* `<command> --help` / `-h` short-circuits first: it prints the command's usage
|
|
154
|
+
* and runs nothing — no header, no notifier, no handler, no file writes.
|
|
155
|
+
*/
|
|
205
156
|
async function main() {
|
|
206
157
|
const [cmd, ...rest] = process.argv.slice(2);
|
|
158
|
+
// Covers: req~per-command-help~1
|
|
159
|
+
const usage = cmd !== undefined && wantsHelp(rest) ? helpFor(cmd) : null;
|
|
160
|
+
if (usage !== null) {
|
|
161
|
+
process.stdout.write(usage.endsWith("\n") ? usage : usage + "\n");
|
|
162
|
+
process.exitCode = 0;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
207
165
|
const flags = parseFlags(rest);
|
|
208
166
|
maybeHeader(cmd, flags);
|
|
209
167
|
await dispatch(cmd, flags);
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's help registry: the global usage text, the one list of dispatchable
|
|
3
|
+
* commands, and each command's own usage text. It lives apart from
|
|
4
|
+
* `src/cli/index.ts` because that module runs `main()` on import, and it is
|
|
5
|
+
* shared with the dispatcher so a command cannot ship without usage text.
|
|
6
|
+
*/
|
|
7
|
+
/** The global usage text printed by `speclaw help`, `--help`, `-h`, and no arguments. */
|
|
8
|
+
export const GLOBAL_HELP = `speclaw — spec-driven, agent-ready projects (Foundation + Compass + Lawbook + Cortex)
|
|
9
|
+
|
|
10
|
+
Usage: speclaw <command> [options] (speclaw <command> --help for one command)
|
|
11
|
+
|
|
12
|
+
Install globally so the command is always available:
|
|
13
|
+
npm i -g @esneiderbravo/speclaw (or run npx @esneiderbravo/speclaw@latest init)
|
|
14
|
+
|
|
15
|
+
Setup
|
|
16
|
+
init Interactive setup: pick agents, scaffold, index, get the prompt
|
|
17
|
+
(--minimal omits setup/lifecycle MCP tools)
|
|
18
|
+
update Re-run itself at the latest version via npx, then apply project
|
|
19
|
+
migrations (--check reports version only; --no-self-update
|
|
20
|
+
migrates with this binary; --minimal persists minimal exposure)
|
|
21
|
+
agent list Show which agents are configured
|
|
22
|
+
agent add <id> Configure another agent later (symlinks + MCP)
|
|
23
|
+
|
|
24
|
+
Compass (code intelligence — the same surface agents use via MCP)
|
|
25
|
+
index (Re)build the local code graph (--force / --prune / --json)
|
|
26
|
+
session-start Silent, fail-safe refresh of an existing index (SessionStart hook)
|
|
27
|
+
watch Keep the index fresh on file changes
|
|
28
|
+
explore <node> A node's source + callers/callees
|
|
29
|
+
search <query> Hybrid find (BM25+vector+name); --focus --max-tokens --explain
|
|
30
|
+
recall "<query>" Hybrid find with concept weights; same flags as search
|
|
31
|
+
impact <node> Blast radius (grouped by module; --flat / --json)
|
|
32
|
+
affected-tests Tests affected by a change (--file / --from-diff / --json)
|
|
33
|
+
diff-context Change context for a diff (--file / --rev / --worktree / --json)
|
|
34
|
+
hotspots Rank files by recent churn × AST complexity (--json / --sort)
|
|
35
|
+
coupling <file> Temporal co-change partners for a file (--json)
|
|
36
|
+
trace <from> <to> A call path between two nodes
|
|
37
|
+
visualize [node] Interactive HTML graph → .speclaw/graph.html
|
|
38
|
+
|
|
39
|
+
Cortex (One brain. Many agents. — multi-agent loop)
|
|
40
|
+
cortex <op> status|start|advance|rework|brief — drive harness.json (--change)
|
|
41
|
+
|
|
42
|
+
Lawbook (spec-driven workflow)
|
|
43
|
+
quick <name> Scaffold a level-0 change (record.md + reports)
|
|
44
|
+
lawbook init Create the lawbook/ workspace
|
|
45
|
+
lawbook list Active/archived changes and capabilities
|
|
46
|
+
lawbook level <mode> Propose/set/promote/explain ceremony level (--json)
|
|
47
|
+
lawbook draft <name> Scaffold a feature change (--level N, --capability C, --json)
|
|
48
|
+
lawbook draft --bug <c> Scaffold a bug change (bugfix.md + reports)
|
|
49
|
+
lawbook investigate Rank bug suspects from graph (--symptom / --stack-trace, --json)
|
|
50
|
+
lawbook validate <c> Validate a change's artifacts
|
|
51
|
+
lawbook sync <c> Promote delta specs to canonical
|
|
52
|
+
lawbook archive <c> Finalize and archive a change
|
|
53
|
+
lawbook harness <op> Deprecated alias for \`speclaw cortex\` (compat)
|
|
54
|
+
|
|
55
|
+
Other
|
|
56
|
+
doctor Verify the installation (--json, --offline, --strict)
|
|
57
|
+
budget Measure always-on context cost (tools, skills, instructions)
|
|
58
|
+
coverage Requirement → impl → test coverage (--json, --tap, --adopt, --write)
|
|
59
|
+
drift Spec↔code drift (--json, --reseal, --reverse, --fail-on)
|
|
60
|
+
owners Compile team.owners → .github/CODEOWNERS (--write / --check / --diff)
|
|
61
|
+
telemetry status Confirm speclaw ships no telemetry
|
|
62
|
+
check Evaluate an action against the laws (hooks call this; --dry-run to preview)
|
|
63
|
+
laws verify Verify the deterministic dependency/graph laws against the index
|
|
64
|
+
laws compile Compile laws into agent rule dialects (AGENTS / Claude / Cursor / …)
|
|
65
|
+
laws import Import third-party rules as draft laws (--from rulesync)
|
|
66
|
+
laws lock Create/refresh committed speclaw.lock digests for rule files
|
|
67
|
+
(keeps drifted strict digests; --force re-baselines, TTY only)
|
|
68
|
+
laws accept <path> Interactively accept a changed rule-file digest (TTY only)
|
|
69
|
+
laws scan Scan rule/skill files for prompt-injection patterns
|
|
70
|
+
verify Verify laws + integrity for CI: exit codes, --sarif, --json, --strict-engines
|
|
71
|
+
mcp Start the MCP server (used by your agent's config)
|
|
72
|
+
help Show this help
|
|
73
|
+
--version Print the installed speclaw version
|
|
74
|
+
`;
|
|
75
|
+
const SEARCH_FLAGS = `Options
|
|
76
|
+
--focus <files> Comma-separated files to boost (files you are editing)
|
|
77
|
+
--max-tokens <n> Token budget for the returned context
|
|
78
|
+
--explain Show how each result was scored
|
|
79
|
+
--json Print the result as JSON
|
|
80
|
+
`;
|
|
81
|
+
/** Usage text for `speclaw index --help`. */
|
|
82
|
+
const INDEX_USAGE = `Usage: speclaw index [options]
|
|
83
|
+
|
|
84
|
+
(Re)build the local Compass code graph for the current directory. Runs are
|
|
85
|
+
incremental: unchanged files are skipped, and an unchanged project skips the
|
|
86
|
+
global post-processing.
|
|
87
|
+
|
|
88
|
+
Options
|
|
89
|
+
--force Re-extract every file
|
|
90
|
+
--prune Also evict embedding-cache rows unused for --retention days
|
|
91
|
+
--retention <days> Retention window for --prune (default 30)
|
|
92
|
+
--max-cache-mb <mb> Embedding-cache size cap (default 256)
|
|
93
|
+
--json Print the index statistics as JSON
|
|
94
|
+
`;
|
|
95
|
+
// Covers: req~per-command-help~1
|
|
96
|
+
/**
|
|
97
|
+
* Every command the CLI dispatches, with its usage text. The dispatcher in
|
|
98
|
+
* `src/cli/index.ts` rejects any command missing from this list, so a new
|
|
99
|
+
* command cannot ship without `--help` output.
|
|
100
|
+
*/
|
|
101
|
+
export const COMMANDS = [
|
|
102
|
+
{ name: "help", aliases: ["--help", "-h"], usage: GLOBAL_HELP },
|
|
103
|
+
{
|
|
104
|
+
name: "version",
|
|
105
|
+
aliases: ["--version", "-v"],
|
|
106
|
+
usage: `Usage: speclaw version (also --version, -v)
|
|
107
|
+
|
|
108
|
+
Print the installed speclaw version as a bare string.
|
|
109
|
+
`,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "mcp",
|
|
113
|
+
usage: `Usage: speclaw mcp
|
|
114
|
+
|
|
115
|
+
Start the speclaw MCP server over stdio. Your agent's MCP config launches it;
|
|
116
|
+
you rarely run it by hand.
|
|
117
|
+
`,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "init",
|
|
121
|
+
usage: `Usage: speclaw init [options]
|
|
122
|
+
|
|
123
|
+
Interactive setup: pick agents, scaffold the constitution and lawbook, build the
|
|
124
|
+
Compass index, and print the starting prompt. Prefer
|
|
125
|
+
npx @esneiderbravo/speclaw@latest init so the scaffold matches the latest release.
|
|
126
|
+
|
|
127
|
+
Options
|
|
128
|
+
--yes, -y Accept the defaults without prompting
|
|
129
|
+
--agents <ids> Comma-separated agents to configure (claude, cursor, …)
|
|
130
|
+
--packs <ids> Comma-separated tool packs to install
|
|
131
|
+
--project-name <name> Project name for the templates
|
|
132
|
+
--minimal Omit setup/lifecycle MCP tools
|
|
133
|
+
--no-index Skip the initial Compass index
|
|
134
|
+
`,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "update",
|
|
138
|
+
usage: `Usage: speclaw update [options]
|
|
139
|
+
|
|
140
|
+
Bring this project up to date. When npm reports a newer speclaw during this run,
|
|
141
|
+
update re-runs itself as npx -y @esneiderbravo/speclaw@<latest> update with the
|
|
142
|
+
same flags and exits with its code; otherwise it applies the project migrations
|
|
143
|
+
with the running binary. Opt out with --no-self-update or SPECLAW_NO_SELF_UPDATE=1.
|
|
144
|
+
|
|
145
|
+
Options
|
|
146
|
+
--check Report the version status only (no re-run, no migration)
|
|
147
|
+
--backup Keep a .bak of each locally edited managed file before refreshing
|
|
148
|
+
--minimal Persist minimal MCP exposure
|
|
149
|
+
--no-self-update Never re-run at the latest version; migrate with this binary
|
|
150
|
+
`,
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "agent",
|
|
154
|
+
usage: `Usage: speclaw agent <list|add <id>>
|
|
155
|
+
|
|
156
|
+
list Show which agents are configured
|
|
157
|
+
add <id> Configure another agent (symlinks + MCP entry)
|
|
158
|
+
`,
|
|
159
|
+
},
|
|
160
|
+
{ name: "index", usage: INDEX_USAGE },
|
|
161
|
+
{
|
|
162
|
+
name: "watch",
|
|
163
|
+
usage: `Usage: speclaw watch
|
|
164
|
+
|
|
165
|
+
Keep the Compass index fresh: re-index changed files until interrupted (Ctrl-C).
|
|
166
|
+
`,
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "session-start",
|
|
170
|
+
usage: `Usage: speclaw session-start
|
|
171
|
+
|
|
172
|
+
Silent, fail-safe refresh of an existing Compass index. The SessionStart hook
|
|
173
|
+
runs it; it prints nothing and never fails the session.
|
|
174
|
+
`,
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "explore",
|
|
178
|
+
usage: `Usage: speclaw explore <node> [options]
|
|
179
|
+
|
|
180
|
+
A symbol's source plus its callers and callees.
|
|
181
|
+
|
|
182
|
+
Options
|
|
183
|
+
--json Print the result as JSON
|
|
184
|
+
`,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: "search",
|
|
188
|
+
usage: `Usage: speclaw search <query> [options]
|
|
189
|
+
|
|
190
|
+
Hybrid find over the code graph (BM25 + vectors + name match).
|
|
191
|
+
|
|
192
|
+
${SEARCH_FLAGS}`,
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: "recall",
|
|
196
|
+
usage: `Usage: speclaw recall "<query>" [options]
|
|
197
|
+
|
|
198
|
+
Hybrid find with concept weights (same flags as search).
|
|
199
|
+
|
|
200
|
+
${SEARCH_FLAGS}`,
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "impact",
|
|
204
|
+
usage: `Usage: speclaw impact <node> [options]
|
|
205
|
+
|
|
206
|
+
Blast radius of a symbol, grouped by module.
|
|
207
|
+
|
|
208
|
+
Options
|
|
209
|
+
--flat Flat list instead of module groups
|
|
210
|
+
--depth <n> Maximum traversal depth (default 4)
|
|
211
|
+
--file <paths> Seed from files instead of a symbol
|
|
212
|
+
--json Print the report as JSON
|
|
213
|
+
`,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: "trace",
|
|
217
|
+
usage: `Usage: speclaw trace <from> <to> [options]
|
|
218
|
+
|
|
219
|
+
A call path between two symbols (Compass call-path query, not requirement
|
|
220
|
+
coverage — that is speclaw coverage).
|
|
221
|
+
|
|
222
|
+
Options
|
|
223
|
+
--json Print the path as JSON
|
|
224
|
+
`,
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "affected-tests",
|
|
228
|
+
usage: `Usage: speclaw affected-tests [options]
|
|
229
|
+
|
|
230
|
+
Tests affected by a change, with a runnable command.
|
|
231
|
+
|
|
232
|
+
Options
|
|
233
|
+
--file <paths> Comma-separated changed files
|
|
234
|
+
--from-diff <ref> Seed from git files changed against <ref> (default main)
|
|
235
|
+
--json Print the selection as JSON
|
|
236
|
+
`,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: "diff-context",
|
|
240
|
+
usage: `Usage: speclaw diff-context [options]
|
|
241
|
+
|
|
242
|
+
Graph context of a change: symbols, blast radius, tests, hotspots.
|
|
243
|
+
|
|
244
|
+
Options
|
|
245
|
+
--file <paths> Comma-separated changed files
|
|
246
|
+
--rev <rev> A git revision to describe
|
|
247
|
+
--worktree Use the working tree changes
|
|
248
|
+
--full Full mode instead of brief
|
|
249
|
+
--json Print the context as JSON
|
|
250
|
+
`,
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "hotspots",
|
|
254
|
+
usage: `Usage: speclaw hotspots [options]
|
|
255
|
+
|
|
256
|
+
Rank files by recent churn × AST complexity.
|
|
257
|
+
|
|
258
|
+
Options
|
|
259
|
+
--days <n> History window in days (default 90)
|
|
260
|
+
--since <date> History start date
|
|
261
|
+
--sort <key> Sort key
|
|
262
|
+
--limit <n> Maximum rows
|
|
263
|
+
--json Print the report as JSON
|
|
264
|
+
`,
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "coupling",
|
|
268
|
+
usage: `Usage: speclaw coupling <file> [options]
|
|
269
|
+
|
|
270
|
+
Temporal co-change partners for a file.
|
|
271
|
+
|
|
272
|
+
Options
|
|
273
|
+
--days <n> History window in days (default 90)
|
|
274
|
+
--since <date> History start date
|
|
275
|
+
--min-shared <n> Minimum shared commits
|
|
276
|
+
--max-files <n> Ignore commits touching more files than this
|
|
277
|
+
--limit <n> Maximum rows
|
|
278
|
+
--json Print the report as JSON
|
|
279
|
+
`,
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
name: "visualize",
|
|
283
|
+
usage: `Usage: speclaw visualize [node] [options]
|
|
284
|
+
|
|
285
|
+
Write an interactive HTML graph to .speclaw/graph.html.
|
|
286
|
+
|
|
287
|
+
Options
|
|
288
|
+
--depth <n> Neighborhood depth around <node>
|
|
289
|
+
--limit <n> Maximum nodes
|
|
290
|
+
--no-open Do not open the browser
|
|
291
|
+
`,
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: "quick",
|
|
295
|
+
usage: `Usage: speclaw quick <name> [options]
|
|
296
|
+
|
|
297
|
+
Scaffold a level-0 change (record.md + change.json + reports/).
|
|
298
|
+
|
|
299
|
+
Options
|
|
300
|
+
--path <files> Files the change touches
|
|
301
|
+
--symbol <names> Symbols the change touches
|
|
302
|
+
--json Print the scaffold as JSON
|
|
303
|
+
`,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: "cortex",
|
|
307
|
+
usage: `Usage: speclaw cortex <status|start|advance|rework|brief> [change] [options]
|
|
308
|
+
|
|
309
|
+
Drive a change's Cortex harness (harness.json).
|
|
310
|
+
|
|
311
|
+
Options
|
|
312
|
+
--change <name> The change (or pass it as the second argument)
|
|
313
|
+
--verdict <v> PASS or FAIL (advance from reviewing/testing)
|
|
314
|
+
--note <text> A history note
|
|
315
|
+
--question <text> An open question (repeatable)
|
|
316
|
+
--pause-questions Pause the loop for open questions
|
|
317
|
+
--json Print the result as JSON
|
|
318
|
+
`,
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: "lawbook",
|
|
322
|
+
usage: `Usage: speclaw lawbook <subcommand> [options]
|
|
323
|
+
|
|
324
|
+
init Create the lawbook/ workspace
|
|
325
|
+
list Active/archived changes and capabilities
|
|
326
|
+
level <mode> [change] propose|set|promote|explain ceremony level (--level, --reason)
|
|
327
|
+
draft <name> Scaffold a feature change (--level N, --capability C)
|
|
328
|
+
draft --bug <name> Scaffold a bug change (bugfix.md + reports)
|
|
329
|
+
investigate Rank bug suspects (--symptom, --stack-trace, --symbol, --path)
|
|
330
|
+
validate <change> Validate a change's artifacts
|
|
331
|
+
sync <change> Promote delta specs to canonical
|
|
332
|
+
archive <change> Finalize and archive a change
|
|
333
|
+
harness <op> Deprecated alias for speclaw cortex
|
|
334
|
+
|
|
335
|
+
Options
|
|
336
|
+
--json Print the result as JSON
|
|
337
|
+
`,
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
name: "doctor",
|
|
341
|
+
usage: `Usage: speclaw doctor [options]
|
|
342
|
+
|
|
343
|
+
Verify the installation and report structured diagnostics.
|
|
344
|
+
|
|
345
|
+
Options
|
|
346
|
+
--json Print the versioned DoctorReport
|
|
347
|
+
--offline Skip network checks
|
|
348
|
+
--strict Exit non-zero on warnings
|
|
349
|
+
--redact Redact paths and secrets (default)
|
|
350
|
+
--no-redact Do not redact
|
|
351
|
+
`,
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: "budget",
|
|
355
|
+
usage: `Usage: speclaw budget [options]
|
|
356
|
+
|
|
357
|
+
Measure always-on context cost (tools, skills, instructions).
|
|
358
|
+
|
|
359
|
+
Options
|
|
360
|
+
--minimal Measure the minimal MCP profile
|
|
361
|
+
--json Print the measurement as JSON
|
|
362
|
+
`,
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
name: "coverage",
|
|
366
|
+
usage: `Usage: speclaw coverage [options]
|
|
367
|
+
|
|
368
|
+
Requirement → impl → test coverage.
|
|
369
|
+
|
|
370
|
+
Options
|
|
371
|
+
--change <name> Include a change's delta specs
|
|
372
|
+
--json Print the versioned coverage report
|
|
373
|
+
--tap Print TAP
|
|
374
|
+
--adopt Propose requirement ids for unidentified requirements
|
|
375
|
+
--write With --adopt, write the ids
|
|
376
|
+
`,
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
name: "drift",
|
|
380
|
+
usage: `Usage: speclaw drift [options]
|
|
381
|
+
|
|
382
|
+
Sealed spec↔code drift.
|
|
383
|
+
|
|
384
|
+
Options
|
|
385
|
+
--capability <name> Limit to one capability
|
|
386
|
+
--fail-on <level> Exit non-zero at this level (default semantic)
|
|
387
|
+
--reverse Report code without spec anchors
|
|
388
|
+
--reseal Photograph current bodies into the anchors
|
|
389
|
+
--explain Explain each finding
|
|
390
|
+
--json Print the versioned drift report
|
|
391
|
+
`,
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
name: "telemetry",
|
|
395
|
+
usage: `Usage: speclaw telemetry status
|
|
396
|
+
|
|
397
|
+
Confirm speclaw ships no telemetry.
|
|
398
|
+
`,
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
name: "owners",
|
|
402
|
+
usage: `Usage: speclaw owners [options]
|
|
403
|
+
|
|
404
|
+
Compile team.owners from lawbook/config.yaml into .github/CODEOWNERS.
|
|
405
|
+
|
|
406
|
+
Options
|
|
407
|
+
--write Write the managed block
|
|
408
|
+
--check Exit non-zero when the block is stale
|
|
409
|
+
--diff Show the pending change
|
|
410
|
+
`,
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
name: "check",
|
|
414
|
+
usage: `Usage: speclaw check [options]
|
|
415
|
+
|
|
416
|
+
Evaluate an action against the laws (agent hooks call this).
|
|
417
|
+
|
|
418
|
+
Options
|
|
419
|
+
--hook-payload <f> Read the hook payload from a file (- for stdin)
|
|
420
|
+
--event <name> The hook event
|
|
421
|
+
--path <file> The file the action touches
|
|
422
|
+
--dry-run Preview the decision without enforcing it
|
|
423
|
+
`,
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
name: "laws",
|
|
427
|
+
usage: `Usage: speclaw laws <subcommand> [options]
|
|
428
|
+
|
|
429
|
+
verify Verify the dependency/graph laws (--engine, --law, --json)
|
|
430
|
+
compile Compile laws into agent rule dialects (--agent)
|
|
431
|
+
import --from <src> Import third-party rules as draft laws (rulesync)
|
|
432
|
+
lock [--force] Create/refresh speclaw.lock. A strict file that drifted from
|
|
433
|
+
the lock keeps its locked digest (run laws accept <path>);
|
|
434
|
+
--force lists the drifted files and, once confirmed,
|
|
435
|
+
re-baselines them (interactive TTY only; --note)
|
|
436
|
+
accept <path> Accept a changed rule-file digest (interactive TTY only; --note)
|
|
437
|
+
scan Scan rule/skill files for prompt-injection patterns
|
|
438
|
+
`,
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
name: "verify",
|
|
442
|
+
usage: `Usage: speclaw verify [options]
|
|
443
|
+
|
|
444
|
+
Verify laws and rule-file integrity for CI.
|
|
445
|
+
|
|
446
|
+
Options
|
|
447
|
+
--ci CI mode
|
|
448
|
+
--engine <e> deps, graph (comma-separated)
|
|
449
|
+
--law <id> Limit to one law
|
|
450
|
+
--fail-on <level> Exit non-zero at this severity
|
|
451
|
+
--format <f> Output format
|
|
452
|
+
--sarif <file> Write SARIF
|
|
453
|
+
--json [file] Print or write the JSON report
|
|
454
|
+
--strict-engines Exit non-zero when an engine cannot run
|
|
455
|
+
`,
|
|
456
|
+
},
|
|
457
|
+
];
|
|
458
|
+
const BY_NAME = new Map();
|
|
459
|
+
for (const cmd of COMMANDS) {
|
|
460
|
+
BY_NAME.set(cmd.name, cmd);
|
|
461
|
+
for (const alias of cmd.aliases ?? [])
|
|
462
|
+
BY_NAME.set(alias, cmd);
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Every argv spelling the dispatcher accepts: command names plus aliases.
|
|
466
|
+
*
|
|
467
|
+
* @returns The set of known command tokens.
|
|
468
|
+
*/
|
|
469
|
+
export function knownCommands() {
|
|
470
|
+
return new Set(BY_NAME.keys());
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* The usage text for a command or alias.
|
|
474
|
+
*
|
|
475
|
+
* @param cmd - The command token as typed after `speclaw`.
|
|
476
|
+
* @returns The usage text, or `null` for an unknown command.
|
|
477
|
+
*/
|
|
478
|
+
export function helpFor(cmd) {
|
|
479
|
+
return BY_NAME.get(cmd)?.usage ?? null;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Whether a command's arguments ask for help.
|
|
483
|
+
*
|
|
484
|
+
* @param args - The arguments after the command name.
|
|
485
|
+
* @returns True when any argument is `--help` or `-h`.
|
|
486
|
+
*/
|
|
487
|
+
export function wantsHelp(args) {
|
|
488
|
+
return args.some((a) => a === "--help" || a === "-h");
|
|
489
|
+
}
|