plan-review 1.0.0 → 1.0.3
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 +70 -28
- package/dist/browser/index.html +5 -0
- package/examples/demo-browser.gif +0 -0
- package/examples/demo-plan.md +129 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# plan-review
|
|
2
2
|
|
|
3
|
-
Interactive CLI for reviewing AI-generated markdown plans. Parses plans into sections, renders them in the terminal or browser, collects your comments, and outputs structured feedback.
|
|
3
|
+
Interactive CLI for reviewing AI-generated markdown plans. Parses plans into sections, renders them in the terminal or browser, collects your comments, and outputs structured feedback — back to the AI or your team.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,30 +8,65 @@ Interactive CLI for reviewing AI-generated markdown plans. Parses plans into sec
|
|
|
8
8
|
npm install -g plan-review
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### Claude Code skill (optional)
|
|
12
|
+
|
|
13
|
+
If you use Claude Code, install the companion skill so you can say *"review this plan"*:
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
plan-review install-skill
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Try the included demo plan
|
|
23
|
+
plan-review --browser examples/demo-plan.md
|
|
16
24
|
|
|
17
|
-
#
|
|
25
|
+
# Review your own plan
|
|
18
26
|
plan-review path/to/plan.md --browser
|
|
27
|
+
|
|
28
|
+
# Pipe feedback directly to Claude
|
|
29
|
+
plan-review path/to/plan.md --browser -o claude
|
|
19
30
|
```
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
## Browser mode (`--browser`)
|
|
33
|
+
|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
The browser mode opens a three-panel review UI:
|
|
22
37
|
|
|
23
38
|
```
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
39
|
+
+------------------+----------------------------+------------------+
|
|
40
|
+
| | | |
|
|
41
|
+
| Table of | Rendered markdown | Comment |
|
|
42
|
+
| Contents | with plan metadata | Sidebar |
|
|
43
|
+
| | | |
|
|
44
|
+
| - Milestone 1 | ## Task 1.1 | [Add comment] |
|
|
45
|
+
| * Task 1.1 ✓ | | |
|
|
46
|
+
| * Task 1.2 | **Depends on:** 1.0 | > "Line 3-5" |
|
|
47
|
+
| - Milestone 2 | **Blocks:** 1.2 | Fix the error |
|
|
48
|
+
| * Task 2.1 | | handling here |
|
|
49
|
+
| | Content with line | |
|
|
50
|
+
| | gutters for anchoring | [Submit Review] |
|
|
51
|
+
| | comments to ranges | |
|
|
52
|
+
+------------------+----------------------------+------------------+
|
|
30
53
|
```
|
|
31
54
|
|
|
32
|
-
|
|
55
|
+
**Line-anchored comments:** Click a line number in the gutter to start a selection. Shift-click another line to select a range. Your comment is anchored to those exact lines.
|
|
33
56
|
|
|
34
|
-
|
|
57
|
+
**Section-level comments:** Click "Add comment to entire section" below any section.
|
|
58
|
+
|
|
59
|
+
**Auto-save:** Comments are saved as you work. Close the browser, come back later, resume where you left off.
|
|
60
|
+
|
|
61
|
+
Click "Submit Review" when done — structured feedback is sent back to the CLI.
|
|
62
|
+
|
|
63
|
+
## Terminal mode (default)
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
plan-review path/to/plan.md
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Interactive terminal UI with table of contents, section navigation, and inline commenting. Works over SSH, in CI, anywhere.
|
|
35
70
|
|
|
36
71
|
| Command | Action |
|
|
37
72
|
|---------|--------|
|
|
@@ -43,21 +78,32 @@ If `-o` is omitted, you'll be prompted to choose after the review. Output target
|
|
|
43
78
|
| *(enter)* | Skip section |
|
|
44
79
|
| *(any text)* | Add comment on current section |
|
|
45
80
|
|
|
46
|
-
##
|
|
81
|
+
## Options
|
|
47
82
|
|
|
48
|
-
|
|
83
|
+
```
|
|
84
|
+
-o, --output <target> Output target: stdout, clipboard, file, claude
|
|
85
|
+
--output-file <path> Custom output file path (with --output file)
|
|
86
|
+
--split-by <strategy> Force split strategy: heading, separator
|
|
87
|
+
--fresh Skip session resume, start clean review
|
|
88
|
+
--browser Open browser-based review UI
|
|
89
|
+
-V, --version Show version
|
|
90
|
+
-h, --help Show help
|
|
91
|
+
```
|
|
49
92
|
|
|
50
|
-
|
|
93
|
+
## The AI feedback loop
|
|
51
94
|
|
|
52
|
-
|
|
95
|
+
The real power is closing the loop between AI-generated plans and human review:
|
|
53
96
|
|
|
54
|
-
|
|
97
|
+
```
|
|
98
|
+
AI writes plan → You review with plan-review → Feedback pipes to Claude → AI revises
|
|
99
|
+
```
|
|
55
100
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
101
|
+
```bash
|
|
102
|
+
# Review in browser, send feedback straight to Claude
|
|
103
|
+
plan-review plan.md --browser -o claude
|
|
104
|
+
```
|
|
59
105
|
|
|
60
|
-
|
|
106
|
+
Your anchored, section-by-section comments become structured input the AI can act on — not a wall of text in a chat message.
|
|
61
107
|
|
|
62
108
|
## How it works
|
|
63
109
|
|
|
@@ -87,16 +133,12 @@ Review progress is auto-saved as you work. If you close the terminal or browser
|
|
|
87
133
|
|
|
88
134
|
Sessions are stored in `~/.plan-review/sessions/`.
|
|
89
135
|
|
|
90
|
-
### Commands
|
|
91
|
-
|
|
92
136
|
```
|
|
93
137
|
plan-review plan.md --fresh Skip session resume, start clean
|
|
94
138
|
plan-review sessions List all saved sessions
|
|
95
139
|
```
|
|
96
140
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
Delete files in `~/.plan-review/sessions/` to remove old sessions.
|
|
141
|
+
Manual cleanup: delete files in `~/.plan-review/sessions/`.
|
|
100
142
|
|
|
101
143
|
## License
|
|
102
144
|
|
package/dist/browser/index.html
CHANGED
|
@@ -297,6 +297,11 @@ body {
|
|
|
297
297
|
.line-inner ol { list-style: decimal; }
|
|
298
298
|
.line-inner blockquote { border-left: 3px solid var(--border); padding-left: 12px; color: var(--text-secondary); margin: 0; }
|
|
299
299
|
.line-inner h3, .line-inner h4 { font-size: 14px; margin: 4px 0; }
|
|
300
|
+
.line-inner table { width: 100%; border-collapse: collapse; margin: 4px 0; font-size: 13px; }
|
|
301
|
+
.line-inner th, .line-inner td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
|
|
302
|
+
.line-inner th { background: var(--bg-secondary); font-weight: 600; color: var(--text-primary); }
|
|
303
|
+
.line-inner td { color: var(--text-secondary); }
|
|
304
|
+
.line-inner tr:hover td { background: rgba(0, 173, 181, 0.05); }
|
|
300
305
|
|
|
301
306
|
.add-section-comment-link {
|
|
302
307
|
display: inline-block;
|
|
Binary file
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# User Authentication System — Implementation Plan
|
|
2
|
+
|
|
3
|
+
**Goal:** Add email/password authentication with session management to the web app.
|
|
4
|
+
|
|
5
|
+
**Architecture:** Express middleware + bcrypt + JWT tokens + PostgreSQL sessions table. Three milestones: database schema, auth endpoints, session management.
|
|
6
|
+
|
|
7
|
+
**Tech Stack:** Node.js, Express, PostgreSQL, bcrypt, jsonwebtoken
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Milestone 1: Database Foundation
|
|
12
|
+
|
|
13
|
+
### Task 1.1: Create users table
|
|
14
|
+
|
|
15
|
+
**Depends On:** (none)
|
|
16
|
+
**Blocks:** 1.2, 2.1, 2.2
|
|
17
|
+
**Related Files:** `src/db/migrations/001_users.sql`, `src/db/schema.ts`
|
|
18
|
+
**Verification:** `npm run migrate && npm test`
|
|
19
|
+
|
|
20
|
+
Create the users table with the following columns:
|
|
21
|
+
|
|
22
|
+
| Column | Type | Constraints |
|
|
23
|
+
|--------|------|-------------|
|
|
24
|
+
| id | UUID | PRIMARY KEY, DEFAULT gen_random_uuid() |
|
|
25
|
+
| email | VARCHAR(255) | UNIQUE, NOT NULL |
|
|
26
|
+
| password_hash | VARCHAR(255) | NOT NULL |
|
|
27
|
+
| created_at | TIMESTAMP | DEFAULT NOW() |
|
|
28
|
+
| updated_at | TIMESTAMP | DEFAULT NOW() |
|
|
29
|
+
|
|
30
|
+
Add an index on `email` for login lookups. The migration should be idempotent (use `IF NOT EXISTS`).
|
|
31
|
+
|
|
32
|
+
### Task 1.2: Create sessions table
|
|
33
|
+
|
|
34
|
+
**Depends On:** 1.1
|
|
35
|
+
**Blocks:** 3.1, 3.2
|
|
36
|
+
**Related Files:** `src/db/migrations/002_sessions.sql`, `src/db/schema.ts`
|
|
37
|
+
**Verification:** `npm run migrate && npm test`
|
|
38
|
+
|
|
39
|
+
Sessions table for server-side session tracking:
|
|
40
|
+
|
|
41
|
+
- `id` (UUID, primary key)
|
|
42
|
+
- `user_id` (UUID, foreign key → users.id, ON DELETE CASCADE)
|
|
43
|
+
- `token` (VARCHAR, unique, indexed)
|
|
44
|
+
- `expires_at` (TIMESTAMP, NOT NULL)
|
|
45
|
+
- `created_at` (TIMESTAMP, DEFAULT NOW())
|
|
46
|
+
|
|
47
|
+
Add a cleanup index on `expires_at` for the session pruning job.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Milestone 2: Authentication Endpoints
|
|
52
|
+
|
|
53
|
+
### Task 2.1: POST /auth/register
|
|
54
|
+
|
|
55
|
+
**Depends On:** 1.1
|
|
56
|
+
**Blocks:** 2.3
|
|
57
|
+
**Related Files:** `src/routes/auth.ts`, `src/services/user.ts`, `tests/auth.test.ts`
|
|
58
|
+
**Verification:** `npm test -- --grep "register"`
|
|
59
|
+
|
|
60
|
+
Accepts `{ email, password }`. Validates:
|
|
61
|
+
- Email format (basic regex, no need for RFC 5322 compliance)
|
|
62
|
+
- Password minimum 8 characters
|
|
63
|
+
- Email not already registered (unique constraint handles race conditions)
|
|
64
|
+
|
|
65
|
+
Hash password with bcrypt (cost factor 12). Return `201 { user: { id, email } }` on success, `400` with validation errors, `409` if email exists.
|
|
66
|
+
|
|
67
|
+
### Task 2.2: POST /auth/login
|
|
68
|
+
|
|
69
|
+
**Depends On:** 1.1
|
|
70
|
+
**Blocks:** 2.3
|
|
71
|
+
**Related Files:** `src/routes/auth.ts`, `src/services/auth.ts`, `tests/auth.test.ts`
|
|
72
|
+
**Verification:** `npm test -- --grep "login"`
|
|
73
|
+
|
|
74
|
+
Accepts `{ email, password }`. Compares against stored bcrypt hash.
|
|
75
|
+
|
|
76
|
+
On success: create a session (Task 3.1), return `200 { token, expiresAt }`.
|
|
77
|
+
On failure: return `401 { error: "Invalid credentials" }`. Do **not** reveal whether the email exists.
|
|
78
|
+
|
|
79
|
+
Rate limiting: 5 attempts per email per 15 minutes. Use a simple in-memory counter (Redis in v2).
|
|
80
|
+
|
|
81
|
+
### Task 2.3: Auth middleware
|
|
82
|
+
|
|
83
|
+
**Depends On:** 2.1, 2.2
|
|
84
|
+
**Blocks:** 3.2
|
|
85
|
+
**Related Files:** `src/middleware/auth.ts`, `tests/middleware.test.ts`
|
|
86
|
+
**Verification:** `npm test -- --grep "middleware"`
|
|
87
|
+
|
|
88
|
+
Express middleware that:
|
|
89
|
+
1. Extracts `Authorization: Bearer <token>` header
|
|
90
|
+
2. Looks up session by token
|
|
91
|
+
3. Checks `expires_at > NOW()`
|
|
92
|
+
4. Attaches `req.user = { id, email }` if valid
|
|
93
|
+
5. Returns `401` if missing/invalid/expired
|
|
94
|
+
|
|
95
|
+
Should be composable: `router.get('/profile', requireAuth, handler)`.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Milestone 3: Session Management
|
|
100
|
+
|
|
101
|
+
### Task 3.1: Session creation and token generation
|
|
102
|
+
|
|
103
|
+
**Depends On:** 1.2
|
|
104
|
+
**Blocks:** 3.2
|
|
105
|
+
**Related Files:** `src/services/session.ts`, `tests/session.test.ts`
|
|
106
|
+
**Verification:** `npm test -- --grep "session"`
|
|
107
|
+
|
|
108
|
+
Generate tokens using `crypto.randomBytes(32).toString('hex')` — not JWT for session tokens (JWTs can't be revoked without a blacklist, defeating the purpose of server-side sessions).
|
|
109
|
+
|
|
110
|
+
Default expiry: 7 days. Configurable via `SESSION_TTL_HOURS` env var.
|
|
111
|
+
|
|
112
|
+
### Task 3.2: Session cleanup and logout
|
|
113
|
+
|
|
114
|
+
**Depends On:** 1.2, 2.3
|
|
115
|
+
**Blocks:** (none)
|
|
116
|
+
**Related Files:** `src/services/session.ts`, `src/routes/auth.ts`, `tests/session.test.ts`
|
|
117
|
+
**Verification:** `npm test -- --grep "logout|cleanup"`
|
|
118
|
+
|
|
119
|
+
Two features:
|
|
120
|
+
|
|
121
|
+
**Logout endpoint** — `POST /auth/logout` (requires auth middleware). Deletes the current session row. Returns `204`.
|
|
122
|
+
|
|
123
|
+
**Cleanup job** — Runs every hour via `setInterval`. Deletes sessions where `expires_at < NOW()`. Log the count of pruned sessions.
|
|
124
|
+
|
|
125
|
+
```sql
|
|
126
|
+
DELETE FROM sessions WHERE expires_at < NOW();
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Consider: should logout invalidate all sessions for the user, or just the current one? Start with current-only. Add "logout everywhere" as a v2 feature.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plan-review",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Interactive CLI for reviewing AI-generated markdown plans",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
-
"skills"
|
|
12
|
+
"skills",
|
|
13
|
+
"examples"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
15
16
|
"build": "tsc && tsc --project tsconfig.browser.json --noEmit && node scripts/build-browser.js",
|