quadwork 0.1.2 → 0.1.3

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.
Files changed (86) hide show
  1. package/README.md +4 -4
  2. package/bin/quadwork.js +153 -52
  3. package/out/404.html +1 -1
  4. package/out/__next.__PAGE__.txt +1 -1
  5. package/out/__next._full.txt +2 -2
  6. package/out/__next._head.txt +1 -1
  7. package/out/__next._index.txt +2 -2
  8. package/out/__next._tree.txt +2 -2
  9. package/out/_next/static/chunks/02ul7y114vj2f.js +13 -0
  10. package/out/_next/static/chunks/{0jsosmtclw5n5.js → 038g944ax83al.js} +1 -1
  11. package/out/_next/static/chunks/0gy_9ugdx7ueh.js +1 -0
  12. package/out/_next/static/chunks/0idtc5k0469of.js +1 -0
  13. package/out/_next/static/chunks/{03hi.hdp6l230.js → 0wda-2lcle8c4.js} +8 -8
  14. package/out/_next/static/chunks/0yxmvmvm1dx_d.css +2 -0
  15. package/out/_not-found/__next._full.txt +2 -2
  16. package/out/_not-found/__next._head.txt +1 -1
  17. package/out/_not-found/__next._index.txt +2 -2
  18. package/out/_not-found/__next._not-found.__PAGE__.txt +1 -1
  19. package/out/_not-found/__next._not-found.txt +1 -1
  20. package/out/_not-found/__next._tree.txt +2 -2
  21. package/out/_not-found.html +1 -1
  22. package/out/_not-found.txt +2 -2
  23. package/out/index.html +1 -1
  24. package/out/index.txt +2 -2
  25. package/out/project/_/__next._full.txt +3 -3
  26. package/out/project/_/__next._head.txt +1 -1
  27. package/out/project/_/__next._index.txt +2 -2
  28. package/out/project/_/__next._tree.txt +2 -2
  29. package/out/project/_/__next.project.$d$id.__PAGE__.txt +2 -2
  30. package/out/project/_/__next.project.$d$id.txt +1 -1
  31. package/out/project/_/__next.project.txt +1 -1
  32. package/out/project/_/memory/__next._full.txt +3 -3
  33. package/out/project/_/memory/__next._head.txt +1 -1
  34. package/out/project/_/memory/__next._index.txt +2 -2
  35. package/out/project/_/memory/__next._tree.txt +2 -2
  36. package/out/project/_/memory/__next.project.$d$id.memory.__PAGE__.txt +2 -2
  37. package/out/project/_/memory/__next.project.$d$id.memory.txt +1 -1
  38. package/out/project/_/memory/__next.project.$d$id.txt +1 -1
  39. package/out/project/_/memory/__next.project.txt +1 -1
  40. package/out/project/_/memory.html +1 -1
  41. package/out/project/_/memory.txt +3 -3
  42. package/out/project/_/queue/__next._full.txt +3 -3
  43. package/out/project/_/queue/__next._head.txt +1 -1
  44. package/out/project/_/queue/__next._index.txt +2 -2
  45. package/out/project/_/queue/__next._tree.txt +2 -2
  46. package/out/project/_/queue/__next.project.$d$id.queue.__PAGE__.txt +2 -2
  47. package/out/project/_/queue/__next.project.$d$id.queue.txt +1 -1
  48. package/out/project/_/queue/__next.project.$d$id.txt +1 -1
  49. package/out/project/_/queue/__next.project.txt +1 -1
  50. package/out/project/_/queue.html +1 -1
  51. package/out/project/_/queue.txt +3 -3
  52. package/out/project/_.html +1 -1
  53. package/out/project/_.txt +3 -3
  54. package/out/settings/__next._full.txt +3 -3
  55. package/out/settings/__next._head.txt +1 -1
  56. package/out/settings/__next._index.txt +2 -2
  57. package/out/settings/__next._tree.txt +2 -2
  58. package/out/settings/__next.settings.__PAGE__.txt +2 -2
  59. package/out/settings/__next.settings.txt +1 -1
  60. package/out/settings.html +1 -1
  61. package/out/settings.txt +3 -3
  62. package/out/setup/__next._full.txt +3 -3
  63. package/out/setup/__next._head.txt +1 -1
  64. package/out/setup/__next._index.txt +2 -2
  65. package/out/setup/__next._tree.txt +2 -2
  66. package/out/setup/__next.setup.__PAGE__.txt +2 -2
  67. package/out/setup/__next.setup.txt +1 -1
  68. package/out/setup.html +1 -1
  69. package/out/setup.txt +3 -3
  70. package/package.json +1 -1
  71. package/server/config.js +42 -2
  72. package/server/index.js +103 -55
  73. package/server/routes.js +104 -66
  74. package/templates/CLAUDE.md +16 -17
  75. package/templates/config.toml +12 -12
  76. package/templates/seeds/{t3.AGENTS.md → dev.AGENTS.md} +19 -19
  77. package/templates/seeds/{t1.AGENTS.md → head.AGENTS.md} +18 -18
  78. package/templates/seeds/{t2a.AGENTS.md → reviewer1.AGENTS.md} +16 -16
  79. package/templates/seeds/{t2b.AGENTS.md → reviewer2.AGENTS.md} +16 -16
  80. package/out/_next/static/chunks/03yov._jigv17.js +0 -1
  81. package/out/_next/static/chunks/0iqqouh_3i5y5.js +0 -13
  82. package/out/_next/static/chunks/15kwal..m9r49.css +0 -2
  83. package/out/_next/static/chunks/17sk4qv6_d0co.js +0 -1
  84. /package/out/_next/static/{vELqtMegFMn5_6zFOkhtG → 91YUiFoMbLQ9sZW4uk45J}/_buildManifest.js +0 -0
  85. /package/out/_next/static/{vELqtMegFMn5_6zFOkhtG → 91YUiFoMbLQ9sZW4uk45J}/_clientMiddlewareManifest.js +0 -0
  86. /package/out/_next/static/{vELqtMegFMn5_6zFOkhtG → 91YUiFoMbLQ9sZW4uk45J}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -84,10 +84,10 @@ Config is stored at `~/.quadwork/config.json`:
84
84
  "repo": "owner/repo",
85
85
  "working_dir": "/path/to/project",
