@mrclrchtr/supi-lsp 3.2.0 → 4.0.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 +72 -62
- package/node_modules/@mrclrchtr/supi-code-runtime/README.md +8 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -4
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts +0 -4
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +3 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts +0 -4
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/llm.ts +0 -10
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +19 -15
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +10 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +19 -29
- package/node_modules/@mrclrchtr/supi-code-runtime/src/index.ts +7 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/query-result.ts +42 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +15 -10
- package/node_modules/@mrclrchtr/supi-core/package.json +2 -4
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +0 -4
- package/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +3 -2
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +0 -4
- package/node_modules/@mrclrchtr/supi-core/src/llm.ts +0 -10
- package/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +19 -15
- package/package.json +4 -5
- package/src/api.ts +9 -9
- package/src/client/client.ts +70 -41
- package/src/client/transport.ts +16 -13
- package/src/config/config.ts +2 -2
- package/src/config/lsp-settings.ts +0 -2
- package/src/index.ts +6 -6
- package/src/manager/manager-diagnostics.ts +5 -95
- package/src/manager/manager-workspace-recovery.ts +4 -3
- package/src/manager/manager-workspace-symbol.ts +44 -6
- package/src/manager/manager.ts +47 -65
- package/src/provider/lsp-semantic-provider.ts +132 -79
- package/src/provider/refactor-planning.ts +6 -14
- package/src/session/readiness.ts +38 -0
- package/src/session/runtime-controller.ts +87 -75
- package/src/session/runtime-registration.ts +5 -5
- package/src/session/{service-registry.ts → runtime-registry.ts} +163 -71
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +0 -31
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/substrate-types.ts +0 -11
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/types.ts +0 -2
- package/node_modules/@mrclrchtr/supi-core/src/abort-utils.ts +0 -31
- package/node_modules/@mrclrchtr/supi-core/src/substrate-types.ts +0 -11
- package/node_modules/@mrclrchtr/supi-core/src/types.ts +0 -2
- package/src/diagnostics/diagnostic-augmentation.ts +0 -82
- package/src/diagnostics/diagnostic-context.ts +0 -116
- package/src/diagnostics/diagnostic-display.ts +0 -69
- package/src/manager/capability-index.ts +0 -24
- package/src/manager/client-pool.ts +0 -33
- package/src/manager/diagnostic-store.ts +0 -51
- package/src/manager/manager-stale-resync.ts +0 -47
- package/src/manager/recovery-coordinator.ts +0 -37
- package/src/manager/workspace-router.ts +0 -44
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
Language Server Protocol runtime library for the [pi coding agent](https://github.com/earendil-works/pi).
|
|
12
12
|
|
|
13
|
-
This is
|
|
13
|
+
This package is library-only. It registers no model-callable tools; `@mrclrchtr/supi-code-intelligence` owns the public `code_*` family.
|
|
14
14
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
@@ -18,90 +18,100 @@ This is a **library-only** package — it has no pi extension surface and does n
|
|
|
18
18
|
npm install @mrclrchtr/supi-lsp
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
## What
|
|
21
|
+
## What it provides
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
- `LspRuntimeController` for workspace lifecycle and status
|
|
24
|
+
- `WorkspaceLspRuntime` for routing, readiness, semantic operations, tracked files, diagnostics, and recovery
|
|
25
|
+
- explicit ready, pending, inactive, disabled, and unavailable registry states
|
|
26
|
+
- a `SemanticProvider` adapter for `supi-code-runtime`
|
|
27
|
+
- precise rename and code-action edit conversion
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
- LSP client lifecycle, transport, and workspace routing
|
|
27
|
-
- diagnostics collection, stale-diagnostic recovery, and summaries
|
|
28
|
-
- a shared `SemanticProvider` adapter for the workspace runtime
|
|
29
|
-
- operation-aware semantic refactor planning for first-wave precise text-edit operations
|
|
29
|
+
Clients, `LspManager`, and the default runtime implementation remain internal.
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
## Runtime split
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
- `update_imports` → precise organize-imports/source actions only
|
|
35
|
-
- `delete_dead_code` → precise quickfix/refactor-rewrite actions only
|
|
36
|
-
- `rename_file` / `move_file` → explicit unavailable results for now
|
|
33
|
+
`LspRuntimeController` owns:
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
- language-server detection and startup
|
|
36
|
+
- shutdown
|
|
37
|
+
- settings and missing-server inventory
|
|
38
|
+
- publishing workspace runtime state
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
`WorkspaceLspRuntime` owns:
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
- hover, definition, references, implementations, symbols, rename, and code actions
|
|
43
|
+
- file/workspace readiness waits
|
|
44
|
+
- tracked-file lifecycle and workspace change notifications
|
|
45
|
+
- diagnostics, summaries, refresh, and recovery
|
|
46
|
+
- project-server inventory and file support checks
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
This separation keeps lifecycle/status distinct from workspace operations.
|
|
45
49
|
|
|
46
|
-
|
|
50
|
+
## Example
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
```ts
|
|
53
|
+
import { getWorkspaceLspRuntime, toLspPosition } from "@mrclrchtr/supi-lsp/api";
|
|
54
|
+
|
|
55
|
+
const state = getWorkspaceLspRuntime("/project");
|
|
56
|
+
if (state.kind === "ready") {
|
|
57
|
+
const definitions = await state.runtime.definition(
|
|
58
|
+
"src/index.ts",
|
|
59
|
+
toLspPosition(6, 11),
|
|
60
|
+
);
|
|
61
|
+
if (definitions.kind === "completed") {
|
|
62
|
+
// `data: null` is a successful no-definition observation.
|
|
63
|
+
console.log(definitions.data);
|
|
56
64
|
}
|
|
57
|
-
|
|
65
|
+
}
|
|
66
|
+
```
|
|
58
67
|
|
|
59
|
-
|
|
68
|
+
Runtime methods use raw 0-based LSP positions. `toLspPosition()` converts user-facing 1-based coordinates. Read-only semantic and diagnostic methods return `CodeQueryResult<T>` so completed empty protocol responses remain distinct from partial or unavailable requests. A ready runtime owner may contain only lazy routes: workspace semantic readiness requires at least one active ready client, while file readiness requires the routed client for that file to start successfully. Empty client sets and failed routes are unavailable, not vacuously ready.
|
|
60
69
|
|
|
61
|
-
|
|
70
|
+
## Startup performance
|
|
62
71
|
|
|
63
|
-
|
|
72
|
+
Detected servers start concurrently. In a polyglot workspace, disable unneeded languages in `.pi/supi/config.json` or `~/.pi/agent/supi/config.json`:
|
|
64
73
|
|
|
65
|
-
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"lsp": {
|
|
77
|
+
"servers": {
|
|
78
|
+
"python": { "enabled": false },
|
|
79
|
+
"rust": { "enabled": false }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
66
84
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
diagnostic capabilities into the shared workspace runtime.
|
|
85
|
+
The old `lsp.enabled` and `lsp.active` settings are deprecated and ignored. If every server definition is disabled, the controller publishes an explicit `disabled` runtime state instead of an empty `ready` runtime. When a ready owner has no active client yet, it stays published for lazy routing while semantic capability remains pending.
|
|
86
|
+
|
|
87
|
+
## Architecture
|
|
71
88
|
|
|
72
89
|
```text
|
|
73
|
-
supi-code-runtime
|
|
74
|
-
|
|
75
|
-
supi-lsp
|
|
76
|
-
|
|
77
|
-
supi-code-intelligence
|
|
90
|
+
supi-code-runtime canonical contracts + capability broker
|
|
91
|
+
↑
|
|
92
|
+
supi-lsp semantic lifecycle + Workspace LSP runtime
|
|
93
|
+
↑
|
|
94
|
+
supi-code-intelligence Workspace session + public code_* tools
|
|
78
95
|
```
|
|
79
96
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
97
|
+
The private `DefaultWorkspaceLspRuntime` is the single operational seam. It normalizes
|
|
98
|
+
paths and coordinates readiness, semantic requests, tracked files, diagnostics, recovery,
|
|
99
|
+
and owner-controlled shutdown around the package-internal manager. Clients and the manager
|
|
100
|
+
remain hidden from consumers.
|
|
84
101
|
|
|
85
|
-
|
|
102
|
+
See [`docs/adr/0016-workspace-lsp-runtime-interface.md`](../../docs/adr/0016-workspace-lsp-runtime-interface.md).
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
import { getSessionLspService, toLspPosition } from "@mrclrchtr/supi-lsp/api";
|
|
89
|
-
|
|
90
|
-
const state = getSessionLspService("/project");
|
|
91
|
-
if (state.kind === "ready") {
|
|
92
|
-
const defs = await state.service.definition("src/index.ts", toLspPosition(6, 11));
|
|
93
|
-
}
|
|
94
|
-
```
|
|
104
|
+
## Package exports
|
|
95
105
|
|
|
96
|
-
|
|
106
|
+
- `@mrclrchtr/supi-lsp/api` — runtime/controller/config types and registry operations
|
|
107
|
+
- `@mrclrchtr/supi-lsp/provider/lsp-semantic-provider` — semantic provider adapter
|
|
97
108
|
|
|
98
109
|
## Source
|
|
99
110
|
|
|
100
|
-
- `src/client/` —
|
|
101
|
-
- `src/config/` — server
|
|
102
|
-
- `src/diagnostics/` — stale diagnostics
|
|
103
|
-
- `src/manager/` —
|
|
104
|
-
- `src/provider
|
|
105
|
-
- `src/session
|
|
106
|
-
- `src/
|
|
107
|
-
- `src/index.ts` — package-root re-export surface
|
|
111
|
+
- `src/client/` — protocol client, transport, refresh, and requests
|
|
112
|
+
- `src/config/` — server configuration and protocol types
|
|
113
|
+
- `src/diagnostics/` — stale diagnostics and workspace sentinels
|
|
114
|
+
- `src/manager/` — package-internal server pool and routing, diagnostic, and recovery mechanics
|
|
115
|
+
- `src/provider/` — semantic and refactor adapters
|
|
116
|
+
- `src/session/runtime-controller.ts` — lifecycle/status
|
|
117
|
+
- `src/session/runtime-registry.ts` — `WorkspaceLspRuntime` and registry
|
|
@@ -8,6 +8,14 @@ This is a **library-only package** — it has no pi extension surface, no user-f
|
|
|
8
8
|
|
|
9
9
|
- `@mrclrchtr/supi-code-runtime/api` — shared canonical types, capability interfaces, workspace runtime registry, and typed request context
|
|
10
10
|
|
|
11
|
+
Read-only provider methods return `CodeQueryResult<T>`:
|
|
12
|
+
|
|
13
|
+
- `completed` — collection completed; `data` may be empty or `null`
|
|
14
|
+
- `partial` — usable data was collected, but one or more provider branches failed
|
|
15
|
+
- `unavailable` — no result was established; includes a reason
|
|
16
|
+
|
|
17
|
+
This keeps successful zero-result facts distinct from routing, transport, and provider failures.
|
|
18
|
+
|
|
11
19
|
## License
|
|
12
20
|
|
|
13
21
|
MIT
|
package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "SuPi core — shared infrastructure for SuPi extensions (XML context tags, config system)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -50,7 +50,6 @@
|
|
|
50
50
|
},
|
|
51
51
|
"main": "src/api.ts",
|
|
52
52
|
"exports": {
|
|
53
|
-
"./abort-utils": "./src/abort-utils.ts",
|
|
54
53
|
"./api": "./src/api.ts",
|
|
55
54
|
"./config": "./src/config.ts",
|
|
56
55
|
"./context": "./src/context.ts",
|
|
@@ -71,7 +70,6 @@
|
|
|
71
70
|
"./status-spinner": "./src/status-spinner.ts",
|
|
72
71
|
"./terminal": "./src/terminal.ts",
|
|
73
72
|
"./tool-framework": "./src/tool-framework.ts",
|
|
74
|
-
"./prompt-surface": "./src/prompt-surface.ts"
|
|
75
|
-
"./types": "./src/types.ts"
|
|
73
|
+
"./prompt-surface": "./src/prompt-surface.ts"
|
|
76
74
|
}
|
|
77
75
|
}
|
package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/api.ts
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
// For lighter imports, use one of the domain subpaths directly
|
|
7
7
|
// (e.g. @mrclrchtr/supi-core/config, @mrclrchtr/supi-core/context).
|
|
8
8
|
|
|
9
|
-
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
10
|
-
export * from "./abort-utils.ts";
|
|
11
9
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
12
10
|
export * from "./config.ts";
|
|
13
11
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
@@ -42,5 +40,3 @@ export * from "./status-spinner.ts";
|
|
|
42
40
|
export * from "./terminal.ts";
|
|
43
41
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
44
42
|
export * from "./tool-framework.ts";
|
|
45
|
-
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
46
|
-
export * from "./types.ts";
|
|
@@ -22,14 +22,15 @@ export interface EvidenceBadgeInput {
|
|
|
22
22
|
* |------------------------------------------------------|---------------------------------------|
|
|
23
23
|
* | shown=12, total=12, omitted=0, label="references" | `12 references` |
|
|
24
24
|
* | shown=8, total=20, omitted=12, label="symbols" | `8 of 20 symbols (12 omitted)` |
|
|
25
|
-
* | shown=5,
|
|
25
|
+
* | shown=5, total=null, omitted=2, reason="timeout" | `5 matches (2 collected omitted; more may exist — timeout)` |
|
|
26
26
|
*/
|
|
27
27
|
export function formatEvidenceBadge(input: EvidenceBadgeInput): string {
|
|
28
28
|
const { shownCount, totalCount, omittedCount, partialReason, label } = input;
|
|
29
29
|
|
|
30
30
|
if (totalCount === null) {
|
|
31
31
|
const reasonSuffix = partialReason ? ` — ${partialReason}` : "";
|
|
32
|
-
|
|
32
|
+
const omittedPrefix = (omittedCount ?? 0) > 0 ? `${omittedCount} collected omitted; ` : "";
|
|
33
|
+
return `${shownCount} ${label} (${omittedPrefix}more may exist${reasonSuffix})`;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
if (omittedCount !== null && omittedCount > 0) {
|
package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/index.ts
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
// For lighter imports, use one of the domain subpaths directly
|
|
7
7
|
// (e.g. @mrclrchtr/supi-core/config, @mrclrchtr/supi-core/context).
|
|
8
8
|
|
|
9
|
-
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
10
|
-
export * from "./abort-utils.ts";
|
|
11
9
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
12
10
|
export * from "./config.ts";
|
|
13
11
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
@@ -36,5 +34,3 @@ export * from "./status-spinner.ts";
|
|
|
36
34
|
export * from "./terminal.ts";
|
|
37
35
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
38
36
|
export * from "./tool-framework.ts";
|
|
39
|
-
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
40
|
-
export * from "./types.ts";
|
package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/llm.ts
CHANGED
|
@@ -24,16 +24,6 @@ export interface WithRetryOptions {
|
|
|
24
24
|
onRetry?: (attempt: number, delayMs: number) => void;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
* Attempt an async operation with retries and exponential backoff.
|
|
29
|
-
*
|
|
30
|
-
* If the signal is already aborted on entry, the operation is skipped entirely.
|
|
31
|
-
* If the signal aborts during a delay, the delay is cancelled immediately.
|
|
32
|
-
*
|
|
33
|
-
* @param fn - The async operation to retry.
|
|
34
|
-
* @param options - Optional configuration for retries, backoff, signal, and callbacks.
|
|
35
|
-
* @returns The result on success, or `null` if all attempts fail or the signal aborts.
|
|
36
|
-
*/
|
|
37
27
|
/**
|
|
38
28
|
* Create a promise that resolves after `ms` milliseconds, or rejects if
|
|
39
29
|
* the signal fires before the timeout elapses.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
2
3
|
|
|
3
4
|
/** Strip pi's optional leading `@` file-path prefix from a tool input. */
|
|
4
5
|
export function stripToolPathPrefix(target: string): string {
|
|
@@ -16,25 +17,28 @@ export function resolveToolPath(cwd: string, target: string): string {
|
|
|
16
17
|
return path.resolve(cwd, stripToolPathPrefix(target));
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Convert a file path to a file:// URI.
|
|
22
|
+
*
|
|
23
|
+
* Uses Node's `pathToFileURL` to produce a standards-compliant URI with
|
|
24
|
+
* proper percent-encoding of spaces, hashes, and other special characters.
|
|
25
|
+
*/
|
|
20
26
|
export function fileToUri(filePath: string): string {
|
|
21
|
-
|
|
22
|
-
if (process.platform === "win32") {
|
|
23
|
-
return `file:///${resolved.replace(/\\/g, "/")}`;
|
|
24
|
-
}
|
|
25
|
-
return `file://${resolved}`;
|
|
27
|
+
return pathToFileURL(filePath).href;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Convert a file:// URI to a file path.
|
|
32
|
+
*
|
|
33
|
+
* Uses Node's `fileURLToPath` for standards-compliant decoding. Non-file
|
|
34
|
+
* URIs are passed through unchanged so consumers (such as LSP diagnostic
|
|
35
|
+
* handling) remain compatible with non-file URI schemes.
|
|
36
|
+
*/
|
|
29
37
|
export function uriToFile(uri: string): string {
|
|
30
38
|
if (!uri.startsWith("file://")) return uri;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/^[A-Za-z]:/.test(filePath.slice(1))
|
|
36
|
-
) {
|
|
37
|
-
filePath = filePath.slice(1);
|
|
39
|
+
try {
|
|
40
|
+
return fileURLToPath(uri);
|
|
41
|
+
} catch {
|
|
42
|
+
return uri;
|
|
38
43
|
}
|
|
39
|
-
return filePath;
|
|
40
44
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-code-runtime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "SuPi code-runtime — shared workspace context, capability contracts, and canonical types for the code-understanding stack",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"!__tests__"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@mrclrchtr/supi-core": "
|
|
32
|
+
"@mrclrchtr/supi-core": "4.0.0"
|
|
33
33
|
},
|
|
34
34
|
"bundledDependencies": [
|
|
35
35
|
"@mrclrchtr/supi-core"
|
|
@@ -15,6 +15,14 @@ export type {
|
|
|
15
15
|
StructuralProvider,
|
|
16
16
|
StructuralResult,
|
|
17
17
|
} from "./capability/types.ts";
|
|
18
|
+
export type { CodeQueryResult } from "./query-result.ts";
|
|
19
|
+
// Shared query-result constructors and contract
|
|
20
|
+
export {
|
|
21
|
+
completedCodeQuery,
|
|
22
|
+
mapCodeQueryResult,
|
|
23
|
+
partialCodeQuery,
|
|
24
|
+
unavailableCodeQuery,
|
|
25
|
+
} from "./query-result.ts";
|
|
18
26
|
// Shared canonical types
|
|
19
27
|
export type {
|
|
20
28
|
CalleeDepth,
|
|
@@ -25,7 +33,9 @@ export type {
|
|
|
25
33
|
CodeResult,
|
|
26
34
|
CodeSymbol,
|
|
27
35
|
ConfidenceMode,
|
|
36
|
+
DeclarationNesting,
|
|
28
37
|
DisambiguationCandidate,
|
|
38
|
+
DocumentCodeSymbol,
|
|
29
39
|
ExportData,
|
|
30
40
|
FileEdit,
|
|
31
41
|
ImportData,
|
|
@@ -37,7 +47,6 @@ export type {
|
|
|
37
47
|
SourceRange,
|
|
38
48
|
WorkspaceEdit,
|
|
39
49
|
} from "./types.ts";
|
|
40
|
-
export { normalizeRefactorOperation } from "./types.ts";
|
|
41
50
|
export type { WorkspaceContext } from "./workspace/context.ts";
|
|
42
51
|
// Workspace context
|
|
43
52
|
export { createWorkspaceContext } from "./workspace/context.ts";
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* tree-sitter) advertise what they can do.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { CodeQueryResult } from "../query-result.ts";
|
|
7
8
|
import type {
|
|
8
9
|
CalleeDepth,
|
|
9
10
|
CalleesData,
|
|
@@ -12,6 +13,7 @@ import type {
|
|
|
12
13
|
CodePosition,
|
|
13
14
|
CodeResult,
|
|
14
15
|
CodeSymbol,
|
|
16
|
+
DocumentCodeSymbol,
|
|
15
17
|
ExportData,
|
|
16
18
|
ImportData,
|
|
17
19
|
NodeAtData,
|
|
@@ -44,32 +46,30 @@ export type CapabilityState =
|
|
|
44
46
|
/**
|
|
45
47
|
* Semantic analysis capability backed by a language server (LSP).
|
|
46
48
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
+
* Every read query preserves whether collection completed, completed only
|
|
50
|
+
* partially, or was unavailable. Successful empty arrays and protocol-level
|
|
51
|
+
* null values are completed observations rather than capability failures.
|
|
49
52
|
*/
|
|
50
53
|
export interface SemanticProvider {
|
|
51
|
-
references(filePath: string, position: CodePosition): Promise<CodeLocation[]
|
|
52
|
-
implementation(
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
references(filePath: string, position: CodePosition): Promise<CodeQueryResult<CodeLocation[]>>;
|
|
55
|
+
implementation(
|
|
56
|
+
filePath: string,
|
|
57
|
+
position: CodePosition,
|
|
58
|
+
): Promise<CodeQueryResult<CodeLocation[]>>;
|
|
59
|
+
documentSymbols(filePath: string): Promise<CodeQueryResult<DocumentCodeSymbol[]>>;
|
|
60
|
+
workspaceSymbols(query: string): Promise<CodeQueryResult<CodeSymbol[]>>;
|
|
55
61
|
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
* the symbol at the given position. When the provider cannot produce
|
|
59
|
-
* definition info, returns `null`.
|
|
60
|
-
*/
|
|
61
|
-
definition?(filePath: string, position: CodePosition): Promise<CodeLocation[] | null>;
|
|
62
|
+
/** Optional definition capability with explicit completed-empty semantics. */
|
|
63
|
+
definition?(filePath: string, position: CodePosition): Promise<CodeQueryResult<CodeLocation[]>>;
|
|
62
64
|
|
|
63
65
|
/**
|
|
64
|
-
* Optional hover capability.
|
|
65
|
-
*
|
|
66
|
-
* provider cannot produce hover info (unavailable, unsupported file,
|
|
67
|
-
* no result at the given position), returns `null`.
|
|
66
|
+
* Optional hover capability. A completed `null` data value means the
|
|
67
|
+
* provider successfully found no hover at the requested point.
|
|
68
68
|
*/
|
|
69
69
|
hover?(
|
|
70
70
|
filePath: string,
|
|
71
71
|
position: CodePosition,
|
|
72
|
-
): Promise<{ contents: string; range?: SourceRange } | null
|
|
72
|
+
): Promise<CodeQueryResult<{ contents: string; range?: SourceRange } | null>>;
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Optional operation-aware refactor capability.
|
|
@@ -85,8 +85,8 @@ export interface SemanticProvider {
|
|
|
85
85
|
* Optional rename capability. When present, the provider supports
|
|
86
86
|
* precise semantic symbol-rename operations.
|
|
87
87
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
88
|
+
* This remains a lower-level substrate helper for providers that expose
|
|
89
|
+
* symbol rename independently of their general refactor planner.
|
|
90
90
|
*/
|
|
91
91
|
rename?(file: string, position: CodePosition, newName: string): Promise<RefactorResult>;
|
|
92
92
|
|
|
@@ -97,16 +97,6 @@ export interface SemanticProvider {
|
|
|
97
97
|
* Kept as a low-level substrate helper and for lightweight introspection.
|
|
98
98
|
*/
|
|
99
99
|
codeActions?(file: string, position: CodePosition): Promise<RefactorResult[]>;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Optional lightweight code action titles for display purposes.
|
|
103
|
-
* Returns simplified title/kind pairs at the given position.
|
|
104
|
-
* When the provider cannot produce code actions, returns `null`.
|
|
105
|
-
*/
|
|
106
|
-
codeActionTitles?(
|
|
107
|
-
file: string,
|
|
108
|
-
position: CodePosition,
|
|
109
|
-
): Promise<Array<{ title: string; kind?: string }> | null>;
|
|
110
100
|
}
|
|
111
101
|
|
|
112
102
|
/**
|
|
@@ -12,9 +12,12 @@ export type {
|
|
|
12
12
|
CapabilityState,
|
|
13
13
|
CodeLocation,
|
|
14
14
|
CodePosition,
|
|
15
|
+
CodeQueryResult,
|
|
15
16
|
CodeResult,
|
|
16
17
|
CodeSymbol,
|
|
17
18
|
ConfidenceMode,
|
|
19
|
+
DeclarationNesting,
|
|
20
|
+
DocumentCodeSymbol,
|
|
18
21
|
ExportData,
|
|
19
22
|
ImportData,
|
|
20
23
|
NodeAtData,
|
|
@@ -29,8 +32,11 @@ export type {
|
|
|
29
32
|
WorkspaceContext,
|
|
30
33
|
} from "./api.ts";
|
|
31
34
|
export {
|
|
35
|
+
completedCodeQuery,
|
|
32
36
|
createWorkspaceContext,
|
|
33
37
|
getDefaultWorkspaceRuntime,
|
|
34
|
-
|
|
38
|
+
mapCodeQueryResult,
|
|
39
|
+
partialCodeQuery,
|
|
40
|
+
unavailableCodeQuery,
|
|
35
41
|
WorkspaceRuntime,
|
|
36
42
|
} from "./api.ts";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of a read-only code-provider query.
|
|
3
|
+
*
|
|
4
|
+
* `completed` includes successful empty observations, such as an empty
|
|
5
|
+
* reference list or a protocol-level null hover. `partial` preserves usable
|
|
6
|
+
* data when a multi-provider query could not complete every branch.
|
|
7
|
+
* `unavailable` means the query did not establish a result.
|
|
8
|
+
*/
|
|
9
|
+
export type CodeQueryResult<T> =
|
|
10
|
+
| { readonly kind: "completed"; readonly data: T }
|
|
11
|
+
| { readonly kind: "partial"; readonly data: T; readonly reason: string }
|
|
12
|
+
| { readonly kind: "unavailable"; readonly reason: string };
|
|
13
|
+
|
|
14
|
+
/** Construct a successfully completed code-query result, including empty data. */
|
|
15
|
+
export function completedCodeQuery<T>(data: T): CodeQueryResult<T> {
|
|
16
|
+
return { kind: "completed", data };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Construct a usable but incomplete code-query result. */
|
|
20
|
+
export function partialCodeQuery<T>(data: T, reason: string): CodeQueryResult<T> {
|
|
21
|
+
return { kind: "partial", data, reason };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Construct a code-query result that could not be established. */
|
|
25
|
+
export function unavailableCodeQuery<T = never>(reason: string): CodeQueryResult<T> {
|
|
26
|
+
return { kind: "unavailable", reason };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Map completed or partial query data while preserving its availability state. */
|
|
30
|
+
export function mapCodeQueryResult<T, U>(
|
|
31
|
+
result: CodeQueryResult<T>,
|
|
32
|
+
map: (data: T) => U,
|
|
33
|
+
): CodeQueryResult<U> {
|
|
34
|
+
switch (result.kind) {
|
|
35
|
+
case "completed":
|
|
36
|
+
return completedCodeQuery(map(result.data));
|
|
37
|
+
case "partial":
|
|
38
|
+
return partialCodeQuery(map(result.data), result.reason);
|
|
39
|
+
case "unavailable":
|
|
40
|
+
return unavailableCodeQuery(result.reason);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -34,6 +34,9 @@ export interface SymbolAnchor {
|
|
|
34
34
|
character: number;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/** Provider-backed nesting evidence for a declaration reported within one document. */
|
|
38
|
+
export type DeclarationNesting = "top-level" | "nested" | "unknown";
|
|
39
|
+
|
|
37
40
|
/**
|
|
38
41
|
* A discovered symbol / declaration.
|
|
39
42
|
*
|
|
@@ -51,9 +54,21 @@ export interface CodeSymbol {
|
|
|
51
54
|
file: string;
|
|
52
55
|
declarationAnchor: SymbolAnchor;
|
|
53
56
|
nameAnchor?: SymbolAnchor;
|
|
57
|
+
/** Named symbolic container when reported; absence does not prove top-level nesting. */
|
|
54
58
|
container?: string | null;
|
|
55
59
|
}
|
|
56
60
|
|
|
61
|
+
/**
|
|
62
|
+
* A document-scoped declaration with explicit hierarchy evidence.
|
|
63
|
+
*
|
|
64
|
+
* `unknown` means the provider returned a flat observation without an actual
|
|
65
|
+
* hierarchy. A reported container name remains metadata and does not promote
|
|
66
|
+
* a flat observation to known nesting.
|
|
67
|
+
*/
|
|
68
|
+
export interface DocumentCodeSymbol extends CodeSymbol {
|
|
69
|
+
nesting: DeclarationNesting;
|
|
70
|
+
}
|
|
71
|
+
|
|
57
72
|
// ── Result types ───────────────────────────────────────────────────────
|
|
58
73
|
|
|
59
74
|
/**
|
|
@@ -143,11 +158,8 @@ export interface WorkspaceEdit {
|
|
|
143
158
|
|
|
144
159
|
/**
|
|
145
160
|
* Supported refactor operation names for the current semantic planning path.
|
|
146
|
-
*
|
|
147
|
-
* `rename` is kept as a legacy alias for the public rename-only surface.
|
|
148
161
|
*/
|
|
149
162
|
export type RefactorOperation =
|
|
150
|
-
| "rename"
|
|
151
163
|
| "rename_symbol"
|
|
152
164
|
| "extract_function"
|
|
153
165
|
| "extract_variable"
|
|
@@ -156,13 +168,6 @@ export type RefactorOperation =
|
|
|
156
168
|
| "update_imports"
|
|
157
169
|
| "delete_dead_code";
|
|
158
170
|
|
|
159
|
-
/** Normalize legacy refactor aliases to their canonical operation names. */
|
|
160
|
-
export function normalizeRefactorOperation(
|
|
161
|
-
operation: RefactorOperation,
|
|
162
|
-
): Exclude<RefactorOperation, "rename"> {
|
|
163
|
-
return operation === "rename" ? "rename_symbol" : operation;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
171
|
/**
|
|
167
172
|
* Operation-aware refactor planning request.
|
|
168
173
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "SuPi core — shared infrastructure for SuPi extensions (XML context tags, config system)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -50,7 +50,6 @@
|
|
|
50
50
|
},
|
|
51
51
|
"main": "src/api.ts",
|
|
52
52
|
"exports": {
|
|
53
|
-
"./abort-utils": "./src/abort-utils.ts",
|
|
54
53
|
"./api": "./src/api.ts",
|
|
55
54
|
"./config": "./src/config.ts",
|
|
56
55
|
"./context": "./src/context.ts",
|
|
@@ -71,7 +70,6 @@
|
|
|
71
70
|
"./status-spinner": "./src/status-spinner.ts",
|
|
72
71
|
"./terminal": "./src/terminal.ts",
|
|
73
72
|
"./tool-framework": "./src/tool-framework.ts",
|
|
74
|
-
"./prompt-surface": "./src/prompt-surface.ts"
|
|
75
|
-
"./types": "./src/types.ts"
|
|
73
|
+
"./prompt-surface": "./src/prompt-surface.ts"
|
|
76
74
|
}
|
|
77
75
|
}
|
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
// For lighter imports, use one of the domain subpaths directly
|
|
7
7
|
// (e.g. @mrclrchtr/supi-core/config, @mrclrchtr/supi-core/context).
|
|
8
8
|
|
|
9
|
-
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
10
|
-
export * from "./abort-utils.ts";
|
|
11
9
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
12
10
|
export * from "./config.ts";
|
|
13
11
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
@@ -42,5 +40,3 @@ export * from "./status-spinner.ts";
|
|
|
42
40
|
export * from "./terminal.ts";
|
|
43
41
|
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
44
42
|
export * from "./tool-framework.ts";
|
|
45
|
-
// biome-ignore lint/performance/noReExportAll: intentional convenience barrel
|
|
46
|
-
export * from "./types.ts";
|