npm package: @ghostwater/soulforge
Description: Pluggable executor workflow engine for AI coding agents. Dispatch workflow steps to Claude Code, Codex CLI, or human review checkpoints.
Author: Ghostwater Studio
Latest version: 1.4.3

# Soulforge 🔥

Pluggable executor workflow engine for AI coding agents.

Define multi-step workflows in YAML and dispatch each step to different executors — Claude Code CLI, Codex CLI, human review checkpoints, or custom agents. A persistent daemon manages execution, state recovery, and notifications.

## Install

```bash
npm install -g @ghostwater/soulforge
```

## Quick Start

```bash
# Start the daemon
soulforge daemon start

# Run a workflow
soulforge run workflows/feature-dev "Add dark mode toggle to the settings page" \
  --workdir /path/to/project/worktrees/feature-dark-mode \
  --no-callback

# Check status
soulforge status

# Approve a checkpoint
soulforge approve <run-id>
```

## Features

- **Pluggable executors** — Claude Code, Codex CLI, human checkpoints, or build your own
- **Persistent daemon** — survives session boundaries, recovers from crashes
- **Workflow YAML** — define steps, models, retry logic, and verification
- **Callback notifications** — `callback-exec` shell hooks on run/step events
- **Auto worktrees** — isolate each run in a git worktree
- **SQLite state** — full run history, step logs, crash recovery
- **CLI-first** — approve, reject, cancel, resume from the command line

## Workflow Example

```yaml
id: feature-dev
version: 2
context:
  repo: "{{repo}}"

steps:
  - id: plan
    executor: claude-code
    model: claude-sonnet-4-20250514
    input: |
      Read the codebase at {{repo}} and create a plan for: {{task}}
    expects: implementation_plan

  - id: implement
    executor: claude-code
    model: claude-sonnet-4-20250514
    callback_message: "Implementing plan for {{task}}"
    input: |
      Implement the following plan in {{repo}}:
      {{steps.plan.output}}

  - id: verify
    executor: claude-code
    model: claude-sonnet-4-20250514
    input: |
      Verify the implementation in {{repo}} builds and works correctly.
```

## CLI Reference

```
soulforge daemon start|stop|status    Manage the daemon
soulforge run <workflow> "<task>"      Start a workflow run
soulforge status [<query>]            Check run status
soulforge runs                        List all runs
soulforge approve <run-id>            Approve a checkpoint
soulforge reject <run-id>             Reject a checkpoint
soulforge cancel <run-id>             Cancel a running workflow
soulforge resume <run-id>             Resume a failed run
soulforge events [<run-id>]           View run events
soulforge logs [<n>]                  View daemon logs
```

## Testing

- `npm run test:compact` — compact reporter (minimal output on success, detailed failures)
- `npm test` / `npm run test:full` — canonical full-detail test output for debugging
- Override test parallelism with `SOULFORGE_TEST_CONCURRENCY=<n>` (fallback: `TEST_CONCURRENCY=<n>`)

### Callback Notifications

```bash
soulforge run workflows/feature-dev "task" \
  --callback-exec "printf '%s|%s|%s' '{{run_id}}' '{{step_id}}' '{{status}}' >> /tmp/soulforge-callbacks.log"
```

HTTP callback flags were removed in Fix #113 (`--callback-url`, `--callback-headers`, `--callback-body`).
Use `--callback-exec` or `--no-callback`.

`soulforge update` changes callback settings for future steps only. A currently running step keeps its existing snapshot.

Callback template variables include `{{run_id}}`, `{{step_id}}`, `{{step_status}}`, `{{status}}`, `{{task}}`, and `{{callback_message}}` on all step events. For backward compatibility, `{{prompt}}` still resolves for pause waiting callbacks.

### Auto Worktrees

```bash
soulforge run workflows/feature-dev "task" \
  --no-callback
```

When `--workdir` is omitted, Soulforge auto-creates an isolated git worktree at `<repo>/worktrees/<generated-name>` from `main`.
Use `--branch <name>` to request a specific branch/worktree name:

```bash
soulforge run workflows/feature-dev "task" \
  --branch feature/my-task \
  --no-callback
```

Guardrails:
- blocks repository main checkout paths (you must target a worktree path)
- requires clean worktrees (`git status --porcelain` must be empty)
- enforces `<repo>/worktrees/` as the default base for `--workdir`
- allows out-of-base paths only with `--allow-outside-worktrees-base`

Recovery steps:
- Main checkout blocked: create/select a worktree path, or rerun without `--workdir` to auto-provision one.
```bash
git worktree add ./worktrees/feature/my-task -b feature/my-task main
```
- Dirty worktree blocked: clean changes, then rerun.
```bash
git status --porcelain
git add -A && git commit -m "checkpoint"
# or: git stash push -u
```
- Out-of-base workdir blocked: move worktrees under `<repo>/worktrees/`, or pass `--allow-outside-worktrees-base` intentionally.

### Environment Variables

- `SOULFORGE_DATA_DIR` — Override the data directory (default: `~/.soulforge`). Useful for testing or running multiple instances.

## Data

All state lives in `~/.soulforge/` by default, or `SOULFORGE_DATA_DIR` if set:
- `soulforge.db` — SQLite database (runs, steps, events)
- `daemon.pid` — daemon process ID
- `daemon.log` — daemon logs
- `events/` — file-based event notifications

## License

MIT — Ghostwater Studio