@dev.fast/whiteboard 0.5.0 → 0.5.2-preview.20261104.146
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/dist/{account-alias-Bw3PT3Qo.js → account-alias-BlYamXAG.js} +5 -5
- package/dist/{agent-cli-kHRrwO4n.js → agent-cli-D7fF5xmm.js} +9 -9
- package/dist/agent-cli-DLibAL4u.js +2 -0
- package/dist/{agent-client-CMacGbMp.js → agent-client-BCEbSPWU.js} +4 -4
- package/dist/{authoring-tools-CiLy46kh.js → authoring-tools-CkfxTVJm.js} +12 -8
- package/dist/{background-server-eZWXoVcI.js → background-server-BraP8pJ9.js} +4 -4
- package/dist/{background-server-BLNHbksB.js → background-server-CwToVN1g.js} +1 -1
- package/dist/build-info.json +1 -1
- package/dist/{cli-Bxmiqutp.js → cli-BpadBaGU.js} +1 -1
- package/dist/{cli-runner-DQPuu7kJ.js → cli-runner-BebYF50a.js} +22 -22
- package/dist/cli.js +2 -2
- package/dist/{fuzzy-match-DZjeOaPY.js → fuzzy-match-CxcsLQGx.js} +3 -3
- package/dist/{headless-host-Dl2KZ9IT.js → headless-host-FAlbekFD.js} +561 -415
- package/dist/{headless-host-B4r0s1ks.js → headless-host-cLipIufH.js} +1 -1
- package/dist/{import-YAIU6rB0.js → import-CZ1958L4.js} +234 -62
- package/dist/{local-data-C58vzLZR.js → local-data-DdFkxFK_.js} +41 -16
- package/dist/{mcp-COYWiGVn.js → mcp-Claiy9xE.js} +9 -6
- package/dist/{package-paths-Cg6fnaGp.js → package-paths-Dk7MOXxN.js} +1 -1
- package/dist/{profile--BYIjPkc.js → profile-Bsgzi9PA.js} +2 -2
- package/dist/profile-BxdzBxHW.js +2 -0
- package/dist/{remote-attach-C1prLjmj.js → remote-attach-LGTpwpUv.js} +4 -4
- package/dist/{remote-extensions-Bw029iIS.js → remote-extensions-BvV29_gk.js} +1 -1
- package/dist/{remote-extensions-MUUgbLJn.js → remote-extensions-L95HNwIH.js} +2 -2
- package/dist/{remote-language-server-z3rdHcLL.js → remote-language-server-BAznkpeu.js} +4 -4
- package/dist/{remote-uninstall-B3Slwor1.js → remote-uninstall-CLP79Cuk.js} +5 -5
- package/dist/{request-origin-B3_XI2VA.js → request-origin-D6B-zrL8.js} +27 -5
- package/dist/{review-app-launcher-BZEbDKuK.js → review-app-launcher-tTe8bTwg.js} +2 -2
- package/dist/{review-home-paths-LdGS4SpR.js → review-home-paths-BmZX2qiz.js} +1 -1
- package/dist/{review-telemetry-x8u-9EZb.js → review-telemetry-DACDMfqq.js} +4 -4
- package/dist/server/desktop-host.js +26 -38
- package/dist/{server-discovery-WmuFl2S3.js → server-discovery-CV5qf1J8.js} +2 -2
- package/dist/sharing/index.d.ts +137 -14
- package/dist/sharing/index.js +1 -1
- package/dist/{src-B2b8cCoI.js → src-BQDlJXkG.js} +44 -5
- package/dist/{src-DLWol7GZ.js → src-CrrW7lcY.js} +16 -1
- package/dist/{stored-document-migration-iwIQ4l5G.js → stored-document-migration-D1wK4yID.js} +3 -3
- package/dist/{thread-state-B7L1mpN_.js → thread-state-WTqSborE.js} +1 -1
- package/dist/{tool-failure-RLR8m9hq.js → tool-failure-YOFGHJCZ.js} +319 -55
- package/instructions/animation.md +69 -5
- package/instructions/animations/before-after-structure/README.md +27 -0
- package/instructions/animations/before-after-structure/animation.html +89 -0
- package/instructions/animations/before-after-structure/block.json +10 -0
- package/instructions/animations/before-after-structure/frames.json +313 -0
- package/instructions/animations/cache-fill-evict/README.md +24 -0
- package/instructions/animations/cache-fill-evict/animation.html +81 -0
- package/instructions/animations/cache-fill-evict/block.json +13 -0
- package/instructions/animations/cache-fill-evict/frames.json +79 -0
- package/instructions/animations/cache-fill-evict/scenarios.json +17 -0
- package/instructions/animations/log-replay/README.md +25 -0
- package/instructions/animations/log-replay/animation.html +86 -0
- package/instructions/animations/log-replay/block.json +10 -0
- package/instructions/animations/log-replay/frames.json +143 -0
- package/instructions/animations/log-replay/scenarios.json +18 -0
- package/instructions/animations/queue-workers/README.md +23 -0
- package/instructions/animations/queue-workers/animation.html +107 -0
- package/instructions/animations/queue-workers/block.json +13 -0
- package/instructions/animations/queue-workers/frames.json +119 -0
- package/instructions/animations/queue-workers/scenarios.json +18 -0
- package/instructions/animations/race-two-lanes/README.md +22 -0
- package/instructions/animations/race-two-lanes/animation.html +97 -0
- package/instructions/animations/race-two-lanes/block.json +1 -0
- package/instructions/animations/race-two-lanes/frames.json +234 -0
- package/instructions/animations/race-two-lanes/scenarios.json +19 -0
- package/instructions/animations/request-across-layers/README.md +24 -0
- package/instructions/animations/request-across-layers/animation.html +85 -0
- package/instructions/animations/request-across-layers/block.json +17 -0
- package/instructions/animations/request-across-layers/frames.json +58 -0
- package/instructions/animations/request-across-layers/scenarios.json +12 -0
- package/instructions/animations/request-timing/README.md +22 -0
- package/instructions/animations/request-timing/animation.html +120 -0
- package/instructions/animations/request-timing/block.json +21 -0
- package/instructions/animations/request-timing/markers.json +32 -0
- package/instructions/animations/request-timing/scenarios.json +4 -0
- package/instructions/animations/retry-backoff/README.md +22 -0
- package/instructions/animations/retry-backoff/animation.html +122 -0
- package/instructions/animations/retry-backoff/block.json +10 -0
- package/instructions/animations/retry-backoff/frames.json +65 -0
- package/instructions/animations/retry-backoff/scenarios.json +12 -0
- package/instructions/animations/state-machine/README.md +24 -0
- package/instructions/animations/state-machine/animation.html +95 -0
- package/instructions/animations/state-machine/block.json +9 -0
- package/instructions/animations/state-machine/frames.json +79 -0
- package/instructions/animations/state-machine/scenarios.json +12 -0
- package/instructions/animations/video-platform-architecture/README.md +24 -0
- package/instructions/animations/video-platform-architecture/animation.html +76 -0
- package/instructions/animations/video-platform-architecture/block.json +17 -0
- package/instructions/animations/video-platform-architecture/frames.json +97 -0
- package/instructions/animations/video-platform-architecture/scenarios.json +28 -0
- package/instructions/whiteboard.d.ts +168 -14
- package/package.json +6 -6
- package/src/animation-stage-kit.ts +150 -10
- package/src/cli-runner.ts +4 -1
- package/src/fixtures/blocks/clip.json +19 -0
- package/src/review-api/README.md +1 -0
- package/src/review-api/agent-cli.ts +3 -2
- package/src/review-api/animation-drafts.ts +151 -47
- package/src/review-api/animation-references.ts +92 -0
- package/src/review-api/animation-render.ts +106 -0
- package/src/review-api/authoring-tools.ts +10 -3
- package/src/review-api/document-text.ts +27 -12
- package/src/review-api/http.ts +52 -6
- package/src/review-api/instructions.ts +1 -1
- package/src/review-api/mcp.ts +10 -5
- package/src/review-api/public-tools.ts +71 -2
- package/src/review-api/store.ts +89 -12
- package/src/server/desktop-server.ts +17 -5
- package/src/server/headless-host.ts +4 -0
- package/src/server/review-gateway.ts +1 -0
- package/src/server/review-server-core.ts +71 -12
- package/src/sharing/client.ts +129 -32
- package/src/sharing/export.ts +42 -5
- package/src/sharing/file.ts +8 -0
- package/src/sharing/host.ts +202 -73
- package/src/sharing/import.ts +125 -33
- package/src/ui-telemetry-events.ts +25 -1
- package/dist/agent-cli-B8KBHuh_.js +0 -2
- package/dist/profile-BjcXi-oH.js +0 -2
package/src/sharing/import.ts
CHANGED
|
@@ -21,7 +21,10 @@ import {
|
|
|
21
21
|
import { textIncludesQuote } from "@review/evidence.js";
|
|
22
22
|
import type { LocalReviewData } from "@review/review-api/local-data.js";
|
|
23
23
|
import { pullRequestUrl } from "@review/review-api/origin.js";
|
|
24
|
-
import type {
|
|
24
|
+
import type {
|
|
25
|
+
ReviewStore,
|
|
26
|
+
SharedProvenance,
|
|
27
|
+
} from "@review/review-api/store.js";
|
|
25
28
|
import { traceSchema } from "@review/review-api/trace-schema.js";
|
|
26
29
|
import {
|
|
27
30
|
devReviewHome,
|
|
@@ -45,7 +48,7 @@ import {
|
|
|
45
48
|
sharedGit,
|
|
46
49
|
} from "./repository.js";
|
|
47
50
|
|
|
48
|
-
export const sharedSnapshotSchema = z.
|
|
51
|
+
export const sharedSnapshotSchema = z.object({
|
|
49
52
|
reviewId: z.string().min(1),
|
|
50
53
|
version: z.number().int().nonnegative(),
|
|
51
54
|
/** Empty for a board never named; it reads "Untitled". */
|
|
@@ -60,7 +63,7 @@ export const sharedSnapshotSchema = z.strictObject({
|
|
|
60
63
|
lenses: z.array(lensSchema).optional(),
|
|
61
64
|
createdAt: z.string(),
|
|
62
65
|
origin: z
|
|
63
|
-
.
|
|
66
|
+
.object({
|
|
64
67
|
branch: z.string().optional(),
|
|
65
68
|
baseRef: z.string().optional(),
|
|
66
69
|
baseBranch: z.string().optional(),
|
|
@@ -75,7 +78,7 @@ export const sharedSnapshotSchema = z.strictObject({
|
|
|
75
78
|
|
|
76
79
|
const count = z.number().int().nonnegative();
|
|
77
80
|
|
|
78
|
-
const counts = z.
|
|
81
|
+
const counts = z.object({ additions: count, deletions: count });
|
|
79
82
|
|
|
80
83
|
const mapSchema = softwareModelDataSchema.extend({
|
|
81
84
|
commit: z.string().regex(COMMIT_ID),
|
|
@@ -88,10 +91,10 @@ const mapSchema = softwareModelDataSchema.extend({
|
|
|
88
91
|
counts.extend({
|
|
89
92
|
file: z.string(),
|
|
90
93
|
hunks: z.array(
|
|
91
|
-
z.
|
|
94
|
+
z.object({
|
|
92
95
|
startLine: count,
|
|
93
96
|
lines: z.array(
|
|
94
|
-
z.
|
|
97
|
+
z.object({
|
|
95
98
|
kind: z.enum(["add", "remove"]),
|
|
96
99
|
oldLine: count.nullable(),
|
|
97
100
|
newLine: count.nullable(),
|
|
@@ -106,7 +109,7 @@ const mapSchema = softwareModelDataSchema.extend({
|
|
|
106
109
|
),
|
|
107
110
|
});
|
|
108
111
|
|
|
109
|
-
export const sharePresentationSchema = z.
|
|
112
|
+
export const sharePresentationSchema = z.object({
|
|
110
113
|
maps: z.record(z.string(), mapSchema),
|
|
111
114
|
});
|
|
112
115
|
|
|
@@ -129,6 +132,12 @@ export function needsRepository(
|
|
|
129
132
|
|
|
130
133
|
export function validateShareBundle(input: ShareBundle) {
|
|
131
134
|
const bundle = shareBundleSchema.parse(input);
|
|
135
|
+
|
|
136
|
+
if (bundle.frozen)
|
|
137
|
+
throw new ReviewInputError(
|
|
138
|
+
"This whiteboard is a read-only snapshot of uncommitted changes. View it in the browser.",
|
|
139
|
+
409,
|
|
140
|
+
);
|
|
132
141
|
// SAFETY: a bundle is parsed from JSON, so its snapshot is a JSON object.
|
|
133
142
|
const stored = bundle.snapshot as JsonObject;
|
|
134
143
|
|
|
@@ -235,18 +244,99 @@ export interface ShareImport {
|
|
|
235
244
|
onStage?: (stage: "fetching" | "validating") => void;
|
|
236
245
|
}
|
|
237
246
|
|
|
238
|
-
|
|
239
|
-
|
|
247
|
+
export const FRESH_IMPORT_VERSION = 0;
|
|
248
|
+
|
|
249
|
+
/** The revision a link serves and its share's latest. */
|
|
250
|
+
export interface ServedRevision {
|
|
251
|
+
revision: { id: string; version: number; createdAt: number };
|
|
252
|
+
latest: string;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export type ShareCopyPlan =
|
|
256
|
+
| { kind: "open"; reviewId: string }
|
|
257
|
+
| { kind: "refresh"; reviewId: string; version: number }
|
|
258
|
+
| { kind: "import" };
|
|
259
|
+
|
|
260
|
+
/** Which copy a served revision opens or refreshes in place; otherwise a new copy. */
|
|
261
|
+
export function planShareCopy(
|
|
262
|
+
copies: ReturnType<ReviewStore["copiesOf"]>,
|
|
263
|
+
served: ServedRevision,
|
|
264
|
+
pinned = false,
|
|
265
|
+
): ShareCopyPlan {
|
|
266
|
+
const same = copies.find(({ shared }) =>
|
|
267
|
+
shared.revisionId === undefined
|
|
268
|
+
? shared.sharedAt === served.revision.createdAt
|
|
269
|
+
: shared.revisionId === served.revision.id,
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
if (same) return { kind: "open", reviewId: same.reviewId };
|
|
273
|
+
|
|
274
|
+
const unedited =
|
|
275
|
+
!pinned &&
|
|
276
|
+
served.revision.id === served.latest &&
|
|
277
|
+
copies.find(
|
|
278
|
+
(copy) =>
|
|
279
|
+
!copy.shared.pinned &&
|
|
280
|
+
copy.version === (copy.shared.importedVersion ?? FRESH_IMPORT_VERSION),
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
return unedited
|
|
284
|
+
? {
|
|
285
|
+
kind: "refresh",
|
|
286
|
+
reviewId: unedited.reviewId,
|
|
287
|
+
version: unedited.version,
|
|
288
|
+
}
|
|
289
|
+
: { kind: "import" };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Opens, refreshes or copies a link's board by the revision it serves. */
|
|
293
|
+
export async function receiveShare(
|
|
294
|
+
input: ShareImport,
|
|
295
|
+
key: string,
|
|
296
|
+
served: ServedRevision,
|
|
297
|
+
download: () => Promise<{
|
|
298
|
+
bundle: ShareBundle;
|
|
299
|
+
attribution: ShareAttribution;
|
|
300
|
+
}>,
|
|
301
|
+
pinned = false,
|
|
302
|
+
): Promise<string> {
|
|
303
|
+
const plan = planShareCopy(input.store.copiesOf(key), served, pinned);
|
|
304
|
+
|
|
305
|
+
if (plan.kind === "open") return plan.reviewId;
|
|
306
|
+
const { bundle, attribution } = await download();
|
|
307
|
+
|
|
308
|
+
const provenance = {
|
|
309
|
+
...attribution,
|
|
310
|
+
revisionId: served.revision.id,
|
|
311
|
+
...(pinned && { pinned }),
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
if (plan.kind === "import")
|
|
315
|
+
return importShare(input, key, bundle, provenance);
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
return await importShare(input, key, bundle, provenance, plan);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
// The board was edited or deleted since the plan read it.
|
|
321
|
+
if (
|
|
322
|
+
error instanceof ReviewInputError &&
|
|
323
|
+
(error.status === 409 || error.status === 404)
|
|
324
|
+
)
|
|
325
|
+
return importShare(input, key, bundle, provenance);
|
|
326
|
+
throw error;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Imports a share as an ordinary board, or into a copy of its link. */
|
|
240
331
|
export async function importShare(
|
|
241
332
|
input: ShareImport,
|
|
242
333
|
key: string,
|
|
243
334
|
received: ShareBundle,
|
|
244
|
-
|
|
335
|
+
provenance?: ShareAttribution &
|
|
336
|
+
Pick<SharedProvenance, "revisionId" | "pinned">,
|
|
337
|
+
into?: { reviewId: string; version: number },
|
|
245
338
|
): Promise<string> {
|
|
246
339
|
const { store, data } = input;
|
|
247
|
-
const existing = store.copyOf(key);
|
|
248
|
-
|
|
249
|
-
if (existing) return existing;
|
|
250
340
|
const { bundle, snapshot, maps } = validateShareBundle(received);
|
|
251
341
|
const cloneUrl = bundle.repository?.cloneUrl;
|
|
252
342
|
let repositoryId: string | undefined;
|
|
@@ -319,27 +409,29 @@ export async function importShare(
|
|
|
319
409
|
|
|
320
410
|
for (const [id, copy] of ids) document = document.replaceAll(id, copy);
|
|
321
411
|
|
|
322
|
-
const
|
|
323
|
-
{
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
...
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}),
|
|
332
|
-
},
|
|
412
|
+
const create = {
|
|
413
|
+
operation: {
|
|
414
|
+
type: "create",
|
|
415
|
+
...(snapshot.title && { title: snapshot.title }),
|
|
416
|
+
...(pins
|
|
417
|
+
? { target: { kind: "commits", ...pins } }
|
|
418
|
+
: repositoryId && {
|
|
419
|
+
target: { kind: "project", repositoryId },
|
|
420
|
+
}),
|
|
333
421
|
},
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
},
|
|
341
|
-
|
|
342
|
-
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
const seed = {
|
|
425
|
+
document: JSON.parse(document),
|
|
426
|
+
lenses: snapshot.lenses,
|
|
427
|
+
origin: snapshot.origin,
|
|
428
|
+
shared: { ...provenance, cloneUrl, key },
|
|
429
|
+
copiedFrom: snapshot.reviewId,
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
const { reviewId } = into
|
|
433
|
+
? await store.refreshCopy(into.reviewId, into.version, create, seed)
|
|
434
|
+
: await store.execute(create, seed, { kind: "person" });
|
|
343
435
|
|
|
344
436
|
return reviewId;
|
|
345
437
|
}
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
REVIEW_COLOR_THEME_KINDS,
|
|
22
22
|
REVIEW_DIFF_LAYOUTS,
|
|
23
23
|
REVIEW_DIFF_LAYOUT_SCOPES,
|
|
24
|
+
REVIEW_OPEN_FILES_IN_CHOICES,
|
|
24
25
|
isJsonObject,
|
|
25
26
|
jsonBoolean,
|
|
26
27
|
jsonNumber,
|
|
@@ -93,7 +94,12 @@ export const LSP_FEATURE = [
|
|
|
93
94
|
|
|
94
95
|
export const LSP_VIA = ["command", "mouse"] as const;
|
|
95
96
|
|
|
96
|
-
export const LSP_EDITOR_KIND = [
|
|
97
|
+
export const LSP_EDITOR_KIND = [
|
|
98
|
+
"files_tab",
|
|
99
|
+
"inline_peek",
|
|
100
|
+
"diff",
|
|
101
|
+
"definition_peek",
|
|
102
|
+
] as const;
|
|
97
103
|
|
|
98
104
|
export const LSP_LANGUAGE = [
|
|
99
105
|
"typescript",
|
|
@@ -212,6 +218,16 @@ const MAP_LEVEL = ["system", "container", "component", "code"] as const;
|
|
|
212
218
|
|
|
213
219
|
const SOURCE_TREE_OPENED_VIA = ["topbar", "home"] as const;
|
|
214
220
|
|
|
221
|
+
const SOURCE_OPENED_DESTINATION = [
|
|
222
|
+
"source_window",
|
|
223
|
+
"vscode",
|
|
224
|
+
"cursor",
|
|
225
|
+
"zed",
|
|
226
|
+
"application",
|
|
227
|
+
] as const;
|
|
228
|
+
|
|
229
|
+
const SOURCE_OPENED_KIND = ["file", "diff", "references", "tree"] as const;
|
|
230
|
+
|
|
215
231
|
/** Tab names the dwell beacon reports. Shared with its request parser. */
|
|
216
232
|
export const REVIEW_TELEMETRY_TABS = [
|
|
217
233
|
"review",
|
|
@@ -431,6 +447,13 @@ export const UI_TELEMETRY_EVENTS = {
|
|
|
431
447
|
event: "review_source_tree_opened",
|
|
432
448
|
properties: { via: SOURCE_TREE_OPENED_VIA },
|
|
433
449
|
},
|
|
450
|
+
source_opened: {
|
|
451
|
+
event: "review_source_opened",
|
|
452
|
+
properties: {
|
|
453
|
+
destination: SOURCE_OPENED_DESTINATION,
|
|
454
|
+
kind: SOURCE_OPENED_KIND,
|
|
455
|
+
},
|
|
456
|
+
},
|
|
434
457
|
whiteboard_file_exported: {
|
|
435
458
|
event: "review_whiteboard_file_exported",
|
|
436
459
|
properties: {},
|
|
@@ -571,6 +594,7 @@ export const UI_TELEMETRY_EVENTS = {
|
|
|
571
594
|
setting: SETTING_NAME,
|
|
572
595
|
enabled: "boolean",
|
|
573
596
|
value: REVIEW_COLOR_THEME_KINDS,
|
|
597
|
+
choice: REVIEW_OPEN_FILES_IN_CHOICES,
|
|
574
598
|
},
|
|
575
599
|
},
|
|
576
600
|
review_opened: {
|
package/dist/profile-BjcXi-oH.js
DELETED