@dev.fast/whiteboard 0.5.2-preview.20261104.147 → 0.5.2-preview.20261109.149
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-DXpd0Px8.js → account-alias-Cs5YqXRj.js} +4 -4
- package/dist/agent-cli-DdUAmdca.js +2 -0
- package/dist/{agent-cli-COrZtFks.js → agent-cli-a5J-juuu.js} +8 -8
- package/dist/{agent-client-BFtYm3Ng.js → agent-client-CgnEo6lf.js} +3 -3
- package/dist/{authoring-tools-D1avYp8-.js → authoring-tools-BgZvnbjN.js} +3 -3
- package/dist/{background-server-HOJozY99.js → background-server-D8SaPvuC.js} +1 -1
- package/dist/{background-server-BiRSqjxG.js → background-server-DHEcsFwH.js} +4 -4
- package/dist/build-info.json +1 -1
- package/dist/{cli-CSlwGRvH.js → cli-Bq5zVqlc.js} +1 -1
- package/dist/{cli-runner-CuffXA0Q.js → cli-runner-hL2efcxb.js} +21 -21
- package/dist/cli.js +1 -1
- package/dist/{fuzzy-match-DEo941za.js → fuzzy-match-DNyQDN3P.js} +2 -2
- package/dist/{headless-host-BCkXVVpU.js → headless-host-CGyfb5mS.js} +1 -1
- package/dist/{headless-host-CIuJJjmM.js → headless-host-bb09yVkX.js} +17 -15
- package/dist/{import-CjcW7EIQ.js → import-_XAsWqen.js} +24 -139
- package/dist/{local-data-B5PBZ0Ge.js → local-data-ZQIkF5k1.js} +81 -70
- package/dist/{mcp-Ba3WvhUh.js → mcp-B-J8P5xm.js} +4 -4
- package/dist/{package-paths-Dk7MOXxN.js → package-paths-wobHueCx.js} +1 -1
- package/dist/profile-Bi2SbpSI.js +2 -0
- package/dist/{profile-CNMhLUhf.js → profile-D-SbO3p9.js} +2 -2
- package/dist/{remote-attach-DkZoYBHV.js → remote-attach-DyIESbbf.js} +4 -4
- package/dist/{remote-extensions-BvV29_gk.js → remote-extensions-BHHFPyYW.js} +1 -1
- package/dist/{remote-extensions-L95HNwIH.js → remote-extensions-gTMcRBg-.js} +2 -2
- package/dist/{remote-language-server-l4ConTfj.js → remote-language-server-Pp261dqJ.js} +4 -4
- package/dist/{remote-uninstall-BAQM7cU8.js → remote-uninstall-D_hSuBik.js} +5 -5
- package/dist/{request-origin-DZexKlc4.js → request-origin-ENYd0Ymr.js} +1 -1
- package/dist/{review-app-launcher-B5F10y_4.js → review-app-launcher-DR5vYGEl.js} +1 -1
- package/dist/{review-home-paths-BmZX2qiz.js → review-home-paths-B8909D07.js} +19 -19
- package/dist/{review-telemetry-kQ7esDRE.js → review-telemetry-CxNvwdDS.js} +4 -4
- package/dist/server/desktop-host.js +74 -16
- package/dist/{server-discovery-DYY_xeG9.js → server-discovery-Fme7f3fb.js} +2 -2
- package/dist/sharing/index.d.ts +21 -21
- package/dist/sharing/index.js +1 -1
- package/dist/{src-DirPN_Qh.js → src-BPrngiWX.js} +1769 -1
- package/dist/{stored-document-migration-vg0NAzXG.js → stored-document-migration-BQcUyXO8.js} +4 -73
- package/dist/{tool-failure-BLBwcl3H.js → tool-failure-Cgjidoud.js} +5 -5
- package/package.json +5 -6
- package/src/review-api/comparison-coverage.ts +6 -20
- package/src/review-api/http.ts +20 -16
- package/src/review-api/review-progress.ts +38 -123
- package/src/review-api/store.ts +4 -6
- package/src/server/review-gateway-pushes.ts +5 -1
- package/src/server/review-gateway.ts +15 -1
- package/src/software-map-diff-counts.ts +4 -2
- package/src/viewed-coverage.ts +9 -252
- package/dist/agent-cli-x6-Eh1S-.js +0 -2
- package/dist/profile-BstQkIY0.js +0 -2
- package/src/review-api/file-lenses.ts +0 -125
- package/src/unified-diff.ts +0 -71
- package/dist/{s3-CsG2EWED.js → s3-d8RGPKwt.js} +1 -1
package/dist/{stored-document-migration-vg0NAzXG.js → stored-document-migration-BQcUyXO8.js}
RENAMED
|
@@ -1,82 +1,13 @@
|
|
|
1
1
|
import { C as renderVcsArgs, v as parseGitRemote, w as runVcs } from "./src-Y30gweiK.js";
|
|
2
2
|
import { d as isBooleanValue, f as isNumberValue, l as jsonValueSchema, m as isStringValue, n as isJsonObject } from "./src-X9phtB2j.js";
|
|
3
|
-
import {
|
|
4
|
-
import "./
|
|
5
|
-
import "./review-home-paths-BmZX2qiz.js";
|
|
3
|
+
import { E as respellLinks, G as lensTargetsSchema, X as label, at as formatAnchor, mt as ReviewInputError } from "./src-BPrngiWX.js";
|
|
4
|
+
import "./review-home-paths-B8909D07.js";
|
|
6
5
|
import { t as errorMessage } from "./error-message-OtiDonty.js";
|
|
6
|
+
import "./src-B-91Rd2d.js";
|
|
7
7
|
import { randomUUID } from "node:crypto";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { execFile } from "node:child_process";
|
|
10
10
|
import { promisify } from "node:util";
|
|
11
|
-
//#region src/viewed-coverage.ts
|
|
12
|
-
const coverageSchema = z.object({
|
|
13
|
-
base: z.array(z.tuple([z.number().int().nonnegative(), z.number().int().nonnegative()])),
|
|
14
|
-
head: z.array(z.tuple([z.number().int().nonnegative(), z.number().int().nonnegative()]))
|
|
15
|
-
});
|
|
16
|
-
const emptyCoverage = () => ({
|
|
17
|
-
base: [],
|
|
18
|
-
head: []
|
|
19
|
-
});
|
|
20
|
-
function intersectIntervals(left, right) {
|
|
21
|
-
const result = [];
|
|
22
|
-
const a = unionIntervals(left), b = unionIntervals(right);
|
|
23
|
-
let i = 0, j = 0;
|
|
24
|
-
while (i < a.length && j < b.length) {
|
|
25
|
-
const start = Math.max(a[i][0], b[j][0]), end = Math.min(a[i][1], b[j][1]);
|
|
26
|
-
if (start < end) result.push([start, end]);
|
|
27
|
-
if (a[i][1] < b[j][1]) i++;
|
|
28
|
-
else j++;
|
|
29
|
-
}
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
function subtractIntervals(left, right) {
|
|
33
|
-
const result = [];
|
|
34
|
-
const removed = unionIntervals(right);
|
|
35
|
-
for (const [start, end] of unionIntervals(left)) {
|
|
36
|
-
let cursor = start;
|
|
37
|
-
for (const [from, to] of removed) {
|
|
38
|
-
if (to <= cursor) continue;
|
|
39
|
-
if (from >= end) break;
|
|
40
|
-
if (from > cursor) result.push([cursor, from]);
|
|
41
|
-
cursor = Math.min(end, Math.max(cursor, to));
|
|
42
|
-
}
|
|
43
|
-
if (cursor < end) result.push([cursor, end]);
|
|
44
|
-
}
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
function updateCoverage(current, scope, viewed) {
|
|
48
|
-
const apply = (side) => viewed ? unionIntervals([...current[side], ...scope[side]]) : subtractIntervals(current[side], scope[side]);
|
|
49
|
-
return {
|
|
50
|
-
base: apply("base"),
|
|
51
|
-
head: apply("head")
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
function scopedCoverage(file, sources) {
|
|
55
|
-
if (!sources) return file.changed;
|
|
56
|
-
const side = (side) => intersectIntervals(file.changed[side], sources.flatMap((source) => source.side === side && source.file === (side === "base" ? file.previousPath ?? file.path : file.path) ? [[source.fromLine - 1, source.toLine]] : []));
|
|
57
|
-
return {
|
|
58
|
-
base: side("base"),
|
|
59
|
-
head: side("head")
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
/** Each file's own sources, grouped once. */
|
|
63
|
-
function sourcesForFile(sources) {
|
|
64
|
-
if (!sources) return () => void 0;
|
|
65
|
-
const byFile = Map.groupBy(sources, (source) => source.file);
|
|
66
|
-
return (file) => {
|
|
67
|
-
const base = byFile.get(file.previousPath ?? file.path) ?? [];
|
|
68
|
-
return file.previousPath && file.previousPath !== file.path ? [...base, ...byFile.get(file.path) ?? []] : base;
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
function coverageSources(file, coverage = file.viewed) {
|
|
72
|
-
return ["base", "head"].flatMap((side) => coverage[side].map(([start, end]) => ({
|
|
73
|
-
side,
|
|
74
|
-
file: side === "base" ? file.previousPath ?? file.path : file.path,
|
|
75
|
-
fromLine: start + 1,
|
|
76
|
-
toLine: end
|
|
77
|
-
})));
|
|
78
|
-
}
|
|
79
|
-
//#endregion
|
|
80
11
|
//#region src/evidence.ts
|
|
81
12
|
/** Quote matching shared by legacy publish and JSON accept: authors paste
|
|
82
13
|
* transcript text with arbitrary line wrapping, so both sides compare on
|
|
@@ -1254,4 +1185,4 @@ function liftFileLenses(document) {
|
|
|
1254
1185
|
};
|
|
1255
1186
|
}
|
|
1256
1187
|
//#endregion
|
|
1257
|
-
export {
|
|
1188
|
+
export { fetchPullRequest as _, SoftwareModelValidationError as a, textIncludesQuote as b, traceSchema as c, setPullRequest as d, sourceBranchName as f, defaultPullRequestDeps as g, GitHubRefusedRead as h, readStoredDocument as i, pullRequestKey as l, resolvePullRequest as m, migrateStoredDocument as n, defineSoftwareMap as o, pullRequestProvider as p, migrateStoredLenses as r, softwareModelDataSchema as s, liftFileLenses as t, pullRequestUrl as u, remoteUrls as v, azureRepositoryOf as y };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { m as isStringValue, n as isJsonObject, u as parseJsonText } from "./src-X9phtB2j.js";
|
|
2
|
-
import {
|
|
3
|
-
import { l as boardTitle } from "./src-B-91Rd2d.js";
|
|
4
|
-
import "./review-home-paths-BmZX2qiz.js";
|
|
5
|
-
import { n as callAuthoringTool, s as ReviewApiError, t as ToolText } from "./agent-client-BFtYm3Ng.js";
|
|
2
|
+
import { F as checkReferences, P as blocks, mt as ReviewInputError } from "./src-BPrngiWX.js";
|
|
6
3
|
import { N as devReviewHome } from "./s3-config-CjcLyFV5.js";
|
|
7
|
-
import
|
|
4
|
+
import "./review-home-paths-B8909D07.js";
|
|
5
|
+
import { t as findReviewPackageRoot } from "./package-paths-wobHueCx.js";
|
|
6
|
+
import { l as boardTitle } from "./src-B-91Rd2d.js";
|
|
7
|
+
import { n as callAuthoringTool, s as ReviewApiError, t as ToolText } from "./agent-client-CgnEo6lf.js";
|
|
8
8
|
import { m as isMissingFileError } from "./thread-state-Jxoh1hde.js";
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
10
|
import { z } from "zod";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev.fast/whiteboard",
|
|
3
|
-
"version": "0.5.2-preview.
|
|
3
|
+
"version": "0.5.2-preview.20261109.149",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -53,7 +53,6 @@
|
|
|
53
53
|
"mdast-util-gfm": "3.1.0",
|
|
54
54
|
"mdast-util-math": "3.0.0",
|
|
55
55
|
"micromark-extension-gfm": "3.0.0",
|
|
56
|
-
"minimatch": "10.2.6",
|
|
57
56
|
"pi-acp": "0.0.34",
|
|
58
57
|
"pino": "10.3.1",
|
|
59
58
|
"semver": "7.8.5",
|
|
@@ -76,12 +75,12 @@
|
|
|
76
75
|
"tsx": "4.21.0",
|
|
77
76
|
"typescript": "6.0.3",
|
|
78
77
|
"vitest": "4.1.12",
|
|
79
|
-
"@dev.fast/review-protocol": "0.0.0",
|
|
80
78
|
"@dev.fast/json": "0.0.0",
|
|
81
|
-
"@dev.fast/review-share-protocol": "0.6.0",
|
|
82
79
|
"@dev.fast/trace-core": "0.0.0",
|
|
80
|
+
"@dev.fast/review-share-protocol": "0.6.0",
|
|
83
81
|
"@dev.fast/trace-protocol": "0.5.0",
|
|
84
|
-
"@dev.fast/
|
|
82
|
+
"@dev.fast/review-protocol": "0.0.0",
|
|
83
|
+
"@dev.fast/whiteboard-document": "0.3.0"
|
|
85
84
|
},
|
|
86
85
|
"engines": {
|
|
87
86
|
"node": ">=24 <25"
|
|
@@ -91,7 +90,7 @@
|
|
|
91
90
|
"repo": "devdotfast/review",
|
|
92
91
|
"docs": "packages/review/instructions/authoring.md"
|
|
93
92
|
},
|
|
94
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "4c0a0af9c57fe774cc885574b7e4236309456dc1",
|
|
95
94
|
"scripts": {
|
|
96
95
|
"prebuild": "pnpm run build:workspace-deps",
|
|
97
96
|
"build": "node --max-old-space-size=8192 node_modules/tsdown/dist/run.mjs",
|
|
@@ -9,20 +9,18 @@ import {
|
|
|
9
9
|
} from "@dev.fast/review-protocol";
|
|
10
10
|
import {
|
|
11
11
|
type AlignmentRow,
|
|
12
|
-
type FileLineRange,
|
|
13
|
-
type Pins,
|
|
14
|
-
patchRows,
|
|
15
|
-
} from "@dev.fast/whiteboard-document";
|
|
16
|
-
import { parseUnifiedPatch } from "@review/unified-diff.js";
|
|
17
|
-
import {
|
|
18
12
|
type Coverage,
|
|
19
13
|
type CoverageFile,
|
|
14
|
+
type FileLineRange,
|
|
20
15
|
type LineInterval,
|
|
16
|
+
type Pins,
|
|
21
17
|
emptyCoverage,
|
|
22
18
|
intersectIntervals,
|
|
19
|
+
patchChanges,
|
|
20
|
+
patchRows,
|
|
23
21
|
subtractIntervals,
|
|
24
22
|
unionIntervals,
|
|
25
|
-
} from "@
|
|
23
|
+
} from "@dev.fast/whiteboard-document";
|
|
26
24
|
|
|
27
25
|
import type { LocalReviewData } from "./local-data.js";
|
|
28
26
|
|
|
@@ -60,19 +58,7 @@ export async function comparisonCoverage(
|
|
|
60
58
|
patches?.get(file.path) ??
|
|
61
59
|
(await data.changes(pins, file.path, file.previousPath));
|
|
62
60
|
|
|
63
|
-
const changed =
|
|
64
|
-
|
|
65
|
-
for (const hunk of parseUnifiedPatch(file.path, patch))
|
|
66
|
-
for (const line of hunk.lines) {
|
|
67
|
-
if (line.kind === "add")
|
|
68
|
-
changed.head.push([line.newLine! - 1, line.newLine!]);
|
|
69
|
-
|
|
70
|
-
if (line.kind === "remove")
|
|
71
|
-
changed.base.push([line.oldLine! - 1, line.oldLine!]);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
changed.base = unionIntervals(changed.base);
|
|
75
|
-
changed.head = unionIntervals(changed.head);
|
|
61
|
+
const changed = patchChanges(file.path, patch);
|
|
76
62
|
|
|
77
63
|
const [base, head] = await Promise.all([
|
|
78
64
|
file.status === "added"
|
package/src/review-api/http.ts
CHANGED
|
@@ -25,8 +25,12 @@ import { errorMessage } from "@dev.fast/trace-core";
|
|
|
25
25
|
import {
|
|
26
26
|
ReviewInputError,
|
|
27
27
|
type ReviewTarget,
|
|
28
|
+
type UncategorizedReport,
|
|
28
29
|
boardRepositoryId,
|
|
29
30
|
elements,
|
|
31
|
+
lensReport,
|
|
32
|
+
scopedCoverage,
|
|
33
|
+
uncategorizedReport,
|
|
30
34
|
} from "@dev.fast/whiteboard-document";
|
|
31
35
|
import {
|
|
32
36
|
type AgentSelection,
|
|
@@ -63,7 +67,6 @@ import {
|
|
|
63
67
|
} from "@review/sharing/host.js";
|
|
64
68
|
import { forgetSharedCommits } from "@review/sharing/repository.js";
|
|
65
69
|
import type { ReviewSessionAgent } from "@review/ui-telemetry-events.js";
|
|
66
|
-
import { scopedCoverage } from "@review/viewed-coverage.js";
|
|
67
70
|
import { type Context, Hono, type MiddlewareHandler } from "hono";
|
|
68
71
|
import { z } from "zod";
|
|
69
72
|
|
|
@@ -91,12 +94,9 @@ import {
|
|
|
91
94
|
reviewRequestOrigin,
|
|
92
95
|
} from "./request-origin.js";
|
|
93
96
|
import {
|
|
94
|
-
type UncategorizedReport,
|
|
95
97
|
legacyModeSchema,
|
|
96
|
-
lensReport,
|
|
97
98
|
progressUpdateSchema,
|
|
98
99
|
reviewProgress,
|
|
99
|
-
uncategorizedReport,
|
|
100
100
|
} from "./review-progress.js";
|
|
101
101
|
import {
|
|
102
102
|
type Author,
|
|
@@ -456,12 +456,16 @@ export function createReviewApi(
|
|
|
456
456
|
|
|
457
457
|
const snapshot = readReview(context.req.param("id"));
|
|
458
458
|
|
|
459
|
+
const progress = await reviewProgress(
|
|
460
|
+
store,
|
|
461
|
+
data,
|
|
462
|
+
snapshot,
|
|
463
|
+
context.req.raw.signal,
|
|
464
|
+
);
|
|
465
|
+
|
|
459
466
|
return context.json({
|
|
460
467
|
version: snapshot.version,
|
|
461
|
-
...lensReport(
|
|
462
|
-
snapshot.lenses ?? [],
|
|
463
|
-
await reviewProgress(store, data, snapshot, context.req.raw.signal),
|
|
464
|
-
),
|
|
468
|
+
...lensReport(snapshot.lenses ?? [], progress.lenses, progress.files),
|
|
465
469
|
});
|
|
466
470
|
});
|
|
467
471
|
app.get("/status", async (context) =>
|
|
@@ -2155,15 +2159,15 @@ export function createReviewApi(
|
|
|
2155
2159
|
if (!data) return {};
|
|
2156
2160
|
|
|
2157
2161
|
try {
|
|
2162
|
+
const progress = await reviewProgress(
|
|
2163
|
+
store,
|
|
2164
|
+
data,
|
|
2165
|
+
store.read(reviewId, version),
|
|
2166
|
+
request.signal,
|
|
2167
|
+
);
|
|
2168
|
+
|
|
2158
2169
|
return {
|
|
2159
|
-
uncategorized: uncategorizedReport(
|
|
2160
|
-
await reviewProgress(
|
|
2161
|
-
store,
|
|
2162
|
-
data,
|
|
2163
|
-
store.read(reviewId, version),
|
|
2164
|
-
request.signal,
|
|
2165
|
-
),
|
|
2166
|
-
),
|
|
2170
|
+
uncategorized: uncategorizedReport(progress.lenses, progress.files),
|
|
2167
2171
|
};
|
|
2168
2172
|
} catch (error) {
|
|
2169
2173
|
return {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type
|
|
2
|
+
type CoverageFile,
|
|
3
3
|
type FileLineRange,
|
|
4
|
-
type Lens,
|
|
5
4
|
type LensSource,
|
|
6
5
|
type Pins,
|
|
6
|
+
type ResolvedLens,
|
|
7
7
|
ReviewInputError,
|
|
8
8
|
SelectionUnavailableError,
|
|
9
9
|
type SelectionUnavailableReason,
|
|
@@ -11,22 +11,18 @@ import {
|
|
|
11
11
|
anchorPins,
|
|
12
12
|
boardRepositoryId,
|
|
13
13
|
comparisonKey,
|
|
14
|
+
emptyCoverage,
|
|
14
15
|
fileLineRangeSchema,
|
|
15
16
|
lensSelections,
|
|
16
17
|
patchRows,
|
|
17
18
|
resolveDiffSelection,
|
|
19
|
+
resolveLenses,
|
|
18
20
|
selectionKey,
|
|
19
21
|
selectionReferences,
|
|
20
22
|
} from "@dev.fast/whiteboard-document";
|
|
21
|
-
import { type CoverageFile, emptyCoverage } from "@review/viewed-coverage.js";
|
|
22
23
|
import { z } from "zod";
|
|
23
24
|
|
|
24
25
|
import type { ComparisonCoverage } from "./comparison-coverage.js";
|
|
25
|
-
import {
|
|
26
|
-
changedPath,
|
|
27
|
-
resolveFileLens,
|
|
28
|
-
uncategorizedSources,
|
|
29
|
-
} from "./file-lenses.js";
|
|
30
26
|
import type { LocalReviewData } from "./local-data.js";
|
|
31
27
|
import type { ReviewStore, Snapshot } from "./store.js";
|
|
32
28
|
|
|
@@ -60,7 +56,7 @@ export interface ReviewProgress {
|
|
|
60
56
|
referenceFiles?: Record<string, Record<string, CoverageFile>>;
|
|
61
57
|
resolvedSelections: Record<string, FileLineRange[]>;
|
|
62
58
|
/** The review's file lenses, then the automatic "Uncategorized changes". */
|
|
63
|
-
lenses: (
|
|
59
|
+
lenses: (ResolvedLens & { pending?: boolean })[];
|
|
64
60
|
/** Untracked files a live worktree review leaves out of its comparison. */
|
|
65
61
|
untrackedFiles?: number;
|
|
66
62
|
}
|
|
@@ -243,40 +239,17 @@ export async function reviewProgress(
|
|
|
243
239
|
}
|
|
244
240
|
};
|
|
245
241
|
|
|
246
|
-
|
|
242
|
+
// Explicit ranges use the same pin validation as diagram evidence.
|
|
243
|
+
await Promise.all(
|
|
247
244
|
(snapshot.lenses ?? []).map(async (authored) => {
|
|
248
|
-
const lens = { id: authored.id, title: authored.title };
|
|
249
|
-
|
|
250
245
|
try {
|
|
251
|
-
// Explicit ranges use the same pin validation as diagram evidence.
|
|
252
246
|
await Promise.all(
|
|
253
247
|
lensSelections([authored]).map(({ source }) =>
|
|
254
248
|
resolveAvailable(source),
|
|
255
249
|
),
|
|
256
250
|
);
|
|
257
|
-
|
|
258
|
-
const resolved = resolveFileLens(
|
|
259
|
-
authored,
|
|
260
|
-
files,
|
|
261
|
-
fileSources,
|
|
262
|
-
(source) => resolvedSelections[selectionKey(source)] ?? [],
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
return {
|
|
266
|
-
...lens,
|
|
267
|
-
...resolved,
|
|
268
|
-
pending: counting,
|
|
269
|
-
unavailable:
|
|
270
|
-
counting || resolved.fileCount
|
|
271
|
-
? undefined
|
|
272
|
-
: "No files match these targets",
|
|
273
|
-
};
|
|
274
251
|
} catch {
|
|
275
|
-
|
|
276
|
-
...lens,
|
|
277
|
-
sources: [],
|
|
278
|
-
unavailable: "Source links need updating at these pins",
|
|
279
|
-
};
|
|
252
|
+
/* resolveLenses reports a lens whose anchors don't parse. */
|
|
280
253
|
}
|
|
281
254
|
}),
|
|
282
255
|
);
|
|
@@ -295,27 +268,19 @@ export async function reviewProgress(
|
|
|
295
268
|
}),
|
|
296
269
|
);
|
|
297
270
|
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
wholeFiles: false,
|
|
312
|
-
fileCount: new Set(uncategorized.map(changedPath(files))).size,
|
|
313
|
-
pending: counting,
|
|
314
|
-
unavailable:
|
|
315
|
-
counting || uncategorized.length
|
|
316
|
-
? undefined
|
|
317
|
-
: "All changed lines are covered by lenses",
|
|
318
|
-
});
|
|
271
|
+
const lenses = pendingLenses(
|
|
272
|
+
resolveLenses(
|
|
273
|
+
snapshot.lenses ?? [],
|
|
274
|
+
files,
|
|
275
|
+
fileSources,
|
|
276
|
+
(source) =>
|
|
277
|
+
unavailableSelections[selectionKey(source)]
|
|
278
|
+
? undefined
|
|
279
|
+
: (resolvedSelections[selectionKey(source)] ?? []),
|
|
280
|
+
{ nocase: process.platform === "darwin" || process.platform === "win32" },
|
|
281
|
+
),
|
|
282
|
+
counting,
|
|
283
|
+
);
|
|
319
284
|
|
|
320
285
|
const progress: ReviewProgress = {
|
|
321
286
|
complete: !counting && !pendingSources.size,
|
|
@@ -333,71 +298,21 @@ export async function reviewProgress(
|
|
|
333
298
|
return progress;
|
|
334
299
|
}
|
|
335
300
|
|
|
336
|
-
/**
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
export function uncategorizedReport(
|
|
354
|
-
progress: ReviewProgress,
|
|
355
|
-
): UncategorizedReport {
|
|
356
|
-
const sources =
|
|
357
|
-
progress.lenses.find((lens) => lens.id === UNCATEGORIZED_LENS_ID)
|
|
358
|
-
?.sources ?? [];
|
|
359
|
-
|
|
360
|
-
const byPath = new Map<string, UncategorizedReport["files"][number]>();
|
|
361
|
-
const pathOf = changedPath(progress.files);
|
|
362
|
-
|
|
363
|
-
for (const source of sources) {
|
|
364
|
-
const path = pathOf(source);
|
|
365
|
-
|
|
366
|
-
const entry = byPath.get(path) ?? { path, lines: 0, ranges: [] };
|
|
367
|
-
entry.lines += source.toLine - source.fromLine + 1;
|
|
368
|
-
entry.ranges.push({
|
|
369
|
-
side: source.side,
|
|
370
|
-
fromLine: source.fromLine,
|
|
371
|
-
toLine: source.toLine,
|
|
372
|
-
});
|
|
373
|
-
byPath.set(path, entry);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const files = [...byPath.values()];
|
|
377
|
-
|
|
378
|
-
const report: UncategorizedReport = {
|
|
379
|
-
lines: files.reduce((total, file) => total + file.lines, 0),
|
|
380
|
-
files: files.slice(0, REPORT_FILES),
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
if (files.length > REPORT_FILES)
|
|
384
|
-
report.moreFiles = files.length - REPORT_FILES;
|
|
385
|
-
|
|
386
|
-
return report;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/** Each lens as authored, with what it resolves to, for a lens author. */
|
|
390
|
-
export function lensReport(lenses: readonly Lens[], progress: ReviewProgress) {
|
|
391
|
-
return {
|
|
392
|
-
lenses: lenses.map((lens) => {
|
|
393
|
-
const resolved = progress.lenses.find((item) => item.id === lens.id);
|
|
394
|
-
|
|
395
|
-
return {
|
|
396
|
-
...lens,
|
|
397
|
-
fileCount: resolved?.fileCount ?? 0,
|
|
398
|
-
...(resolved?.unavailable && { unavailable: resolved.unavailable }),
|
|
399
|
-
};
|
|
400
|
-
}),
|
|
401
|
-
uncategorized: uncategorizedReport(progress),
|
|
402
|
-
};
|
|
301
|
+
/** A lens with no fileCount failed to resolve, so it is never pending. */
|
|
302
|
+
export function pendingLenses(
|
|
303
|
+
lenses: readonly ResolvedLens[],
|
|
304
|
+
counting: boolean,
|
|
305
|
+
): ReviewProgress["lenses"] {
|
|
306
|
+
return lenses.map((lens) => {
|
|
307
|
+
if (lens.fileCount === undefined) return lens;
|
|
308
|
+
|
|
309
|
+
if (!counting) return { ...lens, pending: false };
|
|
310
|
+
|
|
311
|
+
return {
|
|
312
|
+
...lens,
|
|
313
|
+
...(lens.id === UNCATEGORIZED_LENS_ID && { sources: [], fileCount: 0 }),
|
|
314
|
+
unavailable: undefined,
|
|
315
|
+
pending: true,
|
|
316
|
+
};
|
|
317
|
+
});
|
|
403
318
|
}
|
package/src/review-api/store.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type Applied,
|
|
18
18
|
type Block,
|
|
19
19
|
type BoardLinkRef,
|
|
20
|
+
type Coverage,
|
|
20
21
|
type EditSummary,
|
|
21
22
|
type Element,
|
|
22
23
|
type FileLineRange,
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
documentSchema,
|
|
40
41
|
editSchema,
|
|
41
42
|
elements,
|
|
43
|
+
emptyCoverage,
|
|
42
44
|
explicitPins,
|
|
43
45
|
lensEditSchema,
|
|
44
46
|
lensSchema,
|
|
@@ -53,18 +55,14 @@ import {
|
|
|
53
55
|
sourceAnchors,
|
|
54
56
|
sourceReferences,
|
|
55
57
|
summarizeEdit,
|
|
58
|
+
updateCoverage,
|
|
56
59
|
} from "@dev.fast/whiteboard-document";
|
|
57
60
|
import type { GitHubPullRequest } from "@review/github-pr-graph.js";
|
|
58
61
|
import {
|
|
59
62
|
migrateStoredLenses,
|
|
60
63
|
readStoredDocument,
|
|
61
64
|
} from "@review/stored-document-migration.js";
|
|
62
|
-
import {
|
|
63
|
-
type Coverage,
|
|
64
|
-
coverageSchema,
|
|
65
|
-
emptyCoverage,
|
|
66
|
-
updateCoverage,
|
|
67
|
-
} from "@review/viewed-coverage.js";
|
|
65
|
+
import { coverageSchema } from "@review/viewed-coverage.js";
|
|
68
66
|
import { z } from "zod";
|
|
69
67
|
|
|
70
68
|
import { ReviewActivity } from "./activity.js";
|
|
@@ -20,6 +20,7 @@ const REMOTE_VERBS = new Set<ReviewVerbRequest["name"]>([
|
|
|
20
20
|
"authoringCapabilities",
|
|
21
21
|
"openApiReview",
|
|
22
22
|
"focusWindow",
|
|
23
|
+
"renderAnimation",
|
|
23
24
|
]);
|
|
24
25
|
|
|
25
26
|
export function createGatewayPushes(input: {
|
|
@@ -41,7 +42,10 @@ export function createGatewayPushes(input: {
|
|
|
41
42
|
error: `${request.name} is not available from another machine.`,
|
|
42
43
|
};
|
|
43
44
|
|
|
44
|
-
if (
|
|
45
|
+
if (
|
|
46
|
+
request.name === "openApiReview" ||
|
|
47
|
+
request.name === "renderAnimation"
|
|
48
|
+
) {
|
|
45
49
|
const refused = await input.claim(remote, request.args.reviewId);
|
|
46
50
|
|
|
47
51
|
if (refused) return { ok: false, error: refused };
|
|
@@ -63,6 +63,20 @@ const REMOTE_ROUTES: readonly RemoteRoute[] = [
|
|
|
63
63
|
{ method: "GET", path: "diff" },
|
|
64
64
|
{ method: "GET", path: "structural-diff" },
|
|
65
65
|
{ method: "GET", path: "stack" },
|
|
66
|
+
{ method: "GET", path: "place" },
|
|
67
|
+
{ method: "GET", path: "project" },
|
|
68
|
+
{ method: "GET", path: "inspect" },
|
|
69
|
+
{ method: "GET", path: "history" },
|
|
70
|
+
{ method: "GET", path: "lenses" },
|
|
71
|
+
{ method: "GET", path: "activity" },
|
|
72
|
+
{ method: "POST", path: "activity/:action{begin|update|end}" },
|
|
73
|
+
{ method: "POST", path: "person-edit" },
|
|
74
|
+
{ method: "POST", path: "focus" },
|
|
75
|
+
{ method: "POST", path: "animation-run" },
|
|
76
|
+
{ method: "GET", path: "render", slow: true },
|
|
77
|
+
{ method: "GET", path: "links" },
|
|
78
|
+
{ method: "GET", path: "links/peek" },
|
|
79
|
+
{ method: "GET", path: "commit/:commit" },
|
|
66
80
|
{ method: "GET", path: "tree" },
|
|
67
81
|
{ method: "GET", path: "file" },
|
|
68
82
|
{ method: "GET", path: "resources/:name" },
|
|
@@ -85,7 +99,7 @@ const REMOTE_ROUTES: readonly RemoteRoute[] = [
|
|
|
85
99
|
},
|
|
86
100
|
{
|
|
87
101
|
method: "POST",
|
|
88
|
-
path: "ask/:thread/:action{prompt|permission|files|retry|cancel|close}",
|
|
102
|
+
path: "ask/:thread/:action{prompt|permission|files|retry|cancel|close|viewed}",
|
|
89
103
|
},
|
|
90
104
|
{ method: "DELETE", path: "ask/:thread" },
|
|
91
105
|
];
|
|
@@ -3,8 +3,10 @@ import {
|
|
|
3
3
|
diff as readLocalVcsDiff,
|
|
4
4
|
} from "@dev.fast/local-vcs";
|
|
5
5
|
import { jsonString, parseJsonText } from "@dev.fast/review-protocol";
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
type DiffHunkLine,
|
|
8
|
+
parseUnifiedPatch,
|
|
9
|
+
} from "@dev.fast/whiteboard-document";
|
|
8
10
|
|
|
9
11
|
export interface SoftwareMapDiffLineCount {
|
|
10
12
|
additions: number;
|