MCPInstall

graph

Graph engineering for parallel task execution: convert a task, PRD, SPEC, or issue set into a dependency graph (DAG), layer it into supersteps, then implement each independent node concurrently with subagents — each node runs /goal → /review-it → /ship-it in an isolated git worktree, with a fan-in barrier between waves. Triggers on: graph, graph engineering, build a graph, task graph, dependency graph, DAG, parallel implement, 并发实现, 并行实现, 任务图, 把任务变成图, fan-out fan-in, superstep, dynamic workflow.

Installs
252
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/smallnest/goal-workflow --skill graph
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads graph automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

graph — Task/PRD to Parallel Execution Graph

Turn a task (or PRD / SPEC / issue set) into a directed acyclic graph of work units, layer it into supersteps (waves), and implement each wave's independent nodes concurrently using subagents. Each node runs the full /goal → /review-it → /ship-it pipeline inside its own git worktree, so parallel nodes never clobber each other's working tree. Between waves, a fan-in barrier merges results and re-plans the next wave.

This is the parallel sibling of /loop-it. /loop-it is strictly sequential (one worktree, one issue at a time). /graph fans out every independent node in a wave at once.


Mental Model (borrowed from LangGraph / graph engineering)

ConceptHere
NodeOne implementable unit of work (an issue / subtask)
EdgeA dependency: B depends on A → edge A → B
Superstep / waveA set of nodes whose deps are all satisfied — run concurrently
Fan-outDispatch one subagent per node in the current wave
Fan-in (barrier)Wait for all nodes in the wave before starting the next
State channel.graph_state — shared checkpoint, rewritten between waves (resume source)
Live trackergraph.html — Claude-style light-theme dashboard, re-rendered from .graph_state at every checkpoint
Dynamic re-planAfter a wave, revise the graph if new work/deps emerged

Core principle: Independent nodes in the same wave have no shared state and no ordering dependency, so they can run in true parallel. Dependencies define the only ordering. Everything else runs at once.


Overview

Input (task / PRD / SPEC / issues)
        │
        ▼
1. Decompose into nodes  ─────────►  nodes = {id, title, deps, criteria, scope}
        │
        ▼
2. Build DAG + validate  ─────────►  detect cycles, orphan deps
        │
        ▼
3. Topological layering  ─────────►  waves = [[n1,n2,n3], [n4,n5], [n6]]
        │
        ▼
4. Render graph + confirm with user
        │
        ▼  (write .graph_state + graph.html — open graph.html to watch live)
┌──────────── per wave (superstep) ────────────┐
│                                               │
│  FAN-OUT: 1 subagent per node (parallel)      │
│    each subagent, in its own git worktree:    │
│      /goal (inline implement) → /review-it    │
│                              → /ship-it        │
│                                               │
│  FAN-IN barrier: wait for ALL nodes           │
│    integrate, update .graph_state             │
│    re-render graph.html                        │
│    re-plan next wave if graph changed         │
│                                               │
└───────────────────────────────────────────────┘
        │
        ▼
All waves done → final summary

Step 1: Locate & Decompose Input

