feat(v2): implement session persistence, file watcher, and markdown viewer
Phase 4 complete (MVP ship): - SessionDb (rusqlite, WAL mode): sessions + layout_state tables, CRUD - FileWatcherManager (notify v6): watch files, emit Tauri change events - MarkdownPane: marked.js rendering with Catppuccin styles, live reload - Layout store wired to persistence (addPane/removePane/setPreset persist) - restoreFromDb() on startup restores panes in layout order - Sidebar "M" button opens file picker for markdown files - New adapters: session-bridge.ts, file-bridge.ts - Deps: rusqlite (bundled), dirs 5, notify 6, marked
This commit is contained in:
parent
5ca035d438
commit
bdb87978a9
14 changed files with 1075 additions and 17 deletions
|
|
@ -33,15 +33,46 @@
|
|||
title: `Agent ${num}`,
|
||||
});
|
||||
}
|
||||
|
||||
let fileInputEl: HTMLInputElement | undefined = $state();
|
||||
|
||||
function openMarkdown() {
|
||||
fileInputEl?.click();
|
||||
}
|
||||
|
||||
function handleFileSelect(e: Event) {
|
||||
const input = e.target as HTMLInputElement;
|
||||
const file = input.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
// Tauri file paths from input elements include the full path
|
||||
const path = (file as any).path ?? file.name;
|
||||
const id = crypto.randomUUID();
|
||||
addPane({
|
||||
id,
|
||||
type: 'markdown',
|
||||
title: file.name,
|
||||
cwd: path,
|
||||
});
|
||||
input.value = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="session-list">
|
||||
<div class="header">
|
||||
<h2>Sessions</h2>
|
||||
<div class="header-buttons">
|
||||
<button class="new-btn" onclick={openMarkdown} title="Open markdown file">M</button>
|
||||
<button class="new-btn" onclick={newAgent} title="New agent (Ctrl+Shift+N)">A</button>
|
||||
<button class="new-btn" onclick={newTerminal} title="New terminal (Ctrl+N)">+</button>
|
||||
</div>
|
||||
<input
|
||||
bind:this={fileInputEl}
|
||||
type="file"
|
||||
accept=".md,.markdown,.txt"
|
||||
onchange={handleFileSelect}
|
||||
style="display: none;"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="layout-presets">
|
||||
|
|
@ -65,7 +96,7 @@
|
|||
{#each panes as pane (pane.id)}
|
||||
<li class="pane-item" class:focused={pane.focused}>
|
||||
<button class="pane-btn" onclick={() => focusPane(pane.id)}>
|
||||
<span class="pane-icon">{pane.type === 'terminal' ? '>' : pane.type === 'agent' ? '*' : '#'}</span>
|
||||
<span class="pane-icon">{pane.type === 'terminal' ? '>' : pane.type === 'agent' ? '*' : pane.type === 'markdown' ? 'M' : '#'}</span>
|
||||
<span class="pane-name">{pane.title}</span>
|
||||
</button>
|
||||
<button class="remove-btn" onclick={() => removePane(pane.id)}>×</button>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue