@mrclrchtr/supi-code-intelligence 6.3.0 → 7.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.
Files changed (136) hide show
  1. package/README.md +164 -82
  2. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  3. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +8 -1
  4. package/node_modules/@mrclrchtr/supi-core/README.md +8 -0
  5. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  6. package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +10 -3
  7. package/node_modules/@mrclrchtr/supi-core/src/index.ts +2 -0
  8. package/node_modules/@mrclrchtr/supi-core/src/llm.ts +141 -16
  9. package/node_modules/@mrclrchtr/supi-lsp/README.md +35 -13
  10. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  11. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +8 -1
  12. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +8 -0
  13. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  14. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +10 -3
  15. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +2 -0
  16. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/llm.ts +141 -16
  17. package/node_modules/@mrclrchtr/supi-lsp/node_modules/ignore/index.js +3 -1
  18. package/node_modules/@mrclrchtr/supi-lsp/node_modules/ignore/legacy.js +3 -1
  19. package/node_modules/@mrclrchtr/supi-lsp/node_modules/ignore/package.json +1 -1
  20. package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
  21. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +16 -0
  22. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +43 -35
  23. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +83 -17
  24. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +108 -92
  25. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +44 -82
  26. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +3 -4
  27. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +9 -68
  28. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +45 -58
  29. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +230 -331
  30. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +201 -1
  31. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +129 -70
  32. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-typescript.ts +395 -0
  33. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +8 -12
  34. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +685 -183
  35. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +2 -2
  36. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +60 -60
  37. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-request-enrollment.ts +75 -0
  38. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-semantic-input-barrier.ts +443 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-semantic-input-errors.ts +30 -0
  40. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-semantic-input-file.ts +15 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +290 -37
  42. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +72 -16
  43. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +1 -0
  44. package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +30 -4
  45. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +1 -1
  46. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +4 -32
  47. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sources.ts +108 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +10 -4
  49. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-process-crash-report.ts +50 -1
  50. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +11 -7
  51. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +770 -56
  52. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +3 -1
  53. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +37 -4
  54. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +48 -12
  55. package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +50 -4
  56. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  57. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +8 -1
  58. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +8 -0
  59. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  60. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +10 -3
  61. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +2 -0
  62. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/llm.ts +141 -16
  63. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
  64. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +2 -0
  65. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callee-display-name.ts +165 -0
  66. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +67 -9
  67. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +2 -0
  68. package/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +19 -18
  69. package/node_modules/yaml/browser/dist/nodes/Alias.js +25 -23
  70. package/node_modules/yaml/dist/compose/resolve-flow-scalar.js +19 -18
  71. package/node_modules/yaml/dist/nodes/Alias.js +25 -23
  72. package/node_modules/yaml/package.json +1 -1
  73. package/package.json +5 -5
  74. package/src/analysis/health/diagnostics.ts +1 -2
  75. package/src/analysis/health/file-scope.ts +4 -1
  76. package/src/analysis/health/server-status.ts +1 -1
  77. package/src/analysis/relations/callees.ts +17 -8
  78. package/src/analysis/relations/implementations.ts +1 -2
  79. package/src/analysis/relations/references.ts +8 -4
  80. package/src/analysis/relations/types.ts +6 -30
  81. package/src/analysis/target/anchored.ts +9 -1
  82. package/src/analysis/target/symbol.ts +29 -11
  83. package/src/analysis/target/types.ts +14 -6
  84. package/src/api.ts +2 -0
  85. package/src/session/graph/collect.ts +18 -3
  86. package/src/session/health-refresh.ts +27 -11
  87. package/src/session/health-types.ts +21 -4
  88. package/src/session/health-workflow.ts +28 -22
  89. package/src/session/orientation-types.ts +5 -6
  90. package/src/session/orientation-workflow.ts +10 -2
  91. package/src/session/session.ts +12 -5
  92. package/src/session/target-workflow.ts +9 -6
  93. package/src/substrate/lsp/maintenance.ts +53 -47
  94. package/src/substrate/lsp/source-tracking.ts +252 -0
  95. package/src/tool/code_find/guidance.ts +3 -3
  96. package/src/tool/code_find/spec.ts +5 -4
  97. package/src/tool/code_find/tui.ts +7 -1
  98. package/src/tool/code_graph/details.ts +32 -0
  99. package/src/tool/code_graph/display.ts +54 -0
  100. package/src/tool/code_graph/format.ts +60 -0
  101. package/src/tool/code_graph/guidance.ts +2 -2
  102. package/src/tool/code_graph/markdown.ts +76 -198
  103. package/src/tool/code_graph/read-next.ts +65 -0
  104. package/src/tool/code_graph/result.ts +118 -83
  105. package/src/tool/code_graph/tui.ts +216 -54
  106. package/src/tool/code_health/guidance.ts +3 -5
  107. package/src/tool/code_health/markdown.ts +90 -57
  108. package/src/tool/code_health/refresh-outcome.ts +51 -0
  109. package/src/tool/code_health/refresh-status.ts +130 -43
  110. package/src/tool/code_health/scope.ts +78 -0
  111. package/src/tool/code_health/spec.ts +1 -1
  112. package/src/tool/code_health/tui.ts +29 -38
  113. package/src/tool/code_inspect/guidance.ts +5 -3
  114. package/src/tool/code_inspect/tui.ts +7 -1
  115. package/src/tool/code_orientation/guidance.ts +3 -4
  116. package/src/tool/code_orientation/result.ts +31 -8
  117. package/src/tool/code_orientation/tui.ts +26 -5
  118. package/src/tool/code_refactor_apply/guidance.ts +1 -1
  119. package/src/tool/code_refactor_apply/tui.ts +7 -3
  120. package/src/tool/code_refactor_plan/guidance.ts +3 -5
  121. package/src/tool/code_refactor_plan/tui.ts +7 -1
  122. package/src/tool/code_resolve/guidance.ts +3 -5
  123. package/src/tool/code_resolve/result.ts +13 -10
  124. package/src/tool/code_resolve/tui.ts +18 -1
  125. package/src/tool/guidance.ts +11 -9
  126. package/src/tool/infra/truncate.ts +39 -13
  127. package/src/tool/result/candidate-row.ts +27 -0
  128. package/src/tool/result/errors.ts +21 -6
  129. package/src/tool/result/types.ts +7 -3
  130. package/src/tool/schemas.ts +5 -0
  131. package/src/types/execution.ts +2 -0
  132. package/src/types/index.ts +2 -0
  133. package/src/ui/tui/candidate-legacy-body.ts +69 -0
  134. package/src/ui/tui/candidate-selection.ts +366 -0
  135. package/src/ui/tui/common.ts +26 -31
  136. package/src/ui/tui/execution-error.ts +92 -0
