calvyn-code 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +217 -0
- package/README.zh-CN.md +180 -0
- package/acp_adapter/__init__.py +1 -0
- package/acp_adapter/__main__.py +5 -0
- package/acp_adapter/auth.py +68 -0
- package/acp_adapter/bootstrap/__init__.py +0 -0
- package/acp_adapter/bootstrap/bootstrap_browser_tools.ps1 +288 -0
- package/acp_adapter/bootstrap/bootstrap_browser_tools.sh +399 -0
- package/acp_adapter/entry.py +292 -0
- package/acp_adapter/events.py +265 -0
- package/acp_adapter/permissions.py +148 -0
- package/acp_adapter/server.py +1713 -0
- package/acp_adapter/session.py +629 -0
- package/acp_adapter/tools.py +1180 -0
- package/agent/__init__.py +6 -0
- package/agent/__pycache__/__init__.cpython-312.pyc +0 -0
- package/agent/__pycache__/account_usage.cpython-312.pyc +0 -0
- package/agent/__pycache__/anthropic_adapter.cpython-312.pyc +0 -0
- package/agent/__pycache__/async_utils.cpython-312.pyc +0 -0
- package/agent/__pycache__/auxiliary_client.cpython-312.pyc +0 -0
- package/agent/__pycache__/codex_responses_adapter.cpython-312.pyc +0 -0
- package/agent/__pycache__/context_compressor.cpython-312.pyc +0 -0
- package/agent/__pycache__/context_engine.cpython-312.pyc +0 -0
- package/agent/__pycache__/context_references.cpython-312.pyc +0 -0
- package/agent/__pycache__/credential_pool.cpython-312.pyc +0 -0
- package/agent/__pycache__/curator.cpython-312.pyc +0 -0
- package/agent/__pycache__/display.cpython-312.pyc +0 -0
- package/agent/__pycache__/error_classifier.cpython-312.pyc +0 -0
- package/agent/__pycache__/file_safety.cpython-312.pyc +0 -0
- package/agent/__pycache__/google_code_assist.cpython-312.pyc +0 -0
- package/agent/__pycache__/google_oauth.cpython-312.pyc +0 -0
- package/agent/__pycache__/i18n.cpython-312.pyc +0 -0
- package/agent/__pycache__/image_gen_provider.cpython-312.pyc +0 -0
- package/agent/__pycache__/image_gen_registry.cpython-312.pyc +0 -0
- package/agent/__pycache__/insights.cpython-312.pyc +0 -0
- package/agent/__pycache__/lmstudio_reasoning.cpython-312.pyc +0 -0
- package/agent/__pycache__/manual_compression_feedback.cpython-312.pyc +0 -0
- package/agent/__pycache__/markdown_tables.cpython-312.pyc +0 -0
- package/agent/__pycache__/memory_manager.cpython-312.pyc +0 -0
- package/agent/__pycache__/memory_provider.cpython-312.pyc +0 -0
- package/agent/__pycache__/model_metadata.cpython-312.pyc +0 -0
- package/agent/__pycache__/models_dev.cpython-312.pyc +0 -0
- package/agent/__pycache__/moonshot_schema.cpython-312.pyc +0 -0
- package/agent/__pycache__/onboarding.cpython-312.pyc +0 -0
- package/agent/__pycache__/portal_tags.cpython-312.pyc +0 -0
- package/agent/__pycache__/prompt_builder.cpython-312.pyc +0 -0
- package/agent/__pycache__/prompt_caching.cpython-312.pyc +0 -0
- package/agent/__pycache__/redact.cpython-312.pyc +0 -0
- package/agent/__pycache__/retry_utils.cpython-312.pyc +0 -0
- package/agent/__pycache__/shell_hooks.cpython-312.pyc +0 -0
- package/agent/__pycache__/skill_commands.cpython-312.pyc +0 -0
- package/agent/__pycache__/skill_preprocessing.cpython-312.pyc +0 -0
- package/agent/__pycache__/skill_utils.cpython-312.pyc +0 -0
- package/agent/__pycache__/subdirectory_hints.cpython-312.pyc +0 -0
- package/agent/__pycache__/think_scrubber.cpython-312.pyc +0 -0
- package/agent/__pycache__/title_generator.cpython-312.pyc +0 -0
- package/agent/__pycache__/tool_guardrails.cpython-312.pyc +0 -0
- package/agent/__pycache__/tool_result_classification.cpython-312.pyc +0 -0
- package/agent/__pycache__/trajectory.cpython-312.pyc +0 -0
- package/agent/__pycache__/usage_pricing.cpython-312.pyc +0 -0
- package/agent/__pycache__/video_gen_provider.cpython-312.pyc +0 -0
- package/agent/__pycache__/video_gen_registry.cpython-312.pyc +0 -0
- package/agent/__pycache__/web_search_provider.cpython-312.pyc +0 -0
- package/agent/__pycache__/web_search_registry.cpython-312.pyc +0 -0
- package/agent/account_usage.py +326 -0
- package/agent/anthropic_adapter.py +2087 -0
- package/agent/async_utils.py +68 -0
- package/agent/auxiliary_client.py +4893 -0
- package/agent/bedrock_adapter.py +1276 -0
- package/agent/codex_responses_adapter.py +1084 -0
- package/agent/context_compressor.py +1583 -0
- package/agent/context_engine.py +211 -0
- package/agent/context_references.py +519 -0
- package/agent/copilot_acp_client.py +684 -0
- package/agent/credential_pool.py +1780 -0
- package/agent/credential_sources.py +449 -0
- package/agent/curator.py +1782 -0
- package/agent/curator_backup.py +694 -0
- package/agent/display.py +987 -0
- package/agent/error_classifier.py +1058 -0
- package/agent/file_safety.py +112 -0
- package/agent/gemini_cloudcode_adapter.py +909 -0
- package/agent/gemini_native_adapter.py +971 -0
- package/agent/gemini_schema.py +99 -0
- package/agent/google_code_assist.py +452 -0
- package/agent/google_oauth.py +1062 -0
- package/agent/i18n.py +258 -0
- package/agent/image_gen_provider.py +243 -0
- package/agent/image_gen_registry.py +145 -0
- package/agent/image_routing.py +301 -0
- package/agent/insights.py +931 -0
- package/agent/lmstudio_reasoning.py +48 -0
- package/agent/lsp/__init__.py +106 -0
- package/agent/lsp/__pycache__/__init__.cpython-312.pyc +0 -0
- package/agent/lsp/__pycache__/cli.cpython-312.pyc +0 -0
- package/agent/lsp/__pycache__/client.cpython-312.pyc +0 -0
- package/agent/lsp/__pycache__/eventlog.cpython-312.pyc +0 -0
- package/agent/lsp/__pycache__/manager.cpython-312.pyc +0 -0
- package/agent/lsp/__pycache__/protocol.cpython-312.pyc +0 -0
- package/agent/lsp/__pycache__/servers.cpython-312.pyc +0 -0
- package/agent/lsp/__pycache__/workspace.cpython-312.pyc +0 -0
- package/agent/lsp/cli.py +308 -0
- package/agent/lsp/client.py +930 -0
- package/agent/lsp/eventlog.py +213 -0
- package/agent/lsp/install.py +376 -0
- package/agent/lsp/manager.py +644 -0
- package/agent/lsp/protocol.py +196 -0
- package/agent/lsp/range_shift.py +149 -0
- package/agent/lsp/reporter.py +78 -0
- package/agent/lsp/servers.py +1040 -0
- package/agent/lsp/workspace.py +223 -0
- package/agent/manual_compression_feedback.py +49 -0
- package/agent/markdown_tables.py +309 -0
- package/agent/memory_manager.py +556 -0
- package/agent/memory_provider.py +279 -0
- package/agent/model_metadata.py +1827 -0
- package/agent/models_dev.py +724 -0
- package/agent/moonshot_schema.py +231 -0
- package/agent/nous_rate_guard.py +326 -0
- package/agent/onboarding.py +193 -0
- package/agent/plugin_llm.py +1046 -0
- package/agent/portal_tags.py +64 -0
- package/agent/prompt_builder.py +1457 -0
- package/agent/prompt_caching.py +79 -0
- package/agent/rate_limit_tracker.py +246 -0
- package/agent/redact.py +403 -0
- package/agent/retry_utils.py +57 -0
- package/agent/shell_hooks.py +837 -0
- package/agent/skill_commands.py +502 -0
- package/agent/skill_preprocessing.py +131 -0
- package/agent/skill_utils.py +512 -0
- package/agent/subdirectory_hints.py +224 -0
- package/agent/think_scrubber.py +386 -0
- package/agent/title_generator.py +171 -0
- package/agent/tool_guardrails.py +458 -0
- package/agent/tool_result_classification.py +26 -0
- package/agent/trajectory.py +56 -0
- package/agent/transports/__init__.py +68 -0
- package/agent/transports/__pycache__/__init__.cpython-312.pyc +0 -0
- package/agent/transports/__pycache__/anthropic.cpython-312.pyc +0 -0
- package/agent/transports/__pycache__/base.cpython-312.pyc +0 -0
- package/agent/transports/__pycache__/bedrock.cpython-312.pyc +0 -0
- package/agent/transports/__pycache__/chat_completions.cpython-312.pyc +0 -0
- package/agent/transports/__pycache__/codex.cpython-312.pyc +0 -0
- package/agent/transports/__pycache__/types.cpython-312.pyc +0 -0
- package/agent/transports/anthropic.py +179 -0
- package/agent/transports/base.py +89 -0
- package/agent/transports/bedrock.py +154 -0
- package/agent/transports/chat_completions.py +614 -0
- package/agent/transports/codex.py +283 -0
- package/agent/transports/codex_app_server.py +368 -0
- package/agent/transports/codex_app_server_session.py +810 -0
- package/agent/transports/codex_event_projector.py +312 -0
- package/agent/transports/hermes_tools_mcp_server.py +233 -0
- package/agent/transports/types.py +162 -0
- package/agent/usage_pricing.py +877 -0
- package/agent/video_gen_provider.py +300 -0
- package/agent/video_gen_registry.py +117 -0
- package/agent/web_search_provider.py +221 -0
- package/agent/web_search_registry.py +262 -0
- package/assets/banner.png +0 -0
- package/batch_runner.py +1303 -0
- package/bin/calvyn.js +67 -0
- package/calvyn_bootstrap.py +130 -0
- package/calvyn_constants.py +346 -0
- package/calvyn_logging.py +390 -0
- package/calvyn_state.py +2967 -0
- package/calvyn_time.py +105 -0
- package/cli.py +14160 -0
- package/cron/__init__.py +42 -0
- package/cron/__pycache__/__init__.cpython-312.pyc +0 -0
- package/cron/__pycache__/jobs.cpython-312.pyc +0 -0
- package/cron/__pycache__/scheduler.cpython-312.pyc +0 -0
- package/cron/jobs.py +1160 -0
- package/cron/scheduler.py +1832 -0
- package/gateway/__init__.py +35 -0
- package/gateway/__pycache__/__init__.cpython-312.pyc +0 -0
- package/gateway/__pycache__/channel_directory.cpython-312.pyc +0 -0
- package/gateway/__pycache__/config.cpython-312.pyc +0 -0
- package/gateway/__pycache__/delivery.cpython-312.pyc +0 -0
- package/gateway/__pycache__/display_config.cpython-312.pyc +0 -0
- package/gateway/__pycache__/hooks.cpython-312.pyc +0 -0
- package/gateway/__pycache__/pairing.cpython-312.pyc +0 -0
- package/gateway/__pycache__/platform_registry.cpython-312.pyc +0 -0
- package/gateway/__pycache__/restart.cpython-312.pyc +0 -0
- package/gateway/__pycache__/run.cpython-312.pyc +0 -0
- package/gateway/__pycache__/runtime_footer.cpython-312.pyc +0 -0
- package/gateway/__pycache__/session.cpython-312.pyc +0 -0
- package/gateway/__pycache__/session_context.cpython-312.pyc +0 -0
- package/gateway/__pycache__/shutdown_forensics.cpython-312.pyc +0 -0
- package/gateway/__pycache__/slash_access.cpython-312.pyc +0 -0
- package/gateway/__pycache__/status.cpython-312.pyc +0 -0
- package/gateway/__pycache__/stream_consumer.cpython-312.pyc +0 -0
- package/gateway/__pycache__/whatsapp_identity.cpython-312.pyc +0 -0
- package/gateway/assets/telegram-botfather-threads-settings.jpg +0 -0
- package/gateway/builtin_hooks/__init__.py +1 -0
- package/gateway/channel_directory.py +357 -0
- package/gateway/config.py +1873 -0
- package/gateway/delivery.py +258 -0
- package/gateway/display_config.py +206 -0
- package/gateway/hooks.py +210 -0
- package/gateway/mirror.py +179 -0
- package/gateway/pairing.py +322 -0
- package/gateway/platform_registry.py +260 -0
- package/gateway/platforms/ADDING_A_PLATFORM.md +374 -0
- package/gateway/platforms/__init__.py +45 -0
- package/gateway/platforms/__pycache__/__init__.cpython-312.pyc +0 -0
- package/gateway/platforms/__pycache__/base.cpython-312.pyc +0 -0
- package/gateway/platforms/__pycache__/helpers.cpython-312.pyc +0 -0
- package/gateway/platforms/__pycache__/telegram.cpython-312.pyc +0 -0
- package/gateway/platforms/__pycache__/telegram_network.cpython-312.pyc +0 -0
- package/gateway/platforms/__pycache__/yuanbao.cpython-312.pyc +0 -0
- package/gateway/platforms/__pycache__/yuanbao_media.cpython-312.pyc +0 -0
- package/gateway/platforms/__pycache__/yuanbao_proto.cpython-312.pyc +0 -0
- package/gateway/platforms/_http_client_limits.py +84 -0
- package/gateway/platforms/api_server.py +3488 -0
- package/gateway/platforms/base.py +3747 -0
- package/gateway/platforms/bluebubbles.py +937 -0
- package/gateway/platforms/dingtalk.py +1473 -0
- package/gateway/platforms/discord.py +5584 -0
- package/gateway/platforms/email.py +773 -0
- package/gateway/platforms/feishu.py +5059 -0
- package/gateway/platforms/feishu_comment.py +1382 -0
- package/gateway/platforms/feishu_comment_rules.py +430 -0
- package/gateway/platforms/helpers.py +279 -0
- package/gateway/platforms/homeassistant.py +449 -0
- package/gateway/platforms/matrix.py +2777 -0
- package/gateway/platforms/mattermost.py +852 -0
- package/gateway/platforms/msgraph_webhook.py +397 -0
- package/gateway/platforms/qqbot/__init__.py +91 -0
- package/gateway/platforms/qqbot/adapter.py +3072 -0
- package/gateway/platforms/qqbot/chunked_upload.py +602 -0
- package/gateway/platforms/qqbot/constants.py +74 -0
- package/gateway/platforms/qqbot/crypto.py +45 -0
- package/gateway/platforms/qqbot/keyboards.py +473 -0
- package/gateway/platforms/qqbot/onboard.py +220 -0
- package/gateway/platforms/qqbot/utils.py +71 -0
- package/gateway/platforms/signal.py +1518 -0
- package/gateway/platforms/signal_rate_limit.py +369 -0
- package/gateway/platforms/slack.py +3028 -0
- package/gateway/platforms/sms.py +377 -0
- package/gateway/platforms/telegram.py +4836 -0
- package/gateway/platforms/telegram_network.py +249 -0
- package/gateway/platforms/webhook.py +806 -0
- package/gateway/platforms/wecom.py +1610 -0
- package/gateway/platforms/wecom_callback.py +403 -0
- package/gateway/platforms/wecom_crypto.py +142 -0
- package/gateway/platforms/weixin.py +2170 -0
- package/gateway/platforms/whatsapp.py +1283 -0
- package/gateway/platforms/yuanbao.py +4873 -0
- package/gateway/platforms/yuanbao_media.py +645 -0
- package/gateway/platforms/yuanbao_proto.py +1209 -0
- package/gateway/platforms/yuanbao_sticker.py +558 -0
- package/gateway/restart.py +20 -0
- package/gateway/run.py +17074 -0
- package/gateway/runtime_footer.py +150 -0
- package/gateway/session.py +1399 -0
- package/gateway/session_context.py +156 -0
- package/gateway/shutdown_forensics.py +462 -0
- package/gateway/slash_access.py +229 -0
- package/gateway/status.py +972 -0
- package/gateway/sticker_cache.py +111 -0
- package/gateway/stream_consumer.py +1286 -0
- package/gateway/whatsapp_identity.py +156 -0
- package/hermes_cli/__init__.py +47 -0
- package/hermes_cli/__pycache__/__init__.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/_parser.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/auth.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/banner.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/browser_connect.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/callbacks.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/checkpoints.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/cli_output.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/codex_models.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/codex_runtime_switch.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/colors.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/commands.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/config.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/copilot_auth.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/curator.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/curses_ui.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/debug.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/default_soul.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/env_loader.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/fallback_cmd.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/gateway.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/gateway_windows.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/goals.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/inventory.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/kanban.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/kanban_db.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/main.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/model_catalog.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/model_normalize.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/model_switch.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/models.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/nous_subscription.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/pairing.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/platforms.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/plugins.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/profiles.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/providers.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/pt_input_extras.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/runtime_provider.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/security_advisories.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/setup.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/skills_hub.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/skin_engine.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/stdio.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/timeouts.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/tips.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/tools_config.cpython-312.pyc +0 -0
- package/hermes_cli/__pycache__/voice.cpython-312.pyc +0 -0
- package/hermes_cli/_parser.py +365 -0
- package/hermes_cli/_subprocess_compat.py +175 -0
- package/hermes_cli/auth.py +6299 -0
- package/hermes_cli/auth_commands.py +749 -0
- package/hermes_cli/azure_detect.py +300 -0
- package/hermes_cli/backup.py +938 -0
- package/hermes_cli/banner.py +703 -0
- package/hermes_cli/browser_connect.py +139 -0
- package/hermes_cli/callbacks.py +243 -0
- package/hermes_cli/checkpoints.py +244 -0
- package/hermes_cli/claw.py +810 -0
- package/hermes_cli/cli_output.py +78 -0
- package/hermes_cli/clipboard.py +495 -0
- package/hermes_cli/codex_models.py +198 -0
- package/hermes_cli/codex_runtime_plugin_migration.py +757 -0
- package/hermes_cli/codex_runtime_switch.py +266 -0
- package/hermes_cli/colors.py +38 -0
- package/hermes_cli/commands.py +1728 -0
- package/hermes_cli/completion.py +315 -0
- package/hermes_cli/config.py +5382 -0
- package/hermes_cli/copilot_auth.py +392 -0
- package/hermes_cli/cron.py +313 -0
- package/hermes_cli/curator.py +598 -0
- package/hermes_cli/curses_ui.py +472 -0
- package/hermes_cli/debug.py +747 -0
- package/hermes_cli/default_soul.py +11 -0
- package/hermes_cli/dep_ensure.py +107 -0
- package/hermes_cli/dingtalk_auth.py +293 -0
- package/hermes_cli/doctor.py +1863 -0
- package/hermes_cli/dump.py +326 -0
- package/hermes_cli/env_loader.py +175 -0
- package/hermes_cli/fallback_cmd.py +361 -0
- package/hermes_cli/gateway.py +5422 -0
- package/hermes_cli/gateway_windows.py +692 -0
- package/hermes_cli/goals.py +757 -0
- package/hermes_cli/hooks.py +385 -0
- package/hermes_cli/inventory.py +240 -0
- package/hermes_cli/kanban.py +2252 -0
- package/hermes_cli/kanban_db.py +4840 -0
- package/hermes_cli/kanban_diagnostics.py +776 -0
- package/hermes_cli/kanban_specify.py +266 -0
- package/hermes_cli/logs.py +391 -0
- package/hermes_cli/main.py +12396 -0
- package/hermes_cli/mcp_config.py +781 -0
- package/hermes_cli/memory_setup.py +465 -0
- package/hermes_cli/model_catalog.py +330 -0
- package/hermes_cli/model_normalize.py +473 -0
- package/hermes_cli/model_switch.py +1777 -0
- package/hermes_cli/models.py +3789 -0
- package/hermes_cli/nous_subscription.py +799 -0
- package/hermes_cli/oneshot.py +351 -0
- package/hermes_cli/pairing.py +115 -0
- package/hermes_cli/platforms.py +83 -0
- package/hermes_cli/plugins.py +1562 -0
- package/hermes_cli/plugins_cmd.py +1587 -0
- package/hermes_cli/profile_distribution.py +703 -0
- package/hermes_cli/profiles.py +1319 -0
- package/hermes_cli/providers.py +720 -0
- package/hermes_cli/proxy/__init__.py +20 -0
- package/hermes_cli/proxy/adapters/__init__.py +35 -0
- package/hermes_cli/proxy/adapters/base.py +94 -0
- package/hermes_cli/proxy/adapters/nous_portal.py +137 -0
- package/hermes_cli/proxy/cli.py +141 -0
- package/hermes_cli/proxy/server.py +265 -0
- package/hermes_cli/pt_input_extras.py +83 -0
- package/hermes_cli/pty_bridge.py +237 -0
- package/hermes_cli/relaunch.py +205 -0
- package/hermes_cli/runtime_provider.py +1428 -0
- package/hermes_cli/security_advisories.py +452 -0
- package/hermes_cli/setup.py +3559 -0
- package/hermes_cli/skills_config.py +177 -0
- package/hermes_cli/skills_hub.py +1595 -0
- package/hermes_cli/skin_engine.py +929 -0
- package/hermes_cli/slack_cli.py +160 -0
- package/hermes_cli/status.py +550 -0
- package/hermes_cli/stdio.py +252 -0
- package/hermes_cli/timeouts.py +82 -0
- package/hermes_cli/tips.py +487 -0
- package/hermes_cli/tools_config.py +3151 -0
- package/hermes_cli/uninstall.py +681 -0
- package/hermes_cli/vercel_auth.py +70 -0
- package/hermes_cli/voice.py +846 -0
- package/hermes_cli/web_server.py +4438 -0
- package/hermes_cli/webhook.py +275 -0
- package/locales/af.yaml +350 -0
- package/locales/de.yaml +350 -0
- package/locales/en.yaml +365 -0
- package/locales/es.yaml +350 -0
- package/locales/fr.yaml +350 -0
- package/locales/ga.yaml +354 -0
- package/locales/hu.yaml +350 -0
- package/locales/it.yaml +350 -0
- package/locales/ja.yaml +350 -0
- package/locales/ko.yaml +350 -0
- package/locales/pt.yaml +350 -0
- package/locales/ru.yaml +350 -0
- package/locales/tr.yaml +350 -0
- package/locales/uk.yaml +350 -0
- package/locales/zh-hant.yaml +350 -0
- package/locales/zh.yaml +350 -0
- package/mcp_serve.py +898 -0
- package/model_tools.py +899 -0
- package/optional-skills/DESCRIPTION.md +24 -0
- package/optional-skills/autonomous-ai-agents/DESCRIPTION.md +2 -0
- package/optional-skills/autonomous-ai-agents/blackbox/SKILL.md +144 -0
- package/optional-skills/autonomous-ai-agents/honcho/SKILL.md +431 -0
- package/optional-skills/blockchain/evm/SKILL.md +211 -0
- package/optional-skills/blockchain/evm/scripts/evm_client.py +1508 -0
- package/optional-skills/blockchain/hyperliquid/SKILL.md +211 -0
- package/optional-skills/blockchain/hyperliquid/scripts/hyperliquid_client.py +1660 -0
- package/optional-skills/blockchain/solana/SKILL.md +208 -0
- package/optional-skills/blockchain/solana/scripts/solana_client.py +698 -0
- package/optional-skills/communication/DESCRIPTION.md +1 -0
- package/optional-skills/communication/one-three-one-rule/SKILL.md +104 -0
- package/optional-skills/creative/blender-mcp/SKILL.md +117 -0
- package/optional-skills/creative/concept-diagrams/SKILL.md +362 -0
- package/optional-skills/creative/concept-diagrams/examples/apartment-floor-plan-conversion.md +244 -0
- package/optional-skills/creative/concept-diagrams/examples/automated-password-reset-flow.md +276 -0
- package/optional-skills/creative/concept-diagrams/examples/autonomous-llm-research-agent-flow.md +240 -0
- package/optional-skills/creative/concept-diagrams/examples/banana-journey-tree-to-smoothie.md +161 -0
- package/optional-skills/creative/concept-diagrams/examples/commercial-aircraft-structure.md +209 -0
- package/optional-skills/creative/concept-diagrams/examples/cpu-ooo-microarchitecture.md +236 -0
- package/optional-skills/creative/concept-diagrams/examples/electricity-grid-flow.md +182 -0
- package/optional-skills/creative/concept-diagrams/examples/feature-film-production-pipeline.md +172 -0
- package/optional-skills/creative/concept-diagrams/examples/hospital-emergency-department-flow.md +165 -0
- package/optional-skills/creative/concept-diagrams/examples/ml-benchmark-grouped-bar-chart.md +114 -0
- package/optional-skills/creative/concept-diagrams/examples/place-order-uml-sequence.md +325 -0
- package/optional-skills/creative/concept-diagrams/examples/smart-city-infrastructure.md +173 -0
- package/optional-skills/creative/concept-diagrams/examples/smartphone-layer-anatomy.md +154 -0
- package/optional-skills/creative/concept-diagrams/examples/sn2-reaction-mechanism.md +247 -0
- package/optional-skills/creative/concept-diagrams/examples/wind-turbine-structure.md +338 -0
- package/optional-skills/creative/concept-diagrams/references/dashboard-patterns.md +43 -0
- package/optional-skills/creative/concept-diagrams/references/infrastructure-patterns.md +144 -0
- package/optional-skills/creative/concept-diagrams/references/physical-shape-cookbook.md +42 -0
- package/optional-skills/creative/concept-diagrams/templates/template.html +174 -0
- package/optional-skills/creative/hyperframes/SKILL.md +191 -0
- package/optional-skills/creative/hyperframes/references/cli.md +185 -0
- package/optional-skills/creative/hyperframes/references/composition.md +129 -0
- package/optional-skills/creative/hyperframes/references/features.md +289 -0
- package/optional-skills/creative/hyperframes/references/gsap.md +136 -0
- package/optional-skills/creative/hyperframes/references/troubleshooting.md +137 -0
- package/optional-skills/creative/hyperframes/references/website-to-video.md +145 -0
- package/optional-skills/creative/hyperframes/scripts/setup.sh +135 -0
- package/optional-skills/creative/kanban-video-orchestrator/SKILL.md +207 -0
- package/optional-skills/creative/kanban-video-orchestrator/assets/brief.md.tmpl +79 -0
- package/optional-skills/creative/kanban-video-orchestrator/assets/setup.sh.tmpl +185 -0
- package/optional-skills/creative/kanban-video-orchestrator/assets/soul.md.tmpl +38 -0
- package/optional-skills/creative/kanban-video-orchestrator/references/examples.md +227 -0
- package/optional-skills/creative/kanban-video-orchestrator/references/intake.md +166 -0
- package/optional-skills/creative/kanban-video-orchestrator/references/kanban-setup.md +276 -0
- package/optional-skills/creative/kanban-video-orchestrator/references/monitoring.md +180 -0
- package/optional-skills/creative/kanban-video-orchestrator/references/role-archetypes.md +298 -0
- package/optional-skills/creative/kanban-video-orchestrator/references/tool-matrix.md +317 -0
- package/optional-skills/creative/kanban-video-orchestrator/scripts/bootstrap_pipeline.py +501 -0
- package/optional-skills/creative/kanban-video-orchestrator/scripts/monitor.py +195 -0
- package/optional-skills/creative/meme-generation/EXAMPLES.md +46 -0
- package/optional-skills/creative/meme-generation/SKILL.md +130 -0
- package/optional-skills/creative/meme-generation/scripts/generate_meme.py +471 -0
- package/optional-skills/creative/meme-generation/scripts/templates.json +97 -0
- package/optional-skills/devops/cli/SKILL.md +156 -0
- package/optional-skills/devops/cli/references/app-discovery.md +112 -0
- package/optional-skills/devops/cli/references/authentication.md +59 -0
- package/optional-skills/devops/cli/references/cli-reference.md +104 -0
- package/optional-skills/devops/cli/references/running-apps.md +171 -0
- package/optional-skills/devops/docker-management/SKILL.md +281 -0
- package/optional-skills/devops/pinggy-tunnel/SKILL.md +309 -0
- package/optional-skills/devops/watchers/SKILL.md +112 -0
- package/optional-skills/devops/watchers/scripts/_watermark.py +148 -0
- package/optional-skills/devops/watchers/scripts/watch_github.py +168 -0
- package/optional-skills/devops/watchers/scripts/watch_http_json.py +131 -0
- package/optional-skills/devops/watchers/scripts/watch_rss.py +121 -0
- package/optional-skills/dogfood/DESCRIPTION.md +3 -0
- package/optional-skills/dogfood/adversarial-ux-test/SKILL.md +191 -0
- package/optional-skills/email/agentmail/SKILL.md +126 -0
- package/optional-skills/finance/3-statement-model/SKILL.md +433 -0
- package/optional-skills/finance/3-statement-model/references/formatting.md +118 -0
- package/optional-skills/finance/3-statement-model/references/formulas.md +292 -0
- package/optional-skills/finance/3-statement-model/references/sec-filings.md +125 -0
- package/optional-skills/finance/comps-analysis/SKILL.md +662 -0
- package/optional-skills/finance/dcf-model/SKILL.md +1270 -0
- package/optional-skills/finance/dcf-model/TROUBLESHOOTING.md +40 -0
- package/optional-skills/finance/dcf-model/requirements.txt +7 -0
- package/optional-skills/finance/dcf-model/scripts/validate_dcf.py +292 -0
- package/optional-skills/finance/excel-author/SKILL.md +244 -0
- package/optional-skills/finance/excel-author/scripts/recalc.py +88 -0
- package/optional-skills/finance/lbo-model/SKILL.md +291 -0
- package/optional-skills/finance/merger-model/SKILL.md +144 -0
- package/optional-skills/finance/pptx-author/SKILL.md +173 -0
- package/optional-skills/finance/stocks/SKILL.md +95 -0
- package/optional-skills/finance/stocks/scripts/stocks_client.py +755 -0
- package/optional-skills/health/DESCRIPTION.md +1 -0
- package/optional-skills/health/fitness-nutrition/SKILL.md +256 -0
- package/optional-skills/health/fitness-nutrition/references/FORMULAS.md +100 -0
- package/optional-skills/health/fitness-nutrition/scripts/body_calc.py +210 -0
- package/optional-skills/health/fitness-nutrition/scripts/nutrition_search.py +86 -0
- package/optional-skills/health/neuroskill-bci/SKILL.md +459 -0
- package/optional-skills/health/neuroskill-bci/references/api.md +286 -0
- package/optional-skills/health/neuroskill-bci/references/metrics.md +220 -0
- package/optional-skills/health/neuroskill-bci/references/protocols.md +452 -0
- package/optional-skills/mcp/DESCRIPTION.md +3 -0
- package/optional-skills/mcp/fastmcp/SKILL.md +300 -0
- package/optional-skills/mcp/fastmcp/references/fastmcp-cli.md +110 -0
- package/optional-skills/mcp/fastmcp/scripts/scaffold_fastmcp.py +56 -0
- package/optional-skills/mcp/fastmcp/templates/api_wrapper.py +54 -0
- package/optional-skills/mcp/fastmcp/templates/database_server.py +77 -0
- package/optional-skills/mcp/fastmcp/templates/file_processor.py +55 -0
- package/optional-skills/mcp/mcporter/SKILL.md +123 -0
- package/optional-skills/migration/DESCRIPTION.md +2 -0
- package/optional-skills/migration/openclaw-migration/SKILL.md +298 -0
- package/optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py +3136 -0
- package/optional-skills/mlops/accelerate/SKILL.md +336 -0
- package/optional-skills/mlops/accelerate/references/custom-plugins.md +453 -0
- package/optional-skills/mlops/accelerate/references/megatron-integration.md +489 -0
- package/optional-skills/mlops/accelerate/references/performance.md +525 -0
- package/optional-skills/mlops/chroma/SKILL.md +410 -0
- package/optional-skills/mlops/chroma/references/integration.md +38 -0
- package/optional-skills/mlops/clip/SKILL.md +257 -0
- package/optional-skills/mlops/clip/references/applications.md +207 -0
- package/optional-skills/mlops/faiss/SKILL.md +225 -0
- package/optional-skills/mlops/faiss/references/index_types.md +280 -0
- package/optional-skills/mlops/flash-attention/SKILL.md +367 -0
- package/optional-skills/mlops/flash-attention/references/benchmarks.md +215 -0
- package/optional-skills/mlops/flash-attention/references/transformers-integration.md +293 -0
- package/optional-skills/mlops/guidance/SKILL.md +576 -0
- package/optional-skills/mlops/guidance/references/backends.md +554 -0
- package/optional-skills/mlops/guidance/references/constraints.md +674 -0
- package/optional-skills/mlops/guidance/references/examples.md +767 -0
- package/optional-skills/mlops/huggingface-tokenizers/SKILL.md +520 -0
- package/optional-skills/mlops/huggingface-tokenizers/references/algorithms.md +653 -0
- package/optional-skills/mlops/huggingface-tokenizers/references/integration.md +637 -0
- package/optional-skills/mlops/huggingface-tokenizers/references/pipeline.md +723 -0
- package/optional-skills/mlops/huggingface-tokenizers/references/training.md +565 -0
- package/optional-skills/mlops/inference/outlines/SKILL.md +656 -0
- package/optional-skills/mlops/inference/outlines/references/backends.md +615 -0
- package/optional-skills/mlops/inference/outlines/references/examples.md +773 -0
- package/optional-skills/mlops/inference/outlines/references/json_generation.md +652 -0
- package/optional-skills/mlops/instructor/SKILL.md +744 -0
- package/optional-skills/mlops/instructor/references/examples.md +107 -0
- package/optional-skills/mlops/instructor/references/providers.md +70 -0
- package/optional-skills/mlops/instructor/references/validation.md +606 -0
- package/optional-skills/mlops/lambda-labs/SKILL.md +549 -0
- package/optional-skills/mlops/lambda-labs/references/advanced-usage.md +611 -0
- package/optional-skills/mlops/lambda-labs/references/troubleshooting.md +530 -0
- package/optional-skills/mlops/llava/SKILL.md +308 -0
- package/optional-skills/mlops/llava/references/training.md +197 -0
- package/optional-skills/mlops/modal/SKILL.md +345 -0
- package/optional-skills/mlops/modal/references/advanced-usage.md +503 -0
- package/optional-skills/mlops/modal/references/troubleshooting.md +494 -0
- package/optional-skills/mlops/nemo-curator/SKILL.md +387 -0
- package/optional-skills/mlops/nemo-curator/references/deduplication.md +87 -0
- package/optional-skills/mlops/nemo-curator/references/filtering.md +102 -0
- package/optional-skills/mlops/peft/SKILL.md +435 -0
- package/optional-skills/mlops/peft/references/advanced-usage.md +514 -0
- package/optional-skills/mlops/peft/references/troubleshooting.md +480 -0
- package/optional-skills/mlops/pinecone/SKILL.md +362 -0
- package/optional-skills/mlops/pinecone/references/deployment.md +181 -0
- package/optional-skills/mlops/pytorch-fsdp/SKILL.md +130 -0
- package/optional-skills/mlops/pytorch-fsdp/references/index.md +7 -0
- package/optional-skills/mlops/pytorch-fsdp/references/other.md +4261 -0
- package/optional-skills/mlops/pytorch-lightning/SKILL.md +350 -0
- package/optional-skills/mlops/pytorch-lightning/references/callbacks.md +436 -0
- package/optional-skills/mlops/pytorch-lightning/references/distributed.md +490 -0
- package/optional-skills/mlops/pytorch-lightning/references/hyperparameter-tuning.md +556 -0
- package/optional-skills/mlops/qdrant/SKILL.md +497 -0
- package/optional-skills/mlops/qdrant/references/advanced-usage.md +648 -0
- package/optional-skills/mlops/qdrant/references/troubleshooting.md +631 -0
- package/optional-skills/mlops/saelens/SKILL.md +390 -0
- package/optional-skills/mlops/saelens/references/README.md +69 -0
- package/optional-skills/mlops/saelens/references/api.md +333 -0
- package/optional-skills/mlops/saelens/references/tutorials.md +318 -0
- package/optional-skills/mlops/simpo/SKILL.md +223 -0
- package/optional-skills/mlops/simpo/references/datasets.md +478 -0
- package/optional-skills/mlops/simpo/references/hyperparameters.md +452 -0
- package/optional-skills/mlops/simpo/references/loss-functions.md +350 -0
- package/optional-skills/mlops/slime/SKILL.md +468 -0
- package/optional-skills/mlops/slime/references/api-reference.md +392 -0
- package/optional-skills/mlops/slime/references/troubleshooting.md +386 -0
- package/optional-skills/mlops/stable-diffusion/SKILL.md +523 -0
- package/optional-skills/mlops/stable-diffusion/references/advanced-usage.md +716 -0
- package/optional-skills/mlops/stable-diffusion/references/troubleshooting.md +555 -0
- package/optional-skills/mlops/tensorrt-llm/SKILL.md +191 -0
- package/optional-skills/mlops/tensorrt-llm/references/multi-gpu.md +298 -0
- package/optional-skills/mlops/tensorrt-llm/references/optimization.md +242 -0
- package/optional-skills/mlops/tensorrt-llm/references/serving.md +470 -0
- package/optional-skills/mlops/torchtitan/SKILL.md +362 -0
- package/optional-skills/mlops/torchtitan/references/checkpoint.md +181 -0
- package/optional-skills/mlops/torchtitan/references/custom-models.md +258 -0
- package/optional-skills/mlops/torchtitan/references/float8.md +133 -0
- package/optional-skills/mlops/torchtitan/references/fsdp.md +126 -0
- package/optional-skills/mlops/training/axolotl/SKILL.md +166 -0
- package/optional-skills/mlops/training/axolotl/references/api.md +5548 -0
- package/optional-skills/mlops/training/axolotl/references/dataset-formats.md +1029 -0
- package/optional-skills/mlops/training/axolotl/references/index.md +15 -0
- package/optional-skills/mlops/training/axolotl/references/other.md +3563 -0
- package/optional-skills/mlops/training/trl-fine-tuning/SKILL.md +463 -0
- package/optional-skills/mlops/training/trl-fine-tuning/references/dpo-variants.md +227 -0
- package/optional-skills/mlops/training/trl-fine-tuning/references/grpo-training.md +504 -0
- package/optional-skills/mlops/training/trl-fine-tuning/references/online-rl.md +82 -0
- package/optional-skills/mlops/training/trl-fine-tuning/references/reward-modeling.md +122 -0
- package/optional-skills/mlops/training/trl-fine-tuning/references/sft-training.md +168 -0
- package/optional-skills/mlops/training/trl-fine-tuning/templates/basic_grpo_training.py +228 -0
- package/optional-skills/mlops/training/unsloth/SKILL.md +84 -0
- package/optional-skills/mlops/training/unsloth/references/index.md +7 -0
- package/optional-skills/mlops/training/unsloth/references/llms-full.md +16799 -0
- package/optional-skills/mlops/training/unsloth/references/llms-txt.md +12044 -0
- package/optional-skills/mlops/training/unsloth/references/llms.md +82 -0
- package/optional-skills/mlops/whisper/SKILL.md +321 -0
- package/optional-skills/mlops/whisper/references/languages.md +189 -0
- package/optional-skills/productivity/canvas/SKILL.md +98 -0
- package/optional-skills/productivity/canvas/scripts/canvas_api.py +157 -0
- package/optional-skills/productivity/here-now/SKILL.md +217 -0
- package/optional-skills/productivity/here-now/scripts/drive.sh +406 -0
- package/optional-skills/productivity/here-now/scripts/publish.sh +445 -0
- package/optional-skills/productivity/memento-flashcards/SKILL.md +324 -0
- package/optional-skills/productivity/memento-flashcards/scripts/memento_cards.py +353 -0
- package/optional-skills/productivity/memento-flashcards/scripts/youtube_quiz.py +88 -0
- package/optional-skills/productivity/shop-app/SKILL.md +340 -0
- package/optional-skills/productivity/shopify/SKILL.md +373 -0
- package/optional-skills/productivity/siyuan/SKILL.md +298 -0
- package/optional-skills/productivity/telephony/SKILL.md +418 -0
- package/optional-skills/productivity/telephony/scripts/telephony.py +1343 -0
- package/optional-skills/research/bioinformatics/SKILL.md +235 -0
- package/optional-skills/research/darwinian-evolver/SKILL.md +199 -0
- package/optional-skills/research/darwinian-evolver/scripts/parrot_openrouter.py +218 -0
- package/optional-skills/research/darwinian-evolver/scripts/show_snapshot.py +69 -0
- package/optional-skills/research/darwinian-evolver/templates/custom_problem_template.py +240 -0
- package/optional-skills/research/domain-intel/SKILL.md +97 -0
- package/optional-skills/research/domain-intel/scripts/domain_intel.py +397 -0
- package/optional-skills/research/drug-discovery/SKILL.md +227 -0
- package/optional-skills/research/drug-discovery/references/ADMET_REFERENCE.md +66 -0
- package/optional-skills/research/drug-discovery/scripts/chembl_target.py +53 -0
- package/optional-skills/research/drug-discovery/scripts/ro5_screen.py +44 -0
- package/optional-skills/research/duckduckgo-search/SKILL.md +238 -0
- package/optional-skills/research/duckduckgo-search/scripts/duckduckgo.sh +28 -0
- package/optional-skills/research/gitnexus-explorer/SKILL.md +214 -0
- package/optional-skills/research/gitnexus-explorer/scripts/proxy.mjs +92 -0
- package/optional-skills/research/osint-investigation/SKILL.md +277 -0
- package/optional-skills/research/osint-investigation/references/sources/courtlistener.md +98 -0
- package/optional-skills/research/osint-investigation/references/sources/gdelt.md +104 -0
- package/optional-skills/research/osint-investigation/references/sources/icij-offshore.md +104 -0
- package/optional-skills/research/osint-investigation/references/sources/nyc-acris.md +90 -0
- package/optional-skills/research/osint-investigation/references/sources/ofac-sdn.md +92 -0
- package/optional-skills/research/osint-investigation/references/sources/opencorporates.md +103 -0
- package/optional-skills/research/osint-investigation/references/sources/sec-edgar.md +83 -0
- package/optional-skills/research/osint-investigation/references/sources/senate-ld.md +89 -0
- package/optional-skills/research/osint-investigation/references/sources/usaspending.md +97 -0
- package/optional-skills/research/osint-investigation/references/sources/wayback.md +93 -0
- package/optional-skills/research/osint-investigation/references/sources/wikipedia.md +107 -0
- package/optional-skills/research/osint-investigation/scripts/_http.py +82 -0
- package/optional-skills/research/osint-investigation/scripts/_normalize.py +67 -0
- package/optional-skills/research/osint-investigation/scripts/build_findings.py +221 -0
- package/optional-skills/research/osint-investigation/scripts/entity_resolution.py +228 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_courtlistener.py +149 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_gdelt.py +162 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_icij_offshore.py +234 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_nyc_acris.py +203 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_ofac_sdn.py +175 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_opencorporates.py +192 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_sec_edgar.py +184 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_senate_ld.py +146 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_usaspending.py +170 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_wayback.py +142 -0
- package/optional-skills/research/osint-investigation/scripts/fetch_wikipedia.py +267 -0
- package/optional-skills/research/osint-investigation/scripts/timing_analysis.py +253 -0
- package/optional-skills/research/osint-investigation/templates/source-template.md +59 -0
- package/optional-skills/research/parallel-cli/SKILL.md +391 -0
- package/optional-skills/research/qmd/SKILL.md +441 -0
- package/optional-skills/research/scrapling/SKILL.md +336 -0
- package/optional-skills/research/searxng-search/SKILL.md +212 -0
- package/optional-skills/research/searxng-search/scripts/searxng.sh +22 -0
- package/optional-skills/security/1password/SKILL.md +163 -0
- package/optional-skills/security/1password/references/cli-examples.md +31 -0
- package/optional-skills/security/1password/references/get-started.md +21 -0
- package/optional-skills/security/DESCRIPTION.md +3 -0
- package/optional-skills/security/oss-forensics/SKILL.md +423 -0
- package/optional-skills/security/oss-forensics/references/evidence-types.md +89 -0
- package/optional-skills/security/oss-forensics/references/github-archive-guide.md +184 -0
- package/optional-skills/security/oss-forensics/references/investigation-templates.md +131 -0
- package/optional-skills/security/oss-forensics/references/recovery-techniques.md +164 -0
- package/optional-skills/security/oss-forensics/scripts/evidence-store.py +313 -0
- package/optional-skills/security/oss-forensics/templates/forensic-report.md +151 -0
- package/optional-skills/security/oss-forensics/templates/malicious-package-report.md +43 -0
- package/optional-skills/security/sherlock/SKILL.md +193 -0
- package/optional-skills/software-development/rest-graphql-debug/SKILL.md +514 -0
- package/optional-skills/web-development/DESCRIPTION.md +5 -0
- package/optional-skills/web-development/page-agent/SKILL.md +190 -0
- package/package.json +78 -0
- package/plugins/__init__.py +1 -0
- package/plugins/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/context_engine/__init__.py +219 -0
- package/plugins/disk-cleanup/README.md +51 -0
- package/plugins/disk-cleanup/__init__.py +316 -0
- package/plugins/disk-cleanup/disk_cleanup.py +497 -0
- package/plugins/disk-cleanup/plugin.yaml +7 -0
- package/plugins/example-dashboard/dashboard/manifest.json +14 -0
- package/plugins/example-dashboard/dashboard/plugin_api.py +17 -0
- package/plugins/google_meet/README.md +131 -0
- package/plugins/google_meet/SKILL.md +148 -0
- package/plugins/google_meet/__init__.py +103 -0
- package/plugins/google_meet/audio_bridge.py +244 -0
- package/plugins/google_meet/cli.py +479 -0
- package/plugins/google_meet/meet_bot.py +852 -0
- package/plugins/google_meet/node/__init__.py +54 -0
- package/plugins/google_meet/node/cli.py +125 -0
- package/plugins/google_meet/node/client.py +107 -0
- package/plugins/google_meet/node/protocol.py +124 -0
- package/plugins/google_meet/node/registry.py +113 -0
- package/plugins/google_meet/node/server.py +201 -0
- package/plugins/google_meet/plugin.yaml +16 -0
- package/plugins/google_meet/process_manager.py +324 -0
- package/plugins/google_meet/realtime/__init__.py +10 -0
- package/plugins/google_meet/realtime/openai_client.py +332 -0
- package/plugins/google_meet/tools.py +348 -0
- package/plugins/hermes-achievements/LICENSE +21 -0
- package/plugins/hermes-achievements/README.md +150 -0
- package/plugins/hermes-achievements/dashboard/dist/index.js +732 -0
- package/plugins/hermes-achievements/dashboard/dist/style.css +146 -0
- package/plugins/hermes-achievements/dashboard/manifest.json +11 -0
- package/plugins/hermes-achievements/dashboard/plugin_api.py +1062 -0
- package/plugins/hermes-achievements/docs/achievements-performance-implementation-plan.md +157 -0
- package/plugins/hermes-achievements/docs/achievements-performance-implementation-spec.md +219 -0
- package/plugins/hermes-achievements/docs/achievements-performance-spec.md +174 -0
- package/plugins/hermes-achievements/docs/assets/achievements-dashboard-hd.png +0 -0
- package/plugins/hermes-achievements/docs/assets/achievements-tier-showcase-hd.png +0 -0
- package/plugins/hermes-achievements/tests/test_achievement_engine.py +156 -0
- package/plugins/image_gen/openai/__init__.py +303 -0
- package/plugins/image_gen/openai/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/image_gen/openai/plugin.yaml +7 -0
- package/plugins/image_gen/openai-codex/__init__.py +378 -0
- package/plugins/image_gen/openai-codex/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/image_gen/openai-codex/plugin.yaml +5 -0
- package/plugins/image_gen/xai/__init__.py +316 -0
- package/plugins/image_gen/xai/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/image_gen/xai/plugin.yaml +7 -0
- package/plugins/kanban/dashboard/dist/index.js +3143 -0
- package/plugins/kanban/dashboard/dist/style.css +1500 -0
- package/plugins/kanban/dashboard/manifest.json +14 -0
- package/plugins/kanban/dashboard/plugin_api.py +1612 -0
- package/plugins/kanban/systemd/hermes-kanban-dispatcher.service +32 -0
- package/plugins/memory/__init__.py +408 -0
- package/plugins/memory/byterover/README.md +41 -0
- package/plugins/memory/byterover/__init__.py +384 -0
- package/plugins/memory/byterover/plugin.yaml +9 -0
- package/plugins/memory/hindsight/README.md +138 -0
- package/plugins/memory/hindsight/__init__.py +1758 -0
- package/plugins/memory/hindsight/plugin.yaml +8 -0
- package/plugins/memory/holographic/README.md +36 -0
- package/plugins/memory/holographic/__init__.py +409 -0
- package/plugins/memory/holographic/holographic.py +203 -0
- package/plugins/memory/holographic/plugin.yaml +5 -0
- package/plugins/memory/holographic/retrieval.py +593 -0
- package/plugins/memory/holographic/store.py +579 -0
- package/plugins/memory/honcho/README.md +328 -0
- package/plugins/memory/honcho/__init__.py +1329 -0
- package/plugins/memory/honcho/cli.py +1452 -0
- package/plugins/memory/honcho/client.py +784 -0
- package/plugins/memory/honcho/plugin.yaml +7 -0
- package/plugins/memory/honcho/session.py +1255 -0
- package/plugins/memory/mem0/README.md +38 -0
- package/plugins/memory/mem0/__init__.py +374 -0
- package/plugins/memory/mem0/plugin.yaml +5 -0
- package/plugins/memory/openviking/README.md +40 -0
- package/plugins/memory/openviking/__init__.py +945 -0
- package/plugins/memory/openviking/plugin.yaml +9 -0
- package/plugins/memory/retaindb/README.md +40 -0
- package/plugins/memory/retaindb/__init__.py +767 -0
- package/plugins/memory/retaindb/plugin.yaml +7 -0
- package/plugins/memory/supermemory/README.md +99 -0
- package/plugins/memory/supermemory/__init__.py +792 -0
- package/plugins/memory/supermemory/plugin.yaml +5 -0
- package/plugins/model-providers/README.md +70 -0
- package/plugins/model-providers/ai-gateway/__init__.py +43 -0
- package/plugins/model-providers/ai-gateway/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/ai-gateway/plugin.yaml +5 -0
- package/plugins/model-providers/alibaba/__init__.py +13 -0
- package/plugins/model-providers/alibaba/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/alibaba/plugin.yaml +5 -0
- package/plugins/model-providers/alibaba-coding-plan/__init__.py +21 -0
- package/plugins/model-providers/alibaba-coding-plan/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/alibaba-coding-plan/plugin.yaml +5 -0
- package/plugins/model-providers/anthropic/__init__.py +52 -0
- package/plugins/model-providers/anthropic/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/anthropic/plugin.yaml +5 -0
- package/plugins/model-providers/arcee/__init__.py +13 -0
- package/plugins/model-providers/arcee/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/arcee/plugin.yaml +5 -0
- package/plugins/model-providers/azure-foundry/__init__.py +21 -0
- package/plugins/model-providers/azure-foundry/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/azure-foundry/plugin.yaml +5 -0
- package/plugins/model-providers/bedrock/__init__.py +29 -0
- package/plugins/model-providers/bedrock/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/bedrock/plugin.yaml +5 -0
- package/plugins/model-providers/copilot/__init__.py +58 -0
- package/plugins/model-providers/copilot/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/copilot/plugin.yaml +5 -0
- package/plugins/model-providers/copilot-acp/__init__.py +34 -0
- package/plugins/model-providers/copilot-acp/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/copilot-acp/plugin.yaml +5 -0
- package/plugins/model-providers/custom/__init__.py +68 -0
- package/plugins/model-providers/custom/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/custom/plugin.yaml +5 -0
- package/plugins/model-providers/deepseek/__init__.py +99 -0
- package/plugins/model-providers/deepseek/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/deepseek/plugin.yaml +5 -0
- package/plugins/model-providers/gemini/__init__.py +72 -0
- package/plugins/model-providers/gemini/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/gemini/plugin.yaml +5 -0
- package/plugins/model-providers/gmi/__init__.py +31 -0
- package/plugins/model-providers/gmi/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/gmi/plugin.yaml +5 -0
- package/plugins/model-providers/huggingface/__init__.py +20 -0
- package/plugins/model-providers/huggingface/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/huggingface/plugin.yaml +5 -0
- package/plugins/model-providers/kilocode/__init__.py +14 -0
- package/plugins/model-providers/kilocode/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/kilocode/plugin.yaml +5 -0
- package/plugins/model-providers/kimi-coding/__init__.py +71 -0
- package/plugins/model-providers/kimi-coding/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/kimi-coding/plugin.yaml +5 -0
- package/plugins/model-providers/minimax/__init__.py +45 -0
- package/plugins/model-providers/minimax/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/minimax/plugin.yaml +5 -0
- package/plugins/model-providers/nous/__init__.py +54 -0
- package/plugins/model-providers/nous/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/nous/plugin.yaml +5 -0
- package/plugins/model-providers/novita/__init__.py +27 -0
- package/plugins/model-providers/novita/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/novita/plugin.yaml +5 -0
- package/plugins/model-providers/nvidia/__init__.py +21 -0
- package/plugins/model-providers/nvidia/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/nvidia/plugin.yaml +5 -0
- package/plugins/model-providers/ollama-cloud/__init__.py +14 -0
- package/plugins/model-providers/ollama-cloud/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/ollama-cloud/plugin.yaml +5 -0
- package/plugins/model-providers/openai-codex/__init__.py +15 -0
- package/plugins/model-providers/openai-codex/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/openai-codex/plugin.yaml +5 -0
- package/plugins/model-providers/opencode-zen/__init__.py +30 -0
- package/plugins/model-providers/opencode-zen/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/opencode-zen/plugin.yaml +5 -0
- package/plugins/model-providers/openrouter/__init__.py +115 -0
- package/plugins/model-providers/openrouter/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/openrouter/plugin.yaml +5 -0
- package/plugins/model-providers/qwen-oauth/__init__.py +82 -0
- package/plugins/model-providers/qwen-oauth/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/qwen-oauth/plugin.yaml +5 -0
- package/plugins/model-providers/stepfun/__init__.py +14 -0
- package/plugins/model-providers/stepfun/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/stepfun/plugin.yaml +5 -0
- package/plugins/model-providers/xai/__init__.py +15 -0
- package/plugins/model-providers/xai/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/xai/plugin.yaml +5 -0
- package/plugins/model-providers/xiaomi/__init__.py +14 -0
- package/plugins/model-providers/xiaomi/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/xiaomi/plugin.yaml +5 -0
- package/plugins/model-providers/zai/__init__.py +21 -0
- package/plugins/model-providers/zai/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/model-providers/zai/plugin.yaml +5 -0
- package/plugins/observability/langfuse/README.md +53 -0
- package/plugins/observability/langfuse/__init__.py +1004 -0
- package/plugins/observability/langfuse/plugin.yaml +14 -0
- package/plugins/platforms/google_chat/__init__.py +3 -0
- package/plugins/platforms/google_chat/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/platforms/google_chat/__pycache__/adapter.cpython-312.pyc +0 -0
- package/plugins/platforms/google_chat/adapter.py +3343 -0
- package/plugins/platforms/google_chat/oauth.py +639 -0
- package/plugins/platforms/google_chat/plugin.yaml +39 -0
- package/plugins/platforms/irc/__init__.py +3 -0
- package/plugins/platforms/irc/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/platforms/irc/__pycache__/adapter.cpython-312.pyc +0 -0
- package/plugins/platforms/irc/adapter.py +969 -0
- package/plugins/platforms/irc/plugin.yaml +54 -0
- package/plugins/platforms/line/__init__.py +3 -0
- package/plugins/platforms/line/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/platforms/line/__pycache__/adapter.cpython-312.pyc +0 -0
- package/plugins/platforms/line/adapter.py +1639 -0
- package/plugins/platforms/line/plugin.yaml +65 -0
- package/plugins/platforms/simplex/__init__.py +3 -0
- package/plugins/platforms/simplex/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/platforms/simplex/__pycache__/adapter.cpython-312.pyc +0 -0
- package/plugins/platforms/simplex/adapter.py +746 -0
- package/plugins/platforms/simplex/plugin.yaml +37 -0
- package/plugins/platforms/teams/__init__.py +3 -0
- package/plugins/platforms/teams/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/platforms/teams/__pycache__/adapter.cpython-312.pyc +0 -0
- package/plugins/platforms/teams/adapter.py +1188 -0
- package/plugins/platforms/teams/plugin.yaml +48 -0
- package/plugins/spotify/__init__.py +66 -0
- package/plugins/spotify/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/spotify/__pycache__/client.cpython-312.pyc +0 -0
- package/plugins/spotify/__pycache__/tools.cpython-312.pyc +0 -0
- package/plugins/spotify/client.py +435 -0
- package/plugins/spotify/plugin.yaml +13 -0
- package/plugins/spotify/tools.py +454 -0
- package/plugins/teams_pipeline/__init__.py +23 -0
- package/plugins/teams_pipeline/cli.py +463 -0
- package/plugins/teams_pipeline/meetings.py +333 -0
- package/plugins/teams_pipeline/models.py +350 -0
- package/plugins/teams_pipeline/pipeline.py +692 -0
- package/plugins/teams_pipeline/plugin.yaml +9 -0
- package/plugins/teams_pipeline/runtime.py +135 -0
- package/plugins/teams_pipeline/store.py +194 -0
- package/plugins/teams_pipeline/subscriptions.py +249 -0
- package/plugins/video_gen/fal/__init__.py +523 -0
- package/plugins/video_gen/fal/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/video_gen/fal/plugin.yaml +7 -0
- package/plugins/video_gen/xai/__init__.py +441 -0
- package/plugins/video_gen/xai/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/video_gen/xai/plugin.yaml +7 -0
- package/plugins/web/__init__.py +7 -0
- package/plugins/web/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/web/brave_free/__init__.py +14 -0
- package/plugins/web/brave_free/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/web/brave_free/__pycache__/provider.cpython-312.pyc +0 -0
- package/plugins/web/brave_free/plugin.yaml +7 -0
- package/plugins/web/brave_free/provider.py +137 -0
- package/plugins/web/ddgs/__init__.py +15 -0
- package/plugins/web/ddgs/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/web/ddgs/__pycache__/provider.cpython-312.pyc +0 -0
- package/plugins/web/ddgs/plugin.yaml +7 -0
- package/plugins/web/ddgs/provider.py +104 -0
- package/plugins/web/exa/__init__.py +15 -0
- package/plugins/web/exa/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/web/exa/__pycache__/provider.cpython-312.pyc +0 -0
- package/plugins/web/exa/plugin.yaml +7 -0
- package/plugins/web/exa/provider.py +212 -0
- package/plugins/web/firecrawl/__init__.py +28 -0
- package/plugins/web/firecrawl/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/web/firecrawl/__pycache__/provider.cpython-312.pyc +0 -0
- package/plugins/web/firecrawl/plugin.yaml +7 -0
- package/plugins/web/firecrawl/provider.py +773 -0
- package/plugins/web/parallel/__init__.py +16 -0
- package/plugins/web/parallel/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/web/parallel/__pycache__/provider.cpython-312.pyc +0 -0
- package/plugins/web/parallel/plugin.yaml +7 -0
- package/plugins/web/parallel/provider.py +291 -0
- package/plugins/web/searxng/__init__.py +15 -0
- package/plugins/web/searxng/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/web/searxng/__pycache__/provider.cpython-312.pyc +0 -0
- package/plugins/web/searxng/plugin.yaml +7 -0
- package/plugins/web/searxng/provider.py +140 -0
- package/plugins/web/tavily/__init__.py +15 -0
- package/plugins/web/tavily/__pycache__/__init__.cpython-312.pyc +0 -0
- package/plugins/web/tavily/__pycache__/provider.cpython-312.pyc +0 -0
- package/plugins/web/tavily/plugin.yaml +7 -0
- package/plugins/web/tavily/provider.py +285 -0
- package/providers/README.md +78 -0
- package/providers/__init__.py +192 -0
- package/providers/__pycache__/__init__.cpython-312.pyc +0 -0
- package/providers/__pycache__/base.cpython-312.pyc +0 -0
- package/providers/base.py +184 -0
- package/pyproject.toml +255 -0
- package/run_agent.py +16409 -0
- package/scripts/benchmark_browser_eval.py +138 -0
- package/scripts/build_model_catalog.py +95 -0
- package/scripts/build_skills_index.py +325 -0
- package/scripts/check-windows-footguns.py +624 -0
- package/scripts/contributor_audit.py +473 -0
- package/scripts/discord-voice-doctor.py +396 -0
- package/scripts/hermes-gateway +416 -0
- package/scripts/install.cmd +28 -0
- package/scripts/install.ps1 +1611 -0
- package/scripts/install.sh +2007 -0
- package/scripts/install_psutil_android.py +117 -0
- package/scripts/keystroke_diagnostic.py +81 -0
- package/scripts/kill_modal.sh +34 -0
- package/scripts/lib/node-bootstrap.sh +238 -0
- package/scripts/lint_diff.py +207 -0
- package/scripts/postinstall.js +150 -0
- package/scripts/profile-tui.py +626 -0
- package/scripts/release.py +1680 -0
- package/scripts/run_tests.sh +129 -0
- package/scripts/sample_and_compress.py +409 -0
- package/scripts/setup_open_webui.sh +349 -0
- package/scripts/whatsapp-bridge/allowlist.js +88 -0
- package/scripts/whatsapp-bridge/allowlist.test.mjs +80 -0
- package/scripts/whatsapp-bridge/bridge.js +729 -0
- package/scripts/whatsapp-bridge/package-lock.json +2141 -0
- package/scripts/whatsapp-bridge/package.json +19 -0
- package/skills/apple/DESCRIPTION.md +2 -0
- package/skills/apple/apple-notes/SKILL.md +90 -0
- package/skills/apple/apple-reminders/SKILL.md +98 -0
- package/skills/apple/findmy/SKILL.md +131 -0
- package/skills/apple/imessage/SKILL.md +102 -0
- package/skills/apple/macos-computer-use/SKILL.md +201 -0
- package/skills/autonomous-ai-agents/DESCRIPTION.md +3 -0
- package/skills/autonomous-ai-agents/claude-code/SKILL.md +745 -0
- package/skills/autonomous-ai-agents/codex/SKILL.md +130 -0
- package/skills/autonomous-ai-agents/hermes-agent/SKILL.md +1014 -0
- package/skills/autonomous-ai-agents/opencode/SKILL.md +219 -0
- package/skills/creative/DESCRIPTION.md +3 -0
- package/skills/creative/architecture-diagram/SKILL.md +148 -0
- package/skills/creative/architecture-diagram/templates/template.html +319 -0
- package/skills/creative/ascii-art/SKILL.md +322 -0
- package/skills/creative/ascii-video/README.md +290 -0
- package/skills/creative/ascii-video/SKILL.md +241 -0
- package/skills/creative/ascii-video/references/architecture.md +802 -0
- package/skills/creative/ascii-video/references/composition.md +892 -0
- package/skills/creative/ascii-video/references/effects.md +1865 -0
- package/skills/creative/ascii-video/references/inputs.md +685 -0
- package/skills/creative/ascii-video/references/optimization.md +688 -0
- package/skills/creative/ascii-video/references/scenes.md +1011 -0
- package/skills/creative/ascii-video/references/shaders.md +1385 -0
- package/skills/creative/ascii-video/references/troubleshooting.md +367 -0
- package/skills/creative/baoyu-comic/PORT_NOTES.md +77 -0
- package/skills/creative/baoyu-comic/SKILL.md +247 -0
- package/skills/creative/baoyu-comic/references/analysis-framework.md +176 -0
- package/skills/creative/baoyu-comic/references/art-styles/chalk.md +101 -0
- package/skills/creative/baoyu-comic/references/art-styles/ink-brush.md +97 -0
- package/skills/creative/baoyu-comic/references/art-styles/ligne-claire.md +75 -0
- package/skills/creative/baoyu-comic/references/art-styles/manga.md +93 -0
- package/skills/creative/baoyu-comic/references/art-styles/minimalist.md +84 -0
- package/skills/creative/baoyu-comic/references/art-styles/realistic.md +89 -0
- package/skills/creative/baoyu-comic/references/auto-selection.md +71 -0
- package/skills/creative/baoyu-comic/references/base-prompt.md +98 -0
- package/skills/creative/baoyu-comic/references/character-template.md +180 -0
- package/skills/creative/baoyu-comic/references/layouts/cinematic.md +23 -0
- package/skills/creative/baoyu-comic/references/layouts/dense.md +23 -0
- package/skills/creative/baoyu-comic/references/layouts/four-panel.md +40 -0
- package/skills/creative/baoyu-comic/references/layouts/mixed.md +23 -0
- package/skills/creative/baoyu-comic/references/layouts/splash.md +23 -0
- package/skills/creative/baoyu-comic/references/layouts/standard.md +23 -0
- package/skills/creative/baoyu-comic/references/layouts/webtoon.md +30 -0
- package/skills/creative/baoyu-comic/references/ohmsha-guide.md +85 -0
- package/skills/creative/baoyu-comic/references/partial-workflows.md +106 -0
- package/skills/creative/baoyu-comic/references/presets/concept-story.md +121 -0
- package/skills/creative/baoyu-comic/references/presets/four-panel.md +107 -0
- package/skills/creative/baoyu-comic/references/presets/ohmsha.md +114 -0
- package/skills/creative/baoyu-comic/references/presets/shoujo.md +116 -0
- package/skills/creative/baoyu-comic/references/presets/wuxia.md +110 -0
- package/skills/creative/baoyu-comic/references/storyboard-template.md +143 -0
- package/skills/creative/baoyu-comic/references/tones/action.md +110 -0
- package/skills/creative/baoyu-comic/references/tones/dramatic.md +95 -0
- package/skills/creative/baoyu-comic/references/tones/energetic.md +105 -0
- package/skills/creative/baoyu-comic/references/tones/neutral.md +63 -0
- package/skills/creative/baoyu-comic/references/tones/romantic.md +100 -0
- package/skills/creative/baoyu-comic/references/tones/vintage.md +104 -0
- package/skills/creative/baoyu-comic/references/tones/warm.md +94 -0
- package/skills/creative/baoyu-comic/references/workflow.md +401 -0
- package/skills/creative/baoyu-infographic/PORT_NOTES.md +43 -0
- package/skills/creative/baoyu-infographic/SKILL.md +237 -0
- package/skills/creative/baoyu-infographic/references/analysis-framework.md +182 -0
- package/skills/creative/baoyu-infographic/references/base-prompt.md +43 -0
- package/skills/creative/baoyu-infographic/references/layouts/bento-grid.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/binary-comparison.md +48 -0
- package/skills/creative/baoyu-infographic/references/layouts/bridge.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/circular-flow.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/comic-strip.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/comparison-matrix.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/dashboard.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/dense-modules.md +72 -0
- package/skills/creative/baoyu-infographic/references/layouts/funnel.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/hierarchical-layers.md +48 -0
- package/skills/creative/baoyu-infographic/references/layouts/hub-spoke.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/iceberg.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/isometric-map.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/jigsaw.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/linear-progression.md +48 -0
- package/skills/creative/baoyu-infographic/references/layouts/periodic-table.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/story-mountain.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/structural-breakdown.md +48 -0
- package/skills/creative/baoyu-infographic/references/layouts/tree-branching.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/venn-diagram.md +41 -0
- package/skills/creative/baoyu-infographic/references/layouts/winding-roadmap.md +41 -0
- package/skills/creative/baoyu-infographic/references/structured-content-template.md +244 -0
- package/skills/creative/baoyu-infographic/references/styles/aged-academia.md +36 -0
- package/skills/creative/baoyu-infographic/references/styles/bold-graphic.md +36 -0
- package/skills/creative/baoyu-infographic/references/styles/chalkboard.md +61 -0
- package/skills/creative/baoyu-infographic/references/styles/claymation.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/corporate-memphis.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/craft-handmade.md +44 -0
- package/skills/creative/baoyu-infographic/references/styles/cyberpunk-neon.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/hand-drawn-edu.md +63 -0
- package/skills/creative/baoyu-infographic/references/styles/ikea-manual.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/kawaii.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/knolling.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/lego-brick.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/morandi-journal.md +60 -0
- package/skills/creative/baoyu-infographic/references/styles/origami.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/pixel-art.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/pop-laboratory.md +48 -0
- package/skills/creative/baoyu-infographic/references/styles/retro-pop-grid.md +47 -0
- package/skills/creative/baoyu-infographic/references/styles/storybook-watercolor.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/subway-map.md +29 -0
- package/skills/creative/baoyu-infographic/references/styles/technical-schematic.md +36 -0
- package/skills/creative/baoyu-infographic/references/styles/ui-wireframe.md +29 -0
- package/skills/creative/claude-design/SKILL.md +591 -0
- package/skills/creative/comfyui/SKILL.md +612 -0
- package/skills/creative/comfyui/references/official-cli.md +255 -0
- package/skills/creative/comfyui/references/rest-api.md +312 -0
- package/skills/creative/comfyui/references/template-integrity.md +243 -0
- package/skills/creative/comfyui/references/workflow-format.md +226 -0
- package/skills/creative/comfyui/scripts/_common.py +835 -0
- package/skills/creative/comfyui/scripts/auto_fix_deps.py +225 -0
- package/skills/creative/comfyui/scripts/check_deps.py +437 -0
- package/skills/creative/comfyui/scripts/comfyui_setup.sh +286 -0
- package/skills/creative/comfyui/scripts/extract_schema.py +315 -0
- package/skills/creative/comfyui/scripts/fetch_logs.py +158 -0
- package/skills/creative/comfyui/scripts/hardware_check.py +497 -0
- package/skills/creative/comfyui/scripts/health_check.py +223 -0
- package/skills/creative/comfyui/scripts/run_batch.py +243 -0
- package/skills/creative/comfyui/scripts/run_workflow.py +796 -0
- package/skills/creative/comfyui/scripts/ws_monitor.py +267 -0
- package/skills/creative/comfyui/tests/README.md +50 -0
- package/skills/creative/comfyui/tests/conftest.py +64 -0
- package/skills/creative/comfyui/tests/pytest.ini +5 -0
- package/skills/creative/comfyui/tests/test_check_deps.py +68 -0
- package/skills/creative/comfyui/tests/test_cloud_integration.py +95 -0
- package/skills/creative/comfyui/tests/test_common.py +447 -0
- package/skills/creative/comfyui/tests/test_extract_schema.py +185 -0
- package/skills/creative/comfyui/tests/test_run_workflow.py +213 -0
- package/skills/creative/comfyui/workflows/README.md +86 -0
- package/skills/creative/comfyui/workflows/animatediff_video.json +64 -0
- package/skills/creative/comfyui/workflows/flux_dev_txt2img.json +78 -0
- package/skills/creative/comfyui/workflows/sd15_txt2img.json +49 -0
- package/skills/creative/comfyui/workflows/sdxl_img2img.json +54 -0
- package/skills/creative/comfyui/workflows/sdxl_inpaint.json +59 -0
- package/skills/creative/comfyui/workflows/sdxl_txt2img.json +49 -0
- package/skills/creative/comfyui/workflows/upscale_4x.json +27 -0
- package/skills/creative/comfyui/workflows/wan_video_t2v.json +69 -0
- package/skills/creative/creative-ideation/SKILL.md +152 -0
- package/skills/creative/creative-ideation/references/full-prompt-library.md +110 -0
- package/skills/creative/design-md/SKILL.md +199 -0
- package/skills/creative/design-md/templates/starter.md +99 -0
- package/skills/creative/excalidraw/SKILL.md +199 -0
- package/skills/creative/excalidraw/references/colors.md +44 -0
- package/skills/creative/excalidraw/references/dark-mode.md +68 -0
- package/skills/creative/excalidraw/references/examples.md +141 -0
- package/skills/creative/excalidraw/scripts/upload.py +133 -0
- package/skills/creative/humanizer/LICENSE +21 -0
- package/skills/creative/humanizer/SKILL.md +578 -0
- package/skills/creative/manim-video/README.md +23 -0
- package/skills/creative/manim-video/SKILL.md +269 -0
- package/skills/creative/manim-video/references/animation-design-thinking.md +161 -0
- package/skills/creative/manim-video/references/animations.md +282 -0
- package/skills/creative/manim-video/references/camera-and-3d.md +135 -0
- package/skills/creative/manim-video/references/decorations.md +202 -0
- package/skills/creative/manim-video/references/equations.md +216 -0
- package/skills/creative/manim-video/references/graphs-and-data.md +163 -0
- package/skills/creative/manim-video/references/mobjects.md +333 -0
- package/skills/creative/manim-video/references/paper-explainer.md +255 -0
- package/skills/creative/manim-video/references/production-quality.md +190 -0
- package/skills/creative/manim-video/references/rendering.md +185 -0
- package/skills/creative/manim-video/references/scene-planning.md +118 -0
- package/skills/creative/manim-video/references/troubleshooting.md +135 -0
- package/skills/creative/manim-video/references/updaters-and-trackers.md +260 -0
- package/skills/creative/manim-video/references/visual-design.md +124 -0
- package/skills/creative/manim-video/scripts/setup.sh +14 -0
- package/skills/creative/p5js/README.md +64 -0
- package/skills/creative/p5js/SKILL.md +556 -0
- package/skills/creative/p5js/references/animation.md +439 -0
- package/skills/creative/p5js/references/color-systems.md +352 -0
- package/skills/creative/p5js/references/core-api.md +410 -0
- package/skills/creative/p5js/references/export-pipeline.md +566 -0
- package/skills/creative/p5js/references/interaction.md +398 -0
- package/skills/creative/p5js/references/shapes-and-geometry.md +300 -0
- package/skills/creative/p5js/references/troubleshooting.md +532 -0
- package/skills/creative/p5js/references/typography.md +302 -0
- package/skills/creative/p5js/references/visual-effects.md +895 -0
- package/skills/creative/p5js/references/webgl-and-3d.md +423 -0
- package/skills/creative/p5js/scripts/export-frames.js +179 -0
- package/skills/creative/p5js/scripts/render.sh +108 -0
- package/skills/creative/p5js/scripts/serve.sh +28 -0
- package/skills/creative/p5js/scripts/setup.sh +87 -0
- package/skills/creative/p5js/templates/viewer.html +395 -0
- package/skills/creative/pixel-art/ATTRIBUTION.md +54 -0
- package/skills/creative/pixel-art/SKILL.md +218 -0
- package/skills/creative/pixel-art/references/palettes.md +49 -0
- package/skills/creative/pixel-art/scripts/__init__.py +0 -0
- package/skills/creative/pixel-art/scripts/palettes.py +167 -0
- package/skills/creative/pixel-art/scripts/pixel_art.py +162 -0
- package/skills/creative/pixel-art/scripts/pixel_art_video.py +345 -0
- package/skills/creative/popular-web-designs/SKILL.md +214 -0
- package/skills/creative/popular-web-designs/templates/airbnb.md +259 -0
- package/skills/creative/popular-web-designs/templates/airtable.md +102 -0
- package/skills/creative/popular-web-designs/templates/apple.md +326 -0
- package/skills/creative/popular-web-designs/templates/bmw.md +193 -0
- package/skills/creative/popular-web-designs/templates/cal.md +272 -0
- package/skills/creative/popular-web-designs/templates/claude.md +325 -0
- package/skills/creative/popular-web-designs/templates/clay.md +317 -0
- package/skills/creative/popular-web-designs/templates/clickhouse.md +294 -0
- package/skills/creative/popular-web-designs/templates/cohere.md +279 -0
- package/skills/creative/popular-web-designs/templates/coinbase.md +142 -0
- package/skills/creative/popular-web-designs/templates/composio.md +320 -0
- package/skills/creative/popular-web-designs/templates/cursor.md +322 -0
- package/skills/creative/popular-web-designs/templates/elevenlabs.md +278 -0
- package/skills/creative/popular-web-designs/templates/expo.md +294 -0
- package/skills/creative/popular-web-designs/templates/figma.md +233 -0
- package/skills/creative/popular-web-designs/templates/framer.md +259 -0
- package/skills/creative/popular-web-designs/templates/hashicorp.md +291 -0
- package/skills/creative/popular-web-designs/templates/ibm.md +345 -0
- package/skills/creative/popular-web-designs/templates/intercom.md +159 -0
- package/skills/creative/popular-web-designs/templates/kraken.md +138 -0
- package/skills/creative/popular-web-designs/templates/linear.app.md +380 -0
- package/skills/creative/popular-web-designs/templates/lovable.md +311 -0
- package/skills/creative/popular-web-designs/templates/minimax.md +270 -0
- package/skills/creative/popular-web-designs/templates/mintlify.md +339 -0
- package/skills/creative/popular-web-designs/templates/miro.md +121 -0
- package/skills/creative/popular-web-designs/templates/mistral.ai.md +274 -0
- package/skills/creative/popular-web-designs/templates/mongodb.md +279 -0
- package/skills/creative/popular-web-designs/templates/notion.md +322 -0
- package/skills/creative/popular-web-designs/templates/nvidia.md +306 -0
- package/skills/creative/popular-web-designs/templates/ollama.md +280 -0
- package/skills/creative/popular-web-designs/templates/opencode.ai.md +294 -0
- package/skills/creative/popular-web-designs/templates/pinterest.md +243 -0
- package/skills/creative/popular-web-designs/templates/posthog.md +269 -0
- package/skills/creative/popular-web-designs/templates/raycast.md +281 -0
- package/skills/creative/popular-web-designs/templates/replicate.md +274 -0
- package/skills/creative/popular-web-designs/templates/resend.md +316 -0
- package/skills/creative/popular-web-designs/templates/revolut.md +198 -0
- package/skills/creative/popular-web-designs/templates/runwayml.md +257 -0
- package/skills/creative/popular-web-designs/templates/sanity.md +370 -0
- package/skills/creative/popular-web-designs/templates/sentry.md +275 -0
- package/skills/creative/popular-web-designs/templates/spacex.md +207 -0
- package/skills/creative/popular-web-designs/templates/spotify.md +259 -0
- package/skills/creative/popular-web-designs/templates/stripe.md +335 -0
- package/skills/creative/popular-web-designs/templates/supabase.md +268 -0
- package/skills/creative/popular-web-designs/templates/superhuman.md +265 -0
- package/skills/creative/popular-web-designs/templates/together.ai.md +276 -0
- package/skills/creative/popular-web-designs/templates/uber.md +308 -0
- package/skills/creative/popular-web-designs/templates/vercel.md +323 -0
- package/skills/creative/popular-web-designs/templates/voltagent.md +336 -0
- package/skills/creative/popular-web-designs/templates/warp.md +266 -0
- package/skills/creative/popular-web-designs/templates/webflow.md +105 -0
- package/skills/creative/popular-web-designs/templates/wise.md +186 -0
- package/skills/creative/popular-web-designs/templates/x.ai.md +270 -0
- package/skills/creative/popular-web-designs/templates/zapier.md +341 -0
- package/skills/creative/pretext/SKILL.md +220 -0
- package/skills/creative/pretext/references/patterns.md +258 -0
- package/skills/creative/pretext/templates/donut-orbit.html +1468 -0
- package/skills/creative/pretext/templates/hello-orb-flow.html +95 -0
- package/skills/creative/sketch/SKILL.md +218 -0
- package/skills/creative/songwriting-and-ai-music/SKILL.md +287 -0
- package/skills/creative/touchdesigner-mcp/SKILL.md +356 -0
- package/skills/creative/touchdesigner-mcp/references/3d-scene.md +275 -0
- package/skills/creative/touchdesigner-mcp/references/animation.md +221 -0
- package/skills/creative/touchdesigner-mcp/references/audio-reactive.md +175 -0
- package/skills/creative/touchdesigner-mcp/references/dat-scripting.md +352 -0
- package/skills/creative/touchdesigner-mcp/references/external-data.md +322 -0
- package/skills/creative/touchdesigner-mcp/references/geometry-comp.md +121 -0
- package/skills/creative/touchdesigner-mcp/references/glsl.md +151 -0
- package/skills/creative/touchdesigner-mcp/references/layout-compositor.md +131 -0
- package/skills/creative/touchdesigner-mcp/references/mcp-tools.md +382 -0
- package/skills/creative/touchdesigner-mcp/references/midi-osc.md +211 -0
- package/skills/creative/touchdesigner-mcp/references/network-patterns.md +966 -0
- package/skills/creative/touchdesigner-mcp/references/operator-tips.md +106 -0
- package/skills/creative/touchdesigner-mcp/references/operators.md +239 -0
- package/skills/creative/touchdesigner-mcp/references/panel-ui.md +281 -0
- package/skills/creative/touchdesigner-mcp/references/particles.md +245 -0
- package/skills/creative/touchdesigner-mcp/references/pitfalls.md +704 -0
- package/skills/creative/touchdesigner-mcp/references/postfx.md +183 -0
- package/skills/creative/touchdesigner-mcp/references/projection-mapping.md +211 -0
- package/skills/creative/touchdesigner-mcp/references/python-api.md +463 -0
- package/skills/creative/touchdesigner-mcp/references/replicator.md +198 -0
- package/skills/creative/touchdesigner-mcp/references/troubleshooting.md +244 -0
- package/skills/creative/touchdesigner-mcp/scripts/setup.sh +115 -0
- package/skills/data-science/DESCRIPTION.md +3 -0
- package/skills/data-science/jupyter-live-kernel/SKILL.md +167 -0
- package/skills/devops/kanban-orchestrator/SKILL.md +189 -0
- package/skills/devops/kanban-worker/SKILL.md +184 -0
- package/skills/devops/webhook-subscriptions/SKILL.md +204 -0
- package/skills/diagramming/DESCRIPTION.md +3 -0
- package/skills/dogfood/SKILL.md +162 -0
- package/skills/dogfood/references/issue-taxonomy.md +109 -0
- package/skills/dogfood/templates/dogfood-report-template.md +86 -0
- package/skills/domain/DESCRIPTION.md +24 -0
- package/skills/email/DESCRIPTION.md +3 -0
- package/skills/email/himalaya/SKILL.md +299 -0
- package/skills/email/himalaya/references/configuration.md +227 -0
- package/skills/email/himalaya/references/message-composition.md +199 -0
- package/skills/gaming/DESCRIPTION.md +3 -0
- package/skills/gaming/minecraft-modpack-server/SKILL.md +187 -0
- package/skills/gaming/pokemon-player/SKILL.md +216 -0
- package/skills/gifs/DESCRIPTION.md +3 -0
- package/skills/github/DESCRIPTION.md +3 -0
- package/skills/github/codebase-inspection/SKILL.md +116 -0
- package/skills/github/github-auth/SKILL.md +247 -0
- package/skills/github/github-auth/scripts/gh-env.sh +66 -0
- package/skills/github/github-code-review/SKILL.md +481 -0
- package/skills/github/github-code-review/references/review-output-template.md +74 -0
- package/skills/github/github-issues/SKILL.md +370 -0
- package/skills/github/github-issues/templates/bug-report.md +35 -0
- package/skills/github/github-issues/templates/feature-request.md +31 -0
- package/skills/github/github-pr-workflow/SKILL.md +367 -0
- package/skills/github/github-pr-workflow/references/ci-troubleshooting.md +183 -0
- package/skills/github/github-pr-workflow/references/conventional-commits.md +71 -0
- package/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +35 -0
- package/skills/github/github-pr-workflow/templates/pr-body-feature.md +33 -0
- package/skills/github/github-repo-management/SKILL.md +516 -0
- package/skills/github/github-repo-management/references/github-api-cheatsheet.md +161 -0
- package/skills/index-cache/anthropics_skills_skills_.json +1 -0
- package/skills/index-cache/claude_marketplace_anthropics_skills.json +1 -0
- package/skills/index-cache/lobehub_index.json +1 -0
- package/skills/index-cache/openai_skills_skills_.json +1 -0
- package/skills/inference-sh/DESCRIPTION.md +19 -0
- package/skills/mcp/DESCRIPTION.md +3 -0
- package/skills/mcp/native-mcp/SKILL.md +357 -0
- package/skills/media/DESCRIPTION.md +3 -0
- package/skills/media/gif-search/SKILL.md +91 -0
- package/skills/media/heartmula/SKILL.md +171 -0
- package/skills/media/songsee/SKILL.md +83 -0
- package/skills/media/spotify/SKILL.md +135 -0
- package/skills/media/youtube-content/SKILL.md +73 -0
- package/skills/media/youtube-content/references/output-formats.md +56 -0
- package/skills/media/youtube-content/scripts/fetch_transcript.py +124 -0
- package/skills/mlops/DESCRIPTION.md +3 -0
- package/skills/mlops/evaluation/DESCRIPTION.md +3 -0
- package/skills/mlops/evaluation/lm-evaluation-harness/SKILL.md +498 -0
- package/skills/mlops/evaluation/lm-evaluation-harness/references/api-evaluation.md +490 -0
- package/skills/mlops/evaluation/lm-evaluation-harness/references/benchmark-guide.md +488 -0
- package/skills/mlops/evaluation/lm-evaluation-harness/references/custom-tasks.md +602 -0
- package/skills/mlops/evaluation/lm-evaluation-harness/references/distributed-eval.md +519 -0
- package/skills/mlops/evaluation/weights-and-biases/SKILL.md +594 -0
- package/skills/mlops/evaluation/weights-and-biases/references/artifacts.md +584 -0
- package/skills/mlops/evaluation/weights-and-biases/references/integrations.md +700 -0
- package/skills/mlops/evaluation/weights-and-biases/references/sweeps.md +847 -0
- package/skills/mlops/huggingface-hub/SKILL.md +81 -0
- package/skills/mlops/inference/DESCRIPTION.md +3 -0
- package/skills/mlops/inference/llama-cpp/SKILL.md +249 -0
- package/skills/mlops/inference/llama-cpp/references/advanced-usage.md +504 -0
- package/skills/mlops/inference/llama-cpp/references/hub-discovery.md +168 -0
- package/skills/mlops/inference/llama-cpp/references/optimization.md +89 -0
- package/skills/mlops/inference/llama-cpp/references/quantization.md +243 -0
- package/skills/mlops/inference/llama-cpp/references/server.md +150 -0
- package/skills/mlops/inference/llama-cpp/references/troubleshooting.md +442 -0
- package/skills/mlops/inference/obliteratus/SKILL.md +342 -0
- package/skills/mlops/inference/obliteratus/references/analysis-modules.md +166 -0
- package/skills/mlops/inference/obliteratus/references/methods-guide.md +141 -0
- package/skills/mlops/inference/obliteratus/templates/abliteration-config.yaml +33 -0
- package/skills/mlops/inference/obliteratus/templates/analysis-study.yaml +40 -0
- package/skills/mlops/inference/obliteratus/templates/batch-abliteration.yaml +41 -0
- package/skills/mlops/inference/vllm/SKILL.md +372 -0
- package/skills/mlops/inference/vllm/references/optimization.md +226 -0
- package/skills/mlops/inference/vllm/references/quantization.md +284 -0
- package/skills/mlops/inference/vllm/references/server-deployment.md +255 -0
- package/skills/mlops/inference/vllm/references/troubleshooting.md +447 -0
- package/skills/mlops/models/DESCRIPTION.md +3 -0
- package/skills/mlops/models/audiocraft/SKILL.md +568 -0
- package/skills/mlops/models/audiocraft/references/advanced-usage.md +666 -0
- package/skills/mlops/models/audiocraft/references/troubleshooting.md +504 -0
- package/skills/mlops/models/segment-anything/SKILL.md +506 -0
- package/skills/mlops/models/segment-anything/references/advanced-usage.md +589 -0
- package/skills/mlops/models/segment-anything/references/troubleshooting.md +484 -0
- package/skills/mlops/research/DESCRIPTION.md +3 -0
- package/skills/mlops/research/dspy/SKILL.md +594 -0
- package/skills/mlops/research/dspy/references/examples.md +663 -0
- package/skills/mlops/research/dspy/references/modules.md +475 -0
- package/skills/mlops/research/dspy/references/optimizers.md +566 -0
- package/skills/mlops/training/DESCRIPTION.md +3 -0
- package/skills/mlops/vector-databases/DESCRIPTION.md +3 -0
- package/skills/note-taking/DESCRIPTION.md +3 -0
- package/skills/note-taking/obsidian/SKILL.md +61 -0
- package/skills/productivity/DESCRIPTION.md +3 -0
- package/skills/productivity/airtable/SKILL.md +229 -0
- package/skills/productivity/google-workspace/SKILL.md +335 -0
- package/skills/productivity/google-workspace/references/gmail-search-syntax.md +63 -0
- package/skills/productivity/google-workspace/scripts/_hermes_home.py +43 -0
- package/skills/productivity/google-workspace/scripts/google_api.py +1221 -0
- package/skills/productivity/google-workspace/scripts/gws_bridge.py +108 -0
- package/skills/productivity/google-workspace/scripts/setup.py +454 -0
- package/skills/productivity/linear/SKILL.md +380 -0
- package/skills/productivity/linear/scripts/linear_api.py +445 -0
- package/skills/productivity/maps/SKILL.md +195 -0
- package/skills/productivity/maps/scripts/maps_client.py +1298 -0
- package/skills/productivity/nano-pdf/SKILL.md +52 -0
- package/skills/productivity/notion/SKILL.md +448 -0
- package/skills/productivity/notion/references/block-types.md +112 -0
- package/skills/productivity/ocr-and-documents/DESCRIPTION.md +3 -0
- package/skills/productivity/ocr-and-documents/SKILL.md +172 -0
- package/skills/productivity/ocr-and-documents/scripts/extract_marker.py +87 -0
- package/skills/productivity/ocr-and-documents/scripts/extract_pymupdf.py +98 -0
- package/skills/productivity/powerpoint/LICENSE.txt +30 -0
- package/skills/productivity/powerpoint/SKILL.md +237 -0
- package/skills/productivity/powerpoint/editing.md +205 -0
- package/skills/productivity/powerpoint/pptxgenjs.md +420 -0
- package/skills/productivity/powerpoint/scripts/__init__.py +0 -0
- package/skills/productivity/powerpoint/scripts/add_slide.py +195 -0
- package/skills/productivity/powerpoint/scripts/clean.py +286 -0
- package/skills/productivity/powerpoint/scripts/office/helpers/__init__.py +0 -0
- package/skills/productivity/powerpoint/scripts/office/helpers/merge_runs.py +199 -0
- package/skills/productivity/powerpoint/scripts/office/helpers/simplify_redlines.py +197 -0
- package/skills/productivity/powerpoint/scripts/office/pack.py +159 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-contentTypes.xsd +42 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-coreProperties.xsd +50 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-digSig.xsd +49 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-relationships.xsd +33 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/mce/mc.xsd +75 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/productivity/teams-meeting-pipeline/SKILL.md +116 -0
- package/skills/red-teaming/godmode/SKILL.md +404 -0
- package/skills/red-teaming/godmode/references/jailbreak-templates.md +128 -0
- package/skills/red-teaming/godmode/references/refusal-detection.md +142 -0
- package/skills/red-teaming/godmode/scripts/auto_jailbreak.py +769 -0
- package/skills/red-teaming/godmode/scripts/godmode_race.py +530 -0
- package/skills/red-teaming/godmode/scripts/load_godmode.py +45 -0
- package/skills/red-teaming/godmode/scripts/parseltongue.py +550 -0
- package/skills/red-teaming/godmode/templates/prefill-subtle.json +10 -0
- package/skills/red-teaming/godmode/templates/prefill.json +18 -0
- package/skills/research/DESCRIPTION.md +3 -0
- package/skills/research/arxiv/SKILL.md +282 -0
- package/skills/research/arxiv/scripts/search_arxiv.py +114 -0
- package/skills/research/blogwatcher/SKILL.md +137 -0
- package/skills/research/llm-wiki/SKILL.md +507 -0
- package/skills/research/polymarket/SKILL.md +77 -0
- package/skills/research/polymarket/references/api-endpoints.md +220 -0
- package/skills/research/polymarket/scripts/polymarket.py +284 -0
- package/skills/research/research-paper-writing/SKILL.md +2377 -0
- package/skills/research/research-paper-writing/references/autoreason-methodology.md +394 -0
- package/skills/research/research-paper-writing/references/checklists.md +434 -0
- package/skills/research/research-paper-writing/references/citation-workflow.md +564 -0
- package/skills/research/research-paper-writing/references/experiment-patterns.md +728 -0
- package/skills/research/research-paper-writing/references/human-evaluation.md +476 -0
- package/skills/research/research-paper-writing/references/paper-types.md +481 -0
- package/skills/research/research-paper-writing/references/reviewer-guidelines.md +433 -0
- package/skills/research/research-paper-writing/references/sources.md +191 -0
- package/skills/research/research-paper-writing/references/writing-guide.md +474 -0
- package/skills/research/research-paper-writing/templates/README.md +251 -0
- package/skills/research/research-paper-writing/templates/aaai2026/README.md +534 -0
- package/skills/research/research-paper-writing/templates/aaai2026/aaai2026-unified-supp.tex +144 -0
- package/skills/research/research-paper-writing/templates/aaai2026/aaai2026-unified-template.tex +952 -0
- package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.bib +111 -0
- package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.bst +1493 -0
- package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.sty +315 -0
- package/skills/research/research-paper-writing/templates/acl/README.md +50 -0
- package/skills/research/research-paper-writing/templates/acl/acl.sty +312 -0
- package/skills/research/research-paper-writing/templates/acl/acl_latex.tex +377 -0
- package/skills/research/research-paper-writing/templates/acl/acl_lualatex.tex +101 -0
- package/skills/research/research-paper-writing/templates/acl/acl_natbib.bst +1940 -0
- package/skills/research/research-paper-writing/templates/acl/anthology.bib.txt +26 -0
- package/skills/research/research-paper-writing/templates/acl/custom.bib +70 -0
- package/skills/research/research-paper-writing/templates/acl/formatting.md +326 -0
- package/skills/research/research-paper-writing/templates/colm2025/README.md +3 -0
- package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.bib +11 -0
- package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.bst +1440 -0
- package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.pdf +0 -0
- package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.sty +218 -0
- package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.tex +305 -0
- package/skills/research/research-paper-writing/templates/colm2025/fancyhdr.sty +485 -0
- package/skills/research/research-paper-writing/templates/colm2025/math_commands.tex +508 -0
- package/skills/research/research-paper-writing/templates/colm2025/natbib.sty +1246 -0
- package/skills/research/research-paper-writing/templates/iclr2026/fancyhdr.sty +485 -0
- package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.bib +24 -0
- package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.bst +1440 -0
- package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.pdf +0 -0
- package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.sty +246 -0
- package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.tex +414 -0
- package/skills/research/research-paper-writing/templates/iclr2026/math_commands.tex +508 -0
- package/skills/research/research-paper-writing/templates/iclr2026/natbib.sty +1246 -0
- package/skills/research/research-paper-writing/templates/icml2026/algorithm.sty +79 -0
- package/skills/research/research-paper-writing/templates/icml2026/algorithmic.sty +201 -0
- package/skills/research/research-paper-writing/templates/icml2026/example_paper.bib +75 -0
- package/skills/research/research-paper-writing/templates/icml2026/example_paper.pdf +0 -0
- package/skills/research/research-paper-writing/templates/icml2026/example_paper.tex +662 -0
- package/skills/research/research-paper-writing/templates/icml2026/fancyhdr.sty +864 -0
- package/skills/research/research-paper-writing/templates/icml2026/icml2026.bst +1443 -0
- package/skills/research/research-paper-writing/templates/icml2026/icml2026.sty +767 -0
- package/skills/research/research-paper-writing/templates/icml2026/icml_numpapers.pdf +0 -0
- package/skills/research/research-paper-writing/templates/neurips2025/Makefile +36 -0
- package/skills/research/research-paper-writing/templates/neurips2025/extra_pkgs.tex +53 -0
- package/skills/research/research-paper-writing/templates/neurips2025/main.tex +38 -0
- package/skills/research/research-paper-writing/templates/neurips2025/neurips.sty +382 -0
- package/skills/smart-home/DESCRIPTION.md +3 -0
- package/skills/smart-home/openhue/SKILL.md +109 -0
- package/skills/social-media/DESCRIPTION.md +3 -0
- package/skills/social-media/xurl/SKILL.md +414 -0
- package/skills/software-development/debugging-hermes-tui-commands/SKILL.md +152 -0
- package/skills/software-development/hermes-agent-skill-authoring/SKILL.md +165 -0
- package/skills/software-development/node-inspect-debugger/SKILL.md +319 -0
- package/skills/software-development/plan/SKILL.md +58 -0
- package/skills/software-development/python-debugpy/SKILL.md +375 -0
- package/skills/software-development/requesting-code-review/SKILL.md +280 -0
- package/skills/software-development/spike/SKILL.md +197 -0
- package/skills/software-development/subagent-driven-development/SKILL.md +352 -0
- package/skills/software-development/subagent-driven-development/references/context-budget-discipline.md +53 -0
- package/skills/software-development/subagent-driven-development/references/gates-taxonomy.md +93 -0
- package/skills/software-development/systematic-debugging/SKILL.md +367 -0
- package/skills/software-development/test-driven-development/SKILL.md +343 -0
- package/skills/software-development/writing-plans/SKILL.md +297 -0
- package/skills/yuanbao/SKILL.md +108 -0
- package/tools/__init__.py +25 -0
- package/tools/__pycache__/__init__.cpython-312.pyc +0 -0
- package/tools/__pycache__/approval.cpython-312.pyc +0 -0
- package/tools/__pycache__/binary_extensions.cpython-312.pyc +0 -0
- package/tools/__pycache__/browser_camofox.cpython-312.pyc +0 -0
- package/tools/__pycache__/browser_camofox_state.cpython-312.pyc +0 -0
- package/tools/__pycache__/browser_cdp_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/browser_dialog_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/browser_supervisor.cpython-312.pyc +0 -0
- package/tools/__pycache__/browser_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/budget_config.cpython-312.pyc +0 -0
- package/tools/__pycache__/checkpoint_manager.cpython-312.pyc +0 -0
- package/tools/__pycache__/clarify_gateway.cpython-312.pyc +0 -0
- package/tools/__pycache__/clarify_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/code_execution_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/computer_use_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/cronjob_tools.cpython-312.pyc +0 -0
- package/tools/__pycache__/debug_helpers.cpython-312.pyc +0 -0
- package/tools/__pycache__/delegate_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/discord_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/feishu_doc_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/feishu_drive_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/file_operations.cpython-312.pyc +0 -0
- package/tools/__pycache__/file_state.cpython-312.pyc +0 -0
- package/tools/__pycache__/file_tools.cpython-312.pyc +0 -0
- package/tools/__pycache__/homeassistant_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/image_generation_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/interrupt.cpython-312.pyc +0 -0
- package/tools/__pycache__/kanban_tools.cpython-312.pyc +0 -0
- package/tools/__pycache__/lazy_deps.cpython-312.pyc +0 -0
- package/tools/__pycache__/managed_tool_gateway.cpython-312.pyc +0 -0
- package/tools/__pycache__/mcp_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/memory_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/mixture_of_agents_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/openrouter_client.cpython-312.pyc +0 -0
- package/tools/__pycache__/process_registry.cpython-312.pyc +0 -0
- package/tools/__pycache__/registry.cpython-312.pyc +0 -0
- package/tools/__pycache__/schema_sanitizer.cpython-312.pyc +0 -0
- package/tools/__pycache__/send_message_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/session_search_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/skill_manager_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/skill_provenance.cpython-312.pyc +0 -0
- package/tools/__pycache__/skill_usage.cpython-312.pyc +0 -0
- package/tools/__pycache__/skills_guard.cpython-312.pyc +0 -0
- package/tools/__pycache__/skills_sync.cpython-312.pyc +0 -0
- package/tools/__pycache__/skills_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/slash_confirm.cpython-312.pyc +0 -0
- package/tools/__pycache__/terminal_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/tirith_security.cpython-312.pyc +0 -0
- package/tools/__pycache__/todo_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/tool_backend_helpers.cpython-312.pyc +0 -0
- package/tools/__pycache__/tool_result_storage.cpython-312.pyc +0 -0
- package/tools/__pycache__/tts_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/url_safety.cpython-312.pyc +0 -0
- package/tools/__pycache__/video_generation_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/vision_tools.cpython-312.pyc +0 -0
- package/tools/__pycache__/voice_mode.cpython-312.pyc +0 -0
- package/tools/__pycache__/web_tools.cpython-312.pyc +0 -0
- package/tools/__pycache__/website_policy.cpython-312.pyc +0 -0
- package/tools/__pycache__/x_search_tool.cpython-312.pyc +0 -0
- package/tools/__pycache__/xai_http.cpython-312.pyc +0 -0
- package/tools/__pycache__/yuanbao_tools.cpython-312.pyc +0 -0
- package/tools/ansi_strip.py +44 -0
- package/tools/approval.py +1392 -0
- package/tools/binary_extensions.py +42 -0
- package/tools/browser_camofox.py +700 -0
- package/tools/browser_camofox_state.py +48 -0
- package/tools/browser_cdp_tool.py +569 -0
- package/tools/browser_dialog_tool.py +148 -0
- package/tools/browser_providers/__init__.py +10 -0
- package/tools/browser_providers/__pycache__/__init__.cpython-312.pyc +0 -0
- package/tools/browser_providers/__pycache__/base.cpython-312.pyc +0 -0
- package/tools/browser_providers/__pycache__/browser_use.cpython-312.pyc +0 -0
- package/tools/browser_providers/__pycache__/browserbase.cpython-312.pyc +0 -0
- package/tools/browser_providers/__pycache__/firecrawl.cpython-312.pyc +0 -0
- package/tools/browser_providers/base.py +59 -0
- package/tools/browser_providers/browser_use.py +225 -0
- package/tools/browser_providers/browserbase.py +222 -0
- package/tools/browser_providers/firecrawl.py +112 -0
- package/tools/browser_supervisor.py +1457 -0
- package/tools/browser_tool.py +3676 -0
- package/tools/budget_config.py +51 -0
- package/tools/checkpoint_manager.py +1639 -0
- package/tools/clarify_gateway.py +278 -0
- package/tools/clarify_tool.py +141 -0
- package/tools/code_execution_tool.py +1782 -0
- package/tools/computer_use/__init__.py +43 -0
- package/tools/computer_use/__pycache__/__init__.cpython-312.pyc +0 -0
- package/tools/computer_use/__pycache__/backend.cpython-312.pyc +0 -0
- package/tools/computer_use/__pycache__/schema.cpython-312.pyc +0 -0
- package/tools/computer_use/__pycache__/tool.cpython-312.pyc +0 -0
- package/tools/computer_use/backend.py +150 -0
- package/tools/computer_use/cua_backend.py +682 -0
- package/tools/computer_use/schema.py +191 -0
- package/tools/computer_use/tool.py +521 -0
- package/tools/computer_use_tool.py +39 -0
- package/tools/credential_files.py +437 -0
- package/tools/cronjob_tools.py +719 -0
- package/tools/debug_helpers.py +106 -0
- package/tools/delegate_tool.py +2797 -0
- package/tools/discord_tool.py +959 -0
- package/tools/env_passthrough.py +145 -0
- package/tools/environments/__init__.py +14 -0
- package/tools/environments/__pycache__/__init__.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/base.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/docker.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/file_sync.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/local.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/managed_modal.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/modal.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/modal_utils.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/singularity.cpython-312.pyc +0 -0
- package/tools/environments/__pycache__/ssh.cpython-312.pyc +0 -0
- package/tools/environments/base.py +844 -0
- package/tools/environments/daytona.py +270 -0
- package/tools/environments/docker.py +656 -0
- package/tools/environments/file_sync.py +400 -0
- package/tools/environments/local.py +658 -0
- package/tools/environments/managed_modal.py +282 -0
- package/tools/environments/modal.py +479 -0
- package/tools/environments/modal_utils.py +199 -0
- package/tools/environments/singularity.py +263 -0
- package/tools/environments/ssh.py +295 -0
- package/tools/environments/vercel_sandbox.py +655 -0
- package/tools/feishu_doc_tool.py +138 -0
- package/tools/feishu_drive_tool.py +431 -0
- package/tools/file_operations.py +1825 -0
- package/tools/file_state.py +332 -0
- package/tools/file_tools.py +1172 -0
- package/tools/fuzzy_match.py +703 -0
- package/tools/homeassistant_tool.py +513 -0
- package/tools/image_generation_tool.py +1098 -0
- package/tools/interrupt.py +98 -0
- package/tools/kanban_tools.py +1139 -0
- package/tools/lazy_deps.py +608 -0
- package/tools/managed_tool_gateway.py +168 -0
- package/tools/mcp_oauth.py +633 -0
- package/tools/mcp_oauth_manager.py +607 -0
- package/tools/mcp_tool.py +3483 -0
- package/tools/memory_tool.py +584 -0
- package/tools/microsoft_graph_auth.py +245 -0
- package/tools/microsoft_graph_client.py +408 -0
- package/tools/mixture_of_agents_tool.py +542 -0
- package/tools/neutts_samples/jo.txt +1 -0
- package/tools/neutts_samples/jo.wav +0 -0
- package/tools/neutts_synth.py +104 -0
- package/tools/openrouter_client.py +33 -0
- package/tools/osv_check.py +155 -0
- package/tools/patch_parser.py +592 -0
- package/tools/path_security.py +43 -0
- package/tools/process_registry.py +1534 -0
- package/tools/registry.py +589 -0
- package/tools/schema_sanitizer.py +370 -0
- package/tools/send_message_tool.py +1900 -0
- package/tools/session_search_tool.py +613 -0
- package/tools/skill_manager_tool.py +932 -0
- package/tools/skill_provenance.py +78 -0
- package/tools/skill_usage.py +610 -0
- package/tools/skills_guard.py +932 -0
- package/tools/skills_hub.py +3263 -0
- package/tools/skills_sync.py +432 -0
- package/tools/skills_tool.py +1569 -0
- package/tools/slash_confirm.py +167 -0
- package/tools/terminal_tool.py +2376 -0
- package/tools/tirith_security.py +775 -0
- package/tools/todo_tool.py +277 -0
- package/tools/tool_backend_helpers.py +144 -0
- package/tools/tool_output_limits.py +92 -0
- package/tools/tool_result_storage.py +232 -0
- package/tools/transcription_tools.py +936 -0
- package/tools/tts_tool.py +2285 -0
- package/tools/url_safety.py +330 -0
- package/tools/video_generation_tool.py +561 -0
- package/tools/vision_tools.py +1422 -0
- package/tools/voice_mode.py +1019 -0
- package/tools/web_tools.py +1551 -0
- package/tools/website_policy.py +283 -0
- package/tools/x_search_tool.py +424 -0
- package/tools/xai_http.py +83 -0
- package/tools/yuanbao_tools.py +736 -0
- package/toolset_distributions.py +364 -0
- package/toolsets.py +866 -0
- package/trajectory_compressor.py +1509 -0
- package/tui_gateway/__init__.py +0 -0
- package/tui_gateway/entry.py +251 -0
- package/tui_gateway/event_publisher.py +126 -0
- package/tui_gateway/render.py +49 -0
- package/tui_gateway/server.py +6623 -0
- package/tui_gateway/slash_worker.py +76 -0
- package/tui_gateway/transport.py +219 -0
- package/tui_gateway/ws.py +178 -0
- package/utils.py +361 -0
|
@@ -0,0 +1,2007 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# Hermes Agent Installer
|
|
4
|
+
# ============================================================================
|
|
5
|
+
# Installation script for Linux, macOS, and Android/Termux.
|
|
6
|
+
# Uses uv for desktop/server installs and Python's stdlib venv + pip on Termux.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
|
|
10
|
+
#
|
|
11
|
+
# Or with options:
|
|
12
|
+
# curl -fsSL ... | bash -s -- --no-venv --skip-setup
|
|
13
|
+
#
|
|
14
|
+
# ============================================================================
|
|
15
|
+
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
# Guard against environment leakage when the installer is launched from another
|
|
19
|
+
# Python-driven tool session (e.g. Hermes terminal tool). A pre-set PYTHONPATH
|
|
20
|
+
# can force pip/entrypoints to import a different checkout than the one being
|
|
21
|
+
# installed, which makes fresh installs appear broken or stale.
|
|
22
|
+
if [ -n "${PYTHONPATH:-}" ]; then
|
|
23
|
+
echo "⚠ Ignoring inherited PYTHONPATH during install to avoid module shadowing"
|
|
24
|
+
unset PYTHONPATH
|
|
25
|
+
fi
|
|
26
|
+
if [ -n "${PYTHONHOME:-}" ]; then
|
|
27
|
+
echo "⚠ Ignoring inherited PYTHONHOME during install"
|
|
28
|
+
unset PYTHONHOME
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Prevent uv from discovering config files (uv.toml, pyproject.toml) from the
|
|
32
|
+
# wrong user's home directory when running under sudo -u <user>. See #21269.
|
|
33
|
+
export UV_NO_CONFIG=1
|
|
34
|
+
|
|
35
|
+
# Colors
|
|
36
|
+
RED='\033[0;31m'
|
|
37
|
+
GREEN='\033[0;32m'
|
|
38
|
+
YELLOW='\033[0;33m'
|
|
39
|
+
BLUE='\033[0;34m'
|
|
40
|
+
MAGENTA='\033[0;35m'
|
|
41
|
+
CYAN='\033[0;36m'
|
|
42
|
+
NC='\033[0m' # No Color
|
|
43
|
+
BOLD='\033[1m'
|
|
44
|
+
|
|
45
|
+
# Configuration
|
|
46
|
+
REPO_URL_SSH="git@github.com:NousResearch/hermes-agent.git"
|
|
47
|
+
REPO_URL_HTTPS="https://github.com/NousResearch/hermes-agent.git"
|
|
48
|
+
HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"
|
|
49
|
+
# INSTALL_DIR is resolved AFTER arg parsing and OS detection so we can pick an
|
|
50
|
+
# FHS-style layout for root installs. Track whether the user gave us an
|
|
51
|
+
# explicit directory — if so we never override it.
|
|
52
|
+
if [ -n "${HERMES_INSTALL_DIR:-}" ]; then
|
|
53
|
+
INSTALL_DIR="$HERMES_INSTALL_DIR"
|
|
54
|
+
INSTALL_DIR_EXPLICIT=true
|
|
55
|
+
else
|
|
56
|
+
INSTALL_DIR=""
|
|
57
|
+
INSTALL_DIR_EXPLICIT=false
|
|
58
|
+
fi
|
|
59
|
+
PYTHON_VERSION="3.11"
|
|
60
|
+
NODE_VERSION="22"
|
|
61
|
+
|
|
62
|
+
# FHS-style root install layout (set by resolve_install_layout when applicable):
|
|
63
|
+
# code at /usr/local/lib/hermes-agent, command at /usr/local/bin/hermes,
|
|
64
|
+
# data still at /root/.hermes (HERMES_HOME). Matches Claude Code / Codex CLI
|
|
65
|
+
# and keeps Docker bind-mounted /root/ volumes lean.
|
|
66
|
+
ROOT_FHS_LAYOUT=false
|
|
67
|
+
DETECTED_BROWSER_EXECUTABLE=""
|
|
68
|
+
|
|
69
|
+
# Options
|
|
70
|
+
USE_VENV=true
|
|
71
|
+
RUN_SETUP=true
|
|
72
|
+
SKIP_BROWSER=false
|
|
73
|
+
BRANCH="main"
|
|
74
|
+
ENSURE_DEPS=""
|
|
75
|
+
POSTINSTALL_MODE=false
|
|
76
|
+
|
|
77
|
+
# Detect non-interactive mode (e.g. curl | bash)
|
|
78
|
+
# When stdin is not a terminal, read -p will fail with EOF,
|
|
79
|
+
# causing set -e to silently abort the entire script.
|
|
80
|
+
if [ -t 0 ]; then
|
|
81
|
+
IS_INTERACTIVE=true
|
|
82
|
+
else
|
|
83
|
+
IS_INTERACTIVE=false
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Parse arguments
|
|
87
|
+
while [[ $# -gt 0 ]]; do
|
|
88
|
+
case $1 in
|
|
89
|
+
--no-venv)
|
|
90
|
+
USE_VENV=false
|
|
91
|
+
shift
|
|
92
|
+
;;
|
|
93
|
+
--skip-setup)
|
|
94
|
+
RUN_SETUP=false
|
|
95
|
+
shift
|
|
96
|
+
;;
|
|
97
|
+
--skip-browser|--no-playwright)
|
|
98
|
+
SKIP_BROWSER=true
|
|
99
|
+
shift
|
|
100
|
+
;;
|
|
101
|
+
--branch)
|
|
102
|
+
BRANCH="$2"
|
|
103
|
+
shift 2
|
|
104
|
+
;;
|
|
105
|
+
--dir)
|
|
106
|
+
INSTALL_DIR="$2"
|
|
107
|
+
INSTALL_DIR_EXPLICIT=true
|
|
108
|
+
shift 2
|
|
109
|
+
;;
|
|
110
|
+
--hermes-home)
|
|
111
|
+
HERMES_HOME="$2"
|
|
112
|
+
shift 2
|
|
113
|
+
;;
|
|
114
|
+
--ensure)
|
|
115
|
+
ENSURE_DEPS="$2"
|
|
116
|
+
shift 2
|
|
117
|
+
;;
|
|
118
|
+
--postinstall)
|
|
119
|
+
POSTINSTALL_MODE=true
|
|
120
|
+
shift
|
|
121
|
+
;;
|
|
122
|
+
-h|--help)
|
|
123
|
+
echo "Hermes Agent Installer"
|
|
124
|
+
echo ""
|
|
125
|
+
echo "Usage: install.sh [OPTIONS]"
|
|
126
|
+
echo ""
|
|
127
|
+
echo "Options:"
|
|
128
|
+
echo " --no-venv Don't create virtual environment"
|
|
129
|
+
echo " --skip-setup Skip interactive setup wizard"
|
|
130
|
+
echo " --skip-browser Skip Playwright/Chromium install (browser tools won't work)"
|
|
131
|
+
echo " --branch NAME Git branch to install (default: main)"
|
|
132
|
+
echo " --dir PATH Installation directory"
|
|
133
|
+
echo " default (non-root): ~/.hermes/hermes-agent"
|
|
134
|
+
echo " default (root, Linux): /usr/local/lib/hermes-agent"
|
|
135
|
+
echo " --hermes-home PATH Data directory (default: ~/.hermes, or \$HERMES_HOME)"
|
|
136
|
+
echo " -h, --help Show this help"
|
|
137
|
+
echo ""
|
|
138
|
+
echo "Notes:"
|
|
139
|
+
echo " When running as root on Linux, Hermes installs the code under"
|
|
140
|
+
echo " /usr/local/lib/hermes-agent and links the command into"
|
|
141
|
+
echo " /usr/local/bin/hermes (FHS layout — matches Claude Code / Codex CLI)."
|
|
142
|
+
echo " Data, config, sessions, and logs still live in \$HERMES_HOME"
|
|
143
|
+
echo " (default /root/.hermes). This keeps Docker bind-mounted volumes"
|
|
144
|
+
echo " small and ensures the command is on PATH for all shells."
|
|
145
|
+
echo " Existing installs at \$HERMES_HOME/hermes-agent are preserved in-place."
|
|
146
|
+
echo " --ensure DEPS Install only specified deps (comma-separated)"
|
|
147
|
+
echo " Supported: node, browser, ripgrep, ffmpeg"
|
|
148
|
+
echo " Does NOT clone repo or create venv"
|
|
149
|
+
echo " --postinstall Run post-install setup only (for pip users)"
|
|
150
|
+
echo " Installs optional deps + runs hermes setup"
|
|
151
|
+
echo " Does NOT clone repo or create venv"
|
|
152
|
+
exit 0
|
|
153
|
+
;;
|
|
154
|
+
*)
|
|
155
|
+
echo "Unknown option: $1"
|
|
156
|
+
exit 1
|
|
157
|
+
;;
|
|
158
|
+
esac
|
|
159
|
+
done
|
|
160
|
+
|
|
161
|
+
# ============================================================================
|
|
162
|
+
# Helper functions
|
|
163
|
+
# ============================================================================
|
|
164
|
+
|
|
165
|
+
print_banner() {
|
|
166
|
+
echo ""
|
|
167
|
+
echo -e "${MAGENTA}${BOLD}"
|
|
168
|
+
echo "┌─────────────────────────────────────────────────────────┐"
|
|
169
|
+
echo "│ ⚕ Hermes Agent Installer │"
|
|
170
|
+
echo "├─────────────────────────────────────────────────────────┤"
|
|
171
|
+
echo "│ An open source AI agent by Nous Research. │"
|
|
172
|
+
echo "└─────────────────────────────────────────────────────────┘"
|
|
173
|
+
echo -e "${NC}"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
log_info() {
|
|
177
|
+
echo -e "${CYAN}→${NC} $1"
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
log_success() {
|
|
181
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
log_warn() {
|
|
185
|
+
echo -e "${YELLOW}⚠${NC} $1"
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
log_error() {
|
|
189
|
+
echo -e "${RED}✗${NC} $1"
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
prompt_yes_no() {
|
|
193
|
+
local question="$1"
|
|
194
|
+
local default="${2:-yes}"
|
|
195
|
+
local prompt_suffix
|
|
196
|
+
local answer=""
|
|
197
|
+
|
|
198
|
+
# Use case patterns (not ${var,,}) so this works on bash 3.2 (macOS /bin/bash).
|
|
199
|
+
case "$default" in
|
|
200
|
+
[yY]|[yY][eE][sS]|[tT][rR][uU][eE]|1) prompt_suffix="[Y/n]" ;;
|
|
201
|
+
*) prompt_suffix="[y/N]" ;;
|
|
202
|
+
esac
|
|
203
|
+
|
|
204
|
+
if [ "$IS_INTERACTIVE" = true ]; then
|
|
205
|
+
read -r -p "$question $prompt_suffix " answer || answer=""
|
|
206
|
+
elif [ -r /dev/tty ] && [ -w /dev/tty ]; then
|
|
207
|
+
printf "%s %s " "$question" "$prompt_suffix" > /dev/tty
|
|
208
|
+
IFS= read -r answer < /dev/tty || answer=""
|
|
209
|
+
else
|
|
210
|
+
answer=""
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
answer="${answer#"${answer%%[![:space:]]*}"}"
|
|
214
|
+
answer="${answer%"${answer##*[![:space:]]}"}"
|
|
215
|
+
|
|
216
|
+
if [ -z "$answer" ]; then
|
|
217
|
+
case "$default" in
|
|
218
|
+
[yY]|[yY][eE][sS]|[tT][rR][uU][eE]|1) return 0 ;;
|
|
219
|
+
*) return 1 ;;
|
|
220
|
+
esac
|
|
221
|
+
fi
|
|
222
|
+
|
|
223
|
+
case "$answer" in
|
|
224
|
+
[yY]|[yY][eE][sS]) return 0 ;;
|
|
225
|
+
*) return 1 ;;
|
|
226
|
+
esac
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
is_termux() {
|
|
230
|
+
[ -n "${TERMUX_VERSION:-}" ] || [[ "${PREFIX:-}" == *"com.termux/files/usr"* ]]
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
# Decide where the repo checkout + venv live, and where the `hermes` command
|
|
234
|
+
# symlink goes. Called after detect_os so $OS/$DISTRO are known.
|
|
235
|
+
#
|
|
236
|
+
# Defaults:
|
|
237
|
+
# - Non-root, any OS: INSTALL_DIR = $HERMES_HOME/hermes-agent
|
|
238
|
+
# command link in $HOME/.local/bin
|
|
239
|
+
# - Termux (any uid): INSTALL_DIR = $HERMES_HOME/hermes-agent
|
|
240
|
+
# command link in $PREFIX/bin (already on PATH)
|
|
241
|
+
# - Root on Linux (new): INSTALL_DIR = /usr/local/lib/hermes-agent
|
|
242
|
+
# command link in /usr/local/bin
|
|
243
|
+
# (unless a legacy install already exists at
|
|
244
|
+
# $HERMES_HOME/hermes-agent — then preserve it)
|
|
245
|
+
#
|
|
246
|
+
# Always no-op when the user set --dir or $HERMES_INSTALL_DIR.
|
|
247
|
+
resolve_install_layout() {
|
|
248
|
+
if [ "$INSTALL_DIR_EXPLICIT" = true ]; then
|
|
249
|
+
log_info "Install directory: $INSTALL_DIR (explicit)"
|
|
250
|
+
return 0
|
|
251
|
+
fi
|
|
252
|
+
|
|
253
|
+
# Termux: package manager manages /data/data/..., keep code in HERMES_HOME.
|
|
254
|
+
if is_termux; then
|
|
255
|
+
INSTALL_DIR="$HERMES_HOME/hermes-agent"
|
|
256
|
+
return 0
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
# Root on Linux: prefer FHS layout unless a legacy install already exists.
|
|
260
|
+
# macOS root installs keep the legacy layout because /usr/local/ on macOS
|
|
261
|
+
# is Homebrew territory and we don't want to fight that.
|
|
262
|
+
if [ "$OS" = "linux" ] && [ "$(id -u)" -eq 0 ]; then
|
|
263
|
+
if [ -d "$HERMES_HOME/hermes-agent/.git" ]; then
|
|
264
|
+
INSTALL_DIR="$HERMES_HOME/hermes-agent"
|
|
265
|
+
log_info "Existing install detected at $INSTALL_DIR — keeping legacy layout"
|
|
266
|
+
log_info " (new root installs use /usr/local/lib/hermes-agent)"
|
|
267
|
+
return 0
|
|
268
|
+
fi
|
|
269
|
+
INSTALL_DIR="/usr/local/lib/hermes-agent"
|
|
270
|
+
ROOT_FHS_LAYOUT=true
|
|
271
|
+
log_info "Root install on Linux — using FHS layout"
|
|
272
|
+
log_info " Code: $INSTALL_DIR"
|
|
273
|
+
log_info " Command: /usr/local/bin/hermes"
|
|
274
|
+
log_info " Data: $HERMES_HOME (unchanged)"
|
|
275
|
+
return 0
|
|
276
|
+
fi
|
|
277
|
+
|
|
278
|
+
# Default: non-root, non-Termux → legacy user-scoped layout.
|
|
279
|
+
INSTALL_DIR="$HERMES_HOME/hermes-agent"
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
get_command_link_dir() {
|
|
283
|
+
if is_termux && [ -n "${PREFIX:-}" ]; then
|
|
284
|
+
echo "$PREFIX/bin"
|
|
285
|
+
elif [ "$ROOT_FHS_LAYOUT" = true ]; then
|
|
286
|
+
echo "/usr/local/bin"
|
|
287
|
+
else
|
|
288
|
+
echo "$HOME/.local/bin"
|
|
289
|
+
fi
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
get_command_link_display_dir() {
|
|
293
|
+
if is_termux && [ -n "${PREFIX:-}" ]; then
|
|
294
|
+
echo '$PREFIX/bin'
|
|
295
|
+
elif [ "$ROOT_FHS_LAYOUT" = true ]; then
|
|
296
|
+
echo '/usr/local/bin'
|
|
297
|
+
else
|
|
298
|
+
echo '~/.local/bin'
|
|
299
|
+
fi
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
get_hermes_command_path() {
|
|
303
|
+
local link_dir
|
|
304
|
+
link_dir="$(get_command_link_dir)"
|
|
305
|
+
if [ -x "$link_dir/hermes" ]; then
|
|
306
|
+
echo "$link_dir/hermes"
|
|
307
|
+
else
|
|
308
|
+
echo "hermes"
|
|
309
|
+
fi
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
# ============================================================================
|
|
313
|
+
# System detection
|
|
314
|
+
# ============================================================================
|
|
315
|
+
|
|
316
|
+
detect_os() {
|
|
317
|
+
case "$(uname -s)" in
|
|
318
|
+
Linux*)
|
|
319
|
+
if is_termux; then
|
|
320
|
+
OS="android"
|
|
321
|
+
DISTRO="termux"
|
|
322
|
+
else
|
|
323
|
+
OS="linux"
|
|
324
|
+
if [ -f /etc/os-release ]; then
|
|
325
|
+
. /etc/os-release
|
|
326
|
+
DISTRO="$ID"
|
|
327
|
+
else
|
|
328
|
+
DISTRO="unknown"
|
|
329
|
+
fi
|
|
330
|
+
fi
|
|
331
|
+
;;
|
|
332
|
+
Darwin*)
|
|
333
|
+
OS="macos"
|
|
334
|
+
DISTRO="macos"
|
|
335
|
+
;;
|
|
336
|
+
CYGWIN*|MINGW*|MSYS*)
|
|
337
|
+
OS="windows"
|
|
338
|
+
DISTRO="windows"
|
|
339
|
+
log_error "Windows detected. Please use the PowerShell installer:"
|
|
340
|
+
log_info " irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1 | iex"
|
|
341
|
+
exit 1
|
|
342
|
+
;;
|
|
343
|
+
*)
|
|
344
|
+
OS="unknown"
|
|
345
|
+
DISTRO="unknown"
|
|
346
|
+
log_warn "Unknown operating system"
|
|
347
|
+
;;
|
|
348
|
+
esac
|
|
349
|
+
|
|
350
|
+
log_success "Detected: $OS ($DISTRO)"
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
# ============================================================================
|
|
354
|
+
# Dependency checks
|
|
355
|
+
# ============================================================================
|
|
356
|
+
|
|
357
|
+
install_uv() {
|
|
358
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
359
|
+
log_info "Termux detected — using Python's stdlib venv + pip instead of uv"
|
|
360
|
+
UV_CMD=""
|
|
361
|
+
return 0
|
|
362
|
+
fi
|
|
363
|
+
|
|
364
|
+
log_info "Checking for uv package manager..."
|
|
365
|
+
|
|
366
|
+
# Check common locations for uv
|
|
367
|
+
if command -v uv &> /dev/null; then
|
|
368
|
+
UV_CMD="uv"
|
|
369
|
+
UV_VERSION=$($UV_CMD --version 2>/dev/null)
|
|
370
|
+
log_success "uv found ($UV_VERSION)"
|
|
371
|
+
return 0
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
# Check ~/.local/bin (default uv install location) even if not on PATH yet
|
|
375
|
+
if [ -x "$HOME/.local/bin/uv" ]; then
|
|
376
|
+
UV_CMD="$HOME/.local/bin/uv"
|
|
377
|
+
UV_VERSION=$($UV_CMD --version 2>/dev/null)
|
|
378
|
+
log_success "uv found at ~/.local/bin ($UV_VERSION)"
|
|
379
|
+
return 0
|
|
380
|
+
fi
|
|
381
|
+
|
|
382
|
+
# Check ~/.cargo/bin (alternative uv install location)
|
|
383
|
+
if [ -x "$HOME/.cargo/bin/uv" ]; then
|
|
384
|
+
UV_CMD="$HOME/.cargo/bin/uv"
|
|
385
|
+
UV_VERSION=$($UV_CMD --version 2>/dev/null)
|
|
386
|
+
log_success "uv found at ~/.cargo/bin ($UV_VERSION)"
|
|
387
|
+
return 0
|
|
388
|
+
fi
|
|
389
|
+
|
|
390
|
+
# Install uv
|
|
391
|
+
log_info "Installing uv (fast Python package manager)..."
|
|
392
|
+
# Capture installer output so a failure shows the user WHY (network,
|
|
393
|
+
# glibc mismatch on old distros, missing curl, ~/.local/bin not
|
|
394
|
+
# writable, disk full, corp proxy / TLS interception, etc.) instead
|
|
395
|
+
# of the previous "✗ Failed to install uv" with zero diagnostic.
|
|
396
|
+
#
|
|
397
|
+
# Two-stage: download the installer, then run it. Piping
|
|
398
|
+
# `curl | sh` masks curl failures (sh exits 0 on empty stdin)
|
|
399
|
+
# and conflates network errors with installer errors.
|
|
400
|
+
local _uv_install_log _uv_installer
|
|
401
|
+
_uv_install_log="$(mktemp 2>/dev/null || echo "/tmp/hermes-uv-install.$$.log")"
|
|
402
|
+
_uv_installer="$(mktemp 2>/dev/null || echo "/tmp/hermes-uv-installer.$$.sh")"
|
|
403
|
+
if ! curl -LsSf https://astral.sh/uv/install.sh -o "$_uv_installer" 2>"$_uv_install_log"; then
|
|
404
|
+
log_error "Failed to download uv installer from https://astral.sh/uv/install.sh"
|
|
405
|
+
log_info "curl output:"
|
|
406
|
+
sed 's/^/ /' "$_uv_install_log" >&2
|
|
407
|
+
log_info "Install manually: https://docs.astral.sh/uv/getting-started/installation/"
|
|
408
|
+
rm -f "$_uv_install_log" "$_uv_installer"
|
|
409
|
+
exit 1
|
|
410
|
+
fi
|
|
411
|
+
if sh "$_uv_installer" >>"$_uv_install_log" 2>&1; then
|
|
412
|
+
rm -f "$_uv_installer"
|
|
413
|
+
# uv installs to ~/.local/bin by default
|
|
414
|
+
if [ -x "$HOME/.local/bin/uv" ]; then
|
|
415
|
+
UV_CMD="$HOME/.local/bin/uv"
|
|
416
|
+
elif [ -x "$HOME/.cargo/bin/uv" ]; then
|
|
417
|
+
UV_CMD="$HOME/.cargo/bin/uv"
|
|
418
|
+
elif command -v uv &> /dev/null; then
|
|
419
|
+
UV_CMD="uv"
|
|
420
|
+
else
|
|
421
|
+
log_error "uv installer reported success but binary not found on PATH"
|
|
422
|
+
log_info "Installer output:"
|
|
423
|
+
sed 's/^/ /' "$_uv_install_log" >&2
|
|
424
|
+
log_info "Try adding ~/.local/bin to your PATH and re-running"
|
|
425
|
+
rm -f "$_uv_install_log"
|
|
426
|
+
exit 1
|
|
427
|
+
fi
|
|
428
|
+
rm -f "$_uv_install_log"
|
|
429
|
+
UV_VERSION=$($UV_CMD --version 2>/dev/null)
|
|
430
|
+
log_success "uv installed ($UV_VERSION)"
|
|
431
|
+
else
|
|
432
|
+
log_error "Failed to install uv"
|
|
433
|
+
log_info "Installer output:"
|
|
434
|
+
sed 's/^/ /' "$_uv_install_log" >&2
|
|
435
|
+
log_info "Install manually: https://docs.astral.sh/uv/getting-started/installation/"
|
|
436
|
+
rm -f "$_uv_install_log" "$_uv_installer"
|
|
437
|
+
exit 1
|
|
438
|
+
fi
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
check_python() {
|
|
442
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
443
|
+
log_info "Checking Termux Python..."
|
|
444
|
+
if command -v python >/dev/null 2>&1; then
|
|
445
|
+
PYTHON_PATH="$(command -v python)"
|
|
446
|
+
if "$PYTHON_PATH" -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)' 2>/dev/null; then
|
|
447
|
+
PYTHON_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)"
|
|
448
|
+
log_success "Python found: $PYTHON_FOUND_VERSION"
|
|
449
|
+
return 0
|
|
450
|
+
fi
|
|
451
|
+
fi
|
|
452
|
+
|
|
453
|
+
log_info "Installing Python via pkg..."
|
|
454
|
+
pkg install -y python >/dev/null
|
|
455
|
+
PYTHON_PATH="$(command -v python)"
|
|
456
|
+
PYTHON_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)"
|
|
457
|
+
log_success "Python installed: $PYTHON_FOUND_VERSION"
|
|
458
|
+
return 0
|
|
459
|
+
fi
|
|
460
|
+
|
|
461
|
+
log_info "Checking Python $PYTHON_VERSION..."
|
|
462
|
+
|
|
463
|
+
# Let uv handle Python — it can download and manage Python versions
|
|
464
|
+
# First check if a suitable Python is already available
|
|
465
|
+
if PYTHON_PATH="$("$UV_CMD" python find "$PYTHON_VERSION" 2>/dev/null)"; then
|
|
466
|
+
PYTHON_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)"
|
|
467
|
+
log_success "Python found: $PYTHON_FOUND_VERSION"
|
|
468
|
+
return 0
|
|
469
|
+
fi
|
|
470
|
+
|
|
471
|
+
# Python not found — use uv to install it (no sudo needed!)
|
|
472
|
+
log_info "Python $PYTHON_VERSION not found, installing via uv..."
|
|
473
|
+
if "$UV_CMD" python install "$PYTHON_VERSION"; then
|
|
474
|
+
PYTHON_PATH="$("$UV_CMD" python find "$PYTHON_VERSION")"
|
|
475
|
+
PYTHON_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)"
|
|
476
|
+
log_success "Python installed: $PYTHON_FOUND_VERSION"
|
|
477
|
+
else
|
|
478
|
+
log_error "Failed to install Python $PYTHON_VERSION"
|
|
479
|
+
log_info "Install Python $PYTHON_VERSION manually, then re-run this script"
|
|
480
|
+
exit 1
|
|
481
|
+
fi
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
check_git() {
|
|
485
|
+
log_info "Checking Git..."
|
|
486
|
+
|
|
487
|
+
if command -v git &> /dev/null; then
|
|
488
|
+
GIT_VERSION=$(git --version | awk '{print $3}')
|
|
489
|
+
log_success "Git $GIT_VERSION found"
|
|
490
|
+
return 0
|
|
491
|
+
fi
|
|
492
|
+
|
|
493
|
+
log_error "Git not found"
|
|
494
|
+
|
|
495
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
496
|
+
log_info "Installing Git via pkg..."
|
|
497
|
+
pkg install -y git >/dev/null
|
|
498
|
+
if command -v git >/dev/null 2>&1; then
|
|
499
|
+
GIT_VERSION=$(git --version | awk '{print $3}')
|
|
500
|
+
log_success "Git $GIT_VERSION installed"
|
|
501
|
+
return 0
|
|
502
|
+
fi
|
|
503
|
+
fi
|
|
504
|
+
|
|
505
|
+
log_info "Please install Git:"
|
|
506
|
+
|
|
507
|
+
case "$OS" in
|
|
508
|
+
linux)
|
|
509
|
+
case "$DISTRO" in
|
|
510
|
+
ubuntu|debian)
|
|
511
|
+
log_info " sudo apt update && sudo apt install git"
|
|
512
|
+
;;
|
|
513
|
+
fedora)
|
|
514
|
+
log_info " sudo dnf install git"
|
|
515
|
+
;;
|
|
516
|
+
arch)
|
|
517
|
+
log_info " sudo pacman -S git"
|
|
518
|
+
;;
|
|
519
|
+
*)
|
|
520
|
+
log_info " Use your package manager to install git"
|
|
521
|
+
;;
|
|
522
|
+
esac
|
|
523
|
+
;;
|
|
524
|
+
android)
|
|
525
|
+
log_info " pkg install git"
|
|
526
|
+
;;
|
|
527
|
+
macos)
|
|
528
|
+
log_info " xcode-select --install"
|
|
529
|
+
log_info " Or: brew install git"
|
|
530
|
+
;;
|
|
531
|
+
esac
|
|
532
|
+
|
|
533
|
+
exit 1
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
check_node() {
|
|
537
|
+
log_info "Checking Node.js (for browser tools)..."
|
|
538
|
+
|
|
539
|
+
if command -v node &> /dev/null; then
|
|
540
|
+
local found_ver=$(node --version)
|
|
541
|
+
log_success "Node.js $found_ver found"
|
|
542
|
+
HAS_NODE=true
|
|
543
|
+
return 0
|
|
544
|
+
fi
|
|
545
|
+
|
|
546
|
+
# Check our own managed install from a previous run
|
|
547
|
+
if [ -x "$HERMES_HOME/node/bin/node" ]; then
|
|
548
|
+
export PATH="$HERMES_HOME/node/bin:$PATH"
|
|
549
|
+
local found_ver=$("$HERMES_HOME/node/bin/node" --version)
|
|
550
|
+
log_success "Node.js $found_ver found (Hermes-managed)"
|
|
551
|
+
HAS_NODE=true
|
|
552
|
+
return 0
|
|
553
|
+
fi
|
|
554
|
+
|
|
555
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
556
|
+
log_info "Node.js not found — installing Node.js via pkg..."
|
|
557
|
+
else
|
|
558
|
+
log_info "Node.js not found — installing Node.js $NODE_VERSION LTS..."
|
|
559
|
+
fi
|
|
560
|
+
install_node
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
install_node() {
|
|
564
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
565
|
+
log_info "Installing Node.js via pkg..."
|
|
566
|
+
if pkg install -y nodejs >/dev/null; then
|
|
567
|
+
local installed_ver
|
|
568
|
+
installed_ver=$(node --version 2>/dev/null)
|
|
569
|
+
log_success "Node.js $installed_ver installed via pkg"
|
|
570
|
+
HAS_NODE=true
|
|
571
|
+
else
|
|
572
|
+
log_warn "Failed to install Node.js via pkg"
|
|
573
|
+
HAS_NODE=false
|
|
574
|
+
fi
|
|
575
|
+
return 0
|
|
576
|
+
fi
|
|
577
|
+
|
|
578
|
+
local arch=$(uname -m)
|
|
579
|
+
local node_arch
|
|
580
|
+
case "$arch" in
|
|
581
|
+
x86_64) node_arch="x64" ;;
|
|
582
|
+
aarch64|arm64) node_arch="arm64" ;;
|
|
583
|
+
armv7l) node_arch="armv7l" ;;
|
|
584
|
+
*)
|
|
585
|
+
log_warn "Unsupported architecture ($arch) for Node.js auto-install"
|
|
586
|
+
log_info "Install manually: https://nodejs.org/en/download/"
|
|
587
|
+
HAS_NODE=false
|
|
588
|
+
return 0
|
|
589
|
+
;;
|
|
590
|
+
esac
|
|
591
|
+
|
|
592
|
+
local node_os
|
|
593
|
+
case "$OS" in
|
|
594
|
+
linux) node_os="linux" ;;
|
|
595
|
+
macos) node_os="darwin" ;;
|
|
596
|
+
*)
|
|
597
|
+
log_warn "Unsupported OS for Node.js auto-install"
|
|
598
|
+
HAS_NODE=false
|
|
599
|
+
return 0
|
|
600
|
+
;;
|
|
601
|
+
esac
|
|
602
|
+
|
|
603
|
+
# Resolve the latest v22.x.x tarball name from the index page
|
|
604
|
+
local index_url="https://nodejs.org/dist/latest-v${NODE_VERSION}.x/"
|
|
605
|
+
local tarball_name
|
|
606
|
+
tarball_name=$(curl -fsSL "$index_url" \
|
|
607
|
+
| grep -oE "node-v${NODE_VERSION}\.[0-9]+\.[0-9]+-${node_os}-${node_arch}\.tar\.xz" \
|
|
608
|
+
| head -1)
|
|
609
|
+
|
|
610
|
+
# Fallback to .tar.gz if .tar.xz not available
|
|
611
|
+
if [ -z "$tarball_name" ]; then
|
|
612
|
+
tarball_name=$(curl -fsSL "$index_url" \
|
|
613
|
+
| grep -oE "node-v${NODE_VERSION}\.[0-9]+\.[0-9]+-${node_os}-${node_arch}\.tar\.gz" \
|
|
614
|
+
| head -1)
|
|
615
|
+
fi
|
|
616
|
+
|
|
617
|
+
if [ -z "$tarball_name" ]; then
|
|
618
|
+
log_warn "Could not find Node.js $NODE_VERSION binary for $node_os-$node_arch"
|
|
619
|
+
log_info "Install manually: https://nodejs.org/en/download/"
|
|
620
|
+
HAS_NODE=false
|
|
621
|
+
return 0
|
|
622
|
+
fi
|
|
623
|
+
|
|
624
|
+
local download_url="${index_url}${tarball_name}"
|
|
625
|
+
local tmp_dir
|
|
626
|
+
tmp_dir=$(mktemp -d)
|
|
627
|
+
|
|
628
|
+
log_info "Downloading $tarball_name..."
|
|
629
|
+
if ! curl -fsSL "$download_url" -o "$tmp_dir/$tarball_name"; then
|
|
630
|
+
log_warn "Download failed"
|
|
631
|
+
rm -rf "$tmp_dir"
|
|
632
|
+
HAS_NODE=false
|
|
633
|
+
return 0
|
|
634
|
+
fi
|
|
635
|
+
|
|
636
|
+
log_info "Extracting to ~/.hermes/node/..."
|
|
637
|
+
if [[ "$tarball_name" == *.tar.xz ]]; then
|
|
638
|
+
tar xf "$tmp_dir/$tarball_name" -C "$tmp_dir"
|
|
639
|
+
else
|
|
640
|
+
tar xzf "$tmp_dir/$tarball_name" -C "$tmp_dir"
|
|
641
|
+
fi
|
|
642
|
+
|
|
643
|
+
local extracted_dir
|
|
644
|
+
extracted_dir=$(ls -d "$tmp_dir"/node-v* 2>/dev/null | head -1)
|
|
645
|
+
|
|
646
|
+
if [ ! -d "$extracted_dir" ]; then
|
|
647
|
+
log_warn "Extraction failed"
|
|
648
|
+
rm -rf "$tmp_dir"
|
|
649
|
+
HAS_NODE=false
|
|
650
|
+
return 0
|
|
651
|
+
fi
|
|
652
|
+
|
|
653
|
+
# Place into ~/.hermes/node/ and symlink binaries to ~/.local/bin/
|
|
654
|
+
rm -rf "$HERMES_HOME/node"
|
|
655
|
+
mkdir -p "$HERMES_HOME"
|
|
656
|
+
mv "$extracted_dir" "$HERMES_HOME/node"
|
|
657
|
+
rm -rf "$tmp_dir"
|
|
658
|
+
|
|
659
|
+
mkdir -p "$HOME/.local/bin"
|
|
660
|
+
ln -sf "$HERMES_HOME/node/bin/node" "$HOME/.local/bin/node"
|
|
661
|
+
ln -sf "$HERMES_HOME/node/bin/npm" "$HOME/.local/bin/npm"
|
|
662
|
+
ln -sf "$HERMES_HOME/node/bin/npx" "$HOME/.local/bin/npx"
|
|
663
|
+
|
|
664
|
+
export PATH="$HERMES_HOME/node/bin:$PATH"
|
|
665
|
+
|
|
666
|
+
local installed_ver
|
|
667
|
+
installed_ver=$("$HERMES_HOME/node/bin/node" --version 2>/dev/null)
|
|
668
|
+
log_success "Node.js $installed_ver installed to ~/.hermes/node/"
|
|
669
|
+
HAS_NODE=true
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
check_network_prerequisites() {
|
|
673
|
+
log_info "Checking internet connectivity for package install and web tools..."
|
|
674
|
+
|
|
675
|
+
local url
|
|
676
|
+
local failed=false
|
|
677
|
+
local checks=("https://pypi.org/simple/" "https://duckduckgo.com/")
|
|
678
|
+
|
|
679
|
+
if ! command -v curl >/dev/null 2>&1; then
|
|
680
|
+
log_warn "curl not found; skipping connectivity probes"
|
|
681
|
+
return 0
|
|
682
|
+
fi
|
|
683
|
+
|
|
684
|
+
for url in "${checks[@]}"; do
|
|
685
|
+
if ! curl -fsSI --max-time 8 "$url" >/dev/null 2>&1; then
|
|
686
|
+
failed=true
|
|
687
|
+
log_warn "Could not reach $url"
|
|
688
|
+
fi
|
|
689
|
+
done
|
|
690
|
+
|
|
691
|
+
if [ "$failed" = false ]; then
|
|
692
|
+
log_success "Internet connectivity looks good"
|
|
693
|
+
return 0
|
|
694
|
+
fi
|
|
695
|
+
|
|
696
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
697
|
+
log_warn "Termux network prerequisites may be incomplete."
|
|
698
|
+
log_info "Try: pkg install -y ca-certificates curl && pkg update"
|
|
699
|
+
log_info "If mirrors are stale: termux-change-repo"
|
|
700
|
+
log_info "Then test: curl -I https://pypi.org/simple/ && curl -I https://duckduckgo.com/"
|
|
701
|
+
else
|
|
702
|
+
log_warn "Network checks failed. Hermes install may complete, but web search and dependency downloads can fail."
|
|
703
|
+
log_info "Verify internet/DNS and retry if pip install fails."
|
|
704
|
+
fi
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
install_system_packages() {
|
|
708
|
+
# Detect what's missing
|
|
709
|
+
HAS_RIPGREP=false
|
|
710
|
+
HAS_FFMPEG=false
|
|
711
|
+
local need_ripgrep=false
|
|
712
|
+
local need_ffmpeg=false
|
|
713
|
+
|
|
714
|
+
log_info "Checking ripgrep (fast file search)..."
|
|
715
|
+
if command -v rg &> /dev/null; then
|
|
716
|
+
log_success "$(rg --version | head -1) found"
|
|
717
|
+
HAS_RIPGREP=true
|
|
718
|
+
else
|
|
719
|
+
need_ripgrep=true
|
|
720
|
+
fi
|
|
721
|
+
|
|
722
|
+
log_info "Checking ffmpeg (TTS voice messages)..."
|
|
723
|
+
if command -v ffmpeg &> /dev/null; then
|
|
724
|
+
local ffmpeg_ver=$(ffmpeg -version 2>/dev/null | head -1 | awk '{print $3}')
|
|
725
|
+
log_success "ffmpeg $ffmpeg_ver found"
|
|
726
|
+
HAS_FFMPEG=true
|
|
727
|
+
else
|
|
728
|
+
need_ffmpeg=true
|
|
729
|
+
fi
|
|
730
|
+
|
|
731
|
+
# Termux always needs the Android build toolchain for the tested pip path,
|
|
732
|
+
# even when ripgrep/ffmpeg are already present.
|
|
733
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
734
|
+
local termux_pkgs=(clang rust make pkg-config libffi openssl ca-certificates curl)
|
|
735
|
+
if [ "$need_ripgrep" = true ]; then
|
|
736
|
+
termux_pkgs+=("ripgrep")
|
|
737
|
+
fi
|
|
738
|
+
if [ "$need_ffmpeg" = true ]; then
|
|
739
|
+
termux_pkgs+=("ffmpeg")
|
|
740
|
+
fi
|
|
741
|
+
|
|
742
|
+
log_info "Installing Termux packages: ${termux_pkgs[*]}"
|
|
743
|
+
if pkg install -y "${termux_pkgs[@]}" >/dev/null; then
|
|
744
|
+
[ "$need_ripgrep" = true ] && HAS_RIPGREP=true && log_success "ripgrep installed"
|
|
745
|
+
[ "$need_ffmpeg" = true ] && HAS_FFMPEG=true && log_success "ffmpeg installed"
|
|
746
|
+
log_success "Termux build dependencies installed"
|
|
747
|
+
return 0
|
|
748
|
+
fi
|
|
749
|
+
|
|
750
|
+
log_warn "Could not auto-install all Termux packages"
|
|
751
|
+
log_info "Install manually: pkg install ${termux_pkgs[*]}"
|
|
752
|
+
return 0
|
|
753
|
+
fi
|
|
754
|
+
|
|
755
|
+
# Nothing to install — done
|
|
756
|
+
if [ "$need_ripgrep" = false ] && [ "$need_ffmpeg" = false ]; then
|
|
757
|
+
return 0
|
|
758
|
+
fi
|
|
759
|
+
|
|
760
|
+
# Build a human-readable description + package list
|
|
761
|
+
local desc_parts=()
|
|
762
|
+
local pkgs=()
|
|
763
|
+
if [ "$need_ripgrep" = true ]; then
|
|
764
|
+
desc_parts+=("ripgrep for faster file search")
|
|
765
|
+
pkgs+=("ripgrep")
|
|
766
|
+
fi
|
|
767
|
+
if [ "$need_ffmpeg" = true ]; then
|
|
768
|
+
desc_parts+=("ffmpeg for TTS voice messages")
|
|
769
|
+
pkgs+=("ffmpeg")
|
|
770
|
+
fi
|
|
771
|
+
local description
|
|
772
|
+
description=$(IFS=" and "; echo "${desc_parts[*]}")
|
|
773
|
+
|
|
774
|
+
# ── macOS: brew ──
|
|
775
|
+
if [ "$OS" = "macos" ]; then
|
|
776
|
+
if command -v brew &> /dev/null; then
|
|
777
|
+
log_info "Installing ${pkgs[*]} via Homebrew..."
|
|
778
|
+
if brew install "${pkgs[@]}"; then
|
|
779
|
+
[ "$need_ripgrep" = true ] && HAS_RIPGREP=true && log_success "ripgrep installed"
|
|
780
|
+
[ "$need_ffmpeg" = true ] && HAS_FFMPEG=true && log_success "ffmpeg installed"
|
|
781
|
+
return 0
|
|
782
|
+
fi
|
|
783
|
+
fi
|
|
784
|
+
log_warn "Could not auto-install (brew not found or install failed)"
|
|
785
|
+
log_info "Install manually: brew install ${pkgs[*]}"
|
|
786
|
+
return 0
|
|
787
|
+
fi
|
|
788
|
+
|
|
789
|
+
# ── Linux: resolve package manager command ──
|
|
790
|
+
local pkg_install=""
|
|
791
|
+
case "$DISTRO" in
|
|
792
|
+
ubuntu|debian) pkg_install="apt install -y" ;;
|
|
793
|
+
fedora) pkg_install="dnf install -y" ;;
|
|
794
|
+
arch) pkg_install="pacman -S --noconfirm" ;;
|
|
795
|
+
esac
|
|
796
|
+
|
|
797
|
+
if [ -n "$pkg_install" ]; then
|
|
798
|
+
local install_cmd="$pkg_install ${pkgs[*]}"
|
|
799
|
+
|
|
800
|
+
# Prevent needrestart/whiptail dialogs from blocking non-interactive installs
|
|
801
|
+
case "$DISTRO" in
|
|
802
|
+
ubuntu|debian) export DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a ;;
|
|
803
|
+
esac
|
|
804
|
+
|
|
805
|
+
# Already root — just install
|
|
806
|
+
if [ "$(id -u)" -eq 0 ]; then
|
|
807
|
+
log_info "Installing ${pkgs[*]}..."
|
|
808
|
+
if $install_cmd; then
|
|
809
|
+
[ "$need_ripgrep" = true ] && HAS_RIPGREP=true && log_success "ripgrep installed"
|
|
810
|
+
[ "$need_ffmpeg" = true ] && HAS_FFMPEG=true && log_success "ffmpeg installed"
|
|
811
|
+
return 0
|
|
812
|
+
fi
|
|
813
|
+
# Passwordless sudo — just install
|
|
814
|
+
elif command -v sudo &> /dev/null && sudo -n true 2>/dev/null; then
|
|
815
|
+
log_info "Installing ${pkgs[*]}..."
|
|
816
|
+
if sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a $install_cmd; then
|
|
817
|
+
[ "$need_ripgrep" = true ] && HAS_RIPGREP=true && log_success "ripgrep installed"
|
|
818
|
+
[ "$need_ffmpeg" = true ] && HAS_FFMPEG=true && log_success "ffmpeg installed"
|
|
819
|
+
return 0
|
|
820
|
+
fi
|
|
821
|
+
# sudo needs password — ask once for everything
|
|
822
|
+
elif command -v sudo &> /dev/null; then
|
|
823
|
+
if [ "$IS_INTERACTIVE" = true ]; then
|
|
824
|
+
echo ""
|
|
825
|
+
log_info "sudo is needed ONLY to install optional system packages (${pkgs[*]}) via your package manager."
|
|
826
|
+
log_info "Hermes Agent itself does not require or retain root access."
|
|
827
|
+
if prompt_yes_no "Install ${description}? (requires sudo)" "no"; then
|
|
828
|
+
if sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a $install_cmd; then
|
|
829
|
+
[ "$need_ripgrep" = true ] && HAS_RIPGREP=true && log_success "ripgrep installed"
|
|
830
|
+
[ "$need_ffmpeg" = true ] && HAS_FFMPEG=true && log_success "ffmpeg installed"
|
|
831
|
+
return 0
|
|
832
|
+
fi
|
|
833
|
+
fi
|
|
834
|
+
elif (: </dev/tty) 2>/dev/null; then
|
|
835
|
+
# Non-interactive (e.g. curl | bash) but a terminal is available.
|
|
836
|
+
# Read the prompt from /dev/tty (same approach the setup wizard uses).
|
|
837
|
+
# Probe by actually opening /dev/tty: a bare existence test passes
|
|
838
|
+
# in Docker builds where the device node is in the mount namespace
|
|
839
|
+
# but opening fails with ENXIO. See #16746.
|
|
840
|
+
echo ""
|
|
841
|
+
log_info "sudo is needed ONLY to install optional system packages (${pkgs[*]}) via your package manager."
|
|
842
|
+
log_info "Hermes Agent itself does not require or retain root access."
|
|
843
|
+
if prompt_yes_no "Install ${description}?" "yes"; then
|
|
844
|
+
if sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a $install_cmd < /dev/tty; then
|
|
845
|
+
[ "$need_ripgrep" = true ] && HAS_RIPGREP=true && log_success "ripgrep installed"
|
|
846
|
+
[ "$need_ffmpeg" = true ] && HAS_FFMPEG=true && log_success "ffmpeg installed"
|
|
847
|
+
return 0
|
|
848
|
+
fi
|
|
849
|
+
fi
|
|
850
|
+
else
|
|
851
|
+
log_warn "Non-interactive mode and no terminal available — cannot install system packages"
|
|
852
|
+
log_info "Install manually after setup completes: sudo $install_cmd"
|
|
853
|
+
fi
|
|
854
|
+
fi
|
|
855
|
+
fi
|
|
856
|
+
|
|
857
|
+
# ── Fallback for ripgrep: cargo ──
|
|
858
|
+
if [ "$need_ripgrep" = true ] && [ "$HAS_RIPGREP" = false ]; then
|
|
859
|
+
if command -v cargo &> /dev/null; then
|
|
860
|
+
log_info "Trying cargo install ripgrep (no sudo needed)..."
|
|
861
|
+
if cargo install ripgrep; then
|
|
862
|
+
log_success "ripgrep installed via cargo"
|
|
863
|
+
HAS_RIPGREP=true
|
|
864
|
+
fi
|
|
865
|
+
fi
|
|
866
|
+
fi
|
|
867
|
+
|
|
868
|
+
# ── Show manual instructions for anything still missing ──
|
|
869
|
+
if [ "$HAS_RIPGREP" = false ] && [ "$need_ripgrep" = true ]; then
|
|
870
|
+
log_warn "ripgrep not installed (file search will use grep fallback)"
|
|
871
|
+
show_manual_install_hint "ripgrep"
|
|
872
|
+
fi
|
|
873
|
+
if [ "$HAS_FFMPEG" = false ] && [ "$need_ffmpeg" = true ]; then
|
|
874
|
+
log_warn "ffmpeg not installed (TTS voice messages will be limited)"
|
|
875
|
+
show_manual_install_hint "ffmpeg"
|
|
876
|
+
fi
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
show_manual_install_hint() {
|
|
880
|
+
local pkg="$1"
|
|
881
|
+
log_info "To install $pkg manually:"
|
|
882
|
+
case "$OS" in
|
|
883
|
+
linux)
|
|
884
|
+
case "$DISTRO" in
|
|
885
|
+
ubuntu|debian) log_info " sudo apt install $pkg" ;;
|
|
886
|
+
fedora) log_info " sudo dnf install $pkg" ;;
|
|
887
|
+
arch) log_info " sudo pacman -S $pkg" ;;
|
|
888
|
+
*) log_info " Use your package manager or visit the project homepage" ;;
|
|
889
|
+
esac
|
|
890
|
+
;;
|
|
891
|
+
android)
|
|
892
|
+
log_info " pkg install $pkg"
|
|
893
|
+
;;
|
|
894
|
+
macos) log_info " brew install $pkg" ;;
|
|
895
|
+
esac
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
# ============================================================================
|
|
899
|
+
# Installation
|
|
900
|
+
# ============================================================================
|
|
901
|
+
|
|
902
|
+
clone_repo() {
|
|
903
|
+
log_info "Installing to $INSTALL_DIR..."
|
|
904
|
+
|
|
905
|
+
if [ -d "$INSTALL_DIR" ]; then
|
|
906
|
+
if [ -d "$INSTALL_DIR/.git" ]; then
|
|
907
|
+
log_info "Existing installation found, updating..."
|
|
908
|
+
cd "$INSTALL_DIR"
|
|
909
|
+
|
|
910
|
+
local autostash_ref=""
|
|
911
|
+
if [ -n "$(git status --porcelain)" ]; then
|
|
912
|
+
local stash_name
|
|
913
|
+
stash_name="hermes-install-autostash-$(date -u +%Y%m%d-%H%M%S)"
|
|
914
|
+
log_info "Local changes detected, stashing before update..."
|
|
915
|
+
git stash push --include-untracked -m "$stash_name"
|
|
916
|
+
autostash_ref="stash@{0}"
|
|
917
|
+
fi
|
|
918
|
+
|
|
919
|
+
git fetch origin
|
|
920
|
+
git checkout "$BRANCH"
|
|
921
|
+
git pull --ff-only origin "$BRANCH"
|
|
922
|
+
|
|
923
|
+
if [ -n "$autostash_ref" ]; then
|
|
924
|
+
local restore_now="yes"
|
|
925
|
+
if [ -t 0 ] && [ -t 1 ]; then
|
|
926
|
+
echo
|
|
927
|
+
log_warn "Local changes were stashed before updating."
|
|
928
|
+
log_warn "Restoring them may reapply local customizations onto the updated codebase."
|
|
929
|
+
printf "Restore local changes now? [Y/n] "
|
|
930
|
+
read -r restore_answer
|
|
931
|
+
case "$restore_answer" in
|
|
932
|
+
""|y|Y|yes|YES|Yes) restore_now="yes" ;;
|
|
933
|
+
*) restore_now="no" ;;
|
|
934
|
+
esac
|
|
935
|
+
fi
|
|
936
|
+
|
|
937
|
+
if [ "$restore_now" = "yes" ]; then
|
|
938
|
+
log_info "Restoring local changes..."
|
|
939
|
+
if git stash apply "$autostash_ref"; then
|
|
940
|
+
git stash drop "$autostash_ref" >/dev/null
|
|
941
|
+
log_warn "Local changes were restored on top of the updated codebase."
|
|
942
|
+
log_warn "Review git diff / git status if Hermes behaves unexpectedly."
|
|
943
|
+
else
|
|
944
|
+
log_error "Update succeeded, but restoring local changes failed. Your changes are still preserved in git stash."
|
|
945
|
+
log_info "Resolve manually with: git stash apply $autostash_ref"
|
|
946
|
+
exit 1
|
|
947
|
+
fi
|
|
948
|
+
else
|
|
949
|
+
log_info "Skipped restoring local changes."
|
|
950
|
+
log_info "Your changes are still preserved in git stash."
|
|
951
|
+
log_info "Restore manually with: git stash apply $autostash_ref"
|
|
952
|
+
fi
|
|
953
|
+
fi
|
|
954
|
+
else
|
|
955
|
+
log_error "Directory exists but is not a git repository: $INSTALL_DIR"
|
|
956
|
+
log_info "Remove it or choose a different directory with --dir"
|
|
957
|
+
exit 1
|
|
958
|
+
fi
|
|
959
|
+
else
|
|
960
|
+
# Try SSH first (for private repo access), fall back to HTTPS
|
|
961
|
+
# GIT_SSH_COMMAND disables interactive prompts and sets a short timeout
|
|
962
|
+
# so SSH fails fast instead of hanging when no key is configured.
|
|
963
|
+
log_info "Trying SSH clone..."
|
|
964
|
+
if GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=5" \
|
|
965
|
+
git clone --branch "$BRANCH" "$REPO_URL_SSH" "$INSTALL_DIR" 2>/dev/null; then
|
|
966
|
+
log_success "Cloned via SSH"
|
|
967
|
+
else
|
|
968
|
+
rm -rf "$INSTALL_DIR" 2>/dev/null # Clean up partial SSH clone
|
|
969
|
+
log_info "SSH failed, trying HTTPS..."
|
|
970
|
+
if git clone --branch "$BRANCH" "$REPO_URL_HTTPS" "$INSTALL_DIR"; then
|
|
971
|
+
log_success "Cloned via HTTPS"
|
|
972
|
+
else
|
|
973
|
+
log_error "Failed to clone repository"
|
|
974
|
+
exit 1
|
|
975
|
+
fi
|
|
976
|
+
fi
|
|
977
|
+
fi
|
|
978
|
+
|
|
979
|
+
cd "$INSTALL_DIR"
|
|
980
|
+
|
|
981
|
+
log_success "Repository ready"
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
setup_venv() {
|
|
985
|
+
if [ "$USE_VENV" = false ]; then
|
|
986
|
+
log_info "Skipping virtual environment (--no-venv)"
|
|
987
|
+
return 0
|
|
988
|
+
fi
|
|
989
|
+
|
|
990
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
991
|
+
log_info "Creating virtual environment with Termux Python..."
|
|
992
|
+
|
|
993
|
+
if [ -d "venv" ]; then
|
|
994
|
+
log_info "Virtual environment already exists, recreating..."
|
|
995
|
+
rm -rf venv
|
|
996
|
+
fi
|
|
997
|
+
|
|
998
|
+
"$PYTHON_PATH" -m venv venv
|
|
999
|
+
log_success "Virtual environment ready ($(./venv/bin/python --version 2>/dev/null))"
|
|
1000
|
+
return 0
|
|
1001
|
+
fi
|
|
1002
|
+
|
|
1003
|
+
log_info "Creating virtual environment with Python $PYTHON_VERSION..."
|
|
1004
|
+
|
|
1005
|
+
if [ -d "venv" ]; then
|
|
1006
|
+
log_info "Virtual environment already exists, recreating..."
|
|
1007
|
+
rm -rf venv
|
|
1008
|
+
fi
|
|
1009
|
+
|
|
1010
|
+
# uv creates the venv and pins the Python version in one step
|
|
1011
|
+
$UV_CMD venv venv --python "$PYTHON_VERSION"
|
|
1012
|
+
|
|
1013
|
+
log_success "Virtual environment ready (Python $PYTHON_VERSION)"
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
install_deps() {
|
|
1017
|
+
log_info "Installing dependencies..."
|
|
1018
|
+
|
|
1019
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1020
|
+
if [ "$USE_VENV" = true ]; then
|
|
1021
|
+
export VIRTUAL_ENV="$INSTALL_DIR/venv"
|
|
1022
|
+
PIP_PYTHON="$INSTALL_DIR/venv/bin/python"
|
|
1023
|
+
else
|
|
1024
|
+
PIP_PYTHON="$PYTHON_PATH"
|
|
1025
|
+
fi
|
|
1026
|
+
|
|
1027
|
+
if [ -z "${ANDROID_API_LEVEL:-}" ]; then
|
|
1028
|
+
ANDROID_API_LEVEL="$(getprop ro.build.version.sdk 2>/dev/null || true)"
|
|
1029
|
+
if [ -z "$ANDROID_API_LEVEL" ]; then
|
|
1030
|
+
ANDROID_API_LEVEL=24
|
|
1031
|
+
fi
|
|
1032
|
+
export ANDROID_API_LEVEL
|
|
1033
|
+
log_info "Using ANDROID_API_LEVEL=$ANDROID_API_LEVEL for Android wheel builds"
|
|
1034
|
+
fi
|
|
1035
|
+
|
|
1036
|
+
"$PIP_PYTHON" -m pip install --upgrade pip setuptools wheel >/dev/null
|
|
1037
|
+
|
|
1038
|
+
# On Android, psutil's setup.py rejects sys.platform == 'android' before
|
|
1039
|
+
# it ever invokes the C build, so the next pip install would fail at
|
|
1040
|
+
# "platform android is not supported". Prebuild psutil from the official
|
|
1041
|
+
# sdist with a one-line marker patch (Linux source path is fine on
|
|
1042
|
+
# Android). Stopgap until psutil#2762 ships upstream.
|
|
1043
|
+
if "$PIP_PYTHON" -c 'import sys; raise SystemExit(0 if sys.platform == "android" else 1)' 2>/dev/null; then
|
|
1044
|
+
log_info "Android Python detected: prebuilding psutil compatibility shim..."
|
|
1045
|
+
if ! "$PIP_PYTHON" "$INSTALL_DIR/scripts/install_psutil_android.py" --pip "$PIP_PYTHON -m pip"; then
|
|
1046
|
+
log_warn "psutil Android prebuild failed — package install will likely fail next."
|
|
1047
|
+
log_info "Workaround: manually rerun 'python scripts/install_psutil_android.py' once your toolchain is set up."
|
|
1048
|
+
fi
|
|
1049
|
+
fi
|
|
1050
|
+
|
|
1051
|
+
# Try the broad Termux profile first (best-effort "install all" for Android),
|
|
1052
|
+
# then fall back to the conservative Termux baseline, then base package.
|
|
1053
|
+
if ! "$PIP_PYTHON" -m pip install -e '.[termux-all]' -c constraints-termux.txt; then
|
|
1054
|
+
log_warn "Termux broad profile (.[termux-all]) failed, trying baseline Termux profile..."
|
|
1055
|
+
if ! "$PIP_PYTHON" -m pip install -e '.[termux]' -c constraints-termux.txt; then
|
|
1056
|
+
log_warn "Termux baseline profile (.[termux]) failed, trying base install..."
|
|
1057
|
+
if ! "$PIP_PYTHON" -m pip install -e '.' -c constraints-termux.txt; then
|
|
1058
|
+
log_error "Package installation failed on Termux."
|
|
1059
|
+
log_info "Ensure these packages are installed: pkg install clang rust make pkg-config libffi openssl ca-certificates curl"
|
|
1060
|
+
log_info "Then re-run: cd $INSTALL_DIR && python -m pip install -e '.[termux-all]' -c constraints-termux.txt"
|
|
1061
|
+
exit 1
|
|
1062
|
+
fi
|
|
1063
|
+
fi
|
|
1064
|
+
fi
|
|
1065
|
+
|
|
1066
|
+
log_success "Main package installed"
|
|
1067
|
+
log_info "Termux note: matrix e2ee and local faster-whisper extras are excluded from .[termux-all] due to upstream Android wheel/toolchain blockers."
|
|
1068
|
+
log_info "Termux note: browser/WhatsApp tooling is not installed by default; see the Termux guide for optional follow-up steps."
|
|
1069
|
+
|
|
1070
|
+
log_success "All dependencies installed"
|
|
1071
|
+
return 0
|
|
1072
|
+
fi
|
|
1073
|
+
|
|
1074
|
+
if [ "$USE_VENV" = true ]; then
|
|
1075
|
+
# Tell uv to install into our venv (no need to activate)
|
|
1076
|
+
export VIRTUAL_ENV="$INSTALL_DIR/venv"
|
|
1077
|
+
fi
|
|
1078
|
+
|
|
1079
|
+
# On Debian/Ubuntu (including WSL), some Python packages need build tools.
|
|
1080
|
+
# Check and offer to install them if missing.
|
|
1081
|
+
if [ "$DISTRO" = "ubuntu" ] || [ "$DISTRO" = "debian" ]; then
|
|
1082
|
+
local need_build_tools=false
|
|
1083
|
+
for pkg in gcc python3-dev libffi-dev; do
|
|
1084
|
+
if ! dpkg -s "$pkg" &>/dev/null; then
|
|
1085
|
+
need_build_tools=true
|
|
1086
|
+
break
|
|
1087
|
+
fi
|
|
1088
|
+
done
|
|
1089
|
+
if [ "$need_build_tools" = true ]; then
|
|
1090
|
+
log_info "Some build tools may be needed for Python packages..."
|
|
1091
|
+
if command -v sudo &> /dev/null; then
|
|
1092
|
+
if sudo -n true 2>/dev/null; then
|
|
1093
|
+
sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get update -qq && sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get install -y -qq build-essential python3-dev libffi-dev >/dev/null 2>&1 || true
|
|
1094
|
+
log_success "Build tools installed"
|
|
1095
|
+
else
|
|
1096
|
+
log_info "sudo is needed ONLY to install build tools (build-essential, python3-dev, libffi-dev) via apt."
|
|
1097
|
+
log_info "Hermes Agent itself does not require or retain root access."
|
|
1098
|
+
if prompt_yes_no "Install build tools?" "yes"; then
|
|
1099
|
+
sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get update -qq && sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get install -y -qq build-essential python3-dev libffi-dev >/dev/null 2>&1 || true
|
|
1100
|
+
log_success "Build tools installed"
|
|
1101
|
+
fi
|
|
1102
|
+
fi
|
|
1103
|
+
fi
|
|
1104
|
+
fi
|
|
1105
|
+
fi
|
|
1106
|
+
|
|
1107
|
+
# Install the main package in editable mode with all extras.
|
|
1108
|
+
#
|
|
1109
|
+
# Hash-verified install (Tier 0) — when uv.lock is present, prefer
|
|
1110
|
+
# `uv sync --locked`. The lockfile records SHA256 hashes for every
|
|
1111
|
+
# transitive, so a compromised transitive (different hash than what
|
|
1112
|
+
# we shipped) is REJECTED by the resolver. This is the *only* path
|
|
1113
|
+
# that protects against the "direct dep is fine, but the dep's dep
|
|
1114
|
+
# got worm-poisoned overnight" failure mode. All `uv pip install`
|
|
1115
|
+
# tiers below re-resolve transitives fresh from PyPI without any
|
|
1116
|
+
# hash verification — they exist to keep installs working when the
|
|
1117
|
+
# lockfile is stale, missing, or out-of-sync with the current
|
|
1118
|
+
# extras spec, NOT because they're equivalent in posture.
|
|
1119
|
+
if [ -f "uv.lock" ]; then
|
|
1120
|
+
log_info "Trying tier: hash-verified (uv.lock) ..."
|
|
1121
|
+
log_info "(this resolves + downloads the curated [all] set — first run on a"
|
|
1122
|
+
log_info " fresh venv can take 1-5 minutes; uv prints progress below)"
|
|
1123
|
+
# Stream uv's progress directly to the user instead of swallowing
|
|
1124
|
+
# it with `2>"$(mktemp)"`. Two reasons:
|
|
1125
|
+
# 1. `--extra all --locked` against a fresh venv has to pull
|
|
1126
|
+
# every transitive — silencing stderr makes the install
|
|
1127
|
+
# look frozen for minutes on slow networks. Users see
|
|
1128
|
+
# "Trying tier: hash-verified ..." and assume it's hung.
|
|
1129
|
+
# 2. The previous `2>"$(mktemp)"` substituted the path at
|
|
1130
|
+
# command-build time but never saved it, so on failure the
|
|
1131
|
+
# uv error message was unreachable — the user just got the
|
|
1132
|
+
# generic "lockfile may be stale" warning.
|
|
1133
|
+
#
|
|
1134
|
+
# Critical flag choice: `--extra all`, NOT `--all-extras`.
|
|
1135
|
+
# --all-extras = every [project.optional-dependencies] key.
|
|
1136
|
+
# This bypasses the curated `[all]` extra
|
|
1137
|
+
# entirely and pulls e.g. [matrix] (which
|
|
1138
|
+
# needs python-olm + make on Windows) and
|
|
1139
|
+
# [rl] (git+https deps that fail offline).
|
|
1140
|
+
# --extra all = install just the `[all]` extra's contents.
|
|
1141
|
+
# This respects the curation in pyproject.toml.
|
|
1142
|
+
# uv's own progress UI handles TTY detection and downgrades
|
|
1143
|
+
# gracefully when stdout/stderr aren't terminals.
|
|
1144
|
+
if UV_PROJECT_ENVIRONMENT="$INSTALL_DIR/venv" $UV_CMD sync --extra all --locked; then
|
|
1145
|
+
log_success "Main package installed (hash-verified via uv.lock)"
|
|
1146
|
+
log_success "All dependencies installed"
|
|
1147
|
+
return 0
|
|
1148
|
+
fi
|
|
1149
|
+
log_warn "uv.lock sync failed (see uv output above), falling back to PyPI resolve..."
|
|
1150
|
+
else
|
|
1151
|
+
log_info "uv.lock not found — falling back to PyPI resolve (no hash verification)"
|
|
1152
|
+
fi
|
|
1153
|
+
|
|
1154
|
+
# Multi-tier fallback. The point of the tiers is that ONE compromised
|
|
1155
|
+
# PyPI package (a worm-poisoned release that gets quarantined, like
|
|
1156
|
+
# mistralai 2.4.6 in May 2026) shouldn't be able to silently demote a
|
|
1157
|
+
# fresh install all the way down to "core only" — the user should keep
|
|
1158
|
+
# everything else they signed up for.
|
|
1159
|
+
#
|
|
1160
|
+
# Tier 1: [all] — the curated extra in pyproject.toml.
|
|
1161
|
+
# Tier 2: [all] minus the currently-broken extras list (_BROKEN_EXTRAS).
|
|
1162
|
+
# Edit _BROKEN_EXTRAS below when something on PyPI breaks; this
|
|
1163
|
+
# lets users keep the rest of [all] when one transitive is
|
|
1164
|
+
# unavailable. The list of [all]'s contents is parsed from
|
|
1165
|
+
# pyproject.toml at runtime — there is NO hand-mirrored copy
|
|
1166
|
+
# to drift out of sync. If you want to change what [all]
|
|
1167
|
+
# contains, edit pyproject.toml only.
|
|
1168
|
+
# Tier 3: bare `.` — last-resort so at least the core CLI launches.
|
|
1169
|
+
# Skipped tiers like "PyPI-only extras (no git deps)" used to
|
|
1170
|
+
# exist to dodge [rl] / [matrix] git+sdist deps; those are no
|
|
1171
|
+
# longer in [all] post-2026-05-12 lazy-install migration, so
|
|
1172
|
+
# a separate PyPI-only tier had no remaining content.
|
|
1173
|
+
local _BROKEN_EXTRAS=() # populate when an extra becomes unresolvable
|
|
1174
|
+
|
|
1175
|
+
# Parse [project.optional-dependencies].all from pyproject.toml.
|
|
1176
|
+
# tomllib is stdlib on Python 3.11+ which uv's bootstrap guarantees.
|
|
1177
|
+
# Falls back to a hand list if parse fails — defensive only.
|
|
1178
|
+
local _ALL_EXTRAS_CSV
|
|
1179
|
+
_ALL_EXTRAS_CSV="$(
|
|
1180
|
+
"$PYTHON_PATH" - <<'PY' 2>/dev/null
|
|
1181
|
+
import re, sys, tomllib
|
|
1182
|
+
try:
|
|
1183
|
+
with open("pyproject.toml", "rb") as fh:
|
|
1184
|
+
data = tomllib.load(fh)
|
|
1185
|
+
specs = data["project"]["optional-dependencies"]["all"]
|
|
1186
|
+
extras = []
|
|
1187
|
+
for s in specs:
|
|
1188
|
+
m = re.search(r"hermes-agent\[([\w-]+)\]", s)
|
|
1189
|
+
if m:
|
|
1190
|
+
extras.append(m.group(1))
|
|
1191
|
+
print(",".join(extras))
|
|
1192
|
+
except Exception as e:
|
|
1193
|
+
print("", file=sys.stderr)
|
|
1194
|
+
sys.exit(1)
|
|
1195
|
+
PY
|
|
1196
|
+
)"
|
|
1197
|
+
if [ -z "$_ALL_EXTRAS_CSV" ]; then
|
|
1198
|
+
log_warn "Could not parse [all] from pyproject.toml; falling back to .[all] only."
|
|
1199
|
+
_ALL_EXTRAS_CSV=""
|
|
1200
|
+
fi
|
|
1201
|
+
|
|
1202
|
+
# Build "[all] minus broken" spec by filtering the parsed list.
|
|
1203
|
+
local _SAFE_SPEC=".[all]"
|
|
1204
|
+
if [ -n "$_ALL_EXTRAS_CSV" ] && [ "${#_BROKEN_EXTRAS[@]}" -gt 0 ]; then
|
|
1205
|
+
local _SAFE_EXTRAS=()
|
|
1206
|
+
local _e _b _skip
|
|
1207
|
+
IFS=',' read -ra _ALL_EXTRAS_ARR <<< "$_ALL_EXTRAS_CSV"
|
|
1208
|
+
for _e in "${_ALL_EXTRAS_ARR[@]}"; do
|
|
1209
|
+
_skip=false
|
|
1210
|
+
for _b in "${_BROKEN_EXTRAS[@]}"; do
|
|
1211
|
+
if [ "$_e" = "$_b" ]; then _skip=true; break; fi
|
|
1212
|
+
done
|
|
1213
|
+
if [ "$_skip" = false ]; then _SAFE_EXTRAS+=("$_e"); fi
|
|
1214
|
+
done
|
|
1215
|
+
_SAFE_SPEC=".[$(IFS=,; echo "${_SAFE_EXTRAS[*]}")]"
|
|
1216
|
+
fi
|
|
1217
|
+
|
|
1218
|
+
ALL_INSTALL_LOG=$(mktemp)
|
|
1219
|
+
local _installed=false
|
|
1220
|
+
local _tier_name=""
|
|
1221
|
+
|
|
1222
|
+
install_tier() {
|
|
1223
|
+
local name="$1"; local spec="$2"
|
|
1224
|
+
log_info "Trying tier: $name ..."
|
|
1225
|
+
if $UV_CMD pip install -e "$spec" 2>"$ALL_INSTALL_LOG"; then
|
|
1226
|
+
log_success "Main package installed ($name)"
|
|
1227
|
+
_installed=true
|
|
1228
|
+
_tier_name="$name"
|
|
1229
|
+
return 0
|
|
1230
|
+
fi
|
|
1231
|
+
log_warn "Tier '$name' failed. Top of pip output:"
|
|
1232
|
+
head -5 "$ALL_INSTALL_LOG" | sed 's/^/ /' >&2
|
|
1233
|
+
return 1
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
install_tier "all" ".[all]" \
|
|
1237
|
+
|| install_tier "all minus known-broken (${_BROKEN_EXTRAS[*]:-none})" "$_SAFE_SPEC" \
|
|
1238
|
+
|| install_tier "core only (no extras)" "."
|
|
1239
|
+
|
|
1240
|
+
rm -f "$ALL_INSTALL_LOG"
|
|
1241
|
+
|
|
1242
|
+
if [ "$_installed" = false ]; then
|
|
1243
|
+
log_error "Package installation failed even with no extras."
|
|
1244
|
+
log_info "Check that build tools are installed: sudo apt install build-essential python3-dev"
|
|
1245
|
+
log_info "Then re-run: cd $INSTALL_DIR && uv pip install -e '.[all]'"
|
|
1246
|
+
exit 1
|
|
1247
|
+
fi
|
|
1248
|
+
|
|
1249
|
+
if [ "$_tier_name" != "all (with RL/matrix extras)" ]; then
|
|
1250
|
+
log_warn "Note: installed via fallback tier ($_tier_name)."
|
|
1251
|
+
log_info "Some optional features may be missing. After resolving any"
|
|
1252
|
+
log_info "PyPI/network issue, re-run: $UV_CMD pip install -e '.[all]'"
|
|
1253
|
+
fi
|
|
1254
|
+
|
|
1255
|
+
log_success "Main package installed"
|
|
1256
|
+
|
|
1257
|
+
log_success "All dependencies installed"
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
setup_path() {
|
|
1261
|
+
log_info "Setting up hermes command..."
|
|
1262
|
+
|
|
1263
|
+
if [ "$USE_VENV" = true ]; then
|
|
1264
|
+
HERMES_BIN="$INSTALL_DIR/venv/bin/hermes"
|
|
1265
|
+
else
|
|
1266
|
+
HERMES_BIN="$(which hermes 2>/dev/null || echo "")"
|
|
1267
|
+
if [ -z "$HERMES_BIN" ]; then
|
|
1268
|
+
log_warn "hermes not found on PATH after install"
|
|
1269
|
+
return 0
|
|
1270
|
+
fi
|
|
1271
|
+
fi
|
|
1272
|
+
|
|
1273
|
+
# Verify the entry point script was actually generated
|
|
1274
|
+
if [ ! -x "$HERMES_BIN" ]; then
|
|
1275
|
+
log_warn "hermes entry point not found at $HERMES_BIN"
|
|
1276
|
+
log_info "This usually means the pip install didn't complete successfully."
|
|
1277
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1278
|
+
log_info "Try: cd $INSTALL_DIR && python -m pip install -e '.[termux-all]' -c constraints-termux.txt"
|
|
1279
|
+
else
|
|
1280
|
+
log_info "Try: cd $INSTALL_DIR && uv pip install -e '.[all]'"
|
|
1281
|
+
fi
|
|
1282
|
+
return 0
|
|
1283
|
+
fi
|
|
1284
|
+
|
|
1285
|
+
local command_link_dir
|
|
1286
|
+
local command_link_display_dir
|
|
1287
|
+
command_link_dir="$(get_command_link_dir)"
|
|
1288
|
+
command_link_display_dir="$(get_command_link_display_dir)"
|
|
1289
|
+
|
|
1290
|
+
# Create a user-facing shim for the hermes command.
|
|
1291
|
+
# We intentionally clear PYTHONPATH/PYTHONHOME here so inherited env vars
|
|
1292
|
+
# can't make this launcher import modules from another checkout.
|
|
1293
|
+
mkdir -p "$command_link_dir"
|
|
1294
|
+
# Older installs created this path as a symlink to $HERMES_BIN. Without
|
|
1295
|
+
# the rm, `cat >` follows the symlink and overwrites the venv pip entry
|
|
1296
|
+
# point with this shim — making `exec "$HERMES_BIN"` self-recurse. (#21454)
|
|
1297
|
+
rm -f "$command_link_dir/hermes"
|
|
1298
|
+
cat > "$command_link_dir/hermes" <<EOF
|
|
1299
|
+
#!/usr/bin/env bash
|
|
1300
|
+
unset PYTHONPATH
|
|
1301
|
+
unset PYTHONHOME
|
|
1302
|
+
exec "$HERMES_BIN" "\$@"
|
|
1303
|
+
EOF
|
|
1304
|
+
chmod +x "$command_link_dir/hermes"
|
|
1305
|
+
log_success "Installed hermes launcher → $command_link_display_dir/hermes"
|
|
1306
|
+
|
|
1307
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1308
|
+
export PATH="$command_link_dir:$PATH"
|
|
1309
|
+
log_info "$command_link_display_dir is the native Termux command path"
|
|
1310
|
+
log_success "hermes command ready"
|
|
1311
|
+
return 0
|
|
1312
|
+
fi
|
|
1313
|
+
|
|
1314
|
+
# FHS layout: /usr/local/bin is normally on PATH for login shells (via
|
|
1315
|
+
# /etc/profile pathmunge), but on RHEL/CentOS/Rocky/Alma 8+ non-login
|
|
1316
|
+
# interactive root shells (su, sudo -s, tmux panes, some web terminals)
|
|
1317
|
+
# only source /etc/bashrc, which does NOT add /usr/local/bin — and
|
|
1318
|
+
# /root/.bash_profile doesn't either. So verify with `command -v` and
|
|
1319
|
+
# fall back to writing a PATH guard into /root/.bashrc when needed.
|
|
1320
|
+
if [ "$ROOT_FHS_LAYOUT" = true ]; then
|
|
1321
|
+
export PATH="$command_link_dir:$PATH"
|
|
1322
|
+
# Probe a fresh non-login interactive bash the way the user will use it.
|
|
1323
|
+
# `bash -i -c` sources ~/.bashrc but NOT ~/.bash_profile or /etc/profile,
|
|
1324
|
+
# which is the exact scenario where RHEL root loses /usr/local/bin.
|
|
1325
|
+
if env -i HOME="$HOME" TERM="${TERM:-dumb}" bash -i -c 'command -v hermes' \
|
|
1326
|
+
>/dev/null 2>&1; then
|
|
1327
|
+
log_info "/usr/local/bin is already on PATH for all shells"
|
|
1328
|
+
log_success "hermes command ready"
|
|
1329
|
+
return 0
|
|
1330
|
+
fi
|
|
1331
|
+
|
|
1332
|
+
log_info "hermes not on PATH in non-login shells (common on RHEL-family)"
|
|
1333
|
+
PATH_LINE='export PATH="/usr/local/bin:$PATH"'
|
|
1334
|
+
PATH_COMMENT='# Hermes Agent — ensure /usr/local/bin is on PATH (RHEL non-login shells)'
|
|
1335
|
+
for SHELL_CONFIG in "$HOME/.bashrc" "$HOME/.bash_profile"; do
|
|
1336
|
+
[ -f "$SHELL_CONFIG" ] || continue
|
|
1337
|
+
if ! grep -v '^[[:space:]]*#' "$SHELL_CONFIG" 2>/dev/null \
|
|
1338
|
+
| grep -qE 'PATH=.*(/usr/local/bin|\$command_link_dir)'; then
|
|
1339
|
+
echo "" >> "$SHELL_CONFIG"
|
|
1340
|
+
echo "$PATH_COMMENT" >> "$SHELL_CONFIG"
|
|
1341
|
+
echo "$PATH_LINE" >> "$SHELL_CONFIG"
|
|
1342
|
+
log_success "Added /usr/local/bin to PATH in $SHELL_CONFIG"
|
|
1343
|
+
fi
|
|
1344
|
+
done
|
|
1345
|
+
log_success "hermes command ready"
|
|
1346
|
+
return 0
|
|
1347
|
+
fi
|
|
1348
|
+
|
|
1349
|
+
# Check if ~/.local/bin is on PATH; if not, add it to shell config.
|
|
1350
|
+
# Detect the user's actual login shell (not the shell running this script,
|
|
1351
|
+
# which is always bash when piped from curl).
|
|
1352
|
+
if ! echo "$PATH" | tr ':' '\n' | grep -q "^$command_link_dir$"; then
|
|
1353
|
+
SHELL_CONFIGS=()
|
|
1354
|
+
IS_FISH=false
|
|
1355
|
+
LOGIN_SHELL="$(basename "${SHELL:-/bin/bash}")"
|
|
1356
|
+
case "$LOGIN_SHELL" in
|
|
1357
|
+
zsh)
|
|
1358
|
+
[ -f "$HOME/.zshrc" ] && SHELL_CONFIGS+=("$HOME/.zshrc")
|
|
1359
|
+
[ -f "$HOME/.zprofile" ] && SHELL_CONFIGS+=("$HOME/.zprofile")
|
|
1360
|
+
# If neither exists, create ~/.zshrc (common on fresh macOS installs)
|
|
1361
|
+
if [ ${#SHELL_CONFIGS[@]} -eq 0 ]; then
|
|
1362
|
+
touch "$HOME/.zshrc"
|
|
1363
|
+
SHELL_CONFIGS+=("$HOME/.zshrc")
|
|
1364
|
+
fi
|
|
1365
|
+
;;
|
|
1366
|
+
bash)
|
|
1367
|
+
[ -f "$HOME/.bashrc" ] && SHELL_CONFIGS+=("$HOME/.bashrc")
|
|
1368
|
+
[ -f "$HOME/.bash_profile" ] && SHELL_CONFIGS+=("$HOME/.bash_profile")
|
|
1369
|
+
;;
|
|
1370
|
+
fish)
|
|
1371
|
+
# fish uses ~/.config/fish/config.fish and fish_add_path — not export PATH=
|
|
1372
|
+
IS_FISH=true
|
|
1373
|
+
FISH_CONFIG="$HOME/.config/fish/config.fish"
|
|
1374
|
+
mkdir -p "$(dirname "$FISH_CONFIG")"
|
|
1375
|
+
touch "$FISH_CONFIG"
|
|
1376
|
+
;;
|
|
1377
|
+
*)
|
|
1378
|
+
[ -f "$HOME/.bashrc" ] && SHELL_CONFIGS+=("$HOME/.bashrc")
|
|
1379
|
+
[ -f "$HOME/.zshrc" ] && SHELL_CONFIGS+=("$HOME/.zshrc")
|
|
1380
|
+
;;
|
|
1381
|
+
esac
|
|
1382
|
+
# Also ensure ~/.profile has it (sourced by login shells on
|
|
1383
|
+
# Ubuntu/Debian/WSL even when ~/.bashrc is skipped)
|
|
1384
|
+
[ "$IS_FISH" = "false" ] && [ -f "$HOME/.profile" ] && SHELL_CONFIGS+=("$HOME/.profile")
|
|
1385
|
+
|
|
1386
|
+
PATH_LINE='export PATH="$HOME/.local/bin:$PATH"'
|
|
1387
|
+
|
|
1388
|
+
for SHELL_CONFIG in "${SHELL_CONFIGS[@]}"; do
|
|
1389
|
+
if ! grep -v '^[[:space:]]*#' "$SHELL_CONFIG" 2>/dev/null | grep -qE 'PATH=.*\.local/bin'; then
|
|
1390
|
+
echo "" >> "$SHELL_CONFIG"
|
|
1391
|
+
echo "# Hermes Agent — ensure ~/.local/bin is on PATH" >> "$SHELL_CONFIG"
|
|
1392
|
+
echo "$PATH_LINE" >> "$SHELL_CONFIG"
|
|
1393
|
+
log_success "Added ~/.local/bin to PATH in $SHELL_CONFIG"
|
|
1394
|
+
fi
|
|
1395
|
+
done
|
|
1396
|
+
|
|
1397
|
+
# fish uses fish_add_path instead of export PATH=...
|
|
1398
|
+
if [ "$IS_FISH" = "true" ]; then
|
|
1399
|
+
if ! grep -q 'fish_add_path.*\.local/bin' "$FISH_CONFIG" 2>/dev/null; then
|
|
1400
|
+
echo "" >> "$FISH_CONFIG"
|
|
1401
|
+
echo "# Hermes Agent — ensure ~/.local/bin is on PATH" >> "$FISH_CONFIG"
|
|
1402
|
+
echo 'fish_add_path "$HOME/.local/bin"' >> "$FISH_CONFIG"
|
|
1403
|
+
log_success "Added ~/.local/bin to PATH in $FISH_CONFIG"
|
|
1404
|
+
fi
|
|
1405
|
+
fi
|
|
1406
|
+
|
|
1407
|
+
if [ "$IS_FISH" = "false" ] && [ ${#SHELL_CONFIGS[@]} -eq 0 ]; then
|
|
1408
|
+
log_warn "Could not detect shell config file to add ~/.local/bin to PATH"
|
|
1409
|
+
log_info "Add manually: $PATH_LINE"
|
|
1410
|
+
fi
|
|
1411
|
+
else
|
|
1412
|
+
log_info "~/.local/bin already on PATH"
|
|
1413
|
+
fi
|
|
1414
|
+
|
|
1415
|
+
# Export for current session so hermes works immediately
|
|
1416
|
+
export PATH="$command_link_dir:$PATH"
|
|
1417
|
+
|
|
1418
|
+
log_success "hermes command ready"
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
copy_config_templates() {
|
|
1422
|
+
log_info "Setting up configuration files..."
|
|
1423
|
+
|
|
1424
|
+
# Create ~/.hermes directory structure (config at top level, code in subdir)
|
|
1425
|
+
mkdir -p "$HERMES_HOME"/{cron,sessions,logs,pairing,hooks,image_cache,audio_cache,memories,skills}
|
|
1426
|
+
|
|
1427
|
+
# Create .env at ~/.hermes/.env (top level, easy to find)
|
|
1428
|
+
if [ ! -f "$HERMES_HOME/.env" ]; then
|
|
1429
|
+
if [ -f "$INSTALL_DIR/.env.example" ]; then
|
|
1430
|
+
cp "$INSTALL_DIR/.env.example" "$HERMES_HOME/.env"
|
|
1431
|
+
log_success "Created ~/.hermes/.env from template"
|
|
1432
|
+
else
|
|
1433
|
+
touch "$HERMES_HOME/.env"
|
|
1434
|
+
log_success "Created ~/.hermes/.env"
|
|
1435
|
+
fi
|
|
1436
|
+
else
|
|
1437
|
+
log_info "~/.hermes/.env already exists, keeping it"
|
|
1438
|
+
fi
|
|
1439
|
+
# Restrict .env permissions — this file holds API keys and tokens.
|
|
1440
|
+
# 0600 ensures only the file owner can read/write, matching standard
|
|
1441
|
+
# practice for credential files (.netrc, .aws/credentials, .ssh/config).
|
|
1442
|
+
chmod 600 "$HERMES_HOME/.env"
|
|
1443
|
+
configure_browser_env_from_system_browser
|
|
1444
|
+
|
|
1445
|
+
# Create config.yaml at ~/.hermes/config.yaml (top level, easy to find)
|
|
1446
|
+
if [ ! -f "$HERMES_HOME/config.yaml" ]; then
|
|
1447
|
+
if [ -f "$INSTALL_DIR/cli-config.yaml.example" ]; then
|
|
1448
|
+
cp "$INSTALL_DIR/cli-config.yaml.example" "$HERMES_HOME/config.yaml"
|
|
1449
|
+
log_success "Created ~/.hermes/config.yaml from template"
|
|
1450
|
+
fi
|
|
1451
|
+
else
|
|
1452
|
+
log_info "~/.hermes/config.yaml already exists, keeping it"
|
|
1453
|
+
fi
|
|
1454
|
+
|
|
1455
|
+
# Create SOUL.md if it doesn't exist (global persona file)
|
|
1456
|
+
if [ ! -f "$HERMES_HOME/SOUL.md" ]; then
|
|
1457
|
+
cat > "$HERMES_HOME/SOUL.md" << 'SOUL_EOF'
|
|
1458
|
+
# Hermes Agent Persona
|
|
1459
|
+
|
|
1460
|
+
<!--
|
|
1461
|
+
This file defines the agent's personality and tone.
|
|
1462
|
+
The agent will embody whatever you write here.
|
|
1463
|
+
Edit this to customize how Hermes communicates with you.
|
|
1464
|
+
|
|
1465
|
+
Examples:
|
|
1466
|
+
- "You are a warm, playful assistant who uses kaomoji occasionally."
|
|
1467
|
+
- "You are a concise technical expert. No fluff, just facts."
|
|
1468
|
+
- "You speak like a friendly coworker who happens to know everything."
|
|
1469
|
+
|
|
1470
|
+
This file is loaded fresh each message -- no restart needed.
|
|
1471
|
+
Delete the contents (or this file) to use the default personality.
|
|
1472
|
+
-->
|
|
1473
|
+
SOUL_EOF
|
|
1474
|
+
log_success "Created ~/.hermes/SOUL.md (edit to customize personality)"
|
|
1475
|
+
fi
|
|
1476
|
+
|
|
1477
|
+
log_success "Configuration directory ready: ~/.hermes/"
|
|
1478
|
+
|
|
1479
|
+
# Seed bundled skills into ~/.hermes/skills/ (manifest-based, one-time per skill)
|
|
1480
|
+
log_info "Syncing bundled skills to ~/.hermes/skills/ ..."
|
|
1481
|
+
if "$INSTALL_DIR/venv/bin/python" "$INSTALL_DIR/tools/skills_sync.py" 2>/dev/null; then
|
|
1482
|
+
log_success "Skills synced to ~/.hermes/skills/"
|
|
1483
|
+
else
|
|
1484
|
+
# Fallback: simple directory copy if Python sync fails
|
|
1485
|
+
if [ -d "$INSTALL_DIR/skills" ] && [ ! "$(ls -A "$HERMES_HOME/skills/" 2>/dev/null | grep -v '.bundled_manifest')" ]; then
|
|
1486
|
+
cp -r "$INSTALL_DIR/skills/"* "$HERMES_HOME/skills/" 2>/dev/null || true
|
|
1487
|
+
log_success "Skills copied to ~/.hermes/skills/"
|
|
1488
|
+
fi
|
|
1489
|
+
fi
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
find_system_browser() {
|
|
1493
|
+
# Prefer a user-specified browser path, then common Linux/macOS Chrome and
|
|
1494
|
+
# Chromium command names. Arch-family distributions commonly ship plain
|
|
1495
|
+
# `chromium`, while Debian-family systems often use `chromium-browser`.
|
|
1496
|
+
if [ -n "${AGENT_BROWSER_EXECUTABLE_PATH:-}" ]; then
|
|
1497
|
+
if [ -x "$AGENT_BROWSER_EXECUTABLE_PATH" ]; then
|
|
1498
|
+
echo "$AGENT_BROWSER_EXECUTABLE_PATH"
|
|
1499
|
+
return 0
|
|
1500
|
+
fi
|
|
1501
|
+
if command -v "$AGENT_BROWSER_EXECUTABLE_PATH" >/dev/null 2>&1; then
|
|
1502
|
+
command -v "$AGENT_BROWSER_EXECUTABLE_PATH"
|
|
1503
|
+
return 0
|
|
1504
|
+
fi
|
|
1505
|
+
fi
|
|
1506
|
+
|
|
1507
|
+
local candidate
|
|
1508
|
+
for candidate in google-chrome google-chrome-stable chromium chromium-browser chrome; do
|
|
1509
|
+
if command -v "$candidate" >/dev/null 2>&1; then
|
|
1510
|
+
command -v "$candidate"
|
|
1511
|
+
return 0
|
|
1512
|
+
fi
|
|
1513
|
+
done
|
|
1514
|
+
|
|
1515
|
+
return 1
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
run_browser_install_with_timeout() {
|
|
1519
|
+
local timeout_seconds="$1"
|
|
1520
|
+
shift
|
|
1521
|
+
|
|
1522
|
+
if command -v timeout >/dev/null 2>&1; then
|
|
1523
|
+
timeout "$timeout_seconds" "$@"
|
|
1524
|
+
else
|
|
1525
|
+
"$@"
|
|
1526
|
+
fi
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
configure_browser_env_from_system_browser() {
|
|
1530
|
+
local env_file="$HERMES_HOME/.env"
|
|
1531
|
+
local browser_path="${DETECTED_BROWSER_EXECUTABLE:-}"
|
|
1532
|
+
|
|
1533
|
+
if [ -z "$browser_path" ]; then
|
|
1534
|
+
browser_path="$(find_system_browser 2>/dev/null || true)"
|
|
1535
|
+
fi
|
|
1536
|
+
|
|
1537
|
+
if [ -z "$browser_path" ] || [ ! -f "$env_file" ]; then
|
|
1538
|
+
return 0
|
|
1539
|
+
fi
|
|
1540
|
+
|
|
1541
|
+
if grep -q '^AGENT_BROWSER_EXECUTABLE_PATH=' "$env_file" 2>/dev/null; then
|
|
1542
|
+
log_info "AGENT_BROWSER_EXECUTABLE_PATH already configured"
|
|
1543
|
+
return 0
|
|
1544
|
+
fi
|
|
1545
|
+
|
|
1546
|
+
{
|
|
1547
|
+
echo ""
|
|
1548
|
+
echo "# Hermes Agent browser tools — use the system Chrome/Chromium binary."
|
|
1549
|
+
echo "AGENT_BROWSER_EXECUTABLE_PATH=$browser_path"
|
|
1550
|
+
} >> "$env_file"
|
|
1551
|
+
log_success "Configured browser tools to use $browser_path"
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
install_node_deps() {
|
|
1555
|
+
if [ "$HAS_NODE" = false ]; then
|
|
1556
|
+
log_info "Skipping Node.js dependencies (Node not installed)"
|
|
1557
|
+
return 0
|
|
1558
|
+
fi
|
|
1559
|
+
|
|
1560
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1561
|
+
log_info "Skipping automatic Node/browser dependency setup on Termux"
|
|
1562
|
+
log_info "Browser automation is not part of the tested Termux install path yet."
|
|
1563
|
+
log_info "If you want to experiment manually later, run: cd $INSTALL_DIR && npm install"
|
|
1564
|
+
return 0
|
|
1565
|
+
fi
|
|
1566
|
+
|
|
1567
|
+
if [ -f "$INSTALL_DIR/package.json" ]; then
|
|
1568
|
+
log_info "Installing Node.js dependencies (browser tools)..."
|
|
1569
|
+
cd "$INSTALL_DIR"
|
|
1570
|
+
npm install --silent 2>/dev/null || {
|
|
1571
|
+
log_warn "npm install failed (browser tools may not work)"
|
|
1572
|
+
}
|
|
1573
|
+
log_success "Node.js dependencies installed"
|
|
1574
|
+
|
|
1575
|
+
# Install Playwright browser + system dependencies.
|
|
1576
|
+
# Playwright's --with-deps only supports apt-based systems natively.
|
|
1577
|
+
# For Arch/Manjaro we install the system libs via pacman first.
|
|
1578
|
+
# Other systems must install Chromium dependencies manually.
|
|
1579
|
+
if [ "$SKIP_BROWSER" = true ]; then
|
|
1580
|
+
log_info "Skipping Playwright/Chromium install (--skip-browser)"
|
|
1581
|
+
log_info "Browser tools will be unavailable until you run manually:"
|
|
1582
|
+
log_info " cd $INSTALL_DIR && npx playwright install chromium"
|
|
1583
|
+
log_info "On apt-based systems, an admin also needs to run:"
|
|
1584
|
+
log_info " sudo npx playwright install-deps chromium"
|
|
1585
|
+
else
|
|
1586
|
+
log_info "Installing browser engine (Playwright Chromium)..."
|
|
1587
|
+
DETECTED_BROWSER_EXECUTABLE="$(find_system_browser 2>/dev/null || true)"
|
|
1588
|
+
if [ -n "$DETECTED_BROWSER_EXECUTABLE" ]; then
|
|
1589
|
+
log_success "Found system Chrome/Chromium at $DETECTED_BROWSER_EXECUTABLE"
|
|
1590
|
+
log_info "Skipping Playwright browser download; Hermes will use the system browser."
|
|
1591
|
+
else
|
|
1592
|
+
case "$DISTRO" in
|
|
1593
|
+
ubuntu|debian|raspbian|pop|linuxmint|elementary|zorin|kali|parrot)
|
|
1594
|
+
# Use --with-deps only when sudo is available non-interactively
|
|
1595
|
+
# (root, or a user with passwordless sudo). Non-sudo users
|
|
1596
|
+
# — typical for systemd service accounts and unprivileged
|
|
1597
|
+
# operator users — would otherwise get blocked on an
|
|
1598
|
+
# interactive sudo prompt that they can't satisfy. Fall back
|
|
1599
|
+
# to the browser-only install in that case, and print the
|
|
1600
|
+
# exact command the admin needs to run separately.
|
|
1601
|
+
if [ "$(id -u)" -eq 0 ] || (command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null); then
|
|
1602
|
+
log_info "Installing Playwright Chromium with system dependencies..."
|
|
1603
|
+
cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install --with-deps chromium 2>/dev/null || {
|
|
1604
|
+
log_warn "Playwright browser installation failed — browser tools will not work."
|
|
1605
|
+
log_warn "Try running manually: cd $INSTALL_DIR && npx playwright install --with-deps chromium"
|
|
1606
|
+
}
|
|
1607
|
+
else
|
|
1608
|
+
log_warn "No sudo available — skipping system-library install (--with-deps)."
|
|
1609
|
+
log_info "Ask an administrator to run, one time, as root:"
|
|
1610
|
+
log_info " sudo npx playwright install-deps chromium"
|
|
1611
|
+
log_info " (from $INSTALL_DIR, after Node.js deps are installed)"
|
|
1612
|
+
log_info "Installing Chromium binary into this user's Playwright cache..."
|
|
1613
|
+
cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install chromium 2>/dev/null || {
|
|
1614
|
+
log_warn "Playwright browser installation failed — browser tools will not work."
|
|
1615
|
+
log_warn "Try running manually: cd $INSTALL_DIR && npx playwright install chromium"
|
|
1616
|
+
}
|
|
1617
|
+
fi
|
|
1618
|
+
;;
|
|
1619
|
+
arch|manjaro|cachyos|endeavouros|garuda)
|
|
1620
|
+
if command -v pacman &> /dev/null; then
|
|
1621
|
+
log_info "Arch-family distro detected — installing Chromium system dependencies via pacman..."
|
|
1622
|
+
if command -v sudo &> /dev/null && sudo -n true 2>/dev/null; then
|
|
1623
|
+
sudo NEEDRESTART_MODE=a pacman -S --noconfirm --needed \
|
|
1624
|
+
nss atk at-spi2-core cups libdrm libxkbcommon mesa pango cairo alsa-lib >/dev/null 2>&1 || true
|
|
1625
|
+
elif [ "$(id -u)" -eq 0 ]; then
|
|
1626
|
+
pacman -S --noconfirm --needed \
|
|
1627
|
+
nss atk at-spi2-core cups libdrm libxkbcommon mesa pango cairo alsa-lib >/dev/null 2>&1 || true
|
|
1628
|
+
else
|
|
1629
|
+
log_warn "Cannot install browser deps without sudo. Run manually:"
|
|
1630
|
+
log_warn " sudo pacman -S nss atk at-spi2-core cups libdrm libxkbcommon mesa pango cairo alsa-lib"
|
|
1631
|
+
fi
|
|
1632
|
+
fi
|
|
1633
|
+
cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install chromium 2>/dev/null || {
|
|
1634
|
+
log_warn "Playwright browser installation failed — browser tools will not work."
|
|
1635
|
+
}
|
|
1636
|
+
;;
|
|
1637
|
+
fedora|rhel|centos|rocky|alma)
|
|
1638
|
+
log_warn "Playwright does not support automatic dependency installation on RPM-based systems."
|
|
1639
|
+
log_info "Install Chromium system dependencies manually before using browser tools:"
|
|
1640
|
+
log_info " sudo dnf install nss atk at-spi2-core cups-libs libdrm libxkbcommon mesa-libgbm pango cairo alsa-lib"
|
|
1641
|
+
cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install chromium 2>/dev/null || {
|
|
1642
|
+
log_warn "Playwright browser installation failed — install dependencies above and retry."
|
|
1643
|
+
}
|
|
1644
|
+
;;
|
|
1645
|
+
opensuse*|sles)
|
|
1646
|
+
log_warn "Playwright does not support automatic dependency installation on zypper-based systems."
|
|
1647
|
+
log_info "Install Chromium system dependencies manually before using browser tools:"
|
|
1648
|
+
log_info " sudo zypper install mozilla-nss libatk-1_0-0 at-spi2-core cups-libs libdrm2 libxkbcommon0 Mesa-libgbm1 pango cairo libasound2"
|
|
1649
|
+
cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install chromium 2>/dev/null || {
|
|
1650
|
+
log_warn "Playwright browser installation failed — install dependencies above and retry."
|
|
1651
|
+
}
|
|
1652
|
+
;;
|
|
1653
|
+
*)
|
|
1654
|
+
log_warn "Playwright does not support automatic dependency installation on $DISTRO."
|
|
1655
|
+
log_info "Install Chromium/browser system dependencies for your distribution, then run:"
|
|
1656
|
+
log_info " cd $INSTALL_DIR && npx playwright install chromium"
|
|
1657
|
+
log_info "Browser tools will not work until dependencies are installed."
|
|
1658
|
+
cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install chromium 2>/dev/null || true
|
|
1659
|
+
;;
|
|
1660
|
+
esac
|
|
1661
|
+
fi
|
|
1662
|
+
fi
|
|
1663
|
+
log_success "Browser engine setup complete"
|
|
1664
|
+
fi
|
|
1665
|
+
|
|
1666
|
+
# Install TUI dependencies
|
|
1667
|
+
if [ -f "$INSTALL_DIR/ui-tui/package.json" ]; then
|
|
1668
|
+
log_info "Installing TUI dependencies..."
|
|
1669
|
+
cd "$INSTALL_DIR/ui-tui"
|
|
1670
|
+
npm install --silent 2>/dev/null || {
|
|
1671
|
+
log_warn "TUI npm install failed (hermes --tui may not work)"
|
|
1672
|
+
}
|
|
1673
|
+
log_success "TUI dependencies installed"
|
|
1674
|
+
fi
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
run_setup_wizard() {
|
|
1680
|
+
if [ "$RUN_SETUP" = false ]; then
|
|
1681
|
+
log_info "Skipping setup wizard (--skip-setup)"
|
|
1682
|
+
return 0
|
|
1683
|
+
fi
|
|
1684
|
+
|
|
1685
|
+
# The setup wizard reads from /dev/tty, so it works even when the
|
|
1686
|
+
# install script itself is piped (curl | bash). Only skip if no
|
|
1687
|
+
# terminal is available at all (e.g. Docker build, CI).
|
|
1688
|
+
#
|
|
1689
|
+
# Probe by actually opening /dev/tty: a bare existence test passes
|
|
1690
|
+
# in Docker builds where the device node is in the mount namespace
|
|
1691
|
+
# but opening fails with ENXIO, so the wizard would proceed and
|
|
1692
|
+
# then crash on `< /dev/tty` below.
|
|
1693
|
+
if ! (: </dev/tty) 2>/dev/null; then
|
|
1694
|
+
log_info "Setup wizard skipped (no terminal available). Run 'hermes setup' after install."
|
|
1695
|
+
return 0
|
|
1696
|
+
fi
|
|
1697
|
+
|
|
1698
|
+
echo ""
|
|
1699
|
+
log_info "Starting setup wizard..."
|
|
1700
|
+
echo ""
|
|
1701
|
+
|
|
1702
|
+
cd "$INSTALL_DIR"
|
|
1703
|
+
|
|
1704
|
+
# Run hermes setup using the venv Python directly (no activation needed).
|
|
1705
|
+
# Redirect stdin from /dev/tty so interactive prompts work when piped from curl.
|
|
1706
|
+
if [ "$USE_VENV" = true ]; then
|
|
1707
|
+
"$INSTALL_DIR/venv/bin/python" -m hermes_cli.main setup < /dev/tty
|
|
1708
|
+
else
|
|
1709
|
+
python -m hermes_cli.main setup < /dev/tty
|
|
1710
|
+
fi
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
maybe_start_gateway() {
|
|
1714
|
+
# Check if any messaging platform tokens were configured
|
|
1715
|
+
ENV_FILE="$HERMES_HOME/.env"
|
|
1716
|
+
if [ ! -f "$ENV_FILE" ]; then
|
|
1717
|
+
return 0
|
|
1718
|
+
fi
|
|
1719
|
+
|
|
1720
|
+
HAS_MESSAGING=false
|
|
1721
|
+
for VAR in TELEGRAM_BOT_TOKEN DISCORD_BOT_TOKEN SLACK_BOT_TOKEN SLACK_APP_TOKEN WHATSAPP_ENABLED; do
|
|
1722
|
+
VAL=$(grep "^${VAR}=" "$ENV_FILE" 2>/dev/null | cut -d'=' -f2-)
|
|
1723
|
+
if [ -n "$VAL" ] && [ "$VAL" != "your-token-here" ]; then
|
|
1724
|
+
HAS_MESSAGING=true
|
|
1725
|
+
break
|
|
1726
|
+
fi
|
|
1727
|
+
done
|
|
1728
|
+
|
|
1729
|
+
if [ "$HAS_MESSAGING" = false ]; then
|
|
1730
|
+
return 0
|
|
1731
|
+
fi
|
|
1732
|
+
|
|
1733
|
+
echo ""
|
|
1734
|
+
log_info "Messaging platform token detected!"
|
|
1735
|
+
log_info "The gateway needs to be running for Hermes to send/receive messages."
|
|
1736
|
+
|
|
1737
|
+
# If WhatsApp is enabled and no session exists yet, run foreground first for QR scan
|
|
1738
|
+
WHATSAPP_VAL=$(grep "^WHATSAPP_ENABLED=" "$ENV_FILE" 2>/dev/null | cut -d'=' -f2-)
|
|
1739
|
+
WHATSAPP_SESSION="$HERMES_HOME/whatsapp/session/creds.json"
|
|
1740
|
+
if [ "$WHATSAPP_VAL" = "true" ] && [ ! -f "$WHATSAPP_SESSION" ]; then
|
|
1741
|
+
if [ "$IS_INTERACTIVE" = true ]; then
|
|
1742
|
+
echo ""
|
|
1743
|
+
log_info "WhatsApp is enabled but not yet paired."
|
|
1744
|
+
log_info "Running 'hermes whatsapp' to pair via QR code..."
|
|
1745
|
+
echo ""
|
|
1746
|
+
if prompt_yes_no "Pair WhatsApp now?" "yes"; then
|
|
1747
|
+
HERMES_CMD="$(get_hermes_command_path)"
|
|
1748
|
+
$HERMES_CMD whatsapp || true
|
|
1749
|
+
fi
|
|
1750
|
+
else
|
|
1751
|
+
log_info "WhatsApp pairing skipped (non-interactive). Run 'hermes whatsapp' to pair."
|
|
1752
|
+
fi
|
|
1753
|
+
fi
|
|
1754
|
+
|
|
1755
|
+
# Probe by actually opening /dev/tty: a bare existence test passes
|
|
1756
|
+
# in Docker builds where the device node is in the mount namespace
|
|
1757
|
+
# but opening fails with ENXIO. See #16746.
|
|
1758
|
+
if ! (: </dev/tty) 2>/dev/null; then
|
|
1759
|
+
log_info "Gateway setup skipped (no terminal available). Run 'hermes gateway install' later."
|
|
1760
|
+
return 0
|
|
1761
|
+
fi
|
|
1762
|
+
|
|
1763
|
+
echo ""
|
|
1764
|
+
local should_install_gateway=false
|
|
1765
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1766
|
+
if prompt_yes_no "Would you like to start the gateway in the background?" "yes"; then
|
|
1767
|
+
should_install_gateway=true
|
|
1768
|
+
fi
|
|
1769
|
+
else
|
|
1770
|
+
if prompt_yes_no "Would you like to install the gateway as a background service?" "yes"; then
|
|
1771
|
+
should_install_gateway=true
|
|
1772
|
+
fi
|
|
1773
|
+
fi
|
|
1774
|
+
|
|
1775
|
+
if [ "$should_install_gateway" = true ]; then
|
|
1776
|
+
HERMES_CMD="$(get_hermes_command_path)"
|
|
1777
|
+
|
|
1778
|
+
if [ "$DISTRO" != "termux" ] && command -v systemctl &> /dev/null; then
|
|
1779
|
+
log_info "Installing systemd service..."
|
|
1780
|
+
if $HERMES_CMD gateway install 2>/dev/null; then
|
|
1781
|
+
log_success "Gateway service installed"
|
|
1782
|
+
if $HERMES_CMD gateway start 2>/dev/null; then
|
|
1783
|
+
log_success "Gateway started! Your bot is now online."
|
|
1784
|
+
else
|
|
1785
|
+
log_warn "Service installed but failed to start. Try: hermes gateway start"
|
|
1786
|
+
fi
|
|
1787
|
+
else
|
|
1788
|
+
log_warn "Systemd install failed. You can start manually: hermes gateway"
|
|
1789
|
+
fi
|
|
1790
|
+
else
|
|
1791
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1792
|
+
log_info "Termux detected — starting gateway in best-effort background mode..."
|
|
1793
|
+
else
|
|
1794
|
+
log_info "systemd not available — starting gateway in background..."
|
|
1795
|
+
fi
|
|
1796
|
+
nohup $HERMES_CMD gateway > "$HERMES_HOME/logs/gateway.log" 2>&1 &
|
|
1797
|
+
GATEWAY_PID=$!
|
|
1798
|
+
log_success "Gateway started (PID $GATEWAY_PID). Logs: ~/.hermes/logs/gateway.log"
|
|
1799
|
+
log_info "To stop: kill $GATEWAY_PID"
|
|
1800
|
+
log_info "To restart later: hermes gateway"
|
|
1801
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1802
|
+
log_warn "Android may stop background processes when Termux is suspended or the system reclaims resources."
|
|
1803
|
+
fi
|
|
1804
|
+
fi
|
|
1805
|
+
else
|
|
1806
|
+
log_info "Skipped. Start the gateway later with: hermes gateway"
|
|
1807
|
+
fi
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
print_success() {
|
|
1811
|
+
echo ""
|
|
1812
|
+
echo -e "${GREEN}${BOLD}"
|
|
1813
|
+
echo "┌─────────────────────────────────────────────────────────┐"
|
|
1814
|
+
echo "│ ✓ Installation Complete! │"
|
|
1815
|
+
echo "└─────────────────────────────────────────────────────────┘"
|
|
1816
|
+
echo -e "${NC}"
|
|
1817
|
+
echo ""
|
|
1818
|
+
|
|
1819
|
+
# Show file locations
|
|
1820
|
+
echo -e "${CYAN}${BOLD}📁 Your files:${NC}"
|
|
1821
|
+
echo ""
|
|
1822
|
+
echo -e " ${YELLOW}Config:${NC} $HERMES_HOME/config.yaml"
|
|
1823
|
+
echo -e " ${YELLOW}API Keys:${NC} $HERMES_HOME/.env"
|
|
1824
|
+
echo -e " ${YELLOW}Data:${NC} $HERMES_HOME/cron/, sessions/, logs/"
|
|
1825
|
+
echo -e " ${YELLOW}Code:${NC} $INSTALL_DIR"
|
|
1826
|
+
echo ""
|
|
1827
|
+
|
|
1828
|
+
echo -e "${CYAN}─────────────────────────────────────────────────────────${NC}"
|
|
1829
|
+
echo ""
|
|
1830
|
+
echo -e "${CYAN}${BOLD}🚀 Commands:${NC}"
|
|
1831
|
+
echo ""
|
|
1832
|
+
echo -e " ${GREEN}hermes${NC} Start chatting"
|
|
1833
|
+
echo -e " ${GREEN}hermes setup${NC} Configure API keys & settings"
|
|
1834
|
+
echo -e " ${GREEN}hermes config${NC} View/edit configuration"
|
|
1835
|
+
echo -e " ${GREEN}hermes config edit${NC} Open config in editor"
|
|
1836
|
+
echo -e " ${GREEN}hermes gateway install${NC} Install gateway service (messaging + cron)"
|
|
1837
|
+
echo -e " ${GREEN}hermes update${NC} Update to latest version"
|
|
1838
|
+
echo ""
|
|
1839
|
+
|
|
1840
|
+
echo -e "${CYAN}─────────────────────────────────────────────────────────${NC}"
|
|
1841
|
+
echo ""
|
|
1842
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1843
|
+
echo -e "${YELLOW}⚡ 'hermes' was linked into $(get_command_link_display_dir), which is already on PATH in Termux.${NC}"
|
|
1844
|
+
echo ""
|
|
1845
|
+
elif [ "$ROOT_FHS_LAYOUT" = true ]; then
|
|
1846
|
+
echo -e "${YELLOW}⚡ 'hermes' was linked into /usr/local/bin and is ready to use — no shell reload needed.${NC}"
|
|
1847
|
+
echo ""
|
|
1848
|
+
else
|
|
1849
|
+
echo -e "${YELLOW}⚡ Reload your shell to use 'hermes' command:${NC}"
|
|
1850
|
+
echo ""
|
|
1851
|
+
LOGIN_SHELL="$(basename "${SHELL:-/bin/bash}")"
|
|
1852
|
+
if [ "$LOGIN_SHELL" = "zsh" ]; then
|
|
1853
|
+
echo " source ~/.zshrc"
|
|
1854
|
+
elif [ "$LOGIN_SHELL" = "bash" ]; then
|
|
1855
|
+
echo " source ~/.bashrc"
|
|
1856
|
+
elif [ "$LOGIN_SHELL" = "fish" ]; then
|
|
1857
|
+
echo " source ~/.config/fish/config.fish"
|
|
1858
|
+
else
|
|
1859
|
+
echo " source ~/.bashrc # or ~/.zshrc"
|
|
1860
|
+
fi
|
|
1861
|
+
echo ""
|
|
1862
|
+
fi
|
|
1863
|
+
|
|
1864
|
+
# Show Node.js warning if auto-install failed
|
|
1865
|
+
if [ "$HAS_NODE" = false ]; then
|
|
1866
|
+
echo -e "${YELLOW}"
|
|
1867
|
+
echo "Note: Node.js could not be installed automatically."
|
|
1868
|
+
echo "Browser tools need Node.js. Install manually:"
|
|
1869
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1870
|
+
echo " pkg install nodejs"
|
|
1871
|
+
else
|
|
1872
|
+
echo " https://nodejs.org/en/download/"
|
|
1873
|
+
fi
|
|
1874
|
+
echo -e "${NC}"
|
|
1875
|
+
fi
|
|
1876
|
+
|
|
1877
|
+
# Show ripgrep note if not installed
|
|
1878
|
+
if [ "$HAS_RIPGREP" = false ]; then
|
|
1879
|
+
echo -e "${YELLOW}"
|
|
1880
|
+
echo "Note: ripgrep (rg) was not found. File search will use"
|
|
1881
|
+
echo "grep as a fallback. For faster search in large codebases,"
|
|
1882
|
+
if [ "$DISTRO" = "termux" ]; then
|
|
1883
|
+
echo "install ripgrep: pkg install ripgrep"
|
|
1884
|
+
else
|
|
1885
|
+
echo "install ripgrep: sudo apt install ripgrep (or brew install ripgrep)"
|
|
1886
|
+
fi
|
|
1887
|
+
echo -e "${NC}"
|
|
1888
|
+
fi
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
ensure_mode() {
|
|
1892
|
+
detect_os
|
|
1893
|
+
|
|
1894
|
+
IFS=',' read -ra DEPS <<< "$ENSURE_DEPS"
|
|
1895
|
+
for dep in "${DEPS[@]}"; do
|
|
1896
|
+
dep="$(echo "$dep" | tr -d '[:space:]')"
|
|
1897
|
+
case "$dep" in
|
|
1898
|
+
node)
|
|
1899
|
+
check_node
|
|
1900
|
+
;;
|
|
1901
|
+
browser)
|
|
1902
|
+
check_node
|
|
1903
|
+
if [ "$HAS_NODE" = true ]; then
|
|
1904
|
+
DETECTED_BROWSER_EXECUTABLE="$(find_system_browser 2>/dev/null || true)"
|
|
1905
|
+
if [ -z "$DETECTED_BROWSER_EXECUTABLE" ]; then
|
|
1906
|
+
log_info "Installing agent-browser + Chromium..."
|
|
1907
|
+
npm_bin="$(command -v npm 2>/dev/null || echo "")"
|
|
1908
|
+
if [ -n "$npm_bin" ]; then
|
|
1909
|
+
local agent_browser_dir="$HERMES_HOME/node_modules"
|
|
1910
|
+
mkdir -p "$agent_browser_dir"
|
|
1911
|
+
"$npm_bin" install --prefix "$HERMES_HOME" agent-browser 2>/dev/null || true
|
|
1912
|
+
npx playwright install chromium 2>/dev/null || true
|
|
1913
|
+
fi
|
|
1914
|
+
else
|
|
1915
|
+
log_success "System browser found: $DETECTED_BROWSER_EXECUTABLE"
|
|
1916
|
+
fi
|
|
1917
|
+
fi
|
|
1918
|
+
;;
|
|
1919
|
+
ripgrep)
|
|
1920
|
+
if ! command -v rg &>/dev/null; then
|
|
1921
|
+
HAS_RIPGREP=false
|
|
1922
|
+
HAS_FFMPEG=true
|
|
1923
|
+
install_system_packages
|
|
1924
|
+
fi
|
|
1925
|
+
;;
|
|
1926
|
+
ffmpeg)
|
|
1927
|
+
if ! command -v ffmpeg &>/dev/null; then
|
|
1928
|
+
HAS_FFMPEG=false
|
|
1929
|
+
HAS_RIPGREP=true
|
|
1930
|
+
install_system_packages
|
|
1931
|
+
fi
|
|
1932
|
+
;;
|
|
1933
|
+
*)
|
|
1934
|
+
log_warn "Unknown dependency: $dep"
|
|
1935
|
+
;;
|
|
1936
|
+
esac
|
|
1937
|
+
done
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
postinstall_mode() {
|
|
1941
|
+
print_banner
|
|
1942
|
+
detect_os
|
|
1943
|
+
|
|
1944
|
+
log_info "Post-install mode: setting up Hermes for pip install"
|
|
1945
|
+
|
|
1946
|
+
check_node
|
|
1947
|
+
check_network_prerequisites
|
|
1948
|
+
install_system_packages
|
|
1949
|
+
|
|
1950
|
+
if [ "$HAS_NODE" = true ] && [ "$SKIP_BROWSER" = false ]; then
|
|
1951
|
+
DETECTED_BROWSER_EXECUTABLE="$(find_system_browser 2>/dev/null || true)"
|
|
1952
|
+
if [ -z "$DETECTED_BROWSER_EXECUTABLE" ]; then
|
|
1953
|
+
log_info "Installing browser engine..."
|
|
1954
|
+
npm_bin="$(command -v npm 2>/dev/null || echo "")"
|
|
1955
|
+
if [ -n "$npm_bin" ]; then
|
|
1956
|
+
npx playwright install chromium 2>/dev/null || true
|
|
1957
|
+
fi
|
|
1958
|
+
else
|
|
1959
|
+
log_success "System browser found: $DETECTED_BROWSER_EXECUTABLE"
|
|
1960
|
+
fi
|
|
1961
|
+
fi
|
|
1962
|
+
|
|
1963
|
+
HERMES_CMD="$(command -v hermes 2>/dev/null || echo "")"
|
|
1964
|
+
if [ -n "$HERMES_CMD" ]; then
|
|
1965
|
+
log_info "Running hermes setup..."
|
|
1966
|
+
"$HERMES_CMD" setup
|
|
1967
|
+
else
|
|
1968
|
+
log_warn "hermes command not found on PATH"
|
|
1969
|
+
log_info "Try: python -m hermes_cli.main setup"
|
|
1970
|
+
fi
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
# ============================================================================
|
|
1974
|
+
# Main
|
|
1975
|
+
# ============================================================================
|
|
1976
|
+
|
|
1977
|
+
main() {
|
|
1978
|
+
print_banner
|
|
1979
|
+
|
|
1980
|
+
detect_os
|
|
1981
|
+
resolve_install_layout
|
|
1982
|
+
install_uv
|
|
1983
|
+
check_python
|
|
1984
|
+
check_git
|
|
1985
|
+
check_node
|
|
1986
|
+
check_network_prerequisites
|
|
1987
|
+
install_system_packages
|
|
1988
|
+
|
|
1989
|
+
clone_repo
|
|
1990
|
+
setup_venv
|
|
1991
|
+
install_deps
|
|
1992
|
+
install_node_deps
|
|
1993
|
+
setup_path
|
|
1994
|
+
copy_config_templates
|
|
1995
|
+
run_setup_wizard
|
|
1996
|
+
maybe_start_gateway
|
|
1997
|
+
|
|
1998
|
+
print_success
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
if [ -n "$ENSURE_DEPS" ]; then
|
|
2002
|
+
ensure_mode
|
|
2003
|
+
elif [ "$POSTINSTALL_MODE" = true ]; then
|
|
2004
|
+
postinstall_mode
|
|
2005
|
+
else
|
|
2006
|
+
main
|
|
2007
|
+
fi
|