revspec 0.1.0__tar.gz
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.
- revspec-0.1.0/.gitignore +10 -0
- revspec-0.1.0/CLAUDE.md +202 -0
- revspec-0.1.0/PKG-INFO +52 -0
- revspec-0.1.0/README.md +34 -0
- revspec-0.1.0/docs/superpowers/plans/2026-03-16-full-parity-plan.md +2332 -0
- revspec-0.1.0/docs/superpowers/specs/2026-03-16-full-parity-design.md +380 -0
- revspec-0.1.0/pyproject.toml +33 -0
- revspec-0.1.0/revspec/__init__.py +0 -0
- revspec-0.1.0/revspec/app.py +1804 -0
- revspec-0.1.0/revspec/cli.py +57 -0
- revspec-0.1.0/revspec/comment_screen.py +280 -0
- revspec-0.1.0/revspec/markdown.py +239 -0
- revspec-0.1.0/revspec/protocol.py +172 -0
- revspec-0.1.0/revspec/reply.py +40 -0
- revspec-0.1.0/revspec/state.py +184 -0
- revspec-0.1.0/revspec/theme.py +27 -0
- revspec-0.1.0/revspec/watch.py +299 -0
- revspec-0.1.0/tests/__init__.py +0 -0
- revspec-0.1.0/tests/test_markdown.py +248 -0
- revspec-0.1.0/tests/test_protocol.py +343 -0
- revspec-0.1.0/tests/test_reply.py +97 -0
- revspec-0.1.0/tests/test_state.py +463 -0
- revspec-0.1.0/tests/test_watch.py +160 -0
- revspec-0.1.0/uv.lock +130 -0
revspec-0.1.0/.gitignore
ADDED
revspec-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Revspec (Python)
|
|
2
|
+
|
|
3
|
+
Python/Textual port of [revspec](https://github.com/icyrainz/revspec) — the TypeScript/Bun original.
|
|
4
|
+
|
|
5
|
+
## CRITICAL: Full Feature Parity Required
|
|
6
|
+
|
|
7
|
+
This is a 1:1 port of the Bun version. Every feature, keybinding, behavior, and UI detail in the TypeScript version MUST be replicated exactly. When in doubt, clone the original repo and read the source — it is the spec. Do not invent new behavior, skip features, or simplify interactions. The goal is that a user switching between the Bun and Python versions notices zero difference in functionality.
|
|
8
|
+
|
|
9
|
+
The original repo is at: `https://github.com/icyrainz/revspec`
|
|
10
|
+
|
|
11
|
+
**Before implementing any feature, read the corresponding TypeScript source file to understand the exact behavior.** The reference files section below maps Python modules to their TypeScript counterparts.
|
|
12
|
+
|
|
13
|
+
## Why this exists
|
|
14
|
+
|
|
15
|
+
The original revspec depends on Bun (via OpenTUI's bun:ffi bindings to Zig). Some environments block Bun executables, including standalone compiled binaries. This Python port uses Textual for the TUI layer, requiring only Python (which is universally available).
|
|
16
|
+
|
|
17
|
+
## Tech stack
|
|
18
|
+
|
|
19
|
+
- **Python 3.11+** — no native dependencies
|
|
20
|
+
- **Textual** — TUI framework (pip install, pure Python)
|
|
21
|
+
- **Rich** — terminal rendering (Textual dependency)
|
|
22
|
+
- Package: `revspec` on PyPI
|
|
23
|
+
- Install: `pipx install revspec` or `pip install revspec`
|
|
24
|
+
- Run: `revspec <file.md>`
|
|
25
|
+
- Dev: `uv venv && uv pip install hatchling editables && uv pip install -e . --no-build-isolation`
|
|
26
|
+
|
|
27
|
+
## Architecture
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
revspec/
|
|
31
|
+
cli.py # Entry point, arg parsing, subcommand routing
|
|
32
|
+
app.py # Main Textual App — ScrollView pager, overlays, key handling
|
|
33
|
+
state.py # ReviewState — cursor, threads, navigation
|
|
34
|
+
protocol.py # JSONL live event protocol (read/write/replay)
|
|
35
|
+
theme.py # Catppuccin Mocha color scheme
|
|
36
|
+
comment_screen.py # Thread popup with vim normal/insert modes
|
|
37
|
+
markdown.py # Table parsing, rendering, word-wrap helpers
|
|
38
|
+
watch.py # CLI watch subcommand (AI event monitor)
|
|
39
|
+
reply.py # CLI reply subcommand (AI reply writer)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Pager architecture
|
|
43
|
+
|
|
44
|
+
`SpecPager` extends Textual's `ScrollView` using the Line API:
|
|
45
|
+
- `rebuild_visual_model()` builds a list of visual rows: `("spec", idx)`, `("spec_wrap", idx, seg)`, `("table_border", idx, pos)`
|
|
46
|
+
- `render_line(y)` renders a single visual row on demand — Textual's compositor calls this for each visible screen line
|
|
47
|
+
- `virtual_size` tells ScrollView the total content height
|
|
48
|
+
- Scrolling is native to ScrollView — no manual viewport math needed
|
|
49
|
+
|
|
50
|
+
## JSONL Protocol
|
|
51
|
+
|
|
52
|
+
The JSONL protocol is **identical** to the TypeScript version. Both implementations read/write the same `spec.review.jsonl` format, so the AI integration (`revspec watch` / `revspec reply`) works with either TUI.
|
|
53
|
+
|
|
54
|
+
Event types: `comment`, `reply`, `resolve`, `unresolve`, `approve`, `delete`, `submit`, `session-end`, `round`
|
|
55
|
+
|
|
56
|
+
Each event is a single JSON line with `type`, `author`, `ts` fields, plus type-specific fields (`threadId`, `line`, `text`).
|
|
57
|
+
|
|
58
|
+
## Current state
|
|
59
|
+
|
|
60
|
+
### Implemented (full parity achieved)
|
|
61
|
+
- ScrollView pager with Line API virtual scrolling, cursor prefix `>`, gutter indicators (`█` for all states, color-coded)
|
|
62
|
+
- Markdown syntax highlighting (h1-h3 color-coded: blue/blue/mauve, code blocks green, blockquotes with │ prefix, list bullets with •, horizontal rules)
|
|
63
|
+
- Inline markdown rendering (bold, italic, code, links, strikethrough) via parse_inline_markdown()
|
|
64
|
+
- Vim-style navigation: j/k, Ctrl+D/U, gg/G, H/M/L, zz
|
|
65
|
+
- Multi-key sequences: dd, ]t/[t, ]r/[r, ]1/[1, '', gg, zz
|
|
66
|
+
- Jump list: Ctrl+O/Ctrl+I/Tab forward/backward, '' swap
|
|
67
|
+
- Comment input modal (c key) with vim normal/insert modes, timestamps, title update on new thread, border title, colored message pipes, resolve stays open
|
|
68
|
+
- Thread list modal (t key) with sort/filter, wrap-around navigation, empty state
|
|
69
|
+
- Search modal (/ key) with n/N cycling, smartcase, incremental preview (3+ chars), red "No match"
|
|
70
|
+
- Command mode (:q, :q!, :wrap, :{line} with clamping)
|
|
71
|
+
- Confirm dialogs (mauve border, y/Enter confirm, q/Esc cancel)
|
|
72
|
+
- Help screen (? key) with j/k/gg/G/Ctrl+D/U scrolling
|
|
73
|
+
- Spinner modal on submit (80ms animation, Ctrl+C cancel, 120s wall-clock timeout)
|
|
74
|
+
- JSONL protocol: read, write, replay — fully compatible with TypeScript version
|
|
75
|
+
- Resolve/unresolve threads (r key), resolve all pending (R)
|
|
76
|
+
- Approve (A) and Submit (S) with spinner + spec reload polling
|
|
77
|
+
- Status bars: top (file, thread counts, unread, mutation guard, position, breadcrumb) and bottom (thread preview, position, context-sensitive hints with Rich Text styling)
|
|
78
|
+
- Transparent pager background (THEME["base"] = None, inherits terminal bg)
|
|
79
|
+
- Pending key hint in bottom bar (e.g. `g...`, `]...`) with 300ms timeout
|
|
80
|
+
- Transient messages with icon support (info/warn/success), bottom bar guard against overwrites
|
|
81
|
+
- Unread indicators (yellow gutter block)
|
|
82
|
+
- Spec mutation guard (external modification warning in top bar)
|
|
83
|
+
- Live watcher integration (AI reply push into open CommentScreen, flash suppression, offset advance, restart on reload)
|
|
84
|
+
- Markdown-aware table rendering with box-drawing characters
|
|
85
|
+
- Code-block-aware rendering with precomputed state map
|
|
86
|
+
- Line wrapping (:wrap toggle with continuation rows in visual model)
|
|
87
|
+
- Watch CLI subcommand with crash recovery, JSONL truncation guard, lock management
|
|
88
|
+
- Reply CLI subcommand with thread validation, shell escape cleanup
|
|
89
|
+
- All overlay screens use event.stop() to prevent key leaking to main app
|
|
90
|
+
- Welcome hint on first launch (8s)
|
|
91
|
+
- Tests: 157 total (state, protocol, markdown, watch, reply)
|
|
92
|
+
|
|
93
|
+
### Known issues / remaining work
|
|
94
|
+
- **Inline markdown in table cells** — table cell contents are rendered as plain text; `parse_inline_markdown()` is not applied inside `render_table_row()`
|
|
95
|
+
|
|
96
|
+
## Complete keybinding reference (must match exactly)
|
|
97
|
+
|
|
98
|
+
### Normal mode
|
|
99
|
+
| Key | Action | TS Reference |
|
|
100
|
+
|-----|--------|-------------|
|
|
101
|
+
| j / down | Cursor down | app.ts:623 |
|
|
102
|
+
| k / up | Cursor up | app.ts:630 |
|
|
103
|
+
| Ctrl+D | Half-page down | app.ts:637 |
|
|
104
|
+
| Ctrl+U | Half-page up | app.ts:645 |
|
|
105
|
+
| G | Go to bottom | app.ts:651 |
|
|
106
|
+
| gg | Go to top | app.ts:657 |
|
|
107
|
+
| H | Screen top | app.ts:925 |
|
|
108
|
+
| M | Screen middle | app.ts:932 |
|
|
109
|
+
| L | Screen bottom | app.ts:938 |
|
|
110
|
+
| zz | Center cursor | app.ts:663 |
|
|
111
|
+
| n | Search next | app.ts:671 |
|
|
112
|
+
| N | Search prev | app.ts:690 |
|
|
113
|
+
| c | Comment/reply on current line | app.ts:709 |
|
|
114
|
+
| t | Thread list | app.ts:712 |
|
|
115
|
+
| r | Resolve/reopen thread | app.ts:715 |
|
|
116
|
+
| R | Resolve all pending | app.ts:731 |
|
|
117
|
+
| dd | Delete thread (with confirm) | app.ts:746 |
|
|
118
|
+
| S | Submit for rewrite | app.ts:770 |
|
|
119
|
+
| A | Approve (exit) | app.ts:822 |
|
|
120
|
+
| ]t | Next thread | app.ts:827 |
|
|
121
|
+
| [t | Previous thread | app.ts:843 |
|
|
122
|
+
| ]r | Next unread thread | app.ts:855 |
|
|
123
|
+
| [r | Previous unread thread | app.ts:866 |
|
|
124
|
+
| ]1 / [1 | Next/prev h1 heading | app.ts:879 |
|
|
125
|
+
| ]2 / [2 | Next/prev h2 heading | app.ts:879 |
|
|
126
|
+
| ]3 / [3 | Next/prev h3 heading | app.ts:879 |
|
|
127
|
+
| '' | Jump back (swap positions) | app.ts:909 |
|
|
128
|
+
| Ctrl+O | Jump list backward | app.ts:569 |
|
|
129
|
+
| Ctrl+I / Tab | Jump list forward | app.ts:590 |
|
|
130
|
+
| / | Open search | app.ts:948 |
|
|
131
|
+
| : | Command mode | app.ts:951 |
|
|
132
|
+
| ? | Help screen | app.ts:946 |
|
|
133
|
+
| Escape | Clear search highlights | app.ts:601 |
|
|
134
|
+
| Ctrl+C | Exit (session-end) | app.ts:563 |
|
|
135
|
+
|
|
136
|
+
### Command mode
|
|
137
|
+
| Command | Action |
|
|
138
|
+
|---------|--------|
|
|
139
|
+
| :q | Quit (warns if unresolved) |
|
|
140
|
+
| :q! | Force quit |
|
|
141
|
+
| :qa, :wq, etc. | All quit variants supported |
|
|
142
|
+
| :wrap | Toggle line wrapping |
|
|
143
|
+
| :{N} | Jump to line number (clamps to range, rejects <=0) |
|
|
144
|
+
|
|
145
|
+
### Overlay keys
|
|
146
|
+
| Context | Key | Action |
|
|
147
|
+
|---------|-----|--------|
|
|
148
|
+
| Any overlay | Ctrl+C | Force dismiss |
|
|
149
|
+
| Comment popup | Tab | Submit comment |
|
|
150
|
+
| Comment popup | Esc | Cancel/dismiss |
|
|
151
|
+
| Comment popup | i/c | Enter insert mode |
|
|
152
|
+
| Comment popup | Escape (in insert) | Return to normal mode |
|
|
153
|
+
| Thread list | j/k | Navigate (wraps around) |
|
|
154
|
+
| Thread list | Enter | Go to thread |
|
|
155
|
+
| Thread list | Ctrl+F | Cycle filter (all/active/resolved) |
|
|
156
|
+
| Thread list | Esc | Dismiss |
|
|
157
|
+
| Search | Enter | Accept match |
|
|
158
|
+
| Search | Esc | Cancel |
|
|
159
|
+
| Confirm | y/Enter | Confirm |
|
|
160
|
+
| Confirm | q/Esc | Cancel |
|
|
161
|
+
|
|
162
|
+
## Conventions (must match the TypeScript version exactly)
|
|
163
|
+
|
|
164
|
+
- Tab to submit in all text inputs (works through tmux)
|
|
165
|
+
- Destructive actions need confirmation (dd double-tap, approve confirm dialog)
|
|
166
|
+
- Thread popup uses vim-style normal/insert modes (blur textarea in normal)
|
|
167
|
+
- Hint bars use `[key] action` bracket format — all labels defined in keymap
|
|
168
|
+
- Consistent dismiss/confirm keys: `y/Enter` to confirm, `q/Esc` to dismiss (all popups)
|
|
169
|
+
- No inline comment previews in pager — gutter indicators only: █ for all states (white=open, yellow=unread, green=resolved)
|
|
170
|
+
- Thread IDs use nanoid (8-char alphanumeric) — no sequential t1/t2
|
|
171
|
+
- No review JSON — JSONL is the single source of truth
|
|
172
|
+
- `submit` events in JSONL act as round delimiters
|
|
173
|
+
- S submits for rewrite (stays in TUI), A approves (exits)
|
|
174
|
+
- `:q` warns if unresolved threads, `:q!` force quits
|
|
175
|
+
- Search is smartcase (case-sensitive only if query contains uppercase)
|
|
176
|
+
- Search wraps around with notification ("Search wrapped to top/bottom")
|
|
177
|
+
- Thread navigation wraps around with notification ("Wrapped to first/last thread")
|
|
178
|
+
|
|
179
|
+
## Reference: TypeScript source → Python module mapping
|
|
180
|
+
|
|
181
|
+
| Feature | TypeScript source | Python module |
|
|
182
|
+
|---------|-------------------|---------------|
|
|
183
|
+
| Main TUI + keybindings | `src/tui/app.ts` | `revspec/app.py` |
|
|
184
|
+
| Review state | `src/state/review-state.ts` | `revspec/state.py` |
|
|
185
|
+
| JSONL protocol | `src/protocol/live-events.ts` | `revspec/protocol.py` |
|
|
186
|
+
| Protocol types | `src/protocol/types.ts` | `revspec/protocol.py` |
|
|
187
|
+
| Theme/colors | `src/tui/ui/theme.ts` | `revspec/theme.py` |
|
|
188
|
+
| Pager rendering | `src/tui/pager.ts` | `revspec/app.py` (SpecPager ScrollView) |
|
|
189
|
+
| Comment input | `src/tui/comment-input.ts` | `revspec/comment_screen.py` |
|
|
190
|
+
| Search overlay | `src/tui/search.ts` | `revspec/app.py` (SearchScreen class) |
|
|
191
|
+
| Thread list | `src/tui/thread-list.ts` | `revspec/app.py` (ThreadListScreen class) |
|
|
192
|
+
| Confirm dialog | `src/tui/confirm.ts` | `revspec/app.py` (ConfirmScreen class) |
|
|
193
|
+
| Help screen | `src/tui/help.ts` | `revspec/app.py` (HelpScreen class) |
|
|
194
|
+
| Spinner | `src/tui/spinner.ts` | `revspec/app.py` (SpinnerScreen class) |
|
|
195
|
+
| Status bars | `src/tui/status-bar.ts` | `revspec/app.py` (top/bottom bar methods) |
|
|
196
|
+
| Keybind registry | `src/tui/ui/keybinds.ts` | `revspec/app.py` (inline) |
|
|
197
|
+
| Markdown rendering | `src/tui/ui/markdown.ts` | `revspec/markdown.py` + `app.py` (_line_style) |
|
|
198
|
+
| Hint bar | `src/tui/ui/hint-bar.ts` | `revspec/app.py` (inline) |
|
|
199
|
+
| Live watcher | `src/tui/live-watcher.ts` | `revspec/app.py` (_check_live_events) |
|
|
200
|
+
| CLI watch | `src/cli/watch.ts` | `revspec/watch.py` |
|
|
201
|
+
| CLI reply | `src/cli/reply.ts` | `revspec/reply.py` |
|
|
202
|
+
| CLI entry | `bin/revspec.ts` | `revspec/cli.py` |
|
revspec-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: revspec
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Terminal-based spec review tool with real-time AI conversation
|
|
5
|
+
Project-URL: Homepage, https://github.com/icyrainz/revspec-py
|
|
6
|
+
Project-URL: Repository, https://github.com/icyrainz/revspec-py
|
|
7
|
+
Author: icyrainz
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Keywords: ai,claude,review,spec,terminal,tui,vim
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Requires-Dist: textual>=1.0.0
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# revspec (Python)
|
|
20
|
+
|
|
21
|
+
A terminal-based spec review tool with real-time AI conversation. Python implementation of [revspec](https://github.com/icyrainz/revspec).
|
|
22
|
+
|
|
23
|
+
This is a pure-Python alternative for environments where the original Bun-based executable is unavailable. Both versions share the same JSONL protocol and are fully interchangeable.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pipx install revspec
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Or with pip:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install revspec
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Requires Python 3.11+.
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Interactive review
|
|
43
|
+
revspec spec.md
|
|
44
|
+
|
|
45
|
+
# AI integration (used by the /revspec Claude Code skill)
|
|
46
|
+
revspec watch spec.md
|
|
47
|
+
revspec reply spec.md <threadId> "<text>"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Claude Code integration
|
|
51
|
+
|
|
52
|
+
See the [original revspec repo](https://github.com/icyrainz/revspec) for the `/revspec` skill and Claude Code setup instructions. The skill works with either the Bun or Python version — whichever `revspec` is on your PATH.
|
revspec-0.1.0/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# revspec (Python)
|
|
2
|
+
|
|
3
|
+
A terminal-based spec review tool with real-time AI conversation. Python implementation of [revspec](https://github.com/icyrainz/revspec).
|
|
4
|
+
|
|
5
|
+
This is a pure-Python alternative for environments where the original Bun-based executable is unavailable. Both versions share the same JSONL protocol and are fully interchangeable.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pipx install revspec
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or with pip:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install revspec
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Requires Python 3.11+.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Interactive review
|
|
25
|
+
revspec spec.md
|
|
26
|
+
|
|
27
|
+
# AI integration (used by the /revspec Claude Code skill)
|
|
28
|
+
revspec watch spec.md
|
|
29
|
+
revspec reply spec.md <threadId> "<text>"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Claude Code integration
|
|
33
|
+
|
|
34
|
+
See the [original revspec repo](https://github.com/icyrainz/revspec) for the `/revspec` skill and Claude Code setup instructions. The skill works with either the Bun or Python version — whichever `revspec` is on your PATH.
|