Skip to content

Commit 3fe5f34

Browse files
committed
Merge branch 'main' into git-edit
Resolve conflicts: - AGENTS.md: Keep both git edit and agent subcommands sections - src/passthrough.zig: Include all imports (edit, git, detect)
2 parents 7abcc61 + 6dd4162 commit 3fe5f34

29 files changed

Lines changed: 6436 additions & 92 deletions

AGENTS.md

Lines changed: 97 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,32 @@ Example:
2828
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"
2929
```
3030

31-
View prompts with:
31+
When `--prompt` is used, zagi automatically stores metadata in git notes:
32+
- `refs/notes/agent` - detected AI agent (claude, opencode, cursor, windsurf, vscode, terminal)
33+
- `refs/notes/prompt` - the user prompt text
34+
- `refs/notes/session` - full session transcript (for Claude Code, OpenCode)
35+
36+
View metadata with:
3237
```bash
33-
git log --prompts
38+
git log --prompts # show prompts (truncated to 200 chars)
39+
git log --agent # show which AI agent made each commit
40+
git log --session # show session transcript (paginated, first 20k bytes)
41+
git log --session --session-offset=20000 # continue from byte 20000
3442
```
3543

36-
### Environment Setup
44+
### Agent Mode
3745

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

51+
You can also enable it manually:
4052
```bash
41-
export ZAGI_AGENT=claude-code
53+
export ZAGI_AGENT=my-agent
4254
```
4355

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

@@ -165,6 +177,85 @@ edit: complete
165177
rebased: 3 commits
166178
```
167179

180+
## Agent Subcommands
181+
182+
zagi provides two agent subcommands for autonomous task execution using the RALPH pattern (Recursive Agent Loop Pattern for Humans).
183+
184+
### zagi agent plan
185+
186+
Starts an interactive planning session where an AI agent collaborates with you to design and create tasks.
187+
188+
```bash
189+
# Start an interactive session (agent will ask what you want to build)
190+
zagi agent plan
191+
192+
# Start with initial context
193+
zagi agent plan "Add user authentication with JWT"
194+
195+
# Preview the prompt without executing
196+
zagi agent plan --dry-run
197+
```
198+
199+
The planning agent follows an interactive protocol:
200+
1. **Explore codebase**: Reads AGENTS.md and relevant code to understand architecture
201+
2. **Ask clarifying questions**: Asks about scope, constraints, and preferences before drafting any plan
202+
3. **Propose plan**: Presents a numbered implementation plan for your review
203+
4. **Create tasks**: Only creates tasks after you explicitly approve the plan
204+
205+
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:
206+
- **Scope**: What's included/excluded, edge cases, MVP vs nice-to-haves
207+
- **Constraints**: Performance requirements, dependencies, compatibility
208+
- **Preferences**: Approach/patterns, integration with existing code, testing expectations
209+
- **Acceptance criteria**: How we know it's done, what success looks like
210+
211+
### zagi agent run
212+
213+
Executes the RALPH loop to automatically complete pending tasks.
214+
215+
```bash
216+
# Run until all tasks complete (or fail 3x)
217+
zagi agent run
218+
219+
# Run only one task then exit
220+
zagi agent run --once
221+
222+
# Preview what would run without executing
223+
zagi agent run --dry-run
224+
225+
# Set delay between tasks (default: 2 seconds)
226+
zagi agent run --delay 5
227+
228+
# Safety limit - stop after N tasks
229+
zagi agent run --max-tasks 10
230+
```
231+
232+
The run loop will:
233+
1. Pick the next pending task
234+
2. Execute it with the configured agent
235+
3. Mark it done on success (agent calls `zagi tasks done <task-id>`)
236+
4. Skip tasks that fail 3 consecutive times
237+
5. Continue until all tasks complete
238+
239+
### Executor Configuration
240+
241+
Control which AI agent executes tasks using environment variables:
242+
243+
```bash
244+
# Use Claude Code (default)
245+
ZAGI_AGENT=claude zagi agent run
246+
247+
# Use opencode
248+
ZAGI_AGENT=opencode zagi agent run
249+
250+
# Use custom command with auto mode flags
251+
ZAGI_AGENT=claude ZAGI_AGENT_CMD="myclaude --flag" zagi agent run
252+
253+
# Use completely custom tool (no auto flags)
254+
ZAGI_AGENT_CMD="aider --yes" zagi agent run
255+
```
256+
257+
See [docs/setup.md](docs/setup.md) for full configuration details.
258+
168259
### Blocked Commands (in agent mode)
169260

