* fix desktop startup readiness on windows
* add manual desktop build workflow
* hide Windows desktop server process window
* hide Windows Python bridge worker windows
* use no-window Python for Windows desktop CLI calls
---------
Co-authored-by: xingzhi <chuzihao.czh@alibaba-inc.com>
* Fix Windows bundled Hermes CLI launcher
* Update kanban service tests for Hermes process wrapper
---------
Co-authored-by: xingzhi <chuzihao.czh@alibaba-inc.com>
Profile avatars are sent to /profiles/:name/avatar as base64 image data
URLs in a JSON body. The handler allows up to 1MB of raw image data,
which is ~1.37MB once base64-encoded — larger than @koa/bodyparser's
default 1mb jsonLimit, so uploads were rejected with HTTP 413 before
reaching the handler.
Set jsonLimit/textLimit to 4mb, leaving the handler's own 1MB raw-size
check as the authoritative limit (now returning a clear 400 instead of
a confusing 413).
Co-authored-by: xingzhi <chuzihao.czh@alibaba-inc.com>
Provider auth controllers derived the credential directory with
`authPath.substring(0, authPath.lastIndexOf('/'))`. On Windows paths use
backslashes, so `lastIndexOf('/')` returns -1 and the slice yields an
empty string, making `mkdirSync('')` throw
`ENOENT: no such file or directory, mkdir ''` during OAuth login.
Replace the manual slicing with the cross-platform `path.dirname()` in
codex-auth (auth.json + codex CLI token paths), xai-auth, and nous-auth.
Fixes Codex/xAI/Nous login on Windows.
Co-authored-by: xingzhi <chuzihao.czh@alibaba-inc.com>
* fix desktop preload fetch typing
* rename desktop app to Hermes Studio
* rename desktop package to Hermes Studio
* update Hermes Studio desktop icons
* configure desktop signing and app id
* force desktop api calls to local server
* isolate desktop agent bridge ports
* bundle MCP support in desktop Python
* change desktop default port to 8748
* restore webui production port copy
* Add desktop packaging workflow
* Add desktop package homepage
* Fix desktop default credential prompt
* Suppress default credential prompt on desktop
* Publish desktop artifacts on release; reduce CI to PR smoke test
Add desktop-release.yml triggered on release publish (mirroring
docker-publish.yml) to build all platforms and upload .dmg/.exe/
.AppImage/.deb to the GitHub Release.
Trim build.yml desktop job to a PR-only Linux x64 smoke test, since
release artifacts are now produced by desktop-release.yml. This drops
per-push and macOS/Windows packaging from regular CI.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Fix desktop Hermes data home on Windows
---------
Co-authored-by: xingzhi <chuzihao.czh@alibaba-inc.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
When the model interleaves narration text with tool calls within one
turn ("text → tool → more text"), the assistant text was rendered split
across the tool boundary — a word could be cut in half, e.g. the part
before the tool call ending mid-word and the remainder appearing after
the tool card.
Root cause: the agent bridge (`hermes_bridge.py`) accumulated streamed
text in `RunRecord.deltas` and tool/lifecycle events in
`RunRecord.events` as two parallel lists with no relative ordering. On
poll, the aggregated text (`"".join(deltas)`) and the events were
delivered separately, and the Node consumer (`handle-bridge-run.ts`)
processed all `chunk.events` (including `tool.started`) before the
aggregated `chunk.delta`. The real interleaving of text and tool calls
was therefore lost, splitting the text around the tool boundary.
Fix:
- Bridge: `stream_callback` now also appends each text chunk as an
ordered `stream.delta` event into the same `events` list as
tool.started/tool.completed, preserving true interleaving. `deltas`
is still kept for the aggregated `output`/resume snapshot.
- Node: process `stream.delta` events inline within the events loop (in
true order), and skip the aggregated `chunk.delta` when ordered
`stream.delta` events were present for that chunk (avoids duplicate
text). Text-delta handling was extracted into `processBridgeTextDelta`
and reused by both paths.
Verified end-to-end: narration that calls a tool mid-sentence now
streams and persists as coherent text in the exact order produced, with
no word split across the tool boundary.
Co-authored-by: Paulo Cavallari <paulocavallari@users.noreply.github.com>