Skip to content
Draft
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ help:
@echo " test Run fast tests (excludes real CLI calls)"
@echo " test-unit Run unit tests only"
@echo " test-integration Run integration tests (real CLI calls - slow)"
@echo " test-external Run external tests (requires CLIs: claude, codex, gemini, opencode)"
@echo " test-external Run external tests (requires CLIs: claude, cursor(agent), codex, gemini, opencode)"
@echo " test-all Run all tests including integration"
@echo " test-coverage Generate coverage report"
@echo " test-race Run tests with race detector"
Expand Down Expand Up @@ -80,7 +80,7 @@ test-unit:
test-integration:
go test -v -tags=integration ./internal/infrastructure/agents/... ./tests/integration/...

# External tests (requires external CLIs: claude, codex, gemini, opencode)
# External tests (requires external CLIs: claude, cursor(agent), codex, gemini, opencode)
test-external:
go test -v -tags=external ./...

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ A Go CLI tool for orchestrating AI agents (Claude, Gemini, Codex, OpenAI-Compati

- **State Machine Execution** - Define workflows as state machines with conditional transitions based on exit codes, command output, or custom expressions
- **Inline Error Handling** - Specify error messages and exit codes directly on steps without creating separate terminal states
- **Agent Steps** - Invoke AI agents via CLI tools (Claude, Codex, Gemini) or direct HTTP (OpenAI, Ollama, vLLM, Groq) with prompt templates, response parsing, and accurate token tracking
- **Agent Steps** - Invoke AI agents via CLI tools (Claude, Cursor, Codex, Gemini) or direct HTTP (OpenAI, Ollama, vLLM, Groq) with prompt templates, response parsing, and accurate token tracking
- **Output Formatting for Agent Steps** - Automatically strip markdown code fences and validate JSON output; human-readable streaming display controlled by `output_format` field (text vs raw NDJSON)
- **External Prompt Files** - Load agent prompts from `.md` files with full template interpolation, helper functions, and local override support
- **External Script Files** - Load commands from external script files with shebang-based interpreter dispatch, template interpolation, path resolution, and local override support
- **Conversation Mode** - Multi-turn conversations with native session resume for CLI providers (`claude`, `codex`, `gemini`, `opencode`), automatic context window management for HTTP providers, mid-conversation context injection via `inject_context` field, and token tracking across all turns
- **Conversation Mode** - Multi-turn conversations with native session resume for CLI providers (`claude`, `cursor`, `codex`, `gemini`, `opencode`), automatic context window management for HTTP providers, mid-conversation context injection via `inject_context` field, and token tracking across all turns
- **OpenAI-Compatible Provider** - Use any Chat Completions API (OpenAI, Ollama, vLLM, Groq) with native HTTP integration, accurate token reporting, and no CLI tool required
- **Parallel Execution** - Run multiple steps concurrently with configurable strategies
- **Loop Constructs** - For-each and while loops with full context access
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Learn how to use AWF effectively:

- [Commands](user-guide/commands.md) - All CLI commands and flags
- [Interactive Input Collection](user-guide/interactive-inputs.md) - Automatic prompting for missing workflow inputs
- [Agent Steps](user-guide/agent-steps.md) - Invoke AI agents via CLI (Claude, Codex, Gemini) or HTTP APIs (OpenAI, Ollama, vLLM, Groq)
- [Agent Steps](user-guide/agent-steps.md) - Invoke AI agents via CLI (Claude, Cursor, Codex, Gemini) or HTTP APIs (OpenAI, Ollama, vLLM, Groq)
- [Output Formatting](user-guide/agent-steps.md#output-formatting) - Automatic code fence stripping and JSON validation (`output_format: json|text`)
- [Streaming Output Display](user-guide/agent-steps.md#streaming-output-display) - Human-readable filtered output for `--output streaming` and `--output buffered` modes
- [External Prompt Files](user-guide/agent-steps.md#external-prompt-files) - Load prompts from Markdown files with template interpolation
Expand Down
4 changes: 2 additions & 2 deletions docs/development/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ make test-unit
# Integration tests (requires full system setup, tagged with //go:build integration)
make test-integration

# External tests (requires external CLIs: claude, codex, gemini, opencode)
# External tests (requires external CLIs: claude, cursor(agent), codex, gemini, opencode)
make test-external

# All tests including integration
Expand All @@ -41,7 +41,7 @@ AWF uses Go build tags to control which tests run in different environments. Thi
| Tag | Purpose | Usage | Example |
|-----|---------|-------|---------|
| `integration` | Full system tests requiring setup, state persistence, CLI execution | `make test-integration` or `go test -tags=integration ./...` | End-to-end workflow execution |
| `external` | Tests requiring external CLI tools (claude, codex, gemini, opencode) | `make test-external` or `go test -tags=external ./...` | AI provider validation |
| `external` | Tests requiring external CLI tools (claude, cursor(agent), codex, gemini, opencode) | `make test-external` or `go test -tags=external ./...` | AI provider validation |
| `slow` | Resource-intensive tests (high memory, concurrency, long-running) | `go test -tags=slow ./...` | Memory leak detection, stress tests |
| `!short` | Standard Go short mode exclusion for tests that take >100ms | `go test -short ./...` (excludes these) | Database operations, file I/O |

Expand Down
45 changes: 42 additions & 3 deletions docs/user-guide/agent-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Agent Steps Guide"
---

Invoke AI agents (Claude, Codex, Gemini, OpenCode, OpenAI-Compatible) in your workflows with structured prompts and response parsing.
Invoke AI agents (Claude, Cursor, Codex, Gemini, OpenCode, OpenAI-Compatible) in your workflows with structured prompts and response parsing.

## Overview

Expand Down Expand Up @@ -86,6 +86,28 @@ analyze:
- `allowed_tools`: Comma-separated list of tools to allow (e.g., `"bash,read"` → `--allowedTools bash,read`)
- `dangerously_skip_permissions`: Skip permission prompts (boolean, maps to `--dangerously-skip-permissions`). **Security warning**: bypasses all safety prompts — use only in trusted, automated environments. Emits a security audit log.

### Cursor CLI

Requires the Cursor CLI `agent` binary installed (from [cursor.com/cli](https://cursor.com/cli)).

```yaml
analyze:
type: agent
provider: cursor
prompt: "Review this diff: {{.inputs.diff}}"
options:
model: composer-2
mode: ask
timeout: 120
on_success: next
```

**Provider-Specific Options:**
- `model`: Cursor model identifier (no AWF-side whitelist; validated by Cursor CLI at runtime)
- `mode`: `ask` or `plan` (maps to `--mode`)
- `sandbox`: `enabled` or `disabled` (maps to `--sandbox`)
- `dangerously_skip_permissions`: Skip approval prompts (boolean, maps to `--force`). **Security warning**: bypasses safety confirmations — use only in trusted automation environments.

### Codex (OpenAI)

Requires the `codex` CLI tool installed.
Expand Down Expand Up @@ -242,7 +264,24 @@ step validation error: model must start with "gpt-", "codex-", or match o-series

### OpenCode & OpenAI-Compatible

No model validation for `opencode` or `openai_compatible` providers — these use arbitrary backend models.
No model validation for `cursor`, `opencode`, or `openai_compatible` providers — these use arbitrary/backend-specific model names.

## Cursor vs Claude Parity

AWF targets the highest possible parity between `cursor` and `claude` providers. Current mapping:

| Capability | Claude | Cursor | Notes |
|------------|--------|--------|-------|
| Single-turn execution | Yes | Yes | Both run in print/headless mode |
| Conversation mode | Yes | Yes | Cursor uses `--resume <chatId>` |
| Session extraction | `session_id` from `result` | `chat_id`/`chatId` (system init) | Cursor extraction is tolerant to field variants |
| `output_format: text` | Yes | Yes | AWF extracts readable assistant text |
| `output_format: json` | Yes | Yes | AWF exposes final result event payload |
| `system_prompt` in conversation | Native `--system-prompt` | Inlined on first turn | Cursor CLI has no dedicated system prompt flag |
| `allowed_tools` | Supported | Not mapped | No Cursor CLI equivalent currently |
| `dangerously_skip_permissions` | `--dangerously-skip-permissions` | `--force` | Closest available equivalent |

When no exact Cursor equivalent exists, AWF prefers explicit behavior over silent mismatches and documents the fallback.

### When Validation Occurs

Expand Down Expand Up @@ -854,7 +893,7 @@ See [Workflow Syntax — Inline Error Shorthand](workflow-syntax.md#inline-error
|-------|-------|----------|
| Provider not found | CLI tool not installed | Install required CLI (e.g., `claude install`) |
| Timeout | Agent response took too long | Increase timeout or reduce prompt complexity |
| Invalid provider | Unsupported provider | Use `claude`, `codex`, `gemini`, `opencode`, or `openai_compatible` |
| Invalid provider | Unsupported provider | Use `claude`, `cursor`, `codex`, `gemini`, `opencode`, or `openai_compatible` |
| Command failed | Provider CLI returned error | Check provider configuration and logs |

### Debugging
Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ outer=B inner=1

## AI Agent Integration

Invoke AI agents (Claude, Codex, Gemini) directly in workflows:
Invoke AI agents (Claude, Cursor, Codex, Gemini) directly in workflows:

```yaml
name: code-review-with-agent
Expand Down
8 changes: 4 additions & 4 deletions docs/user-guide/workflow-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ states:
| Type | Description |
|------|-------------|
| `step` | Execute a command |
| `agent` | Invoke an AI agent (Claude, Codex, Gemini, etc.) |
| `agent` | Invoke an AI agent (Claude, Cursor, Codex, Gemini, etc.) |
| `terminal` | End state with success/failure status |
| `parallel` | Execute multiple steps concurrently |
| `for_each` | Iterate over a list of items |
Expand Down Expand Up @@ -369,7 +369,7 @@ Error messages include the resolved file path for easy debugging.

## Agent State

Invoke an AI agent (Claude, Codex, Gemini, OpenCode) with a prompt template.
Invoke an AI agent (Claude, Cursor, Codex, Gemini, OpenCode) with a prompt template.

### Basic Agent Step

Expand Down Expand Up @@ -412,7 +412,7 @@ For **automated cross-step session resume** (no stdin loop), use `mode: single`

| Option | Type | Required | Description |
|--------|------|----------|-------------|
| `provider` | string | Yes | Agent provider: `claude`, `codex`, `gemini`, `opencode`, `openai_compatible` |
| `provider` | string | Yes | Agent provider: `claude`, `cursor`, `codex`, `gemini`, `opencode`, `openai_compatible` |
| `mode` | string | No | `single` (default) or `conversation` (interactive user-driven loop) |
| `prompt` | string | Yes* | Prompt template (supports `{{.inputs.*}}` and `{{.states.*}}` interpolation); in `mode: conversation` this serves as the first user message |
| `prompt_file` | string | No* | Path to external prompt template file (mutually exclusive with `prompt`; not supported in `mode: conversation`) |
Expand Down Expand Up @@ -472,7 +472,7 @@ See [Conversation Mode & Session Tracking](conversation-steps.md) for the full r
| `opencode` | `opencode` CLI | Multi-turn (session resume via `-s`) | OpenCode CLI |
| `openai_compatible` | HTTP API | Full multi-turn (messages array) | Chat Completions API (OpenAI, Ollama, vLLM, Groq) |

> **Conversation mode and providers:** All providers support multi-turn conversations. CLI-based providers (`claude`, `codex`, `gemini`, `opencode`) use native session resume flags to maintain context across turns — session IDs are extracted from CLI output after the first turn and passed on subsequent turns. If session ID extraction fails, the provider falls back to stateless mode gracefully. `openai_compatible` maintains full conversation history via the Chat Completions API messages array.
> **Conversation mode and providers:** All providers support multi-turn conversations. CLI-based providers (`claude`, `cursor`, `codex`, `gemini`, `opencode`) use native session resume flags to maintain context across turns — session IDs are extracted from CLI output after the first turn and passed on subsequent turns. If session ID extraction fails, the provider falls back to stateless mode gracefully. `openai_compatible` maintains full conversation history via the Chat Completions API messages array.

### Agent Output

Expand Down
2 changes: 1 addition & 1 deletion internal/domain/ports/agent_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

// AgentProvider defines the contract for executing AI agent CLI commands.
// Implementations adapt specific agent CLIs (Claude, Codex, Gemini, etc.)
// Implementations adapt specific agent CLIs (Claude, Cursor, Codex, Gemini, etc.)
// to this unified interface.
type AgentProvider interface {
// Execute invokes the agent with the given prompt and options.
Expand Down
2 changes: 1 addition & 1 deletion internal/domain/workflow/agent_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var validOutputFormats = map[OutputFormat]bool{

// AgentConfig holds configuration for invoking an AI agent.
type AgentConfig struct {
Provider string `yaml:"provider"` // agent provider: claude, codex, gemini, opencode, openai_compatible
Provider string `yaml:"provider"` // agent provider: claude, cursor, codex, gemini, opencode, openai_compatible
Prompt string `yaml:"prompt"` // prompt template with {{inputs.*}} and {{states.*}} (single mode) or first user message (conversation mode)
PromptFile string `yaml:"prompt_file"` // path to external prompt template file (mutually exclusive with Prompt)
Options map[string]any `yaml:"options"` // provider-specific options (model, temperature, max_tokens, etc.)
Expand Down
2 changes: 1 addition & 1 deletion internal/domain/workflow/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
//
// AI agent invocation:
// - AgentConfig: Provider, prompt, options, timeout, mode
// - Provider values: claude, codex, gemini, opencode, custom
// - Provider values: claude, cursor, codex, gemini, opencode, openai_compatible
// - Mode: single (one-shot) or conversation (multi-turn)
//
// ## Conversation Mode (F033, conversation.go)
Expand Down
Loading
Loading