@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.
Files changed (117) hide show
  1. package/dist/{account-alias-Bw3PT3Qo.js → account-alias-BlYamXAG.js} +5 -5
  2. package/dist/{agent-cli-kHRrwO4n.js → agent-cli-D7fF5xmm.js} +9 -9
  3. package/dist/agent-cli-DLibAL4u.js +2 -0
  4. package/dist/{agent-client-CMacGbMp.js → agent-client-BCEbSPWU.js} +4 -4
  5. package/dist/{authoring-tools-CiLy46kh.js → authoring-tools-CkfxTVJm.js} +12 -8
  6. package/dist/{background-server-eZWXoVcI.js → background-server-BraP8pJ9.js} +4 -4
  7. package/dist/{background-server-BLNHbksB.js → background-server-CwToVN1g.js} +1 -1
  8. package/dist/build-info.json +1 -1
  9. package/dist/{cli-Bxmiqutp.js → cli-BpadBaGU.js} +1 -1
  10. package/dist/{cli-runner-DQPuu7kJ.js → cli-runner-BebYF50a.js} +22 -22
  11. package/dist/cli.js +2 -2
  12. package/dist/{fuzzy-match-DZjeOaPY.js → fuzzy-match-CxcsLQGx.js} +3 -3
  13. package/dist/{headless-host-Dl2KZ9IT.js → headless-host-FAlbekFD.js} +561 -415
  14. package/dist/{headless-host-B4r0s1ks.js → headless-host-cLipIufH.js} +1 -1
  15. package/dist/{import-YAIU6rB0.js → import-CZ1958L4.js} +234 -62
  16. package/dist/{local-data-C58vzLZR.js → local-data-DdFkxFK_.js} +41 -16
  17. package/dist/{mcp-COYWiGVn.js → mcp-Claiy9xE.js} +9 -6
  18. package/dist/{package-paths-Cg6fnaGp.js → package-paths-Dk7MOXxN.js} +1 -1
  19. package/dist/{profile--BYIjPkc.js → profile-Bsgzi9PA.js} +2 -2
  20. package/dist/profile-BxdzBxHW.js +2 -0
  21. package/dist/{remote-attach-C1prLjmj.js → remote-attach-LGTpwpUv.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-BAznkpeu.js} +4 -4
  25. package/dist/{remote-uninstall-B3Slwor1.js → remote-uninstall-CLP79Cuk.js} +5 -5
  26. package/dist/{request-origin-B3_XI2VA.js → request-origin-D6B-zrL8.js} +27 -5
  27. package/dist/{review-app-launcher-BZEbDKuK.js → review-app-launcher-tTe8bTwg.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-DACDMfqq.js} +4 -4
  30. package/dist/server/desktop-host.js +26 -38
  31. package/dist/{server-discovery-WmuFl2S3.js → server-discovery-CV5qf1J8.js} +2 -2
  32. package/dist/sharing/index.d.ts +137 -14
  33. package/dist/sharing/index.js +1 -1
  34. package/dist/{src-B2b8cCoI.js → src-BQDlJXkG.js} +44 -5
  35. package/dist/{src-DLWol7GZ.js → src-CrrW7lcY.js} +16 -1
  36. package/dist/{stored-document-migration-iwIQ4l5G.js → stored-document-migration-D1wK4yID.js} +3 -3
  37. package/dist/{thread-state-B7L1mpN_.js → thread-state-WTqSborE.js} +1 -1
  38. package/dist/{tool-failure-RLR8m9hq.js → tool-failure-YOFGHJCZ.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 +6 -6
  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/document-text.ts +27 -12
  101. package/src/review-api/http.ts +52 -6
  102. package/src/review-api/instructions.ts +1 -1
  103. package/src/review-api/mcp.ts +10 -5
  104. package/src/review-api/public-tools.ts +71 -2
  105. package/src/review-api/store.ts +89 -12
  106. package/src/server/desktop-server.ts +17 -5
  107. package/src/server/headless-host.ts +4 -0
  108. package/src/server/review-gateway.ts +1 -0
  109. package/src/server/review-server-core.ts +71 -12
  110. package/src/sharing/client.ts +129 -32
  111. package/src/sharing/export.ts +42 -5
  112. package/src/sharing/file.ts +8 -0
  113. package/src/sharing/host.ts +202 -73
  114. package/src/sharing/import.ts +125 -33
  115. package/src/ui-telemetry-events.ts +25 -1
  116. package/dist/agent-cli-B8KBHuh_.js +0 -2
  117. package/dist/profile-BjcXi-oH.js +0 -2
@@ -1,10 +1,10 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { E as ReviewCliInstallStampSchema } from "./src-DLWol7GZ.js";
3
- import { C as disableTraceMachine, E as traceMachineStatus, G as listTraceRepositoryRoots, K as traceRepositoryStatus, Q as removeAgentTraceHook, S as configureTraceMachine, T as traceMachineEnabled, U as disableAllTraceRepositories, W as enableTraceRepository, X as describeTraceHookOwners, Y as AGENT_TRACE_HOOK_AGENTS, Z as installHarnessHooks, at as readStoreAuth, n as reviewDesktopStateDir, nt as traceScope, ut as StoreClient } from "./review-home-paths-LdGS4SpR.js";
2
+ import { D as ReviewCliInstallStampSchema } from "./src-CrrW7lcY.js";
3
+ import { C as disableTraceMachine, E as traceMachineStatus, G as listTraceRepositoryRoots, K as traceRepositoryStatus, Q as removeAgentTraceHook, S as configureTraceMachine, T as traceMachineEnabled, U as disableAllTraceRepositories, W as enableTraceRepository, X as describeTraceHookOwners, Y as AGENT_TRACE_HOOK_AGENTS, Z as installHarnessHooks, at as readStoreAuth, n as reviewDesktopStateDir, nt as traceScope, ut as StoreClient } from "./review-home-paths-BmZX2qiz.js";
4
4
  import { I as writeFileAtomicAsync, L as writePrivateJsonAtomic, N as devReviewHome, j as withFileLock } from "./s3-config-CjcLyFV5.js";
5
- import { i as readReviewPackageVersion } from "./package-paths-Cg6fnaGp.js";
6
- import { f as isDirectory, p as isFile } from "./thread-state-B7L1mpN_.js";
7
- import { c as findExecutable, s as executableCommand } from "./fuzzy-match-DZjeOaPY.js";
5
+ import { i as readReviewPackageVersion } from "./package-paths-Dk7MOXxN.js";
6
+ import { f as isDirectory, p as isFile } from "./thread-state-WTqSborE.js";
7
+ import { c as findExecutable, s as executableCommand } from "./fuzzy-match-CxcsLQGx.js";
8
8
  import { createHash } from "node:crypto";
9
9
  import { constants } from "node:fs";
10
10
  import { access, chmod, lstat, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
@@ -1,12 +1,12 @@
1
1
  import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import { T as traceMachineEnabled } from "./review-home-paths-LdGS4SpR.js";
3
- import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-CMacGbMp.js";
2
+ import { T as traceMachineEnabled } from "./review-home-paths-BmZX2qiz.js";
3
+ import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-BCEbSPWU.js";
4
4
  import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
5
- import { n as readBuildCommit } from "./package-paths-Cg6fnaGp.js";
6
- import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-WmuFl2S3.js";
7
- import { n as reviewSessionAgent } from "./review-telemetry-x8u-9EZb.js";
8
- import { a as REVIEW_VIA_HEADER, i as REVIEW_THREAD_HEADER, n as REVIEW_AGENT_HEADER, t as ASK_THREAD_ENV } from "./request-origin-B3_XI2VA.js";
9
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-RLR8m9hq.js";
5
+ import { n as readBuildCommit } from "./package-paths-Dk7MOXxN.js";
6
+ import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-CV5qf1J8.js";
7
+ import { n as reviewSessionAgent } from "./review-telemetry-DACDMfqq.js";
8
+ import { a as REVIEW_VIA_HEADER, i as REVIEW_THREAD_HEADER, n as REVIEW_AGENT_HEADER, t as ASK_THREAD_ENV } from "./request-origin-D6B-zrL8.js";
9
+ import { a as renderedImage, i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-YOFGHJCZ.js";
10
10
  import { existsSync } from "node:fs";
11
11
  import path from "node:path";
12
12
  //#region src/review-api/install-update.ts
@@ -43,7 +43,7 @@ async function runReviewAgentCli(input) {
43
43
  [REVIEW_THREAD_HEADER, thread ?? ""]
44
44
  ]);
45
45
  if (mode === "mcp") {
46
- const { serveReviewMcp } = await import("./mcp-COYWiGVn.js");
46
+ const { serveReviewMcp } = await import("./mcp-Claiy9xE.js");
47
47
  exitOnInstallUpdate(input.stderr);
48
48
  await serveReviewMcp(async (key, agentKind) => {
49
49
  const connected = await connectReviewInstance(key ? {
@@ -124,7 +124,7 @@ async function runReviewAgentCli(input) {
124
124
  ok: true,
125
125
  durationMs: Date.now() - startedAt
126
126
  });
127
- const text = toolResultText(tool, result);
127
+ const text = toolResultText(tool, renderedImage(tool, result).result);
128
128
  input.stdout.write(text.endsWith("\n") ? text : text + "\n");
129
129
  return 0;
130
130
  } catch (error) {
@@ -0,0 +1,2 @@
1
+ import { n as runReviewAgentCli } from "./agent-cli-D7fF5xmm.js";
2
+ export { runReviewAgentCli };
@@ -1,7 +1,7 @@
1
1
  import { d as isBooleanValue, f as isNumberValue, m as isStringValue, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import { ot as ReviewInputError } from "./src-B2b8cCoI.js";
3
- import "./src-DLWol7GZ.js";
4
- import { b as selectReviewInstance, c as reviewServerStateDir, d as ReviewInstanceUnavailableError, i as readReviewServerDiscovery, l as serverNotReady, m as healthyReviewInstance, s as reviewServerIsHealthy, y as reviewInstanceUnavailable } from "./server-discovery-WmuFl2S3.js";
2
+ import { ot as ReviewInputError } from "./src-BQDlJXkG.js";
3
+ import "./src-CrrW7lcY.js";
4
+ import { b as selectReviewInstance, c as reviewServerStateDir, d as ReviewInstanceUnavailableError, i as readReviewServerDiscovery, l as serverNotReady, m as healthyReviewInstance, s as reviewServerIsHealthy, y as reviewInstanceUnavailable } from "./server-discovery-CV5qf1J8.js";
5
5
  //#region ../review-protocol/src/review-api-client.ts
6
6
  const defaultRequest = (url, init) => fetch(url, init);
7
7
  /** A non-2xx reply; the status tells a caller whether retrying can help. */
@@ -259,7 +259,7 @@ async function connectReviewInstance(env = process.env, headers = {}, options =
259
259
  const selection = await selectReviewInstance({ env });
260
260
  const discovery = healthyReviewInstance(selection);
261
261
  if (!discovery) {
262
- const { ensureServerWithoutDesktop } = await import("./background-server-BLNHbksB.js");
262
+ const { ensureServerWithoutDesktop } = await import("./background-server-CwToVN1g.js");
263
263
  const server = await ensureServerWithoutDesktop({
264
264
  selection,
265
265
  env,
@@ -1,7 +1,7 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { F as writableBlockTypes, N as componentReference, ct as activityEndSchema, f as pathTargetSchema, g as publishedEdits, lt as activityUpdateSchema, ot as ReviewInputError, st as activityBeginSchema } from "./src-B2b8cCoI.js";
3
- import { n as uploadSchema, r as commandSchema } from "./local-data-C58vzLZR.js";
4
- import { t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.js";
2
+ import { F as writableBlockTypes, N as componentReference, ct as activityEndSchema, f as pathTargetSchema, g as publishedEdits, lt as activityUpdateSchema, ot as ReviewInputError, st as activityBeginSchema } from "./src-BQDlJXkG.js";
3
+ import { n as uploadSchema, r as commandSchema } from "./local-data-DdFkxFK_.js";
4
+ import { t as findReviewPackageRoot } from "./package-paths-Dk7MOXxN.js";
5
5
  import { z } from "zod";
6
6
  import { readFile } from "node:fs/promises";
7
7
  import path from "node:path";
@@ -73,7 +73,7 @@ const instructionsQuerySchema = z.strictObject({ topic: z.enum([
73
73
  "trace-archaeology"
74
74
  ]).default("authoring") });
75
75
  /** Keep disabled experimental components out of agent guidance. */
76
- const desktopBlockTypes = (animationsEnabled) => writableBlockTypes.filter((type) => animationsEnabled || type !== "animation");
76
+ const desktopBlockTypes = (animationsEnabled) => writableBlockTypes.filter((type) => animationsEnabled || type !== "animation" && type !== "clip");
77
77
  const COMPONENT_EXAMPLE = "Example (replace its path and lines with verified ones): {\"type\":\"sequence\",\"title\":\"Request\",\"actors\":{\"a\":\"Client\",\"b\":\"Server\"},\"steps\":[{\"from\":\"a\",\"to\":\"b\",\"label\":\"Send\",\"source\":\"head/src/app.ts#L10-L20\"}]}";
78
78
  const cache = /* @__PURE__ */ new Map();
79
79
  function read(root, name) {
@@ -145,7 +145,7 @@ function authoringTools(traceEnabled = false, animationsEnabled = false) {
145
145
  "insert adds content: parentId nests it, afterId places it, and omitted placement appends. update patches a component's own fields; null removes an optional one. A section's children and a diagram's units change through their own IDs; a call stack's frames change by replacing the call stack. move and remove take a targetId; removing a flow_node removes its edges.",
146
146
  "The host assigns short durable IDs. The result names the edited component and, for an insert or replace, its first-level children, and quotes the first and last line of each anchor the edit added or changed (the first 20; unquotedAnchors counts the rest): check they are the lines you meant. Accepted edits save at once. An edit to a block the user is editing is refused with an error: edit another block, or retry later.",
147
147
  "While a reader may be watching, write small and often: one paragraph per edit. Insert a new diagram whole. Change one already drawn a unit at a time (a flow_node, flow_edge or step, with parentId naming the diagram), and link each added flow_node to a node already drawn.",
148
- ...animationsEnabled ? ["An animation is edited as files: review_checkout writes it to a folder, you edit the files with your own file tools, and an edit with fromFiles naming that folder publishes it in place of content or changes. Publish the same folder again after each round of edits."] : []
148
+ ...animationsEnabled ? ["An animation or clip is edited as files: review_checkout writes it to a folder, you edit the files with your own file tools, and an edit with fromFiles naming that folder publishes it in place of content or changes. Publish the same folder again after each round of edits."] : []
149
149
  ].join("\n"),
150
150
  lens_edit: "Edit one Diff-view lens. Lenses partition the review's change for the Diff view; they sit beside the document (never in it) and version with it. The host assigns durable lens IDs; updates replace only the fields supplied. Write one lens per call while a reader may be watching; each draws in on the Diffs page. Pass your activityId so your courier draws each lens. The result identifies the lens and reports uncategorized: changed lines no lens selects yet, grouped by file. Keep adding lenses until it is empty or what remains is deliberate. review_lens_get reads the current lenses and gaps.",
151
151
  rename: "Change the review title.",
@@ -191,11 +191,15 @@ function authoringTools(traceEnabled = false, animationsEnabled = false) {
191
191
  ...type === "edit" && { edit: animationsEnabled ? withDraftFiles(publishedEdits(desktopBlockTypes(true))) : publishedEdits(desktopBlockTypes(false)) }
192
192
  }), "POST", "/commands", type);
193
193
  }),
194
- ...animationsEnabled ? [tool("checkout", "Write an animation to a folder of files to edit with your own file tools: animation.html (its html), frames.json (its frames, each with its data), scenarios.json and block.json (title, code, height, pins). Then publish the folder with review_edit, giving fromFiles instead of content or changes. dir defaults to a folder Whiteboard manages; checking out again overwrites it. A publish is refused if the animation changed after the checkout.", z.strictObject({
194
+ ...animationsEnabled ? [tool("checkout", "Write an animation or clip to a folder of files to edit with your own file tools: animation.html (its html), frames.json (an animation's frames, each with its data) or markers.json (a clip's markers), scenarios.json and block.json (title, code, height, pins). Then publish the folder with review_edit, giving fromFiles instead of content or changes. dir defaults to a folder Whiteboard manages; checking out again overwrites it. A publish is refused if the block changed after the checkout.", z.strictObject({
195
195
  ...review,
196
196
  targetId: id,
197
197
  dir: id.optional()
198
- }), "GET", "/:reviewId/inspect")] : [],
198
+ }), "GET", "/:reviewId/inspect"), tool("render", "See an animation or clip as the reader does: Desktop shows one of its frames (frame: a frame key, or a clip's marker key; omitted, the first) on the open whiteboard and returns it as a PNG image, with the error its script threw, if any. The PNG is also written to the path the result names. After publishing, render each frame you changed and look at it, instead of taking screenshots of the screen. The whiteboard must be open in Desktop: review_create opens it, and review_open opens an existing one.", z.strictObject({
199
+ ...review,
200
+ targetId: id,
201
+ frame: id.optional()
202
+ }), "GET", "/:reviewId/render")] : [],
199
203
  tool("list", "List saved reviews.", z.strictObject({}), "GET", ""),
200
204
  tool("get", "Read a readable, nested text outline with editable IDs. targetId reads one component in full; full:true reads all content. Use format:json for raw node data or snapshots instead of text.", z.strictObject({
201
205
  ...review,
@@ -215,7 +219,7 @@ function authoringTools(traceEnabled = false, animationsEnabled = false) {
215
219
  /** Agents may publish an animation's draft folder in place of content or
216
220
  * changes; the agent boundary reads the files before the host sees the edit. */
217
221
  function withDraftFiles(edit) {
218
- const fromFiles = z.string().min(1).describe("An animation's draft folder, from review_checkout or written yourself: publishes its files as the content (insert, replace) or changes (update).");
222
+ const fromFiles = z.string().min(1).describe("An animation's or clip's draft folder, from review_checkout or written yourself: publishes its files as the content (insert, replace) or changes (update). frames.json makes it an animation, markers.json a clip.");
219
223
  const [insert, replace, update, move, remove] = edit.options;
220
224
  return z.discriminatedUnion("type", [
221
225
  insert.partial({ content: true }).extend({ fromFiles: fromFiles.optional() }),
@@ -1,8 +1,8 @@
1
- import "./review-home-paths-LdGS4SpR.js";
1
+ import "./review-home-paths-BmZX2qiz.js";
2
2
  import { D as liveLockOwner, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
3
- import { t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.js";
4
- import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-WmuFl2S3.js";
5
- import { t as desktopApplicationInstalled } from "./review-app-launcher-BZEbDKuK.js";
3
+ import { t as findReviewPackageRoot } from "./package-paths-Dk7MOXxN.js";
4
+ import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-CV5qf1J8.js";
5
+ import { t as desktopApplicationInstalled } from "./review-app-launcher-tTe8bTwg.js";
6
6
  import { mkdir, open, readFile, realpath, stat } from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import { spawn } from "node:child_process";
@@ -1,2 +1,2 @@
1
- import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-eZWXoVcI.js";
1
+ import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-BraP8pJ9.js";
2
2
  export { ensureBackgroundServer, ensureServerWithoutDesktop, headlessServerOwner, stopBackgroundServer };
@@ -1 +1 @@
1
- {"version":"0.5.0","commit":"b3f475d81a1ec90ba0b8c597a19b5bf9221c158a","dirty":true,"builtAt":"2026-11-01T18:28:03.667Z"}
1
+ {"version":"0.5.2-preview.20261104.146","commit":"20f4d6dcfaa9f7a40ff77fd6e6b2467fc89e64fa","dirty":true,"builtAt":"2026-11-04T14:47:42.412Z"}
@@ -1,4 +1,4 @@
1
- import { r as connectReviewApi } from "./agent-client-CMacGbMp.js";
1
+ import { r as connectReviewApi } from "./agent-client-BCEbSPWU.js";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { z } from "zod";
4
4
  import { mkdir, writeFile } from "node:fs/promises";
@@ -1,18 +1,18 @@
1
1
  import { D as __commonJSMin, E as setLocalVcsCommandObserver, O as __require, k as __toESM } from "./src-Y30gweiK.js";
2
2
  import { c as jsonString, n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import { S as REVIEW_REMOTE_ATTACH_END, b as REVIEW_REMOTE_AGENT_IDS, h as REVIEW_CLI_INSTALL_TARGET_LABELS, l as boardTitle, x as REVIEW_REMOTE_ATTACH_BEGIN } from "./src-DLWol7GZ.js";
4
- import { $ as resolveTraceCommand, A as runTraceDeny, E as traceMachineStatus, F as describeSelection, H as resolveTraceRepositoryTarget, J as HOSTED_CAPTURE_SCOPE_DESCRIPTION, K as traceRepositoryStatus, L as loadS3TraceStorage, M as runTraceSessions, N as runTraceStoreDelete, P as runTraceStoreInfo, T as traceMachineEnabled, V as requireTraceConsent, _ as runTraceRepair, at as readStoreAuth, b as runTraceGitHook, c as registerTraceCommands, ct as runStoreWhoami, d as runTraceList$1, dt as withStoreAuthorization, f as runTracePull$1, ft as emitJsonEvent, g as runTraceInstallMachine, h as runTraceEnable, ht as jsonRequestedInArgv, j as runTraceOnboard, k as runTraceAllow, l as resolveTraceReadStorage, lt as StoreApiError, m as runTraceDisable, mt as humanStream, nt as traceScope, ot as runStoreLogin, p as runTraceShow, pt as failWithJsonError, q as readTraceUserConfig, rt as DEFAULT_STORE_ORIGIN, st as runStoreLogout, tt as traceHomeDir, u as runTraceBlame, ut as StoreClient, v as runTraceStatus, w as readLegacyCaptureSettings, x as runTraceHook, y as runTraceSync, z as selectTraceStorage } from "./review-home-paths-LdGS4SpR.js";
5
- import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-CMacGbMp.js";
3
+ import { C as REVIEW_REMOTE_ATTACH_END, S as REVIEW_REMOTE_ATTACH_BEGIN, h as REVIEW_CLI_INSTALL_TARGET_LABELS, l as boardTitle, x as REVIEW_REMOTE_AGENT_IDS } from "./src-CrrW7lcY.js";
4
+ import { $ as resolveTraceCommand, A as runTraceDeny, E as traceMachineStatus, F as describeSelection, H as resolveTraceRepositoryTarget, J as HOSTED_CAPTURE_SCOPE_DESCRIPTION, K as traceRepositoryStatus, L as loadS3TraceStorage, M as runTraceSessions, N as runTraceStoreDelete, P as runTraceStoreInfo, T as traceMachineEnabled, V as requireTraceConsent, _ as runTraceRepair, at as readStoreAuth, b as runTraceGitHook, c as registerTraceCommands, ct as runStoreWhoami, d as runTraceList$1, dt as withStoreAuthorization, f as runTracePull$1, ft as emitJsonEvent, g as runTraceInstallMachine, h as runTraceEnable, ht as jsonRequestedInArgv, j as runTraceOnboard, k as runTraceAllow, l as resolveTraceReadStorage, lt as StoreApiError, m as runTraceDisable, mt as humanStream, nt as traceScope, ot as runStoreLogin, p as runTraceShow, pt as failWithJsonError, q as readTraceUserConfig, rt as DEFAULT_STORE_ORIGIN, st as runStoreLogout, tt as traceHomeDir, u as runTraceBlame, ut as StoreClient, v as runTraceStatus, w as readLegacyCaptureSettings, x as runTraceHook, y as runTraceSync, z as selectTraceStorage } from "./review-home-paths-BmZX2qiz.js";
5
+ import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-BCEbSPWU.js";
6
6
  import { C as s3ProfileSchema, E as writeTraceConfigFile, N as devReviewHome, P as normalizeStoreOrigin, S as readTraceConfigFile, T as sameS3Profile, _ as emptyTraceConfig, c as resolveS3Setup, g as currentStore, h as TraceConfigurationError, i as isS3MockMode, n as clearTraceEnvCache, o as readTraceEnvFile, p as traceSettingsPath, w as s3Store } from "./s3-config-CjcLyFV5.js";
7
7
  import { t as errorMessage } from "./error-message-OtiDonty.js";
8
- import { i as readReviewPackageVersion, r as readBuildInfo, t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.js";
8
+ import { i as readReviewPackageVersion, r as readBuildInfo, t as findReviewPackageRoot } from "./package-paths-Dk7MOXxN.js";
9
9
  import { t as resolveReviewRoot } from "./runtime-Bhk5L_SN.js";
10
- import { a as readReviewServerHealth, b as selectReviewInstance, c as reviewServerStateDir, d as ReviewInstanceUnavailableError, f as clearDefaultReviewInstance, g as requireHealthyReviewDesktop, h as readDefaultReviewInstance, i as readReviewServerDiscovery, l as serverNotReady, m as healthyReviewInstance, p as desktopUsesHome, t as DESKTOP_TAKEOVER_SIGNAL, u as REVIEW_INSTANCE_ENV, x as writeDefaultReviewInstance, y as reviewInstanceUnavailable } from "./server-discovery-WmuFl2S3.js";
11
- import { t as ReviewTelemetry } from "./review-telemetry-x8u-9EZb.js";
12
- import { t as fuzzyRank } from "./fuzzy-match-DZjeOaPY.js";
13
- import { _ as isInstallTarget, a as isOwnedShim, f as windowsInstallerCommand, g as ALL_INSTALL_TARGETS, h as detectConnectAgents, m as connectAgent, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount, v as connectPrompts } from "./account-alias-Bw3PT3Qo.js";
14
- import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-BZEbDKuK.js";
15
- import { t as reviewAgentCliHelp } from "./agent-cli-kHRrwO4n.js";
10
+ import { a as readReviewServerHealth, b as selectReviewInstance, c as reviewServerStateDir, d as ReviewInstanceUnavailableError, f as clearDefaultReviewInstance, g as requireHealthyReviewDesktop, h as readDefaultReviewInstance, i as readReviewServerDiscovery, l as serverNotReady, m as healthyReviewInstance, p as desktopUsesHome, t as DESKTOP_TAKEOVER_SIGNAL, u as REVIEW_INSTANCE_ENV, x as writeDefaultReviewInstance, y as reviewInstanceUnavailable } from "./server-discovery-CV5qf1J8.js";
11
+ import { t as ReviewTelemetry } from "./review-telemetry-DACDMfqq.js";
12
+ import { t as fuzzyRank } from "./fuzzy-match-CxcsLQGx.js";
13
+ import { _ as isInstallTarget, a as isOwnedShim, f as windowsInstallerCommand, g as ALL_INSTALL_TARGETS, h as detectConnectAgents, m as connectAgent, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount, v as connectPrompts } from "./account-alias-BlYamXAG.js";
14
+ import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-tTe8bTwg.js";
15
+ import { t as reviewAgentCliHelp } from "./agent-cli-D7fF5xmm.js";
16
16
  import { existsSync, mkdirSync, renameSync, writeFileSync } from "node:fs";
17
17
  import { realpath } from "node:fs/promises";
18
18
  import path from "node:path";
@@ -4333,7 +4333,7 @@ async function runReviewCli(input) {
4333
4333
  if (!Number.isInteger(port) || port < 0 || port > 65535) throw new ReviewCliUsageError("--port must be an integer between 0 and 65535.");
4334
4334
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4335
4335
  if (options.detach) {
4336
- const { ensureBackgroundServer } = await import("./background-server-BLNHbksB.js");
4336
+ const { ensureBackgroundServer } = await import("./background-server-CwToVN1g.js");
4337
4337
  const { discovery, started } = await ensureBackgroundServer({
4338
4338
  stateDir,
4339
4339
  env,
@@ -4355,7 +4355,7 @@ async function runReviewCli(input) {
4355
4355
  process.once("SIGINT", stop);
4356
4356
  process.once("SIGTERM", stop);
4357
4357
  process.once(DESKTOP_TAKEOVER_SIGNAL, takeover);
4358
- const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-B4r0s1ks.js");
4358
+ const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-cLipIufH.js");
4359
4359
  try {
4360
4360
  await runHeadlessServer({
4361
4361
  stateDir,
@@ -4392,7 +4392,7 @@ async function runReviewCli(input) {
4392
4392
  configureJsonOutput(serverCommand.command("stop").description("Stop a background server started by --detach, the CLI, or Desktop").option("--state-dir <path>", "directory selected when starting the server"), "plain").action(async (_options, command) => {
4393
4393
  const options = command.optsWithGlobals();
4394
4394
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4395
- const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-BLNHbksB.js");
4395
+ const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-CwToVN1g.js");
4396
4396
  const owner = await headlessServerOwner(stateDir);
4397
4397
  const discovery = await readReviewServerDiscovery(stateDir);
4398
4398
  if (owner === void 0) {
@@ -4420,7 +4420,7 @@ async function runReviewCli(input) {
4420
4420
  if (!existsSync(path.join(stateDir, "review-api.db"))) throw new Error(`No saved reviews in ${stateDir}, so there is no server id to reset. Check --state-dir.`);
4421
4421
  const inUse = `A Whiteboard server is using ${stateDir}. Stop it first, then run whiteboard server reset-id again.`;
4422
4422
  if (await desktopUsesHome(stateDir, env)) return refuse(inUse, options.json);
4423
- const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-BjcXi-oH.js"), import("./headless-host-B4r0s1ks.js")]);
4423
+ const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-BxdzBxHW.js"), import("./headless-host-cLipIufH.js")]);
4424
4424
  const reset = await withHeadlessServerLock(await realpath(stateDir), async () => {
4425
4425
  const local = await openReviewProfile(stateDir, { manageWorkspaces: false });
4426
4426
  try {
@@ -4442,7 +4442,7 @@ async function runReviewCli(input) {
4442
4442
  configureJsonOutput(remote.command("attach").description("Start a background server if none is healthy and report how to reach it").option("--state-dir <path>", "directory for saved reviews and server discovery").option("--groups <groups>", "comma-separated optional extension groups the Desktop has enabled, such as go").option("--replace", "stop a running server of another version that the CLI or Desktop started, and start this one"), "plain").action(async (_options, command) => {
4443
4443
  const options = command.optsWithGlobals();
4444
4444
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4445
- const { remoteAttach } = await import("./remote-attach-C1prLjmj.js");
4445
+ const { remoteAttach } = await import("./remote-attach-LGTpwpUv.js");
4446
4446
  let attach;
4447
4447
  try {
4448
4448
  attach = await remoteAttach({
@@ -4469,7 +4469,7 @@ async function runReviewCli(input) {
4469
4469
  });
4470
4470
  configureJsonOutput(remote.command("extensions").description("Language extensions for the language server on a remote").command("ensure").description("Download the curated extensions for this machine and list them for the language server").option("--groups <groups>", "comma-separated optional extension groups the Desktop has enabled, such as go"), "plain").action(async (_options, command) => {
4471
4471
  const { json, groups } = command.optsWithGlobals();
4472
- const { ensureRemoteExtensions } = await import("./remote-extensions-Bw029iIS.js");
4472
+ const { ensureRemoteExtensions } = await import("./remote-extensions-BvV29_gk.js");
4473
4473
  const result = await ensureRemoteExtensions({
4474
4474
  env,
4475
4475
  groups: groups?.split(",").map((group) => group.trim())
@@ -4484,7 +4484,7 @@ async function runReviewCli(input) {
4484
4484
  configureJsonOutput(remote.command("uninstall").description("Remove what Whiteboard Desktop installed on this host, stopping a server it started").addOption(new Option("--keep-reviews", "leave the saved reviews in place").conflicts("deleteReviews")).addOption(new Option("--delete-reviews", "also delete the saved reviews")).option("--state-dir <path>", "directory for saved reviews and server discovery"), "plain").action(async (_options, command) => {
4485
4485
  const options = command.optsWithGlobals();
4486
4486
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4487
- const { remoteUninstall } = await import("./remote-uninstall-B3Slwor1.js");
4487
+ const { remoteUninstall } = await import("./remote-uninstall-CLP79Cuk.js");
4488
4488
  let deleteReviews = options.deleteReviews ? true : options.keepReviews ? false : void 0;
4489
4489
  if (deleteReviews === void 0 && !options.json && input.stdin?.isTTY) {
4490
4490
  const prompt = createInterface$1({
@@ -4706,14 +4706,14 @@ async function runReviewCli(input) {
4706
4706
  command.showHelpAfterError(false).error("Markdown review migration is no longer supported. Ask your agent to migrate your old Whiteboard reviews.");
4707
4707
  });
4708
4708
  configureJsonOutput(configureJsonOutput(program.command("share").description("Upload an immutable review snapshot and return its share link"), "plain").option("--review <id>", "review ID").option("--version <number>", "Saved version to share").option("--preview", "Open the share link in Whiteboard Preview by default").option("--request-id <uuid>", "Reuse this ID when retrying the same immutable upload").action(async (options) => {
4709
- const { runShareCli } = await import("./cli-Bxmiqutp.js");
4709
+ const { runShareCli } = await import("./cli-BpadBaGU.js");
4710
4710
  state.exitCode = await runShareCli({
4711
4711
  ...input,
4712
4712
  ...options,
4713
4713
  env: authoringEnv()
4714
4714
  });
4715
4715
  }).command("revoke <share-id>").description("Revoke future downloads of a share"), "plain").action(async (shareId, options) => {
4716
- const { runShareCli } = await import("./cli-Bxmiqutp.js");
4716
+ const { runShareCli } = await import("./cli-BpadBaGU.js");
4717
4717
  state.exitCode = await runShareCli({
4718
4718
  ...input,
4719
4719
  ...options,
@@ -4722,7 +4722,7 @@ async function runReviewCli(input) {
4722
4722
  });
4723
4723
  });
4724
4724
  configureJsonOutput(program.command("export").description("Write a review snapshot as a .whiteboard file"), "plain").option("--review <id>", "review ID").option("--version <number>", "Saved version to export").option("--out <path>", "File to write, or - for stdout; defaults to <title>.whiteboard here").action(async (options) => {
4725
- const { runExportCli } = await import("./cli-Bxmiqutp.js");
4725
+ const { runExportCli } = await import("./cli-BpadBaGU.js");
4726
4726
  state.exitCode = await runExportCli({
4727
4727
  ...input,
4728
4728
  ...options,
@@ -4730,7 +4730,7 @@ async function runReviewCli(input) {
4730
4730
  env: authoringEnv()
4731
4731
  });
4732
4732
  });
4733
- configureJsonOutput(program.command("login").description("Log in to Whiteboard with GitHub"), "plain").option("--origin <url>", "Whiteboard service origin", DEFAULT_STORE_ORIGIN).option("--traces", "Also authorize GitHub repositories for hosted traces").option("--no-browser", "Print the URL instead of opening a browser").action(async (options) => {
4733
+ configureJsonOutput(program.command("login").description("Log in to Whiteboard with GitHub"), "plain").option("--origin <url>", `Whiteboard service origin (default: $DEV_REVIEW_SERVICE_ORIGIN or ${DEFAULT_STORE_ORIGIN})`).option("--traces", "Also authorize GitHub repositories for hosted traces").option("--no-browser", "Print the URL instead of opening a browser").action(async (options) => {
4734
4734
  state.exitCode = await runtime.runStoreLogin({
4735
4735
  origin: options.origin,
4736
4736
  noBrowser: options.browser === false,
@@ -4803,7 +4803,7 @@ async function runReviewCli(input) {
4803
4803
  return commands;
4804
4804
  } });
4805
4805
  for (const [name, description] of [["api", "Call a JSON review authoring tool on the running server"], ["mcp", "Serve the JSON review authoring tools over stdio MCP"]]) configureOutput(program.command(name).description(description).argument("[args...]", "tool name and JSON input").allowUnknownOption().allowExcessArguments().helpOption(false).passThroughOptions().addHelpText("after", `\n${reviewAgentCliHelp}`), "plain").action(async (args) => {
4806
- const { runReviewAgentCli } = await import("./agent-cli-B8KBHuh_.js");
4806
+ const { runReviewAgentCli } = await import("./agent-cli-DLibAL4u.js");
4807
4807
  state.exitCode = await runReviewAgentCli({
4808
4808
  ...input,
4809
4809
  env: authoringEnv(),
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as jsonNumber, c as jsonString, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import "./src-DLWol7GZ.js";
3
+ import "./src-CrrW7lcY.js";
4
4
  import { existsSync, readFileSync, readdirSync, realpathSync } from "node:fs";
5
5
  import path from "node:path";
6
6
  import os from "node:os";
@@ -17,7 +17,7 @@ async function runCli(effectivePath) {
17
17
  `);
18
18
  return 1;
19
19
  }
20
- const { runReviewCli } = await import("./cli-runner-DQPuu7kJ.js");
20
+ const { runReviewCli } = await import("./cli-runner-BebYF50a.js");
21
21
  return runReviewCli({
22
22
  argv,
23
23
  cliPaths: {
@@ -1,7 +1,7 @@
1
- import "./review-home-paths-LdGS4SpR.js";
1
+ import "./review-home-paths-BmZX2qiz.js";
2
2
  import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
3
- import { n as askAgentIds } from "./thread-state-B7L1mpN_.js";
4
- import { t as ASK_THREAD_ENV } from "./request-origin-B3_XI2VA.js";
3
+ import { n as askAgentIds } from "./thread-state-WTqSborE.js";
4
+ import { t as ASK_THREAD_ENV } from "./request-origin-D6B-zrL8.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { constants } from "node:fs";
7
7
  import { access, chmod, mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";