From 2968932d69c8f9e1da69a5e180b94eeb63c82aa8 Mon Sep 17 00:00:00 2001 From: Florian Egger Date: Wed, 6 May 2026 18:24:24 +0200 Subject: [PATCH] Add error handler and improve coverage --- .eslintrc.js | 4 + coverage/lcov-report/chat-view.ts.html | 274 +++++--- coverage/lcov-report/error-handler.ts.html | 152 ++--- coverage/lcov-report/index.html | 41 +- coverage/lcov-report/ollama-client.ts.html | 38 +- coverage/lcov-report/tool-executor.ts.html | 44 +- coverage/lcov-report/types.ts.html | 34 +- coverage/lcov-report/utils.ts.html | 72 +-- coverage/lcov-report/vault-indexer.ts.html | 236 +++---- coverage/lcov.info | 715 +++++++++++++++------ manifest.json | 2 +- package.json | 2 +- src/chat-view.js | 369 +++++++++++ src/chat-view.ts | 9 + src/constants.js | 13 + src/error-handler.js | 106 +++ src/main.js | 170 +++++ src/main.ts | 13 + src/ollama-client.js | 201 ++++++ src/tool-executor.js | 114 ++++ src/types.js | 79 +++ src/utils.js | 184 ++++++ src/vault-indexer.js | 283 ++++++++ tsconfig.json | 2 +- 24 files changed, 2553 insertions(+), 604 deletions(-) create mode 100644 src/chat-view.js create mode 100644 src/constants.js create mode 100644 src/error-handler.js create mode 100644 src/main.js create mode 100644 src/ollama-client.js create mode 100644 src/tool-executor.js create mode 100644 src/types.js create mode 100644 src/utils.js create mode 100644 src/vault-indexer.js diff --git a/.eslintrc.js b/.eslintrc.js index f9e141a..14cdcd4 100755 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,9 @@ module.exports = { root: true, parser: '@typescript-eslint/parser', + parserOptions: { + project: true, + }, plugins: ['@typescript-eslint'], extends: [ 'eslint:recommended', @@ -20,4 +23,5 @@ module.exports = { es2020: true, jest: true, }, + ignorePatterns: ['**/__mocks__/**', '**/*.test.ts'], }; diff --git a/coverage/lcov-report/chat-view.ts.html b/coverage/lcov-report/chat-view.ts.html index 5b768f8..80ee8ed 100755 --- a/coverage/lcov-report/chat-view.ts.html +++ b/coverage/lcov-report/chat-view.ts.html @@ -23,30 +23,30 @@
- 86.15% + 91.54% Statements - 168/195 + 184/201
- 76.92% + 83.07% Branches - 50/65 + 54/65
- 76.92% + 87.09% Functions - 20/26 + 27/31
- 88.95% + 93.58% Lines - 161/181 + 175/187
@@ -495,7 +495,29 @@ 430 431 432 -4331x +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +4551x       @@ -534,6 +556,19 @@ 31x     +  +2x +  +  +  +4x +  +  +  +2x +  +  +  31x 31x 31x @@ -542,6 +577,11 @@       +  +  +  +  +  1x     @@ -556,6 +596,10 @@       +  +  +  +  3x 3x 3x @@ -567,7 +611,7 @@       -15x +23x 8x 8x   @@ -575,60 +619,60 @@       -27x -27x +33x +33x   -27x +33x     -27x +33x 4x   -27x +33x 4x     4x     -27x +33x   -18x +22x   -18x +22x     -18x -18x +22x +22x       -27x +33x     -254x +262x     -27x +33x 128x   -27x -243x +33x +247x     -243x +247x 104x   -139x +143x     -139x -139x +143x +143x         -27x +33x 128x 3656x 24x @@ -636,8 +680,8 @@       -254x -27x +262x +33x       @@ -648,39 +692,39 @@       -5x +13x     -5x -5x -  -  -  +13x +13x +2x +2x +2x       -5x -5x -  -  -  -  +13x +13x +4x +2x +2x +2x         -5x -5x -5x -5x -5x +13x +13x +13x +7x +7x   -5x +7x         -5x +13x       @@ -707,10 +751,10 @@       -  -  -  -  +2x +2x +2x +2x       @@ -738,34 +782,34 @@       -12x -12x +16x +16x   -12x +16x   -12x -12x +16x +16x     -10x -10x +14x +14x     -10x -10x +14x +14x       -10x +14x       -10x +14x         -10x +14x       @@ -778,7 +822,7 @@       -10x +14x       @@ -796,20 +840,20 @@       -10x +14x   -10x -10x +14x +14x     -10x +14x             -10x +14x       @@ -818,19 +862,19 @@       -10x +14x   -10x +14x   -10x -10x -10x -10x -10x -10x +14x +14x +14x +14x +14x +14x   -10x -10x +14x +14x 12x 12x   @@ -848,7 +892,7 @@       -10x +14x       @@ -918,11 +962,11 @@ 8x     -2x -2x +6x +6x   -12x -12x +16x +16x       @@ -964,6 +1008,19 @@ export class ChatView extends ItemView { private inputKeyDownHandler: ((e: KeyboardEvent) => Promise<void>) | null = null; private newChatButtonClickHandler: (() => void) | null = null; private listenersAttached = false; +  + // Getters for testing + public getSendButtonClickHandler(): (() => Promise<void>) | null { + return this.sendButtonClickHandler; + } +  + public getInputKeyDownHandler(): ((e: KeyboardEvent) => Promise<void>) | null { + return this.inputKeyDownHandler; + } +  + public getNewChatButtonClickHandler(): (() => void) | null { + return this.newChatButtonClickHandler; + }   constructor(leaf: WorkspaceLeaf, settings: PluginSettings) { super(leaf); @@ -972,6 +1029,11 @@ export class ChatView extends ItemView { this.vaultIndexer = new VaultIndexer(this.app.vault); this.toolExecutor = new ToolExecutor(this.app.vault, this.app); } +  + public updateSettings(newSettings: PluginSettings): void { + this.settings = newSettings; + this.ollamaClient = new OllamaClient(newSettings.ollamaUrl, newSettings.model); + }   getViewType(): string { return 'ollama-chat-view'; @@ -986,6 +1048,10 @@ export class ChatView extends ItemView { this.removeEventListeners(); // Clean up any existing listeners before reattaching this.setupEventListeners(); } +  + public onSettingsChange(newSettings: PluginSettings): void { + this.updateSettings(newSettings); + }   async onClose() { this.ollamaClient.cancelStream(); @@ -1084,19 +1150,19 @@ export class ChatView extends ItemView {   // Create handlers if they don't exist if (!this.sendButtonClickHandler) { - this.sendButtonClickHandler = async () => { - Iif (!this.inputEl) return; - await this.handleUserInput((this.inputEl as HTMLTextAreaElement).value); - (this.inputEl as HTMLTextAreaElement).value = ''; + this.sendButtonClickHandler = async () => { + Iif (!this.inputEl) return; + await this.handleUserInput((this.inputEl as HTMLTextAreaElement).value); + (this.inputEl as HTMLTextAreaElement).value = ''; }; }   if (!this.inputKeyDownHandler) { - this.inputKeyDownHandler = async (e: KeyboardEvent) => { - Iif (!this.inputEl || e.key !== 'Enter' || e.shiftKey) return; - e.preventDefault(); - await this.handleUserInput((this.inputEl as HTMLTextAreaElement).value); - (this.inputEl as HTMLTextAreaElement).value = ''; + this.inputKeyDownHandler = async (e: KeyboardEvent) => { + if (!this.inputEl || e.key !== 'Enter' || e.shiftKey) return; + e.preventDefault(); + await this.handleUserInput((this.inputEl as HTMLTextAreaElement).value); + (this.inputEl as HTMLTextAreaElement).value = ''; }; }   @@ -1105,7 +1171,7 @@ export class ChatView extends ItemView { (this.inputEl as HTMLTextAreaElement).addEventListener('keydown', this.inputKeyDownHandler!); if (this.newChatButton) { if (!this.newChatButtonClickHandler) { - this.newChatButtonClickHandler = () => this.clearConversation(); + this.newChatButtonClickHandler = () => this.clearConversation(); } (this.newChatButton as HTMLButtonElement).addEventListener( 'click', @@ -1137,12 +1203,12 @@ export class ChatView extends ItemView { this.listenersAttached = false; }   - private clearConversation(): void { + private clearConversation(): void { // Create new array to ensure immutability - this.messages = []; - this.lastMessageEl = null; - this.render(); - new Notice('Conversation cleared'); + this.messages = []; + this.lastMessageEl = null; + this.render(); + new Notice('Conversation cleared'); }   private updateMessageById(id: string, partial: Partial<ChatMessage>): boolean { @@ -1366,7 +1432,7 @@ export class ChatView extends ItemView {