shipseal 0.0.2 → 0.0.4

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/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["formatCount","measureOpts","propsSchema","propsSchema","propsSchema","formatCount","propsSchema","execFileAsync","API_ROOT","stripScope","repositoryUrl","normalizeGitUrl","textNode","takumiFromJsx","execFileAsync","execFileAsync","matchingBrace","input"],"sources":["../src/core/errors.ts","../src/brand/schema.ts","../src/brand/load.ts","../src/formats.ts","../src/config/schema.ts","../src/config/load.ts","../src/copy/slots.ts","../src/copy/deterministic.ts","../src/bench/percent.ts","../src/fit/fit-text.ts","../src/templates/theme.ts","../src/takumi-jsx/jsx-runtime.ts","../src/templates/code-card.tsx","../src/templates/highlight.ts","../src/templates/bench.tsx","../src/templates/milestone.tsx","../src/templates/release-hero.tsx","../src/templates/release-highlights.tsx","../src/templates/registry.ts","../src/core/generate.ts","../src/facts/merge.ts","../src/facts/fact.ts","../src/sources/bench-file.ts","../src/sources/changelog.ts","../src/sources/git.ts","../src/sources/github.ts","../src/sources/npm.ts","../src/sources/package-json.ts","../src/sources/readme.ts","../src/sources/collect.ts","../src/render/takumi.ts","../src/copy/number-guard.ts","../src/copy/llm.ts","../src/outputs/manifest.ts","../src/outputs/files.ts","../src/outputs/github-release.ts","../src/commands/shared.ts","../src/commands/bench.ts","../src/commands/doctor.ts","../src/brand/color.ts","../src/brand/css-vars.ts","../src/brand/dtcg.ts","../src/brand/logo.ts","../src/brand/png.ts","../src/brand/tailwind.ts","../src/brand/detect.ts","../src/commands/init.ts","../src/commands/milestone.ts","../src/commands/release.ts","../src/cli.ts"],"sourcesContent":["// Typed errors: what went wrong, why, how to fix\n// Spec: docs/PROJECT_PLAN.md §0.3\n\nexport class ShipsealError extends Error {\n readonly code: string;\n readonly fix: string;\n\n constructor(code: string, message: string, fix: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"ShipsealError\";\n this.code = code;\n this.fix = fix;\n }\n}\n\nexport function formatError(error: ShipsealError): string {\n return `${error.message}\\nFix: ${error.fix}`;\n}\n","// brand.json zod schema\n// Spec: docs/PROJECT_PLAN.md §10.2\n\nimport { z } from \"zod\";\n\nexport const hexColorSchema = z\n .string()\n .regex(/^#([\\da-f]{6})$/i, \"Expected a 6-digit hex color like #0b0b0c\");\n\nexport const fontFaceSchema = z.object({\n family: z.string().min(1),\n weight: z.number().int().min(100).max(900),\n file: z.string().min(1).optional(),\n});\n\nexport const brandSchema = z.object({\n $schema: z.string().optional(),\n version: z.literal(1),\n name: z.string().min(1),\n tagline: z.string().optional(),\n url: z.string().optional(),\n logo: z\n .object({\n light: z.string().min(1),\n dark: z.string().min(1).optional(),\n })\n .optional(),\n colors: z.object({\n background: hexColorSchema,\n foreground: hexColorSchema,\n muted: hexColorSchema.optional(),\n primary: hexColorSchema.optional(),\n accent: hexColorSchema.optional(),\n }),\n fonts: z.object({\n heading: fontFaceSchema,\n body: fontFaceSchema,\n mono: fontFaceSchema,\n }),\n radius: z.number().nonnegative(),\n theme: z.enum([\"dark\", \"light\"]),\n style: z.literal(\"minimal\"),\n tokens: z.string().nullable(),\n});\n\nexport type Brand = z.infer<typeof brandSchema>;\n\nexport const DEFAULT_BRAND_COLORS = {\n background: \"#0b0b0c\",\n foreground: \"#fafafa\",\n muted: \"#a1a1aa\",\n primary: \"#ff4d4d\",\n accent: \"#fbbf24\",\n} as const;\n\nexport const DEFAULT_BRAND_FONTS = {\n heading: { family: \"Geist\", weight: 700 },\n body: { family: \"Geist\", weight: 400 },\n mono: { family: \"Geist Mono\", weight: 400 },\n} as const;\n","// Load .shipseal/brand.json\n// Spec: docs/PROJECT_PLAN.md §10.1\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { brandSchema, type Brand } from \"./schema.js\";\n\nexport async function loadBrand(cwd: string): Promise<Brand> {\n const path = join(cwd, \".shipseal\", \"brand.json\");\n try {\n const raw: unknown = JSON.parse(await readFile(path, \"utf8\"));\n return brandSchema.parse(raw);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n throw new ShipsealError(\n \"brand.missing\",\n \"No .shipseal/brand.json found.\",\n \"Run shipseal init to detect brand colors and write brand.json.\",\n );\n }\n throw error;\n }\n}\n","// Single table of platform sizes\n// Spec: docs/PROJECT_PLAN.md §14.2\n\nexport const FORMAT_IDS = [\n \"og\",\n \"github-social\",\n \"x\",\n \"linkedin\",\n \"square\",\n \"portrait\",\n \"producthunt\",\n \"readme-banner\",\n] as const;\n\nexport type FormatId = (typeof FORMAT_IDS)[number];\n\nexport interface Format {\n id: FormatId;\n width: number;\n height: number;\n /** Minimum inset for critical text on landscape formats, in px. */\n safeZone: number;\n}\n\nconst LANDSCAPE_SAFE_ZONE = 64;\n\nexport const FORMATS: Record<FormatId, Format> = {\n og: { id: \"og\", width: 1200, height: 630, safeZone: LANDSCAPE_SAFE_ZONE },\n \"github-social\": {\n id: \"github-social\",\n width: 1280,\n height: 640,\n safeZone: LANDSCAPE_SAFE_ZONE,\n },\n x: { id: \"x\", width: 1200, height: 675, safeZone: LANDSCAPE_SAFE_ZONE },\n linkedin: { id: \"linkedin\", width: 1200, height: 627, safeZone: LANDSCAPE_SAFE_ZONE },\n square: { id: \"square\", width: 1080, height: 1080, safeZone: LANDSCAPE_SAFE_ZONE },\n portrait: { id: \"portrait\", width: 1080, height: 1350, safeZone: LANDSCAPE_SAFE_ZONE },\n producthunt: {\n id: \"producthunt\",\n width: 1270,\n height: 760,\n safeZone: LANDSCAPE_SAFE_ZONE,\n },\n \"readme-banner\": {\n id: \"readme-banner\",\n width: 1280,\n height: 400,\n safeZone: LANDSCAPE_SAFE_ZONE,\n },\n};\n\nexport const V1_FORMAT_IDS = [\"og\", \"github-social\", \"x\", \"linkedin\"] as const satisfies readonly FormatId[];\n","// config.json zod schema\n// Spec: docs/PROJECT_PLAN.md §11\n\nimport { z } from \"zod\";\nimport { FORMAT_IDS } from \"../formats.js\";\n\nexport const configSchema = z.object({\n $schema: z.string().optional(),\n version: z.literal(1),\n outputDir: z.string().optional(),\n formats: z.array(z.enum(FORMAT_IDS)).optional(),\n release: z\n .object({\n templates: z.array(z.string()).optional(),\n maxHighlights: z.number().int().positive().optional(),\n changelogPath: z.string().optional(),\n snippet: z.string().nullable().optional(),\n })\n .optional(),\n milestones: z\n .object({\n stars: z.array(z.number().int().positive()).optional(),\n downloads: z.array(z.number().int().positive()).optional(),\n contributors: z.array(z.number().int().positive()).optional(),\n })\n .optional(),\n bench: z\n .object({\n file: z.string().optional(),\n })\n .optional(),\n copy: z\n .object({\n llm: z.boolean().optional(),\n provider: z.string().nullable().optional(),\n model: z.string().nullable().optional(),\n maxRetries: z.number().int().nonnegative().optional(),\n })\n .optional(),\n output: z\n .object({\n imageFormat: z.enum([\"png\", \"webp\", \"jpeg\"]).optional(),\n })\n .optional(),\n attribution: z.boolean().optional(),\n});\n\nexport type Config = z.infer<typeof configSchema>;\n\nexport const DEFAULT_CONFIG: Config = {\n version: 1,\n outputDir: \".shipseal/output\",\n formats: [\"og\", \"github-social\", \"x\", \"linkedin\"],\n release: {\n templates: [\"release-hero\", \"release-highlights\", \"code-card\"],\n maxHighlights: 4,\n changelogPath: \"CHANGELOG.md\",\n snippet: null,\n },\n milestones: {\n stars: [100, 250, 500, 1000, 2500, 5000, 10000],\n downloads: [1000, 10000, 100000, 1000000],\n contributors: [10, 25, 50, 100],\n },\n bench: {\n file: \".shipseal/bench.json\",\n },\n copy: {\n llm: false,\n provider: null,\n model: null,\n maxRetries: 2,\n },\n output: {\n imageFormat: \"png\",\n },\n attribution: true,\n};\n","// Load and merge config (flags > file > defaults)\n// Spec: docs/PROJECT_PLAN.md §11\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { DEFAULT_CONFIG, configSchema, type Config } from \"./schema.js\";\n\nexport async function loadConfig(cwd: string): Promise<Config> {\n const path = join(cwd, \".shipseal\", \"config.json\");\n try {\n const raw: unknown = JSON.parse(await readFile(path, \"utf8\"));\n const parsed = configSchema.parse(raw);\n return mergeConfig(DEFAULT_CONFIG, parsed);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return DEFAULT_CONFIG;\n }\n throw error;\n }\n}\n\nexport function mergeConfig(base: Config, overlay: Config): Config {\n return {\n ...base,\n ...overlay,\n release: { ...base.release, ...overlay.release },\n milestones: { ...base.milestones, ...overlay.milestones },\n bench: { ...base.bench, ...overlay.bench },\n copy: { ...base.copy, ...overlay.copy },\n output: { ...base.output, ...overlay.output },\n };\n}\n","// Copy slots filled by the copy layer\n// Spec: docs/PROJECT_PLAN.md §13.1\n\nexport const COPY_LIMITS = {\n headline: 48,\n subheadline: 90,\n highlight: 56,\n cta: 32,\n milestoneLine: 48,\n} as const;\n\nexport const MAX_HIGHLIGHTS = 4;\n\nexport interface Copy {\n headline: string;\n subheadline: string;\n highlights: string[];\n cta: string;\n milestoneLine?: string;\n codeLines?: CodeLine[];\n}\n\nexport type CodeLine = Array<{ text: string; color: string }>;\n","// No-LLM copy rules (default path)\n// Spec: docs/PROJECT_PLAN.md §13.2\n\nimport type { Facts } from \"../facts/schema.js\";\nimport { MAX_HIGHLIGHTS, type Copy } from \"./slots.js\";\n\nexport function deterministicCopy(facts: Facts, maxHighlights = MAX_HIGHLIGHTS): Copy {\n const name = facts.project.name.value;\n const version = facts.release?.version.value;\n const features = (facts.release?.features ?? []).map((item) => item.value);\n const fixes = (facts.release?.fixes ?? []).map((item) => item.value);\n const breaking = (facts.release?.breaking ?? []).map((item) => item.value);\n\n const headlineSource = features[0];\n const headline =\n headlineSource !== undefined\n ? cleanLine(headlineSource)\n : version === undefined\n ? name\n : `${name} ${version}`;\n\n const tagline = facts.project.tagline?.value;\n const subheadline =\n tagline !== undefined && tagline.length > 0\n ? cleanLine(tagline)\n : cleanLine(features[1] ?? fixes[0] ?? `What's new in ${version ?? name}`);\n\n const highlights: string[] = [];\n for (const line of features) {\n if (highlights.length >= maxHighlights) {\n break;\n }\n highlights.push(cleanLine(line));\n }\n for (const line of fixes) {\n if (highlights.length >= maxHighlights) {\n break;\n }\n highlights.push(cleanLine(line));\n }\n for (const line of breaking) {\n if (highlights.length >= maxHighlights) {\n break;\n }\n highlights.push(`Breaking: ${cleanLine(line)}`);\n }\n\n return {\n headline,\n subheadline,\n highlights,\n cta: ctaFor(facts),\n };\n}\n\nexport function formatCount(value: number): string {\n return value.toLocaleString(\"en-US\");\n}\n\nexport function milestoneCopy(\n facts: Facts,\n metric: \"stars\" | \"downloads\" | \"contributors\",\n threshold: number,\n): Copy {\n const formatted = formatCount(threshold);\n const line =\n metric === \"stars\"\n ? `Thank you for ${formatted} stars`\n : metric === \"downloads\"\n ? `${formatted} weekly downloads`\n : `Thank you, ${formatted} contributors`;\n const tagline = facts.project.tagline?.value;\n return {\n headline: facts.project.name.value,\n subheadline: tagline !== undefined && tagline.length > 0 ? cleanLine(tagline) : \"\",\n highlights: [],\n cta: ctaFor(facts),\n milestoneLine: line,\n };\n}\n\nexport function benchCopy(facts: Facts): Copy {\n const title = facts.bench?.title.value ?? facts.project.name.value;\n const note = facts.bench?.note?.value;\n return {\n headline: title,\n subheadline: note !== undefined && note.length > 0 ? note : (facts.project.tagline?.value ?? \"\"),\n highlights: [],\n cta: ctaFor(facts),\n };\n}\n\nexport function cleanLine(text: string): string {\n const stripped = text.replaceAll(\"\\u2014\", \":\").replaceAll(\"\\u2013\", \"-\").replaceAll(\"!\", \".\").trim();\n const noTrail = stripped.endsWith(\".\") ? stripped.slice(0, -1) : stripped;\n const first = noTrail.at(0);\n if (first === undefined) {\n return noTrail;\n }\n return first.toUpperCase() + noTrail.slice(1);\n}\n\nfunction ctaFor(facts: Facts): string {\n const npm = facts.project.npmPackage?.value;\n if (npm !== undefined && npm.length > 0) {\n return `npm i ${npm}`;\n }\n const url = facts.project.url?.value ?? facts.project.repo?.value;\n if (url === undefined) {\n return facts.project.name.value;\n }\n return url.replace(/^https?:\\/\\//, \"\");\n}\n","// Percent change for benchmark cards. Display numbers are computed here, never by an LLM.\n// Spec: docs/PROJECT_PLAN.md §12.7\n\nexport interface PercentChange {\n signed: number;\n absPercent: number;\n regression: boolean;\n}\n\nexport function percentChange(before: number, after: number, better: \"lower\" | \"higher\"): PercentChange {\n if (before === 0) {\n if (after === 0) {\n return { signed: 0, absPercent: 0, regression: false };\n }\n const improved = better === \"higher\" ? after > 0 : after < 0;\n return { signed: improved ? 100 : -100, absPercent: 100, regression: !improved };\n }\n const raw = better === \"lower\" ? (before - after) / before : (after - before) / before;\n const signed = Math.round(raw * 100);\n return { signed, absPercent: Math.abs(signed), regression: signed < 0 };\n}\n\nexport function changePhrase(unit: string, better: \"lower\" | \"higher\", change: PercentChange): string {\n if (change.absPercent === 0) {\n return \"unchanged\";\n }\n return `${String(change.absPercent)}% ${deltaWord(unit, better, change.regression)}`;\n}\n\nfunction deltaWord(unit: string, better: \"lower\" | \"higher\", regression: boolean): string {\n if (better === \"higher\") {\n return regression ? \"lower\" : \"higher\";\n }\n const normalized = unit.toLowerCase();\n if (normalized === \"ms\" || normalized === \"s\" || normalized === \"sec\" || normalized === \"seconds\") {\n return regression ? \"slower\" : \"faster\";\n }\n if (\n normalized === \"kb\" ||\n normalized === \"mb\" ||\n normalized === \"b\" ||\n normalized === \"bytes\" ||\n normalized === \"gzip\"\n ) {\n return regression ? \"larger\" : \"smaller\";\n }\n return regression ? \"worse\" : \"better\";\n}\n","// Text fitting: shrink, then retry/truncate + manifest warning\n// Spec: docs/PROJECT_PLAN.md §15\n\nimport type { MeasureTextOptions, RendererAdapter } from \"../render/adapter.js\";\n\nexport interface TextSlotSpec {\n maxLines: number;\n maxFontSize: number;\n minFontSize: number;\n step: number;\n box: { width: number };\n}\n\nexport interface FittedText {\n fontSize: number;\n text: string;\n lines: number;\n truncated: boolean;\n}\n\nexport interface FitFont {\n family: string;\n lineHeight: number;\n weight?: number;\n whiteSpace?: \"normal\" | \"pre\";\n}\n\nexport async function fitText(\n renderer: Pick<RendererAdapter, \"measureText\">,\n text: string,\n spec: TextSlotSpec,\n font: FitFont,\n): Promise<FittedText> {\n const sizes = fontSizes(spec);\n for (const fontSize of sizes) {\n // Sizes must be tried largest-first; the first fit wins.\n // eslint-disable-next-line no-await-in-loop -- sequential by spec §15.2\n const measured = await renderer.measureText(text, measureOpts(spec, font, fontSize));\n if (measured.lines <= spec.maxLines) {\n return { fontSize, text, lines: measured.lines, truncated: false };\n }\n }\n\n const fontSize = spec.minFontSize;\n const truncated = await truncateToFit(renderer, text, spec, font, fontSize);\n const measured = await renderer.measureText(truncated, measureOpts(spec, font, fontSize));\n return { fontSize, text: truncated, lines: measured.lines, truncated: truncated !== text };\n}\n\nfunction fontSizes(spec: TextSlotSpec): number[] {\n const sizes: number[] = [];\n for (let size = spec.maxFontSize; size >= spec.minFontSize; size -= spec.step) {\n sizes.push(size);\n }\n const last = sizes[sizes.length - 1];\n if (last !== spec.minFontSize) {\n sizes.push(spec.minFontSize);\n }\n return sizes;\n}\n\nfunction measureOpts(spec: TextSlotSpec, font: FitFont, fontSize: number): MeasureTextOptions {\n const opts: MeasureTextOptions = {\n fontFamily: font.family,\n fontSize,\n maxWidth: spec.box.width,\n lineHeight: font.lineHeight,\n };\n if (font.weight !== undefined) {\n opts.fontWeight = font.weight;\n }\n if (font.whiteSpace !== undefined) {\n opts.whiteSpace = font.whiteSpace;\n }\n return opts;\n}\n\nasync function truncateToFit(\n renderer: Pick<RendererAdapter, \"measureText\">,\n text: string,\n spec: TextSlotSpec,\n font: FitFont,\n fontSize: number,\n): Promise<string> {\n const words = text.trim().length === 0 ? [] : text.trim().split(/\\s+/);\n if (words.length === 0) {\n return text;\n }\n\n const fits = async (candidate: string): Promise<boolean> => {\n const measured = await renderer.measureText(\n candidate,\n measureOpts(spec, font, fontSize),\n );\n return measured.lines <= spec.maxLines;\n };\n\n for (let count = words.length - 1; count >= 1; count -= 1) {\n const candidate = `${words.slice(0, count).join(\" \")}...`;\n // eslint-disable-next-line no-await-in-loop -- drop words until the truncated text fits\n if (await fits(candidate)) {\n return candidate;\n }\n }\n\n const first = words[0];\n if (first === undefined) {\n return \"...\";\n }\n for (let length = first.length; length >= 1; length -= 1) {\n const candidate = `${first.slice(0, length)}...`;\n // eslint-disable-next-line no-await-in-loop -- hard-cut the first word as a last resort\n if (await fits(candidate)) {\n return candidate;\n }\n }\n return \"...\";\n}\n","// Dark/light palette derived from brand.json\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { DEFAULT_BRAND_COLORS, type Brand } from \"../brand/schema.js\";\n\nexport interface ThemeColors {\n background: string;\n foreground: string;\n muted: string;\n primary: string;\n accent: string;\n card: string;\n}\n\nexport function themeColors(brand: Brand, theme: \"dark\" | \"light\"): ThemeColors {\n const primary = brand.colors.primary ?? DEFAULT_BRAND_COLORS.primary;\n const accent = brand.colors.accent ?? DEFAULT_BRAND_COLORS.accent;\n const muted = brand.colors.muted ?? DEFAULT_BRAND_COLORS.muted;\n if (theme === \"dark\") {\n const background = brand.theme === \"dark\" ? brand.colors.background : brand.colors.foreground;\n const foreground = brand.theme === \"dark\" ? brand.colors.foreground : brand.colors.background;\n return {\n background,\n foreground,\n muted: brand.theme === \"dark\" ? muted : DEFAULT_BRAND_COLORS.muted,\n primary,\n accent,\n card: mix(background, foreground, 0.08),\n };\n }\n const background = brand.theme === \"light\" ? brand.colors.background : brand.colors.foreground;\n const foreground = brand.theme === \"light\" ? brand.colors.foreground : brand.colors.background;\n return {\n background,\n foreground,\n muted: brand.theme === \"light\" ? muted : \"#52525b\",\n primary,\n accent,\n card: mix(background, foreground, 0.06),\n };\n}\n\nfunction mix(a: string, b: string, amount: number): string {\n const ar = Number.parseInt(a.slice(1, 3), 16);\n const ag = Number.parseInt(a.slice(3, 5), 16);\n const ab = Number.parseInt(a.slice(5, 7), 16);\n const br = Number.parseInt(b.slice(1, 3), 16);\n const bg = Number.parseInt(b.slice(3, 5), 16);\n const bb = Number.parseInt(b.slice(5, 7), 16);\n return `#${toHex(ar + (br - ar) * amount)}${toHex(ag + (bg - ag) * amount)}${toHex(ab + (bb - ab) * amount)}`;\n}\n\nfunction toHex(value: number): string {\n return Math.round(value).toString(16).padStart(2, \"0\");\n}\n","// Local four-line JSX runtime for Takumi templates (no React)\n// Spec: docs/PROJECT_PLAN.md §16.2, §25 (S1)\n\nexport type JsxElement = {\n type: string | symbol | ((props: Record<string, unknown>) => unknown);\n props: Record<string, unknown> | null;\n key: string | null;\n};\n\nexport function jsx(\n type: JsxElement[\"type\"],\n props: Record<string, unknown> | null,\n key?: string | null,\n): JsxElement {\n return { type, props, key: key ?? null };\n}\n\nexport const jsxs = jsx;\nexport const jsxDEV = jsx;\nexport const Fragment = Symbol.for(\"takumi.fragment\");\n\nexport namespace JSX {\n export type Element = JsxElement;\n export interface ElementChildrenAttribute {\n children: unknown;\n }\n export type IntrinsicElements = Record<string, Record<string, unknown>>;\n}\n","// Template: syntax-highlighted snippet\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { CodeLine, Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst propsSchema = z.object({\n headline: z.string(),\n headingFamily: z.string(),\n monoFamily: z.string(),\n headingWeight: z.number(),\n monoWeight: z.number(),\n radius: z.number(),\n lines: z.array(z.array(z.object({ text: z.string(), color: z.string() }))),\n});\n\nexport type CodeCardProps = z.infer<typeof propsSchema>;\n\nexport const codeCard: TemplateDefinition = {\n id: \"code-card\",\n events: [\"release\"],\n formats: [\"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone;\n return {\n headline: { maxLines: 1, maxFontSize: 40, minFontSize: 28, step: 2, box: { width } },\n };\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n return { headline: props.headline };\n },\n slotFont(raw, slot) {\n const props = propsSchema.parse(raw);\n if (slot === \"headline\") {\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1.1 };\n }\n return { family: props.monoFamily, weight: props.monoWeight, lineHeight: 1.35, whiteSpace: \"pre\" };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n const lines = copy.codeLines ?? [];\n if (lines.length === 0) {\n missing.push({ fact: \"release.codeSnippet\", effect: \"code card uses empty snippet\" });\n }\n return {\n props: {\n headline: copy.headline,\n headingFamily: brand.fonts.heading.family,\n monoFamily: brand.fonts.mono.family,\n headingWeight: brand.fonts.heading.weight,\n monoWeight: brand.fonts.mono.weight,\n radius: brand.radius,\n lines,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const headline = ctx.fitted.headline;\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n gap: 24,\n }}\n >\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: headline?.fontSize ?? 36,\n color: colors.foreground,\n }}\n >\n {headline?.text ?? props.headline}\n </div>\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n flexGrow: 1,\n backgroundColor: colors.card,\n borderRadius: props.radius,\n padding: 28,\n gap: 0,\n }}\n >\n {props.lines.map((line, lineIndex) => (\n <div\n key={String(lineIndex)}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n flexWrap: \"nowrap\",\n }}\n >\n {line.map((token, tokenIndex) => (\n <div\n key={`${String(lineIndex)}-${String(tokenIndex)}`}\n style={{\n fontFamily: props.monoFamily,\n fontWeight: props.monoWeight,\n fontSize: 22,\n color: token.color,\n whiteSpace: \"pre\",\n lineHeight: 1.35,\n }}\n >\n {token.text}\n </div>\n ))}\n </div>\n ))}\n </div>\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: 400,\n fontSize: 18,\n color: colors.muted,\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n );\n },\n};\n\nexport function emptyCodeLines(): CodeLine[] {\n return [[{ text: \" \", color: \"#e6edf3\" }]];\n}\n","// Syntax-highlight a snippet into colored spans (shiki tokens)\n// Spec: docs/PROJECT_PLAN.md §14.3, spike S5\n\nimport type { CodeLine } from \"../copy/slots.js\";\n\nconst MAX_LINES = 14;\n\nexport async function highlightCode(\n code: string,\n lang: string,\n theme: \"dark\" | \"light\",\n): Promise<CodeLine[]> {\n const clipped = code.split(\"\\n\").slice(0, MAX_LINES).join(\"\\n\");\n const fallbackColor = theme === \"dark\" ? \"#e6edf3\" : \"#1f2328\";\n try {\n const { codeToTokens } = await import(\"shiki\");\n const result = await codeToTokens(clipped, {\n lang: mapLang(lang),\n theme: theme === \"dark\" ? \"github-dark\" : \"github-light\",\n });\n return result.tokens.map((line) => {\n if (line.length === 0) {\n return [{ text: \" \", color: fallbackColor }];\n }\n return line.map((token) => ({\n text: token.content,\n color: token.color ?? fallbackColor,\n }));\n });\n } catch {\n return clipped.split(\"\\n\").map((line) => [{ text: line.length === 0 ? \" \" : line, color: fallbackColor }]);\n }\n}\n\nfunction mapLang(lang: string): \"ts\" | \"js\" | \"tsx\" | \"jsx\" | \"json\" | \"bash\" {\n const key = lang.toLowerCase();\n if (key === \"javascript\" || key === \"js\") {\n return \"js\";\n }\n if (key === \"tsx\") {\n return \"tsx\";\n }\n if (key === \"jsx\") {\n return \"jsx\";\n }\n if (key === \"json\") {\n return \"json\";\n }\n if (key === \"bash\" || key === \"shell\" || key === \"sh\") {\n return \"bash\";\n }\n return \"ts\";\n}\n","// Template: before/after metrics\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport { changePhrase, percentChange } from \"../bench/percent.js\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst rowSchema = z.object({\n label: z.string(),\n beforeText: z.string(),\n afterText: z.string(),\n changeText: z.string(),\n regression: z.boolean(),\n});\n\nconst propsSchema = z.object({\n title: z.string(),\n note: z.string(),\n rows: z.array(rowSchema),\n headingFamily: z.string(),\n bodyFamily: z.string(),\n headingWeight: z.number(),\n bodyWeight: z.number(),\n radius: z.number(),\n});\n\nexport type BenchProps = z.infer<typeof propsSchema>;\n\nexport const bench: TemplateDefinition = {\n id: \"bench\",\n events: [\"bench\"],\n formats: [\"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone;\n const slots: Record<string, { maxLines: number; maxFontSize: number; minFontSize: number; step: number; box: { width: number } }> =\n {\n title: { maxLines: 2, maxFontSize: 48, minFontSize: 28, step: 2, box: { width } },\n };\n for (let index = 0; index < 3; index += 1) {\n slots[`change-${String(index)}`] = {\n maxLines: 1,\n maxFontSize: 36,\n minFontSize: 22,\n step: 2,\n box: { width: Math.min(360, width) },\n };\n }\n return slots;\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n const text: Record<string, string> = { title: props.title };\n props.rows.forEach((row, index) => {\n text[`change-${String(index)}`] = row.changeText;\n });\n return text;\n },\n slotFont(raw, slot) {\n const props = propsSchema.parse(raw);\n if (slot === \"title\") {\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1.15 };\n }\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1.1 };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n if (facts.bench === undefined) {\n missing.push({ fact: \"bench\", effect: \"metrics hidden\" });\n }\n const rows =\n facts.bench?.metrics.map((metric) => {\n const change = percentChange(metric.before.value, metric.after.value, metric.better.value);\n return {\n label: metric.label.value,\n beforeText: `${formatMetric(metric.before.value)} ${metric.unit.value}`,\n afterText: `${formatMetric(metric.after.value)} ${metric.unit.value}`,\n changeText: changePhrase(metric.unit.value, metric.better.value, change),\n regression: change.regression,\n };\n }) ?? [];\n return {\n props: {\n title: copy.headline,\n note: copy.subheadline,\n rows,\n headingFamily: brand.fonts.heading.family,\n bodyFamily: brand.fonts.body.family,\n headingWeight: brand.fonts.heading.weight,\n bodyWeight: brand.fonts.body.weight,\n radius: brand.radius,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const title = ctx.fitted.title;\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n }}\n >\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: title?.fontSize ?? 40,\n color: colors.foreground,\n lineHeight: 1.15,\n }}\n >\n {title?.text ?? props.title}\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 20 }}>\n {props.rows.map((row, index) => {\n const change = ctx.fitted[`change-${String(index)}`];\n return (\n <div\n key={row.label}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n backgroundColor: colors.card,\n borderRadius: props.radius,\n paddingTop: 16,\n paddingBottom: 16,\n paddingLeft: 24,\n paddingRight: 24,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 22,\n color: colors.muted,\n }}\n >\n {row.label}\n </div>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 24,\n color: colors.foreground,\n }}\n >\n {`${row.beforeText} to ${row.afterText}`}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"flex-end\", gap: 4 }}>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: change?.fontSize ?? 32,\n color: row.regression ? colors.primary : colors.accent,\n }}\n >\n {change?.text ?? row.changeText}\n </div>\n {row.regression ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.primary,\n }}\n >\n regression\n </div>\n ) : undefined}\n </div>\n </div>\n );\n })}\n </div>\n <div style={{ display: \"flex\", flexDirection: \"row\", justifyContent: \"space-between\", alignItems: \"flex-end\" }}>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 20,\n color: colors.muted,\n }}\n >\n {props.note}\n </div>\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.muted,\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n </div>\n );\n },\n};\n\nfunction formatMetric(value: number): string {\n return String(value);\n}\n","// Template: milestone big number\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport type { Brand } from \"../brand/schema.js\";\nimport { formatCount } from \"../copy/deterministic.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst propsSchema = z.object({\n name: z.string(),\n numberText: z.string(),\n metricLabel: z.string(),\n thankYou: z.string(),\n headingFamily: z.string(),\n bodyFamily: z.string(),\n headingWeight: z.number(),\n bodyWeight: z.number(),\n radius: z.number(),\n showLogo: z.boolean(),\n});\n\nexport type MilestoneProps = z.infer<typeof propsSchema>;\n\nexport const milestone: TemplateDefinition = {\n id: \"milestone\",\n events: [\"milestone\"],\n formats: [\"og\", \"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone;\n return {\n number: { maxLines: 1, maxFontSize: 160, minFontSize: 72, step: 8, box: { width } },\n thankYou: { maxLines: 2, maxFontSize: 36, minFontSize: 24, step: 2, box: { width } },\n };\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n return { number: props.numberText, thankYou: props.thankYou };\n },\n slotFont(raw, slot) {\n const props = propsSchema.parse(raw);\n if (slot === \"number\") {\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1 };\n }\n return { family: props.bodyFamily, weight: props.bodyWeight, lineHeight: 1.25 };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n const threshold = facts.milestone?.threshold.value;\n if (threshold === undefined) {\n missing.push({ fact: \"milestone.threshold\", effect: \"number hidden\" });\n }\n const metric = facts.milestone?.metric.value;\n const metricLabel =\n metric === \"downloads\" ? \"weekly downloads\" : metric === \"contributors\" ? \"contributors\" : \"stars\";\n const showLogo = brand.logo !== undefined;\n if (!showLogo) {\n missing.push({ fact: \"brand.logo\", effect: \"logo hidden\" });\n }\n const thankYou = copy.milestoneLine ?? (threshold === undefined ? \"\" : `Thank you for ${formatCount(threshold)} ${metricLabel}`);\n return {\n props: {\n name: brand.name,\n numberText: threshold === undefined ? \"\" : formatCount(threshold),\n metricLabel,\n thankYou,\n headingFamily: brand.fonts.heading.family,\n bodyFamily: brand.fonts.body.family,\n headingWeight: brand.fonts.heading.weight,\n bodyWeight: brand.fonts.body.weight,\n radius: brand.radius,\n showLogo,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const number = ctx.fitted.number;\n const thanks = ctx.fitted.thankYou;\n const compact = ctx.format.height <= 640;\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"row\", alignItems: \"center\", gap: 20 }}>\n {props.showLogo && ctx.logoSrc !== undefined ? (\n <img src={ctx.logoSrc} width={compact ? 56 : 72} height={compact ? 56 : 72} />\n ) : undefined}\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: 28,\n color: colors.foreground,\n }}\n >\n {props.name}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: number?.fontSize ?? 140,\n color: colors.foreground,\n lineHeight: 1,\n }}\n >\n {number?.text ?? props.numberText}\n </div>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.headingWeight,\n fontSize: 32,\n color: colors.primary,\n }}\n >\n {props.metricLabel}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"row\", justifyContent: \"space-between\", alignItems: \"flex-end\" }}>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: thanks?.fontSize ?? 28,\n color: colors.muted,\n lineHeight: 1.25,\n }}\n >\n {thanks?.text ?? props.thankYou}\n </div>\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.muted,\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n </div>\n );\n },\n};\n","// Template: release hero\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst propsSchema = z.object({\n name: z.string(),\n version: z.string(),\n headline: z.string(),\n subheadline: z.string(),\n cta: z.string(),\n headingFamily: z.string(),\n bodyFamily: z.string(),\n headingWeight: z.number(),\n bodyWeight: z.number(),\n radius: z.number(),\n showCta: z.boolean(),\n showLogo: z.boolean(),\n});\n\nexport type ReleaseHeroProps = z.infer<typeof propsSchema>;\n\nexport const releaseHero: TemplateDefinition = {\n id: \"release-hero\",\n events: [\"release\"],\n formats: [\"og\", \"github-social\", \"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone;\n return {\n headline: { maxLines: 2, maxFontSize: 72, minFontSize: 48, step: 4, box: { width } },\n subheadline: { maxLines: 2, maxFontSize: 32, minFontSize: 24, step: 2, box: { width } },\n cta: { maxLines: 1, maxFontSize: 28, minFontSize: 22, step: 2, box: { width: Math.min(480, width) } },\n };\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n return {\n headline: props.headline,\n subheadline: props.subheadline,\n cta: props.cta,\n };\n },\n slotFont(raw, slot) {\n const props = propsSchema.parse(raw);\n if (slot === \"headline\") {\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1.1 };\n }\n return { family: props.bodyFamily, weight: props.bodyWeight, lineHeight: 1.25 };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n if (facts.project.npmPackage === undefined && facts.project.url === undefined) {\n missing.push({ fact: \"project.npmPackage\", effect: \"cta uses project name\" });\n }\n const showLogo = brand.logo !== undefined;\n if (!showLogo) {\n missing.push({ fact: \"brand.logo\", effect: \"logo hidden\" });\n }\n const version = facts.release?.version.value ?? \"\";\n return {\n props: {\n name: brand.name,\n version,\n headline: copy.headline,\n subheadline: copy.subheadline,\n cta: copy.cta,\n headingFamily: brand.fonts.heading.family,\n bodyFamily: brand.fonts.body.family,\n headingWeight: brand.fonts.heading.weight,\n bodyWeight: brand.fonts.body.weight,\n radius: brand.radius,\n showCta: copy.cta.length > 0,\n showLogo,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const headline = ctx.fitted.headline;\n const sub = ctx.fitted.subheadline;\n const cta = ctx.fitted.cta;\n const compact = ctx.format.height <= 640;\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"row\", alignItems: \"center\", gap: 20 }}>\n {props.showLogo && ctx.logoSrc !== undefined ? (\n <img src={ctx.logoSrc} width={compact ? 56 : 72} height={compact ? 56 : 72} />\n ) : undefined}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: 28,\n color: colors.foreground,\n }}\n >\n {props.name}\n </div>\n {props.version.length > 0 ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n backgroundColor: colors.card,\n borderRadius: props.radius,\n paddingTop: 6,\n paddingBottom: 6,\n paddingLeft: 14,\n paddingRight: 14,\n }}\n >\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 22,\n color: colors.primary,\n }}\n >\n {`v${props.version}`}\n </div>\n </div>\n ) : undefined}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 16 }}>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: headline?.fontSize ?? 64,\n color: colors.foreground,\n lineHeight: 1.1,\n }}\n >\n {headline?.text ?? props.headline}\n </div>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: sub?.fontSize ?? 28,\n color: colors.muted,\n lineHeight: 1.25,\n }}\n >\n {sub?.text ?? props.subheadline}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"row\", justifyContent: \"space-between\", alignItems: \"flex-end\" }}>\n {props.showCta ? (\n <div\n style={{\n display: \"flex\",\n backgroundColor: colors.primary,\n borderRadius: props.radius,\n paddingTop: 14,\n paddingBottom: 14,\n paddingLeft: 24,\n paddingRight: 24,\n }}\n >\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.headingWeight,\n fontSize: cta?.fontSize ?? 24,\n color: colors.background,\n }}\n >\n {cta?.text ?? props.cta}\n </div>\n </div>\n ) : (\n <div />\n )}\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.muted,\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n </div>\n );\n },\n};\n","// Template: what's new list\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst propsSchema = z.object({\n name: z.string(),\n version: z.string(),\n highlights: z.array(z.string()),\n headingFamily: z.string(),\n bodyFamily: z.string(),\n headingWeight: z.number(),\n bodyWeight: z.number(),\n radius: z.number(),\n});\n\nexport type ReleaseHighlightsProps = z.infer<typeof propsSchema>;\n\nexport const releaseHighlights: TemplateDefinition = {\n id: \"release-highlights\",\n events: [\"release\"],\n formats: [\"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone - 48;\n const slots: Record<string, { maxLines: number; maxFontSize: number; minFontSize: number; step: number; box: { width: number } }> = {};\n for (let index = 0; index < 4; index += 1) {\n slots[`highlight-${String(index)}`] = {\n maxLines: 2,\n maxFontSize: 32,\n minFontSize: 24,\n step: 2,\n box: { width },\n };\n }\n return slots;\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n const text: Record<string, string> = {};\n props.highlights.forEach((line, index) => {\n text[`highlight-${String(index)}`] = line;\n });\n return text;\n },\n slotFont(raw) {\n const props = propsSchema.parse(raw);\n return { family: props.bodyFamily, weight: props.bodyWeight, lineHeight: 1.25 };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n if (copy.highlights.length === 0) {\n missing.push({ fact: \"release.features\", effect: \"highlights list empty\" });\n }\n return {\n props: {\n name: brand.name,\n version: facts.release?.version.value ?? \"\",\n highlights: copy.highlights,\n headingFamily: brand.fonts.heading.family,\n bodyFamily: brand.fonts.body.family,\n headingWeight: brand.fonts.heading.weight,\n bodyWeight: brand.fonts.body.weight,\n radius: brand.radius,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const title = props.version.length > 0 ? `What's new in v${props.version}` : \"What's new\";\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n gap: 28,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 22,\n color: colors.primary,\n }}\n >\n {props.name}\n </div>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: 48,\n color: colors.foreground,\n }}\n >\n {title}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 16 }}>\n {props.highlights.map((line, index) => {\n const fitted = ctx.fitted[`highlight-${String(index)}`];\n const breaking = line.startsWith(\"Breaking:\");\n return (\n <div\n key={String(index)}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"flex-start\",\n gap: 16,\n backgroundColor: colors.card,\n borderRadius: props.radius,\n padding: 18,\n }}\n >\n <div\n style={{\n width: 12,\n height: 12,\n borderRadius: 6,\n backgroundColor: breaking ? colors.accent : colors.primary,\n marginTop: 10,\n }}\n />\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: fitted?.fontSize ?? 28,\n color: colors.foreground,\n lineHeight: 1.25,\n }}\n >\n {fitted?.text ?? line}\n </div>\n </div>\n );\n })}\n </div>\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.muted,\n marginTop: \"auto\",\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n );\n },\n};\n","// Template registry\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { ShipsealError } from \"../core/errors.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { bench } from \"./bench.js\";\nimport { codeCard } from \"./code-card.js\";\nimport { milestone } from \"./milestone.js\";\nimport { releaseHero } from \"./release-hero.js\";\nimport { releaseHighlights } from \"./release-highlights.js\";\n\nconst templates = [releaseHero, releaseHighlights, codeCard, milestone, bench] as const;\n\nexport function getTemplate(id: string): TemplateDefinition {\n const found = templates.find((template) => template.id === id);\n if (found === undefined) {\n throw new ShipsealError(\n \"template.unknown\",\n `Unknown template \"${id}\".`,\n `Use one of: ${templates.map((template) => template.id).join(\", \")}.`,\n );\n }\n return found;\n}\n\nexport function templatesForEvent(kind: \"release\" | \"milestone\" | \"bench\"): TemplateDefinition[] {\n return templates.filter((template) => template.events.includes(kind));\n}\n\nexport const RELEASE_TEMPLATE_IDS = [\"release-hero\", \"release-highlights\", \"code-card\"] as const;\n","// The pure pipeline: facts + copy + brand + templates -> rendered files (no network I/O)\n// Spec: docs/PROJECT_PLAN.md §6.1\n\nimport { createHash } from \"node:crypto\";\nimport { percentChange } from \"../bench/percent.js\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { Config } from \"../config/schema.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { ShipsealEvent } from \"./events.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { fitText, type FittedText } from \"../fit/fit-text.js\";\nimport { FORMATS, type Format, type FormatId } from \"../formats.js\";\nimport type { ImageFormat, RenderOptions, RendererAdapter } from \"../render/adapter.js\";\nimport { emptyCodeLines } from \"../templates/code-card.js\";\nimport type { ManifestMissing, RenderContext, TemplateDefinition } from \"../templates/contract.js\";\nimport { highlightCode } from \"../templates/highlight.js\";\nimport { getTemplate } from \"../templates/registry.js\";\n\nexport interface GenerateInput {\n event: ShipsealEvent;\n facts: Facts;\n brand: Brand;\n config: Config;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n renderer: RendererAdapter;\n themes: Array<\"dark\" | \"light\">;\n generatedAt: string;\n logos?: { light?: Uint8Array; dark?: Uint8Array };\n}\n\nexport interface GeneratedFile {\n fileName: string;\n template: string;\n format: FormatId;\n theme: \"dark\" | \"light\";\n width: number;\n height: number;\n bytes: Uint8Array;\n sha256: string;\n}\n\nexport interface FitWarning {\n type: \"fit-warning\";\n template: string;\n format: FormatId;\n slot: string;\n action: \"truncated\";\n}\n\nexport interface GenerateResult {\n files: GeneratedFile[];\n warnings: FitWarning[];\n missing: Array<ManifestMissing & { template: string }>;\n facts: Facts;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n generatedAt: string;\n computed: Record<string, { value: unknown; computedFrom: string[] }>;\n}\n\nexport async function generate(input: GenerateInput): Promise<GenerateResult> {\n const templateIds = templateIdsFor(input.event, input.config);\n const formatIds = input.config.formats ?? [\"og\", \"github-social\", \"x\", \"linkedin\"];\n const imageFormat: ImageFormat = input.config.output?.imageFormat ?? \"png\";\n const attribution = input.config.attribution !== false;\n const files: GeneratedFile[] = [];\n const warnings: FitWarning[] = [];\n const missing: Array<ManifestMissing & { template: string }> = [];\n const recordedMissing = new Set<string>();\n const omitThemeSuffix = input.themes.length === 1;\n\n for (const templateId of templateIds) {\n const template = getTemplate(templateId);\n if (!template.events.includes(input.event.kind)) {\n continue;\n }\n for (const formatId of formatIds) {\n if (!template.formats.includes(formatId)) {\n continue;\n }\n const format = FORMATS[formatId];\n for (const theme of input.themes) {\n // Formats and themes render sequentially so fit warnings stay attached to the right file.\n // eslint-disable-next-line no-await-in-loop\n const copy = await copyForTemplate(template.id, input.copy, input.facts, theme);\n const built = template.buildProps(input.facts, copy, input.brand);\n const props = template.propsSchema.parse(built.props);\n if (!recordedMissing.has(template.id)) {\n recordedMissing.add(template.id);\n for (const item of built.missing) {\n missing.push({ template: template.id, fact: item.fact, effect: item.effect });\n }\n }\n // eslint-disable-next-line no-await-in-loop\n const { fitted, truncated } = await fitSlots(input.renderer, template, props, format);\n for (const slot of truncated) {\n warnings.push({\n type: \"fit-warning\",\n template: template.id,\n format: formatId,\n slot,\n action: \"truncated\",\n });\n }\n const logo = logoForTheme(input.logos, theme);\n const ctx: RenderContext = {\n format,\n theme,\n brand: input.brand,\n fitted,\n attribution,\n };\n if (logo !== undefined) {\n ctx.logoSrc = \"shipseal-logo\";\n }\n const jsx = template.render(props, ctx);\n // eslint-disable-next-line no-await-in-loop\n const node = await input.renderer.fromJsx(jsx);\n const renderOpts: RenderOptions = {\n width: format.width,\n height: format.height,\n format: imageFormat,\n };\n if (logo !== undefined) {\n renderOpts.images = [{ src: \"shipseal-logo\", data: logo }];\n }\n // eslint-disable-next-line no-await-in-loop\n const bytes = await input.renderer.render(node, renderOpts);\n const fileName = outputName(template.id, formatId, theme, omitThemeSuffix, imageFormat);\n files.push({\n fileName,\n template: template.id,\n format: formatId,\n theme,\n width: format.width,\n height: format.height,\n bytes,\n sha256: createHash(\"sha256\").update(bytes).digest(\"hex\"),\n });\n }\n }\n }\n\n return {\n files,\n warnings,\n missing,\n facts: input.facts,\n copy: input.copy,\n copyMode: input.copyMode,\n generatedAt: input.generatedAt,\n computed: computedFromFacts(input.facts),\n };\n}\n\nfunction templateIdsFor(event: ShipsealEvent, config: Config): string[] {\n if (event.kind === \"milestone\") {\n return [\"milestone\"];\n }\n if (event.kind === \"bench\") {\n return [\"bench\"];\n }\n return config.release?.templates ?? [\"release-hero\", \"release-highlights\", \"code-card\"];\n}\n\nfunction computedFromFacts(facts: Facts): Record<string, { value: unknown; computedFrom: string[] }> {\n const out: Record<string, { value: unknown; computedFrom: string[] }> = {};\n if (facts.bench === undefined) {\n return out;\n }\n facts.bench.metrics.forEach((metric, index) => {\n const change = percentChange(metric.before.value, metric.after.value, metric.better.value);\n const prefix = `bench.metrics[${String(index)}]`;\n out[`${prefix}.percent`] = {\n value: change.signed,\n computedFrom: [`${prefix}.before`, `${prefix}.after`, `${prefix}.better`],\n };\n });\n return out;\n}\n\nasync function fitSlots(\n renderer: RendererAdapter,\n template: TemplateDefinition,\n props: unknown,\n format: Format,\n): Promise<{ fitted: Record<string, FittedText>; truncated: string[] }> {\n const specs = template.slots(format);\n const texts = template.slotText(props);\n const fitted: Record<string, FittedText> = {};\n const truncated: string[] = [];\n for (const [slot, spec] of Object.entries(specs)) {\n const text = texts[slot];\n if (text === undefined) {\n continue;\n }\n const font = template.slotFont(props, slot);\n const fitFont: { family: string; lineHeight: number; weight: number; whiteSpace?: \"normal\" | \"pre\" } = {\n family: font.family,\n lineHeight: font.lineHeight,\n weight: font.weight,\n };\n if (font.whiteSpace !== undefined) {\n fitFont.whiteSpace = font.whiteSpace;\n }\n // eslint-disable-next-line no-await-in-loop -- sizes are sequential per slot spec\n const result = await fitText(renderer, text, spec, fitFont);\n fitted[slot] = result;\n if (result.truncated) {\n truncated.push(slot);\n }\n }\n return { fitted, truncated };\n}\n\nfunction outputName(\n template: string,\n format: FormatId,\n theme: \"dark\" | \"light\",\n omitTheme: boolean,\n imageFormat: string,\n): string {\n const themePart = omitTheme ? \"\" : `-${theme}`;\n return `${template}-${format}${themePart}.${imageFormat}`;\n}\n\nfunction logoForTheme(\n logos: GenerateInput[\"logos\"],\n theme: \"dark\" | \"light\",\n): Uint8Array | undefined {\n if (logos === undefined) {\n return undefined;\n }\n if (theme === \"dark\") {\n return logos.dark ?? logos.light;\n }\n return logos.light ?? logos.dark;\n}\n\nasync function copyForTemplate(\n templateId: string,\n copy: Copy,\n facts: Facts,\n theme: \"dark\" | \"light\",\n): Promise<Copy> {\n if (templateId !== \"code-card\") {\n return copy;\n }\n const snippet = facts.release?.codeSnippet?.value;\n if (snippet === undefined) {\n return { ...copy, codeLines: emptyCodeLines() };\n }\n return { ...copy, codeLines: await highlightCode(snippet.code, snippet.lang, theme) };\n}\n","// Merge partial Facts from sources. Later sources fill holes.\n// Changelog feature lists replace git commit lists when present.\n// Spec: docs/PROJECT_PLAN.md §12\n\nimport { ShipsealError } from \"../core/errors.js\";\nimport type { Facts } from \"./schema.js\";\nimport type { PartialFacts, PartialMetrics, PartialMilestone, PartialProject, PartialRelease } from \"./partial.js\";\n\nexport function mergeFacts(parts: PartialFacts[]): Facts {\n const project: PartialProject = {};\n const release: PartialRelease = {};\n const metrics: PartialMetrics = {};\n const milestone: PartialMilestone = {};\n let bench: Facts[\"bench\"];\n\n for (const part of parts) {\n fillObject(project, part.project);\n mergeRelease(release, part.release);\n fillObject(metrics, part.metrics);\n fillObject(milestone, part.milestone);\n if (part.bench !== undefined) {\n bench = part.bench;\n }\n }\n\n if (project.name === undefined) {\n throw new ShipsealError(\n \"facts.missing-name\",\n \"Could not determine the project name.\",\n \"Add a name field to package.json, or an H1 in README.md.\",\n );\n }\n\n const facts: Facts = {\n project: {\n name: project.name,\n },\n };\n if (project.tagline !== undefined) {\n facts.project.tagline = project.tagline;\n }\n if (project.url !== undefined) {\n facts.project.url = project.url;\n }\n if (project.repo !== undefined) {\n facts.project.repo = project.repo;\n }\n if (project.npmPackage !== undefined) {\n facts.project.npmPackage = project.npmPackage;\n }\n if (project.license !== undefined) {\n facts.project.license = project.license;\n }\n\n // A partial release block is dropped, not fatal. `package.json#version` alone makes\n // `hasRelease` true on every project, so throwing here broke `bench` and `milestone`,\n // which do not need release facts at all (§6.3). The release event still errors, in\n // collectFacts, where the check knows the event kind.\n if (isCompleteRelease(release)) {\n facts.release = {\n version: release.version,\n tag: release.tag,\n date: release.date,\n features: release.features ?? [],\n fixes: release.fixes ?? [],\n breaking: release.breaking ?? [],\n };\n if (release.previousVersion !== undefined) {\n facts.release.previousVersion = release.previousVersion;\n }\n if (release.commitCount !== undefined) {\n facts.release.commitCount = release.commitCount;\n }\n if (release.contributors !== undefined) {\n facts.release.contributors = release.contributors;\n }\n if (release.codeSnippet !== undefined) {\n facts.release.codeSnippet = release.codeSnippet;\n }\n }\n\n if (Object.keys(metrics).length > 0) {\n facts.metrics = metrics;\n }\n if (bench !== undefined) {\n facts.bench = bench;\n }\n if (milestone.metric !== undefined && milestone.threshold !== undefined) {\n facts.milestone = { metric: milestone.metric, threshold: milestone.threshold };\n }\n return facts;\n}\n\nfunction mergeRelease(target: PartialRelease, overlay: PartialRelease | undefined): void {\n if (overlay === undefined) {\n return;\n }\n fillObject(target, overlay, [\"features\", \"fixes\", \"breaking\"]);\n replaceList(target, overlay, \"features\");\n replaceList(target, overlay, \"fixes\");\n replaceList(target, overlay, \"breaking\");\n}\n\nfunction replaceList(\n target: PartialRelease,\n overlay: PartialRelease,\n key: \"features\" | \"fixes\" | \"breaking\",\n): void {\n const next = overlay[key];\n if (next !== undefined) {\n target[key] = next;\n }\n}\n\nfunction fillObject<T extends object>(target: T, overlay: T | undefined, skip: (keyof T)[] = []): void {\n if (overlay === undefined) {\n return;\n }\n const skipped = new Set(skip);\n for (const key of Object.keys(overlay) as (keyof T)[]) {\n if (skipped.has(key)) {\n continue;\n }\n const value = overlay[key];\n if (value !== undefined && target[key] === undefined) {\n target[key] = value;\n }\n }\n}\n\nfunction isCompleteRelease(\n release: PartialRelease,\n): release is PartialRelease &\n Required<Pick<PartialRelease, \"version\" | \"tag\" | \"date\">> {\n return release.version !== undefined && release.tag !== undefined && release.date !== undefined;\n}\n","// fact() helper that attaches provenance\n// Spec: docs/PROJECT_PLAN.md §9.1\n\nimport type { Fact, SourceId } from \"./schema.js\";\n\nexport function fact<T>(\n value: T,\n provenance: { source: SourceId; ref: string; fetchedAt?: string },\n): Fact<T> {\n const fetchedAt = provenance.fetchedAt ?? new Date().toISOString();\n return {\n value,\n provenance: {\n source: provenance.source,\n ref: provenance.ref,\n fetchedAt,\n },\n };\n}\n","// Benchmark JSON reader\n// Spec: docs/PROJECT_PLAN.md §12.7\n\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join } from \"node:path\";\nimport { z } from \"zod\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\n\nconst metricSchema = z.object({\n label: z.string().min(1),\n before: z.number().finite(),\n after: z.number().finite(),\n unit: z.string().min(1),\n better: z.enum([\"lower\", \"higher\"]),\n});\n\nconst benchFileSchema = z.object({\n title: z.string().min(1),\n metrics: z.array(metricSchema).min(1).max(3),\n note: z.string().optional(),\n});\n\nexport async function collectBenchFile(cwd: string, filePath = \".shipseal/bench.json\"): Promise<PartialFacts> {\n const resolved = isAbsolute(filePath) ? filePath : join(cwd, filePath);\n let raw: string;\n try {\n raw = await readFile(resolved, \"utf8\");\n } catch (error) {\n throw new ShipsealError(\n \"bench.missing-file\",\n `Benchmark file not found: ${filePath}.`,\n \"Write .shipseal/bench.json (title, metrics with before/after/unit/better), or pass --file <path>.\",\n { cause: error },\n );\n }\n let json: unknown;\n try {\n json = JSON.parse(raw);\n } catch (error) {\n throw new ShipsealError(\n \"bench.invalid-json\",\n `Benchmark file is not valid JSON: ${filePath}.`,\n \"Fix the JSON syntax, then retry.\",\n { cause: error },\n );\n }\n const parsed = benchFileSchema.safeParse(json);\n if (!parsed.success) {\n throw new ShipsealError(\n \"bench.invalid-shape\",\n `Benchmark file is missing required fields: ${filePath}.`,\n 'Each metric needs label, before, after, unit, and better (\"lower\" or \"higher\"). At most 3 metrics.',\n );\n }\n const fetchedAt = new Date().toISOString();\n const ref = filePath;\n const bench: NonNullable<Facts[\"bench\"]> = {\n title: fact(parsed.data.title, { source: \"bench-file\", ref: `${ref}#title`, fetchedAt }),\n metrics: parsed.data.metrics.map((metric, index) => ({\n label: fact(metric.label, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].label`, fetchedAt }),\n before: fact(metric.before, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].before`, fetchedAt }),\n after: fact(metric.after, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].after`, fetchedAt }),\n unit: fact(metric.unit, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].unit`, fetchedAt }),\n better: fact(metric.better, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].better`, fetchedAt }),\n })),\n };\n if (parsed.data.note !== undefined) {\n bench.note = fact(parsed.data.note, { source: \"bench-file\", ref: `${ref}#note`, fetchedAt });\n }\n return { bench };\n}\n","// Keep a Changelog + Changesets parsing\n// Spec: docs/PROJECT_PLAN.md §12.4\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Fact } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\n\nexport async function collectChangelog(\n cwd: string,\n version: string | undefined,\n changelogPath = \"CHANGELOG.md\",\n): Promise<PartialFacts> {\n if (version === undefined) {\n return {};\n }\n let markdown: string;\n try {\n markdown = await readFile(join(cwd, changelogPath), \"utf8\");\n } catch {\n return {};\n }\n const section = findVersionSection(markdown, version);\n if (section === undefined) {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const features: Fact<string>[] = [];\n const fixes: Fact<string>[] = [];\n const breaking: Fact<string>[] = [];\n\n for (const group of parseGroups(section.body)) {\n const bucket = bucketForHeading(group.heading);\n if (bucket === undefined) {\n continue;\n }\n for (const item of group.items) {\n const cleaned = cleanChangelogItem(item);\n if (cleaned.length === 0) {\n continue;\n }\n const entry = fact(cleaned, {\n source: \"changelog\",\n ref: `${changelogPath} ${section.heading} ${group.heading}: ${item}`,\n fetchedAt,\n });\n if (bucket === \"features\") {\n features.push(entry);\n } else if (bucket === \"fixes\") {\n fixes.push(entry);\n } else {\n breaking.push(entry);\n }\n }\n }\n\n const out: PartialFacts = {\n release: {\n version: fact(version.replace(/^v/, \"\"), {\n source: \"changelog\",\n ref: `${changelogPath} ${section.heading}`,\n fetchedAt,\n }),\n tag: fact(version.startsWith(\"v\") ? version : `v${version}`, {\n source: \"changelog\",\n ref: `${changelogPath} ${section.heading}`,\n fetchedAt,\n }),\n features,\n fixes,\n breaking,\n },\n };\n if (section.date !== undefined) {\n out.release = {\n ...out.release,\n date: fact(section.date, {\n source: \"changelog\",\n ref: `${changelogPath} ${section.heading}`,\n fetchedAt,\n }),\n };\n }\n return out;\n}\n\nexport function findVersionSection(\n markdown: string,\n version: string,\n): { heading: string; body: string; date?: string } | undefined {\n const needle = version.replace(/^v/, \"\");\n const headingRe = /^##\\s+(.+)$/gm;\n const matches = [...markdown.matchAll(headingRe)];\n for (let index = 0; index < matches.length; index += 1) {\n const match = matches[index];\n if (match === undefined) {\n continue;\n }\n const heading = match[1];\n if (heading === undefined || !headingIncludesVersion(heading, needle)) {\n continue;\n }\n const start = (match.index ?? 0) + match[0].length;\n const next = matches[index + 1];\n const end = next?.index ?? markdown.length;\n const date = extractDate(heading);\n const body = markdown.slice(start, end);\n if (date === undefined) {\n return { heading, body };\n }\n return { heading, body, date };\n }\n return undefined;\n}\n\nexport function cleanChangelogItem(item: string): string {\n return item\n .replace(/^\\s*[-*]\\s*/, \"\")\n .replace(/\\[`[a-f0-9]{7,40}`]\\([^)]+\\)/gi, \"\")\n .replace(/^[a-f0-9]{7,40}:\\s*/i, \"\")\n .replace(/\\(#\\d+\\)/g, \"\")\n .replace(/\\[#\\d+]\\([^)]+\\)/g, \"\")\n .replace(/Thanks\\s+\\[@[\\w-]+]\\([^)]+\\)!?\\s*-?\\s*/gi, \"\")\n .replace(/\\[@[\\w-]+]\\([^)]+\\)/g, \"\")\n .replace(/\\(@[\\w-]+\\)/g, \"\")\n .replace(/\\s+by\\s+@[\\w-]+/gi, \"\")\n .replace(/@[\\w-]+/g, \"\")\n .replace(/^Thanks\\s*!?\\s*-?\\s*/i, \"\")\n .replace(/^\\s*[-*]\\s*/, \"\")\n .replace(/\\s+/g, \" \")\n .trim()\n .replace(/\\.$/, \"\");\n}\n\nfunction headingIncludesVersion(heading: string, version: string): boolean {\n const unwrapped = heading.replace(/[[\\]]/g, \" \");\n return new RegExp(`(?:^|\\\\s)v?${escapeRegExp(version)}(?:\\\\s|$)`).test(unwrapped);\n}\n\nfunction extractDate(heading: string): string | undefined {\n const match = /(\\d{4}-\\d{2}-\\d{2})/.exec(heading);\n return match?.[1];\n}\n\nfunction parseGroups(body: string): Array<{ heading: string; items: string[] }> {\n const groups: Array<{ heading: string; items: string[] }> = [];\n const headingRe = /^###\\s+(.+)$/gm;\n const matches = [...body.matchAll(headingRe)];\n if (matches.length === 0) {\n return [{ heading: \"Added\", items: listItems(body) }];\n }\n for (let index = 0; index < matches.length; index += 1) {\n const match = matches[index];\n if (match === undefined) {\n continue;\n }\n const heading = match[1];\n if (heading === undefined) {\n continue;\n }\n const start = (match.index ?? 0) + match[0].length;\n const next = matches[index + 1];\n const end = next?.index ?? body.length;\n groups.push({ heading, items: listItems(body.slice(start, end)) });\n }\n return groups;\n}\n\nfunction listItems(block: string): string[] {\n const items: string[] = [];\n let current: string | undefined;\n for (const raw of block.split(\"\\n\")) {\n const trimmed = raw.trim();\n if (trimmed.startsWith(\"- \") || trimmed.startsWith(\"* \")) {\n if (current !== undefined) {\n items.push(current);\n }\n current = trimmed;\n continue;\n }\n if (current !== undefined && trimmed.length > 0 && !trimmed.startsWith(\"#\")) {\n current = `${current} ${trimmed}`;\n }\n }\n if (current !== undefined) {\n items.push(current);\n }\n return items;\n}\n\nfunction bucketForHeading(heading: string): \"features\" | \"fixes\" | \"breaking\" | undefined {\n const key = heading.trim().toLowerCase();\n if (\n key === \"added\" ||\n key === \"changed\" ||\n key === \"minor changes\" ||\n key === \"features\"\n ) {\n return \"features\";\n }\n if (key === \"fixed\" || key === \"patch changes\" || key === \"security\" || key === \"fixes\") {\n return \"fixes\";\n }\n if (\n key === \"removed\" ||\n key === \"major changes\" ||\n key === \"breaking\" ||\n key === \"breaking changes\"\n ) {\n return \"breaking\";\n }\n return undefined;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","// git source: tags, commits, contributors\n// Spec: docs/PROJECT_PLAN.md §12.1\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Fact } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\nimport { cleanChangelogItem } from \"./changelog.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function collectGit(\n cwd: string,\n event: { tag?: string; previousTag?: string },\n): Promise<PartialFacts> {\n const inside = await git(cwd, [\"rev-parse\", \"--is-inside-work-tree\"]);\n if (inside !== \"true\") {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const tag = event.tag ?? (await gitCurrentTag(cwd));\n if (tag === undefined) {\n return {};\n }\n const exists = await git(cwd, [\"rev-parse\", \"--verify\", `${tag}^{commit}`]);\n if (exists === undefined) {\n return {};\n }\n const version = versionFromTag(tag);\n const tags = await gitLines(cwd, [\"tag\", \"--sort=-v:refname\"]);\n const tagIndex = tags.indexOf(tag);\n const previousTag =\n event.previousTag ?? (tagIndex >= 0 ? tags[tagIndex + 1] : tags.find((candidate) => candidate !== tag));\n const range = previousTag === undefined ? tag : `${previousTag}..${tag}`;\n const log = await git(cwd, [\"log\", range, \"--pretty=format:%s\\t%an\\t%ae\\t%h\\t%cI\"]);\n const commits = (log ?? \"\").split(\"\\n\").filter((line) => line.length > 0);\n const features: Fact<string>[] = [];\n const fixes: Fact<string>[] = [];\n const breaking: Fact<string>[] = [];\n const contributors = new Map<string, string>();\n\n for (const line of commits) {\n const [subject, author, email, hash] = line.split(\"\\t\");\n if (subject === undefined || hash === undefined) {\n continue;\n }\n const parsed = parseConventional(subject);\n const display = parsed.display;\n const ref = `git log ${range} ${hash}`;\n const item = fact(display, { source: \"git\", ref, fetchedAt });\n if (parsed.breaking) {\n breaking.push(item);\n } else if (parsed.type === \"feat\") {\n features.push(item);\n } else if (parsed.type === \"fix\" || parsed.type === \"perf\") {\n fixes.push(item);\n }\n if (email !== undefined && author !== undefined && !isBot(author, email)) {\n contributors.set(email, author);\n }\n }\n\n const dateLine = await git(cwd, [\"log\", \"-1\", \"--format=%cI\", tag]);\n const date = (dateLine ?? fetchedAt).slice(0, 10);\n const names = [...contributors.values()];\n\n const release: NonNullable<PartialFacts[\"release\"]> = {\n version: fact(version, { source: \"git\", ref: `git tag ${tag}`, fetchedAt }),\n tag: fact(tag, { source: \"git\", ref: `git tag ${tag}`, fetchedAt }),\n date: fact(date, { source: \"git\", ref: `git log -1 --format=%cI ${tag}`, fetchedAt }),\n features,\n fixes,\n breaking,\n commitCount: fact(commits.length, {\n source: \"git\",\n ref: `git rev-list --count ${range}`,\n fetchedAt,\n }),\n };\n if (previousTag !== undefined) {\n release.previousVersion = fact(versionFromTag(previousTag), {\n source: \"git\",\n ref: `git tag ${previousTag}`,\n fetchedAt,\n });\n }\n if (names.length > 0) {\n release.contributors = fact(names, {\n source: \"git\",\n ref: `git log ${range} unique authors`,\n fetchedAt,\n });\n }\n return { release };\n}\n\nexport function parseConventional(subject: string): {\n type: string | undefined;\n display: string;\n breaking: boolean;\n} {\n const match = /^(?<type>\\w+)(?<scope>\\([^)]+\\))?(?<bang>!)?:\\s*(?<rest>.+)$/.exec(subject);\n if (match === null || match.groups === undefined) {\n return { type: undefined, display: displaySubject(subject), breaking: false };\n }\n const type = match.groups.type;\n const rest = match.groups.rest ?? subject;\n const breaking = match.groups.bang === \"!\" || /BREAKING CHANGE:/.test(subject);\n return { type, display: displaySubject(rest), breaking };\n}\n\nexport function versionFromTag(tag: string): string {\n const at = tag.lastIndexOf(\"@\");\n if (at >= 0 && at < tag.length - 1) {\n return tag.slice(at + 1).replace(/^v/, \"\");\n }\n return tag.replace(/^v/, \"\");\n}\n\nexport async function gitCurrentTag(cwd: string): Promise<string | undefined> {\n return git(cwd, [\"describe\", \"--tags\", \"--abbrev=0\"]);\n}\n\nasync function git(cwd: string, args: string[]): Promise<string | undefined> {\n try {\n const { stdout } = await execFileAsync(\"git\", args, { cwd });\n const trimmed = stdout.trim();\n return trimmed.length === 0 ? undefined : trimmed;\n } catch {\n return undefined;\n }\n}\n\nasync function gitLines(cwd: string, args: string[]): Promise<string[]> {\n const out = await git(cwd, args);\n return out === undefined ? [] : out.split(\"\\n\").filter((line) => line.length > 0);\n}\n\nfunction isBot(author: string, email: string): boolean {\n const haystack = `${author} ${email}`.toLowerCase();\n return (\n author.endsWith(\"[bot]\") ||\n haystack.includes(\"dependabot\") ||\n haystack.includes(\"renovate\") ||\n haystack.includes(\"github-actions\")\n );\n}\n\nfunction displaySubject(text: string): string {\n const cleaned = cleanChangelogItem(text);\n const first = cleaned.at(0);\n if (first === undefined) {\n return cleaned;\n }\n return first.toUpperCase() + cleaned.slice(1);\n}\n","// GitHub REST via fetch (token optional)\n// Spec: docs/PROJECT_PLAN.md §12.5\n// Docs checked 2026-09-11: https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28\n// GET /repos/{owner}/{repo}\n// GET /repos/{owner}/{repo}/releases/tags/{tag}\n// GET /repos/{owner}/{repo}/contributors\n// Headers: Accept application/vnd.github+json, X-GitHub-Api-Version 2022-11-28\n\nimport { z } from \"zod\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Fact } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\n\nconst API_VERSION = \"2022-11-28\";\nconst API_ROOT = \"https://api.github.com\";\n\nconst repoSchema = z.object({\n stargazers_count: z.number().int().nonnegative(),\n description: z.string().nullable().optional(),\n homepage: z.string().nullable().optional(),\n license: z.object({ spdx_id: z.string().nullable() }).nullable().optional(),\n});\n\nconst releaseSchema = z.object({\n body: z.string().nullable().optional(),\n});\n\nconst contributorsSchema = z.array(z.unknown());\n\nexport interface GithubCacheEntry {\n json: unknown;\n link: string | null;\n}\n\nexport interface GithubCollectOptions {\n repo: string;\n tag?: string;\n token?: string;\n fetchImpl?: typeof fetch;\n cache?: Map<string, GithubCacheEntry>;\n}\n\nexport async function collectGithub(options: GithubCollectOptions): Promise<PartialFacts> {\n const slug = parseRepo(options.repo);\n if (slug === undefined) {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const fetchImpl = options.fetchImpl ?? fetch;\n const cache = options.cache ?? new Map<string, GithubCacheEntry>();\n const repoResponse = await githubGet(\n `${API_ROOT}/repos/${slug.owner}/${slug.repo}`,\n options.token,\n fetchImpl,\n cache,\n );\n if (repoResponse === undefined) {\n return {};\n }\n const repo = repoSchema.parse(repoResponse.json);\n const out: PartialFacts = {\n metrics: {\n stars: fact(repo.stargazers_count, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo} stargazers_count`,\n fetchedAt,\n }),\n },\n project: {},\n };\n if (repo.description !== undefined && repo.description !== null && repo.description.length > 0) {\n out.project = {\n ...out.project,\n tagline: fact(repo.description, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo} description`,\n fetchedAt,\n }),\n };\n }\n if (repo.homepage !== undefined && repo.homepage !== null && repo.homepage.length > 0) {\n out.project = {\n ...out.project,\n url: fact(repo.homepage, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo} homepage`,\n fetchedAt,\n }),\n };\n }\n const license = repo.license?.spdx_id;\n if (license !== undefined && license !== null && license !== \"NOASSERTION\") {\n out.project = {\n ...out.project,\n license: fact(license, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo} license.spdx_id`,\n fetchedAt,\n }),\n };\n }\n\n if (options.tag !== undefined) {\n const releaseResponse = await githubGet(\n `${API_ROOT}/repos/${slug.owner}/${slug.repo}/releases/tags/${encodeURIComponent(options.tag)}`,\n options.token,\n fetchImpl,\n cache,\n { notFoundOk: true },\n );\n if (releaseResponse !== undefined) {\n const release = releaseSchema.parse(releaseResponse.json);\n const features = featuresFromReleaseBody(release.body ?? \"\", options.tag, fetchedAt);\n if (features.length > 0) {\n out.release = { features };\n }\n }\n }\n\n const contributors = await githubGet(\n `${API_ROOT}/repos/${slug.owner}/${slug.repo}/contributors?per_page=1&anon=true`,\n options.token,\n fetchImpl,\n cache,\n { notFoundOk: true },\n );\n if (contributors !== undefined) {\n contributorsSchema.parse(contributors.json);\n const listed = Array.isArray(contributors.json) ? contributors.json.length : 0;\n const fromLink = lastPageFromLink(contributors.link);\n out.metrics = {\n ...out.metrics,\n contributorCount: fact(fromLink ?? listed, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo}/contributors`,\n fetchedAt,\n }),\n };\n }\n\n return out;\n}\n\nexport function parseRepo(value: string): { owner: string; repo: string } | undefined {\n const trimmed = value.trim().replace(/\\.git$/, \"\");\n const match = /^(?:https?:\\/\\/github\\.com\\/)?([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+)$/.exec(trimmed);\n if (match === null || match[1] === undefined || match[2] === undefined) {\n return undefined;\n }\n return { owner: match[1], repo: match[2] };\n}\n\nfunction featuresFromReleaseBody(body: string, tag: string, fetchedAt: string): Fact<string>[] {\n const lines = body\n .split(\"\\n\")\n .map((line) => line.replace(/^\\s*[-*]\\s*/, \"\").trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n return lines.slice(0, 8).map((line) =>\n fact(line.replace(/\\.$/, \"\"), {\n source: \"github-api\",\n ref: `GET /repos/.../releases/tags/${tag} body`,\n fetchedAt,\n }),\n );\n}\n\nasync function githubGet(\n url: string,\n token: string | undefined,\n fetchImpl: typeof fetch,\n cache: Map<string, GithubCacheEntry>,\n opts: { notFoundOk?: boolean } = {},\n): Promise<GithubCacheEntry | undefined> {\n const cached = cache.get(url);\n if (cached !== undefined) {\n return cached;\n }\n const headers: Record<string, string> = {\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": API_VERSION,\n \"User-Agent\": \"shipseal\",\n };\n if (token !== undefined && token.length > 0) {\n headers.Authorization = `Bearer ${token}`;\n }\n let response: Response;\n try {\n response = await fetchImpl(url, { headers });\n } catch (error) {\n throw new ShipsealError(\n \"github.network\",\n \"Could not reach the GitHub API.\",\n \"Check network access, then retry. Unauthenticated calls are optional; facts still come from git and package.json.\",\n { cause: error },\n );\n }\n if (response.status === 404 && opts.notFoundOk === true) {\n return undefined;\n }\n if (response.status === 403 || response.status === 429) {\n throw new ShipsealError(\n \"github.rate-limit\",\n \"GitHub API rate limit exceeded.\",\n \"Set GITHUB_TOKEN in the environment to raise the limit, then retry.\",\n );\n }\n if (!response.ok) {\n throw new ShipsealError(\n \"github.http\",\n `GitHub API returned HTTP ${String(response.status)} for ${url}.`,\n \"Confirm the repository exists and GITHUB_TOKEN can read it.\",\n );\n }\n const json: unknown = await response.json();\n const entry: GithubCacheEntry = { json, link: response.headers.get(\"link\") };\n cache.set(url, entry);\n return entry;\n}\n\nfunction lastPageFromLink(link: string | null): number | undefined {\n if (link === null) {\n return undefined;\n }\n const match = /[?&]page=(\\d+)>;\\s*rel=\"last\"/.exec(link);\n if (match === null || match[1] === undefined) {\n return undefined;\n }\n return Number.parseInt(match[1], 10);\n}\n","// npm weekly downloads\n// Spec: docs/PROJECT_PLAN.md §12.6\n// Docs checked 2026-09-11: https://github.com/npm/registry/blob/main/docs/download-counts.md\n// GET https://api.npmjs.org/downloads/point/{period}/{package}\n// period last-week. Scoped names are URL-encoded (@scope/pkg -> %40scope%2Fpkg).\n// 404 means the package is unpublished or unknown: return nothing.\n\nimport { z } from \"zod\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\n\nconst API_ROOT = \"https://api.npmjs.org/downloads/point/last-week\";\n\nconst pointSchema = z.object({\n downloads: z.number().int().nonnegative(),\n start: z.string().optional(),\n end: z.string().optional(),\n package: z.string().optional(),\n});\n\nexport interface NpmCollectOptions {\n npmPackage: string;\n fetchImpl?: typeof fetch;\n cache?: Map<string, unknown>;\n}\n\nexport async function collectNpm(options: NpmCollectOptions): Promise<PartialFacts> {\n const name = options.npmPackage.trim();\n if (name.length === 0) {\n return {};\n }\n const url = `${API_ROOT}/${encodeURIComponent(name)}`;\n const cache = options.cache ?? new Map<string, unknown>();\n const cached = cache.get(url);\n const json = cached ?? (await npmGet(url, options.fetchImpl ?? fetch, cache));\n if (json === undefined) {\n return {};\n }\n const point = pointSchema.parse(json);\n return {\n metrics: {\n weeklyDownloads: fact(point.downloads, {\n source: \"npm-api\",\n ref: `GET /downloads/point/last-week/${name} downloads`,\n fetchedAt: new Date().toISOString(),\n }),\n },\n };\n}\n\nasync function npmGet(\n url: string,\n fetchImpl: typeof fetch,\n cache: Map<string, unknown>,\n): Promise<unknown | undefined> {\n let response: Response;\n try {\n response = await fetchImpl(url, { headers: { Accept: \"application/json\", \"User-Agent\": \"shipseal\" } });\n } catch (error) {\n throw new ShipsealError(\n \"npm.network\",\n \"Could not reach the npm downloads API.\",\n \"Check network access, then retry. Weekly downloads are optional; other facts still render.\",\n { cause: error },\n );\n }\n if (response.status === 404) {\n return undefined;\n }\n if (response.status === 403 || response.status === 429) {\n throw new ShipsealError(\n \"npm.rate-limit\",\n \"npm downloads API rate limit exceeded.\",\n \"Wait and retry. Milestone cards can still use stars and contributors without downloads.\",\n );\n }\n if (!response.ok) {\n throw new ShipsealError(\n \"npm.http\",\n `npm downloads API returned HTTP ${String(response.status)} for ${url}.`,\n \"Confirm the package name in package.json is published on npm.\",\n );\n }\n const json: unknown = await response.json();\n cache.set(url, json);\n return json;\n}\n","// package.json source\n// Spec: docs/PROJECT_PLAN.md §12.2\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { fact } from \"../facts/fact.js\";\nimport type { PartialFacts, PartialProject } from \"../facts/partial.js\";\n\nconst pkgSchema = z.object({\n name: z.string().optional(),\n description: z.string().optional(),\n version: z.string().optional(),\n homepage: z.string().optional(),\n license: z.string().optional(),\n repository: z.union([z.string(), z.object({ url: z.string().optional() })]).optional(),\n});\n\nexport async function collectPackageJson(\n cwd: string,\n packagePath = \"package.json\",\n): Promise<PartialFacts> {\n const path = join(cwd, packagePath);\n let raw: string;\n try {\n raw = await readFile(path, \"utf8\");\n } catch {\n return {};\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return {};\n }\n const pkg = pkgSchema.safeParse(parsed);\n if (!pkg.success) {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const project: PartialProject = {\n name: fact(stripScope(pkg.data.name ?? basenameFromPath(cwd)), {\n source: \"package-json\",\n ref: `${packagePath}#name`,\n fetchedAt,\n }),\n };\n if (pkg.data.description !== undefined && pkg.data.description.length > 0) {\n project.tagline = fact(pkg.data.description, {\n source: \"package-json\",\n ref: `${packagePath}#description`,\n fetchedAt,\n });\n }\n const url = pkg.data.homepage ?? repositoryUrl(pkg.data.repository);\n if (url !== undefined) {\n project.url = fact(url, {\n source: \"package-json\",\n ref: pkg.data.homepage !== undefined ? `${packagePath}#homepage` : `${packagePath}#repository`,\n fetchedAt,\n });\n }\n const repo = repoSlug(pkg.data.repository);\n if (repo !== undefined) {\n project.repo = fact(repo, {\n source: \"package-json\",\n ref: `${packagePath}#repository`,\n fetchedAt,\n });\n }\n if (pkg.data.name !== undefined) {\n project.npmPackage = fact(pkg.data.name, {\n source: \"package-json\",\n ref: `${packagePath}#name`,\n fetchedAt,\n });\n }\n if (pkg.data.license !== undefined) {\n project.license = fact(pkg.data.license, {\n source: \"package-json\",\n ref: `${packagePath}#license`,\n fetchedAt,\n });\n }\n\n const out: PartialFacts = { project };\n if (pkg.data.version !== undefined) {\n out.release = {\n version: fact(pkg.data.version.replace(/^v/, \"\"), {\n source: \"package-json\",\n ref: `${packagePath}#version`,\n fetchedAt,\n }),\n };\n }\n return out;\n}\n\nfunction stripScope(name: string): string {\n const parts = name.split(\"/\");\n return parts[parts.length - 1] ?? name;\n}\n\nfunction basenameFromPath(cwd: string): string {\n const parts = cwd.split(/[/\\\\]/).filter((part) => part.length > 0);\n return parts[parts.length - 1] ?? \"project\";\n}\n\nfunction repositoryUrl(repository: z.infer<typeof pkgSchema>[\"repository\"]): string | undefined {\n if (typeof repository === \"string\") {\n return normalizeGitUrl(repository);\n }\n if (repository?.url !== undefined) {\n return normalizeGitUrl(repository.url);\n }\n return undefined;\n}\n\nfunction repoSlug(repository: z.infer<typeof pkgSchema>[\"repository\"]): string | undefined {\n const url = repositoryUrl(repository);\n if (url === undefined) {\n return undefined;\n }\n const match = /github\\.com[/:]([^/]+\\/[^/]+)$/.exec(url.replace(/\\.git$/, \"\"));\n return match?.[1];\n}\n\n// npm allows shorthand repository strings: \"owner/repo\", \"github:owner/repo\",\n// and the other hosts' prefixes. Expand the GitHub ones so repoSlug and the\n// GitHub source see a real URL. Without this, `milestone` could not read stars\n// for any project using the shorthand, which is the most common form.\nconst SHORTHAND = /^(?:github:)?([\\w.-]+\\/[\\w.-]+)$/;\n\nfunction normalizeGitUrl(url: string): string {\n const shorthand = SHORTHAND.exec(url);\n if (shorthand?.[1] !== undefined) {\n return `https://github.com/${shorthand[1].replace(/\\.git$/, \"\")}`;\n }\n const ssh = /^git@([^:]+):(.+)$/.exec(url);\n if (ssh !== null && ssh[1] !== undefined && ssh[2] !== undefined) {\n return `https://${ssh[1]}/${ssh[2].replace(/\\.git$/, \"\")}`;\n }\n return url.replace(/^git\\+/, \"\").replace(/\\.git$/, \"\");\n}\n","// README source: title, tagline, first fenced code block\n// Spec: docs/PROJECT_PLAN.md §12.3\n\nimport { readFile } from \"node:fs/promises\";\nimport { extname, join } from \"node:path\";\nimport { fact } from \"../facts/fact.js\";\nimport type { PartialFacts, PartialProject } from \"../facts/partial.js\";\n\nexport async function collectReadme(cwd: string): Promise<PartialFacts> {\n let markdown: string;\n try {\n markdown = await readFile(join(cwd, \"README.md\"), \"utf8\");\n } catch {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const out: PartialFacts = {};\n const h1 = extractH1(markdown);\n const tagline = extractTagline(markdown);\n const snippet = extractFirstCodeFence(markdown);\n\n const project: PartialProject = {};\n if (h1 !== undefined) {\n project.name = fact(h1, { source: \"readme\", ref: \"README.md H1\", fetchedAt });\n }\n if (tagline !== undefined) {\n project.tagline = fact(tagline, {\n source: \"readme\",\n ref: \"README.md first paragraph\",\n fetchedAt,\n });\n }\n if (project.name !== undefined || project.tagline !== undefined) {\n out.project = project;\n }\n if (snippet !== undefined) {\n out.release = {\n codeSnippet: fact(snippet, {\n source: \"readme\",\n ref: \"README.md first fenced code block\",\n fetchedAt,\n }),\n };\n }\n return out;\n}\n\nexport async function collectConfiguredSnippet(\n cwd: string,\n spec: string,\n): Promise<PartialFacts> {\n const parsed = parseSnippetSpec(spec);\n if (parsed === undefined) {\n return {};\n }\n let contents: string;\n try {\n contents = await readFile(join(cwd, parsed.path), \"utf8\");\n } catch {\n return {};\n }\n const lines = contents.split(/\\r?\\n/);\n const slice = lines.slice(parsed.start - 1, parsed.end).join(\"\\n\");\n const fetchedAt = new Date().toISOString();\n return {\n release: {\n codeSnippet: fact(\n { code: slice, lang: langFromPath(parsed.path) },\n { source: \"user-config\", ref: spec, fetchedAt },\n ),\n },\n };\n}\n\n/**\n * Strip fenced code and HTML before reading prose out of a README.\n *\n * Skipping blocks that merely *start* with a fence is not enough. A `#` comment inside a YAML\n * example reads as a markdown H1, and a blank line inside a fence makes its body look like a\n * paragraph. Shipseal's own README hit both: the detected name became\n * \".github/workflows/shipseal.yml\" and the tagline became a chunk of workflow YAML.\n */\nfunction stripNonProse(markdown: string): string {\n return markdown\n .replace(/```[\\s\\S]*?```/g, \"\")\n .replace(/~~~[\\s\\S]*?~~~/g, \"\")\n .replace(/<[^>]+>/g, \"\");\n}\n\nexport function extractH1(markdown: string): string | undefined {\n const match = /^#\\s+(.+)$/m.exec(stripNonProse(markdown));\n const heading = match?.[1];\n if (heading === undefined) {\n return undefined;\n }\n return heading.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\").trim();\n}\n\nexport function extractTagline(markdown: string): string | undefined {\n const prose = stripNonProse(markdown);\n const h1 = /^#\\s+.+$/m.exec(prose);\n const start = h1 === null ? 0 : (h1.index ?? 0) + h1[0].length;\n for (const block of prose.slice(start).split(/\\n\\s*\\n/)) {\n const cleaned = stripBadges(block).trim();\n if (cleaned.length >= 20 && !cleaned.startsWith(\"#\") && !cleaned.startsWith(\"```\")) {\n return cleaned;\n }\n }\n return undefined;\n}\n\nexport function extractFirstCodeFence(markdown: string): { code: string; lang: string } | undefined {\n const match = /```([a-zA-Z0-9+-]+)\\n([\\s\\S]*?)```/.exec(markdown);\n if (match === null || match[1] === undefined || match[2] === undefined) {\n return undefined;\n }\n return { lang: match[1], code: match[2].replace(/\\n$/, \"\") };\n}\n\nfunction parseSnippetSpec(spec: string): { path: string; start: number; end: number } | undefined {\n const match = /^(?<path>.+)#L(?<start>\\d+)(?:-L(?<end>\\d+))?$/.exec(spec);\n if (match === null || match.groups === undefined) {\n return undefined;\n }\n const path = match.groups.path;\n const start = Number.parseInt(match.groups.start ?? \"0\", 10);\n const end = Number.parseInt(match.groups.end ?? match.groups.start ?? \"0\", 10);\n if (path === undefined || start < 1 || end < start) {\n return undefined;\n }\n return { path, start, end };\n}\n\nfunction langFromPath(path: string): string {\n const ext = extname(path).replace(\".\", \"\");\n if (ext === \"ts\") {\n return \"ts\";\n }\n if (ext === \"tsx\") {\n return \"tsx\";\n }\n if (ext === \"js\" || ext === \"mjs\" || ext === \"cjs\") {\n return \"js\";\n }\n if (ext === \"jsx\") {\n return \"jsx\";\n }\n return ext.length > 0 ? ext : \"text\";\n}\n\nfunction stripBadges(text: string): string {\n return text\n .replace(/\\[!\\[[^\\]]*]\\([^)]+\\)]\\([^)]+\\)/g, \"\")\n .replace(/!\\[[^\\]]*]\\([^)]+\\)/g, \"\")\n .replace(/<img[^>]*>/gi, \"\")\n .replace(/<[^>]+>/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","// Orchestrate collectors into one Facts object\n// Spec: docs/PROJECT_PLAN.md §12\n\nimport { dirname, join } from \"node:path\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { mergeFacts } from \"../facts/merge.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\nimport { collectBenchFile } from \"./bench-file.js\";\nimport { collectChangelog } from \"./changelog.js\";\nimport { collectGit, versionFromTag } from \"./git.js\";\nimport { collectGithub } from \"./github.js\";\nimport { collectNpm } from \"./npm.js\";\nimport { collectPackageJson } from \"./package-json.js\";\nimport { collectConfiguredSnippet, collectReadme } from \"./readme.js\";\n\nexport interface CollectOptions {\n cwd: string;\n event: ShipsealEvent;\n packagePath?: string;\n changelogPath?: string;\n snippet?: string | null;\n benchFile?: string;\n githubToken?: string;\n fetchImpl?: typeof fetch;\n skipNetwork?: boolean;\n}\n\nexport async function collectFacts(options: CollectOptions): Promise<Facts> {\n const pkg = await collectPackageJson(options.cwd, options.packagePath ?? \"package.json\");\n const tag = options.event.kind === \"release\" ? options.event.tag : undefined;\n const previousTag = options.event.kind === \"release\" ? options.event.previousTag : undefined;\n const gitEvent: { tag?: string; previousTag?: string } = {};\n if (tag !== undefined) {\n gitEvent.tag = tag;\n }\n if (previousTag !== undefined) {\n gitEvent.previousTag = previousTag;\n }\n const git = await collectGit(options.cwd, gitEvent);\n const version =\n git.release?.version?.value ??\n pkg.release?.version?.value ??\n (tag === undefined ? undefined : versionFromTag(tag));\n const changelog = await collectBestChangelog(\n options.cwd,\n version,\n options.changelogPath ?? \"CHANGELOG.md\",\n options.packagePath,\n );\n const readme = await collectReadme(options.cwd);\n const snippet =\n options.snippet !== undefined && options.snippet !== null && options.snippet.length > 0\n ? await collectConfiguredSnippet(options.cwd, options.snippet)\n : {};\n\n const parts: PartialFacts[] = [pkg, git, readme, changelog, snippet];\n\n if (options.event.kind === \"bench\") {\n parts.push(await collectBenchFile(options.cwd, options.benchFile ?? \".shipseal/bench.json\"));\n }\n\n if (options.skipNetwork !== true) {\n const repo = pkg.project?.repo?.value ?? gitRepoFromParts(pkg, readme);\n if (repo !== undefined) {\n const githubOpts: Parameters<typeof collectGithub>[0] = { repo };\n const githubTag = git.release?.tag?.value ?? tag;\n if (githubTag !== undefined) {\n githubOpts.tag = githubTag;\n }\n if (options.githubToken !== undefined) {\n githubOpts.token = options.githubToken;\n }\n if (options.fetchImpl !== undefined) {\n githubOpts.fetchImpl = options.fetchImpl;\n }\n const github = await collectGithub(githubOpts);\n const githubWithoutFeatures: PartialFacts = {};\n if (github.project !== undefined) {\n githubWithoutFeatures.project = github.project;\n }\n if (github.metrics !== undefined) {\n githubWithoutFeatures.metrics = github.metrics;\n }\n parts.push(githubWithoutFeatures);\n const mergedPreview = mergeFacts(parts);\n if (\n options.event.kind === \"release\" &&\n (mergedPreview.release?.features.length ?? 0) === 0 &&\n github.release?.features !== undefined &&\n github.release.features.length > 0\n ) {\n parts.push({ release: { features: github.release.features } });\n }\n }\n const npmPackage = pkg.project?.npmPackage?.value;\n if (npmPackage !== undefined) {\n const npmOpts: Parameters<typeof collectNpm>[0] = { npmPackage };\n if (options.fetchImpl !== undefined) {\n npmOpts.fetchImpl = options.fetchImpl;\n }\n parts.push(await collectNpm(npmOpts));\n }\n }\n\n const facts = mergeFacts(parts);\n if (options.event.kind === \"release\" && facts.release === undefined) {\n throw new ShipsealError(\n \"facts.missing-release\",\n \"Could not collect release facts.\",\n \"Create a git tag, pass --tag, or add a matching version section to CHANGELOG.md.\",\n );\n }\n return facts;\n}\n\nasync function collectBestChangelog(\n cwd: string,\n version: string | undefined,\n changelogPath: string,\n packagePath: string | undefined,\n): Promise<PartialFacts> {\n const paths = [changelogPath];\n if (packagePath !== undefined) {\n const sibling = join(dirname(packagePath), \"CHANGELOG.md\");\n if (!paths.includes(sibling)) {\n paths.push(sibling);\n }\n }\n const collected = await Promise.all(paths.map((path) => collectChangelog(cwd, version, path)));\n return collected.find((facts) => changelogHasNotes(facts)) ?? {};\n}\n\nfunction changelogHasNotes(facts: PartialFacts): boolean {\n const release = facts.release;\n if (release === undefined) {\n return false;\n }\n return (\n (release.features?.length ?? 0) > 0 ||\n (release.fixes?.length ?? 0) > 0 ||\n (release.breaking?.length ?? 0) > 0\n );\n}\n\nfunction gitRepoFromParts(pkg: PartialFacts, readme: PartialFacts): string | undefined {\n return pkg.project?.repo?.value ?? pkg.project?.url?.value ?? readme.project?.url?.value;\n}\n","// ONLY file allowed to import Takumi (Rule R4). Verify API first (spike S1)\n// Spec: docs/PROJECT_PLAN.md §16\n// Docs checked 2026-09-11: https://takumi.kane.tw/docs , /docs/measure-api, /docs/typography-and-fonts, /docs/helpers\n\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Renderer, type Node } from \"takumi-js/node\";\nimport { container, text as textNode } from \"takumi-js/helpers\";\nimport { fromJsx as takumiFromJsx } from \"takumi-js/helpers/jsx\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport type {\n LayoutNode,\n MeasureOptions,\n MeasureResult,\n MeasureTextOptions,\n RenderOptions,\n RendererAdapter,\n} from \"./adapter.js\";\n\nexport const GEIST_MONO_FAMILY = \"Geist Mono\";\nconst FONT_REL = join(\"assets\", \"fonts\", \"GeistMono[wght].ttf\");\n\nlet shared: Promise<RendererAdapter> | undefined;\n\nexport function getTakumiRenderer(): Promise<RendererAdapter> {\n shared ??= createTakumiRenderer();\n return shared;\n}\n\nexport async function createTakumiRenderer(): Promise<RendererAdapter> {\n const renderer = new Renderer();\n const fontPath = join(resolvePackageRoot(), FONT_REL);\n const data = await readFile(fontPath);\n await renderer.registerFont({\n name: GEIST_MONO_FAMILY,\n data,\n generic: \"monospace\",\n });\n return new TakumiRenderer(renderer);\n}\n\nexport function resolvePackageRoot(from = import.meta.url): string {\n let dir = dirname(fileURLToPath(from));\n for (;;) {\n if (existsSync(join(dir, \"package.json\")) && existsSync(join(dir, FONT_REL))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n throw new ShipsealError(\n \"render.font-missing\",\n `Could not find vendored font ${FONT_REL}.`,\n \"Reinstall shipseal so assets/fonts/GeistMono[wght].ttf is present next to package.json.\",\n );\n }\n dir = parent;\n }\n}\n\nexport interface LineCountNode {\n runs: ReadonlyArray<{ y: number }>;\n children: readonly LineCountNode[];\n}\n\nexport function countLines(node: LineCountNode): number {\n const ys = new Set<number>();\n const walk = (current: LineCountNode): void => {\n for (const run of current.runs) {\n ys.add(Math.round(run.y));\n }\n for (const child of current.children) {\n walk(child);\n }\n };\n walk(node);\n return ys.size;\n}\n\nexport function testCardNode(): LayoutNode {\n return container({\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n padding: 64,\n backgroundColor: \"#0b0b0c\",\n },\n children: [\n textNode(\"Shipseal\", {\n fontFamily: \"Geist\",\n fontSize: 72,\n fontWeight: 700,\n color: \"#fafafa\",\n }),\n textNode(\"Every release, sealed and ready to share\", {\n fontFamily: GEIST_MONO_FAMILY,\n fontSize: 28,\n fontWeight: 400,\n color: \"#a1a1aa\",\n }),\n ],\n });\n}\n\nclass TakumiRenderer implements RendererAdapter {\n constructor(private readonly renderer: Renderer) {}\n\n async fromJsx(element: unknown): Promise<LayoutNode> {\n const result = await takumiFromJsx(asReactElementLike(element));\n return pack(result.node, result.css);\n }\n\n async render(node: LayoutNode, opts: RenderOptions): Promise<Uint8Array> {\n const packed = unpack(node);\n const extras: { css: string[]; images?: RenderOptions[\"images\"] } = {\n css: opts.css ?? packed.css,\n };\n if (opts.images !== undefined) {\n extras.images = opts.images;\n }\n const buffer = await renderWithFormat(this.renderer, packed.node, opts, extras);\n return Uint8Array.from(buffer);\n }\n\n async measure(node: LayoutNode, opts?: MeasureOptions): Promise<MeasureResult> {\n const packed = unpack(node);\n const measured = await this.renderer.measure(packed.node, measureOpts(opts));\n return {\n lines: countLines(measured),\n width: measured.width,\n height: measured.height,\n };\n }\n\n async measureText(value: string, opts: MeasureTextOptions): Promise<MeasureResult> {\n const measured = await this.renderer.measure(asNode(textMeasureNode(value, opts)));\n return {\n lines: countLines(measured),\n width: measured.width,\n height: measured.height,\n };\n }\n}\n\nfunction renderWithFormat(\n renderer: Renderer,\n node: Node,\n opts: RenderOptions,\n extras: { css: string[]; images?: RenderOptions[\"images\"] },\n): Promise<Buffer> {\n const width = opts.width;\n const height = opts.height;\n const css = extras.css;\n const images = extras.images;\n if (opts.format === \"webp\") {\n if (images !== undefined) {\n return renderer.render(node, { width, height, format: \"webp\", css, images });\n }\n return renderer.render(node, { width, height, format: \"webp\", css });\n }\n if (opts.format === \"jpeg\") {\n if (images !== undefined) {\n return renderer.render(node, { width, height, format: \"jpeg\", css, images });\n }\n return renderer.render(node, { width, height, format: \"jpeg\", css });\n }\n if (images !== undefined) {\n return renderer.render(node, { width, height, format: \"png\", css, images });\n }\n return renderer.render(node, { width, height, format: \"png\", css });\n}\n\nfunction measureOpts(opts?: MeasureOptions): { width?: number; height?: number } {\n const out: { width?: number; height?: number } = {};\n if (opts?.width !== undefined) {\n out.width = opts.width;\n }\n if (opts?.height !== undefined) {\n out.height = opts.height;\n }\n return out;\n}\n\nfunction textMeasureNode(value: string, opts: MeasureTextOptions): LayoutNode {\n const style: {\n fontFamily: string;\n fontSize: number;\n lineHeight: number;\n whiteSpace: \"normal\" | \"pre\";\n maxWidth: number;\n fontWeight?: number;\n } = {\n fontFamily: opts.fontFamily,\n fontSize: opts.fontSize,\n lineHeight: opts.lineHeight,\n whiteSpace: opts.whiteSpace ?? \"normal\",\n maxWidth: opts.maxWidth,\n };\n if (opts.fontWeight !== undefined) {\n style.fontWeight = opts.fontWeight;\n }\n return textNode(value, style);\n}\n\nfunction asNode(node: LayoutNode): Node {\n return unpack(node).node;\n}\n\ntype PackedLayout = { readonly __shipseal: true; node: Node; css: string[] };\n\nfunction pack(node: Node, css: string[] = []): LayoutNode {\n const packed: PackedLayout = { __shipseal: true, node, css };\n return packed;\n}\n\nfunction unpack(node: LayoutNode): PackedLayout {\n if (isPacked(node)) {\n return node;\n }\n if (isTakumiNode(node)) {\n return { __shipseal: true, node, css: [] };\n }\n throw new ShipsealError(\n \"render.invalid-node\",\n \"render/measure received a value that is not a Takumi node tree.\",\n \"Pass a node built by the renderer adapter (fromJsx, measureText, or testCardNode).\",\n );\n}\n\nfunction isPacked(node: LayoutNode): node is PackedLayout {\n return typeof node === \"object\" && node !== null && \"__shipseal\" in node;\n}\n\nfunction isTakumiNode(node: LayoutNode): node is Node {\n return typeof node === \"object\" && node !== null && \"type\" in node;\n}\n\nfunction asReactElementLike(element: unknown): { type: unknown; props: unknown; key: string | null } {\n if (typeof element !== \"object\" || element === null || !(\"type\" in element)) {\n throw new ShipsealError(\n \"render.invalid-jsx\",\n \"fromJsx received a value that is not a JSX element.\",\n \"Return JSX from a template render function.\",\n );\n }\n const record = element;\n const type = \"type\" in record ? record.type : undefined;\n const props = \"props\" in record ? record.props : null;\n const key = \"key\" in record && typeof record.key === \"string\" ? record.key : null;\n return { type, props, key };\n}\n","// Rule R1: reject any digits not from facts\n// Spec: docs/PROJECT_PLAN.md §13.3\n\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Copy } from \"./slots.js\";\n\nexport function allowedNumbers(facts: Facts): Set<string> {\n const allowed = new Set<string>();\n const visit = (value: unknown): void => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n addNumber(allowed, value);\n return;\n }\n if (typeof value === \"string\") {\n for (const match of value.match(/\\d+(?:\\.\\d+)*/g) ?? []) {\n allowed.add(match);\n }\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n visit(item);\n }\n return;\n }\n if (typeof value === \"object\" && value !== null) {\n if (\"value\" in value && \"provenance\" in value) {\n visit(value.value);\n return;\n }\n for (const nested of Object.values(value)) {\n visit(nested);\n }\n }\n };\n visit(facts);\n return allowed;\n}\n\nexport function unsourcedDigits(text: string, allowed: Set<string>): string[] {\n const found: string[] = [];\n const withoutGrouped = text.replace(/\\d{1,3}(?:,\\d{3})+/g, (match) => {\n const compact = match.replaceAll(\",\", \"\");\n if (!allowed.has(match) && !allowed.has(compact)) {\n found.push(match);\n }\n return \" \";\n });\n for (const match of withoutGrouped.match(/\\d+(?:\\.\\d+)*/g) ?? []) {\n if (!allowed.has(match)) {\n found.push(match);\n }\n }\n return found;\n}\n\nexport function guardCopy(copy: Copy, facts: Facts): { ok: true } | { ok: false; slot: string; digits: string[] } {\n const allowed = allowedNumbers(facts);\n const slots: Array<[string, string]> = [\n [\"headline\", copy.headline],\n [\"subheadline\", copy.subheadline],\n [\"cta\", copy.cta],\n ];\n if (copy.milestoneLine !== undefined) {\n slots.push([\"milestoneLine\", copy.milestoneLine]);\n }\n copy.highlights.forEach((line, index) => {\n slots.push([`highlights[${String(index)}]`, line]);\n });\n for (const [slot, text] of slots) {\n const digits = unsourcedDigits(text, allowed);\n if (digits.length > 0) {\n return { ok: false, slot, digits };\n }\n }\n return { ok: true };\n}\n\nfunction addNumber(allowed: Set<string>, value: number): void {\n allowed.add(String(value));\n if (Number.isInteger(value)) {\n allowed.add(value.toLocaleString(\"en-US\"));\n }\n}\n","// Optional LLM copy via OpenAI-compatible fetch (BYOK, no extra SDK)\n// Spec: docs/PROJECT_PLAN.md §13.3\n\nimport { z } from \"zod\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { COPY_LIMITS, MAX_HIGHLIGHTS, type Copy } from \"./slots.js\";\nimport { deterministicCopy } from \"./deterministic.js\";\nimport { guardCopy } from \"./number-guard.js\";\n\nconst llmCopySchema = z.object({\n headline: z.string(),\n subheadline: z.string(),\n highlights: z.array(z.string()).max(MAX_HIGHLIGHTS),\n cta: z.string(),\n});\n\nexport interface LlmCopyOptions {\n apiKey: string;\n model: string;\n maxRetries: number;\n baseUrl?: string;\n fetchImpl?: typeof fetch;\n}\n\nexport async function llmCopy(\n facts: Facts,\n options: LlmCopyOptions,\n fallback = deterministicCopy(facts),\n): Promise<{ copy: Copy; mode: \"llm\" | \"deterministic\"; warning?: string }> {\n const payload = factsForLlm(facts);\n let lastError: string | undefined;\n const retries = Math.max(0, options.maxRetries);\n for (let attempt = 0; attempt <= retries; attempt += 1) {\n let parsed: z.infer<typeof llmCopySchema>;\n try {\n // Sequential retries are required: each attempt depends on the previous rejection.\n // eslint-disable-next-line no-await-in-loop\n const raw = await requestCopy(payload, options);\n parsed = llmCopySchema.parse(JSON.parse(raw));\n } catch (error) {\n lastError = error instanceof Error ? error.message : \"LLM request failed\";\n continue;\n }\n const expanded = expandPlaceholders(parsed, facts);\n const styled: Copy = {\n headline: stripStyle(expanded.headline).slice(0, COPY_LIMITS.headline),\n subheadline: stripStyle(expanded.subheadline).slice(0, COPY_LIMITS.subheadline),\n highlights: expanded.highlights.map((line) => stripStyle(line).slice(0, COPY_LIMITS.highlight)),\n cta: stripStyle(expanded.cta).slice(0, COPY_LIMITS.cta),\n };\n const guarded = guardCopy(styled, facts);\n if (!guarded.ok) {\n lastError = `Number guard rejected ${guarded.slot}: ${guarded.digits.join(\", \")}`;\n continue;\n }\n return { copy: styled, mode: \"llm\" };\n }\n return {\n copy: fallback,\n mode: \"deterministic\",\n warning: lastError ?? \"LLM copy failed; using deterministic copy\",\n };\n}\n\nfunction factsForLlm(facts: Facts): Record<string, unknown> {\n return {\n project: {\n name: facts.project.name.value,\n tagline: facts.project.tagline?.value,\n npmPackage: facts.project.npmPackage?.value,\n url: facts.project.url?.value,\n },\n release: facts.release === undefined\n ? undefined\n : {\n version: \"{version}\",\n features: facts.release.features.map((item) => item.value),\n fixes: facts.release.fixes.map((item) => item.value),\n breaking: facts.release.breaking.map((item) => item.value),\n },\n metrics: {\n stars: facts.metrics?.stars === undefined ? undefined : \"{stars}\",\n weeklyDownloads: facts.metrics?.weeklyDownloads === undefined ? undefined : \"{weeklyDownloads}\",\n contributorCount: facts.metrics?.contributorCount === undefined ? undefined : \"{contributorCount}\",\n },\n };\n}\n\nfunction expandPlaceholders(copy: z.infer<typeof llmCopySchema>, facts: Facts): z.infer<typeof llmCopySchema> {\n const map: Record<string, string> = {\n \"{version}\": facts.release?.version.value ?? \"\",\n \"{stars}\": facts.metrics?.stars === undefined ? \"\" : formatCount(facts.metrics.stars.value),\n \"{weeklyDownloads}\":\n facts.metrics?.weeklyDownloads === undefined ? \"\" : formatCount(facts.metrics.weeklyDownloads.value),\n \"{contributorCount}\":\n facts.metrics?.contributorCount === undefined ? \"\" : formatCount(facts.metrics.contributorCount.value),\n };\n const expand = (text: string): string => {\n let out = text;\n for (const [token, value] of Object.entries(map)) {\n out = out.replaceAll(token, value);\n }\n return out;\n };\n return {\n headline: expand(copy.headline),\n subheadline: expand(copy.subheadline),\n highlights: copy.highlights.map(expand),\n cta: expand(copy.cta),\n };\n}\n\nfunction stripStyle(text: string): string {\n return text.replaceAll(\"\\u2014\", \":\").replaceAll(\"\\u2013\", \"-\").replaceAll(\"!\", \".\");\n}\n\nfunction formatCount(value: number): string {\n return value.toLocaleString(\"en-US\");\n}\n\nasync function requestCopy(facts: Record<string, unknown>, options: LlmCopyOptions): Promise<string> {\n const base = (options.baseUrl ?? \"https://api.openai.com/v1\").replace(/\\/$/, \"\");\n const fetchImpl = options.fetchImpl ?? fetch;\n const response = await fetchImpl(`${base}/chat/completions`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${options.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n model: options.model,\n response_format: { type: \"json_object\" },\n messages: [\n {\n role: \"system\",\n content:\n \"Write short release-card copy as JSON with keys headline, subheadline, highlights, cta. No em dashes, no exclamation marks. Use placeholders like {version} for numbers. Never invent numbers.\",\n },\n { role: \"user\", content: JSON.stringify(facts) },\n ],\n }),\n });\n if (!response.ok) {\n throw new ShipsealError(\n \"copy.llm-http\",\n `LLM provider returned HTTP ${String(response.status)}.`,\n \"Check SHIPSEAL_LLM_API_KEY, copy.model, and SHIPSEAL_LLM_BASE_URL.\",\n );\n }\n const json: unknown = await response.json();\n const message = z\n .object({\n choices: z.array(z.object({ message: z.object({ content: z.string() }) })).min(1),\n })\n .parse(json);\n const first = message.choices[0];\n if (first === undefined) {\n throw new ShipsealError(\"copy.llm-empty\", \"LLM returned no choices.\", \"Retry, or run with --no-copy.\");\n }\n return first.message.content;\n}\n","// Build manifest.json with facts, computed values, warnings\n// Spec: docs/PROJECT_PLAN.md §17.2\n\nimport type { Brand } from \"../brand/schema.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { GenerateResult } from \"../core/generate.js\";\n\nexport interface ManifestFile {\n path: string;\n template: string;\n format: string;\n width: number;\n height: number;\n bytes: number;\n sha256: string;\n}\n\nexport interface Manifest {\n shipseal: string;\n event: ShipsealEvent;\n generatedAt: string;\n brand: { name: string; theme: Brand[\"theme\"]; source: string };\n copy: { mode: \"deterministic\" | \"llm\" };\n files: ManifestFile[];\n facts: Record<string, { value: unknown; source: string; ref: string; fetchedAt: string }>;\n computed: Record<string, { value: unknown; computedFrom: string[] }>;\n warnings: GenerateResult[\"warnings\"];\n missing: GenerateResult[\"missing\"];\n}\n\nexport function buildManifest(input: {\n result: GenerateResult;\n event: ShipsealEvent;\n brand: Brand;\n shipsealVersion: string;\n}): Manifest {\n return {\n shipseal: input.shipsealVersion,\n event: input.event,\n generatedAt: input.result.generatedAt,\n brand: {\n name: input.brand.name,\n theme: input.brand.theme,\n source: \".shipseal/brand.json\",\n },\n copy: { mode: input.result.copyMode },\n files: input.result.files.map((file) => ({\n path: file.fileName,\n template: file.template,\n format: file.format,\n width: file.width,\n height: file.height,\n bytes: file.bytes.byteLength,\n sha256: file.sha256,\n })),\n facts: flattenFacts(input.result.facts),\n computed: input.result.computed,\n warnings: input.result.warnings,\n missing: input.result.missing,\n };\n}\n\nexport function flattenFacts(\n facts: Facts,\n): Record<string, { value: unknown; source: string; ref: string; fetchedAt: string }> {\n const out: Record<string, { value: unknown; source: string; ref: string; fetchedAt: string }> = {};\n const walk = (prefix: string, value: unknown): void => {\n if (isFact(value)) {\n out[prefix] = {\n value: value.value,\n source: value.provenance.source,\n ref: value.provenance.ref,\n fetchedAt: value.provenance.fetchedAt,\n };\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n walk(`${prefix}[${String(index)}]`, item);\n });\n return;\n }\n if (typeof value === \"object\" && value !== null) {\n for (const [key, nested] of Object.entries(value)) {\n walk(prefix.length === 0 ? key : `${prefix}.${key}`, nested);\n }\n }\n };\n walk(\"project\", facts.project);\n if (facts.release !== undefined) {\n walk(\"release\", facts.release);\n }\n if (facts.metrics !== undefined) {\n walk(\"metrics\", facts.metrics);\n }\n if (facts.bench !== undefined) {\n walk(\"bench\", facts.bench);\n }\n if (facts.milestone !== undefined) {\n walk(\"milestone\", facts.milestone);\n }\n return out;\n}\n\nfunction isFact(\n value: unknown,\n): value is { value: unknown; provenance: { source: string; ref: string; fetchedAt: string } } {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n if (!(\"value\" in value) || !(\"provenance\" in value)) {\n return false;\n }\n const provenance = value.provenance;\n return (\n typeof provenance === \"object\" &&\n provenance !== null &&\n \"source\" in provenance &&\n \"ref\" in provenance &&\n \"fetchedAt\" in provenance\n );\n}\n","// Write pack files to disk\n// Spec: docs/PROJECT_PLAN.md §17.1\n\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { isAbsolute, join } from \"node:path\";\nimport type { GenerateResult } from \"../core/generate.js\";\nimport { buildManifest, type Manifest } from \"./manifest.js\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\n\nexport async function writePack(input: {\n outDir: string;\n eventId: string;\n result: GenerateResult;\n event: ShipsealEvent;\n brand: Brand;\n shipsealVersion: string;\n}): Promise<{ dir: string; manifest: Manifest }> {\n const dir = join(input.outDir, input.eventId);\n await mkdir(dir, { recursive: true });\n await Promise.all(input.result.files.map((file) => writeFile(join(dir, file.fileName), file.bytes)));\n const manifest = buildManifest({\n result: input.result,\n event: input.event,\n brand: input.brand,\n shipsealVersion: input.shipsealVersion,\n });\n await writeFile(join(dir, \"manifest.json\"), `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n return { dir, manifest };\n}\n\nexport function resolveOutputDir(cwd: string, configured: string): string {\n return isAbsolute(configured) ? configured : join(cwd, configured);\n}\n\nexport function eventId(event: ShipsealEvent, generatedAt = \"\"): string {\n if (event.kind === \"release\") {\n return event.tag;\n }\n if (event.kind === \"milestone\") {\n return `milestone-${event.metric}-${String(event.threshold)}`;\n }\n const day = generatedAt.slice(0, 10);\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(day) ? `bench-${day}` : \"bench\";\n}\n","// Upload assets to a GitHub release and write the Actions job summary\n// Spec: docs/PROJECT_PLAN.md §19.4\n// Docs checked 2026-09-11: `gh release upload <tag> <files>... --clobber`\n// gh is preinstalled on GitHub-hosted runners.\n\nimport { execFile } from \"node:child_process\";\nimport { appendFile } from \"node:fs/promises\";\nimport { promisify } from \"node:util\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport type { Manifest } from \"./manifest.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport type GhExec = (\n file: string,\n args: string[],\n options: { env: NodeJS.ProcessEnv },\n) => Promise<{ stdout: string; stderr: string }>;\n\nexport async function uploadReleaseAssets(options: {\n tag: string;\n files: string[];\n repo?: string;\n token?: string;\n exec?: GhExec;\n}): Promise<void> {\n if (options.files.length === 0) {\n return;\n }\n const exec = options.exec ?? execFileAsync;\n const args = [\"release\", \"upload\", options.tag, ...options.files, \"--clobber\"];\n if (options.repo !== undefined) {\n args.push(\"--repo\", options.repo);\n }\n const env = { ...process.env };\n if (options.token !== undefined) {\n env.GH_TOKEN = options.token;\n env.GITHUB_TOKEN = options.token;\n }\n try {\n await exec(\"gh\", args, { env });\n } catch (error) {\n throw new ShipsealError(\n \"github.upload\",\n `Could not upload assets to GitHub release ${options.tag}.`,\n \"Confirm gh is installed, GITHUB_TOKEN can write contents, and the release exists.\",\n { cause: error },\n );\n }\n}\n\nexport async function appendJobSummary(path: string, manifest: Manifest, dir: string): Promise<void> {\n await appendFile(path, `${jobSummaryMarkdown(manifest, dir)}\\n`, \"utf8\");\n}\n\nexport function jobSummaryMarkdown(manifest: Manifest, dir: string): string {\n const lines = [\n \"## Shipseal\",\n \"\",\n `Generated **${String(manifest.files.length)}** files in \\`${dir}\\`.`,\n \"\",\n ];\n const repo = process.env.GITHUB_REPOSITORY;\n const tag = manifest.event.kind === \"release\" ? manifest.event.tag : undefined;\n if (repo !== undefined && tag !== undefined) {\n for (const file of manifest.files) {\n const url = `https://github.com/${repo}/releases/download/${tag}/${file.path}`;\n lines.push(`![${file.path}](${url})`, \"\");\n }\n } else {\n lines.push(\"| File | Template | Format |\", \"|---|---|---|\");\n for (const file of manifest.files) {\n lines.push(`| ${file.path} | ${file.template} | ${file.format} |`);\n }\n lines.push(\"\");\n }\n lines.push(\"### Facts\", \"\");\n for (const [key, entry] of Object.entries(manifest.facts)) {\n lines.push(`- \\`${key}\\`: ${JSON.stringify(entry.value)} (${entry.source})`);\n }\n if (Object.keys(manifest.computed).length > 0) {\n lines.push(\"\", \"### Computed\", \"\");\n for (const [key, entry] of Object.entries(manifest.computed)) {\n lines.push(`- \\`${key}\\`: ${JSON.stringify(entry.value)}`);\n }\n }\n if (manifest.warnings.length > 0) {\n lines.push(\"\", \"### Warnings\", \"\");\n for (const warning of manifest.warnings) {\n lines.push(`- ${warning.template} ${warning.format} ${warning.slot}: ${warning.action}`);\n }\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n","// Shared helpers for release, milestone, and bench commands\n\nimport { readFileSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join } from \"node:path\";\nimport type { Brand } from \"../brand/schema.js\";\nimport { mergeConfig } from \"../config/load.js\";\nimport { DEFAULT_CONFIG, type Config } from \"../config/schema.js\";\nimport { llmCopy } from \"../copy/llm.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport type { GenerateResult } from \"../core/generate.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { FORMAT_IDS, type FormatId } from \"../formats.js\";\nimport { eventId, resolveOutputDir, writePack } from \"../outputs/files.js\";\nimport { appendJobSummary, uploadReleaseAssets } from \"../outputs/github-release.js\";\nimport type { Manifest } from \"../outputs/manifest.js\";\nimport { resolvePackageRoot } from \"../render/takumi.js\";\n\nexport interface SharedFlags {\n cwd: string;\n formats?: string;\n themes?: string;\n copy?: boolean;\n out?: string;\n strict?: boolean;\n dryRun?: boolean;\n package?: string;\n upload?: boolean;\n fetchImpl?: typeof fetch;\n}\n\nexport function overlayFormats(config: Config, flags: SharedFlags): Config {\n const overlay: Config = { ...config };\n if (flags.formats !== undefined) {\n overlay.formats = parseFormats(flags.formats);\n }\n if (flags.out !== undefined) {\n overlay.outputDir = flags.out;\n }\n return mergeConfig(DEFAULT_CONFIG, overlay);\n}\n\nexport function parseFormats(list: string): FormatId[] {\n const formats: FormatId[] = [];\n for (const part of list.split(\",\")) {\n const id = part.trim();\n if (id.length === 0) {\n continue;\n }\n const match = FORMAT_IDS.find((format) => format === id);\n if (match === undefined) {\n throw new ShipsealError(\n \"release.bad-format\",\n `Unknown format \"${id}\".`,\n `Use a comma-separated list from: ${FORMAT_IDS.join(\", \")}.`,\n );\n }\n formats.push(match);\n }\n return formats;\n}\n\nexport function resolveThemes(flag: string | undefined, brandTheme: Brand[\"theme\"]): Array<\"dark\" | \"light\"> {\n if (flag === \"both\") {\n return [\"dark\", \"light\"];\n }\n if (flag === \"dark\" || flag === \"light\") {\n return [flag];\n }\n return [brandTheme];\n}\n\nexport async function resolveCopy(\n facts: Facts,\n config: Config,\n noCopy: boolean,\n fallback: Copy,\n): Promise<{ copy: Copy; copyMode: \"deterministic\" | \"llm\"; warning?: string }> {\n if (noCopy || config.copy?.llm !== true) {\n return { copy: fallback, copyMode: \"deterministic\" };\n }\n const apiKey = process.env.SHIPSEAL_LLM_API_KEY;\n if (apiKey === undefined || apiKey.length === 0) {\n throw new ShipsealError(\n \"copy.missing-key\",\n \"copy.llm is enabled but SHIPSEAL_LLM_API_KEY is not set.\",\n \"Set SHIPSEAL_LLM_API_KEY, or pass --no-copy for deterministic copy.\",\n );\n }\n const llmOpts: Parameters<typeof llmCopy>[1] = {\n apiKey,\n model: config.copy.model ?? \"gpt-4o-mini\",\n maxRetries: config.copy.maxRetries ?? 2,\n };\n if (process.env.SHIPSEAL_LLM_BASE_URL !== undefined) {\n llmOpts.baseUrl = process.env.SHIPSEAL_LLM_BASE_URL;\n }\n const result = await llmCopy(facts, llmOpts, fallback);\n const out: { copy: Copy; copyMode: \"deterministic\" | \"llm\"; warning?: string } = {\n copy: result.copy,\n copyMode: result.mode,\n };\n if (result.warning !== undefined) {\n out.warning = result.warning;\n }\n return out;\n}\n\nexport async function loadLogos(cwd: string, brand: Brand): Promise<{ light?: Uint8Array; dark?: Uint8Array } | undefined> {\n if (brand.logo === undefined) {\n return undefined;\n }\n const logos: { light?: Uint8Array; dark?: Uint8Array } = {\n light: await readLogo(cwd, brand.logo.light),\n };\n if (brand.logo.dark !== undefined) {\n logos.dark = await readLogo(cwd, brand.logo.dark);\n }\n return logos;\n}\n\nasync function readLogo(cwd: string, path: string): Promise<Uint8Array> {\n const resolved = isAbsolute(path) ? path : join(cwd, path);\n return new Uint8Array(await readFile(resolved));\n}\n\nexport function readShipsealVersion(): string {\n const raw: unknown = JSON.parse(readFileSync(join(resolvePackageRoot(), \"package.json\"), \"utf8\"));\n if (typeof raw === \"object\" && raw !== null && \"version\" in raw && typeof raw.version === \"string\") {\n return raw.version;\n }\n return \"0.0.0\";\n}\n\nexport function collectEnv(flags: SharedFlags): {\n skipNetwork: boolean;\n githubToken?: string;\n packagePath?: string;\n fetchImpl?: typeof fetch;\n} {\n const skipNetwork = flags.dryRun === true && process.env.GITHUB_TOKEN === undefined;\n const out: ReturnType<typeof collectEnv> = { skipNetwork };\n if (process.env.GITHUB_TOKEN !== undefined) {\n out.githubToken = process.env.GITHUB_TOKEN;\n }\n if (flags.package !== undefined) {\n out.packagePath = flags.package;\n }\n if (flags.fetchImpl !== undefined) {\n out.fetchImpl = flags.fetchImpl;\n }\n return out;\n}\n\nexport async function finishPack(input: {\n flags: SharedFlags;\n config: Config;\n event: ShipsealEvent;\n result: GenerateResult;\n brand: Brand;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n facts: Facts;\n}): Promise<{\n dryRun: false;\n facts: Facts;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir: string;\n manifest: Manifest;\n warnings: GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n}> {\n const generatedAt = input.result.generatedAt;\n const written = await writePack({\n outDir: resolveOutputDir(\n input.flags.cwd,\n input.flags.out ?? input.config.outputDir ?? \".shipseal/output\",\n ),\n eventId: eventId(input.event, generatedAt),\n result: input.result,\n event: input.event,\n brand: input.brand,\n shipsealVersion: readShipsealVersion(),\n });\n if (input.flags.upload === true && input.event.kind === \"release\") {\n const files = input.result.files.map((file) => join(written.dir, file.fileName));\n const uploadOpts: Parameters<typeof uploadReleaseAssets>[0] = { tag: input.event.tag, files };\n if (process.env.GITHUB_REPOSITORY !== undefined) {\n uploadOpts.repo = process.env.GITHUB_REPOSITORY;\n }\n if (process.env.GITHUB_TOKEN !== undefined) {\n uploadOpts.token = process.env.GITHUB_TOKEN;\n }\n await uploadReleaseAssets(uploadOpts);\n }\n const summaryPath = process.env.GITHUB_STEP_SUMMARY;\n if (summaryPath !== undefined && summaryPath.length > 0) {\n await appendJobSummary(summaryPath, written.manifest, written.dir);\n }\n const exitCode: 0 | 1 | 2 = input.flags.strict === true && input.result.warnings.length > 0 ? 2 : 0;\n const done: {\n dryRun: false;\n facts: Facts;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir: string;\n manifest: Manifest;\n warnings: GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n } = {\n dryRun: false,\n facts: input.facts,\n copy: input.copy,\n copyMode: input.copyMode,\n dir: written.dir,\n manifest: written.manifest,\n warnings: input.result.warnings,\n exitCode,\n };\n if (input.copyWarning !== undefined) {\n done.copyWarning = input.copyWarning;\n }\n return done;\n}\n","// bench: before/after cards from bench JSON\n// Spec: docs/PROJECT_PLAN.md §18.4\n\nimport { loadBrand } from \"../brand/load.js\";\nimport { loadConfig } from \"../config/load.js\";\nimport { benchCopy } from \"../copy/deterministic.js\";\nimport { generate } from \"../core/generate.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport { collectFacts } from \"../sources/collect.js\";\nimport { createTakumiRenderer } from \"../render/takumi.js\";\nimport {\n collectEnv,\n finishPack,\n loadLogos,\n overlayFormats,\n resolveCopy,\n resolveThemes,\n type SharedFlags,\n} from \"./shared.js\";\n\nexport interface BenchFlags extends SharedFlags {\n file?: string;\n}\n\nexport interface BenchResult {\n dryRun: boolean;\n facts: Awaited<ReturnType<typeof collectFacts>>;\n copy: import(\"../copy/slots.js\").Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir?: string;\n manifest?: import(\"../outputs/manifest.js\").Manifest;\n warnings: import(\"../core/generate.js\").GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n}\n\nexport async function runBench(flags: BenchFlags): Promise<BenchResult> {\n const cwd = flags.cwd;\n const config = overlayFormats(await loadConfig(cwd), flags);\n const brand = await loadBrand(cwd);\n const file = flags.file ?? config.bench?.file ?? \".shipseal/bench.json\";\n const event: ShipsealEvent = { kind: \"bench\", file };\n const env = collectEnv(flags);\n const collectOpts: Parameters<typeof collectFacts>[0] = {\n cwd,\n event,\n skipNetwork: true,\n benchFile: file,\n };\n if (env.packagePath !== undefined) {\n collectOpts.packagePath = env.packagePath;\n }\n const facts = await collectFacts(collectOpts);\n const resolved = await resolveCopy(facts, config, flags.copy === false, benchCopy(facts));\n\n if (flags.dryRun === true) {\n const dry: BenchResult = {\n dryRun: true,\n facts,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n warnings: [],\n exitCode: 0,\n };\n if (resolved.warning !== undefined) {\n dry.copyWarning = resolved.warning;\n }\n return dry;\n }\n\n const renderer = await createTakumiRenderer();\n const generateInput: Parameters<typeof generate>[0] = {\n event,\n facts,\n brand,\n config,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n renderer,\n themes: resolveThemes(flags.themes, brand.theme),\n generatedAt: new Date().toISOString(),\n };\n const logos = await loadLogos(cwd, brand);\n if (logos !== undefined) {\n generateInput.logos = logos;\n }\n const result = await generate(generateInput);\n const packInput: Parameters<typeof finishPack>[0] = {\n flags,\n config,\n event,\n result,\n brand,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n facts,\n };\n if (resolved.warning !== undefined) {\n packInput.copyWarning = resolved.warning;\n }\n return finishPack(packInput);\n}\n","// doctor: environment and config checks\n// Spec: docs/PROJECT_PLAN.md §18.5\n\nimport { execFile } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { brandSchema } from \"../brand/schema.js\";\nimport { FORMATS } from \"../formats.js\";\nimport {\n createTakumiRenderer,\n resolvePackageRoot,\n testCardNode,\n} from \"../render/takumi.js\";\n\nconst execFileAsync = promisify(execFile);\nconst MIN_NODE_MAJOR = 22;\n\nexport type CheckStatus = \"pass\" | \"fail\" | \"info\";\n\nexport interface DoctorCheck {\n name: string;\n status: CheckStatus;\n message: string;\n fix?: string;\n}\n\nexport interface DoctorResult {\n ok: boolean;\n checks: DoctorCheck[];\n}\n\nexport async function runDoctor(cwd: string): Promise<DoctorResult> {\n const checks: DoctorCheck[] = [];\n checks.push(checkNode());\n checks.push(await checkGit(cwd));\n checks.push(await checkShallow(cwd));\n checks.push(await checkBrand(cwd));\n checks.push(await checkFont());\n checks.push(await checkLogo(cwd));\n checks.push(checkGithubToken());\n checks.push(await checkRender());\n\n return {\n ok: checks.every((check) => check.status !== \"fail\"),\n checks,\n };\n}\n\nfunction checkNode(): DoctorCheck {\n const version = process.versions.node;\n const major = Number.parseInt(version.split(\".\")[0] ?? \"0\", 10);\n if (major >= MIN_NODE_MAJOR) {\n return { name: \"node\", status: \"pass\", message: `Node.js ${version}` };\n }\n return {\n name: \"node\",\n status: \"fail\",\n message: `Node.js ${version} is below the minimum of ${MIN_NODE_MAJOR}.`,\n fix: `Install Node.js ${MIN_NODE_MAJOR} or newer.`,\n };\n}\n\nasync function checkGit(cwd: string): Promise<DoctorCheck> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"--version\"], { cwd });\n return { name: \"git\", status: \"pass\", message: stdout.trim() };\n } catch {\n return {\n name: \"git\",\n status: \"fail\",\n message: \"git is not available on PATH.\",\n fix: \"Install git and ensure it is on PATH.\",\n };\n }\n}\n\nasync function checkShallow(cwd: string): Promise<DoctorCheck> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"rev-parse\", \"--is-shallow-repository\"], {\n cwd,\n });\n if (stdout.trim() === \"true\") {\n return {\n name: \"clone-depth\",\n status: \"fail\",\n message: \"This git clone is shallow, so release facts will be incomplete.\",\n fix: \"Re-clone with a full history, or in GitHub Actions set fetch-depth: 0.\",\n };\n }\n return { name: \"clone-depth\", status: \"pass\", message: \"Full git history is available.\" };\n } catch {\n return {\n name: \"clone-depth\",\n status: \"info\",\n message: \"Could not determine whether the clone is shallow.\",\n };\n }\n}\n\nasync function checkBrand(cwd: string): Promise<DoctorCheck> {\n const path = join(cwd, \".shipseal\", \"brand.json\");\n if (!existsSync(path)) {\n return {\n name: \"brand.json\",\n status: \"fail\",\n message: \".shipseal/brand.json is missing.\",\n fix: \"Run shipseal init to detect a brand kit.\",\n };\n }\n try {\n const raw: unknown = JSON.parse(await readFile(path, \"utf8\"));\n const parsed = brandSchema.safeParse(raw);\n if (!parsed.success) {\n return {\n name: \"brand.json\",\n status: \"fail\",\n message: \"brand.json did not match the v1 schema.\",\n fix: parsed.error.issues.map((issue) => issue.message).join(\"; \"),\n };\n }\n return { name: \"brand.json\", status: \"pass\", message: `Brand ${parsed.data.name} is valid.` };\n } catch (error) {\n if (error instanceof SyntaxError) {\n return {\n name: \"brand.json\",\n status: \"fail\",\n message: \"brand.json is not valid JSON.\",\n fix: \"Fix the JSON syntax, or re-run shipseal init --force.\",\n };\n }\n throw error;\n }\n}\n\nasync function checkFont(): Promise<DoctorCheck> {\n try {\n const root = resolvePackageRoot();\n const fontPath = join(root, \"assets\", \"fonts\", \"GeistMono[wght].ttf\");\n if (!existsSync(fontPath)) {\n return {\n name: \"fonts\",\n status: \"fail\",\n message: \"Vendored Geist Mono file is missing.\",\n fix: \"Reinstall shipseal so assets/fonts/GeistMono[wght].ttf is present.\",\n };\n }\n return { name: \"fonts\", status: \"pass\", message: `Geist Mono found at ${fontPath}` };\n } catch {\n return {\n name: \"fonts\",\n status: \"fail\",\n message: \"Could not resolve the vendored Geist Mono font.\",\n fix: \"Reinstall shipseal so assets/fonts/GeistMono[wght].ttf is present.\",\n };\n }\n}\n\nasync function checkLogo(cwd: string): Promise<DoctorCheck> {\n const path = join(cwd, \".shipseal\", \"brand.json\");\n if (!existsSync(path)) {\n return {\n name: \"logo\",\n status: \"info\",\n message: \"Skipped; brand.json is missing.\",\n };\n }\n const raw: unknown = JSON.parse(await readFile(path, \"utf8\"));\n const parsed = brandSchema.safeParse(raw);\n if (!parsed.success || parsed.data.logo === undefined) {\n return { name: \"logo\", status: \"info\", message: \"No logo path in brand.json.\" };\n }\n const light = join(cwd, parsed.data.logo.light);\n if (!existsSync(light)) {\n return {\n name: \"logo\",\n status: \"fail\",\n message: `Logo file ${parsed.data.logo.light} is not readable.`,\n fix: \"Point brand.json logo.light at an existing SVG or PNG, or re-run init.\",\n };\n }\n return { name: \"logo\", status: \"pass\", message: `Logo readable at ${parsed.data.logo.light}` };\n}\n\nfunction checkGithubToken(): DoctorCheck {\n if (process.env.GITHUB_TOKEN !== undefined && process.env.GITHUB_TOKEN.length > 0) {\n return { name: \"GITHUB_TOKEN\", status: \"info\", message: \"GITHUB_TOKEN is set.\" };\n }\n return {\n name: \"GITHUB_TOKEN\",\n status: \"info\",\n message: \"GITHUB_TOKEN is not set. Unauthenticated GitHub API calls have a low rate limit.\",\n };\n}\n\nasync function checkRender(): Promise<DoctorCheck> {\n try {\n const renderer = await createTakumiRenderer();\n const png = await renderer.render(testCardNode(), {\n width: FORMATS.og.width,\n height: FORMATS.og.height,\n format: \"png\",\n });\n if (png.length < 8 || png[0] !== 0x89 || png[1] !== 0x50) {\n return {\n name: \"takumi\",\n status: \"fail\",\n message: \"Takumi rendered bytes that are not a PNG.\",\n fix: \"File an issue with the doctor output and your OS/arch.\",\n };\n }\n return {\n name: \"takumi\",\n status: \"pass\",\n message: `Rendered a ${FORMATS.og.width}x${FORMATS.og.height} test card (${png.length} bytes).`,\n };\n } catch (error) {\n return {\n name: \"takumi\",\n status: \"fail\",\n message: error instanceof Error ? error.message : \"Takumi failed to render a test card.\",\n fix: \"Check that the native Takumi binary installed for this platform.\",\n };\n }\n}\n","// CSS color parsing, oklch to sRGB hex, and contrast (no dependency)\n// Spec: docs/PROJECT_PLAN.md §10.3 and §25 (S7 oklch converter)\n\nconst HEX = /^#([\\da-f]{3}|[\\da-f]{6}|[\\da-f]{8})$/i;\n\nexport function parseCssColor(value: string): string | undefined {\n const trimmed = value.trim();\n const hex = normalizeHex(trimmed);\n if (hex !== undefined) {\n return hex;\n }\n const oklch = parseOklch(trimmed);\n if (oklch !== undefined) {\n return oklchToHex(oklch.l, oklch.c, oklch.h);\n }\n const rgb = parseRgb(trimmed);\n if (rgb !== undefined) {\n return rgbToHex(rgb[0], rgb[1], rgb[2]);\n }\n const hsl = parseHsl(trimmed);\n if (hsl !== undefined) {\n return rgbToHex(...hslToRgb(hsl[0], hsl[1], hsl[2]));\n }\n return undefined;\n}\n\nexport function normalizeHex(value: string): string | undefined {\n const match = HEX.exec(value.trim());\n if (match === null) {\n return undefined;\n }\n const raw = match[1];\n if (raw === undefined) {\n return undefined;\n }\n if (raw.length === 3) {\n return `#${raw[0]}${raw[0]}${raw[1]}${raw[1]}${raw[2]}${raw[2]}`.toLowerCase();\n }\n return `#${raw.slice(0, 6).toLowerCase()}`;\n}\n\nexport function oklchToHex(l: number, c: number, h: number): string {\n const hr = (h * Math.PI) / 180;\n const a = c * Math.cos(hr);\n const b = c * Math.sin(hr);\n const coneL = l + 0.3963377774 * a + 0.2158037573 * b;\n const coneM = l - 0.1055613458 * a - 0.0638541728 * b;\n const coneS = l - 0.0894841775 * a - 1.291485548 * b;\n const l3 = coneL * coneL * coneL;\n const m3 = coneM * coneM * coneM;\n const s3 = coneS * coneS * coneS;\n const r = 4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3;\n const g = -1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3;\n const bLin = -0.0041960863 * l3 - 0.7034186147 * m3 + 1.707614701 * s3;\n return rgbToHex(srgbEncode(r) * 255, srgbEncode(g) * 255, srgbEncode(bLin) * 255);\n}\n\nexport function contrastRatio(hexA: string, hexB: string): number {\n const a = relativeLuminance(hexA);\n const b = relativeLuminance(hexB);\n const [hi, lo] = a > b ? [a, b] : [b, a];\n return (hi + 0.05) / (lo + 0.05);\n}\n\nexport const LARGE_TEXT_CONTRAST = 3;\n\nexport function ensureForegroundContrast(\n background: string,\n foreground: string,\n): { foreground: string; adjusted: boolean } {\n if (contrastRatio(background, foreground) >= LARGE_TEXT_CONTRAST) {\n return { foreground, adjusted: false };\n }\n const light = \"#fafafa\";\n const dark = \"#0b0b0c\";\n const lightRatio = contrastRatio(background, light);\n const darkRatio = contrastRatio(background, dark);\n return { foreground: lightRatio >= darkRatio ? light : dark, adjusted: true };\n}\n\nexport function readableOnBackground(background: string, candidate: string): boolean {\n return contrastRatio(background, candidate) >= LARGE_TEXT_CONTRAST;\n}\n\nfunction srgbEncode(channel: number): number {\n const abs = Math.abs(channel);\n const encoded = abs <= 0.0031308 ? 12.92 * abs : 1.055 * abs ** (1 / 2.4) - 0.055;\n return Math.sign(channel) * encoded;\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return `#${toByte(r)}${toByte(g)}${toByte(b)}`;\n}\n\nfunction toByte(n: number): string {\n return Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .padStart(2, \"0\");\n}\n\nfunction relativeLuminance(hex: string): number {\n const rgb = hexToRgb(hex);\n if (rgb === undefined) {\n return 0;\n }\n const lin = rgb.map((channel) => {\n const s = channel / 255;\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n });\n return 0.2126 * (lin[0] ?? 0) + 0.7152 * (lin[1] ?? 0) + 0.0722 * (lin[2] ?? 0);\n}\n\nexport function isNeutralHex(hex: string): boolean {\n const rgb = hexToRgb(hex);\n if (rgb === undefined) {\n return true;\n }\n const max = Math.max(rgb[0], rgb[1], rgb[2]);\n const min = Math.min(rgb[0], rgb[1], rgb[2]);\n return max - min < 16;\n}\n\nfunction hexToRgb(hex: string): [number, number, number] | undefined {\n const normalized = normalizeHex(hex);\n if (normalized === undefined) {\n return undefined;\n }\n const r = Number.parseInt(normalized.slice(1, 3), 16);\n const g = Number.parseInt(normalized.slice(3, 5), 16);\n const b = Number.parseInt(normalized.slice(5, 7), 16);\n return [r, g, b];\n}\n\nfunction parseOklch(value: string): { l: number; c: number; h: number } | undefined {\n const match = /^oklch\\(\\s*([^/)]+?)(?:\\s*\\/\\s*[^)]+)?\\s*\\)$/i.exec(value);\n if (match === null) {\n return undefined;\n }\n const body = match[1];\n if (body === undefined) {\n return undefined;\n }\n const parts = splitCssArgs(body);\n if (parts.length < 3) {\n return undefined;\n }\n const l = parseLightness(parts[0] ?? \"\");\n const c = parseNumber(parts[1] ?? \"\");\n const h = parseHue(parts[2] ?? \"\");\n if (l === undefined || c === undefined || h === undefined) {\n return undefined;\n }\n return { l, c, h };\n}\n\nfunction parseRgb(value: string): [number, number, number] | undefined {\n const match = /^rgba?\\(\\s*([^/)]+?)(?:\\s*\\/\\s*[^)]+)?\\s*\\)$/i.exec(value);\n if (match === null) {\n return undefined;\n }\n const parts = splitCssArgs(match[1] ?? \"\");\n if (parts.length < 3) {\n return undefined;\n }\n const r = parseRgbChannel(parts[0] ?? \"\");\n const g = parseRgbChannel(parts[1] ?? \"\");\n const b = parseRgbChannel(parts[2] ?? \"\");\n if (r === undefined || g === undefined || b === undefined) {\n return undefined;\n }\n return [r, g, b];\n}\n\nfunction parseHsl(value: string): [number, number, number] | undefined {\n const match = /^hsla?\\(\\s*([^/)]+?)(?:\\s*\\/\\s*[^)]+)?\\s*\\)$/i.exec(value);\n if (match === null) {\n return undefined;\n }\n const parts = splitCssArgs(match[1] ?? \"\");\n if (parts.length < 3) {\n return undefined;\n }\n const h = parseHue(parts[0] ?? \"\");\n const s = parsePercent(parts[1] ?? \"\");\n const l = parsePercent(parts[2] ?? \"\");\n if (h === undefined || s === undefined || l === undefined) {\n return undefined;\n }\n return [h, s, l];\n}\n\nfunction hslToRgb(h: number, s: number, l: number): [number, number, number] {\n const sat = s / 100;\n const light = l / 100;\n const c = (1 - Math.abs(2 * light - 1)) * sat;\n const hp = (((h % 360) + 360) % 360) / 60;\n const x = c * (1 - Math.abs((hp % 2) - 1));\n let r = 0;\n let g = 0;\n let b = 0;\n if (hp < 1) {\n r = c;\n g = x;\n } else if (hp < 2) {\n r = x;\n g = c;\n } else if (hp < 3) {\n g = c;\n b = x;\n } else if (hp < 4) {\n g = x;\n b = c;\n } else if (hp < 5) {\n r = x;\n b = c;\n } else {\n r = c;\n b = x;\n }\n const m = light - c / 2;\n return [(r + m) * 255, (g + m) * 255, (b + m) * 255];\n}\n\nfunction splitCssArgs(body: string): string[] {\n return body\n .split(/[\\s,]+/)\n .map((part) => part.trim())\n .filter((part) => part.length > 0);\n}\n\nfunction parseLightness(token: string): number | undefined {\n if (token.endsWith(\"%\")) {\n const n = Number.parseFloat(token.slice(0, -1));\n return Number.isFinite(n) ? n / 100 : undefined;\n }\n return parseNumber(token);\n}\n\nfunction parseHue(token: string): number | undefined {\n if (token === \"none\") {\n return 0;\n }\n if (token.endsWith(\"deg\")) {\n return parseNumber(token.slice(0, -3));\n }\n if (token.endsWith(\"rad\")) {\n const n = parseNumber(token.slice(0, -3));\n return n === undefined ? undefined : (n * 180) / Math.PI;\n }\n if (token.endsWith(\"turn\")) {\n const n = parseNumber(token.slice(0, -4));\n return n === undefined ? undefined : n * 360;\n }\n if (token.endsWith(\"grad\")) {\n const n = parseNumber(token.slice(0, -4));\n return n === undefined ? undefined : n * 0.9;\n }\n return parseNumber(token);\n}\n\nfunction parsePercent(token: string): number | undefined {\n if (!token.endsWith(\"%\")) {\n return parseNumber(token);\n }\n return parseNumber(token.slice(0, -1));\n}\n\nfunction parseRgbChannel(token: string): number | undefined {\n if (token.endsWith(\"%\")) {\n const n = parseNumber(token.slice(0, -1));\n return n === undefined ? undefined : (n / 100) * 255;\n }\n return parseNumber(token);\n}\n\nfunction parseNumber(token: string): number | undefined {\n if (token === \"none\") {\n return 0;\n }\n const n = Number.parseFloat(token);\n return Number.isFinite(n) ? n : undefined;\n}\n","// CSS :root variable extraction\n// Spec: docs/PROJECT_PLAN.md §10.3\n\nimport { parseCssColor } from \"./color.js\";\nimport type { ExtractedColors } from \"./tailwind.js\";\n\nconst PROP =\n /--(primary|brand|accent|background|foreground|muted-foreground|muted)\\s*:\\s*([^;]+);/g;\n\nexport function extractCssRootColors(css: string): ExtractedColors {\n const fromRoot = extractBlockColors(css, /:root\\s*\\{/g);\n const fromDark = extractBlockColors(css, /\\.dark\\s*\\{/g);\n return mapFoundColors({ ...fromRoot, ...fromDark });\n}\n\nfunction extractBlockColors(css: string, blockRe: RegExp): Record<string, string> {\n const found: Record<string, string> = {};\n blockRe.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = blockRe.exec(css)) !== null) {\n const open = css.indexOf(\"{\", match.index);\n if (open === -1) {\n break;\n }\n const close = matchingBrace(css, open);\n if (close === -1) {\n break;\n }\n const body = css.slice(open + 1, close);\n PROP.lastIndex = 0;\n let prop: RegExpExecArray | null;\n while ((prop = PROP.exec(body)) !== null) {\n const name = prop[1];\n const raw = prop[2];\n if (name === undefined || raw === undefined) {\n continue;\n }\n const hex = parseCssColor(raw.trim());\n if (hex !== undefined) {\n found[name] = hex;\n }\n }\n }\n return found;\n}\n\nfunction mapFoundColors(found: Record<string, string>): ExtractedColors {\n const out: ExtractedColors = {};\n const background = found.background;\n if (background !== undefined) {\n out.background = background;\n }\n const foreground = found.foreground;\n if (foreground !== undefined) {\n out.foreground = foreground;\n }\n const muted = found[\"muted-foreground\"] ?? found.muted;\n if (muted !== undefined) {\n out.muted = muted;\n }\n const primary = found.primary ?? found.brand;\n if (primary !== undefined) {\n out.primary = primary;\n }\n if (found.accent !== undefined) {\n out.accent = found.accent;\n }\n return out;\n}\n\nfunction matchingBrace(source: string, openIndex: number): number {\n let depth = 0;\n for (let i = openIndex; i < source.length; i += 1) {\n const ch = source[i];\n if (ch === \"{\") {\n depth += 1;\n } else if (ch === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return i;\n }\n }\n }\n return -1;\n}\n","// W3C Design Tokens reader\n// Spec: docs/PROJECT_PLAN.md §10.1\n\nimport { parseCssColor } from \"./color.js\";\nimport type { ExtractedColors } from \"./tailwind.js\";\n\nexport function extractDtcgColors(tokens: unknown): ExtractedColors {\n const found: Record<string, string> = {};\n walk(tokens, [], found);\n const out: ExtractedColors = {};\n const background = found.background ?? found.bg;\n if (background !== undefined) {\n out.background = background;\n }\n const foreground = found.foreground ?? found.fg;\n if (foreground !== undefined) {\n out.foreground = foreground;\n }\n if (found.muted !== undefined) {\n out.muted = found.muted;\n }\n const primary = found.primary ?? found.brand;\n if (primary !== undefined) {\n out.primary = primary;\n }\n const accent = found.accent ?? found.secondary;\n if (accent !== undefined) {\n out.accent = accent;\n }\n return out;\n}\n\nfunction walk(node: unknown, path: string[], found: Record<string, string>): void {\n if (!isRecord(node)) {\n return;\n }\n if (node.$type === \"color\") {\n const hex = colorValue(node.$value);\n const leaf = path[path.length - 1];\n if (hex !== undefined && leaf !== undefined && found[leaf] === undefined) {\n found[leaf] = hex;\n }\n return;\n }\n for (const [key, value] of Object.entries(node)) {\n if (key.startsWith(\"$\")) {\n continue;\n }\n walk(value, [...path, key], found);\n }\n}\n\nfunction colorValue(value: unknown): string | undefined {\n if (typeof value === \"string\") {\n return parseCssColor(value);\n }\n if (isRecord(value) && typeof value.hex === \"string\") {\n return parseCssColor(value.hex);\n }\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","// Logo discovery\n// Spec: docs/PROJECT_PLAN.md §10.3\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst DIRECTORIES = [\"\", \"assets\", \"assets/brand\", \"public\", \"public/brand\", \".github\", \"docs\", \"static\", \"branding\"];\nconst ICON_NAMES = [\"icon.svg\", \"icon.png\"];\nconst NAMES = [\"logo.svg\", \"logo.png\", \"logo-light.svg\", \"logo-light.png\"];\nconst FALLBACKS = [...ICON_NAMES, \"favicon.svg\"];\n\nexport function findLogo(cwd: string): string | undefined {\n for (const dir of DIRECTORIES) {\n for (const name of NAMES) {\n const relative = dir === \"\" ? name : join(dir, name);\n if (existsSync(join(cwd, relative))) {\n return relative;\n }\n }\n }\n for (const dir of DIRECTORIES) {\n for (const name of FALLBACKS) {\n const relative = dir === \"\" ? name : join(dir, name);\n if (existsSync(join(cwd, relative))) {\n return relative;\n }\n }\n }\n return undefined;\n}\n\nexport function findLogoPair(cwd: string): { light: string; dark?: string } | undefined {\n const light = findLogo(cwd);\n if (light === undefined) {\n return undefined;\n }\n const darkNames = [\"logo-dark.svg\", \"logo-dark.png\"];\n for (const dir of DIRECTORIES) {\n for (const name of darkNames) {\n const relative = dir === \"\" ? name : join(dir, name);\n if (existsSync(join(cwd, relative))) {\n return { light, dark: relative };\n }\n }\n }\n return { light };\n}\n","// Minimal PNG reader for brand colour detection.\n// Spec: docs/PROJECT_PLAN.md §10.3 (logo colour detection)\n//\n// Logos are the only PNGs this reads, so it covers what logo exporters emit: 8 and 16 bit\n// depths, colour types 0, 2, 3, 4 and 6, no interlacing. Anything else returns undefined and\n// the caller reports the colour as not found rather than guessing. Decoding is done here\n// instead of with a library because `pngjs` would be a runtime dependency for one small job.\n\nimport { inflateSync } from \"node:zlib\";\n\nconst SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n\n/** Channels per pixel for each PNG colour type. Index is the colour type. */\nconst CHANNELS: Record<number, number> = { 0: 1, 2: 3, 3: 1, 4: 2, 6: 4 };\n\nexport interface DecodedPng {\n width: number;\n height: number;\n /** Row-major RGBA, four bytes per pixel. */\n pixels: Uint8Array;\n}\n\nexport function decodePng(buffer: Buffer): DecodedPng | undefined {\n if (buffer.length < 8 || !buffer.subarray(0, 8).equals(SIGNATURE)) {\n return undefined;\n }\n\n let width = 0;\n let height = 0;\n let bitDepth = 0;\n let colorType = 0;\n let interlace = 0;\n let palette: Buffer | undefined;\n let paletteAlpha: Buffer | undefined;\n const idat: Buffer[] = [];\n\n let offset = 8;\n while (offset + 8 <= buffer.length) {\n const length = buffer.readUInt32BE(offset);\n const type = buffer.toString(\"ascii\", offset + 4, offset + 8);\n const start = offset + 8;\n const end = start + length;\n if (end > buffer.length) {\n return undefined;\n }\n\n if (type === \"IHDR\") {\n width = buffer.readUInt32BE(start);\n height = buffer.readUInt32BE(start + 4);\n bitDepth = buffer[start + 8] ?? 0;\n colorType = buffer[start + 9] ?? 0;\n interlace = buffer[start + 12] ?? 0;\n } else if (type === \"PLTE\") {\n palette = buffer.subarray(start, end);\n } else if (type === \"tRNS\") {\n paletteAlpha = buffer.subarray(start, end);\n } else if (type === \"IDAT\") {\n idat.push(buffer.subarray(start, end));\n } else if (type === \"IEND\") {\n break;\n }\n\n offset = end + 4; // skip the CRC\n }\n\n const channels = CHANNELS[colorType];\n if (\n width === 0 ||\n height === 0 ||\n channels === undefined ||\n interlace !== 0 ||\n (bitDepth !== 8 && bitDepth !== 16) ||\n idat.length === 0 ||\n (colorType === 3 && palette === undefined)\n ) {\n return undefined;\n }\n\n // Guard against a malformed header claiming an enormous image.\n if (width * height > 64_000_000) {\n return undefined;\n }\n\n let raw: Buffer;\n try {\n raw = inflateSync(Buffer.concat(idat));\n } catch {\n return undefined;\n }\n\n const bytesPerSample = bitDepth / 8;\n const bpp = channels * bytesPerSample;\n const stride = width * bpp;\n if (raw.length < height * (stride + 1)) {\n return undefined;\n }\n\n const unfiltered = unfilter(raw, height, stride, bpp);\n if (unfiltered === undefined) {\n return undefined;\n }\n\n return { width, height, pixels: toRgba(unfiltered, width, height, colorType, bytesPerSample, palette, paletteAlpha) };\n}\n\n/** Reverse the per-scanline filters defined in the PNG spec. */\nfunction unfilter(raw: Buffer, height: number, stride: number, bpp: number): Buffer | undefined {\n const out = Buffer.alloc(height * stride);\n let pos = 0;\n for (let y = 0; y < height; y++) {\n const filter = raw[pos];\n pos += 1;\n if (filter === undefined || filter > 4) {\n return undefined;\n }\n const rowStart = y * stride;\n const prevStart = rowStart - stride;\n for (let x = 0; x < stride; x++) {\n const value = raw[pos + x] ?? 0;\n const a = x >= bpp ? (out[rowStart + x - bpp] ?? 0) : 0;\n const b = y > 0 ? (out[prevStart + x] ?? 0) : 0;\n const c = x >= bpp && y > 0 ? (out[prevStart + x - bpp] ?? 0) : 0;\n let restored: number;\n switch (filter) {\n case 1: {\n restored = value + a;\n break;\n }\n case 2: {\n restored = value + b;\n break;\n }\n case 3: {\n restored = value + Math.floor((a + b) / 2);\n break;\n }\n case 4: {\n restored = value + paeth(a, b, c);\n break;\n }\n default: {\n restored = value;\n }\n }\n out[rowStart + x] = restored & 0xff;\n }\n pos += stride;\n }\n return out;\n}\n\nfunction paeth(a: number, b: number, c: number): number {\n const p = a + b - c;\n const pa = Math.abs(p - a);\n const pb = Math.abs(p - b);\n const pc = Math.abs(p - c);\n if (pa <= pb && pa <= pc) {\n return a;\n }\n return pb <= pc ? b : c;\n}\n\nfunction toRgba(\n data: Buffer,\n width: number,\n height: number,\n colorType: number,\n bytesPerSample: number,\n palette: Buffer | undefined,\n paletteAlpha: Buffer | undefined,\n): Uint8Array {\n const pixels = new Uint8Array(width * height * 4);\n const channels = CHANNELS[colorType] ?? 4;\n const bpp = channels * bytesPerSample;\n\n for (let i = 0; i < width * height; i++) {\n // For 16 bit samples the high byte is a close enough approximation for colour picking.\n const at = (channel: number): number => data[i * bpp + channel * bytesPerSample] ?? 0;\n const out = i * 4;\n switch (colorType) {\n case 0: {\n const g = at(0);\n pixels[out] = g;\n pixels[out + 1] = g;\n pixels[out + 2] = g;\n pixels[out + 3] = 255;\n break;\n }\n case 2: {\n pixels[out] = at(0);\n pixels[out + 1] = at(1);\n pixels[out + 2] = at(2);\n pixels[out + 3] = 255;\n break;\n }\n case 3: {\n const index = at(0);\n pixels[out] = palette?.[index * 3] ?? 0;\n pixels[out + 1] = palette?.[index * 3 + 1] ?? 0;\n pixels[out + 2] = palette?.[index * 3 + 2] ?? 0;\n pixels[out + 3] = paletteAlpha?.[index] ?? 255;\n break;\n }\n case 4: {\n const g = at(0);\n pixels[out] = g;\n pixels[out + 1] = g;\n pixels[out + 2] = g;\n pixels[out + 3] = at(1);\n break;\n }\n default: {\n pixels[out] = at(0);\n pixels[out + 1] = at(1);\n pixels[out + 2] = at(2);\n pixels[out + 3] = at(3);\n }\n }\n }\n return pixels;\n}\n\n/**\n * Most common non-neutral colour in a logo, as a hex string.\n *\n * Nearly transparent pixels are ignored so a transparent background does not win, and greys\n * are ignored because a logo's black wordmark is not its brand colour. Colours are bucketed\n * into 16 levels per channel so anti-aliased edges group with the solid fill they belong to,\n * then the winning bucket reports the average of the real pixels inside it rather than the\n * bucket centre, which would drift the hue.\n */\nexport function dominantNonNeutralColor(png: DecodedPng): string | undefined {\n const buckets = new Map<number, { count: number; r: number; g: number; b: number }>();\n\n for (let i = 0; i < png.pixels.length; i += 4) {\n const a = png.pixels[i + 3] ?? 0;\n if (a < 128) {\n continue;\n }\n const r = png.pixels[i] ?? 0;\n const g = png.pixels[i + 1] ?? 0;\n const b = png.pixels[i + 2] ?? 0;\n if (Math.max(r, g, b) - Math.min(r, g, b) < 16) {\n continue; // grey, including pure black and white\n }\n const key = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4);\n const bucket = buckets.get(key);\n if (bucket === undefined) {\n buckets.set(key, { count: 1, r, g, b });\n } else {\n bucket.count += 1;\n bucket.r += r;\n bucket.g += g;\n bucket.b += b;\n }\n }\n\n let best: { count: number; r: number; g: number; b: number } | undefined;\n for (const bucket of buckets.values()) {\n if (best === undefined || bucket.count > best.count) {\n best = bucket;\n }\n }\n if (best === undefined) {\n return undefined;\n }\n\n const channel = (total: number): string =>\n Math.round(total / best.count)\n .toString(16)\n .padStart(2, \"0\");\n return `#${channel(best.r)}${channel(best.g)}${channel(best.b)}`;\n}\n","// Static Tailwind v3 config + v4 @theme color extraction\n// Spec: docs/PROJECT_PLAN.md §10.3, spike S7\n\nimport { parseCssColor } from \"./color.js\";\n\nexport interface ExtractedColors {\n background?: string;\n foreground?: string;\n muted?: string;\n primary?: string;\n accent?: string;\n}\n\nconst COLOR_PROP = /--color-([a-zA-Z0-9-]+)\\s*:\\s*([^;]+);/g;\nconst CUSTOM_PROP = /--([a-zA-Z0-9-]+)\\s*:\\s*([^;]+);/g;\nconst SKIP_PREFIXES = new Set([\"chart\", \"sidebar\", \"ring\", \"border\", \"input\", \"destructive\"]);\n\nexport function extractTailwindV4Colors(css: string): ExtractedColors {\n const blocks = themeBlocks(css);\n const custom = collectCustomProperties(css);\n const fromTheme: Record<string, string> = {};\n for (const block of blocks) {\n COLOR_PROP.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = COLOR_PROP.exec(block)) !== null) {\n const name = match[1];\n const raw = match[2];\n if (name === undefined || raw === undefined || shouldSkip(name)) {\n continue;\n }\n fromTheme[name] = raw.trim();\n }\n }\n const resolved: Record<string, string> = {};\n for (const [name, raw] of Object.entries(fromTheme)) {\n const hex = resolveToHex(raw, custom, 0);\n if (hex !== undefined) {\n resolved[name] = hex;\n }\n }\n return mapBrandColors(resolved);\n}\n\nexport function extractTailwindV3Colors(source: string): ExtractedColors {\n const found: Record<string, string> = {};\n const re =\n /\\b(primary|brand|accent|background|foreground|muted|secondary)\\b\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const name = match[1];\n const raw = match[2];\n if (name === undefined || raw === undefined) {\n continue;\n }\n const hex = parseCssColor(raw);\n if (hex !== undefined) {\n found[name] = hex;\n }\n }\n return mapBrandColors(found);\n}\n\nfunction themeBlocks(css: string): string[] {\n const blocks: string[] = [];\n const re = /@theme(?:\\s+inline)?\\s*\\{/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(css)) !== null) {\n const open = css.indexOf(\"{\", match.index);\n if (open === -1) {\n break;\n }\n const close = matchingBrace(css, open);\n if (close === -1) {\n break;\n }\n blocks.push(css.slice(open + 1, close));\n }\n return blocks;\n}\n\nfunction matchingBrace(source: string, openIndex: number): number {\n let depth = 0;\n for (let i = openIndex; i < source.length; i += 1) {\n const ch = source[i];\n if (ch === \"{\") {\n depth += 1;\n } else if (ch === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return i;\n }\n }\n }\n return -1;\n}\n\nfunction collectCustomProperties(css: string): Map<string, string> {\n const props = new Map<string, string>();\n CUSTOM_PROP.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = CUSTOM_PROP.exec(css)) !== null) {\n const name = match[1];\n const value = match[2];\n if (name !== undefined && value !== undefined) {\n props.set(`--${name}`, value.trim());\n }\n }\n return props;\n}\n\nfunction resolveToHex(\n raw: string,\n custom: Map<string, string>,\n depth: number,\n): string | undefined {\n if (depth > 3) {\n return undefined;\n }\n const direct = parseCssColor(raw);\n if (direct !== undefined) {\n return direct;\n }\n const varMatch = /^var\\(\\s*(--[a-zA-Z0-9-]+)\\s*(?:,[^)]+)?\\)$/.exec(raw);\n if (varMatch === null) {\n return undefined;\n }\n const ref = varMatch[1];\n if (ref === undefined) {\n return undefined;\n }\n const next = custom.get(ref);\n if (next === undefined) {\n return undefined;\n }\n return resolveToHex(next, custom, depth + 1);\n}\n\nfunction shouldSkip(name: string): boolean {\n const root = name.split(\"-\")[0];\n return root !== undefined && SKIP_PREFIXES.has(root);\n}\n\nfunction mapBrandColors(found: Record<string, string>): ExtractedColors {\n const out: ExtractedColors = {};\n const background = found.background ?? found.bg;\n if (background !== undefined) {\n out.background = background;\n }\n const foreground = found.foreground ?? found.fg;\n if (foreground !== undefined) {\n out.foreground = foreground;\n }\n const muted = found[\"muted-foreground\"] ?? found.muted;\n if (muted !== undefined) {\n out.muted = muted;\n }\n const primary = found.primary ?? found.brand;\n if (primary !== undefined) {\n out.primary = primary;\n }\n const accent = found.accent ?? found.secondary;\n if (accent !== undefined) {\n out.accent = accent;\n }\n return out;\n}\n","// Brand detection pipeline\n// Spec: docs/PROJECT_PLAN.md §10.3\n\nimport { execFile } from \"node:child_process\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { join, relative, basename } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { z } from \"zod\";\nimport { ensureForegroundContrast, isNeutralHex, parseCssColor, readableOnBackground } from \"./color.js\";\nimport { extractCssRootColors } from \"./css-vars.js\";\nimport { extractDtcgColors } from \"./dtcg.js\";\nimport { findLogoPair } from \"./logo.js\";\nimport { decodePng, dominantNonNeutralColor } from \"./png.js\";\n// One implementation only. detect.ts previously carried its own copies of these, which\n// drifted from the ones in sources/readme.ts and read a YAML comment as the project name.\nimport { extractH1, extractTagline } from \"../sources/readme.js\";\nimport {\n DEFAULT_BRAND_COLORS,\n DEFAULT_BRAND_FONTS,\n type Brand,\n} from \"./schema.js\";\nimport { extractTailwindV3Colors, extractTailwindV4Colors, type ExtractedColors } from \"./tailwind.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \"coverage\",\n \".shipseal\",\n \".next\",\n \"build\",\n]);\n\nexport interface FieldSource {\n field: string;\n source: string;\n}\n\nexport interface BrandDetection {\n brand: Brand;\n sources: FieldSource[];\n notes: string[];\n}\n\nconst packageSchema = z.object({\n private: z.boolean().optional(),\n name: z.string().optional(),\n description: z.string().optional(),\n homepage: z.string().optional(),\n repository: z.union([z.string(), z.object({ url: z.string().optional() })]).optional(),\n});\n\nexport async function detectBrand(cwd: string): Promise<BrandDetection> {\n const sources: FieldSource[] = [];\n const notes: string[] = [];\n const pkg = await readPackage(cwd);\n const readme = await readMaybe(join(cwd, \"README.md\"));\n\n const name = detectName(pkg, readme, cwd, sources);\n const tagline = detectTagline(pkg, readme, sources);\n const url = await detectUrl(pkg, cwd, sources);\n const logo = findLogoPair(cwd);\n if (logo !== undefined) {\n sources.push({ field: \"logo\", source: logo.light });\n }\n\n const colors = await detectColors(cwd, logo?.light, sources, notes);\n const contrast = ensureForegroundContrast(colors.background, colors.foreground);\n if (contrast.adjusted) {\n colors.foreground = contrast.foreground;\n notes.push(\n `Foreground failed WCAG AA large-text contrast (3:1) against background, so it was set to ${contrast.foreground}.`,\n );\n upsertSource(sources, \"colors.foreground\", \"contrast adjustment\");\n }\n applyReadableMuted(colors, sources, notes);\n applyReadableAccent(colors, sources, notes);\n\n const brand: Brand = {\n version: 1,\n name,\n colors,\n fonts: {\n heading: { ...DEFAULT_BRAND_FONTS.heading },\n body: { ...DEFAULT_BRAND_FONTS.body },\n mono: { ...DEFAULT_BRAND_FONTS.mono },\n },\n radius: 16,\n theme: \"dark\",\n style: \"minimal\",\n tokens: null,\n };\n if (tagline !== undefined) {\n brand.tagline = tagline;\n }\n if (url !== undefined) {\n brand.url = url;\n }\n if (logo !== undefined) {\n brand.logo = logo.dark === undefined ? { light: logo.light } : { light: logo.light, dark: logo.dark };\n }\n sources.push({ field: \"fonts\", source: \"built-in Geist / vendored Geist Mono\" });\n return { brand, sources, notes };\n}\n\nfunction detectName(\n pkg: z.infer<typeof packageSchema> | undefined,\n readme: string | undefined,\n cwd: string,\n sources: FieldSource[],\n): string {\n // A private package.json is a workspace root, and its name is plumbing, not a brand.\n // The shipseal repo's own root is \"shipseal-monorepo\", which is not what to put on a card.\n if (pkg?.name !== undefined && pkg.private !== true) {\n const fromPkg = stripScope(pkg.name);\n const h1 = readme === undefined ? undefined : extractH1(readme);\n if (h1 !== undefined && h1.toLowerCase() === fromPkg.toLowerCase() && h1 !== fromPkg) {\n sources.push({ field: \"name\", source: \"README.md H1\" });\n return h1;\n }\n sources.push({ field: \"name\", source: \"package.json#name\" });\n return fromPkg;\n }\n const h1 = readme === undefined ? undefined : extractH1(readme);\n if (h1 !== undefined) {\n sources.push({ field: \"name\", source: \"README.md H1\" });\n return h1;\n }\n sources.push({ field: \"name\", source: \"directory name\" });\n const fromDir = basename(cwd);\n return fromDir.length > 0 ? fromDir : \"project\";\n}\n\nfunction detectTagline(\n pkg: z.infer<typeof packageSchema> | undefined,\n readme: string | undefined,\n sources: FieldSource[],\n): string | undefined {\n if (pkg?.description !== undefined && pkg.description.trim().length > 0) {\n sources.push({ field: \"tagline\", source: \"package.json#description\" });\n return pkg.description.trim();\n }\n if (readme !== undefined) {\n const tagline = extractTagline(readme);\n if (tagline !== undefined) {\n sources.push({ field: \"tagline\", source: \"README.md first paragraph\" });\n return tagline;\n }\n }\n return undefined;\n}\n\nasync function detectUrl(\n pkg: z.infer<typeof packageSchema> | undefined,\n cwd: string,\n sources: FieldSource[],\n): Promise<string | undefined> {\n if (pkg?.homepage !== undefined && pkg.homepage.length > 0) {\n sources.push({ field: \"url\", source: \"package.json#homepage\" });\n return pkg.homepage;\n }\n const repo = repositoryUrl(pkg?.repository);\n if (repo !== undefined) {\n sources.push({ field: \"url\", source: \"package.json#repository\" });\n return repo;\n }\n const remote = await gitRemote(cwd);\n if (remote !== undefined) {\n sources.push({ field: \"url\", source: \"git remote origin\" });\n return remote;\n }\n return undefined;\n}\n\nasync function detectColors(\n cwd: string,\n logoPath: string | undefined,\n sources: FieldSource[],\n notes: string[],\n): Promise<Brand[\"colors\"]> {\n const merged: ExtractedColors = {};\n const files = await listFiles(cwd, 4);\n\n const cssFiles = files.filter((file) => file.endsWith(\".css\"));\n const cssContents = await Promise.all(\n cssFiles.map(async (file) => ({ file, css: await readMaybe(file) })),\n );\n for (const { file, css } of cssContents) {\n if (css === undefined) {\n continue;\n }\n const fromTheme = extractTailwindV4Colors(css);\n const fromRoot = extractCssRootColors(css);\n const rel = relative(cwd, file);\n applyColors(merged, fromTheme, sources, `Tailwind v4 @theme in ${rel}`);\n applyColors(merged, fromRoot, sources, `:root variables in ${rel}`);\n }\n\n const configFiles = files.filter((file) => basename(file).startsWith(\"tailwind.config.\"));\n const configContents = await Promise.all(\n configFiles.map(async (file) => ({ file, source: await readMaybe(file) })),\n );\n for (const { file, source } of configContents) {\n if (source === undefined) {\n continue;\n }\n applyColors(\n merged,\n extractTailwindV3Colors(source),\n sources,\n `Tailwind config ${relative(cwd, file)}`,\n );\n }\n\n const tokenFile = files.find((file) => file.endsWith(\".tokens.json\"));\n if (tokenFile !== undefined) {\n const raw = await readMaybe(tokenFile);\n if (raw !== undefined) {\n try {\n const parsed: unknown = JSON.parse(raw);\n applyColors(merged, extractDtcgColors(parsed), sources, relative(cwd, tokenFile));\n } catch (error) {\n if (error instanceof SyntaxError) {\n notes.push(`Could not parse design tokens file ${relative(cwd, tokenFile)}.`);\n } else {\n throw error;\n }\n }\n }\n }\n\n if (merged.primary === undefined && logoPath !== undefined) {\n const fromPng = logoPath.endsWith(\".png\") ? await dominantLogoColor(join(cwd, logoPath)) : undefined;\n if (fromPng !== undefined) {\n merged.primary = fromPng;\n sources.push({ field: \"colors.primary\", source: `dominant colour in ${logoPath}` });\n }\n const svg = logoPath.endsWith(\".svg\") ? await readMaybe(join(cwd, logoPath)) : undefined;\n if (svg !== undefined) {\n const fromLogo = firstNonNeutralSvgColor(svg);\n if (fromLogo !== undefined) {\n merged.primary = fromLogo;\n sources.push({ field: \"colors.primary\", source: `SVG fill in ${logoPath}` });\n }\n }\n }\n\n // Say which colours are built-in defaults rather than anything found in this project.\n // Every other detected field prints its source, so staying silent here would let a user\n // read Shipseal's own red as their brand colour.\n const fellBack = ([\"background\", \"foreground\", \"muted\", \"primary\", \"accent\"] as const).filter(\n (field) => merged[field] === undefined,\n );\n if (fellBack.length > 0) {\n notes.push(\n `Using built-in defaults for ${fellBack.map((f) => `colors.${f}`).join(\", \")}. ` +\n \"Nothing in this project set them. Edit .shipseal/brand.json to use your own.\",\n );\n }\n\n return {\n background: merged.background ?? DEFAULT_BRAND_COLORS.background,\n foreground: merged.foreground ?? DEFAULT_BRAND_COLORS.foreground,\n muted: merged.muted ?? DEFAULT_BRAND_COLORS.muted,\n primary: merged.primary ?? DEFAULT_BRAND_COLORS.primary,\n accent: merged.accent ?? DEFAULT_BRAND_COLORS.accent,\n };\n}\n\nfunction applyReadableMuted(\n colors: Brand[\"colors\"],\n sources: FieldSource[],\n notes: string[],\n): void {\n if (colors.muted === undefined || readableOnBackground(colors.background, colors.muted)) {\n return;\n }\n colors.muted = DEFAULT_BRAND_COLORS.muted;\n notes.push(\n `Muted text color failed WCAG AA large-text contrast (3:1) against background, so it was set to ${DEFAULT_BRAND_COLORS.muted}.`,\n );\n upsertSource(sources, \"colors.muted\", \"contrast adjustment\");\n}\n\nfunction applyReadableAccent(\n colors: Brand[\"colors\"],\n sources: FieldSource[],\n notes: string[],\n): void {\n if (colors.accent === undefined || readableOnBackground(colors.background, colors.accent)) {\n return;\n }\n colors.accent = colors.primary ?? DEFAULT_BRAND_COLORS.primary;\n notes.push(\"Accent failed contrast against background, so it uses the primary color.\");\n upsertSource(sources, \"colors.accent\", \"contrast adjustment\");\n}\n\nfunction applyColors(\n target: ExtractedColors,\n incoming: ExtractedColors,\n sources: FieldSource[],\n source: string,\n): void {\n const keys = [\"background\", \"foreground\", \"muted\", \"primary\", \"accent\"] as const;\n for (const key of keys) {\n const value = incoming[key];\n if (value !== undefined && target[key] === undefined) {\n target[key] = value;\n sources.push({ field: `colors.${key}`, source });\n }\n }\n}\n\nfunction upsertSource(sources: FieldSource[], field: string, source: string): void {\n const existing = sources.find((entry) => entry.field === field);\n if (existing !== undefined) {\n existing.source = source;\n return;\n }\n sources.push({ field, source });\n}\n\nasync function readPackage(cwd: string): Promise<z.infer<typeof packageSchema> | undefined> {\n const raw = await readMaybe(join(cwd, \"package.json\"));\n if (raw === undefined) {\n return undefined;\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n const result = packageSchema.safeParse(parsed);\n return result.success ? result.data : undefined;\n } catch (error) {\n if (error instanceof SyntaxError) {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function gitRemote(cwd: string): Promise<string | undefined> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"remote\", \"get-url\", \"origin\"], { cwd });\n return normalizeGitUrl(stdout.trim());\n } catch (error) {\n if (error instanceof Error) {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function listFiles(root: string, maxDepth: number): Promise<string[]> {\n const out: string[] = [];\n const walk = async (dir: string, depth: number): Promise<void> => {\n if (depth < 0) {\n return;\n }\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n const nested: Promise<void>[] = [];\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") && entry.name !== \".github\") {\n continue;\n }\n const path = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name)) {\n continue;\n }\n nested.push(walk(path, depth - 1));\n } else {\n out.push(path);\n }\n }\n await Promise.all(nested);\n };\n await walk(root, maxDepth);\n return out;\n}\n\nasync function readMaybe(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\nfunction stripScope(name: string): string {\n const parts = name.split(\"/\");\n return parts[parts.length - 1] ?? name;\n}\n\n\nfunction repositoryUrl(repository: z.infer<typeof packageSchema>[\"repository\"]): string | undefined {\n if (typeof repository === \"string\") {\n return normalizeGitUrl(repository);\n }\n if (repository?.url !== undefined) {\n return normalizeGitUrl(repository.url);\n }\n return undefined;\n}\n\nfunction normalizeGitUrl(url: string): string {\n const ssh = /^git@([^:]+):(.+)$/.exec(url);\n if (ssh !== null && ssh[1] !== undefined && ssh[2] !== undefined) {\n return `https://${ssh[1]}/${ssh[2].replace(/\\.git$/, \"\")}`;\n }\n return url.replace(/^git\\+/, \"\").replace(/\\.git$/, \"\");\n}\n\n/**\n * Dominant non-neutral colour of a PNG logo, or undefined when the file cannot be read or\n * carries no colour. Detection reports the colour as not found rather than falling back to a\n * built-in default that would be presented to the user as \"your brand\".\n */\nasync function dominantLogoColor(path: string): Promise<string | undefined> {\n let buffer: Buffer;\n try {\n buffer = await readFile(path);\n } catch {\n return undefined;\n }\n const png = decodePng(buffer);\n if (png === undefined) {\n return undefined;\n }\n return dominantNonNeutralColor(png);\n}\n\nfunction firstNonNeutralSvgColor(svg: string): string | undefined {\n const re = /(?:fill|stroke)=\"([^\"]+)\"/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(svg)) !== null) {\n const raw = match[1];\n if (raw === undefined || raw === \"none\" || raw === \"currentColor\") {\n continue;\n }\n const hex = parseCssColor(raw);\n if (hex !== undefined && !isNeutralHex(hex)) {\n return hex;\n }\n }\n return undefined;\n}\n","// init: detect brand, write .shipseal/brand.json + config.json, render sample\n// Spec: docs/PROJECT_PLAN.md §18.1\n\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport { join } from \"node:path\";\nimport { detectBrand, type BrandDetection } from \"../brand/detect.js\";\nimport { brandSchema } from \"../brand/schema.js\";\nimport { DEFAULT_CONFIG, configSchema } from \"../config/schema.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { FORMATS } from \"../formats.js\";\nimport { createTakumiRenderer, testCardNode } from \"../render/takumi.js\";\n\nexport interface InitOptions {\n cwd: string;\n yes: boolean;\n force: boolean;\n}\n\nexport interface InitResult {\n brandPath: string;\n configPath: string;\n samplePath: string;\n detection: BrandDetection;\n}\n\nexport async function runInit(options: InitOptions): Promise<InitResult> {\n const detection = await detectBrand(options.cwd);\n const brandDir = join(options.cwd, \".shipseal\");\n const brandPath = join(brandDir, \"brand.json\");\n const configPath = join(brandDir, \"config.json\");\n\n if (!options.force && (existsSync(brandPath) || existsSync(configPath))) {\n throw new ShipsealError(\n \"init.exists\",\n \".shipseal/brand.json or config.json already exists.\",\n \"Re-run with --force to overwrite, or edit the files by hand.\",\n );\n }\n\n if (!options.yes) {\n const accepted = await confirmInit(detection);\n if (!accepted) {\n throw new ShipsealError(\n \"init.cancelled\",\n \"Init cancelled; no files were written.\",\n \"Re-run shipseal init and confirm, or pass --yes to accept detections.\",\n );\n }\n }\n\n const brand = brandSchema.parse(detection.brand);\n const config = configSchema.parse(DEFAULT_CONFIG);\n await mkdir(brandDir, { recursive: true });\n await writeFile(brandPath, `${JSON.stringify(brand, null, 2)}\\n`, \"utf8\");\n await writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf8\");\n await ensureGitignore(options.cwd);\n\n const sampleDir = join(brandDir, \"output\", \"sample\");\n await mkdir(sampleDir, { recursive: true });\n const samplePath = join(sampleDir, \"release-hero-og.png\");\n const renderer = await createTakumiRenderer();\n const png = await renderer.render(testCardNode(), {\n width: FORMATS.og.width,\n height: FORMATS.og.height,\n format: \"png\",\n });\n await writeFile(samplePath, png);\n\n return { brandPath, configPath, samplePath, detection };\n}\n\nasync function confirmInit(detection: BrandDetection): Promise<boolean> {\n if (!input.isTTY) {\n throw new ShipsealError(\n \"init.unattended\",\n \"stdin is not a TTY, so init cannot ask for confirmation.\",\n \"Re-run with --yes to accept the detected brand and write files.\",\n );\n }\n output.write(\"Detected brand:\\n\");\n for (const field of detection.sources) {\n output.write(` ${field.field}: from ${field.source}\\n`);\n }\n for (const note of detection.notes) {\n output.write(` note: ${note}\\n`);\n }\n const rl = createInterface({ input, output });\n try {\n const answer = await rl.question(\"Write .shipseal/brand.json and config.json? [y/N] \");\n return answer.trim().toLowerCase() === \"y\" || answer.trim().toLowerCase() === \"yes\";\n } finally {\n rl.close();\n }\n}\n\nasync function ensureGitignore(cwd: string): Promise<void> {\n const path = join(cwd, \".gitignore\");\n const entry = \".shipseal/output/\";\n if (!existsSync(path)) {\n await writeFile(path, `${entry}\\n`, \"utf8\");\n return;\n }\n const current = await readFile(path, \"utf8\");\n if (current.split(/\\r?\\n/).some((line) => line.trim() === entry || line.trim() === \".shipseal/output\")) {\n return;\n }\n const prefix = current.endsWith(\"\\n\") || current.length === 0 ? \"\" : \"\\n\";\n await writeFile(path, `${current}${prefix}${entry}\\n`, \"utf8\");\n}\n","// milestone: card for highest crossed threshold\n// Spec: docs/PROJECT_PLAN.md §18.3\n\nimport { loadBrand } from \"../brand/load.js\";\nimport { loadConfig } from \"../config/load.js\";\nimport type { Config } from \"../config/schema.js\";\nimport { milestoneCopy } from \"../copy/deterministic.js\";\nimport { generate } from \"../core/generate.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { createTakumiRenderer } from \"../render/takumi.js\";\nimport { collectFacts } from \"../sources/collect.js\";\nimport {\n collectEnv,\n finishPack,\n loadLogos,\n overlayFormats,\n resolveCopy,\n resolveThemes,\n type SharedFlags,\n} from \"./shared.js\";\n\nexport type MilestoneMetric = \"stars\" | \"downloads\" | \"contributors\";\n\nexport interface MilestoneFlags extends SharedFlags {\n metric?: string;\n threshold?: string;\n}\n\nexport interface MilestoneResult {\n dryRun: boolean;\n skipped: boolean;\n message?: string;\n facts: Facts;\n copy?: import(\"../copy/slots.js\").Copy;\n copyMode?: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir?: string;\n manifest?: import(\"../outputs/manifest.js\").Manifest;\n warnings: import(\"../core/generate.js\").GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n}\n\nexport async function runMilestone(flags: MilestoneFlags): Promise<MilestoneResult> {\n const cwd = flags.cwd;\n const config = overlayFormats(await loadConfig(cwd), flags);\n const brand = await loadBrand(cwd);\n const placeholder: ShipsealEvent = { kind: \"milestone\", metric: \"stars\", threshold: 0 };\n const env = collectEnv(flags);\n const collectOpts: Parameters<typeof collectFacts>[0] = {\n cwd,\n event: placeholder,\n skipNetwork: env.skipNetwork,\n };\n if (env.packagePath !== undefined) {\n collectOpts.packagePath = env.packagePath;\n }\n if (env.githubToken !== undefined) {\n collectOpts.githubToken = env.githubToken;\n }\n if (env.fetchImpl !== undefined) {\n collectOpts.fetchImpl = env.fetchImpl;\n }\n const collected = await collectFacts(collectOpts);\n const selected = selectMilestone(collected, config, parseMetric(flags.metric), parseThreshold(flags.threshold));\n if (selected === undefined) {\n return {\n dryRun: flags.dryRun === true,\n skipped: true,\n message: \"No milestone threshold crossed. Nothing to generate.\",\n facts: collected,\n warnings: [],\n exitCode: 0,\n };\n }\n\n const fetchedAt = new Date().toISOString();\n const metricKey = selected.metric === \"downloads\" ? \"downloads\" : selected.metric;\n const facts: Facts = {\n ...collected,\n milestone: {\n metric: fact(selected.metric, { source: \"user-config\", ref: \"shipseal milestone --metric\", fetchedAt }),\n threshold: fact(selected.threshold, {\n source: \"user-config\",\n ref: `config.json milestones.${metricKey}`,\n fetchedAt,\n }),\n },\n };\n const event: ShipsealEvent = { kind: \"milestone\", metric: selected.metric, threshold: selected.threshold };\n const fallback = milestoneCopy(facts, selected.metric, selected.threshold);\n const resolved = await resolveCopy(facts, config, flags.copy === false, fallback);\n\n if (flags.dryRun === true) {\n const dry: MilestoneResult = {\n dryRun: true,\n skipped: false,\n facts,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n warnings: [],\n exitCode: 0,\n };\n if (resolved.warning !== undefined) {\n dry.copyWarning = resolved.warning;\n }\n return dry;\n }\n\n const renderer = await createTakumiRenderer();\n const generateInput: Parameters<typeof generate>[0] = {\n event,\n facts,\n brand,\n config,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n renderer,\n themes: resolveThemes(flags.themes, brand.theme),\n generatedAt: new Date().toISOString(),\n };\n const logos = await loadLogos(cwd, brand);\n if (logos !== undefined) {\n generateInput.logos = logos;\n }\n const result = await generate(generateInput);\n const packInput: Parameters<typeof finishPack>[0] = {\n flags,\n config,\n event,\n result,\n brand,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n facts,\n };\n if (resolved.warning !== undefined) {\n packInput.copyWarning = resolved.warning;\n }\n const packed = await finishPack(packInput);\n return { ...packed, skipped: false };\n}\n\nexport function highestCrossed(thresholds: number[], current: number): number | undefined {\n const crossed = thresholds.filter((item) => current >= item).toSorted((a, b) => b - a);\n return crossed[0];\n}\n\nexport function selectMilestone(\n facts: Facts,\n config: Config,\n metric: MilestoneMetric | undefined,\n threshold: number | undefined,\n): { metric: MilestoneMetric; threshold: number } | undefined {\n const metrics: MilestoneMetric[] = metric === undefined ? [\"stars\", \"downloads\", \"contributors\"] : [metric];\n const candidates: Array<{ metric: MilestoneMetric; threshold: number }> = [];\n for (const item of metrics) {\n const current = currentValue(facts, item);\n if (current === undefined) {\n if (metric !== undefined) {\n throw missingMetric(item);\n }\n continue;\n }\n const list = thresholdsFor(config, item);\n if (threshold !== undefined) {\n if (metric !== undefined || list.includes(threshold)) {\n return { metric: item, threshold };\n }\n continue;\n }\n const crossed = highestCrossed(list, current);\n if (crossed !== undefined) {\n candidates.push({ metric: item, threshold: crossed });\n }\n }\n return candidates.toSorted(\n (a, b) => b.threshold - a.threshold || metrics.indexOf(a.metric) - metrics.indexOf(b.metric),\n )[0];\n}\n\nfunction currentValue(facts: Facts, metric: MilestoneMetric): number | undefined {\n if (metric === \"stars\") {\n return facts.metrics?.stars?.value;\n }\n if (metric === \"downloads\") {\n return facts.metrics?.weeklyDownloads?.value;\n }\n return facts.metrics?.contributorCount?.value;\n}\n\nfunction thresholdsFor(config: Config, metric: MilestoneMetric): number[] {\n if (metric === \"stars\") {\n return config.milestones?.stars ?? [];\n }\n if (metric === \"downloads\") {\n return config.milestones?.downloads ?? [];\n }\n return config.milestones?.contributors ?? [];\n}\n\nfunction parseMetric(value: string | undefined): MilestoneMetric | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === \"stars\" || value === \"downloads\" || value === \"contributors\") {\n return value;\n }\n throw new ShipsealError(\n \"milestone.bad-metric\",\n `Unknown metric \"${value}\".`,\n \"Use --metric stars, --metric downloads, or --metric contributors.\",\n );\n}\n\nfunction parseThreshold(value: string | undefined): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n const parsed = Number.parseInt(value, 10);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new ShipsealError(\n \"milestone.bad-threshold\",\n `Invalid threshold \"${value}\".`,\n \"Pass a positive integer, for example --threshold 1000.\",\n );\n }\n return parsed;\n}\n\nfunction missingMetric(metric: MilestoneMetric): ShipsealError {\n if (metric === \"stars\") {\n return new ShipsealError(\n \"milestone.missing-stars\",\n \"Could not read GitHub stars for this repo.\",\n \"Set GITHUB_TOKEN, or confirm package.json repository points at a public GitHub repo.\",\n );\n }\n if (metric === \"downloads\") {\n return new ShipsealError(\n \"milestone.missing-downloads\",\n \"Could not read npm weekly downloads for this package.\",\n \"Confirm package.json name is published on npm, then retry without --dry-run.\",\n );\n }\n return new ShipsealError(\n \"milestone.missing-contributors\",\n \"Could not read the GitHub contributor count for this repo.\",\n \"Set GITHUB_TOKEN, or confirm package.json repository points at a public GitHub repo.\",\n );\n}\n","// release: generate the release pack\n// Spec: docs/PROJECT_PLAN.md §18.2\n\nimport { loadBrand } from \"../brand/load.js\";\nimport { loadConfig, mergeConfig } from \"../config/load.js\";\nimport { DEFAULT_CONFIG, type Config } from \"../config/schema.js\";\nimport { deterministicCopy } from \"../copy/deterministic.js\";\nimport { generate } from \"../core/generate.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { createTakumiRenderer } from \"../render/takumi.js\";\nimport { collectFacts } from \"../sources/collect.js\";\nimport { gitCurrentTag } from \"../sources/git.js\";\nimport {\n collectEnv,\n finishPack,\n loadLogos,\n overlayFormats,\n resolveCopy,\n resolveThemes,\n type SharedFlags,\n} from \"./shared.js\";\n\nexport interface ReleaseFlags extends SharedFlags {\n tag?: string;\n from?: string;\n templates?: string;\n}\n\nexport interface ReleaseResult {\n dryRun: boolean;\n facts: Awaited<ReturnType<typeof collectFacts>>;\n copy: import(\"../copy/slots.js\").Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir?: string;\n manifest?: import(\"../outputs/manifest.js\").Manifest;\n warnings: import(\"../core/generate.js\").GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n}\n\nexport async function runRelease(flags: ReleaseFlags): Promise<ReleaseResult> {\n const cwd = flags.cwd;\n const config = overlayReleaseConfig(await loadConfig(cwd), flags);\n const brand = await loadBrand(cwd);\n const tag = flags.tag ?? (await gitCurrentTag(cwd));\n if (tag === undefined) {\n throw new ShipsealError(\n \"release.no-tag\",\n \"No git tag found for this release.\",\n \"Create a git tag, or pass --tag vX.Y.Z.\",\n );\n }\n const event: ShipsealEvent =\n flags.from === undefined\n ? { kind: \"release\", tag }\n : { kind: \"release\", tag, previousTag: flags.from };\n\n const env = collectEnv(flags);\n const collectOpts: Parameters<typeof collectFacts>[0] = {\n cwd,\n event,\n skipNetwork: env.skipNetwork,\n };\n if (env.packagePath !== undefined) {\n collectOpts.packagePath = env.packagePath;\n }\n if (config.release?.changelogPath !== undefined) {\n collectOpts.changelogPath = config.release.changelogPath;\n }\n if (config.release?.snippet !== undefined) {\n collectOpts.snippet = config.release.snippet;\n }\n if (env.githubToken !== undefined) {\n collectOpts.githubToken = env.githubToken;\n }\n if (env.fetchImpl !== undefined) {\n collectOpts.fetchImpl = env.fetchImpl;\n }\n const facts = await collectFacts(collectOpts);\n\n const noCopy = flags.copy === false;\n const resolved = await resolveCopy(facts, config, noCopy, deterministicCopy(facts, config.release?.maxHighlights));\n\n if (flags.dryRun === true) {\n const dry: ReleaseResult = {\n dryRun: true,\n facts,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n warnings: [],\n exitCode: 0,\n };\n if (resolved.warning !== undefined) {\n dry.copyWarning = resolved.warning;\n }\n return dry;\n }\n\n const renderer = await createTakumiRenderer();\n const generateInput: Parameters<typeof generate>[0] = {\n event,\n facts,\n brand,\n config,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n renderer,\n themes: resolveThemes(flags.themes, brand.theme),\n generatedAt: new Date().toISOString(),\n };\n const logos = await loadLogos(cwd, brand);\n if (logos !== undefined) {\n generateInput.logos = logos;\n }\n const result = await generate(generateInput);\n const packInput: Parameters<typeof finishPack>[0] = {\n flags,\n config,\n event,\n result,\n brand,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n facts,\n };\n if (resolved.warning !== undefined) {\n packInput.copyWarning = resolved.warning;\n }\n return finishPack(packInput);\n}\n\nfunction overlayReleaseConfig(config: Config, flags: ReleaseFlags): Config {\n const overlay = overlayFormats(config, flags);\n if (flags.templates === undefined) {\n return overlay;\n }\n return mergeConfig(DEFAULT_CONFIG, {\n ...overlay,\n release: {\n ...overlay.release,\n templates: flags.templates\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0),\n },\n });\n}\n","#!/usr/bin/env node\n// CLI entry: parse args, dispatch to commands/*\n// Spec: docs/PROJECT_PLAN.md §18\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { cac } from \"cac\";\nimport { runBench, type BenchFlags } from \"./commands/bench.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runMilestone, type MilestoneFlags } from \"./commands/milestone.js\";\nimport { runRelease, type ReleaseFlags } from \"./commands/release.js\";\nimport { ShipsealError, formatError } from \"./core/errors.js\";\nimport { resolvePackageRoot } from \"./render/takumi.js\";\n\nexport async function runCli(argv = process.argv): Promise<number> {\n process.exitCode = 0;\n const cli = cac(\"shipseal\");\n cli.option(\"--cwd <path>\", \"Working directory\", { default: process.cwd() });\n cli.option(\"--json\", \"Machine-readable JSON output\");\n cli.option(\"--quiet\", \"Suppress non-error output\");\n cli.option(\"--verbose\", \"Verbose output\");\n\n cli\n .command(\"init\", \"Detect brand and write .shipseal/brand.json + config.json\")\n .option(\"--yes\", \"Accept detections without prompting\")\n .option(\"--force\", \"Overwrite existing brand.json and config.json\")\n .action(async (flags: Record<string, unknown>) => {\n const result = await runInit({\n cwd: stringFlag(flags.cwd, process.cwd()),\n yes: flags.yes === true,\n force: flags.force === true,\n });\n if (flags.json === true) {\n process.stdout.write(`${JSON.stringify(result.detection.brand, null, 2)}\\n`);\n return;\n }\n if (flags.quiet !== true) {\n process.stdout.write(`Wrote ${result.brandPath}\\n`);\n process.stdout.write(`Wrote ${result.configPath}\\n`);\n process.stdout.write(`Sample card: ${result.samplePath}\\n`);\n for (const field of result.detection.sources) {\n process.stdout.write(` ${field.field}: ${field.source}\\n`);\n }\n // Notes carry the \"this is a built-in default, not your brand\" disclosures.\n // The interactive prompt already shows them, and --yes skips that prompt, so\n // without this the user never learns which colours were not detected.\n for (const note of result.detection.notes) {\n process.stdout.write(` note: ${note}\\n`);\n }\n }\n });\n\n cli.command(\"doctor\", \"Check Node, git, brand, fonts, and Takumi\").action(async (flags: Record<string, unknown>) => {\n const result = await runDoctor(stringFlag(flags.cwd, process.cwd()));\n if (flags.json === true) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else if (flags.quiet !== true) {\n for (const check of result.checks) {\n const mark = check.status === \"pass\" ? \"ok\" : check.status === \"fail\" ? \"FAIL\" : \"info\";\n process.stdout.write(`[${mark}] ${check.name}: ${check.message}\\n`);\n if (check.fix !== undefined && check.status === \"fail\") {\n process.stdout.write(` Fix: ${check.fix}\\n`);\n }\n }\n }\n if (!result.ok) {\n process.exitCode = 1;\n }\n });\n\n cli\n .command(\"release\", \"Generate the release pack\")\n .option(\"--tag <tag>\", \"Release tag\")\n .option(\"--from <tag>\", \"Previous tag\")\n .option(\"--formats <list>\", \"Comma-separated formats\")\n .option(\"--templates <list>\", \"Comma-separated templates\")\n .option(\"--themes <dark|light|both>\", \"Themes to render\")\n .option(\"--copy\", \"Allow optional LLM copy (default: on when config.copy.llm is true)\")\n .option(\"--out <dir>\", \"Output directory\")\n .option(\"--strict\", \"Fit warnings exit with code 2\")\n .option(\"--dry-run\", \"Collect facts and print them; render nothing\")\n .option(\"--package <path>\", \"package.json path for monorepos\")\n .option(\"--upload\", \"Upload PNG files to the GitHub release\")\n .action(async (flags: Record<string, unknown>) => {\n const releaseFlags: ReleaseFlags = {\n cwd: stringFlag(flags.cwd, process.cwd()),\n strict: flags.strict === true,\n dryRun: flags.dryRun === true,\n };\n applySharedFlags(releaseFlags, flags);\n const tag = optionalString(flags.tag);\n if (tag !== undefined) {\n releaseFlags.tag = tag;\n }\n const from = optionalString(flags.from);\n if (from !== undefined) {\n releaseFlags.from = from;\n }\n const templates = optionalString(flags.templates);\n if (templates !== undefined) {\n releaseFlags.templates = templates;\n }\n const result = await runRelease(releaseFlags);\n process.exitCode = result.exitCode;\n writeCommandOutput(flags, result);\n });\n\n cli\n .command(\"milestone\", \"Generate a milestone card for the highest crossed threshold\")\n .option(\"--metric <stars|downloads|contributors>\", \"Metric to check\")\n .option(\"--threshold <n>\", \"Force a specific threshold\")\n .option(\"--formats <list>\", \"Comma-separated formats\")\n .option(\"--themes <dark|light|both>\", \"Themes to render\")\n .option(\"--copy\", \"Allow optional LLM copy (default: on when config.copy.llm is true)\")\n .option(\"--out <dir>\", \"Output directory\")\n .option(\"--strict\", \"Fit warnings exit with code 2\")\n .option(\"--dry-run\", \"Collect facts and print them; render nothing\")\n .option(\"--package <path>\", \"package.json path for monorepos\")\n .action(async (flags: Record<string, unknown>) => {\n const milestoneFlags: MilestoneFlags = {\n cwd: stringFlag(flags.cwd, process.cwd()),\n strict: flags.strict === true,\n dryRun: flags.dryRun === true,\n };\n applySharedFlags(milestoneFlags, flags);\n const metric = optionalString(flags.metric);\n if (metric !== undefined) {\n milestoneFlags.metric = metric;\n }\n const threshold = optionalString(flags.threshold);\n if (threshold !== undefined) {\n milestoneFlags.threshold = threshold;\n }\n const result = await runMilestone(milestoneFlags);\n process.exitCode = result.exitCode;\n if (flags.json === true) {\n writeJson(resultToJson(result));\n return;\n }\n if (flags.quiet === true) {\n return;\n }\n if (result.skipped) {\n process.stdout.write(`${result.message ?? \"No milestone threshold crossed.\"}\\n`);\n return;\n }\n writeHumanResult(result);\n });\n\n cli\n .command(\"bench\", \"Generate benchmark cards from bench JSON\")\n .option(\"--file <path>\", \"Path to bench JSON\")\n .option(\"--formats <list>\", \"Comma-separated formats\")\n .option(\"--themes <dark|light|both>\", \"Themes to render\")\n .option(\"--copy\", \"Allow optional LLM copy (default: on when config.copy.llm is true)\")\n .option(\"--out <dir>\", \"Output directory\")\n .option(\"--strict\", \"Fit warnings exit with code 2\")\n .option(\"--dry-run\", \"Collect facts and print them; render nothing\")\n .option(\"--package <path>\", \"package.json path for monorepos\")\n .action(async (flags: Record<string, unknown>) => {\n const benchFlags: BenchFlags = {\n cwd: stringFlag(flags.cwd, process.cwd()),\n strict: flags.strict === true,\n dryRun: flags.dryRun === true,\n };\n applySharedFlags(benchFlags, flags);\n const file = optionalString(flags.file);\n if (file !== undefined) {\n benchFlags.file = file;\n }\n const result = await runBench(benchFlags);\n process.exitCode = result.exitCode;\n writeCommandOutput(flags, result);\n });\n\n cli.help();\n cli.version(readVersion());\n\n try {\n cli.parse(argv, { run: false });\n await cli.runMatchedCommand();\n return typeof process.exitCode === \"number\" ? process.exitCode : 0;\n } catch (error) {\n if (error instanceof ShipsealError) {\n process.stderr.write(`${formatError(error)}\\n`);\n return 1;\n }\n if (error instanceof Error) {\n process.stderr.write(`${error.message}\\n`);\n return 1;\n }\n throw error;\n }\n}\n\nfunction stringFlag(value: unknown, fallback: string): string {\n return typeof value === \"string\" && value.length > 0 ? value : fallback;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction applySharedFlags(target: { formats?: string; themes?: string; copy?: boolean; out?: string; package?: string; upload?: boolean }, flags: Record<string, unknown>): void {\n const formats = optionalString(flags.formats);\n if (formats !== undefined) {\n target.formats = formats;\n }\n const themes = optionalString(flags.themes);\n if (themes !== undefined) {\n target.themes = themes;\n }\n if (flags.copy === false) {\n target.copy = false;\n }\n const out = optionalString(flags.out);\n if (out !== undefined) {\n target.out = out;\n }\n const pkg = optionalString(flags.package);\n if (pkg !== undefined) {\n target.package = pkg;\n }\n if (flags.upload === true) {\n target.upload = true;\n }\n}\n\nfunction writeCommandOutput(\n flags: Record<string, unknown>,\n result: {\n dryRun: boolean;\n facts: unknown;\n dir?: string;\n manifest?: unknown;\n copyWarning?: string;\n warnings: Array<{ template: string; format: string; slot: string; action: string }>;\n skipped?: boolean;\n message?: string;\n },\n): void {\n if (flags.json === true) {\n writeJson(resultToJson(result));\n return;\n }\n if (flags.quiet === true) {\n return;\n }\n writeHumanResult(result);\n}\n\nfunction resultToJson(result: {\n dryRun: boolean;\n facts: unknown;\n dir?: string;\n manifest?: unknown;\n skipped?: boolean;\n message?: string;\n}): Record<string, unknown> {\n const payload: Record<string, unknown> = {};\n if (result.skipped === true) {\n payload.skipped = true;\n }\n if (result.message !== undefined) {\n payload.message = result.message;\n }\n if (result.dir !== undefined) {\n payload.dir = result.dir;\n }\n if (result.manifest !== undefined) {\n payload.manifest = result.manifest;\n } else {\n payload.facts = result.facts;\n }\n return payload;\n}\n\nfunction writeHumanResult(result: {\n dryRun: boolean;\n facts: unknown;\n dir?: string;\n copyWarning?: string;\n warnings: Array<{ template: string; format: string; slot: string; action: string }>;\n skipped?: boolean;\n message?: string;\n}): void {\n if (result.skipped === true) {\n process.stdout.write(`${result.message ?? \"Nothing to generate.\"}\\n`);\n return;\n }\n if (result.dryRun) {\n process.stdout.write(`${JSON.stringify(result.facts, null, 2)}\\n`);\n return;\n }\n if (result.dir !== undefined) {\n process.stdout.write(`Wrote ${result.dir}\\n`);\n }\n if (result.copyWarning !== undefined) {\n process.stdout.write(`Copy: ${result.copyWarning}\\n`);\n }\n for (const warning of result.warnings) {\n process.stdout.write(`Warning: ${warning.template} ${warning.format} ${warning.slot} ${warning.action}\\n`);\n }\n}\n\nfunction writeJson(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction readVersion(): string {\n const raw: unknown = JSON.parse(readFileSync(join(resolvePackageRoot(), \"package.json\"), \"utf8\"));\n if (typeof raw === \"object\" && raw !== null && \"version\" in raw && typeof raw.version === \"string\") {\n return raw.version;\n }\n return \"0.0.0\";\n}\n\nif (shouldRun(process.argv[1])) {\n void runCli().then((code) => {\n process.exit(code);\n });\n}\n\nfunction shouldRun(invoked: string | undefined): boolean {\n if (invoked === undefined) {\n return false;\n }\n const normalized = invoked.replaceAll(\"\\\\\", \"/\");\n return (\n normalized.endsWith(\"/cli.js\") ||\n normalized.endsWith(\"/cli.ts\") ||\n normalized.endsWith(\"/shipseal\")\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["formatCount","measureOpts","propsSchema","propsSchema","propsSchema","formatCount","propsSchema","execFileAsync","API_ROOT","stripScope","repositoryUrl","normalizeGitUrl","textNode","takumiFromJsx","execFileAsync","execFileAsync","matchingBrace","input"],"sources":["../src/core/errors.ts","../src/brand/schema.ts","../src/brand/load.ts","../src/formats.ts","../src/config/schema.ts","../src/config/load.ts","../src/copy/slots.ts","../src/copy/deterministic.ts","../src/bench/percent.ts","../src/fit/fit-text.ts","../src/templates/theme.ts","../src/takumi-jsx/jsx-runtime.ts","../src/templates/code-card.tsx","../src/templates/highlight.ts","../src/templates/bench.tsx","../src/templates/milestone.tsx","../src/templates/release-hero.tsx","../src/templates/release-highlights.tsx","../src/templates/registry.ts","../src/core/generate.ts","../src/facts/merge.ts","../src/facts/fact.ts","../src/sources/bench-file.ts","../src/sources/changelog.ts","../src/sources/git.ts","../src/sources/github.ts","../src/sources/npm.ts","../src/sources/package-json.ts","../src/sources/readme.ts","../src/sources/collect.ts","../src/render/takumi.ts","../src/copy/number-guard.ts","../src/copy/llm.ts","../src/outputs/manifest.ts","../src/outputs/files.ts","../src/outputs/github-release.ts","../src/commands/shared.ts","../src/commands/bench.ts","../src/commands/doctor.ts","../src/brand/color.ts","../src/brand/css-vars.ts","../src/brand/dtcg.ts","../src/brand/logo.ts","../src/brand/png.ts","../src/brand/tailwind.ts","../src/brand/detect.ts","../src/commands/init.ts","../src/commands/milestone.ts","../src/commands/release.ts","../src/cli.ts"],"sourcesContent":["// Typed errors: what went wrong, why, how to fix\n// Spec: docs/PROJECT_PLAN.md §0.3\n\nexport class ShipsealError extends Error {\n readonly code: string;\n readonly fix: string;\n\n constructor(code: string, message: string, fix: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"ShipsealError\";\n this.code = code;\n this.fix = fix;\n }\n}\n\nexport function formatError(error: ShipsealError): string {\n return `${error.message}\\nFix: ${error.fix}`;\n}\n","// brand.json zod schema\n// Spec: docs/PROJECT_PLAN.md §10.2\n\nimport { z } from \"zod\";\n\nexport const hexColorSchema = z\n .string()\n .regex(/^#([\\da-f]{6})$/i, \"Expected a 6-digit hex color like #0b0b0c\");\n\nexport const fontFaceSchema = z.object({\n family: z.string().min(1),\n weight: z.number().int().min(100).max(900),\n file: z.string().min(1).optional(),\n});\n\nexport const brandSchema = z.object({\n $schema: z.string().optional(),\n version: z.literal(1),\n name: z.string().min(1),\n tagline: z.string().optional(),\n url: z.string().optional(),\n logo: z\n .object({\n light: z.string().min(1),\n dark: z.string().min(1).optional(),\n })\n .optional(),\n colors: z.object({\n background: hexColorSchema,\n foreground: hexColorSchema,\n muted: hexColorSchema.optional(),\n primary: hexColorSchema.optional(),\n accent: hexColorSchema.optional(),\n }),\n fonts: z.object({\n heading: fontFaceSchema,\n body: fontFaceSchema,\n mono: fontFaceSchema,\n }),\n radius: z.number().nonnegative(),\n theme: z.enum([\"dark\", \"light\"]),\n style: z.literal(\"minimal\"),\n tokens: z.string().nullable(),\n});\n\nexport type Brand = z.infer<typeof brandSchema>;\n\nexport const DEFAULT_BRAND_COLORS = {\n background: \"#0b0b0c\",\n foreground: \"#fafafa\",\n muted: \"#a1a1aa\",\n primary: \"#ff4d4d\",\n accent: \"#fbbf24\",\n} as const;\n\nexport const DEFAULT_BRAND_FONTS = {\n heading: { family: \"Geist\", weight: 700 },\n body: { family: \"Geist\", weight: 400 },\n mono: { family: \"Geist Mono\", weight: 400 },\n} as const;\n","// Load .shipseal/brand.json\n// Spec: docs/PROJECT_PLAN.md §10.1\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { brandSchema, type Brand } from \"./schema.js\";\n\nexport async function loadBrand(cwd: string): Promise<Brand> {\n const path = join(cwd, \".shipseal\", \"brand.json\");\n try {\n const raw: unknown = JSON.parse(await readFile(path, \"utf8\"));\n return brandSchema.parse(raw);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n throw new ShipsealError(\n \"brand.missing\",\n \"No .shipseal/brand.json found.\",\n \"Run shipseal init to detect brand colors and write brand.json.\",\n );\n }\n throw error;\n }\n}\n","// Single table of platform sizes\n// Spec: docs/PROJECT_PLAN.md §14.2\n\nexport const FORMAT_IDS = [\n \"og\",\n \"github-social\",\n \"x\",\n \"linkedin\",\n \"square\",\n \"portrait\",\n \"producthunt\",\n \"readme-banner\",\n] as const;\n\nexport type FormatId = (typeof FORMAT_IDS)[number];\n\nexport interface Format {\n id: FormatId;\n width: number;\n height: number;\n /** Minimum inset for critical text on landscape formats, in px. */\n safeZone: number;\n}\n\nconst LANDSCAPE_SAFE_ZONE = 64;\n\nexport const FORMATS: Record<FormatId, Format> = {\n og: { id: \"og\", width: 1200, height: 630, safeZone: LANDSCAPE_SAFE_ZONE },\n \"github-social\": {\n id: \"github-social\",\n width: 1280,\n height: 640,\n safeZone: LANDSCAPE_SAFE_ZONE,\n },\n x: { id: \"x\", width: 1200, height: 675, safeZone: LANDSCAPE_SAFE_ZONE },\n linkedin: { id: \"linkedin\", width: 1200, height: 627, safeZone: LANDSCAPE_SAFE_ZONE },\n square: { id: \"square\", width: 1080, height: 1080, safeZone: LANDSCAPE_SAFE_ZONE },\n portrait: { id: \"portrait\", width: 1080, height: 1350, safeZone: LANDSCAPE_SAFE_ZONE },\n producthunt: {\n id: \"producthunt\",\n width: 1270,\n height: 760,\n safeZone: LANDSCAPE_SAFE_ZONE,\n },\n \"readme-banner\": {\n id: \"readme-banner\",\n width: 1280,\n height: 400,\n safeZone: LANDSCAPE_SAFE_ZONE,\n },\n};\n\nexport const V1_FORMAT_IDS = [\"og\", \"github-social\", \"x\", \"linkedin\"] as const satisfies readonly FormatId[];\n","// config.json zod schema\n// Spec: docs/PROJECT_PLAN.md §11\n\nimport { z } from \"zod\";\nimport { FORMAT_IDS } from \"../formats.js\";\n\nexport const configSchema = z.object({\n $schema: z.string().optional(),\n version: z.literal(1),\n outputDir: z.string().optional(),\n formats: z.array(z.enum(FORMAT_IDS)).optional(),\n release: z\n .object({\n templates: z.array(z.string()).optional(),\n maxHighlights: z.number().int().positive().optional(),\n changelogPath: z.string().optional(),\n snippet: z.string().nullable().optional(),\n })\n .optional(),\n milestones: z\n .object({\n stars: z.array(z.number().int().positive()).optional(),\n downloads: z.array(z.number().int().positive()).optional(),\n contributors: z.array(z.number().int().positive()).optional(),\n })\n .optional(),\n bench: z\n .object({\n file: z.string().optional(),\n })\n .optional(),\n copy: z\n .object({\n llm: z.boolean().optional(),\n provider: z.string().nullable().optional(),\n model: z.string().nullable().optional(),\n maxRetries: z.number().int().nonnegative().optional(),\n })\n .optional(),\n output: z\n .object({\n imageFormat: z.enum([\"png\", \"webp\", \"jpeg\"]).optional(),\n })\n .optional(),\n attribution: z.boolean().optional(),\n});\n\nexport type Config = z.infer<typeof configSchema>;\n\nexport const DEFAULT_CONFIG: Config = {\n version: 1,\n outputDir: \".shipseal/output\",\n formats: [\"og\", \"github-social\", \"x\", \"linkedin\"],\n release: {\n templates: [\"release-hero\", \"release-highlights\", \"code-card\"],\n maxHighlights: 4,\n changelogPath: \"CHANGELOG.md\",\n snippet: null,\n },\n milestones: {\n stars: [100, 250, 500, 1000, 2500, 5000, 10000],\n downloads: [1000, 10000, 100000, 1000000],\n contributors: [10, 25, 50, 100],\n },\n bench: {\n file: \".shipseal/bench.json\",\n },\n copy: {\n llm: false,\n provider: null,\n model: null,\n maxRetries: 2,\n },\n output: {\n imageFormat: \"png\",\n },\n attribution: true,\n};\n","// Load and merge config (flags > file > defaults)\n// Spec: docs/PROJECT_PLAN.md §11\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { DEFAULT_CONFIG, configSchema, type Config } from \"./schema.js\";\n\nexport async function loadConfig(cwd: string): Promise<Config> {\n const path = join(cwd, \".shipseal\", \"config.json\");\n try {\n const raw: unknown = JSON.parse(await readFile(path, \"utf8\"));\n const parsed = configSchema.parse(raw);\n return mergeConfig(DEFAULT_CONFIG, parsed);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return DEFAULT_CONFIG;\n }\n throw error;\n }\n}\n\nexport function mergeConfig(base: Config, overlay: Config): Config {\n return {\n ...base,\n ...overlay,\n release: { ...base.release, ...overlay.release },\n milestones: { ...base.milestones, ...overlay.milestones },\n bench: { ...base.bench, ...overlay.bench },\n copy: { ...base.copy, ...overlay.copy },\n output: { ...base.output, ...overlay.output },\n };\n}\n","// Copy slots filled by the copy layer\n// Spec: docs/PROJECT_PLAN.md §13.1\n\nexport const COPY_LIMITS = {\n headline: 48,\n subheadline: 90,\n highlight: 56,\n cta: 32,\n milestoneLine: 48,\n} as const;\n\nexport const MAX_HIGHLIGHTS = 4;\n\nexport interface Copy {\n headline: string;\n subheadline: string;\n highlights: string[];\n cta: string;\n milestoneLine?: string;\n codeLines?: CodeLine[];\n}\n\nexport type CodeLine = Array<{ text: string; color: string }>;\n","// No-LLM copy rules (default path)\n// Spec: docs/PROJECT_PLAN.md §13.2\n\nimport type { Facts } from \"../facts/schema.js\";\nimport { MAX_HIGHLIGHTS, type Copy } from \"./slots.js\";\n\nexport function deterministicCopy(facts: Facts, maxHighlights = MAX_HIGHLIGHTS): Copy {\n const name = facts.project.name.value;\n const version = facts.release?.version.value;\n const features = (facts.release?.features ?? []).map((item) => item.value);\n const fixes = (facts.release?.fixes ?? []).map((item) => item.value);\n const breaking = (facts.release?.breaking ?? []).map((item) => item.value);\n\n // Breaking changes lead, then features, then fixes. Looking only at features meant a\n // patch release (every Changesets \"Patch Changes\" entry maps to a fix) fell through to\n // \"{name} {version}\", or worse, to a raw commit subject when git was the only source.\n const headlineSource = breaking[0] ?? features[0] ?? fixes[0];\n const headline =\n headlineSource !== undefined\n ? cleanLine(firstSentence(headlineSource))\n : version === undefined\n ? name\n : `${name} ${version}`;\n\n const tagline = facts.project.tagline?.value;\n const subheadline =\n tagline !== undefined && tagline.length > 0\n ? cleanLine(tagline)\n : cleanLine(features[1] ?? fixes[1] ?? fixes[0] ?? `What's new in ${version ?? name}`);\n\n const highlights: string[] = [];\n for (const line of features) {\n if (highlights.length >= maxHighlights) {\n break;\n }\n highlights.push(cleanLine(line));\n }\n for (const line of fixes) {\n if (highlights.length >= maxHighlights) {\n break;\n }\n highlights.push(cleanLine(line));\n }\n for (const line of breaking) {\n if (highlights.length >= maxHighlights) {\n break;\n }\n highlights.push(`Breaking: ${cleanLine(line)}`);\n }\n\n return {\n headline,\n subheadline,\n highlights,\n cta: ctaFor(facts),\n };\n}\n\nexport function formatCount(value: number): string {\n return value.toLocaleString(\"en-US\");\n}\n\nexport function milestoneCopy(\n facts: Facts,\n metric: \"stars\" | \"downloads\" | \"contributors\",\n threshold: number,\n): Copy {\n const formatted = formatCount(threshold);\n const line =\n metric === \"stars\"\n ? `Thank you for ${formatted} stars`\n : metric === \"downloads\"\n ? `${formatted} weekly downloads`\n : `Thank you, ${formatted} contributors`;\n const tagline = facts.project.tagline?.value;\n return {\n headline: facts.project.name.value,\n subheadline: tagline !== undefined && tagline.length > 0 ? cleanLine(tagline) : \"\",\n highlights: [],\n cta: ctaFor(facts),\n milestoneLine: line,\n };\n}\n\nexport function benchCopy(facts: Facts): Copy {\n const title = facts.bench?.title.value ?? facts.project.name.value;\n const note = facts.bench?.note?.value;\n return {\n headline: title,\n subheadline: note !== undefined && note.length > 0 ? note : (facts.project.tagline?.value ?? \"\"),\n highlights: [],\n cta: ctaFor(facts),\n };\n}\n\n/**\n * First sentence of an entry, for use as a headline.\n *\n * Changesets entries are prose paragraphs written for a changelog, so using one whole made a\n * headline that could only be truncated mid-word. The first sentence is the part a person\n * actually wrote as the summary. Abbreviations are not special-cased: a sentence ending is a\n * period followed by a space and a capital, which leaves \"e.g. foo\" and version numbers alone.\n */\nexport function firstSentence(text: string): string {\n const collapsed = text.replace(/\\s+/g, \" \").trim();\n const match = /^(.+?[.?!])\\s+[A-Z]/.exec(collapsed);\n return match?.[1] ?? collapsed;\n}\n\nexport function cleanLine(text: string): string {\n // Replace an em dash with a colon and swallow the space in front of it, so \"shops \\u2014 mobile\"\n // becomes \"shops: mobile\" rather than \"shops : mobile\". Spaced en dashes become a comma for\n // the same reason: a bare hyphen with spaces reads like a stray dash on a card.\n const stripped = text\n .replace(/\\s*\\u2014\\s*/g, \": \")\n .replace(/\\s+\\u2013\\s+/g, \", \")\n .replaceAll(\"\\u2013\", \"-\")\n .replaceAll(\"!\", \".\")\n .replace(/\\s+/g, \" \")\n .trim();\n const noTrail = stripped.endsWith(\".\") ? stripped.slice(0, -1) : stripped;\n const first = noTrail.at(0);\n if (first === undefined) {\n return noTrail;\n }\n return first.toUpperCase() + noTrail.slice(1);\n}\n\nfunction ctaFor(facts: Facts): string {\n const npm = facts.project.npmPackage?.value;\n if (npm !== undefined && npm.length > 0) {\n return `npm i ${npm}`;\n }\n const url = facts.project.url?.value ?? facts.project.repo?.value;\n if (url === undefined) {\n return facts.project.name.value;\n }\n return url.replace(/^https?:\\/\\//, \"\");\n}\n","// Percent change for benchmark cards. Display numbers are computed here, never by an LLM.\n// Spec: docs/PROJECT_PLAN.md §12.7\n\nexport interface PercentChange {\n signed: number;\n absPercent: number;\n regression: boolean;\n}\n\nexport function percentChange(before: number, after: number, better: \"lower\" | \"higher\"): PercentChange {\n if (before === 0) {\n if (after === 0) {\n return { signed: 0, absPercent: 0, regression: false };\n }\n const improved = better === \"higher\" ? after > 0 : after < 0;\n return { signed: improved ? 100 : -100, absPercent: 100, regression: !improved };\n }\n const raw = better === \"lower\" ? (before - after) / before : (after - before) / before;\n const signed = Math.round(raw * 100);\n return { signed, absPercent: Math.abs(signed), regression: signed < 0 };\n}\n\nexport function changePhrase(unit: string, better: \"lower\" | \"higher\", change: PercentChange): string {\n if (change.absPercent === 0) {\n return \"unchanged\";\n }\n return `${String(change.absPercent)}% ${deltaWord(unit, better, change.regression)}`;\n}\n\nfunction deltaWord(unit: string, better: \"lower\" | \"higher\", regression: boolean): string {\n if (better === \"higher\") {\n return regression ? \"lower\" : \"higher\";\n }\n const normalized = unit.toLowerCase();\n if (normalized === \"ms\" || normalized === \"s\" || normalized === \"sec\" || normalized === \"seconds\") {\n return regression ? \"slower\" : \"faster\";\n }\n if (\n normalized === \"kb\" ||\n normalized === \"mb\" ||\n normalized === \"b\" ||\n normalized === \"bytes\" ||\n normalized === \"gzip\"\n ) {\n return regression ? \"larger\" : \"smaller\";\n }\n return regression ? \"worse\" : \"better\";\n}\n","// Text fitting: shrink, then retry/truncate + manifest warning\n// Spec: docs/PROJECT_PLAN.md §15\n\nimport type { MeasureTextOptions, RendererAdapter } from \"../render/adapter.js\";\n\nexport interface TextSlotSpec {\n maxLines: number;\n maxFontSize: number;\n minFontSize: number;\n step: number;\n box: { width: number };\n}\n\nexport interface FittedText {\n fontSize: number;\n text: string;\n lines: number;\n truncated: boolean;\n}\n\nexport interface FitFont {\n family: string;\n lineHeight: number;\n weight?: number;\n whiteSpace?: \"normal\" | \"pre\";\n}\n\nexport async function fitText(\n renderer: Pick<RendererAdapter, \"measureText\">,\n text: string,\n spec: TextSlotSpec,\n font: FitFont,\n): Promise<FittedText> {\n const sizes = fontSizes(spec);\n for (const fontSize of sizes) {\n // Sizes must be tried largest-first; the first fit wins.\n // eslint-disable-next-line no-await-in-loop -- sequential by spec §15.2\n const measured = await renderer.measureText(text, measureOpts(spec, font, fontSize));\n if (measured.lines <= spec.maxLines) {\n return { fontSize, text, lines: measured.lines, truncated: false };\n }\n }\n\n const fontSize = spec.minFontSize;\n const truncated = await truncateToFit(renderer, text, spec, font, fontSize);\n const measured = await renderer.measureText(truncated, measureOpts(spec, font, fontSize));\n return { fontSize, text: truncated, lines: measured.lines, truncated: truncated !== text };\n}\n\nfunction fontSizes(spec: TextSlotSpec): number[] {\n const sizes: number[] = [];\n for (let size = spec.maxFontSize; size >= spec.minFontSize; size -= spec.step) {\n sizes.push(size);\n }\n const last = sizes[sizes.length - 1];\n if (last !== spec.minFontSize) {\n sizes.push(spec.minFontSize);\n }\n return sizes;\n}\n\nfunction measureOpts(spec: TextSlotSpec, font: FitFont, fontSize: number): MeasureTextOptions {\n const opts: MeasureTextOptions = {\n fontFamily: font.family,\n fontSize,\n maxWidth: spec.box.width,\n lineHeight: font.lineHeight,\n };\n if (font.weight !== undefined) {\n opts.fontWeight = font.weight;\n }\n if (font.whiteSpace !== undefined) {\n opts.whiteSpace = font.whiteSpace;\n }\n return opts;\n}\n\nasync function truncateToFit(\n renderer: Pick<RendererAdapter, \"measureText\">,\n text: string,\n spec: TextSlotSpec,\n font: FitFont,\n fontSize: number,\n): Promise<string> {\n const words = text.trim().length === 0 ? [] : text.trim().split(/\\s+/);\n if (words.length === 0) {\n return text;\n }\n\n const fits = async (candidate: string): Promise<boolean> => {\n const measured = await renderer.measureText(\n candidate,\n measureOpts(spec, font, fontSize),\n );\n return measured.lines <= spec.maxLines;\n };\n\n for (let count = words.length - 1; count >= 1; count -= 1) {\n const candidate = `${words.slice(0, count).join(\" \")}...`;\n // eslint-disable-next-line no-await-in-loop -- drop words until the truncated text fits\n if (await fits(candidate)) {\n return candidate;\n }\n }\n\n const first = words[0];\n if (first === undefined) {\n return \"...\";\n }\n for (let length = first.length; length >= 1; length -= 1) {\n const candidate = `${first.slice(0, length)}...`;\n // eslint-disable-next-line no-await-in-loop -- hard-cut the first word as a last resort\n if (await fits(candidate)) {\n return candidate;\n }\n }\n return \"...\";\n}\n","// Dark/light palette derived from brand.json\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { DEFAULT_BRAND_COLORS, type Brand } from \"../brand/schema.js\";\n\nexport interface ThemeColors {\n background: string;\n foreground: string;\n muted: string;\n primary: string;\n accent: string;\n card: string;\n}\n\nexport function themeColors(brand: Brand, theme: \"dark\" | \"light\"): ThemeColors {\n const primary = brand.colors.primary ?? DEFAULT_BRAND_COLORS.primary;\n const accent = brand.colors.accent ?? DEFAULT_BRAND_COLORS.accent;\n const muted = brand.colors.muted ?? DEFAULT_BRAND_COLORS.muted;\n if (theme === \"dark\") {\n const background = brand.theme === \"dark\" ? brand.colors.background : brand.colors.foreground;\n const foreground = brand.theme === \"dark\" ? brand.colors.foreground : brand.colors.background;\n return {\n background,\n foreground,\n muted: brand.theme === \"dark\" ? muted : DEFAULT_BRAND_COLORS.muted,\n primary,\n accent,\n card: mix(background, foreground, 0.08),\n };\n }\n const background = brand.theme === \"light\" ? brand.colors.background : brand.colors.foreground;\n const foreground = brand.theme === \"light\" ? brand.colors.foreground : brand.colors.background;\n return {\n background,\n foreground,\n muted: brand.theme === \"light\" ? muted : \"#52525b\",\n primary,\n accent,\n card: mix(background, foreground, 0.06),\n };\n}\n\nfunction mix(a: string, b: string, amount: number): string {\n const ar = Number.parseInt(a.slice(1, 3), 16);\n const ag = Number.parseInt(a.slice(3, 5), 16);\n const ab = Number.parseInt(a.slice(5, 7), 16);\n const br = Number.parseInt(b.slice(1, 3), 16);\n const bg = Number.parseInt(b.slice(3, 5), 16);\n const bb = Number.parseInt(b.slice(5, 7), 16);\n return `#${toHex(ar + (br - ar) * amount)}${toHex(ag + (bg - ag) * amount)}${toHex(ab + (bb - ab) * amount)}`;\n}\n\nfunction toHex(value: number): string {\n return Math.round(value).toString(16).padStart(2, \"0\");\n}\n","// Local four-line JSX runtime for Takumi templates (no React)\n// Spec: docs/PROJECT_PLAN.md §16.2, §25 (S1)\n\nexport type JsxElement = {\n type: string | symbol | ((props: Record<string, unknown>) => unknown);\n props: Record<string, unknown> | null;\n key: string | null;\n};\n\nexport function jsx(\n type: JsxElement[\"type\"],\n props: Record<string, unknown> | null,\n key?: string | null,\n): JsxElement {\n return { type, props, key: key ?? null };\n}\n\nexport const jsxs = jsx;\nexport const jsxDEV = jsx;\nexport const Fragment = Symbol.for(\"takumi.fragment\");\n\nexport namespace JSX {\n export type Element = JsxElement;\n export interface ElementChildrenAttribute {\n children: unknown;\n }\n export type IntrinsicElements = Record<string, Record<string, unknown>>;\n}\n","// Template: syntax-highlighted snippet\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { CodeLine, Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst propsSchema = z.object({\n headline: z.string(),\n headingFamily: z.string(),\n monoFamily: z.string(),\n headingWeight: z.number(),\n monoWeight: z.number(),\n radius: z.number(),\n lines: z.array(z.array(z.object({ text: z.string(), color: z.string() }))),\n});\n\nexport type CodeCardProps = z.infer<typeof propsSchema>;\n\nexport const codeCard: TemplateDefinition = {\n id: \"code-card\",\n events: [\"release\"],\n formats: [\"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone;\n return {\n headline: { maxLines: 1, maxFontSize: 40, minFontSize: 28, step: 2, box: { width } },\n };\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n return { headline: props.headline };\n },\n slotFont(raw, slot) {\n const props = propsSchema.parse(raw);\n if (slot === \"headline\") {\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1.1 };\n }\n return { family: props.monoFamily, weight: props.monoWeight, lineHeight: 1.35, whiteSpace: \"pre\" };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n const lines = copy.codeLines ?? [];\n if (lines.length === 0) {\n missing.push({ fact: \"release.codeSnippet\", effect: \"code card uses empty snippet\" });\n }\n return {\n props: {\n headline: copy.headline,\n headingFamily: brand.fonts.heading.family,\n monoFamily: brand.fonts.mono.family,\n headingWeight: brand.fonts.heading.weight,\n monoWeight: brand.fonts.mono.weight,\n radius: brand.radius,\n lines,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const headline = ctx.fitted.headline;\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n gap: 24,\n }}\n >\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: headline?.fontSize ?? 36,\n color: colors.foreground,\n }}\n >\n {headline?.text ?? props.headline}\n </div>\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n flexGrow: 1,\n backgroundColor: colors.card,\n borderRadius: props.radius,\n padding: 28,\n gap: 0,\n }}\n >\n {props.lines.map((line, lineIndex) => (\n <div\n key={String(lineIndex)}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n flexWrap: \"nowrap\",\n }}\n >\n {line.map((token, tokenIndex) => (\n <div\n key={`${String(lineIndex)}-${String(tokenIndex)}`}\n style={{\n fontFamily: props.monoFamily,\n fontWeight: props.monoWeight,\n fontSize: 22,\n color: token.color,\n whiteSpace: \"pre\",\n lineHeight: 1.35,\n }}\n >\n {token.text}\n </div>\n ))}\n </div>\n ))}\n </div>\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: 400,\n fontSize: 18,\n color: colors.muted,\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n );\n },\n};\n\nexport function emptyCodeLines(): CodeLine[] {\n return [[{ text: \" \", color: \"#e6edf3\" }]];\n}\n","// Syntax-highlight a snippet into colored spans (shiki tokens)\n// Spec: docs/PROJECT_PLAN.md §14.3, spike S5\n\nimport type { CodeLine } from \"../copy/slots.js\";\n\nconst MAX_LINES = 14;\n\nexport async function highlightCode(\n code: string,\n lang: string,\n theme: \"dark\" | \"light\",\n): Promise<CodeLine[]> {\n const clipped = code.split(\"\\n\").slice(0, MAX_LINES).join(\"\\n\");\n const fallbackColor = theme === \"dark\" ? \"#e6edf3\" : \"#1f2328\";\n try {\n const { codeToTokens } = await import(\"shiki\");\n const result = await codeToTokens(clipped, {\n lang: mapLang(lang),\n theme: theme === \"dark\" ? \"github-dark\" : \"github-light\",\n });\n return result.tokens.map((line) => {\n if (line.length === 0) {\n return [{ text: \" \", color: fallbackColor }];\n }\n return line.map((token) => ({\n text: token.content,\n color: token.color ?? fallbackColor,\n }));\n });\n } catch {\n return clipped.split(\"\\n\").map((line) => [{ text: line.length === 0 ? \" \" : line, color: fallbackColor }]);\n }\n}\n\nfunction mapLang(lang: string): \"ts\" | \"js\" | \"tsx\" | \"jsx\" | \"json\" | \"bash\" {\n const key = lang.toLowerCase();\n if (key === \"javascript\" || key === \"js\") {\n return \"js\";\n }\n if (key === \"tsx\") {\n return \"tsx\";\n }\n if (key === \"jsx\") {\n return \"jsx\";\n }\n if (key === \"json\") {\n return \"json\";\n }\n if (key === \"bash\" || key === \"shell\" || key === \"sh\") {\n return \"bash\";\n }\n return \"ts\";\n}\n","// Template: before/after metrics\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport { changePhrase, percentChange } from \"../bench/percent.js\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst rowSchema = z.object({\n label: z.string(),\n beforeText: z.string(),\n afterText: z.string(),\n changeText: z.string(),\n regression: z.boolean(),\n});\n\nconst propsSchema = z.object({\n title: z.string(),\n note: z.string(),\n rows: z.array(rowSchema),\n headingFamily: z.string(),\n bodyFamily: z.string(),\n headingWeight: z.number(),\n bodyWeight: z.number(),\n radius: z.number(),\n});\n\nexport type BenchProps = z.infer<typeof propsSchema>;\n\nexport const bench: TemplateDefinition = {\n id: \"bench\",\n events: [\"bench\"],\n formats: [\"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone;\n const slots: Record<string, { maxLines: number; maxFontSize: number; minFontSize: number; step: number; box: { width: number } }> =\n {\n title: { maxLines: 2, maxFontSize: 48, minFontSize: 28, step: 2, box: { width } },\n };\n for (let index = 0; index < 3; index += 1) {\n slots[`change-${String(index)}`] = {\n maxLines: 1,\n maxFontSize: 36,\n minFontSize: 22,\n step: 2,\n box: { width: Math.min(360, width) },\n };\n }\n return slots;\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n const text: Record<string, string> = { title: props.title };\n props.rows.forEach((row, index) => {\n text[`change-${String(index)}`] = row.changeText;\n });\n return text;\n },\n slotFont(raw, slot) {\n const props = propsSchema.parse(raw);\n if (slot === \"title\") {\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1.15 };\n }\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1.1 };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n if (facts.bench === undefined) {\n missing.push({ fact: \"bench\", effect: \"metrics hidden\" });\n }\n const rows =\n facts.bench?.metrics.map((metric) => {\n const change = percentChange(metric.before.value, metric.after.value, metric.better.value);\n return {\n label: metric.label.value,\n beforeText: `${formatMetric(metric.before.value)} ${metric.unit.value}`,\n afterText: `${formatMetric(metric.after.value)} ${metric.unit.value}`,\n changeText: changePhrase(metric.unit.value, metric.better.value, change),\n regression: change.regression,\n };\n }) ?? [];\n return {\n props: {\n title: copy.headline,\n note: copy.subheadline,\n rows,\n headingFamily: brand.fonts.heading.family,\n bodyFamily: brand.fonts.body.family,\n headingWeight: brand.fonts.heading.weight,\n bodyWeight: brand.fonts.body.weight,\n radius: brand.radius,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const title = ctx.fitted.title;\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n }}\n >\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: title?.fontSize ?? 40,\n color: colors.foreground,\n lineHeight: 1.15,\n }}\n >\n {title?.text ?? props.title}\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 20 }}>\n {props.rows.map((row, index) => {\n const change = ctx.fitted[`change-${String(index)}`];\n return (\n <div\n key={row.label}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n backgroundColor: colors.card,\n borderRadius: props.radius,\n paddingTop: 16,\n paddingBottom: 16,\n paddingLeft: 24,\n paddingRight: 24,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 22,\n color: colors.muted,\n }}\n >\n {row.label}\n </div>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 24,\n color: colors.foreground,\n }}\n >\n {`${row.beforeText} to ${row.afterText}`}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"flex-end\", gap: 4 }}>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: change?.fontSize ?? 32,\n color: row.regression ? colors.primary : colors.accent,\n }}\n >\n {change?.text ?? row.changeText}\n </div>\n {row.regression ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.primary,\n }}\n >\n regression\n </div>\n ) : undefined}\n </div>\n </div>\n );\n })}\n </div>\n <div style={{ display: \"flex\", flexDirection: \"row\", justifyContent: \"space-between\", alignItems: \"flex-end\" }}>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 20,\n color: colors.muted,\n }}\n >\n {props.note}\n </div>\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.muted,\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n </div>\n );\n },\n};\n\nfunction formatMetric(value: number): string {\n return String(value);\n}\n","// Template: milestone big number\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport type { Brand } from \"../brand/schema.js\";\nimport { formatCount } from \"../copy/deterministic.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst propsSchema = z.object({\n name: z.string(),\n numberText: z.string(),\n metricLabel: z.string(),\n thankYou: z.string(),\n headingFamily: z.string(),\n bodyFamily: z.string(),\n headingWeight: z.number(),\n bodyWeight: z.number(),\n radius: z.number(),\n showLogo: z.boolean(),\n});\n\nexport type MilestoneProps = z.infer<typeof propsSchema>;\n\nexport const milestone: TemplateDefinition = {\n id: \"milestone\",\n events: [\"milestone\"],\n formats: [\"og\", \"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone;\n return {\n number: { maxLines: 1, maxFontSize: 160, minFontSize: 72, step: 8, box: { width } },\n thankYou: { maxLines: 2, maxFontSize: 36, minFontSize: 24, step: 2, box: { width } },\n };\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n return { number: props.numberText, thankYou: props.thankYou };\n },\n slotFont(raw, slot) {\n const props = propsSchema.parse(raw);\n if (slot === \"number\") {\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1 };\n }\n return { family: props.bodyFamily, weight: props.bodyWeight, lineHeight: 1.25 };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n const threshold = facts.milestone?.threshold.value;\n if (threshold === undefined) {\n missing.push({ fact: \"milestone.threshold\", effect: \"number hidden\" });\n }\n const metric = facts.milestone?.metric.value;\n const metricLabel =\n metric === \"downloads\" ? \"weekly downloads\" : metric === \"contributors\" ? \"contributors\" : \"stars\";\n const showLogo = brand.logo !== undefined;\n if (!showLogo) {\n missing.push({ fact: \"brand.logo\", effect: \"logo hidden\" });\n }\n const thankYou = copy.milestoneLine ?? (threshold === undefined ? \"\" : `Thank you for ${formatCount(threshold)} ${metricLabel}`);\n return {\n props: {\n name: brand.name,\n numberText: threshold === undefined ? \"\" : formatCount(threshold),\n metricLabel,\n thankYou,\n headingFamily: brand.fonts.heading.family,\n bodyFamily: brand.fonts.body.family,\n headingWeight: brand.fonts.heading.weight,\n bodyWeight: brand.fonts.body.weight,\n radius: brand.radius,\n showLogo,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const number = ctx.fitted.number;\n const thanks = ctx.fitted.thankYou;\n const compact = ctx.format.height <= 640;\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"row\", alignItems: \"center\", gap: 20 }}>\n {props.showLogo && ctx.logoSrc !== undefined ? (\n <img src={ctx.logoSrc} width={compact ? 56 : 72} height={compact ? 56 : 72} />\n ) : undefined}\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: 28,\n color: colors.foreground,\n }}\n >\n {props.name}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: number?.fontSize ?? 140,\n color: colors.foreground,\n lineHeight: 1,\n }}\n >\n {number?.text ?? props.numberText}\n </div>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.headingWeight,\n fontSize: 32,\n color: colors.primary,\n }}\n >\n {props.metricLabel}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"row\", justifyContent: \"space-between\", alignItems: \"flex-end\" }}>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: thanks?.fontSize ?? 28,\n color: colors.muted,\n lineHeight: 1.25,\n }}\n >\n {thanks?.text ?? props.thankYou}\n </div>\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.muted,\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n </div>\n );\n },\n};\n","// Template: release hero\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst propsSchema = z.object({\n name: z.string(),\n version: z.string(),\n headline: z.string(),\n subheadline: z.string(),\n cta: z.string(),\n headingFamily: z.string(),\n bodyFamily: z.string(),\n headingWeight: z.number(),\n bodyWeight: z.number(),\n radius: z.number(),\n showCta: z.boolean(),\n showLogo: z.boolean(),\n});\n\nexport type ReleaseHeroProps = z.infer<typeof propsSchema>;\n\nexport const releaseHero: TemplateDefinition = {\n id: \"release-hero\",\n events: [\"release\"],\n formats: [\"og\", \"github-social\", \"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone;\n return {\n headline: { maxLines: 2, maxFontSize: 72, minFontSize: 48, step: 4, box: { width } },\n subheadline: { maxLines: 2, maxFontSize: 32, minFontSize: 24, step: 2, box: { width } },\n cta: { maxLines: 1, maxFontSize: 28, minFontSize: 22, step: 2, box: { width: Math.min(480, width) } },\n };\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n return {\n headline: props.headline,\n subheadline: props.subheadline,\n cta: props.cta,\n };\n },\n slotFont(raw, slot) {\n const props = propsSchema.parse(raw);\n if (slot === \"headline\") {\n return { family: props.headingFamily, weight: props.headingWeight, lineHeight: 1.1 };\n }\n return { family: props.bodyFamily, weight: props.bodyWeight, lineHeight: 1.25 };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n if (facts.project.npmPackage === undefined && facts.project.url === undefined) {\n missing.push({ fact: \"project.npmPackage\", effect: \"cta uses project name\" });\n }\n const showLogo = brand.logo !== undefined;\n if (!showLogo) {\n missing.push({ fact: \"brand.logo\", effect: \"logo hidden\" });\n }\n const version = facts.release?.version.value ?? \"\";\n return {\n props: {\n name: brand.name,\n version,\n headline: copy.headline,\n subheadline: copy.subheadline,\n cta: copy.cta,\n headingFamily: brand.fonts.heading.family,\n bodyFamily: brand.fonts.body.family,\n headingWeight: brand.fonts.heading.weight,\n bodyWeight: brand.fonts.body.weight,\n radius: brand.radius,\n showCta: copy.cta.length > 0,\n showLogo,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const headline = ctx.fitted.headline;\n const sub = ctx.fitted.subheadline;\n const cta = ctx.fitted.cta;\n const compact = ctx.format.height <= 640;\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"row\", alignItems: \"center\", gap: 20 }}>\n {props.showLogo && ctx.logoSrc !== undefined ? (\n <img src={ctx.logoSrc} width={compact ? 56 : 72} height={compact ? 56 : 72} />\n ) : undefined}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: 28,\n color: colors.foreground,\n }}\n >\n {props.name}\n </div>\n {props.version.length > 0 ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n backgroundColor: colors.card,\n borderRadius: props.radius,\n paddingTop: 6,\n paddingBottom: 6,\n paddingLeft: 14,\n paddingRight: 14,\n }}\n >\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 22,\n color: colors.primary,\n }}\n >\n {`v${props.version}`}\n </div>\n </div>\n ) : undefined}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 16 }}>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: headline?.fontSize ?? 64,\n color: colors.foreground,\n lineHeight: 1.1,\n }}\n >\n {headline?.text ?? props.headline}\n </div>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: sub?.fontSize ?? 28,\n color: colors.muted,\n lineHeight: 1.25,\n }}\n >\n {sub?.text ?? props.subheadline}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"row\", justifyContent: \"space-between\", alignItems: \"flex-end\" }}>\n {props.showCta ? (\n <div\n style={{\n display: \"flex\",\n backgroundColor: colors.primary,\n borderRadius: props.radius,\n paddingTop: 14,\n paddingBottom: 14,\n paddingLeft: 24,\n paddingRight: 24,\n }}\n >\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.headingWeight,\n fontSize: cta?.fontSize ?? 24,\n color: colors.background,\n }}\n >\n {cta?.text ?? props.cta}\n </div>\n </div>\n ) : (\n <div />\n )}\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.muted,\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n </div>\n );\n },\n};\n","// Template: what's new list\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { z } from \"zod\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Format } from \"../formats.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { themeColors } from \"./theme.js\";\n\nconst propsSchema = z.object({\n name: z.string(),\n version: z.string(),\n highlights: z.array(z.string()),\n headingFamily: z.string(),\n bodyFamily: z.string(),\n headingWeight: z.number(),\n bodyWeight: z.number(),\n radius: z.number(),\n});\n\nexport type ReleaseHighlightsProps = z.infer<typeof propsSchema>;\n\nexport const releaseHighlights: TemplateDefinition = {\n id: \"release-highlights\",\n events: [\"release\"],\n formats: [\"x\", \"linkedin\"],\n propsSchema,\n slots(format: Format) {\n const width = format.width - 2 * format.safeZone - 48;\n const slots: Record<string, { maxLines: number; maxFontSize: number; minFontSize: number; step: number; box: { width: number } }> = {};\n for (let index = 0; index < 4; index += 1) {\n slots[`highlight-${String(index)}`] = {\n maxLines: 2,\n maxFontSize: 32,\n minFontSize: 24,\n step: 2,\n box: { width },\n };\n }\n return slots;\n },\n slotText(raw) {\n const props = propsSchema.parse(raw);\n const text: Record<string, string> = {};\n props.highlights.forEach((line, index) => {\n text[`highlight-${String(index)}`] = line;\n });\n return text;\n },\n slotFont(raw) {\n const props = propsSchema.parse(raw);\n return { family: props.bodyFamily, weight: props.bodyWeight, lineHeight: 1.25 };\n },\n buildProps(facts: Facts, copy: Copy, brand: Brand) {\n const missing = [];\n if (copy.highlights.length === 0) {\n missing.push({ fact: \"release.features\", effect: \"highlights list empty\" });\n }\n return {\n props: {\n name: brand.name,\n version: facts.release?.version.value ?? \"\",\n highlights: copy.highlights,\n headingFamily: brand.fonts.heading.family,\n bodyFamily: brand.fonts.body.family,\n headingWeight: brand.fonts.heading.weight,\n bodyWeight: brand.fonts.body.weight,\n radius: brand.radius,\n },\n missing,\n };\n },\n render(raw, ctx) {\n const props = propsSchema.parse(raw);\n const colors = themeColors(ctx.brand, ctx.theme);\n const pad = ctx.format.safeZone;\n const title = props.version.length > 0 ? `What's new in v${props.version}` : \"What's new\";\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: colors.background,\n padding: pad,\n gap: 28,\n }}\n >\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 22,\n color: colors.primary,\n }}\n >\n {props.name}\n </div>\n <div\n style={{\n fontFamily: props.headingFamily,\n fontWeight: props.headingWeight,\n fontSize: 48,\n color: colors.foreground,\n }}\n >\n {title}\n </div>\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 16 }}>\n {props.highlights.map((line, index) => {\n const fitted = ctx.fitted[`highlight-${String(index)}`];\n const breaking = line.startsWith(\"Breaking:\");\n return (\n <div\n key={String(index)}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"flex-start\",\n gap: 16,\n backgroundColor: colors.card,\n borderRadius: props.radius,\n padding: 18,\n }}\n >\n <div\n style={{\n width: 12,\n height: 12,\n borderRadius: 6,\n backgroundColor: breaking ? colors.accent : colors.primary,\n marginTop: 10,\n }}\n />\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: fitted?.fontSize ?? 28,\n color: colors.foreground,\n lineHeight: 1.25,\n }}\n >\n {fitted?.text ?? line}\n </div>\n </div>\n );\n })}\n </div>\n {ctx.attribution ? (\n <div\n style={{\n fontFamily: props.bodyFamily,\n fontWeight: props.bodyWeight,\n fontSize: 18,\n color: colors.muted,\n marginTop: \"auto\",\n }}\n >\n made with shipseal.dev\n </div>\n ) : undefined}\n </div>\n );\n },\n};\n","// Template registry\n// Spec: docs/PROJECT_PLAN.md §14.3\n\nimport { ShipsealError } from \"../core/errors.js\";\nimport type { TemplateDefinition } from \"./contract.js\";\nimport { bench } from \"./bench.js\";\nimport { codeCard } from \"./code-card.js\";\nimport { milestone } from \"./milestone.js\";\nimport { releaseHero } from \"./release-hero.js\";\nimport { releaseHighlights } from \"./release-highlights.js\";\n\nconst templates = [releaseHero, releaseHighlights, codeCard, milestone, bench] as const;\n\nexport function getTemplate(id: string): TemplateDefinition {\n const found = templates.find((template) => template.id === id);\n if (found === undefined) {\n throw new ShipsealError(\n \"template.unknown\",\n `Unknown template \"${id}\".`,\n `Use one of: ${templates.map((template) => template.id).join(\", \")}.`,\n );\n }\n return found;\n}\n\nexport function templatesForEvent(kind: \"release\" | \"milestone\" | \"bench\"): TemplateDefinition[] {\n return templates.filter((template) => template.events.includes(kind));\n}\n\nexport const RELEASE_TEMPLATE_IDS = [\"release-hero\", \"release-highlights\", \"code-card\"] as const;\n","// The pure pipeline: facts + copy + brand + templates -> rendered files (no network I/O)\n// Spec: docs/PROJECT_PLAN.md §6.1\n\nimport { createHash } from \"node:crypto\";\nimport { percentChange } from \"../bench/percent.js\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { Config } from \"../config/schema.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport type { ShipsealEvent } from \"./events.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { fitText, type FittedText } from \"../fit/fit-text.js\";\nimport { FORMATS, type Format, type FormatId } from \"../formats.js\";\nimport type { ImageFormat, RenderOptions, RendererAdapter } from \"../render/adapter.js\";\nimport { emptyCodeLines } from \"../templates/code-card.js\";\nimport type { ManifestMissing, RenderContext, TemplateDefinition } from \"../templates/contract.js\";\nimport { highlightCode } from \"../templates/highlight.js\";\nimport { getTemplate } from \"../templates/registry.js\";\n\nexport interface GenerateInput {\n event: ShipsealEvent;\n facts: Facts;\n brand: Brand;\n config: Config;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n renderer: RendererAdapter;\n themes: Array<\"dark\" | \"light\">;\n generatedAt: string;\n logos?: { light?: Uint8Array; dark?: Uint8Array };\n}\n\nexport interface GeneratedFile {\n fileName: string;\n template: string;\n format: FormatId;\n theme: \"dark\" | \"light\";\n width: number;\n height: number;\n bytes: Uint8Array;\n sha256: string;\n}\n\nexport interface FitWarning {\n type: \"fit-warning\";\n template: string;\n format: FormatId;\n slot: string;\n action: \"truncated\";\n}\n\nexport interface GenerateResult {\n files: GeneratedFile[];\n warnings: FitWarning[];\n missing: Array<ManifestMissing & { template: string }>;\n facts: Facts;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n generatedAt: string;\n computed: Record<string, { value: unknown; computedFrom: string[] }>;\n}\n\nexport async function generate(input: GenerateInput): Promise<GenerateResult> {\n const templateIds = templateIdsFor(input.event, input.config);\n const formatIds = input.config.formats ?? [\"og\", \"github-social\", \"x\", \"linkedin\"];\n const imageFormat: ImageFormat = input.config.output?.imageFormat ?? \"png\";\n const attribution = input.config.attribution !== false;\n const files: GeneratedFile[] = [];\n const warnings: FitWarning[] = [];\n const missing: Array<ManifestMissing & { template: string }> = [];\n const recordedMissing = new Set<string>();\n const omitThemeSuffix = input.themes.length === 1;\n\n for (const templateId of templateIds) {\n const template = getTemplate(templateId);\n if (!template.events.includes(input.event.kind)) {\n continue;\n }\n for (const formatId of formatIds) {\n if (!template.formats.includes(formatId)) {\n continue;\n }\n const format = FORMATS[formatId];\n for (const theme of input.themes) {\n // Formats and themes render sequentially so fit warnings stay attached to the right file.\n // eslint-disable-next-line no-await-in-loop\n const copy = await copyForTemplate(template.id, input.copy, input.facts, theme);\n const built = template.buildProps(input.facts, copy, input.brand);\n const props = template.propsSchema.parse(built.props);\n if (!recordedMissing.has(template.id)) {\n recordedMissing.add(template.id);\n for (const item of built.missing) {\n missing.push({ template: template.id, fact: item.fact, effect: item.effect });\n }\n }\n // eslint-disable-next-line no-await-in-loop\n const { fitted, truncated } = await fitSlots(input.renderer, template, props, format);\n for (const slot of truncated) {\n warnings.push({\n type: \"fit-warning\",\n template: template.id,\n format: formatId,\n slot,\n action: \"truncated\",\n });\n }\n const logo = logoForTheme(input.logos, theme);\n const ctx: RenderContext = {\n format,\n theme,\n brand: input.brand,\n fitted,\n attribution,\n };\n if (logo !== undefined) {\n ctx.logoSrc = \"shipseal-logo\";\n }\n const jsx = template.render(props, ctx);\n // eslint-disable-next-line no-await-in-loop\n const node = await input.renderer.fromJsx(jsx);\n const renderOpts: RenderOptions = {\n width: format.width,\n height: format.height,\n format: imageFormat,\n };\n if (logo !== undefined) {\n renderOpts.images = [{ src: \"shipseal-logo\", data: logo }];\n }\n // eslint-disable-next-line no-await-in-loop\n const bytes = await input.renderer.render(node, renderOpts);\n const fileName = outputName(template.id, formatId, theme, omitThemeSuffix, imageFormat);\n files.push({\n fileName,\n template: template.id,\n format: formatId,\n theme,\n width: format.width,\n height: format.height,\n bytes,\n sha256: createHash(\"sha256\").update(bytes).digest(\"hex\"),\n });\n }\n }\n }\n\n return {\n files,\n warnings,\n missing,\n facts: input.facts,\n copy: input.copy,\n copyMode: input.copyMode,\n generatedAt: input.generatedAt,\n computed: computedFromFacts(input.facts),\n };\n}\n\nfunction templateIdsFor(event: ShipsealEvent, config: Config): string[] {\n if (event.kind === \"milestone\") {\n return [\"milestone\"];\n }\n if (event.kind === \"bench\") {\n return [\"bench\"];\n }\n return config.release?.templates ?? [\"release-hero\", \"release-highlights\", \"code-card\"];\n}\n\nfunction computedFromFacts(facts: Facts): Record<string, { value: unknown; computedFrom: string[] }> {\n const out: Record<string, { value: unknown; computedFrom: string[] }> = {};\n if (facts.bench === undefined) {\n return out;\n }\n facts.bench.metrics.forEach((metric, index) => {\n const change = percentChange(metric.before.value, metric.after.value, metric.better.value);\n const prefix = `bench.metrics[${String(index)}]`;\n out[`${prefix}.percent`] = {\n value: change.signed,\n computedFrom: [`${prefix}.before`, `${prefix}.after`, `${prefix}.better`],\n };\n });\n return out;\n}\n\nasync function fitSlots(\n renderer: RendererAdapter,\n template: TemplateDefinition,\n props: unknown,\n format: Format,\n): Promise<{ fitted: Record<string, FittedText>; truncated: string[] }> {\n const specs = template.slots(format);\n const texts = template.slotText(props);\n const fitted: Record<string, FittedText> = {};\n const truncated: string[] = [];\n for (const [slot, spec] of Object.entries(specs)) {\n const text = texts[slot];\n if (text === undefined) {\n continue;\n }\n const font = template.slotFont(props, slot);\n const fitFont: { family: string; lineHeight: number; weight: number; whiteSpace?: \"normal\" | \"pre\" } = {\n family: font.family,\n lineHeight: font.lineHeight,\n weight: font.weight,\n };\n if (font.whiteSpace !== undefined) {\n fitFont.whiteSpace = font.whiteSpace;\n }\n // eslint-disable-next-line no-await-in-loop -- sizes are sequential per slot spec\n const result = await fitText(renderer, text, spec, fitFont);\n fitted[slot] = result;\n if (result.truncated) {\n truncated.push(slot);\n }\n }\n return { fitted, truncated };\n}\n\nfunction outputName(\n template: string,\n format: FormatId,\n theme: \"dark\" | \"light\",\n omitTheme: boolean,\n imageFormat: string,\n): string {\n const themePart = omitTheme ? \"\" : `-${theme}`;\n return `${template}-${format}${themePart}.${imageFormat}`;\n}\n\nfunction logoForTheme(\n logos: GenerateInput[\"logos\"],\n theme: \"dark\" | \"light\",\n): Uint8Array | undefined {\n if (logos === undefined) {\n return undefined;\n }\n if (theme === \"dark\") {\n return logos.dark ?? logos.light;\n }\n return logos.light ?? logos.dark;\n}\n\nasync function copyForTemplate(\n templateId: string,\n copy: Copy,\n facts: Facts,\n theme: \"dark\" | \"light\",\n): Promise<Copy> {\n if (templateId !== \"code-card\") {\n return copy;\n }\n const snippet = facts.release?.codeSnippet?.value;\n if (snippet === undefined) {\n return { ...copy, codeLines: emptyCodeLines() };\n }\n return { ...copy, codeLines: await highlightCode(snippet.code, snippet.lang, theme) };\n}\n","// Merge partial Facts from sources. Later sources fill holes.\n// Changelog feature lists replace git commit lists when present.\n// Spec: docs/PROJECT_PLAN.md §12\n\nimport { ShipsealError } from \"../core/errors.js\";\nimport type { Facts } from \"./schema.js\";\nimport type { PartialFacts, PartialMetrics, PartialMilestone, PartialProject, PartialRelease } from \"./partial.js\";\n\nexport function mergeFacts(parts: PartialFacts[]): Facts {\n const project: PartialProject = {};\n const release: PartialRelease = {};\n const metrics: PartialMetrics = {};\n const milestone: PartialMilestone = {};\n let bench: Facts[\"bench\"];\n\n for (const part of parts) {\n fillObject(project, part.project);\n mergeRelease(release, part.release);\n fillObject(metrics, part.metrics);\n fillObject(milestone, part.milestone);\n if (part.bench !== undefined) {\n bench = part.bench;\n }\n }\n\n if (project.name === undefined) {\n throw new ShipsealError(\n \"facts.missing-name\",\n \"Could not determine the project name.\",\n \"Add a name field to package.json, or an H1 in README.md.\",\n );\n }\n\n const facts: Facts = {\n project: {\n name: project.name,\n },\n };\n if (project.tagline !== undefined) {\n facts.project.tagline = project.tagline;\n }\n if (project.url !== undefined) {\n facts.project.url = project.url;\n }\n if (project.repo !== undefined) {\n facts.project.repo = project.repo;\n }\n if (project.npmPackage !== undefined) {\n facts.project.npmPackage = project.npmPackage;\n }\n if (project.license !== undefined) {\n facts.project.license = project.license;\n }\n\n // A partial release block is dropped, not fatal. `package.json#version` alone makes\n // `hasRelease` true on every project, so throwing here broke `bench` and `milestone`,\n // which do not need release facts at all (§6.3). The release event still errors, in\n // collectFacts, where the check knows the event kind.\n if (isCompleteRelease(release)) {\n facts.release = {\n version: release.version,\n tag: release.tag,\n date: release.date,\n features: release.features ?? [],\n fixes: release.fixes ?? [],\n breaking: release.breaking ?? [],\n };\n if (release.previousVersion !== undefined) {\n facts.release.previousVersion = release.previousVersion;\n }\n if (release.commitCount !== undefined) {\n facts.release.commitCount = release.commitCount;\n }\n if (release.contributors !== undefined) {\n facts.release.contributors = release.contributors;\n }\n if (release.codeSnippet !== undefined) {\n facts.release.codeSnippet = release.codeSnippet;\n }\n }\n\n if (Object.keys(metrics).length > 0) {\n facts.metrics = metrics;\n }\n if (bench !== undefined) {\n facts.bench = bench;\n }\n if (milestone.metric !== undefined && milestone.threshold !== undefined) {\n facts.milestone = { metric: milestone.metric, threshold: milestone.threshold };\n }\n return facts;\n}\n\nfunction mergeRelease(target: PartialRelease, overlay: PartialRelease | undefined): void {\n if (overlay === undefined) {\n return;\n }\n fillObject(target, overlay, [\"features\", \"fixes\", \"breaking\"]);\n replaceList(target, overlay, \"features\");\n replaceList(target, overlay, \"fixes\");\n replaceList(target, overlay, \"breaking\");\n}\n\nfunction replaceList(\n target: PartialRelease,\n overlay: PartialRelease,\n key: \"features\" | \"fixes\" | \"breaking\",\n): void {\n const next = overlay[key];\n if (next !== undefined) {\n target[key] = next;\n }\n}\n\nfunction fillObject<T extends object>(target: T, overlay: T | undefined, skip: (keyof T)[] = []): void {\n if (overlay === undefined) {\n return;\n }\n const skipped = new Set(skip);\n for (const key of Object.keys(overlay) as (keyof T)[]) {\n if (skipped.has(key)) {\n continue;\n }\n const value = overlay[key];\n if (value !== undefined && target[key] === undefined) {\n target[key] = value;\n }\n }\n}\n\nfunction isCompleteRelease(\n release: PartialRelease,\n): release is PartialRelease &\n Required<Pick<PartialRelease, \"version\" | \"tag\" | \"date\">> {\n return release.version !== undefined && release.tag !== undefined && release.date !== undefined;\n}\n","// fact() helper that attaches provenance\n// Spec: docs/PROJECT_PLAN.md §9.1\n\nimport type { Fact, SourceId } from \"./schema.js\";\n\nexport function fact<T>(\n value: T,\n provenance: { source: SourceId; ref: string; fetchedAt?: string },\n): Fact<T> {\n const fetchedAt = provenance.fetchedAt ?? new Date().toISOString();\n return {\n value,\n provenance: {\n source: provenance.source,\n ref: provenance.ref,\n fetchedAt,\n },\n };\n}\n","// Benchmark JSON reader\n// Spec: docs/PROJECT_PLAN.md §12.7\n\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join } from \"node:path\";\nimport { z } from \"zod\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\n\nconst metricSchema = z.object({\n label: z.string().min(1),\n before: z.number().finite(),\n after: z.number().finite(),\n unit: z.string().min(1),\n better: z.enum([\"lower\", \"higher\"]),\n});\n\nconst benchFileSchema = z.object({\n title: z.string().min(1),\n metrics: z.array(metricSchema).min(1).max(3),\n note: z.string().optional(),\n});\n\nexport async function collectBenchFile(cwd: string, filePath = \".shipseal/bench.json\"): Promise<PartialFacts> {\n const resolved = isAbsolute(filePath) ? filePath : join(cwd, filePath);\n let raw: string;\n try {\n raw = await readFile(resolved, \"utf8\");\n } catch (error) {\n throw new ShipsealError(\n \"bench.missing-file\",\n `Benchmark file not found: ${filePath}.`,\n \"Write .shipseal/bench.json (title, metrics with before/after/unit/better), or pass --file <path>.\",\n { cause: error },\n );\n }\n let json: unknown;\n try {\n json = JSON.parse(raw);\n } catch (error) {\n throw new ShipsealError(\n \"bench.invalid-json\",\n `Benchmark file is not valid JSON: ${filePath}.`,\n \"Fix the JSON syntax, then retry.\",\n { cause: error },\n );\n }\n const parsed = benchFileSchema.safeParse(json);\n if (!parsed.success) {\n throw new ShipsealError(\n \"bench.invalid-shape\",\n `Benchmark file is missing required fields: ${filePath}.`,\n 'Each metric needs label, before, after, unit, and better (\"lower\" or \"higher\"). At most 3 metrics.',\n );\n }\n const fetchedAt = new Date().toISOString();\n const ref = filePath;\n const bench: NonNullable<Facts[\"bench\"]> = {\n title: fact(parsed.data.title, { source: \"bench-file\", ref: `${ref}#title`, fetchedAt }),\n metrics: parsed.data.metrics.map((metric, index) => ({\n label: fact(metric.label, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].label`, fetchedAt }),\n before: fact(metric.before, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].before`, fetchedAt }),\n after: fact(metric.after, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].after`, fetchedAt }),\n unit: fact(metric.unit, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].unit`, fetchedAt }),\n better: fact(metric.better, { source: \"bench-file\", ref: `${ref}#metrics[${String(index)}].better`, fetchedAt }),\n })),\n };\n if (parsed.data.note !== undefined) {\n bench.note = fact(parsed.data.note, { source: \"bench-file\", ref: `${ref}#note`, fetchedAt });\n }\n return { bench };\n}\n","// Keep a Changelog + Changesets parsing\n// Spec: docs/PROJECT_PLAN.md §12.4\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Fact } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\n\nexport async function collectChangelog(\n cwd: string,\n version: string | undefined,\n changelogPath = \"CHANGELOG.md\",\n): Promise<PartialFacts> {\n if (version === undefined) {\n return {};\n }\n let markdown: string;\n try {\n markdown = await readFile(join(cwd, changelogPath), \"utf8\");\n } catch {\n return {};\n }\n const section = findVersionSection(markdown, version);\n if (section === undefined) {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const features: Fact<string>[] = [];\n const fixes: Fact<string>[] = [];\n const breaking: Fact<string>[] = [];\n\n for (const group of parseGroups(section.body)) {\n const bucket = bucketForHeading(group.heading);\n if (bucket === undefined) {\n continue;\n }\n for (const item of group.items) {\n const cleaned = cleanChangelogItem(item);\n if (cleaned.length === 0) {\n continue;\n }\n const entry = fact(cleaned, {\n source: \"changelog\",\n ref: `${changelogPath} ${section.heading} ${group.heading}: ${item}`,\n fetchedAt,\n });\n if (bucket === \"features\") {\n features.push(entry);\n } else if (bucket === \"fixes\") {\n fixes.push(entry);\n } else {\n breaking.push(entry);\n }\n }\n }\n\n const out: PartialFacts = {\n release: {\n version: fact(version.replace(/^v/, \"\"), {\n source: \"changelog\",\n ref: `${changelogPath} ${section.heading}`,\n fetchedAt,\n }),\n tag: fact(version.startsWith(\"v\") ? version : `v${version}`, {\n source: \"changelog\",\n ref: `${changelogPath} ${section.heading}`,\n fetchedAt,\n }),\n features,\n fixes,\n breaking,\n },\n };\n if (section.date !== undefined) {\n out.release = {\n ...out.release,\n date: fact(section.date, {\n source: \"changelog\",\n ref: `${changelogPath} ${section.heading}`,\n fetchedAt,\n }),\n };\n }\n return out;\n}\n\nexport function findVersionSection(\n markdown: string,\n version: string,\n): { heading: string; body: string; date?: string } | undefined {\n const needle = version.replace(/^v/, \"\");\n const headingRe = /^##\\s+(.+)$/gm;\n const matches = [...markdown.matchAll(headingRe)];\n for (let index = 0; index < matches.length; index += 1) {\n const match = matches[index];\n if (match === undefined) {\n continue;\n }\n const heading = match[1];\n if (heading === undefined || !headingIncludesVersion(heading, needle)) {\n continue;\n }\n const start = (match.index ?? 0) + match[0].length;\n const next = matches[index + 1];\n const end = next?.index ?? markdown.length;\n const date = extractDate(heading);\n const body = markdown.slice(start, end);\n if (date === undefined) {\n return { heading, body };\n }\n return { heading, body, date };\n }\n return undefined;\n}\n\nexport function cleanChangelogItem(item: string): string {\n return item\n .replace(/^\\s*[-*]\\s*/, \"\")\n .replace(/\\[`[a-f0-9]{7,40}`]\\([^)]+\\)/gi, \"\")\n .replace(/^[a-f0-9]{7,40}:\\s*/i, \"\")\n .replace(/\\(#\\d+\\)/g, \"\")\n .replace(/\\[#\\d+]\\([^)]+\\)/g, \"\")\n .replace(/Thanks\\s+\\[@[\\w-]+]\\([^)]+\\)!?\\s*-?\\s*/gi, \"\")\n .replace(/\\[@[\\w-]+]\\([^)]+\\)/g, \"\")\n .replace(/\\(@[\\w-]+\\)/g, \"\")\n .replace(/\\s+by\\s+@[\\w-]+/gi, \"\")\n .replace(/@[\\w-]+/g, \"\")\n .replace(/^Thanks\\s*!?\\s*-?\\s*/i, \"\")\n .replace(/^\\s*[-*]\\s*/, \"\")\n .replace(/\\s+/g, \" \")\n .trim()\n .replace(/\\.$/, \"\");\n}\n\nfunction headingIncludesVersion(heading: string, version: string): boolean {\n const unwrapped = heading.replace(/[[\\]]/g, \" \");\n return new RegExp(`(?:^|\\\\s)v?${escapeRegExp(version)}(?:\\\\s|$)`).test(unwrapped);\n}\n\nfunction extractDate(heading: string): string | undefined {\n const match = /(\\d{4}-\\d{2}-\\d{2})/.exec(heading);\n return match?.[1];\n}\n\nfunction parseGroups(body: string): Array<{ heading: string; items: string[] }> {\n const groups: Array<{ heading: string; items: string[] }> = [];\n const headingRe = /^###\\s+(.+)$/gm;\n const matches = [...body.matchAll(headingRe)];\n if (matches.length === 0) {\n return [{ heading: \"Added\", items: listItems(body) }];\n }\n for (let index = 0; index < matches.length; index += 1) {\n const match = matches[index];\n if (match === undefined) {\n continue;\n }\n const heading = match[1];\n if (heading === undefined) {\n continue;\n }\n const start = (match.index ?? 0) + match[0].length;\n const next = matches[index + 1];\n const end = next?.index ?? body.length;\n groups.push({ heading, items: listItems(body.slice(start, end)) });\n }\n return groups;\n}\n\nfunction listItems(block: string): string[] {\n const items: string[] = [];\n let current: string | undefined;\n for (const raw of block.split(\"\\n\")) {\n const trimmed = raw.trim();\n if (trimmed.startsWith(\"- \") || trimmed.startsWith(\"* \")) {\n if (current !== undefined) {\n items.push(current);\n }\n current = trimmed;\n continue;\n }\n if (current !== undefined && trimmed.length > 0 && !trimmed.startsWith(\"#\")) {\n current = `${current} ${trimmed}`;\n }\n }\n if (current !== undefined) {\n items.push(current);\n }\n return items;\n}\n\nfunction bucketForHeading(heading: string): \"features\" | \"fixes\" | \"breaking\" | undefined {\n const key = heading.trim().toLowerCase();\n if (\n key === \"added\" ||\n key === \"changed\" ||\n key === \"minor changes\" ||\n key === \"features\"\n ) {\n return \"features\";\n }\n if (key === \"fixed\" || key === \"patch changes\" || key === \"security\" || key === \"fixes\") {\n return \"fixes\";\n }\n if (\n key === \"removed\" ||\n key === \"major changes\" ||\n key === \"breaking\" ||\n key === \"breaking changes\"\n ) {\n return \"breaking\";\n }\n return undefined;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","// git source: tags, commits, contributors\n// Spec: docs/PROJECT_PLAN.md §12.1\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Fact } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\nimport { cleanChangelogItem } from \"./changelog.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function collectGit(\n cwd: string,\n event: { tag?: string; previousTag?: string },\n): Promise<PartialFacts> {\n const inside = await git(cwd, [\"rev-parse\", \"--is-inside-work-tree\"]);\n if (inside !== \"true\") {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const tag = event.tag ?? (await gitCurrentTag(cwd));\n if (tag === undefined) {\n return {};\n }\n const exists = await git(cwd, [\"rev-parse\", \"--verify\", `${tag}^{commit}`]);\n if (exists === undefined) {\n return {};\n }\n const version = versionFromTag(tag);\n const tags = await gitLines(cwd, [\"tag\", \"--sort=-v:refname\"]);\n const tagIndex = tags.indexOf(tag);\n const previousTag =\n event.previousTag ?? (tagIndex >= 0 ? tags[tagIndex + 1] : tags.find((candidate) => candidate !== tag));\n const range = previousTag === undefined ? tag : `${previousTag}..${tag}`;\n const log = await git(cwd, [\"log\", range, \"--pretty=format:%s\\t%an\\t%ae\\t%h\\t%cI\"]);\n const commits = (log ?? \"\").split(\"\\n\").filter((line) => line.length > 0);\n const features: Fact<string>[] = [];\n const fixes: Fact<string>[] = [];\n const breaking: Fact<string>[] = [];\n const contributors = new Map<string, string>();\n\n for (const line of commits) {\n const [subject, author, email, hash] = line.split(\"\\t\");\n if (subject === undefined || hash === undefined) {\n continue;\n }\n const parsed = parseConventional(subject);\n const display = parsed.display;\n const ref = `git log ${range} ${hash}`;\n const item = fact(display, { source: \"git\", ref, fetchedAt });\n if (parsed.breaking) {\n breaking.push(item);\n } else if (parsed.type === \"feat\") {\n features.push(item);\n } else if (parsed.type === \"fix\" || parsed.type === \"perf\") {\n fixes.push(item);\n }\n if (email !== undefined && author !== undefined && !isBot(author, email)) {\n contributors.set(email, author);\n }\n }\n\n const dateLine = await git(cwd, [\"log\", \"-1\", \"--format=%cI\", tag]);\n const date = (dateLine ?? fetchedAt).slice(0, 10);\n const names = [...contributors.values()];\n\n const release: NonNullable<PartialFacts[\"release\"]> = {\n version: fact(version, { source: \"git\", ref: `git tag ${tag}`, fetchedAt }),\n tag: fact(tag, { source: \"git\", ref: `git tag ${tag}`, fetchedAt }),\n date: fact(date, { source: \"git\", ref: `git log -1 --format=%cI ${tag}`, fetchedAt }),\n features,\n fixes,\n breaking,\n commitCount: fact(commits.length, {\n source: \"git\",\n ref: `git rev-list --count ${range}`,\n fetchedAt,\n }),\n };\n if (previousTag !== undefined) {\n release.previousVersion = fact(versionFromTag(previousTag), {\n source: \"git\",\n ref: `git tag ${previousTag}`,\n fetchedAt,\n });\n }\n if (names.length > 0) {\n release.contributors = fact(names, {\n source: \"git\",\n ref: `git log ${range} unique authors`,\n fetchedAt,\n });\n }\n return { release };\n}\n\nexport function parseConventional(subject: string): {\n type: string | undefined;\n display: string;\n breaking: boolean;\n} {\n const match = /^(?<type>\\w+)(?<scope>\\([^)]+\\))?(?<bang>!)?:\\s*(?<rest>.+)$/.exec(subject);\n if (match === null || match.groups === undefined) {\n return { type: undefined, display: displaySubject(subject), breaking: false };\n }\n const type = match.groups.type;\n const rest = match.groups.rest ?? subject;\n const breaking = match.groups.bang === \"!\" || /BREAKING CHANGE:/.test(subject);\n return { type, display: displaySubject(rest), breaking };\n}\n\nexport function versionFromTag(tag: string): string {\n const at = tag.lastIndexOf(\"@\");\n if (at >= 0 && at < tag.length - 1) {\n return tag.slice(at + 1).replace(/^v/, \"\");\n }\n return tag.replace(/^v/, \"\");\n}\n\nexport async function gitCurrentTag(cwd: string): Promise<string | undefined> {\n return git(cwd, [\"describe\", \"--tags\", \"--abbrev=0\"]);\n}\n\nasync function git(cwd: string, args: string[]): Promise<string | undefined> {\n try {\n const { stdout } = await execFileAsync(\"git\", args, { cwd });\n const trimmed = stdout.trim();\n return trimmed.length === 0 ? undefined : trimmed;\n } catch {\n return undefined;\n }\n}\n\nasync function gitLines(cwd: string, args: string[]): Promise<string[]> {\n const out = await git(cwd, args);\n return out === undefined ? [] : out.split(\"\\n\").filter((line) => line.length > 0);\n}\n\nfunction isBot(author: string, email: string): boolean {\n const haystack = `${author} ${email}`.toLowerCase();\n return (\n author.endsWith(\"[bot]\") ||\n haystack.includes(\"dependabot\") ||\n haystack.includes(\"renovate\") ||\n haystack.includes(\"github-actions\")\n );\n}\n\nfunction displaySubject(text: string): string {\n const cleaned = cleanChangelogItem(text);\n const first = cleaned.at(0);\n if (first === undefined) {\n return cleaned;\n }\n return first.toUpperCase() + cleaned.slice(1);\n}\n\n/**\n * Repository slug and URL from `git remote get-url origin`.\n *\n * Kept separate from `collectGit`, which returns nothing without a tag. A monorepo root\n * often has no `homepage` or `repository` in its private package.json, which left the call\n * to action falling back to the workspace name. The remote is always there.\n */\nexport async function collectGitRemote(cwd: string): Promise<PartialFacts> {\n const remote = await git(cwd, [\"remote\", \"get-url\", \"origin\"]);\n if (remote === undefined) {\n return {};\n }\n const slug = githubSlug(remote.trim());\n if (slug === undefined) {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const provenance = { source: \"git\" as const, ref: \"git remote get-url origin\", fetchedAt };\n return {\n project: {\n repo: fact(slug, provenance),\n url: fact(`https://github.com/${slug}`, provenance),\n },\n };\n}\n\nfunction githubSlug(url: string): string | undefined {\n const cleaned = url.replace(/^git\\+/, \"\").replace(/\\.git$/, \"\");\n return /github\\.com[/:]([^/]+\\/[^/]+)$/.exec(cleaned)?.[1];\n}\n","// GitHub REST via fetch (token optional)\n// Spec: docs/PROJECT_PLAN.md §12.5\n// Docs checked 2026-09-11: https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28\n// GET /repos/{owner}/{repo}\n// GET /repos/{owner}/{repo}/releases/tags/{tag}\n// GET /repos/{owner}/{repo}/contributors\n// Headers: Accept application/vnd.github+json, X-GitHub-Api-Version 2022-11-28\n\nimport { z } from \"zod\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Fact } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\n\nconst API_VERSION = \"2022-11-28\";\nconst API_ROOT = \"https://api.github.com\";\n\nconst repoSchema = z.object({\n stargazers_count: z.number().int().nonnegative(),\n description: z.string().nullable().optional(),\n homepage: z.string().nullable().optional(),\n license: z.object({ spdx_id: z.string().nullable() }).nullable().optional(),\n});\n\nconst releaseSchema = z.object({\n body: z.string().nullable().optional(),\n});\n\nconst contributorsSchema = z.array(z.unknown());\n\nexport interface GithubCacheEntry {\n json: unknown;\n link: string | null;\n}\n\nexport interface GithubCollectOptions {\n repo: string;\n tag?: string;\n token?: string;\n fetchImpl?: typeof fetch;\n cache?: Map<string, GithubCacheEntry>;\n}\n\nexport async function collectGithub(options: GithubCollectOptions): Promise<PartialFacts> {\n const slug = parseRepo(options.repo);\n if (slug === undefined) {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const fetchImpl = options.fetchImpl ?? fetch;\n const cache = options.cache ?? new Map<string, GithubCacheEntry>();\n const repoResponse = await githubGet(\n `${API_ROOT}/repos/${slug.owner}/${slug.repo}`,\n options.token,\n fetchImpl,\n cache,\n );\n if (repoResponse === undefined) {\n return {};\n }\n const repo = repoSchema.parse(repoResponse.json);\n const out: PartialFacts = {\n metrics: {\n stars: fact(repo.stargazers_count, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo} stargazers_count`,\n fetchedAt,\n }),\n },\n project: {},\n };\n if (repo.description !== undefined && repo.description !== null && repo.description.length > 0) {\n out.project = {\n ...out.project,\n tagline: fact(repo.description, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo} description`,\n fetchedAt,\n }),\n };\n }\n if (repo.homepage !== undefined && repo.homepage !== null && repo.homepage.length > 0) {\n out.project = {\n ...out.project,\n url: fact(repo.homepage, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo} homepage`,\n fetchedAt,\n }),\n };\n }\n const license = repo.license?.spdx_id;\n if (license !== undefined && license !== null && license !== \"NOASSERTION\") {\n out.project = {\n ...out.project,\n license: fact(license, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo} license.spdx_id`,\n fetchedAt,\n }),\n };\n }\n\n if (options.tag !== undefined) {\n const releaseResponse = await githubGet(\n `${API_ROOT}/repos/${slug.owner}/${slug.repo}/releases/tags/${encodeURIComponent(options.tag)}`,\n options.token,\n fetchImpl,\n cache,\n { notFoundOk: true },\n );\n if (releaseResponse !== undefined) {\n const release = releaseSchema.parse(releaseResponse.json);\n const features = featuresFromReleaseBody(release.body ?? \"\", options.tag, fetchedAt);\n if (features.length > 0) {\n out.release = { features };\n }\n }\n }\n\n const contributors = await githubGet(\n `${API_ROOT}/repos/${slug.owner}/${slug.repo}/contributors?per_page=1&anon=true`,\n options.token,\n fetchImpl,\n cache,\n { notFoundOk: true },\n );\n if (contributors !== undefined) {\n contributorsSchema.parse(contributors.json);\n const listed = Array.isArray(contributors.json) ? contributors.json.length : 0;\n const fromLink = lastPageFromLink(contributors.link);\n out.metrics = {\n ...out.metrics,\n contributorCount: fact(fromLink ?? listed, {\n source: \"github-api\",\n ref: `GET /repos/${slug.owner}/${slug.repo}/contributors`,\n fetchedAt,\n }),\n };\n }\n\n return out;\n}\n\nexport function parseRepo(value: string): { owner: string; repo: string } | undefined {\n const trimmed = value.trim().replace(/\\.git$/, \"\");\n const match = /^(?:https?:\\/\\/github\\.com\\/)?([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+)$/.exec(trimmed);\n if (match === null || match[1] === undefined || match[2] === undefined) {\n return undefined;\n }\n return { owner: match[1], repo: match[2] };\n}\n\nfunction featuresFromReleaseBody(body: string, tag: string, fetchedAt: string): Fact<string>[] {\n const lines = body\n .split(\"\\n\")\n .map((line) => line.replace(/^\\s*[-*]\\s*/, \"\").trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n return lines.slice(0, 8).map((line) =>\n fact(line.replace(/\\.$/, \"\"), {\n source: \"github-api\",\n ref: `GET /repos/.../releases/tags/${tag} body`,\n fetchedAt,\n }),\n );\n}\n\nasync function githubGet(\n url: string,\n token: string | undefined,\n fetchImpl: typeof fetch,\n cache: Map<string, GithubCacheEntry>,\n opts: { notFoundOk?: boolean } = {},\n): Promise<GithubCacheEntry | undefined> {\n const cached = cache.get(url);\n if (cached !== undefined) {\n return cached;\n }\n const headers: Record<string, string> = {\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": API_VERSION,\n \"User-Agent\": \"shipseal\",\n };\n if (token !== undefined && token.length > 0) {\n headers.Authorization = `Bearer ${token}`;\n }\n let response: Response;\n try {\n response = await fetchImpl(url, { headers });\n } catch (error) {\n throw new ShipsealError(\n \"github.network\",\n \"Could not reach the GitHub API.\",\n \"Check network access, then retry. Unauthenticated calls are optional; facts still come from git and package.json.\",\n { cause: error },\n );\n }\n if (response.status === 404 && opts.notFoundOk === true) {\n return undefined;\n }\n if (response.status === 403 || response.status === 429) {\n throw new ShipsealError(\n \"github.rate-limit\",\n \"GitHub API rate limit exceeded.\",\n \"Set GITHUB_TOKEN in the environment to raise the limit, then retry.\",\n );\n }\n if (!response.ok) {\n throw new ShipsealError(\n \"github.http\",\n `GitHub API returned HTTP ${String(response.status)} for ${url}.`,\n \"Confirm the repository exists and GITHUB_TOKEN can read it.\",\n );\n }\n const json: unknown = await response.json();\n const entry: GithubCacheEntry = { json, link: response.headers.get(\"link\") };\n cache.set(url, entry);\n return entry;\n}\n\nfunction lastPageFromLink(link: string | null): number | undefined {\n if (link === null) {\n return undefined;\n }\n const match = /[?&]page=(\\d+)>;\\s*rel=\"last\"/.exec(link);\n if (match === null || match[1] === undefined) {\n return undefined;\n }\n return Number.parseInt(match[1], 10);\n}\n","// npm weekly downloads\n// Spec: docs/PROJECT_PLAN.md §12.6\n// Docs checked 2026-09-11: https://github.com/npm/registry/blob/main/docs/download-counts.md\n// GET https://api.npmjs.org/downloads/point/{period}/{package}\n// period last-week. Scoped names are URL-encoded (@scope/pkg -> %40scope%2Fpkg).\n// 404 means the package is unpublished or unknown: return nothing.\n\nimport { z } from \"zod\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\n\nconst API_ROOT = \"https://api.npmjs.org/downloads/point/last-week\";\n\nconst pointSchema = z.object({\n downloads: z.number().int().nonnegative(),\n start: z.string().optional(),\n end: z.string().optional(),\n package: z.string().optional(),\n});\n\nexport interface NpmCollectOptions {\n npmPackage: string;\n fetchImpl?: typeof fetch;\n cache?: Map<string, unknown>;\n}\n\nexport async function collectNpm(options: NpmCollectOptions): Promise<PartialFacts> {\n const name = options.npmPackage.trim();\n if (name.length === 0) {\n return {};\n }\n const url = `${API_ROOT}/${encodeURIComponent(name)}`;\n const cache = options.cache ?? new Map<string, unknown>();\n const cached = cache.get(url);\n const json = cached ?? (await npmGet(url, options.fetchImpl ?? fetch, cache));\n if (json === undefined) {\n return {};\n }\n const point = pointSchema.parse(json);\n return {\n metrics: {\n weeklyDownloads: fact(point.downloads, {\n source: \"npm-api\",\n ref: `GET /downloads/point/last-week/${name} downloads`,\n fetchedAt: new Date().toISOString(),\n }),\n },\n };\n}\n\nasync function npmGet(\n url: string,\n fetchImpl: typeof fetch,\n cache: Map<string, unknown>,\n): Promise<unknown | undefined> {\n let response: Response;\n try {\n response = await fetchImpl(url, { headers: { Accept: \"application/json\", \"User-Agent\": \"shipseal\" } });\n } catch (error) {\n throw new ShipsealError(\n \"npm.network\",\n \"Could not reach the npm downloads API.\",\n \"Check network access, then retry. Weekly downloads are optional; other facts still render.\",\n { cause: error },\n );\n }\n if (response.status === 404) {\n return undefined;\n }\n if (response.status === 403 || response.status === 429) {\n throw new ShipsealError(\n \"npm.rate-limit\",\n \"npm downloads API rate limit exceeded.\",\n \"Wait and retry. Milestone cards can still use stars and contributors without downloads.\",\n );\n }\n if (!response.ok) {\n throw new ShipsealError(\n \"npm.http\",\n `npm downloads API returned HTTP ${String(response.status)} for ${url}.`,\n \"Confirm the package name in package.json is published on npm.\",\n );\n }\n const json: unknown = await response.json();\n cache.set(url, json);\n return json;\n}\n","// package.json source\n// Spec: docs/PROJECT_PLAN.md §12.2\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { fact } from \"../facts/fact.js\";\nimport type { PartialFacts, PartialProject } from \"../facts/partial.js\";\n\nconst pkgSchema = z.object({\n private: z.boolean().optional(),\n name: z.string().optional(),\n description: z.string().optional(),\n version: z.string().optional(),\n homepage: z.string().optional(),\n license: z.string().optional(),\n repository: z.union([z.string(), z.object({ url: z.string().optional() })]).optional(),\n});\n\nexport async function collectPackageJson(\n cwd: string,\n packagePath = \"package.json\",\n): Promise<PartialFacts> {\n const path = join(cwd, packagePath);\n let raw: string;\n try {\n raw = await readFile(path, \"utf8\");\n } catch {\n return {};\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return {};\n }\n const pkg = pkgSchema.safeParse(parsed);\n if (!pkg.success) {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const project: PartialProject = {\n name: fact(stripScope(pkg.data.name ?? basenameFromPath(cwd)), {\n source: \"package-json\",\n ref: `${packagePath}#name`,\n fetchedAt,\n }),\n };\n if (pkg.data.description !== undefined && pkg.data.description.length > 0) {\n project.tagline = fact(pkg.data.description, {\n source: \"package-json\",\n ref: `${packagePath}#description`,\n fetchedAt,\n });\n }\n const url = pkg.data.homepage ?? repositoryUrl(pkg.data.repository);\n if (url !== undefined) {\n project.url = fact(url, {\n source: \"package-json\",\n ref: pkg.data.homepage !== undefined ? `${packagePath}#homepage` : `${packagePath}#repository`,\n fetchedAt,\n });\n }\n const repo = repoSlug(pkg.data.repository);\n if (repo !== undefined) {\n project.repo = fact(repo, {\n source: \"package-json\",\n ref: `${packagePath}#repository`,\n fetchedAt,\n });\n }\n // A private package is never on npm. Taking its name put \"npm i shipseal-monorepo\" on a\n // real release card, telling people to install a package that does not exist.\n if (pkg.data.name !== undefined && pkg.data.private !== true) {\n project.npmPackage = fact(pkg.data.name, {\n source: \"package-json\",\n ref: `${packagePath}#name`,\n fetchedAt,\n });\n }\n if (pkg.data.license !== undefined) {\n project.license = fact(pkg.data.license, {\n source: \"package-json\",\n ref: `${packagePath}#license`,\n fetchedAt,\n });\n }\n\n const out: PartialFacts = { project };\n if (pkg.data.version !== undefined) {\n out.release = {\n version: fact(pkg.data.version.replace(/^v/, \"\"), {\n source: \"package-json\",\n ref: `${packagePath}#version`,\n fetchedAt,\n }),\n };\n }\n return out;\n}\n\nfunction stripScope(name: string): string {\n const parts = name.split(\"/\");\n return parts[parts.length - 1] ?? name;\n}\n\nfunction basenameFromPath(cwd: string): string {\n const parts = cwd.split(/[/\\\\]/).filter((part) => part.length > 0);\n return parts[parts.length - 1] ?? \"project\";\n}\n\nfunction repositoryUrl(repository: z.infer<typeof pkgSchema>[\"repository\"]): string | undefined {\n if (typeof repository === \"string\") {\n return normalizeGitUrl(repository);\n }\n if (repository?.url !== undefined) {\n return normalizeGitUrl(repository.url);\n }\n return undefined;\n}\n\nfunction repoSlug(repository: z.infer<typeof pkgSchema>[\"repository\"]): string | undefined {\n const url = repositoryUrl(repository);\n if (url === undefined) {\n return undefined;\n }\n const match = /github\\.com[/:]([^/]+\\/[^/]+)$/.exec(url.replace(/\\.git$/, \"\"));\n return match?.[1];\n}\n\n// npm allows shorthand repository strings: \"owner/repo\", \"github:owner/repo\",\n// and the other hosts' prefixes. Expand the GitHub ones so repoSlug and the\n// GitHub source see a real URL. Without this, `milestone` could not read stars\n// for any project using the shorthand, which is the most common form.\nconst SHORTHAND = /^(?:github:)?([\\w.-]+\\/[\\w.-]+)$/;\n\nfunction normalizeGitUrl(url: string): string {\n const shorthand = SHORTHAND.exec(url);\n if (shorthand?.[1] !== undefined) {\n return `https://github.com/${shorthand[1].replace(/\\.git$/, \"\")}`;\n }\n const ssh = /^git@([^:]+):(.+)$/.exec(url);\n if (ssh !== null && ssh[1] !== undefined && ssh[2] !== undefined) {\n return `https://${ssh[1]}/${ssh[2].replace(/\\.git$/, \"\")}`;\n }\n return url.replace(/^git\\+/, \"\").replace(/\\.git$/, \"\");\n}\n","// README source: title, tagline, first fenced code block\n// Spec: docs/PROJECT_PLAN.md §12.3\n\nimport { readFile } from \"node:fs/promises\";\nimport { extname, join } from \"node:path\";\nimport { fact } from \"../facts/fact.js\";\nimport type { PartialFacts, PartialProject } from \"../facts/partial.js\";\n\nexport async function collectReadme(cwd: string): Promise<PartialFacts> {\n let markdown: string;\n try {\n markdown = await readFile(join(cwd, \"README.md\"), \"utf8\");\n } catch {\n return {};\n }\n const fetchedAt = new Date().toISOString();\n const out: PartialFacts = {};\n const h1 = extractH1(markdown);\n const tagline = extractTagline(markdown);\n const snippet = extractFirstCodeFence(markdown);\n\n const project: PartialProject = {};\n if (h1 !== undefined) {\n project.name = fact(h1, { source: \"readme\", ref: \"README.md H1\", fetchedAt });\n }\n if (tagline !== undefined) {\n project.tagline = fact(tagline, {\n source: \"readme\",\n ref: \"README.md first paragraph\",\n fetchedAt,\n });\n }\n if (project.name !== undefined || project.tagline !== undefined) {\n out.project = project;\n }\n if (snippet !== undefined) {\n out.release = {\n codeSnippet: fact(snippet, {\n source: \"readme\",\n ref: \"README.md first fenced code block\",\n fetchedAt,\n }),\n };\n }\n return out;\n}\n\nexport async function collectConfiguredSnippet(\n cwd: string,\n spec: string,\n): Promise<PartialFacts> {\n const parsed = parseSnippetSpec(spec);\n if (parsed === undefined) {\n return {};\n }\n let contents: string;\n try {\n contents = await readFile(join(cwd, parsed.path), \"utf8\");\n } catch {\n return {};\n }\n const lines = contents.split(/\\r?\\n/);\n const slice = lines.slice(parsed.start - 1, parsed.end).join(\"\\n\");\n const fetchedAt = new Date().toISOString();\n return {\n release: {\n codeSnippet: fact(\n { code: slice, lang: langFromPath(parsed.path) },\n { source: \"user-config\", ref: spec, fetchedAt },\n ),\n },\n };\n}\n\n/**\n * Strip fenced code and HTML before reading prose out of a README.\n *\n * Skipping blocks that merely *start* with a fence is not enough. A `#` comment inside a YAML\n * example reads as a markdown H1, and a blank line inside a fence makes its body look like a\n * paragraph. Shipseal's own README hit both: the detected name became\n * \".github/workflows/shipseal.yml\" and the tagline became a chunk of workflow YAML.\n */\nfunction stripNonProse(markdown: string): string {\n return markdown\n .replace(/```[\\s\\S]*?```/g, \"\")\n .replace(/~~~[\\s\\S]*?~~~/g, \"\")\n .replace(/<[^>]+>/g, \"\");\n}\n\nexport function extractH1(markdown: string): string | undefined {\n const match = /^#\\s+(.+)$/m.exec(stripNonProse(markdown));\n const heading = match?.[1];\n if (heading === undefined) {\n return undefined;\n }\n return heading.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\").trim();\n}\n\nexport function extractTagline(markdown: string): string | undefined {\n const prose = stripNonProse(markdown);\n const h1 = /^#\\s+.+$/m.exec(prose);\n const start = h1 === null ? 0 : (h1.index ?? 0) + h1[0].length;\n for (const block of prose.slice(start).split(/\\n\\s*\\n/)) {\n const cleaned = stripBadges(block).trim();\n if (cleaned.length >= 20 && !cleaned.startsWith(\"#\") && !cleaned.startsWith(\"```\")) {\n return cleaned;\n }\n }\n return undefined;\n}\n\nexport function extractFirstCodeFence(markdown: string): { code: string; lang: string } | undefined {\n const match = /```([a-zA-Z0-9+-]+)\\n([\\s\\S]*?)```/.exec(markdown);\n if (match === null || match[1] === undefined || match[2] === undefined) {\n return undefined;\n }\n return { lang: match[1], code: match[2].replace(/\\n$/, \"\") };\n}\n\nfunction parseSnippetSpec(spec: string): { path: string; start: number; end: number } | undefined {\n const match = /^(?<path>.+)#L(?<start>\\d+)(?:-L(?<end>\\d+))?$/.exec(spec);\n if (match === null || match.groups === undefined) {\n return undefined;\n }\n const path = match.groups.path;\n const start = Number.parseInt(match.groups.start ?? \"0\", 10);\n const end = Number.parseInt(match.groups.end ?? match.groups.start ?? \"0\", 10);\n if (path === undefined || start < 1 || end < start) {\n return undefined;\n }\n return { path, start, end };\n}\n\nfunction langFromPath(path: string): string {\n const ext = extname(path).replace(\".\", \"\");\n if (ext === \"ts\") {\n return \"ts\";\n }\n if (ext === \"tsx\") {\n return \"tsx\";\n }\n if (ext === \"js\" || ext === \"mjs\" || ext === \"cjs\") {\n return \"js\";\n }\n if (ext === \"jsx\") {\n return \"jsx\";\n }\n return ext.length > 0 ? ext : \"text\";\n}\n\nfunction stripBadges(text: string): string {\n return text\n .replace(/\\[!\\[[^\\]]*]\\([^)]+\\)]\\([^)]+\\)/g, \"\")\n .replace(/!\\[[^\\]]*]\\([^)]+\\)/g, \"\")\n .replace(/<img[^>]*>/gi, \"\")\n .replace(/<[^>]+>/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","// Orchestrate collectors into one Facts object\n// Spec: docs/PROJECT_PLAN.md §12\n\nimport { readdir } from \"node:fs/promises\";\nimport type { Dirent } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { mergeFacts } from \"../facts/merge.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { PartialFacts } from \"../facts/partial.js\";\nimport { collectBenchFile } from \"./bench-file.js\";\nimport { collectChangelog } from \"./changelog.js\";\nimport { collectGit, collectGitRemote, versionFromTag } from \"./git.js\";\nimport { collectGithub } from \"./github.js\";\nimport { collectNpm } from \"./npm.js\";\nimport { collectPackageJson } from \"./package-json.js\";\nimport { collectConfiguredSnippet, collectReadme } from \"./readme.js\";\n\nexport interface CollectOptions {\n cwd: string;\n event: ShipsealEvent;\n packagePath?: string;\n changelogPath?: string;\n snippet?: string | null;\n benchFile?: string;\n githubToken?: string;\n fetchImpl?: typeof fetch;\n skipNetwork?: boolean;\n}\n\nexport async function collectFacts(options: CollectOptions): Promise<Facts> {\n const pkg = await collectPackageJson(options.cwd, options.packagePath ?? \"package.json\");\n const tag = options.event.kind === \"release\" ? options.event.tag : undefined;\n const previousTag = options.event.kind === \"release\" ? options.event.previousTag : undefined;\n const gitEvent: { tag?: string; previousTag?: string } = {};\n if (tag !== undefined) {\n gitEvent.tag = tag;\n }\n if (previousTag !== undefined) {\n gitEvent.previousTag = previousTag;\n }\n const git = await collectGit(options.cwd, gitEvent);\n const version =\n git.release?.version?.value ??\n pkg.release?.version?.value ??\n (tag === undefined ? undefined : versionFromTag(tag));\n const remote = await collectGitRemote(options.cwd);\n const changelog = await collectBestChangelog(\n options.cwd,\n version,\n options.changelogPath ?? \"CHANGELOG.md\",\n options.packagePath,\n );\n const readme = await collectReadme(options.cwd);\n const snippet =\n options.snippet !== undefined && options.snippet !== null && options.snippet.length > 0\n ? await collectConfiguredSnippet(options.cwd, options.snippet)\n : {};\n\n // The remote goes first so an explicit package.json homepage or repository still wins.\n const parts: PartialFacts[] = [remote, pkg, git, readme, changelog, snippet];\n\n if (options.event.kind === \"bench\") {\n parts.push(await collectBenchFile(options.cwd, options.benchFile ?? \".shipseal/bench.json\"));\n }\n\n if (options.skipNetwork !== true) {\n const repo = pkg.project?.repo?.value ?? gitRepoFromParts(pkg, readme);\n if (repo !== undefined) {\n const githubOpts: Parameters<typeof collectGithub>[0] = { repo };\n const githubTag = git.release?.tag?.value ?? tag;\n if (githubTag !== undefined) {\n githubOpts.tag = githubTag;\n }\n if (options.githubToken !== undefined) {\n githubOpts.token = options.githubToken;\n }\n if (options.fetchImpl !== undefined) {\n githubOpts.fetchImpl = options.fetchImpl;\n }\n const github = await collectGithub(githubOpts);\n const githubWithoutFeatures: PartialFacts = {};\n if (github.project !== undefined) {\n githubWithoutFeatures.project = github.project;\n }\n if (github.metrics !== undefined) {\n githubWithoutFeatures.metrics = github.metrics;\n }\n parts.push(githubWithoutFeatures);\n const mergedPreview = mergeFacts(parts);\n if (\n options.event.kind === \"release\" &&\n (mergedPreview.release?.features.length ?? 0) === 0 &&\n github.release?.features !== undefined &&\n github.release.features.length > 0\n ) {\n parts.push({ release: { features: github.release.features } });\n }\n }\n const npmPackage = pkg.project?.npmPackage?.value;\n if (npmPackage !== undefined) {\n const npmOpts: Parameters<typeof collectNpm>[0] = { npmPackage };\n if (options.fetchImpl !== undefined) {\n npmOpts.fetchImpl = options.fetchImpl;\n }\n parts.push(await collectNpm(npmOpts));\n }\n }\n\n const facts = mergeFacts(parts);\n if (options.event.kind === \"release\" && facts.release === undefined) {\n throw new ShipsealError(\n \"facts.missing-release\",\n \"Could not collect release facts.\",\n \"Create a git tag, pass --tag, or add a matching version section to CHANGELOG.md.\",\n );\n }\n return facts;\n}\n\nasync function collectBestChangelog(\n cwd: string,\n version: string | undefined,\n changelogPath: string,\n packagePath: string | undefined,\n): Promise<PartialFacts> {\n const paths = [changelogPath];\n if (packagePath !== undefined) {\n const sibling = join(dirname(packagePath), \"CHANGELOG.md\");\n if (!paths.includes(sibling)) {\n paths.push(sibling);\n }\n }\n const collected = await Promise.all(paths.map((path) => collectChangelog(cwd, version, path)));\n const found = collected.find((facts) => changelogHasNotes(facts));\n if (found !== undefined) {\n return found;\n }\n\n // Monorepos keep the changelog beside the package, not at the repo root, and Changesets\n // writes it there. Without this, `release` on a workspace root silently fell back to raw\n // commit subjects even though a perfectly good changelog existed one directory down.\n const candidates = await workspaceChangelogs(cwd);\n const fromWorkspace = await Promise.all(\n candidates.map((candidate) => collectChangelog(cwd, version, candidate)),\n );\n return fromWorkspace.find((facts) => changelogHasNotes(facts)) ?? {};\n}\n\nasync function workspaceChangelogs(cwd: string): Promise<string[]> {\n const roots = [\"packages\", \"apps\"];\n const listings = await Promise.all(\n roots.map(async (root) => {\n let entries: Dirent[];\n try {\n entries = await readdir(join(cwd, root), { withFileTypes: true });\n } catch {\n return [];\n }\n return entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => join(root, entry.name, \"CHANGELOG.md\"));\n }),\n );\n return listings.flat().toSorted();\n}\n\nfunction changelogHasNotes(facts: PartialFacts): boolean {\n const release = facts.release;\n if (release === undefined) {\n return false;\n }\n return (\n (release.features?.length ?? 0) > 0 ||\n (release.fixes?.length ?? 0) > 0 ||\n (release.breaking?.length ?? 0) > 0\n );\n}\n\nfunction gitRepoFromParts(pkg: PartialFacts, readme: PartialFacts): string | undefined {\n return pkg.project?.repo?.value ?? pkg.project?.url?.value ?? readme.project?.url?.value;\n}\n","// ONLY file allowed to import Takumi (Rule R4). Verify API first (spike S1)\n// Spec: docs/PROJECT_PLAN.md §16\n// Docs checked 2026-09-11: https://takumi.kane.tw/docs , /docs/measure-api, /docs/typography-and-fonts, /docs/helpers\n\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Renderer, type Node } from \"takumi-js/node\";\nimport { container, text as textNode } from \"takumi-js/helpers\";\nimport { fromJsx as takumiFromJsx } from \"takumi-js/helpers/jsx\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport type {\n LayoutNode,\n MeasureOptions,\n MeasureResult,\n MeasureTextOptions,\n RenderOptions,\n RendererAdapter,\n} from \"./adapter.js\";\n\nexport const GEIST_MONO_FAMILY = \"Geist Mono\";\nconst FONT_REL = join(\"assets\", \"fonts\", \"GeistMono[wght].ttf\");\n\nlet shared: Promise<RendererAdapter> | undefined;\n\nexport function getTakumiRenderer(): Promise<RendererAdapter> {\n shared ??= createTakumiRenderer();\n return shared;\n}\n\nexport async function createTakumiRenderer(): Promise<RendererAdapter> {\n const renderer = new Renderer();\n const fontPath = join(resolvePackageRoot(), FONT_REL);\n const data = await readFile(fontPath);\n await renderer.registerFont({\n name: GEIST_MONO_FAMILY,\n data,\n generic: \"monospace\",\n });\n return new TakumiRenderer(renderer);\n}\n\nexport function resolvePackageRoot(from = import.meta.url): string {\n let dir = dirname(fileURLToPath(from));\n for (;;) {\n if (existsSync(join(dir, \"package.json\")) && existsSync(join(dir, FONT_REL))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n throw new ShipsealError(\n \"render.font-missing\",\n `Could not find vendored font ${FONT_REL}.`,\n \"Reinstall shipseal so assets/fonts/GeistMono[wght].ttf is present next to package.json.\",\n );\n }\n dir = parent;\n }\n}\n\nexport interface LineCountNode {\n runs: ReadonlyArray<{ y: number }>;\n children: readonly LineCountNode[];\n}\n\nexport function countLines(node: LineCountNode): number {\n const ys = new Set<number>();\n const walk = (current: LineCountNode): void => {\n for (const run of current.runs) {\n ys.add(Math.round(run.y));\n }\n for (const child of current.children) {\n walk(child);\n }\n };\n walk(node);\n return ys.size;\n}\n\nexport function testCardNode(): LayoutNode {\n return container({\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n padding: 64,\n backgroundColor: \"#0b0b0c\",\n },\n children: [\n textNode(\"Shipseal\", {\n fontFamily: \"Geist\",\n fontSize: 72,\n fontWeight: 700,\n color: \"#fafafa\",\n }),\n textNode(\"Every release, sealed and ready to share\", {\n fontFamily: GEIST_MONO_FAMILY,\n fontSize: 28,\n fontWeight: 400,\n color: \"#a1a1aa\",\n }),\n ],\n });\n}\n\nclass TakumiRenderer implements RendererAdapter {\n constructor(private readonly renderer: Renderer) {}\n\n async fromJsx(element: unknown): Promise<LayoutNode> {\n const result = await takumiFromJsx(asReactElementLike(element));\n return pack(result.node, result.css);\n }\n\n async render(node: LayoutNode, opts: RenderOptions): Promise<Uint8Array> {\n const packed = unpack(node);\n const extras: { css: string[]; images?: RenderOptions[\"images\"] } = {\n css: opts.css ?? packed.css,\n };\n if (opts.images !== undefined) {\n extras.images = opts.images;\n }\n const buffer = await renderWithFormat(this.renderer, packed.node, opts, extras);\n return Uint8Array.from(buffer);\n }\n\n async measure(node: LayoutNode, opts?: MeasureOptions): Promise<MeasureResult> {\n const packed = unpack(node);\n const measured = await this.renderer.measure(packed.node, measureOpts(opts));\n return {\n lines: countLines(measured),\n width: measured.width,\n height: measured.height,\n };\n }\n\n async measureText(value: string, opts: MeasureTextOptions): Promise<MeasureResult> {\n const measured = await this.renderer.measure(asNode(textMeasureNode(value, opts)));\n return {\n lines: countLines(measured),\n width: measured.width,\n height: measured.height,\n };\n }\n}\n\nfunction renderWithFormat(\n renderer: Renderer,\n node: Node,\n opts: RenderOptions,\n extras: { css: string[]; images?: RenderOptions[\"images\"] },\n): Promise<Buffer> {\n const width = opts.width;\n const height = opts.height;\n const css = extras.css;\n const images = extras.images;\n if (opts.format === \"webp\") {\n if (images !== undefined) {\n return renderer.render(node, { width, height, format: \"webp\", css, images });\n }\n return renderer.render(node, { width, height, format: \"webp\", css });\n }\n if (opts.format === \"jpeg\") {\n if (images !== undefined) {\n return renderer.render(node, { width, height, format: \"jpeg\", css, images });\n }\n return renderer.render(node, { width, height, format: \"jpeg\", css });\n }\n if (images !== undefined) {\n return renderer.render(node, { width, height, format: \"png\", css, images });\n }\n return renderer.render(node, { width, height, format: \"png\", css });\n}\n\nfunction measureOpts(opts?: MeasureOptions): { width?: number; height?: number } {\n const out: { width?: number; height?: number } = {};\n if (opts?.width !== undefined) {\n out.width = opts.width;\n }\n if (opts?.height !== undefined) {\n out.height = opts.height;\n }\n return out;\n}\n\nfunction textMeasureNode(value: string, opts: MeasureTextOptions): LayoutNode {\n const style: {\n fontFamily: string;\n fontSize: number;\n lineHeight: number;\n whiteSpace: \"normal\" | \"pre\";\n maxWidth: number;\n fontWeight?: number;\n } = {\n fontFamily: opts.fontFamily,\n fontSize: opts.fontSize,\n lineHeight: opts.lineHeight,\n whiteSpace: opts.whiteSpace ?? \"normal\",\n maxWidth: opts.maxWidth,\n };\n if (opts.fontWeight !== undefined) {\n style.fontWeight = opts.fontWeight;\n }\n return textNode(value, style);\n}\n\nfunction asNode(node: LayoutNode): Node {\n return unpack(node).node;\n}\n\ntype PackedLayout = { readonly __shipseal: true; node: Node; css: string[] };\n\nfunction pack(node: Node, css: string[] = []): LayoutNode {\n const packed: PackedLayout = { __shipseal: true, node, css };\n return packed;\n}\n\nfunction unpack(node: LayoutNode): PackedLayout {\n if (isPacked(node)) {\n return node;\n }\n if (isTakumiNode(node)) {\n return { __shipseal: true, node, css: [] };\n }\n throw new ShipsealError(\n \"render.invalid-node\",\n \"render/measure received a value that is not a Takumi node tree.\",\n \"Pass a node built by the renderer adapter (fromJsx, measureText, or testCardNode).\",\n );\n}\n\nfunction isPacked(node: LayoutNode): node is PackedLayout {\n return typeof node === \"object\" && node !== null && \"__shipseal\" in node;\n}\n\nfunction isTakumiNode(node: LayoutNode): node is Node {\n return typeof node === \"object\" && node !== null && \"type\" in node;\n}\n\nfunction asReactElementLike(element: unknown): { type: unknown; props: unknown; key: string | null } {\n if (typeof element !== \"object\" || element === null || !(\"type\" in element)) {\n throw new ShipsealError(\n \"render.invalid-jsx\",\n \"fromJsx received a value that is not a JSX element.\",\n \"Return JSX from a template render function.\",\n );\n }\n const record = element;\n const type = \"type\" in record ? record.type : undefined;\n const props = \"props\" in record ? record.props : null;\n const key = \"key\" in record && typeof record.key === \"string\" ? record.key : null;\n return { type, props, key };\n}\n","// Rule R1: reject any digits not from facts\n// Spec: docs/PROJECT_PLAN.md §13.3\n\nimport type { Facts } from \"../facts/schema.js\";\nimport type { Copy } from \"./slots.js\";\n\nexport function allowedNumbers(facts: Facts): Set<string> {\n const allowed = new Set<string>();\n const visit = (value: unknown): void => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n addNumber(allowed, value);\n return;\n }\n if (typeof value === \"string\") {\n for (const match of value.match(/\\d+(?:\\.\\d+)*/g) ?? []) {\n allowed.add(match);\n }\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n visit(item);\n }\n return;\n }\n if (typeof value === \"object\" && value !== null) {\n if (\"value\" in value && \"provenance\" in value) {\n visit(value.value);\n return;\n }\n for (const nested of Object.values(value)) {\n visit(nested);\n }\n }\n };\n visit(facts);\n return allowed;\n}\n\nexport function unsourcedDigits(text: string, allowed: Set<string>): string[] {\n const found: string[] = [];\n const withoutGrouped = text.replace(/\\d{1,3}(?:,\\d{3})+/g, (match) => {\n const compact = match.replaceAll(\",\", \"\");\n if (!allowed.has(match) && !allowed.has(compact)) {\n found.push(match);\n }\n return \" \";\n });\n for (const match of withoutGrouped.match(/\\d+(?:\\.\\d+)*/g) ?? []) {\n if (!allowed.has(match)) {\n found.push(match);\n }\n }\n return found;\n}\n\nexport function guardCopy(copy: Copy, facts: Facts): { ok: true } | { ok: false; slot: string; digits: string[] } {\n const allowed = allowedNumbers(facts);\n const slots: Array<[string, string]> = [\n [\"headline\", copy.headline],\n [\"subheadline\", copy.subheadline],\n [\"cta\", copy.cta],\n ];\n if (copy.milestoneLine !== undefined) {\n slots.push([\"milestoneLine\", copy.milestoneLine]);\n }\n copy.highlights.forEach((line, index) => {\n slots.push([`highlights[${String(index)}]`, line]);\n });\n for (const [slot, text] of slots) {\n const digits = unsourcedDigits(text, allowed);\n if (digits.length > 0) {\n return { ok: false, slot, digits };\n }\n }\n return { ok: true };\n}\n\nfunction addNumber(allowed: Set<string>, value: number): void {\n allowed.add(String(value));\n if (Number.isInteger(value)) {\n allowed.add(value.toLocaleString(\"en-US\"));\n }\n}\n","// Optional LLM copy via OpenAI-compatible fetch (BYOK, no extra SDK)\n// Spec: docs/PROJECT_PLAN.md §13.3\n\nimport { z } from \"zod\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { COPY_LIMITS, MAX_HIGHLIGHTS, type Copy } from \"./slots.js\";\nimport { deterministicCopy } from \"./deterministic.js\";\nimport { guardCopy } from \"./number-guard.js\";\n\nconst llmCopySchema = z.object({\n headline: z.string(),\n subheadline: z.string(),\n highlights: z.array(z.string()).max(MAX_HIGHLIGHTS),\n cta: z.string(),\n});\n\nexport interface LlmCopyOptions {\n apiKey: string;\n model: string;\n maxRetries: number;\n baseUrl?: string;\n fetchImpl?: typeof fetch;\n}\n\nexport async function llmCopy(\n facts: Facts,\n options: LlmCopyOptions,\n fallback = deterministicCopy(facts),\n): Promise<{ copy: Copy; mode: \"llm\" | \"deterministic\"; warning?: string }> {\n const payload = factsForLlm(facts);\n let lastError: string | undefined;\n const retries = Math.max(0, options.maxRetries);\n for (let attempt = 0; attempt <= retries; attempt += 1) {\n let parsed: z.infer<typeof llmCopySchema>;\n try {\n // Sequential retries are required: each attempt depends on the previous rejection.\n // eslint-disable-next-line no-await-in-loop\n const raw = await requestCopy(payload, options);\n parsed = llmCopySchema.parse(JSON.parse(raw));\n } catch (error) {\n lastError = error instanceof Error ? error.message : \"LLM request failed\";\n continue;\n }\n const expanded = expandPlaceholders(parsed, facts);\n const styled: Copy = {\n headline: stripStyle(expanded.headline).slice(0, COPY_LIMITS.headline),\n subheadline: stripStyle(expanded.subheadline).slice(0, COPY_LIMITS.subheadline),\n highlights: expanded.highlights.map((line) => stripStyle(line).slice(0, COPY_LIMITS.highlight)),\n cta: stripStyle(expanded.cta).slice(0, COPY_LIMITS.cta),\n };\n const guarded = guardCopy(styled, facts);\n if (!guarded.ok) {\n lastError = `Number guard rejected ${guarded.slot}: ${guarded.digits.join(\", \")}`;\n continue;\n }\n return { copy: styled, mode: \"llm\" };\n }\n return {\n copy: fallback,\n mode: \"deterministic\",\n warning: lastError ?? \"LLM copy failed; using deterministic copy\",\n };\n}\n\nfunction factsForLlm(facts: Facts): Record<string, unknown> {\n return {\n project: {\n name: facts.project.name.value,\n tagline: facts.project.tagline?.value,\n npmPackage: facts.project.npmPackage?.value,\n url: facts.project.url?.value,\n },\n release: facts.release === undefined\n ? undefined\n : {\n version: \"{version}\",\n features: facts.release.features.map((item) => item.value),\n fixes: facts.release.fixes.map((item) => item.value),\n breaking: facts.release.breaking.map((item) => item.value),\n },\n metrics: {\n stars: facts.metrics?.stars === undefined ? undefined : \"{stars}\",\n weeklyDownloads: facts.metrics?.weeklyDownloads === undefined ? undefined : \"{weeklyDownloads}\",\n contributorCount: facts.metrics?.contributorCount === undefined ? undefined : \"{contributorCount}\",\n },\n };\n}\n\nfunction expandPlaceholders(copy: z.infer<typeof llmCopySchema>, facts: Facts): z.infer<typeof llmCopySchema> {\n const map: Record<string, string> = {\n \"{version}\": facts.release?.version.value ?? \"\",\n \"{stars}\": facts.metrics?.stars === undefined ? \"\" : formatCount(facts.metrics.stars.value),\n \"{weeklyDownloads}\":\n facts.metrics?.weeklyDownloads === undefined ? \"\" : formatCount(facts.metrics.weeklyDownloads.value),\n \"{contributorCount}\":\n facts.metrics?.contributorCount === undefined ? \"\" : formatCount(facts.metrics.contributorCount.value),\n };\n const expand = (text: string): string => {\n let out = text;\n for (const [token, value] of Object.entries(map)) {\n out = out.replaceAll(token, value);\n }\n return out;\n };\n return {\n headline: expand(copy.headline),\n subheadline: expand(copy.subheadline),\n highlights: copy.highlights.map(expand),\n cta: expand(copy.cta),\n };\n}\n\nfunction stripStyle(text: string): string {\n return text.replaceAll(\"\\u2014\", \":\").replaceAll(\"\\u2013\", \"-\").replaceAll(\"!\", \".\");\n}\n\nfunction formatCount(value: number): string {\n return value.toLocaleString(\"en-US\");\n}\n\nasync function requestCopy(facts: Record<string, unknown>, options: LlmCopyOptions): Promise<string> {\n const base = (options.baseUrl ?? \"https://api.openai.com/v1\").replace(/\\/$/, \"\");\n const fetchImpl = options.fetchImpl ?? fetch;\n const response = await fetchImpl(`${base}/chat/completions`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${options.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n model: options.model,\n response_format: { type: \"json_object\" },\n messages: [\n {\n role: \"system\",\n content:\n \"Write short release-card copy as JSON with keys headline, subheadline, highlights, cta. No em dashes, no exclamation marks. Use placeholders like {version} for numbers. Never invent numbers.\",\n },\n { role: \"user\", content: JSON.stringify(facts) },\n ],\n }),\n });\n if (!response.ok) {\n throw new ShipsealError(\n \"copy.llm-http\",\n `LLM provider returned HTTP ${String(response.status)}.`,\n \"Check SHIPSEAL_LLM_API_KEY, copy.model, and SHIPSEAL_LLM_BASE_URL.\",\n );\n }\n const json: unknown = await response.json();\n const message = z\n .object({\n choices: z.array(z.object({ message: z.object({ content: z.string() }) })).min(1),\n })\n .parse(json);\n const first = message.choices[0];\n if (first === undefined) {\n throw new ShipsealError(\"copy.llm-empty\", \"LLM returned no choices.\", \"Retry, or run with --no-copy.\");\n }\n return first.message.content;\n}\n","// Build manifest.json with facts, computed values, warnings\n// Spec: docs/PROJECT_PLAN.md §17.2\n\nimport type { Brand } from \"../brand/schema.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport type { GenerateResult } from \"../core/generate.js\";\n\nexport interface ManifestFile {\n path: string;\n template: string;\n format: string;\n width: number;\n height: number;\n bytes: number;\n sha256: string;\n}\n\nexport interface Manifest {\n shipseal: string;\n event: ShipsealEvent;\n generatedAt: string;\n brand: { name: string; theme: Brand[\"theme\"]; source: string };\n copy: { mode: \"deterministic\" | \"llm\" };\n files: ManifestFile[];\n facts: Record<string, { value: unknown; source: string; ref: string; fetchedAt: string }>;\n computed: Record<string, { value: unknown; computedFrom: string[] }>;\n warnings: GenerateResult[\"warnings\"];\n missing: GenerateResult[\"missing\"];\n}\n\nexport function buildManifest(input: {\n result: GenerateResult;\n event: ShipsealEvent;\n brand: Brand;\n shipsealVersion: string;\n}): Manifest {\n return {\n shipseal: input.shipsealVersion,\n event: input.event,\n generatedAt: input.result.generatedAt,\n brand: {\n name: input.brand.name,\n theme: input.brand.theme,\n source: \".shipseal/brand.json\",\n },\n copy: { mode: input.result.copyMode },\n files: input.result.files.map((file) => ({\n path: file.fileName,\n template: file.template,\n format: file.format,\n width: file.width,\n height: file.height,\n bytes: file.bytes.byteLength,\n sha256: file.sha256,\n })),\n facts: flattenFacts(input.result.facts),\n computed: input.result.computed,\n warnings: input.result.warnings,\n missing: input.result.missing,\n };\n}\n\nexport function flattenFacts(\n facts: Facts,\n): Record<string, { value: unknown; source: string; ref: string; fetchedAt: string }> {\n const out: Record<string, { value: unknown; source: string; ref: string; fetchedAt: string }> = {};\n const walk = (prefix: string, value: unknown): void => {\n if (isFact(value)) {\n out[prefix] = {\n value: value.value,\n source: value.provenance.source,\n ref: value.provenance.ref,\n fetchedAt: value.provenance.fetchedAt,\n };\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n walk(`${prefix}[${String(index)}]`, item);\n });\n return;\n }\n if (typeof value === \"object\" && value !== null) {\n for (const [key, nested] of Object.entries(value)) {\n walk(prefix.length === 0 ? key : `${prefix}.${key}`, nested);\n }\n }\n };\n walk(\"project\", facts.project);\n if (facts.release !== undefined) {\n walk(\"release\", facts.release);\n }\n if (facts.metrics !== undefined) {\n walk(\"metrics\", facts.metrics);\n }\n if (facts.bench !== undefined) {\n walk(\"bench\", facts.bench);\n }\n if (facts.milestone !== undefined) {\n walk(\"milestone\", facts.milestone);\n }\n return out;\n}\n\nfunction isFact(\n value: unknown,\n): value is { value: unknown; provenance: { source: string; ref: string; fetchedAt: string } } {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n if (!(\"value\" in value) || !(\"provenance\" in value)) {\n return false;\n }\n const provenance = value.provenance;\n return (\n typeof provenance === \"object\" &&\n provenance !== null &&\n \"source\" in provenance &&\n \"ref\" in provenance &&\n \"fetchedAt\" in provenance\n );\n}\n","// Write pack files to disk\n// Spec: docs/PROJECT_PLAN.md §17.1\n\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { isAbsolute, join } from \"node:path\";\nimport type { GenerateResult } from \"../core/generate.js\";\nimport { buildManifest, type Manifest } from \"./manifest.js\";\nimport type { Brand } from \"../brand/schema.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\n\nexport async function writePack(input: {\n outDir: string;\n eventId: string;\n result: GenerateResult;\n event: ShipsealEvent;\n brand: Brand;\n shipsealVersion: string;\n}): Promise<{ dir: string; manifest: Manifest }> {\n const dir = join(input.outDir, input.eventId);\n await mkdir(dir, { recursive: true });\n await Promise.all(input.result.files.map((file) => writeFile(join(dir, file.fileName), file.bytes)));\n const manifest = buildManifest({\n result: input.result,\n event: input.event,\n brand: input.brand,\n shipsealVersion: input.shipsealVersion,\n });\n await writeFile(join(dir, \"manifest.json\"), `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n return { dir, manifest };\n}\n\nexport function resolveOutputDir(cwd: string, configured: string): string {\n return isAbsolute(configured) ? configured : join(cwd, configured);\n}\n\nexport function eventId(event: ShipsealEvent, generatedAt = \"\"): string {\n if (event.kind === \"release\") {\n return event.tag;\n }\n if (event.kind === \"milestone\") {\n return `milestone-${event.metric}-${String(event.threshold)}`;\n }\n const day = generatedAt.slice(0, 10);\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(day) ? `bench-${day}` : \"bench\";\n}\n","// Upload assets to a GitHub release and write the Actions job summary\n// Spec: docs/PROJECT_PLAN.md §19.4\n// Docs checked 2026-09-11: `gh release upload <tag> <files>... --clobber`\n// gh is preinstalled on GitHub-hosted runners.\n\nimport { execFile } from \"node:child_process\";\nimport { appendFile } from \"node:fs/promises\";\nimport { promisify } from \"node:util\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport type { Manifest } from \"./manifest.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport type GhExec = (\n file: string,\n args: string[],\n options: { env: NodeJS.ProcessEnv },\n) => Promise<{ stdout: string; stderr: string }>;\n\nexport async function uploadReleaseAssets(options: {\n tag: string;\n files: string[];\n repo?: string;\n token?: string;\n exec?: GhExec;\n}): Promise<void> {\n if (options.files.length === 0) {\n return;\n }\n const exec = options.exec ?? execFileAsync;\n const args = [\"release\", \"upload\", options.tag, ...options.files, \"--clobber\"];\n if (options.repo !== undefined) {\n args.push(\"--repo\", options.repo);\n }\n const env = { ...process.env };\n if (options.token !== undefined) {\n env.GH_TOKEN = options.token;\n env.GITHUB_TOKEN = options.token;\n }\n try {\n await exec(\"gh\", args, { env });\n } catch (error) {\n throw new ShipsealError(\n \"github.upload\",\n `Could not upload assets to GitHub release ${options.tag}.`,\n \"Confirm gh is installed, GITHUB_TOKEN can write contents, and the release exists.\",\n { cause: error },\n );\n }\n}\n\nexport async function appendJobSummary(path: string, manifest: Manifest, dir: string): Promise<void> {\n await appendFile(path, `${jobSummaryMarkdown(manifest, dir)}\\n`, \"utf8\");\n}\n\nexport function jobSummaryMarkdown(manifest: Manifest, dir: string): string {\n const lines = [\n \"## Shipseal\",\n \"\",\n `Generated **${String(manifest.files.length)}** files in \\`${dir}\\`.`,\n \"\",\n ];\n const repo = process.env.GITHUB_REPOSITORY;\n const tag = manifest.event.kind === \"release\" ? manifest.event.tag : undefined;\n if (repo !== undefined && tag !== undefined) {\n for (const file of manifest.files) {\n const url = `https://github.com/${repo}/releases/download/${tag}/${file.path}`;\n lines.push(`![${file.path}](${url})`, \"\");\n }\n } else {\n lines.push(\"| File | Template | Format |\", \"|---|---|---|\");\n for (const file of manifest.files) {\n lines.push(`| ${file.path} | ${file.template} | ${file.format} |`);\n }\n lines.push(\"\");\n }\n lines.push(\"### Facts\", \"\");\n for (const [key, entry] of Object.entries(manifest.facts)) {\n lines.push(`- \\`${key}\\`: ${JSON.stringify(entry.value)} (${entry.source})`);\n }\n if (Object.keys(manifest.computed).length > 0) {\n lines.push(\"\", \"### Computed\", \"\");\n for (const [key, entry] of Object.entries(manifest.computed)) {\n lines.push(`- \\`${key}\\`: ${JSON.stringify(entry.value)}`);\n }\n }\n if (manifest.warnings.length > 0) {\n lines.push(\"\", \"### Warnings\", \"\");\n for (const warning of manifest.warnings) {\n lines.push(`- ${warning.template} ${warning.format} ${warning.slot}: ${warning.action}`);\n }\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n","// Shared helpers for release, milestone, and bench commands\n\nimport { readFileSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join } from \"node:path\";\nimport type { Brand } from \"../brand/schema.js\";\nimport { mergeConfig } from \"../config/load.js\";\nimport { DEFAULT_CONFIG, type Config } from \"../config/schema.js\";\nimport { llmCopy } from \"../copy/llm.js\";\nimport type { Copy } from \"../copy/slots.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport type { GenerateResult } from \"../core/generate.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { FORMAT_IDS, type FormatId } from \"../formats.js\";\nimport { eventId, resolveOutputDir, writePack } from \"../outputs/files.js\";\nimport { appendJobSummary, uploadReleaseAssets } from \"../outputs/github-release.js\";\nimport type { Manifest } from \"../outputs/manifest.js\";\nimport { resolvePackageRoot } from \"../render/takumi.js\";\n\nexport interface SharedFlags {\n cwd: string;\n formats?: string;\n themes?: string;\n copy?: boolean;\n out?: string;\n strict?: boolean;\n dryRun?: boolean;\n package?: string;\n upload?: boolean;\n fetchImpl?: typeof fetch;\n}\n\nexport function overlayFormats(config: Config, flags: SharedFlags): Config {\n const overlay: Config = { ...config };\n if (flags.formats !== undefined) {\n overlay.formats = parseFormats(flags.formats);\n }\n if (flags.out !== undefined) {\n overlay.outputDir = flags.out;\n }\n return mergeConfig(DEFAULT_CONFIG, overlay);\n}\n\nexport function parseFormats(list: string): FormatId[] {\n const formats: FormatId[] = [];\n for (const part of list.split(\",\")) {\n const id = part.trim();\n if (id.length === 0) {\n continue;\n }\n const match = FORMAT_IDS.find((format) => format === id);\n if (match === undefined) {\n throw new ShipsealError(\n \"release.bad-format\",\n `Unknown format \"${id}\".`,\n `Use a comma-separated list from: ${FORMAT_IDS.join(\", \")}.`,\n );\n }\n formats.push(match);\n }\n return formats;\n}\n\nexport function resolveThemes(flag: string | undefined, brandTheme: Brand[\"theme\"]): Array<\"dark\" | \"light\"> {\n if (flag === \"both\") {\n return [\"dark\", \"light\"];\n }\n if (flag === \"dark\" || flag === \"light\") {\n return [flag];\n }\n return [brandTheme];\n}\n\nexport async function resolveCopy(\n facts: Facts,\n config: Config,\n noCopy: boolean,\n fallback: Copy,\n): Promise<{ copy: Copy; copyMode: \"deterministic\" | \"llm\"; warning?: string }> {\n if (noCopy || config.copy?.llm !== true) {\n return { copy: fallback, copyMode: \"deterministic\" };\n }\n const apiKey = process.env.SHIPSEAL_LLM_API_KEY;\n if (apiKey === undefined || apiKey.length === 0) {\n throw new ShipsealError(\n \"copy.missing-key\",\n \"copy.llm is enabled but SHIPSEAL_LLM_API_KEY is not set.\",\n \"Set SHIPSEAL_LLM_API_KEY, or pass --no-copy for deterministic copy.\",\n );\n }\n const llmOpts: Parameters<typeof llmCopy>[1] = {\n apiKey,\n model: config.copy.model ?? \"gpt-4o-mini\",\n maxRetries: config.copy.maxRetries ?? 2,\n };\n if (process.env.SHIPSEAL_LLM_BASE_URL !== undefined) {\n llmOpts.baseUrl = process.env.SHIPSEAL_LLM_BASE_URL;\n }\n const result = await llmCopy(facts, llmOpts, fallback);\n const out: { copy: Copy; copyMode: \"deterministic\" | \"llm\"; warning?: string } = {\n copy: result.copy,\n copyMode: result.mode,\n };\n if (result.warning !== undefined) {\n out.warning = result.warning;\n }\n return out;\n}\n\nexport async function loadLogos(cwd: string, brand: Brand): Promise<{ light?: Uint8Array; dark?: Uint8Array } | undefined> {\n if (brand.logo === undefined) {\n return undefined;\n }\n const logos: { light?: Uint8Array; dark?: Uint8Array } = {\n light: await readLogo(cwd, brand.logo.light),\n };\n if (brand.logo.dark !== undefined) {\n logos.dark = await readLogo(cwd, brand.logo.dark);\n }\n return logos;\n}\n\nasync function readLogo(cwd: string, path: string): Promise<Uint8Array> {\n const resolved = isAbsolute(path) ? path : join(cwd, path);\n return new Uint8Array(await readFile(resolved));\n}\n\nexport function readShipsealVersion(): string {\n const raw: unknown = JSON.parse(readFileSync(join(resolvePackageRoot(), \"package.json\"), \"utf8\"));\n if (typeof raw === \"object\" && raw !== null && \"version\" in raw && typeof raw.version === \"string\") {\n return raw.version;\n }\n return \"0.0.0\";\n}\n\nexport function collectEnv(flags: SharedFlags): {\n skipNetwork: boolean;\n githubToken?: string;\n packagePath?: string;\n fetchImpl?: typeof fetch;\n} {\n const skipNetwork = flags.dryRun === true && process.env.GITHUB_TOKEN === undefined;\n const out: ReturnType<typeof collectEnv> = { skipNetwork };\n if (process.env.GITHUB_TOKEN !== undefined) {\n out.githubToken = process.env.GITHUB_TOKEN;\n }\n if (flags.package !== undefined) {\n out.packagePath = flags.package;\n }\n if (flags.fetchImpl !== undefined) {\n out.fetchImpl = flags.fetchImpl;\n }\n return out;\n}\n\nexport async function finishPack(input: {\n flags: SharedFlags;\n config: Config;\n event: ShipsealEvent;\n result: GenerateResult;\n brand: Brand;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n facts: Facts;\n}): Promise<{\n dryRun: false;\n facts: Facts;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir: string;\n manifest: Manifest;\n warnings: GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n}> {\n const generatedAt = input.result.generatedAt;\n const written = await writePack({\n outDir: resolveOutputDir(\n input.flags.cwd,\n input.flags.out ?? input.config.outputDir ?? \".shipseal/output\",\n ),\n eventId: eventId(input.event, generatedAt),\n result: input.result,\n event: input.event,\n brand: input.brand,\n shipsealVersion: readShipsealVersion(),\n });\n if (input.flags.upload === true && input.event.kind === \"release\") {\n const files = input.result.files.map((file) => join(written.dir, file.fileName));\n const uploadOpts: Parameters<typeof uploadReleaseAssets>[0] = { tag: input.event.tag, files };\n if (process.env.GITHUB_REPOSITORY !== undefined) {\n uploadOpts.repo = process.env.GITHUB_REPOSITORY;\n }\n if (process.env.GITHUB_TOKEN !== undefined) {\n uploadOpts.token = process.env.GITHUB_TOKEN;\n }\n await uploadReleaseAssets(uploadOpts);\n }\n const summaryPath = process.env.GITHUB_STEP_SUMMARY;\n if (summaryPath !== undefined && summaryPath.length > 0) {\n await appendJobSummary(summaryPath, written.manifest, written.dir);\n }\n const exitCode: 0 | 1 | 2 = input.flags.strict === true && input.result.warnings.length > 0 ? 2 : 0;\n const done: {\n dryRun: false;\n facts: Facts;\n copy: Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir: string;\n manifest: Manifest;\n warnings: GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n } = {\n dryRun: false,\n facts: input.facts,\n copy: input.copy,\n copyMode: input.copyMode,\n dir: written.dir,\n manifest: written.manifest,\n warnings: input.result.warnings,\n exitCode,\n };\n if (input.copyWarning !== undefined) {\n done.copyWarning = input.copyWarning;\n }\n return done;\n}\n","// bench: before/after cards from bench JSON\n// Spec: docs/PROJECT_PLAN.md §18.4\n\nimport { loadBrand } from \"../brand/load.js\";\nimport { loadConfig } from \"../config/load.js\";\nimport { benchCopy } from \"../copy/deterministic.js\";\nimport { generate } from \"../core/generate.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport { collectFacts } from \"../sources/collect.js\";\nimport { createTakumiRenderer } from \"../render/takumi.js\";\nimport {\n collectEnv,\n finishPack,\n loadLogos,\n overlayFormats,\n resolveCopy,\n resolveThemes,\n type SharedFlags,\n} from \"./shared.js\";\n\nexport interface BenchFlags extends SharedFlags {\n file?: string;\n}\n\nexport interface BenchResult {\n dryRun: boolean;\n facts: Awaited<ReturnType<typeof collectFacts>>;\n copy: import(\"../copy/slots.js\").Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir?: string;\n manifest?: import(\"../outputs/manifest.js\").Manifest;\n warnings: import(\"../core/generate.js\").GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n}\n\nexport async function runBench(flags: BenchFlags): Promise<BenchResult> {\n const cwd = flags.cwd;\n const config = overlayFormats(await loadConfig(cwd), flags);\n const brand = await loadBrand(cwd);\n const file = flags.file ?? config.bench?.file ?? \".shipseal/bench.json\";\n const event: ShipsealEvent = { kind: \"bench\", file };\n const env = collectEnv(flags);\n const collectOpts: Parameters<typeof collectFacts>[0] = {\n cwd,\n event,\n skipNetwork: true,\n benchFile: file,\n };\n if (env.packagePath !== undefined) {\n collectOpts.packagePath = env.packagePath;\n }\n const facts = await collectFacts(collectOpts);\n const resolved = await resolveCopy(facts, config, flags.copy === false, benchCopy(facts));\n\n if (flags.dryRun === true) {\n const dry: BenchResult = {\n dryRun: true,\n facts,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n warnings: [],\n exitCode: 0,\n };\n if (resolved.warning !== undefined) {\n dry.copyWarning = resolved.warning;\n }\n return dry;\n }\n\n const renderer = await createTakumiRenderer();\n const generateInput: Parameters<typeof generate>[0] = {\n event,\n facts,\n brand,\n config,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n renderer,\n themes: resolveThemes(flags.themes, brand.theme),\n generatedAt: new Date().toISOString(),\n };\n const logos = await loadLogos(cwd, brand);\n if (logos !== undefined) {\n generateInput.logos = logos;\n }\n const result = await generate(generateInput);\n const packInput: Parameters<typeof finishPack>[0] = {\n flags,\n config,\n event,\n result,\n brand,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n facts,\n };\n if (resolved.warning !== undefined) {\n packInput.copyWarning = resolved.warning;\n }\n return finishPack(packInput);\n}\n","// doctor: environment and config checks\n// Spec: docs/PROJECT_PLAN.md §18.5\n\nimport { execFile } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { brandSchema } from \"../brand/schema.js\";\nimport { FORMATS } from \"../formats.js\";\nimport {\n createTakumiRenderer,\n resolvePackageRoot,\n testCardNode,\n} from \"../render/takumi.js\";\n\nconst execFileAsync = promisify(execFile);\nconst MIN_NODE_MAJOR = 22;\n\nexport type CheckStatus = \"pass\" | \"fail\" | \"info\";\n\nexport interface DoctorCheck {\n name: string;\n status: CheckStatus;\n message: string;\n fix?: string;\n}\n\nexport interface DoctorResult {\n ok: boolean;\n checks: DoctorCheck[];\n}\n\nexport async function runDoctor(cwd: string): Promise<DoctorResult> {\n const checks: DoctorCheck[] = [];\n checks.push(checkNode());\n checks.push(await checkGit(cwd));\n checks.push(await checkShallow(cwd));\n checks.push(await checkBrand(cwd));\n checks.push(await checkFont());\n checks.push(await checkLogo(cwd));\n checks.push(checkGithubToken());\n checks.push(await checkRender());\n\n return {\n ok: checks.every((check) => check.status !== \"fail\"),\n checks,\n };\n}\n\nfunction checkNode(): DoctorCheck {\n const version = process.versions.node;\n const major = Number.parseInt(version.split(\".\")[0] ?? \"0\", 10);\n if (major >= MIN_NODE_MAJOR) {\n return { name: \"node\", status: \"pass\", message: `Node.js ${version}` };\n }\n return {\n name: \"node\",\n status: \"fail\",\n message: `Node.js ${version} is below the minimum of ${MIN_NODE_MAJOR}.`,\n fix: `Install Node.js ${MIN_NODE_MAJOR} or newer.`,\n };\n}\n\nasync function checkGit(cwd: string): Promise<DoctorCheck> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"--version\"], { cwd });\n return { name: \"git\", status: \"pass\", message: stdout.trim() };\n } catch {\n return {\n name: \"git\",\n status: \"fail\",\n message: \"git is not available on PATH.\",\n fix: \"Install git and ensure it is on PATH.\",\n };\n }\n}\n\nasync function checkShallow(cwd: string): Promise<DoctorCheck> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"rev-parse\", \"--is-shallow-repository\"], {\n cwd,\n });\n if (stdout.trim() === \"true\") {\n return {\n name: \"clone-depth\",\n status: \"fail\",\n message: \"This git clone is shallow, so release facts will be incomplete.\",\n fix: \"Re-clone with a full history, or in GitHub Actions set fetch-depth: 0.\",\n };\n }\n return { name: \"clone-depth\", status: \"pass\", message: \"Full git history is available.\" };\n } catch {\n return {\n name: \"clone-depth\",\n status: \"info\",\n message: \"Could not determine whether the clone is shallow.\",\n };\n }\n}\n\nasync function checkBrand(cwd: string): Promise<DoctorCheck> {\n const path = join(cwd, \".shipseal\", \"brand.json\");\n if (!existsSync(path)) {\n return {\n name: \"brand.json\",\n status: \"fail\",\n message: \".shipseal/brand.json is missing.\",\n fix: \"Run shipseal init to detect a brand kit.\",\n };\n }\n try {\n const raw: unknown = JSON.parse(await readFile(path, \"utf8\"));\n const parsed = brandSchema.safeParse(raw);\n if (!parsed.success) {\n return {\n name: \"brand.json\",\n status: \"fail\",\n message: \"brand.json did not match the v1 schema.\",\n fix: parsed.error.issues.map((issue) => issue.message).join(\"; \"),\n };\n }\n return { name: \"brand.json\", status: \"pass\", message: `Brand ${parsed.data.name} is valid.` };\n } catch (error) {\n if (error instanceof SyntaxError) {\n return {\n name: \"brand.json\",\n status: \"fail\",\n message: \"brand.json is not valid JSON.\",\n fix: \"Fix the JSON syntax, or re-run shipseal init --force.\",\n };\n }\n throw error;\n }\n}\n\nasync function checkFont(): Promise<DoctorCheck> {\n try {\n const root = resolvePackageRoot();\n const fontPath = join(root, \"assets\", \"fonts\", \"GeistMono[wght].ttf\");\n if (!existsSync(fontPath)) {\n return {\n name: \"fonts\",\n status: \"fail\",\n message: \"Vendored Geist Mono file is missing.\",\n fix: \"Reinstall shipseal so assets/fonts/GeistMono[wght].ttf is present.\",\n };\n }\n return { name: \"fonts\", status: \"pass\", message: `Geist Mono found at ${fontPath}` };\n } catch {\n return {\n name: \"fonts\",\n status: \"fail\",\n message: \"Could not resolve the vendored Geist Mono font.\",\n fix: \"Reinstall shipseal so assets/fonts/GeistMono[wght].ttf is present.\",\n };\n }\n}\n\nasync function checkLogo(cwd: string): Promise<DoctorCheck> {\n const path = join(cwd, \".shipseal\", \"brand.json\");\n if (!existsSync(path)) {\n return {\n name: \"logo\",\n status: \"info\",\n message: \"Skipped; brand.json is missing.\",\n };\n }\n const raw: unknown = JSON.parse(await readFile(path, \"utf8\"));\n const parsed = brandSchema.safeParse(raw);\n if (!parsed.success || parsed.data.logo === undefined) {\n return { name: \"logo\", status: \"info\", message: \"No logo path in brand.json.\" };\n }\n const light = join(cwd, parsed.data.logo.light);\n if (!existsSync(light)) {\n return {\n name: \"logo\",\n status: \"fail\",\n message: `Logo file ${parsed.data.logo.light} is not readable.`,\n fix: \"Point brand.json logo.light at an existing SVG or PNG, or re-run init.\",\n };\n }\n return { name: \"logo\", status: \"pass\", message: `Logo readable at ${parsed.data.logo.light}` };\n}\n\nfunction checkGithubToken(): DoctorCheck {\n if (process.env.GITHUB_TOKEN !== undefined && process.env.GITHUB_TOKEN.length > 0) {\n return { name: \"GITHUB_TOKEN\", status: \"info\", message: \"GITHUB_TOKEN is set.\" };\n }\n return {\n name: \"GITHUB_TOKEN\",\n status: \"info\",\n message: \"GITHUB_TOKEN is not set. Unauthenticated GitHub API calls have a low rate limit.\",\n };\n}\n\nasync function checkRender(): Promise<DoctorCheck> {\n try {\n const renderer = await createTakumiRenderer();\n const png = await renderer.render(testCardNode(), {\n width: FORMATS.og.width,\n height: FORMATS.og.height,\n format: \"png\",\n });\n if (png.length < 8 || png[0] !== 0x89 || png[1] !== 0x50) {\n return {\n name: \"takumi\",\n status: \"fail\",\n message: \"Takumi rendered bytes that are not a PNG.\",\n fix: \"File an issue with the doctor output and your OS/arch.\",\n };\n }\n return {\n name: \"takumi\",\n status: \"pass\",\n message: `Rendered a ${FORMATS.og.width}x${FORMATS.og.height} test card (${png.length} bytes).`,\n };\n } catch (error) {\n return {\n name: \"takumi\",\n status: \"fail\",\n message: error instanceof Error ? error.message : \"Takumi failed to render a test card.\",\n fix: \"Check that the native Takumi binary installed for this platform.\",\n };\n }\n}\n","// CSS color parsing, oklch to sRGB hex, and contrast (no dependency)\n// Spec: docs/PROJECT_PLAN.md §10.3 and §25 (S7 oklch converter)\n\nconst HEX = /^#([\\da-f]{3}|[\\da-f]{6}|[\\da-f]{8})$/i;\n\nexport function parseCssColor(value: string): string | undefined {\n const trimmed = value.trim();\n const hex = normalizeHex(trimmed);\n if (hex !== undefined) {\n return hex;\n }\n const oklch = parseOklch(trimmed);\n if (oklch !== undefined) {\n return oklchToHex(oklch.l, oklch.c, oklch.h);\n }\n const rgb = parseRgb(trimmed);\n if (rgb !== undefined) {\n return rgbToHex(rgb[0], rgb[1], rgb[2]);\n }\n const hsl = parseHsl(trimmed);\n if (hsl !== undefined) {\n return rgbToHex(...hslToRgb(hsl[0], hsl[1], hsl[2]));\n }\n return undefined;\n}\n\nexport function normalizeHex(value: string): string | undefined {\n const match = HEX.exec(value.trim());\n if (match === null) {\n return undefined;\n }\n const raw = match[1];\n if (raw === undefined) {\n return undefined;\n }\n if (raw.length === 3) {\n return `#${raw[0]}${raw[0]}${raw[1]}${raw[1]}${raw[2]}${raw[2]}`.toLowerCase();\n }\n return `#${raw.slice(0, 6).toLowerCase()}`;\n}\n\nexport function oklchToHex(l: number, c: number, h: number): string {\n const hr = (h * Math.PI) / 180;\n const a = c * Math.cos(hr);\n const b = c * Math.sin(hr);\n const coneL = l + 0.3963377774 * a + 0.2158037573 * b;\n const coneM = l - 0.1055613458 * a - 0.0638541728 * b;\n const coneS = l - 0.0894841775 * a - 1.291485548 * b;\n const l3 = coneL * coneL * coneL;\n const m3 = coneM * coneM * coneM;\n const s3 = coneS * coneS * coneS;\n const r = 4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3;\n const g = -1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3;\n const bLin = -0.0041960863 * l3 - 0.7034186147 * m3 + 1.707614701 * s3;\n return rgbToHex(srgbEncode(r) * 255, srgbEncode(g) * 255, srgbEncode(bLin) * 255);\n}\n\nexport function contrastRatio(hexA: string, hexB: string): number {\n const a = relativeLuminance(hexA);\n const b = relativeLuminance(hexB);\n const [hi, lo] = a > b ? [a, b] : [b, a];\n return (hi + 0.05) / (lo + 0.05);\n}\n\nexport const LARGE_TEXT_CONTRAST = 3;\n\nexport function ensureForegroundContrast(\n background: string,\n foreground: string,\n): { foreground: string; adjusted: boolean } {\n if (contrastRatio(background, foreground) >= LARGE_TEXT_CONTRAST) {\n return { foreground, adjusted: false };\n }\n const light = \"#fafafa\";\n const dark = \"#0b0b0c\";\n const lightRatio = contrastRatio(background, light);\n const darkRatio = contrastRatio(background, dark);\n return { foreground: lightRatio >= darkRatio ? light : dark, adjusted: true };\n}\n\nexport function readableOnBackground(background: string, candidate: string): boolean {\n return contrastRatio(background, candidate) >= LARGE_TEXT_CONTRAST;\n}\n\nfunction srgbEncode(channel: number): number {\n const abs = Math.abs(channel);\n const encoded = abs <= 0.0031308 ? 12.92 * abs : 1.055 * abs ** (1 / 2.4) - 0.055;\n return Math.sign(channel) * encoded;\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return `#${toByte(r)}${toByte(g)}${toByte(b)}`;\n}\n\nfunction toByte(n: number): string {\n return Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .padStart(2, \"0\");\n}\n\nfunction relativeLuminance(hex: string): number {\n const rgb = hexToRgb(hex);\n if (rgb === undefined) {\n return 0;\n }\n const lin = rgb.map((channel) => {\n const s = channel / 255;\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n });\n return 0.2126 * (lin[0] ?? 0) + 0.7152 * (lin[1] ?? 0) + 0.0722 * (lin[2] ?? 0);\n}\n\nexport function isNeutralHex(hex: string): boolean {\n const rgb = hexToRgb(hex);\n if (rgb === undefined) {\n return true;\n }\n const max = Math.max(rgb[0], rgb[1], rgb[2]);\n const min = Math.min(rgb[0], rgb[1], rgb[2]);\n return max - min < 16;\n}\n\nfunction hexToRgb(hex: string): [number, number, number] | undefined {\n const normalized = normalizeHex(hex);\n if (normalized === undefined) {\n return undefined;\n }\n const r = Number.parseInt(normalized.slice(1, 3), 16);\n const g = Number.parseInt(normalized.slice(3, 5), 16);\n const b = Number.parseInt(normalized.slice(5, 7), 16);\n return [r, g, b];\n}\n\nfunction parseOklch(value: string): { l: number; c: number; h: number } | undefined {\n const match = /^oklch\\(\\s*([^/)]+?)(?:\\s*\\/\\s*[^)]+)?\\s*\\)$/i.exec(value);\n if (match === null) {\n return undefined;\n }\n const body = match[1];\n if (body === undefined) {\n return undefined;\n }\n const parts = splitCssArgs(body);\n if (parts.length < 3) {\n return undefined;\n }\n const l = parseLightness(parts[0] ?? \"\");\n const c = parseNumber(parts[1] ?? \"\");\n const h = parseHue(parts[2] ?? \"\");\n if (l === undefined || c === undefined || h === undefined) {\n return undefined;\n }\n return { l, c, h };\n}\n\nfunction parseRgb(value: string): [number, number, number] | undefined {\n const match = /^rgba?\\(\\s*([^/)]+?)(?:\\s*\\/\\s*[^)]+)?\\s*\\)$/i.exec(value);\n if (match === null) {\n return undefined;\n }\n const parts = splitCssArgs(match[1] ?? \"\");\n if (parts.length < 3) {\n return undefined;\n }\n const r = parseRgbChannel(parts[0] ?? \"\");\n const g = parseRgbChannel(parts[1] ?? \"\");\n const b = parseRgbChannel(parts[2] ?? \"\");\n if (r === undefined || g === undefined || b === undefined) {\n return undefined;\n }\n return [r, g, b];\n}\n\nfunction parseHsl(value: string): [number, number, number] | undefined {\n const match = /^hsla?\\(\\s*([^/)]+?)(?:\\s*\\/\\s*[^)]+)?\\s*\\)$/i.exec(value);\n if (match === null) {\n return undefined;\n }\n const parts = splitCssArgs(match[1] ?? \"\");\n if (parts.length < 3) {\n return undefined;\n }\n const h = parseHue(parts[0] ?? \"\");\n const s = parsePercent(parts[1] ?? \"\");\n const l = parsePercent(parts[2] ?? \"\");\n if (h === undefined || s === undefined || l === undefined) {\n return undefined;\n }\n return [h, s, l];\n}\n\nfunction hslToRgb(h: number, s: number, l: number): [number, number, number] {\n const sat = s / 100;\n const light = l / 100;\n const c = (1 - Math.abs(2 * light - 1)) * sat;\n const hp = (((h % 360) + 360) % 360) / 60;\n const x = c * (1 - Math.abs((hp % 2) - 1));\n let r = 0;\n let g = 0;\n let b = 0;\n if (hp < 1) {\n r = c;\n g = x;\n } else if (hp < 2) {\n r = x;\n g = c;\n } else if (hp < 3) {\n g = c;\n b = x;\n } else if (hp < 4) {\n g = x;\n b = c;\n } else if (hp < 5) {\n r = x;\n b = c;\n } else {\n r = c;\n b = x;\n }\n const m = light - c / 2;\n return [(r + m) * 255, (g + m) * 255, (b + m) * 255];\n}\n\nfunction splitCssArgs(body: string): string[] {\n return body\n .split(/[\\s,]+/)\n .map((part) => part.trim())\n .filter((part) => part.length > 0);\n}\n\nfunction parseLightness(token: string): number | undefined {\n if (token.endsWith(\"%\")) {\n const n = Number.parseFloat(token.slice(0, -1));\n return Number.isFinite(n) ? n / 100 : undefined;\n }\n return parseNumber(token);\n}\n\nfunction parseHue(token: string): number | undefined {\n if (token === \"none\") {\n return 0;\n }\n if (token.endsWith(\"deg\")) {\n return parseNumber(token.slice(0, -3));\n }\n if (token.endsWith(\"rad\")) {\n const n = parseNumber(token.slice(0, -3));\n return n === undefined ? undefined : (n * 180) / Math.PI;\n }\n if (token.endsWith(\"turn\")) {\n const n = parseNumber(token.slice(0, -4));\n return n === undefined ? undefined : n * 360;\n }\n if (token.endsWith(\"grad\")) {\n const n = parseNumber(token.slice(0, -4));\n return n === undefined ? undefined : n * 0.9;\n }\n return parseNumber(token);\n}\n\nfunction parsePercent(token: string): number | undefined {\n if (!token.endsWith(\"%\")) {\n return parseNumber(token);\n }\n return parseNumber(token.slice(0, -1));\n}\n\nfunction parseRgbChannel(token: string): number | undefined {\n if (token.endsWith(\"%\")) {\n const n = parseNumber(token.slice(0, -1));\n return n === undefined ? undefined : (n / 100) * 255;\n }\n return parseNumber(token);\n}\n\nfunction parseNumber(token: string): number | undefined {\n if (token === \"none\") {\n return 0;\n }\n const n = Number.parseFloat(token);\n return Number.isFinite(n) ? n : undefined;\n}\n","// CSS :root variable extraction\n// Spec: docs/PROJECT_PLAN.md §10.3\n\nimport { parseCssColor } from \"./color.js\";\nimport type { ExtractedColors } from \"./tailwind.js\";\n\n// The trailing semicolon is optional: the last declaration before `}` usually has none,\n// which silently dropped one colour from almost every real stylesheet.\nconst PROP =\n /--(primary|brand|accent|background|foreground|muted-foreground|muted)\\s*:\\s*([^;}]+)[;}]?/g;\n\n/** Any declaration, used to resolve `var(--brand-500)` style indirection. */\nconst ANY_PROP = /(--[\\w-]+)\\s*:\\s*([^;}]+)[;}]?/g;\n\n/**\n * Selectors that carry theme tokens in real projects. `:root` alone missed shadcn's\n * `[data-theme]` blocks, plain `html {}`, and `.light`.\n */\nconst SELECTORS = [\n /:root\\s*\\{/g,\n /(?:^|[\\s,}])html\\s*\\{/g,\n /\\.light\\b[^{]*\\{/g,\n /\\[data-theme=[\"']?light[\"']?\\][^{]*\\{/g,\n /\\.dark\\b[^{]*\\{/g,\n /\\[data-theme=[\"']?dark[\"']?\\][^{]*\\{/g,\n];\n\nexport function extractCssRootColors(css: string): ExtractedColors {\n const vars = allVariables(css);\n const found: Record<string, string> = {};\n // Later selectors win, so a dark block overrides a light one, as it does in a browser.\n for (const selector of SELECTORS) {\n Object.assign(found, extractBlockColors(css, selector, vars));\n }\n return mapFoundColors(found);\n}\n\nfunction allVariables(css: string): Record<string, string> {\n const vars: Record<string, string> = {};\n ANY_PROP.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = ANY_PROP.exec(css)) !== null) {\n const name = match[1];\n const value = match[2];\n if (name !== undefined && value !== undefined) {\n vars[name] = value.trim();\n }\n }\n return vars;\n}\n\n/**\n * Resolve a declaration to a hex colour.\n *\n * Handles two things a plain colour parser does not. First, `var(--brand-500)` indirection,\n * up to three hops within the same file. Second, bare channel lists: shadcn writes\n * `--background: 0 0% 100%` and applies it as `hsl(var(--background))`, so the value is only\n * a colour once wrapped. Percent signs on the last two channels mean HSL, three plain\n * numbers mean RGB.\n */\nfunction resolveColor(raw: string, vars: Record<string, string>, depth = 0): string | undefined {\n const value = raw.trim();\n if (depth < 3) {\n const ref = /^var\\(\\s*(--[\\w-]+)\\s*(?:,[^)]*)?\\)$/.exec(value);\n const target = ref?.[1] === undefined ? undefined : vars[ref[1]];\n if (target !== undefined) {\n return resolveColor(target, vars, depth + 1);\n }\n }\n const direct = parseCssColor(value);\n if (direct !== undefined) {\n return direct;\n }\n const parts = value.split(/[\\s/]+/).filter((p) => p.length > 0);\n if (parts.length === 3) {\n if (parts[1]?.endsWith(\"%\") === true && parts[2]?.endsWith(\"%\") === true) {\n return parseCssColor(`hsl(${parts[0]} ${parts[1]} ${parts[2]})`);\n }\n if (parts.every((p) => /^\\d+(\\.\\d+)?$/.test(p))) {\n return parseCssColor(`rgb(${parts[0]} ${parts[1]} ${parts[2]})`);\n }\n }\n return undefined;\n}\n\nfunction extractBlockColors(\n css: string,\n blockRe: RegExp,\n vars: Record<string, string>,\n): Record<string, string> {\n const found: Record<string, string> = {};\n blockRe.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = blockRe.exec(css)) !== null) {\n const open = css.indexOf(\"{\", match.index);\n if (open === -1) {\n break;\n }\n const close = matchingBrace(css, open);\n if (close === -1) {\n break;\n }\n const body = css.slice(open + 1, close);\n PROP.lastIndex = 0;\n let prop: RegExpExecArray | null;\n while ((prop = PROP.exec(body)) !== null) {\n const name = prop[1];\n const raw = prop[2];\n if (name === undefined || raw === undefined) {\n continue;\n }\n const hex = resolveColor(raw, vars);\n if (hex !== undefined) {\n found[name] = hex;\n }\n }\n }\n return found;\n}\n\nfunction mapFoundColors(found: Record<string, string>): ExtractedColors {\n const out: ExtractedColors = {};\n const background = found.background;\n if (background !== undefined) {\n out.background = background;\n }\n const foreground = found.foreground;\n if (foreground !== undefined) {\n out.foreground = foreground;\n }\n const muted = found[\"muted-foreground\"] ?? found.muted;\n if (muted !== undefined) {\n out.muted = muted;\n }\n const primary = found.primary ?? found.brand;\n if (primary !== undefined) {\n out.primary = primary;\n }\n if (found.accent !== undefined) {\n out.accent = found.accent;\n }\n return out;\n}\n\nfunction matchingBrace(source: string, openIndex: number): number {\n let depth = 0;\n for (let i = openIndex; i < source.length; i += 1) {\n const ch = source[i];\n if (ch === \"{\") {\n depth += 1;\n } else if (ch === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return i;\n }\n }\n }\n return -1;\n}\n","// W3C Design Tokens reader\n// Spec: docs/PROJECT_PLAN.md §10.1\n\nimport { parseCssColor } from \"./color.js\";\nimport type { ExtractedColors } from \"./tailwind.js\";\n\nexport function extractDtcgColors(tokens: unknown): ExtractedColors {\n const found: Record<string, string> = {};\n walk(tokens, [], found);\n const out: ExtractedColors = {};\n const background = found.background ?? found.bg;\n if (background !== undefined) {\n out.background = background;\n }\n const foreground = found.foreground ?? found.fg;\n if (foreground !== undefined) {\n out.foreground = foreground;\n }\n if (found.muted !== undefined) {\n out.muted = found.muted;\n }\n const primary = found.primary ?? found.brand;\n if (primary !== undefined) {\n out.primary = primary;\n }\n const accent = found.accent ?? found.secondary;\n if (accent !== undefined) {\n out.accent = accent;\n }\n return out;\n}\n\nfunction walk(node: unknown, path: string[], found: Record<string, string>): void {\n if (!isRecord(node)) {\n return;\n }\n if (node.$type === \"color\") {\n const hex = colorValue(node.$value);\n const leaf = path[path.length - 1];\n if (hex !== undefined && leaf !== undefined && found[leaf] === undefined) {\n found[leaf] = hex;\n }\n return;\n }\n for (const [key, value] of Object.entries(node)) {\n if (key.startsWith(\"$\")) {\n continue;\n }\n walk(value, [...path, key], found);\n }\n}\n\nfunction colorValue(value: unknown): string | undefined {\n if (typeof value === \"string\") {\n return parseCssColor(value);\n }\n if (isRecord(value) && typeof value.hex === \"string\") {\n return parseCssColor(value.hex);\n }\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","// Logo discovery\n// Spec: docs/PROJECT_PLAN.md §10.3\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst DIRECTORIES = [\"\", \"assets\", \"assets/brand\", \"public\", \"public/brand\", \".github\", \"docs\", \"static\", \"branding\"];\nconst ICON_NAMES = [\"icon.svg\", \"icon.png\"];\nconst NAMES = [\"logo.svg\", \"logo.png\", \"logo-light.svg\", \"logo-light.png\"];\nconst FALLBACKS = [...ICON_NAMES, \"favicon.svg\"];\n\nexport function findLogo(cwd: string): string | undefined {\n for (const dir of DIRECTORIES) {\n for (const name of NAMES) {\n const relative = dir === \"\" ? name : join(dir, name);\n if (existsSync(join(cwd, relative))) {\n return relative;\n }\n }\n }\n for (const dir of DIRECTORIES) {\n for (const name of FALLBACKS) {\n const relative = dir === \"\" ? name : join(dir, name);\n if (existsSync(join(cwd, relative))) {\n return relative;\n }\n }\n }\n return undefined;\n}\n\nexport function findLogoPair(cwd: string): { light: string; dark?: string } | undefined {\n const light = findLogo(cwd);\n if (light === undefined) {\n return undefined;\n }\n const darkNames = [\"logo-dark.svg\", \"logo-dark.png\"];\n for (const dir of DIRECTORIES) {\n for (const name of darkNames) {\n const relative = dir === \"\" ? name : join(dir, name);\n if (existsSync(join(cwd, relative))) {\n return { light, dark: relative };\n }\n }\n }\n return { light };\n}\n","// Minimal PNG reader for brand colour detection.\n// Spec: docs/PROJECT_PLAN.md §10.3 (logo colour detection)\n//\n// Logos are the only PNGs this reads, so it covers what logo exporters emit: 8 and 16 bit\n// depths, colour types 0, 2, 3, 4 and 6, no interlacing. Anything else returns undefined and\n// the caller reports the colour as not found rather than guessing. Decoding is done here\n// instead of with a library because `pngjs` would be a runtime dependency for one small job.\n\nimport { inflateSync } from \"node:zlib\";\n\nconst SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n\n/** Channels per pixel for each PNG colour type. Index is the colour type. */\nconst CHANNELS: Record<number, number> = { 0: 1, 2: 3, 3: 1, 4: 2, 6: 4 };\n\nexport interface DecodedPng {\n width: number;\n height: number;\n /** Row-major RGBA, four bytes per pixel. */\n pixels: Uint8Array;\n}\n\nexport function decodePng(buffer: Buffer): DecodedPng | undefined {\n if (buffer.length < 8 || !buffer.subarray(0, 8).equals(SIGNATURE)) {\n return undefined;\n }\n\n let width = 0;\n let height = 0;\n let bitDepth = 0;\n let colorType = 0;\n let interlace = 0;\n let palette: Buffer | undefined;\n let paletteAlpha: Buffer | undefined;\n const idat: Buffer[] = [];\n\n let offset = 8;\n while (offset + 8 <= buffer.length) {\n const length = buffer.readUInt32BE(offset);\n const type = buffer.toString(\"ascii\", offset + 4, offset + 8);\n const start = offset + 8;\n const end = start + length;\n if (end > buffer.length) {\n return undefined;\n }\n\n if (type === \"IHDR\") {\n width = buffer.readUInt32BE(start);\n height = buffer.readUInt32BE(start + 4);\n bitDepth = buffer[start + 8] ?? 0;\n colorType = buffer[start + 9] ?? 0;\n interlace = buffer[start + 12] ?? 0;\n } else if (type === \"PLTE\") {\n palette = buffer.subarray(start, end);\n } else if (type === \"tRNS\") {\n paletteAlpha = buffer.subarray(start, end);\n } else if (type === \"IDAT\") {\n idat.push(buffer.subarray(start, end));\n } else if (type === \"IEND\") {\n break;\n }\n\n offset = end + 4; // skip the CRC\n }\n\n const channels = CHANNELS[colorType];\n if (\n width === 0 ||\n height === 0 ||\n channels === undefined ||\n interlace !== 0 ||\n (bitDepth !== 8 && bitDepth !== 16) ||\n idat.length === 0 ||\n (colorType === 3 && palette === undefined)\n ) {\n return undefined;\n }\n\n // Guard against a malformed header claiming an enormous image.\n if (width * height > 64_000_000) {\n return undefined;\n }\n\n let raw: Buffer;\n try {\n raw = inflateSync(Buffer.concat(idat));\n } catch {\n return undefined;\n }\n\n const bytesPerSample = bitDepth / 8;\n const bpp = channels * bytesPerSample;\n const stride = width * bpp;\n if (raw.length < height * (stride + 1)) {\n return undefined;\n }\n\n const unfiltered = unfilter(raw, height, stride, bpp);\n if (unfiltered === undefined) {\n return undefined;\n }\n\n return { width, height, pixels: toRgba(unfiltered, width, height, colorType, bytesPerSample, palette, paletteAlpha) };\n}\n\n/** Reverse the per-scanline filters defined in the PNG spec. */\nfunction unfilter(raw: Buffer, height: number, stride: number, bpp: number): Buffer | undefined {\n const out = Buffer.alloc(height * stride);\n let pos = 0;\n for (let y = 0; y < height; y++) {\n const filter = raw[pos];\n pos += 1;\n if (filter === undefined || filter > 4) {\n return undefined;\n }\n const rowStart = y * stride;\n const prevStart = rowStart - stride;\n for (let x = 0; x < stride; x++) {\n const value = raw[pos + x] ?? 0;\n const a = x >= bpp ? (out[rowStart + x - bpp] ?? 0) : 0;\n const b = y > 0 ? (out[prevStart + x] ?? 0) : 0;\n const c = x >= bpp && y > 0 ? (out[prevStart + x - bpp] ?? 0) : 0;\n let restored: number;\n switch (filter) {\n case 1: {\n restored = value + a;\n break;\n }\n case 2: {\n restored = value + b;\n break;\n }\n case 3: {\n restored = value + Math.floor((a + b) / 2);\n break;\n }\n case 4: {\n restored = value + paeth(a, b, c);\n break;\n }\n default: {\n restored = value;\n }\n }\n out[rowStart + x] = restored & 0xff;\n }\n pos += stride;\n }\n return out;\n}\n\nfunction paeth(a: number, b: number, c: number): number {\n const p = a + b - c;\n const pa = Math.abs(p - a);\n const pb = Math.abs(p - b);\n const pc = Math.abs(p - c);\n if (pa <= pb && pa <= pc) {\n return a;\n }\n return pb <= pc ? b : c;\n}\n\nfunction toRgba(\n data: Buffer,\n width: number,\n height: number,\n colorType: number,\n bytesPerSample: number,\n palette: Buffer | undefined,\n paletteAlpha: Buffer | undefined,\n): Uint8Array {\n const pixels = new Uint8Array(width * height * 4);\n const channels = CHANNELS[colorType] ?? 4;\n const bpp = channels * bytesPerSample;\n\n for (let i = 0; i < width * height; i++) {\n // For 16 bit samples the high byte is a close enough approximation for colour picking.\n const at = (channel: number): number => data[i * bpp + channel * bytesPerSample] ?? 0;\n const out = i * 4;\n switch (colorType) {\n case 0: {\n const g = at(0);\n pixels[out] = g;\n pixels[out + 1] = g;\n pixels[out + 2] = g;\n pixels[out + 3] = 255;\n break;\n }\n case 2: {\n pixels[out] = at(0);\n pixels[out + 1] = at(1);\n pixels[out + 2] = at(2);\n pixels[out + 3] = 255;\n break;\n }\n case 3: {\n const index = at(0);\n pixels[out] = palette?.[index * 3] ?? 0;\n pixels[out + 1] = palette?.[index * 3 + 1] ?? 0;\n pixels[out + 2] = palette?.[index * 3 + 2] ?? 0;\n pixels[out + 3] = paletteAlpha?.[index] ?? 255;\n break;\n }\n case 4: {\n const g = at(0);\n pixels[out] = g;\n pixels[out + 1] = g;\n pixels[out + 2] = g;\n pixels[out + 3] = at(1);\n break;\n }\n default: {\n pixels[out] = at(0);\n pixels[out + 1] = at(1);\n pixels[out + 2] = at(2);\n pixels[out + 3] = at(3);\n }\n }\n }\n return pixels;\n}\n\n/**\n * Most common non-neutral colour in a logo, as a hex string.\n *\n * Nearly transparent pixels are ignored so a transparent background does not win, and greys\n * are ignored because a logo's black wordmark is not its brand colour. Colours are bucketed\n * into 16 levels per channel so anti-aliased edges group with the solid fill they belong to,\n * then the winning bucket reports the average of the real pixels inside it rather than the\n * bucket centre, which would drift the hue.\n */\nexport function dominantNonNeutralColor(png: DecodedPng): string | undefined {\n const buckets = new Map<number, { count: number; r: number; g: number; b: number }>();\n\n for (let i = 0; i < png.pixels.length; i += 4) {\n const a = png.pixels[i + 3] ?? 0;\n if (a < 128) {\n continue;\n }\n const r = png.pixels[i] ?? 0;\n const g = png.pixels[i + 1] ?? 0;\n const b = png.pixels[i + 2] ?? 0;\n if (Math.max(r, g, b) - Math.min(r, g, b) < 16) {\n continue; // grey, including pure black and white\n }\n const key = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4);\n const bucket = buckets.get(key);\n if (bucket === undefined) {\n buckets.set(key, { count: 1, r, g, b });\n } else {\n bucket.count += 1;\n bucket.r += r;\n bucket.g += g;\n bucket.b += b;\n }\n }\n\n let best: { count: number; r: number; g: number; b: number } | undefined;\n for (const bucket of buckets.values()) {\n if (best === undefined || bucket.count > best.count) {\n best = bucket;\n }\n }\n if (best === undefined) {\n return undefined;\n }\n\n const channel = (total: number): string =>\n Math.round(total / best.count)\n .toString(16)\n .padStart(2, \"0\");\n return `#${channel(best.r)}${channel(best.g)}${channel(best.b)}`;\n}\n","// Static Tailwind v3 config + v4 @theme color extraction\n// Spec: docs/PROJECT_PLAN.md §10.3, spike S7\n\nimport { parseCssColor } from \"./color.js\";\n\nexport interface ExtractedColors {\n background?: string;\n foreground?: string;\n muted?: string;\n primary?: string;\n accent?: string;\n}\n\nconst COLOR_PROP = /--color-([a-zA-Z0-9-]+)\\s*:\\s*([^;]+);/g;\nconst CUSTOM_PROP = /--([a-zA-Z0-9-]+)\\s*:\\s*([^;]+);/g;\nconst SKIP_PREFIXES = new Set([\"chart\", \"sidebar\", \"ring\", \"border\", \"input\", \"destructive\"]);\n\nexport function extractTailwindV4Colors(css: string): ExtractedColors {\n const blocks = themeBlocks(css);\n const custom = collectCustomProperties(css);\n const fromTheme: Record<string, string> = {};\n for (const block of blocks) {\n COLOR_PROP.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = COLOR_PROP.exec(block)) !== null) {\n const name = match[1];\n const raw = match[2];\n if (name === undefined || raw === undefined || shouldSkip(name)) {\n continue;\n }\n fromTheme[name] = raw.trim();\n }\n }\n const resolved: Record<string, string> = {};\n for (const [name, raw] of Object.entries(fromTheme)) {\n const hex = resolveToHex(raw, custom, 0);\n if (hex !== undefined) {\n resolved[name] = hex;\n }\n }\n return mapBrandColors(resolved);\n}\n\nexport function extractTailwindV3Colors(source: string): ExtractedColors {\n const found: Record<string, string> = {};\n const re =\n /\\b(primary|brand|accent|background|foreground|muted|secondary)\\b\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const name = match[1];\n const raw = match[2];\n if (name === undefined || raw === undefined) {\n continue;\n }\n const hex = parseCssColor(raw);\n if (hex !== undefined) {\n found[name] = hex;\n }\n }\n return mapBrandColors(found);\n}\n\nfunction themeBlocks(css: string): string[] {\n const blocks: string[] = [];\n const re = /@theme(?:\\s+inline)?\\s*\\{/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(css)) !== null) {\n const open = css.indexOf(\"{\", match.index);\n if (open === -1) {\n break;\n }\n const close = matchingBrace(css, open);\n if (close === -1) {\n break;\n }\n blocks.push(css.slice(open + 1, close));\n }\n return blocks;\n}\n\nfunction matchingBrace(source: string, openIndex: number): number {\n let depth = 0;\n for (let i = openIndex; i < source.length; i += 1) {\n const ch = source[i];\n if (ch === \"{\") {\n depth += 1;\n } else if (ch === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return i;\n }\n }\n }\n return -1;\n}\n\nfunction collectCustomProperties(css: string): Map<string, string> {\n const props = new Map<string, string>();\n CUSTOM_PROP.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = CUSTOM_PROP.exec(css)) !== null) {\n const name = match[1];\n const value = match[2];\n if (name !== undefined && value !== undefined) {\n props.set(`--${name}`, value.trim());\n }\n }\n return props;\n}\n\nfunction resolveToHex(\n raw: string,\n custom: Map<string, string>,\n depth: number,\n): string | undefined {\n if (depth > 3) {\n return undefined;\n }\n const direct = parseCssColor(raw);\n if (direct !== undefined) {\n return direct;\n }\n const varMatch = /^var\\(\\s*(--[a-zA-Z0-9-]+)\\s*(?:,[^)]+)?\\)$/.exec(raw);\n if (varMatch === null) {\n return undefined;\n }\n const ref = varMatch[1];\n if (ref === undefined) {\n return undefined;\n }\n const next = custom.get(ref);\n if (next === undefined) {\n return undefined;\n }\n return resolveToHex(next, custom, depth + 1);\n}\n\nfunction shouldSkip(name: string): boolean {\n const root = name.split(\"-\")[0];\n return root !== undefined && SKIP_PREFIXES.has(root);\n}\n\nfunction mapBrandColors(found: Record<string, string>): ExtractedColors {\n const out: ExtractedColors = {};\n const background = found.background ?? found.bg;\n if (background !== undefined) {\n out.background = background;\n }\n const foreground = found.foreground ?? found.fg;\n if (foreground !== undefined) {\n out.foreground = foreground;\n }\n const muted = found[\"muted-foreground\"] ?? found.muted;\n if (muted !== undefined) {\n out.muted = muted;\n }\n const primary = found.primary ?? found.brand;\n if (primary !== undefined) {\n out.primary = primary;\n }\n const accent = found.accent ?? found.secondary;\n if (accent !== undefined) {\n out.accent = accent;\n }\n return out;\n}\n","// Brand detection pipeline\n// Spec: docs/PROJECT_PLAN.md §10.3\n\nimport { execFile } from \"node:child_process\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { join, relative, basename } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { z } from \"zod\";\nimport { ensureForegroundContrast, isNeutralHex, parseCssColor, readableOnBackground } from \"./color.js\";\nimport { extractCssRootColors } from \"./css-vars.js\";\nimport { extractDtcgColors } from \"./dtcg.js\";\nimport { findLogoPair } from \"./logo.js\";\nimport { decodePng, dominantNonNeutralColor } from \"./png.js\";\n// One implementation only. detect.ts previously carried its own copies of these, which\n// drifted from the ones in sources/readme.ts and read a YAML comment as the project name.\nimport { extractH1, extractTagline } from \"../sources/readme.js\";\nimport {\n DEFAULT_BRAND_COLORS,\n DEFAULT_BRAND_FONTS,\n type Brand,\n} from \"./schema.js\";\nimport { extractTailwindV3Colors, extractTailwindV4Colors, type ExtractedColors } from \"./tailwind.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \"coverage\",\n \".shipseal\",\n \".next\",\n \"build\",\n]);\n\nexport interface FieldSource {\n field: string;\n source: string;\n}\n\nexport interface BrandDetection {\n brand: Brand;\n sources: FieldSource[];\n notes: string[];\n}\n\nconst packageSchema = z.object({\n private: z.boolean().optional(),\n name: z.string().optional(),\n description: z.string().optional(),\n homepage: z.string().optional(),\n repository: z.union([z.string(), z.object({ url: z.string().optional() })]).optional(),\n});\n\nexport async function detectBrand(cwd: string): Promise<BrandDetection> {\n const sources: FieldSource[] = [];\n const notes: string[] = [];\n const pkg = await readPackage(cwd);\n const readme = await readMaybe(join(cwd, \"README.md\"));\n\n const name = detectName(pkg, readme, cwd, sources);\n const tagline = detectTagline(pkg, readme, sources);\n const url = await detectUrl(pkg, cwd, sources);\n const logo = findLogoPair(cwd);\n if (logo !== undefined) {\n sources.push({ field: \"logo\", source: logo.light });\n }\n\n const colors = await detectColors(cwd, logo?.light, sources, notes);\n const contrast = ensureForegroundContrast(colors.background, colors.foreground);\n if (contrast.adjusted) {\n colors.foreground = contrast.foreground;\n notes.push(\n `Foreground failed WCAG AA large-text contrast (3:1) against background, so it was set to ${contrast.foreground}.`,\n );\n upsertSource(sources, \"colors.foreground\", \"contrast adjustment\");\n }\n applyReadableMuted(colors, sources, notes);\n applyReadableAccent(colors, sources, notes);\n\n const brand: Brand = {\n version: 1,\n name,\n colors,\n fonts: {\n heading: { ...DEFAULT_BRAND_FONTS.heading },\n body: { ...DEFAULT_BRAND_FONTS.body },\n mono: { ...DEFAULT_BRAND_FONTS.mono },\n },\n radius: 16,\n theme: \"dark\",\n style: \"minimal\",\n tokens: null,\n };\n if (tagline !== undefined) {\n brand.tagline = tagline;\n }\n if (url !== undefined) {\n brand.url = url;\n }\n if (logo !== undefined) {\n brand.logo = logo.dark === undefined ? { light: logo.light } : { light: logo.light, dark: logo.dark };\n }\n sources.push({ field: \"fonts\", source: \"built-in Geist / vendored Geist Mono\" });\n return { brand, sources, notes };\n}\n\nfunction detectName(\n pkg: z.infer<typeof packageSchema> | undefined,\n readme: string | undefined,\n cwd: string,\n sources: FieldSource[],\n): string {\n // A private package.json is a workspace root, and its name is plumbing, not a brand.\n // The shipseal repo's own root is \"shipseal-monorepo\", which is not what to put on a card.\n if (pkg?.name !== undefined && pkg.private !== true) {\n const fromPkg = stripScope(pkg.name);\n const h1 = readme === undefined ? undefined : extractH1(readme);\n if (h1 !== undefined && h1.toLowerCase() === fromPkg.toLowerCase() && h1 !== fromPkg) {\n sources.push({ field: \"name\", source: \"README.md H1\" });\n return h1;\n }\n sources.push({ field: \"name\", source: \"package.json#name\" });\n return fromPkg;\n }\n const h1 = readme === undefined ? undefined : extractH1(readme);\n if (h1 !== undefined) {\n sources.push({ field: \"name\", source: \"README.md H1\" });\n return h1;\n }\n sources.push({ field: \"name\", source: \"directory name\" });\n const fromDir = basename(cwd);\n return fromDir.length > 0 ? fromDir : \"project\";\n}\n\nfunction detectTagline(\n pkg: z.infer<typeof packageSchema> | undefined,\n readme: string | undefined,\n sources: FieldSource[],\n): string | undefined {\n if (pkg?.description !== undefined && pkg.description.trim().length > 0) {\n sources.push({ field: \"tagline\", source: \"package.json#description\" });\n return pkg.description.trim();\n }\n if (readme !== undefined) {\n const tagline = extractTagline(readme);\n if (tagline !== undefined) {\n sources.push({ field: \"tagline\", source: \"README.md first paragraph\" });\n return tagline;\n }\n }\n return undefined;\n}\n\nasync function detectUrl(\n pkg: z.infer<typeof packageSchema> | undefined,\n cwd: string,\n sources: FieldSource[],\n): Promise<string | undefined> {\n if (pkg?.homepage !== undefined && pkg.homepage.length > 0) {\n sources.push({ field: \"url\", source: \"package.json#homepage\" });\n return pkg.homepage;\n }\n const repo = repositoryUrl(pkg?.repository);\n if (repo !== undefined) {\n sources.push({ field: \"url\", source: \"package.json#repository\" });\n return repo;\n }\n const remote = await gitRemote(cwd);\n if (remote !== undefined) {\n sources.push({ field: \"url\", source: \"git remote origin\" });\n return remote;\n }\n return undefined;\n}\n\nasync function detectColors(\n cwd: string,\n logoPath: string | undefined,\n sources: FieldSource[],\n notes: string[],\n): Promise<Brand[\"colors\"]> {\n const merged: ExtractedColors = {};\n const files = await listFiles(cwd, 4);\n\n const cssFiles = files.filter((file) => file.endsWith(\".css\"));\n const cssContents = await Promise.all(\n cssFiles.map(async (file) => ({ file, css: await readMaybe(file) })),\n );\n for (const { file, css } of cssContents) {\n if (css === undefined) {\n continue;\n }\n const fromTheme = extractTailwindV4Colors(css);\n const fromRoot = extractCssRootColors(css);\n const rel = relative(cwd, file);\n applyColors(merged, fromTheme, sources, `Tailwind v4 @theme in ${rel}`);\n applyColors(merged, fromRoot, sources, `:root variables in ${rel}`);\n }\n\n const configFiles = files.filter((file) => basename(file).startsWith(\"tailwind.config.\"));\n const configContents = await Promise.all(\n configFiles.map(async (file) => ({ file, source: await readMaybe(file) })),\n );\n for (const { file, source } of configContents) {\n if (source === undefined) {\n continue;\n }\n applyColors(\n merged,\n extractTailwindV3Colors(source),\n sources,\n `Tailwind config ${relative(cwd, file)}`,\n );\n }\n\n const tokenFile = files.find((file) => file.endsWith(\".tokens.json\"));\n if (tokenFile !== undefined) {\n const raw = await readMaybe(tokenFile);\n if (raw !== undefined) {\n try {\n const parsed: unknown = JSON.parse(raw);\n applyColors(merged, extractDtcgColors(parsed), sources, relative(cwd, tokenFile));\n } catch (error) {\n if (error instanceof SyntaxError) {\n notes.push(`Could not parse design tokens file ${relative(cwd, tokenFile)}.`);\n } else {\n throw error;\n }\n }\n }\n }\n\n if (merged.primary === undefined && logoPath !== undefined) {\n const fromPng = logoPath.endsWith(\".png\") ? await dominantLogoColor(join(cwd, logoPath)) : undefined;\n if (fromPng !== undefined) {\n merged.primary = fromPng;\n sources.push({ field: \"colors.primary\", source: `dominant colour in ${logoPath}` });\n }\n const svg = logoPath.endsWith(\".svg\") ? await readMaybe(join(cwd, logoPath)) : undefined;\n if (svg !== undefined) {\n const fromLogo = firstNonNeutralSvgColor(svg);\n if (fromLogo !== undefined) {\n merged.primary = fromLogo;\n sources.push({ field: \"colors.primary\", source: `SVG fill in ${logoPath}` });\n }\n }\n }\n\n // Say which colours are built-in defaults rather than anything found in this project.\n // Every other detected field prints its source, so staying silent here would let a user\n // read Shipseal's own red as their brand colour.\n const fellBack = ([\"background\", \"foreground\", \"muted\", \"primary\", \"accent\"] as const).filter(\n (field) => merged[field] === undefined,\n );\n if (fellBack.length > 0) {\n notes.push(\n `Using built-in defaults for ${fellBack.map((f) => `colors.${f}`).join(\", \")}. ` +\n \"Nothing in this project set them. Edit .shipseal/brand.json to use your own.\",\n );\n }\n\n return {\n background: merged.background ?? DEFAULT_BRAND_COLORS.background,\n foreground: merged.foreground ?? DEFAULT_BRAND_COLORS.foreground,\n muted: merged.muted ?? DEFAULT_BRAND_COLORS.muted,\n primary: merged.primary ?? DEFAULT_BRAND_COLORS.primary,\n accent: merged.accent ?? DEFAULT_BRAND_COLORS.accent,\n };\n}\n\nfunction applyReadableMuted(\n colors: Brand[\"colors\"],\n sources: FieldSource[],\n notes: string[],\n): void {\n if (colors.muted === undefined || readableOnBackground(colors.background, colors.muted)) {\n return;\n }\n colors.muted = DEFAULT_BRAND_COLORS.muted;\n notes.push(\n `Muted text color failed WCAG AA large-text contrast (3:1) against background, so it was set to ${DEFAULT_BRAND_COLORS.muted}.`,\n );\n upsertSource(sources, \"colors.muted\", \"contrast adjustment\");\n}\n\nfunction applyReadableAccent(\n colors: Brand[\"colors\"],\n sources: FieldSource[],\n notes: string[],\n): void {\n if (colors.accent === undefined || readableOnBackground(colors.background, colors.accent)) {\n return;\n }\n colors.accent = colors.primary ?? DEFAULT_BRAND_COLORS.primary;\n notes.push(\"Accent failed contrast against background, so it uses the primary color.\");\n upsertSource(sources, \"colors.accent\", \"contrast adjustment\");\n}\n\nfunction applyColors(\n target: ExtractedColors,\n incoming: ExtractedColors,\n sources: FieldSource[],\n source: string,\n): void {\n const keys = [\"background\", \"foreground\", \"muted\", \"primary\", \"accent\"] as const;\n for (const key of keys) {\n const value = incoming[key];\n if (value !== undefined && target[key] === undefined) {\n target[key] = value;\n sources.push({ field: `colors.${key}`, source });\n }\n }\n}\n\nfunction upsertSource(sources: FieldSource[], field: string, source: string): void {\n const existing = sources.find((entry) => entry.field === field);\n if (existing !== undefined) {\n existing.source = source;\n return;\n }\n sources.push({ field, source });\n}\n\nasync function readPackage(cwd: string): Promise<z.infer<typeof packageSchema> | undefined> {\n const raw = await readMaybe(join(cwd, \"package.json\"));\n if (raw === undefined) {\n return undefined;\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n const result = packageSchema.safeParse(parsed);\n return result.success ? result.data : undefined;\n } catch (error) {\n if (error instanceof SyntaxError) {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function gitRemote(cwd: string): Promise<string | undefined> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"remote\", \"get-url\", \"origin\"], { cwd });\n return normalizeGitUrl(stdout.trim());\n } catch (error) {\n if (error instanceof Error) {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function listFiles(root: string, maxDepth: number): Promise<string[]> {\n const out: string[] = [];\n const walk = async (dir: string, depth: number): Promise<void> => {\n if (depth < 0) {\n return;\n }\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n const nested: Promise<void>[] = [];\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") && entry.name !== \".github\") {\n continue;\n }\n const path = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name)) {\n continue;\n }\n nested.push(walk(path, depth - 1));\n } else {\n out.push(path);\n }\n }\n await Promise.all(nested);\n };\n await walk(root, maxDepth);\n return out;\n}\n\nasync function readMaybe(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\nfunction stripScope(name: string): string {\n const parts = name.split(\"/\");\n return parts[parts.length - 1] ?? name;\n}\n\n\nfunction repositoryUrl(repository: z.infer<typeof packageSchema>[\"repository\"]): string | undefined {\n if (typeof repository === \"string\") {\n return normalizeGitUrl(repository);\n }\n if (repository?.url !== undefined) {\n return normalizeGitUrl(repository.url);\n }\n return undefined;\n}\n\nfunction normalizeGitUrl(url: string): string {\n const ssh = /^git@([^:]+):(.+)$/.exec(url);\n if (ssh !== null && ssh[1] !== undefined && ssh[2] !== undefined) {\n return `https://${ssh[1]}/${ssh[2].replace(/\\.git$/, \"\")}`;\n }\n return url.replace(/^git\\+/, \"\").replace(/\\.git$/, \"\");\n}\n\n/**\n * Dominant non-neutral colour of a PNG logo, or undefined when the file cannot be read or\n * carries no colour. Detection reports the colour as not found rather than falling back to a\n * built-in default that would be presented to the user as \"your brand\".\n */\nasync function dominantLogoColor(path: string): Promise<string | undefined> {\n let buffer: Buffer;\n try {\n buffer = await readFile(path);\n } catch {\n return undefined;\n }\n const png = decodePng(buffer);\n if (png === undefined) {\n return undefined;\n }\n return dominantNonNeutralColor(png);\n}\n\nfunction firstNonNeutralSvgColor(svg: string): string | undefined {\n const re = /(?:fill|stroke)=\"([^\"]+)\"/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(svg)) !== null) {\n const raw = match[1];\n if (raw === undefined || raw === \"none\" || raw === \"currentColor\") {\n continue;\n }\n const hex = parseCssColor(raw);\n if (hex !== undefined && !isNeutralHex(hex)) {\n return hex;\n }\n }\n return undefined;\n}\n","// init: detect brand, write .shipseal/brand.json + config.json, render sample\n// Spec: docs/PROJECT_PLAN.md §18.1\n\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport { join } from \"node:path\";\nimport { detectBrand, type BrandDetection } from \"../brand/detect.js\";\nimport { brandSchema } from \"../brand/schema.js\";\nimport { DEFAULT_CONFIG, configSchema } from \"../config/schema.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { generate } from \"../core/generate.js\";\nimport { deterministicCopy } from \"../copy/deterministic.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { createTakumiRenderer } from \"../render/takumi.js\";\n\nexport interface InitOptions {\n cwd: string;\n yes: boolean;\n force: boolean;\n}\n\nexport interface InitResult {\n brandPath: string;\n configPath: string;\n samplePath: string;\n detection: BrandDetection;\n}\n\nexport async function runInit(options: InitOptions): Promise<InitResult> {\n const detection = await detectBrand(options.cwd);\n const brandDir = join(options.cwd, \".shipseal\");\n const brandPath = join(brandDir, \"brand.json\");\n const configPath = join(brandDir, \"config.json\");\n\n if (!options.force && (existsSync(brandPath) || existsSync(configPath))) {\n throw new ShipsealError(\n \"init.exists\",\n \".shipseal/brand.json or config.json already exists.\",\n \"Re-run with --force to overwrite, or edit the files by hand.\",\n );\n }\n\n if (!options.yes) {\n const accepted = await confirmInit(detection);\n if (!accepted) {\n throw new ShipsealError(\n \"init.cancelled\",\n \"Init cancelled; no files were written.\",\n \"Re-run shipseal init and confirm, or pass --yes to accept detections.\",\n );\n }\n }\n\n const brand = brandSchema.parse(detection.brand);\n const config = configSchema.parse(DEFAULT_CONFIG);\n await mkdir(brandDir, { recursive: true });\n await writeFile(brandPath, `${JSON.stringify(brand, null, 2)}\\n`, \"utf8\");\n await writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf8\");\n await ensureGitignore(options.cwd);\n\n const sampleDir = join(brandDir, \"output\", \"sample\");\n await mkdir(sampleDir, { recursive: true });\n const samplePath = join(sampleDir, \"release-hero-og.png\");\n const renderer = await createTakumiRenderer();\n // Render the real release-hero template with the brand just detected. This used to be a\n // hard-coded card that said \"Shipseal\" for every user, which made the tool look like it had\n // ignored their project. The point of the sample is to show them their own brand.\n const fetchedAt = new Date().toISOString();\n const provenance = { source: \"brand\" as const, ref: \".shipseal/brand.json\", fetchedAt };\n const sampleFacts: Facts = {\n project: { name: fact(brand.name, provenance) },\n };\n if (brand.tagline !== undefined) {\n sampleFacts.project.tagline = fact(brand.tagline, provenance);\n }\n if (brand.url !== undefined) {\n sampleFacts.project.url = fact(brand.url, provenance);\n }\n const sample = await generate({\n event: { kind: \"release\", tag: \"v1.0.0\" },\n facts: sampleFacts,\n brand,\n config: { ...config, formats: [\"og\"], release: { ...config.release, templates: [\"release-hero\"] } },\n copy: deterministicCopy(sampleFacts),\n copyMode: \"deterministic\",\n renderer,\n themes: [brand.theme],\n generatedAt: fetchedAt,\n });\n const first = sample.files[0];\n if (first === undefined) {\n throw new ShipsealError(\n \"init.sample-failed\",\n \"Could not render the sample card.\",\n \"Run shipseal doctor to check fonts and the renderer.\",\n );\n }\n await writeFile(samplePath, first.bytes);\n\n return { brandPath, configPath, samplePath, detection };\n}\n\nasync function confirmInit(detection: BrandDetection): Promise<boolean> {\n if (!input.isTTY) {\n throw new ShipsealError(\n \"init.unattended\",\n \"stdin is not a TTY, so init cannot ask for confirmation.\",\n \"Re-run with --yes to accept the detected brand and write files.\",\n );\n }\n output.write(\"Detected brand:\\n\");\n for (const field of detection.sources) {\n output.write(` ${field.field}: from ${field.source}\\n`);\n }\n for (const note of detection.notes) {\n output.write(` note: ${note}\\n`);\n }\n const rl = createInterface({ input, output });\n try {\n const answer = await rl.question(\"Write .shipseal/brand.json and config.json? [y/N] \");\n return answer.trim().toLowerCase() === \"y\" || answer.trim().toLowerCase() === \"yes\";\n } finally {\n rl.close();\n }\n}\n\nasync function ensureGitignore(cwd: string): Promise<void> {\n const path = join(cwd, \".gitignore\");\n const entry = \".shipseal/output/\";\n if (!existsSync(path)) {\n await writeFile(path, `${entry}\\n`, \"utf8\");\n return;\n }\n const current = await readFile(path, \"utf8\");\n if (current.split(/\\r?\\n/).some((line) => line.trim() === entry || line.trim() === \".shipseal/output\")) {\n return;\n }\n const prefix = current.endsWith(\"\\n\") || current.length === 0 ? \"\" : \"\\n\";\n await writeFile(path, `${current}${prefix}${entry}\\n`, \"utf8\");\n}\n","// milestone: card for highest crossed threshold\n// Spec: docs/PROJECT_PLAN.md §18.3\n\nimport { loadBrand } from \"../brand/load.js\";\nimport { loadConfig } from \"../config/load.js\";\nimport type { Config } from \"../config/schema.js\";\nimport { milestoneCopy } from \"../copy/deterministic.js\";\nimport { generate } from \"../core/generate.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { fact } from \"../facts/fact.js\";\nimport type { Facts } from \"../facts/schema.js\";\nimport { createTakumiRenderer } from \"../render/takumi.js\";\nimport { collectFacts } from \"../sources/collect.js\";\nimport {\n collectEnv,\n finishPack,\n loadLogos,\n overlayFormats,\n resolveCopy,\n resolveThemes,\n type SharedFlags,\n} from \"./shared.js\";\n\nexport type MilestoneMetric = \"stars\" | \"downloads\" | \"contributors\";\n\nexport interface MilestoneFlags extends SharedFlags {\n metric?: string;\n threshold?: string;\n}\n\nexport interface MilestoneResult {\n dryRun: boolean;\n skipped: boolean;\n message?: string;\n facts: Facts;\n copy?: import(\"../copy/slots.js\").Copy;\n copyMode?: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir?: string;\n manifest?: import(\"../outputs/manifest.js\").Manifest;\n warnings: import(\"../core/generate.js\").GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n}\n\nexport async function runMilestone(flags: MilestoneFlags): Promise<MilestoneResult> {\n const cwd = flags.cwd;\n const config = overlayFormats(await loadConfig(cwd), flags);\n const brand = await loadBrand(cwd);\n const placeholder: ShipsealEvent = { kind: \"milestone\", metric: \"stars\", threshold: 0 };\n const env = collectEnv(flags);\n const collectOpts: Parameters<typeof collectFacts>[0] = {\n cwd,\n event: placeholder,\n skipNetwork: env.skipNetwork,\n };\n if (env.packagePath !== undefined) {\n collectOpts.packagePath = env.packagePath;\n }\n if (env.githubToken !== undefined) {\n collectOpts.githubToken = env.githubToken;\n }\n if (env.fetchImpl !== undefined) {\n collectOpts.fetchImpl = env.fetchImpl;\n }\n const collected = await collectFacts(collectOpts);\n const selected = selectMilestone(collected, config, parseMetric(flags.metric), parseThreshold(flags.threshold));\n if (selected === undefined) {\n return {\n dryRun: flags.dryRun === true,\n skipped: true,\n message: \"No milestone threshold crossed. Nothing to generate.\",\n facts: collected,\n warnings: [],\n exitCode: 0,\n };\n }\n\n const fetchedAt = new Date().toISOString();\n const metricKey = selected.metric === \"downloads\" ? \"downloads\" : selected.metric;\n const facts: Facts = {\n ...collected,\n milestone: {\n metric: fact(selected.metric, { source: \"user-config\", ref: \"shipseal milestone --metric\", fetchedAt }),\n threshold: fact(selected.threshold, {\n source: \"user-config\",\n ref: `config.json milestones.${metricKey}`,\n fetchedAt,\n }),\n },\n };\n const event: ShipsealEvent = { kind: \"milestone\", metric: selected.metric, threshold: selected.threshold };\n const fallback = milestoneCopy(facts, selected.metric, selected.threshold);\n const resolved = await resolveCopy(facts, config, flags.copy === false, fallback);\n\n if (flags.dryRun === true) {\n const dry: MilestoneResult = {\n dryRun: true,\n skipped: false,\n facts,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n warnings: [],\n exitCode: 0,\n };\n if (resolved.warning !== undefined) {\n dry.copyWarning = resolved.warning;\n }\n return dry;\n }\n\n const renderer = await createTakumiRenderer();\n const generateInput: Parameters<typeof generate>[0] = {\n event,\n facts,\n brand,\n config,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n renderer,\n themes: resolveThemes(flags.themes, brand.theme),\n generatedAt: new Date().toISOString(),\n };\n const logos = await loadLogos(cwd, brand);\n if (logos !== undefined) {\n generateInput.logos = logos;\n }\n const result = await generate(generateInput);\n const packInput: Parameters<typeof finishPack>[0] = {\n flags,\n config,\n event,\n result,\n brand,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n facts,\n };\n if (resolved.warning !== undefined) {\n packInput.copyWarning = resolved.warning;\n }\n const packed = await finishPack(packInput);\n return { ...packed, skipped: false };\n}\n\nexport function highestCrossed(thresholds: number[], current: number): number | undefined {\n const crossed = thresholds.filter((item) => current >= item).toSorted((a, b) => b - a);\n return crossed[0];\n}\n\nexport function selectMilestone(\n facts: Facts,\n config: Config,\n metric: MilestoneMetric | undefined,\n threshold: number | undefined,\n): { metric: MilestoneMetric; threshold: number } | undefined {\n const metrics: MilestoneMetric[] = metric === undefined ? [\"stars\", \"downloads\", \"contributors\"] : [metric];\n const candidates: Array<{ metric: MilestoneMetric; threshold: number }> = [];\n for (const item of metrics) {\n const current = currentValue(facts, item);\n if (current === undefined) {\n if (metric !== undefined) {\n throw missingMetric(item);\n }\n continue;\n }\n const list = thresholdsFor(config, item);\n if (threshold !== undefined) {\n if (metric !== undefined || list.includes(threshold)) {\n return { metric: item, threshold };\n }\n continue;\n }\n const crossed = highestCrossed(list, current);\n if (crossed !== undefined) {\n candidates.push({ metric: item, threshold: crossed });\n }\n }\n return candidates.toSorted(\n (a, b) => b.threshold - a.threshold || metrics.indexOf(a.metric) - metrics.indexOf(b.metric),\n )[0];\n}\n\nfunction currentValue(facts: Facts, metric: MilestoneMetric): number | undefined {\n if (metric === \"stars\") {\n return facts.metrics?.stars?.value;\n }\n if (metric === \"downloads\") {\n return facts.metrics?.weeklyDownloads?.value;\n }\n return facts.metrics?.contributorCount?.value;\n}\n\nfunction thresholdsFor(config: Config, metric: MilestoneMetric): number[] {\n if (metric === \"stars\") {\n return config.milestones?.stars ?? [];\n }\n if (metric === \"downloads\") {\n return config.milestones?.downloads ?? [];\n }\n return config.milestones?.contributors ?? [];\n}\n\nfunction parseMetric(value: string | undefined): MilestoneMetric | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === \"stars\" || value === \"downloads\" || value === \"contributors\") {\n return value;\n }\n throw new ShipsealError(\n \"milestone.bad-metric\",\n `Unknown metric \"${value}\".`,\n \"Use --metric stars, --metric downloads, or --metric contributors.\",\n );\n}\n\nfunction parseThreshold(value: string | undefined): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n const parsed = Number.parseInt(value, 10);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new ShipsealError(\n \"milestone.bad-threshold\",\n `Invalid threshold \"${value}\".`,\n \"Pass a positive integer, for example --threshold 1000.\",\n );\n }\n return parsed;\n}\n\nfunction missingMetric(metric: MilestoneMetric): ShipsealError {\n if (metric === \"stars\") {\n return new ShipsealError(\n \"milestone.missing-stars\",\n \"Could not read GitHub stars for this repo.\",\n \"Set GITHUB_TOKEN, or confirm package.json repository points at a public GitHub repo.\",\n );\n }\n if (metric === \"downloads\") {\n return new ShipsealError(\n \"milestone.missing-downloads\",\n \"Could not read npm weekly downloads for this package.\",\n \"Confirm package.json name is published on npm, then retry without --dry-run.\",\n );\n }\n return new ShipsealError(\n \"milestone.missing-contributors\",\n \"Could not read the GitHub contributor count for this repo.\",\n \"Set GITHUB_TOKEN, or confirm package.json repository points at a public GitHub repo.\",\n );\n}\n","// release: generate the release pack\n// Spec: docs/PROJECT_PLAN.md §18.2\n\nimport { loadBrand } from \"../brand/load.js\";\nimport { loadConfig, mergeConfig } from \"../config/load.js\";\nimport { DEFAULT_CONFIG, type Config } from \"../config/schema.js\";\nimport { deterministicCopy } from \"../copy/deterministic.js\";\nimport { generate } from \"../core/generate.js\";\nimport type { ShipsealEvent } from \"../core/events.js\";\nimport { ShipsealError } from \"../core/errors.js\";\nimport { createTakumiRenderer } from \"../render/takumi.js\";\nimport { collectFacts } from \"../sources/collect.js\";\nimport { gitCurrentTag } from \"../sources/git.js\";\nimport {\n collectEnv,\n finishPack,\n loadLogos,\n overlayFormats,\n resolveCopy,\n resolveThemes,\n type SharedFlags,\n} from \"./shared.js\";\n\nexport interface ReleaseFlags extends SharedFlags {\n tag?: string;\n from?: string;\n templates?: string;\n}\n\nexport interface ReleaseResult {\n dryRun: boolean;\n facts: Awaited<ReturnType<typeof collectFacts>>;\n copy: import(\"../copy/slots.js\").Copy;\n copyMode: \"deterministic\" | \"llm\";\n copyWarning?: string;\n dir?: string;\n manifest?: import(\"../outputs/manifest.js\").Manifest;\n warnings: import(\"../core/generate.js\").GenerateResult[\"warnings\"];\n exitCode: 0 | 1 | 2;\n}\n\nexport async function runRelease(flags: ReleaseFlags): Promise<ReleaseResult> {\n const cwd = flags.cwd;\n const config = overlayReleaseConfig(await loadConfig(cwd), flags);\n const brand = await loadBrand(cwd);\n const tag = flags.tag ?? (await gitCurrentTag(cwd));\n if (tag === undefined) {\n throw new ShipsealError(\n \"release.no-tag\",\n \"No git tag found for this release.\",\n \"Create a git tag, or pass --tag vX.Y.Z.\",\n );\n }\n const event: ShipsealEvent =\n flags.from === undefined\n ? { kind: \"release\", tag }\n : { kind: \"release\", tag, previousTag: flags.from };\n\n const env = collectEnv(flags);\n const collectOpts: Parameters<typeof collectFacts>[0] = {\n cwd,\n event,\n skipNetwork: env.skipNetwork,\n };\n if (env.packagePath !== undefined) {\n collectOpts.packagePath = env.packagePath;\n }\n if (config.release?.changelogPath !== undefined) {\n collectOpts.changelogPath = config.release.changelogPath;\n }\n if (config.release?.snippet !== undefined) {\n collectOpts.snippet = config.release.snippet;\n }\n if (env.githubToken !== undefined) {\n collectOpts.githubToken = env.githubToken;\n }\n if (env.fetchImpl !== undefined) {\n collectOpts.fetchImpl = env.fetchImpl;\n }\n const facts = await collectFacts(collectOpts);\n\n const noCopy = flags.copy === false;\n const resolved = await resolveCopy(facts, config, noCopy, deterministicCopy(facts, config.release?.maxHighlights));\n\n if (flags.dryRun === true) {\n const dry: ReleaseResult = {\n dryRun: true,\n facts,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n warnings: [],\n exitCode: 0,\n };\n if (resolved.warning !== undefined) {\n dry.copyWarning = resolved.warning;\n }\n return dry;\n }\n\n const renderer = await createTakumiRenderer();\n const generateInput: Parameters<typeof generate>[0] = {\n event,\n facts,\n brand,\n config,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n renderer,\n themes: resolveThemes(flags.themes, brand.theme),\n generatedAt: new Date().toISOString(),\n };\n const logos = await loadLogos(cwd, brand);\n if (logos !== undefined) {\n generateInput.logos = logos;\n }\n const result = await generate(generateInput);\n const packInput: Parameters<typeof finishPack>[0] = {\n flags,\n config,\n event,\n result,\n brand,\n copy: resolved.copy,\n copyMode: resolved.copyMode,\n facts,\n };\n if (resolved.warning !== undefined) {\n packInput.copyWarning = resolved.warning;\n }\n return finishPack(packInput);\n}\n\nfunction overlayReleaseConfig(config: Config, flags: ReleaseFlags): Config {\n const overlay = overlayFormats(config, flags);\n if (flags.templates === undefined) {\n return overlay;\n }\n return mergeConfig(DEFAULT_CONFIG, {\n ...overlay,\n release: {\n ...overlay.release,\n templates: flags.templates\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0),\n },\n });\n}\n","#!/usr/bin/env node\n// CLI entry: parse args, dispatch to commands/*\n// Spec: docs/PROJECT_PLAN.md §18\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { cac } from \"cac\";\nimport { runBench, type BenchFlags } from \"./commands/bench.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runMilestone, type MilestoneFlags } from \"./commands/milestone.js\";\nimport { runRelease, type ReleaseFlags } from \"./commands/release.js\";\nimport { ShipsealError, formatError } from \"./core/errors.js\";\nimport { resolvePackageRoot } from \"./render/takumi.js\";\n\nexport async function runCli(argv = process.argv): Promise<number> {\n process.exitCode = 0;\n const cli = cac(\"shipseal\");\n cli.option(\"--cwd <path>\", \"Working directory\", { default: process.cwd() });\n cli.option(\"--json\", \"Machine-readable JSON output\");\n cli.option(\"--quiet\", \"Suppress non-error output\");\n cli.option(\"--verbose\", \"Verbose output\");\n\n cli\n .command(\"init\", \"Detect brand and write .shipseal/brand.json + config.json\")\n .option(\"--yes\", \"Accept detections without prompting\")\n .option(\"--force\", \"Overwrite existing brand.json and config.json\")\n .action(async (flags: Record<string, unknown>) => {\n const result = await runInit({\n cwd: stringFlag(flags.cwd, process.cwd()),\n yes: flags.yes === true,\n force: flags.force === true,\n });\n if (flags.json === true) {\n process.stdout.write(`${JSON.stringify(result.detection.brand, null, 2)}\\n`);\n return;\n }\n if (flags.quiet !== true) {\n process.stdout.write(`Wrote ${result.brandPath}\\n`);\n process.stdout.write(`Wrote ${result.configPath}\\n`);\n process.stdout.write(`Sample card: ${result.samplePath}\\n`);\n for (const field of result.detection.sources) {\n process.stdout.write(` ${field.field}: ${field.source}\\n`);\n }\n // Notes carry the \"this is a built-in default, not your brand\" disclosures.\n // The interactive prompt already shows them, and --yes skips that prompt, so\n // without this the user never learns which colours were not detected.\n for (const note of result.detection.notes) {\n process.stdout.write(` note: ${note}\\n`);\n }\n }\n });\n\n cli.command(\"doctor\", \"Check Node, git, brand, fonts, and Takumi\").action(async (flags: Record<string, unknown>) => {\n const result = await runDoctor(stringFlag(flags.cwd, process.cwd()));\n if (flags.json === true) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else if (flags.quiet !== true) {\n for (const check of result.checks) {\n const mark = check.status === \"pass\" ? \"ok\" : check.status === \"fail\" ? \"FAIL\" : \"info\";\n process.stdout.write(`[${mark}] ${check.name}: ${check.message}\\n`);\n if (check.fix !== undefined && check.status === \"fail\") {\n process.stdout.write(` Fix: ${check.fix}\\n`);\n }\n }\n }\n if (!result.ok) {\n process.exitCode = 1;\n }\n });\n\n cli\n .command(\"release\", \"Generate the release pack\")\n .option(\"--tag <tag>\", \"Release tag\")\n .option(\"--from <tag>\", \"Previous tag\")\n .option(\"--formats <list>\", \"Comma-separated formats\")\n .option(\"--templates <list>\", \"Comma-separated templates\")\n .option(\"--themes <dark|light|both>\", \"Themes to render\")\n .option(\"--copy\", \"Allow optional LLM copy (default: on when config.copy.llm is true)\")\n .option(\"--out <dir>\", \"Output directory\")\n .option(\"--strict\", \"Fit warnings exit with code 2\")\n .option(\"--dry-run\", \"Collect facts and print them; render nothing\")\n .option(\"--package <path>\", \"package.json path for monorepos\")\n .option(\"--upload\", \"Upload PNG files to the GitHub release\")\n .action(async (flags: Record<string, unknown>) => {\n const releaseFlags: ReleaseFlags = {\n cwd: stringFlag(flags.cwd, process.cwd()),\n strict: flags.strict === true,\n dryRun: flags.dryRun === true,\n };\n applySharedFlags(releaseFlags, flags);\n const tag = optionalString(flags.tag);\n if (tag !== undefined) {\n releaseFlags.tag = tag;\n }\n const from = optionalString(flags.from);\n if (from !== undefined) {\n releaseFlags.from = from;\n }\n const templates = optionalString(flags.templates);\n if (templates !== undefined) {\n releaseFlags.templates = templates;\n }\n const result = await runRelease(releaseFlags);\n process.exitCode = result.exitCode;\n writeCommandOutput(flags, result);\n });\n\n cli\n .command(\"milestone\", \"Generate a milestone card for the highest crossed threshold\")\n .option(\"--metric <stars|downloads|contributors>\", \"Metric to check\")\n .option(\"--threshold <n>\", \"Force a specific threshold\")\n .option(\"--formats <list>\", \"Comma-separated formats\")\n .option(\"--themes <dark|light|both>\", \"Themes to render\")\n .option(\"--copy\", \"Allow optional LLM copy (default: on when config.copy.llm is true)\")\n .option(\"--out <dir>\", \"Output directory\")\n .option(\"--strict\", \"Fit warnings exit with code 2\")\n .option(\"--dry-run\", \"Collect facts and print them; render nothing\")\n .option(\"--package <path>\", \"package.json path for monorepos\")\n .action(async (flags: Record<string, unknown>) => {\n const milestoneFlags: MilestoneFlags = {\n cwd: stringFlag(flags.cwd, process.cwd()),\n strict: flags.strict === true,\n dryRun: flags.dryRun === true,\n };\n applySharedFlags(milestoneFlags, flags);\n const metric = optionalString(flags.metric);\n if (metric !== undefined) {\n milestoneFlags.metric = metric;\n }\n const threshold = optionalString(flags.threshold);\n if (threshold !== undefined) {\n milestoneFlags.threshold = threshold;\n }\n const result = await runMilestone(milestoneFlags);\n process.exitCode = result.exitCode;\n if (flags.json === true) {\n writeJson(resultToJson(result));\n return;\n }\n if (flags.quiet === true) {\n return;\n }\n if (result.skipped) {\n process.stdout.write(`${result.message ?? \"No milestone threshold crossed.\"}\\n`);\n return;\n }\n writeHumanResult(result);\n });\n\n cli\n .command(\"bench\", \"Generate benchmark cards from bench JSON\")\n .option(\"--file <path>\", \"Path to bench JSON\")\n .option(\"--formats <list>\", \"Comma-separated formats\")\n .option(\"--themes <dark|light|both>\", \"Themes to render\")\n .option(\"--copy\", \"Allow optional LLM copy (default: on when config.copy.llm is true)\")\n .option(\"--out <dir>\", \"Output directory\")\n .option(\"--strict\", \"Fit warnings exit with code 2\")\n .option(\"--dry-run\", \"Collect facts and print them; render nothing\")\n .option(\"--package <path>\", \"package.json path for monorepos\")\n .action(async (flags: Record<string, unknown>) => {\n const benchFlags: BenchFlags = {\n cwd: stringFlag(flags.cwd, process.cwd()),\n strict: flags.strict === true,\n dryRun: flags.dryRun === true,\n };\n applySharedFlags(benchFlags, flags);\n const file = optionalString(flags.file);\n if (file !== undefined) {\n benchFlags.file = file;\n }\n const result = await runBench(benchFlags);\n process.exitCode = result.exitCode;\n writeCommandOutput(flags, result);\n });\n\n cli.help();\n cli.version(readVersion());\n\n try {\n cli.parse(argv, { run: false });\n await cli.runMatchedCommand();\n return typeof process.exitCode === \"number\" ? process.exitCode : 0;\n } catch (error) {\n if (error instanceof ShipsealError) {\n process.stderr.write(`${formatError(error)}\\n`);\n return 1;\n }\n if (error instanceof Error) {\n process.stderr.write(`${error.message}\\n`);\n return 1;\n }\n throw error;\n }\n}\n\nfunction stringFlag(value: unknown, fallback: string): string {\n return typeof value === \"string\" && value.length > 0 ? value : fallback;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction applySharedFlags(target: { formats?: string; themes?: string; copy?: boolean; out?: string; package?: string; upload?: boolean }, flags: Record<string, unknown>): void {\n const formats = optionalString(flags.formats);\n if (formats !== undefined) {\n target.formats = formats;\n }\n const themes = optionalString(flags.themes);\n if (themes !== undefined) {\n target.themes = themes;\n }\n if (flags.copy === false) {\n target.copy = false;\n }\n const out = optionalString(flags.out);\n if (out !== undefined) {\n target.out = out;\n }\n const pkg = optionalString(flags.package);\n if (pkg !== undefined) {\n target.package = pkg;\n }\n if (flags.upload === true) {\n target.upload = true;\n }\n}\n\nfunction writeCommandOutput(\n flags: Record<string, unknown>,\n result: {\n dryRun: boolean;\n facts: unknown;\n dir?: string;\n manifest?: unknown;\n copyWarning?: string;\n warnings: Array<{ template: string; format: string; slot: string; action: string }>;\n skipped?: boolean;\n message?: string;\n },\n): void {\n if (flags.json === true) {\n writeJson(resultToJson(result));\n return;\n }\n if (flags.quiet === true) {\n return;\n }\n writeHumanResult(result);\n}\n\nfunction resultToJson(result: {\n dryRun: boolean;\n facts: unknown;\n dir?: string;\n manifest?: unknown;\n skipped?: boolean;\n message?: string;\n}): Record<string, unknown> {\n const payload: Record<string, unknown> = {};\n if (result.skipped === true) {\n payload.skipped = true;\n }\n if (result.message !== undefined) {\n payload.message = result.message;\n }\n if (result.dir !== undefined) {\n payload.dir = result.dir;\n }\n if (result.manifest !== undefined) {\n payload.manifest = result.manifest;\n } else {\n payload.facts = result.facts;\n }\n return payload;\n}\n\nfunction writeHumanResult(result: {\n dryRun: boolean;\n facts: unknown;\n dir?: string;\n copyWarning?: string;\n warnings: Array<{ template: string; format: string; slot: string; action: string }>;\n skipped?: boolean;\n message?: string;\n}): void {\n if (result.skipped === true) {\n process.stdout.write(`${result.message ?? \"Nothing to generate.\"}\\n`);\n return;\n }\n if (result.dryRun) {\n process.stdout.write(`${JSON.stringify(result.facts, null, 2)}\\n`);\n return;\n }\n if (result.dir !== undefined) {\n process.stdout.write(`Wrote ${result.dir}\\n`);\n }\n if (result.copyWarning !== undefined) {\n process.stdout.write(`Copy: ${result.copyWarning}\\n`);\n }\n for (const warning of result.warnings) {\n process.stdout.write(`Warning: ${warning.template} ${warning.format} ${warning.slot} ${warning.action}\\n`);\n }\n}\n\nfunction writeJson(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction readVersion(): string {\n const raw: unknown = JSON.parse(readFileSync(join(resolvePackageRoot(), \"package.json\"), \"utf8\"));\n if (typeof raw === \"object\" && raw !== null && \"version\" in raw && typeof raw.version === \"string\") {\n return raw.version;\n }\n return \"0.0.0\";\n}\n\nif (shouldRun(process.argv[1])) {\n void runCli().then((code) => {\n process.exit(code);\n });\n}\n\nfunction shouldRun(invoked: string | undefined): boolean {\n if (invoked === undefined) {\n return false;\n }\n const normalized = invoked.replaceAll(\"\\\\\", \"/\");\n return (\n normalized.endsWith(\"/cli.js\") ||\n normalized.endsWith(\"/cli.ts\") ||\n normalized.endsWith(\"/shipseal\")\n );\n}\n"],"mappings":"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"}