Edit Flow
Create and edit pi-flows flows and agents in your session.
Installation
- Make sure Claude is on your device and in your terminal.
Skills load from
~/.claude/skills/when Claude Code starts up β so you need it on your machine first. If you don't have it yet, install it once with the command below, then runclaudein any terminal to verify.One-time setupnpm i -g @anthropic-ai/claude-codeAlready have it? Skip ahead.
- Paste into Claude Code or into your terminal.
This copies the whole skill folder into
~/.claude/skills/edit-flow-blackbelttechnology/β the SKILL.md plus any scripts, reference docs, or templates the skill ships with. Safe default: works for every skill.Faster alternative (instruction-only skills)
Skips the clone and grabs only the SKILL.md file. Don't use this if the skill ships Python scripts, reference markdowns, or asset templates β they won't be downloaded and the skill will fail when it tries to load them.
Quick install (SKILL.md only)Sign up to copy - Restart Claude Code.
Quit and reopen Claude Code (or any other agent that loads from
~/.claude/skills/). New skills are picked up on startup. - Just ask Claude.
Skills auto-activate when your request matches the skill's description β no slash command needed. Trigger phrases live in the skill's own frontmatter; you can read them in the βWhat this skill doesβ section above.
Prefer to read the source first? Open on GitHub.
When Claude uses it
Create and edit pi-flows flows and agents from the main session. Use when the user wants to create a new flow, add or change an agent, or edit an existing flow/agent. Covers agent frontmatter, flow YAML, step types, model references, the flow_agents and flow_write tools, write locations, and how to fix validation errors.
What this skill does
Edit Flow
You are creating and editing pi-flows flows and agents directly in this session. Two tools do the writing (both validate before writing and return diagnostics on failure):
flow_agentsβop: "list"returns the agent catalog;op: "write"validates and writes an agent.mdto.pi/flows/agents/<name>.md(filename derived from the agent's frontmattername).flow_writeβnamespace(defaultcustom),name,content. Validates and writes a flow to.pi/flows/flows/<namespace>/<name>.yaml, which auto-registers as the/<namespace>:<name>command.
These tools derive their write locations from the discovery convention β there is no raw path. Writing to a name that already exists overwrites it (that is how you edit).
The edit-flow tools are off by default. They are active only when
flows.editFlow: trueis set in.pi/settings.json(project, when trusted) or~/.pi/agent/settings.json(global). Ifflow_agents/flow_writeare not available, tell the user to enable that setting and restart the session.
Workflow
- Clarify what the user wants the flow to do. Ask if it is unclear.
- Call
flow_agentswithop: "list"to see existing agents and theirinputs,outputs, andsource_type. Reusebuilt-in/localagents where they fit. - For each role not already covered, author a purpose-built agent with
flow_agentsop: "write". Do not repurpose infrastructure agents (flow-decision,project-context-reader) for unrelated tasks. - Author the flow with
flow_write. Wire every declared input. Fix any validation diagnostics and retry. - Tell the user the resulting command name (
/<namespace>:<name>).
Editing an existing flow/agent = read the current file, change it, then write it back with the same tool and the same name/namespace.
Agent files (.md)
YAML frontmatter + Markdown body (the system prompt).
---
name: code-reviewer
description: Reviews source code for quality and correctness
model: @coding
thinking: medium
tools: read, grep, find
inputs:
- research_context
outputs:
- name: findings
description: Categorized issues found
- name: verdict
description: "pass" or "fail"
access:
read:
- "src/**"
write:
- "src/**"
bash:
deny:
- "rm -rf *"
card:
label: "Reviewer"
metric: "default"
architect:
use_when: "User wants code reviewed for quality"
produces: "A findings report and a pass/fail verdict"
depends_on: "An implementer must have produced code"
domain: "review"
---
# System Prompt
You are a code reviewer. Task: ${{task}}
Context: ${{input.research_context}}
| Field | Required | Notes |
|---|---|---|
name | Yes | Unique. Filename = <name>.md. Referenced as agent: <name> in steps. |
description | Yes | One line. Shown in catalog. |
model | Yes | See Model references. |
tools | Yes | Comma-separated. Guard blocks anything not listed. Standard: read, write, edit, grep, find, ls, bash, ask_user, skill_read. |
thinking | No | off/minimal/low/medium/high/xhigh. Overrides any :level suffix in model. |
skills | No | Comma-separated skill names injected into the prompt. |
inputs | No | Names β ${{input.NAME}} in the prompt. Flow step must wire each one. |
outputs | No | Names (or {name, description} objects). Become finish parameters and ${{result.STEP.NAME}} downstream. |
interactive | No | true allows mid-task UI prompts. Default false. |
output | No | Output file hint (display only). |
access | No | read/write glob allowlists; bash.deny command patterns. * = segment, ** = any depth. |
card | No | label, metric (default/files/tests/custom), role. |
architect | No | use_when/produces/depends_on/domain metadata surfaced in flow_agents op: list. |
Model references
The model: field accepts three forms. Prefer @role. Use the other two when a specific model is required regardless of role config, or when the user explicitly asks for a non-role model.
| Form | Example | When |
|---|---|---|
@role (preferred) | model: @coding | Default. Resolves via the active roleβmodel map (/roles). Built-in roles: @planning, @coding, @fast, @architect. |
provider/model[:thinking] | model: anthropic/claude-haiku-4-5:high | A specific provider+model is required; optional :thinking suffix sets the thinking level. |
bare model-id | model: claude-haiku-4-5 | A specific model id with no provider qualifier; thinking comes from the thinking: field or none. |
A thinking: field always overrides any :thinking suffix in model.
Flow files (.yaml)
name: my-flow # REQUIRED
description: What it does # REQUIRED
max_concurrent: 3 # optional (default 4)
task_required: true # optional β prompt for task if invoked with no args
task_prompt: "Task:" # optional
steps:
- id: research
agent: code-reviewer
task: Review ${{task}}
name is the frontmatter name; the command name comes from the on-disk location (namespace/name you pass to flow_write). Every step needs a unique id. Step type is usually inferred from which fields are present; set type: explicitly when ambiguous.
Step types
- agent β dispatch an agent.
- id: impl agent: implementer task: Implement ${{task}} blockedBy: [research] inputs: ctx: ${{result.research.summary}} on_complete: verify # optional cross-segment jump on_error: handler # optional - fork β user (or
agent:in autonomous mode) picks a branch.Branch keys must match- id: choose type: fork question: Which strategy? options: [Fast, Full] branches: { Fast: fast-impl, Full: full-impl } agent: flow-decision # autonomous-mode decider allowCustom: false multiSelect: falseoptionsexactly. - conditional β presence/absence of a result field.
- id: has-gaps type: conditional check: research.artifacts # stepId.field present: gap-filler absent: finalize - agent-decision β agent calls
finish({ branch })to choose.- id: complexity type: agent-decision agent: analyzer task: Simple or complex? branches: { simple: quick, complex: thorough } - agent-loop-decision β loop back or exit.
- id: should-fix type: agent-loop-decision agent: flow-decision task: Iteration ${{loop.should-fix.iteration}}/${{loop.should-fix.max}}. ${{result.verify.summary}} loop_target: fixer # jump back exit_target: done # continue forward max_iterations: 3 - flow-ref β delegate to another flow file.
- id: sub type: flow-ref path: "project/changes/*/exec.yaml" # glob ok on_complete: verify
Template variables
Expanded in task, inputs values, and question. Not validated β a typo silently becomes empty string.
${{task}}β the user task.${{input.NAME}}β input wired into this step.${{result.STEP_ID.status|summary|artifacts|files|fullOutput|OUTPUTNAME}}βSTEP_IDis the stepid, not the agent name.${{loop.STEP_ID.iteration|max}}β loop counters.
Wire data between steps via inputs: (agent declares names in frontmatter, step supplies values). Prefix an input value with file:// to inject file content verbatim; that file's producer step must be in blockedBy.
Write locations (discovery)
| Content | Tool | Lands at |
|---|---|---|
| Agent | flow_agents op: write | .pi/flows/agents/<name>.md |
| Flow | flow_write | .pi/flows/flows/<namespace>/<name>.yaml β /<namespace>:<name> |
Project-local definitions (.pi/flows/) override package and built-in ones.
Fixing validation errors
Both tools validate before writing. On failure they return { written: false, diagnostics: [...] } and write nothing. Read each diagnostic's message and suggestion, fix the content, and call the tool again. Common cases:
- Missing required field (
name,description,model,toolsfor agents;name,descriptionfor flows) β add it. - "Agent not in catalog" β the flow references an agent that does not exist. Create it with
flow_agentsop: write, then retryflow_write. - Unwired declared input β add the missing key to the step's
inputs:block. - Unknown tool in
tools:β use a valid tool name (see the standard list above) or an extension-registered tool name. - Invalid YAML β fix indentation/quoting; re-validate.
Related skills
PDF Tools & Editing
anthropics
Read, merge, split, rotate, watermark, encrypt, and extract text from PDF files.
PowerPoint Slide Decks
anthropics
Create, edit, read, and extract content from PowerPoint presentations.
Slack GIF Creator
anthropics
Create animated GIFs optimized for Slack messages and emojis.
Honest Postmortem Analyzer
alirezarezvani
Analyze what went wrong in failures without blame to find real causes.