@mrclrchtr/supi-code-intelligence 1.3.1 → 1.4.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 (103) hide show
  1. package/README.md +70 -32
  2. package/node_modules/@mrclrchtr/supi-core/README.md +52 -41
  3. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  4. package/node_modules/@mrclrchtr/supi-core/src/api.ts +13 -13
  5. package/node_modules/@mrclrchtr/supi-core/src/{config-settings.ts → config/config-settings.ts} +2 -2
  6. package/node_modules/@mrclrchtr/{supi-lsp/node_modules/@mrclrchtr/supi-core/src → supi-core/src/context}/context-provider-registry.ts +1 -1
  7. package/node_modules/@mrclrchtr/supi-core/src/extension.ts +1 -1
  8. package/node_modules/@mrclrchtr/supi-core/src/index.ts +13 -13
  9. package/node_modules/@mrclrchtr/{supi-lsp/node_modules/@mrclrchtr/supi-core/src → supi-core/src/settings}/settings-registry.ts +1 -1
  10. package/node_modules/@mrclrchtr/supi-lsp/README.md +58 -39
  11. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +52 -41
  12. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  13. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +13 -13
  14. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{config-settings.ts → config/config-settings.ts} +2 -2
  15. package/node_modules/@mrclrchtr/{supi-core/src → supi-lsp/node_modules/@mrclrchtr/supi-core/src/context}/context-provider-registry.ts +1 -1
  16. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/extension.ts +1 -1
  17. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +13 -13
  18. package/node_modules/@mrclrchtr/{supi-core/src → supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings}/settings-registry.ts +1 -1
  19. package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -2
  20. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +16 -3
  21. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-refresh.ts +1 -1
  22. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +27 -3
  23. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +61 -5
  24. package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +244 -0
  25. package/node_modules/@mrclrchtr/supi-lsp/src/{types.ts → config/types.ts} +4 -2
  26. package/node_modules/@mrclrchtr/supi-lsp/src/coordinates.ts +11 -0
  27. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-augmentation.ts +5 -5
  28. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-context.ts +115 -0
  29. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-display.ts +1 -1
  30. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostic-summary.ts +3 -2
  31. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/diagnostics.ts +1 -1
  32. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/stale-diagnostics.ts +1 -1
  33. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/suppression-diagnostics.ts +1 -1
  34. package/node_modules/@mrclrchtr/supi-lsp/src/{workspace-sentinels.ts → diagnostics/workspace-sentinels.ts} +2 -2
  35. package/node_modules/@mrclrchtr/supi-lsp/src/format.ts +2 -23
  36. package/node_modules/@mrclrchtr/supi-lsp/src/index.ts +18 -5
  37. package/node_modules/@mrclrchtr/supi-lsp/src/lsp.ts +72 -120
  38. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +1 -1
  39. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-helpers.ts +4 -2
  40. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-project-info.ts +10 -7
  41. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +1 -1
  42. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +158 -6
  43. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +202 -43
  44. package/node_modules/@mrclrchtr/supi-lsp/src/{lsp-state.ts → session/lsp-state.ts} +22 -11
  45. package/node_modules/@mrclrchtr/supi-lsp/src/{scanner.ts → session/scanner.ts} +3 -3
  46. package/node_modules/@mrclrchtr/supi-lsp/src/{service-registry.ts → session/service-registry.ts} +104 -12
  47. package/node_modules/@mrclrchtr/supi-lsp/src/{settings-registration.ts → session/settings-registration.ts} +1 -1
  48. package/node_modules/@mrclrchtr/supi-lsp/src/session/tree-persist.ts +75 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/src/summary.ts +1 -1
  50. package/node_modules/@mrclrchtr/supi-lsp/src/tool/guidance.ts +138 -0
  51. package/node_modules/@mrclrchtr/supi-lsp/src/tool/names.ts +19 -0
  52. package/node_modules/@mrclrchtr/supi-lsp/src/{overrides.ts → tool/overrides.ts} +55 -24
  53. package/node_modules/@mrclrchtr/supi-lsp/src/tool/register-tools.ts +224 -0
  54. package/node_modules/@mrclrchtr/supi-lsp/src/tool/service-actions.ts +258 -0
  55. package/node_modules/@mrclrchtr/supi-lsp/src/{ui.ts → ui/ui.ts} +4 -4
  56. package/node_modules/@mrclrchtr/supi-lsp/src/utils.ts +11 -0
  57. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +46 -39
  58. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +1 -1
  59. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +1 -1
  60. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +1 -1
  61. package/node_modules/@mrclrchtr/supi-tree-sitter/src/{runtime.ts → session/runtime.ts} +3 -3
  62. package/node_modules/@mrclrchtr/supi-tree-sitter/src/{session.ts → session/session.ts} +4 -4
  63. package/node_modules/@mrclrchtr/supi-tree-sitter/src/{callees.ts → tool/callees.ts} +3 -3
  64. package/node_modules/@mrclrchtr/supi-tree-sitter/src/{exports.ts → tool/exports.ts} +4 -4
  65. package/node_modules/@mrclrchtr/supi-tree-sitter/src/{formatting.ts → tool/formatting.ts} +1 -1
  66. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/guidance.ts +22 -0
  67. package/node_modules/@mrclrchtr/supi-tree-sitter/src/{imports.ts → tool/imports.ts} +4 -4
  68. package/node_modules/@mrclrchtr/supi-tree-sitter/src/{node-at.ts → tool/node-at.ts} +3 -3
  69. package/node_modules/@mrclrchtr/supi-tree-sitter/src/{outline.ts → tool/outline.ts} +3 -3
  70. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tree-sitter.ts +6 -29
  71. package/package.json +4 -4
  72. package/src/actions/affected-action.ts +4 -4
  73. package/src/actions/brief-action.ts +12 -13
  74. package/src/actions/callees-action.ts +14 -10
  75. package/src/actions/callers-action.ts +4 -4
  76. package/src/actions/implementations-action.ts +4 -4
  77. package/src/code-intelligence.ts +1 -1
  78. package/src/pattern-structured.ts +20 -22
  79. package/src/providers/semantic-provider.ts +34 -0
  80. package/src/providers/structural-provider.ts +14 -0
  81. package/src/target-resolution.ts +26 -35
  82. package/src/tool/guidance.ts +21 -0
  83. package/node_modules/@mrclrchtr/supi-lsp/src/guidance.ts +0 -163
  84. package/node_modules/@mrclrchtr/supi-lsp/src/search-fallback.ts +0 -98
  85. package/node_modules/@mrclrchtr/supi-lsp/src/tool-actions.ts +0 -430
  86. package/node_modules/@mrclrchtr/supi-lsp/src/tree-persist.ts +0 -48
  87. package/node_modules/@mrclrchtr/supi-lsp/src/tsconfig-scope.ts +0 -156
  88. package/src/guidance.ts +0 -42
  89. /package/node_modules/@mrclrchtr/supi-core/src/{config.ts → config/config.ts} +0 -0
  90. /package/node_modules/@mrclrchtr/supi-core/src/{context-messages.ts → context/context-messages.ts} +0 -0
  91. /package/node_modules/@mrclrchtr/supi-core/src/{context-tag.ts → context/context-tag.ts} +0 -0
  92. /package/node_modules/@mrclrchtr/supi-core/src/{settings-command.ts → settings/settings-command.ts} +0 -0
  93. /package/node_modules/@mrclrchtr/supi-core/src/{settings-ui.ts → settings/settings-ui.ts} +0 -0
  94. /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{config.ts → config/config.ts} +0 -0
  95. /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{context-messages.ts → context/context-messages.ts} +0 -0
  96. /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{context-tag.ts → context/context-tag.ts} +0 -0
  97. /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{settings-command.ts → settings/settings-command.ts} +0 -0
  98. /package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/{settings-ui.ts → settings/settings-ui.ts} +0 -0
  99. /package/node_modules/@mrclrchtr/supi-lsp/src/{capabilities.ts → config/capabilities.ts} +0 -0
  100. /package/node_modules/@mrclrchtr/supi-lsp/src/{config.ts → config/config.ts} +0 -0
  101. /package/node_modules/@mrclrchtr/supi-lsp/src/{defaults.json → config/defaults.json} +0 -0
  102. /package/node_modules/@mrclrchtr/supi-lsp/src/{renderer.ts → ui/renderer.ts} +0 -0
  103. /package/node_modules/@mrclrchtr/supi-tree-sitter/src/{structure.ts → tool/structure.ts} +0 -0
