@shiyuphan/follow-me 0.8.0 → 0.9.1
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/README.md +8 -3
- package/dist/src/cli.js +204 -53
- package/dist/src/comments.js +95 -7
- package/dist/src/coverage.js +173 -38
- package/dist/src/host.js +1 -0
- package/dist/src/plan.js +44 -22
- package/dist/src/prompt.js +58 -17
- package/dist/src/refs.js +239 -0
- package/dist/ui/dist/assets/{abnfDiagram-WEYOIA3C-Bp14ygmz.js → abnfDiagram-WEYOIA3C-BWgk01ve.js} +1 -1
- package/dist/ui/dist/assets/{arc-DUR6uzhI.js → arc-Cg_Qb5c4.js} +1 -1
- package/dist/ui/dist/assets/{architecture-WOLXFQ4H-CyfnP65O.js → architecture-WOLXFQ4H-EdfV1etv.js} +1 -1
- package/dist/ui/dist/assets/{architectureDiagram-ZHVYKT53-dJTicIk2.js → architectureDiagram-ZHVYKT53-Dz-gytQU.js} +1 -1
- package/dist/ui/dist/assets/{blockDiagram-RJAE7QA3-BYiqh5Ib.js → blockDiagram-RJAE7QA3-B7Q5KhYC.js} +1 -1
- package/dist/ui/dist/assets/{c4Diagram-XDPPPE54-DHHPQ7xE.js → c4Diagram-XDPPPE54-Cq9IvGR1.js} +1 -1
- package/dist/ui/dist/assets/channel-Da0YvuQF.js +1 -0
- package/dist/ui/dist/assets/{chunk-2E7WHVMD-BODm_awL.js → chunk-2E7WHVMD-BTJB-4C8.js} +1 -1
- package/dist/ui/dist/assets/{chunk-4EMNKR2T-CpZfjf2T.js → chunk-4EMNKR2T-BILthc2j.js} +1 -1
- package/dist/ui/dist/assets/{chunk-55XCU76K-CoP2pJTQ.js → chunk-55XCU76K-DH3fYrJH.js} +1 -1
- package/dist/ui/dist/assets/{chunk-7S6XSTFO-CaQcUvXY.js → chunk-7S6XSTFO-DDIiBvc2.js} +1 -1
- package/dist/ui/dist/assets/{chunk-AQDTSKZB-BZ9Czvbu.js → chunk-AQDTSKZB-b1EeJ3gb.js} +1 -1
- package/dist/ui/dist/assets/{chunk-DSNLSHJZ-CNjUo110.js → chunk-DSNLSHJZ-DZZ635s5.js} +1 -1
- package/dist/ui/dist/assets/{chunk-HAGFOTED-BTmBE_D3.js → chunk-HAGFOTED-DhhrHTIh.js} +1 -1
- package/dist/ui/dist/assets/{chunk-HNE4Q36P-D2cDuT0C.js → chunk-HNE4Q36P-B8wvhc2e.js} +1 -1
- package/dist/ui/dist/assets/{chunk-NQOKRVIF-AZcemFgG.js → chunk-NQOKRVIF-CLtGMwDx.js} +1 -1
- package/dist/ui/dist/assets/{chunk-UHW7PFBP-BszwjUqG.js → chunk-UHW7PFBP-B9fVLGl0.js} +1 -1
- package/dist/ui/dist/assets/{chunk-VQ5W62QI-vFSenYSe.js → chunk-VQ5W62QI-CgPvvMAv.js} +1 -1
- package/dist/ui/dist/assets/{chunk-WQQL4CDK-DZR6is1Q.js → chunk-WQQL4CDK-DdqKu6R9.js} +1 -1
- package/dist/ui/dist/assets/{chunk-XXDRQBXY-CACFh-si.js → chunk-XXDRQBXY-GlM07vbp.js} +1 -1
- package/dist/ui/dist/assets/{chunk-YZO67HFG-DRRTjGuW.js → chunk-YZO67HFG-YqT6M0W9.js} +1 -1
- package/dist/ui/dist/assets/{chunk-ZAUX2LTX-Bxuy-Roa.js → chunk-ZAUX2LTX-DqHK51Gc.js} +1 -1
- package/dist/ui/dist/assets/{chunk-ZCHMQSOR-rYXk__1o.js → chunk-ZCHMQSOR-DEeXkjWz.js} +1 -1
- package/dist/ui/dist/assets/{classDiagram-v2-4MYWR3UA-RiF44tTz.js → classDiagram-v2-4MYWR3UA-BcKsX4up.js} +1 -1
- package/dist/ui/dist/assets/{cose-bilkent-JH36ORCC-0oiQoThS.js → cose-bilkent-JH36ORCC-fu9djgYc.js} +1 -1
- package/dist/ui/dist/assets/{cynefin-EF2NZ3EQ-BAssFK5K.js → cynefin-EF2NZ3EQ-CFJASBsJ.js} +1 -1
- package/dist/ui/dist/assets/{cynefinDiagram-WF24UDRP-Bmd05bak.js → cynefinDiagram-WF24UDRP-BVJD_n0g.js} +1 -1
- package/dist/ui/dist/assets/{dagre-NK4GIZVX-QJkLjPxj.js → dagre-NK4GIZVX-Cx8pjz9O.js} +1 -1
- package/dist/ui/dist/assets/{diagram-CBK3MWTC-PSaSiYXz.js → diagram-CBK3MWTC-CVIkEZ1X.js} +1 -1
- package/dist/ui/dist/assets/{diagram-I5XIIV2D-BmU5X_hr.js → diagram-I5XIIV2D-2rxpF8BZ.js} +1 -1
- package/dist/ui/dist/assets/{diagram-ODIL2UCW-AAV39kUu.js → diagram-ODIL2UCW-NJfGHnLk.js} +1 -1
- package/dist/ui/dist/assets/{diagram-PFBEJUXE-DWlV-oxd.js → diagram-PFBEJUXE-DZHVJSeM.js} +1 -1
- package/dist/ui/dist/assets/{diagram-RJA3I4VV-D8wHRCNX.js → diagram-RJA3I4VV-CQAfOObI.js} +1 -1
- package/dist/ui/dist/assets/{diagram-TYUNFSNR-B_JQEsNY.js → diagram-TYUNFSNR-DGGaMOl6.js} +1 -1
- package/dist/ui/dist/assets/{dist-DxQIK_Ay.js → dist-CW-4NrUq.js} +1 -1
- package/dist/ui/dist/assets/{ebnfDiagram-V4P3TTPT-D83qV8mv.js → ebnfDiagram-V4P3TTPT-92pb2Fcg.js} +1 -1
- package/dist/ui/dist/assets/{elk-QONTBCTQ-BKFAKVSD.js → elk-QONTBCTQ-vu0Z4rYG.js} +1 -1
- package/dist/ui/dist/assets/{erDiagram-KYQIGQAA-CHYRd4aM.js → erDiagram-KYQIGQAA-BXnsRzCQ.js} +1 -1
- package/dist/ui/dist/assets/{eventmodeling-K75KTNOO-BDJDv3Zf.js → eventmodeling-K75KTNOO-bSr88MT1.js} +1 -1
- package/dist/ui/dist/assets/flowDiagram-IUGLLWBU-CUH45H9n.js +1 -0
- package/dist/ui/dist/assets/{ganttDiagram-R7GPNTJY-gTHjYkFj.js → ganttDiagram-R7GPNTJY-BQzVkGbj.js} +1 -1
- package/dist/ui/dist/assets/{gitGraph-VSP46ZUC-D4cWkxKB.js → gitGraph-VSP46ZUC-BegblPQi.js} +1 -1
- package/dist/ui/dist/assets/{gitGraphDiagram-PDYL7XHY-D3M9wYMr.js → gitGraphDiagram-PDYL7XHY-BaGlGpEX.js} +1 -1
- package/dist/ui/dist/assets/index-D74Skifa.css +1 -0
- package/dist/ui/dist/assets/index-D8ErIacA.js +136 -0
- package/dist/ui/dist/assets/{info-OHQRW6UA-B9y0ksVq.js → info-OHQRW6UA-D3HVGJDc.js} +1 -1
- package/dist/ui/dist/assets/{infoDiagram-MVDRKAX5-s4FMwb8r.js → infoDiagram-MVDRKAX5-Ckcp-D0C.js} +1 -1
- package/dist/ui/dist/assets/{ishikawaDiagram-HPEHV2GE-CnQdxybf.js → ishikawaDiagram-HPEHV2GE-CWhd0CTS.js} +1 -1
- package/dist/ui/dist/assets/{journeyDiagram-BOSHW7O7-I-9OpDWY.js → journeyDiagram-BOSHW7O7-CrH5cFXY.js} +1 -1
- package/dist/ui/dist/assets/{kanban-definition-FNSA4HC5-DqUbIdH4.js → kanban-definition-FNSA4HC5-CpORMTDZ.js} +1 -1
- package/dist/ui/dist/assets/{line-BELSui4d.js → line-B3El9R0Z.js} +1 -1
- package/dist/ui/dist/assets/{linear-77hmn2iQ.js → linear-DLfthkbB.js} +1 -1
- package/dist/ui/dist/assets/{mermaid-parser.core-Bxa71wW-.js → mermaid-parser.core-QtQjLaoK.js} +3 -3
- package/dist/ui/dist/assets/{mermaid.core-DBI9F4bh.js → mermaid.core-C2DGgMSc.js} +4 -4
- package/dist/ui/dist/assets/{mindmap-definition-6OY57UG3-BxXMOapP.js → mindmap-definition-6OY57UG3-CW1lSXnX.js} +1 -1
- package/dist/ui/dist/assets/{packet-JDAUHWVQ-DTT77cQh.js → packet-JDAUHWVQ-Dhu_m_17.js} +1 -1
- package/dist/ui/dist/assets/{pegDiagram-ECIUJNBX-HzrOQPT5.js → pegDiagram-ECIUJNBX-BGOhbzN4.js} +1 -1
- package/dist/ui/dist/assets/{pie-XZMESJXO-iHwL1Qw-.js → pie-XZMESJXO-Citt3cMX.js} +1 -1
- package/dist/ui/dist/assets/{pieDiagram-GNMPY74T-DZ1tLVjw.js → pieDiagram-GNMPY74T-DPVZikvz.js} +1 -1
- package/dist/ui/dist/assets/{prism-core-NtO0YF9C.js → prism-core-YgwsYh9d.js} +1 -1
- package/dist/ui/dist/assets/{quadrantDiagram-D57K4MC3-BjTi9H5L.js → quadrantDiagram-D57K4MC3-Bwye1B9e.js} +1 -1
- package/dist/ui/dist/assets/{radar-ABXABTNO-D2hYgXSB.js → radar-ABXABTNO-DRUb4G6V.js} +1 -1
- package/dist/ui/dist/assets/{railroad-I3PHUGI6-DpakXN74.js → railroad-I3PHUGI6-x3Ug2mxX.js} +1 -1
- package/dist/ui/dist/assets/{railroad-abnf-LNEFI6M7-B8ZFR3iy.js → railroad-abnf-LNEFI6M7-Dw14XhkZ.js} +1 -1
- package/dist/ui/dist/assets/{railroad-ebnf-DWYD2UWJ-S1XUyTsC.js → railroad-ebnf-DWYD2UWJ-AwoWTWgL.js} +1 -1
- package/dist/ui/dist/assets/{railroad-peg-JR7BVNR7-BbeHC_6K.js → railroad-peg-JR7BVNR7-U7MXfciE.js} +1 -1
- package/dist/ui/dist/assets/{railroadDiagram-Y72NRBL7-fd-2iyBo.js → railroadDiagram-Y72NRBL7-BxWlCZYs.js} +1 -1
- package/dist/ui/dist/assets/{requirementDiagram-EQYSW5RA-B9-HHKH-.js → requirementDiagram-EQYSW5RA-TPmnZguV.js} +1 -1
- package/dist/ui/dist/assets/{sankeyDiagram-SY24JHO5-CeQN1ZEG.js → sankeyDiagram-SY24JHO5-nPGftpl5.js} +1 -1
- package/dist/ui/dist/assets/{sequenceDiagram-BLEHNHQU-Vff7tx4t.js → sequenceDiagram-BLEHNHQU-BdctgaWa.js} +1 -1
- package/dist/ui/dist/assets/{src-D5-ZzLwt.js → src-zq235FjH.js} +1 -1
- package/dist/ui/dist/assets/{stateDiagram-v2-A6IESKWZ-Bzn_ma9c.js → stateDiagram-v2-A6IESKWZ-BK_E6kPg.js} +1 -1
- package/dist/ui/dist/assets/{swimlanes-B3ENRKFQ-CevqLchV.js → swimlanes-B3ENRKFQ-BY50Ne4l.js} +1 -1
- package/dist/ui/dist/assets/swimlanesDiagram-AYQRV4AK-Ctw23I3i.js +8 -0
- package/dist/ui/dist/assets/{timeline-definition-JXYKGLGB-D9jSDGJI.js → timeline-definition-JXYKGLGB-Bg8AXJ2P.js} +1 -1
- package/dist/ui/dist/assets/{treeView-D4JQ5SDB-CoXKj11m.js → treeView-D4JQ5SDB-B4hz6M4l.js} +1 -1
- package/dist/ui/dist/assets/{treemap-SAJKECNS-cHsansGe.js → treemap-SAJKECNS-e_Vc97Ox.js} +1 -1
- package/dist/ui/dist/assets/{usecaseDiagram-WPOLBNNX-CW9i3bW6.js → usecaseDiagram-WPOLBNNX-Butu_LCX.js} +1 -1
- package/dist/ui/dist/assets/{vennDiagram-Q3Y3IDCW-DuU3qEKJ.js → vennDiagram-Q3Y3IDCW-BGIyxlbf.js} +1 -1
- package/dist/ui/dist/assets/{wardley-7MLQ67FV-dl9RgHUI.js → wardley-7MLQ67FV-Btv95mqq.js} +1 -1
- package/dist/ui/dist/assets/{wardleyDiagram-IVAIDKWA-BOXhrK-a.js → wardleyDiagram-IVAIDKWA-DwTKExJ4.js} +1 -1
- package/dist/ui/dist/assets/{xychartDiagram-4URNHDU4-CLQNGrh4.js → xychartDiagram-4URNHDU4-UmlA5uxc.js} +1 -1
- package/dist/ui/dist/index.html +2 -2
- package/package.json +1 -1
- package/skills/follow-me/SKILL.md +8 -8
- package/dist/ui/dist/assets/channel-CY2cQobm.js +0 -1
- package/dist/ui/dist/assets/flowDiagram-IUGLLWBU-Bke3CfUH.js +0 -1
- package/dist/ui/dist/assets/index-BUOFihod.js +0 -134
- package/dist/ui/dist/assets/index-DLNJT0VS.css +0 -1
- package/dist/ui/dist/assets/swimlanesDiagram-AYQRV4AK-Bkv8hAmN.js +0 -8
package/dist/src/prompt.js
CHANGED
|
@@ -24,13 +24,34 @@ function formatSelection(unit, select) {
|
|
|
24
24
|
function stripEol(text) {
|
|
25
25
|
return text.replace(/\r?\n$/, "");
|
|
26
26
|
}
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Where a hunk's rows sit: "tip lines a-b", or "base lines a-b" when the tip keeps none of them.
|
|
29
|
+
* The header says it so `[n]`, a change index counted from 0, is not read as a line number.
|
|
30
|
+
*/
|
|
31
|
+
function hunkSpan(hunk, tipStart) {
|
|
32
|
+
const kept = hunk.body.filter((line) => line.op !== "-").length;
|
|
33
|
+
const span = (side, from, count) => count === 1 ? `${side} line ${from}` : `${side} lines ${from}-${from + count - 1}`;
|
|
34
|
+
return kept > 0 ? span("tip", tipStart, kept) : span("base", hunk.oldStart + 1, hunk.body.length);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A hunk as `[n]+ text` and `[n]- text` rows, context indented. Under a "### path" heading the
|
|
38
|
+
* path is left out of the hunk's own line. With `gutter`, each row the tip keeps leads with its
|
|
39
|
+
* tip line number, which is what a `path:a-b` ref takes.
|
|
40
|
+
*/
|
|
41
|
+
function renderHunk(hunk, units, opts = {}) {
|
|
42
|
+
const tipStart = tipStartOf(hunk, units);
|
|
43
|
+
let tipLine = tipStart;
|
|
44
|
+
const lines = hunk.body.map((line) => {
|
|
45
|
+
const row = line.op === " "
|
|
46
|
+
? ` ${stripEol(line.text)}`
|
|
47
|
+
: `[${line.change}]${line.op} ${stripEol(line.text)}`;
|
|
48
|
+
if (!opts.gutter)
|
|
49
|
+
return row;
|
|
50
|
+
const number = line.op === "-" ? "" : `${tipLine++}`;
|
|
51
|
+
return `${number.padStart(5)} ${row}`;
|
|
52
|
+
});
|
|
53
|
+
const where = opts.withPath === false ? "" : ` ${hunk.path}`;
|
|
54
|
+
return [`${hunk.id}${where} ${hunkSpan(hunk, tipStart)}`, ...lines].join("\n");
|
|
34
55
|
}
|
|
35
56
|
function renderOtherUnit(unit) {
|
|
36
57
|
if (unit.kind === "mode") {
|
|
@@ -44,8 +65,10 @@ function renderUnits(diff) {
|
|
|
44
65
|
for (const unit of diff.units.values()) {
|
|
45
66
|
byPath.set(unit.path, [...(byPath.get(unit.path) ?? []), unit]);
|
|
46
67
|
}
|
|
47
|
-
const files = [...byPath].map(([path,
|
|
48
|
-
const rendered =
|
|
68
|
+
const files = [...byPath].map(([path, ofPath]) => {
|
|
69
|
+
const rendered = ofPath.map((unit) => unit.kind === "hunk"
|
|
70
|
+
? renderHunk(unit, diff.units, { withPath: false })
|
|
71
|
+
: renderOtherUnit(unit));
|
|
49
72
|
return [`### ${path}`, ...rendered].join("\n\n");
|
|
50
73
|
});
|
|
51
74
|
return files.join("\n\n");
|
|
@@ -208,8 +231,8 @@ function sessionLines(input) {
|
|
|
208
231
|
`- check: ${input.checkCommand}`,
|
|
209
232
|
].join("\n");
|
|
210
233
|
}
|
|
211
|
-
function renderUnit(unit) {
|
|
212
|
-
return unit.kind === "hunk" ? renderHunk(unit) : renderOtherUnit(unit);
|
|
234
|
+
function renderUnit(unit, units, gutter = false) {
|
|
235
|
+
return unit.kind === "hunk" ? renderHunk(unit, units, { gutter }) : renderOtherUnit(unit);
|
|
213
236
|
}
|
|
214
237
|
const QUOTE_LINES = 6;
|
|
215
238
|
const QUOTE_WIDTH = 160;
|
|
@@ -268,7 +291,7 @@ function renderMoved(input, changes, head) {
|
|
|
268
291
|
].join("\n"));
|
|
269
292
|
}
|
|
270
293
|
if (added.length > 0) {
|
|
271
|
-
sections.push(`## New units, in no commit yet\n\n${added.map(renderUnit).join("\n\n")}`);
|
|
294
|
+
sections.push(`## New units, in no commit yet\n\n${added.map((u) => renderUnit(u, units)).join("\n\n")}`);
|
|
272
295
|
}
|
|
273
296
|
const kept = draft.commits.flatMap((commit, k) => commit.units.map((ref) => {
|
|
274
297
|
const path = units.get(ref.unit)?.path ?? "";
|
|
@@ -948,9 +971,10 @@ function folded(review, commits, units, opts) {
|
|
|
948
971
|
export function renderReport(full, commits, units, opts) {
|
|
949
972
|
const session = folded(full, commits, units, opts);
|
|
950
973
|
const { ctx } = session;
|
|
974
|
+
const unkept = renderUnkept(session.review, ctx.commits);
|
|
951
975
|
const excluded = session.review.excluded;
|
|
952
976
|
if (excluded === undefined)
|
|
953
|
-
return renderIncluded(session.review, ctx, opts)
|
|
977
|
+
return `${renderIncluded(session.review, ctx, opts)}${unkept}`;
|
|
954
978
|
const noComments = new Set(excluded.comments);
|
|
955
979
|
const noConcerns = new Set(excluded.concerns);
|
|
956
980
|
const review = {
|
|
@@ -959,9 +983,26 @@ export function renderReport(full, commits, units, opts) {
|
|
|
959
983
|
concerns: (session.review.concerns ?? []).filter((d) => !noConcerns.has(d.concern)),
|
|
960
984
|
};
|
|
961
985
|
const tail = renderExcluded(collectItems(session.review, ctx, opts.responses));
|
|
962
|
-
const main = renderIncluded(review, ctx, opts)
|
|
986
|
+
const main = `${renderIncluded(review, ctx, opts)}${unkept}`;
|
|
963
987
|
return tail.length === 0 ? main : `${main}${main.endsWith("\n") ? "" : "\n"}${tail.join("\n")}`;
|
|
964
988
|
}
|
|
989
|
+
/**
|
|
990
|
+
* The agent's concerns the reviewer did not keep, by id, so the agent knows what the report left
|
|
991
|
+
* out: undecided ones (the page lists them at Submit) and dismissed ones. Empty when none.
|
|
992
|
+
*/
|
|
993
|
+
function renderUnkept(review, commits) {
|
|
994
|
+
const decisions = new Map((review.concerns ?? []).map((d) => [d.concern, d.decision]));
|
|
995
|
+
const all = commits.flatMap((c) => c.concerns ?? []);
|
|
996
|
+
const undecided = all.filter((k) => !decisions.has(k.id)).map((k) => k.id);
|
|
997
|
+
const dismissed = all.filter((k) => decisions.get(k.id) === "dismissed").map((k) => k.id);
|
|
998
|
+
const parts = [
|
|
999
|
+
...(undecided.length === 0 ? [] : [`${undecided.join(", ")} (undecided)`]),
|
|
1000
|
+
...(dismissed.length === 0 ? [] : [`${dismissed.join(", ")} (dismissed)`]),
|
|
1001
|
+
];
|
|
1002
|
+
if (parts.length === 0)
|
|
1003
|
+
return "";
|
|
1004
|
+
return `\nYour concerns the reviewer did not keep, left out of this report: ${parts.join("; ")}.\n`;
|
|
1005
|
+
}
|
|
965
1006
|
function renderIncluded(review, ctx, opts) {
|
|
966
1007
|
const { commits, units } = ctx;
|
|
967
1008
|
const walk = review.mode === "walk";
|
|
@@ -1001,7 +1042,7 @@ function renderIncluded(review, ctx, opts) {
|
|
|
1001
1042
|
if (started.length > 0)
|
|
1002
1043
|
out.push(...renderThreads(ctx, started));
|
|
1003
1044
|
if (walk && items.length > 0) {
|
|
1004
|
-
out.push("
|
|
1045
|
+
out.push("This branch is someone else's, so leave its code alone. When the user asks, post this review to the merge request as porting.md beside the skill says.", "");
|
|
1005
1046
|
}
|
|
1006
1047
|
if (!walk && (feedback.length > 0 || questions.length > 0)) {
|
|
1007
1048
|
out.push("Answer every comment id above in `responses` of the next draft, then run `follow-me check` and `follow-me apply`.", "");
|
|
@@ -1092,12 +1133,12 @@ export function renderEvents(events, ctx = null) {
|
|
|
1092
1133
|
return `${events.flatMap((event) => renderEvent(event, ctx)).join("\n")}\n`;
|
|
1093
1134
|
}
|
|
1094
1135
|
/** A unit as prompt.md prints it, and which commits of the plan take its lines. */
|
|
1095
|
-
export function renderShownUnit(unit, commits) {
|
|
1136
|
+
export function renderShownUnit(unit, units, commits) {
|
|
1096
1137
|
const taken = commits.flatMap((commit, k) => commit.refs
|
|
1097
1138
|
.filter((ref) => ref.unit === unit.id)
|
|
1098
1139
|
.map((ref) => `commit ${k + 1} takes ${formatSelection(ref.unit, ref.select)}`));
|
|
1099
1140
|
const where = taken.length === 0 ? "in no commit of the plan" : taken.join("; ");
|
|
1100
|
-
return `${renderUnit(unit)}\n${where}\n`;
|
|
1141
|
+
return `${renderUnit(unit, units, true)}\n${where}\n`;
|
|
1101
1142
|
}
|
|
1102
1143
|
/** A comment with every row it was made on, its words and the whole thread under it. */
|
|
1103
1144
|
export function renderShownComment(c, ctx, version) {
|
package/dist/src/refs.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/** Lines quoted per ref, as comments quote their rows. */
|
|
2
|
+
export const QUOTE_LINES = 8;
|
|
3
|
+
const GRAMMAR = /^(.+):(\d+)(?:-(\d+))?(?:@(\d+|base))?$/;
|
|
4
|
+
/** `path:12`, `path:12-18`, `path:12@3`, `path:12-18@base`, or null when it is none of those. */
|
|
5
|
+
export function parseRefText(text) {
|
|
6
|
+
const m = GRAMMAR.exec(text);
|
|
7
|
+
const [, path, startRaw, endRaw, atRaw] = m ?? [];
|
|
8
|
+
if (path === undefined || startRaw === undefined)
|
|
9
|
+
return null;
|
|
10
|
+
const start = Number(startRaw);
|
|
11
|
+
const end = endRaw === undefined ? start : Number(endRaw);
|
|
12
|
+
const at = atRaw === undefined ? null : atRaw === "base" ? "base" : Number(atRaw);
|
|
13
|
+
return { text, path, start, end, at };
|
|
14
|
+
}
|
|
15
|
+
/** One key per place, so `a.ts:5` and `a.ts:5-5` share a number. */
|
|
16
|
+
export function refKey(spec) {
|
|
17
|
+
return `${spec.path}:${spec.start}-${spec.end}@${spec.at ?? "tip"}`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A code span names a file when its path has a letter and a slash or a dot, so `10:30`,
|
|
21
|
+
* `localhost:3000` and `127.0.0.1:80` stay code.
|
|
22
|
+
*/
|
|
23
|
+
function looksLikeFile(path) {
|
|
24
|
+
return /[A-Za-z]/.test(path) && /[/.]/.test(path) && !/\s/.test(path);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The text of every inline code span outside fenced blocks, in order, read as CommonMark does: a
|
|
28
|
+
* run of backticks closes only on a run of the same length, and one space padding both ends is
|
|
29
|
+
* dropped.
|
|
30
|
+
*/
|
|
31
|
+
export function codeSpans(markdown) {
|
|
32
|
+
const spans = [];
|
|
33
|
+
let fence = null;
|
|
34
|
+
const prose = [];
|
|
35
|
+
for (const line of markdown.split("\n")) {
|
|
36
|
+
const opener = /^ {0,3}(`{3,}|~{3,})/.exec(line)?.[1];
|
|
37
|
+
if (fence === null && opener !== undefined) {
|
|
38
|
+
fence = opener;
|
|
39
|
+
prose.push("");
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (fence !== null) {
|
|
43
|
+
const closer = /^ {0,3}(`{3,}|~{3,})\s*$/.exec(line)?.[1];
|
|
44
|
+
if (closer !== undefined && closer[0] === fence[0] && closer.length >= fence.length)
|
|
45
|
+
fence = null;
|
|
46
|
+
prose.push("");
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
prose.push(line);
|
|
50
|
+
}
|
|
51
|
+
// Spans never cross a blank line, which ends the paragraph.
|
|
52
|
+
for (const paragraph of prose.join("\n").split(/\n\s*\n/)) {
|
|
53
|
+
let i = 0;
|
|
54
|
+
while (i < paragraph.length) {
|
|
55
|
+
const c = paragraph[i];
|
|
56
|
+
if (c === "\\") {
|
|
57
|
+
i += 2;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (c !== "`") {
|
|
61
|
+
i += 1;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
let run = 0;
|
|
65
|
+
while (paragraph[i + run] === "`")
|
|
66
|
+
run += 1;
|
|
67
|
+
const open = i + run;
|
|
68
|
+
let close = -1;
|
|
69
|
+
for (let j = open; j < paragraph.length;) {
|
|
70
|
+
if (paragraph[j] !== "`") {
|
|
71
|
+
j += 1;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
let k = 0;
|
|
75
|
+
while (paragraph[j + k] === "`")
|
|
76
|
+
k += 1;
|
|
77
|
+
if (k === run) {
|
|
78
|
+
close = j;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
j += k;
|
|
82
|
+
}
|
|
83
|
+
if (close === -1) {
|
|
84
|
+
i = open;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
let text = paragraph.slice(open, close).replace(/\n/g, " ");
|
|
88
|
+
if (text.length > 2 && text.startsWith(" ") && text.endsWith(" ") && text.trim() !== "") {
|
|
89
|
+
text = text.slice(1, -1);
|
|
90
|
+
}
|
|
91
|
+
spans.push(text);
|
|
92
|
+
i = close + run;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return spans;
|
|
96
|
+
}
|
|
97
|
+
/** The refs a reply's markdown writes, each place once, in order of first appearance. */
|
|
98
|
+
export function refsIn(markdown) {
|
|
99
|
+
const seen = new Set();
|
|
100
|
+
const specs = [];
|
|
101
|
+
for (const span of codeSpans(markdown)) {
|
|
102
|
+
const spec = parseRefText(span);
|
|
103
|
+
if (spec === null || !looksLikeFile(spec.path))
|
|
104
|
+
continue;
|
|
105
|
+
const key = refKey(spec);
|
|
106
|
+
if (seen.has(key))
|
|
107
|
+
continue;
|
|
108
|
+
seen.add(key);
|
|
109
|
+
specs.push(spec);
|
|
110
|
+
}
|
|
111
|
+
return specs;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Every line of a changed text file as it reads with the given change lines applied: none for
|
|
115
|
+
* the base, all for the tip, the plan's first n commits for commit n. Null when the file does
|
|
116
|
+
* not exist then.
|
|
117
|
+
*/
|
|
118
|
+
export function linesWith(file, applied) {
|
|
119
|
+
const changes = file.hunks.flatMap((h) => h.body.flatMap((l) => (l.op === " " ? [] : [applied(h, l)])));
|
|
120
|
+
const any = changes.some((c) => c);
|
|
121
|
+
const all = changes.every((c) => c);
|
|
122
|
+
if (file.base === null ? !any : file.tip === null && all)
|
|
123
|
+
return null;
|
|
124
|
+
const base = file.base?.lines ?? [];
|
|
125
|
+
const out = [];
|
|
126
|
+
let b = 0;
|
|
127
|
+
let t = 0;
|
|
128
|
+
const keep = (text) => {
|
|
129
|
+
b += 1;
|
|
130
|
+
t += 1;
|
|
131
|
+
out.push({ text, tip: t, base: b });
|
|
132
|
+
};
|
|
133
|
+
for (const hunk of file.hunks) {
|
|
134
|
+
while (b < hunk.oldStart)
|
|
135
|
+
keep(base[b] ?? "");
|
|
136
|
+
for (const line of hunk.body) {
|
|
137
|
+
if (line.op === " ")
|
|
138
|
+
keep(line.text);
|
|
139
|
+
else if (line.op === "-") {
|
|
140
|
+
b += 1;
|
|
141
|
+
if (!applied(hunk, line))
|
|
142
|
+
out.push({ text: line.text, tip: null, base: b });
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
t += 1;
|
|
146
|
+
if (applied(hunk, line))
|
|
147
|
+
out.push({ text: line.text, tip: t, base: null });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
while (b < base.length)
|
|
152
|
+
keep(base[b] ?? "");
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
/** Whether the plan's first n commits take this change line. */
|
|
156
|
+
export function takenBy(commits) {
|
|
157
|
+
return (hunk, line) => commits.some((c) => c.refs.some((r) => r.unit === hunk.id &&
|
|
158
|
+
(r.select.kind === "rest" || r.select.changes.includes(line.change))));
|
|
159
|
+
}
|
|
160
|
+
/** The repo path a typed path names: its UTF-8 as the latin1 bytes git prints. */
|
|
161
|
+
export function repoPathOfTyped(typed) {
|
|
162
|
+
return Buffer.from(typed, "utf8").toString("latin1");
|
|
163
|
+
}
|
|
164
|
+
function utf8(latin1) {
|
|
165
|
+
return Buffer.from(latin1, "latin1").toString("utf8");
|
|
166
|
+
}
|
|
167
|
+
function spanOf(ns) {
|
|
168
|
+
if (ns.length === 0)
|
|
169
|
+
return null;
|
|
170
|
+
return { start: Math.min(...ns), end: Math.max(...ns) };
|
|
171
|
+
}
|
|
172
|
+
function versionLabel(at) {
|
|
173
|
+
return at === null ? "at the tip" : at === "base" ? "in the base" : `in commit ${at}`;
|
|
174
|
+
}
|
|
175
|
+
/** A written ref resolved to its lines and quote, numbered n, or the reason it does not resolve. */
|
|
176
|
+
export function resolveRef(spec, n, source) {
|
|
177
|
+
const { text, start, end, at } = spec;
|
|
178
|
+
if (start < 1)
|
|
179
|
+
return `${text}: lines count from 1`;
|
|
180
|
+
if (end < start)
|
|
181
|
+
return `${text} ends before it starts`;
|
|
182
|
+
if (typeof at === "number" && (at < 1 || at > source.commits.length)) {
|
|
183
|
+
const count = source.commits.length;
|
|
184
|
+
return `${text}: plan v${source.version} has ${count} commit${count === 1 ? "" : "s"}`;
|
|
185
|
+
}
|
|
186
|
+
const path = repoPathOfTyped(spec.path);
|
|
187
|
+
const where = versionLabel(at);
|
|
188
|
+
let lines;
|
|
189
|
+
let repoPath;
|
|
190
|
+
const file = [...source.textFiles.values()].find((f) => f.path === path);
|
|
191
|
+
const plain = [...source.unchanged].find(([p]) => p === path);
|
|
192
|
+
if (file !== undefined) {
|
|
193
|
+
const applied = at === null ? () => true : at === "base" ? () => false : takenBy(source.commits.slice(0, at));
|
|
194
|
+
const found = linesWith(file, applied);
|
|
195
|
+
if (found === null)
|
|
196
|
+
return `${text}: the file does not exist ${where}`;
|
|
197
|
+
lines = found;
|
|
198
|
+
repoPath = file.path;
|
|
199
|
+
}
|
|
200
|
+
else if (source.otherChanged.has(path)) {
|
|
201
|
+
return `${text}: not a text file`;
|
|
202
|
+
}
|
|
203
|
+
else if (plain !== undefined) {
|
|
204
|
+
lines = plain[1].map((t, i) => ({ text: t, tip: i + 1, base: i + 1 }));
|
|
205
|
+
repoPath = plain[0];
|
|
206
|
+
}
|
|
207
|
+
else
|
|
208
|
+
return `${text}: no such file at the tip`;
|
|
209
|
+
if (end > lines.length) {
|
|
210
|
+
return `${text} is past the end of the file ${where} (${lines.length} lines)`;
|
|
211
|
+
}
|
|
212
|
+
const picked = lines.slice(start - 1, end);
|
|
213
|
+
const kept = picked.flatMap((l) => (l.tip === null ? [] : [l.tip]));
|
|
214
|
+
const removed = picked.flatMap((l) => (l.tip === null && l.base !== null ? [l.base] : []));
|
|
215
|
+
return {
|
|
216
|
+
n,
|
|
217
|
+
path: repoPath,
|
|
218
|
+
start,
|
|
219
|
+
end,
|
|
220
|
+
at,
|
|
221
|
+
quote: picked.slice(0, QUOTE_LINES).map((l) => utf8(l.text).replace(/\r?\n$/, "")),
|
|
222
|
+
tip: source.tip,
|
|
223
|
+
lines: spanOf(kept),
|
|
224
|
+
old: spanOf(removed),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/** Every ref of a body resolved, or every reason one does not, so one fix round is enough. */
|
|
228
|
+
export function resolveRefs(specs, source) {
|
|
229
|
+
const refs = [];
|
|
230
|
+
const problems = [];
|
|
231
|
+
specs.forEach((spec, i) => {
|
|
232
|
+
const ref = resolveRef(spec, i + 1, source);
|
|
233
|
+
if (typeof ref === "string")
|
|
234
|
+
problems.push(ref);
|
|
235
|
+
else
|
|
236
|
+
refs.push(ref);
|
|
237
|
+
});
|
|
238
|
+
return { refs, problems };
|
|
239
|
+
}
|
package/dist/ui/dist/assets/{abnfDiagram-WEYOIA3C-Bp14ygmz.js → abnfDiagram-WEYOIA3C-BWgk01ve.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{m as e,t}from"./mermaid-parser.core-
|
|
1
|
+
import{m as e,t}from"./mermaid-parser.core-QtQjLaoK.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-zq235FjH.js";import"./chunk-DSNLSHJZ-DZZ635s5.js";import{n as i,r as a,t as o}from"./chunk-2E7WHVMD-BTJB-4C8.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-C2DGgMSc.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-
|
|
1
|
+
import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-CW-4NrUq.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
|
package/dist/ui/dist/assets/{architecture-WOLXFQ4H-CyfnP65O.js → architecture-WOLXFQ4H-EdfV1etv.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./chunk-NGNAAXSQ-C2Wy9Xmz.js";export{M as createArchitectureServices}from"./mermaid-parser.core-
|
|
1
|
+
import"./chunk-NGNAAXSQ-C2Wy9Xmz.js";export{M as createArchitectureServices}from"./mermaid-parser.core-QtQjLaoK.js";
|