{"_id":"@agoalofalife/review-kungfu","name":"@agoalofalife/review-kungfu","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@agoalofalife/review-kungfu","version":"0.1.0","description":"Local web-based Markdown annotation tool with Claude Code integration","bin":{"review-kungfu":"server.js"},"scripts":{"start":"node server.js"},"keywords":["markdown","review","claude-code","annotation"],"license":"MIT","author":{"name":"agoalofalife@gmail.com"},"engines":{"node":">=18"},"type":"commonjs","dependencies":{"ws":"^8.20.0"},"_id":"@agoalofalife/review-kungfu@0.1.0","gitHead":"57655d5a9960539e569d15965d1b4f93fa20ca72","_nodeVersion":"24.3.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-d5zgAakzuLqHxw0MjJP3G8gGUCksIeWjTqYs3CPsC1YaCdUorBTUFLX0nxwjE6fP2pQX37yeXq5ASdNStAI5vw==","shasum":"397f90be2372b34c8167d3717b7452808c4a4833","tarball":"https://registry.npmjs.org/@agoalofalife/review-kungfu/-/review-kungfu-0.1.0.tgz","fileCount":24,"unpackedSize":176983,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGyFzXSMW3D4Cot5sBfcZXu+QBmYRiqb1RcuS/CWgz66AiBre4SIitv8TkEFoplj/MMg5cypaGo9ImFBjXycwTi4HQ=="}]},"_npmUser":{"name":"agoalofalife","email":"agoalofalife@gmail.com"},"directories":{},"maintainers":[{"name":"agoalofalife","email":"agoalofalife@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/review-kungfu_0.1.0_1777827164164_0.5755951099895174"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-03T16:52:44.056Z","0.1.0":"2026-05-03T16:52:44.318Z","modified":"2026-05-03T16:52:44.544Z"},"maintainers":[{"name":"agoalofalife","email":"agoalofalife@gmail.com"}],"description":"Local web-based Markdown annotation tool with Claude Code integration","keywords":["markdown","review","claude-code","annotation"],"author":{"name":"agoalofalife@gmail.com"},"license":"MIT","readme":"# review-kungfu\n\n**Local Markdown review tool with native Claude Code integration.**\n\nOpen any set of `.md` files in the browser, annotate them like a GitHub PR, and push the review directly into a running Claude Code session — no copy-paste, no context juggling.\n\nBuilt for reviewing agent-generated plans, RFCs, task lists, and documentation.\n\n**Audience:** solo developers who use Claude Code and want a fast way to review agent-generated markdown plans, docs, RFCs, and task lists, then feed corrections back without copy-paste.\n\n**Not a general-purpose markdown editor.** Read-mostly, with surgical edits (checkbox toggle, comments). Content is not edited inline.\n\n![review-kungfu preview](docs/preview.png)\n\n---\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [Claude Code Integration](#claude-code-integration)\n- [Settings Panel](#settings-panel)\n- [Themes](#themes)\n- [Fonts](#fonts)\n- [Editors & Terminals](#editors--terminals)\n- [File Path Links](#file-path-links)\n- [Keyboard Shortcuts](#keyboard-shortcuts)\n- [Push Format](#push-format)\n- [File Structure](#file-structure)\n- [Architecture](#architecture)\n- [Troubleshooting](#troubleshooting)\n- [Requirements](#requirements)\n- [Uninstall](#uninstall)\n- [License](#license)\n\n---\n\n## Features\n\n**Core**\n- Two view modes: **Source** (raw Markdown with syntax highlighting) and **Preview** (rendered) — toggling preserves your scroll position by line, not by ratio\n- Tabs for multiple files, with active-tab persistence across reloads, and a per-tab close `×` (hover to reveal) when more than one file is open\n- Line-by-line commenting (add, edit, delete, statuses `pending` / `pushed`)\n- **Push to Claude Code** — delivers review via the IDE bridge (MCP over WebSocket)\n- **Auto-submit on push** *(macOS only, opt-in)* — after the push, send Enter to the Claude Code CLI so the review is processed without you switching terminals. See [Auto-submit on push](#auto-submit-on-push)\n- Auto-start Claude Code session from the UI in a terminal of your choice\n\n**Reading**\n- Table of contents, auto-generated from headings, with scroll-sync highlighting\n- In-page hash links (e.g. `[Features](#features)`) jump to the matching heading inside the preview container — Markdown anchor TOCs work as expected\n- Inline images with relative paths (e.g. `![](docs/preview.png)`) are resolved relative to the markdown file's directory and served via an internal asset endpoint\n- Interactive checkboxes in Preview — click `[x]` / `[ ]` to rewrite the source\n- Copy-code button on every fenced block\n- Line numbers in code blocks\n- Mermaid diagrams\n- Syntax highlighting (highlight.js) with theme-aware color palette\n\n**Customization**\n- 13 themes (GitHub, Dracula, Monokai, Nord, One Dark, Gruvbox, Tokyo Night, Solarized, Material, Oceanic, …)\n- 11 fonts (JetBrains Mono default + Fira Code, Source Code Pro, IBM Plex Mono, Inconsolata, Ubuntu Mono, Inter, Merriweather, Lora, Nunito, System UI)\n- Adjustable font size, line height, max content width, TOC size & width — all with live preview and persistence\n\n**Editing**\n- Click any path-like link (`phpstorm://`, `vscode://`, etc.) in Preview to open the file in your configured editor at the right line\n- Path resolution tries: markdown file's dir → git root → CWD\n- Click a line number in Source to copy `file.md:N` to clipboard (great for pasting into Claude)\n\n**Live-reload**\n- File watcher: when the underlying markdown changes on disk, the Preview re-renders with a subtle flash and toast\n\n---\n\n## Installation\n\n```bash\ngit clone <repo>\ncd review-kungfu\nnpm install\nnpm link\n```\n\nAfter `npm link`, the `review-kungfu` command is available globally.\n\n---\n\n## Quick Start\n\n```bash\nreview-kungfu path/to/plan.md\n```\n\nBrowser opens automatically. Click any block's `+` in Preview (or hover a line in Source and click `+`) to add a comment. When you're done, click **Push to Claude Code**.\n\nIf Claude Code isn't yet connected, click **Start Claude Code** in the header — it launches `claude --ide` in your configured terminal with the correct working directory, and connects back automatically.\n\n---\n\n## Usage\n\n```bash\n# Single file\nreview-kungfu docs/plan.md\n\n# Multiple files → shown as tabs\nreview-kungfu docs/plan.md docs/architecture.md docs/rfc-01.md\n\n# Shell glob\nreview-kungfu docs/*.md\n\n# Custom port (default 7700, overridable via REVIEW_KUNGFU_PORT env)\nreview-kungfu docs/plan.md --port 8080\n\n# Resume a previous session (reuses comment history)\nreview-kungfu --session abc123def456\n\n# Pick an editor up front (otherwise auto-detected or set in Settings)\nreview-kungfu docs/plan.md --editor code\n```\n\n---\n\n## Claude Code Integration\n\nreview-kungfu registers itself as an IDE with Claude Code using the same mechanism JetBrains/VS Code plugins use (lockfile at `~/.claude/ide/{port}.lock` + WebSocket MCP server). There are three ways to connect:\n\n### 1. Auto-launch (easiest)\n\nClick the amber **Start Claude Code** button in the browser header. review-kungfu spawns `claude --ide` in your selected terminal (iTerm2 / Ghostty / tmux / Terminal.app) with the correct working directory. The connection is established automatically.\n\nThe button turns into a green **Claude Code connected** label once connected.\n\n### 2. From an existing Claude Code session\n\nIn a running Claude Code conversation:\n\n```\n/ide\n```\n\nSelect **review-kungfu** from the list. Connection established.\n\n### 3. File-based fallback\n\nAfter clicking **Push to Claude Code**, the full formatted review is written to `~/.review-kungfu/latest-push.md`. You can just tell Claude:\n\n```\nRead my review from ~/.review-kungfu/latest-push.md\n```\n\nThe push is also copied to the clipboard via a modal button.\n\n### What happens on Push\n\n1. Pending comments are formatted into the `---MD-REVIEW-PUSH---` envelope\n2. File is written to `~/.review-kungfu/latest-push.md` and session history\n3. The `at_mentioned` MCP notification is sent to Claude Code — it reads the file into context\n4. The exposed MCP tool `get_review_comments` now shows `[NEW REVIEW AVAILABLE]` in its description\n5. Comments are marked `pushed`; you can continue annotating and push again\n6. *(Optional — see below)* If **Auto-submit on push** is enabled, review-kungfu sends `Enter` to the Claude Code terminal so the @-mention is submitted automatically\n\n### Auto-submit on push\n\nBy default `at_mentioned` only stages the push file in Claude Code's input buffer — you still have to press Enter in the terminal yourself. The **Auto-submit on push** setting lets review-kungfu do it for you.\n\n**macOS only.** The implementation uses AppleScript and `tmux send-keys`; there's no equivalent on Linux/Windows.\n\nHow it's done per terminal:\n\n| Terminal | Mechanism | Focus stealing? |\n|---|---|---|\n| **iTerm2** | `osascript` activates iTerm2, then `System Events` → `keystroke return` | Yes (briefly) |\n| **Ghostty** | Same — Ghostty has no scripting API for sending input | Yes (briefly) |\n| **tmux** | `tmux send-keys -t claude Enter` (targets the window the launcher creates) | No |\n| **Terminal.app** | `osascript` activate + `keystroke return` | Yes (briefly) |\n\nCaveats:\n\n- Each push the terminal will briefly come to the front (except tmux). Your browser regains focus after.\n- **Accessibility permission** is required for the keystroke synthesis. The first push triggers a macOS permission dialog asking you to add the parent process (your shell, iTerm2, etc.) to **System Settings → Privacy & Security → Accessibility**. If the dialog doesn't appear, add it manually.\n- iTerm2 / Terminal.app use the **frontmost** window. If you have multiple windows open and Claude Code isn't in the active one, the Enter goes to the wrong place.\n- The tmux path assumes the window is named `claude` (which the launcher creates). If you started Claude in tmux yourself with a different window name, auto-submit won't find it.\n- If auto-submit fails, the toast in the browser will say \"auto-submit failed: …\" and the server log prints `[auto-submit] result ok=false error=…`.\n\n---\n\n## Settings Panel\n\nClick the **⚙** icon in the bottom-left to open the floating settings panel. Every option persists across page reloads and sessions.\n\n| Setting | What it does |\n|---|---|\n| **Theme** | Grid of 13 color themes. Applies to the whole page + swaps highlight.js stylesheet. |\n| **Font** | Select from 11 Google Fonts: monospace, sans-serif, serif. |\n| **Font size** | 12–28 px slider. Code blocks scale proportionally (0.85×). |\n| **Line height** | 1.2–2.5 slider. |\n| **Max width** | 500–1200 px. Keeps long lines readable. |\n| **TOC size** | 9–18 px. Size of table of contents text. |\n| **TOC width** | 120–350 px. Controls TOC panel width and truncation. |\n| **Editor** | Which editor opens when you click a path link. |\n| **Terminal** | Which terminal hosts `claude --ide` and terminal editors (vim/nvim). |\n| **Comment in source** | If on (default), clicking `+` in Preview jumps to Source mode at that line and opens the comment form, then returns to Preview on submit. |\n| **Auto-submit on push** | Off by default. When on, review-kungfu sends `Enter` to the Claude Code terminal right after pushing, so the review is processed without you switching apps. **macOS only.** See [Auto-submit on push](#auto-submit-on-push) below for caveats. |\n\n---\n\n## Themes\n\nAll themes update: page background, text, headings, links, inline code, code blocks, blockquotes, borders, and the highlight.js syntax colors.\n\n- **Default** — adaptive, follows Tailwind's dark/light\n- **GitHub Dark**, **GitHub Light**\n- **Dracula**\n- **Monokai**\n- **Nord**\n- **One Dark** (Atom)\n- **Gruvbox**\n- **Tokyo Night**\n- **Solarized Dark**, **Solarized Light**\n- **Material**\n- **Oceanic**\n\nHover any theme swatch to see its name below the grid.\n\n---\n\n## Fonts\n\nLoaded from Google Fonts with preconnect for fast first paint. Applies to the whole app (body + preview + UI chrome).\n\nMonospace: **JetBrains Mono** (default), **Fira Code**, **Source Code Pro**, **IBM Plex Mono**, **Inconsolata**, **Ubuntu Mono**.\nSans-serif: **Inter**, **Nunito**, **System UI**.\nSerif: **Merriweather**, **Lora**.\n\n---\n\n## Editors & Terminals\n\n### Supported editors\n\nGUI: **PhpStorm**, **RustRover**, **GoLand**, **IntelliJ IDEA**, **Zed**, **VS Code**, **Cursor**.\nTerminal: **Neovim**, **Vim** — launched inside your chosen terminal emulator.\n\nJetBrains IDEs are opened via their native URL scheme (`phpstorm://open?file=…&line=…`) which is the most reliable way on macOS.\n\n### Supported terminals\n\n**iTerm2** (new tab via AppleScript), **Ghostty** (`open -na`), **tmux** (`tmux new-window`), **Terminal.app** (AppleScript).\n\nThe terminal setting is used both for launching Claude Code and for opening vim/nvim on clicked file paths.\n\n---\n\n## File Path Links\n\nWrite links in markdown using editor-protocol URLs — the preview renders them as clickable, and review-kungfu routes the click through your configured editor (not the URL's embedded editor).\n\n```markdown\n[file.php:42](phpstorm://open?file=app/Services/PaymentService.php&line=42)\n[config](vscode://file/~/project/config.yaml&line=1)\n[main.go](goland://open?file=/abs/path/to/main.go&line=100)\n```\n\nThree ways to write paths:\n\n1. **Relative to project root** (recommended for sharing with teammates):\n   ```markdown\n   [Model](phpstorm://open?file=app/Models/User.php&line=42)\n   ```\n   review-kungfu tries: active-file's directory → git root → launch CWD. First hit wins.\n\n2. **Home directory with `~/`**:\n   ```markdown\n   [config](phpstorm://open?file=~/.config/nvim/init.lua)\n   ```\n\n3. **Absolute paths** (personal notes only — don't share):\n   ```markdown\n   [note](phpstorm://open?file=/Users/me/notes.md&line=5)\n   ```\n\n**Bonus:** clicking a line number in **Source** mode copies `file.md:N` to clipboard (shows a toast). Handy for pasting into Claude Code.\n\n---\n\n## Keyboard Shortcuts\n\n| Key | Action |\n|---|---|\n| `Esc` | Cancel comment form / close modal |\n| `Ctrl+Enter` / `Cmd+Enter` | Submit comment or save edit |\n\n---\n\n## Push Format\n\nWhen you click **Push to Claude Code**, the comments are serialized as:\n\n```\n---MD-REVIEW-PUSH---\nSession: abc123def456\nFiles: plan.md\n\n## plan.md\n\n**Line 5** (`This project uses a modular structure`):\n> Need to clarify the module boundaries here\n\n**Line 23** (`### Error Handling`):\n> Does this cover timeout scenarios?\n\nSummary: 2 comments, 1 file(s)\n---END-MD-REVIEW---\n```\n\nThis same payload is:\n- Written to `~/.review-kungfu/latest-push.md` (for manual Claude prompting)\n- Appended to the session history at `~/.review-kungfu/sessions/{id}/push-{n}.md`\n- Printed to the server's stdout (the terminal where review-kungfu runs)\n- Pushed via MCP `at_mentioned` to any connected Claude Code session\n\n---\n\n## File Structure\n\n```\n~/.review-kungfu/\n├── sessions/\n│   └── {session-id}/\n│       ├── meta.json          # files, timestamps, push count\n│       ├── comments.json      # all comments for this session\n│       └── push-{n}.md        # historical push outputs\n├── latest-session.txt         # ID of the last started session\n└── latest-push.md             # most recent push output\n```\n\nNothing is ever deleted automatically; clean up manually if you want.\n\n---\n\n## Architecture\n\n```mermaid\ngraph TD\n    User[User in terminal] -->|review-kungfu file.md| Server[Node.js server.js]\n    Server -->|spawns| HTTP[HTTP :7700+]\n    Server -->|spawns| WS[WebSocket MCP :10000+]\n    HTTP -->|serves| Browser[Browser UI]\n    Browser -->|HTTP + SSE| HTTP\n    WS -->|MCP JSON-RPC| Claude[Claude Code CLI]\n    Server -->|writes| Lockfile[~/.claude/ide/*.lock]\n    Claude -->|reads lockfile, /ide| WS\n    Server -->|fs.watch| Files[Markdown files]\n    Files -->|SSE file-changed| Browser\n    Browser -->|POST /api/push| Server\n    Server -->|bridge.pushReview<br/>at_mentioned| Claude\n```\n\nTwo parallel servers in one Node process:\n\n1. **HTTP + SSE** for the browser UI and REST API (`/api/session`, `/api/files`, `/api/comments`, `/api/push`, `/api/open-editor`, `/api/toggle-checkbox`, `/api/start-claude`, …)\n2. **WebSocket MCP** for Claude Code — speaks the same MCP protocol as the official JetBrains/VS Code plugins\n\nThe browser never talks to Claude Code directly. The server translates HTTP actions into MCP notifications.\n\nFor the full internal architecture and module breakdown, see **[AGENTS.md](AGENTS.md)**.\n\n---\n\n## Troubleshooting\n\n**`/ide` shows review-kungfu but fails to connect.**\nClaude Code validates that its current working directory matches one of the `workspaceFolders` in review-kungfu's lockfile. review-kungfu auto-includes each file's parent directory, each file's git root (if any), and the launch CWD. If your Claude Code session is in a directory outside those, either `cd` into a parent-of-project directory or restart review-kungfu from there.\n\n**`open -a Ghostty` opens but immediately closes with \"No such file or directory\".**\nGhostty passes the `-e` argument to `/usr/bin/login`, not a shell. review-kungfu already wraps the command in `sh -c \"...; exec sh\"`. If you customized the template, keep that pattern.\n\n**Vim/Neovim says \"command not found\" when opened from a clicked link.**\nGUI-launched terminals don't inherit your shell PATH. review-kungfu uses full binary paths (`/opt/homebrew/bin/nvim`, `/usr/bin/vim`). If yours live elsewhere, edit `src/editor.js` (`terminalEditorPaths`).\n\n**File watcher stops reacting to changes.**\n`fs.watch` on macOS is occasionally flaky. Restart review-kungfu. Polling is on the backlog.\n\n**Theme selector doesn't change code-block colors.**\nThat highlight.js CDN doesn't host that theme under the name I guessed. Check `base16/` subfolder (e.g. `base16/dracula`, `base16/solarized-dark`).\n\n**Auto-submit reports `ok=true` in the log but no Enter actually fired in the terminal.**\nThis is the silent-success case for missing **Accessibility** permission. macOS lets `osascript` succeed even when `System Events` → `keystroke` is silently denied. Open **System Settings → Privacy & Security → Accessibility** and add (or toggle on) the parent process that launched review-kungfu — typically your shell's host app (iTerm2, Terminal.app, Ghostty, etc.) or the `node` binary itself. Verify by running this in a regular shell — Ghostty (or whichever terminal) should briefly come to the front and receive an Enter:\n\n```bash\nosascript -e 'tell application \"Ghostty\" to activate' \\\n          -e 'delay 0.2' \\\n          -e 'tell application \"System Events\" to keystroke return'\n```\n\n**Auto-submit doesn't fire at all (no `[auto-submit]` log line).**\nThe browser is probably running the cached old `app.js`. Hard-reload (`Cmd+Shift+R`), then re-toggle the setting under ⚙ — old `localStorage` doesn't carry the new flag.\n\n---\n\n## Requirements\n\n- **Node.js 18+**\n- **macOS** (Ghostty, iTerm2 AppleScript, `open -a` all macOS-specific; Linux/Windows require port modifications)\n- **Claude Code CLI** (installable as `claude` — review-kungfu currently hardcodes `/Applications/cmux.app/Contents/Resources/bin/claude`; edit `src/claude-launcher.js` if yours is elsewhere)\n- Modern browser (Chrome, Firefox, Safari, Edge)\n\n---\n\n## Uninstall\n\n```bash\ncd review-kungfu\nnpm unlink -g review-kungfu\n```\n\nTo remove all stored sessions and pushes:\n\n```bash\nrm -rf ~/.review-kungfu\n```\n\nTo remove any leftover IDE lockfiles:\n\n```bash\nrm -f ~/.claude/ide/*.lock\n```\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-4b7813331afe7959b31acacef82ff30f"}