@dev.fast/whiteboard 0.3.4-preview.20261019.125 → 0.3.4-preview.20261019.126

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 (42) hide show
  1. package/dist/{account-alias-ClRtWF_-.js → account-alias-B5-HYi1D.js} +12 -7
  2. package/dist/{agent-cli-C6AM9dml.js → agent-cli-CohHf6Ua.js} +9 -9
  3. package/dist/agent-cli-_YyMIMRY.js +2 -0
  4. package/dist/{agent-client-G4KxB8zB.js → agent-client-Dtc-Kn_w.js} +2 -2
  5. package/dist/{authoring-tools-Dfo0uOSj.js → authoring-tools-B7KU04f7.js} +2 -2
  6. package/dist/{background-server-BF_lLFxY.js → background-server-C03RKxKS.js} +5 -5
  7. package/dist/{background-server-DJfYWRoN.js → background-server-CB9C4uoc.js} +1 -1
  8. package/dist/build-info.json +1 -1
  9. package/dist/{cli-CqOiiTW_.js → cli-CJaEb7zC.js} +1 -1
  10. package/dist/{cli-runner-D8CsXff4.js → cli-runner-DGDIqh3V.js} +20 -20
  11. package/dist/cli.js +3 -2
  12. package/dist/{fuzzy-match-DH9lZivo.js → fuzzy-match-BmVJJm9I.js} +3 -3
  13. package/dist/{headless-host-CeNnXxiL.js → headless-host-DRtjf9WA.js} +1 -1
  14. package/dist/{headless-host-C4bhVPZx.js → headless-host-XhL1X4vX.js} +20 -16
  15. package/dist/{local-data-BdqqCYUD.js → local-data-Cpl4ENbJ.js} +2 -2
  16. package/dist/{mcp-B2mvDEhC.js → mcp-ovmiUE_x.js} +3 -3
  17. package/dist/{package-paths-Cm1tR8c4.js → package-paths-BWxO-UEL.js} +1 -1
  18. package/dist/{profile-DcigfSms.js → profile-BadSkCkI.js} +3 -3
  19. package/dist/profile-DJvkBJNQ.js +2 -0
  20. package/dist/{remote-attach-DGwVRmY5.js → remote-attach-Dd-YobM6.js} +4 -4
  21. package/dist/{remote-extensions-CferWwM9.js → remote-extensions-CNXwqK0D.js} +3 -3
  22. package/dist/{remote-extensions-D8W2IgKH.js → remote-extensions-VP-kfq0C.js} +1 -1
  23. package/dist/{remote-language-server-By-rEosC.js → remote-language-server-BXk87KCr.js} +5 -5
  24. package/dist/{remote-uninstall-DgHnDAFH.js → remote-uninstall-DuOzsvaD.js} +5 -5
  25. package/dist/{request-origin-DDmfnytX.js → request-origin-B9qCPiVB.js} +7 -2
  26. package/dist/{review-app-launcher-CG3TFZEx.js → review-app-launcher-C7el2Uoy.js} +1 -1
  27. package/dist/{review-home-paths-D1JVitqN.js → review-home-paths-D8AoCdd2.js} +4 -4
  28. package/dist/{review-telemetry-Myzm7o6-.js → review-telemetry-BsoRMC2w.js} +4 -4
  29. package/dist/{s3-DtJFWC0G.js → s3-CsG2EWED.js} +1 -1
  30. package/dist/{s3-config-BTO12tCC.js → s3-config-CjcLyFV5.js} +4 -2
  31. package/dist/{s3-config-CSy3fx8H.js → s3-config-zz4GWh2T.js} +1 -1
  32. package/dist/server/desktop-host.js +11 -11
  33. package/dist/{server-discovery-Bwa_6Tsj.js → server-discovery-CKjw3-6h.js} +5 -4
  34. package/dist/{tool-failure-C9J3r7KD.js → tool-failure-DvI-gys2.js} +1 -1
  35. package/package.json +2 -2
  36. package/src/cli-install.ts +13 -2
  37. package/src/cli.ts +4 -1
  38. package/src/server/headless-host.ts +21 -12
  39. package/src/server-discovery.ts +4 -2
  40. package/src/ui-telemetry-events.ts +8 -2
  41. package/dist/agent-cli-DKpWo-4F.js +0 -2
  42. package/dist/profile-DthRnZ7x.js +0 -2
@@ -1,10 +1,10 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
2
  import { E as ReviewCliInstallStampSchema } from "./src-BiWNbcF_.js";
3
- import { C as disableTraceMachine, E as traceMachineStatus, G as listTraceRepositoryRoots, K as traceRepositoryStatus, Q as removeAgentTraceHook, S as configureTraceMachine, T as traceMachineEnabled, U as disableAllTraceRepositories, W as enableTraceRepository, X as describeTraceHookOwners, Y as AGENT_TRACE_HOOK_AGENTS, Z as installHarnessHooks, at as readStoreAuth, n as reviewDesktopStateDir, nt as traceScope, ut as StoreClient } from "./review-home-paths-D1JVitqN.js";
4
- import { I as writeFileAtomicAsync, L as writePrivateJsonAtomic, N as devReviewHome, j as withFileLock } from "./s3-config-BTO12tCC.js";
5
- import { i as readReviewPackageVersion } from "./package-paths-Cm1tR8c4.js";
3
+ import { C as disableTraceMachine, E as traceMachineStatus, G as listTraceRepositoryRoots, K as traceRepositoryStatus, Q as removeAgentTraceHook, S as configureTraceMachine, T as traceMachineEnabled, U as disableAllTraceRepositories, W as enableTraceRepository, X as describeTraceHookOwners, Y as AGENT_TRACE_HOOK_AGENTS, Z as installHarnessHooks, at as readStoreAuth, n as reviewDesktopStateDir, nt as traceScope, ut as StoreClient } from "./review-home-paths-D8AoCdd2.js";
4
+ import { I as writeFileAtomicAsync, L as writePrivateJsonAtomic, N as devReviewHome, j as withFileLock } from "./s3-config-CjcLyFV5.js";
5
+ import { i as readReviewPackageVersion } from "./package-paths-BWxO-UEL.js";
6
6
  import { n as isFile, t as isDirectory } from "./fs-utils-BMPLt0cr.js";
