@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,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handling Service
|
|
3
|
+
*
|
|
4
|
+
* Provides structured error types, recovery strategies, and user-friendly error messages.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Error Factory
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Create a structured VFS error
|
|
11
|
+
*/
|
|
12
|
+
export function createVFSError(code, message, options = {}) {
|
|
13
|
+
const error = new Error(message);
|
|
14
|
+
error.name = 'VFSError';
|
|
15
|
+
error.code = code;
|
|
16
|
+
error.statusCode = options.statusCode;
|
|
17
|
+
error.path = options.path;
|
|
18
|
+
error.workspaceId = options.workspaceId;
|
|
19
|
+
error.cause = options.cause;
|
|
20
|
+
error.retryable = isRetryableError(code);
|
|
21
|
+
error.userMessage = getUserMessage(code, options.path);
|
|
22
|
+
error.technicalDetails = message;
|
|
23
|
+
error.recoveryOptions = getRecoveryOptions(code);
|
|
24
|
+
return error;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse an error response into a VFSError
|
|
28
|
+
*/
|
|
29
|
+
export function parseError(error, context) {
|
|
30
|
+
// Already a VFSError
|
|
31
|
+
if (isVFSError(error)) {
|
|
32
|
+
return error;
|
|
33
|
+
}
|
|
34
|
+
// Network/fetch errors
|
|
35
|
+
if (error instanceof TypeError && error.message.includes('fetch')) {
|
|
36
|
+
return createVFSError('NETWORK_ERROR', 'Network request failed', context);
|
|
37
|
+
}
|
|
38
|
+
// Timeout errors
|
|
39
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
40
|
+
return createVFSError('TIMEOUT', 'Request timed out', context);
|
|
41
|
+
}
|
|
42
|
+
// HTTP response errors
|
|
43
|
+
if (error instanceof Response) {
|
|
44
|
+
return parseHttpError(error, context);
|
|
45
|
+
}
|
|
46
|
+
// Error with status property (from fetch responses)
|
|
47
|
+
if (error && typeof error === 'object' && 'status' in error) {
|
|
48
|
+
const status = error.status;
|
|
49
|
+
const message = 'message' in error ? String(error.message) : 'Request failed';
|
|
50
|
+
return parseStatusCode(status, message, context);
|
|
51
|
+
}
|
|
52
|
+
// Generic error
|
|
53
|
+
if (error instanceof Error) {
|
|
54
|
+
return createVFSError('UNKNOWN', error.message, { ...context, cause: error });
|
|
55
|
+
}
|
|
56
|
+
return createVFSError('UNKNOWN', String(error), context);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Parse HTTP response into VFSError
|
|
60
|
+
*/
|
|
61
|
+
function parseHttpError(response, context) {
|
|
62
|
+
return parseStatusCode(response.status, response.statusText, context);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Map HTTP status code to VFSError
|
|
66
|
+
*/
|
|
67
|
+
function parseStatusCode(status, message, context) {
|
|
68
|
+
const options = { statusCode: status, ...context };
|
|
69
|
+
switch (status) {
|
|
70
|
+
case 401:
|
|
71
|
+
case 403:
|
|
72
|
+
return createVFSError('PERMISSION_DENIED', message, options);
|
|
73
|
+
case 404:
|
|
74
|
+
return createVFSError('FILE_NOT_FOUND', message, options);
|
|
75
|
+
case 409:
|
|
76
|
+
if (message.toLowerCase().includes('lock')) {
|
|
77
|
+
return createVFSError('FILE_LOCKED', message, options);
|
|
78
|
+
}
|
|
79
|
+
return createVFSError('VERSION_CONFLICT', message, options);
|
|
80
|
+
case 423:
|
|
81
|
+
return createVFSError('FILE_LOCKED', message, options);
|
|
82
|
+
case 429:
|
|
83
|
+
return createVFSError('RATE_LIMITED', message, options);
|
|
84
|
+
case 500:
|
|
85
|
+
case 502:
|
|
86
|
+
case 503:
|
|
87
|
+
case 504:
|
|
88
|
+
return createVFSError('SERVER_ERROR', message, options);
|
|
89
|
+
default:
|
|
90
|
+
return createVFSError('UNKNOWN', message, options);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// Error Classification
|
|
95
|
+
// ============================================================================
|
|
96
|
+
/**
|
|
97
|
+
* Check if error is a VFSError
|
|
98
|
+
*/
|
|
99
|
+
export function isVFSError(error) {
|
|
100
|
+
return error instanceof Error && 'code' in error && 'retryable' in error;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Check if error code is retryable
|
|
104
|
+
*/
|
|
105
|
+
function isRetryableError(code) {
|
|
106
|
+
return [
|
|
107
|
+
'NETWORK_ERROR',
|
|
108
|
+
'CONNECTION_LOST',
|
|
109
|
+
'TIMEOUT',
|
|
110
|
+
'SERVER_ERROR',
|
|
111
|
+
'RATE_LIMITED'
|
|
112
|
+
].includes(code);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if error is a conflict that needs user resolution
|
|
116
|
+
*/
|
|
117
|
+
export function isConflictError(error) {
|
|
118
|
+
return ['FILE_LOCKED', 'LOCK_CONFLICT', 'VERSION_CONFLICT'].includes(error.code);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check if error is recoverable with user action
|
|
122
|
+
*/
|
|
123
|
+
export function isRecoverableError(error) {
|
|
124
|
+
return error.recoveryOptions.length > 0;
|
|
125
|
+
}
|
|
126
|
+
// ============================================================================
|
|
127
|
+
// User Messages
|
|
128
|
+
// ============================================================================
|
|
129
|
+
/**
|
|
130
|
+
* Get user-friendly error message
|
|
131
|
+
*/
|
|
132
|
+
function getUserMessage(code, path) {
|
|
133
|
+
const fileName = path ? path.split('/').pop() : 'the file';
|
|
134
|
+
switch (code) {
|
|
135
|
+
case 'NETWORK_ERROR':
|
|
136
|
+
return 'Unable to connect to the server. Please check your internet connection.';
|
|
137
|
+
case 'CONNECTION_LOST':
|
|
138
|
+
return 'Connection to the server was lost. Attempting to reconnect...';
|
|
139
|
+
case 'TIMEOUT':
|
|
140
|
+
return 'The request took too long to complete. Please try again.';
|
|
141
|
+
case 'FILE_LOCKED':
|
|
142
|
+
return `${fileName} is currently being edited by another user.`;
|
|
143
|
+
case 'LOCK_EXPIRED':
|
|
144
|
+
return `Your editing session for ${fileName} has expired.`;
|
|
145
|
+
case 'LOCK_CONFLICT':
|
|
146
|
+
return `There was a conflict acquiring the lock for ${fileName}.`;
|
|
147
|
+
case 'VERSION_CONFLICT':
|
|
148
|
+
return `${fileName} was modified by someone else while you were editing.`;
|
|
149
|
+
case 'FILE_NOT_FOUND':
|
|
150
|
+
return `${fileName} could not be found. It may have been moved or deleted.`;
|
|
151
|
+
case 'PERMISSION_DENIED':
|
|
152
|
+
return `You don't have permission to access ${fileName}.`;
|
|
153
|
+
case 'WORKSPACE_NOT_FOUND':
|
|
154
|
+
return 'The workspace could not be found.';
|
|
155
|
+
case 'INVALID_OPERATION':
|
|
156
|
+
return 'This operation is not allowed.';
|
|
157
|
+
case 'SERVER_ERROR':
|
|
158
|
+
return 'The server encountered an error. Please try again later.';
|
|
159
|
+
case 'RATE_LIMITED':
|
|
160
|
+
return 'Too many requests. Please wait a moment before trying again.';
|
|
161
|
+
default:
|
|
162
|
+
return 'An unexpected error occurred. Please try again.';
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get recovery options for error code
|
|
167
|
+
*/
|
|
168
|
+
function getRecoveryOptions(code) {
|
|
169
|
+
switch (code) {
|
|
170
|
+
case 'NETWORK_ERROR':
|
|
171
|
+
case 'TIMEOUT':
|
|
172
|
+
case 'SERVER_ERROR':
|
|
173
|
+
return [
|
|
174
|
+
{
|
|
175
|
+
id: 'retry',
|
|
176
|
+
label: 'Retry',
|
|
177
|
+
description: 'Try the operation again',
|
|
178
|
+
action: 'retry',
|
|
179
|
+
recommended: true
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: 'cancel',
|
|
183
|
+
label: 'Cancel',
|
|
184
|
+
description: 'Cancel this operation',
|
|
185
|
+
action: 'cancel'
|
|
186
|
+
}
|
|
187
|
+
];
|
|
188
|
+
case 'CONNECTION_LOST':
|
|
189
|
+
return [
|
|
190
|
+
{
|
|
191
|
+
id: 'wait',
|
|
192
|
+
label: 'Wait for Reconnection',
|
|
193
|
+
description: 'The system will automatically reconnect',
|
|
194
|
+
action: 'wait',
|
|
195
|
+
recommended: true
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: 'refresh',
|
|
199
|
+
label: 'Refresh Page',
|
|
200
|
+
description: 'Reload the page to reconnect',
|
|
201
|
+
action: 'refresh'
|
|
202
|
+
}
|
|
203
|
+
];
|
|
204
|
+
case 'FILE_LOCKED':
|
|
205
|
+
return [
|
|
206
|
+
{
|
|
207
|
+
id: 'wait',
|
|
208
|
+
label: 'Wait',
|
|
209
|
+
description: 'Wait for the lock to be released',
|
|
210
|
+
action: 'wait',
|
|
211
|
+
recommended: true
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
id: 'force',
|
|
215
|
+
label: 'Force Unlock',
|
|
216
|
+
description: 'Take over the lock (may cause data loss for the other user)',
|
|
217
|
+
action: 'force',
|
|
218
|
+
dangerous: true
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
id: 'cancel',
|
|
222
|
+
label: 'Open Read-Only',
|
|
223
|
+
description: 'View the file without editing',
|
|
224
|
+
action: 'cancel'
|
|
225
|
+
}
|
|
226
|
+
];
|
|
227
|
+
case 'LOCK_EXPIRED':
|
|
228
|
+
return [
|
|
229
|
+
{
|
|
230
|
+
id: 'retry',
|
|
231
|
+
label: 'Reacquire Lock',
|
|
232
|
+
description: 'Try to get the lock again and save',
|
|
233
|
+
action: 'retry',
|
|
234
|
+
recommended: true
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
id: 'discard',
|
|
238
|
+
label: 'Discard Changes',
|
|
239
|
+
description: 'Lose your unsaved changes',
|
|
240
|
+
action: 'discard',
|
|
241
|
+
dangerous: true
|
|
242
|
+
}
|
|
243
|
+
];
|
|
244
|
+
case 'VERSION_CONFLICT':
|
|
245
|
+
return [
|
|
246
|
+
{
|
|
247
|
+
id: 'merge',
|
|
248
|
+
label: 'Merge Changes',
|
|
249
|
+
description: 'Review and merge your changes with the server version',
|
|
250
|
+
action: 'merge',
|
|
251
|
+
recommended: true
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
id: 'force',
|
|
255
|
+
label: 'Overwrite',
|
|
256
|
+
description: 'Replace server version with your changes',
|
|
257
|
+
action: 'force',
|
|
258
|
+
dangerous: true
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: 'discard',
|
|
262
|
+
label: 'Use Server Version',
|
|
263
|
+
description: 'Discard your changes and use the latest version',
|
|
264
|
+
action: 'discard'
|
|
265
|
+
}
|
|
266
|
+
];
|
|
267
|
+
case 'FILE_NOT_FOUND':
|
|
268
|
+
return [
|
|
269
|
+
{
|
|
270
|
+
id: 'refresh',
|
|
271
|
+
label: 'Refresh File List',
|
|
272
|
+
description: 'Update the file explorer',
|
|
273
|
+
action: 'refresh',
|
|
274
|
+
recommended: true
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
id: 'cancel',
|
|
278
|
+
label: 'Close',
|
|
279
|
+
description: 'Close this file tab',
|
|
280
|
+
action: 'cancel'
|
|
281
|
+
}
|
|
282
|
+
];
|
|
283
|
+
case 'PERMISSION_DENIED':
|
|
284
|
+
return [
|
|
285
|
+
{
|
|
286
|
+
id: 'cancel',
|
|
287
|
+
label: 'OK',
|
|
288
|
+
description: 'Acknowledge and close',
|
|
289
|
+
action: 'cancel'
|
|
290
|
+
}
|
|
291
|
+
];
|
|
292
|
+
case 'RATE_LIMITED':
|
|
293
|
+
return [
|
|
294
|
+
{
|
|
295
|
+
id: 'wait',
|
|
296
|
+
label: 'Wait',
|
|
297
|
+
description: 'Wait a moment before retrying',
|
|
298
|
+
action: 'wait',
|
|
299
|
+
recommended: true
|
|
300
|
+
}
|
|
301
|
+
];
|
|
302
|
+
default:
|
|
303
|
+
return [
|
|
304
|
+
{
|
|
305
|
+
id: 'retry',
|
|
306
|
+
label: 'Retry',
|
|
307
|
+
description: 'Try the operation again',
|
|
308
|
+
action: 'retry'
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
id: 'cancel',
|
|
312
|
+
label: 'Cancel',
|
|
313
|
+
description: 'Cancel this operation',
|
|
314
|
+
action: 'cancel'
|
|
315
|
+
}
|
|
316
|
+
];
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Execute a recovery action
|
|
321
|
+
*/
|
|
322
|
+
export async function executeRecovery(option, handlers) {
|
|
323
|
+
switch (option.action) {
|
|
324
|
+
case 'retry':
|
|
325
|
+
await handlers.onRetry?.();
|
|
326
|
+
break;
|
|
327
|
+
case 'force':
|
|
328
|
+
await handlers.onForce?.();
|
|
329
|
+
break;
|
|
330
|
+
case 'merge':
|
|
331
|
+
await handlers.onMerge?.();
|
|
332
|
+
break;
|
|
333
|
+
case 'discard':
|
|
334
|
+
await handlers.onDiscard?.();
|
|
335
|
+
break;
|
|
336
|
+
case 'refresh':
|
|
337
|
+
await handlers.onRefresh?.();
|
|
338
|
+
break;
|
|
339
|
+
case 'wait':
|
|
340
|
+
await handlers.onWait?.();
|
|
341
|
+
break;
|
|
342
|
+
case 'cancel':
|
|
343
|
+
handlers.onCancel?.();
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Aggregate multiple errors for batch operations
|
|
349
|
+
*/
|
|
350
|
+
export function aggregateErrors(errors) {
|
|
351
|
+
const byCode = new Map();
|
|
352
|
+
const retryable = [];
|
|
353
|
+
const needsUserAction = [];
|
|
354
|
+
const fatal = [];
|
|
355
|
+
for (const error of errors) {
|
|
356
|
+
// Group by code
|
|
357
|
+
const existing = byCode.get(error.code) || [];
|
|
358
|
+
existing.push(error);
|
|
359
|
+
byCode.set(error.code, existing);
|
|
360
|
+
// Categorize
|
|
361
|
+
if (error.retryable) {
|
|
362
|
+
retryable.push(error);
|
|
363
|
+
}
|
|
364
|
+
else if (isConflictError(error)) {
|
|
365
|
+
needsUserAction.push(error);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
fatal.push(error);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
total: errors.length,
|
|
373
|
+
byCode,
|
|
374
|
+
retryable,
|
|
375
|
+
needsUserAction,
|
|
376
|
+
fatal
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
const errorLog = [];
|
|
380
|
+
const MAX_LOG_SIZE = 100;
|
|
381
|
+
/**
|
|
382
|
+
* Log an error
|
|
383
|
+
*/
|
|
384
|
+
export function logError(error, level = 'error', context) {
|
|
385
|
+
const entry = {
|
|
386
|
+
timestamp: Date.now(),
|
|
387
|
+
error,
|
|
388
|
+
level,
|
|
389
|
+
context
|
|
390
|
+
};
|
|
391
|
+
errorLog.push(entry);
|
|
392
|
+
// Trim log if too large
|
|
393
|
+
if (errorLog.length > MAX_LOG_SIZE) {
|
|
394
|
+
errorLog.shift();
|
|
395
|
+
}
|
|
396
|
+
// Also log to console in development
|
|
397
|
+
if (typeof window !== 'undefined' && window.__DEV__) {
|
|
398
|
+
const logFn = level === 'error' ? console.error : level === 'warn' ? console.warn : console.log;
|
|
399
|
+
logFn(`[VFS ${level.toUpperCase()}]`, error.code, error.userMessage, context);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Get recent errors
|
|
404
|
+
*/
|
|
405
|
+
export function getRecentErrors(limit = 10) {
|
|
406
|
+
return errorLog.slice(-limit);
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Clear error log
|
|
410
|
+
*/
|
|
411
|
+
export function clearErrorLog() {
|
|
412
|
+
errorLog.length = 0;
|
|
413
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Integration Service
|
|
3
|
+
*
|
|
4
|
+
* Coordinates VFS, Agents, and Collaboration stores into a unified system.
|
|
5
|
+
* Handles cross-store communication and event routing.
|
|
6
|
+
*/
|
|
7
|
+
import type { VFSFileLock, Agent } from '../types';
|
|
8
|
+
export interface IDEIntegrationConfig {
|
|
9
|
+
workspaceId: string;
|
|
10
|
+
userId: string;
|
|
11
|
+
userName: string;
|
|
12
|
+
vfsEndpoint?: string;
|
|
13
|
+
enableAgentSync?: boolean;
|
|
14
|
+
enableCollaboration?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface IDEContext {
|
|
17
|
+
workspaceId: string;
|
|
18
|
+
userId: string;
|
|
19
|
+
userName: string;
|
|
20
|
+
connected: boolean;
|
|
21
|
+
synced: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Initialize the IDE integration layer
|
|
25
|
+
* Connects all stores and sets up event routing
|
|
26
|
+
*/
|
|
27
|
+
export declare function initialize(integrationConfig: IDEIntegrationConfig): void;
|
|
28
|
+
/**
|
|
29
|
+
* Update agent cursor position (called from editor)
|
|
30
|
+
*/
|
|
31
|
+
export declare function updateAgentCursorPosition(agentId: string, filePath: string, position: {
|
|
32
|
+
line: number;
|
|
33
|
+
column: number;
|
|
34
|
+
}, selection?: {
|
|
35
|
+
start: {
|
|
36
|
+
line: number;
|
|
37
|
+
column: number;
|
|
38
|
+
};
|
|
39
|
+
end: {
|
|
40
|
+
line: number;
|
|
41
|
+
column: number;
|
|
42
|
+
};
|
|
43
|
+
}): void;
|
|
44
|
+
/**
|
|
45
|
+
* Acquire lock with agent awareness
|
|
46
|
+
*/
|
|
47
|
+
export declare function acquireLockWithContext(filePath: string, purpose?: VFSFileLock['purpose']): Promise<VFSFileLock | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Release lock with cleanup
|
|
50
|
+
*/
|
|
51
|
+
export declare function releaseLockWithContext(filePath: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Check if file can be edited (not locked by others)
|
|
54
|
+
*/
|
|
55
|
+
export declare function canEditFile(filePath: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Get agents currently editing a file
|
|
58
|
+
*/
|
|
59
|
+
export declare function getFileEditors(filePath: string): Agent[];
|
|
60
|
+
/**
|
|
61
|
+
* Get current IDE context
|
|
62
|
+
*/
|
|
63
|
+
export declare function getContext(): IDEContext | null;
|
|
64
|
+
/**
|
|
65
|
+
* Get all online agents
|
|
66
|
+
*/
|
|
67
|
+
export declare function getOnlineAgents(): Agent[];
|
|
68
|
+
/**
|
|
69
|
+
* Get all locks
|
|
70
|
+
*/
|
|
71
|
+
export declare function getAllLocks(): VFSFileLock[];
|
|
72
|
+
/**
|
|
73
|
+
* Get lock for specific file
|
|
74
|
+
*/
|
|
75
|
+
export declare function getFileLock(filePath: string): VFSFileLock | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Cleanup all subscriptions and reset state
|
|
78
|
+
*/
|
|
79
|
+
export declare function cleanup(): void;
|
|
80
|
+
/**
|
|
81
|
+
* Check if integration is initialized
|
|
82
|
+
*/
|
|
83
|
+
export declare function isInitialized(): boolean;
|