@mrclrchtr/supi-code-intelligence 0.2.0 → 1.1.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 (29) hide show
  1. package/README.md +31 -187
  2. package/node_modules/@mrclrchtr/supi-core/package.json +8 -4
  3. package/node_modules/@mrclrchtr/supi-lsp/README.md +40 -86
  4. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +8 -4
  5. package/node_modules/@mrclrchtr/supi-lsp/package.json +15 -5
  6. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/stale-diagnostics.ts +1 -1
  7. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +11 -0
  8. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-stale-resync.ts +47 -0
  9. package/node_modules/@mrclrchtr/supi-lsp/src/settings-registration.ts +1 -1
  10. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +38 -70
  11. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +20 -29
  12. package/node_modules/@mrclrchtr/supi-tree-sitter/src/runtime.ts +9 -0
  13. package/package.json +14 -8
  14. package/src/actions/affected-action.ts +153 -24
  15. package/src/actions/callees-action.ts +17 -0
  16. package/src/actions/callers-action.ts +178 -111
  17. package/src/actions/implementations-action.ts +18 -0
  18. package/src/actions/pattern-action.ts +167 -7
  19. package/src/brief-focused.ts +189 -9
  20. package/src/code-intelligence.ts +10 -2
  21. package/src/git-context.ts +11 -0
  22. package/src/guidance.ts +11 -8
  23. package/src/pattern-structured.ts +196 -0
  24. package/src/prioritization-signals.ts +188 -0
  25. package/src/resolve-target.ts +11 -3
  26. package/src/semantic-action-helpers.ts +28 -0
  27. package/src/target-resolution.ts +215 -0
  28. package/src/tool-actions.ts +8 -0
  29. package/src/types.ts +4 -0
package/README.md CHANGED
@@ -1,212 +1,56 @@
1
1
  # @mrclrchtr/supi-code-intelligence
2
2
 