7
- import { c as findExecutable, s as executableCommand } from "./fuzzy-match-DH9lZivo.js";
7
+ import { c as findExecutable, s as executableCommand } from "./fuzzy-match-BmVJJm9I.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";
@@ -1093,9 +1093,9 @@ async function isOwnedShim(shimPath) {
1093
1093
  * (ELECTRON_RUN_AS_NODE) — the exact runtime the server uses. System Node is
1094
1094
  * the last resort and gets a clear version check instead of a cryptic crash.
1095
1095
  */
1096
- async function writePathShim(shimPath, cliPath, runtimePath, devHome) {
1096
+ async function writePathShim(shimPath, cliPath, runtimePath, devHome, previewHome = devHome) {
1097
1097
  if (process.platform === "win32") {
1098
- await writeFileAtomicAsync(shimPath, windowsCliShim(cliPath, runtimePath ?? process.execPath, devHome), { replaceSymlink: true });
1098
+ await writeFileAtomicAsync(shimPath, windowsCliShim(cliPath, runtimePath ?? process.execPath, devHome === previewHome ? devHome : void 0), { replaceSymlink: true });
1099
1099
  shimPath = shimPath.replace(/\.cmd$/i, "");
1100
1100
  }
1101
1101
  const source = `#!/bin/sh
@@ -1103,6 +1103,8 @@ async function writePathShim(shimPath, cliPath, runtimePath, devHome) {
1103
1103
  FALLBACK_CLI=${shSingleQuote(cliPath)}
1104
1104
  FALLBACK_RUNTIME=${shSingleQuote(runtimePath ?? "")}
1105
1105
  DEFAULT_HOME=${shSingleQuote(devHome)}
1106
+ channel="\${DEV_FAST_REVIEW_CHANNEL:-\${DEV_REVIEW_INSTANCE:-}}"
1107
+ [ "$channel" = preview ] && DEFAULT_HOME=${shSingleQuote(previewHome)}
1106
1108
  export DEV_REVIEW_HOME="\${DEV_REVIEW_HOME:-$DEFAULT_HOME}"
1107
1109
  DESKTOP="$DEV_REVIEW_HOME/review-desktop"
1108
1110
 
@@ -1203,7 +1205,10 @@ async function installReviewCommand(input) {
1203
1205
  output: `[skip] kept the existing whiteboard command at ${shimPath}\n`
1204
1206
  };
1205
1207
  const shadowingCommand = await resolvePathCommand("whiteboard", shimPath, env);
1206
- await writePathShim(shimPath, input.cliPath, input.cliRuntimePath, devReviewHome(env, homeDir));
1208
+ await writePathShim(shimPath, input.cliPath, input.cliRuntimePath, devReviewHome({ DEV_REVIEW_HOME: env.DEV_REVIEW_HOME }, homeDir), devReviewHome({
1209
+ DEV_REVIEW_HOME: env.DEV_REVIEW_HOME,
1210
+ DEV_REVIEW_INSTANCE: "preview"
1211
+ }, homeDir));
1207
1212
  if (await traceMachineEnabled({
1208
1213
  homeDir,
1209
1214
  env
@@ -1,12 +1,12 @@
1
1
  import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import { T as traceMachineEnabled } from "./review-home-paths-D1JVitqN.js";
3
- import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-G4KxB8zB.js";
4
- import { N as devReviewHome } from "./s3-config-BTO12tCC.js";
5
- import { n as readBuildCommit } from "./package-paths-Cm1tR8c4.js";
6
- import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-Bwa_6Tsj.js";
7
- import { n as reviewSessionAgent } from "./review-telemetry-Myzm7o6-.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-DDmfnytX.js";
9
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-C9J3r7KD.js";
2
+ import { T as traceMachineEnabled } from "./review-home-paths-D8AoCdd2.js";
3
+ import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-Dtc-Kn_w.js";
4
+ import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
5
+ import { n as readBuildCommit } from "./package-paths-BWxO-UEL.js";
6
+ import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-CKjw3-6h.js";
7
+ import { n as reviewSessionAgent } from "./review-telemetry-BsoRMC2w.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-B9qCPiVB.js";
9
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-DvI-gys2.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-B2mvDEhC.js");
46
+ const { serveReviewMcp } = await import("./mcp-ovmiUE_x.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-CohHf6Ua.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
2
  import "./src-BiWNbcF_.js";
3
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-Bwa_6Tsj.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-CKjw3-6h.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-DJfYWRoN.js");
262
+ const { ensureServerWithoutDesktop } = await import("./background-server-CB9C4uoc.js");
263
263
  const server = await ensureServerWithoutDesktop({
264
264
  selection,
265
265
  env,
@@ -1,8 +1,8 @@
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-BdqqCYUD.js";
2
+ import { c as activityBeginSchema, l as activityEndSchema, n as uploadSchema, r as commandSchema, u as activityUpdateSchema } from "./local-data-Cpl4ENbJ.js";
3
3
  import { C as pathTargetSchema, D as publishedEditSchema } from "./stored-document-migration-dFbewRTG.js";
4
4
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
5
- import { t as findReviewPackageRoot } from "./package-paths-Cm1tR8c4.js";
5
+ import { t as findReviewPackageRoot } from "./package-paths-BWxO-UEL.js";
6
6
  import { z } from "zod";
7
7
  import { readFile } from "node:fs/promises";
8
8
  import path from "node:path";
@@ -1,8 +1,8 @@
1
- import "./review-home-paths-D1JVitqN.js";
2
- import { D as liveLockOwner, k as processIsAlive } from "./s3-config-BTO12tCC.js";
3
- import { t as findReviewPackageRoot } from "./package-paths-Cm1tR8c4.js";
4
- import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-Bwa_6Tsj.js";
5
- import { t as desktopApplicationInstalled } from "./review-app-launcher-CG3TFZEx.js";
1
+ import "./review-home-paths-D8AoCdd2.js";
2
+ import { D as liveLockOwner, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
3
+ import { t as findReviewPackageRoot } from "./package-paths-BWxO-UEL.js";
4
+ import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-CKjw3-6h.js";
5
+ import { t as desktopApplicationInstalled } from "./review-app-launcher-C7el2Uoy.js";
6
6
  import { mkdir, open, readFile, realpath, stat } from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import { spawn } from "node:child_process";
@@ -1,2 +1,2 @@
1
- import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-BF_lLFxY.js";
1
+ import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-C03RKxKS.js";
2
2
  export { ensureBackgroundServer, ensureServerWithoutDesktop, headlessServerOwner, stopBackgroundServer };
@@ -1 +1 @@
1
- {"version":"0.3.4-preview.20261019.125","commit":"fc51298c9ea617b6624dcbf7416793fa22451afc","dirty":true,"builtAt":"2026-10-19T17:04:54.635Z"}
1
+ {"version":"0.3.4-preview.20261019.126","commit":"dfbb058ea293f9629d5380bcfc27af97484a52f7","dirty":true,"builtAt":"2026-10-19T18:51:08.463Z"}
@@ -1,4 +1,4 @@
1
- import { r as connectReviewApi } from "./agent-client-G4KxB8zB.js";
1
+ import { r as connectReviewApi } from "./agent-client-Dtc-Kn_w.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 { A as __require, O as setLocalVcsCommandObserver, j as __toESM, k as __commonJSMin } from "./src-WPaQn75m.js";
2
2
  import { c as jsonString, n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
3
  import { b as REVIEW_REMOTE_ATTACH_BEGIN, h as REVIEW_CLI_INSTALL_TARGET_LABELS, l as boardTitle, x as REVIEW_REMOTE_ATTACH_END, y as REVIEW_REMOTE_AGENT_IDS } from "./src-BiWNbcF_.js";
4
- import { $ as resolveTraceCommand, A as runTraceDeny, E as traceMachineStatus, F as describeSelection, H as resolveTraceRepositoryTarget, J as HOSTED_CAPTURE_SCOPE_DESCRIPTION, K as traceRepositoryStatus, L as loadS3TraceStorage, M as runTraceSessions, N as runTraceStoreDelete, P as runTraceStoreInfo, T as traceMachineEnabled, V as requireTraceConsent, _ as runTraceRepair, at as readStoreAuth, b as runTraceGitHook, c as registerTraceCommands, ct as runStoreWhoami, d as runTraceList$1, dt as withStoreAuthorization, f as runTracePull$1, ft as emitJsonEvent, g as runTraceInstallMachine, h as runTraceEnable, ht as jsonRequestedInArgv, j as runTraceOnboard, k as runTraceAllow, l as resolveTraceReadStorage, lt as StoreApiError, m as runTraceDisable, mt as humanStream, nt as traceScope, ot as runStoreLogin, p as runTraceShow, pt as failWithJsonError, q as readTraceUserConfig, rt as DEFAULT_STORE_ORIGIN, st as runStoreLogout, tt as traceHomeDir, u as runTraceBlame, ut as StoreClient, v as runTraceStatus, w as readLegacyCaptureSettings, x as runTraceHook, y as runTraceSync, z as selectTraceStorage } from "./review-home-paths-D1JVitqN.js";
5
- import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-G4KxB8zB.js";
4
+ import { $ as resolveTraceCommand, A as runTraceDeny, E as traceMachineStatus, F as describeSelection, H as resolveTraceRepositoryTarget, J as HOSTED_CAPTURE_SCOPE_DESCRIPTION, K as traceRepositoryStatus, L as loadS3TraceStorage, M as runTraceSessions, N as runTraceStoreDelete, P as runTraceStoreInfo, T as traceMachineEnabled, V as requireTraceConsent, _ as runTraceRepair, at as readStoreAuth, b as runTraceGitHook, c as registerTraceCommands, ct as runStoreWhoami, d as runTraceList$1, dt as withStoreAuthorization, f as runTracePull$1, ft as emitJsonEvent, g as runTraceInstallMachine, h as runTraceEnable, ht as jsonRequestedInArgv, j as runTraceOnboard, k as runTraceAllow, l as resolveTraceReadStorage, lt as StoreApiError, m as runTraceDisable, mt as humanStream, nt as traceScope, ot as runStoreLogin, p as runTraceShow, pt as failWithJsonError, q as readTraceUserConfig, rt as DEFAULT_STORE_ORIGIN, st as runStoreLogout, tt as traceHomeDir, u as runTraceBlame, ut as StoreClient, v as runTraceStatus, w as readLegacyCaptureSettings, x as runTraceHook, y as runTraceSync, z as selectTraceStorage } from "./review-home-paths-D8AoCdd2.js";
5
+ import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-Dtc-Kn_w.js";
6
6
  import { t as resolveReviewRoot } from "./runtime-Bj2tD33R.js";
7
- 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-BTO12tCC.js";
7
+ 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";
8
8
  import { t as errorMessage } from "./error-message-OtiDonty.js";
9
- import { i as readReviewPackageVersion, r as readBuildInfo, t as findReviewPackageRoot } from "./package-paths-Cm1tR8c4.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-Bwa_6Tsj.js";
11
- import { t as ReviewTelemetry } from "./review-telemetry-Myzm7o6-.js";
12
- import { t as fuzzyRank } from "./fuzzy-match-DH9lZivo.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-ClRtWF_-.js";
14
- import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-CG3TFZEx.js";
15
- import { t as reviewAgentCliHelp } from "./agent-cli-C6AM9dml.js";
9
+ import { i as readReviewPackageVersion, r as readBuildInfo, t as findReviewPackageRoot } from "./package-paths-BWxO-UEL.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-CKjw3-6h.js";
11
+ import { t as ReviewTelemetry } from "./review-telemetry-BsoRMC2w.js";
12
+ import { t as fuzzyRank } from "./fuzzy-match-BmVJJm9I.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-B5-HYi1D.js";
14
+ import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-C7el2Uoy.js";
15
+ import { t as reviewAgentCliHelp } from "./agent-cli-CohHf6Ua.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";
@@ -4297,7 +4297,7 @@ async function runReviewCli(input) {
4297
4297
  if (!Number.isInteger(port) || port < 0 || port > 65535) throw new ReviewCliUsageError("--port must be an integer between 0 and 65535.");
4298
4298
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4299
4299
  if (options.detach) {
4300
- const { ensureBackgroundServer } = await import("./background-server-DJfYWRoN.js");
4300
+ const { ensureBackgroundServer } = await import("./background-server-CB9C4uoc.js");
4301
4301
  const { discovery, started } = await ensureBackgroundServer({
4302
4302
  stateDir,
4303
4303
  env,
@@ -4319,7 +4319,7 @@ async function runReviewCli(input) {
4319
4319
  process.once("SIGINT", stop);
4320
4320
  process.once("SIGTERM", stop);
4321
4321
  process.once(DESKTOP_TAKEOVER_SIGNAL, takeover);
4322
- const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-CeNnXxiL.js");
4322
+ const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-DRtjf9WA.js");
4323
4323
  try {
4324
4324
  await runHeadlessServer({
4325
4325
  stateDir,
@@ -4356,7 +4356,7 @@ async function runReviewCli(input) {
4356
4356
  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) => {
4357
4357
  const options = command.optsWithGlobals();
4358
4358
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4359
- const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-DJfYWRoN.js");
4359
+ const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-CB9C4uoc.js");
4360
4360
  const owner = await headlessServerOwner(stateDir);
4361
4361
  const discovery = await readReviewServerDiscovery(stateDir);
4362
4362
  if (owner === void 0) {
@@ -4384,7 +4384,7 @@ async function runReviewCli(input) {
4384
4384
  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.`);
4385
4385
  const inUse = `A Whiteboard server is using ${stateDir}. Stop it first, then run whiteboard server reset-id again.`;
4386
4386
  if (await desktopUsesHome(stateDir, env)) return refuse(inUse, options.json);
4387
- const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-DthRnZ7x.js"), import("./headless-host-CeNnXxiL.js")]);
4387
+ const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-DJvkBJNQ.js"), import("./headless-host-DRtjf9WA.js")]);
4388
4388
  const reset = await withHeadlessServerLock(await realpath(stateDir), async () => {
4389
4389
  const local = await openReviewProfile(stateDir, { manageWorkspaces: false });
4390
4390
  try {
@@ -4406,7 +4406,7 @@ async function runReviewCli(input) {
4406
4406
  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) => {
4407
4407
  const options = command.optsWithGlobals();
4408
4408
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4409
- const { remoteAttach } = await import("./remote-attach-DGwVRmY5.js");
4409
+ const { remoteAttach } = await import("./remote-attach-Dd-YobM6.js");
4410
4410
  let attach;
4411
4411
  try {
4412
4412
  attach = await remoteAttach({
@@ -4433,7 +4433,7 @@ async function runReviewCli(input) {
4433
4433
  });
4434
4434
  configureJsonOutput(remote.command("extensions").description("Language extensions for the language server on a remote").command("ensure").description("Download the curated extensions for this machine and list them for the language server").option("--groups <groups>", "comma-separated optional extension groups the Desktop has enabled, such as go"), "plain").action(async (_options, command) => {
4435
4435
  const { json, groups } = command.optsWithGlobals();
4436
- const { ensureRemoteExtensions } = await import("./remote-extensions-D8W2IgKH.js");
4436
+ const { ensureRemoteExtensions } = await import("./remote-extensions-VP-kfq0C.js");
4437
4437
  const result = await ensureRemoteExtensions({
4438
4438
  env,
4439
4439
  groups: groups?.split(",").map((group) => group.trim())
@@ -4448,7 +4448,7 @@ async function runReviewCli(input) {
4448
4448
  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) => {
4449
4449
  const options = command.optsWithGlobals();
4450
4450
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4451
- const { remoteUninstall } = await import("./remote-uninstall-DgHnDAFH.js");
4451
+ const { remoteUninstall } = await import("./remote-uninstall-DuOzsvaD.js");
4452
4452
  let deleteReviews = options.deleteReviews ? true : options.keepReviews ? false : void 0;
4453
4453
  if (deleteReviews === void 0 && !options.json && input.stdin?.isTTY) {
4454
4454
  const prompt = createInterface$1({
@@ -4670,14 +4670,14 @@ async function runReviewCli(input) {
4670
4670
  command.showHelpAfterError(false).error("Markdown review migration is no longer supported. Ask your agent to migrate your old Whiteboard reviews.");
4671
4671
  });
4672
4672
  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) => {
4673
- const { runShareCli } = await import("./cli-CqOiiTW_.js");
4673
+ const { runShareCli } = await import("./cli-CJaEb7zC.js");
4674
4674
  state.exitCode = await runShareCli({
4675
4675
  ...input,
4676
4676
  ...options,
4677
4677
  env: authoringEnv()
4678
4678
  });
4679
4679
  }).command("revoke <share-id>").description("Revoke future downloads of a share"), "plain").action(async (shareId, options) => {
4680
- const { runShareCli } = await import("./cli-CqOiiTW_.js");
4680
+ const { runShareCli } = await import("./cli-CJaEb7zC.js");
4681
4681
  state.exitCode = await runShareCli({
4682
4682
  ...input,
4683
4683
  ...options,
@@ -4758,7 +4758,7 @@ async function runReviewCli(input) {
4758
4758
  return commands;
4759
4759
  } });
4760
4760
  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) => {
4761
- const { runReviewAgentCli } = await import("./agent-cli-DKpWo-4F.js");
4761
+ const { runReviewAgentCli } = await import("./agent-cli-_YyMIMRY.js");
4762
4762
  state.exitCode = await runReviewAgentCli({
4763
4763
  ...input,
4764
4764
  env: authoringEnv(),
package/dist/cli.js CHANGED
@@ -17,7 +17,7 @@ async function runCli(effectivePath) {
17
17
  `);
18
18
  return 1;
19
19
  }
20
- const { runReviewCli } = await import("./cli-runner-D8CsXff4.js");
20
+ const { runReviewCli } = await import("./cli-runner-DGDIqh3V.js");
21
21
  return runReviewCli({
22
22
  argv,
23
23
  cliPaths: {
@@ -45,7 +45,8 @@ async function maybeDelegateToDesktopCli(argv) {
45
45
  ].includes(argument) || /^--state-dir(?:=|$)/.test(argument)) || env.DEV_REVIEW_SERVER_DIR?.trim()) return null;
46
46
  const ownPath = fileURLToPath(import.meta.url);
47
47
  if (!/[\\/]dist[\\/]cli\.js$/.test(ownPath)) return null;
48
- const devHome = env.DEV_REVIEW_HOME?.trim() ? path.resolve(env.DEV_REVIEW_HOME.trim()) : path.join(os.homedir(), ".dev");
48
+ const channel = env.DEV_FAST_REVIEW_CHANNEL?.trim() || env.DEV_REVIEW_INSTANCE?.trim();
49
+ const devHome = env.DEV_REVIEW_HOME?.trim() ? path.resolve(env.DEV_REVIEW_HOME.trim()) : path.join(os.homedir(), channel === "preview" ? ".dev-preview" : ".dev");
49
50
  let cliPath;
50
51
  let runtimePath;
51
52
  const discoveryFile = selectedDiscoveryFile(devHome, env);
@@ -1,7 +1,7 @@
1
- import "./review-home-paths-D1JVitqN.js";
2
- import { N as devReviewHome } from "./s3-config-BTO12tCC.js";
1
+ import "./review-home-paths-D8AoCdd2.js";
2
+ import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
3
3
  import { n as askAgentIds } from "./thread-state-Do5LX10I.js";
4
- import { t as ASK_THREAD_ENV } from "./request-origin-DDmfnytX.js";
4
+ import { t as ASK_THREAD_ENV } from "./request-origin-B9qCPiVB.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-C4bhVPZx.js";
1
+ import { i as withHeadlessServerLock, n as runHeadlessServer, r as takeOverServerHome, t as HeadlessServerBusyError } from "./headless-host-XhL1X4vX.js";
2
2
  export { HeadlessServerBusyError, runHeadlessServer, takeOverServerHome, withHeadlessServerLock };
@@ -1,22 +1,22 @@
1
1
  import { E as runVcs, S as resolveRepoContextSync, d as git, r as defaultBranch } from "./src-WPaQn75m.js";
2
2
  import { c as jsonString, m as isStringValue, n as isJsonObject, p as isObjectValue, u as parseJsonText } from "./src-X9phtB2j.js";
3
3
  import { a as sharedReviewId, c as verifyShareRepository, d as validateShareSources, f as StreamLimitError, h as shareIdSchema, l as exportShare, m as parseShareLink, n as ShareClient, p as readBoundedStream, r as SharePreflightError, s as readShareRepository, t as ShareAuthError, u as referenceCommits } from "./client-lKVF_Elo.js";
4
- import { f as textualRows, h as diffrMissingError, i as inspectSnapshot, m as diffrExecutable, p as invalidateStructuralComparisons, r as commandSchema } from "./local-data-BdqqCYUD.js";
4
+ import { f as textualRows, h as diffrMissingError, i as inspectSnapshot, m as diffrExecutable, p as invalidateStructuralComparisons, r as commandSchema } from "./local-data-Cpl4ENbJ.js";
5
5
  import { N as reviewDiffrSummarizerInputSchema, O as ReviewFeedbackContactSchema, P as decodeStructuralDiffEvent, 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, v as REVIEW_HOST_HEADER } from "./src-BiWNbcF_.js";
6
- 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-D1JVitqN.js";
6
+ 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-D8AoCdd2.js";
7
7
  import { _ as scopedCoverage, h as emptyCoverage, i as anchorSelection, l as resolveDiffSelection, m as coverageSources, n as SelectionUnavailableError, o as comparisonKey, s as formatAnchor, u as selectionKey, v as subtractIntervals, y as unionIntervals } from "./lens-selection-CyJapcsl.js";
8
8
  import { B as stepSources, F as selectionReferences, G as lensSelections, J as fileLineRangeSchema, V as UNCATEGORIZED_LENS_ID, _ as boardRepositoryId, f as anchorPins, g as boardLinks, x as elements } from "./stored-document-migration-dFbewRTG.js";
9
9
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
10
- import { L as writePrivateJsonAtomic, N as devReviewHome, h as TraceConfigurationError, i as isS3MockMode, j as withFileLock } from "./s3-config-BTO12tCC.js";
10
+ 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
11
  import { t as errorMessage } from "./error-message-OtiDonty.js";
12
- import { i as readReviewPackageVersion, n as readBuildCommit, t as findReviewPackageRoot } from "./package-paths-Cm1tR8c4.js";
13
- import { _ as reviewInstanceIdentity, i as readReviewServerDiscovery, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-Bwa_6Tsj.js";
12
+ import { i as readReviewPackageVersion, n as readBuildCommit, t as findReviewPackageRoot } from "./package-paths-BWxO-UEL.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-CKjw3-6h.js";
14
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-Do5LX10I.js";
15
- import { t as openReviewProfile } from "./profile-DcigfSms.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-DDmfnytX.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-DH9lZivo.js";
18
- import { a as inspectQuerySchema, i as renderInstructions, o as queryAnchor, r as instructionsQuerySchema, s as readQuerySchemas, t as authoringTools } from "./authoring-tools-Dfo0uOSj.js";
19
- import { a as headlessServerOwner, c as stopBackgroundServer } from "./background-server-BF_lLFxY.js";
15
+ import { t as openReviewProfile } from "./profile-BadSkCkI.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-B9qCPiVB.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-BmVJJm9I.js";
18
+ import { a as inspectQuerySchema, i as renderInstructions, o as queryAnchor, r as instructionsQuerySchema, s as readQuerySchemas, t as authoringTools } from "./authoring-tools-B7KU04f7.js";
19
+ import { a as headlessServerOwner, c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-C03RKxKS.js";
20
20
  import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
21
21
  import { z } from "zod";
22
22
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
@@ -5194,17 +5194,21 @@ function withHeadlessServerLock(stateDir, operation) {
5194
5194
  * Desktop owns its home: it stops any server there, then starts under that
5195
5195
  * server's lock, so none can start until Desktop has published its discovery.
5196
5196
  */
5197
- async function takeOverServerHome(home, start) {
5197
+ async function takeOverServerHome(home, start, { timeoutMs = 3e4 } = {}) {
5198
5198
  const stateDir = await realpath(home);
5199
- const deadline = Date.now() + 3e4;
5199
+ const deadline = Date.now() + timeoutMs;
5200
5200
  while (true) {
5201
5201
  const outcome = await withHeadlessServerLock(stateDir, start);
5202
5202
  if (outcome.acquired) return outcome.result;
5203
5203
  const owner = await headlessServerOwner(stateDir);
5204
- const discovery = await readReviewServerDiscovery(stateDir).catch(() => null);
5205
- if (owner !== void 0 && discovery?.serverPid === owner) await stopBackgroundServer(discovery, DESKTOP_TAKEOVER_SIGNAL);
5206
- else if (Date.now() > deadline) throw new Error(`Process ${owner} holds the Whiteboard server's lock in ${stateDir} without serving it.`);
5207
- else await setTimeout$1(100);
5204
+ const server = await recordedBackgroundServer(stateDir);
5205
+ if (owner !== void 0 && server?.discovery.serverPid === owner) await stopBackgroundServer(server.discovery, DESKTOP_TAKEOVER_SIGNAL);
5206
+ else if (Date.now() <= deadline) await setTimeout$1(100);
5207
+ else if (owner !== void 0 && processStartIdentity(owner) === null) await rm(headlessServerLockPath(stateDir), {
5208
+ recursive: true,
5209
+ force: true
5210
+ });
5211
+ else throw new Error(`Process ${owner} holds the Whiteboard server's lock in ${stateDir} without serving it.`);
5208
5212
  }
5209
5213
  }
5210
5214
  const LOGIN_PATH_TIMEOUT_MS = 4e3;
@@ -1,11 +1,11 @@
1
1
  import { C as resolveRevision, D as runVcsSync, E as runVcs, S as resolveRepoContextSync, T as renderVcsArgs, _ as listTrackedFilesAtCommit, a as diff, b as readFileAtCommit, c as diffFileSummariesWorkingTree, d as git, 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, x as resolveRepoContext, y as parseGitRemoteSlug } from "./src-WPaQn75m.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 { F as structuralChangeCounts, P as decodeStructuralDiffEvent, c as boardIconKind, l as boardTitle } from "./src-BiWNbcF_.js";
4
- import { s as safeStorageSegment } from "./review-home-paths-D1JVitqN.js";
4
+ import { s as safeStorageSegment } from "./review-home-paths-D8AoCdd2.js";
5
5
  import { b as updateCoverage, c as parseAnchor, f as sourceAnchors, g as intersectIntervals, h as emptyCoverage, p as coverageSchema, v as subtractIntervals, y as unionIntervals } from "./lens-selection-CyJapcsl.js";
6
6
  import { $ as parseMarkdown, A as resourceReferences, E as pinsSchema, G as lensSelections, H as applyLensEdit, I as sourceReferences, J as fileLineRangeSchema, K as SourceRangeError, L as summarizeEdit, M as respellDocumentLinks, N as respellEditLinks, P as reviewTargetSchema, Q as markdownText, R as checkReferences, S as explicitPins, T as pinnedRepositoryIds, U as lensEditSchema, X as sliceSourceRange, Y as requireVisibleSource, Z as markdownNodes, _ as boardRepositoryId, a as SoftwareModelValidationError, b as editSchema, d as adoptFlowUnits, f as anchorPins, g as boardLinks, h as assignMissingIds, i as readStoredDocument, j as respellCommitLinks, k as resourceReference, l as traceSchema, m as assignFreshIds, n as migrateStoredDocument, o as defineSoftwareMap, p as applyEdit, q as checkSourcePath, r as migrateStoredLenses, u as textIncludesQuote, v as commitLinkCommits, w as pinDocumentReferences, x as elements, y as documentSchema, z as documentAdvice } from "./stored-document-migration-dFbewRTG.js";
7
7
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
8
- import { A as processStartIdentity, L as writePrivateJsonAtomic, O as pidReused, j as withFileLock, k as processIsAlive } from "./s3-config-BTO12tCC.js";
8
+ import { A as processStartIdentity, L as writePrivateJsonAtomic, O as pidReused, j as withFileLock, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
9
9
  import { t as errorMessage } from "./error-message-OtiDonty.js";
10
10
  import { r as isMissingFileError } from "./fs-utils-BMPLt0cr.js";
11
11
  import { a as askHistoryEntrySchema, i as askEntrySchema, o as askOfferSchema, s as askPermissionsSchema } from "./thread-state-Do5LX10I.js";
@@ -1,7 +1,7 @@
1
- import { a as toolResultText, s as ReviewApiError } from "./agent-client-G4KxB8zB.js";
1
+ import { a as toolResultText, s as ReviewApiError } from "./agent-client-Dtc-Kn_w.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-Dfo0uOSj.js";
4
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-C9J3r7KD.js";
3
+ import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-B7KU04f7.js";
4
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-DvI-gys2.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";
@@ -1,5 +1,5 @@
1
1
  import { c as jsonString, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import "./review-home-paths-D1JVitqN.js";
2
+ import "./review-home-paths-D8AoCdd2.js";
3
3
  import { readFileSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
@@ -1,6 +1,6 @@
1
- import { a as projectOfCheckout, g as CheckoutGroups, o as groupCheckoutsAhead, s as initializeReviewStoreSchema, t as openLocalReviewStore } from "./local-data-BdqqCYUD.js";
2
- import "./review-home-paths-D1JVitqN.js";
3
- import { j as withFileLock } from "./s3-config-BTO12tCC.js";
1
+ import { a as projectOfCheckout, g as CheckoutGroups, o as groupCheckoutsAhead, s as initializeReviewStoreSchema, t as openLocalReviewStore } from "./local-data-Cpl4ENbJ.js";
2
+ import "./review-home-paths-D8AoCdd2.js";
3
+ import { j as withFileLock } from "./s3-config-CjcLyFV5.js";
4
4
  import { access, mkdir } from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  import { DatabaseSync } from "node:sqlite";
@@ -0,0 +1,2 @@
1
+ import { t as openReviewProfile } from "./profile-BadSkCkI.js";
2
+ export { openReviewProfile };
@@ -1,7 +1,7 @@
1
- import { i as readReviewPackageVersion } from "./package-paths-Cm1tR8c4.js";
2
- import { a as readReviewServerHealth, l as serverNotReady } from "./server-discovery-Bwa_6Tsj.js";
3
- import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-BF_lLFxY.js";
4
- import { t as ensureRemoteLanguageServer } from "./remote-language-server-By-rEosC.js";
1
+ import { i as readReviewPackageVersion } from "./package-paths-BWxO-UEL.js";
2
+ import { a as readReviewServerHealth, l as serverNotReady } from "./server-discovery-CKjw3-6h.js";
3
+ import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-C03RKxKS.js";
4
+ import { t as ensureRemoteLanguageServer } from "./remote-language-server-BXk87KCr.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 { u as parseJsonText } from "./src-X9phtB2j.js";
2
- import "./review-home-paths-D1JVitqN.js";
3
- import { N as devReviewHome } from "./s3-config-BTO12tCC.js";
4
- import { t as findReviewPackageRoot } from "./package-paths-Cm1tR8c4.js";
2
+ import "./review-home-paths-D8AoCdd2.js";
3
+ import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
4
+ import { t as findReviewPackageRoot } from "./package-paths-BWxO-UEL.js";
5
5
  import { createHash } from "node:crypto";
6
6
  import { z } from "zod";
7
7
  import { createReadStream, createWriteStream } from "node:fs";
@@ -1,2 +1,2 @@
1
- import { t as ensureRemoteExtensions } from "./remote-extensions-CferWwM9.js";
1
+ import { t as ensureRemoteExtensions } from "./remote-extensions-CNXwqK0D.js";
2
2
  export { ensureRemoteExtensions };
@@ -1,8 +1,8 @@
1
- import "./review-home-paths-D1JVitqN.js";
2
- import { A as processStartIdentity, j as withFileLock } from "./s3-config-BTO12tCC.js";
3
- import { t as findReviewPackageRoot } from "./package-paths-Cm1tR8c4.js";
4
- import { n as cliSpawn, s as spawnDetached } from "./background-server-BF_lLFxY.js";
5
- import { r as remoteServerPaths, t as ensureRemoteExtensions } from "./remote-extensions-CferWwM9.js";
1
+ import "./review-home-paths-D8AoCdd2.js";
2
+ import { A as processStartIdentity, j as withFileLock } from "./s3-config-CjcLyFV5.js";
3
+ import { t as findReviewPackageRoot } from "./package-paths-BWxO-UEL.js";
4
+ import { n as cliSpawn, s as spawnDetached } from "./background-server-C03RKxKS.js";
5
+ import { r as remoteServerPaths, t as ensureRemoteExtensions } from "./remote-extensions-CNXwqK0D.js";
6
6
  import { randomBytes } from "node:crypto";
7
7
  import { z } from "zod";
8
8
  import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
@@ -1,9 +1,9 @@
1
1
  import { C as REVIEW_REMOTE_WRAPPER_MARK, S as REVIEW_REMOTE_INSTALL_LOCK } from "./src-BiWNbcF_.js";
2
- import "./review-home-paths-D1JVitqN.js";
3
- import { M as DEV_REVIEW_HOME_ENV } from "./s3-config-BTO12tCC.js";
4
- import { c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-BF_lLFxY.js";
5
- import { i as whiteboardRemoteHome } from "./remote-extensions-CferWwM9.js";
6
- import { n as remoteLanguageServerGroups, r as stopProcessGroup } from "./remote-language-server-By-rEosC.js";
2
+ import "./review-home-paths-D8AoCdd2.js";
3
+ import { M as DEV_REVIEW_HOME_ENV } from "./s3-config-CjcLyFV5.js";
4
+ import { c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-C03RKxKS.js";
5
+ import { i as whiteboardRemoteHome } from "./remote-extensions-CNXwqK0D.js";
6
+ import { n as remoteLanguageServerGroups, r as stopProcessGroup } from "./remote-language-server-BXk87KCr.js";
7
7
  import { existsSync } from "node:fs";
8
8
  import { lstat, mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
9
9
  import path from "node:path";
@@ -371,7 +371,12 @@ const ONBOARDING_STEP = [
371
371
  "run"
372
372
  ];
373
373
  const RUN_MODE = ["draw", "copy"];
374
- const NEW_WHITEBOARD_VIA = ["button", "command"];
374
+ const NEW_WHITEBOARD_VIA = [
375
+ "button",
376
+ "command",
377
+ "sidebar"
378
+ ];
379
+ const NEW_WHITEBOARD_MODE = [...RUN_MODE, "empty"];
375
380
  const FIND_SURFACE = ["review", "diff"];
376
381
  const DISCORD_VIA = [
377
382
  "topbar",
@@ -765,7 +770,7 @@ const UI_TELEMETRY_EVENTS = {
765
770
  new_whiteboard_started: {
766
771
  event: "review_new_whiteboard_started",
767
772
  properties: {
768
- mode: RUN_MODE,
773
+ mode: NEW_WHITEBOARD_MODE,
769
774
  embedded: "boolean",
770
775
  agent: askAgentIds
771
776
  }
@@ -1,5 +1,5 @@
1
1
  import { o as parseReviewVerbResponse } from "./src-BiWNbcF_.js";
2
- import { b as selectReviewInstance, m as healthyReviewInstance, v as reviewInstanceStartHint, y as reviewInstanceUnavailable } from "./server-discovery-Bwa_6Tsj.js";
2
+ import { b as selectReviewInstance, m as healthyReviewInstance, v as reviewInstanceStartHint, y as reviewInstanceUnavailable } from "./server-discovery-CKjw3-6h.js";
3
3
  import { closeSync, existsSync, fstatSync, mkdtempSync, openSync, readSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { homedir, tmpdir } from "node:os";
@@ -1,7 +1,7 @@
1
1
  import { E as runVcs, d as git, f as gitAt, x as resolveRepoContext } from "./src-WPaQn75m.js";
2
2
  import { a as jsonNumber, c as jsonString, i as jsonBoolean, m as isStringValue, n as isJsonObject, o as jsonObject, r as jsonArray, t as isJsonArray, u as parseJsonText } from "./src-X9phtB2j.js";
3
3
  import { a as TRACE_STORE_CLIENT_ID, b as commitShaSchema, c as deleteStoreResponseSchema, d as listUploadsResponseSchema, f as storeErrorCodeSchema, g as uploadManifestMismatch, h as traceObjectNameSchema, i as storeRoutes, l as listSessionsResponseSchema, m as storeResponseSchema, n as DEVICE_TOKEN_PATH, o as beginUploadResponseSchema, p as storeErrorEnvelopeSchema, r as SESSION_PATH, s as completeUploadResponseSchema, t as DEVICE_CODE_PATH, u as listUploadsQuerySchema, x as sessionIdSchema } from "./src-CGP5ytbV.js";
4
- import { E as writeTraceConfigFile, F as writeFileAtomic, I as writeFileAtomicAsync, L as writePrivateJsonAtomic, N as devReviewHome, P as normalizeStoreOrigin, S as readTraceConfigFile, _ as emptyTraceConfig, b as hostedCaptureEnabled, c as resolveS3Setup, d as traceEnvPath, f as traceEnvValue$1, g as currentStore, h as TraceConfigurationError, i as isS3MockMode, l as s3CacheIdentity, m as DEFAULT_HOSTED_ORIGIN, n as clearTraceEnvCache$1, p as traceSettingsPath, u as s3MockRoot, v as enabledOriginsOf, w as s3Store, x as hostedOrigin, y as hasHostedStore } from "./s3-config-BTO12tCC.js";
4
+ import { E as writeTraceConfigFile, F as writeFileAtomic, I as writeFileAtomicAsync, L as writePrivateJsonAtomic, N as devReviewHome, P as normalizeStoreOrigin, S as readTraceConfigFile, _ as emptyTraceConfig, b as hostedCaptureEnabled, c as resolveS3Setup, d as traceEnvPath, f as traceEnvValue$1, g as currentStore, h as TraceConfigurationError, i as isS3MockMode, l as s3CacheIdentity, m as DEFAULT_HOSTED_ORIGIN, n as clearTraceEnvCache$1, p as traceSettingsPath, u as s3MockRoot, v as enabledOriginsOf, w as s3Store, x as hostedOrigin, y as hasHostedStore } from "./s3-config-CjcLyFV5.js";
5
5
  import { t as errorMessage } from "./error-message-OtiDonty.js";
6
6
  import crypto, { createHash, randomBytes } from "node:crypto";
7
7
  import { z } from "zod";
@@ -2540,7 +2540,7 @@ function isTraceStorageConfigured(scope = {}) {
2540
2540
  }
2541
2541
  /** Loads the direct-store implementation on demand, without opening a store. */
2542
2542
  async function loadS3TraceStorage() {
2543
- return (await import("./s3-DtJFWC0G.js")).S3TraceStorage;
2543
+ return (await import("./s3-CsG2EWED.js")).S3TraceStorage;
2544
2544
  }
2545
2545
  //#endregion
2546
2546
  //#region ../trace-core/src/trace-upload-status.ts
@@ -5266,7 +5266,7 @@ async function configureTraceMachine(input) {
5266
5266
  if (input.verify !== false) {
5267
5267
  if (env.TRACE_R2_MODE === "mock") verifiedAt = (/* @__PURE__ */ new Date()).toISOString();
5268
5268
  else {
5269
- const { S3TraceStorage } = await import("./s3-DtJFWC0G.js");
5269
+ const { S3TraceStorage } = await import("./s3-CsG2EWED.js");
5270
5270
  const readiness = await S3TraceStorage.fromCredentials({
5271
5271
  endpoint: credentials.endpoint,
5272
5272
  bucket: credentials.bucket,
@@ -5736,7 +5736,7 @@ async function runTraceStatus(input) {
5736
5736
  input.stderr.write("Upload status filters require hosted storage.\n");
5737
5737
  return 1;
5738
5738
  }
5739
- const [{ S3TraceStorage }, { describeS3Setup, noTraceConfigurationMessage }] = await Promise.all([import("./s3-DtJFWC0G.js"), import("./s3-config-CSy3fx8H.js")]);
5739
+ const [{ S3TraceStorage }, { describeS3Setup, noTraceConfigurationMessage }] = await Promise.all([import("./s3-CsG2EWED.js"), import("./s3-config-zz4GWh2T.js")]);
5740
5740
  const setup = describeS3Setup(input.scope.env);
5741
5741
  input.stdout.write(`Checking trace configuration (${setup.envPath})…\n`);
5742
5742
  for (const failure of await listTraceSyncFailures(input.scope.devHome)) input.stdout.write(describeTraceSyncFailure(failure));
@@ -1,9 +1,9 @@
1
1
  import { c as jsonString, l as jsonValueSchema, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
2
2
  import "./src-BiWNbcF_.js";
3
- import "./review-home-paths-D1JVitqN.js";
4
- import { F as writeFileAtomic, N as devReviewHome, j as withFileLock, k as processIsAlive } from "./s3-config-BTO12tCC.js";
5
- import { i as readReviewPackageVersion, t as findReviewPackageRoot } from "./package-paths-Cm1tR8c4.js";
6
- import "./request-origin-DDmfnytX.js";
3
+ import "./review-home-paths-D8AoCdd2.js";
4
+ import { F as writeFileAtomic, N as devReviewHome, j as withFileLock, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
5
+ import { i as readReviewPackageVersion, t as findReviewPackageRoot } from "./package-paths-BWxO-UEL.js";
6
+ import "./request-origin-B9qCPiVB.js";
7
7
  import { createHmac, randomUUID } from "node:crypto";
8
8
  import { z } from "zod";
9
9
  import { existsSync, readFileSync, rmSync } from "node:fs";
@@ -1,6 +1,6 @@
1
1
  import { a as jsonNumber, c as jsonString, o as jsonObject, r as jsonArray, u as parseJsonText } from "./src-X9phtB2j.js";
2
2
  import { S as sessionMetaSchema, b as commitShaSchema, y as byCommitSchema } from "./src-CGP5ytbV.js";
3
- import { i as isS3MockMode, l as s3CacheIdentity, s as resolveS3Credentials, u as s3MockRoot } from "./s3-config-BTO12tCC.js";
3
+ import { i as isS3MockMode, l as s3CacheIdentity, s as resolveS3Credentials, u as s3MockRoot } from "./s3-config-CjcLyFV5.js";
4
4
  import { t as errorMessage } from "./error-message-OtiDonty.js";
5
5
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
6
6
  import path from "node:path";
@@ -169,11 +169,13 @@ const DEV_REVIEW_HOME_ENV = "DEV_REVIEW_HOME";
169
169
  * The one resolver for the Review home directory. Every reader of
170
170
  * DEV_REVIEW_HOME calls this, so an untrimmed or empty value cannot make two
171
171
  * modules disagree about the directory. An empty value means "use the
172
- * default".
172
+ * default", which is ~/.dev-preview for preview.
173
173
  */
174
174
  function devReviewHome(env = process.env, homeDir = os.homedir()) {
175
175
  const override = env[DEV_REVIEW_HOME_ENV]?.trim();
176
- return override ? path.resolve(override) : path.join(homeDir, ".dev");
176
+ if (override) return path.resolve(override);
177
+ const channel = env.DEV_FAST_REVIEW_CHANNEL?.trim() || env.DEV_REVIEW_INSTANCE?.trim();
178
+ return path.join(homeDir, channel === "preview" ? ".dev-preview" : ".dev");
177
179
  }
178
180
  //#endregion
179
181
  //#region ../trace-core/src/with-file-lock.ts
@@ -1,2 +1,2 @@
1
- import { a as noTraceConfigurationMessage, c as resolveS3Setup, d as traceEnvPath, f as traceEnvValue, i as isS3MockMode, l as s3CacheIdentity, n as clearTraceEnvCache, o as readTraceEnvFile, p as traceSettingsPath, r as describeS3Setup, s as resolveS3Credentials, t as S3_DEFAULT_REGION, u as s3MockRoot } from "./s3-config-BTO12tCC.js";
1
+ import { a as noTraceConfigurationMessage, c as resolveS3Setup, d as traceEnvPath, f as traceEnvValue, i as isS3MockMode, l as s3CacheIdentity, n as clearTraceEnvCache, o as readTraceEnvFile, p as traceSettingsPath, r as describeS3Setup, s as resolveS3Credentials, t as S3_DEFAULT_REGION, u as s3MockRoot } from "./s3-config-CjcLyFV5.js";
2
2
  export { S3_DEFAULT_REGION, clearTraceEnvCache, describeS3Setup, isS3MockMode, noTraceConfigurationMessage, readTraceEnvFile, resolveS3Credentials, resolveS3Setup, s3CacheIdentity, s3MockRoot, traceEnvPath, traceEnvValue, traceSettingsPath };
@@ -2,21 +2,21 @@
2
2
  import { a as diff, o as diffFileSummaries, w as splitGitPatchFiles } from "../src-WPaQn75m.js";
3
3
  import { c as jsonString, i as jsonBoolean, n as isJsonObject, p as isObjectValue, s as jsonProperty, u as parseJsonText } from "../src-X9phtB2j.js";
4
4
  import { f as StreamLimitError, i as SharedReviewStore, p as readBoundedStream } from "../client-lKVF_Elo.js";
5
- import { d as pullRequestProvider } from "../local-data-BdqqCYUD.js";
5
+ import { d as pullRequestProvider } from "../local-data-Cpl4ENbJ.js";
6
6
  import { A as ReviewGatewayHostSchema, D as ReviewConnectRequestSchema, N as reviewDiffrSummarizerInputSchema, d as ReviewBugReportRequestSchema, f as parseReviewBugReportResponse, m as REVIEW_CLIENT_REMOTE, p as REVIEW_CLIENT_HEADER, r as parseReviewDesktopVerbFrame, s as parseZod, t as parseReviewCliInstallApplyRequest, u as ReviewBugReportMetaV2Schema, v as REVIEW_HOST_HEADER } from "../src-BiWNbcF_.js";
7
- import { i as reviewInstanceDiscoveryPath, o as reviewLegacyDiscoveryPath } from "../review-home-paths-D1JVitqN.js";
7
+ import { i as reviewInstanceDiscoveryPath, o as reviewLegacyDiscoveryPath } from "../review-home-paths-D8AoCdd2.js";
8
8
  import { A as resourceReferences } from "../stored-document-migration-dFbewRTG.js";
9
9
  import { t as ReviewInputError } from "../input-error-OLgB_h31.js";
10
- import { L as writePrivateJsonAtomic, N as devReviewHome } from "../s3-config-BTO12tCC.js";
10
+ import { L as writePrivateJsonAtomic, N as devReviewHome } from "../s3-config-CjcLyFV5.js";
11
11
  import { t as errorMessage } from "../error-message-OtiDonty.js";
12
- import { i as readReviewPackageVersion, t as findReviewPackageRoot } from "../package-paths-Cm1tR8c4.js";
13
- import { _ as reviewInstanceIdentity, u as REVIEW_INSTANCE_ENV } from "../server-discovery-Bwa_6Tsj.js";
14
- import { t as openReviewProfile } from "../profile-DcigfSms.js";
15
- import { r as reviewTelemetryChannel, t as ReviewTelemetry } from "../review-telemetry-Myzm7o6-.js";
16
- import { l as REVIEW_TELEMETRY_TABS } from "../request-origin-DDmfnytX.js";
17
- import { c as removeLegacyReviewSkills, d as skipCliInstall, h as detectConnectAgents, i as finishCliInstallUpdate, l as resetCliInstall, m as connectAgent, n as applyCliInstall, o as pathShimPath, r as declineCliInstall, s as removeCliInstall, t as aliasInstallationToAccount, u as resolveCliInstallStatus } from "../account-alias-ClRtWF_-.js";
18
- import { C as saveDiffrSummarizer, E as cliAskTools, S as readDiffrConfig, T as testDiffrSummarizer, _ as DEFAULT_MAX_REQUEST_BYTES, a as drainServerCrashReport, b as GlobalReviewDesktopVerbRelay, c as answerErrorsAsJson, d as legacyModeSchema, f as captureSanitizedUiTelemetry, g as readBoundedRequestJson, h as createNodeRequestListener, l as createWhiteboardCore, m as recordClientError, o as installProcessErrorTelemetry, p as clientErrorsForSession, r as takeOverServerHome, s as serverCrashReportPath, u as serverJson, v as HttpJsonError, w as setDiffrConfigValue, x as migrateDiffrConfig, y as ReviewServerError } from "../headless-host-C4bhVPZx.js";
19
- import { s as readQuerySchemas } from "../authoring-tools-Dfo0uOSj.js";
12
+ import { i as readReviewPackageVersion, t as findReviewPackageRoot } from "../package-paths-BWxO-UEL.js";
13
+ import { _ as reviewInstanceIdentity, u as REVIEW_INSTANCE_ENV } from "../server-discovery-CKjw3-6h.js";
14
+ import { t as openReviewProfile } from "../profile-BadSkCkI.js";
15
+ import { r as reviewTelemetryChannel, t as ReviewTelemetry } from "../review-telemetry-BsoRMC2w.js";
16
+ import { l as REVIEW_TELEMETRY_TABS } from "../request-origin-B9qCPiVB.js";
17
+ import { c as removeLegacyReviewSkills, d as skipCliInstall, h as detectConnectAgents, i as finishCliInstallUpdate, l as resetCliInstall, m as connectAgent, n as applyCliInstall, o as pathShimPath, r as declineCliInstall, s as removeCliInstall, t as aliasInstallationToAccount, u as resolveCliInstallStatus } from "../account-alias-B5-HYi1D.js";
18
+ import { C as saveDiffrSummarizer, E as cliAskTools, S as readDiffrConfig, T as testDiffrSummarizer, _ as DEFAULT_MAX_REQUEST_BYTES, a as drainServerCrashReport, b as GlobalReviewDesktopVerbRelay, c as answerErrorsAsJson, d as legacyModeSchema, f as captureSanitizedUiTelemetry, g as readBoundedRequestJson, h as createNodeRequestListener, l as createWhiteboardCore, m as recordClientError, o as installProcessErrorTelemetry, p as clientErrorsForSession, r as takeOverServerHome, s as serverCrashReportPath, u as serverJson, v as HttpJsonError, w as setDiffrConfigValue, x as migrateDiffrConfig, y as ReviewServerError } from "../headless-host-XhL1X4vX.js";
19
+ import { s as readQuerySchemas } from "../authoring-tools-B7KU04f7.js";
20
20
  import crypto, { createHash, randomBytes } from "node:crypto";
21
21
  import { z } from "zod";
22
22
  import fs, { existsSync, readFileSync } from "node:fs";
@@ -1,7 +1,7 @@
1
1
  import { a as jsonNumber, n as isJsonObject, s as jsonProperty, u as parseJsonText } from "./src-X9phtB2j.js";
2
2
  import { n as parseReviewDesktopDiscovery } from "./src-BiWNbcF_.js";
3
- import { a as reviewInstancesDir, o as reviewLegacyDiscoveryPath, r as reviewDevInstanceKey, t as reviewDefaultInstancePath } from "./review-home-paths-D1JVitqN.js";
4
- import { M as DEV_REVIEW_HOME_ENV, N as devReviewHome, k as processIsAlive } from "./s3-config-BTO12tCC.js";
3
+ import { a as reviewInstancesDir, o as reviewLegacyDiscoveryPath, r as reviewDevInstanceKey, t as reviewDefaultInstancePath } from "./review-home-paths-D8AoCdd2.js";
4
+ import { M as DEV_REVIEW_HOME_ENV, N as devReviewHome, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
5
5
  import { z } from "zod";
6
6
  import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
7
7
  import path from "node:path";
@@ -196,8 +196,9 @@ function reviewServerStateDir(env = process.env) {
196
196
  function reviewServerDiscoveryPath(stateDir) {
197
197
  return path.join(stateDir, "review-server", "server.json");
198
198
  }
199
- /** Sent by a Desktop taking over the server's state directory. */
200
- const DESKTOP_TAKEOVER_SIGNAL = "SIGUSR2";
199
+ /** Sent by a Desktop taking over the server's state directory. Windows has no
200
+ * SIGUSR2. */
201
+ const DESKTOP_TAKEOVER_SIGNAL = process.platform === "win32" ? "SIGTERM" : "SIGUSR2";
201
202
  function headlessServerLockPath(stateDir) {
202
203
  return path.join(stateDir, "headless-server.lock");
203
204
  }
@@ -1,6 +1,6 @@
1
1
  import { m as isStringValue, n as isJsonObject } from "./src-X9phtB2j.js";
2
2
  import { l as boardTitle } from "./src-BiWNbcF_.js";
3
- import { n as callAuthoringTool, s as ReviewApiError, t as ToolText } from "./agent-client-G4KxB8zB.js";
3
+ import { n as callAuthoringTool, s as ReviewApiError, t as ToolText } from "./agent-client-Dtc-Kn_w.js";
4
4
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
5
5
  //#region src/review-api/public-tools.ts
6
6
  function publicDescription(text) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dev.fast/whiteboard",
3
- "version": "0.3.4-preview.20261019.125",
3
+ "version": "0.3.4-preview.20261019.126",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -88,7 +88,7 @@
88
88
  "repo": "devdotfast/review",
89
89
  "docs": "packages/review/instructions/authoring.md"
90
90
  },
91
- "gitHead": "fc51298c9ea617b6624dcbf7416793fa22451afc",
91
+ "gitHead": "dfbb058ea293f9629d5380bcfc27af97484a52f7",
92
92
  "scripts": {
93
93
  "prebuild": "pnpm run build:workspace-deps",
94
94
  "build": "node --max-old-space-size=8192 node_modules/tsdown/dist/run.mjs",
@@ -699,11 +699,16 @@ export async function writePathShim(
699
699
  cliPath: string,
700
700
  runtimePath: string | undefined,
701
701
  devHome: string,
702
+ previewHome = devHome,
702
703
  ): Promise<void> {
703
704
  if (process.platform === "win32") {
704
705
  await writeFileAtomicAsync(
705
706
  shimPath,
706
- windowsCliShim(cliPath, runtimePath ?? process.execPath, devHome),
707
+ windowsCliShim(
708
+ cliPath,
709
+ runtimePath ?? process.execPath,
710
+ devHome === previewHome ? devHome : undefined,
711
+ ),
707
712
  { replaceSymlink: true },
708
713
  );
709
714
 
@@ -716,6 +721,8 @@ export async function writePathShim(
716
721
  FALLBACK_CLI=${shSingleQuote(cliPath)}
717
722
  FALLBACK_RUNTIME=${shSingleQuote(runtimePath ?? "")}
718
723
  DEFAULT_HOME=${shSingleQuote(devHome)}
724
+ channel="\${DEV_FAST_REVIEW_CHANNEL:-\${DEV_REVIEW_INSTANCE:-}}"
725
+ [ "$channel" = preview ] && DEFAULT_HOME=${shSingleQuote(previewHome)}
719
726
  export DEV_REVIEW_HOME="\${DEV_REVIEW_HOME:-$DEFAULT_HOME}"
720
727
  DESKTOP="$DEV_REVIEW_HOME/review-desktop"
721
728
 
@@ -836,7 +843,11 @@ export async function installReviewCommand(input: {
836
843
  shimPath,
837
844
  input.cliPath,
838
845
  input.cliRuntimePath,
839
- devReviewHome(env, homeDir),
846
+ devReviewHome({ DEV_REVIEW_HOME: env.DEV_REVIEW_HOME }, homeDir),
847
+ devReviewHome(
848
+ { DEV_REVIEW_HOME: env.DEV_REVIEW_HOME, DEV_REVIEW_INSTANCE: "preview" },
849
+ homeDir,
850
+ ),
840
851
  );
841
852
 
842
853
  if (await traceMachineEnabled({ homeDir, env })) {
package/src/cli.ts CHANGED
@@ -84,9 +84,12 @@ async function maybeDelegateToDesktopCli(
84
84
  // This bootstrap runs before the Node floor check, so it cannot import
85
85
  // devReviewHome() from @dev.fast/trace-core: that module graph needs a modern
86
86
  // Node. Keep this copy in step with devReviewHome().
87
+ const channel =
88
+ env.DEV_FAST_REVIEW_CHANNEL?.trim() || env.DEV_REVIEW_INSTANCE?.trim();
89
+
87
90
  const devHome = env.DEV_REVIEW_HOME?.trim()
88
91
  ? path.resolve(env.DEV_REVIEW_HOME.trim())
89
- : path.join(os.homedir(), ".dev");
92
+ : path.join(os.homedir(), channel === "preview" ? ".dev-preview" : ".dev");
90
93
 
91
94
  let cliPath: string;
92
95
  let runtimePath: string | undefined;
@@ -8,7 +8,11 @@ import path from "node:path";
8
8
  import { setTimeout as delay } from "node:timers/promises";
9
9
 
10
10
  import { isObjectValue } from "@dev.fast/json";
11
- import { withFileLock, writePrivateJsonAtomic } from "@dev.fast/trace-core";
11
+ import {
12
+ processStartIdentity,
13
+ withFileLock,
14
+ writePrivateJsonAtomic,
15
+ } from "@dev.fast/trace-core";
12
16
  import type { AskAgentLauncher } from "@review/ask/agents.js";
13
17
  import { cliAskTools } from "@review/ask/threads.js";
14
18
  import { desktopUsesHome } from "@review/desktop-discovery.js";
@@ -19,12 +23,12 @@ import {
19
23
  type ReviewServerDiscovery,
20
24
  desktopOwnsHome,
21
25
  headlessServerLockPath,
22
- readReviewServerDiscovery,
23
26
  reviewServerDiscoveryPath,
24
27
  } from "@review/server-discovery.js";
25
28
 
26
29
  import {
27
30
  headlessServerOwner,
31
+ recordedBackgroundServer,
28
32
  stopBackgroundServer,
29
33
  } from "./background-server.js";
30
34
  import { migrateDiffrConfig } from "./diffr-config.js";
@@ -96,9 +100,10 @@ export function withHeadlessServerLock<T>(
96
100
  export async function takeOverServerHome<T>(
97
101
  home: string,
98
102
  start: () => Promise<T>,
103
+ { timeoutMs = 30_000 }: { timeoutMs?: number } = {},
99
104
  ): Promise<T> {
100
105
  const stateDir = await realpath(home);
101
- const deadline = Date.now() + 30_000;
106
+ const deadline = Date.now() + timeoutMs;
102
107
 
103
108
  while (true) {
104
109
  const outcome = await withHeadlessServerLock(stateDir, start);
@@ -106,18 +111,22 @@ export async function takeOverServerHome<T>(
106
111
  if (outcome.acquired) return outcome.result;
107
112
 
108
113
  const owner = await headlessServerOwner(stateDir);
109
-
110
- const discovery = await readReviewServerDiscovery(stateDir).catch(
111
- () => null,
112
- );
113
-
114
- if (owner !== undefined && discovery?.serverPid === owner)
115
- await stopBackgroundServer(discovery, DESKTOP_TAKEOVER_SIGNAL);
116
- else if (Date.now() > deadline)
114
+ // A server that answers as its recorded pid; a reused pid would not.
115
+ const server = await recordedBackgroundServer(stateDir);
116
+
117
+ if (owner !== undefined && server?.discovery.serverPid === owner)
118
+ await stopBackgroundServer(server.discovery, DESKTOP_TAKEOVER_SIGNAL);
119
+ else if (Date.now() <= deadline) await delay(100);
120
+ // Without a start time (Windows), nothing proves the owner is the server.
121
+ else if (owner !== undefined && processStartIdentity(owner) === null)
122
+ await rm(headlessServerLockPath(stateDir), {
123
+ recursive: true,
124
+ force: true,
125
+ });
126
+ else
117
127
  throw new Error(
118
128
  `Process ${owner} holds the Whiteboard server's lock in ${stateDir} without serving it.`,
119
129
  );
120
- else await delay(100);
121
130
  }
122
131
  }
123
132
 
@@ -31,8 +31,10 @@ export function reviewServerDiscoveryPath(stateDir: string) {
31
31
  return path.join(stateDir, "review-server", "server.json");
32
32
  }
33
33
 
34
- /** Sent by a Desktop taking over the server's state directory. */
35
- export const DESKTOP_TAKEOVER_SIGNAL = "SIGUSR2";
34
+ /** Sent by a Desktop taking over the server's state directory. Windows has no
35
+ * SIGUSR2. */
36
+ export const DESKTOP_TAKEOVER_SIGNAL: NodeJS.Signals =
37
+ process.platform === "win32" ? "SIGTERM" : "SIGUSR2";
36
38
 
37
39
  export function headlessServerLockPath(stateDir: string) {
38
40
  return path.join(stateDir, "headless-server.lock");
@@ -290,7 +290,9 @@ export const ONBOARDING_STEP = ["welcome", "install", "run"] as const;
290
290
 
291
291
  export const RUN_MODE = ["draw", "copy"] as const;
292
292
 
293
- export const NEW_WHITEBOARD_VIA = ["button", "command"] as const;
293
+ export const NEW_WHITEBOARD_VIA = ["button", "command", "sidebar"] as const;
294
+
295
+ export const NEW_WHITEBOARD_MODE = [...RUN_MODE, "empty"] as const;
294
296
 
295
297
  export const FIND_SURFACE = ["review", "diff"] as const;
296
298
 
@@ -668,7 +670,11 @@ export const UI_TELEMETRY_EVENTS = {
668
670
  },
669
671
  new_whiteboard_started: {
670
672
  event: "review_new_whiteboard_started",
671
- properties: { mode: RUN_MODE, embedded: "boolean", agent: askAgentIds },
673
+ properties: {
674
+ mode: NEW_WHITEBOARD_MODE,
675
+ embedded: "boolean",
676
+ agent: askAgentIds,
677
+ },
672
678
  },
673
679
  remote_host_installed: {
674
680
  event: "review_remote_host_installed",
@@ -1,2 +0,0 @@
1
- import { n as runReviewAgentCli } from "./agent-cli-C6AM9dml.js";
2
- export { runReviewAgentCli };
@@ -1,2 +0,0 @@
1
- import { t as openReviewProfile } from "./profile-DcigfSms.js";
2
- export { openReviewProfile };