agentsclimarketplace

Write flow

Skill 45ck/prompt-language/skills/write-flow

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.From its SKILL.md

Install
npx -y skills add 45ck/prompt-language --skill write-flow

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

7.5 KB, as published. Nobody here has run it

Write a Flow

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.

Step 1: Do You Need a Flow?

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):

  • "Rename the User class to Account" — no verification command
  • "Add a docstring to every public method" — no pass/fail gate
  • "Explain how the auth module works" — informational
  • "Create a new React component for the sidebar" — Claude does this fine without scaffolding

Flow adds value:

  • "Fix the auth tests so they pass" — gate: tests_pass
  • "Make the build pipeline green" — gate: tests_pass + lint_pass
  • "Migrate the database and verify it works" — gate: tests or a custom command
  • "Apply this refactoring to 8 files without breaking tests" — gate: tests_pass, loop: foreach

If 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.

Step 2: Pick Your Gate(s)

Gates are the entire reason to use a flow. Always write done when: first.

Available predicates:

JavaScript/TypeScript:

  • tests_pass — npm test exits 0
  • lint_pass — npm run lint exits 0
  • tests_fail — passes when tests exit non-zero (for "break this" tasks)
  • lint_fail — passes when lint exits non-zero

Python:

  • pytest_pass — pytest exits 0
  • pytest_fail — passes when pytest exits non-zero

Go:

  • go_test_pass — go test ./... exits 0
  • go_test_fail — passes when go test exits non-zero

Rust:

  • cargo_test_pass — cargo test exits 0
  • cargo_test_fail — passes when cargo test exits non-zero

General:

  • diff_nonempty — passes when git diff has output
  • file_exists <path> — passes when the file exists

Compound gates catch more issues:

done when:
  tests_pass
  lint_pass

Step 3: Choose Your Loop Pattern

The Ralph Loop (the core pattern)

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 loops
  • until command_succeeded for inverted condition loops

Foreach (batch operations)

For 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

Single prompt + gate (simplest)

When Claude just needs to do the work and a gate verifies it:

flow:
  prompt: Fix the failing tests

done when:
  tests_pass

Step 4: Stop — Check for Over-engineering

Before outputting the flow, check for these anti-patterns.

For the full anti-pattern catalog and deeper examples, see:

  • references/anti-patterns.md
  • references/advanced.md

Anti-pattern: Sequential prompts

BAD — 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.

Anti-pattern: file_exists gates for things Claude already does

BAD — 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.

Anti-pattern: Variables at short distances

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.

Anti-pattern: Control flow for "organization"

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

Anti-pattern: Flows longer than 10 lines

If your flow block exceeds 10 lines, you're almost certainly over-engineering. Simplify. Combine prompts. Remove unnecessary variables. Trust Claude to handle sequencing.

Output

Write the flow in a fenced code block, or say "no flow needed" and write a plain prompt instead.

Always explain:

  • What the gate enforces and why mechanical verification matters for this task
  • Why a plain prompt wouldn't be sufficient (if you chose a flow)

Advanced (available but rarely needed)

These features exist but should be the exception, not the default:

  • Try/catch — 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 branching — if/else for conditional paths. Usually indicates the flow is trying to do too much. Consider splitting into separate tasks.
  • Variable capture — 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/until loops — while condition/until condition for open-ended loops. retry max N is preferred for bounded iteration.

Additional advanced guidance and tradeoffs:

  • references/advanced.md

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.