@dev.fast/whiteboard 0.2.5-preview.20261015.116 → 0.2.5-preview.20261015.117
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.
- package/dist/{account-alias-ChZR3RIU.js → account-alias-3-HnWkjz.js} +1 -1
- package/dist/{agent-cli-CR2PnA9G.js → agent-cli-BabaNr6w.js} +6 -6
- package/dist/agent-cli-CGL0kFJI.js +2 -0
- package/dist/{agent-client-DVd-prfp.js → agent-client-DHKowVF7.js} +3 -3
- package/dist/{authoring-tools-BXKEwhfi.js → authoring-tools-CuGm_pVC.js} +2 -2
- package/dist/{background-server-Cw7CcfaZ.js → background-server-3SrIevG5.js} +2 -2
- package/dist/{background-server-D2Rrr_e2.js → background-server-xlTnBsup.js} +1 -1
- package/dist/build-info.json +1 -1
- package/dist/{cli-CSrz_wGk.js → cli-C8eB7Ot9.js} +1 -1
- package/dist/{cli-runner-PlGqBeMw.js → cli-runner-VEEG16zJ.js} +19 -19
- package/dist/cli.js +2 -2
- package/dist/{client-DhZzPePs.js → client-BBBwu0P7.js} +2 -2
- package/dist/{headless-host-Cp37C-v0.js → headless-host-CEaaG0YT.js} +1 -1
- package/dist/{headless-host-CVXTSIlx.js → headless-host-DI82imwx.js} +17 -11
- package/dist/{local-data-yfLp5PiJ.js → local-data-DcnL0cBy.js} +85 -15
- package/dist/{mcp-DBbDwG4y.js → mcp-Cjs0MnoL.js} +3 -3
- package/dist/profile-BIwE4tC6.js +2 -0
- package/dist/{profile-pAzg7fxC.js → profile-BoWYDne6.js} +1 -1
- package/dist/{remote-attach-BAt2eZx3.js → remote-attach-xGlaS772.js} +3 -3
- package/dist/{remote-extensions-2Cxf3hMo.js → remote-extensions-ByiuSl1D.js} +1 -1
- package/dist/{remote-extensions-BiNx6NQK.js → remote-extensions-D_4DSOhO.js} +6 -18
- package/dist/{remote-language-server-DQgWUNeV.js → remote-language-server-Chz8NQvC.js} +6 -8
- package/dist/{remote-uninstall-DLtDG0o7.js → remote-uninstall-DGdIgpEg.js} +4 -4
- package/dist/{request-origin-DaRIV3cB.js → request-origin-DjOEwBAK.js} +1 -1
- package/dist/{review-app-launcher-D7I4DGoH.js → review-app-launcher-BkNRvyip.js} +2 -2
- package/dist/{review-telemetry-BqB4CiTD.js → review-telemetry-ycbk-YeT.js} +2 -2
- package/dist/server/desktop-host.js +13 -15
- package/dist/{server-discovery-CifQ3yQS.js → server-discovery-BY_MN7tj.js} +1 -1
- package/dist/sharing/index.d.ts +11 -5
- package/dist/sharing/index.js +1 -1
- package/dist/{src-Bgvf1sEN.js → src-B8adXKNt.js} +0 -1
- package/dist/{stored-document-migration-CFOvjRwW.js → stored-document-migration-CVMl7Te5.js} +15 -3
- package/dist/{tool-failure-BXWzQG8T.js → tool-failure--Jih7UeH.js} +1 -1
- package/package.json +6 -5
- package/remote/install.sh +444 -0
- package/src/agent-selection.ts +11 -5
- package/src/cli-runner.ts +3 -3
- package/src/pinned-download.ts +4 -17
- package/src/remote-extensions.ts +4 -3
- package/src/remote-language-server.ts +3 -9
- package/src/review-api/document.ts +24 -1
- package/src/review-api/http.ts +1 -3
- package/src/review-api/local-data.ts +17 -8
- package/src/review-api/store.ts +91 -4
- package/src/review-api/version-cache.ts +36 -0
- package/src/server/hono-http.ts +16 -1
- package/src/server/review-gateway-hosts.ts +1 -7
- package/src/server/review-gateway.ts +2 -1
- package/src/vsix.ts +1 -12
- package/dist/agent-cli-CRPPmS3l.js +0 -2
- package/dist/profile-BSOkA6A-.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { w as ReviewCliInstallStampSchema } from "./src-
|
|
1
|
+
import { w as ReviewCliInstallStampSchema } from "./src-B8adXKNt.js";
|
|
2
2
|
import { $ as removeAgentTraceHook, C as disableTraceMachine, E as traceMachineStatus, G as listTraceRepositoryRoots, K as traceRepositoryStatus, Q as installHarnessHooks, S as configureTraceMachine, T as traceMachineEnabled, U as disableAllTraceRepositories, W as enableTraceRepository, Y as AGENT_TRACE_HOOK_AGENTS, Z as describeTraceHookOwners, ft as StoreClient, n as reviewDesktopStateDir, rt as traceScope, st as readStoreAuth } from "./review-home-paths-zwevIq4I.js";
|
|
3
3
|
import { A as withFileLock, F as writeFileAtomicAsync, I as writePrivateJsonAtomic, M as devReviewHome } from "./s3-config-DDWWMh5x.js";
|
|
4
4
|
import { i as readReviewPackageVersion } from "./package-paths-BsuI4WUf.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
2
2
|
import { T as traceMachineEnabled } from "./review-home-paths-zwevIq4I.js";
|
|
3
|
-
import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-
|
|
3
|
+
import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-DHKowVF7.js";
|
|
4
4
|
import { M as devReviewHome } from "./s3-config-DDWWMh5x.js";
|
|
5
|
-
import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-
|
|
6
|
-
import { n as reviewSessionAgent } from "./review-telemetry-
|
|
7
|
-
import { n as REVIEW_VIA_HEADER, t as REVIEW_AGENT_HEADER } from "./request-origin-
|
|
8
|
-
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure
|
|
5
|
+
import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-BY_MN7tj.js";
|
|
6
|
+
import { n as reviewSessionAgent } from "./review-telemetry-ycbk-YeT.js";
|
|
7
|
+
import { n as REVIEW_VIA_HEADER, t as REVIEW_AGENT_HEADER } from "./request-origin-DjOEwBAK.js";
|
|
8
|
+
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure--Jih7UeH.js";
|
|
9
9
|
//#region src/review-api/agent-cli.ts
|
|
10
10
|
const reviewAgentCliHelp = "whiteboard api tools (one line per tool)\nwhiteboard api tools <tool-name> (its description and input schema)\nwhiteboard api <tool-name> '<json>'\nwhiteboard api <tool-name> - (read JSON from stdin)\nwhiteboard mcp (stdio MCP adapter; Whiteboard Desktop or whiteboard server start must be running)\nSelect headless state with DEV_REVIEW_SERVER_DIR or whiteboard --state-dir <path> api/mcp.\n";
|
|
11
11
|
async function runReviewAgentCli(input) {
|
|
@@ -20,7 +20,7 @@ async function runReviewAgentCli(input) {
|
|
|
20
20
|
if (extra.length || mode === "mcp" && name) throw new Error("Unexpected arguments. Use whiteboard api --help.");
|
|
21
21
|
const headers = Object.fromEntries([[REVIEW_VIA_HEADER, mode === "mcp" ? "mcp" : "api"], [REVIEW_AGENT_HEADER, reviewSessionAgent(env)]]);
|
|
22
22
|
if (mode === "mcp") {
|
|
23
|
-
const { serveReviewMcp } = await import("./mcp-
|
|
23
|
+
const { serveReviewMcp } = await import("./mcp-Cjs0MnoL.js");
|
|
24
24
|
await serveReviewMcp(async (key, agentKind) => {
|
|
25
25
|
const connected = await connectReviewInstance(key ? {
|
|
26
26
|
...env,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { d as isBooleanValue, f as isNumberValue, m as isStringValue, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
2
|
-
import "./src-
|
|
2
|
+
import "./src-B8adXKNt.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-
|
|
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-BY_MN7tj.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. */
|
|
@@ -250,7 +250,7 @@ async function connectReviewInstance(env = process.env, headers = {}, options =
|
|
|
250
250
|
const selection = await selectReviewInstance({ env });
|
|
251
251
|
const discovery = healthyReviewInstance(selection);
|
|
252
252
|
if (!discovery) {
|
|
253
|
-
const { ensureServerWithoutDesktop } = await import("./background-server-
|
|
253
|
+
const { ensureServerWithoutDesktop } = await import("./background-server-xlTnBsup.js");
|
|
254
254
|
const server = await ensureServerWithoutDesktop({
|
|
255
255
|
selection,
|
|
256
256
|
env,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as activityUpdateSchema, g as activityEndSchema, h as activityBeginSchema, i as commandSchema, n as uploadSchema } from "./local-data-
|
|
2
|
-
import {
|
|
1
|
+
import { _ as activityUpdateSchema, g as activityEndSchema, h as activityBeginSchema, i as commandSchema, n as uploadSchema } from "./local-data-DcnL0cBy.js";
|
|
2
|
+
import { S as publishedEditSchema, y as pathTargetSchema } from "./stored-document-migration-CVMl7Te5.js";
|
|
3
3
|
import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
|
|
4
4
|
import { t as findReviewPackageRoot } from "./package-paths-BsuI4WUf.js";
|
|
5
5
|
import { z } from "zod";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "./review-home-paths-zwevIq4I.js";
|
|
2
2
|
import { D as liveLockOwner, O as processIsAlive } from "./s3-config-DDWWMh5x.js";
|
|
3
3
|
import { t as findReviewPackageRoot } from "./package-paths-BsuI4WUf.js";
|
|
4
|
-
import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-
|
|
5
|
-
import { t as desktopApplicationInstalled } from "./review-app-launcher-
|
|
4
|
+
import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-BY_MN7tj.js";
|
|
5
|
+
import { t as desktopApplicationInstalled } from "./review-app-launcher-BkNRvyip.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-
|
|
1
|
+
import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-3SrIevG5.js";
|
|
2
2
|
export { ensureBackgroundServer, ensureServerWithoutDesktop, headlessServerOwner, stopBackgroundServer };
|
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.2.5-preview.20261015.
|
|
1
|
+
{"version":"0.2.5-preview.20261015.117","commit":"b93a4fc67175685fab7275af8c2d80577d50513b","dirty":true,"builtAt":"2026-10-15T14:00:53.987Z"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { C as setLocalVcsCommandObserver, E as __toESM, T as __require, w as __commonJSMin } from "./src-BMPuxWv4.js";
|
|
2
2
|
import { c as jsonString, n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
3
|
-
import { _ as REVIEW_REMOTE_AGENT_IDS, p as REVIEW_CLI_INSTALL_TARGET_LABELS, v as REVIEW_REMOTE_ATTACH_BEGIN, y as REVIEW_REMOTE_ATTACH_END } from "./src-
|
|
3
|
+
import { _ as REVIEW_REMOTE_AGENT_IDS, p as REVIEW_CLI_INSTALL_TARGET_LABELS, v as REVIEW_REMOTE_ATTACH_BEGIN, y as REVIEW_REMOTE_ATTACH_END } from "./src-B8adXKNt.js";
|
|
4
4
|
import { 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, X as agentTraceHomeDirectory, _ as runTraceRepair, _t as jsonRequestedInArgv, b as runTraceGitHook, c as registerTraceCommands, ct as runStoreLogin, d as runTraceList$1, dt as StoreApiError, et as resolveTraceCommand, f as runTracePull$1, ft as StoreClient, g as runTraceInstallMachine, gt as humanStream, h as runTraceEnable, ht as failWithJsonError, it as DEFAULT_STORE_ORIGIN, j as runTraceOnboard, k as runTraceAllow, l as resolveTraceReadStorage, lt as runStoreLogout, m as runTraceDisable, mt as emitJsonEvent, nt as traceHomeDir, p as runTraceShow, pt as withStoreAuthorization, q as readTraceUserConfig, rt as traceScope, st as readStoreAuth, u as runTraceBlame, ut as runStoreWhoami, v as runTraceStatus, w as readLegacyCaptureSettings, x as runTraceHook, y as runTraceSync, z as selectTraceStorage } from "./review-home-paths-zwevIq4I.js";
|
|
5
|
-
import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-
|
|
5
|
+
import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-DHKowVF7.js";
|
|
6
6
|
import { t as resolveReviewRoot } from "./runtime-CKiWhGrf.js";
|
|
7
7
|
import { C as s3ProfileSchema, E as writeTraceConfigFile, M as devReviewHome, N 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-DDWWMh5x.js";
|
|
8
8
|
import { t as errorMessage } from "./error-message-OtiDonty.js";
|
|
9
9
|
import { i as readReviewPackageVersion, r as readBuildInfo, t as findReviewPackageRoot } from "./package-paths-BsuI4WUf.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-
|
|
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-BY_MN7tj.js";
|
|
11
11
|
import { t as isDirectory } from "./fs-utils-BMPLt0cr.js";
|
|
12
|
-
import { t as ReviewTelemetry } from "./review-telemetry-
|
|
13
|
-
import { _ as connectPrompts, a as isOwnedShim, f as windowsInstallerCommand, g as CONNECT_COMMANDS, h as isInstallTarget, m as ALL_INSTALL_TARGETS, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount } from "./account-alias-
|
|
12
|
+
import { t as ReviewTelemetry } from "./review-telemetry-ycbk-YeT.js";
|
|
13
|
+
import { _ as connectPrompts, a as isOwnedShim, f as windowsInstallerCommand, g as CONNECT_COMMANDS, h as isInstallTarget, m as ALL_INSTALL_TARGETS, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount } from "./account-alias-3-HnWkjz.js";
|
|
14
14
|
import { t as fuzzyRank } from "./fuzzy-match-BoAmcyak.js";
|
|
15
|
-
import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-
|
|
16
|
-
import { t as reviewAgentCliHelp } from "./agent-cli-
|
|
15
|
+
import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-BkNRvyip.js";
|
|
16
|
+
import { t as reviewAgentCliHelp } from "./agent-cli-BabaNr6w.js";
|
|
17
17
|
import { z } from "zod";
|
|
18
18
|
import { constants, existsSync, mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
19
19
|
import { access, readFile, realpath } from "node:fs/promises";
|
|
@@ -4451,7 +4451,7 @@ async function runReviewCli(input) {
|
|
|
4451
4451
|
if (!Number.isInteger(port) || port < 0 || port > 65535) throw new ReviewCliUsageError("--port must be an integer between 0 and 65535.");
|
|
4452
4452
|
const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
|
|
4453
4453
|
if (options.detach) {
|
|
4454
|
-
const { ensureBackgroundServer } = await import("./background-server-
|
|
4454
|
+
const { ensureBackgroundServer } = await import("./background-server-xlTnBsup.js");
|
|
4455
4455
|
const { discovery, started } = await ensureBackgroundServer({
|
|
4456
4456
|
stateDir,
|
|
4457
4457
|
env,
|
|
@@ -4473,7 +4473,7 @@ async function runReviewCli(input) {
|
|
|
4473
4473
|
process.once("SIGINT", stop);
|
|
4474
4474
|
process.once("SIGTERM", stop);
|
|
4475
4475
|
process.once(DESKTOP_TAKEOVER_SIGNAL, takeover);
|
|
4476
|
-
const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-
|
|
4476
|
+
const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-CEaaG0YT.js");
|
|
4477
4477
|
try {
|
|
4478
4478
|
await runHeadlessServer({
|
|
4479
4479
|
stateDir,
|
|
@@ -4510,7 +4510,7 @@ async function runReviewCli(input) {
|
|
|
4510
4510
|
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) => {
|
|
4511
4511
|
const options = command.optsWithGlobals();
|
|
4512
4512
|
const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
|
|
4513
|
-
const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-
|
|
4513
|
+
const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-xlTnBsup.js");
|
|
4514
4514
|
const owner = await headlessServerOwner(stateDir);
|
|
4515
4515
|
const discovery = await readReviewServerDiscovery(stateDir);
|
|
4516
4516
|
if (owner === void 0) {
|
|
@@ -4538,7 +4538,7 @@ async function runReviewCli(input) {
|
|
|
4538
4538
|
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.`);
|
|
4539
4539
|
const inUse = `A Whiteboard server is using ${stateDir}. Stop it first, then run whiteboard server reset-id again.`;
|
|
4540
4540
|
if (await desktopUsesHome(stateDir, env)) return refuse(inUse, options.json);
|
|
4541
|
-
const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-
|
|
4541
|
+
const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-BIwE4tC6.js"), import("./headless-host-CEaaG0YT.js")]);
|
|
4542
4542
|
const reset = await withHeadlessServerLock(await realpath(stateDir), async () => {
|
|
4543
4543
|
const local = await openReviewProfile(stateDir, { manageWorkspaces: false });
|
|
4544
4544
|
try {
|
|
@@ -4560,7 +4560,7 @@ async function runReviewCli(input) {
|
|
|
4560
4560
|
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) => {
|
|
4561
4561
|
const options = command.optsWithGlobals();
|
|
4562
4562
|
const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
|
|
4563
|
-
const { remoteAttach } = await import("./remote-attach-
|
|
4563
|
+
const { remoteAttach } = await import("./remote-attach-xGlaS772.js");
|
|
4564
4564
|
let attach;
|
|
4565
4565
|
try {
|
|
4566
4566
|
attach = await remoteAttach({
|
|
@@ -4583,11 +4583,11 @@ async function runReviewCli(input) {
|
|
|
4583
4583
|
state.exitCode = 1;
|
|
4584
4584
|
return;
|
|
4585
4585
|
}
|
|
4586
|
-
input.stdout.write(options.json ? `${REVIEW_REMOTE_ATTACH_BEGIN}\n${JSON.stringify(attach)}\n${REVIEW_REMOTE_ATTACH_END}\n` : `Whiteboard server ${attach.startedServer ? "started" : "already running"} at ${attach.url}\nLanguage features: ${attach.languageServer ? `
|
|
4586
|
+
input.stdout.write(options.json ? `${REVIEW_REMOTE_ATTACH_BEGIN}\n${JSON.stringify(attach)}\n${REVIEW_REMOTE_ATTACH_END}\n` : `Whiteboard server ${attach.startedServer ? "started" : "already running"} at ${attach.url}\nLanguage features: ${attach.languageServer ? `language server on port ${attach.languageServer.port}` : `unavailable (${attach.languageServerDetail})`}\n`);
|
|
4587
4587
|
});
|
|
4588
|
-
configureJsonOutput(remote.command("extensions").description("Language extensions for the
|
|
4588
|
+
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) => {
|
|
4589
4589
|
const { json, groups } = command.optsWithGlobals();
|
|
4590
|
-
const { ensureRemoteExtensions } = await import("./remote-extensions-
|
|
4590
|
+
const { ensureRemoteExtensions } = await import("./remote-extensions-ByiuSl1D.js");
|
|
4591
4591
|
const result = await ensureRemoteExtensions({
|
|
4592
4592
|
env,
|
|
4593
4593
|
groups: groups?.split(",").map((group) => group.trim())
|
|
@@ -4602,7 +4602,7 @@ async function runReviewCli(input) {
|
|
|
4602
4602
|
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) => {
|
|
4603
4603
|
const options = command.optsWithGlobals();
|
|
4604
4604
|
const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
|
|
4605
|
-
const { remoteUninstall } = await import("./remote-uninstall-
|
|
4605
|
+
const { remoteUninstall } = await import("./remote-uninstall-DGdIgpEg.js");
|
|
4606
4606
|
let deleteReviews = options.deleteReviews ? true : options.keepReviews ? false : void 0;
|
|
4607
4607
|
if (deleteReviews === void 0 && !options.json && input.stdin?.isTTY) {
|
|
4608
4608
|
const prompt = createInterface$1({
|
|
@@ -4810,14 +4810,14 @@ async function runReviewCli(input) {
|
|
|
4810
4810
|
command.showHelpAfterError(false).error("Markdown review migration is no longer supported. Ask your agent to migrate your old Whiteboard reviews.");
|
|
4811
4811
|
});
|
|
4812
4812
|
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) => {
|
|
4813
|
-
const { runShareCli } = await import("./cli-
|
|
4813
|
+
const { runShareCli } = await import("./cli-C8eB7Ot9.js");
|
|
4814
4814
|
state.exitCode = await runShareCli({
|
|
4815
4815
|
...input,
|
|
4816
4816
|
...options,
|
|
4817
4817
|
env: authoringEnv()
|
|
4818
4818
|
});
|
|
4819
4819
|
}).command("revoke <share-id>").description("Revoke future downloads of a share"), "plain").action(async (shareId, options) => {
|
|
4820
|
-
const { runShareCli } = await import("./cli-
|
|
4820
|
+
const { runShareCli } = await import("./cli-C8eB7Ot9.js");
|
|
4821
4821
|
state.exitCode = await runShareCli({
|
|
4822
4822
|
...input,
|
|
4823
4823
|
...options,
|
|
@@ -4898,7 +4898,7 @@ async function runReviewCli(input) {
|
|
|
4898
4898
|
return commands;
|
|
4899
4899
|
} });
|
|
4900
4900
|
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) => {
|
|
4901
|
-
const { runReviewAgentCli } = await import("./agent-cli-
|
|
4901
|
+
const { runReviewAgentCli } = await import("./agent-cli-CGL0kFJI.js");
|
|
4902
4902
|
state.exitCode = await runReviewAgentCli({
|
|
4903
4903
|
...input,
|
|
4904
4904
|
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-
|
|
3
|
+
import "./src-B8adXKNt.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-
|
|
20
|
+
const { runReviewCli } = await import("./cli-runner-VEEG16zJ.js");
|
|
21
21
|
return runReviewCli({
|
|
22
22
|
argv,
|
|
23
23
|
cliPaths: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { f as gitAt } from "./src-BMPuxWv4.js";
|
|
2
2
|
import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
3
|
-
import "./src-
|
|
4
|
-
import { B as
|
|
3
|
+
import "./src-B8adXKNt.js";
|
|
4
|
+
import { B as markdownNodes, C as resourceReference, D as sourceReferences, N as lensSchema, P as lensSelections, V as parseMarkdown, _ as hasCodeReferences, c as traceSchema, h as elements, k as checkReferences, l as textIncludesQuote, n as migrateStoredDocument, o as normalizedSoftwareElementSchema, p as documentSchema, q as sourceAnchors, r as migrateStoredLenses, s as normalizedSoftwareRelationshipSchema, t as liftFileLenses, u as anchorPins, w as resourceReferences, x as pinsSchema } from "./stored-document-migration-CVMl7Te5.js";
|
|
5
5
|
import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
7
|
import { z } from "zod";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as withHeadlessServerLock, n as runHeadlessServer, r as takeOverServerHome, t as HeadlessServerBusyError } from "./headless-host-
|
|
1
|
+
import { i as withHeadlessServerLock, n as runHeadlessServer, r as takeOverServerHome, t as HeadlessServerBusyError } from "./headless-host-DI82imwx.js";
|
|
2
2
|
export { HeadlessServerBusyError, runHeadlessServer, takeOverServerHome, withHeadlessServerLock };
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { d as git, r as defaultBranch } from "./src-BMPuxWv4.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 { a as sharedReviewId, c as verifyShareRepository, d as StreamLimitError, f as readBoundedStream, l as exportShare, m as shareIdSchema, n as ShareClient, p as parseShareLink, r as SharePreflightError, s as readShareRepository, t as ShareAuthError, u as validateShareSources } from "./client-
|
|
4
|
-
import { a as inspectSnapshot, b as diffrMissingError, c as askAgentIds, d as askPicksSchema, f as askQuestionSchema, i as commandSchema, l as askChoiceKinds, m as selectionMarkdown, p as AgentSelectionSchema, r as SCRATCHPAD_ID, s as applyAskChange, u as askPermissionsSchema, v as invalidateStructuralComparisons, y as diffrExecutable } from "./local-data-
|
|
5
|
-
import { A as reviewDiffrSummarizerInputSchema, D as ReviewOnboardingRunRequestSchema, a as parseReviewVerbRequest, g as REVIEW_HOST_HEADER, i as parseReviewDesktopVerbResult, j as decodeStructuralDiffEvent } from "./src-
|
|
3
|
+
import { a as sharedReviewId, c as verifyShareRepository, d as StreamLimitError, f as readBoundedStream, l as exportShare, m as shareIdSchema, n as ShareClient, p as parseShareLink, r as SharePreflightError, s as readShareRepository, t as ShareAuthError, u as validateShareSources } from "./client-BBBwu0P7.js";
|
|
4
|
+
import { a as inspectSnapshot, b as diffrMissingError, c as askAgentIds, d as askPicksSchema, f as askQuestionSchema, i as commandSchema, l as askChoiceKinds, m as selectionMarkdown, p as AgentSelectionSchema, r as SCRATCHPAD_ID, s as applyAskChange, u as askPermissionsSchema, v as invalidateStructuralComparisons, y as diffrExecutable } from "./local-data-DcnL0cBy.js";
|
|
5
|
+
import { A as reviewDiffrSummarizerInputSchema, D as ReviewOnboardingRunRequestSchema, a as parseReviewVerbRequest, g as REVIEW_HOST_HEADER, i as parseReviewDesktopVerbResult, j as decodeStructuralDiffEvent } from "./src-B8adXKNt.js";
|
|
6
6
|
import { B as TraceStorageDeniedError, D as listReviewTraceSessions, I as isTraceStorageConfigured, O as loadReviewAgentTrace, R as resolveTraceStorage, T as traceMachineEnabled, at as clearStoreAuth, ct as runStoreLogin, it as DEFAULT_STORE_ORIGIN, ot as openUrlInBrowser, st as readStoreAuth, tt as shellQuote, z as selectTraceStorage } from "./review-home-paths-zwevIq4I.js";
|
|
7
|
-
import { $ as
|
|
7
|
+
import { $ as subtractIntervals, A as UNCATEGORIZED_LENS_ID, E as selectionReferences, G as resolveDiffSelection, H as anchorSelection, K as selectionKey, L as fileLineRangeSchema, P as lensSelections, Q as scopedCoverage, U as comparisonKey, W as formatAnchor, X as emptyCoverage, Y as coverageSources, et as unionIntervals, h as elements, u as anchorPins } from "./stored-document-migration-CVMl7Te5.js";
|
|
8
8
|
import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
|
|
9
9
|
import { A as withFileLock, I as writePrivateJsonAtomic, M as devReviewHome, h as TraceConfigurationError, i as isS3MockMode } from "./s3-config-DDWWMh5x.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-BsuI4WUf.js";
|
|
12
|
-
import { i as readReviewServerDiscovery, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-
|
|
13
|
-
import { t as openReviewProfile } from "./profile-
|
|
14
|
-
import { a as REVIEW_APP_SESSION_ID_HEADER, c as sanitizeUiTelemetryEvent, i as BUNDLE_FRAME_PATTERN, l as cleanTelemetryText, r as reviewRequestOrigin, s as isReportableCleanedMessage } from "./request-origin-
|
|
15
|
-
import { a as scratchpadAvailable, c as readQuerySchemas, i as renderInstructions, o as inspectQuerySchema, r as instructionsQuerySchema, s as queryAnchor, t as authoringTools } from "./authoring-tools-
|
|
12
|
+
import { i as readReviewServerDiscovery, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-BY_MN7tj.js";
|
|
13
|
+
import { t as openReviewProfile } from "./profile-BoWYDne6.js";
|
|
14
|
+
import { a as REVIEW_APP_SESSION_ID_HEADER, c as sanitizeUiTelemetryEvent, i as BUNDLE_FRAME_PATTERN, l as cleanTelemetryText, r as reviewRequestOrigin, s as isReportableCleanedMessage } from "./request-origin-DjOEwBAK.js";
|
|
15
|
+
import { a as scratchpadAvailable, c as readQuerySchemas, i as renderInstructions, o as inspectQuerySchema, r as instructionsQuerySchema, s as queryAnchor, t as authoringTools } from "./authoring-tools-CuGm_pVC.js";
|
|
16
16
|
import { t as fuzzyRank } from "./fuzzy-match-BoAmcyak.js";
|
|
17
|
-
import { a as headlessServerOwner, c as stopBackgroundServer } from "./background-server-
|
|
17
|
+
import { a as headlessServerOwner, c as stopBackgroundServer } from "./background-server-3SrIevG5.js";
|
|
18
18
|
import { createRequire } from "node:module";
|
|
19
19
|
import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
20
20
|
import { z } from "zod";
|
|
@@ -2146,8 +2146,14 @@ function applyCorsHeaders(request, response) {
|
|
|
2146
2146
|
response.headers.set("access-control-expose-headers", REVIEW_HOST_HEADER);
|
|
2147
2147
|
return response;
|
|
2148
2148
|
}
|
|
2149
|
+
/** The allowed origin, headers and methods hold for the server's lifetime, so
|
|
2150
|
+
* the client may reuse a preflight. Chromium otherwise keeps one for 5 s, and
|
|
2151
|
+
* nearly every request paid a second round trip. Two hours is Chromium's cap. */
|
|
2152
|
+
const PREFLIGHT_MAX_AGE_SECONDS = 7200;
|
|
2149
2153
|
function corsPreflightResponse(request) {
|
|
2150
|
-
|
|
2154
|
+
const response = applyCorsHeaders(request, new Response(null, { status: 204 }));
|
|
2155
|
+
response.headers.set("access-control-max-age", String(PREFLIGHT_MAX_AGE_SECONDS));
|
|
2156
|
+
return response;
|
|
2151
2157
|
}
|
|
2152
2158
|
function isAuthorizedRequest(request, expectedToken) {
|
|
2153
2159
|
const supplied = request.headers.get("x-review-token") ?? new URL(request.url).searchParams.get("token");
|
|
@@ -4262,7 +4268,7 @@ function createReviewApi(store, data, open, shared, capabilities = () => ({
|
|
|
4262
4268
|
head: `b/${diff.newPath}`
|
|
4263
4269
|
} : void 0);
|
|
4264
4270
|
return [
|
|
4265
|
-
|
|
4271
|
+
`Whiteboard: ${snapshot.title}`,
|
|
4266
4272
|
`Session ID: ${snapshot.reviewId}`,
|
|
4267
4273
|
`Version: ${snapshot.version}`,
|
|
4268
4274
|
...selection.apiSource?.commit ? [`Selected commit: ${selection.apiSource.commit}`] : [],
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { _ as parseGitRemote, a as diff, b as resolveRepoContextSync, c as diffFileSummariesWorkingTree, d as git, g as listTrackedFilesAtCommit, h as listCommitRange, i as detectLocalVcs, l as diffTrees, m as jjRevisionIsConflicted, n as createBlobBatchReader, p as gitCommonDir, s as diffFileSummariesTrees, t as LocalVcsToolsMissingError, u as diffWorkingTree, v as readFileAtCommit, x as resolveRevision, y as resolveRepoContext } from "./src-BMPuxWv4.js";
|
|
2
2
|
import { c as jsonString, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
3
|
-
import { C as ReviewApiSelectionSourceSchema, M as structuralChangeCounts, O as ReviewSelectedDiffSchema, j as decodeStructuralDiffEvent, k as SCRATCHPAD_REVIEW_ID } from "./src-
|
|
3
|
+
import { C as ReviewApiSelectionSourceSchema, M as structuralChangeCounts, O as ReviewSelectedDiffSchema, j as decodeStructuralDiffEvent, k as SCRATCHPAD_REVIEW_ID } from "./src-B8adXKNt.js";
|
|
4
4
|
import { s as safeStorageSegment } from "./review-home-paths-zwevIq4I.js";
|
|
5
|
-
import { $ as
|
|
5
|
+
import { $ as subtractIntervals, C as resourceReference, D as sourceReferences, F as SourceRangeError, I as checkSourcePath, J as coverageSchema, L as fileLineRangeSchema, M as lensEditSchema, O as summarizeEdit, P as lensSelections, R as requireVisibleSource, T as reviewTargetSchema, X as emptyCoverage, Z as intersectIntervals, a as defineSoftwareMap, b as pinnedRepositoryIds, c as traceSchema, d as applyEdit, et as unionIntervals, f as assignFreshIds, g as explicitPins, h as elements, i as SoftwareModelValidationError, j as applyLensEdit, k as checkReferences, l as textIncludesQuote, m as editSchema, n as migrateStoredDocument, p as documentSchema, q as sourceAnchors, r as migrateStoredLenses, t as liftFileLenses, tt as updateCoverage, u as anchorPins, v as isUnit, w as resourceReferences, x as pinsSchema, z as sliceSourceRange } from "./stored-document-migration-CVMl7Te5.js";
|
|
6
6
|
import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
|
|
7
7
|
import { A as withFileLock, I as writePrivateJsonAtomic, O as processIsAlive } from "./s3-config-DDWWMh5x.js";
|
|
8
8
|
import { t as errorMessage } from "./error-message-OtiDonty.js";
|
|
@@ -1698,14 +1698,14 @@ const AgentSelectionSchema = z.strictObject({
|
|
|
1698
1698
|
});
|
|
1699
1699
|
function selectionMarkdown(selection, sourceExcerpt = "", diffPaths) {
|
|
1700
1700
|
const target = selection.target;
|
|
1701
|
-
if (selection.selectedDiff) return selectedDiffMarkdown(selection.selectedDiff, diffPaths)
|
|
1701
|
+
if (selection.selectedDiff) return `Selected diff:\n${selectedDiffMarkdown(selection.selectedDiff, diffPaths)}`;
|
|
1702
1702
|
if (target.kind === "review") return "";
|
|
1703
|
-
if (target.kind === "text") return target.quote.split(/\r?\n/).map((line) => `> ${line}`).join("\n")
|
|
1704
|
-
return [
|
|
1703
|
+
if (target.kind === "text") return `Selected text:\n${target.quote.split(/\r?\n/).map((line) => `> ${line}`).join("\n")}`;
|
|
1704
|
+
return `Selected code:\n${[
|
|
1705
1705
|
`## ${selection.title}`,
|
|
1706
1706
|
selection.detail ?? "",
|
|
1707
1707
|
sourceExcerpt
|
|
1708
|
-
].filter(Boolean).join("\n\n")
|
|
1708
|
+
].filter(Boolean).join("\n\n")}`;
|
|
1709
1709
|
}
|
|
1710
1710
|
function selectedDiffMarkdown(diff, paths) {
|
|
1711
1711
|
const oldCount = diff.rows.filter((row) => row.kind !== "added").length;
|
|
@@ -2376,16 +2376,63 @@ var ReviewStore = class {
|
|
|
2376
2376
|
};
|
|
2377
2377
|
}
|
|
2378
2378
|
refreshPending;
|
|
2379
|
+
/** What the last refresh saw of each review. A live worktree's snapshot is
|
|
2380
|
+
* kept, since every pass projects it again. */
|
|
2381
|
+
refreshed = /* @__PURE__ */ new Map();
|
|
2382
|
+
availableRepositories;
|
|
2383
|
+
/** Reviews whose source may have moved since the last pass: every live
|
|
2384
|
+
* worktree, and any other review that is new, edited, restored from trash or
|
|
2385
|
+
* reads from a repository that appeared or went away. */
|
|
2386
|
+
*reviewsToRefresh() {
|
|
2387
|
+
const available = new Set(this.repositories().filter((repository) => existsSync(repository.path)).map((repository) => repository.id));
|
|
2388
|
+
const previous = this.availableRepositories;
|
|
2389
|
+
this.availableRepositories = available;
|
|
2390
|
+
const flipped = (id) => !previous || previous.has(id) !== available.has(id);
|
|
2391
|
+
const rows = this.db.prepare("SELECT reviews.id, reviews.version, review_attention.deleted_at FROM reviews LEFT JOIN review_attention ON review_attention.review_id=reviews.id").all();
|
|
2392
|
+
const present = /* @__PURE__ */ new Set();
|
|
2393
|
+
for (const row of rows) {
|
|
2394
|
+
const reviewId = String(row.id);
|
|
2395
|
+
const version = Number(row.version);
|
|
2396
|
+
const state = `${version}\0${row.deleted_at ?? ""}`;
|
|
2397
|
+
present.add(reviewId);
|
|
2398
|
+
let seen = this.refreshed.get(reviewId);
|
|
2399
|
+
if (seen?.state === state) {
|
|
2400
|
+
if (seen.live) yield seen.live;
|
|
2401
|
+
else if ([...seen.repositories].some(flipped)) yield this.read(reviewId, version);
|
|
2402
|
+
continue;
|
|
2403
|
+
}
|
|
2404
|
+
const snapshot = row.deleted_at ? void 0 : this.read(reviewId, version);
|
|
2405
|
+
if (!snapshot) {
|
|
2406
|
+
this.refreshed.set(reviewId, {
|
|
2407
|
+
state,
|
|
2408
|
+
repositories: /* @__PURE__ */ new Set()
|
|
2409
|
+
});
|
|
2410
|
+
continue;
|
|
2411
|
+
}
|
|
2412
|
+
const live = snapshot.target?.kind === "worktree";
|
|
2413
|
+
seen = {
|
|
2414
|
+
state,
|
|
2415
|
+
repositories: live ? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set([...snapshot.pins ? [snapshot.pins.repositoryId] : [], ...pinnedRepositoryIds(snapshot.document)]),
|
|
2416
|
+
live: live ? snapshot : void 0
|
|
2417
|
+
};
|
|
2418
|
+
this.refreshed.set(reviewId, seen);
|
|
2419
|
+
yield snapshot;
|
|
2420
|
+
}
|
|
2421
|
+
for (const reviewId of this.refreshed.keys()) if (!present.has(reviewId)) this.refreshed.delete(reviewId);
|
|
2422
|
+
}
|
|
2379
2423
|
/** Refresh source state without writing authored document versions. Serialized with edits. */
|
|
2380
2424
|
refreshWorktrees() {
|
|
2381
2425
|
if (this.closing || !this.providers.resolveTarget) return Promise.resolve();
|
|
2382
2426
|
if (this.refreshPending) return this.refreshPending;
|
|
2383
2427
|
const run = this.pending.then(async () => {
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2428
|
+
let slice = performance.now();
|
|
2429
|
+
for (const snapshot of this.reviewsToRefresh()) {
|
|
2430
|
+
if (performance.now() - slice > 16) {
|
|
2431
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
2432
|
+
slice = performance.now();
|
|
2433
|
+
}
|
|
2387
2434
|
try {
|
|
2388
|
-
const live = this.liveSources.get(
|
|
2435
|
+
const live = this.liveSources.get(snapshot.reviewId);
|
|
2389
2436
|
const last = live?.version === snapshot.version ? live : snapshot;
|
|
2390
2437
|
const previous = last.pins;
|
|
2391
2438
|
const projected = await this.projectLiveSource(snapshot, last);
|
|
@@ -3139,6 +3186,27 @@ function inspectSnapshot(snapshot, targetId) {
|
|
|
3139
3186
|
}));
|
|
3140
3187
|
}
|
|
3141
3188
|
//#endregion
|
|
3189
|
+
//#region src/review-api/version-cache.ts
|
|
3190
|
+
/** A stored version never changes, so work derived from it runs once. Keeps
|
|
3191
|
+
* the `capacity` most recently used results. */
|
|
3192
|
+
var VersionCache = class {
|
|
3193
|
+
derive;
|
|
3194
|
+
options;
|
|
3195
|
+
results = /* @__PURE__ */ new Map();
|
|
3196
|
+
constructor(derive, options) {
|
|
3197
|
+
this.derive = derive;
|
|
3198
|
+
this.options = options;
|
|
3199
|
+
}
|
|
3200
|
+
get(input) {
|
|
3201
|
+
const key = this.options.key?.(input) ?? `${input.reviewId}\0${input.version}`;
|
|
3202
|
+
const result = this.results.get(key) ?? this.derive(input);
|
|
3203
|
+
this.results.delete(key);
|
|
3204
|
+
if (this.results.size >= this.options.capacity) this.results.delete(this.results.keys().next().value);
|
|
3205
|
+
this.results.set(key, result);
|
|
3206
|
+
return result;
|
|
3207
|
+
}
|
|
3208
|
+
};
|
|
3209
|
+
//#endregion
|
|
3142
3210
|
//#region src/review-api/workspaces.ts
|
|
3143
3211
|
const OWNED_ELSEWHERE = "Another Whiteboard server is managing this review's language workspaces. Retry once it stops.";
|
|
3144
3212
|
/** Local lifecycle only: source and authored history never depend on preparation.
|
|
@@ -3942,18 +4010,20 @@ var LocalReviewData = class {
|
|
|
3942
4010
|
if (!existsSync(this.store.repositoryPath(anchor.repositoryId))) throw unavailableCheckout();
|
|
3943
4011
|
return anchorPins({ pins: anchor }, void 0);
|
|
3944
4012
|
}
|
|
3945
|
-
/** References whose own repository is unregistered or gone from disk.
|
|
4013
|
+
/** References whose own repository is unregistered or gone from disk.
|
|
4014
|
+
* `snapshot` is a stored version. */
|
|
3946
4015
|
async unavailableAnchors(snapshot) {
|
|
3947
4016
|
const missing = /* @__PURE__ */ new Set();
|
|
3948
|
-
for (const
|
|
3949
|
-
|
|
4017
|
+
for (const repositoryId of pinnedRepositoryIds(snapshot.document)) try {
|
|
4018
|
+
if (!existsSync(this.store.repositoryPath(repositoryId))) missing.add(repositoryId);
|
|
3950
4019
|
} catch (error) {
|
|
3951
4020
|
if (!(error instanceof ReviewInputError)) throw error;
|
|
3952
|
-
missing.add(
|
|
4021
|
+
missing.add(repositoryId);
|
|
3953
4022
|
}
|
|
3954
4023
|
if (!missing.size) return [];
|
|
3955
|
-
return
|
|
4024
|
+
return this.storedReferences.get(snapshot).filter((ref) => ref.source.pins && missing.has(ref.source.pins.repositoryId)).map((ref) => ref.id);
|
|
3956
4025
|
}
|
|
4026
|
+
storedReferences = new VersionCache((snapshot) => sourceReferences(snapshot.document, { tolerant: true }), { capacity: 512 });
|
|
3957
4027
|
trackedFiles = /* @__PURE__ */ new Map();
|
|
3958
4028
|
repositories = /* @__PURE__ */ new Map();
|
|
3959
4029
|
readers = /* @__PURE__ */ new Map();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as toolResultText, s as ReviewApiError } from "./agent-client-
|
|
1
|
+
import { a as toolResultText, s as ReviewApiError } from "./agent-client-DHKowVF7.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-
|
|
4
|
-
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure
|
|
3
|
+
import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-CuGm_pVC.js";
|
|
4
|
+
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure--Jih7UeH.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,4 +1,4 @@
|
|
|
1
|
-
import { o as initializeReviewStoreSchema, t as openLocalReviewStore } from "./local-data-
|
|
1
|
+
import { o as initializeReviewStoreSchema, t as openLocalReviewStore } from "./local-data-DcnL0cBy.js";
|
|
2
2
|
import "./review-home-paths-zwevIq4I.js";
|
|
3
3
|
import { A as withFileLock } from "./s3-config-DDWWMh5x.js";
|
|
4
4
|
import { access, mkdir } from "node:fs/promises";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as readReviewPackageVersion } from "./package-paths-BsuI4WUf.js";
|
|
2
|
-
import { a as readReviewServerHealth, l as serverNotReady } from "./server-discovery-
|
|
3
|
-
import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-
|
|
4
|
-
import { t as ensureRemoteLanguageServer } from "./remote-language-server-
|
|
2
|
+
import { a as readReviewServerHealth, l as serverNotReady } from "./server-discovery-BY_MN7tj.js";
|
|
3
|
+
import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-3SrIevG5.js";
|
|
4
|
+
import { t as ensureRemoteLanguageServer } from "./remote-language-server-Chz8NQvC.js";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
import { gt, valid } from "semver";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as ensureRemoteExtensions } from "./remote-extensions-
|
|
1
|
+
import { t as ensureRemoteExtensions } from "./remote-extensions-D_4DSOhO.js";
|
|
2
2
|
export { ensureRemoteExtensions };
|
|
@@ -15,7 +15,7 @@ import yauzl from "yauzl";
|
|
|
15
15
|
//#region src/pinned-download.ts
|
|
16
16
|
const DOWNLOAD_TIMEOUT_MS = 12e4;
|
|
17
17
|
/** Streams `url` into `file` through a temporary file and returns its sha256. */
|
|
18
|
-
async function downloadFile(url, file, {
|
|
18
|
+
async function downloadFile(url, file, { timeoutMs = DOWNLOAD_TIMEOUT_MS, signal } = {}) {
|
|
19
19
|
const { host } = new URL(url);
|
|
20
20
|
const partial = `${file}.${process.pid}.part`;
|
|
21
21
|
let response;
|
|
@@ -27,13 +27,9 @@ async function downloadFile(url, file, { size, timeoutMs = DOWNLOAD_TIMEOUT_MS,
|
|
|
27
27
|
}
|
|
28
28
|
if (!response.ok || !response.body) throw new Error(`${host} answered ${response.status} for ${url}`);
|
|
29
29
|
const hash = createHash("sha256");
|
|
30
|
-
let received = 0;
|
|
31
|
-
const tooLarge = /* @__PURE__ */ new Error(`${url} is larger than its pinned ${size} bytes`);
|
|
32
30
|
try {
|
|
33
31
|
await pipeline(Readable.fromWeb(response.body), async function* (chunks) {
|
|
34
32
|
for await (const chunk of chunks) {
|
|
35
|
-
received += chunk.length;
|
|
36
|
-
if (size !== void 0 && received > size) throw tooLarge;
|
|
37
33
|
hash.update(chunk);
|
|
38
34
|
yield chunk;
|
|
39
35
|
}
|
|
@@ -41,7 +37,6 @@ async function downloadFile(url, file, { size, timeoutMs = DOWNLOAD_TIMEOUT_MS,
|
|
|
41
37
|
await rename(partial, file);
|
|
42
38
|
} catch (error) {
|
|
43
39
|
await rm(partial, { force: true });
|
|
44
|
-
if (error === tooLarge) throw error;
|
|
45
40
|
throw new Error(`Network error downloading from ${host}: ${error instanceof Error ? networkCause(error) : String(error)}`);
|
|
46
41
|
}
|
|
47
42
|
return hash.digest("hex");
|
|
@@ -49,10 +44,7 @@ async function downloadFile(url, file, { size, timeoutMs = DOWNLOAD_TIMEOUT_MS,
|
|
|
49
44
|
/** Leaves a matching `file` in place; otherwise downloads it and checks the pin. */
|
|
50
45
|
async function downloadPinned(pin, file, options = {}) {
|
|
51
46
|
if (await sha256File(file).catch(() => void 0) === pin.sha256) return;
|
|
52
|
-
const actual = await downloadFile(pin.url, file,
|
|
53
|
-
...options,
|
|
54
|
-
size: pin.size
|
|
55
|
-
});
|
|
47
|
+
const actual = await downloadFile(pin.url, file, options);
|
|
56
48
|
if (actual !== pin.sha256) {
|
|
57
49
|
await rm(file, { force: true });
|
|
58
50
|
throw new Error(`Checksum mismatch for ${pin.url}: expected ${pin.sha256}, got ${actual}. The download was deleted.`);
|
|
@@ -73,8 +65,7 @@ const manifestSchema = z.looseObject({
|
|
|
73
65
|
engines: z.looseObject({ vscode: z.string().optional() }).optional()
|
|
74
66
|
});
|
|
75
67
|
/** Unpacks a VSIX's `extension/` payload into `destination`. */
|
|
76
|
-
async function extractVsix(vsix, destination
|
|
77
|
-
let unpacked = 0;
|
|
68
|
+
async function extractVsix(vsix, destination) {
|
|
78
69
|
const zip = await new Promise((resolve, reject) => yauzl.open(vsix, { lazyEntries: true }, (error, opened) => error ? reject(error) : resolve(opened)));
|
|
79
70
|
const openReadStream = (entry) => new Promise((resolve, reject) => zip.openReadStream(entry, (error, stream) => error ? reject(error) : resolve(stream)));
|
|
80
71
|
try {
|
|
@@ -90,8 +81,6 @@ async function extractVsix(vsix, destination, maxBytes = Number.POSITIVE_INFINIT
|
|
|
90
81
|
const mode = entry.externalFileAttributes >>> 16 & 65535;
|
|
91
82
|
if (parts.some((part) => part === ".." || part === "." || part === "" || part.includes(":")) || path.posix.isAbsolute(relative)) throw new Error(`VSIX contains an unsafe path: ${name}`);
|
|
92
83
|
if ((mode & 61440) === 40960) throw new Error(`VSIX contains a symlink: ${name}`);
|
|
93
|
-
unpacked += entry.uncompressedSize;
|
|
94
|
-
if (unpacked > maxBytes) throw new Error(`VSIX unpacks to more than ${maxBytes} bytes`);
|
|
95
84
|
const output = path.join(destination, ...parts);
|
|
96
85
|
await mkdir(path.dirname(output), { recursive: true });
|
|
97
86
|
await pipeline(await openReadStream(entry), createWriteStream(output));
|
|
@@ -127,8 +116,7 @@ const STAMP_FILE = ".curated.json";
|
|
|
127
116
|
const curatedDownloadSchema = z.object({
|
|
128
117
|
universal: z.boolean(),
|
|
129
118
|
url: z.string(),
|
|
130
|
-
sha256: z.string()
|
|
131
|
-
size: z.number()
|
|
119
|
+
sha256: z.string()
|
|
132
120
|
});
|
|
133
121
|
const curatedExtensionSchema = z.object({
|
|
134
122
|
id: z.string(),
|
|
@@ -256,7 +244,7 @@ function requestedGroups(curated, groups, failed) {
|
|
|
256
244
|
async function readPackagedCurated() {
|
|
257
245
|
const file = path.join(findReviewPackageRoot(import.meta.url), "vscode-server", "curated.json");
|
|
258
246
|
const text = await readFile(file, "utf8").catch(() => {
|
|
259
|
-
throw new Error(`This
|
|
247
|
+
throw new Error(`This Whiteboard server has no language server (${file} is missing).`);
|
|
260
248
|
});
|
|
261
249
|
return z.object({ extensions: z.array(curatedExtensionSchema) }).parse(JSON.parse(text)).extensions;
|
|
262
250
|
}
|
|
@@ -278,7 +266,7 @@ async function install(extension, download, directory, stamp, timeoutMs, signal)
|
|
|
278
266
|
recursive: true,
|
|
279
267
|
force: true
|
|
280
268
|
});
|
|
281
|
-
await extractVsix(part, staging
|
|
269
|
+
await extractVsix(part, staging);
|
|
282
270
|
await sanitizeVsixManifest(staging, extension);
|
|
283
271
|
await checkExecutables(staging, extension);
|
|
284
272
|
await writeFile(path.join(staging, STAMP_FILE), `${JSON.stringify(stamp)}\n`);
|