Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/fluffy-configs-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"warpforge": patch
---

The workspace config has a new preferred home at `.warpforge/workspace.yaml`,
alongside the new `.warpforge/workflows/` directory. Existing config files in
the project root keep working exactly as before; only newly generated configs
land in the `.warpforge/` directory.
31 changes: 31 additions & 0 deletions .changeset/wide-pipelines-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
"warpforge": minor
---

Adds configurable workflows: a task can now run as a pipeline of agent stages
instead of a single session. A workflow is a YAML file in your project's
`.warpforge/workflows/`, and it decides which agent and model runs each stage,
what each stage is told to do, what the reviewers see, and how many review
rounds are allowed. Two built-in templates ship with the app — "Implement +
review loop" and "Plan + implement + review loop" — and either can be copied
into a project in one click to customize.

Pick a workflow in the New Task dialog and the daemon drives the run: it plans
(if the workflow asks for it), implements, then loops review and repair until
the reviewers approve or the round limit runs out. Reviewers can be several
different agents at once and return structured verdicts, and a repeat round
continues in the same reviewer's session so it verifies its own findings
instead of reviewing from scratch.

The pipeline reports to the parent task as a timeline of stages, each with the
agents that ran it — click one to open that agent's own session. It also stops
for you when it needs to: a stage can ask a question, and running out of review
rounds asks whether to grant more, finish as is, or stop. Pipelines can be
paused between stages and resumed with extra guidance, survive a daemon restart
by parking at their last safe point, and never commit anything — a finished run
lands in Needs review for you to inspect.

Reviewers can pin each finding to a line and a short code excerpt, so the
repair stage goes straight to the right place instead of searching, and the
summary a stage hands to the next one is its closing message rather than the
whole turn's tool narration.
67 changes: 67 additions & 0 deletions .warpforge/workflows/review-loop.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Built-in workflow: implement → review ⇄ fix.
#
# This workflow ALWAYS starts with implementation. Omitting `implement` only
# selects Warpforge's built-in implementation settings/prompt; it never removes
# this fixed stage. Copy the file into <project>/.warpforge/workflows/ (or use
# "Copy to project" in the New Task dialog) to customize it.
version: 1
name: Implement + review loop
description: Implement the task, then loop reviews and fixes until reviewers approve.

# Uncomment agent/model to pin this stage. When omitted, they fall back to the
# lead agent/model picked in the New Task dialog.
implement:
# agent: claude
# model: claude-opus-5
prompt: |
You are the implementation stage of a workflow pipeline. Implement the task
completely: write the code, keep the change focused, and verify your work
with builds/tests where feasible. Your final message must summarize what
you did because it is passed to the reviewers.

## Task
{{task_prompt}}

review:
max_rounds: 2 # review ⇄ fix iterations before asking you what to do
on_limit: ask # ask | finish — behaviour when the limit is hit
context: [prompt, implementer_summary, diff]
reviewers:
# Each reviewer may use a different agent/model. Omitted values use Lead.
- agent: codex
model: gpt-5.6-sol
# focus: correctness and edge cases
prompt: |
You are a code reviewer in workflow round {{round}}/{{max_rounds}}.
Review the implementation against the task. Do not edit files. Verify
claims against the diff and report only concrete, actionable problems.

## Task
{{task_prompt}}

## Implementer's summary
{{implementer_summary}}

## Working-copy diff
{{diff}}

fix:
# Uncomment to override the implementation stage. Omitted values inherit it.
# agent: claude
# model: claude-opus-5
prompt: |
You are the repair stage of workflow round {{round}}/{{max_rounds}}.
Address every reviewer finding: fix it or, if it is factually wrong,
explain why in your final summary. Do not change unrelated code. Verify the
result where feasible and summarize what changed for the next review.

## Task
{{task_prompt}}

## Findings to address
{{findings}}

## Current working-copy diff
{{diff}}

