@dev.fast/whiteboard 0.2.1-preview.20261006.99 → 0.2.1-preview.20261007.101

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 (37) hide show
  1. package/dist/{account-alias-DOHN1RSH.js → account-alias-DLE9XZhi.js} +1 -1
  2. package/dist/agent-cli-DdfuiyOF.js +2 -0
  3. package/dist/{agent-cli-ChOq0ZuO.js → agent-cli-d0YJQNrR.js} +6 -6
  4. package/dist/{agent-client-CPQo7iTI.js → agent-client-DoaODH6I.js} +2 -2
  5. package/dist/{authoring-tools-Cr6Kpjsx.js → authoring-tools-Bvre8hN2.js} +2 -2
  6. package/dist/build-info.json +1 -1
  7. package/dist/{cli-hVgHcdsv.js → cli-DtolttUF.js} +1 -1
  8. package/dist/{cli-runner-CMmd6o_m.js → cli-runner-CSEH_mQN.js} +11 -11
  9. package/dist/cli.js +2 -2
  10. package/dist/{client-DFoh50W3.js → client-D01H2KOV.js} +2 -2
  11. package/dist/{desktop-discovery-DBO-PM2V.js → desktop-discovery-DK2HoBy5.js} +1 -1
  12. package/dist/{headless-host-CVMDNmLU.js → headless-host-YxYKMcI5.js} +3 -2
  13. package/dist/{local-data-CxLk75rx.js → local-data-Dy8AngNb.js} +37 -84
  14. package/dist/{mcp-QeF8vkdf.js → mcp-DGKhDPMs.js} +3 -3
  15. package/dist/{process-error-telemetry-CkiiadgB.js → process-error-telemetry-DN5BpZnc.js} +345 -13
  16. package/dist/{profile-4ry2f3AM.js → profile-B6jrb2QN.js} +1 -1
  17. package/dist/profile-D8XSrJYI.js +2 -0
  18. package/dist/{request-origin-D_4QIdoN.js → request-origin-BB2TENZ5.js} +1 -1
  19. package/dist/{review-telemetry-DEFnQsQ2.js → review-telemetry-2UlsdE4D.js} +2 -2
  20. package/dist/server/desktop-host.js +14 -303
  21. package/dist/sharing/index.d.ts +6 -10
  22. package/dist/sharing/index.js +1 -1
  23. package/dist/{src-DnwdaQ2r.js → src-DHiDJQDy.js} +7 -14
  24. package/dist/{stored-document-migration-DHeMpLMb.js → stored-document-migration-T9Uj5MkN.js} +1 -1
  25. package/dist/{tool-failure-C8zB73HV.js → tool-failure-Djeeax6q.js} +1 -1
  26. package/package.json +8 -9
  27. package/src/review-api/comparison-coverage.ts +6 -11
  28. package/src/review-api/http.ts +31 -4
  29. package/src/review-api/store.ts +0 -5
  30. package/src/server/desktop-server.ts +2 -13
  31. package/src/server/diffr-config.ts +170 -128
  32. package/src/server/headless-host.ts +3 -0
  33. package/src/server/structural-diff.ts +12 -39
  34. package/src/server/test-fixtures/diffr-ui-overrides.toml +38 -0
  35. package/dist/agent-cli-DzWfZr6G.js +0 -2
  36. package/dist/profile-Bh5FIrmf.js +0 -2
  37. package/src/server/diffr-languages.ts +0 -97
@@ -1,4 +1,4 @@
1
- import { h as ReviewCliInstallStampSchema } from "./src-DnwdaQ2r.js";
1
+ import { h as ReviewCliInstallStampSchema } from "./src-DHiDJQDy.js";
2
2
  import { G as readStoreAuth, Z as StoreClient } from "./review-agent-traces-DNJFYzc8.js";
3
3
  import { A as devReviewHome, N as writeFileAtomicAsync, O as withFileLock, P as writePrivateJsonAtomic } from "./s3-config-CAxhO9u_.js";
4
4
  import { B as installHarnessHooks, C as disableTraceMachine, E as traceMachineStatus, F as listTraceRepositoryRoots, G as traceScope, I as traceRepositoryStatus, N as disableAllTraceRepositories, P as enableTraceRepository, R as AGENT_TRACE_HOOK_AGENTS, S as configureTraceMachine, T as traceMachineEnabled, V as removeAgentTraceHook, n as reviewDesktopStateDir, z as describeTraceHookOwners } from "./review-home-paths-6zZH-1c9.js";
@@ -0,0 +1,2 @@
1
+ import { n as runReviewAgentCli } from "./agent-cli-d0YJQNrR.js";
2
+ export { runReviewAgentCli };
@@ -1,11 +1,11 @@
1
1
  import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-CPQo7iTI.js";
2
+ import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-DoaODH6I.js";
3
3
  import { A as devReviewHome } from "./s3-config-CAxhO9u_.js";
4
4
  import { T as traceMachineEnabled } from "./review-home-paths-6zZH-1c9.js";
