
Agent Zero Bridge
- 27 installs
- 638 repo stars
- Updated March 7, 2026
- sundial-org/awesome-openclaw-skills
Helps with ai & agent building tasks during AI-assisted development.
About
agent-zero-bridge is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- agent-zero-bridge
- AI & Agent Building
- AI-coding skill
Agent Zero Bridge by the numbers
- 27 all-time installs (skills.sh)
- Ranked #9,601 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/sundial-org/awesome-openclaw-skills --skill agent-zero-bridgeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 27 |
|---|---|
| repo stars | ★ 638 |
| Last updated | March 7, 2026 |
| Repository | sundial-org/awesome-openclaw-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Agent Zero Bridge
Bidirectional communication between Clawdbot and Agent Zero.
When to Use
- Complex coding tasks requiring iteration/self-correction
- Long-running builds, tests, or infrastructure work
- Tasks needing persistent Docker execution environment
- Research with many sequential tool calls
- User explicitly asks for Agent Zero
Setup (First Time Only)
1. Prerequisites
- Node.js 18+ (for built-in fetch)
- Agent Zero running (Docker recommended, port 50001)
- Clawdbot Gateway with HTTP endpoints enabled
2. Install
# Copy skill to Clawdbot skills directory
cp -r <this-skill-folder> ~/.clawdbot/skills/agent-zero-bridge
# Create config from template
cd ~/.clawdbot/skills/agent-zero-bridge
cp .env.example .env3. Configure .env
# Agent Zero (get token from A0 settings or calculate from runtime ID)
A0_API_URL=http://127.0.0.1:50001
A0_API_KEY=your_agent_zero_token
# Clawdbot Gateway
CLAWDBOT_API_URL=http://127.0.0.1:18789
CLAWDBOT_API_TOKEN=your_gateway_token
# For Docker containers reaching host (use your machine's LAN IP)
CLAWDBOT_API_URL_DOCKER=http://192.168.1.x:187894. Get Agent Zero Token
# Calculate from A0's runtime ID
import hashlib, base64
runtime_id = "your_A0_PERSISTENT_RUNTIME_ID" # from A0's .env
hash_bytes = hashlib.sha256(f"{runtime_id}::".encode()).digest()
token = base64.urlsafe_b64encode(hash_bytes).decode().replace("=", "")[:16]
print(token)5. Enable Clawdbot Gateway Endpoints
Add to ~/.clawdbot/clawdbot.json:
{
"gateway": {
"bind": "0.0.0.0",
"auth": { "mode": "token", "token": "your_token" },
"http": { "endpoints": { "chatCompletions": { "enabled": true } } }
}
}Then: clawdbot gateway restart
6. Deploy Client to Agent Zero Container
docker exec <container> mkdir -p /a0/bridge/lib
docker cp scripts/lib/. <container>:/a0/bridge/lib/
docker cp scripts/clawdbot_client.js <container>:/a0/bridge/
docker cp .env <container>:/a0/bridge/
docker exec <container> sh -c 'echo "DOCKER_CONTAINER=true" >> /a0/bridge/.env'Usage
Send Task to Agent Zero
node scripts/a0_client.js "Build a REST API with JWT authentication"
node scripts/a0_client.js "Review this code" --attach ./file.py
node scripts/a0_client.js "New task" --new # Start fresh conversationCheck Status
node scripts/a0_client.js status
node scripts/a0_client.js history
node scripts/a0_client.js reset # Clear conversationTask Breakdown (Creates Tracked Project)
node scripts/task_breakdown.js "Build e-commerce platform"
# Creates notebook/tasks/projects/<name>.md with checkable stepsFrom Agent Zero → Clawdbot
Inside A0 container:
# Report progress
node /a0/bridge/clawdbot_client.js notify "Working on step 3..."
# Ask for input
node /a0/bridge/clawdbot_client.js "Should I use PostgreSQL or SQLite?"
# Invoke Clawdbot tool
node /a0/bridge/clawdbot_client.js tool web_search '{"query":"Node.js best practices"}'Troubleshooting
| Error | Fix |
|---|---|
| 401 / API key error | Check A0_API_KEY matches Agent Zero's mcp_server_token |
| Connection refused from Docker | Use host LAN IP in CLAWDBOT_API_URL_DOCKER, ensure gateway binds 0.0.0.0 |
| A0 500 errors | Check Agent Zero's LLM API key (Gemini/OpenAI) is valid |
Agent Zero Bridge - Clawdbot Skill
Bidirectional communication bridge between Clawdbot and Agent Zero.
What It Does
┌─────────────┐ ┌─────────────┐
│ Clawdbot │◄──────────────────►│ Agent Zero │
│ (Claude) │ │ (A0) │
└─────────────┘ └─────────────┘- Clawdbot → Agent Zero: Delegate complex coding/research tasks
- Agent Zero → Clawdbot: Report progress, ask questions, notify completion
- Task Breakdown: Break complex tasks into tracked, checkable steps
Installation
Option 1: Let Clawdbot Install It
Just tell Clawdbot:
"Install the Agent Zero bridge skill"
Or if you have this repo cloned:
"Install the Agent Zero bridge skill from ~/path/to/this/folder"
Option 2: Manual Installation
# Clone or download this repo
git clone https://github.com/DOWingard/Clawdbot-Agent0-Bridge.git
# Copy to Clawdbot skills directory
cp -r Clawdbot-Agent0-Bridge ~/.clawdbot/skills/agent-zero-bridge
# Configure
cd ~/.clawdbot/skills/agent-zero-bridge
cp .env.example .env
# Edit .env with your API keys (see SKILL.md for details)Quick Start
After installation, tell Clawdbot:
- "Ask Agent Zero to build a REST API"
- "Delegate this coding task to A0"
- "Have Agent Zero review this code"
Or use the CLI directly:
node ~/.clawdbot/skills/agent-zero-bridge/scripts/a0_client.js "Your task here"File Structure
agent-zero-bridge/
├── SKILL.md # Clawdbot skill definition + setup guide
├── .env.example # Configuration template
├── .gitignore
├── LICENSE # MIT
├── README.md # This file
└── scripts/
├── a0_client.js # CLI: Clawdbot → Agent Zero
├── clawdbot_client.js # CLI: Agent Zero → Clawdbot
├── task_breakdown.js # Task breakdown workflow
└── lib/
├── config.js # Configuration loader
├── a0_api.js # Agent Zero API client
├── clawdbot_api.js # Clawdbot API client
└── cli.js # CLI argument parserConfiguration
See SKILL.md for detailed setup instructions, including:
- How to get your Agent Zero API token
- Clawdbot Gateway configuration
- Docker deployment for bidirectional communication
Requirements
- Node.js 18+ (for built-in fetch)
- Agent Zero running (Docker recommended)
- Clawdbot Gateway with HTTP endpoints enabled
License
MIT
#!/usr/bin/env node
/**
* Agent Zero Client - For Clawdbot to call Agent Zero
*
* Usage:
* node a0_client.js <message>
* node a0_client.js message <text> [--new] [--attach <path>]
* node a0_client.js status
* node a0_client.js reset
* node a0_client.js history
* node a0_client.js context [id]
*/
const A0Client = require('./lib/a0_api');
const { parseArgs } = require('./lib/cli');
const HELP = `
Agent Zero Client (Clawdbot → A0)
Usage:
node a0_client.js <message>
node a0_client.js message <text> [--new] [--attach <path>]
node a0_client.js status
node a0_client.js reset
node a0_client.js history [--length <n>]
node a0_client.js context [id]
Options:
--new Start new conversation
--attach <path> Attach file (repeatable)
--timeout <ms> Request timeout
--json Output as JSON
Environment:
A0_API_URL Agent Zero URL (default: http://127.0.0.1:50001)
A0_API_KEY Agent Zero API key (required)
`;
async function main() {
const parsed = parseArgs(process.argv.slice(2));
const commands = ['message', 'reset', 'status', 'history', 'context', 'help'];
// Default to message if command not recognized
if (parsed.command && !commands.includes(parsed.command)) {
parsed.args.unshift(parsed.command);
parsed.command = 'message';
}
if (!parsed.command || parsed.command === 'help' || parsed.options.help) {
console.log(HELP);
return;
}
const client = new A0Client();
try {
let result;
switch (parsed.command) {
case 'message':
const msg = parsed.args.join(' ');
if (!msg) {
console.error("Error: Provide a message");
process.exit(1);
}
result = await client.sendMessage(msg, parsed.options);
break;
case 'reset':
result = await client.reset(parsed.options);
break;
case 'status':
result = await client.status();
result = parsed.options.json ? result : JSON.stringify(result, null, 2);
break;
case 'history':
const hist = await client.history(parsed.options);
if (parsed.options.json) {
result = hist;
} else if (hist.error) {
result = hist.error;
} else {
result = `Context: ${hist.contextId}\nItems: ${hist.totalItems}\n\n` +
hist.items.map(i => `[${i.type}] ${i.heading || ''}: ${(i.content || '').slice(0, 200)}`).join('\n');
}
break;
case 'context':
if (parsed.args[0]) {
client.setContext(parsed.args[0]);
result = `Context set to: ${parsed.args[0]}`;
} else {
const ctx = client.getContext();
result = ctx ? `Current context: ${ctx}` : "No active context";
}
break;
default:
console.error(`Unknown command: ${parsed.command}`);
process.exit(1);
}
if (typeof result === 'object') {
console.log(JSON.stringify(result, null, 2));
} else {
console.log(result);
}
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
}
main();
#!/usr/bin/env node
/**
* Clawdbot Client - For Agent Zero to call Clawdbot
*
* Usage:
* node clawdbot_client.js <message>
* node clawdbot_client.js message <text>
* node clawdbot_client.js notify <text>
* node clawdbot_client.js tool <name> <json>
*
* Environment:
* CLAWDBOT_API_URL - Gateway URL (default: http://127.0.0.1:18789)
* CLAWDBOT_API_TOKEN - Gateway auth token (required)
* DOCKER_CONTAINER - Set to "true" if running inside Docker
*/
const ClawdbotClient = require('./lib/clawdbot_api');
const { parseArgs } = require('./lib/cli');
const HELP = `
Clawdbot Client (Agent Zero → Clawdbot)
Usage:
node clawdbot_client.js <message>
node clawdbot_client.js message <text> - Send message, get response
node clawdbot_client.js notify <text> - Send notification
node clawdbot_client.js tool <name> <json> - Invoke a Clawdbot tool
Environment:
CLAWDBOT_API_URL - Gateway URL (default: http://127.0.0.1:18789)
CLAWDBOT_API_URL_DOCKER - URL when running in Docker (use host IP)
CLAWDBOT_API_TOKEN - Gateway auth token (required)
DOCKER_CONTAINER - Set to "true" if running inside Docker
Examples:
node clawdbot_client.js "Task complete!"
node clawdbot_client.js notify "Progress: 50%"
node clawdbot_client.js tool sessions_list '{}'
`;
async function main() {
const parsed = parseArgs(process.argv.slice(2));
const commands = ['message', 'notify', 'tool', 'help'];
// Default to message if command not recognized
if (parsed.command && !commands.includes(parsed.command)) {
parsed.args.unshift(parsed.command);
parsed.command = 'message';
}
if (!parsed.command || parsed.command === 'help' || parsed.options.help) {
console.log(HELP);
return;
}
const client = new ClawdbotClient();
try {
let result;
const text = parsed.args.join(' ');
switch (parsed.command) {
case 'message':
if (!text) {
console.error("Error: Provide a message");
process.exit(1);
}
result = await client.sendMessage(text, {
prefix: '[FROM AGENT ZERO]',
timeout: parsed.options.timeout
});
break;
case 'notify':
if (!text) {
console.error("Error: Provide a notification");
process.exit(1);
}
result = await client.notify(text);
result = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
break;
case 'tool':
const toolName = parsed.args[0];
if (!toolName) {
console.error("Error: Provide tool name");
process.exit(1);
}
const toolArgs = parsed.args[1] ? JSON.parse(parsed.args[1]) : {};
result = await client.invokeTool(toolName, toolArgs);
result = JSON.stringify(result, null, 2);
break;
default:
console.error(`Unknown command: ${parsed.command}`);
process.exit(1);
}
console.log(result);
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
}
main();
/**
* Agent Zero API Client Library
*/
const fs = require('fs');
const path = require('path');
const config = require('./config');
class A0Client {
constructor(options = {}) {
this.apiUrl = options.apiUrl || config.a0.apiUrl;
this.apiKey = options.apiKey || config.a0.apiKey;
this.contextFile = options.contextFile || config.a0.contextFile;
this.defaultTimeout = options.timeout || config.a0.defaultTimeout;
this.lifetimeHours = options.lifetimeHours || config.a0.lifetimeHours;
if (!this.apiKey) {
console.warn("Warning: A0_API_KEY not set. Set it in .env or environment.");
}
}
async request(endpoint, method = 'POST', body = null, timeout = null) {
const controller = new AbortController();
const timeoutMs = timeout || this.defaultTimeout;
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const options = {
method,
headers: {
'Content-Type': 'application/json',
'X-API-KEY': this.apiKey
},
signal: controller.signal
};
if (body) {
options.body = JSON.stringify(body);
}
const response = await fetch(`${this.apiUrl}${endpoint}`, options);
clearTimeout(timeoutId);
if (!response.ok) {
const text = await response.text();
throw new Error(`HTTP ${response.status}: ${text}`);
}
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
throw new Error(`Request timed out after ${timeoutMs}ms`);
}
throw error;
}
}
// Context management
loadContext() {
try {
if (fs.existsSync(this.contextFile)) {
return fs.readFileSync(this.contextFile, 'utf8').trim();
}
} catch (err) {}
return null;
}
saveContext(contextId) {
try {
fs.writeFileSync(this.contextFile, contextId);
} catch (err) {}
}
clearContext() {
try {
if (fs.existsSync(this.contextFile)) {
fs.unlinkSync(this.contextFile);
}
} catch (err) {}
}
// API methods
async sendMessage(message, options = {}) {
const contextId = options.new ? null : (options.context || this.loadContext());
const attachments = [];
if (options.attach) {
const files = Array.isArray(options.attach) ? options.attach : [options.attach];
for (const filePath of files) {
try {
const content = fs.readFileSync(filePath);
attachments.push({
filename: path.basename(filePath),
base64: content.toString('base64')
});
} catch (err) {
console.warn(`Warning: Could not read attachment ${filePath}`);
}
}
}
const payload = {
message,
context_id: contextId || undefined,
attachments: attachments.length > 0 ? attachments : undefined,
lifetime_hours: this.lifetimeHours
};
const data = await this.request('/api_message', 'POST', payload, options.timeout);
if (data.context_id) {
this.saveContext(data.context_id);
}
return data.response || data.message || "No response received";
}
async reset(options = {}) {
const contextId = options.context || this.loadContext();
if (!contextId) return "No active context to reset";
await this.request('/api_reset_chat', 'POST', { context_id: contextId });
this.clearContext();
return "Conversation reset successfully";
}
async status() {
const data = await this.request('/health', 'GET');
return { status: 'online', git: data.gitinfo, error: data.error };
}
async history(options = {}) {
const contextId = options.context || this.loadContext();
if (!contextId) return { error: "No active context" };
const data = await this.request('/api_log_get', 'POST', {
context_id: contextId,
length: options.length || 50
});
return {
contextId: data.context_id,
totalItems: data.log?.total_items || 0,
items: data.log?.items || []
};
}
getContext() {
return this.loadContext();
}
setContext(contextId) {
this.saveContext(contextId);
return contextId;
}
}
module.exports = A0Client;
/**
* Clawdbot API Client Library
*/
const config = require('./config');
class ClawdbotClient {
constructor(options = {}) {
// Use Docker URL if running inside container, otherwise regular URL
const isDocker = process.env.DOCKER_CONTAINER === 'true';
this.apiUrl = options.apiUrl || (isDocker ? config.clawdbot.apiUrlDocker : config.clawdbot.apiUrl);
this.apiToken = options.apiToken || config.clawdbot.apiToken;
this.defaultTimeout = options.timeout || config.clawdbot.defaultTimeout;
if (!this.apiToken) {
console.warn("Warning: CLAWDBOT_API_TOKEN not set. Set it in .env or environment.");
}
}
async request(endpoint, method = 'POST', body = null, timeout = null) {
const controller = new AbortController();
const timeoutMs = timeout || this.defaultTimeout;
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const options = {
method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiToken}`
},
signal: controller.signal
};
if (body) {
options.body = JSON.stringify(body);
}
const response = await fetch(`${this.apiUrl}${endpoint}`, options);
clearTimeout(timeoutId);
if (!response.ok) {
const text = await response.text();
throw new Error(`HTTP ${response.status}: ${text}`);
}
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
throw new Error(`Request timed out after ${timeoutMs}ms`);
}
throw error;
}
}
// Send message via OpenAI-compatible chat completions
async sendMessage(message, options = {}) {
const payload = {
model: "clawdbot:main",
messages: [
{
role: "user",
content: options.prefix ? `${options.prefix}\n\n${message}` : message
}
],
stream: false
};
const data = await this.request('/v1/chat/completions', 'POST', payload, options.timeout);
return data.choices?.[0]?.message?.content || "No response";
}
// Invoke a Clawdbot tool directly
async invokeTool(tool, args = {}, sessionKey = "main") {
const payload = {
tool,
args,
sessionKey
};
const data = await this.request('/tools/invoke', 'POST', payload);
return data.result || data;
}
// Send notification (fire and forget via sessions_send)
async notify(message) {
try {
return await this.invokeTool('sessions_send', {
sessionKey: 'main',
message: `[Agent Zero Notification]\n\n${message}`
});
} catch (error) {
// Fallback to chat completions
return await this.sendMessage(message, { prefix: '[Agent Zero Notification]' });
}
}
}
module.exports = ClawdbotClient;
/**
* CLI Argument Parser (shared utility)
*/
function parseArgs(args) {
const result = { command: null, args: [], options: {} };
let i = 0;
while (i < args.length) {
const arg = args[i];
if (arg.startsWith('--')) {
const key = arg.slice(2);
const next = args[i + 1];
if (key === 'new' || key === 'help' || key === 'json') {
result.options[key] = true;
} else if (next && !next.startsWith('--')) {
// Handle repeated options (like --attach)
if (result.options[key]) {
if (!Array.isArray(result.options[key])) {
result.options[key] = [result.options[key]];
}
result.options[key].push(next);
} else {
result.options[key] = next;
}
i++;
} else {
result.options[key] = true;
}
} else if (!result.command) {
result.command = arg;
} else {
result.args.push(arg);
}
i++;
}
return result;
}
module.exports = { parseArgs };
/**
* Shared Configuration
* Reads from environment variables or .env file
*/
const path = require('path');
// Load .env file if it exists
try {
const fs = require('fs');
const envPath = path.join(__dirname, '..', '.env');
if (fs.existsSync(envPath)) {
const envContent = fs.readFileSync(envPath, 'utf8');
envContent.split('\n').forEach(line => {
const match = line.match(/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/);
if (match && !process.env[match[1]]) {
process.env[match[1]] = match[2] || '';
}
});
}
} catch (err) {
// Ignore errors loading .env
}
const config = {
// Agent Zero
a0: {
apiUrl: process.env.A0_API_URL || "http://127.0.0.1:50001",
apiKey: process.env.A0_API_KEY || "",
contextFile: path.join(__dirname, '..', '.a0_context'),
defaultTimeout: parseInt(process.env.A0_TIMEOUT) || 120000,
lifetimeHours: parseInt(process.env.A0_LIFETIME_HOURS) || 24
},
// Clawdbot Gateway
clawdbot: {
apiUrl: process.env.CLAWDBOT_API_URL || "http://127.0.0.1:18789",
apiUrlDocker: process.env.CLAWDBOT_API_URL_DOCKER || process.env.CLAWDBOT_API_URL || "http://127.0.0.1:18789",
apiToken: process.env.CLAWDBOT_API_TOKEN || "",
defaultTimeout: parseInt(process.env.CLAWDBOT_TIMEOUT) || 60000
},
// Notebook
notebook: {
path: process.env.NOTEBOOK_PATH || path.join(__dirname, '..', 'notebook')
}
};
// Validation
function validateConfig() {
const errors = [];
if (!config.a0.apiKey) {
errors.push("A0_API_KEY is not set");
}
if (!config.clawdbot.apiToken) {
errors.push("CLAWDBOT_API_TOKEN is not set");
}
return errors;
}
config.validate = validateConfig;
module.exports = config;
#!/usr/bin/env node
/**
* Task Breakdown Workflow
*
* Uses Agent Zero to break complex tasks into steps,
* then tracks them in a notebook system.
*
* Usage:
* node task_breakdown.js "Build a REST API for user authentication"
*/
const fs = require('fs');
const path = require('path');
const A0Client = require('./lib/a0_api');
const config = require('./lib/config');
const HELP = `
Task Breakdown Workflow
Usage:
node task_breakdown.js "Your complex task description"
This will:
1. Send the task to Agent Zero for breakdown
2. Parse the returned steps
3. Create a project file in notebook/tasks/projects/
Environment:
NOTEBOOK_PATH - Path to notebook directory
`;
async function breakdownTask(client, taskDescription) {
const prompt = `You are a senior technical project manager. Break down the following task into clear, actionable steps.
Task: "${taskDescription}"
Return ONLY a numbered list of steps in this exact format:
1. [Step title]: [Brief description]
2. [Step title]: [Brief description]
...
Keep each step atomic and completable in under 2 hours. Include any prerequisites or dependencies. Do not include any preamble or explanation - just the numbered list.`;
return await client.sendMessage(prompt, { new: true });
}
function parseSteps(breakdownText) {
const lines = breakdownText.split('\n').filter(line => line.trim());
const steps = [];
for (const line of lines) {
// Try format: "1. Step title: Description"
const match = line.match(/^\d+\.\s*(.+?):\s*(.+)$/);
if (match) {
steps.push({
title: match[1].trim(),
description: match[2].trim()
});
continue;
}
// Try simpler format: "1. Do something"
const simpleMatch = line.match(/^\d+\.\s*(.+)$/);
if (simpleMatch) {
steps.push({
title: simpleMatch[1].trim(),
description: ''
});
}
}
return steps;
}
function createProjectFile(taskTitle, steps, notebookPath) {
const slug = taskTitle.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '')
.slice(0, 50);
const date = new Date().toISOString().split('T')[0];
const filename = `${date}-${slug}.md`;
const projectsDir = path.join(notebookPath, 'tasks', 'projects');
const filepath = path.join(projectsDir, filename);
// Ensure projects directory exists
if (!fs.existsSync(projectsDir)) {
fs.mkdirSync(projectsDir, { recursive: true });
}
let content = `# ${taskTitle}
**Created:** ${date}
**Status:** In Progress
**Breakdown by:** Agent Zero
---
## Steps
`;
steps.forEach((step, index) => {
content += `### ${index + 1}. ${step.title}
- [ ] **Status:** todo
${step.description ? `- **Details:** ${step.description}\n` : ''}- **Notes:**
`;
});
content += `---
## Progress Log
| Date | Step | Action | Notes |
|------|------|--------|-------|
| ${date} | - | Created | Task broken down into ${steps.length} steps |
---
## Completion Checklist
- [ ] All steps completed
- [ ] Tested/verified
- [ ] Documented
- [ ] Archived
`;
fs.writeFileSync(filepath, content);
return filepath;
}
async function main() {
const task = process.argv.slice(2).join(' ');
if (!task || task === '--help' || task === 'help') {
console.log(HELP);
return;
}
console.log(`📋 Breaking down task: "${task}"\n`);
console.log('🤖 Asking Agent Zero for step breakdown...\n');
const client = new A0Client();
try {
const breakdown = await breakdownTask(client, task);
console.log('📝 Agent Zero response:\n');
console.log(breakdown);
console.log('\n');
const steps = parseSteps(breakdown);
if (steps.length === 0) {
console.log('⚠️ Could not parse steps from response. Raw response saved.');
const filepath = createProjectFile(task, [{
title: 'Review breakdown',
description: breakdown
}], config.notebook.path);
console.log(`📁 Created: ${filepath}`);
return;
}
console.log(`✅ Parsed ${steps.length} steps\n`);
const filepath = createProjectFile(task, steps, config.notebook.path);
console.log(`📁 Project file created: ${filepath}`);
console.log('\nSteps:');
steps.forEach((step, i) => {
console.log(` ${i + 1}. ${step.title}`);
});
} catch (error) {
console.error(`❌ Error: ${error.message}`);
process.exit(1);
}
}
main();