From prompt-language
This skill should be used when the user asks to 'write a flow', 'create a flow', 'design a flow', 'make a flow for', 'I need a flow', or wants to create a prompt-language flow for a task. Decides whether a flow is needed at all — most tasks don't need one.
npx claudepluginhub 45ck/prompt-language --plugin prompt-languageThis skill is limited to using the following tools:
Given a task description, decide whether a prompt-language flow adds value. **Most tasks don't need one.** Claude Code already retries on failure, checks if files exist, and follows multi-step instructions. The DSL's narrow but powerful value: mechanically enforcing completion criteria via real command execution, so Claude can't stop early.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Given a task description, decide whether a prompt-language flow adds value. Most tasks don't need one. Claude Code already retries on failure, checks if files exist, and follows multi-step instructions. The DSL's narrow but powerful value: mechanically enforcing completion criteria via real command execution, so Claude can't stop early.
Ask one question: "Is there a command that must exit 0 before this task is done?"
Task --> Has verifiable completion command (test/lint/build)?
Yes --> Could Claude skip or shortcut verification?
Yes --> USE A FLOW WITH GATE
No --> Plain prompt is fine
No --> PLAIN PROMPT
No flow needed (just write a plain prompt):
Flow adds value:
tests_passtests_pass + lint_passtests_pass, loop: foreachIf the task doesn't need a flow, write a clear plain-language prompt and stop. Don't add DSL overhead for tasks that don't benefit from it.
Gates are the entire reason to use a flow. Always write done when: first.
Available predicates:
JavaScript/TypeScript:
tests_pass — npm test exits 0lint_pass — npm run lint exits 0tests_fail — passes when tests exit non-zero (for "break this" tasks)lint_fail — passes when lint exits non-zeroPython:
pytest_pass — pytest exits 0pytest_fail — passes when pytest exits non-zeroGo:
go_test_pass — go test ./... exits 0go_test_fail — passes when go test exits non-zeroRust:
cargo_test_pass — cargo test exits 0cargo_test_fail — passes when cargo test exits non-zeroGeneral:
diff_nonempty — passes when git diff has outputfile_exists <path> — passes when the file existsCompound gates catch more issues:
done when:
tests_pass
lint_pass
This is prompt-language as an advanced custom Ralph Loop — the same concept (keep iterating until done) but with mechanical verification. Gates run actual commands; Claude can't declare victory until they pass.
flow:
retry max 5
run: npm test
if command_failed
prompt: Fix the failing tests. Read the errors carefully.
end
end
done when:
tests_pass
Why this works: Claude already retries when asked — but without a gate, it can decide "close enough" and stop. The gate forces every iteration to prove the fix worked. Eval data shows this pattern consistently outperforms both plain prompts (on verification-heavy tasks) and over-engineered multi-phase flows.
Variations:
retry max N for bounded retries (prefer this — it has a clear limit)while command_failed for condition-based loopsuntil command_succeeded for inverted condition loopsFor applying the same operation across a list of items:
flow:
foreach file in "src/auth.ts src/db.ts src/api.ts"
prompt: Add error handling to ${file}
run: npm test
end
done when:
tests_pass
When Claude just needs to do the work and a gate verifies it:
flow:
prompt: Fix the failing tests
done when:
tests_pass
Before outputting the flow, check for these anti-patterns.
For the full anti-pattern catalog and deeper examples, see:
references/anti-patterns.mdreferences/advanced.mdBAD — 3 prompts that could be 1:
flow:
prompt: Read the codebase and understand the architecture
prompt: Write a plan for the migration
prompt: Execute the migration
BETTER — one prompt, one gate:
flow:
prompt: Migrate the database schema. Read the codebase first, plan your approach, then execute.
done when:
tests_pass
Claude follows multi-step instructions naturally. Sequential prompts add latency without improving quality.
file_exists gates for things Claude already doesBAD — Claude always creates the file when asked:
done when:
file_exists src/components/Sidebar.tsx
BETTER — plain prompt, no flow:
Create a Sidebar component at src/components/Sidebar.tsx
Only use file_exists when the file is a build artifact or side effect that proves a pipeline worked.
BAD — variable used 2 lines later:
flow:
let version = run "node -v"
prompt: Check compatibility with Node ${version}
BETTER — Claude can just run the command itself:
flow:
prompt: Check the Node version and ensure the code is compatible
done when:
tests_pass
Only use let when the value must span many steps or feed into a foreach.
BAD — phased structure that adds latency:
flow:
run: npm run lint
if command_failed
retry max 3
prompt: Fix lint errors
run: npm run lint
end
end
run: npm test
if command_failed
retry max 3
prompt: Fix test failures
run: npm test
end
end
BETTER — single loop, let Claude figure out the order:
flow:
retry max 5
run: npm run lint && npm test
if command_failed
prompt: The pipeline failed. Read the errors, fix the issues, and try again.
end
end
done when:
tests_pass
lint_pass
If your flow block exceeds 10 lines, you're almost certainly over-engineering. Simplify. Combine prompts. Remove unnecessary variables. Trust Claude to handle sequencing.
Write the flow in a fenced code block, or say "no flow needed" and write a plain prompt instead.
Always explain:
These features exist but should be the exception, not the default:
try/catch blocks for when a specific command might fail and needs distinct recovery. Most errors are handled fine by the Ralph Loop's if command_failed branch.if/else for conditional paths. Usually indicates the flow is trying to do too much. Consider splitting into separate tasks.let x = run "cmd" or let x = prompt "text" for storing values. Only useful when a value must cross many steps or drive a foreach loop.while condition/until condition for open-ended loops. retry max N is preferred for bounded iteration.Additional advanced guidance and tradeoffs:
references/advanced.md