@@ -1,65 +1,78 @@
1
1
  # @mrclrchtr/supi-core
2
2
 
3
- Shared infrastructure for SuPi packages.
3
+ Shared infrastructure for SuPi extensions.
4
+
5
+ This package is mainly for extension authors. It gives you a common config system, settings plumbing, context helpers, registries, and a small extension surface that registers `/supi-settings`.
4
6
 
5
7
  ## Install
6
8
 
7
- Use it as a dependency in another extension package:
9
+ ### As a dependency for another extension
8
10
 
9
11
  ```bash
10
12
  pnpm add @mrclrchtr/supi-core
11
13
  ```
12
14
 
13
- ## Package role
14
-
15
- `@mrclrchtr/supi-core` now has two explicit surfaces:
15
+ ### As a pi package
16
16
 
17
- - `@mrclrchtr/supi-core/api` — shared library helpers for other SuPi packages
18
- - `@mrclrchtr/supi-core/extension` — a minimal pi extension that registers `/supi-settings`
19
-
20
- `pi.extensions` still points at the real file path `./src/extension.ts` inside the package. The `/api` and `/extension` paths are consumer-facing package exports, not manifest aliases.
17
+ ```bash
18
+ pi install npm:@mrclrchtr/supi-core
19
+ ```
21
20
 
