@mrclrchtr/supi-code-intelligence 4.10.0 → 5.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 +2 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/README.md +80 -5
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- 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/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/package.json +7 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +10 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +206 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +78 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +114 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +372 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +14 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +62 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +491 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +71 -11
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +206 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +365 -297
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +52 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +185 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-file-state.ts +25 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +467 -115
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +161 -33
- package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +10 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/defaults.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +45 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +38 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +79 -9
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +13 -4
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +300 -24
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +5 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +464 -96
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-refactor-provider.ts +130 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +45 -329
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +57 -120
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-edit-normalizer.ts +320 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +207 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/readiness.ts +72 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +151 -26
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +40 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +50 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +136 -120
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +49 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +102 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +17 -7
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/LICENSE +21 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/README.md +258 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/babel.cjs +257 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/jiti.cjs +1 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-cli.mjs +34 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-hooks.mjs +124 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-native.mjs +121 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.d.mts +1 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.mjs +4 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-static.mjs +23 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.cjs +30 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.cts +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.mts +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.mjs +29 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/types.d.ts +420 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/package.json +146 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +0 -9
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +16 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +65 -87
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +47 -95
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-timing.ts +147 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client-lifecycle.ts +39 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +561 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-message-size.ts +24 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +452 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +12 -4
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/imports.ts +4 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +5 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +33 -12
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/blocking-test-bootstrap.mjs +34 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/bootstrap.mjs +8 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store-helpers.ts +23 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +400 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/request-control.ts +48 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-parser-helpers.ts +24 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-query-helpers.ts +43 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +421 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +116 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +201 -0
- package/package.json +5 -5
- package/src/analysis/health/diagnostics.ts +236 -24
- package/src/analysis/health/recovery.ts +6 -2
- package/src/analysis/provider.ts +58 -0
- package/src/analysis/readiness.ts +30 -9
- package/src/analysis/refactor/apply.ts +45 -1
- package/src/analysis/refactor/mutation-authority.ts +143 -0
- package/src/analysis/relations/callees.ts +9 -1
- package/src/analysis/relations/types.ts +5 -2
- package/src/analysis/search/ast-scan-timing.ts +9 -2
- package/src/analysis/search/ast-scan.ts +1 -1
- package/src/analysis/search/deadline.ts +2 -2
- package/src/analysis/search/pattern-analysis.ts +46 -32
- package/src/analysis/search/pattern.ts +12 -2
- package/src/analysis/target/anchored.ts +20 -11
- package/src/analysis/target/file.ts +18 -11
- package/src/analysis/target/identity.ts +19 -3
- package/src/analysis/target/symbol.ts +36 -15
- package/src/api.ts +4 -0
- package/src/diagnostics/evidence.ts +51 -0
- package/src/session/capability-adapter.ts +12 -3
- package/src/session/find-workflow.ts +17 -7
- package/src/session/graph/collect.ts +18 -2
- package/src/session/graph-workflow.ts +19 -12
- package/src/session/health-refresh.ts +148 -0
- package/src/session/health-types.ts +37 -15
- package/src/session/health-workflow.ts +37 -39
- package/src/session/inspect/collect.ts +20 -3
- package/src/session/inspect-workflow.ts +10 -5
- package/src/session/orientation/collect.ts +10 -1
- package/src/session/orientation/context-facts.ts +3 -1
- package/src/session/orientation/context-sections.ts +20 -7
- package/src/session/orientation/gather.ts +17 -11
- package/src/session/orientation-types.ts +2 -1
- package/src/session/orientation-workflow.ts +15 -8
- package/src/session/refactor-plans.ts +2 -0
- package/src/session/refactor-workflow.ts +59 -14
- package/src/session/session.ts +4 -1
- package/src/session/target-workflow.ts +54 -23
- package/src/session/workflow-control.ts +7 -3
- package/src/substrate/lsp/lifecycle.ts +26 -46
- package/src/substrate/lsp/maintenance.ts +199 -25
- package/src/substrate/lsp/state.ts +2 -2
- package/src/substrate/workspace-provider-host.ts +25 -3
- package/src/tool/find/execute.ts +7 -1
- package/src/tool/find/render.ts +20 -3
- package/src/tool/find/tui.ts +23 -21
- package/src/tool/graph/execute.ts +23 -3
- package/src/tool/graph/tui.ts +59 -46
- package/src/tool/health/execute.ts +7 -2
- package/src/tool/health/markdown.ts +56 -14
- package/src/tool/health/refresh-status.ts +105 -0
- package/src/tool/health/tui.ts +95 -98
- package/src/tool/infra/workflow-control.ts +8 -0
- package/src/tool/inspect/execute.ts +7 -1
- package/src/tool/inspect/tui.ts +26 -18
- package/src/tool/orientation/execute.ts +21 -3
- package/src/tool/orientation/tui.ts +51 -35
- package/src/tool/refactor-apply/execute.ts +3 -0
- package/src/tool/refactor-apply/tui.ts +43 -25
- package/src/tool/refactor-plan/execute.ts +4 -0
- package/src/tool/refactor-plan/tui.ts +33 -20
- package/src/tool/register.ts +127 -22
- package/src/tool/resolve/execute.ts +18 -1
- package/src/tool/resolve/tui.ts +42 -24
- package/src/tool/result/display.ts +107 -0
- package/src/tool/result/errors.ts +20 -17
- package/src/tool/result/find.ts +52 -8
- package/src/tool/result/graph.ts +44 -1
- package/src/tool/result/health.ts +53 -1
- package/src/tool/result/inspect.ts +113 -1
- package/src/tool/result/orientation.ts +66 -14
- package/src/tool/result/refactor.ts +36 -4
- package/src/tool/result/resolve.ts +44 -7
- package/src/tool/result/types.ts +20 -0
- package/src/types/execution.ts +18 -5
- package/src/types/index.ts +8 -1
- package/src/ui/status-command.ts +5 -3
- package/src/ui/status-overlay.ts +4 -0
- package/src/ui/tui/common.ts +108 -10
- package/src/ui/tui/display.ts +48 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime.ts +0 -351
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
// Tree-sitter
|
|
2
|
-
//
|
|
3
|
-
// This controller owns runtime creation/disposal for one cwd:
|
|
4
|
-
// - Creates and disposes the TreeSitterRuntime
|
|
5
|
-
// - Creates TreeSitterService from the runtime
|
|
6
|
-
// - Publishes SessionTreeSitterService state through the existing registry
|
|
7
|
-
// - Exposes ready/unavailable lifecycle for umbrella adapter consumption
|
|
1
|
+
// Tree-sitter lifecycle controller — owns one Structural Worker for one cwd.
|
|
8
2
|
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
9
4
|
import type { WorkspaceRuntime } from "@mrclrchtr/supi-code-runtime/api";
|
|
10
|
-
import type { SessionTreeSitterService, TreeSitterService } from "../types.ts";
|
|
11
|
-
import { TreeSitterRuntime } from "./runtime.ts";
|
|
5
|
+
import type { SessionTreeSitterService, TreeSitterService, TreeSitterSession } from "../types.ts";
|
|
12
6
|
import {
|
|
13
7
|
registerTreeSitterCapabilities,
|
|
14
8
|
unregisterTreeSitterCapabilities,
|
|
15
9
|
} from "./runtime-registration.ts";
|
|
16
10
|
import { clearSessionTreeSitterService, setSessionTreeSitterService } from "./service-registry.ts";
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
// ── Types ─────────────────────────────────────────────────────────────
|
|
11
|
+
import { createTreeSitterSession } from "./session.ts";
|
|
20
12
|
|
|
21
13
|
/** Starting state before or after shutdown. */
|
|
22
14
|
export type TsControllerState = TsControllerInitial | TsControllerReady | TsControllerUnavailable;
|
|
@@ -27,7 +19,7 @@ interface TsControllerInitial {
|
|
|
27
19
|
|
|
28
20
|
interface TsControllerReady {
|
|
29
21
|
kind: "ready";
|
|
30
|
-
|
|
22
|
+
session: TreeSitterSession;
|
|
31
23
|
service: TreeSitterService;
|
|
32
24
|
}
|
|
33
25
|
|
|
@@ -39,119 +31,105 @@ interface TsControllerUnavailable {
|
|
|
39
31
|
/** Result type from {@link TreeSitterRuntimeController.start}. */
|
|
40
32
|
export type TsStartResult = { kind: "ready" } | { kind: "unavailable"; reason: string };
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Pi-independent Tree-sitter session lifecycle controller.
|
|
46
|
-
*
|
|
47
|
-
* Use this in the umbrella extension (supi-code-intelligence) instead of
|
|
48
|
-
* reaching into substrate extension internals.
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```ts
|
|
52
|
-
* const controller = new TreeSitterRuntimeController(cwd);
|
|
53
|
-
* const result = await controller.start();
|
|
54
|
-
* if (result.kind === "ready") {
|
|
55
|
-
* // use controller.service, controller.runtime
|
|
56
|
-
* }
|
|
57
|
-
* // later
|
|
58
|
-
* await controller.shutdown();
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
34
|
+
/** Pi-independent lifecycle for one shared workspace Structural Worker. */
|
|
61
35
|
export class TreeSitterRuntimeController {
|
|
62
36
|
readonly #cwd: string;
|
|
63
|
-
#state: TsControllerState;
|
|
37
|
+
#state: TsControllerState = { kind: "initial" };
|
|
64
38
|
#runtime: WorkspaceRuntime | null;
|
|
39
|
+
#pendingSession: TreeSitterSession | null = null;
|
|
40
|
+
#generation = 0;
|
|
41
|
+
#transition = Promise.resolve();
|
|
65
42
|
|
|
66
43
|
constructor(cwd: string, runtime?: WorkspaceRuntime) {
|
|
67
44
|
this.#cwd = cwd;
|
|
68
|
-
this.#state = { kind: "initial" };
|
|
69
45
|
this.#runtime = runtime ?? null;
|
|
70
46
|
}
|
|
71
47
|
|
|
72
|
-
/** The workspace cwd this controller was created for. */
|
|
73
48
|
get cwd(): string {
|
|
74
49
|
return this.#cwd;
|
|
75
50
|
}
|
|
76
51
|
|
|
77
|
-
/** Current controller state. */
|
|
78
52
|
get kind(): TsControllerState["kind"] {
|
|
79
53
|
return this.#state.kind;
|
|
80
54
|
}
|
|
81
55
|
|
|
82
|
-
/** The TreeSitterService (structural operations), available when state is "ready". */
|
|
83
56
|
get service(): SessionTreeSitterService | null {
|
|
84
57
|
return this.#state.kind === "ready" ? this.#state.service : null;
|
|
85
58
|
}
|
|
86
59
|
|
|
87
|
-
/** The TreeSitterRuntime, available when state is "ready". */
|
|
88
|
-
get runtime(): TreeSitterRuntime | null {
|
|
89
|
-
return this.#state.kind === "ready" ? this.#state.runtime : null;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Attach a WorkspaceRuntime for capability registration. */
|
|
93
60
|
setRuntime(runtime: WorkspaceRuntime): void {
|
|
94
61
|
this.#runtime = runtime;
|
|
95
62
|
}
|
|
96
63
|
|
|
97
|
-
/**
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (this.#runtime) unregisterTreeSitterCapabilities(this.#runtime, this.#cwd);
|
|
109
|
-
clearSessionTreeSitterService(this.#cwd);
|
|
110
|
-
}
|
|
64
|
+
/** Start and validate one Structural Worker before capability publication. */
|
|
65
|
+
start(): Promise<TsStartResult> {
|
|
66
|
+
const generation = ++this.#generation;
|
|
67
|
+
let result: TsStartResult = supersededStart();
|
|
68
|
+
const transition = this.#transition.then(async () => {
|
|
69
|
+
if (generation !== this.#generation) return;
|
|
70
|
+
result = await this.#startGeneration(generation);
|
|
71
|
+
});
|
|
72
|
+
this.#transition = transition.catch(() => undefined);
|
|
73
|
+
return transition.then(() => result);
|
|
74
|
+
}
|
|
111
75
|
|
|
76
|
+
/** Stop publication, terminate owned Workers, and await their exit. */
|
|
77
|
+
async shutdown(): Promise<void> {
|
|
78
|
+
const generation = ++this.#generation;
|
|
79
|
+
const sessions = this.#takeOwnedSessions();
|
|
80
|
+
await Promise.all([...sessions].map((session) => session.dispose()));
|
|
81
|
+
if (generation === this.#generation) this.#state = { kind: "initial" };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async #startGeneration(generation: number): Promise<TsStartResult> {
|
|
85
|
+
const previous = this.#takeOwnedSessions();
|
|
86
|
+
await Promise.all([...previous].map((session) => session.dispose()));
|
|
87
|
+
if (generation !== this.#generation) return supersededStart();
|
|
112
88
|
this.#state = { kind: "unavailable", reason: "Initializing Tree-sitter" };
|
|
113
89
|
|
|
90
|
+
const session = createTreeSitterSession(this.#cwd);
|
|
91
|
+
this.#pendingSession = session;
|
|
114
92
|
try {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// corrupted WASM early rather than deferring to first tool use.
|
|
120
|
-
await treeSitterRuntime.ensureGrammarParser("javascript");
|
|
121
|
-
|
|
122
|
-
const service = createTreeSitterService(treeSitterRuntime);
|
|
123
|
-
setSessionTreeSitterService(this.#cwd, service);
|
|
124
|
-
|
|
125
|
-
if (this.#runtime) {
|
|
126
|
-
registerTreeSitterCapabilities(this.#runtime, this.#cwd, service);
|
|
93
|
+
const probe = await session.canParse(fileURLToPath(import.meta.url));
|
|
94
|
+
if (probe.kind !== "success") throw new Error(probe.message);
|
|
95
|
+
if (generation !== this.#generation || this.#pendingSession !== session) {
|
|
96
|
+
return supersededStart();
|
|
127
97
|
}
|
|
128
|
-
|
|
129
|
-
this.#
|
|
98
|
+
setSessionTreeSitterService(this.#cwd, session);
|
|
99
|
+
if (this.#runtime) registerTreeSitterCapabilities(this.#runtime, this.#cwd, session);
|
|
100
|
+
this.#pendingSession = null;
|
|
101
|
+
this.#state = { kind: "ready", session, service: session };
|
|
130
102
|
return { kind: "ready" };
|
|
131
|
-
} catch (error
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if (generation !== this.#generation || this.#pendingSession !== session) {
|
|
105
|
+
return supersededStart();
|
|
106
|
+
}
|
|
107
|
+
await session.dispose();
|
|
108
|
+
this.#pendingSession = null;
|
|
132
109
|
const reason = error instanceof Error ? error.message : String(error);
|
|
110
|
+
await this.#clearPublishedSession();
|
|
133
111
|
this.#state = { kind: "unavailable", reason };
|
|
134
|
-
clearSessionTreeSitterService(this.#cwd);
|
|
135
112
|
return { kind: "unavailable", reason };
|
|
136
113
|
}
|
|
137
114
|
}
|
|
138
115
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
*/
|
|
144
|
-
async shutdown(): Promise<void> {
|
|
145
|
-
if (this.#runtime && this.#cwd) {
|
|
146
|
-
unregisterTreeSitterCapabilities(this.#runtime, this.#cwd);
|
|
147
|
-
}
|
|
116
|
+
async #clearPublishedSession(): Promise<void> {
|
|
117
|
+
const sessions = this.#takeOwnedSessions();
|
|
118
|
+
await Promise.all([...sessions].map((session) => session.dispose()));
|
|
119
|
+
}
|
|
148
120
|
|
|
121
|
+
#takeOwnedSessions(): Set<TreeSitterSession> {
|
|
122
|
+
if (this.#runtime) unregisterTreeSitterCapabilities(this.#runtime, this.#cwd);
|
|
149
123
|
clearSessionTreeSitterService(this.#cwd);
|
|
150
|
-
|
|
151
|
-
if (this.#
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
124
|
+
const sessions = new Set<TreeSitterSession>();
|
|
125
|
+
if (this.#pendingSession) sessions.add(this.#pendingSession);
|
|
126
|
+
if (this.#state.kind === "ready") sessions.add(this.#state.session);
|
|
127
|
+
this.#pendingSession = null;
|
|
155
128
|
this.#state = { kind: "initial" };
|
|
129
|
+
return sessions;
|
|
156
130
|
}
|
|
157
131
|
}
|
|
132
|
+
|
|
133
|
+
function supersededStart(): TsStartResult {
|
|
134
|
+
return { kind: "unavailable", reason: "Startup superseded" };
|
|
135
|
+
}
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
// Session factory — creates
|
|
1
|
+
// Session factory — creates asynchronous Structural Worker proxies and owned sessions.
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { supportsGrammarOperation } from "../operation-support.ts";
|
|
5
|
-
import {
|
|
6
|
-
extractCallSites,
|
|
7
|
-
extractExports,
|
|
8
|
-
extractImports,
|
|
9
|
-
extractOutline,
|
|
10
|
-
lookupCalleesAt,
|
|
11
|
-
lookupNodeAt,
|
|
12
|
-
} from "../tool/structure.ts";
|
|
3
|
+
import type { CodeRequestControl } from "@mrclrchtr/supi-code-runtime/api";
|
|
13
4
|
import type {
|
|
14
5
|
CalleesAtResult,
|
|
15
6
|
CallSiteMatch,
|
|
@@ -22,108 +13,69 @@ import type {
|
|
|
22
13
|
TreeSitterService,
|
|
23
14
|
TreeSitterSession,
|
|
24
15
|
} from "../types.ts";
|
|
25
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
StructuralWorkerClient,
|
|
18
|
+
type StructuralWorkerFactory,
|
|
19
|
+
} from "./structural-worker-client.ts";
|
|
26
20
|
|
|
27
|
-
/** Create
|
|
28
|
-
export function createTreeSitterService(
|
|
21
|
+
/** Create one asynchronous service backed by an owned Structural Worker client. */
|
|
22
|
+
export function createTreeSitterService(client: StructuralWorkerClient): TreeSitterService {
|
|
29
23
|
return {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (result.kind !== "success") return result;
|
|
33
|
-
const { resolvedPath, grammarId, tree } = result.data;
|
|
34
|
-
try {
|
|
35
|
-
return {
|
|
36
|
-
kind: "success",
|
|
37
|
-
data: { file: resolvedPath, language: grammarId },
|
|
38
|
-
};
|
|
39
|
-
} finally {
|
|
40
|
-
tree.delete();
|
|
41
|
-
}
|
|
24
|
+
canParse(file, control) {
|
|
25
|
+
return execute(client, { operation: "canParse", file }, control);
|
|
42
26
|
},
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return runtime.queryFile(file, queryString);
|
|
27
|
+
query(file, query, control) {
|
|
28
|
+
return execute<QueryCapture[]>(client, { operation: "query", file, query }, control);
|
|
46
29
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const grammarId = detectGrammar(file);
|
|
50
|
-
if (grammarId && !supportsGrammarOperation(grammarId, "outline")) {
|
|
51
|
-
return {
|
|
52
|
-
kind: "unsupported-language",
|
|
53
|
-
file,
|
|
54
|
-
message: `outline is not supported for ${grammarId} files`,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
const parseResult = await runtime.parseFile(file);
|
|
58
|
-
if (parseResult.kind !== "success") return parseResult;
|
|
59
|
-
const { tree, source } = parseResult.data;
|
|
60
|
-
try {
|
|
61
|
-
const items = extractOutline(tree.rootNode, source);
|
|
62
|
-
return { kind: "success", data: items };
|
|
63
|
-
} finally {
|
|
64
|
-
tree.delete();
|
|
65
|
-
}
|
|
30
|
+
outline(file, control) {
|
|
31
|
+
return execute<OutlineItem[]>(client, { operation: "outline", file }, control);
|
|
66
32
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const grammarId = detectGrammar(file);
|
|
70
|
-
if (grammarId && !supportsGrammarOperation(grammarId, "imports")) {
|
|
71
|
-
return {
|
|
72
|
-
kind: "unsupported-language",
|
|
73
|
-
file,
|
|
74
|
-
message: `imports is not supported for ${grammarId} files`,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
return extractImports(runtime, file);
|
|
33
|
+
imports(file, control) {
|
|
34
|
+
return execute<ImportRecord[]>(client, { operation: "imports", file }, control);
|
|
78
35
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const grammarId = detectGrammar(file);
|
|
82
|
-
if (grammarId && !supportsGrammarOperation(grammarId, "exports")) {
|
|
83
|
-
return {
|
|
84
|
-
kind: "unsupported-language",
|
|
85
|
-
file,
|
|
86
|
-
message: `exports is not supported for ${grammarId} files`,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
return extractExports(runtime, file);
|
|
36
|
+
exports(file, control) {
|
|
37
|
+
return execute<ExportRecord[]>(client, { operation: "exports", file }, control);
|
|
90
38
|
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
file: string,
|
|
94
|
-
line: number,
|
|
95
|
-
character: number,
|
|
96
|
-
): Promise<TreeSitterResult<NodeAtResult>> {
|
|
97
|
-
return lookupNodeAt(runtime, file, line, character);
|
|
39
|
+
nodeAt(file, line, character, control) {
|
|
40
|
+
return execute<NodeAtResult>(client, { operation: "nodeAt", file, line, character }, control);
|
|
98
41
|
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
42
|
+
calleesAt(file, line, character, depthOrOptions) {
|
|
43
|
+
const depth = typeof depthOrOptions === "string" ? depthOrOptions : depthOrOptions?.depth;
|
|
44
|
+
const control = typeof depthOrOptions === "string" ? undefined : depthOrOptions?.control;
|
|
45
|
+
return execute<CalleesAtResult>(
|
|
46
|
+
client,
|
|
47
|
+
{ operation: "calleesAt", file, line, character, depth },
|
|
48
|
+
control,
|
|
49
|
+
);
|
|
107
50
|
},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return extractCallSites(runtime, file);
|
|
51
|
+
callSites(file, control) {
|
|
52
|
+
return execute<CallSiteMatch[]>(client, { operation: "callSites", file }, control);
|
|
111
53
|
},
|
|
112
54
|
};
|
|
113
55
|
}
|
|
114
56
|
|
|
115
57
|
/**
|
|
116
|
-
* Create
|
|
117
|
-
*
|
|
58
|
+
* Create one Tree-sitter session bound to a working directory.
|
|
59
|
+
* Await disposal to prove that its Structural Worker has terminated.
|
|
118
60
|
*/
|
|
119
|
-
export function createTreeSitterSession(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
61
|
+
export function createTreeSitterSession(
|
|
62
|
+
cwd: string,
|
|
63
|
+
options: { readonly workerFactory?: StructuralWorkerFactory } = {},
|
|
64
|
+
): TreeSitterSession {
|
|
65
|
+
const client = new StructuralWorkerClient(cwd, options.workerFactory);
|
|
66
|
+
const service = createTreeSitterService(client);
|
|
123
67
|
return {
|
|
124
68
|
...service,
|
|
125
69
|
dispose() {
|
|
126
|
-
|
|
70
|
+
return client.dispose();
|
|
127
71
|
},
|
|
128
72
|
};
|
|
129
73
|
}
|
|
74
|
+
|
|
75
|
+
function execute<T>(
|
|
76
|
+
client: StructuralWorkerClient,
|
|
77
|
+
input: Parameters<StructuralWorkerClient["execute"]>[0],
|
|
78
|
+
control?: CodeRequestControl,
|
|
79
|
+
): Promise<TreeSitterResult<T>> {
|
|
80
|
+
return control ? client.execute<T>(input, control) : client.execute<T>(input);
|
|
81
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { performance } from "node:perf_hooks";
|
|
2
|
+
import { recordDebugEvent, startDebugTimer } from "@mrclrchtr/supi-core/debug";
|
|
3
|
+
import type { StructuralCacheObservation } from "../worker/parsed-file-store.ts";
|
|
4
|
+
|
|
5
|
+
/** Plain sanitized event sent from the Structural Worker to the parent. */
|
|
6
|
+
export interface StructuralTimingEvent {
|
|
7
|
+
readonly operationId?: string;
|
|
8
|
+
readonly source: "tree-sitter";
|
|
9
|
+
readonly level: "debug";
|
|
10
|
+
readonly category: "structural.parse.timing" | "structural.query.timing";
|
|
11
|
+
readonly message: string;
|
|
12
|
+
readonly data: Readonly<Record<string, unknown>> & {
|
|
13
|
+
readonly timing: {
|
|
14
|
+
readonly durationMs: number;
|
|
15
|
+
readonly phasesMs: Readonly<Record<string, number>>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface StructuralTimer {
|
|
21
|
+
mark(phase: string): void;
|
|
22
|
+
finish(
|
|
23
|
+
event: Omit<StructuralTimingEvent, "data"> & { data: Record<string, unknown> },
|
|
24
|
+
finalPhase: string,
|
|
25
|
+
): void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type ParserState = "cold" | "initializing" | "reused";
|
|
29
|
+
export type ParseTimingPhase =
|
|
30
|
+
| "cache-lookup"
|
|
31
|
+
| "content-hash"
|
|
32
|
+
| "file-read"
|
|
33
|
+
| "parse"
|
|
34
|
+
| "parser-setup";
|
|
35
|
+
export type QueryTimingPhase = "query-cache" | "query-compilation" | "query-execution";
|
|
36
|
+
|
|
37
|
+
export type StructuralTimingObservation =
|
|
38
|
+
| {
|
|
39
|
+
readonly operation: "parse";
|
|
40
|
+
readonly grammar: string;
|
|
41
|
+
readonly parserState: ParserState;
|
|
42
|
+
readonly outcome:
|
|
43
|
+
| "cancelled"
|
|
44
|
+
| "completed"
|
|
45
|
+
| "file-access-error"
|
|
46
|
+
| "runtime-error"
|
|
47
|
+
| "timeout";
|
|
48
|
+
readonly cache?: StructuralCacheObservation;
|
|
49
|
+
readonly finalPhase: ParseTimingPhase;
|
|
50
|
+
}
|
|
51
|
+
| {
|
|
52
|
+
readonly operation: "query";
|
|
53
|
+
readonly grammar: string;
|
|
54
|
+
readonly outcome:
|
|
55
|
+
| "cancelled"
|
|
56
|
+
| "completed"
|
|
57
|
+
| "runtime-error"
|
|
58
|
+
| "timeout"
|
|
59
|
+
| "validation-error";
|
|
60
|
+
readonly captureCount: number;
|
|
61
|
+
readonly cache: StructuralCacheObservation;
|
|
62
|
+
readonly finalPhase: QueryTimingPhase;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Start one failure-isolated Tree-sitter timing observation. */
|
|
66
|
+
export function startStructuralTiming(
|
|
67
|
+
operationId?: string,
|
|
68
|
+
forward?: (event: StructuralTimingEvent) => void,
|
|
69
|
+
): StructuralTimer {
|
|
70
|
+
if (forward) return createForwardedTimer(operationId, forward);
|
|
71
|
+
const timer = startDebugTimer();
|
|
72
|
+
return {
|
|
73
|
+
mark(phase) {
|
|
74
|
+
timer.mark(phase);
|
|
75
|
+
},
|
|
76
|
+
finish(event, finalPhase) {
|
|
77
|
+
timer.finish({ ...event, operationId }, finalPhase);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Finish one sanitized Tree-sitter timing observation. */
|
|
83
|
+
export function finishStructuralTiming(
|
|
84
|
+
timer: StructuralTimer,
|
|
85
|
+
observation: StructuralTimingObservation,
|
|
86
|
+
): void {
|
|
87
|
+
const { finalPhase, ...data } = observation;
|
|
88
|
+
timer.finish(
|
|
89
|
+
{
|
|
90
|
+
source: "tree-sitter",
|
|
91
|
+
level: "debug",
|
|
92
|
+
category: `structural.${data.operation}.timing`,
|
|
93
|
+
message: `Tree-sitter ${data.operation} ${data.outcome}`,
|
|
94
|
+
data: { ...data },
|
|
95
|
+
},
|
|
96
|
+
finalPhase,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Publish one validated Worker timing event into the parent Debug Registry. */
|
|
101
|
+
export function publishStructuralTimingEvent(event: StructuralTimingEvent): void {
|
|
102
|
+
recordDebugEvent(event);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function createForwardedTimer(
|
|
106
|
+
operationId: string | undefined,
|
|
107
|
+
forward: (event: StructuralTimingEvent) => void,
|
|
108
|
+
): StructuralTimer {
|
|
109
|
+
const startedAt = performance.now();
|
|
110
|
+
let previousAt = startedAt;
|
|
111
|
+
let finished = false;
|
|
112
|
+
const phases = new Map<string, number>();
|
|
113
|
+
|
|
114
|
+
const mark = (phase: string, current: number) => {
|
|
115
|
+
phases.set(phase, (phases.get(phase) ?? 0) + Math.max(0, current - previousAt));
|
|
116
|
+
previousAt = current;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
mark(phase) {
|
|
121
|
+
if (!finished) mark(phase, performance.now());
|
|
122
|
+
},
|
|
123
|
+
finish(event, finalPhase) {
|
|
124
|
+
if (finished) return;
|
|
125
|
+
finished = true;
|
|
126
|
+
const completedAt = performance.now();
|
|
127
|
+
mark(finalPhase, completedAt);
|
|
128
|
+
forward({
|
|
129
|
+
...event,
|
|
130
|
+
...(operationId ? { operationId } : {}),
|
|
131
|
+
data: {
|
|
132
|
+
...event.data,
|
|
133
|
+
timing: {
|
|
134
|
+
durationMs: duration(completedAt - startedAt),
|
|
135
|
+
phasesMs: Object.fromEntries(
|
|
136
|
+
[...phases.entries()].map(([name, value]) => [name, duration(value)]),
|
|
137
|
+
),
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
} as StructuralTimingEvent);
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function duration(value: number): number {
|
|
146
|
+
return Math.round(Math.max(0, value) * 10) / 10;
|
|
147
|
+
}
|
package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client-lifecycle.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
interface OwnedWorkerLike {
|
|
2
|
+
terminate(): Promise<number>;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/** Serialize every Worker start, termination, and restart ownership transition. */
|
|
6
|
+
export class StructuralWorkerLifecycle {
|
|
7
|
+
#transition = Promise.resolve();
|
|
8
|
+
#generation = 0;
|
|
9
|
+
|
|
10
|
+
/** Run one transition after every older transition settles. */
|
|
11
|
+
run<T>(operation: () => Promise<T>): Promise<T> {
|
|
12
|
+
const generation = this.#generation;
|
|
13
|
+
const current = this.#transition.then(
|
|
14
|
+
() => this.#runIfCurrent(generation, operation),
|
|
15
|
+
() => this.#runIfCurrent(generation, operation),
|
|
16
|
+
);
|
|
17
|
+
this.#transition = current.then(
|
|
18
|
+
() => undefined,
|
|
19
|
+
() => undefined,
|
|
20
|
+
);
|
|
21
|
+
return current;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Terminate one Worker as part of the serialized transition fence. */
|
|
25
|
+
async terminate(worker: OwnedWorkerLike | null): Promise<void> {
|
|
26
|
+
this.#generation += 1;
|
|
27
|
+
if (worker) await worker.terminate().catch(() => 0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Await every transition admitted before this call. */
|
|
31
|
+
settled(): Promise<void> {
|
|
32
|
+
return this.#transition;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async #runIfCurrent<T>(generation: number, operation: () => Promise<T>): Promise<T> {
|
|
36
|
+
if (generation !== this.#generation) throw new Error("Structural Worker lifecycle superseded");
|
|
37
|
+
return operation();
|
|
38
|
+
}
|
|
39
|
+
}
|