@agentproto/corpus 0.2.0 → 0.3.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/LICENSE +202 -21
- package/dist/index.d.ts +39 -1
- package/dist/index.mjs +99 -14
- package/dist/index.mjs.map +1 -1
- package/dist/report/index.d.ts +27 -2
- package/dist/report/index.mjs +55 -4
- package/dist/report/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/report/index.d.ts
CHANGED
|
@@ -428,7 +428,7 @@ declare function analyzeDataset(opts: AnalyzeDatasetOptions): Promise<AnalyzeDat
|
|
|
428
428
|
*/
|
|
429
429
|
|
|
430
430
|
interface ChapterWriteContext {
|
|
431
|
-
readonly chapter: Pick<ReportChapter, "id" | "title" | "words">;
|
|
431
|
+
readonly chapter: Pick<ReportChapter, "id" | "title" | "words" | "cover">;
|
|
432
432
|
/** Report/document title for framing. */
|
|
433
433
|
readonly title: string;
|
|
434
434
|
/** The chapter's view content (distilled claims with [n]). */
|
|
@@ -437,6 +437,8 @@ interface ChapterWriteContext {
|
|
|
437
437
|
readonly analysisContext?: string;
|
|
438
438
|
/** The global bibliography markdown (for citation verification). */
|
|
439
439
|
readonly bibliography?: string;
|
|
440
|
+
/** Global rules block (`ReportConfig.rulesText`) — appended verbatim. */
|
|
441
|
+
readonly rules?: string;
|
|
440
442
|
}
|
|
441
443
|
declare function buildChapterWritePrompt(ctx: ChapterWriteContext): ReportModelInput;
|
|
442
444
|
/** Single-pass chapter write → a `{ ch, draft }` ready for assembleChapters. */
|
|
@@ -469,6 +471,11 @@ interface ChapterReviewContext {
|
|
|
469
471
|
readonly bibliography?: string;
|
|
470
472
|
/** Highest valid citation [n] — replacements must not exceed it. */
|
|
471
473
|
readonly bibMax: number;
|
|
474
|
+
/**
|
|
475
|
+
* Global rules block (`ReportConfig.rulesText`) — the same contract the
|
|
476
|
+
* writer was given, appended verbatim so review enforces it too.
|
|
477
|
+
*/
|
|
478
|
+
readonly rules?: string;
|
|
472
479
|
}
|
|
473
480
|
declare function buildReviewPrompt(ctx: ChapterReviewContext): ReportModelInput;
|
|
474
481
|
/**
|
|
@@ -502,4 +509,22 @@ interface PlanOutlineResult {
|
|
|
502
509
|
}
|
|
503
510
|
declare function planOutline(opts: PlanOutlineOptions): Promise<PlanOutlineResult>;
|
|
504
511
|
|
|
505
|
-
|
|
512
|
+
/**
|
|
513
|
+
* lintReportConfig — catch mis-named ReportConfig keys before they vanish.
|
|
514
|
+
*
|
|
515
|
+
* `reportConfigSchema` is `.passthrough()` everywhere (intentional — render/
|
|
516
|
+
* presentation fields the engine doesn't read must survive a parse
|
|
517
|
+
* round-trip). The side effect: a typo'd field (`chapters[].brief` instead
|
|
518
|
+
* of `chapters[].cover`) parses fine and silently never reaches the engine.
|
|
519
|
+
* This walks the raw config against the schema shape and flags what
|
|
520
|
+
* `.passthrough()` would otherwise eat quietly.
|
|
521
|
+
*/
|
|
522
|
+
/**
|
|
523
|
+
* Lint a raw (pre- or post-parse — `.passthrough()` preserves extra keys
|
|
524
|
+
* either way) report config for mis-named or dead keys. Returns one message
|
|
525
|
+
* per flagged key, prefixed `WARN`/`INFO`; empty when the config is clean.
|
|
526
|
+
* Parsing behavior is unchanged — this is diagnostics only.
|
|
527
|
+
*/
|
|
528
|
+
declare function lintReportConfig(config: unknown): string[];
|
|
529
|
+
|
|
530
|
+
export { type AnalyzeDatasetOptions, type AnalyzeDatasetResult, type AnalyzeFacetInput, type ApplyEditsOptions, type ApplyEditsResult, type AssembleOptions, type AssembleResult, type BibEntry, type BuildPacksOptions, type BuildPacksResult, type BuildReportContentOptions, type ChapterDraft, type ChapterEdit, type ChapterEditSet, type ChapterReviewContext, type ChapterWriteContext, type CollectSectionsOptions, type PackFile, type PlanOutlineOptions, type PlanOutlineResult, type ReportChapter, type ReportConfig, type ReportContent, type ReportCover, type ReportCoverFact, type ReportCoverPage, ReportModelInput, ReportModelPort, type ReportPart, type ReportSection, type StitchOptions, type StitchResult, analyzeDataset, applyEdits, assembleChapters, bibEntrySchema, buildChapterWritePrompt, buildFacetAnalysisPrompt, buildPacks, buildReportContent, buildReviewPrompt, citesOf, cleanDraft, collectReportSections, lintReportConfig, outOfRangeCites, planOutline, reportChapterSchema, reportConfigSchema, reportContentSchema, reportContentToMarkdown, reportCoverFactSchema, reportCoverPageSchema, reportCoverSchema, reportPartSchema, reportSectionKindSchema, reportSectionSchema, reviewChapter, stitchReport, writeChapter };
|
package/dist/report/index.mjs
CHANGED
|
@@ -461,10 +461,16 @@ ${content}`
|
|
|
461
461
|
function buildChapterWritePrompt(ctx) {
|
|
462
462
|
const words = ctx.chapter.words ?? "800-1500";
|
|
463
463
|
return {
|
|
464
|
-
system: `You are an expert research writer. Write in clear, dense, well-structured prose. Every non-obvious claim must be cited inline as [n] from the Bibliography. Use Markdown H2 and H3 subheaders within the chapter. No meta-commentary or filler. Aim for ${words} words
|
|
464
|
+
system: `You are an expert research writer. Write in clear, dense, well-structured prose. Every non-obvious claim must be cited inline as [n] from the Bibliography. Use Markdown H2 and H3 subheaders within the chapter. No meta-commentary or filler. Aim for ${words} words.` + (ctx.rules ? `
|
|
465
|
+
|
|
466
|
+
${ctx.rules}` : ""),
|
|
465
467
|
prompt: `Write the chapter "${ctx.chapter.title}" for the research document "${ctx.title}".
|
|
466
468
|
|
|
467
|
-
|
|
469
|
+
` + (ctx.chapter.cover ? `## Chapter brief (what this chapter must cover)
|
|
470
|
+
|
|
471
|
+
${ctx.chapter.cover}
|
|
472
|
+
|
|
473
|
+
` : "") + `## Distilled claims for this chapter (with citation numbers):
|
|
468
474
|
|
|
469
475
|
${ctx.packContent}
|
|
470
476
|
|
|
@@ -485,7 +491,9 @@ async function writeChapter(ctx, model) {
|
|
|
485
491
|
}
|
|
486
492
|
function buildReviewPrompt(ctx) {
|
|
487
493
|
return {
|
|
488
|
-
system: "You are a meticulous fact + citation reviewer for a long-form research report. Propose ONLY targeted, exact-match edits \u2014 never a rewrite. Each edit's `find` MUST be a verbatim substring of the chapter that occurs EXACTLY ONCE, and `replace` must keep every citation [n] within the valid range. Fix wrong/missing citations, unsupported or overstated claims, and factual errors against the analysis + bibliography. Output ONLY a JSON object \u2014 no prose, no fences."
|
|
494
|
+
system: "You are a meticulous fact + citation reviewer for a long-form research report. Propose ONLY targeted, exact-match edits \u2014 never a rewrite. Each edit's `find` MUST be a verbatim substring of the chapter that occurs EXACTLY ONCE, and `replace` must keep every citation [n] within the valid range. Fix wrong/missing citations, unsupported or overstated claims, and factual errors against the analysis + bibliography. Output ONLY a JSON object \u2014 no prose, no fences." + (ctx.rules ? `
|
|
495
|
+
|
|
496
|
+
${ctx.rules}` : ""),
|
|
489
497
|
prompt: `Review the chapter "${ctx.chapter.title}". Valid citations are [1]..[${ctx.bibMax}].
|
|
490
498
|
|
|
491
499
|
## Chapter (current text):
|
|
@@ -628,6 +636,49 @@ Aim for about ${target} chapters. Every chapter MUST list at least one facet fro
|
|
|
628
636
|
return { ...parsed.title ? { title: parsed.title } : {}, chapters: parsed.chapters };
|
|
629
637
|
}
|
|
630
638
|
|
|
631
|
-
|
|
639
|
+
// src/report/lint.ts
|
|
640
|
+
var TOP_LEVEL_KEYS = new Set(Object.keys(reportConfigSchema.shape));
|
|
641
|
+
var CHAPTER_KEYS = new Set(Object.keys(reportChapterSchema.shape));
|
|
642
|
+
var ALIASES = {
|
|
643
|
+
brief: "cover",
|
|
644
|
+
claimCap: "cap",
|
|
645
|
+
keywords: "kw",
|
|
646
|
+
maxClaims: "cap"
|
|
647
|
+
};
|
|
648
|
+
var INFORMATIONAL = /* @__PURE__ */ new Set(["subtitle", "writer", "citationStyle", "render"]);
|
|
649
|
+
function lintKeys(obj, known, where) {
|
|
650
|
+
const out = [];
|
|
651
|
+
for (const key of Object.keys(obj)) {
|
|
652
|
+
if (known.has(key)) continue;
|
|
653
|
+
const alias = ALIASES[key];
|
|
654
|
+
if (alias) {
|
|
655
|
+
out.push(`WARN ${where}.${key} \u2014 unknown key, did you mean "${alias}"?`);
|
|
656
|
+
} else if (INFORMATIONAL.has(key)) {
|
|
657
|
+
out.push(`INFO ${where}.${key} \u2014 not read by the engine (informational)`);
|
|
658
|
+
} else {
|
|
659
|
+
out.push(`WARN ${where}.${key} \u2014 unknown key (not read by the engine)`);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return out;
|
|
663
|
+
}
|
|
664
|
+
function lintReportConfig(config) {
|
|
665
|
+
if (typeof config !== "object" || config === null) return [];
|
|
666
|
+
const top = config;
|
|
667
|
+
const messages = lintKeys(top, TOP_LEVEL_KEYS, "config");
|
|
668
|
+
const chapters = top.chapters;
|
|
669
|
+
if (Array.isArray(chapters)) {
|
|
670
|
+
chapters.forEach((chapter, i) => {
|
|
671
|
+
if (typeof chapter !== "object" || chapter === null) return;
|
|
672
|
+
const id = chapter.id;
|
|
673
|
+
const where = `chapters[${i}]${typeof id === "string" ? ` (${id})` : ""}`;
|
|
674
|
+
messages.push(
|
|
675
|
+
...lintKeys(chapter, CHAPTER_KEYS, where)
|
|
676
|
+
);
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
return messages;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
export { analyzeDataset, applyEdits, assembleChapters, bibEntrySchema, buildChapterWritePrompt, buildFacetAnalysisPrompt, buildPacks, buildReportContent, buildReviewPrompt, citesOf, cleanDraft, collectReportSections, lintReportConfig, outOfRangeCites, planOutline, reportChapterSchema, reportConfigSchema, reportContentSchema, reportContentToMarkdown, reportCoverFactSchema, reportCoverPageSchema, reportCoverSchema, reportPartSchema, reportSectionKindSchema, reportSectionSchema, reviewChapter, runModel, stitchReport, writeChapter };
|
|
632
683
|
//# sourceMappingURL=index.mjs.map
|
|
633
684
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/report/packs.ts","../../src/report/cites.ts","../../src/report/assemble.ts","../../src/report/content.ts","../../src/report/stitch.ts","../../src/report/apply-edits.ts","../../src/report/model.ts","../../src/report/analyze.ts","../../src/report/write.ts","../../src/report/review.ts","../../src/report/types.ts","../../src/report/plan.ts"],"names":["z","extractJson"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * buildPacks — materialize a corpus dataset into per-chapter knowledge views\n * (the L2 \"marts\" of the pipeline) + a global citation bibliography.\n *\n * PURE: reads the dataset through an injected read-only `FsPort` and RETURNS\n * the files to write — it never writes. The frontend (CLI / AIP tool) owns\n * the report-rooted writer, so the dataset stays read-only to this module\n * (invariant 1). This is the single source of truth that both the Claude\n * `build-packs.mjs` and the AIP `corpus.report-packs` tool delegate to,\n * porting the skill's semantics (the authoritative reference).\n *\n * Global [n] citation numbering: every source in the dataset gets one stable\n * number (facet-ordered, then title); each distilled entry cites its sources\n * by those numbers. Chapter routing = facet match + keyword needles + cap.\n */\n\nimport matter from \"gray-matter\"\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport type { ReportConfig } from \"./types.js\"\n\nexport interface PackFile {\n /** Path relative to the report root (e.g. `views/_bibliography.json`). */\n readonly path: string\n readonly content: string\n}\n\nexport interface BuildPacksResult {\n /** All files to write under the report root, in deterministic order. */\n readonly files: readonly PackFile[]\n /** Number of sources in the global bibliography. */\n readonly bibliography: number\n /** Per-chapter view summary. */\n readonly chapters: ReadonlyArray<{\n readonly id: string\n readonly title: string\n readonly entryCount: number\n }>\n}\n\nexport interface BuildPacksOptions {\n /** Read-only view of the dataset (sources/ + entries/). */\n readonly dataset: FsPort\n readonly config: ReportConfig\n /**\n * Subdir under the report root for the views + bibliography. Default\n * `views`; the parity path against the legacy on-disk corpora passes\n * `packs`. Also embedded in each view's \"Also read\" pointer text.\n */\n readonly viewsDir?: string\n}\n\ninterface SourceMeta {\n id: string\n title: string\n url: string\n tags: string[]\n n?: number\n}\n\ninterface EntryMeta {\n kind: string\n title: string\n /** Raw confidence as authored (number or string) — string-compared on ties. */\n conf: number | string\n tags: string[]\n ns: number[]\n gist: string\n}\n\n/** flat(v) — join arrays with space, \"\" for null/undefined, else String(v). */\nconst flat = (v: unknown): string =>\n Array.isArray(v) ? v.join(\" \") : v == null ? \"\" : String(v)\n\nconst asTags = (v: unknown): string[] =>\n Array.isArray(v) ? (v as string[]) : v ? [String(v)] : []\n\nconst firstSentence = (body: string): string => {\n const txt = body.replace(/^#.*$/gm, \"\").replace(/\\s+/g, \" \").trim()\n return (txt.split(/(?<=[.!?])\\s/)[0] || txt).slice(0, 260)\n}\n\n/** Read every `.md` under `dir` in the FsPort's native walk order. */\nasync function walkMd(dataset: FsPort, dir: string): Promise<string[]> {\n let rels: readonly string[]\n try {\n rels = await dataset.walk(dir)\n } catch {\n return []\n }\n return rels.filter((r) => r.endsWith(\".md\")).map((r) => `${dir}/${r}`)\n}\n\nexport async function buildPacks(\n opts: BuildPacksOptions\n): Promise<BuildPacksResult> {\n const { dataset, config } = opts\n const viewsDir = opts.viewsDir ?? \"views\"\n const facetOrder = [...new Set(config.chapters.flatMap((c) => c.facets ?? []))]\n\n // ── sources → global bibliography ──────────────────────────────────────\n const sources: SourceMeta[] = []\n for (const path of await walkMd(dataset, \"sources\")) {\n let raw: string\n try {\n raw = await dataset.readFile(path)\n } catch {\n continue\n }\n let fm: Record<string, unknown> = {}\n try {\n fm = matter(raw).data as Record<string, unknown>\n } catch {\n fm = {}\n }\n const id = flat(fm.id).trim()\n if (!id) continue\n const corpusMeta =\n ((fm.metadata as Record<string, unknown> | undefined)?.corpus as\n | Record<string, unknown>\n | undefined) ?? {}\n const url = String(\n corpusMeta.originalUrl ?? corpusMeta.importerSourceUrl ?? \"\"\n )\n .replace(/\\s+/g, \"\")\n .trim()\n sources.push({\n id,\n title: flat(fm.title).replace(/\\s+/g, \" \").trim(),\n url,\n tags: asTags(fm.tags),\n })\n }\n\n const facetOf = (s: SourceMeta): string =>\n facetOrder.find((f) => s.tags.includes(f)) ?? \"other\"\n sources.sort((a, b) => {\n const fa = facetOrder.indexOf(facetOf(a))\n const fb = facetOrder.indexOf(facetOf(b))\n if (fa !== fb) return (fa < 0 ? 99 : fa) - (fb < 0 ? 99 : fb)\n return a.title.localeCompare(b.title)\n })\n const idToN = new Map<string, number>()\n sources.forEach((s, i) => {\n s.n = i + 1\n idToN.set(s.id, i + 1)\n })\n\n // ── entries ────────────────────────────────────────────────────────────\n const entries: EntryMeta[] = []\n for (const path of await walkMd(dataset, \"entries\")) {\n let raw: string\n try {\n raw = await dataset.readFile(path)\n } catch {\n continue\n }\n let parsed: matter.GrayMatterFile<string>\n try {\n parsed = matter(raw)\n } catch {\n continue\n }\n const fm = parsed.data as Record<string, unknown>\n const title = flat(fm.title).replace(/\\s+/g, \" \").trim()\n if (!title) continue\n const segs = path.replace(/^entries\\//, \"\").split(\"/\")\n const kind =\n typeof fm.kind === \"string\" && fm.kind\n ? fm.kind\n : (segs.slice(-2)[0] ?? \"unknown\")\n const srcs = asTags(fm.sources).map((s) => flat(s).replace(/\\s+/g, \"\").trim())\n const ns = [\n ...new Set(srcs.map((id) => idToN.get(id)).filter((n): n is number => !!n)),\n ].sort((a, b) => a - b)\n entries.push({\n kind,\n title,\n conf: (fm.confidence as number | string | undefined) ?? \"\",\n tags: asTags(fm.tags),\n ns,\n gist: firstSentence(parsed.content),\n })\n }\n\n // ── outputs ────────────────────────────────────────────────────────────\n const files: PackFile[] = []\n files.push({\n path: `${viewsDir}/_bibliography.json`,\n content: JSON.stringify({ sources }, null, 2),\n })\n files.push({\n path: `${viewsDir}/_bibliography.md`,\n content:\n \"# Bibliography (global citation index)\\n\\n\" +\n sources.map((s) => `${s.n}. ${s.title || s.id} — ${s.url}`).join(\"\\n\") +\n \"\\n\",\n })\n\n const chapters: Array<{ id: string; title: string; entryCount: number }> = []\n for (const ch of config.chapters) {\n const facets = ch.facets ?? []\n const kw = (ch.kw ?? []).map((s) => s.toLowerCase())\n const seen = new Set<string>()\n const scored: Array<{ e: EntryMeta; hits: number }> = []\n for (const e of entries) {\n if (!facets.some((f) => e.tags.includes(f))) continue\n const hay = `${e.title} ${e.tags.join(\" \")} ${e.gist}`.toLowerCase()\n const hits = kw.filter((k) => hay.includes(k)).length\n if (kw.length && hits === 0) continue\n const key = e.title.toLowerCase().slice(0, 50)\n if (seen.has(key)) continue\n seen.add(key)\n scored.push({ e, hits })\n }\n scored.sort(\n (a, b) =>\n b.hits - a.hits ||\n String(b.e.conf).localeCompare(String(a.e.conf))\n )\n const picks = scored.slice(0, ch.cap ?? 28).map((x) => x.e)\n const srcFiles = [...new Set(facets.map((f) => `sources.${f}.md`))]\n const lines = picks.map(\n (e) =>\n `- **[${e.kind}]** ${e.title}${e.conf ? ` _(conf ${e.conf})_` : \"\"} ` +\n `${e.ns.length ? `[${e.ns.join(\",\")}]` : \"[uncited]\"}\\n ${e.gist}`\n )\n files.push({\n path: `${viewsDir}/${ch.id}.md`,\n content:\n `# Pack — ${ch.title}\\n\\n` +\n `**Facets:** ${facets.join(\", \")} · **${picks.length} distilled claims** ` +\n `(each tagged with its global source number [n]).\\n\\n` +\n `**Also read for full context + exact quotes/URLs:** ${srcFiles.join(\", \")} ` +\n `(in the corpus root), and ${viewsDir}/_bibliography.md.\\n\\n` +\n `## Distilled claims for this chapter\\n\\n${lines.join(\"\\n\")}\\n`,\n })\n chapters.push({ id: ch.id, title: ch.title, entryCount: picks.length })\n }\n\n return { files, bibliography: sources.length, chapters }\n}\n","/**\n * Citation helpers shared across the report glue. A citation is `[n]` or\n * `[n, m, …]` referencing the global bibliography index.\n */\n\n/** Every citation number referenced in a string (flattening `[a, b]`). */\nexport function citesOf(s: string): number[] {\n return [...s.matchAll(/\\[(\\d{1,3}(?:,\\s*\\d{1,3})*)\\]/g)].flatMap((m) =>\n m[1]!.split(\",\").map((n) => parseInt(n.trim(), 10))\n )\n}\n\n/** Citation numbers in `s` outside the valid `[1, bibMax]` range. */\nexport function outOfRangeCites(s: string, bibMax: number): number[] {\n return [...new Set(citesOf(s).filter((n) => n < 1 || n > bibMax))]\n}\n","/**\n * assembleChapters — turn the write step's raw per-chapter drafts into clean\n * chapter files. Pure: in-memory drafts → files to write (the caller owns the\n * report-rooted writer). Mechanical only — strips agent preambles, normalizes\n * `[a→b]` cross-refs to `[b]`, collapses blank runs; no model calls.\n */\n\nimport type { PackFile } from \"./packs.js\"\nimport { outOfRangeCites } from \"./cites.js\"\n\nexport interface ChapterDraft {\n /** Chapter id (= `<chaptersDir>/<ch>.md`). */\n readonly ch: string\n readonly draft: string\n}\n\nexport interface AssembleResult {\n readonly files: readonly PackFile[]\n readonly stats: {\n readonly chapters: number\n readonly preamblesStripped: number\n readonly withOutOfRangeCites: number\n readonly outOfRange: ReadonlyArray<{ ch: string; cites: number[] }>\n }\n}\n\nexport interface AssembleOptions {\n readonly chapters: readonly ChapterDraft[]\n /** Highest valid citation [n]; cites above it are flagged (not dropped). */\n readonly bibMax: number\n /** Subdir under the report root for chapter files. Default `chapters`. */\n readonly chaptersDir?: string\n}\n\nconst PREAMBLE = /^\\s*(?:I have|I'll|Here is|Here's|Writing|Let me|Okay|Done)/i\nconst CROSSREF = /\\[(\\d{1,3})\\s*(?:→|->|—>|to see|see)\\s*(?:see\\s*)?(\\d{1,3})\\]/g\n\n/** Drop any leading agent chatter before the first \"## \" and tidy whitespace. */\nexport function cleanDraft(draft: string | undefined): string {\n if (!draft) return \"\"\n let s = draft.replace(/\\r/g, \"\")\n const i = s.indexOf(\"## \")\n if (i > 0) s = s.slice(i)\n s = s.replace(CROSSREF, \"[$2]\")\n return s.replace(/\\n{3,}/g, \"\\n\\n\").trim()\n}\n\nexport function assembleChapters(opts: AssembleOptions): AssembleResult {\n const chaptersDir = opts.chaptersDir ?? \"chapters\"\n const files: PackFile[] = []\n let preamblesStripped = 0\n const outOfRange: Array<{ ch: string; cites: number[] }> = []\n\n for (const c of opts.chapters) {\n const body = cleanDraft(c.draft)\n if (PREAMBLE.test(c.draft || \"\")) preamblesStripped++\n if (body) files.push({ path: `${chaptersDir}/${c.ch}.md`, content: body + \"\\n\" })\n const oor = outOfRangeCites(body, opts.bibMax)\n if (oor.length) outOfRange.push({ ch: c.ch, cites: oor })\n }\n\n return {\n files,\n stats: {\n chapters: opts.chapters.length,\n preamblesStripped,\n withOutOfRangeCites: outOfRange.length,\n outOfRange,\n },\n }\n}\n","/**\n * ReportContent — the ONE medium-agnostic shape of a finished report.\n *\n * `buildReportContent` reads the report root (config + chapters/ + the\n * bibliography view) and RETURNS the structured content: an ordered list of\n * sections (each raw markdown) plus the structured bibliography and document\n * metadata. It is PURE and port-injected like the rest of the engine — it\n * never touches the dataset and never renders HTML/PDF (no Chrome here).\n *\n * Every render medium is an AIP `render.*` tool whose input is a\n * `ReportContent`; the canvakit driver (in `@canvakit/report`) is the only\n * place HTML/PDF lives. The markdown medium is reconstructed losslessly by\n * `reportContentToMarkdown` — which is exactly what `stitchReport` emits, so\n * REPORT.md byte-parity is preserved (the two share `collectReportSections`).\n */\n\nimport { z } from \"zod\"\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport type { ReportConfig } from \"./types.js\"\n\n/** What role a section plays in the document. */\nexport const reportSectionKindSchema = z.enum([\n \"front\",\n \"part\",\n \"chapter\",\n \"annexes\",\n \"sources\",\n])\n\n/** One contiguous unit of a report (front, a part divider, a chapter, …). */\nexport const reportSectionSchema = z.object({\n /** Stable id — chapter id, or `_front`/`_annexes`/`_sources` for the glue. */\n id: z.string(),\n /** Human label (heading text, leading `#`s stripped). May be \"\". */\n title: z.string(),\n /** The section's raw markdown, exactly as it appears in REPORT.md. */\n markdown: z.string(),\n kind: reportSectionKindSchema,\n})\n\n/** One global citation source (mirrors `views/_bibliography.json`). */\nexport const bibEntrySchema = z.object({\n n: z.number(),\n id: z.string(),\n title: z.string(),\n url: z.string(),\n})\n\n/**\n * The medium-agnostic content a `render.*` tool consumes — the single source\n * of truth for \"what a report's content is\". Zod so the render tool schemas\n * can embed it directly (one definition across the engine and every renderer).\n */\nexport const reportContentSchema = z.object({\n title: z.string(),\n sections: z.array(reportSectionSchema),\n bibliography: z\n .object({\n mode: z.literal(\"numbered\"),\n entries: z.array(bibEntrySchema),\n })\n .optional(),\n /** Document metadata (brand · subtitle · tag · custodian) — presentation-free. */\n meta: z.record(z.string(), z.string()).optional(),\n})\n\nexport type ReportSection = z.infer<typeof reportSectionSchema>\nexport type BibEntry = z.infer<typeof bibEntrySchema>\nexport type ReportContent = z.infer<typeof reportContentSchema>\n\nexport interface CollectSectionsOptions {\n readonly config: ReportConfig\n /** Read-side view of the report root (chapters/ + views/ + front/annexes). */\n readonly report: FsPort\n /** Subdir holding the written chapter files. Default `chapters`. */\n readonly chaptersDir?: string\n /** Subdir holding the bibliography. Default `views`. */\n readonly viewsDir?: string\n}\n\nconst stripHeading = (s: string): string => s.replace(/^#+\\s*/, \"\").trim()\n\n/**\n * Collect a report's ordered sections from the report root. This is the\n * single read path shared by `stitchReport` (markdown medium) and\n * `buildReportContent` (every other medium), so the section boundaries — and\n * therefore REPORT.md — are identical regardless of the consumer.\n *\n * Order: front? · (parts ? part-heading + its chapters : chapters in config\n * order) · annexes? · Sources (from the bibliography). Mirrors the legacy\n * stitch exactly; all reads are report-side (the dataset is never touched).\n */\nexport async function collectReportSections(\n opts: CollectSectionsOptions\n): Promise<ReportSection[]> {\n const { config, report } = opts\n const chaptersDir = opts.chaptersDir ?? \"chapters\"\n const viewsDir = opts.viewsDir ?? \"views\"\n\n const rd = async (p: string): Promise<string> =>\n (await report.readFile(p)).trim()\n const rdOpt = async (p: string): Promise<string | null> => {\n try {\n return await rd(p)\n } catch {\n return null\n }\n }\n const titleOf = (id: string): string =>\n config.chapters.find((c) => c.id === id)?.title ?? id\n\n const sections: ReportSection[] = []\n\n const front = await rdOpt(config.frontFile ?? `${chaptersDir}/_front.md`)\n if (front) sections.push({ id: \"_front\", title: \"\", markdown: front, kind: \"front\" })\n\n if (config.parts && config.parts.length) {\n for (const part of config.parts) {\n sections.push({\n id: stripHeading(part.heading).toLowerCase().replace(/[^a-z0-9]+/g, \"-\"),\n title: stripHeading(part.heading),\n markdown: part.heading,\n kind: \"part\",\n })\n for (const id of part.chapters ?? []) {\n sections.push({\n id,\n title: titleOf(id),\n markdown: await rd(`${chaptersDir}/${id}.md`),\n kind: \"chapter\",\n })\n }\n }\n } else {\n for (const c of config.chapters) {\n sections.push({\n id: c.id,\n title: c.title,\n markdown: await rd(`${chaptersDir}/${c.id}.md`),\n kind: \"chapter\",\n })\n }\n }\n\n if (config.annexesFile) {\n const annexes = await rdOpt(config.annexesFile)\n if (annexes)\n sections.push({ id: \"_annexes\", title: \"Annexes\", markdown: annexes, kind: \"annexes\" })\n }\n\n const bib = (await rd(`${viewsDir}/_bibliography.md`))\n .replace(/^# Bibliography.*$/m, \"\")\n .trim()\n sections.push({\n id: \"_sources\",\n title: \"Sources\",\n markdown: \"## Sources\\n\\n\" + bib,\n kind: \"sources\",\n })\n\n return sections\n}\n\n/**\n * Reconstruct the canonical REPORT.md from collected sections. Byte-identical\n * to the legacy stitch output (`out.join(\"\\n\\n\") + \"\\n\"`).\n */\nexport function reportContentToMarkdown(\n sections: readonly ReportSection[]\n): string {\n return sections.map((s) => s.markdown).join(\"\\n\\n\") + \"\\n\"\n}\n\nexport type BuildReportContentOptions = CollectSectionsOptions\n\n/**\n * Build the medium-agnostic {@link ReportContent} for a report. Pure: reads\n * the report root through the injected FsPort and returns structured content —\n * the single input every `render.*` tool consumes.\n */\nexport async function buildReportContent(\n opts: BuildReportContentOptions\n): Promise<ReportContent> {\n const { config, report } = opts\n const viewsDir = opts.viewsDir ?? \"views\"\n\n const sections = await collectReportSections(opts)\n\n // Title: explicit config, else the first H1 in the front matter, else fallback.\n let title = config.title?.trim() ?? \"\"\n if (!title) {\n const front = sections.find((s) => s.kind === \"front\")\n title = front?.markdown.match(/^#\\s+(.+)$/m)?.[1]?.trim() ?? \"Report\"\n }\n\n // Structured bibliography from the JSON view (the .md is for the Sources block).\n let bibliography: ReportContent[\"bibliography\"]\n try {\n const raw = await report.readFile(`${viewsDir}/_bibliography.json`)\n const parsed = JSON.parse(raw) as { sources?: unknown }\n const src = Array.isArray(parsed.sources) ? parsed.sources : []\n const entries: BibEntry[] = src.map((s) => {\n const o = (s ?? {}) as Record<string, unknown>\n return {\n n: typeof o.n === \"number\" ? o.n : 0,\n id: typeof o.id === \"string\" ? o.id : \"\",\n title: typeof o.title === \"string\" ? o.title : \"\",\n url: typeof o.url === \"string\" ? o.url : \"\",\n }\n })\n if (entries.length) bibliography = { mode: \"numbered\", entries }\n } catch {\n // No bibliography view — content is still valid without one.\n }\n\n // Document metadata — presentation-free scalars from the cover, if present.\n const meta: Record<string, string> = {}\n const cover = config.cover\n if (cover) {\n for (const k of [\"brand\", \"subtitle\", \"tag\", \"meta\"] as const) {\n const v = cover[k]\n if (typeof v === \"string\" && v.trim()) meta[k] = v.trim()\n }\n }\n if (config.profile) meta.profile = config.profile\n\n return {\n title,\n sections,\n ...(bibliography ? { bibliography } : {}),\n ...(Object.keys(meta).length ? { meta } : {}),\n }\n}\n","/**\n * stitchReport — assemble the final REPORT.md = front + part dividers +\n * chapters + annexes + a Sources section (from the global bibliography), per\n * the config's `parts[]`. Pure: reads report-side files through an injected\n * FsPort and RETURNS the document string (the caller writes REPORT.md).\n *\n * It is the markdown render medium: `stitchReport === reportContentToMarkdown\n * ∘ collectReportSections`. The shared section collection guarantees the\n * markdown medium and every `render.*` tool see the exact same boundaries.\n *\n * All reads are report-side (chapters + views) — the dataset is not touched.\n */\n\nimport { collectReportSections, reportContentToMarkdown } from \"./content.js\"\nimport type { CollectSectionsOptions } from \"./content.js\"\n\nexport type StitchOptions = CollectSectionsOptions\n\nexport interface StitchResult {\n readonly content: string\n readonly wordCount: number\n}\n\nexport async function stitchReport(opts: StitchOptions): Promise<StitchResult> {\n const sections = await collectReportSections(opts)\n const content = reportContentToMarkdown(sections)\n const wordCount = sections\n .map((s) => s.markdown)\n .join(\" \")\n .split(/\\s+/).length\n return { content, wordCount }\n}\n","/**\n * applyEdits — apply {find, replace, reason} edits (from the fix step) to\n * chapter files by EXACT match. An edit lands only if `find` occurs exactly\n * once AND `replace` adds no out-of-range [n]; everything else is reported,\n * not forced. A chapter is written only if at least one edit applied and the\n * post-check passes (still starts at \"## \", no out-of-range cites).\n *\n * Reads chapter files through an injected FsPort; RETURNS the writes + a\n * human-readable apply report (the caller owns the writer).\n */\n\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport type { PackFile } from \"./packs.js\"\nimport { outOfRangeCites } from \"./cites.js\"\n\nexport interface ChapterEdit {\n readonly find?: string\n readonly replace?: string\n readonly reason?: string\n}\n\nexport interface ChapterEditSet {\n readonly id: string\n readonly edits?: readonly ChapterEdit[]\n}\n\nexport interface ApplyEditsResult {\n /** Chapter files to (over)write — already post-checked. */\n readonly files: readonly PackFile[]\n /** The fix-apply report markdown. */\n readonly report: string\n readonly stats: {\n readonly filesChanged: number\n readonly applied: number\n readonly skipped: number\n }\n}\n\nexport interface ApplyEditsOptions {\n readonly results: readonly ChapterEditSet[]\n readonly bibMax: number\n /** Read-side view of the report root. */\n readonly report: FsPort\n /** Subdir holding chapter files. Default `chapters`. */\n readonly chaptersDir?: string\n}\n\n/** Count non-overlapping occurrences of `n` in `hay`. */\nfunction occ(hay: string, n: string): number {\n let c = 0\n let i = 0\n while ((i = hay.indexOf(n, i)) !== -1) {\n c++\n i += n.length\n }\n return c\n}\n\nexport async function applyEdits(\n opts: ApplyEditsOptions\n): Promise<ApplyEditsResult> {\n const chaptersDir = opts.chaptersDir ?? \"chapters\"\n const files: PackFile[] = []\n let md =\n \"# Fix-apply report (edit-based)\\n\\n\" +\n \"Each edit lands only if `find` matches exactly once and `replace` adds no out-of-range [n].\\n\\n\"\n let applied = 0\n let skipped = 0\n let filesChanged = 0\n\n for (const r of opts.results) {\n const path = `${chaptersDir}/${r.id}.md`\n let text = await opts.report.readFile(path)\n const edits = r.edits ?? []\n let n = 0\n md += `## ${r.id} — ${edits.length} proposed edit(s)\\n`\n for (const e of edits) {\n const find = e.find ?? \"\"\n const replace = e.replace ?? \"\"\n const oor = outOfRangeCites(replace, opts.bibMax)\n const count = find ? occ(text, find) : 0\n let status: string\n if (!find) status = \"SKIP (empty find)\"\n else if (count === 0) status = \"SKIP (find not matched verbatim)\"\n else if (count > 1) status = `SKIP (find matches ${count}× — ambiguous)`\n else if (oor.length)\n status = `SKIP (replace adds out-of-range cite ${oor.join(\",\")})`\n else {\n text = text.replace(find, replace)\n n++\n status = \"✅ applied\"\n }\n md += `- ${status} — _${e.reason || \"\"}_\\n`\n if (status.startsWith(\"✅\")) {\n md +=\n ` find: ${JSON.stringify(find.slice(0, 200))}\\n` +\n ` replace: ${JSON.stringify(replace.slice(0, 200))}\\n`\n }\n }\n const post: string[] = []\n if (!text.startsWith(\"## \")) post.push(\"no longer starts at '##'\")\n const oorAll = outOfRangeCites(text, opts.bibMax)\n if (oorAll.length) post.push(`out-of-range cites present: ${oorAll.join(\",\")}`)\n if (post.length)\n md += `- ⚠️ POST-CHECK FAILED (${post.join(\"; \")}) → NOT written\\n`\n else if (n > 0) {\n files.push({ path, content: text })\n filesChanged++\n }\n applied += n\n skipped += edits.length - n\n md += `- result: ${n}/${edits.length} applied${post.length ? \" (reverted)\" : \"\"}\\n\\n`\n }\n\n return { files, report: md, stats: { filesChanged, applied, skipped } }\n}\n","/**\n * ReportModelPort — the minimal model seam the report's model steps consume.\n *\n * Structural, not nominal: the AIP `ModelPort` (`complete({system?, prompt}) →\n * {result}`) satisfies it as-is, so the same engine runs under any registered\n * model. The single-pass functions here ARE the \"model driver\" tier; the\n * higher-fidelity claude-code path (Phase C) reuses the same prompt-builders\n * but swaps the executor for file-reading sub-agents.\n */\n\nexport interface ReportModelInput {\n readonly system?: string\n readonly prompt: string\n}\n\nexport interface ReportModelOutput {\n /** Completion payload — string for text, or a structured object. */\n readonly result: string | unknown\n}\n\nexport interface ReportModelPort {\n complete(input: ReportModelInput): Promise<ReportModelOutput>\n}\n\n/** Run a prompt and coerce the completion to text. */\nexport async function runModel(\n model: ReportModelPort,\n input: ReportModelInput\n): Promise<string> {\n const { result } = await model.complete(input)\n return typeof result === \"string\" ? result : JSON.stringify(result)\n}\n","/**\n * analyze — synthesize the distilled entries of each facet into a structured\n * markdown analysis doc (`sources.<facet>.md`), the deeper context the chapter\n * writer reads. A report-side step (invariant 3): it READS the dataset's\n * entries and RETURNS report-rooted files; it never writes the dataset.\n */\n\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport { resolveKnowledge } from \"../knowledge/resolve.js\"\nimport type { PackFile } from \"./packs.js\"\nimport { type ReportModelPort, type ReportModelInput, runModel } from \"./model.js\"\n\nexport interface AnalyzeFacetInput {\n readonly facet: string\n /** Pre-rendered entries block (title/kind/confidence + body per entry). */\n readonly entriesText: string\n}\n\n/** The prompt for one facet's analysis doc — pure, driver-reusable. */\nexport function buildFacetAnalysisPrompt(\n input: AnalyzeFacetInput\n): ReportModelInput {\n return {\n system:\n \"You are a research analyst. Your output is a structured markdown analysis \" +\n \"document that will be used as input to a long-form research bible chapter. \" +\n \"Write in clear, dense prose with H2 headers. No filler, no meta-commentary.\",\n prompt:\n `Synthesize these knowledge entries about the facet \"${input.facet}\" into a structured ` +\n `markdown analysis document for a research bible.\\n\\n` +\n `Include:\\n` +\n `- ## Key Themes: recurring patterns across entries\\n` +\n `- ## Major Findings: the most credible, high-confidence claims\\n` +\n `- ## Notable Examples: concrete worked instances worth citing\\n` +\n `- ## Gaps & Contradictions: what is unknown, disputed, or missing\\n\\n` +\n `ENTRIES:\\n\\n${input.entriesText}`,\n }\n}\n\nexport interface AnalyzeDatasetOptions {\n /** Read-only view of the dataset (entries/). */\n readonly dataset: FsPort\n readonly facets: readonly string[]\n readonly model: ReportModelPort\n}\n\nexport interface AnalyzeDatasetResult {\n /** `sources.<facet>.md` files to write at the report root. */\n readonly files: readonly PackFile[]\n readonly analyzed: number\n /** Facets skipped because they resolved to zero entries. */\n readonly skipped: readonly string[]\n}\n\nexport async function analyzeDataset(\n opts: AnalyzeDatasetOptions\n): Promise<AnalyzeDatasetResult> {\n const files: PackFile[] = []\n const skipped: string[] = []\n\n for (const facet of opts.facets) {\n const entries = await resolveKnowledge({\n fs: opts.dataset,\n query: { tags: [facet] },\n })\n if (entries.length === 0) {\n skipped.push(facet)\n continue\n }\n const entriesText = entries\n .map(\n (e) =>\n `### ${e.title} (${e.kind}, confidence ${e.confidence ?? \"?\"})\\n\\n${e.body}`\n )\n .join(\"\\n\\n---\\n\\n\")\n const content = await runModel(\n opts.model,\n buildFacetAnalysisPrompt({ facet, entriesText })\n )\n files.push({\n path: `sources.${facet}.md`,\n content: `# Analysis: ${facet}\\n\\n${content}`,\n })\n }\n\n return { files, analyzed: files.length, skipped }\n}\n","/**\n * write — the single-pass chapter writer (the \"model driver\" tier). Given a\n * chapter's view (distilled claims + [n] cites), the per-facet analysis, and\n * the bibliography, produce a cited markdown draft.\n *\n * `buildChapterWritePrompt` is pure and exported so the higher-fidelity\n * claude-code driver (Phase C) reuses the identical prompt while swapping the\n * executor for a file-reading sub-agent. `writeChapter` is the model-driver\n * executor. Output is a raw DRAFT — `assembleChapters` then cleans it.\n */\n\nimport type { ReportChapter } from \"./types.js\"\nimport { type ReportModelPort, type ReportModelInput, runModel } from \"./model.js\"\n\nexport interface ChapterWriteContext {\n readonly chapter: Pick<ReportChapter, \"id\" | \"title\" | \"words\">\n /** Report/document title for framing. */\n readonly title: string\n /** The chapter's view content (distilled claims with [n]). */\n readonly packContent: string\n /** Concatenated per-facet analysis docs (optional deeper context). */\n readonly analysisContext?: string\n /** The global bibliography markdown (for citation verification). */\n readonly bibliography?: string\n}\n\nexport function buildChapterWritePrompt(\n ctx: ChapterWriteContext\n): ReportModelInput {\n const words = ctx.chapter.words ?? \"800-1500\"\n return {\n system:\n \"You are an expert research writer. Write in clear, dense, well-structured prose. \" +\n \"Every non-obvious claim must be cited inline as [n] from the Bibliography. \" +\n \"Use Markdown H2 and H3 subheaders within the chapter. No meta-commentary or filler. \" +\n `Aim for ${words} words.`,\n prompt:\n `Write the chapter \"${ctx.chapter.title}\" for the research document \"${ctx.title}\".\\n\\n` +\n `## Distilled claims for this chapter (with citation numbers):\\n\\n${ctx.packContent}\\n\\n` +\n (ctx.analysisContext\n ? `## Per-facet analysis (for deeper context):\\n\\n${ctx.analysisContext}\\n\\n`\n : \"\") +\n `## Bibliography (for citation verification):\\n\\n${ctx.bibliography ?? \"\"}\\n\\n` +\n `Write the chapter now. Start with the \"## ${ctx.chapter.title}\" heading, then the content.`,\n }\n}\n\n/** Single-pass chapter write → a `{ ch, draft }` ready for assembleChapters. */\nexport async function writeChapter(\n ctx: ChapterWriteContext,\n model: ReportModelPort\n): Promise<{ ch: string; draft: string }> {\n const draft = await runModel(model, buildChapterWritePrompt(ctx))\n return { ch: ctx.chapter.id, draft }\n}\n","/**\n * review — the single-pass chapter reviewer (the \"model driver\" tier of the\n * quality loop). Given a chapter's current prose, its per-facet analysis, and\n * the bibliography, the model returns a set of EXACT-MATCH `{find, replace,\n * reason}` edits that `applyEdits` can land verbatim (fact/citation fixes,\n * overstatement trims). It never rewrites the chapter — only proposes targeted,\n * verifiable edits, so the fix step stays deterministic.\n *\n * `buildReviewPrompt` is pure + exported so the claude-code driver reuses it.\n */\n\nimport { z } from \"zod\"\nimport type { ChapterEdit, ChapterEditSet } from \"./apply-edits.js\"\nimport { type ReportModelPort, type ReportModelInput, runModel } from \"./model.js\"\n\nexport interface ChapterReviewContext {\n readonly chapter: { readonly id: string; readonly title: string }\n /** The chapter's current markdown (what gets reviewed). */\n readonly chapterText: string\n /** Concatenated per-facet analysis docs (the ground truth to check against). */\n readonly analysisContext?: string\n /** The global bibliography markdown (citation range + targets). */\n readonly bibliography?: string\n /** Highest valid citation [n] — replacements must not exceed it. */\n readonly bibMax: number\n}\n\nexport function buildReviewPrompt(ctx: ChapterReviewContext): ReportModelInput {\n return {\n system:\n \"You are a meticulous fact + citation reviewer for a long-form research report. \" +\n \"Propose ONLY targeted, exact-match edits — never a rewrite. Each edit's `find` \" +\n \"MUST be a verbatim substring of the chapter that occurs EXACTLY ONCE, and \" +\n \"`replace` must keep every citation [n] within the valid range. Fix wrong/missing \" +\n \"citations, unsupported or overstated claims, and factual errors against the \" +\n \"analysis + bibliography. Output ONLY a JSON object — no prose, no fences.\",\n prompt:\n `Review the chapter \"${ctx.chapter.title}\". Valid citations are [1]..[${ctx.bibMax}].\\n\\n` +\n `## Chapter (current text):\\n\\n${ctx.chapterText}\\n\\n` +\n (ctx.analysisContext\n ? `## Per-facet analysis (ground truth):\\n\\n${ctx.analysisContext}\\n\\n`\n : \"\") +\n `## Bibliography:\\n\\n${ctx.bibliography ?? \"\"}\\n\\n` +\n `Return JSON: { \"edits\": [ { \"find\": \"<verbatim once-occurring span>\", ` +\n `\"replace\": \"<corrected span>\", \"reason\": \"<short why>\" } ] }. ` +\n `Return { \"edits\": [] } if the chapter is clean.`,\n }\n}\n\nconst reviewSchema = z.object({\n edits: z\n .array(\n z.object({\n find: z.string().optional(),\n replace: z.string().optional(),\n reason: z.string().optional(),\n })\n )\n .default([]),\n})\n\n/** Best-effort extraction of a JSON object from a model completion. */\nfunction extractJson(text: string): unknown {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n const body = fenced ? fenced[1]! : text\n const start = body.indexOf(\"{\")\n const end = body.lastIndexOf(\"}\")\n if (start === -1 || end === -1) return { edits: [] }\n try {\n return JSON.parse(body.slice(start, end + 1))\n } catch {\n return { edits: [] }\n }\n}\n\n/**\n * Single-pass chapter review → a {@link ChapterEditSet} ready for\n * `applyEdits`. Tolerant: a malformed completion yields no edits (the chapter\n * is left untouched) rather than throwing — review is an enhancement, not a gate.\n */\nexport async function reviewChapter(\n ctx: ChapterReviewContext,\n model: ReportModelPort\n): Promise<ChapterEditSet> {\n const text = await runModel(model, buildReviewPrompt(ctx))\n const parsed = reviewSchema.safeParse(extractJson(text))\n const edits: ChapterEdit[] = parsed.success ? parsed.data.edits : []\n return { id: ctx.chapter.id, edits }\n}\n","/**\n * ReportConfig — the single source of truth for a long-form report rendered\n * from a corpus dataset. Superset of the two pre-existing shapes (the Claude\n * bible toolkit's `bible.config.json` + the AIP `bibleConfigSchema`); the\n * authoring reference is `.claude/skills/deep-research/bible/config.schema.md`.\n *\n * Validated with zod (NOT AJV — avoids corpus-cli's findSpecsRoot). Unknown\n * keys pass through so presentation/render fields the engine doesn't read\n * (covers, header/footer, parts) survive a parse round-trip untouched.\n */\n\nimport { z } from \"zod\"\n\n/** A key/value fact rendered on a branded cover (`facts[]`). */\nexport const reportCoverFactSchema = z\n .object({ k: z.string(), v: z.string() })\n .passthrough()\n\n/** One extra full-bleed cover (front or back). Data → one shared template. */\nexport const reportCoverPageSchema = z\n .object({\n kicker: z.string().optional(),\n title: z.string().optional(),\n meta: z.string().optional(),\n tag: z.string().optional(),\n align: z.string().optional(),\n facts: z.array(reportCoverFactSchema).optional(),\n })\n .passthrough()\n\n/** The title cover (1re de couverture). */\nexport const reportCoverSchema = z\n .object({\n brand: z.string().optional(),\n subtitle: z.string().optional(),\n tag: z.string().optional(),\n meta: z.string().optional(),\n brandLetterSpacing: z.string().optional(),\n brandFontSize: z.string().optional(),\n })\n .passthrough()\n\n/** A part grouping that drives stitch ordering. */\nexport const reportPartSchema = z\n .object({\n heading: z.string(),\n chapters: z.array(z.string()).default([]),\n })\n .passthrough()\n\n/**\n * One report unit. Carries BOTH write fields (words/src/cover) and\n * pack-routing fields (facets/kw/cap). `id` doubles as the view filename\n * and the `<id>.md` chapter source.\n */\nexport const reportChapterSchema = z\n .object({\n /** = view filename + chapter source filename. */\n id: z.string(),\n /** Exact \"## \" heading the writer must use. */\n title: z.string(),\n /** Target length hint for the writer (e.g. \"700–900\"). */\n words: z.string().optional(),\n /** Analysis files (sources.<facet>.md) the writer/reviewer reads. */\n src: z.array(z.string()).optional(),\n /** The writer brief — what this chapter must cover. */\n cover: z.string().optional(),\n /** build-packs: which distilled-entry tags route into this view. */\n facets: z.array(z.string()).default([]),\n /** build-packs: keyword needles that rank (and gate) entries. */\n kw: z.array(z.string()).optional(),\n /** build-packs: max distilled claims in the view (default 28). */\n cap: z.number().optional(),\n })\n .passthrough()\n\nexport const reportConfigSchema = z\n .object({\n /** Dataset path (repo-relative). Legacy `bible.config.json` key. */\n workspace: z.string().optional(),\n /** Pointer to the dataset this report consumes (the portable form). */\n dataset: z.string().optional(),\n /** Multiple datasets feeding one report (1 report → M datasets). */\n corpora: z.array(z.string()).optional(),\n /** Render/prompt profile preset (bible | brief | memo | deck). */\n profile: z.string().optional(),\n /** Highest valid citation [n]; out-of-range = error (used downstream). */\n bibMax: z.number().optional(),\n\n title: z.string().optional(),\n cover: reportCoverSchema.optional(),\n frontCovers: z.array(reportCoverPageSchema).optional(),\n backCovers: z.array(reportCoverPageSchema).optional(),\n runningHeader: z.string().optional(),\n runningFooter: z.string().optional(),\n\n frontFile: z.string().optional(),\n annexesFile: z.string().optional(),\n parts: z.array(reportPartSchema).optional(),\n\n rulesText: z.string().optional(),\n factsText: z.string().optional(),\n briefText: z.string().optional(),\n\n chapters: z.array(reportChapterSchema),\n })\n .passthrough()\n\nexport type ReportCoverFact = z.infer<typeof reportCoverFactSchema>\nexport type ReportCoverPage = z.infer<typeof reportCoverPageSchema>\nexport type ReportCover = z.infer<typeof reportCoverSchema>\nexport type ReportPart = z.infer<typeof reportPartSchema>\nexport type ReportChapter = z.infer<typeof reportChapterSchema>\nexport type ReportConfig = z.infer<typeof reportConfigSchema>\n","/**\n * plan — the auto-outliner. Turns (brief + dataset facets + profile) into a\n * chapter outline, so a report can run from a topic with NO hand-authored\n * config. Model-driven; the returned chapters are zod-validated and carry the\n * routing fields (facets/kw/cap) the pack builder needs.\n */\n\nimport { z } from \"zod\"\nimport { reportChapterSchema, type ReportChapter } from \"./types.js\"\nimport { type ReportModelPort, runModel } from \"./model.js\"\n\nexport interface PlanOutlineOptions {\n /** The research brief / framing (what the report should cover). */\n readonly brief: string\n /** Facets discovered in the dataset (the tags chapters route against). */\n readonly facets: readonly string[]\n /** Profile preset that shapes the unit (bible | brief | memo | deck). */\n readonly profile?: string\n /** Target chapter count (a hint, not a hard cap). */\n readonly targetChapters?: number\n readonly model: ReportModelPort\n}\n\nconst planSchema = z.object({\n title: z.string().optional(),\n chapters: z.array(reportChapterSchema).min(1),\n})\n\nexport interface PlanOutlineResult {\n readonly title?: string\n readonly chapters: readonly ReportChapter[]\n}\n\n/** Best-effort extraction of a JSON object from a model completion. */\nfunction extractJson(text: string): unknown {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n const body = fenced ? fenced[1]! : text\n const start = body.indexOf(\"{\")\n const end = body.lastIndexOf(\"}\")\n if (start === -1 || end === -1) throw new Error(\"plan: no JSON object in completion\")\n return JSON.parse(body.slice(start, end + 1))\n}\n\nexport async function planOutline(\n opts: PlanOutlineOptions\n): Promise<PlanOutlineResult> {\n const profile = opts.profile ?? \"bible\"\n const target = opts.targetChapters ?? 8\n const text = await runModel(opts.model, {\n system:\n \"You are a research editor planning a long-form, citation-backed report. \" +\n \"Output ONLY a JSON object — no prose, no fences.\",\n prompt:\n `Plan a \"${profile}\" report from this brief and the available dataset facets.\\n\\n` +\n `BRIEF:\\n${opts.brief}\\n\\n` +\n `DATASET FACETS (chapters route against these tags):\\n${opts.facets.join(\", \")}\\n\\n` +\n `Return JSON: { \"title\": string, \"chapters\": [ { \"id\": kebab-id, \"title\": \"N. Heading\", ` +\n `\"facets\": [subset of the facets above], \"kw\": [keyword needles], \"cap\": number, ` +\n `\"words\": \"min-max\", \"cover\": \"1-2 sentence writer brief\" } ] }.\\n` +\n `Aim for about ${target} chapters. Every chapter MUST list at least one facet from the list.`,\n })\n const parsed = planSchema.parse(extractJson(text))\n return { ...(parsed.title ? { title: parsed.title } : {}), chapters: parsed.chapters }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/report/packs.ts","../../src/report/cites.ts","../../src/report/assemble.ts","../../src/report/content.ts","../../src/report/stitch.ts","../../src/report/apply-edits.ts","../../src/report/model.ts","../../src/report/analyze.ts","../../src/report/write.ts","../../src/report/review.ts","../../src/report/types.ts","../../src/report/plan.ts","../../src/report/lint.ts"],"names":["z","extractJson"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * buildPacks — materialize a corpus dataset into per-chapter knowledge views\n * (the L2 \"marts\" of the pipeline) + a global citation bibliography.\n *\n * PURE: reads the dataset through an injected read-only `FsPort` and RETURNS\n * the files to write — it never writes. The frontend (CLI / AIP tool) owns\n * the report-rooted writer, so the dataset stays read-only to this module\n * (invariant 1). This is the single source of truth that both the Claude\n * `build-packs.mjs` and the AIP `corpus.report-packs` tool delegate to,\n * porting the skill's semantics (the authoritative reference).\n *\n * Global [n] citation numbering: every source in the dataset gets one stable\n * number (facet-ordered, then title); each distilled entry cites its sources\n * by those numbers. Chapter routing = facet match + keyword needles + cap.\n */\n\nimport matter from \"gray-matter\"\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport type { ReportConfig } from \"./types.js\"\n\nexport interface PackFile {\n /** Path relative to the report root (e.g. `views/_bibliography.json`). */\n readonly path: string\n readonly content: string\n}\n\nexport interface BuildPacksResult {\n /** All files to write under the report root, in deterministic order. */\n readonly files: readonly PackFile[]\n /** Number of sources in the global bibliography. */\n readonly bibliography: number\n /** Per-chapter view summary. */\n readonly chapters: ReadonlyArray<{\n readonly id: string\n readonly title: string\n readonly entryCount: number\n }>\n}\n\nexport interface BuildPacksOptions {\n /** Read-only view of the dataset (sources/ + entries/). */\n readonly dataset: FsPort\n readonly config: ReportConfig\n /**\n * Subdir under the report root for the views + bibliography. Default\n * `views`; the parity path against the legacy on-disk corpora passes\n * `packs`. Also embedded in each view's \"Also read\" pointer text.\n */\n readonly viewsDir?: string\n}\n\ninterface SourceMeta {\n id: string\n title: string\n url: string\n tags: string[]\n n?: number\n}\n\ninterface EntryMeta {\n kind: string\n title: string\n /** Raw confidence as authored (number or string) — string-compared on ties. */\n conf: number | string\n tags: string[]\n ns: number[]\n gist: string\n}\n\n/** flat(v) — join arrays with space, \"\" for null/undefined, else String(v). */\nconst flat = (v: unknown): string =>\n Array.isArray(v) ? v.join(\" \") : v == null ? \"\" : String(v)\n\nconst asTags = (v: unknown): string[] =>\n Array.isArray(v) ? (v as string[]) : v ? [String(v)] : []\n\nconst firstSentence = (body: string): string => {\n const txt = body.replace(/^#.*$/gm, \"\").replace(/\\s+/g, \" \").trim()\n return (txt.split(/(?<=[.!?])\\s/)[0] || txt).slice(0, 260)\n}\n\n/** Read every `.md` under `dir` in the FsPort's native walk order. */\nasync function walkMd(dataset: FsPort, dir: string): Promise<string[]> {\n let rels: readonly string[]\n try {\n rels = await dataset.walk(dir)\n } catch {\n return []\n }\n return rels.filter((r) => r.endsWith(\".md\")).map((r) => `${dir}/${r}`)\n}\n\nexport async function buildPacks(\n opts: BuildPacksOptions\n): Promise<BuildPacksResult> {\n const { dataset, config } = opts\n const viewsDir = opts.viewsDir ?? \"views\"\n const facetOrder = [...new Set(config.chapters.flatMap((c) => c.facets ?? []))]\n\n // ── sources → global bibliography ──────────────────────────────────────\n const sources: SourceMeta[] = []\n for (const path of await walkMd(dataset, \"sources\")) {\n let raw: string\n try {\n raw = await dataset.readFile(path)\n } catch {\n continue\n }\n let fm: Record<string, unknown> = {}\n try {\n fm = matter(raw).data as Record<string, unknown>\n } catch {\n fm = {}\n }\n const id = flat(fm.id).trim()\n if (!id) continue\n const corpusMeta =\n ((fm.metadata as Record<string, unknown> | undefined)?.corpus as\n | Record<string, unknown>\n | undefined) ?? {}\n const url = String(\n corpusMeta.originalUrl ?? corpusMeta.importerSourceUrl ?? \"\"\n )\n .replace(/\\s+/g, \"\")\n .trim()\n sources.push({\n id,\n title: flat(fm.title).replace(/\\s+/g, \" \").trim(),\n url,\n tags: asTags(fm.tags),\n })\n }\n\n const facetOf = (s: SourceMeta): string =>\n facetOrder.find((f) => s.tags.includes(f)) ?? \"other\"\n sources.sort((a, b) => {\n const fa = facetOrder.indexOf(facetOf(a))\n const fb = facetOrder.indexOf(facetOf(b))\n if (fa !== fb) return (fa < 0 ? 99 : fa) - (fb < 0 ? 99 : fb)\n return a.title.localeCompare(b.title)\n })\n const idToN = new Map<string, number>()\n sources.forEach((s, i) => {\n s.n = i + 1\n idToN.set(s.id, i + 1)\n })\n\n // ── entries ────────────────────────────────────────────────────────────\n const entries: EntryMeta[] = []\n for (const path of await walkMd(dataset, \"entries\")) {\n let raw: string\n try {\n raw = await dataset.readFile(path)\n } catch {\n continue\n }\n let parsed: matter.GrayMatterFile<string>\n try {\n parsed = matter(raw)\n } catch {\n continue\n }\n const fm = parsed.data as Record<string, unknown>\n const title = flat(fm.title).replace(/\\s+/g, \" \").trim()\n if (!title) continue\n const segs = path.replace(/^entries\\//, \"\").split(\"/\")\n const kind =\n typeof fm.kind === \"string\" && fm.kind\n ? fm.kind\n : (segs.slice(-2)[0] ?? \"unknown\")\n const srcs = asTags(fm.sources).map((s) => flat(s).replace(/\\s+/g, \"\").trim())\n const ns = [\n ...new Set(srcs.map((id) => idToN.get(id)).filter((n): n is number => !!n)),\n ].sort((a, b) => a - b)\n entries.push({\n kind,\n title,\n conf: (fm.confidence as number | string | undefined) ?? \"\",\n tags: asTags(fm.tags),\n ns,\n gist: firstSentence(parsed.content),\n })\n }\n\n // ── outputs ────────────────────────────────────────────────────────────\n const files: PackFile[] = []\n files.push({\n path: `${viewsDir}/_bibliography.json`,\n content: JSON.stringify({ sources }, null, 2),\n })\n files.push({\n path: `${viewsDir}/_bibliography.md`,\n content:\n \"# Bibliography (global citation index)\\n\\n\" +\n sources.map((s) => `${s.n}. ${s.title || s.id} — ${s.url}`).join(\"\\n\") +\n \"\\n\",\n })\n\n const chapters: Array<{ id: string; title: string; entryCount: number }> = []\n for (const ch of config.chapters) {\n const facets = ch.facets ?? []\n const kw = (ch.kw ?? []).map((s) => s.toLowerCase())\n const seen = new Set<string>()\n const scored: Array<{ e: EntryMeta; hits: number }> = []\n for (const e of entries) {\n if (!facets.some((f) => e.tags.includes(f))) continue\n const hay = `${e.title} ${e.tags.join(\" \")} ${e.gist}`.toLowerCase()\n const hits = kw.filter((k) => hay.includes(k)).length\n if (kw.length && hits === 0) continue\n const key = e.title.toLowerCase().slice(0, 50)\n if (seen.has(key)) continue\n seen.add(key)\n scored.push({ e, hits })\n }\n scored.sort(\n (a, b) =>\n b.hits - a.hits ||\n String(b.e.conf).localeCompare(String(a.e.conf))\n )\n const picks = scored.slice(0, ch.cap ?? 28).map((x) => x.e)\n const srcFiles = [...new Set(facets.map((f) => `sources.${f}.md`))]\n const lines = picks.map(\n (e) =>\n `- **[${e.kind}]** ${e.title}${e.conf ? ` _(conf ${e.conf})_` : \"\"} ` +\n `${e.ns.length ? `[${e.ns.join(\",\")}]` : \"[uncited]\"}\\n ${e.gist}`\n )\n files.push({\n path: `${viewsDir}/${ch.id}.md`,\n content:\n `# Pack — ${ch.title}\\n\\n` +\n `**Facets:** ${facets.join(\", \")} · **${picks.length} distilled claims** ` +\n `(each tagged with its global source number [n]).\\n\\n` +\n `**Also read for full context + exact quotes/URLs:** ${srcFiles.join(\", \")} ` +\n `(in the corpus root), and ${viewsDir}/_bibliography.md.\\n\\n` +\n `## Distilled claims for this chapter\\n\\n${lines.join(\"\\n\")}\\n`,\n })\n chapters.push({ id: ch.id, title: ch.title, entryCount: picks.length })\n }\n\n return { files, bibliography: sources.length, chapters }\n}\n","/**\n * Citation helpers shared across the report glue. A citation is `[n]` or\n * `[n, m, …]` referencing the global bibliography index.\n */\n\n/** Every citation number referenced in a string (flattening `[a, b]`). */\nexport function citesOf(s: string): number[] {\n return [...s.matchAll(/\\[(\\d{1,3}(?:,\\s*\\d{1,3})*)\\]/g)].flatMap((m) =>\n m[1]!.split(\",\").map((n) => parseInt(n.trim(), 10))\n )\n}\n\n/** Citation numbers in `s` outside the valid `[1, bibMax]` range. */\nexport function outOfRangeCites(s: string, bibMax: number): number[] {\n return [...new Set(citesOf(s).filter((n) => n < 1 || n > bibMax))]\n}\n","/**\n * assembleChapters — turn the write step's raw per-chapter drafts into clean\n * chapter files. Pure: in-memory drafts → files to write (the caller owns the\n * report-rooted writer). Mechanical only — strips agent preambles, normalizes\n * `[a→b]` cross-refs to `[b]`, collapses blank runs; no model calls.\n */\n\nimport type { PackFile } from \"./packs.js\"\nimport { outOfRangeCites } from \"./cites.js\"\n\nexport interface ChapterDraft {\n /** Chapter id (= `<chaptersDir>/<ch>.md`). */\n readonly ch: string\n readonly draft: string\n}\n\nexport interface AssembleResult {\n readonly files: readonly PackFile[]\n readonly stats: {\n readonly chapters: number\n readonly preamblesStripped: number\n readonly withOutOfRangeCites: number\n readonly outOfRange: ReadonlyArray<{ ch: string; cites: number[] }>\n }\n}\n\nexport interface AssembleOptions {\n readonly chapters: readonly ChapterDraft[]\n /** Highest valid citation [n]; cites above it are flagged (not dropped). */\n readonly bibMax: number\n /** Subdir under the report root for chapter files. Default `chapters`. */\n readonly chaptersDir?: string\n}\n\nconst PREAMBLE = /^\\s*(?:I have|I'll|Here is|Here's|Writing|Let me|Okay|Done)/i\nconst CROSSREF = /\\[(\\d{1,3})\\s*(?:→|->|—>|to see|see)\\s*(?:see\\s*)?(\\d{1,3})\\]/g\n\n/** Drop any leading agent chatter before the first \"## \" and tidy whitespace. */\nexport function cleanDraft(draft: string | undefined): string {\n if (!draft) return \"\"\n let s = draft.replace(/\\r/g, \"\")\n const i = s.indexOf(\"## \")\n if (i > 0) s = s.slice(i)\n s = s.replace(CROSSREF, \"[$2]\")\n return s.replace(/\\n{3,}/g, \"\\n\\n\").trim()\n}\n\nexport function assembleChapters(opts: AssembleOptions): AssembleResult {\n const chaptersDir = opts.chaptersDir ?? \"chapters\"\n const files: PackFile[] = []\n let preamblesStripped = 0\n const outOfRange: Array<{ ch: string; cites: number[] }> = []\n\n for (const c of opts.chapters) {\n const body = cleanDraft(c.draft)\n if (PREAMBLE.test(c.draft || \"\")) preamblesStripped++\n if (body) files.push({ path: `${chaptersDir}/${c.ch}.md`, content: body + \"\\n\" })\n const oor = outOfRangeCites(body, opts.bibMax)\n if (oor.length) outOfRange.push({ ch: c.ch, cites: oor })\n }\n\n return {\n files,\n stats: {\n chapters: opts.chapters.length,\n preamblesStripped,\n withOutOfRangeCites: outOfRange.length,\n outOfRange,\n },\n }\n}\n","/**\n * ReportContent — the ONE medium-agnostic shape of a finished report.\n *\n * `buildReportContent` reads the report root (config + chapters/ + the\n * bibliography view) and RETURNS the structured content: an ordered list of\n * sections (each raw markdown) plus the structured bibliography and document\n * metadata. It is PURE and port-injected like the rest of the engine — it\n * never touches the dataset and never renders HTML/PDF (no Chrome here).\n *\n * Every render medium is an AIP `render.*` tool whose input is a\n * `ReportContent`; the canvakit driver (in `@canvakit/report`) is the only\n * place HTML/PDF lives. The markdown medium is reconstructed losslessly by\n * `reportContentToMarkdown` — which is exactly what `stitchReport` emits, so\n * REPORT.md byte-parity is preserved (the two share `collectReportSections`).\n */\n\nimport { z } from \"zod\"\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport type { ReportConfig } from \"./types.js\"\n\n/** What role a section plays in the document. */\nexport const reportSectionKindSchema = z.enum([\n \"front\",\n \"part\",\n \"chapter\",\n \"annexes\",\n \"sources\",\n])\n\n/** One contiguous unit of a report (front, a part divider, a chapter, …). */\nexport const reportSectionSchema = z.object({\n /** Stable id — chapter id, or `_front`/`_annexes`/`_sources` for the glue. */\n id: z.string(),\n /** Human label (heading text, leading `#`s stripped). May be \"\". */\n title: z.string(),\n /** The section's raw markdown, exactly as it appears in REPORT.md. */\n markdown: z.string(),\n kind: reportSectionKindSchema,\n})\n\n/** One global citation source (mirrors `views/_bibliography.json`). */\nexport const bibEntrySchema = z.object({\n n: z.number(),\n id: z.string(),\n title: z.string(),\n url: z.string(),\n})\n\n/**\n * The medium-agnostic content a `render.*` tool consumes — the single source\n * of truth for \"what a report's content is\". Zod so the render tool schemas\n * can embed it directly (one definition across the engine and every renderer).\n */\nexport const reportContentSchema = z.object({\n title: z.string(),\n sections: z.array(reportSectionSchema),\n bibliography: z\n .object({\n mode: z.literal(\"numbered\"),\n entries: z.array(bibEntrySchema),\n })\n .optional(),\n /** Document metadata (brand · subtitle · tag · custodian) — presentation-free. */\n meta: z.record(z.string(), z.string()).optional(),\n})\n\nexport type ReportSection = z.infer<typeof reportSectionSchema>\nexport type BibEntry = z.infer<typeof bibEntrySchema>\nexport type ReportContent = z.infer<typeof reportContentSchema>\n\nexport interface CollectSectionsOptions {\n readonly config: ReportConfig\n /** Read-side view of the report root (chapters/ + views/ + front/annexes). */\n readonly report: FsPort\n /** Subdir holding the written chapter files. Default `chapters`. */\n readonly chaptersDir?: string\n /** Subdir holding the bibliography. Default `views`. */\n readonly viewsDir?: string\n}\n\nconst stripHeading = (s: string): string => s.replace(/^#+\\s*/, \"\").trim()\n\n/**\n * Collect a report's ordered sections from the report root. This is the\n * single read path shared by `stitchReport` (markdown medium) and\n * `buildReportContent` (every other medium), so the section boundaries — and\n * therefore REPORT.md — are identical regardless of the consumer.\n *\n * Order: front? · (parts ? part-heading + its chapters : chapters in config\n * order) · annexes? · Sources (from the bibliography). Mirrors the legacy\n * stitch exactly; all reads are report-side (the dataset is never touched).\n */\nexport async function collectReportSections(\n opts: CollectSectionsOptions\n): Promise<ReportSection[]> {\n const { config, report } = opts\n const chaptersDir = opts.chaptersDir ?? \"chapters\"\n const viewsDir = opts.viewsDir ?? \"views\"\n\n const rd = async (p: string): Promise<string> =>\n (await report.readFile(p)).trim()\n const rdOpt = async (p: string): Promise<string | null> => {\n try {\n return await rd(p)\n } catch {\n return null\n }\n }\n const titleOf = (id: string): string =>\n config.chapters.find((c) => c.id === id)?.title ?? id\n\n const sections: ReportSection[] = []\n\n const front = await rdOpt(config.frontFile ?? `${chaptersDir}/_front.md`)\n if (front) sections.push({ id: \"_front\", title: \"\", markdown: front, kind: \"front\" })\n\n if (config.parts && config.parts.length) {\n for (const part of config.parts) {\n sections.push({\n id: stripHeading(part.heading).toLowerCase().replace(/[^a-z0-9]+/g, \"-\"),\n title: stripHeading(part.heading),\n markdown: part.heading,\n kind: \"part\",\n })\n for (const id of part.chapters ?? []) {\n sections.push({\n id,\n title: titleOf(id),\n markdown: await rd(`${chaptersDir}/${id}.md`),\n kind: \"chapter\",\n })\n }\n }\n } else {\n for (const c of config.chapters) {\n sections.push({\n id: c.id,\n title: c.title,\n markdown: await rd(`${chaptersDir}/${c.id}.md`),\n kind: \"chapter\",\n })\n }\n }\n\n if (config.annexesFile) {\n const annexes = await rdOpt(config.annexesFile)\n if (annexes)\n sections.push({ id: \"_annexes\", title: \"Annexes\", markdown: annexes, kind: \"annexes\" })\n }\n\n const bib = (await rd(`${viewsDir}/_bibliography.md`))\n .replace(/^# Bibliography.*$/m, \"\")\n .trim()\n sections.push({\n id: \"_sources\",\n title: \"Sources\",\n markdown: \"## Sources\\n\\n\" + bib,\n kind: \"sources\",\n })\n\n return sections\n}\n\n/**\n * Reconstruct the canonical REPORT.md from collected sections. Byte-identical\n * to the legacy stitch output (`out.join(\"\\n\\n\") + \"\\n\"`).\n */\nexport function reportContentToMarkdown(\n sections: readonly ReportSection[]\n): string {\n return sections.map((s) => s.markdown).join(\"\\n\\n\") + \"\\n\"\n}\n\nexport type BuildReportContentOptions = CollectSectionsOptions\n\n/**\n * Build the medium-agnostic {@link ReportContent} for a report. Pure: reads\n * the report root through the injected FsPort and returns structured content —\n * the single input every `render.*` tool consumes.\n */\nexport async function buildReportContent(\n opts: BuildReportContentOptions\n): Promise<ReportContent> {\n const { config, report } = opts\n const viewsDir = opts.viewsDir ?? \"views\"\n\n const sections = await collectReportSections(opts)\n\n // Title: explicit config, else the first H1 in the front matter, else fallback.\n let title = config.title?.trim() ?? \"\"\n if (!title) {\n const front = sections.find((s) => s.kind === \"front\")\n title = front?.markdown.match(/^#\\s+(.+)$/m)?.[1]?.trim() ?? \"Report\"\n }\n\n // Structured bibliography from the JSON view (the .md is for the Sources block).\n let bibliography: ReportContent[\"bibliography\"]\n try {\n const raw = await report.readFile(`${viewsDir}/_bibliography.json`)\n const parsed = JSON.parse(raw) as { sources?: unknown }\n const src = Array.isArray(parsed.sources) ? parsed.sources : []\n const entries: BibEntry[] = src.map((s) => {\n const o = (s ?? {}) as Record<string, unknown>\n return {\n n: typeof o.n === \"number\" ? o.n : 0,\n id: typeof o.id === \"string\" ? o.id : \"\",\n title: typeof o.title === \"string\" ? o.title : \"\",\n url: typeof o.url === \"string\" ? o.url : \"\",\n }\n })\n if (entries.length) bibliography = { mode: \"numbered\", entries }\n } catch {\n // No bibliography view — content is still valid without one.\n }\n\n // Document metadata — presentation-free scalars from the cover, if present.\n const meta: Record<string, string> = {}\n const cover = config.cover\n if (cover) {\n for (const k of [\"brand\", \"subtitle\", \"tag\", \"meta\"] as const) {\n const v = cover[k]\n if (typeof v === \"string\" && v.trim()) meta[k] = v.trim()\n }\n }\n if (config.profile) meta.profile = config.profile\n\n return {\n title,\n sections,\n ...(bibliography ? { bibliography } : {}),\n ...(Object.keys(meta).length ? { meta } : {}),\n }\n}\n","/**\n * stitchReport — assemble the final REPORT.md = front + part dividers +\n * chapters + annexes + a Sources section (from the global bibliography), per\n * the config's `parts[]`. Pure: reads report-side files through an injected\n * FsPort and RETURNS the document string (the caller writes REPORT.md).\n *\n * It is the markdown render medium: `stitchReport === reportContentToMarkdown\n * ∘ collectReportSections`. The shared section collection guarantees the\n * markdown medium and every `render.*` tool see the exact same boundaries.\n *\n * All reads are report-side (chapters + views) — the dataset is not touched.\n */\n\nimport { collectReportSections, reportContentToMarkdown } from \"./content.js\"\nimport type { CollectSectionsOptions } from \"./content.js\"\n\nexport type StitchOptions = CollectSectionsOptions\n\nexport interface StitchResult {\n readonly content: string\n readonly wordCount: number\n}\n\nexport async function stitchReport(opts: StitchOptions): Promise<StitchResult> {\n const sections = await collectReportSections(opts)\n const content = reportContentToMarkdown(sections)\n const wordCount = sections\n .map((s) => s.markdown)\n .join(\" \")\n .split(/\\s+/).length\n return { content, wordCount }\n}\n","/**\n * applyEdits — apply {find, replace, reason} edits (from the fix step) to\n * chapter files by EXACT match. An edit lands only if `find` occurs exactly\n * once AND `replace` adds no out-of-range [n]; everything else is reported,\n * not forced. A chapter is written only if at least one edit applied and the\n * post-check passes (still starts at \"## \", no out-of-range cites).\n *\n * Reads chapter files through an injected FsPort; RETURNS the writes + a\n * human-readable apply report (the caller owns the writer).\n */\n\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport type { PackFile } from \"./packs.js\"\nimport { outOfRangeCites } from \"./cites.js\"\n\nexport interface ChapterEdit {\n readonly find?: string\n readonly replace?: string\n readonly reason?: string\n}\n\nexport interface ChapterEditSet {\n readonly id: string\n readonly edits?: readonly ChapterEdit[]\n}\n\nexport interface ApplyEditsResult {\n /** Chapter files to (over)write — already post-checked. */\n readonly files: readonly PackFile[]\n /** The fix-apply report markdown. */\n readonly report: string\n readonly stats: {\n readonly filesChanged: number\n readonly applied: number\n readonly skipped: number\n }\n}\n\nexport interface ApplyEditsOptions {\n readonly results: readonly ChapterEditSet[]\n readonly bibMax: number\n /** Read-side view of the report root. */\n readonly report: FsPort\n /** Subdir holding chapter files. Default `chapters`. */\n readonly chaptersDir?: string\n}\n\n/** Count non-overlapping occurrences of `n` in `hay`. */\nfunction occ(hay: string, n: string): number {\n let c = 0\n let i = 0\n while ((i = hay.indexOf(n, i)) !== -1) {\n c++\n i += n.length\n }\n return c\n}\n\nexport async function applyEdits(\n opts: ApplyEditsOptions\n): Promise<ApplyEditsResult> {\n const chaptersDir = opts.chaptersDir ?? \"chapters\"\n const files: PackFile[] = []\n let md =\n \"# Fix-apply report (edit-based)\\n\\n\" +\n \"Each edit lands only if `find` matches exactly once and `replace` adds no out-of-range [n].\\n\\n\"\n let applied = 0\n let skipped = 0\n let filesChanged = 0\n\n for (const r of opts.results) {\n const path = `${chaptersDir}/${r.id}.md`\n let text = await opts.report.readFile(path)\n const edits = r.edits ?? []\n let n = 0\n md += `## ${r.id} — ${edits.length} proposed edit(s)\\n`\n for (const e of edits) {\n const find = e.find ?? \"\"\n const replace = e.replace ?? \"\"\n const oor = outOfRangeCites(replace, opts.bibMax)\n const count = find ? occ(text, find) : 0\n let status: string\n if (!find) status = \"SKIP (empty find)\"\n else if (count === 0) status = \"SKIP (find not matched verbatim)\"\n else if (count > 1) status = `SKIP (find matches ${count}× — ambiguous)`\n else if (oor.length)\n status = `SKIP (replace adds out-of-range cite ${oor.join(\",\")})`\n else {\n text = text.replace(find, replace)\n n++\n status = \"✅ applied\"\n }\n md += `- ${status} — _${e.reason || \"\"}_\\n`\n if (status.startsWith(\"✅\")) {\n md +=\n ` find: ${JSON.stringify(find.slice(0, 200))}\\n` +\n ` replace: ${JSON.stringify(replace.slice(0, 200))}\\n`\n }\n }\n const post: string[] = []\n if (!text.startsWith(\"## \")) post.push(\"no longer starts at '##'\")\n const oorAll = outOfRangeCites(text, opts.bibMax)\n if (oorAll.length) post.push(`out-of-range cites present: ${oorAll.join(\",\")}`)\n if (post.length)\n md += `- ⚠️ POST-CHECK FAILED (${post.join(\"; \")}) → NOT written\\n`\n else if (n > 0) {\n files.push({ path, content: text })\n filesChanged++\n }\n applied += n\n skipped += edits.length - n\n md += `- result: ${n}/${edits.length} applied${post.length ? \" (reverted)\" : \"\"}\\n\\n`\n }\n\n return { files, report: md, stats: { filesChanged, applied, skipped } }\n}\n","/**\n * ReportModelPort — the minimal model seam the report's model steps consume.\n *\n * Structural, not nominal: the AIP `ModelPort` (`complete({system?, prompt}) →\n * {result}`) satisfies it as-is, so the same engine runs under any registered\n * model. The single-pass functions here ARE the \"model driver\" tier; the\n * higher-fidelity claude-code path (Phase C) reuses the same prompt-builders\n * but swaps the executor for file-reading sub-agents.\n */\n\nexport interface ReportModelInput {\n readonly system?: string\n readonly prompt: string\n}\n\nexport interface ReportModelOutput {\n /** Completion payload — string for text, or a structured object. */\n readonly result: string | unknown\n}\n\nexport interface ReportModelPort {\n complete(input: ReportModelInput): Promise<ReportModelOutput>\n}\n\n/** Run a prompt and coerce the completion to text. */\nexport async function runModel(\n model: ReportModelPort,\n input: ReportModelInput\n): Promise<string> {\n const { result } = await model.complete(input)\n return typeof result === \"string\" ? result : JSON.stringify(result)\n}\n","/**\n * analyze — synthesize the distilled entries of each facet into a structured\n * markdown analysis doc (`sources.<facet>.md`), the deeper context the chapter\n * writer reads. A report-side step (invariant 3): it READS the dataset's\n * entries and RETURNS report-rooted files; it never writes the dataset.\n */\n\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport { resolveKnowledge } from \"../knowledge/resolve.js\"\nimport type { PackFile } from \"./packs.js\"\nimport { type ReportModelPort, type ReportModelInput, runModel } from \"./model.js\"\n\nexport interface AnalyzeFacetInput {\n readonly facet: string\n /** Pre-rendered entries block (title/kind/confidence + body per entry). */\n readonly entriesText: string\n}\n\n/** The prompt for one facet's analysis doc — pure, driver-reusable. */\nexport function buildFacetAnalysisPrompt(\n input: AnalyzeFacetInput\n): ReportModelInput {\n return {\n system:\n \"You are a research analyst. Your output is a structured markdown analysis \" +\n \"document that will be used as input to a long-form research bible chapter. \" +\n \"Write in clear, dense prose with H2 headers. No filler, no meta-commentary.\",\n prompt:\n `Synthesize these knowledge entries about the facet \"${input.facet}\" into a structured ` +\n `markdown analysis document for a research bible.\\n\\n` +\n `Include:\\n` +\n `- ## Key Themes: recurring patterns across entries\\n` +\n `- ## Major Findings: the most credible, high-confidence claims\\n` +\n `- ## Notable Examples: concrete worked instances worth citing\\n` +\n `- ## Gaps & Contradictions: what is unknown, disputed, or missing\\n\\n` +\n `ENTRIES:\\n\\n${input.entriesText}`,\n }\n}\n\nexport interface AnalyzeDatasetOptions {\n /** Read-only view of the dataset (entries/). */\n readonly dataset: FsPort\n readonly facets: readonly string[]\n readonly model: ReportModelPort\n}\n\nexport interface AnalyzeDatasetResult {\n /** `sources.<facet>.md` files to write at the report root. */\n readonly files: readonly PackFile[]\n readonly analyzed: number\n /** Facets skipped because they resolved to zero entries. */\n readonly skipped: readonly string[]\n}\n\nexport async function analyzeDataset(\n opts: AnalyzeDatasetOptions\n): Promise<AnalyzeDatasetResult> {\n const files: PackFile[] = []\n const skipped: string[] = []\n\n for (const facet of opts.facets) {\n const entries = await resolveKnowledge({\n fs: opts.dataset,\n query: { tags: [facet] },\n })\n if (entries.length === 0) {\n skipped.push(facet)\n continue\n }\n const entriesText = entries\n .map(\n (e) =>\n `### ${e.title} (${e.kind}, confidence ${e.confidence ?? \"?\"})\\n\\n${e.body}`\n )\n .join(\"\\n\\n---\\n\\n\")\n const content = await runModel(\n opts.model,\n buildFacetAnalysisPrompt({ facet, entriesText })\n )\n files.push({\n path: `sources.${facet}.md`,\n content: `# Analysis: ${facet}\\n\\n${content}`,\n })\n }\n\n return { files, analyzed: files.length, skipped }\n}\n","/**\n * write — the single-pass chapter writer (the \"model driver\" tier). Given a\n * chapter's view (distilled claims + [n] cites), the per-facet analysis, and\n * the bibliography, produce a cited markdown draft.\n *\n * `buildChapterWritePrompt` is pure and exported so the higher-fidelity\n * claude-code driver (Phase C) reuses the identical prompt while swapping the\n * executor for a file-reading sub-agent. `writeChapter` is the model-driver\n * executor. Output is a raw DRAFT — `assembleChapters` then cleans it.\n */\n\nimport type { ReportChapter } from \"./types.js\"\nimport { type ReportModelPort, type ReportModelInput, runModel } from \"./model.js\"\n\nexport interface ChapterWriteContext {\n readonly chapter: Pick<ReportChapter, \"id\" | \"title\" | \"words\" | \"cover\">\n /** Report/document title for framing. */\n readonly title: string\n /** The chapter's view content (distilled claims with [n]). */\n readonly packContent: string\n /** Concatenated per-facet analysis docs (optional deeper context). */\n readonly analysisContext?: string\n /** The global bibliography markdown (for citation verification). */\n readonly bibliography?: string\n /** Global rules block (`ReportConfig.rulesText`) — appended verbatim. */\n readonly rules?: string\n}\n\nexport function buildChapterWritePrompt(\n ctx: ChapterWriteContext\n): ReportModelInput {\n const words = ctx.chapter.words ?? \"800-1500\"\n return {\n system:\n \"You are an expert research writer. Write in clear, dense, well-structured prose. \" +\n \"Every non-obvious claim must be cited inline as [n] from the Bibliography. \" +\n \"Use Markdown H2 and H3 subheaders within the chapter. No meta-commentary or filler. \" +\n `Aim for ${words} words.` +\n (ctx.rules ? `\\n\\n${ctx.rules}` : \"\"),\n prompt:\n `Write the chapter \"${ctx.chapter.title}\" for the research document \"${ctx.title}\".\\n\\n` +\n (ctx.chapter.cover\n ? `## Chapter brief (what this chapter must cover)\\n\\n${ctx.chapter.cover}\\n\\n`\n : \"\") +\n `## Distilled claims for this chapter (with citation numbers):\\n\\n${ctx.packContent}\\n\\n` +\n (ctx.analysisContext\n ? `## Per-facet analysis (for deeper context):\\n\\n${ctx.analysisContext}\\n\\n`\n : \"\") +\n `## Bibliography (for citation verification):\\n\\n${ctx.bibliography ?? \"\"}\\n\\n` +\n `Write the chapter now. Start with the \"## ${ctx.chapter.title}\" heading, then the content.`,\n }\n}\n\n/** Single-pass chapter write → a `{ ch, draft }` ready for assembleChapters. */\nexport async function writeChapter(\n ctx: ChapterWriteContext,\n model: ReportModelPort\n): Promise<{ ch: string; draft: string }> {\n const draft = await runModel(model, buildChapterWritePrompt(ctx))\n return { ch: ctx.chapter.id, draft }\n}\n","/**\n * review — the single-pass chapter reviewer (the \"model driver\" tier of the\n * quality loop). Given a chapter's current prose, its per-facet analysis, and\n * the bibliography, the model returns a set of EXACT-MATCH `{find, replace,\n * reason}` edits that `applyEdits` can land verbatim (fact/citation fixes,\n * overstatement trims). It never rewrites the chapter — only proposes targeted,\n * verifiable edits, so the fix step stays deterministic.\n *\n * `buildReviewPrompt` is pure + exported so the claude-code driver reuses it.\n */\n\nimport { z } from \"zod\"\nimport type { ChapterEdit, ChapterEditSet } from \"./apply-edits.js\"\nimport { type ReportModelPort, type ReportModelInput, runModel } from \"./model.js\"\n\nexport interface ChapterReviewContext {\n readonly chapter: { readonly id: string; readonly title: string }\n /** The chapter's current markdown (what gets reviewed). */\n readonly chapterText: string\n /** Concatenated per-facet analysis docs (the ground truth to check against). */\n readonly analysisContext?: string\n /** The global bibliography markdown (citation range + targets). */\n readonly bibliography?: string\n /** Highest valid citation [n] — replacements must not exceed it. */\n readonly bibMax: number\n /**\n * Global rules block (`ReportConfig.rulesText`) — the same contract the\n * writer was given, appended verbatim so review enforces it too.\n */\n readonly rules?: string\n}\n\nexport function buildReviewPrompt(ctx: ChapterReviewContext): ReportModelInput {\n return {\n system:\n \"You are a meticulous fact + citation reviewer for a long-form research report. \" +\n \"Propose ONLY targeted, exact-match edits — never a rewrite. Each edit's `find` \" +\n \"MUST be a verbatim substring of the chapter that occurs EXACTLY ONCE, and \" +\n \"`replace` must keep every citation [n] within the valid range. Fix wrong/missing \" +\n \"citations, unsupported or overstated claims, and factual errors against the \" +\n \"analysis + bibliography. Output ONLY a JSON object — no prose, no fences.\" +\n (ctx.rules ? `\\n\\n${ctx.rules}` : \"\"),\n prompt:\n `Review the chapter \"${ctx.chapter.title}\". Valid citations are [1]..[${ctx.bibMax}].\\n\\n` +\n `## Chapter (current text):\\n\\n${ctx.chapterText}\\n\\n` +\n (ctx.analysisContext\n ? `## Per-facet analysis (ground truth):\\n\\n${ctx.analysisContext}\\n\\n`\n : \"\") +\n `## Bibliography:\\n\\n${ctx.bibliography ?? \"\"}\\n\\n` +\n `Return JSON: { \"edits\": [ { \"find\": \"<verbatim once-occurring span>\", ` +\n `\"replace\": \"<corrected span>\", \"reason\": \"<short why>\" } ] }. ` +\n `Return { \"edits\": [] } if the chapter is clean.`,\n }\n}\n\nconst reviewSchema = z.object({\n edits: z\n .array(\n z.object({\n find: z.string().optional(),\n replace: z.string().optional(),\n reason: z.string().optional(),\n })\n )\n .default([]),\n})\n\n/** Best-effort extraction of a JSON object from a model completion. */\nfunction extractJson(text: string): unknown {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n const body = fenced ? fenced[1]! : text\n const start = body.indexOf(\"{\")\n const end = body.lastIndexOf(\"}\")\n if (start === -1 || end === -1) return { edits: [] }\n try {\n return JSON.parse(body.slice(start, end + 1))\n } catch {\n return { edits: [] }\n }\n}\n\n/**\n * Single-pass chapter review → a {@link ChapterEditSet} ready for\n * `applyEdits`. Tolerant: a malformed completion yields no edits (the chapter\n * is left untouched) rather than throwing — review is an enhancement, not a gate.\n */\nexport async function reviewChapter(\n ctx: ChapterReviewContext,\n model: ReportModelPort\n): Promise<ChapterEditSet> {\n const text = await runModel(model, buildReviewPrompt(ctx))\n const parsed = reviewSchema.safeParse(extractJson(text))\n const edits: ChapterEdit[] = parsed.success ? parsed.data.edits : []\n return { id: ctx.chapter.id, edits }\n}\n","/**\n * ReportConfig — the single source of truth for a long-form report rendered\n * from a corpus dataset. Superset of the two pre-existing shapes (the Claude\n * bible toolkit's `bible.config.json` + the AIP `bibleConfigSchema`); the\n * authoring reference is `.claude/skills/deep-research/bible/config.schema.md`.\n *\n * Validated with zod (NOT AJV — avoids corpus-cli's findSpecsRoot). Unknown\n * keys pass through so presentation/render fields the engine doesn't read\n * (covers, header/footer, parts) survive a parse round-trip untouched.\n */\n\nimport { z } from \"zod\"\n\n/** A key/value fact rendered on a branded cover (`facts[]`). */\nexport const reportCoverFactSchema = z\n .object({ k: z.string(), v: z.string() })\n .passthrough()\n\n/** One extra full-bleed cover (front or back). Data → one shared template. */\nexport const reportCoverPageSchema = z\n .object({\n kicker: z.string().optional(),\n title: z.string().optional(),\n meta: z.string().optional(),\n tag: z.string().optional(),\n align: z.string().optional(),\n facts: z.array(reportCoverFactSchema).optional(),\n })\n .passthrough()\n\n/** The title cover (1re de couverture). */\nexport const reportCoverSchema = z\n .object({\n brand: z.string().optional(),\n subtitle: z.string().optional(),\n tag: z.string().optional(),\n meta: z.string().optional(),\n brandLetterSpacing: z.string().optional(),\n brandFontSize: z.string().optional(),\n })\n .passthrough()\n\n/** A part grouping that drives stitch ordering. */\nexport const reportPartSchema = z\n .object({\n heading: z.string(),\n chapters: z.array(z.string()).default([]),\n })\n .passthrough()\n\n/**\n * One report unit. Carries BOTH write fields (words/src/cover) and\n * pack-routing fields (facets/kw/cap). `id` doubles as the view filename\n * and the `<id>.md` chapter source.\n */\nexport const reportChapterSchema = z\n .object({\n /** = view filename + chapter source filename. */\n id: z.string(),\n /** Exact \"## \" heading the writer must use. */\n title: z.string(),\n /** Target length hint for the writer (e.g. \"700–900\"). */\n words: z.string().optional(),\n /** Analysis files (sources.<facet>.md) the writer/reviewer reads. */\n src: z.array(z.string()).optional(),\n /** The writer brief — what this chapter must cover. */\n cover: z.string().optional(),\n /** build-packs: which distilled-entry tags route into this view. */\n facets: z.array(z.string()).default([]),\n /** build-packs: keyword needles that rank (and gate) entries. */\n kw: z.array(z.string()).optional(),\n /** build-packs: max distilled claims in the view (default 28). */\n cap: z.number().optional(),\n })\n .passthrough()\n\nexport const reportConfigSchema = z\n .object({\n /** Dataset path (repo-relative). Legacy `bible.config.json` key. */\n workspace: z.string().optional(),\n /** Pointer to the dataset this report consumes (the portable form). */\n dataset: z.string().optional(),\n /** Multiple datasets feeding one report (1 report → M datasets). */\n corpora: z.array(z.string()).optional(),\n /** Render/prompt profile preset (bible | brief | memo | deck). */\n profile: z.string().optional(),\n /** Highest valid citation [n]; out-of-range = error (used downstream). */\n bibMax: z.number().optional(),\n\n title: z.string().optional(),\n cover: reportCoverSchema.optional(),\n frontCovers: z.array(reportCoverPageSchema).optional(),\n backCovers: z.array(reportCoverPageSchema).optional(),\n runningHeader: z.string().optional(),\n runningFooter: z.string().optional(),\n\n frontFile: z.string().optional(),\n annexesFile: z.string().optional(),\n parts: z.array(reportPartSchema).optional(),\n\n rulesText: z.string().optional(),\n factsText: z.string().optional(),\n briefText: z.string().optional(),\n\n chapters: z.array(reportChapterSchema),\n })\n .passthrough()\n\nexport type ReportCoverFact = z.infer<typeof reportCoverFactSchema>\nexport type ReportCoverPage = z.infer<typeof reportCoverPageSchema>\nexport type ReportCover = z.infer<typeof reportCoverSchema>\nexport type ReportPart = z.infer<typeof reportPartSchema>\nexport type ReportChapter = z.infer<typeof reportChapterSchema>\nexport type ReportConfig = z.infer<typeof reportConfigSchema>\n","/**\n * plan — the auto-outliner. Turns (brief + dataset facets + profile) into a\n * chapter outline, so a report can run from a topic with NO hand-authored\n * config. Model-driven; the returned chapters are zod-validated and carry the\n * routing fields (facets/kw/cap) the pack builder needs.\n */\n\nimport { z } from \"zod\"\nimport { reportChapterSchema, type ReportChapter } from \"./types.js\"\nimport { type ReportModelPort, runModel } from \"./model.js\"\n\nexport interface PlanOutlineOptions {\n /** The research brief / framing (what the report should cover). */\n readonly brief: string\n /** Facets discovered in the dataset (the tags chapters route against). */\n readonly facets: readonly string[]\n /** Profile preset that shapes the unit (bible | brief | memo | deck). */\n readonly profile?: string\n /** Target chapter count (a hint, not a hard cap). */\n readonly targetChapters?: number\n readonly model: ReportModelPort\n}\n\nconst planSchema = z.object({\n title: z.string().optional(),\n chapters: z.array(reportChapterSchema).min(1),\n})\n\nexport interface PlanOutlineResult {\n readonly title?: string\n readonly chapters: readonly ReportChapter[]\n}\n\n/** Best-effort extraction of a JSON object from a model completion. */\nfunction extractJson(text: string): unknown {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n const body = fenced ? fenced[1]! : text\n const start = body.indexOf(\"{\")\n const end = body.lastIndexOf(\"}\")\n if (start === -1 || end === -1) throw new Error(\"plan: no JSON object in completion\")\n return JSON.parse(body.slice(start, end + 1))\n}\n\nexport async function planOutline(\n opts: PlanOutlineOptions\n): Promise<PlanOutlineResult> {\n const profile = opts.profile ?? \"bible\"\n const target = opts.targetChapters ?? 8\n const text = await runModel(opts.model, {\n system:\n \"You are a research editor planning a long-form, citation-backed report. \" +\n \"Output ONLY a JSON object — no prose, no fences.\",\n prompt:\n `Plan a \"${profile}\" report from this brief and the available dataset facets.\\n\\n` +\n `BRIEF:\\n${opts.brief}\\n\\n` +\n `DATASET FACETS (chapters route against these tags):\\n${opts.facets.join(\", \")}\\n\\n` +\n `Return JSON: { \"title\": string, \"chapters\": [ { \"id\": kebab-id, \"title\": \"N. Heading\", ` +\n `\"facets\": [subset of the facets above], \"kw\": [keyword needles], \"cap\": number, ` +\n `\"words\": \"min-max\", \"cover\": \"1-2 sentence writer brief\" } ] }.\\n` +\n `Aim for about ${target} chapters. Every chapter MUST list at least one facet from the list.`,\n })\n const parsed = planSchema.parse(extractJson(text))\n return { ...(parsed.title ? { title: parsed.title } : {}), chapters: parsed.chapters }\n}\n","/**\n * lintReportConfig — catch mis-named ReportConfig keys before they vanish.\n *\n * `reportConfigSchema` is `.passthrough()` everywhere (intentional — render/\n * presentation fields the engine doesn't read must survive a parse\n * round-trip). The side effect: a typo'd field (`chapters[].brief` instead\n * of `chapters[].cover`) parses fine and silently never reaches the engine.\n * This walks the raw config against the schema shape and flags what\n * `.passthrough()` would otherwise eat quietly.\n */\n\nimport { reportChapterSchema, reportConfigSchema } from \"./types.js\"\n\nconst TOP_LEVEL_KEYS = new Set(Object.keys(reportConfigSchema.shape))\nconst CHAPTER_KEYS = new Set(Object.keys(reportChapterSchema.shape))\n\n/** Common typos with an unambiguous correct key. */\nconst ALIASES: Record<string, string> = {\n brief: \"cover\",\n claimCap: \"cap\",\n keywords: \"kw\",\n maxClaims: \"cap\",\n}\n\n/** Known presentation passthroughs — legal, just not read by the engine. */\nconst INFORMATIONAL = new Set([\"subtitle\", \"writer\", \"citationStyle\", \"render\"])\n\nfunction lintKeys(\n obj: Readonly<Record<string, unknown>>,\n known: ReadonlySet<string>,\n where: string\n): string[] {\n const out: string[] = []\n for (const key of Object.keys(obj)) {\n if (known.has(key)) continue\n const alias = ALIASES[key]\n if (alias) {\n out.push(`WARN ${where}.${key} — unknown key, did you mean \"${alias}\"?`)\n } else if (INFORMATIONAL.has(key)) {\n out.push(`INFO ${where}.${key} — not read by the engine (informational)`)\n } else {\n out.push(`WARN ${where}.${key} — unknown key (not read by the engine)`)\n }\n }\n return out\n}\n\n/**\n * Lint a raw (pre- or post-parse — `.passthrough()` preserves extra keys\n * either way) report config for mis-named or dead keys. Returns one message\n * per flagged key, prefixed `WARN`/`INFO`; empty when the config is clean.\n * Parsing behavior is unchanged — this is diagnostics only.\n */\nexport function lintReportConfig(config: unknown): string[] {\n if (typeof config !== \"object\" || config === null) return []\n const top = config as Record<string, unknown>\n const messages = lintKeys(top, TOP_LEVEL_KEYS, \"config\")\n\n const chapters = top.chapters\n if (Array.isArray(chapters)) {\n chapters.forEach((chapter, i) => {\n if (typeof chapter !== \"object\" || chapter === null) return\n const id = (chapter as Record<string, unknown>).id\n const where = `chapters[${i}]${typeof id === \"string\" ? ` (${id})` : \"\"}`\n messages.push(\n ...lintKeys(chapter as Record<string, unknown>, CHAPTER_KEYS, where)\n )\n })\n }\n\n return messages\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentproto/corpus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "@agentproto/corpus — canonical composition of AIP-10 KNOWLEDGE, AIP-12 PLAYBOOK, AIP-18 COLLECTION, AIP-9 OPERATOR, AIP-15 WORKFLOW, AIP-41 ROUTINE into an autonomous knowledge-improvement system. Pure: zero runtime, zero filesystem, zero HTTP — all I/O via injected ports.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agentproto",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"bugs": {
|
|
22
22
|
"url": "https://github.com/agentproto/ts/issues"
|
|
23
23
|
},
|
|
24
|
-
"license": "
|
|
24
|
+
"license": "Apache-2.0",
|
|
25
25
|
"type": "module",
|
|
26
26
|
"main": "dist/index.mjs",
|
|
27
27
|
"module": "dist/index.mjs",
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
"gray-matter": "^4.0.3",
|
|
60
60
|
"yaml": "^2.7.0",
|
|
61
61
|
"zod": "^4.4.3",
|
|
62
|
-
"@agentproto/collection": "0.1.0
|
|
63
|
-
"@agentproto/knowledge": "0.1.0
|
|
64
|
-
"@agentproto/operator": "0.1.0
|
|
65
|
-
"@agentproto/playbook": "0.1.0
|
|
66
|
-
"@agentproto/registry": "0.1.0
|
|
67
|
-
"@agentproto/routine": "0.1.
|
|
68
|
-
"@agentproto/workflow": "0.1.0
|
|
62
|
+
"@agentproto/collection": "0.1.0",
|
|
63
|
+
"@agentproto/knowledge": "0.1.0",
|
|
64
|
+
"@agentproto/operator": "0.1.0",
|
|
65
|
+
"@agentproto/playbook": "0.1.0",
|
|
66
|
+
"@agentproto/registry": "0.1.0",
|
|
67
|
+
"@agentproto/routine": "0.1.2",
|
|
68
|
+
"@agentproto/workflow": "0.1.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.6.2",
|