5
- import { d as selectReviewInstance, t as REVIEW_INSTANCE_ENV } from "./desktop-discovery-DBO-PM2V.js";
6
- import { n as reviewSessionAgent } from "./review-telemetry-DEFnQsQ2.js";
7
- import { n as REVIEW_VIA_HEADER, t as REVIEW_AGENT_HEADER } from "./request-origin-D_4QIdoN.js";
8
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-C8zB73HV.js";
5
+ import { d as selectReviewInstance, t as REVIEW_INSTANCE_ENV } from "./desktop-discovery-DK2HoBy5.js";
6
+ import { n as reviewSessionAgent } from "./review-telemetry-2UlsdE4D.js";
7
+ import { n as REVIEW_VIA_HEADER, t as REVIEW_AGENT_HEADER } from "./request-origin-BB2TENZ5.js";
8
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-Djeeax6q.js";
9
9
  //#region src/review-api/agent-cli.ts
10
10
  const reviewAgentCliHelp = "whiteboard api tools (one line per tool)\nwhiteboard api tools <tool-name> (its description and input schema)\nwhiteboard api <tool-name> '<json>'\nwhiteboard api <tool-name> - (read JSON from stdin)\nwhiteboard mcp (stdio MCP adapter; Whiteboard Desktop or whiteboard server start must be running)\nSelect headless state with DEV_REVIEW_SERVER_DIR or whiteboard --state-dir <path> api/mcp.\n";
