/**
* Scaffold + upstream import primitives.
*
* `EMPTY_DESIGN_MD` is the canonical 9-section skeleton Mandu ships
* for `mandu design init` (no `--from`). It contains heading slots and
* a one-line hint per section so users / agents can fill it in.
*
* `fetchUpstreamDesignMd(slug)` pulls a brand DESIGN.md from VoltAgent's
* awesome-design-md repository (raw GitHub). The function is a thin
* fetch wrapper — caller decides what to do with the body (validate +
* write, dry-run + diff, etc.).
*
* @module core/design/scaffold
*/
/**
* Raw GitHub base for awesome-design-md. Public, MIT licensed.
* Each brand lives at `//DESIGN.md`.
*/
export const AWESOME_DESIGN_MD_RAW_BASE =
"https://raw.githubusercontent.com/VoltAgent/awesome-design-md/main";
/**
* Empty 9-section DESIGN.md skeleton. Meant to be filled in
* incrementally — Mandu's point is that DESIGN.md is a *living*
* artifact, not a one-shot deliverable.
*/
export const EMPTY_DESIGN_MD = `# DESIGN.md
> Living design system spec for this project. AI agents and developers
> read this file before touching UI. See
> https://github.com/VoltAgent/awesome-design-md for examples.
>
> Fill sections incrementally — \`mandu design extract\` (coming soon)
> can propose tokens from your existing code.
## Visual Theme & Philosophy
## Color Palette
## Typography
## Components
## Layout
## Depth & Elevation
## Do's & Don'ts
## Responsive
## Agent Prompts
`;
export interface FetchUpstreamOptions {
/** Override base URL (test fixtures, mirrors). */
baseUrl?: string;
/** AbortSignal so callers can cancel a slow fetch. */
signal?: AbortSignal;
}
/**
* Fetch a DESIGN.md from awesome-design-md by brand slug.
* Throws on HTTP error — the caller (CLI command) catches and prints
* a user-facing message rather than letting it bubble.
*/
export async function fetchUpstreamDesignMd(
slugOrUrl: string,
options: FetchUpstreamOptions = {},
): Promise {
const url = isAbsoluteUrl(slugOrUrl)
? slugOrUrl
: `${options.baseUrl ?? AWESOME_DESIGN_MD_RAW_BASE}/${encodeURIComponent(slugOrUrl)}/DESIGN.md`;
const res = await fetch(url, { signal: options.signal });
if (!res.ok) {
throw new Error(
`fetchUpstreamDesignMd: GET ${url} → HTTP ${res.status} ${res.statusText}`,
);
}
return res.text();
}
function isAbsoluteUrl(s: string): boolean {
return /^https?:\/\//i.test(s);
}