@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,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock AI Service for Demos
|
|
3
|
+
* Simulates AI responses with streaming and tool calls
|
|
4
|
+
*/
|
|
5
|
+
// Mock response templates
|
|
6
|
+
const MOCK_RESPONSES = {
|
|
7
|
+
explain: `I'll explain this code for you.
|
|
8
|
+
|
|
9
|
+
This function implements a **binary search algorithm** that efficiently finds an element in a sorted array.
|
|
10
|
+
|
|
11
|
+
\`\`\`typescript
|
|
12
|
+
function binarySearch<T>(arr: T[], target: T): number {
|
|
13
|
+
let left = 0;
|
|
14
|
+
let right = arr.length - 1;
|
|
15
|
+
|
|
16
|
+
while (left <= right) {
|
|
17
|
+
const mid = Math.floor((left + right) / 2);
|
|
18
|
+
if (arr[mid] === target) return mid;
|
|
19
|
+
if (arr[mid] < target) left = mid + 1;
|
|
20
|
+
else right = mid - 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
\`\`\`
|
|
26
|
+
|
|
27
|
+
**Key points:**
|
|
28
|
+
- Time complexity: O(log n)
|
|
29
|
+
- Space complexity: O(1)
|
|
30
|
+
- Requires a sorted array`,
|
|
31
|
+
refactor: `I'll refactor this code to use modern patterns.
|
|
32
|
+
|
|
33
|
+
Here's the improved version:
|
|
34
|
+
|
|
35
|
+
\`\`\`typescript
|
|
36
|
+
// Before: Callback-based
|
|
37
|
+
function fetchData(url, callback) {
|
|
38
|
+
fetch(url)
|
|
39
|
+
.then(res => res.json())
|
|
40
|
+
.then(data => callback(null, data))
|
|
41
|
+
.catch(err => callback(err));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// After: Async/await with error handling
|
|
45
|
+
async function fetchData(url: string): Promise<Response> {
|
|
46
|
+
const response = await fetch(url);
|
|
47
|
+
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return response.json();
|
|
53
|
+
}
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
**Improvements:**
|
|
57
|
+
- Uses async/await for cleaner syntax
|
|
58
|
+
- Proper TypeScript types
|
|
59
|
+
- Better error handling
|
|
60
|
+
- Returns a Promise instead of using callbacks`,
|
|
61
|
+
bugs: `I found several potential issues in your code:
|
|
62
|
+
|
|
63
|
+
1. **Memory Leak** (Line 42)
|
|
64
|
+
\`\`\`typescript
|
|
65
|
+
// Problem: Event listener never removed
|
|
66
|
+
window.addEventListener('resize', handleResize);
|
|
67
|
+
|
|
68
|
+
// Fix: Clean up in useEffect/onDestroy
|
|
69
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
70
|
+
\`\`\`
|
|
71
|
+
|
|
72
|
+
2. **Race Condition** (Line 67)
|
|
73
|
+
\`\`\`typescript
|
|
74
|
+
// Problem: State update after unmount
|
|
75
|
+
const data = await fetchData();
|
|
76
|
+
setState(data); // Component might be unmounted!
|
|
77
|
+
|
|
78
|
+
// Fix: Check if mounted
|
|
79
|
+
if (isMounted) setState(data);
|
|
80
|
+
\`\`\`
|
|
81
|
+
|
|
82
|
+
3. **Missing Null Check** (Line 89)
|
|
83
|
+
\`\`\`typescript
|
|
84
|
+
// Problem
|
|
85
|
+
user.profile.name.toUpperCase()
|
|
86
|
+
|
|
87
|
+
// Fix
|
|
88
|
+
user?.profile?.name?.toUpperCase() ?? 'Unknown'
|
|
89
|
+
\`\`\``,
|
|
90
|
+
tests: `Here are the tests for your function:
|
|
91
|
+
|
|
92
|
+
\`\`\`typescript
|
|
93
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
94
|
+
import { calculateTotal } from './cart';
|
|
95
|
+
|
|
96
|
+
describe('calculateTotal', () => {
|
|
97
|
+
it('should return 0 for empty cart', () => {
|
|
98
|
+
expect(calculateTotal([])).toBe(0);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should sum item prices correctly', () => {
|
|
102
|
+
const items = [
|
|
103
|
+
{ name: 'Apple', price: 1.50, quantity: 3 },
|
|
104
|
+
{ name: 'Banana', price: 0.75, quantity: 2 }
|
|
105
|
+
];
|
|
106
|
+
expect(calculateTotal(items)).toBe(6.00);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should apply discount correctly', () => {
|
|
110
|
+
const items = [{ name: 'Item', price: 100, quantity: 1 }];
|
|
111
|
+
expect(calculateTotal(items, 0.1)).toBe(90);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should handle negative quantities', () => {
|
|
115
|
+
const items = [{ name: 'Item', price: 10, quantity: -1 }];
|
|
116
|
+
expect(() => calculateTotal(items)).toThrow('Invalid quantity');
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
\`\`\``,
|
|
120
|
+
default: `I understand you're asking about your code. Let me help!
|
|
121
|
+
|
|
122
|
+
Based on the context, here's what I can suggest:
|
|
123
|
+
|
|
124
|
+
1. **Code Quality**: Consider adding more type annotations
|
|
125
|
+
2. **Performance**: The current implementation could be optimized
|
|
126
|
+
3. **Maintainability**: Breaking this into smaller functions would help
|
|
127
|
+
|
|
128
|
+
Would you like me to elaborate on any of these points?`
|
|
129
|
+
};
|
|
130
|
+
// Mock tool call responses
|
|
131
|
+
const TOOL_RESPONSES = {
|
|
132
|
+
read_file: () => ({
|
|
133
|
+
content: `import { useState } from 'react';
|
|
134
|
+
|
|
135
|
+
export function Counter() {
|
|
136
|
+
const [count, setCount] = useState(0);
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<button onClick={() => setCount(c => c + 1)}>
|
|
140
|
+
Count: {count}
|
|
141
|
+
</button>
|
|
142
|
+
);
|
|
143
|
+
}`,
|
|
144
|
+
language: 'typescript'
|
|
145
|
+
}),
|
|
146
|
+
search_files: () => ({
|
|
147
|
+
matches: [
|
|
148
|
+
{ file: 'src/components/Button.tsx', line: 15, match: 'TODO: Add loading state' },
|
|
149
|
+
{ file: 'src/utils/api.ts', line: 42, match: 'TODO: Handle rate limiting' },
|
|
150
|
+
{ file: 'src/hooks/useAuth.ts', line: 8, match: 'TODO: Implement refresh token' }
|
|
151
|
+
]
|
|
152
|
+
}),
|
|
153
|
+
run_command: () => ({
|
|
154
|
+
stdout: 'All tests passed!\n\n PASS src/utils/math.test.ts\n PASS src/components/Button.test.tsx\n\nTest Suites: 2 passed, 2 total\nTests: 8 passed, 8 total',
|
|
155
|
+
exitCode: 0
|
|
156
|
+
}),
|
|
157
|
+
edit_file: () => ({
|
|
158
|
+
success: true,
|
|
159
|
+
linesChanged: 15
|
|
160
|
+
})
|
|
161
|
+
};
|
|
162
|
+
const DEFAULT_CONFIG = {
|
|
163
|
+
streamingDelay: 20,
|
|
164
|
+
responseDelay: 500,
|
|
165
|
+
simulateErrors: false,
|
|
166
|
+
errorRate: 0.1
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Detect response type based on user message
|
|
170
|
+
*/
|
|
171
|
+
function detectResponseType(message) {
|
|
172
|
+
const lower = message.toLowerCase();
|
|
173
|
+
if (lower.includes('explain') || lower.includes('what does'))
|
|
174
|
+
return 'explain';
|
|
175
|
+
if (lower.includes('refactor') || lower.includes('improve') || lower.includes('async'))
|
|
176
|
+
return 'refactor';
|
|
177
|
+
if (lower.includes('bug') || lower.includes('issue') || lower.includes('problem'))
|
|
178
|
+
return 'bugs';
|
|
179
|
+
if (lower.includes('test') || lower.includes('spec'))
|
|
180
|
+
return 'tests';
|
|
181
|
+
return 'default';
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Generate mock tool calls based on message
|
|
185
|
+
*/
|
|
186
|
+
function generateToolCalls(message) {
|
|
187
|
+
const lower = message.toLowerCase();
|
|
188
|
+
const calls = [];
|
|
189
|
+
if (lower.includes('read') || lower.includes('file') || lower.includes('show')) {
|
|
190
|
+
calls.push({
|
|
191
|
+
id: crypto.randomUUID(),
|
|
192
|
+
name: 'read_file',
|
|
193
|
+
arguments: { path: '/src/lib/utils.ts' }
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
if (lower.includes('search') || lower.includes('find') || lower.includes('todo')) {
|
|
197
|
+
calls.push({
|
|
198
|
+
id: crypto.randomUUID(),
|
|
199
|
+
name: 'search_files',
|
|
200
|
+
arguments: { query: 'TODO', include: '**/*.ts' }
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (lower.includes('test') || lower.includes('run')) {
|
|
204
|
+
calls.push({
|
|
205
|
+
id: crypto.randomUUID(),
|
|
206
|
+
name: 'run_command',
|
|
207
|
+
arguments: { command: 'npm test' }
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
if (lower.includes('edit') || lower.includes('change') || lower.includes('fix')) {
|
|
211
|
+
calls.push({
|
|
212
|
+
id: crypto.randomUUID(),
|
|
213
|
+
name: 'edit_file',
|
|
214
|
+
arguments: { path: '/src/lib/utils.ts', startLine: 10, endLine: 25 }
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return calls;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Simulate streaming response
|
|
221
|
+
*/
|
|
222
|
+
export async function* streamMockResponse(message, config = {}) {
|
|
223
|
+
const cfg = { ...DEFAULT_CONFIG, ...config };
|
|
224
|
+
const responseType = detectResponseType(message);
|
|
225
|
+
const fullResponse = MOCK_RESPONSES[responseType] || MOCK_RESPONSES.default;
|
|
226
|
+
// Initial delay
|
|
227
|
+
await sleep(cfg.responseDelay);
|
|
228
|
+
// Simulate error
|
|
229
|
+
if (cfg.simulateErrors && Math.random() < cfg.errorRate) {
|
|
230
|
+
throw new Error('Mock API Error: Connection timeout');
|
|
231
|
+
}
|
|
232
|
+
// Stream character by character (or by words for speed)
|
|
233
|
+
const words = fullResponse.split(' ');
|
|
234
|
+
for (let i = 0; i < words.length; i++) {
|
|
235
|
+
yield words[i] + (i < words.length - 1 ? ' ' : '');
|
|
236
|
+
await sleep(cfg.streamingDelay);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get mock response (non-streaming)
|
|
241
|
+
*/
|
|
242
|
+
export async function getMockResponse(message, config = {}) {
|
|
243
|
+
const cfg = { ...DEFAULT_CONFIG, ...config };
|
|
244
|
+
await sleep(cfg.responseDelay);
|
|
245
|
+
if (cfg.simulateErrors && Math.random() < cfg.errorRate) {
|
|
246
|
+
throw new Error('Mock API Error: Rate limit exceeded');
|
|
247
|
+
}
|
|
248
|
+
const responseType = detectResponseType(message);
|
|
249
|
+
const toolCalls = generateToolCalls(message);
|
|
250
|
+
return {
|
|
251
|
+
content: MOCK_RESPONSES[responseType] || MOCK_RESPONSES.default,
|
|
252
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Execute mock tool call
|
|
257
|
+
*/
|
|
258
|
+
export async function executeMockToolCall(toolCall, config = {}) {
|
|
259
|
+
const cfg = { ...DEFAULT_CONFIG, ...config };
|
|
260
|
+
const start = Date.now();
|
|
261
|
+
// Simulate execution time
|
|
262
|
+
await sleep(500 + Math.random() * 1000);
|
|
263
|
+
if (cfg.simulateErrors && Math.random() < cfg.errorRate) {
|
|
264
|
+
throw new Error(`Tool execution failed: ${toolCall.name}`);
|
|
265
|
+
}
|
|
266
|
+
const handler = TOOL_RESPONSES[toolCall.name];
|
|
267
|
+
const result = handler ? handler() : { success: true };
|
|
268
|
+
return {
|
|
269
|
+
result,
|
|
270
|
+
duration: Date.now() - start
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Create a mock AI message with metadata
|
|
275
|
+
*/
|
|
276
|
+
export function createMockMessage(role, content, options = {}) {
|
|
277
|
+
return {
|
|
278
|
+
id: crypto.randomUUID(),
|
|
279
|
+
role,
|
|
280
|
+
content,
|
|
281
|
+
timestamp: new Date(),
|
|
282
|
+
...options,
|
|
283
|
+
metadata: role === 'assistant' ? {
|
|
284
|
+
model: 'claude-3-5-sonnet-mock',
|
|
285
|
+
tokensUsed: Math.floor(content.length / 4),
|
|
286
|
+
latencyMs: Math.floor(500 + Math.random() * 1500),
|
|
287
|
+
...options.metadata
|
|
288
|
+
} : options.metadata
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Generate a conversation with mock messages
|
|
293
|
+
*/
|
|
294
|
+
export function generateMockConversation(turns = 3) {
|
|
295
|
+
const messages = [];
|
|
296
|
+
const prompts = [
|
|
297
|
+
'Can you explain this code?',
|
|
298
|
+
'How can I refactor this to use async/await?',
|
|
299
|
+
'Are there any bugs in this file?',
|
|
300
|
+
'Write some tests for this function'
|
|
301
|
+
];
|
|
302
|
+
for (let i = 0; i < turns; i++) {
|
|
303
|
+
const userContent = prompts[i % prompts.length];
|
|
304
|
+
const responseType = detectResponseType(userContent);
|
|
305
|
+
messages.push(createMockMessage('user', userContent, {
|
|
306
|
+
timestamp: new Date(Date.now() - (turns - i) * 60000)
|
|
307
|
+
}));
|
|
308
|
+
messages.push(createMockMessage('assistant', MOCK_RESPONSES[responseType], {
|
|
309
|
+
timestamp: new Date(Date.now() - (turns - i) * 60000 + 5000),
|
|
310
|
+
toolCalls: i === 1 ? generateToolCalls(userContent) : undefined
|
|
311
|
+
}));
|
|
312
|
+
}
|
|
313
|
+
return messages;
|
|
314
|
+
}
|
|
315
|
+
// Helper
|
|
316
|
+
function sleep(ms) {
|
|
317
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
318
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optimistic Update Service
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for optimistic UI updates with automatic rollback on failure.
|
|
5
|
+
* Implements a queue-based system for managing pending operations.
|
|
6
|
+
*/
|
|
7
|
+
export interface OptimisticOperation<T> {
|
|
8
|
+
id: string;
|
|
9
|
+
type: string;
|
|
10
|
+
payload: T;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
status: 'pending' | 'committed' | 'failed' | 'rolledback';
|
|
13
|
+
rollbackData?: unknown;
|
|
14
|
+
retryCount: number;
|
|
15
|
+
maxRetries: number;
|
|
16
|
+
}
|
|
17
|
+
export interface OptimisticConfig {
|
|
18
|
+
maxRetries?: number;
|
|
19
|
+
retryDelay?: number;
|
|
20
|
+
onCommit?: (operation: OptimisticOperation<unknown>) => void;
|
|
21
|
+
onRollback?: (operation: OptimisticOperation<unknown>, error: Error) => void;
|
|
22
|
+
onRetry?: (operation: OptimisticOperation<unknown>, attempt: number) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface OptimisticResult<T> {
|
|
25
|
+
success: boolean;
|
|
26
|
+
data?: T;
|
|
27
|
+
error?: Error;
|
|
28
|
+
operation: OptimisticOperation<unknown>;
|
|
29
|
+
}
|
|
30
|
+
type RollbackFn = () => void | Promise<void>;
|
|
31
|
+
type CommitFn<T> = () => Promise<T>;
|
|
32
|
+
/**
|
|
33
|
+
* Execute an optimistic update with automatic rollback on failure
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const result = await optimisticUpdate({
|
|
38
|
+
* type: 'file_save',
|
|
39
|
+
* payload: { path: '/src/main.ts', content: '...' },
|
|
40
|
+
* apply: () => {
|
|
41
|
+
* // Apply change locally immediately
|
|
42
|
+
* updateLocalFile(path, content);
|
|
43
|
+
* },
|
|
44
|
+
* rollback: () => {
|
|
45
|
+
* // Revert to previous state
|
|
46
|
+
* updateLocalFile(path, previousContent);
|
|
47
|
+
* },
|
|
48
|
+
* commit: async () => {
|
|
49
|
+
* // Persist to server
|
|
50
|
+
* return await vfsClient.writeFile(workspaceId, path, content);
|
|
51
|
+
* }
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function optimisticUpdate<T, R>(options: {
|
|
56
|
+
type: string;
|
|
57
|
+
payload: T;
|
|
58
|
+
apply: () => void;
|
|
59
|
+
rollback: RollbackFn;
|
|
60
|
+
commit: CommitFn<R>;
|
|
61
|
+
config?: OptimisticConfig;
|
|
62
|
+
}): Promise<OptimisticResult<R>>;
|
|
63
|
+
/**
|
|
64
|
+
* Create an optimistic state manager for a specific resource
|
|
65
|
+
*/
|
|
66
|
+
export declare function createOptimisticState<T>(initialValue: T): {
|
|
67
|
+
readonly value: T;
|
|
68
|
+
readonly isPending: boolean;
|
|
69
|
+
readonly confirmedValue: T;
|
|
70
|
+
/**
|
|
71
|
+
* Apply an optimistic update
|
|
72
|
+
*/
|
|
73
|
+
update(newValue: T, commit: () => Promise<T>, config?: OptimisticConfig): Promise<OptimisticResult<T>>;
|
|
74
|
+
/**
|
|
75
|
+
* Confirm a pending value (e.g., from server response)
|
|
76
|
+
*/
|
|
77
|
+
confirm(value: T): void;
|
|
78
|
+
/**
|
|
79
|
+
* Reset to initial value
|
|
80
|
+
*/
|
|
81
|
+
reset(): void;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Batch multiple optimistic operations
|
|
85
|
+
*/
|
|
86
|
+
export declare function batchOptimisticUpdates<T>(operations: Array<{
|
|
87
|
+
type: string;
|
|
88
|
+
payload: unknown;
|
|
89
|
+
apply: () => void;
|
|
90
|
+
rollback: RollbackFn;
|
|
91
|
+
commit: CommitFn<unknown>;
|
|
92
|
+
}>, config?: OptimisticConfig): Promise<{
|
|
93
|
+
success: boolean;
|
|
94
|
+
results: OptimisticResult<unknown>[];
|
|
95
|
+
failedCount: number;
|
|
96
|
+
}>;
|
|
97
|
+
/**
|
|
98
|
+
* Get all pending operations
|
|
99
|
+
*/
|
|
100
|
+
export declare function getPendingOperations(): OptimisticOperation<unknown>[];
|
|
101
|
+
/**
|
|
102
|
+
* Get operation by ID
|
|
103
|
+
*/
|
|
104
|
+
export declare function getOperation(id: string): OptimisticOperation<unknown> | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Cancel a pending operation
|
|
107
|
+
*/
|
|
108
|
+
export declare function cancelOperation(id: string): Promise<boolean>;
|
|
109
|
+
/**
|
|
110
|
+
* Cancel all pending operations
|
|
111
|
+
*/
|
|
112
|
+
export declare function cancelAllOperations(): Promise<void>;
|
|
113
|
+
export interface ConflictInfo {
|
|
114
|
+
type: 'version' | 'lock' | 'concurrent';
|
|
115
|
+
localVersion?: number;
|
|
116
|
+
serverVersion?: number;
|
|
117
|
+
conflictingUser?: string;
|
|
118
|
+
path?: string;
|
|
119
|
+
timestamp: number;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Check if an error indicates a conflict
|
|
123
|
+
*/
|
|
124
|
+
export declare function isConflictError(error: Error): ConflictInfo | null;
|
|
125
|
+
/**
|
|
126
|
+
* Parse conflict details from error
|
|
127
|
+
*/
|
|
128
|
+
export declare function parseConflictDetails(error: Error): {
|
|
129
|
+
localContent?: string;
|
|
130
|
+
serverContent?: string;
|
|
131
|
+
baseContent?: string;
|
|
132
|
+
} | null;
|
|
133
|
+
/**
|
|
134
|
+
* Create a debounced optimistic updater
|
|
135
|
+
*/
|
|
136
|
+
export declare function createDebouncedOptimistic<T>(commitFn: (value: T) => Promise<T>, delayMs?: number): {
|
|
137
|
+
update(value: T, apply: () => void, rollback: RollbackFn): Promise<OptimisticResult<T>>;
|
|
138
|
+
flush(): void;
|
|
139
|
+
readonly isPending: boolean;
|
|
140
|
+
};
|
|
141
|
+
export {};
|