@dev.fast/whiteboard 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 +21 -0
- package/README.md +146 -2
- package/THIRD_PARTY_NOTICES.md +93 -0
- package/dist/account-alias-DOHN1RSH.js +973 -0
- package/dist/agent-cli-ChOq0ZuO.js +117 -0
- package/dist/agent-cli-DzWfZr6G.js +2 -0
- package/dist/agent-client-CPQo7iTI.js +305 -0
- package/dist/authoring-tools-Cr6Kpjsx.js +234 -0
- package/dist/build-info.json +1 -0
- package/dist/cli-hVgHcdsv.js +47 -0
- package/dist/cli-runner-D8y2_luU.js +5095 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +128 -0
- package/dist/client-DFoh50W3.js +950 -0
- package/dist/desktop-discovery-DBO-PM2V.js +164 -0
- package/dist/error-message-OtiDonty.js +6 -0
- package/dist/fs-utils-BMPLt0cr.js +22 -0
- package/dist/fuzzy-match-BoAmcyak.js +30 -0
- package/dist/headless-host-BJxf4dUU.js +94 -0
- package/dist/input-error-OLgB_h31.js +11 -0
- package/dist/local-data-CxLk75rx.js +4491 -0
- package/dist/mcp-QeF8vkdf.js +140 -0
- package/dist/package-paths-B6-zxvIO.js +47 -0
- package/dist/process-error-telemetry-v9e5h6D7.js +3952 -0
- package/dist/profile-4ry2f3AM.js +76 -0
- package/dist/profile-Bh5FIrmf.js +2 -0
- package/dist/request-origin-D_4QIdoN.js +811 -0
- package/dist/review-agent-traces-DNJFYzc8.js +3866 -0
- package/dist/review-home-paths-6zZH-1c9.js +2560 -0
- package/dist/review-telemetry-DEFnQsQ2.js +1195 -0
- package/dist/runtime-CKiWhGrf.js +52 -0
- package/dist/runtime.d.ts +9 -0
- package/dist/runtime.js +2 -0
- package/dist/s3-SzLpeCG6.js +345 -0
- package/dist/s3-config-BgxkSoOy.js +2 -0
- package/dist/s3-config-CAxhO9u_.js +676 -0
- package/dist/server/desktop-host.d.ts +4 -0
- package/dist/server/desktop-host.js +1702 -0
- package/dist/server-discovery-Dbzn3w6Z.js +66 -0
- package/dist/sharing/index.d.ts +1977 -0
- package/dist/sharing/index.js +2 -0
- package/dist/src-CGP5ytbV.js +283 -0
- package/dist/src-CmdiBL20.js +3676 -0
- package/dist/src-DnwdaQ2r.js +865 -0
- package/dist/src-X9phtB2j.js +68 -0
- package/dist/stored-document-migration-DHeMpLMb.js +2671 -0
- package/dist/tool-failure-C8zB73HV.js +98 -0
- package/dist/tutorial-trace-DrBvkaeL.js +43 -0
- package/instructions/authoring.md +36 -0
- package/instructions/file-lenses.md +13 -0
- package/instructions/scratchpad.md +23 -0
- package/instructions/trace-archaeology.md +113 -0
- package/onboarding.md +8 -0
- package/package.json +106 -3
- package/src/agent-selection.ts +100 -0
- package/src/agent-session-ref.ts +80 -0
- package/src/ask/agents.ts +351 -0
- package/src/ask/checkout-files.ts +47 -0
- package/src/ask/file-refs.ts +111 -0
- package/src/ask/pi-mcp.ts +154 -0
- package/src/ask/protocol.ts +244 -0
- package/src/ask/thread-state.ts +350 -0
- package/src/ask/thread.ts +1400 -0
- package/src/ask/threads.ts +219 -0
- package/src/ask/watch.ts +79 -0
- package/src/cli-install.ts +1041 -0
- package/src/cli-runner.ts +1461 -0
- package/src/cli-runtime-info.ts +35 -0
- package/src/cli.ts +222 -0
- package/src/connect-prompts.ts +248 -0
- package/src/cursor-deeplink.ts +11 -0
- package/src/desktop-discovery.ts +355 -0
- package/src/diff-selection-migration.ts +63 -0
- package/src/embedded-posthog-key.ts +6 -0
- package/src/error-telemetry.ts +247 -0
- package/src/evidence.ts +14 -0
- package/src/exception-telemetry.ts +126 -0
- package/src/fixtures/blocks/call_stack_diff.json +27 -0
- package/src/fixtures/blocks/callout.json +11 -0
- package/src/fixtures/blocks/code.json +9 -0
- package/src/fixtures/blocks/code_peek.json +8 -0
- package/src/fixtures/blocks/database_lens.json +51 -0
- package/src/fixtures/blocks/divider.json +1 -0
- package/src/fixtures/blocks/fixtures.ts +33 -0
- package/src/fixtures/blocks/flow_diagram.json +36 -0
- package/src/fixtures/blocks/ids.ts +8 -0
- package/src/fixtures/blocks/image.json +9 -0
- package/src/fixtures/blocks/markdown.json +7 -0
- package/src/fixtures/blocks/section.json +11 -0
- package/src/fixtures/blocks/sequence.json +31 -0
- package/src/fixtures/blocks/software_map.json +7 -0
- package/src/fixtures/blocks/trace_quote.json +9 -0
- package/src/fixtures/blocks/tutorial.json +51 -0
- package/src/fs-utils.ts +32 -0
- package/src/fuzzy-match.ts +94 -0
- package/src/install.ts +29 -0
- package/src/legacy-skills.ts +133 -0
- package/src/lens-selection.ts +230 -0
- package/src/markdown-latex-math.ts +230 -0
- package/src/markdown.ts +81 -0
- package/src/package-paths.ts +53 -0
- package/src/posthog-capture-client.ts +610 -0
- package/src/review-api/README.md +295 -0
- package/src/review-api/activity.ts +340 -0
- package/src/review-api/agent-cli.ts +219 -0
- package/src/review-api/agent-client.ts +188 -0
- package/src/review-api/anchor-quotes.ts +88 -0
- package/src/review-api/ask-history.ts +242 -0
- package/src/review-api/authoring-tools.ts +211 -0
- package/src/review-api/blocks/call_stack_diff.ts +75 -0
- package/src/review-api/blocks/callout.ts +24 -0
- package/src/review-api/blocks/code.ts +9 -0
- package/src/review-api/blocks/code_peek.ts +13 -0
- package/src/review-api/blocks/database_lens.ts +150 -0
- package/src/review-api/blocks/definition.ts +40 -0
- package/src/review-api/blocks/divider.ts +6 -0
- package/src/review-api/blocks/flow_diagram.ts +111 -0
- package/src/review-api/blocks/image.ts +10 -0
- package/src/review-api/blocks/index.ts +90 -0
- package/src/review-api/blocks/markdown.ts +17 -0
- package/src/review-api/blocks/section.ts +24 -0
- package/src/review-api/blocks/sequence.ts +56 -0
- package/src/review-api/blocks/software_map.ts +9 -0
- package/src/review-api/blocks/trace_quote.ts +10 -0
- package/src/review-api/blocks/tutorial.ts +39 -0
- package/src/review-api/checkout-fs.ts +14 -0
- package/src/review-api/client.ts +1 -0
- package/src/review-api/comparison-coverage.ts +304 -0
- package/src/review-api/component-reference.ts +30 -0
- package/src/review-api/diff-lenses.ts +175 -0
- package/src/review-api/document-headings.ts +51 -0
- package/src/review-api/document-text.ts +200 -0
- package/src/review-api/document.ts +906 -0
- package/src/review-api/file-lenses.ts +100 -0
- package/src/review-api/http.ts +1877 -0
- package/src/review-api/image-decode.ts +29 -0
- package/src/review-api/input-error.ts +9 -0
- package/src/review-api/instructions.ts +89 -0
- package/src/review-api/lens-alignment.ts +52 -0
- package/src/review-api/local-data.ts +1837 -0
- package/src/review-api/map-input.ts +154 -0
- package/src/review-api/mcp-client-agent.ts +32 -0
- package/src/review-api/mcp.ts +240 -0
- package/src/review-api/origin.ts +43 -0
- package/src/review-api/profile.ts +146 -0
- package/src/review-api/public-tools.ts +102 -0
- package/src/review-api/pull-request.ts +389 -0
- package/src/review-api/read-schemas.ts +85 -0
- package/src/review-api/recovery.ts +2 -0
- package/src/review-api/request-origin.ts +33 -0
- package/src/review-api/review-progress.ts +382 -0
- package/src/review-api/status-tool.ts +10 -0
- package/src/review-api/store-schema.ts +22 -0
- package/src/review-api/store.ts +1647 -0
- package/src/review-api/tool-failure.ts +64 -0
- package/src/review-api/trace-schema.ts +13 -0
- package/src/review-api/traces.ts +119 -0
- package/src/review-api/unsupported-files.integration.ts +91 -0
- package/src/review-api/workspaces.ts +692 -0
- package/src/review-api/worktree-source.ts +170 -0
- package/src/review-api/worktree-structural.integration.ts +320 -0
- package/src/review-app-launcher.ts +432 -0
- package/src/review-app-picker.ts +168 -0
- package/src/review-app.ts +134 -0
- package/src/review-bundled-tools.ts +249 -0
- package/src/review-checkout-paths.ts +37 -0
- package/src/review-diff-files.ts +89 -0
- package/src/review-head-checkout.ts +300 -0
- package/src/review-home-paths.ts +73 -0
- package/src/review-info.ts +59 -0
- package/src/review-instances.ts +113 -0
- package/src/review-logger.ts +183 -0
- package/src/review-preferences.ts +88 -0
- package/src/review-prepare.ts +291 -0
- package/src/review-stack.ts +112 -0
- package/src/review-telemetry.ts +1066 -0
- package/src/runtime.ts +74 -0
- package/src/server/account-alias.ts +30 -0
- package/src/server/bounded-stream.ts +34 -0
- package/src/server/bug-report.ts +301 -0
- package/src/server/client-error-budget.ts +45 -0
- package/src/server/crash-report.ts +273 -0
- package/src/server/desktop-host-shutdown.ts +64 -0
- package/src/server/desktop-host.ts +190 -0
- package/src/server/desktop-server.ts +703 -0
- package/src/server/diffr-config.ts +509 -0
- package/src/server/diffr-languages.ts +97 -0
- package/src/server/global-verb-relay.ts +190 -0
- package/src/server/headless-host.ts +149 -0
- package/src/server/hono-http.ts +162 -0
- package/src/server/http-json.ts +24 -0
- package/src/server/json-review-reporting.ts +174 -0
- package/src/server/process-error-telemetry.ts +174 -0
- package/src/server/review-api-parsers.ts +90 -0
- package/src/server/review-lifecycle-telemetry.ts +73 -0
- package/src/server/review-open-watchdog.ts +46 -0
- package/src/server/review-server-core.ts +290 -0
- package/src/server/structural-comparisons.ts +153 -0
- package/src/server/structural-diff.ts +186 -0
- package/src/server/tutorial-service.ts +241 -0
- package/src/server/ui-telemetry.ts +198 -0
- package/src/server-discovery.ts +95 -0
- package/src/session-markers.ts +132 -0
- package/src/sharing/auth.ts +41 -0
- package/src/sharing/cli.ts +83 -0
- package/src/sharing/client.ts +334 -0
- package/src/sharing/export.ts +195 -0
- package/src/sharing/host.ts +316 -0
- package/src/sharing/import.ts +787 -0
- package/src/sharing/index.ts +16 -0
- package/src/sharing/repository.ts +145 -0
- package/src/sharing/routes.ts +34 -0
- package/src/slug.ts +23 -0
- package/src/software-map-diff-counts.ts +517 -0
- package/src/software-map-model.ts +1147 -0
- package/src/software-map-topology-diff.ts +260 -0
- package/src/source.ts +92 -0
- package/src/startup-trace.ts +232 -0
- package/src/stored-document-migration.ts +151 -0
- package/src/telemetry-clean-text.ts +257 -0
- package/src/telemetry-config.ts +298 -0
- package/src/telemetry-debug-sink.ts +38 -0
- package/src/telemetry.ts +13 -0
- package/src/trace-cli.ts +156 -0
- package/src/trace-storage-cli.ts +509 -0
- package/src/tutorial-conversation.ts +18 -0
- package/src/ui-telemetry-events.ts +765 -0
- package/src/unified-diff.ts +71 -0
- package/src/viewed-coverage.ts +259 -0
- package/src/windows-cli.ts +125 -0
- package/tutorial/document.json +275 -0
- package/tutorial/runtime-manifest.json +12 -0
- package/tutorial/sample-service/package.json +9 -0
- package/tutorial/sample-service/src/api/checkout-api.ts +17 -0
- package/tutorial/sample-service/src/app.ts +26 -0
- package/tutorial/sample-service/src/database/schema.ts +10 -0
- package/tutorial/sample-service/src/fulfillment/fulfillment-queue.ts +15 -0
- package/tutorial/sample-service/src/fulfillment/fulfillment-worker.ts +24 -0
- package/tutorial/sample-service/src/inventory/inventory-service.ts +11 -0
- package/tutorial/sample-service/src/orders/order-service.ts +34 -0
- package/tutorial/sample-service/src/orders/order.ts +21 -0
- package/tutorial/sample-service/src/orders/orders-repository.ts +24 -0
- package/tutorial/sample-service/src/payments/payment-gateway.ts +12 -0
- package/tutorial/sample-service/src/shipping/shipping-gateway.ts +15 -0
- package/tutorial/sample-service/tsconfig.json +12 -0
- package/tutorial/software-map.json +139 -0
- package/tutorial/trace.json +20 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# JSON review API
|
|
2
|
+
|
|
3
|
+
Desktop and `whiteboard server start` share `review-api.db` under `DEV_REVIEW_HOME`.
|
|
4
|
+
A headless `--state-dir` or `DEV_REVIEW_SERVER_DIR` selects an isolated profile;
|
|
5
|
+
Desktop can view it by using the same directory as `DEV_REVIEW_HOME`.
|
|
6
|
+
Both hosts mount the same routes behind token authentication and a bounded JSON request reader.
|
|
7
|
+
The canvas and Home read only the native JSON store. `POST /:id/open` opens a review
|
|
8
|
+
in Desktop, and pinned tabs reopen after restart. The startup importer migrates
|
|
9
|
+
saved MDX reviews before the server starts; there is no legacy runtime or second
|
|
10
|
+
catalog. Tests inject the native store and source-data provider.
|
|
11
|
+
|
|
12
|
+
## Storage and ownership
|
|
13
|
+
|
|
14
|
+
- `reviews`: current version and one increasing ID counter per review.
|
|
15
|
+
- `versions`: complete JSON snapshots, including title, source pins, and content.
|
|
16
|
+
- `authoring_presences`: one row per agent working on a review (focus, color slot, where it last wrote, expiry).
|
|
17
|
+
- `repositories`: server-only local paths; clients receive an ID and display name.
|
|
18
|
+
- `resources`: immutable image, trace and software-map bytes, scoped to a repository.
|
|
19
|
+
- `review_attention`: viewed/dismissed timestamps, separate from document history.
|
|
20
|
+
|
|
21
|
+
One host-owned store serializes writes, including asynchronous validation.
|
|
22
|
+
Presences show who is working across database connections and never block a
|
|
23
|
+
write. Mutation commits recheck the current version after asynchronous
|
|
24
|
+
validation, so independent connections cannot overwrite a newer version.
|
|
25
|
+
Each connection checks SQLite `data_version` every 250 ms and refreshes document,
|
|
26
|
+
catalog and activity subscriptions after another connection commits. Desktop is
|
|
27
|
+
the sole owner of workspace preparation and cleanup; headless connections never
|
|
28
|
+
instantiate that manager. A database-backed process claim prevents a second
|
|
29
|
+
Desktop from resetting live workspace generations or running duplicate jobs.
|
|
30
|
+
The caller closes the store after closing the HTTP server.
|
|
31
|
+
|
|
32
|
+
The document is a tree of Markdown and self-contained components. The server
|
|
33
|
+
adds IDs directly to those objects. No content hashes, manifests, global
|
|
34
|
+
definition tables, retired-ID scans, or second authoring representation.
|
|
35
|
+
Updates/moves retain IDs; replacement retains the outer ID but creates fresh
|
|
36
|
+
child IDs. Restoring an old snapshot does not roll back the ID counter.
|
|
37
|
+
|
|
38
|
+
## API
|
|
39
|
+
|
|
40
|
+
All paths below are relative to `/reviews-api`.
|
|
41
|
+
|
|
42
|
+
| Request | Result |
|
|
43
|
+
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
44
|
+
| `GET /` | Current review summaries |
|
|
45
|
+
| `GET /authoring` | Tool names, host input schemas and HTTP mappings for CLI/MCP adapters |
|
|
46
|
+
| `GET /capabilities` | Desktop availability and permission for optional software-map generation, independent of opening a review |
|
|
47
|
+
| `GET /:id/activity` | Currently reported authoring work, not stored in document history |
|
|
48
|
+
| `POST /:id/activity/{begin,update,end} {activityId?,focus?}` | Begin a presence (returns its `activityId`), update its focus and expiry, or end it; each returns the review's live presences |
|
|
49
|
+
| `GET /watch` | NDJSON review summaries: initial list, then saved changes |
|
|
50
|
+
| `GET /watch?subscriptions=…` | One NDJSON connection for multiple `{reviewId}` subscriptions; `reviewId:null` selects the catalog. Each line is an ordered array of `{value}` or `{error}` results, with `null` where a subscription is unchanged since the previous line. |
|
|
51
|
+
| `GET /:id` | Compact outline |
|
|
52
|
+
| `GET /:id?targetId=step-3` | Full block, sequence step, flow node or flow edge |
|
|
53
|
+
| `GET /:id?full=true` | Full snapshot |
|
|
54
|
+
| `GET /:id?version=2&full=true` | Historical snapshot |
|
|
55
|
+
| `GET /:id/history` | Saved versions with titles and timestamps |
|
|
56
|
+
| `GET /:id/inspect` | Agent reading view: nested text outline with IDs; `targetId` reads one component completely, `full=true` includes all content, `version` selects history. `format=json` returns raw data instead. |
|
|
57
|
+
| `POST /:id/open` | Open the review in the attached Desktop; report an error when none is attached |
|
|
58
|
+
| `GET /:id/watch` | NDJSON snapshots: current state immediately, then committed updates |
|
|
59
|
+
| `POST /commands` | Apply one command; return review ID, version, and for an edit the target ID, its `type`, and — after an insert or replace — `children`: its first-level children as `{id,type}` (a container's blocks; a diagram's steps, or nodes then edges), so new components are addressable without a read. A `create` with `pullRequestUrl` returns the newest existing review for that PR instead (owner/repository matched case-insensitively) unless `operation.reuseExisting` is `false`: `created:false`, a `note`, its stored `target`, `headMoved`, and `working`/`otherReviewIds` when they apply; its target is never moved. A new review reports `created:true`. Either way the result carries `review`, the review's `GET /` catalog entry (target, origin, repository name and path). An interactive `create` also opens the new review in an attached Desktop unless `operation.open` is `false`, and reports `opened` with the open result or an `openError`; the review is saved either way |
|
|
60
|
+
| `POST /commands {operation:{type:"lens_edit",reviewId,edit}}` | Write one file lens, credited to `activityId` when given: `insert {title,targets,afterId?}` (host id `lens-N`), `update {targetId,title?,targets?}` or `remove {targetId}`. Returns `{targetId, type:"lens", uncategorized}`, where `uncategorized` lists changed files and ranges no lens covers yet (at most 50 files) |
|
|
61
|
+
| `GET /:id/lenses` | The current version's file lenses with each one's file count, plus the same `uncategorized` report |
|
|
62
|
+
| `POST /repositories {path}` | Register a local Git/jj repository; return ID/name |
|
|
63
|
+
| `POST /resources` | Upload an image, trace, or map; return resource ID/kind/MIME type |
|
|
64
|
+
| `GET /:id/resources/:resourceId` | Read retained bytes scoped to the review repository; desktop authentication required |
|
|
65
|
+
| `GET /:id/maps/:resourceId?version=0` | Read a pinned map with source-change counts for that review version |
|
|
66
|
+
| `GET /:id/file?side=head&file=src/app.ts` | Read current target source; version selects authored content; live source always follows the checkout |
|
|
67
|
+
| `GET /:id/tree?path=src&side=head` | Immediate target directory entries; path defaults to root, side to head; optional version/commit |
|
|
68
|
+
| `GET /:id/commits?version=0` | List commits and their first-parent statistics for that review version |
|
|
69
|
+
| `GET /:id/diff` | Changed-file summaries `[{path, previousPath?, status, additions, deletions}]`; optional version and commit |
|
|
70
|
+
|
|
71
|
+
Example request:
|
|
72
|
+
|
|
73
|
+
`review_get` uses `/inspect`. MCP returns its text directly, and
|
|
74
|
+
`whiteboard api review_get '{"reviewId":"…","full":true}'` prints it without JSON
|
|
75
|
+
escaping. Use `format:"json"` (or CLI `--json`) when raw objects are needed.
|
|
76
|
+
The canvas continues to use the JSON snapshot routes above.
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"operation": {
|
|
81
|
+
"type": "edit",
|
|
82
|
+
"reviewId": "<returned by create>",
|
|
83
|
+
"edit": {
|
|
84
|
+
"type": "insert",
|
|
85
|
+
"content": {
|
|
86
|
+
"type": "markdown",
|
|
87
|
+
"markdown": "# Summary\n\nWhat changed."
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Commands: `create {title,target,pullRequestUrl?,reuseExisting?}` or `create {pullRequestUrl,title?,repositoryId?,reuseExisting?}`, `set_target {reviewId,target,pullRequestUrl?}`, `edit {reviewId,edit}`, `rename {reviewId,title}`,
|
|
95
|
+
`restore {reviewId,version}`. A review's pins, `{repositoryId,base,head}`, are its target resolved to immutable commits.
|
|
96
|
+
Agents name the checkout by `repositoryPath` in a target, or on a create from a PR alone; `/commands` registers the path and passes the store its id. Retargeting preserves content and component IDs. Restore restores title, target, PR identity, and content. Live targets still read the current checkout.
|
|
97
|
+
PR URLs must be canonical `https://github.com/owner/repository/pull/123` URLs. The PR number is derived from the URL; identity is metadata alongside immutable pins, not a moving source reference. A `create` with a target keeps that target and treats the URL as identity only. A `create` with the URL and no target resolves the PR when accepted: it reads the PR with `gh pr view` (falling back to the public GitHub API), picks the registered checkout named by `repositoryId`, else the checkout of the PR's existing review, else the first registered checkout with a remote whose configured URL is `github.com/owner/repository`, and fetches `refs/pull/N/head` and the base branch from that remote into `refs/review/github/owner/repository/pull/N/*`, never moving branches or bookmarks (a jj repository indexes the commits through a transient tag). It pins that head and its merge base with the base branch; for a PR absorbed by a merge commit it uses the merge base with GitHub's frozen base commit instead. The title defaults to the PR title. A repeat resolves the PR again, so `headMoved` compares the existing review with the PR's current head. `set_target` preserves the document and component IDs, including when source commits change. Its response reports retained source ranges to verify, those in files the new commits changed, and resources that no longer match the pins; agents repair these with `edit`. Existing versions keep their original pins and content. It preserves omitted PR identity within one repository, clears it when switching repositories, and accepts an explicit URL or null.
|
|
98
|
+
|
|
99
|
+
`attention {reviewId,action:"view"|"dismiss"|"restore"}` records viewing or
|
|
100
|
+
reversible dismissal without creating a document version. Home summaries include
|
|
101
|
+
the repository name and attention timestamps.
|
|
102
|
+
The list stream is separate from document streams. Dismissal closes
|
|
103
|
+
the native tab and can be undone from Home. Dismissed API reviews stay saved;
|
|
104
|
+
`delete {reviewId}` permanently removes their versions. Old command
|
|
105
|
+
inputs are erased but their IDs remain, so delayed retries cannot resurrect content.
|
|
106
|
+
Repository resources remain shared. Home and the canvas open a pinned, read-only
|
|
107
|
+
source tree. Each source tab names its review version; files opened from it use
|
|
108
|
+
the same version and side through the API, without a client-side checkout path.
|
|
109
|
+
|
|
110
|
+
Edits: `insert {content,parentId?,afterId?}`, `update {targetId,changes}`,
|
|
111
|
+
`move {targetId,parentId?,afterId?}`, `remove {targetId}`,
|
|
112
|
+
`replace {targetId,content}`. Omitted placement appends to the root; on the
|
|
113
|
+
scratchpad it prepends instead, so the pad reads newest first. Diagram
|
|
114
|
+
units (a `step` in a sequence, a `flow_node` or `flow_edge` in a flow diagram)
|
|
115
|
+
require their diagram as the parent and can move within it, but not between
|
|
116
|
+
diagrams; removing a flow node removes the edges that touched it. A new
|
|
117
|
+
`flow_node` may carry `link:{from|to,label?,style?}` naming a node already
|
|
118
|
+
drawn: the node and its edge are saved in one version, the edge stored as an
|
|
119
|
+
ordinary `flow_edge`, and the version's `lastEdit.linkId` names it so the
|
|
120
|
+
canvas draws the node in its final place and then the edge. Field patches
|
|
121
|
+
preserve omitted values; null removes optional fields. Child collections use
|
|
122
|
+
structural edits or replacement. Use fresh content without IDs for insert/replace.
|
|
123
|
+
|
|
124
|
+
Each accepted edit is one saved version, and the version carries
|
|
125
|
+
`lastEdit: {type, targetId, blockId, kind, unit?, linkId?, fields?, units?}`:
|
|
126
|
+
the edit's kind, the element it landed on, what that element is, and the block
|
|
127
|
+
it belongs to (`unit` names a step, flow node or flow edge inside `blockId`;
|
|
128
|
+
`fields` lists an update's patched keys, so a `defaultCollapsed` patch draws nothing;
|
|
129
|
+
`units` lists a diagram's steps, or its nodes and edges, in drawing order when
|
|
130
|
+
the diagram was inserted or replaced whole, each edge once both of its nodes
|
|
131
|
+
are drawn). Versions made by rename, set_target, restore or import carry none.
|
|
132
|
+
While a reader is watching, the canvas draws each version's edit as it lands:
|
|
133
|
+
a paragraph lands, a unit added to a diagram is traced where it attaches, and a
|
|
134
|
+
diagram written whole is traced in one quick pass.
|
|
135
|
+
|
|
136
|
+
There is no expected-version parameter. Later same-field edits win. A command
|
|
137
|
+
whose response was lost may or may not have applied; read the review before
|
|
138
|
+
retrying.
|
|
139
|
+
|
|
140
|
+
## Validation and remaining work
|
|
141
|
+
|
|
142
|
+
Markdown source links use `[label](review-source:head/src/save.ts#L10-L24)`
|
|
143
|
+
(or `base`, or `#L10` for one line). Paths are repository-relative and URL-encoded
|
|
144
|
+
where needed. Inline and reference-style links open the existing native side peek.
|
|
145
|
+
The same Markdown parser feeds the host's source checks and the renderer, so code
|
|
146
|
+
examples and unused definitions do not become source requests. Invalid paths or
|
|
147
|
+
ranges reject the edit before saving. No extra node type or endpoint is needed.
|
|
148
|
+
|
|
149
|
+
Heading ids are `slugify(text)` made unique in document order over section
|
|
150
|
+
titles and the root-level h2/h3 of Markdown blocks, and `[text](#slug)` links
|
|
151
|
+
scroll to them. Markdown images with `https:` sources render inline.
|
|
152
|
+
|
|
153
|
+
The component schema checks inputs; field patches are checked after merging
|
|
154
|
+
with the target. A small relationship pass checks diagram actors, store fields,
|
|
155
|
+
and base/head frame sides. Sources and resource references use required host
|
|
156
|
+
providers before a version is saved; unchanged references at unchanged pins
|
|
157
|
+
are not checked again. Provider errors must use `ReviewInputError` for messages
|
|
158
|
+
safe to show to clients; unexpected provider/storage failures return HTTP 500.
|
|
159
|
+
|
|
160
|
+
The local provider uses existing Git/jj helpers to read committed objects, not
|
|
161
|
+
working-copy files. It checks code ranges and resource ownership before saving.
|
|
162
|
+
Images are fully decoded to PNG; traces retain supplied text with an explicit
|
|
163
|
+
client-supplied provenance label. Map uploads use the existing nested map format,
|
|
164
|
+
with a JSON shape check followed by the existing relationship/coverage validator
|
|
165
|
+
and pinned source-range checks. Uploads take `{id,repositoryId,kind,...}` with
|
|
166
|
+
`base64` for images, `trace:{label,events:[{id,role,text}]}` for traces, or
|
|
167
|
+
`pins,side,model` for maps. Reusing an upload ID requires identical content.
|
|
168
|
+
|
|
169
|
+
The canvas preserves React identities during updates. The stream coalesces
|
|
170
|
+
updates when a reader falls behind; reconnecting starts with the current saved
|
|
171
|
+
snapshot. Historical views read a fixed snapshot and do not follow live edits.
|
|
172
|
+
Call-stack frames can supply a component-local `key` to align the same frame
|
|
173
|
+
across base/head despite moved source ranges. Without a key, matching uses the
|
|
174
|
+
file and range. This is separate from each frame's durable element identity.
|
|
175
|
+
|
|
176
|
+
File and diff reads also accept `commit` to compare one listed commit against
|
|
177
|
+
its first parent. It must belong to the requested review version; an unrelated
|
|
178
|
+
commit returns 404. Without it, the comparison is the review's base and head.
|
|
179
|
+
|
|
180
|
+
Native code-peek and diff widgets can now consume API-backed read-only models,
|
|
181
|
+
including renamed files and absent diff sides. Native opening supplies this
|
|
182
|
+
adapter to the API canvas. Inline maps use the same pinned-source API for their
|
|
183
|
+
code inspectors, including unchanged mapped ranges. Immutable map resources
|
|
184
|
+
change through document edits, so these maps do not expose the old artifact
|
|
185
|
+
refresh action. Fullscreen uses the existing canvas-root overlay.
|
|
186
|
+
The Map tab uses the retained head/base maps and updates as they arrive.
|
|
187
|
+
The Trace tab and quote side panels read retained trace resources; imported
|
|
188
|
+
labels are preserved without claiming a harness, commit association, or timestamps.
|
|
189
|
+
|
|
190
|
+
The thin agent clients use `whiteboard api <tool-name> '<json>'` (or `-` for stdin)
|
|
191
|
+
and `whiteboard mcp` (stdio). `whiteboard api tools` lists the host's tools, one line each, and `whiteboard api tools <name>` prints one tool's schema.
|
|
192
|
+
Both adapters use existing desktop discovery/authentication and the same HTTP
|
|
193
|
+
routes as the canvas. Neither imports the store or validates document content.
|
|
194
|
+
Command/resource schemas come from the server's existing Zod definitions and
|
|
195
|
+
the read routes share their query schemas with the catalog (`read-schemas.ts`);
|
|
196
|
+
the MCP SDK handles framing. The checkout skill describes this JSON workflow while
|
|
197
|
+
preserving the writing guidance. No integration is installed automatically.
|
|
198
|
+
|
|
199
|
+
The Review tab counts a review as ready once it has content and no authoring
|
|
200
|
+
presence is live. The last presence ending (or expiring) is the only completion
|
|
201
|
+
signal; there is no per-section progress state. Versions and share bundles
|
|
202
|
+
saved while sections carried a `status` field are read and imported without it;
|
|
203
|
+
new edits that send one are rejected by the strict section
|
|
204
|
+
schema.
|
|
205
|
+
|
|
206
|
+
Activity is presence, not ownership. Begin returns a host-assigned `activityId`
|
|
207
|
+
and a color slot (the lowest one free on that review, kept until it ends);
|
|
208
|
+
update changes the focus and extends the presence; end removes it. `edit` and
|
|
209
|
+
`lens_edit` accept an optional `activityId`: the write renews that presence,
|
|
210
|
+
records where it last wrote (`document` or `lenses`), and stamps the version's
|
|
211
|
+
`lastEdit.activityId` so the canvas knows whose courier draws it. Without one,
|
|
212
|
+
a write is credited to the review's only presence when there is exactly one. No
|
|
213
|
+
write is ever refused because another agent is working. A presence expires 3
|
|
214
|
+
minutes after its last credited write or update; deletion removes it. Uploads
|
|
215
|
+
are immutable repository resources and do not require a presence.
|
|
216
|
+
The existing document stream includes an `activity` snapshot and also sends on
|
|
217
|
+
activity changes; activity-only sends reuse the loaded document, and the canvas
|
|
218
|
+
only loads document data when its version changes.
|
|
219
|
+
This avoids another long-lived browser connection. The badge is hidden while
|
|
220
|
+
idle or viewing history, and reports unknown activity on a lost connection.
|
|
221
|
+
Optional `focus:{description,targetId?}` identifies the current work; description is 1–160 characters and targetId is an existing component ID. Omitted focus retains the current focus; null clears it. Snapshots list `activities` (`activityId`, `slot`, `focus?`, `surface?`) while any are live. The header shows descriptions, and matching components show an inline working indicator. Focus is ephemeral, disappears when its presence ends or expires, and is hidden when activity is unknown or history is displayed.
|
|
222
|
+
There is no applying-update state. CLI/MCP expose this as `review_activity_begin`, `review_activity_update` and `review_activity_end`.
|
|
223
|
+
|
|
224
|
+
Profile migration remains later work.
|
|
225
|
+
|
|
226
|
+
The focused test file exercises all twelve block kinds, edits and identity,
|
|
227
|
+
history/restart, retries, asynchronous validation, isolation, and the actual
|
|
228
|
+
desktop HTTP route. The local-data tests use a real Git repository with dirty
|
|
229
|
+
working-copy files, decoded images and saved trace/map evidence, including real
|
|
230
|
+
HTTP requests and restart. Existing desktop-server tests remain unchanged.
|
|
231
|
+
|
|
232
|
+
### Language information and committed source
|
|
233
|
+
|
|
234
|
+
Committed reviews use Review-owned worktrees at their base/head commits for
|
|
235
|
+
language services. The displayed source remains the immutable Git source.
|
|
236
|
+
Existing matching managed checkouts are reused; an equal base/head shares one
|
|
237
|
+
checkout. Opening a review prepares its current sides in the background; older
|
|
238
|
+
versions and selected commits acquire environments on demand.
|
|
239
|
+
|
|
240
|
+
Configure preparation through the repository's existing Git configuration:
|
|
241
|
+
|
|
242
|
+
```sh
|
|
243
|
+
git config devfast.prepare 'pnpm install --frozen-lockfile'
|
|
244
|
+
git config --add devfast.prepare 'pnpm generate'
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Commands run in order inside each managed checkout, never in the invoking user
|
|
248
|
+
checkout. Successful preparation is cached by checkout and command-list hash;
|
|
249
|
+
changed commands or recreated checkouts invalidate it. Preparation has no canvas
|
|
250
|
+
disclosure. `review_open`, and `review_create` when it opens the review, starts acquisition in the background and returns any
|
|
251
|
+
already-recorded acquisition issues. `review_environment` rechecks current base/head
|
|
252
|
+
checkouts; `retry:true` explicitly reruns failed preparation. Missing setup, pending preparation,
|
|
253
|
+
and failed commands with a usable checkout do not produce issues. These checks
|
|
254
|
+
report acquisition failures (including transient errors), not end-to-end LSP health.
|
|
255
|
+
`review_workspace_cleanup` lists failed cleanup of retired checkouts and accepts
|
|
256
|
+
`workspaceId` to retry their removal. Reading and authoring stay available
|
|
257
|
+
while preparation runs. Language requests wait for preparation; no command or a
|
|
258
|
+
failed command leaves best-effort language services in that same pinned checkout,
|
|
259
|
+
without silently borrowing another checkout. Timeout and shutdown stop command
|
|
260
|
+
process groups, leave no successful marker, and allow retry.
|
|
261
|
+
|
|
262
|
+
Language queries require the displayed file to exactly match the file in the
|
|
263
|
+
language environment. A changed file suppresses queries even on unchanged lines;
|
|
264
|
+
matching contents use the same positions directly. Stale-request checks discard
|
|
265
|
+
answers if the source or environment changes during a request.
|
|
266
|
+
|
|
267
|
+
Definitions, type definitions, implementations, and references stay in the same
|
|
268
|
+
review version, side, and selected commit when the destination file matches its
|
|
269
|
+
saved source. Preparation may generate or modify files: changed or absent saved
|
|
270
|
+
destinations retain their native managed-checkout URIs.
|
|
271
|
+
|
|
272
|
+
Preparation does not guarantee reproducibility unless the configured commands
|
|
273
|
+
also reproduce dependencies, generated files, and the toolchain. Historical
|
|
274
|
+
checkouts remain until their owning review is deleted. Environment state and
|
|
275
|
+
commands are local and are never authored into review documents.
|
|
276
|
+
|
|
277
|
+
## Review targets
|
|
278
|
+
|
|
279
|
+
`target` is either `{kind:"worktree",repositoryId,base?}` or
|
|
280
|
+
`{kind:"commits",repositoryId,head,base?}`. Commit revisions resolve on acceptance.
|
|
281
|
+
Omitted commit base means source at head with no diff, exactly as base=head;
|
|
282
|
+
supply its parent to review the changes introduced by a single commit.
|
|
283
|
+
|
|
284
|
+
A worktree target follows saved files in that registered checkout, including
|
|
285
|
+
staged and unstaged changes. Git's untracked files are left out; `git add -N` a
|
|
286
|
+
new file to include it (jj tracks new files itself). The Diff view counts the
|
|
287
|
+
untracked files left out. `base` names the branch to
|
|
288
|
+
compare against, by default the default branch (`origin/HEAD`, `origin/main`,
|
|
289
|
+
`origin/master`, `main`, then `master`); an unborn repository compares with
|
|
290
|
+
empty source. The comparison starts at the merge base of `base` and HEAD,
|
|
291
|
+
resolved again whenever the checkout or its refs change, so it follows a rebase;
|
|
292
|
+
if `base` stops resolving, the last merge base stays. No checkout is created.
|
|
293
|
+
Source ranges default to the head side. File saves refresh source without changing
|
|
294
|
+
authored history. All versions of a live target read the current checkout; authors
|
|
295
|
+
maintain their source references. Use a commit target for fixed source.
|