@mrclrchtr/supi-code-intelligence 1.5.0 → 1.7.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 +42 -24
- package/node_modules/@mrclrchtr/supi-core/package.json +6 -2
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +12 -1
- package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +12 -1
- package/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +116 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +6 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +12 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +12 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +116 -0
- package/node_modules/@mrclrchtr/supi-lsp/package.json +10 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +8 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +79 -190
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +38 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/types.ts +61 -387
- package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +16 -8
- package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/pattern-matcher.ts +11 -184
- package/node_modules/@mrclrchtr/supi-lsp/src/session/lsp-state.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +6 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +12 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +12 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +116 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/LICENSE +21 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/README.md +265 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs +4661 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.cjs.map +7 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js +4605 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.js.map +7 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm +0 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/debug/web-tree-sitter.wasm.map +57 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/package.json +100 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs +4063 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.cjs.map +7 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts +1025 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.cts.map +58 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1025 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +58 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js +4007 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.js.map +7 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm +0 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/web-tree-sitter/web-tree-sitter.wasm.map +55 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +2 -2
- package/package.json +4 -4
- package/src/actions/affected-action.ts +67 -54
- package/src/actions/brief-action.ts +142 -5
- package/src/actions/callees-action.ts +1 -1
- package/src/actions/callers-action.ts +38 -67
- package/src/actions/implementations-action.ts +27 -63
- package/src/actions/map-action.ts +206 -0
- package/src/actions/pattern-action.ts +1 -1
- package/src/api.ts +1 -0
- package/src/brief-focused.ts +5 -5
- package/src/brief.ts +3 -3
- package/src/code-intelligence.ts +6 -75
- package/src/index.ts +1 -0
- package/src/pattern-structured.ts +1 -1
- package/src/prioritization-signals.ts +13 -26
- package/src/query-params.ts +15 -0
- package/src/resolve-target.ts +2 -2
- package/src/search-helpers.ts +2 -2
- package/src/target-resolution.ts +27 -102
- package/src/tool/execute-affected.ts +25 -0
- package/src/tool/execute-brief.ts +25 -0
- package/src/tool/execute-map.ts +32 -0
- package/src/tool/execute-pattern.ts +26 -0
- package/src/tool/execute-relations.ts +48 -0
- package/src/tool/guidance.ts +24 -13
- package/src/tool/register-tools.ts +32 -0
- package/src/tool/tool-specs.ts +184 -0
- package/src/tool/validation.ts +43 -0
- package/src/types.ts +10 -0
- package/src/actions/index-action.ts +0 -187
- package/src/tool/action-specs.ts +0 -66
- package/src/tool-actions.ts +0 -100
|
@@ -1,20 +1,15 @@
|
|
|
1
|
+
import ignore from "ignore";
|
|
2
|
+
|
|
1
3
|
/** Gitignore-style glob pattern matching for path exclusion.
|
|
2
4
|
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Normalize path separators to forward slashes and trim.
|
|
5
|
+
* Delegates to the {@link https://github.com/kaelzhang/node-ignore | ignore} package,
|
|
6
|
+
* which provides battle-tested .gitignore semantics used by ESLint, Prettier, and others.
|
|
7
|
+
*
|
|
8
|
+
* Supports full gitignore syntax: literal names, `*` / `?` wildcards, `**` recursive globs,
|
|
9
|
+
* leading `/` anchored patterns, trailing `/` directory-only patterns, and `!` negation.
|
|
10
|
+
*
|
|
11
|
+
* **Note:** Patterns that start with `#` are treated as comments unless escaped with `\#`.
|
|
14
12
|
*/
|
|
15
|
-
function normalize(p: string): string {
|
|
16
|
-
return p.replaceAll("\\", "/").trim();
|
|
17
|
-
}
|
|
18
13
|
|
|
19
14
|
/**
|
|
20
15
|
* Check whether a project-relative file path matches a gitignore-style glob pattern.
|
|
@@ -24,174 +19,6 @@ function normalize(p: string): string {
|
|
|
24
19
|
* @returns `true` if the file path matches the pattern
|
|
25
20
|
*/
|
|
26
21
|
export function isGlobMatch(filePath: string, pattern: string): boolean {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (!fp || !pat) return false;
|
|
30
|
-
|
|
31
|
-
// Leading / → anchored to root
|
|
32
|
-
const anchored = pat.startsWith("/");
|
|
33
|
-
const noLeadingSlash = anchored ? pat.slice(1) : pat;
|
|
34
|
-
|
|
35
|
-
// Trailing / → directory-only
|
|
36
|
-
const dirOnly = noLeadingSlash.endsWith("/");
|
|
37
|
-
const cleanPat = dirOnly ? noLeadingSlash.slice(0, -1) : noLeadingSlash;
|
|
38
|
-
|
|
39
|
-
if (!cleanPat) return false;
|
|
40
|
-
|
|
41
|
-
return matchGlob(fp, cleanPat, { anchored, dirOnly });
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface MatchOptions {
|
|
45
|
-
anchored: boolean;
|
|
46
|
-
dirOnly: boolean;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Core recursive pattern matching against a multi-segment path.
|
|
51
|
-
*/
|
|
52
|
-
function matchGlob(filePath: string, pattern: string, opts: MatchOptions): boolean {
|
|
53
|
-
// Direct match
|
|
54
|
-
if (!opts.anchored && !opts.dirOnly && filePath === pattern) return true;
|
|
55
|
-
|
|
56
|
-
// Split into segments
|
|
57
|
-
const pathSegments = filePath.split("/");
|
|
58
|
-
const patternSegments = pattern.split("/");
|
|
59
|
-
|
|
60
|
-
// ** recursive glob
|
|
61
|
-
if (pattern.startsWith("**/")) {
|
|
62
|
-
const suffix = pattern.slice(3);
|
|
63
|
-
return (
|
|
64
|
-
matchGlob(filePath, suffix, { ...opts, anchored: false }) ||
|
|
65
|
-
starStarMatch(pathSegments, suffix)
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// prefix/**/suffix bounded recursive glob
|
|
70
|
-
const dstarIdx = pattern.indexOf("/**/");
|
|
71
|
-
if (dstarIdx !== -1) {
|
|
72
|
-
const prefix = pattern.slice(0, dstarIdx);
|
|
73
|
-
const suffix = pattern.slice(dstarIdx + 4);
|
|
74
|
-
return matchBoundedStar(pathSegments, prefix, suffix);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Single-segment patterns
|
|
78
|
-
if (patternSegments.length === 1 && !opts.anchored) {
|
|
79
|
-
return matchSingleSegment(pathSegments, patternSegments[0], opts.dirOnly);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Multi-segment: anchored or unanchored
|
|
83
|
-
if (opts.anchored) {
|
|
84
|
-
return matchSegments(pathSegments, patternSegments, opts.dirOnly);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Unanchored multi-segment: try at each starting position
|
|
88
|
-
return matchUnanchoredSegments(pathSegments, patternSegments, opts.dirOnly);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Match a ** recursive suffix across directory levels.
|
|
93
|
-
*/
|
|
94
|
-
function starStarMatch(segments: string[], suffix: string): boolean {
|
|
95
|
-
for (let i = 0; i < segments.length; i++) {
|
|
96
|
-
const remaining = segments.slice(i).join("/");
|
|
97
|
-
if (matchGlob(remaining, suffix, { anchored: false, dirOnly: false })) return true;
|
|
98
|
-
}
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/** Match prefix plus star-star-slash plus suffix bounded recursive pattern. */
|
|
103
|
-
function matchBoundedStar(segments: string[], prefix: string, suffix: string): boolean {
|
|
104
|
-
// Try to find a split point where left matches prefix and right matches suffix
|
|
105
|
-
for (let i = 1; i < segments.length; i++) {
|
|
106
|
-
const left = segments.slice(0, i).join("/");
|
|
107
|
-
const right = segments.slice(i).join("/");
|
|
108
|
-
if (
|
|
109
|
-
matchGlob(left, prefix, { anchored: false, dirOnly: false }) &&
|
|
110
|
-
matchGlob(right, suffix, { anchored: false, dirOnly: false })
|
|
111
|
-
) {
|
|
112
|
-
return true;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Match a single-segment pattern against path segments.
|
|
120
|
-
*/
|
|
121
|
-
function matchSingleSegment(segments: string[], patternSeg: string, dirOnly: boolean): boolean {
|
|
122
|
-
const hasGlob = patternSeg.includes("*") || patternSeg.includes("?");
|
|
123
|
-
|
|
124
|
-
if (hasGlob) {
|
|
125
|
-
// Glob pattern matches any segment
|
|
126
|
-
return segments.some((seg) => simpleMatch(seg, patternSeg));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Literal segment name
|
|
130
|
-
if (dirOnly) {
|
|
131
|
-
// Match as directory: any segment except the last (file) one
|
|
132
|
-
return segments.slice(0, -1).some((seg) => seg === patternSeg);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Match any segment (file or directory)
|
|
136
|
-
return segments.some((seg) => seg === patternSeg);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Try to match multi-segment pattern at each start position.
|
|
141
|
-
*/
|
|
142
|
-
function matchUnanchoredSegments(segments: string[], pattern: string[], dirOnly: boolean): boolean {
|
|
143
|
-
for (let i = 0; i < segments.length; i++) {
|
|
144
|
-
if (matchSegments(segments.slice(i), pattern, dirOnly)) return true;
|
|
145
|
-
}
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/** Match segments from start. Returns true if all pattern segments match contiguously. */
|
|
150
|
-
function matchSegments(segments: string[], pattern: string[], dirOnly: boolean): boolean {
|
|
151
|
-
if (pattern.length > segments.length) return false;
|
|
152
|
-
|
|
153
|
-
for (let i = 0; i < pattern.length; i++) {
|
|
154
|
-
if (!matchSegmentAtIndex(segments, pattern, i)) return false;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// dirOnly: last matched segment must not be the last path segment
|
|
158
|
-
if (dirOnly && pattern.length === segments.length) return false;
|
|
159
|
-
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** Match a single pattern segment against the corresponding path segment. */
|
|
164
|
-
function matchSegmentAtIndex(segments: string[], pattern: string[], index: number): boolean {
|
|
165
|
-
const patSeg = pattern[index];
|
|
166
|
-
const pathSeg = segments[index];
|
|
167
|
-
|
|
168
|
-
if (patSeg === "**") {
|
|
169
|
-
// ** at end matches all remaining segments
|
|
170
|
-
if (index === pattern.length - 1) return true;
|
|
171
|
-
// Try rest of pattern from various positions
|
|
172
|
-
for (let j = index; j < segments.length; j++) {
|
|
173
|
-
if (matchSegments(segments.slice(j), pattern.slice(index + 1), false)) return true;
|
|
174
|
-
}
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return simpleMatch(pathSeg, patSeg);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Match a single path segment against a single pattern segment.
|
|
183
|
-
* Supports `*` (any chars except `/`) and `?` (single char).
|
|
184
|
-
*/
|
|
185
|
-
function simpleMatch(segment: string, pattern: string): boolean {
|
|
186
|
-
if (pattern === "*") return true;
|
|
187
|
-
if (pattern === segment) return true;
|
|
188
|
-
if (!pattern.includes("*") && !pattern.includes("?")) return false;
|
|
189
|
-
|
|
190
|
-
// Convert pattern to simple regex
|
|
191
|
-
const regexStr = pattern
|
|
192
|
-
.replace(/[.+^${}()|[\]\\]/g, "\\$&")
|
|
193
|
-
.replace(/\*/g, "[^/]*")
|
|
194
|
-
.replace(/\?/g, "[^/]");
|
|
195
|
-
|
|
196
|
-
return new RegExp(`^${regexStr}$`).test(segment);
|
|
22
|
+
if (!filePath || !pattern) return false;
|
|
23
|
+
return ignore().add(pattern).ignores(filePath);
|
|
197
24
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Extracted from lsp.ts to keep file sizes within Biome limits.
|
|
3
3
|
|
|
4
4
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
5
|
-
import type { DetectedProjectServer, ProjectServerInfo } from "../config/
|
|
5
|
+
import type { DetectedProjectServer, ProjectServerInfo } from "../config/server-config.ts";
|
|
6
6
|
import type { LspManager } from "../manager/manager.ts";
|
|
7
7
|
import { LSP_TOOL_NAMES } from "../tool/names.ts";
|
|
8
8
|
import type { LspInspectorState } from "../ui/ui.ts";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Prompt guidance and tool descriptions for the expert LSP toolset.
|
|
2
2
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import type { ProjectServerInfo } from "../config/
|
|
4
|
+
import type { ProjectServerInfo } from "../config/server-config.ts";
|
|
5
5
|
import { LSP_LOOKUP_TOOL, type LspToolName } from "./names.ts";
|
|
6
6
|
import { LSP_TOOL_DEFINITION_SPECS } from "./tool-specs.ts";
|
|
7
7
|
|
|
@@ -103,7 +103,7 @@ export const LSP_TOOL_DEFINITION_SPECS = [
|
|
|
103
103
|
basePromptGuidelines: [
|
|
104
104
|
'Use lsp_lookup with `kind: "hover"` for semantic type or symbol information at a known `file`, `line`, and `character`.',
|
|
105
105
|
'Use lsp_lookup with `kind: "definition"`, `"references"`, or `"implementation"` for semantic navigation at a known position.',
|
|
106
|
-
"Use lsp_lookup after
|
|
106
|
+
"Use lsp_lookup after code_brief, code_map, or tree_sitter has already narrowed the target file and position.",
|
|
107
107
|
],
|
|
108
108
|
parameters: LookupParameters,
|
|
109
109
|
run: (service, cwd, params) =>
|
package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "SuPi core — shared infrastructure for SuPi extensions (XML context tags, config system)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
],
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"@earendil-works/pi-coding-agent": "*",
|
|
23
|
-
"@earendil-works/pi-tui": "*"
|
|
23
|
+
"@earendil-works/pi-tui": "*",
|
|
24
|
+
"typebox": "*"
|
|
24
25
|
},
|
|
25
26
|
"peerDependenciesMeta": {
|
|
26
27
|
"@earendil-works/pi-coding-agent": {
|
|
@@ -28,6 +29,9 @@
|
|
|
28
29
|
},
|
|
29
30
|
"@earendil-works/pi-tui": {
|
|
30
31
|
"optional": true
|
|
32
|
+
},
|
|
33
|
+
"typebox": {
|
|
34
|
+
"optional": true
|
|
31
35
|
}
|
|
32
36
|
},
|
|
33
37
|
"main": "src/api.ts",
|
package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// supi-core — shared infrastructure for SuPi extensions.
|
|
2
2
|
// Provides XML context tag wrapping, unified config system, context-message utilities,
|
|
3
|
-
//
|
|
3
|
+
// settings registry for supi-wide TUI settings, and a shared tool-spec/registration framework.
|
|
4
4
|
|
|
5
5
|
export type { SupiConfigLocation, SupiConfigOptions } from "./config/config.ts";
|
|
6
6
|
export {
|
|
7
7
|
loadSupiConfig,
|
|
8
8
|
loadSupiConfigForScope,
|
|
9
|
+
readJsonFile,
|
|
9
10
|
removeSupiConfigKey,
|
|
10
11
|
writeSupiConfig,
|
|
11
12
|
} from "./config/config.ts";
|
|
@@ -83,3 +84,13 @@ export {
|
|
|
83
84
|
signalWaiting,
|
|
84
85
|
WAITING_SYMBOL,
|
|
85
86
|
} from "./terminal.ts";
|
|
87
|
+
export type { SuiPiToolPromptSurface, SuiPiToolSpec, ToolExecuteFn } from "./tool-framework.ts";
|
|
88
|
+
export {
|
|
89
|
+
CharacterParam,
|
|
90
|
+
derivePromptSurface,
|
|
91
|
+
FileParam,
|
|
92
|
+
LineParam,
|
|
93
|
+
MaxResultsParam,
|
|
94
|
+
registerSuiPiTools,
|
|
95
|
+
SymbolParam,
|
|
96
|
+
} from "./tool-framework.ts";
|
|
@@ -20,7 +20,7 @@ function getProjectConfigPath(cwd: string): string {
|
|
|
20
20
|
return path.join(cwd, PROJECT_CONFIG_DIR, CONFIG_FILE);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function readJsonFile(filePath: string): Record<string, unknown> | null {
|
|
23
|
+
export function readJsonFile(filePath: string): Record<string, unknown> | null {
|
|
24
24
|
let content: string;
|
|
25
25
|
try {
|
|
26
26
|
content = fs.readFileSync(filePath, "utf-8");
|
package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// supi-core — shared infrastructure for SuPi extensions.
|
|
2
2
|
// Provides XML context tag wrapping, unified config system, context-message utilities,
|
|
3
|
-
//
|
|
3
|
+
// settings registry for supi-wide TUI settings, and a shared tool-spec/registration framework.
|
|
4
4
|
|
|
5
5
|
export type { SupiConfigLocation, SupiConfigOptions } from "./config/config.ts";
|
|
6
6
|
export {
|
|
7
7
|
loadSupiConfig,
|
|
8
8
|
loadSupiConfigForScope,
|
|
9
|
+
readJsonFile,
|
|
9
10
|
removeSupiConfigKey,
|
|
10
11
|
writeSupiConfig,
|
|
11
12
|
} from "./config/config.ts";
|
|
@@ -83,3 +84,13 @@ export {
|
|
|
83
84
|
signalWaiting,
|
|
84
85
|
WAITING_SYMBOL,
|
|
85
86
|
} from "./terminal.ts";
|
|
87
|
+
export type { SuiPiToolPromptSurface, SuiPiToolSpec, ToolExecuteFn } from "./tool-framework.ts";
|
|
88
|
+
export {
|
|
89
|
+
CharacterParam,
|
|
90
|
+
derivePromptSurface,
|
|
91
|
+
FileParam,
|
|
92
|
+
LineParam,
|
|
93
|
+
MaxResultsParam,
|
|
94
|
+
registerSuiPiTools,
|
|
95
|
+
SymbolParam,
|
|
96
|
+
} from "./tool-framework.ts";
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Shared tool framework for SuPi extensions.
|
|
2
|
+
//
|
|
3
|
+
// Provides a standard ToolSpec→PromptSurface→registerTool pipeline so
|
|
4
|
+
// individual packages do not duplicate spec interfaces, guidance derivation,
|
|
5
|
+
// registration loops, or common TypeBox parameter schemas.
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
AgentToolResult,
|
|
9
|
+
AgentToolUpdateCallback,
|
|
10
|
+
ExtensionAPI,
|
|
11
|
+
ExtensionContext,
|
|
12
|
+
} from "@earendil-works/pi-coding-agent";
|
|
13
|
+
import { type TSchema, Type } from "typebox";
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Types
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/** Minimum contract for a SuPi tool definition. */
|
|
20
|
+
export interface SuiPiToolSpec {
|
|
21
|
+
name: string;
|
|
22
|
+
label: string;
|
|
23
|
+
description: string;
|
|
24
|
+
promptSnippet: string;
|
|
25
|
+
promptGuidelines: string[];
|
|
26
|
+
parameters: TSchema;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Derived prompt surface — what pi flattens into the system prompt. */
|
|
30
|
+
export interface SuiPiToolPromptSurface {
|
|
31
|
+
description: string;
|
|
32
|
+
promptSnippet: string;
|
|
33
|
+
promptGuidelines: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Guidance derivation
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Static derivation: copies spec fields into a prompt surface.
|
|
42
|
+
*
|
|
43
|
+
* Packages that need dynamic guidance (e.g. server-coverage injection) should
|
|
44
|
+
* build their own surfaces, optionally starting from the output of this helper.
|
|
45
|
+
*/
|
|
46
|
+
export function derivePromptSurface(spec: SuiPiToolSpec): SuiPiToolPromptSurface {
|
|
47
|
+
return {
|
|
48
|
+
description: spec.description,
|
|
49
|
+
promptSnippet: spec.promptSnippet,
|
|
50
|
+
promptGuidelines: [...spec.promptGuidelines],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Registration
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
// biome-ignore lint/complexity/useMaxParams: matches pi ToolDefinition.execute signature
|
|
59
|
+
export type ToolExecuteFn = (
|
|
60
|
+
toolCallId: string,
|
|
61
|
+
params: unknown,
|
|
62
|
+
signal: AbortSignal | undefined,
|
|
63
|
+
onUpdate: AgentToolUpdateCallback<Record<string, unknown>> | undefined,
|
|
64
|
+
ctx: ExtensionContext,
|
|
65
|
+
) => Promise<AgentToolResult<Record<string, unknown>>>;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Register a set of tools from specs + pre-derived surfaces.
|
|
69
|
+
*
|
|
70
|
+
* `createExecute` receives the spec and returns a pi-compatible execute
|
|
71
|
+
* function. This keeps execute-logic package-local while the framework owns
|
|
72
|
+
* the declarative surface and registration boilerplate.
|
|
73
|
+
*/
|
|
74
|
+
export function registerSuiPiTools(
|
|
75
|
+
pi: ExtensionAPI,
|
|
76
|
+
specs: readonly SuiPiToolSpec[],
|
|
77
|
+
surfaces: Record<string, SuiPiToolPromptSurface>,
|
|
78
|
+
createExecute: (spec: SuiPiToolSpec) => ToolExecuteFn,
|
|
79
|
+
): void {
|
|
80
|
+
for (const spec of specs) {
|
|
81
|
+
const surface = surfaces[spec.name];
|
|
82
|
+
pi.registerTool({
|
|
83
|
+
name: spec.name,
|
|
84
|
+
label: spec.label,
|
|
85
|
+
description: surface?.description ?? spec.description,
|
|
86
|
+
promptSnippet: surface?.promptSnippet ?? spec.promptSnippet,
|
|
87
|
+
promptGuidelines: surface?.promptGuidelines ?? [...spec.promptGuidelines],
|
|
88
|
+
parameters: spec.parameters,
|
|
89
|
+
execute: createExecute(spec),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Shared parameter builders
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
/** File path (relative or absolute). */
|
|
99
|
+
export const FileParam = Type.String({ description: "File path (relative or absolute)" });
|
|
100
|
+
|
|
101
|
+
/** 1-based line number. */
|
|
102
|
+
export const LineParam = Type.Number({ description: "1-based line number", minimum: 1 });
|
|
103
|
+
|
|
104
|
+
/** 1-based character column (UTF-16). */
|
|
105
|
+
export const CharacterParam = Type.Number({
|
|
106
|
+
description: "1-based column number (UTF-16)",
|
|
107
|
+
minimum: 1,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
/** Symbol name for discovery-based resolution. */
|
|
111
|
+
export const SymbolParam = Type.String({
|
|
112
|
+
description: "Symbol name for discovery-based resolution",
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
/** Maximum results to return. */
|
|
116
|
+
export const MaxResultsParam = Type.Number({ description: "Maximum results to return" });
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 Max Brunsfeld
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|