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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-read-map",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Pi extension that adds structural file maps for large files",
5
5
  "type": "module",
6
6
  "pi": {
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("warning", "Ctrl+O to expand");
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
@@ -1,7 +0,0 @@
1
- {
2
- "threshold": 15,
3
- "minTokens": 50,
4
- "minLines": 5,
5
- "reporters": ["console"],
6
- "ignore": ["**/fixtures/**", "**/node_modules/**"]
7
- }
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
- }
Binary file