@mrclrchtr/supi-code-intelligence 4.10.0 → 6.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 +4 -3
- 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 +2 -2
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +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 -6
- package/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/README.md +111 -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 +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +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 -6
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- 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 +22 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +245 -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 +171 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +413 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +15 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +214 -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 +690 -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 +97 -16
- 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 +448 -298
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +70 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +231 -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 +529 -119
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +161 -33
- package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +12 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +5 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/config/defaults.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-extends.ts +68 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-path.ts +8 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +176 -24
- package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +45 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +42 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +46 -10
- 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 +17 -7
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +350 -26
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +5 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +586 -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 +42 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +92 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +165 -118
- 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 +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +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 -6
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- 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 +221 -77
- package/src/analysis/health/file-scope.ts +184 -0
- package/src/analysis/health/recovery.ts +14 -3
- package/src/analysis/provider.ts +58 -0
- package/src/analysis/readiness.ts +34 -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 +5 -2
- package/src/analysis/search/deadline.ts +2 -2
- package/src/analysis/search/pattern-analysis.ts +54 -33
- package/src/analysis/search/pattern.ts +18 -3
- 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/config.ts +35 -1
- package/src/diagnostics/evidence.ts +51 -0
- package/src/extension.ts +57 -14
- package/src/overview/overview-data.ts +9 -2
- package/src/overview/overview.ts +49 -30
- package/src/overview/types.ts +2 -0
- package/src/session/capability-adapter.ts +12 -3
- package/src/session/find-types.ts +2 -2
- package/src/session/find-workflow.ts +20 -9
- package/src/session/graph/collect.ts +18 -2
- package/src/session/graph-workflow.ts +19 -12
- package/src/session/health-refresh.ts +175 -0
- package/src/session/health-types.ts +43 -15
- package/src/session/health-workflow.ts +69 -54
- package/src/session/input/workflows.ts +2 -2
- package/src/session/inspect/collect.ts +20 -3
- package/src/session/inspect-workflow.ts +12 -6
- package/src/session/orientation/collect.ts +12 -3
- 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 +4 -1
- package/src/session/orientation-workflow.ts +23 -10
- package/src/session/refactor-plans.ts +2 -0
- package/src/session/refactor-workflow.ts +61 -15
- package/src/session/session.ts +29 -2
- 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 +284 -28
- package/src/substrate/lsp/recovery.ts +11 -5
- package/src/substrate/lsp/state.ts +2 -2
- package/src/substrate/workspace-provider-host.ts +25 -3
- package/src/tool/{find → code_find}/execute.ts +2 -16
- package/src/tool/code_find/guidance.ts +8 -0
- package/src/tool/{find → code_find}/render.ts +21 -4
- package/src/tool/{result/find.ts → code_find/result.ts} +78 -9
- package/src/tool/code_find/spec.ts +37 -0
- package/src/tool/code_find/tui.ts +41 -0
- package/src/tool/code_graph/execute.ts +24 -0
- package/src/tool/code_graph/guidance.ts +6 -0
- package/src/tool/{graph → code_graph}/markdown.ts +1 -1
- package/src/tool/{result/graph.ts → code_graph/result.ts} +111 -3
- package/src/tool/code_graph/spec.ts +39 -0
- package/src/tool/code_graph/tui.ts +117 -0
- package/src/tool/{health → code_health}/execute.ts +2 -13
- package/src/tool/code_health/guidance.ts +8 -0
- package/src/tool/{health → code_health}/markdown.ts +119 -27
- package/src/tool/code_health/refresh-status.ts +105 -0
- package/src/tool/{result/health.ts → code_health/result.ts} +80 -3
- package/src/tool/code_health/spec.ts +41 -0
- package/src/tool/{health → code_health}/tui.ts +95 -98
- package/src/tool/{inspect → code_inspect}/execute.ts +2 -16
- package/src/tool/code_inspect/guidance.ts +6 -0
- package/src/tool/{inspect → code_inspect}/markdown.ts +1 -1
- package/src/tool/{result/inspect.ts → code_inspect/result.ts} +143 -2
- package/src/tool/code_inspect/spec.ts +25 -0
- package/src/tool/code_inspect/tui.ts +44 -0
- package/src/tool/code_orientation/execute.ts +25 -0
- package/src/tool/code_orientation/guidance.ts +9 -0
- package/src/tool/{orientation → code_orientation}/markdown.ts +1 -1
- package/src/tool/code_orientation/result.ts +248 -0
- package/src/tool/code_orientation/spec.ts +25 -0
- package/src/tool/{orientation → code_orientation}/tui.ts +51 -35
- package/src/tool/code_refactor_apply/execute.ts +17 -0
- package/src/tool/code_refactor_apply/guidance.ts +5 -0
- package/src/tool/{refactor-apply/execute.ts → code_refactor_apply/result.ts} +8 -11
- package/src/tool/code_refactor_apply/spec.ts +26 -0
- package/src/tool/code_refactor_apply/tui.ts +73 -0
- package/src/tool/code_refactor_plan/execute.ts +27 -0
- package/src/tool/code_refactor_plan/guidance.ts +8 -0
- package/src/tool/{refactor-plan/execute.ts → code_refactor_plan/result.ts} +13 -22
- package/src/tool/code_refactor_plan/spec.ts +25 -0
- package/src/tool/code_refactor_plan/tui.ts +54 -0
- package/src/tool/code_resolve/execute.ts +19 -0
- package/src/tool/code_resolve/guidance.ts +8 -0
- package/src/tool/{resolve → code_resolve}/markdown.ts +1 -1
- package/src/tool/{result/resolve.ts → code_resolve/result.ts} +79 -29
- package/src/tool/code_resolve/spec.ts +25 -0
- package/src/tool/code_resolve/tui.ts +60 -0
- package/src/tool/guidance.ts +71 -52
- package/src/tool/infra/truncate.ts +40 -0
- package/src/tool/infra/workflow-control.ts +8 -0
- package/src/tool/{refactor-plan/markdown.ts → refactor-markdown.ts} +4 -7
- package/src/tool/register.ts +105 -88
- package/src/tool/result/display.ts +107 -0
- package/src/tool/result/errors.ts +20 -17
- package/src/tool/result/refactor.ts +37 -8
- package/src/tool/result/types.ts +20 -0
- package/src/tool/schemas.ts +26 -157
- package/src/tool/specs.ts +40 -126
- 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
- package/src/tool/find/tui.ts +0 -39
- package/src/tool/graph/execute.ts +0 -62
- package/src/tool/graph/tui.ts +0 -104
- package/src/tool/inspect/tui.ts +0 -36
- package/src/tool/orientation/execute.ts +0 -62
- package/src/tool/refactor-apply/tui.ts +0 -55
- package/src/tool/refactor-plan/tui.ts +0 -41
- package/src/tool/resolve/execute.ts +0 -36
- package/src/tool/resolve/tui.ts +0 -42
- package/src/tool/result/orientation.ts +0 -132
- /package/src/tool/{find → code_find}/ast-kinds.ts +0 -0
- /package/src/tool/{find → code_find}/markdown.ts +0 -0
- /package/src/tool/{find → code_find}/modes.ts +0 -0
- /package/src/tool/{health → code_health}/semantic-state.ts +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Diagnostic } from "../config/types.ts";
|
|
2
|
+
import type { DiagnosticEvidenceSummary } from "../diagnostics/evidence.ts";
|
|
3
|
+
|
|
4
|
+
export type {
|
|
5
|
+
DiagnosticEvidenceDocument,
|
|
6
|
+
DiagnosticEvidenceStatus,
|
|
7
|
+
DiagnosticEvidenceSummary,
|
|
8
|
+
} from "../diagnostics/evidence.ts";
|
|
9
|
+
|
|
10
|
+
/** Workspace diagnostic snapshot with explicit cache freshness and coverage. */
|
|
11
|
+
export interface WorkspaceDiagnosticSnapshot<T> {
|
|
12
|
+
entries: T[];
|
|
13
|
+
current: boolean;
|
|
14
|
+
evidence: DiagnosticEvidenceSummary;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Workspace diagnostic summary grouped by file. */
|
|
18
|
+
export interface WorkspaceDiagnosticSummaryEntry {
|
|
19
|
+
file: string;
|
|
20
|
+
errors: number;
|
|
21
|
+
warnings: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* One coherent post-refresh observation of workspace diagnostics.
|
|
26
|
+
*
|
|
27
|
+
* Both projections are captured from the same client snapshots. The report is
|
|
28
|
+
* short-lived and must not be retained as the runtime's last refresh attempt.
|
|
29
|
+
*/
|
|
30
|
+
export interface WorkspaceDiagnosticReport {
|
|
31
|
+
summary: WorkspaceDiagnosticSnapshot<WorkspaceDiagnosticSummaryEntry>;
|
|
32
|
+
outstanding: WorkspaceDiagnosticSnapshot<{
|
|
33
|
+
file: string;
|
|
34
|
+
diagnostics: Diagnostic[];
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Outstanding diagnostics grouped by file, including info and hint counts. */
|
|
39
|
+
export interface OutstandingDiagnosticSummaryEntry {
|
|
40
|
+
file: string;
|
|
41
|
+
total: number;
|
|
42
|
+
errors: number;
|
|
43
|
+
warnings: number;
|
|
44
|
+
information: number;
|
|
45
|
+
hints: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Result from a workspace diagnostic recovery pass. */
|
|
49
|
+
export interface RecoverDiagnosticsResult {
|
|
50
|
+
/** Active clients targeted by the best-effort refresh, not confirmed successful refreshes. */
|
|
51
|
+
attemptedClients: number;
|
|
52
|
+
restartedClients: number;
|
|
53
|
+
/** Evidence collected by the refresh and recovery operations. */
|
|
54
|
+
diagnosticEvidence: DiagnosticEvidenceSummary;
|
|
55
|
+
/** Final diagnostic report captured after all refresh and recovery work. */
|
|
56
|
+
diagnosticReport: WorkspaceDiagnosticReport;
|
|
57
|
+
/** Failure from the first refresh, when no later pass replaced it. */
|
|
58
|
+
refreshFailureReason?: string;
|
|
59
|
+
/** Wall-clock duration of the whole recovery pass, for telemetry. */
|
|
60
|
+
elapsedMs: number;
|
|
61
|
+
staleAssessment: {
|
|
62
|
+
suspected: boolean;
|
|
63
|
+
matchedFiles: Array<{ file: string; diagnostics: Diagnostic[] }>;
|
|
64
|
+
warning: string | null;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** One tracked file's tsconfig scope decision, for debug telemetry. */
|
|
69
|
+
export interface ScopeDecisionEntry {
|
|
70
|
+
/** Workspace-relative file path. */
|
|
71
|
+
file: string;
|
|
72
|
+
status: "included" | "excluded" | "no-config" | "out-of-tree";
|
|
73
|
+
/** Decision mechanism; null when no decision applies. */
|
|
74
|
+
basis: string | null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Aggregate tsconfig scope decisions for all tracked files, for debug telemetry. */
|
|
78
|
+
export interface ScopeDecisionSummary {
|
|
79
|
+
caseSensitiveFileNames: boolean;
|
|
80
|
+
counts: {
|
|
81
|
+
included: number;
|
|
82
|
+
excluded: number;
|
|
83
|
+
noConfig: number;
|
|
84
|
+
outOfTree: number;
|
|
85
|
+
};
|
|
86
|
+
/** Exact decision-basis counts; keys are {@link ScopeDecisionEntry.basis} values. */
|
|
87
|
+
basisCounts: Record<string, number>;
|
|
88
|
+
/** Bounded workspace-relative entries (oldest first), not the full set. */
|
|
89
|
+
entries: ScopeDecisionEntry[];
|
|
90
|
+
/** Total number of tracked files the summary was computed over. */
|
|
91
|
+
totalFiles: number;
|
|
92
|
+
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
// Shared session-scoped LSP service registry reused by peer extensions.
|
|
2
2
|
|
|
3
|
+
// biome-ignore lint/style/noExcessiveLinesPerFile: session registry, runtime recovery, and telemetry stay in one file; splitting would hide the recovery contract.
|
|
3
4
|
import {
|
|
4
5
|
type CodeQueryResult,
|
|
6
|
+
type CodeRequestControl,
|
|
7
|
+
isCodeRequestInterruption,
|
|
5
8
|
mapCodeQueryResult,
|
|
9
|
+
throwIfCodeRequestInterrupted,
|
|
6
10
|
unavailableCodeQuery,
|
|
7
11
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
12
|
+
import { recordDebugEvent } from "@mrclrchtr/supi-core/debug";
|
|
8
13
|
import { createSessionStateRegistry } from "@mrclrchtr/supi-core/session";
|
|
9
14
|
import type {
|
|
10
15
|
CodeAction,
|
|
@@ -21,9 +26,35 @@ import type {
|
|
|
21
26
|
WorkspaceEdit,
|
|
22
27
|
WorkspaceSymbol,
|
|
23
28
|
} from "../config/types.ts";
|
|
29
|
+
import { boundServerNames, truncateIdentity } from "../debug-telemetry.ts";
|
|
24
30
|
import type { LspManager } from "../manager/manager.ts";
|
|
25
31
|
import { resolveSessionPath } from "../utils.ts";
|
|
26
32
|
import { raceReadinessValue } from "./readiness.ts";
|
|
33
|
+
import type { DiagnosticEvidenceSummary, RecoverDiagnosticsResult } from "./runtime-diagnostics.ts";
|
|
34
|
+
import type {
|
|
35
|
+
RoutedMutationResponse,
|
|
36
|
+
SemanticReadinessResult,
|
|
37
|
+
WorkspaceLspRuntime,
|
|
38
|
+
WorkspaceLspRuntimeState,
|
|
39
|
+
} from "./workspace-lsp-runtime.ts";
|
|
40
|
+
|
|
41
|
+
export type { WorkspaceLspDiagnosticSurface } from "./runtime-diagnostic-surface.ts";
|
|
42
|
+
export type {
|
|
43
|
+
DiagnosticEvidenceDocument,
|
|
44
|
+
DiagnosticEvidenceStatus,
|
|
45
|
+
DiagnosticEvidenceSummary,
|
|
46
|
+
OutstandingDiagnosticSummaryEntry,
|
|
47
|
+
RecoverDiagnosticsResult,
|
|
48
|
+
WorkspaceDiagnosticReport,
|
|
49
|
+
WorkspaceDiagnosticSnapshot,
|
|
50
|
+
WorkspaceDiagnosticSummaryEntry,
|
|
51
|
+
} from "./runtime-diagnostics.ts";
|
|
52
|
+
export type {
|
|
53
|
+
RoutedMutationResponse,
|
|
54
|
+
SemanticReadinessResult,
|
|
55
|
+
WorkspaceLspRuntime,
|
|
56
|
+
WorkspaceLspRuntimeState,
|
|
57
|
+
} from "./workspace-lsp-runtime.ts";
|
|
27
58
|
|
|
28
59
|
function isRange(value: Position | Range): value is Range {
|
|
29
60
|
return "start" in value && "end" in value;
|
|
@@ -33,97 +64,31 @@ function unavailableFileQuery<T>(operation: string, file: string): CodeQueryResu
|
|
|
33
64
|
return unavailableCodeQuery(`No routed LSP client could complete ${operation} for ${file}.`);
|
|
34
65
|
}
|
|
35
66
|
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
warning: string | null;
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export type WorkspaceLspRuntimeState =
|
|
66
|
-
| { kind: "ready"; runtime: WorkspaceLspRuntime }
|
|
67
|
-
| { kind: "inactive"; runtime: WorkspaceLspRuntime }
|
|
68
|
-
| { kind: "pending" }
|
|
69
|
-
| { kind: "disabled" }
|
|
70
|
-
| { kind: "unavailable"; reason: string };
|
|
71
|
-
|
|
72
|
-
export type SemanticReadinessResult =
|
|
73
|
-
| { kind: "ready" }
|
|
74
|
-
| { kind: "timeout" }
|
|
75
|
-
| { kind: "unavailable"; reason: string };
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Workspace-scoped LSP interface that owns routing, readiness, semantic operations,
|
|
79
|
-
* diagnostics, and recovery without exposing clients or the mutable manager.
|
|
80
|
-
* File path inputs may be absolute or session-cwd-relative; a leading `@` is stripped
|
|
81
|
-
* to match pi's built-in path-tool convention. Position arguments use raw 0-based LSP
|
|
82
|
-
* coordinates; use `toLspPosition()` from `@mrclrchtr/supi-lsp/api` when starting from
|
|
83
|
-
* user-facing 1-based line and character values.
|
|
84
|
-
*/
|
|
85
|
-
export interface WorkspaceLspRuntime {
|
|
86
|
-
hover(filePath: string, position: Position): Promise<CodeQueryResult<Hover | null>>;
|
|
87
|
-
definition(
|
|
88
|
-
filePath: string,
|
|
89
|
-
position: Position,
|
|
90
|
-
): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>>;
|
|
91
|
-
references(filePath: string, position: Position): Promise<CodeQueryResult<Location[]>>;
|
|
92
|
-
implementation(
|
|
93
|
-
filePath: string,
|
|
94
|
-
position: Position,
|
|
95
|
-
): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>>;
|
|
96
|
-
documentSymbols(
|
|
97
|
-
filePath: string,
|
|
98
|
-
): Promise<CodeQueryResult<DocumentSymbol[] | SymbolInformation[]>>;
|
|
99
|
-
workspaceSymbol(query: string): Promise<CodeQueryResult<SymbolInformation[] | WorkspaceSymbol[]>>;
|
|
100
|
-
rename(filePath: string, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
|
101
|
-
codeActions(filePath: string, positionOrRange: Position | Range): Promise<CodeAction[] | null>;
|
|
102
|
-
/** Succeeds only when the concrete routed client exists and is query-ready. */
|
|
103
|
-
waitUntilReadyForFile(
|
|
104
|
-
filePath: string,
|
|
105
|
-
options?: { timeoutMs?: number },
|
|
106
|
-
): Promise<SemanticReadinessResult>;
|
|
107
|
-
/** Succeeds only when at least one concrete workspace client is active and query-ready. */
|
|
108
|
-
waitUntilReadyForWorkspace(options?: { timeoutMs?: number }): Promise<SemanticReadinessResult>;
|
|
109
|
-
getProjectServers(): ProjectServerInfo[];
|
|
110
|
-
isSupportedSourceFile(filePath: string): boolean;
|
|
111
|
-
trackFile(filePath: string): Promise<boolean>;
|
|
112
|
-
closeFile(filePath: string): void;
|
|
113
|
-
pruneMissingFiles(): readonly string[];
|
|
114
|
-
noteWorkspaceChanges(changes: FileEvent[]): void;
|
|
115
|
-
fileDiagnostics(filePath: string, maxSeverity?: number): Promise<CodeQueryResult<Diagnostic[]>>;
|
|
116
|
-
refreshOpenDiagnostics(options?: { maxWaitMs?: number; quietMs?: number }): Promise<void>;
|
|
117
|
-
getWorkspaceDiagnosticSummary(): WorkspaceDiagnosticSummaryEntry[];
|
|
118
|
-
getOutstandingDiagnostics(
|
|
119
|
-
maxSeverity?: number,
|
|
120
|
-
): Array<{ file: string; diagnostics: Diagnostic[] }>;
|
|
121
|
-
getOutstandingDiagnosticSummary(maxSeverity?: number): OutstandingDiagnosticSummaryEntry[];
|
|
122
|
-
recoverDiagnostics(options?: {
|
|
123
|
-
restartIfStillStale?: boolean;
|
|
124
|
-
maxWaitMs?: number;
|
|
125
|
-
quietMs?: number;
|
|
126
|
-
}): Promise<RecoverDiagnosticsResult>;
|
|
67
|
+
/** Emit one aggregate tsconfig scope-decision event after a recovery pass. */
|
|
68
|
+
function recordScopeDecisionEvent(manager: LspManager): void {
|
|
69
|
+
try {
|
|
70
|
+
const summary = manager.getScopeDecisionSummary();
|
|
71
|
+
recordDebugEvent({
|
|
72
|
+
source: "lsp",
|
|
73
|
+
level: "debug",
|
|
74
|
+
category: "diagnostics.scope",
|
|
75
|
+
message: "LSP diagnostic tsconfig scope decisions",
|
|
76
|
+
cwd: truncateIdentity(manager.getCwd()),
|
|
77
|
+
data: {
|
|
78
|
+
caseSensitiveFileNames: summary.caseSensitiveFileNames,
|
|
79
|
+
counts: summary.counts,
|
|
80
|
+
basisCounts: summary.basisCounts,
|
|
81
|
+
totalFiles: summary.totalFiles,
|
|
82
|
+
entries: summary.entries.map((entry) => ({
|
|
83
|
+
file: truncateIdentity(entry.file),
|
|
84
|
+
status: entry.status,
|
|
85
|
+
...(entry.basis ? { basis: entry.basis } : {}),
|
|
86
|
+
})),
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
} catch {
|
|
90
|
+
// Telemetry must never turn a completed recovery into a failure.
|
|
91
|
+
}
|
|
127
92
|
}
|
|
128
93
|
|
|
129
94
|
class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
@@ -136,29 +101,38 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
136
101
|
|
|
137
102
|
// ── Semantic lookups ────────────────────────────────────────────────
|
|
138
103
|
|
|
139
|
-
async hover(
|
|
104
|
+
async hover(
|
|
105
|
+
filePath: string,
|
|
106
|
+
position: Position,
|
|
107
|
+
control?: CodeRequestControl,
|
|
108
|
+
): Promise<CodeQueryResult<Hover | null>> {
|
|
140
109
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
141
110
|
const client = await this.manager.ensureFileOpen(resolvedPath);
|
|
142
111
|
if (!client) return unavailableFileQuery("hover", resolvedPath);
|
|
143
|
-
return client.hover(resolvedPath, position);
|
|
112
|
+
return client.hover(resolvedPath, position, control);
|
|
144
113
|
}
|
|
145
114
|
|
|
146
115
|
async definition(
|
|
147
116
|
filePath: string,
|
|
148
117
|
position: Position,
|
|
118
|
+
control?: CodeRequestControl,
|
|
149
119
|
): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>> {
|
|
150
120
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
151
121
|
const client = await this.manager.ensureFileOpen(resolvedPath);
|
|
152
122
|
if (!client) return unavailableFileQuery("definition", resolvedPath);
|
|
153
|
-
return client.definition(resolvedPath, position);
|
|
123
|
+
return client.definition(resolvedPath, position, control);
|
|
154
124
|
}
|
|
155
125
|
|
|
156
|
-
async references(
|
|
126
|
+
async references(
|
|
127
|
+
filePath: string,
|
|
128
|
+
position: Position,
|
|
129
|
+
control?: CodeRequestControl,
|
|
130
|
+
): Promise<CodeQueryResult<Location[]>> {
|
|
157
131
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
158
132
|
const client = await this.manager.ensureFileOpen(resolvedPath);
|
|
159
133
|
if (!client) return unavailableFileQuery("references", resolvedPath);
|
|
160
134
|
return mapCodeQueryResult(
|
|
161
|
-
await client.references(resolvedPath, position),
|
|
135
|
+
await client.references(resolvedPath, position, control),
|
|
162
136
|
(data) => data ?? [],
|
|
163
137
|
);
|
|
164
138
|
}
|
|
@@ -166,43 +140,58 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
166
140
|
async implementation(
|
|
167
141
|
filePath: string,
|
|
168
142
|
position: Position,
|
|
143
|
+
control?: CodeRequestControl,
|
|
169
144
|
): Promise<CodeQueryResult<Location | Location[] | LocationLink[] | null>> {
|
|
170
145
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
171
146
|
const client = await this.manager.ensureFileOpen(resolvedPath);
|
|
172
147
|
if (!client) return unavailableFileQuery("implementation", resolvedPath);
|
|
173
|
-
return client.implementation(resolvedPath, position);
|
|
148
|
+
return client.implementation(resolvedPath, position, control);
|
|
174
149
|
}
|
|
175
150
|
|
|
176
151
|
async documentSymbols(
|
|
177
152
|
filePath: string,
|
|
153
|
+
control?: CodeRequestControl,
|
|
178
154
|
): Promise<CodeQueryResult<DocumentSymbol[] | SymbolInformation[]>> {
|
|
179
155
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
180
156
|
const client = await this.manager.ensureFileOpen(resolvedPath);
|
|
181
157
|
if (!client) return unavailableFileQuery("document symbols", resolvedPath);
|
|
182
|
-
return mapCodeQueryResult(
|
|
158
|
+
return mapCodeQueryResult(
|
|
159
|
+
await client.documentSymbols(resolvedPath, control),
|
|
160
|
+
(data) => data ?? [],
|
|
161
|
+
);
|
|
183
162
|
}
|
|
184
163
|
|
|
185
164
|
async workspaceSymbol(
|
|
186
165
|
query: string,
|
|
166
|
+
control?: CodeRequestControl,
|
|
187
167
|
): Promise<CodeQueryResult<SymbolInformation[] | WorkspaceSymbol[]>> {
|
|
188
|
-
return this.manager.workspaceSymbol(query);
|
|
168
|
+
return this.manager.workspaceSymbol(query, control);
|
|
189
169
|
}
|
|
190
170
|
|
|
191
171
|
async rename(
|
|
192
172
|
filePath: string,
|
|
193
173
|
position: Position,
|
|
194
174
|
newName: string,
|
|
195
|
-
|
|
175
|
+
control?: CodeRequestControl,
|
|
176
|
+
): Promise<RoutedMutationResponse<WorkspaceEdit | null> | null> {
|
|
196
177
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
197
178
|
const client = await this.manager.ensureFileOpen(resolvedPath);
|
|
198
179
|
if (!client) return null;
|
|
199
|
-
return
|
|
180
|
+
return {
|
|
181
|
+
value: await client.rename(resolvedPath, position, newName, control),
|
|
182
|
+
authorizedMutationRoots: [client.root],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
getOpenDocumentVersion(filePath: string): number | null {
|
|
187
|
+
return this.manager.getOpenDocumentVersion(this.resolveFilePath(filePath));
|
|
200
188
|
}
|
|
201
189
|
|
|
202
190
|
async codeActions(
|
|
203
191
|
filePath: string,
|
|
204
192
|
positionOrRange: Position | Range,
|
|
205
|
-
|
|
193
|
+
control?: CodeRequestControl,
|
|
194
|
+
): Promise<RoutedMutationResponse<CodeAction[] | null> | null> {
|
|
206
195
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
207
196
|
const client = await this.manager.ensureFileOpen(resolvedPath);
|
|
208
197
|
if (!client) return null;
|
|
@@ -215,7 +204,10 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
215
204
|
.filter((diagnostic) => diagnostic.range.end.line >= range.start.line)
|
|
216
205
|
.filter((diagnostic) => diagnostic.range.start.line <= range.end.line);
|
|
217
206
|
|
|
218
|
-
return
|
|
207
|
+
return {
|
|
208
|
+
value: await client.codeActions(resolvedPath, range, { diagnostics }, control),
|
|
209
|
+
authorizedMutationRoots: [client.root],
|
|
210
|
+
};
|
|
219
211
|
}
|
|
220
212
|
|
|
221
213
|
/**
|
|
@@ -225,6 +217,7 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
225
217
|
async waitUntilReadyForFile(
|
|
226
218
|
filePath: string,
|
|
227
219
|
options: { timeoutMs?: number } = {},
|
|
220
|
+
control?: CodeRequestControl,
|
|
228
221
|
): Promise<SemanticReadinessResult> {
|
|
229
222
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
230
223
|
if (!this.manager.canServeFile(resolvedPath)) {
|
|
@@ -235,8 +228,9 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
235
228
|
}
|
|
236
229
|
|
|
237
230
|
const readiness = await raceReadinessValue(
|
|
238
|
-
this.manager.waitUntilFileReady(resolvedPath),
|
|
231
|
+
this.manager.waitUntilFileReady(resolvedPath, control),
|
|
239
232
|
options.timeoutMs,
|
|
233
|
+
control,
|
|
240
234
|
);
|
|
241
235
|
if (readiness.kind !== "resolved") return readiness;
|
|
242
236
|
if (readiness.value === null) {
|
|
@@ -254,10 +248,12 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
254
248
|
*/
|
|
255
249
|
async waitUntilReadyForWorkspace(
|
|
256
250
|
options: { timeoutMs?: number } = {},
|
|
251
|
+
control?: CodeRequestControl,
|
|
257
252
|
): Promise<SemanticReadinessResult> {
|
|
258
253
|
const readiness = await raceReadinessValue(
|
|
259
|
-
this.manager.waitUntilWorkspaceReady(),
|
|
254
|
+
this.manager.waitUntilWorkspaceReady(control),
|
|
260
255
|
options.timeoutMs,
|
|
256
|
+
control,
|
|
261
257
|
);
|
|
262
258
|
if (readiness.kind !== "resolved") return readiness;
|
|
263
259
|
if (readiness.value === 0) {
|
|
@@ -297,7 +293,7 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
297
293
|
/** Notify routed clients of workspace file changes and reset pull state. */
|
|
298
294
|
noteWorkspaceChanges(changes: FileEvent[]): void {
|
|
299
295
|
this.manager.clearAllPullResultIds();
|
|
300
|
-
this.manager.
|
|
296
|
+
this.manager.noteWorkspaceChanges(changes);
|
|
301
297
|
}
|
|
302
298
|
|
|
303
299
|
async #shutdown(): Promise<void> {
|
|
@@ -310,34 +306,36 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
310
306
|
async fileDiagnostics(
|
|
311
307
|
filePath: string,
|
|
312
308
|
maxSeverity: number = 4,
|
|
309
|
+
control?: CodeRequestControl,
|
|
313
310
|
): Promise<CodeQueryResult<Diagnostic[]>> {
|
|
314
311
|
const resolvedPath = this.resolveFilePath(filePath);
|
|
315
312
|
if (!this.manager.canServeFile(resolvedPath)) {
|
|
316
313
|
return unavailableFileQuery("diagnostics", resolvedPath);
|
|
317
314
|
}
|
|
318
|
-
return this.manager.syncFileAndGetDiagnostics(resolvedPath, maxSeverity);
|
|
315
|
+
return this.manager.syncFileAndGetDiagnostics(resolvedPath, maxSeverity, control);
|
|
319
316
|
}
|
|
320
317
|
|
|
321
318
|
/** Re-sync every open document and wait for diagnostics to settle. */
|
|
322
|
-
async refreshOpenDiagnostics(
|
|
323
|
-
|
|
319
|
+
async refreshOpenDiagnostics(
|
|
320
|
+
options?: { maxWaitMs?: number; quietMs?: number },
|
|
321
|
+
control?: CodeRequestControl,
|
|
322
|
+
): Promise<DiagnosticEvidenceSummary> {
|
|
323
|
+
return this.manager.refreshOpenDiagnostics({ ...options, ...control });
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
/** Get a lightweight workspace diagnostic summary for all tracked files. */
|
|
327
|
-
getWorkspaceDiagnosticSummary()
|
|
328
|
-
return this.manager.
|
|
327
|
+
getWorkspaceDiagnosticSummary() {
|
|
328
|
+
return this.manager.getDiagnosticSnapshot();
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
/** Get outstanding diagnostics grouped by file at or above the supplied severity threshold. */
|
|
332
|
-
getOutstandingDiagnostics(
|
|
333
|
-
maxSeverity
|
|
334
|
-
): Array<{ file: string; diagnostics: Diagnostic[] }> {
|
|
335
|
-
return this.manager.getOutstandingDiagnostics(maxSeverity);
|
|
332
|
+
getOutstandingDiagnostics(maxSeverity: number = 1) {
|
|
333
|
+
return this.manager.getOutstandingDiagnosticsSnapshot(maxSeverity);
|
|
336
334
|
}
|
|
337
335
|
|
|
338
336
|
/** Get outstanding diagnostic counts grouped by file. */
|
|
339
|
-
getOutstandingDiagnosticSummary(maxSeverity: number = 1)
|
|
340
|
-
return this.manager.
|
|
337
|
+
getOutstandingDiagnosticSummary(maxSeverity: number = 1) {
|
|
338
|
+
return this.manager.getOutstandingDiagnosticSummarySnapshot(maxSeverity);
|
|
341
339
|
}
|
|
342
340
|
|
|
343
341
|
/** Trigger a workspace-wide diagnostics refresh and stale-state recovery pass. */
|
|
@@ -345,8 +343,53 @@ class DefaultWorkspaceLspRuntime implements WorkspaceLspRuntime {
|
|
|
345
343
|
restartIfStillStale?: boolean;
|
|
346
344
|
maxWaitMs?: number;
|
|
347
345
|
quietMs?: number;
|
|
346
|
+
/** Evidence from a refresh the caller already completed; skips this pass's own refresh when no watched-file changes apply. */
|
|
347
|
+
initialEvidence?: DiagnosticEvidenceSummary;
|
|
348
|
+
control?: CodeRequestControl;
|
|
348
349
|
}): Promise<RecoverDiagnosticsResult> {
|
|
349
|
-
|
|
350
|
+
const recoveryStartedAt = Date.now();
|
|
351
|
+
try {
|
|
352
|
+
const result = await this.manager.recoverWorkspaceDiagnostics(options);
|
|
353
|
+
const outcome = result.refreshFailureReason ? "failed" : "completed";
|
|
354
|
+
recordDebugEvent({
|
|
355
|
+
source: "lsp",
|
|
356
|
+
level: "debug",
|
|
357
|
+
category: "runtime.recovery",
|
|
358
|
+
message: `LSP diagnostic recovery ${outcome}`,
|
|
359
|
+
cwd: truncateIdentity(this.manager.getCwd()),
|
|
360
|
+
data: {
|
|
361
|
+
outcome,
|
|
362
|
+
elapsedMs: result.elapsedMs,
|
|
363
|
+
attemptedClients: result.attemptedClients,
|
|
364
|
+
restartedClients: result.restartedClients,
|
|
365
|
+
attemptedServers: boundServerNames(result.attemptedServers ?? []),
|
|
366
|
+
restartedServers: boundServerNames(result.restartedServers ?? []),
|
|
367
|
+
...(result.restartReason ? { reason: result.restartReason } : {}),
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
recordScopeDecisionEvent(this.manager);
|
|
371
|
+
return result;
|
|
372
|
+
} catch (error) {
|
|
373
|
+
// A cancelled pass has no result object, so telemetry records the
|
|
374
|
+
// cancelled outcome, the elapsed time, and the server names that are
|
|
375
|
+
// still running at cancellation. Restart identity is unavailable
|
|
376
|
+
// because the pass produced no result.
|
|
377
|
+
if (isCodeRequestInterruption(error, options?.control)) {
|
|
378
|
+
recordDebugEvent({
|
|
379
|
+
source: "lsp",
|
|
380
|
+
level: "debug",
|
|
381
|
+
category: "runtime.recovery",
|
|
382
|
+
message: "LSP diagnostic recovery cancelled",
|
|
383
|
+
cwd: truncateIdentity(this.manager.getCwd()),
|
|
384
|
+
data: {
|
|
385
|
+
outcome: "cancelled",
|
|
386
|
+
elapsedMs: Date.now() - recoveryStartedAt,
|
|
387
|
+
attemptedServers: boundServerNames(this.manager.getRunningClientNames()),
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
throw error;
|
|
392
|
+
}
|
|
350
393
|
}
|
|
351
394
|
|
|
352
395
|
private resolveFilePath(filePath: string): string {
|
|
@@ -380,15 +423,19 @@ export function getWorkspaceLspRuntime(cwd: string): WorkspaceLspRuntimeState {
|
|
|
380
423
|
export async function waitForWorkspaceLspRuntime(
|
|
381
424
|
cwd: string,
|
|
382
425
|
timeoutMs: number = 250,
|
|
426
|
+
control?: CodeRequestControl,
|
|
383
427
|
): Promise<WorkspaceLspRuntimeState> {
|
|
384
428
|
const deadline = Date.now() + Math.max(0, timeoutMs);
|
|
385
429
|
let state = getWorkspaceLspRuntime(cwd);
|
|
386
430
|
|
|
387
431
|
while (state.kind === "pending" && Date.now() < deadline) {
|
|
432
|
+
throwIfCodeRequestInterrupted(control);
|
|
388
433
|
await new Promise((resolve) => setTimeout(resolve, WAIT_INTERVAL_MS));
|
|
389
434
|
state = getWorkspaceLspRuntime(cwd);
|
|
390
435
|
}
|
|
391
436
|
|
|
437
|
+
// A cancelled poll must not hand a runtime to a caller that no longer awaits.
|
|
438
|
+
throwIfCodeRequestInterrupted(control);
|
|
392
439
|
return state;
|
|
393
440
|
}
|
|
394
441
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { recordDebugEvent } from "@mrclrchtr/supi-core/debug";
|
|
2
|
+
import type { ProjectServerInfo } from "../config/types.ts";
|
|
3
|
+
import { MAX_SERVERS, truncateIdentity } from "../debug-telemetry.ts";
|
|
4
|
+
import type { LspRuntimeTransition } from "./runtime-controller.ts";
|
|
5
|
+
|
|
6
|
+
/** One bounded server entry in a runtime-transition payload. */
|
|
7
|
+
export interface TransitionServerEntry {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly status: ProjectServerInfo["status"];
|
|
10
|
+
readonly ready: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Bound a project-server snapshot to MAX_SERVERS name/status/ready entries. */
|
|
14
|
+
function boundedServerEntries(
|
|
15
|
+
projectServers: readonly ProjectServerInfo[],
|
|
16
|
+
): TransitionServerEntry[] {
|
|
17
|
+
return projectServers.slice(0, MAX_SERVERS).map((server) => ({
|
|
18
|
+
name: truncateIdentity(server.name),
|
|
19
|
+
status: server.status,
|
|
20
|
+
ready: server.ready,
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Record bounded aggregate telemetry for one runtime transition. */
|
|
25
|
+
export function recordLspRuntimeTransition(cwd: string, transition: LspRuntimeTransition): void {
|
|
26
|
+
const readyClients = transition.projectServers.filter(
|
|
27
|
+
(server) => server.status === "running" && server.ready,
|
|
28
|
+
).length;
|
|
29
|
+
const trackedFiles = transition.projectServers.reduce(
|
|
30
|
+
(count, server) => count + server.openFiles.length,
|
|
31
|
+
0,
|
|
32
|
+
);
|
|
33
|
+
recordDebugEvent({
|
|
34
|
+
source: "lsp",
|
|
35
|
+
level: transition.kind === "crash" ? "warning" : "debug",
|
|
36
|
+
category: "runtime.transition",
|
|
37
|
+
message: `LSP runtime transition: ${transition.kind}`,
|
|
38
|
+
cwd: truncateIdentity(cwd),
|
|
39
|
+
data: {
|
|
40
|
+
generation: transition.generation,
|
|
41
|
+
kind: transition.kind,
|
|
42
|
+
semanticReady: transition.semanticReady,
|
|
43
|
+
readyClients,
|
|
44
|
+
totalClients: transition.projectServers.length,
|
|
45
|
+
trackedFiles,
|
|
46
|
+
servers: boundedServerEntries(transition.projectServers),
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|