25 Commits

Author SHA1 Message Date
ethernet
f4a38b1ee8 Merge origin/main into ethie/pm-clean 2026-09-23 10:13:26 -04:00
beardthelion
2c3a75beaa fix(secret-scope): scoped misses fail closed under a foreign-home scope
get_secret returned os.environ on a scoped miss whenever multiplex was
off, but non-multiplex hosts serve foreign homes too (dashboard/desktop
backend, per-profile cron, MCP owner scopes, kanban spawn-env builds),
where os.environ is the launch profile's. Bound scopes now carry the
home they were built for; serves_routed_profile detects a foreign scope
even when the binder deliberately skips the HERMES_HOME override, and
the miss returns the caller's default. Every production binder stamps
its home; own-home scopes keep the deliberate env overlay.
2026-09-23 06:46:02 -07:00
ethernet
3f4b8840f1 Merge remote-tracking branch 'origin/main' into ethie/pm-clean
# Conflicts:
#	pyproject.toml
#	tests/fixtures/resolution_allowlist.json
2026-09-23 07:36:31 -04:00
teknium1
7ed6534c7e Merge origin/main: browser fence composed with the dispatch/retry split (#115184); server registration, i18n, contracts 2026-09-23 03:25:06 -07:00
ethernet
9f2ba1b74d merge origin/main (779 commits) into ethie/pm-clean
Branch semantics kept where main and PM disagree: update_cmd_deps.py,
constraints-termux.txt, the Electron update-api-check module and the
post-swap hand-off test stay deleted; the pending-fleet-restart catch-up
and the local_runtime tag/download ladder stay retired (PM owns engines).

Ported from main onto the branch's shape: profile_scoped_chore for the
auto-archive and plugin-update housekeeping chores, the local-runtime
cross-process boot lock and residency cap, the checkpoint tmp_pack sweep,
the cua daemon-liveness status probe, the remote-served Desktop update
flag (posix.sh / windows.ps1), sign-in for env-pinned remote gateways
(urlDisabled on RemoteSetupFields), the uvloop extra split (uvicorn
without [standard]), and the umask-scoping spawn test.

uv.lock regenerated with pm.build_env --lock-only; new utf-8 reads from
main switched to utf-8-sig (check-windows-footguns).
2026-09-21 00:58:39 -04:00
teknium1
f2f70bed7a fix(browser): orphan reaper binds only on the full socket-dir path, never its basename
The binding half of _verify_reapable_browser_daemon accepted the socket-dir
basename anywhere in argv. That basename is predictable from the session
name, so a recycled PID whose argv merely mentioned it (a grep, a shell)
passed both gates and was tree-killed. Require the full normalized path as
an argv token (bare or --flag=path) or the environ match.

Fixes #116884
2026-09-20 18:25:21 -07:00
teknium1
b2629519e7 fix(bot-screen): a human holding the lease keeps the shared browser alive
The janitor reaped the bot's headed Chromium after 120 s of AGENT inactivity — which is
exactly the state a human takeover (login, 2FA) puts the agent in — so the browser died
under the human mid-login. The janitor now counts a human-held lease as activity for the
browser the human shares with the bot, and the agent-browser daemon's own idle timer
(which cannot see the lease) steps back on the Bot Desktop so the lease-aware janitor
owns that browser's lifetime; a crashed hermes still leaves it to the orphan reaper.

Fixes #110064
2026-09-18 21:07:18 -07:00
ethernet
b4a294fff9 Merge origin/main; keep PM as plugin dependency owner
Reconcile plugin declarations and validation through PM's atomic generation publication; preserve external runtimes, target markers, and conflict refusal. Keep one source-update completion owner and port upstream lifecycle changes to the PM desktop/runtime paths.
2026-09-17 13:52:05 -04:00
Davy
ee62a4b5f6 fix(browser): atexit hooks stay silent when the origin module is unimportable
Mid-hermes update the on-disk tree can be half-new (new config.py
importing a name the old utils.py lacks yet), so the fresh import in
origin_module raises ImportError and both atexit callbacks print
'Exception ignored in atexit callback' tracebacks. Guard the
origin-state accesses at the top of both entry points: an unresolvable
origin means no session state to clean.

Fixes #112437
2026-09-16 16:57:03 -07:00
ethernet
b681f0c50e merge: reconcile origin/main with PM runtime ownership
Preserve upstream fixes without restoring retired dependency installers.
Run configured-feature checks in the selected build interpreter. Reuse a
supported base Python during bootstrap, and preserve durable backup media.

Refresh the dependency lock through PM. Keep the frozen historical import
surface unchanged. Adapt incoming native tests to the platform markers.

Verification: the incoming 86-file pass found two fixture mismatches;
both passed after correction. Targeted PM/update/compatibility checks,
Electron and renderer typechecks, and desktop tests passed.
Native Windows/macOS update journeys and the full suite remain unrun.
2026-09-12 16:55:32 -04:00
ethernet
5e4a2a3d24 refactor(pm): remove legacy dependency and launch managers
Competing installers and checkout-local venv assumptions bypassed PM
selection, install consent, and generation lifetimes. Route consumers
through PM and installation-bound launchers. Refresh source launchers
before obsolete Python entries can be collected.

Remove Node, browser, and CUA acquisition engines, obsolete venv-holder
handling, detached sync, and unused PM APIs. Keep historical updater
exports inert and preserve external tool ownership and native integration.

Share product freshness and prepared inputs across builders. Align plugin
admission, Docker provisioning, setup instructions, and behavioral tests.

Verified targeted Python and JavaScript tests, desktop and web typechecks,
scoped lint, real product builds, and the Docker frontend smoke test.
The missed post-setup test cleanup is included and verified.

Native Windows/macOS execution, full Rust compilation, and the complete
repository suite remain unverified. Historical compatibility requirements
were preserved and extended, not fully rescanned.
2026-09-12 14:57:38 -04:00
LehaoLin
c59c1a98e3 fix(browser): suppress KeyboardInterrupt in atexit cleanup thread stop
A second Ctrl+C while the atexit hook joins the browser janitor thread
surfaced as "Exception ignored in atexit callback: _stop_browser_cleanup_thread"
with a KeyboardInterrupt traceback. The janitor is a daemon thread and the
interpreter is already exiting, so nothing is lost by swallowing the
interrupt — the terminal tool's sibling _stop_cleanup_thread already does.

Salvaged from #10765 (function has since moved to browser_tool_lifecycle.py).

Fixes #10764
Co-authored-by: LehaoLin <lehaolin98@outlook.com>
2026-09-12 08:43:28 -07:00
ethernet
d2c14f4bec merge: reconcile upstream bounded search with literal patterns
Merge d86627a7f3 into pm-clean. Keep the shared bounded ripgrep transport and preserve translate_path=False for probe patterns. Targeted canonical search tests: 19 passed, 3 POSIX-only skips on Windows. Full integrated CI has not been run for this merge.
2026-09-06 16:00:55 -04:00
jango
ed406f929d fix(browser): make the real-profile attach daemon reapable (#100855, salvage #103284)
The `hermes-real-profile` agent-browser daemon (the attach lane for consented
real-profile browsing) ran with plain `_build_browser_env()`: no
`AGENT_BROWSER_SOCKET_DIR`, so it lived in agent-browser's default dir and no
reap path could see it. A wedged daemon + headless Chrome survived 47h across
two gateway restarts (#100855), and on macOS the genuine Chrome binary it held
made "Chrome won't open" for the user.

Give the attach lane the same contract every other lane already has:
`_prepare_session_socket_dir()` (per-session socket dir + `owner_pid` claim)
and `_agent_browser_command_env()`, and add the named dir to the orphan
reaper's scan. The existing `_reap_socket_dir` then applies its owner-liveness
and start-time-fingerprint rules unchanged; the daemon is listed as tracked so
the untracked-idle escape hatch never fires under a live user (per-task `rp_*`
sessions drive it over `--cdp`, so its own dir shows no activity). The daemon-side idle
timeout is NOT inherited: Chrome is launched by Hermes, not the daemon, so a
self-exiting daemon would leave Chrome holding the copy dir while the next
attach re-runs the snapshot overlay over it.

When a reaped daemon's Chrome (Hermes-launched, own process group) still
holds the copy dir, `_real_profile_cdp` re-attaches to it instead of running
the snapshot overlay over a live profile. DevToolsActivePort outlives a
crashed Chrome and its port can be recycled, so the file's browser id must
match `/json/version` before it is trusted; an attach failure on a live
Chrome fails closed rather than overlaying.

Tests: attach/get/close commands carry the reaper-visible socket dir and
owner_pid and no idle timeout; a dead-owner real-profile daemon is reaped by
`_reap_orphaned_browser_sessions`; a surviving Chrome is re-attached, never
overlaid (all red on main).
2026-09-06 23:31:05 +05:30
ethernet
25ce047f98 fix(footguns): utf-8-sig on all reads flagged by check-windows-footguns (164 sites)
The 4,272-commit upstream merge brought 164 new utf-8 read violations
across 96 files. Class-fixed: reads utf-8-sig, writes unchanged.
check-windows-footguns.py --all: 164 -> 0.
2026-09-04 14:46:24 -04:00
Teknium
de60f789a7 simplify(compat): tools/browser_tool + browser_supervisor — drop 114 re-exports + 6 legacy aliases + PEP 562 requests/call_llm hook, repoint 21 non-test callers; siblings read sibling names directly 2026-09-03 14:16:54 -07:00
Teknium
e83816a4d1 review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged)
For each issue anchor present in BASE 63279301bc non-test .py and absent on HEAD, the BASE comment/docstring block was re-attached at the HEAD location of the code it explained (matched by the distinctive code line / enclosing def). Sentences already covered by an existing HEAD comment were deduped; the issue number always survives. Insert-only: no code lines changed.
2026-09-03 09:44:26 -07:00
Teknium
35f8514afc refactor(tools): browser_tool — compact docstrings/comments across browser_tool_* modules (keep every WHY) 2026-09-02 23:53:53 -07:00
Teknium
2b41af97a1 refactor(tools): browser_tool — vision capture phase helper, session/lifecycle body compaction, tighter constant tables 2026-09-02 23:37:37 -07:00
Teknium
ed9476cf40 refactor(tools): browser_tool — consolidate config caches, navigate/eval/console helpers, lifecycle best-effort wrapper, compact session/vision bodies 2026-09-02 23:27:55 -07:00
Teknium
408cafe06f refactor(tools): browser_tool — data-driven tool table, guarded-action helper, compact re-export blocks, _pid_exists delegates to gateway.status 2026-09-02 23:01:32 -07:00
Teknium
d3523096fa refactor(tools): browser_tool — origin proxy replaces per-call _bt lookups, unified JSON/error builders, cached-config helper, dead shim removal 2026-09-02 22:39:28 -07:00
Teknium
6a9387f6f4 refactor(browser): table-driven registry.register loop for the 10 browser tools; bracket-hug compaction across browser_* modules (AST-identical) 2026-09-02 16:26:33 -07:00
Teknium
70282b6baf refactor(browser): lifecycle module imports hermes_constants directly; drop origin imports left unused by the move 2026-09-02 16:15:20 -07:00
Teknium
369dbe4320 refactor(browser): move session lifecycle cluster (janitor, orphan reaper, teardown, atexit cleanup) to tools/browser_tool_lifecycle.py 2026-09-02 16:14:39 -07:00