@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,196 @@
1
+ # HashPilot as an MCP server
2
+
3
+ HashPilot speaks the [Model Context Protocol](https://modelcontextprotocol.io) over
4
+ stdio. Point any MCP host at `hashpilot mcp --stdio` and every editing tier —
5
+ AST, hash-anchored, and diff — shows up as a typed tool, with the same advisory
6
+ locking, provenance, and snapshot/undo guarantees the CLI gets.
7
+
8
+ MCP is now the recommended integration path. The CLI remains fully supported and
9
+ is the fallback for hosts without MCP support, and for shell and CI use.
10
+
11
+ ## Why MCP over the CLI
12
+
13
+ | | MCP | CLI |
14
+ |---|---|---|
15
+ | Multi-line content with quotes and backticks | Rides inside JSON; no escaping | Needs `@file` indirection to dodge the shell |
16
+ | Tool discovery | The host lists tools and schemas to the model | The model must be told the commands |
17
+ | Errors | Structured, with `code` and `recovery` the model can act on | Same envelope, but parsed out of stdout |
18
+ | Availability | Requires an MCP-capable host | Anywhere with a shell |
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npm install -g hashpilot # or: bun add -g hashpilot
24
+ hashpilot doctor # confirm the install is healthy
25
+ ```
26
+
27
+ ## Configure your host
28
+
29
+ ### Claude Code
30
+
31
+ ```bash
32
+ claude mcp add hashpilot -- hashpilot mcp --stdio
33
+ ```
34
+
35
+ Or add it to `~/.claude.json` by hand:
36
+
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "hashpilot": {
41
+ "command": "hashpilot",
42
+ "args": ["mcp", "--stdio"]
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ ### Claude Desktop
49
+
50
+ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS
51
+ (`%APPDATA%\Claude\claude_desktop_config.json` on Windows):
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "hashpilot": {
57
+ "command": "hashpilot",
58
+ "args": ["mcp", "--stdio"]
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ Restart Claude Desktop afterwards; it reads the config only at launch.
65
+
66
+ ### Cursor
67
+
68
+ `.cursor/mcp.json` in the project, or `~/.cursor/mcp.json` globally:
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "hashpilot": {
74
+ "command": "hashpilot",
75
+ "args": ["mcp", "--stdio"]
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ ### Zed, Continue, and other hosts
82
+
83
+ Any host that launches a stdio MCP server takes the same three fields — command
84
+ `hashpilot`, args `["mcp", "--stdio"]`, and no environment beyond your shell's.
85
+ If your host wants an absolute path, use `which hashpilot`.
86
+
87
+ ### Running from a checkout
88
+
89
+ Without a global install, point the host at the repo:
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "hashpilot": {
95
+ "command": "bun",
96
+ "args": ["run", "/absolute/path/to/HashPilot/src/cli.ts", "mcp", "--stdio"]
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ ## Tools
103
+
104
+ Every tool is generated from the operation registry in
105
+ [`src/core/operations.ts`](../src/core/operations.ts), which is the same list the
106
+ CLI surface is verified against — the two cannot drift.
107
+
108
+ ### Reading
109
+
110
+ | Tool | Use it for |
111
+ |---|---|
112
+ | `read_many` | Whole files plus a content hash per file. The hash is the anchor a later `replace_hash` verifies against. |
113
+ | `read_hash` | One line with context and its hash, when you already know the line. |
114
+ | `grep_many` | Regex search across paths. The cheapest way to locate code. |
115
+ | `symbol_lookup_many` | Where symbols are *defined* (not referenced). |
116
+ | `find_symbols` | Every symbol declared in one file. |
117
+ | `ast_capabilities` | Which languages and AST operations are supported. |
118
+
119
+ ### Editing
120
+
121
+ | Tool | Tier | Use it for |
122
+ |---|---|---|
123
+ | `rename_symbol` | AST | Binding-aware, file-scoped rename. |
124
+ | `replace_body` | AST | Swap a function body, keep the signature. |
125
+ | `add_import` / `remove_import` | AST | Imports, in the language's own style. |
126
+ | `insert_before` / `insert_after` | AST | Code anchored to a symbol, not a line number. |
127
+ | `replace_hash` | Hash | Verified replacement — refuses if the file changed since you read it. |
128
+ | `replace_content` | Diff | Exact-match fallback; refuses on an ambiguous match. |
129
+ | `route_edit` | auto | Any operation, letting HashPilot pick the strongest tier available. |
130
+
131
+ ### Verification
132
+
133
+ `verify_changes` runs the project's own formatter, linter, type checker, and
134
+ tests, scoped to the files you edited. Pass `useBaseline: true` so tests that
135
+ were already failing do not get blamed on your edit.
136
+
137
+ Every mutating tool accepts `dryRun`, plus `actor`, `taskId`, and `reason` for
138
+ provenance — the same fields the CLI records, queryable afterwards with
139
+ `hashpilot provenance query <file>`.
140
+
141
+ ## Error handling
142
+
143
+ A failed edit comes back as a normal MCP result with `isError: true`, not as a
144
+ JSON-RPC error. Protocol errors are the host's problem; tool errors are yours to
145
+ read and recover from. The payload is the standard envelope:
146
+
147
+ ```json
148
+ {
149
+ "apiVersion": "1",
150
+ "ok": false,
151
+ "command": "replace_hash",
152
+ "data": null,
153
+ "error": {
154
+ "code": "STALE_ANCHOR",
155
+ "message": "the file changed since the hash was taken",
156
+ "recovery": "Re-read the file and retry with the new hash."
157
+ },
158
+ "warnings": []
159
+ }
160
+ ```
161
+
162
+ Act on `error.code`; `error.recovery` says what to do next. The codes are the
163
+ same ones the CLI reports — see [ADAPTER-CONTRACT.md](ADAPTER-CONTRACT.md).
164
+
165
+ Every tool response — success or failure — carries all five envelope fields,
166
+ byte-for-byte the shape the CLI writes: `command` names the tool that answered,
167
+ `data` and `error` are both present with one of them `null`, and `warnings`
168
+ reports route fallbacks and relocated hash anchors. That last one is the reason
169
+ this matters: an AST edit that quietly became a diff edit is otherwise
170
+ indistinguishable from one that stayed on the AST tier ([#104](../../issues/104)).
171
+
172
+ ## Write boundary
173
+
174
+ The MCP server enforces exactly the same boundary as the CLI: writes are
175
+ confined to the project root, and credentials, shell config, and system paths
176
+ are refused unconditionally. A tool call cannot widen it. Widen the project's
177
+ own `allowedRoots` in `.hashpilot.json` if you legitimately need more.
178
+
179
+ ## Troubleshooting
180
+
181
+ **The host shows no tools.** Check the binary runs: `hashpilot mcp --stdio`
182
+ should sit waiting on stdin rather than exiting. `hashpilot doctor` diagnoses a
183
+ broken install.
184
+
185
+ **Edits fail with `PATH_DENIED`.** The target is outside the project root. Start
186
+ the host from the project directory, or add the location to `allowedRoots`.
187
+
188
+ **AST tools fall back to hash or diff.** tree-sitter is a native module; if the
189
+ bindings did not build, parsers load as `null` and routing degrades silently.
190
+ Reinstall, then check `ast_capabilities`.
191
+
192
+ **Verify a host's view by hand:**
193
+
194
+ ```bash
195
+ printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | hashpilot mcp --stdio
196
+ ```
@@ -0,0 +1,136 @@
1
+ # HashPilot — OpenCode Integration Guide
2
+
3
+ ## Integration Pattern
4
+
5
+ HashPilot integrates with OpenCode as a **skill** (for inline guidance) and a **subagent** (for delegated editing tasks).
6
+
7
+ ## Installed Components
8
+
9
+ ### Skill: `~/.config/opencode/skills/hashpilot/SKILL.md`
10
+
11
+ Provides instructions that OpenCode's AI can reference when deciding how to edit files. The skill triggers when:
12
+ - The user asks to edit files precisely
13
+ - Hash-anchored edits are appropriate
14
+ - TypeScript/TSX symbol-level edits are needed
15
+
16
+ ### Agent: `~/.config/opencode/agent/hashpilot.md`
17
+
18
+ A subagent definition with full tool access (bash, write, edit, read, grep, glob) that:
19
+ - Prefers AST commands for TypeScript, TSX, JavaScript, Python, Go, Rust
20
+ - Uses hash-anchored edits for other files
21
+ - Verifies changes after editing
22
+ - Handles stale anchors by re-reading and retrying
23
+
24
+ ## Setup
25
+
26
+ The skill and agent are already installed. If you need to set them up manually:
27
+
28
+ ```bash
29
+ # Skill
30
+ mkdir -p ~/.config/opencode/skills/hashpilot
31
+ cp ~/.agentic-tools/structured-editing/templates/opencode-skill.md ~/.config/opencode/skills/hashpilot/SKILL.md
32
+
33
+ # Agent (already auto-discovered from ~/.config/opencode/agent/)
34
+ # No additional setup needed
35
+ ```
36
+
37
+ ### PATH requirement
38
+
39
+ Ensure `~/.agentic-tools/bin` is in PATH before launching OpenCode:
40
+
41
+ ```bash
42
+ # Add to ~/.bashrc or ~/.zshrc
43
+ export PATH="$HOME/.agentic-tools/bin:$PATH"
44
+ ```
45
+
46
+ ## Usage in OpenCode Sessions
47
+
48
+ ### Inline skill usage
49
+
50
+ When OpenCode detects file editing tasks, it will reference the hashpilot skill and use `hashpilot` commands directly via bash tool:
51
+
52
+ ```bash
53
+ # OpenCode agent using hash-anchored edit
54
+ HASH=$(hashpilot read-many src/config.ts | jq -r '.[0].hash')
55
+ hashpilot replace-hash src/config.ts "$HASH" "new content"
56
+
57
+ # OpenCode agent using AST edit for TypeScript
58
+ hashpilot ast rename-symbol src/api.ts oldFunc newFunc
59
+ ```
60
+
61
+ ### Subagent delegation
62
+
63
+ Use the HashPilot subagent for complex multi-file editing tasks:
64
+
65
+ ```
66
+ /agent hashpilot
67
+
68
+ Rename the function 'processData' to 'transformData' across all files
69
+ in src/ and update the imports accordingly.
70
+ ```
71
+
72
+ The subagent will:
73
+ 1. Find all files containing `processData`
74
+ 2. Use `ast rename-symbol` for .ts files
75
+ 3. Use `replace-hash` for other files
76
+ 4. Run `verify-changes` on all modified files
77
+
78
+ ## When to Use HashPilot vs Raw Editing
79
+
80
+ | Task | Use HashPilot | Use Direct |
81
+ |------|--------------|------------|
82
+ | Edit existing TS/JS/Python/Go/Rust files | ✅ AST commands | ❌ |
83
+ | Edit any file with hash safety | ✅ replace-hash | ❌ |
84
+ | Rename symbols across files | ✅ ast rename-symbol | ❌ |
85
+ | Add/remove imports | ✅ ast add-import / remove-import | ❌ |
86
+ | Replace function body | ✅ ast replace-body | ❌ |
87
+ | Batch read multiple files | ✅ read-many | ❌ |
88
+ | Verify changes (lint+test) | ✅ verify-changes | ❌ |
89
+ | Create new files | ❌ | ✅ write |
90
+ | Delete files/directories | ❌ | ✅ bash rm |
91
+ | Move/rename files | ❌ | ✅ bash mv |
92
+ | Simple one-line edits | optional | ✅ direct edit |
93
+ | Single-file exploration | optional | ✅ direct read |
94
+
95
+ **General rule**: HashPilot for precision edits to existing files; direct tools for creation, deletion, and file system operations.
96
+
97
+ ## Key Advantages Over Raw Editing
98
+
99
+ | Aspect | Raw Edit | HashPilot |
100
+ |--------|----------|-----------|
101
+ | Line counting | Required, error-prone | Hash-anchored, robust |
102
+ | TypeScript edits | Text-based, imprecise | AST-aware, symbol-level |
103
+ | Conflict detection | None | Stale anchor rejection |
104
+ | Verification | Manual | Bundled formatter+linter+tests |
105
+ | Audit trail | None | Telemetry logging |
106
+
107
+ ## Reference: Complete Command List
108
+
109
+ ```
110
+ hashpilot read-many <files...>
111
+ hashpilot read-hash <file> <line> [-c <context>]
112
+ hashpilot grep-many <pattern> <paths...>
113
+ hashpilot symbol-lookup-many <paths...> --names n1,n2
114
+ hashpilot replace-hash <file> <hash> <content> [--range s:e] [--dry-run] [--actor] [--task-id] [--reason]
115
+ hashpilot ast find-symbols <file>
116
+ hashpilot ast capabilities
117
+ hashpilot ast rename-symbol <file> <old> <new> [--actor] [--task-id] [--reason]
118
+ hashpilot ast replace-body <file> <symbol> <body> [--actor] [--task-id] [--reason]
119
+ hashpilot ast add-import <file> '<spec>' [--actor] [--task-id] [--reason]
120
+ hashpilot ast remove-import <file> '<spec>' [--actor] [--task-id] [--reason]
121
+ hashpilot ast insert-before <file> <symbol> <content> [--actor] [--task-id] [--reason]
122
+ hashpilot ast insert-after <file> <symbol> <content> [--actor] [--task-id] [--reason]
123
+ hashpilot diff generate <file> <old> <new>
124
+ hashpilot diff apply <file> --patch <file> [--dry-run]
125
+ hashpilot route <file> <op> [--policy <json>]
126
+ hashpilot route-edit <file> <op> [--method <route>] [--dry-run]
127
+ hashpilot batch <op> <files...> [--serial] [--dry-run]
128
+ hashpilot intent '<json>' [--project-root <dir>] [--dry-run]
129
+ hashpilot config
130
+ hashpilot doctor
131
+ hashpilot verify-changes <files...> [--formatter] [--linter] [--typecheck] [--test-filter] [--auto-detect]
132
+ hashpilot provenance query <file> [<line>] [--human]
133
+ hashpilot provenance changeset <changeSetId> [--human]
134
+ hashpilot telemetry [show|summary|health|clear|sessions|export|prune]
135
+ hashpilot telemetry health [-w <days>] [--trend]
136
+ ```
@@ -0,0 +1,195 @@
1
+ # HashPilot — Pi Integration Guide
2
+
3
+ ## Two Integration Modes
4
+
5
+ HashPilot integrates with Pi in two ways:
6
+
7
+ 1. **Native Extension** (recommended) — Custom tools registered in Pi's tool system, available in every session
8
+ 2. **CLI Mode** — Direct shell commands via `hashpilot`
9
+
10
+ ## Mode 1: Native Pi Extension (Recommended)
11
+
12
+ The HashPilot Pi extension is installed at `~/.pi/agent/extensions/hashpilot.ts`. It registers 7 custom tools and a `/hp` slash command.
13
+
14
+ ### Registered Tools
15
+
16
+ | Tool | Description |
17
+ |------|-------------|
18
+ | `hashpilot_read` | Batch read files with content hashes |
19
+ | `hashpilot_search` | Grep regex across paths |
20
+ | `hashpilot_read_hash` | Read line with hash anchor and context |
21
+ | `hashpilot_replace_hash` | Hash-anchored content replacement |
22
+ | `hashpilot_ast` | AST operations for supported languages (find-symbols, rename, replace-body, add/remove import, insert) |
23
+ | `hashpilot_verify` | Run formatter + linter + tests on files |
24
+ | `hashpilot_status` | Show routing info and telemetry summary |
25
+
26
+ ### Slash Command
27
+
28
+ `/hp <subcommand>` — Quick access to HashPilot:
29
+ - `/hp route <file> <op>` — Show which edit route would be chosen
30
+ - `/hp telemetry` — Show telemetry summary
31
+
32
+ ### Skill
33
+
34
+ The `hashpilot` skill at `~/.pi/agent/skills/hashpilot/SKILL.md` provides routing instructions and workflow guidance. Use `/skill:hashpilot` to load it.
35
+
36
+ ### How It Works
37
+
38
+ The extension calls `hashpilot` CLI under the hood via `pi.exec()`. Each tool:
39
+ 1. Validates parameters using TypeBox schemas
40
+ 2. Calls the appropriate `hashpilot` command
41
+ 3. Parses JSON output
42
+ 4. Returns structured results to the LLM
43
+
44
+ For `hashpilot_replace_hash`, stale-anchor detection is built in — if the hash is stale, the tool returns a clear error message telling the agent to re-read and retry.
45
+
46
+ ### Enabling/Disabling
47
+
48
+ The `hashpilot_enabled` flag controls whether tools appear in Pi's Available Tools. Default: enabled.
49
+
50
+ ## Mode 2: CLI Direct Usage
51
+
52
+ If the extension isn't loaded, Pi can call `hashpilot` directly via shell:
53
+
54
+ ```bash
55
+ # Read files with hashes
56
+ hashpilot read-many src/main.ts src/worker.ts
57
+
58
+ # Read a line with context
59
+ hashpilot read-hash src/main.ts 42
60
+
61
+ # Hash-anchored replacement
62
+ HASH=$(hashpilot read-many src/config.py | jq -r '.[0].hash')
63
+ hashpilot replace-hash src/config.py "$HASH" "new content"
64
+
65
+ # AST operations (TypeScript, TSX, JavaScript, Python, Go, Rust)
66
+ hashpilot ast find-symbols src/main.ts
67
+ hashpilot ast rename-symbol src/main.ts oldFunc newFunc
68
+ hashpilot ast replace-body src/main.ts myFunc 'return 42;'
69
+ hashpilot ast add-import src/app.ts '{ Router } from express'
70
+ hashpilot ast remove-import src/app.ts './bar'
71
+
72
+ # Generate and apply unified diffs
73
+ hashpilot diff generate src/main.ts "$(cat old.ts)" "$(cat new.ts)"
74
+ hashpilot diff apply src/main.ts --patch changes.patch
75
+
76
+ # Route decisions and config
77
+ hashpilot route src/main.ts rename-symbol
78
+ hashpilot config
79
+
80
+ # Batch edit across files
81
+ hashpilot batch add-import src/*.ts --import-spec "{ z } from zod" --dry-run
82
+
83
+ # Edit provenance
84
+ hashpilot provenance query src/main.ts --human
85
+
86
+ # Verify changes (with auto-detection)
87
+ hashpilot verify-changes src/main.ts --auto-detect
88
+ ```
89
+
90
+ ## Routing Strategy
91
+
92
+ HashPilot uses a strict priority for edit method selection:
93
+
94
+ 1. **AST** — For supported languages (TypeScript, TSX, JavaScript, Python, Go, Rust) with AST-compatible operations (rename, replace-body, add/remove import, insert)
95
+ 2. **Hash** — For hash-anchored content identification (any file type)
96
+ 3. **Diff** — Fallback for unsupported operations
97
+
98
+ Check routing: `hashpilot route <file> <operation> [--policy <json>]`
99
+
100
+ For detailed explanation with policy matches, use `--policy` to test override behavior:
101
+
102
+ ```bash
103
+ hashpilot route src/main.ts rename-symbol
104
+ # → { route: "ast", explanation: { reasons: ["Language 'typescript' supports AST operations"], ... } }
105
+
106
+ hashpilot route src/main.py rename-symbol --policy '{"languageOverrides":{"python":"hash"}}'
107
+ # → { route: "hash", explanation: { policyApplied: true, ... } }
108
+ ```
109
+
110
+ ## Configuration
111
+
112
+ HashPilot supports layered configuration via files and environment variables:
113
+
114
+ | Source | Path | Priority |
115
+ |--------|------|----------|
116
+ | Global config | `~/.config/hashpilot/config.json` | Lowest (applied first) |
117
+ | Project config | `.hashpilot.json` in cwd | Medium |
118
+ | CLI override | `--config <path>` | Higher |
119
+ | Environment | `HASHPILOT_ROUTE_POLICY` env var | Highest |
120
+
121
+ Example project config (`.hashpilot.json`):
122
+
123
+ ```json
124
+ {
125
+ "routePolicy": {
126
+ "languageOverrides": { "python": "hash" },
127
+ "operationOverrides": { "add-import": "diff" }
128
+ }
129
+ }
130
+ ```
131
+
132
+ View current merged config: `hashpilot config`
133
+
134
+ ## Stale Anchor Recovery
135
+
136
+ HashPilot has **auto-recovery** for stale anchors. When the file has changed since the hash was computed, `replace-hash` auto-recovers by applying the edit to the current content and returning `"retries": 1`. This is always safe for full-file replaces.
137
+
138
+ If auto-recovery fails or is disabled:
139
+ 1. Re-read the file: `hashpilot read-many <file>`
140
+ 2. Get the new hash from the response
141
+ 3. Retry `replace-hash` with the updated hash
142
+
143
+ The native `hashpilot_replace_hash` tool surfaces stale-anchor status in its response details (`details.stale`), and the extension handles the result accordingly.
144
+
145
+ ## Telemetry
146
+
147
+ All operations are logged to `~/.agentic-tools/logs/telemetry.jsonl`.
148
+
149
+ ```bash
150
+ hashpilot telemetry summary # Operation counts and timing
151
+ hashpilot telemetry show -n 50 # Last 50 events
152
+ hashpilot telemetry health -w 7 # Health report with per-language stats and warnings
153
+ hashpilot telemetry health -w 7 --trend # Compare to previous window
154
+ hashpilot telemetry sessions # List session-level summaries
155
+ hashpilot telemetry export --from 2026-01-01 # Export events as NDJSON
156
+ hashpilot telemetry prune --older-than 30 # Delete old rotated files
157
+ hashpilot telemetry clear # Clear log
158
+ ```
159
+
160
+ ## When to Use HashPilot Tools vs Raw Commands
161
+
162
+ | Task | Use HashPilot | Use Direct |
163
+ |------|--------------|------------|
164
+ | Edit existing TS/JS/Python/Go/Rust files | ✅ ast commands | ❌ |
165
+ | Edit any file with hash safety | ✅ replace-hash | ❌ |
166
+ | Rename symbols across files | ✅ ast rename-symbol | ❌ |
167
+ | Add/remove imports | ✅ ast add-import / remove-import | ❌ |
168
+ | Replace function body | ✅ ast replace-body | ❌ |
169
+ | Batch read multiple files | ✅ hashpilot_read | ❌ |
170
+ | Verify changes | ✅ hashpilot_verify | ❌ |
171
+ | Create new files | ❌ | ✅ raw write |
172
+ | Delete files/dirs | ❌ | ✅ bash |
173
+ | Move/rename files | ❌ | ✅ bash |
174
+ | Simple one-line edits | optional | ✅ direct edit |
175
+ | Single-file exploration | optional | ✅ direct read |
176
+
177
+ ## Key Benefits
178
+
179
+ 1. **Reduced token usage** — Hash anchoring eliminates line-counting and re-reading
180
+ 2. **Fewer retries** — Stale anchor detection catches conflicts before corruption
181
+ 3. **Structured output** — JSON responses parse easily in agent logic
182
+ 4. **Verification batching** — One command to run all checks
183
+ 5. **Audit trail** — Telemetry logs every operation for debugging
184
+ 6. **Native Pi integration** — Custom tools appear in Pi's tool system with proper schemas and guidelines
185
+
186
+ ## Troubleshooting
187
+
188
+ | Issue | Solution |
189
+ |-------|----------|
190
+ | `hashpilot: command not found` | Add `~/.agentic-tools/bin` to PATH in `~/.bashrc` |
191
+ | `Module not found` errors | Run `bun install` in `~/.agentic-tools/structured-editing/` |
192
+ | Tree-sitter errors | `bun add tree-sitter tree-sitter-typescript` in the structured-editing dir |
193
+ | Pi extension not loading | Check `~/.pi/agent/extensions/hashpilot.ts` exists and has no syntax errors |
194
+ | Tools not appearing | Restart Pi; check `~/.pi/agent/settings.json` doesn't disable extensions |
195
+ | Stale hash errors | Re-read the file with `read-many` or `read-hash` and use the fresh hash |
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@bigknoxy/hashpilot",
3
+ "version": "4.6.3",
4
+ "description": "HashPilot — Global Tool-Agnostic Structured Editing Core for Coding Agents",
5
+ "type": "module",
6
+ "engines": {
7
+ "bun": ">=1.2.0"
8
+ },
9
+ "bin": {
10
+ "hashpilot": "./src/cli-node.cjs"
11
+ },
12
+ "scripts": {
13
+ "test": "bun test",
14
+ "build": "bun build src/cli.ts --outdir dist --target bun",
15
+ "install-cli": "bash scripts/install-cli.sh",
16
+ "semantic-release": "semantic-release",
17
+ "gen:cli-quickref": "bun run scripts/gen-cli-quickref.ts",
18
+ "gen:cli-quickref:check": "bun run scripts/gen-cli-quickref.ts --check",
19
+ "lint:roadmap": "bun run scripts/roadmap-lint.ts",
20
+ "lint:docs": "bun run gen:cli-quickref:check && bun run lint:roadmap",
21
+ "bench": "bun run bench/runner.ts"
22
+ },
23
+ "files": [
24
+ "src/",
25
+ "scripts/",
26
+ "templates/",
27
+ "docs/",
28
+ "LICENSE",
29
+ "package.json",
30
+ "tsconfig.json"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/bigknoxy/HashPilot.git"
35
+ },
36
+ "keywords": [
37
+ "structured-editing",
38
+ "coding-agents",
39
+ "tree-sitter",
40
+ "claude",
41
+ "opencode",
42
+ "pi"
43
+ ],
44
+ "author": "bigknoxy",
45
+ "license": "MIT",
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "bugs": {
50
+ "url": "https://github.com/bigknoxy/HashPilot/issues"
51
+ },
52
+ "homepage": "https://github.com/bigknoxy/HashPilot#readme",
53
+ "dependencies": {
54
+ "chalk": "^6.0.0",
55
+ "commander": "^15.0.0",
56
+ "glob": "^13.0.6",
57
+ "tree-sitter": "^0.25.1",
58
+ "tree-sitter-go": "0.25.0",
59
+ "tree-sitter-javascript": "0.25.0",
60
+ "tree-sitter-python": "^0.25.0",
61
+ "tree-sitter-rust": "^0.24.0",
62
+ "tree-sitter-typescript": "^0.23.2"
63
+ },
64
+ "devDependencies": {
65
+ "@semantic-release/changelog": "^7.0.0",
66
+ "@semantic-release/commit-analyzer": "^13.0.0",
67
+ "@semantic-release/git": "^11.0.1",
68
+ "@semantic-release/github": "^12.0.9",
69
+ "@semantic-release/npm": "^13.1.5",
70
+ "@semantic-release/release-notes-generator": "^14.0.0",
71
+ "@types/bun": "^1.1.0",
72
+ "@types/node": "^26.4.0",
73
+ "conventional-changelog-conventionalcommits": "^10.4.0",
74
+ "fast-check": "^4.9.0",
75
+ "semantic-release": "^25.0.9"
76
+ }
77
+ }
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ # Build the GitHub Pages site into site/.
3
+ #
4
+ # The Pages workflow used to publish the repository root, which served internal
5
+ # planning documents (M5_PLAN.md, M6_AUTOPLAN_REVIEW.md, AUDIT-2026-08.md),
6
+ # workflow files, and the whole source tree under the docs domain (#49). The
7
+ # site is now an explicit allowlist: anything not named here is not published.
8
+ set -euo pipefail
9
+
10
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
11
+ OUT="$ROOT/site"
12
+
13
+ rm -rf "$OUT"
14
+ mkdir -p "$OUT/docs"
15
+
16
+ cp "$ROOT/index.html" "$OUT/index.html"
17
+ cp "$ROOT/README.md" "$OUT/README.md"
18
+ cp "$ROOT/LICENSE" "$OUT/LICENSE"
19
+
20
+ # Docs the landing page links to, or that are written for public consumption.
21
+ PUBLIC_DOCS=(
22
+ ADAPTER-CONTRACT.md
23
+ ARCHITECTURE.md
24
+ CLI-QUICKREF.md
25
+ COMPETITIVE-ANALYSIS.md
26
+ INSTALL.md
27
+ INTEGRATION-CLAUDE.md
28
+ INTEGRATION-MCP.md
29
+ INTEGRATION-OPENCODE.md
30
+ INTEGRATION-PI.md
31
+ )
32
+ for doc in "${PUBLIC_DOCS[@]}"; do
33
+ cp "$ROOT/docs/$doc" "$OUT/docs/$doc"
34
+ done
35
+
36
+ # Jekyll would otherwise skip files and directories beginning with an underscore.
37
+ touch "$OUT/.nojekyll"
38
+
39
+ echo "Built site/ with $(find "$OUT" -type f | wc -l | tr -d ' ') files"