Add direct tool slash commands
This commit is contained in:
@@ -1127,7 +1127,7 @@ export function openPanel() {
|
||||
<span class="notes-header-btn-label">Toggle</span>
|
||||
</button>
|
||||
<button id="notes-minimize-btn" class="modal-minimize-btn" title="Minimize" aria-label="Minimize notes" style="position:relative;left:2px;"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.4" stroke-linecap="round" aria-hidden="true"><line x1="6" y1="18" x2="18" y2="18"/></svg></button>
|
||||
<button id="notes-close-btn" class="close-btn" title="Close" aria-label="Close notes">✖</button>
|
||||
<button id="notes-close-btn" class="close-btn" title="Close" aria-label="Close notes">×</button>
|
||||
</div>
|
||||
<div class="notes-search-bar">
|
||||
<input type="text" id="notes-search" class="memory-search-input" placeholder="Search notes…" autocomplete="off" />
|
||||
|
||||
@@ -1194,22 +1194,6 @@ async function _cmdToggleSidebar(args, ctx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ── Mode ──
|
||||
|
||||
async function _cmdMode(args, ctx) {
|
||||
const mode = (args[0] || '').toLowerCase();
|
||||
if (mode !== 'agent' && mode !== 'chat') {
|
||||
slashReply(`Current mode: ${Storage.getToggle('mode', 'chat')}. Usage: /mode <agent|chat>`);
|
||||
return true;
|
||||
}
|
||||
const ab = document.getElementById('mode-agent-btn'), cb = document.getElementById('mode-chat-btn');
|
||||
if (ab && cb) { ab.classList.toggle('active', mode === 'agent'); cb.classList.toggle('active', mode === 'chat'); }
|
||||
Storage.setToggle('mode', mode);
|
||||
document.querySelectorAll('[data-mode-tool]').forEach(b => { b.style.display = mode === 'agent' ? '' : 'none'; });
|
||||
await typewriterReply(`Mode: ${mode}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ── Settings ──
|
||||
|
||||
async function _cmdOpen(args, ctx) {
|
||||
@@ -1241,9 +1225,15 @@ async function _cmdOpen(args, ctx) {
|
||||
notes: ['tool-notes-btn', 'rail-notes'],
|
||||
tasks: ['tool-tasks-btn', 'rail-tasks'],
|
||||
library: ['tool-library-btn', 'rail-archive'],
|
||||
documents: ['tool-library-btn', 'rail-archive'],
|
||||
docs: ['tool-library-btn', 'rail-archive'],
|
||||
archive: ['tool-library-btn', 'rail-archive'],
|
||||
brain: ['tool-memory-btn', 'rail-memory'],
|
||||
memory: ['tool-memory-btn', 'rail-memory'],
|
||||
memories: ['tool-memory-btn', 'rail-memory'],
|
||||
research: ['tool-research-btn', 'rail-research'],
|
||||
compare: ['tool-compare-btn', 'rail-compare'],
|
||||
theme: ['tool-theme-btn', 'rail-theme'],
|
||||
};
|
||||
const ids = targets[target];
|
||||
if (ids && clickFirst(...ids)) return true;
|
||||
@@ -1254,6 +1244,53 @@ async function _cmdOpen(args, ctx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
async function _cmdToolPanel(tool, args, ctx) {
|
||||
const target = String(tool || '').toLowerCase();
|
||||
const rest = (args || []).join(' ').trim();
|
||||
if (target === 'cookbook') {
|
||||
const sub = (args[0] || '').toLowerCase();
|
||||
if (sub === 'serve') {
|
||||
const query = args.slice(1).join(' ').trim();
|
||||
try {
|
||||
if (cookbookModule && typeof cookbookModule.open === 'function') {
|
||||
await cookbookModule.open({ tab: 'Serve', serveSearch: query });
|
||||
if (query) {
|
||||
try {
|
||||
const mod = await import('./cookbookServe.js');
|
||||
if (mod && typeof mod.openServePanelForRepo === 'function') {
|
||||
setTimeout(() => { mod.openServePanelForRepo(query).catch(() => {}); }, 80);
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
} else {
|
||||
document.getElementById('tool-cookbook-btn')?.click();
|
||||
}
|
||||
} catch (e) {
|
||||
slashReply(`Could not open Cookbook Serve${e?.message ? `: ${ctx.esc(e.message)}` : ''}`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (sub === 'download' || sub === 'scan') {
|
||||
await cookbookModule?.open?.({ tab: 'Download', usecase: args.slice(1).join(' ').trim() || undefined });
|
||||
return true;
|
||||
}
|
||||
await cookbookModule?.open?.({ tab: 'Download', usecase: rest || undefined });
|
||||
return true;
|
||||
}
|
||||
if (target === 'email') {
|
||||
const btn = document.getElementById('rail-email') || document.getElementById('email-section-title');
|
||||
if (btn) btn.click();
|
||||
else slashReply('Could not open Email.');
|
||||
return true;
|
||||
}
|
||||
if (target === 'settings') {
|
||||
if (settingsModule && typeof settingsModule.open === 'function') settingsModule.open(rest || undefined);
|
||||
else document.getElementById('user-bar-settings')?.click();
|
||||
return true;
|
||||
}
|
||||
return _cmdOpen([target], ctx);
|
||||
}
|
||||
|
||||
async function _cmdSettings(args, ctx) {
|
||||
// Opens the Settings modal — primarily useful when the user has hidden the
|
||||
// Settings cog in Appearance and needs a way back in.
|
||||
@@ -5551,13 +5588,6 @@ const COMMANDS = {
|
||||
handler: _cmdPrompt,
|
||||
usage: '/prompt'
|
||||
},
|
||||
mode: {
|
||||
alias: [],
|
||||
category: 'Settings',
|
||||
help: 'Switch agent/chat mode',
|
||||
handler: _cmdMode,
|
||||
usage: '/mode agent|chat'
|
||||
},
|
||||
theme: {
|
||||
alias: [],
|
||||
category: 'Settings',
|
||||
@@ -5580,6 +5610,69 @@ const COMMANDS = {
|
||||
handler: _cmdOpen,
|
||||
usage: '/open Cookbook'
|
||||
},
|
||||
cookbook: {
|
||||
alias: ['cook'],
|
||||
category: 'Tools',
|
||||
help: 'Open Cookbook; use "serve" to jump to model serving',
|
||||
handler: (args, ctx) => _cmdToolPanel('cookbook', args, ctx),
|
||||
usage: '/cookbook · /cookbook serve qwen'
|
||||
},
|
||||
email: {
|
||||
alias: ['mail', 'inbox'],
|
||||
category: 'Tools',
|
||||
help: 'Open Email',
|
||||
handler: (args, ctx) => _cmdToolPanel('email', args, ctx),
|
||||
usage: '/email'
|
||||
},
|
||||
notes: {
|
||||
alias: [],
|
||||
category: 'Tools',
|
||||
help: 'Open Notes',
|
||||
handler: (args, ctx) => _cmdToolPanel('notes', args, ctx),
|
||||
usage: '/notes'
|
||||
},
|
||||
tasks: {
|
||||
alias: [],
|
||||
category: 'Tools',
|
||||
help: 'Open Tasks',
|
||||
handler: (args, ctx) => _cmdToolPanel('tasks', args, ctx),
|
||||
usage: '/tasks'
|
||||
},
|
||||
brain: {
|
||||
alias: ['memories'],
|
||||
category: 'Tools',
|
||||
help: 'Open Brain',
|
||||
handler: (args, ctx) => _cmdToolPanel('brain', args, ctx),
|
||||
usage: '/brain'
|
||||
},
|
||||
library: {
|
||||
alias: ['docs', 'documents'],
|
||||
category: 'Tools',
|
||||
help: 'Open Library',
|
||||
handler: (args, ctx) => _cmdToolPanel('library', args, ctx),
|
||||
usage: '/library'
|
||||
},
|
||||
gallery: {
|
||||
alias: ['photos'],
|
||||
category: 'Tools',
|
||||
help: 'Open Gallery',
|
||||
handler: (args, ctx) => _cmdToolPanel('gallery', args, ctx),
|
||||
usage: '/gallery'
|
||||
},
|
||||
research: {
|
||||
alias: [],
|
||||
category: 'Tools',
|
||||
help: 'Open Deep Research',
|
||||
handler: (args, ctx) => _cmdToolPanel('research', args, ctx),
|
||||
usage: '/research'
|
||||
},
|
||||
compare: {
|
||||
alias: [],
|
||||
category: 'Tools',
|
||||
help: 'Open Compare',
|
||||
handler: (args, ctx) => _cmdToolPanel('compare', args, ctx),
|
||||
usage: '/compare'
|
||||
},
|
||||
models: {
|
||||
alias: ['model'],
|
||||
category: 'Settings',
|
||||
|
||||
@@ -28359,6 +28359,11 @@ body.notes-view .chat-container { flex: 1; min-width: 0; }
|
||||
}
|
||||
body.notes-view #notes-close-btn {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
/* ── Mobile notes UX ────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user