Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
5f9f757
Add git tasks run command to execute RALPH loop
mattzcarey Jan 2, 2026
603d734
Update plan.md progress checkboxes
mattzcarey Jan 2, 2026
3a15d50
Refactor task execution into dedicated agent command
mattzcarey Jan 4, 2026
3d94966
Simplify agent executor config and fix segfault
mattzcarey Jan 4, 2026
3a16db8
Add agent plan subcommand and document friction points
mattzcarey Jan 4, 2026
cb8632b
Fix use-after-free in runDelete and test assertion
mattzcarey Jan 4, 2026
2787435
Fix JSON escaping and update start.sh task runner
mattzcarey Jan 4, 2026
9fb5240
Add streaming JSON output and skip-permissions to start.sh
mattzcarey Jan 4, 2026
46e7565
Add friction.md documenting API issues encountered
mattzcarey Jan 4, 2026
e3622d9
Fix start.sh to use full claude command (cc alias doesn't work in scr…
mattzcarey Jan 4, 2026
8c19e01
Add ZAGI_AGENT validation for invalid values
mattzcarey Jan 4, 2026
68cdf5a
Fix relative path in getPendingTasks() using selfExePath()
mattzcarey Jan 4, 2026
a30c151
Add CONTEXT.md for agent mission context
mattzcarey Jan 4, 2026
9f89a18
Fix hardcoded binary path in agent prompts - resolve dynamically
mattzcarey Jan 4, 2026
9ad1dbc
Fix memory leaks in agent.zig consecutive_failures hashmap
mattzcarey Jan 4, 2026
3b4287b
Cleanup agent.zig - consolidate duplicate logic and simplify
mattzcarey Jan 4, 2026
0a84822
Document agent subcommands in AGENTS.md
mattzcarey Jan 4, 2026
d89e65e
Document environment variables in README.md
mattzcarey Jan 4, 2026
6d7b34c
Add inline documentation to agent.zig
mattzcarey Jan 4, 2026
5617544
Style agent.zig help text to match project conventions
mattzcarey Jan 4, 2026
9403eb3
Add comprehensive tests for agent plan --dry-run
mattzcarey Jan 5, 2026
d6021e4
Add comprehensive tests for agent run with mocked executor
mattzcarey Jan 5, 2026
5732555
Add tests for ZAGI_AGENT_CMD override
mattzcarey Jan 5, 2026
077179c
Add tests for error conditions
mattzcarey Jan 5, 2026
be3d818
Update agent run prompts with executor-aware documentation persistence
mattzcarey Jan 5, 2026
f9ecfe0
Implement append-only task editing for agents
mattzcarey Jan 8, 2026
8280280
Add agent CLI tests for args and executor paths
mattzcarey Jan 8, 2026
62d751e
Improve test performance by optimizing fixture setup
mattzcarey Jan 8, 2026
efc4b70
Implement stream-based parallel task execution
mattzcarey Jan 8, 2026
0d14152
Add --output-format stream-json flag to agent run
mattzcarey Jan 8, 2026
e448e56
Add tests for appendToTask with newlines
mattzcarey Jan 8, 2026
5c7bf61
Add COMPLETION PROMISE requirement to agent task prompts
mattzcarey Jan 8, 2026
05ce496
Merge git-tasks into git-agent-run - resolve test file conflicts
mattzcarey Jan 9, 2026
039df13
Fix test expectations to match implementation
mattzcarey Jan 9, 2026
62c0376
Redesign zagi agent plan as interactive session
mattzcarey Jan 5, 2026
7be7c3e
Update planning prompt to explore codebase before asking questions
mattzcarey Jan 5, 2026
ad75956
Add clarifying questions phase to interactive planning
mattzcarey Jan 5, 2026
45eafef
Add tasks import command for plan-to-tasks conversion
mattzcarey Jan 5, 2026
7a14484
Make zagi agent plan interactive with stdin/stdout passthrough
mattzcarey Jan 5, 2026
0d6c833
Remove --model flag from agent plan
mattzcarey Jan 9, 2026
bea8d54
Remove --model flag from agent commands
mattzcarey Jan 9, 2026
5250e0a
Improve agent run: temp logs, simple completion promise
mattzcarey Jan 9, 2026
5843949
Add knowledge persistence and fix completion promise
mattzcarey Jan 9, 2026
a87dba7
Add executor config: ZAGI_AGENT determines mode flags for custom comm…
mattzcarey Jan 9, 2026
66ffbe7
Add AI agent attribution with separate git notes namespaces
mattzcarey Jan 9, 2026
4b0fff5
Add separate log flags and session pagination
mattzcarey Jan 9, 2026
8ed3f2c
Update documentation for AI attribution and agent auto-detection
mattzcarey Jan 9, 2026
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
103 changes: 97 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,114 @@ Example:
git commit -m "Add logout button" --prompt "Add a logout button to the header. When clicked it should clear the session and redirect to /login"
```

View prompts with:
When `--prompt` is used, zagi automatically stores metadata in git notes:
- `refs/notes/agent` - detected AI agent (claude, opencode, cursor, windsurf, vscode, terminal)
- `refs/notes/prompt` - the user prompt text
- `refs/notes/session` - full session transcript (for Claude Code, OpenCode)

View metadata with:
```bash
git log --prompts
git log --prompts # show prompts (truncated to 200 chars)
git log --agent # show which AI agent made each commit
git log --session # show session transcript (paginated, first 20k bytes)
git log --session --session-offset=20000 # continue from byte 20000
```

### Environment Setup
### Agent Mode

Set `ZAGI_AGENT` to enable prompt enforcement:
Agent mode is automatically enabled when running inside AI tools:
- Claude Code (sets `CLAUDECODE=1`)
- OpenCode (sets `OPENCODE=1`)
- VS Code, Cursor, Windsurf (detected from terminal environment)

You can also enable it manually:
```bash
export ZAGI_AGENT=claude-code
export ZAGI_AGENT=my-agent
```

When this is set:
When agent mode is active:
1. `git commit` will fail without `--prompt`, ensuring all AI-generated commits have their prompts recorded
2. Destructive commands are blocked to prevent data loss

## Agent Subcommands

zagi provides two agent subcommands for autonomous task execution using the RALPH pattern (Recursive Agent Loop Pattern for Humans).

### zagi agent plan

Starts an interactive planning session where an AI agent collaborates with you to design and create tasks.

```bash
# Start an interactive session (agent will ask what you want to build)
zagi agent plan

# Start with initial context
zagi agent plan "Add user authentication with JWT"

# Preview the prompt without executing
zagi agent plan --dry-run
```

The planning agent follows an interactive protocol:
1. **Explore codebase**: Reads AGENTS.md and relevant code to understand architecture
2. **Ask clarifying questions**: Asks about scope, constraints, and preferences before drafting any plan
3. **Propose plan**: Presents a numbered implementation plan for your review
4. **Create tasks**: Only creates tasks after you explicitly approve the plan

This collaborative approach ensures the agent gathers all necessary context before committing to a task breakdown. The agent will ask 2-4 focused questions at a time about:
- **Scope**: What's included/excluded, edge cases, MVP vs nice-to-haves
- **Constraints**: Performance requirements, dependencies, compatibility
- **Preferences**: Approach/patterns, integration with existing code, testing expectations
- **Acceptance criteria**: How we know it's done, what success looks like

### zagi agent run

Executes the RALPH loop to automatically complete pending tasks.

```bash
# Run until all tasks complete (or fail 3x)
zagi agent run

# Run only one task then exit
zagi agent run --once

# Preview what would run without executing
zagi agent run --dry-run

# Set delay between tasks (default: 2 seconds)
zagi agent run --delay 5

# Safety limit - stop after N tasks
zagi agent run --max-tasks 10
```

The run loop will:
1. Pick the next pending task
2. Execute it with the configured agent
3. Mark it done on success (agent calls `zagi tasks done <task-id>`)
4. Skip tasks that fail 3 consecutive times
5. Continue until all tasks complete

### Executor Configuration

Control which AI agent executes tasks using environment variables:

```bash
# Use Claude Code (default)
ZAGI_AGENT=claude zagi agent run

# Use opencode
ZAGI_AGENT=opencode zagi agent run

# Use custom command with auto mode flags
ZAGI_AGENT=claude ZAGI_AGENT_CMD="myclaude --flag" zagi agent run

# Use completely custom tool (no auto flags)
ZAGI_AGENT_CMD="aider --yes" zagi agent run
```

See [docs/setup.md](docs/setup.md) for full configuration details.

### Blocked Commands (in agent mode)

These commands cause unrecoverable data loss and are blocked when `ZAGI_AGENT` is set:
Expand Down
89 changes: 89 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Context

Ephemeral working context for this PR. Delete before merging to main.

## Mission

Build git-native task management and autonomous agent execution for zagi.

## What is zagi?

A Zig + libgit2 wrapper that makes git output concise and agent-friendly:
- Smaller output (agents pay per token)
- Guardrails block destructive commands when `ZAGI_AGENT` is set
- Prompt provenance via `git commit --prompt "why this change"`
- Task management via `zagi tasks` (stored in `refs/tasks/<branch>`)

## Current Focus

Implementing RALPH-driven development for autonomous agent execution.

**RALPH**: https://lukeparker.dev/stop-chatting-with-ai-start-loops-ralph-driven-development

The loop:
1. `zagi agent plan` - Interactive planning session with user
2. `zagi agent run` - Autonomous execution of tasks
3. Tasks stored as git objects (`refs/tasks/<branch>`)
4. Agent picks pending task, completes it, marks done
5. Loop continues until all tasks complete

## Work Streams

### 1. Agent Execution (tasks 001-012) - DONE
- Subcommand refactor (plan/run)
- Executor config (ZAGI_AGENT, ZAGI_AGENT_CMD)
- Validation and bug fixes

### 2. Cleanup & Polish (tasks 013-023)
- Memory leaks in tasks.zig
- Hardcoded paths
- Documentation updates
- Style conformance

### 3. Testing (tasks 024-030)
- Agent plan/run tests
- Error condition coverage
- Full test suite pass

### 4. git edit Feature (tasks 037-062)
- jj-style mid-stack editing
- Lets agents fix commits from earlier in history
- Auto-rebases descendants after edit

### 5. Interactive Planning (tasks 032-036)
- Make `zagi agent plan` interactive (stdin/stdout passthrough)
- Agent explores codebase, asks questions, builds plan with user
- Convert approved plan to tasks

### 6. Observability (tasks 064-067)
- Streaming JSON output for debugging
- CONTEXT.md generation during planning

## Key Files

- `src/cmds/tasks.zig` - Task CRUD operations
- `src/cmds/agent.zig` - Agent plan/run subcommands
- `start.sh` - Independent RALPH loop runner
- `friction.md` - Issues encountered during development

## Constraints

- No external dependencies (everything in git)
- Concise output (agents pay per token)
- No emojis in code or output
- Agents cannot edit/delete tasks (guardrail)
- Always use `--prompt` when committing
- Never `git push` (only commit)

## Build & Test

```bash
zig build # Build
zig build test # Zig unit tests
cd test && bun run test # Integration tests
```

## Environment

- `ZAGI_AGENT=claude|opencode` - Executor, enables guardrails
- `ZAGI_AGENT_CMD` - Custom command override
36 changes: 26 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,29 +69,45 @@ git fork --delete-all

### Agent mode

Set `ZAGI_AGENT` to enable agent-specific features.
Agent mode is automatically enabled when running inside AI tools (Claude Code, OpenCode, Cursor, Windsurf, VS Code). You can also enable it manually:

```bash
export ZAGI_AGENT=claude-code
export ZAGI_AGENT=my-agent
```

The value can be any string describing your agent (e.g. `claude-code`, `cursor`, `opencode`) - this will be used in future features for agent-specific behavior.

This enables:
- **Prompt tracking**: `git commit` requires `--prompt` to record the user request that created the commit
- **AI attribution**: Automatically detects and stores which AI agent made the commit
- **Guardrails**: Blocks destructive commands (`reset --hard`, `checkout .`, `clean -f`, `push --force`) to prevent data loss

```bash
git commit -m "Add feature" --prompt "Add a logout button to the header.."
git log --prompts # view prompts
git commit -m "Add feature" --prompt "Add a logout button to the header"
git log --prompts # view prompts
git log --agent # view which AI agent made commits
git log --session # view full session transcript (with pagination)
```

To prevent child processes from overriding `ZAGI_AGENT`, make it readonly:
Metadata is stored in git notes (`refs/notes/agent`, `refs/notes/prompt`, `refs/notes/session`) which are local by default and don't affect commit history.

### Environment variables

| Variable | Description | Default | Valid values |
|----------|-------------|---------|--------------|
| `ZAGI_AGENT` | Manually enable agent mode. Auto-detected from `CLAUDECODE`, `OPENCODE`, or IDE environment. | (auto) | Any string enables agent mode. For executors: `claude`, `opencode` |
| `ZAGI_AGENT_CMD` | Custom executor command override. When set, the prompt is appended as the final argument. | (unset) | Any shell command (e.g., `aider --yes`) |
| `ZAGI_STRIP_COAUTHORS` | Strips `Co-Authored-By:` lines from commit messages. | (unset) | `1` to enable |

**Agent detection**: Agent mode is automatically enabled when `CLAUDECODE=1` or `OPENCODE=1` is set (by Claude Code or OpenCode), or when running in VS Code/Cursor/Windsurf terminals.

```bash
# bash/zsh
export ZAGI_AGENT=claude-code
readonly ZAGI_AGENT
# Use Claude Code (default)
ZAGI_AGENT=claude zagi agent run

# Use opencode
ZAGI_AGENT=opencode zagi agent run

# Use a custom command
ZAGI_AGENT_CMD="aider --yes" zagi agent run
```

### Strip co-authors
Expand Down
10 changes: 10 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,22 @@ pub fn build(b: *std.Build) void {
});
diff_tests.root_module.linkLibrary(libgit2_dep.artifact("git2"));

const agent_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("src/cmds/agent.zig"),
.target = target,
.optimize = optimize,
}),
});

const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
const run_log_tests = b.addRunArtifact(log_tests);
const run_git_tests = b.addRunArtifact(git_tests);
const run_alias_tests = b.addRunArtifact(alias_tests);
const run_add_tests = b.addRunArtifact(add_tests);
const run_commit_tests = b.addRunArtifact(commit_tests);
const run_diff_tests = b.addRunArtifact(diff_tests);
const run_agent_tests = b.addRunArtifact(agent_tests);

const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_exe_unit_tests.step);
Expand All @@ -109,4 +118,5 @@ pub fn build(b: *std.Build) void {
test_step.dependOn(&run_add_tests.step);
test_step.dependOn(&run_commit_tests.step);
test_step.dependOn(&run_diff_tests.step);
test_step.dependOn(&run_agent_tests.step);
}
45 changes: 32 additions & 13 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ Options:
- `--grep=<pattern>` - filter by commit message
- `--since=<date>` - commits after date (e.g. "2025-01-01", "1 week ago")
- `--until=<date>` - commits before date
- `--prompts` - show AI prompts attached to commits
- `--agent` - show which AI agent made the commit
- `--session` - show session transcript (first 20k bytes)
- `--session-offset=N` - start session display at byte N
- `--session-limit=N` - limit session display to N bytes
- `-- <path>...` - filter to commits affecting paths

### git diff
Expand Down Expand Up @@ -110,34 +115,48 @@ Forks are git worktrees. The `.forks/` directory is auto-added to `.gitignore`.
- `--pick` performs a proper git merge, preserving both base and fork history
- `--promote` moves HEAD to the fork's commit, discarding any base-only commits (stash uncommitted changes first)

### --prompt
### --prompt (AI Attribution)

Store the user prompt that created a commit:
Store the user prompt and AI metadata with a commit:

```bash
git commit -m "Add feature" --prompt "Add a logout button to the header"
git log --prompts # view prompts in log output
```

### ZAGI_AGENT
When `--prompt` is used, zagi stores metadata in git notes:
- `refs/notes/agent` - detected AI agent (claude, opencode, cursor, etc.)
- `refs/notes/prompt` - the user prompt text
- `refs/notes/session` - full session transcript (Claude Code, OpenCode)

Set `ZAGI_AGENT` to enable agent-specific features. The value can be any string describing your agent (e.g. `claude-code`, `cursor`, `aider`) - this will be used in future features for agent-specific behavior.
View with log flags:
```bash
git log --prompts # show prompts (truncated to 200 chars)
git log --agent # show agent name
git log --session # show session transcript (paginated)
git log --session --session-limit=1000 # first 1000 bytes
git log --session --session-offset=1000 # start at byte 1000
```

Git notes are local by default and don't modify commit history.

### Agent Mode

Agent mode is automatically enabled when running inside AI tools:
- Claude Code (`CLAUDECODE=1`)
- OpenCode (`OPENCODE=1`)
- VS Code, Cursor, Windsurf (detected from `VSCODE_GIT_ASKPASS_NODE`)

You can also enable it manually:
```bash
export ZAGI_AGENT=claude-code
git commit -m "x" # error: --prompt required
export ZAGI_AGENT=my-agent
```

When `ZAGI_AGENT` is set:
When agent mode is active:
- `git commit` requires `--prompt` to record the user request
- Destructive commands are blocked (guardrails)

To prevent child processes from overriding `ZAGI_AGENT`, make it readonly:

```bash
# bash/zsh
export ZAGI_AGENT=claude-code
readonly ZAGI_AGENT
git commit -m "x" # error: --prompt required in agent mode
```

### ZAGI_STRIP_COAUTHORS
Expand Down
Loading