@hawkeyexl/manni 4.5.0 → 4.7.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/batch-U6S2JUUN.js +41 -0
- package/dist/build-4RN6WBCP.js +32 -0
- package/dist/calibrate-6VIZYR4L.js +36 -0
- package/dist/capture-DP3NXAZE.js +34 -0
- package/dist/{check-RQIIIURI.js → check-ERVNGKLC.js} +13 -14
- package/dist/check-IWHUPAZM.js +886 -0
- package/dist/check-IWHUPAZM.js.map +1 -0
- package/dist/{check-ESNS7ZBC.js → check-OAJWC3WD.js} +7 -5
- package/dist/check-STHXZIZO.js +26 -0
- package/dist/{chunk-TA42STP7.js → chunk-2ZWTSRE5.js} +4 -4
- package/dist/{chunk-F2OVHJNC.js → chunk-4Z2MN5FR.js} +11 -11
- package/dist/{chunk-HVFR66GQ.js → chunk-5UB47BEV.js} +3280 -283
- package/dist/chunk-5UB47BEV.js.map +1 -0
- package/dist/{chunk-TCC737IS.js → chunk-5VWDIWOH.js} +4 -4
- package/dist/{chunk-B7XUEQF3.js → chunk-6KKZXB2O.js} +7 -5
- package/dist/{chunk-B7XUEQF3.js.map → chunk-6KKZXB2O.js.map} +1 -1
- package/dist/{chunk-ELZ2IIOF.js → chunk-6URSCTTX.js} +2 -2
- package/dist/{chunk-K3U5F2QT.js → chunk-6VDBP5UV.js} +12 -12
- package/dist/chunk-7EL5LLKD.js +233 -0
- package/dist/chunk-7EL5LLKD.js.map +1 -0
- package/dist/{chunk-C3KI45RF.js → chunk-7XZ6INKO.js} +4 -4
- package/dist/{chunk-ZX43SRZR.js → chunk-AMEILOVV.js} +8 -6
- package/dist/{chunk-ZX43SRZR.js.map → chunk-AMEILOVV.js.map} +1 -1
- package/dist/{chunk-SNEHX4VE.js → chunk-B5CMM57M.js} +2 -2
- package/dist/chunk-BWCWTHYS.js +146 -0
- package/dist/chunk-BWCWTHYS.js.map +1 -0
- package/dist/{chunk-QLUMKWQQ.js → chunk-C2TJG5KV.js} +10 -6
- package/dist/{chunk-QLUMKWQQ.js.map → chunk-C2TJG5KV.js.map} +1 -1
- package/dist/{chunk-GAZFKZHM.js → chunk-CEVU3GFF.js} +6 -6
- package/dist/chunk-CI55ABCK.js +502 -0
- package/dist/chunk-CI55ABCK.js.map +1 -0
- package/dist/{chunk-QCBICNKC.js → chunk-CR3HZERW.js} +202 -54
- package/dist/chunk-CR3HZERW.js.map +1 -0
- package/dist/chunk-CU57HT2E.js +116 -0
- package/dist/chunk-CU57HT2E.js.map +1 -0
- package/dist/chunk-CWXZ2MRT.js +222 -0
- package/dist/chunk-CWXZ2MRT.js.map +1 -0
- package/dist/chunk-D2LBN44V.js +134 -0
- package/dist/chunk-D2LBN44V.js.map +1 -0
- package/dist/chunk-D6RO54QD.js +674 -0
- package/dist/chunk-D6RO54QD.js.map +1 -0
- package/dist/{chunk-52PDIZKV.js → chunk-ECVQNGTH.js} +3 -3
- package/dist/chunk-FQGLRJGX.js +174 -0
- package/dist/chunk-FQGLRJGX.js.map +1 -0
- package/dist/{chunk-NGK3N6F2.js → chunk-GCC52YZD.js} +3 -3
- package/dist/chunk-HX44GB4Z.js +30 -0
- package/dist/chunk-HX44GB4Z.js.map +1 -0
- package/dist/{chunk-NN4ASVTY.js → chunk-IIFADWWI.js} +4 -4
- package/dist/{chunk-OIZ3XMKB.js → chunk-IOL74S4J.js} +4 -4
- package/dist/{chunk-UK2I3ACY.js → chunk-IZBBXKMJ.js} +4 -4
- package/dist/{chunk-YA63PVWI.js → chunk-K52CS4KT.js} +12 -10
- package/dist/{chunk-YA63PVWI.js.map → chunk-K52CS4KT.js.map} +1 -1
- package/dist/{chunk-7OQAU4EA.js → chunk-LDKIIZDW.js} +16 -12
- package/dist/{chunk-7OQAU4EA.js.map → chunk-LDKIIZDW.js.map} +1 -1
- package/dist/{chunk-QY3DOZMS.js → chunk-LONRQBGV.js} +4 -4
- package/dist/{chunk-EL2BZTDL.js → chunk-LXJEAV2V.js} +13 -11
- package/dist/{chunk-EL2BZTDL.js.map → chunk-LXJEAV2V.js.map} +1 -1
- package/dist/{chunk-XWFNO5PO.js → chunk-MIBWI5H7.js} +3 -3
- package/dist/{chunk-527HHQPS.js → chunk-MSMB6XOS.js} +6 -4
- package/dist/{chunk-527HHQPS.js.map → chunk-MSMB6XOS.js.map} +1 -1
- package/dist/{chunk-C6HZ6C5T.js → chunk-NIFEEIGQ.js} +2 -2
- package/dist/{chunk-JQU7FHYH.js → chunk-NZ6TNSCU.js} +10 -10
- package/dist/{chunk-3R5Y3XOL.js → chunk-OOEMKOX6.js} +29 -591
- package/dist/chunk-OOEMKOX6.js.map +1 -0
- package/dist/{chunk-MZC62HPZ.js → chunk-PAOVVHQX.js} +2 -2
- package/dist/chunk-PNX43DYW.js +849 -0
- package/dist/chunk-PNX43DYW.js.map +1 -0
- package/dist/chunk-QCHVR4ZM.js +286 -0
- package/dist/chunk-QCHVR4ZM.js.map +1 -0
- package/dist/{chunk-SJO2FTPG.js → chunk-QP5X66TO.js} +73 -1304
- package/dist/chunk-QP5X66TO.js.map +1 -0
- package/dist/{chunk-HQFVJDEN.js → chunk-QQNPVW3J.js} +19 -19
- package/dist/chunk-TPVOOTMN.js +532 -0
- package/dist/chunk-TPVOOTMN.js.map +1 -0
- package/dist/{chunk-IA7BMIPE.js → chunk-UZKQSWHJ.js} +2 -2
- package/dist/chunk-WQWKYAAK.js +86 -0
- package/dist/chunk-WQWKYAAK.js.map +1 -0
- package/dist/{chunk-CP4ZM43V.js → chunk-WTEILBKC.js} +2 -2
- package/dist/{chunk-LJ2RDH3F.js → chunk-XG6PVB5S.js} +1 -23
- package/dist/chunk-XG6PVB5S.js.map +1 -0
- package/dist/{chunk-Q35YIDBV.js → chunk-XKBEHKWO.js} +29 -264
- package/dist/chunk-XKBEHKWO.js.map +1 -0
- package/dist/{chunk-BOIF2XGG.js → chunk-XXDXIIQ4.js} +2 -2
- package/dist/{chunk-6XTQDFGP.js → chunk-YSCZL4U5.js} +3 -3
- package/dist/{chunk-6XTQDFGP.js.map → chunk-YSCZL4U5.js.map} +1 -1
- package/dist/{chunk-7ZUCEMCY.js → chunk-ZEXGGGLW.js} +9 -11
- package/dist/{chunk-7ZUCEMCY.js.map → chunk-ZEXGGGLW.js.map} +1 -1
- package/dist/{chunk-DX32P2DT.js → chunk-ZKAKA54B.js} +2 -2
- package/dist/{chunk-TVIX653Q.js → chunk-ZKCNPKUO.js} +4 -4
- package/dist/{chunk-DE7JSWXV.js → chunk-ZNE25EAR.js} +8 -6
- package/dist/{chunk-DE7JSWXV.js.map → chunk-ZNE25EAR.js.map} +1 -1
- package/dist/{chunk-FLF6AECQ.js → chunk-ZPP75QWG.js} +17 -15
- package/dist/{chunk-FLF6AECQ.js.map → chunk-ZPP75QWG.js.map} +1 -1
- package/dist/{cli-PRZHQ3QB.js → cli-37SRAYNE.js} +14 -15
- package/dist/{cli-PRZHQ3QB.js.map → cli-37SRAYNE.js.map} +1 -1
- package/dist/{cli-TYGOHJOJ.js → cli-HXWYUKGJ.js} +225 -58
- package/dist/cli-HXWYUKGJ.js.map +1 -0
- package/dist/{cli-HUIMNJT6.js → cli-IRHPPUFJ.js} +19 -20
- package/dist/{cli-HUIMNJT6.js.map → cli-IRHPPUFJ.js.map} +1 -1
- package/dist/{cli-6PGVHP7Y.js → cli-KIID535Y.js} +17 -19
- package/dist/{cli-6PGVHP7Y.js.map → cli-KIID535Y.js.map} +1 -1
- package/dist/{cli-AAG3N4NB.js → cli-MTDGQIIV.js} +17 -18
- package/dist/{cli-AAG3N4NB.js.map → cli-MTDGQIIV.js.map} +1 -1
- package/dist/{cli-E3H6ZP4I.js → cli-NM6FZ54R.js} +5 -3
- package/dist/{cli-E3H6ZP4I.js.map → cli-NM6FZ54R.js.map} +1 -1
- package/dist/{cli-MHTYPVOD.js → cli-XIODOEUG.js} +113 -20
- package/dist/{cli-MHTYPVOD.js.map → cli-XIODOEUG.js.map} +1 -1
- package/dist/{cli-YW6VWBHX.js → cli-YL3IDR52.js} +10 -10
- package/dist/{cli-QKIJOXGW.js → cli-ZQUJYQBA.js} +17 -17
- package/dist/cli.js +11 -11
- package/dist/config-O6UBGEDK.js +26 -0
- package/dist/conformance-ALLPNGEQ.js +18 -0
- package/dist/docmeta.js +9 -9
- package/dist/github-UCYLM3DR.js +26 -0
- package/dist/github-VEJFO6JJ.js +31 -0
- package/dist/host-6GURH5HE.js +23 -0
- package/dist/index.d.ts +72 -4
- package/dist/index.js +176 -166
- package/dist/index.js.map +1 -1
- package/dist/{json-4DCKDGUV.js → json-6F52FSXZ.js} +12 -13
- package/dist/lint-X2GNINK6.js +29 -0
- package/dist/list-DP3O3CWB.js +30 -0
- package/dist/list-P77RZFZF.js +28 -0
- package/dist/{page-QEDB7EVU.js → page-WQCMBNRD.js} +11 -12
- package/dist/prepare-52QOK7M4.js +155 -0
- package/dist/prepare-52QOK7M4.js.map +1 -0
- package/dist/{pretty-SQX33UM2.js → pretty-5MMMNSWF.js} +13 -14
- package/dist/{pretty-5DGEBZSV.js → pretty-H4DQREMW.js} +12 -13
- package/dist/provider-AMGRDY6V.js +34 -0
- package/dist/release-CTYRHZL4.js +36 -0
- package/dist/release-CTYRHZL4.js.map +1 -0
- package/dist/{reporters-YELDDYJD.js → reporters-SU3VUKKX.js} +7 -5
- package/dist/{reporters-OHSI3RMV.js → reporters-WIHBEMPG.js} +11 -12
- package/dist/reporters-WIHBEMPG.js.map +1 -0
- package/dist/run-L2DWJ26K.js +32 -0
- package/dist/run-L2DWJ26K.js.map +1 -0
- package/dist/{term-2WMDZ4PY.js → term-PJIJQZNF.js} +16 -17
- package/dist/{term-2WMDZ4PY.js.map → term-PJIJQZNF.js.map} +1 -1
- package/dist/validate-XCDSPURG.js +17 -0
- package/dist/validate-XCDSPURG.js.map +1 -0
- package/package.json +2 -2
- package/plugin/manni/.claude-plugin/plugin.json +1 -1
- package/plugin/manni/hooks/hooks.json +47 -0
- package/dist/batch-GOE3UXOD.js +0 -36
- package/dist/build-M7BMEHL2.js +0 -33
- package/dist/calibrate-6RRAILUY.js +0 -31
- package/dist/capture-RJPQ6B4N.js +0 -32
- package/dist/check-BQD64X3N.js +0 -27
- package/dist/chunk-3R5Y3XOL.js.map +0 -1
- package/dist/chunk-3YHAYXBC.js +0 -164
- package/dist/chunk-3YHAYXBC.js.map +0 -1
- package/dist/chunk-HVFR66GQ.js.map +0 -1
- package/dist/chunk-LJ2RDH3F.js.map +0 -1
- package/dist/chunk-NAZRLJAK.js +0 -3090
- package/dist/chunk-NAZRLJAK.js.map +0 -1
- package/dist/chunk-Q35YIDBV.js.map +0 -1
- package/dist/chunk-QCBICNKC.js.map +0 -1
- package/dist/chunk-SJO2FTPG.js.map +0 -1
- package/dist/chunk-TU2WUBVZ.js +0 -2
- package/dist/cli-TYGOHJOJ.js.map +0 -1
- package/dist/github-3WMSTNTK.js +0 -32
- package/dist/github-OXSJQ4PS.js +0 -27
- package/dist/lint-YDHVVZHT.js +0 -30
- package/dist/list-3ZO2NIYO.js +0 -31
- package/dist/list-EJH6VAOW.js +0 -29
- package/dist/run-IP6NZHAG.js +0 -33
- package/dist/validate-G6HH3YXL.js +0 -16
- /package/dist/{batch-GOE3UXOD.js.map → batch-U6S2JUUN.js.map} +0 -0
- /package/dist/{build-M7BMEHL2.js.map → build-4RN6WBCP.js.map} +0 -0
- /package/dist/{calibrate-6RRAILUY.js.map → calibrate-6VIZYR4L.js.map} +0 -0
- /package/dist/{capture-RJPQ6B4N.js.map → capture-DP3NXAZE.js.map} +0 -0
- /package/dist/{check-BQD64X3N.js.map → check-ERVNGKLC.js.map} +0 -0
- /package/dist/{check-ESNS7ZBC.js.map → check-OAJWC3WD.js.map} +0 -0
- /package/dist/{check-RQIIIURI.js.map → check-STHXZIZO.js.map} +0 -0
- /package/dist/{chunk-TA42STP7.js.map → chunk-2ZWTSRE5.js.map} +0 -0
- /package/dist/{chunk-F2OVHJNC.js.map → chunk-4Z2MN5FR.js.map} +0 -0
- /package/dist/{chunk-TCC737IS.js.map → chunk-5VWDIWOH.js.map} +0 -0
- /package/dist/{chunk-ELZ2IIOF.js.map → chunk-6URSCTTX.js.map} +0 -0
- /package/dist/{chunk-K3U5F2QT.js.map → chunk-6VDBP5UV.js.map} +0 -0
- /package/dist/{chunk-C3KI45RF.js.map → chunk-7XZ6INKO.js.map} +0 -0
- /package/dist/{chunk-SNEHX4VE.js.map → chunk-B5CMM57M.js.map} +0 -0
- /package/dist/{chunk-GAZFKZHM.js.map → chunk-CEVU3GFF.js.map} +0 -0
- /package/dist/{chunk-52PDIZKV.js.map → chunk-ECVQNGTH.js.map} +0 -0
- /package/dist/{chunk-NGK3N6F2.js.map → chunk-GCC52YZD.js.map} +0 -0
- /package/dist/{chunk-NN4ASVTY.js.map → chunk-IIFADWWI.js.map} +0 -0
- /package/dist/{chunk-OIZ3XMKB.js.map → chunk-IOL74S4J.js.map} +0 -0
- /package/dist/{chunk-UK2I3ACY.js.map → chunk-IZBBXKMJ.js.map} +0 -0
- /package/dist/{chunk-QY3DOZMS.js.map → chunk-LONRQBGV.js.map} +0 -0
- /package/dist/{chunk-XWFNO5PO.js.map → chunk-MIBWI5H7.js.map} +0 -0
- /package/dist/{chunk-C6HZ6C5T.js.map → chunk-NIFEEIGQ.js.map} +0 -0
- /package/dist/{chunk-JQU7FHYH.js.map → chunk-NZ6TNSCU.js.map} +0 -0
- /package/dist/{chunk-MZC62HPZ.js.map → chunk-PAOVVHQX.js.map} +0 -0
- /package/dist/{chunk-HQFVJDEN.js.map → chunk-QQNPVW3J.js.map} +0 -0
- /package/dist/{chunk-IA7BMIPE.js.map → chunk-UZKQSWHJ.js.map} +0 -0
- /package/dist/{chunk-CP4ZM43V.js.map → chunk-WTEILBKC.js.map} +0 -0
- /package/dist/{chunk-BOIF2XGG.js.map → chunk-XXDXIIQ4.js.map} +0 -0
- /package/dist/{chunk-DX32P2DT.js.map → chunk-ZKAKA54B.js.map} +0 -0
- /package/dist/{chunk-TVIX653Q.js.map → chunk-ZKCNPKUO.js.map} +0 -0
- /package/dist/{chunk-TU2WUBVZ.js.map → cli-YL3IDR52.js.map} +0 -0
- /package/dist/{cli-QKIJOXGW.js.map → cli-ZQUJYQBA.js.map} +0 -0
- /package/dist/{cli-YW6VWBHX.js.map → config-O6UBGEDK.js.map} +0 -0
- /package/dist/{github-3WMSTNTK.js.map → conformance-ALLPNGEQ.js.map} +0 -0
- /package/dist/{github-OXSJQ4PS.js.map → github-UCYLM3DR.js.map} +0 -0
- /package/dist/{json-4DCKDGUV.js.map → github-VEJFO6JJ.js.map} +0 -0
- /package/dist/{lint-YDHVVZHT.js.map → host-6GURH5HE.js.map} +0 -0
- /package/dist/{list-3ZO2NIYO.js.map → json-6F52FSXZ.js.map} +0 -0
- /package/dist/{list-EJH6VAOW.js.map → lint-X2GNINK6.js.map} +0 -0
- /package/dist/{page-QEDB7EVU.js.map → list-DP3O3CWB.js.map} +0 -0
- /package/dist/{pretty-5DGEBZSV.js.map → list-P77RZFZF.js.map} +0 -0
- /package/dist/{pretty-SQX33UM2.js.map → page-WQCMBNRD.js.map} +0 -0
- /package/dist/{reporters-OHSI3RMV.js.map → pretty-5MMMNSWF.js.map} +0 -0
- /package/dist/{reporters-YELDDYJD.js.map → pretty-H4DQREMW.js.map} +0 -0
- /package/dist/{run-IP6NZHAG.js.map → provider-AMGRDY6V.js.map} +0 -0
- /package/dist/{validate-G6HH3YXL.js.map → reporters-SU3VUKKX.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cite/commands/add.ts","../src/cite/core/mint.ts","../src/cite/core/shift.ts","../src/cite/core/manifest.ts","../src/cite/core/write.ts","../src/cite/commands/remove.ts","../src/cite/commands/update.ts"],"sourcesContent":["/**\n * `manni cite add`: mint one citation and write it to a page.\n *\n * The page lines are the claim: `add docs/limits.md:9 lib/limits.ts:2` pins\n * line 9 of the page to line 2 of the source. Lines reach the command as an\n * editor numbers them and are stored body-relative, so editing the\n * frontmatter never moves them. `--marker` writes a `cite <id>` comment above\n * those lines instead, and pins the text it anchors; `--quote` says the lines\n * are a fenced block that reproduces the source. No lines at all is a bare\n * pin: this page rests on these lines, say so when they change.\n *\n * Every refusal is a `CiteError` (exit 2) with the page and the source\n * spelled as the caller spelled them, and nothing is written. Among them are\n * the pins the command can already see are wrong: a duplicate of an entry the\n * page has, and a claim whose lines hold no text at all.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { relative, resolve } from \"node:path\";\nimport { locateFrontmatter, writeFileAtomic } from \"../../meta/index.js\";\nimport { STDIN_LABEL, STDIN_TOKEN } from \"../../meta/internal.js\";\nimport { ensureEncryptionKey } from \"../../shared/prompt.js\";\nimport { isEncryptedValue } from \"../../shared/encryption.js\";\nimport {\n blockMatches,\n otherClaimSpans,\n pinOfLines,\n spellElsewhere,\n toBodyLines,\n toFileLines,\n} from \"../core/claims.js\";\nimport { resolveCiteRun } from \"../core/config.js\";\nimport { GIT_UNAVAILABLE_COMMIT, gitClient } from \"../core/git.js\";\nimport { sliceLines, splitLines } from \"../core/hash.js\";\nimport { mintCitation } from \"../core/mint.js\";\nimport { bodyLineOf, readPage } from \"../core/page.js\";\nimport {\n formatSrc,\n lineSpec,\n parseLines,\n parseSrc,\n spellLines,\n spellSource,\n tooWide,\n} from \"../core/range.js\";\nimport { misplacedMarkers } from \"../core/reanchor.js\";\nimport { shiftedEntries, withClaimLines, type Shifted } from \"../core/shift.js\";\nimport { readSource, sourceIndexFor } from \"../core/sources.js\";\nimport { shortSrc, spellAt } from \"../core/spell.js\";\nimport { ManifestSet } from \"../core/manifest.js\";\nimport { sidecarsFor, type PageSidecar } from \"../core/sidecar.js\";\nimport {\n ANY_FENCE,\n MAX_IDS_PER_MARKER,\n anchoredLines,\n fenceSpanAt,\n formatStatement,\n isMarkerLine,\n markerIndent,\n offsetOfLine,\n respellStatement,\n unitHolding,\n} from \"../core/statements.js\";\nimport {\n appendFrontmatterCitation,\n entryObject,\n insertStatementBefore,\n spliceEntryField,\n unifiedDiff,\n} from \"../core/write.js\";\nimport { CiteError } from \"../errors.js\";\nimport type {\n AddOptions,\n AddResult,\n Citation,\n CitationClaim,\n PageCitation,\n PageCitations,\n PageLines,\n SourceIndex,\n} from \"../types.js\";\nimport { STDIN_REQUIRES_AS } from \"../../shared/cli-options.js\";\n\n/** The schema's id grammar, checked before anything is written. */\nconst ID = /^[a-z0-9][a-z0-9-]*$/;\n\nconst toPosix = (path: string): string => path.replace(/\\\\/g, \"/\");\n\nfunction isEnoent(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\";\n}\n\nasync function readPageFile(path: string, label: string): Promise<string> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if (isEnoent(error)) throw new CiteError(`File not found: \"${label}\".`);\n throw error;\n }\n}\n\n/** The cited lines, joined as the hashing rule joins them. */\nasync function citedText(\n root: string,\n index: SourceIndex,\n src: string,\n key: string | undefined,\n): Promise<string> {\n const range = parseSrc(src);\n const source = await readSource(root, index, range, key);\n // Minting already read this range, so a miss here is a race with the disk.\n if (source.kind === \"missing\") {\n throw new CiteError(`Source not readable: ${range.path} could not be read.`);\n }\n return sliceLines(splitLines(source.text), range, range.path);\n}\n\n/** How a refusal names an entry: its id, or the pointer a report would use. */\nfunction entryName(entry: PageCitation): string {\n return entry.citation.id ?? `/citations/${String(entry.origin.index)}`;\n}\n\n/**\n * The entry that already pins these very page lines to this very source, in\n * the frontmatter or in the manifest that owns the page's citations. A bare\n * pin matches another bare pin over the same source.\n *\n * The source is compared as each end spells it, so an encrypted one compares\n * as its ciphertext and no path is decrypted to say so. A marker add is not\n * asked: it stores no claim lines, and its own id and anchor checks cover it.\n */\nfunction duplicateOf(\n page: PageCitations,\n src: string,\n pageLines: PageLines | undefined,\n): PageCitation | undefined {\n // opts.src is the caller's plain-path spelling; an existing entry encrypted\n // under a key compares as its ciphertext and will never match here.\n const wanted = formatSrc(parseSrc(src));\n return page.citations.find((entry) => {\n const { citation } = entry;\n if (spellSource(citation.source) !== wanted) return false;\n if (pageLines === undefined) return citation.claim === undefined;\n const spec = citation.claim?.lines;\n if (spec === undefined) return false;\n const recorded = parseLines(spec);\n if (recorded === undefined) return false;\n const file = toFileLines(recorded, page.bodyLine);\n return file.start === pageLines.start && file.end === pageLines.end;\n });\n}\n\n/** Whether a page line can hold no claim at all: it is blank, or it is a fence. */\nfunction holdsNoText(text: string): boolean {\n return text.trim() === \"\" || ANY_FENCE.test(text);\n}\n\n/**\n * The refusal for a claim whose lines hold no text, `at` being the page and\n * the lines as the caller spelled them. Undefined when at least one line\n * carries text. `--quote` never asks, because a quote is fences and content\n * by design.\n */\nfunction emptyClaimRefusal(\n lines: readonly string[],\n pageLines: PageLines,\n at: string,\n): string | undefined {\n const span = lines.slice(pageLines.start - 1, pageLines.end);\n if (span.some((text) => !holdsNoText(text))) return undefined;\n if (pageLines.start !== pageLines.end) return `${at} holds no claim text.`;\n const only = span[0] ?? \"\";\n return only.trim() === \"\" ? `${at} is blank.` : `${at} is a fence line, not claim text.`;\n}\n\nexport async function runAdd(opts: AddOptions): Promise<AddResult> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const run = await resolveCiteRun({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: [],\n root: opts.root,\n onConfigLoaded: opts.onConfigLoaded,\n onNotice: opts.onNotice,\n env: opts.env,\n });\n const { root } = run;\n\n const usingStdin = opts.page === STDIN_TOKEN;\n if (usingStdin && opts.as === undefined) {\n throw new CiteError(STDIN_REQUIRES_AS);\n }\n // `-` names no file: nothing to resolve, and nothing to write back to.\n const path = usingStdin ? undefined : resolve(cwd, opts.page);\n const label = path === undefined ? STDIN_LABEL : toPosix(relative(cwd, path));\n const content = path === undefined ? (opts.stdinContent ?? \"\") : await readPageFile(path, label);\n\n // The manifests that own `citations`, if any collection declares one. The\n // page is labelled from the working directory here, so membership is\n // measured from there too.\n const sidecars = await sidecarsFor(run, {\n base: cwd,\n // A `{page}` manifest (0058) is read for the one page being cited.\n ...(path === undefined ? {} : { pages: [path] }),\n });\n const firstManifest = sidecars?.manifests[0];\n if (usingStdin && firstManifest !== undefined) {\n const keyedBy = firstManifest.join === \"path\" ? \"path\" : firstManifest.join;\n throw new CiteError(\n `A page read from stdin has no path, and its citations live in ${firstManifest.file}, which is keyed by ${keyedBy}.`,\n );\n }\n const sidecar: PageSidecar | undefined = usingStdin\n ? undefined\n : await sidecars?.forPage(label, content, opts.as);\n const owner = sidecar?.owner;\n\n const page = readPage(label, content, {\n ...(opts.as === undefined ? {} : { format: opts.as }),\n // The entries already there are the manifest's, so `--id` uniqueness and\n // the marker checks are measured against them and not against a page\n // that carries none.\n ...(sidecar?.citations === undefined ? {} : { citations: sidecar.citations }),\n ...(owner === undefined ? {} : { owned: { file: owner.file, collection: owner.collection } }),\n });\n const { format } = page;\n\n const pageLines = opts.pageLines;\n const marker = opts.marker === true;\n const quote = opts.quote === true;\n const at = pageLines === undefined ? \"\" : `${label}:${spellLines(pageLines)}`;\n\n // Composition first: these need no source and no search.\n if (marker && pageLines === undefined) {\n throw new CiteError(`--marker needs the page lines to anchor: ${label}:L.`);\n }\n if (marker && opts.id === undefined) {\n throw new CiteError(\"--marker needs --id: the marker names the entry.\");\n }\n const wide = pageLines === undefined ? undefined : tooWide(pageLines);\n if (wide !== undefined) throw new CiteError(`Invalid range \"${at}\": it ${wide}.`);\n if (quote && pageLines === undefined) {\n throw new CiteError(`--quote needs the block's lines: ${label}:L1-L2.`);\n }\n if (opts.id !== undefined && !ID.test(opts.id)) {\n throw new CiteError(\n `Invalid id \"${opts.id}\": use lowercase letters, digits and hyphens, starting with a letter or digit.`,\n );\n }\n if (opts.id !== undefined && page.citations.some((c) => c.citation.id === opts.id)) {\n throw new CiteError(`${label} already has an entry ${opts.id}.`);\n }\n if (marker && opts.id !== undefined) {\n // Joining an id a marker already names would write it twice into one\n // list, which is `marker-invalid`. The entry check above catches the\n // ordinary case; this one is left by a marker whose entry went away.\n const already = page.statements.find(\n (s) => s.payload.kind === \"ref\" && s.payload.ids.includes(opts.id ?? \"\"),\n );\n if (already !== undefined) {\n throw new CiteError(\n `${label} already has a marker ${opts.id} at line ${String(already.line)}.`,\n );\n }\n }\n // The same claim on the same source twice is one citation reported twice,\n // and the second is what a re-run of a script writes.\n const duplicate = marker ? undefined : duplicateOf(page, opts.src, pageLines);\n if (duplicate !== undefined) {\n const src = shortSrc(spellSource(duplicate.citation.source));\n const what =\n pageLines === undefined\n ? `a bare pin for ${src}`\n : `an entry for ${spellAt(pageLines)} and ${src}`;\n throw new CiteError(`${label} already has ${what} (${entryName(duplicate)}).`);\n }\n\n const lines = splitLines(content);\n if (pageLines !== undefined) {\n if (pageLines.end > lines.length) {\n throw new CiteError(`${at} is past the end of the page (${String(lines.length)} lines).`);\n }\n if (pageLines.start < page.bodyLine) {\n throw new CiteError(`${at} is in the frontmatter. A claim is body text.`);\n }\n if (quote) {\n const span = fenceSpanAt(content, pageLines.start, format);\n if (span === undefined || span.end !== pageLines.end) {\n throw new CiteError(`${at} is not a fenced block, so it cannot be a quote.`);\n }\n } else if (!marker) {\n // A pin over a fence or a blank line holds for as long as the page has\n // one, so a check would call it `current` whatever the prose does.\n const empty = emptyClaimRefusal(lines, pageLines, at);\n if (empty !== undefined) throw new CiteError(empty);\n }\n // `add` does not move a marker it did not write, so it refuses to write\n // where a misplaced one would make its entry wrong (proposal 0054).\n const split = misplacedMarkers(page, lines);\n const held = split.find(\n (found) => found.line >= pageLines.start && found.line <= pageLines.end,\n );\n if (held !== undefined) {\n throw new CiteError(\n `${at} holds the marker at line ${String(held.line)}, which splits its paragraph. Run manni cite update first.`,\n );\n }\n const inside = marker\n ? split.find(\n (found) => pageLines.start >= found.unit.start && pageLines.start <= found.unit.end,\n )\n : undefined;\n if (inside !== undefined) {\n throw new CiteError(\n `${at} is in the paragraph at ${spellAt(inside.unit)}, which the marker at line ${String(inside.line)} splits. Run manni cite update first.`,\n );\n }\n }\n\n // Git is used whenever it is there, as on check and update: the index is\n // `git ls-files` and the commit is HEAD. Where it is not, a walk and none.\n const client = opts.gitClient ?? gitClient(root);\n const sourceIndex = await sourceIndexFor(root, client);\n\n // The marker goes in before the claim is pinned, because what it anchors is\n // what the claim pins. Everything below counts lines in `body`, the page\n // with the marker, and the frontmatter append shifts them once at the end.\n let body = content;\n let markerAt: number | undefined;\n /** Whether the id joined a marker already there, rather than getting a line. */\n let markerJoined = false;\n let claimSpan: PageLines | undefined;\n let claim: CitationClaim | undefined;\n // Where else the claim's text sits, for the notice at the end of the run.\n let elsewhere: PageLines[] = [];\n // Entries whose claim lines sit below a marker move down with the text.\n let shifted: Shifted = { frontmatter: [], manifest: new Map() };\n if (marker && pageLines !== undefined) {\n // The marker goes above the paragraph or block holding the lines, below\n // any markers already stacked there, at its indentation, and the lines\n // must stay inside it.\n // A marker line is never part of a pin, so a marker written there would\n // change what the line below it pins. The refusal is keyed to the line\n // rather than to what the marker names.\n if (isMarkerLine(lines[pageLines.start - 1] ?? \"\", format)) {\n throw new CiteError(\n `${label}:${String(pageLines.start)} is a marker line. A marker there would change its pin.`,\n );\n }\n const holding = unitHolding(content, pageLines.start, format, {\n offset: page.bodyOffset,\n line: page.bodyLine,\n });\n if (holding === undefined) {\n throw new CiteError(`${at} has no paragraph or block for a marker to anchor.`);\n }\n if (pageLines.end > holding.end) {\n throw new CiteError(\n `${at} runs past the ${holding.kind} at ${spellAt(holding)}. A marker anchors one paragraph.`,\n );\n }\n // A marker pins everything it anchors, so the range limit applies to that.\n const unitWide = tooWide({ start: holding.start, end: holding.end });\n if (unitWide !== undefined) {\n throw new CiteError(\n `${at} is in a ${holding.kind} at ${spellAt(holding)} that ${unitWide}. A marker anchors the whole ${holding.kind}.`,\n );\n }\n // The marker nearest the anchored text: the one on the text own line when\n // there is one, else the last marker line above it. A reader associates\n // the nearest comment with the prose, and appending there needs no other\n // line to move (proposal 0056).\n const above = page.statements.filter((s) => s.anchorLine === holding.start);\n const nearest = above[above.length - 1];\n // A marker already holding the cap takes no more, so the twenty-sixth\n // citation gets a marker line of its own. Refusing would leave no way to\n // cite the paragraph short of editing the line by hand. A marker the\n // scanner could not read is left alone for the same reason.\n //\n // So is one whose delimiters sit on different lines. That parses, but\n // respelling it folds it onto one line, and the claims below it would\n // then all be one line out while this path shifts nothing.\n const held =\n nearest !== undefined &&\n nearest.payload.kind === \"ref\" &&\n nearest.payload.ids.length < MAX_IDS_PER_MARKER &&\n !/[\\r\\n]/.test(nearest.raw)\n ? nearest.payload.ids\n : undefined;\n /** Where the marker ends in `body`, so what follows it can be anchored. */\n let after: number;\n if (nearest !== undefined && held !== undefined) {\n body = respellStatement(content, nearest, [...held, opts.id ?? \"\"]);\n // Joining changes one line in place, so nothing below it moves and no\n // claim on the page is re-spelled.\n after = nearest.end + (body.length - content.length);\n markerAt = nearest.line;\n markerJoined = true;\n } else {\n shifted = shiftedEntries({\n citations: page.citations,\n at: [holding.start],\n delta: 1,\n bodyLine: page.bodyLine,\n label,\n });\n const statement =\n markerIndent(content, holding.start, format, page.bodyLine) +\n formatStatement(format, { kind: \"ref\", ids: [opts.id ?? \"\"] });\n const insertAt = offsetOfLine(content, holding.start);\n body = insertStatementBefore(content, insertAt, statement);\n after = insertAt + statement.length;\n markerAt = holding.start;\n }\n const unit = anchoredLines(body, after, format, quote);\n const pin = unit === undefined ? undefined : pinOfLines(splitLines(body), unit);\n if (unit === undefined || pin === undefined) {\n throw new CiteError(`${at} has no paragraph or block for a marker to anchor.`);\n }\n for (const { index, lines: moved } of shifted.frontmatter) {\n body = spliceEntryField(body, format, index, [\"claim\", \"lines\"], moved);\n }\n claimSpan = unit;\n claim = { integrity: pin };\n } else if (pageLines !== undefined) {\n const pin = pinOfLines(lines, pageLines);\n if (pin === undefined) {\n throw new CiteError(`${at} is past the end of the page (${String(lines.length)} lines).`);\n }\n claimSpan = pageLines;\n claim = { lines: lineSpec(toBodyLines(pageLines, page.bodyLine)), integrity: pin };\n elsewhere = otherClaimSpans(lines, pageLines, pin, page.bodyLine);\n }\n\n const mint = (key: string | undefined, encrypt: boolean): Promise<Citation> =>\n mintCitation({\n root,\n src: opts.src,\n ...(opts.id === undefined ? {} : { id: opts.id }),\n ...(claim === undefined ? {} : { claim }),\n ...(quote ? { quote: true } : {}),\n ...(opts.commitSha === false ? { commitSha: false as const } : {}),\n encrypt,\n ...(key === undefined ? {} : { key }),\n gitClient: client,\n sourceIndex,\n });\n\n // Encryption follows the key: an available one encrypts every add, with no\n // flag to remember, and `--encrypt` asks for one when there is none. With a\n // key in hand this mint is the citation written. Without one it is plain,\n // and settles every refusal that needs no key before the question is put,\n // so a refused add never leaves a key behind.\n const needsKey = opts.encrypt === true && run.key === undefined;\n let citation = await mint(run.key, run.key !== undefined);\n\n if (quote && claimSpan !== undefined) {\n // The lines inside the fences are what the source has to match.\n const cited = await citedText(root, sourceIndex, opts.src, run.key);\n const inside = splitLines(body).slice(claimSpan.start, claimSpan.end - 1).join(\"\\n\");\n if (!blockMatches(inside, cited)) {\n throw new CiteError(`The block at ${at} does not reproduce ${opts.src}.`);\n }\n }\n\n if (needsKey) {\n const { key } = await ensureEncryptionKey({\n subject: opts.src,\n cwd,\n file: run.configFile ?? null,\n env: opts.env,\n confirm: opts.confirm,\n notice: (message) => {\n opts.onNotice?.(message);\n },\n toError: (message) => new CiteError(message),\n });\n citation = await mint(key, true);\n }\n\n // The first pinned source line, so the report shows what the range caught\n // and a mis-typed one is visible at write time. A whole file has no first\n // line worth naming, and an encrypted source is never spelled in the open.\n const srcRange = parseSrc(opts.src);\n let sourceLine: string | undefined;\n if (srcRange.start !== undefined && !isEncryptedValue(citation.source.file)) {\n const read = await readSource(root, sourceIndex, srcRange, undefined);\n if (read.kind === \"ok\") sourceLine = splitLines(read.text)[srcRange.start - 1];\n }\n\n // Where the entry goes follows the config, not a flag: a collection whose\n // manifest owns `citations` keeps them there, and the page is left alone\n // but for a marker.\n const manifests = new ManifestSet();\n let placed: AddResult[\"manifest\"];\n /** Which item of the entry's `citations` this run added, for the line report. */\n let index = 0;\n if (owner !== undefined) {\n if (sidecar?.entry === undefined) {\n throw new CiteError(\n `${label} carries no ${owner.join}: value, so its citations cannot be keyed in ${owner.file}.`,\n );\n }\n const existing = (sidecar.citations ?? []).map((input, index) => {\n const moved = shifted.manifest.get(index);\n return moved === undefined ? input.entry : withClaimLines(input.entry, moved);\n });\n const list = [...existing, entryObject(citation)];\n index = list.length - 1;\n const at = await manifests.write(owner, sidecar.entry, list, index);\n const [changed] = manifests.changed();\n placed = {\n file: at.file,\n line: at.line,\n content: changed?.text ?? \"\",\n diff: changed?.diff ?? \"\",\n written: false,\n };\n }\n\n const after = owner === undefined ? appendFrontmatterCitation(body, format, citation, label) : body;\n // The frontmatter append leaves the body's bytes alone, so every body line\n // moves by exactly what the block grew. The marker sits in the body, so the\n // page it was inserted into already has this page's body line. An entry\n // written to a manifest grows no block, so nothing moves.\n const shift = bodyLineOf(after, locateFrontmatter(after)?.closeEnd ?? 0) - page.bodyLine;\n\n const result: AddResult = {\n file: label,\n citation,\n placed: owner === undefined ? \"frontmatter\" : \"manifest\",\n content: after,\n diff: unifiedDiff(label, content, after),\n written: false,\n ...(sourceLine === undefined ? {} : { sourceLine }),\n ...(placed === undefined ? {} : { manifest: placed }),\n };\n if (markerAt !== undefined) result.markerLine = markerAt + shift;\n if (markerJoined) result.markerJoined = true;\n if (claimSpan !== undefined) {\n result.claimLines = { start: claimSpan.start + shift, end: claimSpan.end + shift };\n }\n\n // A manifest entry leaves the page byte for byte as it was, unless a\n // marker went into the body; there is then nothing to write.\n result.written = path !== undefined && opts.dryRun !== true && after !== content;\n if (result.written && path !== undefined) await writeFileAtomic(path, after);\n // The entry goes in under compare-and-swap, so what lands may be a replay\n // onto a manifest another command wrote while this one was running. The\n // report names the bytes and the line that actually landed, not the ones\n // this run spliced from.\n if (result.manifest !== undefined && opts.dryRun !== true) {\n const [settled] = await manifests.commit();\n if (owner !== undefined && sidecar?.entry !== undefined) {\n result.manifest.line = manifests.lineOf(owner, sidecar.entry, index) ?? result.manifest.line;\n }\n if (settled !== undefined) {\n result.manifest.content = settled.text;\n result.manifest.diff = settled.diff;\n }\n result.manifest.written = true;\n }\n // The claim's text repeats, so a later move of it could not be told apart\n // from its copies. Said once the entry is written: it is not a refusal, and\n // the lines it names are the page's own after the write.\n if (elsewhere.length > 0) {\n const named = elsewhere.map((span) => ({ start: span.start + shift, end: span.end + shift }));\n const who = citation.id === undefined ? \"\" : `${citation.id}: `;\n opts.onNotice?.(\n `${who}the claim's text also appears at ${spellElsewhere(named)}, so a move would be ambiguous. Use --marker, or pin more lines.`,\n );\n }\n // A commit was wanted (no --no-commit-sha) and git had none to give. Said\n // once the add has succeeded, so a refused add says nothing about git.\n if (opts.commitSha !== false && !(await client.available())) {\n opts.onNotice?.(GIT_UNAVAILABLE_COMMIT);\n }\n return result;\n}\n","/**\n * Mint a citation's source end: read the range through the source index, hash\n * it under the rule (the keyed pin when the source is encrypted), record HEAD\n * unless told not to. Refuses (CiteError) a source the index does not hold, an\n * encrypted source the key cannot open, a range wider than\n * `MAX_RANGE_LINES`, a range past EOF, or a commit that does not contain the\n * lines it would be recorded against. No refusal names the path an encrypted\n * source holds.\n *\n * The claim end is minted by the caller, over the page lines it was given,\n * and passed in whole.\n */\nimport { ENCRYPTION_KEY_ENV } from \"../../shared/encryption-key.js\";\nimport { CiteError } from \"../errors.js\";\nimport type {\n Citation,\n CitationSource,\n MintOptions,\n MissingReason,\n SourceRange,\n} from \"../types.js\";\nimport { historyOf } from \"./classify.js\";\nimport { hashLines, sliceLines, splitLines } from \"./hash.js\";\nimport { parseSrc, rangeLines, tooWide } from \"./range.js\";\nimport { buildSourceIndex, encryptSourcePath, readSource } from \"./sources.js\";\n\n/** The schema's `commit-sha` pattern: seven to sixty-four lowercase hex digits. */\nconst COMMIT_PATTERN = /^[0-9a-f]{7,64}$/;\n\nasync function commitFor(opts: MintOptions): Promise<string | undefined> {\n if (opts.commitSha === false) return undefined;\n if (typeof opts.commitSha === \"string\") {\n if (!COMMIT_PATTERN.test(opts.commitSha)) {\n throw new CiteError(\n `Invalid commit-sha \"${opts.commitSha}\": expected 7 to 64 lowercase hex digits.`,\n );\n }\n return opts.commitSha;\n }\n const client = opts.gitClient;\n if (client === undefined || !(await client.available())) return undefined;\n return (await client.head()) ?? undefined;\n}\n\n/**\n * Refuse a commit that does not contain the lines it would be recorded\n * against. The range is read from the working tree, so an uncommitted edit\n * would otherwise be dated to a commit that never held it. Such a pin reads as\n * `current` forever, because `classifyCitation` returns at the working-tree\n * match without consulting the commit, and then accuses the source of\n * `source-never-true` the first time it changes.\n *\n * `historyOf` is the same question `check` asks, so the answers agree. It\n * accepts the lines sitting elsewhere in the file at that commit, which is what\n * `update` leaves behind when it follows a move and keeps `commit`.\n *\n * A commit git cannot read is recorded unverified. A shallow clone must\n * degrade to \"history unavailable\" rather than refuse (`git.ts`).\n */\nasync function assertCommitHolds(\n opts: MintOptions,\n commit: string,\n path: string,\n range: SourceRange,\n pin: string,\n key: string | undefined,\n): Promise<void> {\n const client = opts.gitClient;\n if (client === undefined || !(await client.available())) return;\n const history = await historyOf(client, commit, path, range, pin, key, undefined);\n if (history.kind !== \"never-true\") return;\n // Named as the caller spelled it: an encrypted source stays a ciphertext.\n throw new CiteError(\n `${opts.src} is not committed: ${commit.slice(0, 7)} does not contain those lines. Commit the source, or use --no-commit-sha.`,\n );\n}\n\n/**\n * The refusal for a source that could not be read, naming it as the caller\n * spelled it: an encrypted source stays a ciphertext even on stderr.\n */\nfunction refusalFor(reason: MissingReason, path: string, encrypted: boolean): CiteError {\n switch (reason) {\n case \"untracked\":\n return new CiteError(\n encrypted\n ? `No tracked file matches ${path} (wrong --root?).`\n : `Source not found: ${path} is not a tracked file under the root.`,\n );\n case \"no-key\":\n return new CiteError(`${path} is encrypted, and no encryption key is available to decrypt it.`);\n case \"undecryptable\":\n return new CiteError(`${path} does not decrypt under the current key.`);\n case \"unreadable\":\n return new CiteError(`Source not readable: ${path} could not be read.`);\n }\n}\n\nexport async function mintCitation(opts: MintOptions): Promise<Citation> {\n const range = parseSrc(opts.src);\n const wide =\n range.start === undefined || range.end === undefined\n ? undefined\n : tooWide({ start: range.start, end: range.end });\n if (wide !== undefined) throw new CiteError(`Invalid range \"${opts.src}\": it ${wide}.`);\n const { key } = opts;\n // A source that is already encrypted stays encrypted whatever `encrypt`\n // says: the check side keys every pin whose file is encrypted, so a plain\n // pin under a ciphertext would never hold.\n const encrypt = opts.encrypt === true || range.encrypted;\n if (encrypt && !range.encrypted && key === undefined) {\n throw new CiteError(\n `${opts.src} must be encrypted, and no encryption key is available. Run \\`manni key set\\`, or set ${ENCRYPTION_KEY_ENV}.`,\n );\n }\n const index = opts.sourceIndex ?? (await buildSourceIndex(opts.root, { gitClient: opts.gitClient }));\n\n const read = await readSource(opts.root, index, range, key);\n if (read.kind === \"missing\") throw refusalFor(read.reason, range.path, range.encrypted);\n\n // The out-of-range error names the source as the caller spelled it, never a\n // decrypted path.\n const joined = sliceLines(splitLines(read.text), range, range.path);\n // Set whenever `encrypt` is: refused above for a plain source, and an\n // encrypted one could not have been read without it.\n const pinKey = encrypt ? key : undefined;\n const file =\n pinKey !== undefined && !range.encrypted ? encryptSourcePath(read.resolvedPath, pinKey) : range.path;\n const lines = rangeLines(range);\n const commitSha = await commitFor(opts);\n const integrity = hashLines(joined, pinKey);\n if (commitSha !== undefined) {\n await assertCommitHolds(opts, commitSha, read.resolvedPath, range, integrity, pinKey);\n }\n\n const source: CitationSource = { file, integrity };\n // Field order is the order a reader scans a source in: which file, which\n // lines, what they hashed to, and when that was taken.\n const ordered: CitationSource = {\n file: source.file,\n ...(lines === undefined ? {} : { lines }),\n integrity: source.integrity,\n ...(commitSha === undefined ? {} : { \"commit-sha\": commitSha }),\n };\n // And an entry reads: what it is called, what it says, what it rests on.\n return {\n ...(opts.id === undefined ? {} : { id: opts.id }),\n ...(opts.claim === undefined ? {} : { claim: opts.claim }),\n source: ordered,\n ...(opts.quote === undefined ? {} : { quote: opts.quote }),\n };\n}\n","/**\n * Moving claim lines when a marker line comes or goes.\n *\n * `add --marker` inserts one line above a paragraph; `remove` deletes the\n * marker lines of the entries it takes out. Either way the claims below the\n * change have to move with the text they pin, in the same write, or the next\n * check reports a page nobody edited. One rule decides both directions, so\n * the two commands cannot disagree about which entries move.\n *\n * A change that lands *inside* a claim's own lines is not a move: it would\n * change what the pin covers. That is a refusal, and nothing is written.\n */\nimport { CiteError } from \"../errors.js\";\nimport type { LineSpec, PageCitation } from \"../types.js\";\nimport { toFileLines } from \"./claims.js\";\nimport { lineSpec, parseLines } from \"./range.js\";\nimport { spellAt } from \"./spell.js\";\n\n/** The new `claim.lines` of each entry the change moves, by where the entry lives. */\nexport interface Shifted {\n frontmatter: { index: number; lines: LineSpec }[];\n manifest: Map<number, LineSpec>;\n}\n\nexport interface ShiftOptions {\n /** The entries to move: on a removal, the ones that survive it. */\n citations: readonly PageCitation[];\n /** File lines where a marker line is inserted, or where one is removed. */\n at: readonly number[];\n /** `1` for lines coming in, `-1` for lines going out. */\n delta: 1 | -1;\n /** File line of body line 1, since `claim.lines` count the body. */\n bodyLine: number;\n /** The page as the run reports it, for the refusal. */\n label: string;\n}\n\n/**\n * The entries whose claim lines move, each by however many of `at` sit above\n * them. An insertion at a claim's first line pushes the whole claim down; a\n * removal of that line is inside the claim instead, because the line is the\n * claim's own. Hence the two comparisons.\n */\nexport function shiftedEntries(opts: ShiftOptions): Shifted {\n const { citations, at, delta, bodyLine, label } = opts;\n const out: Shifted = { frontmatter: [], manifest: new Map() };\n if (at.length === 0) return out;\n for (const { citation, origin } of citations) {\n const spec = citation.claim?.lines;\n const recorded = spec === undefined ? undefined : parseLines(spec);\n if (recorded === undefined) continue;\n const file = toFileLines(recorded, bodyLine);\n const inside = at.find((line) =>\n delta === 1\n ? line > file.start && line <= file.end\n : line >= file.start && line <= file.end,\n );\n if (inside !== undefined) {\n const whose =\n citation.id === undefined\n ? `the claim at ${spellAt(file)}`\n : `the claim of ${citation.id} (${spellAt(file)})`;\n const why =\n delta === 1\n ? \"A marker there would change its pin.\"\n : \"Removing the marker there would change its pin.\";\n throw new CiteError(`${label}:${String(inside)} is inside ${whose}. ${why}`);\n }\n const lines = at.filter((line) => (delta === 1 ? line <= file.start : line < file.start)).length;\n if (lines === 0) continue;\n const moved = lineSpec({\n start: recorded.start + lines * delta,\n end: recorded.end + lines * delta,\n });\n if (origin.kind === \"manifest\") out.manifest.set(origin.index, moved);\n else out.frontmatter.push({ index: origin.index, lines: moved });\n }\n return out;\n}\n\n/** A copy of a manifest entry with its `claim.lines` replaced. */\nexport function withClaimLines(entry: unknown, lines: LineSpec): unknown {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) return entry;\n const claim: unknown = (entry as Record<string, unknown>).claim;\n if (typeof claim !== \"object\" || claim === null || Array.isArray(claim)) return entry;\n return { ...entry, claim: { ...claim, lines } };\n}\n","/**\n * Writing a page's `citations` into the manifest that owns them.\n *\n * The splice itself is meta's (`spliceManifestValue` on the family-internal\n * barrel): one owned value of one entry is replaced, every other byte of the\n * file survives by construction, and the result is read back before it is\n * returned. This module is the part cite owns — holding each manifest's text\n * for the length of a run so it is written once, and finding the line a\n * written entry now sits on, which is what `add` reports and what a finding\n * about an entry points at.\n *\n * Only `commit` touches the disk. A caller reads the manifests it needs and\n * writes them when the whole run has succeeded, the way `key rotate` writes\n * pages only once every one of them could be re-encrypted.\n *\n * That gap is why `commit` re-reads. A run holds a manifest from its first\n * `hold` to its last write, which is seconds of minting, hashing and git, and\n * two runs over one working copy overlap easily. The compare-and-swap that\n * makes the second write see the first is `src/shared/manifest-cas.ts`, which\n * `meta fill` and `meta derive` hold their manifests with too; what stays here\n * is what cite means by an edit, which is one entry's `citations`.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { posix } from \"node:path\";\nimport { LineCounter, isMap, isNode, isScalar, isSeq, parseDocument } from \"yaml\";\nimport { DocmetaError, writeFileAtomic } from \"../../meta/index.js\";\nimport {\n readManifestValue,\n removeManifestKey,\n spliceManifestValue,\n} from \"../../meta/internal.js\";\nimport {\n heldManifest,\n isMissing,\n rebaseable,\n settle,\n type CommitIo as CasCommitIo,\n type HeldManifest as CasHeldManifest,\n type ManifestCodec,\n type ManifestOp as CasManifestOp,\n} from \"../../shared/manifest-cas.js\";\nimport { CiteError } from \"../errors.js\";\nimport { unifiedDiff } from \"./write.js\";\nimport { CITATIONS_KEY, type CitationManifest } from \"./sidecar.js\";\n\n/** One edit this run made, replayable onto bytes read later. */\ntype ManifestOp = CasManifestOp &\n ({ kind: \"splice\"; value: unknown[] } | { kind: \"remove\" });\n\n/** One manifest held for the length of a run: its text before, and now. */\nexport type HeldManifest = CasHeldManifest<ManifestOp>;\n\n/** One recorded edit, and one `citations` value read back, over a manifest. */\nconst codec: ManifestCodec<ManifestOp> = { apply, read: readManifestValue };\n\n/** One manifest this run rewrote, as `changed()` and `commit()` report it. */\nexport interface ManifestChange {\n path: string;\n file: string;\n before: string;\n text: string;\n /**\n * `before` against `text`. A commit that rebased moves `before` to the bytes\n * it compared against, so the diff then shows what this run added on top of\n * a concurrent write rather than against the read `hold()` made.\n */\n diff: string;\n}\n\n/** What `commit()` does with each manifest it settles. */\nexport type CommitIo = CasCommitIo<ManifestChange>;\n\n/** Every manifest one run writes, read once and spliced in memory. */\nexport class ManifestSet {\n private readonly held = new Map<string, HeldManifest>();\n\n /** Read a manifest, or hand back the copy this run has already rewritten. */\n async hold(manifest: CitationManifest): Promise<HeldManifest> {\n const already = this.held.get(manifest.path);\n if (already !== undefined) return already;\n let before: string;\n let absent = false;\n try {\n before = await readFile(manifest.path, \"utf8\");\n } catch (error) {\n // A per-page manifest (proposal 0058) that does not exist yet is a page\n // with nothing cited: held as empty text marked absent, and created by\n // the commit. A missing concrete manifest is refused, as it always was.\n if (manifest.pattern === undefined || !isMissing(error)) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new CiteError(`Manifest ${manifest.file} could not be read: ${reason}`);\n }\n before = \"\";\n absent = true;\n }\n const fresh = heldManifest<ManifestOp>(manifest.path, manifest.file, before, absent);\n this.held.set(manifest.path, fresh);\n return fresh;\n }\n\n /**\n * Write one page's whole `citations` list into its entry, and answer where\n * the entry at `index` now sits. The manifest is not saved: `changed()`\n * lists what the run would write.\n */\n async write(\n manifest: CitationManifest,\n entry: string,\n citations: readonly unknown[],\n index: number,\n ): Promise<{ file: string; line: number }> {\n const held = await this.hold(manifest);\n const op: ManifestOp = {\n kind: \"splice\",\n entry,\n key: CITATIONS_KEY,\n join: manifest.join,\n file: manifest.file,\n value: [...citations],\n };\n rebaseable(held, op, codec);\n const spliced = splice(held.text, {\n entry,\n key: CITATIONS_KEY,\n value: op.value,\n join: manifest.join,\n file: manifest.file,\n });\n held.text = spliced.text;\n held.ops.push(op);\n return { file: manifest.file, line: itemLine(spliced.text, entry, index, manifest.join) ?? spliced.line };\n }\n\n /**\n * Where one item of an entry's `citations` sits in the manifest as this run\n * will write it. `add` names a line in its report, and `commit` may have\n * replayed the entry onto bytes that moved it, so the line is read back from\n * the settled text rather than kept from the splice.\n */\n lineOf(manifest: CitationManifest, entry: string, index: number): number | undefined {\n const held = this.held.get(manifest.path);\n if (held === undefined) return undefined;\n return itemLine(held.text, entry, index, manifest.join);\n }\n\n /**\n * Take a page's `citations` key out of the manifest, for the removal that\n * leaves it with no entries. The entry itself goes when that key was all it\n * had, so a manifest never keeps a document nothing is recorded about.\n */\n async remove(manifest: CitationManifest, entry: string): Promise<void> {\n const held = await this.hold(manifest);\n const op: ManifestOp = {\n kind: \"remove\",\n entry,\n key: CITATIONS_KEY,\n join: manifest.join,\n file: manifest.file,\n };\n rebaseable(held, op, codec);\n held.text = apply(held.text, op);\n held.ops.push(op);\n }\n\n /** The manifests this run rewrote, with the diff of each. */\n changed(): ManifestChange[] {\n return [...this.held.values()]\n .filter((m) => m.text !== m.before)\n .map((m) => ({ ...m, diff: unifiedDiff(m.file, m.before, m.text) }));\n }\n\n /**\n * Write every manifest this run rewrote, and report what landed.\n *\n * The write is the last thing a run does, so this is the one place that\n * knows a manifest is about to be replaced by bytes derived from a read\n * that may be seconds old.\n */\n async commit(io: CommitIo = {}): Promise<ManifestChange[]> {\n // A per-page manifest (proposal 0058) may be the first file in its directory.\n const write =\n io.write ?? ((at: string, text: string): Promise<void> => writeFileAtomic(at, text, { createParents: true }));\n const read = io.read ?? ((at: string): Promise<string> => readFile(at, \"utf8\"));\n const landed: ManifestChange[] = [];\n for (const held of this.held.values()) {\n if (held.text === held.before) continue;\n try {\n await settle(held, { codec, write, read, toError: (message) => new CiteError(message) });\n } catch (error) {\n if (io.onError !== undefined) await io.onError(changeOf(held), error);\n throw error;\n }\n const change = changeOf(held);\n landed.push(change);\n io.after?.(change);\n }\n return landed;\n }\n}\n\n/** The change one held manifest reports, against the bytes it will replace. */\nfunction changeOf(held: HeldManifest): ManifestChange {\n return {\n path: held.path,\n file: held.file,\n before: held.before,\n text: held.text,\n diff: unifiedDiff(held.file, held.before, held.text),\n };\n}\n\n/** One recorded edit, against whatever text it is handed. */\nfunction apply(text: string, op: ManifestOp): string {\n const where = { entry: op.entry, key: op.key, join: op.join, file: op.file };\n if (op.kind === \"splice\") return splice(text, { ...where, value: op.value }).text;\n try {\n return removeManifestKey(text, where).text;\n } catch (error) {\n if (error instanceof DocmetaError) throw new CiteError(error.message);\n throw error;\n }\n}\n\n/** `spliceManifestValue`, with meta's refusal reported as this tool's. */\nexport function splice(\n text: string,\n options: Parameters<typeof spliceManifestValue>[1],\n): { text: string; line: number } {\n try {\n return spliceManifestValue(text, options);\n } catch (error) {\n if (error instanceof DocmetaError) throw new CiteError(error.message);\n throw error;\n }\n}\n\n/**\n * The 1-based line of one item of an entry's `citations`, in a manifest that\n * may not have been written yet. The loader answers this for a manifest on\n * disk; a freshly spliced one has to be read where it stands, so `add` can\n * say where the entry it just wrote went.\n */\nexport function itemLine(\n text: string,\n entry: string,\n index: number,\n join: string,\n): number | undefined {\n const lc = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n if (doc.errors.length > 0) return undefined;\n const root = doc.contents;\n if (!isMap(root)) return undefined;\n const same = (key: unknown): boolean => {\n const spelled = isScalar(key) ? String(key.value) : String(key);\n return join === \"path\" ? posix.normalize(spelled) === posix.normalize(entry) : spelled === entry;\n };\n const pair = root.items.find((p) => same(p.key));\n const value = pair?.value;\n if (!isMap(value)) return undefined;\n const kv = value.items.find(\n (p) => (isScalar(p.key) ? String(p.key.value) : String(p.key)) === CITATIONS_KEY,\n );\n const list = kv?.value;\n if (!isSeq(list)) return undefined;\n const item: unknown = list.items[index];\n const range = isNode(item) ? item.range : undefined;\n return range ? lc.linePos(range[0]).line : undefined;\n}\n","/**\n * Every way the tool rewrites a page. Frontmatter appends go through meta's\n * `applyFrontmatter` (comments and key order preserved). A repair splices one\n * scalar textually at `lineFor(\"/citations/N/source/lines\")` and the like, so\n * nothing else in the block is touched. Markers are inserted by offset with\n * the page's own EOL. Files are written with `writeFileAtomic`.\n *\n * A rewrite of the body goes through `applyEdits`: the caller collects every\n * span it means to replace against one parse and hands them over together, so\n * no position is ever read out of text that has already been written to.\n */\nimport { DocmetaError, locateFrontmatter, type MetadataExtractor } from \"../../meta/index.js\";\nimport { extractorByName } from \"../../meta/internal.js\";\nimport { CiteError } from \"../errors.js\";\nimport type { Citation, LineSpec, TextEdit } from \"../types.js\";\nimport { splitLines } from \"./hash.js\";\nimport { detectEol, lineAt, offsetOfLine } from \"./statements.js\";\n\nfunction extractorFor(format: string): MetadataExtractor {\n const extractor = extractorByName(format);\n if (!extractor) throw new CiteError(`Unknown format \"${format}\".`);\n return extractor;\n}\n\n/**\n * Whether the format reads a leading fenced block as its frontmatter. Asked\n * of the extractor itself rather than kept as a list of names here, so a\n * format added to meta's registry answers for itself. An element-backed\n * format (html, xml) sees the probe as body text and says no.\n */\nfunction readsFencedFrontmatter(extractor: MetadataExtractor, label: string): boolean {\n return extractor.extract(\"---\\nprobe: 1\\n---\\n\", label).fenced === true;\n}\n\n/** Append one entry to `citations` (creating the key), via the format's extractor. */\nexport function appendFrontmatterCitation(\n content: string,\n format: string,\n citation: Citation,\n filePath?: string,\n): string {\n const label = filePath ?? \"the page\";\n const extractor = extractorFor(format);\n // Element-backed metadata (html, xml) has `apply` too, but it is not\n // frontmatter. Whether this *page* can take a block is `apply`'s call:\n // markdown creates one, asciidoc and rst refuse when none exists.\n if (!extractor.apply || !readsFencedFrontmatter(extractor, label)) {\n throw new CiteError(\n `${label} has no frontmatter to write to; keep its citations in a manifest instead.`,\n );\n }\n const extracted = extractor.extract(content, label);\n if (locateFrontmatter(content)?.flavor === \"toml\") {\n throw new CiteError(\n `${label} has TOML frontmatter; manni cannot add a citations table without re-emitting the whole block, which would drop its comments. Add the entry by hand.`,\n );\n }\n\n const raw: unknown = extracted.data.citations ?? [];\n if (!Array.isArray(raw)) {\n throw new CiteError(`${label}: \\`citations\\` is not a list; edit it by hand.`);\n }\n // `isArray` narrows `unknown` to `any[]`; name the element type before it spreads.\n const existing: unknown[] = raw;\n const entry = entryObject(citation);\n try {\n return extractor.apply(content, { citations: [...existing, entry] });\n } catch (e) {\n if (e instanceof DocmetaError) throw new CiteError(`${label}: ${e.message}`);\n throw e;\n }\n}\n\n/**\n * Take entries out of a page's `citations`, by their index in the list, and\n * write what is left back through the format's extractor. An empty list\n * removes the key: an entry deleted by hand once left a `citations:` with\n * nothing under it, and a page that carries no citations should say so by\n * carrying no key.\n *\n * The write is the inverse of `appendFrontmatterCitation` and goes the same\n * way, so a page manni can add to is a page manni can remove from.\n */\nexport function removeFrontmatterCitations(\n content: string,\n format: string,\n drop: ReadonlySet<number>,\n filePath?: string,\n): string {\n const label = filePath ?? \"the page\";\n const extractor = extractorFor(format);\n if (!extractor.apply || !readsFencedFrontmatter(extractor, label)) {\n throw new CiteError(\n `${label} has no frontmatter to write to; keep its citations in a manifest instead.`,\n );\n }\n if (locateFrontmatter(content)?.flavor === \"toml\") {\n throw new CiteError(\n `${label} has TOML frontmatter; manni cannot rewrite a citations table without re-emitting the whole block, which would drop its comments. Remove the entry by hand.`,\n );\n }\n const raw: unknown = extractor.extract(content, label).data.citations ?? [];\n if (!Array.isArray(raw)) {\n throw new CiteError(`${label}: \\`citations\\` is not a list; edit it by hand.`);\n }\n const existing: unknown[] = raw;\n const kept = existing.filter((_entry, index) => !drop.has(index));\n try {\n return kept.length === 0\n ? extractor.apply(content, {}, { deletions: [\"citations\"] })\n : extractor.apply(content, { citations: kept });\n } catch (e) {\n if (e instanceof DocmetaError) throw new CiteError(`${label}: ${e.message}`);\n throw e;\n }\n}\n\n/**\n * `content` with every edit applied in one pass. Each edit's `start` and `end`\n * index `content` as it was handed in, never the text an earlier edit\n * produced, and that is the whole point: a caller collects its edits from one\n * parse and applies them together, so no position outlives the text it was\n * read from and the order they were collected in cannot matter.\n *\n * Edits may not overlap. Two writers reaching for the same bytes is a bug in\n * the caller rather than something to resolve here, so it throws instead of\n * picking a winner. `lineRemovals` is what keeps two neighbouring lines from\n * being that bug.\n */\nexport function applyEdits(content: string, edits: readonly TextEdit[]): string {\n const sorted = [...edits].sort((a, b) => a.start - b.start);\n let out = \"\";\n let at = 0;\n for (const edit of sorted) {\n if (edit.end < edit.start) {\n throw new Error(`cite: backwards edit [${String(edit.start)}, ${String(edit.end)})`);\n }\n if (edit.start < at) {\n throw new Error(`cite: overlapping edits at ${String(edit.start)}`);\n }\n out += content.slice(at, edit.start) + edit.text;\n at = edit.end;\n }\n return out + content.slice(at);\n}\n\n/**\n * The edits that take 1-based `lines` out of `content`, their terminators\n * included: one edit per run of consecutive lines, so two neighbours never\n * reach for the same break. Order and repeats in `lines` do not matter.\n */\nexport function lineRemovals(content: string, lines: readonly number[]): TextEdit[] {\n const sorted = [...new Set(lines)].sort((a, b) => a - b);\n const out: TextEdit[] = [];\n let run: { first: number; last: number } | undefined;\n for (const line of sorted) {\n if (run !== undefined && line === run.last + 1) run.last = line;\n else {\n if (run !== undefined) out.push(runRemoval(content, run.first, run.last));\n run = { first: line, last: line };\n }\n }\n if (run !== undefined) out.push(runRemoval(content, run.first, run.last));\n return out;\n}\n\n/** The span covering 1-based lines `first`..`last` and their terminator. */\nfunction runRemoval(content: string, first: number, last: number): TextEdit {\n let start = offsetOfLine(content, first);\n // `offsetOfLine` answers the length when asked past the end, so a run whose\n // span reaches it on a page with no final newline is the tail of the file.\n // It has no terminator below it to take, so it takes the one above: on CRLF\n // that break is two bytes, and stopping at the LF would leave the CR behind\n // as the tail of a line that is gone. `spliceEntryField` pulls back over a\n // CR for the same reason.\n const end = offsetOfLine(content, last + 1);\n if (end === content.length && !content.endsWith(\"\\n\") && start > 0) {\n let above = content.lastIndexOf(\"\\n\", start - 1);\n if (above > 0 && content.charAt(above - 1) === \"\\r\") above--;\n start = above === -1 ? 0 : above;\n }\n return { start, end, text: \"\" };\n}\n\n/** Delete the whole of 1-based `line`, its terminator included. */\nexport function removeLine(content: string, line: number): string {\n return applyEdits(content, lineRemovals(content, [line]));\n}\n\n/**\n * The entry as a plain object, in the order a reader scans it, with every\n * absent optional left out rather than written as `null`.\n */\nexport function entryObject(citation: Citation): Record<string, unknown> {\n const source: Record<string, unknown> = { file: citation.source.file };\n if (citation.source.lines !== undefined) source.lines = citation.source.lines;\n source.integrity = citation.source.integrity;\n if (citation.source[\"commit-sha\"] !== undefined) {\n source[\"commit-sha\"] = citation.source[\"commit-sha\"];\n }\n const entry: Record<string, unknown> = {};\n if (citation.id !== undefined) entry.id = citation.id;\n if (citation.claim !== undefined) {\n const claim: Record<string, unknown> = {};\n if (citation.claim.lines !== undefined) claim.lines = citation.claim.lines;\n claim.integrity = citation.claim.integrity;\n entry.claim = claim;\n }\n entry.source = source;\n if (citation.quote !== undefined) entry.quote = citation.quote;\n return entry;\n}\n\n/** Plain YAML scalars that would read back as something other than the string. */\nfunction needsYamlQuotes(value: string): boolean {\n return (\n value === \"\" ||\n /^[\\s!&*?|>'\"%@`{}[\\],#]/.test(value) ||\n /^-(\\s|$)/.test(value) ||\n /:\\s|\\s#|:$|\\s$/.test(value) ||\n /^(?:true|false|null|~|yes|no|on|off|[-+]?(?:\\d[\\d_]*\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?)$/i.test(value)\n );\n}\n\n/** `\"…\"` with the escapes YAML and JSON share. */\nconst doubleQuote = (value: string): string => JSON.stringify(value);\nconst singleQuote = (value: string): string => `'${value.replace(/'/g, \"''\")}'`;\n\n/**\n * Split a `key: value` line into its lead (` - src: `), the scalar, and what\n * trails it (a comment, a JSON comma). Undefined when the line does not carry\n * `field`.\n */\nfunction splitScalarLine(\n line: string,\n field: string,\n): { lead: string; scalar: string; trail: string } | undefined {\n const keyed = new RegExp(`^(\\\\s*(?:-\\\\s+)?\"?${field}\"?\\\\s*:\\\\s*)(.*)$`).exec(line);\n const lead = keyed?.[1];\n const rest = keyed?.[2];\n if (lead === undefined || rest === undefined) return undefined;\n const quote = rest.charAt(0);\n let end: number;\n if (quote === '\"' || quote === \"'\") {\n end = -1;\n for (let i = 1; i < rest.length; i++) {\n const ch = rest.charAt(i);\n if (quote === '\"' && ch === \"\\\\\") {\n i++;\n } else if (ch === quote) {\n if (quote === \"'\" && rest.charAt(i + 1) === \"'\") {\n i++;\n continue;\n }\n end = i + 1;\n break;\n }\n }\n if (end < 0) return undefined;\n } else {\n const comment = /\\s#/.exec(rest);\n end = comment ? comment.index : rest.length;\n while (end > 0 && /\\s/.test(rest.charAt(end - 1))) end--;\n }\n return { lead, scalar: rest.slice(0, end), trail: rest.slice(end) };\n}\n\n/** One scalar of an entry a repair may rewrite: a file, an end's lines, its pin, or the commit. */\nexport type EntryPath = readonly [\n end: \"claim\" | \"source\",\n field: \"file\" | \"lines\" | \"integrity\" | \"commit-sha\",\n];\n\n/** Replace the scalar on one line of entry N, e.g. `source.lines` after a move. */\nexport function spliceEntryField(\n content: string,\n format: string,\n index: number,\n path: EntryPath,\n value: LineSpec,\n): string {\n const [which, field] = path;\n const refuse = (): CiteError =>\n new CiteError(\n `Cannot rewrite citations[${String(index)}].${which}.${field} in ${format} frontmatter; edit it by hand.`,\n );\n const extractor = extractorFor(format);\n const pointer = `/citations/${String(index)}/${which}/${field}`;\n // `lineFor` walks up to the nearest recorded ancestor when the exact\n // pointer is unknown (TOML records top-level keys only), so the line it\n // names is checked for the field before anything is touched.\n const line = extractor.extract(content, \"page\").lineFor(pointer);\n if (line === undefined) throw refuse();\n const start = offsetOfLine(content, line);\n const nl = content.indexOf(\"\\n\", start);\n let end = nl === -1 ? content.length : nl;\n if (end > start && content.charAt(end - 1) === \"\\r\") end--;\n const parts = splitScalarLine(content.slice(start, end), field);\n if (!parts) throw refuse();\n\n const quote = parts.scalar.charAt(0);\n // A number is written plain whatever the old value's quoting was, so that\n // a range that became one line reads back as the integer it now is.\n const spelled =\n typeof value === \"number\" ? String(value)\n : quote === '\"' ? doubleQuote(value)\n : quote === \"'\" ? singleQuote(value)\n : needsYamlQuotes(value) ? doubleQuote(value)\n : value;\n const out = content.slice(0, start) + parts.lead + spelled + parts.trail + content.slice(end);\n\n // Read it back: a splice that lands anywhere but on that one value is a\n // refusal, not a damaged page.\n const check: unknown = extractor.extract(out, \"page\").data.citations;\n const entry: unknown = Array.isArray(check) ? check[index] : undefined;\n const block = isRecord(entry) ? entry[which] : undefined;\n const readBack = isRecord(block) ? block[field] : undefined;\n if (readBack !== value) throw refuse();\n return out;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Insert a statement line before the line containing `offset`, with the page's EOL. */\nexport function insertStatementBefore(\n content: string,\n offset: number,\n statement: string,\n): string {\n const start = offsetOfLine(content, lineAt(content, offset));\n return content.slice(0, start) + statement + detectEol(content) + content.slice(start);\n}\n\ntype Edit = { op: \" \" | \"-\" | \"+\"; text: string };\n\n/**\n * A unified diff of two texts, `---`/`+++` headers with the same label. Lines\n * are the hashing rule's (`splitLines`): a BOM is never part of a line, so a\n * page that carries one diffs the same as one that does not.\n */\nexport function unifiedDiff(label: string, before: string, after: string): string {\n const a = splitLines(before);\n const b = splitLines(after);\n // Shared prefix and suffix leave the LCS table to the lines that differ.\n let head = 0;\n while (head < a.length && head < b.length && a[head] === b[head]) head++;\n let tail = 0;\n while (tail < a.length - head && tail < b.length - head && a[a.length - 1 - tail] === b[b.length - 1 - tail]) tail++;\n const x = a.slice(head, a.length - tail);\n const y = b.slice(head, b.length - tail);\n if (x.length === 0 && y.length === 0) return \"\";\n\n const width = y.length + 1;\n const lcs = new Uint32Array((x.length + 1) * width);\n for (let i = x.length - 1; i >= 0; i--) {\n for (let j = y.length - 1; j >= 0; j--) {\n lcs[i * width + j] =\n x[i] === y[j]\n ? (lcs[(i + 1) * width + j + 1] ?? 0) + 1\n : Math.max(lcs[(i + 1) * width + j] ?? 0, lcs[i * width + j + 1] ?? 0);\n }\n }\n const edits: Edit[] = a.slice(0, head).map((text) => ({ op: \" \", text }));\n let i = 0;\n let j = 0;\n while (i < x.length || j < y.length) {\n const xi = x[i];\n const yj = y[j];\n if (xi !== undefined && yj !== undefined && xi === yj) {\n edits.push({ op: \" \", text: xi });\n i++;\n j++;\n } else if (xi !== undefined && (yj === undefined || (lcs[(i + 1) * width + j] ?? 0) >= (lcs[i * width + j + 1] ?? 0))) {\n // Deletions before insertions on a tie, as unified diffs read.\n edits.push({ op: \"-\", text: xi });\n i++;\n } else if (yj !== undefined) {\n edits.push({ op: \"+\", text: yj });\n j++;\n }\n }\n edits.push(...a.slice(a.length - tail).map((text) => ({ op: \" \" as const, text })));\n\n // Hunks: each change with one line of context; hunks whose context touches merge.\n const CONTEXT = 1;\n const out = [`--- ${label}`, `+++ ${label}`];\n let pos = 0;\n while (pos < edits.length) {\n if (edits[pos]?.op === \" \") {\n pos++;\n continue;\n }\n const from = Math.max(0, pos - CONTEXT);\n let to = pos;\n for (let k = pos; k < edits.length; k++) {\n if (edits[k]?.op !== \" \") to = k;\n else if (k - to > CONTEXT * 2) break;\n }\n to = Math.min(edits.length - 1, to + CONTEXT);\n let oldStart = 1;\n let newStart = 1;\n for (let k = 0; k < from; k++) {\n const op = edits[k]?.op;\n if (op !== \"+\") oldStart++;\n if (op !== \"-\") newStart++;\n }\n const slice = edits.slice(from, to + 1);\n const oldCount = slice.filter((e) => e.op !== \"+\").length;\n const newCount = slice.filter((e) => e.op !== \"-\").length;\n out.push(\n `@@ -${oldCount === 0 ? oldStart - 1 : oldStart},${oldCount} +${newCount === 0 ? newStart - 1 : newStart},${newCount} @@`,\n ...slice.map((e) => e.op + e.text),\n );\n pos = to + 1;\n }\n return out.join(\"\\n\") + \"\\n\";\n}\n","/**\n * `manni cite remove`: take a citation off a page.\n *\n * The inverse of `add`, and it undoes all of what `add` did. The entry goes\n * out of the page's frontmatter, or out of the manifest that owns the page's\n * citations, whichever `add` would have written to. Every marker naming it\n * goes out of the body: the id goes out of the marker list, and the whole\n * line goes when that id was the last one (proposal 0056). The claims below\n * each removed marker line move up with the text they pin, which is the\n * inverse of the shift `add --marker` performs and the same rule\n * (`shiftedEntries`). A marker that only loses a word moves nothing.\n *\n * `--only` is required, one entry per occurrence, and nothing is written\n * until every one of them has been found: a run either removes what it was\n * told to or writes nothing. That is `add`'s contract, and the reason there\n * is no exit 1 here.\n *\n * An id with a marker and no entry removes the marker alone, which is how a\n * `marker-orphan` is cleared.\n */\nimport { resolve } from \"node:path\";\nimport { writeFileAtomic } from \"../../meta/index.js\";\nimport { STDIN_LABEL } from \"../../meta/internal.js\";\nimport { ManifestSet } from \"../core/manifest.js\";\nimport { citationInputs, pickExtractor, readPage } from \"../core/page.js\";\nimport { shiftedEntries, withClaimLines } from \"../core/shift.js\";\nimport { isMarkerLine, respellEdit } from \"../core/statements.js\";\nimport { splitLines } from \"../core/hash.js\";\nimport {\n applyEdits,\n lineRemovals,\n removeFrontmatterCitations,\n spliceEntryField,\n unifiedDiff,\n} from \"../core/write.js\";\nimport { CiteError } from \"../errors.js\";\nimport type {\n CitationInput,\n InlineStatement,\n ManifestChange,\n Removal,\n RemoveOptions,\n RemovePage,\n RemoveRun,\n TextEdit,\n} from \"../types.js\";\nimport { assertNoOrphanJoins, assertNoOrphans, joinHits, prepareRun, readTarget } from \"./check.js\";\n\n/** How an entry with no id is named: its place in the page's list. */\nconst POINTER = /^\\/citations\\/(0|[1-9][0-9]*)$/;\n\n/** `4 entries`, `1 entry`. */\nfunction entryCount(n: number): string {\n return `${String(n)} ${n === 1 ? \"entry\" : \"entries\"}`;\n}\n\n/** The `id` of a raw entry, whether or not the schema would accept the rest of it. */\nfunction idOf(entry: unknown): string | undefined {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) return undefined;\n const id: unknown = (entry as Record<string, unknown>).id;\n return typeof id === \"string\" ? id : undefined;\n}\n\n/** What one page's run found, before anything is written. */\ninterface Planned {\n page: RemovePage;\n /** The page as it will be written, when it changed. */\n content?: string;\n /** Absolute path to write it to; absent for the stdin page. */\n path?: string;\n}\n\nexport async function runRemove(opts: RemoveOptions): Promise<RemoveRun> {\n // Repeats collapse, as they do on `--collection`: naming one entry twice\n // asks for one removal, and would otherwise be counted twice.\n const only = [...new Set(opts.only)];\n // Asked before the config is read: it is a usage error, and the answer does\n // not depend on anything on disk.\n if (only.length === 0) {\n throw new CiteError(\"remove needs --only <id>; it never removes every citation on a page.\");\n }\n // Nothing here resolves a source: the run builds no index, and says\n // nothing about where `src:` paths would have come from.\n const prepared = await prepareRun({ ...opts, checkSources: false }, \"removed\", \"remove\", {\n resolve: false,\n });\n const { run, files, usingStdin, forced } = prepared;\n await assertNoOrphans(prepared);\n const hits = joinHits();\n const manifests = new ManifestSet();\n /** Every `--only` value that named something, anywhere in the run. */\n const matched = new Set<string>();\n const pageCount = files.length + (usingStdin ? 1 : 0);\n\n const planned: Planned[] = [];\n const removeOne = async (label: string, content: string, path?: string): Promise<void> => {\n const setup = await prepared.setupFor(label, content);\n if (setup.sidecar !== undefined) hits.record(setup.sidecar, label);\n const owner = setup.sidecar?.owner;\n const page = readPage(label, content, {\n ...(forced === undefined ? {} : { format: forced.name }),\n ...(setup.options.citations === undefined ? {} : { citations: setup.options.citations }),\n ...(owner === undefined ? {} : { owned: { file: owner.file, collection: owner.collection } }),\n });\n const { format } = page;\n const extractor = pickExtractor(label, forced?.name);\n const inputs: CitationInput[] = citationInputs(\n label,\n extractor.extract(content, label),\n setup.sidecar?.citations,\n );\n const lines = splitLines(content);\n\n /** The entries one `--only` value names on this page. */\n const entriesFor = (value: string): number[] => {\n // The digits of a pointer, or nothing for a value that is an id. Read\n // as a capture rather than through `exec(...) !== null`, so the index\n // is a string the compiler has seen narrowed.\n const [, digits] = POINTER.exec(value) ?? [];\n if (digits === undefined) {\n return inputs.flatMap((input, index) => (idOf(input.entry) === value ? [index] : []));\n }\n const index = Number(digits);\n if (index < inputs.length) return [index];\n // A pointer is a position, so over several pages it means the entry at\n // that position wherever there is one. Against one page there is no\n // other page it could have meant.\n if (pageCount === 1) {\n throw new CiteError(\n `\"${value}\" is past the last entry of ${label} (${entryCount(inputs.length)}).`,\n );\n }\n return [];\n };\n /** The markers naming an id. */\n const markersFor = (id: string | undefined): InlineStatement[] =>\n id === undefined\n ? []\n : page.statements.filter(\n (s) => s.payload.kind === \"ref\" && s.payload.ids.includes(id),\n );\n /** Per marker line, the ids this run takes out of its list. */\n const dropped = new Map<number, { statement: InlineStatement; ids: Set<string> }>();\n const drop = (statement: InlineStatement, id: string): void => {\n const held = dropped.get(statement.line) ?? { statement, ids: new Set<string>() };\n held.ids.add(id);\n dropped.set(statement.line, held);\n };\n\n const removed: Removal[] = [];\n const indices = new Set<number>();\n const markerLines: number[] = [];\n for (const value of only) {\n const found = entriesFor(value);\n for (const index of found) {\n const input = inputs[index];\n const id = idOf(input?.entry);\n const markers = markersFor(id);\n indices.add(index);\n markerLines.push(...markers.map((s) => s.line));\n if (id !== undefined) for (const statement of markers) drop(statement, id);\n removed.push({\n ...(id === undefined ? {} : { id }),\n index,\n ...(input === undefined ? {} : { origin: input.origin }),\n markerLines: markers.map((s) => s.line),\n });\n matched.add(value);\n }\n if (found.length > 0) continue;\n // An id no entry carries, but a marker names: the marker alone.\n const markers = markersFor(value);\n if (markers.length === 0) continue;\n markerLines.push(...markers.map((s) => s.line));\n for (const statement of markers) drop(statement, value);\n removed.push({ id: value, markerLines: markers.map((s) => s.line) });\n matched.add(value);\n }\n const nothing: RemovePage = { file: label, removed: [], diff: \"\", written: false };\n if (removed.length === 0) {\n // The stdin page is printed whatever the run did to it.\n if (path === undefined) nothing.content = content;\n planned.push({ page: nothing, ...(path === undefined ? {} : { path }) });\n return;\n }\n\n // A marker sharing its line with text anchors that text, so the line is\n // not the tool's to delete. The refusal is a property of the line rather\n // than of the payload, so it holds however many ids the marker names.\n const touched = [...new Set(markerLines)].sort((a, b) => a - b);\n for (const line of touched) {\n if (!isMarkerLine(lines[line - 1] ?? \"\", format)) {\n const id = page.statements.find((s) => s.line === line)?.payload;\n const named = id?.kind === \"ref\" ? ` ${id.ids.join(\" \")}` : \"\";\n throw new CiteError(\n `the marker${named} at ${label}:${String(line)} shares its line with text; remove it by hand.`,\n );\n }\n }\n // A marker that keeps an id keeps its line: the word goes out of the list\n // and nothing below it moves. Only a marker that loses its last id is a\n // line to delete (proposal 0056).\n const kept = new Map<number, [string, ...string[]]>();\n const ordered: number[] = [];\n for (const line of touched) {\n const held = dropped.get(line);\n // Destructured rather than cast: a marker that keeps nothing is a line\n // to delete, and the head is what tells the two apart.\n const [head, ...rest] =\n held === undefined || held.statement.payload.kind !== \"ref\"\n ? []\n : held.statement.payload.ids.filter((id) => !held.ids.has(id));\n if (head === undefined) ordered.push(line);\n else kept.set(line, [head, ...rest]);\n }\n\n // What stays, moved up by the marker lines going out above it.\n const survivors = page.citations.filter((c) => !indices.has(c.origin.index));\n const shifted = shiftedEntries({\n citations: survivors,\n at: ordered,\n delta: -1,\n bodyLine: page.bodyLine,\n label,\n });\n\n // One parse, one pass.\n //\n // Every position the body rewrite reads -- a statement's byte offsets, a\n // marker's line number -- is read against `content`, the page as it was\n // parsed, and the edits are collected as spans and applied together. So no\n // offset is used after the text it indexes has changed, and no writer has\n // to run before or after another to be correct. The ordering contract this\n // carried is gone rather than satisfied: it was got wrong three times, in\n // three review rounds, and each time silently -- the edit lands nowhere,\n // the entry leaves the frontmatter, and the marker still names the id\n // until some later `cite check` reports a `marker-orphan` with nothing to\n // explain it.\n const edits: TextEdit[] = [];\n for (const [line, ids] of kept) {\n const held = dropped.get(line);\n if (held === undefined) continue;\n const edit = respellEdit(content, held.statement, ids);\n // `content` is the text the statement was parsed from, so the payload is\n // where the statement says it is. A miss would mean the parse and the\n // page disagree, which is worth stopping for rather than writing a page\n // whose marker still names an id no entry has.\n if (edit === undefined) {\n throw new CiteError(\n `manni cannot read the marker at ${label}:${String(line)} to rewrite it; remove it by hand.`,\n );\n }\n edits.push(edit);\n }\n // The marker lines that lost their last id, taken out with their\n // terminators. Neighbours merge into one span, so no two of them reach for\n // the same break.\n edits.push(...lineRemovals(content, ordered));\n let after = applyEdits(content, edits);\n // Then the frontmatter. Both of its writers re-derive their own position\n // from the text they are handed -- `spliceEntryField` by re-extracting,\n // `removeFrontmatterCitations` by re-reading the list -- so neither reads\n // anything out of the parse above and neither cares what the body pass\n // did. The splice still runs before the removal, but for a different\n // reason: its `index` counts the entries the page has now, and the removal\n // is what renumbers them.\n for (const { index, lines: moved } of shifted.frontmatter) {\n after = spliceEntryField(after, format, index, [\"claim\", \"lines\"], moved);\n }\n if (owner === undefined) {\n after = removeFrontmatterCitations(after, format, indices, label);\n } else {\n if (setup.sidecar?.entry === undefined) {\n throw new CiteError(\n `${label} carries no ${owner.join}: value, so its citations cannot be keyed in ${owner.file}.`,\n );\n }\n const kept = inputs\n .map((input, index) => {\n const moved = shifted.manifest.get(index);\n return moved === undefined ? input.entry : withClaimLines(input.entry, moved);\n })\n .filter((_entry, index) => !indices.has(index));\n if (kept.length === 0) await manifests.remove(owner, setup.sidecar.entry);\n // The line a written entry sits on is what `add` reports; a removal\n // reports the line the entry sat on before, from its origin. So the\n // answer is dropped here, and the index it is measured from is any\n // index at all.\n else void (await manifests.write(owner, setup.sidecar.entry, kept, 0));\n }\n\n const out: RemovePage = {\n file: label,\n removed,\n diff: after === content ? \"\" : unifiedDiff(label, content, after),\n written: false,\n };\n // The stdin page has nowhere to be written; the caller prints it instead.\n if (path === undefined) out.content = after;\n planned.push({ page: out, ...(after === content ? {} : { content: after }), ...(path === undefined ? {} : { path }) });\n };\n\n if (usingStdin) await removeOne(STDIN_LABEL, opts.stdinContent ?? \"\");\n for (const file of files) {\n await removeOne(file, await readTarget(run, file), resolve(run.base, file));\n }\n assertNoOrphanJoins(prepared, hits);\n\n // Every name has to have been found somewhere before a byte is written.\n const missing = only.find((value) => !matched.has(value));\n if (missing !== undefined) {\n const where =\n pageCount === 1\n ? `${planned[0]?.page.file ?? \"the page\"} has no`\n : `none of ${String(pageCount)} pages has an`;\n const what = POINTER.test(missing) ? `entry ${missing}` : `entry or marker ${missing}`;\n throw new CiteError(`${where} ${what}.`);\n }\n\n const write = opts.dryRun !== true;\n for (const item of planned) {\n if (item.content === undefined || item.path === undefined) continue;\n if (write) await writeFileAtomic(item.path, item.content);\n item.page.written = write;\n }\n const rewritten: ManifestChange[] = [];\n const record = (changed: { file: string; diff: string }): void => {\n rewritten.push({ file: changed.file, diff: changed.diff, written: write });\n };\n if (write) await manifests.commit({ after: record });\n else for (const changed of manifests.changed()) record(changed);\n\n const pages = planned.map((item) => item.page);\n return {\n pages,\n removed: pages.reduce((n, page) => n + page.removed.length, 0),\n ...(rewritten.length > 0 ? { manifests: rewritten } : {}),\n };\n}\n","/**\n * `manni cite update`: repair what moved; with `--accept`, re-pin what changed.\n *\n * A moved end gets its `lines` spliced where it stands, so comments and\n * quoting are untouched: `claim.lines` for a claim found verbatim elsewhere on\n * the page, `source.lines` for a source found elsewhere in its file. A moved\n * source is re-minted over the range it moved to, so its `commit-sha` names a\n * commit its new lines are true at. A marker never moves, because it travels\n * with its own text.\n *\n * `--accept` re-pins a changed end. A claim is re-pinned over the paragraph,\n * fenced block or table rows now at its first line, and the report prints that\n * text, so the log shows exactly what was accepted. A paragraph grows with the\n * sentence it gained; a table keeps the number of rows the claim was minted\n * over, because a row is a statement of its own. A claim it cannot re-pin is\n * skipped with the reason named, and a sentence that was reworded *and* moved\n * is an `add` again. A source is re-minted at HEAD, with a new `commit-sha`\n * where the entry records one.\n *\n * Every finding the run did not resolve is reported as skipped, and an\n * error-severity one is work left undone: exit 1, as `fill` has it. Writes by\n * default (0025).\n */\nimport { resolve } from \"node:path\";\nimport { writeFileAtomic } from \"../../meta/index.js\";\nimport { STDIN_LABEL } from \"../../meta/internal.js\";\nimport { checkCitations } from \"../core/check-page.js\";\nimport {\n noUnitAt,\n normalizeWhitespace,\n otherClaimSpans,\n pinOfLines,\n spellElsewhere,\n toBodyLines,\n toFileLines,\n unitAt,\n type ClaimUnit,\n type NoUnit,\n} from \"../core/claims.js\";\nimport { historyOf } from \"../core/classify.js\";\nimport { GIT_UNAVAILABLE_COMMIT, SHALLOW_RECOMMIT } from \"../core/git.js\";\nimport { splitLines } from \"../core/hash.js\";\nimport { claimWords, sharesSentence, wordShare } from \"../core/history.js\";\nimport { mintCitation } from \"../core/mint.js\";\nimport { ManifestSet } from \"../core/manifest.js\";\nimport { readPage } from \"../core/page.js\";\nimport {\n formatSrc,\n lineSpec,\n parseLines,\n parseSrc,\n sourceRange,\n spellLines,\n tooWide,\n} from \"../core/range.js\";\nimport {\n applyMarkerMoves,\n misplacedMarkers,\n type MisplacedMarker,\n} from \"../core/reanchor.js\";\nimport { resolveSeverity } from \"../core/severity.js\";\nimport { listOf, spellAt } from \"../core/spell.js\";\nimport { anchoredLines, markerIndent, offsetOfLine } from \"../core/statements.js\";\nimport { spliceEntryField, unifiedDiff } from \"../core/write.js\";\nimport { CiteError } from \"../errors.js\";\nimport type {\n Citation,\n CitationResult,\n CiteRule,\n ClaimEnd,\n LineSpec,\n ManifestChange,\n PageCitation,\n PageCitationReport,\n PageCitations,\n PageLines,\n RecommitReason,\n UpdateOptions,\n UpdatePage,\n UpdateRewrite,\n UpdateRun,\n} from \"../types.js\";\nimport {\n assertNoOrphanJoins,\n assertNoOrphans,\n joinHits,\n prepareRun,\n readTarget,\n sayNotices,\n} from \"./check.js\";\n\ntype Plan =\n | { kind: \"claim-moved\"; result: CitationResult; lines: LineSpec; from: string; to: string }\n /**\n * The pinned lines sit elsewhere in the file now. The entry is re-minted\n * over them, so its `lines`, its `integrity` and its `commit-sha` are three\n * parts of one reading rather than two new ones and a stale third.\n */\n | {\n kind: \"source-moved\";\n result: CitationResult;\n /** The new `source.lines`; absent for a whole-file pin, which has none. */\n lines?: LineSpec;\n /**\n * The new `source.file`, when the pin followed its text into another\n * file. The entry's own `commit-sha` is then left alone: the pin was\n * minted at that commit and still holds, so HEAD would record a mint\n * that never happened (proposal 0055).\n */\n file?: string;\n /** The pin the entry carries afterwards. */\n pin: string;\n /** The commit to advance to, for a move inside the entry's own file. */\n commitSha?: string;\n to: string;\n }\n | {\n kind: \"claim-accepted\";\n result: CitationResult;\n unit: ClaimUnit;\n pin: string;\n lines?: LineSpec;\n /**\n * The line held wholly other text and `--only` named the entry, so the\n * accept stands. The report says so rather than reading as an edit.\n */\n replaced?: true;\n /** The marker's line on the page this run leaves, where one anchors. */\n markerLine?: number;\n }\n /**\n * A changed source, re-pinned at HEAD. Where the in-range search found the\n * old first and last line, the re-mint covers the span they bracket rather\n * than the recorded range, and `source.lines` follows it (proposal 0055).\n */\n | {\n kind: \"source-accepted\";\n result: CitationResult;\n minted: Citation;\n /** The span accepted, when it is not the range the entry records. */\n span?: { lines: LineSpec; from: string; to: string };\n }\n /**\n * The source holds, but the commit it is recorded against does not contain\n * the pinned lines, or is not in the history of HEAD. Only `commit-sha`\n * moves; the pin itself is untouched.\n */\n | {\n kind: \"source-recommitted\";\n result: CitationResult;\n /** The commit the entry records now, and cannot support. */\n from: string;\n /** HEAD, which was checked to contain the lines before this was planned. */\n commitSha: string;\n because: RecommitReason;\n }\n | { kind: \"marker-moved\"; result: CitationResult; from: number; to: number }\n | {\n kind: \"claim-reanchored\";\n result: CitationResult;\n pin: string;\n /** The span that held, in file lines, and the span now pinned. */\n held: string;\n now: string;\n }\n | {\n kind: \"claim-shifted\";\n result: CitationResult;\n lines: LineSpec;\n from: string;\n to: string;\n }\n /**\n * The words the pin covered are unchanged and only the layout moved\n * (proposal 0053). A plain `update` re-pins it, and rewrites its `lines:`\n * when the entry has them.\n */\n | {\n kind: \"claim-words-held\";\n result: CitationResult;\n pin: string;\n /** The file line of the claim's first body line, after any marker move. */\n at: number;\n /** The stored span and the span now pinned, in file lines. */\n fromLines: string;\n toLines: string;\n commitSha?: string;\n lines?: LineSpec;\n }\n /**\n * A changed claim `--accept` refused to re-pin: the line now holds text\n * sharing no sentence with the claim at its baseline, or too few of its\n * words. Nothing is written.\n */\n | {\n kind: \"claim-replaced\";\n result: CitationResult;\n at: number;\n commitSha: string;\n /** The share of the claim's words held, when overlap is what refused it. */\n wordShare?: number;\n /** The pin that stands, and the one that was not written. */\n pin: string;\n would: string;\n };\n\n/**\n * Why one repair was declined, and the rule whose finding says so. One entry\n * can carry findings about both ends, so the reason names which it is about.\n */\ninterface Declined {\n rule: string;\n why: string;\n}\n\n/**\n * Why `--accept` re-pinned nothing at the claim's line, said plainly. Each\n * reason is a different problem: a blank line lost the sentence, a claim that\n * runs out of its fenced block covers a fence rather than code, a line that\n * starts no paragraph is a heading underline or an unclosed fence, a line\n * outside the body is a range the page no longer reaches, a short table lost\n * rows the claim was minted over, and a marker or a table rule is a line that\n * holds no claim text at all.\n */\nfunction sayNoUnit(reason: NoUnit): string {\n switch (reason) {\n case \"outside\":\n return \"the line is outside the page body\";\n case \"blank\":\n return \"the line is blank\";\n case \"fence-crossed\":\n return \"the claim's lines are not all inside one fenced block\";\n case \"marker\":\n return \"that line now holds a cite marker, not claim text\";\n case \"not-a-paragraph\":\n return \"the line does not start a paragraph\";\n case \"table-short\":\n return \"the table no longer holds every row the claim covers\";\n case \"table-rule\":\n return \"that line is a table rule, not claim text\";\n }\n}\n\n/** A unit named in a refusal. `fenced-lines` is a span of code, not a block. */\nfunction unitNoun(kind: ClaimUnit[\"kind\"]): string {\n return kind === \"fenced-lines\" ? \"fenced text\" : kind;\n}\n\n/** The rule a plan settles, so its finding is not also reported as skipped. */\nfunction settles(plan: Plan): string {\n switch (plan.kind) {\n case \"claim-moved\":\n return \"claim-moved\";\n case \"source-moved\":\n return \"source-moved\";\n case \"claim-accepted\":\n return \"claim-changed\";\n case \"source-accepted\":\n return plan.result.source.status === \"never-true\" ? \"source-never-true\" : \"source-changed\";\n case \"marker-moved\":\n return \"marker-misplaced\";\n case \"claim-reanchored\":\n return \"claim-moved\";\n case \"claim-words-held\":\n return \"claim-reanchored\";\n // A refused claim leaves nothing written, but its finding is the row the\n // refusal prints, so it is not also reported as skipped.\n case \"claim-replaced\":\n return \"claim-changed\";\n // A shifted entry was `current`, so it had no finding to settle. A\n // re-committed one was `current` too: `check` never reported it, which is\n // why the repair is asked for rather than offered.\n case \"claim-shifted\":\n case \"source-recommitted\":\n return \"\";\n }\n}\n\nfunction apply(content: string, format: string, plan: Plan): string {\n const index = plan.result.origin.index;\n switch (plan.kind) {\n case \"claim-moved\":\n case \"claim-shifted\":\n return spliceEntryField(content, format, index, [\"claim\", \"lines\"], plan.lines);\n case \"claim-reanchored\":\n return spliceEntryField(content, format, index, [\"claim\", \"integrity\"], plan.pin);\n case \"claim-words-held\": {\n let out = spliceEntryField(content, format, index, [\"claim\", \"integrity\"], plan.pin);\n if (plan.lines !== undefined) {\n out = spliceEntryField(out, format, index, [\"claim\", \"lines\"], plan.lines);\n }\n return out;\n }\n // Nothing is written for a refused claim; the report is the whole of it.\n case \"claim-replaced\":\n // The move is a page rewrite, applied to the whole page before any splice.\n case \"marker-moved\":\n return content;\n case \"source-moved\": {\n let out = content;\n if (plan.file !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"file\"], plan.file);\n }\n if (plan.lines !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"lines\"], plan.lines);\n }\n out = spliceEntryField(out, format, index, [\"source\", \"integrity\"], plan.pin);\n // As on a re-mint: HEAD is written only where the entry already records\n // a commit, because the splice replaces a scalar and never adds a key.\n if (plan.commitSha !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"commit-sha\"], plan.commitSha);\n }\n return out;\n }\n case \"source-recommitted\":\n return spliceEntryField(content, format, index, [\"source\", \"commit-sha\"], plan.commitSha);\n case \"claim-accepted\": {\n let out = spliceEntryField(content, format, index, [\"claim\", \"integrity\"], plan.pin);\n if (plan.lines !== undefined) {\n out = spliceEntryField(out, format, index, [\"claim\", \"lines\"], plan.lines);\n }\n return out;\n }\n case \"source-accepted\": {\n let out = content;\n if (plan.span !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"lines\"], plan.span.lines);\n }\n out = spliceEntryField(\n out,\n format,\n index,\n [\"source\", \"integrity\"],\n plan.minted.source.integrity,\n );\n const commit = plan.minted.source[\"commit-sha\"];\n // An entry with no `commit-sha:` line of its own keeps none: the splice\n // replaces a scalar, it does not add a key.\n if (commit !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"commit-sha\"], commit);\n }\n return out;\n }\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The same repair, against an entry that lives in a manifest. The page's\n * whole `citations` value is written back at the end of the run, so a repair\n * here is an edit to the parsed entry rather than a splice of one scalar.\n * An entry the writer cannot reach — a list item that is not a mapping —\n * leaves its finding reported.\n */\nfunction applyToEntry(entry: unknown, plan: Plan): boolean {\n if (!isRecord(entry)) return false;\n const end = (name: \"claim\" | \"source\"): Record<string, unknown> | undefined =>\n isRecord(entry[name]) ? entry[name] : undefined;\n switch (plan.kind) {\n case \"claim-moved\":\n case \"claim-shifted\": {\n const claim = end(\"claim\");\n if (claim === undefined) return false;\n claim.lines = plan.lines;\n return true;\n }\n case \"claim-reanchored\": {\n const claim = end(\"claim\");\n if (claim === undefined) return false;\n claim.integrity = plan.pin;\n return true;\n }\n case \"claim-words-held\": {\n const claim = end(\"claim\");\n if (claim === undefined) return false;\n claim.integrity = plan.pin;\n if (plan.lines !== undefined) claim.lines = plan.lines;\n return true;\n }\n // Nothing is written for a refused claim.\n case \"claim-replaced\":\n // The page holds the marker, so the manifest has nothing to change.\n case \"marker-moved\":\n return true;\n case \"source-moved\": {\n const source = end(\"source\");\n if (source === undefined) return false;\n if (plan.file !== undefined) source.file = plan.file;\n if (plan.lines !== undefined) source.lines = plan.lines;\n source.integrity = plan.pin;\n if (plan.commitSha !== undefined) source[\"commit-sha\"] = plan.commitSha;\n return true;\n }\n case \"source-recommitted\": {\n const source = end(\"source\");\n if (source === undefined) return false;\n source[\"commit-sha\"] = plan.commitSha;\n return true;\n }\n case \"claim-accepted\": {\n const claim = end(\"claim\");\n if (claim === undefined) return false;\n claim.integrity = plan.pin;\n if (plan.lines !== undefined) claim.lines = plan.lines;\n return true;\n }\n case \"source-accepted\": {\n const source = end(\"source\");\n if (source === undefined) return false;\n if (plan.span !== undefined) source.lines = plan.span.lines;\n source.integrity = plan.minted.source.integrity;\n const commit = plan.minted.source[\"commit-sha\"];\n // As on a page: a re-mint records a commit only where the entry\n // already recorded one, so this never adds the key.\n if (commit !== undefined) source[\"commit-sha\"] = commit;\n return true;\n }\n }\n}\n\nfunction rewriteOf(plan: Plan): UpdateRewrite {\n const { citation, origin, source } = plan.result;\n const base: Pick<UpdateRewrite, \"id\" | \"index\" | \"line\"> = { index: origin.index };\n if (citation.id !== undefined) base.id = citation.id;\n if (origin.line !== undefined) base.line = origin.line;\n\n switch (plan.kind) {\n case \"claim-moved\":\n return {\n ...base,\n end: \"claim\",\n reason: \"moved\",\n status: \"moved\",\n from: plan.from,\n to: plan.to,\n fromLines: plan.from,\n toLines: plan.to,\n };\n case \"marker-moved\": {\n const from = String(plan.from);\n const to = String(plan.to);\n return {\n ...base,\n end: \"marker\",\n reason: \"re-anchored\",\n status: \"misplaced\",\n from,\n to,\n fromLines: from,\n toLines: to,\n };\n }\n case \"claim-reanchored\": {\n const was = citation.claim?.integrity ?? \"\";\n return {\n ...base,\n end: \"claim\",\n reason: \"re-anchored\",\n status: \"moved\",\n from: was,\n to: plan.pin,\n fromPin: was,\n toPin: plan.pin,\n lines: plan.held,\n newLines: plan.now,\n };\n }\n case \"claim-words-held\": {\n const was = citation.claim?.integrity ?? \"\";\n const out: UpdateRewrite = {\n ...base,\n end: \"claim\",\n reason: \"re-anchored\",\n status: \"reanchored\",\n from: was,\n to: plan.pin,\n fromPin: was,\n toPin: plan.pin,\n fromLines: plan.fromLines,\n toLines: plan.toLines,\n at: plan.at,\n };\n if (plan.commitSha !== undefined) out.commitSha = plan.commitSha;\n return out;\n }\n case \"claim-replaced\":\n return {\n ...base,\n end: \"claim\",\n reason: \"replaced\",\n status: \"changed\",\n from: plan.pin,\n to: plan.would,\n fromPin: plan.pin,\n toPin: plan.would,\n at: plan.at,\n commitSha: plan.commitSha,\n ...(plan.wordShare === undefined ? {} : { wordShare: plan.wordShare }),\n };\n case \"claim-shifted\":\n return {\n ...base,\n end: \"claim\",\n reason: \"shifted\",\n status: \"current\",\n from: plan.from,\n to: plan.to,\n fromLines: plan.from,\n toLines: plan.to,\n };\n case \"source-moved\":\n return {\n ...base,\n end: \"source\",\n reason: \"moved\",\n status: \"moved\",\n from: source.src,\n to: plan.to,\n };\n case \"source-recommitted\":\n return {\n ...base,\n end: \"source\",\n reason: \"recommitted\",\n // The source itself held. Only its date was wrong.\n status: \"current\",\n because: plan.because,\n from: plan.from,\n to: plan.commitSha,\n fromCommit: plan.from,\n toCommit: plan.commitSha,\n src: source.src,\n };\n case \"claim-accepted\": {\n const was = citation.claim?.integrity ?? \"\";\n const out: UpdateRewrite = {\n ...base,\n end: \"claim\",\n reason: \"accepted\",\n // A bypassed guard reads `replaced`, so the log shows that the line\n // held other text and a named accept took it anyway.\n status: plan.replaced === true ? \"replaced\" : \"changed\",\n from: was,\n to: plan.pin,\n fromPin: was,\n toPin: plan.pin,\n at: plan.unit.lines.start,\n text: quoted(plan.unit.text),\n };\n // A re-pin over a unit wider than the stored lines names both spans.\n const stored = plan.result.claim?.fileLines;\n const now = spellLines(plan.unit.lines);\n if (stored !== undefined && stored !== now) {\n out.fromLines = stored;\n out.toLines = now;\n }\n // Where the report says the claim is: its marker, when one anchors it.\n // A marker this run moved reads at the line it now sits on, so the row\n // and the move above it name one line rather than two.\n const markerLine =\n plan.markerLine ?? (plan.result.anchor === \"marker\" ? plan.result.markerLine : undefined);\n if (markerLine !== undefined) out.markerLine = markerLine;\n return out;\n }\n case \"source-accepted\": {\n const out: UpdateRewrite = {\n ...base,\n end: \"source\",\n reason: \"accepted\",\n status: source.status === \"never-true\" ? \"never-true\" : \"changed\",\n from: citation.source.integrity,\n to: plan.minted.source.integrity,\n fromPin: citation.source.integrity,\n toPin: plan.minted.source.integrity,\n src: source.src,\n };\n // A re-mint over the span the old first and last line now bracket names\n // both ranges, so the acceptance says which lines it accepted.\n if (plan.span !== undefined) {\n out.fromLines = plan.span.from;\n out.toLines = plan.span.to;\n }\n const commit = plan.minted.source[\"commit-sha\"];\n if (commit !== undefined) out.commitSha = commit;\n return out;\n }\n }\n}\n\n/**\n * How much of the claim's words its line must still hold for a blanket\n * `--accept` to re-pin it, as `wordShare` measures it.\n *\n * A replay of 65 proposed `--accept` re-pins over this repository's own\n * corpus, every one with a baseline to read, put the seven wrong re-pins at\n * 0.38 and below and every safe one at 0.74 and above. Each of the seven had\n * drifted onto a neighbouring table row, and the sentence test below let all\n * seven through. Nothing measured landed between the two bands, so the number\n * is fixed here. A config key would be a knob over a gap no corpus fills.\n */\nconst CLAIM_WORD_SHARE = 0.5;\n\n/** Why a re-pin was refused: the baseline, and the share when overlap is what fired. */\ninterface Replacement {\n /** The baseline the claim's words were read against. */\n commit: string;\n /** Set only when the overlap test fired: the share of the claim's words held. */\n share?: number;\n}\n\n/**\n * Why a re-pin over `text` would bless a line that no longer carries the\n * claim: a neighbouring table row after a shift, or a block inserted under a\n * marker. `undefined` lets the accept stand, which is also what happens with\n * no baseline to read the claim against.\n *\n * Two tests, either of which refuses. The first is sentence intersection: a\n * claim whose paragraph was edited still shares a sentence with what it said\n * at the baseline, and one whose line was replaced outright shares none. The\n * second is word overlap, for the drift the first misses. Two rows of one\n * table end alike often enough to share a sentence while saying different\n * things, so a line holding less than `CLAIM_WORD_SHARE` of the claim's words\n * is refused too, and the report names the share.\n *\n * The guard only asks about an entry the run did not name. Naming an id with\n * `--only` is the human judgement the guard exists to demand, so a reviewer\n * who has read the claim and its source re-pins a reworded sentence without a\n * remove and an add. What the guard is for is a blanket `--accept` quietly\n * re-pinning a hundred claims, one of which now holds a neighbouring table\n * row. A bypass is reported rather than hidden.\n */\nfunction replacementAt(\n claim: ClaimEnd,\n text: readonly string[],\n format: string,\n): Replacement | undefined {\n const was = claim.baselineText;\n const commit = claim.commitSha;\n if (was === undefined || commit === undefined) return undefined;\n const before = claimWords(was, format);\n const now = claimWords(text, format);\n if (!sharesSentence(before, now)) return { commit };\n const share = wordShare(before, now);\n if (share < CLAIM_WORD_SHARE) return { commit, share };\n return undefined;\n}\n\n/** How many characters of re-pinned text the report quotes before it elides. */\nconst QUOTE_CAP = 200;\n\n/**\n * The text a re-pin quotes: whitespace collapsed, and capped, because the\n * unit may be a whole paragraph and the report is one line per rewrite.\n */\nfunction quoted(text: readonly string[]): string {\n const all = normalizeWhitespace(text.join(\"\\n\"));\n return all.length <= QUOTE_CAP ? all : `${all.slice(0, QUOTE_CAP)}…`;\n}\n\n/** `<id>: <text>`, or the text alone for an entry with no id. */\nfunction named(id: string | undefined, text: string): string {\n return id === undefined ? text : `${id}: ${text}`;\n}\n\n/** One misplaced marker `update` left where it is, and the rule its line reads at. */\ninterface MarkerStay {\n line: number;\n rule: CiteRule;\n message: string;\n}\n\n/** What `update` will do to a page's misplaced markers. */\ninterface MarkerDecisions {\n moves: { result: CitationResult; entry: PageCitation; misplaced: MisplacedMarker }[];\n stays: MarkerStay[];\n}\n\n/**\n * A claim-lines entry the move would change: one whose range holds the\n * marker's line, or starts above the unit and reaches the place the marker\n * goes. Moving the marker would rewrite that entry's pinned text.\n */\nfunction crossing(\n page: PageCitations,\n misplaced: MisplacedMarker,\n): string | undefined {\n for (const other of page.citations) {\n const spec = other.citation.claim?.lines;\n const recorded = spec === undefined ? undefined : parseLines(spec);\n if (recorded === undefined) continue;\n const file = toFileLines(recorded, page.bodyLine);\n const holdsMarker = file.start <= misplaced.line && misplaced.line <= file.end;\n const holdsPlace = file.start < misplaced.place && misplaced.place <= file.end;\n if (!holdsMarker && !holdsPlace) continue;\n return other.citation.id === undefined\n ? `the claim at ${spellAt(file)}`\n : `the claim of ${other.citation.id} (${spellAt(file)})`;\n }\n return undefined;\n}\n\n/**\n * Which of a page's misplaced markers move, and why each of the rest stays.\n * Every decision is taken against the page as it was read, before any write.\n */\nfunction decideMarkers(input: {\n page: PageCitations;\n report: PageCitationReport;\n lines: readonly string[];\n accept: boolean;\n only?: Set<string>;\n}): MarkerDecisions {\n const { page, report, lines, accept, only } = input;\n const out: MarkerDecisions = { moves: [], stays: [] };\n for (const misplaced of misplacedMarkers(page, lines)) {\n const entry = misplaced.entry;\n const line = misplaced.line;\n const stay = (rule: CiteRule, message: string): void => {\n out.stays.push({ line, rule, message });\n };\n // An orphan, repeated or invalid marker names no entry that can be\n // checked, and `--only` selects entries, so it selects their markers.\n if (entry === undefined) {\n if (only !== undefined) continue;\n const own = report.findings.find(\n (finding) => finding.line === line && finding.rule.startsWith(\"marker-\") && finding.rule !== \"marker-misplaced\",\n );\n stay(\n own?.rule ?? \"marker-orphan\",\n `the marker at line ${String(line)} stays, because it names no entry update can check.`,\n );\n continue;\n }\n const id = entry.citation.id;\n if (only !== undefined && (id === undefined || !only.has(id))) continue;\n const result = report.citations.find((r) => r.origin.index === entry.origin.index);\n if (result === undefined) continue;\n // Claim lines and a marker both: neither anchor can be trusted.\n if (entry.citation.claim?.lines !== undefined) {\n stay(\n \"anchor-invalid\",\n named(id, `the marker at line ${String(line)} stays, because the entry also has claim lines. Keep one.`),\n );\n continue;\n }\n const across = crossing(page, misplaced);\n if (across !== undefined) {\n stay(\n \"marker-misplaced\",\n named(id, `the marker at line ${String(line)} stays, because moving it would change ${across}.`),\n );\n continue;\n }\n if (result.claim !== null && result.claim.status === \"changed\" && !accept) {\n stay(\n \"marker-misplaced\",\n named(\n id,\n `the marker at line ${String(line)} stays, because its claim changed since it was pinned. update --accept moves it and re-pins.`,\n ),\n );\n continue;\n }\n out.moves.push({ result, entry, misplaced });\n }\n return out;\n}\n\n/**\n * The lines the span an entry's marker anchors covers on the page as it now\n * stands, and the pin over them.\n */\nfunction anchoredNow(\n content: string,\n format: string,\n lines: readonly string[],\n markerLine: number,\n quote: boolean,\n): { span: PageLines; pin: string } | undefined {\n const at = offsetOfLine(content, markerLine) + (lines[markerLine - 1]?.length ?? 0);\n const span = anchoredLines(content, at, format, quote);\n if (span === undefined) return undefined;\n const pin = pinOfLines(lines, span);\n return pin === undefined ? undefined : { span, pin };\n}\n\n/** The errno a failed write carries, when it carries one. */\nfunction codeOf(error: unknown): string | undefined {\n if (typeof error !== \"object\" || error === null || !(\"code\" in error)) return undefined;\n const code: unknown = error.code;\n return typeof code === \"string\" ? code : undefined;\n}\n\n/**\n * A run writes a page and the manifest that keys it, and a marker move needs\n * both to land. So every file this run wrote, page and manifest alike, keeps\n * its original text until the run is done, and a failed write puts them back.\n * A manifest left pinned to text its page no longer holds would read as drift\n * that never happened.\n */\nclass WrittenFiles {\n private readonly before = new Map<string, string>();\n private readonly labels = new Map<string, string>();\n\n /** Remember what `path` held before this run wrote it. */\n record(path: string, label: string, content: string): void {\n if (!this.before.has(path)) {\n this.before.set(path, content);\n this.labels.set(path, label);\n }\n }\n\n /**\n * Put every file back, and say what happened: `<file> could not be written\n * (<code>). <pages> was restored.`\n */\n async restore(file: string, error: unknown): Promise<CiteError> {\n const restored: string[] = [];\n const failed: string[] = [];\n for (const [path, content] of this.before) {\n const label = this.labels.get(path) ?? path;\n try {\n await writeFileAtomic(path, content);\n restored.push(label);\n } catch {\n failed.push(label);\n }\n }\n const code = codeOf(error);\n const why = code === undefined ? \"\" : ` (${code})`;\n const parts = [`${file} could not be written${why}.`];\n if (restored.length > 0) {\n parts.push(`${listOf(restored)} ${restored.length === 1 ? \"was\" : \"were\"} restored.`);\n }\n if (failed.length > 0) {\n parts.push(\n `${listOf(failed)} could not be restored, and ${failed.length === 1 ? \"holds\" : \"hold\"} an intermediate state.`,\n );\n }\n return new CiteError(parts.join(\" \"));\n }\n}\n\n/**\n * Citations counted as a summary counts them: an entry whose marker moved and\n * whose claim was re-pinned is one citation, not two.\n */\nfunction citationsIn(rows: readonly UpdateRewrite[]): number {\n const withMarker = new Set(rows.filter((row) => row.end === \"marker\").map((row) => row.index));\n return withMarker.size + rows.filter((row) => !withMarker.has(row.index)).length;\n}\n\nexport async function runUpdate(opts: UpdateOptions): Promise<UpdateRun> {\n const prepared = await prepareRun(opts, \"updated\", \"update\", { require: true });\n const { run, files, usingStdin, forced, pageOptions, git } = prepared;\n await assertNoOrphans(prepared);\n const hits = joinHits();\n // Each manifest is read once and written once, however many of its pages\n // the run repairs.\n const manifests = new ManifestSet();\n // What every file this run wrote held before, so a failed write is undone.\n const writes = new WrittenFiles();\n const only = opts.only !== undefined && opts.only.length > 0 ? new Set(opts.only) : undefined;\n const accept = opts.accept === true;\n const recommit = opts.recommit === true;\n if (recommit && !(await git.available())) {\n throw new CiteError(\n \"--recommit needs git to verify recorded commits, and git is not available here.\",\n );\n }\n\n /**\n * Whether `commit` is outside the history of `head`. Only a client that can\n * answer both questions, in a clone that is not shallow, says yes. A shallow\n * clone lacks commits that are in the history, so it cannot tell them from\n * a squash merge's orphans.\n */\n const outsideHistory = async (commit: string, head: string): Promise<boolean> => {\n if (git.shallow === undefined || git.isAncestor === undefined) return false;\n if (await git.shallow()) return false;\n return !(await git.isAncestor(commit, head));\n };\n\n /**\n * The commit to record for an entry whose recorded one cannot stand, and\n * why, or `undefined` to leave the entry alone.\n *\n * Three questions. First, is the recorded commit in the history of HEAD? A\n * squash merge leaves a branch commit that main never took, and it may well\n * hold the lines. Second, for a commit in the history, does it contain the\n * lines? It counts as containing them wherever in the file they sit,\n * because `update` follows a move and keeps `commit`, so line drift inside\n * one commit is the tool working rather than damage. Only a pin found\n * nowhere there is unsupported. Third, does HEAD contain them? The entry is\n * `current`, so the working tree does, but an uncommitted edit means HEAD\n * may not, and there is then no commit worth recording. The two questions\n * about lines are asked through `historyOf`, which is what `check` uses, so\n * the answers agree.\n *\n * In a full clone, a commit git cannot read fails the first question, so it\n * is re-recorded. A shallow clone cannot ask the first question. There such\n * a commit answers the second with neither yes nor no, and is left alone.\n */\n const recommitFor = async (\n result: CitationResult,\n ): Promise<{ commit: string; because: RecommitReason } | undefined> => {\n const recorded = result.citation.source[\"commit-sha\"];\n const path = result.source.resolvedPath;\n if (recorded === undefined || path === undefined) return undefined;\n const head = await git.head();\n if (head === null || head === recorded) return undefined;\n const range = sourceRange(result.citation.source);\n const pin = result.citation.source.integrity;\n const key = range.encrypted ? run.key : undefined;\n // History first. It is one memoized `merge-base` per commit, where\n // containment is one `git show` per commit and path. A commit outside the\n // history is re-recorded whatever it holds, so its file is never read.\n let because: RecommitReason;\n if (await outsideHistory(recorded, head)) because = \"not-in-history\";\n else {\n const was = await historyOf(git, recorded, path, range, pin, key, undefined);\n if (was.kind !== \"never-true\") return undefined;\n because = \"not-contained\";\n }\n // `original` means HEAD holds the pinned bytes, at the recorded lines or\n // anywhere else in the file. That is the same reading as question one, so\n // the two answers are comparable.\n const now = await historyOf(git, head, path, range, pin, key, undefined);\n return now.kind === \"original\" ? { commit: head, because } : undefined;\n };\n\n /** What this citation needs, in the order the repairs are worth trying. */\n const plansFor = async (\n result: CitationResult,\n entry: PageCitation | undefined,\n page: PageCitations,\n lines: readonly string[],\n lineNow: (line: number) => number,\n declined: Map<number, Declined>,\n ): Promise<Plan[]> => {\n const out: Plan[] = [];\n const claim = result.claim;\n // A marker-anchored claim has no `lines:` to splice; its repair is a\n // re-pin over the span the marker anchors, planned by the caller.\n if (\n result.anchor !== \"marker\" &&\n claim !== null &&\n claim.status === \"moved\" &&\n claim.newLines !== undefined\n ) {\n const at = parseLines(claim.newLines);\n // A marker that moved shifted the page under the window the search\n // found, so the lines it reported are read through the move.\n const shifted =\n at === undefined\n ? undefined\n : (() => {\n const file = toFileLines(at, page.bodyLine);\n const to = { start: lineNow(file.start), end: lineNow(file.end) };\n return to.end - to.start === file.end - file.start\n ? toBodyLines(to, page.bodyLine)\n : undefined;\n })();\n if (at !== undefined && shifted !== undefined) {\n out.push({\n kind: \"claim-moved\",\n result,\n lines: lineSpec(shifted),\n from: claim.fileLines ?? \"\",\n to: spellLines(toFileLines(shifted, page.bodyLine)),\n });\n }\n }\n // The words the pin covered are unchanged, and the run they sit in moved.\n // A plain `update` re-pins it and rewrites the entry's lines (0053).\n if (\n result.anchor !== \"marker\" &&\n claim !== null &&\n claim.status === \"reanchored\" &&\n claim.newLines !== undefined\n ) {\n const at = parseLines(claim.newLines);\n const file = at === undefined ? undefined : toFileLines(at, page.bodyLine);\n const pin = file === undefined ? undefined : pinOfLines(lines, file);\n const to =\n file === undefined ? undefined : { start: lineNow(file.start), end: lineNow(file.end) };\n if (\n file !== undefined &&\n to !== undefined &&\n pin !== undefined &&\n to.end - to.start === file.end - file.start\n ) {\n const plan: Plan = {\n kind: \"claim-words-held\",\n result,\n pin,\n at: to.start,\n fromLines: claim.fileLines ?? \"\",\n toLines: spellLines(to),\n lines: lineSpec(toBodyLines(to, page.bodyLine)),\n };\n if (claim.commitSha !== undefined) plan.commitSha = claim.commitSha;\n out.push(plan);\n }\n }\n if (result.source.status === \"moved\" && result.source.newSrc !== undefined) {\n const to = result.source.newSrc;\n const recorded = result.citation.source[\"commit-sha\"];\n const at = result.source.newLines === undefined ? undefined : parseLines(result.source.newLines);\n // The path the pin followed its text to, when that is another file. The\n // entry's own `commit-sha` then stands: the pin was minted there and\n // still holds, so HEAD would record a mint that never happened.\n const went = parseSrc(to).path;\n const crossFile = went !== result.citation.source.file;\n if (at !== undefined || result.citation.source.lines === undefined) {\n try {\n if (crossFile) {\n // Nothing to re-mint: the window hashed to the pin the entry\n // already carries, so only the stale halves of the record move.\n out.push({\n kind: \"source-moved\",\n result,\n to,\n file: went,\n pin: result.citation.source.integrity,\n ...(at === undefined ? {} : { lines: lineSpec(at) }),\n });\n } else if (at !== undefined) {\n // Re-minted over the range it moved to, not just re-pointed at it.\n // A pin whose `lines` were rewritten under an older `commit-sha`\n // names a range that commit may not even reach, and the next\n // command to ask for history reads it as a claim that never held.\n const minted = await mintCitation({\n root: run.root,\n src: to,\n ...(run.key === undefined ? {} : { key: run.key }),\n ...(recorded === undefined ? { commitSha: false as const } : {}),\n gitClient: git,\n ...(pageOptions.sourceIndex === undefined\n ? {}\n : { sourceIndex: pageOptions.sourceIndex }),\n });\n const commit = minted.source[\"commit-sha\"];\n // An entry that records a commit needs one to advance to. Without\n // git there is none, and writing the new lines alone would leave the\n // entry naming a range its own commit cannot hold, which is the\n // state this re-mint exists to prevent. So nothing is written: a\n // whole stale entry is one a later run repairs, and a half-written\n // one is not. An entry that records no commit has nothing to keep in\n // step, and is rewritten as before.\n if (recorded !== undefined && commit === undefined) {\n declined.set(result.origin.index, {\n rule: \"source-moved\",\n why: \"Not rewritten: git is not available here, so the entry's commit-sha cannot advance with its lines.\",\n });\n } else {\n out.push({\n kind: \"source-moved\",\n result,\n lines: lineSpec(at),\n to,\n pin: minted.source.integrity,\n ...(commit === undefined ? {} : { commitSha: commit }),\n });\n }\n }\n } catch (error) {\n // A range the re-mint cannot read leaves its finding reported, as a\n // source `--accept` could not re-mint does, and the finding says why\n // rather than reading as a repair that silently did nothing.\n if (!(error instanceof CiteError)) throw error;\n declined.set(result.origin.index, {\n rule: \"source-moved\",\n why: `Not rewritten: ${error.message}`,\n });\n }\n }\n }\n // Asked for, not offered: the entry is `current`, so `check` reported\n // nothing to repair here.\n if (recommit && result.source.status === \"current\") {\n const to = await recommitFor(result);\n if (to !== undefined) {\n out.push({\n kind: \"source-recommitted\",\n result,\n from: result.citation.source[\"commit-sha\"] ?? \"\",\n commitSha: to.commit,\n because: to.because,\n });\n }\n }\n if (!accept) return out;\n\n // A marker-anchored claim is re-pinned against the page the move left,\n // so the caller plans that one.\n if (claim !== null && claim.status === \"changed\" && entry !== undefined && result.anchor !== \"marker\") {\n // The paragraph, block or row now at the claim's first line. Anything\n // else is left for a fresh `cite add`, and says why.\n // The span the claim holds now, and the line it starts on. A table keeps\n // the span: the author chose how many rows the claim covers, and\n // `--accept` re-mints, never redesigns.\n //\n // Both are set for every claim that reaches here. `claimEnd` fills\n // `fileLines` only on the `claim.lines` branch, and the marker branch is\n // already excluded above, so the `undefined` arms below are the types\n // being honest rather than a case a run can land in.\n const held = claim.fileLines === undefined ? undefined : parseLines(claim.fileLines);\n const at = held?.start;\n // Naming an id is the operator saying they have read the line, so the\n // refusals that ask whether it can be claim text at all stand down.\n const named = only !== undefined;\n const unit: ClaimUnit | undefined =\n at === undefined ? undefined : unitAt(page, at, lines, held, named);\n const wantsBlock = entry.citation.quote === true;\n const pin = unit === undefined ? undefined : pinOfLines(lines, unit.lines);\n // A unit past the range limit would pin more than a citation may hold.\n const wide = unit === undefined ? undefined : tooWide(unit.lines);\n if (unit !== undefined && wide !== undefined) {\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: `Not re-pinned: the ${unitNoun(unit.kind)} ${wide}.`,\n });\n } else if (unit === undefined) {\n const why = at === undefined ? undefined : noUnitAt(page, at, lines, held, named);\n if (why !== undefined) {\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: `Not re-pinned: ${sayNoUnit(why)}.`,\n });\n }\n } else if (wantsBlock && unit.kind !== \"block\") {\n // A `quote: true` entry's claim lines are a whole fenced block, fences\n // included; `check` reads anything else as `anchor-invalid`. So a\n // quote whose first line drifted into prose, or into the middle of a\n // block, is left for a fresh `cite add` and says so.\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: \"Not re-pinned: quote: true, and the line no longer opens a fenced block.\",\n });\n } else if (pin !== undefined) {\n // Where else the same text sits. A pin cannot tell two copies apart,\n // so re-pinning over one of them writes a claim that is\n // `moved-ambiguous` the moment anything above it shifts. `add` refuses\n // the same pin for the same reason, before it is ever written.\n const elsewhere = named ? [] : otherClaimSpans(lines, unit.lines, pin, page.bodyLine);\n const replaced = replacementAt(claim, unit.text, page.format);\n // The order of these two matters, and it is the baseline that goes\n // first. Both refusals stop the same re-pin, but they do not carry the\n // same weight. The one the baseline earns says the line no longer\n // holds the claim, which is work left undone, and it exits 1. The\n // uniqueness refusal only reads the line as it stands and exits 0. So\n // a claim that trips both has to keep the stronger signal, or a\n // repeated line would quietly turn a failing run green.\n if (replaced !== undefined && only === undefined) {\n // `plansFor` runs only for a selected entry, so a run with `only`\n // set has named this one. `selected` says which repairs run; the\n // bypass says which entries `--accept` may re-pin, and both hold\n // here.\n out.push({\n kind: \"claim-replaced\",\n result,\n at: unit.lines.start,\n commitSha: replaced.commit,\n ...(replaced.share === undefined ? {} : { wordShare: replaced.share }),\n pin: entry.citation.claim?.integrity ?? \"\",\n would: pin,\n });\n } else if (elsewhere.length > 0) {\n // `--only` takes an id, so an entry without one has no way to say\n // \"accept it anyway\"; the advice is left off rather than made up.\n const id = result.citation.id;\n const anyway = id === undefined ? \"\" : ` Re-run with --only ${id} to accept it anyway.`;\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: `Not re-pinned: the text there also appears at ${spellElsewhere(elsewhere)}, so a pin cannot identify it.${anyway}`,\n });\n } else {\n const plan: Plan = { kind: \"claim-accepted\", result, unit, pin };\n if (replaced !== undefined) plan.replaced = true;\n // A paragraph that grew or shrank moves the claim's last line too.\n if (entry.citation.claim?.lines !== undefined) {\n const body = toBodyLines(unit.lines, page.bodyLine);\n const recorded = parseLines(entry.citation.claim.lines);\n if (\n recorded === undefined ||\n recorded.start !== body.start ||\n recorded.end !== body.end\n ) {\n plan.lines = lineSpec(body);\n }\n }\n out.push(plan);\n }\n }\n }\n if (result.source.status === \"changed\" || result.source.status === \"never-true\") {\n // Where the in-range search found the old first and last line. Accepting\n // the recorded range instead would hash a span the sentence never rested\n // on: an insertion inside a cited range pushes its end out of it.\n const stored = parseSrc(result.source.src);\n const span =\n result.source.newLines === undefined ? undefined : parseLines(result.source.newLines);\n const at =\n span === undefined || (span.start === stored.start && span.end === stored.end)\n ? undefined\n : { ...stored, start: span.start, end: span.end };\n try {\n // The source as the entry spells it: an encrypted one stays encrypted,\n // under the key it decrypted with, and mint keys the pin accordingly.\n // HEAD is recorded only where the entry already records a commit.\n const minted = await mintCitation({\n root: run.root,\n src: at === undefined ? result.source.src : formatSrc(at),\n ...(run.key === undefined ? {} : { key: run.key }),\n ...(result.citation.source[\"commit-sha\"] === undefined\n ? { commitSha: false as const }\n : {}),\n gitClient: git,\n ...(pageOptions.sourceIndex === undefined\n ? {}\n : { sourceIndex: pageOptions.sourceIndex }),\n });\n out.push({\n kind: \"source-accepted\",\n result,\n minted,\n ...(at === undefined || span === undefined\n ? {}\n : {\n span: {\n lines: lineSpec(span),\n from: spellLines({ start: stored.start ?? 1, end: stored.end ?? stored.start ?? 1 }),\n to: spellLines(span),\n },\n }),\n });\n } catch (error) {\n // A range the file no longer reaches cannot be re-minted; its finding stays reported.\n if (!(error instanceof CiteError)) throw error;\n }\n }\n return out;\n };\n\n const pages: UpdatePage[] = [];\n const updateOne = async (\n label: string,\n content: string,\n path?: string,\n ): Promise<PageCitationReport> => {\n const setup = await prepared.setupFor(label, content);\n if (setup.sidecar !== undefined) hits.record(setup.sidecar, label);\n const report = await checkCitations({ file: label, content, format: forced?.name }, setup.options);\n const { format } = report;\n const severity = resolveSeverity(setup.options.severity);\n const page = readPage(label, content, {\n ...(forced === undefined ? {} : { format: forced.name }),\n ...(setup.options.citations === undefined ? {} : { citations: setup.options.citations }),\n ...(setup.options.owned === undefined ? {} : { owned: setup.options.owned }),\n });\n const lines = splitLines(content);\n const rewritten: UpdateRewrite[] = [];\n const refused: UpdateRewrite[] = [];\n /** `<index>\\0<rule>` of every finding a rewrite settled. */\n const settled = new Set<string>();\n /**\n * Why a repair was declined, by entry index, said with the skipped\n * finding it concerns. The rule is carried so the reason lands on that\n * finding and not on another one about the same entry.\n */\n const declined = new Map<number, Declined>();\n\n // Misplaced markers first: the page is rewritten once, with every movable\n // marker relocated, and every pin below is taken against that page.\n const markers = decideMarkers({ page, report, lines, accept, only });\n const movedPage =\n markers.moves.length === 0\n ? undefined\n : applyMarkerMoves(\n content,\n markers.moves.map(({ misplaced }) => ({\n from: misplaced.line,\n place: misplaced.place,\n })),\n (line) => markerIndent(content, line, format, page.bodyLine),\n );\n let after = movedPage?.content ?? content;\n const afterLines = movedPage === undefined ? lines : splitLines(after);\n const movedIndexes = new Set(markers.moves.map(({ entry }) => entry.origin.index));\n const lineNow = (line: number): number => movedPage?.line(line) ?? line;\n // The manifest's entries for this page, edited in memory and written\n // back as one value once the page is done.\n const owner = setup.sidecar?.owner;\n const entries: unknown[] | undefined =\n setup.sidecar?.citations === undefined\n ? undefined\n : (JSON.parse(JSON.stringify(setup.sidecar.citations.map((c) => c.entry))) as unknown[]);\n let manifestDirty = false;\n for (const result of report.citations) {\n // `--only` selects the repairs to make. It does not select the shift a\n // marker move forces on the entries below it, which is planned for\n // every entry further down.\n const selected =\n only === undefined ||\n (result.citation.id !== undefined && only.has(result.citation.id));\n const entry = page.citations.find((c) => c.origin.index === result.origin.index);\n const plans: Plan[] = [];\n\n const move = selected\n ? markers.moves.find((m) => m.entry.origin.index === result.origin.index)\n : undefined;\n if (move !== undefined) {\n plans.push({\n kind: \"marker-moved\",\n result,\n from: move.misplaced.line,\n to: lineNow(move.misplaced.line),\n });\n }\n // The pin a marker anchors is taken against the page the moves left, so\n // the next check reads it as current however the run split.\n const marker = entry?.marker;\n const recorded = entry?.citation.claim?.integrity;\n if (\n selected &&\n result.anchor === \"marker\" &&\n marker !== undefined &&\n recorded !== undefined &&\n result.claim !== null\n ) {\n const quote = entry?.citation.quote === true;\n const now = anchoredNow(after, format, afterLines, lineNow(marker.line), quote);\n const status = result.claim.status;\n if (now !== undefined && now.pin !== recorded) {\n // A `current` claim already covers the unit the marker belongs to,\n // so only a move that split its run can leave it needing a pin.\n const unitText = afterLines.slice(now.span.start - 1, now.span.end);\n if (status === \"moved\" || (status === \"current\" && move !== undefined)) {\n plans.push({\n kind: \"claim-reanchored\",\n result,\n pin: now.pin,\n held: result.claim.fileLines ?? \"\",\n now: spellLines(now.span),\n });\n } else if (status === \"reanchored\") {\n // The marker travels with its text, so nothing moves but the pin.\n const held: Plan = {\n kind: \"claim-words-held\",\n result,\n pin: now.pin,\n at: now.span.start,\n fromLines: result.claim.fileLines ?? \"\",\n toLines: spellLines(now.span),\n };\n if (result.claim.commitSha !== undefined) held.commitSha = result.claim.commitSha;\n plans.push(held);\n } else if (status === \"changed\" && accept) {\n const kind = quote ? \"block\" : \"paragraph\";\n // A marker pins everything it anchors, so the range limit applies\n // to that, exactly as it does to a claim-lines re-pin.\n const wide = tooWide(now.span);\n if (wide !== undefined) {\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: `Not re-pinned: the ${kind} ${wide}.`,\n });\n } else {\n const replaced = replacementAt(result.claim, unitText, format);\n // `--only` naming the entry is the judgement the guard demands,\n // so a named accept stands and says `replaced` in the log.\n plans.push(\n replaced === undefined || only !== undefined\n ? {\n kind: \"claim-accepted\",\n result,\n pin: now.pin,\n markerLine: lineNow(marker.line),\n unit: { lines: now.span, kind, text: unitText },\n ...(replaced === undefined ? {} : { replaced: true as const }),\n }\n : {\n kind: \"claim-replaced\",\n result,\n at: now.span.start,\n commitSha: replaced.commit,\n ...(replaced.share === undefined ? {} : { wordShare: replaced.share }),\n pin: recorded,\n would: now.pin,\n },\n );\n }\n }\n }\n }\n\n if (selected) {\n plans.push(...(await plansFor(result, entry, page, lines, lineNow, declined)));\n }\n\n // A claim-lines entry the moves pushed along keeps its pinned text, so\n // its lines are rewritten in the same write. This one runs outside\n // `--only`: the page has already moved under the entry, so leaving its\n // lines behind would need a second run to put right.\n const spec = entry?.citation.claim?.lines;\n // A claim whose text moved is repaired by `claim-moved`, which finds\n // where the text went. Shifting its lines by the marker's delta would\n // point them somewhere else again, so the shift leaves it alone.\n const wentElsewhere = result.claim?.status === \"moved\";\n if (\n movedPage !== undefined &&\n spec !== undefined &&\n !wentElsewhere &&\n !plans.some((p) => p.kind === \"claim-moved\")\n ) {\n const at = parseLines(spec);\n const file = at === undefined ? undefined : toFileLines(at, page.bodyLine);\n const to =\n file === undefined ? undefined : { start: lineNow(file.start), end: lineNow(file.end) };\n if (\n file !== undefined &&\n to !== undefined &&\n to.end - to.start === file.end - file.start &&\n (to.start !== file.start || to.end !== file.end)\n ) {\n plans.push({\n kind: \"claim-shifted\",\n result,\n lines: lineSpec(toBodyLines(to, page.bodyLine)),\n from: spellLines(file),\n to: spellLines(to),\n });\n }\n }\n\n for (const plan of plans) {\n // A refused claim writes nothing, in either channel; its row is the\n // whole of it, and it keeps the finding from being reported twice.\n if (plan.kind === \"claim-replaced\") {\n refused.push(rewriteOf(plan));\n settled.add(`${String(result.origin.index)}\\0${settles(plan)}`);\n continue;\n }\n if (plan.kind === \"marker-moved\") {\n // The page already carries the move.\n } else if (result.origin.kind === \"manifest\") {\n // The manifest's entry list is shorter than the report's index, so\n // there is nothing to splice. Said rather than dropped: a silent\n // skip would report the check's own message and no reason.\n const held = entries?.[result.origin.index];\n if (held === undefined) {\n declined.set(result.origin.index, {\n rule: settles(plan),\n why: `Not rewritten: ${owner?.file ?? \"the manifest\"} has no entry at index ${String(result.origin.index)}.`,\n });\n continue;\n }\n if (!applyToEntry(held, plan)) continue;\n manifestDirty = true;\n } else {\n after = apply(after, format, plan);\n }\n rewritten.push(rewriteOf(plan));\n settled.add(`${String(result.origin.index)}\\0${settles(plan)}`);\n }\n }\n // A marker that moved settles its finding even where the entry is out of\n // the loop's reach, and a stacked run that split keeps the rest reported.\n for (const index of movedIndexes) settled.add(`${String(index)}\\0marker-misplaced`);\n if (manifestDirty && owner !== undefined && entries !== undefined) {\n if (setup.sidecar?.entry === undefined) {\n throw new CiteError(\n `${label} carries no ${owner.join}: value, so its citations cannot be keyed in ${owner.file}.`,\n );\n }\n await manifests.write(owner, setup.sidecar.entry, entries, 0);\n }\n // A marker that stays says so in place of the check's wording, at the\n // severity of the rule that kept it there. An accept this run declined\n // says why beside the finding that kept its work undone.\n const stayAt = new Map(markers.stays.map((stay) => [stay.line, stay]));\n const skipped = report.findings\n .filter(\n (finding) =>\n (only === undefined || (finding.id !== undefined && only.has(finding.id))) &&\n !settled.has(`${String(finding.index ?? -1)}\\0${finding.rule}`),\n )\n .map((finding) => {\n if (finding.rule === \"marker-misplaced\") {\n const stay = stayAt.get(finding.line ?? -1);\n if (stay === undefined) return finding;\n const level = severity[stay.rule];\n return {\n ...finding,\n message: stay.message,\n ...(level === \"off\" ? {} : { severity: level }),\n };\n }\n const turned = finding.index === undefined ? undefined : declined.get(finding.index);\n const why = turned?.rule === finding.rule ? turned.why : undefined;\n return why === undefined ? finding : { ...finding, message: `${finding.message} ${why}` };\n });\n const diff = after === content ? \"\" : unifiedDiff(label, content, after);\n const written = after !== content && path !== undefined && opts.dryRun !== true;\n if (written) {\n try {\n await writeFileAtomic(path, after);\n } catch (error) {\n throw await writes.restore(label, error);\n }\n writes.record(path, label, content);\n }\n const out: UpdatePage = { file: label, rewritten, refused, skipped, diff, written };\n // The stdin page has nowhere to be written; the caller prints it instead.\n if (path === undefined) out.content = after;\n pages.push(out);\n return report;\n };\n\n const reports: PageCitationReport[] = [];\n if (usingStdin) reports.push(await updateOne(STDIN_LABEL, opts.stdinContent ?? \"\"));\n for (const file of files) {\n reports.push(await updateOne(file, await readTarget(run, file), resolve(run.base, file)));\n }\n assertNoOrphanJoins(prepared, hits);\n\n // One write per manifest, after every page that touches it is settled.\n const write = opts.dryRun !== true;\n const rewrittenManifests: ManifestChange[] = [];\n const record = (changed: { file: string; diff: string }): void => {\n rewrittenManifests.push({ file: changed.file, diff: changed.diff, written: write });\n };\n if (write) {\n await manifests.commit({\n // A manifest joins the run's written files the moment it lands, so a\n // later manifest's failure puts this one back with the pages. Without\n // it the tree would keep pins no page content matches.\n after: (changed) => {\n writes.record(changed.path, changed.file, changed.before);\n record(changed);\n },\n onError: async (changed, error) => {\n throw await writes.restore(changed.file, error);\n },\n });\n } else for (const changed of manifests.changed()) record(changed);\n // A re-mint records HEAD when git has one. Where git is not there the entry\n // is re-pinned without a commit, and the run says so once.\n const reminted = pages.some((page) =>\n page.rewritten.some((r) => r.reason === \"accepted\" && r.end === \"source\"),\n );\n const also: string[] = [];\n if (reminted && !(await git.available())) also.push(GIT_UNAVAILABLE_COMMIT);\n // A shallow clone ran only the containment test, and says so whatever it\n // found, because what it could not check is the point. The guard is the\n // one `outsideHistory` uses, so the notice fires exactly when that test\n // would have run and could not.\n if (recommit && git.shallow !== undefined && git.isAncestor !== undefined && (await git.shallow())) {\n also.push(SHALLOW_RECOMMIT);\n }\n sayNotices(reports, opts.onNotice, also);\n\n const rewritten = pages.reduce((n, page) => n + citationsIn(page.rewritten), 0);\n // A refused claim counts as skipped: `--accept` was asked for it and the\n // run left it undone, which is what the summary's second number means.\n const skipped = pages.reduce((n, page) => n + page.skipped.length + page.refused.length, 0);\n const undone = pages.some(\n (page) =>\n page.refused.length > 0 || page.skipped.some((finding) => finding.severity === \"error\"),\n );\n return {\n pages,\n rewritten,\n skipped,\n ...(rewrittenManifests.length > 0 ? { manifests: rewrittenManifests } : {}),\n exitCode: undone ? 1 : 0,\n };\n}\n"],"mappings":"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","names":["readFile","i","j","readFile","after","index","at","named","resolve","index","markers","named","kept","resolve","resolve","apply","isRecord","named","rewritten","skipped","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/cite/commands/add.ts","../src/cite/core/mint.ts","../src/cite/core/shift.ts","../src/cite/core/manifest.ts","../src/cite/core/write.ts","../src/cite/commands/remove.ts","../src/cite/commands/update.ts"],"sourcesContent":["/**\n * `manni cite add`: mint one citation and write it to a page.\n *\n * The page lines are the claim: `add docs/limits.md:9 lib/limits.ts:2` pins\n * line 9 of the page to line 2 of the source. Lines reach the command as an\n * editor numbers them and are stored body-relative, so editing the\n * frontmatter never moves them. `--marker` writes a `cite <id>` comment above\n * those lines instead, and pins the text it anchors; `--quote` says the lines\n * are a fenced block that reproduces the source. No lines at all is a bare\n * pin: this page rests on these lines, say so when they change.\n *\n * Every refusal is a `CiteError` (exit 2) with the page and the source\n * spelled as the caller spelled them, and nothing is written. Among them are\n * the pins the command can already see are wrong: a duplicate of an entry the\n * page has, and a claim whose lines hold no text at all.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { relative, resolve } from \"node:path\";\nimport { locateFrontmatter, writeFileAtomic } from \"../../meta/index.js\";\nimport { STDIN_LABEL, STDIN_TOKEN } from \"../../meta/internal.js\";\nimport { ensureEncryptionKey } from \"../../shared/prompt.js\";\nimport { isEncryptedValue } from \"../../shared/encryption.js\";\nimport {\n blockMatches,\n otherClaimSpans,\n pinOfLines,\n spellElsewhere,\n toBodyLines,\n toFileLines,\n} from \"../core/claims.js\";\nimport { resolveCiteRun } from \"../core/config.js\";\nimport { GIT_UNAVAILABLE_COMMIT, gitClient } from \"../core/git.js\";\nimport { sliceLines, splitLines } from \"../core/hash.js\";\nimport { mintCitation } from \"../core/mint.js\";\nimport { bodyLineOf, readPage } from \"../core/page.js\";\nimport {\n formatSrc,\n lineSpec,\n parseLines,\n parseSrc,\n spellLines,\n spellSource,\n tooWide,\n} from \"../core/range.js\";\nimport { misplacedMarkers } from \"../core/reanchor.js\";\nimport { shiftedEntries, withClaimLines, type Shifted } from \"../core/shift.js\";\nimport { readSource, sourceIndexFor } from \"../core/sources.js\";\nimport { shortSrc, spellAt } from \"../core/spell.js\";\nimport { ManifestSet } from \"../core/manifest.js\";\nimport { sidecarsFor, type PageSidecar } from \"../core/sidecar.js\";\nimport {\n ANY_FENCE,\n MAX_IDS_PER_MARKER,\n anchoredLines,\n fenceSpanAt,\n formatStatement,\n isMarkerLine,\n markerIndent,\n offsetOfLine,\n respellStatement,\n unitHolding,\n} from \"../core/statements.js\";\nimport {\n appendFrontmatterCitation,\n entryObject,\n insertStatementBefore,\n spliceEntryField,\n unifiedDiff,\n} from \"../core/write.js\";\nimport { CiteError } from \"../errors.js\";\nimport type {\n AddOptions,\n AddResult,\n Citation,\n CitationClaim,\n PageCitation,\n PageCitations,\n PageLines,\n SourceIndex,\n} from \"../types.js\";\nimport { STDIN_REQUIRES_AS } from \"../../shared/cli-options.js\";\n\n/** The schema's id grammar, checked before anything is written. */\nconst ID = /^[a-z0-9][a-z0-9-]*$/;\n\nconst toPosix = (path: string): string => path.replace(/\\\\/g, \"/\");\n\nfunction isEnoent(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\";\n}\n\nasync function readPageFile(path: string, label: string): Promise<string> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if (isEnoent(error)) throw new CiteError(`File not found: \"${label}\".`);\n throw error;\n }\n}\n\n/** The cited lines, joined as the hashing rule joins them. */\nasync function citedText(\n root: string,\n index: SourceIndex,\n src: string,\n key: string | undefined,\n): Promise<string> {\n const range = parseSrc(src);\n const source = await readSource(root, index, range, key);\n // Minting already read this range, so a miss here is a race with the disk.\n if (source.kind === \"missing\") {\n throw new CiteError(`Source not readable: ${range.path} could not be read.`);\n }\n return sliceLines(splitLines(source.text), range, range.path);\n}\n\n/** How a refusal names an entry: its id, or the pointer a report would use. */\nfunction entryName(entry: PageCitation): string {\n return entry.citation.id ?? `/citations/${String(entry.origin.index)}`;\n}\n\n/**\n * The entry that already pins these very page lines to this very source, in\n * the frontmatter or in the manifest that owns the page's citations. A bare\n * pin matches another bare pin over the same source.\n *\n * The source is compared as each end spells it, so an encrypted one compares\n * as its ciphertext and no path is decrypted to say so. A marker add is not\n * asked: it stores no claim lines, and its own id and anchor checks cover it.\n */\nfunction duplicateOf(\n page: PageCitations,\n src: string,\n pageLines: PageLines | undefined,\n): PageCitation | undefined {\n // opts.src is the caller's plain-path spelling; an existing entry encrypted\n // under a key compares as its ciphertext and will never match here.\n const wanted = formatSrc(parseSrc(src));\n return page.citations.find((entry) => {\n const { citation } = entry;\n if (spellSource(citation.source) !== wanted) return false;\n if (pageLines === undefined) return citation.claim === undefined;\n const spec = citation.claim?.lines;\n if (spec === undefined) return false;\n const recorded = parseLines(spec);\n if (recorded === undefined) return false;\n const file = toFileLines(recorded, page.bodyLine);\n return file.start === pageLines.start && file.end === pageLines.end;\n });\n}\n\n/** Whether a page line can hold no claim at all: it is blank, or it is a fence. */\nfunction holdsNoText(text: string): boolean {\n return text.trim() === \"\" || ANY_FENCE.test(text);\n}\n\n/**\n * The refusal for a claim whose lines hold no text, `at` being the page and\n * the lines as the caller spelled them. Undefined when at least one line\n * carries text. `--quote` never asks, because a quote is fences and content\n * by design.\n */\nfunction emptyClaimRefusal(\n lines: readonly string[],\n pageLines: PageLines,\n at: string,\n): string | undefined {\n const span = lines.slice(pageLines.start - 1, pageLines.end);\n if (span.some((text) => !holdsNoText(text))) return undefined;\n if (pageLines.start !== pageLines.end) return `${at} holds no claim text.`;\n const only = span[0] ?? \"\";\n return only.trim() === \"\" ? `${at} is blank.` : `${at} is a fence line, not claim text.`;\n}\n\nexport async function runAdd(opts: AddOptions): Promise<AddResult> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const run = await resolveCiteRun({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: [],\n root: opts.root,\n onConfigLoaded: opts.onConfigLoaded,\n onNotice: opts.onNotice,\n env: opts.env,\n });\n const { root } = run;\n\n const usingStdin = opts.page === STDIN_TOKEN;\n if (usingStdin && opts.as === undefined) {\n throw new CiteError(STDIN_REQUIRES_AS);\n }\n // `-` names no file: nothing to resolve, and nothing to write back to.\n const path = usingStdin ? undefined : resolve(cwd, opts.page);\n const label = path === undefined ? STDIN_LABEL : toPosix(relative(cwd, path));\n const content = path === undefined ? (opts.stdinContent ?? \"\") : await readPageFile(path, label);\n\n // The manifests that own `citations`, if any collection declares one. The\n // page is labelled from the working directory here, so membership is\n // measured from there too.\n const sidecars = await sidecarsFor(run, {\n base: cwd,\n // A `{page}` manifest (0058) is read for the one page being cited.\n ...(path === undefined ? {} : { pages: [path] }),\n });\n const firstManifest = sidecars?.manifests[0];\n if (usingStdin && firstManifest !== undefined) {\n const keyedBy = firstManifest.join === \"path\" ? \"path\" : firstManifest.join;\n throw new CiteError(\n `A page read from stdin has no path, and its citations live in ${firstManifest.file}, which is keyed by ${keyedBy}.`,\n );\n }\n const sidecar: PageSidecar | undefined = usingStdin\n ? undefined\n : await sidecars?.forPage(label, content, opts.as);\n const owner = sidecar?.owner;\n\n const page = readPage(label, content, {\n ...(opts.as === undefined ? {} : { format: opts.as }),\n // The entries already there are the manifest's, so `--id` uniqueness and\n // the marker checks are measured against them and not against a page\n // that carries none.\n ...(sidecar?.citations === undefined ? {} : { citations: sidecar.citations }),\n ...(owner === undefined ? {} : { owned: { file: owner.file, collection: owner.collection } }),\n });\n const { format } = page;\n\n const pageLines = opts.pageLines;\n const marker = opts.marker === true;\n const quote = opts.quote === true;\n const at = pageLines === undefined ? \"\" : `${label}:${spellLines(pageLines)}`;\n\n // Composition first: these need no source and no search.\n if (marker && pageLines === undefined) {\n throw new CiteError(`--marker needs the page lines to anchor: ${label}:L.`);\n }\n if (marker && opts.id === undefined) {\n throw new CiteError(\"--marker needs --id: the marker names the entry.\");\n }\n const wide = pageLines === undefined ? undefined : tooWide(pageLines);\n if (wide !== undefined) throw new CiteError(`Invalid range \"${at}\": it ${wide}.`);\n if (quote && pageLines === undefined) {\n throw new CiteError(`--quote needs the block's lines: ${label}:L1-L2.`);\n }\n if (opts.id !== undefined && !ID.test(opts.id)) {\n throw new CiteError(\n `Invalid id \"${opts.id}\": use lowercase letters, digits and hyphens, starting with a letter or digit.`,\n );\n }\n if (opts.id !== undefined && page.citations.some((c) => c.citation.id === opts.id)) {\n throw new CiteError(`${label} already has an entry ${opts.id}.`);\n }\n if (marker && opts.id !== undefined) {\n // Joining an id a marker already names would write it twice into one\n // list, which is `marker-invalid`. The entry check above catches the\n // ordinary case; this one is left by a marker whose entry went away.\n const already = page.statements.find(\n (s) => s.payload.kind === \"ref\" && s.payload.ids.includes(opts.id ?? \"\"),\n );\n if (already !== undefined) {\n throw new CiteError(\n `${label} already has a marker ${opts.id} at line ${String(already.line)}.`,\n );\n }\n }\n // The same claim on the same source twice is one citation reported twice,\n // and the second is what a re-run of a script writes.\n const duplicate = marker ? undefined : duplicateOf(page, opts.src, pageLines);\n if (duplicate !== undefined) {\n const src = shortSrc(spellSource(duplicate.citation.source));\n const what =\n pageLines === undefined\n ? `a bare pin for ${src}`\n : `an entry for ${spellAt(pageLines)} and ${src}`;\n throw new CiteError(`${label} already has ${what} (${entryName(duplicate)}).`);\n }\n\n const lines = splitLines(content);\n if (pageLines !== undefined) {\n if (pageLines.end > lines.length) {\n throw new CiteError(`${at} is past the end of the page (${String(lines.length)} lines).`);\n }\n if (pageLines.start < page.bodyLine) {\n throw new CiteError(`${at} is in the frontmatter. A claim is body text.`);\n }\n if (quote) {\n const span = fenceSpanAt(content, pageLines.start, format);\n if (span === undefined || span.end !== pageLines.end) {\n throw new CiteError(`${at} is not a fenced block, so it cannot be a quote.`);\n }\n } else if (!marker) {\n // A pin over a fence or a blank line holds for as long as the page has\n // one, so a check would call it `current` whatever the prose does.\n const empty = emptyClaimRefusal(lines, pageLines, at);\n if (empty !== undefined) throw new CiteError(empty);\n }\n // `add` does not move a marker it did not write, so it refuses to write\n // where a misplaced one would make its entry wrong (proposal 0054).\n const split = misplacedMarkers(page, lines);\n const held = split.find(\n (found) => found.line >= pageLines.start && found.line <= pageLines.end,\n );\n if (held !== undefined) {\n throw new CiteError(\n `${at} holds the marker at line ${String(held.line)}, which splits its paragraph. Run manni cite update first.`,\n );\n }\n const inside = marker\n ? split.find(\n (found) => pageLines.start >= found.unit.start && pageLines.start <= found.unit.end,\n )\n : undefined;\n if (inside !== undefined) {\n throw new CiteError(\n `${at} is in the paragraph at ${spellAt(inside.unit)}, which the marker at line ${String(inside.line)} splits. Run manni cite update first.`,\n );\n }\n }\n\n // Git is used whenever it is there, as on check and update: the index is\n // `git ls-files` and the commit is HEAD. Where it is not, a walk and none.\n const client = opts.gitClient ?? gitClient(root);\n const sourceIndex = await sourceIndexFor(root, client);\n\n // The marker goes in before the claim is pinned, because what it anchors is\n // what the claim pins. Everything below counts lines in `body`, the page\n // with the marker, and the frontmatter append shifts them once at the end.\n let body = content;\n let markerAt: number | undefined;\n /** Whether the id joined a marker already there, rather than getting a line. */\n let markerJoined = false;\n let claimSpan: PageLines | undefined;\n let claim: CitationClaim | undefined;\n // Where else the claim's text sits, for the notice at the end of the run.\n let elsewhere: PageLines[] = [];\n // Entries whose claim lines sit below a marker move down with the text.\n let shifted: Shifted = { frontmatter: [], manifest: new Map() };\n if (marker && pageLines !== undefined) {\n // The marker goes above the paragraph or block holding the lines, below\n // any markers already stacked there, at its indentation, and the lines\n // must stay inside it.\n // A marker line is never part of a pin, so a marker written there would\n // change what the line below it pins. The refusal is keyed to the line\n // rather than to what the marker names.\n if (isMarkerLine(lines[pageLines.start - 1] ?? \"\", format)) {\n throw new CiteError(\n `${label}:${String(pageLines.start)} is a marker line. A marker there would change its pin.`,\n );\n }\n const holding = unitHolding(content, pageLines.start, format, {\n offset: page.bodyOffset,\n line: page.bodyLine,\n });\n if (holding === undefined) {\n throw new CiteError(`${at} has no paragraph or block for a marker to anchor.`);\n }\n if (pageLines.end > holding.end) {\n throw new CiteError(\n `${at} runs past the ${holding.kind} at ${spellAt(holding)}. A marker anchors one paragraph.`,\n );\n }\n // A marker pins everything it anchors, so the range limit applies to that.\n const unitWide = tooWide({ start: holding.start, end: holding.end });\n if (unitWide !== undefined) {\n throw new CiteError(\n `${at} is in a ${holding.kind} at ${spellAt(holding)} that ${unitWide}. A marker anchors the whole ${holding.kind}.`,\n );\n }\n // The marker nearest the anchored text: the one on the text own line when\n // there is one, else the last marker line above it. A reader associates\n // the nearest comment with the prose, and appending there needs no other\n // line to move (proposal 0056).\n const above = page.statements.filter((s) => s.anchorLine === holding.start);\n const nearest = above[above.length - 1];\n // A marker already holding the cap takes no more, so the twenty-sixth\n // citation gets a marker line of its own. Refusing would leave no way to\n // cite the paragraph short of editing the line by hand. A marker the\n // scanner could not read is left alone for the same reason.\n //\n // So is one whose delimiters sit on different lines. That parses, but\n // respelling it folds it onto one line, and the claims below it would\n // then all be one line out while this path shifts nothing.\n const held =\n nearest !== undefined &&\n nearest.payload.kind === \"ref\" &&\n nearest.payload.ids.length < MAX_IDS_PER_MARKER &&\n !/[\\r\\n]/.test(nearest.raw)\n ? nearest.payload.ids\n : undefined;\n /** Where the marker ends in `body`, so what follows it can be anchored. */\n let after: number;\n if (nearest !== undefined && held !== undefined) {\n body = respellStatement(content, nearest, [...held, opts.id ?? \"\"]);\n // Joining changes one line in place, so nothing below it moves and no\n // claim on the page is re-spelled.\n after = nearest.end + (body.length - content.length);\n markerAt = nearest.line;\n markerJoined = true;\n } else {\n shifted = shiftedEntries({\n citations: page.citations,\n at: [holding.start],\n delta: 1,\n bodyLine: page.bodyLine,\n label,\n });\n const statement =\n markerIndent(content, holding.start, format, page.bodyLine) +\n formatStatement(format, { kind: \"ref\", ids: [opts.id ?? \"\"] });\n const insertAt = offsetOfLine(content, holding.start);\n body = insertStatementBefore(content, insertAt, statement);\n after = insertAt + statement.length;\n markerAt = holding.start;\n }\n const unit = anchoredLines(body, after, format, quote);\n const pin = unit === undefined ? undefined : pinOfLines(splitLines(body), unit);\n if (unit === undefined || pin === undefined) {\n throw new CiteError(`${at} has no paragraph or block for a marker to anchor.`);\n }\n for (const { index, lines: moved } of shifted.frontmatter) {\n body = spliceEntryField(body, format, index, [\"claim\", \"lines\"], moved);\n }\n claimSpan = unit;\n claim = { integrity: pin };\n } else if (pageLines !== undefined) {\n const pin = pinOfLines(lines, pageLines);\n if (pin === undefined) {\n throw new CiteError(`${at} is past the end of the page (${String(lines.length)} lines).`);\n }\n claimSpan = pageLines;\n claim = { lines: lineSpec(toBodyLines(pageLines, page.bodyLine)), integrity: pin };\n elsewhere = otherClaimSpans(lines, pageLines, pin, page.bodyLine);\n }\n\n const mint = (key: string | undefined, encrypt: boolean): Promise<Citation> =>\n mintCitation({\n root,\n src: opts.src,\n ...(opts.id === undefined ? {} : { id: opts.id }),\n ...(claim === undefined ? {} : { claim }),\n ...(quote ? { quote: true } : {}),\n ...(opts.commitSha === false ? { commitSha: false as const } : {}),\n encrypt,\n ...(key === undefined ? {} : { key }),\n gitClient: client,\n sourceIndex,\n });\n\n // Encryption follows the key: an available one encrypts every add, with no\n // flag to remember, and `--encrypt` asks for one when there is none. With a\n // key in hand this mint is the citation written. Without one it is plain,\n // and settles every refusal that needs no key before the question is put,\n // so a refused add never leaves a key behind.\n const needsKey = opts.encrypt === true && run.key === undefined;\n let citation = await mint(run.key, run.key !== undefined);\n\n if (quote && claimSpan !== undefined) {\n // The lines inside the fences are what the source has to match.\n const cited = await citedText(root, sourceIndex, opts.src, run.key);\n const inside = splitLines(body).slice(claimSpan.start, claimSpan.end - 1).join(\"\\n\");\n if (!blockMatches(inside, cited)) {\n throw new CiteError(`The block at ${at} does not reproduce ${opts.src}.`);\n }\n }\n\n if (needsKey) {\n const { key } = await ensureEncryptionKey({\n subject: opts.src,\n cwd,\n file: run.configFile ?? null,\n env: opts.env,\n confirm: opts.confirm,\n notice: (message) => {\n opts.onNotice?.(message);\n },\n toError: (message) => new CiteError(message),\n });\n citation = await mint(key, true);\n }\n\n // The first pinned source line, so the report shows what the range caught\n // and a mis-typed one is visible at write time. A whole file has no first\n // line worth naming, and an encrypted source is never spelled in the open.\n const srcRange = parseSrc(opts.src);\n let sourceLine: string | undefined;\n if (srcRange.start !== undefined && !isEncryptedValue(citation.source.file)) {\n const read = await readSource(root, sourceIndex, srcRange, undefined);\n if (read.kind === \"ok\") sourceLine = splitLines(read.text)[srcRange.start - 1];\n }\n\n // Where the entry goes follows the config, not a flag: a collection whose\n // manifest owns `citations` keeps them there, and the page is left alone\n // but for a marker.\n const manifests = new ManifestSet();\n let placed: AddResult[\"manifest\"];\n /** Which item of the entry's `citations` this run added, for the line report. */\n let index = 0;\n if (owner !== undefined) {\n if (sidecar?.entry === undefined) {\n throw new CiteError(\n `${label} carries no ${owner.join}: value, so its citations cannot be keyed in ${owner.file}.`,\n );\n }\n const existing = (sidecar.citations ?? []).map((input, index) => {\n const moved = shifted.manifest.get(index);\n return moved === undefined ? input.entry : withClaimLines(input.entry, moved);\n });\n const list = [...existing, entryObject(citation)];\n index = list.length - 1;\n const at = await manifests.write(owner, sidecar.entry, list, index);\n const [changed] = manifests.changed();\n placed = {\n file: at.file,\n line: at.line,\n content: changed?.text ?? \"\",\n diff: changed?.diff ?? \"\",\n written: false,\n };\n }\n\n const after = owner === undefined ? appendFrontmatterCitation(body, format, citation, label) : body;\n // The frontmatter append leaves the body's bytes alone, so every body line\n // moves by exactly what the block grew. The marker sits in the body, so the\n // page it was inserted into already has this page's body line. An entry\n // written to a manifest grows no block, so nothing moves.\n const shift = bodyLineOf(after, locateFrontmatter(after)?.closeEnd ?? 0) - page.bodyLine;\n\n const result: AddResult = {\n file: label,\n citation,\n placed: owner === undefined ? \"frontmatter\" : \"manifest\",\n content: after,\n diff: unifiedDiff(label, content, after),\n written: false,\n ...(sourceLine === undefined ? {} : { sourceLine }),\n ...(placed === undefined ? {} : { manifest: placed }),\n };\n if (markerAt !== undefined) result.markerLine = markerAt + shift;\n if (markerJoined) result.markerJoined = true;\n if (claimSpan !== undefined) {\n result.claimLines = { start: claimSpan.start + shift, end: claimSpan.end + shift };\n }\n\n // A manifest entry leaves the page byte for byte as it was, unless a\n // marker went into the body; there is then nothing to write.\n result.written = path !== undefined && opts.dryRun !== true && after !== content;\n if (result.written && path !== undefined) await writeFileAtomic(path, after);\n // The entry goes in under compare-and-swap, so what lands may be a replay\n // onto a manifest another command wrote while this one was running. The\n // report names the bytes and the line that actually landed, not the ones\n // this run spliced from.\n if (result.manifest !== undefined && opts.dryRun !== true) {\n const [settled] = await manifests.commit();\n if (owner !== undefined && sidecar?.entry !== undefined) {\n result.manifest.line = manifests.lineOf(owner, sidecar.entry, index) ?? result.manifest.line;\n }\n if (settled !== undefined) {\n result.manifest.content = settled.text;\n result.manifest.diff = settled.diff;\n }\n result.manifest.written = true;\n }\n // The claim's text repeats, so a later move of it could not be told apart\n // from its copies. Said once the entry is written: it is not a refusal, and\n // the lines it names are the page's own after the write.\n if (elsewhere.length > 0) {\n const named = elsewhere.map((span) => ({ start: span.start + shift, end: span.end + shift }));\n const who = citation.id === undefined ? \"\" : `${citation.id}: `;\n opts.onNotice?.(\n `${who}the claim's text also appears at ${spellElsewhere(named)}, so a move would be ambiguous. Use --marker, or pin more lines.`,\n );\n }\n // A commit was wanted (no --no-commit-sha) and git had none to give. Said\n // once the add has succeeded, so a refused add says nothing about git.\n if (opts.commitSha !== false && !(await client.available())) {\n opts.onNotice?.(GIT_UNAVAILABLE_COMMIT);\n }\n return result;\n}\n","/**\n * Mint a citation's source end: read the range through the source index, hash\n * it under the rule (the keyed pin when the source is encrypted), record HEAD\n * unless told not to. Refuses (CiteError) a source the index does not hold, an\n * encrypted source the key cannot open, a range wider than\n * `MAX_RANGE_LINES`, a range past EOF, or a commit that does not contain the\n * lines it would be recorded against. No refusal names the path an encrypted\n * source holds.\n *\n * The claim end is minted by the caller, over the page lines it was given,\n * and passed in whole.\n */\nimport { ENCRYPTION_KEY_ENV } from \"../../shared/encryption-key.js\";\nimport { CiteError } from \"../errors.js\";\nimport type {\n Citation,\n CitationSource,\n MintOptions,\n MissingReason,\n SourceRange,\n} from \"../types.js\";\nimport { historyOf } from \"./classify.js\";\nimport { hashLines, sliceLines, splitLines } from \"./hash.js\";\nimport { parseSrc, rangeLines, tooWide } from \"./range.js\";\nimport { buildSourceIndex, encryptSourcePath, readSource } from \"./sources.js\";\n\n/** The schema's `commit-sha` pattern: seven to sixty-four lowercase hex digits. */\nconst COMMIT_PATTERN = /^[0-9a-f]{7,64}$/;\n\nasync function commitFor(opts: MintOptions): Promise<string | undefined> {\n if (opts.commitSha === false) return undefined;\n if (typeof opts.commitSha === \"string\") {\n if (!COMMIT_PATTERN.test(opts.commitSha)) {\n throw new CiteError(\n `Invalid commit-sha \"${opts.commitSha}\": expected 7 to 64 lowercase hex digits.`,\n );\n }\n return opts.commitSha;\n }\n const client = opts.gitClient;\n if (client === undefined || !(await client.available())) return undefined;\n return (await client.head()) ?? undefined;\n}\n\n/**\n * Refuse a commit that does not contain the lines it would be recorded\n * against. The range is read from the working tree, so an uncommitted edit\n * would otherwise be dated to a commit that never held it. Such a pin reads as\n * `current` forever, because `classifyCitation` returns at the working-tree\n * match without consulting the commit, and then accuses the source of\n * `source-never-true` the first time it changes.\n *\n * `historyOf` is the same question `check` asks, so the answers agree. It\n * accepts the lines sitting elsewhere in the file at that commit, which is what\n * `update` leaves behind when it follows a move and keeps `commit`.\n *\n * A commit git cannot read is recorded unverified. A shallow clone must\n * degrade to \"history unavailable\" rather than refuse (`git.ts`).\n */\nasync function assertCommitHolds(\n opts: MintOptions,\n commit: string,\n path: string,\n range: SourceRange,\n pin: string,\n key: string | undefined,\n): Promise<void> {\n const client = opts.gitClient;\n if (client === undefined || !(await client.available())) return;\n const history = await historyOf(client, commit, path, range, pin, key, undefined);\n if (history.kind !== \"never-true\") return;\n // Named as the caller spelled it: an encrypted source stays a ciphertext.\n throw new CiteError(\n `${opts.src} is not committed: ${commit.slice(0, 7)} does not contain those lines. Commit the source, or use --no-commit-sha.`,\n );\n}\n\n/**\n * The refusal for a source that could not be read, naming it as the caller\n * spelled it: an encrypted source stays a ciphertext even on stderr.\n */\nfunction refusalFor(reason: MissingReason, path: string, encrypted: boolean): CiteError {\n switch (reason) {\n case \"untracked\":\n return new CiteError(\n encrypted\n ? `No tracked file matches ${path} (wrong --root?).`\n : `Source not found: ${path} is not a tracked file under the root.`,\n );\n case \"no-key\":\n return new CiteError(`${path} is encrypted, and no encryption key is available to decrypt it.`);\n case \"undecryptable\":\n return new CiteError(`${path} does not decrypt under the current key.`);\n case \"unreadable\":\n return new CiteError(`Source not readable: ${path} could not be read.`);\n }\n}\n\nexport async function mintCitation(opts: MintOptions): Promise<Citation> {\n const range = parseSrc(opts.src);\n const wide =\n range.start === undefined || range.end === undefined\n ? undefined\n : tooWide({ start: range.start, end: range.end });\n if (wide !== undefined) throw new CiteError(`Invalid range \"${opts.src}\": it ${wide}.`);\n const { key } = opts;\n // A source that is already encrypted stays encrypted whatever `encrypt`\n // says: the check side keys every pin whose file is encrypted, so a plain\n // pin under a ciphertext would never hold.\n const encrypt = opts.encrypt === true || range.encrypted;\n if (encrypt && !range.encrypted && key === undefined) {\n throw new CiteError(\n `${opts.src} must be encrypted, and no encryption key is available. Run \\`manni key set\\`, or set ${ENCRYPTION_KEY_ENV}.`,\n );\n }\n const index = opts.sourceIndex ?? (await buildSourceIndex(opts.root, { gitClient: opts.gitClient }));\n\n const read = await readSource(opts.root, index, range, key);\n if (read.kind === \"missing\") throw refusalFor(read.reason, range.path, range.encrypted);\n\n // The out-of-range error names the source as the caller spelled it, never a\n // decrypted path.\n const joined = sliceLines(splitLines(read.text), range, range.path);\n // Set whenever `encrypt` is: refused above for a plain source, and an\n // encrypted one could not have been read without it.\n const pinKey = encrypt ? key : undefined;\n const file =\n pinKey !== undefined && !range.encrypted ? encryptSourcePath(read.resolvedPath, pinKey) : range.path;\n const lines = rangeLines(range);\n const commitSha = await commitFor(opts);\n const integrity = hashLines(joined, pinKey);\n if (commitSha !== undefined) {\n await assertCommitHolds(opts, commitSha, read.resolvedPath, range, integrity, pinKey);\n }\n\n const source: CitationSource = { file, integrity };\n // Field order is the order a reader scans a source in: which file, which\n // lines, what they hashed to, and when that was taken.\n const ordered: CitationSource = {\n file: source.file,\n ...(lines === undefined ? {} : { lines }),\n integrity: source.integrity,\n ...(commitSha === undefined ? {} : { \"commit-sha\": commitSha }),\n };\n // And an entry reads: what it is called, what it says, what it rests on.\n return {\n ...(opts.id === undefined ? {} : { id: opts.id }),\n ...(opts.claim === undefined ? {} : { claim: opts.claim }),\n source: ordered,\n ...(opts.quote === undefined ? {} : { quote: opts.quote }),\n };\n}\n","/**\n * Moving claim lines when a marker line comes or goes.\n *\n * `add --marker` inserts one line above a paragraph; `remove` deletes the\n * marker lines of the entries it takes out. Either way the claims below the\n * change have to move with the text they pin, in the same write, or the next\n * check reports a page nobody edited. One rule decides both directions, so\n * the two commands cannot disagree about which entries move.\n *\n * A change that lands *inside* a claim's own lines is not a move: it would\n * change what the pin covers. That is a refusal, and nothing is written.\n */\nimport { CiteError } from \"../errors.js\";\nimport type { LineSpec, PageCitation } from \"../types.js\";\nimport { toFileLines } from \"./claims.js\";\nimport { lineSpec, parseLines } from \"./range.js\";\nimport { spellAt } from \"./spell.js\";\n\n/** The new `claim.lines` of each entry the change moves, by where the entry lives. */\nexport interface Shifted {\n frontmatter: { index: number; lines: LineSpec }[];\n manifest: Map<number, LineSpec>;\n}\n\nexport interface ShiftOptions {\n /** The entries to move: on a removal, the ones that survive it. */\n citations: readonly PageCitation[];\n /** File lines where a marker line is inserted, or where one is removed. */\n at: readonly number[];\n /** `1` for lines coming in, `-1` for lines going out. */\n delta: 1 | -1;\n /** File line of body line 1, since `claim.lines` count the body. */\n bodyLine: number;\n /** The page as the run reports it, for the refusal. */\n label: string;\n}\n\n/**\n * The entries whose claim lines move, each by however many of `at` sit above\n * them. An insertion at a claim's first line pushes the whole claim down; a\n * removal of that line is inside the claim instead, because the line is the\n * claim's own. Hence the two comparisons.\n */\nexport function shiftedEntries(opts: ShiftOptions): Shifted {\n const { citations, at, delta, bodyLine, label } = opts;\n const out: Shifted = { frontmatter: [], manifest: new Map() };\n if (at.length === 0) return out;\n for (const { citation, origin } of citations) {\n const spec = citation.claim?.lines;\n const recorded = spec === undefined ? undefined : parseLines(spec);\n if (recorded === undefined) continue;\n const file = toFileLines(recorded, bodyLine);\n const inside = at.find((line) =>\n delta === 1\n ? line > file.start && line <= file.end\n : line >= file.start && line <= file.end,\n );\n if (inside !== undefined) {\n const whose =\n citation.id === undefined\n ? `the claim at ${spellAt(file)}`\n : `the claim of ${citation.id} (${spellAt(file)})`;\n const why =\n delta === 1\n ? \"A marker there would change its pin.\"\n : \"Removing the marker there would change its pin.\";\n throw new CiteError(`${label}:${String(inside)} is inside ${whose}. ${why}`);\n }\n const lines = at.filter((line) => (delta === 1 ? line <= file.start : line < file.start)).length;\n if (lines === 0) continue;\n const moved = lineSpec({\n start: recorded.start + lines * delta,\n end: recorded.end + lines * delta,\n });\n if (origin.kind === \"manifest\") out.manifest.set(origin.index, moved);\n else out.frontmatter.push({ index: origin.index, lines: moved });\n }\n return out;\n}\n\n/** A copy of a manifest entry with its `claim.lines` replaced. */\nexport function withClaimLines(entry: unknown, lines: LineSpec): unknown {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) return entry;\n const claim: unknown = (entry as Record<string, unknown>).claim;\n if (typeof claim !== \"object\" || claim === null || Array.isArray(claim)) return entry;\n return { ...entry, claim: { ...claim, lines } };\n}\n","/**\n * Writing a page's `citations` into the manifest that owns them.\n *\n * The splice itself is meta's (`spliceManifestValue` on the family-internal\n * barrel): one owned value of one entry is replaced, every other byte of the\n * file survives by construction, and the result is read back before it is\n * returned. This module is the part cite owns — holding each manifest's text\n * for the length of a run so it is written once, and finding the line a\n * written entry now sits on, which is what `add` reports and what a finding\n * about an entry points at.\n *\n * Only `commit` touches the disk. A caller reads the manifests it needs and\n * writes them when the whole run has succeeded, the way `key rotate` writes\n * pages only once every one of them could be re-encrypted.\n *\n * That gap is why `commit` re-reads. A run holds a manifest from its first\n * `hold` to its last write, which is seconds of minting, hashing and git, and\n * two runs over one working copy overlap easily. The compare-and-swap that\n * makes the second write see the first is `src/shared/manifest-cas.ts`, which\n * `meta fill` and `meta derive` hold their manifests with too; what stays here\n * is what cite means by an edit, which is one entry's `citations`.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { posix } from \"node:path\";\nimport { LineCounter, isMap, isNode, isScalar, isSeq, parseDocument } from \"yaml\";\nimport { DocmetaError, writeFileAtomic } from \"../../meta/index.js\";\nimport {\n readManifestValue,\n removeManifestKey,\n spliceManifestValue,\n} from \"../../meta/internal.js\";\nimport {\n heldManifest,\n isMissing,\n rebaseable,\n settle,\n type CommitIo as CasCommitIo,\n type HeldManifest as CasHeldManifest,\n type ManifestCodec,\n type ManifestOp as CasManifestOp,\n} from \"../../shared/manifest-cas.js\";\nimport { CiteError } from \"../errors.js\";\nimport { unifiedDiff } from \"./write.js\";\nimport { CITATIONS_KEY, type CitationManifest } from \"./sidecar.js\";\n\n/** One edit this run made, replayable onto bytes read later. */\ntype ManifestOp = CasManifestOp &\n ({ kind: \"splice\"; value: unknown[] } | { kind: \"remove\" });\n\n/** One manifest held for the length of a run: its text before, and now. */\nexport type HeldManifest = CasHeldManifest<ManifestOp>;\n\n/** One recorded edit, and one `citations` value read back, over a manifest. */\nconst codec: ManifestCodec<ManifestOp> = { apply, read: readManifestValue };\n\n/** One manifest this run rewrote, as `changed()` and `commit()` report it. */\nexport interface ManifestChange {\n path: string;\n file: string;\n before: string;\n text: string;\n /**\n * `before` against `text`. A commit that rebased moves `before` to the bytes\n * it compared against, so the diff then shows what this run added on top of\n * a concurrent write rather than against the read `hold()` made.\n */\n diff: string;\n}\n\n/** What `commit()` does with each manifest it settles. */\nexport type CommitIo = CasCommitIo<ManifestChange>;\n\n/** Every manifest one run writes, read once and spliced in memory. */\nexport class ManifestSet {\n private readonly held = new Map<string, HeldManifest>();\n\n /** Read a manifest, or hand back the copy this run has already rewritten. */\n async hold(manifest: CitationManifest): Promise<HeldManifest> {\n const already = this.held.get(manifest.path);\n if (already !== undefined) return already;\n let before: string;\n let absent = false;\n try {\n before = await readFile(manifest.path, \"utf8\");\n } catch (error) {\n // A per-page manifest (proposal 0058) that does not exist yet is a page\n // with nothing cited: held as empty text marked absent, and created by\n // the commit. A missing concrete manifest is refused, as it always was.\n if (manifest.pattern === undefined || !isMissing(error)) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new CiteError(`Manifest ${manifest.file} could not be read: ${reason}`);\n }\n before = \"\";\n absent = true;\n }\n const fresh = heldManifest<ManifestOp>(manifest.path, manifest.file, before, absent);\n this.held.set(manifest.path, fresh);\n return fresh;\n }\n\n /**\n * Write one page's whole `citations` list into its entry, and answer where\n * the entry at `index` now sits. The manifest is not saved: `changed()`\n * lists what the run would write.\n */\n async write(\n manifest: CitationManifest,\n entry: string,\n citations: readonly unknown[],\n index: number,\n ): Promise<{ file: string; line: number }> {\n const held = await this.hold(manifest);\n const op: ManifestOp = {\n kind: \"splice\",\n entry,\n key: CITATIONS_KEY,\n join: manifest.join,\n file: manifest.file,\n value: [...citations],\n };\n rebaseable(held, op, codec);\n const spliced = splice(held.text, {\n entry,\n key: CITATIONS_KEY,\n value: op.value,\n join: manifest.join,\n file: manifest.file,\n });\n held.text = spliced.text;\n held.ops.push(op);\n return { file: manifest.file, line: itemLine(spliced.text, entry, index, manifest.join) ?? spliced.line };\n }\n\n /**\n * Where one item of an entry's `citations` sits in the manifest as this run\n * will write it. `add` names a line in its report, and `commit` may have\n * replayed the entry onto bytes that moved it, so the line is read back from\n * the settled text rather than kept from the splice.\n */\n lineOf(manifest: CitationManifest, entry: string, index: number): number | undefined {\n const held = this.held.get(manifest.path);\n if (held === undefined) return undefined;\n return itemLine(held.text, entry, index, manifest.join);\n }\n\n /**\n * Take a page's `citations` key out of the manifest, for the removal that\n * leaves it with no entries. The entry itself goes when that key was all it\n * had, so a manifest never keeps a document nothing is recorded about.\n */\n async remove(manifest: CitationManifest, entry: string): Promise<void> {\n const held = await this.hold(manifest);\n const op: ManifestOp = {\n kind: \"remove\",\n entry,\n key: CITATIONS_KEY,\n join: manifest.join,\n file: manifest.file,\n };\n rebaseable(held, op, codec);\n held.text = apply(held.text, op);\n held.ops.push(op);\n }\n\n /** The manifests this run rewrote, with the diff of each. */\n changed(): ManifestChange[] {\n return [...this.held.values()]\n .filter((m) => m.text !== m.before)\n .map((m) => ({ ...m, diff: unifiedDiff(m.file, m.before, m.text) }));\n }\n\n /**\n * Write every manifest this run rewrote, and report what landed.\n *\n * The write is the last thing a run does, so this is the one place that\n * knows a manifest is about to be replaced by bytes derived from a read\n * that may be seconds old.\n */\n async commit(io: CommitIo = {}): Promise<ManifestChange[]> {\n // A per-page manifest (proposal 0058) may be the first file in its directory.\n const write =\n io.write ?? ((at: string, text: string): Promise<void> => writeFileAtomic(at, text, { createParents: true }));\n const read = io.read ?? ((at: string): Promise<string> => readFile(at, \"utf8\"));\n const landed: ManifestChange[] = [];\n for (const held of this.held.values()) {\n if (held.text === held.before) continue;\n try {\n await settle(held, { codec, write, read, toError: (message) => new CiteError(message) });\n } catch (error) {\n if (io.onError !== undefined) await io.onError(changeOf(held), error);\n throw error;\n }\n const change = changeOf(held);\n landed.push(change);\n io.after?.(change);\n }\n return landed;\n }\n}\n\n/** The change one held manifest reports, against the bytes it will replace. */\nfunction changeOf(held: HeldManifest): ManifestChange {\n return {\n path: held.path,\n file: held.file,\n before: held.before,\n text: held.text,\n diff: unifiedDiff(held.file, held.before, held.text),\n };\n}\n\n/** One recorded edit, against whatever text it is handed. */\nfunction apply(text: string, op: ManifestOp): string {\n const where = { entry: op.entry, key: op.key, join: op.join, file: op.file };\n if (op.kind === \"splice\") return splice(text, { ...where, value: op.value }).text;\n try {\n return removeManifestKey(text, where).text;\n } catch (error) {\n if (error instanceof DocmetaError) throw new CiteError(error.message);\n throw error;\n }\n}\n\n/** `spliceManifestValue`, with meta's refusal reported as this tool's. */\nexport function splice(\n text: string,\n options: Parameters<typeof spliceManifestValue>[1],\n): { text: string; line: number } {\n try {\n return spliceManifestValue(text, options);\n } catch (error) {\n if (error instanceof DocmetaError) throw new CiteError(error.message);\n throw error;\n }\n}\n\n/**\n * The 1-based line of one item of an entry's `citations`, in a manifest that\n * may not have been written yet. The loader answers this for a manifest on\n * disk; a freshly spliced one has to be read where it stands, so `add` can\n * say where the entry it just wrote went.\n */\nexport function itemLine(\n text: string,\n entry: string,\n index: number,\n join: string,\n): number | undefined {\n const lc = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n if (doc.errors.length > 0) return undefined;\n const root = doc.contents;\n if (!isMap(root)) return undefined;\n const same = (key: unknown): boolean => {\n const spelled = isScalar(key) ? String(key.value) : String(key);\n return join === \"path\" ? posix.normalize(spelled) === posix.normalize(entry) : spelled === entry;\n };\n const pair = root.items.find((p) => same(p.key));\n const value = pair?.value;\n if (!isMap(value)) return undefined;\n const kv = value.items.find(\n (p) => (isScalar(p.key) ? String(p.key.value) : String(p.key)) === CITATIONS_KEY,\n );\n const list = kv?.value;\n if (!isSeq(list)) return undefined;\n const item: unknown = list.items[index];\n const range = isNode(item) ? item.range : undefined;\n return range ? lc.linePos(range[0]).line : undefined;\n}\n","/**\n * Every way the tool rewrites a page. Frontmatter appends go through meta's\n * `applyFrontmatter` (comments and key order preserved). A repair splices one\n * scalar textually at `lineFor(\"/citations/N/source/lines\")` and the like, so\n * nothing else in the block is touched. Markers are inserted by offset with\n * the page's own EOL. Files are written with `writeFileAtomic`.\n *\n * A rewrite of the body goes through `applyEdits`: the caller collects every\n * span it means to replace against one parse and hands them over together, so\n * no position is ever read out of text that has already been written to.\n */\nimport { DocmetaError, locateFrontmatter, type MetadataExtractor } from \"../../meta/index.js\";\nimport { extractorByName } from \"../../meta/internal.js\";\nimport { CiteError } from \"../errors.js\";\nimport type { Citation, LineSpec, TextEdit } from \"../types.js\";\nimport { splitLines } from \"./hash.js\";\nimport { detectEol, lineAt, offsetOfLine } from \"./statements.js\";\n\nfunction extractorFor(format: string): MetadataExtractor {\n const extractor = extractorByName(format);\n if (!extractor) throw new CiteError(`Unknown format \"${format}\".`);\n return extractor;\n}\n\n/**\n * Whether the format reads a leading fenced block as its frontmatter. Asked\n * of the extractor itself rather than kept as a list of names here, so a\n * format added to meta's registry answers for itself. An element-backed\n * format (html, xml) sees the probe as body text and says no.\n */\nfunction readsFencedFrontmatter(extractor: MetadataExtractor, label: string): boolean {\n return extractor.extract(\"---\\nprobe: 1\\n---\\n\", label).fenced === true;\n}\n\n/** Append one entry to `citations` (creating the key), via the format's extractor. */\nexport function appendFrontmatterCitation(\n content: string,\n format: string,\n citation: Citation,\n filePath?: string,\n): string {\n const label = filePath ?? \"the page\";\n const extractor = extractorFor(format);\n // Element-backed metadata (html, xml) has `apply` too, but it is not\n // frontmatter. Whether this *page* can take a block is `apply`'s call:\n // markdown creates one, asciidoc and rst refuse when none exists.\n if (!extractor.apply || !readsFencedFrontmatter(extractor, label)) {\n throw new CiteError(\n `${label} has no frontmatter to write to; keep its citations in a manifest instead.`,\n );\n }\n const extracted = extractor.extract(content, label);\n if (locateFrontmatter(content)?.flavor === \"toml\") {\n throw new CiteError(\n `${label} has TOML frontmatter; manni cannot add a citations table without re-emitting the whole block, which would drop its comments. Add the entry by hand.`,\n );\n }\n\n const raw: unknown = extracted.data.citations ?? [];\n if (!Array.isArray(raw)) {\n throw new CiteError(`${label}: \\`citations\\` is not a list; edit it by hand.`);\n }\n // `isArray` narrows `unknown` to `any[]`; name the element type before it spreads.\n const existing: unknown[] = raw;\n const entry = entryObject(citation);\n try {\n return extractor.apply(content, { citations: [...existing, entry] });\n } catch (e) {\n if (e instanceof DocmetaError) throw new CiteError(`${label}: ${e.message}`);\n throw e;\n }\n}\n\n/**\n * Take entries out of a page's `citations`, by their index in the list, and\n * write what is left back through the format's extractor. An empty list\n * removes the key: an entry deleted by hand once left a `citations:` with\n * nothing under it, and a page that carries no citations should say so by\n * carrying no key.\n *\n * The write is the inverse of `appendFrontmatterCitation` and goes the same\n * way, so a page manni can add to is a page manni can remove from.\n */\nexport function removeFrontmatterCitations(\n content: string,\n format: string,\n drop: ReadonlySet<number>,\n filePath?: string,\n): string {\n const label = filePath ?? \"the page\";\n const extractor = extractorFor(format);\n if (!extractor.apply || !readsFencedFrontmatter(extractor, label)) {\n throw new CiteError(\n `${label} has no frontmatter to write to; keep its citations in a manifest instead.`,\n );\n }\n if (locateFrontmatter(content)?.flavor === \"toml\") {\n throw new CiteError(\n `${label} has TOML frontmatter; manni cannot rewrite a citations table without re-emitting the whole block, which would drop its comments. Remove the entry by hand.`,\n );\n }\n const raw: unknown = extractor.extract(content, label).data.citations ?? [];\n if (!Array.isArray(raw)) {\n throw new CiteError(`${label}: \\`citations\\` is not a list; edit it by hand.`);\n }\n const existing: unknown[] = raw;\n const kept = existing.filter((_entry, index) => !drop.has(index));\n try {\n return kept.length === 0\n ? extractor.apply(content, {}, { deletions: [\"citations\"] })\n : extractor.apply(content, { citations: kept });\n } catch (e) {\n if (e instanceof DocmetaError) throw new CiteError(`${label}: ${e.message}`);\n throw e;\n }\n}\n\n/**\n * `content` with every edit applied in one pass. Each edit's `start` and `end`\n * index `content` as it was handed in, never the text an earlier edit\n * produced, and that is the whole point: a caller collects its edits from one\n * parse and applies them together, so no position outlives the text it was\n * read from and the order they were collected in cannot matter.\n *\n * Edits may not overlap. Two writers reaching for the same bytes is a bug in\n * the caller rather than something to resolve here, so it throws instead of\n * picking a winner. `lineRemovals` is what keeps two neighbouring lines from\n * being that bug.\n */\nexport function applyEdits(content: string, edits: readonly TextEdit[]): string {\n const sorted = [...edits].sort((a, b) => a.start - b.start);\n let out = \"\";\n let at = 0;\n for (const edit of sorted) {\n if (edit.end < edit.start) {\n throw new Error(`cite: backwards edit [${String(edit.start)}, ${String(edit.end)})`);\n }\n if (edit.start < at) {\n throw new Error(`cite: overlapping edits at ${String(edit.start)}`);\n }\n out += content.slice(at, edit.start) + edit.text;\n at = edit.end;\n }\n return out + content.slice(at);\n}\n\n/**\n * The edits that take 1-based `lines` out of `content`, their terminators\n * included: one edit per run of consecutive lines, so two neighbours never\n * reach for the same break. Order and repeats in `lines` do not matter.\n */\nexport function lineRemovals(content: string, lines: readonly number[]): TextEdit[] {\n const sorted = [...new Set(lines)].sort((a, b) => a - b);\n const out: TextEdit[] = [];\n let run: { first: number; last: number } | undefined;\n for (const line of sorted) {\n if (run !== undefined && line === run.last + 1) run.last = line;\n else {\n if (run !== undefined) out.push(runRemoval(content, run.first, run.last));\n run = { first: line, last: line };\n }\n }\n if (run !== undefined) out.push(runRemoval(content, run.first, run.last));\n return out;\n}\n\n/** The span covering 1-based lines `first`..`last` and their terminator. */\nfunction runRemoval(content: string, first: number, last: number): TextEdit {\n let start = offsetOfLine(content, first);\n // `offsetOfLine` answers the length when asked past the end, so a run whose\n // span reaches it on a page with no final newline is the tail of the file.\n // It has no terminator below it to take, so it takes the one above: on CRLF\n // that break is two bytes, and stopping at the LF would leave the CR behind\n // as the tail of a line that is gone. `spliceEntryField` pulls back over a\n // CR for the same reason.\n const end = offsetOfLine(content, last + 1);\n if (end === content.length && !content.endsWith(\"\\n\") && start > 0) {\n let above = content.lastIndexOf(\"\\n\", start - 1);\n if (above > 0 && content.charAt(above - 1) === \"\\r\") above--;\n start = above === -1 ? 0 : above;\n }\n return { start, end, text: \"\" };\n}\n\n/** Delete the whole of 1-based `line`, its terminator included. */\nexport function removeLine(content: string, line: number): string {\n return applyEdits(content, lineRemovals(content, [line]));\n}\n\n/**\n * The entry as a plain object, in the order a reader scans it, with every\n * absent optional left out rather than written as `null`.\n */\nexport function entryObject(citation: Citation): Record<string, unknown> {\n const source: Record<string, unknown> = { file: citation.source.file };\n if (citation.source.lines !== undefined) source.lines = citation.source.lines;\n source.integrity = citation.source.integrity;\n if (citation.source[\"commit-sha\"] !== undefined) {\n source[\"commit-sha\"] = citation.source[\"commit-sha\"];\n }\n const entry: Record<string, unknown> = {};\n if (citation.id !== undefined) entry.id = citation.id;\n if (citation.claim !== undefined) {\n const claim: Record<string, unknown> = {};\n if (citation.claim.lines !== undefined) claim.lines = citation.claim.lines;\n claim.integrity = citation.claim.integrity;\n entry.claim = claim;\n }\n entry.source = source;\n if (citation.quote !== undefined) entry.quote = citation.quote;\n return entry;\n}\n\n/** Plain YAML scalars that would read back as something other than the string. */\nfunction needsYamlQuotes(value: string): boolean {\n return (\n value === \"\" ||\n /^[\\s!&*?|>'\"%@`{}[\\],#]/.test(value) ||\n /^-(\\s|$)/.test(value) ||\n /:\\s|\\s#|:$|\\s$/.test(value) ||\n /^(?:true|false|null|~|yes|no|on|off|[-+]?(?:\\d[\\d_]*\\.?\\d*|\\.\\d+)(?:e[-+]?\\d+)?)$/i.test(value)\n );\n}\n\n/** `\"…\"` with the escapes YAML and JSON share. */\nconst doubleQuote = (value: string): string => JSON.stringify(value);\nconst singleQuote = (value: string): string => `'${value.replace(/'/g, \"''\")}'`;\n\n/**\n * Split a `key: value` line into its lead (` - src: `), the scalar, and what\n * trails it (a comment, a JSON comma). Undefined when the line does not carry\n * `field`.\n */\nfunction splitScalarLine(\n line: string,\n field: string,\n): { lead: string; scalar: string; trail: string } | undefined {\n const keyed = new RegExp(`^(\\\\s*(?:-\\\\s+)?\"?${field}\"?\\\\s*:\\\\s*)(.*)$`).exec(line);\n const lead = keyed?.[1];\n const rest = keyed?.[2];\n if (lead === undefined || rest === undefined) return undefined;\n const quote = rest.charAt(0);\n let end: number;\n if (quote === '\"' || quote === \"'\") {\n end = -1;\n for (let i = 1; i < rest.length; i++) {\n const ch = rest.charAt(i);\n if (quote === '\"' && ch === \"\\\\\") {\n i++;\n } else if (ch === quote) {\n if (quote === \"'\" && rest.charAt(i + 1) === \"'\") {\n i++;\n continue;\n }\n end = i + 1;\n break;\n }\n }\n if (end < 0) return undefined;\n } else {\n const comment = /\\s#/.exec(rest);\n end = comment ? comment.index : rest.length;\n while (end > 0 && /\\s/.test(rest.charAt(end - 1))) end--;\n }\n return { lead, scalar: rest.slice(0, end), trail: rest.slice(end) };\n}\n\n/** One scalar of an entry a repair may rewrite: a file, an end's lines, its pin, or the commit. */\nexport type EntryPath = readonly [\n end: \"claim\" | \"source\",\n field: \"file\" | \"lines\" | \"integrity\" | \"commit-sha\",\n];\n\n/** Replace the scalar on one line of entry N, e.g. `source.lines` after a move. */\nexport function spliceEntryField(\n content: string,\n format: string,\n index: number,\n path: EntryPath,\n value: LineSpec,\n): string {\n const [which, field] = path;\n const refuse = (): CiteError =>\n new CiteError(\n `Cannot rewrite citations[${String(index)}].${which}.${field} in ${format} frontmatter; edit it by hand.`,\n );\n const extractor = extractorFor(format);\n const pointer = `/citations/${String(index)}/${which}/${field}`;\n // `lineFor` walks up to the nearest recorded ancestor when the exact\n // pointer is unknown (TOML records top-level keys only), so the line it\n // names is checked for the field before anything is touched.\n const line = extractor.extract(content, \"page\").lineFor(pointer);\n if (line === undefined) throw refuse();\n const start = offsetOfLine(content, line);\n const nl = content.indexOf(\"\\n\", start);\n let end = nl === -1 ? content.length : nl;\n if (end > start && content.charAt(end - 1) === \"\\r\") end--;\n const parts = splitScalarLine(content.slice(start, end), field);\n if (!parts) throw refuse();\n\n const quote = parts.scalar.charAt(0);\n // A number is written plain whatever the old value's quoting was, so that\n // a range that became one line reads back as the integer it now is.\n const spelled =\n typeof value === \"number\" ? String(value)\n : quote === '\"' ? doubleQuote(value)\n : quote === \"'\" ? singleQuote(value)\n : needsYamlQuotes(value) ? doubleQuote(value)\n : value;\n const out = content.slice(0, start) + parts.lead + spelled + parts.trail + content.slice(end);\n\n // Read it back: a splice that lands anywhere but on that one value is a\n // refusal, not a damaged page.\n const check: unknown = extractor.extract(out, \"page\").data.citations;\n const entry: unknown = Array.isArray(check) ? check[index] : undefined;\n const block = isRecord(entry) ? entry[which] : undefined;\n const readBack = isRecord(block) ? block[field] : undefined;\n if (readBack !== value) throw refuse();\n return out;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Insert a statement line before the line containing `offset`, with the page's EOL. */\nexport function insertStatementBefore(\n content: string,\n offset: number,\n statement: string,\n): string {\n const start = offsetOfLine(content, lineAt(content, offset));\n return content.slice(0, start) + statement + detectEol(content) + content.slice(start);\n}\n\ntype Edit = { op: \" \" | \"-\" | \"+\"; text: string };\n\n/**\n * A unified diff of two texts, `---`/`+++` headers with the same label. Lines\n * are the hashing rule's (`splitLines`): a BOM is never part of a line, so a\n * page that carries one diffs the same as one that does not.\n */\nexport function unifiedDiff(label: string, before: string, after: string): string {\n const a = splitLines(before);\n const b = splitLines(after);\n // Shared prefix and suffix leave the LCS table to the lines that differ.\n let head = 0;\n while (head < a.length && head < b.length && a[head] === b[head]) head++;\n let tail = 0;\n while (tail < a.length - head && tail < b.length - head && a[a.length - 1 - tail] === b[b.length - 1 - tail]) tail++;\n const x = a.slice(head, a.length - tail);\n const y = b.slice(head, b.length - tail);\n if (x.length === 0 && y.length === 0) return \"\";\n\n const width = y.length + 1;\n const lcs = new Uint32Array((x.length + 1) * width);\n for (let i = x.length - 1; i >= 0; i--) {\n for (let j = y.length - 1; j >= 0; j--) {\n lcs[i * width + j] =\n x[i] === y[j]\n ? (lcs[(i + 1) * width + j + 1] ?? 0) + 1\n : Math.max(lcs[(i + 1) * width + j] ?? 0, lcs[i * width + j + 1] ?? 0);\n }\n }\n const edits: Edit[] = a.slice(0, head).map((text) => ({ op: \" \", text }));\n let i = 0;\n let j = 0;\n while (i < x.length || j < y.length) {\n const xi = x[i];\n const yj = y[j];\n if (xi !== undefined && yj !== undefined && xi === yj) {\n edits.push({ op: \" \", text: xi });\n i++;\n j++;\n } else if (xi !== undefined && (yj === undefined || (lcs[(i + 1) * width + j] ?? 0) >= (lcs[i * width + j + 1] ?? 0))) {\n // Deletions before insertions on a tie, as unified diffs read.\n edits.push({ op: \"-\", text: xi });\n i++;\n } else if (yj !== undefined) {\n edits.push({ op: \"+\", text: yj });\n j++;\n }\n }\n edits.push(...a.slice(a.length - tail).map((text) => ({ op: \" \" as const, text })));\n\n // Hunks: each change with one line of context; hunks whose context touches merge.\n const CONTEXT = 1;\n const out = [`--- ${label}`, `+++ ${label}`];\n let pos = 0;\n while (pos < edits.length) {\n if (edits[pos]?.op === \" \") {\n pos++;\n continue;\n }\n const from = Math.max(0, pos - CONTEXT);\n let to = pos;\n for (let k = pos; k < edits.length; k++) {\n if (edits[k]?.op !== \" \") to = k;\n else if (k - to > CONTEXT * 2) break;\n }\n to = Math.min(edits.length - 1, to + CONTEXT);\n let oldStart = 1;\n let newStart = 1;\n for (let k = 0; k < from; k++) {\n const op = edits[k]?.op;\n if (op !== \"+\") oldStart++;\n if (op !== \"-\") newStart++;\n }\n const slice = edits.slice(from, to + 1);\n const oldCount = slice.filter((e) => e.op !== \"+\").length;\n const newCount = slice.filter((e) => e.op !== \"-\").length;\n out.push(\n `@@ -${oldCount === 0 ? oldStart - 1 : oldStart},${oldCount} +${newCount === 0 ? newStart - 1 : newStart},${newCount} @@`,\n ...slice.map((e) => e.op + e.text),\n );\n pos = to + 1;\n }\n return out.join(\"\\n\") + \"\\n\";\n}\n","/**\n * `manni cite remove`: take a citation off a page.\n *\n * The inverse of `add`, and it undoes all of what `add` did. The entry goes\n * out of the page's frontmatter, or out of the manifest that owns the page's\n * citations, whichever `add` would have written to. Every marker naming it\n * goes out of the body: the id goes out of the marker list, and the whole\n * line goes when that id was the last one (proposal 0056). The claims below\n * each removed marker line move up with the text they pin, which is the\n * inverse of the shift `add --marker` performs and the same rule\n * (`shiftedEntries`). A marker that only loses a word moves nothing.\n *\n * `--only` is required, one entry per occurrence, and nothing is written\n * until every one of them has been found: a run either removes what it was\n * told to or writes nothing. That is `add`'s contract, and the reason there\n * is no exit 1 here.\n *\n * An id with a marker and no entry removes the marker alone, which is how a\n * `marker-orphan` is cleared.\n */\nimport { resolve } from \"node:path\";\nimport { writeFileAtomic } from \"../../meta/index.js\";\nimport { STDIN_LABEL } from \"../../meta/internal.js\";\nimport { ManifestSet } from \"../core/manifest.js\";\nimport { citationInputs, pickExtractor, readPage } from \"../core/page.js\";\nimport { shiftedEntries, withClaimLines } from \"../core/shift.js\";\nimport { isMarkerLine, respellEdit } from \"../core/statements.js\";\nimport { splitLines } from \"../core/hash.js\";\nimport {\n applyEdits,\n lineRemovals,\n removeFrontmatterCitations,\n spliceEntryField,\n unifiedDiff,\n} from \"../core/write.js\";\nimport { CiteError } from \"../errors.js\";\nimport type {\n CitationInput,\n InlineStatement,\n ManifestChange,\n Removal,\n RemoveOptions,\n RemovePage,\n RemoveRun,\n TextEdit,\n} from \"../types.js\";\nimport { assertNoOrphanJoins, assertNoOrphans, joinHits, prepareRun, readTarget } from \"./check.js\";\n\n/** How an entry with no id is named: its place in the page's list. */\nconst POINTER = /^\\/citations\\/(0|[1-9][0-9]*)$/;\n\n/** `4 entries`, `1 entry`. */\nfunction entryCount(n: number): string {\n return `${String(n)} ${n === 1 ? \"entry\" : \"entries\"}`;\n}\n\n/** The `id` of a raw entry, whether or not the schema would accept the rest of it. */\nfunction idOf(entry: unknown): string | undefined {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) return undefined;\n const id: unknown = (entry as Record<string, unknown>).id;\n return typeof id === \"string\" ? id : undefined;\n}\n\n/** What one page's run found, before anything is written. */\ninterface Planned {\n page: RemovePage;\n /** The page as it will be written, when it changed. */\n content?: string;\n /** Absolute path to write it to; absent for the stdin page. */\n path?: string;\n}\n\nexport async function runRemove(opts: RemoveOptions): Promise<RemoveRun> {\n // Repeats collapse, as they do on `--collection`: naming one entry twice\n // asks for one removal, and would otherwise be counted twice.\n const only = [...new Set(opts.only)];\n // Asked before the config is read: it is a usage error, and the answer does\n // not depend on anything on disk.\n if (only.length === 0) {\n throw new CiteError(\"remove needs --only <id>; it never removes every citation on a page.\");\n }\n // Nothing here resolves a source: the run builds no index, and says\n // nothing about where `src:` paths would have come from.\n const prepared = await prepareRun({ ...opts, checkSources: false }, \"removed\", \"remove\", {\n resolve: false,\n });\n const { run, files, usingStdin, forced } = prepared;\n await assertNoOrphans(prepared);\n const hits = joinHits();\n const manifests = new ManifestSet();\n /** Every `--only` value that named something, anywhere in the run. */\n const matched = new Set<string>();\n const pageCount = files.length + (usingStdin ? 1 : 0);\n\n const planned: Planned[] = [];\n const removeOne = async (label: string, content: string, path?: string): Promise<void> => {\n const setup = await prepared.setupFor(label, content);\n if (setup.sidecar !== undefined) hits.record(setup.sidecar, label);\n const owner = setup.sidecar?.owner;\n const page = readPage(label, content, {\n ...(forced === undefined ? {} : { format: forced.name }),\n ...(setup.options.citations === undefined ? {} : { citations: setup.options.citations }),\n ...(owner === undefined ? {} : { owned: { file: owner.file, collection: owner.collection } }),\n });\n const { format } = page;\n const extractor = pickExtractor(label, forced?.name);\n const inputs: CitationInput[] = citationInputs(\n label,\n extractor.extract(content, label),\n setup.sidecar?.citations,\n );\n const lines = splitLines(content);\n\n /** The entries one `--only` value names on this page. */\n const entriesFor = (value: string): number[] => {\n // The digits of a pointer, or nothing for a value that is an id. Read\n // as a capture rather than through `exec(...) !== null`, so the index\n // is a string the compiler has seen narrowed.\n const [, digits] = POINTER.exec(value) ?? [];\n if (digits === undefined) {\n return inputs.flatMap((input, index) => (idOf(input.entry) === value ? [index] : []));\n }\n const index = Number(digits);\n if (index < inputs.length) return [index];\n // A pointer is a position, so over several pages it means the entry at\n // that position wherever there is one. Against one page there is no\n // other page it could have meant.\n if (pageCount === 1) {\n throw new CiteError(\n `\"${value}\" is past the last entry of ${label} (${entryCount(inputs.length)}).`,\n );\n }\n return [];\n };\n /** The markers naming an id. */\n const markersFor = (id: string | undefined): InlineStatement[] =>\n id === undefined\n ? []\n : page.statements.filter(\n (s) => s.payload.kind === \"ref\" && s.payload.ids.includes(id),\n );\n /** Per marker line, the ids this run takes out of its list. */\n const dropped = new Map<number, { statement: InlineStatement; ids: Set<string> }>();\n const drop = (statement: InlineStatement, id: string): void => {\n const held = dropped.get(statement.line) ?? { statement, ids: new Set<string>() };\n held.ids.add(id);\n dropped.set(statement.line, held);\n };\n\n const removed: Removal[] = [];\n const indices = new Set<number>();\n const markerLines: number[] = [];\n for (const value of only) {\n const found = entriesFor(value);\n for (const index of found) {\n const input = inputs[index];\n const id = idOf(input?.entry);\n const markers = markersFor(id);\n indices.add(index);\n markerLines.push(...markers.map((s) => s.line));\n if (id !== undefined) for (const statement of markers) drop(statement, id);\n removed.push({\n ...(id === undefined ? {} : { id }),\n index,\n ...(input === undefined ? {} : { origin: input.origin }),\n markerLines: markers.map((s) => s.line),\n });\n matched.add(value);\n }\n if (found.length > 0) continue;\n // An id no entry carries, but a marker names: the marker alone.\n const markers = markersFor(value);\n if (markers.length === 0) continue;\n markerLines.push(...markers.map((s) => s.line));\n for (const statement of markers) drop(statement, value);\n removed.push({ id: value, markerLines: markers.map((s) => s.line) });\n matched.add(value);\n }\n const nothing: RemovePage = { file: label, removed: [], diff: \"\", written: false };\n if (removed.length === 0) {\n // The stdin page is printed whatever the run did to it.\n if (path === undefined) nothing.content = content;\n planned.push({ page: nothing, ...(path === undefined ? {} : { path }) });\n return;\n }\n\n // A marker sharing its line with text anchors that text, so the line is\n // not the tool's to delete. The refusal is a property of the line rather\n // than of the payload, so it holds however many ids the marker names.\n const touched = [...new Set(markerLines)].sort((a, b) => a - b);\n for (const line of touched) {\n if (!isMarkerLine(lines[line - 1] ?? \"\", format)) {\n const id = page.statements.find((s) => s.line === line)?.payload;\n const named = id?.kind === \"ref\" ? ` ${id.ids.join(\" \")}` : \"\";\n throw new CiteError(\n `the marker${named} at ${label}:${String(line)} shares its line with text; remove it by hand.`,\n );\n }\n }\n // A marker that keeps an id keeps its line: the word goes out of the list\n // and nothing below it moves. Only a marker that loses its last id is a\n // line to delete (proposal 0056).\n const kept = new Map<number, [string, ...string[]]>();\n const ordered: number[] = [];\n for (const line of touched) {\n const held = dropped.get(line);\n // Destructured rather than cast: a marker that keeps nothing is a line\n // to delete, and the head is what tells the two apart.\n const [head, ...rest] =\n held === undefined || held.statement.payload.kind !== \"ref\"\n ? []\n : held.statement.payload.ids.filter((id) => !held.ids.has(id));\n if (head === undefined) ordered.push(line);\n else kept.set(line, [head, ...rest]);\n }\n\n // What stays, moved up by the marker lines going out above it.\n const survivors = page.citations.filter((c) => !indices.has(c.origin.index));\n const shifted = shiftedEntries({\n citations: survivors,\n at: ordered,\n delta: -1,\n bodyLine: page.bodyLine,\n label,\n });\n\n // One parse, one pass.\n //\n // Every position the body rewrite reads -- a statement's byte offsets, a\n // marker's line number -- is read against `content`, the page as it was\n // parsed, and the edits are collected as spans and applied together. So no\n // offset is used after the text it indexes has changed, and no writer has\n // to run before or after another to be correct. The ordering contract this\n // carried is gone rather than satisfied: it was got wrong three times, in\n // three review rounds, and each time silently -- the edit lands nowhere,\n // the entry leaves the frontmatter, and the marker still names the id\n // until some later `cite check` reports a `marker-orphan` with nothing to\n // explain it.\n const edits: TextEdit[] = [];\n for (const [line, ids] of kept) {\n const held = dropped.get(line);\n if (held === undefined) continue;\n const edit = respellEdit(content, held.statement, ids);\n // `content` is the text the statement was parsed from, so the payload is\n // where the statement says it is. A miss would mean the parse and the\n // page disagree, which is worth stopping for rather than writing a page\n // whose marker still names an id no entry has.\n if (edit === undefined) {\n throw new CiteError(\n `manni cannot read the marker at ${label}:${String(line)} to rewrite it; remove it by hand.`,\n );\n }\n edits.push(edit);\n }\n // The marker lines that lost their last id, taken out with their\n // terminators. Neighbours merge into one span, so no two of them reach for\n // the same break.\n edits.push(...lineRemovals(content, ordered));\n let after = applyEdits(content, edits);\n // Then the frontmatter. Both of its writers re-derive their own position\n // from the text they are handed -- `spliceEntryField` by re-extracting,\n // `removeFrontmatterCitations` by re-reading the list -- so neither reads\n // anything out of the parse above and neither cares what the body pass\n // did. The splice still runs before the removal, but for a different\n // reason: its `index` counts the entries the page has now, and the removal\n // is what renumbers them.\n for (const { index, lines: moved } of shifted.frontmatter) {\n after = spliceEntryField(after, format, index, [\"claim\", \"lines\"], moved);\n }\n if (owner === undefined) {\n after = removeFrontmatterCitations(after, format, indices, label);\n } else {\n if (setup.sidecar?.entry === undefined) {\n throw new CiteError(\n `${label} carries no ${owner.join}: value, so its citations cannot be keyed in ${owner.file}.`,\n );\n }\n const kept = inputs\n .map((input, index) => {\n const moved = shifted.manifest.get(index);\n return moved === undefined ? input.entry : withClaimLines(input.entry, moved);\n })\n .filter((_entry, index) => !indices.has(index));\n if (kept.length === 0) await manifests.remove(owner, setup.sidecar.entry);\n // The line a written entry sits on is what `add` reports; a removal\n // reports the line the entry sat on before, from its origin. So the\n // answer is dropped here, and the index it is measured from is any\n // index at all.\n else void (await manifests.write(owner, setup.sidecar.entry, kept, 0));\n }\n\n const out: RemovePage = {\n file: label,\n removed,\n diff: after === content ? \"\" : unifiedDiff(label, content, after),\n written: false,\n };\n // The stdin page has nowhere to be written; the caller prints it instead.\n if (path === undefined) out.content = after;\n planned.push({ page: out, ...(after === content ? {} : { content: after }), ...(path === undefined ? {} : { path }) });\n };\n\n if (usingStdin) await removeOne(STDIN_LABEL, opts.stdinContent ?? \"\");\n for (const file of files) {\n await removeOne(file, await readTarget(run, file), resolve(run.base, file));\n }\n assertNoOrphanJoins(prepared, hits);\n\n // Every name has to have been found somewhere before a byte is written.\n const missing = only.find((value) => !matched.has(value));\n if (missing !== undefined) {\n const where =\n pageCount === 1\n ? `${planned[0]?.page.file ?? \"the page\"} has no`\n : `none of ${String(pageCount)} pages has an`;\n const what = POINTER.test(missing) ? `entry ${missing}` : `entry or marker ${missing}`;\n throw new CiteError(`${where} ${what}.`);\n }\n\n const write = opts.dryRun !== true;\n for (const item of planned) {\n if (item.content === undefined || item.path === undefined) continue;\n if (write) await writeFileAtomic(item.path, item.content);\n item.page.written = write;\n }\n const rewritten: ManifestChange[] = [];\n const record = (changed: { file: string; diff: string }): void => {\n rewritten.push({ file: changed.file, diff: changed.diff, written: write });\n };\n if (write) await manifests.commit({ after: record });\n else for (const changed of manifests.changed()) record(changed);\n\n const pages = planned.map((item) => item.page);\n return {\n pages,\n removed: pages.reduce((n, page) => n + page.removed.length, 0),\n ...(rewritten.length > 0 ? { manifests: rewritten } : {}),\n };\n}\n","/**\n * `manni cite update`: repair what moved; with `--accept`, re-pin what changed.\n *\n * A moved end gets its `lines` spliced where it stands, so comments and\n * quoting are untouched: `claim.lines` for a claim found verbatim elsewhere on\n * the page, `source.lines` for a source found elsewhere in its file. A moved\n * source is re-minted over the range it moved to, so its `commit-sha` names a\n * commit its new lines are true at. A marker never moves, because it travels\n * with its own text.\n *\n * `--accept` re-pins a changed end. A claim is re-pinned over the paragraph,\n * fenced block or table rows now at its first line, and the report prints that\n * text, so the log shows exactly what was accepted. A paragraph grows with the\n * sentence it gained; a table keeps the number of rows the claim was minted\n * over, because a row is a statement of its own. A claim it cannot re-pin is\n * skipped with the reason named, and a sentence that was reworded *and* moved\n * is an `add` again. A source is re-minted at HEAD, with a new `commit-sha`\n * where the entry records one.\n *\n * Every finding the run did not resolve is reported as skipped, and an\n * error-severity one is work left undone: exit 1, as `fill` has it. Writes by\n * default (0025).\n */\nimport { resolve } from \"node:path\";\nimport { writeFileAtomic } from \"../../meta/index.js\";\nimport { STDIN_LABEL } from \"../../meta/internal.js\";\nimport { checkCitations } from \"../core/check-page.js\";\nimport {\n noUnitAt,\n normalizeWhitespace,\n otherClaimSpans,\n pinOfLines,\n spellElsewhere,\n toBodyLines,\n toFileLines,\n unitAt,\n type ClaimUnit,\n type NoUnit,\n} from \"../core/claims.js\";\nimport { historyOf } from \"../core/classify.js\";\nimport { GIT_UNAVAILABLE_COMMIT, SHALLOW_RECOMMIT } from \"../core/git.js\";\nimport { splitLines } from \"../core/hash.js\";\nimport { claimWords, sharesSentence, wordShare } from \"../core/history.js\";\nimport { mintCitation } from \"../core/mint.js\";\nimport { ManifestSet } from \"../core/manifest.js\";\nimport { readPage } from \"../core/page.js\";\nimport {\n formatSrc,\n lineSpec,\n parseLines,\n parseSrc,\n sourceRange,\n spellLines,\n tooWide,\n} from \"../core/range.js\";\nimport {\n applyMarkerMoves,\n misplacedMarkers,\n type MisplacedMarker,\n} from \"../core/reanchor.js\";\nimport { resolveSeverity } from \"../core/severity.js\";\nimport { listOf, spellAt } from \"../core/spell.js\";\nimport { anchoredLines, markerIndent, offsetOfLine } from \"../core/statements.js\";\nimport { spliceEntryField, unifiedDiff } from \"../core/write.js\";\nimport { CiteError } from \"../errors.js\";\nimport type {\n Citation,\n CitationResult,\n CiteRule,\n ClaimEnd,\n LineSpec,\n ManifestChange,\n PageCitation,\n PageCitationReport,\n PageCitations,\n PageLines,\n RecommitReason,\n UpdateOptions,\n UpdatePage,\n UpdateRewrite,\n UpdateRun,\n} from \"../types.js\";\nimport {\n assertNoOrphanJoins,\n assertNoOrphans,\n joinHits,\n prepareRun,\n readTarget,\n sayNotices,\n} from \"./check.js\";\n\ntype Plan =\n | { kind: \"claim-moved\"; result: CitationResult; lines: LineSpec; from: string; to: string }\n /**\n * The pinned lines sit elsewhere in the file now. The entry is re-minted\n * over them, so its `lines`, its `integrity` and its `commit-sha` are three\n * parts of one reading rather than two new ones and a stale third.\n */\n | {\n kind: \"source-moved\";\n result: CitationResult;\n /** The new `source.lines`; absent for a whole-file pin, which has none. */\n lines?: LineSpec;\n /**\n * The new `source.file`, when the pin followed its text into another\n * file. The entry's own `commit-sha` is then left alone: the pin was\n * minted at that commit and still holds, so HEAD would record a mint\n * that never happened (proposal 0055).\n */\n file?: string;\n /** The pin the entry carries afterwards. */\n pin: string;\n /** The commit to advance to, for a move inside the entry's own file. */\n commitSha?: string;\n to: string;\n }\n | {\n kind: \"claim-accepted\";\n result: CitationResult;\n unit: ClaimUnit;\n pin: string;\n lines?: LineSpec;\n /**\n * The line held wholly other text and `--only` named the entry, so the\n * accept stands. The report says so rather than reading as an edit.\n */\n replaced?: true;\n /** The marker's line on the page this run leaves, where one anchors. */\n markerLine?: number;\n }\n /**\n * A changed source, re-pinned at HEAD. Where the in-range search found the\n * old first and last line, the re-mint covers the span they bracket rather\n * than the recorded range, and `source.lines` follows it (proposal 0055).\n */\n | {\n kind: \"source-accepted\";\n result: CitationResult;\n minted: Citation;\n /** The span accepted, when it is not the range the entry records. */\n span?: { lines: LineSpec; from: string; to: string };\n }\n /**\n * The source holds, but the commit it is recorded against does not contain\n * the pinned lines, or is not in the history of HEAD. Only `commit-sha`\n * moves; the pin itself is untouched.\n */\n | {\n kind: \"source-recommitted\";\n result: CitationResult;\n /** The commit the entry records now, and cannot support. */\n from: string;\n /** HEAD, which was checked to contain the lines before this was planned. */\n commitSha: string;\n because: RecommitReason;\n }\n | { kind: \"marker-moved\"; result: CitationResult; from: number; to: number }\n | {\n kind: \"claim-reanchored\";\n result: CitationResult;\n pin: string;\n /** The span that held, in file lines, and the span now pinned. */\n held: string;\n now: string;\n }\n | {\n kind: \"claim-shifted\";\n result: CitationResult;\n lines: LineSpec;\n from: string;\n to: string;\n }\n /**\n * The words the pin covered are unchanged and only the layout moved\n * (proposal 0053). A plain `update` re-pins it, and rewrites its `lines:`\n * when the entry has them.\n */\n | {\n kind: \"claim-words-held\";\n result: CitationResult;\n pin: string;\n /** The file line of the claim's first body line, after any marker move. */\n at: number;\n /** The stored span and the span now pinned, in file lines. */\n fromLines: string;\n toLines: string;\n commitSha?: string;\n lines?: LineSpec;\n }\n /**\n * A changed claim `--accept` refused to re-pin: the line now holds text\n * sharing no sentence with the claim at its baseline, or too few of its\n * words. Nothing is written.\n */\n | {\n kind: \"claim-replaced\";\n result: CitationResult;\n at: number;\n commitSha: string;\n /** The share of the claim's words held, when overlap is what refused it. */\n wordShare?: number;\n /** The pin that stands, and the one that was not written. */\n pin: string;\n would: string;\n };\n\n/**\n * Why one repair was declined, and the rule whose finding says so. One entry\n * can carry findings about both ends, so the reason names which it is about.\n */\ninterface Declined {\n rule: string;\n why: string;\n}\n\n/**\n * Why `--accept` re-pinned nothing at the claim's line, said plainly. Each\n * reason is a different problem: a blank line lost the sentence, a claim that\n * runs out of its fenced block covers a fence rather than code, a line that\n * starts no paragraph is a heading underline or an unclosed fence, a line\n * outside the body is a range the page no longer reaches, a short table lost\n * rows the claim was minted over, and a marker or a table rule is a line that\n * holds no claim text at all.\n */\nfunction sayNoUnit(reason: NoUnit): string {\n switch (reason) {\n case \"outside\":\n return \"the line is outside the page body\";\n case \"blank\":\n return \"the line is blank\";\n case \"fence-crossed\":\n return \"the claim's lines are not all inside one fenced block\";\n case \"marker\":\n return \"that line now holds a cite marker, not claim text\";\n case \"not-a-paragraph\":\n return \"the line does not start a paragraph\";\n case \"table-short\":\n return \"the table no longer holds every row the claim covers\";\n case \"table-rule\":\n return \"that line is a table rule, not claim text\";\n }\n}\n\n/** A unit named in a refusal. `fenced-lines` is a span of code, not a block. */\nfunction unitNoun(kind: ClaimUnit[\"kind\"]): string {\n return kind === \"fenced-lines\" ? \"fenced text\" : kind;\n}\n\n/** The rule a plan settles, so its finding is not also reported as skipped. */\nfunction settles(plan: Plan): string {\n switch (plan.kind) {\n case \"claim-moved\":\n return \"claim-moved\";\n case \"source-moved\":\n return \"source-moved\";\n case \"claim-accepted\":\n return \"claim-changed\";\n case \"source-accepted\":\n return plan.result.source.status === \"never-true\" ? \"source-never-true\" : \"source-changed\";\n case \"marker-moved\":\n return \"marker-misplaced\";\n case \"claim-reanchored\":\n return \"claim-moved\";\n case \"claim-words-held\":\n return \"claim-reanchored\";\n // A refused claim leaves nothing written, but its finding is the row the\n // refusal prints, so it is not also reported as skipped.\n case \"claim-replaced\":\n return \"claim-changed\";\n // A shifted entry was `current`, so it had no finding to settle. A\n // re-committed one was `current` too: `check` never reported it, which is\n // why the repair is asked for rather than offered.\n case \"claim-shifted\":\n case \"source-recommitted\":\n return \"\";\n }\n}\n\nfunction apply(content: string, format: string, plan: Plan): string {\n const index = plan.result.origin.index;\n switch (plan.kind) {\n case \"claim-moved\":\n case \"claim-shifted\":\n return spliceEntryField(content, format, index, [\"claim\", \"lines\"], plan.lines);\n case \"claim-reanchored\":\n return spliceEntryField(content, format, index, [\"claim\", \"integrity\"], plan.pin);\n case \"claim-words-held\": {\n let out = spliceEntryField(content, format, index, [\"claim\", \"integrity\"], plan.pin);\n if (plan.lines !== undefined) {\n out = spliceEntryField(out, format, index, [\"claim\", \"lines\"], plan.lines);\n }\n return out;\n }\n // Nothing is written for a refused claim; the report is the whole of it.\n case \"claim-replaced\":\n // The move is a page rewrite, applied to the whole page before any splice.\n case \"marker-moved\":\n return content;\n case \"source-moved\": {\n let out = content;\n if (plan.file !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"file\"], plan.file);\n }\n if (plan.lines !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"lines\"], plan.lines);\n }\n out = spliceEntryField(out, format, index, [\"source\", \"integrity\"], plan.pin);\n // As on a re-mint: HEAD is written only where the entry already records\n // a commit, because the splice replaces a scalar and never adds a key.\n if (plan.commitSha !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"commit-sha\"], plan.commitSha);\n }\n return out;\n }\n case \"source-recommitted\":\n return spliceEntryField(content, format, index, [\"source\", \"commit-sha\"], plan.commitSha);\n case \"claim-accepted\": {\n let out = spliceEntryField(content, format, index, [\"claim\", \"integrity\"], plan.pin);\n if (plan.lines !== undefined) {\n out = spliceEntryField(out, format, index, [\"claim\", \"lines\"], plan.lines);\n }\n return out;\n }\n case \"source-accepted\": {\n let out = content;\n if (plan.span !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"lines\"], plan.span.lines);\n }\n out = spliceEntryField(\n out,\n format,\n index,\n [\"source\", \"integrity\"],\n plan.minted.source.integrity,\n );\n const commit = plan.minted.source[\"commit-sha\"];\n // An entry with no `commit-sha:` line of its own keeps none: the splice\n // replaces a scalar, it does not add a key.\n if (commit !== undefined) {\n out = spliceEntryField(out, format, index, [\"source\", \"commit-sha\"], commit);\n }\n return out;\n }\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The same repair, against an entry that lives in a manifest. The page's\n * whole `citations` value is written back at the end of the run, so a repair\n * here is an edit to the parsed entry rather than a splice of one scalar.\n * An entry the writer cannot reach — a list item that is not a mapping —\n * leaves its finding reported.\n */\nfunction applyToEntry(entry: unknown, plan: Plan): boolean {\n if (!isRecord(entry)) return false;\n const end = (name: \"claim\" | \"source\"): Record<string, unknown> | undefined =>\n isRecord(entry[name]) ? entry[name] : undefined;\n switch (plan.kind) {\n case \"claim-moved\":\n case \"claim-shifted\": {\n const claim = end(\"claim\");\n if (claim === undefined) return false;\n claim.lines = plan.lines;\n return true;\n }\n case \"claim-reanchored\": {\n const claim = end(\"claim\");\n if (claim === undefined) return false;\n claim.integrity = plan.pin;\n return true;\n }\n case \"claim-words-held\": {\n const claim = end(\"claim\");\n if (claim === undefined) return false;\n claim.integrity = plan.pin;\n if (plan.lines !== undefined) claim.lines = plan.lines;\n return true;\n }\n // Nothing is written for a refused claim.\n case \"claim-replaced\":\n // The page holds the marker, so the manifest has nothing to change.\n case \"marker-moved\":\n return true;\n case \"source-moved\": {\n const source = end(\"source\");\n if (source === undefined) return false;\n if (plan.file !== undefined) source.file = plan.file;\n if (plan.lines !== undefined) source.lines = plan.lines;\n source.integrity = plan.pin;\n if (plan.commitSha !== undefined) source[\"commit-sha\"] = plan.commitSha;\n return true;\n }\n case \"source-recommitted\": {\n const source = end(\"source\");\n if (source === undefined) return false;\n source[\"commit-sha\"] = plan.commitSha;\n return true;\n }\n case \"claim-accepted\": {\n const claim = end(\"claim\");\n if (claim === undefined) return false;\n claim.integrity = plan.pin;\n if (plan.lines !== undefined) claim.lines = plan.lines;\n return true;\n }\n case \"source-accepted\": {\n const source = end(\"source\");\n if (source === undefined) return false;\n if (plan.span !== undefined) source.lines = plan.span.lines;\n source.integrity = plan.minted.source.integrity;\n const commit = plan.minted.source[\"commit-sha\"];\n // As on a page: a re-mint records a commit only where the entry\n // already recorded one, so this never adds the key.\n if (commit !== undefined) source[\"commit-sha\"] = commit;\n return true;\n }\n }\n}\n\nfunction rewriteOf(plan: Plan): UpdateRewrite {\n const { citation, origin, source } = plan.result;\n const base: Pick<UpdateRewrite, \"id\" | \"index\" | \"line\"> = { index: origin.index };\n if (citation.id !== undefined) base.id = citation.id;\n if (origin.line !== undefined) base.line = origin.line;\n\n switch (plan.kind) {\n case \"claim-moved\":\n return {\n ...base,\n end: \"claim\",\n reason: \"moved\",\n status: \"moved\",\n from: plan.from,\n to: plan.to,\n fromLines: plan.from,\n toLines: plan.to,\n };\n case \"marker-moved\": {\n const from = String(plan.from);\n const to = String(plan.to);\n return {\n ...base,\n end: \"marker\",\n reason: \"re-anchored\",\n status: \"misplaced\",\n from,\n to,\n fromLines: from,\n toLines: to,\n };\n }\n case \"claim-reanchored\": {\n const was = citation.claim?.integrity ?? \"\";\n return {\n ...base,\n end: \"claim\",\n reason: \"re-anchored\",\n status: \"moved\",\n from: was,\n to: plan.pin,\n fromPin: was,\n toPin: plan.pin,\n lines: plan.held,\n newLines: plan.now,\n };\n }\n case \"claim-words-held\": {\n const was = citation.claim?.integrity ?? \"\";\n const out: UpdateRewrite = {\n ...base,\n end: \"claim\",\n reason: \"re-anchored\",\n status: \"reanchored\",\n from: was,\n to: plan.pin,\n fromPin: was,\n toPin: plan.pin,\n fromLines: plan.fromLines,\n toLines: plan.toLines,\n at: plan.at,\n };\n if (plan.commitSha !== undefined) out.commitSha = plan.commitSha;\n return out;\n }\n case \"claim-replaced\":\n return {\n ...base,\n end: \"claim\",\n reason: \"replaced\",\n status: \"changed\",\n from: plan.pin,\n to: plan.would,\n fromPin: plan.pin,\n toPin: plan.would,\n at: plan.at,\n commitSha: plan.commitSha,\n ...(plan.wordShare === undefined ? {} : { wordShare: plan.wordShare }),\n };\n case \"claim-shifted\":\n return {\n ...base,\n end: \"claim\",\n reason: \"shifted\",\n status: \"current\",\n from: plan.from,\n to: plan.to,\n fromLines: plan.from,\n toLines: plan.to,\n };\n case \"source-moved\":\n return {\n ...base,\n end: \"source\",\n reason: \"moved\",\n status: \"moved\",\n from: source.src,\n to: plan.to,\n };\n case \"source-recommitted\":\n return {\n ...base,\n end: \"source\",\n reason: \"recommitted\",\n // The source itself held. Only its date was wrong.\n status: \"current\",\n because: plan.because,\n from: plan.from,\n to: plan.commitSha,\n fromCommit: plan.from,\n toCommit: plan.commitSha,\n src: source.src,\n };\n case \"claim-accepted\": {\n const was = citation.claim?.integrity ?? \"\";\n const out: UpdateRewrite = {\n ...base,\n end: \"claim\",\n reason: \"accepted\",\n // A bypassed guard reads `replaced`, so the log shows that the line\n // held other text and a named accept took it anyway.\n status: plan.replaced === true ? \"replaced\" : \"changed\",\n from: was,\n to: plan.pin,\n fromPin: was,\n toPin: plan.pin,\n at: plan.unit.lines.start,\n text: quoted(plan.unit.text),\n };\n // A re-pin over a unit wider than the stored lines names both spans.\n const stored = plan.result.claim?.fileLines;\n const now = spellLines(plan.unit.lines);\n if (stored !== undefined && stored !== now) {\n out.fromLines = stored;\n out.toLines = now;\n }\n // Where the report says the claim is: its marker, when one anchors it.\n // A marker this run moved reads at the line it now sits on, so the row\n // and the move above it name one line rather than two.\n const markerLine =\n plan.markerLine ?? (plan.result.anchor === \"marker\" ? plan.result.markerLine : undefined);\n if (markerLine !== undefined) out.markerLine = markerLine;\n return out;\n }\n case \"source-accepted\": {\n const out: UpdateRewrite = {\n ...base,\n end: \"source\",\n reason: \"accepted\",\n status: source.status === \"never-true\" ? \"never-true\" : \"changed\",\n from: citation.source.integrity,\n to: plan.minted.source.integrity,\n fromPin: citation.source.integrity,\n toPin: plan.minted.source.integrity,\n src: source.src,\n };\n // A re-mint over the span the old first and last line now bracket names\n // both ranges, so the acceptance says which lines it accepted.\n if (plan.span !== undefined) {\n out.fromLines = plan.span.from;\n out.toLines = plan.span.to;\n }\n const commit = plan.minted.source[\"commit-sha\"];\n if (commit !== undefined) out.commitSha = commit;\n return out;\n }\n }\n}\n\n/**\n * How much of the claim's words its line must still hold for a blanket\n * `--accept` to re-pin it, as `wordShare` measures it.\n *\n * A replay of 65 proposed `--accept` re-pins over this repository's own\n * corpus, every one with a baseline to read, put the seven wrong re-pins at\n * 0.38 and below and every safe one at 0.74 and above. Each of the seven had\n * drifted onto a neighbouring table row, and the sentence test below let all\n * seven through. Nothing measured landed between the two bands, so the number\n * is fixed here. A config key would be a knob over a gap no corpus fills.\n */\nconst CLAIM_WORD_SHARE = 0.5;\n\n/** Why a re-pin was refused: the baseline, and the share when overlap is what fired. */\ninterface Replacement {\n /** The baseline the claim's words were read against. */\n commit: string;\n /** Set only when the overlap test fired: the share of the claim's words held. */\n share?: number;\n}\n\n/**\n * Why a re-pin over `text` would bless a line that no longer carries the\n * claim: a neighbouring table row after a shift, or a block inserted under a\n * marker. `undefined` lets the accept stand, which is also what happens with\n * no baseline to read the claim against.\n *\n * Two tests, either of which refuses. The first is sentence intersection: a\n * claim whose paragraph was edited still shares a sentence with what it said\n * at the baseline, and one whose line was replaced outright shares none. The\n * second is word overlap, for the drift the first misses. Two rows of one\n * table end alike often enough to share a sentence while saying different\n * things, so a line holding less than `CLAIM_WORD_SHARE` of the claim's words\n * is refused too, and the report names the share.\n *\n * The guard only asks about an entry the run did not name. Naming an id with\n * `--only` is the human judgement the guard exists to demand, so a reviewer\n * who has read the claim and its source re-pins a reworded sentence without a\n * remove and an add. What the guard is for is a blanket `--accept` quietly\n * re-pinning a hundred claims, one of which now holds a neighbouring table\n * row. A bypass is reported rather than hidden.\n */\nfunction replacementAt(\n claim: ClaimEnd,\n text: readonly string[],\n format: string,\n): Replacement | undefined {\n const was = claim.baselineText;\n const commit = claim.commitSha;\n if (was === undefined || commit === undefined) return undefined;\n const before = claimWords(was, format);\n const now = claimWords(text, format);\n if (!sharesSentence(before, now)) return { commit };\n const share = wordShare(before, now);\n if (share < CLAIM_WORD_SHARE) return { commit, share };\n return undefined;\n}\n\n/** How many characters of re-pinned text the report quotes before it elides. */\nconst QUOTE_CAP = 200;\n\n/**\n * The text a re-pin quotes: whitespace collapsed, and capped, because the\n * unit may be a whole paragraph and the report is one line per rewrite.\n */\nfunction quoted(text: readonly string[]): string {\n const all = normalizeWhitespace(text.join(\"\\n\"));\n return all.length <= QUOTE_CAP ? all : `${all.slice(0, QUOTE_CAP)}…`;\n}\n\n/** `<id>: <text>`, or the text alone for an entry with no id. */\nfunction named(id: string | undefined, text: string): string {\n return id === undefined ? text : `${id}: ${text}`;\n}\n\n/** One misplaced marker `update` left where it is, and the rule its line reads at. */\ninterface MarkerStay {\n line: number;\n rule: CiteRule;\n message: string;\n}\n\n/** What `update` will do to a page's misplaced markers. */\ninterface MarkerDecisions {\n moves: { result: CitationResult; entry: PageCitation; misplaced: MisplacedMarker }[];\n stays: MarkerStay[];\n}\n\n/**\n * A claim-lines entry the move would change: one whose range holds the\n * marker's line, or starts above the unit and reaches the place the marker\n * goes. Moving the marker would rewrite that entry's pinned text.\n */\nfunction crossing(\n page: PageCitations,\n misplaced: MisplacedMarker,\n): string | undefined {\n for (const other of page.citations) {\n const spec = other.citation.claim?.lines;\n const recorded = spec === undefined ? undefined : parseLines(spec);\n if (recorded === undefined) continue;\n const file = toFileLines(recorded, page.bodyLine);\n const holdsMarker = file.start <= misplaced.line && misplaced.line <= file.end;\n const holdsPlace = file.start < misplaced.place && misplaced.place <= file.end;\n if (!holdsMarker && !holdsPlace) continue;\n return other.citation.id === undefined\n ? `the claim at ${spellAt(file)}`\n : `the claim of ${other.citation.id} (${spellAt(file)})`;\n }\n return undefined;\n}\n\n/**\n * Which of a page's misplaced markers move, and why each of the rest stays.\n * Every decision is taken against the page as it was read, before any write.\n */\nfunction decideMarkers(input: {\n page: PageCitations;\n report: PageCitationReport;\n lines: readonly string[];\n accept: boolean;\n only?: Set<string>;\n}): MarkerDecisions {\n const { page, report, lines, accept, only } = input;\n const out: MarkerDecisions = { moves: [], stays: [] };\n for (const misplaced of misplacedMarkers(page, lines)) {\n const entry = misplaced.entry;\n const line = misplaced.line;\n const stay = (rule: CiteRule, message: string): void => {\n out.stays.push({ line, rule, message });\n };\n // An orphan, repeated or invalid marker names no entry that can be\n // checked, and `--only` selects entries, so it selects their markers.\n if (entry === undefined) {\n if (only !== undefined) continue;\n const own = report.findings.find(\n (finding) => finding.line === line && finding.rule.startsWith(\"marker-\") && finding.rule !== \"marker-misplaced\",\n );\n stay(\n own?.rule ?? \"marker-orphan\",\n `the marker at line ${String(line)} stays, because it names no entry update can check.`,\n );\n continue;\n }\n const id = entry.citation.id;\n if (only !== undefined && (id === undefined || !only.has(id))) continue;\n const result = report.citations.find((r) => r.origin.index === entry.origin.index);\n if (result === undefined) continue;\n // Claim lines and a marker both: neither anchor can be trusted.\n if (entry.citation.claim?.lines !== undefined) {\n stay(\n \"anchor-invalid\",\n named(id, `the marker at line ${String(line)} stays, because the entry also has claim lines. Keep one.`),\n );\n continue;\n }\n const across = crossing(page, misplaced);\n if (across !== undefined) {\n stay(\n \"marker-misplaced\",\n named(id, `the marker at line ${String(line)} stays, because moving it would change ${across}.`),\n );\n continue;\n }\n if (result.claim !== null && result.claim.status === \"changed\" && !accept) {\n stay(\n \"marker-misplaced\",\n named(\n id,\n `the marker at line ${String(line)} stays, because its claim changed since it was pinned. update --accept moves it and re-pins.`,\n ),\n );\n continue;\n }\n out.moves.push({ result, entry, misplaced });\n }\n return out;\n}\n\n/**\n * The lines the span an entry's marker anchors covers on the page as it now\n * stands, and the pin over them.\n */\nfunction anchoredNow(\n content: string,\n format: string,\n lines: readonly string[],\n markerLine: number,\n quote: boolean,\n): { span: PageLines; pin: string } | undefined {\n const at = offsetOfLine(content, markerLine) + (lines[markerLine - 1]?.length ?? 0);\n const span = anchoredLines(content, at, format, quote);\n if (span === undefined) return undefined;\n const pin = pinOfLines(lines, span);\n return pin === undefined ? undefined : { span, pin };\n}\n\n/** The errno a failed write carries, when it carries one. */\nfunction codeOf(error: unknown): string | undefined {\n if (typeof error !== \"object\" || error === null || !(\"code\" in error)) return undefined;\n const code: unknown = error.code;\n return typeof code === \"string\" ? code : undefined;\n}\n\n/**\n * A run writes a page and the manifest that keys it, and a marker move needs\n * both to land. So every file this run wrote, page and manifest alike, keeps\n * its original text until the run is done, and a failed write puts them back.\n * A manifest left pinned to text its page no longer holds would read as drift\n * that never happened.\n */\nclass WrittenFiles {\n private readonly before = new Map<string, string>();\n private readonly labels = new Map<string, string>();\n\n /** Remember what `path` held before this run wrote it. */\n record(path: string, label: string, content: string): void {\n if (!this.before.has(path)) {\n this.before.set(path, content);\n this.labels.set(path, label);\n }\n }\n\n /**\n * Put every file back, and say what happened: `<file> could not be written\n * (<code>). <pages> was restored.`\n */\n async restore(file: string, error: unknown): Promise<CiteError> {\n const restored: string[] = [];\n const failed: string[] = [];\n for (const [path, content] of this.before) {\n const label = this.labels.get(path) ?? path;\n try {\n await writeFileAtomic(path, content);\n restored.push(label);\n } catch {\n failed.push(label);\n }\n }\n const code = codeOf(error);\n const why = code === undefined ? \"\" : ` (${code})`;\n const parts = [`${file} could not be written${why}.`];\n if (restored.length > 0) {\n parts.push(`${listOf(restored)} ${restored.length === 1 ? \"was\" : \"were\"} restored.`);\n }\n if (failed.length > 0) {\n parts.push(\n `${listOf(failed)} could not be restored, and ${failed.length === 1 ? \"holds\" : \"hold\"} an intermediate state.`,\n );\n }\n return new CiteError(parts.join(\" \"));\n }\n}\n\n/**\n * Citations counted as a summary counts them: an entry whose marker moved and\n * whose claim was re-pinned is one citation, not two.\n */\nfunction citationsIn(rows: readonly UpdateRewrite[]): number {\n const withMarker = new Set(rows.filter((row) => row.end === \"marker\").map((row) => row.index));\n return withMarker.size + rows.filter((row) => !withMarker.has(row.index)).length;\n}\n\nexport async function runUpdate(opts: UpdateOptions): Promise<UpdateRun> {\n const prepared = await prepareRun(opts, \"updated\", \"update\", { require: true });\n const { run, files, usingStdin, forced, pageOptions, git } = prepared;\n await assertNoOrphans(prepared);\n const hits = joinHits();\n // Each manifest is read once and written once, however many of its pages\n // the run repairs.\n const manifests = new ManifestSet();\n // What every file this run wrote held before, so a failed write is undone.\n const writes = new WrittenFiles();\n const only = opts.only !== undefined && opts.only.length > 0 ? new Set(opts.only) : undefined;\n const accept = opts.accept === true;\n const recommit = opts.recommit === true;\n if (recommit && !(await git.available())) {\n throw new CiteError(\n \"--recommit needs git to verify recorded commits, and git is not available here.\",\n );\n }\n\n /**\n * Whether `commit` is outside the history of `head`. Only a client that can\n * answer both questions, in a clone that is not shallow, says yes. A shallow\n * clone lacks commits that are in the history, so it cannot tell them from\n * a squash merge's orphans.\n */\n const outsideHistory = async (commit: string, head: string): Promise<boolean> => {\n if (git.shallow === undefined || git.isAncestor === undefined) return false;\n if (await git.shallow()) return false;\n return !(await git.isAncestor(commit, head));\n };\n\n /**\n * The commit to record for an entry whose recorded one cannot stand, and\n * why, or `undefined` to leave the entry alone.\n *\n * Three questions. First, is the recorded commit in the history of HEAD? A\n * squash merge leaves a branch commit that main never took, and it may well\n * hold the lines. Second, for a commit in the history, does it contain the\n * lines? It counts as containing them wherever in the file they sit,\n * because `update` follows a move and keeps `commit`, so line drift inside\n * one commit is the tool working rather than damage. Only a pin found\n * nowhere there is unsupported. Third, does HEAD contain them? The entry is\n * `current`, so the working tree does, but an uncommitted edit means HEAD\n * may not, and there is then no commit worth recording. The two questions\n * about lines are asked through `historyOf`, which is what `check` uses, so\n * the answers agree.\n *\n * In a full clone, a commit git cannot read fails the first question, so it\n * is re-recorded. A shallow clone cannot ask the first question. There such\n * a commit answers the second with neither yes nor no, and is left alone.\n */\n const recommitFor = async (\n result: CitationResult,\n ): Promise<{ commit: string; because: RecommitReason } | undefined> => {\n const recorded = result.citation.source[\"commit-sha\"];\n const path = result.source.resolvedPath;\n if (recorded === undefined || path === undefined) return undefined;\n const head = await git.head();\n if (head === null || head === recorded) return undefined;\n const range = sourceRange(result.citation.source);\n const pin = result.citation.source.integrity;\n const key = range.encrypted ? run.key : undefined;\n // History first. It is one memoized `merge-base` per commit, where\n // containment is one `git show` per commit and path. A commit outside the\n // history is re-recorded whatever it holds, so its file is never read.\n let because: RecommitReason;\n if (await outsideHistory(recorded, head)) because = \"not-in-history\";\n else {\n const was = await historyOf(git, recorded, path, range, pin, key, undefined);\n if (was.kind !== \"never-true\") return undefined;\n because = \"not-contained\";\n }\n // `original` means HEAD holds the pinned bytes, at the recorded lines or\n // anywhere else in the file. That is the same reading as question one, so\n // the two answers are comparable.\n const now = await historyOf(git, head, path, range, pin, key, undefined);\n return now.kind === \"original\" ? { commit: head, because } : undefined;\n };\n\n /** What this citation needs, in the order the repairs are worth trying. */\n const plansFor = async (\n result: CitationResult,\n entry: PageCitation | undefined,\n page: PageCitations,\n lines: readonly string[],\n lineNow: (line: number) => number,\n declined: Map<number, Declined>,\n ): Promise<Plan[]> => {\n const out: Plan[] = [];\n const claim = result.claim;\n // A marker-anchored claim has no `lines:` to splice; its repair is a\n // re-pin over the span the marker anchors, planned by the caller.\n if (\n result.anchor !== \"marker\" &&\n claim !== null &&\n claim.status === \"moved\" &&\n claim.newLines !== undefined\n ) {\n const at = parseLines(claim.newLines);\n // A marker that moved shifted the page under the window the search\n // found, so the lines it reported are read through the move.\n const shifted =\n at === undefined\n ? undefined\n : (() => {\n const file = toFileLines(at, page.bodyLine);\n const to = { start: lineNow(file.start), end: lineNow(file.end) };\n return to.end - to.start === file.end - file.start\n ? toBodyLines(to, page.bodyLine)\n : undefined;\n })();\n if (at !== undefined && shifted !== undefined) {\n out.push({\n kind: \"claim-moved\",\n result,\n lines: lineSpec(shifted),\n from: claim.fileLines ?? \"\",\n to: spellLines(toFileLines(shifted, page.bodyLine)),\n });\n }\n }\n // The words the pin covered are unchanged, and the run they sit in moved.\n // A plain `update` re-pins it and rewrites the entry's lines (0053).\n if (\n result.anchor !== \"marker\" &&\n claim !== null &&\n claim.status === \"reanchored\" &&\n claim.newLines !== undefined\n ) {\n const at = parseLines(claim.newLines);\n const file = at === undefined ? undefined : toFileLines(at, page.bodyLine);\n const pin = file === undefined ? undefined : pinOfLines(lines, file);\n const to =\n file === undefined ? undefined : { start: lineNow(file.start), end: lineNow(file.end) };\n if (\n file !== undefined &&\n to !== undefined &&\n pin !== undefined &&\n to.end - to.start === file.end - file.start\n ) {\n const plan: Plan = {\n kind: \"claim-words-held\",\n result,\n pin,\n at: to.start,\n fromLines: claim.fileLines ?? \"\",\n toLines: spellLines(to),\n lines: lineSpec(toBodyLines(to, page.bodyLine)),\n };\n if (claim.commitSha !== undefined) plan.commitSha = claim.commitSha;\n out.push(plan);\n }\n }\n if (result.source.status === \"moved\" && result.source.newSrc !== undefined) {\n const to = result.source.newSrc;\n const recorded = result.citation.source[\"commit-sha\"];\n const at = result.source.newLines === undefined ? undefined : parseLines(result.source.newLines);\n // The path the pin followed its text to, when that is another file. The\n // entry's own `commit-sha` then stands: the pin was minted there and\n // still holds, so HEAD would record a mint that never happened.\n const went = parseSrc(to).path;\n const crossFile = went !== result.citation.source.file;\n if (at !== undefined || result.citation.source.lines === undefined) {\n try {\n if (crossFile) {\n // Nothing to re-mint: the window hashed to the pin the entry\n // already carries, so only the stale halves of the record move.\n out.push({\n kind: \"source-moved\",\n result,\n to,\n file: went,\n pin: result.citation.source.integrity,\n ...(at === undefined ? {} : { lines: lineSpec(at) }),\n });\n } else if (at !== undefined) {\n // Re-minted over the range it moved to, not just re-pointed at it.\n // A pin whose `lines` were rewritten under an older `commit-sha`\n // names a range that commit may not even reach, and the next\n // command to ask for history reads it as a claim that never held.\n const minted = await mintCitation({\n root: run.root,\n src: to,\n ...(run.key === undefined ? {} : { key: run.key }),\n ...(recorded === undefined ? { commitSha: false as const } : {}),\n gitClient: git,\n ...(pageOptions.sourceIndex === undefined\n ? {}\n : { sourceIndex: pageOptions.sourceIndex }),\n });\n const commit = minted.source[\"commit-sha\"];\n // An entry that records a commit needs one to advance to. Without\n // git there is none, and writing the new lines alone would leave the\n // entry naming a range its own commit cannot hold, which is the\n // state this re-mint exists to prevent. So nothing is written: a\n // whole stale entry is one a later run repairs, and a half-written\n // one is not. An entry that records no commit has nothing to keep in\n // step, and is rewritten as before.\n if (recorded !== undefined && commit === undefined) {\n declined.set(result.origin.index, {\n rule: \"source-moved\",\n why: \"Not rewritten: git is not available here, so the entry's commit-sha cannot advance with its lines.\",\n });\n } else {\n out.push({\n kind: \"source-moved\",\n result,\n lines: lineSpec(at),\n to,\n pin: minted.source.integrity,\n ...(commit === undefined ? {} : { commitSha: commit }),\n });\n }\n }\n } catch (error) {\n // A range the re-mint cannot read leaves its finding reported, as a\n // source `--accept` could not re-mint does, and the finding says why\n // rather than reading as a repair that silently did nothing.\n if (!(error instanceof CiteError)) throw error;\n declined.set(result.origin.index, {\n rule: \"source-moved\",\n why: `Not rewritten: ${error.message}`,\n });\n }\n }\n }\n // Asked for, not offered: the entry is `current`, so `check` reported\n // nothing to repair here.\n if (recommit && result.source.status === \"current\") {\n const to = await recommitFor(result);\n if (to !== undefined) {\n out.push({\n kind: \"source-recommitted\",\n result,\n from: result.citation.source[\"commit-sha\"] ?? \"\",\n commitSha: to.commit,\n because: to.because,\n });\n }\n }\n if (!accept) return out;\n\n // A marker-anchored claim is re-pinned against the page the move left,\n // so the caller plans that one.\n if (claim !== null && claim.status === \"changed\" && entry !== undefined && result.anchor !== \"marker\") {\n // The paragraph, block or row now at the claim's first line. Anything\n // else is left for a fresh `cite add`, and says why.\n // The span the claim holds now, and the line it starts on. A table keeps\n // the span: the author chose how many rows the claim covers, and\n // `--accept` re-mints, never redesigns.\n //\n // Both are set for every claim that reaches here. `claimEnd` fills\n // `fileLines` only on the `claim.lines` branch, and the marker branch is\n // already excluded above, so the `undefined` arms below are the types\n // being honest rather than a case a run can land in.\n const held = claim.fileLines === undefined ? undefined : parseLines(claim.fileLines);\n const at = held?.start;\n // Naming an id is the operator saying they have read the line, so the\n // refusals that ask whether it can be claim text at all stand down.\n const named = only !== undefined;\n const unit: ClaimUnit | undefined =\n at === undefined ? undefined : unitAt(page, at, lines, held, named);\n const wantsBlock = entry.citation.quote === true;\n const pin = unit === undefined ? undefined : pinOfLines(lines, unit.lines);\n // A unit past the range limit would pin more than a citation may hold.\n const wide = unit === undefined ? undefined : tooWide(unit.lines);\n if (unit !== undefined && wide !== undefined) {\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: `Not re-pinned: the ${unitNoun(unit.kind)} ${wide}.`,\n });\n } else if (unit === undefined) {\n const why = at === undefined ? undefined : noUnitAt(page, at, lines, held, named);\n if (why !== undefined) {\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: `Not re-pinned: ${sayNoUnit(why)}.`,\n });\n }\n } else if (wantsBlock && unit.kind !== \"block\") {\n // A `quote: true` entry's claim lines are a whole fenced block, fences\n // included; `check` reads anything else as `anchor-invalid`. So a\n // quote whose first line drifted into prose, or into the middle of a\n // block, is left for a fresh `cite add` and says so.\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: \"Not re-pinned: quote: true, and the line no longer opens a fenced block.\",\n });\n } else if (pin !== undefined) {\n // Where else the same text sits. A pin cannot tell two copies apart,\n // so re-pinning over one of them writes a claim that is\n // `moved-ambiguous` the moment anything above it shifts. `add` refuses\n // the same pin for the same reason, before it is ever written.\n const elsewhere = named ? [] : otherClaimSpans(lines, unit.lines, pin, page.bodyLine);\n const replaced = replacementAt(claim, unit.text, page.format);\n // The order of these two matters, and it is the baseline that goes\n // first. Both refusals stop the same re-pin, but they do not carry the\n // same weight. The one the baseline earns says the line no longer\n // holds the claim, which is work left undone, and it exits 1. The\n // uniqueness refusal only reads the line as it stands and exits 0. So\n // a claim that trips both has to keep the stronger signal, or a\n // repeated line would quietly turn a failing run green.\n if (replaced !== undefined && only === undefined) {\n // `plansFor` runs only for a selected entry, so a run with `only`\n // set has named this one. `selected` says which repairs run; the\n // bypass says which entries `--accept` may re-pin, and both hold\n // here.\n out.push({\n kind: \"claim-replaced\",\n result,\n at: unit.lines.start,\n commitSha: replaced.commit,\n ...(replaced.share === undefined ? {} : { wordShare: replaced.share }),\n pin: entry.citation.claim?.integrity ?? \"\",\n would: pin,\n });\n } else if (elsewhere.length > 0) {\n // `--only` takes an id, so an entry without one has no way to say\n // \"accept it anyway\"; the advice is left off rather than made up.\n const id = result.citation.id;\n const anyway = id === undefined ? \"\" : ` Re-run with --only ${id} to accept it anyway.`;\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: `Not re-pinned: the text there also appears at ${spellElsewhere(elsewhere)}, so a pin cannot identify it.${anyway}`,\n });\n } else {\n const plan: Plan = { kind: \"claim-accepted\", result, unit, pin };\n if (replaced !== undefined) plan.replaced = true;\n // A paragraph that grew or shrank moves the claim's last line too.\n if (entry.citation.claim?.lines !== undefined) {\n const body = toBodyLines(unit.lines, page.bodyLine);\n const recorded = parseLines(entry.citation.claim.lines);\n if (\n recorded === undefined ||\n recorded.start !== body.start ||\n recorded.end !== body.end\n ) {\n plan.lines = lineSpec(body);\n }\n }\n out.push(plan);\n }\n }\n }\n if (result.source.status === \"changed\" || result.source.status === \"never-true\") {\n // Where the in-range search found the old first and last line. Accepting\n // the recorded range instead would hash a span the sentence never rested\n // on: an insertion inside a cited range pushes its end out of it.\n const stored = parseSrc(result.source.src);\n const span =\n result.source.newLines === undefined ? undefined : parseLines(result.source.newLines);\n const at =\n span === undefined || (span.start === stored.start && span.end === stored.end)\n ? undefined\n : { ...stored, start: span.start, end: span.end };\n try {\n // The source as the entry spells it: an encrypted one stays encrypted,\n // under the key it decrypted with, and mint keys the pin accordingly.\n // HEAD is recorded only where the entry already records a commit.\n const minted = await mintCitation({\n root: run.root,\n src: at === undefined ? result.source.src : formatSrc(at),\n ...(run.key === undefined ? {} : { key: run.key }),\n ...(result.citation.source[\"commit-sha\"] === undefined\n ? { commitSha: false as const }\n : {}),\n gitClient: git,\n ...(pageOptions.sourceIndex === undefined\n ? {}\n : { sourceIndex: pageOptions.sourceIndex }),\n });\n out.push({\n kind: \"source-accepted\",\n result,\n minted,\n ...(at === undefined || span === undefined\n ? {}\n : {\n span: {\n lines: lineSpec(span),\n from: spellLines({ start: stored.start ?? 1, end: stored.end ?? stored.start ?? 1 }),\n to: spellLines(span),\n },\n }),\n });\n } catch (error) {\n // A range the file no longer reaches cannot be re-minted; its finding stays reported.\n if (!(error instanceof CiteError)) throw error;\n }\n }\n return out;\n };\n\n const pages: UpdatePage[] = [];\n const updateOne = async (\n label: string,\n content: string,\n path?: string,\n ): Promise<PageCitationReport> => {\n const setup = await prepared.setupFor(label, content);\n if (setup.sidecar !== undefined) hits.record(setup.sidecar, label);\n const report = await checkCitations({ file: label, content, format: forced?.name }, setup.options);\n const { format } = report;\n const severity = resolveSeverity(setup.options.severity);\n const page = readPage(label, content, {\n ...(forced === undefined ? {} : { format: forced.name }),\n ...(setup.options.citations === undefined ? {} : { citations: setup.options.citations }),\n ...(setup.options.owned === undefined ? {} : { owned: setup.options.owned }),\n });\n const lines = splitLines(content);\n const rewritten: UpdateRewrite[] = [];\n const refused: UpdateRewrite[] = [];\n /** `<index>\\0<rule>` of every finding a rewrite settled. */\n const settled = new Set<string>();\n /**\n * Why a repair was declined, by entry index, said with the skipped\n * finding it concerns. The rule is carried so the reason lands on that\n * finding and not on another one about the same entry.\n */\n const declined = new Map<number, Declined>();\n\n // Misplaced markers first: the page is rewritten once, with every movable\n // marker relocated, and every pin below is taken against that page.\n const markers = decideMarkers({ page, report, lines, accept, only });\n const movedPage =\n markers.moves.length === 0\n ? undefined\n : applyMarkerMoves(\n content,\n markers.moves.map(({ misplaced }) => ({\n from: misplaced.line,\n place: misplaced.place,\n })),\n (line) => markerIndent(content, line, format, page.bodyLine),\n );\n let after = movedPage?.content ?? content;\n const afterLines = movedPage === undefined ? lines : splitLines(after);\n const movedIndexes = new Set(markers.moves.map(({ entry }) => entry.origin.index));\n const lineNow = (line: number): number => movedPage?.line(line) ?? line;\n // The manifest's entries for this page, edited in memory and written\n // back as one value once the page is done.\n const owner = setup.sidecar?.owner;\n const entries: unknown[] | undefined =\n setup.sidecar?.citations === undefined\n ? undefined\n : (JSON.parse(JSON.stringify(setup.sidecar.citations.map((c) => c.entry))) as unknown[]);\n let manifestDirty = false;\n for (const result of report.citations) {\n // `--only` selects the repairs to make. It does not select the shift a\n // marker move forces on the entries below it, which is planned for\n // every entry further down.\n const selected =\n only === undefined ||\n (result.citation.id !== undefined && only.has(result.citation.id));\n const entry = page.citations.find((c) => c.origin.index === result.origin.index);\n const plans: Plan[] = [];\n\n const move = selected\n ? markers.moves.find((m) => m.entry.origin.index === result.origin.index)\n : undefined;\n if (move !== undefined) {\n plans.push({\n kind: \"marker-moved\",\n result,\n from: move.misplaced.line,\n to: lineNow(move.misplaced.line),\n });\n }\n // The pin a marker anchors is taken against the page the moves left, so\n // the next check reads it as current however the run split.\n const marker = entry?.marker;\n const recorded = entry?.citation.claim?.integrity;\n if (\n selected &&\n result.anchor === \"marker\" &&\n marker !== undefined &&\n recorded !== undefined &&\n result.claim !== null\n ) {\n const quote = entry?.citation.quote === true;\n const now = anchoredNow(after, format, afterLines, lineNow(marker.line), quote);\n const status = result.claim.status;\n if (now !== undefined && now.pin !== recorded) {\n // A `current` claim already covers the unit the marker belongs to,\n // so only a move that split its run can leave it needing a pin.\n const unitText = afterLines.slice(now.span.start - 1, now.span.end);\n if (status === \"moved\" || (status === \"current\" && move !== undefined)) {\n plans.push({\n kind: \"claim-reanchored\",\n result,\n pin: now.pin,\n held: result.claim.fileLines ?? \"\",\n now: spellLines(now.span),\n });\n } else if (status === \"reanchored\") {\n // The marker travels with its text, so nothing moves but the pin.\n const held: Plan = {\n kind: \"claim-words-held\",\n result,\n pin: now.pin,\n at: now.span.start,\n fromLines: result.claim.fileLines ?? \"\",\n toLines: spellLines(now.span),\n };\n if (result.claim.commitSha !== undefined) held.commitSha = result.claim.commitSha;\n plans.push(held);\n } else if (status === \"changed\" && accept) {\n const kind = quote ? \"block\" : \"paragraph\";\n // A marker pins everything it anchors, so the range limit applies\n // to that, exactly as it does to a claim-lines re-pin.\n const wide = tooWide(now.span);\n if (wide !== undefined) {\n declined.set(result.origin.index, {\n rule: \"claim-changed\",\n why: `Not re-pinned: the ${kind} ${wide}.`,\n });\n } else {\n const replaced = replacementAt(result.claim, unitText, format);\n // `--only` naming the entry is the judgement the guard demands,\n // so a named accept stands and says `replaced` in the log.\n plans.push(\n replaced === undefined || only !== undefined\n ? {\n kind: \"claim-accepted\",\n result,\n pin: now.pin,\n markerLine: lineNow(marker.line),\n unit: { lines: now.span, kind, text: unitText },\n ...(replaced === undefined ? {} : { replaced: true as const }),\n }\n : {\n kind: \"claim-replaced\",\n result,\n at: now.span.start,\n commitSha: replaced.commit,\n ...(replaced.share === undefined ? {} : { wordShare: replaced.share }),\n pin: recorded,\n would: now.pin,\n },\n );\n }\n }\n }\n }\n\n if (selected) {\n plans.push(...(await plansFor(result, entry, page, lines, lineNow, declined)));\n }\n\n // A claim-lines entry the moves pushed along keeps its pinned text, so\n // its lines are rewritten in the same write. This one runs outside\n // `--only`: the page has already moved under the entry, so leaving its\n // lines behind would need a second run to put right.\n const spec = entry?.citation.claim?.lines;\n // A claim whose text moved is repaired by `claim-moved`, which finds\n // where the text went. Shifting its lines by the marker's delta would\n // point them somewhere else again, so the shift leaves it alone.\n const wentElsewhere = result.claim?.status === \"moved\";\n if (\n movedPage !== undefined &&\n spec !== undefined &&\n !wentElsewhere &&\n !plans.some((p) => p.kind === \"claim-moved\")\n ) {\n const at = parseLines(spec);\n const file = at === undefined ? undefined : toFileLines(at, page.bodyLine);\n const to =\n file === undefined ? undefined : { start: lineNow(file.start), end: lineNow(file.end) };\n if (\n file !== undefined &&\n to !== undefined &&\n to.end - to.start === file.end - file.start &&\n (to.start !== file.start || to.end !== file.end)\n ) {\n plans.push({\n kind: \"claim-shifted\",\n result,\n lines: lineSpec(toBodyLines(to, page.bodyLine)),\n from: spellLines(file),\n to: spellLines(to),\n });\n }\n }\n\n for (const plan of plans) {\n // A refused claim writes nothing, in either channel; its row is the\n // whole of it, and it keeps the finding from being reported twice.\n if (plan.kind === \"claim-replaced\") {\n refused.push(rewriteOf(plan));\n settled.add(`${String(result.origin.index)}\\0${settles(plan)}`);\n continue;\n }\n if (plan.kind === \"marker-moved\") {\n // The page already carries the move.\n } else if (result.origin.kind === \"manifest\") {\n // The manifest's entry list is shorter than the report's index, so\n // there is nothing to splice. Said rather than dropped: a silent\n // skip would report the check's own message and no reason.\n const held = entries?.[result.origin.index];\n if (held === undefined) {\n declined.set(result.origin.index, {\n rule: settles(plan),\n why: `Not rewritten: ${owner?.file ?? \"the manifest\"} has no entry at index ${String(result.origin.index)}.`,\n });\n continue;\n }\n if (!applyToEntry(held, plan)) continue;\n manifestDirty = true;\n } else {\n after = apply(after, format, plan);\n }\n rewritten.push(rewriteOf(plan));\n settled.add(`${String(result.origin.index)}\\0${settles(plan)}`);\n }\n }\n // A marker that moved settles its finding even where the entry is out of\n // the loop's reach, and a stacked run that split keeps the rest reported.\n for (const index of movedIndexes) settled.add(`${String(index)}\\0marker-misplaced`);\n if (manifestDirty && owner !== undefined && entries !== undefined) {\n if (setup.sidecar?.entry === undefined) {\n throw new CiteError(\n `${label} carries no ${owner.join}: value, so its citations cannot be keyed in ${owner.file}.`,\n );\n }\n await manifests.write(owner, setup.sidecar.entry, entries, 0);\n }\n // A marker that stays says so in place of the check's wording, at the\n // severity of the rule that kept it there. An accept this run declined\n // says why beside the finding that kept its work undone.\n const stayAt = new Map(markers.stays.map((stay) => [stay.line, stay]));\n const skipped = report.findings\n .filter(\n (finding) =>\n (only === undefined || (finding.id !== undefined && only.has(finding.id))) &&\n !settled.has(`${String(finding.index ?? -1)}\\0${finding.rule}`),\n )\n .map((finding) => {\n if (finding.rule === \"marker-misplaced\") {\n const stay = stayAt.get(finding.line ?? -1);\n if (stay === undefined) return finding;\n const level = severity[stay.rule];\n return {\n ...finding,\n message: stay.message,\n ...(level === \"off\" ? {} : { severity: level }),\n };\n }\n const turned = finding.index === undefined ? undefined : declined.get(finding.index);\n const why = turned?.rule === finding.rule ? turned.why : undefined;\n return why === undefined ? finding : { ...finding, message: `${finding.message} ${why}` };\n });\n const diff = after === content ? \"\" : unifiedDiff(label, content, after);\n const written = after !== content && path !== undefined && opts.dryRun !== true;\n if (written) {\n try {\n await writeFileAtomic(path, after);\n } catch (error) {\n throw await writes.restore(label, error);\n }\n writes.record(path, label, content);\n }\n const out: UpdatePage = { file: label, rewritten, refused, skipped, diff, written };\n // The stdin page has nowhere to be written; the caller prints it instead.\n if (path === undefined) out.content = after;\n pages.push(out);\n return report;\n };\n\n const reports: PageCitationReport[] = [];\n if (usingStdin) reports.push(await updateOne(STDIN_LABEL, opts.stdinContent ?? \"\"));\n for (const file of files) {\n reports.push(await updateOne(file, await readTarget(run, file), resolve(run.base, file)));\n }\n assertNoOrphanJoins(prepared, hits);\n\n // One write per manifest, after every page that touches it is settled.\n const write = opts.dryRun !== true;\n const rewrittenManifests: ManifestChange[] = [];\n const record = (changed: { file: string; diff: string }): void => {\n rewrittenManifests.push({ file: changed.file, diff: changed.diff, written: write });\n };\n if (write) {\n await manifests.commit({\n // A manifest joins the run's written files the moment it lands, so a\n // later manifest's failure puts this one back with the pages. Without\n // it the tree would keep pins no page content matches.\n after: (changed) => {\n writes.record(changed.path, changed.file, changed.before);\n record(changed);\n },\n onError: async (changed, error) => {\n throw await writes.restore(changed.file, error);\n },\n });\n } else for (const changed of manifests.changed()) record(changed);\n // A re-mint records HEAD when git has one. Where git is not there the entry\n // is re-pinned without a commit, and the run says so once.\n const reminted = pages.some((page) =>\n page.rewritten.some((r) => r.reason === \"accepted\" && r.end === \"source\"),\n );\n const also: string[] = [];\n if (reminted && !(await git.available())) also.push(GIT_UNAVAILABLE_COMMIT);\n // A shallow clone ran only the containment test, and says so whatever it\n // found, because what it could not check is the point. The guard is the\n // one `outsideHistory` uses, so the notice fires exactly when that test\n // would have run and could not.\n if (recommit && git.shallow !== undefined && git.isAncestor !== undefined && (await git.shallow())) {\n also.push(SHALLOW_RECOMMIT);\n }\n sayNotices(reports, opts.onNotice, also);\n\n const rewritten = pages.reduce((n, page) => n + citationsIn(page.rewritten), 0);\n // A refused claim counts as skipped: `--accept` was asked for it and the\n // run left it undone, which is what the summary's second number means.\n const skipped = pages.reduce((n, page) => n + page.skipped.length + page.refused.length, 0);\n const undone = pages.some(\n (page) =>\n page.refused.length > 0 || page.skipped.some((finding) => finding.severity === \"error\"),\n );\n return {\n pages,\n rewritten,\n skipped,\n ...(rewrittenManifests.length > 0 ? { manifests: rewrittenManifests } : {}),\n exitCode: undone ? 1 : 0,\n };\n}\n"],"mappings":"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","names":["readFile","i","j","readFile","after","index","at","named","resolve","index","markers","named","kept","resolve","resolve","apply","isRecord","named","rewritten","skipped","resolve"]}
|