quadwork 0.1.3 → 1.0.1
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 +58 -83
- package/bin/quadwork.js +376 -60
- package/out/404.html +1 -1
- package/out/__next.__PAGE__.txt +1 -1
- package/out/__next._full.txt +2 -2
- package/out/__next._head.txt +1 -1
- package/out/__next._index.txt +2 -2
- package/out/__next._tree.txt +2 -2
- package/out/_next/static/chunks/0ahp74n0wkel0.js +1 -0
- package/out/_next/static/chunks/{038g944ax83al.js → 0dmi9pk2bd712.js} +3 -3
- package/out/_next/static/chunks/0ezniz80psxr6.js +1 -0
- package/out/_next/static/chunks/0g-nq4.uckan-.js +1 -0
- package/out/_next/static/chunks/0io_y3d0p5v~b.js +2 -0
- package/out/_next/static/chunks/0jt42fqe6jaw6.js +1 -0
- package/out/_next/static/chunks/{0wda-2lcle8c4.js → 0q5hwcek8vu2q.js} +12 -12
- package/out/_next/static/chunks/0r_tb4lmfa_yb.js +1 -0
- package/out/_next/static/chunks/0s8jbc4nxw6y6.css +2 -0
- package/out/_next/static/chunks/0z~0.4hivi.f2.js +31 -0
- package/out/_next/static/chunks/135rms05ismy4.js +13 -0
- package/out/_next/static/chunks/14kr4rvjq-2md.js +1 -0
- package/out/_next/static/chunks/turbopack-0sammtvunroor.js +1 -0
- package/out/_not-found/__next._full.txt +2 -2
- package/out/_not-found/__next._head.txt +1 -1
- package/out/_not-found/__next._index.txt +2 -2
- package/out/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/out/_not-found/__next._not-found.txt +1 -1
- package/out/_not-found/__next._tree.txt +2 -2
- package/out/_not-found.html +1 -1
- package/out/_not-found.txt +2 -2
- package/out/app-shell/__next._full.txt +18 -0
- package/out/app-shell/__next._head.txt +6 -0
- package/out/app-shell/__next._index.txt +6 -0
- package/out/app-shell/__next._tree.txt +3 -0
- package/out/app-shell/__next.app-shell.__PAGE__.txt +5 -0
- package/out/app-shell/__next.app-shell.txt +5 -0
- package/out/app-shell.html +1 -0
- package/out/app-shell.txt +18 -0
- package/out/index.html +1 -1
- package/out/index.txt +2 -2
- package/out/project/_/__next._full.txt +3 -4
- package/out/project/_/__next._head.txt +1 -1
- package/out/project/_/__next._index.txt +2 -2
- package/out/project/_/__next._tree.txt +2 -3
- package/out/project/_/__next.project.$d$id.__PAGE__.txt +2 -3
- package/out/project/_/__next.project.$d$id.txt +1 -1
- package/out/project/_/__next.project.txt +1 -1
- package/out/project/_/memory/__next._full.txt +3 -3
- package/out/project/_/memory/__next._head.txt +1 -1
- package/out/project/_/memory/__next._index.txt +2 -2
- package/out/project/_/memory/__next._tree.txt +2 -2
- package/out/project/_/memory/__next.project.$d$id.memory.__PAGE__.txt +2 -2
- package/out/project/_/memory/__next.project.$d$id.memory.txt +1 -1
- package/out/project/_/memory/__next.project.$d$id.txt +1 -1
- package/out/project/_/memory/__next.project.txt +1 -1
- package/out/project/_/memory.html +1 -1
- package/out/project/_/memory.txt +3 -3
- package/out/project/_/queue/__next._full.txt +3 -3
- package/out/project/_/queue/__next._head.txt +1 -1
- package/out/project/_/queue/__next._index.txt +2 -2
- package/out/project/_/queue/__next._tree.txt +2 -2
- package/out/project/_/queue/__next.project.$d$id.queue.__PAGE__.txt +2 -2
- package/out/project/_/queue/__next.project.$d$id.queue.txt +1 -1
- package/out/project/_/queue/__next.project.$d$id.txt +1 -1
- package/out/project/_/queue/__next.project.txt +1 -1
- package/out/project/_/queue.html +1 -1
- package/out/project/_/queue.txt +3 -3
- package/out/project/_.html +1 -1
- package/out/project/_.txt +3 -4
- package/out/settings/__next._full.txt +3 -3
- package/out/settings/__next._head.txt +1 -1
- package/out/settings/__next._index.txt +2 -2
- package/out/settings/__next._tree.txt +2 -2
- package/out/settings/__next.settings.__PAGE__.txt +2 -2
- package/out/settings/__next.settings.txt +1 -1
- package/out/settings.html +1 -1
- package/out/settings.txt +3 -3
- package/out/setup/__next._full.txt +3 -3
- package/out/setup/__next._head.txt +1 -1
- package/out/setup/__next._index.txt +2 -2
- package/out/setup/__next._tree.txt +2 -2
- package/out/setup/__next.setup.__PAGE__.txt +2 -2
- package/out/setup/__next.setup.txt +1 -1
- package/out/setup.html +1 -1
- package/out/setup.txt +3 -3
- package/package.json +1 -1
- package/server/config.js +25 -1
- package/server/index.js +248 -15
- package/server/routes.js +91 -2
- package/out/_next/static/chunks/0.dzh0qf9zq1l.js +0 -2
- package/out/_next/static/chunks/02ul7y114vj2f.js +0 -13
- package/out/_next/static/chunks/0gy_9ugdx7ueh.js +0 -1
- package/out/_next/static/chunks/0idtc5k0469of.js +0 -1
- package/out/_next/static/chunks/0yxmvmvm1dx_d.css +0 -2
- package/out/_next/static/chunks/13uu.sohs74zg.js +0 -31
- package/out/_next/static/chunks/turbopack-06pqx~0d8czn_.js +0 -1
- /package/out/_next/static/{91YUiFoMbLQ9sZW4uk45J → Mr9iv4uVZG9o4FJ5IPgRX}/_buildManifest.js +0 -0
- /package/out/_next/static/{91YUiFoMbLQ9sZW4uk45J → Mr9iv4uVZG9o4FJ5IPgRX}/_clientMiddlewareManifest.js +0 -0
- /package/out/_next/static/{91YUiFoMbLQ9sZW4uk45J → Mr9iv4uVZG9o4FJ5IPgRX}/_ssgManifest.js +0 -0
package/bin/quadwork.js
CHANGED
|
@@ -164,46 +164,295 @@ function writeConfig(config) {
|
|
|
164
164
|
|
|
165
165
|
let agentChattrFound = false;
|
|
166
166
|
|
|
167
|
-
function
|
|
167
|
+
function detectPlatform() {
|
|
168
|
+
const p = os.platform();
|
|
169
|
+
if (p === "darwin") return "macos";
|
|
170
|
+
if (p === "linux") {
|
|
171
|
+
// Check for apt vs dnf vs yum
|
|
172
|
+
if (which("apt")) return "linux-apt";
|
|
173
|
+
if (which("dnf")) return "linux-dnf";
|
|
174
|
+
if (which("yum")) return "linux-yum";
|
|
175
|
+
return "linux";
|
|
176
|
+
}
|
|
177
|
+
return "other";
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function tryInstall(rl, name, description, commands, { platform } = {}) {
|
|
181
|
+
const cmd = typeof commands === "function" ? commands(platform) : commands;
|
|
182
|
+
if (!cmd) {
|
|
183
|
+
warn(`${name} cannot be auto-installed on your system.`);
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
console.log("");
|
|
187
|
+
log(`${description}`);
|
|
188
|
+
const doInstall = await askYN(rl, `Install ${name} now?`, true);
|
|
189
|
+
if (!doInstall) {
|
|
190
|
+
log("Skipped.");
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
const sp = spinner(`Installing ${name}...`);
|
|
194
|
+
const result = run(`${cmd} 2>&1`, { timeout: 120000 });
|
|
195
|
+
if (result !== null) {
|
|
196
|
+
sp.stop(true);
|
|
197
|
+
return true;
|
|
198
|
+
} else {
|
|
199
|
+
sp.stop(false);
|
|
200
|
+
warn(`Auto-install failed. You can install manually and try again.`);
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async function checkPrereqs(rl) {
|
|
168
206
|
header("Step 1: Prerequisites");
|
|
207
|
+
const platform = detectPlatform();
|
|
169
208
|
let allOk = true;
|
|
209
|
+
let hasPython = false;
|
|
210
|
+
let hasPipx = false;
|
|
170
211
|
|
|
171
|
-
// Node.js 20+
|
|
212
|
+
// ── 1. Node.js 20+ (must already exist — user ran npx) ──
|
|
172
213
|
const nodeVer = run("node --version");
|
|
173
214
|
if (nodeVer) {
|
|
174
215
|
const major = parseInt(nodeVer.replace("v", "").split(".")[0], 10);
|
|
175
|
-
if (major >= 20)
|
|
176
|
-
|
|
177
|
-
|
|
216
|
+
if (major >= 20) {
|
|
217
|
+
ok(`Node.js ${nodeVer}`);
|
|
218
|
+
} else {
|
|
219
|
+
fail(`Node.js ${nodeVer} — version 20 or newer is required`);
|
|
220
|
+
log("Update from: https://nodejs.org");
|
|
221
|
+
allOk = false;
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
fail("Node.js not found (this shouldn't happen since you ran npx)");
|
|
225
|
+
allOk = false;
|
|
226
|
+
}
|
|
178
227
|
|
|
179
|
-
// Python 3.10+
|
|
228
|
+
// ── 2. Python 3.10+ (manual install — guide only) ──
|
|
180
229
|
const pyVer = run("python3 --version");
|
|
181
230
|
if (pyVer) {
|
|
182
231
|
const parts = pyVer.replace("Python ", "").split(".");
|
|
183
232
|
const minor = parseInt(parts[1], 10);
|
|
184
|
-
if (parseInt(parts[0], 10) >= 3 && minor >= 10)
|
|
185
|
-
|
|
186
|
-
|
|
233
|
+
if (parseInt(parts[0], 10) >= 3 && minor >= 10) {
|
|
234
|
+
ok(`${pyVer}`);
|
|
235
|
+
hasPython = true;
|
|
236
|
+
} else {
|
|
237
|
+
console.log("");
|
|
238
|
+
warn(`${pyVer} found, but version 3.10 or newer is required.`);
|
|
239
|
+
log("Python powers the agent communication layer.");
|
|
240
|
+
log("Download the latest version from:");
|
|
241
|
+
log(` → https://python.org/downloads`);
|
|
242
|
+
log("");
|
|
243
|
+
log("After installing, close and reopen your terminal, then run:");
|
|
244
|
+
log(" → npx quadwork init");
|
|
245
|
+
allOk = false;
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
console.log("");
|
|
249
|
+
warn("Python 3 is required but not installed on your system.");
|
|
250
|
+
log("");
|
|
251
|
+
log("Python powers the agent communication layer. Install it from:");
|
|
252
|
+
log(" → https://python.org/downloads (download and run the installer)");
|
|
253
|
+
log("");
|
|
254
|
+
log("After installing, close and reopen your terminal, then run:");
|
|
255
|
+
log(" → npx quadwork init");
|
|
256
|
+
allOk = false;
|
|
257
|
+
}
|
|
187
258
|
|
|
188
|
-
|
|
259
|
+
if (!hasPython) {
|
|
260
|
+
// Can't continue with pipx/AgentChattr without Python
|
|
261
|
+
console.log("");
|
|
262
|
+
fail("Python is required before we can set up the remaining tools.");
|
|
263
|
+
log("Install Python first, then re-run: npx quadwork init");
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ── 3. pipx (needs Python) ──
|
|
268
|
+
if (which("pipx")) {
|
|
269
|
+
ok("pipx");
|
|
270
|
+
hasPipx = true;
|
|
271
|
+
} else {
|
|
272
|
+
console.log("");
|
|
273
|
+
warn("pipx is needed to install AgentChattr safely.");
|
|
274
|
+
log("(pipx keeps Python tools isolated so they don't conflict with your system)");
|
|
275
|
+
const installed = await tryInstall(rl, "pipx", "We can install it automatically.",
|
|
276
|
+
"python3 -m pip install --user pipx && python3 -m pipx ensurepath");
|
|
277
|
+
if (installed && which("pipx")) {
|
|
278
|
+
ok("pipx installed");
|
|
279
|
+
hasPipx = true;
|
|
280
|
+
} else if (installed) {
|
|
281
|
+
// pipx installed but not in PATH yet
|
|
282
|
+
warn("pipx was installed but isn't in your PATH yet.");
|
|
283
|
+
log("Close and reopen your terminal, then run: npx quadwork init");
|
|
284
|
+
return false;
|
|
285
|
+
} else {
|
|
286
|
+
warn("pipx skipped — you can install it later:");
|
|
287
|
+
log(" → python3 -m pip install --user pipx && pipx ensurepath");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ── 4. AgentChattr (needs pipx) ──
|
|
189
292
|
const acVer = run("agentchattr --version") || run("python3 -m agentchattr --version");
|
|
190
|
-
if (acVer) {
|
|
191
|
-
|
|
293
|
+
if (acVer) {
|
|
294
|
+
ok(`AgentChattr ${acVer}`);
|
|
295
|
+
agentChattrFound = true;
|
|
296
|
+
} else if (hasPipx) {
|
|
297
|
+
console.log("");
|
|
298
|
+
warn("AgentChattr lets your AI agents communicate with each other.");
|
|
299
|
+
const installed = await tryInstall(rl, "AgentChattr",
|
|
300
|
+
"We can install it now using pipx.", "pipx install agentchattr");
|
|
301
|
+
const acVerAfter = run("agentchattr --version") || run("python3 -m agentchattr --version");
|
|
302
|
+
if (acVerAfter) {
|
|
303
|
+
ok(`AgentChattr ${acVerAfter} installed`);
|
|
304
|
+
agentChattrFound = true;
|
|
305
|
+
} else {
|
|
306
|
+
warn("AgentChattr not available — agents won't be able to chat until it's installed.");
|
|
307
|
+
log(" → Install later: pipx install agentchattr");
|
|
308
|
+
allOk = false;
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
warn("AgentChattr not found — install pipx first, then: pipx install agentchattr");
|
|
312
|
+
allOk = false;
|
|
313
|
+
}
|
|
192
314
|
|
|
193
|
-
//
|
|
194
|
-
if (which("gh"))
|
|
195
|
-
|
|
315
|
+
// ── 5. GitHub CLI (independent) ──
|
|
316
|
+
if (which("gh")) {
|
|
317
|
+
ok("GitHub CLI (gh)");
|
|
318
|
+
} else {
|
|
319
|
+
console.log("");
|
|
320
|
+
warn("GitHub CLI is required for agents to create branches, PRs, and reviews.");
|
|
321
|
+
const ghCmd = (p) => {
|
|
322
|
+
if (p === "macos") return "brew install gh";
|
|
323
|
+
if (p === "linux-apt") return "sudo apt install gh -y";
|
|
324
|
+
if (p === "linux-dnf") return "sudo dnf install gh -y";
|
|
325
|
+
return null;
|
|
326
|
+
};
|
|
327
|
+
const cmd = ghCmd(platform);
|
|
328
|
+
if (cmd) {
|
|
329
|
+
const installed = await tryInstall(rl, "GitHub CLI",
|
|
330
|
+
"We can install it now.", ghCmd, { platform });
|
|
331
|
+
if (installed && which("gh")) {
|
|
332
|
+
ok("GitHub CLI installed");
|
|
333
|
+
} else {
|
|
334
|
+
fail("GitHub CLI is required. Install from: https://cli.github.com");
|
|
335
|
+
allOk = false;
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
338
|
+
fail("GitHub CLI is required. Install from: https://cli.github.com");
|
|
339
|
+
allOk = false;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// ── 6. AI CLIs — at least one required (independent) ──
|
|
344
|
+
let hasClaude = which("claude");
|
|
345
|
+
let hasCodex = which("codex");
|
|
196
346
|
|
|
197
|
-
// Claude Code or Codex
|
|
198
|
-
const hasClaude = which("claude");
|
|
199
|
-
const hasCodex = which("codex");
|
|
200
347
|
if (hasClaude) ok("Claude Code");
|
|
201
348
|
if (hasCodex) ok("Codex CLI");
|
|
349
|
+
|
|
202
350
|
if (!hasClaude && !hasCodex) {
|
|
203
|
-
|
|
351
|
+
console.log("");
|
|
352
|
+
warn("You need at least one AI CLI to power your agents.");
|
|
353
|
+
log("Choose one (or both) to install:");
|
|
354
|
+
console.log("");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Offer to install Claude Code if missing
|
|
358
|
+
if (!hasClaude) {
|
|
359
|
+
const isRequired = !hasCodex;
|
|
360
|
+
log("Claude Code — Anthropic's AI coding assistant");
|
|
361
|
+
const installClaude = await askYN(rl, "Install Claude Code?", isRequired);
|
|
362
|
+
if (installClaude) {
|
|
363
|
+
const sp = spinner("Installing Claude Code...");
|
|
364
|
+
const result = run("npm install -g @anthropic-ai/claude-code 2>&1", { timeout: 120000 });
|
|
365
|
+
sp.stop(result !== null);
|
|
366
|
+
hasClaude = which("claude");
|
|
367
|
+
if (hasClaude) ok("Claude Code installed");
|
|
368
|
+
else warn("Install failed — try manually: npm install -g @anthropic-ai/claude-code");
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Offer to install Codex CLI if missing
|
|
373
|
+
if (!hasCodex) {
|
|
374
|
+
const isRequired = !hasClaude;
|
|
375
|
+
if (hasClaude) {
|
|
376
|
+
console.log("");
|
|
377
|
+
log("Tip: Installing Codex CLI too gives your team different AI perspectives.");
|
|
378
|
+
}
|
|
379
|
+
log("Codex CLI — OpenAI's AI coding assistant");
|
|
380
|
+
const installCodex = await askYN(rl, "Install Codex CLI?", isRequired);
|
|
381
|
+
if (installCodex) {
|
|
382
|
+
const sp = spinner("Installing Codex CLI...");
|
|
383
|
+
const result = run("npm install -g codex 2>&1", { timeout: 120000 });
|
|
384
|
+
sp.stop(result !== null);
|
|
385
|
+
hasCodex = which("codex");
|
|
386
|
+
if (hasCodex) ok("Codex CLI installed");
|
|
387
|
+
else warn("Install failed — try manually: npm install -g codex");
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (!hasClaude && !hasCodex) {
|
|
392
|
+
fail("At least one AI CLI is required (Claude Code or Codex CLI).");
|
|
393
|
+
log("Install one and re-run: npx quadwork init");
|
|
204
394
|
allOk = false;
|
|
205
395
|
}
|
|
206
396
|
|
|
397
|
+
// ── CLI Authentication Checks ──
|
|
398
|
+
if (allOk) {
|
|
399
|
+
console.log("");
|
|
400
|
+
log("Checking CLI authentication...");
|
|
401
|
+
console.log("");
|
|
402
|
+
|
|
403
|
+
// GitHub CLI auth
|
|
404
|
+
const ghAuth = run("gh auth status 2>&1");
|
|
405
|
+
if (ghAuth && ghAuth.includes("Logged in")) {
|
|
406
|
+
ok("GitHub CLI — authenticated");
|
|
407
|
+
} else {
|
|
408
|
+
warn("GitHub CLI is installed but not logged in.");
|
|
409
|
+
log(" Run this command to log in:");
|
|
410
|
+
log(" → gh auth login");
|
|
411
|
+
log("");
|
|
412
|
+
const recheck = await askYN(rl, "Done? Press Y to re-check, or N to continue anyway", false);
|
|
413
|
+
if (recheck) {
|
|
414
|
+
const ghAuth2 = run("gh auth status 2>&1");
|
|
415
|
+
if (ghAuth2 && ghAuth2.includes("Logged in")) {
|
|
416
|
+
ok("GitHub CLI — authenticated");
|
|
417
|
+
} else {
|
|
418
|
+
warn("Still not authenticated — you can set this up later.");
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Claude Code auth
|
|
424
|
+
if (hasClaude) {
|
|
425
|
+
const claudeAuth = run("claude auth status 2>&1") || run("claude --version 2>&1");
|
|
426
|
+
if (claudeAuth && (claudeAuth.includes("authenticated") || claudeAuth.includes("Logged in") || claudeAuth.includes("@"))) {
|
|
427
|
+
ok("Claude Code — authenticated");
|
|
428
|
+
} else {
|
|
429
|
+
warn("Claude Code may need authentication.");
|
|
430
|
+
log(" If prompted when agents start, run: claude auth login");
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Codex CLI auth
|
|
435
|
+
if (hasCodex) {
|
|
436
|
+
const codexAuth = run("codex auth status 2>&1") || run("codex --version 2>&1");
|
|
437
|
+
if (codexAuth && (codexAuth.includes("authenticated") || codexAuth.includes("Logged in") || codexAuth.includes("@"))) {
|
|
438
|
+
ok("Codex CLI — authenticated");
|
|
439
|
+
} else {
|
|
440
|
+
warn("Codex CLI may need authentication.");
|
|
441
|
+
log(" If prompted when agents start, run: codex auth");
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// ── Summary ──
|
|
447
|
+
console.log("");
|
|
448
|
+
if (allOk) {
|
|
449
|
+
ok("All prerequisites ready!");
|
|
450
|
+
} else {
|
|
451
|
+
console.log("");
|
|
452
|
+
log("Some prerequisites are missing. Fix the issues above and re-run:");
|
|
453
|
+
log(" → npx quadwork init");
|
|
454
|
+
}
|
|
455
|
+
|
|
207
456
|
return allOk;
|
|
208
457
|
}
|
|
209
458
|
|
|
@@ -247,28 +496,52 @@ async function setupGitHub(rl) {
|
|
|
247
496
|
async function setupAgents(rl, repo) {
|
|
248
497
|
header("Step 3: Agent Configuration");
|
|
249
498
|
|
|
250
|
-
//
|
|
499
|
+
// Detect available CLIs
|
|
251
500
|
const hasClaude = which("claude");
|
|
252
501
|
const hasCodex = which("codex");
|
|
502
|
+
const bothAvailable = hasClaude && hasCodex;
|
|
503
|
+
const onlyOneCli = (hasClaude && !hasCodex) || (!hasClaude && hasCodex);
|
|
253
504
|
let defaultBackend = hasClaude ? "claude" : "codex";
|
|
254
|
-
log("Choose which AI CLI to run in agent terminals. Claude Code (`claude`) or OpenAI Codex (`codex`).");
|
|
255
|
-
const backend = await ask(rl, "Default CLI backend (claude/codex)", defaultBackend);
|
|
256
|
-
if (backend !== "claude" && backend !== "codex") {
|
|
257
|
-
fail("Backend must be 'claude' or 'codex'");
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
505
|
|
|
261
|
-
// Per-agent backend selection
|
|
262
506
|
const backends = {};
|
|
263
|
-
|
|
264
|
-
if (
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
507
|
+
|
|
508
|
+
if (onlyOneCli) {
|
|
509
|
+
// Single-CLI mode: default all agents, no prompt needed
|
|
510
|
+
const cliName = hasClaude ? "Claude Code" : "Codex CLI";
|
|
511
|
+
const otherName = hasClaude ? "Codex CLI" : "Claude Code";
|
|
512
|
+
const installCmd = hasClaude ? "npm install -g codex" : "npm install -g @anthropic-ai/claude-code";
|
|
513
|
+
ok(`${cliName} detected — all 4 agents will use ${cliName}.`);
|
|
514
|
+
console.log("");
|
|
515
|
+
log(`Tip: Installing ${otherName} too gives your team different AI perspectives,`);
|
|
516
|
+
log(`which can improve code review quality. You can add it anytime:`);
|
|
517
|
+
log(` → ${installCmd}`);
|
|
518
|
+
console.log("");
|
|
519
|
+
for (const agent of AGENTS) backends[agent] = defaultBackend;
|
|
520
|
+
} else if (bothAvailable) {
|
|
521
|
+
log("Both Claude Code and Codex CLI are available.");
|
|
522
|
+
log("Choose which AI CLI to run in agent terminals.");
|
|
523
|
+
const backend = await ask(rl, "Default CLI backend (claude/codex)", defaultBackend);
|
|
524
|
+
if (backend !== "claude" && backend !== "codex") {
|
|
525
|
+
fail("Backend must be 'claude' or 'codex'");
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
defaultBackend = backend;
|
|
529
|
+
|
|
530
|
+
// Per-agent backend selection
|
|
531
|
+
const customPerAgent = await askYN(rl, "Use same backend for all agents?", true);
|
|
532
|
+
if (customPerAgent) {
|
|
533
|
+
for (const agent of AGENTS) backends[agent] = backend;
|
|
534
|
+
} else {
|
|
535
|
+
for (const agent of AGENTS) {
|
|
536
|
+
const agentBackend = await ask(rl, `${agent.toUpperCase()} backend (claude/codex)`, backend);
|
|
537
|
+
backends[agent] = (agentBackend === "claude" || agentBackend === "codex") ? agentBackend : backend;
|
|
538
|
+
}
|
|
270
539
|
}
|
|
540
|
+
} else {
|
|
541
|
+
fail("No AI CLI found — install Claude Code or Codex CLI first.");
|
|
542
|
+
return null;
|
|
271
543
|
}
|
|
544
|
+
const backend = defaultBackend;
|
|
272
545
|
|
|
273
546
|
log("Path to your local clone of the repo. Four worktrees will be created next to it");
|
|
274
547
|
log("(e.g., project-head/, project-reviewer1/, project-reviewer2/, project-dev/).");
|
|
@@ -411,14 +684,14 @@ function writeAgentChattrConfig(setup, configTomlPath, { skipInstall = false } =
|
|
|
411
684
|
let acAvailable = which("agentchattr");
|
|
412
685
|
if (!acAvailable && !skipInstall) {
|
|
413
686
|
const acSpinner = spinner("Installing AgentChattr...");
|
|
414
|
-
const installResult = run("
|
|
687
|
+
const installResult = run("pipx install agentchattr 2>&1");
|
|
415
688
|
if (installResult !== null) {
|
|
416
689
|
acSpinner.stop(true);
|
|
417
690
|
acAvailable = which("agentchattr");
|
|
418
691
|
if (!acAvailable) warn("agentchattr binary not found in PATH after install");
|
|
419
692
|
} else {
|
|
420
693
|
acSpinner.stop(false);
|
|
421
|
-
warn("Install manually:
|
|
694
|
+
warn("Install manually: pipx install agentchattr");
|
|
422
695
|
}
|
|
423
696
|
}
|
|
424
697
|
|
|
@@ -670,29 +943,27 @@ async function cmdInit() {
|
|
|
670
943
|
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.white}${c.bold}QuadWork Init${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
671
944
|
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.dim}Global setup — projects via web UI${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
672
945
|
console.log(` ${c.cyan}${c.bold}╚══════════════════════════════════════════╝${c.reset}`);
|
|
673
|
-
console.log(`\n ${c.dim}
|
|
946
|
+
console.log(`\n ${c.dim}Press Enter to accept defaults. Takes under 30 seconds.${c.reset}\n`);
|
|
674
947
|
|
|
675
948
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
676
949
|
|
|
677
950
|
try {
|
|
678
|
-
// Step 1: Prerequisites
|
|
679
|
-
|
|
680
|
-
const prereqsOk = checkPrereqs();
|
|
951
|
+
// Step 1: Prerequisites (header printed by checkPrereqs)
|
|
952
|
+
const prereqsOk = await checkPrereqs(rl);
|
|
681
953
|
if (!prereqsOk) {
|
|
682
|
-
|
|
683
|
-
|
|
954
|
+
console.log("");
|
|
955
|
+
log("Once everything is installed, re-run: npx quadwork init");
|
|
956
|
+
rl.close();
|
|
957
|
+
process.exit(1);
|
|
684
958
|
}
|
|
685
959
|
|
|
686
|
-
// Step 2:
|
|
687
|
-
header("Step 2:
|
|
688
|
-
const port = await ask(rl, "
|
|
689
|
-
const defaultBackend = which("claude") ? "claude" : which("codex") ? "codex" : "claude";
|
|
690
|
-
const backend = await ask(rl, "Default CLI backend (claude/codex)", defaultBackend);
|
|
960
|
+
// Step 2: Dashboard port
|
|
961
|
+
header("Step 2: Dashboard Port");
|
|
962
|
+
const port = await ask(rl, "Port for the QuadWork dashboard (Enter for default)", "8400");
|
|
691
963
|
|
|
692
964
|
// Write global config
|
|
693
965
|
const config = readConfig();
|
|
694
966
|
config.port = parseInt(port, 10) || 8400;
|
|
695
|
-
config.default_backend = backend;
|
|
696
967
|
writeConfig(config);
|
|
697
968
|
ok(`Wrote ${CONFIG_PATH}`);
|
|
698
969
|
|
|
@@ -700,6 +971,7 @@ async function cmdInit() {
|
|
|
700
971
|
header("Step 3: Starting Dashboard");
|
|
701
972
|
const quadworkDir = path.join(__dirname, "..");
|
|
702
973
|
const serverDir = path.join(quadworkDir, "server");
|
|
974
|
+
let serverPid = null;
|
|
703
975
|
if (fs.existsSync(path.join(serverDir, "index.js"))) {
|
|
704
976
|
const server = spawn("node", [serverDir], {
|
|
705
977
|
stdio: "ignore",
|
|
@@ -708,28 +980,59 @@ async function cmdInit() {
|
|
|
708
980
|
});
|
|
709
981
|
server.unref();
|
|
710
982
|
if (server.pid) {
|
|
711
|
-
|
|
983
|
+
serverPid = server.pid;
|
|
984
|
+
ok(`Server started (PID: ${serverPid})`);
|
|
712
985
|
const pidFile = path.join(CONFIG_DIR, "server.pid");
|
|
713
986
|
if (!fs.existsSync(CONFIG_DIR)) fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
714
|
-
fs.writeFileSync(pidFile, String(
|
|
987
|
+
fs.writeFileSync(pidFile, String(serverPid));
|
|
715
988
|
}
|
|
716
989
|
} else {
|
|
717
990
|
warn("Server not found — run from the quadwork directory");
|
|
718
991
|
}
|
|
719
992
|
|
|
720
|
-
// Done
|
|
993
|
+
// Done — celebratory welcome
|
|
721
994
|
const dashPort = parseInt(port, 10) || 8400;
|
|
722
995
|
const dashboardUrl = `http://127.0.0.1:${dashPort}`;
|
|
723
996
|
|
|
724
|
-
|
|
725
|
-
log(`
|
|
726
|
-
log(`
|
|
727
|
-
log(`
|
|
728
|
-
log(
|
|
729
|
-
log(
|
|
730
|
-
log(`
|
|
731
|
-
log(
|
|
732
|
-
log(
|
|
997
|
+
console.log("");
|
|
998
|
+
console.log(` ${c.cyan}${c.bold}╔══════════════════════════════════════════════════════════╗${c.reset}`);
|
|
999
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1000
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.green}${c.bold}Welcome to QuadWork!${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1001
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1002
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} Your AI-powered dev team is ready to ship. ${c.cyan}${c.bold}║${c.reset}`);
|
|
1003
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1004
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.green}*${c.reset} ${c.bold}Head${c.reset} ${c.dim}— coordinates & merges${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1005
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.green}*${c.reset} ${c.bold}Dev${c.reset} ${c.dim}— writes all the code${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1006
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.green}*${c.reset} ${c.bold}Reviewer1${c.reset} ${c.dim}— independent code review${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1007
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.green}*${c.reset} ${c.bold}Reviewer2${c.reset} ${c.dim}— independent code review${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1008
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1009
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} 4 agents. Full GitHub workflow. Runs while you sleep. ${c.cyan}${c.bold}║${c.reset}`);
|
|
1010
|
+
console.log(` ${c.cyan}${c.bold}║${c.reset} ${c.cyan}${c.bold}║${c.reset}`);
|
|
1011
|
+
console.log(` ${c.cyan}${c.bold}╚══════════════════════════════════════════════════════════╝${c.reset}`);
|
|
1012
|
+
console.log("");
|
|
1013
|
+
if (serverPid) {
|
|
1014
|
+
console.log(` ${c.green}*${c.reset} Server running at ${c.cyan}${dashboardUrl}${c.reset} ${c.dim}(PID: ${serverPid})${c.reset}`);
|
|
1015
|
+
} else {
|
|
1016
|
+
console.log(` ${c.yellow}*${c.reset} Server not started — run ${c.dim}npx quadwork start${c.reset} to launch`);
|
|
1017
|
+
}
|
|
1018
|
+
console.log(` ${c.green}*${c.reset} Config saved to ${c.dim}${CONFIG_PATH}${c.reset}`);
|
|
1019
|
+
console.log("");
|
|
1020
|
+
console.log(` ${c.cyan}${c.bold}--- Create Your First Project ---${c.reset}`);
|
|
1021
|
+
console.log("");
|
|
1022
|
+
console.log(` Your browser is opening now. If not, visit:`);
|
|
1023
|
+
console.log("");
|
|
1024
|
+
console.log(` ${c.cyan}${c.bold}${dashboardUrl}/setup${c.reset}`);
|
|
1025
|
+
console.log("");
|
|
1026
|
+
console.log(` ${c.dim}1.${c.reset} Connect a GitHub repo`);
|
|
1027
|
+
console.log(` ${c.dim}2.${c.reset} Pick models for each agent`);
|
|
1028
|
+
console.log(` ${c.dim}3.${c.reset} Hit Start — your team takes it from there`);
|
|
1029
|
+
console.log("");
|
|
1030
|
+
console.log(` ${c.dim}Commands:${c.reset}`);
|
|
1031
|
+
console.log(` ${c.dim}npx quadwork start${c.reset} — restart everything`);
|
|
1032
|
+
console.log(` ${c.dim}npx quadwork stop${c.reset} — shut it all down`);
|
|
1033
|
+
console.log("");
|
|
1034
|
+
console.log(` ${c.green}${c.bold}Happy shipping!${c.reset}`);
|
|
1035
|
+
console.log("");
|
|
733
1036
|
|
|
734
1037
|
// Open browser
|
|
735
1038
|
const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
@@ -850,6 +1153,19 @@ function cmdStop() {
|
|
|
850
1153
|
|
|
851
1154
|
if (stopPid("Server", "server.pid")) stopped++;
|
|
852
1155
|
|
|
1156
|
+
// Stop caffeinate via the running server's API (targets only QuadWork's instance)
|
|
1157
|
+
if (process.platform === "darwin") {
|
|
1158
|
+
const cfg = readConfig();
|
|
1159
|
+
const qwPort = cfg.port || 8400;
|
|
1160
|
+
try {
|
|
1161
|
+
const result = run(`curl -s -X POST http://127.0.0.1:${qwPort}/api/caffeinate/stop 2>/dev/null`);
|
|
1162
|
+
if (result && result.includes('"ok":true')) {
|
|
1163
|
+
ok("Stopped caffeinate (sleep prevention)");
|
|
1164
|
+
stopped++;
|
|
1165
|
+
}
|
|
1166
|
+
} catch {}
|
|
1167
|
+
}
|
|
1168
|
+
|
|
853
1169
|
if (stopped === 0) warn("No running processes found");
|
|
854
1170
|
else ok(`Stopped ${stopped} process(es)`);
|
|
855
1171
|
log("");
|
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/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,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";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>
|
|
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/0s8jbc4nxw6y6.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/0z~0.4hivi.f2.js"/><script src="/_next/static/chunks/0ezniz80psxr6.js" async=""></script><script src="/_next/static/chunks/0r7t_sj_sejq9.js" async=""></script><script src="/_next/static/chunks/0io_y3d0p5v~b.js" async=""></script><script src="/_next/static/chunks/0excsn2a_5qsb.js" async=""></script><script src="/_next/static/chunks/turbopack-0sammtvunroor.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,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";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/0z~0.4hivi.f2.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/0s8jbc4nxw6y6.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/0s8jbc4nxw6y6.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/0s8jbc4nxw6y6.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"Mr9iv4uVZG9o4FJ5IPgRX\"}\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>
|
package/out/__next.__PAGE__.txt
CHANGED
|
@@ -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":"
|
|
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":"Mr9iv4uVZG9o4FJ5IPgRX"}
|
|
6
6
|
5:null
|