Overview
Replace claude -p subprocess dependency with direct Anthropic Messages API calls from pure Zig. This is the critical unlock — after this, Claude CLI is no longer needed.
What exists (no new code needed — 2,147 LOC)
| File |
LOC |
Status |
src/vibeec/anthropic_client.zig |
384 |
Messages API client, 8 tests |
src/vibeec/streaming_sse.zig |
413 |
SSE parser/formatter, 5 tests |
src/vibeec/json_parser.zig |
468 |
Recursive descent JSON, tested |
src/vibeec/igla_tool_use_engine.zig |
882 |
Tool execution engine, sandboxed |
New code (~300 LOC)
tool_protocol.zig
Parse tool_use content blocks from Anthropic API response, format tool_result for next request.
// Parse from API response:
// {"type":"tool_use","id":"toolu_xxx","name":"Read","input":{"file_path":"src/main.zig"}}
// Format for next request:
// {"type":"tool_result","tool_use_id":"toolu_xxx","content":"file contents..."}
pub const ToolUseBlock = struct {
id: []const u8,
name: []const u8,
input_json: []const u8,
};
pub fn parseToolUse(response_json: []const u8) ?ToolUseBlock { ... }
pub fn formatToolResult(tool_use_id: []const u8, content: []const u8) []const u8 { ... }
Wiring tasks
- Add
tri-cli executable target to build.zig (link orphaned vibeec files)
- Wire:
anthropic_client → SSE streaming → tool_protocol → igla_tool_use_engine → loop
- Replace
claude -p subprocess in agent_loop.zig with direct API call
- Read
ANTHROPIC_API_KEY from environment
Agentic loop (core ~50 LOC)
while (true) {
const response = try api.sendMessages(messages, tool_definitions);
switch (response.stop_reason) {
.end_turn => break,
.tool_use => {
const tool = parseToolUse(response);
const result = try igla.execute(tool);
messages.append(.{ .role = "tool", .content = formatToolResult(tool.id, result) });
},
}
}
Acceptance criteria
Architecture after Phase 2
BEFORE: tri-bot → claude CLI (TypeScript/Node.js) → Anthropic API
AFTER: tri-bot → anthropic_client.zig (Pure Zig) → Anthropic API
~300 LOC new code connects ~2,500 LOC of existing tested code.
Depends on: #56 (merged)
Overview
Replace
claude -psubprocess dependency with direct Anthropic Messages API calls from pure Zig. This is the critical unlock — after this, Claude CLI is no longer needed.What exists (no new code needed — 2,147 LOC)
src/vibeec/anthropic_client.zigsrc/vibeec/streaming_sse.zigsrc/vibeec/json_parser.zigsrc/vibeec/igla_tool_use_engine.zigNew code (~300 LOC)
tool_protocol.zigParse
tool_usecontent blocks from Anthropic API response, formattool_resultfor next request.Wiring tasks
tri-cliexecutable target tobuild.zig(link orphaned vibeec files)anthropic_client→ SSE streaming →tool_protocol→igla_tool_use_engine→ loopclaude -psubprocess inagent_loop.zigwith direct API callANTHROPIC_API_KEYfrom environmentAgentic loop (core ~50 LOC)
Acceptance criteria
tri-clibinary compiles (new target in build.zig)api.anthropic.com/v1/messagesdirectly (noclaudebinary)Read,Bash,Write) executed via igla engineend_turnor max turnstri-botcan use direct API instead of CLI)Architecture after Phase 2
~300 LOC new code connects ~2,500 LOC of existing tested code.
Depends on: #56 (merged)