@agentshouse/mdmodel 0.1.0-alpha.17 → 0.1.0-alpha.19

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.
Files changed (59) hide show
  1. package/API.md +13 -11
  2. package/dist/links.d.ts.map +1 -1
  3. package/dist/links.js +529 -148
  4. package/dist/links.js.map +1 -1
  5. package/dist/project.d.ts.map +1 -1
  6. package/dist/project.js +10 -2
  7. package/dist/project.js.map +1 -1
  8. package/dist/schema.d.ts +2 -1
  9. package/dist/schema.d.ts.map +1 -1
  10. package/dist/schema.js +5 -0
  11. package/dist/schema.js.map +1 -1
  12. package/dist/sections.d.ts +2 -1
  13. package/dist/sections.d.ts.map +1 -1
  14. package/dist/sections.js +33 -15
  15. package/dist/sections.js.map +1 -1
  16. package/dist/validate.d.ts.map +1 -1
  17. package/dist/validate.js +49 -22
  18. package/dist/validate.js.map +1 -1
  19. package/dist/version.d.ts +1 -1
  20. package/dist/version.js +1 -1
  21. package/dist/version.js.map +1 -1
  22. package/dist/yaml.d.ts +1 -0
  23. package/dist/yaml.d.ts.map +1 -1
  24. package/dist/yaml.js +1 -1
  25. package/dist/yaml.js.map +1 -1
  26. package/fixtures/README.md +11 -5
  27. package/fixtures/cases/section-item-enum/context.json +1 -0
  28. package/fixtures/cases/section-item-enum/expected.json +7 -0
  29. package/fixtures/cases/section-item-enum/library/task.md +8 -0
  30. package/fixtures/cases/section-item-enum/schema.yaml +4 -0
  31. package/fixtures/cases/section-item-kind/context.json +1 -0
  32. package/fixtures/cases/section-item-kind/expected.json +7 -0
  33. package/fixtures/cases/section-item-kind/library/task.md +8 -0
  34. package/fixtures/cases/section-item-kind/schema.yaml +4 -0
  35. package/fixtures/cases/section-items/context.json +1 -0
  36. package/fixtures/cases/section-items/expected.json +1 -0
  37. package/fixtures/cases/section-items/library/other.md +3 -0
  38. package/fixtures/cases/section-items/library/page.md +28 -0
  39. package/fixtures/cases/section-items/schema.yaml +8 -0
  40. package/fixtures/cases/section-reference-path/context.json +1 -0
  41. package/fixtures/cases/section-reference-path/expected.json +7 -0
  42. package/fixtures/cases/section-reference-path/library/other.md +3 -0
  43. package/fixtures/cases/section-reference-path/library/page.md +7 -0
  44. package/fixtures/cases/section-reference-path/schema.yaml +4 -0
  45. package/fixtures/cases/section-reference-type/context.json +1 -0
  46. package/fixtures/cases/section-reference-type/expected.json +7 -0
  47. package/fixtures/cases/section-reference-type/library/note.md +1 -0
  48. package/fixtures/cases/section-reference-type/library/page.md +7 -0
  49. package/fixtures/cases/section-reference-type/schema.yaml +4 -0
  50. package/fixtures/cases/shortcut-reference-link/context.json +1 -0
  51. package/fixtures/cases/shortcut-reference-link/expected.json +6 -0
  52. package/fixtures/cases/shortcut-reference-link/library/item.md +10 -0
  53. package/fixtures/cases/shortcut-reference-link/schema.yaml +6 -0
  54. package/fixtures/cases/text-field-kind/context.json +1 -0
  55. package/fixtures/cases/text-field-kind/expected.json +7 -0
  56. package/fixtures/cases/text-field-kind/library/page.md +4 -0
  57. package/fixtures/cases/text-field-kind/schema.yaml +4 -0
  58. package/fixtures/projection.json +61 -0
  59. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdmodel/src/validate.ts"],"sourcesContent":["import { readSchema, type Definition, type FieldSpec } from './definition.js';\nimport { parse } from './document.js';\nimport { hrefOccurrences } from './links.js';\nimport { classifyHref } from './paths.js';\nimport { refusal } from './refuse.js';\nimport { parseListSection } from './sections.js';\nimport { validateFields } from './schema.js';\nimport type {\n Document,\n Library,\n ModelVerification,\n Validation,\n ValidationContext,\n VerifiedModel,\n} from './types.js';\nimport { VERSION } from './version.js';\nimport { bodyAfterFrontmatter } from './yaml.js';\n\nconst MEMBER_FIELD = 'member';\n\nconst MEMBER_SPEC: FieldSpec = { kind: 'string', required: false };\n\nfunction refuse(\n file: string,\n rule: string,\n extra?: { location?: string; referrers?: readonly string[] },\n): Validation {\n return { verdict: 'refuse', ...refusal(file, rule, extra) };\n}\n\nfunction instanceType(document: Document): string | null {\n const raw = document.fields.type;\n if (raw === undefined || raw === null) return 'any';\n if (typeof raw !== 'string' || raw === '') return null;\n return raw;\n}\n\nfunction referenceTargets(spec: FieldSpec, value: unknown): string[] {\n if (spec.kind === 'reference' && typeof value === 'string') return [value];\n if (spec.kind === 'list' && spec.of.kind === 'reference' && Array.isArray(value)) {\n return value.filter((item): item is string => typeof item === 'string');\n }\n return [];\n}\n\nfunction expectedReferenceType(spec: FieldSpec): string | null {\n if (spec.kind === 'reference') return spec.to;\n if (spec.kind === 'list' && spec.of.kind === 'reference') return spec.of.to;\n return null;\n}\n\nfunction declaredTypeOf(content: string): string | undefined {\n const parsed = parse(content);\n if (!parsed.ok) return undefined;\n return parsed.document.type ?? 'any';\n}\n\nexport function verify(schema: string): ModelVerification {\n const read = readSchema(schema);\n if ('types' in read) return { verdict: 'accept', model: read };\n return {\n verdict: 'refuse',\n rule: read.rule,\n version: VERSION,\n ...(read.location === undefined ? {} : { location: read.location }),\n };\n}\n\nfunction declaredFields(definition: Definition): Readonly<Record<string, FieldSpec>> {\n if (!definition.memberDocument || Object.hasOwn(definition.fields, MEMBER_FIELD))\n return definition.fields;\n return { ...definition.fields, [MEMBER_FIELD]: MEMBER_SPEC };\n}\n\nexport function validate(\n library: Library,\n context: ValidationContext = { binaryTargets: [] },\n model: VerifiedModel = { types: {} },\n): Validation {\n const binaryTargets = new Set(context.binaryTargets);\n const files = Object.keys(library).sort();\n const documents = new Map<string, ReturnType<typeof parse>>();\n for (const file of files) {\n if (binaryTargets.has(file)) return refuse(file, 'binary-target-document');\n const parsed = parse(library[file]!, file);\n documents.set(file, parsed);\n if (!parsed.ok) return { verdict: 'refuse', ...parsed.refusal };\n }\n\n const definitions = new Map(Object.entries(model.types));\n\n for (const file of files) {\n const parsed = documents.get(file);\n if (parsed === undefined || !parsed.ok) continue;\n const kind = instanceType(parsed.document);\n if (kind === 'any') continue;\n const definition = kind === null ? undefined : definitions.get(kind);\n if (definition === undefined) return refuse(file, 'unknown-type', { location: 'type' });\n const fields = declaredFields(definition);\n const fieldFailure = validateFields(fields, parsed.document.fields);\n if (fieldFailure !== undefined) {\n return refuse(file, fieldFailure.rule, { location: fieldFailure.field });\n }\n const declared = new Set(Object.keys(fields));\n const undeclared = Object.keys(parsed.document.fields).find(\n (name) => !['type', 'site', 'received'].includes(name) && !declared.has(name),\n );\n if (undeclared !== undefined) return refuse(file, 'undeclared-field', { location: undeclared });\n for (const [name, spec] of Object.entries(definition.sections)) {\n const body = parsed.document.sections[name];\n if (body === undefined) {\n if (spec.required) return refuse(file, 'required-section', { location: name });\n continue;\n }\n if (spec.kind === 'list' && !parseListSection(body)) {\n return refuse(file, 'structured-section', { location: name });\n }\n }\n }\n\n for (const file of files) {\n const parsed = documents.get(file);\n if (parsed === undefined || !parsed.ok) continue;\n const kind = instanceType(parsed.document);\n if (kind === null || kind === 'any') continue;\n const definition = definitions.get(kind);\n if (definition === undefined) continue;\n for (const [name, spec] of Object.entries(definition.fields)) {\n const targets = referenceTargets(spec, parsed.document.fields[name]);\n const expected = expectedReferenceType(spec);\n if (expected === null) continue;\n for (const target of targets) {\n const resolved = classifyHref(file, target);\n if (resolved.kind !== 'path' || binaryTargets.has(resolved.path))\n return refuse(file, 'unresolved-reference', { location: name });\n if (!documents.has(resolved.path)) continue;\n const targetType = declaredTypeOf(library[resolved.path]!);\n if (targetType !== expected)\n return refuse(file, 'unresolved-reference', { location: name });\n }\n }\n const body = bodyAfterFrontmatter(library[file]!);\n for (const occurrence of hrefOccurrences(body)) {\n const resolved = classifyHref(file, occurrence.href);\n if (resolved.kind === 'skip') continue;\n if (\n resolved.kind === 'invalid' ||\n (!documents.has(resolved.path) && !binaryTargets.has(resolved.path))\n ) {\n return refuse(file, 'unresolved-link');\n }\n }\n }\n\n const missing = new Map<string, string[]>();\n for (const file of files) {\n const parsed = documents.get(file);\n if (parsed === undefined || !parsed.ok) continue;\n const kind = instanceType(parsed.document);\n if (kind === null || kind === 'any') continue;\n const definition = definitions.get(kind);\n if (definition === undefined) continue;\n for (const [name, spec] of Object.entries(definition.fields)) {\n const expected = expectedReferenceType(spec);\n if (expected === null) continue;\n for (const target of referenceTargets(spec, parsed.document.fields[name])) {\n const resolved = classifyHref(file, target);\n if (resolved.kind !== 'path') continue;\n if (documents.has(resolved.path)) continue;\n const referrers = missing.get(resolved.path) ?? [];\n referrers.push(file);\n missing.set(resolved.path, referrers);\n }\n }\n }\n const missingPaths = [...missing.keys()].sort();\n if (missingPaths.length > 0) {\n const path = missingPaths[0]!;\n const referrers = [...new Set(missing.get(path) ?? [])].sort();\n return refuse(path, 'referenced-missing-file', { referrers });\n }\n\n return { verdict: 'accept' };\n}\n"],"names":["readSchema","parse","hrefOccurrences","classifyHref","refusal","parseListSection","validateFields","VERSION","bodyAfterFrontmatter","MEMBER_FIELD","MEMBER_SPEC","kind","required","refuse","file","rule","extra","verdict","instanceType","document","raw","fields","type","undefined","referenceTargets","spec","value","of","Array","isArray","filter","item","expectedReferenceType","to","declaredTypeOf","content","parsed","ok","verify","schema","read","model","version","location","declaredFields","definition","memberDocument","Object","hasOwn","validate","library","context","binaryTargets","types","Set","files","keys","sort","documents","Map","has","set","definitions","entries","get","fieldFailure","field","declared","undeclared","find","name","includes","sections","body","targets","expected","target","resolved","path","targetType","occurrence","href","missing","referrers","push","missingPaths","length"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdmodel/src/validate.ts"],"sourcesContent":["import { readSchema, type Definition, type FieldSpec } from './definition.js';\nimport { parse } from './document.js';\nimport { hrefOccurrences, linkInventory } from './links.js';\nimport { classifyHref } from './paths.js';\nimport { refusal } from './refuse.js';\nimport { fitsKind, validateFields } from './schema.js';\nimport { headingSpans, listItems } from './sections.js';\nimport type {\n Document,\n Extent,\n Library,\n ModelVerification,\n ParseResult,\n Validation,\n ValidationContext,\n VerifiedModel,\n} from './types.js';\nimport { VERSION } from './version.js';\nimport { bodyAfterFrontmatter, bodyStartOf } from './yaml.js';\n\ntype SectionReferences = {\n readonly section: string;\n readonly to: string;\n readonly hrefs: readonly string[];\n};\n\nconst MEMBER_FIELD = 'member';\n\nconst MEMBER_SPEC: FieldSpec = { kind: 'string', required: false };\n\nfunction refuse(\n file: string,\n rule: string,\n extra?: { location?: string; referrers?: readonly string[] },\n): Validation {\n return { verdict: 'refuse', ...refusal(file, rule, extra) };\n}\n\nfunction instanceType(document: Document): string | null {\n const raw = document.fields.type;\n if (raw === undefined || raw === null) return 'any';\n if (typeof raw !== 'string' || raw === '') return null;\n return raw;\n}\n\nfunction referenceTargets(spec: FieldSpec, value: unknown): string[] {\n if (spec.kind === 'reference' && typeof value === 'string') return [value];\n if (spec.kind === 'list' && spec.of.kind === 'reference' && Array.isArray(value)) {\n return value.filter((item): item is string => typeof item === 'string');\n }\n return [];\n}\n\nfunction expectedReferenceType(spec: FieldSpec): string | null {\n if (spec.kind === 'reference') return spec.to;\n if (spec.kind === 'list' && spec.of.kind === 'reference') return spec.of.to;\n return null;\n}\n\nfunction reaches(\n file: string,\n href: string,\n to: string,\n documents: ReadonlyMap<string, ParseResult>,\n binaryTargets: ReadonlySet<string>,\n): boolean {\n const resolved = classifyHref(file, href);\n if (resolved.kind !== 'path' || binaryTargets.has(resolved.path)) return false;\n const held = documents.get(resolved.path);\n return held === undefined || (held.ok && (held.document.type ?? 'any') === to);\n}\n\nfunction itemHrefs(content: string, items: readonly Extent[]): string[] | null {\n const bodyStart = bodyStartOf(content);\n const { uses } = linkInventory(content.slice(bodyStart));\n const hrefs: string[] = [];\n for (const item of items) {\n const link = uses.find(\n (use) =>\n bodyStart + use.start === item.start &&\n bodyStart + use.end === item.end &&\n content[item.start] === '[',\n );\n if (link === undefined) return null;\n hrefs.push(link.destination.href);\n }\n return hrefs;\n}\n\nexport function verify(schema: string): ModelVerification {\n const read = readSchema(schema);\n if ('types' in read) return { verdict: 'accept', model: read };\n return {\n verdict: 'refuse',\n rule: read.rule,\n version: VERSION,\n ...(read.location === undefined ? {} : { location: read.location }),\n };\n}\n\nfunction declaredFields(definition: Definition): Readonly<Record<string, FieldSpec>> {\n if (!definition.memberDocument || Object.hasOwn(definition.fields, MEMBER_FIELD))\n return definition.fields;\n return { ...definition.fields, [MEMBER_FIELD]: MEMBER_SPEC };\n}\n\nexport function validate(\n library: Library,\n context: ValidationContext = { binaryTargets: [] },\n model: VerifiedModel = { types: {} },\n): Validation {\n const binaryTargets = new Set(context.binaryTargets);\n const files = Object.keys(library).sort();\n const documents = new Map<string, ParseResult>();\n for (const file of files) {\n if (binaryTargets.has(file)) return refuse(file, 'binary-target-document');\n const parsed = parse(library[file]!, file);\n documents.set(file, parsed);\n if (!parsed.ok) return { verdict: 'refuse', ...parsed.refusal };\n }\n\n const definitions = new Map(Object.entries(model.types));\n const sectionReferences = new Map<string, SectionReferences[]>();\n\n for (const file of files) {\n const parsed = documents.get(file);\n if (parsed === undefined || !parsed.ok) continue;\n const kind = instanceType(parsed.document);\n if (kind === 'any') continue;\n const definition = kind === null ? undefined : definitions.get(kind);\n if (definition === undefined) return refuse(file, 'unknown-type', { location: 'type' });\n const fields = declaredFields(definition);\n const fieldFailure = validateFields(fields, parsed.document.fields);\n if (fieldFailure !== undefined) {\n return refuse(file, fieldFailure.rule, { location: fieldFailure.field });\n }\n const declared = new Set(Object.keys(fields));\n const undeclared = Object.keys(parsed.document.fields).find(\n (name) => !['type', 'site', 'received'].includes(name) && !declared.has(name),\n );\n if (undeclared !== undefined) return refuse(file, 'undeclared-field', { location: undeclared });\n const content = library[file]!;\n const spans = headingSpans(content, bodyStartOf(content));\n const references: SectionReferences[] = [];\n for (const [name, spec] of Object.entries(definition.sections)) {\n const occurrences = spans.filter((one) => one.name === name);\n if (occurrences.length === 0 && spec.required)\n return refuse(file, 'required-section', { location: name });\n if (spec.kind !== 'list') continue;\n for (const span of occurrences) {\n const items = listItems(content, span.bodyStart, span.bodyEnd);\n if (\n items === null ||\n items.some((item) => !fitsKind(spec.of, content.slice(item.start, item.end)))\n )\n return refuse(file, 'structured-section', { location: name });\n if (spec.of.kind !== 'reference') continue;\n const hrefs = itemHrefs(content, items);\n if (hrefs === null) return refuse(file, 'structured-section', { location: name });\n references.push({ section: name, to: spec.of.to, hrefs });\n }\n }\n sectionReferences.set(file, references);\n }\n\n for (const file of files) {\n const parsed = documents.get(file);\n if (parsed === undefined || !parsed.ok) continue;\n const kind = instanceType(parsed.document);\n if (kind === null || kind === 'any') continue;\n const definition = definitions.get(kind);\n if (definition === undefined) continue;\n for (const [name, spec] of Object.entries(definition.fields)) {\n const targets = referenceTargets(spec, parsed.document.fields[name]);\n const expected = expectedReferenceType(spec);\n if (expected === null) continue;\n for (const target of targets) {\n if (!reaches(file, target, expected, documents, binaryTargets))\n return refuse(file, 'unresolved-reference', { location: name });\n }\n }\n const body = bodyAfterFrontmatter(library[file]!);\n for (const occurrence of hrefOccurrences(body)) {\n const resolved = classifyHref(file, occurrence.href);\n if (resolved.kind === 'skip') continue;\n if (\n resolved.kind === 'invalid' ||\n (!documents.has(resolved.path) && !binaryTargets.has(resolved.path))\n ) {\n return refuse(file, 'unresolved-link');\n }\n }\n for (const { section, to, hrefs } of sectionReferences.get(file)!) {\n for (const href of hrefs) {\n if (!reaches(file, href, to, documents, binaryTargets))\n return refuse(file, 'unresolved-reference', { location: section });\n }\n }\n }\n\n const missing = new Map<string, string[]>();\n for (const file of files) {\n const parsed = documents.get(file);\n if (parsed === undefined || !parsed.ok) continue;\n const kind = instanceType(parsed.document);\n if (kind === null || kind === 'any') continue;\n const definition = definitions.get(kind);\n if (definition === undefined) continue;\n for (const [name, spec] of Object.entries(definition.fields)) {\n const expected = expectedReferenceType(spec);\n if (expected === null) continue;\n for (const target of referenceTargets(spec, parsed.document.fields[name])) {\n const resolved = classifyHref(file, target);\n if (resolved.kind !== 'path') continue;\n if (documents.has(resolved.path)) continue;\n const referrers = missing.get(resolved.path) ?? [];\n referrers.push(file);\n missing.set(resolved.path, referrers);\n }\n }\n }\n const missingPaths = [...missing.keys()].sort();\n if (missingPaths.length > 0) {\n const path = missingPaths[0]!;\n const referrers = [...new Set(missing.get(path) ?? [])].sort();\n return refuse(path, 'referenced-missing-file', { referrers });\n }\n\n return { verdict: 'accept' };\n}\n"],"names":["readSchema","parse","hrefOccurrences","linkInventory","classifyHref","refusal","fitsKind","validateFields","headingSpans","listItems","VERSION","bodyAfterFrontmatter","bodyStartOf","MEMBER_FIELD","MEMBER_SPEC","kind","required","refuse","file","rule","extra","verdict","instanceType","document","raw","fields","type","undefined","referenceTargets","spec","value","of","Array","isArray","filter","item","expectedReferenceType","to","reaches","href","documents","binaryTargets","resolved","has","path","held","get","ok","itemHrefs","content","items","bodyStart","uses","slice","hrefs","link","find","use","start","end","push","destination","verify","schema","read","model","version","location","declaredFields","definition","memberDocument","Object","hasOwn","validate","library","context","types","Set","files","keys","sort","Map","parsed","set","definitions","entries","sectionReferences","fieldFailure","field","declared","undeclared","name","includes","spans","references","sections","occurrences","one","length","span","bodyEnd","some","section","targets","expected","target","body","occurrence","missing","referrers","missingPaths"],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.0-alpha.17";
