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

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 (43) hide show
  1. package/dist/{account-alias-DtN9zBzt.js → account-alias-Bw3PT3Qo.js} +3 -3
  2. package/dist/agent-cli-B8KBHuh_.js +2 -0
  3. package/dist/{agent-cli-D2WEQwul.js → agent-cli-kHRrwO4n.js} +6 -6
  4. package/dist/{agent-client-CXXjD60Q.js → agent-client-CMacGbMp.js} +3 -3
  5. package/dist/{authoring-tools-BEGW2s0A.js → authoring-tools-CiLy46kh.js} +1 -1
  6. package/dist/{background-server-Cw7lddwb.js → background-server-BLNHbksB.js} +1 -1
  7. package/dist/{background-server-D_4Xt3fF.js → background-server-eZWXoVcI.js} +2 -2
  8. package/dist/build-info.json +1 -1
  9. package/dist/{cli-SDWXOZPY.js → cli-Bxmiqutp.js} +35 -2
  10. package/dist/{cli-runner-DaPGJWRf.js → cli-runner-DQPuu7kJ.js} +26 -17
  11. package/dist/cli.js +2 -2
  12. package/dist/{fuzzy-match-BMcd-rQ0.js → fuzzy-match-DZjeOaPY.js} +2 -2
  13. package/dist/{headless-host-CMDr4BpH.js → headless-host-B4r0s1ks.js} +1 -1
  14. package/dist/{headless-host-DDYA2wwn.js → headless-host-Dl2KZ9IT.js} +88 -26
  15. package/dist/{import-LsDP99A9.js → import-YAIU6rB0.js} +9 -3
  16. package/dist/{local-data-G2I-77FX.js → local-data-C58vzLZR.js} +3 -3
  17. package/dist/{mcp-tqD6Fwvy.js → mcp-COYWiGVn.js} +3 -3
  18. package/dist/{profile-i2n1HdIg.js → profile--BYIjPkc.js} +1 -1
  19. package/dist/profile-BjcXi-oH.js +2 -0
  20. package/dist/{remote-attach-BsOO_ER4.js → remote-attach-C1prLjmj.js} +3 -3
  21. package/dist/{remote-language-server-AamAHhw_.js → remote-language-server-z3rdHcLL.js} +1 -1
  22. package/dist/{remote-uninstall-BH2ovwP1.js → remote-uninstall-B3Slwor1.js} +3 -3
  23. package/dist/{request-origin-BkrzpcVd.js → request-origin-B3_XI2VA.js} +21 -2
  24. package/dist/{review-app-launcher-1tcH84u6.js → review-app-launcher-BZEbDKuK.js} +2 -2
  25. package/dist/{review-telemetry-B6mxAOXA.js → review-telemetry-x8u-9EZb.js} +2 -2
  26. package/dist/server/desktop-host.js +10 -10
  27. package/dist/{server-discovery-nLX2SH_v.js → server-discovery-WmuFl2S3.js} +1 -1
  28. package/dist/sharing/index.d.ts +2 -0
  29. package/dist/sharing/index.js +1 -1
  30. package/dist/{src-Coec7jLU.js → src-DLWol7GZ.js} +7 -0
  31. package/dist/{stored-document-migration-Ca9BWqEF.js → stored-document-migration-iwIQ4l5G.js} +1 -1
  32. package/dist/{thread-state-DosGpp3S.js → thread-state-B7L1mpN_.js} +1 -1
  33. package/dist/{tool-failure-CwTgI76j.js → tool-failure-RLR8m9hq.js} +3 -3
  34. package/package.json +10 -10
  35. package/src/cli-runner.ts +29 -0
  36. package/src/sharing/cli.ts +59 -0
  37. package/src/sharing/export.ts +11 -0
  38. package/src/sharing/file.ts +52 -0
  39. package/src/sharing/host.ts +131 -37
  40. package/src/sharing/import.ts +1 -1
  41. package/src/ui-telemetry-events.ts +17 -0
  42. package/dist/agent-cli-m3uWrslh.js +0 -2
  43. package/dist/profile-Bw0hDDNd.js +0 -2
