thurview 0.1.4
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 +21 -0
- package/README.md +185 -0
- package/bin/thurview.js +8 -0
- package/dist/cli.js +1101 -0
- package/dist/cli.js.map +1 -0
- package/dist/diff.js +65 -0
- package/dist/diff.js.map +1 -0
- package/dist/document/compile.js +418 -0
- package/dist/document/compile.js.map +1 -0
- package/dist/document/parse.js +139 -0
- package/dist/document/parse.js.map +1 -0
- package/dist/document/schema.js +129 -0
- package/dist/document/schema.js.map +1 -0
- package/dist/flags.js +66 -0
- package/dist/flags.js.map +1 -0
- package/dist/git.js +206 -0
- package/dist/git.js.map +1 -0
- package/dist/highlight-theme.js +93 -0
- package/dist/highlight-theme.js.map +1 -0
- package/dist/highlight.js +163 -0
- package/dist/highlight.js.map +1 -0
- package/dist/main.js +3 -0
- package/dist/main.js.map +1 -0
- package/dist/server/server.js +387 -0
- package/dist/server/server.js.map +1 -0
- package/dist/store.js +100 -0
- package/dist/store.js.map +1 -0
- package/dist/symbols.js +192 -0
- package/dist/symbols.js.map +1 -0
- package/dist/theme.js +301 -0
- package/dist/theme.js.map +1 -0
- package/dist/threads.js +87 -0
- package/dist/threads.js.map +1 -0
- package/dist/ui/app.css +1415 -0
- package/dist/ui/app.js +2303 -0
- package/dist/ui/app.js.map +7 -0
- package/dist/ui/assets/fonts/inter-400.woff2 +0 -0
- package/dist/ui/assets/fonts/jetbrains-mono-400.woff2 +0 -0
- package/dist/ui/assets/fonts/press-start-2p-400.woff2 +0 -0
- package/dist/ui/assets/inter-400.woff2 +0 -0
- package/dist/ui/assets/jetbrains-mono-400.woff2 +0 -0
- package/dist/ui/assets/press-start-2p-400.woff2 +0 -0
- package/dist/ui/index.html +13 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +70 -0
- package/skills/thurview/SKILL.md +219 -0
- package/skills/thurview/references/components.md +120 -0
- package/skills/thurview/references/document-authoring.md +107 -0
- package/skills/thurview/references/lifecycle.md +88 -0
- package/skills/thurview/references/software-map.md +42 -0
- package/skills/thurview/references/theme.md +90 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: thurview
|
|
3
|
+
description: Author and publish a thurview review - a guided, evidence-anchored explanation of a branch, pull request or commit range that the reader opens in the browser, annotates, asks questions about, and approves or sends back. Use when the user asks to review a branch or PR, to explain or walk through a change, "review my branch against main", to explain how a codebase or subsystem works, or invokes /thurview. Not for a pass/fail bug hunt.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
argument-hint: "[<pr-number|pr-url> | --base <ref> --head <ref> | <architecture topic>]"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# thurview
|
|
9
|
+
|
|
10
|
+
The agent studies the change and writes a short document in which every claim
|
|
11
|
+
about code is anchored to an exact file and line range at a pinned commit.
|
|
12
|
+
thurview validates those anchors, seals a revision, and serves it in the
|
|
13
|
+
browser with live code peeks, diffs, diagrams and a map. The reader asks
|
|
14
|
+
questions, leaves anchored comments, and approves or requests changes. The
|
|
15
|
+
agent answers, updates, republishes.
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
flowchart LR
|
|
19
|
+
A[scaffold: pin base and head] --> B[author review.md, data.yaml, map.yaml]
|
|
20
|
+
B --> C[publish: validate and seal revision]
|
|
21
|
+
C --> D[open: reader reviews in the browser]
|
|
22
|
+
D -->|question| E[threads reply]
|
|
23
|
+
E --> D
|
|
24
|
+
D -->|request changes| B
|
|
25
|
+
D -->|approve| F[done]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Run the CLI as `thurview`. When it is not on PATH, `npx -y thurview` runs
|
|
29
|
+
the published package with the same commands; substitute it everywhere below.
|
|
30
|
+
|
|
31
|
+
Every command prints TOON on stdout: the result, then `help[]` with the next
|
|
32
|
+
commands. Errors are structured on stdout too (`error`, `code`, `help`); exit
|
|
33
|
+
code 1 is a failure, 2 a usage error such as an unknown flag. Progress goes to
|
|
34
|
+
stderr; do not scrape it. `thurview` alone shows the reviews of the current
|
|
35
|
+
directory; `thurview <command> --help` shows flags and examples.
|
|
36
|
+
|
|
37
|
+
## Request
|
|
38
|
+
|
|
39
|
+
$ARGUMENTS
|
|
40
|
+
|
|
41
|
+
Empty: the current branch against its up-to-date trunk. A PR number or URL:
|
|
42
|
+
that pull request. `--base`/`--head`: that range. Anything else: an
|
|
43
|
+
architecture review of that topic in the current repository.
|
|
44
|
+
|
|
45
|
+
## Before authoring
|
|
46
|
+
|
|
47
|
+
Read the guidance files that exist, in this order. The second wins on
|
|
48
|
+
conflict.
|
|
49
|
+
|
|
50
|
+
1. `~/.thurview/THURVIEW.md` (or `$THURVIEW_HOME/THURVIEW.md`), user guidance.
|
|
51
|
+
2. `THURVIEW.md` at the repository root, repository guidance.
|
|
52
|
+
|
|
53
|
+
`thurview scaffold` lists the ones it found under `guidance`.
|
|
54
|
+
|
|
55
|
+
Read [Document authoring](references/document-authoring.md) before you write.
|
|
56
|
+
Read [Components](references/components.md) before you edit `data.yaml` or add
|
|
57
|
+
a fenced component. Read [Lifecycle](references/lifecycle.md) for statuses,
|
|
58
|
+
storage and thread rules. Read [Software map](references/software-map.md)
|
|
59
|
+
before you author `map.yaml`. Read [Theme](references/theme.md) before you
|
|
60
|
+
write `theme.yaml`.
|
|
61
|
+
|
|
62
|
+
## Workflow
|
|
63
|
+
|
|
64
|
+
### 1. Resolve the review
|
|
65
|
+
|
|
66
|
+
Run `thurview info` in the source worktree. It lists reviews bound to that
|
|
67
|
+
worktree with `inSync` (HEAD equals the pinned head). Reuse a review that
|
|
68
|
+
matches the requested change. Otherwise run `thurview scaffold` with the
|
|
69
|
+
matching flags:
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
thurview scaffold # current branch vs trunk fork point
|
|
73
|
+
thurview scaffold --pr 123 # pull request (needs gh)
|
|
74
|
+
thurview scaffold --base <ref> --head <ref>
|
|
75
|
+
thurview scaffold --new # another review for the same binding
|
|
76
|
+
thurview scaffold --update --review <id> # re-pin after the branch moved
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Record from the scaffold output: `review.id` (short id accepted everywhere),
|
|
80
|
+
`review.dir`, `review.base`, `review.head`, `files.document`, `files.data`,
|
|
81
|
+
`files.map`, `files.theme`, `change` (files, additions, deletions) and
|
|
82
|
+
`guidance`.
|
|
83
|
+
|
|
84
|
+
Resolve refs before passing them. Pass commit ids or plain ref names; do not
|
|
85
|
+
pass `<rev>^` inside a jj workspace.
|
|
86
|
+
|
|
87
|
+
### 2. Show small changes at once
|
|
88
|
+
|
|
89
|
+
When `change.additions + change.deletions` is under 300, publish first and
|
|
90
|
+
land the reader on the diff, then write the document:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
thurview publish --review <id> --view files --open
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The scaffolded stub validates as long as `README.md` exists at head; if it
|
|
97
|
+
does not, point the `entry` anchor at any file that does. Larger changes skip
|
|
98
|
+
this step.
|
|
99
|
+
|
|
100
|
+
### 3. Study the change
|
|
101
|
+
|
|
102
|
+
Read the whole diff once (`git diff <base> <head>`). Then read each changed
|
|
103
|
+
symbol's callers and callees at head. Trace the main flow through storage,
|
|
104
|
+
network and configuration boundaries. Compare the stated intent (commit
|
|
105
|
+
messages, PR description, the user's own words) with what the code does. The
|
|
106
|
+
gap is the most valuable finding.
|
|
107
|
+
|
|
108
|
+
Read every range you anchor from the pinned commit, not the working tree:
|
|
109
|
+
`git show <head>:<path>` or `git show <base>:<path>`.
|
|
110
|
+
|
|
111
|
+
### 4. Author the document
|
|
112
|
+
|
|
113
|
+
Edit `review.md` and `data.yaml` in the review directory following
|
|
114
|
+
[Document authoring](references/document-authoring.md). Keep it short.
|
|
115
|
+
Default to anchor links for evidence; use an inline peek only when the reader
|
|
116
|
+
must see the code to follow the main claim.
|
|
117
|
+
|
|
118
|
+
### 5. Theme the review after the project
|
|
119
|
+
|
|
120
|
+
Read [Theme](references/theme.md). Decide the look in its order: what the
|
|
121
|
+
user asked for, then the reviewed project's own design system read from its
|
|
122
|
+
files at head, then the default skin. Write `theme.yaml` in the review
|
|
123
|
+
directory when steps 1 or 2 yield tokens; leave it empty otherwise. Say
|
|
124
|
+
which source you used when you hand over the review.
|
|
125
|
+
|
|
126
|
+
### 6. Author the map
|
|
127
|
+
|
|
128
|
+
Dispatch one sub-agent to write `map.yaml` per
|
|
129
|
+
[Software map](references/software-map.md) while you write the document, with
|
|
130
|
+
this prompt filled in:
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
Use the thurview skill's software-map reference (`thurview skill` prints the
|
|
134
|
+
SKILL.md path; the reference is in references/software-map.md beside it).
|
|
135
|
+
|
|
136
|
+
Review directory: <dir>
|
|
137
|
+
Source worktree: <worktree>
|
|
138
|
+
Base commit: <base>
|
|
139
|
+
Head commit: <head>
|
|
140
|
+
|
|
141
|
+
Author <dir>/map.yaml: the head structure under nodes/edges and the base
|
|
142
|
+
structure under base. Do not edit review.md or data.yaml. Do not publish.
|
|
143
|
+
Return when `thurview publish --review <id>` reports no map.yaml errors, or
|
|
144
|
+
report the errors you could not fix.
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Without a sub-agent facility, write the map yourself after the document, or
|
|
148
|
+
leave `nodes: []` and say the map is not published.
|
|
149
|
+
|
|
150
|
+
### 7. Publish
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
thurview publish --review <id>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Read every row of `diagnostics`. Fix each `error` and publish again. A
|
|
157
|
+
`warning` does not block. `publish` refuses (code `THREADS_OPEN`) when a
|
|
158
|
+
submitted comment thread is still open (see step 9). On success `published`
|
|
159
|
+
carries `rev` and `url`; the status becomes `awaiting-review`.
|
|
160
|
+
|
|
161
|
+
Then open it for the reader:
|
|
162
|
+
|
|
163
|
+
```sh
|
|
164
|
+
thurview open --review <id> # prints url; --view files|commits|map
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Give the user the `url` from the output.
|
|
168
|
+
|
|
169
|
+
### 8. Wait for the reader
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
thurview wait --review <id>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
It blocks until the reader needs you and prints `wait.reason` with the
|
|
176
|
+
threads that need you:
|
|
177
|
+
|
|
178
|
+
- `question`: an "Ask now" thread. Answer each thread in `threads` with
|
|
179
|
+
`thurview threads reply <threadId> --review <id> --body "<answer>"`. Do
|
|
180
|
+
not change the document for a question. Wait again.
|
|
181
|
+
- `awaiting-agent-updates`: the reader submitted with "Request changes".
|
|
182
|
+
`threads` lists what to address and `wait.decision` the summary. Go to
|
|
183
|
+
step 9.
|
|
184
|
+
- `accepted`: approved. Report and stop.
|
|
185
|
+
- `review-dismissed` or `review-deleted`: stop.
|
|
186
|
+
- error `TIMEOUT` (exit code 1, after `--timeout` seconds, default 3600):
|
|
187
|
+
wait again, or report that the reader has not responded.
|
|
188
|
+
|
|
189
|
+
### 9. Address requested changes
|
|
190
|
+
|
|
191
|
+
For each thread in `thurview threads list --review <id> --open`:
|
|
192
|
+
|
|
193
|
+
- A document problem: fix `review.md` or `data.yaml`.
|
|
194
|
+
- A code change request: change the branch under the normal rules (failing
|
|
195
|
+
test first), then `thurview scaffold --update --review <id>` to re-pin, and
|
|
196
|
+
re-read every anchored range that moved.
|
|
197
|
+
- Answer in the thread with `threads reply` when the reader asked something
|
|
198
|
+
or when it is not obvious what you changed.
|
|
199
|
+
- `thurview threads resolve <threadId> --review <id>` once the requested
|
|
200
|
+
change is present. Do not resolve a thread you did not address.
|
|
201
|
+
|
|
202
|
+
Then publish again (step 7), and wait again (step 8). A republish requires
|
|
203
|
+
zero open submitted comment threads; questions do not block.
|
|
204
|
+
|
|
205
|
+
## Architecture reviews
|
|
206
|
+
|
|
207
|
+
Pin the same commit as base and head: `thurview scaffold --base HEAD --head
|
|
208
|
+
HEAD`. Choose sections that describe the system (data flows, state, storage,
|
|
209
|
+
module boundaries) and skip diff-specific ones. Scope to one subsystem. All
|
|
210
|
+
other steps are the same; the Files tab shows any file at head on request.
|
|
211
|
+
|
|
212
|
+
## Completion criteria
|
|
213
|
+
|
|
214
|
+
Report completion only when all of these hold:
|
|
215
|
+
|
|
216
|
+
- The reader has the URL of a published revision.
|
|
217
|
+
- Every `error` diagnostic is resolved.
|
|
218
|
+
- The map is published, or you said why it is not.
|
|
219
|
+
- The review is waiting on the reader, accepted, dismissed or deleted.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Components
|
|
2
|
+
|
|
3
|
+
`data.yaml` holds typed inputs. `review.md` references them by id. Validation
|
|
4
|
+
is strict: an unknown key fails `publish`.
|
|
5
|
+
|
|
6
|
+
## data.yaml
|
|
7
|
+
|
|
8
|
+
```yaml
|
|
9
|
+
actors:
|
|
10
|
+
agent: { label: Agent }
|
|
11
|
+
server: { label: Server, map: system.server } # map: optional node id
|
|
12
|
+
|
|
13
|
+
anchors:
|
|
14
|
+
spawn:
|
|
15
|
+
title: PTY spawn site # required
|
|
16
|
+
detail: Cold-path fallback branch # optional, shown with the peek
|
|
17
|
+
map: system.server # optional node id
|
|
18
|
+
peek: # required for links, peeks and diagrams
|
|
19
|
+
file: src/pty.ts # path at the pinned commit
|
|
20
|
+
from: 214 # 1-based, inclusive
|
|
21
|
+
to: 223 # >= from
|
|
22
|
+
graph: head # head (default) or base
|
|
23
|
+
|
|
24
|
+
stores:
|
|
25
|
+
reviewDb:
|
|
26
|
+
kind: relational # relational (tables) or document (documents)
|
|
27
|
+
label: review.db
|
|
28
|
+
tables:
|
|
29
|
+
threads:
|
|
30
|
+
label: threads # optional
|
|
31
|
+
key: id # optional
|
|
32
|
+
schema:
|
|
33
|
+
id: { type: text, pk: true }
|
|
34
|
+
body: { type: text }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
An anchor without `peek` can label a map node but cannot open code.
|
|
38
|
+
|
|
39
|
+
## Anchor link
|
|
40
|
+
|
|
41
|
+
```markdown
|
|
42
|
+
[the spawn site](anchor:spawn)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Opens the range in the side peek. The anchor needs a `peek`.
|
|
46
|
+
|
|
47
|
+
## peek
|
|
48
|
+
|
|
49
|
+
````markdown
|
|
50
|
+
```peek
|
|
51
|
+
spawn
|
|
52
|
+
```
|
|
53
|
+
````
|
|
54
|
+
|
|
55
|
+
Renders the range inline with title, path and detail.
|
|
56
|
+
|
|
57
|
+
## sequence
|
|
58
|
+
|
|
59
|
+
````markdown
|
|
60
|
+
```sequence
|
|
61
|
+
label: Open a trace quote
|
|
62
|
+
messages:
|
|
63
|
+
- { from: agent, to: server, label: "startLogin(cols, rows)", anchor: spawn }
|
|
64
|
+
- { from: server, to: server, label: "spawnPty(dims)", code: "spawnPty(dims)" }
|
|
65
|
+
- { from: server, to: { label: CLI }, label: ready, anchor: ready }
|
|
66
|
+
```
|
|
67
|
+
````
|
|
68
|
+
|
|
69
|
+
`from` and `to` are actor ids or an inline `{ label }`. Each message needs an
|
|
70
|
+
`anchor` (peekable) or `code` (a string, or `{ language, text }`). Clicking a
|
|
71
|
+
message opens its anchor.
|
|
72
|
+
|
|
73
|
+
## callstack
|
|
74
|
+
|
|
75
|
+
````markdown
|
|
76
|
+
```callstack
|
|
77
|
+
title: Warm allocation
|
|
78
|
+
base: [reconcile, auth, enqueueWork]
|
|
79
|
+
head:
|
|
80
|
+
- reconcile
|
|
81
|
+
- enqueueWork
|
|
82
|
+
- { calls: [enqueueWork, processItem], reason: dispatched via the work queue }
|
|
83
|
+
```
|
|
84
|
+
````
|
|
85
|
+
|
|
86
|
+
Rules:
|
|
87
|
+
|
|
88
|
+
1. List order is the stack; each frame calls the one below it.
|
|
89
|
+
2. One anchor per frame, at the call site or the function head.
|
|
90
|
+
3. The diff is positional over anchor identity. A frame kept in both stacks
|
|
91
|
+
is one head-graph anchor listed in both lists; it renders as context.
|
|
92
|
+
4. A frame only in `base` is a removed call; its anchor must use
|
|
93
|
+
`graph: base`. Frames in `head` must use head anchors.
|
|
94
|
+
5. `{ calls: [parent, child], reason }` marks a hop that is hard to follow
|
|
95
|
+
(queue, callback, RPC). It renders the child with a dashed `≈`.
|
|
96
|
+
6. One component is one linear stack. Use two for two flows.
|
|
97
|
+
7. `publish` checks each `-` frame against deleted lines and each `+` frame
|
|
98
|
+
against added lines in the pinned diff. Listing a frame on one side only
|
|
99
|
+
for contrast is rejected.
|
|
100
|
+
|
|
101
|
+
## database
|
|
102
|
+
|
|
103
|
+
````markdown
|
|
104
|
+
```database
|
|
105
|
+
title: Thread storage
|
|
106
|
+
stores: [reviewDb]
|
|
107
|
+
usecases:
|
|
108
|
+
- id: resolve
|
|
109
|
+
label: Resolve a thread
|
|
110
|
+
summary: optional one-liner
|
|
111
|
+
ops:
|
|
112
|
+
- { op: read, store: reviewDb.threads, actor: agent, label: load open threads, anchor: loadThreads }
|
|
113
|
+
- { op: write, store: reviewDb.threads.body, actor: agent, label: mark resolved, anchor: markResolved }
|
|
114
|
+
```
|
|
115
|
+
````
|
|
116
|
+
|
|
117
|
+
`store` is `storeId.collection` or `storeId.collection.field`. A read flows
|
|
118
|
+
store to actor; a write flows actor to store; `op` sets the direction. Every
|
|
119
|
+
store used must be listed in `stores`. Every `actor` must exist in
|
|
120
|
+
`data.yaml`. Add this component only when a storage view materially helps.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Document authoring
|
|
2
|
+
|
|
3
|
+
## Reader contract
|
|
4
|
+
|
|
5
|
+
The reader sees the original request and your document. Not your reasoning,
|
|
6
|
+
not the implementation session, not the names you used while working.
|
|
7
|
+
Jargon coined during implementation is noise to them.
|
|
8
|
+
|
|
9
|
+
The H1 is the review's title in the browser and on the home page. Make it
|
|
10
|
+
short and specific to the change ("Publish pipeline: single mount"), never
|
|
11
|
+
generic.
|
|
12
|
+
|
|
13
|
+
Write short. Decide what to leave out before deciding what to put in. Every
|
|
14
|
+
sentence costs the reader attention; spend it on what they cannot get from the
|
|
15
|
+
diff: intent, the shape of the change, risk, what was left out and why.
|
|
16
|
+
|
|
17
|
+
Write in plain, direct sentences. One idea per sentence. No praise of the
|
|
18
|
+
change ("robust", "comprehensive"). Describe it.
|
|
19
|
+
|
|
20
|
+
## Structure
|
|
21
|
+
|
|
22
|
+
Open with a landing section between the H1 and the first H2:
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
# Audit every login
|
|
26
|
+
|
|
27
|
+
**Summary**
|
|
28
|
+
|
|
29
|
+
- login() now records every attempt before checking the user
|
|
30
|
+
- failed attempts are logged too, which the old code skipped
|
|
31
|
+
- one new module, no interface change
|
|
32
|
+
|
|
33
|
+
**Why**
|
|
34
|
+
|
|
35
|
+
Support could not tell whether a locked-out user had tried at all. The
|
|
36
|
+
request was "log every attempt, not only successes".
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Then fewer than five further sections when practical. Pick those that fit:
|
|
40
|
+
|
|
41
|
+
- requirements
|
|
42
|
+
- design
|
|
43
|
+
- interface change
|
|
44
|
+
- lifecycle or data flow
|
|
45
|
+
- state or storage
|
|
46
|
+
- testing evidence
|
|
47
|
+
- decision log
|
|
48
|
+
|
|
49
|
+
Add implementation detail only where it lets the reader check an important
|
|
50
|
+
claim. In the decision log, keep the user's requirements in the user's words
|
|
51
|
+
and add the implementation decisions that shaped the result.
|
|
52
|
+
|
|
53
|
+
Do not invent user-impact risks. When risk depends on usage you do not know,
|
|
54
|
+
say so or ask.
|
|
55
|
+
|
|
56
|
+
Collapse optional detail with `{collapsed}` at the end of an H2:
|
|
57
|
+
|
|
58
|
+
```markdown
|
|
59
|
+
## Edge cases {collapsed}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Progressive disclosure: every `##` heading is a section the reader can fold.
|
|
63
|
+
|
|
64
|
+
## Evidence
|
|
65
|
+
|
|
66
|
+
Every claim about code carries an anchor. An anchor is a named source range
|
|
67
|
+
at the pinned base or head commit, defined in `data.yaml`. Link prose to it
|
|
68
|
+
with an anchor link; the browser opens the range beside the document:
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
The [spawn site](anchor:spawn) falls back to 120x30.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Show code inline only when the reader must see it to follow the main claim:
|
|
75
|
+
|
|
76
|
+
````markdown
|
|
77
|
+
```peek
|
|
78
|
+
spawn
|
|
79
|
+
```
|
|
80
|
+
````
|
|
81
|
+
|
|
82
|
+
Use the smallest range that proves the claim. Read the range from the pinned
|
|
83
|
+
commit before you anchor it. `publish` rejects an anchor whose file or lines
|
|
84
|
+
do not exist at that commit, and an anchor link to an anchor with no `peek`.
|
|
85
|
+
|
|
86
|
+
A claim you cannot anchor is a question, not a fact. Write it as one.
|
|
87
|
+
|
|
88
|
+
## Diagrams
|
|
89
|
+
|
|
90
|
+
Use the fenced components for behaviour that prose explains badly:
|
|
91
|
+
|
|
92
|
+
- `sequence` for temporal behaviour across actors
|
|
93
|
+
- `callstack` for call-flow differences between base and head
|
|
94
|
+
- `database` for persisted-state structure and the operations on it
|
|
95
|
+
|
|
96
|
+
Each message, frame and operation carries an anchor, so the reader can open
|
|
97
|
+
the code behind every arrow. See [Components](components.md).
|
|
98
|
+
|
|
99
|
+
Add a diagram only when it materially helps. A document with one good
|
|
100
|
+
sequence diagram beats one with four.
|
|
101
|
+
|
|
102
|
+
## Files you edit
|
|
103
|
+
|
|
104
|
+
Only `review.md`, `data.yaml`, `map.yaml` and `theme.yaml` in the review
|
|
105
|
+
directory. Never
|
|
106
|
+
edit `review.json`, `threads.json` or `revisions/`. Threads change only
|
|
107
|
+
through `thurview threads`.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Lifecycle and storage
|
|
2
|
+
|
|
3
|
+
## Binding and pins
|
|
4
|
+
|
|
5
|
+
A review binds to one unit of change: a branch, a pull request, or an
|
|
6
|
+
explicit range. Scaffold resolves and records exact base and head commit
|
|
7
|
+
ids. Everything is read from those commits, so moving the checkout changes
|
|
8
|
+
nothing the reader sees.
|
|
9
|
+
|
|
10
|
+
Choose the base deliberately:
|
|
11
|
+
|
|
12
|
+
- bare scaffold: the trunk fork point (`merge-base` with `origin/HEAD`)
|
|
13
|
+
- one commit: `--base <head>~1 --head <head>`
|
|
14
|
+
- a stack: the branch directly below it
|
|
15
|
+
|
|
16
|
+
`thurview scaffold --update --review <id>` re-pins from the binding: a branch
|
|
17
|
+
follows its local tip, a PR asks GitHub. Publication never moves pins; it
|
|
18
|
+
warns when the branch moved past them.
|
|
19
|
+
|
|
20
|
+
## Statuses
|
|
21
|
+
|
|
22
|
+
| Status | Owner and next action |
|
|
23
|
+
| ------------------------ | -------------------------------------------------------- |
|
|
24
|
+
| `draft` | Agent authors and publishes. |
|
|
25
|
+
| `awaiting-review` | Reader reads, asks, comments, decides. |
|
|
26
|
+
| `awaiting-agent-updates` | Agent addresses threads, resolves them, republishes. |
|
|
27
|
+
| `accepted` | Terminal. Cannot be republished. |
|
|
28
|
+
| `rejected` | Terminal. |
|
|
29
|
+
|
|
30
|
+
"Ask now" does not change the status. "Submit review" with "Request changes"
|
|
31
|
+
sets `awaiting-agent-updates`; with "Approve" sets `accepted`.
|
|
32
|
+
|
|
33
|
+
Dismissal is separate: the reader removes the review from the active list and
|
|
34
|
+
`wait` returns `review-dismissed`. A new publication restores it.
|
|
35
|
+
|
|
36
|
+
## Threads
|
|
37
|
+
|
|
38
|
+
Two kinds, chosen by the reader when creating one:
|
|
39
|
+
|
|
40
|
+
- `ask` mode (a question): delivered at once. `wait` returns `question`.
|
|
41
|
+
Answer with `threads reply`. It stays open until the reader resolves it;
|
|
42
|
+
open questions never block a republish.
|
|
43
|
+
- `review` mode (a comment): held as pending until the reader submits. Then
|
|
44
|
+
`wait` returns `awaiting-agent-updates` with the submitted threads.
|
|
45
|
+
|
|
46
|
+
Targets: a document block (with an optional quoted selection), a file line
|
|
47
|
+
on the base or head side, a map node, or the whole review.
|
|
48
|
+
|
|
49
|
+
`publish` after the first revision requires zero open submitted comment
|
|
50
|
+
threads. Resolve a thread only when its requested change is present. Do not
|
|
51
|
+
rewrite or merge threads.
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
thurview threads list --review <id> [--open]
|
|
55
|
+
thurview threads get <threadId> --review <id>
|
|
56
|
+
thurview threads reply <threadId> --review <id> --body "<text>"
|
|
57
|
+
thurview threads resolve <threadId> --review <id>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Storage
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
${THURVIEW_HOME:-~/.thurview}/
|
|
64
|
+
├── THURVIEW.md user guidance (optional)
|
|
65
|
+
├── server.json running server, if any
|
|
66
|
+
└── reviews/<id>/
|
|
67
|
+
├── review.md you edit
|
|
68
|
+
├── data.yaml you edit
|
|
69
|
+
├── map.yaml you edit
|
|
70
|
+
├── theme.yaml you edit (project look; empty = default skin)
|
|
71
|
+
├── review.json binding, pins, status, presented revision
|
|
72
|
+
├── threads.json threads and decisions (use the CLI)
|
|
73
|
+
└── revisions/<n>/ sealed copies plus compiled document.json, map.json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
A failed publish leaves the last sealed revision in place. The reader can
|
|
77
|
+
switch between revisions in the browser.
|
|
78
|
+
|
|
79
|
+
## wait
|
|
80
|
+
|
|
81
|
+
`thurview wait --review <id> [--timeout <s>]` polls the review and returns
|
|
82
|
+
`wait.reason` in `question`, `awaiting-agent-updates`, `accepted`,
|
|
83
|
+
`rejected`, `review-dismissed`, `review-deleted`, with the threads that need
|
|
84
|
+
you. After the timeout it fails with code `TIMEOUT` (exit 1). A question
|
|
85
|
+
already answered by the agent is not reported again.
|
|
86
|
+
|
|
87
|
+
`thurview threads get <id>` truncates bodies over 1500 characters; pass
|
|
88
|
+
`--full` when the hint says so.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Software map
|
|
2
|
+
|
|
3
|
+
`map.yaml` describes the repository structure at head, and optionally at
|
|
4
|
+
base, as nested nodes. The Map tab lets the reader drill from systems to code
|
|
5
|
+
and shows what the change added, removed or touched.
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
nodes:
|
|
9
|
+
- { id: app, kind: system, label: Review app, description: Local server and UI }
|
|
10
|
+
- { id: app.cli, kind: container, label: CLI, files: ["src/cli.ts"] }
|
|
11
|
+
- { id: app.server, kind: container, label: Server, files: ["src/server/**"] }
|
|
12
|
+
- { id: app.server.threads, kind: component, label: Threads, files: ["src/threads.ts"], anchor: createThread }
|
|
13
|
+
- { id: reader, kind: person, label: Reader }
|
|
14
|
+
edges:
|
|
15
|
+
- { from: reader, to: app.server, label: reviews in the browser }
|
|
16
|
+
- { from: app.cli, to: app.server, label: publishes revisions }
|
|
17
|
+
base: # optional: structure at the base commit
|
|
18
|
+
nodes: [...]
|
|
19
|
+
edges: [...]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Rules:
|
|
23
|
+
|
|
24
|
+
- `id` is a dot path. Every parent must exist as a node (`app` before
|
|
25
|
+
`app.cli`). Identity is the id; keep ids stable between base and head.
|
|
26
|
+
- `kind`: `person`, `system`, `container`, `component`, `code`.
|
|
27
|
+
- `files`: globs relative to the repository root (`*`, `**`, `?`). They link
|
|
28
|
+
the node to changed files in the Files tab. A glob matching nothing at the
|
|
29
|
+
pinned commit is a warning.
|
|
30
|
+
- `anchor`: an anchor id from `data.yaml` that opens representative code.
|
|
31
|
+
- Edges reference node ids. Labels are short verbs.
|
|
32
|
+
|
|
33
|
+
Model the important people, systems, containers, components and code
|
|
34
|
+
elements. Do not model incidental implementation detail. For a large
|
|
35
|
+
repository, keep the top level small and put detail one level down.
|
|
36
|
+
|
|
37
|
+
Work base first, then apply only the structural changes of the diff to get
|
|
38
|
+
head. Without `base`, nodes touched by the diff show as changed and nothing
|
|
39
|
+
shows as added or removed.
|
|
40
|
+
|
|
41
|
+
`thurview publish` validates the map with the document; map errors block
|
|
42
|
+
publication like document errors. An empty `nodes: []` means no map.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Theme
|
|
2
|
+
|
|
3
|
+
A review looks like the project it reviews. `theme.yaml` in the review
|
|
4
|
+
directory carries the tokens; `publish` validates it and seals it with the
|
|
5
|
+
revision. An empty or absent file gives the default skin.
|
|
6
|
+
|
|
7
|
+
## Decide the look, in this order
|
|
8
|
+
|
|
9
|
+
Move to the next step only when the current one yields nothing.
|
|
10
|
+
|
|
11
|
+
1. The user asked for a specific look or named a design system: use that.
|
|
12
|
+
2. Inspect the reviewed project at the head commit and match its own design
|
|
13
|
+
system: a Tailwind or theme config, CSS custom properties or design
|
|
14
|
+
tokens, a component library theme, brand assets, an existing styled page
|
|
15
|
+
or website directory, font files it ships. Read the real values; do not
|
|
16
|
+
guess. Record what you read in `source`.
|
|
17
|
+
3. Nothing found: keep the default skin. Do not invent a palette.
|
|
18
|
+
|
|
19
|
+
State which of the three you used when you hand over the review.
|
|
20
|
+
|
|
21
|
+
## theme.yaml
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
name: acme-web # shown in the review menu
|
|
25
|
+
source: tailwind.config.ts, src/styles/tokens.css
|
|
26
|
+
mode: light # dark (default) or light
|
|
27
|
+
|
|
28
|
+
colors: # any CSS color; every key optional
|
|
29
|
+
bg: "#ffffff" # page
|
|
30
|
+
bg2: "#f6f7f9" # panels, bars
|
|
31
|
+
bg3: "#eef0f3" # hover
|
|
32
|
+
code: "#f8fafc" # code surfaces
|
|
33
|
+
fg: "#111827" # text
|
|
34
|
+
fg2: "#4b5563" # secondary text
|
|
35
|
+
muted: "#9ca3af"
|
|
36
|
+
line: "#e5e7eb" # borders
|
|
37
|
+
accent: "#2563eb" # headings, primary actions, status
|
|
38
|
+
link: "#2563eb" # links and anchor links
|
|
39
|
+
ok: "#16a34a"
|
|
40
|
+
warn: "#d97706"
|
|
41
|
+
del: "#dc2626"
|
|
42
|
+
add: "rgb(22 163 74 / .12)" # added-line background
|
|
43
|
+
remove: "rgb(220 38 38 / .12)" # deleted-line background
|
|
44
|
+
select: "rgb(217 119 6 / .18)" # highlighted-line background
|
|
45
|
+
|
|
46
|
+
fonts:
|
|
47
|
+
display: "Inter, sans-serif" # brand, buttons, document headings
|
|
48
|
+
body: "Inter, sans-serif"
|
|
49
|
+
mono: "'JetBrains Mono', monospace"
|
|
50
|
+
stylesheets: # external font css, loaded by the page
|
|
51
|
+
- https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap
|
|
52
|
+
files: # font files the project ships, read at head
|
|
53
|
+
- { family: Acme Sans, path: web/public/fonts/acme-sans.woff2, weight: "400 700" }
|
|
54
|
+
|
|
55
|
+
shape:
|
|
56
|
+
radius: 8px # 0 in the default skin
|
|
57
|
+
bevel: false # pixel bevels on panels and buttons
|
|
58
|
+
glow: false # neon text glow on headings and tabs
|
|
59
|
+
scanlines: false # CRT overlay
|
|
60
|
+
headingTransform: none # uppercase in the default skin
|
|
61
|
+
|
|
62
|
+
code: # syntax palette; any key optional
|
|
63
|
+
keyword: "#7c3aed"
|
|
64
|
+
string: "#15803d"
|
|
65
|
+
function: "#b45309"
|
|
66
|
+
type: "#b45309"
|
|
67
|
+
variable: "#0369a1"
|
|
68
|
+
number: "#b45309"
|
|
69
|
+
comment: "#9ca3af"
|
|
70
|
+
punctuation: "#6b7280"
|
|
71
|
+
operator: "#374151"
|
|
72
|
+
tag: "#be185d"
|
|
73
|
+
fg: "#111827"
|
|
74
|
+
|
|
75
|
+
css: | # optional extra rules, appended last
|
|
76
|
+
.doc h1 { letter-spacing: 0; }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Rules:
|
|
80
|
+
|
|
81
|
+
- Keep contrast readable: body text against `bg`, code against `code`.
|
|
82
|
+
- A light project gets `mode: light` and light backgrounds; the default skin
|
|
83
|
+
is dark and its bevels, glow and scanlines are off by default only when you
|
|
84
|
+
set them so.
|
|
85
|
+
- `fonts.files` paths must exist at the pinned head commit; `publish`
|
|
86
|
+
rejects a missing one. Font stylesheets are fetched by the reader's
|
|
87
|
+
browser.
|
|
88
|
+
- Map the project's semantic roles, not its whole palette: primary to
|
|
89
|
+
`accent` and `link`, success/warning/danger to `ok`/`warn`/`del`.
|
|
90
|
+
- Unknown keys fail validation.
|