SkillFlow = Skill × Flow — An AI-powered visual workflow editor that turns SKILL.md files into interactive, inspectable reasoning graphs.
SkillFlow bridges the gap between opaque agent behavior and human understanding. Upload a SKILL.md file and an LLM parses it into a visual workflow graph, surfacing the agent's reasoning steps as nodes and edges you can explore, edit, and trace in real time. Every change you make on the canvas propagates back to the source SKILL.md, keeping the two representations permanently in sync.
- 📄 Upload SKILL.md → async LLM parsing → visual workflow graph powered by ReactFlow
- 🔁 Bidirectional sync — edit nodes on the canvas and the SKILL.md updates automatically; edit the SKILL.md and the canvas reflects it instantly
- 🧩 9 node types — Trigger, Instruction, Script, Tool, Decision, Loop, HITL, SubSkill, Output
- 🔀 Work modes — define multiple reasoning paths (e.g., "quick", "deep analysis") within a single skill
- ⚡ Real-time execution tracking via Socket.IO — nodes highlight as an agent executes them
- 📝 Source / Workflow toggle — view raw SKILL.md alongside the visual graph in the editor
- 🔄 Re-parse on demand — re-run LLM parsing with one click without leaving the page
- 🔵 Parse status indicator — "parsing" shows an animated spinner on the list and a canvas overlay; resolves to "done" or "failed"
- 💬 Chat panel — describe changes in natural language; the agent updates SKILL.md and the graph simultaneously
┌─────────────────────────────────────────────────────────────────────────┐
│ Browser (Next.js 16) │
│ │
│ ┌──────────────────────┐ ┌─────────────────────────────────────┐ │
│ │ Chat Panel │ │ SkillFlow Canvas (ReactFlow v12) │ │
│ │ - Natural language │ │ - 9 node type components │ │
│ │ skill editing │ │ - Node edit drawer │ │
│ │ - Change summaries │ │ - Work mode tab switcher │ │
│ │ - Parse status │ │ - Execution state highlighting │ │
│ └──────────┬───────────┘ └────────────────┬────────────────────┘ │
│ │ REST + Socket.IO │ │
└─────────────┼──────────────────────────────────-┼───────────────────────┘
│ │
┌─────────────▼────────────────────────────────────▼───────────────────────┐
│ Backend (FastAPI + Socket.IO) │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ REST API /api/skillflow/ │ │
│ └──────────────────────────────┬────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────▼────────────────────────────────────┐ │
│ │ SkillFlow Agent │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ SKILL.md │ │ SKILL.md │ │ LLM Provider │ │ │
│ │ │ Parser │ │ Compiler │ │ (Anthropic / │ │ │
│ │ │ (MD → Graph) │ │ (Patch → MD) │ │ OpenAI) │ │ │
│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ Bidirectional Sync Engine │ │ │
│ │ │ Change Tracker · Conflict Resolver · Socket.IO Event Bus │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────┬────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────▼────────────────────────────────────┐ │
│ │ Storage Layer │ │
│ │ SQLite (aiosqlite) — Skills, Nodes, Modes, Executions │ │
│ │ Filesystem — workspace/skills/{name}/SKILL.md │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
| Requirement | Version | Notes |
|---|---|---|
| Python | 3.13+ | Backend runtime |
| Node.js | 18+ | Frontend runtime |
| uv | latest | Python package manager (pip install uv) |
| npm | 9+ | Frontend package manager |
| Anthropic or OpenAI API key | — | Required for LLM parsing |
git clone https://github.com/your-org/skill-flow.git
cd skill-flowcp backend/.env.example backend/.envOpen backend/.env and set your API key:
# Any OpenAI-compatible API (OpenRouter, Azure, local Ollama, etc.)
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://openrouter.ai/api/v1
SKILLFLOW_AGENT_MODEL=openai/gpt-4omake installThis runs uv sync in the backend and npm install in the frontend.
make backend
# FastAPI + Socket.IO listening on http://localhost:8000
# Interactive API docs: http://localhost:8000/docsmake frontend
# Next.js dev server on http://localhost:3000Navigate to http://localhost:3000/skillflow.
To start both services simultaneously in a single terminal:
make devAll backend configuration is loaded from backend/.env via Pydantic BaseSettings.
# ---- LLM Provider (OpenAI-compatible) ----
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL= # leave empty for OpenAI; set for custom endpoint
SKILLFLOW_AGENT_MODEL=gpt-4o # model nameThe Makefile at the project root provides all common commands:
make help # Show all available commands
# Install dependencies
make install # Install backend (uv sync) + frontend (npm install)
make backend-install # Install backend dependencies only
make frontend-install # Install frontend dependencies only
# Run services
make dev # Start backend + frontend simultaneously
make backend # Start backend only (http://localhost:8000)
make frontend # Start frontend only (http://localhost:3000)
# Verify backend
make backend-check # Import-check the FastAPI app
# Build
make frontend-build # Production build of the Next.js frontendcd backend
source .venv/bin/activate
pytest tests/| Layer | Technology | Version |
|---|---|---|
| Backend language | Python | 3.13+ |
| Backend framework | FastAPI | 0.135+ |
| ORM | SQLAlchemy (async) | 2.0+ |
| Database | SQLite via aiosqlite | — |
| Real-time | python-socketio | 5.16+ |
| LLM SDK | anthropic / openai | 0.86+ / 2.30+ |
| Frontend framework | Next.js | 16 |
| UI library | React | 19 |
| Language | TypeScript | 5+ |
| Styling | Tailwind CSS | 4 |
| Graph engine | @xyflow/react (ReactFlow) | v12 |
| State management | Zustand + immer | — |
| Graph layout | dagre | — |
User uploads SKILL.md
│
▼
POST /api/skillflow/skills/upload
→ Skill record saved with parse_status = "parsing"
→ Background task spawned
│
▼
SkillMDParser.parse(skill_md_content)
1. Extract YAML frontmatter → TriggerNode input params
2. Find skillflow anchor comments <!-- skillflow:node:{type}:{id} -->
3. Map each anchored section to its node type
4. LLM fallback for un-anchored sections (semantic inference)
5. Build directed edges between nodes
6. Infer work modes from path structure
│
▼
WorkflowGraph saved to database
parse_status = "done" (or "failed" on error)
│
▼
Socket.IO → parse_status_changed → Browser
Canvas renders nodes + edges
dagre auto-layout positions nodes
Work mode tabs appear in the toolbar
User edits a node in the canvas drawer
│
▼
PATCH /api/skillflow/skills/{id}/nodes/{node_id}
Body: { field: new_value } (NodePatch)
│
▼
SkillMDCompiler.compile_patch(skill_md, patch)
1. Locate anchor comment for the node <!-- skillflow:node:...:node-id -->
2. Replace only the relevant section — minimal diff, not a full rewrite
3. For ScriptNode: also update the corresponding .py file
│
▼
Updated SKILL.md written to workspace/skills/{name}/SKILL.md
│
▼
Socket.IO → skill_md_updated → Browser
Source panel refreshes
Chat panel shows diff summary: "Node [label] updated — SKILL.md synced"
External agent begins executing a Skill
│
▼
Agent emits node_state_changed events as each step runs
{ execution_id, node_id, status: "running" | "completed" | "failed" }
│
▼
Socket.IO → Browser canvas
Running node: blue border + pulse animation
Completed node: green border + check mark
Failed node: red border + error tooltip
│
▼
execution_completed event
Canvas shows the full traversed path highlighted
Execution is persisted to the database for history
- Fork the repository and create a feature branch from
main. - Follow the existing code style — backend uses standard Python typing, frontend uses TypeScript strict mode.
- Add tests for new backend logic under
backend/tests/. - Open a pull request with a clear description of the change and its motivation.
MIT License — see LICENSE for details.
