Day 1 (monorepo + Node layout engine): - Turborepo + pnpm workspaces with apps/web, apps/render-worker, and packages for types, layout-engine, prompts, api-lib. - @banner-studio/types: BannerSpec contract, every layer kind, ResolvedLayer, zod schemas mirroring each interface. - @banner-studio/layout-engine: Dropflow WASM wrapper, text measurement, shrink-to-fit, push_siblings, resolveLayout. Snapshot-tested. Day 2 (browser parity + AI pipeline): - Layout engine ./browser subpath: same resolveLayout in the browser via Dropflow WASM build. Quarantined wasm-locator import (dropflow 0.5.1 exports gap). - Cross-group push_siblings bug fix: deltas now thread through group recursion via a shared accumulator; regression test added. - DEMO_TEMPLATE_300x250 promoted to packages/layout-engine/src/templates/. - @banner-studio/prompts: versioned extract + generate prompts with zod-defined tool schemas (claude-sonnet-4-6, forced tool-use). - @banner-studio/api-lib: CSV feed loader, extract/generate/route-node/ assemble agents, orchestrator returning fully-resolved BannerSpec. Generate agent retries on character-limit overflow. - apps/web (Next.js 14 App Router): /api/generate route, /parity diff page, promise-singleton browser engine init. - feeds/demo.csv with five hand-authored rows of varied length. - SLICE_DEVIATIONS.md documents the five intentional gaps from ARCHITECTURE.md with V1 reversal paths. Verified end-to-end: POST /api/generate against the live Claude API returns three resolved BannerSpecs and two honestly-skipped rows (overflow after two attempts). 26 unit + integration tests passing. |
||
|---|---|---|
| .. | ||
| demo.csv | ||
| README.md | ||
/feeds
Slice-only convention. The CSVs in here are inputs to the AI orchestration pipeline. In V1 this folder goes away — the Feed/Brief service receives campaign feeds through an upload API and the Template service owns the column mapping.
demo.csv
Hand-authored five-row demo feed. Row lengths are deliberately varied so the slice shows Generate doing real work and exercising the shrink/push cascade.
Columns:
raw_description— freeform product description. The Extract agent parses this into structured fields.product— product name. Treated as ground truth.offer— optional. If present, the Generate agent is allowed to reference it in the headline or subheadline.hero_image_url— URL of the hero image. Routed onto the SmartAssetLayer'sdirect_url. SLICE_ONLY: in V1 this becomes a variant group selection.click_url— landing page URL. Written onto BannerSpec.click_destinations.