Accept any of: a free-form task description, a PRD/SPEC file, or an existing issue set (GitHub / local .md).

  • PRD/SPEC → reuse /to-issues decomposition rules (one node per User Story; split large, merge tiny).
  • Existing issues → each issue is a node; parse dependencies from issue bodies (Depends on: #3, Dependencies: #3, #5).
  • Free-form task → break into the smallest independently-shippable units yourself.

Each node MUST have:

Node #N
  title:      short imperative title
  deps:       [list of node ids] or []
  criteria:   acceptance criteria (checklist) — how the subagent knows it's done
  type:       backend | frontend | fullstack | ui | infra | docs
  scope_hint: which files/dirs this node is expected to touch (for conflict analysis)

scope_hint matters: two nodes with no dependency edge but overlapping file scope are not truly independent — see Step 3.


Step 2: Build the DAG & Validate

Construct edges from deps. Then validate:

CheckAction on failure
Cycle (A → B → A)Print ⚠️ 循环依赖: #A ↔ #B. Break by node id order, warn user, ask to confirm or fix.
Dangling dep (#7 depends on #99, no such node)Print warning, drop the phantom edge.
Scope collision (two dep-free nodes edit same files)Add a soft edge to serialize them (lower id first), OR flag for user. Never let two parallel worktrees fight over the same files.

Hot-file exception: A shared wiring file that nearly every node must touch (e.g. router.go, main.go, mod.rs, a DI container, an __init__ re-export) does NOT count as a scope collision — treating it as one would serialize the entire graph into a chain. For such files, assume append-only edits merge cleanly, and prefer one of: (a) designate a single node that owns wiring and have others expose a registration hook, or (b) do a tiny follow-up "wire everything" node in the last wave. Reserve the collision rule for nodes that edit the same logic in the same file (e.g. two handlers rewriting the same function).


Step 3: Topological Layering into Waves

Compute waves via Kahn's algorithm:

  1. Wave 0 = all nodes with deps == [] and no scope collision among themselves.
  2. Remove wave-0 nodes; Wave 1 = nodes whose deps are now all satisfied.
  3. Repeat until all nodes placed.
  4. Within a wave, if two nodes edit the same logic in the same file (real collision, per the hot-file exception in Step 2), push the higher-id one to the next wave. Bare wiring-file overlap does not trigger this.

ID conventions (used consistently): lower id wins — cycles break by lowest id first (Step 2), and scope collisions serialize with the lower id first (higher id deferred to the next wave).

Print the layered plan:

📊 Graph: 6 nodes, 3 waves

Wave 0 (parallel ×3):  #1 db schema   #2 config loader   #3 logging util
Wave 1 (parallel ×2):  #4 API handler (deps #1)   #5 CLI flags (deps #2)
Wave 2 (parallel ×1):  #6 integration (deps #4,#5)

Max parallelism: 3 subagents in Wave 0.

Also emit a Mermaid diagram for the user:

```mermaid
graph LR
  n1[#1 db schema] --> n4[#4 API handler]
  n2[#2 config loader] --> n5[#5 CLI flags]
  n3[#3 logging util]
  n4 --> n6[#6 integration]
  n5 --> n6
```

Wait for user confirmation before dispatching any subagent. Let them adjust nodes, deps, or the max-parallelism cap.


Step 4: Pre-flight Checks

Before the first wave (same spirit as /loop-it):

git rev-parse --is-inside-work-tree   # in a repo?
git status --porcelain                # clean tree? (dirty → stash/abort)
git branch --show-current             # on main/master?
git ls-remote --heads origin          # remote reachable?
gh auth status                        # if shipping to GitHub

Any hard failure → print the error and stop. Confirm a max concurrency cap with the user (default 3–4 parallel subagents; more risks rate limits and review noise).

Then initialize the state channel + live tracker (do this once, right after the plan is confirmed and before the first fan-out):

# 1. Write the initial checkpoint (all nodes pending, current_wave 0).
cat > .graph_state <<'JSON'
{ "version": 1, "task": "...", "repo": "owner/repo",
  "waves": [[1,2,3],[4,5],[6]], "current_wave": 0,
  "nodes": { "1": {"title":"...","deps":[],"status":"pending","wave":0}, ... } }
JSON

# 2. Keep it out of git.
grep -qxF '.graph_state' .gitignore || printf '.graph_state\ngraph.html\n' >> .gitignore

# 3. Render the Claude-style light-theme dashboard.
python3 skills/graph/scripts/render_graph_html.py .graph_state graph.html

Tell the user: open graph.html in a browser — it auto-refreshes every 5s, so it tracks execution live (waves, node statuses, progress bar, and a Mermaid DAG colored by status). Re-run the render command at every checkpoint (see Step 5b) to push updates.


Step 5: Execute Wave by Wave (fan-out → fan-in)

For each wave, in order:

5a. FAN-OUT — one subagent per node, in parallel

Dispatch all nodes of the wave in a single response (multiple Agent/subagent calls in one message = concurrent). Each subagent works in its own git worktree so parallel file edits never collide:

# The orchestrator creates a worktree per node BEFORE dispatching:
git worktree add -b feat/node-{N}-{slug} ../.graph-worktrees/node-{N} main

Each subagent receives a self-contained prompt (it does NOT inherit orchestrator context):

You are implementing ONE node of a task graph, working in an ISOLATED git worktree.

Worktree:  ../.graph-worktrees/node-{N}   (already created on branch feat/node-{N}-{slug})
Node #{N}: {title}
Type:      {type}
Scope:     {scope_hint}  — stay within these files; do not touch other nodes' scope

Acceptance criteria (all must pass):
- [ ] {criterion 1}
- [ ] {criterion 2}

Context (deps already merged into main, pull first):
{summaries of dependency nodes' outputs, or the referenced PRD/SPEC excerpt}

Your pipeline (run all three, in order):
1. IMPLEMENT (inline /goal): read the node + any referenced PRD/SPEC, read adjacent
   code, implement to satisfy EVERY acceptance criterion, run build + tests + lint
   (e.g. go build ./... && go vet ./... && go test ./...). Iterate until all green.
2. REVIEW (/review-it): run code review on your changes, apply accepted findings,
   re-run focused tests, repeat until review is clean (max 2 rounds).
3. SHIP (/ship-it): commit (message references the node/issue), push branch,
   create PR, merge, close the issue.

Constraints:
- Work ONLY inside your worktree. Do NOT edit files outside {scope_hint}.
- Do NOT try to call `goal` via the Skill tool (it's a UI command, not a skill) —
  "implement" means you write the code yourself. /review-it and /ship-it ARE skills.
- If you cannot satisfy a criterion, STOP and report what's blocking — don't fake it.

Return: node id, PASS/FAIL, PR/commit refs, files changed, and — if you discovered new required work or a dependency the graph didn't capture — a `NEW_WORK:` line describing it (title + which nodes it blocks). Emit `NEW_WORK: none` if there's nothing.

Why worktrees, not branches alone: /goal mutates the working tree. Two subagents editing the same checkout would corrupt each other. A worktree per node gives each its own filesystem checkout on its own branch — that's what makes the wave genuinely parallel and safe.

5b. FAN-IN — barrier, integrate, re-plan

Wait for every subagent in the wave to return (BSP barrier — the next wave cannot start until this one commits). Then:

  1. Read each subagent's summary. Mark node shipped or failed.
  2. git checkout main && git pull — dependency outputs are now on main for the next wave.
  3. Remove finished worktrees: git worktree remove ../.graph-worktrees/node-{N} (keep failed ones for investigation).
  4. Write checkpoint to .graph_state, then re-render the tracker: python3 skills/graph/scripts/render_graph_html.py .graph_state graph.html (the open graph.html picks it up on its next auto-refresh).
  5. Dynamic re-plan (LangGraph-style conditional edge): scan each subagent's NEW_WORK: line. If any is not none, add the new node(s)/edge(s) and re-layer the remaining nodes before starting the next wave. Show the user the delta.
  6. If any node in the wave failed, mark all nodes that depend on it as blocked and skip them (their inputs aren't ready).

Proceed to the next wave.


State File: .graph_state (+ live tracker graph.html)

.graph_state lives at the repo root and must be in .gitignore. It's the single source of truth: checkpoint it after every wave so a crash resumes at the wave boundary, and re-render graph.html from it so the browser dashboard stays live. graph.html is a derived view — never hand-edit it; regenerate it from .graph_state.

{
  "version": 1,
  "updated_at": "2026-07-21T10:30:00Z",
  "task": "Add user auth",
  "repo": "owner/repo",
  "waves": [[1, 2, 3], [4, 5], [6]],
  "current_wave": 1,
  "nodes": {
    "1": { "title": "db schema", "deps": [], "status": "shipped", "branch": "feat/node-1-db-schema", "pr": 43, "wave": 0 },
    "2": { "title": "config loader", "deps": [], "status": "shipped", "wave": 0 },
    "3": { "title": "logging util", "deps": [], "status": "failed", "wave": 0, "error": "test TestLog failed", "attempts": 2 },
    "4": { "title": "API handler", "deps": [1], "status": "in_progress", "wave": 1 },
    "6": { "title": "integration", "deps": [4, 5], "status": "blocked", "wave": 2, "reason": "depends on #3 (failed)" }
  }
}

Status values: pending | in_progress | shipped | failed | blocked | skipped. Each node carries title + deps so graph.html can draw the DAG and cards straight from the checkpoint.

Render the tracker any time with:

python3 skills/graph/scripts/render_graph_html.py .graph_state graph.html

On resume: read .graph_state, skip shipped, ask about failed (retry/skip), re-derive remaining waves, and re-render graph.html.


Safety Guards

  • Worktree isolation is mandatory — never run two parallel /goal sessions in the same checkout.
  • Fan-in barrier is mandatory — never start wave N+1 before every node in wave N returns and merges.
  • Scope collisions serialize — dep-free nodes touching the same files go in different waves.
  • Never skip /review-it before /ship-it.
  • Cap concurrency — default 3–4; more invites rate limits and merge contention.
  • Never force-push to main. Each node ships via its own branch/PR.
  • Failed node blocks its dependents — don't ship on top of unmet inputs.
  • Max retries per node — reuse /loop-it's error classes; don't loop forever.
  • Confirm the plan before the first fan-out.

Common Mistakes

MistakeFix
Dispatching subagents in separate responsesOne response, multiple calls = parallel. Separate = sequential.
No worktree → parallel edits corrupt the treeOne git worktree per node.
Two "independent" nodes edit the same fileAdd a soft edge; put them in different waves.
Starting the next wave before all nodes mergeEnforce the fan-in barrier.
Over-decomposing into 20 trivial nodesMerge tiny units; a node should be a meaningful shippable unit.
Ignoring a failed node's dependentsMark them blocked, skip them.

Relationship to Other Skills

/prd → /prd-to-spec → /to-issues ─┬─► /loop-it   (sequential: one node at a time)
                                   └─► /graph     (parallel: whole wave at once)
                                          │
                     each node: inline /goal → /review-it → /ship-it (in its own worktree)
  • /to-issues — decomposition rules reused for building nodes.
  • /loop-it — sequential counterpart; use it when nodes heavily share files or serial safety matters.
  • /graph — this skill; use it when the DAG has genuine parallelism (independent subsystems).
  • /review-it, /ship-it — real skills each node's subagent invokes.

FAQ

What does the graph skill do?

Graph engineering for parallel task execution: convert a task, PRD, SPEC, or issue set into a dependency graph (DAG), layer it into supersteps, then implement each independent node concurrently with subagents — each node runs /goal → /review-it → /ship-it in an isolated git worktree, with a fan-in barrier between waves. Triggers on: graph, graph engineering, build a graph, task graph, dependency graph, DAG, parallel implement, 并发实现, 并行实现, 任务图, 把任务变成图, fan-out fan-in, superstep, dynamic workflow.

How do I install graph?

Run npx skills add https://github.com/smallnest/goal-workflow --skill graph in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/graph/ (personal) or .claude/skills/graph/ (project).

Which AI agents can use graph?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is graph safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains graph?

It is published by smallnest in smallnest/goal-workflow. It has 252 recorded installs.

More from smallnest/goal-workflow

View all →

smell

smallnest/goal-workflow

Detect software architecture bad smells, algorithmic complexity hotspots, and anti-patterns in a codebase. Produces a detailed markdown report identifying violations of architectural principles, design patterns, code quality, and performance complexity. Triggers on: smell, code smell, architecture smell, find anti-patterns, detect bad smells, complexity analysis, 代码坏味道, 架构坏味道, 反模式, 找出坏味道, 复杂度分析.

humanize-it

smallnest/goal-workflow

对指定文档进行去 AI 味的改写。自动选择最合适的人性化策略(humanizer-zh / humanize-chinese / technical-writing), 迭代改写直到效果达标或迭代 42 次为止。适用于中文文本的去 AI 化处理,包括通用文章、技术文档、学术论文等。 Use when user says: "humanize this", "去AI味", "降AIGC", "人性化改写", "改成人话", "去除AI痕迹", "humanize document", "make text human-like", "去机器味", "降低AI率", "过AIGC检测"

Docs & Writing534 installs

prd

smallnest/goal-workflow

Generate a Product Requirements Document (PRD) for a new feature. Use when planning a feature, starting a new project, or when asked to create a PRD. After PRD is confirmed, use /prd-to-spec (optional) for technical design, then /to-issues to create implementable tickets. Triggers on: create a prd, write prd for, plan this feature, requirements for, spec out, 写PRD, 需求文档, 需求分析, 规格说明.

insight-diagram

smallnest/goal-workflow

为任意项目生成 UML 图、架构图和流程图。分析代码库后让用户选择要生成的图表类型,使用 architecture-diagram skill 渲染为 HTML+SVG,保存到 docs/ 目录。适用于任何软件项目的文档可视化。

Docs & Writing524 installs

refactor

smallnest/goal-workflow

Expert code refactoring based on Martin Fowler's catalog — improve maintainability without changing behavior. Covers code smells, composing methods, moving features, organizing data, simplifying conditionals, method calls, and generalization. Triggers on: refactor, 重构, clean up, improve code, code smell, extract method, rename, simplify.

modern-go

smallnest/goal-workflow

Modernize Go code by applying version-appropriate idioms and APIs (gofix-style transformations). Scans go.mod for the Go version, then transforms Go source files to use modern patterns—from Go 1.0 through 1.26+. Use when the user says "现代化","现代Go语言", "地道的", "idiomatic", "modernize", "modern-go", "update Go code", "gofix", or wants to upgrade Go idioms.

Popular productivity & automation skills

View category →

agent-browser

vercel-labs/agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.

OfficialProductivity & Automation1.3M installs

lark-doc

open.feishu.cn

飞书云文档(Docx / Wiki)内容操作:读取、创建、编辑文档,插入或下载图片附件,以及操作思维笔记。用户提供文档 URL/token(包括 doubao.com 的 /docx/、/wiki/)时使用;按 URL 路径/token 而非域名路由;/page/ 是妙搭应用,非飞书云文档。文档内嵌资源按读取参考中的统一规则分流。独立评论操作走 lark-drive;随正文读取评论使用 docs +fetch。表格或 Base 内部数据操作不在本 skill。

lark-base

open.feishu.cn

飞书多维表格(Base)操作:建表、字段、记录、视图、统计、公式/lookup、表单、仪表盘、应用模式(BaseApp/AppMode 页面与组件)、Workspace 目录、workflow、角色权限、模板中心(多维表格模板分类/列表/搜索);遇到 Base/多维表格/bitable、BaseApp/AppMode、/base/ 或 /app/ 链接时使用。BaseApp 不走 lark-apps;文件导入/导出转 lark-drive,认证/授权转 lark-shared。

lark-drive

open.feishu.cn

飞书云空间(云盘/云存储):管理 Drive 文件和文件夹,包含上传/下载、创建文件夹、复制/移动/删除、查看元数据、查询权限设置、评论/权限/订阅、标题、版本、飞书文档密级标签(secure labels)和本地文件导入。用户需要整理云盘目录、处理云空间资源 URL/token、判断链接类型/真实 token/标题,或导入 Word/Markdown/Excel/CSV/PPTX/.base 为 docx/sheet/bitable/slides 时使用;doubao.com 云空间 URL/token 也按资源路径和 token 路由,不回退 WebFetch。不负责:文档内容编辑(走 lark-doc)、表格/Base 表内数据操作(走 lark-sheets/lark-base)、知识空间节点/成员管理(走 lark-wiki)、原生 Markdown 文件读写/patch/diff(走 lark-markdown)。

lark-shared

open.feishu.cn

Use for lark-cli setup/auth tasks: auth login/status/logout, user vs bot identity, business-domain permissions (--domain, including all/docs/drive), missing scopes, revoking authorization, or handling notice JSON.

lark-im

open.feishu.cn

飞书即时通讯:收发消息和管理群聊。发送和回复消息、搜索聊天记录、管理群聊成员、上传下载图片和文件、管理表情回复、发送应用内/短信/电话加急、发送和处理交互卡片(Interactive Card)、监听卡片按钮回调(card.action.trigger)。当用户需要发消息、查看或搜索聊天记录、下载聊天中的文件、查看群成员、搜索群、创建群聊或话题群、管理标记数据、管理 Feed 置顶(添加/移除/查询置顶会话)、管理标签数据、处理卡片回调时使用。