| name | prd-component |
| description | Create a structured PRD (Product Requirements Document) as a JSON task file with prioritized stories for automated execution. Ralph is the project's task runner script that processes stories sequentially. Use this skill whenever the user wants to plan work, break down a feature into stories, create a task plan, or prepare a batch of component migrations. Triggers: create PRD, plan tasks, break down work, create stories, task planning, batch migration, ralph, plan component work. |
PRD Intake (Generic)
Use this skill to generate prd.json that works for component migration, bugfixing, backend logic, or mixed work.
Ralph is the project's automated task runner (.agents/skills/prd-component/ralph.sh). It reads a PRD JSON file, iterates through stories in priority order, and executes each one by spawning Claude with the story's context and execution skill. Stories are retried up to maxIterationsPerStory times until acceptance criteria pass.
Output
- Primary:
.agents/tasks/<prd-name>.json (e.g. .agents/tasks/prd-navbar-redesign.json)
- Templates:
.agents/skills/prd-component/assets/prd.template.json (generic)
.agents/skills/prd-component/assets/prd.template.component.json
.agents/skills/prd-component/assets/prd.template.bugfix.json
.agents/skills/prd-component/assets/prd.template.backend.json
Canonical Structure
Use this root contract:
{
"project": "",
"branchName": "",
"description": "",
"loopConfig": {},
"stories": [],
"generatedAt": "",
"status": "ready"
}
stories[] is canonical. Keep compatibility with legacy keys only when ingesting old PRDs.
Optional root constraints (recommended):
constraints
rules
nonGoals
qualityGates
successMetrics
goals
uiNotes
These are passed into loop prompts as a global constraints context.
loopConfig
Recommended defaults:
{
"maxIterationsPerStory": 3,
"maxStagnantIterations": 2,
"orderedByPriority": true,
"memoryFile": "tmp/ralph-memory.jsonl",
"autonomy": {
"noQuestions": true,
"assumeBestJudgment": true
},
"requiredChecks": [],
"finalReview": {
"enabled": true,
"minScore": 8,
"maxPasses": 3
}
}
Notes:
mode is optional metadata/context only; do not rely on it for hard validation.
requiredChecks should list concrete commands/checks for the current task type.
autonomy.noQuestions=true means the agent must not pause to ask clarifying questions.
autonomy.assumeBestJudgment=true means ambiguous details are resolved by defaults and logged as assumptions.
Story Shape
Each story should use:
{
"id": "US-001",
"title": "",
"description": "",
"status": "open",
"priority": 1,
"passes": false,
"notes": "",
"dependsOn": [],
"acceptanceCriteria": [],
"loopState": {
"phase": "queued",
"status": "pending",
"attempt": 0,
"errors": []
},
"data": {},
"metadata": {
"executionSkill": ""
}
}
Guidelines:
- Keep reusable, scheduler-relevant fields at the story root.
- Put domain-specific payload in
data.
- Put operational hints/checkpoints/tags in
metadata.
dependsOn: array of story IDs that must pass before this story can run.
Component Migration Convention
For stories that copy/migrate components from strapi.io, the /copy-component skill must be used. It contains critical extraction logic (Playwright computed styles, design token mapping, responsive diffing, reuse auditing) that cannot be replicated by ad-hoc implementation.
Required fields
data.copyComponentInput — single source of truth for /copy-component execution params. See the "Inputs (Intake Contract)" section in copy-component/SKILL.md for the full contract schema and field definitions.
metadata.executionSkill = "copy-component" — required for deterministic skill routing. The ralph runner uses this to inject a mandatory skill invocation instruction into the executor prompt. Without it, the LLM may attempt manual implementation.
Story description guidance
The story description must explicitly reference the skill — this is what the LLM reads first and plans around:
Good: "Use /copy-component skill to extract, map, and generate the pricing hero section. Pass data.copyComponentInput as the intake contract."
Bad: "Copy the pricing hero section with simplified schema and token-mapped Tailwind." (The LLM will try to do this manually.)
Acceptance criteria
Always include /copy-component skill was invoked with data.copyComponentInput plus the quality checks from copy-component/references/quality-checks.md as applicable.
Other conventions
- Do not duplicate
copyComponentInput fields as top-level data.* camelCase keys — copyComponentInput is the authoritative execution payload.
- Use
metadata.checkpoints for restart/write/review requirements.
URL/Selector Auto-Detection
When the user provides a source URL (e.g. strapi.io/*, or any URL pointing to a live website) AND a CSS selector / XPath / section identifier / section description, the story IS a copy-component migration story. Apply these rules automatically:
- Set
metadata.executionSkill = "copy-component".
- Fill
data.copyComponentInput with the user's exact values:
source_url: the URL the user provided (verbatim)
selector: the CSS selector or XPath the user provided (verbatim)
component_name: derive from selector context or user description (kebab-case)
goal: derive from user description
content_constraints: from user notes, or "none"
reuse_mode: from user input, default "balanced"
shadcn_mode: default "prefer-existing"
acceptance_profile: default "balanced-default"
category: from user input, default "sections"
- If the user provides multiple URLs for the same component (variants), fill
source_urls array in copyComponentInput.
- Use the story description template from "Story description guidance" above.
- Include the standard copy-component acceptance criteria from "Acceptance criteria" above.
Critical: URLs and selectors MUST appear in data.copyComponentInput — not only in acceptance criteria or description text. The ralph runner reads copyComponentInput to construct the skill invocation prompt. If the data is only in free-text fields, the skill will not receive it.
Validation Rules
A story is runnable when:
id, title, priority, acceptanceCriteria exist.
loopState.status is not blocked.
status (if present) is not blocked.
- All stories in
dependsOn have passes=true (skip, don't block, if unmet).
- Required
data for that story type is present.
- If
metadata.executionSkill = "copy-component":
data.copyComponentInput MUST exist.
data.copyComponentInput.source_url MUST be a non-empty URL string.
data.copyComponentInput.selector MUST be a non-empty string.
data.copyComponentInput.component_name MUST be a non-empty kebab-case string.
- If any of these are missing or empty, the story is invalid.
- If
metadata.executionSkill = "consolidate-patterns":
data.batch_story_ids MUST be a non-empty array of story ID strings.
- If missing, the story is invalid.
If invalid:
- keep story in
stories[]
- set
loopState.status = "blocked"
- append exact reasons to
loopState.errors
Batch Migration from Manifest
When the user provides a manifest file (markdown) listing multiple components to migrate, generate one PRD with all components as stories plus interleaved consolidation checkpoints.
Manifest format
Each component is a markdown H2 heading followed by structured fields:
## component-name
- **URL**: https://strapi.io/page
- **Selector**: section:nth-of-type(2)
- **Variants**: https://strapi.io/other-page | selector: .hero-section | variant: enterprise
- **Notes**: Has dark background variant, 3-column card grid
- **Category**: sections
- **Reuse mode**: balanced
Field defaults when omitted:
- Category:
sections
- Reuse mode:
balanced
- Shadcn mode:
prefer-existing
- Content constraints:
none
Generation rules
- Read the manifest and parse each H2 entry.
- Generate one story per component using the Component Migration Convention format:
metadata.executionSkill = "copy-component"
data.copyComponentInput filled from manifest fields (apply URL/Selector Auto-Detection rules)
- If Variants field is present, parse each variant entry and populate
source_urls array in copyComponentInput
- Story description uses the standard copy-component template
- Include all standard copy-component acceptance criteria
- Insert consolidation checkpoint every 3-4 component stories:
metadata.executionSkill = "consolidate-patterns"
data.batch_story_ids lists the IDs of the preceding 3-4 component stories
data.min_occurrences = 2
dependsOn lists all preceding component story IDs in the batch
- Subsequent component stories
dependsOn the checkpoint story
- Title:
"Consolidation checkpoint: review {component names} for reusable patterns"
- Acceptance criteria:
["Recently created components reviewed for reusable patterns", "Any extracted elementary components pass typecheck", "docs/component-registry.md updated if new atoms created"]
- Priority ordering: Component stories in manifest order (priority 1, 2, 3, ...), checkpoint stories inserted at the appropriate priority between batches.
- PRD naming: Use
prd-batch-migration-{date}.json or user-specified name.
Example output structure
For a manifest with 7 components (A, B, C, D, E, F, G):
| Priority | ID | Type | dependsOn |
|---|
| 1 | US-001 | Component A | [] |
| 2 | US-002 | Component B | [] |
| 3 | US-003 | Component C | [] |
| 4 | US-004 | Checkpoint | [001, 002, 003] |
| 5 | US-005 | Component D | [004] |
| 6 | US-006 | Component E | [004] |
| 7 | US-007 | Component F | [004] |
| 8 | US-008 | Checkpoint | [005, 006, 007] |
| 9 | US-009 | Component G | [008] |
| 10 | US-010 | Checkpoint | [009] |
Guardrails
- One file per session: All features discussed in a single planning session go into one PRD file under
.agents/tasks/. Never split related work into multiple PRD files — use dependsOn in stories to express ordering.
- Naming convention: Use
prd-<kebab-case-name>.json (e.g. prd-navbar-redesign.json, prd-auth-flow.json).
- Append to existing PRDs: If a PRD file already exists at the target path, read it first and append new stories (continuing the ID sequence). Merge top-level arrays (goals, nonGoals, rules, etc.) — do not overwrite existing entries.
- One story should map to one coherent unit of work.
- Keep IDs stable for retry idempotency.
- Never hide blockers; write them to
loopState.errors and notes.
- Prefer explicit checks in
loopConfig.requiredChecks over implicit assumptions.
- Default loop posture is autonomous: no user Q&A mid-run, assumptions logged instead.
See Also
.agents/skills/prd-component/ralph.sh
.agents/skills/copy-component/SKILL.md
.agents/skills/create-content-component/SKILL.md
.agents/skills/seed-content/SKILL.md