@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,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Persistence Store
|
|
3
|
+
*
|
|
4
|
+
* Handles saving and loading AI conversations to IndexedDB/localStorage
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_CONFIG = {
|
|
7
|
+
dbName: 'svelte-ide-ai',
|
|
8
|
+
storeName: 'conversations',
|
|
9
|
+
version: 1,
|
|
10
|
+
maxConversations: 100,
|
|
11
|
+
autoSave: true,
|
|
12
|
+
autoSaveDebounceMs: 1000
|
|
13
|
+
};
|
|
14
|
+
// State
|
|
15
|
+
let config = $state({ ...DEFAULT_CONFIG });
|
|
16
|
+
let db = $state(null);
|
|
17
|
+
let initialized = $state(false);
|
|
18
|
+
let error = $state(null);
|
|
19
|
+
// Debounce timer for auto-save
|
|
20
|
+
let saveTimer = null;
|
|
21
|
+
/**
|
|
22
|
+
* Initialize the persistence layer
|
|
23
|
+
*/
|
|
24
|
+
export async function initPersistence(options) {
|
|
25
|
+
if (initialized)
|
|
26
|
+
return true;
|
|
27
|
+
config = { ...DEFAULT_CONFIG, ...options };
|
|
28
|
+
try {
|
|
29
|
+
// Check if IndexedDB is available
|
|
30
|
+
if (!('indexedDB' in globalThis)) {
|
|
31
|
+
console.warn('IndexedDB not available, using localStorage fallback');
|
|
32
|
+
initialized = true;
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
db = await openDatabase();
|
|
36
|
+
initialized = true;
|
|
37
|
+
error = null;
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
error = err instanceof Error ? err.message : 'Failed to initialize persistence';
|
|
42
|
+
console.error('Persistence init error:', err);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Open IndexedDB database
|
|
48
|
+
*/
|
|
49
|
+
function openDatabase() {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
const request = indexedDB.open(config.dbName, config.version);
|
|
52
|
+
request.onerror = () => reject(request.error);
|
|
53
|
+
request.onsuccess = () => resolve(request.result);
|
|
54
|
+
request.onupgradeneeded = (event) => {
|
|
55
|
+
const database = event.target.result;
|
|
56
|
+
// Create conversations store
|
|
57
|
+
if (!database.objectStoreNames.contains(config.storeName)) {
|
|
58
|
+
const store = database.createObjectStore(config.storeName, { keyPath: 'id' });
|
|
59
|
+
store.createIndex('updatedAt', 'updatedAt', { unique: false });
|
|
60
|
+
store.createIndex('starred', 'starred', { unique: false });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Save a conversation
|
|
67
|
+
*/
|
|
68
|
+
export async function saveConversation(conversation) {
|
|
69
|
+
if (!initialized)
|
|
70
|
+
await initPersistence();
|
|
71
|
+
const data = {
|
|
72
|
+
...conversation,
|
|
73
|
+
updatedAt: new Date()
|
|
74
|
+
};
|
|
75
|
+
if (db) {
|
|
76
|
+
// IndexedDB
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
const transaction = db.transaction(config.storeName, 'readwrite');
|
|
79
|
+
const store = transaction.objectStore(config.storeName);
|
|
80
|
+
const request = store.put(data);
|
|
81
|
+
request.onsuccess = () => resolve();
|
|
82
|
+
request.onerror = () => reject(request.error);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// localStorage fallback
|
|
87
|
+
const conversations = getLocalStorageConversations();
|
|
88
|
+
const index = conversations.findIndex((c) => c.id === conversation.id);
|
|
89
|
+
if (index >= 0) {
|
|
90
|
+
conversations[index] = data;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
conversations.push(data);
|
|
94
|
+
}
|
|
95
|
+
setLocalStorageConversations(conversations);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Auto-save with debounce
|
|
100
|
+
*/
|
|
101
|
+
export function autoSaveConversation(conversation) {
|
|
102
|
+
if (!config.autoSave)
|
|
103
|
+
return;
|
|
104
|
+
if (saveTimer) {
|
|
105
|
+
clearTimeout(saveTimer);
|
|
106
|
+
}
|
|
107
|
+
saveTimer = setTimeout(() => {
|
|
108
|
+
saveConversation(conversation);
|
|
109
|
+
saveTimer = null;
|
|
110
|
+
}, config.autoSaveDebounceMs);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Load all conversations
|
|
114
|
+
*/
|
|
115
|
+
export async function loadConversations() {
|
|
116
|
+
if (!initialized)
|
|
117
|
+
await initPersistence();
|
|
118
|
+
if (db) {
|
|
119
|
+
// IndexedDB
|
|
120
|
+
return new Promise((resolve, reject) => {
|
|
121
|
+
const transaction = db.transaction(config.storeName, 'readonly');
|
|
122
|
+
const store = transaction.objectStore(config.storeName);
|
|
123
|
+
const request = store.getAll();
|
|
124
|
+
request.onsuccess = () => {
|
|
125
|
+
const conversations = request.result;
|
|
126
|
+
// Sort by updatedAt descending
|
|
127
|
+
conversations.sort((a, b) => {
|
|
128
|
+
const dateA = new Date(a.updatedAt).getTime();
|
|
129
|
+
const dateB = new Date(b.updatedAt).getTime();
|
|
130
|
+
return dateB - dateA;
|
|
131
|
+
});
|
|
132
|
+
resolve(conversations);
|
|
133
|
+
};
|
|
134
|
+
request.onerror = () => reject(request.error);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// localStorage fallback
|
|
139
|
+
return getLocalStorageConversations();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Load a single conversation by ID
|
|
144
|
+
*/
|
|
145
|
+
export async function loadConversation(id) {
|
|
146
|
+
if (!initialized)
|
|
147
|
+
await initPersistence();
|
|
148
|
+
if (db) {
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
const transaction = db.transaction(config.storeName, 'readonly');
|
|
151
|
+
const store = transaction.objectStore(config.storeName);
|
|
152
|
+
const request = store.get(id);
|
|
153
|
+
request.onsuccess = () => resolve(request.result || null);
|
|
154
|
+
request.onerror = () => reject(request.error);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
const conversations = getLocalStorageConversations();
|
|
159
|
+
return conversations.find((c) => c.id === id) || null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Delete a conversation
|
|
164
|
+
*/
|
|
165
|
+
export async function deleteConversation(id) {
|
|
166
|
+
if (!initialized)
|
|
167
|
+
await initPersistence();
|
|
168
|
+
if (db) {
|
|
169
|
+
return new Promise((resolve, reject) => {
|
|
170
|
+
const transaction = db.transaction(config.storeName, 'readwrite');
|
|
171
|
+
const store = transaction.objectStore(config.storeName);
|
|
172
|
+
const request = store.delete(id);
|
|
173
|
+
request.onsuccess = () => resolve();
|
|
174
|
+
request.onerror = () => reject(request.error);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
const conversations = getLocalStorageConversations();
|
|
179
|
+
const filtered = conversations.filter((c) => c.id !== id);
|
|
180
|
+
setLocalStorageConversations(filtered);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Delete all conversations
|
|
185
|
+
*/
|
|
186
|
+
export async function clearAllConversations() {
|
|
187
|
+
if (!initialized)
|
|
188
|
+
await initPersistence();
|
|
189
|
+
if (db) {
|
|
190
|
+
return new Promise((resolve, reject) => {
|
|
191
|
+
const transaction = db.transaction(config.storeName, 'readwrite');
|
|
192
|
+
const store = transaction.objectStore(config.storeName);
|
|
193
|
+
const request = store.clear();
|
|
194
|
+
request.onsuccess = () => resolve();
|
|
195
|
+
request.onerror = () => reject(request.error);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
setLocalStorageConversations([]);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Search conversations
|
|
204
|
+
*/
|
|
205
|
+
export async function searchConversations(query) {
|
|
206
|
+
const conversations = await loadConversations();
|
|
207
|
+
const lowerQuery = query.toLowerCase();
|
|
208
|
+
return conversations.filter((conv) => {
|
|
209
|
+
// Search in title
|
|
210
|
+
if (conv.title.toLowerCase().includes(lowerQuery))
|
|
211
|
+
return true;
|
|
212
|
+
// Search in messages
|
|
213
|
+
return conv.messages.some((msg) => msg.content.toLowerCase().includes(lowerQuery));
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Get starred conversations
|
|
218
|
+
*/
|
|
219
|
+
export async function getStarredConversations() {
|
|
220
|
+
const conversations = await loadConversations();
|
|
221
|
+
return conversations.filter((c) => c.starred);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Star/unstar a conversation
|
|
225
|
+
*/
|
|
226
|
+
export async function toggleStarConversation(id, starred) {
|
|
227
|
+
const conversation = await loadConversation(id);
|
|
228
|
+
if (conversation) {
|
|
229
|
+
await saveConversation({ ...conversation, starred });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Export conversation to JSON
|
|
234
|
+
*/
|
|
235
|
+
export function exportConversationJSON(conversation) {
|
|
236
|
+
return JSON.stringify(conversation, null, 2);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Export conversation to Markdown
|
|
240
|
+
*/
|
|
241
|
+
export function exportConversationMarkdown(conversation) {
|
|
242
|
+
const lines = [
|
|
243
|
+
`# ${conversation.title}`,
|
|
244
|
+
'',
|
|
245
|
+
`*Created: ${new Date(conversation.createdAt).toLocaleString()}*`,
|
|
246
|
+
`*Updated: ${new Date(conversation.updatedAt).toLocaleString()}*`,
|
|
247
|
+
'',
|
|
248
|
+
'---',
|
|
249
|
+
''
|
|
250
|
+
];
|
|
251
|
+
for (const message of conversation.messages) {
|
|
252
|
+
const role = message.role === 'user' ? 'You' : message.role === 'assistant' ? 'AI' : message.role;
|
|
253
|
+
const time = new Date(message.timestamp).toLocaleTimeString();
|
|
254
|
+
lines.push(`## ${role} *${time}*`);
|
|
255
|
+
lines.push('');
|
|
256
|
+
lines.push(message.content);
|
|
257
|
+
lines.push('');
|
|
258
|
+
if (message.toolCalls && message.toolCalls.length > 0) {
|
|
259
|
+
lines.push('### Tool Calls');
|
|
260
|
+
for (const tool of message.toolCalls) {
|
|
261
|
+
lines.push(`- **${tool.name}**: \`${JSON.stringify(tool.arguments)}\``);
|
|
262
|
+
}
|
|
263
|
+
lines.push('');
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return lines.join('\n');
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Import conversation from JSON
|
|
270
|
+
*/
|
|
271
|
+
export async function importConversationJSON(json) {
|
|
272
|
+
try {
|
|
273
|
+
const conversation = JSON.parse(json);
|
|
274
|
+
// Validate required fields
|
|
275
|
+
if (!conversation.id || !conversation.title || !Array.isArray(conversation.messages)) {
|
|
276
|
+
throw new Error('Invalid conversation format');
|
|
277
|
+
}
|
|
278
|
+
// Generate new ID to avoid conflicts
|
|
279
|
+
conversation.id = crypto.randomUUID();
|
|
280
|
+
conversation.createdAt = new Date();
|
|
281
|
+
conversation.updatedAt = new Date();
|
|
282
|
+
await saveConversation(conversation);
|
|
283
|
+
return conversation;
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
console.error('Failed to import conversation:', err);
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Prune old conversations to stay under max limit
|
|
292
|
+
*/
|
|
293
|
+
export async function pruneOldConversations() {
|
|
294
|
+
const conversations = await loadConversations();
|
|
295
|
+
if (conversations.length <= config.maxConversations) {
|
|
296
|
+
return 0;
|
|
297
|
+
}
|
|
298
|
+
// Sort by updatedAt and keep starred ones
|
|
299
|
+
const toDelete = conversations
|
|
300
|
+
.filter((c) => !c.starred)
|
|
301
|
+
.slice(config.maxConversations);
|
|
302
|
+
for (const conv of toDelete) {
|
|
303
|
+
await deleteConversation(conv.id);
|
|
304
|
+
}
|
|
305
|
+
return toDelete.length;
|
|
306
|
+
}
|
|
307
|
+
// localStorage helpers
|
|
308
|
+
function getLocalStorageConversations() {
|
|
309
|
+
try {
|
|
310
|
+
const data = localStorage.getItem('ai-conversations');
|
|
311
|
+
return data ? JSON.parse(data) : [];
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function setLocalStorageConversations(conversations) {
|
|
318
|
+
try {
|
|
319
|
+
localStorage.setItem('ai-conversations', JSON.stringify(conversations));
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
console.error('Failed to save to localStorage:', err);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// Getters for reactive state
|
|
326
|
+
export function isInitialized() {
|
|
327
|
+
return initialized;
|
|
328
|
+
}
|
|
329
|
+
export function getError() {
|
|
330
|
+
return error;
|
|
331
|
+
}
|
|
332
|
+
export function getConfig() {
|
|
333
|
+
return config;
|
|
334
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI store using Svelte 5 runes
|
|
3
|
+
* Manages AI conversations, messages, and tools
|
|
4
|
+
*
|
|
5
|
+
* Note: Svelte 5 modules cannot directly export $derived values.
|
|
6
|
+
* We use getter functions to expose reactive derived state.
|
|
7
|
+
*/
|
|
8
|
+
import type { AIMessage, AIConversation, AIContext, AITool, AIPanelConfig, AIEditSession, AISuggestion } from '../types';
|
|
9
|
+
export declare function getConversations(): AIConversation[];
|
|
10
|
+
export declare function getActiveConversationId(): string | null;
|
|
11
|
+
export declare function getActiveConversation(): AIConversation | null;
|
|
12
|
+
export declare function getMessages(): AIMessage[];
|
|
13
|
+
export declare function getTools(): AITool[];
|
|
14
|
+
export declare function getConfig(): AIPanelConfig;
|
|
15
|
+
export declare function getEditSessions(): AIEditSession[];
|
|
16
|
+
export declare function getActiveEditSessions(): AIEditSession[];
|
|
17
|
+
export declare function getSuggestions(): AISuggestion[];
|
|
18
|
+
export declare function getIsStreaming(): boolean;
|
|
19
|
+
export declare function getIsPanelOpen(): boolean;
|
|
20
|
+
export declare function getError(): string | null;
|
|
21
|
+
export declare const conversations: {
|
|
22
|
+
readonly current: AIConversation[];
|
|
23
|
+
};
|
|
24
|
+
export declare const activeConversationId: {
|
|
25
|
+
readonly current: string | null;
|
|
26
|
+
};
|
|
27
|
+
export declare const activeConversation: {
|
|
28
|
+
readonly current: AIConversation | null;
|
|
29
|
+
};
|
|
30
|
+
export declare const messages: {
|
|
31
|
+
readonly current: AIMessage[];
|
|
32
|
+
};
|
|
33
|
+
export declare const tools: {
|
|
34
|
+
readonly current: AITool[];
|
|
35
|
+
};
|
|
36
|
+
export declare const config: {
|
|
37
|
+
readonly current: AIPanelConfig;
|
|
38
|
+
};
|
|
39
|
+
export declare const editSessions: {
|
|
40
|
+
readonly current: AIEditSession[];
|
|
41
|
+
};
|
|
42
|
+
export declare const activeEditSessions: {
|
|
43
|
+
readonly current: AIEditSession[];
|
|
44
|
+
};
|
|
45
|
+
export declare const suggestions: {
|
|
46
|
+
readonly current: AISuggestion[];
|
|
47
|
+
};
|
|
48
|
+
export declare const isStreaming: {
|
|
49
|
+
readonly current: boolean;
|
|
50
|
+
};
|
|
51
|
+
export declare const isPanelOpen: {
|
|
52
|
+
readonly current: boolean;
|
|
53
|
+
};
|
|
54
|
+
export declare const error: {
|
|
55
|
+
readonly current: string | null;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Create a new conversation
|
|
59
|
+
*/
|
|
60
|
+
export declare function createConversation(title?: string, context?: AIContext): string;
|
|
61
|
+
/**
|
|
62
|
+
* Set active conversation
|
|
63
|
+
*/
|
|
64
|
+
export declare function setActiveConversation(conversationId: string | null): void;
|
|
65
|
+
/**
|
|
66
|
+
* Delete a conversation
|
|
67
|
+
*/
|
|
68
|
+
export declare function deleteConversation(conversationId: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Add a message to the active conversation
|
|
71
|
+
*/
|
|
72
|
+
export declare function addMessage(message: Omit<AIMessage, 'id' | 'timestamp'>): string;
|
|
73
|
+
/**
|
|
74
|
+
* Update a message (for streaming)
|
|
75
|
+
*/
|
|
76
|
+
export declare function updateMessage(messageId: string, updates: Partial<AIMessage>): void;
|
|
77
|
+
/**
|
|
78
|
+
* Send a user message and get AI response
|
|
79
|
+
*/
|
|
80
|
+
export declare function sendMessage(content: string, context?: AIContext): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Register a tool
|
|
83
|
+
*/
|
|
84
|
+
export declare function registerTool(tool: AITool): void;
|
|
85
|
+
/**
|
|
86
|
+
* Unregister a tool
|
|
87
|
+
*/
|
|
88
|
+
export declare function unregisterTool(toolName: string): void;
|
|
89
|
+
/**
|
|
90
|
+
* Update AI configuration
|
|
91
|
+
*/
|
|
92
|
+
export declare function updateConfig(updates: Partial<AIPanelConfig>): void;
|
|
93
|
+
/**
|
|
94
|
+
* Toggle AI panel visibility
|
|
95
|
+
*/
|
|
96
|
+
export declare function togglePanel(): void;
|
|
97
|
+
/**
|
|
98
|
+
* Open AI panel
|
|
99
|
+
*/
|
|
100
|
+
export declare function openPanel(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Close AI panel
|
|
103
|
+
*/
|
|
104
|
+
export declare function closePanel(): void;
|
|
105
|
+
/**
|
|
106
|
+
* Start an AI edit session
|
|
107
|
+
*/
|
|
108
|
+
export declare function startEditSession(conversationId: string, filePath: string, originalContent: string): string;
|
|
109
|
+
/**
|
|
110
|
+
* Update edit session status
|
|
111
|
+
*/
|
|
112
|
+
export declare function updateEditSession(sessionId: string, updates: Partial<AIEditSession>): void;
|
|
113
|
+
/**
|
|
114
|
+
* Complete an edit session
|
|
115
|
+
*/
|
|
116
|
+
export declare function completeEditSession(sessionId: string, proposedContent: string, diff?: string): void;
|
|
117
|
+
/**
|
|
118
|
+
* Apply or reject an edit session
|
|
119
|
+
*/
|
|
120
|
+
export declare function resolveEditSession(sessionId: string, apply: boolean): void;
|
|
121
|
+
/**
|
|
122
|
+
* Add a suggestion
|
|
123
|
+
*/
|
|
124
|
+
export declare function addSuggestion(suggestion: Omit<AISuggestion, 'id'>): string;
|
|
125
|
+
/**
|
|
126
|
+
* Remove a suggestion
|
|
127
|
+
*/
|
|
128
|
+
export declare function removeSuggestion(suggestionId: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Clear all suggestions
|
|
131
|
+
*/
|
|
132
|
+
export declare function clearSuggestions(): void;
|
|
133
|
+
/**
|
|
134
|
+
* Update conversation context
|
|
135
|
+
*/
|
|
136
|
+
export declare function updateContext(context: Partial<AIContext>): void;
|
|
137
|
+
/**
|
|
138
|
+
* Clear error state
|
|
139
|
+
*/
|
|
140
|
+
export declare function clearError(): void;
|