quadwork 1.3.0 → 1.5.0

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 (93) hide show
  1. package/README.md +189 -82
  2. package/bin/quadwork.js +82 -0
  3. package/out/404.html +1 -1
  4. package/out/__next.__PAGE__.txt +3 -3
  5. package/out/__next._full.txt +12 -12
  6. package/out/__next._head.txt +4 -4
  7. package/out/__next._index.txt +6 -6
  8. package/out/__next._tree.txt +2 -2
  9. package/out/_next/static/chunks/{134b1p_egmf1c.js → 0-y13tz~pmpno.js} +1 -1
  10. package/out/_next/static/chunks/{0swlbn4q4u71z.js → 0.9m84as-sc_r.js} +14 -14
  11. package/out/_next/static/chunks/05.po0c1knrbu.css +2 -0
  12. package/out/_next/static/chunks/084lff9v4p_vh.js +1 -0
  13. package/out/_next/static/chunks/{0md7hgvwnovzq.js → 0e.ktwt1nyj...js} +1 -1
  14. package/out/_next/static/chunks/{0e~ue9ca5zrep.js → 0za4cvk8.n0-y.js} +1 -1
  15. package/out/_next/static/chunks/17y2walb2um9w.js +1 -0
  16. package/out/_not-found/__next._full.txt +11 -11
  17. package/out/_not-found/__next._head.txt +4 -4
  18. package/out/_not-found/__next._index.txt +6 -6
  19. package/out/_not-found/__next._not-found.__PAGE__.txt +2 -2
  20. package/out/_not-found/__next._not-found.txt +3 -3
  21. package/out/_not-found/__next._tree.txt +2 -2
  22. package/out/_not-found.html +1 -1
  23. package/out/_not-found.txt +11 -11
  24. package/out/app-shell/__next._full.txt +11 -11
  25. package/out/app-shell/__next._head.txt +4 -4
  26. package/out/app-shell/__next._index.txt +6 -6
  27. package/out/app-shell/__next._tree.txt +2 -2
  28. package/out/app-shell/__next.app-shell.__PAGE__.txt +2 -2
  29. package/out/app-shell/__next.app-shell.txt +3 -3
  30. package/out/app-shell.html +1 -1
  31. package/out/app-shell.txt +11 -11
  32. package/out/index.html +1 -1
  33. package/out/index.txt +12 -12
  34. package/out/project/_/__next._full.txt +12 -12
  35. package/out/project/_/__next._head.txt +4 -4
  36. package/out/project/_/__next._index.txt +6 -6
  37. package/out/project/_/__next._tree.txt +2 -2
  38. package/out/project/_/__next.project.$d$id.__PAGE__.txt +3 -3
  39. package/out/project/_/__next.project.$d$id.txt +3 -3
  40. package/out/project/_/__next.project.txt +3 -3
  41. package/out/project/_/memory/__next._full.txt +12 -12
  42. package/out/project/_/memory/__next._head.txt +4 -4
  43. package/out/project/_/memory/__next._index.txt +6 -6
  44. package/out/project/_/memory/__next._tree.txt +2 -2
  45. package/out/project/_/memory/__next.project.$d$id.memory.__PAGE__.txt +3 -3
  46. package/out/project/_/memory/__next.project.$d$id.memory.txt +3 -3
  47. package/out/project/_/memory/__next.project.$d$id.txt +3 -3
  48. package/out/project/_/memory/__next.project.txt +3 -3
  49. package/out/project/_/memory.html +1 -1
  50. package/out/project/_/memory.txt +12 -12
  51. package/out/project/_/queue/__next._full.txt +12 -12
  52. package/out/project/_/queue/__next._head.txt +4 -4
  53. package/out/project/_/queue/__next._index.txt +6 -6
  54. package/out/project/_/queue/__next._tree.txt +2 -2
  55. package/out/project/_/queue/__next.project.$d$id.queue.__PAGE__.txt +3 -3
  56. package/out/project/_/queue/__next.project.$d$id.queue.txt +3 -3
  57. package/out/project/_/queue/__next.project.$d$id.txt +3 -3
  58. package/out/project/_/queue/__next.project.txt +3 -3
  59. package/out/project/_/queue.html +1 -1
  60. package/out/project/_/queue.txt +12 -12
  61. package/out/project/_.html +1 -1
  62. package/out/project/_.txt +12 -12
  63. package/out/settings/__next._full.txt +12 -12
  64. package/out/settings/__next._head.txt +4 -4
  65. package/out/settings/__next._index.txt +6 -6
  66. package/out/settings/__next._tree.txt +2 -2
  67. package/out/settings/__next.settings.__PAGE__.txt +3 -3
  68. package/out/settings/__next.settings.txt +3 -3
  69. package/out/settings.html +1 -1
  70. package/out/settings.txt +12 -12
  71. package/out/setup/__next._full.txt +12 -12
  72. package/out/setup/__next._head.txt +4 -4
  73. package/out/setup/__next._index.txt +6 -6
  74. package/out/setup/__next._tree.txt +2 -2
  75. package/out/setup/__next.setup.__PAGE__.txt +3 -3
  76. package/out/setup/__next.setup.txt +3 -3
  77. package/out/setup.html +1 -1
  78. package/out/setup.txt +12 -12
  79. package/package.json +5 -2
  80. package/server/index.js +274 -12
  81. package/server/queue-watcher.js +47 -10
  82. package/server/queue-watcher.test.js +64 -0
  83. package/server/routes.batchProgress.test.js +94 -0
  84. package/server/routes.js +752 -33
  85. package/server/routes.parseActiveBatch.test.js +88 -0
  86. package/server/routes.telegramBridge.test.js +70 -0
  87. package/templates/CLAUDE.md +0 -1
  88. package/out/_next/static/chunks/06mbme.sc_26-.css +0 -2
  89. package/out/_next/static/chunks/0caq73v0knw_w.js +0 -1
  90. package/out/_next/static/chunks/0omuxbg.tg-il.js +0 -1
  91. /package/out/_next/static/{na3L7KeOGKGsbamYVibRj → OzDK1Fplm2eUu23bzILlU}/_buildManifest.js +0 -0
  92. /package/out/_next/static/{na3L7KeOGKGsbamYVibRj → OzDK1Fplm2eUu23bzILlU}/_clientMiddlewareManifest.js +0 -0
  93. /package/out/_next/static/{na3L7KeOGKGsbamYVibRj → OzDK1Fplm2eUu23bzILlU}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -1,11 +1,55 @@
