|
| 1 | +# Lovcode v0.40 — Rewrite Plan |
| 2 | + |
| 3 | +> **Goal**: Refocus Lovcode from a general "vibe coding assistant" into a single-purpose **AI conversation search** tool, with four interchangeable surfaces (CLI / MCP / Tauri desktop + floating window / Web) backed by one Rust core crate and an adapter-based ingest layer. |
| 4 | +
|
| 5 | +**Legacy code** (v0.39 — Workbench / Skills / Marketplace / Lab / MaaS / claude.ai sync / PTY / Codex commands / etc.) is preserved on the `legacy/v0.39-workbench` branch and will not be deleted from history. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Design Principles |
| 10 | + |
| 11 | +1. **One Rust core, many thin shells.** All search logic lives in `lovcode-core`. CLI, Tauri commands, HTTP server, and MCP server are thin call sites. No duplicated logic. |
| 12 | +2. **No daemon required.** CLI cold-start must feel instant (< 100 ms for cached queries). HTTP server is opt-in. |
| 13 | +3. **Local-first.** Conversations never leave the machine unless the user explicitly configures a remote index. |
| 14 | +4. **Adapters over features.** A new data source is one Rust file implementing a `SourceAdapter` trait, not a core refactor. |
| 15 | +5. **No premature abstraction.** Three concrete adapters before extracting a registry; two CLI subcommands before extracting a router; one HTTP endpoint before introducing layered middleware. |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +## Target Repo Layout |
| 20 | + |
| 21 | +``` |
| 22 | +lovcode/ |
| 23 | +├── crates/ |
| 24 | +│ ├── lovcode-core/ # Pure library: adapters, index, query, watcher |
| 25 | +│ ├── lovcode-cli/ # `lovcode` binary (search/index/sources/serve/mcp) |
| 26 | +│ └── lovcode-mcp/ # MCP server library used by `lovcode mcp` |
| 27 | +├── src-tauri/ # Tauri shell — depends on lovcode-core |
| 28 | +│ └── src/ |
| 29 | +│ ├── lib.rs |
| 30 | +│ ├── commands.rs # invoke handlers, all thin wrappers |
| 31 | +│ └── floating.rs # floating window + global hotkey |
| 32 | +├── src/ # React frontend (drastically slimmed) |
| 33 | +│ ├── pages/ |
| 34 | +│ │ ├── index.tsx # main search |
| 35 | +│ │ ├── conversation/[id].tsx |
| 36 | +│ │ └── settings.tsx |
| 37 | +│ ├── components/search/ |
| 38 | +│ └── components/floating/ |
| 39 | +├── docs/ |
| 40 | +└── README.md |
| 41 | +``` |
| 42 | + |
| 43 | +**Cargo workspace.** `Cargo.toml` at repo root defines a workspace including all three crates + `src-tauri`. |
| 44 | + |
| 45 | +--- |
| 46 | + |
| 47 | +## Phase 1 — Foundation (Rust core + repo cleanup) |
| 48 | + |
| 49 | +**Outcome:** Repo compiles. `lovcode-core` exists with two adapters and a working index. Frontend stripped to skeleton. |
| 50 | + |
| 51 | +### 1.1 Cargo workspace |
| 52 | +- [ ] Create `crates/lovcode-core/` (lib). |
| 53 | +- [ ] Move `Cargo.toml` deps relevant to search (`tantivy`, `jieba-rs`, `notify`, `chrono`, `serde`, `serde_json`, `rayon`) to `lovcode-core`. |
| 54 | +- [ ] Add workspace `Cargo.toml` at repo root, declare members: `crates/lovcode-core`, `crates/lovcode-cli`, `crates/lovcode-mcp`, `src-tauri`. |
| 55 | + |
| 56 | +### 1.2 Core types |
| 57 | +- [ ] `lovcode_core::types`: `Conversation`, `Message`, `Source`, `SourceId`, `IndexedDoc`, `SearchQuery`, `SearchResult`. |
| 58 | +- [ ] `lovcode_core::adapter::SourceAdapter` trait: |
| 59 | + ```rust |
| 60 | + pub trait SourceAdapter: Send + Sync { |
| 61 | + fn id(&self) -> &'static str; // "claude-code", "codex", ... |
| 62 | + fn name(&self) -> &'static str; // human label |
| 63 | + fn discover(&self) -> Result<Vec<PathBuf>>; |
| 64 | + fn parse(&self, path: &Path) -> Result<Conversation>; |
| 65 | + fn watch_roots(&self) -> Vec<PathBuf>; // for notify |
| 66 | + } |
| 67 | + ``` |
| 68 | +- [ ] Port existing `session_listing.rs` + `session_parsing.rs` logic into `adapters/claude_code.rs` and `adapters/codex.rs` implementing the trait. |
| 69 | + |
| 70 | +### 1.3 Index + query |
| 71 | +- [ ] `lovcode_core::index`: tantivy schema (id, source, project, title, body, role, ts, raw_path), CJK tokenizer via jieba. |
| 72 | +- [ ] `lovcode_core::query`: `SearchQuery` builder (filters: source, project, since/until, role) → `Vec<SearchResult>`. |
| 73 | +- [ ] `lovcode_core::watcher`: `notify`-based incremental reindex; debounced batch updates. |
| 74 | + |
| 75 | +### 1.4 Frontend strip |
| 76 | +- [ ] Delete `src/pages/`: `agents`, `commands`, `dashboard.tsx`, `docs.tsx`, `events`, `extensions`, `features.tsx`, `hooks`, `knowledge`, `lab.tsx`, `marketplace`, `mcp`, `output-styles`, `prompt-detail.tsx`, `skills`, `statusline`, `wishes`, `workbench.tsx`, `workspace.tsx`, `annual-report-2025.tsx`, `landing.tsx`. |
| 77 | +- [ ] Delete corresponding `src/views/` subtrees. |
| 78 | +- [ ] Keep: `history` (rename → search), `search-overlay` (floating-window content), `settings`, `index.tsx`. |
| 79 | +- [ ] Audit and remove now-unused `components/`, `hooks/`, `store/`, `types/` entries. |
| 80 | + |
| 81 | +### 1.5 Backend strip |
| 82 | +- [ ] Delete `src-tauri/src/app/`: `agents.rs`, `agent_harness.rs`, `agent_runtime.rs`, `annual_report.rs`, `claude_web.rs`, `codex_commands.rs`, `command_registry.rs`, `command_routers.rs`, `command_stats.rs`, `commands.rs`, `context.rs`, `docs.rs`, `extensions.rs`, `feedback_*.rs`, `git.rs`, `hook_watcher_commands.rs`, `knowledge_reference.rs`, `lovstudio_auth.rs`, `maas_*.rs`, `marketplace_catalog.rs`, `project_logo.rs`, `provider_context.rs`, `pty.rs`, `run.rs`, `session_bridge.rs`, `session_cache.rs`, `session_migration.rs`, `skills.rs`, `template_install.rs`, `workspace.rs`, `claude_web_sync.rs`, `pty_manager.rs`, `hook_watcher.rs`. |
| 83 | +- [ ] Keep & port: `search.rs`, `session_listing.rs`, `session_parsing.rs`, `session_messages.rs` → moved into `lovcode-core`. |
| 84 | +- [ ] Keep in `src-tauri`: `lib.rs` (slim), `commands.rs` (thin invoke wrappers), `macos_window.rs` (floating window), `filesystem.rs` (path utils only if still needed), `lovcode_version.rs`, `network.rs` (only if floating-window needs it; otherwise delete), `settings_core.rs` (slim to just app prefs), `diagnostics.rs`. |
| 85 | +- [ ] Remove deps no longer needed: `portable-pty`, `arboard` (unless palette uses it), `shell-escape`, `zip`, `encoding_rs`, `filetime`, `libc`, `rusqlite`, `aes`, `cbc`, `pbkdf2`, `sha1`, `cocoa`, `objc`, `security-framework`. Re-add only what the floating window actually requires. |
| 86 | + |
| 87 | +### 1.6 Build green |
| 88 | +- [ ] `cargo check --workspace` passes. |
| 89 | +- [ ] `pnpm build` (frontend tsc + vite) passes. |
| 90 | +- [ ] `pnpm tauri dev` opens to the bare search page (may be empty results). |
| 91 | + |
| 92 | +--- |
| 93 | + |
| 94 | +## Phase 2 — CLI binary |
| 95 | + |
| 96 | +**Outcome:** `lovcode` is a usable single-binary search tool. |
| 97 | + |
| 98 | +### 2.1 `crates/lovcode-cli/` |
| 99 | +- [ ] `clap`-based command tree: |
| 100 | + - `lovcode index` — build/update the local index. |
| 101 | + - `lovcode search <query> [--source X] [--project P] [--since 7d] [--json]` |
| 102 | + - `lovcode sources` — list configured adapters + indexed counts. |
| 103 | + - `lovcode serve [--port 7878]` — HTTP server (axum), JSON API. |
| 104 | + - `lovcode mcp` — MCP server over stdio (uses `lovcode-mcp`). |
| 105 | +- [ ] Default index location: `~/.lovcode/index/`. Override via `--index-dir` or `LOVCODE_INDEX_DIR`. |
| 106 | +- [ ] Default config: `~/.lovcode/config.toml` (which adapters to enable, custom paths). |
| 107 | +- [ ] Output: plain pretty-printed by default; `--json` for scripting; `--no-color` honored. |
| 108 | + |
| 109 | +### 2.2 HTTP server (`serve`) |
| 110 | +- [ ] `axum` routes: `GET /search`, `GET /sources`, `GET /conversation/:id`, `POST /index/refresh`. |
| 111 | +- [ ] CORS default off; `--cors '*'` opt-in. |
| 112 | +- [ ] Bind `127.0.0.1` only by default; `--host 0.0.0.0` opt-in. |
| 113 | + |
| 114 | +### 2.3 Distribution |
| 115 | +- [ ] `cargo install lovcode` (publish to crates.io once stable). |
| 116 | +- [ ] GitHub Actions: build matrix → release binaries for macOS (arm64/x64), Linux (x64/arm64), Windows. |
| 117 | +- [ ] Install script `lovcode.dev/install.sh` (later — Phase 4). |
| 118 | + |
| 119 | +--- |
| 120 | + |
| 121 | +## Phase 3 — MCP server + more adapters |
| 122 | + |
| 123 | +### 3.1 MCP (`crates/lovcode-mcp/`) |
| 124 | +- [ ] Use `rmcp` (official Rust MCP SDK). Stdio transport. |
| 125 | +- [ ] Tools exposed: |
| 126 | + - `search_conversations(query, source?, project?, since?, limit?)` → results. |
| 127 | + - `get_conversation(id)` → full transcript. |
| 128 | + - `list_sources()` → adapters + counts. |
| 129 | +- [ ] `lovcode mcp` subcommand wires the server up; no daemon, spawned per-invocation by the MCP client. |
| 130 | + |
| 131 | +### 3.2 New adapters |
| 132 | +- [ ] **Claude Desktop** — port the cookie + Keychain decrypt logic from legacy `claude_web_sync.rs` into `adapters/claude_desktop.rs`. Pull conversations via API, persist as canonical `Conversation` JSON under `~/.lovcode/cache/claude-desktop/`. |
| 133 | +- [ ] **ChatGPT export** — parse the `.zip` export format. Trigger via `lovcode index --import-chatgpt path/to/export.zip`. |
| 134 | +- [ ] **Gemini export** — same shape as ChatGPT (Google Takeout format). |
| 135 | +- [ ] Document adapter contract in `docs/adapters.md` so external contributors can write their own. |
| 136 | + |
| 137 | +--- |
| 138 | + |
| 139 | +## Phase 4 — Tauri polish + Web UI + distribution |
| 140 | + |
| 141 | +### 4.1 Tauri desktop |
| 142 | +- [ ] Main window: single search page (input + result list + transcript preview pane). |
| 143 | +- [ ] Floating palette window: global hotkey (default `⌘⇧K`), Spotlight-style, opens fully invisible chrome. |
| 144 | +- [ ] Background watcher: `lovcode-core::watcher` runs in a Tokio task, surfaces "indexing N files…" status to the UI. |
| 145 | +- [ ] Settings page: enable/disable adapters, custom paths, hotkey rebinding, theme. |
| 146 | +- [ ] Auto-update via `tauri-plugin-updater` (kept from v0.39). |
| 147 | + |
| 148 | +### 4.2 Web UI |
| 149 | +- [ ] The same React frontend, built static, served by `lovcode serve` from the bundled assets. |
| 150 | +- [ ] Detect runtime: if `window.__TAURI__` → call `invoke`; else → call `/api/*`. Single switch in `src/lib/transport.ts`. |
| 151 | + |
| 152 | +### 4.3 Distribution |
| 153 | +- [ ] CI release pipeline: tag → build CLI binaries + Tauri bundles + publish crates. |
| 154 | +- [ ] Homebrew tap, scoop manifest, AUR (community). |
| 155 | +- [ ] `lovcode.dev` landing page with the four-surface story. |
| 156 | + |
| 157 | +--- |
| 158 | + |
| 159 | +## Out of Scope (for v0.40) |
| 160 | + |
| 161 | +- Cloud sync / multi-machine index. |
| 162 | +- Cross-conversation entity extraction or summarization. |
| 163 | +- Editing conversations. |
| 164 | +- Anything resembling Workbench / Skills / Marketplace / Lab. |
| 165 | +- Mobile app. |
| 166 | + |
| 167 | +--- |
| 168 | + |
| 169 | +## Open Questions |
| 170 | + |
| 171 | +1. **Index location for the desktop app vs CLI** — share `~/.lovcode/index/` or namespace them? Default plan: share. Single source of truth, instant reuse. |
| 172 | +2. **Hotkey default on Linux/Windows** — `⌘⇧K` translates to `Ctrl+Shift+K`. Confirm no conflicts (VSCode uses it for kill line; acceptable since palette is global, but offer easy rebind). |
| 173 | +3. **Authentication for `lovcode serve`** — bind-to-localhost is enough for v0.40. Token-based auth for `--host 0.0.0.0` deferred to v0.41. |
| 174 | +4. **MCP tool naming convention** — `search_conversations` vs `lovcode_search`. Decide before publishing to MCP registries. |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +## Tracking |
| 179 | + |
| 180 | +This file is the source of truth. Each phase ships as one or more commits on `main`; the legacy branch is frozen. |
| 181 | + |
| 182 | +Cross-references: |
| 183 | +- README (top-level) — public-facing pitch. |
| 184 | +- `legacy/v0.39-workbench` branch — pre-rewrite codebase. |
| 185 | +- `CHANGELOG.md` — per-release notes. |
0 commit comments