From essentials
Validates prd.json schema for Ralph TUI workflows. Ensures required fields like name, userStories array, story id/title in .claude/prd/*.json before editing or reviewing.
npx claudepluginhub gantisstorm/essentials-claude-code --plugin essentialsThis skill is limited to using the following tools:
prd.json schema reference from [Ralph TUI](https://github.com/subsy/ralph-tui). Use this when creating, editing, or reviewing `.claude/prd/*.json` files.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
prd.json schema reference from Ralph TUI. Use this when creating, editing, or reviewing .claude/prd/*.json files.
Invoke /prd-schema before editing any prd.json file. Invoke /prd-schema validate <path> to check an existing file.
prd.json files are typically created by /tasks-converter from architectural plans (.claude/plans/*-plan.md). The pipeline:
/plan-creator (or /bug-plan-creator, /code-quality-plan-creator)
↓ writes
.claude/plans/{slug}-{hash5}-plan.md
↓ consumed by
/tasks-converter <plan-path>
↓ writes
.claude/prd/<slug>.json
↓ executed by
/tasks-loop or /tasks-swarm or ralph-tui
How plan sections map to prd.json fields:
| Plan Section | prd.json Field |
|---|---|
## Summary | name, description |
## Files | One user story per file (typically) |
### Requirements | acceptanceCriteria[] |
### Reference Implementation | description (full code copied verbatim) |
### Migration Pattern | description (before/after code copied verbatim) |
## Dependency Graph | dependsOn[] (file deps translated to story IDs) |
## Exit Criteria | acceptanceCriteria[] |
| Plan path | metadata.planReference |
Each story's description must be 100% self-contained — the executor agent receives only the story description, never the source plan. All code, requirements, and verification commands are copied verbatim from the plan into the story.
{
"name": "string (REQUIRED)",
"description": "string (optional)",
"branchName": "string (optional)",
"userStories": ["array (REQUIRED, see below)"],
"metadata": {
"createdAt": "ISO 8601 string (optional)",
"updatedAt": "ISO 8601 string (auto-set on write)",
"version": "string (optional)",
"sourcePrd": "string — path to source PRD markdown (optional)"
}
}
project is accepted as an alias for name, but name is preferred.
{
"id": "string (REQUIRED) — e.g. 'US-001'",
"title": "string (REQUIRED)",
"description": "string (optional)",
"acceptanceCriteria": ["string[] (optional)"],
"priority": "number (optional, default: 2) — 1=highest, 4=lowest",
"passes": "boolean (REQUIRED) — false=incomplete, true=complete",
"labels": ["string[] (optional)"],
"dependsOn": ["string[] (optional) — IDs of blocking stories"],
"notes": "string (optional)",
"completionNotes": "string (optional, alias for notes)"
}
| Scope | Field | Type |
|---|---|---|
| Root | name | string |
| Root | userStories | array (1+ elements) |
| Story | id | string |
| Story | title | string |
| Story | passes | boolean |
| Field | Why It's Wrong |
|---|---|
prd | Don't wrap content in a prd key |
tasks | Use userStories, not tasks |
status | Use passes (boolean), not status (string) |
subtasks | Flat list only, no nesting |
estimated_hours | No time tracking |
files | Not part of schema |
assignee | Not part of schema |
type | Not part of schema |
epic | Not part of schema |
parent | Not part of schema |
dependsOn is an array of story IDs. A story is blocked until all its dependencies have passes: true.
{
"id": "US-003",
"title": "Integration tests",
"dependsOn": ["US-001", "US-002"],
"passes": false
}
Ralph TUI selects the next task by:
passes: falsedependsOn resolved (passes: true)priority (lowest number first){
"name": "My Feature",
"userStories": [
{
"id": "US-001",
"title": "First task",
"passes": false
}
]
}
{
"name": "User Authentication",
"description": "Add user authentication to the application",
"branchName": "feature/auth",
"userStories": [
{
"id": "US-001",
"title": "Create login page",
"description": "Build login form with email and password fields.",
"acceptanceCriteria": [
"Form has email and password inputs",
"Form validates required fields",
"Submit button is disabled during submission"
],
"priority": 1,
"passes": false,
"dependsOn": []
},
{
"id": "US-002",
"title": "Implement authentication API",
"description": "POST /api/auth/login endpoint that verifies credentials and returns JWT.",
"acceptanceCriteria": [
"POST /api/auth/login accepts email and password",
"Returns JWT token on success",
"Returns 401 on invalid credentials"
],
"priority": 1,
"passes": false,
"dependsOn": []
},
{
"id": "US-003",
"title": "Connect login form to API",
"description": "Wire up the login form to call the authentication API.",
"acceptanceCriteria": [
"Form submits to /api/auth/login",
"Success stores token and redirects",
"Error shows message to user"
],
"priority": 2,
"passes": false,
"dependsOn": ["US-001", "US-002"]
}
],
"metadata": {
"createdAt": "2024-01-15T10:00:00Z",
"version": "1.0"
}
}
Parse $ARGUMENTS to determine mode.
$ARGUMENTS starts with validate:Extract the path from $ARGUMENTS (e.g., /prd-schema validate .claude/prd/auth.json).
Read the file and check for schema violations:
# Check for rejected top-level fields
jq 'keys[] | select(. == "prd" or . == "tasks")' <path>
# Check every story has required fields
jq '.userStories[] | select(.id == null or .title == null or .passes == null) | .id // "unnamed"' <path>
# Check for unsupported story fields
jq '.userStories[] | to_entries[] | select(.key | test("^(subtasks|estimated_hours|files|status|assignee|type|epic|parent)$")) | "\(.key) in story"' <path>
Report each violation with the fix from the schema above.
$ARGUMENTS is empty:Output the schema summary:
prd.json Schema (Ralph TUI)
Root: name (req), description, branchName, userStories (req), metadata
Story: id (req), title (req), passes (req), description, acceptanceCriteria, priority, labels, dependsOn, notes, completionNotes
Rejected fields: prd, tasks, status, subtasks, estimated_hours, files, assignee, type, epic, parent
Use "passes: false" (not "status: open"). Use "userStories" (not "tasks").