@dev.fast/whiteboard 0.0.0-stage → 0.2.1-preview.20261005.98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +146 -2
  3. package/THIRD_PARTY_NOTICES.md +93 -0
  4. package/dist/account-alias-DOHN1RSH.js +973 -0
  5. package/dist/agent-cli-ChOq0ZuO.js +117 -0
  6. package/dist/agent-cli-DzWfZr6G.js +2 -0
  7. package/dist/agent-client-CPQo7iTI.js +305 -0
  8. package/dist/authoring-tools-Cr6Kpjsx.js +234 -0
  9. package/dist/build-info.json +1 -0
  10. package/dist/cli-hVgHcdsv.js +47 -0
  11. package/dist/cli-runner-D8y2_luU.js +5095 -0
  12. package/dist/cli.d.ts +1 -0
  13. package/dist/cli.js +128 -0
  14. package/dist/client-DFoh50W3.js +950 -0
  15. package/dist/desktop-discovery-DBO-PM2V.js +164 -0
  16. package/dist/error-message-OtiDonty.js +6 -0
  17. package/dist/fs-utils-BMPLt0cr.js +22 -0
  18. package/dist/fuzzy-match-BoAmcyak.js +30 -0
  19. package/dist/headless-host-BJxf4dUU.js +94 -0
  20. package/dist/input-error-OLgB_h31.js +11 -0
  21. package/dist/local-data-CxLk75rx.js +4491 -0
  22. package/dist/mcp-QeF8vkdf.js +140 -0
  23. package/dist/package-paths-B6-zxvIO.js +47 -0
  24. package/dist/process-error-telemetry-v9e5h6D7.js +3952 -0
  25. package/dist/profile-4ry2f3AM.js +76 -0
  26. package/dist/profile-Bh5FIrmf.js +2 -0
  27. package/dist/request-origin-D_4QIdoN.js +811 -0
  28. package/dist/review-agent-traces-DNJFYzc8.js +3866 -0
  29. package/dist/review-home-paths-6zZH-1c9.js +2560 -0
  30. package/dist/review-telemetry-DEFnQsQ2.js +1195 -0
  31. package/dist/runtime-CKiWhGrf.js +52 -0
  32. package/dist/runtime.d.ts +9 -0
  33. package/dist/runtime.js +2 -0
  34. package/dist/s3-SzLpeCG6.js +345 -0
  35. package/dist/s3-config-BgxkSoOy.js +2 -0
  36. package/dist/s3-config-CAxhO9u_.js +676 -0
  37. package/dist/server/desktop-host.d.ts +4 -0
  38. package/dist/server/desktop-host.js +1702 -0
  39. package/dist/server-discovery-Dbzn3w6Z.js +66 -0
  40. package/dist/sharing/index.d.ts +1977 -0
  41. package/dist/sharing/index.js +2 -0
  42. package/dist/src-CGP5ytbV.js +283 -0
  43. package/dist/src-CmdiBL20.js +3676 -0
  44. package/dist/src-DnwdaQ2r.js +865 -0
  45. package/dist/src-X9phtB2j.js +68 -0
  46. package/dist/stored-document-migration-DHeMpLMb.js +2671 -0
  47. package/dist/tool-failure-C8zB73HV.js +98 -0
  48. package/dist/tutorial-trace-DrBvkaeL.js +43 -0
  49. package/instructions/authoring.md +36 -0
  50. package/instructions/file-lenses.md +13 -0
  51. package/instructions/scratchpad.md +23 -0
  52. package/instructions/trace-archaeology.md +113 -0
  53. package/onboarding.md +8 -0
  54. package/package.json +106 -3
  55. package/src/agent-selection.ts +100 -0
  56. package/src/agent-session-ref.ts +80 -0
  57. package/src/ask/agents.ts +351 -0
  58. package/src/ask/checkout-files.ts +47 -0
  59. package/src/ask/file-refs.ts +111 -0
  60. package/src/ask/pi-mcp.ts +154 -0
  61. package/src/ask/protocol.ts +244 -0
  62. package/src/ask/thread-state.ts +350 -0
  63. package/src/ask/thread.ts +1400 -0
  64. package/src/ask/threads.ts +219 -0
  65. package/src/ask/watch.ts +79 -0
  66. package/src/cli-install.ts +1041 -0
  67. package/src/cli-runner.ts +1461 -0
  68. package/src/cli-runtime-info.ts +35 -0
  69. package/src/cli.ts +222 -0
  70. package/src/connect-prompts.ts +248 -0
  71. package/src/cursor-deeplink.ts +11 -0
  72. package/src/desktop-discovery.ts +355 -0
  73. package/src/diff-selection-migration.ts +63 -0
  74. package/src/embedded-posthog-key.ts +6 -0
  75. package/src/error-telemetry.ts +247 -0
  76. package/src/evidence.ts +14 -0
  77. package/src/exception-telemetry.ts +126 -0
  78. package/src/fixtures/blocks/call_stack_diff.json +27 -0
  79. package/src/fixtures/blocks/callout.json +11 -0
  80. package/src/fixtures/blocks/code.json +9 -0
  81. package/src/fixtures/blocks/code_peek.json +8 -0
  82. package/src/fixtures/blocks/database_lens.json +51 -0
  83. package/src/fixtures/blocks/divider.json +1 -0
  84. package/src/fixtures/blocks/fixtures.ts +33 -0
  85. package/src/fixtures/blocks/flow_diagram.json +36 -0
  86. package/src/fixtures/blocks/ids.ts +8 -0
  87. package/src/fixtures/blocks/image.json +9 -0
  88. package/src/fixtures/blocks/markdown.json +7 -0
  89. package/src/fixtures/blocks/section.json +11 -0
  90. package/src/fixtures/blocks/sequence.json +31 -0
  91. package/src/fixtures/blocks/software_map.json +7 -0
  92. package/src/fixtures/blocks/trace_quote.json +9 -0
  93. package/src/fixtures/blocks/tutorial.json +51 -0
  94. package/src/fs-utils.ts +32 -0
  95. package/src/fuzzy-match.ts +94 -0
  96. package/src/install.ts +29 -0
  97. package/src/legacy-skills.ts +133 -0
  98. package/src/lens-selection.ts +230 -0
  99. package/src/markdown-latex-math.ts +230 -0
  100. package/src/markdown.ts +81 -0
  101. package/src/package-paths.ts +53 -0
  102. package/src/posthog-capture-client.ts +610 -0
  103. package/src/review-api/README.md +295 -0
  104. package/src/review-api/activity.ts +340 -0
  105. package/src/review-api/agent-cli.ts +219 -0
  106. package/src/review-api/agent-client.ts +188 -0
  107. package/src/review-api/anchor-quotes.ts +88 -0
  108. package/src/review-api/ask-history.ts +242 -0
  109. package/src/review-api/authoring-tools.ts +211 -0
  110. package/src/review-api/blocks/call_stack_diff.ts +75 -0
  111. package/src/review-api/blocks/callout.ts +24 -0
  112. package/src/review-api/blocks/code.ts +9 -0
  113. package/src/review-api/blocks/code_peek.ts +13 -0
  114. package/src/review-api/blocks/database_lens.ts +150 -0
  115. package/src/review-api/blocks/definition.ts +40 -0
  116. package/src/review-api/blocks/divider.ts +6 -0
  117. package/src/review-api/blocks/flow_diagram.ts +111 -0
  118. package/src/review-api/blocks/image.ts +10 -0
  119. package/src/review-api/blocks/index.ts +90 -0
  120. package/src/review-api/blocks/markdown.ts +17 -0
  121. package/src/review-api/blocks/section.ts +24 -0
  122. package/src/review-api/blocks/sequence.ts +56 -0
  123. package/src/review-api/blocks/software_map.ts +9 -0
  124. package/src/review-api/blocks/trace_quote.ts +10 -0
  125. package/src/review-api/blocks/tutorial.ts +39 -0
  126. package/src/review-api/checkout-fs.ts +14 -0
  127. package/src/review-api/client.ts +1 -0
  128. package/src/review-api/comparison-coverage.ts +304 -0
  129. package/src/review-api/component-reference.ts +30 -0
  130. package/src/review-api/diff-lenses.ts +175 -0
  131. package/src/review-api/document-headings.ts +51 -0
  132. package/src/review-api/document-text.ts +200 -0
  133. package/src/review-api/document.ts +906 -0
  134. package/src/review-api/file-lenses.ts +100 -0
  135. package/src/review-api/http.ts +1877 -0
  136. package/src/review-api/image-decode.ts +29 -0
  137. package/src/review-api/input-error.ts +9 -0
  138. package/src/review-api/instructions.ts +89 -0
  139. package/src/review-api/lens-alignment.ts +52 -0
  140. package/src/review-api/local-data.ts +1837 -0
  141. package/src/review-api/map-input.ts +154 -0
  142. package/src/review-api/mcp-client-agent.ts +32 -0
  143. package/src/review-api/mcp.ts +240 -0
  144. package/src/review-api/origin.ts +43 -0
  145. package/src/review-api/profile.ts +146 -0
  146. package/src/review-api/public-tools.ts +102 -0
  147. package/src/review-api/pull-request.ts +389 -0
  148. package/src/review-api/read-schemas.ts +85 -0
  149. package/src/review-api/recovery.ts +2 -0
  150. package/src/review-api/request-origin.ts +33 -0
  151. package/src/review-api/review-progress.ts +382 -0
  152. package/src/review-api/status-tool.ts +10 -0
  153. package/src/review-api/store-schema.ts +22 -0
  154. package/src/review-api/store.ts +1647 -0
  155. package/src/review-api/tool-failure.ts +64 -0
  156. package/src/review-api/trace-schema.ts +13 -0
  157. package/src/review-api/traces.ts +119 -0
  158. package/src/review-api/unsupported-files.integration.ts +91 -0
  159. package/src/review-api/workspaces.ts +692 -0
  160. package/src/review-api/worktree-source.ts +170 -0
  161. package/src/review-api/worktree-structural.integration.ts +320 -0
  162. package/src/review-app-launcher.ts +432 -0
  163. package/src/review-app-picker.ts +168 -0
  164. package/src/review-app.ts +134 -0
  165. package/src/review-bundled-tools.ts +249 -0
  166. package/src/review-checkout-paths.ts +37 -0
  167. package/src/review-diff-files.ts +89 -0
  168. package/src/review-head-checkout.ts +300 -0
  169. package/src/review-home-paths.ts +73 -0
  170. package/src/review-info.ts +59 -0
  171. package/src/review-instances.ts +113 -0
  172. package/src/review-logger.ts +183 -0
  173. package/src/review-preferences.ts +88 -0
  174. package/src/review-prepare.ts +291 -0
  175. package/src/review-stack.ts +112 -0
  176. package/src/review-telemetry.ts +1066 -0
  177. package/src/runtime.ts +74 -0
  178. package/src/server/account-alias.ts +30 -0
  179. package/src/server/bounded-stream.ts +34 -0
  180. package/src/server/bug-report.ts +301 -0
  181. package/src/server/client-error-budget.ts +45 -0
  182. package/src/server/crash-report.ts +273 -0
  183. package/src/server/desktop-host-shutdown.ts +64 -0
  184. package/src/server/desktop-host.ts +190 -0
  185. package/src/server/desktop-server.ts +703 -0
  186. package/src/server/diffr-config.ts +509 -0
  187. package/src/server/diffr-languages.ts +97 -0
  188. package/src/server/global-verb-relay.ts +190 -0
  189. package/src/server/headless-host.ts +149 -0
  190. package/src/server/hono-http.ts +162 -0
  191. package/src/server/http-json.ts +24 -0
  192. package/src/server/json-review-reporting.ts +174 -0
  193. package/src/server/process-error-telemetry.ts +174 -0
  194. package/src/server/review-api-parsers.ts +90 -0
  195. package/src/server/review-lifecycle-telemetry.ts +73 -0
  196. package/src/server/review-open-watchdog.ts +46 -0
  197. package/src/server/review-server-core.ts +290 -0
  198. package/src/server/structural-comparisons.ts +153 -0
  199. package/src/server/structural-diff.ts +186 -0
  200. package/src/server/tutorial-service.ts +241 -0
  201. package/src/server/ui-telemetry.ts +198 -0
  202. package/src/server-discovery.ts +95 -0
  203. package/src/session-markers.ts +132 -0
  204. package/src/sharing/auth.ts +41 -0
  205. package/src/sharing/cli.ts +83 -0
  206. package/src/sharing/client.ts +334 -0
  207. package/src/sharing/export.ts +195 -0
  208. package/src/sharing/host.ts +316 -0
  209. package/src/sharing/import.ts +787 -0
  210. package/src/sharing/index.ts +16 -0
  211. package/src/sharing/repository.ts +145 -0
  212. package/src/sharing/routes.ts +34 -0
  213. package/src/slug.ts +23 -0
  214. package/src/software-map-diff-counts.ts +517 -0
  215. package/src/software-map-model.ts +1147 -0
  216. package/src/software-map-topology-diff.ts +260 -0
  217. package/src/source.ts +92 -0
  218. package/src/startup-trace.ts +232 -0
  219. package/src/stored-document-migration.ts +151 -0
  220. package/src/telemetry-clean-text.ts +257 -0
  221. package/src/telemetry-config.ts +298 -0
  222. package/src/telemetry-debug-sink.ts +38 -0
  223. package/src/telemetry.ts +13 -0
  224. package/src/trace-cli.ts +156 -0
  225. package/src/trace-storage-cli.ts +509 -0
  226. package/src/tutorial-conversation.ts +18 -0
  227. package/src/ui-telemetry-events.ts +765 -0
  228. package/src/unified-diff.ts +71 -0
  229. package/src/viewed-coverage.ts +259 -0
  230. package/src/windows-cli.ts +125 -0
  231. package/tutorial/document.json +275 -0
  232. package/tutorial/runtime-manifest.json +12 -0
  233. package/tutorial/sample-service/package.json +9 -0
  234. package/tutorial/sample-service/src/api/checkout-api.ts +17 -0
  235. package/tutorial/sample-service/src/app.ts +26 -0
  236. package/tutorial/sample-service/src/database/schema.ts +10 -0
  237. package/tutorial/sample-service/src/fulfillment/fulfillment-queue.ts +15 -0
  238. package/tutorial/sample-service/src/fulfillment/fulfillment-worker.ts +24 -0
  239. package/tutorial/sample-service/src/inventory/inventory-service.ts +11 -0
  240. package/tutorial/sample-service/src/orders/order-service.ts +34 -0
  241. package/tutorial/sample-service/src/orders/order.ts +21 -0
  242. package/tutorial/sample-service/src/orders/orders-repository.ts +24 -0
  243. package/tutorial/sample-service/src/payments/payment-gateway.ts +12 -0
  244. package/tutorial/sample-service/src/shipping/shipping-gateway.ts +15 -0
  245. package/tutorial/sample-service/tsconfig.json +12 -0
  246. package/tutorial/software-map.json +139 -0
  247. package/tutorial/trace.json +20 -0