3
- SuPi Code Intelligence extensionthe main agent-facing code understanding tool for [pi](https://github.com/earendil-works/pi).
3
+ Project understanding for PIyour agent knows your codebase before you ask.
4
4
 
5
- Registers the `code_intel` tool with seven high-level actions and injects structural project context into the agent's first turn.
5
+ The first thing an agent does in a new project is read files to figure out what's there. Code Intelligence skips that — it auto-injects a compact project map on turn one, so the agent is already oriented.
6
6
 
7
- ## Injection Points
7
+ Beyond the overview, it gives the agent high-level analysis: architecture briefs, impact assessment, call tracing, and smart search that knows when to use LSP vs. tree-sitter vs. text search.
8
8
 
9
- The extension hooks into pi's lifecycle at six points:
9
+ ## What you get
10
10
 
11
- | # | Injection Point | What It Does |
12
- |---|---|---|
13
- | 1 | `package.json` → `pi.extensions` | Manifest entry that tells pi to load the extension at startup |
14
- | 2 | `pi.registerTool({ name: "code_intel", ... })` | Makes the `code_intel` tool callable from agent turns |
15
- | 3 | `promptGuidelines` (7 guidelines) | Flattened into the system prompt's `Guidelines:` section — teaches the agent *when* to use each action |
16
- | 4 | `promptSnippet` (1 line) | Injected near the tool definition in context — short reminder to use `code_intel` over broad file reads |
17
- | 5 | `pi.on("session_start", ...)` | Resets injection dedup state and scans the active branch to avoid re-injecting on reload/resume |
18
- | 6 | `pi.on("before_agent_start", ...)` | On the first agent turn, builds an architecture model and injects a compact Markdown overview as a custom message (`customType: "code-intelligence-overview"`, `display: false`) — the agent sees it in conversation context without UI clutter |
11
+ ### Instant orientation
19
12
 
20
- ### First-Turn Overview Flow
13
+ Every session starts with a project map in the agent's context: what packages exist, how they depend on each other, which files matter. The agent walks in knowing your codebase instead of discovering it file by file.
21
14
 
22
- 1. `session_start` fires → resets `hasInjectedOverview`, scans branch for existing `code-intelligence-overview` custom message
23
- 2. First `before_agent_start` fires → calls `buildArchitectureModel(ctx.cwd)` to parse the project
24
- 3. If modules are found, `generateOverview(model)` produces a dense Markdown summary (~500 tokens, max 8 modules) with git context when available
25
- 4. Returns a `BeforeAgentStartEventResult` with a `customMessage`; pi places it in the agent's context
26
- 5. Subsequent turns skip injection entirely
15
+ ### Architecture-level questions
27
16
 
28
- ## Tool Actions
17
+ Ask "what's in this package?" or "what depends on this module?" The agent gets a structural answer, not a file listing.
29
18
 
30
- ### `brief` — Architecture overviews and focused briefs
19
+ ### Impact analysis
31
20
 
32
- Scopes: project (no params), package/directory (`path`), file (`file`), or anchored symbol (`file`, `line`, and `character`).
21
+ Before a change: "show me everything that would break." The agent sees direct callers, downstream dependents, and risk level before touching code.
33
22
 
34
- - Project-level brief: module listing, dependency graph, "start here" recommendations, suggested next queries
35
- - Focused brief (`path` or anchored symbol): stripped-down version with a single module or symbol focus
36
- - Now includes git context (branch, dirty files, last commit) when inside a git repository
37
- - Metadata returned: `BriefDetails` with confidence, focus target, public surfaces, dependency summary
23
+ ### Smarter search
38
24
 
39
- ### `callers` Find call sites for a symbol
25
+ `code_intel pattern` is text search that knows about code structure. Search for definitions (not just any text match), group by directory, or filter by import/export. Falls back from LSP to tree-sitter to ripgrep automatically.
40
26
 
41
- - LSP-first (references query), falls back to heuristic text search (word-boundary ripgrep)
42
- - Results grouped by file with ranked, contextual call sites
43
- - Confidence labeling: `semantic` (LSP), `heuristic` (text search)
44
-
45
- ### `callees` — Structural outgoing call map
46
-
47
- - Structural tree-sitter analysis for all grammars configured in `supi-tree-sitter`
48
- - Finds outgoing function/method calls from an anchored position
49
- - Supports JavaScript/TypeScript, Python, Rust, Go, C/C++, Java, Kotlin, Ruby, Bash, and R
50
-
51
- ### `implementations` — Find concrete implementations
52
-
53
- - Resolves interface/abstract method implementations via LSP
54
- - Falls back to heuristic text search for `implements`/`extends` patterns
55
-
56
- ### `affected` — Blast-radius analysis
57
-
58
- Before changing exported APIs, shared helpers, config surfaces, or cross-package contracts:
59
- - Direct references (callers/importers)
60
- - Downstream dependents (transitive)
61
- - Risk level: `low` | `medium` | `high`
62
- - Likely test files
63
- - Returns `AffectedDetails` metadata
64
-
65
- ### `index` — Factual project map
66
-
67
- A non-interpretive project overview for quick orientation:
68
-
69
- - File counts by language/extension
70
- - Top-level directory tree with file counts
71
- - Landmark config files detected (package.json, tsconfig.json, Makefile, etc.)
72
- - Skips low-signal directories (`node_modules`, `dist`, `build`, `.git`)
73
-
74
- Use when you need to understand "what's here?" before diving into specific files.
75
-
76
- ```json
77
- { "action": "index" }
78
- ```
79
-
80
- ### `pattern` — Bounded, scope-aware text search
81
-
82
- Optimized for common agent lookups:
83
-
84
- - `pattern` is treated as a **literal string by default**
85
- - Set `regex: true` to opt into raw ripgrep regex semantics
86
- - Malformed regex input returns an explicit error instead of a misleading "No matches found"
87
- - Nearby matches in the same file deduplicate overlapping context lines to reduce token waste
88
- - Results grouped with file and context lines
89
- - `summary: true` returns aggregate counts by directory instead of line-level matches (useful for "how common is this pattern?")
90
-
91
- Examples:
27
+ ## Install
92
28
 
93
- ```json
94
- { "action": "pattern", "pattern": "sendMessage({", "path": "packages/" }
95
- { "action": "pattern", "pattern": "register(Settings|Config)", "path": "packages/", "regex": true }
96
- { "action": "pattern", "pattern": "createServerFn", "summary": true }
29
+ ```bash
30
+ pi install npm:@mrclrchtr/supi-code-intelligence
97
31
  ```
98
32
 
99
- ## Language & File Type Support
100
-
101
- | Feature / Language | JS/TS | Python | Rust | Go | Java/Kotlin | Ruby | PHP | Swift | C/C++ | Other text |
102
- |---|---|---|---|---|---|---|---|---|---|---|
103
- | **`index`** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
104
- | **`brief` (project)** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅¹ |
105
- | **`brief` (directory/file)** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
106
- | **`callers`** | ✅ | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ⚠️³ |
107
- | **`callees`** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
108
- | **`implementations`** | ✅ | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ⚠️³ |
109
- | **`affected`** | ✅ | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ✅² | ⚠️³ |
110
- | **`pattern`** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁴ |
111
-
112
- **Legend:**
113
- - **✅** Fully supported for that action.
114
- - **⚠️** Partial or best-effort support (see footnotes).
115
- - **❌** Not supported for that action.
116
- - **¹** Project-level brief works for any project with a recognized manifest (`package.json`, `Cargo.toml`, `go.mod`, `pyproject.toml`, etc.).
117
- - **²** Requires an active LSP server for semantic resolution; falls back to heuristic text search otherwise.
118
- - **³** Heuristic text-search fallback only; no semantic or structural resolution.
119
- - **⁴** `pattern` works on any text file. Binary files (`.png`, `.jpg`, `.zip`, `.pdf`, etc.) are explicitly rejected.
120
-
121
- ## Confidence Labeling
122
-
123
- Every result carries a `confidence` label from the result metadata:
124
-
125
- | Label | Meaning |
126
- |---|---|
127
- | `semantic` | Truth from LSP (definitions, references, diagnostics) |
128
- | `structural` | From tree-sitter AST (outlines, imports/exports, syntax) |
129
- | `heuristic` | Text search / best-effort inference |
130
- | `unavailable` | No data could be produced |
131
-
132
- ## Result Metadata
33
+ ## Quick look
133
34
 
134
- **Contract:** `details` is returned for every action handler execution. It is
135
- `undefined` *only* when the request is rejected before any handler runs
136
- (parameter validation errors, unknown action, missing required `pattern`).
35
+ | Action | What the agent can ask |
36
+ |--------|----------------------|
37
+ | `brief` | "Summarize this package / file / project" |
38
+ | `callers` | "Who calls this function?" |
39
+ | `callees` | "What does this function call?" |
40
+ | `affected` | "What breaks if I change this?" |
41
+ | `pattern` | "Find this text / pattern" |
42
+ | `index` | "What's in this project?" |
43
+ | `implementations` | "What implements this interface?" |
137
44
 
138
- For no-result and error states, `details` carries `confidence: "unavailable"` or
139
- `confidence: "heuristic"` with appropriately zeroed counts, so consumers always
140
- get structured metadata back.
45
+ Every result includes a confidence label (semantic / structural / heuristic) so the agent knows how much to trust the answer.
141
46
 
142
- - **`brief`** `BriefDetails` (confidence, focus target, start-here suggestions, public surfaces, dependency summary, omitted count, next queries)
143
- - **`search`** → `SearchDetails` (callers/callees/implementations/pattern: confidence, scope, candidate count, omitted count)
144
- - **`affected`** → `AffectedDetails` (direct count, downstream count, risk level, likely tests, check-next list)
47
+ ## For extension developers
145
48
 
146
- ## Parameter Validation
147
-
148
- The tool enforces these rules and returns explicit error messages:
149
-
150
- - `line`/`character` require `file`, not `path` — `path` is for scope/focus, `file` anchors a position
151
- - `file` that points to a directory is rejected — use `path` for directory scoping
152
- - Unknown actions are rejected with a list of supported actions
153
-
154
- ## Architecture
155
-
156
- Each action employs an appropriate fallback chain from the available services:
157
-
158
- - **`@mrclrchtr/supi-lsp`** — Semantic truth via LSP (references, symbols, implementations, diagnostics)
159
- - **`@mrclrchtr/supi-tree-sitter`** — Structural extraction (outlines, imports/exports, callees, syntax context)
160
- - **`@mrclrchtr/supi-core`** — Project/root utilities (root walking, known-root mapping, path containment)
161
-
162
- **Per-action fallback chains:** `callers`, `implementations`, and `affected` use LSP → ripgrep text search; `callees` uses tree-sitter AST analysis; `brief` uses the architecture model (plus tree-sitter outline for anchored briefs); `pattern` and `index` use filesystem and text-search primitives.
163
-
164
- ### Programmatic API
165
-
166
- The package exports its internal APIs for use by peer extensions:
49
+ The architecture model and brief generator are exported for reuse:
167
50
 
168
51
  ```ts
169
- // Architecture model
170
- export type { ArchitectureModel, DependencyEdge, ModuleInfo } from "./architecture.ts";
171
- export { buildArchitectureModel, findModuleForPath, getDependencies, getDependents } from "./architecture.ts";
172
-
173
- // Brief generation
174
- export { generateFocusedBrief, generateOverview, generateProjectBrief } from "./brief.ts";
175
-
176
- // Target resolution
177
- export type { ResolvedTarget, TargetResolutionResult } from "./target-resolution.ts";
178
- export { normalizePath, resolveAnchoredTarget, resolveSymbolTarget, toZeroBased } from "./target-resolution.ts";
179
-
180
- // Result types
181
- export type { AffectedDetails, BriefDetails, CodeIntelResult, ConfidenceMode, DisambiguationCandidate, SearchDetails } from "./types.ts";
182
- ```
52
+ import { buildArchitectureModel, generateOverview } from "@mrclrchtr/supi-code-intelligence";
183
53
 
184
- ## Session Integration
185
-
186
- - The overview custom message type (`code-intelligence-overview`) uses `display: false` so it appears in the LLM context but not in the TUI message log
187
- - On `session_start`, the extension scans the session branch for an existing overview to avoid re-injecting on `/reload` or session resume
188
- - The `hasInjectedOverview` flag is per-session, reset each `session_start`
189
-
190
- ## Prompt Guidelines (full text)
191
-
192
- These seven guidelines are injected into the system prompt:
193
-
194
- > - Use `code_intel brief` before editing an unfamiliar package, directory, or file to get architecture context and reduce blind reads.
195
- > - Use `code_intel affected` before changing exported APIs, shared helpers, config surfaces, or cross-package contracts to check blast radius and risk.
196
- > - Use `code_intel callers` before modifying a function to verify all call sites; use `callees` and `implementations` for dependency and interface analysis.
197
- > - Use `code_intel pattern` for bounded, scope-aware text search when the question is textual rather than semantic; it treats patterns as literal strings by default and supports `regex: true` when needed.
198
- > - Use `code_intel index` for a factual project map (file counts, directory structure, landmark files) when you need to orient yourself in a new codebase.
199
- > - After `code_intel` narrows the target, use raw `lsp` and `tree_sitter` tools for precise drill-down on exact symbols, types, or AST nodes.
200
- > - Do not prefer `code_intel` over direct file reads or lower-level tools for trivial, already-localized edits or exact symbol/AST drill-down tasks.
201
-
202
- ## Install
203
-
204
- Included in the `@mrclrchtr/supi` meta-package, or install standalone:
205
-
206
- ```bash
207
- pi install npm:@mrclrchtr/supi-code-intelligence
54
+ const model = await buildArchitectureModel("/project");
55
+ const overview = generateOverview(model);
208
56
  ```
209
-
210
- ## License
211
-
212
- MIT
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "0.2.0",
3
+ "version": "1.1.3",
4
4
  "description": "SuPi core — shared infrastructure for SuPi extensions (XML context tags, config system)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,9 +22,13 @@
22
22
  "@earendil-works/pi-coding-agent": "*",
23
23
  "@earendil-works/pi-tui": "*"
24
24
  },
25
- "devDependencies": {
26
- "@types/node": "25.6.2",
27
- "vitest": "4.1.5"
25
+ "peerDependenciesMeta": {
26
+ "@earendil-works/pi-coding-agent": {
27
+ "optional": true
28
+ },
29
+ "@earendil-works/pi-tui": {
30
+ "optional": true
31
+ }
28
32
  },
29
33
  "main": "src/index.ts"
30
34
  }
@@ -1,112 +1,66 @@
1
1
  # @mrclrchtr/supi-lsp
2
2
 
3
- Language Server Protocol integration for the [pi coding agent](https://github.com/earendil-works/pi).
3
+ Language Server Protocol for PI your agent navigates code like an IDE.
4
4
 
5
- ## Install
6
-
7
- ```bash
8
- pi install npm:@mrclrchtr/supi-lsp
9
- ```
10
-
11
- ## What it adds
12
-
13
- - `lsp` tool with `hover`, `definition`, `references`, `diagnostics`, `symbols`, `rename`, `code_actions`, `workspace_symbol`, `search`, `symbol_hover`, and `recover`
14
- - Stable system-prompt guidance that tells the agent to prefer LSP over grep/rg for code navigation
15
- - Proactive project scanning and eager startup of detected language servers
16
- - Automatic stale-diagnostic recovery when workspace sentinels change (`package.json`, root lockfiles, `tsconfig*`, generated `*.d.ts` files`) before the next agent turn, plus immediate recovery after successful `write` or `edit` calls for those paths
17
- - Inline diagnostic surfacing around reads, writes, and edits
18
- - Compact diagnostic context injection when outstanding diagnostics change, with stale-diagnostic warnings when needed
19
- - `/lsp-status` status overlay
5
+ Without LSP, agents grep and guess. With it, they jump to definitions, find every reference, rename across files, and catch type errors inline. The same precision you get from an editor, available to your agent.
20
6
 