1
+ export declare const VERSION = "0.1.0-alpha.19";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
- export const VERSION = '0.1.0-alpha.17';
1
+ export const VERSION = '0.1.0-alpha.19';
2
2
 
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdmodel/src/version.ts"],"sourcesContent":["export const VERSION = '0.1.0-alpha.17';\n"],"names":["VERSION"],"mappings":"AAAA,OAAO,MAAMA,UAAU,iBAAiB"}
1
+ {"version":3,"sources":["/workspace/packages/mdmodel/src/version.ts"],"sourcesContent":["export const VERSION = '0.1.0-alpha.19';\n"],"names":["VERSION"],"mappings":"AAAA,OAAO,MAAMA,UAAU,iBAAiB"}
package/dist/yaml.d.ts CHANGED
@@ -27,6 +27,7 @@ export type YamlMap = {
27
27
  readonly end: number;
28
28
  };
29
29
  export type YamlNode = YamlScalar | YamlSeq | YamlMap;
30
+ export declare function interpretPlain(text: string): string | number | boolean | null;
30
31
  export declare function parseYamlMapping(text: string, start: number, end: number): YamlMap;
31
32
  export declare function jsValue(node: YamlNode): unknown;
32
33
  export declare function mapEntry(map: YamlMap, key: string): YamlEntry | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAnC,YAAqB,MAAM,EAAE,MAAM,EAGlC;CACF;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAqStD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAclF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAM/C;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAEzE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMjD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQlD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAqB9F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAQjE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEzD"}
