hermes-bsd/tests/tools
Teknium 3f78d8073c fix(skills): make content_hash filename-sensitive too (symmetric with bundle_content_hash)
PR #6656 added rel_path + \x00 prefixing to ``bundle_content_hash`` so a
filename swap between two files in a bundle changes the digest. But it
only patched the in-memory side — ``content_hash`` in ``tools/skills_guard.py``
(the on-disk equivalent) still hashed file contents only.

These two functions need to stay symmetric: ``check_for_skill_updates``
compares the disk hash of an installed skill against the bundle hash
of the upstream copy. With the asymmetric fix, every clean install
showed as drifted because the digests no longer matched
(2 existing tests in ``test_skills_hub.py`` started failing as soon as
the contributor's change landed).

Apply the same ``rel_path + \x00 + content`` shape to the disk-side
function. Both functions now produce the same digest for the same skill
content laid out two ways. Documented the symmetry invariant in the
docstring so a future change to either function knows to touch both.

Also adds tests/tools/test_pr_6656_regressions.py with 10 regression
tests covering all three fixes salvaged in PR #6656:
  - uninstall_skill path traversal (4 cases: parent segments, absolute
    paths, symlink escape, legitimate skill)
  - bundle_content_hash filename swap detection (4 cases: in-memory
    swap, identity, disk-side swap, bundle↔disk symmetry)
  - list_pending lock contract (2 cases: source-grep contract, smoke)

Also fixes AUTHOR_MAP entry for @aaronlab — their commit email
(1115117931@qq.com) maps to "aaronagent" which isn't a real GitHub
login, so changelog @mentions would 404.
2026-05-22 19:59:24 -07:00
..
__init__.py
conftest.py test(tools): centralize disable_lazy_stt_install fixture in conftest 2026-05-22 03:33:01 -07:00
test_accretion_caps.py fix(ci): recover 38 failing tests on main (#17642) 2026-04-29 20:05:32 -07:00
test_ansi_strip.py
test_approval.py Inspired by Claude Code: tighten dangerous-command detection (#26829) 2026-05-16 01:24:25 -07:00
test_approval_heartbeat.py test: remove 50 stale/broken tests to unblock CI (#22098) 2026-05-08 14:55:40 -07:00
test_approval_plugin_hooks.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_base_environment.py fix(env): pass -- to cd for hyphen-prefixed workdirs 2026-05-04 04:45:03 -07:00
test_browser_camofox.py
test_browser_camofox_persistence.py feat(browser): support externally managed Camofox sessions 2026-05-12 15:14:49 -07:00
test_browser_camofox_state.py feat(browser): support externally managed Camofox sessions 2026-05-12 15:14:49 -07:00
test_browser_cdp_override.py
test_browser_cdp_tool.py
test_browser_chromium_check.py fix(install): skip browser download when system chromium exists 2026-05-13 22:07:02 -07:00
test_browser_cleanup.py
test_browser_cloud_fallback.py
test_browser_cloud_provider_cache.py fix(browser_tool): fall through to autodetect on config read failure 2026-05-09 13:35:39 -07:00
test_browser_console.py
test_browser_content_none_guard.py
test_browser_eval_supervisor_path.py perf(browser): route browser_console eval through supervisor's persistent CDP WS (180x faster) (#23226) 2026-05-10 07:37:55 -07:00
test_browser_hardening.py
test_browser_homebrew_paths.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
test_browser_hybrid_routing.py
test_browser_lightpanda.py fix(browser): tighten Lightpanda fallback edge cases 2026-05-06 03:41:21 -07:00
test_browser_orphan_reaper.py test: migrate stale os.kill monkeypatches to gateway.status._pid_exists 2026-05-08 14:27:40 -07:00
test_browser_secret_exfil.py fix(test): deflake two intermittent CI failures 2026-05-22 19:46:18 -07:00
test_browser_ssrf_local.py fix(browser): enforce cloud-metadata SSRF floor in hybrid routing (#16234) (#21228) 2026-05-07 05:38:05 -07:00
test_browser_supervisor.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_browser_supervisor_healthcheck.py test(browser_supervisor): cover cache-hit healthcheck on dead thread/loop 2026-04-30 20:33:33 -07:00
test_budget_config.py
test_checkpoint_manager.py fix(checkpoint): guard _touch_project against non-dict project metadata 2026-05-09 17:53:13 -07:00
test_clarify_gateway.py fix(gateway): enable text-intercept for multi-choice clarify fallback (#25567) 2026-05-14 07:59:12 -07:00
test_clarify_tool.py
test_clipboard.py fix(clipboard): reject non-png clipboard images when png normalization fails 2026-05-13 22:54:21 -07:00
test_code_execution.py fix(windows): enable execute_code — stale AF_UNIX gate was blocking the tool 2026-05-08 14:27:40 -07:00
test_code_execution_modes.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
test_code_execution_windows_env.py execute_code: set PYTHONIOENCODING=utf-8 + PYTHONUTF8=1 in child env 2026-05-08 14:27:40 -07:00
test_command_guards.py test: remove 50 stale/broken tests to unblock CI (#22098) 2026-05-08 14:55:40 -07:00
test_computer_use.py fix(computer-use): skip capture_after when action failed (ok=False) 2026-05-22 01:19:01 -07:00
test_computer_use_capture_routing.py test(computer_use): end-to-end regression for capture routing (#24015) 2026-05-21 17:38:19 -07:00
test_computer_use_vision_routing.py test(computer_use): cover capture vision-routing helper 2026-05-21 17:38:19 -07:00
test_config_null_guard.py
test_credential_files.py
test_credential_pool_env_fallback.py test: remove 50 stale/broken tests to unblock CI (#22098) 2026-05-08 14:55:40 -07:00
test_cron_approval_mode.py fix(approval): cron jobs must not be treated as gateway context 2026-05-08 07:30:14 -07:00
test_cron_prompt_injection.py
test_cronjob_tools.py fix(cron): allow emoji ZWJ sequences in prompts 2026-05-19 00:10:43 -07:00
test_daytona_environment.py fix(daytona): migrate legacy-sandbox lookup to cursor-based list() (#24587) 2026-05-12 16:31:46 -07:00
test_debug_helpers.py
test_delegate.py test(delegation): add regression test for runtime missing 'provider' key 2026-05-17 11:40:05 -07:00
test_delegate_composite_toolsets.py fix(delegate): expand composite toolsets before intersection in delegate_task 2026-05-07 06:41:42 -07:00
test_delegate_subagent_timeout_diagnostic.py
test_delegate_toolset_scope.py
test_discord_tool.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_docker_environment.py feat(docker): run container as host user to avoid root-owned bind mounts 2026-04-29 16:16:43 +10:00
test_docker_find.py
test_dockerfile_node_modules_perms.py fix(docker): chown runtime node_modules trees to hermes user (#18800) 2026-05-07 06:17:49 -07:00
test_dockerfile_pid1_reaping.py fix(docker): preload messaging gateway deps 2026-05-17 11:51:46 -07:00
test_env_passthrough.py
test_feishu_tools.py
test_file_operations.py fix(file-safety): also write-deny <root>/control-files in profile mode 2026-05-22 04:32:14 -07:00
test_file_operations_edge_cases.py feat(file_tools): post-write delta lint on write_file + patch, add JSON/YAML/TOML/Python in-process linters (#20191) 2026-05-05 04:54:17 -07:00
test_file_ops_cwd_tracking.py
test_file_read_guards.py
test_file_staleness.py
test_file_state_registry.py
test_file_sync.py
test_file_sync_back.py fix: move pytest.importorskip below pytest import in skip-guarded tests 2026-05-09 11:12:03 -07:00
test_file_sync_perf.py
test_file_tools.py test(patch-tool): collapse 9 schema-shape tests into 2 invariants 2026-05-08 16:59:24 -07:00
test_file_tools_container_config.py
test_file_tools_live.py
test_file_write_safety.py
test_force_dangerous_override.py
test_fuzzy_match.py
test_hardline_blocklist.py fix(terminal): block sudo -S password guessing when SUDO_PASSWORD is not set 2026-05-11 06:56:30 -07:00
test_heartbeat_stale_thresholds.py test: add unit tests for heartbeat stale threshold increase 2026-05-04 05:08:51 -07:00
test_hidden_dir_filter.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
test_homeassistant_tool.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_image_generation.py
test_image_generation_env.py feat(image-gen): actionable setup message when no FAL backend is reachable (#26222) 2026-05-15 01:33:13 -07:00
test_image_generation_plugin_dispatch.py
test_init_session_cwd_respect.py fix(cli): respect terminal.cwd config in local terminal backend 2026-04-28 22:16:08 -07:00
test_interrupt.py
test_kanban_codex_lane_skill.py docs: add kanban codex lane skill 2026-05-18 21:01:14 -07:00
test_kanban_tools.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_lazy_deps.py fix(update): refresh lazy-installed backends on hermes update (#25766) 2026-05-14 08:03:40 -07:00
test_llm_content_none_guard.py feat(session_search): single-shape tool with discovery, scroll, browse — no LLM (#27590) 2026-05-17 23:28:45 -07:00
test_local_background_child_hang.py
test_local_env_blocklist.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_local_env_cwd_recovery.py fix(local): test root as ancestor candidate; use real pipe for fake stdout 2026-05-04 15:31:47 -07:00
test_local_env_windows_msys.py fix(windows): stop spamming cwd-missing + tirith-spawn warnings on every terminal call 2026-05-15 16:25:31 -07:00
test_local_interrupt_cleanup.py fix(ci): stabilize main test suite regressions (#17660) 2026-04-29 23:18:55 -07:00
test_local_shell_init.py
test_local_tempdir.py
test_managed_browserbase_and_modal.py fix(browser): self-review pass — dead-import, log levels, future-proofing 2026-05-17 04:04:15 -07:00
test_managed_media_gateways.py
test_managed_modal_environment.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
test_managed_tool_gateway.py
test_mcp_cancelled_error_propagation.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
test_mcp_circuit_breaker.py
test_mcp_dynamic_discovery.py fix(ci): recover 38 failing tests on main (#17642) 2026-04-29 20:05:32 -07:00
test_mcp_empty_error_message.py fix(mcp): include exception type in error messages when str(exc) is empty 2026-05-07 06:33:57 -07:00
test_mcp_image_content.py fix(mcp): surface image tool results as MEDIA tags instead of dropping them (#21328) 2026-05-07 07:14:16 -07:00
test_mcp_invalid_url.py fix(mcp): validate remote URLs up-front with a clear error (#27105) 2026-05-16 13:06:56 -07:00
test_mcp_oauth.py fix(mcp-oauth): print SSH tunnel hint in _redirect_handler 2026-05-17 02:29:37 -07:00
test_mcp_oauth_bidirectional.py
test_mcp_oauth_cold_load_expiry.py
test_mcp_oauth_integration.py
test_mcp_oauth_manager.py
test_mcp_oauth_metadata.py fix(mcp-oauth): persist OAuth server metadata across process restarts (#21226) 2026-05-07 05:35:33 -07:00
test_mcp_probe.py fix(async): close unscheduled coroutines in all threadsafe bridges (#26584) 2026-05-15 14:00:01 -07:00
test_mcp_reconnect_signal.py
test_mcp_sse_transport.py fix(mcp): forward OAuth auth and bump sse_read_timeout on SSE transport (#21323) 2026-05-07 07:08:04 -07:00
test_mcp_stability.py fix(mcp): use module-level time so test patches do not race background sleepers 2026-05-17 13:33:26 -07:00
test_mcp_structured_content.py fix(async): close unscheduled coroutines in all threadsafe bridges (#26584) 2026-05-15 14:00:01 -07:00
test_mcp_tool.py fix(mcp): prevent parallel-safe prefix collisions 2026-05-17 11:41:26 -07:00
test_mcp_tool_401_handling.py
test_mcp_tool_issue_948.py
test_mcp_tool_session_expired.py fix(mcp): retry stale pipe transport failures 2026-05-07 06:32:45 -07:00
test_mcp_utility_capability_gating.py fix(mcp): gate utility stubs on server-advertised capabilities (#21347) 2026-05-07 07:39:50 -07:00
test_memory_tool.py
test_memory_tool_import_fallback.py
test_memory_tool_schema.py fix(memory): remove dead allOf schema block at the source 2026-05-07 07:03:21 -07:00
test_microsoft_graph_auth.py test(msgraph): cover concurrent token cache reuse 2026-05-08 09:27:26 -07:00
test_microsoft_graph_client.py fix(msgraph): stream download_to_file body instead of buffering 2026-05-08 09:27:26 -07:00
test_mixture_of_agents_tool.py
test_modal_bulk_upload.py
test_modal_sandbox_fixes.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_modal_snapshot_isolation.py
test_notify_on_complete.py
test_osv_check.py
test_parse_env_var.py
test_patch_parser.py fix(lint): skip per-file shell linter when LSP will handle the file (#29054) 2026-05-20 01:46:40 -05:00
test_pr_6656_regressions.py fix(skills): make content_hash filename-sensitive too (symmetric with bundle_content_hash) 2026-05-22 19:59:24 -07:00
test_process_registry.py fix(tests): catch up 25 stale tests after recent merges (#28626) 2026-05-19 01:28:32 -07:00
test_read_loop_detection.py
test_registry.py test(ci): stabilize shared optional dependency baselines 2026-05-13 17:32:22 -07:00
test_resolve_path.py
test_schema_sanitizer.py fix(xai-responses): strip enum values containing '/' from tool schemas 2026-05-18 10:37:35 -07:00
test_search_hidden_dirs.py
test_send_message_missing_platforms.py
test_send_message_telegram_proxy.py test+release: align send_message mocks for MessageEntity import; map @fonhal 2026-05-18 22:19:50 -07:00
test_send_message_tool.py refactor(gateway): migrate Discord adapter to bundled plugin (full Teams parity) 2026-05-22 14:21:41 -07:00
test_session_search.py feat(session_search): single-shape tool with discovery, scroll, browse — no LLM (#27590) 2026-05-17 23:28:45 -07:00
test_shared_container_task_id.py
test_signal_media.py
test_singularity_preflight.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
test_skill_env_passthrough.py
test_skill_improvements.py
test_skill_manager_tool.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
test_skill_provenance.py test: remove 50 stale/broken tests to unblock CI (#22098) 2026-05-08 14:55:40 -07:00
test_skill_size_limits.py
test_skill_usage.py fix(skills): lock usage telemetry updates 2026-05-07 06:13:37 -07:00
test_skill_view_path_check.py
test_skill_view_traversal.py
test_skills_guard.py
test_skills_hub.py fix(skills-hub): deduplicate search results by identifier, not name 2026-05-20 15:04:01 -07:00
test_skills_hub_browse_sh.py fix(browse-sh): fetch SKILL.md via /api/skills/{slug}+skillMdUrl 2026-05-19 14:17:38 -07:00
test_skills_hub_clawhub.py fix(skills-hub): cover remaining SSRF fetch paths after #10029 2026-05-09 17:52:12 -07:00
test_skills_sync.py
test_skills_tool.py fix(skills): prune dependency/venv dirs from all skill scanners (#30042) 2026-05-21 14:18:02 -07:00
test_slash_confirm.py feat(gateway,cli): confirm /reload-mcp to warn about prompt cache invalidation 2026-04-29 21:56:47 -07:00
test_spotify_client.py
test_ssh_bulk_upload.py fix(ssh): keep bulk sync extraction scoped to .hermes 2026-05-21 19:17:51 -07:00
test_ssh_environment.py
test_symlink_prefix_confusion.py
test_sync_back_backends.py
test_terminal_compound_background.py
test_terminal_config_env_sync.py fix(terminal): bridge docker_env config to TERMINAL_DOCKER_ENV 2026-05-09 17:53:35 -07:00
test_terminal_exit_semantics.py
test_terminal_foreground_timeout_cap.py
test_terminal_none_command_guard.py
test_terminal_output_transform_hook.py
test_terminal_requirements.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_terminal_task_cwd.py fix(acp): honor task cwd for foreground terminal commands 2026-05-09 14:46:34 -07:00
test_terminal_timeout_output.py
test_terminal_tool.py fix(terminal): skip sudo prompt when local NOPASSWD sudo works 2026-04-30 20:38:09 -07:00
test_terminal_tool_pty_fallback.py
test_terminal_tool_requirements.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_threaded_process_handle.py
test_tirith_security.py fix(tirith): suppress .app lookalike_tld false positives in warn verdicts 2026-05-18 10:20:07 -07:00
test_todo_tool.py
test_tool_backend_helpers.py
test_tool_output_limits.py
test_tool_result_storage.py fix(tool-result-storage): persist via stdin to bypass 128 KB exec-arg cap (#22913) 2026-05-09 18:44:58 -07:00
test_transcription.py test(tools): centralize disable_lazy_stt_install fixture in conftest 2026-05-22 03:33:01 -07:00
test_transcription_dotenv_fallback.py test(tools): centralize disable_lazy_stt_install fixture in conftest 2026-05-22 03:33:01 -07:00
test_transcription_tools.py test(tools): centralize disable_lazy_stt_install fixture in conftest 2026-05-22 03:33:01 -07:00
test_tts_command_providers.py feat(tts): add Piper as a native local TTS provider (closes #8508) (#17885) 2026-04-30 02:53:20 -07:00
test_tts_dotenv_fallback.py fix(xai-http): preserve ~/.hermes/.env fallback and XAI_STT_BASE_URL precedence 2026-05-15 12:11:32 -07:00
test_tts_gemini.py
test_tts_kittentts.py test(ci): stabilize shared optional dependency baselines 2026-05-13 17:32:22 -07:00
test_tts_max_text_length.py
test_tts_mistral.py fix(deps): unbreak [all] install — drop mistralai while PyPI quarantined (#24205) 2026-05-11 23:02:15 -07:00
test_tts_opus_routing.py fix(tts): keep native audio outside Telegram voice delivery 2026-05-18 22:29:45 -07:00
test_tts_piper.py feat(tts): add Piper as a native local TTS provider (closes #8508) (#17885) 2026-04-30 02:53:20 -07:00
test_tts_speed.py fix(tts): align MiniMax TTS defaults with current API and add GroupId support 2026-05-13 22:04:28 -07:00
test_tts_xai_speech_tags.py Add opt-in xAI TTS speech tag pauses 2026-05-20 09:22:28 -07:00
test_url_safety.py fix(url_safety): block IPv4-mapped IPv6 addresses to prevent SSRF bypass 2026-05-18 10:51:15 -07:00
test_vercel_sandbox_environment.py test: remove 50 stale/broken tests to unblock CI (#22098) 2026-05-08 14:55:40 -07:00
test_video_analyze.py feat: add video_analyze tool for native video understanding (#19301) 2026-05-04 00:04:36 +05:30
test_video_generation_dispatch.py feat(video_gen): unified video_generate tool with pluggable provider backends (#25126) 2026-05-13 16:39:41 -07:00
test_video_generation_dynamic_schema.py feat(video_gen): unified video_generate tool with pluggable provider backends (#25126) 2026-05-13 16:39:41 -07:00
test_video_generation_tool_surface_matrix.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_vision_native_fast_path.py fix(dashboard): UI polish — modals, layout, consistency, test fixes 2026-05-12 13:59:22 -04:00
test_vision_tools.py
test_voice_cli_integration.py fix(voice): chunk oversized CLI recordings 2026-05-21 14:17:39 -07:00
test_voice_mode.py fix(voice): chunk oversized CLI recordings 2026-05-21 14:17:39 -07:00
test_watch_patterns.py
test_web_providers.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_web_providers_brave_free.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_web_providers_ddgs.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_web_providers_searxng.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_web_providers_xai.py feat(web): add xAI Web Search provider plugin 2026-05-19 19:27:34 -07:00
test_web_tools_config.py refactor(web): dispatch all three tools through web_search_registry 2026-05-13 22:31:28 -07:00
test_web_tools_tavily.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_website_policy.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_windows_compat.py
test_windows_native_support.py feat(security): supply-chain advisory checker + lazy-install framework + tiered install fallback (#24220) 2026-05-12 01:02:25 -07:00
test_write_deny.py test: use subprocesses for each test file (#29016) 2026-05-21 16:40:04 +05:30
test_x_search_tool.py fix(x_search): surface degraded results + validate dates 2026-05-21 02:38:45 +05:30
test_yolo_mode.py fix(approval): harden YOLO mode env parsing against quoted-bool strings 2026-04-30 20:37:37 -07:00
test_zombie_process_cleanup.py ci(tests): add pytest-timeout 60s hard cap to break suite-teardown deadlock (#28861) 2026-05-19 17:27:24 -07:00