21
- ## Public library API
7
+ ## What you get
22
8
 
23
- In addition to the extension entrypoint, `@mrclrchtr/supi-lsp` exports a reusable session-scoped service API for peer extensions:
9
+ ### Navigate with precision
24
10
 
25
- ```ts
26
- import { getSessionLspService, SessionLspService } from "@mrclrchtr/supi-lsp";
27
-
28
- const state = getSessionLspService("/project");
11
+ Go-to-definition, find-references, rename, hover types. The agent stops guessing and starts navigating your codebase with IDE-level accuracy.
29
12
 
30
- if (state.kind === "ready") {
31
- const service = state.service;
32
- const hover = await service.hover("src/index.ts", { line: 5, character: 10 });
33
- const defs = await service.definition("src/index.ts", { line: 5, character: 10 });
34
- const refs = await service.references("src/index.ts", { line: 5, character: 10 });
35
- const impls = await service.implementation("src/index.ts", { line: 5, character: 10 });
36
- const symbols = await service.documentSymbols("src/index.ts");
37
- const projectServers = service.getProjectServers();
38
- }
39
- ```
13
+ ### Catch problems immediately
40
14
 
41
- Peer extensions can import from the package root without reaching into private files.
15
+ Type errors, warnings, and hints surface inline after every edit. The agent sees mistakes as it makes them — not 10 turns later when tests fail.
42
16
 
