@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.
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/components/agents/AgentActivityPanel.svelte +565 -0
- package/dist/components/agents/AgentActivityPanel.svelte.d.ts +24 -0
- package/dist/components/agents/AgentAvatar.svelte +417 -0
- package/dist/components/agents/AgentAvatar.svelte.d.ts +23 -0
- package/dist/components/agents/AgentCursor.svelte +224 -0
- package/dist/components/agents/AgentCursor.svelte.d.ts +35 -0
- package/dist/components/agents/AgentPresenceBar.svelte +261 -0
- package/dist/components/agents/AgentPresenceBar.svelte.d.ts +20 -0
- package/dist/components/agents/index.d.ts +4 -0
- package/dist/components/agents/index.js +5 -0
- package/dist/components/ai/AIConversationList.svelte +524 -0
- package/dist/components/ai/AIConversationList.svelte.d.ts +17 -0
- package/dist/components/ai/AIEditPreview.svelte +132 -0
- package/dist/components/ai/AIEditPreview.svelte.d.ts +8 -0
- package/dist/components/ai/AIInlineEdit.svelte +155 -0
- package/dist/components/ai/AIInlineEdit.svelte.d.ts +10 -0
- package/dist/components/ai/AIMessage.svelte +239 -0
- package/dist/components/ai/AIMessage.svelte.d.ts +13 -0
- package/dist/components/ai/AIMessageActions.svelte +176 -0
- package/dist/components/ai/AIMessageActions.svelte.d.ts +12 -0
- package/dist/components/ai/AIMessageContent.svelte +355 -0
- package/dist/components/ai/AIMessageContent.svelte.d.ts +7 -0
- package/dist/components/ai/AIPanel.svelte +561 -0
- package/dist/components/ai/AIPanel.svelte.d.ts +7 -0
- package/dist/components/ai/AISuggestionWidget.svelte +132 -0
- package/dist/components/ai/AISuggestionWidget.svelte.d.ts +10 -0
- package/dist/components/ai/AIToolCallDisplay.svelte +317 -0
- package/dist/components/ai/AIToolCallDisplay.svelte.d.ts +12 -0
- package/dist/components/ai/index.d.ts +9 -0
- package/dist/components/ai/index.js +10 -0
- package/dist/components/core/Avatar.svelte +110 -0
- package/dist/components/core/Avatar.svelte.d.ts +12 -0
- package/dist/components/core/Badge.svelte +98 -0
- package/dist/components/core/Badge.svelte.d.ts +11 -0
- package/dist/components/core/Button.svelte +175 -0
- package/dist/components/core/Button.svelte.d.ts +18 -0
- package/dist/components/core/ConnectionStatus.svelte +294 -0
- package/dist/components/core/ConnectionStatus.svelte.d.ts +20 -0
- package/dist/components/core/ContextMenu.svelte +176 -0
- package/dist/components/core/ContextMenu.svelte.d.ts +19 -0
- package/dist/components/core/ErrorBoundary.svelte +277 -0
- package/dist/components/core/ErrorBoundary.svelte.d.ts +23 -0
- package/dist/components/core/Icon.svelte +107 -0
- package/dist/components/core/Icon.svelte.d.ts +8 -0
- package/dist/components/core/Input.svelte +138 -0
- package/dist/components/core/Input.svelte.d.ts +20 -0
- package/dist/components/core/Kbd.svelte +34 -0
- package/dist/components/core/Kbd.svelte.d.ts +7 -0
- package/dist/components/core/ResizeHandle.svelte +200 -0
- package/dist/components/core/ResizeHandle.svelte.d.ts +23 -0
- package/dist/components/core/Spinner.svelte +35 -0
- package/dist/components/core/Spinner.svelte.d.ts +7 -0
- package/dist/components/core/Textarea.svelte +112 -0
- package/dist/components/core/Textarea.svelte.d.ts +18 -0
- package/dist/components/core/Tooltip.svelte +103 -0
- package/dist/components/core/Tooltip.svelte.d.ts +11 -0
- package/dist/components/core/index.d.ts +13 -0
- package/dist/components/core/index.js +14 -0
- package/dist/components/editor/AIFocusLayer.svelte +430 -0
- package/dist/components/editor/AIFocusLayer.svelte.d.ts +32 -0
- package/dist/components/editor/Breadcrumbs.svelte +435 -0
- package/dist/components/editor/Breadcrumbs.svelte.d.ts +33 -0
- package/dist/components/editor/BreakpointLayer.svelte +642 -0
- package/dist/components/editor/BreakpointLayer.svelte.d.ts +20 -0
- package/dist/components/editor/CognitiveLoadMeter.svelte +324 -0
- package/dist/components/editor/CognitiveLoadMeter.svelte.d.ts +18 -0
- package/dist/components/editor/CollaborativeEditor.svelte +218 -0
- package/dist/components/editor/CollaborativeEditor.svelte.d.ts +32 -0
- package/dist/components/editor/CommandPalette.svelte +434 -0
- package/dist/components/editor/CommandPalette.svelte.d.ts +11 -0
- package/dist/components/editor/ComplexityLayer.svelte +293 -0
- package/dist/components/editor/ComplexityLayer.svelte.d.ts +23 -0
- package/dist/components/editor/ConflictZoneLayer.svelte +441 -0
- package/dist/components/editor/ConflictZoneLayer.svelte.d.ts +25 -0
- package/dist/components/editor/ContextLens.svelte +262 -0
- package/dist/components/editor/ContextLens.svelte.d.ts +27 -0
- package/dist/components/editor/CustomEditor.svelte +1242 -0
- package/dist/components/editor/CustomEditor.svelte.d.ts +37 -0
- package/dist/components/editor/DebugConsole.svelte +646 -0
- package/dist/components/editor/DebugConsole.svelte.d.ts +41 -0
- package/dist/components/editor/EchoCursorLayer.svelte +363 -0
- package/dist/components/editor/EchoCursorLayer.svelte.d.ts +24 -0
- package/dist/components/editor/Editor.svelte +61 -0
- package/dist/components/editor/Editor.svelte.d.ts +22 -0
- package/dist/components/editor/EditorGutter.svelte +119 -0
- package/dist/components/editor/EditorGutter.svelte.d.ts +19 -0
- package/dist/components/editor/EditorLines.svelte +182 -0
- package/dist/components/editor/EditorLines.svelte.d.ts +43 -0
- package/dist/components/editor/EditorPane.svelte +134 -0
- package/dist/components/editor/EditorPane.svelte.d.ts +9 -0
- package/dist/components/editor/EditorSelections.svelte +186 -0
- package/dist/components/editor/EditorSelections.svelte.d.ts +25 -0
- package/dist/components/editor/EditorTabs.svelte +170 -0
- package/dist/components/editor/EditorTabs.svelte.d.ts +12 -0
- package/dist/components/editor/FileExplorer.svelte +811 -0
- package/dist/components/editor/FileExplorer.svelte.d.ts +67 -0
- package/dist/components/editor/FileIcon.svelte +110 -0
- package/dist/components/editor/FileIcon.svelte.d.ts +10 -0
- package/dist/components/editor/FindReplace.svelte +448 -0
- package/dist/components/editor/FindReplace.svelte.d.ts +40 -0
- package/dist/components/editor/GhostBracketLayer.svelte +391 -0
- package/dist/components/editor/GhostBracketLayer.svelte.d.ts +24 -0
- package/dist/components/editor/GitBlameLayer.svelte +436 -0
- package/dist/components/editor/GitBlameLayer.svelte.d.ts +18 -0
- package/dist/components/editor/InlineDiagnosticsLayer.svelte +540 -0
- package/dist/components/editor/InlineDiagnosticsLayer.svelte.d.ts +35 -0
- package/dist/components/editor/InlineDiffLayer.svelte +337 -0
- package/dist/components/editor/InlineDiffLayer.svelte.d.ts +31 -0
- package/dist/components/editor/MinimalEditor.svelte +75 -0
- package/dist/components/editor/MinimalEditor.svelte.d.ts +6 -0
- package/dist/components/editor/MinimalEditor2.svelte +84 -0
- package/dist/components/editor/MinimalEditor2.svelte.d.ts +6 -0
- package/dist/components/editor/Minimap.svelte +327 -0
- package/dist/components/editor/Minimap.svelte.d.ts +34 -0
- package/dist/components/editor/PluginPreviewSandbox.svelte +793 -0
- package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +49 -0
- package/dist/components/editor/ProblemsPanel.svelte +628 -0
- package/dist/components/editor/ProblemsPanel.svelte.d.ts +25 -0
- package/dist/components/editor/QuickActionsMenu.svelte +403 -0
- package/dist/components/editor/QuickActionsMenu.svelte.d.ts +18 -0
- package/dist/components/editor/SnippetPalette.svelte +530 -0
- package/dist/components/editor/SnippetPalette.svelte.d.ts +16 -0
- package/dist/components/editor/StructureMap.svelte +431 -0
- package/dist/components/editor/StructureMap.svelte.d.ts +37 -0
- package/dist/components/editor/SymbolOutline.svelte +722 -0
- package/dist/components/editor/SymbolOutline.svelte.d.ts +44 -0
- package/dist/components/editor/TimelineScrubber.svelte +470 -0
- package/dist/components/editor/TimelineScrubber.svelte.d.ts +40 -0
- package/dist/components/editor/TokenRenderer.svelte +69 -0
- package/dist/components/editor/TokenRenderer.svelte.d.ts +15 -0
- package/dist/components/editor/constants.d.ts +32 -0
- package/dist/components/editor/constants.js +36 -0
- package/dist/components/editor/core/ai-awareness.d.ts +176 -0
- package/dist/components/editor/core/ai-awareness.js +210 -0
- package/dist/components/editor/core/bracket-healer.d.ts +189 -0
- package/dist/components/editor/core/bracket-healer.js +406 -0
- package/dist/components/editor/core/breakpoints.d.ts +203 -0
- package/dist/components/editor/core/breakpoints.js +414 -0
- package/dist/components/editor/core/commands.d.ts +108 -0
- package/dist/components/editor/core/commands.js +246 -0
- package/dist/components/editor/core/complexity-analyzer.d.ts +123 -0
- package/dist/components/editor/core/complexity-analyzer.js +376 -0
- package/dist/components/editor/core/conflict-predictor.d.ts +135 -0
- package/dist/components/editor/core/conflict-predictor.js +316 -0
- package/dist/components/editor/core/crdt-binding.d.ts +118 -0
- package/dist/components/editor/core/crdt-binding.js +286 -0
- package/dist/components/editor/core/diagnostics.d.ts +210 -0
- package/dist/components/editor/core/diagnostics.js +335 -0
- package/dist/components/editor/core/echo-cursor.d.ts +201 -0
- package/dist/components/editor/core/echo-cursor.js +267 -0
- package/dist/components/editor/core/folding.d.ts +124 -0
- package/dist/components/editor/core/folding.js +672 -0
- package/dist/components/editor/core/ghost-pair.d.ts +122 -0
- package/dist/components/editor/core/ghost-pair.js +221 -0
- package/dist/components/editor/core/git-blame.d.ts +170 -0
- package/dist/components/editor/core/git-blame.js +324 -0
- package/dist/components/editor/core/index.d.ts +26 -0
- package/dist/components/editor/core/index.js +24 -0
- package/dist/components/editor/core/keybindings.d.ts +79 -0
- package/dist/components/editor/core/keybindings.js +357 -0
- package/dist/components/editor/core/multi-cursor.d.ts +196 -0
- package/dist/components/editor/core/multi-cursor.js +521 -0
- package/dist/components/editor/core/navigation.d.ts +107 -0
- package/dist/components/editor/core/navigation.js +408 -0
- package/dist/components/editor/core/quick-actions.d.ts +189 -0
- package/dist/components/editor/core/quick-actions.js +427 -0
- package/dist/components/editor/core/search.d.ts +88 -0
- package/dist/components/editor/core/search.js +192 -0
- package/dist/components/editor/core/semantic-analyzer.d.ts +77 -0
- package/dist/components/editor/core/semantic-analyzer.js +424 -0
- package/dist/components/editor/core/snippet-manager.d.ts +202 -0
- package/dist/components/editor/core/snippet-manager.js +565 -0
- package/dist/components/editor/core/state.d.ts +367 -0
- package/dist/components/editor/core/state.js +900 -0
- package/dist/components/editor/core/timeline.d.ts +204 -0
- package/dist/components/editor/core/timeline.js +349 -0
- package/dist/components/editor/editor-find.d.ts +56 -0
- package/dist/components/editor/editor-find.js +148 -0
- package/dist/components/editor/editor-input.d.ts +77 -0
- package/dist/components/editor/editor-input.js +445 -0
- package/dist/components/editor/editor-multicursor.d.ts +21 -0
- package/dist/components/editor/editor-multicursor.js +196 -0
- package/dist/components/editor/editor-scroll.d.ts +14 -0
- package/dist/components/editor/editor-scroll.js +34 -0
- package/dist/components/editor/index.d.ts +15 -0
- package/dist/components/editor/index.js +21 -0
- package/dist/components/editor/languages.d.ts +62 -0
- package/dist/components/editor/languages.js +285 -0
- package/dist/components/editor/theme.d.ts +88 -0
- package/dist/components/editor/theme.js +139 -0
- package/dist/components/editor/tokenizer/base.d.ts +40 -0
- package/dist/components/editor/tokenizer/base.js +203 -0
- package/dist/components/editor/tokenizer/index.d.ts +56 -0
- package/dist/components/editor/tokenizer/index.js +215 -0
- package/dist/components/editor/tokenizer/languages/css.d.ts +17 -0
- package/dist/components/editor/tokenizer/languages/css.js +194 -0
- package/dist/components/editor/tokenizer/languages/go.d.ts +17 -0
- package/dist/components/editor/tokenizer/languages/go.js +220 -0
- package/dist/components/editor/tokenizer/languages/html.d.ts +24 -0
- package/dist/components/editor/tokenizer/languages/html.js +145 -0
- package/dist/components/editor/tokenizer/languages/javascript.d.ts +56 -0
- package/dist/components/editor/tokenizer/languages/javascript.js +452 -0
- package/dist/components/editor/tokenizer/languages/json.d.ts +12 -0
- package/dist/components/editor/tokenizer/languages/json.js +91 -0
- package/dist/components/editor/tokenizer/languages/markdown.d.ts +16 -0
- package/dist/components/editor/tokenizer/languages/markdown.js +156 -0
- package/dist/components/editor/tokenizer/languages/python.d.ts +20 -0
- package/dist/components/editor/tokenizer/languages/python.js +227 -0
- package/dist/components/editor/tokenizer/languages/svelte.d.ts +40 -0
- package/dist/components/editor/tokenizer/languages/svelte.js +326 -0
- package/dist/components/editor/tokenizer/types.d.ts +86 -0
- package/dist/components/editor/tokenizer/types.js +4 -0
- package/dist/components/layout/IDELayout.svelte +274 -0
- package/dist/components/layout/IDELayout.svelte.d.ts +29 -0
- package/dist/components/layout/StatusBar.svelte +511 -0
- package/dist/components/layout/StatusBar.svelte.d.ts +47 -0
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +3 -0
- package/dist/components/lsp/AutocompleteWidget.svelte +364 -0
- package/dist/components/lsp/AutocompleteWidget.svelte.d.ts +33 -0
- package/dist/components/lsp/DiagnosticMarker.svelte +166 -0
- package/dist/components/lsp/DiagnosticMarker.svelte.d.ts +19 -0
- package/dist/components/lsp/DiagnosticsPanel.svelte +388 -0
- package/dist/components/lsp/DiagnosticsPanel.svelte.d.ts +21 -0
- package/dist/components/lsp/HoverTooltip.svelte +274 -0
- package/dist/components/lsp/HoverTooltip.svelte.d.ts +24 -0
- package/dist/components/lsp/LSPEditor.svelte +486 -0
- package/dist/components/lsp/LSPEditor.svelte.d.ts +39 -0
- package/dist/components/lsp/SignatureHelpWidget.svelte +216 -0
- package/dist/components/lsp/SignatureHelpWidget.svelte.d.ts +22 -0
- package/dist/components/lsp/index.d.ts +6 -0
- package/dist/components/lsp/index.js +7 -0
- package/dist/components/plugins/PluginCard.svelte +153 -0
- package/dist/components/plugins/PluginCard.svelte.d.ts +19 -0
- package/dist/components/plugins/PluginPanel.svelte +280 -0
- package/dist/components/plugins/PluginPanel.svelte.d.ts +8 -0
- package/dist/components/plugins/PluginProposalForm.svelte +250 -0
- package/dist/components/plugins/PluginProposalForm.svelte.d.ts +6 -0
- package/dist/components/plugins/PluginStatusBadge.svelte +14 -0
- package/dist/components/plugins/PluginStatusBadge.svelte.d.ts +8 -0
- package/dist/components/plugins/index.d.ts +4 -0
- package/dist/components/plugins/index.js +5 -0
- package/dist/components/vfs/LockConflictDialog.svelte +705 -0
- package/dist/components/vfs/LockConflictDialog.svelte.d.ts +21 -0
- package/dist/components/vfs/LockIndicator.svelte +194 -0
- package/dist/components/vfs/LockIndicator.svelte.d.ts +29 -0
- package/dist/components/vfs/LockOverlay.svelte +344 -0
- package/dist/components/vfs/LockOverlay.svelte.d.ts +17 -0
- package/dist/components/vfs/VersionConflictDialog.svelte +549 -0
- package/dist/components/vfs/VersionConflictDialog.svelte.d.ts +24 -0
- package/dist/components/vfs/index.d.ts +4 -0
- package/dist/components/vfs/index.js +5 -0
- package/dist/crdt/awareness.d.ts +42 -0
- package/dist/crdt/awareness.js +109 -0
- package/dist/crdt/document.d.ts +101 -0
- package/dist/crdt/document.js +187 -0
- package/dist/crdt/index.d.ts +9 -0
- package/dist/crdt/index.js +8 -0
- package/dist/crdt/provider.d.ts +85 -0
- package/dist/crdt/provider.js +150 -0
- package/dist/crdt/types.d.ts +61 -0
- package/dist/crdt/types.js +4 -0
- package/dist/crdt/undo.d.ts +34 -0
- package/dist/crdt/undo.js +70 -0
- package/dist/index.d.ts +277 -0
- package/dist/index.js +280 -0
- package/dist/plugins/index.d.ts +103 -0
- package/dist/plugins/index.js +153 -0
- package/dist/services/error-handling.d.ts +95 -0
- package/dist/services/error-handling.js +413 -0
- package/dist/services/ide-integration.d.ts +83 -0
- package/dist/services/ide-integration.js +367 -0
- package/dist/services/lsp-client.d.ts +69 -0
- package/dist/services/lsp-client.js +667 -0
- package/dist/services/mock-ai.d.ts +37 -0
- package/dist/services/mock-ai.js +318 -0
- package/dist/services/optimistic.d.ts +141 -0
- package/dist/services/optimistic.js +367 -0
- package/dist/services/vfs-client.d.ts +81 -0
- package/dist/services/vfs-client.js +348 -0
- package/dist/stores/agents.svelte.d.ts +85 -0
- package/dist/stores/agents.svelte.js +459 -0
- package/dist/stores/ai-persistence.svelte.d.ts +76 -0
- package/dist/stores/ai-persistence.svelte.js +334 -0
- package/dist/stores/ai.svelte.d.ts +140 -0
- package/dist/stores/ai.svelte.js +383 -0
- package/dist/stores/collaboration.svelte.d.ts +164 -0
- package/dist/stores/collaboration.svelte.js +334 -0
- package/dist/stores/editor.svelte.d.ts +131 -0
- package/dist/stores/editor.svelte.js +250 -0
- package/dist/stores/index.d.ts +10 -0
- package/dist/stores/index.js +29 -0
- package/dist/stores/layout.svelte.d.ts +171 -0
- package/dist/stores/layout.svelte.js +351 -0
- package/dist/stores/plugin.svelte.d.ts +121 -0
- package/dist/stores/plugin.svelte.js +410 -0
- package/dist/stores/vfs.svelte.d.ts +123 -0
- package/dist/stores/vfs.svelte.js +680 -0
- package/dist/styles/theme.css +623 -0
- package/dist/types/agents.d.ts +127 -0
- package/dist/types/agents.js +5 -0
- package/dist/types/ai.d.ts +137 -0
- package/dist/types/ai.js +4 -0
- package/dist/types/crdt.d.ts +222 -0
- package/dist/types/crdt.js +5 -0
- package/dist/types/editor.d.ts +52 -0
- package/dist/types/editor.js +18 -0
- package/dist/types/events.d.ts +133 -0
- package/dist/types/events.js +4 -0
- package/dist/types/filesystem.d.ts +77 -0
- package/dist/types/filesystem.js +4 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +12 -0
- package/dist/types/lsp.d.ts +691 -0
- package/dist/types/lsp.js +108 -0
- package/dist/types/plugin.d.ts +239 -0
- package/dist/types/plugin.js +5 -0
- package/dist/types/vfs.d.ts +191 -0
- package/dist/types/vfs.js +18 -0
- package/dist/utils/format.d.ts +55 -0
- package/dist/utils/format.js +152 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/keybindings.d.ts +33 -0
- package/dist/utils/keybindings.js +171 -0
- package/dist/utils/language.d.ts +27 -0
- package/dist/utils/language.js +222 -0
- package/package.json +178 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cognitive Complexity Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes code complexity in real-time to help developers understand
|
|
5
|
+
* cognitive load and identify areas that may benefit from refactoring.
|
|
6
|
+
*
|
|
7
|
+
* Based on cognitive complexity research and common code quality metrics.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Thresholds for complexity levels
|
|
11
|
+
*/
|
|
12
|
+
const THRESHOLDS = {
|
|
13
|
+
low: 30,
|
|
14
|
+
medium: 50,
|
|
15
|
+
high: 70,
|
|
16
|
+
critical: 85,
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Weights for different complexity factors
|
|
20
|
+
*/
|
|
21
|
+
const WEIGHTS = {
|
|
22
|
+
nestingDepth: 15,
|
|
23
|
+
branchingFactor: 8,
|
|
24
|
+
lineCount: 0.3,
|
|
25
|
+
identifierCount: 0.2,
|
|
26
|
+
callCount: 0.5,
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Patterns for detecting code constructs
|
|
30
|
+
*/
|
|
31
|
+
const PATTERNS = {
|
|
32
|
+
// Nesting increasers
|
|
33
|
+
nestingStart: /\b(if|for|while|switch|try|catch|with)\s*\(|=>\s*\{|\bdo\s*\{/,
|
|
34
|
+
// Branching statements
|
|
35
|
+
branching: /\b(if|else\s+if|else|case|default|\?.*:)/g,
|
|
36
|
+
// Function definitions — exclude control flow keywords from method-style match
|
|
37
|
+
functionDef: /\b(function\s+(\w+)|(\w+)\s*=\s*(?:async\s*)?\(|(?!(?:if|else|for|while|do|switch|try|catch|finally|with|return|throw|new|typeof|void|delete|await|yield)\b)(\w+)\s*\([^)]*\)\s*\{|class\s+(\w+))/,
|
|
38
|
+
// Function calls
|
|
39
|
+
functionCall: /\b\w+\s*\(/g,
|
|
40
|
+
// Identifiers (simplified)
|
|
41
|
+
identifier: /\b[a-zA-Z_]\w*\b/g,
|
|
42
|
+
// Block openers
|
|
43
|
+
blockOpen: /\{/g,
|
|
44
|
+
// Block closers
|
|
45
|
+
blockClose: /\}/g,
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Complexity Analyzer class
|
|
49
|
+
*/
|
|
50
|
+
export class ComplexityAnalyzer {
|
|
51
|
+
cache = new Map();
|
|
52
|
+
cacheKey = '';
|
|
53
|
+
/**
|
|
54
|
+
* Analyze complexity of the given lines
|
|
55
|
+
*/
|
|
56
|
+
analyze(lines, language = 'javascript') {
|
|
57
|
+
// Simple cache check based on content hash
|
|
58
|
+
const key = this.computeCacheKey(lines);
|
|
59
|
+
if (key === this.cacheKey && this.cache.has(key)) {
|
|
60
|
+
return this.cache.get(key);
|
|
61
|
+
}
|
|
62
|
+
const regions = this.identifyRegions(lines, language);
|
|
63
|
+
const analyzedRegions = regions.map((region) => this.analyzeRegion(lines, region));
|
|
64
|
+
const hotspots = this.findHotspots(analyzedRegions);
|
|
65
|
+
const overall = this.calculateOverall(analyzedRegions, lines.length);
|
|
66
|
+
const metrics = {
|
|
67
|
+
overall,
|
|
68
|
+
level: this.getLevel(overall),
|
|
69
|
+
regions: analyzedRegions,
|
|
70
|
+
hotspots,
|
|
71
|
+
};
|
|
72
|
+
this.cacheKey = key;
|
|
73
|
+
this.cache.set(key, metrics);
|
|
74
|
+
return metrics;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get complexity for a specific line
|
|
78
|
+
*/
|
|
79
|
+
getLineComplexity(metrics, line) {
|
|
80
|
+
for (const region of metrics.regions) {
|
|
81
|
+
if (line >= region.startLine && line <= region.endLine) {
|
|
82
|
+
return region.score;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if a line is a hotspot
|
|
89
|
+
*/
|
|
90
|
+
isHotspot(metrics, line) {
|
|
91
|
+
return metrics.hotspots.includes(line);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Compute a cache key from all line content using a fast hash
|
|
95
|
+
*/
|
|
96
|
+
computeCacheKey(lines) {
|
|
97
|
+
// Use a simple DJB2 hash across all line content for reliable cache invalidation
|
|
98
|
+
let hash = 5381;
|
|
99
|
+
for (let i = 0; i < lines.length; i++) {
|
|
100
|
+
const text = lines[i].text;
|
|
101
|
+
for (let j = 0; j < text.length; j++) {
|
|
102
|
+
hash = ((hash << 5) + hash + text.charCodeAt(j)) | 0;
|
|
103
|
+
}
|
|
104
|
+
// Include newline separator in hash
|
|
105
|
+
hash = ((hash << 5) + hash + 10) | 0;
|
|
106
|
+
}
|
|
107
|
+
return `${lines.length}:${hash}`;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Identify code regions (functions, classes, blocks)
|
|
111
|
+
*
|
|
112
|
+
* Uses brace-depth tracking to correctly handle inline braces
|
|
113
|
+
* (object literals, destructuring) that don't represent new blocks.
|
|
114
|
+
*/
|
|
115
|
+
identifyRegions(lines, _language) {
|
|
116
|
+
const regions = [];
|
|
117
|
+
// Track blocks with their brace depth at push time
|
|
118
|
+
const blockStack = [];
|
|
119
|
+
let braceDepth = 0;
|
|
120
|
+
for (let i = 0; i < lines.length; i++) {
|
|
121
|
+
const text = lines[i].text;
|
|
122
|
+
// Check for function/class definition
|
|
123
|
+
const funcMatch = text.match(PATTERNS.functionDef);
|
|
124
|
+
// Process character by character to properly match braces
|
|
125
|
+
// Skip braces inside strings and comments
|
|
126
|
+
let inString = null;
|
|
127
|
+
let inLineComment = false;
|
|
128
|
+
for (let ch = 0; ch < text.length; ch++) {
|
|
129
|
+
const c = text[ch];
|
|
130
|
+
const next = text[ch + 1];
|
|
131
|
+
// Handle line comments
|
|
132
|
+
if (!inString && c === '/' && next === '/') {
|
|
133
|
+
inLineComment = true;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
// Handle strings
|
|
137
|
+
if (!inLineComment) {
|
|
138
|
+
if (inString) {
|
|
139
|
+
if (c === inString && text[ch - 1] !== '\\') {
|
|
140
|
+
inString = null;
|
|
141
|
+
}
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
else if (c === '"' || c === "'" || c === '`') {
|
|
145
|
+
inString = c;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!inString && !inLineComment) {
|
|
150
|
+
if (c === '{') {
|
|
151
|
+
braceDepth++;
|
|
152
|
+
// If this is the opening brace of a function/class def, push it
|
|
153
|
+
if (funcMatch && this.isDefOpeningBrace(text, ch, funcMatch)) {
|
|
154
|
+
blockStack.push({ line: i, type: funcMatch[5] ? 'class' : 'function', name: funcMatch[2] || funcMatch[3] || funcMatch[4] || funcMatch[5], depth: braceDepth });
|
|
155
|
+
}
|
|
156
|
+
else if (!funcMatch || braceDepth > (blockStack.length > 0 ? blockStack[blockStack.length - 1].depth : 0) + 1) {
|
|
157
|
+
// Anonymous/inline brace — only push as block if it's a
|
|
158
|
+
// statement-level block (i.e., after control flow keyword on this line)
|
|
159
|
+
const prefix = text.slice(0, ch).trim();
|
|
160
|
+
if (/\b(if|else|for|while|do|switch|try|catch|finally)\b/.test(prefix) || prefix.endsWith('=>') || prefix.endsWith(')')) {
|
|
161
|
+
blockStack.push({ line: i, type: 'block', depth: braceDepth });
|
|
162
|
+
}
|
|
163
|
+
// Otherwise it's an expression brace (object literal, destructuring) — ignore
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (c === '}') {
|
|
167
|
+
// Close: pop if this brace matches a tracked block's depth
|
|
168
|
+
if (blockStack.length > 0 && braceDepth === blockStack[blockStack.length - 1].depth) {
|
|
169
|
+
const block = blockStack.pop();
|
|
170
|
+
if (block.type === 'function' || block.type === 'class') {
|
|
171
|
+
regions.push({
|
|
172
|
+
startLine: block.line,
|
|
173
|
+
endLine: i,
|
|
174
|
+
type: block.type,
|
|
175
|
+
name: block.name,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// If no regions found, treat whole file as one region
|
|
185
|
+
if (regions.length === 0 && lines.length > 0) {
|
|
186
|
+
regions.push({
|
|
187
|
+
startLine: 0,
|
|
188
|
+
endLine: lines.length - 1,
|
|
189
|
+
type: 'file',
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return regions;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Check if a `{` at position `ch` is the opening brace of a function/class definition
|
|
196
|
+
*/
|
|
197
|
+
isDefOpeningBrace(text, ch, funcMatch) {
|
|
198
|
+
// For class: `class Foo {` — the `{` follows the class name
|
|
199
|
+
if (funcMatch[5]) {
|
|
200
|
+
return true; // First `{` on a class line is the class body
|
|
201
|
+
}
|
|
202
|
+
// For functions: the `{` should follow the parameter list closing `)`
|
|
203
|
+
// or follow `=>` for arrow functions
|
|
204
|
+
const before = text.slice(0, ch).trimEnd();
|
|
205
|
+
return before.endsWith(')') || before.endsWith('=>');
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Analyze a specific region
|
|
209
|
+
*/
|
|
210
|
+
analyzeRegion(lines, region) {
|
|
211
|
+
const factors = this.calculateFactors(lines, region.startLine, region.endLine);
|
|
212
|
+
const score = this.calculateScore(factors);
|
|
213
|
+
const suggestion = this.getSuggestion(factors, score);
|
|
214
|
+
return {
|
|
215
|
+
...region,
|
|
216
|
+
score,
|
|
217
|
+
factors,
|
|
218
|
+
suggestion,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Calculate complexity factors for a range of lines
|
|
223
|
+
*/
|
|
224
|
+
calculateFactors(lines, startLine, endLine) {
|
|
225
|
+
let nestingDepth = 0;
|
|
226
|
+
let maxNesting = 0;
|
|
227
|
+
let branchingFactor = 0;
|
|
228
|
+
let callCount = 0;
|
|
229
|
+
const identifiers = new Set();
|
|
230
|
+
// Use a global version of the nesting pattern so we can count all matches per line
|
|
231
|
+
const nestingStartGlobal = /\b(if|for|while|switch|try|catch|with)\s*\(|=>\s*\{|\bdo\s*\{/g;
|
|
232
|
+
// Keywords that should NOT be counted as function calls
|
|
233
|
+
const controlKeywords = new Set(['if', 'for', 'while', 'switch', 'catch', 'function', 'return', 'typeof', 'new', 'throw', 'await', 'yield', 'import', 'export', 'class', 'super', 'this', 'void', 'delete', 'in', 'of']);
|
|
234
|
+
for (let i = startLine; i <= endLine && i < lines.length; i++) {
|
|
235
|
+
const text = lines[i].text;
|
|
236
|
+
// Track nesting — count ALL nesting openers per line
|
|
237
|
+
nestingStartGlobal.lastIndex = 0;
|
|
238
|
+
let nestingMatches = 0;
|
|
239
|
+
while (nestingStartGlobal.exec(text) !== null) {
|
|
240
|
+
nestingMatches++;
|
|
241
|
+
}
|
|
242
|
+
nestingDepth += nestingMatches;
|
|
243
|
+
maxNesting = Math.max(maxNesting, nestingDepth);
|
|
244
|
+
// Count closing braces (simplified nesting tracking)
|
|
245
|
+
const closes = (text.match(PATTERNS.blockClose) || []).length;
|
|
246
|
+
nestingDepth = Math.max(0, nestingDepth - closes);
|
|
247
|
+
// Count branching
|
|
248
|
+
const branches = text.match(PATTERNS.branching);
|
|
249
|
+
if (branches) {
|
|
250
|
+
branchingFactor += branches.length;
|
|
251
|
+
}
|
|
252
|
+
// Count function calls — exclude control keywords and function declaration names
|
|
253
|
+
const callRegex = /\b(\w+)\s*\(/g;
|
|
254
|
+
let callMatch;
|
|
255
|
+
while ((callMatch = callRegex.exec(text)) !== null) {
|
|
256
|
+
if (controlKeywords.has(callMatch[1]))
|
|
257
|
+
continue;
|
|
258
|
+
// Skip function declaration names: "function foo(" → "foo" is not a call
|
|
259
|
+
const before = text.slice(0, callMatch.index).trimEnd();
|
|
260
|
+
if (before.endsWith('function'))
|
|
261
|
+
continue;
|
|
262
|
+
callCount++;
|
|
263
|
+
}
|
|
264
|
+
// Collect identifiers
|
|
265
|
+
const ids = text.match(PATTERNS.identifier);
|
|
266
|
+
if (ids) {
|
|
267
|
+
ids.forEach((id) => identifiers.add(id));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
nestingDepth: maxNesting,
|
|
272
|
+
branchingFactor,
|
|
273
|
+
lineCount: endLine - startLine + 1,
|
|
274
|
+
identifierCount: identifiers.size,
|
|
275
|
+
callCount,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Calculate complexity score from factors
|
|
280
|
+
*/
|
|
281
|
+
calculateScore(factors) {
|
|
282
|
+
const score = factors.nestingDepth * WEIGHTS.nestingDepth +
|
|
283
|
+
factors.branchingFactor * WEIGHTS.branchingFactor +
|
|
284
|
+
factors.lineCount * WEIGHTS.lineCount +
|
|
285
|
+
factors.identifierCount * WEIGHTS.identifierCount +
|
|
286
|
+
factors.callCount * WEIGHTS.callCount;
|
|
287
|
+
return Math.min(100, Math.round(score));
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Get suggestion based on factors
|
|
291
|
+
*/
|
|
292
|
+
getSuggestion(factors, score) {
|
|
293
|
+
if (score < THRESHOLDS.medium) {
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
if (factors.nestingDepth > 4) {
|
|
297
|
+
return 'Deep nesting detected. Consider extracting nested logic into separate functions.';
|
|
298
|
+
}
|
|
299
|
+
if (factors.lineCount > 50) {
|
|
300
|
+
return 'Long function detected. Consider breaking it into smaller, focused functions.';
|
|
301
|
+
}
|
|
302
|
+
if (factors.branchingFactor > 10) {
|
|
303
|
+
return 'High branching complexity. Consider using a lookup table, strategy pattern, or polymorphism.';
|
|
304
|
+
}
|
|
305
|
+
if (factors.callCount > 20) {
|
|
306
|
+
return 'Many function calls. Consider if some operations can be combined or simplified.';
|
|
307
|
+
}
|
|
308
|
+
if (score >= THRESHOLDS.high) {
|
|
309
|
+
return 'High cognitive complexity. This code may be difficult to understand and maintain.';
|
|
310
|
+
}
|
|
311
|
+
return undefined;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Find hotspot lines (lines in high-complexity regions)
|
|
315
|
+
*/
|
|
316
|
+
findHotspots(regions) {
|
|
317
|
+
const hotspots = [];
|
|
318
|
+
for (const region of regions) {
|
|
319
|
+
if (region.score >= THRESHOLDS.high) {
|
|
320
|
+
for (let i = region.startLine; i <= region.endLine; i++) {
|
|
321
|
+
hotspots.push(i);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return hotspots;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Calculate overall complexity
|
|
329
|
+
*/
|
|
330
|
+
calculateOverall(regions, _totalLines) {
|
|
331
|
+
if (regions.length === 0)
|
|
332
|
+
return 0;
|
|
333
|
+
// Weighted average based on region size
|
|
334
|
+
let totalWeight = 0;
|
|
335
|
+
let weightedSum = 0;
|
|
336
|
+
for (const region of regions) {
|
|
337
|
+
const weight = region.endLine - region.startLine + 1;
|
|
338
|
+
weightedSum += region.score * weight;
|
|
339
|
+
totalWeight += weight;
|
|
340
|
+
}
|
|
341
|
+
// Normalize to total lines
|
|
342
|
+
const avgScore = totalWeight > 0 ? weightedSum / totalWeight : 0;
|
|
343
|
+
// Boost score slightly for files with many high-complexity regions
|
|
344
|
+
const highComplexityCount = regions.filter((r) => r.score >= THRESHOLDS.high).length;
|
|
345
|
+
const boost = Math.min(10, highComplexityCount * 2);
|
|
346
|
+
return Math.min(100, Math.round(avgScore + boost));
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Get complexity level from score
|
|
350
|
+
*/
|
|
351
|
+
getLevel(score) {
|
|
352
|
+
if (score >= THRESHOLDS.critical)
|
|
353
|
+
return 'critical';
|
|
354
|
+
if (score >= THRESHOLDS.high)
|
|
355
|
+
return 'high';
|
|
356
|
+
if (score >= THRESHOLDS.medium)
|
|
357
|
+
return 'medium';
|
|
358
|
+
return 'low';
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Create a new complexity analyzer
|
|
363
|
+
*/
|
|
364
|
+
export function createComplexityAnalyzer() {
|
|
365
|
+
return new ComplexityAnalyzer();
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Singleton instance for convenience
|
|
369
|
+
*/
|
|
370
|
+
let defaultAnalyzer = null;
|
|
371
|
+
export function getComplexityAnalyzer() {
|
|
372
|
+
if (!defaultAnalyzer) {
|
|
373
|
+
defaultAnalyzer = createComplexityAnalyzer();
|
|
374
|
+
}
|
|
375
|
+
return defaultAnalyzer;
|
|
376
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
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
|
+
import type { SemanticRegion } from './semantic-analyzer';
|
|
9
|
+
/**
|
|
10
|
+
* User awareness state for conflict detection
|
|
11
|
+
*/
|
|
12
|
+
export interface UserAwareness {
|
|
13
|
+
/** User ID */
|
|
14
|
+
id: string;
|
|
15
|
+
/** User display name */
|
|
16
|
+
name: string;
|
|
17
|
+
/** User color */
|
|
18
|
+
color: string;
|
|
19
|
+
/** Whether this is an AI agent */
|
|
20
|
+
isAI: boolean;
|
|
21
|
+
/** Current cursor line */
|
|
22
|
+
cursorLine: number;
|
|
23
|
+
/** Current cursor column */
|
|
24
|
+
cursorColumn: number;
|
|
25
|
+
/** Last edit timestamp */
|
|
26
|
+
lastEditTime: number;
|
|
27
|
+
/** Lines edited in the last N seconds */
|
|
28
|
+
recentlyEditedLines: number[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Conflict zone information
|
|
32
|
+
*/
|
|
33
|
+
export interface ConflictZone {
|
|
34
|
+
/** Unique zone ID */
|
|
35
|
+
id: string;
|
|
36
|
+
/** Start line of the conflict zone */
|
|
37
|
+
startLine: number;
|
|
38
|
+
/** End line of the conflict zone */
|
|
39
|
+
endLine: number;
|
|
40
|
+
/** Conflict probability (0-1) */
|
|
41
|
+
probability: number;
|
|
42
|
+
/** Severity level */
|
|
43
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
44
|
+
/** Users involved in the potential conflict */
|
|
45
|
+
participants: Array<{
|
|
46
|
+
userId: string;
|
|
47
|
+
userName: string;
|
|
48
|
+
color: string;
|
|
49
|
+
cursorLine: number;
|
|
50
|
+
lastEditTime: number;
|
|
51
|
+
isAI: boolean;
|
|
52
|
+
}>;
|
|
53
|
+
/** Semantic context of the conflict zone */
|
|
54
|
+
semanticUnit: string;
|
|
55
|
+
/** Suggested action */
|
|
56
|
+
suggestion?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Conflict prediction configuration
|
|
60
|
+
*/
|
|
61
|
+
export interface ConflictPredictorConfig {
|
|
62
|
+
/** Time window for recent edits in ms (default: 30000) */
|
|
63
|
+
recentEditWindow: number;
|
|
64
|
+
/** Minimum proximity in lines to consider conflict (default: 10) */
|
|
65
|
+
proximityThreshold: number;
|
|
66
|
+
/** Probability threshold to show warning (default: 0.3) */
|
|
67
|
+
warningThreshold: number;
|
|
68
|
+
/** Enable AI conflict detection (default: true) */
|
|
69
|
+
includeAI: boolean;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Conflict Predictor class
|
|
73
|
+
*/
|
|
74
|
+
export declare class ConflictPredictor {
|
|
75
|
+
private config;
|
|
76
|
+
private listeners;
|
|
77
|
+
private lastZones;
|
|
78
|
+
constructor(config?: Partial<ConflictPredictorConfig>);
|
|
79
|
+
/**
|
|
80
|
+
* Predict conflict zones based on user awareness and semantic regions
|
|
81
|
+
*/
|
|
82
|
+
predict(users: UserAwareness[], semanticRegions: SemanticRegion[]): ConflictZone[];
|
|
83
|
+
/**
|
|
84
|
+
* Get the last predicted zones
|
|
85
|
+
*/
|
|
86
|
+
getLastZones(): ConflictZone[];
|
|
87
|
+
/**
|
|
88
|
+
* Subscribe to conflict zone changes
|
|
89
|
+
*/
|
|
90
|
+
subscribe(listener: (zones: ConflictZone[]) => void): () => void;
|
|
91
|
+
/**
|
|
92
|
+
* Calculate conflict probability
|
|
93
|
+
*/
|
|
94
|
+
private calculateProbability;
|
|
95
|
+
/**
|
|
96
|
+
* Calculate average pairwise proximity between cursor positions
|
|
97
|
+
*/
|
|
98
|
+
private calculateAverageProximity;
|
|
99
|
+
/**
|
|
100
|
+
* Get severity level from probability
|
|
101
|
+
*/
|
|
102
|
+
private getSeverity;
|
|
103
|
+
/**
|
|
104
|
+
* Get suggestion based on conflict state
|
|
105
|
+
*/
|
|
106
|
+
private getSuggestion;
|
|
107
|
+
/**
|
|
108
|
+
* Detect proximity-based conflicts outside semantic regions
|
|
109
|
+
*/
|
|
110
|
+
private detectProximityConflicts;
|
|
111
|
+
/**
|
|
112
|
+
* Calculate probability for proximity-based conflict
|
|
113
|
+
*/
|
|
114
|
+
private calculateProximityProbability;
|
|
115
|
+
/**
|
|
116
|
+
* Merge overlapping conflict zones
|
|
117
|
+
*/
|
|
118
|
+
private mergeOverlappingZones;
|
|
119
|
+
/**
|
|
120
|
+
* Merge participant lists, removing duplicates
|
|
121
|
+
*/
|
|
122
|
+
private mergeParticipants;
|
|
123
|
+
/**
|
|
124
|
+
* Notify listeners of zone changes
|
|
125
|
+
*/
|
|
126
|
+
private notifyListeners;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create a conflict predictor instance
|
|
130
|
+
*/
|
|
131
|
+
export declare function createConflictPredictor(config?: Partial<ConflictPredictorConfig>): ConflictPredictor;
|
|
132
|
+
/**
|
|
133
|
+
* Get the global conflict predictor
|
|
134
|
+
*/
|
|
135
|
+
export declare function getConflictPredictor(): ConflictPredictor;
|