@hawkeyexl/manni 4.4.0 → 4.5.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-DFRCLY77.js → batch-GOE3UXOD.js} +11 -11
- package/dist/{build-Q5C6SX5J.js → build-M7BMEHL2.js} +13 -11
- package/dist/{calibrate-XQILKXS3.js → calibrate-6RRAILUY.js} +12 -12
- package/dist/{capture-JQMOC3BW.js → capture-RJPQ6B4N.js} +12 -12
- package/dist/{check-NFZQLJKN.js → check-BQD64X3N.js} +11 -11
- package/dist/{check-HYNGXYJV.js → check-ESNS7ZBC.js} +4 -4
- package/dist/{check-U54XV6BP.js → check-RQIIIURI.js} +12 -12
- package/dist/{chunk-7QMCHA4N.js → chunk-3R5Y3XOL.js} +3 -3
- package/dist/{chunk-K3D6FPV6.js → chunk-3YHAYXBC.js} +2 -2
- package/dist/{chunk-JVTNMVYU.js → chunk-527HHQPS.js} +4 -4
- package/dist/{chunk-JVTNMVYU.js.map → chunk-527HHQPS.js.map} +1 -1
- package/dist/{chunk-6OYEI2VV.js → chunk-52PDIZKV.js} +3 -3
- package/dist/{chunk-UZC7LDAQ.js → chunk-6XTQDFGP.js} +2 -2
- package/dist/{chunk-UZC7LDAQ.js.map → chunk-6XTQDFGP.js.map} +1 -1
- package/dist/{chunk-NWZ2SLYL.js → chunk-7OQAU4EA.js} +5 -5
- package/dist/{chunk-5YXBLLAC.js → chunk-7ZUCEMCY.js} +8 -8
- package/dist/{chunk-M2JCK5F6.js → chunk-B7XUEQF3.js} +13 -2
- package/dist/chunk-B7XUEQF3.js.map +1 -0
- package/dist/{chunk-MYMBCTDE.js → chunk-BOIF2XGG.js} +2 -2
- package/dist/{chunk-H6FZ66XR.js → chunk-C3KI45RF.js} +8 -6
- package/dist/{chunk-H6FZ66XR.js.map → chunk-C3KI45RF.js.map} +1 -1
- package/dist/{chunk-3AFUD75K.js → chunk-C6HZ6C5T.js} +2 -2
- package/dist/{chunk-XYLUCIKQ.js → chunk-CP4ZM43V.js} +2 -2
- package/dist/chunk-DE7JSWXV.js +2462 -0
- package/dist/chunk-DE7JSWXV.js.map +1 -0
- package/dist/{chunk-YTCZRLTU.js → chunk-DX32P2DT.js} +2 -2
- package/dist/{chunk-644JVKJ4.js → chunk-EL2BZTDL.js} +137 -50
- package/dist/chunk-EL2BZTDL.js.map +1 -0
- package/dist/{chunk-JOHKIAVH.js → chunk-ELZ2IIOF.js} +332 -2522
- package/dist/chunk-ELZ2IIOF.js.map +1 -0
- package/dist/{chunk-OBFENF3U.js → chunk-F2OVHJNC.js} +10 -10
- package/dist/{chunk-5KHIFVD2.js → chunk-FLF6AECQ.js} +7 -7
- package/dist/{chunk-77HX34KD.js → chunk-GAZFKZHM.js} +4 -4
- package/dist/{chunk-KCGV52AM.js → chunk-HQFVJDEN.js} +7 -7
- package/dist/{chunk-RLR4TKUZ.js → chunk-HVFR66GQ.js} +2 -2
- package/dist/{chunk-2U3ORT6D.js → chunk-IA7BMIPE.js} +2 -2
- package/dist/{chunk-LAKAWRV5.js → chunk-JQU7FHYH.js} +6 -6
- package/dist/{chunk-YIL4XLLJ.js → chunk-K3U5F2QT.js} +183 -31
- package/dist/chunk-K3U5F2QT.js.map +1 -0
- package/dist/{chunk-X3BPBDGQ.js → chunk-MZC62HPZ.js} +2 -2
- package/dist/{chunk-V46OILVC.js → chunk-NAZRLJAK.js} +3 -3
- package/dist/{chunk-BUXDLRDT.js → chunk-NGK3N6F2.js} +3 -3
- package/dist/{chunk-WQE54PNH.js → chunk-NN4ASVTY.js} +3 -3
- package/dist/{chunk-PCHZY2I7.js → chunk-OIZ3XMKB.js} +13 -11
- package/dist/chunk-OIZ3XMKB.js.map +1 -0
- package/dist/{chunk-CYWHFSRT.js → chunk-QCBICNKC.js} +6 -6
- package/dist/chunk-QCBICNKC.js.map +1 -0
- package/dist/{chunk-YFQBFNQS.js → chunk-QLUMKWQQ.js} +3 -3
- package/dist/{chunk-YYBFZLAJ.js → chunk-QY3DOZMS.js} +4 -4
- package/dist/{chunk-IEQHSCZG.js → chunk-SJO2FTPG.js} +6 -6
- package/dist/{chunk-ERMSO34F.js → chunk-SNEHX4VE.js} +2 -2
- package/dist/{chunk-252LNOEG.js → chunk-TA42STP7.js} +4 -4
- package/dist/{chunk-CK7SKVHR.js → chunk-TBAMBLF3.js} +3 -12
- package/dist/chunk-TBAMBLF3.js.map +1 -0
- package/dist/{chunk-C6OH6CNF.js → chunk-TCC737IS.js} +3 -3
- package/dist/{chunk-H2DLH2JI.js → chunk-TVIX653Q.js} +3 -3
- package/dist/{chunk-G7NJSREW.js → chunk-UK2I3ACY.js} +3 -3
- package/dist/{chunk-XSLV76YK.js → chunk-XWFNO5PO.js} +3 -3
- package/dist/{chunk-PHF3D7ER.js → chunk-YA63PVWI.js} +5 -5
- package/dist/chunk-YGFIQ6Y5.js +17 -0
- package/dist/chunk-YGFIQ6Y5.js.map +1 -0
- package/dist/{chunk-MYC3O5EJ.js → chunk-ZX43SRZR.js} +3 -3
- package/dist/{cli-URZQXL4K.js → cli-6PGVHP7Y.js} +15 -15
- package/dist/{cli-2QPR2OZG.js → cli-AAG3N4NB.js} +16 -16
- package/dist/{cli-4IOPGZHR.js → cli-E3H6ZP4I.js} +2 -2
- package/dist/{cli-OFPZ5MAS.js → cli-HUIMNJT6.js} +20 -15
- package/dist/cli-HUIMNJT6.js.map +1 -0
- package/dist/{cli-LJLLIQB2.js → cli-MHTYPVOD.js} +16 -16
- package/dist/{cli-5FL73WHA.js → cli-PRZHQ3QB.js} +15 -13
- package/dist/{cli-5FL73WHA.js.map → cli-PRZHQ3QB.js.map} +1 -1
- package/dist/{cli-SRHFUZHA.js → cli-QKIJOXGW.js} +13 -13
- package/dist/{cli-C262QOWM.js → cli-TYGOHJOJ.js} +25 -25
- package/dist/{cli-SHSMSRQY.js → cli-YW6VWBHX.js} +9 -9
- package/dist/cli.js +11 -11
- package/dist/docmeta.js +8 -8
- package/dist/{github-QXL3VMK2.js → github-3WMSTNTK.js} +13 -13
- package/dist/{github-FE6KCNYJ.js → github-OXSJQ4PS.js} +11 -11
- package/dist/index.d.ts +30 -8
- package/dist/index.js +42 -38
- package/dist/index.js.map +1 -1
- package/dist/{json-SGZ6ZRFD.js → json-4DCKDGUV.js} +11 -11
- package/dist/lint-YDHVVZHT.js +30 -0
- package/dist/{list-7BKNYPSB.js → list-3ZO2NIYO.js} +11 -11
- package/dist/{list-6BAXTZUM.js → list-EJH6VAOW.js} +11 -11
- package/dist/{page-3U2GCFNE.js → page-QEDB7EVU.js} +10 -10
- package/dist/{pretty-N6DO4OOL.js → pretty-5DGEBZSV.js} +11 -11
- package/dist/{pretty-2H57QVTY.js → pretty-SQX33UM2.js} +12 -12
- package/dist/{reporters-N6GHXSS7.js → reporters-OHSI3RMV.js} +12 -11
- package/dist/{reporters-UCNEV7PH.js → reporters-YELDDYJD.js} +4 -4
- package/dist/{run-XZDAREJE.js → run-IP6NZHAG.js} +11 -11
- package/dist/{term-5ICGKPC3.js → term-2WMDZ4PY.js} +15 -15
- package/dist/{validate-GQRM77YN.js → validate-G6HH3YXL.js} +5 -5
- package/package.json +1 -1
- package/plugin/manni/.claude-plugin/plugin.json +1 -1
- package/plugin/manni/hooks/hooks.json +21 -4
- package/plugin/manni/hooks/manni.mjs +157 -0
- package/plugin/manni/skills/check/SKILL.md +3 -3
- package/plugin/manni/skills/evals/SKILL.md +2 -2
- package/plugin/manni/skills/fix/SKILL.md +3 -3
- package/plugin/manni/skills/setup/SKILL.md +3 -3
- package/dist/chunk-644JVKJ4.js.map +0 -1
- package/dist/chunk-CK7SKVHR.js.map +0 -1
- package/dist/chunk-CYWHFSRT.js.map +0 -1
- package/dist/chunk-JOHKIAVH.js.map +0 -1
- package/dist/chunk-M2JCK5F6.js.map +0 -1
- package/dist/chunk-PCHZY2I7.js.map +0 -1
- package/dist/chunk-YIL4XLLJ.js.map +0 -1
- package/dist/cli-OFPZ5MAS.js.map +0 -1
- package/dist/lint-DL4LJRAY.js +0 -28
- /package/dist/{batch-DFRCLY77.js.map → batch-GOE3UXOD.js.map} +0 -0
- /package/dist/{build-Q5C6SX5J.js.map → build-M7BMEHL2.js.map} +0 -0
- /package/dist/{calibrate-XQILKXS3.js.map → calibrate-6RRAILUY.js.map} +0 -0
- /package/dist/{capture-JQMOC3BW.js.map → capture-RJPQ6B4N.js.map} +0 -0
- /package/dist/{check-HYNGXYJV.js.map → check-BQD64X3N.js.map} +0 -0
- /package/dist/{check-NFZQLJKN.js.map → check-ESNS7ZBC.js.map} +0 -0
- /package/dist/{check-U54XV6BP.js.map → check-RQIIIURI.js.map} +0 -0
- /package/dist/{chunk-7QMCHA4N.js.map → chunk-3R5Y3XOL.js.map} +0 -0
- /package/dist/{chunk-K3D6FPV6.js.map → chunk-3YHAYXBC.js.map} +0 -0
- /package/dist/{chunk-6OYEI2VV.js.map → chunk-52PDIZKV.js.map} +0 -0
- /package/dist/{chunk-NWZ2SLYL.js.map → chunk-7OQAU4EA.js.map} +0 -0
- /package/dist/{chunk-5YXBLLAC.js.map → chunk-7ZUCEMCY.js.map} +0 -0
- /package/dist/{chunk-MYMBCTDE.js.map → chunk-BOIF2XGG.js.map} +0 -0
- /package/dist/{chunk-3AFUD75K.js.map → chunk-C6HZ6C5T.js.map} +0 -0
- /package/dist/{chunk-XYLUCIKQ.js.map → chunk-CP4ZM43V.js.map} +0 -0
- /package/dist/{chunk-YTCZRLTU.js.map → chunk-DX32P2DT.js.map} +0 -0
- /package/dist/{chunk-OBFENF3U.js.map → chunk-F2OVHJNC.js.map} +0 -0
- /package/dist/{chunk-5KHIFVD2.js.map → chunk-FLF6AECQ.js.map} +0 -0
- /package/dist/{chunk-77HX34KD.js.map → chunk-GAZFKZHM.js.map} +0 -0
- /package/dist/{chunk-KCGV52AM.js.map → chunk-HQFVJDEN.js.map} +0 -0
- /package/dist/{chunk-RLR4TKUZ.js.map → chunk-HVFR66GQ.js.map} +0 -0
- /package/dist/{chunk-2U3ORT6D.js.map → chunk-IA7BMIPE.js.map} +0 -0
- /package/dist/{chunk-LAKAWRV5.js.map → chunk-JQU7FHYH.js.map} +0 -0
- /package/dist/{chunk-X3BPBDGQ.js.map → chunk-MZC62HPZ.js.map} +0 -0
- /package/dist/{chunk-V46OILVC.js.map → chunk-NAZRLJAK.js.map} +0 -0
- /package/dist/{chunk-BUXDLRDT.js.map → chunk-NGK3N6F2.js.map} +0 -0
- /package/dist/{chunk-WQE54PNH.js.map → chunk-NN4ASVTY.js.map} +0 -0
- /package/dist/{chunk-YFQBFNQS.js.map → chunk-QLUMKWQQ.js.map} +0 -0
- /package/dist/{chunk-YYBFZLAJ.js.map → chunk-QY3DOZMS.js.map} +0 -0
- /package/dist/{chunk-IEQHSCZG.js.map → chunk-SJO2FTPG.js.map} +0 -0
- /package/dist/{chunk-ERMSO34F.js.map → chunk-SNEHX4VE.js.map} +0 -0
- /package/dist/{chunk-252LNOEG.js.map → chunk-TA42STP7.js.map} +0 -0
- /package/dist/{chunk-C6OH6CNF.js.map → chunk-TCC737IS.js.map} +0 -0
- /package/dist/{chunk-H2DLH2JI.js.map → chunk-TVIX653Q.js.map} +0 -0
- /package/dist/{chunk-G7NJSREW.js.map → chunk-UK2I3ACY.js.map} +0 -0
- /package/dist/{chunk-XSLV76YK.js.map → chunk-XWFNO5PO.js.map} +0 -0
- /package/dist/{chunk-PHF3D7ER.js.map → chunk-YA63PVWI.js.map} +0 -0
- /package/dist/{chunk-MYC3O5EJ.js.map → chunk-ZX43SRZR.js.map} +0 -0
- /package/dist/{cli-URZQXL4K.js.map → cli-6PGVHP7Y.js.map} +0 -0
- /package/dist/{cli-2QPR2OZG.js.map → cli-AAG3N4NB.js.map} +0 -0
- /package/dist/{cli-4IOPGZHR.js.map → cli-E3H6ZP4I.js.map} +0 -0
- /package/dist/{cli-LJLLIQB2.js.map → cli-MHTYPVOD.js.map} +0 -0
- /package/dist/{cli-SRHFUZHA.js.map → cli-QKIJOXGW.js.map} +0 -0
- /package/dist/{cli-C262QOWM.js.map → cli-TYGOHJOJ.js.map} +0 -0
- /package/dist/{cli-SHSMSRQY.js.map → cli-YW6VWBHX.js.map} +0 -0
- /package/dist/{github-FE6KCNYJ.js.map → github-3WMSTNTK.js.map} +0 -0
- /package/dist/{github-QXL3VMK2.js.map → github-OXSJQ4PS.js.map} +0 -0
- /package/dist/{json-SGZ6ZRFD.js.map → json-4DCKDGUV.js.map} +0 -0
- /package/dist/{lint-DL4LJRAY.js.map → lint-YDHVVZHT.js.map} +0 -0
- /package/dist/{list-6BAXTZUM.js.map → list-3ZO2NIYO.js.map} +0 -0
- /package/dist/{list-7BKNYPSB.js.map → list-EJH6VAOW.js.map} +0 -0
- /package/dist/{page-3U2GCFNE.js.map → page-QEDB7EVU.js.map} +0 -0
- /package/dist/{pretty-2H57QVTY.js.map → pretty-5DGEBZSV.js.map} +0 -0
- /package/dist/{pretty-N6DO4OOL.js.map → pretty-SQX33UM2.js.map} +0 -0
- /package/dist/{reporters-N6GHXSS7.js.map → reporters-OHSI3RMV.js.map} +0 -0
- /package/dist/{reporters-UCNEV7PH.js.map → reporters-YELDDYJD.js.map} +0 -0
- /package/dist/{run-XZDAREJE.js.map → run-IP6NZHAG.js.map} +0 -0
- /package/dist/{term-5ICGKPC3.js.map → term-2WMDZ4PY.js.map} +0 -0
- /package/dist/{validate-GQRM77YN.js.map → validate-G6HH3YXL.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graph/types.ts","../src/graph/core/iri.ts","../src/graph/core/config.ts","../src/graph/core/config-schema.json","../src/graph/core/vocab.ts","../src/graph/core/iirds.ts","../src/graph/core/coverage.ts","../src/graph/embed/types.ts","../src/graph/core/sort.ts"],"sourcesContent":["/** Shared types for manni graph. */\nimport { ToolError } from \"../shared/errors.js\";\nimport type { DocFormat } from \"./core/analyze.js\";\n\n/** Operational error: expected failure reported to the user, exit code 2. */\nexport class GraphError extends ToolError {\n constructor(message: string) {\n super(message);\n this.name = \"GraphError\";\n }\n}\n\n/** A heading-derived section within a document. */\nexport interface Section {\n /** GitHub-style slug, disambiguated (`install`, `install-1`, ...). */\n slug: string;\n /** Heading text. */\n title: string;\n /** Heading level, 1-6. */\n level: number;\n /** 1-based position among siblings under the same parent. */\n order: number;\n /** Slug of the enclosing section, or null when the parent is the document. */\n parentSlug: string | null;\n}\n\n/** A link found in a document body. */\nexport interface DocLink {\n /** The raw target as written in the source. */\n raw: string;\n /**\n * internal: resolves to a discovered doc (repo-relative path in `resolvedPath`,\n * optional `anchor`);\n * external: absolute URL;\n * broken: relative target that does not match a discovered doc.\n */\n kind: \"internal\" | \"external\" | \"broken\";\n /** Repo-relative path of the target doc (internal links only). */\n resolvedPath?: string;\n /** Fragment identifier without `#`, when present. */\n anchor?: string;\n /** Normalized absolute URL (external links only). */\n url?: string;\n}\n\n/** An image reference found in a document body. */\nexport interface DocImage {\n raw: string;\n /** Absolute URL or repo-relative path resolved from the doc's location. */\n target: string;\n external: boolean;\n}\n\n/** Everything dockg derives from one source file. */\nexport interface DocModel {\n /** Repo-relative path with forward slashes, e.g. `docs/guide.md`. */\n path: string;\n /** Parsed frontmatter data ({} when absent). */\n frontmatter: Record<string, unknown>;\n /** Whether a frontmatter block was present. */\n frontmatterPresent: boolean;\n /** The format the page was parsed as: `--as`, else its extension. */\n format: DocFormat;\n /** First H1 text, if any (used as title fallback). */\n firstH1?: string;\n sections: Section[];\n links: DocLink[];\n images: DocImage[];\n /** Distinct fenced code block languages, sorted. */\n codeLanguages: string[];\n /**\n * BCP-47 tag from the nearest enclosing route mapping that declares one\n * (ADR 01037), or undefined when no route covers this path or none in the\n * chain declares a language. The page's own `lang`/`language` frontmatter\n * outranks it.\n */\n routeLanguage?: string;\n /**\n * Lowercase sha256 hex digest of the document's UTF-8 content, as read —\n * line endings included, so it matches `sha256sum <file>` (ADR 01036).\n */\n contentHash: string;\n}\n","/**\n * Deterministic IRI minting. Every node in the graph gets a stable IRI derived\n * from the base IRI plus repo-relative paths, heading slugs, or concept labels —\n * never blank nodes. Identical inputs mint identical IRIs on every OS.\n */\nimport { slug as githubSlug } from \"github-slugger\";\n\n/** Default base when the config sets none: valid, deterministic, obviously placeholder. */\nexport const DEFAULT_BASE_IRI = \"urn:manni:graph:\";\n\n/** Normalize a config base IRI; http(s) bases get a trailing slash. */\nexport function resolveBaseIri(base: string | undefined): string {\n if (!base) return DEFAULT_BASE_IRI;\n if (base.endsWith(\"/\") || base.endsWith(\":\")) return base;\n return `${base}/`;\n}\n\n/** Repo-relative path with forward slashes and no leading `./`. */\nexport function normalizeDocPath(p: string): string {\n let out = p.replace(/\\\\/g, \"/\");\n while (out.startsWith(\"./\")) out = out.slice(2);\n return out;\n}\n\n/** RFC 3986 strict percent-encoding of one path segment (UTF-8 for non-ASCII). */\nexport function encodeSegment(segment: string): string {\n return encodeURIComponent(segment).replace(\n /[!'()*]/g,\n (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n}\n\n/**\n * The display path of a document read from stdin (`-`). It has no file name,\n * so its node is `{base}stdin` rather than a `doc/` path, and its links\n * resolve from the working directory.\n */\nexport const STDIN_PATH = \"<stdin>\";\n\n/**\n * `{base}doc/{repo-relative-path}`, segment-wise percent-encoded. A document\n * read from stdin is `{base}stdin`.\n */\nexport function mintDocIri(base: string, relPath: string): string {\n if (relPath === STDIN_PATH) return `${base}stdin`;\n const path = normalizeDocPath(relPath)\n .split(\"/\")\n .map(encodeSegment)\n .join(\"/\");\n return `${base}doc/${path}`;\n}\n\n/** `{docIri}#{slug}` — the slug comes pre-disambiguated from analysis. */\nexport function mintSectionIri(docIri: string, slugValue: string): string {\n return `${docIri}#${slugValue}`;\n}\n\n/** Stateless GitHub-style slug; identical labels always converge. */\nexport function conceptSlug(label: string): string {\n return githubSlug(label);\n}\n\n/** `{base}concept/{slug(label)}` — one shared namespace for all concepts. */\nexport function mintConceptIri(base: string, label: string): string {\n return `${base}concept/${encodeSegment(conceptSlug(label))}`;\n}\n\n/**\n * `{base}product/{slug(label)}` — iiRDS ProductVariant nodes (graph.applies-to).\n * Separate `product/` segment so a product and a concept sharing a label\n * cannot converge on one IRI.\n */\nexport function mintProductIri(base: string, label: string): string {\n return `${base}product/${encodeSegment(conceptSlug(label))}`;\n}\n\n/** The single skos:ConceptScheme node for the graph. */\nexport function mintSchemeIri(base: string): string {\n return `${base}scheme`;\n}\n\n/**\n * The kind of actor an agent IRI names, mirroring PROV-O's three\n * `prov:Agent` subclasses. Segmenting by kind keeps a person and a model\n * whose names slug alike (\"GPT 4\" / \"gpt-4\") from merging into one node.\n */\nexport type AgentKind = \"person\" | \"org\" | \"software\";\n\n/** `{base}agent/{kind}/{slug(name)}`. */\nexport function mintAgentIri(\n base: string,\n kind: AgentKind,\n name: string,\n): string {\n return `${base}agent/${kind}/${encodeSegment(conceptSlug(name))}`;\n}\n\n/** The graph itself as a prov:Entity. */\nexport function mintGraphIri(base: string): string {\n return `${base}graph`;\n}\n\n/** The build run as a prov:Activity. */\nexport function mintBuildActivityIri(base: string): string {\n return `${base}activity/build`;\n}\n","/**\n * Loads and validates the `graph:` section of `manni.config.yaml`. Discovery is\n * the family's (`src/shared/config-file.ts`); validation is JSON Schema\n * (2020-12) via Ajv; defaults are applied in code afterward so the resolved\n * shape is fully typed. Mirrors the docevals config pattern.\n */\nimport { dirname, resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { Ajv2020 } from \"ajv/dist/2020.js\";\nimport configSchema from \"./config-schema.json\" with { type: \"json\" };\nimport {\n findConfigFileSync,\n readConfigFileSync,\n type ConfigFileOptions,\n} from \"../../shared/config-file.js\";\nimport type { CollectionConfig } from \"../../shared/collections.js\";\nimport { parseCollections } from \"../../shared/collections.js\";\nimport {\n PROVIDERS_KEY,\n assertKnownProvider,\n parseProviders,\n type ProvidersConfig,\n} from \"../../shared/providers.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { GraphError } from \"../types.js\";\nimport { resolveBaseIri } from \"./iri.js\";\nimport { COVERAGE_FIELD_NAMES } from \"./coverage.js\";\n// Pure data module (no transformers import), so config stays Node-light.\nimport { DEFAULT_MODEL as DEFAULT_EMBED_MODEL } from \"../embed/types.js\";\n\nexport type DeriveSource =\n | \"frontmatter\"\n | \"sections\"\n | \"links\"\n | \"tags\"\n | \"images\"\n | \"code\"\n | \"provenance\";\n\nexport type FillField =\n // SKOS concept fields\n | \"label\"\n | \"alt-labels\"\n | \"broader\"\n | \"narrower\"\n | \"related-concepts\"\n | \"concepts\"\n // iiRDS typing + negative scope (ADR 01015)\n | \"type\"\n | \"applies-to\"\n | \"about-product-lifecycle\"\n | \"about-product-aspect\"\n | \"not-applicable-to\"\n | \"not-about-product-aspect\";\n\n/** Every fillable field, in a stable order — the default `fill.fields`. */\nexport const ALL_FILL_FIELDS: FillField[] = [\n \"label\",\n \"alt-labels\",\n \"broader\",\n \"narrower\",\n \"related-concepts\",\n \"concepts\",\n \"type\",\n \"applies-to\",\n \"about-product-lifecycle\",\n \"about-product-aspect\",\n \"not-applicable-to\",\n \"not-about-product-aspect\",\n];\n\n/** Maps published-site routes back to source files. */\nexport interface RouteMapping {\n /** Site prefix, normalized: leading `/`, no trailing `/`; `\"\"` = site root. */\n basePath: string;\n /** Repo-relative directory routes resolve into (no trailing slash). */\n root: string;\n /** Extensions to try when the route names a page without one. */\n extensions: string[];\n /** Basenames to try for directory routes (`/docs/actions/`). */\n indexFiles: string[];\n /**\n * BCP-47 tag labelling every document under `root` (ADR 01037). A page's own\n * `lang`/`language` frontmatter wins; absent that, the nearest enclosing\n * route that declares one applies. Omitted, the route says nothing about\n * language.\n */\n language?: string;\n}\n\nexport interface GraphConfig {\n /**\n * The family's document sets, from the file's top-level `collections:`\n * (proposal 0041). `[]` when the key is absent or no file governs the run.\n */\n collections: CollectionConfig[];\n /**\n * The config file as the user would name it, for messages; `null` when no\n * file governs the run and every value is a built-in default.\n */\n configSource: string | null;\n /**\n * `graph.provider`, or `null` when unset: the family's `providers.provider`\n * decides then, and `auto` (detect) after it. `--provider` wins over it and\n * `--local` overrides both (proposal 0051 §3).\n */\n provider: string | null;\n /**\n * The model within the provider, or `null` for the provider's own default.\n * manni pins no model: the inference library chooses, and the model it\n * resolves to is what every cache key names. Not `embed.model`, which is a\n * local embedding model id and has nothing to do with a provider.\n */\n model: string | null;\n /**\n * The family's top-level `providers:`: the provider and model every tool\n * falls back to, and the connection settings for each provider. `{}` when\n * the file declares none, or no file governs the run.\n */\n providers: ProvidersConfig;\n /** Normalized base IRI (trailing slash for http(s); `urn:manni:graph:` default). */\n baseIri: string;\n /** Output path of the built Turtle file, relative to configDir. */\n out: string;\n routes: RouteMapping[];\n build: { derive: DeriveSource[] };\n /** Graph-level SHACL validation (`manni graph check`). */\n check: {\n /** Shapes .ttl paths; empty = the shapes bundled with manni. */\n shapes: string[];\n };\n provenance: {\n /**\n * Emit qualified attribution/association nodes with roles.\n *\n * The one provenance setting left. `git` was tri-state until proposal\n * 0051 §6: git history is *detected* now, used wherever git can run over a\n * repository and degraded to a warning where it cannot (graph ADR 01010's\n * `\"auto\"`, minus the switch). `qualified` stays because it switches what\n * is written, not what is discovered.\n */\n qualified: boolean;\n };\n fill: {\n temperature: number;\n /**\n * Stop after this many inference calls; `null` (the default) is\n * unbounded. One page is one turn, and a cached proposal spends none.\n * Replaces the dollar cap graph ADR 01027 found unenforceable, as docevals\n * ADR 01019 replaced its own (proposal 0051 §3).\n */\n maxTurns: number | null;\n cacheDir: string;\n fields: FillField[];\n /**\n * Minimum model self-confidence (0..1) to write a proposed field; below\n * this it is reported but not written (ADR 01015). Default 0.7. Named as\n * meta, docevals and tracevals name it (proposal 0051 §3).\n */\n confidenceThreshold: number;\n /** Record the page-level meta-provenance on filled docs (proposal 0046). */\n writeProvenance: boolean;\n /** Reject proposals that would violate the SHACL shapes contract. */\n validateGraph: boolean;\n /** Also propose per-section metadata (ADR 01032). Opt-in: more output. */\n sections: boolean;\n };\n stats: {\n /**\n * Per-field minimum coverage percentages (0–100) enforced under\n * `stats --check`. Resolved shape is always a map; a uniform number in the\n * config expands across every measured field. Default `{}` gates nothing.\n * See ADR 01011.\n */\n coverageThreshold: Record<string, number>;\n };\n embed: {\n /**\n * Embedding model id (ADR 01020). An open string, not an enum: the\n * documented table is the *tested* set, not the permitted set, so a newer\n * model works without a manni release.\n */\n model: string;\n /** Weight quantization. `q8` keeps int32 accumulation, which is associative. */\n dtype: string;\n /**\n * Directory the sidecars are written into (ADR 01038). One file per\n * language, named by `vectorIndexFilename`, so this is a directory rather\n * than the single path it was before the fan-out. Resolved from the\n * working directory, as `out` is. Undefined means the index directory,\n * which is why it has no default here.\n */\n out: string | undefined;\n /**\n * Per-language model overrides, keyed by BCP-47 tag (ADR 01038). A German\n * corpus embedded with an English-only model returns confident, meaningless\n * vectors and fails nothing, so this is the knob that makes the fan-out\n * worth having. Unset languages use `model`/`dtype`.\n */\n byLanguage: Record<string, { model?: string; dtype?: string }>;\n /** Per-text vector cache, keyed on text+model+dtype. */\n cacheDir: string;\n };\n export: {\n /** iiRDS package export metadata (ADR 01017); all fields optional. */\n iirds: {\n /** Package title; when absent the exporter uses a default. */\n title?: string;\n /** Creator organization name → a Creator iirds:Party + vcard:Organization. */\n creator?: string;\n /** iiRDS version literal written to the package. Default \"1.3\". */\n version: \"1.2\" | \"1.3\";\n };\n };\n /** Absolute path of the loaded config file. */\n configPath: string;\n /** Directory containing the config file; relative paths resolve against it. */\n configDir: string;\n}\n\n/** The family config file; this tool reads its `graph:` key. */\nexport const DEFAULT_CONFIG_FILENAME = \"manni.config.yaml\";\n/** The tool's key in the family file. */\nexport const CONFIG_SECTION = \"graph\";\n/** The family's top-level key for document sets (proposal 0041). */\nconst COLLECTIONS_KEY = \"collections\";\n\n/**\n * Where the metadata tool's configuration reference documents `collections:`.\n * The literal docevals', cite's and meta's config modules carry, repeated\n * because those modules are theirs.\n */\nconst CONFIG_REF =\n \"https://hawkeyexl.github.io/manni/meta/reference/configuration/\";\n\n/**\n * The keys proposal 0041 moved out of `graph:` and up to the family level.\n * Refused rather than aliased, as meta, cite and docevals refuse theirs: an\n * alias would be a second place to declare a document set that is meant to be\n * declared once. Checked before Ajv, which would call them unknown keys.\n */\nconst MOVED_KEYS = [\"inputs\", \"exclude\"] as const;\n\nexport const ALL_DERIVE_SOURCES: DeriveSource[] = [\n \"frontmatter\",\n \"sections\",\n \"links\",\n \"tags\",\n \"images\",\n \"code\",\n \"provenance\",\n];\n\n/** Default candidates for extensionless link targets (routes AND relative links). */\nexport const DEFAULT_LINK_EXTENSIONS = [\".md\", \".mdx\", \".markdown\"];\nexport const DEFAULT_INDEX_FILES = [\"index\", \"README\"];\n\n/** `/docs/` -> `/docs`; `/` or `` -> `` (site root). */\nfunction normalizeBasePath(basePath: string): string {\n let out = basePath.trim();\n if (!out.startsWith(\"/\")) out = `/${out}`;\n out = out.replace(/\\/+$/, \"\");\n return out;\n}\n\nconst ajv = new Ajv2020({ allErrors: true, allowUnionTypes: true });\nconst validateConfig = ajv.compile(configSchema);\n\n/** One `routes:` entry as the file spells it; only `root` is required. */\ninterface RawRouteMapping {\n basePath?: string;\n root: string;\n extensions?: string[];\n indexFiles?: string[];\n language?: string;\n}\n\n/**\n * The config file's own shape, in its own spelling.\n *\n * Ajv has already validated `raw` against `config-schema.json` by the time this\n * is used, so the optionality here is the schema's, not a guess. Declaring it is\n * what lets `parseConfigSection` read the file without an `any` — and an `any`\n * here would be the worst place for one, since every default in the tool flows\n * through this function. `RawDocevalsConfig` is the same declaration in the\n * evals tool.\n */\ninterface RawGraphConfig {\n provider?: string;\n model?: string;\n baseIri?: string;\n out?: string;\n routes?: RawRouteMapping[];\n build?: { derive?: DeriveSource[] };\n check?: { shapes?: string[] };\n provenance?: { qualified?: boolean };\n stats?: { coverageThreshold?: number | Record<string, number> };\n fill?: {\n temperature?: number;\n maxTurns?: number | null;\n cacheDir?: string;\n confidenceThreshold?: number;\n writeProvenance?: boolean;\n validateGraph?: boolean;\n fields?: FillField[];\n sections?: boolean;\n };\n embed?: {\n model?: string;\n dtype?: string;\n out?: string;\n cacheDir?: string;\n byLanguage?: Record<string, { model?: string; dtype?: string }>;\n };\n export?: {\n iirds?: { title?: string; creator?: string; version?: \"1.2\" | \"1.3\" };\n };\n}\n\n/**\n * One Ajv error, as a line a reader can act on.\n *\n * Ajv reports an unknown key against the *parent* object, so the bare message\n * (\"must NOT have additional properties\") leaves the reader to diff their file\n * against the schema to find which key it meant. Name it, as docevals does\n * (PR #10): the common case here is a key that was removed — `version:`,\n * `provenance.git:` and `fill.provider:` after proposal 0051 — and a message\n * that makes you guess is one people work around.\n *\n * The path is the one the user writes. Ajv validates the `graph:` section on its\n * own, so its `instancePath` starts inside it; `/graph` goes back on the front,\n * so a reader can find `/graph/fill` in `manni.config.yaml` without translating.\n */\nfunction configErrorLine(e: {\n instancePath: string;\n keyword: string;\n params: unknown;\n message?: string | undefined;\n}): string {\n const extra =\n e.keyword === \"additionalProperties\"\n ? (e.params as { additionalProperty?: string }).additionalProperty\n : undefined;\n const where = `/${CONFIG_SECTION}${e.instancePath}`;\n return extra === undefined\n ? ` ${where}: ${e.message ?? \"is invalid\"}`\n : ` ${where}: unknown key \"${extra}\"`;\n}\n\n/**\n * Normalize `stats.coverageThreshold` to a per-field map. Ajv has already\n * validated the input as a number, an object of known fields, or absent; a\n * uniform number expands across every measured field so the resolved shape is\n * always a map (default `{}`).\n */\nfunction resolveCoverageThreshold(\n raw: number | Record<string, number> | undefined,\n): Record<string, number> {\n if (raw == null) return {};\n if (typeof raw === \"number\")\n return Object.fromEntries(COVERAGE_FIELD_NAMES.map((f) => [f, raw]));\n return { ...raw };\n}\n\n/** What the file the section came from carries beside it. */\nexport interface ConfigFileContext {\n /** The file as the user would name it, for messages. */\n source: string;\n /** The file's top-level `collections:`. */\n collections: CollectionConfig[];\n /** The file's top-level `providers:`; `{}` when it declares none. */\n providers?: ProvidersConfig;\n}\n\n/**\n * Parse and validate config YAML text. A document with a `graph:` key is a family\n * file, so its top-level `collections:` is read too; anything else is the\n * tool's section on its own.\n */\nexport function parseConfig(text: string, configPath: string): GraphConfig {\n let raw: unknown;\n try {\n raw = parseYaml(text);\n } catch (e) {\n throw new GraphError(\n `Invalid YAML in ${configPath}: ${errorMessage(e)}`,\n );\n }\n if (raw == null) return parseConfigSection(null, configPath);\n if (typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new GraphError(`Invalid config in ${configPath}: root must be an object`);\n }\n const doc = raw as Record<string, unknown>;\n const wrapped = Object.hasOwn(doc, CONFIG_SECTION);\n const toError = (message: string): Error => new GraphError(message);\n // The family keys, parsed as the shared loader parses them, so a config\n // built from text selects from the same collections, and the same\n // providers, a discovered file would.\n const collections = Object.hasOwn(doc, COLLECTIONS_KEY)\n ? parseCollections(doc[COLLECTIONS_KEY], configPath, toError)\n : [];\n const providers = Object.hasOwn(doc, PROVIDERS_KEY)\n ? parseProviders(\n doc[PROVIDERS_KEY],\n configPath,\n dirname(resolve(configPath)),\n toError,\n )\n : {};\n return parseConfigSection(wrapped ? doc[CONFIG_SECTION] : doc, configPath, {\n source: configPath,\n collections,\n providers,\n });\n}\n\n/**\n * Validate the tool's section. `raw` is what sat under `graph:` in a family\n * file, or the whole document of an explicit path with no wrapper key.\n * Messages name `configPath`; relative paths in the config resolve against its\n * directory. `file` carries the family keys; absent, the section is its own\n * source and declares no collections.\n *\n * `null` is an empty section, which is every default: a `graph:` key somebody\n * added while migrating and has not filled in yet is a config, not an error.\n */\nexport function parseConfigSection(\n raw: unknown,\n configPath: string,\n file: ConfigFileContext = { source: configPath, collections: [] },\n): GraphConfig {\n if (raw == null) raw = {};\n if (typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new GraphError(\n `Invalid config in ${configPath}: root must be an object`,\n );\n }\n for (const key of MOVED_KEYS) {\n if (Object.hasOwn(raw as Record<string, unknown>, key)) {\n throw new GraphError(\n `${file.source}: \"${key}\" is no longer a graph key. Document sets are declared once for every tool, under a top-level collections: list. See ${CONFIG_REF}#${COLLECTIONS_KEY}`,\n );\n }\n }\n if (!validateConfig(raw)) {\n const details = (validateConfig.errors ?? [])\n .map((e) => configErrorLine(e))\n .join(\"\\n\");\n throw new GraphError(`Invalid config in ${configPath}:\\n${details}`);\n }\n\n // Past this point Ajv has validated `raw` against config-schema.json, so the\n // shape is known-good and reading fields off it is safe. The cast is to that\n // shape, spelled out once in `RawGraphConfig`, rather than to `any`: the file's\n // optionality is then the schema's and every default below is checked.\n const r = raw as RawGraphConfig;\n const abs = resolve(configPath);\n const dir = dirname(abs);\n\n // The name is checked here, with the message `manni meta fill` gives, so a\n // typo is caught by every verb and not only the one that reaches a model.\n // Whether a model has a provider to own it waits for the flags: a\n // `--provider`, or the family's `providers.provider`, can supply the\n // provider a configured model needs.\n const provider: string | null = r.provider ?? null;\n if (provider !== null) {\n assertKnownProvider(provider, (message) => new GraphError(message));\n }\n\n return {\n collections: file.collections,\n configSource: file.source,\n provider,\n model: r.model ?? null,\n providers: file.providers ?? {},\n baseIri: resolveBaseIri(r.baseIri),\n out: r.out ?? \"graph/graph.ttl\",\n routes: (r.routes ?? []).map((m) => ({\n basePath: normalizeBasePath(m.basePath ?? \"/\"),\n root: m.root\n .replace(/\\\\/g, \"/\")\n .replace(/^\\.\\//, \"\")\n .replace(/\\/+$/, \"\"),\n extensions: m.extensions ?? [...DEFAULT_LINK_EXTENSIONS],\n indexFiles: m.indexFiles ?? [...DEFAULT_INDEX_FILES],\n ...(m.language === undefined ? {} : { language: m.language }),\n })),\n build: {\n derive: r.build?.derive ?? [...ALL_DERIVE_SOURCES],\n },\n check: {\n // Empty means: use the shapes bundled with manni (see bundledShapesPath).\n shapes: r.check?.shapes ?? [],\n },\n provenance: {\n qualified: r.provenance?.qualified ?? true,\n },\n stats: {\n coverageThreshold: resolveCoverageThreshold(r.stats?.coverageThreshold),\n },\n fill: {\n temperature: r.fill?.temperature ?? 0,\n maxTurns: r.fill?.maxTurns ?? null,\n cacheDir: r.fill?.cacheDir ?? \".manni/graph/cache\",\n fields: r.fill?.fields ?? [...ALL_FILL_FIELDS],\n confidenceThreshold: r.fill?.confidenceThreshold ?? 0.7,\n writeProvenance: r.fill?.writeProvenance ?? true,\n validateGraph: r.fill?.validateGraph ?? true,\n sections: r.fill?.sections ?? false,\n },\n embed: {\n model: r.embed?.model ?? DEFAULT_EMBED_MODEL,\n dtype: r.embed?.dtype ?? \"q8\",\n out: r.embed?.out,\n cacheDir: r.embed?.cacheDir ?? \".manni/graph/embed-cache\",\n byLanguage: r.embed?.byLanguage ?? {},\n },\n export: {\n iirds: {\n title: r.export?.iirds?.title,\n creator: r.export?.iirds?.creator,\n version: r.export?.iirds?.version ?? \"1.3\",\n },\n },\n configPath: abs,\n configDir: dir,\n };\n}\n\nconst CONFIG_FILE: ConfigFileOptions = {\n section: CONFIG_SECTION,\n // The tool was `dockg` before it joined the family (proposal 0051 §7), but\n // it published no config file under that old name, so — like cite, a11y and\n // docevals — there is no pre-family filename to read (proposal 0051 §2).\n legacyNames: [],\n toError: (message) => new GraphError(message),\n};\n\n/**\n * Load config from an explicit path, or discover the family file from the\n * working directory upward (`src/shared/config-file.ts`: `manni.config.yaml`\n * read at its `graph:` key). With no config file present, built-in defaults\n * apply.\n */\nexport function loadConfig(path?: string, cwd = process.cwd()): GraphConfig {\n const file = path\n ? readConfigFileSync(path, cwd, CONFIG_FILE)\n : findConfigFileSync(cwd, CONFIG_FILE);\n if (file === null) return defaultConfig(cwd);\n return parseConfigSection(file.value, file.path, {\n source: file.source,\n collections: file.collections,\n ...(file.providers === undefined ? {} : { providers: file.providers }),\n });\n}\n\n/**\n * Every built-in default, with no file behind it: what a run gets when\n * discovery finds nothing, or under `--no-config`. It declares no collections,\n * so such a run reads only the paths it was given.\n */\nexport function defaultConfig(cwd = process.cwd()): GraphConfig {\n return {\n ...parseConfigSection(null, resolve(cwd, DEFAULT_CONFIG_FILENAME)),\n configSource: null,\n };\n}\n\nexport interface RunConfigOptions {\n /** `-c/--config`. */\n configPath?: string;\n /** `--no-config`: skip discovery and run on the built-in defaults. */\n noConfig?: boolean;\n /** Positional paths; checked here only for how they combine with `collection`. */\n paths?: string[];\n /** `--collection <name>`, repeatable. */\n collection?: string[];\n}\n\n/**\n * The config a command runs under. `--collection` names something only a\n * config can define and selects a set the operator did not type, so pairing it\n * with paths is refused before discovery, and the message is about the flags\n * rather than about whatever the walk found.\n */\nexport function loadRunConfig(\n opts: RunConfigOptions,\n cwd = process.cwd(),\n): GraphConfig {\n assertCollectionWithoutPaths(opts.collection, opts.paths);\n return opts.noConfig ? defaultConfig(cwd) : loadConfig(opts.configPath, cwd);\n}\n\n/** The message meta, cite and docevals give, in graph's error class. */\nexport function assertCollectionWithoutPaths(\n collection: readonly string[] | undefined,\n paths: readonly string[] | undefined,\n): void {\n if ((collection ?? []).length > 0 && (paths ?? []).length > 0) {\n throw new GraphError(\n \"--collection selects a configured collection; it cannot be combined with paths.\",\n );\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"manni:graph:config\",\n \"title\": \"manni graph configuration\",\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"provider\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Which provider `manni graph fill` sends pages to: auto | anthropic | openai | claude-cli | llama-cpp. Unset, the family's top-level providers.provider decides, then auto, detected exactly as manni meta fill detects: an Anthropic key, then an OpenAI key, then the Claude CLI, then a local model. --provider wins over it, and --local overrides both. Connection settings live in the family's top-level providers: map.\"\n },\n \"model\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The model, within the provider named beside it. A model is carried only to the provider its own level names: a differing --provider or providers.provider takes its own default instead. With no provider here, it goes to whichever provider is in force, which must not be auto, because a model name does not say which provider owns it. Unset (the default) takes the provider's default model from the inference library; manni pins none. --model wins over it. This is not `embed.model`, which is a local embedding model id.\"\n },\n \"baseIri\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"out\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"routes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"root\"],\n \"properties\": {\n \"basePath\": {\n \"type\": \"string\"\n },\n \"root\": {\n \"type\": \"string\"\n },\n \"extensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"pattern\": \"^\\\\.\"\n }\n },\n \"language\": {\n \"type\": \"string\",\n \"pattern\": \"^[A-Za-z]{2,3}(-[A-Za-z]{4})?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*$\"\n },\n \"indexFiles\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1\n }\n }\n }\n }\n },\n \"build\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"derive\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"frontmatter\",\n \"sections\",\n \"links\",\n \"tags\",\n \"images\",\n \"code\",\n \"provenance\"\n ]\n }\n }\n }\n },\n \"check\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"shapes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1\n }\n }\n }\n },\n \"provenance\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"qualified\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"stats\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"coverageThreshold\": {\n \"anyOf\": [\n {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"title\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"description\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"creator\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"created\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"modified\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"subject\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"label\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"language\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"type\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"applies-to\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"about-product-lifecycle\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n },\n \"about-product-aspect\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 100\n }\n }\n }\n ]\n }\n }\n },\n \"fill\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"temperature\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 2\n },\n \"maxTurns\": {\n \"type\": [\"integer\", \"null\"],\n \"minimum\": 1,\n \"description\": \"Stop after this many inference calls. One page is one turn, and a cached proposal spends none. Null (the default) is unbounded. Replaces the maxCostUsd ceiling, which read as zero for every model outside the library's price table — see graph ADR 01027 and docevals ADR 01019.\"\n },\n \"cacheDir\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"confidenceThreshold\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1,\n \"description\": \"Minimum model self-confidence (0..1) to write a proposed field; below it the field is reported and not written. Default 0.7. `--confidence` wins over it.\"\n },\n \"writeProvenance\": {\n \"type\": \"boolean\"\n },\n \"validateGraph\": {\n \"type\": \"boolean\"\n },\n \"fields\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"label\",\n \"alt-labels\",\n \"broader\",\n \"narrower\",\n \"related-concepts\",\n \"concepts\",\n \"type\",\n \"applies-to\",\n \"about-product-lifecycle\",\n \"about-product-aspect\",\n \"not-applicable-to\",\n \"not-about-product-aspect\"\n ]\n }\n },\n \"sections\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"embed\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"model\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"dtype\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"out\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"cacheDir\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"byLanguage\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"patternProperties\": {\n \"^[A-Za-z]{2,3}(-[A-Za-z]{4})?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*$\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"model\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"dtype\": {\n \"type\": \"string\",\n \"minLength\": 1\n }\n }\n }\n }\n }\n }\n },\n \"export\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"iirds\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"creator\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"version\": {\n \"enum\": [\"1.2\", \"1.3\"]\n }\n }\n }\n }\n }\n }\n}\n","/**\n * Namespace table. Standard vocabularies wherever a term exists; the custom\n * `graph:` namespace stays minimal, and the newest vocabulary document under\n * `ns/` defines every term it holds — a bidirectional drift guard in\n * test/graph/unit/vocabulary.test.ts enforces both directions. Neither the term\n * count nor the version is written here: both went stale the first time a term\n * was added, and the guard resolves the file rather than naming it. The prefix\n * set is fixed — every emitted graph carries the same header.\n *\n * The custom prefix is `graph:` and its namespace is the manni site's, which is\n * where it dereferences (proposal 0051 §7). Both were `dockg` until the tool\n * joined the family, and graph ADR 01030's rule — the namespace IRI must resolve\n * — is why they moved rather than staying: `hawkeyexl.github.io/dockg` never\n * served anything and never will.\n *\n * The block an author writes on a page is `graph:`, and the prefix is `graph:`\n * too. The spelling is shared but the things differ: the key names frontmatter,\n * the prefix abbreviates an IRI in emitted RDF, and the prefix carries the\n * tool's name because `…/manni/graph/ns#` is the tool's namespace. Nothing\n * collides: no other prefix in this table is `graph`, and a `graph:` CURIE typed\n * at `--predicates` or `--subject` expanded to nothing before.\n */\nexport const NS = {\n dcterms: \"http://purl.org/dc/terms/\",\n foaf: \"http://xmlns.com/foaf/0.1/\",\n graph: \"https://hawkeyexl.github.io/manni/graph/ns#\",\n iirds: \"http://iirds.tekom.de/iirds#\",\n iirdsSft: \"http://iirds.tekom.de/iirds/domain/software#\",\n prov: \"http://www.w3.org/ns/prov#\",\n rdf: \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\",\n schema: \"https://schema.org/\",\n skos: \"http://www.w3.org/2004/02/skos/core#\",\n xsd: \"http://www.w3.org/2001/XMLSchema#\",\n} as const;\n\nexport type Prefix = keyof typeof NS;\n\n/** Prefixes in emission order (sorted by prefix name). */\nexport const PREFIXES: ReadonlyArray<[Prefix, string]> = (\n Object.entries(NS) as Array<[Prefix, string]>\n).sort(([a], [b]) => (a < b ? -1 : 1));\n\nexport const RDF_TYPE = `${NS.rdf}type`;\n\n/**\n * Role individuals for qualified provenance (prov:hadRole objects). Part of\n * the deliberately small graph vocabulary.\n */\nexport const ROLE = {\n author: `${NS.graph}authorRole`,\n generator: `${NS.graph}generatorRole`,\n tool: `${NS.graph}toolRole`,\n} as const;\n","/**\n * iiRDS Core + Software-domain term IRIs and the frontmatter-value → IRI maps\n * (ADR 01012). Every IRI here is byte-verified against the published\n * `iirds-core.rdf` / `iirds-software.rdf` in iirds-consortium/models. dockg\n * references these IRIs; it never redefines or re-types them (iiRDS is\n * CC BY-ND). This is the single source of truth shared by the schema\n * (via the schema-sync drift guard), derive, and shapes.\n */\nimport { NS } from \"./vocab.js\";\n\n/** Predicates (Core). */\nexport const IIRDS_HAS_TOPIC_TYPE = `${NS.iirds}has-topic-type`;\nexport const IIRDS_RELATES_TO_PRODUCT_VARIANT = `${NS.iirds}relates-to-product-variant`;\nexport const IIRDS_RELATES_TO_LIFECYCLE_PHASE = `${NS.iirds}relates-to-product-lifecycle-phase`;\nexport const IIRDS_HAS_SUBJECT = `${NS.iirds}has-subject`;\n\n/** Class minted for `graph.applies-to` nodes. */\nexport const IIRDS_PRODUCT_VARIANT = `${NS.iirds}ProductVariant`;\n\n/**\n * Package-serialization terms (iiRDS package export, ADR 01017). Local names\n * byte-verified against the canonical RDF/XML example in the published spec\n * (`sections/structure/serialization.md`). Used only by the package projection —\n * never emitted into the built graph. IUs are typed `iirds:Topic` (the subclass\n * that carries `has-topic-type`/`has-subject`), one of the valid IU subclasses.\n */\nexport const IIRDS_PACKAGE = `${NS.iirds}Package`;\nexport const IIRDS_IIRDS_VERSION = `${NS.iirds}iiRDSVersion`;\nexport const IIRDS_TOPIC = `${NS.iirds}Topic`;\nexport const IIRDS_IS_PART_OF_PACKAGE = `${NS.iirds}is-part-of-package`;\nexport const IIRDS_HAS_RENDITION = `${NS.iirds}has-rendition`;\nexport const IIRDS_RENDITION = `${NS.iirds}Rendition`;\nexport const IIRDS_SOURCE = `${NS.iirds}source`;\nexport const IIRDS_FORMAT = `${NS.iirds}format`;\nexport const IIRDS_TITLE = `${NS.iirds}title`;\nexport const IIRDS_LANGUAGE = `${NS.iirds}language`;\nexport const IIRDS_PARTY = `${NS.iirds}Party`;\nexport const IIRDS_HAS_PARTY_ROLE = `${NS.iirds}has-party-role`;\nexport const IIRDS_CREATOR = `${NS.iirds}Creator`;\nexport const IIRDS_RELATES_TO_PARTY = `${NS.iirds}relates-to-party`;\nexport const IIRDS_RELATES_TO_VCARD = `${NS.iirds}relates-to-vcard`;\n\n/** vcard namespace — package-local (not in the global NS/PREFIXES table). */\nexport const VCARD_NS = \"http://www.w3.org/2006/vcard/ns#\";\nexport const VCARD_ORGANIZATION = `${VCARD_NS}Organization`;\nexport const VCARD_ORGANIZATION_NAME = `${VCARD_NS}organization-name`;\n\n/**\n * Negative-scope predicates (ADR 01014). Minted into `graph:` — no standard\n * term exists, and OWL negative property assertions require blank nodes. Each\n * mirrors, and is SHACL-disjoint from, its positive counterpart above.\n */\nexport const GRAPH_NOT_APPLICABLE_TO_VARIANT = `${NS.graph}notApplicableToVariant`;\nexport const GRAPH_NOT_SOFTWARE_SUBJECT = `${NS.graph}notSoftwareSubject`;\n\n/**\n * Page-level `type` → `graph.type` (ADR 01024). The page's `type` is an open\n * vocabulary (docmeta:core); `graph.type` is the closed iiRDS enum. When the block\n * is silent, the page's value derives one through this map — an unmapped page\n * type derives nothing rather than inventing a topic type. An explicit\n * `graph.type` always wins: deeper wins, the page level is the fallback.\n */\nexport const PAGE_TYPE_TO_TOPIC_TYPE: Readonly<Record<string, string>> = {\n \"how-to\": \"task\",\n tutorial: \"learning\",\n explanation: \"concept\",\n reference: \"reference\",\n troubleshooting: \"troubleshooting\",\n};\n\n/** `graph.type` value → `iirds:has-topic-type` object IRI. */\nexport const TOPIC_TYPE_IRIS: Readonly<Record<string, string>> = {\n task: `${NS.iirds}GenericTask`,\n concept: `${NS.iirds}GenericConcept`,\n reference: `${NS.iirds}GenericReference`,\n learning: `${NS.iirds}GenericLearning`,\n troubleshooting: `${NS.iirds}GenericTroubleshooting`,\n form: `${NS.iirds}GenericForm`,\n};\n\n/**\n * `graph.about-product-lifecycle` value → `iirds:relates-to-product-lifecycle-phase`\n * object IRI (Software domain: iirds:Use/PuttingToUse/AfterUse instances).\n */\nexport const SOFTWARE_LIFECYCLE_IRIS: Readonly<Record<string, string>> = {\n administration: `${NS.iirdsSft}Administration`,\n customization: `${NS.iirdsSft}Customization`,\n update: `${NS.iirdsSft}Update`,\n deployment: `${NS.iirdsSft}Deployment`,\n integration: `${NS.iirdsSft}Integration`,\n deinstallation: `${NS.iirdsSft}Deinstallation`,\n};\n\n/**\n * `graph.about-product-aspect` value → `iirds:has-subject` object IRI (Software domain:\n * iirds:TechnicalOverview/TechnicalData instances).\n */\nexport const SOFTWARE_SUBJECT_IRIS: Readonly<Record<string, string>> = {\n architecture: `${NS.iirdsSft}Architecture`,\n interface: `${NS.iirdsSft}Interface`,\n \"system-requirement\": `${NS.iirdsSft}SystemRequirement`,\n};\n","/**\n * Metadata coverage fields (ADR 01011). Coverage answers the ADR 01008\n * question — what can a graph-side consumer see — by counting `graph:Document`\n * nodes that carry each predicate. The list is fixed and deliberate: a\n * predicate absent from every document still shows as 0%, which a dynamic\n * census could not surface. It is shared between the config parser (which\n * expands a uniform threshold across every field) and `manni graph stats` (which\n * reports and gates), and pinned by test/unit/schema-sync.ts against the\n * config schema so it cannot silently drift.\n */\nimport { NS } from \"./vocab.js\";\nimport {\n IIRDS_HAS_SUBJECT,\n IIRDS_HAS_TOPIC_TYPE,\n IIRDS_RELATES_TO_LIFECYCLE_PHASE,\n IIRDS_RELATES_TO_PRODUCT_VARIANT,\n} from \"./iirds.js\";\n\nexport interface CoverageField {\n /** Config/report key. */\n field: string;\n /** Full predicate IRI counted against `graph:Document` subjects. */\n iri: string;\n}\n\n/**\n * Report order is this array's order. Only the IRI is stored; the compact form\n * shown in the report is derived from it with `compactIri`, so there is one\n * source of truth for the namespace.\n */\nexport const COVERAGE_FIELDS: readonly CoverageField[] = [\n { field: \"title\", iri: `${NS.dcterms}title` },\n { field: \"description\", iri: `${NS.dcterms}description` },\n { field: \"creator\", iri: `${NS.dcterms}creator` },\n { field: \"created\", iri: `${NS.dcterms}created` },\n { field: \"modified\", iri: `${NS.dcterms}modified` },\n { field: \"subject\", iri: `${NS.dcterms}subject` },\n { field: \"label\", iri: `${NS.foaf}primaryTopic` },\n // Dropped by ADR 01011 as \"near-universally 0% noise\", which was true on the\n // monolingual corpora it was measured against and false the moment language\n // means something. Restored by ADR 01037, which made it a scope dimension:\n // an unlabelled document in a translated corpus cannot be filtered, indexed\n // per locale, or counted against the right audience.\n { field: \"language\", iri: `${NS.dcterms}language` },\n // The iiRDS typing added in Phases 2–4. Coverage predates all of it, so the\n // measure of \"what a graph-side consumer can see\" was silent about the\n // vocabulary the project spent four phases adding (ADR 01029).\n { field: \"type\", iri: IIRDS_HAS_TOPIC_TYPE },\n { field: \"applies-to\", iri: IIRDS_RELATES_TO_PRODUCT_VARIANT },\n {\n field: \"about-product-lifecycle\",\n iri: IIRDS_RELATES_TO_LIFECYCLE_PHASE,\n },\n { field: \"about-product-aspect\", iri: IIRDS_HAS_SUBJECT },\n];\n\n/**\n * Section-level coverage: the fields a `graph.sections` block can attach\n * (ADR 01013), measured over `graph:Section` nodes.\n *\n * Sections are explicit-only — a section gets exactly what its own block\n * declares and nothing from its document — so these numbers are low by\n * construction on most corpora. That is the point: the granularity golden rule\n * says content granularity must match node granularity, and this is the number\n * that says whether it does.\n *\n * `label` is absent deliberately: ADR 01013 rejected `prefLabel` at section\n * level as meaningless, so it cannot be missing.\n */\n/** Section-attachable field NAMES; the IRIs come from COVERAGE_FIELDS, so a\n * namespace revision cannot move one table and not the other. */\nconst SECTION_FIELD_NAMES: readonly string[] = [\n \"type\",\n \"applies-to\",\n \"about-product-lifecycle\",\n \"about-product-aspect\",\n \"subject\",\n];\n\nexport const SECTION_COVERAGE_FIELDS: readonly CoverageField[] =\n SECTION_FIELD_NAMES.map((name) => {\n const field = COVERAGE_FIELDS.find((f) => f.field === name);\n /* c8 ignore next 3 -- unreachable while the two lists agree, which the\n drift guard in test/unit/schema-sync.test.ts keeps true. */\n if (field === undefined) {\n throw new Error(\n `SECTION_FIELD_NAMES names ${name}, which COVERAGE_FIELDS does not define`,\n );\n }\n return field;\n });\n\n/** The measured field names, in report order. */\nexport const COVERAGE_FIELD_NAMES: readonly string[] = COVERAGE_FIELDS.map(\n (f) => f.field,\n);\n\n/**\n * The two negative predicates (ADR 01014) are deliberately not measured.\n *\n * Coverage answers \"what can a consumer see that the author lifted\". A document\n * with no `not-applicable-to` is not under-annotated — under open-world\n * semantics its absence means *unknown*, which is the normal and correct state\n * for almost every document. Counting it as a gap would put every healthy\n * corpus permanently near zero on two rows and teach readers to ignore the\n * table.\n */\nexport const UNMEASURED_BY_DESIGN: readonly string[] = [\n \"not-applicable-to\",\n \"not-about-product-aspect\",\n];\n","/**\n * The embedder seam (ADR 01020). Platform-neutral and dependency-free, so the\n * runtime and the CLI can both speak it without either pulling in a model.\n *\n * Everything that computes embeddings — the local transformers.js embedder, the\n * deterministic mock, or a host's own — implements `Embedder`.\n */\n\nexport interface Embedder {\n /** Stable identity of the model; recorded in the sidecar header. */\n readonly model: string;\n /** Weight quantization the vectors were produced under. */\n readonly dtype: string;\n /** Output dimensions. Never assumed by callers — always read from here. */\n readonly dims: number;\n /**\n * Embed one text. Single-text rather than batched **on purpose**: float\n * addition is not associative, so a batched vector depends on what it was\n * batched with, and adding one document would perturb its neighbours' vectors\n * (ADR 01020). Determinism is worth more here than throughput.\n */\n embed(text: string): Promise<Float32Array>;\n}\n\n/**\n * A model's quirks, applied on both the build and query sides so a user cannot\n * get them wrong. Some models require a prefix on queries and/or passages and\n * degrade *silently* without it.\n */\nexport interface ModelProfile {\n /** Hugging Face repo id. */\n id: string;\n /** Prepended when embedding a search query. */\n queryPrefix?: string;\n /** Prepended when embedding indexed content. */\n passagePrefix?: string;\n /** Human note surfaced in docs and `--help`. */\n note?: string;\n}\n\n/** What a text is being embedded *for* — decides which prefix applies. */\nexport type EmbedRole = \"query\" | \"passage\";\n\n/**\n * Models dockg has been tested against. This is the *tested* set, not the\n * permitted set: `embed.model` accepts any id, and an unknown one is used\n * as-is with no prefixes.\n */\n/**\n * The default, named rather than found at index 0: `DEFAULT_MODEL` below then\n * reads it directly instead of asserting that the list has a first element.\n */\nconst DEFAULT_PROFILE: ModelProfile = {\n id: \"onnx-community/granite-embedding-small-english-r2-ONNX\",\n note: \"Default. 384-d, 8192-token context so sections are never truncated; no prefixes.\",\n};\n\nexport const MODEL_PROFILES: readonly ModelProfile[] = [\n DEFAULT_PROFILE,\n {\n id: \"Xenova/gte-small\",\n note: \"Lighter (~34 MB). 384-d, 512-token context; no prefixes.\",\n },\n {\n id: \"Xenova/bge-small-en-v1.5\",\n queryPrefix: \"Represent this sentence for searching relevant passages: \",\n note: \"384-d. Needs a query prefix — applied automatically here, since omitting it degrades retrieval silently.\",\n },\n {\n id: \"Xenova/all-MiniLM-L6-v2\",\n note: \"Smallest (~23 MB) but truncates at 256 wordpieces (~190 words), so long sections lose their tail.\",\n },\n];\n\nexport const DEFAULT_MODEL = DEFAULT_PROFILE.id;\n\n/** The profile for a model id, or a bare profile when it is not a tested one. */\nexport function profileFor(id: string): ModelProfile {\n return MODEL_PROFILES.find((p) => p.id === id) ?? { id };\n}\n\n/** Apply the model's prefix convention for the role, if it has one. */\nexport function withPrefix(\n profile: ModelProfile,\n role: EmbedRole,\n text: string,\n): string {\n const prefix = role === \"query\" ? profile.queryPrefix : profile.passagePrefix;\n return prefix ? `${prefix}${text}` : text;\n}\n","/**\n * The ordering primitive behind the determinism contract. Every sort that\n * reaches output — the file list, emitted subjects/predicates/objects, query\n * results — must go through this comparator so ordering never depends on\n * locale, ICU version, or platform, the way `String.prototype.localeCompare`\n * and `Array.prototype.sort`'s default string coercion do.\n */\n\n/** Locale-independent code-unit comparison for stable sorting. */\nexport function byCodeUnit(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lint/core/infer.ts","../src/lint/commands/templates.ts","../src/lint/commands/tools.ts"],"sourcesContent":["/**\n * Write a first template from a page that already has the shape its author\n * wants.\n *\n * The format is strict by default: every rule is one occurrence, and a section\n * no rule describes is a finding. A new author's first run against a\n * hand-written template is therefore a screen of unexpected sections, and this\n * is the escape. Proposal 0061's stress test 5 records it, and says the two\n * ship together.\n *\n * Two rules govern everything here.\n *\n * **The output must lint its input clean.** That is the whole contract, and it\n * is why each inference below is the weakest claim that still describes the\n * page. `contains:` lists only the kinds that are there, at `min: 1`, so a\n * section holding more of something still passes. A table's `columns:` is\n * claimed only where every table in that section agrees about them, and a code\n * block's `language:` only where every block in that section declares one -\n * both rules report per offending node, so a claim drawn from one node would\n * fail on its neighbour. A template that fails the page it was inferred from is\n * worse than no template: it hands a new author findings about the very\n * document they pointed at.\n *\n * **Nothing is optional and nothing repeats.** One page cannot show what\n * varies, so no `min: 0`, no `max`, no `repeat` and no `pattern` is invented.\n * Two sections with one heading are two rules. Loosening a heading into a list\n * or a pattern, marking a rule optional, and adding a trailing wildcard are the\n * author's edits, and the reference page says so.\n */\nimport { stringify as stringifyYaml } from \"yaml\";\nimport { LintError } from \"../types.js\";\nimport type {\n CodeNode,\n ContentKind,\n ContentNode,\n DocumentTree,\n Position,\n SectionNode,\n TableNode,\n} from \"../types.js\";\nimport { BLOCK_KINDS, BLOCK_KIND_NODE } from \"./template.js\";\nimport type {\n BlockKind,\n BlockRule,\n HeadingRule,\n Rule,\n Template,\n TemplateFile,\n} from \"./template.js\";\n\n/** How an inferred template is written out. */\nexport const INFER_FORMATS = [\"yaml\", \"json\"] as const;\nexport type InferFormat = (typeof INFER_FORMATS)[number];\n\nexport function isInferFormat(value: string): value is InferFormat {\n return (INFER_FORMATS as readonly string[]).includes(value);\n}\n\n/**\n * Template names the schema's `templates` map accepts.\n *\n * Checked here rather than left to Ajv. `templates` is `additionalProperties:\n * false` beside a `patternProperties` key, so a name outside the pattern is\n * reported as an unexpected property - which names the offending key and says\n * nothing whatsoever about what is wrong with it.\n */\nconst TEMPLATE_NAME = /^[A-Za-z][A-Za-z0-9\\-_]*$/;\n\n/** The node each block-rule key counts, inverted: `codeBlock` -> `codeBlocks`. */\nconst KIND_KEY = new Map<ContentKind, BlockKind>(\n BLOCK_KINDS.map((key) => [BLOCK_KIND_NODE[key], key]),\n);\n\n/* -------------------------------------------------------------------------- *\n * The page as the template's subject\n * -------------------------------------------------------------------------- */\n\n/** A zero-width span at the top of a file, for a document with no sections. */\nfunction origin(): Position {\n return {\n start: { line: 1, column: 1, offset: 0 },\n end: { line: 1, column: 1, offset: 0 },\n };\n}\n\n/** First section's start through the last one's end. */\nfunction span(sections: SectionNode[]): Position {\n const first = sections[0];\n const last = sections[sections.length - 1];\n if (!first || !last) return origin();\n return { start: { ...first.position.start }, end: { ...last.position.end } };\n}\n\n/**\n * The section the template describes: the page itself.\n *\n * Deliberately the same reading `validator.ts` applies, because the template\n * this produces is checked by that one. A page whose body is a single `# Title`\n * *is* that section; anything else - several top-level headings, or a body that\n * starts at `##` with no lead content - has no section standing for the page,\n * so one is synthesised with no heading of its own. The duplication is small\n * and the alternative is worse: an inference that read the page differently\n * from the checker would produce templates that fail their own source.\n */\nfunction pageSection(tree: DocumentTree): SectionNode {\n const [only] = tree.sections;\n if (tree.sections.length === 1 && only && only.level <= 1) return only;\n return {\n slug: \"\",\n title: \"\",\n level: 0,\n order: 0,\n parentSlug: null,\n titlePosition: null,\n position: span(tree.sections),\n children: [],\n sections: tree.sections,\n };\n}\n\n/* -------------------------------------------------------------------------- *\n * Content\n * -------------------------------------------------------------------------- */\n\n/** The header row's cells, in order, or none where the table has no header. */\nfunction headerCells(table: TableNode): string[] {\n const header = table.children.find((row) => row.header);\n return header ? header.children.map((cell) => cell.text) : [];\n}\n\n/**\n * `columns:` for a run of tables, where they all agree about it.\n *\n * `tables.columns` reports once per table whose header differs, so a claim\n * taken from the first of two unlike tables fails on the second - in the very\n * page it was drawn from. Where the tables disagree, or any of them has no\n * header row, the count alone is what the page can honestly be said to show.\n */\nfunction columnsOf(tables: TableNode[]): { columns?: string[] } {\n const headers = tables.map(headerCells);\n const [first] = headers;\n if (first === undefined || first.length === 0) return {};\n const same = (cells: string[]): boolean =>\n cells.length === first.length && cells.every((c, i) => c === first[i]);\n return headers.every(same) ? { columns: [...first] } : {};\n}\n\n/**\n * `language:` for a run of code blocks, where every one of them declares one.\n *\n * `codeBlocks.language` holds every block in the run to the accepted set, so a\n * section mixing a tagged fence with a bare one can claim nothing: the bare one\n * would fail. Where the tags differ the list form says what the page shows,\n * which is what \"one of these\" is for.\n */\nfunction languageOf(blocks: CodeNode[]): { language?: string | string[] } {\n const declared: string[] = [];\n for (const block of blocks) {\n if (block.language === undefined || block.language.length === 0) return {};\n declared.push(block.language);\n }\n const distinct = [...new Set(declared)];\n const [only] = distinct;\n if (only === undefined) return {};\n return { language: distinct.length === 1 ? only : distinct };\n}\n\n/**\n * What a section holds, as a `contains:` rule, or nothing where it holds none\n * of the kinds a template can count.\n *\n * `contains` rather than `sequence`: the page shows one order, and asserting it\n * would make moving a paragraph below a list a finding. Order is a claim its\n * author makes deliberately.\n */\nfunction inferContains(children: ContentNode[]): BlockRule | undefined {\n const byKey = new Map<BlockKind, ContentNode[]>();\n for (const node of children) {\n const key = KIND_KEY.get(node.kind);\n if (key === undefined) continue;\n const bucket = byKey.get(key);\n if (bucket) bucket.push(node);\n else byKey.set(key, [node]);\n }\n\n const rule: BlockRule = {};\n let any = false;\n // In `BLOCK_KINDS` order, not the order the page happens to put them in, so\n // two pages holding the same kinds produce byte-identical rules.\n for (const key of BLOCK_KINDS) {\n const nodes = byKey.get(key);\n if (nodes === undefined) continue;\n any = true;\n if (key === \"tables\") {\n rule.tables = { min: 1, ...columnsOf(nodes as TableNode[]) };\n } else if (key === \"codeBlocks\") {\n rule.codeBlocks = { min: 1, ...languageOf(nodes as CodeNode[]) };\n } else {\n // A computed key, as `validator.ts` does it: every other block rule is a\n // bare count, and nine near-identical branches would say less.\n Object.assign(rule, { [key]: { min: 1 } });\n }\n }\n return any ? rule : undefined;\n}\n\n/* -------------------------------------------------------------------------- *\n * Rules\n * -------------------------------------------------------------------------- */\n\n/**\n * A section's heading, as a rule about it.\n *\n * Exact text, because that is what the page shows; a one-of list or a pattern\n * is a generalisation only its author can make. `false` for a section with no\n * heading of its own - the implicit lead section, and the synthesised page -\n * because that is as specific a claim as naming one.\n *\n * An empty title is the one case with no spelling: the schema's `heading`\n * requires a non-empty string, and `false` would be a lie about a section that\n * does have a heading. The key is omitted, which matches any heading.\n */\nfunction inferHeading(section: SectionNode): HeadingRule | undefined {\n if (section.titlePosition === null) return false;\n return section.title.length > 0 ? section.title : undefined;\n}\n\n/** One section, and every section under it. */\nfunction inferRule(section: SectionNode): Rule {\n const rule: Rule = {};\n const heading = inferHeading(section);\n if (heading !== undefined) rule.heading = heading;\n const contains = inferContains(section.children);\n if (contains) rule.contains = contains;\n // Omitted, never `[]`. An absent `sections:` says nothing about the\n // subsections; an empty list says none are permitted.\n if (section.sections.length > 0) {\n rule.sections = section.sections.map(inferRule);\n }\n return rule;\n}\n\n/** The template one page describes: the page rule, with its sections under it. */\nexport function inferTemplate(tree: DocumentTree): Template {\n return inferRule(pageSection(tree));\n}\n\n/* -------------------------------------------------------------------------- *\n * The file\n * -------------------------------------------------------------------------- */\n\n/** Refuse a name the `templates` map cannot hold, in words that name the rule. */\nexport function assertTemplateName(name: string): string {\n if (TEMPLATE_NAME.test(name)) return name;\n throw new LintError(\n `\"${name}\" is not a usable template name. A name starts with a letter and ` +\n `holds only letters, digits, \"-\" and \"_\". Pass --name <name>.`,\n );\n}\n\n/** A one-template file, ready to serialize. */\nexport function inferTemplateFile(\n tree: DocumentTree,\n name: string,\n): TemplateFile {\n return { templates: { [assertTemplateName(name)]: inferTemplate(tree) } };\n}\n\n/**\n * Serialize a template file.\n *\n * `lineWidth: 0` turns off YAML's folding. A folded heading still parses back\n * to the same string, but a template is read and edited by hand, and a heading\n * broken across two lines is the one thing in this output a reader would\n * mistrust.\n */\nexport function renderTemplateFile(\n file: TemplateFile,\n format: InferFormat,\n): string {\n const text =\n format === \"json\"\n ? JSON.stringify(file, null, 2)\n : stringifyYaml(file, { lineWidth: 0 });\n return text.endsWith(\"\\n\") ? text : `${text}\\n`;\n}\n","/**\n * `templates` command cores.\n *\n * `runTemplates` reports the templates a run could resolve: the built-ins, plus\n * the named templates in any files given by `--templates` or by\n * `lint.templates` in the config, with the doctypes each serves.\n *\n * The `types` column is the part worth printing. It is what frontmatter\n * routing will match a page against, so seeing it is how someone works out\n * which `type:` value to write in a page - or that no template claims the one\n * they already wrote.\n *\n * `runTemplatesInfer` writes a first template from a page that already has the\n * shape its author wants. The inference itself is `../core/infer.ts`; what\n * lives here is the plumbing around it - which parser reads the page, what the\n * template is called, and where the file goes.\n *\n * Both return data; `src/lint/reporters/index.ts` renders the listing, and an\n * inferred template is already the text it will be written as.\n */\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile } from \"node:fs/promises\";\nimport { basename, dirname, extname, resolve } from \"node:path\";\nimport { errorMessage, ToolError } from \"../../shared/errors.js\";\nimport { writeTextAtomic } from \"../../shared/write-file.js\";\nimport { LintError } from \"../types.js\";\nimport type { DocumentParser, DocumentTree } from \"../types.js\";\nimport {\n parserByName,\n parserForExtension,\n supportedExtensions,\n} from \"../parsers/index.js\";\nimport {\n assertTemplateName,\n inferTemplateFile,\n isInferFormat,\n renderTemplateFile,\n type InferFormat,\n} from \"../core/infer.js\";\nimport type { TemplateFile } from \"../core/template.js\";\nimport { resolveLintRun } from \"../core/config.js\";\nimport {\n listBuiltins,\n loadTemplateFile,\n} from \"../core/template-registry.js\";\n\n/** `TemplateInfo.source` for a template that ships with the tool. */\nexport const BUILTIN_SOURCE = \"builtin\";\n\nexport interface TemplateInfo {\n /** The ref to pass to `--template`. */\n id: string;\n /**\n * Human-readable title. Empty for templates read from a user file: the\n * template DSL has no title field, only the built-in registry carries one.\n */\n title: string;\n /** Doctypes the template serves, matched against a page `type`. */\n types: string[];\n /** `builtin`, or the template file this entry came from. */\n source: string;\n}\n\nexport interface TemplatesInfo {\n templates: TemplateInfo[];\n}\n\nexport interface TemplatesOptions {\n /** Template files whose entries join the built-ins. */\n templates?: string | string[];\n}\n\nexport async function runTemplates(\n opts: TemplatesOptions = {},\n): Promise<TemplatesInfo> {\n const templates: TemplateInfo[] = listBuiltins().map((builtin) => ({\n id: builtin.id,\n title: builtin.title,\n types: builtin.types,\n source: BUILTIN_SOURCE,\n }));\n\n // Listed after the built-ins, in the order supplied - the same order\n // `buildTypeIndex` applies them in, so a later entry claiming the same\n // doctype is the one that would win.\n const paths =\n opts.templates == null\n ? []\n : Array.isArray(opts.templates)\n ? opts.templates\n : [opts.templates];\n\n for (const path of paths) {\n const file = await loadTemplateFile(path);\n for (const [id, template] of Object.entries(file.templates ?? {})) {\n templates.push({\n id,\n title: \"\",\n types: template.types ?? [],\n source: path,\n });\n }\n }\n\n return { templates };\n}\n\n/* -------------------------------------------------------------------------- *\n * infer\n * -------------------------------------------------------------------------- */\n\n/** The token that means stdin, in every command of the family. */\nconst STDIN = \"-\";\n\n/** What a page read from stdin is called when nothing else names it. */\nconst STDIN_NAME = \"stdin\";\n\nexport interface TemplatesInferOptions {\n /** The one page to infer from: a path, or `-` for stdin. */\n page: string;\n /** `--as`: force an input format, by parser name. */\n as?: string;\n /** `--name`: what to call the template. Defaults to the page's own doctype. */\n name?: string;\n /** `-f/--format`: how the file is written. Defaults to `yaml`. */\n format?: InferFormat;\n /** `-o/--out`: write here instead of returning text for stdout. */\n out?: string;\n /** `--force`: replace an existing `--out`. */\n force?: boolean;\n cwd?: string;\n /** Content for the `-` page, injected by the CLI and by tests. */\n stdinContent?: string;\n /** `-c/--config`. */\n configPath?: string;\n /** `--no-config`: skip discovery. */\n noConfig?: boolean;\n /** Told which config governed the run, and where it came from. */\n onConfigLoaded?: (info: { path: string; dir: string }) => void;\n}\n\nexport interface TemplatesInferResult {\n /** The name the template was written under. */\n name: string;\n /** The inferred file, for a caller that wants the data rather than the text. */\n file: TemplateFile;\n /** The serialized template file, exactly as written. */\n text: string;\n /** Where it was written. Absent without `--out`. */\n written?: string;\n}\n\n/**\n * The parser that reads this page.\n *\n * Resolved before anything is read, as `runLint` does it: a typo in `--as`\n * should fail immediately rather than after a file was opened it was going to\n * mis-parse anyway. A name no parser answers to is unknown whatever it was\n * meant to name, so the message points at the one command that lists them.\n */\nfunction parserFor(page: string, as: string | undefined): DocumentParser {\n if (as !== undefined) {\n const forced = parserByName(as);\n if (forced) return forced;\n throw new LintError(\n `Unknown format \"${as}\". Run \"manni lint tools\" to see the formats manni lint reads.`,\n );\n }\n if (page === STDIN) {\n throw new LintError(\n \"Reading from stdin (-) requires --as <format> to choose a parser.\",\n );\n }\n const ext = extname(page);\n const parser = parserForExtension(ext);\n if (parser) return parser;\n throw new LintError(\n `no parser is registered for \"${ext || page}\". Supported extensions: ` +\n `${supportedExtensions().join(\", \")}. Use --as to override.`,\n );\n}\n\n/**\n * What the template is called: `--name`, else the page's own doctype, else the\n * file's stem.\n *\n * The doctype first because that is the handle the page already carries, and\n * the one `types:` will route on once the author adds it. A file read from\n * stdin has no stem, so it falls back to a word rather than to `-`.\n */\nfunction defaultName(tree: DocumentTree, page: string): string {\n const declared = tree.frontmatter?.[\"type\"];\n if (typeof declared === \"string\" && declared.trim().length > 0) {\n return declared.trim();\n }\n if (page === STDIN) return STDIN_NAME;\n return basename(page, extname(page)) || STDIN_NAME;\n}\n\n/**\n * Infer a template from one page.\n *\n * One page, never a set. A template is a generalisation, and this makes exactly\n * the generalisation one exemplar supports; inferring from several would mean\n * deciding which differences are variation and which are mistakes, which is the\n * author's judgment and not the tool's.\n */\nexport async function runTemplatesInfer(\n opts: TemplatesInferOptions,\n): Promise<TemplatesInferResult> {\n const format = opts.format ?? \"yaml\";\n if (!isInferFormat(format)) {\n throw new LintError(\n `Unknown --format \"${String(format)}\". Use yaml or json.`,\n );\n }\n\n // Which config governs the run, said once, the way every other lint verb\n // says it. With a page typed on the command line the base stays the working\n // directory, so the path means what it looked like it meant.\n const run = await resolveLintRun({\n cwd: opts.cwd ?? process.cwd(),\n ...(opts.configPath === undefined ? {} : { configPath: opts.configPath }),\n ...(opts.noConfig === undefined ? {} : { noConfig: opts.noConfig }),\n inputs: [opts.page],\n ...(opts.onConfigLoaded === undefined\n ? {}\n : { onConfigLoaded: opts.onConfigLoaded }),\n });\n const cwd = run.base;\n\n const parser = parserFor(opts.page, opts.as);\n // A name the schema cannot hold is refused before the page is read, beside\n // the other refusals: a run that is going to fail should leave the working\n // tree, and the reader's terminal, exactly as it found them.\n if (opts.name !== undefined) assertTemplateName(opts.name);\n\n // Every refusal happens before the write, and the `--out` guard happens\n // before the read - the ordering `meta schemas infer` established. The path\n // is echoed as it was typed, because that is the string the reader will edit.\n let absOut: string | undefined;\n if (opts.out !== undefined) {\n absOut = resolve(cwd, opts.out);\n if (opts.force !== true && existsSync(absOut)) {\n throw new LintError(`${opts.out} exists. Pass --force to overwrite it.`);\n }\n }\n\n let content: string;\n if (opts.page === STDIN) {\n content = opts.stdinContent ?? \"\";\n } else {\n try {\n content = await readFile(resolve(cwd, opts.page), \"utf8\");\n } catch (err) {\n // The OS message travels verbatim: \"permission denied\" and \"no such\n // file\" send the reader to different places, and this cannot tell which.\n throw new LintError(\n `\"${opts.page}\" could not be read: ${errorMessage(err)}`,\n );\n }\n }\n\n let tree: DocumentTree;\n try {\n tree = parser.parse(content, opts.page === STDIN ? \"<stdin>\" : opts.page);\n } catch (err) {\n // A page that will not parse has no shape to infer, and the parser's own\n // message already names the file and the syntax it choked on.\n if (err instanceof ToolError) throw new LintError(err.message);\n throw err;\n }\n\n const name = opts.name ?? defaultName(tree, opts.page);\n const file = inferTemplateFile(tree, name);\n const text = renderTemplateFile(file, format);\n\n if (absOut === undefined) return { name, file, text };\n\n await mkdir(dirname(absOut), { recursive: true });\n await writeTextAtomic(absOut, text);\n return { name, file, text, written: opts.out };\n}\n","/**\n * `tools` command core. One row per lint job: which tool performs it, whether\n * this checkout can run it, what it read its settings from, and the input\n * formats it understands.\n *\n * It replaces `formats`, which reported the parser registry alone. Proposal\n * 0050 records the rename. The registry is here as one column of the job that\n * reads it, because the formats belong to the tool performing that job.\n *\n * The column lists exactly the formats the tool reads, so a row carries no\n * state: a listed format is one that is read, and `--as` accepts every name in\n * it.\n *\n * Returns data; `src/lint/reporters/index.ts` renders it.\n */\nimport type { ContentKind } from \"../types.js\";\nimport { BLOCK_KIND_NODE } from \"../core/template.js\";\nimport { resolveStructureTool } from \"../tools/index.js\";\nimport {\n LINT_JOBS,\n resolveLintRun,\n type LintConfig,\n type LintJob,\n type LintTool,\n} from \"../core/config.js\";\n\n/**\n * The content kinds a template rule can actually name - `BLOCK_KIND_NODE`'s\n * values, the nine block-rule keys map onto. `manni lint tools` lists this\n * column to answer \"can my rule run against this format\", and a rule can\n * never ask about `listItem`, `tableRow`, `tableCell`, or `definitionItem`:\n * those are structural kinds a parser reports so the content model can\n * describe a list's items or a table's cells, not kinds a `sections:` rule\n * counts on its own. What a parser *declares* (`DocumentParser.kinds`, read by\n * the pruner in `validator.ts`) is untouched - this is a display decision, so\n * it belongs here rather than trimming the declaration itself.\n */\nconst REPORTABLE_KINDS = new Set<ContentKind>(Object.values(BLOCK_KIND_NODE));\n\nexport interface FormatInfo {\n /** Parser name, also what `--as` accepts. */\n name: string;\n label: string;\n extensions: string[];\n /** The content kinds this format's parser actually emits today. */\n kinds: ContentKind[];\n}\n\n/** One job, and the tool that would perform it on this run. */\nexport interface ToolInfo {\n job: LintJob;\n tool: LintTool;\n /** Whether the config declares this job, or anything the job's tool reads. */\n configured: boolean;\n /** Whether the tool can run here, as its own probe reported it. */\n available: boolean;\n /**\n * The version the probe reported, or null when it reported none.\n *\n * Null rather than a placeholder string, because this is the shape\n * `-f json` emits: a consumer can test for an absent version, where a dash\n * would be a value it has to know to recognize. The pretty reporter renders\n * the dash.\n */\n version: string | null;\n /** Where the tool read its settings: the config file, or the defaults. */\n config: string;\n /** The input formats the tool reads. */\n formats: FormatInfo[];\n}\n\nexport interface ToolsOptions {\n cwd?: string;\n /** `-c/--config`. */\n configPath?: string;\n /** `--no-config`: ignore any discovered config file. */\n noConfig?: boolean;\n}\n\n/** What a run with no config file to read reports in the `config` column. */\nexport const BUILT_IN_DEFAULTS = \"built-in defaults\";\n\n/**\n * Whether the config says anything about this job.\n *\n * The job's own mapping counts, and so does every key its tool reads: a repo\n * that has written `templates:` and `overrides:` has configured the structure\n * job whether or not it also spelled `structure:` out. Saying otherwise would\n * report \"not configured\" beside a run those keys visibly govern.\n */\nfunction isConfigured(job: LintJob, config: LintConfig): boolean {\n if (config[job] !== undefined) return true;\n return (\n config.templates !== undefined ||\n config.template !== undefined ||\n config.types !== undefined ||\n config.overrides !== undefined\n );\n}\n\nexport async function runTools(opts: ToolsOptions = {}): Promise<ToolInfo[]> {\n // The same resolution every other command does, so a config this command\n // cannot read is the same exit 2 with the same message, rather than a row\n // saying \"built-in defaults\" over a file that is really there and broken.\n const cwd = opts.cwd ?? process.cwd();\n const run = await resolveLintRun({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: [],\n });\n\n return await Promise.all(\n LINT_JOBS.map(async (job) => {\n const tool: LintTool = run.config[job]?.tool ?? \"manni\";\n // The row is the tool's own answer about itself. It used to be two\n // literals that happened to be right while manni was the only tool:\n // \"available\" was hard-coded true, and the version was this package's\n // whatever performed the job.\n const descriptor = resolveStructureTool(tool);\n // The family's `tools:` travels with the probe: a tool outside the\n // package is found where its own `tools.<tool>` says it is, so probing\n // without it would report \"not available\" over the very installation the\n // run would go on to use.\n const probed = await descriptor.probe({\n cwd,\n tools: run.tools,\n ...(run.configDir === undefined ? {} : { configDir: run.configDir }),\n });\n return {\n job,\n tool,\n configured: isConfigured(job, run.config),\n available: probed.available,\n version: probed.version,\n config: run.configSource ?? BUILT_IN_DEFAULTS,\n formats: descriptor.formats().map((format) => ({\n ...format,\n kinds: format.kinds.filter((kind) => REPORTABLE_KINDS.has(kind)),\n })),\n };\n }),\n );\n}\n"],"mappings":"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","names":[]}
|