@nocturnium/svelte-ide 1.0.0-rc.1

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 (330) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/dist/components/agents/AgentActivityPanel.svelte +565 -0
  4. package/dist/components/agents/AgentActivityPanel.svelte.d.ts +24 -0
  5. package/dist/components/agents/AgentAvatar.svelte +417 -0
  6. package/dist/components/agents/AgentAvatar.svelte.d.ts +23 -0
  7. package/dist/components/agents/AgentCursor.svelte +224 -0
  8. package/dist/components/agents/AgentCursor.svelte.d.ts +35 -0
  9. package/dist/components/agents/AgentPresenceBar.svelte +261 -0
  10. package/dist/components/agents/AgentPresenceBar.svelte.d.ts +20 -0
  11. package/dist/components/agents/index.d.ts +4 -0
  12. package/dist/components/agents/index.js +5 -0
  13. package/dist/components/ai/AIConversationList.svelte +524 -0
  14. package/dist/components/ai/AIConversationList.svelte.d.ts +17 -0
  15. package/dist/components/ai/AIEditPreview.svelte +132 -0
  16. package/dist/components/ai/AIEditPreview.svelte.d.ts +8 -0
  17. package/dist/components/ai/AIInlineEdit.svelte +155 -0
  18. package/dist/components/ai/AIInlineEdit.svelte.d.ts +10 -0
  19. package/dist/components/ai/AIMessage.svelte +239 -0
  20. package/dist/components/ai/AIMessage.svelte.d.ts +13 -0
  21. package/dist/components/ai/AIMessageActions.svelte +176 -0
  22. package/dist/components/ai/AIMessageActions.svelte.d.ts +12 -0
  23. package/dist/components/ai/AIMessageContent.svelte +355 -0
  24. package/dist/components/ai/AIMessageContent.svelte.d.ts +7 -0
  25. package/dist/components/ai/AIPanel.svelte +561 -0
  26. package/dist/components/ai/AIPanel.svelte.d.ts +7 -0
  27. package/dist/components/ai/AISuggestionWidget.svelte +132 -0
  28. package/dist/components/ai/AISuggestionWidget.svelte.d.ts +10 -0
  29. package/dist/components/ai/AIToolCallDisplay.svelte +317 -0
  30. package/dist/components/ai/AIToolCallDisplay.svelte.d.ts +12 -0
  31. package/dist/components/ai/index.d.ts +9 -0
  32. package/dist/components/ai/index.js +10 -0
  33. package/dist/components/core/Avatar.svelte +110 -0
  34. package/dist/components/core/Avatar.svelte.d.ts +12 -0
  35. package/dist/components/core/Badge.svelte +98 -0
  36. package/dist/components/core/Badge.svelte.d.ts +11 -0
  37. package/dist/components/core/Button.svelte +175 -0
  38. package/dist/components/core/Button.svelte.d.ts +18 -0
  39. package/dist/components/core/ConnectionStatus.svelte +294 -0
  40. package/dist/components/core/ConnectionStatus.svelte.d.ts +20 -0
  41. package/dist/components/core/ContextMenu.svelte +176 -0
  42. package/dist/components/core/ContextMenu.svelte.d.ts +19 -0
  43. package/dist/components/core/ErrorBoundary.svelte +277 -0
  44. package/dist/components/core/ErrorBoundary.svelte.d.ts +23 -0
  45. package/dist/components/core/Icon.svelte +107 -0
  46. package/dist/components/core/Icon.svelte.d.ts +8 -0
  47. package/dist/components/core/Input.svelte +138 -0
  48. package/dist/components/core/Input.svelte.d.ts +20 -0
  49. package/dist/components/core/Kbd.svelte +34 -0
  50. package/dist/components/core/Kbd.svelte.d.ts +7 -0
  51. package/dist/components/core/ResizeHandle.svelte +200 -0
  52. package/dist/components/core/ResizeHandle.svelte.d.ts +23 -0
  53. package/dist/components/core/Spinner.svelte +35 -0
  54. package/dist/components/core/Spinner.svelte.d.ts +7 -0
  55. package/dist/components/core/Textarea.svelte +112 -0
  56. package/dist/components/core/Textarea.svelte.d.ts +18 -0
  57. package/dist/components/core/Tooltip.svelte +103 -0
  58. package/dist/components/core/Tooltip.svelte.d.ts +11 -0
  59. package/dist/components/core/index.d.ts +13 -0
  60. package/dist/components/core/index.js +14 -0
  61. package/dist/components/editor/AIFocusLayer.svelte +430 -0
  62. package/dist/components/editor/AIFocusLayer.svelte.d.ts +32 -0
  63. package/dist/components/editor/Breadcrumbs.svelte +435 -0
  64. package/dist/components/editor/Breadcrumbs.svelte.d.ts +33 -0
  65. package/dist/components/editor/BreakpointLayer.svelte +642 -0
  66. package/dist/components/editor/BreakpointLayer.svelte.d.ts +20 -0
  67. package/dist/components/editor/CognitiveLoadMeter.svelte +324 -0
  68. package/dist/components/editor/CognitiveLoadMeter.svelte.d.ts +18 -0
  69. package/dist/components/editor/CollaborativeEditor.svelte +218 -0
  70. package/dist/components/editor/CollaborativeEditor.svelte.d.ts +32 -0
  71. package/dist/components/editor/CommandPalette.svelte +434 -0
  72. package/dist/components/editor/CommandPalette.svelte.d.ts +11 -0
  73. package/dist/components/editor/ComplexityLayer.svelte +293 -0
  74. package/dist/components/editor/ComplexityLayer.svelte.d.ts +23 -0
  75. package/dist/components/editor/ConflictZoneLayer.svelte +441 -0
  76. package/dist/components/editor/ConflictZoneLayer.svelte.d.ts +25 -0
  77. package/dist/components/editor/ContextLens.svelte +262 -0
  78. package/dist/components/editor/ContextLens.svelte.d.ts +27 -0
  79. package/dist/components/editor/CustomEditor.svelte +1242 -0
  80. package/dist/components/editor/CustomEditor.svelte.d.ts +37 -0
  81. package/dist/components/editor/DebugConsole.svelte +646 -0
  82. package/dist/components/editor/DebugConsole.svelte.d.ts +41 -0
  83. package/dist/components/editor/EchoCursorLayer.svelte +363 -0
  84. package/dist/components/editor/EchoCursorLayer.svelte.d.ts +24 -0
  85. package/dist/components/editor/Editor.svelte +61 -0
  86. package/dist/components/editor/Editor.svelte.d.ts +22 -0
  87. package/dist/components/editor/EditorGutter.svelte +119 -0
  88. package/dist/components/editor/EditorGutter.svelte.d.ts +19 -0
  89. package/dist/components/editor/EditorLines.svelte +182 -0
  90. package/dist/components/editor/EditorLines.svelte.d.ts +43 -0
  91. package/dist/components/editor/EditorPane.svelte +134 -0
  92. package/dist/components/editor/EditorPane.svelte.d.ts +9 -0
  93. package/dist/components/editor/EditorSelections.svelte +186 -0
  94. package/dist/components/editor/EditorSelections.svelte.d.ts +25 -0
  95. package/dist/components/editor/EditorTabs.svelte +170 -0
  96. package/dist/components/editor/EditorTabs.svelte.d.ts +12 -0
  97. package/dist/components/editor/FileExplorer.svelte +811 -0
  98. package/dist/components/editor/FileExplorer.svelte.d.ts +67 -0
  99. package/dist/components/editor/FileIcon.svelte +110 -0
  100. package/dist/components/editor/FileIcon.svelte.d.ts +10 -0
  101. package/dist/components/editor/FindReplace.svelte +448 -0
  102. package/dist/components/editor/FindReplace.svelte.d.ts +40 -0
  103. package/dist/components/editor/GhostBracketLayer.svelte +391 -0
  104. package/dist/components/editor/GhostBracketLayer.svelte.d.ts +24 -0
  105. package/dist/components/editor/GitBlameLayer.svelte +436 -0
  106. package/dist/components/editor/GitBlameLayer.svelte.d.ts +18 -0
  107. package/dist/components/editor/InlineDiagnosticsLayer.svelte +540 -0
  108. package/dist/components/editor/InlineDiagnosticsLayer.svelte.d.ts +35 -0
  109. package/dist/components/editor/InlineDiffLayer.svelte +337 -0
  110. package/dist/components/editor/InlineDiffLayer.svelte.d.ts +31 -0
  111. package/dist/components/editor/MinimalEditor.svelte +75 -0
  112. package/dist/components/editor/MinimalEditor.svelte.d.ts +6 -0
  113. package/dist/components/editor/MinimalEditor2.svelte +84 -0
  114. package/dist/components/editor/MinimalEditor2.svelte.d.ts +6 -0
  115. package/dist/components/editor/Minimap.svelte +327 -0
  116. package/dist/components/editor/Minimap.svelte.d.ts +34 -0
  117. package/dist/components/editor/PluginPreviewSandbox.svelte +793 -0
  118. package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +49 -0
  119. package/dist/components/editor/ProblemsPanel.svelte +628 -0
  120. package/dist/components/editor/ProblemsPanel.svelte.d.ts +25 -0
  121. package/dist/components/editor/QuickActionsMenu.svelte +403 -0
  122. package/dist/components/editor/QuickActionsMenu.svelte.d.ts +18 -0
  123. package/dist/components/editor/SnippetPalette.svelte +530 -0
  124. package/dist/components/editor/SnippetPalette.svelte.d.ts +16 -0
  125. package/dist/components/editor/StructureMap.svelte +431 -0
  126. package/dist/components/editor/StructureMap.svelte.d.ts +37 -0
  127. package/dist/components/editor/SymbolOutline.svelte +722 -0
  128. package/dist/components/editor/SymbolOutline.svelte.d.ts +44 -0
  129. package/dist/components/editor/TimelineScrubber.svelte +470 -0
  130. package/dist/components/editor/TimelineScrubber.svelte.d.ts +40 -0
  131. package/dist/components/editor/TokenRenderer.svelte +69 -0
  132. package/dist/components/editor/TokenRenderer.svelte.d.ts +15 -0
  133. package/dist/components/editor/constants.d.ts +32 -0
  134. package/dist/components/editor/constants.js +36 -0
  135. package/dist/components/editor/core/ai-awareness.d.ts +176 -0
  136. package/dist/components/editor/core/ai-awareness.js +210 -0
  137. package/dist/components/editor/core/bracket-healer.d.ts +189 -0
  138. package/dist/components/editor/core/bracket-healer.js +406 -0
  139. package/dist/components/editor/core/breakpoints.d.ts +203 -0
  140. package/dist/components/editor/core/breakpoints.js +414 -0
  141. package/dist/components/editor/core/commands.d.ts +108 -0
  142. package/dist/components/editor/core/commands.js +246 -0
  143. package/dist/components/editor/core/complexity-analyzer.d.ts +123 -0
  144. package/dist/components/editor/core/complexity-analyzer.js +376 -0
  145. package/dist/components/editor/core/conflict-predictor.d.ts +135 -0
  146. package/dist/components/editor/core/conflict-predictor.js +316 -0
  147. package/dist/components/editor/core/crdt-binding.d.ts +118 -0
  148. package/dist/components/editor/core/crdt-binding.js +286 -0
  149. package/dist/components/editor/core/diagnostics.d.ts +210 -0
  150. package/dist/components/editor/core/diagnostics.js +335 -0
  151. package/dist/components/editor/core/echo-cursor.d.ts +201 -0
  152. package/dist/components/editor/core/echo-cursor.js +267 -0
  153. package/dist/components/editor/core/folding.d.ts +124 -0
  154. package/dist/components/editor/core/folding.js +672 -0
  155. package/dist/components/editor/core/ghost-pair.d.ts +122 -0
  156. package/dist/components/editor/core/ghost-pair.js +221 -0
  157. package/dist/components/editor/core/git-blame.d.ts +170 -0
  158. package/dist/components/editor/core/git-blame.js +324 -0
  159. package/dist/components/editor/core/index.d.ts +26 -0
  160. package/dist/components/editor/core/index.js +24 -0
  161. package/dist/components/editor/core/keybindings.d.ts +79 -0
  162. package/dist/components/editor/core/keybindings.js +357 -0
  163. package/dist/components/editor/core/multi-cursor.d.ts +196 -0
  164. package/dist/components/editor/core/multi-cursor.js +521 -0
  165. package/dist/components/editor/core/navigation.d.ts +107 -0
  166. package/dist/components/editor/core/navigation.js +408 -0
  167. package/dist/components/editor/core/quick-actions.d.ts +189 -0
  168. package/dist/components/editor/core/quick-actions.js +427 -0
  169. package/dist/components/editor/core/search.d.ts +88 -0
  170. package/dist/components/editor/core/search.js +192 -0
  171. package/dist/components/editor/core/semantic-analyzer.d.ts +77 -0
  172. package/dist/components/editor/core/semantic-analyzer.js +424 -0
  173. package/dist/components/editor/core/snippet-manager.d.ts +202 -0
  174. package/dist/components/editor/core/snippet-manager.js +565 -0
  175. package/dist/components/editor/core/state.d.ts +367 -0
  176. package/dist/components/editor/core/state.js +900 -0
  177. package/dist/components/editor/core/timeline.d.ts +204 -0
  178. package/dist/components/editor/core/timeline.js +349 -0
  179. package/dist/components/editor/editor-find.d.ts +56 -0
  180. package/dist/components/editor/editor-find.js +148 -0
  181. package/dist/components/editor/editor-input.d.ts +77 -0
  182. package/dist/components/editor/editor-input.js +445 -0
  183. package/dist/components/editor/editor-multicursor.d.ts +21 -0
  184. package/dist/components/editor/editor-multicursor.js +196 -0
  185. package/dist/components/editor/editor-scroll.d.ts +14 -0
  186. package/dist/components/editor/editor-scroll.js +34 -0
  187. package/dist/components/editor/index.d.ts +15 -0
  188. package/dist/components/editor/index.js +21 -0
  189. package/dist/components/editor/languages.d.ts +62 -0
  190. package/dist/components/editor/languages.js +285 -0
  191. package/dist/components/editor/theme.d.ts +88 -0
  192. package/dist/components/editor/theme.js +139 -0
  193. package/dist/components/editor/tokenizer/base.d.ts +40 -0
  194. package/dist/components/editor/tokenizer/base.js +203 -0
  195. package/dist/components/editor/tokenizer/index.d.ts +56 -0
  196. package/dist/components/editor/tokenizer/index.js +215 -0
  197. package/dist/components/editor/tokenizer/languages/css.d.ts +17 -0
  198. package/dist/components/editor/tokenizer/languages/css.js +194 -0
  199. package/dist/components/editor/tokenizer/languages/go.d.ts +17 -0
  200. package/dist/components/editor/tokenizer/languages/go.js +220 -0
  201. package/dist/components/editor/tokenizer/languages/html.d.ts +24 -0
  202. package/dist/components/editor/tokenizer/languages/html.js +145 -0
  203. package/dist/components/editor/tokenizer/languages/javascript.d.ts +56 -0
  204. package/dist/components/editor/tokenizer/languages/javascript.js +452 -0
  205. package/dist/components/editor/tokenizer/languages/json.d.ts +12 -0
  206. package/dist/components/editor/tokenizer/languages/json.js +91 -0
  207. package/dist/components/editor/tokenizer/languages/markdown.d.ts +16 -0
  208. package/dist/components/editor/tokenizer/languages/markdown.js +156 -0
  209. package/dist/components/editor/tokenizer/languages/python.d.ts +20 -0
  210. package/dist/components/editor/tokenizer/languages/python.js +227 -0
  211. package/dist/components/editor/tokenizer/languages/svelte.d.ts +40 -0
  212. package/dist/components/editor/tokenizer/languages/svelte.js +326 -0
  213. package/dist/components/editor/tokenizer/types.d.ts +86 -0
  214. package/dist/components/editor/tokenizer/types.js +4 -0
  215. package/dist/components/layout/IDELayout.svelte +274 -0
  216. package/dist/components/layout/IDELayout.svelte.d.ts +29 -0
  217. package/dist/components/layout/StatusBar.svelte +511 -0
  218. package/dist/components/layout/StatusBar.svelte.d.ts +47 -0
  219. package/dist/components/layout/index.d.ts +2 -0
  220. package/dist/components/layout/index.js +3 -0
  221. package/dist/components/lsp/AutocompleteWidget.svelte +364 -0
  222. package/dist/components/lsp/AutocompleteWidget.svelte.d.ts +33 -0
  223. package/dist/components/lsp/DiagnosticMarker.svelte +166 -0
  224. package/dist/components/lsp/DiagnosticMarker.svelte.d.ts +19 -0
  225. package/dist/components/lsp/DiagnosticsPanel.svelte +388 -0
  226. package/dist/components/lsp/DiagnosticsPanel.svelte.d.ts +21 -0
  227. package/dist/components/lsp/HoverTooltip.svelte +274 -0
  228. package/dist/components/lsp/HoverTooltip.svelte.d.ts +24 -0
  229. package/dist/components/lsp/LSPEditor.svelte +486 -0
  230. package/dist/components/lsp/LSPEditor.svelte.d.ts +39 -0
  231. package/dist/components/lsp/SignatureHelpWidget.svelte +216 -0
  232. package/dist/components/lsp/SignatureHelpWidget.svelte.d.ts +22 -0
  233. package/dist/components/lsp/index.d.ts +6 -0
  234. package/dist/components/lsp/index.js +7 -0
  235. package/dist/components/plugins/PluginCard.svelte +153 -0
  236. package/dist/components/plugins/PluginCard.svelte.d.ts +19 -0
  237. package/dist/components/plugins/PluginPanel.svelte +280 -0
  238. package/dist/components/plugins/PluginPanel.svelte.d.ts +8 -0
  239. package/dist/components/plugins/PluginProposalForm.svelte +250 -0
  240. package/dist/components/plugins/PluginProposalForm.svelte.d.ts +6 -0
  241. package/dist/components/plugins/PluginStatusBadge.svelte +14 -0
  242. package/dist/components/plugins/PluginStatusBadge.svelte.d.ts +8 -0
  243. package/dist/components/plugins/index.d.ts +4 -0
  244. package/dist/components/plugins/index.js +5 -0
  245. package/dist/components/vfs/LockConflictDialog.svelte +705 -0
  246. package/dist/components/vfs/LockConflictDialog.svelte.d.ts +21 -0
  247. package/dist/components/vfs/LockIndicator.svelte +194 -0
  248. package/dist/components/vfs/LockIndicator.svelte.d.ts +29 -0
  249. package/dist/components/vfs/LockOverlay.svelte +344 -0
  250. package/dist/components/vfs/LockOverlay.svelte.d.ts +17 -0
  251. package/dist/components/vfs/VersionConflictDialog.svelte +549 -0
  252. package/dist/components/vfs/VersionConflictDialog.svelte.d.ts +24 -0
  253. package/dist/components/vfs/index.d.ts +4 -0
  254. package/dist/components/vfs/index.js +5 -0
  255. package/dist/crdt/awareness.d.ts +42 -0
  256. package/dist/crdt/awareness.js +109 -0
  257. package/dist/crdt/document.d.ts +101 -0
  258. package/dist/crdt/document.js +187 -0
  259. package/dist/crdt/index.d.ts +9 -0
  260. package/dist/crdt/index.js +8 -0
  261. package/dist/crdt/provider.d.ts +85 -0
  262. package/dist/crdt/provider.js +150 -0
  263. package/dist/crdt/types.d.ts +61 -0
  264. package/dist/crdt/types.js +4 -0
  265. package/dist/crdt/undo.d.ts +34 -0
  266. package/dist/crdt/undo.js +70 -0
  267. package/dist/index.d.ts +277 -0
  268. package/dist/index.js +280 -0
  269. package/dist/plugins/index.d.ts +103 -0
  270. package/dist/plugins/index.js +153 -0
  271. package/dist/services/error-handling.d.ts +95 -0
  272. package/dist/services/error-handling.js +413 -0
  273. package/dist/services/ide-integration.d.ts +83 -0
  274. package/dist/services/ide-integration.js +367 -0
  275. package/dist/services/lsp-client.d.ts +69 -0
  276. package/dist/services/lsp-client.js +667 -0
  277. package/dist/services/mock-ai.d.ts +37 -0
  278. package/dist/services/mock-ai.js +318 -0
  279. package/dist/services/optimistic.d.ts +141 -0
  280. package/dist/services/optimistic.js +367 -0
  281. package/dist/services/vfs-client.d.ts +81 -0
  282. package/dist/services/vfs-client.js +348 -0
  283. package/dist/stores/agents.svelte.d.ts +85 -0
  284. package/dist/stores/agents.svelte.js +459 -0
  285. package/dist/stores/ai-persistence.svelte.d.ts +76 -0
  286. package/dist/stores/ai-persistence.svelte.js +334 -0
  287. package/dist/stores/ai.svelte.d.ts +140 -0
  288. package/dist/stores/ai.svelte.js +383 -0
  289. package/dist/stores/collaboration.svelte.d.ts +164 -0
  290. package/dist/stores/collaboration.svelte.js +334 -0
  291. package/dist/stores/editor.svelte.d.ts +131 -0
  292. package/dist/stores/editor.svelte.js +250 -0
  293. package/dist/stores/index.d.ts +10 -0
  294. package/dist/stores/index.js +29 -0
  295. package/dist/stores/layout.svelte.d.ts +171 -0
  296. package/dist/stores/layout.svelte.js +351 -0
  297. package/dist/stores/plugin.svelte.d.ts +121 -0
  298. package/dist/stores/plugin.svelte.js +410 -0
  299. package/dist/stores/vfs.svelte.d.ts +123 -0
  300. package/dist/stores/vfs.svelte.js +680 -0
  301. package/dist/styles/theme.css +623 -0
  302. package/dist/types/agents.d.ts +127 -0
  303. package/dist/types/agents.js +5 -0
  304. package/dist/types/ai.d.ts +137 -0
  305. package/dist/types/ai.js +4 -0
  306. package/dist/types/crdt.d.ts +222 -0
  307. package/dist/types/crdt.js +5 -0
  308. package/dist/types/editor.d.ts +52 -0
  309. package/dist/types/editor.js +18 -0
  310. package/dist/types/events.d.ts +133 -0
  311. package/dist/types/events.js +4 -0
  312. package/dist/types/filesystem.d.ts +77 -0
  313. package/dist/types/filesystem.js +4 -0
  314. package/dist/types/index.d.ts +9 -0
  315. package/dist/types/index.js +12 -0
  316. package/dist/types/lsp.d.ts +691 -0
  317. package/dist/types/lsp.js +108 -0
  318. package/dist/types/plugin.d.ts +239 -0
  319. package/dist/types/plugin.js +5 -0
  320. package/dist/types/vfs.d.ts +191 -0
  321. package/dist/types/vfs.js +18 -0
  322. package/dist/utils/format.d.ts +55 -0
  323. package/dist/utils/format.js +152 -0
  324. package/dist/utils/index.d.ts +3 -0
  325. package/dist/utils/index.js +4 -0
  326. package/dist/utils/keybindings.d.ts +33 -0
  327. package/dist/utils/keybindings.js +171 -0
  328. package/dist/utils/language.d.ts +27 -0
  329. package/dist/utils/language.js +222 -0
  330. package/package.json +178 -0
