feat(media): add image/video/audio project kinds via od media generate
Introduce non-web media surfaces (image, video, audio) as first-class project kinds. The unifying contract is "skill workflow + project metadata tell the agent WHAT to make; one shell command — od media generate — is HOW bytes are produced", so any code-agent CLI with shell access can drive it without bespoke tools. - Frontend: New Project panel gains Image/Video/Audio tabs with model picker, aspect/length/duration controls, and audio kind/voice selection. Examples and Design Systems tabs gain layered sections. FileViewer renders the generated image/video/audio files. - Shared registry: src/media/models.ts is the single source of truth for image/video/audio model IDs, aspects, and defaults — consumed by the picker AND the daemon dispatcher. - Prompts: media-contract.ts is pinned LAST in the system prompt for media surfaces so its hard rules (call od media generate, don't emit binary in <artifact>, allowed model IDs) win over softer earlier wording. - Daemon: new media.js dispatcher + media-models.js JSON view of the registry; cli.js gets the `od media generate` subcommand wired up via server.js / projects.js so the daemon writes files back into the project dir. - Skills: audio-jingle, image-poster, video-shortform seed examples for the three surfaces. Made-with: Cursor
This commit is contained in:
@@ -29,6 +29,11 @@ export async function listDesignSystems(root) {
|
||||
category: extractCategory(raw) ?? 'Uncategorized',
|
||||
summary: summarize(raw),
|
||||
swatches: extractSwatches(raw),
|
||||
// Optional `> Surface: image|video|audio` blockquote line. Most
|
||||
// existing systems target the web surface and don't declare it;
|
||||
// we default to 'web' so the right-side filter classifies them
|
||||
// correctly.
|
||||
surface: extractSurface(raw),
|
||||
body: raw,
|
||||
});
|
||||
} catch {
|
||||
@@ -67,6 +72,14 @@ function extractCategory(raw) {
|
||||
return m?.[1];
|
||||
}
|
||||
|
||||
const KNOWN_SURFACES = new Set(['web', 'image', 'video', 'audio']);
|
||||
function extractSurface(raw) {
|
||||
const m = /^>\s*Surface:\s*(.+?)\s*$/im.exec(raw);
|
||||
if (!m) return 'web';
|
||||
const v = m[1].trim().toLowerCase();
|
||||
return KNOWN_SURFACES.has(v) ? v : 'web';
|
||||
}
|
||||
|
||||
// Strip boilerplate like "Design System Inspired by Cohere" → "Cohere" so
|
||||
// the picker dropdown reads cleanly. Hand-authored titles that don't match
|
||||
// the pattern (e.g. "Neutral Modern") pass through unchanged.
|
||||
|
||||
Reference in New Issue
Block a user