86
86
  "agents": {
87
- "t1": { "cwd": "/path/to/project-t1", "command": "claude" },
88
- "t2a": { "cwd": "/path/to/project-t2a", "command": "claude" },
89
- "t2b": { "cwd": "/path/to/project-t2b", "command": "claude" },
90
- "t3": { "cwd": "/path/to/project-t3", "command": "claude" }
87
+ "head": { "cwd": "/path/to/project-head", "command": "claude" },
88
+ "reviewer1": { "cwd": "/path/to/project-reviewer1", "command": "claude" },
89
+ "reviewer2": { "cwd": "/path/to/project-reviewer2", "command": "claude" },
90
+ "dev": { "cwd": "/path/to/project-dev", "command": "claude" }
91
91
  }
92
92
  }
93
93
  ]
package/bin/quadwork.js CHANGED
@@ -11,7 +11,7 @@ const readline = require("readline");
11
11
  const CONFIG_DIR = path.join(os.homedir(), ".quadwork");
12
12
  const CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
13
13
  const TEMPLATES_DIR = path.join(__dirname, "..", "templates");
14
- const AGENTS = ["t1", "t2a", "t2b", "t3"];
14
+ const AGENTS = ["head", "reviewer1", "reviewer2", "dev"];
15
15
 
16
16
  // ─── ANSI Helpers ──────────────────────────────────────────────────────────
17
17
 
@@ -123,9 +123,33 @@ function askYN(rl, question, defaultYes = false) {
123
123
  });
124
124
  }
125
125
 
126
+ // Migration: rename old agent keys to new ones
127
+ const AGENT_KEY_MAP = { t1: "head", t2a: "reviewer1", t2b: "reviewer2", t3: "dev" };
128
+
129
+ function migrateAgentKeys(config) {
130
+ let changed = false;
131
+ if (config.projects) {
132
+ for (const project of config.projects) {
133
+ if (!project.agents) continue;
134
+ for (const [oldKey, newKey] of Object.entries(AGENT_KEY_MAP)) {
135
+ if (project.agents[oldKey] && !project.agents[newKey]) {
136
+ project.agents[newKey] = project.agents[oldKey];
137
+ delete project.agents[oldKey];
138
+ changed = true;
139
+ }
140
+ }
141
+ }
142
+ }
143
+ if (changed) {
144
+ try { writeConfig(config); } catch {}
145
+ }
146
+ return config;
147
+ }
148
+
126
149
  function readConfig() {
127
150
  try {
128
- return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
151
+ const config = JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
152
+ return migrateAgentKeys(config);
129
153
  } catch {
130
154
  return { port: 8400, agentchattr_url: "http://127.0.0.1:8300", projects: [] };
131
155
  }
@@ -247,7 +271,7 @@ async function setupAgents(rl, repo) {
247
271
  }
248
272
 
249
273
  log("Path to your local clone of the repo. Four worktrees will be created next to it");
250
- log("(e.g., project-t1/, project-t2a/, project-t2b/, project-t3/).");
274
+ log("(e.g., project-head/, project-reviewer1/, project-reviewer2/, project-dev/).");
251
275
  const projectDir = await ask(rl, "Project directory", process.cwd());
252
276
  const absDir = path.resolve(projectDir);
253
277
 
@@ -263,12 +287,12 @@ async function setupAgents(rl, repo) {
263
287
  }
264
288
 
265
289
  // Prompt for reviewer credentials (optional)
266
- log("A separate reviewer account lets T2a/T2b approve PRs independently. You can set this up later in Settings.");
267
- const wantReviewer = await askYN(rl, "Use a separate GitHub account for reviewers (T2a/T2b)?", false);
290
+ log("A separate reviewer account lets Reviewer1/Reviewer2 approve PRs independently. You can set this up later in Settings.");
291
+ const wantReviewer = await askYN(rl, "Use a separate GitHub account for reviewers (Reviewer1/Reviewer2)?", false);
268
292
  let reviewerUser = "";
269
293
  let reviewerTokenPath = "";
270
294
  if (wantReviewer) {
271
- log("GitHub username for the reviewer account (used in T2a/T2b seed files for PR reviews).");
295
+ log("GitHub username for the reviewer account (used in Reviewer1/Reviewer2 seed files for PR reviews).");
272
296
  reviewerUser = await ask(rl, "Reviewer GitHub username", "");
273
297
  log("Path to a file containing a GitHub PAT for the reviewer account.");
274
298
  reviewerTokenPath = await ask(rl, "Reviewer token file path", path.join(os.homedir(), ".quadwork", "reviewer-token"));
@@ -342,7 +366,7 @@ function writeAgentChattrConfig(setup, configTomlPath, { skipInstall = false } =
342
366
 
343
367
  let tomlContent = fs.readFileSync(path.join(TEMPLATES_DIR, "config.toml"), "utf-8");
344
368
  for (const agent of AGENTS) {
345
- tomlContent = tomlContent.replace(`{{${agent}_cwd}}`, setup.worktrees[agent]);
369
+ tomlContent = tomlContent.replace(new RegExp(`\\{\\{${agent}_cwd\\}\\}`, "g"), setup.worktrees[agent]);
346
370
  }
347
371
  // Replace placeholders
348
372
  tomlContent = tomlContent.replace(/\{\{project_name\}\}/g, setup.projectName);
@@ -356,6 +380,27 @@ function writeAgentChattrConfig(setup, configTomlPath, { skipInstall = false } =
356
380
  );
357
381
  }
358
382
 
383
+ // Per-project: isolated data dir and port
384
+ const dataDir = path.join(path.dirname(configTomlPath), "data");
385
+ if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true });
386
+ // Read assigned port from config (set by writeQuadWorkConfig)
387
+ const existingConfig = readConfig();
388
+ const existingProject = existingConfig.projects?.find((p) => p.id === setup.projectName);
389
+ const chattrPort = existingProject?.agentchattr_url
390
+ ? new URL(existingProject.agentchattr_url).port
391
+ : "8300";
392
+ const mcpHttp = existingProject?.mcp_http_port || 8200;
393
+ const mcpSse = existingProject?.mcp_sse_port || 8201;
394
+ tomlContent = tomlContent.replace(/^port = \d+/m, `port = ${chattrPort}`);
395
+ tomlContent = tomlContent.replace(/^data_dir = .+/m, `data_dir = "${dataDir}"`);
396
+ // Add session_token to [server] section if project has one
397
+ const sessionToken = existingProject?.agentchattr_token || "";
398
+ if (sessionToken) {
399
+ tomlContent = tomlContent.replace(/^(data_dir = .+)$/m, `$1\nsession_token = "${sessionToken}"`);
400
+ }
401
+ tomlContent = tomlContent.replace(/^http_port = \d+/m, `http_port = ${mcpHttp}`);
402
+ tomlContent = tomlContent.replace(/^sse_port = \d+/m, `sse_port = ${mcpSse}`);
403
+
359
404
  // Write config.toml
