@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
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/** Presentation-neutral relation collection used by the session-owned graph workflow. */
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
type CodeRequestControl,
|
|
5
|
+
isCodeRequestInterruption,
|
|
6
|
+
unavailableCodeQuery,
|
|
7
|
+
} from "@mrclrchtr/supi-code-runtime/api";
|
|
3
8
|
import type { CodeProvider } from "../../analysis/provider.ts";
|
|
4
9
|
import {
|
|
5
10
|
readNextEnclosingScope,
|
|
@@ -25,6 +30,7 @@ export interface CollectRelationOptions {
|
|
|
25
30
|
semanticReadinessError: string | null;
|
|
26
31
|
anchorKind: AnchorKind;
|
|
27
32
|
calleeDepth?: "direct" | "deep";
|
|
33
|
+
requestControl?: CodeRequestControl;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
/** Collect one evidence-backed graph relation without rendering it. */
|
|
@@ -46,6 +52,7 @@ export async function collectRelation(
|
|
|
46
52
|
return collectImplementationsRelation(options);
|
|
47
53
|
}
|
|
48
54
|
} catch (error) {
|
|
55
|
+
if (isCodeRequestInterruption(error, options.requestControl)) throw error;
|
|
49
56
|
return {
|
|
50
57
|
kind: "unavailable",
|
|
51
58
|
rel: relation,
|
|
@@ -61,7 +68,11 @@ async function collectReferences(options: CollectRelationOptions): Promise<Graph
|
|
|
61
68
|
|
|
62
69
|
const result = await collectCallers(options.file, options.position, options.displayName, {
|
|
63
70
|
cwd: options.cwd,
|
|
64
|
-
provider: {
|
|
71
|
+
provider: {
|
|
72
|
+
references: async (file, position) =>
|
|
73
|
+
options.provider?.references(file, position, options.requestControl) ??
|
|
74
|
+
unavailableCodeQuery("References unavailable"),
|
|
75
|
+
},
|
|
65
76
|
});
|
|
66
77
|
if (result.confidence === "unavailable") {
|
|
67
78
|
return { kind: "unavailable", rel: "references", message: "References unavailable" };
|
|
@@ -118,6 +129,7 @@ async function collectCalleesRelation(options: CollectRelationOptions): Promise<
|
|
|
118
129
|
{ cwd: options.cwd, provider: { calleesAt: options.provider.calleesAt } },
|
|
119
130
|
undefined,
|
|
120
131
|
options.calleeDepth ?? "direct",
|
|
132
|
+
options.requestControl,
|
|
121
133
|
);
|
|
122
134
|
if (result.confidence === "unavailable") {
|
|
123
135
|
return { kind: "unavailable", rel: "callees", message: "Callees unavailable" };
|
|
@@ -161,7 +173,11 @@ async function collectImplementationsRelation(
|
|
|
161
173
|
|
|
162
174
|
const result = await collectImplementations(options.file, options.position, options.displayName, {
|
|
163
175
|
cwd: options.cwd,
|
|
164
|
-
provider: {
|
|
176
|
+
provider: {
|
|
177
|
+
implementation: async (file, position) =>
|
|
178
|
+
options.provider?.implementation(file, position, options.requestControl) ??
|
|
179
|
+
unavailableCodeQuery("Implementations unavailable"),
|
|
180
|
+
},
|
|
165
181
|
});
|
|
166
182
|
if (result.confidence === "unavailable") {
|
|
167
183
|
return { kind: "unavailable", rel: "implements", message: "Implementations unavailable" };
|
|
@@ -54,7 +54,9 @@ export async function runGraphWorkflow(
|
|
|
54
54
|
maxResults: request.maxResults,
|
|
55
55
|
},
|
|
56
56
|
deps,
|
|
57
|
+
control,
|
|
57
58
|
);
|
|
59
|
+
throwIfAborted(control);
|
|
58
60
|
if (targetOutcome.kind === "target-group") {
|
|
59
61
|
return {
|
|
60
62
|
kind: "invalid-input",
|
|
@@ -64,12 +66,13 @@ export async function runGraphWorkflow(
|
|
|
64
66
|
if (targetOutcome.kind !== "resolved") return targetOutcome;
|
|
65
67
|
|
|
66
68
|
const entry = targetOutcome.entry;
|
|
67
|
-
const semanticReadinessError = await getSemanticReadinessError(
|
|
69
|
+
const semanticReadinessError = await getSemanticReadinessError({
|
|
68
70
|
relations,
|
|
69
|
-
entry.file,
|
|
70
|
-
deps.capability,
|
|
71
|
-
deps.cwd,
|
|
72
|
-
|
|
71
|
+
file: entry.file,
|
|
72
|
+
capability: deps.capability,
|
|
73
|
+
cwd: deps.cwd,
|
|
74
|
+
control,
|
|
75
|
+
});
|
|
73
76
|
const provider = deps.capability.getProvider(deps.cwd);
|
|
74
77
|
const maxResults = request.maxResults ?? 8;
|
|
75
78
|
const displayName =
|
|
@@ -94,9 +97,11 @@ export async function runGraphWorkflow(
|
|
|
94
97
|
semanticReadinessError,
|
|
95
98
|
anchorKind: entry.anchorKind,
|
|
96
99
|
calleeDepth: request.calleeDepth,
|
|
100
|
+
requestControl: control,
|
|
97
101
|
}),
|
|
98
102
|
);
|
|
99
103
|
}
|
|
104
|
+
throwIfAborted(control);
|
|
100
105
|
|
|
101
106
|
if (sections.length > 0 && sections.every((section) => section.kind === "unavailable")) {
|
|
102
107
|
return {
|
|
@@ -127,16 +132,18 @@ function normalizeRelations(
|
|
|
127
132
|
return requested as readonly GraphRelationKind[];
|
|
128
133
|
}
|
|
129
134
|
|
|
130
|
-
async function getSemanticReadinessError(
|
|
131
|
-
relations: readonly GraphRelationKind[]
|
|
132
|
-
file: string
|
|
133
|
-
capability: CapabilityAdapter
|
|
134
|
-
cwd: string
|
|
135
|
-
|
|
135
|
+
async function getSemanticReadinessError(options: {
|
|
136
|
+
relations: readonly GraphRelationKind[];
|
|
137
|
+
file: string;
|
|
138
|
+
capability: CapabilityAdapter;
|
|
139
|
+
cwd: string;
|
|
140
|
+
control?: WorkflowControl;
|
|
141
|
+
}): Promise<string | null> {
|
|
142
|
+
const { relations, file, capability, cwd, control } = options;
|
|
136
143
|
if (!relations.some((relation) => relation === "references" || relation === "implements")) {
|
|
137
144
|
return null;
|
|
138
145
|
}
|
|
139
|
-
const readiness = await capability.ensureSemanticReadiness(cwd, { kind: "file", file });
|
|
146
|
+
const readiness = await capability.ensureSemanticReadiness(cwd, { kind: "file", file }, control);
|
|
140
147
|
if (readiness.kind === "ready") return null;
|
|
141
148
|
if (readiness.kind === "timeout") {
|
|
142
149
|
return "Semantic readiness timed out. Retry shortly or inspect code_health.";
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type CodeRequestControl,
|
|
3
|
+
isCodeRequestInterruption,
|
|
4
|
+
} from "@mrclrchtr/supi-code-runtime/api";
|
|
5
|
+
import type { WorkspaceDiagnosticReport, WorkspaceLspRuntime } from "@mrclrchtr/supi-lsp/api";
|
|
6
|
+
import { recoverDiagnosticRuntime } from "../analysis/health/recovery.ts";
|
|
7
|
+
import { mergeDiagnosticEvidence } from "../diagnostics/evidence.ts";
|
|
8
|
+
import { refreshFileLspMaintenance, refreshLspMaintenance } from "../substrate/lsp/maintenance.ts";
|
|
9
|
+
import type { HealthDiagnosticScope, HealthRefreshAttempt } from "./health-types.ts";
|
|
10
|
+
|
|
11
|
+
interface HealthRefreshAttemptOptions {
|
|
12
|
+
readonly runtime: WorkspaceLspRuntime;
|
|
13
|
+
readonly diagnosticsScope: HealthDiagnosticScope;
|
|
14
|
+
readonly attemptedAt: number;
|
|
15
|
+
readonly cwd: string;
|
|
16
|
+
readonly sentinelSnapshot: Map<string, number>;
|
|
17
|
+
readonly control?: CodeRequestControl;
|
|
18
|
+
readonly reportRecoveryProgress?: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HealthRefreshCollection {
|
|
22
|
+
readonly attempt: HealthRefreshAttempt;
|
|
23
|
+
/** Final report from the runtime, retained only for the current workflow. */
|
|
24
|
+
readonly diagnosticReport?: WorkspaceDiagnosticReport;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Run one file- or workspace-scoped health refresh attempt. */
|
|
28
|
+
export async function collectHealthRefreshAttempt(
|
|
29
|
+
options: HealthRefreshAttemptOptions,
|
|
30
|
+
): Promise<HealthRefreshCollection> {
|
|
31
|
+
if (options.diagnosticsScope.kind === "file") {
|
|
32
|
+
return collectFileRefreshAttempt(options, options.diagnosticsScope);
|
|
33
|
+
}
|
|
34
|
+
return collectWorkspaceRefreshAttempt(options);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function collectFileRefreshAttempt(
|
|
38
|
+
options: HealthRefreshAttemptOptions,
|
|
39
|
+
scope: Extract<HealthDiagnosticScope, { kind: "file" }>,
|
|
40
|
+
): Promise<HealthRefreshCollection> {
|
|
41
|
+
const maintenance = await refreshFileLspMaintenance({
|
|
42
|
+
runtime: options.runtime,
|
|
43
|
+
cwd: options.cwd,
|
|
44
|
+
sentinelSnapshot: options.sentinelSnapshot,
|
|
45
|
+
filePath: scope.path,
|
|
46
|
+
control: options.control,
|
|
47
|
+
});
|
|
48
|
+
updateSentinelSnapshot(options.sentinelSnapshot, maintenance.snapshot);
|
|
49
|
+
const readiness = await options.runtime.waitUntilReadyForFile(
|
|
50
|
+
scope.path,
|
|
51
|
+
undefined,
|
|
52
|
+
options.control,
|
|
53
|
+
);
|
|
54
|
+
return {
|
|
55
|
+
attempt: {
|
|
56
|
+
kind: "completed",
|
|
57
|
+
attemptedAt: options.attemptedAt,
|
|
58
|
+
elapsedMs: Date.now() - options.attemptedAt,
|
|
59
|
+
requestedDiagnosticScope: scope,
|
|
60
|
+
operationScope: "file-runtime",
|
|
61
|
+
attemptedActiveClients: readiness.kind === "ready" ? 1 : 0,
|
|
62
|
+
restartedClients: 0,
|
|
63
|
+
staleAssessment: {
|
|
64
|
+
scope: "file",
|
|
65
|
+
suspected: null,
|
|
66
|
+
matchedFileCount: maintenance.matchedStaleFileCount,
|
|
67
|
+
warning: null,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function collectWorkspaceRefreshAttempt(
|
|
74
|
+
options: HealthRefreshAttemptOptions,
|
|
75
|
+
): Promise<HealthRefreshCollection> {
|
|
76
|
+
const workspaceScope =
|
|
77
|
+
options.diagnosticsScope.kind === "tracked-files" ? options.diagnosticsScope : null;
|
|
78
|
+
const maintenance = await refreshLspMaintenance(
|
|
79
|
+
options.runtime,
|
|
80
|
+
options.cwd,
|
|
81
|
+
options.sentinelSnapshot,
|
|
82
|
+
{
|
|
83
|
+
control: options.control,
|
|
84
|
+
scope: workspaceScope?.filter ?? null,
|
|
85
|
+
trackSources: workspaceScope !== null,
|
|
86
|
+
},
|
|
87
|
+
);
|
|
88
|
+
updateSentinelSnapshot(options.sentinelSnapshot, maintenance.snapshot);
|
|
89
|
+
if (maintenance.failureReason) {
|
|
90
|
+
return {
|
|
91
|
+
attempt: {
|
|
92
|
+
kind: "failed",
|
|
93
|
+
attemptedAt: options.attemptedAt,
|
|
94
|
+
elapsedMs: Date.now() - options.attemptedAt,
|
|
95
|
+
requestedDiagnosticScope: options.diagnosticsScope,
|
|
96
|
+
operationScope: "workspace-runtime",
|
|
97
|
+
diagnosticEvidence: maintenance.diagnosticEvidence,
|
|
98
|
+
reason: maintenance.failureReason,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const recovery = await recoverDiagnosticRuntime({
|
|
105
|
+
service: options.runtime,
|
|
106
|
+
control: options.control,
|
|
107
|
+
progress: options.reportRecoveryProgress,
|
|
108
|
+
// The maintenance pass already refreshed every open document; reuse its
|
|
109
|
+
// evidence so the recovery pass skips a redundant second refresh.
|
|
110
|
+
initialEvidence: maintenance.diagnosticEvidence,
|
|
111
|
+
});
|
|
112
|
+
const diagnosticEvidence = mergeDiagnosticEvidence(
|
|
113
|
+
maintenance.diagnosticEvidence,
|
|
114
|
+
recovery.diagnosticEvidence,
|
|
115
|
+
options.cwd,
|
|
116
|
+
);
|
|
117
|
+
if (recovery.refreshFailureReason) {
|
|
118
|
+
return {
|
|
119
|
+
attempt: {
|
|
120
|
+
kind: "failed",
|
|
121
|
+
attemptedAt: options.attemptedAt,
|
|
122
|
+
elapsedMs: Date.now() - options.attemptedAt,
|
|
123
|
+
requestedDiagnosticScope: options.diagnosticsScope,
|
|
124
|
+
operationScope: "workspace-runtime",
|
|
125
|
+
diagnosticEvidence,
|
|
126
|
+
reason: recovery.refreshFailureReason,
|
|
127
|
+
},
|
|
128
|
+
diagnosticReport: recovery.diagnosticReport,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
attempt: {
|
|
133
|
+
kind: "completed",
|
|
134
|
+
attemptedAt: options.attemptedAt,
|
|
135
|
+
elapsedMs: Date.now() - options.attemptedAt,
|
|
136
|
+
requestedDiagnosticScope: options.diagnosticsScope,
|
|
137
|
+
operationScope: "workspace-runtime",
|
|
138
|
+
attemptedActiveClients: recovery.attemptedClients,
|
|
139
|
+
restartedClients: recovery.restartedClients,
|
|
140
|
+
diagnosticEvidence,
|
|
141
|
+
staleAssessment: {
|
|
142
|
+
scope: "workspace",
|
|
143
|
+
suspected: recovery.staleAssessment.suspected,
|
|
144
|
+
matchedFileCount: recovery.staleAssessment.matchedFiles.length,
|
|
145
|
+
warning: recovery.staleAssessment.warning,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
diagnosticReport: recovery.diagnosticReport,
|
|
149
|
+
};
|
|
150
|
+
} catch (error) {
|
|
151
|
+
// Cancellation must propagate; a cancelled caller no longer awaits a
|
|
152
|
+
// recorded failed attempt.
|
|
153
|
+
if (isCodeRequestInterruption(error, options.control)) throw error;
|
|
154
|
+
return {
|
|
155
|
+
attempt: {
|
|
156
|
+
kind: "failed",
|
|
157
|
+
attemptedAt: options.attemptedAt,
|
|
158
|
+
elapsedMs: Date.now() - options.attemptedAt,
|
|
159
|
+
requestedDiagnosticScope: options.diagnosticsScope,
|
|
160
|
+
operationScope: "workspace-runtime",
|
|
161
|
+
diagnosticEvidence: maintenance.diagnosticEvidence,
|
|
162
|
+
reason: errorMessage(error),
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function updateSentinelSnapshot(target: Map<string, number>, next: Map<string, number>): void {
|
|
169
|
+
target.clear();
|
|
170
|
+
for (const [key, value] of next) target.set(key, value);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function errorMessage(error: unknown): string {
|
|
174
|
+
return error instanceof Error && error.message ? error.message : "Diagnostic refresh failed.";
|
|
175
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DiagnosticEvidenceSummary, FileScopeDecision } from "@mrclrchtr/supi-lsp/api";
|
|
1
2
|
import type { CapabilityWarningReport } from "../analysis/capability/capability-warnings.ts";
|
|
2
3
|
|
|
3
4
|
export type HealthSection = "diagnostics" | "servers";
|
|
@@ -53,46 +54,73 @@ export type HealthDiagnosticObservation =
|
|
|
53
54
|
readonly kind: "completed";
|
|
54
55
|
readonly scope: HealthDiagnosticScope;
|
|
55
56
|
readonly entries: readonly HealthDiagnosticEntry[];
|
|
57
|
+
readonly evidence: DiagnosticEvidenceSummary;
|
|
58
|
+
/** Tsconfig scope decision for the requested file (file scope only). */
|
|
59
|
+
readonly scopeStatus?: FileScopeDecision;
|
|
56
60
|
}
|
|
57
61
|
| {
|
|
58
62
|
readonly kind: "partial";
|
|
59
63
|
readonly scope: HealthDiagnosticScope;
|
|
60
64
|
readonly entries: readonly HealthDiagnosticEntry[];
|
|
65
|
+
readonly evidence: DiagnosticEvidenceSummary;
|
|
61
66
|
readonly reason: string;
|
|
67
|
+
/** Tsconfig scope decision for the requested file (file scope only). */
|
|
68
|
+
readonly scopeStatus?: FileScopeDecision;
|
|
62
69
|
}
|
|
63
70
|
| {
|
|
64
71
|
readonly kind: "unavailable";
|
|
65
72
|
readonly scope: HealthDiagnosticScope;
|
|
66
73
|
readonly entries: readonly HealthDiagnosticEntry[];
|
|
74
|
+
readonly evidence: DiagnosticEvidenceSummary;
|
|
67
75
|
readonly reason: string;
|
|
76
|
+
/** Tsconfig scope decision for the requested file (file scope only). */
|
|
77
|
+
readonly scopeStatus?: FileScopeDecision;
|
|
68
78
|
};
|
|
69
79
|
|
|
70
|
-
/** Bounded stale-diagnostic metadata from
|
|
80
|
+
/** Bounded stale-diagnostic metadata from one refresh attempt. */
|
|
71
81
|
export interface HealthStaleAssessment {
|
|
72
|
-
readonly
|
|
82
|
+
readonly scope: "file" | "workspace";
|
|
83
|
+
readonly suspected: boolean | null;
|
|
73
84
|
readonly matchedFileCount: number;
|
|
74
85
|
readonly warning: string | null;
|
|
75
86
|
}
|
|
76
87
|
|
|
77
|
-
|
|
88
|
+
export type HealthRefreshOperationScope = "file-runtime" | "workspace-runtime";
|
|
89
|
+
|
|
90
|
+
/** Shared facts for one completed refresh or file-maintenance attempt. */
|
|
91
|
+
interface CompletedHealthRefreshAttempt {
|
|
92
|
+
readonly kind: "completed";
|
|
93
|
+
readonly attemptedAt: number;
|
|
94
|
+
/** Wall-clock duration of the attempt, for telemetry. */
|
|
95
|
+
readonly elapsedMs: number;
|
|
96
|
+
/** The diagnostic evidence scope requested by the caller, not the runtime operation scope. */
|
|
97
|
+
readonly requestedDiagnosticScope: HealthDiagnosticScope;
|
|
98
|
+
/** Active clients targeted by the best-effort operation; this is not a confirmed-success count. */
|
|
99
|
+
readonly attemptedActiveClients: number;
|
|
100
|
+
readonly restartedClients: number;
|
|
101
|
+
readonly staleAssessment: HealthStaleAssessment;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** A diagnostic refresh attempt against an explicit LSP runtime scope. */
|
|
78
105
|
export type HealthRefreshAttempt =
|
|
79
|
-
| {
|
|
80
|
-
readonly kind: "completed";
|
|
81
|
-
readonly attemptedAt: number;
|
|
82
|
-
/** The diagnostic evidence scope requested by the caller, not the runtime operation scope. */
|
|
83
|
-
readonly requestedDiagnosticScope: HealthDiagnosticScope;
|
|
84
|
-
/** Recovery always operates against the workspace runtime. */
|
|
106
|
+
| (CompletedHealthRefreshAttempt & {
|
|
85
107
|
readonly operationScope: "workspace-runtime";
|
|
86
|
-
/**
|
|
87
|
-
readonly
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
108
|
+
/** Final document-level evidence from the refresh or recovery pass. */
|
|
109
|
+
readonly diagnosticEvidence: DiagnosticEvidenceSummary;
|
|
110
|
+
})
|
|
111
|
+
| (CompletedHealthRefreshAttempt & {
|
|
112
|
+
/** File maintenance does not claim a workspace diagnostic refresh. */
|
|
113
|
+
readonly operationScope: "file-runtime";
|
|
114
|
+
})
|
|
91
115
|
| {
|
|
92
116
|
readonly kind: "failed";
|
|
93
117
|
readonly attemptedAt: number;
|
|
118
|
+
/** Wall-clock duration of the attempt, for telemetry. */
|
|
119
|
+
readonly elapsedMs: number;
|
|
94
120
|
readonly requestedDiagnosticScope: HealthDiagnosticScope;
|
|
95
|
-
readonly operationScope:
|
|
121
|
+
readonly operationScope: HealthRefreshOperationScope;
|
|
122
|
+
/** Evidence collected before the operation failed, when available. */
|
|
123
|
+
readonly diagnosticEvidence?: DiagnosticEvidenceSummary;
|
|
96
124
|
readonly reason: string;
|
|
97
125
|
};
|
|
98
126
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/** Session-owned workspace health workflow. */
|
|
2
2
|
|
|
3
3
|
import type { CapabilityState } from "@mrclrchtr/supi-code-runtime/api";
|
|
4
|
+
import { isCodeRequestInterruption } from "@mrclrchtr/supi-code-runtime/api";
|
|
4
5
|
import type {
|
|
5
6
|
LspRuntimeController,
|
|
7
|
+
WorkspaceDiagnosticReport,
|
|
6
8
|
WorkspaceLspRuntime,
|
|
7
9
|
WorkspaceLspRuntimeState,
|
|
8
10
|
} from "@mrclrchtr/supi-lsp/api";
|
|
@@ -15,11 +17,12 @@ import {
|
|
|
15
17
|
diagnosticScope,
|
|
16
18
|
isScopedFile,
|
|
17
19
|
} from "../analysis/health/diagnostics.ts";
|
|
18
|
-
import { describeStructuralState
|
|
20
|
+
import { describeStructuralState } from "../analysis/health/recovery.ts";
|
|
19
21
|
import { collectServers } from "../analysis/health/signals.ts";
|
|
22
|
+
import { SEMANTIC_READINESS_TIMEOUT_REASON } from "../analysis/readiness.ts";
|
|
20
23
|
import { resolveScope } from "../analysis/search/paths.ts";
|
|
21
|
-
import { refreshLspMaintenance } from "../substrate/lsp/maintenance.ts";
|
|
22
24
|
import type { CapabilityAdapter } from "./capability-adapter.ts";
|
|
25
|
+
import { collectHealthRefreshAttempt } from "./health-refresh.ts";
|
|
23
26
|
import type {
|
|
24
27
|
HealthData,
|
|
25
28
|
HealthDiagnosticScope,
|
|
@@ -63,14 +66,15 @@ export async function runHealthWorkflow(
|
|
|
63
66
|
phase: "collection",
|
|
64
67
|
message: "Collecting workspace health evidence",
|
|
65
68
|
});
|
|
66
|
-
|
|
67
69
|
const lspState = deps.capability.getLspRuntimeState(deps.cwd);
|
|
68
70
|
const capabilityStates = deps.capability.getCapabilityStates(deps.cwd);
|
|
69
71
|
const runtime = lspState.kind === "ready" ? lspState.runtime : null;
|
|
72
|
+
const evidenceRuntime =
|
|
73
|
+
lspState.kind === "ready" || lspState.kind === "inactive" ? lspState.runtime : null;
|
|
70
74
|
const serverInventoryAvailable = lspState.kind === "ready" || lspState.kind === "disabled";
|
|
71
75
|
|
|
72
76
|
const diagnosticsScope = diagnosticScope(scopeFilter);
|
|
73
|
-
const
|
|
77
|
+
const refreshCollection = await collectRefreshState({
|
|
74
78
|
refreshRequested: request.refresh === true,
|
|
75
79
|
diagnosticsRequested: included.includes("diagnostics"),
|
|
76
80
|
runtime,
|
|
@@ -85,18 +89,31 @@ export async function runHealthWorkflow(
|
|
|
85
89
|
scopeFilter,
|
|
86
90
|
lspState,
|
|
87
91
|
capabilityState: capabilityStates.semantic,
|
|
92
|
+
control,
|
|
88
93
|
});
|
|
89
94
|
const semanticReady = semanticState?.kind === "ready";
|
|
90
95
|
throwIfAborted(control);
|
|
91
96
|
|
|
92
97
|
const diagnostics = await collectDiagnostics({
|
|
93
98
|
service: semanticReady ? runtime : null,
|
|
99
|
+
evidenceService: evidenceRuntime,
|
|
94
100
|
included,
|
|
95
101
|
scope: diagnosticsScope,
|
|
96
102
|
cwd: deps.cwd,
|
|
97
103
|
unavailableReason: diagnosticUnavailableReason(semanticState),
|
|
98
104
|
detailed: level === "detailed",
|
|
105
|
+
requestControl: control,
|
|
106
|
+
refreshEvidence:
|
|
107
|
+
(refreshCollection.attempt.kind === "completed" ||
|
|
108
|
+
refreshCollection.attempt.kind === "failed") &&
|
|
109
|
+
refreshCollection.attempt.operationScope === "workspace-runtime"
|
|
110
|
+
? refreshCollection.attempt.diagnosticEvidence
|
|
111
|
+
: undefined,
|
|
112
|
+
refreshReport: refreshCollection.diagnosticReport,
|
|
99
113
|
});
|
|
114
|
+
// A cancellation that landed during diagnostic resolution must not produce
|
|
115
|
+
// a completed health result the caller no longer awaits.
|
|
116
|
+
throwIfAborted(control);
|
|
100
117
|
const servers = collectServers(runtime, included);
|
|
101
118
|
const capabilityWarnings = collectCapabilityWarnings(semanticRequested, deps);
|
|
102
119
|
|
|
@@ -108,14 +125,14 @@ export async function runHealthWorkflow(
|
|
|
108
125
|
structuralStatus: describeStructuralState(capabilityStates.structural),
|
|
109
126
|
diagnostics,
|
|
110
127
|
servers,
|
|
111
|
-
refresh,
|
|
128
|
+
refresh: refreshCollection.attempt,
|
|
112
129
|
level,
|
|
113
130
|
capabilityWarnings: capabilityWarnings?.hasWarnings ? capabilityWarnings : undefined,
|
|
114
131
|
};
|
|
115
132
|
|
|
133
|
+
throwIfAborted(control);
|
|
116
134
|
return { kind: "completed", data };
|
|
117
135
|
}
|
|
118
|
-
|
|
119
136
|
function healthNeedsSemantic(included: readonly HealthSection[]): boolean {
|
|
120
137
|
return included.includes("diagnostics") || included.includes("servers");
|
|
121
138
|
}
|
|
@@ -126,6 +143,7 @@ interface SemanticHealthStateOptions {
|
|
|
126
143
|
scopeFilter: string | null;
|
|
127
144
|
lspState: WorkspaceLspRuntimeState;
|
|
128
145
|
capabilityState: CapabilityState;
|
|
146
|
+
control?: WorkflowControl;
|
|
129
147
|
}
|
|
130
148
|
|
|
131
149
|
async function establishSemanticHealthState(
|
|
@@ -133,10 +151,14 @@ async function establishSemanticHealthState(
|
|
|
133
151
|
): Promise<SemanticHealthState | null> {
|
|
134
152
|
if (!options.requested) return null;
|
|
135
153
|
if (options.runtime && isScopedFile(options.scopeFilter)) {
|
|
136
|
-
const readiness = await options.runtime.waitUntilReadyForFile(
|
|
154
|
+
const readiness = await options.runtime.waitUntilReadyForFile(
|
|
155
|
+
options.scopeFilter,
|
|
156
|
+
undefined,
|
|
157
|
+
options.control,
|
|
158
|
+
);
|
|
137
159
|
if (readiness.kind === "ready") return { kind: "ready" };
|
|
138
160
|
if (readiness.kind === "timeout") {
|
|
139
|
-
return { kind: "pending", reason:
|
|
161
|
+
return { kind: "pending", reason: SEMANTIC_READINESS_TIMEOUT_REASON };
|
|
140
162
|
}
|
|
141
163
|
return { kind: "unavailable", reason: readiness.reason };
|
|
142
164
|
}
|
|
@@ -195,6 +217,11 @@ function collectCapabilityWarnings(
|
|
|
195
217
|
return report.hasWarnings ? report : undefined;
|
|
196
218
|
}
|
|
197
219
|
|
|
220
|
+
interface HealthRefreshStateCollection {
|
|
221
|
+
readonly attempt: HealthRefreshState;
|
|
222
|
+
readonly diagnosticReport?: WorkspaceDiagnosticReport;
|
|
223
|
+
}
|
|
224
|
+
|
|
198
225
|
interface RefreshStateOptions {
|
|
199
226
|
readonly refreshRequested: boolean;
|
|
200
227
|
readonly diagnosticsRequested: boolean;
|
|
@@ -206,91 +233,79 @@ interface RefreshStateOptions {
|
|
|
206
233
|
}
|
|
207
234
|
|
|
208
235
|
/** Run the requested workspace-runtime refresh and retain only facts the runtime establishes. */
|
|
209
|
-
async function collectRefreshState(
|
|
236
|
+
async function collectRefreshState(
|
|
237
|
+
options: RefreshStateOptions,
|
|
238
|
+
): Promise<HealthRefreshStateCollection> {
|
|
210
239
|
const { deps, diagnosticsRequested, diagnosticsScope, lspState, runtime } = options;
|
|
211
240
|
if (!diagnosticsRequested) {
|
|
212
241
|
return {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
242
|
+
attempt: {
|
|
243
|
+
kind: "not-requested",
|
|
244
|
+
reason: "Diagnostics were not requested.",
|
|
245
|
+
lastAttempt: deps.lastRefreshAttempt,
|
|
246
|
+
},
|
|
216
247
|
};
|
|
217
248
|
}
|
|
218
249
|
if (!options.refreshRequested) {
|
|
219
250
|
return {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
251
|
+
attempt: {
|
|
252
|
+
kind: "not-requested",
|
|
253
|
+
reason: "Refresh was not requested.",
|
|
254
|
+
lastAttempt: deps.lastRefreshAttempt,
|
|
255
|
+
},
|
|
223
256
|
};
|
|
224
257
|
}
|
|
225
258
|
if (!runtime) {
|
|
226
259
|
return {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
260
|
+
attempt: {
|
|
261
|
+
kind: "not-attempted",
|
|
262
|
+
reason: refreshUnavailableReason(lspState),
|
|
263
|
+
lastAttempt: deps.lastRefreshAttempt,
|
|
264
|
+
},
|
|
230
265
|
};
|
|
231
266
|
}
|
|
232
267
|
|
|
233
268
|
const attemptedAt = Date.now();
|
|
269
|
+
const operationScope = diagnosticsScope.kind === "file" ? "file-runtime" : "workspace-runtime";
|
|
234
270
|
try {
|
|
235
271
|
reportProgress(options.control, {
|
|
236
272
|
intent: "health",
|
|
237
273
|
phase: "maintenance",
|
|
238
274
|
message: "Refreshing LSP state and sentinel snapshot",
|
|
239
275
|
});
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
// Recovery still gets a chance to restart a failed routed client.
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const recovery = await recoverDiagnosticRuntime({
|
|
253
|
-
service: runtime,
|
|
254
|
-
progress: () =>
|
|
276
|
+
const attempt = await collectHealthRefreshAttempt({
|
|
277
|
+
runtime,
|
|
278
|
+
diagnosticsScope,
|
|
279
|
+
attemptedAt,
|
|
280
|
+
cwd: options.deps.cwd,
|
|
281
|
+
sentinelSnapshot: options.deps.sentinelSnapshot,
|
|
282
|
+
control: options.control,
|
|
283
|
+
reportRecoveryProgress: () =>
|
|
255
284
|
reportProgress(options.control, {
|
|
256
285
|
intent: "health",
|
|
257
286
|
phase: "recovery",
|
|
258
287
|
message: "Refreshing diagnostics and recovery state",
|
|
259
288
|
}),
|
|
260
289
|
});
|
|
261
|
-
|
|
262
|
-
kind: "completed",
|
|
263
|
-
attemptedAt,
|
|
264
|
-
requestedDiagnosticScope: diagnosticsScope,
|
|
265
|
-
operationScope: "workspace-runtime",
|
|
266
|
-
attemptedActiveClients: recovery.attemptedClients,
|
|
267
|
-
restartedClients: recovery.restartedClients,
|
|
268
|
-
staleAssessment: {
|
|
269
|
-
suspected: recovery.staleAssessment.suspected,
|
|
270
|
-
matchedFileCount: recovery.staleAssessment.matchedFiles.length,
|
|
271
|
-
warning: recovery.staleAssessment.warning,
|
|
272
|
-
},
|
|
273
|
-
};
|
|
274
|
-
deps.trackRefreshAttempt(attempt);
|
|
290
|
+
deps.trackRefreshAttempt(attempt.attempt);
|
|
275
291
|
return attempt;
|
|
276
292
|
} catch (error) {
|
|
293
|
+
// Cancellation must propagate; a cancelled caller no longer awaits a
|
|
294
|
+
// recorded failed attempt or the refresh data it would carry.
|
|
295
|
+
if (isCodeRequestInterruption(error, options.control)) throw error;
|
|
277
296
|
const attempt: HealthRefreshAttempt = {
|
|
278
297
|
kind: "failed",
|
|
279
298
|
attemptedAt,
|
|
299
|
+
elapsedMs: Date.now() - attemptedAt,
|
|
280
300
|
requestedDiagnosticScope: diagnosticsScope,
|
|
281
|
-
operationScope
|
|
301
|
+
operationScope,
|
|
282
302
|
reason: errorMessage(error),
|
|
283
303
|
};
|
|
284
304
|
deps.trackRefreshAttempt(attempt);
|
|
285
|
-
return attempt;
|
|
305
|
+
return { attempt };
|
|
286
306
|
}
|
|
287
307
|
}
|
|
288
308
|
|
|
289
|
-
function updateSentinelSnapshot(target: Map<string, number>, next: Map<string, number>): void {
|
|
290
|
-
target.clear();
|
|
291
|
-
for (const [key, value] of next) target.set(key, value);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
309
|
function refreshUnavailableReason(lspState: WorkspaceLspRuntimeState): string {
|
|
295
310
|
switch (lspState.kind) {
|
|
296
311
|
case "unavailable":
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Runtime parsers for inspection, Orientation, graph, and find workflows. */
|
|
2
2
|
|
|
3
|
-
import { type CodeFindAstKind, isCodeFindAstKind } from "../../tool/
|
|
4
|
-
import { CODE_FIND_MODES } from "../../tool/
|
|
3
|
+
import { type CodeFindAstKind, isCodeFindAstKind } from "../../tool/code_find/ast-kinds.ts";
|
|
4
|
+
import { CODE_FIND_MODES } from "../../tool/code_find/modes.ts";
|
|
5
5
|
import type { FindMode, FindWorkflowInput } from "../find-types.ts";
|
|
6
6
|
import type { GraphWorkflowInput, RequestedGraphRelation } from "../graph-types.ts";
|
|
7
7
|
import type { InspectWorkflowInput } from "../inspect-types.ts";
|