1
+ {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAnC,YAAqB,MAAM,EAAE,MAAM,EAGlC;CACF;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAoEtD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAM7E;AA2ND,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAclF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAM/C;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAEzE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMjD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQlD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAqB9F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAQjE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEzD"}
package/dist/yaml.js CHANGED
@@ -66,7 +66,7 @@ function scalar(value, start, end) {
66
66
  end
67
67
  };
68
68
  }
69
- function interpretPlain(text) {
69
+ export function interpretPlain(text) {
70
70
  if (text === 'true') return true;
71
71
  if (text === 'false') return false;
72
72
  if (text === 'null' || text === '') return null;
package/dist/yaml.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdmodel/src/yaml.ts"],"sourcesContent":["export class YamlError extends Error {\n constructor(readonly offset: number) {\n super('yaml');\n this.name = 'YamlError';\n }\n}\n\nexport type YamlScalar = {\n readonly kind: 'scalar';\n readonly value: string | number | boolean | null;\n readonly start: number;\n readonly end: number;\n};\n\nexport type YamlSeq = {\n readonly kind: 'seq';\n readonly items: readonly YamlNode[];\n readonly start: number;\n readonly end: number;\n};\n\nexport type YamlEntry = {\n readonly key: string;\n readonly keyStart: number;\n readonly keyEnd: number;\n readonly value: YamlNode;\n};\n\nexport type YamlMap = {\n readonly kind: 'map';\n readonly entries: readonly YamlEntry[];\n readonly start: number;\n readonly end: number;\n};\n\nexport type YamlNode = YamlScalar | YamlSeq | YamlMap;\n\ntype Ctx = { text: string; i: number; end: number };\n\nfunction peek(c: Ctx): string {\n return c.i < c.end ? c.text[c.i]! : '';\n}\n\nfunction skipEol(c: Ctx): void {\n if (peek(c) === '\\r') c.i += 1;\n if (peek(c) === '\\n') c.i += 1;\n}\n\nfunction skipSpaces(c: Ctx): void {\n while (peek(c) === ' ') c.i += 1;\n if (peek(c) === '\\t') throw new YamlError(c.i);\n}\n\nfunction skipToEol(c: Ctx): void {\n while (c.i < c.end && peek(c) !== '\\n' && peek(c) !== '\\r') c.i += 1;\n}\n\nfunction skipBlankAndComments(c: Ctx): void {\n while (c.i < c.end) {\n skipSpaces(c);\n if (peek(c) === '#') skipToEol(c);\n if (peek(c) === '\\r' || peek(c) === '\\n') {\n skipEol(c);\n continue;\n }\n break;\n }\n}\n\nfunction skipFlowSpace(c: Ctx): void {\n while (c.i < c.end) {\n const ch = peek(c);\n if (ch === ' ' || ch === '\\n' || ch === '\\r') {\n c.i += 1;\n continue;\n }\n if (ch === '#') {\n skipToEol(c);\n continue;\n }\n if (ch === '\\t') throw new YamlError(c.i);\n break;\n }\n}\n\nfunction indentAt(c: Ctx): number {\n let j = c.i;\n while (j > 0 && c.text[j - 1] !== '\\n' && c.text[j - 1] !== '\\r') j -= 1;\n let n = 0;\n while (j < c.i) {\n const ch = c.text[j]!;\n if (ch === ' ') n += 1;\n else if (ch === '\\t') throw new YamlError(j);\n else break;\n j += 1;\n }\n return n;\n}\n\nfunction scalar(value: string | number | boolean | null, start: number, end: number): YamlScalar {\n return { kind: 'scalar', value, start, end };\n}\n\nfunction interpretPlain(text: string): string | number | boolean | null {\n if (text === 'true') return true;\n if (text === 'false') return false;\n if (text === 'null' || text === '') return null;\n if (/^-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?$/.test(text)) return Number(text);\n return text;\n}\n\nfunction parseQuoted(c: Ctx): YamlScalar {\n const quote = peek(c);\n const start = c.i;\n c.i += 1;\n let out = '';\n while (c.i < c.end) {\n const ch = peek(c);\n if (ch === quote) {\n c.i += 1;\n return scalar(out, start, c.i);\n }\n if (ch === '\\n' || ch === '\\r') throw new YamlError(c.i);\n if (quote === \"'\" && ch === \"'\" && c.text[c.i + 1] === \"'\") {\n out += \"'\";\n c.i += 2;\n continue;\n }\n if (quote === '\"' && ch === '\\\\') {\n c.i += 1;\n const escaped = peek(c);\n if (escaped === 'n') out += '\\n';\n else if (escaped === 't') out += '\\t';\n else if (escaped === '\"') out += '\"';\n else if (escaped === '\\\\') out += '\\\\';\n else throw new YamlError(c.i);\n c.i += 1;\n continue;\n }\n out += ch;\n c.i += 1;\n }\n throw new YamlError(c.i);\n}\n\nfunction parsePlain(c: Ctx, flow: boolean): YamlScalar {\n const start = c.i;\n while (c.i < c.end) {\n const ch = peek(c);\n if (flow && (ch === ',' || ch === ']' || ch === '}')) break;\n if (ch === '\\n' || ch === '\\r') break;\n if (ch === '#' && (c.i === start || c.text[c.i - 1] === ' ' || c.text[c.i - 1] === '\\t')) break;\n c.i += 1;\n }\n if (c.i === start) throw new YamlError(c.i);\n const raw = c.text.slice(start, c.i);\n const trimmed = raw.trimEnd();\n return scalar(interpretPlain(trimmed), start, start + trimmed.length);\n}\n\nfunction parseScalar(c: Ctx, flow: boolean): YamlScalar {\n const ch = peek(c);\n if (ch === '\"' || ch === \"'\") return parseQuoted(c);\n return parsePlain(c, flow);\n}\n\nfunction parseKey(c: Ctx): { name: string; start: number; end: number } {\n const start = c.i;\n if (peek(c) === '\"' || peek(c) === \"'\") {\n const quoted = parseQuoted(c);\n if (typeof quoted.value !== 'string') throw new YamlError(start);\n return { name: quoted.value, start, end: c.i };\n }\n let end = c.i;\n while (c.i < c.end) {\n const ch = peek(c);\n if (\n ch === ':' ||\n ch === '\\n' ||\n ch === '\\r' ||\n ch === ',' ||\n ch === '}' ||\n ch === ']' ||\n ch === '#' ||\n ch === '{' ||\n ch === '['\n ) {\n break;\n }\n c.i += 1;\n if (ch !== ' ' && ch !== '\\t') end = c.i;\n }\n if (end === start) throw new YamlError(c.i);\n c.i = end;\n return { name: c.text.slice(start, end), start, end };\n}\n\nfunction parseFlowValue(c: Ctx): YamlNode {\n skipFlowSpace(c);\n const ch = peek(c);\n if (ch === '{') return parseFlowMap(c);\n if (ch === '[') return parseFlowSeq(c);\n if (ch === '|' || ch === '>') throw new YamlError(c.i);\n return parseScalar(c, true);\n}\n\nfunction parseFlowMap(c: Ctx): YamlMap {\n const start = c.i;\n if (peek(c) !== '{') throw new YamlError(c.i);\n c.i += 1;\n skipFlowSpace(c);\n const entries: YamlEntry[] = [];\n const seen = new Set<string>();\n if (peek(c) === '}') {\n c.i += 1;\n return { kind: 'map', entries, start, end: c.i };\n }\n while (c.i < c.end) {\n skipFlowSpace(c);\n const key = parseKey(c);\n skipFlowSpace(c);\n if (peek(c) !== ':') throw new YamlError(c.i);\n c.i += 1;\n const value = parseFlowValue(c);\n if (seen.has(key.name)) throw new YamlError(key.start);\n seen.add(key.name);\n entries.push({ key: key.name, keyStart: key.start, keyEnd: key.end, value });\n skipFlowSpace(c);\n if (peek(c) === ',') {\n c.i += 1;\n continue;\n }\n if (peek(c) === '}') {\n c.i += 1;\n return { kind: 'map', entries, start, end: c.i };\n }\n throw new YamlError(c.i);\n }\n throw new YamlError(c.i);\n}\n\nfunction parseFlowSeq(c: Ctx): YamlSeq {\n const start = c.i;\n if (peek(c) !== '[') throw new YamlError(c.i);\n c.i += 1;\n skipFlowSpace(c);\n const items: YamlNode[] = [];\n if (peek(c) === ']') {\n c.i += 1;\n return { kind: 'seq', items, start, end: c.i };\n }\n while (c.i < c.end) {\n items.push(parseFlowValue(c));\n skipFlowSpace(c);\n if (peek(c) === ',') {\n c.i += 1;\n skipFlowSpace(c);\n continue;\n }\n if (peek(c) === ']') {\n c.i += 1;\n return { kind: 'seq', items, start, end: c.i };\n }\n throw new YamlError(c.i);\n }\n throw new YamlError(c.i);\n}\n\nfunction parseValue(c: Ctx, parentKeyIndent: number): YamlNode {\n skipSpaces(c);\n if (peek(c) === '#') skipToEol(c);\n const ch = peek(c);\n if (ch === '' || ch === '\\n' || ch === '\\r') {\n skipEol(c);\n skipBlankAndComments(c);\n if (c.i >= c.end) return scalar(null, c.i, c.i);\n const nextIndent = indentAt(c);\n if (nextIndent <= parentKeyIndent) return scalar(null, c.i, c.i);\n if (peek(c) === '-') return parseBlockSeq(c, nextIndent);\n if (peek(c) === '[') return parseFlowSeq(c);\n if (peek(c) === '{') return parseFlowMap(c);\n return parseBlockMap(c, nextIndent);\n }\n if (ch === '{') return parseFlowMap(c);\n if (ch === '[') return parseFlowSeq(c);\n if (ch === '|' || ch === '>') throw new YamlError(c.i);\n return parseScalar(c, false);\n}\n\nfunction parseBlockSeq(c: Ctx, indent: number): YamlSeq {\n const start = c.i;\n const items: YamlNode[] = [];\n let end = start;\n while (c.i < c.end) {\n skipBlankAndComments(c);\n if (c.i >= c.end) break;\n if (indentAt(c) !== indent) break;\n if (peek(c) !== '-') break;\n c.i += 1;\n items.push(parseValue(c, indent));\n end = c.i;\n }\n return { kind: 'seq', items, start, end };\n}\n\nfunction parseBlockMap(c: Ctx, indent: number): YamlMap {\n const start = c.i;\n const entries: YamlEntry[] = [];\n const seen = new Set<string>();\n let end = start;\n while (c.i < c.end) {\n skipBlankAndComments(c);\n if (c.i >= c.end) break;\n if (indentAt(c) < indent) break;\n if (indentAt(c) > indent) throw new YamlError(c.i);\n const key = parseKey(c);\n skipSpaces(c);\n if (peek(c) !== ':') throw new YamlError(c.i);\n c.i += 1;\n const value = parseValue(c, indent);\n if (seen.has(key.name)) throw new YamlError(key.start);\n seen.add(key.name);\n entries.push({ key: key.name, keyStart: key.start, keyEnd: key.end, value });\n end = c.i;\n }\n return { kind: 'map', entries, start, end };\n}\n\nexport function parseYamlMapping(text: string, start: number, end: number): YamlMap {\n const c: Ctx = { text, i: start, end };\n skipBlankAndComments(c);\n if (c.i >= end) return { kind: 'map', entries: [], start, end };\n if (peek(c) === '{') {\n const mapped = parseFlowMap(c);\n skipBlankAndComments(c);\n if (c.i < end) throw new YamlError(c.i);\n return mapped;\n }\n const mapped = parseBlockMap(c, indentAt(c));\n skipBlankAndComments(c);\n if (c.i < end) throw new YamlError(c.i);\n return mapped;\n}\n\nexport function jsValue(node: YamlNode): unknown {\n if (node.kind === 'scalar') return node.value;\n if (node.kind === 'seq') return node.items.map(jsValue);\n const record: Record<string, unknown> = Object.create(null);\n for (const entry of node.entries) record[entry.key] = jsValue(entry.value);\n return record;\n}\n\nexport function mapEntry(map: YamlMap, key: string): YamlEntry | undefined {\n return map.entries.find((entry) => entry.key === key);\n}\n\nexport function isPlainSafe(text: string): boolean {\n if (text === '' || text === 'true' || text === 'false' || text === 'null') return false;\n if (/[\\s#:{}[\\],&*!|>'\"%@`]/.test(text)) return false;\n if (text.startsWith('-') || text.startsWith('?') || text.startsWith(':')) return false;\n if (/^-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?$/.test(text)) return false;\n return true;\n}\n\nexport function serializeJs(value: unknown): string {\n if (value === null) return 'null';\n if (value === true) return 'true';\n if (value === false) return 'false';\n if (typeof value === 'number' && Number.isFinite(value)) return JSON.stringify(value);\n if (typeof value === 'string') return isPlainSafe(value) ? value : JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(serializeJs).join(', ')}]`;\n throw new YamlError(0);\n}\n\nexport function serializeKey(name: string): string {\n return isPlainSafe(name) || /^[A-Za-z][A-Za-z0-9_-]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nexport function bodyStartAfterYaml(content: string, yamlEnd: number): number {\n const closeLine = content.indexOf('\\n', yamlEnd);\n return closeLine === -1 ? content.length : closeLine + 1;\n}\n\nexport function bodyStartOf(content: string): number {\n const fence = extractFrontmatter(content);\n return fence.kind === 'ok' ? bodyStartAfterYaml(content, fence.yamlEnd) : 0;\n}\n\nexport function bodyAfterFrontmatter(content: string): string {\n return content.slice(bodyStartOf(content));\n}\n\nexport function extractFrontmatter(\n content: string,\n): { kind: 'none' } | { kind: 'unclosed' } | { kind: 'ok'; yamlStart: number; yamlEnd: number } {\n if (!content.startsWith('---')) return { kind: 'none' };\n const firstNl = content.indexOf('\\n');\n const firstLine =\n firstNl === -1\n ? content\n : content.slice(0, content[firstNl - 1] === '\\r' ? firstNl - 1 : firstNl);\n if (!/^---[ \\t]*$/.test(firstLine)) return { kind: 'none' };\n if (firstNl === -1) return { kind: 'unclosed' };\n const yamlStart = firstNl + 1;\n let i = yamlStart;\n while (i <= content.length) {\n const nl = content.indexOf('\\n', i);\n const lineEnd = nl === -1 ? content.length : nl;\n let line = content.slice(i, lineEnd);\n if (line.endsWith('\\r')) line = line.slice(0, -1);\n if (/^---[ \\t]*$/.test(line)) return { kind: 'ok', yamlStart, yamlEnd: i };\n if (nl === -1) return { kind: 'unclosed' };\n i = nl + 1;\n }\n return { kind: 'unclosed' };\n}\n\nexport function equalValue(left: unknown, right: unknown): boolean {\n if (left === right) return true;\n if (Array.isArray(left) && Array.isArray(right)) {\n return (\n left.length === right.length && left.every((item, index) => equalValue(item, right[index]))\n );\n }\n return false;\n}\n\nexport function lineEnding(content: string): '\\n' | '\\r\\n' {\n return content.includes('\\r\\n') ? '\\r\\n' : '\\n';\n}\n"],"names":["YamlError","Error","offset","name","peek","c","i","end","text","skipEol","skipSpaces","skipToEol","skipBlankAndComments","skipFlowSpace","ch","indentAt","j","n","scalar","value","start","kind","interpretPlain","test","Number","parseQuoted","quote","out","escaped","parsePlain","flow","raw","slice","trimmed","trimEnd","length","parseScalar","parseKey","quoted","parseFlowValue","parseFlowMap","parseFlowSeq","entries","seen","Set","key","has","add","push","keyStart","keyEnd","items","parseValue","parentKeyIndent","nextIndent","parseBlockSeq","parseBlockMap","indent","parseYamlMapping","mapped","jsValue","node","map","record","Object","create","entry","mapEntry","find","isPlainSafe","startsWith","serializeJs","isFinite","JSON","stringify","Array","isArray","join","serializeKey","bodyStartAfterYaml","content","yamlEnd","closeLine","indexOf","bodyStartOf","fence","extractFrontmatter","bodyAfterFrontmatter","firstNl","firstLine","yamlStart","nl","lineEnd","line","endsWith","equalValue","left","right","every","item","index","lineEnding","includes"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdmodel/src/yaml.ts"],"sourcesContent":["export class YamlError extends Error {\n constructor(readonly offset: number) {\n super('yaml');\n this.name = 'YamlError';\n }\n}\n\nexport type YamlScalar = {\n readonly kind: 'scalar';\n readonly value: string | number | boolean | null;\n readonly start: number;\n readonly end: number;\n};\n\nexport type YamlSeq = {\n readonly kind: 'seq';\n readonly items: readonly YamlNode[];\n readonly start: number;\n readonly end: number;\n};\n\nexport type YamlEntry = {\n readonly key: string;\n readonly keyStart: number;\n readonly keyEnd: number;\n readonly value: YamlNode;\n};\n\nexport type YamlMap = {\n readonly kind: 'map';\n readonly entries: readonly YamlEntry[];\n readonly start: number;\n readonly end: number;\n};\n\nexport type YamlNode = YamlScalar | YamlSeq | YamlMap;\n\ntype Ctx = { text: string; i: number; end: number };\n\nfunction peek(c: Ctx): string {\n return c.i < c.end ? c.text[c.i]! : '';\n}\n\nfunction skipEol(c: Ctx): void {\n if (peek(c) === '\\r') c.i += 1;\n if (peek(c) === '\\n') c.i += 1;\n}\n\nfunction skipSpaces(c: Ctx): void {\n while (peek(c) === ' ') c.i += 1;\n if (peek(c) === '\\t') throw new YamlError(c.i);\n}\n\nfunction skipToEol(c: Ctx): void {\n while (c.i < c.end && peek(c) !== '\\n' && peek(c) !== '\\r') c.i += 1;\n}\n\nfunction skipBlankAndComments(c: Ctx): void {\n while (c.i < c.end) {\n skipSpaces(c);\n if (peek(c) === '#') skipToEol(c);\n if (peek(c) === '\\r' || peek(c) === '\\n') {\n skipEol(c);\n continue;\n }\n break;\n }\n}\n\nfunction skipFlowSpace(c: Ctx): void {\n while (c.i < c.end) {\n const ch = peek(c);\n if (ch === ' ' || ch === '\\n' || ch === '\\r') {\n c.i += 1;\n continue;\n }\n if (ch === '#') {\n skipToEol(c);\n continue;\n }\n if (ch === '\\t') throw new YamlError(c.i);\n break;\n }\n}\n\nfunction indentAt(c: Ctx): number {\n let j = c.i;\n while (j > 0 && c.text[j - 1] !== '\\n' && c.text[j - 1] !== '\\r') j -= 1;\n let n = 0;\n while (j < c.i) {\n const ch = c.text[j]!;\n if (ch === ' ') n += 1;\n else if (ch === '\\t') throw new YamlError(j);\n else break;\n j += 1;\n }\n return n;\n}\n\nfunction scalar(value: string | number | boolean | null, start: number, end: number): YamlScalar {\n return { kind: 'scalar', value, start, end };\n}\n\nexport function interpretPlain(text: string): string | number | boolean | null {\n if (text === 'true') return true;\n if (text === 'false') return false;\n if (text === 'null' || text === '') return null;\n if (/^-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?$/.test(text)) return Number(text);\n return text;\n}\n\nfunction parseQuoted(c: Ctx): YamlScalar {\n const quote = peek(c);\n const start = c.i;\n c.i += 1;\n let out = '';\n while (c.i < c.end) {\n const ch = peek(c);\n if (ch === quote) {\n c.i += 1;\n return scalar(out, start, c.i);\n }\n if (ch === '\\n' || ch === '\\r') throw new YamlError(c.i);\n if (quote === \"'\" && ch === \"'\" && c.text[c.i + 1] === \"'\") {\n out += \"'\";\n c.i += 2;\n continue;\n }\n if (quote === '\"' && ch === '\\\\') {\n c.i += 1;\n const escaped = peek(c);\n if (escaped === 'n') out += '\\n';\n else if (escaped === 't') out += '\\t';\n else if (escaped === '\"') out += '\"';\n else if (escaped === '\\\\') out += '\\\\';\n else throw new YamlError(c.i);\n c.i += 1;\n continue;\n }\n out += ch;\n c.i += 1;\n }\n throw new YamlError(c.i);\n}\n\nfunction parsePlain(c: Ctx, flow: boolean): YamlScalar {\n const start = c.i;\n while (c.i < c.end) {\n const ch = peek(c);\n if (flow && (ch === ',' || ch === ']' || ch === '}')) break;\n if (ch === '\\n' || ch === '\\r') break;\n if (ch === '#' && (c.i === start || c.text[c.i - 1] === ' ' || c.text[c.i - 1] === '\\t')) break;\n c.i += 1;\n }\n if (c.i === start) throw new YamlError(c.i);\n const raw = c.text.slice(start, c.i);\n const trimmed = raw.trimEnd();\n return scalar(interpretPlain(trimmed), start, start + trimmed.length);\n}\n\nfunction parseScalar(c: Ctx, flow: boolean): YamlScalar {\n const ch = peek(c);\n if (ch === '\"' || ch === \"'\") return parseQuoted(c);\n return parsePlain(c, flow);\n}\n\nfunction parseKey(c: Ctx): { name: string; start: number; end: number } {\n const start = c.i;\n if (peek(c) === '\"' || peek(c) === \"'\") {\n const quoted = parseQuoted(c);\n if (typeof quoted.value !== 'string') throw new YamlError(start);\n return { name: quoted.value, start, end: c.i };\n }\n let end = c.i;\n while (c.i < c.end) {\n const ch = peek(c);\n if (\n ch === ':' ||\n ch === '\\n' ||\n ch === '\\r' ||\n ch === ',' ||\n ch === '}' ||\n ch === ']' ||\n ch === '#' ||\n ch === '{' ||\n ch === '['\n ) {\n break;\n }\n c.i += 1;\n if (ch !== ' ' && ch !== '\\t') end = c.i;\n }\n if (end === start) throw new YamlError(c.i);\n c.i = end;\n return { name: c.text.slice(start, end), start, end };\n}\n\nfunction parseFlowValue(c: Ctx): YamlNode {\n skipFlowSpace(c);\n const ch = peek(c);\n if (ch === '{') return parseFlowMap(c);\n if (ch === '[') return parseFlowSeq(c);\n if (ch === '|' || ch === '>') throw new YamlError(c.i);\n return parseScalar(c, true);\n}\n\nfunction parseFlowMap(c: Ctx): YamlMap {\n const start = c.i;\n if (peek(c) !== '{') throw new YamlError(c.i);\n c.i += 1;\n skipFlowSpace(c);\n const entries: YamlEntry[] = [];\n const seen = new Set<string>();\n if (peek(c) === '}') {\n c.i += 1;\n return { kind: 'map', entries, start, end: c.i };\n }\n while (c.i < c.end) {\n skipFlowSpace(c);\n const key = parseKey(c);\n skipFlowSpace(c);\n if (peek(c) !== ':') throw new YamlError(c.i);\n c.i += 1;\n const value = parseFlowValue(c);\n if (seen.has(key.name)) throw new YamlError(key.start);\n seen.add(key.name);\n entries.push({ key: key.name, keyStart: key.start, keyEnd: key.end, value });\n skipFlowSpace(c);\n if (peek(c) === ',') {\n c.i += 1;\n continue;\n }\n if (peek(c) === '}') {\n c.i += 1;\n return { kind: 'map', entries, start, end: c.i };\n }\n throw new YamlError(c.i);\n }\n throw new YamlError(c.i);\n}\n\nfunction parseFlowSeq(c: Ctx): YamlSeq {\n const start = c.i;\n if (peek(c) !== '[') throw new YamlError(c.i);\n c.i += 1;\n skipFlowSpace(c);\n const items: YamlNode[] = [];\n if (peek(c) === ']') {\n c.i += 1;\n return { kind: 'seq', items, start, end: c.i };\n }\n while (c.i < c.end) {\n items.push(parseFlowValue(c));\n skipFlowSpace(c);\n if (peek(c) === ',') {\n c.i += 1;\n skipFlowSpace(c);\n continue;\n }\n if (peek(c) === ']') {\n c.i += 1;\n return { kind: 'seq', items, start, end: c.i };\n }\n throw new YamlError(c.i);\n }\n throw new YamlError(c.i);\n}\n\nfunction parseValue(c: Ctx, parentKeyIndent: number): YamlNode {\n skipSpaces(c);\n if (peek(c) === '#') skipToEol(c);\n const ch = peek(c);\n if (ch === '' || ch === '\\n' || ch === '\\r') {\n skipEol(c);\n skipBlankAndComments(c);\n if (c.i >= c.end) return scalar(null, c.i, c.i);\n const nextIndent = indentAt(c);\n if (nextIndent <= parentKeyIndent) return scalar(null, c.i, c.i);\n if (peek(c) === '-') return parseBlockSeq(c, nextIndent);\n if (peek(c) === '[') return parseFlowSeq(c);\n if (peek(c) === '{') return parseFlowMap(c);\n return parseBlockMap(c, nextIndent);\n }\n if (ch === '{') return parseFlowMap(c);\n if (ch === '[') return parseFlowSeq(c);\n if (ch === '|' || ch === '>') throw new YamlError(c.i);\n return parseScalar(c, false);\n}\n\nfunction parseBlockSeq(c: Ctx, indent: number): YamlSeq {\n const start = c.i;\n const items: YamlNode[] = [];\n let end = start;\n while (c.i < c.end) {\n skipBlankAndComments(c);\n if (c.i >= c.end) break;\n if (indentAt(c) !== indent) break;\n if (peek(c) !== '-') break;\n c.i += 1;\n items.push(parseValue(c, indent));\n end = c.i;\n }\n return { kind: 'seq', items, start, end };\n}\n\nfunction parseBlockMap(c: Ctx, indent: number): YamlMap {\n const start = c.i;\n const entries: YamlEntry[] = [];\n const seen = new Set<string>();\n let end = start;\n while (c.i < c.end) {\n skipBlankAndComments(c);\n if (c.i >= c.end) break;\n if (indentAt(c) < indent) break;\n if (indentAt(c) > indent) throw new YamlError(c.i);\n const key = parseKey(c);\n skipSpaces(c);\n if (peek(c) !== ':') throw new YamlError(c.i);\n c.i += 1;\n const value = parseValue(c, indent);\n if (seen.has(key.name)) throw new YamlError(key.start);\n seen.add(key.name);\n entries.push({ key: key.name, keyStart: key.start, keyEnd: key.end, value });\n end = c.i;\n }\n return { kind: 'map', entries, start, end };\n}\n\nexport function parseYamlMapping(text: string, start: number, end: number): YamlMap {\n const c: Ctx = { text, i: start, end };\n skipBlankAndComments(c);\n if (c.i >= end) return { kind: 'map', entries: [], start, end };\n if (peek(c) === '{') {\n const mapped = parseFlowMap(c);\n skipBlankAndComments(c);\n if (c.i < end) throw new YamlError(c.i);\n return mapped;\n }\n const mapped = parseBlockMap(c, indentAt(c));\n skipBlankAndComments(c);\n if (c.i < end) throw new YamlError(c.i);\n return mapped;\n}\n\nexport function jsValue(node: YamlNode): unknown {\n if (node.kind === 'scalar') return node.value;\n if (node.kind === 'seq') return node.items.map(jsValue);\n const record: Record<string, unknown> = Object.create(null);\n for (const entry of node.entries) record[entry.key] = jsValue(entry.value);\n return record;\n}\n\nexport function mapEntry(map: YamlMap, key: string): YamlEntry | undefined {\n return map.entries.find((entry) => entry.key === key);\n}\n\nexport function isPlainSafe(text: string): boolean {\n if (text === '' || text === 'true' || text === 'false' || text === 'null') return false;\n if (/[\\s#:{}[\\],&*!|>'\"%@`]/.test(text)) return false;\n if (text.startsWith('-') || text.startsWith('?') || text.startsWith(':')) return false;\n if (/^-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?$/.test(text)) return false;\n return true;\n}\n\nexport function serializeJs(value: unknown): string {\n if (value === null) return 'null';\n if (value === true) return 'true';\n if (value === false) return 'false';\n if (typeof value === 'number' && Number.isFinite(value)) return JSON.stringify(value);\n if (typeof value === 'string') return isPlainSafe(value) ? value : JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(serializeJs).join(', ')}]`;\n throw new YamlError(0);\n}\n\nexport function serializeKey(name: string): string {\n return isPlainSafe(name) || /^[A-Za-z][A-Za-z0-9_-]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nexport function bodyStartAfterYaml(content: string, yamlEnd: number): number {\n const closeLine = content.indexOf('\\n', yamlEnd);\n return closeLine === -1 ? content.length : closeLine + 1;\n}\n\nexport function bodyStartOf(content: string): number {\n const fence = extractFrontmatter(content);\n return fence.kind === 'ok' ? bodyStartAfterYaml(content, fence.yamlEnd) : 0;\n}\n\nexport function bodyAfterFrontmatter(content: string): string {\n return content.slice(bodyStartOf(content));\n}\n\nexport function extractFrontmatter(\n content: string,\n): { kind: 'none' } | { kind: 'unclosed' } | { kind: 'ok'; yamlStart: number; yamlEnd: number } {\n if (!content.startsWith('---')) return { kind: 'none' };\n const firstNl = content.indexOf('\\n');\n const firstLine =\n firstNl === -1\n ? content\n : content.slice(0, content[firstNl - 1] === '\\r' ? firstNl - 1 : firstNl);\n if (!/^---[ \\t]*$/.test(firstLine)) return { kind: 'none' };\n if (firstNl === -1) return { kind: 'unclosed' };\n const yamlStart = firstNl + 1;\n let i = yamlStart;\n while (i <= content.length) {\n const nl = content.indexOf('\\n', i);\n const lineEnd = nl === -1 ? content.length : nl;\n let line = content.slice(i, lineEnd);\n if (line.endsWith('\\r')) line = line.slice(0, -1);\n if (/^---[ \\t]*$/.test(line)) return { kind: 'ok', yamlStart, yamlEnd: i };\n if (nl === -1) return { kind: 'unclosed' };\n i = nl + 1;\n }\n return { kind: 'unclosed' };\n}\n\nexport function equalValue(left: unknown, right: unknown): boolean {\n if (left === right) return true;\n if (Array.isArray(left) && Array.isArray(right)) {\n return (\n left.length === right.length && left.every((item, index) => equalValue(item, right[index]))\n );\n }\n return false;\n}\n\nexport function lineEnding(content: string): '\\n' | '\\r\\n' {\n return content.includes('\\r\\n') ? '\\r\\n' : '\\n';\n}\n"],"names":["YamlError","Error","offset","name","peek","c","i","end","text","skipEol","skipSpaces","skipToEol","skipBlankAndComments","skipFlowSpace","ch","indentAt","j","n","scalar","value","start","kind","interpretPlain","test","Number","parseQuoted","quote","out","escaped","parsePlain","flow","raw","slice","trimmed","trimEnd","length","parseScalar","parseKey","quoted","parseFlowValue","parseFlowMap","parseFlowSeq","entries","seen","Set","key","has","add","push","keyStart","keyEnd","items","parseValue","parentKeyIndent","nextIndent","parseBlockSeq","parseBlockMap","indent","parseYamlMapping","mapped","jsValue","node","map","record","Object","create","entry","mapEntry","find","isPlainSafe","startsWith","serializeJs","isFinite","JSON","stringify","Array","isArray","join","serializeKey","bodyStartAfterYaml","content","yamlEnd","closeLine","indexOf","bodyStartOf","fence","extractFrontmatter","bodyAfterFrontmatter","firstNl","firstLine","yamlStart","nl","lineEnd","line","endsWith","equalValue","left","right","every","item","index","lineEnding","includes"],"mappings":"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"}
@@ -26,17 +26,23 @@ fenced headings, newline/source preservation, and a moved-export link rewrite.
26
26
  validation Libraries. It carries `schema`, one schema text, and `cases`. Each
27
27
  case carries `name`, the `file` the Document sits at, exact `source`, the
28
28
  `documentTargets` the collection holds as Markdown documents, the `definition`
29
- type name or `null`, an optional `move`, and `expected`.
29
+ type name or `null`, an optional `move`, an optional `links` inventory, an
30
+ optional `relabel`, and `expected`.
30
31
  A case carrying a `move` lists both the Path its target sits at and the Path the
31
32
  move takes it to, because the collection holds that target either way.
32
33
 
33
34
  Verify the schema, parse the source, call `project(document, file, context)`
34
35
  with `documentTargets` and the verified type `definition` names, and compare against `expected`, replacing the
35
- `<package-version>` token in a refusal the same way `cases/` does. Then check
36
+ `<package-version>` token in a refusal the same way `cases/` does. Where
37
+ `links` is present, compare `links(document, file)` against it. Then check
36
38
  that the source is unchanged. Where `move` is present, apply
37
39
  `{ kind: 'link', href, to }`, confirm the serialized Document changed, and
38
40
  confirm the projection of the moved Document is still exactly `expected`: a
39
- moved Path rewrites destinations and leaves the projection alone.
41
+ moved Path rewrites destinations and leaves the projection alone. Where
42
+ `relabel` is present, split the source at its `from`, which the source carries
43
+ exactly once, join the pieces with its `to`, parse the result, and confirm its
44
+ projection is exactly the relabel's own `expected` and differs from the case's:
45
+ a changed visible label changes the projection.
40
46
 
41
47
  ## Division
42
48
 
@@ -111,9 +117,9 @@ replace it with the package's semantic version before comparing.
111
117
  | `field-kind` | A field value fails its kind, including date |
112
118
  | `field-enum` | A field value is not one of the declared enum values |
113
119
  | `undeclared-field` | A typed file carries a frontmatter field its type does not declare |
114
- | `unresolved-reference` | A reference does not resolve to a current file of the required type |
120
+ | `unresolved-reference` | A reference field or item resolves to no current file of the required type |
115
121
  | `unresolved-link` | A relative body link does not resolve to a current path |
116
- | `structured-section` | A declared structured-list section does not parse as a list |
122
+ | `structured-section` | A declared list section is not a list of its declared item kind |
117
123
  | `referenced-missing-file` | Remaining files still reference an absent path |
118
124
  | `unwritable-link` | No Markdown destination form can carry a new link destination |
119
125
  | `division-budget` | A division budget is not a whole number of at least 2 |
@@ -0,0 +1 @@
1
+ { "binaryTargets": [] }
@@ -0,0 +1,7 @@
1
+ {
2
+ "verdict": "refuse",
3
+ "file": "task.md",
4
+ "location": "Stages",
5
+ "rule": "structured-section",
6
+ "version": "<package-version>"
7
+ }
@@ -0,0 +1,8 @@
1
+ ---
2
+ type: task
3
+ ---
4
+
5
+ ## Stages
6
+
7
+ - draft
8
+ - shipped
@@ -0,0 +1,4 @@
1
+ types:
2
+ task:
3
+ sections:
4
+ Stages: { kind: list, of: enum, values: [draft, done] }
@@ -0,0 +1 @@
1
+ { "binaryTargets": [] }
@@ -0,0 +1,7 @@
1
+ {
2
+ "verdict": "refuse",
3
+ "file": "task.md",
4
+ "location": "Estimates",
5
+ "rule": "structured-section",
6
+ "version": "<package-version>"
7
+ }
@@ -0,0 +1,8 @@
1
+ ---
2
+ type: task
3
+ ---
4
+
5
+ ## Estimates
6
+
7
+ - 3
8
+ - not a number
@@ -0,0 +1,4 @@
1
+ types:
2
+ task:
3
+ sections:
4
+ Estimates: { kind: list, of: number }
@@ -0,0 +1 @@
1
+ { "binaryTargets": [] }
@@ -0,0 +1 @@
1
+ { "verdict": "accept" }
@@ -0,0 +1,3 @@
1
+ ---
2
+ type: page
3
+ ---
@@ -0,0 +1,28 @@
1
+ ---
2
+ type: page
3
+ ---
4
+
5
+ [self]: page.md
6
+
7
+ ## Estimates
8
+
9
+ - 3
10
+ - -1.5
11
+
12
+ ## Dates
13
+
14
+ - 2026-10-06
15
+
16
+ ## Stages
17
+
18
+ - draft
19
+ - done
20
+
21
+ ## Related
22
+
23
+ - [the other page](other.md)
24
+ - [this page][self]
25
+
26
+ ## Notes
27
+
28
+ - any text, [a link](other.md) included
@@ -0,0 +1,8 @@
1
+ types:
2
+ page:
3
+ sections:
4
+ Estimates: { kind: list, of: number }
5
+ Dates: { kind: list, of: date }
6
+ Stages: { kind: list, of: enum, values: [draft, done] }
7
+ Related: { kind: list, of: reference, to: page }
8
+ Notes: { kind: list, of: string }
@@ -0,0 +1 @@
1
+ { "binaryTargets": [] }
@@ -0,0 +1,7 @@
1
+ {
2
+ "verdict": "refuse",
3
+ "file": "page.md",
4
+ "location": "Related",
5
+ "rule": "structured-section",
6
+ "version": "<package-version>"
7
+ }
@@ -0,0 +1,3 @@
1
+ ---
2
+ type: page
3
+ ---
@@ -0,0 +1,7 @@
1
+ ---
2
+ type: page
3
+ ---
4
+
5
+ ## Related
6
+
7
+ - other.md
@@ -0,0 +1,4 @@
1
+ types:
2
+ page:
3
+ sections:
4
+ Related: { kind: list, of: reference, to: page }
@@ -0,0 +1 @@
1
+ { "binaryTargets": [] }
@@ -0,0 +1,7 @@
1
+ {
2
+ "verdict": "refuse",
3
+ "file": "page.md",
4
+ "location": "Related",
5
+ "rule": "unresolved-reference",
6
+ "version": "<package-version>"
7
+ }
@@ -0,0 +1,7 @@
1
+ ---
2
+ type: page
3
+ ---
4
+
5
+ ## Related
6
+
7
+ - [a note](note.md)
@@ -0,0 +1,4 @@
1
+ types:
2
+ page:
3
+ sections:
4
+ Related: { kind: list, of: reference, to: page }
@@ -0,0 +1 @@
1
+ { "binaryTargets": [] }
@@ -0,0 +1,6 @@
1
+ {
2
+ "verdict": "refuse",
3
+ "file": "item.md",
4
+ "rule": "unresolved-link",
5
+ "version": "<package-version>"
6
+ }
@@ -0,0 +1,10 @@
1
+ ---
2
+ type: task
3
+ title: Ship
4
+ ---
5
+
6
+ ## Description
7
+
8
+ See [Plan].
9
+
10
+ [plan]: missing.md
@@ -0,0 +1,6 @@
1
+ types:
2
+ task:
3
+ fields:
4
+ title: { kind: string, required: true }
5
+ sections:
6
+ Description: { kind: text, required: true }
@@ -0,0 +1 @@
1
+ { "binaryTargets": [] }
@@ -0,0 +1,7 @@
1
+ {
2
+ "verdict": "refuse",
3
+ "file": "page.md",
4
+ "location": "name",
5
+ "rule": "field-kind",
6
+ "version": "<package-version>"
7
+ }
@@ -0,0 +1,4 @@
1
+ ---
2
+ type: page
3
+ name: 12
4
+ ---
@@ -0,0 +1,4 @@
1
+ types:
2
+ page:
3
+ fields:
4
+ name: { kind: text, required: true }
@@ -80,6 +80,14 @@
80
80
  "href": "../plans/q3.md",
81
81
  "to": "../plans/2026-q3.md"
82
82
  },
83
+ "relabel": {
84
+ "from": "[the plan][plan] and",
85
+ "to": "[the roadmap][plan] and",
86
+ "expected": {
87
+ "ok": true,
88
+ "text": "Shipping the release\n\n\nPreamble prose that mentions the plan.\n\n## Description\n\nFollow the roadmap and the plan again, then read it.\n\n\n## Checklist\n\n- the plan is read\n\n## Notes\n\nUndeclared prose about the plan.\n"
89
+ }
90
+ },
83
91
  "expected": {
84
92
  "ok": true,
85
93
  "text": "Shipping the release\n\n\nPreamble prose that mentions the plan.\n\n## Description\n\nFollow the plan and the plan again, then read it.\n\n\n## Checklist\n\n- the plan is read\n\n## Notes\n\nUndeclared prose about the plan.\n"
@@ -158,6 +166,59 @@
158
166
  "ok": true,
159
167
  "text": "Read the plan and the chart.\nAlso the plan and the chart.\n\n"
160
168
  }
169
+ },
170
+ {
171
+ "name": "a shortcut reference link projects its label and its definition leaves the projection",
172
+ "file": "notes/five.md",
173
+ "source": "Read [Plan] and [the draft], then [plan](not a link).\nAlso [[Plan]], [ plan ], \\[Plan] and [Release plan].\n\n[plan]: ../plans/q3.md\n[release plan]: ../plans/q3.md\n",
174
+ "documentTargets": [
175
+ "plans/q3.md",
176
+ "plans/2026-q3.md"
177
+ ],
178
+ "definition": null,
179
+ "move": {
180
+ "href": "../plans/q3.md",
181
+ "to": "../plans/2026-q3.md"
182
+ },
183
+ "links": [
184
+ {
185
+ "href": "../plans/q3.md",
186
+ "target": "plans/q3.md"
187
+ }
188
+ ],
189
+ "expected": {
190
+ "ok": true,
191
+ "text": "Read Plan and [the draft], then plan(not a link).\nAlso [Plan], plan , \\[Plan] and Release plan.\n\n"
192
+ }
193
+ },
194
+ {
195
+ "name": "an image whose description holds a link projects both labels",
196
+ "file": "notes/six.md",
197
+ "source": "Read ![outer [Plan](../plans/q3.md)](../plans/q4.md).\n",
198
+ "documentTargets": [
199
+ "plans/q3.md",
200
+ "plans/2026-q3.md",
201
+ "plans/q4.md"
202
+ ],
203
+ "definition": null,
204
+ "move": {
205
+ "href": "../plans/q3.md",
206
+ "to": "../plans/2026-q3.md"
207
+ },
208
+ "links": [
209
+ {
210
+ "href": "../plans/q3.md",
211
+ "target": "plans/q3.md"
212
+ },
213
+ {
214
+ "href": "../plans/q4.md",
215
+ "target": "plans/q4.md"
216
+ }
217
+ ],
218
+ "expected": {
219
+ "ok": true,
220
+ "text": "Read outer Plan.\n"
221
+ }
161
222
  }
162
223
  ]
163
224
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/mdmodel",
3
- "version": "0.1.0-alpha.17",
3
+ "version": "0.1.0-alpha.19",
4
4
  "description": "MD Type language, parser, validator, structured change application, Markdown syntax profile, and conformance fixtures",
5
5
  "license": "MIT",
6
6
  "type": "module",