vault backup: 2026-01-26 17:57:11
This commit is contained in:
Vendored
+413
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
};
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
.note-buddy-chat {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.note-buddy-chat h2 {
|
||||
margin: 10px;
|
||||
font-size: var(--font-ui-medium);
|
||||
color: var(--text-normal);
|
||||
font-weight: var(--font-semibold);
|
||||
}
|
||||
|
||||
.message-container {
|
||||
background-color: var(--background-primary-alt);
|
||||
border-radius: var(--radius-md);
|
||||
margin: 0 10px 10px 10px;
|
||||
}
|
||||
|
||||
.input-bar textarea {
|
||||
background-color: var(--background-primary);
|
||||
color: var(--text-normal);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: var(--radius-sm);
|
||||
font-family: var(--font-interface);
|
||||
font-size: var(--font-ui-sm);
|
||||
}
|
||||
|
||||
.input-bar textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--interactive-accent);
|
||||
}
|
||||
|
||||
.input-bar button {
|
||||
background-color: var(--interactive-accent);
|
||||
color: var(--text-on-accent);
|
||||
border: none;
|
||||
border-radius: var(--radius-sm);
|
||||
font-family: var(--font-interface);
|
||||
font-weight: var(--font-semibold);
|
||||
font-size: var(--font-ui-sm);
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.input-bar button:hover {
|
||||
background-color: var(--interactive-accent-hover);
|
||||
}
|
||||
Reference in New Issue
Block a user