@mrclrchtr/supi-code-intelligence 1.3.1 → 1.5.0
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/README.md +70 -32
- package/node_modules/@mrclrchtr/supi-core/README.md +52 -41
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +15 -13
- package/node_modules/@mrclrchtr/supi-core/src/{config-settings.ts → config/config-settings.ts} +2 -2
- package/node_modules/@mrclrchtr/{supi-lsp/node_modules/@mrclrchtr/supi-core/src → supi-core/src/context}/context-provider-registry.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/extension.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +15 -13
- package/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +40 -0
- package/node_modules/@mrclrchtr/supi-core/src/registry-utils.ts +42 -10
- package/node_modules/@mrclrchtr/{supi-lsp/node_modules/@mrclrchtr/supi-core/src → supi-core/src/settings}/settings-registry.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/README.md +58 -39
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +52 -41
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +15 -13
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{config-settings.ts → config/config-settings.ts} +2 -2
- package/node_modules/@mrclrchtr/{supi-core/src → supi-lsp/node_modules/@mrclrchtr/supi-core/src/context}/context-provider-registry.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/extension.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +15 -13
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +40 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/registry-utils.ts +42 -10
- package/node_modules/@mrclrchtr/{supi-core/src → supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings}/settings-registry.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +16 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +27 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +61 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +244 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/{types.ts → config/types.ts} +4 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/coordinates.ts +11 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-augmentation.ts +5 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-context.ts +115 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-display.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-summary.ts +3 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostics.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/stale-diagnostics.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/suppression-diagnostics.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/{workspace-sentinels.ts → diagnostics/workspace-sentinels.ts} +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +2 -23
- package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +18 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +72 -120
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-helpers.ts +4 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +10 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +158 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +202 -43
- package/node_modules/@mrclrchtr/supi-lsp/src/{lsp-state.ts → session/lsp-state.ts} +22 -11
- package/node_modules/@mrclrchtr/supi-lsp/src/{scanner.ts → session/scanner.ts} +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/{service-registry.ts → session/service-registry.ts} +109 -33
- package/node_modules/@mrclrchtr/supi-lsp/src/{settings-registration.ts → session/settings-registration.ts} +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +75 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +78 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +19 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/{overrides.ts → tool/overrides.ts} +55 -24
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +71 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +258 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +248 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/{ui.ts → ui/ui.ts} +4 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/utils.ts +5 -23
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +58 -39
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +107 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +44 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +85 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +76 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +186 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/context/context-messages.ts +119 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/context/context-provider-registry.ts +36 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/context/context-tag.ts +31 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +255 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/extension.ts +1 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +85 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +40 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/project-roots.ts +170 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/registry-utils.ts +86 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/session-utils.ts +29 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +15 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +41 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +226 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/terminal.ts +60 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +8 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +6 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +6 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/{runtime.ts → session/runtime.ts} +6 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/service-registry.ts +30 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/{session.ts → session/session.ts} +20 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/action-specs.ts +92 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/{callees.ts → tool/callees.ts} +3 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/{exports.ts → tool/exports.ts} +4 -4
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/{formatting.ts → tool/formatting.ts} +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +31 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/{imports.ts → tool/imports.ts} +4 -4
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/{node-at.ts → tool/node-at.ts} +3 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/{outline.ts → tool/outline.ts} +3 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +118 -91
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +13 -2
- package/package.json +4 -4
- package/src/actions/affected-action.ts +4 -4
- package/src/actions/brief-action.ts +12 -13
- package/src/actions/callees-action.ts +14 -10
- package/src/actions/callers-action.ts +4 -4
- package/src/actions/implementations-action.ts +4 -4
- package/src/code-intelligence.ts +4 -11
- package/src/pattern-structured.ts +20 -22
- package/src/providers/semantic-provider.ts +34 -0
- package/src/providers/structural-provider.ts +26 -0
- package/src/search-helpers.ts +4 -15
- package/src/target-resolution.ts +26 -35
- package/src/tool/action-specs.ts +66 -0
- package/src/tool/guidance.ts +18 -0
- package/src/tool-actions.ts +23 -40
- package/node_modules/@mrclrchtr/supi-lsp/src/guidance.ts +0 -163
- package/node_modules/@mrclrchtr/supi-lsp/src/search-fallback.ts +0 -98
- package/node_modules/@mrclrchtr/supi-lsp/src/tool-actions.ts +0 -430
- package/node_modules/@mrclrchtr/supi-lsp/src/tree-persist.ts +0 -48
- package/node_modules/@mrclrchtr/supi-lsp/src/tsconfig-scope.ts +0 -156
- package/src/guidance.ts +0 -42
- /package/node_modules/@mrclrchtr/supi-core/src/{config.ts → config/config.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-core/src/{context-messages.ts → context/context-messages.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-core/src/{context-tag.ts → context/context-tag.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-core/src/{settings-command.ts → settings/settings-command.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-core/src/{settings-ui.ts → settings/settings-ui.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{config.ts → config/config.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{context-messages.ts → context/context-messages.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{context-tag.ts → context/context-tag.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{settings-command.ts → settings/settings-command.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{settings-ui.ts → settings/settings-ui.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/src/{capabilities.ts → config/capabilities.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/src/{config.ts → config/config.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/src/{defaults.json → config/defaults.json} +0 -0
- /package/node_modules/@mrclrchtr/supi-lsp/src/{renderer.ts → ui/renderer.ts} +0 -0
- /package/node_modules/@mrclrchtr/supi-tree-sitter/src/{structure.ts → tool/structure.ts} +0 -0
|
@@ -1,430 +0,0 @@
|
|
|
1
|
-
// LSP tool action implementations — dispatches agent tool calls to LSP clients.
|
|
2
|
-
// biome-ignore-all lint/nursery/noExcessiveLinesPerFile: action dispatch remains cohesive; recovery helpers stay adjacent for readability.
|
|
3
|
-
|
|
4
|
-
import * as fs from "node:fs";
|
|
5
|
-
import * as path from "node:path";
|
|
6
|
-
import type { LspClient } from "./client/client.ts";
|
|
7
|
-
import { formatDiagnostics } from "./diagnostics/diagnostics.ts";
|
|
8
|
-
import {
|
|
9
|
-
formatCodeActions,
|
|
10
|
-
formatDocumentSymbols,
|
|
11
|
-
formatHover,
|
|
12
|
-
formatLocations,
|
|
13
|
-
formatSearchResults,
|
|
14
|
-
formatSymbolInformation,
|
|
15
|
-
formatWorkspaceEdit,
|
|
16
|
-
formatWorkspaceSymbols,
|
|
17
|
-
normalizeLocations,
|
|
18
|
-
} from "./format.ts";
|
|
19
|
-
import type { LspManager } from "./manager/manager.ts";
|
|
20
|
-
import { fallbackGrep } from "./search-fallback.ts";
|
|
21
|
-
import type { DocumentSymbol, Range, SymbolInformation } from "./types.ts";
|
|
22
|
-
import { uriToFile } from "./utils.ts";
|
|
23
|
-
|
|
24
|
-
// ── Types ─────────────────────────────────────────────────────────────
|
|
25
|
-
|
|
26
|
-
export type LspAction =
|
|
27
|
-
| "hover"
|
|
28
|
-
| "definition"
|
|
29
|
-
| "references"
|
|
30
|
-
| "diagnostics"
|
|
31
|
-
| "symbols"
|
|
32
|
-
| "rename"
|
|
33
|
-
| "code_actions"
|
|
34
|
-
| "workspace_symbol"
|
|
35
|
-
| "search"
|
|
36
|
-
| "symbol_hover"
|
|
37
|
-
| "recover";
|
|
38
|
-
|
|
39
|
-
export interface LspToolParams {
|
|
40
|
-
action: LspAction;
|
|
41
|
-
file?: string;
|
|
42
|
-
line?: number;
|
|
43
|
-
character?: number;
|
|
44
|
-
newName?: string;
|
|
45
|
-
query?: string;
|
|
46
|
-
symbol?: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// ── Tool Description ──────────────────────────────────────────────────
|
|
50
|
-
|
|
51
|
-
export const lspToolDescription = `Language Server Protocol tool — provides type-aware code intelligence.
|
|
52
|
-
|
|
53
|
-
Actions:
|
|
54
|
-
- hover: Get type info and docs at a position. Params: file, line, character
|
|
55
|
-
- definition: Go to definition of a symbol. Params: file, line, character
|
|
56
|
-
- references: Find all references to a symbol. Params: file, line, character
|
|
57
|
-
- diagnostics: Get type errors and warnings. Params: file (optional — omit for all files)
|
|
58
|
-
- symbols: List all symbols in a file. Params: file
|
|
59
|
-
- rename: Rename a symbol across the project. Params: file, line, character, newName
|
|
60
|
-
- code_actions: Get available fixes/refactors at a position. Params: file, line, character
|
|
61
|
-
- workspace_symbol: Fuzzy symbol search across the project. Params: query
|
|
62
|
-
- search: Search for symbols (LSP first, then text fallback). Params: query
|
|
63
|
-
- symbol_hover: Hover info by symbol name (zero coordinates). Params: symbol
|
|
64
|
-
- recover: Refresh cached diagnostics after a workspace change. Params: none
|
|
65
|
-
|
|
66
|
-
Line and character are 1-based. File paths are relative to cwd.`;
|
|
67
|
-
|
|
68
|
-
// ── Action Dispatcher ─────────────────────────────────────────────────
|
|
69
|
-
|
|
70
|
-
export async function executeAction(manager: LspManager, params: LspToolParams): Promise<string> {
|
|
71
|
-
const cwd = manager.getCwd();
|
|
72
|
-
switch (params.action) {
|
|
73
|
-
case "hover":
|
|
74
|
-
return handleHover(manager, params, cwd);
|
|
75
|
-
case "definition":
|
|
76
|
-
return handleDefinition(manager, params, cwd);
|
|
77
|
-
case "references":
|
|
78
|
-
return handleReferences(manager, params, cwd);
|
|
79
|
-
case "diagnostics":
|
|
80
|
-
return handleDiagnostics(manager, params, cwd);
|
|
81
|
-
case "symbols":
|
|
82
|
-
return handleSymbols(manager, params, cwd);
|
|
83
|
-
case "rename":
|
|
84
|
-
return handleRename(manager, params, cwd);
|
|
85
|
-
case "code_actions":
|
|
86
|
-
return handleCodeActions(manager, params, cwd);
|
|
87
|
-
case "workspace_symbol":
|
|
88
|
-
return handleWorkspaceSymbol(manager, params, cwd);
|
|
89
|
-
case "search":
|
|
90
|
-
return handleSearch(manager, params, cwd);
|
|
91
|
-
case "symbol_hover":
|
|
92
|
-
return handleSymbolHover(manager, params, cwd);
|
|
93
|
-
case "recover":
|
|
94
|
-
return handleRecover(manager);
|
|
95
|
-
default:
|
|
96
|
-
return `Unknown action: ${params.action}`;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Top-level error guard for unexpected throws in action handlers.
|
|
102
|
-
* Each handler aims to catch its own errors, but this ensures that
|
|
103
|
-
* an unforeseen runtime failure produces a descriptive string return
|
|
104
|
-
* instead of an unhandled tool error that pi would surface to the agent.
|
|
105
|
-
*/
|
|
106
|
-
export async function safeExecuteAction(
|
|
107
|
-
manager: LspManager,
|
|
108
|
-
params: LspToolParams,
|
|
109
|
-
): Promise<string> {
|
|
110
|
-
try {
|
|
111
|
-
return await executeAction(manager, params);
|
|
112
|
-
} catch (err) {
|
|
113
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
114
|
-
return `LSP action failed: ${message}`;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// ── Validation helpers ────────────────────────────────────────────────
|
|
119
|
-
|
|
120
|
-
function validateFilePosition(
|
|
121
|
-
params: LspToolParams,
|
|
122
|
-
action: string,
|
|
123
|
-
): { file: string; line: number; character: number } | string {
|
|
124
|
-
if (!params.file) return `Validation error: 'file' is required for ${action} action.`;
|
|
125
|
-
if (params.line === undefined)
|
|
126
|
-
return `Validation error: 'line' is required for ${action} action.`;
|
|
127
|
-
if (params.character === undefined)
|
|
128
|
-
return `Validation error: 'character' is required for ${action} action.`;
|
|
129
|
-
if (!Number.isInteger(params.line) || params.line < 1)
|
|
130
|
-
return `Validation error: 'line' must be a positive 1-based integer for ${action} action.`;
|
|
131
|
-
if (!Number.isInteger(params.character) || params.character < 1)
|
|
132
|
-
return `Validation error: 'character' must be a positive 1-based integer for ${action} action.`;
|
|
133
|
-
return { file: params.file, line: params.line, character: params.character };
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function validateNonEmptyString(
|
|
137
|
-
value: string | undefined,
|
|
138
|
-
name: string,
|
|
139
|
-
action: string,
|
|
140
|
-
): { value: string } | string {
|
|
141
|
-
if (!value || value.trim().length === 0) {
|
|
142
|
-
return `Validation error: '${name}' is required for ${action} action.`;
|
|
143
|
-
}
|
|
144
|
-
return { value };
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function resolveFilePath(file: string, cwd: string): string {
|
|
148
|
-
return path.resolve(cwd, file);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function toZeroBased(line: number, character: number): { line: number; character: number } {
|
|
152
|
-
return { line: line - 1, character: character - 1 };
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function noServerMessage(file: string): string {
|
|
156
|
-
return `No LSP server available for this file type (${path.extname(file) || "unknown"})`;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// ── Higher-order helpers ──────────────────────────────────────────────
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Encapsulates the common preamble shared by file-position-based action handlers:
|
|
163
|
-
* validates file/line/character, resolves the path, obtains the LSP client, and
|
|
164
|
-
* returns an error string if any step fails. Passes the ready client and zero-based
|
|
165
|
-
* coordinates to the callback.
|
|
166
|
-
*/
|
|
167
|
-
// biome-ignore lint/complexity/useMaxParams: Higher-order callback wrapper intentionally takes 5 params.
|
|
168
|
-
async function withFileClient(
|
|
169
|
-
manager: LspManager,
|
|
170
|
-
params: LspToolParams,
|
|
171
|
-
cwd: string,
|
|
172
|
-
action: string,
|
|
173
|
-
fn: (client: LspClient, file: string, line: number, character: number) => Promise<string>,
|
|
174
|
-
): Promise<string> {
|
|
175
|
-
const validation = validateFilePosition(params, action);
|
|
176
|
-
if (typeof validation === "string") return validation;
|
|
177
|
-
const { file, line, character } = validation;
|
|
178
|
-
const resolvedPath = resolveFilePath(file, cwd);
|
|
179
|
-
|
|
180
|
-
const client = await manager.ensureFileOpen(resolvedPath);
|
|
181
|
-
if (!client) return noServerMessage(resolvedPath);
|
|
182
|
-
|
|
183
|
-
return fn(client, resolvedPath, line, character);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// ── Action Handlers ───────────────────────────────────────────────────
|
|
187
|
-
|
|
188
|
-
async function handleHover(
|
|
189
|
-
manager: LspManager,
|
|
190
|
-
params: LspToolParams,
|
|
191
|
-
cwd: string,
|
|
192
|
-
): Promise<string> {
|
|
193
|
-
return withFileClient(manager, params, cwd, "hover", async (client, file, line, character) => {
|
|
194
|
-
const hover = await client.hover(file, toZeroBased(line, character));
|
|
195
|
-
if (!hover) return "No hover information available at this position.";
|
|
196
|
-
return formatHover(hover);
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async function handleDefinition(
|
|
201
|
-
manager: LspManager,
|
|
202
|
-
params: LspToolParams,
|
|
203
|
-
cwd: string,
|
|
204
|
-
): Promise<string> {
|
|
205
|
-
return withFileClient(
|
|
206
|
-
manager,
|
|
207
|
-
params,
|
|
208
|
-
cwd,
|
|
209
|
-
"definition",
|
|
210
|
-
async (client, file, line, character) => {
|
|
211
|
-
const result = await client.definition(file, toZeroBased(line, character));
|
|
212
|
-
if (!result) return "No definition found.";
|
|
213
|
-
|
|
214
|
-
const locations = normalizeLocations(result);
|
|
215
|
-
if (locations.length === 0) return "No definition found.";
|
|
216
|
-
|
|
217
|
-
return formatLocations("Definition", locations, cwd);
|
|
218
|
-
},
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
async function handleReferences(
|
|
223
|
-
manager: LspManager,
|
|
224
|
-
params: LspToolParams,
|
|
225
|
-
cwd: string,
|
|
226
|
-
): Promise<string> {
|
|
227
|
-
return withFileClient(
|
|
228
|
-
manager,
|
|
229
|
-
params,
|
|
230
|
-
cwd,
|
|
231
|
-
"references",
|
|
232
|
-
async (client, file, line, character) => {
|
|
233
|
-
const locations = await client.references(file, toZeroBased(line, character));
|
|
234
|
-
if (!locations || locations.length === 0) return "No references found.";
|
|
235
|
-
|
|
236
|
-
return formatLocations("References", locations, cwd);
|
|
237
|
-
},
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async function handleDiagnostics(
|
|
242
|
-
manager: LspManager,
|
|
243
|
-
params: LspToolParams,
|
|
244
|
-
cwd: string,
|
|
245
|
-
): Promise<string> {
|
|
246
|
-
if (params.file) {
|
|
247
|
-
const resolvedPath = resolveFilePath(params.file, cwd);
|
|
248
|
-
const client = await manager.ensureFileOpen(resolvedPath);
|
|
249
|
-
if (!client) return noServerMessage(resolvedPath);
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
const content = fs.readFileSync(resolvedPath, "utf-8");
|
|
253
|
-
const diags = await client.syncAndWaitForDiagnostics(resolvedPath, content);
|
|
254
|
-
return formatDiagnostics(resolvedPath, diags, cwd);
|
|
255
|
-
} catch {
|
|
256
|
-
return `Error: failed to read or query diagnostics for ${params.file}`;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const summary = manager.getDiagnosticSummary();
|
|
261
|
-
if (summary.length === 0) return "No diagnostics across any files.";
|
|
262
|
-
|
|
263
|
-
const lines = ["## Diagnostics Summary\n"];
|
|
264
|
-
for (const s of summary) {
|
|
265
|
-
lines.push(`- **${s.file}**: ${s.errors} error(s), ${s.warnings} warning(s)`);
|
|
266
|
-
}
|
|
267
|
-
return lines.join("\n");
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
async function handleSymbols(
|
|
271
|
-
manager: LspManager,
|
|
272
|
-
params: LspToolParams,
|
|
273
|
-
cwd: string,
|
|
274
|
-
): Promise<string> {
|
|
275
|
-
if (!params.file) return "Validation error: 'file' is required for symbols action.";
|
|
276
|
-
const resolvedPath = resolveFilePath(params.file, cwd);
|
|
277
|
-
|
|
278
|
-
const client = await manager.ensureFileOpen(resolvedPath);
|
|
279
|
-
if (!client) return noServerMessage(resolvedPath);
|
|
280
|
-
|
|
281
|
-
const symbols = await client.documentSymbols(resolvedPath);
|
|
282
|
-
if (!symbols || symbols.length === 0) return "No symbols found.";
|
|
283
|
-
|
|
284
|
-
if ("children" in symbols[0] || "selectionRange" in symbols[0]) {
|
|
285
|
-
return formatDocumentSymbols(symbols as DocumentSymbol[], 0);
|
|
286
|
-
}
|
|
287
|
-
return formatSymbolInformation(symbols as SymbolInformation[], cwd);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
async function handleRename(
|
|
291
|
-
manager: LspManager,
|
|
292
|
-
params: LspToolParams,
|
|
293
|
-
cwd: string,
|
|
294
|
-
): Promise<string> {
|
|
295
|
-
const nameValidation = validateNonEmptyString(params.newName, "newName", "rename");
|
|
296
|
-
if (typeof nameValidation === "string") return nameValidation;
|
|
297
|
-
const newName = nameValidation.value;
|
|
298
|
-
|
|
299
|
-
return withFileClient(manager, params, cwd, "rename", async (client, file, line, character) => {
|
|
300
|
-
const edit = await client.rename(file, toZeroBased(line, character), newName);
|
|
301
|
-
if (!edit) return "Rename not available at this position.";
|
|
302
|
-
|
|
303
|
-
return formatWorkspaceEdit(edit, cwd);
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
async function handleCodeActions(
|
|
308
|
-
manager: LspManager,
|
|
309
|
-
params: LspToolParams,
|
|
310
|
-
cwd: string,
|
|
311
|
-
): Promise<string> {
|
|
312
|
-
return withFileClient(
|
|
313
|
-
manager,
|
|
314
|
-
params,
|
|
315
|
-
cwd,
|
|
316
|
-
"code_actions",
|
|
317
|
-
async (client, file, line, character) => {
|
|
318
|
-
const pos = toZeroBased(line, character);
|
|
319
|
-
const range: Range = { start: pos, end: pos };
|
|
320
|
-
const diags = client.getDiagnostics(file);
|
|
321
|
-
|
|
322
|
-
const relevantDiags = diags.filter(
|
|
323
|
-
(d) => d.range.start.line <= pos.line && d.range.end.line >= pos.line,
|
|
324
|
-
);
|
|
325
|
-
|
|
326
|
-
const actions = await client.codeActions(file, range, {
|
|
327
|
-
diagnostics: relevantDiags,
|
|
328
|
-
});
|
|
329
|
-
if (!actions || actions.length === 0) return "No code actions available at this position.";
|
|
330
|
-
|
|
331
|
-
return formatCodeActions(actions);
|
|
332
|
-
},
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
async function handleWorkspaceSymbol(
|
|
337
|
-
manager: LspManager,
|
|
338
|
-
params: LspToolParams,
|
|
339
|
-
cwd: string,
|
|
340
|
-
): Promise<string> {
|
|
341
|
-
const validation = validateNonEmptyString(params.query, "query", "workspace_symbol");
|
|
342
|
-
if (typeof validation === "string") return validation;
|
|
343
|
-
const query = validation.value;
|
|
344
|
-
|
|
345
|
-
const symbols = await manager.workspaceSymbol(query);
|
|
346
|
-
if (!symbols) return "Workspace symbol search not supported by this language server.";
|
|
347
|
-
if (symbols.length === 0) return `No symbols found for query "${query}".`;
|
|
348
|
-
|
|
349
|
-
return formatWorkspaceSymbols(symbols as SymbolInformation[], cwd);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
async function handleSearch(
|
|
353
|
-
manager: LspManager,
|
|
354
|
-
params: LspToolParams,
|
|
355
|
-
cwd: string,
|
|
356
|
-
): Promise<string> {
|
|
357
|
-
const validation = validateNonEmptyString(params.query, "query", "search");
|
|
358
|
-
if (typeof validation === "string") return validation;
|
|
359
|
-
const query = validation.value;
|
|
360
|
-
|
|
361
|
-
const symbols = await manager.workspaceSymbol(query);
|
|
362
|
-
if (symbols && symbols.length > 0) {
|
|
363
|
-
return formatWorkspaceSymbols(symbols as SymbolInformation[], cwd);
|
|
364
|
-
}
|
|
365
|
-
const grepMatches = fallbackGrep(cwd, query);
|
|
366
|
-
return formatSearchResults(null, grepMatches, cwd);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
async function handleSymbolHover(
|
|
370
|
-
manager: LspManager,
|
|
371
|
-
params: LspToolParams,
|
|
372
|
-
_cwd: string,
|
|
373
|
-
): Promise<string> {
|
|
374
|
-
const validation = validateNonEmptyString(params.symbol, "symbol", "symbol_hover");
|
|
375
|
-
if (typeof validation === "string") return validation;
|
|
376
|
-
const symbol = validation.value;
|
|
377
|
-
|
|
378
|
-
const symbols = await manager.workspaceSymbol(symbol);
|
|
379
|
-
if (!symbols || symbols.length === 0) {
|
|
380
|
-
return `Symbol "${symbol}" not found.`;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Use the first match arbitrarily; LSP servers return results in their own
|
|
384
|
-
// order. The agent can use workspace_symbol or search to disambiguate.
|
|
385
|
-
const match = symbols[0];
|
|
386
|
-
const filePath = uriToFile(match.location.uri);
|
|
387
|
-
const client = await manager.ensureFileOpen(filePath);
|
|
388
|
-
if (!client) return noServerMessage(filePath);
|
|
389
|
-
|
|
390
|
-
const hover = await client.hover(filePath, match.location.range.start);
|
|
391
|
-
if (!hover) return `No hover information available for "${symbol}".`;
|
|
392
|
-
|
|
393
|
-
let result = formatHover(hover);
|
|
394
|
-
if (symbols.length > 1) {
|
|
395
|
-
result += `\n\n(${symbols.length - 1} other match${symbols.length === 2 ? "" : "es"} found — use workspace_symbol or search to disambiguate)`;
|
|
396
|
-
}
|
|
397
|
-
return result;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
interface RecoveryAssessmentLike {
|
|
401
|
-
suspected: boolean;
|
|
402
|
-
matchedFiles: Array<{ file: string; diagnostics: unknown[] }>;
|
|
403
|
-
warning: string | null;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
interface RecoveryResultLike {
|
|
407
|
-
refreshedClients: number;
|
|
408
|
-
restartedClients: number;
|
|
409
|
-
staleAssessment: RecoveryAssessmentLike;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
async function handleRecover(manager: LspManager): Promise<string> {
|
|
413
|
-
const result = await manager.recoverWorkspaceDiagnostics({ restartIfStillStale: true });
|
|
414
|
-
return formatRecoveryResult(result);
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
function formatRecoveryResult(result: RecoveryResultLike): string {
|
|
418
|
-
const refreshed = pluralize(result.refreshedClients, "client");
|
|
419
|
-
const restarted = pluralize(result.restartedClients, "client");
|
|
420
|
-
const status = result.staleAssessment.suspected
|
|
421
|
-
? "stale diagnostics still suspected"
|
|
422
|
-
: "stale diagnostics cleared";
|
|
423
|
-
const warning = result.staleAssessment.warning ? ` — ${result.staleAssessment.warning}` : "";
|
|
424
|
-
|
|
425
|
-
return `LSP recovery complete: refreshed ${refreshed}, restarted ${restarted}, ${status}${warning}.`;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
function pluralize(count: number, word: string): string {
|
|
429
|
-
return `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
430
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
// LSP tree navigation persistence — restores tool activation state across /tree navigation.
|
|
2
|
-
|
|
3
|
-
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
-
|
|
5
|
-
/** Shape of the entry persisted via `pi.appendEntry()`. */
|
|
6
|
-
export interface LspStateEntry {
|
|
7
|
-
active: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/** Restore LSP activation state from the current branch after /tree navigation. */
|
|
11
|
-
export function registerTreePersistHandlers(pi: ExtensionAPI, state: { lspActive: boolean }): void {
|
|
12
|
-
pi.on("session_tree", async (_event, ctx) => {
|
|
13
|
-
const branch = ctx.sessionManager.getBranch();
|
|
14
|
-
let lastEntry: LspStateEntry | undefined;
|
|
15
|
-
|
|
16
|
-
for (const entry of branch) {
|
|
17
|
-
if (entry.type === "custom" && entry.customType === "lsp-active") {
|
|
18
|
-
lastEntry = entry.data as LspStateEntry | undefined;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (lastEntry?.active) {
|
|
23
|
-
const activeTools = pi.getActiveTools();
|
|
24
|
-
if (!activeTools.includes("lsp")) {
|
|
25
|
-
pi.setActiveTools([...activeTools, "lsp"]);
|
|
26
|
-
}
|
|
27
|
-
state.lspActive = true;
|
|
28
|
-
} else {
|
|
29
|
-
const activeTools = pi.getActiveTools();
|
|
30
|
-
if (activeTools.includes("lsp")) {
|
|
31
|
-
pi.setActiveTools(activeTools.filter((t) => t !== "lsp"));
|
|
32
|
-
}
|
|
33
|
-
state.lspActive = false;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Persist that LSP is active in the session tree. */
|
|
39
|
-
export function persistLspActiveState(pi: ExtensionAPI, state: { lspActive: boolean }): void {
|
|
40
|
-
state.lspActive = true;
|
|
41
|
-
pi.appendEntry<LspStateEntry>("lsp-active", { active: true });
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Persist that LSP is inactive in the session tree. */
|
|
45
|
-
export function persistLspInactiveState(pi: ExtensionAPI, state: { lspActive: boolean }): void {
|
|
46
|
-
state.lspActive = false;
|
|
47
|
-
pi.appendEntry<LspStateEntry>("lsp-active", { active: false });
|
|
48
|
-
}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
// tsconfig-aware file scope detection.
|
|
2
|
-
//
|
|
3
|
-
// Determines whether a file is within the compilation scope of its nearest
|
|
4
|
-
// tsconfig.json by checking `include` and `exclude` patterns. Used by the
|
|
5
|
-
// diagnostic filter to suppress LSP errors on files that TypeScript itself
|
|
6
|
-
// would not type-check.
|
|
7
|
-
|
|
8
|
-
import * as fs from "node:fs";
|
|
9
|
-
import * as path from "node:path";
|
|
10
|
-
|
|
11
|
-
interface TsconfigInfo {
|
|
12
|
-
dir: string;
|
|
13
|
-
include: string[] | undefined;
|
|
14
|
-
exclude: string[] | undefined;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const cache = new Map<string, TsconfigInfo | null>();
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Check whether a file is excluded by its nearest tsconfig.json.
|
|
21
|
-
*
|
|
22
|
-
* @param filePath - Project-relative file path (e.g., "packages/foo/__tests__/x.test.ts")
|
|
23
|
-
* @param cwd - Absolute project root directory
|
|
24
|
-
* @returns `true` if the file is excluded from compilation scope
|
|
25
|
-
*/
|
|
26
|
-
export function isFileExcludedByTsconfig(filePath: string, cwd: string): boolean {
|
|
27
|
-
const absolutePath = path.resolve(cwd, filePath);
|
|
28
|
-
const tsconfig = findNearestTsconfig(path.dirname(absolutePath), cwd);
|
|
29
|
-
if (!tsconfig) return false;
|
|
30
|
-
|
|
31
|
-
const relativeToTsconfig = path.relative(tsconfig.dir, absolutePath).replaceAll("\\", "/");
|
|
32
|
-
|
|
33
|
-
// Check exclude patterns first
|
|
34
|
-
if (tsconfig.exclude) {
|
|
35
|
-
for (const pattern of tsconfig.exclude) {
|
|
36
|
-
if (matchesPattern(relativeToTsconfig, pattern)) return true;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// If include is specified, the file must match at least one pattern
|
|
41
|
-
if (tsconfig.include) {
|
|
42
|
-
let included = false;
|
|
43
|
-
for (const pattern of tsconfig.include) {
|
|
44
|
-
if (matchesPattern(relativeToTsconfig, pattern)) {
|
|
45
|
-
included = true;
|
|
46
|
-
break;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
if (!included) return true;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Find the nearest tsconfig.json walking upward from `startDir`,
|
|
57
|
-
* stopping at `rootDir`.
|
|
58
|
-
*/
|
|
59
|
-
function findNearestTsconfig(startDir: string, rootDir: string): TsconfigInfo | null {
|
|
60
|
-
let dir = startDir;
|
|
61
|
-
while (true) {
|
|
62
|
-
const cached = cache.get(dir);
|
|
63
|
-
if (cached !== undefined) return cached;
|
|
64
|
-
|
|
65
|
-
const tsconfigPath = path.join(dir, "tsconfig.json");
|
|
66
|
-
if (fs.existsSync(tsconfigPath)) {
|
|
67
|
-
const info = parseTsconfig(dir, tsconfigPath);
|
|
68
|
-
cache.set(dir, info);
|
|
69
|
-
return info;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (path.relative(rootDir, dir).startsWith("..") || dir === rootDir) {
|
|
73
|
-
// Don't look above the project root
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const parent = path.dirname(dir);
|
|
78
|
-
if (parent === dir) {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
dir = parent;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function parseTsconfig(dir: string, tsconfigPath: string): TsconfigInfo | null {
|
|
86
|
-
try {
|
|
87
|
-
const raw = fs.readFileSync(tsconfigPath, "utf-8");
|
|
88
|
-
// Strip comments without touching content inside double-quoted strings.
|
|
89
|
-
const cleaned = raw
|
|
90
|
-
.replace(/("(?:\\.|[^"\\])*")|\/\/.*$/gm, "$1")
|
|
91
|
-
.replace(/("(?:\\.|[^"\\])*")|\/[\s\S]*?\*\//g, "$1");
|
|
92
|
-
const json = JSON.parse(cleaned);
|
|
93
|
-
return {
|
|
94
|
-
dir,
|
|
95
|
-
include: json.include as string[] | undefined,
|
|
96
|
-
exclude: json.exclude as string[] | undefined,
|
|
97
|
-
};
|
|
98
|
-
} catch {
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Lightweight pattern matching for tsconfig include/exclude patterns.
|
|
105
|
-
* Handles directory names, extensions, recursive globs, and literal paths.
|
|
106
|
-
*/
|
|
107
|
-
function matchesPattern(filePath: string, pattern: string): boolean {
|
|
108
|
-
const normalizedPattern = pattern.replaceAll("\\", "/");
|
|
109
|
-
|
|
110
|
-
// Directory-prefixed recursive glob: prefix/**/*.ext
|
|
111
|
-
if (normalizedPattern.includes("/**/")) {
|
|
112
|
-
const idx = normalizedPattern.indexOf("/**/");
|
|
113
|
-
const prefix = normalizedPattern.slice(0, idx);
|
|
114
|
-
const suffix = normalizedPattern.slice(idx + 4);
|
|
115
|
-
return (
|
|
116
|
-
filePath.startsWith(`${prefix}/`) && matchesPattern(filePath.slice(prefix.length + 1), suffix)
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Recursive glob: **/*.ext
|
|
121
|
-
if (normalizedPattern.startsWith("**/")) {
|
|
122
|
-
const suffix = normalizedPattern.slice(3); // e.g., "*.ts"
|
|
123
|
-
return matchesPattern(filePath, suffix) || filePath.includes(`/${suffix}`);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Directory match: pattern has no glob chars and no "."
|
|
127
|
-
// e.g., "node_modules" or "__tests__"
|
|
128
|
-
if (!normalizedPattern.includes("*") && !normalizedPattern.includes(".")) {
|
|
129
|
-
return (
|
|
130
|
-
filePath === normalizedPattern ||
|
|
131
|
-
filePath.startsWith(`${normalizedPattern}/`) ||
|
|
132
|
-
filePath.includes(`/${normalizedPattern}/`)
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Simple glob: *.ext — match basename
|
|
137
|
-
if (normalizedPattern.startsWith("*.")) {
|
|
138
|
-
const ext = normalizedPattern.slice(1); // e.g., ".ts"
|
|
139
|
-
return filePath.endsWith(ext) && !filePath.includes("/", filePath.length - ext.length - 1);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Literal path
|
|
143
|
-
if (!normalizedPattern.includes("*")) {
|
|
144
|
-
return filePath === normalizedPattern || filePath.startsWith(`${normalizedPattern}/`);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Fallback: path contains the pattern segment
|
|
148
|
-
return filePath.includes(`/${normalizedPattern}`) || filePath === normalizedPattern;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Clear the tsconfig cache. Useful for testing or after filesystem changes.
|
|
153
|
-
*/
|
|
154
|
-
export function clearTsconfigCache(): void {
|
|
155
|
-
cache.clear();
|
|
156
|
-
}
|
package/src/guidance.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
// Prompt guidance and tool description for the code_intel tool.
|
|
2
|
-
|
|
3
|
-
export const toolDescription = `Code intelligence tool — architecture briefs, semantic relationships, impact analysis, structured text search, and project indexing.
|
|
4
|
-
|
|
5
|
-
Actions:
|
|
6
|
-
- brief: Architecture overview or focused brief for a project, package, directory, file, or anchored symbol
|
|
7
|
-
- callers: Find call sites for a symbol, or analyze a file-level export surface when only \`file\` is provided
|
|
8
|
-
- callees: Best-effort outgoing calls from a symbol (structural tree-sitter analysis across supported grammars)
|
|
9
|
-
- implementations: Find concrete implementations of an interface or abstract type
|
|
10
|
-
- affected: Blast-radius analysis for a symbol or exported file surface — direct references, downstream dependents, risk level, likely tests
|
|
11
|
-
- pattern: Bounded text search with grouped matches, context lines, structured \`kind\` filters (\`definition\` | \`export\` | \`import\`), partial-result warnings on oversized structured scans, and regex opt-in via \`regex: true\`
|
|
12
|
-
- index: Factual project map — file counts by language, top-level directory tree, landmark config files
|
|
13
|
-
|
|
14
|
-
Coordinates are 1-based (line, character) with UTF-16 character columns, matching lsp and tree_sitter conventions.
|
|
15
|
-
Relative paths resolve from the session working directory. A leading @ on path/file is stripped automatically.
|
|
16
|
-
|
|
17
|
-
Examples:
|
|
18
|
-
{ "action": "brief" }
|
|
19
|
-
{ "action": "brief", "path": "packages/supi-lsp/" }
|
|
20
|
-
{ "action": "brief", "file": "packages/supi-lsp/lsp.ts", "line": 42, "character": 7 }
|
|
21
|
-
{ "action": "callers", "file": "packages/supi-core/index.ts" }
|
|
22
|
-
{ "action": "callers", "symbol": "registerSettings", "path": "packages/supi-core/" }
|
|
23
|
-
{ "action": "callees", "file": "src/handler.ts", "line": 88, "character": 12 }
|
|
24
|
-
{ "action": "implementations", "symbol": "SessionLspService", "path": "packages/" }
|
|
25
|
-
{ "action": "affected", "file": "packages/supi-core/index.ts" }
|
|
26
|
-
{ "action": "pattern", "pattern": "registerSettings", "path": "packages/", "maxResults": 10 }
|
|
27
|
-
{ "action": "pattern", "pattern": "register(Settings|Config)", "path": "packages/", "regex": true, "maxResults": 10 }
|
|
28
|
-
{ "action": "pattern", "pattern": "payment", "kind": "definition", "path": "src/" }`;
|
|
29
|
-
|
|
30
|
-
export const promptSnippet =
|
|
31
|
-
"Use the code_intel tool for architecture orientation, semantic relationships, impact analysis, and structured search before broad file reads.";
|
|
32
|
-
|
|
33
|
-
export const promptGuidelines = [
|
|
34
|
-
"Use `code_intel brief` before editing an unfamiliar package, directory, or file to get architecture context and reduce blind reads.",
|
|
35
|
-
"Use `code_intel affected` before changing exported APIs, shared helpers, config surfaces, or cross-package contracts to check blast radius and risk; file-only requests now expand across exported targets when possible.",
|
|
36
|
-
"Use `code_intel callers` before modifying a function to verify all call sites; use `callees` and `implementations` for dependency and interface analysis, and use file-only `callers` when you need the export surface of a module.",
|
|
37
|
-
'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, supports `regex: true`, supports `kind: "definition" | "export" | "import"` for structured searches, and may return a partial-result warning when a structured scan is too broad.',
|
|
38
|
-
"Use `code_intel brief` and `code_intel affected` priority signals to notice diagnostics, low coverage, or unused-code hints before editing risky files.",
|
|
39
|
-
"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.",
|
|
40
|
-
"After `code_intel` narrows the target, use raw `lsp` and `tree_sitter` tools for precise drill-down on exact symbols, types, or AST nodes.",
|
|
41
|
-
"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.",
|
|
42
|
-
];
|
|
File without changes
|
/package/node_modules/@mrclrchtr/supi-core/src/{context-messages.ts → context/context-messages.ts}
RENAMED
|
File without changes
|
|
File without changes
|
/package/node_modules/@mrclrchtr/supi-core/src/{settings-command.ts → settings/settings-command.ts}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|