@turmind/halo 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/admin-out/404.html +1 -1
  2. package/admin-out/_next/static/chunks/212-c5f046048be9c367.js +1 -0
  3. package/admin-out/_next/static/chunks/4-e7ba0b1ced30190b.js +1 -0
  4. package/admin-out/_next/static/chunks/app/page-5a6cf2b73a12b849.js +1 -0
  5. package/admin-out/_next/static/css/62b8bf49e6404ffc.css +3 -0
  6. package/admin-out/index.html +1 -1
  7. package/admin-out/index.txt +5 -5
  8. package/bundled-docs/design/agent.md +2 -1
  9. package/bundled-docs/design/cron.md +9 -3
  10. package/bundled-docs/design/session.md +3 -1
  11. package/bundled-docs/design/ws.md +21 -4
  12. package/bundled-docs/dev/api.md +37 -3
  13. package/bundled-docs/dev/env.md +2 -0
  14. package/bundled-docs/dev/tools.md +13 -4
  15. package/bundled-docs/guide/chat.md +1 -1
  16. package/bundled-docs/guide/workspace.md +2 -2
  17. package/bundled-docs/requirements/settings.md +8 -0
  18. package/dist/index.js +416 -247
  19. package/package.json +1 -1
  20. package/templates/agents/__apply_agent__/agent.yaml +1 -1
  21. package/templates/agents/__evo_agent__/agent.yaml +1 -1
  22. package/templates/agents/__score__/agent.yaml +1 -1
  23. package/templates/agents/deep-executor/agent.yaml +1 -1
  24. package/templates/agents/default/agent.yaml +1 -1
  25. package/templates/agents/goal/agent.yaml +1 -1
  26. package/templates/skills/agent/SKILL.md +2 -2
  27. package/admin-out/_next/static/chunks/212-e217e00ce6cc2bdc.js +0 -1
  28. package/admin-out/_next/static/chunks/397-fc5a406d80d46ca7.js +0 -1
  29. package/admin-out/_next/static/chunks/app/page-f8208e0c7f315faa.js +0 -1
  30. package/admin-out/_next/static/css/80eca65cb72e5c69.css +0 -3
  31. /package/admin-out/_next/static/{WvYu_osMZVpohYN4ntkpS → CWrUwTypkebkhwZ5i82_G}/_buildManifest.js +0 -0
  32. /package/admin-out/_next/static/{WvYu_osMZVpohYN4ntkpS → CWrUwTypkebkhwZ5i82_G}/_ssgManifest.js +0 -0