22
- ## What it provides
21
+ Installing it as a pi package adds the minimal `/supi-settings` extension surface.
23
22
 
24
- Current exports cover:
23
+ ## Package surfaces
25
24
 
26
- - shared config loading, scoped reads, writes, and key removal
27
- - config-backed settings registration helpers for `/supi-settings`
28
- - the shared settings registry, overlay UI, and `registerSettingsCommand()` helper
29
- - XML `<extension-context>` wrapping plus context-message utilities
30
- - context-provider and debug-event registries reused across SuPi packages
31
- - project root and path helpers reused by packages such as `supi-lsp`
25
+ - `@mrclrchtr/supi-core/api` reusable helpers for other packages and extensions
26
+ - `@mrclrchtr/supi-core/extension` minimal pi extension that registers `/supi-settings`
32
27
 
33
- ## Config system
28
+ ## What you get from the API
34
29
 
35
- Config resolution order:
30
+ ### Config helpers
36
31
 
37
- ```text
38
- defaults <- global <- project
39
- ```
32
+ - `loadSupiConfig()` — merged config with resolution order `defaults <- global <- project`
33
+ - `loadSupiConfigForScope()` load one scope at a time for settings UIs
34
+ - `writeSupiConfig()` — persist values
35
+ - `removeSupiConfigKey()` — remove a key or override
40
36
 
41
37
  Config file locations:
42
38
 
43
39
  - global: `~/.pi/agent/supi/config.json`
44
40
  - project: `.pi/supi/config.json`
45
41
 
46
- Main helpers:
42
+ ### Settings helpers
43
+
44
+ - `registerSettings()` — register an arbitrary settings section
45
+ - `registerConfigSettings()` — register a config-backed settings section with scoped persistence helpers
46
+ - `registerSettingsCommand()` — register `/supi-settings`
47
+ - `openSettingsOverlay()` — open the shared settings UI directly
48
+ - `createInputSubmenu()` — helper for simple text-entry submenus
49
+
50
+ The built-in settings UI supports:
47
51
 
48
- - `loadSupiConfig()` — effective merged config (`defaults <- global <- project`)
49
- - `loadSupiConfigForScope()` raw single-scope config for settings UIs (`defaults <- selected scope`)
50
- - `writeSupiConfig()`
51
- - `removeSupiConfigKey()`
52
- - `registerConfigSettings()`
52
+ - project/global scope toggle
53
+ - grouped extension sections
54
+ - searchable setting lists
53
55
 