43
- ## Tool actions
17
+ ### Always ready
44
18
 
45
- The `lsp` tool supports these actions:
19
+ Servers start automatically for your project. The agent gets language-aware guidance at session start and stale diagnostics are refreshed when dependencies change.
46
20
 
47
- - `hover`: type info at a position
48
- - `definition`: go to definition
49
- - `references`: find all references
50
- - `diagnostics`: per-file or project-wide diagnostics
51
- - `symbols`: document symbols
52
- - `rename`: workspace-wide rename
53
- - `code_actions`: quick fixes at a position
54
- - `workspace_symbol`: fuzzy symbol search across the project
55
- - `search`: symbol search with text fallback
56
- - `symbol_hover`: hover by symbol name
57
- - `recover`: refresh diagnostics after workspace-wide dependency, config, or generated-type changes
58
-
59
- Line and character positions are **1-based**.
60
-
61
- Example:
21
+ ## Install
62
22
 
63
- ```json
64
- {
65
- "action": "definition",
66
- "file": "src/index.ts",
67
- "line": 12,
68
- "character": 8
69
- }
23
+ ```bash
24
+ pi install npm:@mrclrchtr/supi-lsp
70
25
  ```
71
26
 
72
- ## Configuration
27
+ ## Quick look
73
28
 
74
- If your install surface includes `/supi-settings` (for example via `@mrclrchtr/supi`), this package contributes an LSP settings section there. Use that panel to:
29
+ The agent gets an `lsp` tool. The most-used actions:
75
30
 
76
- - enable or disable LSP globally
77
- - control the severity threshold
78
- - select active language servers
79
- - configure file exclusion patterns
31
+ | Action | What the agent can do |
32
+ |--------|----------------------|
33
+ | `hover` | See the type of any symbol |
34
+ | `definition` | Jump to where something is defined |
35
+ | `references` | Find every usage across the project |
36
+ | `diagnostics` | See errors, warnings, and hints |
37
+ | `rename` | Rename across the entire project |
80
38
 
81
- ## Commands
39
+ Full action reference: the agent's system prompt includes complete guidelines for all 11 actions (hover, definition, references, diagnostics, symbols, rename, code_actions, workspace_symbol, search, symbol_hover, recover). All positions are 1-based.
82
40
 
83
- `/lsp-status` toggles an overlay showing active language servers and outstanding diagnostics:
41
+ ## Settings
84
42
 
85
- ```text
86
- λ LSP inspector /lsp-status toggles
87
- 3 servers running • 12 open files • 5 errors • 2 warnings
43
+ Configure via `/supi-settings` (LSP panel):
88
44
 
