|
| 1 | +# PATTERN_ — Deep Work Interview Prep IDE |
| 2 | + |
| 3 | +A single-page interview prep tool designed for deliberate practice. Works standalone in the browser (no server required) — or with an optional Flask backend for Python/Java execution. |
| 4 | + |
| 5 | +Built to embed as an iframe on a blog. Users bring their own Gemini API key. |
| 6 | + |
| 7 | +  |
| 8 | + |
| 9 | +--- |
| 10 | + |
| 11 | +## Core Workflow |
| 12 | + |
| 13 | +The app enforces a structured problem-solving workflow across four steps before writing code: |
| 14 | + |
| 15 | +1. **Absorption & Constraints** — restate the problem, identify inputs/outputs/edge cases |
| 16 | +2. **Pattern Hunt & Data Structures** — identify applicable patterns and data structures |
| 17 | +3. **Logical Flow (Pseudocode)** — write pseudocode for the approach |
| 18 | +4. **Dry Run & Edge Cases** — trace through examples manually |
| 19 | + |
| 20 | +Each step has a Monaco editor and an **AI Validate** button that sends your work to Gemini for feedback. |
| 21 | + |
| 22 | +After the four steps, the **Implementation** section provides a full code editor with run/test capabilities. |
| 23 | + |
| 24 | +--- |
| 25 | + |
| 26 | +## Features |
| 27 | + |
| 28 | +### Problem Management |
| 29 | +- **LeetCode Catalog Search** — search and load problems from a cached LeetCode problem list |
| 30 | +- **Custom Problems** — paste any problem statement directly |
| 31 | +- **LC Seed Paste (📋)** — paste raw LeetCode API JSON blob to populate the problem catalog into localStorage |
| 32 | +- **Multi-Tab Workspace** — open multiple problems as tabs, each with independent state |
| 33 | +- **Tab Close vs Delete** — closing a tab hides it; deleting (🗑 in sidebar) permanently removes with confirmation |
| 34 | +- **Rename/Delete** — hover sidebar items to rename (✎) or delete (🗑) |
| 35 | + |
| 36 | +### AI Integration (Gemini) |
| 37 | +- **Collapsible API Key Input** — `{🗝}` trigger in sidebar footer, animated border pulse when no key is set, green when configured |
| 38 | +- **Step Validation** — each workbook step can be validated against the problem statement |
| 39 | +- **AI Strategy Analysis** — full pattern/approach analysis in the Reference view |
| 40 | +- **Boilerplate Generation** — auto-generates language-appropriate starter code on problem init |
| 41 | +- **Test Generation** — generates unit tests from your implementation code |
| 42 | +- **Auto Test Gen Timer** — after a successful code run, a 9-second countdown triggers silent background test generation (if tests editor is empty). Cancelable with Escape or click. |
| 43 | +- **Parallel Call Prevention (genMgr)** — prevents concurrent Gemini calls. All `[data-genaction]` buttons disable/dim during active calls. Dedup keys prevent re-running identical requests. |
| 44 | +- **Contextual Chat** — select any text in editors, description, or AI analysis to open a contextual question popup |
| 45 | +- **Chat Threads** — threaded Q&A with `@hash` cross-referencing between threads |
| 46 | +- **Ad-Hoc Chat** — general questions with code context (800 chars) and last 3 thread Q&As included automatically |
| 47 | +- **Gemini Proxy** — calls go through server when available, direct to Gemini API when in browser-only mode |
| 48 | + |
| 49 | +### Code Execution |
| 50 | +- **JavaScript** — sandboxed execution in a hidden iframe (no server needed, 10s timeout) |
| 51 | +- **Python / Java** — server-side execution via Flask backend |
| 52 | +- **Run Logic** — executes the code editor contents |
| 53 | +- **Run Tests** — concatenates code + tests editors and executes together |
| 54 | +- **Sanity Check** — client-side static analysis blocks dangerous patterns (`eval`, `subprocess`, `__import__`, etc.). Server-side AI check for Python/Java. |
| 55 | +- **Safe Code Hash Cache** — previously approved code skips re-checking |
| 56 | + |
| 57 | +### Voice (STT / TTS) |
| 58 | +- **Speech-to-Text (🎤)** — continuous speech recognition via Web Speech API |
| 59 | +- **Text-to-Speech (🔇/🔊)** — reads AI responses aloud, strips markdown, chunks to 200 chars |
| 60 | +- **Unified Toggle** — `Ctrl+Shift+V` (or `⌘+Shift+V` on Mac) toggles both mic and TTS together |
| 61 | +- **Smart Voice Input Targeting** — voice text goes to: last focused Monaco editor → focused input/textarea → fallback to ad-hoc chat (auto-opens panel) |
| 62 | +- **Robust Restart** — Chrome kills recognition after ~60s silence; auto-restarts with 300ms backoff |
| 63 | +- **Iframe Support** — requires `allow="microphone"` on the iframe tag |
| 64 | + |
| 65 | +### Editor & Layout |
| 66 | +- **Monaco Editors** — syntax-highlighted editors for all steps, code, and tests |
| 67 | +- **Language Selector** — Python, Java, JavaScript (Python/Java disabled when server unavailable) |
| 68 | +- **Maximize/Restore (⤢)** — any editor can go fullscreen with `Ctrl+Shift+M` or click |
| 69 | +- **Docked Terminal** — when code editor is maximized, terminal docks at bottom with its own run/test buttons |
| 70 | +- **Description Dock** — toggle description between top bar and left panel (`⬒ Dock Left` / `⬓ Dock Top`) |
| 71 | +- **Description Auto-Hide** — collapse description, peek on hover |
| 72 | +- **Collapsible Sidebar** — hamburger toggle, auto-expand on hover when collapsed |
| 73 | +- **Terminal** — color-coded output with spinner animations during async operations |
| 74 | + |
| 75 | +### Persistence |
| 76 | +- **localStorage First** — all state always written to localStorage |
| 77 | +- **Server Mirror** — when Flask server is available, state is mirrored to disk (`workspace_state.json`) |
| 78 | +- **Conflict Resolution** — localStorage wins on load; falls back to server if localStorage is empty |
| 79 | +- **Clobber Prevention** — `stateLoaded` flag prevents saving before load completes; empty-tabs guard prevents overwriting good data |
| 80 | +- **API Key** — stored only in localStorage, never sent to server for storage |
| 81 | +- **Terminal State** — per-tab terminal output and color persisted across tab switches |
| 82 | + |
| 83 | +### Status Bar |
| 84 | +- Thin 24px bar at bottom of viewport |
| 85 | +- **Left**: voice state with breathing pulse (`🎤 Listening · 🔊 Speaking` or `🎤 Voice off · Ctrl+Shift+V`) |
| 86 | +- **Right**: sync/server status (`Browser-Only Mode`, `Syncing...`, `Saved`, `Server Connected`) |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +## Keyboard Shortcuts |
| 91 | + |
| 92 | +| Shortcut | Action | |
| 93 | +|---|---| |
| 94 | +| `Ctrl+S` | Save | |
| 95 | +| `Ctrl+'` | Run Logic | |
| 96 | +| `Ctrl+"` | Generate Tests | |
| 97 | +| `Ctrl+Shift+L` | Clear Terminal | |
| 98 | +| `Ctrl+Shift+M` | Maximize/Restore focused editor | |
| 99 | +| `Ctrl+Shift+V` | Toggle Voice (STT + TTS) | |
| 100 | +| `Escape` | Cancel test gen timer / stop mic / stop TTS / restore maximized editor | |
| 101 | + |
| 102 | +--- |
| 103 | + |
| 104 | +## Running |
| 105 | + |
| 106 | +### Browser-Only (No Server) |
| 107 | + |
| 108 | +Open `templates/index.html` directly or serve with any static file server. JavaScript execution works out of the box. Set your Gemini API key via the `{🗝}` button. |
| 109 | + |
| 110 | +### With Flask Server |
| 111 | + |
| 112 | +```bash |
| 113 | +pip install flask |
| 114 | +python server.py |
| 115 | +``` |
| 116 | + |
| 117 | +Server runs on port **8500**. Enables: |
| 118 | +- Python and Java code execution |
| 119 | +- LeetCode problem fetching |
| 120 | +- Server-side sanity checking |
| 121 | +- Workspace state mirroring to disk |
| 122 | + |
| 123 | +### Embedding as iframe |
| 124 | + |
| 125 | +```html |
| 126 | +<iframe src="https://your-domain/..." allow="microphone" style="width:100%;height:100vh;border:none;"></iframe> |
| 127 | +``` |
| 128 | + |
| 129 | +The `allow="microphone"` attribute is required for voice features. |
| 130 | + |
| 131 | +--- |
| 132 | + |
| 133 | +## Project Structure |
| 134 | + |
| 135 | +``` |
| 136 | +├── templates/ |
| 137 | +│ └── index.html # Single-page app (~1600 lines) |
| 138 | +├── server.py # Optional Flask backend (port 8500) |
| 139 | +├── leetcode_cache.json # Cached problem list (367KB) |
| 140 | +└── workspace_state.json # Server-side state mirror |
| 141 | +``` |
| 142 | + |
| 143 | +--- |
| 144 | + |
| 145 | +## Tech Stack |
| 146 | + |
| 147 | +- **Frontend**: Vanilla JS, Monaco Editor, Tailwind CSS (CDN), Marked.js |
| 148 | +- **AI**: Google Gemini API (direct or proxied) |
| 149 | +- **Voice**: Web Speech API (SpeechRecognition + SpeechSynthesis) |
| 150 | +- **Backend** (optional): Flask, Python subprocess for code execution |
0 commit comments