pi-read-map 1.2.0 → 1.2.2
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/CHANGELOG.md +12 -0
- package/README.md +4 -0
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/.codemap/cache.db +0 -0
- package/.husky/pre-commit +0 -1
- package/.jscpd.json +0 -7
- package/AGENTS.md +0 -158
- package/demo.md +0 -108
- package/knip.json +0 -11
- package/src/.codemap/cache.db +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.2.2] - 2026-02-14
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- "Ctrl+O to expand" hint in file map summary uses dim styling instead of warning (yellow) for a less alarming appearance
|
|
10
|
+
|
|
11
|
+
## [1.2.1] - 2026-02-14
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Published tarball reduced from 310 KB to 49 KB by adding `.npmignore` (excluded `.codemap/` caches, compiled Go binary, `.pi/` agent files, tests, and demo assets)
|
|
16
|
+
|
|
5
17
|
## [1.2.0] - 2026-02-14
|
|
6
18
|
|
|
7
19
|
### Added
|
package/README.md
CHANGED
|
@@ -182,6 +182,10 @@ The extension intercepts `read` calls and decides:
|
|
|
182
182
|
- `jq` - JSON mapper
|
|
183
183
|
- `universal-ctags` - Language fallback
|
|
184
184
|
|
|
185
|
+
## Known Issues
|
|
186
|
+
|
|
187
|
+
**Peer dependency warnings during install.** You may see `npm warn ERESOLVE overriding peer dependency` messages about `tree-sitter-cpp`. This is cosmetic — the extension installs and works correctly. The warning occurs because `tree-sitter-cpp@0.23.4` on npm declares `peerDependencies: { "tree-sitter": "^0.21.1" }` while we use `tree-sitter@0.22.4` (required by `tree-sitter-rust`). The fix exists on the tree-sitter-cpp master branch but hasn't been published to npm yet. See [tree-sitter/tree-sitter-cpp#349](https://github.com/tree-sitter/tree-sitter-cpp/issues/349) for tracking.
|
|
188
|
+
|
|
185
189
|
## Acknowledgments
|
|
186
190
|
|
|
187
191
|
This project was inspired by and built upon the foundation of [codemap](https://github.com/kcosr/codemap) by [kcosr](https://github.com/kcosr). Check out the original project for the ideas that made this possible.
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -142,7 +142,7 @@ export default function piReadMapExtension(pi: ExtensionAPI): void {
|
|
|
142
142
|
summary += theme.fg("muted", ` │ `);
|
|
143
143
|
summary += theme.fg("dim", detailLanguage);
|
|
144
144
|
summary += theme.fg("muted", ` │ `);
|
|
145
|
-
summary += theme.fg("
|
|
145
|
+
summary += theme.fg("dim", "Ctrl+O to expand");
|
|
146
146
|
|
|
147
147
|
return new Text(summary, 0, 0);
|
|
148
148
|
}
|
package/.codemap/cache.db
DELETED
|
Binary file
|
package/.husky/pre-commit
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm run validate && npm run test -- --exclude='**/e2e/**'
|
package/.jscpd.json
DELETED
package/AGENTS.md
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
> Last updated: 2026-02-14
|
|
4
|
-
|
|
5
|
-
Pi extension that augments the built-in `read` tool with structural file maps for large files (>2,000 lines or >50 KB). Intercepts `read` calls, generates symbol maps via language-specific parsers, and sends them as separate `file-map` messages after the tool result.
|
|
6
|
-
|
|
7
|
-
## Commands (verified 2026-02-14)
|
|
8
|
-
|
|
9
|
-
| Command | Purpose | ~Time |
|
|
10
|
-
|---------|---------|-------|
|
|
11
|
-
| `npm run test` | Unit + integration tests (vitest) | ~2s |
|
|
12
|
-
| `npm run test:integration` | Integration tests only | ~1s |
|
|
13
|
-
| `npm run test:e2e` | E2E tests (requires pi + tmux) | ~60s |
|
|
14
|
-
| `npm run bench` | Benchmarks | ~5s |
|
|
15
|
-
| `npm run typecheck` | `tsc --noEmit` | ~2s |
|
|
16
|
-
| `npm run lint` | oxlint (via npx) | ~1s |
|
|
17
|
-
| `npm run lint:fix` | Auto-fix lint issues | ~1s |
|
|
18
|
-
| `npm run format` | Format with oxfmt | ~1s |
|
|
19
|
-
| `npm run format:check` | Check formatting | ~1s |
|
|
20
|
-
| `npm run validate` | typecheck + lint + format:check | ~4s |
|
|
21
|
-
|
|
22
|
-
## File Map
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
src/
|
|
26
|
-
├── index.ts → Extension entry: tool registration, caching, message rendering
|
|
27
|
-
├── mapper.ts → Dispatcher: routes files to language mappers, fallback chain
|
|
28
|
-
├── formatter.ts → Budget-aware formatting with progressive detail reduction
|
|
29
|
-
├── language-detect.ts → File extension → language mapping
|
|
30
|
-
├── types.ts → FileMap, FileSymbol, MapOptions, FileMapMessageDetails
|
|
31
|
-
├── enums.ts → SymbolKind (21 kinds), DetailLevel (5 levels)
|
|
32
|
-
├── constants.ts → THRESHOLDS: lines, bytes, budget tiers
|
|
33
|
-
└── mappers/ → One mapper per language (17 total)
|
|
34
|
-
├── typescript.ts → ts-morph (handles TS + JS)
|
|
35
|
-
├── rust.ts → tree-sitter-rust
|
|
36
|
-
├── cpp.ts → tree-sitter-cpp (C++ and .h files)
|
|
37
|
-
├── clojure.ts → tree-sitter-clojure (.clj, .cljs, .cljc, .edn)
|
|
38
|
-
├── python.ts → subprocess: scripts/python_outline.py
|
|
39
|
-
├── go.ts → subprocess: scripts/go_outline.go
|
|
40
|
-
├── json.ts → subprocess: jq
|
|
41
|
-
├── c.ts → Regex patterns
|
|
42
|
-
├── sql.ts → Regex
|
|
43
|
-
├── markdown.ts → Regex
|
|
44
|
-
├── yaml.ts → Regex
|
|
45
|
-
├── toml.ts → Regex
|
|
46
|
-
├── csv.ts → In-process streaming
|
|
47
|
-
├── jsonl.ts → In-process streaming
|
|
48
|
-
├── ctags.ts → universal-ctags fallback
|
|
49
|
-
└── fallback.ts → Grep-based final fallback
|
|
50
|
-
|
|
51
|
-
scripts/
|
|
52
|
-
├── python_outline.py → Python AST extraction (called by python mapper)
|
|
53
|
-
├── go_outline.go → Go AST extraction (compiled on first use)
|
|
54
|
-
└── go_outline → Compiled Go binary
|
|
55
|
-
|
|
56
|
-
tests/
|
|
57
|
-
├── unit/ → Mapper tests, formatter tests, language detection
|
|
58
|
-
├── integration/ → Dispatch, caching, budget enforcement, map messages
|
|
59
|
-
├── e2e/ → Real pi sessions via tmux (vitest.e2e.config.ts)
|
|
60
|
-
├── fixtures/ → Sample files per language
|
|
61
|
-
├── benchmarks/ → Mapper performance benchmarks
|
|
62
|
-
└── helpers/ → Test utilities (pi-runner, constants, tree-sitter)
|
|
63
|
-
|
|
64
|
-
docs/
|
|
65
|
-
├── plans/ → Implementation plans (phased)
|
|
66
|
-
├── handoffs/ → Session handoff notes
|
|
67
|
-
├── reviews/ → Phase review documents
|
|
68
|
-
└── todo/ → Outstanding work items
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Architecture
|
|
72
|
-
|
|
73
|
-
Dispatch chain: `index.ts` → `mapper.ts` → language mapper → ctags → fallback.
|
|
74
|
-
|
|
75
|
-
Budget enforcement in `formatter.ts` uses progressive detail reduction:
|
|
76
|
-
- 10 KB: full detail (signatures, modifiers)
|
|
77
|
-
- 15 KB: compact (drop signatures)
|
|
78
|
-
- 20 KB: minimal (names + line ranges only)
|
|
79
|
-
- 50 KB: outline (top-level symbols only)
|
|
80
|
-
- 100 KB: truncated (first/last 50 symbols, hard cap)
|
|
81
|
-
|
|
82
|
-
Maps are cached in-memory by `(filePath, mtime)`. Delivered as custom `file-map` messages via `pi.sendMessage()` after the `tool_result` event.
|
|
83
|
-
|
|
84
|
-
## Golden Samples
|
|
85
|
-
|
|
86
|
-
| For | Reference | Key patterns |
|
|
87
|
-
|-----|-----------|--------------|
|
|
88
|
-
| New mapper | `src/mappers/csv.ts` | Simple, clean, regex-free in-process parsing |
|
|
89
|
-
| Complex mapper | `src/mappers/typescript.ts` | ts-morph AST walk, nested symbols, modifiers |
|
|
90
|
-
| Tree-sitter mapper | `src/mappers/clojure.ts` | tree-sitter AST walk, reader conditionals, platform modifiers |
|
|
91
|
-
| Subprocess mapper | `src/mappers/python.ts` | Calls external script, parses JSON output |
|
|
92
|
-
| Unit test | `tests/unit/mappers/csv.test.ts` | Fixture-based, edge cases, null returns |
|
|
93
|
-
| Integration test | `tests/integration/budget-enforcement.test.ts` | Tests progressive detail reduction |
|
|
94
|
-
|
|
95
|
-
## Heuristics
|
|
96
|
-
|
|
97
|
-
| When | Do |
|
|
98
|
-
|------|-----|
|
|
99
|
-
| Adding a new language | Create `src/mappers/<lang>.ts`, add to `MAPPERS` in `mapper.ts`, add extension in `language-detect.ts`, add unit test |
|
|
100
|
-
| Mapper returns too many symbols | Rely on `formatter.ts` budget system, don't filter in mappers |
|
|
101
|
-
| Mapper can't parse a file | Return `null` — the dispatch chain falls through to ctags then fallback |
|
|
102
|
-
| Adding a new SymbolKind | Add to `enums.ts`, update formatter if display differs |
|
|
103
|
-
| Testing mappers | Use fixture files in `tests/fixtures/`, never mock file reads |
|
|
104
|
-
| E2E tests | Require pi installed + tmux; use `tests/helpers/pi-runner.ts` |
|
|
105
|
-
|
|
106
|
-
## Boundaries
|
|
107
|
-
|
|
108
|
-
**Always:**
|
|
109
|
-
- Return `FileMap` or `null` from mappers (never throw)
|
|
110
|
-
- Include `startLine` and `endLine` for every symbol (1-indexed)
|
|
111
|
-
- Run `npm run validate` before committing
|
|
112
|
-
- Use existing `FileSymbol` interface for all symbol data
|
|
113
|
-
|
|
114
|
-
**Ask first:**
|
|
115
|
-
- Changing budget thresholds in `constants.ts`
|
|
116
|
-
- Adding new `DetailLevel` variants
|
|
117
|
-
- Modifying the tool description in `index.ts`
|
|
118
|
-
- Changes to the `tool_result` event handler
|
|
119
|
-
|
|
120
|
-
**Never:**
|
|
121
|
-
- Filter symbols in mappers based on budget (formatter handles this)
|
|
122
|
-
- Add runtime dependencies without discussing (binary size matters for pi extensions)
|
|
123
|
-
- Use `any` types
|
|
124
|
-
- Disable lint rules
|
|
125
|
-
|
|
126
|
-
## Codebase State
|
|
127
|
-
|
|
128
|
-
- `oxlint` installed as devDependency; `npm run lint` exits cleanly (0 errors, 0 warnings)
|
|
129
|
-
- `tree-sitter` pinned to 0.22.4 due to peer dependency conflicts (see `docs/todo/upgrade-tree-sitter-0.26.md`)
|
|
130
|
-
- `tree-sitter-clojure` pinned to commit SHA from `github:ghoseb/tree-sitter-clojure` (third-party fork)
|
|
131
|
-
- Go outline script auto-compiles on first use; compiled binary checked in at `scripts/go_outline`
|
|
132
|
-
- Phase 1-5 of implementation plan complete; remaining TODOs in `docs/todo/`
|
|
133
|
-
|
|
134
|
-
| Docstrings / JSDoc | `FileSymbol.docstring?: string` | First-line summary of doc comments |
|
|
135
|
-
| Exported flag | `FileSymbol.isExported?: boolean` | Whether symbol is part of public API |
|
|
136
|
-
| Required imports | `FileMap.imports: string[]` | Always an array, never undefined |
|
|
137
|
-
|
|
138
|
-
## Terminology
|
|
139
|
-
|
|
140
|
-
| Docstring | First line of a JSDoc / doc comment on a symbol |
|
|
141
|
-
| isExported | Boolean flag: true if symbol is part of the module's public API |
|
|
142
|
-
| Term | Means |
|
|
143
|
-
|------|-------|
|
|
144
|
-
| Map | Structural outline of a file's symbols with line ranges |
|
|
145
|
-
| Mapper | Language-specific parser that produces a `FileMap` |
|
|
146
|
-
| Budget | Maximum byte size for formatted map output |
|
|
147
|
-
| Detail level | How much information each symbol carries (full → truncated) |
|
|
148
|
-
| Fallback chain | mapper → ctags → grep when parsers fail |
|
|
149
|
-
| Pending map | Map waiting to be sent after `tool_result` event fires |
|
|
150
|
-
|
|
151
|
-
## Tech Stack
|
|
152
|
-
|
|
153
|
-
- **Runtime:** Node.js (ES2022 modules)
|
|
154
|
-
- **Language:** TypeScript (strict, `noUncheckedIndexedAccess`)
|
|
155
|
-
- **Testing:** Vitest (unit/integration: 10s timeout, e2e: 60s timeout)
|
|
156
|
-
- **Linting:** oxlint + oxfmt
|
|
157
|
-
- **Parsing:** ts-morph, tree-sitter (rust, cpp, clojure), regex, subprocess (Python/Go/jq)
|
|
158
|
-
- **Framework:** pi extension API (`@mariozechner/pi-coding-agent`)
|
package/demo.md
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# Skipped Read Recovery
|
|
2
|
-
|
|
3
|
-
*2026-02-12T16:06:08Z*
|
|
4
|
-
|
|
5
|
-
When pi-read-map generates a file map for a large file, it sends the map via `pi.sendMessage()`. During streaming, this defaults to `deliverAs: "steer"`, which pushes the message into the agent's steering queue. After each tool execution, the agent loop checks the steering queue — if non-empty, it skips all remaining tool calls with 'Skipped due to queued user message.'
|
|
6
|
-
|
|
7
|
-
This means: if the agent requests 3 parallel reads and the first file triggers a map, the other 2 reads are cancelled.
|
|
8
|
-
|
|
9
|
-
**Skipped Read Recovery** detects these cancelled reads at `turn_end` and sends a `followUp` message instructing the agent to re-issue them.
|
|
10
|
-
|
|
11
|
-
## How It Works
|
|
12
|
-
|
|
13
|
-
1. A `turn_end` event handler inspects all tool results for the turn
|
|
14
|
-
2. It identifies read results containing 'Skipped due to queued user message.'
|
|
15
|
-
3. It extracts the file paths from the assistant message's `toolCall` entries
|
|
16
|
-
4. It sends a `read-recovery` followUp message listing the interrupted paths
|
|
17
|
-
5. The followUp triggers a new turn where the agent re-reads the skipped files
|
|
18
|
-
|
|
19
|
-
## Files Changed
|
|
20
|
-
|
|
21
|
-
| File | Change |
|
|
22
|
-
|------|--------|
|
|
23
|
-
| `src/index.ts` | Added `turn_end` handler and `read-recovery` message renderer |
|
|
24
|
-
| `tests/integration/skipped-read-recovery.test.ts` | 9 new tests covering detection, edge cases, and rendering |
|
|
25
|
-
|
|
26
|
-
## Tests
|
|
27
|
-
|
|
28
|
-
The new test suite covers:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
cd /home/will/projects/pi-read-map && npx vitest run tests/integration/skipped-read-recovery.test.ts 2>&1 | tail -20
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
```output
|
|
35
|
-
|
|
36
|
-
RUN v3.2.4 /home/will/projects/pi-read-map
|
|
37
|
-
|
|
38
|
-
✓ tests/integration/skipped-read-recovery.test.ts (9 tests) 6ms
|
|
39
|
-
|
|
40
|
-
Test Files 1 passed (1)
|
|
41
|
-
Tests 9 passed (9)
|
|
42
|
-
Start at 08:06:28
|
|
43
|
-
Duration 845ms (transform 139ms, setup 0ms, collect 625ms, tests 6ms, environment 0ms, prepare 61ms)
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Full Validation
|
|
48
|
-
|
|
49
|
-
Typecheck, lint, format, and dead-code detection all pass:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
cd /home/will/projects/pi-read-map && npm run validate 2>&1
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
```output
|
|
56
|
-
|
|
57
|
-
> pi-read-map@1.0.0 validate
|
|
58
|
-
> npm run typecheck && npm run lint && npm run format:check && npm run dead-code
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
> pi-read-map@1.0.0 typecheck
|
|
62
|
-
> tsc --noEmit
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
> pi-read-map@1.0.0 lint
|
|
66
|
-
> oxlint -c .oxlintrc.json src tests
|
|
67
|
-
|
|
68
|
-
Found 0 warnings and 0 errors.
|
|
69
|
-
Finished in 214ms on 61 files with 427 rules using 16 threads.
|
|
70
|
-
|
|
71
|
-
> pi-read-map@1.0.0 format:check
|
|
72
|
-
> oxfmt --config .oxfmtrc.jsonc src tests --check
|
|
73
|
-
|
|
74
|
-
Checking formatting...
|
|
75
|
-
|
|
76
|
-
All matched files use the correct format.
|
|
77
|
-
Finished in 556ms on 73 files using 16 threads.
|
|
78
|
-
|
|
79
|
-
> pi-read-map@1.0.0 dead-code
|
|
80
|
-
> knip
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Full Test Suite
|
|
85
|
-
|
|
86
|
-
All 197 tests pass (27 test files), including the 9 new recovery tests:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
cd /home/will/projects/pi-read-map && npm run test 2>&1 | grep -E "(Test Files|Tests|✓ tests/integration)"
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
```output
|
|
93
|
-
✓ tests/integration/mapper-dispatch.test.ts (8 tests) 627ms
|
|
94
|
-
✓ tests/integration/budget-enforcement.test.ts (8 tests) 693ms
|
|
95
|
-
✓ tests/integration/directory-read.test.ts (4 tests) 14ms
|
|
96
|
-
✓ tests/integration/cache-behavior.test.ts (4 tests) 262ms
|
|
97
|
-
✓ tests/integration/skipped-read-recovery.test.ts (9 tests) 7ms
|
|
98
|
-
✓ tests/integration/separate-map-message.test.ts (6 tests) 9ms
|
|
99
|
-
✓ tests/integration/extension-load.test.ts (6 tests) 6ms
|
|
100
|
-
Test Files 27 passed (27)
|
|
101
|
-
Tests 197 passed (197)
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Implementation Detail
|
|
105
|
-
|
|
106
|
-
The recovery handler in `src/index.ts` narrows the `AgentMessage` union to `AssistantMessage` (via `role === "assistant"` check) and then matches skipped `toolCallId`s against the `toolCall` entries in the assistant content to extract file paths. The recovery message is delivered as a `followUp`, which triggers a new agent turn without entering the steering queue.
|
|
107
|
-
|
|
108
|
-
A custom `read-recovery` message renderer shows a compact summary in collapsed view (e.g., 'Recovery: 2 interrupted read(s) being re-issued') and the full path list when expanded.
|
package/knip.json
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://unpkg.com/knip@latest/schema.json",
|
|
3
|
-
"entry": ["src/index.ts"],
|
|
4
|
-
"project": ["src/**/*.ts"],
|
|
5
|
-
"ignore": ["scripts/**", "tests/fixtures/**"],
|
|
6
|
-
"ignoreDependencies": [
|
|
7
|
-
"@factory/eslint-plugin",
|
|
8
|
-
"ultracite",
|
|
9
|
-
"@mariozechner/pi-tui"
|
|
10
|
-
]
|
|
11
|
-
}
|
package/src/.codemap/cache.db
DELETED
|
Binary file
|