hermes-bsd/tests/tools
Brooklyn Nicholson 81436e143e fix(approval): carry allow_permanent to TUI + desktop approval prompts
When a tirith content-security warning is present the approval backend
forces allow_permanent=False and silently downgrades an "always" choice to
session scope (the persistence loop in check_all_command_guards only honors
"always" → permanent when no tirith finding exists). But the gateway notify
payload that drives the TUI and the Electron desktop app never carried that
flag, so both surfaces always rendered "Always allow" — offering a permanent
allow the backend would quietly refuse to persist.

Plumb allow_permanent end-to-end:
- tools/approval.py: include `allow_permanent: not has_tirith` in the gateway
  approval_data the notify callback emits as `approval.request`.
- ui-tui: thread `allowPermanent` through the event handler, gateway types,
  and ApprovalReq; ApprovalPrompt drops the "always" option (and renumbers the
  quick-pick keys) when it's false.
- apps/desktop: thread `allow_permanent` through the gateway payload type, the
  per-session approval store, and the inline ApprovalBar, which now hides the
  "Always allow…" dropdown item when permanent allow is disallowed — reusing
  the existing DropdownMenu / confirm-Dialog UI.

The desktop/TUI render path for approvals already landed in #38578 (the root
cause of approvals not surfacing in the GUI); this completes the salvage of
#37856 by carrying allow_permanent across both surfaces. #37856's original
thread-local _block() approach is dropped: desktop/TUI approvals resolve via
approval.respond → resolve_gateway_approval (the per-session queue), not the
_block()/request_id correlation, so a worker-thread callback waiting on _block
would never be released by the real UI.

Tests: gateway notify payload carries allow_permanent (True without tirith,
False with a tirith warning); ui-tui approvalAction reduced option set +
event-handler allowPermanent propagation; desktop store round-trip + the
ApprovalBar showing/hiding "Always allow".

Supersedes #37856
Closes #37812

