Commit Graph
50 Commits
Author SHA1 Message Date
ethernet 53a024994a Merge pull request #20890 from NousResearch/fix/docker-push
ci(docker): don't cancel overlapping builds, guard :latest
2026-05-06 17:38:21 -04:00
ethernet f4031df05d ci(docker): don't cancel overlapping builds, guard :latest
Switch top-level concurrency to cancel-in-progress=false so every push
to main gets its own SHA-tagged image published — no more discarded
builds when commits land back-to-back.

Guard the :latest tag with a second job that has its own concurrency
group with cancel-in-progress=true plus a git-ancestor check against
the revision label on the current :latest. Together these guarantee
:latest only ever moves forward in history: a slower run whose commit
isn't a descendant of the current :latest refuses to clobber it, and
a newer push mid-way through the move-latest job preempts the older
one before it can retag.

- Every main push publishes nousresearch/hermes-agent:sha-<commit>
  with an org.opencontainers.image.revision label embedded.
- move-latest job reads that label off :latest, runs merge-base
  --is-ancestor, and only retags (via buildx imagetools create,
  registry-side, no rebuild) if our commit strictly descends.
- fetch-depth bumped to 1000 so merge-base has the history it needs.
- Release tag flow unchanged (unique tag, no race).
2026-05-06 15:53:47 -04:00
ethernet a345f7b6e5 Merge pull request #19908 from NousResearch/typecheck
change: enable ruff/ty
2026-05-06 14:43:14 -04:00
ethernet 9627ee70e5 feat(ci): add typecheck (warnings only in CI) 2026-05-06 10:58:12 -04:00
ethernet 63c51d8962 change: enable ruff/ty 2026-05-06 10:45:25 -04:00
ethernet 59c1a13f45 Merge pull request #15680 from NousResearch/fix/nix-package-lock
fix: let fixing nix pkgs command work without an initial build
2026-04-30 16:21:51 -04:00
Ari Lotter 9ac4a2e53e fix: let fixing nix pkgs command work without an initial build 2026-04-30 15:39:45 -04:00
ethernet b737af8226 Merge pull request #18047 from stephenschoettler/fix/acp-persist-user-message-test-mocks
test(acp): accept prompt persistence kwargs in MCP E2E mocks
2026-04-30 14:43:26 -04:00
ethernet 8fbc9d7d78 Merge pull request #18043 from NousResearch/feat/help-ui
feat(tui): add a mini help menu when u write ? in the input field
2026-04-30 14:02:28 -04:00
ethernet 7c07422202 feat(tui): add a mini help menu when u write ? in the input field
it feels so nice :3 just a lil popup ! doesn't get in the way or take
any focus or anything, and directs users to /help for more info :3
2026-04-30 13:37:12 -04:00
ethernet d499d17271 Merge pull request #17969 from stephenschoettler/fix/current-main-test-regressions
fix(ci): stabilize current main test regressions
2026-04-30 13:23:38 -04:00
ethernetandHermes Agent 2d3c041338 change(nix): dedupe nix lockfile checking scripts in ci (#18000)
* change(nix): dedupe nix lockfile checking scripts in ci

* feat(nix): make .#fix-lockfiles run --apply if no args passed

* fix(nix): use same nodejs version everywhere & small lints

- prevent lockfile thrashing while using nix :3
- use lib.getExe instead of raw /bin/ paths
- use inputs'.self instead of passing system in manually

* fix(nix): update lock files yet again (hopefully for the last time)

* fix(nix): align indentation of collision check echo

---------

Co-authored-by: Hermes Agent <hermes@nousresearch.com>
2026-04-30 22:52:30 +05:30
Ari Lotter 868bc1c242 feat(irc): add interactive setup
feat(gateway): refine Platform._missing_ and platform-connected dispatch

Restricts plugin-name acceptance to bundled plugin scan + registry
(no arbitrary string -> enum-pollution), pulls per-platform connectivity
checks into a _PLATFORM_CONNECTED_CHECKERS lambda map with a clean
_is_platform_connected method, and adds tests covering the checker map,
plugin platform interface, and IRC setup wizard.
2026-04-29 21:56:51 -07:00
Ari Lotter 6e42daf7dd fix(nix): bundle plugins/ and expose it via HERMES_BUNDLED_PLUGINS
Nix-built hermes only copied skills/ into the output, so bundled platform
plugins weren't discoverable when running `nix run` (IRC invisible, no
plugin.yaml files present). Mirror the bundled-skills pattern:

