docs: update meta files for Memora adapter registration

This commit is contained in:
Hibryda 2026-03-11 04:09:29 +01:00
parent be504cadcf
commit 0139f482b5
5 changed files with 31 additions and 5 deletions

View file

@ -5,7 +5,7 @@
- v1 is a single-file Python app (`bterminal.py`). Changes are localized. - v1 is a single-file Python app (`bterminal.py`). Changes are localized.
- v2 docs are in `docs/`. Architecture decisions are in `docs/task_plan.md`. - v2 docs are in `docs/`. Architecture decisions are in `docs/task_plan.md`.
- v2 Phases 1-7 + multi-machine (A-D) + profiles/skills complete. Extras: SSH, ctx, themes, detached mode, auto-updater, shiki, copy/paste, session resume, drag-resize, session groups, Deno sidecar, Claude profiles, skill discovery. - v2 Phases 1-7 + multi-machine (A-D) + profiles/skills complete. Extras: SSH, ctx, themes, detached mode, auto-updater, shiki, copy/paste, session resume, drag-resize, session groups, Deno sidecar, Claude profiles, skill discovery.
- v3 Mission Control (All Phases 1-10 Complete + S-1 Phase 1/1.5/2/3 + S-2 Session Anchors + Provider Adapter Pattern + Provider Runners): project groups, workspace store, 12 Workspace components, session continuity, workspace teardown, file overlap conflict detection, inotify-based external write detection, multi-provider adapter pattern (3 phases + Codex/Ollama runners), worktree isolation, session anchors, dead v2 component cleanup. 256 vitest + 42 cargo tests. - v3 Mission Control (All Phases 1-10 Complete + S-1 Phase 1/1.5/2/3 + S-2 Session Anchors + Provider Adapter Pattern + Provider Runners + Memora Adapter): project groups, workspace store, 12 Workspace components, session continuity, workspace teardown, file overlap conflict detection, inotify-based external write detection, multi-provider adapter pattern (3 phases + Codex/Ollama runners), worktree isolation, session anchors, Memora adapter (read-only SQLite), dead v2 component cleanup. 272 vitest + 49 cargo tests.
- v3 docs: `docs/v3-task_plan.md`, `docs/v3-findings.md`, `docs/v3-progress.md`. - v3 docs: `docs/v3-task_plan.md`, `docs/v3-findings.md`, `docs/v3-progress.md`.
- Consult Memora (tag: `bterminal`) before making architectural changes. - Consult Memora (tag: `bterminal`) before making architectural changes.
@ -38,7 +38,7 @@
- AgentQueryOptions supports `provider` field (defaults to 'claude', flows Rust -> sidecar), `provider_config` blob (Rust passes through as serde_json::Value), `permission_mode` (defaults to 'bypassPermissions'), `setting_sources` (defaults to ['user', 'project']), `system_prompt`, `model`, `claude_config_dir` (for multi-account), `additional_directories`, `worktree_name` (when set, passed as `extraArgs: { worktree: name }` to SDK → `--worktree <name>` CLI flag). - AgentQueryOptions supports `provider` field (defaults to 'claude', flows Rust -> sidecar), `provider_config` blob (Rust passes through as serde_json::Value), `permission_mode` (defaults to 'bypassPermissions'), `setting_sources` (defaults to ['user', 'project']), `system_prompt`, `model`, `claude_config_dir` (for multi-account), `additional_directories`, `worktree_name` (when set, passed as `extraArgs: { worktree: name }` to SDK → `--worktree <name>` CLI flag).
- Worktree isolation (S-1 Phase 3): Per-project `useWorktrees` toggle in SettingsTab. When enabled, AgentPane passes `worktree_name=sessionId` in queryAgent(). Agent runs in `<repo>/.claude/worktrees/<sessionId>/`. CWD-based detection: agent-dispatcher.ts `detectWorktreeFromCwd()` matches `.claude/worktrees/`, `.codex/worktrees/`, `.cursor/worktrees/` patterns on init events → calls `setSessionWorktree()` for conflict suppression. Dual detection: CWD-based (primary, from init event) + tool_call-based `extractWorktreePath()` (subagent fallback). - Worktree isolation (S-1 Phase 3): Per-project `useWorktrees` toggle in SettingsTab. When enabled, AgentPane passes `worktree_name=sessionId` in queryAgent(). Agent runs in `<repo>/.claude/worktrees/<sessionId>/`. CWD-based detection: agent-dispatcher.ts `detectWorktreeFromCwd()` matches `.claude/worktrees/`, `.codex/worktrees/`, `.cursor/worktrees/` patterns on init events → calls `setSessionWorktree()` for conflict suppression. Dual detection: CWD-based (primary, from init event) + tool_call-based `extractWorktreePath()` (subagent fallback).
- Claude profiles: claude_list_profiles() reads ~/.config/switcher/profiles/ with profile.toml metadata. Profile set per-project in Settings (project.profile field), passed through AgentSession -> AgentPane `profile` prop -> resolved to config_dir for SDK. Profile name shown as info-only in ProjectHeader. - Claude profiles: claude_list_profiles() reads ~/.config/switcher/profiles/ with profile.toml metadata. Profile set per-project in Settings (project.profile field), passed through AgentSession -> AgentPane `profile` prop -> resolved to config_dir for SDK. Profile name shown as info-only in ProjectHeader.
- ProjectBox has project-level tab bar: Model | Docs | Context | Files | SSH | Memory. Three mount strategies: PERSISTED-EAGER (Model, Docs, Context — always mounted, display:flex/none), PERSISTED-LAZY (Files, SSH, Memory — mount on first activation via {#if everActivated} + display:flex/none). Tab type: `'model' | 'docs' | 'context' | 'files' | 'ssh' | 'memories'`. Model tab = AgentSession+TeamAgentsPanel. Docs tab = ProjectFiles (markdown viewer). Context tab = ContextTab.svelte (LLM context window visualization: stats bar, segmented token meter, file references, turn breakdown; reads from agent store via sessionId prop; replaced old ContextPane ctx database viewer). Files tab = FilesTab.svelte (VSCode-style directory tree + CodeMirror 6 editor with 15 language modes, dirty tracking, Ctrl+S save, save-on-blur setting, image display via convertFileSrc, 10MB gate; CodeEditor.svelte wrapper; PdfViewer.svelte for PDF files via pdfjs-dist with canvas multi-page rendering + zoom 0.5x3x; CsvTable.svelte for CSV with RFC 4180 parser, delimiter auto-detect, sortable columns). SSH tab = SshTab.svelte (CRUD for SSH connections, launch spawns terminal tab in Model tab). Memory tab = MemoriesTab.svelte (pluggable via MemoryAdapter interface in memory-adapter.ts). Rust backend: list_directory_children + read_file_content + write_file_content (FileContent tagged union: Text/Binary/TooLarge). Frontend bridge: files-bridge.ts. - ProjectBox has project-level tab bar: Model | Docs | Context | Files | SSH | Memory. Three mount strategies: PERSISTED-EAGER (Model, Docs, Context — always mounted, display:flex/none), PERSISTED-LAZY (Files, SSH, Memory — mount on first activation via {#if everActivated} + display:flex/none). Tab type: `'model' | 'docs' | 'context' | 'files' | 'ssh' | 'memories'`. Model tab = AgentSession+TeamAgentsPanel. Docs tab = ProjectFiles (markdown viewer). Context tab = ContextTab.svelte (LLM context window visualization: stats bar, segmented token meter, file references, turn breakdown; reads from agent store via sessionId prop; replaced old ContextPane ctx database viewer). Files tab = FilesTab.svelte (VSCode-style directory tree + CodeMirror 6 editor with 15 language modes, dirty tracking, Ctrl+S save, save-on-blur setting, image display via convertFileSrc, 10MB gate; CodeEditor.svelte wrapper; PdfViewer.svelte for PDF files via pdfjs-dist with canvas multi-page rendering + zoom 0.5x3x; CsvTable.svelte for CSV with RFC 4180 parser, delimiter auto-detect, sortable columns). SSH tab = SshTab.svelte (CRUD for SSH connections, launch spawns terminal tab in Model tab). Memory tab = MemoriesTab.svelte (pluggable via MemoryAdapter interface in memory-adapter.ts; MemoraAdapter registered at startup, reads ~/.local/share/memora/memories.db via Rust memora.rs). Rust backend: list_directory_children + read_file_content + write_file_content (FileContent tagged union: Text/Binary/TooLarge). Frontend bridge: files-bridge.ts.
- ProjectHeader shows CWD (ellipsized from START via `direction: rtl`) + profile name as info-only text on right side. AgentPane no longer has DIR/ACC toolbar — CWD and profile are props from parent. - ProjectHeader shows CWD (ellipsized from START via `direction: rtl`) + profile name as info-only text on right side. AgentPane no longer has DIR/ACC toolbar — CWD and profile are props from parent.
- Skill discovery: claude_list_skills() reads ~/.claude/skills/ (dirs with SKILL.md or .md files). claude_read_skill() reads content. AgentPane `/` prefix triggers autocomplete menu. Skill content injected as prompt via expandSkillPrompt(). - Skill discovery: claude_list_skills() reads ~/.claude/skills/ (dirs with SKILL.md or .md files). claude_read_skill() reads content. AgentPane `/` prefix triggers autocomplete menu. Skill content injected as prompt via expandSkillPrompt().
- claude-bridge.ts adapter wraps profile/skill Tauri commands (ClaudeProfile, ClaudeSkill interfaces). provider-bridge.ts wraps claude-bridge as generic provider bridge (delegates by ProviderId). - claude-bridge.ts adapter wraps profile/skill Tauri commands (ClaudeProfile, ClaudeSkill interfaces). provider-bridge.ts wraps claude-bridge as generic provider bridge (delegates by ProviderId).

View file

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `claude_read_skill` path traversal: added `canonicalize()` + `starts_with()` validation to prevent reading arbitrary files via crafted skill paths (lib.rs) - `claude_read_skill` path traversal: added `canonicalize()` + `starts_with()` validation to prevent reading arbitrary files via crafted skill paths (lib.rs)
### Added ### Added
- **Memora adapter**`MemoraAdapter` (memora-bridge.ts) implements `MemoryAdapter` interface, bridging to Memora's SQLite database (`~/.local/share/memora/memories.db`) via read-only Rust backend (`memora.rs`). FTS5 text search, tag filtering via `json_each()`. 4 Tauri commands (memora_available, memora_list, memora_search, memora_get). Registered in App.svelte onMount. 16 vitest + 7 cargo tests. MemoriesTab now shows Memora memories on startup
- **Codex provider runner**`sidecar/codex-runner.ts` wraps `@openai/codex-sdk` (dynamic import, graceful failure if not installed). Maps Codex ThreadEvents (agent_message, reasoning, command_execution, file_change, mcp_tool_call, web_search) to common AgentMessage format via `codex-messages.ts` adapter. Sandbox/approval mode mapping from BTerminal permission modes. Session resume via thread ID. `providers/codex.ts` ProviderMeta (gpt-5.4 default, hasSandbox, supportsResume). 19 adapter tests - **Codex provider runner**`sidecar/codex-runner.ts` wraps `@openai/codex-sdk` (dynamic import, graceful failure if not installed). Maps Codex ThreadEvents (agent_message, reasoning, command_execution, file_change, mcp_tool_call, web_search) to common AgentMessage format via `codex-messages.ts` adapter. Sandbox/approval mode mapping from BTerminal permission modes. Session resume via thread ID. `providers/codex.ts` ProviderMeta (gpt-5.4 default, hasSandbox, supportsResume). 19 adapter tests
- **Ollama provider runner**`sidecar/ollama-runner.ts` uses direct HTTP to `localhost:11434/api/chat` with NDJSON streaming (zero external dependencies). Health check before session start. Configurable host/model/num_ctx/think via providerConfig. Supports Qwen3 extended thinking. `ollama-messages.ts` adapter maps streaming chunks to AgentMessage (text, thinking, cost with token counts). `providers/ollama.ts` ProviderMeta (qwen3:8b default, modelSelection only). 11 adapter tests - **Ollama provider runner**`sidecar/ollama-runner.ts` uses direct HTTP to `localhost:11434/api/chat` with NDJSON streaming (zero external dependencies). Health check before session start. Configurable host/model/num_ctx/think via providerConfig. Supports Qwen3 extended thinking. `ollama-messages.ts` adapter maps streaming chunks to AgentMessage (text, thinking, cost with token counts). `providers/ollama.ts` ProviderMeta (qwen3:8b default, modelSelection only). 11 adapter tests
- All 3 providers registered in App.svelte onMount + message-adapters.ts. `build:sidecar` builds all 3 runners - All 3 providers registered in App.svelte onMount + message-adapters.ts. `build:sidecar` builds all 3 runners

View file

@ -43,6 +43,7 @@ Terminal emulator with SSH and Claude Code session management. v1 (GTK3+VTE Pyth
| `v2/src-tauri/src/session.rs` | SessionDb (rusqlite, sessions + layout + settings + ssh_sessions + agent_messages + project_agent_state + session_anchors) | | `v2/src-tauri/src/session.rs` | SessionDb (rusqlite, sessions + layout + settings + ssh_sessions + agent_messages + project_agent_state + session_anchors) |
| `v2/src-tauri/src/watcher.rs` | FileWatcherManager (notify crate, file change events) | | `v2/src-tauri/src/watcher.rs` | FileWatcherManager (notify crate, file change events) |
| `v2/src-tauri/src/ctx.rs` | CtxDb (read-only access to ~/.claude-context/context.db) | | `v2/src-tauri/src/ctx.rs` | CtxDb (read-only access to ~/.claude-context/context.db) |
| `v2/src-tauri/src/memora.rs` | MemoraDb (read-only access to ~/.local/share/memora/memories.db, FTS5 search) |
| `v2/src-tauri/src/telemetry.rs` | OTEL telemetry (TelemetryGuard, tracing + OTLP export, BTERMINAL_OTLP_ENDPOINT) | | `v2/src-tauri/src/telemetry.rs` | OTEL telemetry (TelemetryGuard, tracing + OTLP export, BTERMINAL_OTLP_ENDPOINT) |
| `v2/src/lib/stores/workspace.svelte.ts` | v3 workspace store (project groups, tabs, focus, replaces layout store) | | `v2/src/lib/stores/workspace.svelte.ts` | v3 workspace store (project groups, tabs, focus, replaces layout store) |
| `v2/src/lib/stores/layout.svelte.ts` | v2 layout store (panes, presets, groups, persistence, Svelte 5 runes) | | `v2/src/lib/stores/layout.svelte.ts` | v2 layout store (panes, presets, groups, persistence, Svelte 5 runes) |
@ -72,6 +73,7 @@ Terminal emulator with SSH and Claude Code session management. v1 (GTK3+VTE Pyth
| `v2/src/lib/adapters/remote-bridge.ts` | Remote machine management IPC wrapper | | `v2/src/lib/adapters/remote-bridge.ts` | Remote machine management IPC wrapper |
| `v2/src/lib/adapters/files-bridge.ts` | File browser IPC wrapper (list_directory_children, read_file_content) | | `v2/src/lib/adapters/files-bridge.ts` | File browser IPC wrapper (list_directory_children, read_file_content) |
| `v2/src/lib/adapters/memory-adapter.ts` | Pluggable memory adapter interface (MemoryAdapter, registry) | | `v2/src/lib/adapters/memory-adapter.ts` | Pluggable memory adapter interface (MemoryAdapter, registry) |
| `v2/src/lib/adapters/memora-bridge.ts` | Memora IPC bridge + MemoraAdapter (read-only SQLite via Tauri commands) |
| `v2/src/lib/adapters/fs-watcher-bridge.ts` | Filesystem watcher IPC wrapper (project CWD write detection) | | `v2/src/lib/adapters/fs-watcher-bridge.ts` | Filesystem watcher IPC wrapper (project CWD write detection) |
| `v2/src/lib/adapters/anchors-bridge.ts` | Session anchors IPC wrapper (save, load, delete, clear, updateType) | | `v2/src/lib/adapters/anchors-bridge.ts` | Session anchors IPC wrapper (save, load, delete, clear, updateType) |
| `v2/src/lib/adapters/telemetry-bridge.ts` | Frontend telemetry bridge (routes events to Rust tracing via IPC) | | `v2/src/lib/adapters/telemetry-bridge.ts` | Frontend telemetry bridge (routes events to Rust tracing via IPC) |
@ -111,6 +113,7 @@ Terminal emulator with SSH and Claude Code session management. v1 (GTK3+VTE Pyth
| `v2/src/lib/adapters/claude-messages.test.ts` | Vitest tests for Claude message adapter (25 tests) | | `v2/src/lib/adapters/claude-messages.test.ts` | Vitest tests for Claude message adapter (25 tests) |
| `v2/src/lib/adapters/codex-messages.test.ts` | Vitest tests for Codex message adapter (19 tests) | | `v2/src/lib/adapters/codex-messages.test.ts` | Vitest tests for Codex message adapter (19 tests) |
| `v2/src/lib/adapters/ollama-messages.test.ts` | Vitest tests for Ollama message adapter (11 tests) | | `v2/src/lib/adapters/ollama-messages.test.ts` | Vitest tests for Ollama message adapter (11 tests) |
| `v2/src/lib/adapters/memora-bridge.test.ts` | Vitest tests for Memora bridge + adapter (16 tests) |
| `v2/src/lib/adapters/agent-bridge.test.ts` | Vitest tests for agent IPC bridge (11 tests) | | `v2/src/lib/adapters/agent-bridge.test.ts` | Vitest tests for agent IPC bridge (11 tests) |
| `v2/src/lib/agent-dispatcher.test.ts` | Vitest tests for agent dispatcher (29 tests) | | `v2/src/lib/agent-dispatcher.test.ts` | Vitest tests for agent dispatcher (29 tests) |
| `v2/src/lib/stores/conflicts.test.ts` | Vitest tests for conflict detection (28 tests) | | `v2/src/lib/stores/conflicts.test.ts` | Vitest tests for conflict detection (28 tests) |

View file

@ -3,7 +3,6 @@
## Active ## Active
### v2/v3 Remaining ### v2/v3 Remaining
- [ ] **Register Memora adapter** -- MemoryAdapter interface exists but no concrete adapter registered at app init. Need to create a MemoraAdapter that bridges to Memora MCP/CLI and register it on startup.
- [ ] **E2E testing — expand coverage** -- 48 tests passing across 8 describe blocks (WebdriverIO v9.24 + tauri-driver, single spec file, ~23s). Add tests for agent sessions, terminal interaction. - [ ] **E2E testing — expand coverage** -- 48 tests passing across 8 describe blocks (WebdriverIO v9.24 + tauri-driver, single spec file, ~23s). Add tests for agent sessions, terminal interaction.
- [ ] **Multi-machine real-world testing** -- Test bterminal-relay with 2 machines. - [ ] **Multi-machine real-world testing** -- Test bterminal-relay with 2 machines.
- [ ] **Multi-machine TLS/certificate pinning** -- TLS support for bterminal-relay + certificate pinning in RemoteManager. - [ ] **Multi-machine TLS/certificate pinning** -- TLS support for bterminal-relay + certificate pinning in RemoteManager.
@ -11,6 +10,7 @@
- [ ] **Configurable stall threshold** -- health.yaml per-project config for stall threshold (currently hardcoded 15 min). Adaptive suggestions after 50 sessions from session_metrics data. - [ ] **Configurable stall threshold** -- health.yaml per-project config for stall threshold (currently hardcoded 15 min). Adaptive suggestions after 50 sessions from session_metrics data.
## Completed ## Completed
- [x] **Register Memora adapter** -- MemoraAdapter (memora-bridge.ts) implements MemoryAdapter, reads ~/.local/share/memora/memories.db via Rust memora.rs (read-only SQLite, FTS5 search). 4 Tauri commands, 16 vitest + 7 cargo tests. 272 vitest + 49 cargo total. | Done: 2026-03-11
- [x] **Add Codex/Ollama provider runners** -- Full provider stack for both: ProviderMeta constants, message adapters (codex-messages.ts, ollama-messages.ts), sidecar runners (codex-runner.ts uses @openai/codex-sdk dynamic import, ollama-runner.ts uses direct HTTP). 30 new tests, 256 vitest total. | Done: 2026-03-11 - [x] **Add Codex/Ollama provider runners** -- Full provider stack for both: ProviderMeta constants, message adapters (codex-messages.ts, ollama-messages.ts), sidecar runners (codex-runner.ts uses @openai/codex-sdk dynamic import, ollama-runner.ts uses direct HTTP). 30 new tests, 256 vitest total. | Done: 2026-03-11
- [x] **Worktree isolation per project (S-1 Phase 3)** -- UI toggle in SettingsTab, spawn with --worktree via sidecar extraArgs, CWD-based worktree detection in agent-dispatcher (matches .claude/.codex/.cursor patterns). 8 files, +125 lines. 226 vitest + 42 cargo tests. | Done: 2026-03-11 - [x] **Worktree isolation per project (S-1 Phase 3)** -- UI toggle in SettingsTab, spawn with --worktree via sidecar extraArgs, CWD-based worktree detection in agent-dispatcher (matches .claude/.codex/.cursor patterns). 8 files, +125 lines. 226 vitest + 42 cargo tests. | Done: 2026-03-11
- [x] **S-2 — Session Anchors + Configurable Budget** -- Preserves important turns through compaction chains. Auto-anchors first 3 turns (observation-masked — reasoning preserved in full per research). Configurable budget via AnchorBudgetScale slider (Small=2K, Medium=6K, Large=12K, Full=20K) in SettingsTab per-project. Manual pin, promote/demote in ContextTab. Re-injection via system_prompt. 219 vitest + 42 cargo tests. | Done: 2026-03-11 - [x] **S-2 — Session Anchors + Configurable Budget** -- Preserves important turns through compaction chains. Auto-anchors first 3 turns (observation-masked — reasoning preserved in full per research). Configurable budget via AnchorBudgetScale slider (Small=2K, Medium=6K, Large=12K, Full=20K) in SettingsTab per-project. Manual pin, promote/demote in ContextTab. Re-injection via system_prompt. 219 vitest + 42 cargo tests. | Done: 2026-03-11
@ -20,5 +20,3 @@
- [x] **Conflict Detection Enhancements (S-1 Phase 1.5)** -- Bash write detection, acknowledge/dismiss conflicts, worktree-aware suppression. 194/194 tests. | Done: 2026-03-11 - [x] **Conflict Detection Enhancements (S-1 Phase 1.5)** -- Bash write detection, acknowledge/dismiss conflicts, worktree-aware suppression. 194/194 tests. | Done: 2026-03-11
- [x] **File Overlap Conflict Detection (S-1 Phase 1)** -- conflicts.svelte.ts store tracks per-session Write/Edit file paths. Detects 2+ agents writing same file. 170/170 tests. | Done: 2026-03-10 - [x] **File Overlap Conflict Detection (S-1 Phase 1)** -- conflicts.svelte.ts store tracks per-session Write/Edit file paths. Detects 2+ agents writing same file. 170/170 tests. | Done: 2026-03-10
- [x] **Project Health Dashboard (S-3)** -- health.svelte.ts store, Mission Control status bar, session_metrics SQLite table. | Done: 2026-03-10 - [x] **Project Health Dashboard (S-3)** -- health.svelte.ts store, Mission Control status bar, session_metrics SQLite table. | Done: 2026-03-10
- [x] **Context tab repurpose** -- Replaced ContextPane with ContextTab (LLM context window visualization). | Done: 2026-03-10
- [x] **CodeMirror 6 editor** -- Replaced shiki viewer with CodeMirror 6. 15 language modes, Catppuccin theme. | Done: 2026-03-10

View file

@ -683,3 +683,27 @@ All editor themes map to the same `--ctp-*` CSS custom property names (26 vars).
- [x] package.json: build:sidecar builds all 3 runners - [x] package.json: build:sidecar builds all 3 runners
- [x] vitest: 256/256 tests pass - [x] vitest: 256/256 tests pass
- [x] cargo test: 42/42 pass - [x] cargo test: 42/42 pass
### 2026-03-11 — Register Memora Adapter
**Duration:** ~15 min
**What happened:**
Registered a concrete MemoraAdapter that bridges the MemoryAdapter interface to the Memora SQLite database. Direct read-only SQLite access (no MCP/CLI dependency at runtime).
#### Rust Backend
- [x] memora.rs — MemoraDb struct (read-only SQLite, Option<Connection>, graceful absence)
- [x] list() with tag filtering via json_each() + IN clause
- [x] search() via FTS5 MATCH on memories_fts, optional tag join
- [x] get() by ID
- [x] 4 Tauri commands: memora_available, memora_list, memora_search, memora_get
- [x] 7 cargo tests (missing-db error paths)
#### TypeScript Bridge + Adapter
- [x] memora-bridge.ts — IPC wrappers + MemoraAdapter class implementing MemoryAdapter
- [x] App.svelte — registers MemoraAdapter on mount with async availability check
- [x] memora-bridge.test.ts — 16 tests (IPC + adapter)
#### Results
- [x] vitest: 272/272 tests pass
- [x] cargo test: 49/49 pass