89
- Servers
90
- typescript running 24 open files
91
- python running 8 open files
92
- bash running 0 open files
45
+ - Enable or disable LSP per project
46
+ - Set diagnostic severity threshold (errors only, or include warnings/hints)
47
+ - Choose which language servers to activate
48
+ - Add file exclusion patterns (gitignore-style globs)
93
49
 
94
- Problems
95
- src/lsp.ts:42 Cannot find name 'foo' ts(2304)
96
- src/manager.ts:108 Property 'bar' does not exist ts(2339)
97
- ```
50
+ Settings are stored in `~/.pi/agent/supi/config.json` (global) or `.pi/supi/config.json` (project). The `/lsp-status` command shows active servers and outstanding diagnostics.
98
51
 
99
- When no servers are available, the overlay shows `no LSP servers available for this project`. A compact status summary is always visible in the pi status bar.
52
+ ## For extension developers
100
53
 
101
- ## Requirements
54
+ This package exports a reusable session-scoped LSP service. Peer extensions can query the same LSP runtime without starting duplicate servers:
102
55
 
103
- - `@earendil-works/pi-coding-agent`
104
- - `@earendil-works/pi-tui`
105
- - `typebox`
106
- - relevant language servers installed and available on `PATH`
107
- - `@mrclrchtr/supi-core`
56
+ ```ts
57
+ import { getSessionLspService, SessionLspService } from "@mrclrchtr/supi-lsp";
108
58
 
