@bigknoxy/hashpilot 4.6.3

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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +777 -0
  3. package/docs/ADAPTER-CONTRACT.md +1260 -0
  4. package/docs/ARCHITECTURE.md +846 -0
  5. package/docs/CLI-QUICKREF.md +827 -0
  6. package/docs/COMPETITIVE-ANALYSIS.md +307 -0
  7. package/docs/INSTALL.md +403 -0
  8. package/docs/INTEGRATION-CLAUDE.md +126 -0
  9. package/docs/INTEGRATION-MCP.md +196 -0
  10. package/docs/INTEGRATION-OPENCODE.md +136 -0
  11. package/docs/INTEGRATION-PI.md +195 -0
  12. package/package.json +77 -0
  13. package/scripts/build-site.sh +39 -0
  14. package/scripts/doctor.sh +218 -0
  15. package/scripts/gen-cli-quickref.ts +232 -0
  16. package/scripts/install-cli.sh +60 -0
  17. package/scripts/install.sh +466 -0
  18. package/scripts/roadmap-lint.ts +200 -0
  19. package/scripts/uninstall.sh +202 -0
  20. package/src/cli-node.cjs +51 -0
  21. package/src/cli.ts +209 -0
  22. package/src/commands/ast.ts +255 -0
  23. package/src/commands/diff.ts +98 -0
  24. package/src/commands/edit.ts +93 -0
  25. package/src/commands/hash.ts +64 -0
  26. package/src/commands/intent.ts +68 -0
  27. package/src/commands/maintenance.ts +191 -0
  28. package/src/commands/mcp.ts +28 -0
  29. package/src/commands/provenance.ts +111 -0
  30. package/src/commands/read.ts +117 -0
  31. package/src/commands/route.ts +42 -0
  32. package/src/commands/shared.ts +65 -0
  33. package/src/commands/telemetry.ts +126 -0
  34. package/src/commands/verify.ts +61 -0
  35. package/src/core/ast-edit.ts +2357 -0
  36. package/src/core/batch-edit.ts +185 -0
  37. package/src/core/config.ts +189 -0
  38. package/src/core/diff-engine.ts +474 -0
  39. package/src/core/doctor.ts +303 -0
  40. package/src/core/encoding.ts +116 -0
  41. package/src/core/envelope.ts +163 -0
  42. package/src/core/exit-codes.ts +198 -0
  43. package/src/core/format.ts +339 -0
  44. package/src/core/grep.ts +180 -0
  45. package/src/core/hash-edit.ts +416 -0
  46. package/src/core/index.ts +155 -0
  47. package/src/core/intent.ts +584 -0
  48. package/src/core/locking.ts +292 -0
  49. package/src/core/module-system.ts +142 -0
  50. package/src/core/operations.ts +557 -0
  51. package/src/core/output.ts +122 -0
  52. package/src/core/path-normalize.ts +61 -0
  53. package/src/core/paths.ts +326 -0
  54. package/src/core/plan-executor.ts +437 -0
  55. package/src/core/platform.ts +132 -0
  56. package/src/core/provenance.ts +214 -0
  57. package/src/core/read.ts +111 -0
  58. package/src/core/redact.ts +98 -0
  59. package/src/core/resolve-content.ts +12 -0
  60. package/src/core/router.ts +463 -0
  61. package/src/core/snapshot.ts +346 -0
  62. package/src/core/telemetry.ts +838 -0
  63. package/src/core/utils.ts +7 -0
  64. package/src/core/verify-baseline.ts +186 -0
  65. package/src/core/verify-scope.ts +282 -0
  66. package/src/core/verify.ts +753 -0
  67. package/src/mcp/server.ts +325 -0
  68. package/templates/claude-section.md +12 -0
  69. package/templates/opencode-agent.md +106 -0
  70. package/templates/opencode-skill.md +241 -0
  71. package/templates/pi-extension.ts +288 -0
  72. package/templates/pi-skill.md +123 -0
  73. package/tsconfig.json +19 -0
