# poetry-extract API

Domain-to-theme extraction: fetch a site's design signals and compose a DESIGN.md + token set from them.

## Poetry::Extract::Runner

The orchestration: fetch -> compose -> derive -> write. Never touches
the theme - the printed handoff goes through poetry:design:import,
where the AA gate stays the single door.

### .normalize_domain(domain)

Reduce a URL or bare domain to its lowercase host.

### .run!(domain, out_root: OUT_ROOT, signals: nil, composer: Compose, io: $stdout)

Extract a domain's design system: fetch the signals, compose
DESIGN.md, derive the two token stylesheets, and write all three
files under out_root. Prints the poetry:design:import handoff
command - importing is deliberately left to the AA gate.

### .validate!(design_md, io)

The composed document must at least parse as DESIGN.md; a missing
frontmatter is a warning, not a failure - prose-only documents
still carry the body sections, and import will say so again.

## Poetry

The poetry namespace.

## Poetry::Extract

The optional design-extraction gem: domain in, theme out. Produces a
DESIGN.md + deterministic token stylesheets and hands them to
poetry-core's AA-gated design importer - never the theme directly.

## Poetry::Extract::Compose

The one model call: compose DESIGN.md from the fetched signals. The
prompt spec is adapted from an MIT-licensed source (source and
license in THIRD_PARTY_NOTICES.md). Direct Anthropic Messages API
over Net::HTTP - no SDK dependency; the screenshot rides as a
URL-source image block.

### .design_md(domain:, signals:, http: method(:post_anthropic))

Compose the DESIGN.md document for a domain from its fetched
signals in one model call; the screenshot, when present, is
attached as an image block.

## Poetry::Extract::Error

The gem's one error class: fetch, compose, and write failures all
raise it (missing API keys included).

## Poetry::Extract::Fetch

The fetch layer. Primary path: the context.dev SDK (the gem's one
service dependency - same four calls as upstream). Degraded path (no
CONTEXT_DEV_API_KEY): a plain homepage fetch for the markdown signal,
nil for the rest - extraction still works, on less evidence.

### .signals(domain, client: default_client, homepage_fetcher: method(:fetch_homepage))

Fetch the four design signals for a domain. Without a client
(CONTEXT_DEV_API_KEY unset) it takes the degraded path: homepage
markdown only, every other signal nil.

## Poetry::Extract::Railtie

Installs the poetry:design:extract task into any Rails host the
moment the gem is bundled.

## Poetry::Extract::Signals

The four design signals for a domain. Any member may be nil - the
derivers and the prompt both accept the degraded shape.

### #brand

Returns the value of attribute brand

### #brand=(value)

Sets the attribute brand

### #markdown

Returns the value of attribute markdown

### #markdown=(value)

Sets the attribute markdown

### #screenshot_url

Returns the value of attribute screenshot_url

### #screenshot_url=(value)

Sets the attribute screenshot_url

### #styleguide

Returns the value of attribute styleguide

### #styleguide=(value)

Sets the attribute styleguide