@dev.fast/whiteboard 0.5.1 → 0.5.2-preview.20261104.147

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.
Files changed (120) hide show
  1. package/dist/{account-alias-Bw3PT3Qo.js → account-alias-DXpd0Px8.js} +5 -5
  2. package/dist/{agent-cli-kHRrwO4n.js → agent-cli-COrZtFks.js} +9 -9
  3. package/dist/agent-cli-x6-Eh1S-.js +2 -0
  4. package/dist/{agent-client-CMacGbMp.js → agent-client-BFtYm3Ng.js} +4 -4
  5. package/dist/{authoring-tools-CiLy46kh.js → authoring-tools-D1avYp8-.js} +12 -8
  6. package/dist/{background-server-eZWXoVcI.js → background-server-BiRSqjxG.js} +4 -4
  7. package/dist/{background-server-BLNHbksB.js → background-server-HOJozY99.js} +1 -1
  8. package/dist/build-info.json +1 -1
  9. package/dist/{cli-Bxmiqutp.js → cli-CSlwGRvH.js} +1 -1
  10. package/dist/{cli-runner-DQPuu7kJ.js → cli-runner-CuffXA0Q.js} +22 -22
  11. package/dist/cli.js +2 -2
  12. package/dist/{fuzzy-match-DZjeOaPY.js → fuzzy-match-DEo941za.js} +3 -3
  13. package/dist/{headless-host-B4r0s1ks.js → headless-host-BCkXVVpU.js} +1 -1
  14. package/dist/{headless-host-Dl2KZ9IT.js → headless-host-CIuJJjmM.js} +561 -415
  15. package/dist/{import-YAIU6rB0.js → import-CjcW7EIQ.js} +235 -63
  16. package/dist/{local-data-C58vzLZR.js → local-data-B5PBZ0Ge.js} +101 -17
  17. package/dist/{mcp-COYWiGVn.js → mcp-Ba3WvhUh.js} +9 -6
  18. package/dist/{package-paths-Cg6fnaGp.js → package-paths-Dk7MOXxN.js} +1 -1
  19. package/dist/profile-BstQkIY0.js +2 -0
  20. package/dist/{profile--BYIjPkc.js → profile-CNMhLUhf.js} +2 -2
  21. package/dist/{remote-attach-C1prLjmj.js → remote-attach-DkZoYBHV.js} +4 -4
  22. package/dist/{remote-extensions-Bw029iIS.js → remote-extensions-BvV29_gk.js} +1 -1
  23. package/dist/{remote-extensions-MUUgbLJn.js → remote-extensions-L95HNwIH.js} +2 -2
  24. package/dist/{remote-language-server-z3rdHcLL.js → remote-language-server-l4ConTfj.js} +4 -4
  25. package/dist/{remote-uninstall-B3Slwor1.js → remote-uninstall-BAQM7cU8.js} +5 -5
  26. package/dist/{request-origin-B3_XI2VA.js → request-origin-DZexKlc4.js} +28 -5
  27. package/dist/{review-app-launcher-BZEbDKuK.js → review-app-launcher-B5F10y_4.js} +2 -2
  28. package/dist/{review-home-paths-LdGS4SpR.js → review-home-paths-BmZX2qiz.js} +1 -1
  29. package/dist/{review-telemetry-x8u-9EZb.js → review-telemetry-kQ7esDRE.js} +4 -4
  30. package/dist/server/desktop-host.js +26 -38
  31. package/dist/{server-discovery-WmuFl2S3.js → server-discovery-DYY_xeG9.js} +2 -2
  32. package/dist/sharing/index.d.ts +137 -14
  33. package/dist/sharing/index.js +1 -1
  34. package/dist/{src-DLWol7GZ.js → src-B-91Rd2d.js} +17 -1
  35. package/dist/{src-B2b8cCoI.js → src-DirPN_Qh.js} +82 -6
  36. package/dist/{stored-document-migration-iwIQ4l5G.js → stored-document-migration-vg0NAzXG.js} +4 -89
  37. package/dist/{thread-state-B7L1mpN_.js → thread-state-Jxoh1hde.js} +1 -1
  38. package/dist/{tool-failure-RLR8m9hq.js → tool-failure-BLBwcl3H.js} +319 -55
  39. package/instructions/animation.md +69 -5
  40. package/instructions/animations/before-after-structure/README.md +27 -0
  41. package/instructions/animations/before-after-structure/animation.html +89 -0
  42. package/instructions/animations/before-after-structure/block.json +10 -0
  43. package/instructions/animations/before-after-structure/frames.json +313 -0
  44. package/instructions/animations/cache-fill-evict/README.md +24 -0
  45. package/instructions/animations/cache-fill-evict/animation.html +81 -0
  46. package/instructions/animations/cache-fill-evict/block.json +13 -0
  47. package/instructions/animations/cache-fill-evict/frames.json +79 -0
  48. package/instructions/animations/cache-fill-evict/scenarios.json +17 -0
  49. package/instructions/animations/log-replay/README.md +25 -0
  50. package/instructions/animations/log-replay/animation.html +86 -0
  51. package/instructions/animations/log-replay/block.json +10 -0
  52. package/instructions/animations/log-replay/frames.json +143 -0
  53. package/instructions/animations/log-replay/scenarios.json +18 -0
  54. package/instructions/animations/queue-workers/README.md +23 -0
  55. package/instructions/animations/queue-workers/animation.html +107 -0
  56. package/instructions/animations/queue-workers/block.json +13 -0
  57. package/instructions/animations/queue-workers/frames.json +119 -0
  58. package/instructions/animations/queue-workers/scenarios.json +18 -0
  59. package/instructions/animations/race-two-lanes/README.md +22 -0
  60. package/instructions/animations/race-two-lanes/animation.html +97 -0
  61. package/instructions/animations/race-two-lanes/block.json +1 -0
  62. package/instructions/animations/race-two-lanes/frames.json +234 -0
  63. package/instructions/animations/race-two-lanes/scenarios.json +19 -0
  64. package/instructions/animations/request-across-layers/README.md +24 -0
  65. package/instructions/animations/request-across-layers/animation.html +85 -0
  66. package/instructions/animations/request-across-layers/block.json +17 -0
  67. package/instructions/animations/request-across-layers/frames.json +58 -0
  68. package/instructions/animations/request-across-layers/scenarios.json +12 -0
  69. package/instructions/animations/request-timing/README.md +22 -0
  70. package/instructions/animations/request-timing/animation.html +120 -0
  71. package/instructions/animations/request-timing/block.json +21 -0
  72. package/instructions/animations/request-timing/markers.json +32 -0
  73. package/instructions/animations/request-timing/scenarios.json +4 -0
  74. package/instructions/animations/retry-backoff/README.md +22 -0
  75. package/instructions/animations/retry-backoff/animation.html +122 -0
  76. package/instructions/animations/retry-backoff/block.json +10 -0
  77. package/instructions/animations/retry-backoff/frames.json +65 -0
  78. package/instructions/animations/retry-backoff/scenarios.json +12 -0
  79. package/instructions/animations/state-machine/README.md +24 -0
  80. package/instructions/animations/state-machine/animation.html +95 -0
  81. package/instructions/animations/state-machine/block.json +9 -0
  82. package/instructions/animations/state-machine/frames.json +79 -0
  83. package/instructions/animations/state-machine/scenarios.json +12 -0
  84. package/instructions/animations/video-platform-architecture/README.md +24 -0
  85. package/instructions/animations/video-platform-architecture/animation.html +76 -0
  86. package/instructions/animations/video-platform-architecture/block.json +17 -0
  87. package/instructions/animations/video-platform-architecture/frames.json +97 -0
  88. package/instructions/animations/video-platform-architecture/scenarios.json +28 -0
  89. package/instructions/whiteboard.d.ts +168 -14
  90. package/package.json +5 -5
  91. package/src/animation-stage-kit.ts +150 -10
  92. package/src/cli-runner.ts +4 -1
  93. package/src/fixtures/blocks/clip.json +19 -0
  94. package/src/review-api/README.md +1 -0
  95. package/src/review-api/agent-cli.ts +3 -2
  96. package/src/review-api/animation-drafts.ts +151 -47
  97. package/src/review-api/animation-references.ts +92 -0
  98. package/src/review-api/animation-render.ts +106 -0
  99. package/src/review-api/authoring-tools.ts +10 -3
  100. package/src/review-api/comparison-coverage.ts +6 -7
  101. package/src/review-api/document-text.ts +27 -12
  102. package/src/review-api/http.ts +52 -6
  103. package/src/review-api/instructions.ts +1 -1
  104. package/src/review-api/mcp.ts +10 -5
  105. package/src/review-api/public-tools.ts +71 -2
  106. package/src/review-api/review-progress.ts +2 -3
  107. package/src/review-api/store.ts +89 -12
  108. package/src/server/desktop-server.ts +17 -5
  109. package/src/server/headless-host.ts +4 -0
  110. package/src/server/review-gateway.ts +1 -0
  111. package/src/server/review-server-core.ts +71 -12
  112. package/src/sharing/client.ts +129 -32
  113. package/src/sharing/export.ts +42 -5
  114. package/src/sharing/file.ts +8 -0
  115. package/src/sharing/host.ts +202 -73
  116. package/src/sharing/import.ts +125 -33
  117. package/src/ui-telemetry-events.ts +26 -1
  118. package/dist/agent-cli-B8KBHuh_.js +0 -2
  119. package/dist/profile-BjcXi-oH.js +0 -2
  120. package/src/review-api/lens-alignment.ts +0 -52