54
- ## Context and settings helpers
56
+ ### Context helpers
55
57
 
56
- - `wrapExtensionContext()`
58
+ - `wrapExtensionContext()` — wrap injected text in SuPi's `<extension-context>` tag
57
59
  - `findLastUserMessageIndex()`
58
60
  - `getContextToken()`
61
+ - `getPromptContent()`
59
62
  - `pruneAndReorderContextMessages()`
60
- - `registerSettings()`
61
- - `registerSettingsCommand()`
62
- - `openSettingsOverlay()`
63
+ - `restorePromptContent()`
64
+
65
+ ### Shared registries
66
+
67
+ - context-provider registry for `/supi-context`
68
+ - debug-event registry for producers that want shared debug capture
69
+ - settings registry used by `/supi-settings`
70
+
71
+ ### Project and session helpers
72
+
73
+ - project-root detection and directory walking helpers such as `findProjectRoot()` and `walkProject()`
74
+ - active-branch session helper: `getActiveBranchEntries()`
75
+ - terminal helpers such as `formatTitle()`, `signalWaiting()`, and `signalDone()`
63
76
 
64
77
  ## Example
65
78
 
@@ -80,17 +93,15 @@ registerConfigSettings({
80
93
  });
81
94
 
82
95
  const message = wrapExtensionContext("my-extension", "hello", {
83
- turn: 1,
84
96
  file: "CLAUDE.md",
97
+ turn: 1,
85
98
  });
