thurview 0.12.0 → 0.13.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": "thurview",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Guided, evidence-anchored reviews of agent-written code. A coding agent authors the review; you read, ask, comment and decide in the browser.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: thurview
3
- description: Author and publish a thurview document - a guided, evidence-anchored explanation the reader opens in the browser, annotates, asks questions about, and approves or sends back. Two kinds — a review of a branch, pull request or commit range, and a code explainer of a whole codebase or one subsystem at a pinned commit. 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 where its design problems might be, or invokes /thurview. Not for a pass/fail bug hunt.
3
+ description: Author and publish a thurview document - a guided, evidence-anchored explanation the reader opens in the browser, annotates, asks questions about, and approves or sends back. Two kinds — a review of a branch, pull request or commit range, and a code explainer of a whole codebase or one subsystem at a pinned commit. For a design, an architecture proposal or an implementation plan — a change not written yet — use the thurview-design skill instead. 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 where its design problems might be, or invokes /thurview. Not for a pass/fail bug hunt.
4
4
  user-invocable: true
5
5
  argument-hint: "[<pr-number|pr-url> | --base <ref> --head <ref> | explain [<path>]]"
6
6
  ---
7
7
 
8
8
  # thurview
9
9
 
10
- There are two kinds of document, and the first decision is which one the
10
+ There are three kinds of document, and the first decision is which one the
11
11
  request asks for.
12
12
 
13
13
  - A **review** explains a CHANGE: a branch, a pull request, a commit range. It
@@ -18,6 +18,12 @@ request asks for.
18
18
  design problems themselves. It has no diff and nothing to approve, and it
19
19
  states what it did not examine. Read
20
20
  [Code explainer](references/code-explainer.md) and follow that instead.
21
+ - A **design** explains a change that is NOT WRITTEN YET: a design, an
22
+ architecture proposal, an implementation plan. It is pinned to the one commit
23
+ it argues from, its anchors are the code as it stands, and what it would
24
+ build is declared as a proposal attached to the code that proposal lands in.
25
+ It is a separate skill — `thurview-design`, installed beside this one; run
26
+ `thurview skill` for its path. Stop here and read that instead.
21
27
 
22
28
  Reviewing a change and fixing what the review finds - and posting what stays
23
29
  unfixed to a pull or merge request - is the `review-fix` skill, not this one.
@@ -61,7 +67,9 @@ Empty: a review of the current branch against its up-to-date trunk. A PR
61
67
  number or URL: that pull request. `--base`/`--head`: that range. `explain`, or
62
68
  a request to explain the codebase, a subsystem or its architecture rather than
63
69
  a change: a code explainer, per
64
- [Code explainer](references/code-explainer.md).
70
+ [Code explainer](references/code-explainer.md). A request for how something
71
+ _should_ be built rather than what was built: a design, per the
72
+ `thurview-design` skill.
65
73
 
66
74
  ## Before authoring
67
75
 
@@ -321,6 +329,13 @@ author, publish, wait, answer - over a document kind whose unit is a codebase:
321
329
  no diff, no commits, no interface delta, and a Coverage tab stating what the
322
330
  document reached and what it did not.
323
331
 
332
+ ## Designing a change rather than reviewing one
333
+
334
+ Same trap, same answer. A plan pinned as a review claims a diff that does not
335
+ exist. Run `thurview design [<path>]` and follow the `thurview-design` skill:
336
+ one pinned commit, anchors on the code as it stands, and what the design would
337
+ build declared as proposals the reader approves or sends back.
338
+
324
339
  ## Completion criteria
325
340
 
326
341
  Report completion only when all of these hold:
@@ -0,0 +1,265 @@
1
+ ---
2
+ name: thurview-design
3
+ description: Author and publish a thurview design document - a design, architecture proposal or implementation plan the reader opens in the browser, annotates, asks questions about, and approves or sends back. Every claim about the code as it stands is anchored to a file and line range at a pinned commit, and what the design would build is declared as a proposal attached to the code it lands in. Use when the user asks for a design or architecture document, an implementation plan, an RFC or a technical proposal, asks how something should be built, asks to review or sign off a plan, or invokes /thurview-design. Not for reviewing a change that is already written, which is the thurview skill.
4
+ user-invocable: true
5
+ argument-hint: "[<path scope>] [what to design]"
6
+ ---
7
+
8
+ # thurview design
9
+
10
+ A **design document** says what should be built and why, argued against the
11
+ code as it stands. It is the third thurview document kind, beside a review of a
12
+ change and an explainer of a codebase, and it is read in the same browser
13
+ surface: anchored code peeks, a map, threads, revisions, and a decision that is
14
+ **Approve the design** or **Send it back**.
15
+
16
+ thurview is evidence-anchored, so the whole kind turns on one rule. Read
17
+ [Anchors and proposals](references/anchors-and-proposals.md) before you write
18
+ anything. The short version:
19
+
20
+ > **An anchor is evidence, never a proposal.** Every anchor in a design
21
+ > document resolves to real code at the one pinned commit — what the design
22
+ > changes, and what constrains it. Code the design would write is declared as a
23
+ > **proposal**, and a proposal names the **site**: the anchor of the code it
24
+ > lands in, replaces or plugs into today.
25
+
26
+ A design that lands nowhere in today's code has nothing thurview can anchor.
27
+ Say so and write ordinary prose instead; do not pin a commit to get a page.
28
+
29
+ ```mermaid
30
+ flowchart LR
31
+ A[design: pin the commit it argues from] --> B[study the code as it stands]
32
+ B --> C[author review.md, data.yaml, map.yaml]
33
+ C --> D[publish: validate anchors, seal a revision]
34
+ D --> E[open: reader reads and annotates]
35
+ E -->|question| F[threads reply]
36
+ F --> E
37
+ E -->|send it back| C
38
+ E -->|approve the design| G[build it]
39
+ ```
40
+
41
+ Run the CLI as `thurview`; `npx -y thurview` runs the published package with
42
+ the same commands. Every command prints TOON on stdout — the result, then
43
+ `help[]` with the next commands. Errors are structured on stdout too (`error`,
44
+ `code`, `help`); exit 1 is a failure, 2 a usage error. If a command answers
45
+ `unknown command` for something this skill tells you to run, the installed CLI
46
+ is older than the skill: run `thurview update`, retry once, then report it.
47
+
48
+ ## Request
49
+
50
+ $ARGUMENTS
51
+
52
+ A path scope narrows the design to one part of the system; with none it is the
53
+ whole repository. The rest of the request is what to design.
54
+
55
+ ## Which kind is this
56
+
57
+ | The request is about | Kind | Skill |
58
+ | ------------------------------------------------------------- | ---------- | ---------------------------------------- |
59
+ | code that is written — a branch, a PR, a range | review | `thurview` |
60
+ | code that exists, explained — "how does this work" | explainer | `thurview`, its code-explainer reference |
61
+ | code that is **not written yet** — "how should we build this" | **design** | this one |
62
+
63
+ A plan for work already done is a review. An explanation with a
64
+ recommendation stapled on is an explainer that broke its own rule. If the
65
+ request is genuinely "explain this, then propose a change", write the design:
66
+ its anchors carry the explanation and its proposals carry the change.
67
+
68
+ ## Before authoring
69
+
70
+ Read the guidance files that exist, in this order; the second wins on conflict.
71
+
72
+ 1. `~/.thurview/THURVIEW.md` (or `$THURVIEW_HOME/THURVIEW.md`), user guidance.
73
+ 2. `THURVIEW.md` at the repository root, repository guidance.
74
+
75
+ `thurview design` lists the ones it found under `guidance`.
76
+
77
+ The `thurview` skill ships the references this one shares — components,
78
+ software map, theme, lifecycle. `thurview skill` prints the path of every
79
+ bundled SKILL.md; the references sit beside each one. Read **Components**
80
+ before you edit `data.yaml`, **Software map** before you author `map.yaml`,
81
+ **Theme** before you write `theme.yaml`, and **Lifecycle** for statuses,
82
+ storage and thread rules — they are identical for all three kinds.
83
+
84
+ ## Workflow
85
+
86
+ ### 1. Pin the commit the design argues from
87
+
88
+ ```sh
89
+ thurview design # the whole repository at HEAD
90
+ thurview design src/server # one part of it
91
+ thurview design --commit v1.2.0 # a released commit rather than HEAD
92
+ ```
93
+
94
+ A design is pinned to **one** commit: the code as it stands, which the design
95
+ changes. An active design on the same scope is reused and re-pinned
96
+ (`design.reused` is true); `--new` starts a separate one, and
97
+ `thurview design --update --review <id>` re-pins after the branch moves.
98
+
99
+ Record `design.id`, `design.dir`, `design.commit`, `design.scope`,
100
+ `scale.filesInScope`, `files.*` and `guidance`. Everywhere else the id is
101
+ passed as `--review <id>`; that flag names a document, whichever kind it is.
102
+
103
+ ### 2. Study what the design has to fit
104
+
105
+ The design is an argument about a system, so read the system before proposing
106
+ anything. The code graph is the fastest way in, and it is the same graph the
107
+ reader can re-derive:
108
+
109
+ ```sh
110
+ thurview graph architecture --review <id> # clusters in the scope, their hubs, the edges between them
111
+ thurview graph callers <symbol> --review <id> # who depends on what you plan to change
112
+ thurview graph tests-for <symbol> --review <id> # what would have to move with it
113
+ ```
114
+
115
+ `graph interfaces` and `graph impact` compare two commits and are refused here:
116
+ there is one. The graph covers TypeScript, JavaScript, Python, Go, Rust, Java
117
+ and Elixir; other files are absent from it, not empty, and `truncated` means
118
+ the answer is partial.
119
+
120
+ Read every range you intend to anchor from the pinned commit itself —
121
+ `git show <commit>:<path>` — not from the working tree.
122
+
123
+ ### 3. Decide what it proposes, and anchor each proposal to its site
124
+
125
+ This is the step the kind exists for. In `data.yaml`, under `interfaces`, write
126
+ one entry per interface the design would **add, change or remove**:
127
+
128
+ ```yaml
129
+ anchors:
130
+ dispatch:
131
+ title: where a request picks its handler today
132
+ peek: { file: src/server/router.ts, from: 41, to: 58 }
133
+
134
+ interfaces:
135
+ routeTable:
136
+ name: Router.register(path, handler)
137
+ change: added
138
+ capability: A feature registers its own route instead of editing the switch.
139
+ anchor: dispatch
140
+ ```
141
+
142
+ - `name` is what a consumer would type or call. `change` is what the design
143
+ would do to it. `capability` is what it lets somebody do, in their words, not
144
+ a restatement of the signature.
145
+ - `anchor` is the **site**: real code at the pinned commit that this proposal
146
+ lands in, replaces or plugs into. It must resolve and it must have a `peek`.
147
+ - A `symbol:` entry is refused. That shape annotates a row the code graph
148
+ derived from a diff, and a design has none.
149
+ - **A design with no entry here is refused.** A document that proposes nothing
150
+ is an explainer; write one of those instead.
151
+
152
+ The panel above the document states these as `Proposed: 2 added, 1 changed.`,
153
+ in the slot a review gives the interface delta. Do not repeat the list in
154
+ prose — explain the ones whose consequence is not obvious.
155
+
156
+ ### 4. Author the document
157
+
158
+ Edit `review.md` in the design directory. Keep it short; a design nobody
159
+ finishes is a design nobody decided on. A shape that works:
160
+
161
+ 1. **What we are trying to do** — the problem, in the requester's terms.
162
+ 2. **How it works today** — anchored. Every sentence about current behaviour
163
+ links to the code with `[text](anchor:<id>)` or shows it with a `peek`
164
+ fence. This is what makes a design arguable rather than assertible.
165
+ 3. **What to build** — the proposals in step 3, with the reasoning the panel
166
+ cannot carry.
167
+ 4. **What it costs** — what has to move, what breaks, what is left out. Use
168
+ `thurview graph callers` for the blast radius rather than guessing it.
169
+ 5. **What was considered and dropped**, with the reason. This is the section
170
+ readers send a design back for missing.
171
+
172
+ **Proposed code goes in a plain fenced block, never in a peek.** A peek is
173
+ code that exists at the pinned commit; a plain fence is a sketch. The reader
174
+ tells them apart at a glance, and that difference is the whole trust model.
175
+
176
+ Sequence diagrams work for a proposed flow: give a message a `code:` string
177
+ rather than an `anchor:` where the code does not exist yet, and an `anchor:`
178
+ where it does. See the `thurview` skill's Components reference for the shape.
179
+
180
+ ### 5. Map the shape, when there is one
181
+
182
+ The Map tab is where a design shows structure. Put the structure it
183
+ **proposes** under `nodes`/`edges` and the structure **as it stands** under
184
+ `base`, and the reader sees exactly what the design adds, changes and removes.
185
+
186
+ - A node under `nodes` may own files that do not exist yet. That is a proposed
187
+ part, and publish does not warn about it.
188
+ - A node under `base` may not. It is a claim about today, and publish warns
189
+ when its globs match nothing at the pinned commit.
190
+ - Seed `base` from `thurview graph architecture --review <id>`.
191
+
192
+ A design that changes one part in place does not raise the question: leave
193
+ `nodes: []` and say so in the handover.
194
+
195
+ ### 6. Theme, then publish
196
+
197
+ Write `theme.yaml` per the `thurview` skill's Theme reference, or leave it
198
+ empty for the default skin. Then:
199
+
200
+ ```sh
201
+ thurview publish --review <id>
202
+ ```
203
+
204
+ Read every row of `diagnostics`. Fix each `error` and publish again; a
205
+ `warning` does not block. On success, `published.proposes` is the verdict the
206
+ reader sees above the document, and `published.url` is the page.
207
+
208
+ ```sh
209
+ thurview open --review <id>
210
+ ```
211
+
212
+ ### 7. Hand over
213
+
214
+ In a few lines, and nothing more: the `url`; the commit and scope it argues
215
+ from; `published.proposes` in its own words; what the design deliberately
216
+ leaves out; whether there is a map and why not if there is none; and that you
217
+ are waiting for their questions and their decision. The page explains its own
218
+ controls.
219
+
220
+ ### 8. Wait, answer, revise
221
+
222
+ ```sh
223
+ thurview wait --review <id> --timeout <seconds>
224
+ ```
225
+
226
+ Identical to a review. `wait.reason` is `question` (answer each thread with
227
+ `thurview threads reply <threadId> --review <id> --body "<answer>"`, then wait
228
+ again), `awaiting-agent-updates` (the reader sent it back — revise, resolve
229
+ each thread you addressed, publish, wait again), `accepted` (approved — report
230
+ and stop), `closed`, `review-dismissed`, `review-deleted`, or `timeout`.
231
+
232
+ Keep `--timeout` under your shell tool's own limit and run it again on
233
+ `timeout`. Do not loop it to look present: a question asked with nobody waiting
234
+ is queued, not lost.
235
+
236
+ **An approved design is a decision, not a diff.** Building it is separate work:
237
+ a review of the branch that implements it, with the `thurview` skill.
238
+
239
+ ## Surface the trade-off; do not hide it
240
+
241
+ A design is a recommendation, so unlike an explainer it is allowed a verdict —
242
+ but only on the choice, never dressed up as a fact. Keep the two apart:
243
+
244
+ - Fact, anchored: "`Router.dispatch` is referenced from 14 places, none of them
245
+ in tests." Anchor it and the reader can check it.
246
+ - Judgement, labelled: "So I would register routes rather than extend the
247
+ switch, and pay one indirection for it."
248
+
249
+ A design with no stated cost and no rejected alternative reads as advocacy, and
250
+ readers approve it without deciding anything — which is the failure this whole
251
+ document kind exists to prevent.
252
+
253
+ ## Completion criteria
254
+
255
+ Report completion only when all of these hold:
256
+
257
+ - The reader has the URL of a published revision.
258
+ - Every `error` diagnostic is resolved.
259
+ - Every proposal names a site in today's code, and every anchor resolves.
260
+ - The map is published, or you said why it is not.
261
+ - The design is waiting on the reader, accepted, closed, dismissed or deleted.
262
+
263
+ Close with the decision and its summary (`wait.decision`) and the URL. When the
264
+ reader has not responded, say so and leave it open; a later session picks it up
265
+ from `thurview` in the same worktree.
@@ -0,0 +1,90 @@
1
+ # Anchors and proposals
2
+
3
+ thurview's one promise is that a claim about code can be opened. An anchor is a
4
+ file and a line range at a pinned commit; the reader clicks it and sees the
5
+ code. A review and an explainer both keep that promise trivially, because the
6
+ code they describe is written.
7
+
8
+ A design describes code that is **not written yet**. This file is how the kind
9
+ keeps the same promise anyway.
10
+
11
+ ## The rule
12
+
13
+ > **An anchor is evidence, never a proposal.**
14
+ >
15
+ > Every anchor in a design document resolves to real code at the one pinned
16
+ > commit. Code the design would write is not anchored. It is declared as a
17
+ > **proposal**, and the proposal names the **site** — the anchor of the code it
18
+ > lands in, replaces or plugs into today.
19
+
20
+ So an anchor means exactly one thing in all three kinds, and the reader never
21
+ has to ask which sort of anchor they are looking at. One anchor that resolves
22
+ to nothing would put that question on every other anchor in the document.
23
+
24
+ ## What this buys, concretely
25
+
26
+ | The design says | How it is carried | What the reader can do |
27
+ | ---------------------------------------------- | ---------------------------------------------------- | --------------------------------------------- |
28
+ | "today the router picks a handler in a switch" | anchor with a `peek` | open the switch |
29
+ | "we would add `Router.register`" | proposal, `change: added`, anchored at the switch | open the code it replaces |
30
+ | "it would look roughly like this" | plain fenced code block in `review.md` | read it as a sketch, because it is not a peek |
31
+ | "these fourteen callers move" | anchor per caller, or the count from `graph callers` | check the count |
32
+
33
+ ## The refusals, and why each one is there
34
+
35
+ `thurview publish` refuses a design that breaks the rule. Each message says
36
+ why; these are the reasons behind them.
37
+
38
+ - **`graph: base` on an anchor.** A design has one pinned commit. A base-graph
39
+ anchor would resolve against a commit the document never named.
40
+ - **A `symbol:` interface entry.** That shape annotates a row the code graph
41
+ derived from a diff. A design has no diff, so there is no derived row, and an
42
+ annotation with nothing under it is an assertion wearing a badge.
43
+ - **A design that proposes nothing.** A document with no `interfaces` entry is
44
+ prose about the code as it stands. That is an explainer, and it should be one
45
+ — the reader of a design is being asked to approve something.
46
+ - **A proposal whose anchor does not resolve, or has no `peek`.** The site is
47
+ the whole point of the entry. Without it the proposal floats.
48
+
49
+ The map follows the same line, in its own terms: a node under `base` whose
50
+ `files` globs match nothing at the pinned commit is a wrong claim about today
51
+ and gets a warning, while a node under `nodes` that owns no file yet is a
52
+ proposed part and gets none.
53
+
54
+ ## The boundary of the kind
55
+
56
+ **Greenfield is out of scope.** A design that lands nowhere in an existing
57
+ codebase has no site to anchor and nothing for the reader to check against.
58
+ thurview would give it a nice page and no evidence, which is worse than a
59
+ markdown file, because the page implies evidence.
60
+
61
+ When the request is greenfield, say that, and write ordinary prose. When it is
62
+ mostly greenfield with one integration point, the integration point is the
63
+ site: anchor there, and be honest in the document that the rest is unanchored.
64
+
65
+ ## Writing a proposal that earns its entry
66
+
67
+ Each entry is one line in the panel above the document, so it has to be worth
68
+ the reader's attention.
69
+
70
+ ```yaml
71
+ interfaces:
72
+ routeTable:
73
+ name: Router.register(path, handler)
74
+ change: added
75
+ capability: A feature registers its own route instead of editing the switch.
76
+ anchor: dispatch
77
+ ```
78
+
79
+ - `name` is what a consumer types or calls — a signature, a CLI flag, an HTTP
80
+ route, a config key, a file format. Not a component name, not a task.
81
+ - `change` is `added`, `changed` or `removed`. `removed` is the entry a reader
82
+ must not miss, and the panel sorts it first.
83
+ - `capability` is what somebody can now do, in their words. "Adds a register
84
+ method" is the signature again; "a feature registers its own route instead of
85
+ editing the switch" is the reason the design exists.
86
+ - `anchor` is the site, and it is what makes the entry checkable.
87
+
88
+ One entry per interface, not one per task. An implementation plan with eleven
89
+ steps and two interface changes has two entries; the eleven steps are prose,
90
+ and the reader decides on the two.