@@ -15,6 +15,7 @@ type JsonObject$1 = {
15
15
  };
16
16
  //#endregion
17
17
  //#region ../review-share-protocol/src/index.d.ts
18
+ /** Unknown fields drop, so a reader opens bundles from newer sharers. */
18
19
  declare const shareBundleSchema: z.ZodObject<{
19
20
  format: z.ZodLiteral<"review-share/2">;
20
21
  reviewId: z.ZodString;
@@ -23,7 +24,7 @@ declare const shareBundleSchema: z.ZodObject<{
23
24
  snapshot: z.ZodRecord<z.ZodString, z.ZodUnknown>;
24
25
  images: z.ZodRecord<z.ZodString, z.ZodObject<{
25
26
  png: z.ZodBase64;
26
- }, z.core.$strict>>;
27
+ }, z.core.$strip>>;
27
28
  traces: z.ZodRecord<z.ZodString, z.ZodUnknown>;
28
29
  maps: z.ZodRecord<z.ZodString, z.ZodUnknown>;
29
30
  commits: z.ZodArray<z.ZodUnknown>;
@@ -39,20 +40,53 @@ declare const shareBundleSchema: z.ZodObject<{
39
40
  repositoryId: z.ZodString;
40
41
  head: z.ZodString;
41
42
  base: z.ZodOptional<z.ZodString>;
42
- }, z.core.$strict>>;
43
- }, z.core.$strict>>>;
43
+ }, z.core.$strip>>;
44
+ }, z.core.$strip>>>;
44
45
  sources: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
45
46
  kind: z.ZodLiteral<"excerpt">;
46
47
  file: z.ZodString;
47
48
  commit: z.ZodString;
48
49
  fromLine: z.ZodNumber;
49
50
  lines: z.ZodArray<z.ZodString>;