170261
These commands cause unrecoverable data loss and are blocked when `ZAGI_AGENT` is set:

CONTEXT.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Context
2+
3+
Ephemeral working context for this PR. Delete before merging to main.
4+
5+
## Mission
6+
7+
Build git-native task management and autonomous agent execution for zagi.
8+
9+
## What is zagi?
10+
11+
A Zig + libgit2 wrapper that makes git output concise and agent-friendly:
12+
- Smaller output (agents pay per token)
13+
- Guardrails block destructive commands when `ZAGI_AGENT` is set
14+
- Prompt provenance via `git commit --prompt "why this change"`
15+
- Task management via `zagi tasks` (stored in `refs/tasks/<branch>`)
16+
17+
## Current Focus
18+
19+
Implementing RALPH-driven development for autonomous agent execution.
20+
21+
**RALPH**: https://lukeparker.dev/stop-chatting-with-ai-start-loops-ralph-driven-development
22+
23+
The loop:
24+
1. `zagi agent plan` - Interactive planning session with user
25+
2. `zagi agent run` - Autonomous execution of tasks
26+
3. Tasks stored as git objects (`refs/tasks/<branch>`)
27+
4. Agent picks pending task, completes it, marks done
28+
5. Loop continues until all tasks complete
29+
30+
## Work Streams
31+
32+
### 1. Agent Execution (tasks 001-012) - DONE
33+
- Subcommand refactor (plan/run)
34+
- Executor config (ZAGI_AGENT, ZAGI_AGENT_CMD)
35+
- Validation and bug fixes
36+
37+
### 2. Cleanup & Polish (tasks 013-023)
38+
- Memory leaks in tasks.zig
39+
- Hardcoded paths
40+
- Documentation updates
41+
- Style conformance
42+
43+
### 3. Testing (tasks 024-030)
44+
- Agent plan/run tests
45+
- Error condition coverage
46+
- Full test suite pass
47+
48+
### 4. git edit Feature (tasks 037-062)
49+
- jj-style mid-stack editing
50+
- Lets agents fix commits from earlier in history
51+
- Auto-rebases descendants after edit
52+
53+
### 5. Interactive Planning (tasks 032-036)
54+
- Make `zagi agent plan` interactive (stdin/stdout passthrough)
55+
- Agent explores codebase, asks questions, builds plan with user
56+
- Convert approved plan to tasks
57+
58+
### 6. Observability (tasks 064-067)
59+
- Streaming JSON output for debugging
60+
- CONTEXT.md generation during planning
61+
62+
## Key Files
63+
64+
- `src/cmds/tasks.zig` - Task CRUD operations
65+
- `src/cmds/agent.zig` - Agent plan/run subcommands
66+
- `start.sh` - Independent RALPH loop runner
67+
- `friction.md` - Issues encountered during development
68+
69+
## Constraints
70+
71+
- No external dependencies (everything in git)
72+
- Concise output (agents pay per token)
73+
- No emojis in code or output
74+
- Agents cannot edit/delete tasks (guardrail)
75+
- Always use `--prompt` when committing
76+
- Never `git push` (only commit)
77+
78+
## Build & Test
79+
80+
```bash
81+
zig build # Build
82+
zig build test # Zig unit tests
83+
cd test && bun run test # Integration tests
84+
```
85+
86+
## Environment
87+
88+
- `ZAGI_AGENT=claude|opencode` - Executor, enables guardrails
89+
- `ZAGI_AGENT_CMD` - Custom command override

README.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,29 +69,45 @@ git fork --delete-all
6969

7070
### Agent mode
7171

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

7474
```bash
75-
export ZAGI_AGENT=claude-code
75+
export ZAGI_AGENT=my-agent
7676
```
7777

78-
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.
79-
8078
This enables:
8179
- **Prompt tracking**: `git commit` requires `--prompt` to record the user request that created the commit
80+
- **AI attribution**: Automatically detects and stores which AI agent made the commit
8281
- **Guardrails**: Blocks destructive commands (`reset --hard`, `checkout .`, `clean -f`, `push --force`) to prevent data loss
8382

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

