@henryavila/mdprobe 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,152 +1,160 @@
1
- ![mdprobe](header.png)
1
+ ![mdProbe](header.png)
2
2
 
3
- # mdprobe
3
+ # mdProbe
4
4
 
5
- **The missing link between AI coding agents and human review.**
5
+ Markdown viewer and reviewer with live reload, persistent annotations, and AI agent integration.
6
6
 
7
- AI agents generate specs, docs, and RFCs — but you need to actually *read* them, *annotate* them, and *send structured feedback back*. mdprobe closes that loop: it renders markdown in the browser, lets you annotate inline, and returns structured YAML that agents can parse and act on.
8
-
9
- It works standalone too — as a markdown viewer with live reload and persistent annotations for any review workflow.
10
-
11
- [Install](#install) | [Quick Start](#quick-start) | [Features](#features) | [CLI Reference](#cli-reference) | [Library API](#library-api) | [Schema](#annotation-schema) | [AI Integration](#ai-agent-integration)
7
+ Open `.md` files in the browser, annotate inline, approve sections, and export structured feedback as YAML all from the terminal.
12
8
 
13
9
  ---
14
10
 
15
- ## What is mdprobe?
11
+ ## What mdProbe is
16
12
 
17
- A CLI tool that turns markdown files into a review environment in your browser.
13
+ - A **CLI tool** that renders markdown in the browser with live reload
14
+ - An **annotation system** where you select text and add tagged comments (bug, question, suggestion, nitpick)
15
+ - A **review workflow** with section-level approval (approve/reject per heading)
16
+ - An **MCP server** that lets AI agents (Claude Code, Cursor, etc.) open files, read annotations, and resolve feedback programmatically
18
17
 
19
- ```
20
- AI Agent writes spec.md ──> mdprobe spec.md --once ──> Human reviews & annotates ──> spec.annotations.yaml ──> Agent reads feedback
21
- ```
18
+ ## What mdProbe is not
22
19
 
23
- ### The problem
20
+ - Not a markdown editor — you edit in your own editor, mdprobe renders and annotates
21
+ - Not a static site generator — it runs a local server for live preview
22
+ - Not exclusive to AI — works perfectly as a standalone review tool
24
23
 
25
- AI agents produce markdown output (specs, architecture docs, RFCs) but have no way to get **structured, line-level feedback** from humans. You either paste comments back into chat (losing context) or approve blindly.
24
+ ---
26
25
 
27
- ### The solution
26
+ ## Install
28
27
 
29
- mdprobe renders your markdown with full GFM, syntax highlighting, Mermaid diagrams and math, then lets you select text and add annotations — `bug`, `question`, `suggestion`, `nitpick` — that are saved as a YAML sidecar. In `--once` mode, the agent's process blocks until you finish reviewing, then reads the annotations programmatically.
28
+ ```bash
29
+ npm install -g @henryavila/mdprobe
30
+ mdprobe setup
31
+ ```
30
32
 
31
- It also works as a standalone tool for any markdown review workflow no AI required.
33
+ The setup wizard configures your author name, installs the AI skill to detected IDEs (Claude Code, Cursor, Gemini), registers the MCP server, and adds a PostToolUse hook.
32
34
 
33
- ### Three workflows
35
+ For non-interactive environments: `mdprobe setup --yes --author "Your Name"`
34
36
 
35
- | Workflow | Command | Use case |
36
- |----------|---------|----------|
37
- | **View** | `mdprobe spec.md` | Render complex markdown in the browser with live reload |
38
- | **Review** | `mdprobe spec.md --once` | Agent blocks until human finishes annotating, then reads feedback |
39
- | **Embed** | `import { createHandler }` | Mount mdprobe inside your own Node.js server or tool |
37
+ Or run without installing:
38
+
39
+ ```bash
40
+ npx @henryavila/mdprobe README.md
41
+ ```
40
42
 
41
- Annotations are stored as plain YAML — readable by humans, parseable by machines, and version-controllable with git.
43
+ **Requirements:** Node.js 20+, a browser.
42
44
 
43
45
  ---
44
46
 
45
- ## Install
47
+ ## Quick Start
48
+
49
+ ### View and edit
46
50
 
47
51
  ```bash
48
- npm install -g @henryavila/mdprobe
52
+ mdprobe README.md
49
53
  ```
50
54
 
51
- Or use directly with npx:
55
+ Opens rendered markdown in the browser. Edit the source file — the browser updates instantly via WebSocket.
52
56
 
53
57
  ```bash
54
- npx @henryavila/mdprobe spec.md
58
+ mdprobe docs/
55
59
  ```
56
60
 
57
- ### Requirements
61
+ Discovers all `.md` files recursively and shows a file picker.
62
+
63
+ ### Annotate
64
+
65
+ Select any text in the browser → choose a tag → write a comment → save.
66
+
67
+ | Tag | Meaning |
68
+ |-----|---------|
69
+ | `bug` | Something is wrong |
70
+ | `question` | Needs clarification |
71
+ | `suggestion` | Improvement idea |
72
+ | `nitpick` | Minor style/wording |
58
73
 
59
- - Node.js 20+
60
- - A browser (auto-opens on macOS, Linux, and WSL)
74
+ Annotations are stored in `.annotations.yaml` sidecar files — human-readable, git-friendly.
61
75
 
62
76
  ---
63
77
 
64
- ## Quick Start
78
+ ## Singleton Server
65
79
 
66
- ### View a file
80
+ mdProbe runs a **single server instance**. Multiple invocations share the same server instead of starting duplicates:
67
81
 
68
82
  ```bash
69
- mdprobe README.md
83
+ mdprobe README.md # Starts server on port 3000, opens browser
84
+ mdprobe CHANGELOG.md # Detects running server, adds file, opens browser, exits
70
85
  ```
71
86
 
72
- Opens the rendered markdown in your browser. Edit the file in your editor the browser updates instantly.
87
+ The second invocation adds its files to the existing server and exits immediately. The browser shows all files in the sidebar.
73
88
 
74
- ### View a directory
89
+ **How it works:** A lock file at `/tmp/mdprobe.lock` records the running server's PID, port, and URL. New invocations read the lock file, verify the server is alive via HTTP health check, and join via `POST /api/add-files`. On shutdown (`Ctrl+C`), the lock file is removed automatically.
75
90
 
76
- ```bash
77
- mdprobe docs/
78
- ```
91
+ **Stale lock recovery:** If a previous instance crashed, the next invocation detects the dead process and starts fresh.
79
92
 
80
- Discovers all `.md` files recursively and shows a file picker.
93
+ ---
94
+
95
+ ## Two Review Workflows
96
+
97
+ mdProbe supports two distinct review workflows for different contexts:
81
98
 
82
- ### Review mode (blocking)
99
+ ### 1. Blocking review (`--once`) — for CI/CD and scripts
83
100
 
84
101
  ```bash
85
102
  mdprobe spec.md --once
86
103
  ```
87
104
 
88
- The process **blocks** until you click "Finish Review" in the UI. Annotations are saved to `spec.annotations.yaml`. Useful for AI agents that need human feedback before continuing.
105
+ Blocks the process until you click **"Finish Review"** in the UI. When you finish, annotations are saved to `spec.annotations.yaml` and the process exits with the list of created files. This is useful for pipelines that need human sign-off before continuing.
89
106
 
90
- ### Configure your name
107
+ `--once` mode always creates an **isolated server instance** — it does not participate in the singleton. This ensures review sessions have independent lifecycle.
91
108
 
92
- ```bash
93
- mdprobe config author "Your Name"
109
+ ### 2. AI-assisted review (MCP) — for AI coding agents
110
+
111
+ When working with AI agents (Claude Code, Cursor, etc.), the workflow is different. The agent does **not** use `--once`. Instead:
112
+
113
+ ```
114
+ Agent writes spec.md
115
+
116
+ Agent calls mdprobe_view → browser opens, server stays running
117
+
118
+ Human reads, annotates, approves/rejects sections
119
+
120
+ Human tells agent via chat: "done reviewing"
121
+
122
+ Agent calls mdprobe_annotations → reads all feedback
123
+
124
+ Agent fixes bugs, answers questions, evaluates suggestions
125
+
126
+ Agent reports changes, asks human to confirm
127
+
128
+ Agent calls mdprobe_update → resolves annotations
129
+
130
+ Human sees resolved items in real-time (greyed out)
94
131
  ```
95
132
 
96
- Your name is attached to every annotation and reply. On first use, mdprobe will prompt you interactively.
133
+ The server stays running across the entire conversation. The agent reads annotations on demand — no blocking, no process exit. Multiple files can be reviewed in the same session via the singleton server.
97
134
 
98
135
  ---
99
136
 
100
137
  ## Features
101
138
 
102
- ### Markdown Rendering
139
+ ### Rendering
103
140
 
104
- - **GFM** tables, task lists, strikethrough, autolinks
105
- - **Syntax highlighting** — all languages via highlight.js
106
- - **Mermaid diagrams** — rendered client-side
107
- - **Math/LaTeX** — via KaTeX (inline and display)
108
- - **Frontmatter** — YAML and TOML (parsed and stripped from output)
109
- - **Raw HTML** — passthrough with allowlist
110
- - **Images** — served from the markdown file's directory
141
+ GFM tables, syntax highlighting (highlight.js), Mermaid diagrams, math/LaTeX (KaTeX), YAML/TOML frontmatter, raw HTML passthrough, images from source directory.
111
142
 
112
143
  ### Live Reload
113
144
 
114
- File changes are detected via chokidar and pushed to the browser over WebSocket. Debounced at 100ms to avoid flicker during rapid saves. Scroll position is preserved across reloads.
115
-
116
- ### Annotations
117
-
118
- Select any text in the rendered markdown to open the annotation popover:
119
-
120
- - **4 tags**: `bug`, `question`, `suggestion`, `nitpick` — color-coded pills
121
- - **Threaded replies** — discuss annotations inline
122
- - **Resolve/reopen** — mark items as handled
123
- - **Persistent** — saved to `.annotations.yaml` sidecar (YAML format, git-friendly)
124
- - **Draggable popover** — move the form to read the content underneath
125
- - **Keyboard shortcuts** — `Ctrl+Enter` to save, `Esc` to close
145
+ File changes detected via chokidar, pushed over WebSocket. Debounced at 100ms. Scroll position preserved.
126
146
 
127
147
  ### Section Approval
128
148
 
129
- Every heading in your document gets approve/reject buttons:
130
-
131
- - **Symmetric cascade** — approving a parent approves all children; rejecting or resetting does the same
132
- - **Indeterminate state** — when children have mixed statuses, the parent shows a visual indicator
133
- - **Approve All / Clear All** — bulk operations for the entire document
149
+ Every heading gets approve/reject buttons. Approving a parent cascades to all children. Progress bar tracks reviewed vs total sections.
134
150
 
135
151
  ### Drift Detection
136
152
 
137
- When the source markdown changes after annotations were created, mdprobe shows a warning banner. This prevents stale annotations from going unnoticed.
153
+ Warning banner when the source file changes after annotations were created.
138
154
 
139
155
  ### Themes
140
156
 
141
- Five built-in themes based on the Catppuccin palette:
142
-
143
- | Theme | Style |
144
- |-------|-------|
145
- | **Mocha** | Dark (default) |
146
- | **Macchiato** | Dark, warm |
147
- | **Frappe** | Dark, deep blue |
148
- | **Latte** | Light |
149
- | **Light** | Pure white |
157
+ Five themes based on Catppuccin: Mocha (dark, default), Macchiato, Frappe, Latte, Light.
150
158
 
151
159
  ### Keyboard Shortcuts
152
160
 
@@ -154,24 +162,61 @@ Five built-in themes based on the Catppuccin palette:
154
162
  |-----|--------|
155
163
  | `[` | Toggle left panel (files + TOC) |
156
164
  | `]` | Toggle right panel (annotations) |
157
- | `\` | Toggle both panels (focus mode) |
165
+ | `\` | Focus mode (hide both panels) |
158
166
  | `j` / `k` | Next / previous annotation |
159
- | `?` | Show help overlay |
167
+ | `?` | Help overlay |
160
168
  | `Ctrl+Enter` | Save annotation |
161
- | `Esc` | Close popover / modal |
162
169
 
163
170
  ### Export
164
171
 
165
- Export annotations in four formats:
166
-
167
172
  ```bash
168
173
  mdprobe export spec.md --report # Markdown review report
169
- mdprobe export spec.md --inline # HTML comments inserted into source
174
+ mdprobe export spec.md --inline # Annotations inserted into source
170
175
  mdprobe export spec.md --json # Plain JSON
171
- mdprobe export spec.md --sarif # SARIF 2.1.0 (for CI/CD integration)
176
+ mdprobe export spec.md --sarif # SARIF 2.1.0 (CI/CD integration)
177
+ ```
178
+
179
+ ---
180
+
181
+ ## AI Agent Integration
182
+
183
+ mdProbe includes an MCP (Model Context Protocol) server and a skill file (`SKILL.md`) that teaches AI agents how to use the review workflow. This enables a two-way loop: the agent writes markdown, the human annotates, the agent reads feedback and resolves it.
184
+
185
+ ### Setup
186
+
187
+ ```bash
188
+ mdprobe setup
172
189
  ```
173
190
 
174
- Also available via the HTTP API: `GET /api/export?path=spec.md&format=json`
191
+ Interactive wizard that:
192
+ 1. Installs the `SKILL.md` to detected IDEs (Claude Code, Cursor, Gemini)
193
+ 2. Registers the MCP server (`mdprobe mcp`) in your Claude Code config
194
+ 3. Adds a PostToolUse hook that reminds the agent to use mdprobe when editing `.md` files
195
+ 4. Configures your author name
196
+
197
+ Non-interactive: `mdprobe setup --yes --author "Your Name"`
198
+ Remove everything: `mdprobe setup --remove`
199
+
200
+ ### MCP Tools
201
+
202
+ Once set up, AI agents can call these tools:
203
+
204
+ | Tool | Purpose |
205
+ |------|---------|
206
+ | `mdprobe_view` | Open `.md` files in the browser |
207
+ | `mdprobe_annotations` | Read annotations and section statuses |
208
+ | `mdprobe_update` | Resolve, reply, add, or delete annotations |
209
+ | `mdprobe_status` | Check if the server is running |
210
+
211
+ The MCP server participates in the singleton — if a CLI-started server is already running, the agent reuses it.
212
+
213
+ ### Manual MCP Registration
214
+
215
+ If you prefer not to use `mdprobe setup`:
216
+
217
+ ```bash
218
+ claude mcp add --scope user --transport stdio mdprobe -- mdprobe mcp
219
+ ```
175
220
 
176
221
  ---
177
222
 
@@ -182,27 +227,20 @@ mdprobe [files...] [options]
182
227
 
183
228
  Options:
184
229
  --port <n> Port number (default: 3000, auto-increments if busy)
185
- --once Review modeblocks until human finishes
230
+ --once Blocking reviewisolated server, exits on "Finish Review"
186
231
  --no-open Don't auto-open browser
187
232
  --help, -h Show help
188
233
  --version, -v Show version
189
234
 
190
235
  Subcommands:
191
- config [key] [value] Manage configuration
192
- export <path> [format-flag] Export annotations
193
- install --plugin Install Claude Code skill
236
+ setup Interactive setup (skill + MCP + hook)
237
+ setup --remove Uninstall everything
238
+ setup --yes [--author] Non-interactive setup
239
+ mcp Start MCP server (stdio, for AI agents)
240
+ config [key] [value] Manage configuration
241
+ export <path> [flags] Export annotations (--report, --inline, --json, --sarif)
194
242
  ```
195
243
 
196
- ### Config
197
-
198
- ```bash
199
- mdprobe config # Show all configuration
200
- mdprobe config author # Show current author
201
- mdprobe config author "Name" # Set author
202
- ```
203
-
204
- Configuration is stored in `~/.mdprobe.json`.
205
-
206
244
  ---
207
245
 
208
246
  ## Library API
@@ -216,7 +254,6 @@ const handler = createHandler({
216
254
  resolveFile: (req) => '/path/to/file.md',
217
255
  listFiles: () => [
218
256
  { id: 'spec', path: '/docs/spec.md', label: 'Specification' },
219
- { id: 'adr', path: '/docs/adr.md', label: 'Architecture Decision' },
220
257
  ],
221
258
  basePath: '/review',
222
259
  author: 'Review Bot',
@@ -234,13 +271,11 @@ http.createServer(handler).listen(3000)
234
271
  ```javascript
235
272
  import { AnnotationFile } from '@henryavila/mdprobe/annotations'
236
273
 
237
- // Load existing annotations
238
274
  const af = await AnnotationFile.load('spec.annotations.yaml')
239
275
 
240
276
  // Query
241
277
  const open = af.getOpen()
242
278
  const bugs = af.getByTag('bug')
243
- const mine = af.getByAuthor('Henry')
244
279
 
245
280
  // Mutate
246
281
  af.add({
@@ -253,13 +288,10 @@ af.add({
253
288
  author: 'Henry',
254
289
  })
255
290
  af.resolve(bugs[0].id)
256
-
257
- // Persist
258
291
  await af.save('spec.annotations.yaml')
259
292
 
260
293
  // Export
261
294
  import { exportJSON, exportSARIF } from '@henryavila/mdprobe/export'
262
- const json = exportJSON(af)
263
295
  const sarif = exportSARIF(af, 'spec.md')
264
296
  ```
265
297
 
@@ -267,7 +299,7 @@ const sarif = exportSARIF(af, 'spec.md')
267
299
 
268
300
  ## Annotation Schema
269
301
 
270
- Annotations are stored in YAML sidecar files (`<filename>.annotations.yaml`):
302
+ Sidecar file format (`<filename>.annotations.yaml`):
271
303
 
272
304
  ```yaml
273
305
  version: 1
@@ -277,91 +309,42 @@ sections:
277
309
  - heading: Introduction
278
310
  level: 2
279
311
  status: approved
280
- - heading: Requirements
281
- level: 2
282
- status: pending
283
312
  annotations:
284
313
  - id: "a1b2c3d4"
285
314
  selectors:
286
- position:
287
- startLine: 15
288
- startColumn: 1
289
- endLine: 15
290
- endColumn: 42
291
- quote:
292
- exact: "The system shall support concurrent users"
293
- prefix: ""
294
- suffix: ""
295
- comment: "How many concurrent users? Need a number."
315
+ position: { startLine: 15, startColumn: 1, endLine: 15, endColumn: 42 }
316
+ quote: { exact: "The system shall support concurrent users" }
317
+ comment: "How many concurrent users?"
296
318
  tag: question
297
319
  status: open
298
320
  author: Henry
299
321
  created_at: "2026-04-08T10:30:00.000Z"
300
- updated_at: "2026-04-08T10:30:00.000Z"
301
322
  replies:
302
- - author: Alice
323
+ - author: Agent
303
324
  comment: "Target is 500 concurrent."
304
325
  created_at: "2026-04-08T11:00:00.000Z"
305
326
  ```
306
327
 
307
- A JSON Schema is available at `@henryavila/mdprobe/schema.json` for validation.
308
-
309
- ### Tags
310
-
311
- | Tag | Meaning | SARIF Severity |
312
- |-----|---------|----------------|
313
- | `bug` | Something is wrong | error |
314
- | `question` | Needs clarification | note |
315
- | `suggestion` | Improvement idea | warning |
316
- | `nitpick` | Minor style/wording | note |
317
-
318
- ---
319
-
320
- ## AI Agent Integration
321
-
322
- mdprobe ships with a Claude Code skill that teaches the AI when and how to use it.
323
-
324
- ### Install the skill
325
-
326
- ```bash
327
- mdprobe install --plugin
328
- ```
329
-
330
- ### Agent workflow
331
-
332
- 1. Agent writes a spec/document to a `.md` file
333
- 2. Agent launches `mdprobe spec.md --once` (blocks)
334
- 3. Human reviews in the browser, adds annotations
335
- 4. Human clicks "Finish Review"
336
- 5. Agent reads `spec.annotations.yaml` and addresses each annotation
337
-
338
- ```javascript
339
- // Agent reads feedback after review
340
- import { AnnotationFile } from '@henryavila/mdprobe/annotations'
341
-
342
- const af = await AnnotationFile.load('spec.annotations.yaml')
343
- for (const ann of af.getOpen()) {
344
- console.log(`[${ann.tag}] Line ${ann.selectors.position.startLine}: ${ann.comment}`)
345
- }
346
- ```
328
+ JSON Schema available at `@henryavila/mdprobe/schema.json`.
347
329
 
348
330
  ---
349
331
 
350
332
  ## HTTP API
351
333
 
352
- All endpoints are available when the server is running.
334
+ Available when the server is running:
353
335
 
354
336
  | Method | Endpoint | Description |
355
337
  |--------|----------|-------------|
356
338
  | `GET` | `/api/files` | List markdown files |
357
- | `GET` | `/api/file?path=<file>` | Get rendered HTML + TOC + frontmatter |
358
- | `GET` | `/api/annotations?path=<file>` | Get annotations + sections + drift status |
339
+ | `GET` | `/api/file?path=<file>` | Rendered HTML + TOC + frontmatter |
340
+ | `GET` | `/api/annotations?path=<file>` | Annotations + sections + drift status |
359
341
  | `POST` | `/api/annotations` | Create/update/delete annotations |
360
342
  | `POST` | `/api/sections` | Approve/reject/reset sections |
361
343
  | `GET` | `/api/export?path=<file>&format=<fmt>` | Export (json, report, inline, sarif) |
362
- | `GET` | `/api/config` | Get current author |
344
+ | `GET` | `/api/status` | Server identity, PID, port, file list |
345
+ | `POST` | `/api/add-files` | Add files to a running server (singleton join) |
363
346
 
364
- WebSocket at `/ws` provides real-time file change notifications.
347
+ WebSocket at `/ws` for real-time updates.
365
348
 
366
349
  ---
367
350
 
@@ -371,30 +354,35 @@ WebSocket at `/ws` provides real-time file change notifications.
371
354
  git clone https://github.com/henryavila/mdprobe.git
372
355
  cd mdprobe
373
356
  npm install
374
- npm run build:ui # Build the Preact UI
375
- npm test # Run test suite (489 tests)
357
+ npm run build:ui
358
+ npm test
376
359
  ```
377
360
 
378
- ### Project structure
361
+ ### Project Structure
379
362
 
380
363
  ```
381
364
  bin/cli.js CLI entry point
382
365
  src/
383
366
  server.js HTTP + WebSocket server
384
- renderer.js Markdown rendering pipeline (remark/rehype)
385
- annotations.js Annotation CRUD + section approval + cascade
386
- export.js 4 export formats (report, inline, JSON, SARIF)
367
+ singleton.js Lock file + cross-process singleton coordination
368
+ mcp.js MCP server (4 tools, stdio transport)
369
+ renderer.js Markdown HTML (unified/remark/rehype)
370
+ annotations.js Annotation CRUD + section approval
371
+ export.js Export: report, inline, JSON, SARIF
372
+ setup.js IDE skill + MCP + hook registration
373
+ setup-ui.js Interactive setup wizard
387
374
  handler.js Library API for embedding
388
- config.js User configuration (~/.mdprobe.json)
375
+ config.js User config (~/.mdprobe.json)
376
+ open-browser.js Cross-platform browser launcher
389
377
  hash.js SHA-256 drift detection
390
- anchoring.js Text position matching for highlights
378
+ anchoring.js Text position matching
391
379
  ui/
392
- components/ Preact components (App, Content, Popover, Panels...)
393
- hooks/ Custom hooks (WebSocket, keyboard, theme, annotations)
394
- state/store.js Preact Signals state management
395
- styles/themes.css Catppuccin theme system
396
- schema.json JSON Schema for annotation YAML
397
- skills/ Claude Code integration skill
380
+ components/ Preact components
381
+ hooks/ WebSocket, keyboard, theme, annotations
382
+ state/store.js Preact Signals state
383
+ styles/themes.css Catppuccin themes
384
+ schema.json Annotation YAML schema
385
+ skills/mdprobe/ AI agent skill (SKILL.md)
398
386
  ```
399
387
 
400
388
  ---