@@ -22,11 +22,11 @@ npm install @mrclrchtr/supi-lsp
22
22
 
23
23
  The runtime starts an installed server when the project contains a matching file type and, where configured, a root marker. Some built-in servers use extension-based discovery without a root marker. Built-in command names must be on `PATH`; a configured absolute command path is also supported. This table describes diagnostic support, not the full semantic feature set. A push server can still provide hover, definitions, references, symbols, and refactors.
24
24
 
25
- The table records an initialize-handshake audit performed on 2026-08-21 against the locally installed server versions. The handshake is authoritative and can report a different mode after an upgrade; treat rows marked `unverified` as unknown until a probe confirms them. Pull-capability facts come from the official LSP specification (pull diagnostics are a 3.17 feature; 3.18 is the current specification at microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification).
25
+ The table is a historical initialize-handshake audit performed on 2026-08-21 against the locally installed server versions. It is not a current retest. The TypeScript row also records a separate issue 407 adapter verification on 2026-09-13. That verification did not retest the other server binaries; their audit versions and statuses remain historical. The handshake is authoritative and can report a different mode after an upgrade; treat rows marked `unverified` as unknown until a probe confirms them. Pull-capability facts come from the official LSP specification (pull diagnostics are a 3.17 feature; 3.18 is the current specification at microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification).
26
26
 
27
27
  | Language | Server binary | Pull diagnostics (probe) | Built-in SuPi mode | Notes |
28
28
  |---|---|---|---|---|
29
- | TypeScript / JavaScript | `typescript-language-server` 5.3.0 | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
29
+ | TypeScript / JavaScript | `typescript-language-server` 5.3.0 (audit, 2026-08-21); 6.0.0 (adapter verification, 2026-09-13) | No standard pull in the recorded checks | TypeScript request adapter when eligible; push observation otherwise | The 5.3.0 capability row is historical. The 6.0.0 adapter is described below. |
30
30
  | Python | `pyright-langserver` 1.1.411 | Dynamic-only pull (confirmed) | Pull | No static `diagnosticProvider` in the initialize result; registers `textDocument/diagnostic` dynamically after `initialized`. The #320 handshake inspected only the initialize result and missed the registration. |
31
31
  | Rust | `rust-analyzer` 0.0.0 (2026-08-10) | No (confirmed) | Push | No `diagnosticProvider` in the initialize result. |
32
32
  | Go | `gopls` v0.23.0 | Conditional (confirmed) | Push | Default is push; `initializationOptions.pullDiagnostics: true` makes gopls advertise `diagnosticProvider`. Keep push while golang/go#70199 stays open; initial pull support tracked in golang/go#53275. gopls v0.23.0 pull reports omit the `kind` discriminator (`""`) and `resultId`; SuPi tolerates the empty-kind full report. |
@@ -46,23 +46,43 @@ SuPi advertises static and dynamic pull support. It advertises server-requested
46
46
 
47
47
  A server gets pull diagnostics when it declares a valid `diagnosticProvider` during initialization. A server also gets pull diagnostics after it registers `textDocument/diagnostic`. The pull support stays active until the server removes the registration. SuPi validates registration parameters. Invalid parameters do not enable pull support. SuPi ignores other registration methods.
48
48
 
49
- When a server sends `workspace/diagnostic/refresh`, SuPi returns `null` immediately. It then refreshes the owning client's tracked documents in the background. The refresh covers open, cached, and failed tracked documents. SuPi does not add workspace-wide `workspace/diagnostic` pulls.
49
+ When a server sends `workspace/diagnostic/refresh`, SuPi returns `null` immediately. It then invalidates diagnostic evidence only and refreshes the owning client's tracked documents in the background. Unchanged open documents keep their input synchronization; SuPi sends no no-op `didChange`, `didClose`, or `didOpen`. It uses native pull or the tested TypeScript request adapter when available. Push-only routes keep partial or unconfirmed evidence. Actual disk changes use the normal document synchronization path. Overlapping refresh requests share one active pass and one newer pending demand; an active diagnostic transport stays owned until it settles. The refresh covers open, cached, and failed tracked documents. SuPi does not add workspace-wide `workspace/diagnostic` pulls.
50
50
 
51
51
  Protocol support is separate from the configured mode. A server may support pull diagnostics and still use SuPi's push mode because the built-in configuration does not enable pull mode.
52
52
 
53
53
  The LSP 3.18 specification adds `Diagnostic.message` markup content, guarded by the client capability `textDocument.diagnostic.markupMessageSupport`; SuPi's validator already accepts plaintext and markdown messages but does not advertise the capability. Other 3.18 features (snippet text edits, inline completion, folding-range refresh, multi-range formatting) are outside the diagnostic surface and are not implemented.
54
54
 
55
- Pull diagnostics use `textDocument/diagnostic`, so the client can tie a report to the current request. Push diagnostics are asynchronous and can omit a document version. After a workspace change, SuPi may report push-only diagnostics as partial or unavailable when it cannot prove that the result matches the current document. It does not treat missing fresh evidence as a clean file.
55
+ ### Diagnostic evidence policy
56
56
 
