@turmind/halo 0.2.1-bc7cf2b → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,49 +6,119 @@
6
6
 
7
7
  [English](README.md) | [中文](README.zh-CN.md)
8
8
 
9
- **A multi-agent collaborative workspace you drive through natural language.** Describe what you want built; a primary agent decomposes the work, spawns sub-agents, and delivers it — while you watch, redirect, or take over at any point. Everything lives as files in a workspace you can read, edit, fork, and share.
9
+ **Throw in an idea. A team of agents builds it.**
10
10
 
11
- ![Halo workspace — file explorer, code canvas, and chat in one tab](assets/workspace.jpg)
11
+ Halo is a multi-agent workspace you drive in plain language. A primary agent reads your intent, breaks the work down, and fans it out to sub-agents that run in parallel — while every reasoning step and tool call streams by live, and you interrupt, redirect, or take over whenever you like. Everything the team knows and produces is plain files in a workspace you can read, edit, `git clone`, and share. No hidden memory. No opaque state.
12
12
 
13
- ## Highlights
13
+ ![Halo admin — a landing page assembled by parallel sub-agents, previewing live in Canvas](assets/workspace-hero.jpg)
14
+ <p align="center"><sub>One prompt — <i>“Build a landing page for our coffee roastery… split the sections across sub-agents in parallel, then assemble.”</i> Executors fan out, report back, and the assembled page previews in Canvas, all in one browser tab.</sub></p>
14
15
 
15
- **🧬 It improves itself.** Halo learns from its own conversations. Run `/evo` (or let pre-compact fire) and an internal evolution agent analyzes the session, drafts an improvement to its own prompt files, dry-runs it in a sandbox, and a scoring agent grades the result. You approve in the **Evolution** tab → the change merges back into the workspace. The agent literally refines its own instructions, with you as the reviewer.
16
+ ## Install
16
17
 
17
- ![Agents panel — global agents plus the internal Apply / Evolution / Score agents that power self-evolution](assets/agents.jpg)
18
-
19
- **🌐 One workspace, every channel.** Start a task in the browser, check progress from WeChat on your phone, give follow-up instructions over Telegram or Slack. Every channel connects to the *same* workspace and session — the workspace is the collaboration anchor, not the chat window.
18
+ ```bash
19
+ npm install -g @turmind/halo # one binary, all subcommands
20
+ halo setup # interactive: password / port / model keys / optional skills
21
+ halo server start # → open http://localhost:9527
22
+ ```
20
23
 