50
- }, z.core.$strict>], "kind">>;
51
+ }, z.core.$strip>], "kind">>;
52
+ alignments: z.ZodOptional<z.ZodArray<z.ZodObject<{
53
+ file: z.ZodString;
54
+ previousFile: z.ZodOptional<z.ZodString>;
55
+ head: z.ZodString;
56
+ base: z.ZodOptional<z.ZodString>;
57
+ rows: z.ZodArray<z.ZodTuple<[z.ZodNullable<z.ZodNumber>, z.ZodNullable<z.ZodNumber>], null>>;
58
+ }, z.core.$strip>>>;
51
59
  repository: z.ZodOptional<z.ZodObject<{
52
60
  cloneUrl: z.ZodString;
53
- }, z.core.$strict>>;
54
- }, z.core.$strict>;
61
+ }, z.core.$strip>>;
62
+ frozen: z.ZodOptional<z.ZodLiteral<true>>;
63
+ }, z.core.$strip>;
55
64
  type ShareBundle = z.infer<typeof shareBundleSchema>;
65
+ declare const shareRevisionsSchema: z.ZodObject<{
66
+ latest: z.ZodUUID;
67
+ items: z.ZodArray<z.ZodObject<{
68
+ id: z.ZodUUID;
69
+ version: z.ZodNumber;
70
+ createdAt: z.ZodNumber;
71
+ size: z.ZodNumber;
72
+ url: z.ZodURL;
73
+ }, z.core.$strip>>;
74
+ }, z.core.$strip>;
75
+ type ShareRevisions = z.infer<typeof shareRevisionsSchema>;
76
+ declare const sharedMetaSchema: z.ZodObject<{
77
+ sender: z.ZodObject<{
78
+ login: z.ZodString;
79
+ }, z.core.$strict>;
80
+ sharedAt: z.ZodNumber;
81
+ size: z.ZodNumber;
82
+ revision: z.ZodObject<{
83
+ id: z.ZodUUID;
84
+ version: z.ZodNumber;
85
+ createdAt: z.ZodNumber;
86
+ }, z.core.$strip>;
87
+ latest: z.ZodUUID;
88
+ }, z.core.$strip>;
89
+ type SharedMeta = z.infer<typeof sharedMetaSchema>;
56
90
  //#endregion
57
91
  //#region src/sharing/client.d.ts
58
92
  /** Account tokens go only to the configured API origin. */
@@ -76,8 +110,11 @@ declare class ShareClient {
76
110
  url: string;
77
111
  }>;
78
112
  revoke(shareId: string): Promise<JsonValue$1>;
79
- /** The bundle and who shared it, read with the link's capability. */
80
- download(capability: string): Promise<{
113
+ revisions(shareId: string): Promise<ShareRevisions>;
114
+ /** Who shared a link's revision, and which revision is its latest. */
115
+ shared(capability: string, revision?: string): Promise<SharedMeta>;
116
+ /** The bundle of the revision the meta names, and who shared it. */
117
+ download(capability: string, revision?: string): Promise<{
81
118
  bundle: {
82
119
  format: "review-share/2";
83
120
  reviewId: string;
@@ -108,14 +145,28 @@ declare class ShareClient {
108
145
  fromLine: number;
109
146
  lines: string[];
110
147
  }[];
148
+ alignments?: {
149
+ file: string;
150
+ head: string;
151
+ rows: [number | null, number | null][];
152
+ previousFile?: string | undefined;
153
+ base?: string | undefined;
154
+ }[] | undefined;
111
155
  repository?: {
112
156
  cloneUrl: string;
113
157
  } | undefined;
158
+ frozen?: true | undefined;
114
159
  };
115
160
  attribution: {
116
161
  login: string;
117
162
  sharedAt: number;
118
163
  };
164
+ revision: {
165
+ id: string;
166
+ version: number;
167
+ createdAt: number;
168
+ };
169
+ latest: string;
119
170
  }>;
120
171
  }
121
172
  //#endregion
@@ -1058,6 +1109,31 @@ declare const leafSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1058
1109
  head: z.ZodString;
1059
1110
  base: z.ZodOptional<z.ZodString>;
1060
1111
  }, z.core.$strict>>;
1112
+ }, z.core.$strict>, z.ZodObject<{
1113
+ type: z.ZodLiteral<"clip">;
1114
+ id: z.ZodOptional<z.ZodString>;
1115
+ title: z.ZodString;
1116
+ html: z.ZodString;
1117
+ markers: z.ZodArray<z.ZodObject<{
1118
+ key: z.ZodString;
1119
+ title: z.ZodString;
1120
+ caption: z.ZodOptional<z.ZodString>;
1121
+ code: z.ZodOptional<z.ZodArray<z.ZodString>>;
1122
+ }, z.core.$strict>>;
1123
+ scenarios: z.ZodOptional<z.ZodArray<z.ZodObject<{
1124
+ key: z.ZodString;
1125
+ label: z.ZodString;
1126
+ }, z.core.$strict>>>;
1127
+ code: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
1128
+ source: z.ZodString;
1129
+ label: z.ZodString;
1130
+ }, z.core.$strict>]>>>;
1131
+ height: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodNumber]>>;
1132
+ pins: z.ZodOptional<z.ZodObject<{
1133
+ repositoryId: z.ZodString;
1134
+ head: z.ZodString;
1135
+ base: z.ZodOptional<z.ZodString>;
1136
+ }, z.core.$strict>>;
1061
1137
  }, z.core.$strict>], "type">;
1062
1138
  type LeafBlock = z.infer<typeof leafSchema>;
1063
1139
  type Block = LeafBlock | SectionBlock | CalloutBlock;
@@ -1382,6 +1458,31 @@ declare const editSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1382
1458
  head: z.ZodString;
1383
1459
  base: z.ZodOptional<z.ZodString>;
1384
1460
  }, z.core.$strict>>;
