diff --git a/apps/docs/docs.json b/apps/docs/docs.json
index b5353a13a..ecc4da365 100644
--- a/apps/docs/docs.json
+++ b/apps/docs/docs.json
@@ -30,7 +30,13 @@
},
{
"group": "Codemod Platform",
- "pages": ["scanner", "migrations", "insights", "codemod-studio"]
+ "pages": [
+ "scanner",
+ "migrations",
+ "insights",
+ "codemod-studio",
+ "workflows"
+ ]
},
{
"group": "OSS & Community",
diff --git a/apps/docs/workflows.mdx b/apps/docs/workflows.mdx
new file mode 100644
index 000000000..410a1a510
--- /dev/null
+++ b/apps/docs/workflows.mdx
@@ -0,0 +1,499 @@
+---
+title: 'Codemod CLI'
+description: Run, validate, and automate code-modification workflows locally or in the cloud.
+icon: 'code'
+---
+
+---
+
+Codemod CLI is a self-hosted workflow engine for code-base changes—codemods, grep-style edits, automated lint fixes, and more. Define once in YAML; run unchanged on your laptop **or** in the Codemod platform.
+
+## Core Features
+
+- **Single binary, no server** — works anywhere you have a shell
+- **Schema-validated shared state** — tasks share one JSON document
+- **Dynamic matrix fan-out** — tasks appear/disappear as state arrays change
+- **Manual gates** — pause tasks until you trigger them
+- **Durable & resumable** — state survives crashes or reboots
+- **Parallel scheduling** — independent nodes run when dependencies allow
+- **Host-shell execution** — commands run directly on your machine (container runtimes on the roadmap)
+
+---
+
+## Quick Start
+
+
+
+ ```bash
+ cargo install codemod-cli
+ ```
+
+
+ ```yaml workflow.yaml
+ version: "1"
+ nodes:
+ - id: hello
+ name: Hello World
+ type: automatic
+ steps:
+ - name: Say hello
+ run: echo "Hello, World!"
+ ```
+
+
+ ```bash
+ codemod validate -w workflow.yaml
+ codemod run -w workflow.yaml
+ codemod run ./my-workflow/ # run a bundle folder
+ ```
+
+
+
+
+Registry identifiers such as `my-registry/react-mods:latest` are on the roadmap.
+
+
+---
+
+## Directory Layout
+
+```
+my-workflow/
+├─ workflow.yaml
+├─ scripts/
+└─ rules/
+```
+
+The folder—called a **workflow bundle**—is the root when you run `codemod run ./my-workflow/`. `$CODEMOD_PATH` points here inside every task.
+
+
+A workflow bundle is a directory containing your workflow.yaml
and any scripts, rules, or assets referenced by your workflow.
+
+- When you run codemod run ./my-workflow/
, the directory is used as the root for all relative paths.
+- You can also run a workflow directly from a file:
+
+ codemod run -w workflow.yaml
+
+
+Registry support (run workflows from remote sources) is planned for the future.
+
+
+
+## Workflow File
+
+```yaml workflow.yaml
+version: "1"
+state:
+ schema: []
+templates: []
+nodes: []
+```
+
+A workflow has four top-level keys:
+
+| Key | Required | Purpose |
+|-----|----------|---------|
+| `version` | ✓ | Declare workflow schema version (default: `"1"`). |
+| [`state`](#shared-state) | | Declares shared-state schema. |
+| [`templates`](#templates) | | Re-usable blocks. |
+| [`nodes`](#nodes) | ✓ | Executable DAG. |
+
+---
+
+## Shared State
+
+```yaml
+state:
+ schema:
+ - name: shards
+ type: array
+ items:
+ type: object
+ properties:
+ team: { type: string }
+ shardId: { type: string }
+```
+
+---
+
+## Templates
+
+```yaml
+templates:
+ - id: checkout-repo
+ name: Checkout Repository
+ inputs:
+ - name: repo_url
+ type: string
+ required: true
+ steps:
+ - name: Clone
+ run: git clone ${{inputs.repo_url}} repo
+```
+
+**Template Inputs & Usage**:
+
+Templates can define required or optional inputs, which are referenced in their steps.
+
+To use a template in a node step:
+
+```yaml
+steps:
+ - name: Checkout
+ uses:
+ - template: checkout-repo
+ inputs:
+ repo_url: ${{params.repo_url}}
+```
+
+---
+## Nodes & Steps
+
+### Nodes
+
+```yaml
+nodes:
+ - id: build
+ name: Build
+ type: automatic
+ steps:
+ - name: npm install
+ run: npm ci
+```
+
+
+ Unique within the workflow.
+
+
+ Display name.
+
+
+ `automatic` (default) or `manual`.
+
+
+ Upstream node IDs.
+
+
+ `{ type: manual }` → approval gate.
+
+
+ Matrix configuration.
+
+
+ Ordered list of steps.
+
+Container/runtime configuration (e.g., Docker).
+Environment variables for the node or step.
+
+### Step
+
+
+ Step label.
+
+
+ Inline shell command to execute.
+
+ Provide either run
or uses
, not both.
+
+
+ Template call(s).
+
+ Provide either run
or uses
, not both.
+
+
+
+## Matrix Strategy
+
+```yaml
+nodes:
+ - id: matrix-codemod
+ name: Matrix Codemod
+ strategy:
+ type: matrix
+ from_state: shards
+ steps:
+ - name: Codemod
+ run: node codemod.js --team=$team --shard=$shardId
+```
+
+
+When the array referenced by `from_state` changes, Codemod CLI:
+
+1. Creates new tasks for new items.
+2. Marks tasks as `WontDo` if their item is removed.
+3. Leaves existing tasks untouched if their item remains.
+
+
+Matrix nodes have a master task that tracks the status of all generated tasks.
+
+
+
+---
+
+## Manual Trigger
+
+```yaml
+nodes:
+ - id: manual-approval
+ name: Manual Approval
+ trigger:
+ type: manual
+ steps:
+ - name: Wait for approval
+ run: echo "Waiting for manual approval"
+```
+
+
+Manual tasks are assigned unique UUIDs. You can resume:
+
+- All paused tasks:
+ ```bash
+ codemod resume -i --trigger-all
+ ```
+- A specific task:
+ ```bash
+ codemod resume -i -t
+ ```
+
+
+---
+
+## State Updates
+
+| Syntax | Meaning | Example |
+|----------------|----------------------------------------------|----------------------------------------------|
+| `KEY=VAL` | Set state key to value | `count=10` |
+| `KEY@=VAL` | Append value to array at state key | `shards@={"team":"core","shardId":"1"}` |
+| Dot notation | Set nested state fields | `config.retries=5` |
+| JSON values | Use valid JSON for objects/arrays | `user={"name":"Alice","id":123}` |
+
+
+All state updates must be valid JSON if not a primitive. Updates are applied only if the task exits successfully.
+
+
+
+
+You can specify how a node or template runs:
+
+```yaml
+runtime:
+ type: docker
+ image: node:18-alpine
+```
+
+Supported types: `docker`, `podman`, `direct` (host shell).
+
+
+
+
+Workflow state is persisted after every task. If interrupted, you can resume from the last saved state—no work is lost.
+
+
+
+
+For matrix nodes, a master task aggregates the status of all generated tasks.
+If all child tasks complete, the master is `Completed`. If any fail, the master is `Failed`.
+
+
+
+If your workflow has a cycle:
+
+```yaml
+nodes:
+ - id: a
+ depends_on: [b]
+ - id: b
+ depends_on: [a]
+```
+
+You'll see:
+
+```bash
+✗ Workflow definition is invalid
+Error: Cyclic dependency detected: a → b → a
+```
+
+
+
+
+---
+
+## End-to-End Example
+
+```yaml
+version: "1"
+state:
+ schema:
+ - name: shards
+ type: array
+ items:
+ type: object
+ properties:
+ team: { type: string }
+ shardId: { type: string }
+templates:
+ - id: checkout-repo
+ name: Checkout Repository
+ inputs:
+ - name: repo_url
+ type: string
+ required: true
+ steps:
+ - name: Clone
+ run: git clone ${{inputs.repo_url}} repo
+nodes:
+ - id: make-shards
+ name: Make Shards
+ type: automatic
+ steps:
+ - name: Write shards
+ run: echo 'shards@={"team":"core","shardId":"1"}' >> "$STATE_OUTPUTS"
+ - id: matrix-codemod
+ name: Matrix Codemod
+ strategy:
+ type: matrix
+ from_state: shards
+ trigger:
+ type: manual
+ steps:
+ - name: Codemod
+ run: node codemod.js --team=$team --shard=$shardId
+ - name: PR
+ run: codemodctl pr create
+```
+
+---
+
+## Task Statuses
+
+
+ Queued; waiting for runner.
+
+
+ Currently executing.
+
+
+ Succeeded; diff applied.
+
+
+ Script exited non-zero; diff discarded.
+
+
+ Waiting for manual approval.
+
+
+ Dependencies not finished.
+
+
+ Matrix item removed; task skipped.
+
+
+
+## Variable Resolution
+
+- **Parameter:** `${{params.branch}}` — Supplied at runtime
+- **Environment:** `${{env.CI}}` — Host env var
+- **Shared State:** `${{state.counter}}` — Live JSON value
+
+
+In matrix tasks, each object key becomes an environment variable (e.g., `$team`, `$shardId`, …).
+
+
+---
+
+## CLI Commands
+
+### `codemod validate`
+Lint workflow & print issues.
+
+
+ Path to the workflow file.
+
+
+### `codemod run`
+Start a run.
+
+
+ Path to the workflow file.
+
+
+ Path to a workflow bundle directory.
+
+
+### `codemod resume`
+Resume or trigger tasks.
+
+
+ Run ID to resume.
+
+
+ Resume all paused tasks.
+
+
+ Resume a single task by UUID.
+
+
+### `codemod graph`
+Render DAG image.
+
+
+ Path to the workflow file.
+
+
+ Output PNG file for the DAG image.
+
+
+
+## Task Statuses
+
+
+ Queued; waiting for runner.
+
+
+ Currently executing.
+
+
+ Succeeded; diff applied.
+
+
+ Script exited non-zero; diff discarded.
+
+
+ Waiting for manual approval.
+
+
+ Dependencies not finished.
+
+
+ Matrix item removed; task skipped.
+
+
+
+## Validation Checks
+
+`codemod validate` catches issues before execution:
+
+| Check | Ensures |
+|-------|---------|
+| Schema validation | YAML matches spec |
+| Unique IDs | Node & template IDs unique |
+| Dependency validation | Every `depends_on` exists |
+| Cyclic dependency detection | DAG has no cycles |
+| Template references | All `template:` IDs exist |
+| Matrix validation | `from_state` matches schema |
+| State schema validation | `state.schema` is valid |
+| Variable syntax | `${{…}}` uses `params`, `env`, `state` |
+
+---
+
+## Roadmap
+
+
+ Support for runtime: docker
and other container runtimes, allowing tasks to run in isolated environments.
+
+
+ Ability to pass parameters to workflows via --param key=value
flags.
+
+
+ Support for matrix strategies within matrix strategies, enabling more complex task fan-out.
+
\ No newline at end of file