57
- Unversioned pushes are accepted for an open document when they arrive after the document's sync moment (the client-side instant the `didChange` or `didOpen` that produced them was sent) and are re-stamped with the current synchronization; unversioned pushes for closed or untracked URIs, and pushes that arrive before a sync moment, stay fail-closed. On push-only routes, the first valid publication for a synchronization is tentative. A later valid publication for the same synchronization confirms it, and every publication restarts the quiet period. If no publication arrives, the existing bounded reopen path may ask the server to publish on `didOpen`; a tentative timeout does not reopen that document. In a mixed batch, silent documents can still use the reopen path. Non-empty tentative diagnostics are visible as partial evidence, but they do not enter the confirmed path. An empty tentative publication cannot establish a clean file and stays unavailable until a diagnostic republish arrives. Repeated unchanged queries share the tentative publication's wait age instead of starting a new full wait. A late republish promotes the cache without a new refresh.
57
+ See [`ADR 0022`](../../docs/adr/0022-request-confirmed-lsp-agnostic-diagnostics.md) for the decision record. SuPi uses one shared diagnostic engine with optional internal request adapters. It selects one source for each file:
58
58
 
59
- Server readiness follows LSP work-done progress: a created progress token is pending and never blocks readiness; an observed `begin` marks active work and makes the client not ready until its `end` or the bounded per-token timeout.
59
+ | Source | Used when | Evidence result |
60
+ |---|---|---|
61
+ | Native LSP pull | A valid static or dynamic `diagnosticProvider` applies to the file. | A validated current report can confirm that file. |
62
+ | TypeScript request | The supported TypeScript route advertises `typescript.tsserverRequest` and the file type matches its configuration. | A complete validated phase collection can confirm that file. |
63
+ | Ambient push | No request source applies, or a request collection fails and a push is available. | Observation only; non-empty data may be partial, but it cannot confirm clean. |
64
+
65
+ Native pull uses `textDocument/diagnostic`. The client validates full and unchanged reports, carries result IDs, and applies a report only when the document synchronization and evidence revision are current. A valid native provider has priority over the TypeScript adapter when both apply. The adapter is internal and does not change the server's advertised capabilities.
66
+
67
+ The TypeScript adapter was verified with `typescript-language-server` 6.0.0 and TypeScript 6.0.3. It uses the running server's tsserver through `workspace/executeCommand` and `typescript.tsserverRequest`. It collects `syntacticDiagnosticsSync`, `semanticDiagnosticsSync`, and `suggestionDiagnosticsSync` in order, then validates and combines all three phases. It uses execution target `0` and does not start a second compiler. Conversion validates positions and categories and carries supported tags and related information. A missing, failed, malformed, cancelled, or superseded phase does not establish request evidence.
68
+
69
+ This adapter applies only when the command is `typescript-language-server`, the route advertises `typescript.tsserverRequest`, and the file suffix matches the route's `fileTypes`. The 6.0.0 verification does not retest other server binaries. Do not infer request support from a language name. Other routes need a valid native pull provider or remain on the ambient push path.
70
+
71
+ Push diagnostics are asynchronous and may omit a document version. An unversioned push for an open document is accepted only after that document's local sync moment; pushes for closed or untracked URIs, and pushes before that moment, stay fail-closed. This gate blocks some stale messages. It does not confirm diagnostic completion. Every accepted push remains observed or tentative. A document version, publication count, quiet interval, or later republish does not confirm it. Non-empty push diagnostics may be returned as partial evidence. An empty push stays unconfirmed or unavailable. Ambient pushes do not replace request-confirmed cache entries.
72
+
73
+ A request is file-scoped. A successful TypeScript collection confirms only the requested file and current document generation. It is not a check of every file in a TypeScript program, a workspace, or all language servers. Workspace refresh reports exact tracked-file coverage for `requested`, `confirmed`, `unconfirmed`, `failed`, and `removed` documents. A missing or removed file is reported in that refresh and is not kept in later tracked-file snapshots. A broad `code_health` maintenance pass can refresh active tracked files outside a requested directory; its refresh-attempt evidence is separate from the later diagnostic result scope and coverage. `code_health` keeps these coverage states separate from diagnostic entries.
60
74
 
61
- A workspace diagnostic refresh returns exact coverage counts for requested, confirmed, unconfirmed, failed, and removed tracked documents. `code_health` marks tracked-file diagnostics as complete when each requested document is confirmed or known to be removed. It shows non-empty tentative diagnostics as partial entries, reports the same coverage counts in summary and detailed views, and explains when a diagnostic republish is needed. A refresh attempt does not prove fresh evidence by itself. A removed file is reported by the refresh that finds it and is not retained in later tracked-file snapshots.
75
+ Refresh and file collection share synchronization, evidence-revision, deadline, cancellation, cache, and response-validation rules. Duplicate requests for one route, file, synchronization, and revision share one job. The scheduler runs one request at a time per client route and allows at most 32 pending jobs. Refresh collection is sequential and stops at its shared deadline; unfinished files remain explicit in the coverage counts. The default refresh budget is 3,000 ms and the default push quiet window is 200 ms. The quiet window only ends an observation wait; it cannot confirm diagnostics.
62
76
 
63
- An explicit diagnostic refresh also returns a bounded process-crash report. It gives exact recovered, skipped, failed, and exhausted route counts, up to 16 route entries, and an omitted-entry count. Each entry names the server and workspace-relative root. A skipped route recommends an exact-file refresh; a failed or exhausted route recommends a workspace reload. A failed entry may include only the caught error message, limited to 512 characters. Broad refreshes select only routes whose root overlaps the requested directory and use retained tracked-file paths from the crash snapshot. Exact-file readiness reports only the file's route. Recovery does not cold-start routes, consume an attempt for a skip, or add a second attempt.
77
+ Caller cancellation or deadline stops only that caller's wait. Explicit diagnostic requests use an owned transport lifetime: supersession drops queued jobs and stops future adapter phases but does not cancel an active protocol request. The route stays occupied until actual settlement or connection disposal. The owner timeout attempts protocol cancellation but does not prove that the backend stopped. The owner bound is at least 30 seconds (or a larger collection budget). A result from an obsolete document generation is discarded. Ordinary semantic requests still pass caller cancellation to the protocol transport.
64
78
 
