Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
187 commits
Select commit Hold shift + click to select a range
b16cb32
fix(models): restore gemini-3-flash-preview to Gemini OAuth picker (#…
teknium1 Jun 2, 2026
bd2e77e
fix(desktop): stabilize project folder sessions (#37586)
OutThisLife Jun 2, 2026
27637bf
fix(desktop): triage batch of GUI quality-of-life fixes (#37536)
austinpickett Jun 2, 2026
3b92f49
Merge pull request #37597 from NousResearch/ethie/desktop-linux-install
ethernet8023 Jun 2, 2026
d8e779b
feat(desktop): make xAI Grok a first-class OAuth provider in the laun…
OutThisLife Jun 2, 2026
7ba97d3
fix(desktop): order xAI Grok after MiniMax in the OAuth catalog
OutThisLife Jun 2, 2026
6d585a6
fix(desktop): address Copilot review on xAI loopback flow
OutThisLife Jun 2, 2026
471f8c9
fix(desktop): address second Copilot pass on xAI loopback flow
OutThisLife Jun 2, 2026
0f7a137
ci(nix): fold package+devShell builds into flake check
ethernet8023 May 29, 2026
3ae2587
fix(desktop): use auth-store path as xAI OAuth source_label
OutThisLife Jun 2, 2026
ad6ca76
fix(desktop): signal loopback worker to stop on cancel
OutThisLife Jun 2, 2026
ef7c792
fix(web-server): move event channel state from module globals to app.…
ethernet8023 Jun 2, 2026
cae337d
Merge remote-tracking branch 'origin/main' into bb/grok-provider-desktop
OutThisLife Jun 2, 2026
608377d
Merge pull request #37697 from NousResearch/bb/grok-provider-desktop
OutThisLife Jun 2, 2026
3001cb5
fix(gateway): route /background result media by type
teknium1 Jun 2, 2026
71f50f7
test(honcho): de-flake prewarm smoke test's thread wait (#37614)
teknium1 Jun 3, 2026
ed6cf71
feat(desktop): inline model picker in the status bar
OutThisLife Jun 3, 2026
f28b739
fix(desktop): adopt existing macOS install + auto-place app
OutThisLife Jun 3, 2026
c4a879f
fix(aux): self-heal Nous-routed calls when a pinned model leaves the …
teknium1 Jun 3, 2026
5c9db50
fix(gateway): close ResponseStore + dispose unowned adapter on reconn…
Fearvox Jun 2, 2026
f5515ee
fix(release): add fearvox1015@gmail.com -> Fearvox to AUTHOR_MAP
Fearvox Jun 2, 2026
e137076
polish(gateway): address Copilot review comments on fd-leak fix
Fearvox Jun 2, 2026
639e251
fix(desktop): address Copilot review on model picker
OutThisLife Jun 3, 2026
2f5938d
fix(node/nix): consolidate workspace lockfile + update all consumers
ethernet8023 May 31, 2026
3b20321
refactor(uv): single managed-uv path, delete fts5 installer escalation
ethernet8023 Jun 2, 2026
d412c0c
fix(tests): add _patch_managed_uv autouse fixture to uv-dependent tes…
ethernet8023 Jun 2, 2026
a270e68
fix(desktop): write Dock tile as a file-reference URL
OutThisLife Jun 3, 2026
b8ab388
fix(desktop): configure Linux Electron sandbox helper
ethernet8023 Jun 2, 2026
440a2a6
fix(desktop): inherit microphone entitlement for macOS helpers
xxxigm Jun 3, 2026
64bcd14
test(desktop): assert macOS device entitlements are inherited
xxxigm Jun 3, 2026
1740daa
fix(desktop): roll back optimistic model switch on failure
OutThisLife Jun 3, 2026
51cb228
docs(desktop): sync marker schema comment + default dock note arg
OutThisLife Jun 3, 2026
69ffca8
Merge pull request #37739 from NousResearch/bb/desktop-macos-install-…
OutThisLife Jun 3, 2026
0dfadc9
fix(desktop): switch model on keyboard activation of picker rows
OutThisLife Jun 3, 2026
b7b7041
Merge pull request #37738 from NousResearch/bb/statusbar-model-menu
OutThisLife Jun 3, 2026
c2a6e29
fix(dashboard): allow desktop websocket origins on remote binds
leonardsellem Jun 2, 2026
ce31bf8
chore: add leonardsellem to AUTHOR_MAP for PR #37405
teknium1 Jun 3, 2026
2a43222
fix: expand skill bundles in cron jobs
vinoth12940 May 20, 2026
e282ff0
Merge pull request #37745 from xxxigm/fix/macos-mic-entitlement-inherit
OutThisLife Jun 3, 2026
f0c3ebe
feat(cli): configurable default interface (cli vs tui)
OutThisLife Jun 3, 2026
88405e3
fix(deps): refresh lockfile to clear 6 npm audit findings (#37752)
teknium1 Jun 3, 2026
0a7ee0d
Merge pull request #37782 from NousResearch/bb/configurable-default-i…
OutThisLife Jun 3, 2026
53d84cb
fix(setup): default browser/TTS picker to free local backend, not pai…
teknium1 Jun 3, 2026
e47e062
fix(tui): clear selection on right-click copy + group transcript blocks
OutThisLife Jun 3, 2026
db6bc0d
Merge pull request #37786 from NousResearch/bb/tui-rightclick-and-bou…
OutThisLife Jun 3, 2026
b28b934
fix(desktop): stop chat scroll jumping by disabling native scroll anc…
OutThisLife Jun 3, 2026
01db686
Merge pull request #37866 from NousResearch/bb/desktop-scroll-anchor
OutThisLife Jun 3, 2026
e3af115
feat(desktop): clamp sticky human messages to ~2 lines until hover/focus
OutThisLife Jun 3, 2026
7e82805
fix(dashboard): trust non-web WS origins on OAuth-gated binds after t…
benbarclay Jun 3, 2026
adcd28d
fix(desktop): inset sticky human messages with --sticky-human-top
OutThisLife Jun 3, 2026
6ca72a6
chore: uptick
OutThisLife Jun 3, 2026
968f889
fix(desktop): drop sticky human clamp max-height transition
OutThisLife Jun 3, 2026
760d3f8
fix(desktop): restore sticky human clamp transition at 0.75s
OutThisLife Jun 3, 2026
f84a291
chore: uptick
OutThisLife Jun 3, 2026
860e1d3
Merge pull request #37877 from NousResearch/bb/desktop-sticky-msg-clamp
OutThisLife Jun 3, 2026
f052c1b
feat(desktop): custom zoom shortcuts at half default step
ethernet8023 Jun 3, 2026
4c1fc7c
fix(docker): seed gateway_state.json from HERMES_GATEWAY_BOOTSTRAP_ST…
benbarclay Jun 3, 2026
5caa7ce
fix(desktop): keep in-flight new chats from vanishing on refresh
OutThisLife Jun 3, 2026
293c143
fix(desktop): label in-flight new chats with the first message
OutThisLife Jun 3, 2026
afe666d
Merge pull request #37908 from NousResearch/bb/desktop-concurrent-ses…
OutThisLife Jun 3, 2026
ca7db1c
fix(docker): point TUI launcher at prebuilt bundle via HERMES_TUI_DIR…
benbarclay Jun 3, 2026
99263cc
fix(desktop): disable GPU acceleration on remote displays to stop fli…
OutThisLife Jun 3, 2026
8d38164
fix(desktop): don't treat WSLg as a remote display
OutThisLife Jun 3, 2026
ee2f10d
Merge pull request #37932 from NousResearch/bb/desktop-remote-flicker
OutThisLife Jun 3, 2026
f05de08
fix(desktop): keep slash/@ completion menu navigable and Esc-dismissable
kshitijk4poor Jun 3, 2026
8445209
Merge pull request #37937 from kshitijk4poor/fix/desktop-slash-menu-k…
kshitijk4poor Jun 3, 2026
a30cb78
fix(desktop): make Stop button actually interrupt when a turn is queued
kshitijk4poor Jun 3, 2026
1f836e8
Merge pull request #37948 from kshitijk4poor/fix/desktop-stop-button-…
kshitijk4poor Jun 3, 2026
0a2e3fb
fix(desktop): stop background session messages bleeding into the acti…
kshitijk4poor Jun 3, 2026
f294e51
fix(dashboard): authenticate server-spawned PTY child WS with a proce…
benbarclay Jun 3, 2026
167ac32
test(dashboard): direct unit coverage for internal WS credential + do…
kshitijk4poor Jun 3, 2026
455ab7a
test(desktop): real-DOM regression for slash/@ menu keyboard nav
kshitijk4poor Jun 3, 2026
419c329
fix(desktop): stop Esc reopening the slash/@ menu; harden keyup guard
kshitijk4poor Jun 3, 2026
11e6470
Merge pull request #37999 from kshitijk4poor/desktop-slash-nav-dom-re…
kshitijk4poor Jun 3, 2026
b3d113c
Merge pull request #37975 from kshitijk4poor/fix/desktop-session-view…
kshitijk4poor Jun 3, 2026
3861298
chore: remove committed RELEASE_v*.md changelogs from repo root (#37855)
teknium1 Jun 3, 2026
f2eda62
fix(windows): rip out unused submodule support in installer & docker …
ethernet8023 Jun 3, 2026
ec13fa8
fix(docs): remove remaining stale submodule references missed by #380…
teknium1 Jun 3, 2026
0f2f6eb
docs: explain remote-gateway session token for Hermes Desktop (#38144)
teknium1 Jun 3, 2026
923b7d6
feat(matrix): support bang command aliases
nepenth May 18, 2026
5a27580
fix(matrix): make bang-command resolution robust + fix dead skill-com…
alt-glitch Jun 3, 2026
f4ec735
docs: add remote-backend section to the Desktop App page (#38180)
teknium1 Jun 3, 2026
1679146
fix(cli): exclude desktop-managed backend from stale-dashboard kill
liuhao1024 Jun 2, 2026
82289fc
fix(desktop): pass live backend PID to in-app update so its own dashb…
teknium1 Jun 3, 2026
71244b3
chore: add bbednarski9 to AUTHOR_MAP for #29722 salvage (#38189)
kshitijk4poor Jun 3, 2026
276aba2
docs: make the Desktop App remote-backend section self-contained (#38…
teknium1 Jun 3, 2026
212be5a
fix(mcp): banner shows 'disabled' not 'failed' for enabled:false serv…
teknium1 Jun 3, 2026
b6cb0af
feat(debug): include desktop.log in hermes debug share / /debug / her…
teknium1 Jun 3, 2026
e18bda2
fix(desktop): add @testing-library/dom as explicit dev dependency
vladkvlchk Jun 1, 2026
0b35721
chore: regenerate lockfile + map vladkvlchk for salvaged #36978
teknium1 Jun 3, 2026
2277620
fix(nix): bump npmDepsHash for refreshed lockfile
teknium1 Jun 3, 2026
b86139e
fix(desktop): stop chat scroll backward-jump from content-growth inte…
luyao618 Jun 3, 2026
b7ceec8
fix(desktop): honor upward wheel scroll in long threads
ferminquant Jun 3, 2026
fce6dc4
feat(dashboard): check-before-update flow on the System page (#38205)
teknium1 Jun 3, 2026
6356ee4
fix(tui): stop persisting full tool output in trail lines (silent OOM…
teknium1 Jun 3, 2026
096ea3e
Merge pull request #38221 from NousResearch/hermes/hermes-45accc84
OutThisLife Jun 3, 2026
b95f506
fix(kanban): don't permanently block tasks that hit a provider rate l…
teknium1 Jun 3, 2026
1b29853
Merge pull request #38224 from NousResearch/hermes/hermes-79601e59
OutThisLife Jun 3, 2026
d02fe3f
feat(observability): observer-grade telemetry hooks + NeMo-Relay plugin
bbednarski9 Jun 3, 2026
e2748a0
test: restore unrelated trailing newlines in cwd/tool-search tests
kshitijk4poor Jun 3, 2026
a2b86c8
perf(observability): gate tool-hook emit on has_hook; slim per-tool f…
teknium1 Jun 3, 2026
035fb98
test: stub has_hook in transform_tool_result hook tests
teknium1 Jun 3, 2026
45fc8da
fix(doctor): detect + repair stale HERMES_MAX_ITERATIONS .env ghost s…
teknium1 Jun 3, 2026
2ae42a3
fix(install.ps1): handle dirty worktree on Windows update (#38239)
teknium1 Jun 3, 2026
b9f170c
fix(install): require Node >=20.19/22.12 for the desktop build
OutThisLife Jun 3, 2026
31f46c7
feat(dashboard): enrich profiles dashboard and de-dupe channel env va…
austinpickett Jun 3, 2026
99d5e77
Merge pull request #38255 from NousResearch/bb/installer-desktop-buil…
OutThisLife Jun 3, 2026
b279b5c
fix(tui): save TUI /save snapshots under Hermes home with system prom…
austinpickett Jun 3, 2026
e919a06
fix(desktop): self-update rebuilds and relaunches cleanly on macOS
OutThisLife Jun 3, 2026
9a5470b
fix(desktop): dedupe clipboard image paste
OutThisLife Jun 3, 2026
f08eacd
Merge pull request #38306 from NousResearch/bb/desktop-clipboard-imag…
OutThisLife Jun 3, 2026
f3e179c
fix(installer): stop mislabeling stdout-style progress as stderr
OutThisLife Jun 3, 2026
87093fe
fix(dashboard): clamp PTY resize dimensions for WSL2 winsize garbage …
teknium1 Jun 3, 2026
335ab35
fix(gateway): decode schtasks output with locale encoding on Windows
xxxigm Jun 3, 2026
14cc2b2
test(gateway): cover schtasks locale-safe decoding on Windows
xxxigm Jun 3, 2026
85cd3cf
docs: remote desktop connect needs --tui on the backend (#38350)
teknium1 Jun 3, 2026
730616d
Potential fix for pull request finding
OutThisLife Jun 3, 2026
63ce4db
Potential fix for pull request finding
OutThisLife Jun 3, 2026
9f95c0b
Merge pull request #38296 from NousResearch/bb/fix-dmg-update-relaunch
OutThisLife Jun 3, 2026
74a769d
Merge pull request #38312 from NousResearch/bb/installer-stderr-log-l…
OutThisLife Jun 3, 2026
b782824
fix(installer): pass LogStream to emit_log calls from #38296
OutThisLife Jun 3, 2026
1d10edc
Merge pull request #38384 from NousResearch/bb/fix-installer-emit-log…
OutThisLife Jun 3, 2026
c218936
fix(desktop): persist pins, reconnect after sleep, dedupe session search
OutThisLife Jun 3, 2026
fe65b2a
fix(desktop): guard reconnect sockets and keep branch search precise
OutThisLife Jun 3, 2026
0a7e199
Merge pull request #38393 from NousResearch/bb/desktop-session-fixes
OutThisLife Jun 3, 2026
1084e44
fix(packaging): ship locales/ i18n catalogs in wheel, sdist, and Nix …
alt-glitch Jun 3, 2026
14bf237
fix(installer): never brick the install when a self-update swap fails
kshitijk4poor Jun 3, 2026
196ae87
test(installer): cover the post-update relaunch/install target deriva…
kshitijk4poor Jun 3, 2026
4db5bdf
feat(cli): make `hermes portal` the human-readable Portal onboarding …
kshitijk4poor Jun 3, 2026
dcc68c5
fix(setup): point Portal login-failure retry hints at `hermes portal`
kshitijk4poor Jun 3, 2026
44e1043
fix(desktop): prevent IME Enter from splitting messages and viewport …
stremtec Jun 3, 2026
42b1bfe
Merge pull request #38449 from kshitijk4poor/portal-login-alias
kshitijk4poor Jun 3, 2026
757c866
feat(cli): make `hermes portal` run the full quick-setup Nous flow (m…
kshitijk4poor Jun 3, 2026
f9fa7c5
fix(cli): harden `hermes portal` SystemExit handling + finish model-p…
kshitijk4poor Jun 3, 2026
a9caf74
Merge pull request #38465 from kshitijk4poor/portal-quick-setup-model
kshitijk4poor Jun 3, 2026
373ae35
fix(packaging): modernize project.license to PEP 639 SPDX string (#38…
teknium1 Jun 3, 2026
bf2dcb0
fix(skills): document xurl X Article ingestion
helix4u Jun 3, 2026
d7b6689
fix(docker): bake hindsight-client into the image (#38128) (#38530)
benbarclay Jun 3, 2026
d0c367e
fix(desktop): surface skill & quick-command slash commands in the pal…
teknium1 Jun 3, 2026
4ac098f
docs(dashboard): document connecting Hermes Desktop to a remote backe…
teknium1 Jun 3, 2026
2a977c4
Merge pull request #38517 from NousResearch/bb/desktop-yolo-statusbar…
OutThisLife Jun 3, 2026
9d09be0
fix(desktop): stop validating provider keys in launch setup
OutThisLife Jun 3, 2026
f834bc9
fix(update): stop stash/restore from clobbering desktop source on man…
teknium1 Jun 3, 2026
bea9401
fix(tui): cgroup-aware V8 heap cap so memory-limited containers stop …
teknium1 Jun 3, 2026
5e21376
docs(desktop): point Chat section to remote-backend + dashboard doc (…
teknium1 Jun 3, 2026
15981fd
fix: strip extra_content from tool_calls for strict APIs (Fireworks, …
nateGeorge Jun 3, 2026
da383c9
fix(install): cap requires-python at <3.14 and pin UV_PYTHON to the v…
teknium1 Jun 3, 2026
057a46a
Merge pull request #38546 from NousResearch/bb/disable-provider-key-v…
OutThisLife Jun 3, 2026
359e0a1
fix(dashboard): sanction plugin WS/upload auth via SDK helpers (gated…
benbarclay Jun 3, 2026
16c7345
feat(prompt): broaden Hermes self-knowledge pointer to docs + skill (…
teknium1 Jun 4, 2026
168b9f4
fix(hermes-ink): collapse SGR mouse fragment guards into one flush-aw…
OutThisLife Jun 4, 2026
8c6383d
fix(docker): chown build trees on UID remap independently of $HERMES_…
benbarclay Jun 4, 2026
b4beb47
fix(hermes-ink): reassemble split mouse sequences at the tokenizer; d…
OutThisLife Jun 4, 2026
985fbc8
test(hermes-ink): drop input-event SGR guard test
OutThisLife Jun 4, 2026
20db7ad
refactor(hermes-ink): delete now-dead SGR mouse fragment recovery
OutThisLife Jun 4, 2026
d1417d9
feat(cli): resume relaunches in the directory the session was started…
teknium1 Jun 4, 2026
b143ab6
test(hermes-ink): fuzz the tokenizer flush valve against fragment leaks
OutThisLife Jun 4, 2026
ef45b9e
fix(onboarding): clarify Anthropic API vs OAuth provider entries and …
teknium1 Jun 4, 2026
34eb799
feat(web): wire local/custom endpoints into model assignment
xxxigm Jun 3, 2026
245e5b9
fix(desktop): configure local/custom endpoint without an API key or U…
xxxigm Jun 3, 2026
43ff9bb
fix(mcp): resolve ${ENV} in discovery probe so header auth works (#38…
teknium1 Jun 4, 2026
47e2514
fix(docker): reject unsupported --user <arbitrary-uid> start with cle…
benbarclay Jun 4, 2026
8f0aaa3
Merge pull request #38564 from NousResearch/bb/tui-sgr-mouse-fragment…
OutThisLife Jun 4, 2026
286bed0
fix(docker): run config migrations during container boot (salvage #35…
benbarclay Jun 4, 2026
57010da
fix(desktop): render approval/sudo/secret prompts so tools stop silen…
teknium1 Jun 4, 2026
9549126
feat(dashboard): add Debug Share to the System page (#38600)
teknium1 Jun 4, 2026
c20e310
fix(constants): use windows native default hermes home
LeonSGP43 May 26, 2026
6346144
fix(gateway-windows): anchor detached/startup cwd at HERMES_HOME
Dusk1e May 29, 2026
ab2d89a
fix(docker): accept Unraid uid mappings (#38098)
sweetcornna Jun 4, 2026
3eb1163
feat(tool_search): optional embedding reranker for progressive tool d…
davidgut1982 May 30, 2026
96bfa72
fix(delegate): profile MCP toolsets bypass parent intersection
davidgut1982 May 26, 2026
6318ea6
docs(delegate): document profile_name MCP bypass in AGENTS.md and doc…
davidgut1982 May 26, 2026
9d92bd3
feat: lazy MCP discovery for no_mcp platforms (Phase 2)
davidgut1982 May 26, 2026
1423ef9
fix: resolve Pyright type errors in _cfg config bridge block
davidgut1982 May 26, 2026
3eaa3c0
fix(test): restore missing unittest.mock import in test_delegate_tool…
davidgut1982 May 30, 2026
a0ca3c1
fix(tool_search): per-scope reranker cache to avoid cross-agent embed…
davidgut1982 May 30, 2026
7f5e25a
fix(logging): apply per-logger levels from config so tool_search DEBU…
davidgut1982 May 30, 2026
b4f2d24
fix(delegate): wire profile_name through delegate_task so profile MCP…
davidgut1982 May 30, 2026
babac3b
fix(delegate): profile toolsets are authoritative — block batch-mode …
davidgut1982 May 30, 2026
2a7fb89
fix(delegate): copy profile toolsets to prevent config aliasing (fina…
davidgut1982 May 30, 2026
fa44759
fix(delegate): profile toolsets override inherit_mcp_toolsets — no pa…
davidgut1982 May 30, 2026
988d45b
fix(tools): coerce stringified booleans/integers in MCP tool args
davidgut1982 Jun 2, 2026
5d7b526
feat(tools): add model_switch tool for agent-driven complexity-based …
davidgut1982 Jun 2, 2026
c959d05
fix(gateway): remove anthropic haiku backstop from fallback provider
davidgut1982 Jun 2, 2026
3698a11
fix(ci): resolve four CI check failures for PR #37442
davidgut1982 Jun 5, 2026
bcaba0e
test(zai): mock detect_zai_endpoint to de-flake test_runtime_zai; fix…
davidgut1982 Jun 5, 2026
b01fb3d
fix(guard): hoist _longest_shared_prefix, fix guard predicate, fix mo…
davidgut1982 Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .envrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
watch_file pyproject.toml uv.lock
watch_file ui-tui/package-lock.json ui-tui/package.json
watch_file package-lock.json package.json web/package.json ui-tui/package.json website/package.json apps/shared/package.json apps/desktop/package.json ui-tui/packages/hermes-ink/package.json
watch_file flake.nix flake.lock nix/devShell.nix nix/tui.nix nix/package.nix nix/python.nix

use flake
4 changes: 0 additions & 4 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: recursive

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
Expand Down Expand Up @@ -194,8 +192,6 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: recursive

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/nix-lockfile-fix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ on:
push:
branches: [main]
paths:
- 'ui-tui/package-lock.json'
- 'package-lock.json'
- 'package.json'
- 'ui-tui/package.json'
- 'apps/dashboard/package-lock.json'
- 'apps/dashboard/package.json'
- 'apps/desktop/package.json'
workflow_dispatch:
inputs:
pr_number:
Expand All @@ -27,9 +27,9 @@ concurrency:

jobs:
# ── Auto-fix on main ───────────────────────────────────────────────
# Fires when a push to main touches package.json or package-lock.json
# in ui-tui/ or apps/dashboard/. Runs fix-lockfiles and pushes the hash
# update commit directly to main so Nix builds never stay broken.
# Fires when a push to main touches package.json or package-lock.json.
# Runs fix-lockfiles and pushes the hash update commit directly to main
# so Nix builds never stay broken.
#
# Safety invariants:
# 1. The fix commit only touches nix/*.nix files, which are NOT in
Expand Down Expand Up @@ -109,8 +109,8 @@ jobs:
# our computed hashes are stale. Abort and let the next triggered
# run recompute from the correct package-lock state.
pkg_changed="$(git diff --name-only "$BASE_SHA"..origin/main -- \
'ui-tui/package-lock.json' 'ui-tui/package.json' \
'apps/dashboard/package-lock.json' 'apps/dashboard/package.json' || true)"
'package-lock.json' 'package.json' \
'ui-tui/package.json' 'apps/desktop/package.json' || true)"
if [ -n "$pkg_changed" ]; then
echo "::warning::Package files changed since hash computation — aborting; a fresh run will recompute"
exit 0
Expand Down
28 changes: 8 additions & 20 deletions .github/workflows/nix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,16 @@ jobs:

- name: Check flake
id: flake
if: runner.os == 'Linux'
continue-on-error: true
run: nix flake check --print-build-logs

- name: Build package
id: build
if: runner.os == 'Linux'
continue-on-error: true
run: nix build --print-build-logs

# When the real Nix build fails, run a targeted diagnostic to see if
# When the flake check fails, run a targeted diagnostic to see if
# the failure is specifically a stale npm lockfile hash in one of the
# known npm subpackages (tui / web). This avoids surfacing a generic
# "build failed" message when the fix is a single known command.
- name: Diagnose npm lockfile hashes
id: hash_check
if: (steps.flake.outcome == 'failure' || steps.build.outcome == 'failure') && runner.os == 'Linux'
if: steps.flake.outcome == 'failure' && runner.os == 'Linux'
continue-on-error: true
env:
LINK_SHA: ${{ steps.sha.outputs.full }}
Expand Down Expand Up @@ -88,30 +81,25 @@ jobs:
- Or [run the Nix Lockfile Fix workflow](${{ github.server_url }}/${{ github.repository }}/actions/workflows/nix-lockfile-fix.yml) manually (pass PR `#${{ github.event.pull_request.number }}`)
- Or locally: `nix run .#fix-lockfiles` and commit the diff

# Clear the sticky comment when either the build passed outright (no
# Clear the sticky comment when either the flake check passed outright (no
# hash check needed) or the hash check explicitly returned stale=false
# (build failed for a non-hash reason).
# (check failed for a non-hash reason).
- name: Clear sticky PR comment (resolved)
if: |
github.event_name == 'pull_request' &&
runner.os == 'Linux' &&
(steps.hash_check.outputs.stale == 'false' ||
(steps.flake.outcome == 'success' && steps.build.outcome == 'success'))
steps.flake.outcome == 'success')
uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
with:
header: nix-lockfile-check
delete: true

- name: Final fail if build or flake failed
if: steps.flake.outcome == 'failure' || steps.build.outcome == 'failure'
- name: Final fail if flake check failed
if: steps.flake.outcome == 'failure'
run: |
if [ "${{ steps.hash_check.outputs.stale }}" == "true" ]; then
echo "::error::Nix build failed due to stale npm lockfile hash. Run: nix run .#fix-lockfiles"
else
echo "::error::Nix build/flake check failed. See logs above."
echo "::error::Nix flake check failed. See logs above."
fi
exit 1

- name: Evaluate flake (macOS)
if: runner.os == 'macOS'
run: nix flake show --json > /dev/null
4 changes: 1 addition & 3 deletions .github/workflows/osv-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ on:
- 'package.json'
- 'package-lock.json'
- 'ui-tui/package.json'
- 'ui-tui/package-lock.json'
- 'website/package.json'
- 'website/package-lock.json'
- '.github/workflows/osv-scanner.yml'
Expand All @@ -39,7 +38,6 @@ on:
- 'pyproject.toml'
- 'package.json'
- 'package-lock.json'
- 'ui-tui/package-lock.json'
- 'website/package-lock.json'
schedule:
# Weekly scan against main — catches CVEs published after merge for
Expand All @@ -62,6 +60,6 @@ jobs:
# the three sources of truth and skip vendored / test / worktree dirs.
scan-args: |-
--lockfile=uv.lock
--lockfile=ui-tui/package-lock.json
--lockfile=package-lock.json
--lockfile=website/package-lock.json
fail-on-vuln: false
5 changes: 5 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ jobs:
source .venv/bin/activate
uv pip install -e ".[all,dev]"

- name: Packaged-wheel i18n smoke test
run: |
source .venv/bin/activate
python -m pytest -m integration tests/test_wheel_locales_e2e.py -v

- name: Run e2e tests
run: |
source .venv/bin/activate
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,9 @@ docs/superpowers/*
# Tool Search live-test harness output — non-deterministic model transcripts,
# regenerated by scripts/tool_search_livetest.py. Never an artifact of the repo.
scripts/out/

# Per-release changelog drafts. These exist only transiently during a release
# cut (passed to `gh release create --notes-file`); the GitHub Release itself
# stores the published notes. They are not a build artifact and must never be
# committed to the repo root. See the hermes-release skill.
RELEASE_v*.md
25 changes: 25 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,21 @@ The dashboard embeds the real `hermes --tui` — **not** a rewrite. See `hermes

**Structured React UI around the TUI is allowed when it is not a second chat surface.** Sidebar widgets, inspectors, summaries, status panels, and similar supporting views (e.g. `ChatSidebar`, `ModelPickerDialog`, `ToolCall`) are fine when they complement the embedded TUI rather than replacing the transcript / composer / terminal. Keep their state independent of the PTY child's session and surface their failures non-destructively so the terminal pane keeps working unimpaired.

### Electron Desktop Chat App (`apps/desktop/`)

A **separate** chat surface from both the classic CLI and the dashboard's embedded TUI. It is an Electron + React + nanostore renderer (`@assistant-ui/react`) that talks to a `tui_gateway` backend over JSON-RPC (`requestGateway(method, params)`). It does NOT embed `hermes --tui` — it has its own composer, transcript, and slash-command pipeline. Route desktop bugs to the `hermes-desktop-app-work` skill, not `hermes-dashboard-work`.

**Slash commands in the desktop app are curated client-side, then dispatched to the backend.** The pipeline:

- **Backend already provides everything.** `tui_gateway/server.py` `commands.catalog` (empty-query list) and `complete.slash` (typed-query completions) both include built-in commands, user `quick_commands`, AND skill-derived commands (`scan_skill_commands()` / `get_skill_commands()`). The desktop app does not need a new RPC to see skills.
- **The renderer curates via `apps/desktop/src/lib/desktop-slash-commands.ts`.** This is the load-bearing file. It holds `DESKTOP_COMMANDS` (the ~19 built-ins shown in the palette) plus block-lists for terminal-only / messaging-only / picker-owned / settings-owned / advanced commands that should NOT clutter the desktop popover.
- `isDesktopSlashCommand(name)` — gates **execution**. Returns true for built-ins AND for any non-built-in (skill / quick command), so typed extension commands run.
- `isDesktopSlashSuggestion(name)` — gates **discovery/completion**. Used by BOTH completion paths in `app/chat/composer/hooks/use-slash-completions.ts` (empty-query catalog filter + typed-query `complete.slash` filter) and by `filterDesktopCommandsCatalog`.
- `isDesktopSlashExtensionCommand(name)` — true when the command is NOT a known Hermes built-in (i.e. a skill or user quick command). Both suggestion and catalog-filter paths allow extensions through so skill commands surface in the palette. (Added when fixing "skill commands missing from the desktop slash palette" — the curated allow-list was silently dropping every skill/quick command from completions even though they executed fine when typed.)
- **Dispatch** lives in `app/session/hooks/use-prompt-actions.ts` (`runSlash`): built-ins that the desktop owns (`/skin`, `/help`, `/new`, …) are handled locally or via `commands.catalog`; everything else goes to `slash.exec`, falling back to `command.dispatch` (which the gateway resolves into skill / alias / exec directives). A skill command resolves to `{type: "skill", message}` and is submitted as a normal prompt.

**Rule:** the desktop slash palette's curation is about hiding noise (terminal-only / messaging-only built-ins), NOT about hiding user-activated extensions. Skill commands and `quick_commands` are extensions the backend surfaces — they belong in completions. If you tighten `desktop-slash-commands.ts`, keep `isDesktopSlashExtensionCommand` flowing into both the suggestion and catalog-filter paths. Tests: `apps/desktop/src/lib/desktop-slash-commands.test.ts` (run via the repo-root `vitest`, since `apps/desktop` resolves deps from the root workspace install).

---

## Adding New Tools
Expand Down Expand Up @@ -766,6 +781,16 @@ Key config knobs (under `delegation:` in `config.yaml`):
`orchestrator_enabled`, `subagent_auto_approve`, `inherit_mcp_toolsets`,
`max_iterations`.

**MCP toolset resolution for named profiles:** When `_build_child_agent()`
is called with `profile_name` set (i.e. the delegation originated from a
named `agent_profiles` entry), MCP toolsets in the requested list bypass
the parent-intersection check and are resolved directly from the global
`mcp_servers` config. This prevents a silent failure mode where an
orchestrator that restricts its own MCP context (via `no_mcp` in
`platform_toolsets`) inadvertently starves child agents of domain MCP tools
they explicitly need. Non-MCP toolsets still go through parent intersection
— the security boundary for ad-hoc delegation is preserved. See #32668.

Synchronicity rule: delegate_task is **not** durable. For long-running
work that must outlive the current turn, use `cronjob` or
`terminal(background=True, notify_on_complete=True)` instead.
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ This isn't a quality bar — it's a coupling-and-maintenance decision. Memory pr

| Requirement | Notes |
|-------------|-------|
| **Git** | With `--recurse-submodules` support, and the `git-lfs` extension installed |
| **Git** | With the `git-lfs` extension installed |
| **Python 3.11+** | uv will install it if missing |
| **uv** | Fast Python package manager ([install](https://docs.astral.sh/uv/)) |
| **Node.js 20+** | Optional — needed for browser tools and WhatsApp bridge (matches root `package.json` engines) |

### Clone and install

```bash
git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git
git clone https://github.com/NousResearch/hermes-agent.git
cd hermes-agent

# Create venv with Python 3.11
Expand Down
32 changes: 27 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ WORKDIR /opt/hermes
# ui-tui/package.json. Copying the tree up front lets npm resolve the
# workspace to real content instead of stopping at a bare package.json.
COPY package.json package-lock.json ./
COPY web/package.json web/package-lock.json web/
COPY ui-tui/package.json ui-tui/package-lock.json ui-tui/
COPY web/package.json web/
COPY ui-tui/package.json ui-tui/
COPY ui-tui/packages/hermes-ink/ ui-tui/packages/hermes-ink/

# `npm_config_install_links=false` forces npm to install `file:` deps as
Expand All @@ -131,8 +131,6 @@ ENV npm_config_install_links=false

RUN npm install --prefer-offline --no-audit && \
npx playwright install --with-deps chromium --only-shell && \
(cd web && npm install --prefer-offline --no-audit) && \
(cd ui-tui && npm install --prefer-offline --no-audit) && \
npm cache clean --force

# ---------- Layer-cached Python dependency install ----------
Expand All @@ -159,10 +157,17 @@ RUN npm install --prefer-offline --no-audit && \
# so Docker users can use these providers without requiring runtime
# lazy-install access to PyPI (often blocked in containerized envs).
#
# The hindsight memory provider's client (hindsight-client) is baked in
# for the same reason: it lazy-installs into /opt/hermes/.venv at first
# use, which lives inside the (immutable) image layer rather than the
# mounted /opt/data volume, so it is lost on every container recreate /
# image update and recall/retain then fails with
# `ModuleNotFoundError: No module named 'hindsight_client'` (#38128).
#
# The editable link is created after the source copy below.
COPY pyproject.toml uv.lock ./
RUN touch ./README.md
RUN uv sync --frozen --no-install-project --extra all --extra messaging --extra anthropic --extra bedrock --extra azure-identity
RUN uv sync --frozen --no-install-project --extra all --extra messaging --extra anthropic --extra bedrock --extra azure-identity --extra hindsight

# ---------- Source code ----------
# .dockerignore excludes node_modules, so the installs above survive.
Expand Down Expand Up @@ -245,6 +250,23 @@ COPY --chmod=0755 docker/cont-init.d/02-reconcile-profiles /etc/cont-init.d/02-r

# ---------- Runtime ----------
ENV HERMES_WEB_DIST=/opt/hermes/hermes_cli/web_dist
# Point the TUI launcher at the prebuilt bundle baked at build time (Layer 8:
# `ui-tui && npm run build`). This makes _make_tui_argv take the prebuilt-bundle
# fast path (`node --expose-gc /opt/hermes/ui-tui/dist/entry.js`) and skip the
# _tui_need_npm_install / runtime `npm install` branch entirely — exactly the
# nix/packaged-release path the launcher was designed for.
#
# Why this is required (not just an optimization): the root package-lock.json
# describes the WHOLE monorepo workspace set (root + web + ui-tui + apps/*),
# but the image only installs root/web/ui-tui (apps/* — the desktop app — is
# never `npm install`ed here). So the actualized node_modules permanently
# disagrees with the canonical lock, _tui_need_npm_install() returns True on
# every launch, and the runtime `npm install` it triggers (a) can never
# converge against the partial monorepo and (b) races itself across concurrent
# embedded-chat (/api/pty) connections → ENOTEMPTY → the chat tab dies with a
# 502 / "[session ended]". Pointing at the prebuilt bundle sidesteps the whole
# check. (A separate launcher hardening is tracked independently.)
ENV HERMES_TUI_DIR=/opt/hermes/ui-tui
ENV HERMES_HOME=/opt/data

# `docker exec` privilege-drop shim. When operators run
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
graft skills
graft optional-skills
graft locales
# Bundled plugin manifests (plugin.yaml / plugin.yml). Without these the
# PluginManager scan (hermes_cli/plugins.py) finds zero plugins on installs
# built from the sdist (e.g. Homebrew, downstream packagers). package-data
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ One command from a fresh install:
hermes setup --portal
```

That logs you in via OAuth, sets Nous as your provider, and turns on the Tool Gateway. Check what's wired up any time with `hermes portal status`. Full details on the [Tool Gateway docs page](https://hermes-agent.nousresearch.com/docs/user-guide/features/tool-gateway).
That logs you in via OAuth, sets Nous as your provider, and turns on the Tool Gateway. Check what's wired up any time with `hermes portal info`. Full details on the [Tool Gateway docs page](https://hermes-agent.nousresearch.com/docs/user-guide/features/tool-gateway).

You can still bring your own keys per-tool whenever you want — the gateway is per-backend, not all-or-nothing.

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Hermes 始终允许你使用任意服务商,这点不会改变。但如果你
hermes setup --portal
```

它会通过 OAuth 登录、把 Nous 设为推理服务商,并启用 Tool Gateway。随时用 `hermes portal status` 查看路由状态。完整说明见 [Tool Gateway 文档](https://hermes-agent.nousresearch.com/docs/user-guide/features/tool-gateway)。
它会通过 OAuth 登录、把 Nous 设为推理服务商,并启用 Tool Gateway。随时用 `hermes portal info` 查看路由状态。完整说明见 [Tool Gateway 文档](https://hermes-agent.nousresearch.com/docs/user-guide/features/tool-gateway)。

你随时可以按工具单独切回自己的 API Key — Gateway 是按工具粒度生效的,不是一刀切。

Expand Down
27 changes: 0 additions & 27 deletions RELEASE_v0.10.0.md

This file was deleted.

Loading