- packages.nix: cleanSourceWith plugins/, copy to
  $out/share/hermes-agent/plugins, set HERMES_BUNDLED_PLUGINS on every
  wrapper.
- checks.nix: new bundled-plugins check verifying the directory, a
  sample manifest, and the wrapper env var.
- hermes_cli.plugins.get_bundled_plugins_dir(): central helper that
  honors HERMES_BUNDLED_PLUGINS with a dev-checkout fallback. Used by
  plugins.py, plugins_cmd.py, gateway.py, and web_server.py so every
  call site resolves the same path.
2026-04-29 21:56:51 -07:00
Ari Lotter 1f1608067c feat(gateway): unify setup flows, load platforms dynamically from registry
Merge the two gateway setup paths (hermes setup gateway + hermes gateway
setup) to use a single _unified_platforms() list that merges built-in
_PLATFORMS with dynamically registered plugin entries from
platform_registry.

- Add setup_fn field to PlatformEntry for plugin setup flows
- _unified_platforms() merges built-ins with registry entries by key
- setup_gateway() now uses unified list instead of hardcoded
  _GATEWAY_PLATFORMS tuple list
- gateway_setup() uses same unified list, plugin entries appear
  alongside built-ins with no [plugin] suffix
- _platform_status() handles plugin platforms via registry check_fn
- Plugin platforms with setup_fn get called directly; plugins without
  get a generic env-var display fallback

IRC and other plugin platforms now appear automatically in the setup
menu when registered via platform_registry.register().

feat(gateway): surface disabled platform plugins in setup and auto-enable on select

