multi-agent-workbench 0.0.0-stage → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +12 -0
- package/README.md +28 -2
- package/bin/maw.mjs +31 -0
- package/multi-agent-workbench/SKILL.md +18 -0
- package/multi-agent-workbench/agents/openai.yaml +3 -0
- package/multi-agent-workbench/references/task-schema.md +3 -0
- package/multi-agent-workbench/scripts/supervisor.mjs +38 -0
- package/package.json +34 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ruhul Amin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files, to deal in the Software
|
|
7
|
+
without restriction, including without limitation the rights to use, copy,
|
|
8
|
+
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software.
|
|
9
|
+
|
|
10
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
11
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
12
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
package/README.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Multi-Agent Workbench
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Run multiple coding-agent CLIs in parallel with isolated worktrees, micro-task queues, handoff history, and live status.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
Create `tasks.json` in your project:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
[
|
|
11
|
+
{"id":"L1","owner":"claude","command":"claude","worktree":"../project-claude","task":"API task","prompt":"Implement the API task and commit it."},
|
|
12
|
+
{"id":"C1","owner":"codex","command":"codex","worktree":"../project-codex","task":"Frontend task","prompt":"Implement the frontend task and commit it."},
|
|
13
|
+
{"id":"A1","owner":"antigravity","command":"agy","worktree":"../project-agy","task":"QA task","prompt":"Audit the current changes, fix only clear issues, and commit them."}
|
|
14
|
+
]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Install and run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g multi-agent-workbench
|
|
21
|
+
multi-agent-workbench init
|
|
22
|
+
# edit tasks.json for your project
|
|
23
|
+
multi-agent-workbench
|
|
24
|
+
# or without installing
|
|
25
|
+
npx multi-agent-workbench init
|
|
26
|
+
npx multi-agent-workbench
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The supervisor reads `tasks.json` from the current project and writes `.agent-workbench/status.json` and `.agent-workbench/supervisor.log`. Review each commit before merging or deploying.
|
package/bin/maw.mjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { dirname, resolve } from "node:path";
|
|
6
|
+
import { writeFile } from "node:fs/promises";
|
|
7
|
+
|
|
8
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
9
|
+
const supervisor = resolve(packageRoot, "multi-agent-workbench/scripts/supervisor.mjs");
|
|
10
|
+
const command = process.argv[2];
|
|
11
|
+
if (command === "--help" || command === "-h") {
|
|
12
|
+
console.log("multi-agent-workbench — run Claude and Codex tasks in parallel");
|
|
13
|
+
console.log("\nCommands:\n maw init Create a starter tasks.json\n maw Run the task queue in the current project");
|
|
14
|
+
process.exit(0);
|
|
15
|
+
}
|
|
16
|
+
if (command === "init") {
|
|
17
|
+
const target = resolve(process.cwd(), "tasks.json");
|
|
18
|
+
await writeFile(target, JSON.stringify([
|
|
19
|
+
{ id: "L1", owner: "claude", command: "claude", worktree: "../project-claude", task: "Backend task", prompt: "Implement the backend task and commit it." },
|
|
20
|
+
{ id: "C1", owner: "codex", command: "codex", worktree: "../project-codex", task: "Frontend task", prompt: "Implement the frontend task and commit it." },
|
|
21
|
+
{ id: "A1", owner: "antigravity", command: "agy", worktree: "../project-agy", task: "QA task", prompt: "Audit the current changes, fix only clear issues, and commit them." }
|
|
22
|
+
], null, 2) + "\n", { flag: "wx" });
|
|
23
|
+
console.log(`Created ${target}. Edit it, then run maw.`);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
const child = spawn(process.execPath, [supervisor, ...process.argv.slice(2)], {
|
|
27
|
+
cwd: process.cwd(),
|
|
28
|
+
stdio: "inherit",
|
|
29
|
+
env: process.env,
|
|
30
|
+
});
|
|
31
|
+
child.on("exit", (code, signal) => process.exit(signal ? 1 : (code ?? 1)));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: multi-agent-workbench
|
|
3
|
+
description: Orchestrate multiple local coding-agent CLIs in isolated worktrees with micro-task queues, handoffs, live status, review gates, and optional deployment triggers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Multi-agent workbench
|
|
7
|
+
|
|
8
|
+
Use this skill when a software task benefits from multiple coding-agent CLIs working in parallel.
|
|
9
|
+
|
|
10
|
+
- Split work into bounded micro-tasks with owners, dependencies, and acceptance checks.
|
|
11
|
+
- Give each agent its own Git worktree and branch.
|
|
12
|
+
- Assign frontend/integration tasks to Codex and backend/data tasks to Claude when requested.
|
|
13
|
+
- Capture commit, tests, changed files, output, and risks after every task.
|
|
14
|
+
- Review and cherry-pick centrally; never auto-merge unreviewed work.
|
|
15
|
+
- Keep production tests/builds on the VPS when the repository uses a server-side deployment workflow.
|
|
16
|
+
- Expose current state, task, commit, output, and completed history in a live status file/dashboard.
|
|
17
|
+
|
|
18
|
+
See `references/task-schema.md` for handoff records and `scripts/supervisor.mjs` for the Node.js supervisor.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdir, readFile, writeFile, appendFile } from "node:fs/promises";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
|
|
6
|
+
const root = process.env.WORKBENCH_ROOT || process.cwd();
|
|
7
|
+
const dir = `${root}/.agent-workbench`;
|
|
8
|
+
await mkdir(dir, { recursive: true });
|
|
9
|
+
const taskPath = process.env.WORKBENCH_TASKS || `${root}/tasks.json`;
|
|
10
|
+
let tasks;
|
|
11
|
+
try {
|
|
12
|
+
tasks = JSON.parse(await readFile(taskPath, "utf8"));
|
|
13
|
+
} catch (error) {
|
|
14
|
+
console.error(`No tasks.json found at ${taskPath}. Create a task queue first; see the README example.`);
|
|
15
|
+
process.exitCode = 2;
|
|
16
|
+
process.exit();
|
|
17
|
+
}
|
|
18
|
+
if (!Array.isArray(tasks) || tasks.length === 0) {
|
|
19
|
+
console.error(`No tasks found in ${taskPath}. Add at least one Claude or Codex task.`);
|
|
20
|
+
process.exitCode = 2;
|
|
21
|
+
process.exit();
|
|
22
|
+
}
|
|
23
|
+
const statePath = `${dir}/status.json`, logPath = `${dir}/supervisor.log`;
|
|
24
|
+
const state = { agents: {}, history: [], recent: [] };
|
|
25
|
+
const save = () => writeFile(statePath, JSON.stringify({ ...state, updated_at: new Date().toISOString() }, null, 2));
|
|
26
|
+
const log = async (line) => { const s = `[${new Date().toISOString()}] ${line}`; state.recent = [...state.recent, s].slice(-40); await appendFile(logPath, s + "\n"); await save(); };
|
|
27
|
+
function run(cmd, args, cwd) { return new Promise(resolve => { const p = spawn(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] }); let out = ""; p.stdout.on("data", x => { out += x; process.stdout.write(x); }); p.stderr.on("data", x => { out += x; process.stderr.write(x); }); p.on("close", code => resolve({ code: code ?? 1, out })); }); }
|
|
28
|
+
async function execute(task) {
|
|
29
|
+
state.agents[task.owner] = { state: "working", task: task.task, commit: null, output: [] }; await log(`${task.owner} start ${task.id}`);
|
|
30
|
+
const command = task.command || task.owner;
|
|
31
|
+
const args = command === "claude" ? ["--model", process.env.CLAUDE_MODEL || "haiku", "--effort", "low", "-p", task.prompt, "--dangerously-skip-permissions"] : command === "agy" || command === "antigravity" ? ["--dangerously-skip-permissions", "--print", task.prompt] : ["exec", "-m", process.env.CODEX_MODEL || "gpt-6.1-sol", "-s", "danger-full-access", "--dangerously-bypass-approvals-and-sandbox", task.prompt];
|
|
32
|
+
const r = await run(command === "claude" ? "claude" : command === "agy" || command === "antigravity" ? "agy" : "codex", args, task.worktree);
|
|
33
|
+
const commit = (r.out.match(/\b[0-9a-f]{7,40}\b/g) || []).at(-1) || null;
|
|
34
|
+
state.agents[task.owner] = { state: r.code === 0 ? "done" : "blocked", task: task.task, commit, output: r.out.split("\n").slice(-30) };
|
|
35
|
+
state.history = [...state.history, { id: task.id, owner: task.owner, task: task.task, commit, state: state.agents[task.owner].state, output: state.agents[task.owner].output, finished_at: new Date().toISOString() }].slice(-40);
|
|
36
|
+
await log(`${task.owner} ${state.agents[task.owner].state} ${task.id} ${commit || "—"}`); return r.code === 0;
|
|
37
|
+
}
|
|
38
|
+
await Promise.all(Object.entries(Object.groupBy(tasks, t => t.owner)).map(async ([, queue]) => { for (const task of queue) if (!await execute(task)) break; }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "multi-agent-workbench",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Run multiple coding-agent CLIs in parallel with task queues, isolated worktrees, handoffs, and live status.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"multi-agent-workbench": "bin/maw.mjs",
|
|
8
|
+
"maw": "bin/maw.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"multi-agent-workbench",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "node bin/maw.mjs",
|
|
18
|
+
"check": "node --check bin/maw.mjs && node --check multi-agent-workbench/scripts/supervisor.mjs",
|
|
19
|
+
"pack:check": "npm pack --dry-run"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/ruhul0/multi-agent-workbench.git"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/ruhul0/multi-agent-workbench/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/ruhul0/multi-agent-workbench#readme",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"multi-agent-workbench": "github:ruhul0/multi-agent-workbench"
|
|
35
|
+
}
|
|
36
|
+
}
|