Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
371 commits
Select commit Hold shift + click to select a range
967e078
fix(windows): share one bounded, tree-killing git probe across both c…
OutThisLife Jul 22, 2026
b11b5ec
fix(tui): revision-aware reload.mcp β€” an ack now means the revision w…
OutThisLife Jul 22, 2026
e6cc561
fix(ui-tui): boot theme cache gets provenance β€” a stale hint can't pi…
OutThisLife Jul 22, 2026
c25e08a
fix(ui-tui): stacked dialog gets input before the grid under it
OutThisLife Jul 22, 2026
9fb2a63
fix(ui-tui): make `npm run visual` portable off POSIX β€” zero new deps
OutThisLife Jul 22, 2026
cd24efe
perf(ui-tui): shimmer loaders share one clock and stop after a bounde…
OutThisLife Jul 22, 2026
7d757cf
fmt(js): prettier pass on the new review tests
OutThisLife Jul 22, 2026
502939e
chore: gitignore node_modules symlinks, not just directories
OutThisLife Jul 22, 2026
3de91c6
fix(desktop): stop long-session transcript from drifting to old turns…
OutThisLife Jul 22, 2026
5c714be
ci: retrigger (transient setup-uv manifest fetch flake)
OutThisLife Jul 22, 2026
32a9f2a
Merge pull request #68999 from NousResearch/bb/widget-grid-hardening
OutThisLife Jul 22, 2026
d8fcab4
feat(ui-tui): widget-app SDK β€” registry, host, dispatch; demos become…
OutThisLife Jul 21, 2026
fc3be32
feat(ui-tui): weather reference app β€” the async-data contract, themed…
OutThisLife Jul 21, 2026
76b58d6
feat(ui-tui): ambient widget mode β€” registry-driven slash catalog + i…
OutThisLife Jul 21, 2026
ca0b1b1
feat(ui-tui): self-authored widgets β€” user-widget loader, hot-load, s…
OutThisLife Jul 21, 2026
ed93d6a
feat(ui-tui): widget primitives β€” charts, accordion, shimmer, stable …
OutThisLife Jul 21, 2026
a7e2671
docs(skill): tui-widgets β€” auto-open recipe (openWidget at end of reg…
OutThisLife Jul 21, 2026
9627d4f
feat(ui-tui): ambient zone system + widget crash boundary
OutThisLife Jul 21, 2026
2ed61d4
refactor(ui-tui): host placement router + grid-test width-floor fix
OutThisLife Jul 21, 2026
a8444fb
feat(themes): cross-surface theme SDK β€” one skin themes CLI, TUI, and…
OutThisLife Jul 21, 2026
91c5c0c
fix(themes): activate skins via `hermes config set`, never a config.y…
OutThisLife Jul 21, 2026
eb45491
feat(themes): agent-authored skins switch live via a gateway skin wat…
OutThisLife Jul 21, 2026
727f670
feat(themes): TUI paints its own background from the skin (OSC 11)
OutThisLife Jul 22, 2026
30ee6f7
feat(themes): element tokens (ui_tool, ui_thinking) + skinnable diffs
OutThisLife Jul 22, 2026
2a4e5fa
fix(themes): tweak the ACTIVE skin in place, never fork default
OutThisLife Jul 22, 2026
4f4f938
feat(themes): `hermes skin set` β€” deterministic one-color tweak, bg u…
OutThisLife Jul 22, 2026
3ba6eeb
feat(themes): dedicated code-syntax palette keys
OutThisLife Jul 22, 2026
428a053
test(themes): E2E live skin switch β€” config write β†’ skin.changed broa…
OutThisLife Jul 22, 2026
50170fd
fix(themes): reconcile element/syntax tokens with main's derive+adapt…
OutThisLife Jul 22, 2026
300a0f1
fix(themes): apply a runtime switch back to default on the desktop
OutThisLife Jul 22, 2026
850b8da
fix(tui_gateway): serve candidate-inclusive display on warm/live resume
OutThisLife Jul 22, 2026
77855ce
fix(tui_gateway): candidate-inclusive display on child-watch resume +…
OutThisLife Jul 22, 2026
ef81d9d
fix(cli): add skin to _BUILTIN_SUBCOMMANDS for plugin gating
OutThisLife Jul 22, 2026
8f51376
Merge pull request #69040 from NousResearch/bb/fix-verify-candidate-w…
OutThisLife Jul 22, 2026
7dc535a
Merge pull request #68306 from NousResearch/bb/tui-widget-sdk
OutThisLife Jul 22, 2026
367810a
Merge pull request #68857 from NousResearch/bb/theme-sdk
OutThisLife Jul 22, 2026
5c4c419
fmt(js): `npm run fix` on merge (#69048)
hermes-seaeye[bot] Jul 22, 2026
7c68b4e
feat(desktop): Billing page revamp β€” current-plan card, in-app plans …
alt-glitch Jul 22, 2026
14f8441
fmt(js): `npm run fix` on merge (#69050)
hermes-seaeye[bot] Jul 22, 2026
9baad4e
feat(cli): plan catalog on Free + plan= deep link + top-up/auto-refil…
alt-glitch Jul 22, 2026
60ec6a3
feat(desktop): native in-app downgrade β€” chargeless preview β†’ schedul…
alt-glitch Jul 22, 2026
d8bf3df
fmt(js): `npm run fix` on merge (#69067)
hermes-seaeye[bot] Jul 22, 2026
3493a6c
fix(desktop): feed memory.provider dropdown from live discovery
austinpickett Jul 22, 2026
baa3bf3
refactor: make memory.provider schema-driven instead of a 2nd fetch
austinpickett Jul 22, 2026
e60a4cc
refactor: tidy dynamic schema-options merge
austinpickett Jul 22, 2026
fd96e13
fix(gateway): hard-exit CLI runner after graceful teardown
web3blind Jul 21, 2026
c9ab8ba
test: update gateway run stub for hard-exit helper
web3blind Jul 21, 2026
4425ddd
fix(gateway): hard-exit on KeyboardInterrupt path too
kshitijk4poor Jul 21, 2026
1c0a578
fix(cli): pass conversation_history on /new /resume /branch flush
Bartok9 Jul 21, 2026
a46fbaf
test: drop source-grep change-detector from #68480
kshitijk4poor Jul 21, 2026
e57918a
test: update mock assertions for conversation_history kwarg
kshitijk4poor Jul 22, 2026
2ab1532
fix(gateway): make adapter fatal-error handoff cancellation-proof; ex…
anoopmehendale-cue Jul 21, 2026
4999de8
chore: map anoop.mehendale@gmail.com -> anoopmehendale-cue
kshitijk4poor Jul 22, 2026
e99882c
fix(update): isolate systemctl timeouts per gateway unit during fleet…
HexLab98 Jul 21, 2026
b7b0c37
test(update): cover fleet restart timeout isolation (#68523)
HexLab98 Jul 21, 2026
52d219b
fix: refresh vulnerable npm lockfile entries
Jul 21, 2026
3e953ed
chore: AUTHOR_MAP for tinetwork
kshitijk4poor Jul 22, 2026
377244f
fix(compression): prevent stale-budget retry loops
cucurigoo Jul 21, 2026
97499d7
fix(compression): harden startup route scoping
cucurigoo Jul 21, 2026
cb785e6
fix(providers): align custom route scoping
cucurigoo Jul 22, 2026
ca6b8cd
test(compression): cover overflow after blocked preflight
cucurigoo Jul 22, 2026
fcae6fb
test(providers): cover route URL identity boundaries
cucurigoo Jul 22, 2026
2507af2
test(providers): cover query path slash identity
cucurigoo Jul 22, 2026
639cee5
test(providers): complete hermetic route coverage
cucurigoo Jul 22, 2026
ddd6675
test(providers): cover URL whitespace route identity
cucurigoo Jul 22, 2026
f3f0135
fix(providers): fail closed on missing active route
cucurigoo Jul 22, 2026
63dd651
fix(providers): scope route-owned runtime settings
cucurigoo Jul 22, 2026
9fa2906
fix: restore base_url rstrip, extract should_clear_context_pin helper
kshitijk4poor Jul 22, 2026
f489601
fix(compression): ignore assistant handoff summaries in tail anchor
McHersheys Jul 21, 2026
9eb7b1a
chore: AUTHOR_MAP for McHermes
kshitijk4poor Jul 22, 2026
45fce38
fix(telegram): group authz fallback + command sender identity
Jul 20, 2026
7078430
fix(telegram): address review findings from PR #67816
kshitijk4poor Jul 22, 2026
9ecacd6
fix(telegram): update auth check tests for group_allow_from split
kshitijk4poor Jul 22, 2026
323e9ba
fix(openviking): recover pending session commits
ehz0ah Jul 5, 2026
f7c198d
docs: clarify OpenViking local setup
NPFernando Jun 2, 2026
3fd9658
fix(openviking): serialize orphan session recovery
ehz0ah Jul 18, 2026
81fc424
fix(openviking): chunk structured session sync
ckorhonen Jul 18, 2026
c3c80e1
refactor: cleanup follow-up for salvaged PR #58871
kshitijk4poor Jul 22, 2026
11c1ca0
fix(openviking): inject session-start memory context
itsflownium Jun 30, 2026
8af2133
fix(openviking): align session context with shared profile contract
ehz0ah Jul 17, 2026
0c76cc6
fix: discard both session IDs on compression for profile re-injection
Jul 22, 2026
7de5542
chore: add kshitij@kshitij.dev to AUTHOR_MAP
Jul 22, 2026
77f3b3e
fix(secrets): fall back to stale disk cache when bws live fetch fails
jackjin1997 Jun 8, 2026
7db521a
fix(secrets): port stale-cache fallback to current DiskCache API + ga…
jackjin1997 Jul 14, 2026
a616b9f
fix(secrets): fold OP_CONNECT_HOST/OP_CONNECT_TOKEN into 1Password au…
briandevans Jul 7, 2026
fe8c0f7
fix(secrets): pass OP_LOAD_DESKTOP_APP_SETTINGS through to the op chi…
menhguin Jul 11, 2026
2beed8b
fix(mcp): pass secret-source-injected env vars to stdio servers
westkite1201 Jul 22, 2026
fe5d0be
fix(env): stop printing Bitwarden secret names
andrexibiza Jul 7, 2026
8e089db
fix(secrets): validate bitwarden status token
izumi0uu Jun 6, 2026
c7b0c0d
fix(secrets): mark _APPLIED_HOMES only after a real fetch attempt (#4…
teknium1 Jul 22, 2026
c758ded
fix(secrets): fall back to os.environ on scope miss when multiplexing…
Soju06 Jul 20, 2026
e66e02d
test(gateway): activate multiplex flag in cross-profile env isolation…
teknium1 Jul 22, 2026
86fb046
feat(secrets): orchestrator-level preserve_existing + profile aliasin…
teknium1 Jul 22, 2026
ff46376
fix(gateway): preserve shared route transport adapter
yungchentang Jul 16, 2026
c6f9e0c
test(gateway): cover routed transport delivery
yungchentang Jul 16, 2026
0583692
fix(secrets): scope BWS-injected provider keys
izumi0uu Jul 4, 2026
0c4cab5
test(secrets): match real ApplyReport shape in isolation test
teknium1 Jul 22, 2026
4c64ff3
feat(nous): send top-level session_id for provider sticky routing (#6…
teknium1 Jul 22, 2026
3d5dd8e
feat(secrets): add `command` secret source + unified secrets.provider…
0xr00tf3rr3t Jun 11, 2026
4f0ee4d
feat(secrets): rework command source as a registered SecretSource β€” n…
teknium1 Jul 22, 2026
1cb67a5
chore: suppress windows-footgun on the POSIX-gated killpg call
teknium1 Jul 22, 2026
8d811f5
feat(config): resolve ${env:VAR} SecretRefs in config.yaml, matching …
teknium1 Jul 22, 2026
1384087
fix(secrets): add encrypted Bitwarden stale cache
andyylin Jul 16, 2026
e89216e
fix(secrets): harden encrypted Bitwarden cache
andyylin Jul 19, 2026
0faf4c8
fix(secrets): unify encrypted-cache fallback with the merged stale-ca…
teknium1 Jul 22, 2026
9acc4b4
perf(state): external-content FTS + tool-row-free trigram index (sche…
teknium1 Jul 22, 2026
8967e73
fix(cli): restart managed dashboard service after update (#39166)
andyylin Jul 22, 2026
9fed768
fix(desktop): scope model options by profile (#62795)
embwl0x Jul 22, 2026
7857d87
feat(dashboard-auth): RFC 8252 native desktop sign-in (system browser…
benbarclay Jul 20, 2026
49423f8
fix(desktop-auth): make RFC 8252 native login work end-to-end at runtime
benbarclay Jul 22, 2026
edebe45
chore(desktop): drop unrelated assistant-ui bump + lockfile churn
teknium1 Jul 22, 2026
4d23b22
fix(dashboard-auth): harden the public native-authorize surface
teknium1 Jul 22, 2026
93ff129
fix(gateway): follow async completions across compression
richkapp Jul 14, 2026
f1a1d2d
chore(release): map richkapp in AUTHOR_MAP
teknium1 Jul 22, 2026
b120121
fix(gateway): honest durable ack semantics for undeliverable async co…
teknium1 Jul 22, 2026
85f04d4
fix(gateway): Responses API stores bloated context after compression
LiangYang666 Jul 4, 2026
806b34c
test(gateway): add regression test for compressed Responses transcrip…
LiangYang666 Jul 4, 2026
2ced026
feat(api_server): persist compressed messages to prevent re-compression
LiangYang666 Jul 16, 2026
f66e773
fix(gateway): in-place compression not persisted in response_store
LiangYang666 Jul 16, 2026
a26ed50
test(gateway): exercise real compression detection path with fake agents
LiangYang666 Jul 16, 2026
4166fdd
fix(api_server): log warning when compressed response_store persist f…
LiangYang666 Jul 17, 2026
146a545
chore(contributors): map LiangYang666 emails
teknium1 Jul 22, 2026
1c21e96
refactor(api): dedupe compressed-transcript persist sites, drop confi…
teknium1 Jul 22, 2026
3807df7
fix(api-server): preserve compaction summaries on auto truncation
ooiuuii Jun 29, 2026
28b6bd6
fix(api): preserve compaction summaries at any history position durin…
teknium1 Jul 22, 2026
644b397
fix(agent): make the compression retry cap config-driven (compression…
Kenmege Jul 13, 2026
fca883f
fix(compaction): cap post-tool attempts per turn
dombejar Jul 13, 2026
cf433a3
chore: map dombejar contributor email for PR #63870 salvage
teknium1 Jul 22, 2026
1c2faed
fix(compression): unify the attempt cap across every compression site
teknium1 Jul 22, 2026
c93e404
fix(compression): preserve zero-user provenance
embwl0x Jul 14, 2026
7de7a07
fix(compression): preserve synthetic user provenance
embwl0x Jul 16, 2026
a269a5b
docs(compression): note acceptable false-positive path in zero-user p…
teknium1 Jul 22, 2026
3f33a1c
fix(compression): handle CJK token budgeting
Jun 25, 2026
ea0fd39
perf(compression): gate CJK-aware token estimation behind an ASCII fa…
teknium1 Jul 22, 2026
928bcdd
fix(compression): refresh gateway activity during compaction
WeiYusc Jul 5, 2026
7f9956a
chore: map contributor email for @WeiYusc
teknium1 Jul 22, 2026
8fceaac
test(compression): adapt strict-signature heartbeat test to signature…
teknium1 Jul 22, 2026
1e0f5a6
fix(slack): detect Block-Kit-only @mentions in bot filter and router
Bartok9 Jun 25, 2026
1f92842
fix(slack): read thread context from attachments and blocks
xcompass Jul 9, 2026
3865694
fix(slack): surface Block Kit content in fetched thread context
bpross Jul 22, 2026
453d0ee
chore(contributors): map emails for slack block-text salvage (#29541,…
teknium1 Jul 22, 2026
63e363f
fix(codex): scope app-server notifications to active turn
Jul 12, 2026
2eb6c84
fix(codex): wait for compaction turn identity
Jul 16, 2026
8a580e8
chore: add contributor mapping for tandixit95
teknium1 Jul 22, 2026
4c2e34f
fix(moa): measure advisor guidance before compression
frizikk Jul 16, 2026
cb39be9
fix: update test assertions for /compact -> /compress rename
liuhao1024 Jul 2, 2026
27a4e92
fix(acp,tui): rename /compact to /compress and /density to resolve co…
liuhao1024 Jul 2, 2026
15d33d5
fix(desktop,tui,docs): dedup commands.catalog, route desktop /compact…
teknium1 Jul 22, 2026
d46f0fb
fix(compression): notify context engine after commit
the3asic Jul 16, 2026
7d4ed8e
chore(release): map the3asic noreply email for contributor attribution
teknium1 Jul 22, 2026
1927b60
fix(tui): extend deferred context-engine finalize to the compute-host…
teknium1 Jul 22, 2026
9d73006
fix: forward timestamp in CLI, gateway, and TUI branch copy loops
Jun 17, 2026
961b832
test(sessions): cover branch-seed and compression timestamp round-trips
teknium1 Jul 22, 2026
870770b
fix(slack): harden rich table block fallback
tw0316 Jul 1, 2026
d91a143
fix(slack): guard rich_text builders against empty content rejected a…
kamonspecial Jul 6, 2026
8fc0c08
fix: replace assert with runtime guard in Slack block_kit rich_text b…
AlexFucuson9 Jul 14, 2026
c13af09
fix(slack): truncate inflated original_text in approval/confirm chat.…
liuhao1024 Jun 27, 2026
a2d8b4b
fix(slack): guard against empty text in chat.postMessage
liuhao1024 Jun 25, 2026
72da4f8
fix(slack): truncate edit_message content to prevent msg_too_long
sowork-skills Jul 22, 2026
a43ac2a
fix(slack): sanitize outbound Block Kit payloads at the API boundary
teknium1 Jul 22, 2026
b2ba069
test(slack): regression tests for Block Kit boundary sanitizer and ov…
teknium1 Jul 22, 2026
295e203
feat(delegation): let subagents use execute_code (#69325)
teknium1 Jul 22, 2026
dbc71fb
fix(compression): don't recommend a threshold the small-context floor…
Sora-bluesky Jul 19, 2026
19a59f7
fix(compression): mirror the full trigger recomputation in the sugges…
Sora-bluesky Jul 19, 2026
cca7b93
chore(contributors): register Sora-bluesky email mapping
Sora-bluesky Jul 22, 2026
004de13
fix(memory/holographic): don't harvest compaction summaries; honor au…
wernerhp Jul 3, 2026
cc84af9
fix(memory): preserve genuine pre-delimiter content in merged compact…
wernerhp Jul 15, 2026
17fa591
chore: map contributor wernerhp
teknium1 Jul 22, 2026
e71c113
fix(anthropic): prepend user turn when compaction leaves a leading as…
fesalfayed Jun 25, 2026
b6a2b70
fix(anthropic): extend leading-user guard to the extracted-system-abs…
teknium1 Jul 22, 2026
3c74c12
fix(state): inherit cwd/git_repo_root on parent_session_id children
Jul 15, 2026
75099ca
fix(state): inherit git_branch + gateway origin columns on compressio…
teknium1 Jul 22, 2026
9bb253d
fix(tools): filter compaction summaries from session_search bookends …
liuhao1024 Jun 10, 2026
596dda9
fix(agent): create built-in memory store when memory toolset is enabl…
Jul 16, 2026
4518240
fix(agent): add regression test for #65429 (memory store with skip_me…
Jul 16, 2026
f453c50
test(memory): behavioral check β€” memory tool handler works with skip_…
teknium1 Jul 22, 2026
5f2fdf6
feat: per-model compression threshold overrides (v2, rebased on main)
Jul 12, 2026
f944e84
fix: close review gaps for per-model threshold overrides (#63020)
teknium1 Jul 22, 2026
95aad92
feat(slack): Block Kit buttons for clarify prompts
Jul 22, 2026
07cbb50
fix(clarify): reject arbitrary prose for native interactive multi-cho…
liuhao1024 Jul 22, 2026
76283a9
fix(gateway): suppress tool-progress bubble for clarify prompts
teknium1 Jul 22, 2026
d358280
test(gateway): thread follow-ups survive a pending native clarify
teknium1 Jul 22, 2026
77beb6a
fix(slack): set non-retryable fatal error on missing Slack credentials
x7peeps Jul 22, 2026
54a0f07
fix(gateway): mark unconfigured platforms as non-retryable to stop re…
dskwe Jul 22, 2026
7bbdabb
fix(slack): stop client tasks before closing the Socket Mode session
juniperbevensee Jul 18, 2026
caf8e2f
fix(slack): heal wedged Socket Mode via ping/pong staleness
Jun 26, 2026
45556b7
fix(slack): close clients on gateway shutdown
LeonSGP43 Jun 24, 2026
3c5c389
fix(slack): widen Socket Mode dedup TTL to cover reconnect redelivery
MrAbsaroka Jul 22, 2026
40c3b62
chore(contributors): map MrAbsaroka and 87degrees emails
teknium1 Jul 22, 2026
2d71e9e
fix(slack): ignore stale thread sessions when gating thread-context r…
ooiuuii Jul 22, 2026
c8089da
fix(slack): include bot's own prior replies in cold-start thread context
temalo Jul 22, 2026
fd433e0
fix(slack): preserve thread context for commands via channel_context
LevSky22 Jul 22, 2026
ad40347
fix(slack): refresh active thread context on explicit mention
heathley Jul 22, 2026
fc0009b
fix(slack): rehydrate thread context after gateway restart
vexclawx31 Jul 22, 2026
fee392f
fix(slack): wake on human replies in threads whose root we authored
knoal Jul 22, 2026
73d5c89
fix(slack): route replies from mentioned thread parents
kaiyisg Jul 22, 2026
503c0c0
fix(slack): expose shared-thread author mention target
LeonSGP43 Jul 22, 2026
5d747a9
fix(slack): humanize inbound user mentions + ground bot identity
benbarclay Jul 22, 2026
17155e3
chore(contributors): add email mappings for slack thread-lifecycle sa…
teknium1 Jul 22, 2026
b10952e
feat(state): cjk_unicode61 FTS5 tokenizer β€” unicode61 + CJK bigrams (…
Soju06 Jul 22, 2026
8364576
feat(state): slow-query log for session search with routing-path attr…
Soju06 Jul 22, 2026
f13f845
feat(state): messages_fts_cjk β€” CJK-bigram index on the v23 external-…
teknium1 Jul 22, 2026
bc48241
fix(compression): preserve latest actionable user turn
John-Lussier Jul 11, 2026
97cd0d9
test(compression): cover leading and input-text blanks
John-Lussier Jul 11, 2026
2ee50c6
docs(compression): note blank-echo removal survives summary abort
teknium1 Jul 22, 2026
0acdf1d
fix(compression): apply strict redaction at every compaction text bou…
teknium1 Jul 22, 2026
e5078e3
feat(compression): add absolute token threshold via compression.thres…
DanielMaly Jul 13, 2026
020bd1b
test(compression): behavioral + config wiring coverage for threshold_…
teknium1 Jul 22, 2026
2b84ed9
fix: dedupe persisted compaction handoffs
WXBR Jul 15, 2026
5a3ee3c
fix(compression): let handoff-strip supersede the head-copy skip
teknium1 Jul 22, 2026
356ff99
feat: log compression attempt telemetry
deltaahead Jul 7, 2026
cbc1054
fix: adapt compression attempt logging to current main aux-call contract
teknium1 Jul 22, 2026
08ea88f
fix(agent): decay protected summaries after restart
harjothkhara Jul 22, 2026
a4aedde
test(compression): adapt salvaged pins to task-snapshot grounding + a…
teknium1 Jul 22, 2026
76e17bc
fix(compression): recover merged-handoff prior-tail content through t…
teknium1 Jul 22, 2026
72056fa
feat(compression): add opt-in idle-triggered context compaction
iso2kx Jun 30, 2026
1efe709
feat(compression): harden idle compaction β€” lock/guard interplay, con…
teknium1 Jul 22, 2026
163fab8
Merge pull request #69077 from NousResearch/bb/desktop-memory-dropdow…
OutThisLife Jul 22, 2026
bcc3396
fmt(js): `npm run fix` on merge (#69503)
hermes-seaeye[bot] Jul 22, 2026
72dd01c
fix(desktop): no per-paragraph action bars on sealed interim messages
OutThisLife Jul 22, 2026
9b1028f
Merge pull request #69501 from NousResearch/bb/interim-message-actions
OutThisLife Jul 22, 2026
cbf5b05
feat(agent): add active-turn redirect core primitive
OutThisLife Jul 13, 2026
f6d2ee4
feat(codex): honor redirect and hard stop in the app-server runtime
OutThisLife Jul 13, 2026
f071f42
feat(desktop): let the agent open the preview pane
OutThisLife Jul 22, 2026
e4877ba
flatten assistant message actions into an inline icon row
OutThisLife Jul 22, 2026
34d0de8
feat(surfaces): route busy-input corrections through active-turn redi…
OutThisLife Jul 13, 2026
79b0478
docs: describe active-turn redirect busy-input behavior
OutThisLife Jul 13, 2026
3d40a1c
feat(desktop): Cursor-style stop-and-correct on the composer
OutThisLife Jul 13, 2026
70ba3c4
feat(desktop): agent can focus panes + shared desktop-UI event bridge
OutThisLife Jul 22, 2026
4204e6d
Merge pull request #69519 from NousResearch/bb/desktop-preview-open
OutThisLife Jul 22, 2026
ca244e2
refine inline message actions: fork icon, sine-wave read-aloud, share…
OutThisLife Jul 22, 2026
9160f10
fix(desktop): tsc clean before dev / build
OutThisLife Jul 22, 2026
59614ef
Merge pull request #69505 from NousResearch/bb/inline-msg-actions
OutThisLife Jul 22, 2026
96560ee
fix(agent): recover pure-Latin search matches embedded in CJK text (#…
gnanam1990 Jun 28, 2026
b591afe
test(state): cover pure-Latin embedded-in-CJK recovery via the cjk index
teknium1 Jul 22, 2026
2b27c17
fix(redirect): cover the build-window and post-reconnect correction r…
OutThisLife Jul 22, 2026
3459461
fix(themes): broadcast live skin.changed to WS surfaces (desktop/dash…
OutThisLife Jul 22, 2026
fea838c
fix(auth): detect upstream Codex quota resets and lift stale pool coo…
teknium1 Jul 22, 2026
9dbad81
fix(themes): re-affirming the active skin repaints surfaces that miss…
OutThisLife Jul 22, 2026
02fa447
fix(desktop): validate gateway WebSocket URLs
ethernet8023 Jul 22, 2026
5a40fd3
Merge pull request #69453 from NousResearch/bb/stale-js-shadow-guard
ethernet8023 Jul 22, 2026
c07973a
chore(gitignore): ignore installer .install_method stamp (salvage of …
Bartok9 Jul 22, 2026
bb24364
Merge pull request #63104 from NousResearch/bb/active-turn-steering
OutThisLife Jul 22, 2026
0ec4a87
fmt(js): `npm run fix` on merge (#69562)
hermes-seaeye[bot] Jul 22, 2026
39f72e4
refactor(themes): DRY the event frame, type the transport registry, t…
OutThisLife Jul 22, 2026
e0b9ab5
Merge pull request #69533 from NousResearch/bb/skin-live-broadcast
OutThisLife Jul 22, 2026
afd0270
fix(themes): repaint the desktop on an in-place edit of the active skin
OutThisLife Jul 22, 2026
87088d1
Merge pull request #69581 from NousResearch/bb/skin-live-edit-repaint
OutThisLife Jul 22, 2026
1bdd478
fix(desktop): scope submit drift guard to genuine session switches (#…
ethernet8023 Jul 22, 2026
ea55685
🎨 Palette: Improve accessibility of external docs button
MillionthOdin16 Jul 27, 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
  •  
  •  
  •  
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,13 @@ jobs:

review-labels:
name: Review label gate
needs: detect
if: needs.detect.outputs.event_name == 'pull_request' && (needs.detect.outputs.ci_review == 'true' || needs.detect.outputs.mcp_catalog == 'true')
needs: [detect, supply-chain]
if: always() && needs.detect.outputs.event_name == 'pull_request' && (needs.detect.outputs.ci_review == 'true' || needs.detect.outputs.mcp_catalog == 'true' || needs.supply-chain.outputs.critical_findings == 'true')
uses: ./.github/workflows/review-labels.yml
with:
ci_review: ${{ needs.detect.outputs.ci_review == 'true' }}
mcp_catalog: ${{ needs.detect.outputs.mcp_catalog == 'true' }}
supply_chain: ${{ needs.supply-chain.outputs.critical_findings == 'true' }}
secrets: inherit

osv-scanner:
Expand Down
18 changes: 12 additions & 6 deletions .github/workflows/review-labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ on:
description: Whether the MCP catalog / installer changed.
type: boolean
default: false
supply_chain:
description: Whether the critical supply-chain scan found a risk requiring review.
type: boolean
default: false
outputs:
ci_reviewed:
description: Whether the ci-reviewed label is present. Empty when neither input was true.
Expand All @@ -42,7 +46,7 @@ permissions:
jobs:
check:
name: Review label gate
if: inputs.ci_review || inputs.mcp_catalog
if: inputs.ci_review || inputs.mcp_catalog || inputs.supply_chain
runs-on: ubuntu-latest
timeout-minutes: 2
outputs:
Expand Down Expand Up @@ -75,15 +79,17 @@ jobs:
env:
CI_REVIEW: ${{ inputs.ci_review }}
MCP_CATALOG: ${{ inputs.mcp_catalog }}
SUPPLY_CHAIN: ${{ inputs.supply_chain }}
LABEL_PRESENT: ${{ steps.label-check.outputs.ci_reviewed }}
run: |
set -euo pipefail
ARGS=""
if [ "$CI_REVIEW" = "true" ]; then ARGS="$ARGS --ci-review"; fi
if [ "$MCP_CATALOG" = "true" ]; then ARGS="$ARGS --mcp-catalog"; fi
if [ "$LABEL_PRESENT" = "true" ]; then ARGS="$ARGS --label-present"; fi
args=()
if [ "$CI_REVIEW" = "true" ]; then args+=(--ci-review); fi
if [ "$MCP_CATALOG" = "true" ]; then args+=(--mcp-catalog); fi
if [ "$SUPPLY_CHAIN" = "true" ]; then args+=(--supply-chain); fi
if [ "$LABEL_PRESENT" = "true" ]; then args+=(--label-present); fi

python3 scripts/ci/emit_review_status.py $ARGS --output "$GITHUB_OUTPUT"
python3 scripts/ci/emit_review_status.py "${args[@]}" --output "$GITHUB_OUTPUT"

- name: Fail on missing label
if: steps.label-check.outputs.ci_reviewed != 'true'
Expand Down
44 changes: 17 additions & 27 deletions .github/workflows/supply-chain-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ name: Supply Chain Audit
# ``review-labels.yml`` so it can be rerun independently.
#
# Outputs:
# review_status β€” JSON array of status objects consumed by the review
# comment assembler (scripts/ci/assemble_review_comment.py).
# Each job (``scan``, ``dep-bounds``) emits its own
# array; an ``aggregate`` job merges them into the
# workflow-level output.
# review_status β€” JSON array of status objects consumed by the review
# comment assembler (scripts/ci/assemble_review_comment.py).
# critical_findings β€” "true" when the narrow critical-pattern scan found
# something. The review-label gate consumes this and
# owns the action-required result, so adding
# ``ci-reviewed`` can heal the run on rerun.

on:
workflow_call:
Expand All @@ -41,6 +42,9 @@ on:
review_status:
description: JSON array of review status objects for the review comment assembler.
value: ${{ jobs.aggregate.outputs.review_status }}
critical_findings:
description: Whether the critical-pattern scan found a risk requiring maintainer review.
value: ${{ jobs.aggregate.outputs.critical_findings }}

permissions:
pull-requests: write
Expand All @@ -54,6 +58,7 @@ jobs:
timeout-minutes: 15
outputs:
review_status: ${{ steps.emit-status.outputs.review_status }}
critical_findings: ${{ steps.scan.outputs.found }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down Expand Up @@ -165,33 +170,15 @@ jobs:
python3 - <<'PYEOF'
import json, os

found = os.environ.get("FOUND", "") == "true"

if found:
with open("/tmp/findings.md", encoding="utf-8") as f:
detail = f.read()
status = [{
"source": "supply chain",
"results": [{
"kind": "error",
"title": "Critical supply chain risk",
"summary": "Critical supply chain risk patterns detected in this PR.",
"detail": detail,
"how_to_fix": "Review the flagged code carefully. If intentional, add the `ci-reviewed` label."
}]
}]
else:
status = []
# The review-label gate renders and blocks critical findings. Keep
# this scan a fact-finder so adding ci-reviewed can rerun the gate
# without requiring the scanner itself to fail again.
status = []

with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as f:
f.write(f"review_status={json.dumps(status)}\n")
PYEOF

- name: Fail on critical findings
if: steps.scan.outputs.found == 'true'
run: |
echo "::error::CRITICAL supply chain risk patterns detected in this PR. See the review comment for details."
exit 1

dep-bounds:
name: Check PyPI dependency upper bounds
Expand Down Expand Up @@ -279,12 +266,14 @@ jobs:
timeout-minutes: 15
outputs:
review_status: ${{ steps.merge.outputs.review_status }}
critical_findings: ${{ steps.merge.outputs.critical_findings }}
steps:
- name: Merge review statuses
id: merge
env:
SCAN_STATUS: ${{ needs.scan.outputs.review_status }}
DEP_STATUS: ${{ needs.dep-bounds.outputs.review_status }}
CRITICAL_FINDINGS: ${{ needs.scan.outputs.critical_findings }}
run: |
python3 - <<'PYEOF'
import json, os
Expand All @@ -303,4 +292,5 @@ jobs:

with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as f:
f.write(f"review_status={json.dumps(merged)}\n")
f.write("critical_findings=" + os.environ.get("CRITICAL_FINDINGS", "false") + "\n")
PYEOF
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ run_datagen_sonnet.sh
source-data/*
run_datagen_megascience_glm4-6.sh
data/*
node_modules/
# No trailing slash: also matches node_modules SYMLINKS (worktrees often
# symlink node_modules to the main checkout; the dir-only pattern let one
# slip into a commit and break `npm ci` on CI with ENOTDIR).
node_modules
browser-use/
agent-browser/
# Private keys
Expand Down Expand Up @@ -72,6 +75,8 @@ environments/benchmarks/evals/

# Web UI build output
hermes_cli/web_dist/
# Cross-process web UI build lock (flock target, always empty)
.web_ui_build.lock
apps/desktop/build/
apps/desktop/dist/

Expand Down Expand Up @@ -145,6 +150,11 @@ docs/superpowers/*
.update-incomplete
.update-incomplete.lock

# Installer-written method stamp in the managed checkout root (scripts/install.sh).
# Runtime metadata only β€” never a code change. Ignore so `git status` stays clean
# and `hermes update`'s untracked autostash does not treat it as a local edit (#66189 / #54855).
/.install_method

# 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/
Expand All @@ -164,3 +174,4 @@ apps/desktop/demo/
# PR body is the archive. See the hermes-agent-dev skill's
# pr-infographic-workflow reference (storage rule + lapse #8 / #COMMIT-1).
infographic/
native/fts5_cjk/*.so
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,8 @@ Two shapes:
Roles:

- `role="leaf"` (default) β€” focused worker. Cannot call `delegate_task`,
`clarify`, `memory`, `send_message`, `execute_code`.
`clarify`, `memory`, `send_message`, `cronjob`. Retains `execute_code`
(programmatic tool calling).
- `role="orchestrator"` β€” retains `delegate_task` so it can spawn its
own workers. Gated by `delegation.orchestrator_enabled` (default true)
and bounded by `delegation.max_spawn_depth` (default 2).
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
graft skills
graft optional-skills
graft optional-mcps
graft hermes_cli/web_dist
graft locales
# Bundled plugin manifests (plugin.yaml / plugin.yml). Without these the
# PluginManager scan (hermes_cli/plugins.py) finds zero plugins on installs
Expand Down
110 changes: 84 additions & 26 deletions acp_adapter/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ class HermesACPAgent(acp.Agent):
"tools": "List available tools",
"context": "Show conversation context info",
"reset": "Clear conversation history",
"compact": "Compress conversation context",
"compress": "Compress conversation context",
"steer": "Inject guidance into the currently running agent turn",
"queue": "Queue a prompt to run after the current turn finishes",
"version": "Show Hermes version",
Expand Down Expand Up @@ -485,7 +485,7 @@ class HermesACPAgent(acp.Agent):
"description": "Clear conversation history",
},
{
"name": "compact",
"name": "compress",
"description": "Compress conversation context",
},
{
Expand Down Expand Up @@ -1218,12 +1218,19 @@ async def cancel(self, session_id: str, **kwargs: Any) -> None:
with state.runtime_lock:
if state.is_running and state.current_prompt_text:
state.interrupted_prompt_text = state.current_prompt_text
state.cancel_event.set()
try:
if getattr(state, "agent", None) and hasattr(state.agent, "interrupt"):
state.agent.interrupt()
except Exception:
logger.debug("Failed to interrupt ACP session %s", session_id, exc_info=True)
# Publish cancellation and hard-stop the agent before another
# prompt can acquire this lock and mistake the turn for
# redirectable work.
state.cancel_event.set()
try:
if getattr(state, "agent", None) and hasattr(state.agent, "interrupt"):
state.agent.interrupt()
except Exception:
logger.debug(
"Failed to interrupt ACP session %s",
session_id,
exc_info=True,
)
logger.info("Cancelled session %s", session_id)

async def fork_session(
Expand Down Expand Up @@ -1352,6 +1359,26 @@ async def prompt(
elif rewrite_idle:
user_text = steer_text
user_content = steer_text
elif (
text_only_prompt
and isinstance(user_content, str)
and not user_text.startswith("/")
):
# Some ACP clients implement "stop and send" as two protocol calls:
# cancel the active prompt, then submit plain correction text. Keep
# the cancelled request attached so deictic follow-ups ("not that
# file") still have an explicit target.
interrupted_prompt = ""
with state.runtime_lock:
if not state.is_running and state.interrupted_prompt_text:
interrupted_prompt = state.interrupted_prompt_text
state.interrupted_prompt_text = ""
if interrupted_prompt:
user_text = (
f"{interrupted_prompt}\n\n"
f"User correction/guidance after interrupt: {user_text}"
)
user_content = user_text

# Intercept slash commands β€” handle locally without calling the LLM.
# Slash commands are text-only; if the client included images/resources,
Expand All @@ -1366,23 +1393,54 @@ async def prompt(
await self._send_usage_update(state)
return PromptResponse(stop_reason="end_turn")

# If Zed sends another regular prompt while the same ACP session is
# still running, queue it instead of racing two AIAgent loops against
# the same state.history. /steer and /queue are handled above and can
# land immediately.
# If the client sends another regular text prompt while this ACP session
# is running, route it through the core active-turn redirect. Rich media
# and older runtimes retain the proven next-turn queue fallback.
redirected = False
queued_depth: int | None = None
with state.runtime_lock:
if state.is_running:
queued_text = user_text or "[Image attachment]"
state.queued_prompts.append(queued_text)
depth = len(state.queued_prompts)
if self._conn:
update = acp.update_agent_message_text(
f"Queued for the next turn. ({depth} queued)"
if (
text_only_prompt
and isinstance(user_content, str)
and getattr(
state.agent,
"_supports_active_turn_redirect",
False,
)
await self._conn.session_update(session_id, update)
return PromptResponse(stop_reason="end_turn")
state.is_running = True
state.current_prompt_text = user_text or "[Image attachment]"
is True
and hasattr(state.agent, "redirect")
):
try:
redirected = bool(state.agent.redirect(user_content))
except Exception:
logger.debug(
"ACP active-turn redirect failed for %s",
session_id,
exc_info=True,
)
if not redirected:
queued_text = user_text or "[Image attachment]"
state.queued_prompts.append(queued_text)
queued_depth = len(state.queued_prompts)
else:
state.is_running = True
state.current_prompt_text = user_text or "[Image attachment]"

if redirected:
if self._conn:
update = acp.update_agent_message_text(
"Redirected the active turn with your correction."
)
await self._conn.session_update(session_id, update)
return PromptResponse(stop_reason="end_turn")
if queued_depth is not None:
if self._conn:
update = acp.update_agent_message_text(
f"Queued for the next turn. ({queued_depth} queued)"
)
await self._conn.session_update(session_id, update)
return PromptResponse(stop_reason="end_turn")

logger.info("Prompt on session %s: %s", session_id, user_text[:100])

Expand Down Expand Up @@ -1756,7 +1814,7 @@ def _handle_slash_command(self, text: str, state: SessionState) -> str | None:
"tools": self._cmd_tools,
"context": self._cmd_context,
"reset": self._cmd_reset,
"compact": self._cmd_compact,
"compress": self._cmd_compress,
"steer": self._cmd_steer,
"queue": self._cmd_queue,
"version": self._cmd_version,
Expand Down Expand Up @@ -1898,7 +1956,7 @@ def _cmd_context(self, args: str, state: SessionState) -> str:
lines.append(
f"Compression: due now (threshold ~{threshold_tokens:,}"
+ (f", {threshold_pct:.0f}%" if threshold_pct else "")
+ "). Run /compact."
+ "). Run /compress."
)
else:
lines.append(
Expand All @@ -1913,7 +1971,7 @@ def _cmd_context(self, args: str, state: SessionState) -> str:
if getattr(agent, "compression_enabled", True) is False:
lines.append("Compression is disabled for this agent.")
else:
lines.append("Tip: run /compact to compress manually before the threshold.")
lines.append("Tip: run /compress to compress manually before the threshold.")

return "\n".join(lines)

Expand All @@ -1933,7 +1991,7 @@ def _cmd_reset(self, args: str, state: SessionState) -> str:
return "Conversation history cleared. Agent session state reset failed; see logs."
return "Conversation history cleared."

def _cmd_compact(self, args: str, state: SessionState) -> str:
def _cmd_compress(self, args: str, state: SessionState) -> str:
if not state.history:
return "Nothing to compress β€” conversation is empty."
try:
Expand Down
Loading
Loading