109
- ## Source
59
+ const state = getSessionLspService("/project");
60
+ if (state.kind === "ready") {
61
+ const defs = await state.service.definition("src/index.ts", { line: 5, character: 10 });
62
+ const refs = await state.service.references("src/index.ts", { line: 5, character: 10 });
63
+ }
64
+ ```
110
65
 
111
- - Extension entrypoint: `lsp.ts`
112
- - Public library surface: `index.ts`
66
+ Import from the package root — no need to reach into internal files.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "0.2.0",
3
+ "version": "1.1.3",
4
4
  "description": "SuPi core — shared infrastructure for SuPi extensions (XML context tags, config system)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,9 +22,13 @@
22
22
  "@earendil-works/pi-coding-agent": "*",
23
23
  "@earendil-works/pi-tui": "*"
24
24
  },
25
- "devDependencies": {
26
- "@types/node": "25.6.2",
27
- "vitest": "4.1.5"
25
+ "peerDependenciesMeta": {
26
+ "@earendil-works/pi-coding-agent": {
27
+ "optional": true
28
+ },
29
+ "@earendil-works/pi-tui": {
30
+ "optional": true
31
+ }
28
32
  },
29
33
  "main": "src/index.ts"
30
34
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-lsp",
3
- "version": "1.0.0",
3
+ "version": "1.1.3",
4
4
  "description": "SuPi LSP extension — Language Server Protocol integration for pi",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,7 +21,7 @@
21
21
  "!__tests__"
22
22
  ],
23
23
  "dependencies": {
24
- "@mrclrchtr/supi-core": "workspace:*"
24
+ "@mrclrchtr/supi-core": "1.1.3"
25
25
  },
26
26
  "bundledDependencies": [
27
27
  "@mrclrchtr/supi-core"
@@ -32,9 +32,19 @@
32
32
  "@earendil-works/pi-tui": "*",
33
33
  "typebox": "*"
34
34
  },
35
- "devDependencies": {
36
- "vitest": "4.1.5",
37
- "@mrclrchtr/supi-test-utils": "workspace:*"
35
+ "peerDependenciesMeta": {
36
+ "@earendil-works/pi-ai": {
37
+ "optional": true
38
+ },
39
+ "@earendil-works/pi-coding-agent": {
40
+ "optional": true
41
+ },
42
+ "@earendil-works/pi-tui": {
43
+ "optional": true
44
+ },
45
+ "typebox": {
46
+ "optional": true
47
+ }
38
48
  },
39
49
  "pi": {
40
50
  "extensions": [
@@ -31,7 +31,7 @@ export function assessStaleDiagnostics(
31
31
  };
32
32
  }
33
33
 
34
- function isLikelyStaleDiagnostic(diagnostic: Diagnostic): boolean {
34
+ export function isLikelyStaleDiagnostic(diagnostic: Diagnostic): boolean {
35
35
  if (diagnostic.severity === undefined) return false;
36
36
  if (diagnostic.code !== undefined) {
37
37
  if (typeof diagnostic.code === "number" && MODULE_RESOLUTION_CODES.has(diagnostic.code)) {
@@ -29,6 +29,7 @@ import {
29
29
  removeLspTool,
30
30
  } from "./lsp-state.ts";
31
31
  import { LspManager } from "./manager/manager.ts";
32
+ import { forceResyncStaleModuleFiles } from "./manager/manager-stale-resync.ts";
32
33
  import { registerLspAwareToolOverrides } from "./overrides.ts";
33
34
  import { registerLspMessageRenderer } from "./renderer.ts";
34
35
  import { scanMissingServers, scanProjectCapabilities, startDetectedServers } from "./scanner.ts";
@@ -305,6 +306,16 @@ function registerBehaviorHandlers(pi: ExtensionAPI, state: LspRuntimeState): voi
305
306
  // Refresh failures must not prevent agent startup
306
307
  }
307
308
  state.manager.pruneMissingFiles();
309
+
310
+ // Force re-open files with module-resolution errors to clear stale
311
+ // diagnostics that persist when the TS server caches by content hash.
312
+ // Must run before the diagnostic summary so fresh results are captured.
313
+ try {
314
+ await forceResyncStaleModuleFiles(state.manager, ctx.cwd);
315
+ } catch {
316
+ // Best-effort: don't fail the agent turn
317
+ }
318
+
308
319
  refreshProjectServers(state);
309
320
  updateLspUi(ctx, state.manager, state.inlineSeverity, state.projectServers);
310
321
 
@@ -0,0 +1,47 @@
1
+ import * as path from "node:path";
2
+ import { isLikelyStaleDiagnostic } from "../diagnostics/stale-diagnostics.ts";
3
+ import type { LspManager } from "./manager.ts";
4
+
5
+ /**
6
+ * Force re-open files with module-resolution errors (e.g., "Cannot find module")
7
+ * to trigger fresh analysis by the language server.
8
+ *
9
+ * The TypeScript server caches diagnostics by file content hash. When a new
10
+ * file is created that resolves an existing file's import, the stale diagnostic
11
+ * persists because the importing file's content hasn't changed. Re-opening the
12
+ * file (didClose + didOpen) forces the server to re-resolve all imports.
13
+ *
14
+ * Returns true if any files were re-synced.
15
+ */
16
+ export async function forceResyncStaleModuleFiles(
17
+ manager: LspManager,
18
+ cwd: string,
19
+ ): Promise<boolean> {
20
+ const outstanding = manager.getOutstandingDiagnostics(1);
21
+ const staleFiles: string[] = [];
22
+
23
+ for (const entry of outstanding) {
24
+ if (entry.diagnostics.some((d) => isLikelyStaleDiagnostic(d))) {
25
+ staleFiles.push(entry.file);
26
+ }
27
+ }
28
+
29
+ if (staleFiles.length === 0) return false;
30
+
31
+ for (const file of staleFiles) {
32
+ const filePath = path.resolve(cwd, file);
33
+ // Close the file to clear cached diagnostics and remove from openDocs
34
+ manager.closeFile(filePath);
35
+ // Re-open to force the server to re-resolve imports
36
+ await manager.ensureFileOpen(filePath);
37
+ }
38
+
39
+ // Re-sync and wait for fresh diagnostics after the re-opens
40
+ try {
41
+ await manager.refreshOpenDiagnostics({ quietMs: 300, maxWaitMs: 2000 });
42
+ } catch {
43
+ // Best-effort: don't fail the agent turn if refresh has issues
44
+ }
45
+
46
+ return true;
47
+ }
@@ -151,7 +151,7 @@ function buildLspSettingItems(
151
151
  id: "exclude",
152
152
  label: "Exclude Patterns",
153
153
  description:
154
- "Gitignore patterns to suppress LSP diagnostics (e.g. __tests__/, *.generated.ts)",
154
+ "Gitignore patterns to suppress LSP diagnostics. Edit .pi/supi/config.json → lsp.exclude (or ~/.pi/agent/supi/config.json for global). Patterns like __tests__/ exclude a directory, *.test.ts wildcards match at any depth, /dist anchors to root.",
155
155
  currentValue: settings.exclude.length > 0 ? settings.exclude.join(", ") : "none",
156
156
  submenu: (_currentValue, done) => createExcludeSubmenu(scope, cwd, settings, done),
157
157
  },