visualproof 0.2.0 → 0.3.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/README.md +40 -26
- package/dist/assets/webfonts/LICENSE-Noto.txt +95 -0
- package/dist/assets/webfonts/metrics.json +1 -0
- package/dist/assets/webfonts/ttf/jost-400-normal.ttf +0 -0
- package/dist/assets/webfonts/ttf/jost-500-normal.ttf +0 -0
- package/dist/assets/webfonts/ttf/noto-sans-math.ttf +0 -0
- package/dist/assets/webfonts/ttf/noto-sans.ttf +0 -0
- package/dist/assets/webfonts/ttf/source-sans-3-400-italic.ttf +0 -0
- package/dist/assets/webfonts/ttf/source-sans-3-400-normal.ttf +0 -0
- package/dist/assets/webfonts/ttf/source-sans-3-500-normal.ttf +0 -0
- package/dist/assets/webfonts/ttf/source-sans-3-600-normal.ttf +0 -0
- package/dist/assets/webfonts/ttf/source-sans-3-700-normal.ttf +0 -0
- package/dist/assets/webfonts/ttf/source-serif-4-400-italic.ttf +0 -0
- package/dist/assets/webfonts/ttf/source-serif-4-600-italic.ttf +0 -0
- package/dist/server/agent.js +84 -86
- package/dist/server/agentdocs.js +1 -1
- package/dist/server/artcmd.js +335 -0
- package/dist/server/live.js +6 -0
- package/dist/server/main.js +136 -8
- package/dist/server/mcptools.js +4 -1
- package/dist/server/pipeline.js +15 -9
- package/dist/server/readonlygate.js +1 -1
- package/dist/server/review.js +4 -1
- package/dist/server/reviewapi.js +35 -1
- package/dist/server/snapshot.js +10 -1
- package/dist/server/view.js +0 -7
- package/dist/server/views.js +24 -0
- package/dist/shared/artfonts.js +81 -0
- package/dist/shared/artrecipe.js +316 -0
- package/dist/shared/collab.js +7 -2
- package/dist/shared/declfind.js +95 -0
- package/dist/shared/lostfound.js +1 -0
- package/dist/shared/pastgraph.js +6 -6
- package/dist/shared/review.js +62 -5
- package/dist/web/bundle/app.js +713 -164
- package/dist/web/bundle/edges.js +1 -1
- package/dist/web/src/agentmark.js +14 -0
- package/dist/web/src/artwork.js +1000 -0
- package/dist/web/src/bundles.js +151 -0
- package/dist/web/src/canvas.js +3694 -0
- package/dist/web/src/drag.js +61 -0
- package/dist/web/src/edgequeue.js +204 -0
- package/dist/web/src/gl/gl.js +123 -0
- package/dist/web/src/gl/renderer.js +451 -0
- package/dist/web/src/halo.js +95 -0
- package/dist/web/src/highlight.js +108 -0
- package/dist/web/src/overview.js +393 -0
- package/dist/web/src/reviewqueue.js +250 -0
- package/dist/web/src/selection.js +272 -0
- package/dist/web/src/status.js +80 -0
- package/dist/web/src/visitors.js +318 -0
- package/dist/web/src/visits.js +174 -0
- package/dist/web/style.css +7 -0
- package/docs/agent-api/README.md +1 -1
- package/docs/agent-api/export.md +41 -2
- package/docs/agent-api/history.md +2 -1
- package/docs/agent-api/mcp.md +1 -1
- package/docs/agent-api/reading.md +2 -1
- package/package.json +3 -1
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// The reader's visitors laid on the board's scene (ViewSpec decision 27, the owner's decision of
|
|
2
|
+
// 2026-10-11): each in its own place in the cluster hierarchy, the clusters it needs added as
|
|
3
|
+
// temporary ones (web/src/visitors.ts, planVisitors), the outermost of them in the deepest cluster the
|
|
4
|
+
// board draws, at a spot chosen once.
|
|
5
|
+
//
|
|
6
|
+
// Making room: what a visitor brings goes where its cluster has free room, nearest the declarations it
|
|
7
|
+
// has references with; where the cluster has none, against its rim where it covers least, and what it
|
|
8
|
+
// covers makes way, as from a drop, the circle growing only where that cannot fit (web/src/scene.ts,
|
|
9
|
+
// setHeld). Nothing of it is a pin or the board's: when the visitors go, every place comes back.
|
|
10
|
+
//
|
|
11
|
+
// A spot is in its cluster's coordinates and carried to followers with the trail (PresenceView), so a
|
|
12
|
+
// follower draws the temporary clusters where the leader does; the rest — which clusters, nested how,
|
|
13
|
+
// packed how — is a function of the visitors and the board, the same on every page.
|
|
14
|
+
import { LEAF_R } from "./scene.js";
|
|
15
|
+
import { freeSpot, packPlan, planVisitors, rimSpot } from "./visitors.js";
|
|
16
|
+
/** How far outside what it holds a cluster's circle is drawn (web/src/scene.ts, computeExtents). */
|
|
17
|
+
const DRAWN_MARGIN = 6;
|
|
18
|
+
/** Whether a declaration's name is a namespace too, on a board whose declarations are `names` (the
|
|
19
|
+
* outside world's left out), the visitors' among them: a structure then sits in its own namespace's
|
|
20
|
+
* cluster, as the board would draw it (shared/layout.ts, pathOf). */
|
|
21
|
+
export function prefixTest(g, visitors) {
|
|
22
|
+
const memo = new Map();
|
|
23
|
+
return (name) => {
|
|
24
|
+
let hit = memo.get(name);
|
|
25
|
+
if (hit !== undefined)
|
|
26
|
+
return hit;
|
|
27
|
+
const head = `${name}.`;
|
|
28
|
+
hit = visitors.some((v) => v.startsWith(head));
|
|
29
|
+
for (let i = 0; !hit && i < g.n; i++)
|
|
30
|
+
if (!g.isExt(i) && g.nodes[i].name.startsWith(head))
|
|
31
|
+
hit = true;
|
|
32
|
+
memo.set(name, hit);
|
|
33
|
+
return hit;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Where the visitors `vs` belong on a board (web/src/visitors.ts, planVisitors): its layout `L` by
|
|
37
|
+
* `mode`, the levels `hidden`, its graph `g`. */
|
|
38
|
+
export function planOn(L, mode, hidden, g, vs) {
|
|
39
|
+
const drawn = new Map(L.clusters.map((c, k) => [c.key, k]));
|
|
40
|
+
return planVisitors(mode, drawn, new Set(hidden), vs, prefixTest(g, vs.map((v) => v.name)));
|
|
41
|
+
}
|
|
42
|
+
/** The board's clusters round the places of the visitors `chosen` (indices of the trail): the folded
|
|
43
|
+
* ones among them open for the reader while those are selected (ViewSpec decision 27). */
|
|
44
|
+
export function openFor(plan, parent, chosen) {
|
|
45
|
+
const out = new Set();
|
|
46
|
+
for (const k of chosen)
|
|
47
|
+
for (let c = plan.at[k]?.in ?? -1; c >= 0; c = parent[c])
|
|
48
|
+
out.add(c);
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
/** Place the visitors `vs` (the trail, oldest first) on a board as `plan` says (planOn): its layout
|
|
52
|
+
* `L`, its scene `S` as the board arranges it. An item keeps the place its oldest visitor has in
|
|
53
|
+
* that cluster; one with none is given a spot — in the order its oldest visitor came, so that a newer
|
|
54
|
+
* one never moves an older one — where `ok` (a spot of the world and a radius) finds no cluster's
|
|
55
|
+
* name written. */
|
|
56
|
+
export function placeVisits(S, L, plan, vs, ok = () => true) {
|
|
57
|
+
const names = vs.map((v) => v.name);
|
|
58
|
+
const pack = packPlan(plan, names);
|
|
59
|
+
const keyOf = (c) => (c < 0 ? "" : L.clusters[c].key);
|
|
60
|
+
// the outermost items, and which visitors each holds
|
|
61
|
+
const items = [];
|
|
62
|
+
const ofTemp = new Map();
|
|
63
|
+
plan.temps.forEach((t, k) => {
|
|
64
|
+
if (t.up >= 0)
|
|
65
|
+
return;
|
|
66
|
+
ofTemp.set(k, items.length);
|
|
67
|
+
items.push({ in: t.in, temp: k, visitor: -1, at: [0, 0], r: pack.r[k], slot: 0 });
|
|
68
|
+
});
|
|
69
|
+
const item = plan.at.map((a, k) => {
|
|
70
|
+
if (a.up < 0) {
|
|
71
|
+
items.push({ in: a.in, temp: -1, visitor: k, at: [0, 0], r: LEAF_R, slot: 0 });
|
|
72
|
+
return items.length - 1;
|
|
73
|
+
}
|
|
74
|
+
let t = a.up;
|
|
75
|
+
while (plan.temps[t].up >= 0)
|
|
76
|
+
t = plan.temps[t].up;
|
|
77
|
+
return ofTemp.get(t);
|
|
78
|
+
});
|
|
79
|
+
const members = items.map(() => []);
|
|
80
|
+
item.forEach((j, k) => members[j].push(k));
|
|
81
|
+
// in the order their oldest visitors came
|
|
82
|
+
const order = items.map((_, j) => j).sort((a, b) => members[a][0] - members[b][0]);
|
|
83
|
+
const placed = new Map();
|
|
84
|
+
for (const j of order) {
|
|
85
|
+
const it = items[j];
|
|
86
|
+
const kept = members[j].map((k) => vs[k].place).find((p) => p && p.in === keyOf(it.in));
|
|
87
|
+
if (kept)
|
|
88
|
+
it.at = [kept.at[0], kept.at[1]];
|
|
89
|
+
else {
|
|
90
|
+
const room = S.roomOf(it.in);
|
|
91
|
+
// a sub-cluster's circle is drawn a little outside what it holds (Scene, computeExtents)
|
|
92
|
+
const bodies = [...S.discsIn(it.in).map((d) => (d.r > LEAF_R ? { ...d, r: d.r + DRAWN_MARGIN } : d)), ...(placed.get(it.in) ?? []).map((o) => ({ x: o.at[0], y: o.at[1], r: o.r }))];
|
|
93
|
+
// towards the declarations it has references with, as the board arranges them
|
|
94
|
+
const [ox, oy] = S.anchorWorld(it.in);
|
|
95
|
+
let sx = 0, sy = 0, m = 0;
|
|
96
|
+
for (const k of members[j])
|
|
97
|
+
for (const i of vs[k].near) {
|
|
98
|
+
const [cx, cy] = S.anchorWorld(S.nodeCluster[i]);
|
|
99
|
+
sx += cx + S.ancNX[i];
|
|
100
|
+
sy += cy + S.ancNY[i];
|
|
101
|
+
m++;
|
|
102
|
+
}
|
|
103
|
+
const prefer = m ? [sx / m - ox, sy / m - oy] : [0, 0];
|
|
104
|
+
const okHere = (x, y) => ok(ox + x, oy + y, it.r);
|
|
105
|
+
it.at = freeSpot(bodies, room, it.r, prefer, okHere) ?? rimSpot(bodies, room, it.r, prefer);
|
|
106
|
+
}
|
|
107
|
+
const list = placed.get(it.in) ?? [];
|
|
108
|
+
it.slot = list.length;
|
|
109
|
+
list.push(it);
|
|
110
|
+
placed.set(it.in, list);
|
|
111
|
+
}
|
|
112
|
+
const held = new Map();
|
|
113
|
+
for (const [c, list] of placed)
|
|
114
|
+
held.set(c, list.map((o) => ({ x: o.at[0], y: o.at[1], r: o.r })));
|
|
115
|
+
const places = item.map((j) => ({ in: keyOf(items[j].in), at: [items[j].at[0], items[j].at[1]] }));
|
|
116
|
+
return { plan, pack, items, item, places, held };
|
|
117
|
+
}
|
|
118
|
+
export function visitWorld(V, S) {
|
|
119
|
+
const T = V.plan.temps.length, K = V.plan.at.length;
|
|
120
|
+
const W = { tx: new Float64Array(T), ty: new Float64Array(T), tr: new Float64Array(T), trep: new Int32Array(T), vx: new Float64Array(K), vy: new Float64Array(K), vrep: new Int32Array(K) };
|
|
121
|
+
const centre = (it) => {
|
|
122
|
+
const at = S.heldAt.get(it.in);
|
|
123
|
+
const hx = at ? at[2 * it.slot] : it.at[0], hy = at ? at[2 * it.slot + 1] : it.at[1];
|
|
124
|
+
if (it.in < 0)
|
|
125
|
+
return [hx, hy, 1];
|
|
126
|
+
const s = S.scale[it.in];
|
|
127
|
+
return [S.cwx[it.in] + hx * s, S.cwy[it.in] + hy * s, s];
|
|
128
|
+
};
|
|
129
|
+
const scaleOf = (c) => (c < 0 ? 1 : S.scale[c]);
|
|
130
|
+
const repOf = (c) => (c < 0 ? -1 : S.rep[c]);
|
|
131
|
+
for (let t = 0; t < T; t++) {
|
|
132
|
+
const tc = V.plan.temps[t];
|
|
133
|
+
const s = scaleOf(tc.in);
|
|
134
|
+
if (tc.up < 0) {
|
|
135
|
+
const it = V.items[V.items.findIndex((x) => x.temp === t)];
|
|
136
|
+
[W.tx[t], W.ty[t]] = centre(it);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
W.tx[t] = W.tx[tc.up] + V.pack.x[t] * s;
|
|
140
|
+
W.ty[t] = W.ty[tc.up] + V.pack.y[t] * s;
|
|
141
|
+
}
|
|
142
|
+
W.tr[t] = V.pack.r[t] * s;
|
|
143
|
+
W.trep[t] = repOf(tc.in);
|
|
144
|
+
}
|
|
145
|
+
for (let k = 0; k < K; k++) {
|
|
146
|
+
const a = V.plan.at[k];
|
|
147
|
+
if (a.up >= 0) {
|
|
148
|
+
const s = scaleOf(a.in);
|
|
149
|
+
W.vx[k] = W.tx[a.up] + V.pack.vx[k] * s;
|
|
150
|
+
W.vy[k] = W.ty[a.up] + V.pack.vy[k] * s;
|
|
151
|
+
}
|
|
152
|
+
else
|
|
153
|
+
[W.vx[k], W.vy[k]] = centre(V.items[V.item[k]]);
|
|
154
|
+
W.vrep[k] = repOf(a.in);
|
|
155
|
+
}
|
|
156
|
+
return W;
|
|
157
|
+
}
|
|
158
|
+
/** A visitor's chain of position ids up to the top level, as its edges are bundled through the
|
|
159
|
+
* hierarchy (web/src/bundles.ts, joinChains): itself, its temporary clusters, the board's clusters
|
|
160
|
+
* round it — or, hidden in a folded cluster's card, that card and the clusters round it. Ids past the
|
|
161
|
+
* scene's (`base` = clusters and declarations) are the visitors' own: a temporary cluster t at
|
|
162
|
+
* base + t, a visitor k at base + temps + k. */
|
|
163
|
+
export function visitChain(V, W, S, base, k) {
|
|
164
|
+
const out = [];
|
|
165
|
+
const a = V.plan.at[k];
|
|
166
|
+
if (W.vrep[k] < 0) {
|
|
167
|
+
out.push(base + V.plan.temps.length + k);
|
|
168
|
+
for (let t = a.up; t >= 0; t = V.plan.temps[t].up)
|
|
169
|
+
out.push(base + t);
|
|
170
|
+
}
|
|
171
|
+
for (let c = W.vrep[k] >= 0 ? W.vrep[k] : a.in; c >= 0; c = S.parent[c])
|
|
172
|
+
out.push(c);
|
|
173
|
+
return out;
|
|
174
|
+
}
|
package/dist/web/style.css
CHANGED
|
@@ -438,6 +438,12 @@ body.art-moving :is(#bar .brand, #bar .library-wrap, #export-btn, #activity-btn,
|
|
|
438
438
|
}
|
|
439
439
|
.sw-review .rv-text { min-height: calc(5 * 1.45em + 12px); }
|
|
440
440
|
.rv-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
|
|
441
|
+
/* whom the opinion is for (ReviewSpec decision 8): a name beside the buttons; while it is another
|
|
442
|
+
person's, a coloured line over the box says so */
|
|
443
|
+
.rv-for { display: inline-flex; align-items: center; gap: 5px; margin-left: auto; font-size: 11.5px; color: var(--text-2); white-space: nowrap; }
|
|
444
|
+
.rv-for-in { width: 9em; font: 12px var(--font); color: var(--text); background: var(--surface-solid); border: 1px solid var(--line); border-radius: 6px; padding: 3px 6px; }
|
|
445
|
+
.rv-for-on { margin: 0 0 6px; padding: 5px 9px; border-radius: 7px; font-size: 12px; color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); }
|
|
446
|
+
.rv-for-on[hidden] { display: none; }
|
|
441
447
|
.rv-btn {
|
|
442
448
|
border: 1px solid var(--line); background: var(--surface-solid); color: var(--text); font: 12px var(--font);
|
|
443
449
|
padding: 4px 10px; border-radius: 7px; cursor: pointer;
|
|
@@ -1967,6 +1973,7 @@ a.link:hover { text-decoration: underline; }
|
|
|
1967
1973
|
/* the reader's "Open in editor" template, under the keys */
|
|
1968
1974
|
.help-editor, .help-about { display: flex; flex-direction: column; gap: 6px; margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); }
|
|
1969
1975
|
.help-note { color: var(--text-2); font-size: 12px; line-height: 1.45; }
|
|
1976
|
+
.help-note a { color: var(--accent); }
|
|
1970
1977
|
.help-note code { font: 11px var(--mono); background: var(--code-bg); padding: 1px 4px; border-radius: 4px; overflow-wrap: anywhere; }
|
|
1971
1978
|
.help-input {
|
|
1972
1979
|
font: 12.5px var(--mono); color: var(--text); background: var(--surface-solid); border: 1px solid var(--line);
|
package/docs/agent-api/README.md
CHANGED
|
@@ -85,7 +85,7 @@ parameters and answer.
|
|
|
85
85
|
| [following](following.md) | where people are, your own view, links to it, asking to follow, what people see |
|
|
86
86
|
| [views](views.md) | the query language, views, places on the board, pins and undo |
|
|
87
87
|
| [library](library.md) | papers and images, their pages, links to them |
|
|
88
|
-
| [export](export.md) | a view's document: its model, typesetting, its files |
|
|
88
|
+
| [export](export.md) | a view's document: its model, typesetting, its files; a picture (artwork) |
|
|
89
89
|
| [history](history.md) | the timeline, the builds kept, diffs, renames, the lost-and-found |
|
|
90
90
|
| [talking](talking.md) | your inbox, replies, your status line, your state, the conversation |
|
|
91
91
|
| [mcp](mcp.md) | the MCP server: installing it, its tools and their actions, `wait_for_message` |
|
package/docs/agent-api/export.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Exported documents
|
|
2
2
|
|
|
3
|
-
A view's document, read as JSON or typeset as a PDF
|
|
4
|
-
(`model`, `typeset`, `job`, `file`).
|
|
3
|
+
A view's document, read as JSON or typeset as a PDF; and a picture of the board ([Artwork](#artwork)).
|
|
4
|
+
Any level: it only reads. MCP: `export` (`model`, `typeset`, `job`, `file`, `artwork`).
|
|
5
5
|
|
|
6
6
|
## What it holds
|
|
7
7
|
|
|
@@ -118,3 +118,42 @@ kept). 503: no XeLaTeX.
|
|
|
118
118
|
typeset it again (`.tex`, style file, fonts). **409** with `Retry-After: 2` while running, 409 if
|
|
119
119
|
failed, 404 if unknown or gone from the cache. E.g.
|
|
120
120
|
`curl -fsSK ~/.visualproof/curl.cfg "$VP/api/agent/export/file?id=<id>" -o doc.pdf`.
|
|
121
|
+
|
|
122
|
+
## Artwork
|
|
123
|
+
|
|
124
|
+
`POST /api/agent/artwork {recipe, save?}`: a link that opens the board as a picture in the artwork mode, as a **recipe** says, in words that
|
|
125
|
+
hold on any project: one recipe makes the same kind of picture of every codebase. The page that
|
|
126
|
+
opens it draws the picture and, with `save` (`png`, `svg`, `png,svg`), saves the files there once
|
|
127
|
+
the board is still; nothing comes back to the server. The link holds no key (a script enters with
|
|
128
|
+
it: `scripts/artwork-batch.mjs` in VisualProof's repository).
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{ "recipe": { "size": "a2", "orientation": "portrait", "theme": "light", "border": true,
|
|
132
|
+
"names": { "clusters": 1 }, "targets": ["Lib.mainTheorem"],
|
|
133
|
+
"selection": { "name": "Lib.mainTheorem", "mode": "tcb" }, "keys": false, "notes": false,
|
|
134
|
+
"source": true, "title": "Lib", "subtitle": "One line about the work" }, "save": "png,svg" }
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Every field is optional; left out, as a new artwork has it.
|
|
138
|
+
|
|
139
|
+
- `size`: `hd`, `4k` (default), `square`, `a3`, `a2` (300 dpi), or `{w, h}`; `orientation`;
|
|
140
|
+
`style` (`board`, `cells`, `stars`); `theme` (`light`, `dark`), `transparent`; `colouring`
|
|
141
|
+
(`kind`, `status`); `border`; `title`, `subtitle` (null: the project's own; `""`: none),
|
|
142
|
+
`titleSize`, `footSize` (hundredths of the height); `source` (git source and commit).
|
|
143
|
+
- `names`: `board`, `clusters`, `none`, or a rule `{clusters, minShare, targets, decls, omit,
|
|
144
|
+
from}`: `clusters` a depth (0: the top level) or keys; a depth names the outside world and the
|
|
145
|
+
clusters holding at least `minShare` of the project (default 0.01), each written only where it
|
|
146
|
+
covers no name already written (`ruled`), never over another; keys, `decls` (full names) and
|
|
147
|
+
`targets` (default true: the marked targets' names) written wherever they fall; `omit` keys or
|
|
148
|
+
names; `from` `none` (default) or `board`.
|
|
149
|
+
- `targets`: `all` (default), `none`, `faded`, or a list of targets marked alone. `keys`, `notes`:
|
|
150
|
+
default true. `edges`: `all` (under a selection, the rest faint), `selection`, `none`.
|
|
151
|
+
- `selection`: `{name, mode}` (`mode` as `POST view`'s; default `tcb`), lit while `lit` (default
|
|
152
|
+
true). `view`: a view's id; left out, the Project.
|
|
153
|
+
|
|
154
|
+
Answer: `{ok, link, length, size, names: {clusters, decls, ruled}, targets, selection, left, note}`;
|
|
155
|
+
`left`: names or targets beyond what an artwork carries, left out. Saving both files, the page says
|
|
156
|
+
the browser may ask to allow several downloads. 400: a field unknown or wrong; 404: a name, target,
|
|
157
|
+
cluster or view the recipe names that the board has not (`problems`; a target of the review the
|
|
158
|
+
graph no longer has is left out unsaid).
|
|
159
|
+
|
|
@@ -20,7 +20,8 @@ name bare).
|
|
|
20
20
|
Every event with a `by` has `agent`. `by` is null on a `view`, `note` or `undo` event done without a
|
|
21
21
|
name (a private reader's; their opinions, targets, key marks and trust keep their name).
|
|
22
22
|
|
|
23
|
-
- Review's logs (no `id`): `opinion
|
|
23
|
+
- Review's logs (no `id`): `opinion` (`recordedBy`: who typed it for `by`, at one screen), `target`,
|
|
24
|
+
`key` (as marked now: `target`, `name`), `file`
|
|
24
25
|
(`what` added, edited, archived or restored; `sha`, `title` then, `wasTitle` before an edit),
|
|
25
26
|
`link` (`what` made, edited or removed; `id`, `subject`, `label`, `file`; an edit's `changed`
|
|
26
27
|
(of `subject`, `label`, `place`), `wasSubject`, `wasLabel`, and `auto` if VisualProof carried it
|
package/docs/agent-api/mcp.md
CHANGED
|
@@ -40,7 +40,7 @@ Each wraps the endpoints of a topic, which says what their answers hold. `*`: th
|
|
|
40
40
|
| `library` | `list`, `file`, `text`, `search`, `page`, `clip`, `save`; `add_url`, `add_file`, `edit`, `archive` (advise) | `library/…`, [library](library.md) |
|
|
41
41
|
| `links` | `list`; `make`, `edit`, `remove` (advise) | `GET links`, `POST link`, `link/edit`, `unlink`, [library](library.md) |
|
|
42
42
|
| `history` | `snapshots`, `diff`, `moves`, `last`, `lost`, `archived`; `attach`, `unmove`, `archive` (full) | `history/…`, [history](history.md) |
|
|
43
|
-
| `export` | `model`, `typeset`, `job`, `file` | `export`, `export/job`, `export/file`, [export](export.md) |
|
|
43
|
+
| `export` | `model`, `typeset`, `job`, `file`, `artwork` | `export`, `export/job`, `export/file`, `artwork`, [export](export.md) |
|
|
44
44
|
|
|
45
45
|
Paths are under `/api/agent/`. `GET /api/agent/history/graph` has no tool (it is large: ask it over
|
|
46
46
|
HTTP when you need a past build's whole graph).
|
|
@@ -36,7 +36,8 @@ Everything about one declaration; here `include=print` while Lean loads:
|
|
|
36
36
|
- `axioms`: all its proof and definition reach; `nonStandardAxioms`: beyond the standard three
|
|
37
37
|
(`sorryAx`). `review`: `opinions` (people's latest) and `advice` (agents', `yours: true`), one
|
|
38
38
|
each; `onPresentVersion: false`: on an earlier version; `verified: true`: from someone invited by
|
|
39
|
-
a personal link, `by` their name now; `
|
|
39
|
+
a personal link, `by` their name now; `recordedBy`: typed for `by` by that person, at one screen
|
|
40
|
+
(theirs all the same); `trustedBy`: covering prefixes, or `["standard axiom"]`.
|
|
40
41
|
- `editedSinceCompiled`: file differs from what was compiled (null outside the project); `keyFor`,
|
|
41
42
|
`inTcbOf`: targets it is key for, whose TCB holds it; `usesDirect`, `usedBy.direct`: what it
|
|
42
43
|
refers to by name, what refers to it (`uses`, `users` list them); `usedBy.all`: all reaching it,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "visualproof",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "See a Lean codebase's declaration graph and the TCB of its theorems.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"build": "node scripts/build.mjs",
|
|
21
21
|
"prepack": "npm run build",
|
|
22
22
|
"serve": "node src/server/main.ts serve",
|
|
23
|
+
"showcase": "node scripts/showcase.mjs",
|
|
23
24
|
"typecheck": "tsc --noEmit -p .",
|
|
24
25
|
"test": "node --test --import ./test/setup.ts \"test/*.test.ts\"",
|
|
25
26
|
"test:toolchains": "node scripts/test-toolchains.mjs",
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
"node": "^22.18.0 || >=24.2.0"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
33
|
+
"@resvg/resvg-wasm": "2.6.2",
|
|
32
34
|
"d3-hierarchy": "^3.1.2",
|
|
33
35
|
"pdfjs-dist": "6.3.289"
|
|
34
36
|
},
|