@@ -1,10 +1,10 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { E as ReviewCliInstallStampSchema } from "./src-Coec7jLU.js";
2
+ import { E as ReviewCliInstallStampSchema } from "./src-DLWol7GZ.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 { 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";
6
+ import { f as isDirectory, p as isFile } from "./thread-state-B7L1mpN_.js";
7
+ import { c as findExecutable, s as executableCommand } from "./fuzzy-match-DZjeOaPY.js";
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";
@@ -0,0 +1,2 @@
1
+ import { n as runReviewAgentCli } from "./agent-cli-kHRrwO4n.js";
2
+ export { runReviewAgentCli };
@@ -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-CXXjD60Q.js";
3
+ import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-CMacGbMp.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-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";
6
+ import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-WmuFl2S3.js";
7
+ import { n as reviewSessionAgent } from "./review-telemetry-x8u-9EZb.js";
8
+ import { a as REVIEW_VIA_HEADER, i as REVIEW_THREAD_HEADER, n as REVIEW_AGENT_HEADER, t as ASK_THREAD_ENV } from "./request-origin-B3_XI2VA.js";
9
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-RLR8m9hq.js";
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-tqD6Fwvy.js");
46
+ const { serveReviewMcp } = await import("./mcp-COYWiGVn.js");
47
47
  exitOnInstallUpdate(input.stderr);
