reliant-labs/reliant/workflow-builder
Claude Code and agent skill by reliant-labs/reliant
- community
Checking that the SKILL.md file is still in the repository.
Build a bot or agent that runs on a schedule or event (cron, webhook, twice a day, daily digest, monitor, triage); also multi-agent Reliant workflows. Use to create, edit, test or debug any workflow.
Install
npx vskill@latest install reliant-labs/reliant/workflow-builderSKILL.md
Workflow Builder
You build Reliant workflows. Your goal: create working workflows that solve the user's problem.
Threading, context, loops, parallelization, inputs, prompts, error handling and composition have their own do's-and-don'ts reference: skill(action="load", path="workflow-builder/design-patterns"). Load it before designing a workflow's control flow.
When to use
- Building an agent or automation that runs on its own: on a schedule ("every morning", "twice a day", cron), on a webhook or an app event — a bot, monitor, digest or triage job, even when it sounds like "just a script"
- Creating a new Reliant workflow from scratch
- Editing or extending an existing workflow
- Debugging workflow execution issues
- Writing scenario tests for workflows
- Understanding workflow patterns and best practices
Approach
Every workflow tool that targets an existing workflow (get_workflow, edit_workflow, write_workflow, and the scenario tools) requires an explicit id — a UUID, slug, or name. Nothing binds this chat to a workflow, so there is no "current workflow"; any chat can work on any workflow.
Starting from scratch? Call create_workflow first — it returns the new draft's id, name, and slug. Pass that id to every subsequent call. Omit both name and content to get a random name and the default agent template; pass content with complete workflow YAML to start from a specific design.
Editing an existing workflow? Find it with list_workflows and pass its id or slug. If the user's message names a workflow (e.g. "Workflow swift-fox-a1b2: ..."), use that as the id.
Follow this process:
- Setup — New workflow: call
create_workflow. Existing workflow: callget_workflowwith itsidto see current content. - Understand — Ask clarifying questions about the user's goal
- Learn — Use
list_workflowsto see examples and patterns,list_presets/get_presetto see what
agent presets exist before inventing a system prompt from scratch. Calling an external service? search_integrations finds the action ref and get_integration_schema its params before you write the node
- Explore — Read the user's codebase (test commands, code patterns). Note: references to "workflows" and "nodes" in user code are unlikely to be Reliant-specific.
- Build — Use
edit_workflowfor small changes,write_workflowfor larger rewrites - Test — Create and run scenarios (aim for 3+ covering positive, negative, and edge cases). Try to break your workflow. It's frustrating for users to run a workflow for an hour and hit a bug at the end—scenarios catch this early.
Working in a chat that isn't running this preset? These tools are still reachable: load_tool(name="tag:workflow") loads all of them on demand.
Key concepts
Workflows are DAGs
Every workflow must be a directed acyclic graph. You cannot create cycles in the graph structure. Use loop nodes (with while conditions) for iterative behavior.
CEL expressions
Two syntax modes:
- `condition` / `while` fields: Pure CEL — no
{{}}wrapping
``yaml condition: "nodes.llm.stop_reason == 'tool_use'" while: "outputs.stop_reason in ['tool_use', 'incomplete', 'truncated', 'interrupted'] && iter.iteration < 50" ``
- All other fields: Template interpolation with
{{}}
``yaml model: "{{inputs.model}}" system_prompt: "You are helping with {{inputs.task}}" ``
Always use has() or safe navigation (object.?field) before accessing optional fields.
Template rules. A {{ }} is read as CEL, so a brace inside a string literal is data ({{ x.startsWith('{') }} works) and a newline inside it is whitespace (a folded >- scalar is fine). A {{ that never closes, an empty {{ }} and an expression that does not parse are validation errors with the field path and line/column, never literal text; write a literal {{ as {{ '{{' }}. Raw-CEL fields (condition, while, a trigger filter) take no {{ }}. Inside an inline type: workflow body, templates are evaluated in the BODY's scope when it runs (its own inputs and nodes), not the parent's.
Deterministic logic belongs in the workflow, not a script. Use a type: compute node (below) for labels, size buckets, lease expiry, id validation and parsing a node's JSON stdout. Expressions have Strings, Lists, Sets, Math, Encoders, Bindings, Regex, optional types, timestamps and durations, and json.decode(s) (tolerant: an optional, .?status.orValue('error')) beside the strict parseJson(s). Evaluation is cost-bounded (a runaway expression fails with cost limit exceeded). The CEL reference has a table of worked helper expressions. Test an expression with `cel_eval` before writing it into a workflow.
Compute node
type: compute computes named outputs from CEL in the workflow: no model, no shell, no worker, no mock needed in a scenario. outputs: maps a name to a value; a value that is exactly one {{ }} keeps its type, text around it makes a string, a non-string is a literal. Read them as nodes.<id>.<name> (validation checks the names; values are dyn, so compare a boolean output in a condition: nodes.facts.ready == true). Outputs cannot read each other: chain two compute nodes. A failing expression fails the node.
Publishing a branch
type: git_publish commits a worktree's changes and pushes them to a feature branch with no shell ever holding a credential. Pair it with credentials: none on the editing shell.
Refused (the node completes with refused: true and a refusal, it does not fail): the default branch, protected branches, main, master, release/*, names that are not plain branches, branches outside allow, a pull request head in a fork. Never forces: a diverged remote is refused. No changes means pushed: false and no error. Outputs: pushed, sha, branch, base_sha, files_changed, insertions, deletions, refused, refusal. Route on them: condition: nodes.publish.pushed == true. The push is recorded in the write ledger with its sha, so its events carry trigger.origin. In a scenario, mock the node's outputs like any activity.
Shells without credentials
credentials: none removes GitHub, git, ssh and cloud credentials from a command's environment: no GH_TOKEN/GITHUB_TOKEN, no ssh agent, no cloud variables, no kubeconfig, git's credential helpers reset, GIT_TERMINAL_PROMPT=0, an empty GH_CONFIG_DIR. A git push or gh pr merge from it fails to authenticate at once and never prompts. Set it for an agent's shell with tools_config.tools.shell (bound, so the model is never shown it) and on a run node with credentials: none.
On Linux (every Reliant cloud machine) the command also runs in a sandbox where the daemon's credential files are absent (~/.reliant/daemon.json, ~/.config/forge, ~/.git-credentials, ~/.ssh, ~/.config/gh, kubeconfig and cloud files, the container engine's socket), sees only its own processes, and has no capabilities. It shares the network and can write its working directory, and on macOS and Windows only the environment is scrubbed. Never tell an agent to look elsewhere for a token; publish with a git_publish node.
Threading
Modes: inherit (default), new, fork
- inherit: Reuse parent thread (default)
- new: Create a fresh thread
- fork: Copy parent thread into a new one
Key rules:
- Use
memoin loops to reuse the same thread across iterations - Use
injectto prepend a message when entering a sub-workflow - Never run parallel agents on the same thread simultaneously
Edge routing
- Multiple
caseson one edge = exactly 1 executes (first match wins) - All cases require a
condition— usedefaultfor the fallback - For parallelism: create multiple edges from the same source node, OR use
default: [node-a, node-b]
Syntactic sugar
These shorthands compile to standard nodes/edges at parse time. They are not in the proto — purely YAML convenience.
sequence: sugar
A top-level workflow field (alongside name:, nodes:, edges:) that replaces the combination of entry:, nodes:, and sequential edges: for linear chains.
Rules:
- Cannot coexist with
entry:(it implies entry from the first node) - CAN coexist with
nodes:andedges:for mixed patterns (e.g., linear main flow with extra branches) - Compiles to standard
entry:+nodes:+edges:at parse time
Before (explicit):
After (sugar):
type: parallel sugar
A node type used inside nodes: that desugars into branch nodes + a join node + fan-out/fan-in edges.
Rules:
- Must have
id:andbranches:fields branches:is a list of regular node definitions- The parallel node's
idbecomes the join node's id (so downstream edges referencing it still work) - Join uses
condition: all(all branches must complete) - Incoming edges targeting the parallel node get rewritten to fan-out to all branches
Before (explicit):
After (sugar):
Triggers: when a workflow runs
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckinginternal/skills/catalog/builtin/workflow-builder/SKILL.md
Popularity
- Repository stars
- 60
- Repository forks
- 5
- 7-day trend score
- 21
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/reliant-labs/reliant/workflow-builder)