@dev.fast/whiteboard 0.4.1-preview.20261028.142 → 0.4.1-preview.20261030.143

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 (112) hide show
  1. package/dist/{account-alias-D1iIc7j5.js → account-alias-DtN9zBzt.js} +3 -3
  2. package/dist/{agent-cli-B_gSzrhA.js → agent-cli-D2WEQwul.js} +6 -6
  3. package/dist/agent-cli-m3uWrslh.js +2 -0
  4. package/dist/{agent-client-DudPjH3I.js → agent-client-CXXjD60Q.js} +4 -4
  5. package/dist/{authoring-tools-B-OyXmtR.js → authoring-tools-BEGW2s0A.js} +31 -46
  6. package/dist/{background-server-CORnMQmu.js → background-server-Cw7lddwb.js} +1 -1
  7. package/dist/{background-server-CesuMV6N.js → background-server-D_4Xt3fF.js} +2 -2
  8. package/dist/build-info.json +1 -1
  9. package/dist/{cli-CIP_-Fvm.js → cli-SDWXOZPY.js} +1 -1
  10. package/dist/{cli-runner-dHnKnyNw.js → cli-runner-DaPGJWRf.js} +17 -17
  11. package/dist/cli.js +2 -2
  12. package/dist/{fuzzy-match-CTvayutE.js → fuzzy-match-BMcd-rQ0.js} +2 -2
  13. package/dist/{headless-host-Cnu-o0xk.js → headless-host-CMDr4BpH.js} +1 -1
  14. package/dist/{headless-host-CWuFw-CO.js → headless-host-DDYA2wwn.js} +34 -18
  15. package/dist/{import-FOpJL22V.js → import-LsDP99A9.js} +2 -3
  16. package/dist/{local-data-BhNZ1Yep.js → local-data-G2I-77FX.js} +60 -18
  17. package/dist/{mcp-2bWqlJNW.js → mcp-tqD6Fwvy.js} +12 -13
  18. package/dist/profile-Bw0hDDNd.js +2 -0
  19. package/dist/{profile-DnwIJvlh.js → profile-i2n1HdIg.js} +1 -1
  20. package/dist/{remote-attach-C79X5M2Z.js → remote-attach-BsOO_ER4.js} +3 -3
  21. package/dist/{remote-language-server-Dw1o27aF.js → remote-language-server-AamAHhw_.js} +1 -1
  22. package/dist/{remote-uninstall-Aza0u1_3.js → remote-uninstall-BH2ovwP1.js} +3 -3
  23. package/dist/{request-origin-DEQd09Db.js → request-origin-BkrzpcVd.js} +3 -4
  24. package/dist/{review-app-launcher-L7xKjTLQ.js → review-app-launcher-1tcH84u6.js} +2 -2
  25. package/dist/{review-telemetry-lmK8HPLI.js → review-telemetry-B6mxAOXA.js} +2 -2
  26. package/dist/server/desktop-host.js +11 -11
  27. package/dist/{server-discovery-D-2vz5gG.js → server-discovery-nLX2SH_v.js} +1 -1
  28. package/dist/sharing/index.d.ts +847 -175
  29. package/dist/sharing/index.js +1 -1
  30. package/dist/{stored-document-migration-CZe65mkx.js → src-B2b8cCoI.js} +1606 -2630
  31. package/dist/{src-Bew3mW9I.js → src-Coec7jLU.js} +1 -0
  32. package/dist/stored-document-migration-Ca9BWqEF.js +1342 -0
  33. package/dist/{thread-state-XgVKaQ3-.js → thread-state-DosGpp3S.js} +22 -2
  34. package/dist/tool-failure-CwTgI76j.js +715 -0
  35. package/instructions/animation.md +51 -270
  36. package/instructions/whiteboard.d.ts +286 -0
  37. package/package.json +9 -7
  38. package/src/animation-stage-kit.ts +413 -0
  39. package/src/review-api/activity.ts +10 -45
  40. package/src/review-api/agent-client.ts +2 -2
  41. package/src/review-api/anchor-quotes.ts +4 -6
  42. package/src/review-api/animation-drafts.ts +354 -0
  43. package/src/review-api/animation-runs.ts +54 -0
  44. package/src/review-api/ask-history.ts +1 -2
  45. package/src/review-api/authoring-tools.ts +59 -8
  46. package/src/review-api/azure-devops-provider.ts +1 -1
  47. package/src/review-api/comparison-coverage.ts +5 -3
  48. package/src/review-api/document-headings.ts +5 -3
  49. package/src/review-api/document-text.ts +37 -5
  50. package/src/review-api/file-lenses.ts +6 -4
  51. package/src/review-api/foreign-references.ts +2 -2
  52. package/src/review-api/github-provider.ts +1 -1
  53. package/src/review-api/http.ts +21 -7
  54. package/src/review-api/image-decode.ts +1 -1
  55. package/src/review-api/instructions.ts +19 -4
  56. package/src/review-api/lens-alignment.ts +1 -1
  57. package/src/review-api/link-preview.ts +1 -1
  58. package/src/review-api/local-data.ts +20 -22
  59. package/src/review-api/mcp.ts +10 -15
  60. package/src/review-api/onboarding.ts +1 -1
  61. package/src/review-api/provider.ts +2 -1
  62. package/src/review-api/public-tools.ts +91 -3
  63. package/src/review-api/pull-request.ts +1 -2
  64. package/src/review-api/read-schemas.ts +4 -3
  65. package/src/review-api/review-progress.ts +12 -15
  66. package/src/review-api/scratchpad-plan-upgrade.ts +1 -1
  67. package/src/review-api/store.ts +69 -32
  68. package/src/review-api/tool-failure.ts +1 -1
  69. package/src/review-api/traces.ts +1 -2
  70. package/src/review-api/workspaces.ts +1 -1
  71. package/src/review-api/worktree-source.ts +1 -1
  72. package/src/review-api/worktree-structural.integration.ts +1 -1
  73. package/src/server/json-review-reporting.ts +1 -1
  74. package/src/server/review-server-core.ts +1 -1
  75. package/src/sharing/auth.ts +1 -1
  76. package/src/sharing/export.ts +7 -8
  77. package/src/sharing/host.ts +1 -1
  78. package/src/sharing/import.ts +4 -4
  79. package/src/sharing/repository.ts +1 -1
  80. package/src/stored-document-migration.ts +7 -4
  81. package/src/ui-telemetry-events.ts +1 -2
  82. package/src/viewed-coverage.ts +6 -20
  83. package/dist/agent-cli-DtjnkDSL.js +0 -2
  84. package/dist/fs-utils-BMPLt0cr.js +0 -22
  85. package/dist/input-error-OLgB_h31.js +0 -11
  86. package/dist/lens-selection-B_LTVyTB.js +0 -223
  87. package/dist/profile-BmtFpq8d.js +0 -2
  88. package/dist/tool-failure-Bi_-Zck-.js +0 -105
  89. package/src/lens-selection.ts +0 -266
  90. package/src/markdown-latex-math.ts +0 -230
  91. package/src/markdown.ts +0 -123
  92. package/src/review-api/blocks/animation.ts +0 -148
  93. package/src/review-api/blocks/call_stack_diff.ts +0 -75
  94. package/src/review-api/blocks/callout.ts +0 -24
  95. package/src/review-api/blocks/code.ts +0 -9
  96. package/src/review-api/blocks/code_peek.ts +0 -13
  97. package/src/review-api/blocks/database_lens.ts +0 -155
  98. package/src/review-api/blocks/definition.ts +0 -42
  99. package/src/review-api/blocks/divider.ts +0 -6
  100. package/src/review-api/blocks/flow_diagram.ts +0 -111
  101. package/src/review-api/blocks/image.ts +0 -10
  102. package/src/review-api/blocks/index.ts +0 -110
  103. package/src/review-api/blocks/markdown.ts +0 -17
  104. package/src/review-api/blocks/section.ts +0 -24
  105. package/src/review-api/blocks/sequence.ts +0 -136
  106. package/src/review-api/blocks/software_map.ts +0 -9
  107. package/src/review-api/blocks/trace_quote.ts +0 -10
  108. package/src/review-api/component-reference.ts +0 -47
  109. package/src/review-api/diff-lenses.ts +0 -175
  110. package/src/review-api/document.ts +0 -1260
  111. package/src/review-api/input-error.ts +0 -9
  112. package/src/source.ts +0 -92
