visualproof 0.0.0-stage → 0.2.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 +202 -0
- package/README.md +99 -2
- package/dist/assets/fonts/JuliaMono-Regular.ttf +0 -0
- package/dist/assets/fonts/JuliaMono-RegularItalic.ttf +0 -0
- package/dist/assets/fonts/JuliaMono-SemiBold.ttf +0 -0
- package/dist/assets/fonts/LICENSE-JuliaMono.txt +93 -0
- package/dist/assets/latex/visualproof.sty +308 -0
- package/dist/assets/webfonts/LICENSE-Jost.txt +93 -0
- package/dist/assets/webfonts/LICENSE-SourceSans3.txt +93 -0
- package/dist/assets/webfonts/LICENSE-SourceSerif4.txt +93 -0
- package/dist/assets/webfonts/jost-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/webfonts/jost-latin-wght-normal.woff2 +0 -0
- package/dist/assets/webfonts/source-sans-3-greek-wght-italic.woff2 +0 -0
- package/dist/assets/webfonts/source-sans-3-greek-wght-normal.woff2 +0 -0
- package/dist/assets/webfonts/source-sans-3-latin-ext-wght-italic.woff2 +0 -0
- package/dist/assets/webfonts/source-sans-3-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/webfonts/source-sans-3-latin-wght-italic.woff2 +0 -0
- package/dist/assets/webfonts/source-sans-3-latin-wght-normal.woff2 +0 -0
- package/dist/assets/webfonts/source-serif-4-greek-wght-italic.woff2 +0 -0
- package/dist/assets/webfonts/source-serif-4-greek-wght-normal.woff2 +0 -0
- package/dist/assets/webfonts/source-serif-4-latin-ext-wght-italic.woff2 +0 -0
- package/dist/assets/webfonts/source-serif-4-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/webfonts/source-serif-4-latin-wght-italic.woff2 +0 -0
- package/dist/assets/webfonts/source-serif-4-latin-wght-normal.woff2 +0 -0
- package/dist/extractor/Extract.lean +1180 -0
- package/dist/extractor/Usage.lean +900 -0
- package/dist/mcp/visualproof-mcp.mjs +476 -0
- package/dist/server/access.js +95 -0
- package/dist/server/agent.js +3270 -0
- package/dist/server/agentdocs.js +35 -0
- package/dist/server/agentlibrary.js +202 -0
- package/dist/server/agentnotes.js +701 -0
- package/dist/server/agentviews.js +703 -0
- package/dist/server/askfollow.js +286 -0
- package/dist/server/boardspots.js +159 -0
- package/dist/server/dirs.js +175 -0
- package/dist/server/doctor.js +186 -0
- package/dist/server/events.js +198 -0
- package/dist/server/export.js +420 -0
- package/dist/server/extract.js +204 -0
- package/dist/server/fetchurl.js +321 -0
- package/dist/server/figures.js +158 -0
- package/dist/server/history.js +780 -0
- package/dist/server/historyapi.js +304 -0
- package/dist/server/hover.js +595 -0
- package/dist/server/identity.js +114 -0
- package/dist/server/invites.js +241 -0
- package/dist/server/layoutthread.js +51 -0
- package/dist/server/library.js +600 -0
- package/dist/server/libraryroute.js +211 -0
- package/dist/server/live.js +1101 -0
- package/dist/server/lostfound.js +199 -0
- package/dist/server/main.js +1406 -0
- package/dist/server/mcptools.js +496 -0
- package/dist/server/pastdoc.js +73 -0
- package/dist/server/pipeline.js +159 -0
- package/dist/server/poppler.js +251 -0
- package/dist/server/presence.js +252 -0
- package/dist/server/project.js +222 -0
- package/dist/server/prompt.js +53 -0
- package/dist/server/readonly.js +152 -0
- package/dist/server/readonlygate.js +123 -0
- package/dist/server/renames.js +268 -0
- package/dist/server/review.js +334 -0
- package/dist/server/reviewapi.js +188 -0
- package/dist/server/snapshot.js +50 -0
- package/dist/server/sourcestore.js +473 -0
- package/dist/server/status.js +360 -0
- package/dist/server/talk.js +476 -0
- package/dist/server/tokens.js +221 -0
- package/dist/server/usage.js +501 -0
- package/dist/server/versions.js +82 -0
- package/dist/server/view.js +164 -0
- package/dist/server/views.js +1167 -0
- package/dist/shared/askfollow.js +46 -0
- package/dist/shared/board.js +332 -0
- package/dist/shared/build.js +2 -0
- package/dist/shared/collab.js +241 -0
- package/dist/shared/comment.js +285 -0
- package/dist/shared/context.js +157 -0
- package/dist/shared/doc/authors.js +98 -0
- package/dist/shared/doc/build.js +358 -0
- package/dist/shared/doc/latex.js +455 -0
- package/dist/shared/doc/markdown.js +159 -0
- package/dist/shared/doc/model.js +37 -0
- package/dist/shared/doc/order.js +124 -0
- package/dist/shared/doc/outline.js +45 -0
- package/dist/shared/doc/proof.js +272 -0
- package/dist/shared/doc/sections.js +93 -0
- package/dist/shared/doc/settings.js +75 -0
- package/dist/shared/edgecodec.js +102 -0
- package/dist/shared/editor.js +64 -0
- package/dist/shared/excerpt.js +87 -0
- package/dist/shared/graph.js +16 -0
- package/dist/shared/items.js +92 -0
- package/dist/shared/keys.js +203 -0
- package/dist/shared/layout.js +926 -0
- package/dist/shared/lexer.js +130 -0
- package/dist/shared/library.js +711 -0
- package/dist/shared/lostfound.js +150 -0
- package/dist/shared/moves.js +244 -0
- package/dist/shared/notecard.js +295 -0
- package/dist/shared/noteplace.js +505 -0
- package/dist/shared/palette.js +46 -0
- package/dist/shared/pastgraph.js +103 -0
- package/dist/shared/places.js +80 -0
- package/dist/shared/projectnotes.js +244 -0
- package/dist/shared/query.js +818 -0
- package/dist/shared/review.js +642 -0
- package/dist/shared/reviewqueue.js +333 -0
- package/dist/shared/ring.js +366 -0
- package/dist/shared/scope.js +255 -0
- package/dist/shared/scopeedit.js +81 -0
- package/dist/shared/search.js +191 -0
- package/dist/shared/separate.js +178 -0
- package/dist/shared/sharesnap.js +281 -0
- package/dist/shared/sticky.js +501 -0
- package/dist/shared/timeline.js +73 -0
- package/dist/shared/titles.js +300 -0
- package/dist/shared/viewgraph.js +157 -0
- package/dist/shared/views.js +859 -0
- package/dist/web/bundle/app.js +52671 -0
- package/dist/web/bundle/edges.js +407 -0
- package/dist/web/bundle/layout.js +1010 -0
- package/dist/web/bundle/pdfworker.js +48322 -0
- package/dist/web/index.html +257 -0
- package/dist/web/src/motion.js +430 -0
- package/dist/web/src/past.js +224 -0
- package/dist/web/src/scene.js +804 -0
- package/dist/web/style.css +2548 -0
- package/docs/agent-api/README.md +91 -0
- package/docs/agent-api/advice.md +108 -0
- package/docs/agent-api/export.md +120 -0
- package/docs/agent-api/following.md +140 -0
- package/docs/agent-api/history.md +142 -0
- package/docs/agent-api/library.md +65 -0
- package/docs/agent-api/mcp.md +104 -0
- package/docs/agent-api/notes.md +93 -0
- package/docs/agent-api/reading.md +166 -0
- package/docs/agent-api/requests.md +94 -0
- package/docs/agent-api/talking.md +100 -0
- package/docs/agent-api/tcb.md +135 -0
- package/docs/agent-api/views.md +125 -0
- package/docs/agent-api/words.md +56 -0
- package/package.json +39 -4
- package/test/toolchains.json +5 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Targets and their TCB
|
|
2
|
+
|
|
3
|
+
Targets, the members of a target's TCB that need review, its key declarations, why something is in
|
|
4
|
+
a TCB, and references (`uses`, `users`): any level. Then marking targets and keys, and trust (needs
|
|
5
|
+
full). Terms: [Words](words.md). MCP: `review` (actions `targets`, `tcb`, `keys`, `why`); `refs`
|
|
6
|
+
(actions `uses`, `users`); `mark` (actions `target`, `key`); `trust`.
|
|
7
|
+
|
|
8
|
+
## `GET /api/agent/targets`
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
{"targets": [{"name": "Hilbert91", "markedBy": "Bob", "at": "…", "inGraph": true,
|
|
12
|
+
"counts": {"needReview": 16, "approved": 1, "commented": 0, "stale": 0, "unreviewed": 15,
|
|
13
|
+
"advised": 2, "agentComments": 0, "advisedByYou": 2,
|
|
14
|
+
"key": {"total": 4, "approved": 1, "commented": 0, "stale": 0, "unreviewed": 3}}},
|
|
15
|
+
{"name": "FltRegular.caseI", "markedBy": "Alice's AI", "markedByAgent": true, …}, …]}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`approved` … `unreviewed`: people's statuses, summing to `needReview`. `advised`, `agentComments`,
|
|
19
|
+
`advisedByYou`: agents' advice on present versions, counted apart. `key`: the second level of
|
|
20
|
+
progress, the target's key declarations (the target among them).
|
|
21
|
+
|
|
22
|
+
## `GET /api/agent/tcb?target=&include=&todo=&key=&offset=&limit=`
|
|
23
|
+
|
|
24
|
+
The members of `target`'s TCB that need review, in review order; any declaration may be the target
|
|
25
|
+
(`isTarget`: whether it is marked). `limit` 1–500, default 50; `next`: the next `offset`, null at
|
|
26
|
+
the end.
|
|
27
|
+
|
|
28
|
+
| parameter | effect |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `todo=1` | only members you have not advised on in their present version (to resume a pre-review); with `include=review` only; 400 if you do not say who you are |
|
|
31
|
+
| `key=first`, `key=only` | key declarations first, then the rest; or key declarations alone (the review list's ◆ Key); each in review order |
|
|
32
|
+
| `include` | `review` (default); `trusted`: the trusted members; `all`: those needing review, then the trusted, `position` counting within each |
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{"target": "Hilbert91", "isTarget": true, "order": "review: …", "counts": {"needReview": 16, …},
|
|
36
|
+
"trustedNotCounted": 195, "axioms": [], "include": "review", "offset": 0, "limit": 50, "total": 16, "next": null,
|
|
37
|
+
"members": [{"position": 2, "name": "RelativeUnits", "kind": "def", "module": "…", "key": true,
|
|
38
|
+
"status": "approved", "advice": [], "youAdvised": false},
|
|
39
|
+
{"position": 7, …, "advice": [{"by": "Claude", "verdict": "approve"}], "youAdvised": true}, …]}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- `position`: place in the whole review order (also with `todo`, `key`); `total`: what the filter
|
|
43
|
+
keeps. The target comes last. `counts.key` counts the `key: true` members by status.
|
|
44
|
+
- No "next to review", for people or agents: the review set is read as a list.
|
|
45
|
+
- `axioms`: every axiom beyond the three standard ones the target rests on, through statements,
|
|
46
|
+
bodies or proofs, as `#print axioms` finds them (`sorryAx` included); each
|
|
47
|
+
`{name, inGraph, status, usedIn}`, `usedIn` the declarations using it. They need review whatever
|
|
48
|
+
is trusted, come first, count in `needReview`; `why` answers `inTcb: false, inReview: true` and
|
|
49
|
+
`usedIn` for them.
|
|
50
|
+
- `include=trusted`: each member's `trustedBy`, the prefixes covering it (`"@external"`: the whole
|
|
51
|
+
outside world) or `"standard axiom"`; the project's own first, then by prefix, then by name.
|
|
52
|
+
`trusted` sums them: `{project, external, byPrefix: {"Init": 6, …}}`.
|
|
53
|
+
|
|
54
|
+
## `GET /api/agent/keys?target=&members=`
|
|
55
|
+
|
|
56
|
+
A target's key declarations top-down: the target, then each a layer below every key declaration
|
|
57
|
+
resting on it (within a layer, later in review order first). Each with `doc`, `restsOn` (the key
|
|
58
|
+
declarations it rests on directly) and its `support` (members it reaches through non-key members)
|
|
59
|
+
by status; plus the key graph's `edges`. `members=0`: support counts only, no names.
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{"target": "Hilbert91", "isTarget": true, "order": "top-down: …", "note": "…",
|
|
63
|
+
"counts": {"key": {"total": 4, "approved": 1, …}, "all": {"total": 16, …}, "offBoardAxioms": 0},
|
|
64
|
+
"keys": [{"name": "Hilbert91", "target": true, "status": "none", "doc": null, "restsOn": ["RelativeUnits", …], …},
|
|
65
|
+
{"name": "systemOfUnits.IsFundamental", "kind": "def", "markedBy": "Alice", "markedAt": "…", "restsOn": ["systemOfUnits"],
|
|
66
|
+
"support": {"total": 5, "unreviewed": 5, …, "members": ["CyclotomicIntegers", …]}, …}, …],
|
|
67
|
+
"edges": [["systemOfUnits.IsFundamental", "systemOfUnits"], …], "viaProof": []}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`viaProof`: non-standard axioms the target rests on through proofs alone (no statement or body
|
|
71
|
+
reaches them), part of its support. `marksOutsideReview`, when any: marks on declarations the review
|
|
72
|
+
no longer holds (trusted since, or out of the TCB), kept, counted for nothing.
|
|
73
|
+
|
|
74
|
+
## `GET /api/agent/why?target=&name=`
|
|
75
|
+
|
|
76
|
+
The shortest chain of statement and body references from the target to the declaration.
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{"target": "Hilbert91", "name": "CyclotomicIntegers", "inTcb": true,
|
|
80
|
+
"chain": [{"name": "Hilbert91", "kind": "theorem", "module": "…"},
|
|
81
|
+
{"name": "relativeUnitsModule", "kind": "instance", …, "usedIn": "the statement of Hilbert91"},
|
|
82
|
+
{"name": "CyclotomicIntegers", …, "usedIn": "the statement of relativeUnitsModule"}],
|
|
83
|
+
"reviewPosition": {"position": 1, "of": 16}}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`inTcb: false`, `chain` null: nothing in the statement, nor in the body of a definition it reaches,
|
|
87
|
+
refers to it.
|
|
88
|
+
|
|
89
|
+
## `GET /api/agent/uses?name=&where=&offset=&limit=` and `GET /api/agent/users?…`
|
|
90
|
+
|
|
91
|
+
`uses`: what the declaration refers to by name; `users`: what refers to it. Each reference with
|
|
92
|
+
`where` it sits (in the declaration for `uses`, in the user for `users`): `statement`, `body`,
|
|
93
|
+
`proof`, or `grammar` (syntax that only declares grammar). Order: statement, body, then proof and
|
|
94
|
+
grammar; the project before the outside world; then name. `where=statement|body|proof|grammar`
|
|
95
|
+
filters; `counts` cover all (statement, body, proof; grammar only in `total`). `limit` 1–1000,
|
|
96
|
+
default 100; `next`: the next `offset`. A folded name counts as its owner; references to itself are
|
|
97
|
+
left out.
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{"name": "flt_regular", "direction": "uses", "note": "…", "offset": 0, "limit": 4, "total": 65, "next": 4,
|
|
101
|
+
"counts": {"total": 65, "statement": 8, "body": 0, "proof": 65, "project": 3, "external": 62, "trusted": 62},
|
|
102
|
+
"refs": [{"name": "Fact", "kind": "class", "module": "Mathlib.Logic.Basic", "external": true,
|
|
103
|
+
"where": ["statement", "proof"], "trusted": true, "trustedBy": ["Mathlib"]}, …]}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Notation** in `uses`: units of `kind: notation` (with `display`). The macro or elaborator that ran
|
|
107
|
+
on the text is at `statement` or `body`; the syntax the text parses with (helper syntax a parent
|
|
108
|
+
notation consumes included) at `where: ["grammar"]`, `grammar: true`, outside the TCB. Notation used
|
|
109
|
+
only in proofs: `where: ["proof"]`, not in the TCB. `where=grammar` lists just the grammar. A
|
|
110
|
+
rule's `uses`: the syntax it interprets (grammar), the meta code it calls, the notation its
|
|
111
|
+
expansion emits.
|
|
112
|
+
|
|
113
|
+
## Marking targets and keys, and trust (level full)
|
|
114
|
+
|
|
115
|
+
At level full you do what a person can through the page; below it, 403 saying which level refused.
|
|
116
|
+
Each is checked as the page's requests are and recorded under your name in your own review log,
|
|
117
|
+
`"agent": true`, with your mark in the timeline.
|
|
118
|
+
|
|
119
|
+
Names resolve as everywhere (`didYouMean`, folded names). `on` defaults to true. The answer says
|
|
120
|
+
whether anything `changed`; if so, `recorded` is the event written; if it was so already, nothing is
|
|
121
|
+
written.
|
|
122
|
+
|
|
123
|
+
| request | what |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `POST /api/agent/target {name, on}` | mark a project declaration as a target (☆ Target) or take it off. Marking makes no view: `view` (its linked view) is `null` after marking; `next`: the request that puts you on its view, a temporary view of its TCB where it has none. Taken off, its view (if any) stays, unlinked; marked again, nothing relinks it |
|
|
126
|
+
| `POST /api/agent/key {target, name, on}` or `{target, names: […], on}` | mark or unmark key declarations of a target's review; `names` up to 100, each answered on its own (`results`, with `status`). 409 if `target` is not a target; the name must be in its review (`tcb?target=` lists it); the target is always key (400) |
|
|
127
|
+
| `POST /api/agent/trust {prefix, on}` | trust without review, or stop trusting (a default too): a module or namespace, a whole dotted component, or `@external` (everything outside the project). Answers `covers` (`{project, outside}`) and `trusted`, the list after |
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{"ok": true, "changed": true,
|
|
131
|
+
"recorded": {"op": "target", "at": "…", "by": "Alice's AI", "name": "FltRegular.caseI", "on": true, "agent": true},
|
|
132
|
+
"view": null, "next": "POST /api/agent/view {\"review\": \"FltRegular.caseI\"} puts you on its view …"}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Views, pins and undoing a layout: [Views](views.md).
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Views and the layout
|
|
2
|
+
|
|
3
|
+
Views, their targets and focus, queries, the endpoints, past builds, pins on the Project view.
|
|
4
|
+
|
|
5
|
+
## Views
|
|
6
|
+
|
|
7
|
+
A view is a board everyone shares: its **scope** (a query) and arrangement (clustering, folds, pins,
|
|
8
|
+
hidden levels of its cluster tree); each person's camera and selection are their own. The
|
|
9
|
+
Project (`project`) holds everything; it cannot be deleted or renamed (400). A view on a query
|
|
10
|
+
nobody arranges or names is not kept: it lives while someone (a page, or you) is on it; pinning,
|
|
11
|
+
folding or naming keeps it.
|
|
12
|
+
|
|
13
|
+
- **A target has at most one view**, or none, opened by clicking it anywhere. Marking makes and
|
|
14
|
+
links none. `views/link` sets it to any view; the view left keeps scope and arrangement.
|
|
15
|
+
- **A view may have several targets** (`targets`, first linked first; a star by its title, which
|
|
16
|
+
stays as any view's, names them). Its focus starts as its first target; later links leave it.
|
|
17
|
+
- Taking a target off unlinks it alone; its view stays. A target's view is rescoped, renamed and
|
|
18
|
+
deleted as any kept view; deleted, its targets have no view, and nothing gives them one by itself
|
|
19
|
+
(not marking, a restart, a build or a rename).
|
|
20
|
+
- A click on a target with no view, or `view {review}` ([following](following.md)), gives it a
|
|
21
|
+
temporary view of its TCB (`tcb(<target>)`, at the latest build), focused on it and linked while
|
|
22
|
+
it lasts: kept (pinned, folded, named, rescoped, another target linked), it keeps the link; gone,
|
|
23
|
+
the target has none again. Making it is no timeline event; nothing else makes a target a view.
|
|
24
|
+
- Views named `review:<target>` (made by marking before) are ordinary views.
|
|
25
|
+
|
|
26
|
+
## The review is a focus
|
|
27
|
+
|
|
28
|
+
A view has a focus target or none. With one, the page's review works there — the strip, its line
|
|
29
|
+
of progress, marking key (`k`), why a declaration is in the TCB — over the focus's whole review set,
|
|
30
|
+
whatever the board holds ([tcb](tcb.md)). `focus` (in every answer giving a view) is: as set (a
|
|
31
|
+
target's Key view, opened from its panel: that target; Zoom in: the focus of the view it came from;
|
|
32
|
+
by the first target linked; by anyone), else the first target linked, else the one target its
|
|
33
|
+
board holds, else `null`. Your own focus (`POST view {focus}`) changes nothing of the view.
|
|
34
|
+
|
|
35
|
+
## The query language
|
|
36
|
+
|
|
37
|
+
`all`, `tcb(A, B)`, `uses(A)` (everything used), `usedBy(A)`, `refs(A)` (A and what it uses
|
|
38
|
+
directly: the page's Direct), `decl(A, B)`, `key(T)` (the target and the declarations
|
|
39
|
+
marked key for it that its review still holds; `key(targets)`: every target's), `ns(P)`, `file(P)`,
|
|
40
|
+
`trusted`, `external`, `kind(theorem, def)`, `status(unreviewed|approved|commented|stale)`,
|
|
41
|
+
`advice(approve|comment)`, `sorry`, `nonstandard`; joined left to right by `and`, `or`, `except`;
|
|
42
|
+
parentheses group; a closure may take a query (`tcb(ns(P) except external)`); a name that needs it
|
|
43
|
+
is in JSON quotes. A target's review set: `tcb(T) except trusted or (uses(T) and kind(axiom) and
|
|
44
|
+
nonstandard)`. At most 20,000 characters, 32 levels of nesting, 1,000 parts, 2,000 names, 64
|
|
45
|
+
closures (`tcb`, `uses`, `usedBy`, `refs`, each target of a `key(…)`); beyond, 400.
|
|
46
|
+
|
|
47
|
+
## The endpoints
|
|
48
|
+
|
|
49
|
+
Under `/api/agent/`; changes are for everyone on the view. MCP: `views`, action the path's last
|
|
50
|
+
part (`list` for `GET views`, `read` for `views/view`).
|
|
51
|
+
|
|
52
|
+
| request | needs | what |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `GET views` | — | per view `{id, title, description, name, scope, clustering, kept, targets?, focus, by, at, version?, on}`: `title` as shown (people's name, else short, "… @ Oct 9 22:27" at a past build), `description` the scope in full, `by` null for the nameless (a private reader), `on` who is on it, `version` the snapshot it is kept at. `unreadable`: kept views the server cannot read now, left untouched |
|
|
55
|
+
| `GET views/view?id=&mode=&members=` | — | scope; holdings `{project, outside}`; items `{add, remove}` (project notes added, taken out: `{id, text}`; `all: true` on the Project); folds; `hidden`; pins; clusters as laid out (`key, depth, count, r, parent, room, at, pinned`), in its own coordinates. `members=1`: its declarations (≤ 5,000) |
|
|
56
|
+
| `POST views/open {scope, version?, clustering?, focus?}` | — | the view on that query (the open one with the same scope and build, or a new unkept one); you are on it: `{view, holds, note}`. `version`: a snapshot id (`null`, `0`, left out: latest); `clustering`, `focus` (the target it is made from): a new one's |
|
|
57
|
+
| `POST views/create {name, scope?, clustering?, from?, version?}` | full | a kept, named view on a scope, or a copy of `from` (scope, clustering, pins, folds, items — on the Project, every note its scope would not give, as added — and build; with `scope`, that scope arranged as `from`); `version` keeps it at a build (the Time Machine's Save as new view), `null`/`0` latest |
|
|
58
|
+
| `POST views/scope {id, scope}` | full | change what it holds (those on it are told) |
|
|
59
|
+
| `POST views/items {id, add?, remove?}` | full | project notes (by id) added or taken out: on the add list only where the scope does not give it, the remove list only where it does. Not the Project (400; deleting is [`note/delete`](notes.md)); 404 for no project note. An Activity event, as a scope change: `{ok, changed, view, items: {add, remove}, notes: [{id, shown}]}` |
|
|
60
|
+
| `POST views/focus {id, focus}` | full | the view's own focus: a target's full name, or `null`/left out; personal focuses stay: `{ok, changed, view}` |
|
|
61
|
+
| `POST views/link {id, target}` | full | link a target (a view with targets takes another; an unkept one becomes kept); not the Project, nor a view at a past build (409): `{ok, changed, view, left?}`, `left` the view it leaves |
|
|
62
|
+
| `POST views/arrange {id, clustering?, hide?, show?, fold?, unfold?, pins?, version?}` | full | `version`: the build it is kept at (Keep this version in this view; `null`/`0`: latest again; never on the Project or a target's view; a timeline event); clustering; `hide`/`show` levels (`[keys]`: a hidden cluster's contents sit in its parent, a fold on it goes, the export's sections follow; nothing on the board moves, pins in what moves keep their place); `fold`/`unfold` (`[keys]`); `pins` `[{name or cluster, at: [x, y] or null}]` in the board's coordinates after hiding/showing (≤ 500; beyond the parent's room brought inside): `{ok, view, changed, hidden, placed, note?}` |
|
|
63
|
+
| `POST views/duplicate {id, name?}` | full | a kept copy (scope, clustering, pins, folds, items as for `create`), named `"<its title> (copy)"` (numbered while taken) unless named; you are on it: `{view, from}` |
|
|
64
|
+
| `POST views/rename {id, name}` | full | `null` removes a kept view's name: `{ok, changed, view}` |
|
|
65
|
+
| `POST views/delete {id}` | full | a kept view, with its pins, folds, layout; pages on it go to the Project. A target's view: `unlinked` names its targets; one timeline event: `{ok, deleted, title, scope, unlinked?, note}` |
|
|
66
|
+
| `POST views/relayout {id}` | full | ⚙ Board's Re-layout: every pin goes, not undoable; folds stay; on the Project the whole graph is laid out anew: `{ok, view, dropped, note}` |
|
|
67
|
+
|
|
68
|
+
## Views at a past build
|
|
69
|
+
|
|
70
|
+
Its `version` is a snapshot ([history](history.md)): the pages show that build's graph (a clock on
|
|
71
|
+
its tab, changes since marked), arranged as any view, with that build's layout memory. Not reviewed
|
|
72
|
+
(the review is the latest build's); exported by its id as that build's document
|
|
73
|
+
([export](export.md)); sources: `GET source?name=&snapshot=<version>`. These endpoints answer its
|
|
74
|
+
holdings, clusters and pins at the latest build; a layout they make never becomes its memory. The
|
|
75
|
+
companion shows who is in the Time Machine ([following](following.md)).
|
|
76
|
+
|
|
77
|
+
## `GET /api/agent/place?name=|cluster=&mode=&near=&limit=` (any level)
|
|
78
|
+
|
|
79
|
+
`place`, `pins` and `undo` are about the **Project view** (other views: `views/view`,
|
|
80
|
+
`views/arrange`). MCP: `pins` (actions `place`, `pin`, `undo`).
|
|
81
|
+
|
|
82
|
+
Where a declaration or cluster is (`mode`: `namespace`, default, or `module`), and what else is in
|
|
83
|
+
its parent. Coordinates are in the **parent cluster's frame**, origin at its centre.
|
|
84
|
+
`r`: radius (5 for a declaration); `room`: how far from the centre its centre may go;
|
|
85
|
+
`parent.room`: the parent's usable radius (less its label's room), so a child of radius `r` goes up
|
|
86
|
+
to `parent.room − r`. The page keeps a drop inside. A cluster's key is its full path
|
|
87
|
+
(`systemOfUnits.IsFundamental`); a top-level one has `parent.cluster` and `room` null, in the
|
|
88
|
+
canvas's frame.
|
|
89
|
+
|
|
90
|
+
`pinned`: its pin (null: at `laidOut`); `pinnedBy`: `{name, agent, at}`, null if unknown (`name`
|
|
91
|
+
null: a private reader, or a page that gave none). An undo's restored pins count
|
|
92
|
+
as the undoer's. `siblings`: the rest of the parent (declarations, clusters), each with `r`, `at`
|
|
93
|
+
(pin or layout), pinned and by whom, nearest first to `nearestTo` (your `near=x,y`, else the thing
|
|
94
|
+
itself); `gap`: free space between the circles were the thing at `nearestTo` (below zero:
|
|
95
|
+
overlap). `limit` 0–2000, default 100; `more`: the rest.
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{ "kind": "node", "key": "systemOfUnits.index", "r": 5, "room": 34.2, …,
|
|
99
|
+
"parent": { "cluster": "systemOfUnits", "r": 53.1, "room": 39.2 }, "laidOut": [-15.1, 22.9],
|
|
100
|
+
"pinned": [-10.8, -32.4], "pinnedBy": { "name": "Claude", "agent": true, "at": "…" },
|
|
101
|
+
"siblings": { "total": 10, "pinned": 1, "nearestTo": [-20, 30], "more": 8,
|
|
102
|
+
"list": [ { "key": "…", "declKind": "theorem", "at": [-25.4, 22.9], "gap": -1.1, … }, … ] } }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
To avoid overlaps, ask with `near=` your spot and move until the first sibling's `gap` is positive:
|
|
106
|
+
on the page a pin pushes aside what is not pinned (a declaration, or a cluster with its contents),
|
|
107
|
+
and the later of two overlapping pins pushes the earlier, so an overlap moves things you did not
|
|
108
|
+
mean to, others' pins included.
|
|
109
|
+
|
|
110
|
+
## `POST /api/agent/pins` (needs full)
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{ "mode": "namespace", "pins": [ { "name": "systemOfUnits.index", "at": [-15, -45] },
|
|
114
|
+
{ "name": "systemOfUnits.isMaximal", "at": null } ] }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`at` in the parent's frame (`place`); `null` lets go (back to the layout). ≤ 500 per request;
|
|
118
|
+
beyond the parent's `room`, brought inside as a drag is. Pins are shared, live on every page. The
|
|
119
|
+
request is **one batch** in the timeline ("Claude moved 3 declarations"), with each pin's previous
|
|
120
|
+
place. Answer `{ok, id, count, placed: [{key, at}, …]}`; `id` null when nothing changed.
|
|
121
|
+
|
|
122
|
+
## `POST /api/agent/undo {id}` (needs full)
|
|
123
|
+
|
|
124
|
+
The batch's pins go back, except those moved since (`kept`): `{ok, id, restored, kept, note?}`; 409
|
|
125
|
+
already undone; 404 no such batch. People undo from Activity. `views/arrange` pins are no batch.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Words
|
|
2
|
+
|
|
3
|
+
The terms the other topics use.
|
|
4
|
+
|
|
5
|
+
- **Declaration**: a Lean constant of the project (`kind`: def, theorem, structure, inductive,
|
|
6
|
+
class, instance, abbrev, opaque, axiom, notation, …) or outside it (`external: true`, no source).
|
|
7
|
+
- **Unit**: a declaration of the graph is a command as written; what Lean generates from it unnamed
|
|
8
|
+
in the text (what a project's declaring command writes beside the declaration it names, `@[simps]`
|
|
9
|
+
lemmas) is part of it, in `also`, its references, axioms and content hash included.
|
|
10
|
+
- **Folded names**: constructors, structure fields and projections, recursors, matchers, equation
|
|
11
|
+
lemmas, `also` names are not graph declarations; a reference to one is to its owner. Asked for,
|
|
12
|
+
an `also` name or a name one component below a declaration or `also` name
|
|
13
|
+
(`systemOfUnits.units`) is that declaration, unless a typo or two from a declaration beside it
|
|
14
|
+
(generated last parts like `mk`, `rec`, `eq_1` fold even then); the answer adds `asked`,
|
|
15
|
+
`foldedInto`, `foldedNote`. `describe` and `print` take the folded name.
|
|
16
|
+
- **Notation** (`kind: notation`): a project syntax extension command (`syntax`, `notation`,
|
|
17
|
+
`macro`, `macro_rules`, `elab`, `elab_rules`, `declare_syntax_cat`; `local`, `scoped` too) as one
|
|
18
|
+
unit, its parser and `_aux_` macro or elaborator folded in. Statement: the command's text;
|
|
19
|
+
`display`: the page's name (`notation · I · in UnitLemmas`); `leanName`: its Lean constant where
|
|
20
|
+
its name is not one. Names: rules `<kind>.macro_rules`, `<kind>.elab_rules` (`_2`, … for later
|
|
21
|
+
rules of the kind in the module; `.<Module>` if not in the syntax's module), a syntax its kind, a
|
|
22
|
+
category `<category>.syntax_cat`. `describe` and `print` of a unit ask about its constant
|
|
23
|
+
(`unit` in the answer).
|
|
24
|
+
- **Grammar** (`grammar: true`, flag `grammar`): a notation unit only declaring syntax (`syntax`,
|
|
25
|
+
`declare_syntax_cat`): in no TCB, no review; references to it are `where: grammar`, which a TCB
|
|
26
|
+
does not follow. A declaration depends on the macros and elaborators that actually ran on its
|
|
27
|
+
statement or body (of an overloaded kind's rules, that one; with no run in the info tree, the only
|
|
28
|
+
rule of a syntax its text parses): notation units with an implementation, declarations registered
|
|
29
|
+
`@[macro]`, `@[term_elab]`, `@[command_elab]`; and on the meta code they call (ordinary units,
|
|
30
|
+
flagged `meta`). Notation an expansion emits is a dependency of the rule emitting it. A rule
|
|
31
|
+
lists the syntax it `interprets`; a grammar unit, its `interpretedBy`. Unexpanders, delaborators:
|
|
32
|
+
in no TCB. Notation from outside the project is never recorded: no use listed, in no TCB.
|
|
33
|
+
- **`where`** a reference sits, one or several: `statement` (the type), `body` (a definition's
|
|
34
|
+
value), `proof` (a subterm whose type is a proposition).
|
|
35
|
+
- **TCB of T**: everything T's *statement* reaches through statement and body references, T
|
|
36
|
+
included; proof references never count. Includes the notation units interpreting their text
|
|
37
|
+
(never grammar) and the code they call. [Targets and their TCB](tcb.md).
|
|
38
|
+
- **Instances of classes whose instances are all equal** (`Decidable`, `DecidableEq`, `Fintype`,
|
|
39
|
+
`Unique`, …): in no TCB; such an instance argument is a `proof` reference. Instances of classes
|
|
40
|
+
carrying data (`Add`, `Monad`, `Inhabited`, …) stay.
|
|
41
|
+
- **Needs review**: a TCB member not *trusted*. Trusted: under a trusted prefix (by module, or by
|
|
42
|
+
name for the project's own; default `Batteries`, `Init`, `Lean`, `Mathlib`, `Std`), and the
|
|
43
|
+
standard axioms `propext`, `Classical.choice`, `Quot.sound`.
|
|
44
|
+
- **Review order**: bottom-up (what a declaration uses before it; mutual users together), then
|
|
45
|
+
what more targets rest on, then name. A review judges a declaration assuming what it uses means
|
|
46
|
+
what it says.
|
|
47
|
+
- **Status** (people's): `commented` if some reviewer's latest opinion on the present version is a
|
|
48
|
+
comment; else `approved` if one approves; else `stale` if it has opinions, none on the present
|
|
49
|
+
version; else `none`.
|
|
50
|
+
- **Target**: a theorem whose TCB is reviewed; marked by people, or agents at level full
|
|
51
|
+
(`markedByAgent`).
|
|
52
|
+
- **Key declaration**: a review member that matters for reading the target (central definitions,
|
|
53
|
+
the structures under them, the main theorem), marked per target as targets are; the target always
|
|
54
|
+
is one. A non-key member is **supported by** a key declaration reaching it by statement and body
|
|
55
|
+
references through non-key members; the **key graph** links key declarations reached so. People
|
|
56
|
+
review key declarations first.
|
package/package.json
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "visualproof",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "See a Lean codebase's declaration graph and the TCB of its theorems.",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/LucianoXu/VisualProof.git"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"visualproof": "dist/server/main.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"docs/agent-api/",
|
|
17
|
+
"test/toolchains.json"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "node scripts/build.mjs",
|
|
21
|
+
"prepack": "npm run build",
|
|
22
|
+
"serve": "node src/server/main.ts serve",
|
|
23
|
+
"typecheck": "tsc --noEmit -p .",
|
|
24
|
+
"test": "node --test --import ./test/setup.ts \"test/*.test.ts\"",
|
|
25
|
+
"test:toolchains": "node scripts/test-toolchains.mjs",
|
|
26
|
+
"golden:update": "VP_GOLDEN_UPDATE=1 node --test --import ./test/setup.ts test/compat.test.ts"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": "^22.18.0 || >=24.2.0"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"d3-hierarchy": "^3.1.2",
|
|
33
|
+
"pdfjs-dist": "6.3.289"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/d3-hierarchy": "^3.1.7",
|
|
37
|
+
"@types/node": "^24.0.0",
|
|
38
|
+
"esbuild": "^0.28.2",
|
|
39
|
+
"typescript": "^5.9.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"policy": "The last six or so stable Lean releases, and whatever the showcase project needs (v4.34.0-rc2, for NavierStokesAndEuler); v4.28.0, for the sphere packing formalization (the showcase before it), stays the floor; the newest patch of each minor release.",
|
|
3
|
+
"floor": "v4.28.0",
|
|
4
|
+
"toolchains": ["v4.28.0", "v4.29.1", "v4.30.0", "v4.31.0", "v4.32.2", "v4.33.1", "v4.34.0-rc2", "v4.34.1", "v4.35.0"]
|
|
5
|
+
}
|