21
- **🧠 Provider-agnostic models.** A single `ModelRuntime` interface drives 10 model providers, configured per-agent. Run Claude on Bedrock for the heavy lifting and a cheaper local-region model for routine sub-tasks — no code changes.
24
+ > [!IMPORTANT]
25
+ > **First message fails with `Could not load credentials from any providers`?** API keys entered during `halo setup` are stored but **not auto-bound to any agent** — the built-in `default` agent initially points at AWS Bedrock. Open **Agents → default** in the admin and switch its model provider to the one you configured. (Bedrock users with a working AWS credential chain are unaffected.) Details in [Quick Start](#quick-start).
22
26
 
23
- **👁 Transparent orchestration.** Every agent's reasoning, tool call, and file change is visible in real time. Interrupts are graceful (conversation repair, not a hard abort), and sub-agents auto-report when done. You stay in the loop instead of running and praying.
27
+ ## Why Halo
24
28
 
25
- **🖥 IDE-like admin UI.** Chat + Monaco editor + file explorer + terminal (xterm.js), all in one browser tab. No switching between "talking to the AI" and "looking at the code."
29
+ ### 🧬 It rewrites its own prompts — and you review the diff
26
30
 
27
- **📁 The workspace is a portable unit.** Agent configs, skills, session history, and project docs are all just files under `.halo/` — no hidden memory, no opaque state. Because the whole agent lives in one directory, the unit you share is the *entire workspace*, not a single skill: copy `.halo/` (or `git clone` it) and the recipient gets a complete, runnable agent — persona, every skill, and config — that starts working on arrival. This is also what makes self-evolution possible: the evolution agent rewrites real files in the workspace, dry-runs them, and merges on approval.
31
+ Halo learns from its own conversations. Run `/evo` (or let pre-compact trigger it): an internal evolution agent analyzes the session, drafts a patch to the workspace's own prompt files, dry-runs the patched agent in a sandbox against the original scenario, and a scoring agent grades the outcome. You approve or reject in the **Evolution** tab; approved patches merge back into the workspace. Real file diffs reviewed by you — not silent fine-tuning.
28
32
 
29
- **🔒 Permission isolation.** Three access levels (`full` / `workspace` / `readonly`) enforced by a bubblewrap sandbox. Hand someone a `readonly` entry point and they can use your agents without write access to your files. (Filesystem isolation only — see [Status & Limitations](#status--limitations).)
33
+ ![Evolution tab — a run awaiting review with scores, dry-run reasoning, and the patch](assets/evolution-review.jpg)
34
+ <p align="center"><sub>A real run awaiting review: lint / behavior / scope scores, the grader's reasoning, and the patch itself — one click merges it into the workspace.</sub></p>
30
35
 
31
- ## Quick Start
36
+ ### 📁 The whole agent team is one folder
32
37
 
33
- Published on npm as [`@turmind/halo`](https://www.npmjs.com/package/@turmind/halo) — one binary, all subcommands:
38
+ Personas, skills, knowledge, session history — the entire agent team lives under `.halo/` as plain files:
34
39
 
35
- ```bash
36
- npm install -g @turmind/halo
37
- halo setup # interactive: password / port / model keys / optional skills
38
- halo server start # launch on :9527 (default)
39
40
  ```
41
+ my-project/
42
+ ├─ .halo/
43
+ │ ├─ agents/ # who's on the team — persona, model, tools per agent
44
+ │ ├─ skills/ # what they can do — markdown, injected on demand
45
+ │ ├─ docs/ # what they've learned — knowledge they read & write
46
+ │ ├─ memory/ # dated decision notes
47
+ │ └─ sessions/ # every conversation, replayable
48
+ └─ src/ … # your actual project
49
+ ```
50
+
51
+ `git clone` the workspace and the recipient gets a complete, runnable agent team — not an export, the real thing. It's also what makes self-evolution possible: the evolution agent edits real files, and you review real diffs.
52
+
53
+ ### 🌐 One workspace, every screen
54
+
55
+ Kick off a build in the browser, check progress from WeChat on the metro, drop a follow-up in Telegram or Slack, finish in the terminal. Every channel connects to the *same* workspace and session — channels are doors, the workspace is the room.
56
+
57
+ <p align="center">
58
+ <img src="assets/wechat-phone.jpg" alt="Halo in WeChat" width="270" />
59
+ &nbsp;&nbsp;
60
+ <img src="assets/telegram-phone.jpg" alt="Halo in Telegram" width="270" />
61
+ </p>
62
+ <p align="center"><sub>The same workspace, continued from WeChat and Telegram on a phone.</sub></p>
63
+
64
+ ### 👁 Watch it think
65
+
66
+ Every reasoning step, tool call, and file change streams in real time — including inside sub-agents. Interrupts are graceful (conversation repair, not a hard kill), and sub-agents report back when done. You stay in the loop instead of running and praying.
67
+
68
+ ![Chat panel — the primary agent dispatching three executor sub-agents in parallel](assets/orchestration.jpg)
69
+ <p align="center"><sub>The primary agent fans out three executors in parallel — every <code>start_session</code> and tool call visible as it happens.</sub></p>
70
+
71
+ And when you'd rather have ambience than logs: [Halo City](#halo-city) renders the same runtime as a living pixel town.
72
+
73
+ ## Also in the box
74
+
75
+ - **11 model providers, one runtime** — provider and model set per-agent: Claude on Bedrock for the heavy lifting, a cheap regional model for routine sub-tasks. No code changes.
76
+ - **IDE-grade admin** — chat + Monaco editor + file explorer + git panel + terminal (xterm.js) in one browser tab.
77
+ - **Skills** — markdown skill definitions injected into prompts on demand; workspace-scoped or global, no code required.
78
+ - **Cron tasks** — scheduled agent runs (recurring or one-shot) whose output fans out to your chat channels.
79
+ - **Permission isolation** — `full` / `workspace` / `readonly` access levels enforced by a bubblewrap sandbox (filesystem only — see [Status & Limitations](#status--limitations)).
80
+ - **ACP adapter** — plug a halo workspace into Claude Code as a native ACP agent, or let one halo delegate to another.
81
+ - **Structured sessions** — hierarchical parent ↔ child sessions with async coordination and auto-reports on completion.
40
82
 
41
- Then open **http://localhost:9527**.
83
+ ## New in v0.2.1
42
84
 
43
- - **Upgrade**: `halo upgrade && halo server restart`. The server's startup check refreshes bundled docs / agents / skills automatically when the on-disk template version is behind.
85
+ - 🎨 **Four UI themes** — dark, light, midnight, warm; synced server-side so every browser gets your pick.
86
+ - ⌨️ **TUI overhaul** — reworked input, verbose mode, and persistent history in the standalone terminal client.
87
+ - 🏙 **Halo City performance** — viewport culling + offscreen skyline; smooth on busy servers.
88
+ - 📊 **PPTX speaker-notes sidebar** — the slide preview now shows the notes lane alongside slides.
89
+ - ✂️ **Graceful interrupts, fully surfaced** — interrupted tool calls are repaired and shown in the session UI instead of vanishing.
90
+
91
+ ![Four themes — dark, light, midnight, warm](assets/themes.jpg)
92
+
93
+ ## Quick Start
94
+
95
+ Published on npm as [`@turmind/halo`](https://www.npmjs.com/package/@turmind/halo) — one binary, all subcommands. After the three install commands above, open **http://localhost:9527**.
96
+
97
+ | Prerequisite | Notes |
98
+ |---|---|
99
+ | Node.js >= 22 | the only hard system requirement |
100
+ | An API key for any supported model provider | entered during `halo setup`; AWS Bedrock users can leave keys unset and use the standard credential chain (env / `~/.aws` / instance role) instead |
101
+ | pnpm >= 9 | source builds only |
102
+
103
+ - **Bind your provider to the agent**: `halo setup` stores keys; agents choose providers. The built-in `default` agent ships pointing at AWS Bedrock, so if you configured a different provider, switch it once in **Agents → default → model provider** — your first conversation will thank you.
104
+ - **Upgrade**: `halo upgrade && halo server restart`. The startup check refreshes bundled docs / agents / skills automatically when the on-disk template version is behind.
44
105
  - **Docker / CI**: `halo setup --non-interactive` and supply credentials via the `HALO_PASSWORD` env var.
45
106
  - **From source**: `pnpm install && pnpm build`.
46
107
 
47
- | Prerequisite | Version |
48
- |---|---|
49
- | Node.js | >= 22 |
50
- | pnpm (source builds only) | >= 9 |
51
- | AWS credentials | Bedrock access, default region `us-east-1` |
108
+ ### Talk to it from curl
109
+
110
+ Every workspace can expose a token-authenticated HTTP + SSE endpoint — the Web channel, aka the "build your own UI" channel:
111
+
112
+ 1. In the admin, open **Channels → Web → Add Account**, pick a workspace and access level, and copy the token (shown once).
113
+ 2. Stream a conversation:
114
+
115
+ ```bash
116
+ curl -N -H "x-token: $TOKEN" -H "Content-Type: application/json" \
117
+ -d '{"message":"What files are in this workspace?"}' \
118
+ http://localhost:9527/api/web/chat
119
+ ```
120
+
121
+ The response is SSE frames — `session` / `thinking` / `tool_call` / `stream` / `complete` — full protocol in [`.halo/docs/guide/channels/web.md`](.halo/docs/guide/channels/web.md).
52
122
 
53
123
  ## Models
54
124
 
@@ -63,6 +133,7 @@ Configured per-agent through one provider-agnostic runtime. AWS Bedrock Claude i
63
133
  | DeepSeek | |
64
134
  | Kimi (Moonshot AI) | |
65
135
  | MiniMax | |
136
+ | Mimo (Xiaomi) | Anthropic-compatible gateway, 1M context |
66
137
  | Qwen (Aliyun) | |
67
138
  | Hunyuan (Tencent) | |
68
139
  | Doubao (Volcengine) | |
@@ -76,7 +147,7 @@ Every channel shares the same workspace and session state. Onboarding guides liv
76
147
  | Channel | Transport | Notes |
77
148
  |---|---|---|
78
149
  | **Admin** | WebSocket | Full-featured browser UI |
79
- | **Web** | HTTP + SSE | Token-authenticated API, independently deployable |
150
+ | **Web** | HTTP + SSE | Token-authenticated API, independently deployable — see [curl example](#talk-to-it-from-curl) |
80
151
  | **CLI / TUI** | local | Standalone terminal client, embedded agent loop (no server required) |
81
152
  | **Telegram** | Bot API | Long polling |
82
153
  | **Slack** | Socket Mode | No public webhook required |
@@ -84,30 +155,21 @@ Every channel shares the same workspace and session state. Onboarding guides liv
84
155
  | **WeChat** | QR bind | Scan to bind, mobile access |
85
156
  | **ACP adapter** | stdio JSON-RPC | Bridges ACP clients (Claude Code, etc.) onto the Web channel |
86
157
 
87
- <p align="center">
88
- <img src="assets/wechat-phone.jpg" alt="Halo in WeChat" width="270" />
89
- &nbsp;&nbsp;
90
- <img src="assets/telegram-phone.jpg" alt="Halo in Telegram" width="270" />
91
- </p>
92
- <p align="center"><sub>Same workspace, driven from WeChat and Telegram on a phone.</sub></p>
93
-
94
- ## More Capabilities
158
+ ![Halo TUI — delegation and reporting streamed in the terminal](assets/tui.jpg)
159
+ <p align="center"><sub>The TUI runs the same agent loop in your terminal — here delegating to an executor and consolidating its report, no server needed.</sub></p>
95
160
 
96
- - **Multi-agent collaboration** — root agent decomposes tasks and spawns sub-agents; hierarchical sessions with async parent-child coordination.
97
- - **Workspace tools** — `file_read` / `file_write` / `file_edit`, sandboxed `shell_exec`, `grep` / `glob`, `web_fetch`, `view_image`, plus session tools (`start_session`, `query_session`, `interrupt_session`, …) for multi-agent control.
98
- - **Skills system** — Markdown-based skill definitions injected into agent prompts on demand; workspace-scoped or global, extensible without code changes.
99
- - **Cron tasks** — scheduled agent runs (recurring or one-shot) that fan output out to bound channel accounts.
100
- - **Halo City** — a read-only pixel **city block** that visualizes a server's runtime: each workspace is a building, each session an animal citizen at a desk, click anyone to inspect their live session log. Pure client-side canvas, zero model tokens. Lives at [`halo-city/`](halo-city/) — see [design notes](.halo/docs/design/halo-city.md).
161
+ ## Halo City
101
162
 
102
- ![Halo City — a pixel city block visualizing the server runtime](assets/halo-city.jpg)
163
+ A read-only pixel city that visualizes a live halo server: each workspace is a building, each session an animal citizen — at a desk when working, grabbing coffee or hitting the arcade when idle. Click any citizen to inspect the real thing: live session log, delegation chain, last tool call, token usage. Pure client-side canvas on a single polling endpoint — **zero model tokens burned**.
103
164
 
104
- ![Skills panel — global and workspace skills, extensible without code changes](assets/skills.jpg)
165
+ ![Halo City street level — sub-agent citizens at work, one inspected](assets/halo-city-street.jpg)
166
+ <p align="center"><sub>Street level: three sub-agent citizens heads-down in the <code>aurora-cafe</code> building; the inspector shows one executor's live log and delegation chain.</sub></p>
105
167
 
106
- ![Halo CLI / TUI](assets/cli.jpg)
168
+ Lives at [`halo-city/`](halo-city/) (plain static files, no build) — see the [design notes](.halo/docs/design/halo-city.md).
107
169
 
108
170
  ## Tech Stack
109
171
 
110
- - **Monorepo**: pnpm workspace (`packages/core`, `server`, `admin`, `cli`)
172
+ - **Monorepo**: pnpm workspace (`core`, `server`, `admin`, `cli`, `desktop`, `acp-adapter`, `web-demo`)
111
173
  - **Backend**: Hono + WebSocket, single Node.js process on port 9527
112
174
  - **Frontend**: Next.js 15 static export, served directly by Hono
113
175
  - **Agent**: custom orchestration loop, provider-agnostic `ModelRuntime` interface
@@ -120,17 +182,18 @@ Every channel shares the same workspace and session state. Onboarding guides liv
120
182
  - [`.halo/docs/requirements/overview.md`](.halo/docs/requirements/overview.md) — product concept
121
183
  - [`.halo/docs/design/architecture.md`](.halo/docs/design/architecture.md) — backend architecture
122
184
  - [`.halo/docs/design/evolution.md`](.halo/docs/design/evolution.md) — self-evolution design
185
+ - [`.halo/docs/guide/channels/`](.halo/docs/guide/channels/) — per-channel onboarding guides
123
186
  - [`.halo/docs/dev/deploy.md`](.halo/docs/dev/deploy.md) — deployment (systemd / Nginx)
124
187
  - [`.halo/docs/dev/env.md`](.halo/docs/dev/env.md) — env vars, build commands
125
188
  - [`CLAUDE.md`](CLAUDE.md) — development instructions for Claude Code
126
189
 
127
190
  ## Status & Limitations
128
191
 
129
- Halo is young and single-maintainer. It runs, but treat it as an early-stage project, not a hardened product:
192
+ Halo is young — treat it as an early-stage project:
130
193
 
131
194
  - **Sandbox isolates the filesystem, not the network.** The bubblewrap sandbox covers access levels and filesystem reach (host paths, `~/.aws`/`~/.ssh` masked), but does **not** isolate the network — code running inside it can still make outbound connections. The threat model is accidental damage and path escape by a trusted agent, **not** containment of a deliberately malicious skill exfiltrating data. Network isolation is on the roadmap.
132
- - **No automated test suite yet.** Correctness rests on review and manual verification. Targeted tests for the externally-fixed contracts (session-file format, WS protocol) are planned over broad unit coverage.
133
- - **Single maintainer, minimal external validation.** Expect rough edges; APIs and on-disk formats may still change between versions.
195
+ - **Test coverage is unit/regression-level, not end-to-end.** 345 tests across the four packages (core, server, cli, admin) run on every push via CI, covering core logic — path-boundary checks, session repair, channel message formatting, the TUI engine, and more. There's no end-to-end or integration suite yet.
196
+ - **APIs and on-disk formats may still change between versions.** Expect rough edges while things stabilize.
134
197
 
135
198
  If you hit something broken or surprising, please open an issue — early feedback is genuinely useful right now.
136
199
 
@@ -1 +1 @@
1
- <!DOCTYPE html><!--iSrc6429pyTB0lK_EE5oH--><html lang="en" class="dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/e4af272ccee01ff0-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/66df341f99220f5c.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-47520cdc55be63e7.js"/><script src="/_next/static/chunks/fb4ec4d6-3fa44f69484f91b9.js" async=""></script><script src="/_next/static/chunks/635-3dd0043ed0520b9d.js" async=""></script><script src="/_next/static/chunks/main-app-483b436873410ddc.js" async=""></script><script src="/_next/static/chunks/212-170855bed19f67f3.js" async=""></script><script src="/_next/static/chunks/app/layout-c2fa8035998e48d5.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>Halo - Multi-Agent Workspace</title><meta name="description" content="Multi-agent collaboration workspace for complex project delivery"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16"/><link rel="icon" href="/icon.svg?3a6863548daca964" type="image/svg+xml" sizes="any"/><script>try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__variable_f367f3 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><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><!--$--><!--/$--><script src="/_next/static/chunks/webpack-47520cdc55be63e7.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[59391,[\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"177\",\"static/chunks/app/layout-c2fa8035998e48d5.js\"],\"ThemeProvider\"]\n3:I[26967,[\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"177\",\"static/chunks/app/layout-c2fa8035998e48d5.js\"],\"AppI18nProvider\"]\n4:I[66048,[],\"\"]\n5:I[29926,[],\"\"]\n6:I[11789,[],\"OutletBoundary\"]\n8:I[21528,[],\"AsyncMetadataOutlet\"]\na:I[11789,[],\"ViewportBoundary\"]\nc:I[11789,[],\"MetadataBoundary\"]\nd:\"$Sreact.suspense\"\nf:I[79836,[],\"\"]\n:HL[\"/_next/static/media/e4af272ccee01ff0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/66df341f99220f5c.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"iSrc6429pyTB0lK-EE5oH\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/66df341f99220f5c.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"dark\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}\"}}]}],[\"$\",\"body\",null,{\"className\":\"__variable_f367f3 font-sans antialiased\",\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]}]]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$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\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"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.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$L7\",[\"$\",\"$L8\",null,{\"promise\":\"$@9\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$La\",null,{\"children\":\"$Lb\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$Lc\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$d\",null,{\"fallback\":null,\"children\":\"$Le\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$f\",[]],\"s\":false,\"S\":true}\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\"}]]\n7:null\n"])</script><script>self.__next_f.push([1,"10:I[89592,[],\"IconMark\"]\n9:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Halo - Multi-Agent Workspace\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Multi-agent collaboration workspace for complex project delivery\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon.svg?3a6863548daca964\",\"type\":\"image/svg+xml\",\"sizes\":\"any\"}],[\"$\",\"$L10\",\"4\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"e:\"$9:metadata\"\n"])</script></body></html>
1
+ <!DOCTYPE html><!--vHdygDsxwoyxkXg5umpZ1--><html lang="en" class="dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/e4af272ccee01ff0-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/66df341f99220f5c.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-47520cdc55be63e7.js"/><script src="/_next/static/chunks/fb4ec4d6-3fa44f69484f91b9.js" async=""></script><script src="/_next/static/chunks/635-3dd0043ed0520b9d.js" async=""></script><script src="/_next/static/chunks/main-app-483b436873410ddc.js" async=""></script><script src="/_next/static/chunks/212-170855bed19f67f3.js" async=""></script><script src="/_next/static/chunks/app/layout-c2fa8035998e48d5.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>Halo - Multi-Agent Workspace</title><meta name="description" content="Multi-agent collaboration workspace for complex project delivery"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16"/><link rel="icon" href="/icon.svg?3a6863548daca964" type="image/svg+xml" sizes="any"/><script>try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__variable_f367f3 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><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><!--$--><!--/$--><script src="/_next/static/chunks/webpack-47520cdc55be63e7.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[59391,[\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"177\",\"static/chunks/app/layout-c2fa8035998e48d5.js\"],\"ThemeProvider\"]\n3:I[26967,[\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"177\",\"static/chunks/app/layout-c2fa8035998e48d5.js\"],\"AppI18nProvider\"]\n4:I[66048,[],\"\"]\n5:I[29926,[],\"\"]\n6:I[11789,[],\"OutletBoundary\"]\n8:I[21528,[],\"AsyncMetadataOutlet\"]\na:I[11789,[],\"ViewportBoundary\"]\nc:I[11789,[],\"MetadataBoundary\"]\nd:\"$Sreact.suspense\"\nf:I[79836,[],\"\"]\n:HL[\"/_next/static/media/e4af272ccee01ff0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/66df341f99220f5c.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"vHdygDsxwoyxkXg5umpZ1\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/66df341f99220f5c.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"dark\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}\"}}]}],[\"$\",\"body\",null,{\"className\":\"__variable_f367f3 font-sans antialiased\",\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]}]]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$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\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"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.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$L7\",[\"$\",\"$L8\",null,{\"promise\":\"$@9\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$La\",null,{\"children\":\"$Lb\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$Lc\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$d\",null,{\"fallback\":null,\"children\":\"$Le\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$f\",[]],\"s\":false,\"S\":true}\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\"}]]\n7:null\n"])</script><script>self.__next_f.push([1,"10:I[89592,[],\"IconMark\"]\n9:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Halo - Multi-Agent Workspace\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Multi-agent collaboration workspace for complex project delivery\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon.svg?3a6863548daca964\",\"type\":\"image/svg+xml\",\"sizes\":\"any\"}],[\"$\",\"$L10\",\"4\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"e:\"$9:metadata\"\n"])</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><!--iSrc6429pyTB0lK_EE5oH--><html lang="en" class="dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/e4af272ccee01ff0-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/66df341f99220f5c.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/659eccb5db697b76.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-47520cdc55be63e7.js"/><script src="/_next/static/chunks/fb4ec4d6-3fa44f69484f91b9.js" async=""></script><script src="/_next/static/chunks/635-3dd0043ed0520b9d.js" async=""></script><script src="/_next/static/chunks/main-app-483b436873410ddc.js" async=""></script><script src="/_next/static/chunks/212-170855bed19f67f3.js" async=""></script><script src="/_next/static/chunks/app/layout-c2fa8035998e48d5.js" async=""></script><script src="/_next/static/chunks/1d2d5650-810a3ca1ae20cab5.js" async=""></script><script src="/_next/static/chunks/307-d7a99f9a4a436ec3.js" async=""></script><script src="/_next/static/chunks/app/page-31317ef1fb0ba31f.js" async=""></script><meta name="next-size-adjust" content=""/><title>Halo - Multi-Agent Workspace</title><meta name="description" content="Multi-agent collaboration workspace for complex project delivery"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16"/><link rel="icon" href="/icon.svg?3a6863548daca964" type="image/svg+xml" sizes="any"/><script>try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__variable_f367f3 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><div class="flex h-screen w-screen items-center justify-center bg-[var(--background)]"><div class="text-sm text-[var(--muted-foreground)]">Loading...</div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-47520cdc55be63e7.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[59391,[\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"177\",\"static/chunks/app/layout-c2fa8035998e48d5.js\"],\"ThemeProvider\"]\n3:I[26967,[\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"177\",\"static/chunks/app/layout-c2fa8035998e48d5.js\"],\"AppI18nProvider\"]\n4:I[66048,[],\"\"]\n5:I[29926,[],\"\"]\n6:I[57917,[],\"ClientPageRoot\"]\n7:I[11704,[\"560\",\"static/chunks/1d2d5650-810a3ca1ae20cab5.js\",\"307\",\"static/chunks/307-d7a99f9a4a436ec3.js\",\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"974\",\"static/chunks/app/page-31317ef1fb0ba31f.js\"],\"default\"]\na:I[11789,[],\"OutletBoundary\"]\nc:I[21528,[],\"AsyncMetadataOutlet\"]\ne:I[11789,[],\"ViewportBoundary\"]\n10:I[11789,[],\"MetadataBoundary\"]\n11:\"$Sreact.suspense\"\n13:I[79836,[],\"\"]\n:HL[\"/_next/static/media/e4af272ccee01ff0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/66df341f99220f5c.css\",\"style\"]\n:HL[\"/_next/static/css/659eccb5db697b76.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"iSrc6429pyTB0lK-EE5oH\",\"p\":\"\",\"c\":[\"\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/66df341f99220f5c.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"dark\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}\"}}]}],[\"$\",\"body\",null,{\"className\":\"__variable_f367f3 font-sans antialiased\",\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"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\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$L6\",null,{\"Component\":\"$7\",\"searchParams\":{},\"params\":{},\"promises\":[\"$@8\",\"$@9\"]}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/659eccb5db697b76.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"$La\",null,{\"children\":[\"$Lb\",[\"$\",\"$Lc\",null,{\"promise\":\"$@d\"}]]}]]}],{},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[[\"$\",\"$Le\",null,{\"children\":\"$Lf\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$L10\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$11\",null,{\"fallback\":null,\"children\":\"$L12\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$13\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:{}\n9:\"$0:f:0:1:2:children:1:props:children:0:props:params\"\n"])</script><script>self.__next_f.push([1,"f:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\nb:null\n"])</script><script>self.__next_f.push([1,"14:I[89592,[],\"IconMark\"]\nd:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Halo - Multi-Agent Workspace\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Multi-agent collaboration workspace for complex project delivery\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon.svg?3a6863548daca964\",\"type\":\"image/svg+xml\",\"sizes\":\"any\"}],[\"$\",\"$L14\",\"4\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"12:\"$d:metadata\"\n"])</script></body></html>
1
+ <!DOCTYPE html><!--vHdygDsxwoyxkXg5umpZ1--><html lang="en" class="dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/e4af272ccee01ff0-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/66df341f99220f5c.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/659eccb5db697b76.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-47520cdc55be63e7.js"/><script src="/_next/static/chunks/fb4ec4d6-3fa44f69484f91b9.js" async=""></script><script src="/_next/static/chunks/635-3dd0043ed0520b9d.js" async=""></script><script src="/_next/static/chunks/main-app-483b436873410ddc.js" async=""></script><script src="/_next/static/chunks/212-170855bed19f67f3.js" async=""></script><script src="/_next/static/chunks/app/layout-c2fa8035998e48d5.js" async=""></script><script src="/_next/static/chunks/1d2d5650-810a3ca1ae20cab5.js" async=""></script><script src="/_next/static/chunks/307-d7a99f9a4a436ec3.js" async=""></script><script src="/_next/static/chunks/app/page-31317ef1fb0ba31f.js" async=""></script><meta name="next-size-adjust" content=""/><title>Halo - Multi-Agent Workspace</title><meta name="description" content="Multi-agent collaboration workspace for complex project delivery"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16"/><link rel="icon" href="/icon.svg?3a6863548daca964" type="image/svg+xml" sizes="any"/><script>try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__variable_f367f3 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><div class="flex h-screen w-screen items-center justify-center bg-[var(--background)]"><div class="text-sm text-[var(--muted-foreground)]">Loading...</div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-47520cdc55be63e7.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[59391,[\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"177\",\"static/chunks/app/layout-c2fa8035998e48d5.js\"],\"ThemeProvider\"]\n3:I[26967,[\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"177\",\"static/chunks/app/layout-c2fa8035998e48d5.js\"],\"AppI18nProvider\"]\n4:I[66048,[],\"\"]\n5:I[29926,[],\"\"]\n6:I[57917,[],\"ClientPageRoot\"]\n7:I[11704,[\"560\",\"static/chunks/1d2d5650-810a3ca1ae20cab5.js\",\"307\",\"static/chunks/307-d7a99f9a4a436ec3.js\",\"212\",\"static/chunks/212-170855bed19f67f3.js\",\"974\",\"static/chunks/app/page-31317ef1fb0ba31f.js\"],\"default\"]\na:I[11789,[],\"OutletBoundary\"]\nc:I[21528,[],\"AsyncMetadataOutlet\"]\ne:I[11789,[],\"ViewportBoundary\"]\n10:I[11789,[],\"MetadataBoundary\"]\n11:\"$Sreact.suspense\"\n13:I[79836,[],\"\"]\n:HL[\"/_next/static/media/e4af272ccee01ff0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/66df341f99220f5c.css\",\"style\"]\n:HL[\"/_next/static/css/659eccb5db697b76.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"vHdygDsxwoyxkXg5umpZ1\",\"p\":\"\",\"c\":[\"\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/66df341f99220f5c.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"dark\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}\"}}]}],[\"$\",\"body\",null,{\"className\":\"__variable_f367f3 font-sans antialiased\",\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"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\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$L6\",null,{\"Component\":\"$7\",\"searchParams\":{},\"params\":{},\"promises\":[\"$@8\",\"$@9\"]}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/659eccb5db697b76.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"$La\",null,{\"children\":[\"$Lb\",[\"$\",\"$Lc\",null,{\"promise\":\"$@d\"}]]}]]}],{},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[[\"$\",\"$Le\",null,{\"children\":\"$Lf\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$L10\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$11\",null,{\"fallback\":null,\"children\":\"$L12\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$13\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:{}\n9:\"$0:f:0:1:2:children:1:props:children:0:props:params\"\n"])</script><script>self.__next_f.push([1,"f:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\nb:null\n"])</script><script>self.__next_f.push([1,"14:I[89592,[],\"IconMark\"]\nd:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Halo - Multi-Agent Workspace\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Multi-agent collaboration workspace for complex project delivery\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon.svg?3a6863548daca964\",\"type\":\"image/svg+xml\",\"sizes\":\"any\"}],[\"$\",\"$L14\",\"4\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"12:\"$d:metadata\"\n"])</script></body></html>
@@ -14,7 +14,7 @@ e:I[11789,[],"ViewportBoundary"]
14
14
  :HL["/_next/static/media/e4af272ccee01ff0-s.p.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
15
15
  :HL["/_next/static/css/66df341f99220f5c.css","style"]
16
16
  :HL["/_next/static/css/659eccb5db697b76.css","style"]
17
- 0:{"P":null,"b":"iSrc6429pyTB0lK-EE5oH","p":"","c":["",""],"i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/66df341f99220f5c.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"dark","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}"}}]}],["$","body",null,{"className":"__variable_f367f3 font-sans antialiased","children":["$","$L2",null,{"children":["$","$L3",null,{"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":["__PAGE__",["$","$1","c",{"children":[["$","$L6",null,{"Component":"$7","searchParams":{},"params":{},"promises":["$@8","$@9"]}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/659eccb5db697b76.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","$La",null,{"children":["$Lb",["$","$Lc",null,{"promise":"$@d"}]]}]]}],{},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Le",null,{"children":"$Lf"}],["$","meta",null,{"name":"next-size-adjust","content":""}]],["$","$L10",null,{"children":["$","div",null,{"hidden":true,"children":["$","$11",null,{"fallback":null,"children":"$L12"}]}]}]]}],false]],"m":"$undefined","G":["$13",[]],"s":false,"S":true}
17
+ 0:{"P":null,"b":"vHdygDsxwoyxkXg5umpZ1","p":"","c":["",""],"i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/66df341f99220f5c.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"dark","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"try{var t=localStorage.getItem('halo_theme');if(t==='light'||t==='midnight'||t==='warm')document.documentElement.dataset.theme=t}catch(e){}"}}]}],["$","body",null,{"className":"__variable_f367f3 font-sans antialiased","children":["$","$L2",null,{"children":["$","$L3",null,{"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":["__PAGE__",["$","$1","c",{"children":[["$","$L6",null,{"Component":"$7","searchParams":{},"params":{},"promises":["$@8","$@9"]}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/659eccb5db697b76.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","$La",null,{"children":["$Lb",["$","$Lc",null,{"promise":"$@d"}]]}]]}],{},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Le",null,{"children":"$Lf"}],["$","meta",null,{"name":"next-size-adjust","content":""}]],["$","$L10",null,{"children":["$","div",null,{"hidden":true,"children":["$","$11",null,{"fallback":null,"children":"$L12"}]}]}]]}],false]],"m":"$undefined","G":["$13",[]],"s":false,"S":true}
18
18
  8:{}
19
19
  9:"$0:f:0:1:2:children:1:props:children:0:props:params"
20
20
  f:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
@@ -0,0 +1,97 @@
1
+ # AgentCore Runtime Mode
2
+
3
+ Halo server as an **Amazon Bedrock AgentCore Runtime** container — a fourth
4
+ way to run halo (server / CLI / desktop / AgentCore). One env var flips it:
5
+ `HALO_RUNTIME_MODE=agentcore`. Demo package: `packages/agentcore-demo/`
6
+ (Dockerfile, chat frontend, CDK stack, auth Lambdas — its README carries the
7
+ operational gotchas; this doc covers how the mode works inside the server).
8
+
9
+ ```
10
+ Browser (static frontend, S3 + CloudFront)
11
+ │ /api/login, /api/verify → CloudFront /api/* behavior → API GW → auth Lambda (DDB users, JWT)
12
+ │ /api/ws-presign → presign Lambda (SigV4-signs the AgentCore WS URL)
13
+ │ wss (presigned URL, 5-min TTL)
14
+ ▼
15
+ AgentCore Runtime (per-session microVM, auth terminated here)
16
+ │ X-Amzn-Bedrock-AgentCore-Runtime-Session-Id = user UUID
17
+ ▼
18
+ halo server :8080 (HALO_RUNTIME_MODE=agentcore)
19
+ ├── GET /ping Healthy | HealthyBusy (any running agent session)
20
+ ├── POST /invocations {"input":{"prompt"}} → full assistant message
21
+ └── WS /ws streaming frames (primary path)
22
+ ```
23
+
24
+ ## What the mode changes (packages/server/src/index.ts)
25
+
26
+ `config.server.runtimeMode === 'agentcore'` (env `HALO_RUNTIME_MODE`) skips:
27
+
28
+ - **Password/JWT gate** — AgentCore terminates auth upstream (SigV4 presign /
29
+ OAuth); the container is only reachable through the runtime.
30
+ - **Single-instance lock** — one microVM per session; many server processes
31
+ coexist by design.
32
+ - **Channels, cron, evolution, archive daemon** — meaningless in an ephemeral
33
+ per-session microVM; sessions are driven only through the AgentCore surface.
34
+
35
+ Everything else (agent loop, tools, skills, sqlite persistence) is the normal
36
+ server. The adapter itself is `packages/server/src/routes/agentcore.ts`,
37
+ mounted at the root (the AgentCore contract paths live outside `/api`).
38
+
39
+ ## Per-user workspace isolation
40
+
41
+ `userWorkspace(base, runtimeSessionId)` maps each runtime session id to
42
+ `<HALO_WORKSPACE>/users/<sanitized-id>/` — an isolated workspace with its own
43
+ `.halo/` (sqlite + session files). The id chain:
44
+
45
+ DDB `agentcore-demo-users` UUID → login response → frontend uses it as
46
+ sessionId → presign Lambda signs it into
47
+ `X-Amzn-Bedrock-AgentCore-Runtime-Session-Id` → adapter routes the workspace.
48
+
49
+ So **1 user = 1 runtime session id = 1 workspace**: users never see each
50
+ other's history; reconnecting with the same id resumes the same conversation.
51
+ `HALO_WORKSPACE` points at an EFS mount (`/mnt/efs`) — microVMs are ephemeral,
52
+ EFS makes the workspaces survive session termination and image rollouts.
53
+
54
+ ## WS protocol quirks (why /init exists)
55
+
56
+ The AgentCore WS proxy only forwards **client frames containing `inputText`**
57
+ and cannot push server frames on connect. Hence:
58
+
59
+ - Frontend sends `{"inputText":"/init"}` after open; the server special-cases
60
+ it (also accepts `{"type":"init"}`) and replies with a `history` frame —
61
+ a full snapshot, which the frontend renders by rebuild-from-scratch (not
62
+ append), keyed by a signature so identical snapshots skip re-rendering.
63
+ - Frames without `inputText` are silently ignored server-side — the frontend
64
+ uses `{type:'ping'}` every 30s purely to keep the proxy from cutting the
65
+ socket.
66
+ - `/session switch` sends a `{type:'switch'}` frame → frontend clears, then
67
+ the follow-up history frame rebuilds.
68
+
69
+ ## Session lifecycle (the part everyone gets wrong)
70
+
71
+ - Idle timeout (`idleRuntimeSessionTimeout`) terminates a session whose
72
+ `/ping` reports `Healthy`; `maxLifetime` (8h) force-terminates even busy
73
+ ones; failed health checks kill immediately.
74
+ - **An open WebSocket = an in-flight invocation** — the session never counts
75
+ as idle while a socket is open. The 30s frontend keepalive therefore keeps
76
+ the whole session warm; effective idle timeout ≈ "after the tab closes".
77
+ - `/ping` returns `HealthyBusy` whenever any agent session is running
78
+ (`registry.list().some(sm => sm.hasRunningSessions())`) — the official
79
+ keep-alive for long tool chains with no open connection.
80
+ - Termination is cheap: data is on EFS, next connect cold-starts (~3s) and
81
+ history reloads. `stop-runtime-session` kills one session on demand; there
82
+ is **no list/get-runtime-sessions API** (observe via CloudWatch `Sessions`
83
+ metric + runtime log filtering).
84
+
85
+ ## Ops crib sheet
86
+
87
+ - CloudWatch logs capture container **stdout**; halo's logger drops
88
+ sub-threshold lines before stdout — set `HALO_LOG_LEVEL=info` or the log
89
+ group stays near-empty.
90
+ - `update-agent-runtime` **replaces the whole config** — omit
91
+ `--filesystem-configurations` and the EFS mount silently disappears.
92
+ Fetch-modify-send, and strip `requireServiceS3Endpoint` (rejected on
93
+ newer runtimes).
94
+ - VPC mode has no public IP: private subnets need `0.0.0.0/0 → NAT` or all
95
+ egress (Bedrock included) hangs → opaque 502s.
96
+ - Full operational detail + deploy walkthrough:
97
+ `packages/agentcore-demo/README.md`.
@@ -109,7 +109,7 @@ Sandbox is whitelist-cp from main workspace (only: `INSTRUCTIONS.md`, `INDEX.md`
109
109
  ### Phase B — Dry-run + Fix Loop
110
110
 
111
111
  ```
112
- timeout 600 halo cli -a <patch.testScenario.agentId> -n -w <runDir>/sandbox \
112
+ timeout 1800 halo cli -a <patch.testScenario.agentId> -n -w <runDir>/sandbox \
113
113
  --access workspace <patch.testScenario.testMessage>
114
114
  ```
115
115
 
@@ -174,7 +174,7 @@ The wrapper clears any stale ABORT.md (from a crashed previous attempt) at the s
174
174
  For each source_run_id:
175
175
 
176
176
  1. Read `testScenario` from source run's `patch.md`.
177
- 2. Run `timeout 600 halo cli -a <agentId> -n -w <applyDir>/sandbox <testMessage>` against merged sandbox.
177
+ 2. Run `timeout 1800 halo cli -a <agentId> -n -w <applyDir>/sandbox <testMessage>` against merged sandbox.
178
178
  3. Spawn `__score__` with regress-mode brief, write `regress/<runId>/score.json`.
179
179
  4. Any score with `lint < 50` or `behavior < 50` → regression, abort with `failed`.
180
180
 
@@ -34,10 +34,11 @@ Halo 服务器运行态的**街景式**像素可视化:侧视、剖面的像素
34
34
  | 🪜 楼梯间 | 大楼左侧,真的逐层爬上爬下(没有传送) |
35
35
  | 💺 工作层 | 每层 3 张工位(按 agent 名固定)+ 1 个技能站 + 随机小设施(盆栽/小书架/白板/售货机);干活时屏幕滚代码 |
36
36
  | 🍵 公共层 | 冰箱(偶尔开门漏光)、水吧(水壶冒汽)、书报架、沙发,外加街机/鱼缸/猫爬架三选一;右侧伸出**阳台**(烟灰桶+盆栽)——抽烟点 |
37
- | 🚬 习惯 | 每个 session 由 id hash 派生 **3 个固定偏好**(抽烟/咖啡/泡茶/翻冰箱/看书/街机/看鱼/撸猫/打电话/下楼遛弯/沙发),摸鱼时偏好权重 ~4×——"这个会话就爱在阳台抽烟"是稳定人设,不是随机骰子 |
38
- | 🧭 就近原则 | 市民**生在自己的归属层**(自己的工位层;子代理用父代理的工位层),不再从大堂爬上来。休息活动以**归属层**为锚点就近找公共层(每 3 层就有),不会为了倒杯茶爬通天,**也不会随时间往低层漂**——12 楼的人永远回 F11 休息,不会一路沉到大堂。高层会话不下大堂:`下楼遛弯` 只有 F5 及以下才真下街,F6+ 改在就近休息层放风 |
37
+ | 🚬 习惯 | 每个 session 由 id hash 派生 **3 个固定偏好**(抽烟/咖啡/泡茶/翻冰箱/看书/街机/看鱼/撸猫/打电话/下楼遛弯/沙发/工位打游戏/工位刷手机),摸鱼时偏好权重 ~4×——"这个会话就爱在阳台抽烟"是稳定人设,不是随机骰子(工位打游戏/工位刷手机不挪窝,就在自己座位上摸鱼;面板文案里"工位刷手机"沿用了"打电话"那条文案) |
38
+ | 🧭 就近原则 | 市民**生在自己的归属层**(自己的工位层;子代理不论嵌套多深都解析到所在会话树的**根会话**工位层,不再掉进大堂)。休息活动以**归属层**为锚点找最近的公共层,不会为了倒杯茶爬通天,**也不会随时间往低层漂**——12 楼的人永远回 F11 休息,不会一路沉到大堂。街机/鱼缸/猫爬架这类稀有设施只在归属层 **±4 层**的漫游带内找最近一个,带外直接放弃改走最近的休息层;`下楼遛弯` 同样按漫游带算——归属层在 F3 及以下才真下街,F4+ 改在带内最近的休息层放风 |
39
+ | 📌 稳定工位 | 每个**根会话**的工位楼层只在**第一次出现**时分配一次(选最低空位),离开释放、回来复用——不会因为 `/api/show/state` 按 `updated_at DESC` 排序每次轮询都重排,否则摸鱼回来就会撞上"工位换人"的错觉 |
39
40
  | 💡 灯光 | 有人在的楼层灯亮(running 或 idle 都算——摸鱼也开灯),只有彻底 stopped 的层才熄;天黑后街灯/霓虹/远景窗火全亮 |
40
- | ↳ 小一号 | 子代理:生在并聚在父代理那层桌边,不占工位 |
41
+ | ↳ 小一号 | 子代理:生在所在会话树的**根会话**工位层(而不是直接父代理那层),干活时聚在**直接**父代理桌边,不占工位 |
41
42
 
42
43
  进出有戏:新会话直接出现在自己的工位层(从本层楼梯口走到工位,不再从街上爬通天);结束的走出门沿街远去淡出。
43
44
 
@@ -51,7 +52,8 @@ Halo 服务器运行态的**街景式**像素可视化:侧视、剖面的像素
51
52
  - **上下文仪表**:`134k / 200k (67%)` —— 分母是该会话的**真实** `maxContextTokens`
52
53
  - **委派链**:父/子会话可点击跳转,每行带 token 数和消息数
53
54
  - **点楼层**:该层的会话委派关系树(缩进、可点跳转)——工作层看"谁在这层干活、
54
- 带着哪些子代理",公共层看"谁在摸鱼"
55
+ 带着哪些子代理",公共层看"谁在摸鱼";**工位在这层的人即使正外出休息也照样算在这层**
56
+ (按归属工位层统计,不是按人此刻站在哪),点楼层永远能看全常驻名单
55
57
  - 点大楼:全员 roster + token 合计;点技能站:谁在用
56
58
 
57
59
  ## 街景与载具
@@ -77,6 +79,9 @@ Halo 服务器运行态的**街景式**像素可视化:侧视、剖面的像素
77
79
  - **纯净模式(zen)**:淡出所有 HUD(统计/动态/图例/缩放条/面板),只留街景,适合大屏常驻展示
78
80
  - **多语言(i18n)**:中文 / English 一键切;`?lang=en`/`?lang=zh` 直达,选择存 localStorage。
79
81
  运行时文案走 `t()`,静态 DOM 走 `data-i18n` 属性填充
82
+ - **背景音乐**:🎵/🔇 HUD 按钮(挨着 中/EN),纯 Web Audio 程序生成、零素材,
83
+ 默认开、偏好存 localStorage;受浏览器自动播放策略限制,AudioContext 在首次
84
+ 用户手势后才创建,关掉时真正 suspend(零 CPU),音频图与画面 rAF 循环完全独立
80
85
 
81
86
  ## 调试参数
82
87
 
@@ -107,10 +112,18 @@ js/
107
112
  ## 服务端配套
108
113
 
109
114
  - `GET /api/show/session?ws=&id=` — 只读会话详情:裁剪后的消息日志 + 真实
110
- token 上限。鉴权同 `/api/show/state`(x-token;非 full 只能看自己 workspace)
115
+ token 上限。鉴权同 `/api/show/state`(x-token;`full`/`observer` 可跨
116
+ workspace 读取,其余 accessLevel 只能看自己 workspace)
111
117
  - `/api/show/state` — 无活跃 UIState 的会话(idle/stopped/重启后)token
112
118
  从会话文件头读取(mtime 缓存,不随轮询刷盘),不显示 0;含 `messageCount` 字段
113
119
 
120
+ > **`observer` token 的权限面**:除了 `/show/state` 的聚合计数外,`observer`
121
+ > 还能调 `/show/session` 读取**任意 workspace** 任意会话的明细——最近 40 条
122
+ > 消息(每条截断到 600 字,tool input 截到 200 字)。它是"看板/监控"用的
123
+ > 全局只读角色,但这条 transcript 读取能力不止是计数;签发 observer token 时
124
+ > 要知道它相当于给了跨 workspace 的会话内容只读权限,不要把它当成纯粹的
125
+ > "数字仪表盘"凭证随手发放。
126
+
114
127
  ## 性能设计
115
128
 
116
129
  原则:一个纯只读可视化页面,轮询**不得对服务端会话生命周期产生任何副作用**,
@@ -296,8 +296,8 @@ general: # built-in declarer (the server itself
296
296
  max_message_slice: 800
297
297
  summarize_timeout_sec: 300
298
298
  sandbox:
299
- hidden_dirs: "~/.halo/secrets,~/.aws,~/.ssh,~/.gnupg,~/.docker"
300
- hidden_files: "~/.npmrc,~/.bash_history,~/.gitconfig"
299
+ hidden_dirs: "~/.halo/secrets,~/.aws,~/.ssh,~/.gnupg,~/.docker,~/.config/gh"
300
+ hidden_files: "~/.npmrc,~/.bash_history,~/.gitconfig,~/.git-credentials,~/.netrc"
301
301
  logging:
302
302
  level: warn
303
303
 
@@ -352,8 +352,8 @@ A value of the form `<<ENV_NAME>>` is replaced at read time with `process.env.EN
352
352
  | `general.limits.tool_result_ui_chars` | 65536 | Per-tool-result cap on the content **stored for UI display** (admin/web chat panel). Far larger than the LLM cap so a normal command's full output stays visible, but bounded so a multi-MB `cat` can't bloat the session file / WS payload / browser render; excess truncated with a marker pointing at `file_read` |
353
353
  | `general.limits.ws_event_buffer` | 5000 | Events buffered per detached WS session before oldest are dropped on reattach |
354
354
  | `general.limits.terminal_scrollback_bytes` | 50000 | Off-screen scrollback bytes retained per detached persistent terminal |
355
- | `general.sandbox.hidden_dirs` | `~/.halo/secrets,~/.aws,~/.ssh,~/.gnupg,~/.docker` | bwrap tmpfs overlay (Linux only) |
356
- | `general.sandbox.hidden_files` | `~/.npmrc,~/.bash_history,~/.gitconfig` | bwrap /dev/null bind (Linux only) |
355
+ | `general.sandbox.hidden_dirs` | `~/.halo/secrets,~/.aws,~/.ssh,~/.gnupg,~/.docker,~/.config/gh` | bwrap tmpfs overlay (Linux only) |
356
+ | `general.sandbox.hidden_files` | `~/.npmrc,~/.bash_history,~/.gitconfig,~/.git-credentials,~/.netrc` | bwrap /dev/null bind (Linux only) |
357
357
  | `general.logging.level` | warn | `debug` / `info` / `warn` / `error` |
358
358
 
359
359
  Schema source: [packages/server/src/settings-schema.ts](../../../packages/server/src/settings-schema.ts) `generalSection()`.