Co-authored-by: LeonSGP43 <cine.dreamer.one@gmail.com>
2026-06-11 18:23:59 -05:00
..
__init__.py
conftest.py
test_accretion_caps.py
test_ansi_strip.py
test_approval.py fix(approval): gate resolved Hermes config paths 2026-06-08 11:55:40 -07:00
test_approval_heartbeat.py
test_approval_plugin_hooks.py
test_base_environment.py
test_blueprints.py refactor(cron): rebrand Cron Recipes -> Automation Blueprints 2026-06-11 10:49:47 -07:00
test_browser_camofox.py
test_browser_camofox_persistence.py
test_browser_camofox_state.py
test_browser_cdp_override.py
test_browser_cdp_tool.py
test_browser_chromium_check.py
test_browser_cleanup.py
test_browser_cloud_fallback.py
test_browser_cloud_provider_cache.py
test_browser_console.py
test_browser_content_none_guard.py
test_browser_eval_supervisor_path.py
test_browser_hardening.py
test_browser_homebrew_paths.py
test_browser_hybrid_routing.py
test_browser_lightpanda.py
test_browser_orphan_reaper.py
test_browser_secret_exfil.py fix(tools): percent-encode non-ascii URL components 2026-06-07 11:42:26 -06:00
test_browser_ssrf_local.py
test_browser_supervisor.py
test_browser_supervisor_healthcheck.py
test_budget_config.py
test_checkpoint_manager.py
test_clarify_gateway.py
test_clarify_tool.py
test_clipboard.py
test_code_execution.py
test_code_execution_modes.py
test_code_execution_windows_env.py
test_command_guards.py fix(approval): carry allow_permanent to TUI + desktop approval prompts 2026-06-11 18:23:59 -05:00
test_computer_use.py fix(xai): accept Grok Build code during loopback wait + tiny screenshot guard 2026-06-09 23:21:24 -07:00
test_computer_use_capture_routing.py fix(xai): accept Grok Build code during loopback wait + tiny screenshot guard 2026-06-09 23:21:24 -07:00
test_computer_use_vision_routing.py fix(computer_use): honor custom vision routing 2026-06-07 02:09:20 -07:00
test_config_null_guard.py
test_credential_files.py refactor(image_gen): delegate cache-path mapping to shared helper 2026-06-06 13:19:07 -07:00
test_credential_pool_env_fallback.py
test_cron_approval_mode.py
test_cron_prompt_injection.py
test_cronjob_tools.py test(cron): cover provider "custom" → providers.custom resolution 2026-06-10 14:39:03 -07:00
test_cross_profile_guard.py
test_daytona_environment.py
test_debug_helpers.py
test_delegate.py fix(delegate): resolve custom-endpoint subagent pools by endpoint identity (#41730) 2026-06-07 22:05:14 -07:00
test_delegate_composite_toolsets.py
test_delegate_subagent_timeout_diagnostic.py
test_delegate_toolset_scope.py
test_discord_tool.py
test_docker_config_migrate.py fix(config): preserve custom-provider models maps and metadata through v11->v12 migration (#40573) 2026-06-06 18:43:20 -07:00
test_docker_environment.py test: update docker preflight assertion for stdin=DEVNULL kwarg 2026-06-08 22:46:57 -07:00
test_docker_find.py
test_docker_orphan_reaper_integration.py
test_dockerfile_node_modules_perms.py fix(docker): chown gateway install tree on UID remap (salvage #37928) (#38655) 2026-06-04 13:34:23 +10:00
test_dockerfile_pid1_reaping.py fix(docker): pre-install matrix deps in Docker image (#30399) (#42413) 2026-06-10 19:23:06 +10:00
test_env_passthrough.py
test_env_probe.py
test_execute_code_approval_cluster.py fix(approval): check is_approved in execute_code guard (#39275) 2026-06-04 19:40:30 -07:00
test_feishu_tools.py
test_file_operations.py
test_file_operations_edge_cases.py
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
test_file_sync_perf.py
test_file_tools.py fix(file_tools): block agent writes to ~/.hermes/config.yaml to prevent silent approval bypass 2026-06-01 03:29:48 -07:00
test_file_tools_container_config.py
test_file_tools_cwd_resolution.py fix(file-tools): reject sentinel TERMINAL_CWD; anchor worktree edits before live cwd exists (#41861) 2026-06-07 23:58:47 -07:00
test_file_tools_live.py
test_file_write_safety.py
test_force_dangerous_override.py
test_fuzzy_match.py
test_gateway_cwd_contract.py test(tools): characterize tool-surface TERMINAL_CWD contract (#29265) 2026-06-01 16:55:04 -07:00
test_hardline_blocklist.py
test_heartbeat_stale_thresholds.py
test_hidden_dir_filter.py
test_homeassistant_tool.py
test_image_generation.py
test_image_generation_artifacts.py fix(image_gen): expose backend-visible artifact paths 2026-06-06 13:19:07 -07:00
test_image_generation_env.py
test_image_generation_plugin_dispatch.py
test_init_session_cwd_respect.py
test_interrupt.py
test_kanban_tools.py fix(kanban): kanban_create inherits the spawning worker's task workspace (#37182) 2026-06-01 21:26:29 -07:00
test_lazy_deps.py
test_line_ending_preservation.py
test_llm_content_none_guard.py
test_local_background_child_hang.py
test_local_env_blocklist.py fix(terminal): complete sane PATH entries on POSIX (salvage of #35614) (#42653) 2026-06-09 02:21:12 -07:00
test_local_env_cwd_recovery.py
test_local_env_windows_msys.py
test_local_interrupt_cleanup.py
test_local_shell_init.py
test_local_tempdir.py
test_managed_browserbase_and_modal.py test(approval): regression for shell-escape denylist bypass (#36846, #36847) 2026-06-07 03:57:21 -07:00
test_managed_media_gateways.py
test_managed_modal_environment.py
test_managed_tool_gateway.py
test_mcp_cancelled_error_propagation.py
test_mcp_circuit_breaker.py
test_mcp_client_cert.py
test_mcp_dynamic_discovery.py
test_mcp_empty_error_message.py
test_mcp_image_content.py
test_mcp_invalid_url.py
test_mcp_loop_profile_override.py fix(mcp): propagate HERMES_HOME override onto the MCP event loop (#44220) 2026-06-11 04:37:01 -07:00
test_mcp_oauth.py
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
test_mcp_preflight_content_type.py fix(mcp): make non-MCP HTTP endpoint fast-fail robust and non-retryable 2026-06-01 19:49:50 -07:00
test_mcp_probe.py
test_mcp_reconnect_signal.py
test_mcp_sse_transport.py
test_mcp_stability.py fix(tests): close pid-file read race in test_grandchild_reaped_via_pgroup (#43447) 2026-06-10 02:57:27 -07:00
test_mcp_structured_content.py
test_mcp_tool.py fix(mcp): avoid false failed startup status 2026-06-11 09:01:52 -07:00
test_mcp_tool_401_handling.py
test_mcp_tool_issue_948.py
test_mcp_tool_session_expired.py
test_mcp_utility_capability_gating.py
test_memory_tool.py fix(memory): instruct in-turn consolidation + retry on overflow (#41755) 2026-06-07 22:16:28 -07:00
test_memory_tool_import_fallback.py
test_memory_tool_schema.py
test_microsoft_graph_auth.py
test_microsoft_graph_client.py
test_mixture_of_agents_tool.py
test_modal_bulk_upload.py
test_modal_sandbox_fixes.py
test_modal_snapshot_isolation.py
test_notify_on_complete.py
test_osv_check.py fix(osv_check): honor npx --package/-p install target when parsing package arg (#40567) 2026-06-06 18:30:39 -07:00
test_parse_env_var.py
test_patch_failure_tracking.py
test_patch_parser.py
test_pr_6656_regressions.py
test_process_registry.py fix(tui): handle Windows PTY stdin and detached WS frames (#41953) 2026-06-08 09:41:20 -07:00
test_read_loop_detection.py
test_registry.py
test_resolve_path.py
test_schema_sanitizer.py
test_search_error_guard.py fix(file-ops): make rg/grep search error guard reachable and preserve partial matches (#39858) 2026-06-05 17:44:52 -07:00
test_search_hidden_dirs.py
test_send_message_missing_platforms.py refactor(gateway): migrate Home Assistant adapter to bundled plugin 2026-06-06 11:46:24 -07:00
test_send_message_target_parse.py fix(photon): support E.164 and DM GUID targets for home channel 2026-06-08 21:03:58 -07:00
test_send_message_telegram_proxy.py
test_send_message_tool.py fix(photon): support E.164 and DM GUID targets for home channel 2026-06-08 21:03:58 -07:00
test_session_search.py feat(desktop): drag sessions into chat as @session links + spawn loader 2026-06-04 19:41:51 -05:00
test_shared_container_task_id.py fix(terminal): collapse CWD-only overrides to shared container 2026-06-07 23:04:54 -07:00
test_signal_media.py
test_singularity_preflight.py
test_skill_env_passthrough.py
test_skill_improvements.py
test_skill_manager_tool.py fix(skill_manager): allow SKILL.md in _validate_file_path without weakening traversal guard (#40568) 2026-06-06 18:32:37 -07:00
test_skill_provenance.py
test_skill_size_limits.py
test_skill_usage.py
test_skill_view_path_check.py
test_skill_view_traversal.py fix(skills): block path traversal via skill_view name argument (#40566) 2026-06-06 18:29:52 -07:00
test_skills_ast_audit.py
test_skills_guard.py
test_skills_hub.py fix(skills): honour overall_timeout and bound ClawHub catalog walk 2026-06-09 23:22:54 -07:00
test_skills_hub_browse_sh.py
test_skills_hub_clawhub.py fix(skills): let ClawHub index build walk past the 12s browse budget (#44500) 2026-06-11 18:03:11 -04:00
test_skills_sync.py feat(skills): blank-slate skills — install --no-skills + opt-out/opt-in (#36228) 2026-06-01 02:57:57 -07:00
test_skills_tool.py fix(skills): resolve skill_view by frontmatter name when dir name differs 2026-06-10 10:51:45 +05:30
test_slash_confirm.py
test_spotify_client.py
test_ssh_bulk_upload.py fix(ssh): handle WinError 1314 symlink failure with shutil.copy2 fallback 2026-06-04 18:06:21 -07:00
test_ssh_environment.py
test_stage2_hook_build_tree_chown.py fix(docker): chown build trees on UID remap independently of $HERMES_HOME (#35027 regression) (#38556) 2026-06-04 10:17:55 +10:00
test_stage2_hook_gateway_bootstrap_state.py fix(docker): seed gateway_state.json from HERMES_GATEWAY_BOOTSTRAP_STATE on first boot (#37896) 2026-06-03 15:11:15 +10:00
test_stage2_hook_install_dir_chown.py fix(docker): chown gateway install tree on UID remap (salvage #37928) (#38655) 2026-06-04 13:34:23 +10:00
test_stage2_hook_puid_pgid.py fix(docker): run config migrations during container boot (salvage #35508) (#36627) 2026-06-04 11:11:27 +10:00
test_stage2_hook_toplevel_chown.py
test_stage2_hook_unraid_uid.py fix(docker): accept Unraid uid mappings (#38098) 2026-06-04 12:38:24 +10:00
test_stage2_hook_user_flag_guard.py fix(docker): reject unsupported --user <arbitrary-uid> start with clear guidance (#38579) 2026-06-04 10:51:51 +10:00
test_subprocess_stdin_guard.py test: guard OAuth setup-token stays interactive + marker exemption 2026-06-08 22:46:57 -07:00
test_symlink_prefix_confusion.py
test_sync_back_backends.py
test_terminal_compound_background.py
test_terminal_config_env_sync.py fix(test): track TERMINAL_CONFIG_ENV_MAP after env-sync consolidation (#42695) 2026-06-09 02:11:46 -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
test_terminal_task_cwd.py fix(terminal): guard os.getcwd() against a deleted CWD 2026-06-04 23:39:34 -07:00
test_terminal_timeout_output.py
test_terminal_tool.py fix(desktop): use sudo callback without interactive env 2026-06-10 14:29:56 -07:00
test_terminal_tool_pty_fallback.py
test_terminal_tool_requirements.py
test_threaded_process_handle.py
test_threat_patterns.py
test_tirith_security.py
test_todo_tool.py hardening(todo): bound TodoStore item content length and count 2026-06-07 18:06:27 -07:00
test_tool_backend_helpers.py
test_tool_output_limits.py
test_tool_result_storage.py
test_tool_search.py test: restore unrelated trailing newlines in cwd/tool-search tests 2026-06-03 06:36:46 -07:00
test_transcription.py
test_transcription_command_providers.py
test_transcription_dotenv_fallback.py
test_transcription_plugin_dispatch.py
test_transcription_tools.py
test_tts_command_providers.py
test_tts_dotenv_fallback.py
test_tts_gemini.py feat(tts): add Gemini audio tag rewrite 2026-06-10 02:57:39 -07:00
test_tts_kittentts.py
test_tts_max_text_length.py test: port voice-reply suffix assertions, fix change-detector cap test, add AUTHOR_MAP entry 2026-06-10 02:57:39 -07:00
test_tts_mistral.py
test_tts_opus_routing.py
test_tts_path_traversal.py
test_tts_piper.py
test_tts_plugin_dispatch.py
test_tts_speed.py
test_tts_xai_speech_tags.py
test_url_safety.py fix(tools): percent-encode non-ascii URL components 2026-06-07 11:42:26 -06:00
test_video_analyze.py
test_video_generation_dispatch.py
test_video_generation_dynamic_schema.py
test_video_generation_tool_surface_matrix.py fix(xai): route video models by modality 2026-06-01 19:00:30 -07:00
test_vision_native_fast_path.py
test_vision_tools.py fix(web): run URL SSRF checks off the event loop in async paths 2026-06-04 18:04:47 -07:00
test_voice_cli_integration.py
test_voice_mode.py
test_watch_patterns.py
test_web_keyless_default_fallback.py test(web): cover keyless default surviving a failed plugin sweep 2026-06-11 12:56:44 -07:00
test_web_providers.py feat(web): Parallel-backed web search & extract — free Search MCP when keyless, v1 REST when keyed 2026-06-10 19:54:38 -07:00
test_web_providers_brave_free.py fix(test): patch async_is_safe_url in web-provider SSRF mocks 2026-06-04 18:04:47 -07:00
test_web_providers_ddgs.py feat(web): Parallel-backed web search & extract — free Search MCP when keyless, v1 REST when keyed 2026-06-10 19:54:38 -07:00
test_web_providers_searxng.py feat(web): Parallel-backed web search & extract — free Search MCP when keyless, v1 REST when keyed 2026-06-10 19:54:38 -07:00
test_web_providers_xai.py
test_web_tools_config.py feat(web): Parallel-backed web search & extract — free Search MCP when keyless, v1 REST when keyed 2026-06-10 19:54:38 -07:00
test_web_tools_tavily.py
test_website_policy.py fix(web): run URL SSRF checks off the event loop in async paths 2026-06-04 18:04:47 -07:00
test_windows_compat.py
test_windows_native_support.py fix(terminal): complete sane PATH entries on POSIX (salvage of #35614) (#42653) 2026-06-09 02:21:12 -07:00
test_write_approval.py fix(memory,skills): repair write-approval inline prompt, gateway staging, and gateway /skills review (#43452) 2026-06-10 02:57:15 -07:00
test_write_deny.py
test_x_search_tool.py
test_yolo_mode.py
test_zombie_process_cleanup.py