@dev.fast/whiteboard 0.2.5-preview.20261013.112 → 0.2.5-preview.20261015.115
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/THIRD_PARTY_NOTICES.md +29 -0
- package/dist/{account-alias-D0hF0sKk.js → account-alias-ChZR3RIU.js} +94 -8
- package/dist/{agent-cli-BBPxwUOd.js → agent-cli-CR2PnA9G.js} +9 -12
- package/dist/agent-cli-CRPPmS3l.js +2 -0
- package/dist/{agent-client-P3J4y8Zn.js → agent-client-DVd-prfp.js} +31 -14
- package/dist/{authoring-tools-D8WXsm_g.js → authoring-tools-BXKEwhfi.js} +5 -5
- package/dist/background-server-Cw7CcfaZ.js +156 -0
- package/dist/background-server-D2Rrr_e2.js +2 -0
- package/dist/build-info.json +1 -1
- package/dist/{cli-C0ziP6hg.js → cli-CSrz_wGk.js} +1 -1
- package/dist/{cli-runner-C1gY-HAI.js → cli-runner-PlGqBeMw.js} +368 -252
- package/dist/cli.js +3 -2
- package/dist/{client-DzcSt6pV.js → client-DhZzPePs.js} +5 -3
- package/dist/{process-error-telemetry-C0swByfp.js → headless-host-CVXTSIlx.js} +3285 -2585
- package/dist/headless-host-Cp37C-v0.js +2 -0
- package/dist/input-error-OLgB_h31.js +11 -0
- package/dist/{local-data-BlERtVm2.js → local-data-yfLp5PiJ.js} +237 -157
- package/dist/{mcp-t7VN9R3k.js → mcp-DBbDwG4y.js} +4 -4
- package/dist/{package-paths-B9PDoAl6.js → package-paths-BsuI4WUf.js} +1 -1
- package/dist/profile-BSOkA6A-.js +2 -0
- package/dist/{profile-BsYDBr7t.js → profile-pAzg7fxC.js} +3 -3
- package/dist/remote-attach-BAt2eZx3.js +137 -0
- package/dist/remote-extensions-2Cxf3hMo.js +2 -0
- package/dist/remote-extensions-BiNx6NQK.js +323 -0
- package/dist/remote-language-server-DQgWUNeV.js +252 -0
- package/dist/remote-uninstall-DLtDG0o7.js +153 -0
- package/dist/{request-origin-DA4K1qWY.js → request-origin-DaRIV3cB.js} +5 -2
- package/dist/review-app-launcher-D7I4DGoH.js +222 -0
- package/dist/{review-home-paths-Y9mYWkCI.js → review-home-paths-zwevIq4I.js} +7 -7
- package/dist/{review-telemetry-CmM6tCbj.js → review-telemetry-BqB4CiTD.js} +5 -5
- package/dist/{s3-SzLpeCG6.js → s3-77-qkEhs.js} +1 -1
- package/dist/{s3-config-BgxkSoOy.js → s3-config-0xuCh-F_.js} +1 -1
- package/dist/{s3-config-CAxhO9u_.js → s3-config-DDWWMh5x.js} +5 -1
- package/dist/server/desktop-host.js +1663 -266
- package/dist/{desktop-discovery-Ba3dD5Cn.js → server-discovery-CifQ3yQS.js} +88 -3
- package/dist/sharing/index.d.ts +88 -32
- package/dist/sharing/index.js +1 -1
- package/dist/{src-DiHP11l3.js → src-BMPuxWv4.js} +6 -11
- package/dist/{src-WCbabvdS.js → src-Bgvf1sEN.js} +128 -8
- package/dist/{stored-document-migration-u4L_1VZa.js → stored-document-migration-CFOvjRwW.js} +5 -18
- package/dist/{tool-failure-CJHBCHMh.js → tool-failure-BXWzQG8T.js} +2 -2
- package/instructions/authoring.md +16 -12
- package/instructions/file-lenses.md +4 -2
- package/package.json +9 -14
- package/src/agent-connect.ts +507 -0
- package/src/agent-selection.ts +4 -0
- package/src/ask/agents.ts +59 -13
- package/src/ask/pi-mcp.ts +7 -3
- package/src/ask/thread-state.ts +9 -4
- package/src/ask/thread.ts +88 -50
- package/src/ask/threads.ts +53 -7
- package/src/cli-install.ts +3 -1
- package/src/cli-runner.ts +472 -81
- package/src/cli.ts +1 -1
- package/src/connect-agents.ts +285 -0
- package/src/connect-prompts.ts +60 -6
- package/src/desktop-discovery.ts +24 -0
- package/src/pinned-download.ts +118 -0
- package/src/remote-attach.ts +130 -0
- package/src/remote-extensions.ts +359 -0
- package/src/remote-language-server.ts +428 -0
- package/src/remote-toolchains.ts +107 -0
- package/src/remote-uninstall.ts +280 -0
- package/src/review-api/README.md +1 -3
- package/src/review-api/agent-cli.ts +4 -4
- package/src/review-api/agent-client.ts +23 -0
- package/src/review-api/ask-history.ts +31 -16
- package/src/review-api/authoring-tools.ts +1 -1
- package/src/review-api/blocks/index.ts +2 -4
- package/src/review-api/document.ts +1 -4
- package/src/review-api/github-provider.ts +154 -0
- package/src/review-api/http.ts +265 -237
- package/src/review-api/local-data.ts +34 -17
- package/src/review-api/onboarding.ts +478 -0
- package/src/review-api/origin.ts +10 -6
- package/src/review-api/provider.ts +44 -0
- package/src/review-api/pull-request.ts +15 -146
- package/src/review-api/recent-folders.ts +173 -0
- package/src/review-api/store.ts +56 -10
- package/src/review-api/workspaces.ts +56 -11
- package/src/review-app-launcher.ts +61 -3
- package/src/review-stack.ts +162 -36
- package/src/server/background-server.ts +250 -0
- package/src/server/desktop-host-shutdown.ts +24 -0
- package/src/server/desktop-host.ts +39 -24
- package/src/server/desktop-server.ts +68 -118
- package/src/server/global-verb-relay.ts +16 -0
- package/src/server/headless-host.ts +128 -3
- package/src/server/hono-http.ts +6 -1
- package/src/server/legacy-tutorial-cleanup.ts +38 -0
- package/src/server/review-gateway-hosts.ts +379 -0
- package/src/server/review-gateway-list.ts +109 -0
- package/src/server/review-gateway-memory.ts +130 -0
- package/src/server/review-gateway-pushes.ts +142 -0
- package/src/server/review-gateway-streams.ts +415 -0
- package/src/server/review-gateway-transport.ts +204 -0
- package/src/server/review-gateway.ts +433 -0
- package/src/server/review-server-core.ts +36 -6
- package/src/server-discovery.ts +11 -0
- package/src/sharing/import.ts +1 -0
- package/src/ui-telemetry-events.ts +5 -1
- package/src/vsix.ts +122 -0
- package/dist/agent-cli-YSuhE5X8.js +0 -2
- package/dist/headless-host-BHD_Vg5F.js +0 -95
- package/dist/profile-j97aRTS7.js +0 -2
- package/dist/server-discovery-ZVi8Ay8J.js +0 -66
- package/src/fixtures/blocks/tutorial.json +0 -14
- package/src/review-api/blocks/tutorial.ts +0 -23
- package/src/server/tutorial-service.ts +0 -217
- package/tutorial/document.json +0 -216
- package/tutorial/lenses.json +0 -10
- package/tutorial/runtime-manifest.json +0 -11
- package/tutorial/sample-service/package.json +0 -9
- package/tutorial/sample-service/src/api/checkout-api.ts +0 -17
- package/tutorial/sample-service/src/app.ts +0 -26
- package/tutorial/sample-service/src/database/drizzle-orm.d.ts +0 -16
- package/tutorial/sample-service/src/database/schema.ts +0 -9
- package/tutorial/sample-service/src/fulfillment/fulfillment-queue.ts +0 -15
- package/tutorial/sample-service/src/fulfillment/fulfillment-worker.ts +0 -24
- package/tutorial/sample-service/src/inventory/forklift-mood.ts +0 -4
- package/tutorial/sample-service/src/inventory/inventory-service.ts +0 -28
- package/tutorial/sample-service/src/inventory/warehouse-lore.ts +0 -11
- package/tutorial/sample-service/src/orders/order-service.ts +0 -35
- package/tutorial/sample-service/src/orders/order.ts +0 -43
- package/tutorial/sample-service/src/orders/orders-repository.ts +0 -24
- package/tutorial/sample-service/src/payments/fraud-vibes.ts +0 -4
- package/tutorial/sample-service/src/payments/payment-gateway.ts +0 -29
- package/tutorial/sample-service/src/payments/raccoon-ledger.ts +0 -9
- package/tutorial/sample-service/src/shipping/shipping-gateway.ts +0 -15
- package/tutorial/sample-service/tsconfig.json +0 -12
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -91,3 +91,32 @@ Direct third-party runtime/UI dependencies currently include:
|
|
|
91
91
|
- `semver` (`ISC`)
|
|
92
92
|
- `zod` (`MIT`)
|
|
93
93
|
- `zustand` (`MIT`)
|
|
94
|
+
- `yauzl` (`MIT`)
|
|
95
|
+
|
|
96
|
+
## Bundled VS Code Server
|
|
97
|
+
|
|
98
|
+
The published package carries `vscode-server/`, staged by
|
|
99
|
+
`apps/review-desktop/scripts/stage-vscode-server.mjs`. It is built from the
|
|
100
|
+
Code OSS fork (`MIT`) and carries the fork's `LICENSE.txt` and
|
|
101
|
+
`ThirdPartyNotices.txt`. It bundles:
|
|
102
|
+
|
|
103
|
+
- in the server and extension host (`MIT` unless noted): `@vscode/proxy-agent`,
|
|
104
|
+
`agent-base`, `cookie`, `debug`, `http-proxy-agent`, `https-proxy-agent`,
|
|
105
|
+
`ip-address`, `minimist`, `ms`, `smart-buffer`, `socks`,
|
|
106
|
+
`socks-proxy-agent`, `supports-color`, `undici`, `vscode-regexpp` and
|
|
107
|
+
`tslib` (`0BSD`)
|
|
108
|
+
- in the built-in language extensions (`MIT` unless noted): `@vscode/l10n`,
|
|
109
|
+
`@vscode/sync-api-client`, `@vscode/sync-api-common`,
|
|
110
|
+
`@vscode/sync-api-service`, `@vscode/ts-package-manager`, `jsonc-parser`,
|
|
111
|
+
`request-light`, `semver` (`ISC`), `vscode-css-languageservice`,
|
|
112
|
+
`vscode-html-languageservice`, `vscode-json-languageservice`,
|
|
113
|
+
`vscode-languageclient`, `vscode-languageserver`,
|
|
114
|
+
`vscode-languageserver-textdocument`, `vscode-tas-client` and `vscode-uri`
|
|
115
|
+
- `typescript` (`Apache-2.0`), for the built-in TypeScript extension
|
|
116
|
+
- `@vscode/ripgrep-universal` (`MIT`), whose `rg` binaries are ripgrep
|
|
117
|
+
(`MIT OR Unlicense`)
|
|
118
|
+
- `@parcel/watcher` and its Linux prebuilds (`MIT`), with `detect-libc`
|
|
119
|
+
(`Apache-2.0`), `is-glob`, `is-extglob` and `picomatch` (`MIT`)
|
|
120
|
+
|
|
121
|
+
Curated extensions are not bundled; `whiteboard remote extensions ensure`
|
|
122
|
+
downloads them from Open VSX on the remote.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { C as disableTraceMachine, E as traceMachineStatus, G as listTraceRepositoryRoots, K as traceRepositoryStatus, Q as
|
|
3
|
-
import { A as
|
|
4
|
-
import { i as readReviewPackageVersion } from "./package-paths-
|
|
1
|
+
import { w as ReviewCliInstallStampSchema } from "./src-Bgvf1sEN.js";
|
|
2
|
+
import { $ as removeAgentTraceHook, C as disableTraceMachine, E as traceMachineStatus, G as listTraceRepositoryRoots, K as traceRepositoryStatus, Q as installHarnessHooks, S as configureTraceMachine, T as traceMachineEnabled, U as disableAllTraceRepositories, W as enableTraceRepository, Y as AGENT_TRACE_HOOK_AGENTS, Z as describeTraceHookOwners, ft as StoreClient, n as reviewDesktopStateDir, rt as traceScope, st as readStoreAuth } from "./review-home-paths-zwevIq4I.js";
|
|
3
|
+
import { A as withFileLock, F as writeFileAtomicAsync, I as writePrivateJsonAtomic, M as devReviewHome } from "./s3-config-DDWWMh5x.js";
|
|
4
|
+
import { i as readReviewPackageVersion } from "./package-paths-BsuI4WUf.js";
|
|
5
5
|
import { n as isFile, t as isDirectory } from "./fs-utils-BMPLt0cr.js";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import { constants } from "node:fs";
|
|
@@ -75,12 +75,84 @@ function fffSteps(input, target) {
|
|
|
75
75
|
const CLAUDE_WINDOWS_MCP_ADD = `claude mcp add -s user whiteboard -- ${WINDOWS_MCP_LAUNCH.command} ${WINDOWS_MCP_LAUNCH.args.join(" ")}`;
|
|
76
76
|
/** Copilot CLI loads the Claude plugin, so on Windows it too registers the server directly. */
|
|
77
77
|
const COPILOT_WINDOWS_MCP_ADD = `copilot mcp add whiteboard -- ${WINDOWS_MCP_LAUNCH.command} ${WINDOWS_MCP_LAUNCH.args.join(" ")}`;
|
|
78
|
+
const CONNECT_COMMANDS = {
|
|
79
|
+
claude: [
|
|
80
|
+
{ argv: [
|
|
81
|
+
"claude",
|
|
82
|
+
"plugin",
|
|
83
|
+
"marketplace",
|
|
84
|
+
"add",
|
|
85
|
+
"devdotfast/whiteboard"
|
|
86
|
+
] },
|
|
87
|
+
{ argv: [
|
|
88
|
+
"claude",
|
|
89
|
+
"plugin",
|
|
90
|
+
"install",
|
|
91
|
+
"whiteboard@devfast",
|
|
92
|
+
"--scope",
|
|
93
|
+
"user"
|
|
94
|
+
] },
|
|
95
|
+
{
|
|
96
|
+
argv: [
|
|
97
|
+
"claude",
|
|
98
|
+
"mcp",
|
|
99
|
+
"remove",
|
|
100
|
+
"-s",
|
|
101
|
+
"user",
|
|
102
|
+
"whiteboard"
|
|
103
|
+
],
|
|
104
|
+
ifAny: true
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
codex: [
|
|
108
|
+
{ argv: [
|
|
109
|
+
"codex",
|
|
110
|
+
"plugin",
|
|
111
|
+
"marketplace",
|
|
112
|
+
"add",
|
|
113
|
+
"devdotfast/whiteboard"
|
|
114
|
+
] },
|
|
115
|
+
{ argv: [
|
|
116
|
+
"codex",
|
|
117
|
+
"plugin",
|
|
118
|
+
"add",
|
|
119
|
+
"whiteboard@devfast"
|
|
120
|
+
] },
|
|
121
|
+
{
|
|
122
|
+
argv: [
|
|
123
|
+
"codex",
|
|
124
|
+
"mcp",
|
|
125
|
+
"remove",
|
|
126
|
+
"whiteboard"
|
|
127
|
+
],
|
|
128
|
+
ifAny: true
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
opencode: [{ argv: [
|
|
132
|
+
"opencode",
|
|
133
|
+
"mcp",
|
|
134
|
+
"add",
|
|
135
|
+
"--global",
|
|
136
|
+
"whiteboard",
|
|
137
|
+
"--",
|
|
138
|
+
REVIEW_MCP_LAUNCH.command,
|
|
139
|
+
...REVIEW_MCP_LAUNCH.args
|
|
140
|
+
] }],
|
|
141
|
+
pi: [{ argv: [
|
|
142
|
+
"pi",
|
|
143
|
+
"install",
|
|
144
|
+
PI_WHITEBOARD_PACKAGE
|
|
145
|
+
] }]
|
|
146
|
+
};
|
|
147
|
+
function runBlock(commands) {
|
|
148
|
+
return `Run:\n\n\`\`\`sh\n${commands.map(({ argv, ifAny }) => `${argv.join(" ")}${ifAny ? " # old manual registration, if any" : ""}`).join("\n")}\n\`\`\``;
|
|
149
|
+
}
|
|
78
150
|
function pluginSteps(target, platform) {
|
|
79
151
|
switch (target) {
|
|
80
152
|
case "claude":
|
|
81
153
|
if (platform === "win32") return [`Run:\n\n\`\`\`sh\nclaude plugin uninstall whiteboard@devfast # its launch cannot start on Windows, if installed\nclaude mcp remove -s user whiteboard # old registration, if any\n${CLAUDE_WINDOWS_MCP_ADD}\n\`\`\``];
|
|
82
|
-
return [
|
|
83
|
-
case "codex": return [
|
|
154
|
+
return [runBlock(CONNECT_COMMANDS.claude)];
|
|
155
|
+
case "codex": return [runBlock(CONNECT_COMMANDS.codex)];
|
|
84
156
|
case "opencode": {
|
|
85
157
|
const launch = reviewMcpLaunch(true, platform);
|
|
86
158
|
const entry = JSON.stringify({ whiteboard: {
|
|
@@ -145,6 +217,20 @@ function connectPrompts(input) {
|
|
|
145
217
|
};
|
|
146
218
|
}
|
|
147
219
|
//#endregion
|
|
220
|
+
//#region src/install.ts
|
|
221
|
+
const ALL_INSTALL_TARGETS = [
|
|
222
|
+
"claude",
|
|
223
|
+
"codex",
|
|
224
|
+
"cursor",
|
|
225
|
+
"opencode",
|
|
226
|
+
"pi",
|
|
227
|
+
"omp",
|
|
228
|
+
"copilot"
|
|
229
|
+
];
|
|
230
|
+
function isInstallTarget(value) {
|
|
231
|
+
return ALL_INSTALL_TARGETS.some((target) => target === value);
|
|
232
|
+
}
|
|
233
|
+
//#endregion
|
|
148
234
|
//#region src/legacy-skills.ts
|
|
149
235
|
const LEGACY_SKILL_NAMES = [
|
|
150
236
|
"whiteboard",
|
|
@@ -316,7 +402,7 @@ async function windowsUserPathContains(directory, key = "HKCU\\Environment") {
|
|
|
316
402
|
const installErrors = /* @__PURE__ */ new Map();
|
|
317
403
|
const SHIM_MARKER = "Managed by Whiteboard";
|
|
318
404
|
function hasManagedShimMarker(source) {
|
|
319
|
-
return source.includes(SHIM_MARKER) || source.includes("Managed by Review Desktop") || source.includes("Managed by Whiteboard Desktop");
|
|
405
|
+
return source.includes(SHIM_MARKER) || source.includes("Managed by Review Desktop") || source.includes("Managed by Whiteboard Desktop") || source.includes("# Written by Whiteboard Desktop, which replaces it with each install.");
|
|
320
406
|
}
|
|
321
407
|
const PROFILE_MARKER = "# Managed by Review Desktop: review command PATH. Do not edit.";
|
|
322
408
|
const PROFILE_BLOCK = `\n${PROFILE_MARKER}\nexport PATH="\$HOME/.local/bin:\$PATH"\n`;
|
|
@@ -969,4 +1055,4 @@ async function aliasInstallationToAccount(telemetry, env = process.env, fetchImp
|
|
|
969
1055
|
} catch {}
|
|
970
1056
|
}
|
|
971
1057
|
//#endregion
|
|
972
|
-
export { isOwnedShim as a, removeLegacyReviewSkills as c, skipCliInstall as d, windowsInstallerCommand as f, finishCliInstallUpdate as i, resetCliInstall as l,
|
|
1058
|
+
export { connectPrompts as _, isOwnedShim as a, removeLegacyReviewSkills as c, skipCliInstall as d, windowsInstallerCommand as f, CONNECT_COMMANDS as g, isInstallTarget as h, finishCliInstallUpdate as i, resetCliInstall as l, ALL_INSTALL_TARGETS as m, applyCliInstall as n, pathShimPath as o, scanLegacySkills as p, declineCliInstall as r, removeCliInstall as s, aliasInstallationToAccount as t, resolveCliInstallStatus as u, reviewMcpLaunch as v, cursorInstallDeeplink as y };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
2
|
-
import { T as traceMachineEnabled } from "./review-home-paths-
|
|
3
|
-
import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { n as reviewSessionAgent } from "./review-telemetry-
|
|
7
|
-
import { n as REVIEW_VIA_HEADER, t as REVIEW_AGENT_HEADER } from "./request-origin-
|
|
8
|
-
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-
|
|
2
|
+
import { T as traceMachineEnabled } from "./review-home-paths-zwevIq4I.js";
|
|
3
|
+
import { a as toolResultText, i as connectReviewInstance, s as ReviewApiError } from "./agent-client-DVd-prfp.js";
|
|
4
|
+
import { M as devReviewHome } from "./s3-config-DDWWMh5x.js";
|
|
5
|
+
import { b as selectReviewInstance, u as REVIEW_INSTANCE_ENV } from "./server-discovery-CifQ3yQS.js";
|
|
6
|
+
import { n as reviewSessionAgent } from "./review-telemetry-BqB4CiTD.js";
|
|
7
|
+
import { n as REVIEW_VIA_HEADER, t as REVIEW_AGENT_HEADER } from "./request-origin-DaRIV3cB.js";
|
|
8
|
+
import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-BXWzQG8T.js";
|
|
9
9
|
//#region src/review-api/agent-cli.ts
|
|
10
10
|
const reviewAgentCliHelp = "whiteboard api tools (one line per tool)\nwhiteboard api tools <tool-name> (its description and input schema)\nwhiteboard api <tool-name> '<json>'\nwhiteboard api <tool-name> - (read JSON from stdin)\nwhiteboard mcp (stdio MCP adapter; Whiteboard Desktop or whiteboard server start must be running)\nSelect headless state with DEV_REVIEW_SERVER_DIR or whiteboard --state-dir <path> api/mcp.\n";
|
|
11
11
|
async function runReviewAgentCli(input) {
|
|
@@ -18,12 +18,9 @@ async function runReviewAgentCli(input) {
|
|
|
18
18
|
return 0;
|
|
19
19
|
}
|
|
20
20
|
if (extra.length || mode === "mcp" && name) throw new Error("Unexpected arguments. Use whiteboard api --help.");
|
|
21
|
-
const headers =
|
|
22
|
-
[REVIEW_VIA_HEADER]: mode === "mcp" ? "mcp" : "api",
|
|
23
|
-
[REVIEW_AGENT_HEADER]: reviewSessionAgent(env)
|
|
24
|
-
};
|
|
21
|
+
const headers = Object.fromEntries([[REVIEW_VIA_HEADER, mode === "mcp" ? "mcp" : "api"], [REVIEW_AGENT_HEADER, reviewSessionAgent(env)]]);
|
|
25
22
|
if (mode === "mcp") {
|
|
26
|
-
const { serveReviewMcp } = await import("./mcp-
|
|
23
|
+
const { serveReviewMcp } = await import("./mcp-DBbDwG4y.js");
|
|
27
24
|
await serveReviewMcp(async (key, agentKind) => {
|
|
28
25
|
const connected = await connectReviewInstance(key ? {
|
|
29
26
|
...env,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { C as ReviewInputError } from "./src-DiHP11l3.js";
|
|
2
1
|
import { d as isBooleanValue, f as isNumberValue, m as isStringValue, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
3
|
-
import "./src-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import "./src-Bgvf1sEN.js";
|
|
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-CifQ3yQS.js";
|
|
6
5
|
//#region ../review-protocol/src/review-api-client.ts
|
|
7
6
|
const defaultRequest = (url, init) => fetch(url, init);
|
|
8
7
|
/** A non-2xx reply; the status tells a caller whether retrying can help. */
|
|
@@ -44,8 +43,8 @@ var ReviewApiClient = class {
|
|
|
44
43
|
signal
|
|
45
44
|
})).json();
|
|
46
45
|
}
|
|
47
|
-
async *watch(
|
|
48
|
-
const reader = (await this.response(
|
|
46
|
+
async *watch(subscriptions, signal) {
|
|
47
|
+
const reader = (await this.response(`/watch?subscriptions=${encodeURIComponent(JSON.stringify(subscriptions))}`, { signal })).body.pipeThrough(new TextDecoderStream()).getReader();
|
|
49
48
|
const cancel = () => {
|
|
50
49
|
reader.cancel().catch(() => {});
|
|
51
50
|
};
|
|
@@ -73,7 +72,7 @@ var ReviewApiClient = class {
|
|
|
73
72
|
if (signal.aborted) return;
|
|
74
73
|
let connections = liveConnections.get(this.request);
|
|
75
74
|
if (!connections) liveConnections.set(this.request, connections = /* @__PURE__ */ new Map());
|
|
76
|
-
const key =
|
|
75
|
+
const key = this.liveKey();
|
|
77
76
|
let live = connections.get(key);
|
|
78
77
|
if (!live) {
|
|
79
78
|
live = new LiveConnection(this, () => connections.delete(key));
|
|
@@ -83,6 +82,13 @@ var ReviewApiClient = class {
|
|
|
83
82
|
if (mode) subscription.mode = mode;
|
|
84
83
|
return live.add(subscription, signal, (value) => accept(value), disconnected);
|
|
85
84
|
}
|
|
85
|
+
/** Reopen the shared stream now rather than after its backoff. */
|
|
86
|
+
reconnect() {
|
|
87
|
+
liveConnections.get(this.request)?.get(this.liveKey())?.reconnect();
|
|
88
|
+
}
|
|
89
|
+
liveKey() {
|
|
90
|
+
return JSON.stringify([this.connection.serverUrl, this.connection.token]);
|
|
91
|
+
}
|
|
86
92
|
};
|
|
87
93
|
const restartDelayMs = 20;
|
|
88
94
|
const retryDelayMs = 1e3;
|
|
@@ -97,6 +103,9 @@ function sleep(ms, signal) {
|
|
|
97
103
|
signal.addEventListener("abort", done, { once: true });
|
|
98
104
|
});
|
|
99
105
|
}
|
|
106
|
+
function concerns(line, subscription) {
|
|
107
|
+
return line.kind === "list" ? subscription.reviewId === null && (subscription.mode ?? "structural") === line.mode : subscription.reviewId === line.reviewId;
|
|
108
|
+
}
|
|
100
109
|
function report(listener, cause) {
|
|
101
110
|
if (listener.signal.aborted) return;
|
|
102
111
|
try {
|
|
@@ -165,13 +174,11 @@ var LiveConnection = class {
|
|
|
165
174
|
let delay = 1e3;
|
|
166
175
|
while (!signal.aborted) {
|
|
167
176
|
try {
|
|
168
|
-
for await (const
|
|
177
|
+
for await (const line of this.client.watch(listeners.map((item) => item.subscription), signal)) {
|
|
169
178
|
if (signal.aborted) break;
|
|
170
179
|
delay = 1e3;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (result) this.deliver(listener, result);
|
|
174
|
-
});
|
|
180
|
+
const result = line.kind === "list" ? { value: line.reviews } : line;
|
|
181
|
+
for (const listener of listeners) if (concerns(line, listener.subscription)) this.deliver(listener, result);
|
|
175
182
|
}
|
|
176
183
|
if (!signal.aborted) disconnected(/* @__PURE__ */ new Error("Connection closed."));
|
|
177
184
|
} catch (error) {
|
|
@@ -195,7 +202,7 @@ var LiveConnection = class {
|
|
|
195
202
|
while (listener.queued && !listener.signal.aborted) {
|
|
196
203
|
const next = listener.queued;
|
|
197
204
|
listener.queued = void 0;
|
|
198
|
-
if (next
|
|
205
|
+
if ("error" in next) {
|
|
199
206
|
report(listener, new Error(next.error));
|
|
200
207
|
continue;
|
|
201
208
|
}
|
|
@@ -222,7 +229,7 @@ const TEXT_TOOLS = /* @__PURE__ */ new Set([
|
|
|
222
229
|
async function connectReviewApi(env = process.env, headers = {}) {
|
|
223
230
|
return (await connectReviewInstance(env, headers)).client;
|
|
224
231
|
}
|
|
225
|
-
async function connectReviewInstance(env = process.env, headers = {}) {
|
|
232
|
+
async function connectReviewInstance(env = process.env, headers = {}, options = {}) {
|
|
226
233
|
const request = (url, init) => {
|
|
227
234
|
const merged = new Headers(init?.headers);
|
|
228
235
|
for (const [key, value] of Object.entries(headers)) merged.set(key, value);
|
|
@@ -243,6 +250,16 @@ async function connectReviewInstance(env = process.env, headers = {}) {
|
|
|
243
250
|
const selection = await selectReviewInstance({ env });
|
|
244
251
|
const discovery = healthyReviewInstance(selection);
|
|
245
252
|
if (!discovery) {
|
|
253
|
+
const { ensureServerWithoutDesktop } = await import("./background-server-D2Rrr_e2.js");
|
|
254
|
+
const server = await ensureServerWithoutDesktop({
|
|
255
|
+
selection,
|
|
256
|
+
env,
|
|
257
|
+
...options
|
|
258
|
+
});
|
|
259
|
+
if (server) return { client: new ReviewApiClient({
|
|
260
|
+
serverUrl: server.url,
|
|
261
|
+
token: server.token
|
|
262
|
+
}, request) };
|
|
246
263
|
const unavailable = reviewInstanceUnavailable(selection);
|
|
247
264
|
const message = `${unavailable.message} For headless authoring, select a running server with --state-dir or DEV_REVIEW_SERVER_DIR.`;
|
|
248
265
|
if (unavailable instanceof ReviewInstanceUnavailableError) throw new ReviewInstanceUnavailableError(message);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { t as findReviewPackageRoot } from "./package-paths-
|
|
1
|
+
import { _ as activityUpdateSchema, g as activityEndSchema, h as activityBeginSchema, i as commandSchema, n as uploadSchema } from "./local-data-yfLp5PiJ.js";
|
|
2
|
+
import { x as publishedEditSchema, y as pathTargetSchema } from "./stored-document-migration-CFOvjRwW.js";
|
|
3
|
+
import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
|
|
4
|
+
import { t as findReviewPackageRoot } from "./package-paths-BsuI4WUf.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
7
7
|
import path from "node:path";
|
|
@@ -166,7 +166,7 @@ function authoringTools(scratchpadAvailable = false, traceEnabled = false) {
|
|
|
166
166
|
kind: true
|
|
167
167
|
});
|
|
168
168
|
const descriptions = {
|
|
169
|
-
create: "Create a review of saved working files, immutable commits or a GitHub PR. Revisions are resolved on acceptance. A worktree target reviews the saved files in its checkout, uncommitted ones included and untracked ones left out (git add -N a new file to include it), against base: the branch to compare against, by default the default branch of the repository. The diff starts at the merge base of base and HEAD, which follows rebases. Omitted commits base means source at head with no diff; supply the parent to review introduced changes. For a GitHub PR, pullRequestUrl alone is enough: target and title become optional, and the host fetches the PR into a registered checkout of its repository and pins the current PR head and GitHub diff base, titled from the PR. When the existing review for that PR is in Trash, creation reports its ID; restore it with review_lifecycle state:\"active\" before continuing. When an active review for that PR exists, it is returned instead, reporting whether its head moved and whether an agent is working on it; update it in place, move its target with review_set_target, or create a separate review with reuseExisting. kind:\"scratchpad\" names the one scratchpad, which the host creates itself. The result carries review, the review as review_list shows it: its target with resolved commits, origin (its PR), repositoryName and repositoryPath, so no follow-up read is needed before diffing. When Desktop is available the review opens there and the result reports opened, softwareMapEnabled and environmentIssues, as review_open does; set open:false to author in the background without taking over Desktop.",
|
|
169
|
+
create: "Create a review of saved working files, immutable commits or a GitHub PR. Revisions are resolved on acceptance. A worktree target reviews the saved files in its checkout, uncommitted ones included and untracked ones left out (git add -N a new file to include it), against base: the branch to compare against, by default the default branch of the repository. The diff starts at the merge base of base and HEAD, which follows rebases. Omitted commits base means source at head with no diff; supply the parent to review introduced changes. For a branch stacked on another, pass the branch below it as base; Desktop links reviews into a stack through their bases. For a GitHub PR, pullRequestUrl alone is enough: target and title become optional, and the host fetches the PR into a registered checkout of its repository and pins the current PR head and GitHub diff base, titled from the PR. When the existing review for that PR is in Trash, creation reports its ID; restore it with review_lifecycle state:\"active\" before continuing. When an active review for that PR exists, it is returned instead, reporting whether its head moved and whether an agent is working on it; update it in place, move its target with review_set_target, or create a separate review with reuseExisting. kind:\"scratchpad\" names the one scratchpad, which the host creates itself. The result carries review, the review as review_list shows it: its target with resolved commits, origin (its PR), repositoryName and repositoryPath, so no follow-up read is needed before diffing. When Desktop is available the review opens there and the result reports opened, softwareMapEnabled and environmentIssues, as review_open does; set open:false to author in the background without taking over Desktop.",
|
|
170
170
|
set_target: "Move the review to a new target, such as the commits after a rebase or amend, preserving the document and component IDs. Revisions are resolved on acceptance. Returns warnings for retained source ranges in files the new commits changed, to verify, and resources that no longer match; fix them with review_edit. Earlier versions keep their source. Omitted pullRequestUrl keeps the PR within the same repository; changing repositories clears it. Supply a URL to replace it or null to detach.",
|
|
171
171
|
edit: [
|
|
172
172
|
"Edit one document component. content is one component, named by its type; each type's fields are in the Components section of session_get_instructions (authoring or scratchpad).",
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import "./review-home-paths-zwevIq4I.js";
|
|
2
|
+
import { D as liveLockOwner, O as processIsAlive } from "./s3-config-DDWWMh5x.js";
|
|
3
|
+
import { t as findReviewPackageRoot } from "./package-paths-BsuI4WUf.js";
|
|
4
|
+
import { a as readReviewServerHealth, c as reviewServerStateDir, i as readReviewServerDiscovery, n as desktopOwnsHome, p as desktopUsesHome, r as headlessServerLockPath } from "./server-discovery-CifQ3yQS.js";
|
|
5
|
+
import { t as desktopApplicationInstalled } from "./review-app-launcher-D7I4DGoH.js";
|
|
6
|
+
import { mkdir, open, readFile, realpath, stat } from "node:fs/promises";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { spawn } from "node:child_process";
|
|
9
|
+
import { setTimeout } from "node:timers/promises";
|
|
10
|
+
//#region src/server/background-server.ts
|
|
11
|
+
function backgroundServerLogPath(stateDir) {
|
|
12
|
+
return path.join(stateDir, "review-server", "server.log");
|
|
13
|
+
}
|
|
14
|
+
async function ensureBackgroundServer(input) {
|
|
15
|
+
const stateDir = path.resolve(input.stateDir);
|
|
16
|
+
const running = await healthyDiscovery(stateDir);
|
|
17
|
+
if (running) return {
|
|
18
|
+
discovery: running,
|
|
19
|
+
started: false
|
|
20
|
+
};
|
|
21
|
+
if (await desktopUsesHome(stateDir, input.env)) throw new Error(desktopOwnsHome(stateDir));
|
|
22
|
+
const logPath = backgroundServerLogPath(stateDir);
|
|
23
|
+
await mkdir(path.dirname(logPath), {
|
|
24
|
+
recursive: true,
|
|
25
|
+
mode: 448
|
|
26
|
+
});
|
|
27
|
+
const logStart = (await stat(logPath).catch(() => null))?.size ?? 0;
|
|
28
|
+
const deadline = Date.now() + (input.timeoutMs ?? 15e3);
|
|
29
|
+
let child = await spawnServer(stateDir, logPath, input);
|
|
30
|
+
let respawned = false;
|
|
31
|
+
while (Date.now() < deadline) {
|
|
32
|
+
const discovery = await healthyDiscovery(stateDir);
|
|
33
|
+
if (discovery) return {
|
|
34
|
+
discovery,
|
|
35
|
+
started: discovery.serverPid === child.pid
|
|
36
|
+
};
|
|
37
|
+
if (child.error) throw new Error(`Could not start the Whiteboard server: ${child.error.message}`);
|
|
38
|
+
if (child.exited && await headlessServerOwner(stateDir) === void 0) {
|
|
39
|
+
if (respawned) break;
|
|
40
|
+
respawned = true;
|
|
41
|
+
child = await spawnServer(stateDir, logPath, input);
|
|
42
|
+
}
|
|
43
|
+
await setTimeout(100);
|
|
44
|
+
}
|
|
45
|
+
const owner = await headlessServerOwner(stateDir);
|
|
46
|
+
throw new Error(`The Whiteboard server did not become ready${child.exited ? "" : ` within ${Math.round((input.timeoutMs ?? 15e3) / 1e3)} s; process ${child.pid} is still starting`}.${owner !== void 0 && owner !== child.pid ? ` Process ${owner} holds its state directory without answering; \`whiteboard server stop\` ends it.` : ""} The end of ${logPath}:\n${await logTail(logPath, logStart)}`);
|
|
47
|
+
}
|
|
48
|
+
async function ensureServerWithoutDesktop(input) {
|
|
49
|
+
const { selection, env } = input;
|
|
50
|
+
if (selection.source !== "fallback" || selection.instances.length !== 0 || selection.problem || (input.desktopInstalled ?? (() => desktopApplicationInstalled({ env })))()) return void 0;
|
|
51
|
+
const { discovery } = await ensureBackgroundServer({
|
|
52
|
+
stateDir: reviewServerStateDir(env),
|
|
53
|
+
env,
|
|
54
|
+
cli: input.cli
|
|
55
|
+
});
|
|
56
|
+
return discovery;
|
|
57
|
+
}
|
|
58
|
+
async function headlessServerOwner(stateDir) {
|
|
59
|
+
const resolved = await realpath(stateDir).catch(() => path.resolve(stateDir));
|
|
60
|
+
return liveLockOwner(headlessServerLockPath(resolved));
|
|
61
|
+
}
|
|
62
|
+
async function recordedBackgroundServer(stateDir) {
|
|
63
|
+
const discovery = await readReviewServerDiscovery(stateDir).catch(() => null);
|
|
64
|
+
const health = discovery && await readReviewServerHealth(discovery);
|
|
65
|
+
return discovery && health?.serverPid === discovery.serverPid ? {
|
|
66
|
+
discovery,
|
|
67
|
+
health
|
|
68
|
+
} : void 0;
|
|
69
|
+
}
|
|
70
|
+
async function stopBackgroundServer(discovery, first = "SIGTERM") {
|
|
71
|
+
const { serverPid } = discovery;
|
|
72
|
+
for (const [signal, waitMs] of [[first, 1e4], ["SIGKILL", 2e3]]) {
|
|
73
|
+
try {
|
|
74
|
+
process.kill(serverPid, signal);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error instanceof Error && "code" in error && error.code === "ESRCH") return;
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
for (let waited = 0; waited < waitMs; waited += 100) {
|
|
80
|
+
if (!processIsAlive(serverPid)) return;
|
|
81
|
+
await setTimeout(100);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
throw new Error(`The Whiteboard server (process ${serverPid}) did not stop.`);
|
|
85
|
+
}
|
|
86
|
+
async function spawnDetached(input) {
|
|
87
|
+
const log = await open(input.log, "a", 384);
|
|
88
|
+
const child = spawn(input.command, input.args, {
|
|
89
|
+
cwd: input.cwd,
|
|
90
|
+
detached: true,
|
|
91
|
+
env: input.env,
|
|
92
|
+
stdio: [
|
|
93
|
+
"ignore",
|
|
94
|
+
log.fd,
|
|
95
|
+
log.fd
|
|
96
|
+
]
|
|
97
|
+
});
|
|
98
|
+
const state = {
|
|
99
|
+
pid: child.pid,
|
|
100
|
+
exited: false
|
|
101
|
+
};
|
|
102
|
+
child.once("exit", () => state.exited = true);
|
|
103
|
+
child.once("error", (error) => {
|
|
104
|
+
state.exited = true;
|
|
105
|
+
state.error = error;
|
|
106
|
+
});
|
|
107
|
+
child.unref();
|
|
108
|
+
await log.close();
|
|
109
|
+
return state;
|
|
110
|
+
}
|
|
111
|
+
function spawnServer(stateDir, logPath, input) {
|
|
112
|
+
const { command, args, env } = cliSpawn(input.cli, input.env ?? process.env);
|
|
113
|
+
return spawnDetached({
|
|
114
|
+
command,
|
|
115
|
+
args: [
|
|
116
|
+
...args,
|
|
117
|
+
"server",
|
|
118
|
+
"start",
|
|
119
|
+
"--state-dir",
|
|
120
|
+
stateDir,
|
|
121
|
+
"--started-by",
|
|
122
|
+
input.startedBy ?? "cli",
|
|
123
|
+
...input.args ?? []
|
|
124
|
+
],
|
|
125
|
+
cwd: stateDir,
|
|
126
|
+
env,
|
|
127
|
+
log: logPath
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function cliSpawn(cli, env) {
|
|
131
|
+
const [command, ...args] = cli ?? currentCli();
|
|
132
|
+
return {
|
|
133
|
+
command,
|
|
134
|
+
args,
|
|
135
|
+
env: args.at(-1)?.endsWith(".ts") && !env.TSX_TSCONFIG_PATH ? {
|
|
136
|
+
...env,
|
|
137
|
+
TSX_TSCONFIG_PATH: path.join(findReviewPackageRoot(import.meta.url), "tsconfig.json")
|
|
138
|
+
} : env
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function currentCli() {
|
|
142
|
+
return [
|
|
143
|
+
process.execPath,
|
|
144
|
+
...process.execArgv,
|
|
145
|
+
path.resolve(process.argv[1])
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
async function healthyDiscovery(stateDir) {
|
|
149
|
+
const discovery = await readReviewServerDiscovery(stateDir).catch(() => null);
|
|
150
|
+
return discovery && await readReviewServerHealth(discovery) ? discovery : null;
|
|
151
|
+
}
|
|
152
|
+
async function logTail(logPath, from) {
|
|
153
|
+
return (await readFile(logPath)).subarray(from).toString("utf8").trimEnd().split("\n").slice(-20).join("\n");
|
|
154
|
+
}
|
|
155
|
+
//#endregion
|
|
156
|
+
export { headlessServerOwner as a, stopBackgroundServer as c, ensureServerWithoutDesktop as i, cliSpawn as n, recordedBackgroundServer as o, ensureBackgroundServer as r, spawnDetached as s, backgroundServerLogPath as t };
|
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.2.5-preview.
|
|
1
|
+
{"version":"0.2.5-preview.20261015.115","commit":"fd78e6a852a7f20798854059c5196c661f0df44f","dirty":true,"builtAt":"2026-10-15T00:45:01.986Z"}
|