1
+ <div align="center">
2
+
1
3
  # QuadWork
2
4
 
3
- Your AI dev team in a box. Four agents — one Head, one Dev, two Reviewers — that code, review, and ship while you sleep.
5
+ ### Your AI dev team while you sleep.
6
+
7
+ <p>
8
+ <a href="#-quick-start"><strong>Quick Start</strong></a> ·
9
+ <a href="#-how-it-works"><strong>How it Works</strong></a> ·
10
+ <a href="#-features"><strong>Features</strong></a> ·
11
+ <a href="#-external-tools"><strong>Credits</strong></a> ·
12
+ <a href="https://github.com/bcurts/agentchattr"><strong>Built on AgentChattr</strong></a>
13
+ </p>
14
+
15
+ <p>
16
+ <a href="https://www.npmjs.com/package/quadwork"><img src="https://img.shields.io/npm/v/quadwork" alt="npm version" /></a>
17
+ <a href="https://www.npmjs.com/package/quadwork"><img src="https://img.shields.io/npm/dm/quadwork" alt="npm downloads" /></a>
18
+ <a href="https://github.com/realproject7/quadwork/releases/latest"><img src="https://img.shields.io/github/v/release/realproject7/quadwork" alt="latest release" /></a>
19
+ <img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey" alt="platform" />
20
+ <img src="https://img.shields.io/badge/runs-locally-00d4aa" alt="runs locally" />
21
+ <img src="https://img.shields.io/badge/agents-4-orange" alt="4 agents" />
22
+ <a href="https://github.com/bcurts/agentchattr"><img src="https://img.shields.io/badge/built_on-AgentChattr-8b5cf6" alt="AgentChattr" /></a>
23
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License" /></a>
24
+ </p>
25
+
26
+ </div>
27
+
28
+ ---
29
+
30
+ ## Why QuadWork?
31
+
32
+ Manually reviewing every AI-generated PR is exhausting. Letting one AI agent
33
+ push straight to `main` is how you end up rolling back broken migrations at
34
+ 2am. QuadWork runs a **four-agent team** that enforces a real GitHub workflow
35
+ on each other — code, review, ship — autonomously, with safety rails.
36
+
37
+ - 🤖 **Runs 24/7** — agents keep working overnight while you rest
38
+ - 🛡️ **Always reviewed** — every PR needs **2 independent approvals** before merge
39
+ - 🔒 **Local-first** — the dashboard, terminals, chat server, and PTY sessions all run on your machine. The agents still make outbound calls to the LLM APIs you've configured (Claude / Codex / Gemini) and to GitHub, and the optional Telegram bridge mirrors chat to your phone. QuadWork itself doesn't host or proxy any of that traffic through a third party
4
40
 
5
- ## Getting Started
41
+ ## Who is QuadWork for?
42
+
43
+ - **Solo founders / indie hackers** who want to ship faster than they can review
44
+ - **Open-source maintainers** who get more PRs than they have hours to look at
45
+ - **Engineers** who want a team workflow without the overhead of hiring
46
+ - **Tinkerers** who've tried Claude Code / Codex and wished they had reviewers who pushed back
47
+
48
+ ## ─ Quick Start
6
49
 