@@ -117,8 +117,8 @@ Each session carries `accessLevel: 'readonly' | 'workspace' | null` (persisted i
117
117
  | Level | DB value | Tools (with bwrap) | Tools (without bwrap) | Sandbox |
118
118
  |---|---|---|---|---|
119
119
  | `null` (full) | `full` | All 9 tools | All 9 tools | None |
120
- | `workspace` | `workspace` | All 9 tools | All 9 tools | bwrap: workspace rw, sensitive paths hidden |
121
- | `readonly` | `readonly` | All 9 tools | file_read, view_image, file_list, grep, glob (5 tools) | bwrap: workspace ro, sensitive paths hidden |
120
+ | `workspace` | `workspace` | All 9 tools | All 9 tools | bwrap: workspace rw, sensitive paths + workspace runtime state hidden |
121
+ | `readonly` | `readonly` | All 9 tools | file_read, view_image, file_list, grep, glob (5 tools) | bwrap: workspace ro, sensitive paths + workspace runtime state hidden |
122
122
 
123
123
  `view_image` is additionally gated on `capabilities.image` (see its section above). Models without vision support get the same lists minus `view_image` — so a non-vision model on `readonly` ends up with 4 tools, not 5.
124
124
 
@@ -131,9 +131,9 @@ Dependency: `bubblewrap` (`apt install bubblewrap`) on Linux. Without it, only l
131
131
 
132
132
  ### Sandbox hidden paths
133
133
 
134
- Sensitive directories and files are hidden from workspace/readonly sessions via bwrap overlays. Paths that don't exist on the filesystem are silently skipped.
134
+ Sensitive directories and files are hidden from workspace/readonly sessions via bwrap overlays (and the same lists gate `assertPathAllowed` on the no-bwrap fallback). Paths that don't exist on the filesystem are silently skipped. Two categories coexist:
135
135
 
136
- Configured in `settings.yaml` under `general.sandbox`:
136
+ **Global lists (configurable)** — credentials and cross-workspace state, configured in `settings.yaml` under `general.sandbox`:
137
137
 
138
138
  | Setting | Default | Method |
139
139
  |---|---|---|
@@ -143,6 +143,15 @@ Configured in `settings.yaml` under `general.sandbox`:
143
143
 
144
144
  Changes take effect immediately — `config.ts` reads settings.yaml via an mtime-watched lazy cache, so the next `shell_exec` reads the latest values. These keys are `globalOnly` in the schema — a workspace `settings.yaml` cannot override them, since they define the security boundary agents run inside.
145
145
 
146
+ **Workspace-relative set (hardcoded)** — the workspace's own runtime state, which holds other channels'/users' conversations on a shared workspace. Code constants in `sandbox.ts` (`WORKSPACE_HIDDEN_DIRS` / `WORKSPACE_HIDDEN_FILES`), deliberately not settings: this is a security boundary (a config edit must not be able to open it), and the entries are workspace-relative while the settings lists are absolute/`~` paths.
147
+
148
+ | Constant | Entries | Method |
149
+ |---|---|---|
150
+ | `WORKSPACE_HIDDEN_DIRS` | `.halo/sessions` (session transcripts), `.halo/logs`, `.halo/evo` (run dirs contain full source-session snapshots) | `--tmpfs` overlay |
151
+ | `WORKSPACE_HIDDEN_FILES` | `.halo/halo.db` + `-wal`/`-shm` (sqlite `agent_sessions` rows) | `--ro-bind /dev/null` |
152
+
153
+ The rest of `.halo/` (INSTRUCTIONS.md, INDEX.md, docs/, memory/, skills/, agents/, prompts/, tmp/, canvas/, goal/, settings.yaml) stays readable — it's workspace knowledge agents need to work. `full` sessions bypass the sandbox entirely and see everything.
154
+
146
155
  `/tmp` is not in the hidden list — it receives a standalone `--tmpfs` mount for process isolation (each bwrap invocation gets its own empty `/tmp`), not for hiding secrets.
147
156
 
148
157
  Per-channel defaults:
@@ -74,7 +74,7 @@ If you're chatting from WeChat, the same shared commands are available (routed t
74
74
  | `/qr [level]` | Generate an invite QR for a new bot account (full 权限 bot 专用) |
75
75
  | `/help` | Show help |
76
76
 
77
- If the session is currently compacting or busy when your message arrives, you'll see a hint — ("⏳ integrating context…" / "🔄 queued…") — and the message is queued (while compacting it's dropped; while busy it's kept).
77
+ If the session is currently compacting or busy when your message arrives, you'll see a hint — ("⏳ integrating context…" / "🔄 queued…") — and the message is queued either way, processed as soon as the compact / current turn finishes.
78
78
 
79
79
  ## Interrupt vs Stop
80
80
 
@@ -126,6 +126,6 @@ Two tabs in the header: Chat / Terminal. Current tab lives in `editorStore.botto
126
126
  The login page runs through `POST /api/auth/login`; the JWT lives in an HTTP-only cookie:
127
127
  - 14-day expiry
128
128
  - Auto-refresh after 24 hours of access
129
- - Click the avatar in the top-right to log out
129
+ - Log out via **Settings → Security** (returns to the login page; this browser only)
130
130
 
131
- **Where to set the password**: `~/.halo/secrets/config.yaml`'s `server.password`, or the `HALO_PASSWORD` env var.
131
+ **Password**: set initially by `halo setup` (or the `HALO_PASSWORD` env var); change it later in **Settings → Security** (needs the current password). Forgot it? Re-run `halo setup` to reset.
@@ -164,6 +164,14 @@ Values present in `settings.yaml` whose namespace doesn't appear in any current
164
164
 
165
165
  `general.*` is intentionally excluded from orphan detection — its declared keys are enumerated by the built-in schema, so anything else there is treated as either a typo or a forward-compat field, not an orphan.
166
166
 
167
+ ## Security view (change password + logout)
168
+
169
+ A **Security** entry in the left nav (below the System group) opens a page with two cards. Like `__orphans` it's a synthetic nav target, not a schema section — the credential lives in `~/.halo/secrets/config.yaml` (`server.password`, scrypt hash), not `settings.yaml`, and the header shows that path accordingly.
170
+
171
+ **Change password** — three inputs: current password, new password, confirm. Live client-side feedback while typing: strength rule (≥8 chars, at least one letter and one digit), new ≠ current, confirm matches; the submit button stays disabled until all pass. Submit posts to `POST /api/auth/change-password` (see [dev/api.md](../dev/api.md)) — the server re-runs the same checks authoritatively; a server rejection is shown verbatim under the form. Success shows an inline confirmation and clears all three fields. Existing sessions stay signed in (`jwt_secret` is not rotated). Forgotten password (can't provide the current one) is out of scope here — that's `halo setup`'s reset path.
172
+
173
+ **Log out** — the login state is an httpOnly JWT cookie, so JS can't clear it directly: the button calls `POST /api/auth/logout` (server expires the cookie via Set-Cookie) and reloads; the boot auth check then lands on the login page. This browser only — no server-side token blacklist.
174
+
167
175
  ## API
168
176
 
169
177
  | Operation | Method | Endpoint | Purpose |