# Warpforge appends the need_user_input/verdict JSON protocols to these prompts.
17 changes: 15 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Workspace orchestrator with TUI and desktop interfaces. Manages multiple dev pro
- **PTY:** `portable-pty` — real TTY for spawned agents
- **Terminal emulation:** `vt100` crate — parses ANSI into screen buffer
- **CLI:** `clap` derive API
- **Config:** `.workspace.yaml` per project (serde_yaml), registry in `~/.warpforge/projects.json`
- **Config:** `.warpforge/workspace.yaml` per project (serde_yaml; legacy root-level `.warpforge.yaml` / `.wf.yaml` / `.workspace.yaml` still load), registry in `~/.warpforge/projects.json`
- **Port isolation:** each project gets 100-port range (4000+), `${svc.port}` interpolation in env vars
- **Daemon IPC:** WebSocket JSON-RPC (port 61814)

Expand Down Expand Up @@ -40,7 +40,8 @@ main.rs — CLI entry (clap), subcommands: add, remove, list, ui
app.rs — TUI event loop (tokio::select), AppState, InputMode (Navigate/Terminal), key handling
agent.rs — AgentManager: PTY spawn via portable-pty, vt100 parser, input/output channels
service.rs — ServiceManager: sh -c spawn, stdout/stderr log capture, process-group kill, port allocation
config.rs — .workspace.yaml parsing + auto-detect (package.json scripts, docker-compose)
config.rs — workspace config parsing + auto-detect (package.json scripts, docker-compose)
workflow_config.rs — .warpforge/workflows/*.yaml templates: schema, validation, prompt rendering
registry.rs — ~/.warpforge/projects.json CRUD
ports.rs — Port range allocation (4000+), ${svc.port} env interpolation
tui/
Expand All @@ -54,6 +55,9 @@ tui/
- WebSocket server (port 61814) that desktop/TUI connect to
- Manages agents, services, port-forwards, tasks, git operations
- Key files: server.rs, actor.rs, task.rs, agents.rs, diff.rs
- **workflow.rs** — deterministic workflow pipeline: run state, stage prompts,
agent protocols. Actor glue is the workflow block at the end of actor.rs.
Templates are parsed by `src/workflow_config.rs`; see `docs/adr/0001`.

**Desktop source (`desktop/src/`):**
```
Expand Down Expand Up @@ -112,6 +116,10 @@ lib/ — Utilities (38 files: sessionActivity, sessionTiming, e
- **Agent setup:** detect/install agents (Claude, Codex), bootstrap wizard
- **UI state:** Zustand store with localStorage persistence (panels, toggles, view)
- **Orchestration:** planner → workers → reviewers pipeline (daemon-driven)
- **Workflows:** pick a configured pipeline (`.warpforge/workflows/*.yaml`) in
New Task; the daemon runs `plan? → implement → review ⇄ fix` as child tasks,
asks you at barriers (stage question, review limit), and supports
pause/resume. See `docs/adr/0001-workflow-pipelines.md` before changing it.

### Known Issues / TODO

Expand All @@ -123,6 +131,11 @@ lib/ — Utilities (38 files: sessionActivity, sessionTiming, e

### Key Design Decisions

**Read `docs/adr/` before changing a subsystem it covers.** Those records hold
the rejected alternatives and the invariants that are not visible in the code —
each entry's *Invariants* section lists mistakes already made once. Add a new
numbered record when you make a decision a future reader could not infer.

- **Ratatui + vt100** for terminal-in-terminal: native cell-by-cell rendering with zero translation layer. Previous TypeScript/OpenTUI attempt couldn't render ANSI properly.
- **vt100 + TerminalPane:** Agent PTY output → `vt100::Parser::process()` → `Screen` → iterate cells with colors/attributes → write directly to ratatui `Buffer`. Cursor rendered via `Modifier::REVERSED`.
- **portable-pty:** Cross-platform PTY. Reader/writer in `spawn_blocking` tasks, input via `mpsc::unbounded_channel`.
Expand Down
Loading
Loading