@turmind/halo 1.5.11 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +2 -2
  2. package/admin-out/404.html +1 -1
  3. package/admin-out/_next/static/chunks/{941-4719e7343b54b9bd.js → 147-d4200c70445aabb6.js} +1 -1
  4. package/admin-out/_next/static/chunks/989-a7f752480eaaa2dc.js +1 -0
  5. package/admin-out/_next/static/chunks/app/{layout-5ec6c5f713a8562b.js → layout-ea161287d934ba96.js} +1 -1
  6. package/admin-out/_next/static/chunks/app/page-8173112f256bc483.js +1 -0
  7. package/admin-out/_next/static/chunks/{webpack-efd27999305b080a.js → webpack-dc73047e0279979b.js} +1 -1
  8. package/admin-out/_next/static/css/7b736202f0b1dbfd.css +1 -0
  9. package/admin-out/_next/static/css/981c9e5610ce535a.css +1 -0
  10. package/admin-out/index.html +1 -1
  11. package/admin-out/index.txt +6 -5
  12. package/bundled-docs/design/a2a.md +286 -0
  13. package/bundled-docs/design/agentcore.md +194 -122
  14. package/bundled-docs/design/architecture.md +2 -2
  15. package/bundled-docs/design/canvas-extensions.md +30 -9
  16. package/bundled-docs/design/observability.md +12 -4
  17. package/bundled-docs/design/relay.md +1 -1
  18. package/bundled-docs/design/session.md +3 -1
  19. package/bundled-docs/design/storage.md +9 -2
  20. package/bundled-docs/design/web.md +5 -56
  21. package/bundled-docs/dev/api.md +70 -4
  22. package/bundled-docs/dev/deploy.md +2 -1
  23. package/bundled-docs/dev/env.md +8 -4
  24. package/bundled-docs/dev/tools.md +93 -3
  25. package/bundled-docs/guide/channels/web.md +0 -26
  26. package/bundled-docs/guide/cli.md +40 -4
  27. package/bundled-docs/guide/delegation-and-access.md +3 -2
  28. package/bundled-docs/guide/skills.md +1 -1
  29. package/bundled-docs/requirements/agent.md +1 -1
  30. package/bundled-docs/requirements/chat.md +3 -1
  31. package/bundled-docs/requirements/editor.md +9 -3
  32. package/bundled-docs/requirements/workspace.md +6 -0
  33. package/dist/index.js +4428 -2299
  34. package/package.json +1 -1
  35. package/templates/models/aws-bedrock-claude-invoke.yaml +40 -1
  36. package/templates/models/aws-bedrock-openai.yaml +100 -6
  37. package/templates/prompts/all/RUNTIME.md +2 -1
  38. package/templates/skills/send-file/SKILL.md +1 -1
  39. package/templates/skills/send-file/a2a.md +13 -0
  40. package/admin-out/_next/static/chunks/989-86b0f677f69ccf3b.js +0 -1
  41. package/admin-out/_next/static/chunks/app/page-4792aa1c79f7e7f1.js +0 -1
  42. package/admin-out/_next/static/css/97f3ac570664d044.css +0 -3
  43. /package/admin-out/_next/static/{GO2W5JoiC46FIxLjtFAXx → _F_Fkyh9PainUNY82EEjY}/_buildManifest.js +0 -0
  44. /package/admin-out/_next/static/{GO2W5JoiC46FIxLjtFAXx → _F_Fkyh9PainUNY82EEjY}/_ssgManifest.js +0 -0