@@ -0,0 +1,667 @@
1
+ /**
2
+ * LSP WebSocket Client
3
+ * Communicates with a language server via WebSocket + JSON-RPC
4
+ */
5
+ // ============================================================================
6
+ // Default Client Capabilities
7
+ // ============================================================================
8
+ const DEFAULT_CLIENT_CAPABILITIES = {
9
+ workspace: {
10
+ applyEdit: true,
11
+ workspaceEdit: { documentChanges: true },
12
+ didChangeConfiguration: { dynamicRegistration: true },
13
+ didChangeWatchedFiles: { dynamicRegistration: true },
14
+ symbol: { dynamicRegistration: true },
15
+ executeCommand: { dynamicRegistration: true },
16
+ workspaceFolders: true,
17
+ configuration: true
18
+ },
19
+ textDocument: {
20
+ synchronization: {
21
+ dynamicRegistration: true,
22
+ willSave: true,
23
+ willSaveWaitUntil: true,
24
+ didSave: true
25
+ },
26
+ completion: {
27
+ dynamicRegistration: true,
28
+ completionItem: {
29
+ snippetSupport: true,
30
+ commitCharactersSupport: true,
31
+ documentationFormat: ['markdown', 'plaintext'],
32
+ deprecatedSupport: true,
33
+ preselectSupport: true,
34
+ insertReplaceSupport: true,
35
+ labelDetailsSupport: true
36
+ },
37
+ contextSupport: true
38
+ },
39
+ hover: {
40
+ dynamicRegistration: true,
41
+ contentFormat: ['markdown', 'plaintext']
42
+ },
43
+ signatureHelp: {
44
+ dynamicRegistration: true,
45
+ signatureInformation: {
46
+ documentationFormat: ['markdown', 'plaintext'],
47
+ parameterInformation: { labelOffsetSupport: true }
48
+ },
49
+ contextSupport: true
50
+ },
51
+ definition: { dynamicRegistration: true, linkSupport: true },
52
+ typeDefinition: { dynamicRegistration: true, linkSupport: true },
53
+ implementation: { dynamicRegistration: true, linkSupport: true },
54
+ references: { dynamicRegistration: true },
55
+ documentHighlight: { dynamicRegistration: true },
56
+ documentSymbol: { dynamicRegistration: true },
57
+ codeAction: {
58
+ dynamicRegistration: true,
59
+ codeActionLiteralSupport: {
60
+ codeActionKind: {
61
+ valueSet: [
62
+ 'quickfix',
63
+ 'refactor',
64
+ 'refactor.extract',
65
+ 'refactor.inline',
66
+ 'refactor.rewrite',
67
+ 'source',
68
+ 'source.organizeImports',
69
+ 'source.fixAll'
70
+ ]
71
+ }
72
+ },
73
+ isPreferredSupport: true,
74
+ disabledSupport: true,
75
+ dataSupport: true,
76
+ resolveSupport: { properties: ['edit'] }
77
+ },
78
+ codeLens: { dynamicRegistration: true },
79
+ formatting: { dynamicRegistration: true },
80
+ rangeFormatting: { dynamicRegistration: true },
81
+ onTypeFormatting: { dynamicRegistration: true },
82
+ rename: { dynamicRegistration: true, prepareSupport: true },
83
+ publishDiagnostics: {
84
+ relatedInformation: true,
85
+ tagSupport: { valueSet: [1, 2] },
86
+ versionSupport: true,
87
+ codeDescriptionSupport: true,
88
+ dataSupport: true
89
+ }
90
+ },
91
+ window: {
92
+ workDoneProgress: true,
93
+ showMessage: { messageActionItem: { additionalPropertiesSupport: true } },
94
+ showDocument: { support: true }
95
+ }
96
+ };
97
+ // ============================================================================
98
+ // LSP Client Class
99
+ // ============================================================================
100
+ export class LSPClient {
101
+ config;
102
+ ws = null;
103
+ requestId = 0;
104
+ pendingRequests = new Map();
105
+ // Each method may have multiple subscribers; store a Set so subscribing does
106
+ // not clobber an existing handler and unsubscribing removes only its own.
107
+ notificationHandlers = new Map();
108
+ _state = 'disconnected';
109
+ _capabilities = null;
110
+ reconnectAttempts = 0;
111
+ reconnectTimeout = null;
112
+ // Document tracking
113
+ openDocuments = new Map();
114
+ diagnosticsCache = new Map();
115
+ // Event handlers. Each event may have multiple subscribers; store a Set per
116
+ // event so on() does not overwrite a prior handler and the returned
117
+ // unsubscribe removes only the specific callback it registered.
118
+ eventHandlers = {};
119
+ constructor(config) {
120
+ this.config = config;
121
+ // Set defaults
122
+ this.config = {
123
+ autoReconnect: true,
124
+ reconnectDelay: 1000,
125
+ maxReconnectAttempts: 5,
126
+ requestTimeout: 30000,
127
+ debug: false,
128
+ ...config
129
+ };
130
+ // Register built-in notification handlers
131
+ this.onNotification('textDocument/publishDiagnostics', (params) => {
132
+ const diagnosticsParams = params;
133
+ this.diagnosticsCache.set(diagnosticsParams.uri, diagnosticsParams.diagnostics);
134
+ this.emitEvent('onDiagnostics', diagnosticsParams);
135
+ });
136
+ }
137
+ // ============================================================================
138
+ // Connection Management
139
+ // ============================================================================
140
+ get state() {
141
+ return this._state;
142
+ }
143
+ get capabilities() {
144
+ return this._capabilities;
145
+ }
146
+ get isReady() {
147
+ return this._state === 'ready';
148
+ }
149
+ /**
150
+ * Dispatch an event to every subscriber registered via on(). Iterates a copy
151
+ * so a handler that unsubscribes during dispatch cannot corrupt iteration,
152
+ * and isolates handler errors so one failure does not block the others.
153
+ */
154
+ emitEvent(event, ...args) {
155
+ const handlers = this.eventHandlers[event];
156
+ if (!handlers)
157
+ return;
158
+ for (const handler of [...handlers]) {
159
+ try {
160
+ handler(...args);
161
+ }
162
+ catch (err) {
163
+ if (this.config.debug) {
164
+ console.error(`[LSP] Event handler for "${String(event)}" threw:`, err);
165
+ }
166
+ }
167
+ }
168
+ }
169
+ setState(state) {
170
+ this._state = state;
171
+ this.emitEvent('onConnectionStateChange', state);
172
+ if (this.config.debug) {
173
+ console.log(`[LSP] State changed to: ${state}`);
174
+ }
175
+ }
176
+ async connect() {
177
+ if (this._state !== 'disconnected' && this._state !== 'error') {
178
+ return;
179
+ }
180
+ this.setState('connecting');
181
+ return new Promise((resolve, reject) => {
182
+ try {
183
+ this.ws = new WebSocket(this.config.serverUrl);
184
+ this.ws.onopen = async () => {
185
+ this.reconnectAttempts = 0;
186
+ this.setState('connected');
187
+ try {
188
+ await this.initialize();
189
+ resolve();
190
+ }
191
+ catch (err) {
192
+ reject(err);
193
+ }
194
+ };
195
+ this.ws.onclose = () => {
196
+ this.handleDisconnect();
197
+ };
198
+ this.ws.onerror = (event) => {
199
+ const error = new Error('WebSocket error');
200
+ this.emitEvent('onError', error);
201
+ if (this._state === 'connecting') {
202
+ reject(error);
203
+ }
204
+ };
205
+ this.ws.onmessage = (event) => {
206
+ this.handleMessage(event.data);
207
+ };
208
+ }
209
+ catch (err) {
210
+ this.setState('error');
211
+ reject(err);
212
+ }
213
+ });
214
+ }
215
+ handleDisconnect() {
216
+ this.setState('disconnected');
217
+ // Cancel pending requests
218
+ for (const [id, pending] of this.pendingRequests) {
219
+ clearTimeout(pending.timeout);
220
+ pending.reject(new Error('Connection closed'));
221
+ }
222
+ this.pendingRequests.clear();
223
+ // Auto-reconnect
224
+ if (this.config.autoReconnect &&
225
+ this.reconnectAttempts < (this.config.maxReconnectAttempts ?? 5)) {
226
+ this.reconnectAttempts++;
227
+ const delay = (this.config.reconnectDelay ?? 1000) * this.reconnectAttempts;
228
+ if (this.config.debug) {
229
+ console.log(`[LSP] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
230
+ }
231
+ this.reconnectTimeout = setTimeout(() => {
232
+ this.connect().catch((err) => {
233
+ this.emitEvent('onError', err);
234
+ });
235
+ }, delay);
236
+ }
237
+ }
238
+ async disconnect() {
239
+ if (this.reconnectTimeout) {
240
+ clearTimeout(this.reconnectTimeout);
241
+ this.reconnectTimeout = null;
242
+ }
243
+ if (this.ws) {
244
+ // Send shutdown request
245
+ if (this._state === 'ready') {
246
+ try {
247
+ await this.sendRequest('shutdown', null);
248
+ this.sendNotification('exit', null);
249
+ }
250
+ catch {
251
+ // Ignore errors during shutdown
252
+ }
253
+ }
254
+ this.ws.close();
255
+ this.ws = null;
256
+ }
257
+ this.setState('disconnected');
258
+ }
259
+ // ============================================================================
260
+ // Initialize
261
+ // ============================================================================
262
+ async initialize() {
263
+ this.setState('initializing');
264
+ const params = {
265
+ processId: null,
266
+ rootUri: this.config.rootUri,
267
+ capabilities: DEFAULT_CLIENT_CAPABILITIES,
268
+ workspaceFolders: [
269
+ {
270
+ uri: this.config.rootUri,
271
+ name: this.config.rootUri.split('/').pop() ?? 'workspace'
272
+ }
273
+ ]
274
+ };
275
+ const result = (await this.sendRequest('initialize', params));
276
+ this._capabilities = result.capabilities;
277
+ this.emitEvent('onServerCapabilities', result.capabilities);
278
+ // Send initialized notification
279
+ this.sendNotification('initialized', {});
280
+ this.setState('ready');
281
+ if (this.config.debug) {
282
+ console.log('[LSP] Initialized with capabilities:', result.capabilities);
283
+ }
284
+ }
285
+ // ============================================================================
286
+ // JSON-RPC Transport
287
+ // ============================================================================
288
+ handleMessage(data) {
289
+ try {
290
+ const message = JSON.parse(data);
291
+ if (this.config.debug) {
292
+ console.log('[LSP] Received:', message);
293
+ }
294
+ if ('id' in message && message.id !== null) {
295
+ // Response to a request
296
+ const pending = this.pendingRequests.get(message.id);
297
+ if (pending) {
298
+ clearTimeout(pending.timeout);
299
+ this.pendingRequests.delete(message.id);
300
+ if ('error' in message) {
301
+ pending.reject(new Error(message.error.message));
302
+ }
303
+ else {
304
+ pending.resolve(message.result);
305
+ }
306
+ }
307
+ }
308
+ else if ('method' in message) {
309
+ // Server notification or request — dispatch to every subscriber.
310
+ const handlers = this.notificationHandlers.get(message.method);
311
+ if (handlers && handlers.size > 0) {
312
+ // Iterate a copy so a handler can unsubscribe during dispatch.
313
+ for (const handler of [...handlers]) {
314
+ try {
315
+ handler(message.params);
316
+ }
317
+ catch (err) {
318
+ if (this.config.debug) {
319
+ console.error(`[LSP] Notification handler for "${message.method}" threw:`, err);
320
+ }
321
+ }
322
+ }
323
+ }
324
+ else if (this.config.debug) {
325
+ console.log(`[LSP] Unhandled notification: ${message.method}`);
326
+ }
327
+ }
328
+ }
329
+ catch (err) {
330
+ if (this.config.debug) {
331
+ console.error('[LSP] Failed to parse message:', err);
332
+ }
333
+ }
334
+ }
335
+ async sendRequest(method, params) {
336
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
337
+ throw new Error('Not connected to LSP server');
338
+ }
339
+ const id = ++this.requestId;
340
+ return new Promise((resolve, reject) => {
341
+ const timeout = setTimeout(() => {
342
+ this.pendingRequests.delete(id);
343
+ reject(new Error(`Request ${method} timed out`));
344
+ }, this.config.requestTimeout ?? 30000);
345
+ this.pendingRequests.set(id, {
346
+ resolve: resolve,
347
+ reject,
348
+ timeout
349
+ });
350
+ const request = {
351
+ jsonrpc: '2.0',
352
+ id,
353
+ method,
354
+ params
355
+ };
356
+ if (this.config.debug) {
357
+ console.log('[LSP] Sending:', request);
358
+ }
359
+ this.ws.send(JSON.stringify(request));
360
+ });
361
+ }
362
+ sendNotification(method, params) {
363
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
364
+ return;
365
+ }
366
+ const notification = {
367
+ jsonrpc: '2.0',
368
+ method,
369
+ params
370
+ };
371
+ if (this.config.debug) {
372
+ console.log('[LSP] Sending notification:', notification);
373
+ }
374
+ this.ws.send(JSON.stringify(notification));
375
+ }
376
+ onNotification(method, handler) {
377
+ let handlers = this.notificationHandlers.get(method);
378
+ if (!handlers) {
379
+ handlers = new Set();
380
+ this.notificationHandlers.set(method, handlers);
381
+ }
382
+ handlers.add(handler);
383
+ // Unsubscribe removes only this specific callback, leaving any other
384
+ // subscribers to the same method intact.
385
+ return () => {
386
+ const set = this.notificationHandlers.get(method);
387
+ if (!set)
388
+ return;
389
+ set.delete(handler);
390
+ if (set.size === 0) {
391
+ this.notificationHandlers.delete(method);
392
+ }
393
+ };
394
+ }
395
+ // ============================================================================
396
+ // Event Handlers
397
+ // ============================================================================
398
+ on(event, handler) {
399
+ let handlers = this.eventHandlers[event];
400
+ if (!handlers) {
401
+ handlers = new Set();
402
+ this.eventHandlers[event] = handlers;
403
+ }
404
+ handlers.add(handler);
405
+ // Unsubscribe removes only this specific callback, leaving any other
406
+ // subscribers to the same event intact.
407
+ return () => {
408
+ const set = this.eventHandlers[event];
409
+ if (!set)
410
+ return;
411
+ set.delete(handler);
412
+ if (set.size === 0) {
413
+ delete this.eventHandlers[event];
414
+ }
415
+ };
416
+ }
417
+ // ============================================================================
418
+ // Document Sync
419
+ // ============================================================================
420
+ didOpen(uri, languageId, version, text) {
421
+ this.openDocuments.set(uri, { version, languageId });
422
+ const params = {
423
+ uri,
424
+ languageId,
425
+ version,
426
+ text
427
+ };
428
+ this.sendNotification('textDocument/didOpen', { textDocument: params });
429
+ }
430
+ didChange(uri, version, changes) {
431
+ const doc = this.openDocuments.get(uri);
432
+ if (doc) {
433
+ doc.version = version;
434
+ }
435
+ this.sendNotification('textDocument/didChange', {
436
+ textDocument: { uri, version },
437
+ contentChanges: changes
438
+ });
439
+ }
440
+ didSave(uri, text) {
441
+ this.sendNotification('textDocument/didSave', {
442
+ textDocument: { uri },
443
+ text
444
+ });
445
+ }
446
+ didClose(uri) {
447
+ this.openDocuments.delete(uri);
448
+ this.diagnosticsCache.delete(uri);
449
+ this.sendNotification('textDocument/didClose', {
450
+ textDocument: { uri }
451
+ });
452
+ }
453
+ // ============================================================================
454
+ // Completion
455
+ // ============================================================================
456
+ async completion(uri, position, triggerKind = 1, triggerCharacter) {
457
+ if (!this._capabilities?.completionProvider) {
458
+ return [];
459
+ }
460
+ const params = {
461
+ textDocument: { uri },
462
+ position,
463
+ context: { triggerKind, triggerCharacter }
464
+ };
465
+ const result = await this.sendRequest('textDocument/completion', params);
466
+ if (!result)
467
+ return [];
468
+ if (Array.isArray(result))
469
+ return result;
470
+ return result.items;
471
+ }
472
+ async completionResolve(item) {
473
+ if (!this._capabilities?.completionProvider?.resolveProvider) {
474
+ return item;
475
+ }
476
+ return this.sendRequest('completionItem/resolve', item);
477
+ }
478
+ // ============================================================================
479
+ // Hover
480
+ // ============================================================================
481
+ async hover(uri, position) {
482
+ if (!this._capabilities?.hoverProvider) {
483
+ return null;
484
+ }
485
+ const params = {
486
+ textDocument: { uri },
487
+ position
488
+ };
489
+ return this.sendRequest('textDocument/hover', params);
490
+ }
491
+ // ============================================================================
492
+ // Signature Help
493
+ // ============================================================================
494
+ async signatureHelp(uri, position, triggerCharacter) {
495
+ if (!this._capabilities?.signatureHelpProvider) {
496
+ return null;
497
+ }
498
+ const params = {
499
+ textDocument: { uri },
500
+ position,
501
+ context: {
502
+ triggerKind: triggerCharacter ? 2 : 1,
503
+ triggerCharacter,
504
+ isRetrigger: false
505
+ }
506
+ };
507
+ return this.sendRequest('textDocument/signatureHelp', params);
508
+ }
509
+ // ============================================================================
510
+ // Go to Definition
511
+ // ============================================================================
512
+ async definition(uri, position) {
513
+ if (!this._capabilities?.definitionProvider) {
514
+ return [];
515
+ }
516
+ const params = {
517
+ textDocument: { uri },
518
+ position
519
+ };
520
+ const result = await this.sendRequest('textDocument/definition', params);
521
+ if (!result)
522
+ return [];
523
+ return Array.isArray(result) ? result : [result];
524
+ }
525
+ async typeDefinition(uri, position) {
526
+ if (!this._capabilities?.typeDefinitionProvider) {
527
+ return [];
528
+ }
529
+ const result = await this.sendRequest('textDocument/typeDefinition', { textDocument: { uri }, position });
530
+ if (!result)
531
+ return [];
532
+ return Array.isArray(result) ? result : [result];
533
+ }
534
+ // ============================================================================
535
+ // References
536
+ // ============================================================================
537
+ async references(uri, position, includeDeclaration = true) {
538
+ if (!this._capabilities?.referencesProvider) {
539
+ return [];
540
+ }
541
+ const params = {
542
+ textDocument: { uri },
543
+ position,
544
+ context: { includeDeclaration }
545
+ };
546
+ const result = await this.sendRequest('textDocument/references', params);
547
+ return result ?? [];
548
+ }
549
+ // ============================================================================
550
+ // Code Actions
551
+ // ============================================================================
552
+ async codeAction(uri, range, diagnostics = []) {
553
+ if (!this._capabilities?.codeActionProvider) {
554
+ return [];
555
+ }
556
+ const params = {
557
+ textDocument: { uri },
558
+ range,
559
+ context: { diagnostics }
560
+ };
561
+ const result = await this.sendRequest('textDocument/codeAction', params);
562
+ return result ?? [];
563
+ }
564
+ // ============================================================================
565
+ // Rename
566
+ // ============================================================================
567
+ async prepareRename(uri, position) {
568
+ const renameOptions = this._capabilities?.renameProvider;
569
+ if (!renameOptions || (typeof renameOptions === 'object' && !renameOptions.prepareProvider)) {
570
+ return null;
571
+ }
572
+ return this.sendRequest('textDocument/prepareRename', { textDocument: { uri }, position });
573
+ }
574
+ async rename(uri, position, newName) {
575
+ if (!this._capabilities?.renameProvider) {
576
+ return null;
577
+ }
578
+ const params = {
579
+ textDocument: { uri },
580
+ position,
581
+ newName
582
+ };
583
+ return this.sendRequest('textDocument/rename', params);
584
+ }
585
+ // ============================================================================
586
+ // Formatting
587
+ // ============================================================================
588
+ async formatting(uri, options) {
589
+ if (!this._capabilities?.documentFormattingProvider) {
590
+ return [];
591
+ }
592
+ const params = {
593
+ textDocument: { uri },
594
+ options: {
595
+ tabSize: options?.tabSize ?? 2,
596
+ insertSpaces: options?.insertSpaces ?? true,
597
+ trimTrailingWhitespace: options?.trimTrailingWhitespace,
598
+ insertFinalNewline: options?.insertFinalNewline,
599
+ trimFinalNewlines: options?.trimFinalNewlines
600
+ }
601
+ };
602
+ const result = await this.sendRequest('textDocument/formatting', params);
603
+ return result ?? [];
604
+ }
605
+ // ============================================================================
606
+ // Diagnostics
607
+ // ============================================================================
608
+ getDiagnostics(uri) {
609
+ return this.diagnosticsCache.get(uri) ?? [];
610
+ }
611
+ getAllDiagnostics() {
612
+ return new Map(this.diagnosticsCache);
613
+ }
614
+ // ============================================================================
615
+ // Utility Methods
616
+ // ============================================================================
617
+ getCompletionTriggerCharacters() {
618
+ return this._capabilities?.completionProvider?.triggerCharacters ?? [];
619
+ }
620
+ getSignatureHelpTriggerCharacters() {
621
+ return this._capabilities?.signatureHelpProvider?.triggerCharacters ?? [];
622
+ }
623
+ supportsFeature(feature) {
624
+ if (!this._capabilities)
625
+ return false;
626
+ return !!this._capabilities[feature];
627
+ }
628
+ }
629
+ // ============================================================================
630
+ // Factory Function
631
+ // ============================================================================
632
+ export function createLSPClient(config) {
633
+ return new LSPClient(config);
634
+ }
635
+ // ============================================================================
636
+ // Helper: Position Utilities
637
+ // ============================================================================
638
+ export function positionToOffset(content, position) {
639
+ const lines = content.split('\n');
640
+ let offset = 0;
641
+ for (let i = 0; i < position.line && i < lines.length; i++) {
642
+ offset += lines[i].length + 1; // +1 for newline
643
+ }
644
+ offset += Math.min(position.character, lines[position.line]?.length ?? 0);
645
+ return offset;
646
+ }
647
+ export function offsetToPosition(content, offset) {
648
+ const lines = content.split('\n');
649
+ let remaining = offset;
650
+ for (let line = 0; line < lines.length; line++) {
651
+ if (remaining <= lines[line].length) {
652
+ return { line, character: remaining };
653
+ }
654
+ remaining -= lines[line].length + 1;
655
+ }
656
+ // Past end of document
657
+ return {
658
+ line: lines.length - 1,
659
+ character: lines[lines.length - 1]?.length ?? 0
660
+ };
661
+ }
662
+ export function rangeToOffsets(content, range) {
663
+ return {
664
+ start: positionToOffset(content, range.start),
665
+ end: positionToOffset(content, range.end)
666
+ };
667
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Mock AI Service for Demos
3
+ * Simulates AI responses with streaming and tool calls
4
+ */
5
+ import type { AIMessage, AIToolCall } from '../types';
6
+ export interface MockAIConfig {
7
+ streamingDelay?: number;
8
+ responseDelay?: number;
9
+ simulateErrors?: boolean;
10
+ errorRate?: number;
11
+ }
12
+ /**
13
+ * Simulate streaming response
14
+ */
15
+ export declare function streamMockResponse(message: string, config?: MockAIConfig): AsyncGenerator<string, void, unknown>;
16
+ /**
17
+ * Get mock response (non-streaming)
18
+ */
19
+ export declare function getMockResponse(message: string, config?: MockAIConfig): Promise<{
20
+ content: string;
21
+ toolCalls?: AIToolCall[];
22
+ }>;
23
+ /**
24
+ * Execute mock tool call
25
+ */
26
+ export declare function executeMockToolCall(toolCall: AIToolCall, config?: MockAIConfig): Promise<{
27
+ result: unknown;
28
+ duration: number;
29
+ }>;
30
+ /**
31
+ * Create a mock AI message with metadata
32
+ */
33
+ export declare function createMockMessage(role: 'user' | 'assistant', content: string, options?: Partial<AIMessage>): AIMessage;
34
+ /**
35
+ * Generate a conversation with mock messages
36
+ */
37
+ export declare function generateMockConversation(turns?: number): AIMessage[];