2026-01-26 17:57:11 +08:00
/*
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"
};
2026-01-30 10:38:04 +08:00
var MODELS_CACHE_TTL = 5 * 60 * 1e3 ;
2026-01-26 17:57:11 +08:00
// src/service.ts
2026-01-30 10:38:04 +08:00
var OpenCodeClient = class _OpenCodeClient {
constructor ( serviceUrl , defaultModelId , onModelUnavailable ) {
2026-01-26 17:57:11 +08:00
this . session = null ;
2026-01-30 10:38:04 +08:00
this . cachedProviders = null ;
this . providersCacheTime = 0 ;
this . cachedDefaults = null ;
2026-01-26 17:57:11 +08:00
this . serviceUrl = serviceUrl ;
2026-01-30 10:38:04 +08:00
this . defaultModelId = defaultModelId ;
this . onModelUnavailable = onModelUnavailable ;
2026-01-26 17:57:11 +08:00
}
2026-01-30 10:38:04 +08:00
static {
this . DEFAULT_REQUEST_TIMEOUT_MS = 1e4 ;
}
static {
this . MESSAGE_REQUEST_TIMEOUT_MS = 6e4 ;
}
async request ( options , timeoutMs = _OpenCodeClient . DEFAULT_REQUEST_TIMEOUT_MS ) {
2026-01-26 17:57:11 +08:00
return await Promise . race ([
( 0 , import_obsidian . requestUrl )( options ),
new Promise (
2026-01-30 10:38:04 +08:00
( _ , reject ) => setTimeout (() => reject ( new Error ( `Request timeout after ${ timeoutMs / 1e3 } seconds` )), timeoutMs )
2026-01-26 17:57:11 +08:00
)
]);
}
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 {
2026-01-30 10:38:04 +08:00
sessionID : data . id ,
createTime : data . time . created ,
2026-01-26 17:57:11 +08:00
title : data . title
};
}
2026-01-30 10:38:04 +08:00
if ( response . status === 400 ) {
const details = this . formatBadRequest ( response . json , response . text );
throw new Error ( details );
}
throw new Error ( `HTTP ${ response . status } : ${ response . text } ` );
2026-01-26 17:57:11 +08:00
} catch ( error ) {
const err = error ;
throw new Error ( `Failed to create session: ${ err . message } ` );
}
}
2026-01-30 10:38:04 +08:00
formatBadRequest ( payload , fallbackText ) {
if ( ! payload || typeof payload !== "object" ) {
return `Bad request: ${ fallbackText || "Unknown error" } ` ;
}
const p = payload ;
const errText = typeof p . errors === "string" ? p . errors : p . errors ? JSON . stringify ( p . errors ) : "" ;
const dataText = p . data ? JSON . stringify ( p . data ) : "" ;
const msg = [ errText , dataText ]. filter ( Boolean ). join ( " " );
return msg ? `Bad request: ${ msg } ` : `Bad request: ${ fallbackText || "Unknown error" } ` ;
}
formatNotFound ( payload , fallbackText ) {
if ( ! payload || typeof payload !== "object" ) {
return fallbackText || "Not found" ;
}
const p = payload ;
const name = typeof p . name === "string" ? p . name : "" ;
const data = p . data ? JSON . stringify ( p . data ) : "" ;
return [ name , data ]. filter ( Boolean ). join ( " " ) || fallbackText || "Not found" ;
}
2026-01-26 17:57:11 +08:00
async sendMessageInternal ( sessionID , message ) {
const url = ` ${ this . serviceUrl } /session/ ${ sessionID } /message` ;
try {
2026-01-30 10:38:04 +08:00
const response = await this . request (
{
url ,
method : "POST" ,
headers : {
"Content-Type" : "application/json"
},
body : JSON . stringify ( message )
2026-01-26 17:57:11 +08:00
},
2026-01-30 10:38:04 +08:00
_OpenCodeClient . MESSAGE_REQUEST_TIMEOUT_MS
);
2026-01-26 17:57:11 +08:00
if ( response . status === 200 ) {
2026-01-30 10:38:04 +08:00
const raw = ( response . text ?? "" ). trim ();
if ( ! raw ) {
throw new Error ( "Server returned empty response" );
}
let data ;
try {
data = JSON . parse ( raw );
} catch {
throw new Error ( `Invalid JSON response: ${ raw . slice ( 0 , 50 ) }${ raw . length > 50 ? "..." : "" } ` );
}
if ( ! data || typeof data !== "object" || ! Array . isArray ( data . parts )) {
throw new Error ( "Invalid response shape (expected {info, parts[]})" );
}
return data ;
2026-01-26 17:57:11 +08:00
}
2026-01-30 10:38:04 +08:00
if ( response . status === 400 ) {
const payload = response . json ;
throw new Error ( this . formatBadRequest ( payload , response . text ));
}
if ( response . status === 404 ) {
const payload = response . json ;
throw new Error ( `Session not found: ${ this . formatNotFound ( payload , response . text ) } ` );
}
throw new Error ( `HTTP ${ response . status } : ${ response . text } ` );
2026-01-26 17:57:11 +08:00
} 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 = {
2026-01-30 10:38:04 +08:00
parts : [{ type : "text" , text : input }]
2026-01-26 17:57:11 +08:00
};
2026-01-30 10:38:04 +08:00
if ( this . defaultModelId ) {
const parts = this . defaultModelId . split ( "/" );
if ( parts . length === 2 ) {
message . model = {
providerID : parts [ 0 ],
modelID : parts [ 1 ]
};
}
}
let response ;
try {
response = await this . sendMessageInternal ( this . session . sessionID , message );
} catch ( error ) {
const err = error ;
if ( message . model && this . isLikelyModelError ( err )) {
console . log ( "[NoteBuddy] Selected model unavailable, falling back to server default" );
if ( this . onModelUnavailable ) {
this . onModelUnavailable ();
}
const fallbackMessage = {
parts : message . parts
};
response = await this . sendMessageInternal ( this . session . sessionID , fallbackMessage );
} else {
throw error ;
}
}
const assistantText = response . parts . filter (( part ) => part . type === "text" ). map (( part ) => part . type === "text" ? part . text : "" ). filter ( Boolean ). join ( "\n" );
2026-01-26 17:57:11 +08:00
return assistantText ;
}
async sendMessageToSession ( sessionID , message ) {
return await this . sendMessageInternal ( sessionID , message );
}
2026-01-30 10:38:04 +08:00
isModelsCacheValid () {
if ( ! this . cachedProviders ) {
return false ;
}
const now = Date . now ();
return now - this . providersCacheTime < MODELS_CACHE_TTL ;
}
clearModelsCache () {
this . cachedProviders = null ;
this . providersCacheTime = 0 ;
this . cachedDefaults = null ;
}
async getCapabilities ( forceRefresh = false ) {
const now = Date . now ();
if ( ! forceRefresh && this . cachedProviders && now - this . providersCacheTime < MODELS_CACHE_TTL ) {
return this . cachedProviders ;
}
const url = ` ${ this . serviceUrl } /config/providers` ;
try {
const response = await this . request ({
url ,
method : "GET"
});
if ( response . status === 200 ) {
let data ;
try {
data = response . json ;
} catch {
const preview = ( response . text || "" ). trim (). slice ( 0 , 50 );
if ( preview . toLowerCase (). startsWith ( "<!" )) {
throw new Error (
"Server returned HTML instead of JSON. Check the Service URL and ensure the server exposes /config/providers."
);
}
throw new Error ( `Invalid JSON response: ${ preview } ...` );
}
const raw = data . providers || [];
this . cachedDefaults = data . default || {};
const providers = raw . map (( p ) => ({
id : p . id ,
name : p . name ,
models : Object . entries ( p . models || {}). map (([ id , m ]) => ({ id , name : m ? . name ?? id }))
}));
this . cachedProviders = providers ;
this . providersCacheTime = now ;
return providers ;
} else {
throw new Error ( `HTTP ${ response . status } : ${ response . text } ` );
}
} catch ( error ) {
const err = error ;
throw new Error ( `Failed to get capabilities: ${ err . message } ` );
}
}
isLikelyModelError ( err ) {
const msg = ( err . message || "" ). toLowerCase ();
return msg . includes ( "model" ) && ( msg . includes ( "not found" ) || msg . includes ( "invalid" ) || msg . includes ( "unknown" ));
}
2026-01-26 17:57:11 +08:00
};
// 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 = [];
2026-01-30 10:38:04 +08:00
this . client = new OpenCodeClient (
plugin . settings . serviceUrl ,
plugin . settings . defaultModelId ,
plugin . onModelUnavailable ? . bind ( plugin )
);
2026-01-26 17:57:11 +08:00
}
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 ;
2026-01-30 10:38:04 +08:00
this . messages . push ({ kind : "userText" , text : message });
2026-01-26 17:57:11 +08:00
this . renderMessages ();
textarea . value = "" ;
try {
if ( ! this . plugin . sessionState ) {
this . plugin . sessionState = await this . client . createSession ();
}
const sendData = {
2026-01-30 10:38:04 +08:00
parts : [{ type : "text" , text : message }]
2026-01-26 17:57:11 +08:00
};
2026-01-30 10:38:04 +08:00
if ( this . plugin . settings . defaultModelId ) {
const parts = this . plugin . settings . defaultModelId . split ( "/" );
if ( parts . length === 2 ) {
sendData . model = {
providerID : parts [ 0 ],
modelID : parts [ 1 ]
};
}
}
2026-01-26 17:57:11 +08:00
let response ;
try {
response = await this . client . sendMessageToSession ( this . plugin . sessionState . sessionID , sendData );
} catch ( sendError ) {
const err = sendError ;
2026-01-30 10:38:04 +08:00
if ( err . message . includes ( "Session not found" )) {
2026-01-26 17:57:11 +08:00
this . plugin . sessionState = await this . client . createSession ();
response = await this . client . sendMessageToSession ( this . plugin . sessionState . sessionID , sendData );
} else {
throw sendError ;
}
}
2026-01-30 10:38:04 +08:00
for ( const part of response . parts ) {
this . messages . push ({ kind : "assistantPart" , part });
}
2026-01-26 17:57:11 +08:00
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 ;
}
2026-01-30 10:38:04 +08:00
for ( const item of this . messages ) {
if ( item . kind === "userText" ) {
const messageEl2 = this . messagesContainer . createDiv ({ cls : "nb-message nb-message-user" });
messageEl2 . createSpan ({ text : item . text });
messageEl2 . style . cssText = `
padding: 0.75rem;
background-color: var(--background-modifier-accent);
border-radius: 0.5rem;
font-size: 0.9rem;
align-self: flex-end;
max-width: 70%;
` ;
continue ;
}
const part = item . part ;
const messageEl = this . messagesContainer . createDiv ({ cls : "nb-message nb-message-assistant" });
2026-01-26 17:57:11 +08:00
messageEl . style . cssText = `
padding: 0.75rem;
2026-01-30 10:38:04 +08:00
background-color: var(--background-secondary);
2026-01-26 17:57:11 +08:00
border-radius: 0.5rem;
font-size: 0.9rem;
2026-01-30 10:38:04 +08:00
align-self: flex-start;
2026-01-26 17:57:11 +08:00
max-width: 70%;
` ;
2026-01-30 10:38:04 +08:00
switch ( part . type ) {
case "text" :
messageEl . createSpan ({ text : part . text });
break ;
case "reasoning" :
messageEl . createSpan ({ text : part . text });
break ;
case "tool" :
messageEl . createEl ( "strong" , { text : `Tool: ${ part . tool } ` });
messageEl . createEl ( "pre" , { text : JSON . stringify ( part . state ?? {}, null , 2 ) });
break ;
case "patch" :
messageEl . createEl ( "strong" , { text : `Patch: ${ part . hash } ` });
messageEl . createEl ( "pre" , { text : ( part . files || []). join ( "\n" ) });
break ;
case "file" :
messageEl . createEl ( "strong" , { text : `File: ${ part . filename ?? part . url } ` });
messageEl . createEl ( "div" , { text : `mime: ${ part . mime } ` });
messageEl . createEl ( "div" , { text : `url: ${ part . url } ` });
break ;
case "agent" :
messageEl . createEl ( "strong" , { text : `Agent: ${ part . name } ` });
break ;
case "step_start" :
messageEl . createEl ( "strong" , { text : `Step start ${ part . title ? `: ${ part . title } ` : "" } ` });
break ;
case "step_finish" :
messageEl . createEl ( "strong" , { text : `Step finish ${ part . title ? `: ${ part . title } ` : "" } ` });
break ;
case "snapshot" :
messageEl . createEl ( "strong" , { text : "Snapshot" });
messageEl . createEl ( "pre" , { text : JSON . stringify ( part , null , 2 ) });
break ;
case "retry" :
messageEl . createEl ( "strong" , { text : "Retry" });
messageEl . createEl ( "pre" , { text : JSON . stringify ( part , null , 2 ) });
break ;
case "compaction" :
messageEl . createEl ( "strong" , { text : "Compaction" });
messageEl . createEl ( "pre" , { text : JSON . stringify ( part , null , 2 ) });
break ;
case "unknown" :
messageEl . createEl ( "strong" , {
text : `Unsupported part type: ${ part . originalType } `
});
messageEl . createEl ( "pre" , { text : JSON . stringify ( part , null , 2 ) });
break ;
}
2026-01-26 17:57:11 +08:00
}
}
};
// src/settings.ts
var import_obsidian3 = require ( "obsidian" );
var NoteBuddySettingTab = class extends import_obsidian3 . PluginSettingTab {
constructor ( app , plugin ) {
super ( app , plugin );
2026-01-30 10:38:04 +08:00
this . providers = [];
this . isLoadingModels = false ;
2026-01-26 17:57:11 +08:00
this . plugin = plugin ;
}
2026-01-30 10:38:04 +08:00
async display ( useCachedProviders ) {
2026-01-26 17:57:11 +08:00
const { containerEl } = this ;
containerEl . empty ();
containerEl . createEl ( "h2" , { text : "NoteBuddy Settings" });
2026-01-30 10:38:04 +08:00
if ( ! useCachedProviders ) {
try {
await this . loadProviders ();
} catch {
}
}
2026-01-26 17:57:11 +08:00
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 () => {
2026-01-30 10:38:04 +08:00
const client = new OpenCodeClient ( this . plugin . settings . serviceUrl , this . plugin . settings . defaultModelId );
2026-01-26 17:57:11 +08:00
const result = await client . healthCheck ();
if ( result . status === "connected" ) {
new import_obsidian3 . Notice ( "Connection successful!" );
} else {
new import_obsidian3 . Notice ( `Connection failed: ${ result . lastError } ` );
}
})
);
2026-01-30 10:38:04 +08:00
this . displayModelSelection ( containerEl );
this . displayRefreshButton ( containerEl );
}
async loadProviders ( client , forceRefresh ) {
if ( this . isLoadingModels ) {
return ;
}
this . isLoadingModels = true ;
try {
const c = client ?? new OpenCodeClient ( this . plugin . settings . serviceUrl , this . plugin . settings . defaultModelId );
this . providers = await c . getCapabilities ( forceRefresh ?? false );
} catch ( error ) {
this . providers = [];
console . error ( "[NoteBuddy] Failed to load providers:" , error );
throw error ;
} finally {
this . isLoadingModels = false ;
}
}
displayModelSelection ( containerEl ) {
const modelOptions = {};
modelOptions [ "" ] = "Use server default" ;
for ( const provider of this . providers ) {
for ( const model of provider . models ) {
const value = ` ${ provider . id } / ${ model . id } ` ;
modelOptions [ value ] = ` ${ provider . name } - ${ model . name } ` ;
}
}
const currentValue = this . getCurrentModelSelection ();
new import_obsidian3 . Setting ( containerEl ). setName ( "Default Model" ). setDesc ( "Select the default AI model to use for conversations" ). addDropdown (
( dropdown ) => dropdown . addOptions ( modelOptions ). setValue ( currentValue ). onChange ( async ( value ) => {
if ( value ) {
this . plugin . settings . defaultModelId = value ;
} else {
this . plugin . settings . defaultModelId = void 0 ;
}
await this . plugin . saveSettings ();
})
);
}
getCurrentModelSelection () {
return this . plugin . settings . defaultModelId || "" ;
}
displayRefreshButton ( container ) {
new import_obsidian3 . Setting ( container ). setName ( "Refresh Models" ). setDesc ( "Reload the list of available models from the service" ). addButton (
( button ) => button . setButtonText ( "Refresh" ). onClick ( async () => {
const client = new OpenCodeClient ( this . plugin . settings . serviceUrl , this . plugin . settings . defaultModelId );
client . clearModelsCache ();
try {
await this . loadProviders ( client , true );
new import_obsidian3 . Notice ( "Models refreshed" );
await this . display ( true );
} catch ( error ) {
console . error ( "[NoteBuddy] Failed to load providers:" , error );
new import_obsidian3 . Notice ( `Failed to refresh models: ${ error . message } ` );
await this . display ( true );
}
})
);
2026-01-26 17:57:11 +08:00
}
};
// 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 ());
}
2026-01-30 10:38:04 +08:00
// Callback for when selected model is unavailable
onModelUnavailable () {
new import_obsidian4 . Notice ( "Selected model is unavailable. Using server default instead." );
}
2026-01-26 17:57:11 +08:00
async saveSettings () {
await this . saveData ( this . settings );
}
};