@@ -1,10 +1,10 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { E as ReviewCliInstallStampSchema } from "./src-Bew3mW9I.js";
2
+ import { E as ReviewCliInstallStampSchema } from "./src-Coec7jLU.js";
3
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";
4
4
  import { I as writeFileAtomicAsync, L as writePrivateJsonAtomic, N as devReviewHome, j as withFileLock } from "./s3-config-CjcLyFV5.js";
5
5
  import { i as readReviewPackageVersion } from "./package-paths-Cg6fnaGp.js";
6
- import { n as isFile, t as isDirectory } from "./fs-utils-BMPLt0cr.js";
7
- import { c as findExecutable, s as executableCommand } from "./fuzzy-match-CTvayutE.js";
6
+ import { f as isDirectory, p as isFile } from "./thread-state-DosGpp3S.js";
7
+ import { c as findExecutable, s as executableCommand } from "./fuzzy-match-BMcd-rQ0.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
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-DudPjH3I.js";
3
+ import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-CXXjD60Q.js";
4
4
  import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
5
5
  import { n as readBuildCommit } from "./package-paths-Cg6fnaGp.js";
6
- import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-D-2vz5gG.js";
7
- import { n as reviewSessionAgent } from "./review-telemetry-lmK8HPLI.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-DEQd09Db.js";
9
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-Bi_-Zck-.js";
6
+ import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-nLX2SH_v.js";
7
+ import { n as reviewSessionAgent } from "./review-telemetry-B6mxAOXA.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-BkrzpcVd.js";
9
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-CwTgI76j.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-2bWqlJNW.js");
46
+ const { serveReviewMcp } = await import("./mcp-tqD6Fwvy.js");
47
47
  exitOnInstallUpdate(input.stderr);