86
99
  ```
87
100
 
88
- ## Requirements
89
-
90
- - `@earendil-works/pi-coding-agent`
91
- - `@earendil-works/pi-tui`
92
-
93
101
  ## Source
94
102
 
95
- - Library surface: `src/api.ts`
96
- - Extension surface: `src/extension.ts`
103
+ - `src/api.ts` — exported library surface
104
+ - `src/extension.ts` — minimal `/supi-settings` entrypoint
105
+ - `src/config.ts` — shared config loading and writing
106
+ - `src/config-settings.ts` — config-backed settings registration helper
107
+ - `src/settings-ui.ts` — shared settings overlay
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "SuPi core — shared infrastructure for SuPi extensions (XML context tags, config system)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -2,30 +2,30 @@
2
2
  // Provides XML context tag wrapping, unified config system, context-message utilities,
3
3
  // and settings registry for supi-wide TUI settings.
4
4
 
5
- export type { SupiConfigLocation, SupiConfigOptions } from "./config.ts";
5
+ export type { SupiConfigLocation, SupiConfigOptions } from "./config/config.ts";
6
6
  export {
7
7
  loadSupiConfig,
8
8
  loadSupiConfigForScope,
9
9
  removeSupiConfigKey,
10
10
  writeSupiConfig,
11
- } from "./config.ts";
12
- export type { ConfigSettingsHelpers, ConfigSettingsOptions } from "./config-settings.ts";
13
- export { registerConfigSettings } from "./config-settings.ts";
14
- export type { ContextMessageLike } from "./context-messages.ts";
11
+ } from "./config/config.ts";
12
+ export type { ConfigSettingsHelpers, ConfigSettingsOptions } from "./config/config-settings.ts";
13
+ export { registerConfigSettings } from "./config/config-settings.ts";
14
+ export type { ContextMessageLike } from "./context/context-messages.ts";
15
15
  export {
16
16
  findLastUserMessageIndex,
17
17
  getContextToken,
18
18
  getPromptContent,
19
19
  pruneAndReorderContextMessages,
20
20
  restorePromptContent,
21
- } from "./context-messages.ts";
22
- export type { ContextProvider } from "./context-provider-registry.ts";
21
+ } from "./context/context-messages.ts";
22
+ export type { ContextProvider } from "./context/context-provider-registry.ts";
23
23
  export {
24
24
  clearRegisteredContextProviders,
25
25
  getRegisteredContextProviders,
26
26
  registerContextProvider,
27
- } from "./context-provider-registry.ts";
28
- export { wrapExtensionContext } from "./context-tag.ts";
27
+ } from "./context/context-provider-registry.ts";
28
+ export { wrapExtensionContext } from "./context/context-tag.ts";
29
29
  export type {
30
30
  DebugAgentAccess,
31
31
  DebugEvent,
@@ -64,14 +64,14 @@ export {
64
64
  walkProject,
65
65
  } from "./project-roots.ts";
66
66
  export { getActiveBranchEntries } from "./session-utils.ts";
67
- export { registerSettingsCommand } from "./settings-command.ts";
68
- export type { SettingsScope, SettingsSection } from "./settings-registry.ts";
67
+ export { registerSettingsCommand } from "./settings/settings-command.ts";
68
+ export type { SettingsScope, SettingsSection } from "./settings/settings-registry.ts";
69
69
  export {
70
70
  clearRegisteredSettings,
71
71
  getRegisteredSettings,
72
72
  registerSettings,
73
- } from "./settings-registry.ts";
74
- export { createInputSubmenu, openSettingsOverlay } from "./settings-ui.ts";
73
+ } from "./settings/settings-registry.ts";
74
+ export { createInputSubmenu, openSettingsOverlay } from "./settings/settings-ui.ts";
75
75
  export type { TitleTarget } from "./terminal.ts";
76
76
  export {
77
77
  DONE_SYMBOL,
@@ -2,9 +2,9 @@
2
2
  // Wraps registerSettings() and centralizes selected-scope loading + scoped persistence.
3
3
 
4
4
  import type { SettingItem } from "@earendil-works/pi-tui";
5
+ import type { SettingsScope } from "../settings/settings-registry.ts";
6
+ import { registerSettings } from "../settings/settings-registry.ts";
5
7
  import { loadSupiConfigForScope, removeSupiConfigKey, writeSupiConfig } from "./config.ts";
6
- import type { SettingsScope } from "./settings-registry.ts";
7
- import { registerSettings } from "./settings-registry.ts";
8
8
 
9
9
  export interface ConfigSettingsHelpers {
10
10
  /** Write a key to the selected scope's config section. */
@@ -3,7 +3,7 @@
3
3
  // Extensions declare context data providers via `registerContextProvider()` during their
4
4
  // factory function. The `/supi-context` command reads them via `getRegisteredContextProviders()`.
5
5
 
6
- import { createRegistry } from "./registry-utils.ts";
6
+ import { createRegistry } from "../registry-utils.ts";
7
7
 
8
8
  export interface ContextProvider {
9
9
  /** Unique identifier — e.g. "rtk" */
@@ -1 +1 @@
1
- export { registerSettingsCommand as default } from "./settings-command.ts";
1
+ export { registerSettingsCommand as default } from "./settings/settings-command.ts";
@@ -2,30 +2,30 @@
2
2
  // Provides XML context tag wrapping, unified config system, context-message utilities,
3
3
  // and settings registry for supi-wide TUI settings.
4
4
 
5
- export type { SupiConfigLocation, SupiConfigOptions } from "./config.ts";
5
+ export type { SupiConfigLocation, SupiConfigOptions } from "./config/config.ts";
6
6
  export {
7
7
  loadSupiConfig,
8
8
  loadSupiConfigForScope,
9
9
  removeSupiConfigKey,
10
10
  writeSupiConfig,
11
- } from "./config.ts";
12
- export type { ConfigSettingsHelpers, ConfigSettingsOptions } from "./config-settings.ts";
13
- export { registerConfigSettings } from "./config-settings.ts";
14
- export type { ContextMessageLike } from "./context-messages.ts";
11
+ } from "./config/config.ts";
12
+ export type { ConfigSettingsHelpers, ConfigSettingsOptions } from "./config/config-settings.ts";
13
+ export { registerConfigSettings } from "./config/config-settings.ts";
14
+ export type { ContextMessageLike } from "./context/context-messages.ts";
15
15
  export {
16
16
  findLastUserMessageIndex,
17
17
  getContextToken,
18
18
  getPromptContent,
19
19
  pruneAndReorderContextMessages,
20
20
  restorePromptContent,
21
- } from "./context-messages.ts";
22
- export type { ContextProvider } from "./context-provider-registry.ts";
21
+ } from "./context/context-messages.ts";
22
+ export type { ContextProvider } from "./context/context-provider-registry.ts";
23
23
  export {
24
24
  clearRegisteredContextProviders,
25
25
  getRegisteredContextProviders,
26
26
  registerContextProvider,
27
- } from "./context-provider-registry.ts";
28
- export { wrapExtensionContext } from "./context-tag.ts";
27
+ } from "./context/context-provider-registry.ts";
28
+ export { wrapExtensionContext } from "./context/context-tag.ts";
29
29
  export type {
30
30
  DebugAgentAccess,
31
31
  DebugEvent,
@@ -64,14 +64,14 @@ export {
64
64
  walkProject,
65
65
  } from "./project-roots.ts";
66
66
  export { getActiveBranchEntries } from "./session-utils.ts";
67
- export { registerSettingsCommand } from "./settings-command.ts";
68
- export type { SettingsScope, SettingsSection } from "./settings-registry.ts";
67
+ export { registerSettingsCommand } from "./settings/settings-command.ts";
68
+ export type { SettingsScope, SettingsSection } from "./settings/settings-registry.ts";
69
69
  export {
70
70
  clearRegisteredSettings,
71
71
  getRegisteredSettings,
72
72
  registerSettings,
73
- } from "./settings-registry.ts";
74
- export { createInputSubmenu, openSettingsOverlay } from "./settings-ui.ts";
73
+ } from "./settings/settings-registry.ts";
74
+ export { createInputSubmenu, openSettingsOverlay } from "./settings/settings-ui.ts";
75
75
  export type { TitleTarget } from "./terminal.ts";
76
76
  export {
77
77
  DONE_SYMBOL,
@@ -4,7 +4,7 @@
4
4
  // factory function. The generic settings UI reads them via `getRegisteredSettings()`.
5
5
 
6
6
  import type { SettingItem } from "@earendil-works/pi-tui";
7
- import { createRegistry } from "./registry-utils.ts";
7
+ import { createRegistry } from "../registry-utils.ts";
8
8
 
9
9
  export type SettingsScope = "project" | "global";
10
10
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-lsp",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "SuPi LSP extension — Language Server Protocol integration for pi",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,7 +21,8 @@
21
21
  "!__tests__"
22
22
  ],
23
23
  "dependencies": {
24
- "@mrclrchtr/supi-core": "1.3.1"
24
+ "typescript": "6.0.3",
25
+ "@mrclrchtr/supi-core": "1.4.0"
25
26
  },
26
27
  "bundledDependencies": [
27
28
  "@mrclrchtr/supi-core"
@@ -1,8 +1,7 @@
1
1
  // Public API surface for the LSP session-scoped service.
2
2
 
3
- export type { SessionLspServiceState } from "./service-registry.ts";
4
- export { getSessionLspService, SessionLspService } from "./service-registry.ts";
5
3
  export type {
4
+ CodeAction,
6
5
  Diagnostic,
7
6
  DocumentSymbol,
8
7
  Hover,
@@ -10,6 +9,20 @@ export type {
10
9
  LocationLink,
11
10
  Position,
12
11
  ProjectServerInfo,
12
+ Range,
13
13
  SymbolInformation,
14
+ WorkspaceEdit,
14
15
  WorkspaceSymbol,
15
- } from "./types.ts";
16
+ } from "./config/types.ts";
17
+ export { toLspPosition, toOneBasedPosition } from "./coordinates.ts";
18
+ export type {
19
+ OutstandingDiagnosticSummaryEntry,
20
+ RecoverDiagnosticsResult,
21
+ SessionLspServiceState,
22
+ WorkspaceDiagnosticSummaryEntry,
23
+ } from "./session/service-registry.ts";
24
+ export {
25
+ getSessionLspService,
26
+ SessionLspService,
27
+ waitForSessionLspService,
28
+ } from "./session/service-registry.ts";
@@ -2,7 +2,7 @@
2
2
  // Extracted from client.ts to keep file sizes manageable.
3
3
 
4
4
  import { existsSync, readFileSync } from "node:fs";
5
- import type { DocumentDiagnosticReport, TextDocumentIdentifier } from "../types.ts";
5
+ import type { DocumentDiagnosticReport, TextDocumentIdentifier } from "../config/types.ts";
6
6
  import { uriToFile } from "../utils.ts";
7
7
  import type { DiagnosticCacheEntry, LspClient } from "./client.ts";
8
8
  import type { JsonRpcClient } from "./transport.ts";
@@ -4,7 +4,8 @@
4
4
  // biome-ignore lint/nursery/noExcessiveLinesPerFile: LspClient remains a cohesive stateful wrapper; refresh logic is already split out.
5
5
  import { type ChildProcess, spawn } from "node:child_process";
6
6
  import { existsSync } from "node:fs";
7
- import { CLIENT_CAPABILITIES } from "../capabilities.ts";
7
+ import * as path from "node:path";
8
+ import { CLIENT_CAPABILITIES } from "../config/capabilities.ts";
8
9
  import type {
9
10
  CodeAction,
10
11
  CodeActionContext,
@@ -27,9 +28,9 @@ import type {
27
28
  VersionedTextDocumentIdentifier,
28
29
  WorkspaceEdit,
29
30
  WorkspaceSymbol,
30
- } from "../types.ts";
31
+ } from "../config/types.ts";
31
32
  import { detectLanguageId, fileToUri, uriToFile } from "../utils.ts";
32
- import { JsonRpcClient } from "./transport.ts";
33
+ import { JsonRpcClient, JsonRpcRequestError } from "./transport.ts";
33
34
 
34
35
  const SHUTDOWN_TIMEOUT_MS = 5_000;
35
36
  const DIAGNOSTIC_WAIT_MS = 3_000;
@@ -119,6 +120,7 @@ export class LspClient {
119
120
  this.handlePublishDiagnostics(params as PublishDiagnosticsParams);
120
121
  }
121
122
  });
123
+ this.rpc.onRequest((method, params) => this.handleServerRequest(method, params));
122
124
 
123
125
  // Handle crashes
124
126
  this.process.on("exit", (_code) => {
@@ -469,6 +471,28 @@ export class LspClient {
469
471
  }
470
472
  }
471
473
 
474
+ private handleServerRequest(method: string, params: unknown): unknown {
475
+ switch (method) {
476
+ case "workspace/configuration":
477
+ return this.buildWorkspaceConfigurationResult(params);
478
+ case "workspace/workspaceFolders":
479
+ return [{ uri: fileToUri(this.root), name: path.basename(this.root) || this.root }];
480
+ case "client/registerCapability":
481
+ case "client/unregisterCapability":
482
+ case "window/workDoneProgress/create":
483
+ return null;
484
+ default:
485
+ throw new JsonRpcRequestError(-32601, `Method not found: ${method}`);
486
+ }
487
+ }
488
+
489
+ private buildWorkspaceConfigurationResult(params: unknown): unknown[] {
490
+ if (!params || typeof params !== "object") return [];
491
+ const items = (params as { items?: unknown }).items;
492
+ if (!Array.isArray(items)) return [];
493
+ return items.map(() => null);
494
+ }
495
+
472
496
  private handlePublishDiagnostics(params: PublishDiagnosticsParams): void {
473
497
  // If the publication includes a version and we have a newer synced
474
498
  // version for this open document, ignore the stale publication.
@@ -2,11 +2,12 @@
2
2
 
3
3
  import type { Readable, Writable } from "node:stream";
4
4
  import type {
5
+ JsonRpcId,
5
6
  JsonRpcMessage,
6
7
  JsonRpcNotification,
7
8
  JsonRpcRequest,
8
9
  JsonRpcResponse,
9
- } from "../types.ts";
10
+ } from "../config/types.ts";
10
11
 
11
12
  const CONTENT_LENGTH = "Content-Length: ";
12
13
  const HEADER_DELIMITER = "\r\n\r\n";
@@ -15,6 +16,7 @@ const DEFAULT_TIMEOUT_MS = 30_000;
15
16
  // ── Types ─────────────────────────────────────────────────────────────
16
17
 
17
18
  export type NotificationHandler = (method: string, params: unknown) => void;
19
+ export type RequestHandler = (method: string, params: unknown) => Promise<unknown> | unknown;
18
20
 
19
21
  interface PendingRequest {
20
22
  resolve: (result: unknown) => void;
@@ -22,13 +24,25 @@ interface PendingRequest {
22
24
  timer: ReturnType<typeof setTimeout>;
23
25
  }
24
26
 
27
+ export class JsonRpcRequestError extends Error {
28
+ constructor(
29
+ readonly code: number,
30
+ message: string,
31
+ readonly data?: unknown,
32
+ ) {
33
+ super(message);
34
+ this.name = "JsonRpcRequestError";
35
+ }
36
+ }
37
+
25
38
  // ── JsonRpcClient ─────────────────────────────────────────────────────
26
39
 
27
40
  export class JsonRpcClient {
28
41
  private nextId = 1;
29
42
  private buffer = Buffer.alloc(0);
30
- private pending = new Map<number, PendingRequest>();
43
+ private pending = new Map<JsonRpcId, PendingRequest>();
31
44
  private notificationHandler: NotificationHandler | null = null;
45
+ private requestHandler: RequestHandler | null = null;
32
46
  private closed = false;
33
47
  private readonly timeoutMs: number;
34
48
 
@@ -48,6 +62,11 @@ export class JsonRpcClient {
48
62
  this.notificationHandler = handler;
49
63
  }
50
64
 
65
+ /** Register a handler for server-initiated requests. */
66
+ onRequest(handler: RequestHandler): void {
67
+ this.requestHandler = handler;
68
+ }
69
+
51
70
  /** Send a request and wait for the correlated response, optionally overriding the timeout. */
52
71
  sendRequest(
53
72
  method: string,
@@ -147,9 +166,11 @@ export class JsonRpcClient {
147
166
  // Response (has id, has result or error)
148
167
  if ("id" in msg && msg.id != null && ("result" in msg || "error" in msg)) {
149
168
  const response = msg as JsonRpcResponse;
150
- const pending = this.pending.get(response.id);
169
+ const id = response.id;
170
+ if (id === null) return;
171
+ const pending = this.pending.get(id);
151
172
  if (pending) {
152
- this.pending.delete(response.id);
173
+ this.pending.delete(id);
153
174
  clearTimeout(pending.timer);
154
175
  if (response.error) {
155
176
  pending.reject(new Error(`LSP error ${response.error.code}: ${response.error.message}`));
@@ -164,9 +185,44 @@ export class JsonRpcClient {
164
185
  if ("method" in msg && !("id" in msg)) {
165
186
  const notification = msg as JsonRpcNotification;
166
187
  this.notificationHandler?.(notification.method, notification.params);
188
+ return;
167
189
  }
168
190
 
169
- // Request from server (has id + method) — we don't handle server→client requests yet
191
+ // Request from server (has id + method)
192
+ if ("method" in msg && "id" in msg && msg.id != null) {
193
+ void this.handleInboundRequest(msg as JsonRpcRequest);
194
+ }
195
+ }
196
+
197
+ private async handleInboundRequest(request: JsonRpcRequest): Promise<void> {
198
+ if (this.closed) return;
199
+
200
+ try {
201
+ if (!this.requestHandler) {
202
+ throw new JsonRpcRequestError(-32601, `Method not found: ${request.method}`);
203
+ }
204
+
205
+ const result = await this.requestHandler(request.method, request.params);
206
+ this.writeMessage({
207
+ jsonrpc: "2.0",
208
+ id: request.id,
209
+ result: result ?? null,
210
+ } satisfies JsonRpcResponse);
211
+ } catch (error) {
212
+ const failure =
213
+ error instanceof JsonRpcRequestError
214
+ ? error
215
+ : new JsonRpcRequestError(-32603, error instanceof Error ? error.message : String(error));
216
+ this.writeMessage({
217
+ jsonrpc: "2.0",
218
+ id: request.id,
219
+ error: {
220
+ code: failure.code,
221
+ message: failure.message,
222
+ ...(failure.data !== undefined ? { data: failure.data } : {}),
223
+ },
224
+ } satisfies JsonRpcResponse);
225
+ }
170
226
  }
171
227
 
172
228
  private onClose(): void {