11
11
  async function runReviewAgentCli(input) {
@@ -23,7 +23,7 @@ async function runReviewAgentCli(input) {
23
23
  [REVIEW_AGENT_HEADER]: reviewSessionAgent(env)
24
24
  };
25
25
  if (mode === "mcp") {
26
- const { serveReviewMcp } = await import("./mcp-QeF8vkdf.js");
26
+ const { serveReviewMcp } = await import("./mcp-DGKhDPMs.js");
27
27
  await serveReviewMcp(async (key, agentKind) => {
28
28
  const connected = await connectReviewInstance(key ? {
29
29
  ...env,
@@ -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-DnwdaQ2r.js";
2
+ import "./src-DHiDJQDy.js";
3
3
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
4
- import { d as selectReviewInstance, i as healthyReviewInstance, n as ReviewInstanceUnavailableError, u as reviewInstanceUnavailable } from "./desktop-discovery-DBO-PM2V.js";
4
+ import { d as selectReviewInstance, i as healthyReviewInstance, n as ReviewInstanceUnavailableError, u as reviewInstanceUnavailable } from "./desktop-discovery-DK2HoBy5.js";
5
5
  import { a as reviewServerIsHealthy, n as readReviewServerDiscovery, o as reviewServerStateDir, s as serverNotReady } from "./server-discovery-Dbzn3w6Z.js";
6
6
  //#region ../review-protocol/src/review-api-client.ts
7
7
  const defaultRequest = (url, init) => fetch(url, init);
@@ -1,5 +1,5 @@
1
- import { g as activityUpdateSchema, h as activityEndSchema, i as commandSchema, m as activityBeginSchema, n as uploadSchema } from "./local-data-CxLk75rx.js";
2
- import { x as publishedEditSchema, y as pathTargetSchema } from "./stored-document-migration-DHeMpLMb.js";
1
+ import { g as activityUpdateSchema, h as activityEndSchema, i as commandSchema, m as activityBeginSchema, n as uploadSchema } from "./local-data-Dy8AngNb.js";
2
+ import { x as publishedEditSchema, y as pathTargetSchema } from "./stored-document-migration-T9Uj5MkN.js";
3
3
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
4
4
  import { t as findReviewPackageRoot } from "./package-paths-B6-zxvIO.js";
5
5
  import { z } from "zod";
@@ -1 +1 @@
1
- {"version":"0.2.1-preview.20261006.99","commit":"b8634e9e5ae077e753c5bdd743c9702d31fb9efe","dirty":true,"builtAt":"2026-10-06T15:32:34.232Z"}
1
+ {"version":"0.2.1-preview.20261007.101","commit":"38a74d5fee8c32a67c5b77c2726d2104184be532","dirty":true,"builtAt":"2026-10-07T09:54:42.865Z"}
@@ -1,4 +1,4 @@
1
- import { r as connectReviewApi } from "./agent-client-CPQo7iTI.js";
1
+ import { r as connectReviewApi } from "./agent-client-DoaODH6I.js";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { z } from "zod";
4
4
  //#region src/sharing/cli.ts
@@ -1,19 +1,19 @@
1
1
  import { C as __commonJSMin, S as setLocalVcsCommandObserver, T as __toESM, w as __require } from "./src-CmdiBL20.js";
2
2
  import { c as jsonString, n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import { a as parseReviewVerbResponse } from "./src-DnwdaQ2r.js";
3
+ import { a as parseReviewVerbResponse } from "./src-DHiDJQDy.js";
4
4
  import { $ as emitJsonEvent, G as readStoreAuth, H as DEFAULT_STORE_ORIGIN, J as runStoreLogout, N as requireTraceConsent, P as resolveTraceRepositoryTarget, Q as withStoreAuthorization, V as readTraceUserConfig, X as StoreApiError, Y as runStoreWhoami, Z as StoreClient, b as selectTraceStorage, et as failWithJsonError, g as describeSelection, nt as jsonRequestedInArgv, q as runStoreLogin, tt as humanStream, v as loadS3TraceStorage } from "./review-agent-traces-DNJFYzc8.js";
5
- import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-CPQo7iTI.js";
5
+ import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-DoaODH6I.js";
6
6
  import { t as resolveReviewRoot } from "./runtime-CKiWhGrf.js";
7
7
  import { A as devReviewHome, C as s3ProfileSchema, D as processIsAlive, E as writeTraceConfigFile, S as readTraceConfigFile, T as sameS3Profile, _ as emptyTraceConfig, c as resolveS3Setup, g as currentStore, h as TraceConfigurationError, i as isS3MockMode, j as normalizeStoreOrigin, k as DEV_REVIEW_HOME_ENV, n as clearTraceEnvCache, o as readTraceEnvFile, p as traceSettingsPath, w as s3Store } from "./s3-config-CAxhO9u_.js";
8
8
  import { t as errorMessage } from "./error-message-OtiDonty.js";
9
9
  import { A as runTraceSessions, D as runTraceAllow, E as traceMachineStatus, G as traceScope, H as resolveTraceCommand, I as traceRepositoryStatus, L as HOSTED_CAPTURE_SCOPE_DESCRIPTION, M as runTraceStoreInfo, O as runTraceDeny, T as traceMachineEnabled, W as traceHomeDir, _ as runTraceRepair, b as runTraceGitHook, c as registerTraceCommands, d as runTraceList$1, f as runTracePull$1, g as runTraceInstallMachine, h as runTraceEnable, j as runTraceStoreDelete, k as runTraceOnboard, l as resolveTraceReadStorage, m as runTraceDisable, p as runTraceShow, u as runTraceBlame, v as runTraceStatus, w as readLegacyCaptureSettings, x as runTraceHook, y as runTraceSync } from "./review-home-paths-6zZH-1c9.js";
10
10
  import { i as readReviewPackageVersion, r as readBuildInfo, t as findReviewPackageRoot } from "./package-paths-B6-zxvIO.js";
11
- import { a as readDefaultReviewInstance, d as selectReviewInstance, f as writeDefaultReviewInstance, i as healthyReviewInstance, l as reviewInstanceStartHint, n as ReviewInstanceUnavailableError, o as readReviewInstances, r as clearDefaultReviewInstance, s as requireHealthyReviewDesktop, t as REVIEW_INSTANCE_ENV, u as reviewInstanceUnavailable } from "./desktop-discovery-DBO-PM2V.js";
12
- import { t as ReviewTelemetry } from "./review-telemetry-DEFnQsQ2.js";
13
- import { a as isOwnedShim, f as windowsInstallerCommand, m as connectPrompts, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount } from "./account-alias-DOHN1RSH.js";
11
+ import { a as readDefaultReviewInstance, d as selectReviewInstance, f as writeDefaultReviewInstance, i as healthyReviewInstance, l as reviewInstanceStartHint, n as ReviewInstanceUnavailableError, o as readReviewInstances, r as clearDefaultReviewInstance, s as requireHealthyReviewDesktop, t as REVIEW_INSTANCE_ENV, u as reviewInstanceUnavailable } from "./desktop-discovery-DK2HoBy5.js";
12
+ import { t as ReviewTelemetry } from "./review-telemetry-2UlsdE4D.js";
13
+ import { a as isOwnedShim, f as windowsInstallerCommand, m as connectPrompts, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount } from "./account-alias-DLE9XZhi.js";
14
14
  import { t as fuzzyRank } from "./fuzzy-match-BoAmcyak.js";
15
15
  import { n as readReviewServerDiscovery, o as reviewServerStateDir, r as readReviewServerHealth, s as serverNotReady } from "./server-discovery-Dbzn3w6Z.js";
16
- import { t as reviewAgentCliHelp } from "./agent-cli-ChOq0ZuO.js";
16
+ import { t as reviewAgentCliHelp } from "./agent-cli-d0YJQNrR.js";
17
17
  import { closeSync, existsSync, fstatSync, mkdirSync, mkdtempSync, openSync, readSync, renameSync, writeFileSync } from "node:fs";
18
18
  import { realpath } from "node:fs/promises";
19
19
  import path from "node:path";
@@ -4495,7 +4495,7 @@ async function runReviewCli(input) {
4495
4495
  process.once("SIGINT", stop);
4496
4496
  process.once("SIGTERM", stop);
4497
4497
  try {
4498
- const { runHeadlessServer } = await import("./headless-host-CVMDNmLU.js");
4498
+ const { runHeadlessServer } = await import("./headless-host-YxYKMcI5.js");
4499
4499
  await runHeadlessServer({
4500
4500
  stateDir,
4501
4501
  port,
@@ -4546,7 +4546,7 @@ async function runReviewCli(input) {
4546
4546
  if (problem) throw new Error(`Cannot tell whether a Whiteboard Desktop is using ${stateDir}: ${problem.message}`);
4547
4547
  const inUse = () => /* @__PURE__ */ new Error(`A Whiteboard server is using ${stateDir}. Stop it first, then run whiteboard server reset-id again.`);
4548
4548
  if (desktops.instances.some(({ discovery }) => [discovery.appPid, discovery.serverPid].some((pid) => processIsAlive(pid)))) throw inUse();
4549
- const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-Bh5FIrmf.js"), import("./headless-host-CVMDNmLU.js")]);
4549
+ const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-D8XSrJYI.js"), import("./headless-host-YxYKMcI5.js")]);
4550
4550
  const reset = await withHeadlessServerLock(await realpath(stateDir), async () => {
4551
4551
  const local = await openReviewProfile(stateDir, { manageWorkspaces: false });
4552
4552
  try {
@@ -4686,14 +4686,14 @@ async function runReviewCli(input) {
4686
4686
  command.showHelpAfterError(false).error("Markdown review migration is no longer supported. Ask your agent to migrate your old Whiteboard reviews.");
4687
4687
  });
4688
4688
  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) => {
4689
- const { runShareCli } = await import("./cli-hVgHcdsv.js");
4689
+ const { runShareCli } = await import("./cli-DtolttUF.js");
4690
4690
  state.exitCode = await runShareCli({
4691
4691
  ...input,
4692
4692
  ...options,
4693
4693
  env: authoringEnv()
4694
4694
  });
4695
4695
  }).command("revoke <share-id>").description("Revoke future downloads of a share"), "plain").action(async (shareId, options) => {
4696
- const { runShareCli } = await import("./cli-hVgHcdsv.js");
4696
+ const { runShareCli } = await import("./cli-DtolttUF.js");
4697
4697
  state.exitCode = await runShareCli({
4698
4698
  ...input,
4699
4699
  ...options,
@@ -4774,7 +4774,7 @@ async function runReviewCli(input) {
4774
4774
  return commands;
4775
4775
  } });
4776
4776
  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) => {
4777
- const { runReviewAgentCli } = await import("./agent-cli-DzWfZr6G.js");
4777
+ const { runReviewAgentCli } = await import("./agent-cli-DdfuiyOF.js");
4778
4778
  state.exitCode = await runReviewAgentCli({
4779
4779
  ...input,
4780
4780
  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-DnwdaQ2r.js";
3
+ import "./src-DHiDJQDy.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-CMmd6o_m.js");
20
+ const { runReviewCli } = await import("./cli-runner-CSEH_mQN.js");
21
21
  return runReviewCli({
22
22
  argv,
23
23
  cliPaths: {
@@ -1,7 +1,7 @@
1
1
  import { d as gitAt } from "./src-CmdiBL20.js";
2
2
  import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import "./src-DnwdaQ2r.js";
4
- import { B as parseMarkdown, C as resourceReferences, E as sourceReferences, K as sourceAnchors, M as lensSchema, N as lensSelections, O as checkReferences, S as resourceReference, _ as hasCodeReferences, b as pinsSchema, c as traceSchema, h as elements, l as textIncludesQuote, n as migrateStoredDocument, o as normalizedSoftwareElementSchema, p as documentSchema, r as migrateStoredLenses, s as normalizedSoftwareRelationshipSchema, t as liftFileLenses, u as anchorPins, z as markdownNodes } from "./stored-document-migration-DHeMpLMb.js";
3
+ import "./src-DHiDJQDy.js";
4
+ import { B as parseMarkdown, C as resourceReferences, E as sourceReferences, K as sourceAnchors, M as lensSchema, N as lensSelections, O as checkReferences, S as resourceReference, _ as hasCodeReferences, b as pinsSchema, c as traceSchema, h as elements, l as textIncludesQuote, n as migrateStoredDocument, o as normalizedSoftwareElementSchema, p as documentSchema, r as migrateStoredLenses, s as normalizedSoftwareRelationshipSchema, t as liftFileLenses, u as anchorPins, z as markdownNodes } from "./stored-document-migration-T9Uj5MkN.js";
5
5
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
6
6
  import { createHash, randomUUID } from "node:crypto";
7
7
  import { z } from "zod";
@@ -1,5 +1,5 @@
1
1
  import { a as jsonNumber, n as isJsonObject, s as jsonProperty, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import { n as parseReviewDesktopDiscovery } from "./src-DnwdaQ2r.js";
2
+ import { n as parseReviewDesktopDiscovery } from "./src-DHiDJQDy.js";
3
3
  import { a as reviewInstancesDir, o as reviewLegacyDiscoveryPath, r as reviewDevInstanceKey, t as reviewDefaultInstancePath } from "./review-home-paths-6zZH-1c9.js";
4
4
  import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
5
5
  import path from "node:path";
@@ -1,8 +1,8 @@
1
1
  import { p as isObjectValue } from "./src-X9phtB2j.js";
2
2
  import { O as withFileLock, P as writePrivateJsonAtomic } from "./s3-config-CAxhO9u_.js";
3
3
  import "./review-home-paths-6zZH-1c9.js";
4
- import { t as openReviewProfile } from "./profile-4ry2f3AM.js";
5
- import { i as createWhiteboardCore, l as createNodeRequestListener, n as installProcessErrorTelemetry, p as GlobalReviewDesktopVerbRelay, t as drainServerCrashReport } from "./process-error-telemetry-CkiiadgB.js";
4
+ import { t as openReviewProfile } from "./profile-B6jrb2QN.js";
5
+ import { i as createWhiteboardCore, l as createNodeRequestListener, m as migrateDiffrConfig, n as installProcessErrorTelemetry, p as GlobalReviewDesktopVerbRelay, t as drainServerCrashReport } from "./process-error-telemetry-DN5BpZnc.js";
6
6
  import { i as reviewServerDiscoveryPath, t as headlessServerLockPath } from "./server-discovery-Dbzn3w6Z.js";
7
7
  import { randomBytes, randomUUID } from "node:crypto";
8
8
  import { mkdir, realpath, rm } from "node:fs/promises";
@@ -34,6 +34,7 @@ function withHeadlessServerLock(stateDir, operation) {
34
34
  }
35
35
  async function serve(input) {
36
36
  if (input.signal.aborted) return;
37
+ await migrateDiffrConfig(input.signal);
37
38
  if (input.telemetry) await drainServerCrashReport(input.telemetry);
38
39
  const local = await openReviewProfile(input.stateDir, { manageWorkspaces: false });
39
40
  const discovery = {
@@ -1,25 +1,35 @@
1
1
  import { _ as readFileAtCommit, b as resolveRevision, c as diffTrees, f as gitCommonDir, g as parseGitRemote, h as listTrackedFilesAtCommit, i as diff, l as diffWorkingTree, m as listCommitRange, n as createBlobBatchReader, o as diffFileSummariesTrees, p as jjRevisionIsConflicted, r as detectLocalVcs, s as diffFileSummariesWorkingTree, t as LocalVcsToolsMissingError, u as git, v as resolveRepoContext, y as resolveRepoContextSync } from "./src-CmdiBL20.js";
2
2
  import { c as jsonString, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import { _ as SCRATCHPAD_REVIEW_ID, b as structuralChangeCounts, g as ReviewSelectedDiffSchema, m as ReviewApiSelectionSourceSchema, y as decodeStructuralDiffEvent } from "./src-DnwdaQ2r.js";
4
- import { $ as unionIntervals, A as applyLensEdit, C as resourceReferences, D as summarizeEdit, E as sourceReferences, F as checkSourcePath, I as fileLineRangeSchema, K as sourceAnchors, L as requireVisibleSource, N as lensSelections, O as checkReferences, P as SourceRangeError, Q as subtractIntervals, R as sliceSourceRange, S as resourceReference, X as intersectIntervals, Y as emptyCoverage, a as defineSoftwareMap, b as pinsSchema, c as traceSchema, d as applyEdit, et as updateCoverage, f as assignFreshIds, g as explicitPins, h as elements, i as SoftwareModelValidationError, j as lensEditSchema, l as textIncludesQuote, m as editSchema, n as migrateStoredDocument, p as documentSchema, q as coverageSchema, r as migrateStoredLenses, t as liftFileLenses, u as anchorPins, v as isUnit, w as reviewTargetSchema } from "./stored-document-migration-DHeMpLMb.js";
3
+ import { _ as SCRATCHPAD_REVIEW_ID, b as structuralChangeCounts, g as ReviewSelectedDiffSchema, m as ReviewApiSelectionSourceSchema, y as decodeStructuralDiffEvent } from "./src-DHiDJQDy.js";
4
+ import { $ as unionIntervals, A as applyLensEdit, C as resourceReferences, D as summarizeEdit, E as sourceReferences, F as checkSourcePath, I as fileLineRangeSchema, K as sourceAnchors, L as requireVisibleSource, N as lensSelections, O as checkReferences, P as SourceRangeError, Q as subtractIntervals, R as sliceSourceRange, S as resourceReference, X as intersectIntervals, Y as emptyCoverage, a as defineSoftwareMap, b as pinsSchema, c as traceSchema, d as applyEdit, et as updateCoverage, f as assignFreshIds, g as explicitPins, h as elements, i as SoftwareModelValidationError, j as lensEditSchema, l as textIncludesQuote, m as editSchema, n as migrateStoredDocument, p as documentSchema, q as coverageSchema, r as migrateStoredLenses, t as liftFileLenses, u as anchorPins, v as isUnit, w as reviewTargetSchema } from "./stored-document-migration-T9Uj5MkN.js";
5
5
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
6
6
  import { D as processIsAlive, O as withFileLock, P as writePrivateJsonAtomic } from "./s3-config-CAxhO9u_.js";
7
7
  import { t as errorMessage } from "./error-message-OtiDonty.js";
8
8
  import { s as safeStorageSegment } from "./review-home-paths-6zZH-1c9.js";
9
- import { t as findReviewPackageRoot } from "./package-paths-B6-zxvIO.js";
10
9
  import { r as isMissingFileError } from "./fs-utils-BMPLt0cr.js";
11
10
  import { createRequire } from "node:module";
12
11
  import crypto, { createHash, randomUUID } from "node:crypto";
13
12
  import { z } from "zod";
14
- import { existsSync, lstatSync, readFileSync, realpathSync, rmSync, watch } from "node:fs";
13
+ import { existsSync, realpathSync, rmSync, watch } from "node:fs";
15
14
  import * as fs$1 from "node:fs/promises";
16
15
  import { lstat, mkdir, readFile, readdir, realpath, rm, stat, writeFile } from "node:fs/promises";
17
16
  import path, { dirname, isAbsolute, relative, resolve, sep } from "node:path";
18
- import os from "node:os";
19
17
  import { execFile, spawn } from "node:child_process";
20
18
  import { promisify } from "node:util";
21
19
  import { DatabaseSync } from "node:sqlite";
22
20
  import { createInterface } from "node:readline";
21
+ //#region ../../node_modules/@dev.fast/diffr/dist/binary.js
22
+ /** The diffr executable from the installed platform package, if npm installed one for this machine. */
23
+ function diffrBinaryPath() {
24
+ const name = process.platform === "win32" ? "diffr.exe" : "diffr";
25
+ try {
26
+ const self = createRequire(import.meta.url).resolve("@dev.fast/diffr/package.json");
27
+ return createRequire(self).resolve(`@dev.fast/diffr-${process.platform}-${process.arch}/${name}`);
28
+ } catch {
29
+ return;
30
+ }
31
+ }
32
+ //#endregion
23
33
  //#region ../review-protocol/src/source-alignment.ts
24
34
  /** The 0-based, half-open line span a region touches. An end at column 0 does not touch its end line. */
25
35
  function alignmentRegionLines(region) {
@@ -28,13 +38,13 @@ function alignmentRegionLines(region) {
28
38
  end: region.end.column === 0 ? region.end.line : region.end.line + 1
29
39
  };
30
40
  }
31
- function alignmentLeaves(regions) {
41
+ function alignmentLeaves(root) {
32
42
  const leaves = [];
33
43
  const walk = (region) => {
34
44
  if (region.kind === "leaf") leaves.push(region);
35
45
  else for (const child of region.children) walk(child);
36
46
  };
37
- for (const region of regions ?? []) walk(region);
47
+ if (root) walk(root);
38
48
  return leaves;
39
49
  }
40
50
  /** Monaco keeps a final empty line after a newline; the wire need not mention it. */
@@ -48,8 +58,8 @@ function monacoLineCount(source) {
48
58
  * lines Monaco keeps.
49
59
  */
50
60
  function structuralRows(diff) {
51
- const lhsLeaves = alignmentLeaves(diff.lhs?.regions);
52
- const rhsLeaves = alignmentLeaves(diff.rhs?.regions);
61
+ const lhsLeaves = alignmentLeaves(diff.lhs?.root);
62
+ const rhsLeaves = alignmentLeaves(diff.rhs?.root);
53
63
  const leftCount = monacoLineCount(diff.lhs);
54
64
  const rightCount = monacoLineCount(diff.rhs);
55
65
  const rows = [];
@@ -381,65 +391,14 @@ function isInsideDirectory(filePath, directory) {
381
391
  return Boolean(relative) && !relative.startsWith("..") && !path.isAbsolute(relative);
382
392
  }
383
393
  //#endregion
384
- //#region src/server/diffr-languages.ts
385
- const exec$1 = promisify(execFile);
386
- const versionSchema = z.object({ version: z.string() });
387
- const stampSchema = z.object({
388
- version: z.string(),
389
- full: z.boolean()
390
- });
391
- const pending = /* @__PURE__ */ new Map();
392
- function configuration(root) {
393
- const installer = path.join(root, "bin/diffr-package/bin/fetch.mjs");
394
- const { version } = versionSchema.parse(JSON.parse(readFileSync(path.join(root, "bin/diffr-package/package.json"), "utf8")));
395
- const directory = path.join(process.env.XDG_CACHE_HOME || path.join(os.homedir(), ".cache"), "diffr", version, `${process.platform}-${process.arch}`, "full");
396
- return {
397
- installer,
398
- version,
399
- directory,
400
- binary: path.join(directory, process.platform === "win32" ? "diffr.exe" : "diffr")
401
- };
402
- }
403
- function installedFullDiffr(root) {
404
- try {
405
- const { binary, directory, version } = configuration(root);
406
- const stat = lstatSync(binary);
407
- const stamp = stampSchema.parse(JSON.parse(readFileSync(path.join(directory, "diffr.stamp.json"), "utf8")));
408
- if (stat.isFile() && (process.platform === "win32" || stat.mode & 73) && stamp.full && stamp.version === version) return binary;
409
- } catch {}
410
- }
411
- function installFullDiffr(root = findReviewPackageRoot(import.meta.url)) {
412
- if (process.env.REVIEW_DIFFR_BINARY) return Promise.reject(/* @__PURE__ */ new Error("An explicitly selected diffr executable is in use. Install its full edition separately."));
413
- const { installer, directory } = configuration(root);
414
- const current = pending.get(directory);
415
- if (current) return current;
416
- const task = exec$1(process.execPath, [
417
- installer,
418
- "--full",
419
- "--required",
420
- "--into",
421
- directory
422
- ], {
423
- env: {
424
- ...process.env,
425
- ELECTRON_RUN_AS_NODE: "1"
426
- },
427
- timeout: 18e4
428
- }).then(() => {}).finally(() => pending.delete(directory));
429
- pending.set(directory, task);
430
- return task;
431
- }
432
- //#endregion
433
394
  //#region src/server/structural-diff.ts
434
- function diffrExecutable(packageRoot = findReviewPackageRoot(import.meta.url)) {
435
- if (process.env.REVIEW_DIFFR_BINARY) return process.env.REVIEW_DIFFR_BINARY;
436
- const full = installedFullDiffr(packageRoot);
437
- if (full) return full;
438
- const bundled = path.join(packageRoot, "bin", process.platform === "win32" ? "diffr.exe" : "diffr");
439
- return existsSync(bundled) ? bundled : "diffr";
395
+ function diffrExecutable() {
396
+ const executable = diffrBinaryPath();
397
+ if (!executable) throw diffrMissingError();
398
+ return executable;
440
399
  }
441
400
  function diffrMissingError() {
442
- return /* @__PURE__ */ new Error(`Cannot find diffr at ${diffrExecutable()}. Whiteboard Desktop bundles it at bin/diffr under its runtime; in a checkout, run \`pnpm --filter @dev.fast/whiteboard ensure:diffr\` or install diffr on PATH, or set REVIEW_DIFFR_BINARY to its executable.`);
401
+ return /* @__PURE__ */ new Error("The bundled diffr executable is missing. Reinstall Whiteboard.");
443
402
  }
444
403
  /**
445
404
  * Stream validated diffr records. File errors and aborted completion are data;
@@ -448,13 +407,13 @@ function diffrMissingError() {
448
407
  */
449
408
  async function* structuralDiff(input) {
450
409
  input.signal.throwIfAborted();
410
+ const executable = diffrExecutable();
451
411
  const comparison = input.comparison;
452
412
  const args = [
453
413
  "--repo",
454
414
  input.repositoryPath,
455
415
  "--format",
456
- "ndjson",
457
- "--stream-annotations"
416
+ "ndjson"
458
417
  ];
459
418
  switch (comparison.kind) {
460
419
  case "worktree":
@@ -469,8 +428,8 @@ async function* structuralDiff(input) {
469
428
  const idleAbort = new AbortController();
470
429
  const idle = setTimeout(() => idleAbort.abort(), 12e4);
471
430
  const signal = AbortSignal.any([idleAbort.signal, input.signal]);
472
- console.info(`[Review] structural diff: ${diffrExecutable()} ${args.join(" ")}`);
473
- const child = spawn(diffrExecutable(), args, {
431
+ console.info(`[Review] structural diff: ${executable} ${args.join(" ")}`);
432
+ const child = spawn(executable, args, {
474
433
  cwd: input.repositoryPath,
475
434
  stdio: [
476
435
  "ignore",
@@ -496,7 +455,6 @@ async function* structuralDiff(input) {
496
455
  let completed = false;
497
456
  let aborted;
498
457
  let failed = 0;
499
- let annotationFailed = false;
500
458
  const lines = createInterface({
501
459
  input: child.stdout,
502
460
  crlfDelay: Infinity
@@ -509,14 +467,13 @@ async function* structuralDiff(input) {
509
467
  const event = decodeStructuralDiffEvent(line);
510
468
  if (completed) throw new Error("diffr emitted data after completion.");
511
469
  if (!started) {
512
- if (event.type !== "start" || event.version !== 4) throw new Error("Unsupported diffr stream protocol.");
470
+ if (event.type !== "start" || event.version !== 3) throw new Error("Unsupported diffr stream protocol.");
513
471
  started = true;
514
472
  } else if (event.type === "complete") {
515
473
  completed = true;
516
474
  failed = event.failed;
517
475
  aborted = event.aborted;
518
- } else if (event.type === "annotations") annotationFailed ||= event.error !== void 0;
519
- else if (event.type !== "file") throw new Error(`Unexpected diffr event: ${event.type}`);
476
+ } else if (event.type !== "file") throw new Error(`Unexpected diffr event: ${event.type}`);
520
477
  yield event;
521
478
  }
522
479
  if (!completed) {
@@ -525,7 +482,7 @@ async function* structuralDiff(input) {
525
482
  throw new Error("diffr stream ended before completion.");
526
483
  }
527
484
  const code = await exited;
528
- if (code !== 0 && !(code === 2 && (failed > 0 || annotationFailed || aborted !== void 0))) throw exitError(code);
485
+ if (code !== 0 && !(code === 2 && (failed > 0 || aborted !== void 0))) throw exitError(code);
529
486
  } finally {
530
487
  clearTimeout(idle);
531
488
  lines.close();
@@ -1101,7 +1058,7 @@ async function comparisonCoverage(data, reviewId, pins, mode, signal, publish) {
1101
1058
  previousPath,
1102
1059
  fingerprint,
1103
1060
  changed: diff.type === "text" ? diff.structural_changes : emptyCoverage(),
1104
- folded: foldedChanges(event.visibility, diff),
1061
+ folded: foldedChanges(diff),
1105
1062
  viewed: emptyCoverage()
1106
1063
  });
1107
1064
  publish?.({
@@ -1128,20 +1085,17 @@ async function comparisonCoverage(data, reviewId, pins, mode, signal, publish) {
1128
1085
  * the lines, not just the counts, are known. A paired leaf contributes its
1129
1086
  * changed spans' lines; an unpaired leaf, all of its lines.
1130
1087
  */
1131
- function foldedChanges(visibility, diff) {
1088
+ function foldedChanges(diff) {
1132
1089
  if (diff.type !== "text") return emptyCoverage();
1133
1090
  const all = diff.structural_changes;
1134
- if (visibility?.collapsed) return {
1135
- base: unionIntervals(all.base),
1136
- head: unionIntervals(all.head)
1137
- };
1138
1091
  const side = (changed, source, other) => {
1092
+ if (source?.root.visibility?.collapsed) return unionIntervals(changed);
1139
1093
  const paired = /* @__PURE__ */ new Set();
1140
1094
  const pair = (region) => {
1141
1095
  if (region.kind === "leaf") paired.add(region.alignment_id);
1142
1096
  else region.children.forEach(pair);
1143
1097
  };
1144
- other?.regions?.forEach(pair);
1098
+ if (other) pair(other.root);
1145
1099
  const hidden = [], visible = [];
1146
1100
  const collect = (region, folded) => {
1147
1101
  folded ||= region.visibility?.collapsed === true;
@@ -1153,7 +1107,7 @@ function foldedChanges(visibility, diff) {
1153
1107
  if (paired.has(region.alignment_id)) for (const span of region.changed ?? []) lines.push([span.line, span.line + 1]);
1154
1108
  else lines.push([region.start.line, region.end.column === 0 ? region.end.line : region.end.line + 1]);
1155
1109
  };
1156
- for (const region of source?.regions ?? []) collect(region, false);
1110
+ if (source) collect(source.root, false);
1157
1111
  return subtractIntervals(intersectIntervals(changed, hidden), visible);
1158
1112
  };
1159
1113
  return {
@@ -2800,7 +2754,6 @@ var ReviewStore = class {
2800
2754
  ...lensTarget && { type: lensTarget.type },
2801
2755
  ...applied?.children && { children: applied.children }
2802
2756
  };
2803
- if (snapshot.staleSources?.length) warnings.push("Some authored source ranges changed. Update their references before presenting this review.");
2804
2757
  if (warnings.length) result.warnings = warnings;
2805
2758
  this.commitCommand(result, () => {
2806
2759
  this.db.prepare("INSERT INTO reviews(id,version,next_id) VALUES(?,?,?) ON CONFLICT(id) DO UPDATE SET version=excluded.version,next_id=excluded.next_id").run(id, snapshot.version, nextId);
@@ -4488,4 +4441,4 @@ async function readWorkspace(file) {
4488
4441
  }
4489
4442
  }
4490
4443
  //#endregion
4491
- export { invalidateStructuralComparisons as _, inspectSnapshot as a, installFullDiffr as b, askAgentIds as c, askQuestionSchema as d, AgentSelectionSchema as f, activityUpdateSchema as g, activityEndSchema as h, commandSchema as i, askChoiceKinds as l, activityBeginSchema as m, uploadSchema as n, initializeReviewStoreSchema as o, selectionMarkdown as p, SCRATCHPAD_ID as r, applyAskChange as s, openLocalReviewStore as t, askPicksSchema as u, diffrExecutable as v, diffrMissingError as y };
4444
+ export { invalidateStructuralComparisons as _, inspectSnapshot as a, askAgentIds as c, askQuestionSchema as d, AgentSelectionSchema as f, activityUpdateSchema as g, activityEndSchema as h, commandSchema as i, askChoiceKinds as l, activityBeginSchema as m, uploadSchema as n, initializeReviewStoreSchema as o, selectionMarkdown as p, SCRATCHPAD_ID as r, applyAskChange as s, openLocalReviewStore as t, askPicksSchema as u, diffrExecutable as v, diffrMissingError as y };
@@ -1,7 +1,7 @@
1
- import { a as toolResultText, s as ReviewApiError } from "./agent-client-CPQo7iTI.js";
1
+ import { a as toolResultText, s as ReviewApiError } from "./agent-client-DoaODH6I.js";
2
2
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
3
- import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-Cr6Kpjsx.js";
4
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-C8zB73HV.js";
3
+ import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-Bvre8hN2.js";
4
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-Djeeax6q.js";
5
5
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
6
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
7
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";