48
48
  await serveReviewMcp(async (key, agentKind) => {
49
49
  const connected = await connectReviewInstance(key ? {
@@ -0,0 +1,2 @@
1
+ import { n as runReviewAgentCli } from "./agent-cli-D2WEQwul.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 "./src-Bew3mW9I.js";
3
- import { t as ReviewInputError } from "./input-error-OLgB_h31.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-D-2vz5gG.js";
2
+ import { ot as ReviewInputError } from "./src-B2b8cCoI.js";
3
+ import "./src-Coec7jLU.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-nLX2SH_v.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-CORnMQmu.js");
262
+ const { ensureServerWithoutDesktop } = await import("./background-server-Cw7lddwb.js");
263
263
  const server = await ensureServerWithoutDesktop({
264
264
  selection,
265
265
  env,
@@ -1,7 +1,6 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { c as activityBeginSchema, l as activityEndSchema, n as uploadSchema, r as commandSchema, u as activityUpdateSchema } from "./local-data-BhNZ1Yep.js";
3
- import { P as pathTargetSchema, R as publishedEdits } from "./stored-document-migration-CZe65mkx.js";
4
- import { t as ReviewInputError } from "./input-error-OLgB_h31.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-G2I-77FX.js";
5
4
  import { t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.js";
6
5
  import { z } from "zod";
7
6
  import { readFile } from "node:fs/promises";
@@ -67,52 +66,15 @@ const readQuerySchemas = {
67
66
  }),
68
67
  commits: z.strictObject({ version })
69
68
  };
70
- //#endregion
71
- //#region src/review-api/component-reference.ts
72
- /** The animation component, shown only while Animations are on. */
73
- const ANIMATION = ["- animation {title, html, frames: {key, title, label?, caption?, duration? (ms)}[] (1 to 60), code?: {name: anchor}, height?: \"auto\" (default) | number (120 to 1200 CSS px), pins?}; declare every possible frame", "Use an animation for change over time that a static diagram cannot show: state before and after, a cache filling, data changing as a request crosses layers. It can sit in design beside the diagram, or replace it when the motion is the point. If nothing changes between frames, use a sequence or flow_diagram instead: their steps and nodes link to code. Read session_get_instructions({topic:\"animation\"}) before writing one."];
74
- /** Every component's fields, for session_get_instructions: the edit tool's
75
- * description must stay short enough that clients don't cut it off. */
76
- const COMPONENT_REFERENCE = [
77
- "## Components",
78
- "",
79
- "session_edit's content is one component, named by its type. Fields, with ? for optional and anchor for a source anchor string:",
80
- "",
81
- "- markdown {markdown, pins?}",
82
- "- code {text, language?, caption?}",
83
- "- divider {}",
84
- "- code_peek {source: anchor, caption?, pins?}",
85
- "- section {title, children: component[], defaultCollapsed?}",
86
- "- callout {children: component[], title?, tone?: info|warning|danger|success}",
87
- "- image {assetId from session_upload, alt, caption?}",
88
- "- trace_quote {traceId, eventId, text}",
89
- "- software_map {mapVersionId, focusElementId?}",
90
- "- sequence {title, actors: {key: label}, steps: step[], pins?}",
91
- "- step {from, to (actor keys), label, style?: call|return|async, and exactly one of source: anchor or anchor[] (at most 4), explanation, or code: {text, language?}; pins?}",
92
- "A step's source is the line where its arrow leaves `from` (the call, return or emit). Add an additional range only when that line can't be read without it: the type or schema of what it passes, or the code that builds its argument. Never the callee's body; that is the next step.",
93
- "- flow_diagram {title, nodes: flow_node[] (1 to 100), edges: flow_edge[], description?, direction?: right|down, pins?}",
94
- "- flow_node {key, label, description?, kind?: process|decision|terminal, attachments?: {label, sources: anchor[], pins?}[], link?: {from or to, label?, style?}}",
95
- "- flow_edge {from, to (node keys), label?, style?: solid|dashed}",
96
- "- call_stack_diff {title, base: frame[], head: frame[], pins?}; either side may be empty",
97
- "- frame {source: anchor, label?, key?, parentKey? (an earlier frame on that side), callSite?: anchor, contextSources?: anchor[], via?: {kind: call|queue|callback|rpc, reason}, pins?}",
98
- "- database_lens {title, actors: {key: label}, stores: {key: store}, useCases: useCase[] (1 or more), pins?}",
99
- "- store {label, storage: relational|document, collections: {key: {label, fields: {key: field}, source?: anchor of its schema declaration}}, dataStoreKind?: database|objectStore|bucket|artifactStore|fileStore}",
100
- "- field {label, dataType, nullable?, primaryKey?, references?: {store, collection, field}, fields?: {key: field}}",
101
- "- useCase {label, summary?, operations: operation[] (1 or more)}; operation {kind: read|write, actor, store, collection, label, source: anchor, field?, detail?, pins?}, naming declared keys",
102
- ...ANIMATION,
103
- "",
104
- "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\"}]}"
105
- ].join("\n");
106
- /** Keep disabled experimental components out of agent guidance. */
107
- function componentReference(animationsEnabled) {
108
- return animationsEnabled ? COMPONENT_REFERENCE : COMPONENT_REFERENCE.split("\n").filter((line) => !ANIMATION.includes(line)).join("\n");
109
- }
110
69
  const instructionsQuerySchema = z.strictObject({ topic: z.enum([
111
70
  "authoring",
112
71
  "animation",
113
72
  "file-lenses",
114
73
  "trace-archaeology"
115
74
  ]).default("authoring") });
75
+ /** Keep disabled experimental components out of agent guidance. */
76
+ const desktopBlockTypes = (animationsEnabled) => writableBlockTypes.filter((type) => animationsEnabled || type !== "animation");
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\"}]}";
116
78
  const cache = /* @__PURE__ */ new Map();
117
79
  function read(root, name) {
118
80
  const file = path.join(root, "instructions", `${name}.md`);
@@ -133,7 +95,11 @@ async function renderInstructions(topic, context, root = findReviewPackageRoot(i
133
95
  const more = [...context.traceEnabled ? ["- Why code exists / past agent sessions: `session_get_instructions({topic:\"trace-archaeology\"})`"] : []];
134
96
  return [
135
97
  await read(root, "authoring"),
136
- componentReference(context.animationsEnabled === true),
98
+ [
99
+ componentReference(desktopBlockTypes(context.animationsEnabled === true)),
100
+ "",
101
+ COMPONENT_EXAMPLE
102
+ ].join("\n"),
137
103
  ...context.traceEnabled ? ["## Traces\n\nAt the end, run `whiteboard trace list --session <sessionId> --json`, which covers every commit in the review. If it lists no sessions, there are no traces to quote: skip this step. Otherwise read `session_get_instructions({topic:\"trace-archaeology\"})` and rewrite as much as possible of the what/why, design, and requirements sections in terms of literal trace quotes from the user."] : [],
138
104
  ...more.length ? [`## More guidance\n\n${more.join("\n")}`] : []
139
105
  ].join("\n\n");
@@ -178,7 +144,8 @@ function authoringTools(traceEnabled = false, animationsEnabled = false) {
178
144
  "Anchors are head/path#L10-L20 or base/path#L7, or diff/path#L84-R90 for a range across sides, with repository-relative paths and 1-based inclusive lines. pins {head, base?} say which commits of the whiteboard's repository anchors quote: a step, frame, attachment or operation without pins uses its block's, and a block without them the review's.",
179
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.",
180
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.",
181
- "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."
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."] : []
182
149
  ].join("\n"),
183
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.",
184
151
  rename: "Change the review title.",
@@ -221,9 +188,14 @@ function authoringTools(traceEnabled = false, animationsEnabled = false) {
221
188
  open: z.boolean().optional()
222
189
  },
223
190
  ...type === "set_target" && { target: pathTargetSchema },
224
- ...type === "edit" && { edit: publishedEdits(animationsEnabled) }
191
+ ...type === "edit" && { edit: animationsEnabled ? withDraftFiles(publishedEdits(desktopBlockTypes(true))) : publishedEdits(desktopBlockTypes(false)) }
225
192
  }), "POST", "/commands", type);
226
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({
195
+ ...review,
196
+ targetId: id,
197
+ dir: id.optional()
198
+ }), "GET", "/:reviewId/inspect")] : [],
227
199
  tool("list", "List saved reviews.", z.strictObject({}), "GET", ""),
228
200
  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({
229
201
  ...review,
@@ -240,6 +212,19 @@ function authoringTools(traceEnabled = false, animationsEnabled = false) {
240
212
  tool("upload", "Retain an image or trace for use in a review. kind:\"image\" takes base64; kind:\"trace\" takes trace. Reusing an upload ID requires identical content; rejected uploads are not saved.", uploadInput, "POST", "/resources")
241
213
  ];
242
214
  }
215
+ /** Agents may publish an animation's draft folder in place of content or
216
+ * changes; the agent boundary reads the files before the host sees the edit. */
217
+ 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).");
219
+ const [insert, replace, update, move, remove] = edit.options;
220
+ return z.discriminatedUnion("type", [
221
+ insert.partial({ content: true }).extend({ fromFiles: fromFiles.optional() }),
222
+ replace.partial({ content: true }).extend({ fromFiles: fromFiles.optional() }),
223
+ update.partial({ changes: true }).extend({ fromFiles: fromFiles.optional() }),
224
+ move,
225
+ remove
226
+ ]);
227
+ }
243
228
  /** Drops repositoryId from pins: the host fills in the board's own. */
244
229
  function withoutRepositoryIds(schema) {
245
230
  return JSON.parse(JSON.stringify(schema), (_key, value) => {
@@ -1,2 +1,2 @@
1
- import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-CesuMV6N.js";
1
+ import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-D_4Xt3fF.js";
2
2
  export { ensureBackgroundServer, ensureServerWithoutDesktop, headlessServerOwner, stopBackgroundServer };
@@ -1,8 +1,8 @@
1
1
  import "./review-home-paths-LdGS4SpR.js";
2
2
  import { D as liveLockOwner, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
3
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-D-2vz5gG.js";
5
- import { t as desktopApplicationInstalled } from "./review-app-launcher-L7xKjTLQ.js";
4
+ import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-nLX2SH_v.js";
5
+ import { t as desktopApplicationInstalled } from "./review-app-launcher-1tcH84u6.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 +1 @@
1
- {"version":"0.4.1-preview.20261028.142","commit":"bedb61d18982132726ec118b55337804e8992238","dirty":true,"builtAt":"2026-10-28T15:47:13.214Z"}
1
+ {"version":"0.4.1-preview.20261030.143","commit":"6900e30267289f6b6d3d16ecf8b7f626ff0c355f","dirty":true,"builtAt":"2026-10-30T04:40:00.211Z"}
@@ -1,4 +1,4 @@
1
- import { r as connectReviewApi } from "./agent-client-DudPjH3I.js";
1
+ import { r as connectReviewApi } from "./agent-client-CXXjD60Q.js";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { z } from "zod";
4
4
  //#region src/sharing/cli.ts
@@ -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-Bew3mW9I.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-Coec7jLU.js";
4
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-DudPjH3I.js";
5
+ import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-CXXjD60Q.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
8
  import { i as readReviewPackageVersion, r as readBuildInfo, t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.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-D-2vz5gG.js";
11
- import { t as ReviewTelemetry } from "./review-telemetry-lmK8HPLI.js";
12
- import { t as fuzzyRank } from "./fuzzy-match-CTvayutE.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-D1iIc7j5.js";
14
- import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-L7xKjTLQ.js";
15
- import { t as reviewAgentCliHelp } from "./agent-cli-B_gSzrhA.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-nLX2SH_v.js";
11
+ import { t as ReviewTelemetry } from "./review-telemetry-B6mxAOXA.js";
12
+ import { t as fuzzyRank } from "./fuzzy-match-BMcd-rQ0.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-DtN9zBzt.js";
14
+ import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-1tcH84u6.js";
15
+ import { t as reviewAgentCliHelp } from "./agent-cli-D2WEQwul.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-CORnMQmu.js");
4336
+ const { ensureBackgroundServer } = await import("./background-server-Cw7lddwb.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-Cnu-o0xk.js");
4358
+ const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-CMDr4BpH.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-CORnMQmu.js");
4395
+ const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-Cw7lddwb.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-BmtFpq8d.js"), import("./headless-host-Cnu-o0xk.js")]);
4423
+ const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-Bw0hDDNd.js"), import("./headless-host-CMDr4BpH.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-C79X5M2Z.js");
4445
+ const { remoteAttach } = await import("./remote-attach-BsOO_ER4.js");
4446
4446
  let attach;
4447
4447
  try {
4448
4448
  attach = await remoteAttach({
@@ -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-Aza0u1_3.js");
4487
+ const { remoteUninstall } = await import("./remote-uninstall-BH2ovwP1.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-CIP_-Fvm.js");
4709
+ const { runShareCli } = await import("./cli-SDWXOZPY.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-CIP_-Fvm.js");
4716
+ const { runShareCli } = await import("./cli-SDWXOZPY.js");
4717
4717
  state.exitCode = await runShareCli({
4718
4718
  ...input,
4719
4719
  ...options,
@@ -4794,7 +4794,7 @@ async function runReviewCli(input) {
4794
4794
  return commands;
4795
4795
  } });
4796
4796
  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) => {
4797
- const { runReviewAgentCli } = await import("./agent-cli-DtjnkDSL.js");
4797
+ const { runReviewAgentCli } = await import("./agent-cli-m3uWrslh.js");
4798
4798
  state.exitCode = await runReviewAgentCli({
4799
4799
  ...input,
4800
4800
  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-Bew3mW9I.js";
3
+ import "./src-Coec7jLU.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-dHnKnyNw.js");
20
+ const { runReviewCli } = await import("./cli-runner-DaPGJWRf.js");
21
21
  return runReviewCli({
22
22
  argv,
23
23
  cliPaths: {
@@ -1,7 +1,7 @@
1
1
  import "./review-home-paths-LdGS4SpR.js";
2
2
  import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
3
- import { n as askAgentIds } from "./thread-state-XgVKaQ3-.js";
4
- import { t as ASK_THREAD_ENV } from "./request-origin-DEQd09Db.js";
3
+ import { n as askAgentIds } from "./thread-state-DosGpp3S.js";
4
+ import { t as ASK_THREAD_ENV } from "./request-origin-BkrzpcVd.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";
@@ -1,2 +1,2 @@
1
- import { i as withHeadlessServerLock, n as runHeadlessServer, r as takeOverServerHome, t as HeadlessServerBusyError } from "./headless-host-CWuFw-CO.js";
1
+ import { i as withHeadlessServerLock, n as runHeadlessServer, r as takeOverServerHome, t as HeadlessServerBusyError } from "./headless-host-DDYA2wwn.js";
2
2
  export { HeadlessServerBusyError, runHeadlessServer, takeOverServerHome, withHeadlessServerLock };
@@ -1,22 +1,21 @@
1
1
  import { b as resolveRepoContext, d as git, r as defaultBranch, w as runVcs } from "./src-Y30gweiK.js";
2
2
  import { c as jsonString, m as isStringValue, n as isJsonObject, p as isObjectValue, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import { _ as parseShareLink, a as readShareRepository, c as exportShare, d as lensReport, f as progressUpdateSchema, g as readBoundedStream, h as StreamLimitError, i as forgetSharedCommits, l as validateShareSources, m as uncategorizedReport, n as shareKey, o as ShareAuthError, p as reviewProgress, s as ShareClient, t as importShare, u as legacyModeSchema, v as shareIdSchema } from "./import-FOpJL22V.js";
4
- import { d as invalidateStructuralComparisons, f as diffrExecutable, i as inspectSnapshot, m as readGitHubPullRequests, p as diffrMissingError, r as commandSchema } from "./local-data-BhNZ1Yep.js";
5
- import { I as decodeStructuralDiffEvent, N as reviewDiffrLoginsSchema, O as ReviewFeedbackContactSchema, P as reviewDiffrSummarizerInputSchema, a as parseReviewVerbRequest, c as boardIconKind, i as parseReviewDesktopVerbResult, j as ReviewOnboardingRunRequestSchema, k as ReviewFeedbackSchema, l as boardTitle, m as REVIEW_CLIENT_REMOTE, p as REVIEW_CLIENT_HEADER, y as REVIEW_HOST_HEADER } from "./src-Bew3mW9I.js";
3
+ import { _ as parseShareLink, a as readShareRepository, c as exportShare, d as lensReport, f as progressUpdateSchema, g as readBoundedStream, h as StreamLimitError, i as forgetSharedCommits, l as validateShareSources, m as uncategorizedReport, n as shareKey, o as ShareAuthError, p as reviewProgress, s as ShareClient, t as importShare, u as legacyModeSchema, v as shareIdSchema } from "./import-LsDP99A9.js";
4
+ import { I as stepSources, T as selectionReferences, U as animationCode, et as formatAnchor, n as anchorPins, o as boardRepositoryId, ot as ReviewInputError, rt as selectionKey, u as elements } from "./src-B2b8cCoI.js";
5
+ import { c as invalidateStructuralComparisons, d as readGitHubPullRequests, i as inspectSnapshot, l as diffrExecutable, r as commandSchema, u as diffrMissingError } from "./local-data-G2I-77FX.js";
6
+ import { I as decodeStructuralDiffEvent, N as reviewDiffrLoginsSchema, O as ReviewFeedbackContactSchema, P as reviewDiffrSummarizerInputSchema, a as parseReviewVerbRequest, c as boardIconKind, i as parseReviewDesktopVerbResult, j as ReviewOnboardingRunRequestSchema, k as ReviewFeedbackSchema, l as boardTitle, m as REVIEW_CLIENT_REMOTE, p as REVIEW_CLIENT_HEADER, y as REVIEW_HOST_HEADER } from "./src-Coec7jLU.js";
6
7
  import { B as TraceStorageDeniedError, D as listReviewTraceSessions, I as isTraceStorageConfigured, O as loadReviewAgentTrace, R as resolveTraceStorage, T as traceMachineEnabled, at as readStoreAuth, et as shellQuote, it as clearStoreAuth, ot as runStoreLogin, rt as DEFAULT_STORE_ORIGIN, z as selectTraceStorage } from "./review-home-paths-LdGS4SpR.js";
7
- import { _ as scopedCoverage, s as formatAnchor, u as selectionKey } from "./lens-selection-B_LTVyTB.js";
8
- import { K as selectionReferences, M as elements, O as boardRepositoryId, Z as stepSources, f as sourceBranchName, l as pullRequestKey, p as pullRequestProvider, w as anchorPins } from "./stored-document-migration-CZe65mkx.js";
9
- import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
8
+ import { D as scopedCoverage, f as sourceBranchName, l as pullRequestKey, p as pullRequestProvider } from "./stored-document-migration-Ca9BWqEF.js";
10
9
  import { A as processStartIdentity, L as writePrivateJsonAtomic, N as devReviewHome, h as TraceConfigurationError, i as isS3MockMode, j as withFileLock } from "./s3-config-CjcLyFV5.js";
11
10
  import { t as errorMessage } from "./error-message-OtiDonty.js";
12
11
  import { i as readReviewPackageVersion, n as readBuildCommit, t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.js";
13
- import { _ as reviewInstanceIdentity, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-D-2vz5gG.js";
14
- import { c as askPicksSchema, d as selectionMarkdown, l as askQuestionSchema, n as askAgentIds, r as askChoiceKinds, s as askPermissionsSchema, t as applyAskChange, u as AgentSelectionSchema } from "./thread-state-XgVKaQ3-.js";
15
- import { t as openReviewProfile } from "./profile-DnwIJvlh.js";
16
- import { c as REVIEW_APP_SESSION_ID_HEADER, d as sanitizeUiTelemetryEvent, f as cleanTelemetryText, o as reviewRequestOrigin, r as REVIEW_PERSON_HEADER, s as BUNDLE_FRAME_PATTERN, t as ASK_THREAD_ENV, u as isReportableCleanedMessage } from "./request-origin-DEQd09Db.js";
17
- import { a as defaultAskPermissions, i as askAgents, l as launchAskAgent, n as askAgentSettings, o as detectAskAgents, r as askAgentTakesMcp, t as fuzzyRank } from "./fuzzy-match-CTvayutE.js";
18
- import { a as inspectQuerySchema, i as renderInstructions, o as queryAnchor, r as instructionsQuerySchema, s as readQuerySchemas, t as authoringTools } from "./authoring-tools-B-OyXmtR.js";
19
- import { a as headlessServerOwner, c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-CesuMV6N.js";
12
+ import { _ as reviewInstanceIdentity, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-nLX2SH_v.js";
13
+ import { c as askPicksSchema, d as selectionMarkdown, l as askQuestionSchema, n as askAgentIds, r as askChoiceKinds, s as askPermissionsSchema, t as applyAskChange, u as AgentSelectionSchema } from "./thread-state-DosGpp3S.js";
14
+ import { t as openReviewProfile } from "./profile-i2n1HdIg.js";
15
+ import { c as REVIEW_APP_SESSION_ID_HEADER, d as sanitizeUiTelemetryEvent, f as cleanTelemetryText, o as reviewRequestOrigin, r as REVIEW_PERSON_HEADER, s as BUNDLE_FRAME_PATTERN, t as ASK_THREAD_ENV, u as isReportableCleanedMessage } from "./request-origin-BkrzpcVd.js";
16
+ import { a as defaultAskPermissions, i as askAgents, l as launchAskAgent, n as askAgentSettings, o as detectAskAgents, r as askAgentTakesMcp, t as fuzzyRank } from "./fuzzy-match-BMcd-rQ0.js";
17
+ import { a as inspectQuerySchema, i as renderInstructions, o as queryAnchor, r as instructionsQuerySchema, s as readQuerySchemas, t as authoringTools } from "./authoring-tools-BEGW2s0A.js";
18
+ import { a as headlessServerOwner, c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-D_4Xt3fF.js";
20
19
  import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
21
20
  import { z } from "zod";
22
21
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
@@ -2815,7 +2814,7 @@ async function anchorQuotes(before, after, read) {
2815
2814
  //#endregion
2816
2815
  //#region src/review-api/document-text.ts
2817
2816
  /** A reading view of saved content, not another document format to maintain. */
2818
- function documentText(snapshot, targetId, full = false, relations) {
2817
+ function documentText(snapshot, targetId, full = false, relations, runs) {
2819
2818
  const target = targetId === void 0 ? void 0 : elements(snapshot.document).find((item) => item.id === targetId);
2820
2819
  if (targetId !== void 0 && !target) throw new ReviewInputError("Target not found in this version.", 404);
2821
2820
  const detailed = full || target !== void 0;
@@ -2910,8 +2909,20 @@ function documentText(snapshot, targetId, full = false, relations) {
2910
2909
  for (const edge of element.edges) detail(`[${edge.id}] ${edge.from} → ${edge.to}${edge.label ? `: ${edge.label}` : ""}`);
2911
2910
  break;
2912
2911
  case "animation":
2913
- for (const [index, frame] of element.frames.entries()) detail(`Frame ${index + 1} [${frame.key}]: ${frame.title}${frame.caption ? ` — ${frame.caption}` : ""}`);
2914
- for (const [name, anchor] of Object.entries(element.code)) detail(`Code ${name}: ${anchor}`);
2912
+ for (const [index, frame] of element.frames.entries()) {
2913
+ detail(`Frame ${index + 1} [${frame.key}]: ${frame.title}${frame.caption ? ` — ${frame.caption}` : ""}`);
2914
+ if (frame.code) write(depth + 2, `Code: ${frame.code.join(", ")}`);
2915
+ if (detailed && frame.data !== void 0) write(depth + 2, `Data: ${JSON.stringify(frame.data)}`);
2916
+ }
2917
+ for (const scenario of element.scenarios ?? []) detail(`Scenario [${scenario.key}] ${scenario.label}: ${scenario.frames.join(" → ")}`);
2918
+ if (runs) {
2919
+ const run = element.id === void 0 ? void 0 : runs.get(element.id);
2920
+ write(depth + 1, run?.error ? `Script error: ${run.error}` : run ? "Ran in an open whiteboard without a script error." : "Not run yet: its script runs only where the whiteboard is open.");
2921
+ }
2922
+ for (const [name, entry] of Object.entries(element.code)) {
2923
+ const { source, label } = animationCode(entry);
2924
+ detail(`Code ${name}${label ? ` (${label})` : ""}: ${source}`);
2925
+ }
2915
2926
  if (detailed) code(depth + 1, {
2916
2927
  language: "html",
2917
2928
  text: element.html
@@ -3515,7 +3526,7 @@ function createReviewApi(store, data, open, sharing = false, capabilities = () =
3515
3526
  * board's header. */
3516
3527
  const placeOf = (id) => {
3517
3528
  if (!store.has(id)) return { siblings: [] };
3518
- const { board, parent, siblings, children } = store.place(id);
3529
+ const { board, repository, parent, siblings, children } = store.place(id);
3519
3530
  const url = board.origin?.pullRequestUrl;
3520
3531
  const state = data?.pullRequestState(url);
3521
3532
  const baseBranch = url && data?.pullRequestBaseBranch(url);
@@ -3537,6 +3548,7 @@ function createReviewApi(store, data, open, sharing = false, capabilities = () =
3537
3548
  ...state && { pullRequestState: state },
3538
3549
  ...baseBranch && { baseBranch },
3539
3550
  ...headBranch && { headBranch },
3551
+ ...repository && { repository },
3540
3552
  board: place(board),
3541
3553
  ...parent && { parent: place(parent) },
3542
3554
  siblings: siblings.map(listed),
@@ -3629,6 +3641,10 @@ function createReviewApi(store, data, open, sharing = false, capabilities = () =
3629
3641
  });
3630
3642
  app.post("/:id/person-edit", async (context) => context.json(await store.personEdit(context.req.param("id"), await readBoundedRequestJson(context.req.raw, PERSON_EDIT_MAX_BYTES))));
3631
3643
  app.post("/:id/focus", async (context) => context.json(store.focus(context.req.param("id"), await readBoundedRequestJson(context.req.raw))));
3644
+ app.post("/:id/animation-run", async (context) => context.json(store.reportAnimationRun(context.req.param("id"), {
3645
+ ...z.strictObject({ version: z.coerce.number().int().nonnegative() }).parse(context.req.query()),
3646
+ report: await readBoundedRequestJson(context.req.raw)
3647
+ })));
3632
3648
  app.post("/:id/discard", async (context) => context.json(await store.discard(context.req.param("id"))));
3633
3649
  app.get("/watch", (context) => {
3634
3650
  let input;
@@ -4478,7 +4494,7 @@ function createReviewApi(store, data, open, sharing = false, capabilities = () =
4478
4494
  const query = inspectQuerySchema.parse(context.req.query());
4479
4495
  const id = context.req.param("id");
4480
4496
  const snapshot = readReview(id, query.version);
4481
- return context.json(query.format === "text" ? documentText(snapshot, query.targetId, Boolean(query.full), relatedBoards(id)) : query.targetId !== void 0 ? inspectSnapshot(snapshot, query.targetId) : {
4497
+ return context.json(query.format === "text" ? documentText(snapshot, query.targetId, Boolean(query.full), relatedBoards(id), query.version === void 0 ? store.animationRunsOf(id) : void 0) : query.targetId !== void 0 ? inspectSnapshot(snapshot, query.targetId) : {
4482
4498
  ...query.full ? snapshot : inspectSnapshot(snapshot),
4483
4499
  ...listedRelations(store.relations(id))
4484
4500
  });
@@ -1,9 +1,8 @@
1
1
  import { f as gitAt } from "./src-Y30gweiK.js";
2
2
  import { u as parseJsonText } from "./src-X9phtB2j.js";
3
+ import { $ as comparisonKey, A as parseMarkdown, B as lensSchema, E as sourceReferences, L as UNCATEGORIZED_LENS_ID, M as checkReferences, O as markdownNodes, Q as anchorSelection, T as selectionReferences, V as lensSelections, Z as SelectionUnavailableError, _ as readsAtBoardPins, at as unionIntervals, c as documentSchema, h as pinsSchema, it as sourceAnchors, n as anchorPins, nt as resolveDiffSelection, o as boardRepositoryId, ot as ReviewInputError, q as fileLineRangeSchema, rt as selectionKey, u as elements, v as resourceReference, y as resourceReferences } from "./src-B2b8cCoI.js";
3
4
  import { s as safeStorageSegment } from "./review-home-paths-LdGS4SpR.js";
4
- import { _ as scopedCoverage, b as unionIntervals, f as sourceAnchors, h as emptyCoverage, i as anchorSelection, l as resolveDiffSelection, m as coverageSources, n as SelectionUnavailableError, o as comparisonKey, u as selectionKey, v as sourcesForFile, y as subtractIntervals } from "./lens-selection-B_LTVyTB.js";
5
- import { A as documentSchema, B as resourceReference, K as selectionReferences, L as pinsSchema, M as elements, O as boardRepositoryId, Q as UNCATEGORIZED_LENS_ID, V as resourceReferences, Y as checkReferences, at as fileLineRangeSchema, b as textIncludesQuote, c as traceSchema, ct as markdownNodes, n as migrateStoredDocument, nt as lensSelections, q as sourceReferences, r as migrateStoredLenses, s as softwareModelDataSchema, t as liftFileLenses, tt as lensSchema, u as pullRequestUrl, ut as parseMarkdown, w as anchorPins, x as textualRows, z as readsAtBoardPins } from "./stored-document-migration-CZe65mkx.js";
6
- import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
5
+ import { D as scopedCoverage, O as sourcesForFile, T as emptyCoverage, b as textIncludesQuote, c as traceSchema, k as subtractIntervals, n as migrateStoredDocument, r as migrateStoredLenses, s as softwareModelDataSchema, t as liftFileLenses, u as pullRequestUrl, w as coverageSources, x as textualRows } from "./stored-document-migration-Ca9BWqEF.js";
7
6
  import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
8
7
  import { createHash, randomUUID } from "node:crypto";
9
8
  import { z } from "zod";