@@ -0,0 +1,140 @@
1
+ import { a as toolResultText, s as ReviewApiError } from "./agent-client-CPQo7iTI.js";
2
+ import { t as ReviewInputError } from "./input-error-OLgB_h31.js";
3
+ import { n as REVIEW_STATUS_TOOL, t as authoringTools } from "./authoring-tools-Cr6Kpjsx.js";
4
+ import { i as publicTool, n as RECOVERY, r as callPublicTool, t as toolFailure } from "./tool-failure-C8zB73HV.js";
5
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
8
+ //#region src/review-api/mcp-client-agent.ts
9
+ /**
10
+ * The agent behind an MCP client, from the name it sends in `initialize`.
11
+ * Names seen on 2026-10-02: Claude Code `claude-code`, Codex
12
+ * `codex-mcp-client`, the Cursor CLI `Cursor`, OpenCode `opencode`, Pi `pi`
13
+ * and Oh My Pi `omp-coding-agent`. Undefined for
14
+ * a client this does not recognize, so the caller can fall back to the
15
+ * session environment. Codex strips its `CODEX_*` variables from the MCP
16
+ * server's environment, so for Codex the handshake is the only signal.
17
+ */
18
+ function mcpClientAgent(name) {
19
+ const normalized = name?.trim().toLowerCase();
20
+ if (!normalized) return void 0;
21
+ if (normalized.startsWith("codex")) return "codex";
22
+ if (normalized.startsWith("claude")) return "claude";
23
+ if (normalized.startsWith("cursor")) return "cursor";
24
+ if (normalized.startsWith("opencode")) return "opencode";
25
+ if (/^omp(?:$|[-_ ])/.test(normalized)) return "omp";
26
+ if (/^pi(?:$|[-_ ])/.test(normalized)) return "pi";
27
+ }
28
+ //#endregion
29
+ //#region src/review-api/mcp.ts
30
+ const RELOAD_TOOLS = "Whiteboard is running now, but this session listed Whiteboard's tools before it started, so you may see only session_get_instructions. Before authoring, reload the `whiteboard` MCP server's tools (reconnect it in your agent, or start a new agent session). If you can already see tools such as session_create, carry on.";
31
+ function mcpAuthoringGuidance(context) {
32
+ return [
33
+ "Whiteboard explains code in documents the user reads in Whiteboard Desktop. Call session_get_instructions before creating or editing a Whiteboard and follow it. Read session_capabilities before authoring; session_create opens the new review in Desktop when it is available, so call session_open only for an existing review, and generate software maps only when softwareMapEnabled is true. When the user asks for a Whiteboard or to use Whiteboard (for example to review a branch, a change or a pull request, or to explain a system in Whiteboard), author a Whiteboard with the default topic.",
34
+ ...context.scratchpadAvailable ? ["When the user asks in conversation to be shown how code works or wants a diagram, without asking for a Whiteboard, call session_capabilities; if it reports scratchpadEnabled and desktopAvailable, draw on the Whiteboard scratchpad rather than answering only in chat, starting with session_get_instructions({topic:\"scratchpad\"})."] : [],
35
+ ...context.traceEnabled ? ["For why code exists, what an agent was thinking, or whether an agent solved something before, call session_get_instructions({topic:\"trace-archaeology\"})."] : [],
36
+ "Never read or write Whiteboard files or SQL."
37
+ ].join(" ");
38
+ }
39
+ async function serveReviewMcp(connect, stdin, stdout, stderr = process.stderr, traceEnabled = false, offlineStatus, onToolCall, environmentAgent) {
40
+ const instructionsTool = {
41
+ ...authoringTools(false, traceEnabled).find((tool) => tool.name === "review_get_instructions"),
42
+ name: "session_get_instructions"
43
+ };
44
+ const server = new Server({
45
+ name: "whiteboard",
46
+ version: "1.0.0"
47
+ }, { capabilities: { tools: { listChanged: true } } });
48
+ let catalog = [];
49
+ let announceCatalog = false;
50
+ let listedWhileDown = false;
51
+ let latched;
52
+ const agentKind = () => mcpClientAgent(server.getClientVersion()?.name) ?? environmentAgent;
53
+ const load = async (signal) => {
54
+ const { client, instance } = await connect(latched, agentKind());
55
+ latched ??= instance?.key;
56
+ catalog = (await client.read("/authoring", signal)).map(publicTool);
57
+ if (announceCatalog) {
58
+ announceCatalog = false;
59
+ server.sendToolListChanged().catch(() => {});
60
+ }
61
+ return {
62
+ client,
63
+ tools: catalog
64
+ };
65
+ };
66
+ server.setRequestHandler(ListToolsRequestSchema, async (_request, extra) => {
67
+ let tools = catalog;
68
+ try {
69
+ ({tools} = await load(extra.signal));
70
+ listedWhileDown = false;
71
+ } catch (error) {
72
+ announceCatalog = true;
73
+ listedWhileDown = true;
74
+ stderr.write(`whiteboard mcp: ${error instanceof Error ? error.message : String(error)}\n`);
75
+ }
76
+ const always = [instructionsTool, REVIEW_STATUS_TOOL].map((fallback) => tools.find((tool) => tool.name === fallback.name) ?? fallback);
77
+ return { tools: [...always, ...tools.filter((tool) => !always.includes(tool))].map(({ name, description, inputSchema }) => ({
78
+ name,
79
+ description: name === instructionsTool.name ? `${mcpAuthoringGuidance({
80
+ scratchpadAvailable: true,
81
+ traceEnabled
82
+ })}\n\n${description}` : description,
83
+ inputSchema
84
+ })) };
85
+ });
86
+ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
87
+ const startedAt = Date.now();
88
+ let tool;
89
+ let phase = "connect";
90
+ const report = (failure) => void onToolCall?.({
91
+ tool: tool?.name ?? "other",
92
+ via: "mcp",
93
+ ok: !failure,
94
+ durationMs: Date.now() - startedAt,
95
+ agentKind: agentKind(),
96
+ ...failure
97
+ });
98
+ try {
99
+ let client;
100
+ let tools;
101
+ try {
102
+ ({client, tools} = await load(extra.signal));
103
+ } catch (error) {
104
+ announceCatalog = true;
105
+ if (request.params.name === instructionsTool.name && !(error instanceof ReviewApiError)) return { content: [{
106
+ type: "text",
107
+ text: RECOVERY
108
+ }] };
109
+ if (request.params.name === REVIEW_STATUS_TOOL.name && offlineStatus) return { content: [{
110
+ type: "text",
111
+ text: JSON.stringify(await offlineStatus(error instanceof Error ? error.message : String(error)))
112
+ }] };
113
+ throw error;
114
+ }
115
+ phase = "call";
116
+ tool = tools.find((tool) => tool.name === request.params.name);
117
+ if (!tool) throw new ReviewInputError(`Unknown Whiteboard tool: ${request.params.name}`);
118
+ const result = await callPublicTool(client, tool, request.params.arguments ?? {}, extra.signal);
119
+ const text = toolResultText(tool, result);
120
+ report();
121
+ return { content: [{
122
+ type: "text",
123
+ text: listedWhileDown && tool.name === instructionsTool.name ? `${RELOAD_TOOLS}\n\n${text}` : text
124
+ }] };
125
+ } catch (error) {
126
+ report(toolFailure(error, phase));
127
+ return {
128
+ isError: true,
129
+ content: [{
130
+ type: "text",
131
+ text: error instanceof Error ? error.message : String(error)
132
+ }]
133
+ };
134
+ }
135
+ });
136
+ await server.connect(new StdioServerTransport(stdin, stdout));
137
+ return server;
138
+ }
139
+ //#endregion
140
+ export { serveReviewMcp };
@@ -0,0 +1,47 @@
1
+ import { c as jsonString, o as jsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
2
+ import "./review-home-paths-6zZH-1c9.js";
3
+ import { readFileSync } from "node:fs";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ //#region ../trace-core/src/package-root.ts
7
+ /** Finds the package containing a source or bundled module URL. */
8
+ function findPackageRoot(moduleUrl) {
9
+ const currentDir = path.dirname(fileURLToPath(moduleUrl));
10
+ let candidate = currentDir;
11
+ while (true) {
12
+ const directoryName = path.basename(candidate);
13
+ if (directoryName === "src" || directoryName === "dist") return path.dirname(candidate);
14
+ const parent = path.dirname(candidate);
15
+ if (parent === candidate) return currentDir;
16
+ candidate = parent;
17
+ }
18
+ }
19
+ //#endregion
20
+ //#region src/package-paths.ts
21
+ function findReviewPackageRoot(moduleUrl = import.meta.url) {
22
+ return findPackageRoot(moduleUrl);
23
+ }
24
+ function readReviewPackageVersion(moduleUrl = import.meta.url) {
25
+ try {
26
+ const packageJson = jsonObject(parseJsonText(readFileSync(path.join(findReviewPackageRoot(moduleUrl), "package.json"), "utf8")));
27
+ return jsonString(packageJson?.version) ?? "unknown";
28
+ } catch {
29
+ return "unknown";
30
+ }
31
+ }
32
+ /** `build-info.json` in a built package's `dist`, when present. */
33
+ function readBuildInfo(distDirectory) {
34
+ try {
35
+ return jsonObject(parseJsonText(readFileSync(path.join(distDirectory, "build-info.json"), "utf8")));
36
+ } catch {
37
+ return;
38
+ }
39
+ }
40
+ /** The build's commit; null from source, where an old `dist` may linger. */
41
+ function readBuildCommit(moduleUrl) {
42
+ const dist = path.join(findReviewPackageRoot(moduleUrl), "dist");
43
+ if (!fileURLToPath(moduleUrl).startsWith(`${dist}${path.sep}`)) return null;
44
+ return jsonString(readBuildInfo(dist)?.commit) ?? null;
45
+ }
46
+ //#endregion
47
+ export { readReviewPackageVersion as i, readBuildCommit as n, readBuildInfo as r, findReviewPackageRoot as t };