65
- An explicit recovery pass restarts a push-only client only on a protocol-stall signal (a readiness stall, or repeated JSON-RPC request failures) never on unconfirmed evidence alone, because the reopen-resync fallback recovers unconfirmed documents without discarding warm server state. It never restarts a pull-capable client because push evidence is absent, and it never restarts a client during passive health display. Each client route restarts at most once per workspace invalidation generation. The replacement process has a fixed startup bound of 5 seconds; exceeding the bound fails closed as start-failed without retry. Recovery telemetry records the outcome, elapsed time, attempted clients, restart count, the bounded server names involved, and the stall signal that triggered a restart, without changing the evidence semantics of the result.
79
+ If another request first opens a document during an active semantic or diagnostic request, the client can synchronize and repeat the request once. The retry retains the caller's original signal and deadline. Content, workspace, close, and lifecycle changes still reject stale results. A diagnostic retry collects new request evidence; it does not promote an old cache. This retry is not route recovery. A second enrollment during the retry still rejects the result. Semantic failure reasons state whether the retry failed or was exhausted. The `semantic-request.enrollment-retry` debug event records retry start and outcome with the public call's opaque operation ID, when supplied. A completed RPC alone does not establish accepted semantic evidence.
80
+
81
+ Diagnostic collection does not close and reopen a document to obtain confirmation. It does not send a no-op `didChange` for that purpose. Refresh retains unchanged documents and their current server state, and resynchronizes changed or invalidated documents. A client restart may reopen tracked documents to restore client state; that is recovery, not diagnostic confirmation.
82
+
83
+ Server readiness follows LSP work-done progress: a created progress token is pending and never blocks readiness; an observed `begin` marks active work and makes the client not ready until its `end` or the bounded per-token timeout.
84
+
85
+ An explicit diagnostic refresh retries failed startup and exhausted process-crash routes in scope. It returns separate bounded startup-retry and process-crash reports. Healthy routes are reused, and process readiness is not diagnostic evidence. Recovery keeps the ADR 0020 rule: restart a push-only route only for a protocol-stall signal, not for unconfirmed evidence. A route with native pull or the TypeScript request adapter is not restarted because an ambient push is absent. Passive health display does not restart routes.
66
86
 
67
87
  ### Optional diagnostic configuration
68
88
 
@@ -102,6 +122,8 @@ Set `lsp.exclude` in project or global SuPi configuration:
102
122
 
103
123
  An exact semantic request can still route an excluded file when a compatible server is available. This does not add the file to automatic work. Configured diagnostic suppression still applies to diagnostic output.
104
124
 
125
+ Tsconfig and jsconfig filtering applies only to TypeScript and JavaScript-family files (`.ts`, `.tsx`, `.mts`, `.cts`, `.js`, `.jsx`, `.mjs`, and `.cjs`). Other-language diagnostics are not filtered by a nearby TypeScript or JavaScript project config. Automatic path exclusions and configured diagnostic suppression still apply. A single-file health result omits the `Tsconfig` coverage line for other languages.
126
+
105
127
  ### Custom server configuration
106
128
 
107
129
  A custom server needs a command and at least one file type:
@@ -166,11 +188,11 @@ Retained and persisted LSP debug events may identify local workspaces, servers,
166
188
  - `method` — exact LSP method, e.g. `textDocument/hover`
167
189
  - `root` — server root, absolute where present
168
190
 
169
- `runtime.transition` events carry `cwd` and a bounded `servers` array (name, status, ready, and an optional process-crash status reason; at most 16 entries) alongside the aggregate counts. `readiness.*` events carry `cwd`, `server`, and `root`; their messages and data never embed raw progress-token values. `request.timing` events carry the exact `method`, `server`, and `cwd`, plus the JSON-RPC error code: the server-reported code for failed requests, and the defined constant `-32095` (`LSP_REQUEST_TIMEOUT_ERROR_CODE`) for local timeouts; cancellations carry no code. `diagnostics.timing` events carry `cwd`, `server`, and a workspace-relative `file` for `sync-file` operations; `refresh-open` stays aggregate. `runtime.recovery` events carry `cwd`, bounded server and route-root identity, an outcome, and elapsed time for process-crash recovery. Diagnostic recovery events keep their existing bounded attempted/restarted server names. `capability.transition` events fire only on semantic ready↔pending transitions and carry `cwd` and the ready state — never for initialize, registration, or unregistration traffic. Code-intelligence events (`code-operation.*`, `workflow.timing`, `ast-scan.timing`) carry `cwd` only.
191
+ `runtime.transition` events carry `cwd` and a bounded `servers` array (name, status, ready, and an optional process-crash status reason; at most 16 entries) alongside the aggregate counts. `readiness.*` events carry `cwd`, `server`, and `root`; their messages and data never embed raw progress-token values. `request.timing` events carry the exact `method`, `server`, and `cwd`, plus the JSON-RPC error code: the server-reported code for failed requests, and the defined constant `-32095` (`LSP_REQUEST_TIMEOUT_ERROR_CODE`) for local timeouts; cancellations carry no code. `diagnostics.timing` events carry `cwd`, `server`, and a workspace-relative `file` for `sync-file` operations; `refresh-open` stays aggregate. Their `collection` value identifies the source, such as `pull`, `typescript`, `mixed`, or `push`. `diagnostics.publication` keeps bounded publication counts for observation; a count or late publication does not promote confirmation. `runtime.recovery` events carry `cwd`, bounded server and route-root identity, an outcome, and elapsed time for process-crash recovery. Diagnostic recovery events keep their existing bounded attempted/restarted server names. `capability.transition` events fire only on semantic ready↔pending transitions and carry `cwd` and the ready state — never for initialize, registration, or unregistration traffic. Code-intelligence events (`code-operation.*`, `workflow.timing`, `ast-scan.timing`) carry `cwd` only.
170
192
 
