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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revspec",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "revspec": "./bin/revspec.ts"
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Install/sync the revspec Claude Code skill to ~/.claude/skills/revspec/
5
+ # Run this after cloning the repo or pulling updates.
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ REPO_SKILL="$SCRIPT_DIR/../skills/revspec"
9
+ LOCAL_SKILL="$HOME/.claude/skills/revspec"
10
+
11
+ if [ ! -f "$REPO_SKILL/SKILL.md" ]; then
12
+ echo "Error: skill not found at $REPO_SKILL/SKILL.md"
13
+ exit 1
14
+ fi
15
+
16
+ mkdir -p "$LOCAL_SKILL"
17
+ cp "$REPO_SKILL/SKILL.md" "$LOCAL_SKILL/SKILL.md"
18
+
19
+ echo "Installed revspec skill to $LOCAL_SKILL"
20
+ echo "Use /revspec in Claude Code to launch spec reviews."
@@ -34,18 +34,17 @@ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
34
34
  exit 0
35
35
  fi
36
36
 
37
- # Tag if not already tagged
38
- if ! git tag -l "v$VERSION" | grep -q .; then
39
- git tag "v$VERSION"
40
- fi
37
+ # Tag current commit (force-update if tag exists)
38
+ git tag -f "v$VERSION"
41
39
 
42
40
  # Publish to npm
43
41
  echo ""
44
42
  echo "Publishing to npm..."
45
43
  npm publish
46
44
 
47
- # Push
48
- git push && git push origin "v$VERSION"
45
+ # Push commit and tag (force-update remote tag if it exists)
46
+ git push
47
+ git push origin "v$VERSION" --force
49
48
 
50
49
  echo ""