89-
To prevent child processes from overriding `ZAGI_AGENT`, make it readonly:
90+
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.
91+
92+
### Environment variables
93+
94+
| Variable | Description | Default | Valid values |
95+
|----------|-------------|---------|--------------|
96+
| `ZAGI_AGENT` | Manually enable agent mode. Auto-detected from `CLAUDECODE`, `OPENCODE`, or IDE environment. | (auto) | Any string enables agent mode. For executors: `claude`, `opencode` |
97+
| `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`) |
98+
| `ZAGI_STRIP_COAUTHORS` | Strips `Co-Authored-By:` lines from commit messages. | (unset) | `1` to enable |
99+
100+
**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.
90101

91102
```bash
92-
# bash/zsh
93-
export ZAGI_AGENT=claude-code
94-
readonly ZAGI_AGENT
103+
# Use Claude Code (default)
104+
ZAGI_AGENT=claude zagi agent run
105+
106+
# Use opencode
107+
ZAGI_AGENT=opencode zagi agent run
108+
109+
# Use a custom command
110+
ZAGI_AGENT_CMD="aider --yes" zagi agent run
95111
```
96112

97113
### Strip co-authors

build.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,22 @@ pub fn build(b: *std.Build) void {
9393
});
9494
diff_tests.root_module.linkLibrary(libgit2_dep.artifact("git2"));
9595

96+
const agent_tests = b.addTest(.{
97+
.root_module = b.createModule(.{
98+
.root_source_file = b.path("src/cmds/agent.zig"),
99+
.target = target,
100+
.optimize = optimize,
101+
}),
102+
});
103+
96104
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
97105
const run_log_tests = b.addRunArtifact(log_tests);
98106
const run_git_tests = b.addRunArtifact(git_tests);
99107
const run_alias_tests = b.addRunArtifact(alias_tests);
100108
const run_add_tests = b.addRunArtifact(add_tests);
101109
const run_commit_tests = b.addRunArtifact(commit_tests);
102110
const run_diff_tests = b.addRunArtifact(diff_tests);
111+
const run_agent_tests = b.addRunArtifact(agent_tests);
103112

104113
const test_step = b.step("test", "Run unit tests");
105114
test_step.dependOn(&run_exe_unit_tests.step);
@@ -109,4 +118,5 @@ pub fn build(b: *std.Build) void {
109118
test_step.dependOn(&run_add_tests.step);
110119
test_step.dependOn(&run_commit_tests.step);
111120
test_step.dependOn(&run_diff_tests.step);
121+
test_step.dependOn(&run_agent_tests.step);
112122
}

docs/features.md

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ Options:
3939
- `--grep=<pattern>` - filter by commit message
4040
- `--since=<date>` - commits after date (e.g. "2025-01-01", "1 week ago")
4141
- `--until=<date>` - commits before date
42+
- `--prompts` - show AI prompts attached to commits
43+
- `--agent` - show which AI agent made the commit
44+
- `--session` - show session transcript (first 20k bytes)
45+
- `--session-offset=N` - start session display at byte N
46+
- `--session-limit=N` - limit session display to N bytes
4247
- `-- <path>...` - filter to commits affecting paths
4348

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

113-
### --prompt
118+
### --prompt (AI Attribution)
114119

115-
Store the user prompt that created a commit:
120+
Store the user prompt and AI metadata with a commit:
116121

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

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

124-
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.
131+
View with log flags:
132+
```bash
133+
git log --prompts # show prompts (truncated to 200 chars)
134+
git log --agent # show agent name
135+
git log --session # show session transcript (paginated)
136+
git log --session --session-limit=1000 # first 1000 bytes
137+
git log --session --session-offset=1000 # start at byte 1000
138+
```
139+
140+
Git notes are local by default and don't modify commit history.
125141

142+
### Agent Mode
143+
144+
Agent mode is automatically enabled when running inside AI tools:
145+
- Claude Code (`CLAUDECODE=1`)
146+
- OpenCode (`OPENCODE=1`)
147+
- VS Code, Cursor, Windsurf (detected from `VSCODE_GIT_ASKPASS_NODE`)
148+
149+
You can also enable it manually:
126150
```bash
127-
export ZAGI_AGENT=claude-code
128-
git commit -m "x" # error: --prompt required
151+
export ZAGI_AGENT=my-agent
129152
```
130153

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

135-
To prevent child processes from overriding `ZAGI_AGENT`, make it readonly:
136-
137158
```bash
138-
# bash/zsh
139-
export ZAGI_AGENT=claude-code
140-
readonly ZAGI_AGENT
159+
git commit -m "x" # error: --prompt required in agent mode
141160
```
142161

143162
### ZAGI_STRIP_COAUTHORS

0 commit comments

Comments
 (0)