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 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 tasks = JSON.parse(await readFile(process.env.WORKBENCH_TASKS || `${root}/tasks.json`, "utf8"));
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 args = task.owner === "claude" ? ["--model", process.env.CLAUDE_MODEL || "haiku", "--effort", "low", "-p", task.prompt, "--dangerously-skip-permissions"] : ["exec", "-m", process.env.CODEX_MODEL || "gpt-6.1-sol", "-s", "danger-full-access", "--dangerously-bypass-approvals-and-sandbox", task.prompt];
18
- const r = await run(task.owner === "claude" ? "claude" : "codex", args, task.worktree);
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.0",
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": ["bin", "multi-agent-workbench", "README.md", "LICENSE"],
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": {"node": ">=20"},
21
+ "engines": {
22
+ "node": ">=20"
23
+ },
17
24
  "license": "MIT",
18
- "repository": {"type": "git", "url": "https://github.com/ruhul0/multi-agent-workbench.git"},
19
- "bugs": {"url": "https://github.com/ruhul0/multi-agent-workbench/issues"},
20
- "homepage": "https://github.com/ruhul0/multi-agent-workbench#readme"
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
  }