171
193
  `ProjectServerInfo.statusReason` is present only for process-crash recovery states: `process-crashed`, `process-crash-recovery-pending`, or `process-crash-recovery-exhausted`. An LSP route is one configured server and workspace root. A route stays in `error` status for all three states.
172
194
 
173
- Semantic evidence operations recover each required, previously running crashed route and wait for the shared replacement. Scoped workspace-symbol operations select routes by operation support and root intersection; unscoped operations select every known supporting route. Required routes start in parallel. File diagnostics can also recover their route. An explicit broad diagnostic refresh can recover crashed routes that retain tracked files in its scope. Server inventory, workspace readiness, and passive diagnostic snapshots do not start recovery. Recovery never cold-starts a route that did not initialize successfully.
195
+ Semantic evidence operations recover each required, previously running crashed route and wait for the shared replacement. Scoped workspace-symbol operations select routes by operation support and root intersection; unscoped operations select every known supporting route. Required routes start in parallel. File diagnostics can also recover their route. An explicit health refresh can retry failed startup and crashed routes in its scope, including routes without retained files, and can discover configured servers that are now available in Pi's environment. Server inventory, workspace readiness, and passive diagnostic snapshots do not start recovery. A healthy route is reused, and an explicit refresh can restore its automatic process-crash attempt budget after observing readiness. Ordinary semantic and diagnostic requests keep the automatic recovery limit. Recovery never claims diagnostic evidence from process readiness alone.
174
196
 
175
197
  Identity strings — `cwd`, `server`, `file`, `method`, and `root` — are bounded to 512 UTF-16 code units (marker included; truncation appends `…`) and server lists to 16 entries. No raw protocol dumps, request/response params, diagnostic text, progress tokens, or unbounded file lists are recorded; `openFiles` stays a count. Identity fields are intentionally **not** secret-redacted — the debug registry still redacts secret keys and values, but server names, workspace-relative files, and method names pass through unredacted so local protocol failures stay diagnosable. The supi-debug package documents this disclosure for retained and persisted events.
176
198
 