48
48
  await serveReviewMcp(async (key, agentKind) => {
49
49
  const connected = await connectReviewInstance(key ? {
@@ -1,7 +1,7 @@
1
1
  import { d as isBooleanValue, f as isNumberValue, m as isStringValue, u as parseJsonText } from "./src-X9phtB2j.js";
2
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";
3
+ import "./src-DLWol7GZ.js";
4
+ import { b as selectReviewInstance, c as reviewServerStateDir, d as ReviewInstanceUnavailableError, i as readReviewServerDiscovery, l as serverNotReady, m as healthyReviewInstance, s as reviewServerIsHealthy, y as reviewInstanceUnavailable } from "./server-discovery-WmuFl2S3.js";
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-Cw7lddwb.js");
262
+ const { ensureServerWithoutDesktop } = await import("./background-server-BLNHbksB.js");
263
263
  const server = await ensureServerWithoutDesktop({
264
264
  selection,
265
265
  env,
@@ -1,6 +1,6 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
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";
3
+ import { n as uploadSchema, r as commandSchema } from "./local-data-C58vzLZR.js";
4
4
  import { t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.js";
5
5
  import { z } from "zod";
6
6
  import { readFile } from "node:fs/promises";
@@ -1,2 +1,2 @@
1
- import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-D_4Xt3fF.js";
1
+ import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-eZWXoVcI.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-nLX2SH_v.js";
5
- import { t as desktopApplicationInstalled } from "./review-app-launcher-1tcH84u6.js";
4
+ import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-WmuFl2S3.js";
5
+ import { t as desktopApplicationInstalled } from "./review-app-launcher-BZEbDKuK.js";
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.20261030.143","commit":"6900e30267289f6b6d3d16ecf8b7f626ff0c355f","dirty":true,"builtAt":"2026-10-30T04:40:00.211Z"}
1
+ {"version":"0.4.1-preview.20261101.145","commit":"d52f162d92fa13b7e200741599424bfe33c7a1eb","dirty":true,"builtAt":"2026-11-01T17:51:30.437Z"}
@@ -1,6 +1,8 @@
1
- import { r as connectReviewApi } from "./agent-client-CXXjD60Q.js";
1
+ import { r as connectReviewApi } from "./agent-client-CMacGbMp.js";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { z } from "zod";
4
+ import { mkdir, writeFile } from "node:fs/promises";
5
+ import path from "node:path";
4
6
  //#region src/sharing/cli.ts
5
7
  const resultSchema = z.strictObject({
6
8
  shareId: z.uuid(),
@@ -43,5 +45,36 @@ async function runShareCli(input) {
43
45
  return 1;
44
46
  }
45
47
  }
48
+ const exportSchema = z.strictObject({
49
+ filename: z.string().min(1),
50
+ text: z.string()
51
+ });
52
+ async function runExportCli(input) {
53
+ try {
54
+ if (!input.review) throw new Error("Use whiteboard export --review <id>.");
55
+ const client = await connectReviewApi(input.env);
56
+ const result = exportSchema.parse(await client.post("/sharing/export", {
57
+ reviewId: input.review,
58
+ version: input.version === void 0 ? void 0 : z.number().int().nonnegative().parse(Number(input.version))
59
+ }));
60
+ if (input.out === "-") {
61
+ input.stdout.write(result.text);
62
+ return 0;
63
+ }
64
+ const file = path.resolve(input.cwd, input.out ?? result.filename);
65
+ await mkdir(path.dirname(file), { recursive: true });
66
+ await writeFile(file, result.text);
67
+ input.stdout.write(input.json ? JSON.stringify({ path: file }) + "\n" : file + "\n");
68
+ return 0;
69
+ } catch (error) {
70
+ const message = error instanceof Error ? error.message : "Export failed.";
71
+ if (input.json) input.stdout.write(JSON.stringify({ error: {
72
+ code: "export_failed",
73
+ message
74
+ } }) + "\n");
75
+ input.stderr.write(message + "\n");
76
+ return 1;
77
+ }
78
+ }
46
79
  //#endregion
47
- export { runShareCli };
80
+ export { runExportCli, runShareCli };
@@ -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-Coec7jLU.js";
3
+ import { S as REVIEW_REMOTE_ATTACH_END, b as REVIEW_REMOTE_AGENT_IDS, h as REVIEW_CLI_INSTALL_TARGET_LABELS, l as boardTitle, x as REVIEW_REMOTE_ATTACH_BEGIN } from "./src-DLWol7GZ.js";
4
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-CXXjD60Q.js";
5
+ import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-CMacGbMp.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-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";
10
+ import { a as readReviewServerHealth, b as selectReviewInstance, c as reviewServerStateDir, d as ReviewInstanceUnavailableError, f as clearDefaultReviewInstance, g as requireHealthyReviewDesktop, h as readDefaultReviewInstance, i as readReviewServerDiscovery, l as serverNotReady, m as healthyReviewInstance, p as desktopUsesHome, t as DESKTOP_TAKEOVER_SIGNAL, u as REVIEW_INSTANCE_ENV, x as writeDefaultReviewInstance, y as reviewInstanceUnavailable } from "./server-discovery-WmuFl2S3.js";
11
+ import { t as ReviewTelemetry } from "./review-telemetry-x8u-9EZb.js";
12
+ import { t as fuzzyRank } from "./fuzzy-match-DZjeOaPY.js";
13
+ import { _ as isInstallTarget, a as isOwnedShim, f as windowsInstallerCommand, g as ALL_INSTALL_TARGETS, h as detectConnectAgents, m as connectAgent, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount, v as connectPrompts } from "./account-alias-Bw3PT3Qo.js";
14
+ import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-BZEbDKuK.js";
15
+ import { t as reviewAgentCliHelp } from "./agent-cli-kHRrwO4n.js";
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-Cw7lddwb.js");
4336
+ const { ensureBackgroundServer } = await import("./background-server-BLNHbksB.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-CMDr4BpH.js");
4358
+ const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-B4r0s1ks.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-Cw7lddwb.js");
4395
+ const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-BLNHbksB.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-Bw0hDDNd.js"), import("./headless-host-CMDr4BpH.js")]);
4423
+ const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-BjcXi-oH.js"), import("./headless-host-B4r0s1ks.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-BsOO_ER4.js");
4445
+ const { remoteAttach } = await import("./remote-attach-C1prLjmj.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-BH2ovwP1.js");
4487
+ const { remoteUninstall } = await import("./remote-uninstall-B3Slwor1.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-SDWXOZPY.js");
4709
+ const { runShareCli } = await import("./cli-Bxmiqutp.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-SDWXOZPY.js");
4716
+ const { runShareCli } = await import("./cli-Bxmiqutp.js");
4717
4717
  state.exitCode = await runShareCli({
4718
4718
  ...input,
4719
4719
  ...options,
@@ -4721,6 +4721,15 @@ async function runReviewCli(input) {
4721
4721
  env: authoringEnv()
4722
4722
  });
4723
4723
  });
4724
+ configureJsonOutput(program.command("export").description("Write a review snapshot as a .whiteboard file"), "plain").option("--review <id>", "review ID").option("--version <number>", "Saved version to export").option("--out <path>", "File to write, or - for stdout; defaults to <title>.whiteboard here").action(async (options) => {
4725
+ const { runExportCli } = await import("./cli-Bxmiqutp.js");
4726
+ state.exitCode = await runExportCli({
4727
+ ...input,
4728
+ ...options,
4729
+ cwd,
4730
+ env: authoringEnv()
4731
+ });
4732
+ });
4724
4733
  configureJsonOutput(program.command("login").description("Log in to Whiteboard with GitHub"), "plain").option("--origin <url>", "Whiteboard service origin", DEFAULT_STORE_ORIGIN).option("--traces", "Also authorize GitHub repositories for hosted traces").option("--no-browser", "Print the URL instead of opening a browser").action(async (options) => {
4725
4734
  state.exitCode = await runtime.runStoreLogin({
4726
4735
  origin: options.origin,
@@ -4794,7 +4803,7 @@ async function runReviewCli(input) {
4794
4803
  return commands;
4795
4804
  } });
4796
4805
  for (const [name, description] of [["api", "Call a JSON review authoring tool on the running server"], ["mcp", "Serve the JSON review authoring tools over stdio MCP"]]) configureOutput(program.command(name).description(description).argument("[args...]", "tool name and JSON input").allowUnknownOption().allowExcessArguments().helpOption(false).passThroughOptions().addHelpText("after", `\n${reviewAgentCliHelp}`), "plain").action(async (args) => {
4797
- const { runReviewAgentCli } = await import("./agent-cli-m3uWrslh.js");
4806
+ const { runReviewAgentCli } = await import("./agent-cli-B8KBHuh_.js");
4798
4807
  state.exitCode = await runReviewAgentCli({
4799
4808
  ...input,
4800
4809
  env: authoringEnv(),
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as jsonNumber, c as jsonString, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import "./src-Coec7jLU.js";
3
+ import "./src-DLWol7GZ.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-DaPGJWRf.js");
20
+ const { runReviewCli } = await import("./cli-runner-DQPuu7kJ.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-DosGpp3S.js";
4
- import { t as ASK_THREAD_ENV } from "./request-origin-BkrzpcVd.js";
3
+ import { n as askAgentIds } from "./thread-state-B7L1mpN_.js";
4
+ import { t as ASK_THREAD_ENV } from "./request-origin-B3_XI2VA.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-DDYA2wwn.js";
1
+ import { i as withHeadlessServerLock, n as runHeadlessServer, r as takeOverServerHome, t as HeadlessServerBusyError } from "./headless-host-Dl2KZ9IT.js";
2
2
  export { HeadlessServerBusyError, runHeadlessServer, takeOverServerHome, withHeadlessServerLock };
@@ -1,21 +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-LsDP99A9.js";
3
+ import { _ as readBoundedStream, a as forgetSharedCommits, b as shareBundleSchema, c as ShareClient, d as legacyModeSchema, f as lensReport, g as StreamLimitError, h as uncategorizedReport, l as exportShare, m as reviewProgress, n as needsRepository, o as readShareRepository, p as progressUpdateSchema, r as shareKey, s as ShareAuthError, t as importShare, u as validateShareSources, x as shareIdSchema, y as parseShareLink } from "./import-YAIU6rB0.js";
4
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";
5
+ import { c as invalidateStructuralComparisons, d as readGitHubPullRequests, i as inspectSnapshot, l as diffrExecutable, r as commandSchema, u as diffrMissingError } from "./local-data-C58vzLZR.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-DLWol7GZ.js";
7
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";
8
- import { D as scopedCoverage, f as sourceBranchName, l as pullRequestKey, p as pullRequestProvider } from "./stored-document-migration-Ca9BWqEF.js";
8
+ import { D as scopedCoverage, f as sourceBranchName, l as pullRequestKey, p as pullRequestProvider } from "./stored-document-migration-iwIQ4l5G.js";
9
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";
10
10
  import { t as errorMessage } from "./error-message-OtiDonty.js";
11
11
  import { i as readReviewPackageVersion, n as readBuildCommit, t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.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";
12
+ import { _ as reviewInstanceIdentity, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-WmuFl2S3.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-B7L1mpN_.js";
14
+ import { t as openReviewProfile } from "./profile--BYIjPkc.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-B3_XI2VA.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-DZjeOaPY.js";
17
+ import { a as inspectQuerySchema, i as renderInstructions, o as queryAnchor, r as instructionsQuerySchema, s as readQuerySchemas, t as authoringTools } from "./authoring-tools-CiLy46kh.js";
18
+ import { a as headlessServerOwner, c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-eZWXoVcI.js";
19
19
  import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
20
20
  import { z } from "zod";
21
21
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
@@ -2601,12 +2601,48 @@ async function readSharingAuth(env = process.env) {
2601
2601
  };
2602
2602
  }
2603
2603
  //#endregion
2604
+ //#region src/slug.ts
2605
+ /** Lowercase ASCII slug: runs of anything but `a-z0-9` become one `-`, outer
2606
+ * dashes go. Empty input, or input with no letters or digits, yields `""`;
2607
+ * callers choose their own fallback (`"section"`, `"diagram"`, `"database"`).
2608
+ * This is the rule sequence and lens ids were already published with, so it
2609
+ * must not change. */
2610
+ function slugify(text) {
2611
+ return text.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
2612
+ }
2613
+ //#endregion
2614
+ //#region src/sharing/file.ts
2615
+ const WHITEBOARD_FILE_EXTENSION = ".whiteboard";
2616
+ const headerSchema = z.looseObject({ format: z.string() });
2617
+ function whiteboardFileName(title) {
2618
+ return `${slugify(title) || "untitled"}${WHITEBOARD_FILE_EXTENSION}`;
2619
+ }
2620
+ function whiteboardFileText(bundle) {
2621
+ return JSON.stringify(bundle, null, 2) + "\n";
2622
+ }
2623
+ function parseWhiteboardFile(text) {
2624
+ let parsed;
2625
+ try {
2626
+ parsed = JSON.parse(text);
2627
+ } catch {
2628
+ parsed = void 0;
2629
+ }
2630
+ const header = headerSchema.safeParse(parsed);
2631
+ if (!header.success) throw new ReviewInputError("This is not a Whiteboard file.", 400);
2632
+ if (header.data.format !== "review-share/2") throw new ReviewInputError("This file needs a different Whiteboard version.", 400);
2633
+ return shareBundleSchema.parse(parsed);
2634
+ }
2635
+ function whiteboardFileKey(text) {
2636
+ return createHash("sha256").update("whiteboard-file\0").update(text).digest("hex");
2637
+ }
2638
+ //#endregion
2604
2639
  //#region src/sharing/host.ts
2605
2640
  const publishSchema = z.strictObject({
2606
2641
  reviewId: z.string().min(1),
2607
2642
  version: z.number().int().nonnegative().optional(),
2608
2643
  requestId: z.uuid().optional()
2609
2644
  });
2645
+ const importSchema = z.union([z.strictObject({ url: z.string().max(2048) }), z.strictObject({ path: z.string().min(1).max(4096) })]);
2610
2646
  /** Mounted behind local host authentication. Account credentials never enter the renderer. */
2611
2647
  function mountSharingHost(app, store, data, options = {}) {
2612
2648
  const startLogin = options.login ?? runStoreLogin;
@@ -2677,22 +2713,17 @@ function mountSharingHost(app, store, data, options = {}) {
2677
2713
  ...status.stage === "ready" && { title: store.read(reviewId).title }
2678
2714
  });
2679
2715
  });
2680
- app.post("/sharing/import", async (context) => {
2681
- const { url } = z.strictObject({ url: z.string().max(2048) }).parse(await readBoundedRequestJson(context.req.raw));
2682
- const parsed = parseShareLink(url);
2683
- const account = await readStoreAuth();
2684
- if (parsed.origin !== DEFAULT_STORE_ORIGIN && parsed.origin !== account?.origin) throw new ReviewInputError("This share uses an untrusted service. Sign in to that service before opening its links.", 400);
2685
- const id = shareKey(parsed.origin, parsed.capability);
2716
+ const startImport = (id, initial, load) => {
2686
2717
  const known = imports.get(id)?.stage;
2687
2718
  if (!known || known === "ready" || known === "error") {
2688
2719
  const copy = store.copyOf(id);
2689
2720
  const status = copy ? {
2690
2721
  stage: "ready",
2691
2722
  reviewId: copy
2692
- } : { stage: "downloading" };
2723
+ } : { stage: initial };
2693
2724
  imports.set(id, status);
2694
2725
  if (!copy) importing = importing.then(async () => {
2695
- const { bundle, attribution } = await new ShareClient(parsed.origin).download(parsed.capability);
2726
+ const { bundle, attribution } = await load();
2696
2727
  status.reviewId = await importShare({
2697
2728
  store,
2698
2729
  data,
@@ -2709,32 +2740,63 @@ function mountSharingHost(app, store, data, options = {}) {
2709
2740
  });
2710
2741
  }
2711
2742
  const { reviewId: _reviewId, ...status } = imports.get(id);
2712
- return context.json({
2743
+ return {
2713
2744
  reviewId: id,
2714
2745
  ...status
2715
- }, 202);
2746
+ };
2747
+ };
2748
+ app.post("/sharing/import", async (context) => {
2749
+ const input = importSchema.parse(await readBoundedRequestJson(context.req.raw));
2750
+ if ("path" in input) {
2751
+ if (!path.isAbsolute(input.path)) throw new ReviewInputError("Use an absolute file path.", 400);
2752
+ const text = await readFile(input.path, "utf8").catch(() => {
2753
+ throw new ReviewInputError(`Could not read ${path.basename(input.path)}. Check that the file still exists and Whiteboard can open it.`, 400);
2754
+ });
2755
+ return context.json(startImport(whiteboardFileKey(text), "reading", async () => ({ bundle: parseWhiteboardFile(text) })), 202);
2756
+ }
2757
+ const parsed = parseShareLink(input.url);
2758
+ const account = await readStoreAuth();
2759
+ if (parsed.origin !== DEFAULT_STORE_ORIGIN && parsed.origin !== account?.origin) throw new ReviewInputError("This share uses an untrusted service. Sign in to that service before opening its links.", 400);
2760
+ return context.json(startImport(shareKey(parsed.origin, parsed.capability), "downloading", () => new ShareClient(parsed.origin).download(parsed.capability)), 202);
2716
2761
  });
2717
2762
  }
2718
2763
  /** Publishing needs only an authored store, never Desktop or recipient workspaces. */
2719
2764
  function mountSharingPublisher(app, store, data, options = {}) {
2720
- app.post("/sharing/publish", async (context) => {
2721
- const input = publishSchema.parse(await readBoundedRequestJson(context.req.raw));
2765
+ const shareable = (input) => {
2722
2766
  const snapshot = store.read(input.reviewId, input.version);
2723
2767
  if (snapshot.target?.kind === "worktree") throw new ReviewInputError("Pin this review to commits before sharing it.");
2724
2768
  validateShareSources(snapshot);
2725
- const account = await readSharingAuth();
2726
- if (!account) throw new ReviewInputError("Set DEV_REVIEW_SHARE_TOKEN for CI, or run whiteboard login before sharing.", 409);
2769
+ return snapshot;
2770
+ };
2771
+ const shareBundle = async (snapshot) => {
2727
2772
  const repositoryId = snapshot.pins?.repositoryId ?? snapshot.target?.repositoryId;
2728
2773
  const root = repositoryId ? store.repositoryPath(repositoryId) : void 0;
2729
2774
  const repository = root ? (options.readRepository ?? readShareRepository)(root).catch(() => void 0) : void 0;
2730
2775
  const bundle = await exportShare({
2731
2776
  store,
2732
2777
  data,
2733
- reviewId: input.reviewId,
2778
+ reviewId: snapshot.reviewId,
2734
2779
  version: snapshot.version
2735
2780
  });
2736
2781
  const verified = await repository;
2737
2782
  if (verified) bundle.repository = verified;
2783
+ return bundle;
2784
+ };
2785
+ app.post("/sharing/export", async (context) => {
2786
+ const snapshot = shareable(publishSchema.parse(await readBoundedRequestJson(context.req.raw)));
2787
+ const bundle = await shareBundle(snapshot);
2788
+ if (!bundle.repository && needsRepository(bundle, snapshot)) throw new ReviewInputError("Exporting pinned code needs a GitHub remote the file's reader can fetch from.");
2789
+ return context.json({
2790
+ filename: whiteboardFileName(snapshot.title),
2791
+ text: whiteboardFileText(bundle)
2792
+ });
2793
+ });
2794
+ app.post("/sharing/publish", async (context) => {
2795
+ const input = publishSchema.parse(await readBoundedRequestJson(context.req.raw));
2796
+ const snapshot = shareable(input);
2797
+ const account = await readSharingAuth();
2798
+ if (!account) throw new ReviewInputError("Set DEV_REVIEW_SHARE_TOKEN for CI, or run whiteboard login before sharing.", 409);
2799
+ const bundle = await shareBundle(snapshot);
2738
2800
  try {
2739
2801
  const result = await new ShareClient(account.origin, account.token, options.fetch).create(bundle, input.requestId ?? randomUUID());
2740
2802
  const url = new URL(result.url);
@@ -2,7 +2,7 @@ import { f as gitAt } from "./src-Y30gweiK.js";
2
2
  import { u as parseJsonText } from "./src-X9phtB2j.js";
3
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";
4
4
  import { s as safeStorageSegment } from "./review-home-paths-LdGS4SpR.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";
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-iwIQ4l5G.js";
6
6
  import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
7
7
  import { createHash, randomUUID } from "node:crypto";
8
8
  import { z } from "zod";
@@ -58,7 +58,7 @@ const shareBundleSchema = z.strictObject({
58
58
  format: z.literal(SHARE_FORMAT),
59
59
  reviewId: z.string().min(1).max(256),
60
60
  version: z.number().int().nonnegative(),
61
- title: z.string().min(1).max(4096),
61
+ title: z.string().max(4096),
62
62
  /** Validated against the document schema by the reader. */
63
63
  snapshot: z.record(z.string(), z.unknown()),
64
64
  images: z.record(z.string(), z.strictObject({ png: z.base64() })),
@@ -426,6 +426,12 @@ async function exportShare(input) {
426
426
  const repositoryId = boardRepositoryId(stored);
427
427
  const { target, staleSources: _staleSources, sourceUnavailable: _sourceUnavailable, lastEdit: _lastEdit, trashedAt: _trashedAt, personEdit: _personEdit, ...snapshot } = stored;
428
428
  if (target?.kind === "worktree") throw new ReviewInputError("Pin this review to commits before sharing it.");
429
+ const pullRequestUrl = snapshot.origin?.pullRequestUrl;
430
+ const baseBranch = pullRequestUrl && !snapshot.origin?.baseBranch && (snapshot.origin?.pullRequestBaseBranch ?? input.data.pullRequestBaseBranch(pullRequestUrl));
431
+ if (baseBranch) snapshot.origin = {
432
+ ...snapshot.origin,
433
+ baseBranch
434
+ };
429
435
  documentSchema.parse(snapshot.document);
430
436
  checkReferences(snapshot.document);
431
437
  validateShareSources(snapshot);
@@ -1044,4 +1050,4 @@ async function shareRepository({ store, data, ...git }, cloneUrl, pins, commits,
1044
1050
  return repositoryId;
1045
1051
  }
1046
1052
  //#endregion
1047
- export { parseShareLink as _, readShareRepository as a, exportShare as c, lensReport as d, progressUpdateSchema as f, readBoundedStream as g, StreamLimitError as h, forgetSharedCommits as i, validateShareSources as l, uncategorizedReport as m, shareKey as n, ShareAuthError as o, reviewProgress as p, validateShareBundle as r, ShareClient as s, importShare as t, legacyModeSchema as u, shareIdSchema as v };
1053
+ export { readBoundedStream as _, forgetSharedCommits as a, shareBundleSchema as b, ShareClient as c, legacyModeSchema as d, lensReport as f, StreamLimitError as g, uncategorizedReport as h, validateShareBundle as i, exportShare as l, reviewProgress as m, needsRepository as n, readShareRepository as o, progressUpdateSchema as p, shareKey as r, ShareAuthError as s, importShare as t, validateShareSources as u, SHARE_FORMAT as v, shareIdSchema as x, parseShareLink as y };
@@ -1,12 +1,12 @@
1
1
  import { S as splitGitPatchFiles, T as runVcsSync, _ as listTrackedFilesAtCommit, a as diff, b as resolveRepoContext, c as diffFileSummariesWorkingTree, d as git, f as gitAt, g as listCommitRange, h as jjRevisionIsConflicted, i as detectLocalVcs, l as diffTrees, m as gitCommonDirSync, n as createBlobBatchReader, p as gitCommonDir, s as diffFileSummariesTrees, t as LocalVcsToolsMissingError, u as diffWorkingTree, v as parseGitRemote, w as runVcs, x as resolveRevision, y as readFileAtCommit } from "./src-Y30gweiK.js";
2
2
  import { c as jsonString, m as isStringValue, n as isJsonObject, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
3
  import { A as parseMarkdown, B as lensSchema, D as summarizeEdit, E as sourceReferences, G as SourceRangeError, J as requireVisibleSource, K as checkSourcePath, M as checkReferences, O as markdownNodes, P as documentAdvice, R as applyLensEdit, S as respellEditLinks, V as lensSelections, Y as sliceSourceRange, a as boardLinks, at as unionIntervals, b as respellCommitLinks, c as documentSchema, ct as activityEndSchema, d as explicitPins, h as pinsSchema, i as assignMissingIds, it as sourceAnchors, k as markdownText, l as editSchema, lt as activityUpdateSchema, m as pinnedRepositoryIds, n as anchorPins, o as boardRepositoryId, ot as ReviewInputError, p as pinDocumentReferences, q as fileLineRangeSchema, r as applyEdit, s as commitLinkCommits, st as activityBeginSchema, t as adoptFlowUnits, tt as parseAnchor, u as elements, ut as focusSchema, v as resourceReference, w as reviewTargetSchema, x as respellDocumentLinks, y as resourceReferences, z as lensEditSchema } from "./src-B2b8cCoI.js";
4
- import { F as applyStructuralUpdate, I as decodeStructuralDiffEvent, L as structuralChangeCounts, c as boardIconKind, l as boardTitle } from "./src-Coec7jLU.js";
4
+ import { F as applyStructuralUpdate, I as decodeStructuralDiffEvent, L as structuralChangeCounts, c as boardIconKind, l as boardTitle } from "./src-DLWol7GZ.js";
5
5
  import { s as safeStorageSegment } from "./review-home-paths-LdGS4SpR.js";
6
- import { A as updateCoverage, C as coverageSchema, E as intersectIntervals, S as parseUnifiedPatch, T as emptyCoverage, _ as fetchPullRequest, a as SoftwareModelValidationError, b as textIncludesQuote, c as traceSchema, d as setPullRequest, f as sourceBranchName, g as defaultPullRequestDeps, h as GitHubRefusedRead, i as readStoredDocument, k as subtractIntervals, l as pullRequestKey, m as resolvePullRequest, n as migrateStoredDocument, o as defineSoftwareMap, r as migrateStoredLenses, u as pullRequestUrl, v as remoteUrls, x as textualRows, y as azureRepositoryOf } from "./stored-document-migration-Ca9BWqEF.js";
6
+ import { A as updateCoverage, C as coverageSchema, E as intersectIntervals, S as parseUnifiedPatch, T as emptyCoverage, _ as fetchPullRequest, a as SoftwareModelValidationError, b as textIncludesQuote, c as traceSchema, d as setPullRequest, f as sourceBranchName, g as defaultPullRequestDeps, h as GitHubRefusedRead, i as readStoredDocument, k as subtractIntervals, l as pullRequestKey, m as resolvePullRequest, n as migrateStoredDocument, o as defineSoftwareMap, r as migrateStoredLenses, u as pullRequestUrl, v as remoteUrls, x as textualRows, y as azureRepositoryOf } from "./stored-document-migration-iwIQ4l5G.js";
7
7
  import { A as processStartIdentity, L as writePrivateJsonAtomic, O as pidReused, j as withFileLock, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
8
8
  import { t as errorMessage } from "./error-message-OtiDonty.js";
9
- import { a as askHistoryEntrySchema, i as askEntrySchema, m as isMissingFileError, o as askOfferSchema, s as askPermissionsSchema } from "./thread-state-DosGpp3S.js";
9
+ import { a as askHistoryEntrySchema, i as askEntrySchema, m as isMissingFileError, o as askOfferSchema, s as askPermissionsSchema } from "./thread-state-B7L1mpN_.js";
10
10
  import { createRequire } from "node:module";
11
11
  import crypto, { createHash, randomUUID } from "node:crypto";
12
12
  import { z } from "zod";
@@ -1,8 +1,8 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
2
  import { ot as ReviewInputError } from "./src-B2b8cCoI.js";
3
- import { a as toolResultText, s as ReviewApiError, t as ToolText } from "./agent-client-CXXjD60Q.js";
4
- import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-BEGW2s0A.js";
5
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-CwTgI76j.js";
3
+ import { a as toolResultText, s as ReviewApiError, t as ToolText } from "./agent-client-CMacGbMp.js";
4
+ import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-CiLy46kh.js";
5
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-RLR8m9hq.js";
6
6
  import { Server } from "@modelcontextprotocol/server";
7
7
  import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
8
8
  //#region src/review-api/mcp-client-agent.ts
@@ -1,4 +1,4 @@
1
- import { a as projectOfCheckout, f as CheckoutGroups, o as groupCheckoutsAhead, s as initializeReviewStoreSchema, t as openLocalReviewStore } from "./local-data-G2I-77FX.js";
1
+ import { a as projectOfCheckout, f as CheckoutGroups, o as groupCheckoutsAhead, s as initializeReviewStoreSchema, t as openLocalReviewStore } from "./local-data-C58vzLZR.js";
2
2
  import "./review-home-paths-LdGS4SpR.js";
3
3
  import { j as withFileLock } from "./s3-config-CjcLyFV5.js";
4
4
  import { access, mkdir } from "node:fs/promises";
@@ -0,0 +1,2 @@
1
+ import { t as openReviewProfile } from "./profile--BYIjPkc.js";
2
+ export { openReviewProfile };
@@ -1,7 +1,7 @@
1
1
  import { i as readReviewPackageVersion } from "./package-paths-Cg6fnaGp.js";
2
- import { a as readReviewServerHealth, l as serverNotReady } from "./server-discovery-nLX2SH_v.js";
3
- import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-D_4Xt3fF.js";
4
- import { t as ensureRemoteLanguageServer } from "./remote-language-server-AamAHhw_.js";
2
+ import { a as readReviewServerHealth, l as serverNotReady } from "./server-discovery-WmuFl2S3.js";
3
+ import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-eZWXoVcI.js";
4
+ import { t as ensureRemoteLanguageServer } from "./remote-language-server-z3rdHcLL.js";
5
5
  import path from "node:path";
6
6
  import { spawn } from "node:child_process";
7
7
  import { gt, valid } from "semver";
@@ -1,7 +1,7 @@
1
1
  import "./review-home-paths-LdGS4SpR.js";
2
2
  import { A as processStartIdentity, j as withFileLock } from "./s3-config-CjcLyFV5.js";
3
3
  import { t as findReviewPackageRoot } from "./package-paths-Cg6fnaGp.js";
4
- import { n as cliSpawn, s as spawnDetached } from "./background-server-D_4Xt3fF.js";
4
+ import { n as cliSpawn, s as spawnDetached } from "./background-server-eZWXoVcI.js";
5
5
  import { r as remoteServerPaths, t as ensureRemoteExtensions } from "./remote-extensions-MUUgbLJn.js";
6
6
  import { randomBytes } from "node:crypto";
7
7
  import { z } from "zod";