multi-agent-workbench 0.1.0 → 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/README.md +6 -2
- package/bin/maw.mjs +17 -0
- package/multi-agent-workbench/scripts/supervisor.mjs +17 -3
- package/package.json +21 -6
package/README.md
CHANGED
|
@@ -8,8 +8,9 @@ Create `tasks.json` in your project:
|
|
|
8
8
|
|
|
9
9
|
```json
|
|
10
10
|
[
|
|
11
|
-
{"id":"L1","owner":"claude","worktree":"../project-claude","task":"API task","prompt":"Implement the API task and commit it."},
|
|
12
|
-
{"id":"C1","owner":"codex","worktree":"../project-codex","task":"Frontend task","prompt":"Implement the frontend task and commit it."}
|
|
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."}
|
|
13
14
|
]
|
|
14
15
|
```
|
|
15
16
|
|
|
@@ -17,8 +18,11 @@ Install and run:
|
|
|
17
18
|
|
|
18
19
|
```bash
|
|
19
20
|
npm install -g multi-agent-workbench
|
|
21
|
+
multi-agent-workbench init
|
|
22
|
+
# edit tasks.json for your project
|
|
20
23
|
multi-agent-workbench
|
|
21
24
|
# or without installing
|
|
25
|
+
npx multi-agent-workbench init
|
|
22
26
|
npx multi-agent-workbench
|
|
23
27
|
```
|
|
24
28
|
|
package/bin/maw.mjs
CHANGED
|
@@ -3,9 +3,26 @@ import { spawn } from "node:child_process";
|
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { dirname, resolve } from "node:path";
|
|
6
|
+
import { writeFile } from "node:fs/promises";
|
|
6
7
|
|
|
7
8
|
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
8
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
|
+
}
|
|
9
26
|
const child = spawn(process.execPath, [supervisor, ...process.argv.slice(2)], {
|
|
10
27
|
cwd: process.cwd(),
|
|
11
28
|
stdio: "inherit",
|
|
@@ -6,7 +6,20 @@ import process from "node:process";
|
|
|
6
6
|
const root = process.env.WORKBENCH_ROOT || process.cwd();
|
|
7
7
|
const dir = `${root}/.agent-workbench`;
|
|
8
8
|
await mkdir(dir, { recursive: true });
|
|
9
|
-
const
|
|
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
|
+
}
|
|
10
23
|
const statePath = `${dir}/status.json`, logPath = `${dir}/supervisor.log`;
|
|
11
24
|
const state = { agents: {}, history: [], recent: [] };
|
|
12
25
|
const save = () => writeFile(statePath, JSON.stringify({ ...state, updated_at: new Date().toISOString() }, null, 2));
|
|
@@ -14,8 +27,9 @@ const log = async (line) => { const s = `[${new Date().toISOString()}] ${line}`;
|
|
|
14
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 })); }); }
|
|
15
28
|
async function execute(task) {
|
|
16
29
|
state.agents[task.owner] = { state: "working", task: task.task, commit: null, output: [] }; await log(`${task.owner} start ${task.id}`);
|
|
17
|
-
const
|
|
18
|
-
const
|
|
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);
|
|
19
33
|
const commit = (r.out.match(/\b[0-9a-f]{7,40}\b/g) || []).at(-1) || null;
|
|
20
34
|
state.agents[task.owner] = { state: r.code === 0 ? "done" : "blocked", task: task.task, commit, output: r.out.split("\n").slice(-30) };
|
|
21
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);
|
package/package.json
CHANGED
|
@@ -1,21 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "multi-agent-workbench",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Run multiple coding-agent CLIs in parallel with task queues, isolated worktrees, handoffs, and live status.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"multi-agent-workbench": "bin/maw.mjs",
|
|
8
8
|
"maw": "bin/maw.mjs"
|
|
9
9
|
},
|
|
10
|
-
"files": [
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"multi-agent-workbench",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
11
16
|
"scripts": {
|
|
12
17
|
"start": "node bin/maw.mjs",
|
|
13
18
|
"check": "node --check bin/maw.mjs && node --check multi-agent-workbench/scripts/supervisor.mjs",
|
|
14
19
|
"pack:check": "npm pack --dry-run"
|
|
15
20
|
},
|
|
16
|
-
"engines": {
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20"
|
|
23
|
+
},
|
|
17
24
|
"license": "MIT",
|
|
18
|
-
"repository": {
|
|
19
|
-
|
|
20
|
-
|
|
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
|
+
}
|
|
21
36
|
}
|