@@ -0,0 +1,827 @@
1
+ # CLI Quick Reference
2
+
3
+ Copy-paste reference for `hashpilot`, aimed at agents driving the CLI without
4
+ prior context. The command tables below are **generated from the CLI's own `--help`**,
5
+ so they cannot drift from what the binary accepts.
6
+
7
+ - Regenerate: `bun run gen:cli-quickref`
8
+ - CI enforces freshness with `bun run gen:cli-quickref:check` (also covered by `bun test`).
9
+ - Output *shapes* and exit codes are asserted by `tests/cli-contract.test.ts` — the
10
+ "Gotchas" section below is executable, not folklore.
11
+
12
+ Related: [`ADAPTER-CONTRACT.md`](ADAPTER-CONTRACT.md) for the machine contract,
13
+ [`ARCHITECTURE.md`](ARCHITECTURE.md) for how the routing tiers fit together.
14
+
15
+ ---
16
+
17
+ ## Gotchas
18
+
19
+ Each of these cost a real agent a wasted round-trip. Every claim has a test in
20
+ `tests/cli-contract.test.ts`.
21
+
22
+ ### Positionals are positional — `grep-many` is the one that also takes flags
23
+
24
+ ```bash
25
+ hashpilot grep-many '<pattern>' <path>... # ✅ positional form
26
+ hashpilot grep-many --pattern x --path src --path lib # ✅ flag form (--path repeatable)
27
+ hashpilot grep-many x --pattern x src # ❌ both forms, exit 1
28
+ hashpilot grep-many --pattern x --paths src # ❌ the flag is --path, exit 1
29
+ ```
30
+
31
+ `symbol-lookup-many` is the exception in the search family: paths are positional but
32
+ names come from `--names n1,n2`.
33
+
34
+ Every other command is positional-only. A wrong flag is no longer a bare Commander
35
+ line on stderr: any parse error — unknown flag, missing positional, unknown
36
+ subcommand — writes the usage envelope to stdout with `INVALID_ARGUMENT`, a
37
+ `recovery` pointing at `--help`, and exit 1, with nothing on stderr (#57).
38
+
39
+ ### `replace-body` takes statements only — no braces, no indentation
40
+
41
+ `replace-body` owns both the braces and the indentation of the body it writes.
42
+ Whatever you pass is placed *inside* the existing braces and indented to the
43
+ symbol. Passing either back produces a file that still parses, so the mistake is
44
+ silent (#108).
45
+
46
+ ```bash
47
+ hashpilot ast replace-body f.ts f 'return a * 2;' # ✅
48
+ hashpilot ast replace-body f.ts f '{ return a * 2; }' # ❌ nested block inside the body
49
+ hashpilot ast replace-body f.ts f ' return a * 2;' # ❌ double-indented
50
+ ```
51
+
52
+ Multi-line bodies are written flush-left, one statement per line; the command
53
+ re-indents every line to the symbol.
54
+
55
+ ### An import spec quotes its module path
56
+
57
+ The module path is a string literal in every supported language, and the spec is
58
+ parsed as source. An unquoted path is `PARSE_ERROR` (#109).
59
+
60
+ ```bash
61
+ hashpilot ast add-import f.ts '{ Foo } from "./bar"' # ✅
62
+ hashpilot ast add-import f.ts '{ Foo } from ./bar' # ❌ PARSE_ERROR
63
+ ```
64
+
65
+ ### A JavaScript import spec is always written in ESM form
66
+
67
+ You pass the same `'{ join } from "path"'` spec whatever the file's module system
68
+ is. For a CommonJS JavaScript file, `add-import` translates it and writes
69
+ `const { join } = require("path");` — passing `require` syntax as the spec is not
70
+ supported. The module system is decided by, in order: a `.cjs`/`.mjs` extension,
71
+ the nearest `package.json` `type` field (absent ⇒ CommonJS, per Node), then a
72
+ content sniff.
73
+
74
+ ```bash
75
+ hashpilot ast add-import mod.cjs '{ join } from "path"' # → const { join } = require("path");
76
+ hashpilot ast add-import mod.mjs '{ join } from "path"' # → import { join } from "path";
77
+ ```
78
+
79
+ A JavaScript file that mixes `require` and `import` with no extension or
80
+ `package.json` to settle it is refused with `MODULE_SYSTEM_MISMATCH` rather than
81
+ guessing — emitting either syntax risks a file that parses but will not load
82
+ (#139). Two specs have no single CommonJS declaration and are also refused:
83
+ a combined default-and-named spec (`'fs, { join } from "path"'` — issue it as two
84
+ calls) and a `type`-only spec. TypeScript and TSX are unaffected: they are always
85
+ emitted in ESM form.
86
+
87
+ ### `read-many` returns a bare top-level array, not an envelope
88
+
89
+ ```jsonc
90
+ [ { "path": "…", "hash": "…", "content": "…" } ] // read-many
91
+ { "pattern": "…", "results": [ … ] } // grep-many
92
+ { "checks": [ … ] } // doctor
93
+ ```
94
+
95
+ Do not assume `.results` or `.success` on every command. The uniform envelope is
96
+ [#18 (B15)](../../issues/18); until it lands, shapes are per-command and the tables
97
+ below plus `ADAPTER-CONTRACT.md` are the source of truth.
98
+
99
+ ### `telemetry show -n 0` means zero, and reads always exit 0
100
+
101
+ A telemetry query reports on *past* operations. Its exit code describes the query,
102
+ not the events: a log full of failures still exits 0. Do not infer health from the
103
+ exit code — read `telemetry health`.
104
+
105
+ `-n 0` returns `[]`. (It used to return the entire log, because `slice(-0)` is
106
+ `slice(0)`.)
107
+
108
+ A read that *cannot complete* is the exception: if the log exists but is
109
+ unreadable, the query exits `5` with `errorCode: "READ_FAILED"` instead of
110
+ returning `[]`. Malformed lines are skipped, counted, and reported on stderr
111
+ (`warning: skipped N malformed telemetry line(s)`) — stdout keeps its shape.
112
+
113
+ ### The telemetry subcommand is `show`, not `recent`
114
+
115
+ `hashpilot telemetry show -n 50`. Siblings: `summary`, `health`, `clear`,
116
+ `sessions`, `export`, `prune`.
117
+
118
+ ### Never read an exit code through a pipe
119
+
120
+ ```bash
121
+ hashpilot doctor | head # $? is head's status — always 0
122
+ hashpilot doctor >/dev/null 2>&1; echo $? # ✅ the real code
123
+ ```
124
+
125
+ This masked a genuine exit-70 during review and made a broken build look green.
126
+
127
+ ### Exit codes are the retry contract
128
+
129
+ | Code | Meaning | What an agent should do |
130
+ |------|---------|-------------------------|
131
+ | 0 | ok | continue |
132
+ | 1 | usage error | fix the command line; do not retry as-is |
133
+ | 2 | edit failed | the edit was refused; re-read and re-plan |
134
+ | 3 | stale anchor / precondition | **re-read the file and retry** — this one is retryable |
135
+ | 4 | verification failed | the edit applied but checks failed |
136
+ | 5 | I/O error | check the path exists and is writable |
137
+ | 70 | internal error | a HashPilot bug — report it |
138
+
139
+ Batch commands return worst-wins across their files.
140
+
141
+ ### `PARSE_ERROR` is not retryable — fix the source
142
+
143
+ Every AST edit refuses a file that does not already parse, and reparses its own output
144
+ before writing. Both refusals surface as `error.code: "PARSE_ERROR"` with exit 2, and the
145
+ message carries `line:column`. Re-reading and retrying will not help; either fix the
146
+ syntax error or pass the global `--allow-parse-errors` (which waives the *pre*-check only —
147
+ an edit that would corrupt a clean file is still discarded).
148
+
149
+ Hash and diff edits get the post-edit check too, whenever a parser exists for the language.
150
+
151
+ ### File size is not a limit (fixed in v3.1)
152
+
153
+ Through v3.0.0 the tree-sitter Node binding rejected `parse(string)` at 32767 characters
154
+ with a bare `Invalid argument`, so AST edits silently demoted to the diff route on any
155
+ large file ([#55](../../issues/55)). Source is now streamed to the parser in chunks; there
156
+ is no size ceiling and no reason to force `--method hash` on a big file.
157
+
158
+ ### `bun install` before anything else
159
+
160
+ tree-sitter is a native module. Without `node_modules/`, the AST test files abort with
161
+ `Cannot find package 'tree-sitter'` while the rest of the suite passes — the failure
162
+ looks unrelated to AST. Green baseline is `bun test` fully passing (515 pass / 0 fail).
163
+
164
+ ---
165
+
166
+ ## Command reference
167
+
168
+ <!-- BEGIN GENERATED: command reference -->
169
+
170
+ _36 commands, generated from `--help`. Do not edit by hand — run `bun run gen:cli-quickref`._
171
+
172
+ ### Global options
173
+
174
+ Accepted before the subcommand, e.g. `hashpilot --allowed-root /srv/app read-many f.ts`.
175
+
176
+ ```
177
+ hashpilot [options] [command]
178
+ ```
179
+
180
+ | Flag | Meaning |
181
+ |------|---------|
182
+ | `-V, --version` | output the version number |
183
+ | `--allow-outside-root` | Permit writes outside the project root (credentials and system paths stay blocked) |
184
+ | `--allowed-root <dir...>` | Additional directory writes may target |
185
+ | `--no-telemetry` | Disable telemetry logging for this invocation |
186
+ | `--allow-parse-errors` | Edit a file that already has syntax errors (the post-edit parse check still applies) |
187
+ | `--format <fmt>` | Output format: json or text (default: json if piped/CI, text if TTY) |
188
+ | `--json` | [deprecated: use --format json] Force JSON output (default: false) |
189
+ | `-q, --quiet` | Suppress the human-readable success line (the JSON envelope is never suppressed) |
190
+ | `-v, --verbose` | Write routing and timing diagnostics to stderr |
191
+ | `--no-color` | Disable ANSI color in text output (also honors NO_COLOR) |
192
+
193
+ ### Command groups
194
+
195
+ | Group | Subcommands |
196
+ |-------|-------------|
197
+ | `ast` | `capabilities`, `find-symbols`, `rename-symbol`, `replace-body`, `add-import`, `remove-import`, `insert-before`, `insert-after` |
198
+ | `diff` | `generate`, `apply` |
199
+ | `telemetry` | `show`, `summary`, `health`, `clear`, `sessions`, `export`, `prune` |
200
+ | `provenance` | `query`, `changeset` |
201
+
202
+ ### Commands
203
+
204
+ #### `read-many`
205
+
206
+ Read multiple files, return content + hashes
207
+
208
+ ```
209
+ hashpilot read-many [options] <files...>
210
+ ```
211
+
212
+ | Positional | Meaning |
213
+ |------------|---------|
214
+ | `files` | File paths |
215
+
216
+ #### `read-hash`
217
+
218
+ Read a line with hash and context
219
+
220
+ ```
221
+ hashpilot read-hash [options] <file> <line>
222
+ ```
223
+
224
+ | Positional | Meaning |
225
+ |------------|---------|
226
+ | `file` | File path |
227
+ | `line` | Line number |
228
+
229
+ | Flag | Meaning |
230
+ |------|---------|
231
+ | `-c, --context <n>` | Context lines (default: "3") |
232
+
233
+ #### `grep-many`
234
+
235
+ Search pattern across multiple paths. Usage: grep-many "safeWrite" src/ (or the flag form: grep-many --pattern "safeWrite" --path src/)
236
+
237
+ ```
238
+ hashpilot grep-many [options] [pattern] [paths...]
239
+ ```
240
+
241
+ | Positional | Meaning |
242
+ |------------|---------|
243
+ | `pattern` | Regex pattern (or use --pattern) |
244
+ | `paths` | Paths to search (or use --path) |
245
+
246
+ | Flag | Meaning |
247
+ |------|---------|
248
+ | `-i, --ignore-case` | Case insensitive |
249
+ | `--pattern <p>` | Regex pattern, flag form of the positional |
250
+ | `--path <dir>` | Path to search, flag form of the positional (repeatable) (default: []) |
251
+ | `--file-pattern <glob>` | File pattern filter |
252
+ | `--max-results <n>` | Max results |
253
+
254
+ #### `symbol-lookup-many`
255
+
256
+ Find symbol definitions. Usage: symbol-lookup-many <paths...> --names n1,n2
257
+
258
+ ```
259
+ hashpilot symbol-lookup-many [options] <paths...>
260
+ ```
261
+
262
+ | Positional | Meaning |
263
+ |------------|---------|
264
+ | `paths` | Paths to search |
265
+
266
+ | Flag | Meaning |
267
+ |------|---------|
268
+ | `--names <names>` | Comma-separated symbol names |
269
+
270
+ #### `replace-hash`
271
+
272
+ Replace content identified by hash anchor
273
+
274
+ ```
275
+ hashpilot replace-hash [options] <file> <old-hash> <new-content>
276
+ ```
277
+
278
+ | Positional | Meaning |
279
+ |------------|---------|
280
+ | `file` | File path |
281
+ | `old-hash` | Hash of content to replace |
282
+ | `new-content` | New content (or @file to read from file) |
283
+
284
+ | Flag | Meaning |
285
+ |------|---------|
286
+ | `--range <start:end>` | Line range (1-indexed). N or N:M |
287
+ | `--no-recover` | Fail immediately on a stale anchor instead of attempting relocation |
288
+ | `--dry-run` | Preview without writing |
289
+ | `--actor <name>` | Agent identity for provenance tracking |
290
+ | `--task-id <id>` | Task/issue reference for provenance |
291
+ | `--reason <text>` | Human-readable reason for the edit |
292
+
293
+ #### `ast capabilities`
294
+
295
+ Show supported AST languages, operations, and limitations
296
+
297
+ ```
298
+ hashpilot ast capabilities [options]
299
+ ```
300
+
301
+ #### `ast find-symbols`
302
+
303
+ List symbols in a file
304
+
305
+ ```
306
+ hashpilot ast find-symbols [options] <file>
307
+ ```
308
+
309
+ | Positional | Meaning |
310
+ |------------|---------|
311
+ | `file` | File path |
312
+
313
+ #### `ast rename-symbol`
314
+
315
+ File-scoped, binding-aware rename of a symbol and its references. Refuses with AMBIGUOUS_SYMBOL when the name binds more than one symbol in the file (a shadowed local, a foreign import, or a duplicate declaration).
316
+
317
+ ```
318
+ hashpilot ast rename-symbol [options] <file> <old-name> <new-name>
319
+ ```
320
+
321
+ | Positional | Meaning |
322
+ |------------|---------|
323
+ | `file` | File path |
324
+ | `old-name` | Current symbol name |
325
+ | `new-name` | New symbol name |
326
+
327
+ | Flag | Meaning |
328
+ |------|---------|
329
+ | `--dry-run` | Preview only |
330
+ | `--include-source` | On a dry run, return the whole post-edit file instead of a diff |
331
+ | `--actor <name>` | Agent identity for provenance tracking |
332
+ | `--task-id <id>` | Task/issue reference for provenance |
333
+ | `--reason <text>` | Human-readable reason for the edit |
334
+
335
+ #### `ast replace-body`
336
+
337
+ Replace function/method body
338
+
339
+ ```
340
+ hashpilot ast replace-body [options] <file> <symbol> <new-body>
341
+ ```
342
+
343
+ | Positional | Meaning |
344
+ |------------|---------|
345
+ | `file` | File path |
346
+ | `symbol` | Symbol name |
347
+ | `new-body` | New body statements only — no braces, no indentation (or @file) |
348
+
349
+ | Flag | Meaning |
350
+ |------|---------|
351
+ | `--dry-run` | Preview only |
352
+ | `--include-source` | On a dry run, return the whole post-edit file instead of a diff |
353
+ | `--actor <name>` | Agent identity for provenance tracking |
354
+ | `--task-id <id>` | Task/issue reference for provenance |
355
+ | `--reason <text>` | Human-readable reason for the edit |
356
+
357
+ #### `ast add-import`
358
+
359
+ Add an import statement
360
+
361
+ ```
362
+ hashpilot ast add-import [options] <file> <import-spec>
363
+ ```
364
+
365
+ | Positional | Meaning |
366
+ |------------|---------|
367
+ | `file` | File path |
368
+ | `import-spec` | Import spec, module path quoted: '{ Foo } from "./bar"' |
369
+
370
+ | Flag | Meaning |
371
+ |------|---------|
372
+ | `--dry-run` | Preview only |
373
+ | `--include-source` | On a dry run, return the whole post-edit file instead of a diff |
374
+ | `--actor <name>` | Agent identity for provenance tracking |
375
+ | `--task-id <id>` | Task/issue reference for provenance |
376
+ | `--reason <text>` | Human-readable reason for the edit |
377
+
378
+ #### `ast remove-import`
379
+
380
+ Remove an import statement
381
+
382
+ ```
383
+ hashpilot ast remove-import [options] <file> <import-spec>
384
+ ```
385
+
386
+ | Positional | Meaning |
387
+ |------------|---------|
388
+ | `file` | File path |
389
+ | `import-spec` | Import spec to remove, e.g. '{ Foo } from "./bar"' or a bare binding name |
390
+
391
+ | Flag | Meaning |
392
+ |------|---------|
393
+ | `--dry-run` | Preview only |
394
+ | `--include-source` | On a dry run, return the whole post-edit file instead of a diff |
395
+ | `--actor <name>` | Agent identity for provenance tracking |
396
+ | `--task-id <id>` | Task/issue reference for provenance |
397
+ | `--reason <text>` | Human-readable reason for the edit |
398
+
399
+ #### `ast insert-before`
400
+
401
+ Insert content before a symbol
402
+
403
+ ```
404
+ hashpilot ast insert-before [options] <file> <symbol> <content>
405
+ ```
406
+
407
+ | Positional | Meaning |
408
+ |------------|---------|
409
+ | `file` | File path |
410
+ | `symbol` | Symbol name |
411
+ | `content` | Content to insert (or @file) |
412
+
413
+ | Flag | Meaning |
414
+ |------|---------|
415
+ | `--dry-run` | Preview only |
416
+ | `--include-source` | On a dry run, return the whole post-edit file instead of a diff |
417
+ | `--actor <name>` | Agent identity for provenance tracking |
418
+ | `--task-id <id>` | Task/issue reference for provenance |
419
+ | `--reason <text>` | Human-readable reason for the edit |
420
+
421
+ #### `ast insert-after`
422
+
423
+ Insert content after a symbol
424
+
425
+ ```
426
+ hashpilot ast insert-after [options] <file> <symbol> <content>
427
+ ```
428
+
429
+ | Positional | Meaning |
430
+ |------------|---------|
431
+ | `file` | File path |
432
+ | `symbol` | Symbol name |
433
+ | `content` | Content to insert (or @file) |
434
+
435
+ | Flag | Meaning |
436
+ |------|---------|
437
+ | `--dry-run` | Preview only |
438
+ | `--include-source` | On a dry run, return the whole post-edit file instead of a diff |
439
+ | `--actor <name>` | Agent identity for provenance tracking |
440
+ | `--task-id <id>` | Task/issue reference for provenance |
441
+ | `--reason <text>` | Human-readable reason for the edit |
442
+
443
+ #### `route-edit`
444
+
445
+ Auto-routed structured edit through AST → Hash → Diff pipeline
446
+
447
+ ```
448
+ hashpilot route-edit [options] <file> <operation>
449
+ ```
450
+
451
+ | Positional | Meaning |
452
+ |------------|---------|
453
+ | `file` | File path |
454
+ | `operation` | Operation (rename-symbol, replace-body, add-import, remove-import, insert-before, insert-after, replace-hash, replace-content) |
455
+
456
+ | Flag | Meaning |
457
+ |------|---------|
458
+ | `--method <route>` | Force a specific route (ast, hash, diff) |
459
+ | `--old-hash <hash>` | Hash for hash-route verification |
460
+ | `--new-content <text>` | New content (or @file) |
461
+ | `--old-content <text>` | Old content for diff-route search-and-replace |
462
+ | `--range <start:end>` | Line range for hash route |
463
+ | `--old-name <name>` | Old symbol name (rename-symbol) |
464
+ | `--new-name <name>` | New symbol name (rename-symbol) |
465
+ | `--symbol <name>` | Symbol name (replace-body, insert-before, insert-after) |
466
+ | `--new-body <text>` | New body statements only — no braces, no indentation (replace-body, or @file) |
467
+ | `--import-spec <spec>` | Import spec, module path quoted: '{ Foo } from "./bar"' |
468
+ | `--content <text>` | Content (insert-before, insert-after, or @file) |
469
+ | `--policy <json>` | Inline RoutePolicy JSON |
470
+ | `--dry-run` | Preview without writing |
471
+ | `--include-source` | On a dry run, return the whole post-edit file instead of a diff |
472
+ | `--actor <name>` | Agent identity for provenance tracking |
473
+ | `--task-id <id>` | Task/issue reference for provenance |
474
+ | `--reason <text>` | Human-readable reason for the edit |
475
+
476
+ #### `batch`
477
+
478
+ Apply the same edit to multiple files in parallel
479
+
480
+ ```
481
+ hashpilot batch [options] <operation> <files...>
482
+ ```
483
+
484
+ | Positional | Meaning |
485
+ |------------|---------|
486
+ | `operation` | Operation (rename-symbol, replace-body, add-import, remove-import, insert-before, insert-after, replace-hash, replace-content) |
487
+ | `files` | Files to edit |
488
+
489
+ | Flag | Meaning |
490
+ |------|---------|
491
+ | `--method <route>` | Force a specific route (ast, hash, diff) |
492
+ | `--old-hash <hash>` | Hash for hash-route verification |
493
+ | `--new-content <text>` | New content (or @file) |
494
+ | `--old-content <text>` | Old content for diff-route search-and-replace |
495
+ | `--range <start:end>` | Line range for hash route |
496
+ | `--old-name <name>` | Old symbol name (rename-symbol) |
497
+ | `--new-name <name>` | New symbol name (rename-symbol) |
498
+ | `--symbol <name>` | Symbol name (replace-body, insert-before, insert-after) |
499
+ | `--new-body <text>` | New body statements only — no braces, no indentation (replace-body, or @file) |
500
+ | `--import-spec <spec>` | Import spec, module path quoted: '{ Foo } from "./bar"' |
501
+ | `--content <text>` | Content (insert-before, insert-after, or @file) |
502
+ | `--policy <json>` | Inline RoutePolicy JSON |
503
+ | `--serial` | Execute sequentially instead of parallel |
504
+ | `--dry-run` | Preview without writing |
505
+ | `--include-source` | On a dry run, return the whole post-edit file instead of a diff |
506
+ | `--actor <name>` | Agent identity for provenance tracking |
507
+ | `--task-id <id>` | Task/issue reference for provenance |
508
+ | `--reason <text>` | Human-readable reason for the edit |
509
+
510
+ #### `intent`
511
+
512
+ Execute an editing intent — one command, full blast radius
513
+
514
+ ```
515
+ hashpilot intent [options] <intent>
516
+ ```
517
+
518
+ | Positional | Meaning |
519
+ |------------|---------|
520
+ | `intent` | Intent as JSON: {"operation":"add-parameter","symbol":"fn","param":{"name":"x"}} |
521
+
522
+ | Flag | Meaning |
523
+ |------|---------|
524
+ | `--project-root <dir>` | Project root directory |
525
+ | `--dry-run` | Preview plan without modifying files |
526
+ | `--yes` | Apply the plan even though part of the intent could not be resolved |
527
+ | `--no-verify` | Skip verification after execution |
528
+ | `--no-revert` | Don't roll back on failure |
529
+ | `--timeout <ms>` | Timeout per operation in ms (default: "30000") |
530
+ | `--actor <name>` | Agent identity for provenance tracking |
531
+ | `--task-id <id>` | Task/issue reference for provenance |
532
+ | `--reason <text>` | Human-readable reason for the edit |
533
+ | `--context <text>` | Agent prompt/context (or @file) |
534
+
535
+ #### `diff generate`
536
+
537
+ Generate a unified diff between old and new content
538
+
539
+ ```
540
+ hashpilot diff generate [options] <file> <old-content> <new-content>
541
+ ```
542
+
543
+ | Positional | Meaning |
544
+ |------------|---------|
545
+ | `file` | File path (for diff header) |
546
+ | `old-content` | Old content (or @file) |
547
+ | `new-content` | New content (or @file) |
548
+
549
+ | Flag | Meaning |
550
+ |------|---------|
551
+ | `-c, --context <n>` | Context lines (default: "3") |
552
+ | `--raw` | Print the diff text alone, without the JSON envelope |
553
+
554
+ #### `diff apply`
555
+
556
+ Apply a unified diff patch to a file
557
+
558
+ ```
559
+ hashpilot diff apply [options] <file>
560
+ ```
561
+
562
+ | Positional | Meaning |
563
+ |------------|---------|
564
+ | `file` | File to patch |
565
+
566
+ | Flag | Meaning |
567
+ |------|---------|
568
+ | `--patch <file>` | Patch file to apply (or '-' for stdin) |
569
+ | `--dry-run` | Preview without writing |
570
+ | `-f, --fuzzy <n>` | Fuzzy match tolerance in lines; 0 = strict (exact offset and content, refuses otherwise) (default: "3") |
571
+ | `--actor <name>` | Agent identity for provenance tracking |
572
+ | `--task-id <id>` | Task/issue reference for provenance |
573
+ | `--reason <text>` | Human-readable reason for the edit |
574
+
575
+ #### `verify-changes`
576
+
577
+ Run formatter, linter, typechecker, and tests on changed files
578
+
579
+ ```
580
+ hashpilot verify-changes [options] <files...>
581
+ ```
582
+
583
+ | Positional | Meaning |
584
+ |------------|---------|
585
+ | `files` | Files to verify |
586
+
587
+ | Flag | Meaning |
588
+ |------|---------|
589
+ | `--formatter <cmd>` | Formatter command |
590
+ | `--linter <cmd>` | Linter command |
591
+ | `--typecheck <cmd>` | Type checker command (e.g. 'tsc --noEmit') |
592
+ | `--test-filter <pattern>` | Test filter pattern |
593
+ | `--test-runner <runner>` | Test runner (bun test, vitest, jest, pytest, go test, cargo test) |
594
+ | `--formatter-args <args...>` | Formatter args |
595
+ | `--linter-args <args...>` | Linter args |
596
+ | `--test-args <args...>` | Test runner args |
597
+ | `--auto-detect` | Auto-detect tools from project config files |
598
+ | `--allow-arbitrary-tool` | Allow binaries outside the allowlist (warns on each use) |
599
+ | `--revert-on-failure` | Restore original file contents if any check fails |
600
+ | `--timeout <ms>` | Per-check timeout in ms (default 30000) |
601
+ | `--no-scope-tests` | Run the whole test suite instead of only tests related to the changed files |
602
+ | `--use-baseline` | Ignore tests that were already failing at this commit (see --record-baseline) |
603
+ | `--record-baseline` | Record which tests currently fail, for later --use-baseline runs. Run this before editing. |
604
+
605
+ #### `telemetry show`
606
+
607
+ Show recent telemetry events
608
+
609
+ ```
610
+ hashpilot telemetry show [options]
611
+ ```
612
+
613
+ | Flag | Meaning |
614
+ |------|---------|
615
+ | `-n, --limit <n>` | Number of events (default: "20") |
616
+
617
+ #### `telemetry summary`
618
+
619
+ Show telemetry summary
620
+
621
+ ```
622
+ hashpilot telemetry summary [options]
623
+ ```
624
+
625
+ #### `telemetry health`
626
+
627
+ Show telemetry health report with per-language stats and threshold warnings
628
+
629
+ ```
630
+ hashpilot telemetry health [options]
631
+ ```
632
+
633
+ | Flag | Meaning |
634
+ |------|---------|
635
+ | `-w, --window <days>` | Time window in days (default: "7") |
636
+ | `-t, --trend` | Compare current window to previous window |
637
+
638
+ #### `telemetry clear`
639
+
640
+ Clear telemetry log
641
+
642
+ ```
643
+ hashpilot telemetry clear [options]
644
+ ```
645
+
646
+ #### `telemetry sessions`
647
+
648
+ List session summaries
649
+
650
+ ```
651
+ hashpilot telemetry sessions [options]
652
+ ```
653
+
654
+ #### `telemetry export`
655
+
656
+ Export telemetry events as NDJSON
657
+
658
+ ```
659
+ hashpilot telemetry export [options]
660
+ ```
661
+
662
+ | Flag | Meaning |
663
+ |------|---------|
664
+ | `--from <date>` | Start date (ISO format) |
665
+ | `--to <date>` | End date (ISO format) |
666
+ | `--session <id>` | Session ID filter |
667
+ | `--ndjson` | Stream one compact event per line instead of the JSON envelope |
668
+
669
+ #### `telemetry prune`
670
+
671
+ Delete old rotated telemetry files
672
+
673
+ ```
674
+ hashpilot telemetry prune [options]
675
+ ```
676
+
677
+ | Flag | Meaning |
678
+ |------|---------|
679
+ | `-d, --older-than <days>` | Days threshold (default: "30") |
680
+
681
+ #### `provenance query`
682
+
683
+ Show edit history for a file (like git blame for agent edits)
684
+
685
+ ```
686
+ hashpilot provenance query [options] <file> [line]
687
+ ```
688
+
689
+ | Positional | Meaning |
690
+ |------------|---------|
691
+ | `file` | File path |
692
+ | `line` | Optional line number to filter by |
693
+
694
+ | Flag | Meaning |
695
+ |------|---------|
696
+ | `--human` | Human-readable output |
697
+ | `--fuzzy` | Include edits without diff data in line-filtered queries |
698
+ | `--limit <n>` | Max entries to show |
699
+
700
+ #### `provenance changeset`
701
+
702
+ Show all edits in a changeSet
703
+
704
+ ```
705
+ hashpilot provenance changeset [options] <changeSetId>
706
+ ```
707
+
708
+ | Positional | Meaning |
709
+ |------------|---------|
710
+ | `changeSetId` | ChangeSet UUID |
711
+
712
+ | Flag | Meaning |
713
+ |------|---------|
714
+ | `--human` | Human-readable output |
715
+
716
+ #### `changesets`
717
+
718
+ List undoable changeSets, newest first
719
+
720
+ ```
721
+ hashpilot changesets [options]
722
+ ```
723
+
724
+ | Flag | Meaning |
725
+ |------|---------|
726
+ | `--limit <n>` | Max changeSets to list (default 20) |
727
+
728
+ #### `undo`
729
+
730
+ Restore every file in a changeSet to its pre-edit contents
731
+
732
+ ```
733
+ hashpilot undo [options] [changeSetId]
734
+ ```
735
+
736
+ | Positional | Meaning |
737
+ |------------|---------|
738
+ | `changeSetId` | ChangeSet to undo; omit with --last |
739
+
740
+ | Flag | Meaning |
741
+ |------|---------|
742
+ | `--last` | Undo the most recent changeSet |
743
+ | `--force` | Restore even files modified since the edit was applied |
744
+ | `--dry-run` | Report what would be restored without touching the disk |
745
+
746
+ #### `mcp`
747
+
748
+ Run HashPilot as an MCP server over stdio
749
+
750
+ ```
751
+ hashpilot mcp [options]
752
+ ```
753
+
754
+ | Flag | Meaning |
755
+ |------|---------|
756
+ | `--stdio` | Speak MCP over stdin/stdout (the only transport, and the default) |
757
+
758
+ #### `doctor`
759
+
760
+ Verify HashPilot installation health
761
+
762
+ ```
763
+ hashpilot doctor [options]
764
+ ```
765
+
766
+ #### `upgrade`
767
+
768
+ Upgrade HashPilot to the latest version from GitHub
769
+
770
+ ```
771
+ hashpilot upgrade [options]
772
+ ```
773
+
774
+ | Flag | Meaning |
775
+ |------|---------|
776
+ | `--channel <channel>` | Release channel (default: main) (default: "main") |
777
+ | `--target <dir>` | Install target directory (default: ~/.agentic-tools) |
778
+ | `--keep-telemetry` | Preserve existing telemetry on upgrade |
779
+ | `--force` | Skip confirmation prompt |
780
+ | `--dry-run` | Show what would be done without executing |
781
+
782
+ #### `uninstall`
783
+
784
+ Remove HashPilot and all its components from the system
785
+
786
+ ```
787
+ hashpilot uninstall [options]
788
+ ```
789
+
790
+ | Flag | Meaning |
791
+ |------|---------|
792
+ | `--keep-config` | Preserve config and telemetry data |
793
+ | `--force` | Skip confirmation prompt (auto-detected when piped) |
794
+ | `--dry-run` | Show what would be removed without deleting anything |
795
+ | `--target <dir>` | Install target directory (default: ~/.agentic-tools) |
796
+
797
+ #### `route`
798
+
799
+ Show which edit route would be chosen (with detailed explanation)
800
+
801
+ ```
802
+ hashpilot route [options] <file> <operation>
803
+ ```
804
+
805
+ | Positional | Meaning |
806
+ |------------|---------|
807
+ | `file` | File path |
808
+ | `operation` | Operation name |
809
+
810
+ | Flag | Meaning |
811
+ |------|---------|
812
+ | `--policy <json>` | Inline policy JSON to test |
813
+ | `--no-default-config` | Ignore config file policies |
814
+
815
+ #### `config`
816
+
817
+ Show current HashPilot configuration
818
+
819
+ ```
820
+ hashpilot config [options]
821
+ ```
822
+
823
+ | Flag | Meaning |
824
+ |------|---------|
825
+ | `--config <path>` | Config file path override |
826
+
827
+ <!-- END GENERATED: command reference -->