@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
|
@@ -110,6 +110,8 @@ git diff HEAD~1 | halo cli -w /path/to/review-ws "review this diff"
|
|
|
110
110
|
halo cli "check for issues" && echo "OK" || echo "FAILED"
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
+
When stdin is not a TTY, piped input is appended after the positional prompt. With a positional prompt, stdin is only read if its first data arrives within 0.5 s — then to EOF, however long it takes. Otherwise it's ignored, so an open-but-idle stdin (scripts, CI, cron, `ssh host 'halo cli …'` without `-t`) no longer hangs the run. A producer that takes longer than that to print anything gets ignored too; capture it first (`out=$(slow-cmd); halo cli "summarize" <<<"$out"`). Without a positional prompt, stdin *is* the prompt: `halo cli` waits for EOF, and after 1 s of silence prints one `waiting for the prompt on stdin` hint to stderr.
|
|
114
|
+
|
|
113
115
|
## TUI Mode (interactive)
|
|
114
116
|
|
|
115
117
|
```bash
|
|
@@ -233,13 +235,22 @@ Normally run for you by `/extension models`, which downloads the hub's newest `m
|
|
|
233
235
|
## Server Mode (background daemon)
|
|
234
236
|
|
|
235
237
|
`halo server start|stop|restart|status|logs` manages a local server from the
|
|
236
|
-
same binary. `start -d` runs it
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
238
|
+
same binary. On Linux with systemd, `start -d` (and `restart`) runs it as the
|
|
239
|
+
user unit `~/.config/systemd/user/halo.service`, written and enabled for you
|
|
240
|
+
with linger on, so it starts at boot and comes back 5s after a crash. Your
|
|
241
|
+
shell's environment is saved to `~/.halo/secrets/server.env` for it. A system
|
|
242
|
+
unit that already runs `halo server start` as you is started instead.
|
|
243
|
+
`stop|restart|status` on a unit-run server go through `systemctl`, and print
|
|
244
|
+
the `sudo systemctl …` line when a system unit needs it. See
|
|
245
|
+
[dev/deploy.md](../dev/deploy.md#option-c-systemd-for-the-npm-install).
|
|
246
|
+
|
|
247
|
+
Elsewhere (macOS, Windows, Linux without systemd, a redirected HOME, an
|
|
248
|
+
unreachable user manager) `start -d` runs it in the background **with a bounded
|
|
249
|
+
respawn supervisor**: the detached process supervises the server and brings it
|
|
250
|
+
back on a crash (non-zero exit, or a kill by anything other than
|
|
251
|
+
SIGTERM/SIGINT), at most 5 times per 5 minutes with a 2s pause, logging each
|
|
252
|
+
decision as `[respawn] …` into `~/.halo/logs/server.log`. `halo server stop` is
|
|
253
|
+
recognized as intentional and never respawns. Full policy in
|
|
243
254
|
[dev/deploy.md](../dev/deploy.md#crash-semantics--why-restarton-failure-is-load-bearing).
|
|
244
255
|
|
|
245
256
|
## AgentCore runtime (`halo agentcore`)
|
|
@@ -274,7 +285,8 @@ packages/cli/
|
|
|
274
285
|
src/
|
|
275
286
|
index.ts — Entry: subcommand dispatch (tui/cli/agents/sessions/server/setup/upgrade/acp), SIGINT/SIGTERM handling
|
|
276
287
|
harness.ts — Shared agent harness wrapping SessionManager
|
|
277
|
-
server-supervisor.ts — Respawn policy for `halo server start -d`
|
|
288
|
+
server-supervisor.ts — Respawn policy for `halo server start -d` off systemd
|
|
289
|
+
server-systemd.ts — Linux systemd path: user unit + env snapshot, unit routing for stop/restart/status
|
|
278
290
|
cli.ts — Non-interactive: stdin/args → agent → stdout → exit
|
|
279
291
|
tui.tsx — Interactive entry: mounts the ink app
|
|
280
292
|
tui/
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
What to do the first time you open Halo.
|
|
4
4
|
|
|
5
|
+
Not installed yet? The [README Install section](../../../README.md#install) covers the three things a fresh box trips on: Node 22 first (Ubuntu 24.04's own `nodejs` is 18 and won't work), `sudo npm install -g` with a system-wide Node, and keeping **Configure…** (the default) at `halo setup`'s key step before binding the default agent.
|
|
6
|
+
|
|
5
7
|
## Log in
|
|
6
8
|
|
|
7
9
|
Open `http://localhost:9527` (or your deployment URL) in a browser and enter the password.
|
|
@@ -14,6 +16,8 @@ Open `http://localhost:9527` (or your deployment URL) in a browser and enter the
|
|
|
14
16
|
|
|
15
17
|
After login, you land in the workspace. A URL with `?folder=/abs/path` opens that directory directly; without `?folder`, Halo reopens the last workspace you used, or your home directory if there isn't one — everything still works.
|
|
16
18
|
|
|
19
|
+
`halo cli` / `halo tui` use the current directory as the workspace, so running them in `$HOME` makes `~/.halo` itself a workspace (`halo.db`, `sessions/`, `memory/`, `canvas/` appear next to `global/` and `secrets/`). `cd` into a project, or pass `-w <dir>`, to keep them apart.
|
|
20
|
+
|
|
17
21
|
The Explorer top bar has two ways to switch workspace:
|
|
18
22
|
- **Type an absolute path** + Enter — invalid paths raise an error
|
|
19
23
|
- **Click the 📁🔍 button** — opens a VS Code-style directory picker: single click to select, double click to enter, ArrowUp to go up, 🏠 for home, paste paths into the top input
|
|
@@ -65,21 +69,25 @@ After `halo setup`:
|
|
|
65
69
|
```
|
|
66
70
|
~/.halo/
|
|
67
71
|
├── global/ ← server-managed, see overwrite policy below
|
|
72
|
+
│ ├── .template-version ← seed version stamp, compared on every start
|
|
68
73
|
│ ├── INSTRUCTIONS.md ← refreshed on upgrade
|
|
69
74
|
│ ├── prompts/{bootstrap,all,root}/ ← refreshed on upgrade
|
|
70
75
|
│ ├── models/<provider>.yaml ← refreshed on upgrade
|
|
71
76
|
│ ├── docs/ ← refreshed on upgrade (bundled platform docs)
|
|
72
77
|
│ ├── agents/ ← built-in ids refreshed; user-added ones untouched
|
|
73
|
-
│
|
|
74
|
-
|
|
78
|
+
│ ├── skills/ ← built-in ids refreshed; user-added ones untouched
|
|
79
|
+
│ ├── aliases.yaml ← command aliases, seeded once, never overwritten
|
|
80
|
+
│ └── extensions/ ← preview extensions, created empty
|
|
81
|
+
└── secrets/ ← mode 700, files 600; never overwritten after first creation
|
|
75
82
|
├── config.yaml ← leaf-merged: new server knobs added, existing values kept
|
|
76
|
-
|
|
77
|
-
└── channels/channels.db ← per-channel account state
|
|
83
|
+
└── settings.yaml ← created empty if missing; otherwise untouched
|
|
78
84
|
```
|
|
79
85
|
|
|
86
|
+
The first `halo server start` adds the runtime state: `global/{a2a,cron,evo,runs}.db`, `global/logs/`, `global/models.d/`, `global/server.lock`, `global/server.stop` (after a stop), and `secrets/channels/channels.db` (per-channel account state).
|
|
87
|
+
|
|
80
88
|
**When does "refreshed on upgrade" actually run?** `halo setup` always re-runs the seed; the server's startup check — and the same check at the start of `halo cli` / `halo tui` — also re-runs it automatically when `~/.halo/global/.template-version` is behind the bundled `TEMPLATE_VERSION`. So the routine flow `halo upgrade && halo server restart` is enough — no need to remember `halo setup` — and a CLI-only user just runs `halo cli` / `halo tui` after `halo upgrade`.
|
|
81
89
|
|
|
82
|
-
**Server-refreshed**: `INSTRUCTIONS.md`, `prompts/`, `models/`, `docs/`, the built-in agent ids (`default`, `executor`, `deep-executor
|
|
90
|
+
**Server-refreshed**: `INSTRUCTIONS.md`, `prompts/`, `models/`, `docs/`, the built-in agent ids (`default`, `executor`, `deep-executor` plus the internal agents), and the built-in skill ids (`agent`, `skill`, `workspace`, `cron`, `send-file`, `self`, `aws-knowledge`, `web-search`, `halo`, `extension`). To customize one, copy it into the workspace scope (`<project>/.halo/...`) — workspace replaces global at runtime.
|
|
83
91
|
|
|
84
92
|
**Never overwritten**: anything else under `agents/` or `skills/` (your own creations), and everything under `secrets/`.
|
|
85
93
|
|
|
@@ -64,6 +64,8 @@ VS Code style:
|
|
|
64
64
|
|
|
65
65
|
Right-click menu: New File / New Folder / Open in Integrated Terminal / Reveal in File Manager (desktop app only) / Open to the Side / Download / Rename / Delete / Open as Workspace (folders).
|
|
66
66
|
|
|
67
|
+
**Download a folder**: right-click a folder (or the empty area for the whole workspace) → Download. A confirm shows the approximate size and file count; `node_modules`, `.git` and other build/cache folders are left out unless you tick the checkbox, and `.env` files, secrets (plus common credential stores: ~/.kube, cloud CLI configs, shell histories) and Halo's session data are always left out. You get one `<folder>.zip`; anything left out is listed in `_halo-excluded.txt` inside it. Folders with more than 200,000 files can't be downloaded in one go — pick a subfolder.
|
|
68
|
+
|
|
67
69
|
**Quick Open**: `Cmd/Ctrl+P` opens fuzzy file search — server-side, full-project, independent of expansion state.
|
|
68
70
|
|
|
69
71
|
### Skipped directories
|
|
@@ -93,6 +93,6 @@ API: `GET/PUT /api/agent-configs/:id/md/:fileType`, `GET /api/agent-configs/:id/
|
|
|
93
93
|
- **Not rendered for internal agents** (`internal: true`) — they're delegated to by other agents, never driven directly
|
|
94
94
|
|
|
95
95
|
### Internal agents
|
|
96
|
-
Agents flagged `internal: true` in agent.yaml (e.g. `__evo_agent__`, `__apply_agent__`, `__score__
|
|
96
|
+
Agents flagged `internal: true` in agent.yaml (e.g. `__evo_agent__`, `__apply_agent__`, `__score__`) are platform tooling. They are hidden from every user-facing surface: the delegation roster, `/session new` default pick, the chat agent selector, the Cron job agent picker and `halo cli`'s agent list (`halo agents`) — and have no Test button. They stay editable in the management sidebar's collapsed **Internal** group.
|
|
97
97
|
|
|
98
98
|
Replaces the old built-in test chat panel, giving a more realistic environment (full workspace tools + session persistence).
|
|
@@ -144,6 +144,14 @@ Constraints:
|
|
|
144
144
|
- Desktop: screen share needs macOS **Screen Recording** permission; the camera prompts for **Camera** permission on first use, with an "Open Settings" path if previously denied. Browser: the page must be served over HTTPS or from localhost (`getDisplayMedia` / `getUserMedia` are absent elsewhere, so the buttons don't render); a denied camera shows a hint pointing at the address bar's site settings.
|
|
145
145
|
- Binding is **in-memory only** and shared by all chat tabs — a page reload or restart requires re-selecting.
|
|
146
146
|
|
|
147
|
+
### Extension buttons (chat bar)
|
|
148
|
+
An installed extension whose manifest declares `chatbar` (e.g. the hub's voice input) adds one button to the input toolbar, right after the capture buttons; several sort by `chatbar.order`, then id. No such extension installed = toolbar unchanged; install / uninstall shows up without a reload.
|
|
149
|
+
- **Button**: 32×32 like Attach; the extension's icon in the toolbar colour (a microphone when it has none); tooltip = its title (Chinese UI: `title_zh` → `title` → name; English: `title` → name). Primary-coloured while its panel is open.
|
|
150
|
+
- **Panel**: opens above the whole input box, floating over the editor if the chat is docked low (up to 420 px wide, nearly full width on a phone; height from the manifest, default 160 px, shrunk to fit the space above the input — never so far that its title bar and × leave the screen) with a thin title bar and ×. It follows the input when the dock is resized or the floating chat is moved; switching chat tabs, or hiding the chat (terminal tab, collapsed dock), closes it. One panel at a time — another extension's button switches to it. Its own button again, ×, or Esc closes it (Esc in the text box closes the panel first, before the usual "Esc interrupts the turn"). Clicking elsewhere does **not** close it, so the user can keep dictating while editing the draft.
|
|
151
|
+
- **Lifetime**: the extension runs only while its panel is open; closing stops it (the microphone with it). An extension that says it is still busy (e.g. the last sentence is being recognised) gets to finish first: on its button / × / Esc the panel stays (button still lit, text still arriving) until it is done — at most 35 s; closing it again closes it at once. Switching chat tabs, hiding the chat, or opening another extension's panel closes it at once. Uninstalling it while open closes the panel. An extension that doesn't answer within 10 s shows "did not respond" with Retry.
|
|
152
|
+
- **Text into the draft**: the extension can insert text at the cursor (replacing a selection), exactly as given; the cursor lands after it and keyboard focus stays in the panel. It works while the agent is replying (it only edits the draft). The extension can **never send** — the user always presses Send.
|
|
153
|
+
- Settings → Extensions labels such an extension "Chat bar". Design: [design/canvas-extensions.md → Chat-bar entries](../design/canvas-extensions.md#chat-bar-entries).
|
|
154
|
+
|
|
147
155
|
### The agent's face (`self.html`)
|
|
148
156
|
A second channel beyond text: a visual space the agent drives in real time to express itself. Works everywhere (pure HTML/canvas, no Electron dependency) — desktop **and** plain browser.
|
|
149
157
|
|
|
@@ -66,7 +66,7 @@ VS Code-style highlight selection (no checkboxes):
|
|
|
66
66
|
|
|
67
67
|
### Right-click menu
|
|
68
68
|
|
|
69
|
-
Items shown depend on the click target. With several items selected the menu offers only Delete; on the workspace root row only New File / New Folder / Open in Integrated Terminal / Reveal in File Manager apply:
|
|
69
|
+
Items shown depend on the click target. With several items selected the menu offers only Delete; on the workspace root row only New File / New Folder / Open in Integrated Terminal / Reveal in File Manager / Download apply:
|
|
70
70
|
|
|
71
71
|
| Action | Shown when | API / behavior |
|
|
72
72
|
|---|---|---|
|
|
@@ -74,13 +74,25 @@ Items shown depend on the click target. With several items selected the menu off
|
|
|
74
74
|
| Open in Integrated Terminal | Always | Spawns a terminal at the target dir (or file's parent) |
|
|
75
75
|
| Reveal in File Manager | Desktop app only | Opens the OS file manager (Finder / Explorer / Linux FM) at the target — a folder opens itself, a file is highlighted in its parent dir. Hidden in a plain browser (gated on the `window.haloReveal` IPC bridge exposed by the desktop preload) |
|
|
76
76
|
| Open to the Side | File or bundle directory | Splits the editor and opens the file (or bundle) in the right pane |
|
|
77
|
-
| Download | File
|
|
77
|
+
| Download | File, folder, workspace root | File: `GET /api/files/download?path=...`. Folder / root: estimate + confirm, then one streamed zip — see [Folder download](#folder-download) |
|
|
78
78
|
| Rename | Single file/folder | `POST /api/files/rename` |
|
|
79
79
|
| Delete | Single or multi-select | `DELETE /api/files?path=...` (with confirm) |
|
|
80
80
|
| Open as Workspace | Folder only | Switches the active workspace to that folder, reusing the path-input switch flow (validate → persist → reload). Shown at the bottom of the menu |
|
|
81
81
|
|
|
82
82
|
The menu auto-clamps to the viewport, so right-clicking near the window edge does not clip the bottom items.
|
|
83
83
|
|
|
84
|
+
### Folder download
|
|
85
|
+
Download on a folder (or the workspace root) zips it on the server while it streams — nothing is staged on disk or in memory (`GET /api/files/download-folder`, see [dev/api.md](../dev/api.md#files)).
|
|
86
|
+
- Clicking Download first fetches an estimate (`estimate=1`, a walk without reading contents) and opens a confirm: `≈ <size> · <n> files`, what is excluded by default with counts (node_modules / .git by name, the rest as "other build/cache folders"), how many items are always excluded or skipped
|
|
87
|
+
- Checkbox "Include node_modules, .git and other build/cache folders" (`include=excluded`) re-fetches the estimate when toggled
|
|
88
|
+
- More than 200,000 files, or a scan longer than 10 s → the dialog shows the server's 413 message ("download a subfolder instead") and Download stays disabled
|
|
89
|
+
- Confirm → a plain `<a href>` download of `<folder name>.zip` (workspace root: the workspace dir name); the browser / desktop default save flow takes it from there
|
|
90
|
+
- **Excluded by default**: any folder whose name is in the file watcher's ignore list (`IGNORED_SEGMENTS`: `.git`, `node_modules`, `dist`, `.venv`, `__pycache__`, caches …)
|
|
91
|
+
- **Always excluded**, checkbox or not: the sandbox hidden host paths (`~/.halo/secrets`, `~/.ssh`, `~/.aws` … — a home dir can be a workspace), workspace runtime state (`.halo/sessions`, logs, evo, the dbs — also in a nested workspace's `.halo/`), `.halo/settings.yaml`, any `.env` / `.env.*` file, plus common credential stores (~/.kube, cloud CLI configs, shell histories)
|
|
92
|
+
- **Names a zip can't hold** (containing `\`, or a top-level `C:`-style prefix) are skipped and listed as unreadable
|
|
93
|
+
- **Symlinks**: folder links are never followed; a file link is included only when its target stays inside the workspace and is not excluded
|
|
94
|
+
- When anything was left out, the zip carries `_halo-excluded.txt` at its root: excluded paths grouped by reason (a pruned folder is listed once, not its contents; capped at 1000 per reason plus a count), including unreadable files and skipped links
|
|
95
|
+
|
|
84
96
|
### Modification indicator
|
|
85
97
|
Files with unsaved editor edits show a coloured dot in the tree (synced from `editorStore.modifiedPaths`).
|
|
86
98
|
|
|
@@ -102,7 +102,7 @@ An installed canvas extension declares its own config in its manifest: `"setting
|
|
|
102
102
|
|
|
103
103
|
### General — built-in
|
|
104
104
|
|
|
105
|
-
Declared in [packages/server/src/settings-schema.ts](../../../packages/server/src/settings-schema.ts) `generalSection()`. The server itself is the implicit declarer. Keys: `language`, `theme`, `agent.max_retries`, `server.*`, `session.*`, `compact.*`, `sandbox.*`, `logging.*`, `observability.*` (read once at boot — restart to apply), `evolution.*`, `limits.*`. All `general.*` keys are `globalOnly`: `config.ts` resolves them through `settingsValue()` against `~/.halo/secrets/settings.yaml` only, so a workspace `settings.yaml` cannot override them. Per-workspace layering applies to namespaced `params` / `secrets` (`getServerSecret(ns, key, workspaceRoot)`, `substituteSecrets`).
|
|
105
|
+
Declared in [packages/server/src/settings-schema.ts](../../../packages/server/src/settings-schema.ts) `generalSection()`. The server itself is the implicit declarer. Keys: `language`, `theme`, `agent.max_retries`, `server.*`, `session.*`, `compact.*`, `sandbox.*`, `logging.*`, `observability.*` (read once at boot — restart the server to apply; cron / evolution runs pick a change up on their next run), `evolution.*`, `limits.*`. All `general.*` keys are `globalOnly`: `config.ts` resolves them through `settingsValue()` against `~/.halo/secrets/settings.yaml` only, so a workspace `settings.yaml` cannot override them. Per-workspace layering applies to namespaced `params` / `secrets` (`getServerSecret(ns, key, workspaceRoot)`, `substituteSecrets`).
|
|
106
106
|
|
|
107
107
|
`server.trust_proxy` (boolean, default `false`, `globalOnly`): whether the brute-force rate limiter (`middleware/brute-force.ts` `getClientIp`) trusts the `x-forwarded-for` header for client IP resolution. Direct-connect deployments leave it `false` and get the socket address. Behind a reverse proxy (nginx / Cloudflare / etc.), set it to `true` so the real client IP is honored instead of the proxy's — but only when that proxy is one you control and rewrites the header itself, otherwise a client can forge XFF to dodge lockouts.
|
|
108
108
|
|
|
@@ -123,7 +123,7 @@ There is no "default provider" setting: a newly created agent's `model:` is a co
|
|
|
123
123
|
|
|
124
124
|
**Advanced fold**: on the General page, `language` and `theme` are shown in the open; every other General field is in an "Advanced" area, collapsed by default (schema flag `advanced: true`, set in `generalSection()`).
|
|
125
125
|
|
|
126
|
-
**Restart-required fields**: `agent.max_retries`, `session.max_queue_size`, `session.max_nesting_depth`, `compact.keep_messages`, `compact.max_summary_input`, `compact.max_message_slice`, `logging.level` and the four `observability.*` keys are read once at server start (object literals in `config.ts`; observability is mapped onto `OTEL_*` env by `initObservability()` at boot). They carry `restartRequired: true`; after a save or Reset of one of them the Settings page shows a notice above the section listing the saved keys and saying the Halo server must be restarted (dismissable; it stays until dismissed). Every other General key is read live.
|
|
126
|
+
**Restart-required fields**: `agent.max_retries`, `session.max_queue_size`, `session.max_nesting_depth`, `compact.keep_messages`, `compact.max_summary_input`, `compact.max_message_slice`, `logging.level` and the four `observability.*` keys are read once at server start (object literals in `config.ts`; observability is mapped onto `OTEL_*` env by `initObservability()` at boot). For observability that applies to the server's own exporter only: cron / evolution runs are `halo cli` children that don't inherit those settings-derived `OTEL_*` vars (`cleanChildEnv()` strips them), so they use a new value on their next run — as the field descriptions say. They carry `restartRequired: true`; after a save or Reset of one of them the Settings page shows a notice above the section listing the saved keys and saying the Halo server must be restarted (dismissable; it stays until dismissed). Every other General key is read live.
|
|
127
127
|
|
|
128
128
|
### Field attributes
|
|
129
129
|
|
|
@@ -42,6 +42,10 @@ The Bottom Panel (Chat + Terminal) can also be **floated** into a draggable wind
|
|
|
42
42
|
|
|
43
43
|
The Source Control entry is hidden in workspaces that are not git repos.
|
|
44
44
|
|
|
45
|
+
**Extension entries.** An installed [canvas extension](../design/canvas-extensions.md#activity-bar-entries) whose manifest declares `activity` adds one button after Cron (several sort by the manifest's `order`, then id; the built-in tabs never move). It uses the extension's icon (tinted like the built-in icons; a puzzle piece when it has none) and its title / description in the hover drawer, in the admin's language. Clicking it shows the extension's page full-width in the main area with no sidebar, like Agents / Settings; leaving the tab closes the page (anything it was playing or refreshing stops). The last-used page is restored after a reload; if that extension has been removed, or doesn't run on this device, the workspace opens on Explorer instead. With no such extension installed, the bar is unchanged.
|
|
46
|
+
|
|
47
|
+
**Short windows.** When the window is too short for every view button, the upper group (built-in views + extension entries) scrolls (no visible scrollbar); Settings and the quick-toggles entry stay pinned at the bottom.
|
|
48
|
+
|
|
45
49
|
Below Settings sits the quick-toggles entry (network status, finish notification, and on desktop pin / keep-screen-awake) — see [explorer.md → Desktop windows](explorer.md#desktop-windows-multi-window).
|
|
46
50
|
|
|
47
51
|
### Hover drawer
|