7
50
  1. Install [Node.js 20+](https://nodejs.org) if you don't have it
8
- 2. Install [Homebrew](https://brew.sh) if you're on macOS: `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
51
+ 2. On macOS, install [Homebrew](https://brew.sh):
52
+ `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
9
53
  3. Open your terminal and run:
10
54
 
11
55
  ```bash
@@ -14,11 +58,14 @@ npx quadwork init
14
58
 
15
59
  4. The wizard installs everything else and opens your dashboard.
16
60
 
17
- That's it. The wizard handles Python, GitHub CLI, AI tools, and authentication — you just follow the prompts.
61
+ That's it. The wizard handles Python, GitHub CLI, AI tools, and
62
+ authentication — you just follow the prompts. Subsequent runs are one
63
+ command: `npx quadwork start`.
18
64
 
19
- ## How It Works
65
+ ## How it Works
20
66
 
21
- QuadWork runs a team of 4 AI agents on your local machine:
67
+ QuadWork runs a team of 4 AI agents on your local machine and enforces a
68
+ GitHub-native workflow on them:
22
69
 
23
70
  | Agent | Role | What it does |
24
71
  |-------|------|-------------|
@@ -27,81 +74,104 @@ QuadWork runs a team of 4 AI agents on your local machine:
27
74
  | **Reviewer1** | Reviewer | Independent code review with veto authority |
28
75
  | **Reviewer2** | Reviewer | Independent code review with veto authority |
29
76
 
30
- Every task follows a GitHub workflow: Issue → Branch → PR → 2 Reviews → Merge. Branch protection ensures no agent can skip the process.
31
-
32
- ## Dashboard
33
-
34
- ```
35
- +--------+----------------------------+----------------------------+
36
- | | Head Terminal | GitHub (Issues + PRs) |
37
- | Side- | (Coordinator) | |
38
- | bar +----------------------------+----------------------------+
39
- | | Agent Chat | Reviewer1 | Reviewer2 |
40
- | [Home] | (AgentChattr) | | |
41
- | [Proj] | +-------------+--------------+
42
- | [+] | | Dev Terminal |
43
- | [Set] | | (Builder) |
44
- +--------+----------------------------+----------------------------+
45
- | Keep Alive | Server: Stop Restart Reset | System: Keep Awake |
46
- +--------+----------------------------+----------------------------+
47
- ```
48
-
49
- ## Features
50
-
51
- - **Terminal panels** — Live terminals for each agent with PTY sessions
52
- - **Agent chat** — Real-time agent coordination via AgentChattr
53
- - **GitHub board** — Issues, PRs, and review status at a glance
54
- - **Task queue** — Build and dispatch work queues with one click
55
- - **Keep Alive** — Scheduled check-in messages to keep agents active (with auto-stop duration)
56
- - **Keep Awake** — Prevent your Mac from sleeping during overnight runs
57
- - **Multi-project** — Each project gets its own AgentChattr instance and ports
58
- - **Telegram bridge** — Optional mobile notifications via [agentchattr-telegram](https://github.com/realproject7/agentchattr-telegram)
59
-
60
- ## Commands
61
-
62
- | Command | Description |
63
- |---------|-------------|
64
- | `npx quadwork init` | One-time setup — installs prerequisites and opens the dashboard |
65
- | `npx quadwork start` | Start the dashboard server |
66
- | `npx quadwork stop` | Stop all processes |
67
- | `npx quadwork cleanup --project <id>` | Remove a project's AgentChattr clone and config entry |
68
- | `npx quadwork cleanup --legacy` | Remove the legacy `~/.quadwork/agentchattr/` install after migration |
69
-
70
- After init, create projects from the web UI at `http://127.0.0.1:8400/setup`.
71
-
72
- ### Disk usage
73
-
74
- Each project gets its own AgentChattr clone at `~/.quadwork/{project_id}/agentchattr/` (~77 MB). For example:
75
-
76
- | Projects | Disk |
77
- |---------:|-----:|
78
- | 1 | ~77 MB |
79
- | 5 | ~385 MB |
80
- | 10 | ~770 MB |
81
-
82
- Per-project clones are necessary so multiple projects can run AgentChattr simultaneously without port conflicts (each clone has its own `config.toml`, ports, and data directory).
77
+ Every task follows the same cycle: **Issue → Branch → PR → 2 Reviews → Merge**.
78
+ Branch protection ensures no agent can skip the process.
83
79
 
84
- To free space, delete unused projects from the dashboard or run:
80
+ ### The full autonomous loop
85
81
 
86
- ```sh
87
- npx quadwork cleanup --project <id>
88
82
  ```
89
-
90
- Existing v1 users are auto-migrated to per-project clones on the next `npx quadwork start`. After all projects are migrated, the legacy shared install can be removed with:
91
-
92
- ```sh
93
- npx quadwork cleanup --legacy
83
+ You: "@head start a batch for feature X"
84
+
85
+
86
+ Head: creates issues + queue, asks you to kick off the batch
87
+
88
+ ▼ (you click "Start Trigger" in the Operator panel)
89
+ Head: assigns the first issue to Dev
90
+
91
+
92
+ Dev: opens a PR with code
93
+
94
+
95
+ Reviewer1 + Reviewer2: independent reviews
96
+
97
+ ▼ (both approve)
98
+ Head: merges, picks the next issue
99
+
100
+ └──── repeat overnight ────┐
101
+
102
+
103
+ You wake up to merged PRs
94
104
  ```
95
105
 
96
- `cleanup --legacy` refuses to run unless every project already has its own working per-project clone, so it can never strand a project on a missing install.
97
-
98
- ## Configuration
99
-
100
- Config is stored at `~/.quadwork/config.json`:
106
+ ### A concrete example
107
+
108
+ 1. You drop a batch of 5 related tickets into chat: `@head start 5 sub-tickets under #123`.
109
+ 2. Head files the 5 issues on GitHub, writes them to `OVERNIGHT-QUEUE.md`, and asks you to click **Start Trigger**.
110
+ 3. You click it, close the laptop, and sleep.
111
+ 4. The Scheduled Trigger pulses the agents every 15 minutes. Each pulse, Head assigns the next queued issue to Dev.
112
+ 5. Dev opens a PR. Reviewer1 + Reviewer2 each review independently — approve, request changes, or veto. Dev iterates until both approve.
113
+ 6. Head merges and picks the next ticket. Loop until the queue is empty or the duration expires.
114
+ 7. You wake up to 5 merged PRs, a clean queue, and a chat transcript you can scroll.
115
+
116
+ ## ─ Features
117
+
118
+ ### Dashboard
119
+
120
+ - 📺 **4-quadrant project view** — chat, agent terminals (HEAD / DEV / RE1 / RE2), GitHub board, operator panel
121
+ - ⏰ **Scheduled Trigger** — recurring "queue check" pulses for autonomous overnight runs
122
+ - 📲 **Telegram bridge** — mirror the chat to your phone for remote monitoring
123
+ - 💾 **Project history export/import** — JSON snapshots of the full chat transcript
124
+ - 🧯 **Loop Guard control** — raise the hop limit and auto-resume stuck chains without restarting AC
125
+ - 🔔 **Notification sounds** — Web Audio chime on new agent messages with a background-only mode
126
+ - 🎞️ **Current Batch Progress panel** — per-issue progress bars computed from live GitHub state
127
+ - 🗂️ **Recently closed / merged feed** — so finished work doesn't disappear from the GitHub panel
128
+ - 💤 **Keep Mac Awake** — `caffeinate` wrapper so your laptop survives the night
129
+
130
+ ### Workflow
131
+
132
+ - 🧭 **Multi-project support** — each project has its own AgentChattr instance + isolated worktrees
133
+ - 📝 **Per-project `OVERNIGHT-QUEUE.md`** with auto-incrementing batch numbers
134
+ - 💬 **Slash commands** — `/continue`, `/clear`, `/summary`, `/poetry`, `/roastreview`
135
+ - 🏷️ **Chat polish** — threaded replies, colored `@mentions`, short reviewer labels (RE1/RE2)
136
+ - 🧰 **Operator identity** — set your chat display name in Settings
137
+
138
+ ### Safety
139
+
140
+ - 🚧 **GitHub branch protection** enforced on `main`
141
+ - ✅ **2-of-2 reviewer approval** required before merge
142
+ - 🛑 **Sender lockdown** — chat POSTs can't impersonate an agent (`head`, `dev`, …) from the UI
143
+ - 🗄️ **Auto-snapshot** of chat history to `~/.quadwork/{project}/history-snapshots/` before every AgentChattr restart, with an in-dashboard **Restore** button and an optional auto-restore-on-restart opt-in
144
+
145
+ ## ─ External Tools
146
+
147
+ QuadWork stands on top of some great open-source work. Explicit thanks:
148
+
149
+ - **[AgentChattr](https://github.com/bcurts/agentchattr)** — by [@bcurts](https://github.com/bcurts).
150
+ The local chat server + MCP tooling that lets QuadWork's agents talk to
151
+ each other. **QuadWork would not exist without it** — huge thanks to
152
+ bcurts for building such a clean foundation.
153
+ - **[GitHub CLI (`gh`)](https://cli.github.com)** — used by all four agents
154
+ for issues, PRs, reviews, and merges.
155
+ - **[Claude Code](https://github.com/anthropics/claude-code)** — Anthropic's
156
+ CLI. Recommended for the Dev / Reviewer2 roles.
157
+ - **[Codex CLI](https://github.com/openai/codex)** — OpenAI's CLI.
158
+ Recommended for the Head / Reviewer1 roles.
159
+ - **[Next.js](https://nextjs.org)** + **[Express](https://expressjs.com)** —
160
+ dashboard frontend + backend.
161
+ - **[node-pty](https://github.com/microsoft/node-pty)** — embeds the agent
162
+ terminals.
163
+ - **[xterm.js](https://xtermjs.org)** — in-browser terminal rendering.
164
+
165
+ ## ─ Configuration
166
+
167
+ Global config lives at `~/.quadwork/config.json`. Per-project AgentChattr
168
+ config lives at `~/.quadwork/{project_id}/agentchattr/config.toml`. The per-
169
+ project queue lives at `~/.quadwork/{project_id}/OVERNIGHT-QUEUE.md`.
101
170
 
102
171
  ```json
103
172
  {
104
173
  "port": 8400,
174
+ "operator_name": "user",
105
175
  "projects": [
106
176
  {
107
177
  "id": "my-project",
@@ -111,10 +181,13 @@ Config is stored at `~/.quadwork/config.json`:
111
181
  "agentchattr_url": "http://127.0.0.1:8300",
112
182
  "mcp_http_port": 8200,
113
183
  "mcp_sse_port": 8201,
184
+ "auto_continue_loop_guard": false,
185
+ "auto_continue_delay_sec": 30,
186
+ "auto_restore_after_restart": false,
114
187
  "agents": {
115
- "head": { "cwd": "/path/to/project-head", "command": "codex" },
116
- "dev": { "cwd": "/path/to/project-dev", "command": "claude" },
117
- "reviewer1": { "cwd": "/path/to/project-reviewer1", "command": "codex" },
188
+ "head": { "cwd": "/path/to/project-head", "command": "codex" },
189
+ "dev": { "cwd": "/path/to/project-dev", "command": "claude" },
190
+ "reviewer1": { "cwd": "/path/to/project-reviewer1", "command": "codex" },
118
191
  "reviewer2": { "cwd": "/path/to/project-reviewer2", "command": "claude" }
119
192
  }
120
193
  }
@@ -124,16 +197,50 @@ Config is stored at `~/.quadwork/config.json`:
124
197
 
125
198
  Each project gets its own AgentChattr instance, ports, and git worktrees.
126
199
 
127
- ## Architecture
200
+ ## Architecture
201
+
202
+ QuadWork runs as a single Express server on `127.0.0.1:8400`:
203
+
204
+ - **Static frontend** — pre-built Next.js export (the `out/` directory)
205
+ - **REST API** — agent lifecycle, config, GitHub proxy, chat proxy, triggers, loop guard, batch progress, project history
206
+ - **WebSocket** — xterm.js terminal PTY sessions + AgentChattr ws fan-out
128
207
 
129
- QuadWork runs a single Express server that serves:
208
+ Per-project AgentChattr clones live at `~/.quadwork/{project}/agentchattr/`,
209
+ each with their own ports. Per-project git worktrees sit next to the repo:
210
+ `{repo}-head`, `{repo}-dev`, `{repo}-reviewer1`, `{repo}-reviewer2`. The
211
+ dashboard's xterm.js tiles attach to node-pty sessions over a WebSocket;
212
+ nothing about the agent state is held client-side.
130
213
 
131
- - **Static frontend** — Pre-built Next.js export
132
- - **REST API** — Agent lifecycle, config, GitHub, chat proxy, triggers
133
- - **WebSocket** Terminal PTY sessions
214
+ ## Commands
215
+
216
+ | Command | Description |
217
+ |---------|-------------|
218
+ | `npx quadwork init` | One-time setup — installs prerequisites, opens the dashboard |
219
+ | `npx quadwork start` | Start the dashboard server |
220
+ | `npx quadwork stop` | Stop all processes |
221
+ | `npx quadwork cleanup --project <id>` | Remove a project's AgentChattr clone and config entry |
222
+ | `npx quadwork cleanup --legacy` | Remove the legacy `~/.quadwork/agentchattr/` install after migration |
223
+
224
+ After `init`, create projects from the web UI at `http://127.0.0.1:8400/setup`.
225
+
226
+ ### Disk usage
227
+
228
+ Each project gets its own AgentChattr clone at
229
+ `~/.quadwork/{project_id}/agentchattr/` (~77 MB per project):
230
+
231
+ | Projects | Disk |
232
+ |---------:|-----:|
233
+ | 1 | ~77 MB |
234
+ | 5 | ~385 MB |
235
+ | 10 | ~770 MB |
134
236
 
135
- All on one port (`127.0.0.1:8400`).
237
+ Per-project clones are necessary so multiple projects can run AgentChattr
238
+ simultaneously without port conflicts. Existing v1 users are auto-migrated
239
+ to per-project clones on the next `npx quadwork start`; once every project
240
+ has a working clone, the legacy shared install can be removed safely via
241
+ `npx quadwork cleanup --legacy` (which refuses to run if any project is
242
+ still on the legacy install).
136
243
 
137
- ## License
244
+ ## License
138
245
 
139
246
  MIT
package/bin/quadwork.js CHANGED
@@ -14,6 +14,18 @@ const TEMPLATES_DIR = path.join(__dirname, "..", "templates");
14
14
  const AGENTS = ["head", "reviewer1", "reviewer2", "dev"];
15
15
  const DEFAULT_AGENTCHATTR_DIR = path.join(CONFIG_DIR, "agentchattr");
16
16
  const AGENTCHATTR_REPO = "https://github.com/bcurts/agentchattr.git";
17
+ // #348: pinned AgentChattr commit shipped with this QuadWork
18
+ // release. The install path clones the default branch and then
19
+ // checks this commit out so two fresh installs on different days
20
+ // produce byte-identical clones. When bumping this pin,
21
+ // deliberately test against the new upstream commit first and
22
+ // note the update in docs/RELEASING.md.
23
+ //
24
+ // On checkout failure (e.g. upstream force-pushed the commit
25
+ // away), the install path falls back to the default branch with
26
+ // a loud warning instead of hard-failing — see installAgentChattr
27
+ // below.
28
+ const AGENTCHATTR_PIN = "3e71d4267572579e7ffeb83576645f90932c1849";
17
29
 
18
30
  // ─── ANSI Helpers ──────────────────────────────────────────────────────────
19
31
 
@@ -234,6 +246,14 @@ function _installAgentChattrLocked(dir, setError) {
234
246
  const cloneResult = run(`git clone "${AGENTCHATTR_REPO}" "${dir}" 2>&1`, { timeout: 60000 });
235
247
  if (cloneResult === null) return setError(`git clone of ${AGENTCHATTR_REPO} into ${dir} failed`);
236
248
  if (!fs.existsSync(runPy)) return setError(`Clone completed but run.py missing at ${dir}`);
249
+ // #348: pin to the known-good AgentChattr commit shipped with
250
+ // this QuadWork release. On failure (commit unreachable /
251
+ // force-pushed away), fall back to the default branch with a
252
+ // loud warning instead of hard-failing the install.
253
+ const pinResult = run(`git -C "${dir}" checkout ${AGENTCHATTR_PIN} 2>&1`, { timeout: 30000 });
254
+ if (pinResult === null) {
255
+ try { console.warn(`[quadwork] WARNING: could not check out AgentChattr pin ${AGENTCHATTR_PIN} at ${dir}; falling back to default branch. The upstream commit may have been force-pushed away — update AGENTCHATTR_PIN in bin/quadwork.js for reproducible installs.`); } catch {}
256
+ }
237
257
  }
238
258
 
239
259
  // 2. Create venv if missing.
@@ -1877,6 +1897,64 @@ async function cmdCleanup() {
1877
1897
  }
1878
1898
  }
1879
1899
 
1900
+ // ─── Doctor ─────────────────────────────────────────────────────────────────
1901
+
1902
+ // #348: show the AgentChattr pin and the actual commit SHA of
1903
+ // every per-project clone so operators can spot mismatches. The
1904
+ // global clone at DEFAULT_AGENTCHATTR_DIR is checked first, then
1905
+ // any clones under ~/.quadwork/<projectId>/agentchattr that are
1906
+ // referenced by config.json.
1907
+ function cmdDoctor() {
1908
+ console.log("");
1909
+ console.log("QuadWork doctor");
1910
+ console.log("===============");
1911
+ console.log(`AgentChattr repo: ${AGENTCHATTR_REPO}`);
1912
+ console.log(`Expected pin: ${AGENTCHATTR_PIN}`);
1913
+ console.log("");
1914
+ const cloneShaAt = (dir) => {
1915
+ if (!fs.existsSync(path.join(dir, ".git"))) return null;
1916
+ const sha = run(`git -C "${dir}" rev-parse HEAD 2>&1`);
1917
+ return sha ? sha.trim() : null;
1918
+ };
1919
+ const report = (label, dir) => {
1920
+ if (!dir || !fs.existsSync(dir)) {
1921
+ console.log(` [skip] ${label}: ${dir || "(not configured)"} — missing`);
1922
+ return;
1923
+ }
1924
+ const sha = cloneShaAt(dir);
1925
+ if (!sha) {
1926
+ console.log(` [warn] ${label}: ${dir} — not a git clone`);
1927
+ return;
1928
+ }
1929
+ const tag = sha === AGENTCHATTR_PIN ? "OK " : "DIFF";
1930
+ console.log(` [${tag}] ${label}: ${sha} (${dir})`);
1931
+ };
1932
+ // Global clone
1933
+ report("global", DEFAULT_AGENTCHATTR_DIR);
1934
+ // Per-project clones referenced by config.json
1935
+ try {
1936
+ const cfg = readConfig();
1937
+ const projects = Array.isArray(cfg.projects) ? cfg.projects : [];
1938
+ if (projects.length === 0) {
1939
+ console.log(" (no projects in config.json)");
1940
+ }
1941
+ for (const p of projects) {
1942
+ // Per-project clones live under ~/.quadwork/<id>/agentchattr
1943
+ // per cmdAddProject's layout, but a project may also override
1944
+ // via its own agentchattr_dir field.
1945
+ const perProject = p && p.agentchattr_dir
1946
+ ? p.agentchattr_dir
1947
+ : path.join(CONFIG_DIR, p.id || "", "agentchattr");
1948
+ report(`project:${p.id || "(unnamed)"}`, perProject);
1949
+ }
1950
+ } catch (err) {
1951
+ console.log(` (could not enumerate projects: ${err.message})`);
1952
+ }
1953
+ console.log("");
1954
+ console.log("Legend: [OK ] clone matches the pin; [DIFF] clone is off-pin (re-clone manually to re-sync)");
1955
+ console.log("");
1956
+ }
1957
+
1880
1958
  // ─── Main ───────────────────────────────────────────────────────────────────
1881
1959
 
1882
1960
  const command = process.argv[2];
@@ -1897,6 +1975,9 @@ switch (command) {
1897
1975
  case "cleanup":
1898
1976
  cmdCleanup();
1899
1977
  break;
1978
+ case "doctor":
1979
+ cmdDoctor();
1980
+ break;
1900
1981
  default:
1901
1982
  console.log(`
1902
1983
  Usage: quadwork <command>
@@ -1907,6 +1988,7 @@ switch (command) {
1907
1988
  stop Stop all QuadWork processes
1908
1989
  add-project Add a project via CLI (alternative to web UI /setup)
1909
1990
  cleanup Reclaim disk space (--project <id> or --legacy)
1991
+ doctor Report the AgentChattr pin + per-project clone SHAs
1910
1992
 
1911
1993
  Workflow:
1912
1994
  1. npx quadwork init — one-time global setup, opens dashboard
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/06mbme.sc_26-.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/15i5_ay.0ap.6.js" async=""></script><script src="/_next/static/chunks/0excsn2a_5qsb.js" async=""></script><script src="/_next/static/chunks/turbopack-0wh29ykoy-rb5.js" async=""></script><script src="/_next/static/chunks/0e~ue9ca5zrep.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 flex-col"><div hidden=""><!--$--><!--/$--></div><header class="sticky top-0 z-40 flex h-12 items-center justify-between border-b border-white/10 bg-neutral-950/90 px-4 backdrop-blur"><div class="flex items-center gap-3 min-w-0"><a class="text-sm font-bold text-white hover:text-blue-400 shrink-0" href="/">QuadWork</a><span class="hidden sm:inline text-neutral-600">|</span><span class="hidden sm:inline text-[13px] text-neutral-400 truncate">Your AI dev team while you<!-- --> <span class="text-neutral-200"></span><span class="ml-0.5 inline-block w-[1px] h-[12px] align-middle bg-neutral-400 animate-qw-blink"></span></span></div><div class="flex items-center gap-3 shrink-0"><button type="button" aria-label="About QuadWork" class="rounded p-1 text-neutral-400 hover:bg-white/5 hover:text-white"><svg width="18" height="18" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="10" cy="10" r="8"></circle><path d="M10 9v5" stroke-linecap="round"></path><circle cx="10" cy="6.5" r="0.8" fill="currentColor"></circle></svg></button><a href="https://github.com/realproject7/quadwork" target="_blank" rel="noopener noreferrer" class="text-[12px] text-neutral-400 hover:text-white">QuadWork github</a></div></header><div class="flex flex-1 min-h-0"><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></div><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[34852,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n3:I[86081,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n4:I[12527,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n5:I[59763,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n6:I[11717,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\na:I[11717,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"ViewportBoundary\"]\nc:I[11717,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"MetadataBoundary\"]\ne:I[92243,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/06mbme.sc_26-.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/06mbme.sc_26-.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0e~ue9ca5zrep.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 flex-col\",\"children\":[[\"$\",\"$L2\",null,{}],[\"$\",\"div\",null,{\"className\":\"flex flex-1 min-h-0\",\"children\":[[\"$\",\"$L3\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1 min-w-0 overflow-auto\",\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",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,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",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: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: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: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:1:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,null]},null,false,\"$@9\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$La\",null,{\"children\":\"$Lb\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lc\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Ld\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/06mbme.sc_26-.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"na3L7KeOGKGsbamYVibRj\"}\n"])</script><script>self.__next_f.push([1,"f:[]\n9:\"$Wf\"\n"])</script><script>self.__next_f.push([1,"b:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"10:I[80070,[\"/_next/static/chunks/0e~ue9ca5zrep.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"IconMark\"]\n8:null\nd:[[\"$\",\"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\"}],[\"$\",\"$L10\",\"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/05.po0c1knrbu.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/15i5_ay.0ap.6.js" async=""></script><script src="/_next/static/chunks/0excsn2a_5qsb.js" async=""></script><script src="/_next/static/chunks/turbopack-0wh29ykoy-rb5.js" async=""></script><script src="/_next/static/chunks/0za4cvk8.n0-y.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 flex-col"><div hidden=""><!--$--><!--/$--></div><header class="sticky top-0 z-40 flex h-12 items-center justify-between border-b border-white/10 bg-neutral-950/90 px-4 backdrop-blur"><div class="flex items-center gap-3 min-w-0"><a class="text-sm font-bold text-white hover:text-blue-400 shrink-0" href="/">QuadWork</a><span class="hidden sm:inline text-neutral-600">|</span><span class="hidden sm:inline text-[13px] text-neutral-400 truncate">Your AI dev team while you<!-- --> <span class="text-neutral-200"></span><span class="ml-0.5 inline-block w-[1px] h-[12px] align-middle bg-neutral-400 animate-qw-blink"></span></span></div><div class="flex items-center gap-3 shrink-0"><button type="button" aria-label="About QuadWork" class="rounded p-1 text-neutral-400 hover:bg-white/5 hover:text-white"><svg width="18" height="18" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="10" cy="10" r="8"></circle><path d="M10 9v5" stroke-linecap="round"></path><circle cx="10" cy="6.5" r="0.8" fill="currentColor"></circle></svg></button><a href="https://github.com/realproject7/quadwork" target="_blank" rel="noopener noreferrer" class="text-[12px] text-neutral-400 hover:text-white">QuadWork github</a></div></header><div class="flex flex-1 min-h-0"><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></div><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[34852,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n3:I[86081,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n4:I[12527,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n5:I[59763,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\"]\n6:I[11717,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\na:I[11717,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"ViewportBoundary\"]\nc:I[11717,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"MetadataBoundary\"]\ne:I[92243,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/05.po0c1knrbu.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/05.po0c1knrbu.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0za4cvk8.n0-y.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 flex-col\",\"children\":[[\"$\",\"$L2\",null,{}],[\"$\",\"div\",null,{\"className\":\"flex flex-1 min-h-0\",\"children\":[[\"$\",\"$L3\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1 min-w-0 overflow-auto\",\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",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,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",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: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: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: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:1:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,null]},null,false,\"$@9\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$La\",null,{\"children\":\"$Lb\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lc\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Ld\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/05.po0c1knrbu.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"OzDK1Fplm2eUu23bzILlU\"}\n"])</script><script>self.__next_f.push([1,"f:[]\n9:\"$Wf\"\n"])</script><script>self.__next_f.push([1,"b:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"10:I[80070,[\"/_next/static/chunks/0za4cvk8.n0-y.js\",\"/_next/static/chunks/0ox7p_szjhn69.js\"],\"IconMark\"]\n8:null\nd:[[\"$\",\"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\"}],[\"$\",\"$L10\",\"3\",{}]]\n"])</script></body></html>
@@ -1,6 +1,6 @@
1
1
  1:"$Sreact.fragment"
2
- 2:I[16348,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js","/_next/static/chunks/0md7hgvwnovzq.js"],"default"]
3
- 3:I[11717,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"OutletBoundary"]
2
+ 2:I[16348,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js","/_next/static/chunks/0e.ktwt1nyj...js"],"default"]
3
+ 3:I[11717,["/_next/static/chunks/0za4cvk8.n0-y.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/0md7hgvwnovzq.js","async":true}]],["$","$L3",null,{"children":["$","$4",null,{"name":"Next.MetadataOutlet","children":"$@5"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"na3L7KeOGKGsbamYVibRj"}
5
+ 0:{"rsc":["$","$1","c",{"children":[["$","$L2",null,{}],[["$","script","script-0",{"src":"/_next/static/chunks/0e.ktwt1nyj...js","async":true}]],["$","$L3",null,{"children":["$","$4",null,{"name":"Next.MetadataOutlet","children":"$@5"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"OzDK1Fplm2eUu23bzILlU"}
6
6
  5:null
@@ -1,18 +1,18 @@
1
1
  1:"$Sreact.fragment"
2
- 2:I[34852,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
3
- 3:I[86081,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
4
- 4:I[12527,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
5
- 5:I[59763,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
6
- 6:I[16348,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js","/_next/static/chunks/0md7hgvwnovzq.js"],"default"]
7
- 7:I[11717,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"OutletBoundary"]
2
+ 2:I[34852,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
3
+ 3:I[86081,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
4
+ 4:I[12527,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
5
+ 5:I[59763,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default"]
6
+ 6:I[16348,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js","/_next/static/chunks/0e.ktwt1nyj...js"],"default"]
7
+ 7:I[11717,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"OutletBoundary"]
8
8
  8:"$Sreact.suspense"
9
- a:I[11717,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"ViewportBoundary"]
10
- c:I[11717,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"MetadataBoundary"]
11
- e:I[92243,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default",1]
12
- :HL["/_next/static/chunks/06mbme.sc_26-.css","style"]
9
+ a:I[11717,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"ViewportBoundary"]
10
+ c:I[11717,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"MetadataBoundary"]
11
+ e:I[92243,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"default",1]
12
+ :HL["/_next/static/chunks/05.po0c1knrbu.css","style"]
13
13
  :HL["/_next/static/media/797e433ab948586e-s.p.0.q-h669a_dqa.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
14
- 0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/06mbme.sc_26-.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/0e~ue9ca5zrep.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 flex-col","children":[["$","$L2",null,{}],["$","div",null,{"className":"flex flex-1 min-h-0","children":[["$","$L3",null,{}],["$","main",null,{"className":"flex-1 min-w-0 overflow-auto","children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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":[["$","$L6",null,{}],[["$","script","script-0",{"src":"/_next/static/chunks/0md7hgvwnovzq.js","async":true,"nonce":"$undefined"}]],["$","$L7",null,{"children":["$","$8",null,{"name":"Next.MetadataOutlet","children":"$@9"}]}]]}],{},null,false,null]},null,false,null],["$","$1","h",{"children":[null,["$","$La",null,{"children":"$Lb"}],["$","div",null,{"hidden":true,"children":["$","$Lc",null,{"children":["$","$8",null,{"name":"Next.Metadata","children":"$Ld"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$e",[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/06mbme.sc_26-.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"na3L7KeOGKGsbamYVibRj"}
14
+ 0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/05.po0c1knrbu.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/0za4cvk8.n0-y.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 flex-col","children":[["$","$L2",null,{}],["$","div",null,{"className":"flex flex-1 min-h-0","children":[["$","$L3",null,{}],["$","main",null,{"className":"flex-1 min-w-0 overflow-auto","children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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":[["$","$L6",null,{}],[["$","script","script-0",{"src":"/_next/static/chunks/0e.ktwt1nyj...js","async":true,"nonce":"$undefined"}]],["$","$L7",null,{"children":["$","$8",null,{"name":"Next.MetadataOutlet","children":"$@9"}]}]]}],{},null,false,null]},null,false,null],["$","$1","h",{"children":[null,["$","$La",null,{"children":"$Lb"}],["$","div",null,{"hidden":true,"children":["$","$Lc",null,{"children":["$","$8",null,{"name":"Next.Metadata","children":"$Ld"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$e",[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/05.po0c1knrbu.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"OzDK1Fplm2eUu23bzILlU"}
15
15
  b:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
16
- f:I[80070,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"IconMark"]
16
+ f:I[80070,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"IconMark"]
17
17
  9:null
18
18
  d:[["$","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",{}]]
@@ -1,6 +1,6 @@
1
1
  1:"$Sreact.fragment"
2
- 2:I[11717,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"ViewportBoundary"]
3
- 3:I[11717,["/_next/static/chunks/0e~ue9ca5zrep.js","/_next/static/chunks/0ox7p_szjhn69.js"],"MetadataBoundary"]
2
+ 2:I[11717,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"ViewportBoundary"]
3
+ 3:I[11717,["/_next/static/chunks/0za4cvk8.n0-y.js","/_next/static/chunks/0ox7p_szjhn69.js"],"MetadataBoundary"]
4
4
  4:"$Sreact.suspense"
5
- 5:I[80070,["/_next/static/chunks/0e~ue9ca5zrep.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":"na3L7KeOGKGsbamYVibRj"}
5
+ 5:I[80070,["/_next/static/chunks/0za4cvk8.n0-y.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":"OzDK1Fplm2eUu23bzILlU"}