@hawkeyexl/manni 2.5.1 → 2.6.0
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 +1 -1
- package/dist/{chunk-22WVCFP4.js → chunk-5RJVKWFZ.js} +2 -2
- package/dist/{chunk-22WVCFP4.js.map → chunk-5RJVKWFZ.js.map} +1 -1
- package/dist/{chunk-KZDTVSFK.js → chunk-J5YKHZDB.js} +2 -2
- package/dist/{chunk-NFCH7HCA.js → chunk-TQUTQD7J.js} +597 -36
- package/dist/chunk-TQUTQD7J.js.map +1 -0
- package/dist/cli.js +23 -9
- package/dist/cli.js.map +1 -1
- package/dist/docmeta.js +2 -2
- package/dist/index.d.ts +230 -9
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-NFCH7HCA.js.map +0 -1
- /package/dist/{chunk-KZDTVSFK.js.map → chunk-J5YKHZDB.js.map} +0 -0
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
withValueAt,
|
|
72
72
|
writeEncryptionKey,
|
|
73
73
|
writeFileAtomic
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-5RJVKWFZ.js";
|
|
75
75
|
|
|
76
76
|
// src/meta/core/reencrypt.ts
|
|
77
77
|
import { extname } from "node:path";
|
|
@@ -185,10 +185,12 @@ __export(cite_exports, {
|
|
|
185
185
|
GIT_UNAVAILABLE_HISTORY: () => GIT_UNAVAILABLE_HISTORY,
|
|
186
186
|
MARKER_JSON: () => MARKER_JSON,
|
|
187
187
|
MAX_MARKERS_PER_PAGE: () => MAX_MARKERS_PER_PAGE,
|
|
188
|
+
MAX_PAGE_COMMITS: () => MAX_PAGE_COMMITS,
|
|
188
189
|
MAX_RANGE_LINES: () => MAX_RANGE_LINES,
|
|
189
190
|
MOVE_BUDGET_BYTES: () => MOVE_BUDGET_BYTES,
|
|
190
191
|
MOVE_WINDOW_LINES: () => MOVE_WINDOW_LINES,
|
|
191
192
|
ManifestSet: () => ManifestSet,
|
|
193
|
+
PAGE_HISTORY_UNAVAILABLE: () => PAGE_HISTORY_UNAVAILABLE,
|
|
192
194
|
RULE_ID_PREFIX: () => RULE_ID_PREFIX,
|
|
193
195
|
SRC_PATTERN: () => SRC_PATTERN,
|
|
194
196
|
anchoredLines: () => anchoredLines,
|
|
@@ -198,9 +200,12 @@ __export(cite_exports, {
|
|
|
198
200
|
buildSourceIndex: () => buildSourceIndex,
|
|
199
201
|
checkCitations: () => checkCitations,
|
|
200
202
|
citationInputs: () => citationInputs,
|
|
203
|
+
claimDiff: () => claimDiff,
|
|
201
204
|
claimEnd: () => claimEnd,
|
|
205
|
+
claimHistory: () => claimHistory,
|
|
202
206
|
claimLine: () => claimLine,
|
|
203
207
|
claimMessageFor: () => claimMessageFor,
|
|
208
|
+
claimWords: () => claimWords,
|
|
204
209
|
classifyCitation: () => classifyCitation,
|
|
205
210
|
detectEol: () => detectEol,
|
|
206
211
|
duplicateJoinRefusal: () => duplicateJoinRefusal,
|
|
@@ -218,6 +223,7 @@ __export(cite_exports, {
|
|
|
218
223
|
hashLines: () => hashLines,
|
|
219
224
|
hashRange: () => hashRange2,
|
|
220
225
|
historyOf: () => historyOf,
|
|
226
|
+
holdsWords: () => holdsWords,
|
|
221
227
|
insertStatementBefore: () => insertStatementBefore,
|
|
222
228
|
insideFence: () => insideFence,
|
|
223
229
|
isBoundLine: () => isBoundLine,
|
|
@@ -258,6 +264,8 @@ __export(cite_exports, {
|
|
|
258
264
|
readSource: () => readSource,
|
|
259
265
|
reencryptCitationEntries: () => reencryptCitationEntries,
|
|
260
266
|
reencryptCitations: () => reencryptCitations,
|
|
267
|
+
refineClaim: () => refineClaim,
|
|
268
|
+
refusalLine: () => refusalLine,
|
|
261
269
|
removalLine: () => removalLine,
|
|
262
270
|
removeFrontmatterCitations: () => removeFrontmatterCitations,
|
|
263
271
|
removeLine: () => removeLine,
|
|
@@ -276,6 +284,9 @@ __export(cite_exports, {
|
|
|
276
284
|
runCheck: () => runCheck,
|
|
277
285
|
runRemove: () => runRemove,
|
|
278
286
|
runUpdate: () => runUpdate,
|
|
287
|
+
runsHolding: () => runsHolding,
|
|
288
|
+
sentencesOf: () => sentencesOf,
|
|
289
|
+
sharesSentence: () => sharesSentence,
|
|
279
290
|
shiftedEntries: () => shiftedEntries,
|
|
280
291
|
shortCommit: () => shortCommit,
|
|
281
292
|
shortLine: () => shortLine,
|
|
@@ -292,6 +303,7 @@ __export(cite_exports, {
|
|
|
292
303
|
splitLines: () => splitLines,
|
|
293
304
|
splitUnit: () => splitUnit,
|
|
294
305
|
statementForms: () => statementForms,
|
|
306
|
+
stripMarkers: () => stripMarkers,
|
|
295
307
|
toBodyLines: () => toBodyLines,
|
|
296
308
|
toFileLines: () => toFileLines,
|
|
297
309
|
toValidationResult: () => toValidationResult,
|
|
@@ -313,6 +325,7 @@ var CITE_RULES = [
|
|
|
313
325
|
"source-missing",
|
|
314
326
|
"claim-moved",
|
|
315
327
|
"claim-moved-ambiguous",
|
|
328
|
+
"claim-reanchored",
|
|
316
329
|
"claim-changed",
|
|
317
330
|
"marker-orphan",
|
|
318
331
|
"marker-invalid",
|
|
@@ -348,6 +361,7 @@ var DEFAULT_SEVERITY = {
|
|
|
348
361
|
"source-missing": "error",
|
|
349
362
|
"claim-moved": "notice",
|
|
350
363
|
"claim-moved-ambiguous": "warning",
|
|
364
|
+
"claim-reanchored": "notice",
|
|
351
365
|
"claim-changed": "warning",
|
|
352
366
|
"marker-orphan": "error",
|
|
353
367
|
"marker-invalid": "error",
|
|
@@ -1734,6 +1748,10 @@ function gitClient(root) {
|
|
|
1734
1748
|
};
|
|
1735
1749
|
const available = () => once("available", async () => (await run2(root, ["rev-parse", "--show-toplevel"])).ok);
|
|
1736
1750
|
const failed = (verb, outcome) => new CiteError(`git ${verb} failed: ${outcome.stderr.trim() || outcome.message}`);
|
|
1751
|
+
const shallow = () => once("shallow", async () => {
|
|
1752
|
+
const out = await run2(root, ["rev-parse", "--is-shallow-repository"]);
|
|
1753
|
+
return out.ok && out.stdout.trim() === "true";
|
|
1754
|
+
});
|
|
1737
1755
|
const hasCommit = (commit) => once(`has\0${commit}`, async () => {
|
|
1738
1756
|
const out = await run2(root, ["rev-parse", "--verify", "--quiet", "--end-of-options", `${commit}^{commit}`]);
|
|
1739
1757
|
if (out.ok) return true;
|
|
@@ -1771,10 +1789,34 @@ function gitClient(root) {
|
|
|
1771
1789
|
const out = await run2(root, ["diff", "--end-of-options", commit, "--", path]);
|
|
1772
1790
|
if (!out.ok) throw failed("diff", out);
|
|
1773
1791
|
return out.stdout;
|
|
1792
|
+
}),
|
|
1793
|
+
pageCommits: (path, cap) => once(`commits\0${String(cap)}\0${path}`, async () => {
|
|
1794
|
+
if (!await available()) return { commits: [], shallow: false, truncated: false };
|
|
1795
|
+
const out = await run2(root, [
|
|
1796
|
+
"log",
|
|
1797
|
+
`--format=%H${UNIT}%s`,
|
|
1798
|
+
"--topo-order",
|
|
1799
|
+
`-n${String(cap + 1)}`,
|
|
1800
|
+
"HEAD",
|
|
1801
|
+
"--",
|
|
1802
|
+
path
|
|
1803
|
+
]);
|
|
1804
|
+
if (!out.ok) throw failed("log", out);
|
|
1805
|
+
const commits = [];
|
|
1806
|
+
for (const line of out.stdout.split(/\r?\n/)) {
|
|
1807
|
+
if (line === "") continue;
|
|
1808
|
+
const at2 = line.indexOf(UNIT);
|
|
1809
|
+
if (at2 === -1) continue;
|
|
1810
|
+
commits.push({ sha: line.slice(0, at2), subject: line.slice(at2 + 1) });
|
|
1811
|
+
}
|
|
1812
|
+
const truncated = commits.length > cap;
|
|
1813
|
+
return { commits: commits.slice(0, cap), shallow: await shallow(), truncated };
|
|
1774
1814
|
})
|
|
1775
1815
|
};
|
|
1776
1816
|
}
|
|
1777
|
-
var
|
|
1817
|
+
var UNIT = "";
|
|
1818
|
+
var GIT_UNAVAILABLE_HISTORY = "git is not available here, so citations are checked without history: no never-true, no reanchored claims, no diffs, no commit subjects.";
|
|
1819
|
+
var PAGE_HISTORY_UNAVAILABLE = "the page history ends before the pin held; use fetch-depth: 0 to tell reanchored claims from changed ones";
|
|
1778
1820
|
var GIT_UNAVAILABLE_COMMIT = "git is not available here, so the citation records no commit.";
|
|
1779
1821
|
function noGit() {
|
|
1780
1822
|
return {
|
|
@@ -1783,10 +1825,293 @@ function noGit() {
|
|
|
1783
1825
|
lsFiles: () => Promise.resolve([]),
|
|
1784
1826
|
showFile: () => Promise.resolve({ missing: "commit" }),
|
|
1785
1827
|
subjectsSince: () => Promise.resolve([]),
|
|
1786
|
-
diffSince: () => Promise.resolve("")
|
|
1828
|
+
diffSince: () => Promise.resolve(""),
|
|
1829
|
+
pageCommits: () => Promise.resolve({ commits: [], shallow: false, truncated: false })
|
|
1787
1830
|
};
|
|
1788
1831
|
}
|
|
1789
1832
|
|
|
1833
|
+
// src/cite/core/history.ts
|
|
1834
|
+
var MAX_PAGE_COMMITS = 256;
|
|
1835
|
+
function stripMarkers(lines, format) {
|
|
1836
|
+
return lines.filter((line) => !isMarkerLine(line, format));
|
|
1837
|
+
}
|
|
1838
|
+
function claimWords(lines, format) {
|
|
1839
|
+
return stripMarkers(lines, format).join(" ").replace(/\s+/g, " ").trim();
|
|
1840
|
+
}
|
|
1841
|
+
function sentencesOf(text) {
|
|
1842
|
+
return text.split(/(?<=[.!?])\s+/).map((sentence) => sentence.replace(/\s+/g, " ").trim().toLowerCase()).filter((sentence) => sentence !== "");
|
|
1843
|
+
}
|
|
1844
|
+
function sharesSentence(a, b) {
|
|
1845
|
+
const left = new Set(sentencesOf(a));
|
|
1846
|
+
return sentencesOf(b).some((sentence) => left.has(sentence));
|
|
1847
|
+
}
|
|
1848
|
+
function holdsWords(outer, inner) {
|
|
1849
|
+
if (inner === "") return true;
|
|
1850
|
+
if (outer === inner) return true;
|
|
1851
|
+
if (outer.startsWith(`${inner} `)) return true;
|
|
1852
|
+
if (outer.endsWith(` ${inner}`)) return true;
|
|
1853
|
+
return outer.includes(` ${inner} `);
|
|
1854
|
+
}
|
|
1855
|
+
function runsHolding(lines, format, bodyLine, inner) {
|
|
1856
|
+
if (inner === "") return [];
|
|
1857
|
+
let text = "";
|
|
1858
|
+
const at2 = [];
|
|
1859
|
+
for (let n = Math.max(bodyLine, 1); n <= lines.length; n++) {
|
|
1860
|
+
const line = lines[n - 1] ?? "";
|
|
1861
|
+
if (isMarkerLine(line, format)) continue;
|
|
1862
|
+
const words = line.replace(/\s+/g, " ").trim();
|
|
1863
|
+
if (words === "") continue;
|
|
1864
|
+
if (text !== "") {
|
|
1865
|
+
text += " ";
|
|
1866
|
+
at2.push(n);
|
|
1867
|
+
}
|
|
1868
|
+
for (let i = 0; i < words.length; i++) at2.push(n);
|
|
1869
|
+
text += words;
|
|
1870
|
+
}
|
|
1871
|
+
const out = [];
|
|
1872
|
+
let from = 0;
|
|
1873
|
+
for (; ; ) {
|
|
1874
|
+
const found = text.indexOf(inner, from);
|
|
1875
|
+
if (found === -1) break;
|
|
1876
|
+
from = found + 1;
|
|
1877
|
+
const before = found === 0 ? " " : text[found - 1];
|
|
1878
|
+
const afterAt = found + inner.length;
|
|
1879
|
+
const after = afterAt === text.length ? " " : text[afterAt];
|
|
1880
|
+
if (before !== " " || after !== " ") continue;
|
|
1881
|
+
const start = at2[found];
|
|
1882
|
+
const end = at2[afterAt - 1];
|
|
1883
|
+
if (start === void 0 || end === void 0) continue;
|
|
1884
|
+
if (!out.some((span) => span.start === start && span.end === end)) out.push({ start, end });
|
|
1885
|
+
}
|
|
1886
|
+
return out.filter(
|
|
1887
|
+
(span) => !out.some(
|
|
1888
|
+
(other) => (other.start !== span.start || other.end !== span.end) && other.start >= span.start && other.end <= span.end
|
|
1889
|
+
)
|
|
1890
|
+
);
|
|
1891
|
+
}
|
|
1892
|
+
function bounds(line) {
|
|
1893
|
+
return line === void 0 || line.trim() === "" || ANY_FENCE.test(line);
|
|
1894
|
+
}
|
|
1895
|
+
function pinOf2(lines, span) {
|
|
1896
|
+
if (span.start < 1 || span.end > lines.length || span.end < span.start) return void 0;
|
|
1897
|
+
return hashLines(lines.slice(span.start - 1, span.end).join("\n"));
|
|
1898
|
+
}
|
|
1899
|
+
function readThen(input, text) {
|
|
1900
|
+
const then = readPage(input.page.file, text, { format: input.page.format });
|
|
1901
|
+
const lines = splitLines(then.content);
|
|
1902
|
+
if (input.entry.citation.claim?.lines !== void 0) return { page: then, lines };
|
|
1903
|
+
const id = input.entry.citation.id;
|
|
1904
|
+
if (id === void 0) return void 0;
|
|
1905
|
+
const marker = then.statements.find(
|
|
1906
|
+
(statement) => statement.payload.kind === "ref" && statement.payload.id === id
|
|
1907
|
+
);
|
|
1908
|
+
if (marker === void 0) return void 0;
|
|
1909
|
+
return { page: then, lines, marker };
|
|
1910
|
+
}
|
|
1911
|
+
function anchorHeldAt(input, then) {
|
|
1912
|
+
const pin = input.entry.citation.claim?.integrity;
|
|
1913
|
+
if (pin === void 0) return { kind: "absent" };
|
|
1914
|
+
const was = {
|
|
1915
|
+
citation: input.entry.citation,
|
|
1916
|
+
origin: input.entry.origin,
|
|
1917
|
+
...then.marker === void 0 ? {} : { marker: then.marker }
|
|
1918
|
+
};
|
|
1919
|
+
const split = then.marker === void 0 ? void 0 : misplacedMarkerAt(then.page, then.lines, then.marker.line, was);
|
|
1920
|
+
const end = claimEnd(then.page, was, then.lines, split);
|
|
1921
|
+
if (end === null || end.status !== "current" && end.status !== "moved") {
|
|
1922
|
+
return { kind: "absent" };
|
|
1923
|
+
}
|
|
1924
|
+
for (const spec of [end.fileLines, end.newFileLines]) {
|
|
1925
|
+
const span = spec === void 0 ? void 0 : parseLines(spec);
|
|
1926
|
+
if (span !== void 0 && pinOf2(then.lines, span) === pin) {
|
|
1927
|
+
return { kind: "found", span, lines: then.lines.slice(span.start - 1, span.end) };
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
if (split !== void 0) {
|
|
1931
|
+
const text = unitText(then.lines, split);
|
|
1932
|
+
if (hashLines(text.join("\n")) === pin) {
|
|
1933
|
+
return { kind: "found", span: movedUnit(split), lines: text };
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
return { kind: "absent" };
|
|
1937
|
+
}
|
|
1938
|
+
function windowHeldAt(input, then) {
|
|
1939
|
+
const pin = input.entry.citation.claim?.integrity;
|
|
1940
|
+
const marker = then.marker;
|
|
1941
|
+
if (pin === void 0 || marker === void 0) return { kind: "absent" };
|
|
1942
|
+
if (input.entry.citation.quote === true) return { kind: "absent" };
|
|
1943
|
+
const lines = then.lines;
|
|
1944
|
+
let stop = marker.line;
|
|
1945
|
+
for (let n = marker.line + 1; n <= lines.length; n++) {
|
|
1946
|
+
if (bounds(lines[n - 1])) break;
|
|
1947
|
+
stop = n;
|
|
1948
|
+
}
|
|
1949
|
+
const starts = [marker.line];
|
|
1950
|
+
for (let n = marker.line + 1; n <= stop; n++) {
|
|
1951
|
+
const line = lines[n - 1] ?? "";
|
|
1952
|
+
if (line.trim() === "" || isMarkerLine(line, then.page.format)) continue;
|
|
1953
|
+
starts.push(n);
|
|
1954
|
+
}
|
|
1955
|
+
for (const start of starts) {
|
|
1956
|
+
for (let end = start; end <= stop; end++) {
|
|
1957
|
+
if (pinOf2(lines, { start, end }) === pin) {
|
|
1958
|
+
return { kind: "found", span: { start, end }, lines: lines.slice(start - 1, end) };
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
return { kind: "absent" };
|
|
1963
|
+
}
|
|
1964
|
+
async function stillWritten(input, commit, pageText) {
|
|
1965
|
+
const pin = input.entry.citation.claim?.integrity;
|
|
1966
|
+
if (pin === void 0) return { stop: true, born: true };
|
|
1967
|
+
const manifest = input.manifest;
|
|
1968
|
+
if (manifest !== void 0) {
|
|
1969
|
+
const shown = await input.git.showFile(commit, manifest);
|
|
1970
|
+
const held2 = "text" in shown && shown.text.includes(pin);
|
|
1971
|
+
return { stop: !held2, born: !held2 };
|
|
1972
|
+
}
|
|
1973
|
+
const held = pageText.includes(pin);
|
|
1974
|
+
return { stop: false, born: !held };
|
|
1975
|
+
}
|
|
1976
|
+
async function claimHistory(input) {
|
|
1977
|
+
const { git, path } = input;
|
|
1978
|
+
if (git.pageCommits === void 0) return { kind: "none" };
|
|
1979
|
+
if (!await git.available()) return { kind: "none" };
|
|
1980
|
+
const cap = input.cap ?? MAX_PAGE_COMMITS;
|
|
1981
|
+
const history = await git.pageCommits(path, cap);
|
|
1982
|
+
const { commits } = history;
|
|
1983
|
+
if (commits.length === 0) return { kind: "none" };
|
|
1984
|
+
const format = input.page.format;
|
|
1985
|
+
const baselineAt = (index, then, found) => {
|
|
1986
|
+
if (found.kind !== "found") return { kind: "none" };
|
|
1987
|
+
const commit = commits[index];
|
|
1988
|
+
if (commit === void 0) return { kind: "none" };
|
|
1989
|
+
return {
|
|
1990
|
+
kind: "baseline",
|
|
1991
|
+
commit: commit.sha,
|
|
1992
|
+
commitsSince: commits.slice(0, index).map((c) => c.subject),
|
|
1993
|
+
words: claimWords(found.lines, format),
|
|
1994
|
+
pageWords: claimWords(then.lines.slice(then.page.bodyLine - 1), format),
|
|
1995
|
+
lines: found.lines,
|
|
1996
|
+
at: spellLines(found.span)
|
|
1997
|
+
};
|
|
1998
|
+
};
|
|
1999
|
+
const examined = [];
|
|
2000
|
+
let ended = "cap";
|
|
2001
|
+
let born = false;
|
|
2002
|
+
for (let i = 0; i < commits.length; i++) {
|
|
2003
|
+
const commit = commits[i];
|
|
2004
|
+
if (commit === void 0) continue;
|
|
2005
|
+
const shown = await git.showFile(commit.sha, path);
|
|
2006
|
+
if (!("text" in shown)) {
|
|
2007
|
+
ended = shown.missing === "commit" ? "unavailable" : "birth";
|
|
2008
|
+
break;
|
|
2009
|
+
}
|
|
2010
|
+
const then = readThen(input, shown.text);
|
|
2011
|
+
if (then === void 0) {
|
|
2012
|
+
ended = "birth";
|
|
2013
|
+
break;
|
|
2014
|
+
}
|
|
2015
|
+
examined.push(then);
|
|
2016
|
+
const found = anchorHeldAt(input, then);
|
|
2017
|
+
if (found.kind === "found") return baselineAt(i, then, found);
|
|
2018
|
+
const written = await stillWritten(input, commit.sha, shown.text);
|
|
2019
|
+
if (written.born) born = true;
|
|
2020
|
+
if (written.stop) {
|
|
2021
|
+
ended = "birth";
|
|
2022
|
+
break;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
for (const [i, then] of examined.entries()) {
|
|
2026
|
+
const found = windowHeldAt(input, then);
|
|
2027
|
+
if (found.kind === "found") return baselineAt(i, then, found);
|
|
2028
|
+
}
|
|
2029
|
+
if (ended === "birth" || born) return { kind: "none" };
|
|
2030
|
+
if (ended === "unavailable") return { kind: "unavailable" };
|
|
2031
|
+
return history.truncated || history.shallow ? { kind: "unavailable" } : { kind: "none" };
|
|
2032
|
+
}
|
|
2033
|
+
function claimDiff(input) {
|
|
2034
|
+
const a = input.was.lines;
|
|
2035
|
+
const b = input.now.lines;
|
|
2036
|
+
let head = 0;
|
|
2037
|
+
while (head < a.length && head < b.length && a[head] === b[head]) head++;
|
|
2038
|
+
let tail = 0;
|
|
2039
|
+
while (tail < a.length - head && tail < b.length - head && a[a.length - 1 - tail] === b[b.length - 1 - tail]) {
|
|
2040
|
+
tail++;
|
|
2041
|
+
}
|
|
2042
|
+
const out = [
|
|
2043
|
+
`--- ${input.file}@${shortCommit(input.commit)}:${input.was.at}`,
|
|
2044
|
+
`+++ ${input.file}:${input.now.at}`
|
|
2045
|
+
];
|
|
2046
|
+
for (const line of a.slice(0, head)) out.push(` ${line}`);
|
|
2047
|
+
for (const line of a.slice(head, a.length - tail)) out.push(`-${line}`);
|
|
2048
|
+
for (const line of b.slice(head, b.length - tail)) out.push(`+${line}`);
|
|
2049
|
+
for (const line of a.slice(a.length - tail)) out.push(` ${line}`);
|
|
2050
|
+
return out.join("\n");
|
|
2051
|
+
}
|
|
2052
|
+
function refineClaim(input) {
|
|
2053
|
+
const { claim, history, entry, page, lines } = input;
|
|
2054
|
+
if (history.kind === "unavailable") return { ...claim, historyAvailable: false };
|
|
2055
|
+
if (history.kind === "none") return claim;
|
|
2056
|
+
const format = page.format;
|
|
2057
|
+
const base = {
|
|
2058
|
+
...claim,
|
|
2059
|
+
commitSha: history.commit,
|
|
2060
|
+
historyAvailable: true,
|
|
2061
|
+
commitsSince: history.commitsSince,
|
|
2062
|
+
baselineText: history.lines
|
|
2063
|
+
};
|
|
2064
|
+
const withDiff = (end, now2) => {
|
|
2065
|
+
const diff = claimDiff({
|
|
2066
|
+
file: page.file,
|
|
2067
|
+
commit: history.commit,
|
|
2068
|
+
was: { at: history.at, lines: history.lines },
|
|
2069
|
+
now: now2
|
|
2070
|
+
});
|
|
2071
|
+
return { ...end, diff };
|
|
2072
|
+
};
|
|
2073
|
+
if (entry.citation.quote === true) {
|
|
2074
|
+
const now2 = claim.text ?? [];
|
|
2075
|
+
const same = stripMarkers(now2, format).join("\n") === stripMarkers(history.lines, format).join("\n");
|
|
2076
|
+
const at2 = claim.fileLines ?? history.at;
|
|
2077
|
+
return withDiff(same ? { ...base, status: "reanchored" } : base, { at: at2, lines: now2 });
|
|
2078
|
+
}
|
|
2079
|
+
if (entry.citation.claim?.lines === void 0) {
|
|
2080
|
+
const now2 = claim.text ?? [];
|
|
2081
|
+
const w12 = claimWords(now2, format);
|
|
2082
|
+
const at2 = claim.fileLines ?? history.at;
|
|
2083
|
+
const held = holdsWords(w12, history.words) && holdsWords(history.pageWords, w12);
|
|
2084
|
+
return withDiff(held ? { ...base, status: "reanchored" } : base, { at: at2, lines: now2 });
|
|
2085
|
+
}
|
|
2086
|
+
const runs = runsHolding(lines, format, page.bodyLine, history.words);
|
|
2087
|
+
const [only] = runs;
|
|
2088
|
+
if (runs.length > 1) {
|
|
2089
|
+
return {
|
|
2090
|
+
...claim,
|
|
2091
|
+
status: "moved-ambiguous",
|
|
2092
|
+
candidates: runs.map((span) => spellLines(toBodyLines(span, page.bodyLine))),
|
|
2093
|
+
candidateFileLines: runs.map(spellLines)
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
if (only === void 0) {
|
|
2097
|
+
return withDiff(base, { at: claim.fileLines ?? history.at, lines: claim.text ?? [] });
|
|
2098
|
+
}
|
|
2099
|
+
const now = lines.slice(only.start - 1, only.end);
|
|
2100
|
+
const w1 = claimWords(now, format);
|
|
2101
|
+
if (!holdsWords(history.pageWords, w1)) {
|
|
2102
|
+
return withDiff(base, { at: claim.fileLines ?? history.at, lines: claim.text ?? [] });
|
|
2103
|
+
}
|
|
2104
|
+
return withDiff(
|
|
2105
|
+
{
|
|
2106
|
+
...base,
|
|
2107
|
+
status: "reanchored",
|
|
2108
|
+
newLines: spellLines(toBodyLines(only, page.bodyLine)),
|
|
2109
|
+
newFileLines: spellLines(only)
|
|
2110
|
+
},
|
|
2111
|
+
{ at: spellLines(only), lines: now }
|
|
2112
|
+
);
|
|
2113
|
+
}
|
|
2114
|
+
|
|
1790
2115
|
// src/cite/core/classify.ts
|
|
1791
2116
|
async function historyOf(git, commit, path, range, pin, key, budget) {
|
|
1792
2117
|
const shown = await git.showFile(commit, path);
|
|
@@ -2437,13 +2762,37 @@ function claimMessageFor(result) {
|
|
|
2437
2762
|
id,
|
|
2438
2763
|
`the claim at ${at(where ?? "?")} now appears at lines ${listOf(claim.candidateFileLines ?? [])}.`
|
|
2439
2764
|
);
|
|
2765
|
+
case "reanchored": {
|
|
2766
|
+
const since = claim.commitSha === void 0 ? "" : ` since ${short(claim.commitSha)}`;
|
|
2767
|
+
const to = claim.newFileLines === void 0 ? "" : `, to ${at(claim.newFileLines)}`;
|
|
2768
|
+
return named2(
|
|
2769
|
+
id,
|
|
2770
|
+
`the claim at ${at(where ?? "?")} was reanchored${since}${to}. Its words are unchanged.`
|
|
2771
|
+
);
|
|
2772
|
+
}
|
|
2440
2773
|
case "changed":
|
|
2441
|
-
|
|
2774
|
+
if (where === void 0) {
|
|
2775
|
+
return named2(
|
|
2776
|
+
id,
|
|
2777
|
+
"the claim has no lines and no marker names the entry, so its pin anchors nothing."
|
|
2778
|
+
);
|
|
2779
|
+
}
|
|
2780
|
+
return named2(id, `the claim at ${at(where)} has ${claimChange(claim)}`);
|
|
2442
2781
|
case "current":
|
|
2443
2782
|
case "skipped":
|
|
2444
2783
|
return "";
|
|
2445
2784
|
}
|
|
2446
2785
|
}
|
|
2786
|
+
function claimChange(claim) {
|
|
2787
|
+
if (claim.historyAvailable === false) {
|
|
2788
|
+
return "changed since it was pinned (history unavailable; fetch-depth: 0).";
|
|
2789
|
+
}
|
|
2790
|
+
if (claim.commitSha === void 0) return "changed since it was pinned.";
|
|
2791
|
+
const at2 = short(claim.commitSha);
|
|
2792
|
+
const since = claim.commitsSince ?? [];
|
|
2793
|
+
const count = since.length === 0 ? "uncommitted" : plural(since.length, "commit");
|
|
2794
|
+
return `changed since ${at2}, ${count}.`;
|
|
2795
|
+
}
|
|
2447
2796
|
function misplacedMessageFor(id, marker) {
|
|
2448
2797
|
const place = marker.block ? `above the block at line ${String(marker.place)}` : `above line ${String(marker.place)}`;
|
|
2449
2798
|
return named2(
|
|
@@ -2656,6 +3005,7 @@ async function checkCitations(page, opts) {
|
|
|
2656
3005
|
const read = readPage(page.file, page.content, readOptions);
|
|
2657
3006
|
const severity = resolveSeverity(opts.severity);
|
|
2658
3007
|
const client = opts.gitClient ?? gitClient(opts.root);
|
|
3008
|
+
const pageGit = opts.pageGitClient ?? (opts.pageRoot === void 0 || opts.pageRoot === opts.root ? client : gitClient(opts.pageRoot));
|
|
2659
3009
|
const checkSources = opts.checkSources !== false;
|
|
2660
3010
|
const lines = splitLines(read.content);
|
|
2661
3011
|
const results = [];
|
|
@@ -2679,7 +3029,10 @@ async function checkCitations(page, opts) {
|
|
|
2679
3029
|
const misplacedAt = new Map(misplaced.map((found) => [found.line, found]));
|
|
2680
3030
|
for (const entry of read.citations) {
|
|
2681
3031
|
const split = entry.marker === void 0 ? void 0 : misplacedAt.get(entry.marker.line);
|
|
2682
|
-
const claim =
|
|
3032
|
+
const claim = await withClaimHistory(
|
|
3033
|
+
{ page: read, entry, claim: claimEnd(read, entry, lines, split), lines },
|
|
3034
|
+
{ path: read.file, git: pageGit, ...opts.pageCommitCap === void 0 ? {} : { cap: opts.pageCommitCap }, ...opts.owned === void 0 ? {} : { manifest: opts.owned.file } }
|
|
3035
|
+
);
|
|
2683
3036
|
const source = classifyOpts === void 0 ? skippedSource(entry) : await classifyCitation(entry, classifyOpts);
|
|
2684
3037
|
const result = {
|
|
2685
3038
|
citation: entry.citation,
|
|
@@ -2731,8 +3084,15 @@ async function checkCitations(page, opts) {
|
|
|
2731
3084
|
}
|
|
2732
3085
|
}
|
|
2733
3086
|
findings.push(...findingsFor(results, severity));
|
|
2734
|
-
const
|
|
2735
|
-
|
|
3087
|
+
const wantsSourceHistory = checkSources && read.citations.some(({ citation }) => citation.source["commit-sha"] !== void 0);
|
|
3088
|
+
const wantsClaimHistory = results.some((r) => r.claim?.status === "changed");
|
|
3089
|
+
if (wantsSourceHistory && !await client.available()) notices.push(GIT_UNAVAILABLE_HISTORY);
|
|
3090
|
+
else if (wantsClaimHistory && !await pageGit.available()) {
|
|
3091
|
+
notices.push(GIT_UNAVAILABLE_HISTORY);
|
|
3092
|
+
}
|
|
3093
|
+
if (results.some((r) => r.claim?.historyAvailable === false)) {
|
|
3094
|
+
notices.push(PAGE_HISTORY_UNAVAILABLE);
|
|
3095
|
+
}
|
|
2736
3096
|
const unavailable = results.find((r) => r.source.historyAvailable === false);
|
|
2737
3097
|
if (unavailable?.source.commitSha !== void 0) {
|
|
2738
3098
|
notices.push(
|
|
@@ -2752,6 +3112,14 @@ async function checkCitations(page, opts) {
|
|
|
2752
3112
|
notices
|
|
2753
3113
|
};
|
|
2754
3114
|
}
|
|
3115
|
+
async function withClaimHistory(now, read) {
|
|
3116
|
+
const { claim } = now;
|
|
3117
|
+
if (claim === null || claim.status !== "changed") return claim;
|
|
3118
|
+
if (read.path === STDIN_LABEL) return claim;
|
|
3119
|
+
const input = { page: now.page, entry: now.entry, claim, ...read };
|
|
3120
|
+
const history = await claimHistory(input);
|
|
3121
|
+
return refineClaim({ ...input, lines: now.lines, history });
|
|
3122
|
+
}
|
|
2755
3123
|
function skippedSource(entry) {
|
|
2756
3124
|
const { source } = entry.citation;
|
|
2757
3125
|
const out = { src: spellSource(source), status: "skipped" };
|
|
@@ -3090,12 +3458,15 @@ async function prepareRun(opts, action, verb, sources = {}) {
|
|
|
3090
3458
|
});
|
|
3091
3459
|
assertNonEmpty({ files, inputs: fileInputs, usingStdin, allowEmpty, exclude, exts, gitignoreSkipped, action });
|
|
3092
3460
|
const git = opts.gitClient ?? gitClient(run3.root);
|
|
3461
|
+
const pageGit = opts.pageGitClient ?? (run3.base === run3.root ? git : gitClient(run3.base));
|
|
3093
3462
|
const pageOptions = {
|
|
3094
3463
|
root: run3.root,
|
|
3095
3464
|
checkSources,
|
|
3096
3465
|
key: run3.key,
|
|
3097
3466
|
severity: config?.severity,
|
|
3098
|
-
gitClient: git
|
|
3467
|
+
gitClient: git,
|
|
3468
|
+
pageRoot: run3.base,
|
|
3469
|
+
pageGitClient: pageGit
|
|
3099
3470
|
};
|
|
3100
3471
|
if (checkSources) pageOptions.sourceIndex = await sourceIndexFor(run3.root, git);
|
|
3101
3472
|
const sidecars2 = await sidecarsFor(run3);
|
|
@@ -3721,6 +4092,12 @@ function settles(plan) {
|
|
|
3721
4092
|
return "marker-misplaced";
|
|
3722
4093
|
case "claim-reanchored":
|
|
3723
4094
|
return "claim-moved";
|
|
4095
|
+
case "claim-words-held":
|
|
4096
|
+
return "claim-reanchored";
|
|
4097
|
+
// A refused claim leaves nothing written, but its finding is the row the
|
|
4098
|
+
// refusal prints, so it is not also reported as skipped.
|
|
4099
|
+
case "claim-replaced":
|
|
4100
|
+
return "claim-changed";
|
|
3724
4101
|
// A shifted entry was `current`, so it had no finding to settle.
|
|
3725
4102
|
case "claim-shifted":
|
|
3726
4103
|
return "";
|
|
@@ -3734,6 +4111,15 @@ function apply(content, format, plan) {
|
|
|
3734
4111
|
return spliceEntryField(content, format, index, ["claim", "lines"], plan.lines);
|
|
3735
4112
|
case "claim-reanchored":
|
|
3736
4113
|
return spliceEntryField(content, format, index, ["claim", "integrity"], plan.pin);
|
|
4114
|
+
case "claim-words-held": {
|
|
4115
|
+
let out = spliceEntryField(content, format, index, ["claim", "integrity"], plan.pin);
|
|
4116
|
+
if (plan.lines !== void 0) {
|
|
4117
|
+
out = spliceEntryField(out, format, index, ["claim", "lines"], plan.lines);
|
|
4118
|
+
}
|
|
4119
|
+
return out;
|
|
4120
|
+
}
|
|
4121
|
+
// Nothing is written for a refused claim; the report is the whole of it.
|
|
4122
|
+
case "claim-replaced":
|
|
3737
4123
|
// The move is a page rewrite, applied to the whole page before any splice.
|
|
3738
4124
|
case "marker-moved":
|
|
3739
4125
|
return content;
|
|
@@ -3782,6 +4168,15 @@ function applyToEntry(entry, plan) {
|
|
|
3782
4168
|
claim.integrity = plan.pin;
|
|
3783
4169
|
return true;
|
|
3784
4170
|
}
|
|
4171
|
+
case "claim-words-held": {
|
|
4172
|
+
const claim = end("claim");
|
|
4173
|
+
if (claim === void 0) return false;
|
|
4174
|
+
claim.integrity = plan.pin;
|
|
4175
|
+
if (plan.lines !== void 0) claim.lines = plan.lines;
|
|
4176
|
+
return true;
|
|
4177
|
+
}
|
|
4178
|
+
// Nothing is written for a refused claim.
|
|
4179
|
+
case "claim-replaced":
|
|
3785
4180
|
// The page holds the marker, so the manifest has nothing to change.
|
|
3786
4181
|
case "marker-moved":
|
|
3787
4182
|
return true;
|
|
@@ -3854,6 +4249,37 @@ function rewriteOf(plan) {
|
|
|
3854
4249
|
newLines: plan.now
|
|
3855
4250
|
};
|
|
3856
4251
|
}
|
|
4252
|
+
case "claim-words-held": {
|
|
4253
|
+
const was = citation.claim?.integrity ?? "";
|
|
4254
|
+
const out = {
|
|
4255
|
+
...base,
|
|
4256
|
+
end: "claim",
|
|
4257
|
+
reason: "re-anchored",
|
|
4258
|
+
status: "reanchored",
|
|
4259
|
+
from: was,
|
|
4260
|
+
to: plan.pin,
|
|
4261
|
+
fromPin: was,
|
|
4262
|
+
toPin: plan.pin,
|
|
4263
|
+
fromLines: plan.fromLines,
|
|
4264
|
+
toLines: plan.toLines,
|
|
4265
|
+
at: plan.at
|
|
4266
|
+
};
|
|
4267
|
+
if (plan.commitSha !== void 0) out.commitSha = plan.commitSha;
|
|
4268
|
+
return out;
|
|
4269
|
+
}
|
|
4270
|
+
case "claim-replaced":
|
|
4271
|
+
return {
|
|
4272
|
+
...base,
|
|
4273
|
+
end: "claim",
|
|
4274
|
+
reason: "replaced",
|
|
4275
|
+
status: "changed",
|
|
4276
|
+
from: plan.pin,
|
|
4277
|
+
to: plan.would,
|
|
4278
|
+
fromPin: plan.pin,
|
|
4279
|
+
toPin: plan.would,
|
|
4280
|
+
at: plan.at,
|
|
4281
|
+
commitSha: plan.commitSha
|
|
4282
|
+
};
|
|
3857
4283
|
case "claim-shifted":
|
|
3858
4284
|
return {
|
|
3859
4285
|
...base,
|
|
@@ -3880,14 +4306,22 @@ function rewriteOf(plan) {
|
|
|
3880
4306
|
...base,
|
|
3881
4307
|
end: "claim",
|
|
3882
4308
|
reason: "accepted",
|
|
3883
|
-
|
|
4309
|
+
// A bypassed guard reads `replaced`, so the log shows that the line
|
|
4310
|
+
// held other text and a named accept took it anyway.
|
|
4311
|
+
status: plan.replaced === true ? "replaced" : "changed",
|
|
3884
4312
|
from: was,
|
|
3885
4313
|
to: plan.pin,
|
|
3886
4314
|
fromPin: was,
|
|
3887
4315
|
toPin: plan.pin,
|
|
3888
4316
|
at: plan.unit.lines.start,
|
|
3889
|
-
text:
|
|
4317
|
+
text: quoted(plan.unit.text)
|
|
3890
4318
|
};
|
|
4319
|
+
const stored = plan.result.claim?.fileLines;
|
|
4320
|
+
const now = spellLines(plan.unit.lines);
|
|
4321
|
+
if (stored !== void 0 && stored !== now) {
|
|
4322
|
+
out.fromLines = stored;
|
|
4323
|
+
out.toLines = now;
|
|
4324
|
+
}
|
|
3891
4325
|
const markerLine = plan.markerLine ?? (plan.result.anchor === "marker" ? plan.result.markerLine : void 0);
|
|
3892
4326
|
if (markerLine !== void 0) out.markerLine = markerLine;
|
|
3893
4327
|
return out;
|
|
@@ -3910,6 +4344,18 @@ function rewriteOf(plan) {
|
|
|
3910
4344
|
}
|
|
3911
4345
|
}
|
|
3912
4346
|
}
|
|
4347
|
+
function replacementAt(claim, text, format) {
|
|
4348
|
+
const was = claim.baselineText;
|
|
4349
|
+
const commit = claim.commitSha;
|
|
4350
|
+
if (was === void 0 || commit === void 0) return void 0;
|
|
4351
|
+
if (sharesSentence(claimWords(was, format), claimWords(text, format))) return void 0;
|
|
4352
|
+
return commit;
|
|
4353
|
+
}
|
|
4354
|
+
var QUOTE_CAP = 200;
|
|
4355
|
+
function quoted(text) {
|
|
4356
|
+
const all = normalizeWhitespace(text.join("\n"));
|
|
4357
|
+
return all.length <= QUOTE_CAP ? all : `${all.slice(0, QUOTE_CAP)}\u2026`;
|
|
4358
|
+
}
|
|
3913
4359
|
function named3(id, text) {
|
|
3914
4360
|
return id === void 0 ? text : `${id}: ${text}`;
|
|
3915
4361
|
}
|
|
@@ -4064,6 +4510,25 @@ async function runUpdate(opts) {
|
|
|
4064
4510
|
});
|
|
4065
4511
|
}
|
|
4066
4512
|
}
|
|
4513
|
+
if (result.anchor !== "marker" && claim !== null && claim.status === "reanchored" && claim.newLines !== void 0) {
|
|
4514
|
+
const at2 = parseLines(claim.newLines);
|
|
4515
|
+
const file = at2 === void 0 ? void 0 : toFileLines(at2, page.bodyLine);
|
|
4516
|
+
const pin = file === void 0 ? void 0 : pinOfLines(lines, file);
|
|
4517
|
+
const to = file === void 0 ? void 0 : { start: lineNow(file.start), end: lineNow(file.end) };
|
|
4518
|
+
if (file !== void 0 && to !== void 0 && pin !== void 0 && to.end - to.start === file.end - file.start) {
|
|
4519
|
+
const plan = {
|
|
4520
|
+
kind: "claim-words-held",
|
|
4521
|
+
result,
|
|
4522
|
+
pin,
|
|
4523
|
+
at: to.start,
|
|
4524
|
+
fromLines: claim.fileLines ?? "",
|
|
4525
|
+
toLines: spellLines(to),
|
|
4526
|
+
lines: lineSpec(toBodyLines(to, page.bodyLine))
|
|
4527
|
+
};
|
|
4528
|
+
if (claim.commitSha !== void 0) plan.commitSha = claim.commitSha;
|
|
4529
|
+
out.push(plan);
|
|
4530
|
+
}
|
|
4531
|
+
}
|
|
4067
4532
|
if (result.source.status === "moved" && result.source.newLines !== void 0) {
|
|
4068
4533
|
const at2 = parseLines(result.source.newLines);
|
|
4069
4534
|
if (at2 !== void 0 && result.source.newSrc !== void 0) {
|
|
@@ -4085,15 +4550,28 @@ async function runUpdate(opts) {
|
|
|
4085
4550
|
why: `Not re-pinned: the ${unit.kind} ${wide}.`
|
|
4086
4551
|
});
|
|
4087
4552
|
} else if (unit !== void 0 && pin !== void 0 && (!wantsBlock || unit.kind === "block")) {
|
|
4088
|
-
const
|
|
4089
|
-
if (
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4553
|
+
const replaced = replacementAt(claim, unit.text, page.format);
|
|
4554
|
+
if (replaced !== void 0 && only === void 0) {
|
|
4555
|
+
out.push({
|
|
4556
|
+
kind: "claim-replaced",
|
|
4557
|
+
result,
|
|
4558
|
+
at: unit.lines.start,
|
|
4559
|
+
commitSha: replaced,
|
|
4560
|
+
pin: entry.citation.claim?.integrity ?? "",
|
|
4561
|
+
would: pin
|
|
4562
|
+
});
|
|
4563
|
+
} else {
|
|
4564
|
+
const plan = { kind: "claim-accepted", result, unit, pin };
|
|
4565
|
+
if (replaced !== void 0) plan.replaced = true;
|
|
4566
|
+
if (entry.citation.claim?.lines !== void 0) {
|
|
4567
|
+
const body = toBodyLines(unit.lines, page.bodyLine);
|
|
4568
|
+
const recorded = parseLines(entry.citation.claim.lines);
|
|
4569
|
+
if (recorded === void 0 || recorded.start !== body.start || recorded.end !== body.end) {
|
|
4570
|
+
plan.lines = lineSpec(body);
|
|
4571
|
+
}
|
|
4094
4572
|
}
|
|
4573
|
+
out.push(plan);
|
|
4095
4574
|
}
|
|
4096
|
-
out.push(plan);
|
|
4097
4575
|
}
|
|
4098
4576
|
}
|
|
4099
4577
|
if (result.source.status === "changed" || result.source.status === "never-true") {
|
|
@@ -4127,6 +4605,7 @@ async function runUpdate(opts) {
|
|
|
4127
4605
|
});
|
|
4128
4606
|
const lines = splitLines(content);
|
|
4129
4607
|
const rewritten2 = [];
|
|
4608
|
+
const refused = [];
|
|
4130
4609
|
const settled = /* @__PURE__ */ new Set();
|
|
4131
4610
|
const declined = /* @__PURE__ */ new Map();
|
|
4132
4611
|
const markers = decideMarkers({ page, report, lines, accept, only });
|
|
@@ -4165,6 +4644,7 @@ async function runUpdate(opts) {
|
|
|
4165
4644
|
const now = anchoredNow(after, format, afterLines, lineNow(marker.line), quote);
|
|
4166
4645
|
const status = result.claim.status;
|
|
4167
4646
|
if (now !== void 0 && now.pin !== recorded) {
|
|
4647
|
+
const unitText2 = afterLines.slice(now.span.start - 1, now.span.end);
|
|
4168
4648
|
if (status === "moved" || status === "current" && move !== void 0) {
|
|
4169
4649
|
plans.push({
|
|
4170
4650
|
kind: "claim-reanchored",
|
|
@@ -4173,6 +4653,17 @@ async function runUpdate(opts) {
|
|
|
4173
4653
|
held: result.claim.fileLines ?? "",
|
|
4174
4654
|
now: spellLines(now.span)
|
|
4175
4655
|
});
|
|
4656
|
+
} else if (status === "reanchored") {
|
|
4657
|
+
const held = {
|
|
4658
|
+
kind: "claim-words-held",
|
|
4659
|
+
result,
|
|
4660
|
+
pin: now.pin,
|
|
4661
|
+
at: now.span.start,
|
|
4662
|
+
fromLines: result.claim.fileLines ?? "",
|
|
4663
|
+
toLines: spellLines(now.span)
|
|
4664
|
+
};
|
|
4665
|
+
if (result.claim.commitSha !== void 0) held.commitSha = result.claim.commitSha;
|
|
4666
|
+
plans.push(held);
|
|
4176
4667
|
} else if (status === "changed" && accept) {
|
|
4177
4668
|
const kind = quote ? "block" : "paragraph";
|
|
4178
4669
|
const wide = tooWide(now.span);
|
|
@@ -4182,17 +4673,24 @@ async function runUpdate(opts) {
|
|
|
4182
4673
|
why: `Not re-pinned: the ${kind} ${wide}.`
|
|
4183
4674
|
});
|
|
4184
4675
|
} else {
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
kind,
|
|
4193
|
-
|
|
4676
|
+
const replaced = replacementAt(result.claim, unitText2, format);
|
|
4677
|
+
plans.push(
|
|
4678
|
+
replaced === void 0 || only !== void 0 ? {
|
|
4679
|
+
kind: "claim-accepted",
|
|
4680
|
+
result,
|
|
4681
|
+
pin: now.pin,
|
|
4682
|
+
markerLine: lineNow(marker.line),
|
|
4683
|
+
unit: { lines: now.span, kind, text: unitText2 },
|
|
4684
|
+
...replaced === void 0 ? {} : { replaced: true }
|
|
4685
|
+
} : {
|
|
4686
|
+
kind: "claim-replaced",
|
|
4687
|
+
result,
|
|
4688
|
+
at: now.span.start,
|
|
4689
|
+
commitSha: replaced,
|
|
4690
|
+
pin: recorded,
|
|
4691
|
+
would: now.pin
|
|
4194
4692
|
}
|
|
4195
|
-
|
|
4693
|
+
);
|
|
4196
4694
|
}
|
|
4197
4695
|
}
|
|
4198
4696
|
}
|
|
@@ -4217,6 +4715,11 @@ async function runUpdate(opts) {
|
|
|
4217
4715
|
}
|
|
4218
4716
|
}
|
|
4219
4717
|
for (const plan of plans) {
|
|
4718
|
+
if (plan.kind === "claim-replaced") {
|
|
4719
|
+
refused.push(rewriteOf(plan));
|
|
4720
|
+
settled.add(`${String(result.origin.index)}\0${settles(plan)}`);
|
|
4721
|
+
continue;
|
|
4722
|
+
}
|
|
4220
4723
|
if (plan.kind === "marker-moved") {
|
|
4221
4724
|
} else if (result.origin.kind === "manifest") {
|
|
4222
4725
|
const held = entries?.[result.origin.index];
|
|
@@ -4273,7 +4776,7 @@ async function runUpdate(opts) {
|
|
|
4273
4776
|
}
|
|
4274
4777
|
writes.record(path, label, content);
|
|
4275
4778
|
}
|
|
4276
|
-
const out = { file: label, rewritten: rewritten2, skipped: skipped2, diff, written };
|
|
4779
|
+
const out = { file: label, rewritten: rewritten2, refused, skipped: skipped2, diff, written };
|
|
4277
4780
|
if (path === void 0) out.content = after;
|
|
4278
4781
|
pages.push(out);
|
|
4279
4782
|
return report;
|
|
@@ -4303,8 +4806,10 @@ async function runUpdate(opts) {
|
|
|
4303
4806
|
);
|
|
4304
4807
|
sayNotices(reports, opts.onNotice, reminted && !await git.available() ? [GIT_UNAVAILABLE_COMMIT] : []);
|
|
4305
4808
|
const rewritten = pages.reduce((n, page) => n + citationsIn(page.rewritten), 0);
|
|
4306
|
-
const skipped = pages.reduce((n, page) => n + page.skipped.length, 0);
|
|
4307
|
-
const undone = pages.some(
|
|
4809
|
+
const skipped = pages.reduce((n, page) => n + page.skipped.length + page.refused.length, 0);
|
|
4810
|
+
const undone = pages.some(
|
|
4811
|
+
(page) => page.refused.length > 0 || page.skipped.some((finding2) => finding2.severity === "error")
|
|
4812
|
+
);
|
|
4308
4813
|
return {
|
|
4309
4814
|
pages,
|
|
4310
4815
|
rewritten,
|
|
@@ -4505,11 +5010,27 @@ function claimColumn(result) {
|
|
|
4505
5010
|
status = `moved, ${plural2(at2.length, "candidate")} (${at2.join(", ")})`;
|
|
4506
5011
|
break;
|
|
4507
5012
|
}
|
|
5013
|
+
case "reanchored": {
|
|
5014
|
+
const since = claim.commitSha === void 0 ? "" : ` since ${shortCommit(claim.commitSha)}`;
|
|
5015
|
+
const to = claim.newFileLines === void 0 ? "" : ` -> :${claim.newFileLines}`;
|
|
5016
|
+
status = `reanchored${since}${to}`;
|
|
5017
|
+
break;
|
|
5018
|
+
}
|
|
5019
|
+
case "changed":
|
|
5020
|
+
status = changedText(claim);
|
|
5021
|
+
break;
|
|
4508
5022
|
default:
|
|
4509
5023
|
status = claim.status;
|
|
4510
5024
|
}
|
|
4511
5025
|
return where === "" ? status : `${where} ${status}`;
|
|
4512
5026
|
}
|
|
5027
|
+
function changedText(claim) {
|
|
5028
|
+
if (claim.historyAvailable === false) return "changed (history unavailable; fetch-depth: 0)";
|
|
5029
|
+
if (claim.commitSha === void 0) return "changed";
|
|
5030
|
+
const since = claim.commitsSince ?? [];
|
|
5031
|
+
const count = since.length === 0 ? "uncommitted" : plural2(since.length, "commit");
|
|
5032
|
+
return `changed since ${shortCommit(claim.commitSha)}, ${count}`;
|
|
5033
|
+
}
|
|
4513
5034
|
function sourceColumn(result, opts, dim) {
|
|
4514
5035
|
const { source } = result;
|
|
4515
5036
|
const src = shortSrc(source.src);
|
|
@@ -4530,10 +5051,19 @@ function diffLines(result, dim) {
|
|
|
4530
5051
|
return out;
|
|
4531
5052
|
}
|
|
4532
5053
|
function claimLines(result, dim) {
|
|
4533
|
-
const
|
|
4534
|
-
const
|
|
5054
|
+
const claim = result.claim;
|
|
5055
|
+
const diff = claim?.diff;
|
|
5056
|
+
if (claim === null || diff === void 0 || diff === "") {
|
|
5057
|
+
return capped(claim?.text ?? [], dim);
|
|
5058
|
+
}
|
|
5059
|
+
const out = [];
|
|
5060
|
+
for (const subject of claim.commitsSince ?? []) out.push(dim(` ${subject}`));
|
|
5061
|
+
return [...out, ...capped(diff.split(/\r?\n/), dim)];
|
|
5062
|
+
}
|
|
5063
|
+
function capped(lines, dim) {
|
|
5064
|
+
const shown = lines.slice(0, DIFF_LINE_CAP);
|
|
4535
5065
|
const out = shown.map((line) => dim(` ${line}`));
|
|
4536
|
-
const more =
|
|
5066
|
+
const more = lines.length - shown.length;
|
|
4537
5067
|
if (more > 0) out.push(dim(` \u2026 (${plural2(more, "more line")})`));
|
|
4538
5068
|
return out;
|
|
4539
5069
|
}
|
|
@@ -4598,7 +5128,9 @@ function renderCheckPretty(run3, opts) {
|
|
|
4598
5128
|
}
|
|
4599
5129
|
if (opts.showDiff) {
|
|
4600
5130
|
if (own.some((f) => f.rule === "source-changed")) under.push(...diffLines(result, c.dim));
|
|
4601
|
-
if (own.some((f) => f.rule === "claim-changed"
|
|
5131
|
+
if (own.some((f) => f.rule === "claim-changed" || f.rule === "claim-reanchored")) {
|
|
5132
|
+
under.push(...claimLines(result, c.dim));
|
|
5133
|
+
}
|
|
4602
5134
|
}
|
|
4603
5135
|
const forgivenEnd = own.length > 0 && live.length === 0 ? c.dim(" (baselined)") : "";
|
|
4604
5136
|
rows.push({
|
|
@@ -4672,6 +5204,18 @@ function widening(held, now) {
|
|
|
4672
5204
|
if (parts.length === 0) return ", which held a marker line";
|
|
4673
5205
|
return `, ${parts.join(" and ")} newly pinned`;
|
|
4674
5206
|
}
|
|
5207
|
+
function widened(rewrite) {
|
|
5208
|
+
return rewrite.fromLines !== void 0 && rewrite.toLines !== void 0 && rewrite.fromLines !== rewrite.toLines;
|
|
5209
|
+
}
|
|
5210
|
+
function movedSpan(rewrite) {
|
|
5211
|
+
if (widened(rewrite)) return `lines ${rewrite.fromLines ?? ""} -> ${rewrite.toLines ?? ""}`;
|
|
5212
|
+
const at2 = rewrite.toLines ?? rewrite.fromLines ?? String(rewrite.at ?? 0);
|
|
5213
|
+
return `at ${spellAtSpec(at2)}`;
|
|
5214
|
+
}
|
|
5215
|
+
function refusalLine(rewrite) {
|
|
5216
|
+
const at2 = shortCommit(rewrite.commitSha ?? "");
|
|
5217
|
+
return `claim at ${spellAtSpec(String(rewrite.at ?? 0))} skipped: that line now holds different text than the claim at ${at2}. Re-add it with cite add.`;
|
|
5218
|
+
}
|
|
4675
5219
|
function rewriteLine(rewrite) {
|
|
4676
5220
|
const word = rewrite.from.includes("-") ? "lines" : "line";
|
|
4677
5221
|
const status = rewrite.status === "never-true" ? "never true" : rewrite.status;
|
|
@@ -4681,6 +5225,10 @@ function rewriteLine(rewrite) {
|
|
|
4681
5225
|
if (rewrite.reason === "shifted") {
|
|
4682
5226
|
return `claim ${word} ${rewrite.from} -> ${rewrite.to} (shifted by a marker)`;
|
|
4683
5227
|
}
|
|
5228
|
+
if (rewrite.reason === "re-anchored" && rewrite.status === "reanchored") {
|
|
5229
|
+
const since = rewrite.commitSha === void 0 ? "" : ` since ${shortCommit(rewrite.commitSha)}`;
|
|
5230
|
+
return `claim ${movedSpan(rewrite)} re-pinned (reanchored; words unchanged${since})`;
|
|
5231
|
+
}
|
|
4684
5232
|
if (rewrite.reason === "re-anchored") {
|
|
4685
5233
|
const held = rewrite.lines ?? "";
|
|
4686
5234
|
const now = rewrite.newLines ?? "";
|
|
@@ -4690,6 +5238,9 @@ function rewriteLine(rewrite) {
|
|
|
4690
5238
|
return rewrite.end === "claim" ? `claim ${word} ${rewrite.from} -> ${rewrite.to} (moved)` : `source ${shortSrc(rewrite.from)} -> ${shortSrc(rewrite.to)} (moved)`;
|
|
4691
5239
|
}
|
|
4692
5240
|
if (rewrite.end === "claim") {
|
|
5241
|
+
if (widened(rewrite)) {
|
|
5242
|
+
return `claim ${movedSpan(rewrite)} re-pinned (${status}; now "${rewrite.text ?? ""}")`;
|
|
5243
|
+
}
|
|
4693
5244
|
const where = rewrite.markerLine === void 0 ? `line ${String(rewrite.at ?? 0)}` : `marker line ${String(rewrite.markerLine)}`;
|
|
4694
5245
|
return `claim at ${where} re-pinned (${status}; now "${rewrite.text ?? ""}")`;
|
|
4695
5246
|
}
|
|
@@ -4711,6 +5262,10 @@ function renderUpdatePretty(run3, opts) {
|
|
|
4711
5262
|
const label = rewrite.id ?? `#${String(rewrite.index)}`;
|
|
4712
5263
|
lines.push(`${page.file}: ${c.cyan(label)} ${rewriteLine(rewrite)}`);
|
|
4713
5264
|
}
|
|
5265
|
+
for (const rewrite of page.refused) {
|
|
5266
|
+
const label = rewrite.id ?? `#${String(rewrite.index)}`;
|
|
5267
|
+
lines.push(`${page.file}: ${c.cyan(label)} ${refusalLine(rewrite)}`);
|
|
5268
|
+
}
|
|
4714
5269
|
for (const finding2 of page.skipped) {
|
|
4715
5270
|
const mark = severityMark(finding2.severity, c);
|
|
4716
5271
|
lines.push(
|
|
@@ -4799,6 +5354,10 @@ function publicCitation(result) {
|
|
|
4799
5354
|
if (result.claim.fileLines !== void 0) claim.fileLines = result.claim.fileLines;
|
|
4800
5355
|
if (result.claim.newLines !== void 0) claim.newLines = result.claim.newLines;
|
|
4801
5356
|
if (result.claim.candidates !== void 0) claim.candidates = result.claim.candidates;
|
|
5357
|
+
if (result.claim.commitSha !== void 0) claim.commitSha = result.claim.commitSha;
|
|
5358
|
+
if (result.claim.historyAvailable !== void 0) {
|
|
5359
|
+
claim.historyAvailable = result.claim.historyAvailable;
|
|
5360
|
+
}
|
|
4802
5361
|
}
|
|
4803
5362
|
return {
|
|
4804
5363
|
...result.citation.id === void 0 ? {} : { id: result.citation.id },
|
|
@@ -4819,9 +5378,11 @@ function renderRemoveJson(run3) {
|
|
|
4819
5378
|
return JSON.stringify(run3, null, 2);
|
|
4820
5379
|
}
|
|
4821
5380
|
function renderUpdateJson(run3) {
|
|
5381
|
+
const strip = (rows) => rows.map(({ markerLine: _pretty, ...rewrite }) => rewrite);
|
|
4822
5382
|
const pages = run3.pages.map((page) => ({
|
|
4823
5383
|
...page,
|
|
4824
|
-
rewritten: page.rewritten
|
|
5384
|
+
rewritten: strip(page.rewritten),
|
|
5385
|
+
refused: strip(page.refused)
|
|
4825
5386
|
}));
|
|
4826
5387
|
return JSON.stringify({ ...run3, pages }, null, 2);
|
|
4827
5388
|
}
|
|
@@ -5315,4 +5876,4 @@ export {
|
|
|
5315
5876
|
runKeyRotate,
|
|
5316
5877
|
runKeySet
|
|
5317
5878
|
};
|
|
5318
|
-
//# sourceMappingURL=chunk-
|
|
5879
|
+
//# sourceMappingURL=chunk-TQUTQD7J.js.map
|