@@ -194,7 +216,7 @@ if (state.kind === "ready") {
194
216
 
195
217
  Runtime methods use raw 0-based LSP positions. `toLspPosition()` converts user-facing 1-based coordinates. Read-only semantic and diagnostic methods return `CodeQueryResult<T>` so completed empty protocol responses remain distinct from partial or unavailable requests. A ready runtime owner may contain only lazy routes: workspace semantic readiness requires at least one active ready client, while file readiness requires the routed client for that file to start successfully. Empty client sets and failed routes are unavailable, not vacuously ready.
196
218
 
197
- Semantic and explicit diagnostic operations accept optional shared `CodeRequestControl` metadata. The semantic adapter preserves the exact value through `WorkspaceLspRuntime`. The signal maps to LSP protocol cancellation (`$/cancelRequest`) and the absolute deadline bounds every request and readiness wait. The opaque Debug Operation ID reaches sanitized request and diagnostic timing events. Ambient readiness, lifecycle, capability, and push-diagnostic events have no Debug Operation ID.
219
+ Semantic and explicit diagnostic operations accept optional shared `CodeRequestControl` metadata. The semantic adapter preserves the exact value through `WorkspaceLspRuntime`. Semantic requests pass caller cancellation to the LSP transport. Explicit diagnostic requests use the owned transport lifetime described above: caller cancellation or a caller deadline ends only that caller's wait, and supersession does not cancel an active protocol request. The route stays occupied until actual settlement or connection disposal; an owner timeout attempts protocol cancellation but does not prove that the backend stopped. The opaque Debug Operation ID reaches sanitized request and diagnostic timing events. Ambient readiness, lifecycle, capability, and push-diagnostic events have no Debug Operation ID.
198
220
 
199
221
  ## Startup performance
200
222
 
@@ -237,7 +259,7 @@ See [`docs/adr/0016-workspace-lsp-runtime-interface.md`](../../docs/adr/0016-wor
237
259
 
238
260
  ## Source
239
261
 
240
- - `src/client/` — protocol client, transport, refresh, and requests
262
+ - `src/client/` — protocol client, transport, diagnostic request adapters, refresh, and requests
241
263
  - `src/config/` — server configuration and protocol types
242
264
  - `src/diagnostics/` — stale diagnostics and workspace sentinels
243
265
  - `src/manager/` — package-internal server pool and routing, diagnostic, and recovery mechanics
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-code-runtime",
3
- "version": "6.3.0",
3
+ "version": "7.0.0",
4
4
  "description": "Shared workspace context and capability contracts for code intelligence",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -234,7 +234,14 @@ export type CalleeDepth = "direct" | "deep";
234
234
  */
235
235
  export interface CalleesData {
236
236
  enclosingScope: { name: string; startLine: number; endLine: number };
237
- callees: Array<{ name: string; startLine: number }>;
237
+ /** Distinct call sites with 1-based UTF-16 start coordinates. */
238
+ callees: Array<{
239
+ name: string;
240
+ /** Optional syntax-shortened label for presentation; does not replace `name`. */
241
+ displayName?: string;
242
+ startLine: number;
243
+ startCharacter: number;
244
+ }>;
238
245
  depth: CalleeDepth;
239
246
  }
240
247
 
@@ -21,6 +21,7 @@ pnpm add @mrclrchtr/supi-core
21
21
  ## Package surfaces
22
22
 
23
23
  - `@mrclrchtr/supi-core/api` — reusable helpers for other packages and extensions
24
+ - `@mrclrchtr/supi-core/llm` — PI-owned direct model requests and JSON helpers
24
25
  - `@mrclrchtr/supi-core/report` — shared text/report rendering helpers for TUI and plain-text summaries
25
26
 
26
27
  ## What you get from the API
@@ -48,6 +49,13 @@ Config file locations:
48
49
 
49
50
  - `wrapExtensionContext()` — wrap injected text in SuPi's `<extension-context>` tag
50
51
 
52
+ ### Model requests
53
+
54
+ - `completeModelRequest(ctx, model, context, options)` — complete through PI's model registry with stable feature affinity. PI owns auth and endpoint resolution.
55
+ - `callWithJsonResponse()` — retry a registry request, extract JSON, and validate it with TypeBox.
56
+
57
+ `completeModelRequest()` requires a stable `affinityScope`. It keeps cache retention defaults, does not include prompt content in the affinity ID, and adds OpenCode headers only when the provider or exact model endpoint matches OpenCode. Pass `maxTokens: model.maxTokens` when a caller needs the model's declared output cap without using PI private modules.
58
+
51
59
  ### Shared registries
52
60
 
53
61
  - context-provider registry for `/supi-context`
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "6.3.0",
3
+ "version": "7.0.0",
4
4
  "description": "Shared settings, configuration, reporting, and session infrastructure",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -2,17 +2,24 @@
2
2
  //
3
3
  // Extensions register pre-styled text chunks with a placement hint
4
4
  // ("stats" for the metrics line, "status" for the extension status line).
5
- // The custom footer in supi-extras (or PI's built-in footer) reads these
6
- // contributions and renders them alongside the built-in metrics.
5
+ // The custom footer in supi-extras reads these contributions and renders them
6
+ // alongside the built-in metrics. Extensions can use PI's status API as a
7
+ // fallback when the custom footer is not installed.
7
8
 
8
9
  import { createRegistry } from "./registry-utils.ts";
9
10
 
11
+ /** Event emitted when a dynamic footer contribution needs a new render. */
12
+ export const FOOTER_INVALIDATE_EVENT = "supi:footer:invalidate";
13
+
10
14
  /** Where the contribution should appear in the footer. */
11
15
  export type FooterPlacement = "stats" | "stats-end" | "status";
12
16
 
13
17
  /** A single footer contribution registered by an extension. */
14
18
  export interface FooterContribution {
15
- /** Unique key for this contribution. Re-registering with the same key replaces it. */
19
+ /**
20
+ * Unique key for this contribution. Re-registering with the same key replaces it.
21
+ * A same-key Pi status is treated as this contribution's built-in-footer fallback.
22
+ */
16
23
  key: string;
17
24
  /** Which footer line this belongs on. */
18
25
  placement: FooterPlacement;
@@ -15,6 +15,8 @@ export * from "./debug.ts";
15
15
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
16
16
  export * from "./footer-registry.ts";
17
17
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
18
+ export * from "./llm.ts";
19
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
18
20
  export * from "./model-selection.ts";
19
21
  // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
20
22
  export * from "./path.ts";
@@ -1,12 +1,131 @@
1
- import { complete } from "@earendil-works/pi-ai/compat";
1
+ import { createHash } from "node:crypto";
2
+ import type {
3
+ Api,
4
+ AssistantMessage,
5
+ Context,
6
+ Model,
7
+ ModelsApiStreamOptions,
8
+ ProviderHeaders,
9
+ } from "@earendil-works/pi-ai";
2
10
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
3
11
  import type { TSchema } from "typebox";
4
12
  import { Value } from "typebox/value";
5
13
 
6
14
  // Shared LLM utilities for SuPi extensions.
7
15
  //
8
- // Provides retry logic, structured LLM call helpers, and other
9
- // common patterns for extensions that interact with AI models.
16
+ // Provides PI-owned model requests, retry logic, structured LLM call helpers,
17
+ // and other common patterns for extensions that interact with AI models.
18
+
19
+ const MODEL_REQUEST_NAMESPACE = "supi-direct-model-request-v1";
20
+
21
+ /**
22
+ * Options for {@link completeModelRequest}.
23
+ *
24
+ * Authentication, provider environment, and session identity stay under PI
25
+ * control. The feature supplies a stable scope for its prompt stream.
26
+ */
27
+ export type CompleteModelRequestOptions<TApi extends Api = Api> = Omit<
28
+ ModelsApiStreamOptions<TApi>,
29
+ "apiKey" | "env" | "sessionId"
30
+ > & {
31
+ /** Stable feature scope. Do not include prompt, turn, or retry data. */
32
+ affinityScope: string;
33
+ /** PI owns these fields, including for APIs with open-ended option types. */
34
+ apiKey?: never;
35
+ env?: never;
36
+ sessionId?: never;
37
+ };
38
+
39
+ function createModelRequestAffinityId(
40
+ sessionId: string,
41
+ affinityScope: string,
42
+ model: Model<Api>,
43
+ ): string {
44
+ const material = JSON.stringify([
45
+ MODEL_REQUEST_NAMESPACE,
46
+ sessionId,
47
+ affinityScope,
48
+ model.provider,
49
+ model.id,
50
+ ]);
51
+ const digest = createHash("sha256").update(material, "utf8").digest("hex");
52
+ return `supi-${digest.slice(0, 56)}`;
53
+ }
54
+
55
+ function isOpenCodeModel(model: Model<Api>): boolean {
56
+ if (model.provider === "opencode" || model.provider === "opencode-go") return true;
57
+
58
+ try {
59
+ return new URL(model.baseUrl).hostname === "opencode.ai";
60
+ } catch {
61
+ return false;
62
+ }
63
+ }
64
+
65
+ function hasHeader(headers: ProviderHeaders, name: string): boolean {
66
+ const lowerName = name.toLowerCase();
67
+ return Object.keys(headers).some((headerName) => headerName.toLowerCase() === lowerName);
68
+ }
69
+
70
+ function addOpenCodeDefaultHeaders(
71
+ model: Model<Api>,
72
+ affinityId: string,
73
+ headers: ProviderHeaders,
74
+ ): ProviderHeaders {
75
+ if (!isOpenCodeModel(model)) return headers;
76
+
77
+ const result = { ...headers };
78
+ if (!hasHeader(result, "x-opencode-session")) {
79
+ result["x-opencode-session"] = affinityId;
80
+ }
81
+ if (!hasHeader(result, "x-opencode-client")) {
82
+ result["x-opencode-client"] = "pi";
83
+ }
84
+ return result;
85
+ }
86
+
87
+ /**
88
+ * Complete a direct request through PI's model registry.
89
+ *
90
+ * PI resolves authentication, provider headers, environment, and the
91
+ * effective endpoint. This helper adds one stable opaque session identity for
92
+ * the feature prompt stream and applies the OpenCode compatibility defaults.
93
+ * It does not retry, validate output, or present errors.
94
+ *
95
+ * When `maxTokens` is omitted, the underlying registry receives no explicit
96
+ * output cap. A caller that needs the selected model's declared cap can pass
97
+ * `maxTokens: model.maxTokens` without importing PI internals.
98
+ */
99
+ export async function completeModelRequest<TApi extends Api>(
100
+ ctx: ExtensionContext,
101
+ model: Model<TApi>,
102
+ context: Context,
103
+ options: CompleteModelRequestOptions<TApi>,
104
+ ): Promise<AssistantMessage> {
105
+ const { affinityScope, transformHeaders: callerTransformHeaders, ...requestOptions } = options;
106
+ const safeRequestOptions = { ...requestOptions };
107
+ delete safeRequestOptions.apiKey;
108
+ delete safeRequestOptions.env;
109
+ delete safeRequestOptions.sessionId;
110
+
111
+ const affinityId = createModelRequestAffinityId(
112
+ ctx.sessionManager.getSessionId(),
113
+ affinityScope,
114
+ model,
115
+ );
116
+ const transformHeaders = async (headers: ProviderHeaders): Promise<ProviderHeaders> => {
117
+ const transformed = callerTransformHeaders ? await callerTransformHeaders(headers) : headers;
118
+ return addOpenCodeDefaultHeaders(model, affinityId, transformed);
119
+ };
120
+
121
+ // Restore PI's conditional provider-option type after removing owned fields.
122
+ return ctx.modelRegistry.complete(model, context, {
123
+ ...safeRequestOptions,
124
+ signal: safeRequestOptions.signal ?? ctx.signal,
125
+ sessionId: affinityId,
126
+ transformHeaders,
127
+ } as unknown as ModelsApiStreamOptions<TApi>);
128
+ }
10
129
 
11
130
  /**
12
131
  * Options for {@link withRetry}.
@@ -122,6 +241,8 @@ export function extractJsonFromResponse<T extends TSchema>(
122
241
  export interface CallWithJsonResponseOptions {
123
242
  /** The prompt to send to the LLM. */
124
243
  prompt: string;
244
+ /** Stable feature scope for request affinity. Do not include prompt or retry data. */
245
+ affinityScope: string;
125
246
  /** Optional data context appended to the prompt. */
126
247
  dataContext?: string;
127
248
  /** Maximum tokens for the response. Default: 4096 */
@@ -135,8 +256,9 @@ export interface CallWithJsonResponseOptions {
135
256
  /**
136
257
  * Call the LLM with a prompt and validate the JSON response against a TypeBox schema.
137
258
  *
138
- * Handles model resolution, auth, retry via `withRetry`, text extraction,
139
- * JSON regex matching, and TypeBox validation.
259
+ * Handles model resolution, retry via `withRetry`, text extraction, JSON
260
+ * matching, and TypeBox validation. The request itself stays under PI
261
+ * registry authority through {@link completeModelRequest}.
140
262
  *
141
263
  * Returns `null` when:
142
264
  * - No model is available
@@ -145,7 +267,7 @@ export interface CallWithJsonResponseOptions {
145
267
  * - JSON doesn't match the schema
146
268
  * - The request is aborted
147
269
  *
148
- * @param ctx - The extension context for model resolution and auth.
270
+ * @param ctx - The extension context for model selection and PI registry access.
149
271
  * @param options - Call options including prompt, schema, and retry config.
150
272
  * @param schema - TypeBox schema to validate the JSON response against.
151
273
  * @returns The parsed and validated result, or `null`.
@@ -155,14 +277,18 @@ export async function callWithJsonResponse<T extends TSchema>(
155
277
  options: CallWithJsonResponseOptions,
156
278
  schema: T,
157
279
  ): Promise<{ parsed: import("typebox").Static<T> } | null> {
158
- const { prompt, dataContext, maxTokens = 4096, systemPrompt = "", retries = 2 } = options;
280
+ const {
281
+ prompt,
282
+ affinityScope,
283
+ dataContext,
284
+ maxTokens = 4096,
285
+ systemPrompt = "",
286
+ retries = 2,
287
+ } = options;
159
288
 
160
289
  const model = ctx.model ?? ctx.modelRegistry.getAvailable()[0] ?? null;
161
290
  if (!model) return null;
162
291
 
163
- const auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);
164
- if (!auth.ok || !auth.apiKey) return null;
165
-
166
292
  const fullPrompt = dataContext
167
293
  ? `${prompt}
168
294
 
@@ -171,8 +297,9 @@ ${dataContext}`
171
297
  : prompt;
172
298
 
173
299
  const response = await withRetry(
174
- async () => {
175
- return complete(
300
+ async () =>
301
+ completeModelRequest(
302
+ ctx,
176
303
  model,
177
304
  {
178
305
  systemPrompt,
@@ -185,13 +312,11 @@ ${dataContext}`
185
312
  ],
186
313
  },
187
314
  {
188
- apiKey: auth.apiKey,
189
- headers: auth.headers,
315
+ affinityScope,
190
316
  signal: ctx.signal,
191
317
  maxTokens,
192
318
  },
193
- );
194
- },
319
+ ),
195
320
  { retries, baseDelayMs: 1000, signal: ctx.signal },
196
321
  );
197
322
 
@@ -16,7 +16,9 @@ const REGEX_LITERAL_SPECIAL = /[.*+?()[\]{}^$|\\/]/
16
16
  // A line of only spaces is blank -- the trailing-space trimming empties it --
17
17
  // but a line holding a tab is a pattern for a tab-named path, since git
18
18
  // never trims a tab.
19
- const REGEX_TEST_BLANK_LINE = /^ +$/
19
+ // A leading BOM is removed during compilation, so reject a line that would
20
+ // become empty after removing it and trimming spaces.
21
+ const REGEX_TEST_BLANK_LINE = /^\uFEFF? *$/
20
22
  const REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/
21
23
  const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/
22
24
  const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/
@@ -29,7 +29,9 @@ var REGEX_LITERAL_SPECIAL = /[.*+?()[\]{}^$|\\/]/;
29
29
  // A line of only spaces is blank -- the trailing-space trimming empties it --
30
30
  // but a line holding a tab is a pattern for a tab-named path, since git
31
31
  // never trims a tab.
32
- var REGEX_TEST_BLANK_LINE = /^ +$/;
32
+ // A leading BOM is removed during compilation, so reject a line that would
33
+ // become empty after removing it and trimming spaces.
34
+ var REGEX_TEST_BLANK_LINE = /^\uFEFF? *$/;
33
35
  var REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/;
34
36
  var REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/;
35
37
  var REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ignore",
3
- "version": "7.0.8",
3
+ "version": "7.0.9",
4
4
  "description": "Ignore is a manager and filter for .gitignore rules, the one used by eslint, gitbook and many others.",
5
5
  "types": "index.d.ts",
6
6
  "files": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-lsp",
3
- "version": "6.3.0",
3
+ "version": "7.0.0",
4
4
  "description": "Language Server Protocol runtime for SuPi code intelligence",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -37,8 +37,8 @@
37
37
  "vscode-jsonrpc": "^9.0.0",
38
38
  "vscode-languageserver-protocol": "^3.18.0",
39
39
  "vscode-languageserver-types": "^3.18.0",
40
- "@mrclrchtr/supi-code-runtime": "6.3.0",
41
- "@mrclrchtr/supi-core": "6.3.0"
40
+ "@mrclrchtr/supi-code-runtime": "7.0.0",
41
+ "@mrclrchtr/supi-core": "7.0.0"
42
42
  },
43
43
  "bundledDependencies": [
44
44
  "@mrclrchtr/supi-code-runtime",
@@ -1,5 +1,6 @@
1
1
  // Public API surface for the LSP session-scoped service.
2
2
 
3
+ export { isMissingFileError } from "./client/client-file-state.ts";
3
4
  export { type LoadConfigOptions, loadConfig } from "./config/config.ts";
4
5
  export type { LspSettings } from "./config/lsp-settings.ts";
5
6
  export { loadLspSettings } from "./config/lsp-settings.ts";
@@ -11,6 +12,7 @@ export {
11
12
  invalidateTsconfigCacheForConfig,
12
13
  invalidateTsconfigCacheForConfigDir,
13
14
  isProjectConfigFileName,
15
+ isTsconfigApplicableFile,
14
16
  type ScopeDecisionBasis,
15
17
  } from "./config/tsconfig-scope.ts";
16
18
  export type {
@@ -41,6 +43,12 @@ export {
41
43
  type WorkspaceSentinelScanOptions,
42
44
  type WorkspaceSentinelSyncResult,
43
45
  } from "./diagnostics/workspace-sentinels.ts";
46
+ export {
47
+ scanWorkspaceSources,
48
+ type WorkspaceSourceInventory,
49
+ type WorkspaceSourceInventoryReason,
50
+ type WorkspaceSourceScanOptions,
51
+ } from "./diagnostics/workspace-sources.ts";
44
52
  export { raceReadinessValue, raceRequestControl } from "./session/readiness.ts";
45
53
  export type {
46
54
  LspControllerState,
@@ -51,6 +59,8 @@ export type {
51
59
  } from "./session/runtime-controller.ts";
52
60
  export { LspRuntimeController } from "./session/runtime-controller.ts";
53
61
  export type {
62
+ BulkTrackFileOutcome,
63
+ BulkTrackFilesResult,
54
64
  DiagnosticEvidenceDocument,
55
65
  DiagnosticEvidenceStatus,
56
66
  DiagnosticEvidenceSummary,
@@ -63,6 +73,10 @@ export type {
63
73
  RecoverDiagnosticsResult,
64
74
  RoutedMutationResponse,
65
75
  SemanticReadinessResult,
76
+ StartupRetryEntry,
77
+ StartupRetryNextAction,
78
+ StartupRetryOutcome,
79
+ StartupRetryReport,
66
80
  WorkspaceDiagnosticReport,
67
81
  WorkspaceDiagnosticSnapshot,
68
82
  WorkspaceDiagnosticSummaryEntry,
@@ -73,12 +87,14 @@ export type {
73
87
  export {
74
88
  clearWorkspaceLspRuntime,
75
89
  emptyProcessCrashRecoveryReport,
90
+ emptyStartupRetryReport,
76
91
  getWorkspaceLspRuntime,
77
92
  MAX_PROCESS_CRASH_RECOVERY_ENTRIES,
78
93
  setWorkspaceLspRuntimeState,
79
94
  waitForWorkspaceLspRuntime,
80
95
  } from "./session/runtime-registry.ts";
81
96
  export { scanMissingServers } from "./session/scanner.ts";
97
+ export { MAX_BULK_TRACK_FILES } from "./session/workspace-lsp-runtime.ts";
82
98
  export {
83
99
  AUTOMATIC_LSP_EXCLUDED_DIRECTORIES,
84
100
  type AutomaticLspPathPolicy,