@dev.fast/whiteboard 0.3.2 → 0.3.3-preview.20261018.124
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-D_mqo_Jk.js → account-alias-xOdmMnDH.js} +2 -2
- package/dist/{agent-cli-DjLmorAW.js → agent-cli-DT7MdaqL.js} +6 -6
- package/dist/agent-cli-DeCrUC2s.js +2 -0
- package/dist/{agent-client-DjXQy6CL.js → agent-client-BRBzv3AV.js} +3 -3
- package/dist/{authoring-tools-ByMdW_S8.js → authoring-tools-DGSEag8y.js} +2 -2
- package/dist/{background-server-CVL7QpsL.js → background-server-C_REWFkG.js} +1 -1
- package/dist/{background-server-ONy-xKJ1.js → background-server-WKzI_a98.js} +2 -2
- package/dist/build-info.json +1 -1
- package/dist/{cli-Cko4zfif.js → cli-BBSDi_dX.js} +1 -1
- package/dist/{cli-runner-DEKbykD8.js → cli-runner-DshTBske.js} +17 -17
- package/dist/cli.js +2 -2
- package/dist/{client-CLqKkzOc.js → client-BN_FDxFr.js} +2 -2
- package/dist/{fuzzy-match-C9olHRCK.js → fuzzy-match-bFX6wm8j.js} +1 -1
- package/dist/{headless-host-CnCDrHTx.js → headless-host-CS4Gv0c5.js} +58 -11
- package/dist/{headless-host-DRwHcAuF.js → headless-host-CzvYpKOX.js} +1 -1
- package/dist/{local-data-DKmj2ygd.js → local-data-DtQTIzHX.js} +16 -3
- package/dist/{mcp-D-7jkRTU.js → mcp-DpKnnmHH.js} +3 -3
- package/dist/profile-Cz7L781D.js +2 -0
- package/dist/{profile-B58hz5n7.js → profile-DaqmODhc.js} +1 -1
- package/dist/{remote-attach-DJxW9402.js → remote-attach-DCngg8cl.js} +3 -3
- package/dist/{remote-language-server-CGsCaqro.js → remote-language-server-UWQgpoh-.js} +1 -1
- package/dist/{remote-uninstall-DYmNOetF.js → remote-uninstall-CcDOcGyi.js} +3 -3
- package/dist/{request-origin-BSwTNS8K.js → request-origin-Zcn_CjX4.js} +2 -2
- package/dist/{review-app-launcher-i1hmxOZA.js → review-app-launcher-tqSQPlbu.js} +2 -2
- package/dist/{review-telemetry-ClhP_5lW.js → review-telemetry-BHWJsnoD.js} +2 -2
- package/dist/server/desktop-host.js +11 -11
- package/dist/{server-discovery-DVqrcIDT.js → server-discovery-BVqrE1_-.js} +1 -1
- package/dist/sharing/index.d.ts +2 -0
- package/dist/sharing/index.js +1 -1
- package/dist/{src-DZG1xAqW.js → src-DsM3jO8G.js} +61 -1
- package/dist/{stored-document-migration-DLBhkSfp.js → stored-document-migration-CChxtFAy.js} +1 -1
- package/dist/{thread-state-DZihwhfu.js → thread-state-5pYr6_zM.js} +1 -1
- package/dist/{tool-failure-CVJrfi5s.js → tool-failure-BFt2xj9i.js} +1 -1
- package/package.json +4 -4
- package/src/review-api/http.ts +4 -0
- package/src/review-api/store.ts +20 -0
- package/src/server/feedback.ts +80 -0
- package/src/server/review-server-core.ts +2 -0
- package/dist/agent-cli-CoHvydp7.js +0 -2
- package/dist/profile-D1rScZ-E.js +0 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { n as isJsonObject } from "./src-X9phtB2j.js";
|
|
2
|
-
import { w as ReviewCliInstallStampSchema } from "./src-
|
|
2
|
+
import { w as ReviewCliInstallStampSchema } from "./src-DsM3jO8G.js";
|
|
3
3
|
import { C as disableTraceMachine, E as traceMachineStatus, G as listTraceRepositoryRoots, K as traceRepositoryStatus, Q as removeAgentTraceHook, S as configureTraceMachine, T as traceMachineEnabled, U as disableAllTraceRepositories, W as enableTraceRepository, X as describeTraceHookOwners, Y as AGENT_TRACE_HOOK_AGENTS, Z as installHarnessHooks, dt as StoreClient, n as reviewDesktopStateDir, nt as traceScope, ot as readStoreAuth } from "./review-home-paths-Lc02WFuX.js";
|
|
4
4
|
import { A as withFileLock, F as writeFileAtomicAsync, I as writePrivateJsonAtomic, M as devReviewHome } from "./s3-config-DDWWMh5x.js";
|
|
5
5
|
import { i as readReviewPackageVersion } from "./package-paths-jMg6JxDP.js";
|
|
6
6
|
import { n as isFile, t as isDirectory } from "./fs-utils-BMPLt0cr.js";
|
|
7
|
-
import { s as findExecutable } from "./fuzzy-match-
|
|
7
|
+
import { s as findExecutable } from "./fuzzy-match-bFX6wm8j.js";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import { constants } from "node:fs";
|
|
10
10
|
import { access, chmod, lstat, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
2
2
|
import { T as traceMachineEnabled } from "./review-home-paths-Lc02WFuX.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-BRBzv3AV.js";
|
|
4
4
|
import { M as devReviewHome } from "./s3-config-DDWWMh5x.js";
|
|
5
5
|
import { n as readBuildCommit } from "./package-paths-jMg6JxDP.js";
|
|
6
|
-
import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-
|
|
7
|
-
import { n as reviewSessionAgent } from "./review-telemetry-
|
|
8
|
-
import { n as REVIEW_VIA_HEADER, t as REVIEW_AGENT_HEADER } from "./request-origin-
|
|
9
|
-
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-
|
|
6
|
+
import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-BVqrE1_-.js";
|
|
7
|
+
import { n as reviewSessionAgent } from "./review-telemetry-BHWJsnoD.js";
|
|
8
|
+
import { n as REVIEW_VIA_HEADER, t as REVIEW_AGENT_HEADER } from "./request-origin-Zcn_CjX4.js";
|
|
9
|
+
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-BFt2xj9i.js";
|
|
10
10
|
import { existsSync } from "node:fs";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
//#region src/review-api/install-update.ts
|
|
@@ -38,7 +38,7 @@ async function runReviewAgentCli(input) {
|
|
|
38
38
|
if (extra.length || mode === "mcp" && name) throw new Error("Unexpected arguments. Use whiteboard api --help.");
|
|
39
39
|
const headers = Object.fromEntries([[REVIEW_VIA_HEADER, mode === "mcp" ? "mcp" : "api"], [REVIEW_AGENT_HEADER, reviewSessionAgent(env)]]);
|
|
40
40
|
if (mode === "mcp") {
|
|
41
|
-
const { serveReviewMcp } = await import("./mcp-
|
|
41
|
+
const { serveReviewMcp } = await import("./mcp-DpKnnmHH.js");
|
|
42
42
|
exitOnInstallUpdate(input.stderr);
|
|
43
43
|
await serveReviewMcp(async (key, agentKind) => {
|
|
44
44
|
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-
|
|
2
|
+
import "./src-DsM3jO8G.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-BVqrE1_-.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. */
|
|
@@ -249,7 +249,7 @@ async function connectReviewInstance(env = process.env, headers = {}, options =
|
|
|
249
249
|
const selection = await selectReviewInstance({ env });
|
|
250
250
|
const discovery = healthyReviewInstance(selection);
|
|
251
251
|
if (!discovery) {
|
|
252
|
-
const { ensureServerWithoutDesktop } = await import("./background-server-
|
|
252
|
+
const { ensureServerWithoutDesktop } = await import("./background-server-C_REWFkG.js");
|
|
253
253
|
const server = await ensureServerWithoutDesktop({
|
|
254
254
|
selection,
|
|
255
255
|
env,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as activityEndSchema, i as commandSchema, l as activityUpdateSchema, n as uploadSchema, s as activityBeginSchema } from "./local-data-
|
|
2
|
-
import { S as publishedEditSchema, y as pathTargetSchema } from "./stored-document-migration-
|
|
1
|
+
import { c as activityEndSchema, i as commandSchema, l as activityUpdateSchema, n as uploadSchema, s as activityBeginSchema } from "./local-data-DtQTIzHX.js";
|
|
2
|
+
import { S as publishedEditSchema, y as pathTargetSchema } from "./stored-document-migration-CChxtFAy.js";
|
|
3
3
|
import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
|
|
4
4
|
import { t as findReviewPackageRoot } from "./package-paths-jMg6JxDP.js";
|
|
5
5
|
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-
|
|
1
|
+
import { a as headlessServerOwner, c as stopBackgroundServer, i as ensureServerWithoutDesktop, r as ensureBackgroundServer } from "./background-server-WKzI_a98.js";
|
|
2
2
|
export { ensureBackgroundServer, ensureServerWithoutDesktop, headlessServerOwner, stopBackgroundServer };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "./review-home-paths-Lc02WFuX.js";
|
|
2
2
|
import { D as liveLockOwner, O as processIsAlive } from "./s3-config-DDWWMh5x.js";
|
|
3
3
|
import { t as findReviewPackageRoot } from "./package-paths-jMg6JxDP.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-BVqrE1_-.js";
|
|
5
|
+
import { t as desktopApplicationInstalled } from "./review-app-launcher-tqSQPlbu.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";
|
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.3.
|
|
1
|
+
{"version":"0.3.3-preview.20261018.124","commit":"710b08c0dcb2166b8088ded6af639dd9598288c9","dirty":true,"builtAt":"2026-10-18T18:42:24.072Z"}
|
|
@@ -1,18 +1,18 @@
|
|
|
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-DsM3jO8G.js";
|
|
4
4
|
import { $ as resolveTraceCommand, A as runTraceDeny, E as traceMachineStatus, F as describeSelection, H as resolveTraceRepositoryTarget, J as HOSTED_CAPTURE_SCOPE_DESCRIPTION, K as traceRepositoryStatus, L as loadS3TraceStorage, M as runTraceSessions, N as runTraceStoreDelete, P as runTraceStoreInfo, T as traceMachineEnabled, V as requireTraceConsent, _ as runTraceRepair, b as runTraceGitHook, c as registerTraceCommands, ct as runStoreLogout, d as runTraceList$1, dt as StoreClient, f as runTracePull$1, ft as withStoreAuthorization, g as runTraceInstallMachine, gt as jsonRequestedInArgv, h as runTraceEnable, ht as humanStream, j as runTraceOnboard, k as runTraceAllow, l as resolveTraceReadStorage, lt as runStoreWhoami, m as runTraceDisable, mt as failWithJsonError, nt as traceScope, ot as readStoreAuth, p as runTraceShow, pt as emitJsonEvent, q as readTraceUserConfig, rt as DEFAULT_STORE_ORIGIN, st as runStoreLogin, tt as traceHomeDir, u as runTraceBlame, ut as StoreApiError, v as runTraceStatus, w as readLegacyCaptureSettings, x as runTraceHook, y as runTraceSync, z as selectTraceStorage } from "./review-home-paths-Lc02WFuX.js";
|
|
5
|
-
import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-
|
|
5
|
+
import { o as ReviewApiClient, s as ReviewApiError } from "./agent-client-BRBzv3AV.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-jMg6JxDP.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-
|
|
11
|
-
import { t as ReviewTelemetry } from "./review-telemetry-
|
|
12
|
-
import { t as fuzzyRank } from "./fuzzy-match-
|
|
13
|
-
import { _ as isInstallTarget, a as isOwnedShim, f as windowsInstallerCommand, g as ALL_INSTALL_TARGETS, h as detectConnectAgents, m as connectAgent, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount, v as connectPrompts } from "./account-alias-
|
|
14
|
-
import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-
|
|
15
|
-
import { t as reviewAgentCliHelp } from "./agent-cli-
|
|
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-BVqrE1_-.js";
|
|
11
|
+
import { t as ReviewTelemetry } from "./review-telemetry-BHWJsnoD.js";
|
|
12
|
+
import { t as fuzzyRank } from "./fuzzy-match-bFX6wm8j.js";
|
|
13
|
+
import { _ as isInstallTarget, a as isOwnedShim, f as windowsInstallerCommand, g as ALL_INSTALL_TARGETS, h as detectConnectAgents, m as connectAgent, o as pathShimPath, p as scanLegacySkills, t as aliasInstallationToAccount, v as connectPrompts } from "./account-alias-xOdmMnDH.js";
|
|
14
|
+
import { n as focusReviewDesktop, r as runReviewAppLaunch } from "./review-app-launcher-tqSQPlbu.js";
|
|
15
|
+
import { t as reviewAgentCliHelp } from "./agent-cli-DT7MdaqL.js";
|
|
16
16
|
import { existsSync, mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
17
17
|
import { realpath } from "node:fs/promises";
|
|
18
18
|
import path from "node:path";
|
|
@@ -4297,7 +4297,7 @@ async function runReviewCli(input) {
|
|
|
4297
4297
|
if (!Number.isInteger(port) || port < 0 || port > 65535) throw new ReviewCliUsageError("--port must be an integer between 0 and 65535.");
|
|
4298
4298
|
const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
|
|
4299
4299
|
if (options.detach) {
|
|
4300
|
-
const { ensureBackgroundServer } = await import("./background-server-
|
|
4300
|
+
const { ensureBackgroundServer } = await import("./background-server-C_REWFkG.js");
|
|
4301
4301
|
const { discovery, started } = await ensureBackgroundServer({
|
|
4302
4302
|
stateDir,
|
|
4303
4303
|
env,
|
|
@@ -4319,7 +4319,7 @@ async function runReviewCli(input) {
|
|
|
4319
4319
|
process.once("SIGINT", stop);
|
|
4320
4320
|
process.once("SIGTERM", stop);
|
|
4321
4321
|
process.once(DESKTOP_TAKEOVER_SIGNAL, takeover);
|
|
4322
|
-
const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-
|
|
4322
|
+
const { HeadlessServerBusyError, runHeadlessServer } = await import("./headless-host-CzvYpKOX.js");
|
|
4323
4323
|
try {
|
|
4324
4324
|
await runHeadlessServer({
|
|
4325
4325
|
stateDir,
|
|
@@ -4356,7 +4356,7 @@ async function runReviewCli(input) {
|
|
|
4356
4356
|
configureJsonOutput(serverCommand.command("stop").description("Stop a background server started by --detach, the CLI, or Desktop").option("--state-dir <path>", "directory selected when starting the server"), "plain").action(async (_options, command) => {
|
|
4357
4357
|
const options = command.optsWithGlobals();
|
|
4358
4358
|
const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
|
|
4359
|
-
const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-
|
|
4359
|
+
const { headlessServerOwner, stopBackgroundServer } = await import("./background-server-C_REWFkG.js");
|
|
4360
4360
|
const owner = await headlessServerOwner(stateDir);
|
|
4361
4361
|
const discovery = await readReviewServerDiscovery(stateDir);
|
|
4362
4362
|
if (owner === void 0) {
|
|
@@ -4384,7 +4384,7 @@ async function runReviewCli(input) {
|
|
|
4384
4384
|
if (!existsSync(path.join(stateDir, "review-api.db"))) throw new Error(`No saved reviews in ${stateDir}, so there is no server id to reset. Check --state-dir.`);
|
|
4385
4385
|
const inUse = `A Whiteboard server is using ${stateDir}. Stop it first, then run whiteboard server reset-id again.`;
|
|
4386
4386
|
if (await desktopUsesHome(stateDir, env)) return refuse(inUse, options.json);
|
|
4387
|
-
const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-
|
|
4387
|
+
const [{ openReviewProfile }, { withHeadlessServerLock }] = await Promise.all([import("./profile-Cz7L781D.js"), import("./headless-host-CzvYpKOX.js")]);
|
|
4388
4388
|
const reset = await withHeadlessServerLock(await realpath(stateDir), async () => {
|
|
4389
4389
|
const local = await openReviewProfile(stateDir, { manageWorkspaces: false });
|
|
4390
4390
|
try {
|
|
@@ -4406,7 +4406,7 @@ async function runReviewCli(input) {
|
|
|
4406
4406
|
configureJsonOutput(remote.command("attach").description("Start a background server if none is healthy and report how to reach it").option("--state-dir <path>", "directory for saved reviews and server discovery").option("--groups <groups>", "comma-separated optional extension groups the Desktop has enabled, such as go").option("--replace", "stop a running server of another version that the CLI or Desktop started, and start this one"), "plain").action(async (_options, command) => {
|
|
4407
4407
|
const options = command.optsWithGlobals();
|
|
4408
4408
|
const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
|
|
4409
|
-
const { remoteAttach } = await import("./remote-attach-
|
|
4409
|
+
const { remoteAttach } = await import("./remote-attach-DCngg8cl.js");
|
|
4410
4410
|
let attach;
|
|
4411
4411
|
try {
|
|
4412
4412
|
attach = await remoteAttach({
|
|
@@ -4448,7 +4448,7 @@ async function runReviewCli(input) {
|
|
|
4448
4448
|
configureJsonOutput(remote.command("uninstall").description("Remove what Whiteboard Desktop installed on this host, stopping a server it started").addOption(new Option("--keep-reviews", "leave the saved reviews in place").conflicts("deleteReviews")).addOption(new Option("--delete-reviews", "also delete the saved reviews")).option("--state-dir <path>", "directory for saved reviews and server discovery"), "plain").action(async (_options, command) => {
|
|
4449
4449
|
const options = command.optsWithGlobals();
|
|
4450
4450
|
const stateDir = reviewServerStateDir(authoringEnv(options.stateDir));
|
|
4451
|
-
const { remoteUninstall } = await import("./remote-uninstall-
|
|
4451
|
+
const { remoteUninstall } = await import("./remote-uninstall-CcDOcGyi.js");
|
|
4452
4452
|
let deleteReviews = options.deleteReviews ? true : options.keepReviews ? false : void 0;
|
|
4453
4453
|
if (deleteReviews === void 0 && !options.json && input.stdin?.isTTY) {
|
|
4454
4454
|
const prompt = createInterface$1({
|
|
@@ -4670,14 +4670,14 @@ async function runReviewCli(input) {
|
|
|
4670
4670
|
command.showHelpAfterError(false).error("Markdown review migration is no longer supported. Ask your agent to migrate your old Whiteboard reviews.");
|
|
4671
4671
|
});
|
|
4672
4672
|
configureJsonOutput(configureJsonOutput(program.command("share").description("Upload an immutable review snapshot and return its share link"), "plain").option("--review <id>", "review ID").option("--version <number>", "Saved version to share").option("--preview", "Open the share link in Whiteboard Preview by default").option("--request-id <uuid>", "Reuse this ID when retrying the same immutable upload").action(async (options) => {
|
|
4673
|
-
const { runShareCli } = await import("./cli-
|
|
4673
|
+
const { runShareCli } = await import("./cli-BBSDi_dX.js");
|
|
4674
4674
|
state.exitCode = await runShareCli({
|
|
4675
4675
|
...input,
|
|
4676
4676
|
...options,
|
|
4677
4677
|
env: authoringEnv()
|
|
4678
4678
|
});
|
|
4679
4679
|
}).command("revoke <share-id>").description("Revoke future downloads of a share"), "plain").action(async (shareId, options) => {
|
|
4680
|
-
const { runShareCli } = await import("./cli-
|
|
4680
|
+
const { runShareCli } = await import("./cli-BBSDi_dX.js");
|
|
4681
4681
|
state.exitCode = await runShareCli({
|
|
4682
4682
|
...input,
|
|
4683
4683
|
...options,
|
|
@@ -4758,7 +4758,7 @@ async function runReviewCli(input) {
|
|
|
4758
4758
|
return commands;
|
|
4759
4759
|
} });
|
|
4760
4760
|
for (const [name, description] of [["api", "Call a JSON review authoring tool on the running server"], ["mcp", "Serve the JSON review authoring tools over stdio MCP"]]) configureOutput(program.command(name).description(description).argument("[args...]", "tool name and JSON input").allowUnknownOption().allowExcessArguments().helpOption(false).passThroughOptions().addHelpText("after", `\n${reviewAgentCliHelp}`), "plain").action(async (args) => {
|
|
4761
|
-
const { runReviewAgentCli } = await import("./agent-cli-
|
|
4761
|
+
const { runReviewAgentCli } = await import("./agent-cli-DeCrUC2s.js");
|
|
4762
4762
|
state.exitCode = await runReviewAgentCli({
|
|
4763
4763
|
...input,
|
|
4764
4764
|
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-DsM3jO8G.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-DshTBske.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 { C as resourceReference, D as sourceReferences, F as lensSchema, H as markdownNodes, I as lensSelections, U as parseMarkdown, Y as sourceAnchors, _ as hasCodeReferences, c as traceSchema, h as elements, k as checkReferences, l as textIncludesQuote, n as migrateStoredDocument, o as normalizedSoftwareElementSchema, p as documentSchema, r as migrateStoredLenses, s as normalizedSoftwareRelationshipSchema, t as liftFileLenses, u as anchorPins, w as resourceReferences, x as pinsSchema } from "./stored-document-migration-
|
|
3
|
+
import "./src-DsM3jO8G.js";
|
|
4
|
+
import { C as resourceReference, D as sourceReferences, F as lensSchema, H as markdownNodes, I as lensSelections, U as parseMarkdown, Y as sourceAnchors, _ as hasCodeReferences, c as traceSchema, h as elements, k as checkReferences, l as textIncludesQuote, n as migrateStoredDocument, o as normalizedSoftwareElementSchema, p as documentSchema, r as migrateStoredLenses, s as normalizedSoftwareRelationshipSchema, t as liftFileLenses, u as anchorPins, w as resourceReferences, x as pinsSchema } from "./stored-document-migration-CChxtFAy.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,6 +1,6 @@
|
|
|
1
1
|
import "./review-home-paths-Lc02WFuX.js";
|
|
2
2
|
import { M as devReviewHome } from "./s3-config-DDWWMh5x.js";
|
|
3
|
-
import { n as askAgentIds } from "./thread-state-
|
|
3
|
+
import { n as askAgentIds } from "./thread-state-5pYr6_zM.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { constants } from "node:fs";
|
|
6
6
|
import { access, chmod, mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
@@ -1,21 +1,21 @@
|
|
|
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, d as invalidateStructuralComparisons, f as diffrExecutable, i as commandSchema, p as diffrMissingError, r as SCRATCHPAD_ID } from "./local-data-
|
|
5
|
-
import {
|
|
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-BN_FDxFr.js";
|
|
4
|
+
import { a as inspectSnapshot, d as invalidateStructuralComparisons, f as diffrExecutable, i as commandSchema, p as diffrMissingError, r as SCRATCHPAD_ID } from "./local-data-DtQTIzHX.js";
|
|
5
|
+
import { D as ReviewFeedbackSchema, E as ReviewFeedbackContactSchema, M as reviewDiffrSummarizerInputSchema, N as decodeStructuralDiffEvent, a as parseReviewVerbRequest, g as REVIEW_HOST_HEADER, i as parseReviewDesktopVerbResult, k as ReviewOnboardingRunRequestSchema } from "./src-DsM3jO8G.js";
|
|
6
6
|
import { B as TraceStorageDeniedError, D as listReviewTraceSessions, I as isTraceStorageConfigured, O as loadReviewAgentTrace, R as resolveTraceStorage, T as traceMachineEnabled, at as openUrlInBrowser, et as shellQuote, it as clearStoreAuth, ot as readStoreAuth, rt as DEFAULT_STORE_ORIGIN, st as runStoreLogin, z as selectTraceStorage } from "./review-home-paths-Lc02WFuX.js";
|
|
7
|
-
import { E as selectionReferences, G as comparisonKey, I as lensSelections, J as selectionKey, K as formatAnchor, M as UNCATEGORIZED_LENS_ID, Q as emptyCoverage, W as anchorSelection, Z as coverageSources, et as scopedCoverage, h as elements, j as stepSources, nt as unionIntervals, q as resolveDiffSelection, tt as subtractIntervals, u as anchorPins, z as fileLineRangeSchema } from "./stored-document-migration-
|
|
7
|
+
import { E as selectionReferences, G as comparisonKey, I as lensSelections, J as selectionKey, K as formatAnchor, M as UNCATEGORIZED_LENS_ID, Q as emptyCoverage, W as anchorSelection, Z as coverageSources, et as scopedCoverage, h as elements, j as stepSources, nt as unionIntervals, q as resolveDiffSelection, tt as subtractIntervals, u as anchorPins, z as fileLineRangeSchema } from "./stored-document-migration-CChxtFAy.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-jMg6JxDP.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 { 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-
|
|
14
|
-
import { t as openReviewProfile } from "./profile-
|
|
15
|
-
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-
|
|
16
|
-
import { a as defaultAskPermissions, c as launchAskAgent, i as askAgents, n as askAgentSettings, o as detectAskAgents, r as askAgentTakesMcp, t as fuzzyRank } from "./fuzzy-match-
|
|
17
|
-
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-
|
|
18
|
-
import { a as headlessServerOwner, c as stopBackgroundServer } from "./background-server-
|
|
12
|
+
import { _ as reviewInstanceIdentity, i as readReviewServerDiscovery, n as desktopOwnsHome, o as reviewServerDiscoveryPath, p as desktopUsesHome, r as headlessServerLockPath, t as DESKTOP_TAKEOVER_SIGNAL } from "./server-discovery-BVqrE1_-.js";
|
|
13
|
+
import { c as askPicksSchema, d as selectionMarkdown, l as askQuestionSchema, n as askAgentIds, r as askChoiceKinds, s as askPermissionsSchema, t as applyAskChange, u as AgentSelectionSchema } from "./thread-state-5pYr6_zM.js";
|
|
14
|
+
import { t as openReviewProfile } from "./profile-DaqmODhc.js";
|
|
15
|
+
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-Zcn_CjX4.js";
|
|
16
|
+
import { a as defaultAskPermissions, c as launchAskAgent, i as askAgents, n as askAgentSettings, o as detectAskAgents, r as askAgentTakesMcp, t as fuzzyRank } from "./fuzzy-match-bFX6wm8j.js";
|
|
17
|
+
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-DGSEag8y.js";
|
|
18
|
+
import { a as headlessServerOwner, c as stopBackgroundServer } from "./background-server-WKzI_a98.js";
|
|
19
19
|
import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
20
20
|
import { z } from "zod";
|
|
21
21
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
@@ -3566,6 +3566,7 @@ function createReviewApi(store, data, open, shared, capabilities = () => ({
|
|
|
3566
3566
|
await ensureScratchpad();
|
|
3567
3567
|
return context.json(catalog());
|
|
3568
3568
|
});
|
|
3569
|
+
app.get("/feedback-eligibility", (context) => context.json({ eligible: store.feedbackEligible() }));
|
|
3569
3570
|
const instructionContext = async () => ({
|
|
3570
3571
|
desktopAvailable: Boolean(open),
|
|
3571
3572
|
scratchpadEnabled: scratchpadEnabled(),
|
|
@@ -4482,6 +4483,51 @@ function watch(lines, subscribe) {
|
|
|
4482
4483
|
} });
|
|
4483
4484
|
}
|
|
4484
4485
|
//#endregion
|
|
4486
|
+
//#region src/server/feedback.ts
|
|
4487
|
+
const FEEDBACK_URL = "https://dev.fast/api/feedback";
|
|
4488
|
+
/** Runs behind the local API's auth middleware. No telemetry envelope is sent. */
|
|
4489
|
+
function mountFeedback(app) {
|
|
4490
|
+
const localUrl = process.env.DEV_FAST_REVIEW_FEEDBACK_URL;
|
|
4491
|
+
const receiver = localUrl && reviewInstanceIdentity(process.env).channel !== "stable" && [
|
|
4492
|
+
"localhost",
|
|
4493
|
+
"127.0.0.1",
|
|
4494
|
+
"[::1]"
|
|
4495
|
+
].includes(new URL(localUrl).hostname) ? localUrl : FEEDBACK_URL;
|
|
4496
|
+
for (const [path, schema] of [["/feedback", ReviewFeedbackSchema], ["/feedback/contact", ReviewFeedbackContactSchema]]) app.post(path, async (context) => {
|
|
4497
|
+
const input = schema.safeParse(await readBoundedRequestJson(context.req.raw, 65536));
|
|
4498
|
+
if (!input.success) return context.json({
|
|
4499
|
+
ok: false,
|
|
4500
|
+
error: "Invalid feedback."
|
|
4501
|
+
}, 400);
|
|
4502
|
+
const signal = AbortSignal.any([context.req.raw.signal, AbortSignal.timeout(5e3)]);
|
|
4503
|
+
try {
|
|
4504
|
+
const response = await fetch(receiver, {
|
|
4505
|
+
method: "POST",
|
|
4506
|
+
headers: { "content-type": "application/json" },
|
|
4507
|
+
body: JSON.stringify(input.data),
|
|
4508
|
+
signal,
|
|
4509
|
+
redirect: "error"
|
|
4510
|
+
});
|
|
4511
|
+
const body = await response.json().catch((error) => {
|
|
4512
|
+
if (signal.aborted || error instanceof TypeError) throw error;
|
|
4513
|
+
return null;
|
|
4514
|
+
});
|
|
4515
|
+
if (!response.ok || body?.ok !== true) return context.json({
|
|
4516
|
+
ok: false,
|
|
4517
|
+
code: "receiver",
|
|
4518
|
+
error: "Feedback could not be saved. Please try again."
|
|
4519
|
+
}, 502);
|
|
4520
|
+
return context.json({ ok: true });
|
|
4521
|
+
} catch {
|
|
4522
|
+
return context.json({
|
|
4523
|
+
ok: false,
|
|
4524
|
+
code: "network",
|
|
4525
|
+
error: "Feedback could not be saved. Please try again."
|
|
4526
|
+
}, 502);
|
|
4527
|
+
}
|
|
4528
|
+
});
|
|
4529
|
+
}
|
|
4530
|
+
//#endregion
|
|
4485
4531
|
//#region src/server/review-server-core.ts
|
|
4486
4532
|
const version = readReviewPackageVersion(import.meta.url);
|
|
4487
4533
|
const commit = readBuildCommit(import.meta.url);
|
|
@@ -4519,6 +4565,7 @@ function createReviewServerApp(input) {
|
|
|
4519
4565
|
await next();
|
|
4520
4566
|
});
|
|
4521
4567
|
app.get("/control", (context) => openControlEvents(context, input.relay));
|
|
4568
|
+
mountFeedback(app);
|
|
4522
4569
|
app.post("/control/result", async (context) => {
|
|
4523
4570
|
const accepted = input.relay.acceptResult(await readBoundedRequestJson(context.req.raw));
|
|
4524
4571
|
return serverJson(accepted ? 200 : 404, { ok: accepted });
|
|
@@ -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-CS4Gv0c5.js";
|
|
2
2
|
export { HeadlessServerBusyError, runHeadlessServer, takeOverServerHome, withHeadlessServerLock };
|
|
@@ -1,13 +1,13 @@
|
|
|
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 {
|
|
3
|
+
import { N as decodeStructuralDiffEvent, P as structuralChangeCounts, j as SCRATCHPAD_REVIEW_ID } from "./src-DsM3jO8G.js";
|
|
4
4
|
import { s as safeStorageSegment } from "./review-home-paths-Lc02WFuX.js";
|
|
5
|
-
import { $ as intersectIntervals, A as documentAdvice, B as requireVisibleSource, C as resourceReference, D as sourceReferences, I as lensSelections, L as SourceRangeError, N as applyLensEdit, O as summarizeEdit, P as lensEditSchema, Q as emptyCoverage, R as checkSourcePath, T as reviewTargetSchema, V as sliceSourceRange, X as coverageSchema, Y as sourceAnchors, a as defineSoftwareMap, b as pinnedRepositoryIds, c as traceSchema, d as applyEdit, f as assignFreshIds, g as explicitPins, h as elements, i as SoftwareModelValidationError, k as checkReferences, l as textIncludesQuote, m as editSchema, n as migrateStoredDocument, nt as unionIntervals, p as documentSchema, r as migrateStoredLenses, rt as updateCoverage, t as liftFileLenses, tt as subtractIntervals, u as anchorPins, v as isUnit, w as resourceReferences, x as pinsSchema, z as fileLineRangeSchema } from "./stored-document-migration-
|
|
5
|
+
import { $ as intersectIntervals, A as documentAdvice, B as requireVisibleSource, C as resourceReference, D as sourceReferences, I as lensSelections, L as SourceRangeError, N as applyLensEdit, O as summarizeEdit, P as lensEditSchema, Q as emptyCoverage, R as checkSourcePath, T as reviewTargetSchema, V as sliceSourceRange, X as coverageSchema, Y as sourceAnchors, a as defineSoftwareMap, b as pinnedRepositoryIds, c as traceSchema, d as applyEdit, f as assignFreshIds, g as explicitPins, h as elements, i as SoftwareModelValidationError, k as checkReferences, l as textIncludesQuote, m as editSchema, n as migrateStoredDocument, nt as unionIntervals, p as documentSchema, r as migrateStoredLenses, rt as updateCoverage, t as liftFileLenses, tt as subtractIntervals, u as anchorPins, v as isUnit, w as resourceReferences, x as pinsSchema, z as fileLineRangeSchema } from "./stored-document-migration-CChxtFAy.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";
|
|
9
9
|
import { r as isMissingFileError } from "./fs-utils-BMPLt0cr.js";
|
|
10
|
-
import { a as askHistoryEntrySchema, i as askEntrySchema, o as askOfferSchema, s as askPermissionsSchema } from "./thread-state-
|
|
10
|
+
import { a as askHistoryEntrySchema, i as askEntrySchema, o as askOfferSchema, s as askPermissionsSchema } from "./thread-state-5pYr6_zM.js";
|
|
11
11
|
import { createRequire } from "node:module";
|
|
12
12
|
import crypto, { createHash, randomUUID } from "node:crypto";
|
|
13
13
|
import { z } from "zod";
|
|
@@ -2552,6 +2552,19 @@ var ReviewStore = class {
|
|
|
2552
2552
|
if (!this.has(SCRATCHPAD_ID)) throw error;
|
|
2553
2553
|
}
|
|
2554
2554
|
}
|
|
2555
|
+
/** Two saved board/day pairs in the last fourteen days. */
|
|
2556
|
+
feedbackEligible(now = Date.now()) {
|
|
2557
|
+
const row = this.db.prepare(`SELECT count(*) AS pairs FROM (
|
|
2558
|
+
SELECT DISTINCT review_id, date(json_extract(snapshot, '$.createdAt')) AS utc_date
|
|
2559
|
+
FROM versions
|
|
2560
|
+
WHERE (version = 0 OR json_type(snapshot, '$.lastEdit') = 'object')
|
|
2561
|
+
AND json_extract(snapshot, '$.kind') IS NOT 'scratchpad'
|
|
2562
|
+
AND json_extract(snapshot, '$.origin.tutorial') IS NOT 1
|
|
2563
|
+
AND julianday(json_extract(snapshot, '$.createdAt')) BETWEEN julianday(?) AND julianday(?)
|
|
2564
|
+
LIMIT 2
|
|
2565
|
+
)`).get((/* @__PURE__ */ new Date(now - 12096e5)).toISOString(), new Date(now).toISOString());
|
|
2566
|
+
return Number(row?.pairs) >= 2;
|
|
2567
|
+
}
|
|
2555
2568
|
history(id) {
|
|
2556
2569
|
return this.db.prepare("SELECT version,json_extract(snapshot,'$.title') AS title,json_extract(snapshot,'$.createdAt') AS created_at FROM versions WHERE review_id=? ORDER BY version").all(id).map((row) => ({
|
|
2557
2570
|
version: Number(row.version),
|
|
@@ -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-BRBzv3AV.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-DGSEag8y.js";
|
|
4
|
+
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-BFt2xj9i.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-DtQTIzHX.js";
|
|
2
2
|
import "./review-home-paths-Lc02WFuX.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-jMg6JxDP.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-BVqrE1_-.js";
|
|
3
|
+
import { c as stopBackgroundServer, o as recordedBackgroundServer, r as ensureBackgroundServer } from "./background-server-WKzI_a98.js";
|
|
4
|
+
import { t as ensureRemoteLanguageServer } from "./remote-language-server-UWQgpoh-.js";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
import { gt, valid } from "semver";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./review-home-paths-Lc02WFuX.js";
|
|
2
2
|
import { A as withFileLock, k as processStartIdentity } from "./s3-config-DDWWMh5x.js";
|
|
3
3
|
import { t as findReviewPackageRoot } from "./package-paths-jMg6JxDP.js";
|
|
4
|
-
import { n as cliSpawn, s as spawnDetached } from "./background-server-
|
|
4
|
+
import { n as cliSpawn, s as spawnDetached } from "./background-server-WKzI_a98.js";
|
|
5
5
|
import { r as remoteServerPaths, t as ensureRemoteExtensions } from "./remote-extensions-BCAbQZTv.js";
|
|
6
6
|
import { randomBytes } from "node:crypto";
|
|
7
7
|
import { z } from "zod";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { b as REVIEW_REMOTE_INSTALL_LOCK, x as REVIEW_REMOTE_WRAPPER_MARK } from "./src-
|
|
1
|
+
import { b as REVIEW_REMOTE_INSTALL_LOCK, x as REVIEW_REMOTE_WRAPPER_MARK } from "./src-DsM3jO8G.js";
|
|
2
2
|
import "./review-home-paths-Lc02WFuX.js";
|
|
3
3
|
import { j as DEV_REVIEW_HOME_ENV } from "./s3-config-DDWWMh5x.js";
|
|
4
|
-
import { c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-
|
|
4
|
+
import { c as stopBackgroundServer, o as recordedBackgroundServer } from "./background-server-WKzI_a98.js";
|
|
5
5
|
import { i as whiteboardRemoteHome } from "./remote-extensions-BCAbQZTv.js";
|
|
6
|
-
import { n as remoteLanguageServerGroups, r as stopProcessGroup } from "./remote-language-server-
|
|
6
|
+
import { n as remoteLanguageServerGroups, r as stopProcessGroup } from "./remote-language-server-UWQgpoh-.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,6 +1,6 @@
|
|
|
1
1
|
import { a as jsonNumber, c as jsonString, i as jsonBoolean, n as isJsonObject } from "./src-X9phtB2j.js";
|
|
2
|
-
import { S as REVIEW_THEME_CHOICES, h as REVIEW_DIFF_LAYOUT_SCOPES, m as REVIEW_DIFF_LAYOUTS } from "./src-
|
|
3
|
-
import { n as askAgentIds } from "./thread-state-
|
|
2
|
+
import { S as REVIEW_THEME_CHOICES, h as REVIEW_DIFF_LAYOUT_SCOPES, m as REVIEW_DIFF_LAYOUTS } from "./src-DsM3jO8G.js";
|
|
3
|
+
import { n as askAgentIds } from "./thread-state-5pYr6_zM.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/telemetry-clean-text.ts
|
|
6
6
|
const USER_DATA_REGEXES = [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { o as parseReviewVerbResponse } from "./src-
|
|
2
|
-
import { b as selectReviewInstance, m as healthyReviewInstance, v as reviewInstanceStartHint, y as reviewInstanceUnavailable } from "./server-discovery-
|
|
1
|
+
import { o as parseReviewVerbResponse } from "./src-DsM3jO8G.js";
|
|
2
|
+
import { b as selectReviewInstance, m as healthyReviewInstance, v as reviewInstanceStartHint, y as reviewInstanceUnavailable } from "./server-discovery-BVqrE1_-.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,9 +1,9 @@
|
|
|
1
1
|
import { c as jsonString, l as jsonValueSchema, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
2
|
-
import "./src-
|
|
2
|
+
import "./src-DsM3jO8G.js";
|
|
3
3
|
import "./review-home-paths-Lc02WFuX.js";
|
|
4
4
|
import { A as withFileLock, M as devReviewHome, O as processIsAlive, P as writeFileAtomic } from "./s3-config-DDWWMh5x.js";
|
|
5
5
|
import { i as readReviewPackageVersion, t as findReviewPackageRoot } from "./package-paths-jMg6JxDP.js";
|
|
6
|
-
import "./request-origin-
|
|
6
|
+
import "./request-origin-Zcn_CjX4.js";
|
|
7
7
|
import { createHmac, randomUUID } from "node:crypto";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { S as splitGitPatchFiles, a as diff, o as diffFileSummaries } from "../src-BMPuxWv4.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 { d as StreamLimitError, f as readBoundedStream, i as SharedReviewStore } from "../client-
|
|
5
|
-
import { u as pullRequestProvider } from "../local-data-
|
|
6
|
-
import {
|
|
4
|
+
import { d as StreamLimitError, f as readBoundedStream, i as SharedReviewStore } from "../client-BN_FDxFr.js";
|
|
5
|
+
import { u as pullRequestProvider } from "../local-data-DtQTIzHX.js";
|
|
6
|
+
import { M as reviewDiffrSummarizerInputSchema, O as ReviewGatewayHostSchema, T as ReviewConnectRequestSchema, c as ReviewBugReportMetaV2Schema, d as REVIEW_CLIENT_HEADER, f as REVIEW_CLIENT_REMOTE, g as REVIEW_HOST_HEADER, l as ReviewBugReportRequestSchema, r as parseReviewDesktopVerbFrame, s as parseZod, t as parseReviewCliInstallApplyRequest, u as parseReviewBugReportResponse } from "../src-DsM3jO8G.js";
|
|
7
7
|
import { i as reviewInstanceDiscoveryPath, o as reviewLegacyDiscoveryPath } from "../review-home-paths-Lc02WFuX.js";
|
|
8
|
-
import { w as resourceReferences } from "../stored-document-migration-
|
|
8
|
+
import { w as resourceReferences } from "../stored-document-migration-CChxtFAy.js";
|
|
9
9
|
import { t as ReviewInputError } from "../input-error-OLgB_h31.js";
|
|
10
10
|
import { I as writePrivateJsonAtomic, M as devReviewHome } from "../s3-config-DDWWMh5x.js";
|
|
11
11
|
import { t as errorMessage } from "../error-message-OtiDonty.js";
|
|
12
12
|
import { i as readReviewPackageVersion, t as findReviewPackageRoot } from "../package-paths-jMg6JxDP.js";
|
|
13
|
-
import { _ as reviewInstanceIdentity, u as REVIEW_INSTANCE_ENV } from "../server-discovery-
|
|
14
|
-
import { t as openReviewProfile } from "../profile-
|
|
15
|
-
import { r as reviewTelemetryChannel, t as ReviewTelemetry } from "../review-telemetry-
|
|
16
|
-
import { o as REVIEW_TELEMETRY_TABS } from "../request-origin-
|
|
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-
|
|
18
|
-
import { C as saveDiffrSummarizer, E as cliAskTools, S as readDiffrConfig, T as testDiffrSummarizer, _ as DEFAULT_MAX_REQUEST_BYTES, a as drainServerCrashReport, b as GlobalReviewDesktopVerbRelay, c as answerErrorsAsJson, d as legacyModeSchema, f as captureSanitizedUiTelemetry, g as readBoundedRequestJson, h as createNodeRequestListener, l as createWhiteboardCore, m as recordClientError, o as installProcessErrorTelemetry, p as clientErrorsForSession, r as takeOverServerHome, s as serverCrashReportPath, u as serverJson, v as HttpJsonError, w as setDiffrConfigValue, x as migrateDiffrConfig, y as ReviewServerError } from "../headless-host-
|
|
19
|
-
import { c as readQuerySchemas } from "../authoring-tools-
|
|
13
|
+
import { _ as reviewInstanceIdentity, u as REVIEW_INSTANCE_ENV } from "../server-discovery-BVqrE1_-.js";
|
|
14
|
+
import { t as openReviewProfile } from "../profile-DaqmODhc.js";
|
|
15
|
+
import { r as reviewTelemetryChannel, t as ReviewTelemetry } from "../review-telemetry-BHWJsnoD.js";
|
|
16
|
+
import { o as REVIEW_TELEMETRY_TABS } from "../request-origin-Zcn_CjX4.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-xOdmMnDH.js";
|
|
18
|
+
import { C as saveDiffrSummarizer, E as cliAskTools, S as readDiffrConfig, T as testDiffrSummarizer, _ as DEFAULT_MAX_REQUEST_BYTES, a as drainServerCrashReport, b as GlobalReviewDesktopVerbRelay, c as answerErrorsAsJson, d as legacyModeSchema, f as captureSanitizedUiTelemetry, g as readBoundedRequestJson, h as createNodeRequestListener, l as createWhiteboardCore, m as recordClientError, o as installProcessErrorTelemetry, p as clientErrorsForSession, r as takeOverServerHome, s as serverCrashReportPath, u as serverJson, v as HttpJsonError, w as setDiffrConfigValue, x as migrateDiffrConfig, y as ReviewServerError } from "../headless-host-CS4Gv0c5.js";
|
|
19
|
+
import { c as readQuerySchemas } from "../authoring-tools-DGSEag8y.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-
|
|
2
|
+
import { n as parseReviewDesktopDiscovery } from "./src-DsM3jO8G.js";
|
|
3
3
|
import { a as reviewInstancesDir, o as reviewLegacyDiscoveryPath, r as reviewDevInstanceKey, t as reviewDefaultInstancePath } from "./review-home-paths-Lc02WFuX.js";
|
|
4
4
|
import { M as devReviewHome, O as processIsAlive, j as DEV_REVIEW_HOME_ENV } from "./s3-config-DDWWMh5x.js";
|
|
5
5
|
import { z } from "zod";
|
package/dist/sharing/index.d.ts
CHANGED
|
@@ -1484,6 +1484,8 @@ declare class ReviewStore {
|
|
|
1484
1484
|
/** The one scratchpad, made on first use. A host that loses the race to
|
|
1485
1485
|
* another on the same home finds it made. */
|
|
1486
1486
|
ensureScratchpad(): Promise<void>;
|
|
1487
|
+
/** Two saved board/day pairs in the last fourteen days. */
|
|
1488
|
+
feedbackEligible(now?: number): boolean;
|
|
1487
1489
|
history(id: string): {
|
|
1488
1490
|
version: number;
|
|
1489
1491
|
title: string;
|
package/dist/sharing/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as sharedReviewId, c as verifyShareRepository, i as SharedReviewStore, l as exportShare, n as ShareClient, o as validateShareBundle } from "../client-
|
|
1
|
+
import { a as sharedReviewId, c as verifyShareRepository, i as SharedReviewStore, l as exportShare, n as ShareClient, o as validateShareBundle } from "../client-BN_FDxFr.js";
|
|
2
2
|
export { ShareClient, SharedReviewStore, exportShare, sharedReviewId, validateShareBundle, verifyShareRepository };
|
|
@@ -831,6 +831,66 @@ z.discriminatedUnion("ok", [z.strictObject({
|
|
|
831
831
|
toolCalls: z.number(),
|
|
832
832
|
events: z.array(ReviewAgentTraceEventSchema)
|
|
833
833
|
}), ReviewErrorResponseSchema]);
|
|
834
|
+
const REVIEW_FEEDBACK_CAMPAIGN = "whiteboard-feedback-2026-10";
|
|
835
|
+
/** The host supplies its persistent installation ID, not a form or launch ID. */
|
|
836
|
+
const feedbackId = z.string().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/);
|
|
837
|
+
const feedbackSelections = (values) => z.array(z.enum(values)).max(values.length).refine((items) => new Set(items).size === items.length);
|
|
838
|
+
/** Required survey answers and optional contact are separate submissions. */
|
|
839
|
+
const ReviewFeedbackSchema = z.strictObject({
|
|
840
|
+
id: feedbackId,
|
|
841
|
+
campaign: z.literal(REVIEW_FEEDBACK_CAMPAIGN),
|
|
842
|
+
environment: z.enum([
|
|
843
|
+
"production",
|
|
844
|
+
"preview",
|
|
845
|
+
"development",
|
|
846
|
+
"test"
|
|
847
|
+
]).optional(),
|
|
848
|
+
contexts: feedbackSelections([
|
|
849
|
+
"work",
|
|
850
|
+
"personal_projects",
|
|
851
|
+
"open_source_projects",
|
|
852
|
+
"other"
|
|
853
|
+
]).refine((items) => items.length > 0),
|
|
854
|
+
contextsOther: z.string().trim().max(500).optional(),
|
|
855
|
+
benefit: z.string().trim().min(1).max(4e3),
|
|
856
|
+
feature: z.enum([
|
|
857
|
+
"code_understanding",
|
|
858
|
+
"planning_editing",
|
|
859
|
+
"collaboration",
|
|
860
|
+
"other"
|
|
861
|
+
]),
|
|
862
|
+
featureOther: z.string().trim().max(500).optional(),
|
|
863
|
+
rating: z.number().int().min(1).max(5),
|
|
864
|
+
roles: feedbackSelections([
|
|
865
|
+
"developer",
|
|
866
|
+
"engineering_manager",
|
|
867
|
+
"founder",
|
|
868
|
+
"other"
|
|
869
|
+
]).refine((items) => items.length > 0),
|
|
870
|
+
rolesOther: z.string().trim().max(500).optional()
|
|
871
|
+
}).superRefine((response, context) => {
|
|
872
|
+
for (const [selected, other] of [
|
|
873
|
+
[response.contexts.includes("other"), "contextsOther"],
|
|
874
|
+
[response.feature === "other", "featureOther"],
|
|
875
|
+
[response.roles.includes("other"), "rolesOther"]
|
|
876
|
+
]) if (selected ? !response[other]?.trim() : response[other] !== void 0) context.addIssue({
|
|
877
|
+
code: "custom",
|
|
878
|
+
path: [other],
|
|
879
|
+
message: selected ? "Describe Other." : "Select Other before supplying its text."
|
|
880
|
+
});
|
|
881
|
+
});
|
|
882
|
+
const ReviewFeedbackContactSchema = z.strictObject({
|
|
883
|
+
kind: z.literal("contact"),
|
|
884
|
+
id: feedbackId,
|
|
885
|
+
campaign: z.literal(REVIEW_FEEDBACK_CAMPAIGN),
|
|
886
|
+
environment: z.enum([
|
|
887
|
+
"production",
|
|
888
|
+
"preview",
|
|
889
|
+
"development",
|
|
890
|
+
"test"
|
|
891
|
+
]).optional(),
|
|
892
|
+
email: z.email().max(254)
|
|
893
|
+
});
|
|
834
894
|
//#endregion
|
|
835
895
|
//#region ../review-protocol/src/bug-report.ts
|
|
836
896
|
const requiredString = z.string({ error: "must be a string" }).refine((value) => value.trim().length > 0, "must be a string");
|
|
@@ -979,4 +1039,4 @@ function formatIssuePath(path) {
|
|
|
979
1039
|
return output;
|
|
980
1040
|
}
|
|
981
1041
|
//#endregion
|
|
982
|
-
export {
|
|
1042
|
+
export { ReviewSelectedDiffSchema as A, ReviewApiSelectionSourceSchema as C, ReviewFeedbackSchema as D, ReviewFeedbackContactSchema as E, reviewDiffrSummarizerInputSchema as M, decodeStructuralDiffEvent as N, ReviewGatewayHostSchema as O, structuralChangeCounts as P, REVIEW_THEME_CHOICES as S, ReviewConnectRequestSchema as T, REVIEW_REMOTE_AGENT_IDS as _, parseReviewVerbRequest as a, REVIEW_REMOTE_INSTALL_LOCK as b, ReviewBugReportMetaV2Schema as c, REVIEW_CLIENT_HEADER as d, REVIEW_CLIENT_REMOTE as f, REVIEW_HOST_HEADER as g, REVIEW_DIFF_LAYOUT_SCOPES as h, parseReviewDesktopVerbResult as i, SCRATCHPAD_REVIEW_ID as j, ReviewOnboardingRunRequestSchema as k, ReviewBugReportRequestSchema as l, REVIEW_DIFF_LAYOUTS as m, parseReviewDesktopDiscovery as n, parseReviewVerbResponse as o, REVIEW_CLI_INSTALL_TARGET_LABELS as p, parseReviewDesktopVerbFrame as r, parseZod as s, parseReviewCliInstallApplyRequest as t, parseReviewBugReportResponse as u, REVIEW_REMOTE_ATTACH_BEGIN as v, ReviewCliInstallStampSchema as w, REVIEW_REMOTE_WRAPPER_MARK as x, REVIEW_REMOTE_ATTACH_END as y };
|
package/dist/{stored-document-migration-DLBhkSfp.js → stored-document-migration-CChxtFAy.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { f as isNumberValue, l as jsonValueSchema, m as isStringValue, n as isJsonObject } from "./src-X9phtB2j.js";
|
|
2
|
-
import "./src-
|
|
2
|
+
import "./src-DsM3jO8G.js";
|
|
3
3
|
import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { fromMarkdown } from "mdast-util-from-markdown";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as ReviewSelectedDiffSchema, C as ReviewApiSelectionSourceSchema } from "./src-DsM3jO8G.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
/** A semantic selection, independent of comment/thread creation. */
|
|
4
4
|
const AgentSelectionSchema = z.strictObject({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { m as isStringValue, n as isJsonObject } from "./src-X9phtB2j.js";
|
|
2
|
-
import { n as callAuthoringTool, s as ReviewApiError, t as ToolText } from "./agent-client-
|
|
2
|
+
import { n as callAuthoringTool, s as ReviewApiError, t as ToolText } from "./agent-client-BRBzv3AV.js";
|
|
3
3
|
import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
|
|
4
4
|
//#region src/review-api/public-tools.ts
|
|
5
5
|
function publicDescription(text) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev.fast/whiteboard",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3-preview.20261018.124",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"vitest": "4.1.11",
|
|
77
77
|
"@dev.fast/json": "0.0.0",
|
|
78
78
|
"@dev.fast/review-protocol": "0.0.0",
|
|
79
|
+
"@dev.fast/trace-protocol": "0.5.0",
|
|
79
80
|
"@dev.fast/trace-core": "0.0.0",
|
|
80
|
-
"@dev.fast/review-share-protocol": "0.1.2"
|
|
81
|
-
"@dev.fast/trace-protocol": "0.5.0"
|
|
81
|
+
"@dev.fast/review-share-protocol": "0.1.2"
|
|
82
82
|
},
|
|
83
83
|
"engines": {
|
|
84
84
|
"node": ">=24 <25"
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"repo": "devdotfast/review",
|
|
89
89
|
"docs": "packages/review/instructions/authoring.md"
|
|
90
90
|
},
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "710b08c0dcb2166b8088ded6af639dd9598288c9",
|
|
92
92
|
"scripts": {
|
|
93
93
|
"prebuild": "pnpm run build:workspace-deps",
|
|
94
94
|
"build": "node --max-old-space-size=8192 node_modules/tsdown/dist/run.mjs",
|
package/src/review-api/http.ts
CHANGED
|
@@ -317,6 +317,10 @@ export function createReviewApi(
|
|
|
317
317
|
return context.json(catalog());
|
|
318
318
|
});
|
|
319
319
|
|
|
320
|
+
app.get("/feedback-eligibility", (context) =>
|
|
321
|
+
context.json({ eligible: store.feedbackEligible() }),
|
|
322
|
+
);
|
|
323
|
+
|
|
320
324
|
// Server-owned state only: asking the Desktop canvas would let a stalled
|
|
321
325
|
// renderer block tool listing and the first instructions call.
|
|
322
326
|
const instructionContext = async () => ({
|
package/src/review-api/store.ts
CHANGED
|
@@ -1074,6 +1074,26 @@ export class ReviewStore {
|
|
|
1074
1074
|
if (!this.has(SCRATCHPAD_ID)) throw error;
|
|
1075
1075
|
}
|
|
1076
1076
|
}
|
|
1077
|
+
/** Two saved board/day pairs in the last fourteen days. */
|
|
1078
|
+
feedbackEligible(now = Date.now()): boolean {
|
|
1079
|
+
const row = this.db
|
|
1080
|
+
.prepare(`SELECT count(*) AS pairs FROM (
|
|
1081
|
+
SELECT DISTINCT review_id, date(json_extract(snapshot, '$.createdAt')) AS utc_date
|
|
1082
|
+
FROM versions
|
|
1083
|
+
WHERE (version = 0 OR json_type(snapshot, '$.lastEdit') = 'object')
|
|
1084
|
+
AND json_extract(snapshot, '$.kind') IS NOT 'scratchpad'
|
|
1085
|
+
AND json_extract(snapshot, '$.origin.tutorial') IS NOT 1
|
|
1086
|
+
AND julianday(json_extract(snapshot, '$.createdAt')) BETWEEN julianday(?) AND julianday(?)
|
|
1087
|
+
LIMIT 2
|
|
1088
|
+
)`)
|
|
1089
|
+
.get(
|
|
1090
|
+
new Date(now - 14 * 24 * 60 * 60 * 1000).toISOString(),
|
|
1091
|
+
new Date(now).toISOString(),
|
|
1092
|
+
);
|
|
1093
|
+
|
|
1094
|
+
return Number(row?.pairs) >= 2;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1077
1097
|
history(id: string) {
|
|
1078
1098
|
return this.db
|
|
1079
1099
|
.prepare(
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ReviewFeedbackContactSchema,
|
|
3
|
+
ReviewFeedbackSchema,
|
|
4
|
+
} from "@dev.fast/review-protocol";
|
|
5
|
+
import { reviewInstanceIdentity } from "@review/desktop-discovery";
|
|
6
|
+
import type { Hono } from "hono";
|
|
7
|
+
|
|
8
|
+
import { type ReviewHonoEnv, readBoundedRequestJson } from "./hono-http";
|
|
9
|
+
|
|
10
|
+
const FEEDBACK_URL = "https://dev.fast/api/feedback";
|
|
11
|
+
|
|
12
|
+
/** Runs behind the local API's auth middleware. No telemetry envelope is sent. */
|
|
13
|
+
export function mountFeedback(app: Hono<ReviewHonoEnv>) {
|
|
14
|
+
// Dev/Preview can exercise the form against a local receiver.
|
|
15
|
+
const localUrl = process.env.DEV_FAST_REVIEW_FEEDBACK_URL;
|
|
16
|
+
|
|
17
|
+
const receiver =
|
|
18
|
+
localUrl &&
|
|
19
|
+
reviewInstanceIdentity(process.env).channel !== "stable" &&
|
|
20
|
+
["localhost", "127.0.0.1", "[::1]"].includes(new URL(localUrl).hostname)
|
|
21
|
+
? localUrl
|
|
22
|
+
: FEEDBACK_URL;
|
|
23
|
+
|
|
24
|
+
for (const [path, schema] of [
|
|
25
|
+
["/feedback", ReviewFeedbackSchema],
|
|
26
|
+
["/feedback/contact", ReviewFeedbackContactSchema],
|
|
27
|
+
] as const) {
|
|
28
|
+
app.post(path, async (context) => {
|
|
29
|
+
const input = schema.safeParse(
|
|
30
|
+
await readBoundedRequestJson(context.req.raw, 65_536),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
if (!input.success)
|
|
34
|
+
return context.json({ ok: false, error: "Invalid feedback." }, 400);
|
|
35
|
+
|
|
36
|
+
const signal = AbortSignal.any([
|
|
37
|
+
context.req.raw.signal,
|
|
38
|
+
AbortSignal.timeout(5_000),
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(receiver, {
|
|
43
|
+
method: "POST",
|
|
44
|
+
headers: { "content-type": "application/json" },
|
|
45
|
+
body: JSON.stringify(input.data),
|
|
46
|
+
signal,
|
|
47
|
+
redirect: "error",
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const body = await response.json().catch((error) => {
|
|
51
|
+
if (signal.aborted || error instanceof TypeError) throw error;
|
|
52
|
+
|
|
53
|
+
return null;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
if (!response.ok || body?.ok !== true) {
|
|
57
|
+
return context.json(
|
|
58
|
+
{
|
|
59
|
+
ok: false,
|
|
60
|
+
code: "receiver",
|
|
61
|
+
error: "Feedback could not be saved. Please try again.",
|
|
62
|
+
},
|
|
63
|
+
502,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return context.json({ ok: true });
|
|
68
|
+
} catch {
|
|
69
|
+
return context.json(
|
|
70
|
+
{
|
|
71
|
+
ok: false,
|
|
72
|
+
code: "network",
|
|
73
|
+
error: "Feedback could not be saved. Please try again.",
|
|
74
|
+
},
|
|
75
|
+
502,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -30,6 +30,7 @@ import { streamSSE } from "hono/streaming";
|
|
|
30
30
|
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
|
31
31
|
import { z } from "zod";
|
|
32
32
|
|
|
33
|
+
import { mountFeedback } from "./feedback";
|
|
33
34
|
import type { ReviewDesktopVerbRelay } from "./global-verb-relay";
|
|
34
35
|
import {
|
|
35
36
|
type ReviewHonoEnv,
|
|
@@ -92,6 +93,7 @@ export function createReviewServerApp(input: {
|
|
|
92
93
|
await next();
|
|
93
94
|
});
|
|
94
95
|
app.get("/control", (context) => openControlEvents(context, input.relay));
|
|
96
|
+
mountFeedback(app);
|
|
95
97
|
app.post("/control/result", async (context) => {
|
|
96
98
|
const accepted = input.relay.acceptResult(
|
|
97
99
|
await readBoundedRequestJson(context.req.raw),
|
package/dist/profile-D1rScZ-E.js
DELETED