360
405
  const configDir = path.dirname(configTomlPath);
361
406
  if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });
@@ -390,8 +435,9 @@ function writeAgentChattrConfig(setup, configTomlPath, { skipInstall = false } =
390
435
  acProc.unref();
391
436
  if (acProc.pid) {
392
437
  ok(`AgentChattr started (PID: ${acProc.pid})`);
393
- const pidFile = path.join(CONFIG_DIR, "agentchattr.pid");
438
+ // Per-project PID file
394
439
  if (!fs.existsSync(CONFIG_DIR)) fs.mkdirSync(CONFIG_DIR, { recursive: true });
440
+ const pidFile = path.join(CONFIG_DIR, `agentchattr-${setup.projectName}.pid`);
395
441
  fs.writeFileSync(pidFile, String(acProc.pid));
396
442
  } else {
397
443
  warn("Could not start AgentChattr — start manually: agentchattr --config " + configTomlPath);
@@ -464,12 +510,17 @@ async function setupAddons(rl, setup, configTomlPath) {
464
510
  bridge_dir: telegramDir,
465
511
  };
466
512
 
513
+ // Resolve per-project AgentChattr URL
514
+ const projectCfg = readConfig();
515
+ const projectEntry = projectCfg.projects?.find((p) => p.id === setup.projectName);
516
+ const projectChattrUrl = projectEntry?.agentchattr_url || "http://127.0.0.1:8300";
517
+
467
518
  // Append telegram section to config.toml (token read from env at runtime)
468
519
  const telegramSection = `
469
520
  [telegram]
470
521
  bot_token = "env:${envKey}"
471
522
  chat_id = "${chatId}"
472
- agentchattr_url = "http://127.0.0.1:8300"
523
+ agentchattr_url = "${projectChattrUrl}"
473
524
  poll_interval = 2
474
525
  bridge_sender = "telegram-bridge"
475
526
  `;
@@ -481,7 +532,7 @@ bridge_sender = "telegram-bridge"
481
532
  if (fs.existsSync(bridgeScript)) {
482
533
  log("Starting Telegram bridge...");
483
534
  const bridgeToml = path.join(CONFIG_DIR, `telegram-${setup.projectName}.toml`);
484
- const bridgeTomlContent = `[telegram]\nbot_token = "${botToken}"\nchat_id = "${chatId}"\n\n[agentchattr]\nurl = "http://127.0.0.1:8300"\n`;
535
+ const bridgeTomlContent = `[telegram]\nbot_token = "${botToken}"\nchat_id = "${chatId}"\n\n[agentchattr]\nurl = "${projectChattrUrl}"\n`;
485
536
  fs.writeFileSync(bridgeToml, bridgeTomlContent, { mode: 0o600 });
486
537
  fs.chmodSync(bridgeToml, 0o600);
487
538
  const bridgeProc = spawn("python3", [bridgeScript, "--config", bridgeToml], {
@@ -586,9 +637,25 @@ function writeQuadWorkConfig(setup) {
586
637
  };
587
638
  }
588
639
 
640
+ // Auto-assign per-project AgentChattr and MCP ports (scan existing to avoid collisions)
641
+ const existingIdx = config.projects.findIndex((p) => p.id === setup.projectName);
642
+ const usedChattrPorts = new Set(config.projects.map((p) => {
643
+ try { return parseInt(new URL(p.agentchattr_url).port, 10); } catch { return 0; }
644
+ }).filter(Boolean));
645
+ const usedMcpPorts = new Set(config.projects.flatMap((p) => [p.mcp_http_port, p.mcp_sse_port]).filter(Boolean));
646
+ let chattrPort = 8300;
647
+ while (usedChattrPorts.has(chattrPort)) chattrPort++;
648
+ let mcp_http = 8200;
649
+ while (usedMcpPorts.has(mcp_http)) mcp_http++;
650
+ let mcp_sse = mcp_http + 1;
651
+ while (usedMcpPorts.has(mcp_sse)) mcp_sse++;
652
+ project.agentchattr_url = `http://127.0.0.1:${chattrPort}`;
653
+ project.agentchattr_token = require("crypto").randomBytes(16).toString("hex");
654
+ project.mcp_http_port = mcp_http;
655
+ project.mcp_sse_port = mcp_sse;
656
+
589
657
  // Upsert project
590
- const idx = config.projects.findIndex((p) => p.id === setup.projectName);
591
- if (idx >= 0) config.projects[idx] = project;
658
+ if (existingIdx >= 0) config.projects[existingIdx] = project;
592
659
  else config.projects.push(project);
593
660
 
594
661
  writeConfig(config);
@@ -601,7 +668,7 @@ async function cmdInit() {
601
668
  console.log("");
602
669
  console.log(` ${c.cyan}${c.bold}╔══════════════════════════════════════════╗${c.reset}`);
603
670
  console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.white}${c.bold}QuadWork Init${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
604
- console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.dim}4-agent coding team setup${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
671
+ console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.dim}Global setup projects via web UI${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
605
672
  console.log(` ${c.cyan}${c.bold}╚══════════════════════════════════════════╝${c.reset}`);
606
673
  console.log(`\n ${c.dim}Tip: Press Enter to accept defaults shown in [brackets].${c.reset}\n`);
607
674
 
@@ -609,46 +676,67 @@ async function cmdInit() {
609
676
 
610
677
  try {
611
678
  // Step 1: Prerequisites
679
+ header("Step 1: Prerequisites");
612
680
  const prereqsOk = checkPrereqs();
613
681
  if (!prereqsOk) {
614
682
  const proceed = await askYN(rl, "Some prerequisites missing. Continue anyway?", false);
615
683
  if (!proceed) { rl.close(); process.exit(1); }
616
684
  }
617
685
 
618
- // Step 2: GitHub
619
- const repo = await setupGitHub(rl);
620
- if (!repo) { rl.close(); process.exit(1); }
621
-
622
- // Step 3: Agents
623
- const setup = await setupAgents(rl, repo);
624
- if (!setup) { rl.close(); process.exit(1); }
625
-
626
- // Step 4: AgentChattr config (skip install if prereqs already flagged it missing)
627
- const configTomlPath = path.join(setup.absDir, "config.toml");
628
- writeAgentChattrConfig(setup, configTomlPath, { skipInstall: !agentChattrFound });
629
-
630
- // Step 5: Optional add-ons
631
- await setupAddons(rl, setup, configTomlPath);
632
-
633
- // Write QuadWork config
634
- writeQuadWorkConfig(setup);
686
+ // Step 2: Global config
687
+ header("Step 2: Global Configuration");
688
+ const port = await ask(rl, "Dashboard port", "8400");
689
+ const defaultBackend = which("claude") ? "claude" : which("codex") ? "codex" : "claude";
690
+ const backend = await ask(rl, "Default CLI backend (claude/codex)", defaultBackend);
691
+
692
+ // Write global config
693
+ const config = readConfig();
694
+ config.port = parseInt(port, 10) || 8400;
695
+ config.default_backend = backend;
696
+ writeConfig(config);
697
+ ok(`Wrote ${CONFIG_PATH}`);
698
+
699
+ // Step 3: Start server
700
+ header("Step 3: Starting Dashboard");
701
+ const quadworkDir = path.join(__dirname, "..");
702
+ const serverDir = path.join(quadworkDir, "server");
703
+ if (fs.existsSync(path.join(serverDir, "index.js"))) {
704
+ const server = spawn("node", [serverDir], {
705
+ stdio: "ignore",
706
+ detached: true,
707
+ env: { ...process.env },
708
+ });
709
+ server.unref();
710
+ if (server.pid) {
711
+ ok(`Server started (PID: ${server.pid})`);
712
+ const pidFile = path.join(CONFIG_DIR, "server.pid");
713
+ if (!fs.existsSync(CONFIG_DIR)) fs.mkdirSync(CONFIG_DIR, { recursive: true });
714
+ fs.writeFileSync(pidFile, String(server.pid));
715
+ }
716
+ } else {
717
+ warn("Server not found — run from the quadwork directory");
718
+ }
635
719
 
636
720
  // Done
721
+ const dashPort = parseInt(port, 10) || 8400;
722
+ const dashboardUrl = `http://127.0.0.1:${dashPort}`;
723
+
637
724
  header("Setup Complete");
638
- log(`Project: ${setup.projectName}`);
639
- log(`Repo: ${setup.repo}`);
640
- log(`Worktrees: ${AGENTS.map((a) => `${setup.projectName}-${a}/`).join(", ")}`);
641
- log(`Backends: ${AGENTS.map((a) => `${a.toUpperCase()}=${(setup.backends && setup.backends[a]) || setup.backend}`).join(", ")}`);
642
- log(`Config: ${CONFIG_PATH}`);
643
- log(`AgentChattr: ${configTomlPath}`);
644
- if (setup.telegram) log(`Telegram: configured`);
645
- if (setup.memoryDir) log(`Shared Memory: ${setup.memoryDir}`);
725
+ log(`Config: ${CONFIG_PATH}`);
726
+ log(`Dashboard: ${dashboardUrl}`);
727
+ log(`Backend: ${backend}`);
646
728
  log("");
647
729
  log("Next steps:");
648
- log(" npx quadwork start — launch dashboard + agents");
730
+ log(` Open ${c.cyan}${dashboardUrl}/setup${c.reset} to create your first project`);
649
731
  log(" npx quadwork stop — stop all processes");
650
732
  log("");
651
733
 
734
+ // Open browser
735
+ const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
736
+ setTimeout(() => {
737
+ try { execSync(`${openCmd} ${dashboardUrl}/setup`, { stdio: "ignore" }); } catch {}
738
+ }, 1500);
739
+
652
740
  rl.close();
653
741
  } catch (err) {
654
742
  fail(err.message);
@@ -698,11 +786,12 @@ function cmdStart() {
698
786
  const pidFile = path.join(CONFIG_DIR, "server.pid");
699
787
  fs.writeFileSync(pidFile, String(server.pid));
700
788
 
701
- // Start AgentChattr if installed and config.toml exists for first project
702
- const firstProject = config.projects[0];
703
- if (firstProject && which("agentchattr")) {
704
- const configToml = path.join(firstProject.working_dir, "config.toml");
705
- if (fs.existsSync(configToml)) {
789
+ // Start AgentChattr for each project that has a config.toml
790
+ if (which("agentchattr")) {
791
+ for (const project of config.projects) {
792
+ if (!project.working_dir) continue;
793
+ const configToml = path.join(project.working_dir, "agentchattr", "config.toml");
794
+ if (!fs.existsSync(configToml)) continue;
706
795
  const acProc = spawn("agentchattr", ["--config", configToml], {
707
796
  stdio: "ignore",
708
797
  detached: true,
@@ -710,8 +799,8 @@ function cmdStart() {
710
799
  acProc.on("error", () => {});
711
800
  acProc.unref();
712
801
  if (acProc.pid) {
713
- ok(`AgentChattr started (PID: ${acProc.pid})`);
714
- fs.writeFileSync(path.join(CONFIG_DIR, "agentchattr.pid"), String(acProc.pid));
802
+ ok(`AgentChattr started for ${project.id} (PID: ${acProc.pid})`);
803
+ fs.writeFileSync(path.join(CONFIG_DIR, `agentchattr-${project.id}.pid`), String(acProc.pid));
715
804
  }
716
805
  }
717
806
  }
@@ -750,7 +839,15 @@ function cmdStop() {
750
839
 
751
840
  let stopped = 0;
752
841
  if (stopPid("Telegram bridge", "telegram-bridge.pid")) stopped++;
842
+
843
+ // Stop per-project AgentChattr instances
844
+ const config = readConfig();
845
+ for (const project of (config.projects || [])) {
846
+ if (stopPid(`AgentChattr (${project.id})`, `agentchattr-${project.id}.pid`)) stopped++;
847
+ }
848
+ // Also stop legacy single-instance PID if present
753
849
  if (stopPid("AgentChattr", "agentchattr.pid")) stopped++;
850
+
754
851
  if (stopPid("Server", "server.pid")) stopped++;
755
852
 
756
853
  if (stopped === 0) warn("No running processes found");
@@ -772,11 +869,11 @@ async function cmdAddProject() {
772
869
  const setup = await setupAgents(rl, repo);
773
870
  if (!setup) { rl.close(); process.exit(1); }
774
871
 
775
- const configTomlPath = path.join(setup.absDir, "config.toml");
776
- writeAgentChattrConfig(setup, configTomlPath);
777
-
778
872
  writeQuadWorkConfig(setup);
779
873
 
874
+ const configTomlPath = path.join(setup.absDir, "agentchattr", "config.toml");
875
+ writeAgentChattrConfig(setup, configTomlPath);
876
+
780
877
  header("Project Added");
781
878
  log(`Project: ${setup.projectName}`);
782
879
  log(`Repo: ${setup.repo}`);
@@ -813,16 +910,20 @@ switch (command) {
813
910
  Usage: quadwork <command>
814
911
 
815
912
  Commands:
816
- init Set up a new QuadWork 4-agent environment
913
+ init Global setup (prereqs, port, backend) then open web UI
817
914
  start Start the QuadWork dashboard and backend
818
915
  stop Stop all QuadWork processes
819
- add-project Add a project to an existing QuadWork setup
916
+ add-project Add a project via CLI (alternative to web UI /setup)
917
+
918
+ Workflow:
919
+ 1. npx quadwork init — one-time global setup, opens dashboard
920
+ 2. Open /setup in browser — create projects with guided web UI
921
+ 3. npx quadwork stop — stop everything when done
820
922
 
821
923
  Examples:
822
924
  npx quadwork init
823
925
  npx quadwork start
824
926
  npx quadwork stop
825
- npx quadwork add-project
826
927
  `);
827
928
  if (command) process.exit(1);
828
929
  }
package/out/404.html CHANGED
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en" class="geist_mono_8d43a2aa-module__8Li5zG__variable h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/15kwal..m9r49.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/13uu.sohs74zg.js"/><script src="/_next/static/chunks/0excsn2a_5qsb.js" async=""></script><script src="/_next/static/chunks/0r7t_sj_sejq9.js" async=""></script><script src="/_next/static/chunks/0.dzh0qf9zq1l.js" async=""></script><script src="/_next/static/chunks/turbopack-06pqx~0d8czn_.js" async=""></script><script src="/_next/static/chunks/08fgie1bcjynm.js" async=""></script><script src="/_next/static/chunks/0ox7p_szjhn69.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>QuadWork</title><meta name="description" content="Unified dashboard for multi-agent coding teams"/><link rel="icon" href="/favicon.ico?favicon.0x3dzn~oxb6tn.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body class="h-full flex"><div hidden=""><!--$--><!--/$--></div><aside class="w-16 shrink-0 h-full border-r border-border bg-bg-surface flex flex-col items-center py-3"><a class="w-10 h-10 flex items-center justify-center rounded-sm transition-colors text-text-muted hover:text-text hover:bg-[#1a1a1a]" title="Home" href="/"><svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 10L10 3l7 7"></path><path d="M5 8.5V16h3.5v-4h3v4H15V8.5"></path></svg></a><div class="w-6 h-px bg-border my-2"></div><div class="flex-1 flex flex-col items-center gap-2 overflow-y-auto min-h-0"><a class="w-10 h-10 flex items-center justify-center rounded-full border border-dashed border-border text-text-muted hover:text-text hover:bg-[#1a1a1a] transition-colors" title="Add project" href="/setup"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M8 3v10M3 8h10"></path></svg></a></div><div class="w-6 h-px bg-border my-2"></div><a class="w-10 h-10 flex items-center justify-center rounded-sm transition-colors text-text-muted hover:text-text hover:bg-[#1a1a1a]" title="Settings" href="/settings"><svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="9" r="2.5"></circle><path d="M7.5 1.5h3l.4 2.1a5.5 5.5 0 011.3.7l2-.8 1.5 2.6-1.6 1.3a5.5 5.5 0 010 1.5l1.6 1.3-1.5 2.6-2-.8a5.5 5.5 0 01-1.3.7l-.4 2.1h-3l-.4-2.1a5.5 5.5 0 01-1.3-.7l-2 .8-1.5-2.6 1.6-1.3a5.5 5.5 0 010-1.5L2.3 6.1l1.5-2.6 2 .8a5.5 5.5 0 011.3-.7z"></path></svg></a></aside><main class="flex-1 min-w-0 overflow-auto"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--></main><script src="/_next/static/chunks/13uu.sohs74zg.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[86081,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n3:I[12527,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n4:I[59763,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n5:I[11717,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"OutletBoundary\"]\n6:\"$Sreact.suspense\"\n9:I[11717,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"ViewportBoundary\"]\nb:I[11717,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"MetadataBoundary\"]\nd:I[92243,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/15kwal..m9r49.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/15kwal..m9r49.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/08fgie1bcjynm.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0ox7p_szjhn69.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"geist_mono_8d43a2aa-module__8Li5zG__variable h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"h-full flex\",\"children\":[[\"$\",\"$L2\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1 min-w-0 overflow-auto\",\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:1:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:1:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:1:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:1:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L5\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@7\"}]}]]}],{},null,false,null]},null,false,\"$@8\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lc\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/15kwal..m9r49.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"vELqtMegFMn5_6zFOkhtG\"}\n"])</script><script>self.__next_f.push([1,"e:[]\n8:\"$We\"\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"f:I[80070,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"IconMark\"]\n7:null\nc:[[\"$\",\"title\",\"0\",{\"children\":\"QuadWork\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Unified dashboard for multi-agent coding teams\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0x3dzn~oxb6tn.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lf\",\"3\",{}]]\n"])</script></body></html>
1
+ <!DOCTYPE html><html lang="en" class="geist_mono_8d43a2aa-module__8Li5zG__variable h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/0yxmvmvm1dx_d.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/13uu.sohs74zg.js"/><script src="/_next/static/chunks/0excsn2a_5qsb.js" async=""></script><script src="/_next/static/chunks/0r7t_sj_sejq9.js" async=""></script><script src="/_next/static/chunks/0.dzh0qf9zq1l.js" async=""></script><script src="/_next/static/chunks/turbopack-06pqx~0d8czn_.js" async=""></script><script src="/_next/static/chunks/08fgie1bcjynm.js" async=""></script><script src="/_next/static/chunks/0ox7p_szjhn69.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>QuadWork</title><meta name="description" content="Unified dashboard for multi-agent coding teams"/><link rel="icon" href="/favicon.ico?favicon.0x3dzn~oxb6tn.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body class="h-full flex"><div hidden=""><!--$--><!--/$--></div><aside class="w-16 shrink-0 h-full border-r border-border bg-bg-surface flex flex-col items-center py-3"><a class="w-10 h-10 flex items-center justify-center rounded-sm transition-colors text-text-muted hover:text-text hover:bg-[#1a1a1a]" title="Home" href="/"><svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 10L10 3l7 7"></path><path d="M5 8.5V16h3.5v-4h3v4H15V8.5"></path></svg></a><div class="w-6 h-px bg-border my-2"></div><div class="flex-1 flex flex-col items-center gap-2 overflow-y-auto min-h-0"><a class="w-10 h-10 flex items-center justify-center rounded-full border border-dashed border-border text-text-muted hover:text-text hover:bg-[#1a1a1a] transition-colors" title="Add project" href="/setup"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M8 3v10M3 8h10"></path></svg></a></div><div class="w-6 h-px bg-border my-2"></div><a class="w-10 h-10 flex items-center justify-center rounded-sm transition-colors text-text-muted hover:text-text hover:bg-[#1a1a1a]" title="Settings" href="/settings"><svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="9" r="2.5"></circle><path d="M7.5 1.5h3l.4 2.1a5.5 5.5 0 011.3.7l2-.8 1.5 2.6-1.6 1.3a5.5 5.5 0 010 1.5l1.6 1.3-1.5 2.6-2-.8a5.5 5.5 0 01-1.3.7l-.4 2.1h-3l-.4-2.1a5.5 5.5 0 01-1.3-.7l-2 .8-1.5-2.6 1.6-1.3a5.5 5.5 0 010-1.5L2.3 6.1l1.5-2.6 2 .8a5.5 5.5 0 011.3-.7z"></path></svg></a></aside><main class="flex-1 min-w-0 overflow-auto"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--></main><script src="/_next/static/chunks/13uu.sohs74zg.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[86081,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n3:I[12527,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n4:I[59763,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n5:I[11717,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"OutletBoundary\"]\n6:\"$Sreact.suspense\"\n9:I[11717,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"ViewportBoundary\"]\nb:I[11717,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"MetadataBoundary\"]\nd:I[92243,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/0yxmvmvm1dx_d.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0yxmvmvm1dx_d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/08fgie1bcjynm.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0ox7p_szjhn69.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"geist_mono_8d43a2aa-module__8Li5zG__variable h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"h-full flex\",\"children\":[[\"$\",\"$L2\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1 min-w-0 overflow-auto\",\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:1:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:1:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:1:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:1:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L5\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@7\"}]}]]}],{},null,false,null]},null,false,\"$@8\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lc\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0yxmvmvm1dx_d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"91YUiFoMbLQ9sZW4uk45J\"}\n"])</script><script>self.__next_f.push([1,"e:[]\n8:\"$We\"\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"f:I[80070,[\"/_next/static/chunks/08fgie1bcjynm.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"IconMark\"]\n7:null\nc:[[\"$\",\"title\",\"0\",{\"children\":\"QuadWork\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Unified dashboard for multi-agent coding teams\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0x3dzn~oxb6tn.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lf\",\"3\",{}]]\n"])</script></body></html>
@@ -2,5 +2,5 @@
2
2
  2:I[16348,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js","/_next/static/chunks/03v5eoc-wic6o.js"],"default"]
3
3
  3:I[11717,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"OutletBoundary"]
4
4
  4:"$Sreact.suspense"
5
- 0:{"rsc":["$","$1","c",{"children":[["$","$L2",null,{}],[["$","script","script-0",{"src":"/_next/static/chunks/03v5eoc-wic6o.js","async":true}]],["$","$L3",null,{"children":["$","$4",null,{"name":"Next.MetadataOutlet","children":"$@5"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"vELqtMegFMn5_6zFOkhtG"}
5
+ 0:{"rsc":["$","$1","c",{"children":[["$","$L2",null,{}],[["$","script","script-0",{"src":"/_next/static/chunks/03v5eoc-wic6o.js","async":true}]],["$","$L3",null,{"children":["$","$4",null,{"name":"Next.MetadataOutlet","children":"$@5"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"91YUiFoMbLQ9sZW4uk45J"}
6
6
  5:null
@@ -8,9 +8,9 @@
8
8
  9:I[11717,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"ViewportBoundary"]
9
9
  b:I[11717,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"MetadataBoundary"]
10
10
  d:I[92243,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default",1]
11
- :HL["/_next/static/chunks/15kwal..m9r49.css","style"]
11
+ :HL["/_next/static/chunks/0yxmvmvm1dx_d.css","style"]
12
12
  :HL["/_next/static/media/797e433ab948586e-s.p.0.q-h669a_dqa.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
13
- 0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/15kwal..m9r49.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/08fgie1bcjynm.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/0ox7p_szjhn69.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"geist_mono_8d43a2aa-module__8Li5zG__variable h-full","children":["$","body",null,{"className":"h-full flex","children":[["$","$L2",null,{}],["$","main",null,{"className":"flex-1 min-w-0 overflow-auto","children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$L5",null,{}],[["$","script","script-0",{"src":"/_next/static/chunks/03v5eoc-wic6o.js","async":true,"nonce":"$undefined"}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],{},null,false,null]},null,false,null],["$","$1","h",{"children":[null,["$","$L9",null,{"children":"$La"}],["$","div",null,{"hidden":true,"children":["$","$Lb",null,{"children":["$","$7",null,{"name":"Next.Metadata","children":"$Lc"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$d",[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/15kwal..m9r49.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"vELqtMegFMn5_6zFOkhtG"}
13
+ 0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/0yxmvmvm1dx_d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/08fgie1bcjynm.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/0ox7p_szjhn69.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"geist_mono_8d43a2aa-module__8Li5zG__variable h-full","children":["$","body",null,{"className":"h-full flex","children":[["$","$L2",null,{}],["$","main",null,{"className":"flex-1 min-w-0 overflow-auto","children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$L5",null,{}],[["$","script","script-0",{"src":"/_next/static/chunks/03v5eoc-wic6o.js","async":true,"nonce":"$undefined"}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],{},null,false,null]},null,false,null],["$","$1","h",{"children":[null,["$","$L9",null,{"children":"$La"}],["$","div",null,{"hidden":true,"children":["$","$Lb",null,{"children":["$","$7",null,{"name":"Next.Metadata","children":"$Lc"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$d",[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/0yxmvmvm1dx_d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"91YUiFoMbLQ9sZW4uk45J"}
14
14
  a:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
15
15
  e:I[80070,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"IconMark"]
16
16
  8:null
@@ -3,4 +3,4 @@
3
3
  3:I[11717,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"MetadataBoundary"]
4
4
  4:"$Sreact.suspense"
5
5
  5:I[80070,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"IconMark"]
6
- 0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"QuadWork"}],["$","meta","1",{"name":"description","content":"Unified dashboard for multi-agent coding teams"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.0x3dzn~oxb6tn.ico","sizes":"256x256","type":"image/x-icon"}],["$","$L5","3",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"vELqtMegFMn5_6zFOkhtG"}
6
+ 0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"QuadWork"}],["$","meta","1",{"name":"description","content":"Unified dashboard for multi-agent coding teams"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.0x3dzn~oxb6tn.ico","sizes":"256x256","type":"image/x-icon"}],["$","$L5","3",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"91YUiFoMbLQ9sZW4uk45J"}
@@ -2,5 +2,5 @@
2
2
  2:I[86081,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
3
3
  3:I[12527,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
4
4
  4:I[59763,["/_next/static/chunks/08fgie1bcjynm.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
5
- :HL["/_next/static/chunks/15kwal..m9r49.css","style"]
6
- 0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/15kwal..m9r49.css","precedence":"next"}],["$","script","script-0",{"src":"/_next/static/chunks/08fgie1bcjynm.js","async":true}],["$","script","script-1",{"src":"/_next/static/chunks/0ox7p_szjhn69.js","async":true}]],["$","html",null,{"lang":"en","className":"geist_mono_8d43a2aa-module__8Li5zG__variable h-full","children":["$","body",null,{"className":"h-full flex","children":[["$","$L2",null,{}],["$","main",null,{"className":"flex-1 min-w-0 overflow-auto","children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]]}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"vELqtMegFMn5_6zFOkhtG"}
5
+ :HL["/_next/static/chunks/0yxmvmvm1dx_d.css","style"]
6
+ 0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/0yxmvmvm1dx_d.css","precedence":"next"}],["$","script","script-0",{"src":"/_next/static/chunks/08fgie1bcjynm.js","async":true}],["$","script","script-1",{"src":"/_next/static/chunks/0ox7p_szjhn69.js","async":true}]],["$","html",null,{"lang":"en","className":"geist_mono_8d43a2aa-module__8Li5zG__variable h-full","children":["$","body",null,{"className":"h-full flex","children":[["$","$L2",null,{}],["$","main",null,{"className":"flex-1 min-w-0 overflow-auto","children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]]}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"91YUiFoMbLQ9sZW4uk45J"}
@@ -1,3 +1,3 @@
1
- :HL["/_next/static/chunks/15kwal..m9r49.css","style"]
1
+ :HL["/_next/static/chunks/0yxmvmvm1dx_d.css","style"]
2
2
  :HL["/_next/static/media/797e433ab948586e-s.p.0.q-h669a_dqa.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
3
- 0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}},"staleTime":300,"buildId":"vELqtMegFMn5_6zFOkhtG"}
3
+ 0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}},"staleTime":300,"buildId":"91YUiFoMbLQ9sZW4uk45J"}
@@ -0,0 +1,13 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,83810,e=>{"use strict";var t=e.i(85899),r=e.i(16353),s=e.i(4232);function a(){return new Date().toISOString().slice(0,10)}function o(e,t){let r=a(),s=[`# Task Queue — ${r}`,"",`Repo: \`${t}\``,"","## Batch 1",""];return e.forEach((e,r)=>{s.push(`${r+1}. [${t}#${e.number}](https://github.com/${t}/issues/${e.number}) — ${e.title} (task/${e.number}-slug)`)}),s.push(""),s.push("## Rules"),s.push(""),s.push("1. Assign ONE ticket at a time to @dev"),s.push("2. Wait for @reviewer1 AND @reviewer2 to both approve before merging"),s.push("3. After merge, immediately assign the next ticket"),s.push("4. PR titles: [#<issue>] Short description"),s.push("5. Branch naming: task/<issue-number>-<slug>"),s.push("6. NEVER store keys/secrets"),s.push("7. Communicate via AgentChattr MCP chat by tagging agents"),s.push("8. Do NOT push to main — only merge approved PRs"),s.push(""),s.join("\n")}function i({projectId:e}){let[r,n]=(0,s.useState)(""),[c,l]=(0,s.useState)(""),[d,p]=(0,s.useState)(!1),[x,m]=(0,s.useState)(!1),[h,u]=(0,s.useState)(!1);(0,s.useEffect)(()=>{fetch("/api/config").then(e=>e.ok?e.json():null).then(t=>{let r=t?.projects?.find(t=>t.id===e);r?.repo&&l(r.repo)}).catch(()=>{})},[e]);let b=(0,s.useCallback)(()=>{fetch(`/api/github/issues?project=${encodeURIComponent(e)}`).then(e=>{if(!e.ok)throw Error(`${e.status}`);return e.json()}).then(e=>{n(o(e.filter(e=>"OPEN"===e.state),c))}).catch(()=>{n(o([],c))})},[e,c]),g=(0,s.useMemo)(()=>r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/^### (.+)$/gm,'<h3 class="text-sm font-semibold text-text mt-3 mb-1">$1</h3>').replace(/^## (.+)$/gm,'<h2 class="text-sm font-semibold text-accent mt-4 mb-1">$1</h2>').replace(/^# (.+)$/gm,'<h1 class="text-base font-bold text-text mt-2 mb-2">$1</h1>').replace(/^\d+\. (.+)$/gm,'<div class="pl-4 text-text">• $1</div>').replace(/^- (.+)$/gm,'<div class="pl-4 text-text-muted">– $1</div>').replace(/\*\*(.+?)\*\*/g,'<strong class="text-text">$1</strong>').replace(/`([^`]+)`/g,'<code class="text-accent text-[11px] bg-bg px-1">$1</code>').replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" target="_blank" rel="noopener" class="text-accent hover:underline">$1</a>').replace(/\n\n/g,'<div class="h-2"></div>').replace(/\n/g,"<br>"),[r]),f=`@head Work through this queue top-to-bottom. Assign ONE ticket at a time to
2
+ @dev. After each PR is merged, assign the next ticket immediately.
3
+ All tickets are autonomous — no operator gates.
4
+
5
+ IMPORTANT — Repo context:
6
+ - All work is on repo ${c}.
7
+ - Use -R ${c} for ALL gh commands (issues, PRs, merges).
8
+ - Branches, PRs, and issues are all on ${c}.
9
+
10
+ ${r}
11
+
12
+ Start now. Assign the first ticket to @dev.`,w=async()=>{await navigator.clipboard.writeText(f),m(!0),setTimeout(()=>m(!1),2e3)},j=async()=>{try{let t=await fetch("/api/config");if(!t.ok)throw Error("config");let r=await t.json(),s=await fetch(`/api/agents/${e}/head/write`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:f+"\n"})});if(404===s.status){let t=r.projects?.find(t=>t.id===e),a=t?.agents?.head?.command||"claude",o="https:"===window.location.protocol?"wss:":"ws:",i=r.port||8400,n=parseInt(window.location.port,10),c=n&&n!==i?`${window.location.hostname}:${i}`:window.location.host,l=`${o}//${c}/ws/terminal?project=${encodeURIComponent(e)}&agent=head`,d=new WebSocket(l);await new Promise((e,t)=>{d.onopen=()=>e(),d.onerror=()=>t(Error("WebSocket failed")),setTimeout(()=>t(Error("WebSocket timeout")),5e3)}),await new Promise(e=>setTimeout(e,500)),await fetch(`/api/agents/${e}/head/write`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:`${a}
13
+ `})}),await new Promise(e=>setTimeout(e,3e3)),s=await fetch(`/api/agents/${e}/head/write`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:f+"\n"})})}if(s.ok)u(!0),setTimeout(()=>u(!1),3e3);else{let e=await s.json().catch(()=>({}));alert(`Send failed: ${e.error||s.status}`)}}catch{await w(),alert("Could not reach backend. Prompt copied to clipboard instead.")}};return(0,t.jsxs)("div",{className:"h-full flex flex-col p-6 max-w-5xl",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h1",{className:"text-lg font-semibold text-text tracking-tight",children:"Task Queue"}),(0,t.jsx)("p",{className:"text-xs text-text-muted mt-0.5",children:c||e})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("button",{onClick:b,className:"px-3 py-1.5 text-[12px] border border-border text-text-muted hover:text-text hover:border-accent transition-colors",children:"Generate Template"}),(0,t.jsx)("button",{onClick:()=>{let e=new Blob([r],{type:"text/markdown"}),t=URL.createObjectURL(e),s=document.createElement("a");s.href=t,s.download=`queue-${a()}.md`,s.click(),URL.revokeObjectURL(t)},className:"px-3 py-1.5 text-[12px] border border-border text-text-muted hover:text-text hover:border-accent transition-colors",children:"Export .md"})]})]}),(0,t.jsxs)("div",{className:"flex-1 min-h-0 grid grid-cols-2 gap-0 border border-border mb-4",children:[(0,t.jsxs)("div",{className:"flex flex-col border-r border-border",children:[(0,t.jsx)("div",{className:"px-3 py-1.5 border-b border-border",children:(0,t.jsx)("span",{className:"text-[10px] text-text-muted uppercase tracking-wider",children:"Editor"})}),(0,t.jsx)("textarea",{value:r,onChange:e=>n(e.target.value),placeholder:"# Task Queue Paste or generate a queue template...",className:"flex-1 bg-bg-surface p-3 text-[12px] text-text outline-none resize-none"})]}),(0,t.jsxs)("div",{className:"flex flex-col",children:[(0,t.jsx)("div",{className:"px-3 py-1.5 border-b border-border",children:(0,t.jsx)("span",{className:"text-[10px] text-text-muted uppercase tracking-wider",children:"Preview"})}),(0,t.jsx)("div",{className:"flex-1 overflow-y-auto p-3 text-[12px] text-text",children:r?(0,t.jsx)("div",{dangerouslySetInnerHTML:{__html:g}}):(0,t.jsx)("span",{className:"text-text-muted",children:"Preview will appear here..."})})]})]}),(0,t.jsxs)("div",{className:"mb-4 px-3 py-2 border border-border bg-bg-surface text-[11px] text-text-muted",children:[(0,t.jsx)("strong",{className:"text-text",children:"How to use:"}),'Click "Generate Template" to auto-fill from open issues. Edit the queue, organize into batches, then click "Start Queue" to generate and send the Head initiation prompt.']}),(0,t.jsxs)("div",{className:"border border-border",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between px-3 py-2 border-b border-border",children:[(0,t.jsx)("span",{className:"text-[11px] text-text-muted uppercase tracking-wider",children:"Start Queue"}),(0,t.jsx)("button",{onClick:()=>p(!d),className:"text-[10px] text-text-muted hover:text-text transition-colors",children:d?"▾ hide prompt":"▸ show prompt"})]}),d&&(0,t.jsx)("div",{className:"px-3 py-2 border-b border-border bg-bg-surface max-h-48 overflow-y-auto",children:(0,t.jsx)("pre",{className:"text-[11px] text-text-muted whitespace-pre-wrap",children:f})}),(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-3",children:[(0,t.jsx)("button",{onClick:j,className:"px-4 py-1.5 bg-accent text-bg text-[12px] font-semibold hover:bg-accent-dim transition-colors",children:h?"Sent to Head":"Send to Head Terminal"}),(0,t.jsx)("button",{onClick:w,className:"px-3 py-1.5 text-[12px] border border-border text-text-muted hover:text-text hover:border-accent transition-colors",children:x?"Copied":"Copy Prompt"})]})]})]})}e.s(["default",0,function(){let e=(0,r.usePathname)().split("/")[2]||"";return e&&"_"!==e?(0,t.jsx)(i,{projectId:e}):null}],83810)}]);