/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => NoteBuddyPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian4 = require("obsidian"); // src/chat-view.ts var import_obsidian2 = require("obsidian"); // src/service.ts var import_obsidian = require("obsidian"); // src/models.ts var defaultSettings = { serviceUrl: "http://127.0.0.1:4096" }; // src/service.ts var OpenCodeClient = class { constructor(serviceUrl) { this.session = null; this.serviceUrl = serviceUrl; } async request(options) { return await Promise.race([ (0, import_obsidian.requestUrl)(options), new Promise( (_, reject) => setTimeout(() => reject(new Error("Request timeout after 10 seconds")), 1e4) ) ]); } async healthCheck() { const url = `${this.serviceUrl}/global/health`; try { const response = await this.request({ url, method: "GET" }); if (response.status === 200 && response.json.healthy === true) { return { status: "connected" /* Connected */, lastTestTime: Date.now() }; } else { return { status: "disconnected" /* Disconnected */, lastTestTime: Date.now(), lastError: `Service unhealthy or unreachable` }; } } catch (error) { const err = error; return { status: "disconnected" /* Disconnected */, lastTestTime: Date.now(), lastError: err.message || "Unknown error" }; } } async createSession() { const url = `${this.serviceUrl}/session`; try { const response = await this.request({ url, method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({}) }); if (response.status === 200) { const data = response.json; return { sessionID: data.sessionID, createTime: data.createTime, title: data.title }; } else { throw new Error(`HTTP ${response.status}: ${response.text}`); } } catch (error) { const err = error; throw new Error(`Failed to create session: ${err.message}`); } } async sendMessageInternal(sessionID, message) { const url = `${this.serviceUrl}/session/${sessionID}/message`; try { const response = await this.request({ url, method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(message) }); if (response.status === 200) { return response.json; } else if (response.status === 404) { throw new Error("Session not found"); } else { throw new Error(`HTTP ${response.status}: ${response.text}`); } } catch (error) { const err = error; throw new Error(`Failed to send message: ${err.message}`); } } async sendMessage(input) { if (!this.session) { this.session = await this.createSession(); } const message = { parts: [{ text: input, role: "user" }] }; const response = await this.sendMessageInternal(this.session.sessionID, message); const assistantParts = response.parts.filter((part) => part.role === "assistant"); const assistantText = assistantParts.map((part) => part.text).join("\n"); return assistantText; } async sendMessageToSession(sessionID, message) { return await this.sendMessageInternal(sessionID, message); } }; // src/chat-view.ts var VIEW_TYPE_CHAT = "note-buddy-chat-view"; var ChatView = class extends import_obsidian2.ItemView { constructor(leaf, plugin) { super(leaf); this.plugin = plugin; this.messages = []; this.client = new OpenCodeClient(plugin.settings.serviceUrl); } getViewType() { return VIEW_TYPE_CHAT; } getDisplayText() { return "NoteBuddy Chat"; } async onOpen() { const container = this.containerEl.children[1]; container.empty(); const chatContainer = container.createDiv({ cls: "nb-chat-container" }); chatContainer.style.cssText = ` display: flex; flex-direction: column; height: 100%; gap: 1rem; `; const messagesContainer = chatContainer.createDiv({ cls: "nb-messages-container" }); this.messagesContainer = messagesContainer; messagesContainer.style.cssText = ` flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 0.5rem; padding: 1rem; `; this.renderMessages(); const welcomeMessage = messagesContainer.createDiv({ cls: "nb-message nb-message-system" }); welcomeMessage.createSpan({ text: "Welcome to NoteBuddy! Chat with your notes here." }); welcomeMessage.style.cssText = ` padding: 0.75rem; background-color: var(--background-secondary); border-radius: 0.5rem; font-size: 0.9rem; color: var(--text-muted); `; const inputContainer = chatContainer.createDiv({ cls: "nb-input-container" }); inputContainer.style.cssText = ` display: flex; gap: 0.5rem; padding: 1rem; border-top: 1px solid var(--background-modifier-border); `; const textarea = inputContainer.createEl("textarea", { cls: "nb-chat-input", attr: { placeholder: "Type your message..." } }); textarea.style.cssText = ` flex: 1; min-height: 60px; max-height: 150px; padding: 0.5rem; border: 1px solid var(--background-modifier-border); border-radius: 0.375rem; background-color: var(--background-primary); color: var(--text-normal); resize: vertical; font-family: inherit; `; const sendButton = inputContainer.createEl("button", { cls: "nb-send-button", text: "Send" }); sendButton.style.cssText = ` padding: 0.5rem 1rem; background-color: var(--interactive-accent); color: var(--text-on-accent); border: none; border-radius: 0.375rem; cursor: pointer; font-weight: 500; `; const sendMessage = async () => { const message = textarea.value.trim(); if (!message) return; this.messages.push({ text: message, role: "user" }); this.renderMessages(); textarea.value = ""; try { if (!this.plugin.sessionState) { this.plugin.sessionState = await this.client.createSession(); } const sendData = { parts: [{ text: message, role: "user" }], model: { providerID: "anthropic", modelID: "claude-3-5-sonnet-20241022" } }; let response; try { response = await this.client.sendMessageToSession(this.plugin.sessionState.sessionID, sendData); } catch (sendError) { const err = sendError; if (err.message.includes("Session not found") || err.message.includes("404")) { this.plugin.sessionState = await this.client.createSession(); response = await this.client.sendMessageToSession(this.plugin.sessionState.sessionID, sendData); } else { throw sendError; } } this.messages.push(...response.parts); this.renderMessages(); this.messagesContainer.scrollTop = this.messagesContainer.scrollHeight; } catch (error) { console.error("[NoteBuddy] Send failed:", error); new import_obsidian2.Notice(`Failed to send message: ${error.message}`); } }; sendButton.onclick = sendMessage; textarea.addEventListener("keydown", (e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); } async onClose() { console.log("[NoteBuddy] Chat view closed"); } renderMessages() { this.messagesContainer.empty(); if (this.messages.length === 0) { const welcomeMessage = this.messagesContainer.createDiv({ cls: "nb-message nb-message-system" }); welcomeMessage.createSpan({ text: "Welcome to NoteBuddy! Chat with your notes here." }); welcomeMessage.style.cssText = ` padding: 0.75rem; background-color: var(--background-secondary); border-radius: 0.5rem; font-size: 0.9rem; color: var(--text-muted); `; return; } for (const message of this.messages) { const messageEl = this.messagesContainer.createDiv({ cls: `nb-message nb-message-${message.role}` }); messageEl.createSpan({ text: message.text }); messageEl.style.cssText = ` padding: 0.75rem; background-color: ${message.role === "user" ? "var(--background-modifier-accent)" : "var(--background-secondary)"}; border-radius: 0.5rem; font-size: 0.9rem; align-self: ${message.role === "user" ? "flex-end" : "flex-start"}; max-width: 70%; `; } } }; // src/settings.ts var import_obsidian3 = require("obsidian"); var NoteBuddySettingTab = class extends import_obsidian3.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); containerEl.createEl("h2", { text: "NoteBuddy Settings" }); new import_obsidian3.Setting(containerEl).setName("Service URL").setDesc("The URL of the OpenCode service (must include protocol, hostname, and port)").addText( (text) => text.setPlaceholder("http://127.0.0.1:4096").setValue(this.plugin.settings.serviceUrl).onChange(async (value) => { if (!value.startsWith("http://") && !value.startsWith("https://")) { new import_obsidian3.Notice("Service URL must start with http:// or https://"); return; } try { const url = new URL(value); if (!url.hostname || url.hostname === "") { new import_obsidian3.Notice("Service URL must include a valid hostname"); return; } if (!url.port || url.port === "") { new import_obsidian3.Notice("Service URL must include a port number"); return; } } catch (e) { new import_obsidian3.Notice("Service URL must be a valid URL format"); return; } this.plugin.settings.serviceUrl = value; await this.plugin.saveSettings(); }) ); new import_obsidian3.Setting(containerEl).setName("Test Connection").setDesc("Test the connection to the service").addButton( (button) => button.setButtonText("Test").setCta().onClick(async () => { const client = new OpenCodeClient(this.plugin.settings.serviceUrl); const result = await client.healthCheck(); if (result.status === "connected") { new import_obsidian3.Notice("Connection successful!"); } else { new import_obsidian3.Notice(`Connection failed: ${result.lastError}`); } }) ); } }; // src/main.ts var DEFAULT_SETTINGS = defaultSettings; var NoteBuddyPlugin = class extends import_obsidian4.Plugin { constructor() { super(...arguments); this.ribbonIconEl = null; } async onload() { console.log("Loading NoteBuddy plugin..."); await this.loadSettings(); this.registerView( VIEW_TYPE_CHAT, (leaf) => new ChatView(leaf, this) ); this.addRibbonIcon("bot", "NoteBuddy", () => { this.activateView(); }); this.addCommand({ id: "open-chat-view", name: "Open NoteBuddy Chat", callback: () => { this.activateView(); } }); this.app.workspace.onLayoutReady(() => { this.activateView(); }); this.addSettingTab(new NoteBuddySettingTab(this.app, this)); } onunload() { console.log("Unloading NoteBuddy plugin..."); } async activateView() { const { workspace } = this.app; let leaf = null; const leaves = workspace.getLeavesOfType(VIEW_TYPE_CHAT); if (leaves.length > 0) { leaf = leaves[0]; } else { leaf = workspace.getRightLeaf(false); } if (leaf) { await workspace.setActiveLeaf(leaf); await leaf.setViewState({ type: VIEW_TYPE_CHAT, active: true }); } } async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings() { await this.saveData(this.settings); } };