Skip to content

feat(pipeline): add format-detecting ingest stage with content extraction#146

Merged
PAMulligan merged 1 commit into
mainfrom
feat/pipeline-ingest-stage
Jun 21, 2026
Merged

feat(pipeline): add format-detecting ingest stage with content extraction#146
PAMulligan merged 1 commit into
mainfrom
feat/pipeline-ingest-stage

Conversation

@PAMulligan

Copy link
Copy Markdown
Collaborator

Summary

Adds a new ingest stage at the front of the InDesign→FSE pipeline
(ingest → map → generate). Unlike the per-format parse-idml/parse-pdf
bins — which dispatch on file extension and emit only design/geometry — this
stage sniffs the source bytes and extracts semantic content that the IR
previously didn't capture.

  • detect.js — format detection by magic bytes: PK + the literal
    designmap.xml manifest name ⇒ IDML (zip filenames are stored uncompressed,
    so this works even though entry data is deflated); %PDF- ⇒ PDF. Works on
    extensionless files and streams.
  • content.js — the ETL transform: walks spreads → frames → stories →
    styles to build a reading-order content model (headings with font-size-
    inferred levels h1–h6, paragraphs, figures), a flat outline, and stats. Pure
    and deterministic.
  • ingest/index.jsingestSource/ingestBuffer (detect → parse →
    Document.parse re-validate → enrich) and toArtifact.
  • bin/ingest.mjsflavian-ingest CLI (file or stdin, --out,
    --format, --dpi, --no-content). Runnable via pnpm pipeline:ingest.

The content model is attached under an additive content key the mapper and
generator ignore, so the artifact stays a valid Document and the shared IR
schema is not forked
(project invariant). The enriched artifact pipes straight
into generate-theme.

Test plan

New tests (fixtures generated in code — no binary blobs, per pipeline convention):

  • ingest-detect.test.mjs — IDML/PDF/plain-zip/garbage detection.
  • ingest-content.test.mjs — reading-order sort, multi-level heading inference,
    figures, run grouping, dangling-ref accounting.
  • ingest.test.mjs — end-to-end IDML + PDF ingest, determinism, and proof the
    artifact is generator-consumable.

Verified locally:

  • pnpm --filter @flavian/pipeline test118 pass / 0 fail (18 new).
  • InDesign smoke test + tests/fixtures/indesign/fixtures.test.mjs → pass (no regression).
  • CLI end-to-end: IDML→artifact→theme; PDF via binary stdin; auto-detect a PDF
    from an extensionless file
    ; unrecognized input exits 1.
  • commitlint on the commit message → pass.

🤖 Generated with Claude Code

…tion

Add a front-of-pipeline ingest stage for the InDesign->FSE pipeline. Where the
per-format parse bins dispatch on file extension and only emit design/geometry,
this stage sniffs the source bytes (Zip + designmap.xml = IDML, %PDF- = PDF),
parses to the canonical IR, re-validates it against the schema, and derives a
reading-order content model: each editorial spread becomes a section of blocks
(headings with font-size-inferred levels h1-h6, paragraphs, figures), plus a
flat outline and stats.

The content model is attached under an additive `content` key the mapper and
generator ignore, so the artifact remains a valid Document and the shared IR
schema is not forked. Exposed as `flavian-ingest` and `pnpm pipeline:ingest`.

- src/indesign/ingest/{detect,content,index}.js + bin/ingest.mjs
- exports + bin wiring + root pnpm script
- tests: byte detection, content transform, end-to-end ingest (IDML + PDF),
  determinism, and generator-consumability
- docs/pipeline/ingest-stage.md

Redence-Proof-Token: RDNC-8EU6UU

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@PAMulligan PAMulligan merged commit 082f75d into main Jun 21, 2026
20 checks passed
@PAMulligan PAMulligan deleted the feat/pipeline-ingest-stage branch June 21, 2026 21:27
PAMulligan pushed a commit that referenced this pull request Jun 22, 2026
…p-tokens, and flavian indesign

The positional-capture guard `!arg.startsWith('-')` incorrectly rejected
a bare `-` because `'-'.startsWith('-')` is true. Add `arg === '-'` as
an explicit early condition so the stdin sentinel is captured before the
dash check, matching the pattern already used in flavian-ingest (ref #146).

Affected: packages/pipeline/bin/generate-theme.mjs:68
          packages/pipeline/bin/map-tokens.mjs:60
          bin/flavian.mjs:80

Fixes #148
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant