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.
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .venv/
7
+ *.egg
8
+ .mypy_cache/
9
+ .pytest_cache/
10
+ *.review.jsonl
@@ -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.
@@ -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.