51
50
  echo "Released v$VERSION"
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: revspec
3
+ description: Launch revspec to review a spec document with real-time AI feedback. Use when the user says /revspec, "review the spec", "let me review this", or after generating a spec/design document that needs human review. Also use when a brainstorming or writing-plans skill produces a markdown spec file.
4
+ ---
5
+
6
+ # Revspec — Live Spec Review
7
+
8
+ Launch revspec to let the human review a spec document with real-time AI conversation. The reviewer comments on specific lines, you reply instantly, and the discussion continues until the spec is approved.
9
+
10
+ ## When to Use
11
+
12
+ - After writing or updating a spec/design document
13
+ - When the user explicitly asks to review a spec
14
+ - After the brainstorming or writing-plans skill produces a `.md` file
15
+
16
+ ## How It Works
17
+
18
+ You and the human communicate through revspec's CLI:
19
+ - `revspec watch <file.md>` — blocks until the reviewer adds comments, then returns them
20
+ - `revspec reply <file.md> <threadId> "<text>"` — sends your reply (appears in the TUI instantly)
21
+
22
+ The reviewer stays in the revspec TUI for the entire session. You run the watch/reply loop.
23
+
24
+ ## Step 1: Find the Spec File
25
+
26
+ Detect which spec was recently created or modified in this conversation. Look for:
27
+ - Files written to `docs/superpowers/specs/*.md`
28
+ - The last `.md` file you created or edited
29
+ - If ambiguous, ask the user which file to review
30
+
31
+ ## Step 2: Launch Revspec
32
+
33
+ Check if running inside tmux:
34
+
35
+ ```bash
36
+ echo $TMUX
37
+ ```
38
+
39
+ **If tmux is available:**
40
+ ```bash
41
+ tmux split-window -v "revspec <spec-file>"
42
+ ```
43
+
44
+ **If no tmux:**
45
+ Tell the user: "Please run in another terminal: `revspec <spec-file>`"
46
+
47
+ ## Step 3: Run the Watch/Reply Loop
48
+
49
+ Start watching for reviewer comments:
50
+
51
+ ```bash
52
+ revspec watch <spec-file>
53
+ ```
54
+
55
+ This blocks until the reviewer adds comments. When it returns, you'll see output like:
56
+
57
+ ```
58
+ --- New threads ---
59
+
60
+ [t1] line 14 (new):
61
+ Context:
62
+ 12: The system uses polling...
63
+ >14: it sends a notification via webhook.
64
+ 16: resource state.
65
+ Comment: "this is unclear"
66
+
67
+ To reply: revspec reply spec.md <threadId> "<your response>"
68
+ When done replying, run: revspec watch spec.md
69
+ ```
70
+
71
+ **For each comment:** Read the context, understand the concern, and reply thoughtfully:
72
+
73
+ ```bash
74
+ revspec reply <spec-file> t1 "Good point. I'll clarify — it uses polling to detect changes, then sends a webhook notification to downstream services."
75
+ ```
76
+
77
+ After replying to all comments, run `revspec watch` again to wait for the next batch.
78
+
79
+ **If watch returns "Session ended. Reviewer exited revspec."** — the reviewer closed the TUI. Check the review JSON for resolved threads that require spec changes (see Step 4). If no resolved threads, stop and wait — the user can invoke `/revspec` again later to resume.
80
+
81
+ **Important:** Your replies should be substantive — address the concern, explain your reasoning, or acknowledge the change you'll make. Don't just say "noted" or "will fix."
82
+
83
+ ## Step 4: Handle Session End or Approval
84
+
85
+ The watch loop ends in one of two ways:
86
+
87
+ ### Session ended (reviewer exited with `:q`)
88
+
89
+ Read the review JSON and check for **resolved threads**. Resolved = the reviewer acknowledged your reply and wants you to make that change.
90
+
91
+ **If resolved threads with actionable feedback exist:**
92
+ 1. Rewrite the spec incorporating the feedback from resolved threads
93
+ 2. Commit the updated spec
94
+ 3. Append a round marker to the JSONL:
95
+ ```bash
96
+ echo '{"type":"round","author":"owner","round":2,"ts":'$(date +%s000)'}' >> <spec-file>.review.live.jsonl
97
+ ```
98
+ 4. Launch a new revspec session (go back to Step 2) so the reviewer can verify the changes
99
+
100
+ **If no resolved threads (or only open/pending threads):**
101
+ The reviewer left without resolving anything — stop and wait. The user can invoke `/revspec` again later.
102
+
103
+ ### Approved (reviewer pressed `a`)
104
+
105
+ Watch returns:
106
+ ```
107
+ Review approved.
108
+ Review file: <path-to-review.json>
109
+ ```
110
+
111
+ The spec is finalized. Report: "Spec approved and finalized at `<spec-file>`. Ready to proceed with implementation."
112
+
113
+ ## Thread Status Meanings
114
+
115
+ - **Open** — under discussion, AI replied, reviewer hasn't responded yet
116
+ - **Pending** — owner replied, waiting for reviewer to read
117
+ - **Resolved** — reviewer acknowledged the plan, AI should make the change
118
+ - **Approve** — spec is final, proceed to implementation
119
+
120
+ ## Loop Summary
121
+
122
+ ```
123
+ 1. Launch revspec on spec file
124
+ 2. Watch for comments
125
+ 3. Reply to each comment
126
+ 4. Watch again (repeat 2-3 until session-end or approval)
127
+ 5. On session-end: check for resolved threads
128
+ 6. If resolved threads need spec changes: rewrite spec, launch new round (go to 1)
129
+ 7. On approval: spec is finalized, done
130
+ ```
131
+
132
+ ## Tips
133
+
134
+ - Read the full thread history in the watch output before replying — the reviewer may have added context across multiple messages
135
+ - When rewriting the spec after approval, address every resolved thread — the reviewer trusted you to incorporate their feedback
136
+ - Keep replies concise but complete — the reviewer can see them instantly and will follow up if needed
137
+ - If a comment is about a section you're unsure about, say so honestly — "I'm not sure about the best approach here. Options are X or Y — which do you prefer?"
@@ -29,6 +29,7 @@ const VALID_LIVE_EVENT_TYPES: readonly LiveEventType[] = [
29
29
  "approve",
30
30
  "delete",
31
31
  "round",
32
+ "session-end",
32
33
  ];
33
34
 
34
35
  export function isValidLiveEvent(value: unknown): value is LiveEvent {
@@ -47,8 +48,8 @@ export function isValidLiveEvent(value: unknown): value is LiveEvent {
47
48
  if (typeof v.ts !== "number") return false;
48
49
  if (typeof v.author !== "string") return false;
49
50
 
50
- // threadId required for all except approve and round
51
- if (v.type !== "approve" && v.type !== "round") {
51
+ // threadId required for all except approve, round, and session-end
52
+ if (v.type !== "approve" && v.type !== "round" && v.type !== "session-end") {
52
53
  if (typeof v.threadId !== "string") return false;
53
54
  }
54
55