@mrclrchtr/supi-code-intelligence 1.4.0 → 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/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +2 -0
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +2 -0
- 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/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +2 -0
- 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-lsp/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +2 -16
- package/node_modules/@mrclrchtr/supi-lsp/src/session/service-registry.ts +5 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +15 -75
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +13 -166
- package/node_modules/@mrclrchtr/supi-lsp/src/tool/tool-specs.ts +248 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/utils.ts +5 -34
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +18 -6
- 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 +5 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +5 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime.ts +3 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/service-registry.ts +30 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +16 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/action-specs.ts +92 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +12 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +111 -61
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +13 -2
- package/package.json +4 -4
- package/src/actions/brief-action.ts +5 -5
- package/src/code-intelligence.ts +3 -10
- package/src/pattern-structured.ts +1 -1
- package/src/providers/structural-provider.ts +15 -3
- package/src/search-helpers.ts +4 -15
- package/src/tool/action-specs.ts +66 -0
- package/src/tool/guidance.ts +4 -7
- package/src/tool-actions.ts +23 -40
|
@@ -49,6 +49,7 @@ export {
|
|
|
49
49
|
redactDebugData,
|
|
50
50
|
resetDebugRegistry,
|
|
51
51
|
} from "./debug-registry.ts";
|
|
52
|
+
export { fileToUri, resolveToolPath, stripToolPathPrefix, uriToFile } from "./path-utils.ts";
|
|
52
53
|
export type { KnownRootEntry } from "./project-roots.ts";
|
|
53
54
|
export {
|
|
54
55
|
buildKnownRootsMap,
|
|
@@ -63,6 +64,7 @@ export {
|
|
|
63
64
|
sortRootsBySpecificity,
|
|
64
65
|
walkProject,
|
|
65
66
|
} from "./project-roots.ts";
|
|
67
|
+
export { createRegistry, createSessionStateRegistry } from "./registry-utils.ts";
|
|
66
68
|
export { getActiveBranchEntries } from "./session-utils.ts";
|
|
67
69
|
export { registerSettingsCommand } from "./settings/settings-command.ts";
|
|
68
70
|
export type { SettingsScope, SettingsSection } from "./settings/settings-registry.ts";
|
|
@@ -49,6 +49,7 @@ export {
|
|
|
49
49
|
redactDebugData,
|
|
50
50
|
resetDebugRegistry,
|
|
51
51
|
} from "./debug-registry.ts";
|
|
52
|
+
export { fileToUri, resolveToolPath, stripToolPathPrefix, uriToFile } from "./path-utils.ts";
|
|
52
53
|
export type { KnownRootEntry } from "./project-roots.ts";
|
|
53
54
|
export {
|
|
54
55
|
buildKnownRootsMap,
|
|
@@ -63,6 +64,7 @@ export {
|
|
|
63
64
|
sortRootsBySpecificity,
|
|
64
65
|
walkProject,
|
|
65
66
|
} from "./project-roots.ts";
|
|
67
|
+
export { createRegistry, createSessionStateRegistry } from "./registry-utils.ts";
|
|
66
68
|
export { getActiveBranchEntries } from "./session-utils.ts";
|
|
67
69
|
export { registerSettingsCommand } from "./settings/settings-command.ts";
|
|
68
70
|
export type { SettingsScope, SettingsSection } from "./settings/settings-registry.ts";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
|
|
3
|
+
/** Strip pi's optional leading `@` file-path prefix from a tool input. */
|
|
4
|
+
export function stripToolPathPrefix(target: string): string {
|
|
5
|
+
return target.startsWith("@") ? target.slice(1) : target;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a tool-style file path from a session cwd.
|
|
10
|
+
*
|
|
11
|
+
* Built-in pi file tools accept a leading `@` prefix in path arguments, so
|
|
12
|
+
* shared SuPi path helpers normalize that prefix before resolving relative
|
|
13
|
+
* paths.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveToolPath(cwd: string, target: string): string {
|
|
16
|
+
return path.resolve(cwd, stripToolPathPrefix(target));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Convert a file path to a file:// URI. */
|
|
20
|
+
export function fileToUri(filePath: string): string {
|
|
21
|
+
const resolved = path.resolve(filePath);
|
|
22
|
+
if (process.platform === "win32") {
|
|
23
|
+
return `file:///${resolved.replace(/\\/g, "/")}`;
|
|
24
|
+
}
|
|
25
|
+
return `file://${resolved}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Convert a file:// URI to a file path. */
|
|
29
|
+
export function uriToFile(uri: string): string {
|
|
30
|
+
if (!uri.startsWith("file://")) return uri;
|
|
31
|
+
let filePath = decodeURIComponent(uri.slice(7));
|
|
32
|
+
if (
|
|
33
|
+
process.platform === "win32" &&
|
|
34
|
+
filePath.startsWith("/") &&
|
|
35
|
+
/^[A-Za-z]:/.test(filePath.slice(1))
|
|
36
|
+
) {
|
|
37
|
+
filePath = filePath.slice(1);
|
|
38
|
+
}
|
|
39
|
+
return filePath;
|
|
40
|
+
}
|
|
@@ -5,8 +5,20 @@
|
|
|
5
5
|
// Without this, each symlink path gets its own module copy and its own Map,
|
|
6
6
|
// so registrations from one instance are invisible to consumers in another.
|
|
7
7
|
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
|
|
8
10
|
const SYMBOL_PREFIX = "@mrclrchtr/supi-core/";
|
|
9
11
|
|
|
12
|
+
function getGlobalRegistryMap<T>(name: string): Map<string, T> {
|
|
13
|
+
const key = Symbol.for(SYMBOL_PREFIX + name);
|
|
14
|
+
let map = (globalThis as Record<symbol, unknown>)[key] as Map<string, T> | undefined;
|
|
15
|
+
if (!map) {
|
|
16
|
+
map = new Map<string, T>();
|
|
17
|
+
(globalThis as Record<symbol, unknown>)[key] = map;
|
|
18
|
+
}
|
|
19
|
+
return map;
|
|
20
|
+
}
|
|
21
|
+
|
|
10
22
|
/**
|
|
11
23
|
* Create a named registry backed by `globalThis` + `Symbol.for`.
|
|
12
24
|
*
|
|
@@ -18,16 +30,7 @@ const SYMBOL_PREFIX = "@mrclrchtr/supi-core/";
|
|
|
18
30
|
* @returns An object with `register`, `getAll`, and `clear` functions.
|
|
19
31
|
*/
|
|
20
32
|
export function createRegistry<T>(name: string) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const getMap = (): Map<string, T> => {
|
|
24
|
-
let map = (globalThis as Record<symbol, unknown>)[key] as Map<string, T> | undefined;
|
|
25
|
-
if (!map) {
|
|
26
|
-
map = new Map<string, T>();
|
|
27
|
-
(globalThis as Record<symbol, unknown>)[key] = map;
|
|
28
|
-
}
|
|
29
|
-
return map;
|
|
30
|
-
};
|
|
33
|
+
const getMap = (): Map<string, T> => getGlobalRegistryMap<T>(name);
|
|
31
34
|
|
|
32
35
|
return {
|
|
33
36
|
/**
|
|
@@ -52,3 +55,32 @@ export function createRegistry<T>(name: string) {
|
|
|
52
55
|
},
|
|
53
56
|
};
|
|
54
57
|
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create a named session-state registry keyed by normalized cwd.
|
|
61
|
+
*
|
|
62
|
+
* This helper is intended for session-scoped runtime services that should be
|
|
63
|
+
* shared across duplicate jiti module instances while keeping package-specific
|
|
64
|
+
* state unions and convenience wrappers local to the calling package.
|
|
65
|
+
*/
|
|
66
|
+
export function createSessionStateRegistry<TState>(name: string) {
|
|
67
|
+
const getMap = (): Map<string, TState> => getGlobalRegistryMap<TState>(name);
|
|
68
|
+
const normalizeCwd = (cwd: string): string => path.resolve(cwd);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
/** Get the current state for one session cwd. */
|
|
72
|
+
get: (cwd: string): TState | undefined => {
|
|
73
|
+
return getMap().get(normalizeCwd(cwd));
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/** Store the current state for one session cwd. */
|
|
77
|
+
set: (cwd: string, state: TState): void => {
|
|
78
|
+
getMap().set(normalizeCwd(cwd), state);
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
/** Clear the current state for one session cwd. */
|
|
82
|
+
clear: (cwd: string): void => {
|
|
83
|
+
getMap().delete(normalizeCwd(cwd));
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -49,6 +49,7 @@ export {
|
|
|
49
49
|
redactDebugData,
|
|
50
50
|
resetDebugRegistry,
|
|
51
51
|
} from "./debug-registry.ts";
|
|
52
|
+
export { fileToUri, resolveToolPath, stripToolPathPrefix, uriToFile } from "./path-utils.ts";
|
|
52
53
|
export type { KnownRootEntry } from "./project-roots.ts";
|
|
53
54
|
export {
|
|
54
55
|
buildKnownRootsMap,
|
|
@@ -63,6 +64,7 @@ export {
|
|
|
63
64
|
sortRootsBySpecificity,
|
|
64
65
|
walkProject,
|
|
65
66
|
} from "./project-roots.ts";
|
|
67
|
+
export { createRegistry, createSessionStateRegistry } from "./registry-utils.ts";
|
|
66
68
|
export { getActiveBranchEntries } from "./session-utils.ts";
|
|
67
69
|
export { registerSettingsCommand } from "./settings/settings-command.ts";
|
|
68
70
|
export type { SettingsScope, SettingsSection } from "./settings/settings-registry.ts";
|
|
@@ -49,6 +49,7 @@ export {
|
|
|
49
49
|
redactDebugData,
|
|
50
50
|
resetDebugRegistry,
|
|
51
51
|
} from "./debug-registry.ts";
|
|
52
|
+
export { fileToUri, resolveToolPath, stripToolPathPrefix, uriToFile } from "./path-utils.ts";
|
|
52
53
|
export type { KnownRootEntry } from "./project-roots.ts";
|
|
53
54
|
export {
|
|
54
55
|
buildKnownRootsMap,
|
|
@@ -63,6 +64,7 @@ export {
|
|
|
63
64
|
sortRootsBySpecificity,
|
|
64
65
|
walkProject,
|
|
65
66
|
} from "./project-roots.ts";
|
|
67
|
+
export { createRegistry, createSessionStateRegistry } from "./registry-utils.ts";
|
|
66
68
|
export { getActiveBranchEntries } from "./session-utils.ts";
|
|
67
69
|
export { registerSettingsCommand } from "./settings/settings-command.ts";
|
|
68
70
|
export type { SettingsScope, SettingsSection } from "./settings/settings-registry.ts";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
|
|
3
|
+
/** Strip pi's optional leading `@` file-path prefix from a tool input. */
|
|
4
|
+
export function stripToolPathPrefix(target: string): string {
|
|
5
|
+
return target.startsWith("@") ? target.slice(1) : target;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a tool-style file path from a session cwd.
|
|
10
|
+
*
|
|
11
|
+
* Built-in pi file tools accept a leading `@` prefix in path arguments, so
|
|
12
|
+
* shared SuPi path helpers normalize that prefix before resolving relative
|
|
13
|
+
* paths.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveToolPath(cwd: string, target: string): string {
|
|
16
|
+
return path.resolve(cwd, stripToolPathPrefix(target));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Convert a file path to a file:// URI. */
|
|
20
|
+
export function fileToUri(filePath: string): string {
|
|
21
|
+
const resolved = path.resolve(filePath);
|
|
22
|
+
if (process.platform === "win32") {
|
|
23
|
+
return `file:///${resolved.replace(/\\/g, "/")}`;
|
|
24
|
+
}
|
|
25
|
+
return `file://${resolved}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Convert a file:// URI to a file path. */
|
|
29
|
+
export function uriToFile(uri: string): string {
|
|
30
|
+
if (!uri.startsWith("file://")) return uri;
|
|
31
|
+
let filePath = decodeURIComponent(uri.slice(7));
|
|
32
|
+
if (
|
|
33
|
+
process.platform === "win32" &&
|
|
34
|
+
filePath.startsWith("/") &&
|
|
35
|
+
/^[A-Za-z]:/.test(filePath.slice(1))
|
|
36
|
+
) {
|
|
37
|
+
filePath = filePath.slice(1);
|
|
38
|
+
}
|
|
39
|
+
return filePath;
|
|
40
|
+
}
|
package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/registry-utils.ts
CHANGED
|
@@ -5,8 +5,20 @@
|
|
|
5
5
|
// Without this, each symlink path gets its own module copy and its own Map,
|
|
6
6
|
// so registrations from one instance are invisible to consumers in another.
|
|
7
7
|
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
|
|
8
10
|
const SYMBOL_PREFIX = "@mrclrchtr/supi-core/";
|
|
9
11
|
|
|
12
|
+
function getGlobalRegistryMap<T>(name: string): Map<string, T> {
|
|
13
|
+
const key = Symbol.for(SYMBOL_PREFIX + name);
|
|
14
|
+
let map = (globalThis as Record<symbol, unknown>)[key] as Map<string, T> | undefined;
|
|
15
|
+
if (!map) {
|
|
16
|
+
map = new Map<string, T>();
|
|
17
|
+
(globalThis as Record<symbol, unknown>)[key] = map;
|
|
18
|
+
}
|
|
19
|
+
return map;
|
|
20
|
+
}
|
|
21
|
+
|
|
10
22
|
/**
|
|
11
23
|
* Create a named registry backed by `globalThis` + `Symbol.for`.
|
|
12
24
|
*
|
|
@@ -18,16 +30,7 @@ const SYMBOL_PREFIX = "@mrclrchtr/supi-core/";
|
|
|
18
30
|
* @returns An object with `register`, `getAll`, and `clear` functions.
|
|
19
31
|
*/
|
|
20
32
|
export function createRegistry<T>(name: string) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const getMap = (): Map<string, T> => {
|
|
24
|
-
let map = (globalThis as Record<symbol, unknown>)[key] as Map<string, T> | undefined;
|
|
25
|
-
if (!map) {
|
|
26
|
-
map = new Map<string, T>();
|
|
27
|
-
(globalThis as Record<symbol, unknown>)[key] = map;
|
|
28
|
-
}
|
|
29
|
-
return map;
|
|
30
|
-
};
|
|
33
|
+
const getMap = (): Map<string, T> => getGlobalRegistryMap<T>(name);
|
|
31
34
|
|
|
32
35
|
return {
|
|
33
36
|
/**
|
|
@@ -52,3 +55,32 @@ export function createRegistry<T>(name: string) {
|
|
|
52
55
|
},
|
|
53
56
|
};
|
|
54
57
|
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create a named session-state registry keyed by normalized cwd.
|
|
61
|
+
*
|
|
62
|
+
* This helper is intended for session-scoped runtime services that should be
|
|
63
|
+
* shared across duplicate jiti module instances while keeping package-specific
|
|
64
|
+
* state unions and convenience wrappers local to the calling package.
|
|
65
|
+
*/
|
|
66
|
+
export function createSessionStateRegistry<TState>(name: string) {
|
|
67
|
+
const getMap = (): Map<string, TState> => getGlobalRegistryMap<TState>(name);
|
|
68
|
+
const normalizeCwd = (cwd: string): string => path.resolve(cwd);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
/** Get the current state for one session cwd. */
|
|
72
|
+
get: (cwd: string): TState | undefined => {
|
|
73
|
+
return getMap().get(normalizeCwd(cwd));
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/** Store the current state for one session cwd. */
|
|
77
|
+
set: (cwd: string, state: TState): void => {
|
|
78
|
+
getMap().set(normalizeCwd(cwd), state);
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
/** Clear the current state for one session cwd. */
|
|
82
|
+
clear: (cwd: string): void => {
|
|
83
|
+
getMap().delete(normalizeCwd(cwd));
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-lsp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "SuPi LSP extension — Language Server Protocol integration for pi",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"typescript": "6.0.3",
|
|
25
|
-
"@mrclrchtr/supi-core": "1.
|
|
25
|
+
"@mrclrchtr/supi-core": "1.5.0"
|
|
26
26
|
},
|
|
27
27
|
"bundledDependencies": [
|
|
28
28
|
"@mrclrchtr/supi-core"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { LspClient } from "../client/client.ts";
|
|
2
2
|
import type { ProjectServerInfo } from "../config/types.ts";
|
|
3
3
|
import { displayRelativeFilePath } from "../summary.ts";
|
|
4
|
+
import { getSupportedLspServerActions } from "../tool/tool-specs.ts";
|
|
4
5
|
|
|
5
6
|
interface ProjectServerInfoInput {
|
|
6
7
|
serverName: string;
|
|
@@ -28,22 +29,7 @@ export function buildProjectServerInfo(
|
|
|
28
29
|
root: input.root,
|
|
29
30
|
fileTypes: input.fileTypes,
|
|
30
31
|
status,
|
|
31
|
-
supportedActions:
|
|
32
|
+
supportedActions: getSupportedLspServerActions(input.client?.serverCapabilities),
|
|
32
33
|
openFiles: input.client?.openFiles.map((file) => displayRelativeFilePath(file, cwd)) ?? [],
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
-
function getSupportedActions(capabilities: LspClient["serverCapabilities"] | undefined): string[] {
|
|
37
|
-
if (!capabilities) return [];
|
|
38
|
-
|
|
39
|
-
const actions: string[] = ["diagnostics [optional file]"];
|
|
40
|
-
if (capabilities.hoverProvider) actions.push("hover(file,line,char)");
|
|
41
|
-
if (capabilities.definitionProvider) actions.push("definition(file,line,char)");
|
|
42
|
-
if (capabilities.referencesProvider) actions.push("references(file,line,char)");
|
|
43
|
-
if (capabilities.implementationProvider) actions.push("implementation(file,line,char)");
|
|
44
|
-
if (capabilities.documentSymbolProvider) actions.push("symbols(file)");
|
|
45
|
-
if (capabilities.workspaceSymbolProvider) actions.push("workspace_symbols(query)");
|
|
46
|
-
if (capabilities.renameProvider) actions.push("rename(file,line,char,newName)");
|
|
47
|
-
if (capabilities.codeActionProvider) actions.push("code_actions(file,line,char)");
|
|
48
|
-
return actions;
|
|
49
|
-
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Peer extensions can import `getSessionLspService` from the package root
|
|
3
3
|
// to reuse the active LSP runtime without starting duplicate servers.
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import { createSessionStateRegistry } from "@mrclrchtr/supi-core/api";
|
|
6
6
|
import type {
|
|
7
7
|
CodeAction,
|
|
8
8
|
Diagnostic,
|
|
@@ -189,34 +189,18 @@ export class SessionLspService {
|
|
|
189
189
|
|
|
190
190
|
// ── Registry ──────────────────────────────────────────────────────────
|
|
191
191
|
|
|
192
|
-
const REGISTRY_KEY = Symbol.for("@mrclrchtr/supi-lsp/session-registry");
|
|
193
192
|
const WAIT_INTERVAL_MS = 25;
|
|
194
|
-
|
|
195
|
-
function getRegistry(): Map<string, SessionLspServiceState> {
|
|
196
|
-
const globalScope = globalThis as typeof globalThis & Record<symbol, unknown>;
|
|
197
|
-
const existing = globalScope[REGISTRY_KEY];
|
|
198
|
-
if (existing instanceof Map) return existing as Map<string, SessionLspServiceState>;
|
|
199
|
-
|
|
200
|
-
const registry = new Map<string, SessionLspServiceState>();
|
|
201
|
-
globalScope[REGISTRY_KEY] = registry;
|
|
202
|
-
return registry;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function normalizeCwd(cwd: string): string {
|
|
206
|
-
return path.resolve(cwd);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const registry = getRegistry();
|
|
193
|
+
const registry = createSessionStateRegistry<SessionLspServiceState>("supi-lsp/session-registry");
|
|
210
194
|
|
|
211
195
|
/** Publish the LSP service state for a session cwd. */
|
|
212
196
|
export function setSessionLspServiceState(cwd: string, state: SessionLspServiceState): void {
|
|
213
|
-
registry.set(
|
|
197
|
+
registry.set(cwd, state);
|
|
214
198
|
}
|
|
215
199
|
|
|
216
200
|
/** Acquire the LSP service state for a session cwd. */
|
|
217
201
|
export function getSessionLspService(cwd: string): SessionLspServiceState {
|
|
218
202
|
return (
|
|
219
|
-
registry.get(
|
|
203
|
+
registry.get(cwd) ?? {
|
|
220
204
|
kind: "unavailable",
|
|
221
205
|
reason: "No LSP session initialized for this workspace",
|
|
222
206
|
}
|
|
@@ -241,5 +225,5 @@ export async function waitForSessionLspService(
|
|
|
241
225
|
|
|
242
226
|
/** Remove the LSP service state for a session cwd. */
|
|
243
227
|
export function clearSessionLspService(cwd: string): void {
|
|
244
|
-
registry.
|
|
228
|
+
registry.clear(cwd);
|
|
245
229
|
}
|
|
@@ -2,15 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import type { ProjectServerInfo } from "../config/types.ts";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
LSP_DOCUMENT_SYMBOLS_TOOL,
|
|
8
|
-
LSP_LOOKUP_TOOL,
|
|
9
|
-
LSP_RECOVER_TOOL,
|
|
10
|
-
LSP_REFACTOR_TOOL,
|
|
11
|
-
LSP_WORKSPACE_SYMBOLS_TOOL,
|
|
12
|
-
type LspToolName,
|
|
13
|
-
} from "./names.ts";
|
|
5
|
+
import { LSP_LOOKUP_TOOL, type LspToolName } from "./names.ts";
|
|
6
|
+
import { LSP_TOOL_DEFINITION_SPECS } from "./tool-specs.ts";
|
|
14
7
|
|
|
15
8
|
export interface LspToolPromptSurface {
|
|
16
9
|
description: string;
|
|
@@ -20,33 +13,6 @@ export interface LspToolPromptSurface {
|
|
|
20
13
|
|
|
21
14
|
export type LspToolPromptSurfaceMap = Record<LspToolName, LspToolPromptSurface>;
|
|
22
15
|
|
|
23
|
-
const LOOKUP_GUIDELINES = [
|
|
24
|
-
'Use lsp_lookup with `kind: "hover"` for semantic type or symbol information at a known `file`, `line`, and `character`.',
|
|
25
|
-
'Use lsp_lookup with `kind: "definition"`, `"references"`, or `"implementation"` for semantic navigation at a known position.',
|
|
26
|
-
"Use lsp_lookup after code_intel or tree_sitter has already narrowed the target file and position.",
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
const DOCUMENT_SYMBOL_GUIDELINES = [
|
|
30
|
-
"Use lsp_document_symbols(file) for semantic declarations in one supported file.",
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
const WORKSPACE_SYMBOL_GUIDELINES = [
|
|
34
|
-
"Use lsp_workspace_symbols(query) for semantic symbol-name lookup across the current project.",
|
|
35
|
-
];
|
|
36
|
-
|
|
37
|
-
const DIAGNOSTICS_GUIDELINES = [
|
|
38
|
-
"Use lsp_diagnostics(file?) when you need current diagnostics for one file or a workspace-level summary.",
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
const REFACTOR_GUIDELINES = [
|
|
42
|
-
'Use lsp_refactor with `kind: "rename"` for semantic rename planning at a known `file`, `line`, and `character`.',
|
|
43
|
-
'Use lsp_refactor with `kind: "code_actions"` for semantic fixes or refactors at a known position.',
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
const RECOVER_GUIDELINES = [
|
|
47
|
-
"Use lsp_recover() when diagnostics look stale after workspace-level changes or generated-file updates.",
|
|
48
|
-
];
|
|
49
|
-
|
|
50
16
|
export const defaultLspToolPromptSurfaces = buildLspToolPromptSurfaces([], ".");
|
|
51
17
|
|
|
52
18
|
export function buildLspToolPromptSurfaces(
|
|
@@ -55,45 +21,19 @@ export function buildLspToolPromptSurfaces(
|
|
|
55
21
|
): LspToolPromptSurfaceMap {
|
|
56
22
|
const coverageGuidelines = buildCoverageGuidelines(servers, cwd);
|
|
57
23
|
|
|
58
|
-
return
|
|
59
|
-
[
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
},
|
|
72
|
-
[LSP_WORKSPACE_SYMBOLS_TOOL]: {
|
|
73
|
-
description:
|
|
74
|
-
"Language Server Protocol workspace symbols tool — semantic symbol-name lookup across the current project. Use lsp_workspace_symbols to find declarations by name before opening a specific file.",
|
|
75
|
-
promptSnippet: "lsp_workspace_symbols — semantic symbol-name lookup across the project",
|
|
76
|
-
promptGuidelines: WORKSPACE_SYMBOL_GUIDELINES,
|
|
77
|
-
},
|
|
78
|
-
[LSP_DIAGNOSTICS_TOOL]: {
|
|
79
|
-
description:
|
|
80
|
-
"Language Server Protocol diagnostics tool — current diagnostics for one file or a workspace summary. Use lsp_diagnostics for semantic compiler or language-server issues instead of guessing from text alone.",
|
|
81
|
-
promptSnippet: "lsp_diagnostics — current diagnostics for one file or the workspace",
|
|
82
|
-
promptGuidelines: DIAGNOSTICS_GUIDELINES,
|
|
83
|
-
},
|
|
84
|
-
[LSP_REFACTOR_TOOL]: {
|
|
85
|
-
description:
|
|
86
|
-
"Language Server Protocol refactor tool — semantic rename planning and code actions at a known file position. Use lsp_refactor when you need language-server-backed edits or quick-fix suggestions.",
|
|
87
|
-
promptSnippet: "lsp_refactor — semantic rename planning and code actions at a known position",
|
|
88
|
-
promptGuidelines: REFACTOR_GUIDELINES,
|
|
89
|
-
},
|
|
90
|
-
[LSP_RECOVER_TOOL]: {
|
|
91
|
-
description:
|
|
92
|
-
"Language Server Protocol recover tool — refresh diagnostics after workspace changes and stale language-server state. Use lsp_recover when new files, generated types, or config updates leave diagnostics out of sync.",
|
|
93
|
-
promptSnippet: "lsp_recover — refresh stale diagnostics after workspace changes",
|
|
94
|
-
promptGuidelines: RECOVER_GUIDELINES,
|
|
95
|
-
},
|
|
96
|
-
};
|
|
24
|
+
return Object.fromEntries(
|
|
25
|
+
LSP_TOOL_DEFINITION_SPECS.map((spec) => [
|
|
26
|
+
spec.name,
|
|
27
|
+
{
|
|
28
|
+
description: spec.description,
|
|
29
|
+
promptSnippet: spec.promptSnippet,
|
|
30
|
+
promptGuidelines:
|
|
31
|
+
"includeCoverageGuidelines" in spec && spec.includeCoverageGuidelines
|
|
32
|
+
? [...spec.basePromptGuidelines, ...coverageGuidelines]
|
|
33
|
+
: [...spec.basePromptGuidelines],
|
|
34
|
+
} satisfies LspToolPromptSurface,
|
|
35
|
+
]),
|
|
36
|
+
) as LspToolPromptSurfaceMap;
|
|
97
37
|
}
|
|
98
38
|
|
|
99
39
|
function buildCoverageGuidelines(servers: ProjectServerInfo[], cwd: string): string[] {
|