@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,316 @@
1
+ /**
2
+ * Conflict Predictor
3
+ *
4
+ * Real-time conflict prediction for collaborative editing.
5
+ * Detects when multiple users are editing the same semantic region
6
+ * and predicts potential merge conflicts before they happen.
7
+ */
8
+ const DEFAULT_CONFIG = {
9
+ recentEditWindow: 30000,
10
+ proximityThreshold: 10,
11
+ warningThreshold: 0.3,
12
+ includeAI: true
13
+ };
14
+ /**
15
+ * Conflict Predictor class
16
+ */
17
+ export class ConflictPredictor {
18
+ config;
19
+ listeners = new Set();
20
+ lastZones = [];
21
+ constructor(config = {}) {
22
+ this.config = { ...DEFAULT_CONFIG, ...config };
23
+ }
24
+ /**
25
+ * Predict conflict zones based on user awareness and semantic regions
26
+ */
27
+ predict(users, semanticRegions) {
28
+ const zones = [];
29
+ const now = Date.now();
30
+ // Filter to active users (edited recently)
31
+ const activeUsers = users.filter((user) => {
32
+ if (!this.config.includeAI && user.isAI)
33
+ return false;
34
+ return now - user.lastEditTime < this.config.recentEditWindow;
35
+ });
36
+ // Need at least 2 active users for conflict
37
+ if (activeUsers.length < 2) {
38
+ this.lastZones = [];
39
+ this.notifyListeners([]);
40
+ return [];
41
+ }
42
+ // Check each semantic region for multiple users
43
+ for (const region of semanticRegions) {
44
+ const usersInRegion = activeUsers.filter((user) => user.cursorLine >= region.startLine &&
45
+ user.cursorLine <= region.endLine);
46
+ // Also check for users near the region
47
+ const usersNearRegion = activeUsers.filter((user) => {
48
+ const distanceToRegion = Math.min(Math.abs(user.cursorLine - region.startLine), Math.abs(user.cursorLine - region.endLine));
49
+ return (distanceToRegion <= this.config.proximityThreshold &&
50
+ !usersInRegion.includes(user));
51
+ });
52
+ const allRelevantUsers = [...usersInRegion, ...usersNearRegion];
53
+ if (allRelevantUsers.length >= 2) {
54
+ const probability = this.calculateProbability(allRelevantUsers, region, now);
55
+ if (probability >= this.config.warningThreshold) {
56
+ zones.push({
57
+ id: `conflict-${region.startLine}-${region.endLine}`,
58
+ startLine: region.startLine,
59
+ endLine: region.endLine,
60
+ probability,
61
+ severity: this.getSeverity(probability),
62
+ participants: allRelevantUsers.map((user) => ({
63
+ userId: user.id,
64
+ userName: user.name,
65
+ color: user.color,
66
+ cursorLine: user.cursorLine,
67
+ lastEditTime: user.lastEditTime,
68
+ isAI: user.isAI
69
+ })),
70
+ semanticUnit: region.label || `Lines ${region.startLine + 1}-${region.endLine + 1}`,
71
+ suggestion: this.getSuggestion(allRelevantUsers, probability)
72
+ });
73
+ }
74
+ }
75
+ }
76
+ // Also check for proximity-based conflicts outside semantic regions
77
+ const proximityZones = this.detectProximityConflicts(activeUsers, semanticRegions);
78
+ zones.push(...proximityZones);
79
+ // Merge overlapping zones
80
+ const mergedZones = this.mergeOverlappingZones(zones);
81
+ this.lastZones = mergedZones;
82
+ this.notifyListeners(mergedZones);
83
+ return mergedZones;
84
+ }
85
+ /**
86
+ * Get the last predicted zones
87
+ */
88
+ getLastZones() {
89
+ return this.lastZones;
90
+ }
91
+ /**
92
+ * Subscribe to conflict zone changes
93
+ */
94
+ subscribe(listener) {
95
+ this.listeners.add(listener);
96
+ return () => this.listeners.delete(listener);
97
+ }
98
+ /**
99
+ * Calculate conflict probability
100
+ */
101
+ calculateProbability(users, region, now) {
102
+ // Factors:
103
+ // 1. Number of users (more users = higher probability)
104
+ // 2. Cursor proximity (closer = higher probability)
105
+ // 3. Edit recency (more recent = higher probability)
106
+ // 4. Region size (smaller = higher probability due to less space)
107
+ const userCount = users.length;
108
+ const userCountFactor = Math.min(1, (userCount - 1) / 3); // 2 users = 0.33, 3 = 0.66, 4+ = 1
109
+ // Calculate average cursor proximity
110
+ const cursorLines = users.map((u) => u.cursorLine);
111
+ const avgProximity = this.calculateAverageProximity(cursorLines);
112
+ const proximityFactor = Math.max(0, 1 - avgProximity / this.config.proximityThreshold);
113
+ // Calculate edit recency factor
114
+ const recencyFactors = users.map((u) => {
115
+ const timeSinceEdit = now - u.lastEditTime;
116
+ return Math.max(0, 1 - timeSinceEdit / this.config.recentEditWindow);
117
+ });
118
+ const avgRecency = recencyFactors.reduce((a, b) => a + b, 0) / recencyFactors.length;
119
+ // Region size factor (smaller regions are more conflict-prone)
120
+ const regionSize = region.endLine - region.startLine + 1;
121
+ const sizeFactor = Math.min(1, 10 / regionSize);
122
+ // Weighted combination
123
+ const probability = userCountFactor * 0.3 + proximityFactor * 0.35 + avgRecency * 0.25 + sizeFactor * 0.1;
124
+ return Math.min(1, Math.max(0, probability));
125
+ }
126
+ /**
127
+ * Calculate average pairwise proximity between cursor positions
128
+ */
129
+ calculateAverageProximity(lines) {
130
+ if (lines.length < 2)
131
+ return Infinity;
132
+ let totalDistance = 0;
133
+ let pairs = 0;
134
+ for (let i = 0; i < lines.length; i++) {
135
+ for (let j = i + 1; j < lines.length; j++) {
136
+ totalDistance += Math.abs(lines[i] - lines[j]);
137
+ pairs++;
138
+ }
139
+ }
140
+ return pairs > 0 ? totalDistance / pairs : Infinity;
141
+ }
142
+ /**
143
+ * Get severity level from probability
144
+ */
145
+ getSeverity(probability) {
146
+ if (probability >= 0.8)
147
+ return 'critical';
148
+ if (probability >= 0.6)
149
+ return 'high';
150
+ if (probability >= 0.4)
151
+ return 'medium';
152
+ return 'low';
153
+ }
154
+ /**
155
+ * Get suggestion based on conflict state
156
+ */
157
+ getSuggestion(users, probability) {
158
+ const userNames = users.map((u) => u.name);
159
+ const aiUsers = users.filter((u) => u.isAI);
160
+ const humanUsers = users.filter((u) => !u.isAI);
161
+ if (probability >= 0.8) {
162
+ if (aiUsers.length > 0 && humanUsers.length > 0) {
163
+ return `AI is editing nearby. Consider pausing AI changes.`;
164
+ }
165
+ return `High conflict risk with ${userNames.join(', ')}. Consider coordinating.`;
166
+ }
167
+ if (probability >= 0.6) {
168
+ return `${userNames.join(' and ')} are editing nearby.`;
169
+ }
170
+ return `Multiple editors in this area.`;
171
+ }
172
+ /**
173
+ * Detect proximity-based conflicts outside semantic regions
174
+ */
175
+ detectProximityConflicts(users, semanticRegions) {
176
+ const zones = [];
177
+ // Group users by proximity
178
+ const visited = new Set();
179
+ for (let i = 0; i < users.length; i++) {
180
+ if (visited.has(users[i].id))
181
+ continue;
182
+ const cluster = [users[i]];
183
+ visited.add(users[i].id);
184
+ for (let j = i + 1; j < users.length; j++) {
185
+ if (visited.has(users[j].id))
186
+ continue;
187
+ const distance = Math.abs(users[i].cursorLine - users[j].cursorLine);
188
+ if (distance <= this.config.proximityThreshold) {
189
+ cluster.push(users[j]);
190
+ visited.add(users[j].id);
191
+ }
192
+ }
193
+ if (cluster.length >= 2) {
194
+ // Check if this cluster is already covered by a semantic region
195
+ const minLine = Math.min(...cluster.map((u) => u.cursorLine));
196
+ const maxLine = Math.max(...cluster.map((u) => u.cursorLine));
197
+ const isInSemanticRegion = semanticRegions.some((r) => minLine >= r.startLine && maxLine <= r.endLine);
198
+ if (!isInSemanticRegion) {
199
+ const probability = this.calculateProximityProbability(cluster);
200
+ if (probability >= this.config.warningThreshold) {
201
+ zones.push({
202
+ id: `proximity-${minLine}-${maxLine}`,
203
+ startLine: Math.max(0, minLine - 2),
204
+ endLine: maxLine + 2,
205
+ probability,
206
+ severity: this.getSeverity(probability),
207
+ participants: cluster.map((user) => ({
208
+ userId: user.id,
209
+ userName: user.name,
210
+ color: user.color,
211
+ cursorLine: user.cursorLine,
212
+ lastEditTime: user.lastEditTime,
213
+ isAI: user.isAI
214
+ })),
215
+ semanticUnit: `Lines ${minLine + 1}-${maxLine + 1}`,
216
+ suggestion: this.getSuggestion(cluster, probability)
217
+ });
218
+ }
219
+ }
220
+ }
221
+ }
222
+ return zones;
223
+ }
224
+ /**
225
+ * Calculate probability for proximity-based conflict
226
+ */
227
+ calculateProximityProbability(users) {
228
+ const now = Date.now();
229
+ // Simpler calculation for proximity conflicts
230
+ const cursorLines = users.map((u) => u.cursorLine);
231
+ const avgProximity = this.calculateAverageProximity(cursorLines);
232
+ const proximityFactor = Math.max(0, 1 - avgProximity / this.config.proximityThreshold);
233
+ const recencyFactors = users.map((u) => {
234
+ const timeSinceEdit = now - u.lastEditTime;
235
+ return Math.max(0, 1 - timeSinceEdit / this.config.recentEditWindow);
236
+ });
237
+ const avgRecency = recencyFactors.reduce((a, b) => a + b, 0) / recencyFactors.length;
238
+ return proximityFactor * 0.6 + avgRecency * 0.4;
239
+ }
240
+ /**
241
+ * Merge overlapping conflict zones
242
+ */
243
+ mergeOverlappingZones(zones) {
244
+ if (zones.length <= 1)
245
+ return zones;
246
+ // Sort by start line
247
+ const sorted = [...zones].sort((a, b) => a.startLine - b.startLine);
248
+ const merged = [];
249
+ let current = sorted[0];
250
+ for (let i = 1; i < sorted.length; i++) {
251
+ const next = sorted[i];
252
+ if (next.startLine <= current.endLine + 1) {
253
+ // Merge overlapping zones
254
+ current = {
255
+ ...current,
256
+ id: `${current.id}-${next.id}`,
257
+ endLine: Math.max(current.endLine, next.endLine),
258
+ probability: Math.max(current.probability, next.probability),
259
+ severity: this.getSeverity(Math.max(current.probability, next.probability)),
260
+ participants: this.mergeParticipants(current.participants, next.participants),
261
+ semanticUnit: current.semanticUnit
262
+ };
263
+ }
264
+ else {
265
+ merged.push(current);
266
+ current = next;
267
+ }
268
+ }
269
+ merged.push(current);
270
+ return merged;
271
+ }
272
+ /**
273
+ * Merge participant lists, removing duplicates
274
+ */
275
+ mergeParticipants(a, b) {
276
+ const seen = new Set();
277
+ const result = [];
278
+ for (const p of [...a, ...b]) {
279
+ if (!seen.has(p.userId)) {
280
+ seen.add(p.userId);
281
+ result.push(p);
282
+ }
283
+ }
284
+ return result;
285
+ }
286
+ /**
287
+ * Notify listeners of zone changes
288
+ */
289
+ notifyListeners(zones) {
290
+ for (const listener of this.listeners) {
291
+ try {
292
+ listener(zones);
293
+ }
294
+ catch (e) {
295
+ console.error('[ConflictPredictor] Listener error:', e);
296
+ }
297
+ }
298
+ }
299
+ }
300
+ /**
301
+ * Create a conflict predictor instance
302
+ */
303
+ export function createConflictPredictor(config) {
304
+ return new ConflictPredictor(config);
305
+ }
306
+ // Singleton instance
307
+ let globalPredictor = null;
308
+ /**
309
+ * Get the global conflict predictor
310
+ */
311
+ export function getConflictPredictor() {
312
+ if (!globalPredictor) {
313
+ globalPredictor = createConflictPredictor();
314
+ }
315
+ return globalPredictor;
316
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * CRDT binding for the custom editor
3
+ *
4
+ * This module provides integration between the custom editor state
5
+ * and Yjs CRDT for real-time collaborative editing.
6
+ */
7
+ import * as Y from 'yjs';
8
+ import type { EditorState, Position } from './state';
9
+ /**
10
+ * CRDT binding configuration
11
+ */
12
+ export interface CRDTBindingConfig {
13
+ /** Yjs document */
14
+ doc: Y.Doc;
15
+ /** Text type name in the document */
16
+ textName?: string;
17
+ /** Editor state to bind */
18
+ editorState: EditorState;
19
+ }
20
+ /**
21
+ * Position in both local and CRDT coordinates
22
+ */
23
+ export interface CRDTPosition {
24
+ /** Local position (line/column) */
25
+ local: Position;
26
+ /** CRDT index position */
27
+ index: number;
28
+ }
29
+ /**
30
+ * CRDT binding class that syncs editor state with Yjs
31
+ */
32
+ export declare class CRDTBinding {
33
+ private doc;
34
+ private text;
35
+ private editorState;
36
+ private isUpdating;
37
+ private isDestroyed;
38
+ private cleanupFns;
39
+ private textObserver;
40
+ constructor(config: CRDTBindingConfig);
41
+ /**
42
+ * Set up bidirectional bindings
43
+ */
44
+ private setupBindings;
45
+ /**
46
+ * Sync content from CRDT to editor
47
+ */
48
+ private syncFromCRDT;
49
+ /**
50
+ * Handle changes from CRDT
51
+ * Uses Yjs relative positions for accurate cursor preservation during concurrent edits
52
+ */
53
+ private handleCRDTChange;
54
+ /**
55
+ * Convert position to index using provided lines (for atomic operations)
56
+ */
57
+ private positionToIndexWithLines;
58
+ /**
59
+ * Handle local editor changes
60
+ */
61
+ private handleLocalChange;
62
+ /**
63
+ * Convert editor position to CRDT index
64
+ */
65
+ positionToIndex(position: Position): number;
66
+ /**
67
+ * Convert CRDT index to editor position
68
+ */
69
+ indexToPosition(index: number): Position;
70
+ /**
71
+ * Apply a full local content replacement into the bound editor state,
72
+ * which propagates to the CRDT / Yjs text via the local-change listener.
73
+ *
74
+ * Use this for edits that originate outside the bound EditorState (e.g. an
75
+ * inner editor component that maintains its own state) so that local typing
76
+ * reaches collaborators. No-op while a remote update is being applied, which
77
+ * also prevents a remote -> local -> remote echo loop.
78
+ *
79
+ * @returns `true` if the content changed and was propagated, `false` otherwise.
80
+ */
81
+ setContent(content: string): boolean;
82
+ /**
83
+ * Whether a remote (CRDT-originated) update is currently being applied.
84
+ * Callers can use this to suppress re-sending an echoed local change.
85
+ */
86
+ get isApplyingRemoteChange(): boolean;
87
+ /**
88
+ * Get the Yjs text type
89
+ */
90
+ getText(): Y.Text;
91
+ /**
92
+ * Get the Yjs document
93
+ */
94
+ getDoc(): Y.Doc;
95
+ /**
96
+ * Clean up bindings
97
+ */
98
+ destroy(): void;
99
+ }
100
+ /**
101
+ * Create a CRDT binding
102
+ */
103
+ export declare function createCRDTBinding(config: CRDTBindingConfig): CRDTBinding;
104
+ /**
105
+ * Relative position for cursor synchronization
106
+ */
107
+ export interface RelativePosition {
108
+ /** Yjs relative position */
109
+ yRelPos: Y.RelativePosition;
110
+ }
111
+ /**
112
+ * Create a relative position from an editor position
113
+ */
114
+ export declare function createRelativePosition(text: Y.Text, binding: CRDTBinding, position: Position): RelativePosition;
115
+ /**
116
+ * Resolve a relative position to an editor position
117
+ */
118
+ export declare function resolveRelativePosition(doc: Y.Doc, binding: CRDTBinding, relPos: RelativePosition): Position | null;