1461
+ }, z.core.$strict>, z.ZodObject<{
1462
+ type: z.ZodLiteral<"clip">;
1463
+ id: z.ZodOptional<z.ZodString>;
1464
+ title: z.ZodString;
1465
+ html: z.ZodString;
1466
+ markers: z.ZodArray<z.ZodObject<{
1467
+ key: z.ZodString;
1468
+ title: z.ZodString;
1469
+ caption: z.ZodOptional<z.ZodString>;
1470
+ code: z.ZodOptional<z.ZodArray<z.ZodString>>;
1471
+ }, z.core.$strict>>;
1472
+ scenarios: z.ZodOptional<z.ZodArray<z.ZodObject<{
1473
+ key: z.ZodString;
1474
+ label: z.ZodString;
1475
+ }, z.core.$strict>>>;
1476
+ code: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
1477
+ source: z.ZodString;
1478
+ label: z.ZodString;
1479
+ }, z.core.$strict>]>>>;
1480
+ height: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodNumber]>>;
1481
+ pins: z.ZodOptional<z.ZodObject<{
1482
+ repositoryId: z.ZodString;
1483
+ head: z.ZodString;
1484
+ base: z.ZodOptional<z.ZodString>;
1485
+ }, z.core.$strict>>;
1385
1486
  }, z.core.$strict>], "type">, z.ZodObject<{
1386
1487
  type: z.ZodLiteral<"section">;
1387
1488
  id: z.ZodOptional<z.ZodString>;
@@ -2109,6 +2210,11 @@ interface SharedProvenance {
2109
2210
  sharedAt?: number;
2110
2211
  cloneUrl?: string;
2111
2212
  key?: string;
2213
+ revisionId?: string;
2214
+ /** The version import wrote; anything later is the receiver's edit. */
2215
+ importedVersion?: number;
2216
+ /** Opened from a link naming a revision: never refreshed. */
2217
+ pinned?: boolean;
2112
2218
  }
2113
2219
  /** Content a new board starts with, as another board left it. */
2114
2220
  interface Seed {
@@ -2308,8 +2414,12 @@ declare class ReviewStore {
2308
2414
  /** Forgets a checkout no board uses, after every write queued before it,
2309
2415
  * so a board being made with it keeps it. */
2310
2416
  unregisterRepository(id: string): Promise<void>;
2311
- /** The board copied from a share link, until it is deleted. */
2312
- copyOf(key: string): string | undefined;
2417
+ /** The boards copied from a share link, newest first, until each is deleted. */
2418
+ copiesOf(key: string): {
2419
+ reviewId: string;
2420
+ version: number;
2421
+ shared: SharedProvenance;
2422
+ }[];
2313
2423
  /** Checkouts whose remote is cloneUrl, most recently used first. */
2314
2424
  checkoutsOf(cloneUrl: string): string[];
2315
2425
  /** Registered checkouts, oldest registration first. */
@@ -2361,11 +2471,14 @@ declare class ReviewStore {
2361
2471
  history(id: string): HistoryEntry[];
2362
2472
  inspect(id: string, targetId?: string, version?: number): Element | {
2363
2473
  id: string | undefined;
2364
- type: "markdown" | "code" | "divider" | "code_peek" | "sequence" | "call_stack_diff" | "database_lens" | "image" | "trace_quote" | "software_map" | "flow_diagram" | "animation" | "step" | "flow_node" | "flow_edge" | "section" | "callout";
2474
+ type: "markdown" | "code" | "divider" | "code_peek" | "sequence" | "call_stack_diff" | "database_lens" | "image" | "trace_quote" | "software_map" | "flow_diagram" | "animation" | "clip" | "step" | "flow_node" | "flow_edge" | "section" | "callout";
2365
2475
  label: string | undefined;
2366
2476
  }[];
2367
2477
  /** The host can seed a document; transport callers only supply a command. */
2368
2478
  execute(input: unknown, initial?: Seed, author?: Author): Promise<Result>;
2479
+ /** Replaces a share copy's content under the same board id; 409 once it moved past `baseVersion`. */
2480
+ refreshCopy(reviewId: string, baseVersion: number, create: unknown, seed: Seed): Promise<Result>;
2481
+ private track;
2369
2482
  /** Resolve optional network context before entering the write queue. */
2370
2483
  private prepareCommand;
2371
2484
  private applyPreparedCommand;
@@ -2974,9 +3087,17 @@ declare function validateShareBundle(input: ShareBundle): {
2974
3087
  fromLine: number;
2975
3088
  lines: string[];
2976
3089
  }[];
3090
+ alignments?: {
3091
+ file: string;
3092
+ head: string;
3093
+ rows: [number | null, number | null][];
3094
+ previousFile?: string | undefined;
3095
+ base?: string | undefined;
3096
+ }[] | undefined;
2977
3097
  repository?: {
2978
3098
  cloneUrl: string;
2979
3099
  } | undefined;
3100
+ frozen?: true | undefined;
2980
3101
  };
2981
3102
  snapshot: {
2982
3103
  reviewId: string;
@@ -3111,8 +3232,10 @@ interface ShareImport {
3111
3232
  cloneRepository?: typeof cloneSharedRepository;
3112
3233
  onStage?: (stage: "fetching" | "validating") => void;
3113
3234
  }
3114
- /** Imports a share as an ordinary board, once per link: the link's copy
3115
- * comes back while it exists, even from Trash. */
3116
- declare function importShare(input: ShareImport, key: string, received: ShareBundle, attribution?: ShareAttribution): Promise<string>;
3235
+ /** Imports a share as an ordinary board, or into a copy of its link. */
3236
+ declare function importShare(input: ShareImport, key: string, received: ShareBundle, provenance?: ShareAttribution & Pick<SharedProvenance, "revisionId" | "pinned">, into?: {
3237
+ reviewId: string;
3238
+ version: number;
3239
+ }): Promise<string>;
3117
3240
  //#endregion
3118
3241
  export { ShareClient, exportShare, importShare, shareKey, validateShareBundle };
@@ -1,2 +1,2 @@
1
- import { c as ShareClient, i as validateShareBundle, l as exportShare, r as shareKey, t as importShare } from "../import-YAIU6rB0.js";
1
+ import { a as shareKey, g as exportShare, o as validateShareBundle, t as importShare, u as ShareClient } from "../import-CjcW7EIQ.js";
2
2
  export { ShareClient, exportShare, importShare, shareKey, validateShareBundle };
@@ -285,6 +285,14 @@ const loopbackOriginSchema = urlSchema("origin", (url) => url.protocol === "http
285
285
  const REVIEW_DIFF_LAYOUTS = ["split", "unified"];
286
286
  const REVIEW_DIFF_LAYOUT_SCOPES = ["diff", "peek"];
287
287
  const REVIEW_COLOR_THEME_KINDS = ["dark", "light"];
288
+ const REVIEW_OPEN_FILES_IN_CHOICES = [
289
+ "whiteboard",
290
+ "vscode",
291
+ "cursor",
292
+ "zed",
293
+ "intellij",
294
+ "application"
295
+ ];
288
296
  const reviewDiffrLoginsSchema = z.record(z.string(), z.object({
289
297
  ready: z.boolean(),
290
298
  message: z.string().optional()
@@ -834,6 +842,14 @@ const ReviewVerbRequestSchema = z.discriminatedUnion("name", [
834
842
  reviewId: apiReviewIdSchema,
835
843
  version: z.number().int().nonnegative().optional()
836
844
  })
845
+ }),
846
+ z.strictObject({
847
+ name: z.literal("renderAnimation"),
848
+ args: z.strictObject({
849
+ reviewId: apiReviewIdSchema,
850
+ targetId: requiredString$1,
851
+ frame: requiredString$1
852
+ })
837
853
  })
838
854
  ]);
839
855
  const ReviewVerbResponseSchema = z.discriminatedUnion("ok", [z.strictObject({
@@ -1189,4 +1205,4 @@ function formatIssuePath(path) {
1189
1205
  return output;
1190
1206
  }
1191
1207
  //#endregion
1192
- export { ReviewGatewayHostSchema as A, REVIEW_REMOTE_INSTALL_LOCK as C, ReviewConnectRequestSchema as D, ReviewCliInstallStampSchema as E, applyStructuralUpdate as F, decodeStructuralDiffEvent as I, structuralChangeCounts as L, ReviewSelectedDiffSchema as M, reviewDiffrLoginsSchema as N, ReviewFeedbackContactSchema as O, reviewDiffrSummarizerInputSchema as P, REVIEW_REMOTE_ATTACH_END as S, ReviewApiSelectionSourceSchema as T, REVIEW_DIFF_LAYOUTS as _, parseReviewVerbRequest as a, REVIEW_REMOTE_AGENT_IDS as b, boardIconKind as c, ReviewBugReportRequestSchema as d, parseReviewBugReportResponse as f, REVIEW_COLOR_THEME_KINDS as g, REVIEW_CLI_INSTALL_TARGET_LABELS as h, parseReviewDesktopVerbResult as i, ReviewOnboardingRunRequestSchema as j, ReviewFeedbackSchema as k, boardTitle as l, REVIEW_CLIENT_REMOTE as m, parseReviewDesktopDiscovery as n, parseReviewVerbResponse as o, REVIEW_CLIENT_HEADER as p, parseReviewDesktopVerbFrame as r, parseZod as s, parseReviewCliInstallApplyRequest as t, ReviewBugReportMetaV2Schema as u, REVIEW_DIFF_LAYOUT_SCOPES as v, REVIEW_REMOTE_WRAPPER_MARK as w, REVIEW_REMOTE_ATTACH_BEGIN as x, REVIEW_HOST_HEADER as y };
1208
+ export { ReviewFeedbackSchema as A, REVIEW_REMOTE_ATTACH_END as C, ReviewCliInstallStampSchema as D, ReviewApiSelectionSourceSchema as E, reviewDiffrSummarizerInputSchema as F, applyStructuralUpdate as I, decodeStructuralDiffEvent as L, ReviewOnboardingRunRequestSchema as M, ReviewSelectedDiffSchema as N, ReviewConnectRequestSchema as O, reviewDiffrLoginsSchema as P, structuralChangeCounts as R, REVIEW_REMOTE_ATTACH_BEGIN as S, REVIEW_REMOTE_WRAPPER_MARK as T, REVIEW_DIFF_LAYOUTS as _, parseReviewVerbRequest as a, REVIEW_OPEN_FILES_IN_CHOICES as b, boardIconKind as c, ReviewBugReportRequestSchema as d, parseReviewBugReportResponse as f, REVIEW_COLOR_THEME_KINDS as g, REVIEW_CLI_INSTALL_TARGET_LABELS as h, parseReviewDesktopVerbResult as i, ReviewGatewayHostSchema as j, ReviewFeedbackContactSchema as k, boardTitle as l, REVIEW_CLIENT_REMOTE as m, parseReviewDesktopDiscovery as n, parseReviewVerbResponse as o, REVIEW_CLIENT_HEADER as p, parseReviewDesktopVerbFrame as r, parseZod as s, parseReviewCliInstallApplyRequest as t, ReviewBugReportMetaV2Schema as u, REVIEW_DIFF_LAYOUT_SCOPES as v, REVIEW_REMOTE_INSTALL_LOCK as w, REVIEW_REMOTE_AGENT_IDS as x, REVIEW_HOST_HEADER as y };
@@ -116,6 +116,43 @@ function formatAnchor(selection) {
116
116
  const letter = (side) => side === "base" ? "L" : "R";
117
117
  return `diff/${file}#${letter(start.side)}${start.line}-${letter(end.side)}${end.line}`;
118
118
  }
119
+ const HUNK = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
120
+ /** The 0-based line pairs a unified patch aligns, unchanged gaps included,
121
+ * for files of `baseCount` and `headCount` lines. An empty patch pairs each
122
+ * line with itself. */
123
+ function patchRows(patch, baseCount, headCount) {
124
+ const rows = [];
125
+ let base = 0;
126
+ let head = 0;
127
+ let removed = 0;
128
+ let added = 0;
129
+ let inHunk = false;
130
+ const append = (baseEnd, headEnd) => {
131
+ while (base < baseEnd || head < headEnd) rows.push([base < baseEnd ? base++ : null, head < headEnd ? head++ : null]);
132
+ };
133
+ const flush = () => {
134
+ append(base + removed, head + added);
135
+ removed = added = 0;
136
+ };
137
+ for (const line of patch.split(/\r?\n/)) {
138
+ const hunk = HUNK.exec(line);
139
+ if (hunk) {
140
+ inHunk = true;
141
+ flush();
142
+ const [, oldStart, oldLines = "1", newStart, newLines = "1"] = hunk;
143
+ append(Number(oldLines) ? Number(oldStart) - 1 : Number(oldStart), Number(newLines) ? Number(newStart) - 1 : Number(newStart));
144
+ } else if (!inHunk) continue;
145
+ else if (line.startsWith("+")) added++;
146
+ else if (line.startsWith("-")) removed++;
147
+ else if (line.startsWith(" ")) {
148
+ flush();
149
+ append(base + 1, head + 1);
150
+ }
151
+ }
152
+ flush();
153
+ append(baseCount, headCount);
154
+ return rows;
155
+ }
119
156
  /** Pins-less selections keep the key they always had. */
120
157
  function selectionKey(source) {
121
158
  return JSON.stringify([
@@ -298,6 +335,8 @@ const animationScenarioSchema = z.strictObject({
298
335
  label: z.string().min(1).max(32).describe("What the reader picks above the animation, e.g. Retried request. Keep it short."),
299
336
  frames: z.array(handle).min(1).max(60).describe("The frame keys this scenario plays, in order.")
300
337
  });
338
+ /** One named source range of an animation or clip: an anchor, or one with
339
+ * the label it opens under. */
301
340
  const animationCodeSchema = z.union([anchorSchema, z.strictObject({
302
341
  source: anchorSchema,
303
342
  label: z.string().min(1).max(48).describe("What the range is, e.g. checkoutAnimation.")
@@ -505,6 +544,40 @@ const callout = {
505
544
  schema: calloutSchema
506
545
  };
507
546
  //#endregion
547
+ //#region ../whiteboard-document/src/blocks/clip.ts
548
+ const clipMarkerSchema = z.strictObject({
549
+ key: handle.describe("Names the marker for the html: clip.marker(key) places it in time, and whiteboard.on(key, ...) runs as the playhead reaches it."),
550
+ title: label$1.describe("What the step strip under the clip shows for this marker, e.g. Lock taken. Keep it to a few words."),
551
+ caption: text$1.optional().describe("One or two short sentences shown under the clip."),
552
+ code: z.array(handle).min(1).max(8).optional().describe("The code this moment shows, by name in the block's code. The tour stops here with it.")
553
+ });
554
+ const clipScenarioSchema = z.strictObject({
555
+ key: handle.describe("Names the scenario: whiteboard.clip(key) builds its timeline."),
556
+ label: z.string().min(1).max(32).describe("What the reader picks above the clip, e.g. Slow replica. Keep it short.")
557
+ });
558
+ const clip = {
559
+ type: "clip",
560
+ reference: ["- clip {title, html, markers: {key, title (a few words), caption?, code? ([names in code] this moment shows)}[] (1 to 60), scenarios?: {key, label}[] (2 to 8, each a timeline the script builds), code?: {name: anchor | {source: anchor, label}}, height?: \"auto\" (default) | number (120 to 1200 CSS px), pins?}; the script places every marker in time", "Use a clip for continuous motion where the timing itself is the point: a token crossing a system, a race, a queue draining. The reader plays it, pauses it and jumps between its markers. Use an animation instead when the reader needs to compare discrete states. Read session_get_instructions({topic:\"animation\"}) before writing one."],
561
+ schema: defineBlock("clip", {
562
+ title: label$1,
563
+ html: text$1.min(1).max(2e5).describe("The clip's body markup: elements, <style> and <script>. Its script builds the timeline with whiteboard.clip() in a sandboxed iframe; see session_get_instructions({topic:\"animation\"})."),
564
+ markers: z.array(clipMarkerSchema).min(1).max(60).describe("The named moments the reader jumps between, with unique, stable keys. The script places each one in time."),
565
+ scenarios: z.array(clipScenarioSchema).min(2).max(8).optional().describe("Alternate timelines the script builds, one per key. The whiteboard draws a labelled scenario picker above the clip and starts on the first one."),
566
+ code: z.record(handle, animationCodeSchema).default({}).describe("Source ranges by name, each an anchor or {source, label}: the label names the range where it opens. Elements with data-wb-open open them; data-wb-code shows one inline."),
567
+ height: z.union([z.literal("auto"), z.number().int().min(120).max(1200)]).default("auto").describe("Fit the clip to its content by default, or set a fixed height in CSS pixels."),
568
+ pins: elementPins
569
+ }),
570
+ check(block) {
571
+ if (new Set(block.markers.map((marker) => marker.key)).size !== block.markers.length) throw new ReviewInputError("Clip marker keys must be unique within the clip.");
572
+ for (const marker of block.markers) {
573
+ const unknown = marker.code?.find((name) => !(name in block.code));
574
+ if (unknown) throw new ReviewInputError(`Marker "${marker.key}" lists code "${unknown}", which the clip's code does not name.`);
575
+ }
576
+ const scenarios = block.scenarios ?? [];
577
+ if (new Set(scenarios.map((scenario) => scenario.key)).size !== scenarios.length) throw new ReviewInputError("Clip scenario keys must be unique within the clip.");
578
+ }
579
+ };
580
+ //#endregion
508
581
  //#region ../whiteboard-document/src/blocks/code.ts
509
582
  /** Shared with sequence steps. */
510
583
  const codeFields = {
@@ -769,7 +842,8 @@ const leafSchema = z.discriminatedUnion("type", [
769
842
  trace_quote.schema,
770
843
  software_map.schema,
771
844
  flow_diagram.schema,
772
- animation.schema
845
+ animation.schema,
846
+ clip.schema
773
847
  ]);
774
848
  /** Every block kind, keyed by type. A kind without a definition is a compile error. */
775
849
  const blocks = {
@@ -785,6 +859,7 @@ const blocks = {
785
859
  software_map,
786
860
  flow_diagram,
787
861
  animation,
862
+ clip,
788
863
  section,
789
864
  callout
790
865
  };
@@ -804,7 +879,8 @@ const referenceOrder = [
804
879
  "flow_diagram",
805
880
  "call_stack_diff",
806
881
  "database_lens",
807
- "animation"
882
+ "animation",
883
+ "clip"
808
884
  ];
809
885
  /** The selected blocks' fields, for agent guidance. */
810
886
  function componentReference(types = writableBlockTypes) {
@@ -1736,8 +1812,8 @@ const unitTypes = /* @__PURE__ */ new Set([
1736
1812
  "flow_edge"
1737
1813
  ]);
1738
1814
  const isUnit = (element) => unitTypes.has(element.type);
1739
- /** The reference id of a code peek an animation names: the canvas finds the
1740
- * peek's resolved anchor by it. */
1815
+ /** The reference id of a code peek an animation or clip names: the canvas
1816
+ * finds the peek's resolved anchor by it. */
1741
1817
  const animationCodeId = (blockId, name) => `${blockId}:code:${name}`;
1742
1818
  /** Rewrites old review-source: and review-trace: links to their whiteboard: form. */
1743
1819
  function canonicalLink(href) {
@@ -1921,7 +1997,7 @@ function documentReferences(document, { tolerant = false, markdown = true, repos
1921
1997
  label: attachment.label,
1922
1998
  peek: true
1923
1999
  })))));
1924
- if (element.type === "animation") return Object.entries(element.code).flatMap(([name, entry]) => {
2000
+ if (element.type === "animation" || element.type === "clip") return Object.entries(element.code).flatMap(([name, entry]) => {
1925
2001
  const code = animationCode(entry);
1926
2002
  return select(code.source, element.pins).map((source) => ({
1927
2003
  id: animationCodeId(element.id, name),
@@ -2329,4 +2405,4 @@ function written(element) {
2329
2405
  return applied;
2330
2406
  }
2331
2407
  //#endregion
2332
- export { comparisonKey as $, parseMarkdown as A, lensSchema as B, respellLinks as C, summarizeEdit as D, sourceReferences as E, writableBlockTypes as F, SourceRangeError as G, lensTargetsSchema as H, stepSources as I, requireVisibleSource as J, checkSourcePath as K, UNCATEGORIZED_LENS_ID as L, checkReferences as M, componentReference as N, markdownNodes as O, documentAdvice as P, anchorSelection as Q, applyLensEdit as R, respellEditLinks as S, selectionReferences as T, animationCode as U, lensSelections as V, label$1 as W, SELECTION_UNAVAILABLE_REASONS as X, sliceSourceRange as Y, SelectionUnavailableError as Z, readsAtBoardPins as _, boardLinks as a, unionIntervals as at, respellCommitLinks as b, documentSchema as c, activityEndSchema as ct, explicitPins as d, formatAnchor as et, pathTargetSchema as f, publishedEdits as g, pinsSchema as h, assignMissingIds as i, sourceAnchors as it, blocks as j, markdownText as k, editSchema as l, activityUpdateSchema as lt, pinnedRepositoryIds as m, anchorPins as n, resolveDiffSelection as nt, boardRepositoryId as o, ReviewInputError as ot, pinDocumentReferences as p, fileLineRangeSchema as q, applyEdit as r, selectionKey as rt, commitLinkCommits as s, activityBeginSchema as st, adoptFlowUnits as t, parseAnchor as tt, elements as u, focusSchema as ut, resourceReference as v, reviewTargetSchema as w, respellDocumentLinks as x, resourceReferences as y, lensEditSchema as z };
2408
+ export { comparisonKey as $, parseMarkdown as A, lensSchema as B, respellLinks as C, summarizeEdit as D, sourceReferences as E, writableBlockTypes as F, SourceRangeError as G, lensTargetsSchema as H, stepSources as I, requireVisibleSource as J, checkSourcePath as K, UNCATEGORIZED_LENS_ID as L, checkReferences as M, componentReference as N, markdownNodes as O, documentAdvice as P, anchorSelection as Q, applyLensEdit as R, respellEditLinks as S, selectionReferences as T, animationCode as U, lensSelections as V, label$1 as W, SELECTION_UNAVAILABLE_REASONS as X, sliceSourceRange as Y, SelectionUnavailableError as Z, readsAtBoardPins as _, boardLinks as a, sourceAnchors as at, respellCommitLinks as b, documentSchema as c, activityBeginSchema as ct, explicitPins as d, focusSchema as dt, formatAnchor as et, pathTargetSchema as f, publishedEdits as g, pinsSchema as h, assignMissingIds as i, selectionKey as it, blocks as j, markdownText as k, editSchema as l, activityEndSchema as lt, pinnedRepositoryIds as m, anchorPins as n, patchRows as nt, boardRepositoryId as o, unionIntervals as ot, pinDocumentReferences as p, fileLineRangeSchema as q, applyEdit as r, resolveDiffSelection as rt, commitLinkCommits as s, ReviewInputError as st, adoptFlowUnits as t, parseAnchor as tt, elements as u, activityUpdateSchema as ut, resourceReference as v, reviewTargetSchema as w, respellDocumentLinks as x, resourceReferences as y, lensEditSchema as z };
@@ -1,8 +1,8 @@
1
1
  import { C as renderVcsArgs, v as parseGitRemote, w as runVcs } from "./src-Y30gweiK.js";
2
2
  import { d as isBooleanValue, f as isNumberValue, l as jsonValueSchema, m as isStringValue, n as isJsonObject } from "./src-X9phtB2j.js";
3
- import { C as respellLinks, H as lensTargetsSchema, W as label, at as unionIntervals, et as formatAnchor, ot as ReviewInputError } from "./src-B2b8cCoI.js";
4
- import "./src-DLWol7GZ.js";
5
- import "./review-home-paths-LdGS4SpR.js";
3
+ import { C as respellLinks, H as lensTargetsSchema, W as label, et as formatAnchor, ot as unionIntervals, st as ReviewInputError } from "./src-DirPN_Qh.js";
4
+ import "./src-B-91Rd2d.js";
5
+ import "./review-home-paths-BmZX2qiz.js";
6
6
  import { t as errorMessage } from "./error-message-OtiDonty.js";
7
7
  import { randomUUID } from "node:crypto";
8
8
  import { z } from "zod";
@@ -77,91 +77,6 @@ function coverageSources(file, coverage = file.viewed) {
77
77
  })));
78
78
  }
79
79
  //#endregion
80
- //#region src/unified-diff.ts
81
- const HUNK_HEADER = /^@@ -(?<oldStart>\d+)(?:,(?<oldLines>\d+))? \+(?<newStart>\d+)(?:,(?<newLines>\d+))? @@/;
82
- function parseUnifiedPatch(file, patch) {
83
- if (!patch) return [];
84
- const hunks = [];
85
- let current = null;
86
- let oldLine = 0;
87
- let newLine = 0;
88
- for (const row of patch.split(/\r?\n/)) {
89
- const header = HUNK_HEADER.exec(row);
90
- if (header?.groups) {
91
- current = {
92
- file,
93
- oldStart: Number(header.groups.oldStart),
94
- oldLines: Number(header.groups.oldLines ?? "1"),
95
- newStart: Number(header.groups.newStart),
96
- newLines: Number(header.groups.newLines ?? "1"),
97
- lines: []
98
- };
99
- oldLine = current.oldStart;
100
- newLine = current.newStart;
101
- hunks.push(current);
102
- continue;
103
- }
104
- if (!current || row.startsWith("\")) continue;
105
- const marker = row[0];
106
- const text = row.slice(1);
107
- let line = null;
108
- if (marker === " ") {
109
- line = {
110
- kind: "context",
111
- oldLine,
112
- newLine,
113
- text
114
- };
115
- oldLine += 1;
116
- newLine += 1;
117
- } else if (marker === "+") {
118
- line = {
119
- kind: "add",
120
- oldLine: null,
121
- newLine,
122
- text
123
- };
124
- newLine += 1;
125
- } else if (marker === "-") {
126
- line = {
127
- kind: "remove",
128
- oldLine,
129
- newLine: null,
130
- text
131
- };
132
- oldLine += 1;
133
- }
134
- if (line) current.lines.push(line);
135
- }
136
- return hunks;
137
- }
138
- //#endregion
139
- //#region src/review-api/lens-alignment.ts
140
- /** Project the already-computed patch's runs, including unchanged gaps. */
141
- function textualRows(path, patch, baseCount, headCount) {
142
- const rows = [];
143
- let base = 0, head = 0;
144
- const append = (baseEnd, headEnd) => {
145
- while (base < baseEnd || head < headEnd) rows.push([base < baseEnd ? base++ : null, head < headEnd ? head++ : null]);
146
- };
147
- for (const hunk of parseUnifiedPatch(path, patch)) {
148
- append(hunk.oldLines ? hunk.oldStart - 1 : hunk.oldStart, hunk.newLines ? hunk.newStart - 1 : hunk.newStart);
149
- let removed = 0, added = 0;
150
- const flush = () => {
151
- append(base + removed, head + added);
152
- removed = added = 0;
153
- };
154
- for (const line of hunk.lines) if (line.kind === "context") {
155
- flush();
156
- append(base + 1, head + 1);
157
- } else if (line.kind === "add") added++;
158
- else removed++;
159
- flush();
160
- }
161
- append(baseCount, headCount);
162
- return rows;
163
- }
164
- //#endregion
165
80
  //#region src/evidence.ts
166
81
  /** Quote matching shared by legacy publish and JSON accept: authors paste
167
82
  * transcript text with arbitrary line wrapping, so both sides compare on
@@ -1339,4 +1254,4 @@ function liftFileLenses(document) {
1339
1254
  };
1340
1255
  }
1341
1256
  //#endregion
1342
- export { updateCoverage as A, coverageSchema as C, scopedCoverage as D, intersectIntervals as E, sourcesForFile as O, parseUnifiedPatch as S, emptyCoverage as T, fetchPullRequest as _, SoftwareModelValidationError as a, textIncludesQuote as b, traceSchema as c, setPullRequest as d, sourceBranchName as f, defaultPullRequestDeps as g, GitHubRefusedRead as h, readStoredDocument as i, subtractIntervals as k, pullRequestKey as l, resolvePullRequest as m, migrateStoredDocument as n, defineSoftwareMap as o, pullRequestProvider as p, migrateStoredLenses as r, softwareModelDataSchema as s, liftFileLenses as t, pullRequestUrl as u, remoteUrls as v, coverageSources as w, textualRows as x, azureRepositoryOf as y };
1257
+ export { emptyCoverage as C, subtractIntervals as D, sourcesForFile as E, updateCoverage as O, coverageSources as S, scopedCoverage as T, fetchPullRequest as _, SoftwareModelValidationError as a, textIncludesQuote as b, traceSchema as c, setPullRequest as d, sourceBranchName as f, defaultPullRequestDeps as g, GitHubRefusedRead as h, readStoredDocument as i, pullRequestKey as l, resolvePullRequest as m, migrateStoredDocument as n, defineSoftwareMap as o, pullRequestProvider as p, migrateStoredLenses as r, softwareModelDataSchema as s, liftFileLenses as t, pullRequestUrl as u, remoteUrls as v, intersectIntervals as w, coverageSchema as x, azureRepositoryOf as y };
@@ -1,4 +1,4 @@
1
- import { M as ReviewSelectedDiffSchema, T as ReviewApiSelectionSourceSchema } from "./src-DLWol7GZ.js";
1
+ import { E as ReviewApiSelectionSourceSchema, N as ReviewSelectedDiffSchema } from "./src-B-91Rd2d.js";
2
2
  import { z } from "zod";
3
3
  import { stat } from "node:fs/promises";
4
4
  //#region src/fs-utils.ts