revspec 0.2.2 → 0.4.0
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/CLAUDE.md +10 -2
- package/README.md +86 -29
- package/bin/revspec.ts +2 -1
- package/docs/superpowers/plans/2026-03-15-ui-refactor.md +1025 -0
- package/package.json +1 -1
- package/scripts/install-skill.sh +20 -0
- package/scripts/release.sh +5 -6
- package/skills/revspec/SKILL.md +137 -0
- package/src/protocol/live-events.ts +3 -2
- package/src/tui/app.ts +198 -310
- package/src/tui/comment-input.ts +145 -144
- package/src/tui/confirm.ts +29 -43
- package/src/tui/help.ts +33 -57
- package/src/tui/pager.ts +162 -82
- package/src/tui/search.ts +6 -6
- package/src/tui/status-bar.ts +77 -34
- package/src/tui/thread-list.ts +28 -54
- package/src/tui/ui/dialog.ts +106 -0
- package/src/tui/ui/hint-bar.ts +20 -0
- package/src/tui/ui/keybinds.ts +104 -0
- package/src/tui/ui/markdown.ts +251 -0
- package/src/tui/ui/theme.ts +49 -0
- package/test/tui/ui/keybinds.test.ts +71 -0
- package/src/tui/theme.ts +0 -34
package/CLAUDE.md
CHANGED
|
@@ -4,16 +4,24 @@
|
|
|
4
4
|
- npm: `revspec` | GitHub: icyrainz/revspec
|
|
5
5
|
- Run: `bun run bin/revspec.ts <file.md>`
|
|
6
6
|
- Test: `bun test`
|
|
7
|
-
- Release: `./scripts/release.sh
|
|
7
|
+
- Release: `./scripts/release.sh` (version is set manually in package.json)
|
|
8
|
+
- Dev: `bun link` to symlink local build to global `revspec` command
|
|
8
9
|
|
|
9
10
|
## OpenTUI Gotchas
|
|
10
|
-
- Don't use StyledText
|
|
11
|
+
- Don't use StyledText at all — BigInt FFI crash happens even on small content
|
|
11
12
|
- Don't use ANSI escape codes in TextRenderable content (renders as literal text)
|
|
12
13
|
- MarkdownRenderable needs `syntaxStyle` + `conceal: true` for proper rendering
|
|
13
14
|
- Use `visible: false` to hide renderables, not removal/re-addition
|
|
15
|
+
- ScrollBox: don't use `stickyScroll` with manual scrolling (fights scroll position)
|
|
16
|
+
- ScrollBox: `scrollBy` overshoots silently on large deltas — use `scrollTo` with clamped position
|
|
17
|
+
- Textarea consumes Ctrl+D/U (emacs bindings) — blur textarea in normal mode for vim-style scroll
|
|
14
18
|
|
|
15
19
|
## Conventions
|
|
16
20
|
- Line mode is default, markdown mode via `m` toggle
|
|
17
21
|
- Tab to submit in all text inputs (works through tmux)
|
|
18
22
|
- Destructive actions need confirmation (dd double-tap, approve confirm dialog)
|
|
19
23
|
- All review actions auto-switch to line mode
|
|
24
|
+
- Thread popup uses vim-style normal/insert modes (blur textarea in normal)
|
|
25
|
+
- Hint bars use `[key] action` bracket format consistently
|
|
26
|
+
- No inline comment previews in pager — gutter indicators only (▌/█/✓)
|
|
27
|
+
- Live integration: JSONL for communication, `revspec watch`/`reply` CLI subcommands
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Revspec
|
|
2
2
|
|
|
3
|
-
A review tool for AI-generated spec documents
|
|
3
|
+
A review tool for AI-generated spec documents with real-time AI conversation. Comment on specific lines, get AI replies instantly, resolve discussions, and approve — all without leaving the terminal.
|
|
4
4
|
|
|
5
5
|
## Why
|
|
6
6
|
|
|
7
|
-
When an AI generates a spec, the human review step breaks the agentic loop. You have to open the file separately, read it, then type unstructured feedback
|
|
7
|
+
When an AI generates a spec, the human review step breaks the agentic loop. You have to open the file separately, read it, then type unstructured feedback. Revspec closes this loop with a TUI that lets you comment inline and discuss with the AI in real-time — like a chatroom anchored to the spec.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -27,67 +27,124 @@ cd revspec && bun install && bun link
|
|
|
27
27
|
revspec spec.md
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
Opens a TUI with
|
|
31
|
-
|
|
32
|
-
- **Markdown mode** (default) — rendered markdown for reading. `j/k` scrolls.
|
|
33
|
-
- **Line mode** (`m`) — line numbers + thread indicators for commenting.
|
|
30
|
+
Opens a TUI in line mode with vim-style navigation. Press `c` on any line to open a thread and start commenting.
|
|
34
31
|
|
|
35
32
|
### Keybindings
|
|
36
33
|
|
|
37
34
|
| Key | Action |
|
|
38
35
|
|-----|--------|
|
|
39
|
-
| `j/k` |
|
|
36
|
+
| `j/k` | Move cursor down/up |
|
|
40
37
|
| `gg` / `G` | Go to top / bottom |
|
|
41
38
|
| `Ctrl+D/U` | Half page down/up |
|
|
42
39
|
| `m` | Toggle markdown / line mode |
|
|
43
|
-
| `c` |
|
|
40
|
+
| `c` | Open thread / comment on line |
|
|
44
41
|
| `r` | Resolve thread (toggle) |
|
|
45
42
|
| `R` | Resolve all pending |
|
|
46
43
|
| `dd` | Delete draft comment (double-tap) |
|
|
47
44
|
| `/` | Search |
|
|
48
45
|
| `n/N` | Next/prev search match |
|
|
49
46
|
| `]t/[t` | Next/prev thread |
|
|
47
|
+
| `]r/[r` | Next/prev unread AI reply |
|
|
50
48
|
| `l` | List threads |
|
|
51
49
|
| `a` | Approve spec |
|
|
52
|
-
| `:w` |
|
|
53
|
-
| `:
|
|
54
|
-
| `:
|
|
55
|
-
| `:q!` | Quit without
|
|
50
|
+
| `:w` | Merge changes to review JSON |
|
|
51
|
+
| `:wq` | Merge and quit |
|
|
52
|
+
| `:q` | Quit (only if merged) |
|
|
53
|
+
| `:q!` | Quit without merging |
|
|
56
54
|
| `?` | Help |
|
|
57
55
|
|
|
58
|
-
###
|
|
56
|
+
### Thread popup
|
|
57
|
+
|
|
58
|
+
The thread popup has two modes:
|
|
59
|
+
|
|
60
|
+
- **Insert mode** — type your comment, `Tab` sends, `Esc` switches to normal mode
|
|
61
|
+
- **Normal mode** — `j/k` and `Ctrl+D/U` scroll the conversation history, `c` to reply, `r` to resolve, `Esc` to close
|
|
62
|
+
|
|
63
|
+
## Live AI Integration
|
|
64
|
+
|
|
65
|
+
Revspec supports real-time communication with AI coding tools (Claude Code, opencode, etc.) via two CLI subcommands:
|
|
66
|
+
|
|
67
|
+
### `revspec watch <file.md>`
|
|
68
|
+
|
|
69
|
+
Blocks until the reviewer adds comments, then returns them with spec context:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
=== New Comments ===
|
|
73
|
+
Thread: t1 (line 14)
|
|
74
|
+
Context:
|
|
75
|
+
12: The system uses polling...
|
|
76
|
+
> 14: it sends a notification via webhook.
|
|
77
|
+
16: resource state.
|
|
78
|
+
[reviewer]: this is unclear
|
|
79
|
+
|
|
80
|
+
To reply: revspec reply spec.md t1 "<your response>"
|
|
81
|
+
When done replying, run: revspec watch spec.md
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `revspec reply <file.md> <threadId> "<text>"`
|
|
85
|
+
|
|
86
|
+
Sends an AI reply that appears instantly in the reviewer's TUI:
|
|
59
87
|
|
|
60
|
-
|
|
88
|
+
```bash
|
|
89
|
+
revspec reply spec.md t1 "Good point. I'll clarify the polling vs webhook distinction."
|
|
90
|
+
```
|
|
61
91
|
|
|
62
|
-
|
|
92
|
+
### The loop
|
|
63
93
|
|
|
64
|
-
|
|
94
|
+
```
|
|
95
|
+
1. AI generates spec
|
|
96
|
+
2. AI launches: revspec spec.md (in tmux pane or separate terminal)
|
|
97
|
+
3. AI runs: revspec watch spec.md (blocks)
|
|
98
|
+
4. Reviewer comments on lines in the TUI
|
|
99
|
+
5. Watch returns with comments → AI replies → watch again
|
|
100
|
+
6. Reviewer resolves threads → approves
|
|
101
|
+
7. AI reads review JSON, rewrites spec, launches new round
|
|
102
|
+
8. Repeat until clean approval
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Claude Code skill
|
|
106
|
+
|
|
107
|
+
Install the `/revspec` skill for Claude Code:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
./scripts/install-skill.sh
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Then use `/revspec` in Claude Code after generating a spec.
|
|
114
|
+
|
|
115
|
+
## Protocol
|
|
116
|
+
|
|
117
|
+
Communication happens through a JSONL file (`spec.review.live.jsonl`) — append-only, both sides write to it. On session end, events are merged into `spec.review.json`.
|
|
118
|
+
|
|
119
|
+
### Event types
|
|
120
|
+
|
|
121
|
+
```jsonl
|
|
122
|
+
{"type":"comment","threadId":"t1","line":14,"author":"reviewer","text":"unclear","ts":1710400000}
|
|
123
|
+
{"type":"reply","threadId":"t1","author":"owner","text":"I'll fix it","ts":1710400005}
|
|
124
|
+
{"type":"resolve","threadId":"t1","author":"reviewer","ts":1710400010}
|
|
125
|
+
{"type":"approve","author":"reviewer","ts":1710400050}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Review JSON
|
|
65
129
|
|
|
66
130
|
```json
|
|
67
131
|
{
|
|
68
132
|
"file": "spec.md",
|
|
69
133
|
"threads": [
|
|
70
134
|
{
|
|
71
|
-
"id": "
|
|
72
|
-
"line":
|
|
73
|
-
"status": "
|
|
135
|
+
"id": "t1",
|
|
136
|
+
"line": 14,
|
|
137
|
+
"status": "resolved",
|
|
74
138
|
"messages": [
|
|
75
|
-
{ "author": "
|
|
139
|
+
{ "author": "reviewer", "text": "this is unclear", "ts": 1710400000 },
|
|
140
|
+
{ "author": "owner", "text": "I'll restructure this section", "ts": 1710400005 }
|
|
76
141
|
]
|
|
77
142
|
}
|
|
78
143
|
]
|
|
79
144
|
}
|
|
80
145
|
```
|
|
81
146
|
|
|
82
|
-
Thread statuses: `open` (
|
|
83
|
-
|
|
84
|
-
The AI reads this JSON, addresses comments, updates the spec, rewrites the review file with updated anchors/statuses, and re-invokes Revspec. The loop continues until the human approves.
|
|
85
|
-
|
|
86
|
-
## Roadmap
|
|
87
|
-
|
|
88
|
-
- **v1** (current): Built-in TUI pager
|
|
89
|
-
- **v2**: Neovim plugin, web UI, diff highlighting
|
|
90
|
-
- **v3**: Google Docs integration
|
|
147
|
+
Thread statuses: `open` (owner's turn), `pending` (reviewer's turn), `resolved`, `outdated`.
|
|
91
148
|
|
|
92
149
|
## License
|
|
93
150
|
|
package/bin/revspec.ts
CHANGED
|
@@ -66,7 +66,8 @@ const draftPath = join(specDir, `${specBase}.review.draft.json`);
|
|
|
66
66
|
|
|
67
67
|
// 3. Launch TUI (skip if REVSPEC_SKIP_TUI=1)
|
|
68
68
|
if (process.env.REVSPEC_SKIP_TUI !== "1") {
|
|
69
|
-
await
|
|
69
|
+
const pkg = await Bun.file(new URL("../package.json", import.meta.url)).json();
|
|
70
|
+
await runTui(specPath, reviewPath, draftPath, pkg.version);
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
// 4. After TUI exits, check if approved via JSONL
|