@mrclrchtr/supi-code-intelligence 2.0.6 → 2.1.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 +71 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +29 -21
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-core/README.md +29 -21
- package/node_modules/@mrclrchtr/supi-core/package.json +2 -1
- package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
- package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
- package/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
- package/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
- package/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
- package/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +29 -21
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +29 -21
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +2 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
- package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +29 -21
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +29 -21
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +2 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
- package/package.json +5 -5
- package/src/analysis/evidence.ts +13 -0
- package/src/analysis/search/pattern.ts +24 -13
- package/src/analysis/search/ripgrep.ts +92 -7
- package/src/extension.ts +1 -1
- package/src/session/capability-adapter.ts +218 -0
- package/src/session/session.ts +39 -1
- package/src/session/target-workflow.ts +430 -0
- package/src/substrate/lsp/settings.ts +7 -3
- package/src/tool/find/execute.ts +23 -10
- package/src/tool/find/orchestrate.ts +67 -54
- package/src/tool/find/semantic-search.ts +30 -16
- package/src/tool/graph/collect-relation.ts +2 -1
- package/src/tool/graph/execute.ts +40 -12
- package/src/tool/graph/markdown-base.ts +5 -37
- package/src/tool/graph/orchestrate.ts +9 -35
- package/src/tool/graph/tui.ts +2 -0
- package/src/tool/guidance.ts +1 -1
- package/src/tool/health/markdown.ts +12 -70
- package/src/tool/health/orchestrate.ts +5 -13
- package/src/tool/impact/analysis.ts +0 -27
- package/src/tool/impact/change-set-impact.ts +3 -2
- package/src/tool/impact/execute.ts +27 -0
- package/src/tool/impact/file-level-impact.ts +3 -2
- package/src/tool/impact/result.ts +2 -21
- package/src/tool/impact/single-impact.ts +3 -2
- package/src/tool/infra/error-results.ts +18 -196
- package/src/tool/infra/pipeline.ts +24 -1
- package/src/tool/inspect/markdown.ts +4 -41
- package/src/tool/inspect/orchestrate.ts +27 -28
- package/src/tool/orientation/orchestrate.ts +5 -8
- package/src/tool/orientation/precise-target.ts +65 -69
- package/src/tool/refactor-apply/orchestrate.ts +2 -7
- package/src/tool/refactor-plan/orchestrate.ts +31 -39
- package/src/tool/resolve/markdown.ts +5 -6
- package/src/tool/resolve/orchestrate.ts +7 -103
- package/src/tool/result/errors.ts +199 -0
- package/src/tool/result/find.ts +29 -0
- package/src/tool/result/graph.ts +93 -0
- package/src/tool/result/health.ts +94 -0
- package/src/tool/result/impact.ts +50 -0
- package/src/tool/result/inspect.ts +60 -0
- package/src/tool/result/orientation.ts +30 -0
- package/src/tool/result/refactor.ts +35 -0
- package/src/tool/result/resolve.ts +114 -0
- package/src/tool/result/types.ts +188 -0
- package/src/tool/schemas.ts +22 -1
- package/src/types/details.ts +17 -185
- package/src/ui/tui/common.ts +45 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-tree-sitter",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "SuPi Tree-sitter extension — structural AST analysis for pi",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"web-tree-sitter": "^0.26.8",
|
|
38
|
-
"@mrclrchtr/supi-code-runtime": "2.0
|
|
39
|
-
"@mrclrchtr/supi-core": "2.0
|
|
38
|
+
"@mrclrchtr/supi-code-runtime": "2.1.0",
|
|
39
|
+
"@mrclrchtr/supi-core": "2.1.0"
|
|
40
40
|
},
|
|
41
41
|
"bundledDependencies": [
|
|
42
42
|
"@mrclrchtr/supi-code-runtime",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-code-intelligence",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "SuPi Code Intelligence extension — architecture briefs, caller/callee analysis, impact assessment, and pattern search for pi",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"ts-pattern": "^5.9.0",
|
|
37
|
-
"@mrclrchtr/supi-code-runtime": "2.0
|
|
38
|
-
"@mrclrchtr/supi-core": "2.0
|
|
39
|
-
"@mrclrchtr/supi-lsp": "2.0
|
|
40
|
-
"@mrclrchtr/supi-tree-sitter": "2.0
|
|
37
|
+
"@mrclrchtr/supi-code-runtime": "2.1.0",
|
|
38
|
+
"@mrclrchtr/supi-core": "2.1.0",
|
|
39
|
+
"@mrclrchtr/supi-lsp": "2.1.0",
|
|
40
|
+
"@mrclrchtr/supi-tree-sitter": "2.1.0"
|
|
41
41
|
},
|
|
42
42
|
"bundledDependencies": [
|
|
43
43
|
"@mrclrchtr/supi-code-runtime",
|
package/src/analysis/evidence.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence-list helpers — the shared leaf utility for bounded tool-evidence
|
|
3
|
+
* collections with explicit completeness metadata.
|
|
4
|
+
*
|
|
5
|
+
* These helpers (types, builders, disclosure renderers) are consumed by both
|
|
6
|
+
* the `analysis/` layer (brief/reference/git formatters that produce markdown
|
|
7
|
+
* fragments) and the `tool/` layer (markdown/TUI renderers and tool-result
|
|
8
|
+
* assembly). They live here, at the lower layer, so `analysis/` never imports
|
|
9
|
+
* upward into `tool/`. The tool-result *assembly* (`assemble*` functions and
|
|
10
|
+
* details types) lives in `src/tool/result/`; this module is the shared
|
|
11
|
+
* evidence-list primitive beneath it.
|
|
12
|
+
*/
|
|
13
|
+
|
|
1
14
|
export type EvidencePartialReason = "timeout" | "safety-limit" | "interrupted" | "provider-limited";
|
|
2
15
|
|
|
3
16
|
export interface EvidenceListMetadata {
|
|
@@ -64,7 +64,7 @@ export function isStructuredPatternKind(kind: string | undefined): kind is Struc
|
|
|
64
64
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: enumeration-interrupted, cap, timeout, and error branches are each necessary
|
|
65
65
|
export async function getStructuredPatternMatches(
|
|
66
66
|
params: StructuredPatternParams,
|
|
67
|
-
scopePath: string,
|
|
67
|
+
scopePath: string | readonly string[],
|
|
68
68
|
cwd: string,
|
|
69
69
|
relScope: string,
|
|
70
70
|
structural: StructuralSubstrate,
|
|
@@ -143,7 +143,10 @@ interface FileEnumeration {
|
|
|
143
143
|
* Enumerate all tree-sitter-supported source files in scopePath using rg --files.
|
|
144
144
|
* Returns null if ripgrep is not available.
|
|
145
145
|
*/
|
|
146
|
-
function enumerateSourceFiles(
|
|
146
|
+
function enumerateSourceFiles(
|
|
147
|
+
scopePath: string | readonly string[],
|
|
148
|
+
cwd: string,
|
|
149
|
+
): FileEnumeration | null {
|
|
147
150
|
const extensions = getSupportedExtensions();
|
|
148
151
|
// Strip leading dots — ripgrep -g expects ".ext" without the dot prefix
|
|
149
152
|
const globPattern = `*.{${Array.from(extensions)
|
|
@@ -151,18 +154,14 @@ function enumerateSourceFiles(scopePath: string, cwd: string): FileEnumeration |
|
|
|
151
154
|
.join(",")}}`;
|
|
152
155
|
|
|
153
156
|
try {
|
|
154
|
-
const output = execFileSync("rg", ["--files", "-g", globPattern, scopePath], {
|
|
157
|
+
const output = execFileSync("rg", ["--files", "-g", globPattern, ...scopePathArgs(scopePath)], {
|
|
155
158
|
encoding: "utf-8",
|
|
156
159
|
cwd,
|
|
157
160
|
timeout: 5000,
|
|
158
161
|
stdio: ["pipe", "pipe", "pipe"],
|
|
159
162
|
});
|
|
160
163
|
return {
|
|
161
|
-
files: output
|
|
162
|
-
.split("\n")
|
|
163
|
-
.map((line) => line.trim())
|
|
164
|
-
.filter((line) => line.length > 0)
|
|
165
|
-
.sort((a, b) => a.localeCompare(b)),
|
|
164
|
+
files: normalizeEnumeratedFiles(output),
|
|
166
165
|
interrupted: false,
|
|
167
166
|
};
|
|
168
167
|
} catch (err: unknown) {
|
|
@@ -174,11 +173,7 @@ function enumerateSourceFiles(scopePath: string, cwd: string): FileEnumeration |
|
|
|
174
173
|
const stdout = typeof err.stdout === "string" ? err.stdout : "";
|
|
175
174
|
const wasKilled = (err as { killed?: boolean }).killed === true;
|
|
176
175
|
return {
|
|
177
|
-
files: stdout
|
|
178
|
-
.split("\n")
|
|
179
|
-
.map((line) => line.trim())
|
|
180
|
-
.filter((line) => line.length > 0)
|
|
181
|
-
.sort((a, b) => a.localeCompare(b)),
|
|
176
|
+
files: normalizeEnumeratedFiles(stdout),
|
|
182
177
|
interrupted: wasKilled,
|
|
183
178
|
};
|
|
184
179
|
}
|
|
@@ -186,6 +181,22 @@ function enumerateSourceFiles(scopePath: string, cwd: string): FileEnumeration |
|
|
|
186
181
|
}
|
|
187
182
|
}
|
|
188
183
|
|
|
184
|
+
function scopePathArgs(scopePath: string | readonly string[]): string[] {
|
|
185
|
+
const paths = Array.isArray(scopePath) ? scopePath : [scopePath];
|
|
186
|
+
return paths.length > 0 ? [...paths] : ["."];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function normalizeEnumeratedFiles(output: string): string[] {
|
|
190
|
+
return [
|
|
191
|
+
...new Set(
|
|
192
|
+
output
|
|
193
|
+
.split("\n")
|
|
194
|
+
.map((line) => line.trim())
|
|
195
|
+
.filter((line) => line.length > 0),
|
|
196
|
+
),
|
|
197
|
+
].sort((a, b) => a.localeCompare(b));
|
|
198
|
+
}
|
|
199
|
+
|
|
189
200
|
// biome-ignore lint/complexity/useMaxParams: helper takes explicit collection inputs to avoid intermediate objects in the hot path
|
|
190
201
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: kind-specific tree-sitter matching is clearest as one helper
|
|
191
202
|
async function collectMatchesForFile(
|
|
@@ -47,6 +47,11 @@ export function isInProjectPath(filePath: string, cwd: string): boolean {
|
|
|
47
47
|
/** Result of resolving a user-provided `scope` value to an absolute path. */
|
|
48
48
|
export type ScopeResolution = { kind: "ok"; path: string } | { kind: "error"; reason: string };
|
|
49
49
|
|
|
50
|
+
/** Result of resolving a code_find `scope` value to one or more absolute paths. */
|
|
51
|
+
export type ScopeSetResolution =
|
|
52
|
+
| { kind: "ok"; paths: string[]; display: string | null }
|
|
53
|
+
| { kind: "error"; reason: string };
|
|
54
|
+
|
|
50
55
|
/**
|
|
51
56
|
* Resolve a `scope` value to an absolute path using pi scope semantics:
|
|
52
57
|
* - strip leading `@`
|
|
@@ -61,6 +66,55 @@ export function resolveScope(scope: string | undefined, cwd: string): ScopeResol
|
|
|
61
66
|
reason: `Scope accepts a single directory or file path, not multiple: \`${scope}\``,
|
|
62
67
|
};
|
|
63
68
|
}
|
|
69
|
+
return resolveSingleScope(scope, cwd);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Resolve a code_find scope input to one or more absolute paths.
|
|
74
|
+
*
|
|
75
|
+
* `code_find` is intentionally more flexible than other code-intelligence tools:
|
|
76
|
+
* it accepts `scope: ["docs", "packages"]` and also splits delimiter-separated
|
|
77
|
+
* strings such as `"docs packages"` only when no exact path by that name exists.
|
|
78
|
+
*/
|
|
79
|
+
export function resolveScopeSet(
|
|
80
|
+
scope: string | readonly string[] | undefined,
|
|
81
|
+
cwd: string,
|
|
82
|
+
): ScopeSetResolution {
|
|
83
|
+
if (scope === undefined) {
|
|
84
|
+
return { kind: "ok", paths: [cwd], display: null };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const labels = typeof scope === "string" ? splitScopeString(scope, cwd) : [...scope];
|
|
88
|
+
if (labels.length === 0) {
|
|
89
|
+
return { kind: "error", reason: "Scope must include at least one directory or file path." };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const resolved: Array<{ label: string; path: string }> = [];
|
|
93
|
+
for (const label of labels) {
|
|
94
|
+
const trimmed = label.trim();
|
|
95
|
+
if (!trimmed) {
|
|
96
|
+
return { kind: "error", reason: "Scope must not include empty path entries." };
|
|
97
|
+
}
|
|
98
|
+
const single = resolveSingleScope(trimmed, cwd);
|
|
99
|
+
if (single.kind === "error") return single;
|
|
100
|
+
resolved.push({ label: trimmed, path: single.path });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const byPath = new Map<string, string>();
|
|
104
|
+
for (const entry of resolved) {
|
|
105
|
+
if (!byPath.has(entry.path)) byPath.set(entry.path, entry.label);
|
|
106
|
+
}
|
|
107
|
+
const paths = [...byPath.keys()];
|
|
108
|
+
const uniqueLabels = paths.map((p) => byPath.get(p) ?? p);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
kind: "ok",
|
|
112
|
+
paths,
|
|
113
|
+
display: uniqueLabels.length > 0 ? uniqueLabels.join(", ") : null,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function resolveSingleScope(scope: string, cwd: string): ScopeResolution {
|
|
64
118
|
const resolved = normalizePath(scope, cwd);
|
|
65
119
|
if (!existsSync(resolved)) {
|
|
66
120
|
return { kind: "error", reason: `Scope path not found: \`${scope}\`` };
|
|
@@ -68,6 +122,20 @@ export function resolveScope(scope: string | undefined, cwd: string): ScopeResol
|
|
|
68
122
|
return { kind: "ok", path: resolved };
|
|
69
123
|
}
|
|
70
124
|
|
|
125
|
+
function splitScopeString(scope: string, cwd: string): string[] {
|
|
126
|
+
const trimmed = scope.trim();
|
|
127
|
+
if (!trimmed) return [];
|
|
128
|
+
|
|
129
|
+
const exact = resolveSingleScope(trimmed, cwd);
|
|
130
|
+
if (exact.kind === "ok") return [trimmed];
|
|
131
|
+
|
|
132
|
+
const parts = trimmed
|
|
133
|
+
.split(/[,;\s]+/)
|
|
134
|
+
.map((part) => part.trim())
|
|
135
|
+
.filter((part) => part.length > 0);
|
|
136
|
+
return parts.length > 1 ? parts : [trimmed];
|
|
137
|
+
}
|
|
138
|
+
|
|
71
139
|
/** Escape regex special characters. */
|
|
72
140
|
export function escapeRegex(s: string): string {
|
|
73
141
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -152,7 +220,7 @@ export class RipgrepAbortedError extends Error {
|
|
|
152
220
|
*/
|
|
153
221
|
export async function runRipgrep(
|
|
154
222
|
pattern: string,
|
|
155
|
-
scopePath: string,
|
|
223
|
+
scopePath: string | readonly string[],
|
|
156
224
|
cwd: string,
|
|
157
225
|
opts?: RipgrepOptions,
|
|
158
226
|
): Promise<RgMatch[]> {
|
|
@@ -166,7 +234,7 @@ export async function runRipgrep(
|
|
|
166
234
|
*/
|
|
167
235
|
export async function runRipgrepDetailed(
|
|
168
236
|
pattern: string,
|
|
169
|
-
scopePath: string,
|
|
237
|
+
scopePath: string | readonly string[],
|
|
170
238
|
cwd: string,
|
|
171
239
|
opts?: RipgrepOptions,
|
|
172
240
|
): Promise<RipgrepRunResult> {
|
|
@@ -195,16 +263,16 @@ export async function runRipgrepDetailed(
|
|
|
195
263
|
};
|
|
196
264
|
case "ok":
|
|
197
265
|
case "nomatch":
|
|
198
|
-
return { matches: parseRgJson(proc.stdout, filter) };
|
|
266
|
+
return { matches: dedupeMatches(parseRgJson(proc.stdout, filter)) };
|
|
199
267
|
case "timeout":
|
|
200
268
|
// Timeout: yield any partial stdout matches with no error surfaced — an
|
|
201
269
|
// improvement over the prior execFileSync path, which discarded partial
|
|
202
270
|
// output on timeout (the timeout error lacked a `status`, so the old
|
|
203
271
|
// handleRipgrepError returned an empty match set).
|
|
204
|
-
return { matches: proc.stdout ? parseRgJson(proc.stdout, filter) : [] };
|
|
272
|
+
return { matches: proc.stdout ? dedupeMatches(parseRgJson(proc.stdout, filter)) : [] };
|
|
205
273
|
case "error":
|
|
206
274
|
return {
|
|
207
|
-
matches: proc.stdout ? parseRgJson(proc.stdout, filter) : [],
|
|
275
|
+
matches: proc.stdout ? dedupeMatches(parseRgJson(proc.stdout, filter)) : [],
|
|
208
276
|
...(proc.stderr.trim() ? { error: proc.stderr.trim() } : {}),
|
|
209
277
|
};
|
|
210
278
|
}
|
|
@@ -212,7 +280,7 @@ export async function runRipgrepDetailed(
|
|
|
212
280
|
|
|
213
281
|
function buildRipgrepArgs(
|
|
214
282
|
pattern: string,
|
|
215
|
-
scopePath: string,
|
|
283
|
+
scopePath: string | readonly string[],
|
|
216
284
|
opts?: { maxMatches?: number; contextLines?: number; literal?: boolean },
|
|
217
285
|
): string[] {
|
|
218
286
|
const args = ["--json", "-m", String(opts?.maxMatches ?? 30)];
|
|
@@ -222,10 +290,15 @@ function buildRipgrepArgs(
|
|
|
222
290
|
if (opts?.literal) {
|
|
223
291
|
args.push("-F");
|
|
224
292
|
}
|
|
225
|
-
args.push("-e", pattern, scopePath);
|
|
293
|
+
args.push("-e", pattern, ...normalizeScopePathArgs(scopePath));
|
|
226
294
|
return args;
|
|
227
295
|
}
|
|
228
296
|
|
|
297
|
+
function normalizeScopePathArgs(scopePath: string | readonly string[]): string[] {
|
|
298
|
+
const paths = Array.isArray(scopePath) ? scopePath : [scopePath];
|
|
299
|
+
return paths.length > 0 ? [...paths] : ["."];
|
|
300
|
+
}
|
|
301
|
+
|
|
229
302
|
/** Discriminated result of a single ripgrep process run (see {@link runRgProcess}). */
|
|
230
303
|
type RgProcessResult =
|
|
231
304
|
| { kind: "ok"; stdout: string; stderr: string; status: number }
|
|
@@ -432,6 +505,18 @@ function parseRgJson(output: string, filterLowSignal: boolean): RgMatch[] {
|
|
|
432
505
|
return matches;
|
|
433
506
|
}
|
|
434
507
|
|
|
508
|
+
function dedupeMatches(matches: RgMatch[]): RgMatch[] {
|
|
509
|
+
const seen = new Set<string>();
|
|
510
|
+
const deduped: RgMatch[] = [];
|
|
511
|
+
for (const match of matches) {
|
|
512
|
+
const key = `${match.file}\u0000${match.line}\u0000${match.text}`;
|
|
513
|
+
if (seen.has(key)) continue;
|
|
514
|
+
seen.add(key);
|
|
515
|
+
deduped.push(match);
|
|
516
|
+
}
|
|
517
|
+
return deduped;
|
|
518
|
+
}
|
|
519
|
+
|
|
435
520
|
/**
|
|
436
521
|
* Minimal interface for a reference-like object with a URI and range start.
|
|
437
522
|
* Used by {@link filterOutDeclaration} to avoid coupling to a specific LspRef type.
|
package/src/extension.ts
CHANGED
|
@@ -38,7 +38,7 @@ export default function codeIntelligenceExtension(
|
|
|
38
38
|
const tsState = createTsAdapterState();
|
|
39
39
|
|
|
40
40
|
// ── Substrate wiring ──────────────────────────────────────────────
|
|
41
|
-
registerLspSettings();
|
|
41
|
+
registerLspSettings(pi);
|
|
42
42
|
registerLspSessionLifecycle(pi, lspState);
|
|
43
43
|
registerLspAwareToolOverrides(pi, lspState);
|
|
44
44
|
registerDiagnosticInjectionHandlers(pi, lspState);
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability adapter — injected dependency for WorkspaceCodeIntelligenceSession.
|
|
3
|
+
*
|
|
4
|
+
* Encapsulates provider access and readiness so the session target
|
|
5
|
+
* workflow can be tested with an in-memory adapter. Two adapters
|
|
6
|
+
* (production and test) justify the seam.
|
|
7
|
+
*
|
|
8
|
+
* @mrclrchtr/supi-code-intelligence — internal, not exported via api.ts
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { SemanticProvider, StructuralProvider } from "@mrclrchtr/supi-code-runtime/api";
|
|
12
|
+
import { getDefaultWorkspaceRuntime } from "@mrclrchtr/supi-code-runtime/api";
|
|
13
|
+
import type { SessionLspServiceState } from "@mrclrchtr/supi-lsp/api";
|
|
14
|
+
import {
|
|
15
|
+
type CodeProvider,
|
|
16
|
+
type CodeProviderState,
|
|
17
|
+
getCodeProviderState,
|
|
18
|
+
} from "../analysis/provider.ts";
|
|
19
|
+
import { ensureSemanticReadiness } from "../analysis/readiness.ts";
|
|
20
|
+
|
|
21
|
+
// ── Interface ─────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Readiness scope for semantic provider gating.
|
|
25
|
+
* `workspace` waits for all servers; `file` waits for a specific file's server.
|
|
26
|
+
*/
|
|
27
|
+
export type ReadinessScope = { kind: "workspace" } | { kind: "file"; file: string };
|
|
28
|
+
|
|
29
|
+
/** Outcome of a readiness wait. */
|
|
30
|
+
export type ReadinessOutcome =
|
|
31
|
+
| { kind: "ready" }
|
|
32
|
+
| { kind: "timeout" }
|
|
33
|
+
| { kind: "unavailable"; reason: string };
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Injected capability adapter.
|
|
37
|
+
*
|
|
38
|
+
* Production adapter reads the global workspace runtime. Test adapter
|
|
39
|
+
* provides semantic/structural providers in memory without global state.
|
|
40
|
+
*/
|
|
41
|
+
export interface CapabilityAdapter {
|
|
42
|
+
/** Get the composite code provider state for a workspace. */
|
|
43
|
+
getProviderState(cwd: string): CodeProviderState;
|
|
44
|
+
|
|
45
|
+
/** Convenience: get the ready composite provider, or null. */
|
|
46
|
+
getProvider(cwd: string): CodeProvider | null;
|
|
47
|
+
|
|
48
|
+
/** Get the raw semantic provider, or null. */
|
|
49
|
+
getSemanticProvider(cwd: string): SemanticProvider | null;
|
|
50
|
+
|
|
51
|
+
/** Get the raw structural provider, or null. */
|
|
52
|
+
getStructuralProvider(cwd: string): StructuralProvider | null;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Wait for semantic (LSP) readiness. Returns a typed outcome so
|
|
56
|
+
* the target workflow can decide whether to proceed, return a
|
|
57
|
+
* timeout note, or return an unavailable result.
|
|
58
|
+
*/
|
|
59
|
+
ensureSemanticReadiness(cwd: string, scope: ReadinessScope): Promise<ReadinessOutcome>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ── Production adapter ────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Production capability adapter that reads from the global workspace
|
|
66
|
+
* runtime. Used in the real pi session.
|
|
67
|
+
*/
|
|
68
|
+
export class WorkspaceCapabilityAdapter implements CapabilityAdapter {
|
|
69
|
+
getProviderState(cwd: string): CodeProviderState {
|
|
70
|
+
return getCodeProviderState(cwd);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getProvider(cwd: string): CodeProvider | null {
|
|
74
|
+
const state = this.getProviderState(cwd);
|
|
75
|
+
return state.kind === "ready" ? state.provider : null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getSemanticProvider(cwd: string): SemanticProvider | null {
|
|
79
|
+
const runtime = getDefaultWorkspaceRuntime();
|
|
80
|
+
const ws = runtime.getWorkspace(cwd);
|
|
81
|
+
if (
|
|
82
|
+
(ws.semantic.state.kind === "ready" || ws.semantic.state.kind === "pending") &&
|
|
83
|
+
ws.semantic.provider !== null
|
|
84
|
+
) {
|
|
85
|
+
return ws.semantic.provider as SemanticProvider;
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getStructuralProvider(cwd: string): StructuralProvider | null {
|
|
91
|
+
const runtime = getDefaultWorkspaceRuntime();
|
|
92
|
+
const ws = runtime.getWorkspace(cwd);
|
|
93
|
+
if (ws.structural.state.kind === "ready" && ws.structural.provider !== null) {
|
|
94
|
+
return ws.structural.provider as StructuralProvider;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async ensureSemanticReadiness(cwd: string, scope: ReadinessScope): Promise<ReadinessOutcome> {
|
|
100
|
+
const result = await ensureSemanticReadiness(cwd, scope);
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Convenience: LSP service state for impact/health consumers still using it directly. */
|
|
105
|
+
getLspService(cwd: string): SessionLspServiceState {
|
|
106
|
+
const state = this.getProviderState(cwd);
|
|
107
|
+
return state.kind === "ready"
|
|
108
|
+
? state.lspService
|
|
109
|
+
: { kind: "unavailable" as const, reason: "No provider" };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ── Test adapter ──────────────────────────────────────────────────────
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* In-memory capability adapter for tests.
|
|
117
|
+
*
|
|
118
|
+
* Pass explicit providers and readiness outcomes without touching
|
|
119
|
+
* the global workspace runtime.
|
|
120
|
+
*/
|
|
121
|
+
export class TestCapabilityAdapter implements CapabilityAdapter {
|
|
122
|
+
readonly #semantic: SemanticProvider | null;
|
|
123
|
+
readonly #structural: StructuralProvider | null;
|
|
124
|
+
readonly #readiness: ReadinessOutcome;
|
|
125
|
+
readonly #lspService: SessionLspServiceState;
|
|
126
|
+
|
|
127
|
+
constructor(options: {
|
|
128
|
+
semantic?: SemanticProvider | null;
|
|
129
|
+
structural?: StructuralProvider | null;
|
|
130
|
+
readiness?: ReadinessOutcome;
|
|
131
|
+
lspService?: SessionLspServiceState;
|
|
132
|
+
}) {
|
|
133
|
+
this.#semantic = options.semantic ?? null;
|
|
134
|
+
this.#structural = options.structural ?? null;
|
|
135
|
+
this.#readiness = options.readiness ?? { kind: "ready" };
|
|
136
|
+
this.#lspService = options.lspService ?? {
|
|
137
|
+
kind: "unavailable" as const,
|
|
138
|
+
reason: "no test LSP",
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
getProviderState(_cwd: string): CodeProviderState {
|
|
143
|
+
if (!this.#semantic && !this.#structural) {
|
|
144
|
+
return { kind: "unavailable", reason: "No providers in test adapter" };
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
kind: "ready",
|
|
148
|
+
provider: this.getProvider(_cwd) as CodeProvider,
|
|
149
|
+
lspService: this.#lspService,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: adapter maps many provider methods; splitting would degrade readability
|
|
154
|
+
getProvider(_cwd: string): CodeProvider | null {
|
|
155
|
+
if (!this.#semantic && !this.#structural) return null;
|
|
156
|
+
return {
|
|
157
|
+
// Semantic pass-through
|
|
158
|
+
references: this.#semantic?.references
|
|
159
|
+
? (...args: Parameters<SemanticProvider["references"]>) =>
|
|
160
|
+
this.#semantic?.references?.(...args)
|
|
161
|
+
: async () => null,
|
|
162
|
+
implementation: this.#semantic?.implementation
|
|
163
|
+
? (...args) => this.#semantic?.implementation?.(...args)
|
|
164
|
+
: async () => null,
|
|
165
|
+
documentSymbols: this.#semantic?.documentSymbols
|
|
166
|
+
? (...args) => this.#semantic?.documentSymbols?.(...args)
|
|
167
|
+
: async () => [],
|
|
168
|
+
workspaceSymbols: this.#semantic?.workspaceSymbols
|
|
169
|
+
? (...args) => this.#semantic?.workspaceSymbols?.(...args)
|
|
170
|
+
: async () => [],
|
|
171
|
+
hover: this.#semantic?.hover ? (...args) => this.#semantic?.hover?.(...args) : undefined,
|
|
172
|
+
definition: this.#semantic?.definition
|
|
173
|
+
? (...args) => this.#semantic?.definition?.(...args)
|
|
174
|
+
: undefined,
|
|
175
|
+
codeActions: this.#semantic?.codeActions
|
|
176
|
+
? (...args) => this.#semantic?.codeActions?.(...args)
|
|
177
|
+
: undefined,
|
|
178
|
+
codeActionTitles: this.#semantic?.codeActionTitles
|
|
179
|
+
? (...args) => this.#semantic?.codeActionTitles?.(...args)
|
|
180
|
+
: undefined,
|
|
181
|
+
rename: this.#semantic?.rename ? (...args) => this.#semantic?.rename?.(...args) : undefined,
|
|
182
|
+
refactor: this.#semantic?.refactor
|
|
183
|
+
? (...args) => this.#semantic?.refactor?.(...args)
|
|
184
|
+
: undefined,
|
|
185
|
+
// Structural pass-through
|
|
186
|
+
calleesAt: this.#structural?.calleesAt
|
|
187
|
+
? (...args) => this.#structural?.calleesAt?.(...args)
|
|
188
|
+
: async () => ({ kind: "unavailable" as const, message: "no test structural" }),
|
|
189
|
+
exports: this.#structural?.exports
|
|
190
|
+
? (...args) => this.#structural?.exports?.(...args)
|
|
191
|
+
: async () => ({ kind: "unavailable" as const, message: "no test structural" }),
|
|
192
|
+
outline: this.#structural?.outline
|
|
193
|
+
? (...args) => this.#structural?.outline?.(...args)
|
|
194
|
+
: async () => ({ kind: "unavailable" as const, message: "no test structural" }),
|
|
195
|
+
imports: this.#structural?.imports
|
|
196
|
+
? (...args) => this.#structural?.imports?.(...args)
|
|
197
|
+
: async () => ({ kind: "unavailable" as const, message: "no test structural" }),
|
|
198
|
+
nodeAt: this.#structural?.nodeAt
|
|
199
|
+
? (...args) => this.#structural?.nodeAt?.(...args)
|
|
200
|
+
: async () => ({ kind: "unavailable" as const, message: "no test structural" }),
|
|
201
|
+
callSites: this.#structural?.callSites
|
|
202
|
+
? (...args) => this.#structural?.callSites?.(...args)
|
|
203
|
+
: async () => ({ kind: "unavailable" as const, message: "no test structural" }),
|
|
204
|
+
} as CodeProvider;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
getSemanticProvider(_cwd: string): SemanticProvider | null {
|
|
208
|
+
return this.#semantic;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
getStructuralProvider(_cwd: string): StructuralProvider | null {
|
|
212
|
+
return this.#structural;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async ensureSemanticReadiness(_cwd: string, _scope: ReadinessScope): Promise<ReadinessOutcome> {
|
|
216
|
+
return this.#readiness;
|
|
217
|
+
}
|
|
218
|
+
}
|
package/src/session/session.ts
CHANGED
|
@@ -24,6 +24,7 @@ import type { LspRuntimeController } from "@mrclrchtr/supi-lsp/api";
|
|
|
24
24
|
import { CoverageWarningState } from "../analysis/coverage/coverage-warnings.ts";
|
|
25
25
|
import type { CodeProvider } from "../analysis/provider.ts";
|
|
26
26
|
import { getCodeProvider } from "../analysis/provider.ts";
|
|
27
|
+
import { type CapabilityAdapter, WorkspaceCapabilityAdapter } from "./capability-adapter.ts";
|
|
27
28
|
import { getPlan, type RefactorPlan, removePlan, storePlan } from "./refactor-plans.ts";
|
|
28
29
|
import {
|
|
29
30
|
getWorkflowTarget,
|
|
@@ -33,11 +34,18 @@ import {
|
|
|
33
34
|
type TargetRegistrationOutput,
|
|
34
35
|
type TargetStoreEntry,
|
|
35
36
|
} from "./target-store.ts";
|
|
37
|
+
import {
|
|
38
|
+
resolveTargetWorkflow,
|
|
39
|
+
type TargetWorkflowInput,
|
|
40
|
+
type TargetWorkflowOutcome,
|
|
41
|
+
type TargetWorkflowPolicy,
|
|
42
|
+
} from "./target-workflow.ts";
|
|
36
43
|
|
|
37
44
|
// ── Re-export types consumed by callers ───────────────────────────────
|
|
38
45
|
|
|
39
46
|
export type { CoverageWarningState } from "../analysis/coverage/coverage-warnings.ts";
|
|
40
47
|
export type { CodeProvider, CodeProviderState } from "../analysis/provider.ts";
|
|
48
|
+
export type { CapabilityAdapter } from "./capability-adapter.ts";
|
|
41
49
|
export type { RefactorPlan } from "./refactor-plans.ts";
|
|
42
50
|
export type {
|
|
43
51
|
TargetLookupResult,
|
|
@@ -45,6 +53,11 @@ export type {
|
|
|
45
53
|
TargetRegistrationOutput,
|
|
46
54
|
TargetStoreEntry,
|
|
47
55
|
} from "./target-store.ts";
|
|
56
|
+
export type {
|
|
57
|
+
TargetWorkflowInput,
|
|
58
|
+
TargetWorkflowOutcome,
|
|
59
|
+
TargetWorkflowPolicy,
|
|
60
|
+
} from "./target-workflow.ts";
|
|
48
61
|
|
|
49
62
|
// ── Target ID expansion result ────────────────────────────────────────
|
|
50
63
|
|
|
@@ -74,6 +87,9 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
74
87
|
/** Canonical workspace directory for this session. */
|
|
75
88
|
readonly cwd: string;
|
|
76
89
|
|
|
90
|
+
/** Injected capability adapter — two adapters (production/test) justify the seam. */
|
|
91
|
+
readonly #capability: CapabilityAdapter;
|
|
92
|
+
|
|
77
93
|
/** Whether the hidden architecture overview has been injected. */
|
|
78
94
|
hasInjectedOverview = false;
|
|
79
95
|
|
|
@@ -100,8 +116,30 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
100
116
|
*/
|
|
101
117
|
tsController: import("@mrclrchtr/supi-tree-sitter/api").TreeSitterRuntimeController | null = null;
|
|
102
118
|
|
|
103
|
-
constructor(cwd: string) {
|
|
119
|
+
constructor(cwd: string, capability?: CapabilityAdapter) {
|
|
104
120
|
this.cwd = cwd;
|
|
121
|
+
this.#capability = capability ?? new WorkspaceCapabilityAdapter();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ── Target workflow (deep seam) ───────────────────────────────────
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Resolve target input into an immutable resolved target.
|
|
128
|
+
*
|
|
129
|
+
* This is the deep module interface. Tool executors call this instead
|
|
130
|
+
* of `expandTargetId` or direct `resolveTarget`/`resolveAnchoredSymbolTarget`
|
|
131
|
+
* calls. Returns typed outcomes — no markdown, no mutated params.
|
|
132
|
+
*/
|
|
133
|
+
async resolveTarget(
|
|
134
|
+
input: TargetWorkflowInput,
|
|
135
|
+
policy: TargetWorkflowPolicy,
|
|
136
|
+
): Promise<TargetWorkflowOutcome> {
|
|
137
|
+
return resolveTargetWorkflow(input, policy, {
|
|
138
|
+
cwd: this.cwd,
|
|
139
|
+
capability: this.#capability,
|
|
140
|
+
lookupTargetId: (id) => this.lookupTargetId(id),
|
|
141
|
+
registerTarget: (inp) => this.registerTarget(inp),
|
|
142
|
+
});
|
|
105
143
|
}
|
|
106
144
|
|
|
107
145
|
// ── Provider access ───────────────────────────────────────────────
|