@turmind/halo 1.6.3 → 1.6.5
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 +66 -67
- package/admin-out/404.html +1 -1
- package/admin-out/_next/static/chunks/87-6a2716c98a819c4e.js +1 -0
- package/admin-out/_next/static/chunks/989-066a874961bd519f.js +1 -0
- package/admin-out/_next/static/chunks/app/page-812bcbb46db628b6.js +1 -0
- package/admin-out/_next/static/css/e890aa0d13e94290.css +1 -0
- package/admin-out/index.html +1 -1
- package/admin-out/index.txt +5 -5
- package/bin/halo.js +4 -0
- package/bundled-docs/design/architecture.md +1 -1
- package/bundled-docs/design/canvas-extensions.md +40 -9
- package/bundled-docs/design/cron.md +12 -4
- package/bundled-docs/design/halo-city.md +14 -149
- package/bundled-docs/design/observability.md +7 -5
- package/bundled-docs/design/storage.md +14 -7
- package/bundled-docs/design/stt-local.md +106 -0
- package/bundled-docs/design/web.md +1 -1
- package/bundled-docs/design/wechat.md +1 -1
- package/bundled-docs/dev/add-model-provider.md +2 -1
- package/bundled-docs/dev/api.md +13 -9
- package/bundled-docs/dev/deploy.md +114 -26
- package/bundled-docs/dev/desktop-packaging.md +50 -10
- package/bundled-docs/dev/env.md +4 -4
- package/bundled-docs/dev/logging.md +13 -2
- package/bundled-docs/dev/tools.md +2 -2
- package/bundled-docs/guide/agents.md +2 -2
- package/bundled-docs/guide/cli.md +20 -8
- package/bundled-docs/guide/getting-started.md +13 -5
- package/bundled-docs/guide/workspace.md +2 -0
- package/bundled-docs/requirements/agent.md +1 -1
- package/bundled-docs/requirements/chat.md +8 -0
- package/bundled-docs/requirements/explorer.md +14 -2
- package/bundled-docs/requirements/settings.md +2 -2
- package/bundled-docs/requirements/workspace.md +4 -0
- package/dist/index.js +3645 -1725
- package/package.json +4 -2
- package/templates/models/gemini.yaml +93 -0
- package/templates/skills/cron/SKILL.md +2 -1
- package/templates/skills/cron/manage-cron.py +2 -1
- package/admin-out/_next/static/chunks/147-d4200c70445aabb6.js +0 -1
- package/admin-out/_next/static/chunks/989-ddba0eb72566da23.js +0 -1
- package/admin-out/_next/static/chunks/app/page-7ffcbddb49dc56c4.js +0 -1
- package/admin-out/_next/static/css/3b4dcd0ac6b8eae8.css +0 -1
- /package/admin-out/_next/static/{k5zuJrivSdbaPifBatwdr → 8v1hCXbUqJhyMuK7LVeet}/_buildManifest.js +0 -0
- /package/admin-out/_next/static/{k5zuJrivSdbaPifBatwdr → 8v1hCXbUqJhyMuK7LVeet}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -8,25 +8,47 @@
|
|
|
8
8
|
|
|
9
9
|
**Throw in an idea. A team of agents builds it.**
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
A self-hosted AI agent team that works in your project folder. Bring your own model key and drive it from a browser, Slack, Telegram or the terminal. A primary agent breaks the work down and fans it out to sub-agents that run in parallel; every tool call shows up live, and you can interrupt, redirect or take over at any point. Everything the team knows and produces is plain files in the workspace — no hidden memory, no opaque state.
|
|
12
12
|
|
|
13
13
|

