AI agent skill

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.

·

When to use this skill

Use Edit Flow when an AI agent needs a reusable SKILL.md workflow for this job: 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.

When not to use it

Skip Edit Flow when the task is outside the coding category, or when a more specific skill in this directory already covers the same workflow with clearer triggers.

How to install

  1. Personal install: create ~/.claude/skills/edit-flow/SKILL.md (and any bundled scripts) so Claude Code, Claude Desktop, and compatible agents can load it in every project.
  2. Project install: commit the same folder at .claude/skills/edit-flow/ so teammates get the skill with the repo.
  3. Restart the agent session after copying files so it re-scans the skills directory, then ask for the task in words that match the skill description.

Full install guide for Claude, Cursor, and Codex

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 `.md` to `.pi/flows/agents/<name>.md` (filename derived from the agent's frontmatter `name`). - `flow_write` — `namespace` (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).

```markdown --- 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`)

```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. ```yaml - 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. ```yaml - 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. ```yaml - id: has-gaps type: conditional check: research.artifacts # stepId.field present: gap-filler absent: finalize ``` 4. **agent-decision** — agent calls `finish({ branch })` to choose. ```yaml - id: complexity type: agent-decision agent: analyzer task: Simple or complex? branches: { simple: quick, complex: thorough } ``` 5. **agent-loop-decision** — loop back or exit. ```yaml - 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. ```yaml - 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)

| 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`, `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.

Intended uses

  • 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>).

Related skills

Related skills in this directory, for comparison before you install another skill.

coding

Add Backend

Guide for adding a backend (Rust or Python) to the agent-sec-core security middleware. Use when creating new backends, integrating Rust or Python code into the security middleware, or extending with new backend actions.

View skill

coding

Agent Device

Drive iOS and Android devices for the Expensify App - testing, debugging, performance profiling, bug reproduction, and feature verification. Use when the developer needs to interact with the mobile app on a device.

View skill

Ranked Claude skills