Edit Flow

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 flowagents and flowwrite tools, write locations, and how to fix validation errors.

83OpxScoreProvisional
Community resultNot enough feedback0 votes
Model evidenceNo verified tests
ClaudeChatGPTGemini+5

Score breakdown

Estimated from the available content and source signals.

Provisional
Documentation92
Practical value92
Evidence61
Source trust72

Model compatibility

Inferred fit is not the same as a recorded hands-on test.

ClaudeinferredThe skill text mentions Claude or a closely associated term.
ChatGPTinferredThe skill uses model-agnostic prompt or LLM terminology.
GeminiinferredThe skill uses model-agnostic prompt or LLM terminology.
CopilotinferredThe skill uses model-agnostic prompt or LLM terminology.
LlamainferredThe skill uses model-agnostic prompt or LLM terminology.
PerplexityinferredThe skill uses model-agnostic prompt or LLM terminology.
MistralinferredThe skill uses model-agnostic prompt or LLM terminology.
GrokinferredThe skill uses model-agnostic prompt or LLM terminology.

Overview

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_agentsop: "list" returns the agent catalog; op: "write" validates and writes an agent .md to .pi/flows/agents/<name>.md (filename derived from the agent's frontmatter name).
  • flow_writenamespace (default custom), 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: true is set in .pi/settings.json (project, when trusted) or ~/.pi/agent/settings.json (global). If flow_agents/flow_write are not available, tell the user to enable that setting and restart the session.

Workflow

  1. Clarify what the user wants the flow to do. Ask if it is unclear.
  2. Call flow_agents with op: "list" to see existing agents and their inputs, outputs, and source_type. Reuse built-in/local agents where they fit.
  3. For each role not already covered, author a purpose-built agent with flow_agents op: "write". Do not repurpose infrastructure agents (flow-decision, project-context-reader) for unrelated tasks.
  4. Author the flow with flow_write. Wire every declared input. Fix any validation diagnostics and retry.
  5. 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}}
FieldRequiredNotes
nameYesUnique. Filename = <name>.md. Referenced as agent: <name> in steps.
descriptionYesOne line. Shown in catalog.
modelYesSee Model references.
toolsYesComma-separated. Guard blocks anything not listed. Standard: read, write, edit, grep, find, ls, bash, ask_user, skill_read.
thinkingNooff/minimal/low/medium/high/xhigh. Overrides any :level suffix in model.
skillsNoComma-separated skill names injected into the prompt.
inputsNoNames → ${{input.NAME}} in the prompt. Flow step must wire each one.
outputsNoNames (or {name, description} objects). Become finish parameters and ${{result.STEP.NAME}} downstream.
interactiveNotrue allows mid-task UI prompts. Default false.
outputNoOutput file hint (display only).
accessNoread/write glob allowlists; bash.deny command patterns. * = segment, ** = any depth.
cardNolabel, metric (default/files/tests/custom), role.
architectNouse_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.

FormExampleWhen
@role (preferred)model: @codingDefault. Resolves via the active role→model map (/roles). Built-in roles: @planning, @coding, @fast, @architect.
provider/model[:thinking]model: anthropic/claude-haiku-4-5:highA specific provider+model is required; optional :thinking suffix sets the thinking level.
bare model-idmodel: claude-haiku-4-5A 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

  1. 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
    
  2. fork — user (or agent: in autonomous mode) picks a branch.
    - 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: false
    
    Branch keys must match options exactly.
  3. conditional — presence/absence of a result field.
    - id: has-gaps
      type: conditional
      check: research.artifacts   # stepId.field
      present: gap-filler
      absent: finalize
    
  4. agent-decision — agent calls finish({ branch }) to choose.
    - id: complexity
      type: agent-decision
      agent: analyzer
      task: Simple or complex?
      branches: { simple: quick, complex: thorough }
    
  5. 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
    
  6. 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_ID is the step id, 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)

ContentToolLands at
Agentflow_agents op: write.pi/flows/agents/<name>.md
Flowflow_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, tools for agents; name, description for flows) → add it.
  • "Agent not in catalog" → the flow references an agent that does not exist. Create it with flow_agents op: write, then retry flow_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.

Best for

  • Clarify what the user wants the flow to do. Ask if it is unclear.
  • Call flowagents with op: "list" to see existing agents and their inputs, outputs, and sourcetype. Reuse built-in/local agents where they fit.
  • For each role not already covered, author a purpose-built agent with flowagents op: "write". Do not repurpose infrastructure agents (flow-decision, project-context-reader) for unrelated tasks.
  • Author the flow with flowwrite. Wire every declared input. Fix any validation diagnostics and retry.
  • Tell the user the resulting command name (/<namespace>:<name>).

Tips and best practices

  • Review the source instructions and adapt inputs before running the workflow.

What This Skill Can Do

AI-generated examples showing real capabilities

Was this skill useful?

Be the first to share a result.

Related skills