|
|
14
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>
|
|
15
15
|
|
|
16
|
+
https://github.com/user-attachments/assets/45f86359-2d83-4c61-b937-0747b184340e
|
|
17
|
+
|
|
18
|
+
<p align="center"><sub>One real run in 83 seconds: one prompt → the primary agent reads the brief, plans and starts four executors in parallel → Halo City shows the same run as a pixel town → the executors report back and the primary agent assembles the page, previewed in Canvas. 2 h 06 min of real time from prompt to done; sped-up and skipped stretches are marked on screen.</sub></p>
|
|
19
|
+
|
|
16
20
|
## Install
|
|
17
21
|
|
|
22
|
+
Halo runs on Linux (x64 / arm64), macOS and Windows, and needs **Node.js 22+**. Ubuntu 24.04's own `nodejs` package is 18 and won't work (`halo` refuses to start on it), so get 22 first:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs # Ubuntu / Debian
|
|
26
|
+
brew install node@22 # macOS (keg-only: add it to PATH as brew prints)
|
|
27
|
+
nvm install 22 # with nvm (or: fnm install 22)
|
|
28
|
+
```
|
|
29
|
+
|
|
18
30
|
```bash
|
|
19
31
|
npm install -g @turmind/halo # one binary, all subcommands
|
|
20
32
|
halo setup # interactive: password / port / model keys / optional skills
|
|
21
33
|
halo server start # → open http://localhost:9527
|
|
22
34
|
```
|
|
23
35
|
|
|
24
|
-
Bring any one model key — Anthropic, OpenAI (or any OpenAI-compatible endpoint), DeepSeek, Kimi, Qwen…
|
|
36
|
+
Bring any one model key — Anthropic, OpenAI (or any OpenAI-compatible endpoint), Gemini, DeepSeek, Kimi, Qwen… An AWS account is **not** required; Bedrock is just one of the [providers](#models) (and can use your AWS credential chain instead of a key).
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
- **`sudo`**: with a system-wide Node (apt / NodeSource), `npm install -g` needs `sudo`; with nvm / fnm it doesn't.
|
|
39
|
+
- **In `halo setup`**: at *Configure model provider keys now?* pick **Configure…** (the default). Pick your provider and paste the key, choose **── Done** (the last row; ↑ wraps to it), then press Enter on *Switch default agent to …*.
|
|
40
|
+
- **On a remote box**: run `halo server start -d` (plain `start` stays in the foreground and dies with your SSH session; on Linux with systemd, `-d` installs a user service that starts at boot), tunnel with `ssh -L 9527:localhost:9527 user@host`, and open `http://localhost:9527` on your machine. Don't open 9527 in a security group — see [Status & Limitations](#status--limitations).
|
|
41
|
+
- **Linux sandbox**: the `workspace` / `readonly` access levels need `sudo apt install bubblewrap`, and on Ubuntu 23.10+ / 24.04 also an [AppArmor profile](.halo/docs/dev/deploy.md#bubblewrap-on-ubuntu-2310-and-2404-apparmor). Without it the server warns at startup with the fix, `/api/health` shows `sandbox: null`, and non-full sessions can't run shell.
|
|
42
|
+
- **Upgrade**: `halo upgrade && halo server restart`. A server under systemd restarts through `systemctl`; a system unit ([deploy.md Option C](.halo/docs/dev/deploy.md#option-c-systemd-for-the-npm-install)) may need `sudo systemctl restart halo`. Bundled docs, agents and skills refresh on the next start.
|
|
43
|
+
- **Docker / CI**: `halo setup --non-interactive` with `HALO_DEFAULT_PROVIDER=deepseek` and `DEEPSEEK_API_KEY` set binds the built-in agents and writes the key's `<<DEEPSEEK_API_KEY>>` placeholder (never the key) into `~/.halo/secrets/settings.yaml`; keep the variable set for the server too ([deploy.md](.halo/docs/dev/deploy.md#non-interactive-docker--ci-details)). `HALO_PASSWORD` is the *admin* password only.
|
|
44
|
+
- **From source**: `pnpm install && pnpm build` (pnpm 11).
|
|
45
|
+
|
|
46
|
+
**Desktop app**: [GitHub releases](https://github.com/turmind/halo-agent/releases) carry a Windows x64 `.exe` and a macOS Apple Silicon `.dmg` (not every release has both) that bundle the server, admin and their own Node runtime — no `npm`, same `~/.halo/` data, so you can switch later. They're unsigned (macOS "damaged" → `sudo xattr -dr com.apple.quarantine /Applications/Halo.app`; Windows SmartScreen may warn).
|
|
27
47
|
|
|
28
48
|
> [!IMPORTANT]
|
|
29
|
-
> **First message fails with `Could not load credentials from any providers`?** The built-in
|
|
49
|
+
> **First message fails with `Could not load credentials from any providers`?** The built-in agents ship pointing at AWS Bedrock, and the *"Bind the default agent to a provider you just configured?"* step in `halo setup` was skipped. Re-run `halo setup` — it rebinds every built-in agent, the internal `/evo` ones included — or switch the model provider under **Agents → default**.
|
|
50
|
+
>
|
|
51
|
+
> **On EC2 / ECS with an instance role there is no error**: an unbound install quietly uses Bedrock Claude on that AWS account instead. Check which model answers in the footer of `halo cli -v "hi"`, or under **Agents → default**.
|
|
30
52
|
|
|
31
53
|
## Why Halo
|
|
32
54
|
|
|
@@ -52,11 +74,13 @@ my-project/
|
|
|
52
74
|
└─ src/ … # your actual project
|
|
53
75
|
```
|
|
54
76
|
|
|
55
|
-
|
|
77
|
+
Commit `.halo/` with your code and whoever clones it gets the same agents, skills and knowledge — the real files, not an export (they bring their own model key); `/workspace share` zips the config without sessions, memory or secrets. Initializing the repo from Halo's Source Control panel writes a `.gitignore` for sessions, logs, `tmp/` and databases; in an existing repo, add those yourself, and keep real keys out of `.halo/settings.yaml` (use `<<ENV>>` placeholders).
|
|
78
|
+
|
|
79
|
+
There's no vector database: `.halo/INDEX.md` is injected into the prompt every turn, and agents open the docs it points to when they need them. Halo is built the same way — this repo's own `.halo/` holds its dev, release and reviewer agents and the docs they work from, and most of its commits were made through Halo itself (they carry the `Co-Authored-By: halo` trailer).
|
|
56
80
|
|
|
57
81
|
### 🌐 One workspace, every screen
|
|
58
82
|
|
|
59
|
-
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
|
|
83
|
+
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 — channels are doors, the workspace is the room — and a full-access account can `/session switch` to pick up a conversation started elsewhere.
|
|
60
84
|
|
|
61
85
|
<p align="center">
|
|
62
86
|
<img src="assets/wechat-phone.jpg" alt="Halo in WeChat" width="270" />
|
|
@@ -67,71 +91,34 @@ Kick off a build in the browser, check progress from WeChat on the metro, drop a
|
|
|
67
91
|
|
|
68
92
|
### 👁 Watch it think
|
|
69
93
|
|
|
70
|
-
|
|
94
|
+
The primary agent's reasoning, every tool call (sub-agents' included) and every file change stream in real time; a sub-agent's full log opens from the **Sessions** tab and keeps updating while it runs. 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.
|
|
71
95
|
|
|
72
96
|

|
|
73
97
|
<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>
|
|
74
98
|
|
|
75
|
-
And when you'd rather have ambience than logs: [Halo City](#halo-city) renders the same runtime as a living pixel town.
|
|
76
|
-
|
|
77
99
|
## Also in the box
|
|
78
100
|
|
|
79
|
-
- **
|
|
80
|
-
- **IDE-grade admin** — chat + Monaco editor + file explorer + git panel + terminal (xterm.js) in one browser tab.
|
|
81
|
-
- **Skills** —
|
|
101
|
+
- **Per-agent models** — each agent picks its own provider and model: the built-ins ship with Claude Opus for the primary agent and Claude Sonnet for the executors it fans out, and routine sub-tasks can go to a cheap model. No code changes.
|
|
102
|
+
- **IDE-grade admin** — chat + Monaco editor + file explorer + git panel + terminal (xterm.js) in one browser tab, in four themes.
|
|
103
|
+
- **Skills and agents are files** — a skill is markdown injected on demand; an agent is a persona plus an `agent.yaml`. Workspace-scoped or global, no code required.
|
|
104
|
+
- **Extensions** — installable viewers and small apps from [halo-hub](https://github.com/turmind/halo-hub): 3D models, draw.io, Excalidraw, Jupyter notebooks, a meeting recorder and more. Besides opening files in the editor, an extension can add a page to the activity bar (Halo City) or a button to the chat input toolbar (voice input). Install with `/extension install <id>` or a zip under **Settings → Extensions** ([design](.halo/docs/design/canvas-extensions.md)).
|
|
105
|
+
- **Voice input** — `/extension install voice-input` adds a mic to the chat toolbar: click to record, click again to stop, and the text lands at the cursor; it never sends. Speech is transcribed on your own Halo server (SenseVoice-Small + Silero VAD via sherpa-onnx) in Mandarin, English, Cantonese, Japanese or Korean, with Mandarin written in Simplified characters. Audio never leaves your server and no cloud API is involved; the server downloads the ~240 MB model once, when the extension is installed or first used ([design](.halo/docs/design/stt-local.md)).
|
|
106
|
+
- **An optional face** — the ✨ button in the chat toolbar pins a particle face (`.halo/canvas/self.html`) in the editor, and the agent drives it with hidden markers in its replies: words, pictures and gestures alongside what it says. Off until you turn it on ([design](.halo/docs/design/express-self.md)).
|
|
82
107
|
- **Cron tasks** — scheduled agent runs (recurring or one-shot) whose output fans out to your chat channels.
|
|
83
|
-
- **
|
|
84
|
-
- **ACP adapter** — plug a halo workspace into Claude Code as a native ACP agent, or let one halo delegate to another.
|
|
108
|
+
- **Access levels** — `full` / `workspace` / `readonly` per session, enforced by an OS sandbox (bubblewrap on Linux, Seatbelt on macOS); a sub-agent never gets more access than its parent ([how levels are set](.halo/docs/guide/delegation-and-access.md#5-access-levels), [limits](#status--limitations)).
|
|
85
109
|
- **Structured sessions** — hierarchical parent ↔ child sessions with async coordination and auto-reports on completion.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
- ☁️ **AgentCore runtime mode** — run Halo as an Amazon Bedrock AgentCore Runtime (A2A protocol) with `halo agentcore`, on an EFS-backed workspace.
|
|
90
|
-
- 🎨 **Four UI themes** — dark, light, midnight, warm; synced server-side so every browser gets your pick.
|
|
91
|
-
- ⌨️ **TUI overhaul** — reworked input, verbose mode, and persistent history in the standalone terminal client.
|
|
92
|
-
- ✂️ **Graceful interrupts, fully surfaced** — interrupted tool calls are repaired and shown in the session UI instead of vanishing.
|
|
93
|
-
|
|
94
|
-

|
|
95
|
-
|
|
96
|
-
## Quick Start
|
|
97
|
-
|
|
98
|
-
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**.
|
|
99
|
-
|
|
100
|
-
| Prerequisite | Notes |
|
|
101
|
-
|---|---|
|
|
102
|
-
| Node.js >= 22 | the only hard system requirement |
|
|
103
|
-
| 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 |
|
|
104
|
-
| pnpm >= 9 | source builds only |
|
|
105
|
-
|
|
106
|
-
- **Bind your provider to the agent**: agents choose providers, and the built-in `default` agent ships pointing at AWS Bedrock. When you configure a different provider, `halo setup` ends by offering to rebind the built-in agents to it (with a single provider and no Bedrock keys, Enter accepts). Skipped it? Re-run `halo setup`, or switch once in **Agents → default → model provider**.
|
|
107
|
-
- **Upgrade**: `halo upgrade && halo server restart`. The startup check refreshes bundled docs / agents / skills automatically when the on-disk template version is behind.
|
|
108
|
-
- **Docker / CI**: `halo setup --non-interactive` and supply credentials via the `HALO_PASSWORD` env var; `HALO_DEFAULT_PROVIDER=<provider>` binds the built-in agents without a prompt.
|
|
109
|
-
- **From source**: `pnpm install && pnpm build`.
|
|
110
|
-
|
|
111
|
-
### Talk to it from curl
|
|
112
|
-
|
|
113
|
-
Every workspace can expose a token-authenticated HTTP + SSE endpoint — the Web channel, aka the "build your own UI" channel:
|
|
114
|
-
|
|
115
|
-
1. In the admin, open **Channels → Web → Add Account**, pick a workspace and access level, and copy the token (shown once).
|
|
116
|
-
2. Stream a conversation:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
curl -N -H "x-token: $TOKEN" -H "Content-Type: application/json" \
|
|
120
|
-
-d '{"message":"What files are in this workspace?"}' \
|
|
121
|
-
http://localhost:9527/api/web/chat
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
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).
|
|
110
|
+
- **Beyond one workspace** — [relay](.halo/docs/design/relay.md) work to another workspace on the same server, talk [A2A v1.0](.halo/docs/design/a2a.md) with other agent servers, or run headless as an Amazon Bedrock [AgentCore](.halo/docs/design/agentcore.md) Runtime with `halo agentcore`.
|
|
111
|
+
- **Observability** — set one OTLP endpoint and traces, metrics and logs (GenAI semantic conventions) go to any OpenTelemetry collector; `/api/metrics` serves Prometheus gauges ([design](.halo/docs/design/observability.md)).
|
|
125
112
|
|
|
126
113
|
## Models
|
|
127
114
|
|
|
128
|
-
Configured per-agent through one provider-agnostic runtime. AWS Bedrock Claude is the primary target; the rest are first-class.
|
|
115
|
+
Configured per-agent through one provider-agnostic runtime. AWS Bedrock Claude is the primary target; the rest are first-class. `/extension models` pulls updated provider configs from the hub without a Halo release.
|
|
129
116
|
|
|
130
117
|
| Provider | Notes |
|
|
131
118
|
|---|---|
|
|
132
119
|
| **AWS Bedrock Claude** | Primary — Bedrock Invoke API |
|
|
133
120
|
| AWS Bedrock Mantle | OpenAI GPT-class models via Bedrock |
|
|
134
|
-
| AWS Bedrock OpenAI-compatible | GPT
|
|
121
|
+
| AWS Bedrock OpenAI-compatible | GPT, Grok, Kimi and GLM models via the bedrock-runtime OpenAI Responses API |
|
|
135
122
|
| Anthropic | Direct API |
|
|
136
123
|
| OpenAI | Direct / any OpenAI-compatible endpoint |
|
|
137
124
|
| DeepSeek | |
|
|
@@ -142,12 +129,13 @@ Configured per-agent through one provider-agnostic runtime. AWS Bedrock Claude i
|
|
|
142
129
|
| Hunyuan (Tencent) | |
|
|
143
130
|
| Doubao (Volcengine) | |
|
|
144
131
|
| Zhipu AI (GLM) | GLM-5.3 family; vision on the Flash models |
|
|
132
|
+
| Google Gemini | Gemini API (OpenAI-compatible endpoint) — 3.8 Flash, 3.5 Flash-Lite |
|
|
145
133
|
|
|
146
134
|

|
|
147
135
|
|
|
148
136
|
## Channels
|
|
149
137
|
|
|
150
|
-
|
|
138
|
+
Telegram, Slack, Feishu, WeCom and WeChat all connect outbound — no public URL or open port needed. New channel accounts start at `readonly`; each [onboarding guide](.halo/docs/guide/channels/) says who can reach the bot.
|
|
151
139
|
|
|
152
140
|
| Channel | Transport | Notes |
|
|
153
141
|
|---|---|---|
|
|
@@ -159,51 +147,62 @@ Every channel shares the same workspace and session state. Onboarding guides liv
|
|
|
159
147
|
| **Feishu / Lark** | Long-connect | `appId` + `appSecret` |
|
|
160
148
|
| **WeCom** | Long-connect | `botId` + `secret` (智能机器人, no HTTP send API) |
|
|
161
149
|
| **WeChat** | QR bind | Scan to bind, mobile access |
|
|
162
|
-
| **ACP adapter** | stdio JSON-RPC |
|
|
150
|
+
| **ACP adapter** | stdio JSON-RPC | `halo acp` bridges ACP editors (Zed, JetBrains IDEs) onto the Web channel — [guide](.halo/docs/guide/channels/acp.md) |
|
|
163
151
|
|
|
164
152
|

|
|
165
153
|
<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>
|
|
166
154
|
|
|
155
|
+
### Talk to it from curl
|
|
156
|
+
|
|
157
|
+
The Web channel is a token-authenticated HTTP + SSE endpoint for your own UI or scripts. In the admin, open **Channels → Web → Add Account**, pick a workspace and access level, and copy the token (shown once). Then:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
curl -N -H "x-token: $TOKEN" -H "Content-Type: application/json" \
|
|
161
|
+
-d '{"message":"What files are in this workspace?"}' \
|
|
162
|
+
http://localhost:9527/api/web/chat
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
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).
|
|
166
|
+
|
|
167
167
|
## Halo City
|
|
168
168
|
|
|
169
|
-
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**.
|
|
169
|
+
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**. Since 1.6.5 it installs as a [halo-hub extension](https://github.com/turmind/halo-hub/tree/main/extensions/halo-city): `/extension install halo-city` adds a Halo City entry to the activity bar that opens straight into the city on your admin login (no token to paste), and ⛶ at the top right goes fullscreen — see the [design notes](.halo/docs/design/halo-city.md).
|
|
170
170
|
|
|
171
171
|

|
|
172
172
|
<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>
|
|
173
173
|
|
|
174
|
-
Lives at [`halo-city/`](halo-city/) (plain static files, no build) — see the [design notes](.halo/docs/design/halo-city.md).
|
|
175
|
-
|
|
176
174
|
## Tech Stack
|
|
177
175
|
|
|
178
176
|
- **Monorepo**: pnpm workspace (`core`, `server`, `admin`, `cli`, `desktop`, `acp-adapter`)
|
|
179
|
-
- **Backend**: Hono + WebSocket, single Node.js process on port 9527
|
|
177
|
+
- **Backend**: Hono + WebSocket, single Node.js 22+ process on port 9527 (ESM, TypeScript strict)
|
|
180
178
|
- **Frontend**: Next.js 15 static export, served directly by Hono
|
|
181
179
|
- **Agent**: custom orchestration loop, provider-agnostic `ModelRuntime` interface
|
|
182
180
|
- **Storage**: SQLite + Drizzle ORM — no external services to stand up
|
|
183
|
-
- **Runtime**: Node.js 22+, ESM, TypeScript strict
|
|
184
181
|
|
|
185
182
|
## Docs
|
|
186
183
|
|
|
187
184
|
- [`.halo/INDEX.md`](.halo/INDEX.md) — project overview + doc index
|
|
185
|
+
- [`.halo/docs/guide/`](.halo/docs/guide/README.md) — user guide
|
|
188
186
|
- [`.halo/docs/requirements/overview.md`](.halo/docs/requirements/overview.md) — product concept
|
|
189
187
|
- [`.halo/docs/design/architecture.md`](.halo/docs/design/architecture.md) — backend architecture
|
|
190
188
|
- [`.halo/docs/design/evolution.md`](.halo/docs/design/evolution.md) — self-evolution design
|
|
191
189
|
- [`.halo/docs/guide/channels/`](.halo/docs/guide/channels/) — per-channel onboarding guides
|
|
192
190
|
- [`.halo/docs/dev/deploy.md`](.halo/docs/dev/deploy.md) — deployment (systemd / Nginx)
|
|
193
191
|
- [`.halo/docs/dev/env.md`](.halo/docs/dev/env.md) — env vars, build commands
|
|
192
|
+
- [`CHANGELOG.md`](CHANGELOG.md) — what changed in each release
|
|
194
193
|
- [`CLAUDE.md`](CLAUDE.md) — development instructions for Claude Code
|
|
195
194
|
|
|
196
195
|
## Status & Limitations
|
|
197
196
|
|
|
198
197
|
Halo is young — treat it as an early-stage project:
|
|
199
198
|
|
|
200
|
-
- **
|
|
201
|
-
- **
|
|
202
|
-
- **
|
|
203
|
-
- **
|
|
199
|
+
- **The sandbox guards writes and credentials, not the network.** In `workspace` / `readonly` sessions, bubblewrap (Linux) or Seatbelt (macOS) limits writes to the workspace and temp dirs (`readonly`: temp dirs only) and hides `~/.halo/secrets`, `~/.ssh`, `~/.aws` and similar paths; the rest of the host stays readable and outbound connections work. The threat model is accidental damage and path escape by a trusted agent — not containing a malicious skill or extension, or a prompt-injected session sending out what it can read.
|
|
200
|
+
- **Windows hosts have no sandbox.** There a `workspace` session is effectively `full`, and `readonly` can read any path the halo process can — don't hand out non-`full` channel tokens on a Windows host expecting isolation ([dev/tools.md](.halo/docs/dev/tools.md)).
|
|
201
|
+
- **The admin is single-tenant, on plain HTTP, on all interfaces.** One password (5 failed logins lock that IP out for 15 minutes); whoever holds the admin cookie controls the server — every workspace, shell as the server user, every channel credential. Keep port 9527 behind a firewall, VPN or SSH tunnel, or a reverse proxy with TLS ([deploy.md §10](.halo/docs/dev/deploy.md#10-optional-nginx-reverse-proxy)), and give other people channel accounts with their own access levels instead of the admin login.
|
|
202
|
+
- **Tests are unit/regression-level.** CI runs them on every push and PR to `main`; there's no end-to-end or integration suite yet.
|
|
204
203
|
- **APIs and on-disk formats may still change between versions.** Expect rough edges while things stabilize.
|
|
205
204
|
|
|
206
|
-
If you hit something broken or surprising, please open an issue — early feedback is genuinely useful right now.
|
|
205
|
+
If you hit something broken or surprising, please open an issue — early feedback is genuinely useful right now. Security reports go through [SECURITY.md](SECURITY.md).
|
|
207
206
|
|
|
208
207
|
## Contributing
|
|
209
208
|
|
package/admin-out/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
1
|
+
<!DOCTYPE html><!--8v1hCXbUqJhyMuK7LVeet--><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/7b736202f0b1dbfd.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/e890aa0d13e94290.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-74f577c1b094f942.js"/><script src="/_next/static/chunks/1b86ba38-c29611e086b2ce25.js" async=""></script><script src="/_next/static/chunks/698-19872069fed27164.js" async=""></script><script src="/_next/static/chunks/main-app-340a5b58ed229c4d.js" async=""></script><script src="/_next/static/chunks/989-066a874961bd519f.js" async=""></script><script src="/_next/static/chunks/app/layout-ea161287d934ba96.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_d8ebd1 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-74f577c1b094f942.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[58321,[\"989\",\"static/chunks/989-066a874961bd519f.js\",\"177\",\"static/chunks/app/layout-ea161287d934ba96.js\"],\"ThemeProvider\"]\n3:I[24554,[\"989\",\"static/chunks/989-066a874961bd519f.js\",\"177\",\"static/chunks/app/layout-ea161287d934ba96.js\"],\"AppI18nProvider\"]\n4:I[63693,[],\"\"]\n5:I[74713,[],\"\"]\n6:I[23632,[],\"OutletBoundary\"]\n8:I[86889,[],\"AsyncMetadataOutlet\"]\na:I[23632,[],\"ViewportBoundary\"]\nc:I[23632,[],\"MetadataBoundary\"]\nd:\"$Sreact.suspense\"\nf:I[1935,[],\"\"]\n:HL[\"/_next/static/media/e4af272ccee01ff0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/7b736202f0b1dbfd.css\",\"style\"]\n:HL[\"/_next/static/css/e890aa0d13e94290.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"8v1hCXbUqJhyMuK7LVeet\",\"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/7b736202f0b1dbfd.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/e890aa0d13e94290.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_d8ebd1 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[88809,[],\"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>
|