@@ -154,7 +154,7 @@ Halo seeds these skills on every startup (the ids in `BUILTIN_SKILL_IDS`, `packa
154
154
  | skill | Create / update skills — backs the `create` / `update` verbs of `/skill` |
155
155
  | workspace | Workspace maintenance — backs `/workspace setup` / `tidy` (init / reorganize `.halo/` INDEX.md / INSTRUCTIONS.md / memory/) and `/workspace share` (export a shareable bundle) |
156
156
  | cron | Create / list / update / enable / disable / delete scheduled agent runs — backs `/cron` |
157
- | send-file | Deliver an image/video/file as a channel attachment by emitting `MEDIA:<absolute_path>` — works on Web / WeChat / Telegram / Slack / Feishu (no command; model-activated, workspace access) |
157
+ | send-file | Deliver an image/video/file as a channel attachment by emitting `MEDIA:<absolute_path>` — works on Web / WeChat / Telegram / Slack / Feishu / WeCom / A2A (no command; model-activated, workspace access) |
158
158
  | self | The agent's own visual space (`.halo/canvas/self.html`) for self-expression (no command; model-activated, full access) |
159
159
  | aws-knowledge | Query the official AWS Knowledge MCP server for up-to-date AWS docs (no command, `user-invocable: false`; model auto-activates) |
160
160
  | web-search | Real-time web search on AWS Bedrock (needs the machine's AWS credentials with Bedrock access) in two gears: fast (Amazon Nova grounding, default; US regions only) and deep (`--deep`, GPT-5.6 `web_search` via Bedrock Mantle, slower and token-expensive); regions set via its `fast_region` / `deep_region` params (Settings → Skills) (no command, `user-invocable: false`; model auto-activates) |
@@ -55,7 +55,7 @@ Same id present in both scopes: workspace wins; the overridden global is greyed
55
55
 
56
56
  ### Tool selection
57
57
  - **Session tools**: `start_session` / `session_list` / `query_session` / `interrupt_session` / `stop_session` / `archive_session` / `get_session_output` / `query_agent` — **not** selected by name; the whole bundle is granted automatically by a non-empty `team` (see below). Listing them under `agent.yaml tools` has no effect.
58
- - **Workspace tools**: `file_read` / `view_image` / `file_write` / `file_edit` / `file_list` / `shell_exec` / `grep` / `glob` / `web_fetch`, plus the single `relay_send` chip (grants the whole cross-workspace relay set, full-access sessions only), returned by `GET /api/agent-configs/tools`. `view_image` is dropped at runtime when the model can't take images (the form dims it)
58
+ - **Workspace tools**: `file_read` / `view_image` / `file_write` / `file_edit` / `file_list` / `shell_exec` / `grep` / `glob` / `web_fetch`, plus the single `relay_send` chip (grants the whole cross-workspace relay set, full-access sessions only) and the single `a2a_send` chip (grants the cross-server A2A set — `a2a_send` / `a2a_stop` / `a2a_read` / `a2a_list` — at every access level except the A2A read-only profile), returned by `GET /api/agent-configs/tools`. `view_image` is dropped at runtime when the model can't take images (the form dims it)
59
59
  - **`activate_skill`**: auto-injected when the YAML lists at least one usable skill (not disabled, allowed at the session's access level); loads the full SKILL.md on demand
60
60
 
61
61
  ### Team (delegation switch + whitelist)
@@ -23,7 +23,8 @@ The primary surface for talking to an agent.
23
23
  - Markdown + code-block highlighting
24
24
  - Tool-call card: expandable, shows tool name / input / output
25
25
  - Sub-agent streams stay out of the chat: their reports land as a green callout, and Debug mode adds agent start/done markers labelled with the agent name (e.g. "Coder", "Researcher")
26
- - A reply that has produced nothing yet shows a spinner with "Thinking..."
26
+ - A reply that has produced nothing yet shows a spinner with "Thinking..."; once the model streams reasoning text, the spinner gives way to a **live thinking panel**: expanded, muted, with a "Thinking..." header and char count, capped at about 9 lines and tailing its own text (so the chat log grows by at most the cap). It folds to the one-line collapsed "Thinking · N chars" header (click to expand; it stays in the log) as soon as text or a tool call follows, or the message settles. Providers that stream no reasoning text stay on the spinner; Debug mode is unchanged (spinner until text or a tool call arrives, collapsed headers only)
27
+ - **Follow the bottom by intent**: while a reply streams the log follows its end, and scrolling up stops the follow. Upward input — mouse wheel, touch drag, PageUp / ArrowUp / Home / Shift+Space, or grabbing the scrollbar — detaches the moment it arrives, so a fast stream can't snap the view back mid-gesture; upward input that a nested scroller (the live thinking panel, an expanded tool body) would take doesn't count. The log re-attaches only when the view is scrolled back down to within 80 px of the end. Applies to the chat panel, the Sessions tab viewer and the live thinking panel alike; a reader scrolling inside the thinking panel stops its tail the same way
27
28
  - The user bubble shows its send time (`HH:mm`, browser-local) at the left of its header row, after the expand chevron (see [User-message actions](#user-message-actions-expand--copy--delete)); hovering it gives the full date. Same bubble component as the Sessions tab, so both surfaces get it
28
29
  - In Debug mode the system-prompt `context` row stays in the list but doesn't open an exchange of its own, so there is no blank strip above the first bubble
29
30
 
@@ -59,6 +60,7 @@ The workspace's root sessions as **Chrome-style vertical tabs** on the right edg
59
60
  - **Rows**: one line per row — just the title, no leading icon cell (the "New session" draft row has none either, so the titles line up). Message count, time-ago, model and the state text (`Working…` / `New messages` / `Idle`) are in the tooltip, the state after a ` · ` at the end of its second line. `N msgs` counts the session's user turns **over its whole lifetime**, so compacting or archiving history never makes it go backwards.
60
61
  - Each row carries a **2px status bar** along its bottom edge, full row width with 6px inset on both sides and rounded ends (absolutely positioned, so a state change never reflows a narrow list — the spinner it replaced did; decorative, `aria-hidden`): **amber, breathing** (`animate-pulse`) while a loaded tab's turn is running; **blue**, solid, when a loaded background tab is idle with unread output (output landed while it wasn't on screen; cleared when shown); **green** otherwise — including sessions no tab has loaded and tabs a reconnect released. Green is the norm, so it is **dimmed** (`/40`) to recede into the background, and rises to `/70` on the selected and hovered row; amber and blue never dim. The list endpoint's `status` is not used. In the light and warm themes amber renders as the theme's darker orange, same as the rest of the UI.
61
62
  - Infinite scroll pages older sessions. A "+" footer starts a new session.
63
+ - **Hover peek (collapsed list)**: resting the mouse on the collapsed rail for 300 ms slides the **full list** (header + rows) in over the chat to its left, at the saved width, without reflowing the chat; leaving closes it after a 200 ms grace. Touch never opens it. It stays open while a rename input or the delete confirm started from it is in progress, and selecting a row closes it. Collapsing by mouse click does not peek straight back open under the pointer until it leaves and re-enters; the peek header's expand button pins the list open.
62
64
  - **New session**: "+", `/session new` and `/clear` open a **draft tab**. A "New session" row sits on top while it is on screen, and an untouched draft is reused rather than duplicated. The session is created by the draft's first message or command. The previous session keeps streaming in its own tab.
63
65
  - **Background tabs**: one WS connection carries every loaded tab, so a session that isn't on screen keeps receiving its turn. After a reconnect only the tab on screen is reattached; the others reload when clicked. Live capture and face (`<<<SHOW>>>`) markers only act for the tab on screen.
64
66
  - **Delete (trash icon)**: deletes the session after a confirm dialog in the UI language ("Delete this session? Its history cannot be recovered." / its Chinese counterpart). Deletion is the REST delete first, then the WS one, so sub-session files go too. The trash icon, like the **rename** pencil, appears only on hover — the active tab included.
@@ -63,7 +63,8 @@ File types without a built-in plugin can be handled by an **installed extension*
63
63
  - **Fallback**: a file with no built-in plugin and no installed extension shows a static page — "no built-in preview for this type; extensions for more file types are on <hub> ↗", where `<hub>` is the extension skill's `hub_repo` (default halo-hub; a local path / ssh remote shows as text) — plus Open as text / Download. No online lookup
64
64
  - **Editable extensions** (manifest `capabilities: ["save"]`): the iframe reports dirty → tab shows the dirty dot → header **Save** button (Ctrl/Cmd+S is *not* wired for extension tabs — Monaco isn't mounted) → `PUT /api/files/raw`. If the file changed on disk since it was loaded the save gets a 409 and the user is asked "changed on disk … Overwrite?". An external change while the tab is clean reloads it; while dirty, local edits are kept silently and the conflict surfaces at the next save
65
65
  - **Export from an editable extension** (e.g. draw.io *File ▸ Export as*, Excalidraw main menu *Export PNG / SVG*): the extension iframe can't download files, so the exported image is saved **into the workspace, next to the open file** (`flow.drawio` → `flow.png`). If that file already exists the user is asked whether to overwrite it. On success a banner "Exported to <path>" appears above the preview with a **Download** link. Exporting never marks the tab modified and never changes the open file. Only on Halo builds newer than 1.5.9; on older hosts the extension shows no working export (drawio ≥ 1.1.0 / excalidraw ≥ 1.1.0 hide or fall back on their own)
66
- - **Bundle extensions** (manifest `bundle: true`, e.g. the `htrans` meeting recorder): a *directory* named with the extension's suffix (`Standup.htrans/`) is one document. In the Explorer it shows a package icon; clicking the row (or Enter) opens it as a tab, and only its chevron expands it so the files inside stay browsable. Right-click → Open to the Side works on it. **New File** with a bundle suffix (`Standup.htrans`) creates the directory and opens it. The extension reads and writes only inside that directory. While it reports busy (e.g. recording) the tab shows the dirty dot, asks before closing, and stays mounted when you switch tabs. Ctrl/Cmd+S / Save do nothing on it. A bundle tab survives a reload while the extension is installed and supported here; otherwise the tab is dropped and the directory is an ordinary folder again
66
+ - **Bundle extensions** (manifest `bundle: true`, e.g. the `htrans` meeting recorder): a *directory* named with the extension's suffix (`Standup.htrans/`) is one document. In the Explorer it shows a package icon; clicking the row (or Enter) opens it as a tab, and only its chevron expands it so the files inside stay browsable. Right-click → Open to the Side works on it. **New File** with a bundle suffix (`Standup.htrans`) creates the directory and opens it — from the file tree's inline New File and from the Explorer header's New File button alike. The extension reads and writes only inside that directory. While it reports busy (e.g. recording) the tab shows the dirty dot, asks before closing, and stays mounted when you switch tabs. Ctrl/Cmd+S / Save do nothing on it. A bundle tab survives a reload while the extension is installed and supported here; otherwise the tab is dropped and the directory is an ordinary folder again
67
+ - **File access beyond the open file** (manifest capability `fs-read`; Settings → Extensions tags it "Reads files on this machine"): a viewer such as an emulator or model viewer may read other files in the workspace or anywhere on the server machine (never write), and ask the user to choose one. The choice is made in a **file picker** the viewer opens on demand: Workspace and Home shortcuts, an editable path box, a breadcrumb, folders first, only files matching the viewer's suffix filter; arrow keys / Enter / Backspace to navigate, Esc or Cancel to close it. A file inside the workspace is handed back as a workspace-relative path, any other as an absolute one. Halo's own secrets (`~/.halo/secrets`, `~/.ssh`, git credentials, the global databases — the same paths the agent sandbox hides) never show up in the picker and can't be read this way, symlinks included
67
68
  - **Platforms** (manifest `platforms`: `web` / `desktop-mac` / `desktop-win` / `desktop-linux`; omitted = everywhere): on an excluded platform (the Halo desktop app is detected by its user agent) the extension acts as if it were not installed. The fallback page says `"<name>" only runs on: <platforms>`, and Settings → Extensions shows a platforms badge plus a gray "not supported here" tag. Manifest capability `media` lets the extension use the microphone and screen capture
68
69
  - **Install sources**: Settings → Extensions zip upload; `/extension install <id|zip|url>` (listed by the built-in `default` agent, full access), where an id comes from the hub in Settings → Skills → extension → `hub_repo` (default halo-hub; GitHub / Gitea / Forgejo / GitLab release zips, or tags of any other git repo); or a manual directory drop
69
70
  - **Live install / upgrade / uninstall** (from Settings → Extensions upload / remove, the `/extension` skill, or a manual directory change): pushed over WS, no reload. An upgraded extension remounts open tabs (or shows a "updated — reload" banner if the tab is dirty); uninstalling drops clean tabs to the fallback page and keeps dirty tabs alive with a banner
@@ -77,7 +78,7 @@ Markdown and HTML open as text in Monaco *and* have a rendered view — Canvas d
77
78
  - Toggle to Edit → Monaco source, Cmd+S saves as usual
78
79
 
79
80
  ### Preview caching (MRU)
80
- Recently opened preview tabs stay mounted (up to 5, MRU) so switching between them doesn't re-fetch or re-parse. Plugins flagged `heavy: true` bypass the cache — only the active instance mounts, others unmount; switching between two heavy tabs of the same type (e.g. two `.ipynb`) remounts the viewer, so it shows the newly active file. An extension tab with unsaved edits stays pinned beyond the 5. Closing a preview tab removes it from the cache immediately (aborting any in-flight fetch).
81
+ Recently opened preview tabs stay mounted (up to 5, MRU) so switching between them doesn't re-fetch or re-parse. Plugins flagged `heavy: true` bypass the cache — only the active instance mounts, others unmount; switching between two heavy tabs of the same type (e.g. two `.ipynb`) remounts the viewer, so it shows the newly active file. An extension tab with unsaved edits stays pinned beyond the 5. Cached previews keep a fixed (path-sorted) order in the DOM rather than moving with recency, so switching tabs never reloads an extension iframe — a running emulator keeps its state. Closing a preview tab removes it from the cache immediately (aborting any in-flight fetch).
81
82
 
82
83
  ### File metadata in header
83
84
  The Canvas header shows `(size · Created … · Modified …)` for the active tab. Both text tabs and preview tabs populate this — preview tabs fetch `GET /api/files/stat` on open (and on tab restore from localStorage) since they never read content.
@@ -90,6 +91,11 @@ The header has a maximize button on the far right. Toggling it expands Canvas to
90
91
 
91
92
  Canvas (including Monaco instances, file tree, and open tab contents) stays mounted across activity-tab switches and maximize toggles — switching away and back does **not** reload content.
92
93
 
94
+ **Immersive mode for viewer extensions.** When the focused pane's active tab is an extension viewer without `save` (a bundle counts), maximize goes further: the viewer fills the whole viewport and the Canvas header, tab bar, other pane and floating chat panel are hidden. A maximize click also enters real fullscreen (a maximize restored after a reload stays in-page). The viewer keeps running — nothing reloads.
95
+ - **Exit**: `Esc` (including while focus is inside the viewer), or the **× Exit · Esc** pill at the top — on mouse it appears for a moment on entering and whenever the pointer moves to the top edge; on touch it stays on screen as a small × at the top-left, and a tap near the top widens it. A viewer's own fullscreen (e.g. an emulator's) takes the first `Esc`.
96
+ - **Chat replies while immersive**: when an agent finishes a reply the chat can't be seen, so a toast "Agent replied · <session title>" (or "N sessions replied") appears at the top right for ~8 s with **Back to chat**, which leaves immersive, opens that session and puts the caret in the chat input.
97
+ - Editable extensions (`save`) and ordinary files keep the plain maximize described above.
98
+
93
99
  ## Shortcuts
94
100
 
95
101
  | Shortcut | Action |
@@ -97,4 +103,4 @@ Canvas (including Monaco instances, file tree, and open tab contents) stays moun
97
103
  | Cmd/Ctrl + P | Quick Open (fuzzy file search) |
98
104
  | Cmd/Ctrl + S | Save current tab |
99
105
  | Alt + W | Close current tab (Cmd+W cannot be overridden in browsers; the desktop app uses Cmd/Ctrl + W, and closes the window when no tab is open) |
100
- | Esc | Exit maximized Canvas (when not inside an input / Monaco / Quick Open) |
106
+ | Esc | Exit maximized Canvas (when not inside an input / Monaco / Quick Open); also exits the immersive viewer, including from inside it |
@@ -44,6 +44,12 @@ The Source Control entry is hidden in workspaces that are not git repos.
44
44
 
45
45
  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
46
 
47
+ ### Hover drawer
48
+ The bar is icon-only (48px) at rest. Resting the **mouse** on it for 300 ms widens it into a 240px drawer that shows each view's name plus a one-line description (the quick-toggles entry too); leaving closes it after a 200 ms grace, and moving back in within that grace keeps it open. The view icons no longer carry native tooltips.
49
+ - **No reflow**: the bar is an absolute layer over a fixed 48px slot, so the drawer overlays the sidebar / main area instead of pushing them.
50
+ - **Mouse only**: touch and pen never open it, and neither do touch-primary devices — a tap still just switches view.
51
+ - **Stays open** while the quick-toggles panel (anchored to the drawer's right edge) is up. **Esc** or picking a view closes it.
52
+
47
53
  ## Resizable panels
48
54
  - **Sidebar width**: drag between sidebar and main content
49
55
  - **Bottom panel height**: drag between main content and bottom panel