@eclipse-docks/extension-rag-system 0.7.122 → 0.7.124
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/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ extensionRegistry.registerExtension({
|
|
|
9
9
|
id: pkg.name,
|
|
10
10
|
name: t.EXT_RAG_SYSTEM_NAME,
|
|
11
11
|
description: t.EXT_RAG_SYSTEM_DESC,
|
|
12
|
-
loader: () => import("./rag-system-extension-
|
|
12
|
+
loader: () => import("./rag-system-extension-tTT5Pglo.js"),
|
|
13
13
|
icon: "database",
|
|
14
14
|
experimental: true,
|
|
15
15
|
dependencies: ["@eclipse-docks/extension-ai-system", "@eclipse-docks/extension-in-browser-ml"]
|
|
@@ -276,7 +276,7 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
276
276
|
this.searchQuery = "";
|
|
277
277
|
await this.updateFilteredDocuments();
|
|
278
278
|
}}
|
|
279
|
-
size="
|
|
279
|
+
size="s"
|
|
280
280
|
with-clear
|
|
281
281
|
autocomplete="off"
|
|
282
282
|
style="flex: 1; max-width: 400px;">
|
|
@@ -289,7 +289,7 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
289
289
|
this.filterByActiveWorkspace = e.target.checked;
|
|
290
290
|
await this.loadDocuments();
|
|
291
291
|
}}
|
|
292
|
-
size="
|
|
292
|
+
size="s">
|
|
293
293
|
Active workspace only
|
|
294
294
|
</wa-switch>
|
|
295
295
|
|
|
@@ -300,7 +300,7 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
300
300
|
this.filterWorkspace = e.target.value || null;
|
|
301
301
|
await this.updateFilteredDocuments();
|
|
302
302
|
}}
|
|
303
|
-
size="
|
|
303
|
+
size="s"
|
|
304
304
|
style="width: 200px;">
|
|
305
305
|
<wa-option value="">All Workspaces</wa-option>
|
|
306
306
|
${workspaces.map((ws) => html`
|
|
@@ -310,7 +310,7 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
310
310
|
` : nothing}
|
|
311
311
|
|
|
312
312
|
<docks-command
|
|
313
|
-
size="
|
|
313
|
+
size="s"
|
|
314
314
|
icon="arrow-rotate-right"
|
|
315
315
|
title="Refresh document list"
|
|
316
316
|
.action=${() => this.loadDocuments()}
|
|
@@ -319,7 +319,7 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
319
319
|
</docks-command>
|
|
320
320
|
|
|
321
321
|
<docks-command
|
|
322
|
-
size="
|
|
322
|
+
size="s"
|
|
323
323
|
icon="database"
|
|
324
324
|
title="Re-index all documents"
|
|
325
325
|
.action=${() => this.reindexAllDocuments()}
|
|
@@ -384,7 +384,7 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
384
384
|
<wa-button
|
|
385
385
|
variant="neutral"
|
|
386
386
|
appearance="plain"
|
|
387
|
-
size="
|
|
387
|
+
size="s"
|
|
388
388
|
title="Reindex"
|
|
389
389
|
@click=${() => this.reindexDocument(doc)}>
|
|
390
390
|
<wa-icon name="arrow-rotate-right"></wa-icon>
|
|
@@ -392,7 +392,7 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
392
392
|
<wa-button
|
|
393
393
|
variant="danger"
|
|
394
394
|
appearance="plain"
|
|
395
|
-
size="
|
|
395
|
+
size="s"
|
|
396
396
|
title="Delete"
|
|
397
397
|
@click=${() => this.deleteDocument(doc)}>
|
|
398
398
|
<wa-icon name="trash"></wa-icon>
|
|
@@ -413,11 +413,11 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
413
413
|
label="File Path"
|
|
414
414
|
.value=${this.selectedDocument.filePath}
|
|
415
415
|
readonly
|
|
416
|
-
size="
|
|
416
|
+
size="s">
|
|
417
417
|
<wa-copy-button
|
|
418
418
|
slot="end"
|
|
419
419
|
.value=${this.selectedDocument.filePath}
|
|
420
|
-
size="
|
|
420
|
+
size="s"
|
|
421
421
|
label="Copy file path">
|
|
422
422
|
</wa-copy-button>
|
|
423
423
|
</wa-input>
|
|
@@ -426,11 +426,11 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
426
426
|
label="Workspace"
|
|
427
427
|
.value=${this.selectedDocument.workspacePath}
|
|
428
428
|
readonly
|
|
429
|
-
size="
|
|
429
|
+
size="s">
|
|
430
430
|
<wa-copy-button
|
|
431
431
|
slot="end"
|
|
432
432
|
.value=${this.selectedDocument.workspacePath}
|
|
433
|
-
size="
|
|
433
|
+
size="s"
|
|
434
434
|
label="Copy workspace">
|
|
435
435
|
</wa-copy-button>
|
|
436
436
|
</wa-input>
|
|
@@ -439,11 +439,11 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
439
439
|
label="File Type"
|
|
440
440
|
.value=${this.selectedDocument.fileType}
|
|
441
441
|
readonly
|
|
442
|
-
size="
|
|
442
|
+
size="s">
|
|
443
443
|
<wa-copy-button
|
|
444
444
|
slot="end"
|
|
445
445
|
.value=${this.selectedDocument.fileType}
|
|
446
|
-
size="
|
|
446
|
+
size="s"
|
|
447
447
|
label="Copy file type">
|
|
448
448
|
</wa-copy-button>
|
|
449
449
|
</wa-input>
|
|
@@ -452,11 +452,11 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
452
452
|
label="Size"
|
|
453
453
|
.value=${this.formatFileSize(this.selectedDocument.metadata.size)}
|
|
454
454
|
readonly
|
|
455
|
-
size="
|
|
455
|
+
size="s">
|
|
456
456
|
<wa-copy-button
|
|
457
457
|
slot="end"
|
|
458
458
|
.value=${this.formatFileSize(this.selectedDocument.metadata.size)}
|
|
459
|
-
size="
|
|
459
|
+
size="s"
|
|
460
460
|
label="Copy size">
|
|
461
461
|
</wa-copy-button>
|
|
462
462
|
</wa-input>
|
|
@@ -465,11 +465,11 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
465
465
|
label="Indexed At"
|
|
466
466
|
.value=${this.formatDate(this.selectedDocument.indexedAt)}
|
|
467
467
|
readonly
|
|
468
|
-
size="
|
|
468
|
+
size="s">
|
|
469
469
|
<wa-copy-button
|
|
470
470
|
slot="end"
|
|
471
471
|
.value=${this.formatDate(this.selectedDocument.indexedAt)}
|
|
472
|
-
size="
|
|
472
|
+
size="s"
|
|
473
473
|
label="Copy indexed date">
|
|
474
474
|
</wa-copy-button>
|
|
475
475
|
</wa-input>
|
|
@@ -478,11 +478,11 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
478
478
|
label="Last Updated"
|
|
479
479
|
.value=${this.formatDate(this.selectedDocument.updatedAt)}
|
|
480
480
|
readonly
|
|
481
|
-
size="
|
|
481
|
+
size="s">
|
|
482
482
|
<wa-copy-button
|
|
483
483
|
slot="end"
|
|
484
484
|
.value=${this.formatDate(this.selectedDocument.updatedAt)}
|
|
485
|
-
size="
|
|
485
|
+
size="s"
|
|
486
486
|
label="Copy updated date">
|
|
487
487
|
</wa-copy-button>
|
|
488
488
|
</wa-input>
|
|
@@ -494,11 +494,11 @@ var DocksRAGSystemManager = class DocksRAGSystemManager extends DocksPart {
|
|
|
494
494
|
label="Tags"
|
|
495
495
|
.value=${this.selectedDocument.metadata.tags.join(", ")}
|
|
496
496
|
readonly
|
|
497
|
-
size="
|
|
497
|
+
size="s">
|
|
498
498
|
<wa-copy-button
|
|
499
499
|
slot="end"
|
|
500
500
|
.value=${this.selectedDocument.metadata.tags.join(", ")}
|
|
501
|
-
size="
|
|
501
|
+
size="s"
|
|
502
502
|
label="Copy tags">
|
|
503
503
|
</wa-copy-button>
|
|
504
504
|
</wa-input>
|
|
@@ -1029,4 +1029,4 @@ function ragSystemExtension(context) {
|
|
|
1029
1029
|
//#endregion
|
|
1030
1030
|
export { ragSystemExtension as default };
|
|
1031
1031
|
|
|
1032
|
-
//# sourceMappingURL=rag-system-extension-
|
|
1032
|
+
//# sourceMappingURL=rag-system-extension-tTT5Pglo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rag-system-extension-tTT5Pglo.js","names":[],"sources":["../src/rag-system-manager.ts","../src/rag-system-extension.ts"],"sourcesContent":["import { customElement, property, state } from 'lit/decorators.js';\nimport { css, html, TemplateResult, nothing } from 'lit';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { DocksPart } from '@eclipse-docks/core';\nimport { EditorInput } from '@eclipse-docks/core';\nimport { documentIndexService, IndexedDocument } from './document-index-service';\nimport { searchWorkspaceDocuments, RAGSearchResult } from './rag-service';\nimport { workspaceService, File } from '@eclipse-docks/core';\nimport { createLogger } from '@eclipse-docks/core';\nimport { getWorkspacePath } from './utils/workspace-utils';\nimport { SnippetExtractor } from './utils/snippet-extractor';\nimport { CONTENT_PREVIEW_LENGTHS, SNIPPET_LENGTHS } from './utils/constants';\nimport { toastError, toastInfo } from '@eclipse-docks/core';\nimport { taskService } from '@eclipse-docks/core';\nimport { editorRegistry } from '@eclipse-docks/core';\n\nconst logger = createLogger('RAGSystemManager');\nconst snippetExtractor = new SnippetExtractor();\n\n@customElement('docks-rag-system-manager')\nexport class DocksRAGSystemManager extends DocksPart {\n @property({ attribute: false })\n public input?: EditorInput;\n\n @state()\n private documents: IndexedDocument[] = [];\n\n\n @state()\n private stats: { totalDocuments: number; byWorkspace: Record<string, number> } = {\n totalDocuments: 0,\n byWorkspace: {}\n };\n\n @state()\n private loading = false;\n\n @state()\n private selectedDocument: IndexedDocument | null = null;\n\n @state()\n private searchQuery = '';\n\n @state()\n private filterWorkspace: string | null = null;\n\n @state()\n private filterByActiveWorkspace = true;\n\n @state()\n private filteredDocuments: IndexedDocument[] = [];\n \n @state()\n private searchResults: Map<string, RAGSearchResult> = new Map();\n\n @state()\n private reindexing = false;\n\n private treeRef = createRef<HTMLElement>();\n private searchDebounceTimer?: number;\n private searchInputValue = '';\n\n protected async doInitUI() {\n try {\n await documentIndexService.initialize();\n await Promise.all([\n this.loadDocuments(),\n this.loadStats()\n ]);\n } catch (error) {\n logger.error(`Failed to initialize document index manager: ${error}`);\n toastError(`Failed to initialize: ${error}`);\n }\n }\n\n private async loadDocuments() {\n this.loading = true;\n this.requestUpdate();\n try {\n let workspacePath: string | undefined;\n if (this.filterByActiveWorkspace) {\n const workspaceResult = await getWorkspacePath();\n workspacePath = workspaceResult?.workspacePath;\n }\n this.documents = await documentIndexService.listDocuments(workspacePath);\n await this.updateFilteredDocuments();\n } catch (error) {\n logger.error(`Failed to load documents: ${error}`);\n toastError(`Failed to load documents: ${error}`);\n } finally {\n this.loading = false;\n }\n }\n\n private async updateFilteredDocuments() {\n this.filteredDocuments = await this.getFilteredDocuments();\n this.requestUpdate();\n }\n\n private async loadStats() {\n try {\n this.stats = await documentIndexService.getStats();\n this.requestUpdate();\n } catch (error) {\n logger.error(`Failed to load stats: ${error}`);\n }\n }\n\n private handleTreeSelection(e: CustomEvent) {\n // Try getting from event detail first (as per extensions pattern)\n let selection = e.detail?.selection || [];\n\n // If no selection in detail, try getting from tree element directly (as per docks-filebrowser pattern)\n if (selection.length === 0 && this.treeRef.value) {\n // @ts-ignore\n selection = this.treeRef.value.selectedItems || [];\n }\n\n if (selection.length > 0) {\n const selectedItem = selection[0];\n if (selectedItem?.model) {\n this.selectedDocument = selectedItem.model;\n } else {\n this.selectedDocument = null;\n }\n } else {\n this.selectedDocument = null;\n }\n }\n\n private async getFilteredDocuments(): Promise<IndexedDocument[]> {\n if (!this.documents || this.documents.length === 0) {\n return [];\n }\n\n if (this.searchQuery.trim()) {\n try {\n const searchResults = await searchWorkspaceDocuments(this.searchQuery, {\n limit: 50,\n workspacePath: this.filterWorkspace || undefined\n });\n\n this.searchResults.clear();\n const uniqueDocs = new Map<string, IndexedDocument>();\n const aggregatedResults = new Map<string, RAGSearchResult>();\n \n for (const result of searchResults) {\n const docId = result.document.id;\n uniqueDocs.set(docId, result.document);\n \n const existing = aggregatedResults.get(docId);\n if (!existing) {\n aggregatedResults.set(docId, {\n document: result.document,\n relevance: result.relevance,\n matchedSnippets: [...result.matchedSnippets]\n });\n } else {\n if (result.relevance > existing.relevance) {\n existing.relevance = result.relevance;\n }\n const seenSnippets = new Set(existing.matchedSnippets);\n for (const snippet of result.matchedSnippets) {\n if (!seenSnippets.has(snippet)) {\n existing.matchedSnippets.push(snippet);\n seenSnippets.add(snippet);\n }\n }\n }\n }\n \n for (const [docId, result] of aggregatedResults) {\n this.searchResults.set(docId, result);\n }\n\n const resultDocs = Array.from(uniqueDocs.values());\n \n if (this.filterWorkspace) {\n return resultDocs.filter(doc => doc.workspacePath === this.filterWorkspace);\n }\n \n return resultDocs;\n } catch (error) {\n logger.debug(`RAG search failed in document manager: ${error}`);\n this.searchResults.clear();\n return [];\n }\n } else {\n this.searchResults.clear();\n }\n\n let filtered = [...this.documents];\n\n if (this.filterWorkspace) {\n filtered = filtered.filter(doc => doc.workspacePath === this.filterWorkspace);\n }\n\n return filtered;\n }\n\n private highlightMatches(text: string, query: string): TemplateResult {\n if (!query || !query.trim()) {\n return html`${text}`;\n }\n\n const queryLower = query.toLowerCase();\n const textLower = text.toLowerCase();\n const parts: Array<string | TemplateResult> = [];\n let lastIndex = 0;\n let index = textLower.indexOf(queryLower, lastIndex);\n\n while (index !== -1) {\n if (index > lastIndex) {\n parts.push(text.substring(lastIndex, index));\n }\n parts.push(html`<mark class=\"search-match\">${text.substring(index, index + query.length)}</mark>`);\n lastIndex = index + query.length;\n index = textLower.indexOf(queryLower, lastIndex);\n }\n\n if (lastIndex < text.length) {\n parts.push(text.substring(lastIndex));\n }\n\n return html`${parts}`;\n }\n\n private getContentPreview(doc: IndexedDocument): TemplateResult {\n const searchResult = this.searchResults.get(doc.id);\n \n if (searchResult && searchResult.matchedSnippets.length > 0) {\n return html`\n <table class=\"snippets-table\">\n <thead>\n <tr>\n <th class=\"snippet-number-col\">#</th>\n <th class=\"snippet-content-col\">Content</th>\n </tr>\n </thead>\n <tbody>\n ${searchResult.matchedSnippets.map((snippet, idx) => html`\n <tr>\n <td class=\"snippet-number\">${idx + 1}</td>\n <td class=\"snippet-content\">${this.highlightMatches(snippet, this.searchQuery)}</td>\n </tr>\n `)}\n </tbody>\n </table>\n `;\n }\n\n if (this.searchQuery && this.searchQuery.trim()) {\n const snippets = snippetExtractor.extractContextSnippets(\n doc.content,\n this.searchQuery,\n SNIPPET_LENGTHS.CONTEXT\n );\n\n if (snippets.length > 0) {\n return html`\n <table class=\"snippets-table\">\n <thead>\n <tr>\n <th class=\"snippet-number-col\">#</th>\n <th class=\"snippet-content-col\">Content</th>\n </tr>\n </thead>\n <tbody>\n ${snippets.map((snippet, idx) => html`\n <tr>\n <td class=\"snippet-number\">${idx + 1}</td>\n <td class=\"snippet-content\">${this.highlightMatches(doc.content.substring(snippet.start, snippet.end), this.searchQuery)}</td>\n </tr>\n `)}\n </tbody>\n </table>\n `;\n }\n }\n\n const preview = snippetExtractor.extractSimpleSnippet(doc.content, CONTENT_PREVIEW_LENGTHS.LONG);\n return html`\n <div class=\"snippet-preview\">${preview}</div>\n `;\n }\n\n private async deleteDocument(doc: IndexedDocument) {\n try {\n await documentIndexService.deleteDocument(doc.id);\n toastInfo(`Deleted: ${doc.fileName}`);\n await this.loadDocuments();\n await this.loadStats();\n if (this.selectedDocument?.id === doc.id) {\n this.selectedDocument = null;\n }\n } catch (error) {\n toastError(`Failed to delete document: ${error}`);\n }\n }\n\n private async reindexDocument(doc: IndexedDocument) {\n try {\n const workspaceResult = await getWorkspacePath();\n if (!workspaceResult) {\n toastError('No workspace connected');\n return;\n }\n\n const resource = await workspaceResult.workspace.getResource(doc.filePath);\n if (!resource) {\n toastError(`File not found: ${doc.filePath}`);\n return;\n }\n\n if (!(resource instanceof File)) {\n toastError(`Resource is not a file: ${doc.filePath}`);\n return;\n }\n\n const file: File = resource;\n\n await taskService.runAsync('Reindexing document', async progress => {\n progress.message = `Reindexing ${doc.fileName}...`;\n await documentIndexService.reindexDocument(file);\n progress.progress = 100;\n });\n\n toastInfo(`Reindexed: ${doc.fileName}`);\n await this.loadDocuments();\n if (this.selectedDocument?.id === doc.id) {\n this.selectedDocument = await documentIndexService.getDocument(doc.id);\n }\n } catch (error) {\n toastError(`Failed to reindex document: ${error}`);\n }\n }\n\n private async reindexAllDocuments() {\n if (this.reindexing) {\n return;\n }\n\n const stats = await documentIndexService.getStats();\n if (stats.totalDocuments === 0) {\n toastInfo('No documents to reindex');\n return;\n }\n\n this.reindexing = true;\n this.requestUpdate();\n\n try {\n const result = await taskService.runAsync('Reindexing all documents', async progress => {\n progress.message = 'Starting reindexing...';\n \n const total = stats.totalDocuments;\n\n const reindexResult = await documentIndexService.reindexAllDocuments();\n \n const processed = reindexResult.succeeded + reindexResult.failed;\n progress.progress = total > 0 ? (processed / total) * 100 : 100;\n progress.message = `Reindexed ${reindexResult.succeeded}/${total} documents${reindexResult.failed > 0 ? ` (${reindexResult.failed} failed)` : ''}`;\n \n return reindexResult;\n });\n\n await this.loadDocuments();\n await this.loadStats();\n toastInfo(`Reindexing completed: ${result.succeeded} succeeded, ${result.failed} failed`);\n } catch (error) {\n logger.error(`Failed to reindex all documents: ${error}`);\n toastError(`Failed to reindex all documents: ${error}`);\n } finally {\n this.reindexing = false;\n this.requestUpdate();\n }\n }\n\n private formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} MiB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n\n private formatDate(timestamp: number): string {\n return new Date(timestamp).toLocaleString();\n }\n\n private getFileIcon(fileType: string): string {\n return editorRegistry.getFileIcon(fileType);\n }\n\n protected renderToolbar(): TemplateResult {\n const workspaces = Object.keys(this.stats?.byWorkspace || {});\n\n return html`\n <wa-input\n type=\"search\"\n placeholder=\"Search documents...\"\n .value=${this.searchInputValue}\n @input=${(e: any) => {\n this.searchInputValue = e.target.value;\n \n if (this.searchDebounceTimer) {\n clearTimeout(this.searchDebounceTimer);\n }\n \n this.searchDebounceTimer = window.setTimeout(async () => {\n this.searchQuery = this.searchInputValue;\n await this.updateFilteredDocuments();\n }, 200);\n }}\n @wa-clear=${async () => {\n if (this.searchDebounceTimer) {\n clearTimeout(this.searchDebounceTimer);\n }\n this.searchInputValue = '';\n this.searchQuery = '';\n await this.updateFilteredDocuments();\n }}\n size=\"s\"\n with-clear\n autocomplete=\"off\"\n style=\"flex: 1; max-width: 400px;\">\n <wa-icon name=\"magnifying-glass\" slot=\"start\"></wa-icon>\n </wa-input>\n \n <wa-switch\n .checked=${this.filterByActiveWorkspace}\n @change=${async (e: any) => {\n this.filterByActiveWorkspace = e.target.checked;\n await this.loadDocuments();\n }}\n size=\"s\">\n Active workspace only\n </wa-switch>\n \n ${workspaces.length > 1 ? html`\n <wa-select \n .value=${this.filterWorkspace || ''}\n @change=${async (e: any) => {\n this.filterWorkspace = e.target.value || null;\n await this.updateFilteredDocuments();\n }}\n size=\"s\"\n style=\"width: 200px;\">\n <wa-option value=\"\">All Workspaces</wa-option>\n ${workspaces.map(ws => html`\n <wa-option value=\"${ws}\">${ws} (${this.stats.byWorkspace[ws]})</wa-option>\n `)}\n </wa-select>\n ` : nothing}\n \n <docks-command \n size=\"s\" \n icon=\"arrow-rotate-right\"\n title=\"Refresh document list\"\n .action=${() => this.loadDocuments()}\n ?disabled=${this.reindexing}>\n Refresh\n </docks-command>\n \n <docks-command \n size=\"s\" \n icon=\"database\"\n title=\"Re-index all documents\"\n .action=${() => this.reindexAllDocuments()}\n ?disabled=${this.reindexing || this.loading}>\n ${this.reindexing ? 'Reindexing...' : 'Re-index All'}\n </docks-command>\n `;\n }\n\n protected renderContent(): TemplateResult {\n if (!this.stats) {\n this.stats = { totalDocuments: 0, byWorkspace: {} };\n }\n\n const filteredDocs = this.filteredDocuments;\n const workspaces = Object.keys(this.stats.byWorkspace || {});\n\n return html`\n <div class=\"rag-system-manager\">\n <div class=\"header\">\n <div class=\"header-content\">\n <div class=\"stats\">\n <span>Total: ${this.stats.totalDocuments} documents</span>\n ${workspaces.length > 0 ? html`\n <span>Workspaces: ${workspaces.length}</span>\n ` : nothing}\n </div>\n </div>\n </div>\n\n <wa-split-panel position=\"40\" style=\"height: 100%;\">\n <div class=\"document-list\" slot=\"start\">\n ${this.loading ? html`\n <div class=\"loading\">\n <wa-spinner></wa-spinner>\n <span>Loading documents...</span>\n </div>\n ` : filteredDocs.length === 0 ? html`\n <div class=\"empty\">\n <wa-icon name=\"inbox\" style=\"font-size: 3rem; opacity: 0.3;\"></wa-icon>\n <p>${this.searchQuery || this.filterWorkspace ? 'No documents match your filters' : 'No documents indexed yet'}</p>\n </div>\n ` : html`\n <wa-tree \n ${ref(this.treeRef)}\n selection=\"leaf\"\n style=\"--indent-guide-width: 1px;\"\n @wa-selection-change=${(e: CustomEvent) => {\n this.handleTreeSelection(e);\n }}>\n ${filteredDocs.map(doc => html`\n <wa-tree-item \n .model=${doc}\n ?selected=${this.selectedDocument?.id === doc.id}>\n <wa-icon name=\"${this.getFileIcon(doc.fileType)}\"></wa-icon>\n <div class=\"tree-item-info\">\n <strong class=\"tree-item-path\">${doc.filePath}</strong>\n <div class=\"tree-item-meta\">\n <small class=\"meta-size\">${this.formatFileSize(doc.metadata.size)}</small>\n <small class=\"meta-date\">${this.formatDate(doc.indexedAt)}</small>\n </div>\n </div>\n <div class=\"tree-item-actions\" @click=${(e: Event) => e.stopPropagation()}>\n <wa-button\n variant=\"neutral\"\n appearance=\"plain\"\n size=\"s\"\n title=\"Reindex\"\n @click=${() => this.reindexDocument(doc)}>\n <wa-icon name=\"arrow-rotate-right\"></wa-icon>\n </wa-button>\n <wa-button\n variant=\"danger\"\n appearance=\"plain\"\n size=\"s\"\n title=\"Delete\"\n @click=${() => this.deleteDocument(doc)}>\n <wa-icon name=\"trash\"></wa-icon>\n </wa-button>\n </div>\n </wa-tree-item>\n `)}\n </wa-tree>\n `}\n </div>\n\n <div slot=\"end\">\n ${this.selectedDocument ? html`\n <div class=\"document-details\">\n <div class=\"details-content\">\n <div class=\"metadata-grid\">\n <wa-input\n label=\"File Path\"\n .value=${this.selectedDocument.filePath}\n readonly\n size=\"s\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.selectedDocument.filePath}\n size=\"s\"\n label=\"Copy file path\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"Workspace\"\n .value=${this.selectedDocument.workspacePath}\n readonly\n size=\"s\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.selectedDocument.workspacePath}\n size=\"s\"\n label=\"Copy workspace\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"File Type\"\n .value=${this.selectedDocument.fileType}\n readonly\n size=\"s\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.selectedDocument.fileType}\n size=\"s\"\n label=\"Copy file type\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"Size\"\n .value=${this.formatFileSize(this.selectedDocument.metadata.size)}\n readonly\n size=\"s\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.formatFileSize(this.selectedDocument.metadata.size)}\n size=\"s\"\n label=\"Copy size\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"Indexed At\"\n .value=${this.formatDate(this.selectedDocument.indexedAt)}\n readonly\n size=\"s\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.formatDate(this.selectedDocument.indexedAt)}\n size=\"s\"\n label=\"Copy indexed date\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"Last Updated\"\n .value=${this.formatDate(this.selectedDocument.updatedAt)}\n readonly\n size=\"s\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.formatDate(this.selectedDocument.updatedAt)}\n size=\"s\"\n label=\"Copy updated date\">\n </wa-copy-button>\n </wa-input>\n </div>\n \n ${this.selectedDocument.metadata.tags && this.selectedDocument.metadata.tags.length > 0 ? html`\n <div class=\"tags-section\">\n <wa-input\n label=\"Tags\"\n .value=${this.selectedDocument.metadata.tags.join(', ')}\n readonly\n size=\"s\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.selectedDocument.metadata.tags.join(', ')}\n size=\"s\"\n label=\"Copy tags\">\n </wa-copy-button>\n </wa-input>\n </div>\n ` : nothing}\n \n <div class=\"detail-section\">\n <label>Content Preview${this.searchQuery ? html` <span class=\"search-hint\">(showing matches for \"${this.searchQuery}\")</span>` : nothing}</label>\n <wa-scroller class=\"content-preview\" orientation=\"vertical\">\n <div class=\"content-preview-inner\">\n ${this.getContentPreview(this.selectedDocument)}\n </div>\n </wa-scroller>\n </div>\n </div>\n </div>\n ` : html`\n <div class=\"document-details empty\">\n <wa-icon name=\"file-lines\" style=\"font-size: 3rem; opacity: 0.3;\"></wa-icon>\n <p>Select a document to view details</p>\n </div>\n `}\n </div>\n </wa-split-panel>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n min-height: 0;\n }\n\n .rag-system-manager {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n }\n\n wa-split-panel {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }\n\n .document-list {\n height: 100%;\n overflow-y: auto;\n }\n\n .tree-item-info {\n flex: 1;\n min-width: 0;\n }\n\n .tree-item-path {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tree-item-meta {\n display: flex;\n align-items: center;\n gap: var(--wa-space-xs);\n flex-wrap: wrap;\n margin-top: var(--wa-space-xs);\n }\n\n .tree-item-actions {\n opacity: 0;\n }\n\n wa-tree-item:hover .tree-item-actions {\n opacity: 1;\n }\n\n .document-details {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n }\n\n .details-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: var(--wa-space-s);\n min-height: 0;\n overflow: hidden;\n }\n\n .metadata-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--wa-space-s);\n flex-shrink: 0;\n }\n\n .tags-section {\n margin-top: var(--wa-space-s);\n flex-shrink: 0;\n margin-bottom: var(--wa-space-s);\n }\n\n .detail-section {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n position: relative;\n }\n\n .detail-section label {\n flex-shrink: 0;\n margin-bottom: var(--wa-space-xs);\n }\n\n .content-preview {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n bottom: 0;\n }\n\n .content-preview-inner {\n width: 100%;\n }\n\n .snippets-table {\n width: 100%;\n border-collapse: collapse;\n background-color: var(--wa-color-surface-raised);\n }\n\n .snippets-table thead {\n background-color: var(--wa-color-neutral-fill-quiet);\n }\n\n .snippets-table th {\n padding: var(--wa-space-xs) var(--wa-space-s);\n text-align: left;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--wa-color-text-quiet);\n border-bottom: 1px solid var(--wa-color-surface-border);\n }\n\n .snippets-table td {\n padding: var(--wa-space-s);\n border-bottom: 1px solid var(--wa-color-surface-border);\n vertical-align: top;\n }\n\n .snippets-table tbody tr:last-child td {\n border-bottom: none;\n }\n\n .snippets-table tbody tr:hover {\n background-color: var(--wa-color-neutral-fill-quiet);\n }\n\n .snippet-number-col {\n width: 3rem;\n text-align: center;\n }\n\n .snippet-content-col {\n width: auto;\n }\n\n .snippet-number {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--wa-color-text-quiet);\n text-align: center;\n }\n\n .snippet-content {\n white-space: pre-wrap;\n word-wrap: breaword;\n overflow-wrap: breaword;\n font-family: monospace;\n font-size: 0.875rem;\n line-height: 1.5;\n color: var(--wa-color-text-normal);\n }\n\n .snippet-preview {\n white-space: pre-wrap;\n word-wrap: breaword;\n overflow-wrap: breaword;\n font-family: monospace;\n font-size: 0.875rem;\n line-height: 1.5;\n color: var(--wa-color-text-normal);\n padding: var(--wa-space-s);\n background-color: var(--wa-color-surface-raised);\n border-radius: var(--wa-border-radius-medium);\n }\n\n .snippet-content mark.search-match {\n background: var(--wa-color-warning-fill-loud);\n color: var(--wa-color-warning-text-loud);\n padding: 0 2px;\n border-radius: 2px;\n font-weight: 600;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-rag-system-manager': DocksRAGSystemManager;\n }\n}\n\n","import { documentIndexService } from './document-index-service';\nimport { registerAll } from '@eclipse-docks/core';\nimport { workspaceService, File } from '@eclipse-docks/core';\nimport { toastError, toastInfo } from '@eclipse-docks/core';\nimport { taskService } from '@eclipse-docks/core';\nimport { activeSelectionSignal } from '@eclipse-docks/core';\nimport { createLogger } from '@eclipse-docks/core';\nimport { contributionRegistry } from '@eclipse-docks/core';\nimport { editorRegistry, EditorInput } from '@eclipse-docks/core';\nimport { html } from 'lit';\nimport { TOOLBAR_MAIN_RIGHT } from '@eclipse-docks/core';\n// Import the component to ensure it's registered\nimport './rag-system-manager';\n\nconst logger = createLogger('RAGSystemExtension');\n\nexport default function ragSystemExtension(context: any) {\n documentIndexService.initialize().catch(err => {\n logger.error(`Failed to initialize document index service: ${err}`);\n });\n\n registerAll({\n command: {\n id: 'rag-system.index-file',\n name: 'Index Document',\n description: 'Index the currently selected file for search and retrieval',\n parameters: [\n {\n name: 'includeContent',\n description: 'Whether to include full content in index (default: true)',\n required: false\n }\n ]\n },\n handler: {\n canExecute: context => {\n const selection = activeSelectionSignal.get();\n return selection instanceof File;\n },\n execute: async context => {\n const selection = activeSelectionSignal.get();\n \n if (!(selection instanceof File)) {\n toastError('Please select a file to index');\n return;\n }\n\n const includeContent = context.params?.includeContent !== false;\n\n await taskService.runAsync('Indexing document', async progress => {\n progress.message = `Indexing ${selection.getName()}...`;\n \n try {\n const document = await documentIndexService.indexDocument(selection, {\n includeContent\n });\n \n progress.progress = 100;\n toastInfo(`Document indexed: ${document.fileName}`);\n } catch (error) {\n toastError(`Failed to index document: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.index-workspace',\n name: 'Index Workspace',\n description: 'Index all indexable files in the current workspace',\n parameters: [\n {\n name: 'includeContent',\n description: 'Whether to include full content in index (default: true)',\n required: false\n },\n {\n name: 'maxFileSize',\n description: 'Maximum file size in bytes to index (default: 5MB)',\n required: false\n }\n ]\n },\n handler: {\n canExecute: context => {\n return true;\n },\n execute: async context => {\n const workspace = await workspaceService.getWorkspace();\n \n if (!workspace) {\n toastError('No workspace selected');\n return;\n }\n\n const includeContent = context.params?.includeContent !== false;\n const maxFileSize = context.params?.maxFileSize \n ? parseInt(context.params.maxFileSize) \n : undefined;\n\n await taskService.runAsync('Indexing workspace', async progress => {\n progress.message = 'Collecting files...';\n progress.progress = 0;\n\n try {\n const result = await documentIndexService.indexWorkspace(workspace, {\n includeContent,\n maxFileSize\n });\n\n progress.progress = 100;\n \n if (result.failed > 0) {\n toastError(\n `Indexing complete: ${result.indexed} indexed, ${result.failed} failed. ` +\n `Check console for details.`\n );\n } else {\n toastInfo(`Workspace indexed: ${result.indexed} documents`);\n }\n } catch (error) {\n toastError(`Failed to index workspace: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.list-documents',\n name: 'List Indexed Documents',\n description: 'List all indexed documents in the current workspace',\n parameters: []\n },\n handler: {\n canExecute: context => {\n return true;\n },\n execute: async context => {\n const workspace = await workspaceService.getWorkspace();\n const workspacePath = workspace?.getName();\n\n await taskService.runAsync('Loading indexed documents', async progress => {\n try {\n const documents = await documentIndexService.listDocuments(workspacePath);\n \n progress.progress = 100;\n \n if (documents.length === 0) {\n toastInfo('No documents indexed in this workspace');\n } else {\n logger.info(`Found ${documents.length} indexed documents`);\n toastInfo(`Found ${documents.length} indexed documents (check console for details)`);\n }\n } catch (error) {\n toastError(`Failed to list documents: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.delete-document',\n name: 'Delete Document from Index',\n description: 'Remove the selected file from the document index',\n parameters: []\n },\n handler: {\n canExecute: context => {\n const selection = activeSelectionSignal.get();\n return selection instanceof File;\n },\n execute: async context => {\n const selection = activeSelectionSignal.get();\n \n if (!(selection instanceof File)) {\n toastError('Please select a file to remove from index');\n return;\n }\n\n const workspace = selection.getWorkspace();\n const workspacePath = workspace.getName();\n const filePath = selection.getWorkspacePath();\n\n await taskService.runAsync('Deleting document from index', async progress => {\n try {\n const deleted = await documentIndexService.deleteDocumentByPath(\n workspacePath,\n filePath\n );\n\n progress.progress = 100;\n\n if (deleted) {\n toastInfo(`Document removed from index: ${selection.getName()}`);\n } else {\n toastInfo(`Document not found in index: ${selection.getName()}`);\n }\n } catch (error) {\n toastError(`Failed to delete document from index: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.clear-workspace',\n name: 'Clear Workspace Index',\n description: 'Remove all indexed documents from the current workspace',\n parameters: []\n },\n handler: {\n canExecute: context => {\n return true;\n },\n execute: async context => {\n const workspace = await workspaceService.getWorkspace();\n \n if (!workspace) {\n toastError('No workspace selected');\n return;\n }\n\n const workspacePath = workspace.getName();\n\n await taskService.runAsync('Clearing workspace index', async progress => {\n try {\n const deleted = await documentIndexService.deleteWorkspace(workspacePath);\n\n progress.progress = 100;\n toastInfo(`Removed ${deleted} documents from index`);\n } catch (error) {\n toastError(`Failed to clear workspace index: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.get-stats',\n name: 'Document Index Statistics',\n description: 'Get statistics about the document index',\n parameters: []\n },\n handler: {\n canExecute: context => {\n return true;\n },\n execute: async context => {\n await taskService.runAsync('Loading statistics', async progress => {\n try {\n const stats = await documentIndexService.getStats();\n \n progress.progress = 100;\n \n logger.info(`Document index statistics: ${JSON.stringify(stats)}`);\n toastInfo(\n `Index statistics: ${stats.totalDocuments} total documents. ` +\n `Check console for details.`\n );\n } catch (error) {\n toastError(`Failed to get statistics: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.reindex-file',\n name: 'Reindex Document',\n description: 'Reindex the selected file (useful after file changes)',\n parameters: []\n },\n handler: {\n canExecute: context => {\n const selection = activeSelectionSignal.get();\n return selection instanceof File;\n },\n execute: async context => {\n const selection = activeSelectionSignal.get();\n \n if (!(selection instanceof File)) {\n toastError('Please select a file to reindex');\n return;\n }\n\n await taskService.runAsync('Reindexing document', async progress => {\n progress.message = `Reindexing ${selection.getName()}...`;\n \n try {\n const document = await documentIndexService.reindexDocument(selection);\n \n progress.progress = 100;\n toastInfo(`Document reindexed: ${document.fileName}`);\n } catch (error) {\n toastError(`Failed to reindex document: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n logger.info('RAG system extension loaded');\n\n // Register editor for document index manager\n editorRegistry.registerEditorInputHandler({\n editorId: 'system.rag-system-manager',\n label: 'RAG System Manager',\n ranking: 1000,\n canHandle: (input: EditorInput) => {\n return input.key === '.system.rag-system';\n },\n handle: async (input: EditorInput) => {\n input.component = (id: string) => html`\n <docks-rag-system-manager id=\"${id}\" .input=${input}></docks-rag-system-manager>\n `;\n return input;\n }\n });\n\n // Register command and toolbar button to open document index manager\n registerAll({\n command: {\n id: 'open-rag-system-manager',\n name: 'Open RAG System Manager',\n description: 'Opens the RAG system manager to view and manage indexed documents',\n parameters: []\n },\n handler: {\n execute: _context => {\n const editorInput: Partial<EditorInput> = {\n title: 'RAG System Manager',\n data: {},\n key: '.system.rag-system',\n icon: 'database',\n state: {},\n };\n editorRegistry.loadEditor(editorInput as EditorInput).catch(err => {\n logger.error(`Failed to open document index manager: ${err}`);\n });\n }\n },\n contribution: {\n target: TOOLBAR_MAIN_RIGHT,\n icon: 'database',\n label: 'RAG System',\n }\n });\n\n // Register context menu entry for indexing documents in the filebrowser view\n contributionRegistry.registerContribution('contextmenu:view.filebrowser', {\n name: 'contextmenu.filebrowser.indexDocument',\n command: 'rag-system.index-file',\n icon: 'database',\n label: 'Index Document',\n disabled: () => {\n const selection = activeSelectionSignal.get();\n return !(selection instanceof File);\n }\n });\n\n // Integrate RAG with AI system\n import('./rag-integration').then(rag => {\n rag.integrateRAGWithAI();\n logger.info('RAG integration enabled');\n }).catch(err => {\n logger.warn(`Failed to load RAG integration: ${err}`);\n });\n}\n\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rag-system-extension-BE7Q_0rq.js","names":[],"sources":["../src/rag-system-manager.ts","../src/rag-system-extension.ts"],"sourcesContent":["import { customElement, property, state } from 'lit/decorators.js';\nimport { css, html, TemplateResult, nothing } from 'lit';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { DocksPart } from '@eclipse-docks/core';\nimport { EditorInput } from '@eclipse-docks/core';\nimport { documentIndexService, IndexedDocument } from './document-index-service';\nimport { searchWorkspaceDocuments, RAGSearchResult } from './rag-service';\nimport { workspaceService, File } from '@eclipse-docks/core';\nimport { createLogger } from '@eclipse-docks/core';\nimport { getWorkspacePath } from './utils/workspace-utils';\nimport { SnippetExtractor } from './utils/snippet-extractor';\nimport { CONTENT_PREVIEW_LENGTHS, SNIPPET_LENGTHS } from './utils/constants';\nimport { toastError, toastInfo } from '@eclipse-docks/core';\nimport { taskService } from '@eclipse-docks/core';\nimport { editorRegistry } from '@eclipse-docks/core';\n\nconst logger = createLogger('RAGSystemManager');\nconst snippetExtractor = new SnippetExtractor();\n\n@customElement('docks-rag-system-manager')\nexport class DocksRAGSystemManager extends DocksPart {\n @property({ attribute: false })\n public input?: EditorInput;\n\n @state()\n private documents: IndexedDocument[] = [];\n\n\n @state()\n private stats: { totalDocuments: number; byWorkspace: Record<string, number> } = {\n totalDocuments: 0,\n byWorkspace: {}\n };\n\n @state()\n private loading = false;\n\n @state()\n private selectedDocument: IndexedDocument | null = null;\n\n @state()\n private searchQuery = '';\n\n @state()\n private filterWorkspace: string | null = null;\n\n @state()\n private filterByActiveWorkspace = true;\n\n @state()\n private filteredDocuments: IndexedDocument[] = [];\n \n @state()\n private searchResults: Map<string, RAGSearchResult> = new Map();\n\n @state()\n private reindexing = false;\n\n private treeRef = createRef<HTMLElement>();\n private searchDebounceTimer?: number;\n private searchInputValue = '';\n\n protected async doInitUI() {\n try {\n await documentIndexService.initialize();\n await Promise.all([\n this.loadDocuments(),\n this.loadStats()\n ]);\n } catch (error) {\n logger.error(`Failed to initialize document index manager: ${error}`);\n toastError(`Failed to initialize: ${error}`);\n }\n }\n\n private async loadDocuments() {\n this.loading = true;\n this.requestUpdate();\n try {\n let workspacePath: string | undefined;\n if (this.filterByActiveWorkspace) {\n const workspaceResult = await getWorkspacePath();\n workspacePath = workspaceResult?.workspacePath;\n }\n this.documents = await documentIndexService.listDocuments(workspacePath);\n await this.updateFilteredDocuments();\n } catch (error) {\n logger.error(`Failed to load documents: ${error}`);\n toastError(`Failed to load documents: ${error}`);\n } finally {\n this.loading = false;\n }\n }\n\n private async updateFilteredDocuments() {\n this.filteredDocuments = await this.getFilteredDocuments();\n this.requestUpdate();\n }\n\n private async loadStats() {\n try {\n this.stats = await documentIndexService.getStats();\n this.requestUpdate();\n } catch (error) {\n logger.error(`Failed to load stats: ${error}`);\n }\n }\n\n private handleTreeSelection(e: CustomEvent) {\n // Try getting from event detail first (as per extensions pattern)\n let selection = e.detail?.selection || [];\n\n // If no selection in detail, try getting from tree element directly (as per docks-filebrowser pattern)\n if (selection.length === 0 && this.treeRef.value) {\n // @ts-ignore\n selection = this.treeRef.value.selectedItems || [];\n }\n\n if (selection.length > 0) {\n const selectedItem = selection[0];\n if (selectedItem?.model) {\n this.selectedDocument = selectedItem.model;\n } else {\n this.selectedDocument = null;\n }\n } else {\n this.selectedDocument = null;\n }\n }\n\n private async getFilteredDocuments(): Promise<IndexedDocument[]> {\n if (!this.documents || this.documents.length === 0) {\n return [];\n }\n\n if (this.searchQuery.trim()) {\n try {\n const searchResults = await searchWorkspaceDocuments(this.searchQuery, {\n limit: 50,\n workspacePath: this.filterWorkspace || undefined\n });\n\n this.searchResults.clear();\n const uniqueDocs = new Map<string, IndexedDocument>();\n const aggregatedResults = new Map<string, RAGSearchResult>();\n \n for (const result of searchResults) {\n const docId = result.document.id;\n uniqueDocs.set(docId, result.document);\n \n const existing = aggregatedResults.get(docId);\n if (!existing) {\n aggregatedResults.set(docId, {\n document: result.document,\n relevance: result.relevance,\n matchedSnippets: [...result.matchedSnippets]\n });\n } else {\n if (result.relevance > existing.relevance) {\n existing.relevance = result.relevance;\n }\n const seenSnippets = new Set(existing.matchedSnippets);\n for (const snippet of result.matchedSnippets) {\n if (!seenSnippets.has(snippet)) {\n existing.matchedSnippets.push(snippet);\n seenSnippets.add(snippet);\n }\n }\n }\n }\n \n for (const [docId, result] of aggregatedResults) {\n this.searchResults.set(docId, result);\n }\n\n const resultDocs = Array.from(uniqueDocs.values());\n \n if (this.filterWorkspace) {\n return resultDocs.filter(doc => doc.workspacePath === this.filterWorkspace);\n }\n \n return resultDocs;\n } catch (error) {\n logger.debug(`RAG search failed in document manager: ${error}`);\n this.searchResults.clear();\n return [];\n }\n } else {\n this.searchResults.clear();\n }\n\n let filtered = [...this.documents];\n\n if (this.filterWorkspace) {\n filtered = filtered.filter(doc => doc.workspacePath === this.filterWorkspace);\n }\n\n return filtered;\n }\n\n private highlightMatches(text: string, query: string): TemplateResult {\n if (!query || !query.trim()) {\n return html`${text}`;\n }\n\n const queryLower = query.toLowerCase();\n const textLower = text.toLowerCase();\n const parts: Array<string | TemplateResult> = [];\n let lastIndex = 0;\n let index = textLower.indexOf(queryLower, lastIndex);\n\n while (index !== -1) {\n if (index > lastIndex) {\n parts.push(text.substring(lastIndex, index));\n }\n parts.push(html`<mark class=\"search-match\">${text.substring(index, index + query.length)}</mark>`);\n lastIndex = index + query.length;\n index = textLower.indexOf(queryLower, lastIndex);\n }\n\n if (lastIndex < text.length) {\n parts.push(text.substring(lastIndex));\n }\n\n return html`${parts}`;\n }\n\n private getContentPreview(doc: IndexedDocument): TemplateResult {\n const searchResult = this.searchResults.get(doc.id);\n \n if (searchResult && searchResult.matchedSnippets.length > 0) {\n return html`\n <table class=\"snippets-table\">\n <thead>\n <tr>\n <th class=\"snippet-number-col\">#</th>\n <th class=\"snippet-content-col\">Content</th>\n </tr>\n </thead>\n <tbody>\n ${searchResult.matchedSnippets.map((snippet, idx) => html`\n <tr>\n <td class=\"snippet-number\">${idx + 1}</td>\n <td class=\"snippet-content\">${this.highlightMatches(snippet, this.searchQuery)}</td>\n </tr>\n `)}\n </tbody>\n </table>\n `;\n }\n\n if (this.searchQuery && this.searchQuery.trim()) {\n const snippets = snippetExtractor.extractContextSnippets(\n doc.content,\n this.searchQuery,\n SNIPPET_LENGTHS.CONTEXT\n );\n\n if (snippets.length > 0) {\n return html`\n <table class=\"snippets-table\">\n <thead>\n <tr>\n <th class=\"snippet-number-col\">#</th>\n <th class=\"snippet-content-col\">Content</th>\n </tr>\n </thead>\n <tbody>\n ${snippets.map((snippet, idx) => html`\n <tr>\n <td class=\"snippet-number\">${idx + 1}</td>\n <td class=\"snippet-content\">${this.highlightMatches(doc.content.substring(snippet.start, snippet.end), this.searchQuery)}</td>\n </tr>\n `)}\n </tbody>\n </table>\n `;\n }\n }\n\n const preview = snippetExtractor.extractSimpleSnippet(doc.content, CONTENT_PREVIEW_LENGTHS.LONG);\n return html`\n <div class=\"snippet-preview\">${preview}</div>\n `;\n }\n\n private async deleteDocument(doc: IndexedDocument) {\n try {\n await documentIndexService.deleteDocument(doc.id);\n toastInfo(`Deleted: ${doc.fileName}`);\n await this.loadDocuments();\n await this.loadStats();\n if (this.selectedDocument?.id === doc.id) {\n this.selectedDocument = null;\n }\n } catch (error) {\n toastError(`Failed to delete document: ${error}`);\n }\n }\n\n private async reindexDocument(doc: IndexedDocument) {\n try {\n const workspaceResult = await getWorkspacePath();\n if (!workspaceResult) {\n toastError('No workspace connected');\n return;\n }\n\n const resource = await workspaceResult.workspace.getResource(doc.filePath);\n if (!resource) {\n toastError(`File not found: ${doc.filePath}`);\n return;\n }\n\n if (!(resource instanceof File)) {\n toastError(`Resource is not a file: ${doc.filePath}`);\n return;\n }\n\n const file: File = resource;\n\n await taskService.runAsync('Reindexing document', async progress => {\n progress.message = `Reindexing ${doc.fileName}...`;\n await documentIndexService.reindexDocument(file);\n progress.progress = 100;\n });\n\n toastInfo(`Reindexed: ${doc.fileName}`);\n await this.loadDocuments();\n if (this.selectedDocument?.id === doc.id) {\n this.selectedDocument = await documentIndexService.getDocument(doc.id);\n }\n } catch (error) {\n toastError(`Failed to reindex document: ${error}`);\n }\n }\n\n private async reindexAllDocuments() {\n if (this.reindexing) {\n return;\n }\n\n const stats = await documentIndexService.getStats();\n if (stats.totalDocuments === 0) {\n toastInfo('No documents to reindex');\n return;\n }\n\n this.reindexing = true;\n this.requestUpdate();\n\n try {\n const result = await taskService.runAsync('Reindexing all documents', async progress => {\n progress.message = 'Starting reindexing...';\n \n const total = stats.totalDocuments;\n\n const reindexResult = await documentIndexService.reindexAllDocuments();\n \n const processed = reindexResult.succeeded + reindexResult.failed;\n progress.progress = total > 0 ? (processed / total) * 100 : 100;\n progress.message = `Reindexed ${reindexResult.succeeded}/${total} documents${reindexResult.failed > 0 ? ` (${reindexResult.failed} failed)` : ''}`;\n \n return reindexResult;\n });\n\n await this.loadDocuments();\n await this.loadStats();\n toastInfo(`Reindexing completed: ${result.succeeded} succeeded, ${result.failed} failed`);\n } catch (error) {\n logger.error(`Failed to reindex all documents: ${error}`);\n toastError(`Failed to reindex all documents: ${error}`);\n } finally {\n this.reindexing = false;\n this.requestUpdate();\n }\n }\n\n private formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} MiB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n\n private formatDate(timestamp: number): string {\n return new Date(timestamp).toLocaleString();\n }\n\n private getFileIcon(fileType: string): string {\n return editorRegistry.getFileIcon(fileType);\n }\n\n protected renderToolbar(): TemplateResult {\n const workspaces = Object.keys(this.stats?.byWorkspace || {});\n\n return html`\n <wa-input\n type=\"search\"\n placeholder=\"Search documents...\"\n .value=${this.searchInputValue}\n @input=${(e: any) => {\n this.searchInputValue = e.target.value;\n \n if (this.searchDebounceTimer) {\n clearTimeout(this.searchDebounceTimer);\n }\n \n this.searchDebounceTimer = window.setTimeout(async () => {\n this.searchQuery = this.searchInputValue;\n await this.updateFilteredDocuments();\n }, 200);\n }}\n @wa-clear=${async () => {\n if (this.searchDebounceTimer) {\n clearTimeout(this.searchDebounceTimer);\n }\n this.searchInputValue = '';\n this.searchQuery = '';\n await this.updateFilteredDocuments();\n }}\n size=\"small\"\n with-clear\n autocomplete=\"off\"\n style=\"flex: 1; max-width: 400px;\">\n <wa-icon name=\"magnifying-glass\" slot=\"start\"></wa-icon>\n </wa-input>\n \n <wa-switch\n .checked=${this.filterByActiveWorkspace}\n @change=${async (e: any) => {\n this.filterByActiveWorkspace = e.target.checked;\n await this.loadDocuments();\n }}\n size=\"small\">\n Active workspace only\n </wa-switch>\n \n ${workspaces.length > 1 ? html`\n <wa-select \n .value=${this.filterWorkspace || ''}\n @change=${async (e: any) => {\n this.filterWorkspace = e.target.value || null;\n await this.updateFilteredDocuments();\n }}\n size=\"small\"\n style=\"width: 200px;\">\n <wa-option value=\"\">All Workspaces</wa-option>\n ${workspaces.map(ws => html`\n <wa-option value=\"${ws}\">${ws} (${this.stats.byWorkspace[ws]})</wa-option>\n `)}\n </wa-select>\n ` : nothing}\n \n <docks-command \n size=\"small\" \n icon=\"arrow-rotate-right\"\n title=\"Refresh document list\"\n .action=${() => this.loadDocuments()}\n ?disabled=${this.reindexing}>\n Refresh\n </docks-command>\n \n <docks-command \n size=\"small\" \n icon=\"database\"\n title=\"Re-index all documents\"\n .action=${() => this.reindexAllDocuments()}\n ?disabled=${this.reindexing || this.loading}>\n ${this.reindexing ? 'Reindexing...' : 'Re-index All'}\n </docks-command>\n `;\n }\n\n protected renderContent(): TemplateResult {\n if (!this.stats) {\n this.stats = { totalDocuments: 0, byWorkspace: {} };\n }\n\n const filteredDocs = this.filteredDocuments;\n const workspaces = Object.keys(this.stats.byWorkspace || {});\n\n return html`\n <div class=\"rag-system-manager\">\n <div class=\"header\">\n <div class=\"header-content\">\n <div class=\"stats\">\n <span>Total: ${this.stats.totalDocuments} documents</span>\n ${workspaces.length > 0 ? html`\n <span>Workspaces: ${workspaces.length}</span>\n ` : nothing}\n </div>\n </div>\n </div>\n\n <wa-split-panel position=\"40\" style=\"height: 100%;\">\n <div class=\"document-list\" slot=\"start\">\n ${this.loading ? html`\n <div class=\"loading\">\n <wa-spinner></wa-spinner>\n <span>Loading documents...</span>\n </div>\n ` : filteredDocs.length === 0 ? html`\n <div class=\"empty\">\n <wa-icon name=\"inbox\" style=\"font-size: 3rem; opacity: 0.3;\"></wa-icon>\n <p>${this.searchQuery || this.filterWorkspace ? 'No documents match your filters' : 'No documents indexed yet'}</p>\n </div>\n ` : html`\n <wa-tree \n ${ref(this.treeRef)}\n selection=\"leaf\"\n style=\"--indent-guide-width: 1px;\"\n @wa-selection-change=${(e: CustomEvent) => {\n this.handleTreeSelection(e);\n }}>\n ${filteredDocs.map(doc => html`\n <wa-tree-item \n .model=${doc}\n ?selected=${this.selectedDocument?.id === doc.id}>\n <wa-icon name=\"${this.getFileIcon(doc.fileType)}\"></wa-icon>\n <div class=\"tree-item-info\">\n <strong class=\"tree-item-path\">${doc.filePath}</strong>\n <div class=\"tree-item-meta\">\n <small class=\"meta-size\">${this.formatFileSize(doc.metadata.size)}</small>\n <small class=\"meta-date\">${this.formatDate(doc.indexedAt)}</small>\n </div>\n </div>\n <div class=\"tree-item-actions\" @click=${(e: Event) => e.stopPropagation()}>\n <wa-button\n variant=\"neutral\"\n appearance=\"plain\"\n size=\"small\"\n title=\"Reindex\"\n @click=${() => this.reindexDocument(doc)}>\n <wa-icon name=\"arrow-rotate-right\"></wa-icon>\n </wa-button>\n <wa-button\n variant=\"danger\"\n appearance=\"plain\"\n size=\"small\"\n title=\"Delete\"\n @click=${() => this.deleteDocument(doc)}>\n <wa-icon name=\"trash\"></wa-icon>\n </wa-button>\n </div>\n </wa-tree-item>\n `)}\n </wa-tree>\n `}\n </div>\n\n <div slot=\"end\">\n ${this.selectedDocument ? html`\n <div class=\"document-details\">\n <div class=\"details-content\">\n <div class=\"metadata-grid\">\n <wa-input\n label=\"File Path\"\n .value=${this.selectedDocument.filePath}\n readonly\n size=\"small\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.selectedDocument.filePath}\n size=\"small\"\n label=\"Copy file path\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"Workspace\"\n .value=${this.selectedDocument.workspacePath}\n readonly\n size=\"small\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.selectedDocument.workspacePath}\n size=\"small\"\n label=\"Copy workspace\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"File Type\"\n .value=${this.selectedDocument.fileType}\n readonly\n size=\"small\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.selectedDocument.fileType}\n size=\"small\"\n label=\"Copy file type\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"Size\"\n .value=${this.formatFileSize(this.selectedDocument.metadata.size)}\n readonly\n size=\"small\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.formatFileSize(this.selectedDocument.metadata.size)}\n size=\"small\"\n label=\"Copy size\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"Indexed At\"\n .value=${this.formatDate(this.selectedDocument.indexedAt)}\n readonly\n size=\"small\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.formatDate(this.selectedDocument.indexedAt)}\n size=\"small\"\n label=\"Copy indexed date\">\n </wa-copy-button>\n </wa-input>\n \n <wa-input\n label=\"Last Updated\"\n .value=${this.formatDate(this.selectedDocument.updatedAt)}\n readonly\n size=\"small\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.formatDate(this.selectedDocument.updatedAt)}\n size=\"small\"\n label=\"Copy updated date\">\n </wa-copy-button>\n </wa-input>\n </div>\n \n ${this.selectedDocument.metadata.tags && this.selectedDocument.metadata.tags.length > 0 ? html`\n <div class=\"tags-section\">\n <wa-input\n label=\"Tags\"\n .value=${this.selectedDocument.metadata.tags.join(', ')}\n readonly\n size=\"small\">\n <wa-copy-button\n slot=\"end\"\n .value=${this.selectedDocument.metadata.tags.join(', ')}\n size=\"small\"\n label=\"Copy tags\">\n </wa-copy-button>\n </wa-input>\n </div>\n ` : nothing}\n \n <div class=\"detail-section\">\n <label>Content Preview${this.searchQuery ? html` <span class=\"search-hint\">(showing matches for \"${this.searchQuery}\")</span>` : nothing}</label>\n <wa-scroller class=\"content-preview\" orientation=\"vertical\">\n <div class=\"content-preview-inner\">\n ${this.getContentPreview(this.selectedDocument)}\n </div>\n </wa-scroller>\n </div>\n </div>\n </div>\n ` : html`\n <div class=\"document-details empty\">\n <wa-icon name=\"file-lines\" style=\"font-size: 3rem; opacity: 0.3;\"></wa-icon>\n <p>Select a document to view details</p>\n </div>\n `}\n </div>\n </wa-split-panel>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n min-height: 0;\n }\n\n .rag-system-manager {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n }\n\n wa-split-panel {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }\n\n .document-list {\n height: 100%;\n overflow-y: auto;\n }\n\n .tree-item-info {\n flex: 1;\n min-width: 0;\n }\n\n .tree-item-path {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tree-item-meta {\n display: flex;\n align-items: center;\n gap: var(--wa-space-xs);\n flex-wrap: wrap;\n margin-top: var(--wa-space-xs);\n }\n\n .tree-item-actions {\n opacity: 0;\n }\n\n wa-tree-item:hover .tree-item-actions {\n opacity: 1;\n }\n\n .document-details {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n }\n\n .details-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: var(--wa-space-s);\n min-height: 0;\n overflow: hidden;\n }\n\n .metadata-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--wa-space-s);\n flex-shrink: 0;\n }\n\n .tags-section {\n margin-top: var(--wa-space-s);\n flex-shrink: 0;\n margin-bottom: var(--wa-space-s);\n }\n\n .detail-section {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n position: relative;\n }\n\n .detail-section label {\n flex-shrink: 0;\n margin-bottom: var(--wa-space-xs);\n }\n\n .content-preview {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n bottom: 0;\n }\n\n .content-preview-inner {\n width: 100%;\n }\n\n .snippets-table {\n width: 100%;\n border-collapse: collapse;\n background-color: var(--wa-color-surface-raised);\n }\n\n .snippets-table thead {\n background-color: var(--wa-color-neutral-fill-quiet);\n }\n\n .snippets-table th {\n padding: var(--wa-space-xs) var(--wa-space-s);\n text-align: left;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--wa-color-text-quiet);\n border-bottom: 1px solid var(--wa-color-surface-border);\n }\n\n .snippets-table td {\n padding: var(--wa-space-s);\n border-bottom: 1px solid var(--wa-color-surface-border);\n vertical-align: top;\n }\n\n .snippets-table tbody tr:last-child td {\n border-bottom: none;\n }\n\n .snippets-table tbody tr:hover {\n background-color: var(--wa-color-neutral-fill-quiet);\n }\n\n .snippet-number-col {\n width: 3rem;\n text-align: center;\n }\n\n .snippet-content-col {\n width: auto;\n }\n\n .snippet-number {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--wa-color-text-quiet);\n text-align: center;\n }\n\n .snippet-content {\n white-space: pre-wrap;\n word-wrap: breaword;\n overflow-wrap: breaword;\n font-family: monospace;\n font-size: 0.875rem;\n line-height: 1.5;\n color: var(--wa-color-text-normal);\n }\n\n .snippet-preview {\n white-space: pre-wrap;\n word-wrap: breaword;\n overflow-wrap: breaword;\n font-family: monospace;\n font-size: 0.875rem;\n line-height: 1.5;\n color: var(--wa-color-text-normal);\n padding: var(--wa-space-s);\n background-color: var(--wa-color-surface-raised);\n border-radius: var(--wa-border-radius-medium);\n }\n\n .snippet-content mark.search-match {\n background: var(--wa-color-warning-fill-loud);\n color: var(--wa-color-warning-text-loud);\n padding: 0 2px;\n border-radius: 2px;\n font-weight: 600;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-rag-system-manager': DocksRAGSystemManager;\n }\n}\n\n","import { documentIndexService } from './document-index-service';\nimport { registerAll } from '@eclipse-docks/core';\nimport { workspaceService, File } from '@eclipse-docks/core';\nimport { toastError, toastInfo } from '@eclipse-docks/core';\nimport { taskService } from '@eclipse-docks/core';\nimport { activeSelectionSignal } from '@eclipse-docks/core';\nimport { createLogger } from '@eclipse-docks/core';\nimport { contributionRegistry } from '@eclipse-docks/core';\nimport { editorRegistry, EditorInput } from '@eclipse-docks/core';\nimport { html } from 'lit';\nimport { TOOLBAR_MAIN_RIGHT } from '@eclipse-docks/core';\n// Import the component to ensure it's registered\nimport './rag-system-manager';\n\nconst logger = createLogger('RAGSystemExtension');\n\nexport default function ragSystemExtension(context: any) {\n documentIndexService.initialize().catch(err => {\n logger.error(`Failed to initialize document index service: ${err}`);\n });\n\n registerAll({\n command: {\n id: 'rag-system.index-file',\n name: 'Index Document',\n description: 'Index the currently selected file for search and retrieval',\n parameters: [\n {\n name: 'includeContent',\n description: 'Whether to include full content in index (default: true)',\n required: false\n }\n ]\n },\n handler: {\n canExecute: context => {\n const selection = activeSelectionSignal.get();\n return selection instanceof File;\n },\n execute: async context => {\n const selection = activeSelectionSignal.get();\n \n if (!(selection instanceof File)) {\n toastError('Please select a file to index');\n return;\n }\n\n const includeContent = context.params?.includeContent !== false;\n\n await taskService.runAsync('Indexing document', async progress => {\n progress.message = `Indexing ${selection.getName()}...`;\n \n try {\n const document = await documentIndexService.indexDocument(selection, {\n includeContent\n });\n \n progress.progress = 100;\n toastInfo(`Document indexed: ${document.fileName}`);\n } catch (error) {\n toastError(`Failed to index document: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.index-workspace',\n name: 'Index Workspace',\n description: 'Index all indexable files in the current workspace',\n parameters: [\n {\n name: 'includeContent',\n description: 'Whether to include full content in index (default: true)',\n required: false\n },\n {\n name: 'maxFileSize',\n description: 'Maximum file size in bytes to index (default: 5MB)',\n required: false\n }\n ]\n },\n handler: {\n canExecute: context => {\n return true;\n },\n execute: async context => {\n const workspace = await workspaceService.getWorkspace();\n \n if (!workspace) {\n toastError('No workspace selected');\n return;\n }\n\n const includeContent = context.params?.includeContent !== false;\n const maxFileSize = context.params?.maxFileSize \n ? parseInt(context.params.maxFileSize) \n : undefined;\n\n await taskService.runAsync('Indexing workspace', async progress => {\n progress.message = 'Collecting files...';\n progress.progress = 0;\n\n try {\n const result = await documentIndexService.indexWorkspace(workspace, {\n includeContent,\n maxFileSize\n });\n\n progress.progress = 100;\n \n if (result.failed > 0) {\n toastError(\n `Indexing complete: ${result.indexed} indexed, ${result.failed} failed. ` +\n `Check console for details.`\n );\n } else {\n toastInfo(`Workspace indexed: ${result.indexed} documents`);\n }\n } catch (error) {\n toastError(`Failed to index workspace: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.list-documents',\n name: 'List Indexed Documents',\n description: 'List all indexed documents in the current workspace',\n parameters: []\n },\n handler: {\n canExecute: context => {\n return true;\n },\n execute: async context => {\n const workspace = await workspaceService.getWorkspace();\n const workspacePath = workspace?.getName();\n\n await taskService.runAsync('Loading indexed documents', async progress => {\n try {\n const documents = await documentIndexService.listDocuments(workspacePath);\n \n progress.progress = 100;\n \n if (documents.length === 0) {\n toastInfo('No documents indexed in this workspace');\n } else {\n logger.info(`Found ${documents.length} indexed documents`);\n toastInfo(`Found ${documents.length} indexed documents (check console for details)`);\n }\n } catch (error) {\n toastError(`Failed to list documents: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.delete-document',\n name: 'Delete Document from Index',\n description: 'Remove the selected file from the document index',\n parameters: []\n },\n handler: {\n canExecute: context => {\n const selection = activeSelectionSignal.get();\n return selection instanceof File;\n },\n execute: async context => {\n const selection = activeSelectionSignal.get();\n \n if (!(selection instanceof File)) {\n toastError('Please select a file to remove from index');\n return;\n }\n\n const workspace = selection.getWorkspace();\n const workspacePath = workspace.getName();\n const filePath = selection.getWorkspacePath();\n\n await taskService.runAsync('Deleting document from index', async progress => {\n try {\n const deleted = await documentIndexService.deleteDocumentByPath(\n workspacePath,\n filePath\n );\n\n progress.progress = 100;\n\n if (deleted) {\n toastInfo(`Document removed from index: ${selection.getName()}`);\n } else {\n toastInfo(`Document not found in index: ${selection.getName()}`);\n }\n } catch (error) {\n toastError(`Failed to delete document from index: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.clear-workspace',\n name: 'Clear Workspace Index',\n description: 'Remove all indexed documents from the current workspace',\n parameters: []\n },\n handler: {\n canExecute: context => {\n return true;\n },\n execute: async context => {\n const workspace = await workspaceService.getWorkspace();\n \n if (!workspace) {\n toastError('No workspace selected');\n return;\n }\n\n const workspacePath = workspace.getName();\n\n await taskService.runAsync('Clearing workspace index', async progress => {\n try {\n const deleted = await documentIndexService.deleteWorkspace(workspacePath);\n\n progress.progress = 100;\n toastInfo(`Removed ${deleted} documents from index`);\n } catch (error) {\n toastError(`Failed to clear workspace index: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.get-stats',\n name: 'Document Index Statistics',\n description: 'Get statistics about the document index',\n parameters: []\n },\n handler: {\n canExecute: context => {\n return true;\n },\n execute: async context => {\n await taskService.runAsync('Loading statistics', async progress => {\n try {\n const stats = await documentIndexService.getStats();\n \n progress.progress = 100;\n \n logger.info(`Document index statistics: ${JSON.stringify(stats)}`);\n toastInfo(\n `Index statistics: ${stats.totalDocuments} total documents. ` +\n `Check console for details.`\n );\n } catch (error) {\n toastError(`Failed to get statistics: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n registerAll({\n command: {\n id: 'rag-system.reindex-file',\n name: 'Reindex Document',\n description: 'Reindex the selected file (useful after file changes)',\n parameters: []\n },\n handler: {\n canExecute: context => {\n const selection = activeSelectionSignal.get();\n return selection instanceof File;\n },\n execute: async context => {\n const selection = activeSelectionSignal.get();\n \n if (!(selection instanceof File)) {\n toastError('Please select a file to reindex');\n return;\n }\n\n await taskService.runAsync('Reindexing document', async progress => {\n progress.message = `Reindexing ${selection.getName()}...`;\n \n try {\n const document = await documentIndexService.reindexDocument(selection);\n \n progress.progress = 100;\n toastInfo(`Document reindexed: ${document.fileName}`);\n } catch (error) {\n toastError(`Failed to reindex document: ${error}`);\n throw error;\n }\n });\n }\n }\n });\n\n logger.info('RAG system extension loaded');\n\n // Register editor for document index manager\n editorRegistry.registerEditorInputHandler({\n editorId: 'system.rag-system-manager',\n label: 'RAG System Manager',\n ranking: 1000,\n canHandle: (input: EditorInput) => {\n return input.key === '.system.rag-system';\n },\n handle: async (input: EditorInput) => {\n input.component = (id: string) => html`\n <docks-rag-system-manager id=\"${id}\" .input=${input}></docks-rag-system-manager>\n `;\n return input;\n }\n });\n\n // Register command and toolbar button to open document index manager\n registerAll({\n command: {\n id: 'open-rag-system-manager',\n name: 'Open RAG System Manager',\n description: 'Opens the RAG system manager to view and manage indexed documents',\n parameters: []\n },\n handler: {\n execute: _context => {\n const editorInput: Partial<EditorInput> = {\n title: 'RAG System Manager',\n data: {},\n key: '.system.rag-system',\n icon: 'database',\n state: {},\n };\n editorRegistry.loadEditor(editorInput as EditorInput).catch(err => {\n logger.error(`Failed to open document index manager: ${err}`);\n });\n }\n },\n contribution: {\n target: TOOLBAR_MAIN_RIGHT,\n icon: 'database',\n label: 'RAG System',\n }\n });\n\n // Register context menu entry for indexing documents in the filebrowser view\n contributionRegistry.registerContribution('contextmenu:view.filebrowser', {\n name: 'contextmenu.filebrowser.indexDocument',\n command: 'rag-system.index-file',\n icon: 'database',\n label: 'Index Document',\n disabled: () => {\n const selection = activeSelectionSignal.get();\n return !(selection instanceof File);\n }\n });\n\n // Integrate RAG with AI system\n import('./rag-integration').then(rag => {\n rag.integrateRAGWithAI();\n logger.info('RAG integration enabled');\n }).catch(err => {\n logger.warn(`Failed to load RAG integration: ${err}`);\n });\n}\n\n"],"mappings":"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"}
|