Platform plugins under plugins/platforms/* (IRC, etc.) were gated behind
plugins.enabled, so `hermes gateway setup` wouldn't list them until the
user ran `hermes plugins enable <name>` first. Now the setup menu always
surfaces them as "plugin disabled — select to enable", and picking one
adds it to plugins.enabled before running its setup flow.

Along the way, unify the two gateway setup flows so `hermes setup gateway`
and `hermes gateway setup` both read from the same platform list (built-in
_PLATFORMS + platform_registry entries), dispatch through a single
_configure_platform() helper, and share _platform_status(). Deletes the
dead bespoke wrappers in setup.py (_setup_whatsapp, _setup_weixin,
_setup_email, etc.) that duplicated logic now covered by the registry
path or _setup_standard_platform.

Also:
- PlatformEntry gains a plugin_name field so the registry knows which
  plugin owns each entry (required for auto-enable).
- PluginContext.register_platform auto-stamps plugin_name from the
  manifest so plugins don't have to pass it explicitly.
- PluginManager now scans plugins/platforms/* as its own category root,
  one level below the bundled plugin scan.
- Fix IRC plugin discovery: rename PLUGIN.yaml → plugin.yaml (the
  scanner is case-sensitive) and add the missing __init__.py that
  _load_directory_module requires.
2026-04-29 21:56:51 -07:00
ethernet 7d48a16f14 remove relaunch_chat
not needed
2026-04-29 20:33:29 -07:00
ethernet 3c673468b4 refactor(cli): derive relaunch flag table from argparse introspection
Pull the top-level + chat parser construction out of main() into
hermes_cli/_parser.py so relaunch.py can introspect parser._actions to
discover which flags exist and whether they take values, instead of
maintaining a parallel hand-rolled (flag, takes_value) tuple list.

- _parser.py: build_top_level_parser() returns (parser, subparsers,
  chat_parser); side-effect-free import.
- main.py: ~290 lines of inline parser construction collapsed to a
  helper call. Other subparsers stay inline (dispatch is bound to
  module-level cmd_* functions).
- _parser._inherited_flag(parser, ...): wraps parser.add_argument and
  sets action.inherit_on_relaunch = True. Used in place of
  parser.add_argument for the 25 flags (top-level + chat) that need to
  carry over.
- _parser.PRE_ARGPARSE_INHERITED_FLAGS: holds --profile/-p, which
  isn't on argparse (consumed earlier by main._apply_profile_override).
- relaunch.py: drops _CRITICAL_DESTS and _PRE_ARGPARSE_FLAGS; the table
  builder now filters by getattr(action, 'inherit_on_relaunch', False).
- test_ignore_user_config_flags.py: brittle inspect.getsource grep
  replaced with proper parser introspection.
- test_relaunch.py: introspection sanity tests added.

Salvaged from PR #17549; added top-level -t/--toolsets flag to
_parser.py so #17623 (fix(tui): honor launch toolsets) behavior is
preserved on current main.

Co-authored-by: ethernet <arilotter@gmail.com>
2026-04-29 20:33:29 -07:00
ethernetandClaude Opus 4.7 95f2802f84 feat(cli): preserve --tui and other flags across internal relaunches
Extract all os.execvp('hermes', ...) calls into a utility so flags like
--tui, --dev, --profile, --model, --provider, et al. survive session
resume and post-setup relaunch.

- resolve_hermes_bin: prefers sys.argv[0] when callable, then PATH,
  then falls back to '${sys.executable} -m hermes_cli.main' (fixes nix
run relaunches)
- build_relaunch_argv: allowlists critical flags so they carry over
- cmd_sessions browse now calls relaunch(['--resume', <id>])
- _apply_profile_override skips redundant work when HERMES_HOME is
  already set (child inherits parent profile)
- setup.py replaces _resolve_hermes_chat_argv with relaunch_chat()
- added comprehensive tests for flag extraction and binary resolution

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 20:33:29 -07:00
ethernet 9fc9c15b4a fix(banner): show correct update status on nix-built hermes (#17550)
check_for_updates() looked at __file__.parent.parent for a .git dir to
  diff against origin/main. A nix-built hermes lives in /nix/store with
  no .git there, so the check fell through to whatever editable-install
  dev checkout last populated ~/.hermes/.update_check, producing stale
  "X commits behind" warnings right after a fresh `nix run --refresh`.

  Embed the locked flake rev into the wrapper as HERMES_REVISION (only
on
  clean builds — dirty refs don't represent any upstream commit). When
  set, banner.py compares it to upstream main via `git ls-remote`
instead
  of inspecting a local checkout, and the cache key includes the rev so
  nix updates invalidate immediately. Without local history we can't
  count commits, so the message is a plain "update available" with no
  suggested command — nix users may install via `nix run`, profile,
  system flake, or home-manager, and we don't know which.

  Also bump web/package-lock.json npmDepsHash via `nix run
.#fix-lockfiles`.
2026-04-30 07:03:00 +05:30
ethernet 7db2703b33 Merge pull request #14895 from NousResearch/tui-resume
fix(tui): keep FloatingOverlays visible when input is blocked
2026-04-24 01:44:50 -03:00
Ari Lotter 7c59e1a871 fix(tui): keep FloatingOverlays visible when input is blocked
FloatingOverlays (SessionPicker, ModelPicker, SkillsHub, pager,
completions) was nested inside the !isBlocked guard in ComposerPane.
When any overlay opened, isBlocked became true, which removed the
entire composer box from the tree — including the overlay that was
trying to render. This made /resume with no args appear to do nothing
(the input line vanished and no picker appeared).

Since 99d859ce (feat: refactor by splitting up app and doing proper
state), isBlocked gated only the text input lines so that
approval/clarify prompts and pickers rendered above a hidden composer.

The regression happened in 408fc893 (fix(tui): tighten composer — status
sits directly above input, overlays anchor to input) when
FloatingOverlays was moved into the input row for anchoring but
accidentally kept inside the !isBlocked guard.

so here, we render FloatingOverlays outside the !isBlocked guard inside
the same position:relative Box, so overlays
stay visible even when text input is hidden. Only the actual input
buffer lines and TextInput are gated now.

Fixes: /resume, /history, /logs, /model, /skills, and completion
dropdowns when blocked overlays are active.
2026-04-23 23:44:52 -04:00
ethernet c95c6bdb7c Merge pull request #14818 from NousResearch/ink-perf
perf(ink): cache text measurements across yoga flex re-passes
2026-04-23 20:58:54 -03:00
Ari Lotter bd929ea514 perf(ink): cache text measurements across yoga flex re-passes
Adds a per-ink-text measurement cache keyed by width|widthMode to avoid
re-squashing and re-wrapping the same text when yoga calls measureFunc
multiple times per frame with different widths during flex layout re-pass.
2026-04-23 19:45:10 -04:00
ethernet 943602b68a Merge pull request #13646 from NousResearch/fix/nix
update package.locks to build in nix
2026-04-21 14:54:23 -04:00
Ari Lotter ce0ecce6cf update package.locks 2026-04-21 14:42:49 -04:00
ethernet ac4e8cb43a Merge pull request #13183 from NousResearch/fix/nix
fix/nix
2026-04-20 17:10:52 -04:00
Ari Lotter 1d2615b602 dedupe nix cache 2026-04-20 16:52:57 -04:00
Ari Lotter 5395df1b6c normalize newlines :3 2026-04-20 16:50:45 -04:00
Ari Lotter 4dd6d6eeb4 nix: run CI on all lockfile changes 2026-04-20 16:17:15 -04:00
ethernet 761c113427 nix: automatic lockfile fixing to keep main building with nix (#13136)
* ci(nix): automatic lockfile fixing to keep main building

This reverts commit 688c9f5b7c.

* update lockfiles
2026-04-21 01:42:28 +05:30
Ari Lotter 688c9f5b7c Revert "nix: automatic lockfile fixing to keep main building with nix"
This reverts commit 6f079933cb.
2026-04-20 13:58:02 -04:00
Ari Lotter 6f079933cb nix: automatic lockfile fixing to keep main building with nix 2026-04-20 13:53:09 -04:00
Ari Lotter fc0623f0af update nix 2026-04-16 11:50:35 -04:00
Ari Lotter 56524bb1d9 fix: nix local dev with tui 2026-04-13 15:09:31 -04:00
Ari Lotter 3bf0f39337 wrap preformatted ansi in <Ansi> component 2026-04-12 16:53:53 -04:00
Ari Lotter 8e0df1d532 launch tui later to allow setup et al 2026-04-11 20:23:30 -04:00
Ari Lotter 29721fcc58 nix fixes 2026-04-11 19:35:00 -04:00
Ari Lotter 5e5e65f6d5 fix nix build 2026-04-11 15:30:37 -04:00
Ari Lotter 660379637a one more nix fix 2026-04-10 01:41:29 -04:00
Ari Lotter bc80848e49 update lockfile 2026-04-10 00:50:39 -04:00
Ari Lotter 658cd2dd4c nix: add tui lockfile update script 2026-04-10 00:46:37 -04:00
Ari Lotter 74241328f0 direnv: watch lockfiles/nix files; gitignore .nix-stamps 2026-04-09 15:50:24 -04:00
Ari Lotter df5874c119 nix: add bundled TUI build-time verification check 2026-04-09 15:50:24 -04:00
Ari Lotter 21afb3fa3c nix: delegate devShell setup to package passthru hooks
- use inputsFrom to inherit build inputs from packages
- concat passthru.devShellHook from each package
2026-04-09 15:50:24 -04:00
Ari Lotter 31b2c12f0f nix: bundle TUI in main package with passthru hooks
- build tui.nix, copy to $out/ui-tui/ (same layout as dev)
- set HERMES_TUI_DIR, HERMES_PYTHON in wrapper
- add passthru.devShellHook with stamp-checked venv setup
- expose tui as separate package output
2026-04-09 15:50:24 -04:00
Ari Lotter 405c1b4e84 nix: add TUI derivation with buildNpmPackage
- fetchNpmDeps for reproducibilty
- compile ts to js
- passthru.devShellHook for dev shell stamp-checked auto dep install
2026-04-09 15:50:24 -04:00
Ari Lotter 5ff96551d5 cli: support bundled TUI at HERMES_TUI_DIR (for nix)
- Fix cwd to use bundled TUI dir, not PROJECT_ROOT
- Set HERMES_ROOT from env with cwd fallback
2026-04-09 15:50:24 -04:00
Ari Lotter 2b4272ef5b ui-tui: update package-lock.json 2026-04-09 15:35:54 -04:00
Ari Lotter 670dcea8f4 ui-tui: add tsc build pipeline
- Switch tsconfig to nodenext module resolution for Node 22 (used by
installer script)
- Add shebang to entry.tsx, preserved into index.js
- Add HERMES_ROOT env var fallback for repo root resolution
2026-04-09 15:35:29 -04:00
ethernet 637ad443bf nix: add tirith to runtime deps (#6721) 2026-04-09 22:28:00 +05:30