@dev.fast/whiteboard 0.4.1-preview.20261026.139 → 0.4.1-preview.20261027.141

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 (38) hide show
  1. package/dist/{account-alias-DpQNSiaM.js → account-alias-AJ6miBT5.js} +2 -2
  2. package/dist/agent-cli-BDcF54b3.js +2 -0
  3. package/dist/{agent-cli-z_qF_J8n.js → agent-cli-DIC2tBpL.js} +6 -6
  4. package/dist/{agent-client-3980WBdQ.js → agent-client-DyNmSHfO.js} +3 -3
  5. package/dist/{authoring-tools-CphR87Aa.js → authoring-tools-B9MhiKw4.js} +2 -2
  6. package/dist/{background-server-GMGjm8xu.js → background-server-CZaB8zFH.js} +1 -1
  7. package/dist/{background-server-Dq8Zf4OM.js → background-server-DlgbnDVt.js} +2 -2
  8. package/dist/build-info.json +1 -1
  9. package/dist/{cli-BPd7DLd-.js → cli-D7Lpc4ws.js} +1 -1
  10. package/dist/{cli-runner-iHNaGXZg.js → cli-runner-JPkbHD7I.js} +17 -17
  11. package/dist/cli.js +2 -2
  12. package/dist/{fuzzy-match-bbbTSBPK.js → fuzzy-match-rWIeloqo.js} +2 -2
  13. package/dist/{headless-host-BEdTaS2j.js → headless-host-Cn6WDmaL.js} +41 -25
  14. package/dist/{headless-host-CpqwtaaX.js → headless-host-DmuAjcgt.js} +1 -1
  15. package/dist/{import-DG435Ifj.js → import-CUNdl3NP.js} +2 -2
  16. package/dist/{lens-selection-fz59ca6x.js → lens-selection-BQxqiuWY.js} +1 -1
  17. package/dist/{local-data-C4TFet-6.js → local-data-DxkQXCNG.js} +4 -4
  18. package/dist/{mcp-C__btJSK.js → mcp-B154Vpj0.js} +3 -3
  19. package/dist/profile-BLToeYh6.js +2 -0
  20. package/dist/{profile-Bpsilnd7.js → profile-hC1iAoRB.js} +1 -1
  21. package/dist/{remote-attach-BM9FaV1Q.js → remote-attach-DhvNHMe1.js} +3 -3
  22. package/dist/{remote-language-server-c4fdgeA8.js → remote-language-server-zgvAe8wb.js} +1 -1
  23. package/dist/{remote-uninstall-DvBENfrg.js → remote-uninstall-BR-rIuvK.js} +3 -3
  24. package/dist/{request-origin-CtTmXRoS.js → request-origin-BnA7Nnca.js} +3 -3
  25. package/dist/{review-app-launcher-CffrNlrU.js → review-app-launcher-B0Z4B8By.js} +2 -2
  26. package/dist/{review-telemetry-_54CVkjH.js → review-telemetry-yuCLNpDu.js} +2 -2
  27. package/dist/server/desktop-host.js +10 -10
  28. package/dist/{server-discovery-BjelO8cl.js → server-discovery-Dj_xSDSa.js} +1 -1
  29. package/dist/sharing/index.js +1 -1
  30. package/dist/{src-D0h06Qsl.js → src-BJ_MeEmN.js} +6 -1
  31. package/dist/{stored-document-migration-B2Wp1ePB.js → stored-document-migration-fQWLDqDx.js} +2 -2
  32. package/dist/{thread-state-Dbs5siMf.js → thread-state-BburMvgn.js} +1 -1
  33. package/dist/{tool-failure-pgc2CD1C.js → tool-failure-BuvwfVeF.js} +2 -2
  34. package/package.json +4 -4
  35. package/src/review-api/http.ts +46 -31
  36. package/src/review-api/onboarding.ts +29 -2
  37. package/dist/agent-cli-D4JapSBa.js +0 -2
  38. package/dist/profile-DPqMPFYS.js +0 -2
@@ -1,11 +1,11 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { E as ReviewCliInstallStampSchema } from "./src-D0h06Qsl.js";
2
+ import { E as ReviewCliInstallStampSchema } from "./src-BJ_MeEmN.js";
3
3
  import { G as removeAgentTraceHook, H as AGENT_TRACE_HOOK_AGENTS, I as disableAllTraceRepositories, L as enableTraceRepository, Q as readStoreAuth, R as listTraceRepositoryRoots, U as describeTraceHookOwners, W as installHarnessHooks, Y as traceScope, g as disableTraceMachine, h as configureTraceMachine, rt as StoreClient, v as traceMachineEnabled, y as traceMachineStatus, z as traceRepositoryStatus } from "./src-KTjWplV9.js";
4
4
  import { I as writeFileAtomicAsync, L as writePrivateJsonAtomic, N as devReviewHome, j as withFileLock } from "./s3-config-CjcLyFV5.js";
5
5
  import { i as readReviewPackageVersion } from "./package-paths-LcO6HNp_.js";
6
6
  import { n as reviewDesktopStateDir } from "./review-home-paths-CjHB5c8m.js";
7
7
  import { n as isFile, t as isDirectory } from "./fs-utils-BMPLt0cr.js";
8
- import { c as findExecutable, s as executableCommand } from "./fuzzy-match-bbbTSBPK.js";
8
+ import { c as findExecutable, s as executableCommand } from "./fuzzy-match-rWIeloqo.js";
9
9
  import { createHash } from "node:crypto";
10
10
  import { constants } from "node:fs";
11
11
  import { access, chmod, lstat, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
@@ -0,0 +1,2 @@
1
+ import { n as runReviewAgentCli } from "./agent-cli-DIC2tBpL.js";
2
+ export { runReviewAgentCli };
@@ -1,13 +1,13 @@
1
1
  import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
2
2
  import { v as traceMachineEnabled } from "./src-KTjWplV9.js";
3
- import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-3980WBdQ.js";
3
+ import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-DyNmSHfO.js";
4
4
  import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
5
5
  import { n as readBuildCommit } from "./package-paths-LcO6HNp_.js";
6
6
  import "./review-home-paths-CjHB5c8m.js";
7
- import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-BjelO8cl.js";
8
- import { n as reviewSessionAgent } from "./review-telemetry-_54CVkjH.js";
9
- import { a as REVIEW_VIA_HEADER, i as REVIEW_THREAD_HEADER, n as REVIEW_AGENT_HEADER, t as ASK_THREAD_ENV } from "./request-origin-CtTmXRoS.js";
10
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-pgc2CD1C.js";
7
+ import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-Dj_xSDSa.js";
8
+ import { n as reviewSessionAgent } from "./review-telemetry-yuCLNpDu.js";
9
+ import { a as REVIEW_VIA_HEADER, i as REVIEW_THREAD_HEADER, n as REVIEW_AGENT_HEADER, t as ASK_THREAD_ENV } from "./request-origin-BnA7Nnca.js";
10
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-BuvwfVeF.js";
11
11
  import { existsSync } from "node:fs";
12
12
  import path from "node:path";
13
13
  //#region src/review-api/install-update.ts
@@ -44,7 +44,7 @@ async function runReviewAgentCli(input) {
44
44
  [REVIEW_THREAD_HEADER, thread ?? ""]
45
45
  ]);
