chamba 0.7.0 → 0.8.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/LICENSE +53 -14
- package/README.md +28 -8
- package/dist/commands/advanced.js +7 -278
- package/dist/commands/dev.js +11 -612
- package/dist/commands/doctor.js +1 -29
- package/dist/commands/menu.js +1 -80
- package/dist/commands/onboard.js +6 -230
- package/dist/commands/settings.js +15 -349
- package/dist/lib/agent-commands.js +2 -0
- package/dist/lib/agent-context.js +6 -210
- package/dist/lib/browser.js +1 -40
- package/dist/lib/chamba-yaml.js +10 -191
- package/dist/lib/constants.js +1 -125
- package/dist/lib/dockerfile-builder.js +41 -261
- package/dist/lib/env.js +2 -78
- package/dist/lib/git-env.js +1 -21
- package/dist/lib/global-config.js +4 -66
- package/dist/lib/pnpm-store.js +1 -19
- package/dist/lib/ports.js +1 -210
- package/dist/lib/safe-rm.js +1 -36
- package/dist/lib/sessions.js +2 -34
- package/dist/lib/shadows.js +1 -176
- package/dist/lib/skills.js +2 -0
- package/dist/lib/templates.js +1 -0
- package/dist/lib/webterm.js +1 -305
- package/dist/lib/workspace-identity.js +4 -260
- package/package.json +4 -4
- package/templates/Dockerfile +12 -19
- package/templates/claude-statusline.sh +5 -7
- package/templates/context/baseline.md +2 -0
- package/templates/pane-apps/client/assets/c-BNa-DeUl.json +3552 -0
- package/templates/pane-apps/client/assets/cpp-B-T4NRoH.json +20239 -0
- package/templates/pane-apps/client/assets/csharp-BbxHChhA.json +6010 -0
- package/templates/pane-apps/client/assets/css-CWCxuwmz.json +1860 -0
- package/templates/pane-apps/client/assets/diff-B-2N89g8.json +154 -0
- package/templates/pane-apps/client/assets/docker-DWTvYW26.json +103 -0
- package/templates/pane-apps/client/assets/files-D0nJgFAA.js +12 -0
- package/templates/pane-apps/client/assets/files-h0K1vZyQ.css +1 -0
- package/templates/pane-apps/client/assets/go-B2hyYeNg.json +3156 -0
- package/templates/pane-apps/client/assets/graphql-Z6Id2aNO.json +1292 -0
- package/templates/pane-apps/client/assets/html-BtzvlIfu.json +2627 -0
- package/templates/pane-apps/client/assets/ini-Bn3Twap1.json +108 -0
- package/templates/pane-apps/client/assets/java-C7t2dwLO.json +1885 -0
- package/templates/pane-apps/client/assets/javascript-DuC2v0C0.json +5996 -0
- package/templates/pane-apps/client/assets/json-CwdkWeV5.json +206 -0
- package/templates/pane-apps/client/assets/jsonc-MYWDbTU3.json +206 -0
- package/templates/pane-apps/client/assets/jsx-Cn8EZuIC.json +5996 -0
- package/templates/pane-apps/client/assets/kotlin-CFNOz1gw.json +580 -0
- package/templates/pane-apps/client/assets/make-BVnlFCcl.json +629 -0
- package/templates/pane-apps/client/assets/markdown-B4Xk2WM_.json +3263 -0
- package/templates/pane-apps/client/assets/php-CAQzQmmI.json +4188 -0
- package/templates/pane-apps/client/assets/python-CYQee8m4.json +4174 -0
- package/templates/pane-apps/client/assets/reviews-BsoGZ35r.css +1 -0
- package/templates/pane-apps/client/assets/reviews-iW0Mbn4e.js +153 -0
- package/templates/pane-apps/client/assets/ruby-D7R58tus.json +3114 -0
- package/templates/pane-apps/client/assets/rust-BFBbFiei.json +1103 -0
- package/templates/pane-apps/client/assets/scss-TQRhBkPG.json +1874 -0
- package/templates/pane-apps/client/assets/shellscript-DieAkC4W.json +2375 -0
- package/templates/pane-apps/client/assets/specs-D9z3neR-.js +13 -0
- package/templates/pane-apps/client/assets/sql-Bxd030LV.json +634 -0
- package/templates/pane-apps/client/assets/toml-ChrKGzsV.json +430 -0
- package/templates/pane-apps/client/assets/tsx-D2e90MFw.json +5996 -0
- package/templates/pane-apps/client/assets/typescript-DonXQ_n1.json +5747 -0
- package/templates/pane-apps/client/assets/xml-B17r2RXF.json +382 -0
- package/templates/pane-apps/client/assets/yaml-CKn4h1zy.json +627 -0
- package/templates/pane-apps/client/reviews/index.html +15 -0
- package/templates/pane-apps/client/specs/index.html +3 -2
- package/templates/pane-apps/server/reviews.mjs +20 -0
- package/templates/pane-apps/server/specs.mjs +5 -1588
- package/templates/skills/chamba-statusline/SKILL.md +7 -19
- package/templates/skills/dx-review/SKILL.md +123 -0
- package/templates/skills/dx-review/references/acts.md +162 -0
- package/templates/skills/dx-spec/SKILL.md +223 -27
- package/templates/skills/dx-spec/references/principles-template.md +2 -0
- package/templates/skills/dx-spec/references/review-guide.md +4 -50
- package/templates/skills/dx-spec/references/spec-guide.md +24 -4
- package/templates/skills/dx-spec/references/stages.md +143 -58
- package/templates/skills/dx-spec-execute/SKILL.md +148 -35
- package/templates/startup.mjs +10 -4
- package/templates/tool-helper.sh +166 -0
- package/templates/webterm/README.md +60 -26
- package/templates/webterm/color.js +61 -0
- package/templates/webterm/config.js +35 -4
- package/templates/webterm/context/claude.md +0 -1
- package/templates/webterm/public/app/alerts.js +4 -4
- package/templates/webterm/public/app/anchored.js +81 -0
- package/templates/webterm/public/app/connection.js +9 -0
- package/templates/webterm/public/app/dom.js +2 -0
- package/templates/webterm/public/app/frames.js +51 -17
- package/templates/webterm/public/app/main.js +22 -8
- package/templates/webterm/public/app/new-session.js +13 -41
- package/templates/webterm/public/app/palette.js +58 -0
- package/templates/webterm/public/app/pane-shape.js +167 -0
- package/templates/webterm/public/app/pane-shell.js +199 -134
- package/templates/webterm/public/app/pane.js +33 -24
- package/templates/webterm/public/app/reviews-host.js +15 -0
- package/templates/webterm/public/app/specs-host.js +12 -218
- package/templates/webterm/public/app/state.js +5 -0
- package/templates/webterm/public/app/tabs.js +6 -2
- package/templates/webterm/public/app/theme.js +75 -27
- package/templates/webterm/public/app/tool-host.js +302 -0
- package/templates/webterm/public/app/workspace-color.js +192 -0
- package/templates/webterm/public/index.html +17 -3
- package/templates/webterm/public/styles.css +143 -21
- package/templates/webterm/server.js +198 -150
- package/templates/webterm/tools/commands.js +61 -0
- package/templates/webterm/tools/index.js +25 -0
- package/templates/webterm/tools/mount.js +337 -0
- package/templates/webterm/tools/paths.js +34 -0
- package/templates/webterm/tools/reviews.js +133 -0
- package/templates/webterm/tools/specs.js +154 -0
- package/templates/webterm/typed-line.js +70 -7
- package/templates/context/context-usage.md +0 -1
- package/templates/context-usage.sh +0 -266
- package/templates/pane-apps/client/assets/specs-B1970L17.css +0 -1
- package/templates/pane-apps/client/assets/specs-cEee_SPn.js +0 -23
- package/templates/skills/dx-spec-config/SKILL.md +0 -313
- package/templates/skills/dx-spec-config/references/principles-template.md +0 -12
- package/templates/specs.sh +0 -106
- package/templates/webterm/specs.js +0 -358
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: chamba-statusline
|
|
3
|
-
description: Explain where a session's status lives in chamba - the strip in the web interface, the snapshot behind it
|
|
3
|
+
description: Explain where a session's status lives in chamba - the strip in the web interface, and the snapshot behind it. Use when the user mentions the status line, asks why the terminal has none, asks what the strip above the composer means, or wants a status line of their own.
|
|
4
|
+
metadata:
|
|
5
|
+
audience: claude
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# chamba-statusline: Where a session's status is
|
|
@@ -25,31 +27,17 @@ The web interface shows the attached session's status in one line between the te
|
|
|
25
27
|
|
|
26
28
|
The strip belongs to the session it is drawn for, and only a claude session has one - the snapshot is a Claude Code feature, so a codex or opencode tab has no strip at all.
|
|
27
29
|
|
|
28
|
-
## Step 2 - The snapshot behind it
|
|
30
|
+
## Step 2 - The snapshot behind it
|
|
29
31
|
|
|
30
32
|
The script at `{{statusline_path}}` is what makes any of this exist. Claude Code runs it on every prompt render and hands it the session's state on stdin; the script parses it, resolves the pid of the claude process it was run by, and writes a small JSON file. Fields: `session_id`, `claude_pid`, `claude_pid_start`, `updated_at`, `context_tokens`, `context_used_pct`, `context_window_size`, `model`, `effort`, `quota_left_pct`, `quota_resets_at`, `quota_week_left_pct`, `quota_week_resets_at`, `version`. The two `quota_*` pairs are the five-hour and seven-day rate-limit windows; both percentages are what is LEFT, inverted from the percentage used that Claude Code reports.
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
- The web interface, which matches a snapshot to a session by that pid and draws the strip from it.
|
|
34
|
-
- The `context-usage` command, which is how an agent inspects its own context and quota from the terminal. Run it rather than reading the files by hand.
|
|
35
|
-
|
|
36
|
-
If the user wants the numbers without the browser, `context-usage` is the answer. It prints one labelled line per thing the snapshot carried:
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
session: 78b4025b-... (this session, updated 3s ago)
|
|
40
|
-
context: 70.8k tokens (7% of 1M window)
|
|
41
|
-
quota: 84% remaining, resets in 21m
|
|
42
|
-
weekly: 59% remaining, resets in 4d 6h
|
|
43
|
-
model: Fable 5 (effort high)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
`quota` is the five-hour window and `weekly` the seven-day one; a window the account does not have prints no line at all, and neither does a field the snapshot is missing. The `(this session, ...)` marker means the snapshot was matched to the asking session by pid and is certainly its own; without it the newest file was used instead, and a `warning:` line says why that may mislead. The numbers are as of the moment the current prompt was submitted, so the turn in flight is not in them yet.
|
|
34
|
+
The web interface reads those files: it matches a snapshot to a session by that pid and draws the strip from it. The numbers are as of the moment the current prompt was submitted, so the turn in flight is not in them yet.
|
|
47
35
|
|
|
48
36
|
## Step 3 - When the user wants a status line of their own
|
|
49
37
|
|
|
50
38
|
The chamba script prints nothing on purpose: a status line is redrawn inside the conversation, so in a browser it scrolls away with the output and costs a row of the terminal every prompt. The strip is the same information somewhere it stays put.
|
|
51
39
|
|
|
52
|
-
A user who works in the terminal and wants a visible line back can have one - by pointing Claude Code at their own script. Explain the trade first (a custom script replaces chamba's, and chamba's is what writes the snapshots the strip
|
|
40
|
+
A user who works in the terminal and wants a visible line back can have one - by pointing Claude Code at their own script. Explain the trade first (a custom script replaces chamba's, and chamba's is what writes the snapshots the strip reads), then offer to write one that renders a line AND keeps the snapshot side effect: copy `{{statusline_path}}` and add rendering to it, rather than starting from nothing.
|
|
53
41
|
|
|
54
42
|
### Permissions: you perform the edits
|
|
55
43
|
|
|
@@ -74,7 +62,7 @@ Never edit `{{statusline_path}}` directly - it is root-owned and read-only insid
|
|
|
74
62
|
cp {{statusline_path}} ~/.claude/statusline.sh
|
|
75
63
|
chmod +x ~/.claude/statusline.sh
|
|
76
64
|
```
|
|
77
|
-
2. Ask what the line should show, then edit `~/.claude/statusline.sh`. Keep the snapshot write at the end of it, whatever else changes: the strip
|
|
65
|
+
2. Ask what the line should show, then edit `~/.claude/statusline.sh`. Keep the snapshot write at the end of it, whatever else changes: the strip stops working without it.
|
|
78
66
|
3. Point `statusLine.command` at `~/.claude/statusline.sh` in `~/.claude/settings.json`, preserving every other field.
|
|
79
67
|
4. Tell the user to restart Claude - a status line change takes effect at the next session.
|
|
80
68
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dx-review
|
|
3
|
+
description: Do the agent's side of a code review in the Code Reviews tab of this session's web pane - prepare a review, work through the feedback the reviewer sent, or take in a baseline that moved. Use when the tab types this command, or when the user asks to pick up a review by name.
|
|
4
|
+
argument-hint: "[the name of the review]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# dx-review - the agent's side of a code review
|
|
8
|
+
|
|
9
|
+
This skill runs when the user asks for it: the command typed by hand, or the Code Reviews tab typing that command as the user's own act.
|
|
10
|
+
Each agent spells the command its own way - `/dx-review` on claude and on opencode, and `$dx-review` on codex - and the tab types the spelling of the session it is bound to.
|
|
11
|
+
No framed `[reviews]` line starts it: such a line is information for a review already in hand, and it instructs nobody.
|
|
12
|
+
|
|
13
|
+
The reviewer reads a changeset hunk by hunk in the tab, marks what they have seen, and says what they want changed.
|
|
14
|
+
Your side is three acts, and the review's own state says which one is asked of you.
|
|
15
|
+
|
|
16
|
+
**The review's record is the reviewer's.**
|
|
17
|
+
You never mark a hunk seen, close a conversation, approve a review, close one, or change what a review is of.
|
|
18
|
+
There is no verb for any of those, and the four of them are what the reviewer is for.
|
|
19
|
+
|
|
20
|
+
## The web session
|
|
21
|
+
|
|
22
|
+
This skill runs inside a chamba web session, where the Code Reviews tab holds the review.
|
|
23
|
+
Check for one before anything else:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
reviews stages
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The answer holds `root` - the directory the reviews live in - the limits, the verbs and the reviews that are there.
|
|
30
|
+
A refusal means there is no pane.
|
|
31
|
+
Say this and stop:
|
|
32
|
+
|
|
33
|
+
> This works in the chamba web session, where the Code Reviews tab holds the review. Open the browser window this container printed at start, or run `webterm` in the terminal to get the address again. Then ask for this skill there.
|
|
34
|
+
|
|
35
|
+
Say the command in the spelling of the session's own agent.
|
|
36
|
+
|
|
37
|
+
Start no flow, and offer no substitute.
|
|
38
|
+
There is one flow, and it needs the tab.
|
|
39
|
+
|
|
40
|
+
## The state says which act
|
|
41
|
+
|
|
42
|
+
Read the state first, and do nothing before you have:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
reviews state "<the review's name>"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
With no name given, `reviews stages` lists the reviews that are there.
|
|
49
|
+
One of them is the review the tab woke you for: the one whose `awaits.side` is `agent`.
|
|
50
|
+
Where more than one is, say which ones and ask the reviewer in this terminal which they mean.
|
|
51
|
+
|
|
52
|
+
The answer holds what you need and nothing you have to work out:
|
|
53
|
+
|
|
54
|
+
| Field | What it is |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `awaits` | `{ side, act, reason }` - who holds the review, which act is asked, and why, in one line |
|
|
57
|
+
| `act` | `prepare`, `process`, `sync`, or null |
|
|
58
|
+
| `side` | `agent` while the review is yours, `you` while it is the reviewer's |
|
|
59
|
+
| `status` | `reviewing` while there is work; `approved`, `closed` or `archived` where there is none |
|
|
60
|
+
| `baseline` | The changeset: the `fingerprint`, the totals, and every file with the id and header of each of its hunks |
|
|
61
|
+
| `metadata` | The grouping and the notes as they stand, and empty where nothing is grouped |
|
|
62
|
+
| `ungrouped` | The hunks no group holds, which is what a grouping post answers with |
|
|
63
|
+
| `threads` | Every conversation, with its anchor, whether it is open, and its messages |
|
|
64
|
+
| `send` | The newest batch the reviewer sent: `sentAt`, the `fingerprint` it was written against, and its `items` |
|
|
65
|
+
| `selection` | What the review is of, in one line |
|
|
66
|
+
| `loops` | How many times the reviewer has sent feedback |
|
|
67
|
+
|
|
68
|
+
Then act on `awaits`:
|
|
69
|
+
|
|
70
|
+
- **`side` is `you`** - the review is not yours. Every verb that writes is refused, and rightly. Say the review is with the reviewer and stop.
|
|
71
|
+
- **`status` is not `reviewing`** - the review is finished. Say so and stop.
|
|
72
|
+
- **`act` is one of the three** - do that act. `references/acts.md` holds each one in detail; read the one you are doing.
|
|
73
|
+
- **`act` is null and `side` is `agent`** - there is nothing waiting. Say so in this terminal and post nothing at all, `activity` and `done` included.
|
|
74
|
+
|
|
75
|
+
The last two cases are real cases, not faults.
|
|
76
|
+
The tab types this command for every act that hands a review over, and "Ask the agent to continue" types it again on a review that may be in hand already, so the command arriving is not by itself work to do.
|
|
77
|
+
A review that came back to the reviewer a moment ago answers `side: you`, and there is nothing for you in it.
|
|
78
|
+
|
|
79
|
+
### The three acts, in one line each
|
|
80
|
+
|
|
81
|
+
- **`prepare`** - the review has a baseline and no grouping. Group every hunk into a few pieces of work, give each group a narrative, and write the notes: `info` where an explanation helps the reviewer, `attention` where a passage needs a human eye, `issue` where you are certain something is wrong.
|
|
82
|
+
- **`process`** - the reviewer sent a batch. Do what each item asks, and reply in the conversation each item opened.
|
|
83
|
+
- **`sync`** - the baseline moved, because the reviewer synced the review, stopped you, or followed a merge. Group what is new, and revise what the new code made wrong.
|
|
84
|
+
|
|
85
|
+
## What you post
|
|
86
|
+
|
|
87
|
+
Five verbs, and they are the whole of what you may do to a review:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
echo '<json>' | reviews metadata "<review>" the grouping and the notes for this baseline
|
|
91
|
+
echo '<json>' | reviews reply "<review>" one reply in one conversation: { thread, text }
|
|
92
|
+
echo '<json>' | reviews activity "<review>" what you are doing right now: { said, groups? }
|
|
93
|
+
echo '<json>' | reviews log "<review>" one dated line for the activity log: { said }
|
|
94
|
+
reviews done "<review>" your act is finished
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
A payload is JSON on stdin, and the answer is JSON on stdout.
|
|
98
|
+
`references/acts.md` holds the shape of each payload.
|
|
99
|
+
|
|
100
|
+
**Post `activity` as you go.**
|
|
101
|
+
It is one short sentence in the present tense - "Grouping the parser changes", "Working on the second item" - and the tab shows it with the time you posted it.
|
|
102
|
+
A review that has said nothing for ten minutes is drawn as stale, so a long act posts as it moves rather than once at the end.
|
|
103
|
+
|
|
104
|
+
**Post `done` last, and only when the act is finished.**
|
|
105
|
+
It hands the review back to the reviewer, and the tool recomputes the baseline as it does.
|
|
106
|
+
So a `metadata` or a `reply` after `done` is refused: the review is no longer yours.
|
|
107
|
+
|
|
108
|
+
**Change no code that the act did not ask for.**
|
|
109
|
+
`done` recomputes the baseline from the tree as it stands, so any edit of yours becomes part of what the reviewer reads, and the marks they made are carried onto it.
|
|
110
|
+
`prepare` and `sync` are reading acts: group it, note it, reply, and leave the code alone.
|
|
111
|
+
`process` is the one act that writes code, and it writes what the reviewer asked for and no more.
|
|
112
|
+
|
|
113
|
+
**A grouping is posted against the baseline you read.**
|
|
114
|
+
The post carries that baseline's `fingerprint`, and a post against a fingerprint that has moved on is refused with the reason.
|
|
115
|
+
That is not an error to work around: the reviewer changed what the review is of while you worked, the review awaits you again, and the answer is to read the state and work from the baseline that is there now.
|
|
116
|
+
|
|
117
|
+
## When you are not sure
|
|
118
|
+
|
|
119
|
+
Ask the reviewer, in this terminal, and wait for the answer.
|
|
120
|
+
A piece of feedback that could mean two things is worth one question; a guess costs the reviewer a whole loop of the review.
|
|
121
|
+
|
|
122
|
+
The one thing never to do with an unclear item is to reply in its conversation as though it were settled.
|
|
123
|
+
A reply is your answer to what was asked, and the tab shows it as one.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# The three acts, in detail
|
|
2
|
+
|
|
3
|
+
Read the act you are doing.
|
|
4
|
+
`SKILL.md` says how you learn which one that is: `reviews state "<review>"`, and then `awaits.act`.
|
|
5
|
+
|
|
6
|
+
Everything here is posted with the verbs of `SKILL.md`, and nothing else writes to a review.
|
|
7
|
+
|
|
8
|
+
## prepare - the review has a baseline and no grouping
|
|
9
|
+
|
|
10
|
+
The reviewer has filed a review and is waiting to read it.
|
|
11
|
+
Until you post a grouping the screen shows every hunk under "Not grouped yet", which is a wall of diff with no story in it.
|
|
12
|
+
So this act is the one the reviewer waits on longest, and it is the one that decides how the review reads.
|
|
13
|
+
|
|
14
|
+
**1. Read the change before you group it.**
|
|
15
|
+
The state's `baseline` holds every file and, for each one, the id and header of each of its hunks.
|
|
16
|
+
Read the code itself as well - the files of the workspace are there, and the review is of the tree you are in.
|
|
17
|
+
A grouping written from headers alone groups by file, which the tab could have done without you.
|
|
18
|
+
|
|
19
|
+
**2. Group by intent, not by file.**
|
|
20
|
+
A group is a piece of work somebody did: "the discount rules", "the new error path", "the rename that follows from it".
|
|
21
|
+
Three to seven groups reads well for most changesets.
|
|
22
|
+
One group of forty hunks says nothing, and twenty groups of two are the file list again.
|
|
23
|
+
|
|
24
|
+
- A hunk may sit in several groups where it belongs to both.
|
|
25
|
+
- A hunk in no group lands under "Ungrouped", which is the tool's own group. It is for the case where you missed one, and a review that shows it is a review you left half grouped.
|
|
26
|
+
- `ungrouped` in the post's answer is that list. Read it, and post again with the hunks it names in the groups they belong to.
|
|
27
|
+
|
|
28
|
+
**3. Give each group a narrative and its facts.**
|
|
29
|
+
The narrative is a short paragraph in plain language: what this piece of work does, and why the change is what it is.
|
|
30
|
+
The reviewer reads it before the hunks, so it says the thing the diff cannot - the intent.
|
|
31
|
+
The facts are a few short lines of what is true and checkable: "adds one table column", "no call site outside the cart", "the old path stays for one release".
|
|
32
|
+
Facts are facts. Anything that needs "I think" is not one.
|
|
33
|
+
|
|
34
|
+
**4. Write the notes.**
|
|
35
|
+
You read every line of this change, and the reviewer has not.
|
|
36
|
+
The notes are what you learned while you read, beside the code, so that the human review is quick and misses nothing.
|
|
37
|
+
A note is plain text of one kind, on one hunk or on a line range inside it.
|
|
38
|
+
|
|
39
|
+
- `info` - an explanation that helps the reviewer understand the code: what a passage does, why the change is the way it is, what it mirrors elsewhere. "This mirrors the rule in `pricing.ts`." Write one wherever an explanation would save the reviewer a search or a guess.
|
|
40
|
+
- `attention` - anything that deserves the reviewer's eyes, whether or not you found a fault in it: a hard passage, a change of behaviour, a decision with a trade-off, a place you believe is right and a human should confirm. "This drops the guard the caller used to hold." Attention is relative to this changeset: it marks the parts of this change that most need a human.
|
|
41
|
+
- `issue` - something you are certain is wrong. The text says what is wrong in one or two sentences and, where you see it, how to fix it. "The loop never steps `i`, so it never ends. Step it at the end of the body." Write an issue only when you are sure; where you are not, write `attention` and say what you suspect.
|
|
42
|
+
|
|
43
|
+
The screen counts the open `issue` and `attention` notes on each group and in the status bar, so the reviewer sees where the eyes are needed before they read.
|
|
44
|
+
The reviewer can dismiss a note, ask you to fix an issue, or open a conversation on it.
|
|
45
|
+
One note per thing you have to say, and the kind that fits it.
|
|
46
|
+
A note on every hunk is a rail nobody reads, but a hunk that needs an explanation and has none is a question the reviewer has to ask you.
|
|
47
|
+
|
|
48
|
+
**Do not fix anything in this act.**
|
|
49
|
+
You found the issue, and the reviewer decides what to do with it: the fix is an item in the batch they send, and `process` is where you do it.
|
|
50
|
+
|
|
51
|
+
**5. Post it.**
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
echo '{
|
|
55
|
+
"fingerprint": "sha256:...",
|
|
56
|
+
"groups": [
|
|
57
|
+
{ "id": "discount-rules", "name": "Discount rules",
|
|
58
|
+
"narrative": "The rules move out of the cart and into one place ...",
|
|
59
|
+
"facts": ["adds one table column", "no call site outside the cart"],
|
|
60
|
+
"hunks": ["src/cart/discount.ts#9f3a...#1", "src/cart/discount.ts#9f3a...#2"] }
|
|
61
|
+
],
|
|
62
|
+
"notes": [
|
|
63
|
+
{ "hunk": "src/cart/discount.ts#9f3a...#1", "kind": "attention", "lines": [44, 46],
|
|
64
|
+
"text": "This drops the guard the caller used to hold." },
|
|
65
|
+
{ "hunk": "src/cart/discount.ts#9f3a...#2", "kind": "issue", "lines": [61],
|
|
66
|
+
"text": "The loop never steps `i`, so it never ends. Step it at the end of the body." }
|
|
67
|
+
]
|
|
68
|
+
}' | reviews metadata "<review>"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`fingerprint` is the baseline's own, from the state you read.
|
|
72
|
+
`id` is yours to choose and is the name the tool refers to the group by; `name` is what the reviewer reads.
|
|
73
|
+
`kind` is `info`, `attention` or `issue`.
|
|
74
|
+
`lines` are new-side line numbers inside the hunk, and a note without them is about the whole hunk.
|
|
75
|
+
The screen draws one bar in the gutter from the smallest number to the largest, so two numbers name a range.
|
|
76
|
+
|
|
77
|
+
**A post replaces the whole grouping.**
|
|
78
|
+
That is what makes a group appear as it becomes ready: post the groups you have, and post them all again with the next one added.
|
|
79
|
+
The screen then shows three groups, then four.
|
|
80
|
+
A post with no group empties the grouping, which is what it says.
|
|
81
|
+
|
|
82
|
+
**6. Say what you are doing, and finish.**
|
|
83
|
+
Post `activity` as you work through it - "Grouping the parser changes, 3 of 5 ready" - and `done` when the grouping is complete and every note is in.
|
|
84
|
+
|
|
85
|
+
**Say how many groups there will be, in `groups`.**
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
echo '{ "said": "Grouping the parser changes, 3 of 5 ready", "groups": 5 }' | reviews activity "<review>"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
You are the only one who knows it: the tool holds the groups you posted, and the tab draws one card waiting for each group you promised and has not arrived, so the reviewer sees how much is still coming.
|
|
92
|
+
Post it once you know the number, and post the sentence alone after that - the count stands until you post another, and it is cleared when the review goes back to the reviewer.
|
|
93
|
+
|
|
94
|
+
## process - the reviewer sent a batch
|
|
95
|
+
|
|
96
|
+
`send` in the state is the newest batch: when it was sent, the baseline it was written against, and its `items`.
|
|
97
|
+
Each item is one thing the reviewer asked, and each one has already opened or joined a conversation on the hunk or the group it is about.
|
|
98
|
+
|
|
99
|
+
An item carries:
|
|
100
|
+
|
|
101
|
+
- `hunk` - the hunk it is about, or null for a comment on a group.
|
|
102
|
+
- `group` - the group it is about, and null for everything else.
|
|
103
|
+
- `act` - what the reviewer asked for: `undo` (undo the change), `explain` (explain it in a comment), `comment`, `fix` (fix what a note of yours says), or `group-comment`.
|
|
104
|
+
- `lines` - the new-side lines the item is about, or null for the whole hunk or a group.
|
|
105
|
+
- `text` - what they said, and it may be empty for an `undo` that speaks for itself.
|
|
106
|
+
|
|
107
|
+
**Do the work first, and reply about what you did.**
|
|
108
|
+
The order matters: a reply is a statement about the code, and a reply written before the change is a promise.
|
|
109
|
+
|
|
110
|
+
- `undo` - put that hunk's change back as it was, unless doing so breaks something the reviewer cannot see. Where it does, do not undo it quietly: say what breaks, in the conversation, and leave the code as it is.
|
|
111
|
+
- `explain` - the reviewer wants the reasoning, not a change. Answer in the conversation and change nothing.
|
|
112
|
+
- `fix` - the reviewer read an `issue` note of yours and asks for the fix. The text is the note, with anything they added, and `lines` says where. Fix it, and reply with what you did.
|
|
113
|
+
- `comment` and `group-comment` - read what they asked for and do it. It may be a change, a question, or both.
|
|
114
|
+
|
|
115
|
+
**Reply in the conversation each item is on.**
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
echo '{ "thread": "<the thread id from the state>", "text": "Undone. The old guard is back, and ..." }' | reviews reply "<review>"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The `threads` in the state hold the id, the anchor and every message, so the thread of an item is the one whose anchor is that item's hunk or group.
|
|
122
|
+
One reply per item, and each one lands live on the reviewer's screen under the hunk they were looking at.
|
|
123
|
+
|
|
124
|
+
You cannot close a conversation, and you should not try to write a reply that reads like a closing.
|
|
125
|
+
The reviewer closes a conversation when they are satisfied, and that is the whole point of the control.
|
|
126
|
+
|
|
127
|
+
**Where an item is unclear, ask in the terminal.**
|
|
128
|
+
Then do the item, and reply once you know what it asked.
|
|
129
|
+
Do not reply with a question: a reply is your answer, and the tab draws it as one.
|
|
130
|
+
|
|
131
|
+
**Finish with `done`.**
|
|
132
|
+
It hands the review back and the tool recomputes the baseline, so the reviewer sees your commits as part of the review and every hunk they had read that you did not touch is still read.
|
|
133
|
+
|
|
134
|
+
## sync - the baseline moved
|
|
135
|
+
|
|
136
|
+
The reviewer synced the review, stopped you mid-act, or followed a merge.
|
|
137
|
+
Either way the baseline is a new one, and the state's `metadata` is what you posted for the baseline before it.
|
|
138
|
+
|
|
139
|
+
**What is already true, and what you do not have to do again.**
|
|
140
|
+
The tool carried every mark, conversation and pending item onto the hunks that did not change, and it kept the grouping of every hunk that is still there.
|
|
141
|
+
A hunk the reviewer had read whose content changed comes back unread with a "changed since you saw it" marker, which is the tool's, not a note of yours.
|
|
142
|
+
|
|
143
|
+
So this act is the difference, and not the review again:
|
|
144
|
+
|
|
145
|
+
1. **Group what is new.** `ungrouped` names the hunks no group holds. Most of them are new hunks, and each one belongs in a group that exists or in one more group.
|
|
146
|
+
2. **Revise what the new code made wrong.** A narrative that describes code that is no longer there is worse than none, because the reviewer reads it as current. Read your own narratives against the new baseline and rewrite the ones that moved.
|
|
147
|
+
3. **Read your notes again.** The tool dropped the notes of every hunk whose content changed, and kept the rest. Write again only the notes that are still true of the new code, and write notes for what is new. An issue you fixed gets no note: the rail shows the code as it is, not what it was.
|
|
148
|
+
4. **Answer what is open.** A conversation the reviewer is waiting on is one that is open and whose last message is theirs. Answer it if the new code answers it.
|
|
149
|
+
|
|
150
|
+
Post the whole grouping again, with the new baseline's `fingerprint`, and `done` when it is in.
|
|
151
|
+
|
|
152
|
+
## The no-act case
|
|
153
|
+
|
|
154
|
+
`awaits.act` is null, so none of the three applies.
|
|
155
|
+
It happens two ways, and both are ordinary.
|
|
156
|
+
|
|
157
|
+
- **`side` is `you`.** The review is with the reviewer. It came back to them when the last act posted `done`, or they stopped you and are reading it now. The command arrived because they asked again, or because it was typed by hand.
|
|
158
|
+
- **`side` is `agent` and `act` is null.** The review is yours and names no act, which is a review that has nothing pending in it.
|
|
159
|
+
|
|
160
|
+
Say so in the terminal, in one line, and post nothing.
|
|
161
|
+
Not `activity`, and not `done`: `done` recomputes the baseline and hands back a review that was never taken, and the reviewer reads that as work that happened.
|
|
162
|
+
Where the review is the reviewer's, every verb that writes is refused in any case, and the refusal is the right answer rather than something to work around.
|