From a3b4065984d97ae525c39c19e5c0da0d94c5f54a Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Tue, 14 Apr 2026 23:11:12 +0530 Subject: [PATCH] docs: add v5.0 platform design spec Plugin-first architecture with four subsystems: - Plugin system (registry, context API, event bus) - Writing Studio (manuscript manager, sprints, snapshots, proofreading) - AI Assistant (multi-provider: Ollama, LMStudio, GGUF+GPU, cloud APIs) - Collaboration (git-based async, comments, review requests) Amit Haridas --- .gitignore | 3 + .../specs/2026-04-14-v5-platform-design.md | 389 ++++++++++++++++++ 2 files changed, 392 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-14-v5-platform-design.md diff --git a/.gitignore b/.gitignore index cc1a981..5b7783b 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,6 @@ pdf\ modal.png CLAUDE.md agents.md coverage/ + +# Superpowers brainstorm artifacts +.superpowers/ diff --git a/docs/superpowers/specs/2026-04-14-v5-platform-design.md b/docs/superpowers/specs/2026-04-14-v5-platform-design.md new file mode 100644 index 0000000..b608655 --- /dev/null +++ b/docs/superpowers/specs/2026-04-14-v5-platform-design.md @@ -0,0 +1,389 @@ +# MarkdownConverter v5.0 — Platform Design + +**Date:** 2026-04-14 +**Status:** Approved +**Author:** Amit Haridas + +## Overview + +Transform MarkdownConverter from a monolithic editor into an extensible platform with a plugin system and three feature packs, shipped together as v5.0. + +## Subsystems + +1. **Plugin System** — Lightweight plugin registry with extension points (sidebar, commands, settings, status bar, export hooks, event bus) +2. **Writing Studio Plugin** — Manuscript manager, goal tracking, writing sprints, snapshots, smart proofreading +3. **AI Assistant Plugin** — Multi-provider AI writing assistant (Ollama, LMStudio, GGUF direct with GPU, Anthropic, OpenAI) +4. **Collaboration Plugin** — Git-based async collaboration, comments/annotations, review requests + +## Core Principle + +**Existing functionality is never replaced or broken.** The plugin system is additive. All existing keyboard shortcuts, features, and UI remain untouched. Plugin shortcuts use `Ctrl+Alt+` namespace. + +--- + +## 1. Plugin System + +### File Structure + +``` +src/ + plugins/ + plugin-registry.js # Load, register, lifecycle + plugin-api.js # Base class plugins extend + plugin-loader.js # Discovers and validates manifests + built-in/ + writing-studio/ + manifest.json + index.js + panels/ + components/ + ai-assistant/ + manifest.json + index.js + providers/ + collaboration/ + manifest.json + index.js +``` + +### Manifest Schema + +```json +{ + "id": "writing-studio", + "name": "Writing Studio", + "version": "1.0.0", + "description": "Manuscript management, goal tracking, writing sprints", + "icon": "pen-tool", + "extensionPoints": { + "sidebar": { "panel": "panels/manuscript-panel.js", "order": 30 }, + "settings": { "section": "settings/index.js" }, + "statusBar": { "indicators": ["sprint-timer", "word-goal"] }, + "commands": [ + { "id": "start-sprint", "label": "Start Writing Sprint", "shortcut": "Ctrl+Alt+S" }, + { "id": "take-snapshot", "label": "Take Snapshot", "shortcut": "Ctrl+Alt+N" } + ], + "exportHooks": { + "preExport": "hooks/pre-export.js", + "postExport": "hooks/post-export.js" + } + }, + "settings": [ + { "key": "dailyGoal", "type": "number", "default": 1000, "label": "Daily word goal" }, + { "key": "sprintDuration", "type": "number", "default": 25, "label": "Sprint duration (min)" } + ] +} +``` + +### Plugin Lifecycle + +1. PluginLoader discovers manifests in `built-in/` + user plugins directory +2. PluginRegistry validates manifests +3. Each plugin calls `Plugin.init(context)` receiving scoped API context +4. Extension points registered (sidebar panels, commands, status bar items) +5. Plugins activate lazily — sidebar panel loads JS when user clicks tab + +### Plugin Context API + +Each plugin's `init()` receives: + +```javascript +{ + sidebar: { + registerPanel(id, { icon, title, component }) + }, + commands: { + register(id, label, handler, shortcut?) + }, + statusBar: { + registerIndicator(id, { position, render }) + }, + settings: { + get(key), // plugin-scoped + set(key, value), // auto-persisted via electron-store + onChanged(key, callback) + }, + editor: { + getContent(), // current document + getSelection(), // selected text + insertAtCursor(text), // requires opt-in + onContentChanged(callback) + }, + events: { + on(event, handler), + emit(event, data) + }, + exports: { + registerPreHook(handler), + registerPostHook(handler) + }, + ipc: { + invoke(channel, ...args), + on(channel, handler) + } +} +``` + +### Event Bus Events + +``` +document:opened, document:saved, document:changed, +editor:selection-changed, tab:switched, tab:closed, +export:started, export:completed, export:failed, +plugin:loaded, plugin:activated, plugin:deactivated, +app:ready, app:before-quit +``` + +### Design Rules + +- Built-in plugins use the same API as future third-party plugins +- Lazy activation — sidebar panels don't load until clicked +- Scoped settings: `plugins..` in electron-store +- Plugin errors caught and shown as notifications, never crash the app +- Plugin commands namespaced `:` + +--- + +## 2. Writing Studio Plugin + +### 2A. Manuscript / Project Manager + +Folder-based project structure: + +``` +~/Manuscripts/ + my-novel/ + .project.json # { title, targets, metadata } + 01-chapter-one.md + 02-chapter-two.md + characters/ + protagonist.md + research/ + world-building.md + .snapshots/ + 2026-04-14T10-30.json +``` + +`.project.json`: + +```json +{ + "title": "My Novel", + "type": "manuscript", + "target": { "words": 80000, "deadline": "2026-09-01" }, + "chapters": [ + { "file": "01-chapter-one.md", "title": "The Beginning", "status": "draft" } + ], + "metadata": { "author": "", "genre": "", "synopsis": "" } +} +``` + +Sidebar panel shows project tree with drag-to-reorder, word counts per chapter, target progress bar. "Compile manuscript" exports all chapters as a single document. + +### 2B. Goal Tracking & Writing Sprints + +- **Status bar**: daily progress bar + sprint timer +- **Writing sprint**: configurable duration (15/25/30/45/60 min), word count delta, WPM at end +- **Goal tracking**: daily/weekly word goals, streak tracking, 30-day bar chart +- **Enhanced analytics**: session tracking, readability scores, productive time-of-day heatmap +- Data stored in `plugins.writing-studio.history` as date-keyed map + +### 2C. Snapshot & Versioning + +- `Ctrl+Alt+N` or toolbar button saves snapshot +- Stored as JSON: `{ timestamp, content, wordCount, cursorPos, label }` +- Snapshot panel in sidebar: Restore, Diff (side-by-side), auto-snapshot interval +- Snapshots in `.snapshots/` inside project folder, or app data if no project + +### 2D. Smart Proofreading + +Delegates to AI plugin via event bus. Writing Studio provides: +- Right-click context menu: "Check grammar", "Suggest alternatives", "Analyze readability" +- Inline wavy underline decorations for issues +- Proofread panel: issues categorized by type with Accept/Dismiss + +### Commands + +| Command | Shortcut | Action | +|---------|----------|--------| +| `start-sprint` | `Ctrl+Alt+S` | Start writing sprint | +| `stop-sprint` | `Ctrl+Alt+Shift+S` | Stop sprint | +| `take-snapshot` | `Ctrl+Alt+N` | Save snapshot | +| `restore-last-snapshot` | `Ctrl+Alt+Z` | Restore latest snapshot | +| `new-project` | — | Create manuscript project | +| `compile-manuscript` | `Ctrl+Alt+E` | Export all chapters | +| `proofread-document` | `Ctrl+Alt+G` | AI proofread | + +--- + +## 3. AI Assistant Plugin + +### Provider Architecture + +``` +AI Plugin + ├── Provider Interface + │ ├── complete(prompt, options) → string + │ ├── stream(prompt, options) → AsyncIterable + │ └── analyze(text, type) → AnalysisResult + │ + ├── Providers + │ ├── OllamaProvider — localhost:11434 + │ ├── LMStudioProvider — localhost:1234/v1 + │ ├── GGUFProvider — direct llama.cpp with GPU support + │ ├── AnthropicProvider — Claude API + │ └── OpenAIProvider — GPT API + │ + └── Features + ├── Grammar/style check + ├── Inline auto-complete + ├── AI chat panel (sidebar) + ├── Document analysis + └── Smart commands (command palette) +``` + +### Provider Details + +**Ollama:** `GET /api/tags` for models, `POST /api/generate` and `POST /api/chat` for inference. + +**LMStudio:** OpenAI-compatible API at `localhost:1234/v1`. `GET /v1/models`, standard chat completion format, SSE streaming. + +**GGUF Direct (with GPU):** +- Ships bundled llama.cpp binaries per platform (CUDA, Vulkan, Metal, CPU variants) +- Auto-detects GPU: CUDA (nvidia-smi), Vulkan driver, Metal (macOS) +- GPU layer offloading: configurable, auto-suggests based on VRAM vs model size +- Settings: GPU backend selection, layer count, context length, thread count +- "Keep model loaded" option for faster repeated requests +- WASM fallback for sandboxed environments (CPU-only) +- External binary path for advanced users with custom builds +- Process management: spawn llama.cpp in server mode, clean up on app quit + +**Cloud (Anthropic/OpenAI):** +- API key stored encrypted via electron safeStorage +- Token usage tracking with estimated cost +- Rate limit awareness with request queueing and backoff + +### IPC Design + +All provider HTTP requests go through main process: +- No CORS issues +- API keys never in renderer +- Main process enforces rate limiting +- GGUF inference in main process + +``` +Renderer → ipc.invoke('ai:complete') → Main → HTTP to provider → result → Renderer +Renderer → ipc.invoke('ai:stream') → Main → HTTP stream → ipc.on('ai:chunk') → Renderer +``` + +### Features + +1. **Inline suggestions**: ghost text after configurable delay, Tab to accept, Esc to dismiss +2. **AI chat panel**: sidebar conversation, "Insert" / "Replace selection" buttons +3. **Document analysis**: grammar, style, tone, with accept/reject per suggestion +4. **Smart commands**: summarize, generate outline, find inconsistencies, translate, explain code + +### Privacy + +- Local-first: default provider is Ollama +- No telemetry: requests go direct to provider +- Content gating: exclude file types from AI +- Status bar shows "AI: processing..." with cancel option +- Cloud usage stats in settings (tokens, cost) + +### Cross-Plugin Integration + +```javascript +// Writing Studio calls AI Plugin +context.events.emit('ai:analyze', { text, type: 'grammar', callback }); +``` + +--- + +## 4. Collaboration Plugin + +### 4A. Enhanced Git Panel + +Upgrades to existing git panel: +- Remote management (add/remove remotes, push/pull) +- Branch list and switching +- Commit history with diff viewer (side-by-side or unified) +- Conflict resolution UI (accept-ours/accept-theirs/per-edit) + +### 4B. Shared Repository Workflow + +1. Writer A creates project + initializes git + pushes to shared repo +2. Writer B clones repo from within MarkdownConverter +3. Both write on their own branches +4. Writer A creates review request (simplified PR) + +Review request: changed files, word count diff, commit messages. Reviewer can approve, request changes, leave inline comments. Reviews are git branches + comments as git notes. + +### 4C. Comments & Annotations + +Inline comments stored as JSON in `.comments/` directory (git-tracked): +```json +{ + "id": "uuid", + "file": "03-chapter-three.md", + "range": { "start": 142, "end": 189 }, + "text": "This dialogue feels unnatural", + "author": "amit", + "timestamp": "2026-04-14T14:30:00Z", + "replies": [], + "resolved": false +} +``` + +- Highlighted text in editor with tooltip on hover +- Comment panel in sidebar: all unresolved comments across files +- Resolution workflow: add → address → reply → resolve +- Resolved comments dim but stay visible + +### 4D. Change Notifications + +- Status bar indicator: `↓ 3 new commits` +- Click to see changes, one-click pull +- Conflicts trigger resolution UI +- Push button only when local commits ahead of remote + +### 4E. Offline-First + +All writing happens locally. Git is the sync mechanism. No internet required for writing, commenting, snapshots, or sprints. Push/pull on user action or auto-sync setting. + +### Commands + +| Command | Shortcut | Action | +|---------|----------|--------| +| `collab:commit` | `Ctrl+Shift+G` | Commit with message | +| `collab:push` | — | Push current branch | +| `collab:pull` | — | Pull from remote | +| `collab:add-comment` | `Ctrl+Alt+C` | Comment on selection | +| `collab:next-comment` | `F8` | Next unresolved comment | +| `collab:prev-comment` | `Shift+F8` | Previous comment | +| `collab:create-review` | — | Create review request | + +### Cross-Plugin Integration + +```javascript +context.events.emit('snapshot:created', { file, snapshotId }); +context.events.on('project:chapter-opened', (chapter) => { /* load comments */ }); +context.events.on('comment:added', (comment) => { /* AI could suggest fix */ }); +``` + +--- + +## Bundle Size Impact + +- llama.cpp binaries: ~15MB per GPU variant, only target platform shipped +- Plugin system core: ~30KB +- Each built-in plugin: ~50-100KB +- Total estimated increase: ~50-70MB (primarily from llama.cpp binaries) + +## Testing Strategy + +- Plugin system: unit tests for registry, loader, context API mocking +- Each plugin: isolated unit tests, integration tests via plugin context +- AI provider tests: mock HTTP responses, test streaming parsing +- Git tests: use test repository fixture +- E2E: verify plugin loading doesn't break existing features