46
46
  if (mode === "mcp") {
47
- const { serveReviewMcp } = await import("./mcp-C__btJSK.js");
47
+ const { serveReviewMcp } = await import("./mcp-B154Vpj0.js");
48
48
  exitOnInstallUpdate(input.stderr);
49
49
  await serveReviewMcp(async (key, agentKind) => {
50
50
  const connected = await connectReviewInstance(key ? {
@@ -1,7 +1,7 @@
1
1
  import { d as isBooleanValue, f as isNumberValue, m as isStringValue, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import "./src-D0h06Qsl.js";
2
+ import "./src-BJ_MeEmN.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-BjelO8cl.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-Dj_xSDSa.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-GMGjm8xu.js");
262
+ const { ensureServerWithoutDesktop } = await import("./background-server-CZaB8zFH.js");
263
263
  const server = await ensureServerWithoutDesktop({
264
264
  selection,
265
265
  env,
@@ -1,6 +1,6 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { c as activityBeginSchema, l as activityEndSchema, n as uploadSchema, r as commandSchema, u as activityUpdateSchema } from "./local-data-C4TFet-6.js";
3
- import { F as pathTargetSchema, z as publishedEdits } from "./stored-document-migration-B2Wp1ePB.js";
2
+ import { c as activityBeginSchema, l as activityEndSchema, n as uploadSchema, r as commandSchema, u as activityUpdateSchema } from "./local-data-DxkQXCNG.js";
3
+ import { F as pathTargetSchema, z as publishedEdits } from "./stored-document-migration-fQWLDqDx.js";
4
4
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
5
5
  import { t as findReviewPackageRoot } from "./package-paths-LcO6HNp_.js";
6
6
  import { z } from "zod";
@@ -1,2 +1,2 @@
1
- import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-Dq8Zf4OM.js";
1
+ import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-DlgbnDVt.js";
2
2
  export { ensureBackgroundServer, ensureServerWithoutDesktop, headlessServerOwner, stopBackgroundServer };
@@ -1,8 +1,8 @@
1
1
  import "./src-KTjWplV9.js";
2
2
  import { D as liveLockOwner, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
3
3
  import { t as findReviewPackageRoot } from "./package-paths-LcO6HNp_.js";
4
- import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-BjelO8cl.js";
5
- import { t as desktopApplicationInstalled } from "./review-app-launcher-CffrNlrU.js";
4
+ import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-Dj_xSDSa.js";
5
+ import { t as desktopApplicationInstalled } from "./review-app-launcher-B0Z4B8By.js";
6
6
  import { mkdir, open, readFile, realpath, stat } from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import { spawn } from "node:child_process";
@@ -1 +1 @@
1
- {"version":"0.4.1-preview.20261026.139","commit":"07b9f3b0f8794c4dcb31d77c9fda8be928df33bf","dirty":true,"builtAt":"2026-10-26T21:39:51.114Z"}
1
+ {"version":"0.4.1-preview.20261027.141","commit":"27c5ce9a6af4a118a675105249b81e9a930e0ed3","dirty":true,"builtAt":"2026-10-27T00:03:42.445Z"}
@@ -1,4 +1,4 @@
1
- import { r as connectReviewApi } from "./agent-client-3980WBdQ.js";
1
+ import { r as connectReviewApi } from "./agent-client-DyNmSHfO.js";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { z } from "zod";
4
4
  //#region src/sharing/cli.ts
@@ -1,19 +1,19 @@
1
1
  import { D as __commonJSMin, E as setLocalVcsCommandObserver, O as __require, k as __toESM } from "./src-BTCRHmRM.js";
2
2
  import { c as jsonString, n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import { S as REVIEW_REMOTE_ATTACH_END, b as REVIEW_REMOTE_AGENT_IDS, h as REVIEW_CLI_INSTALL_TARGET_LABELS, l as boardTitle, x as REVIEW_REMOTE_ATTACH_BEGIN } from "./src-D0h06Qsl.js";
3
+ import { S as REVIEW_REMOTE_ATTACH_END, b as REVIEW_REMOTE_AGENT_IDS, h as REVIEW_CLI_INSTALL_TARGET_LABELS, l as boardTitle, x as REVIEW_REMOTE_ATTACH_BEGIN } from "./src-BJ_MeEmN.js";
4
4
  import { $ as runStoreLogin, A as loadS3TraceStorage, B as readTraceUserConfig, C as runTraceDeny, D as runTraceStoreInfo, E as runTraceStoreDelete, F as resolveTraceRepositoryTarget, J as traceHomeDir, K as resolveTraceCommand, M as selectTraceStorage, O as describeSelection, P as requireTraceConsent, Q as readStoreAuth, S as runTraceAllow, T as runTraceSessions, V as HOSTED_CAPTURE_SCOPE_DESCRIPTION, X as DEFAULT_STORE_ORIGIN, Y as traceScope, _ as readLegacyCaptureSettings, a as runTracePull$1, at as emitJsonEvent, c as runTraceEnable, ct as jsonRequestedInArgv, d as runTraceStatus, et as runStoreLogout, f as runTraceSync, i as runTraceList$1, it as withStoreAuthorization, l as runTraceInstallMachine, m as runTraceHook, n as resolveTraceReadStorage, nt as StoreApiError, o as runTraceShow, ot as failWithJsonError, p as runTraceGitHook, r as runTraceBlame, rt as StoreClient, s as runTraceDisable, st as humanStream, t as registerTraceCommands, tt as runStoreWhoami, u as runTraceRepair, v as traceMachineEnabled, w as runTraceOnboard, y as traceMachineStatus, z as traceRepositoryStatus } from "./src-KTjWplV9.js";
5
- import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-3980WBdQ.js";
5
+ import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-DyNmSHfO.js";
6
6
  import { C as s3ProfileSchema, E as writeTraceConfigFile, N as devReviewHome, P as normalizeStoreOrigin, S as readTraceConfigFile, T as sameS3Profile, _ as emptyTraceConfig, c as resolveS3Setup, g as currentStore, h as TraceConfigurationError, i as isS3MockMode, n as clearTraceEnvCache, o as readTraceEnvFile, p as traceSettingsPath, w as s3Store } from "./s3-config-CjcLyFV5.js";
7
7
  import { t as errorMessage } from "./error-message-OtiDonty.js";
8
8
  import { i as readReviewPackageVersion, r as readBuildInfo, t as findReviewPackageRoot } from "./package-paths-LcO6HNp_.js";
9
9
  import { t as resolveReviewRoot } from "./runtime-5WG8rRgg.js";
10
10
  import "./review-home-paths-CjHB5c8m.js";
11
- 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-BjelO8cl.js";
12
- import { t as ReviewTelemetry } from "./review-telemetry-_54CVkjH.js";
13
- import { t as fuzzyRank } from "./fuzzy-match-bbbTSBPK.js";
14
- 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-DpQNSiaM.js";
15
- import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-CffrNlrU.js";
16
- import { t as reviewAgentCliHelp } from "./agent-cli-z_qF_J8n.js";
11
+ 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-Dj_xSDSa.js";
12
+ import { t as ReviewTelemetry } from "./review-telemetry-yuCLNpDu.js";
13
+ import { t as fuzzyRank } from "./fuzzy-match-rWIeloqo.js";
14
+ 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-AJ6miBT5.js";
15
+ import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-B0Z4B8By.js";
16
+ import { t as reviewAgentCliHelp } from "./agent-cli-DIC2tBpL.js";
17
17
  import { existsSync, mkdirSync, renameSync, writeFileSync } from "node:fs";
18
18
  import { realpath } from "node:fs/promises";
19
19
  import path from "node:path";
@@ -4334,7 +4334,7 @@ async function runReviewCli(input) {
4334
4334
  if (!Number.isInteger(port) || port < 0 || port > 65535) throw new ReviewCliUsageError("--port must be an integer between 0 and 65535.");
4335
4335
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4336
4336
  if (options.detach) {
4337
- const { ensureBackgroundServer } = await import("./background-server-GMGjm8xu.js");
4337
+ const { ensureBackgroundServer } = await import("./background-server-CZaB8zFH.js");
4338
4338
  const { discovery, started } = await ensureBackgroundServer({
4339
4339
  stateDir,
4340
4340
  env,
@@ -4356,7 +4356,7 @@ async function runReviewCli(input) {
4356
4356
  process.once("SIGINT", stop);
4357
4357
  process.once("SIGTERM", stop);
4358
4358
  process.once(DESKTOP_TAKEOVER_SIGNAL, takeover);
4359
- const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-CpqwtaaX.js");
4359
+ const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-DmuAjcgt.js");
4360
4360
  try {
4361
4361
  await runHeadlessServer({
4362
4362
  stateDir,
@@ -4393,7 +4393,7 @@ async function runReviewCli(input) {
4393
4393
  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) => {
4394
4394
  const options = command.optsWithGlobals();
4395
4395
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4396
- const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-GMGjm8xu.js");
4396
+ const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-CZaB8zFH.js");
4397
4397
  const owner = await headlessServerOwner(stateDir);
4398
4398
  const discovery = await readReviewServerDiscovery(stateDir);
4399
4399
  if (owner === void 0) {
@@ -4421,7 +4421,7 @@ async function runReviewCli(input) {
4421
4421
  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.`);
4422
4422
  const inUse = `A Whiteboard server is using ${stateDir}. Stop it first, then run whiteboard server reset-id again.`;
4423
4423
  if (await desktopUsesHome(stateDir, env)) return refuse(inUse, options.json);
4424
- const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-DPqMPFYS.js"), import("./headless-host-CpqwtaaX.js")]);
4424
+ const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-BLToeYh6.js"), import("./headless-host-DmuAjcgt.js")]);
4425
4425
  const reset = await withHeadlessServerLock(await realpath(stateDir), async () => {
4426
4426
  const local = await openReviewProfile(stateDir, { manageWorkspaces: false });
4427
4427
  try {
@@ -4443,7 +4443,7 @@ async function runReviewCli(input) {
4443
4443
  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) => {
4444
4444
  const options = command.optsWithGlobals();
4445
4445
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4446
- const { remoteAttach } = await import("./remote-attach-BM9FaV1Q.js");
4446
+ const { remoteAttach } = await import("./remote-attach-DhvNHMe1.js");
4447
4447
  let attach;
4448
4448
  try {
4449
4449
  attach = await remoteAttach({
@@ -4485,7 +4485,7 @@ async function runReviewCli(input) {
4485
4485
  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) => {
4486
4486
  const options = command.optsWithGlobals();
4487
4487
  const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
4488
- const { remoteUninstall } = await import("./remote-uninstall-DvBENfrg.js");
4488
+ const { remoteUninstall } = await import("./remote-uninstall-BR-rIuvK.js");
4489
4489
  let deleteReviews = options.deleteReviews ? true : options.keepReviews ? false : void 0;
4490
4490
  if (deleteReviews === void 0 && !options.json && input.stdin?.isTTY) {
4491
4491
  const prompt = createInterface$1({
@@ -4707,14 +4707,14 @@ async function runReviewCli(input) {
4707
4707
  command.showHelpAfterError(false).error("Markdown review migration is no longer supported. Ask your agent to migrate your old Whiteboard reviews.");
4708
4708
  });
4709
4709
  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) => {
4710
- const { runShareCli } = await import("./cli-BPd7DLd-.js");
4710
+ const { runShareCli } = await import("./cli-D7Lpc4ws.js");
4711
4711
  state.exitCode = await runShareCli({
4712
4712
  ...input,
4713
4713
  ...options,
4714
4714
  env: authoringEnv()
4715
4715
  });
4716
4716
  }).command("revoke <share-id>").description("Revoke future downloads of a share"), "plain").action(async (shareId, options) => {
4717
- const { runShareCli } = await import("./cli-BPd7DLd-.js");
4717
+ const { runShareCli } = await import("./cli-D7Lpc4ws.js");
4718
4718
  state.exitCode = await runShareCli({
4719
4719
  ...input,
4720
4720
  ...options,
@@ -4795,7 +4795,7 @@ async function runReviewCli(input) {
4795
4795
  return commands;
4796
4796
  } });
4797
4797
  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) => {
4798
- const { runReviewAgentCli } = await import("./agent-cli-D4JapSBa.js");
4798
+ const { runReviewAgentCli } = await import("./agent-cli-BDcF54b3.js");
4799
4799
  state.exitCode = await runReviewAgentCli({
4800
4800
  ...input,
4801
4801
  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-D0h06Qsl.js";
3
+ import "./src-BJ_MeEmN.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-iHNaGXZg.js");
20
+ const { runReviewCli } = await import("./cli-runner-JPkbHD7I.js");
21
21
  return runReviewCli({
22
22
  argv,
23
23
  cliPaths: {
@@ -1,7 +1,7 @@
1
1
  import "./src-KTjWplV9.js";
2
2
  import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
3
- import { n as askAgentIds } from "./thread-state-Dbs5siMf.js";
4
- import { t as ASK_THREAD_ENV } from "./request-origin-CtTmXRoS.js";
3
+ import { n as askAgentIds } from "./thread-state-BburMvgn.js";
4
+ import { t as ASK_THREAD_ENV } from "./request-origin-BnA7Nnca.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,23 +1,23 @@
1
1
  import { b as resolveRepoContext, d as git, r as defaultBranch, w as runVcs } from "./src-BTCRHmRM.js";
2
2
  import { c as jsonString, m as isStringValue, n as isJsonObject, p as isObjectValue, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import { _ as readBoundedStream, a as verifyShareRepository, c as exportShare, d as legacyModeSchema, f as lensReport, g as StreamLimitError, h as uncategorizedReport, i as readShareRepository, l as referenceCommits, m as reviewProgress, n as sharedReviewId, o as ShareAuthError, p as progressUpdateSchema, s as ShareClient, u as validateShareSources, v as parseShareLink, y as shareIdSchema } from "./import-DG435Ifj.js";
4
- import { d as invalidateStructuralComparisons, f as diffrExecutable, i as inspectSnapshot, m as readGitHubPullRequests, p as diffrMissingError, r as commandSchema } from "./local-data-C4TFet-6.js";
5
- import { I as decodeStructuralDiffEvent, N as reviewDiffrLoginsSchema, O as ReviewFeedbackContactSchema, P as reviewDiffrSummarizerInputSchema, a as parseReviewVerbRequest, c as boardIconKind, i as parseReviewDesktopVerbResult, j as ReviewOnboardingRunRequestSchema, k as ReviewFeedbackSchema, l as boardTitle, m as REVIEW_CLIENT_REMOTE, p as REVIEW_CLIENT_HEADER, y as REVIEW_HOST_HEADER } from "./src-D0h06Qsl.js";
3
+ import { _ as readBoundedStream, a as verifyShareRepository, c as exportShare, d as legacyModeSchema, f as lensReport, g as StreamLimitError, h as uncategorizedReport, i as readShareRepository, l as referenceCommits, m as reviewProgress, n as sharedReviewId, o as ShareAuthError, p as progressUpdateSchema, s as ShareClient, u as validateShareSources, v as parseShareLink, y as shareIdSchema } from "./import-CUNdl3NP.js";
4
+ import { d as invalidateStructuralComparisons, f as diffrExecutable, i as inspectSnapshot, m as readGitHubPullRequests, p as diffrMissingError, r as commandSchema } from "./local-data-DxkQXCNG.js";
5
+ import { I as decodeStructuralDiffEvent, N as reviewDiffrLoginsSchema, O as ReviewFeedbackContactSchema, P as reviewDiffrSummarizerInputSchema, a as parseReviewVerbRequest, c as boardIconKind, i as parseReviewDesktopVerbResult, j as ReviewOnboardingRunRequestSchema, k as ReviewFeedbackSchema, l as boardTitle, m as REVIEW_CLIENT_REMOTE, p as REVIEW_CLIENT_HEADER, y as REVIEW_HOST_HEADER } from "./src-BJ_MeEmN.js";
6
6
  import { $ as runStoreLogin, M as selectTraceStorage, N as TraceStorageDeniedError, Q as readStoreAuth, X as DEFAULT_STORE_ORIGIN, Z as clearStoreAuth, b as listReviewTraceSessions, j as resolveTraceStorage, k as isTraceStorageConfigured, q as shellQuote, v as traceMachineEnabled, x as loadReviewAgentTrace } from "./src-KTjWplV9.js";
7
- import { _ as scopedCoverage, s as formatAnchor, u as selectionKey } from "./lens-selection-fz59ca6x.js";
8
- import { N as elements, O as boardLinks, Q as stepSources, f as sourceBranchName, k as boardRepositoryId, l as pullRequestKey, p as pullRequestProvider, q as selectionReferences, w as anchorPins } from "./stored-document-migration-B2Wp1ePB.js";
7
+ import { _ as scopedCoverage, s as formatAnchor, u as selectionKey } from "./lens-selection-BQxqiuWY.js";
8
+ import { N as elements, O as boardLinks, Q as stepSources, f as sourceBranchName, k as boardRepositoryId, l as pullRequestKey, p as pullRequestProvider, q as selectionReferences, w as anchorPins } from "./stored-document-migration-fQWLDqDx.js";
9
9
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
10
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
12
  import { i as readReviewPackageVersion, n as readBuildCommit, t as findReviewPackageRoot } from "./package-paths-LcO6HNp_.js";
13
13
  import "./review-home-paths-CjHB5c8m.js";
14
- import { _ as reviewInstanceIdentity, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-BjelO8cl.js";
15
- 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-Dbs5siMf.js";
16
- import { t as openReviewProfile } from "./profile-Bpsilnd7.js";
17
- 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-CtTmXRoS.js";
18
- 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-bbbTSBPK.js";
19
- import { a as inspectQuerySchema, i as renderInstructions, o as queryAnchor, r as instructionsQuerySchema, s as readQuerySchemas, t as authoringTools } from "./authoring-tools-CphR87Aa.js";
20
- import { a as headlessServerOwner, c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-Dq8Zf4OM.js";
14
+ import { _ as reviewInstanceIdentity, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-Dj_xSDSa.js";
15
+ 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-BburMvgn.js";
16
+ import { t as openReviewProfile } from "./profile-hC1iAoRB.js";
17
+ 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-BnA7Nnca.js";
18
+ 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-rWIeloqo.js";
19
+ import { a as inspectQuerySchema, i as renderInstructions, o as queryAnchor, r as instructionsQuerySchema, s as readQuerySchemas, t as authoringTools } from "./authoring-tools-B9MhiKw4.js";
20
+ import { a as headlessServerOwner, c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-DlgbnDVt.js";
21
21
  import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
22
22
  import { z } from "zod";
23
23
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
@@ -3034,7 +3034,8 @@ async function recentFolders(input = {}) {
3034
3034
  //#region src/review-api/onboarding.ts
3035
3035
  const COMMAND_TIMEOUT_MS = 15e3;
3036
3036
  const PULL_REQUEST_LIMIT = 10;
3037
- /** Ignored when the agent does not offer the model. */
3037
+ /** Where the reader picks nothing; ignored when the agent does not offer
3038
+ * the model. */
3038
3039
  const RUN_PICKS = {
3039
3040
  claude: { model: "sonnet" },
3040
3041
  codex: { model: "gpt-6-luna" }
@@ -3285,6 +3286,14 @@ async function runContext(ask, agent, threadId, reviewId) {
3285
3286
  * it, and start an agent drawing it in its Ask panel. */
3286
3287
  function registerOnboardingRoutes(app, store, ask, host, run = runCommand) {
3287
3288
  app.get("/onboarding/agents", async (context) => context.json({ agents: await ask.agents() }));
3289
+ app.get("/onboarding/agents/:agent/offer", async (context) => {
3290
+ const agent = z.enum(askAgentIds).parse(context.req.param("agent"));
3291
+ const { path: directory, model } = z.object({
3292
+ path: z.string().min(1),
3293
+ model: askPicksSchema.shape.model
3294
+ }).parse(context.req.query());
3295
+ return context.json({ offer: await host.offer(agent, model ?? RUN_PICKS[agent]?.model, async () => directory) });
3296
+ });
3288
3297
  app.get("/onboarding/projects", async (context) => context.json({ projects: await onboardingProjects([...store.repositories().map((repository) => repository.path), ...await recentFolders()], { run }) }));
3289
3298
  app.get("/onboarding/targets", async (context) => {
3290
3299
  const directory = context.req.query("path");
@@ -3345,7 +3354,10 @@ function registerOnboardingRoutes(app, store, ask, host, run = runCommand) {
3345
3354
  head,
3346
3355
  selection: { title },
3347
3356
  context: await runContext(ask, input.agent, id, reviewId),
3348
- picks: RUN_PICKS[input.agent],
3357
+ picks: {
3358
+ ...RUN_PICKS[input.agent],
3359
+ ...input.picks
3360
+ },
3349
3361
  question: { text: input.prompt }
3350
3362
  });
3351
3363
  host.handOff(reviewId, id);
@@ -4133,27 +4145,31 @@ function createReviewApi(store, data, open, shared, capabilities = () => ({
4133
4145
  await selectionContext(reviewId, selection, version)
4134
4146
  ].join("\n");
4135
4147
  };
4148
+ const askOffer = async (agent, model, cwd) => {
4149
+ const stored = store.askHistory.offer(agent);
4150
+ const last = stored && Object.keys(stored.choices).length ? stored : void 0;
4151
+ const models = last?.choices.model;
4152
+ const another = model !== void 0 && model !== models?.current && (!models || models.options.some((option) => option.value === model));
4153
+ const known = another ? store.askHistory.offer(agent, model) : last;
4154
+ if (known) return known;
4155
+ const offer = await ask.threads.offered(agent, await cwd(), another ? model : void 0);
4156
+ if (last) store.askHistory.saveModelOffer(agent, offer);
4157
+ else store.askHistory.saveOffer(agent, offer);
4158
+ return offer;
4159
+ };
4136
4160
  registerOnboardingRoutes(app, store, ask, {
4137
4161
  register: (root) => data.register(root),
4138
4162
  historyHooks,
4139
4163
  handOff,
4140
- open: openCreated
4164
+ open: openCreated,
4165
+ offer: askOffer
4141
4166
  });
4142
4167
  app.get("/ask/working", (context) => context.json({ agents: ask.threads.working() }));
4143
4168
  app.get("/:id/ask/agents", async (context) => context.json({ agents: await ask.agents() }));
4144
4169
  app.get("/:id/ask/agents/:agent/offer", async (context) => {
4145
4170
  const agent = z.enum(askAgentIds).parse(context.req.param("agent"));
4146
4171
  const { model } = askOfferQuerySchema.parse(context.req.query());
4147
- const stored = store.askHistory.offer(agent);
4148
- const last = stored && Object.keys(stored.choices).length ? stored : void 0;
4149
- const models = last?.choices.model;
4150
- const another = model !== void 0 && model !== models?.current && (!models || models.options.some((option) => option.value === model));
4151
- const known = another ? store.askHistory.offer(agent, model) : last;
4152
- if (known) return context.json({ offer: known });
4153
- const checkout = await data.agentCheckout(readReview(context.req.param("id")));
4154
- const offer = await ask.threads.offered(agent, checkout.rootPath, another ? model : void 0);
4155
- if (last) store.askHistory.saveModelOffer(agent, offer);
4156
- else store.askHistory.saveOffer(agent, offer);
4172
+ const offer = await askOffer(agent, model, async () => (await data.agentCheckout(readReview(context.req.param("id")))).rootPath);
4157
4173
  return context.json({ offer });
4158
4174
  });
4159
4175
  app.get("/:id/ask/mentions", async (context) => {
@@ -1,2 +1,2 @@
1
- import { i as withHeadlessServerLock, n as runHeadlessServer, r as takeOverServerHome, t as HeadlessServerBusyError } from "./headless-host-BEdTaS2j.js";
1
+ import { i as withHeadlessServerLock, n as runHeadlessServer, r as takeOverServerHome, t as HeadlessServerBusyError } from "./headless-host-Cn6WDmaL.js";
2
2
  export { HeadlessServerBusyError, runHeadlessServer, takeOverServerHome, withHeadlessServerLock };
@@ -1,7 +1,7 @@
1
1
  import { f as gitAt } from "./src-BTCRHmRM.js";
2
2
  import { u as parseJsonText } from "./src-X9phtB2j.js";
3
- import { _ as scopedCoverage, b as unionIntervals, f as sourceAnchors, h as emptyCoverage, i as anchorSelection, l as resolveDiffSelection, m as coverageSources, n as SelectionUnavailableError, o as comparisonKey, u as selectionKey, v as sourcesForFile, y as subtractIntervals } from "./lens-selection-fz59ca6x.js";
4
- import { $ as UNCATEGORIZED_LENS_ID, B as readsAtBoardPins, H as resourceReferences, J as sourceReferences, N as elements, R as pinsSchema, V as resourceReference, X as checkReferences, b as textIncludesQuote, c as traceSchema, dt as parseMarkdown, j as documentSchema, k as boardRepositoryId, lt as markdownNodes, n as migrateStoredDocument, nt as lensSchema, ot as fileLineRangeSchema, q as selectionReferences, r as migrateStoredLenses, rt as lensSelections, s as softwareModelDataSchema, t as liftFileLenses, u as pullRequestUrl, w as anchorPins, x as textualRows } from "./stored-document-migration-B2Wp1ePB.js";
3
+ import { _ as scopedCoverage, b as unionIntervals, f as sourceAnchors, h as emptyCoverage, i as anchorSelection, l as resolveDiffSelection, m as coverageSources, n as SelectionUnavailableError, o as comparisonKey, u as selectionKey, v as sourcesForFile, y as subtractIntervals } from "./lens-selection-BQxqiuWY.js";
4
+ import { $ as UNCATEGORIZED_LENS_ID, B as readsAtBoardPins, H as resourceReferences, J as sourceReferences, N as elements, R as pinsSchema, V as resourceReference, X as checkReferences, b as textIncludesQuote, c as traceSchema, dt as parseMarkdown, j as documentSchema, k as boardRepositoryId, lt as markdownNodes, n as migrateStoredDocument, nt as lensSchema, ot as fileLineRangeSchema, q as selectionReferences, r as migrateStoredLenses, rt as lensSelections, s as softwareModelDataSchema, t as liftFileLenses, u as pullRequestUrl, w as anchorPins, x as textualRows } from "./stored-document-migration-fQWLDqDx.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,4 +1,4 @@
1
- import "./src-D0h06Qsl.js";
1
+ import "./src-BJ_MeEmN.js";
2
2
  import { z } from "zod";
3
3
  //#region src/viewed-coverage.ts
4
4
  const coverageSchema = z.object({
@@ -1,15 +1,15 @@
1
1
  import { S as splitGitPatchFiles, T as runVcsSync, _ as listTrackedFilesAtCommit, a as diff, b as resolveRepoContext, c as diffFileSummariesWorkingTree, d as git, f as gitAt, g as listCommitRange, h as jjRevisionIsConflicted, i as detectLocalVcs, l as diffTrees, m as gitCommonDirSync, n as createBlobBatchReader, p as gitCommonDir, s as diffFileSummariesTrees, t as LocalVcsToolsMissingError, u as diffWorkingTree, v as parseGitRemote, w as runVcs, x as resolveRevision, y as readFileAtCommit } from "./src-BTCRHmRM.js";
2
2
  import { c as jsonString, m as isStringValue, n as isJsonObject, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
3
- import { F as applyStructuralUpdate, I as decodeStructuralDiffEvent, L as structuralChangeCounts, c as boardIconKind, l as boardTitle } from "./src-D0h06Qsl.js";
3
+ import { F as applyStructuralUpdate, I as decodeStructuralDiffEvent, L as structuralChangeCounts, c as boardIconKind, l as boardTitle } from "./src-BJ_MeEmN.js";
4
4
  import "./src-KTjWplV9.js";
5
- import { b as unionIntervals, c as parseAnchor, f as sourceAnchors, g as intersectIntervals, h as emptyCoverage, p as coverageSchema, x as updateCoverage, y as subtractIntervals } from "./lens-selection-fz59ca6x.js";
6
- import { A as commitLinkCommits, C as adoptFlowUnits, D as assignMissingIds, E as assignFreshIds, G as respellEditLinks, H as resourceReferences, I as pinDocumentReferences, J as sourceReferences, K as reviewTargetSchema, L as pinnedRepositoryIds, M as editSchema, N as elements, O as boardLinks, P as explicitPins, R as pinsSchema, S as parseUnifiedPatch, T as applyEdit, U as respellCommitLinks, V as resourceReference, W as respellDocumentLinks, X as checkReferences, Y as summarizeEdit, Z as documentAdvice, _ as fetchPullRequest, a as SoftwareModelValidationError, at as checkSourcePath, b as textIncludesQuote, c as traceSchema, ct as sliceSourceRange, d as setPullRequest, dt as parseMarkdown, et as applyLensEdit, f as sourceBranchName, g as defaultPullRequestDeps, h as GitHubRefusedRead, i as readStoredDocument, it as SourceRangeError, j as documentSchema, k as boardRepositoryId, l as pullRequestKey, lt as markdownNodes, m as resolvePullRequest, n as migrateStoredDocument, o as defineSoftwareMap, ot as fileLineRangeSchema, r as migrateStoredLenses, rt as lensSelections, st as requireVisibleSource, tt as lensEditSchema, u as pullRequestUrl, ut as markdownText, v as remoteUrls, w as anchorPins, x as textualRows, y as azureRepositoryOf } from "./stored-document-migration-B2Wp1ePB.js";
5
+ import { b as unionIntervals, c as parseAnchor, f as sourceAnchors, g as intersectIntervals, h as emptyCoverage, p as coverageSchema, x as updateCoverage, y as subtractIntervals } from "./lens-selection-BQxqiuWY.js";
6
+ import { A as commitLinkCommits, C as adoptFlowUnits, D as assignMissingIds, E as assignFreshIds, G as respellEditLinks, H as resourceReferences, I as pinDocumentReferences, J as sourceReferences, K as reviewTargetSchema, L as pinnedRepositoryIds, M as editSchema, N as elements, O as boardLinks, P as explicitPins, R as pinsSchema, S as parseUnifiedPatch, T as applyEdit, U as respellCommitLinks, V as resourceReference, W as respellDocumentLinks, X as checkReferences, Y as summarizeEdit, Z as documentAdvice, _ as fetchPullRequest, a as SoftwareModelValidationError, at as checkSourcePath, b as textIncludesQuote, c as traceSchema, ct as sliceSourceRange, d as setPullRequest, dt as parseMarkdown, et as applyLensEdit, f as sourceBranchName, g as defaultPullRequestDeps, h as GitHubRefusedRead, i as readStoredDocument, it as SourceRangeError, j as documentSchema, k as boardRepositoryId, l as pullRequestKey, lt as markdownNodes, m as resolvePullRequest, n as migrateStoredDocument, o as defineSoftwareMap, ot as fileLineRangeSchema, r as migrateStoredLenses, rt as lensSelections, st as requireVisibleSource, tt as lensEditSchema, u as pullRequestUrl, ut as markdownText, v as remoteUrls, w as anchorPins, x as textualRows, y as azureRepositoryOf } from "./stored-document-migration-fQWLDqDx.js";
7
7
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
8
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 { s as safeStorageSegment } from "./review-home-paths-CjHB5c8m.js";
11
11
  import { r as isMissingFileError } from "./fs-utils-BMPLt0cr.js";
12
- import { a as askHistoryEntrySchema, i as askEntrySchema, o as askOfferSchema, s as askPermissionsSchema } from "./thread-state-Dbs5siMf.js";
12
+ import { a as askHistoryEntrySchema, i as askEntrySchema, o as askOfferSchema, s as askPermissionsSchema } from "./thread-state-BburMvgn.js";
13
13
  import { createRequire } from "node:module";
14
14
  import crypto, { createHash, randomUUID } from "node:crypto";
15
15
  import { z } from "zod";
@@ -1,8 +1,8 @@
1
1
  import { n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { a as toolResultText, s as ReviewApiError, t as ToolText } from "./agent-client-3980WBdQ.js";
2
+ import { a as toolResultText, s as ReviewApiError, t as ToolText } from "./agent-client-DyNmSHfO.js";
3
3
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
4
- import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-CphR87Aa.js";
5
- import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-pgc2CD1C.js";
4
+ import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-B9MhiKw4.js";
5
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-BuvwfVeF.js";
6
6
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
7
7
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
8
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
@@ -0,0 +1,2 @@
1
+ import { t as openReviewProfile } from "./profile-hC1iAoRB.js";
2
+ export { openReviewProfile };
@@ -1,4 +1,4 @@
1
- import { a as projectOfCheckout, h as CheckoutGroups, o as groupCheckoutsAhead, s as initializeReviewStoreSchema, t as openLocalReviewStore } from "./local-data-C4TFet-6.js";
1
+ import { a as projectOfCheckout, h as CheckoutGroups, o as groupCheckoutsAhead, s as initializeReviewStoreSchema, t as openLocalReviewStore } from "./local-data-DxkQXCNG.js";
2
2
  import "./src-KTjWplV9.js";
3
3
  import { j as withFileLock } from "./s3-config-CjcLyFV5.js";
4
4
  import { access, mkdir } from "node:fs/promises";
@@ -1,7 +1,7 @@
1
1
  import { i as readReviewPackageVersion } from "./package-paths-LcO6HNp_.js";
2
- import { a as readReviewServerHealth, l as serverNotReady } from "./server-discovery-BjelO8cl.js";
3
- import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-Dq8Zf4OM.js";
4
- import { t as ensureRemoteLanguageServer } from "./remote-language-server-c4fdgeA8.js";
2
+ import { a as readReviewServerHealth, l as serverNotReady } from "./server-discovery-Dj_xSDSa.js";
3
+ import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-DlgbnDVt.js";
4
+ import { t as ensureRemoteLanguageServer } from "./remote-language-server-zgvAe8wb.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 "./src-KTjWplV9.js";
2
2
  import { A as processStartIdentity, j as withFileLock } from "./s3-config-CjcLyFV5.js";
3
3
  import { t as findReviewPackageRoot } from "./package-paths-LcO6HNp_.js";
4
- import { n as cliSpawn, s as spawnDetached } from "./background-server-Dq8Zf4OM.js";
4
+ import { n as cliSpawn, s as spawnDetached } from "./background-server-DlgbnDVt.js";
5
5
  import { r as remoteServerPaths, t as ensureRemoteExtensions } from "./remote-extensions-DMKyDjAs.js";
6
6
  import { randomBytes } from "node:crypto";
7
7
  import { z } from "zod";
@@ -1,9 +1,9 @@
1
- import { C as REVIEW_REMOTE_INSTALL_LOCK, w as REVIEW_REMOTE_WRAPPER_MARK } from "./src-D0h06Qsl.js";
1
+ import { C as REVIEW_REMOTE_INSTALL_LOCK, w as REVIEW_REMOTE_WRAPPER_MARK } from "./src-BJ_MeEmN.js";
2
2
  import { M as DEV_REVIEW_HOME_ENV } from "./s3-config-CjcLyFV5.js";
3
3
  import "./review-home-paths-CjHB5c8m.js";
4
- import { c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-Dq8Zf4OM.js";
4
+ import { c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-DlgbnDVt.js";
5
5
  import { i as whiteboardRemoteHome } from "./remote-extensions-DMKyDjAs.js";
6
- import { n as remoteLanguageServerGroups, r as stopProcessGroup } from "./remote-language-server-c4fdgeA8.js";
6
+ import { n as remoteLanguageServerGroups, r as stopProcessGroup } from "./remote-language-server-zgvAe8wb.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";
@@ -1,7 +1,7 @@
1
1
  import { a as jsonNumber, c as jsonString, i as jsonBoolean, n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { _ as REVIEW_DIFF_LAYOUTS, g as REVIEW_COLOR_THEME_KINDS, v as REVIEW_DIFF_LAYOUT_SCOPES } from "./src-D0h06Qsl.js";
3
- import { t as SELECTION_UNAVAILABLE_REASONS } from "./lens-selection-fz59ca6x.js";
4
- import { n as askAgentIds } from "./thread-state-Dbs5siMf.js";
2
+ import { _ as REVIEW_DIFF_LAYOUTS, g as REVIEW_COLOR_THEME_KINDS, v as REVIEW_DIFF_LAYOUT_SCOPES } from "./src-BJ_MeEmN.js";
3
+ import { t as SELECTION_UNAVAILABLE_REASONS } from "./lens-selection-BQxqiuWY.js";
4
+ import { n as askAgentIds } from "./thread-state-BburMvgn.js";
5
5
  import { z } from "zod";
6
6
  //#region src/telemetry-clean-text.ts
7
7
  const USER_DATA_REGEXES = [
@@ -1,5 +1,5 @@
1
- import { o as parseReviewVerbResponse } from "./src-D0h06Qsl.js";
2
- import { b as selectReviewInstance, m as healthyReviewInstance, v as reviewInstanceStartHint, y as reviewInstanceUnavailable } from "./server-discovery-BjelO8cl.js";
1
+ import { o as parseReviewVerbResponse } from "./src-BJ_MeEmN.js";
2
+ import { b as selectReviewInstance, m as healthyReviewInstance, v as reviewInstanceStartHint, y as reviewInstanceUnavailable } from "./server-discovery-Dj_xSDSa.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,10 +1,10 @@
1
1
  import { c as jsonString, l as jsonValueSchema, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import "./src-D0h06Qsl.js";
2
+ import "./src-BJ_MeEmN.js";
3
3
  import "./src-KTjWplV9.js";
4
4
  import { F as writeFileAtomic, N as devReviewHome, j as withFileLock, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
5
5
  import { i as readReviewPackageVersion, t as findReviewPackageRoot } from "./package-paths-LcO6HNp_.js";
6
6
  import "./review-home-paths-CjHB5c8m.js";
7
- import "./request-origin-CtTmXRoS.js";
7
+ import "./request-origin-BnA7Nnca.js";
8
8
  import { createHmac, randomUUID } from "node:crypto";
9
9
  import { z } from "zod";
10
10
  import { existsSync, readFileSync, rmSync } from "node:fs";
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import { S as splitGitPatchFiles, a as diff, o as diffFileSummaries } from "../src-BTCRHmRM.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
- import { _ as readBoundedStream, d as legacyModeSchema, g as StreamLimitError, t as SharedReviewStore } from "../import-DG435Ifj.js";
5
- import { A as ReviewGatewayHostSchema, D as ReviewConnectRequestSchema, P 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, y as REVIEW_HOST_HEADER } from "../src-D0h06Qsl.js";
4
+ import { _ as readBoundedStream, d as legacyModeSchema, g as StreamLimitError, t as SharedReviewStore } from "../import-CUNdl3NP.js";
5
+ import { A as ReviewGatewayHostSchema, D as ReviewConnectRequestSchema, P 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, y as REVIEW_HOST_HEADER } from "../src-BJ_MeEmN.js";
6
6
  import "../src-KTjWplV9.js";
7
- import { H as resourceReferences, p as pullRequestProvider } from "../stored-document-migration-B2Wp1ePB.js";
7
+ import { H as resourceReferences, p as pullRequestProvider } from "../stored-document-migration-fQWLDqDx.js";
8
8
  import { t as ReviewInputError } from "../input-error-OLgB_h31.js";
9
9
  import { L as writePrivateJsonAtomic, N as devReviewHome } from "../s3-config-CjcLyFV5.js";
10
10
  import { t as errorMessage } from "../error-message-OtiDonty.js";
11
11
  import { i as readReviewPackageVersion, t as findReviewPackageRoot } from "../package-paths-LcO6HNp_.js";
12
12
  import { i as reviewInstanceDiscoveryPath, o as reviewLegacyDiscoveryPath } from "../review-home-paths-CjHB5c8m.js";
13
- import { _ as reviewInstanceIdentity, u as REVIEW_INSTANCE_ENV } from "../server-discovery-BjelO8cl.js";
14
- import { t as openReviewProfile } from "../profile-Bpsilnd7.js";
15
- import { r as reviewTelemetryChannel, t as ReviewTelemetry } from "../review-telemetry-_54CVkjH.js";
16
- import { l as REVIEW_TELEMETRY_TABS } from "../request-origin-CtTmXRoS.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-DpQNSiaM.js";
18
- import { C as setDiffrConfigValue, S as saveDiffrSummarizer, T as cliAskTools, _ as HttpJsonError, a as drainServerCrashReport, b as migrateDiffrConfig, c as answerErrorsAsJson, d as captureSanitizedUiTelemetry, f as clientErrorsForSession, g as DEFAULT_MAX_REQUEST_BYTES, h as readBoundedRequestJson, l as createWhiteboardCore, m as createNodeRequestListener, o as installProcessErrorTelemetry, p as recordClientError, r as takeOverServerHome, s as serverCrashReportPath, u as serverJson, v as ReviewServerError, w as testDiffrSummarizer, x as readDiffrConfig, y as GlobalReviewDesktopVerbRelay } from "../headless-host-BEdTaS2j.js";
19
- import { s as readQuerySchemas } from "../authoring-tools-CphR87Aa.js";
13
+ import { _ as reviewInstanceIdentity, u as REVIEW_INSTANCE_ENV } from "../server-discovery-Dj_xSDSa.js";
14
+ import { t as openReviewProfile } from "../profile-hC1iAoRB.js";
15
+ import { r as reviewTelemetryChannel, t as ReviewTelemetry } from "../review-telemetry-yuCLNpDu.js";
16
+ import { l as REVIEW_TELEMETRY_TABS } from "../request-origin-BnA7Nnca.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-AJ6miBT5.js";
18
+ import { C as setDiffrConfigValue, S as saveDiffrSummarizer, T as cliAskTools, _ as HttpJsonError, a as drainServerCrashReport, b as migrateDiffrConfig, c as answerErrorsAsJson, d as captureSanitizedUiTelemetry, f as clientErrorsForSession, g as DEFAULT_MAX_REQUEST_BYTES, h as readBoundedRequestJson, l as createWhiteboardCore, m as createNodeRequestListener, o as installProcessErrorTelemetry, p as recordClientError, r as takeOverServerHome, s as serverCrashReportPath, u as serverJson, v as ReviewServerError, w as testDiffrSummarizer, x as readDiffrConfig, y as GlobalReviewDesktopVerbRelay } from "../headless-host-Cn6WDmaL.js";
19
+ import { s as readQuerySchemas } from "../authoring-tools-B9MhiKw4.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,5 +1,5 @@
1
1
  import { a as jsonNumber, n as isJsonObject, s as jsonProperty, u as parseJsonText } from "./src-X9phtB2j.js";
2
- import { n as parseReviewDesktopDiscovery } from "./src-D0h06Qsl.js";
2
+ import { n as parseReviewDesktopDiscovery } from "./src-BJ_MeEmN.js";
3
3
  import "./src-KTjWplV9.js";
4
4
  import { M as DEV_REVIEW_HOME_ENV, N as devReviewHome, k as processIsAlive } from "./s3-config-CjcLyFV5.js";
5
5
  import { a as reviewInstancesDir, o as reviewLegacyDiscoveryPath, r as reviewDevInstanceKey, t as reviewDefaultInstancePath } from "./review-home-paths-CjHB5c8m.js";
@@ -1,2 +1,2 @@
1
- import { a as verifyShareRepository, c as exportShare, n as sharedReviewId, r as validateShareBundle, s as ShareClient, t as SharedReviewStore } from "../import-DG435Ifj.js";
1
+ import { a as verifyShareRepository, c as exportShare, n as sharedReviewId, r as validateShareBundle, s as ShareClient, t as SharedReviewStore } from "../import-CUNdl3NP.js";
2
2
  export { ShareClient, SharedReviewStore, exportShare, sharedReviewId, validateShareBundle, verifyShareRepository };
@@ -665,7 +665,12 @@ const ReviewOnboardingRunRequestSchema = z.strictObject({
665
665
  base: stringAllowEmpty,
666
666
  target: ReviewOnboardingTargetSchema,
667
667
  agent: requiredString$1,
668
- prompt: z.string().trim().min(1).max(8e3)
668
+ prompt: z.string().trim().min(1).max(8e3),
669
+ /** The model and effort to draw with, where the agent offers them. */
670
+ picks: z.strictObject({
671
+ model: z.string().min(1).max(200).optional(),
672
+ effort: z.string().min(1).max(200).optional()
673
+ }).optional()
669
674
  });
670
675
  const ReviewDiffFileSchema = z.strictObject({
671
676
  path: requiredString$1,
@@ -1,8 +1,8 @@
1
1
  import { C as renderVcsArgs, v as parseGitRemote, w as runVcs } from "./src-BTCRHmRM.js";
2
2
  import { d as isBooleanValue, f as isNumberValue, l as jsonValueSchema, m as isStringValue, n as isJsonObject, t as isJsonArray } from "./src-X9phtB2j.js";
3
- import "./src-D0h06Qsl.js";
3
+ import "./src-BJ_MeEmN.js";
4
4
  import "./src-KTjWplV9.js";
5
- import { a as commitLinkTarget, c as parseAnchor, d as selectionProblem, f as sourceAnchors, i as anchorSelection, r as anchorSchema, s as formatAnchor } from "./lens-selection-fz59ca6x.js";
5
+ import { a as commitLinkTarget, c as parseAnchor, d as selectionProblem, f as sourceAnchors, i as anchorSelection, r as anchorSchema, s as formatAnchor } from "./lens-selection-BQxqiuWY.js";
6
6
  import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
7
7
  import { t as errorMessage } from "./error-message-OtiDonty.js";
8
8
  import { randomUUID } from "node:crypto";
@@ -1,4 +1,4 @@
1
- import { M as ReviewSelectedDiffSchema, T as ReviewApiSelectionSourceSchema } from "./src-D0h06Qsl.js";
1
+ import { M as ReviewSelectedDiffSchema, T as ReviewApiSelectionSourceSchema } from "./src-BJ_MeEmN.js";
2
2
  import { z } from "zod";
3
3
  /** A semantic selection, independent of comment/thread creation. */
4
4
  const AgentSelectionSchema = z.strictObject({
@@ -1,6 +1,6 @@
1
1
  import { m as isStringValue, n as isJsonObject } from "./src-X9phtB2j.js";
2
- import { l as boardTitle } from "./src-D0h06Qsl.js";
3
- import { n as callAuthoringTool, s as ReviewApiError, t as ToolText } from "./agent-client-3980WBdQ.js";
2
+ import { l as boardTitle } from "./src-BJ_MeEmN.js";
3
+ import { n as callAuthoringTool, s as ReviewApiError, t as ToolText } from "./agent-client-DyNmSHfO.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.4.1-preview.20261026.139",
3
+ "version": "0.4.1-preview.20261027.141",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -62,7 +62,7 @@
62
62
  "undici": "7.29.1",
63
63
  "yauzl": "3.4.0",
64
64
  "zod": "4.6.6",
65
- "@dev.fast/diffr": "0.1.21"
65
+ "@dev.fast/diffr": "0.1.22"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@dev.fast/local-vcs": "^0.1.0",
@@ -76,9 +76,9 @@
76
76
  "typescript": "6.0.3",
77
77
  "vitest": "4.1.11",
78
78
  "@dev.fast/review-protocol": "0.0.0",
79
- "@dev.fast/json": "0.0.0",
80
79
  "@dev.fast/review-share-protocol": "0.3.0",
81
80
  "@dev.fast/trace-core": "0.0.0",
81
+ "@dev.fast/json": "0.0.0",
82
82
  "@dev.fast/trace-protocol": "0.5.0"
83
83
  },
84
84
  "engines": {
@@ -89,7 +89,7 @@
89
89
  "repo": "devdotfast/review",
90
90
  "docs": "packages/review/instructions/authoring.md"
91
91
  },
92
- "gitHead": "07b9f3b0f8794c4dcb31d77c9fda8be928df33bf",
92
+ "gitHead": "27c5ce9a6af4a118a675105249b81e9a930e0ed3",
93
93
  "scripts": {
94
94
  "prebuild": "pnpm run build:workspace-deps",
95
95
  "build": "node --max-old-space-size=8192 node_modules/tsdown/dist/run.mjs",
@@ -1406,31 +1406,15 @@ export function createReviewApi(
1406
1406
  ].join("\n");
1407
1407
  };
1408
1408
 
1409
- registerOnboardingRoutes(app, store, ask, {
1410
- register: (root) => data.register(root),
1411
- historyHooks,
1412
- handOff,
1413
- open: openCreated,
1414
- });
1415
-
1416
- // The agents answering in any review, which quitting the app would stop.
1417
- app.get("/ask/working", (context) =>
1418
- context.json({ agents: ask.threads.working() }),
1419
- );
1420
-
1421
- // Each agent with the models and efforts it offered last; none until
1422
- // it has run.
1423
- app.get("/:id/ask/agents", async (context) =>
1424
- context.json({ agents: await ask.agents() }),
1425
- );
1426
-
1427
- // What an agent offers: what it said last, else what a session
1428
- // started in the review's checkout says. With another model it offers,
1429
- // what it said last with that model, else what such a session says once
1430
- // it has the model: the efforts on offer depend on it.
1431
- app.get("/:id/ask/agents/:agent/offer", async (context) => {
1432
- const agent = z.enum(askAgentIds).parse(context.req.param("agent"));
1433
- const { model } = askOfferQuerySchema.parse(context.req.query());
1409
+ // What an agent offers: what it said last, else what a session started
1410
+ // in `cwd` says. With another model it offers, what it said last with
1411
+ // that model, else what such a session says once it has the model: the
1412
+ // efforts on offer depend on it.
1413
+ const askOffer = async (
1414
+ agent: AskAgentId,
1415
+ model: string | undefined,
1416
+ cwd: () => Promise<string>,
1417
+ ) => {
1434
1418
  const stored = store.askHistory.offer(agent);
1435
1419
 
1436
1420
  // An offer of nothing to choose was saved before the agent's
@@ -1447,21 +1431,52 @@ export function createReviewApi(
1447
1431
 
1448
1432
  const known = another ? store.askHistory.offer(agent, model) : last;
1449
1433
 
1450
- if (known) return context.json({ offer: known });
1451
-
1452
- const checkout = await data.agentCheckout(
1453
- readReview(context.req.param("id")),
1454
- );
1434
+ if (known) return known;
1455
1435
 
1456
1436
  const offer = await ask.threads.offered(
1457
1437
  agent,
1458
- checkout.rootPath,
1438
+ await cwd(),
1459
1439
  another ? model : undefined,
1460
1440
  );
1461
1441
 
1462
1442
  if (last) store.askHistory.saveModelOffer(agent, offer);
1463
1443
  else store.askHistory.saveOffer(agent, offer);
1464
1444
 
1445
+ return offer;
1446
+ };
1447
+
1448
+ registerOnboardingRoutes(app, store, ask, {
1449
+ register: (root) => data.register(root),
1450
+ historyHooks,
1451
+ handOff,
1452
+ open: openCreated,
1453
+ offer: askOffer,
1454
+ });
1455
+
1456
+ // The agents answering in any review, which quitting the app would stop.
1457
+ app.get("/ask/working", (context) =>
1458
+ context.json({ agents: ask.threads.working() }),
1459
+ );
1460
+
1461
+ // Each agent with the models and efforts it offered last; none until
1462
+ // it has run.
1463
+ app.get("/:id/ask/agents", async (context) =>
1464
+ context.json({ agents: await ask.agents() }),
1465
+ );
1466
+
1467
+ // What an agent offers, from a session in the review's checkout.
1468
+ app.get("/:id/ask/agents/:agent/offer", async (context) => {
1469
+ const agent = z.enum(askAgentIds).parse(context.req.param("agent"));
1470
+ const { model } = askOfferQuerySchema.parse(context.req.query());
1471
+
1472
+ const offer = await askOffer(
1473
+ agent,
1474
+ model,
1475
+ async () =>
1476
+ (await data.agentCheckout(readReview(context.req.param("id"))))
1477
+ .rootPath,
1478
+ );
1479
+
1465
1480
  return context.json({ offer });
1466
1481
  });
1467
1482
 
@@ -12,8 +12,10 @@ import {
12
12
  } from "@dev.fast/review-protocol";
13
13
  import {
14
14
  type AskAgentId,
15
+ type AskOffer,
15
16
  type AskPicks,
16
17
  askAgentIds,
18
+ askPicksSchema,
17
19
  } from "@review/ask/thread-state.js";
18
20
  import type { AskThreadHooks } from "@review/ask/thread.js";
19
21
  import { readBoundedRequestJson } from "@review/server/hono-http.js";
@@ -30,7 +32,8 @@ const COMMAND_TIMEOUT_MS = 15_000;
30
32
 
31
33
  const PULL_REQUEST_LIMIT = 10;
32
34
 
33
- /** Ignored when the agent does not offer the model. */
35
+ /** Where the reader picks nothing; ignored when the agent does not offer
36
+ * the model. */
34
37
  const RUN_PICKS: Partial<Record<AskAgentId, AskPicks>> = {
35
38
  claude: { model: "sonnet" },
36
39
  codex: { model: "gpt-6-luna" },
@@ -436,6 +439,12 @@ export interface OnboardingRunHost {
436
439
  handOff(reviewId: string, threadId: string): void;
437
440
  /** Shows a review in Desktop; reports, rather than throws, a failure. */
438
441
  open(reviewId: string): Promise<{ opened: boolean }>;
442
+ /** What an agent offers to choose, from a session in `cwd`. */
443
+ offer(
444
+ agent: AskAgentId,
445
+ model: string | undefined,
446
+ cwd: () => Promise<string>,
447
+ ): Promise<AskOffer>;
439
448
  }
440
449
 
441
450
  /** First run's Run step, and Home's New whiteboard: make the whiteboard, open
@@ -451,6 +460,24 @@ export function registerOnboardingRoutes(
451
460
  context.json({ agents: await ask.agents() }),
452
461
  );
453
462
 
463
+ // The models and efforts an agent offers to draw with: with the run's own
464
+ // model until the reader picks another.
465
+ app.get("/onboarding/agents/:agent/offer", async (context) => {
466
+ const agent = z.enum(askAgentIds).parse(context.req.param("agent"));
467
+
468
+ const { path: directory, model } = z
469
+ .object({ path: z.string().min(1), model: askPicksSchema.shape.model })
470
+ .parse(context.req.query());
471
+
472
+ return context.json({
473
+ offer: await host.offer(
474
+ agent,
475
+ model ?? RUN_PICKS[agent]?.model,
476
+ async () => directory,
477
+ ),
478
+ });
479
+ });
480
+
454
481
  app.get("/onboarding/projects", async (context) =>
455
482
  context.json({
456
483
  projects: await onboardingProjects(
@@ -550,7 +577,7 @@ export function registerOnboardingRoutes(
550
577
  head,
551
578
  selection: { title },
552
579
  context: await runContext(ask, input.agent, id, reviewId),
553
- picks: RUN_PICKS[input.agent],
580
+ picks: { ...RUN_PICKS[input.agent], ...input.picks },
554
581
  question: { text: input.prompt },
555
582
  });
556
583
 
@@ -1,2 +0,0 @@
1
- import { n as runReviewAgentCli } from "./agent-cli-z_qF_J8n.js";
2
- export { runReviewAgentCli };
@@ -1,2 +0,0 @@
1
- import { t as openReviewProfile } from "./profile-Bpsilnd7.js";
2
- export { openReviewProfile };