mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
feat: add toggleable quick actions with context menu and toolbar options
Add settings to enable/disable quick actions in both the editor context menu and toolbar. Implement dynamic registration system that updates when settings change. Include event-driven architecture for settings changes and improve toolbar injection logic. Update dependencies to latest versions.
This commit is contained in:
parent
7be9b3f321
commit
841b3af5a4
14 changed files with 203 additions and 91 deletions
|
|
@ -84,6 +84,12 @@ export enum Copy {
|
|||
TooltipLearnMoreFileMonitoring = "Learn more in Plugin Guide",
|
||||
TooltipAccessMemories = "View Memories",
|
||||
|
||||
SettingQuickActions = "Quick Actions",
|
||||
SettingEnableContextMenuActions = "Enable Context Menu Actions",
|
||||
SettingEnableContextMenuActionsDesc = "Show quick actions in the right-click editor context menu.",
|
||||
SettingEnableToolbarActions = "Enable Toolbar Actions",
|
||||
SettingEnableToolbarActionsDesc = "Show a quick actions button in the editor toolbar (mobile friendly).",
|
||||
|
||||
AIThoughtMessage = "Thinking...",
|
||||
AIThoughtGeneratingNote = "Generating note contents...",
|
||||
AIThoughtPreparingQuery = "Preparing user query...",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export enum Event {
|
||||
DiffOpened = "diffOpened",
|
||||
DiffClosed = "diffClosed",
|
||||
RateLimitCountdown = "rateLimitCountdown"
|
||||
RateLimitCountdown = "rateLimitCountdown",
|
||||
QuickActionsSettingsChanged = "quickActionsSettingsChanged"
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ export class EventService extends Events {
|
|||
public trigger(name: Event.DiffOpened, data?: unknown): void;
|
||||
public trigger(name: Event.DiffClosed, data?: unknown): void;
|
||||
public trigger(name: Event.RateLimitCountdown, delayMs: number): void;
|
||||
public trigger(name: Event.QuickActionsSettingsChanged, data?: unknown): void;
|
||||
|
||||
public trigger(name: string, ...data: unknown[]): void {
|
||||
super.trigger(name, ...data);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Resolve } from "./DependencyService";
|
|||
import { Services } from "./Services";
|
||||
import type { QuickAgent } from "./AIServices/QuickAgent";
|
||||
import type VaultkeeperAIPlugin from "main";
|
||||
import { FuzzySuggestModal, MarkdownView, Menu, Notice, setIcon, TFile, type Editor, type MarkdownFileInfo } from "obsidian";
|
||||
import { FuzzySuggestModal, MarkdownView, Menu, Notice, setIcon, TFile, type Editor, type EventRef, type MarkdownFileInfo } from "obsidian";
|
||||
import { FileSystemService } from "./FileSystemService";
|
||||
import { BeautifyPrompt } from "AIPrompts/QuickActionPrompts/Beautify";
|
||||
import Spinner from "Components/Spinner.svelte";
|
||||
|
|
@ -10,25 +10,40 @@ import { mount } from "svelte";
|
|||
import { ApplyTemplatePrompt } from "AIPrompts/QuickActionPrompts/ApplyTemplatePrompt";
|
||||
import { Copy } from "Enums/Copy";
|
||||
import type { WorkSpaceService } from "./WorkSpaceService";
|
||||
import type { SettingsService } from "./SettingsService";
|
||||
import type { EventService } from "./EventService";
|
||||
import { Event } from "Enums/Event";
|
||||
import { openPluginSettings } from "Helpers/Helpers";
|
||||
|
||||
export class QuickActionsService {
|
||||
|
||||
private readonly actionTimeout: number = 30000;
|
||||
|
||||
private plugin: VaultkeeperAIPlugin;
|
||||
private workSpaceService: WorkSpaceService
|
||||
private workSpaceService: WorkSpaceService;
|
||||
private fileSystemService: FileSystemService;
|
||||
private settingsService: SettingsService;
|
||||
private eventService: EventService;
|
||||
|
||||
private editorMenuEventRef: EventRef | null = null;
|
||||
private layoutChangeEventRef: EventRef | null = null;
|
||||
|
||||
public constructor() {
|
||||
this.plugin = Resolve<VaultkeeperAIPlugin>(Services.VaultkeeperAIPlugin);
|
||||
this.workSpaceService = Resolve<WorkSpaceService>(Services.WorkSpaceService);
|
||||
this.fileSystemService = Resolve<FileSystemService>(Services.FileSystemService);
|
||||
this.settingsService = Resolve<SettingsService>(Services.SettingsService);
|
||||
this.eventService = Resolve<EventService>(Services.EventService);
|
||||
|
||||
this.plugin.registerEvent(
|
||||
this.eventService.on(Event.QuickActionsSettingsChanged, () => {
|
||||
this.updateRegistrations();
|
||||
})
|
||||
);
|
||||
|
||||
this.registerViewActions();
|
||||
this.registerEditorMenuActions();
|
||||
this.registerViewActions();
|
||||
}
|
||||
|
||||
/* Edit Menu Action Definitions */
|
||||
/* Action Definitions */
|
||||
|
||||
private async beautify(menu: Menu, editor: Editor, view: MarkdownView | MarkdownFileInfo) {
|
||||
const file = view.file;
|
||||
|
|
@ -38,7 +53,7 @@ export class QuickActionsService {
|
|||
|
||||
const selection = editor.getSelection();
|
||||
const content = await this.fileSystemService.readFile(file);
|
||||
|
||||
|
||||
if (content instanceof Error || (selection.trim() === "" && content.trim() === "")) {
|
||||
return; // Either an excluded file or nothing to beautify
|
||||
}
|
||||
|
|
@ -92,65 +107,90 @@ export class QuickActionsService {
|
|||
});
|
||||
}
|
||||
|
||||
/* Registered Edit Menu Actions */
|
||||
/* Action Registration */
|
||||
|
||||
private registerEditorMenuActions() {
|
||||
// Beautify
|
||||
this.plugin.registerEvent(
|
||||
this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => {
|
||||
menu.addItem((item) => {
|
||||
if (!this.settingsService.settings.enableContextMenuActions) {
|
||||
if (this.editorMenuEventRef) {
|
||||
this.plugin.app.workspace.offref(this.editorMenuEventRef);
|
||||
this.editorMenuEventRef = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.editorMenuEventRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.editorMenuEventRef = this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => {
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Beautify")
|
||||
.setIcon("palette")
|
||||
.onClick(async () => this.beautify(menu, editor, view));
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
// Apply Template
|
||||
this.plugin.registerEvent(
|
||||
this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => {
|
||||
menu.addItem((item) => {
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Apply template")
|
||||
.setIcon("notepad-text-dashed")
|
||||
.onClick(async () => this.applyTemplate(menu, editor, view));
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
this.plugin.registerEvent(this.editorMenuEventRef);
|
||||
}
|
||||
|
||||
private registerViewActions() {
|
||||
this.plugin.registerEvent(
|
||||
this.plugin.app.workspace.on("layout-change", () => {
|
||||
const actionsView = this.workSpaceService.getViewActionsView();
|
||||
if (actionsView) {
|
||||
if (actionsView.querySelector(".vault-keeper-ai-actions")) {
|
||||
return;
|
||||
}
|
||||
const button = createEl("button", { cls: "clickable-icon view-action vault-keeper-ai-actions" });
|
||||
button.setAttribute('aria-label', 'AI Quick Actions');
|
||||
button.addEventListener('click', (evt) => {
|
||||
const view = this.workSpaceService.getActiveViewOfType(MarkdownView);
|
||||
if (view) {
|
||||
const { editor } = view;
|
||||
const menu = new Menu();
|
||||
menu.addItem((item) =>
|
||||
item.setTitle("Beautify")
|
||||
.setIcon("palette")
|
||||
.onClick(async () => this.beautify(menu, editor, view))
|
||||
);
|
||||
menu.addItem((item) =>
|
||||
item.setTitle("Apply template")
|
||||
.setIcon("notepad-text-dashed")
|
||||
.onClick(async () => this.applyTemplate(menu, editor, view))
|
||||
);
|
||||
menu.showAtMouseEvent(evt);
|
||||
}
|
||||
});
|
||||
setIcon(button, "sparkles");
|
||||
actionsView.prepend(button);
|
||||
}
|
||||
})
|
||||
);
|
||||
if (!this.settingsService.settings.enableToolbarActions) {
|
||||
if (this.layoutChangeEventRef) {
|
||||
this.plugin.app.workspace.offref(this.layoutChangeEventRef);
|
||||
this.layoutChangeEventRef = null;
|
||||
// Remove any existing toolbar buttons
|
||||
this.plugin.app.workspace.containerEl
|
||||
.querySelectorAll(".vault-keeper-ai-actions")
|
||||
.forEach(el => el.remove());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.layoutChangeEventRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.layoutChangeEventRef = this.plugin.app.workspace.on("layout-change", () => {
|
||||
this.injectToolbarButton();
|
||||
});
|
||||
this.plugin.registerEvent(this.layoutChangeEventRef);
|
||||
this.injectToolbarButton();
|
||||
}
|
||||
|
||||
private injectToolbarButton() {
|
||||
const actionsView = this.workSpaceService.getViewActionsView();
|
||||
if (!actionsView || actionsView.querySelector(".vault-keeper-ai-actions")) {
|
||||
return;
|
||||
}
|
||||
const button = createEl("button", { cls: "clickable-icon view-action vault-keeper-ai-actions" });
|
||||
button.setAttribute('aria-label', 'AI quick actions');
|
||||
button.addEventListener('click', (evt) => {
|
||||
const view = this.workSpaceService.getActiveViewOfType(MarkdownView);
|
||||
if (view) {
|
||||
const { editor } = view;
|
||||
const menu = new Menu();
|
||||
menu.addItem((item) =>
|
||||
item.setTitle("Beautify")
|
||||
.setIcon("palette")
|
||||
.onClick(async () => this.beautify(menu, editor, view))
|
||||
);
|
||||
menu.addItem((item) =>
|
||||
item.setTitle("Apply template")
|
||||
.setIcon("notepad-text-dashed")
|
||||
.onClick(async () => this.applyTemplate(menu, editor, view))
|
||||
);
|
||||
menu.showAtMouseEvent(evt);
|
||||
}
|
||||
});
|
||||
setIcon(button, "sparkles");
|
||||
actionsView.prepend(button);
|
||||
}
|
||||
|
||||
private updateRegistrations() {
|
||||
this.registerEditorMenuActions();
|
||||
this.registerViewActions();
|
||||
}
|
||||
|
||||
/* Helpers */
|
||||
|
|
@ -166,14 +206,13 @@ export class QuickActionsService {
|
|||
}
|
||||
|
||||
private async newAction(action: string, context: string): Promise<string | null> {
|
||||
if (this.settingsService.getApiKeyForCurrentModel().trim() == "") {
|
||||
openPluginSettings(this.plugin);
|
||||
return null;
|
||||
}
|
||||
const agent = Resolve<QuickAgent>(Services.QuickAgent);
|
||||
agent.resolveAIProvider();
|
||||
|
||||
const timeoutPromise = new Promise<never>((_, reject) =>
|
||||
activeWindow.setTimeout(() => reject(new DOMException(`Action timed out after ${this.actionTimeout}s`, "AbortError")), this.actionTimeout)
|
||||
);
|
||||
|
||||
return Promise.race([agent.quickAction(action, context), timeoutPromise]);
|
||||
return agent.quickAction(action, context);
|
||||
}
|
||||
|
||||
private showNotice(message: string): Notice {
|
||||
|
|
@ -186,10 +225,10 @@ export class QuickActionsService {
|
|||
height: "var(--size-4-4)",
|
||||
background: "var(--background-modifier-message)"
|
||||
}});
|
||||
|
||||
|
||||
container.createSpan({ text: message });
|
||||
fragment.appendChild(container);
|
||||
|
||||
|
||||
return new Notice(fragment, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,10 @@ const DEFAULT_SETTINGS: IVaultkeeperAISettings = {
|
|||
allowUpdatingMemories: true,
|
||||
|
||||
enableWebSearch: true,
|
||||
enableWebViewer: false
|
||||
enableWebViewer: false,
|
||||
|
||||
enableContextMenuActions: true,
|
||||
enableToolbarActions: true
|
||||
}
|
||||
|
||||
export interface IVaultkeeperAISettings {
|
||||
|
|
@ -55,6 +58,9 @@ export interface IVaultkeeperAISettings {
|
|||
|
||||
enableWebSearch: boolean;
|
||||
enableWebViewer: boolean;
|
||||
|
||||
enableContextMenuActions: boolean;
|
||||
enableToolbarActions: boolean;
|
||||
}
|
||||
|
||||
export class SettingsService {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export class WorkSpaceService {
|
|||
return activeFile;
|
||||
}
|
||||
|
||||
public getActiveViewOfType<ViewType extends View>(type: new (...args: any[]) => ViewType): ViewType | null {
|
||||
public getActiveViewOfType<ViewType extends View>(type: new (...args: WorkspaceLeaf[]) => ViewType): ViewType | null {
|
||||
return this.plugin.app.workspace.getActiveViewOfType(type);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import { AIProvider, AIProviderModel, fromModel, isValidProviderModel } from "Enums/ApiProvider";
|
||||
import { Copy } from "Enums/Copy";
|
||||
import { Event } from "Enums/Event";
|
||||
import { Selector } from "Enums/Selector";
|
||||
import type VaultkeeperAIPlugin from "main";
|
||||
import { HelpModal } from "Modals/HelpModal";
|
||||
import { DropdownComponent, PluginSettingTab, Setting, ToggleComponent, setIcon, setTooltip } from "obsidian";
|
||||
import { Resolve } from "Services/DependencyService";
|
||||
import type { EventService } from "Services/EventService";
|
||||
import type { SettingsService } from "Services/SettingsService";
|
||||
import { Services } from "Services/Services";
|
||||
import { RegisterAiProvider } from "Services/ServiceRegistration";
|
||||
|
|
@ -15,6 +17,7 @@ export class VaultkeeperAISettingTab extends PluginSettingTab {
|
|||
private readonly plugin: VaultkeeperAIPlugin;
|
||||
private readonly settingsService: SettingsService;
|
||||
private readonly memoriesService: MemoriesService;
|
||||
private readonly eventService: EventService;
|
||||
|
||||
private apiKeySetting: Setting | null = null;
|
||||
private apiKeyInputEl: HTMLInputElement | null = null;
|
||||
|
|
@ -32,6 +35,7 @@ export class VaultkeeperAISettingTab extends PluginSettingTab {
|
|||
|
||||
this.settingsService = Resolve<SettingsService>(Services.SettingsService);
|
||||
this.memoriesService = Resolve<MemoriesService>(Services.MemoriesService);
|
||||
this.eventService = Resolve<EventService>(Services.EventService);
|
||||
}
|
||||
|
||||
public display() {
|
||||
|
|
@ -263,7 +267,42 @@ export class VaultkeeperAISettingTab extends PluginSettingTab {
|
|||
});
|
||||
setIcon(button.extraSettingsEl, "clipboard-clock");
|
||||
});
|
||||
this.updateFileDisclaimer();
|
||||
this.updateFileDisclaimer();
|
||||
|
||||
/* Quick Actions Header */
|
||||
new Setting(containerEl)
|
||||
.setHeading()
|
||||
.setName(Copy.SettingQuickActions);
|
||||
|
||||
/* Enable Context Menu Actions */
|
||||
new Setting(containerEl)
|
||||
.setName(Copy.SettingEnableContextMenuActions)
|
||||
.setDesc(Copy.SettingEnableContextMenuActionsDesc)
|
||||
.addToggle(toggle => {
|
||||
toggle
|
||||
.setValue(this.settingsService.settings.enableContextMenuActions)
|
||||
.onChange(async (value) => {
|
||||
this.settingsService.settings.enableContextMenuActions = value;
|
||||
await this.settingsService.saveSettings(() =>
|
||||
this.eventService.trigger(Event.QuickActionsSettingsChanged)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
/* Enable Toolbar Actions */
|
||||
new Setting(containerEl)
|
||||
.setName(Copy.SettingEnableToolbarActions)
|
||||
.setDesc(Copy.SettingEnableToolbarActionsDesc)
|
||||
.addToggle(toggle => {
|
||||
toggle
|
||||
.setValue(this.settingsService.settings.enableToolbarActions)
|
||||
.onChange(async (value) => {
|
||||
this.settingsService.settings.enableToolbarActions = value;
|
||||
await this.settingsService.saveSettings(() =>
|
||||
this.eventService.trigger(Event.QuickActionsSettingsChanged)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private populateModelDropdown(dropdown: DropdownComponent, providerFilter?: AIProvider): void {
|
||||
|
|
|
|||
|
|
@ -107,7 +107,9 @@ describe('SettingsService', () => {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Claude,
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
settingsService = new SettingsService(loadedSettings);
|
||||
});
|
||||
|
|
@ -154,7 +156,9 @@ describe('SettingsService', () => {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Claude,
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
settingsService = new SettingsService(loadedSettings);
|
||||
|
||||
|
|
@ -181,7 +185,9 @@ describe('SettingsService', () => {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.OpenAI,
|
||||
quickActionModel: AIProviderModel.GPT_5_4_Mini
|
||||
quickActionModel: AIProviderModel.GPT_5_4_Mini,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
settingsService = new SettingsService(loadedSettings);
|
||||
|
||||
|
|
@ -208,7 +214,9 @@ describe('SettingsService', () => {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Gemini,
|
||||
quickActionModel: AIProviderModel.GeminiFlash_2_5
|
||||
quickActionModel: AIProviderModel.GeminiFlash_2_5,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
settingsService = new SettingsService(loadedSettings);
|
||||
|
||||
|
|
@ -263,7 +271,9 @@ describe('SettingsService', () => {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Claude,
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
settingsService = new SettingsService(loadedSettings);
|
||||
});
|
||||
|
|
@ -324,7 +334,9 @@ describe('SettingsService', () => {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Claude,
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
settingsService = new SettingsService(loadedSettings);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -105,7 +105,9 @@ const mockSettings: IVaultkeeperAISettings = {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Claude,
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
|
||||
let settingsService: SettingsService;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,9 @@ const mockSettings: IVaultkeeperAISettings = {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Claude,
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
|
||||
const mockPlugin = {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,9 @@ const mockSettings: IVaultkeeperAISettings = {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Claude,
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
|
||||
let settingsService: SettingsService;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ const mockSettings: IVaultkeeperAISettings = {
|
|||
enableWebSearch: true,
|
||||
enableWebViewer: false,
|
||||
provider: AIProvider.Claude,
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6
|
||||
quickActionModel: AIProviderModel.ClaudeSonnet_4_6,
|
||||
enableContextMenuActions: false,
|
||||
enableToolbarActions: false
|
||||
};
|
||||
|
||||
const mockPlugin = {
|
||||
|
|
|
|||
24
package-lock.json
generated
24
package-lock.json
generated
|
|
@ -9,7 +9,7 @@
|
|||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.90.0",
|
||||
"@anthropic-ai/sdk": "^0.91.0",
|
||||
"@google/genai": "^1.50.1",
|
||||
"@shikijs/rehype": "^4.0.2",
|
||||
"core-js": "^3.49.0",
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
"eslint-plugin-obsidianmd": "^0.2.4",
|
||||
"happy-dom": "^20.9.0",
|
||||
"obsidian": "latest",
|
||||
"svelte": "^5.55.4",
|
||||
"svelte": "^5.55.5",
|
||||
"svelte-check": "^4.4.6",
|
||||
"svelte-preprocess": "^6.0.3",
|
||||
"tslib": "2.8.1",
|
||||
|
|
@ -64,9 +64,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/sdk": {
|
||||
"version": "0.90.0",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.90.0.tgz",
|
||||
"integrity": "sha512-MzZtPabJF1b0FTDl6Z6H5ljphPwACLGP13lu8MTiB8jXaW/YXlpOp+Po2cVou3MPM5+f5toyLnul9whKCy7fBg==",
|
||||
"version": "0.91.0",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.91.0.tgz",
|
||||
"integrity": "sha512-hybd/DOI3ujG4gZyqqcWnSekYxkdjr1JbZYqP2Lb4AmcsU6HCTHSrTOgqedPSsQAruBVucHNAoD1vTQnpPzedw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"json-schema-to-ts": "^3.1.1"
|
||||
|
|
@ -3725,14 +3725,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.20.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz",
|
||||
"integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==",
|
||||
"version": "5.21.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz",
|
||||
"integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.3.0"
|
||||
"tapable": "^2.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
|
|
@ -10270,9 +10270,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "5.55.4",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.4.tgz",
|
||||
"integrity": "sha512-q8DFohk6vUswSng95IZb9nzWJnbINZsK7OiM1snAa3qCjJBL0ZQpvMyAaVXjUukdM75J/m8UE8xwqat8Ors/zQ==",
|
||||
"version": "5.55.5",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.5.tgz",
|
||||
"integrity": "sha512-2uCs/LZ9us+AktdzYJM8OcxQ8qnPS1kpaO7syGT/MgO+6Qr1Ybl+TqPq+97u7PHqmmMlye5ZkoyXONy5mjjAbw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
"eslint-plugin-obsidianmd": "^0.2.4",
|
||||
"happy-dom": "^20.9.0",
|
||||
"obsidian": "latest",
|
||||
"svelte": "^5.55.4",
|
||||
"svelte": "^5.55.5",
|
||||
"svelte-check": "^4.4.6",
|
||||
"svelte-preprocess": "^6.0.3",
|
||||
"tslib": "2.8.1",
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
"vitest": "^4.1.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.90.0",
|
||||
"@anthropic-ai/sdk": "^0.91.0",
|
||||
"@google/genai": "^1.50.1",
|
||||
"@shikijs/rehype": "^4.0.2",
|
||||
"core-js": "^3.49.0",
|
||||
|
|
|
|||
Loading…
Reference in a new issue