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.
Files changed (1718) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +217 -0
  3. package/README.zh-CN.md +180 -0
  4. package/acp_adapter/__init__.py +1 -0
  5. package/acp_adapter/__main__.py +5 -0
  6. package/acp_adapter/auth.py +68 -0
  7. package/acp_adapter/bootstrap/__init__.py +0 -0
  8. package/acp_adapter/bootstrap/bootstrap_browser_tools.ps1 +288 -0
  9. package/acp_adapter/bootstrap/bootstrap_browser_tools.sh +399 -0
  10. package/acp_adapter/entry.py +292 -0
  11. package/acp_adapter/events.py +265 -0
  12. package/acp_adapter/permissions.py +148 -0
  13. package/acp_adapter/server.py +1713 -0
  14. package/acp_adapter/session.py +629 -0
  15. package/acp_adapter/tools.py +1180 -0
  16. package/agent/__init__.py +6 -0
  17. package/agent/__pycache__/__init__.cpython-312.pyc +0 -0
  18. package/agent/__pycache__/account_usage.cpython-312.pyc +0 -0
  19. package/agent/__pycache__/anthropic_adapter.cpython-312.pyc +0 -0
  20. package/agent/__pycache__/async_utils.cpython-312.pyc +0 -0
  21. package/agent/__pycache__/auxiliary_client.cpython-312.pyc +0 -0
  22. package/agent/__pycache__/codex_responses_adapter.cpython-312.pyc +0 -0
  23. package/agent/__pycache__/context_compressor.cpython-312.pyc +0 -0
  24. package/agent/__pycache__/context_engine.cpython-312.pyc +0 -0
  25. package/agent/__pycache__/context_references.cpython-312.pyc +0 -0
  26. package/agent/__pycache__/credential_pool.cpython-312.pyc +0 -0
  27. package/agent/__pycache__/curator.cpython-312.pyc +0 -0
  28. package/agent/__pycache__/display.cpython-312.pyc +0 -0
  29. package/agent/__pycache__/error_classifier.cpython-312.pyc +0 -0
  30. package/agent/__pycache__/file_safety.cpython-312.pyc +0 -0
  31. package/agent/__pycache__/google_code_assist.cpython-312.pyc +0 -0
  32. package/agent/__pycache__/google_oauth.cpython-312.pyc +0 -0
  33. package/agent/__pycache__/i18n.cpython-312.pyc +0 -0
  34. package/agent/__pycache__/image_gen_provider.cpython-312.pyc +0 -0
  35. package/agent/__pycache__/image_gen_registry.cpython-312.pyc +0 -0
  36. package/agent/__pycache__/insights.cpython-312.pyc +0 -0
  37. package/agent/__pycache__/lmstudio_reasoning.cpython-312.pyc +0 -0
  38. package/agent/__pycache__/manual_compression_feedback.cpython-312.pyc +0 -0
  39. package/agent/__pycache__/markdown_tables.cpython-312.pyc +0 -0
  40. package/agent/__pycache__/memory_manager.cpython-312.pyc +0 -0
  41. package/agent/__pycache__/memory_provider.cpython-312.pyc +0 -0
  42. package/agent/__pycache__/model_metadata.cpython-312.pyc +0 -0
  43. package/agent/__pycache__/models_dev.cpython-312.pyc +0 -0
  44. package/agent/__pycache__/moonshot_schema.cpython-312.pyc +0 -0
  45. package/agent/__pycache__/onboarding.cpython-312.pyc +0 -0
  46. package/agent/__pycache__/portal_tags.cpython-312.pyc +0 -0
  47. package/agent/__pycache__/prompt_builder.cpython-312.pyc +0 -0
  48. package/agent/__pycache__/prompt_caching.cpython-312.pyc +0 -0
  49. package/agent/__pycache__/redact.cpython-312.pyc +0 -0
  50. package/agent/__pycache__/retry_utils.cpython-312.pyc +0 -0
  51. package/agent/__pycache__/shell_hooks.cpython-312.pyc +0 -0
  52. package/agent/__pycache__/skill_commands.cpython-312.pyc +0 -0
  53. package/agent/__pycache__/skill_preprocessing.cpython-312.pyc +0 -0
  54. package/agent/__pycache__/skill_utils.cpython-312.pyc +0 -0
  55. package/agent/__pycache__/subdirectory_hints.cpython-312.pyc +0 -0
  56. package/agent/__pycache__/think_scrubber.cpython-312.pyc +0 -0
  57. package/agent/__pycache__/title_generator.cpython-312.pyc +0 -0
  58. package/agent/__pycache__/tool_guardrails.cpython-312.pyc +0 -0
  59. package/agent/__pycache__/tool_result_classification.cpython-312.pyc +0 -0
  60. package/agent/__pycache__/trajectory.cpython-312.pyc +0 -0
  61. package/agent/__pycache__/usage_pricing.cpython-312.pyc +0 -0
  62. package/agent/__pycache__/video_gen_provider.cpython-312.pyc +0 -0
  63. package/agent/__pycache__/video_gen_registry.cpython-312.pyc +0 -0
  64. package/agent/__pycache__/web_search_provider.cpython-312.pyc +0 -0
  65. package/agent/__pycache__/web_search_registry.cpython-312.pyc +0 -0
  66. package/agent/account_usage.py +326 -0
  67. package/agent/anthropic_adapter.py +2087 -0
  68. package/agent/async_utils.py +68 -0
  69. package/agent/auxiliary_client.py +4893 -0
  70. package/agent/bedrock_adapter.py +1276 -0
  71. package/agent/codex_responses_adapter.py +1084 -0
  72. package/agent/context_compressor.py +1583 -0
  73. package/agent/context_engine.py +211 -0
  74. package/agent/context_references.py +519 -0
  75. package/agent/copilot_acp_client.py +684 -0
  76. package/agent/credential_pool.py +1780 -0
  77. package/agent/credential_sources.py +449 -0
  78. package/agent/curator.py +1782 -0
  79. package/agent/curator_backup.py +694 -0
  80. package/agent/display.py +987 -0
  81. package/agent/error_classifier.py +1058 -0
  82. package/agent/file_safety.py +112 -0
  83. package/agent/gemini_cloudcode_adapter.py +909 -0
  84. package/agent/gemini_native_adapter.py +971 -0
  85. package/agent/gemini_schema.py +99 -0
  86. package/agent/google_code_assist.py +452 -0
  87. package/agent/google_oauth.py +1062 -0
  88. package/agent/i18n.py +258 -0
  89. package/agent/image_gen_provider.py +243 -0
  90. package/agent/image_gen_registry.py +145 -0
  91. package/agent/image_routing.py +301 -0
  92. package/agent/insights.py +931 -0
  93. package/agent/lmstudio_reasoning.py +48 -0
  94. package/agent/lsp/__init__.py +106 -0
  95. package/agent/lsp/__pycache__/__init__.cpython-312.pyc +0 -0
  96. package/agent/lsp/__pycache__/cli.cpython-312.pyc +0 -0
  97. package/agent/lsp/__pycache__/client.cpython-312.pyc +0 -0
  98. package/agent/lsp/__pycache__/eventlog.cpython-312.pyc +0 -0
  99. package/agent/lsp/__pycache__/manager.cpython-312.pyc +0 -0
  100. package/agent/lsp/__pycache__/protocol.cpython-312.pyc +0 -0
  101. package/agent/lsp/__pycache__/servers.cpython-312.pyc +0 -0
  102. package/agent/lsp/__pycache__/workspace.cpython-312.pyc +0 -0
  103. package/agent/lsp/cli.py +308 -0
  104. package/agent/lsp/client.py +930 -0
  105. package/agent/lsp/eventlog.py +213 -0
  106. package/agent/lsp/install.py +376 -0
  107. package/agent/lsp/manager.py +644 -0
  108. package/agent/lsp/protocol.py +196 -0
  109. package/agent/lsp/range_shift.py +149 -0
  110. package/agent/lsp/reporter.py +78 -0
  111. package/agent/lsp/servers.py +1040 -0
  112. package/agent/lsp/workspace.py +223 -0
  113. package/agent/manual_compression_feedback.py +49 -0
  114. package/agent/markdown_tables.py +309 -0
  115. package/agent/memory_manager.py +556 -0
  116. package/agent/memory_provider.py +279 -0
  117. package/agent/model_metadata.py +1827 -0
  118. package/agent/models_dev.py +724 -0
  119. package/agent/moonshot_schema.py +231 -0
  120. package/agent/nous_rate_guard.py +326 -0
  121. package/agent/onboarding.py +193 -0
  122. package/agent/plugin_llm.py +1046 -0
  123. package/agent/portal_tags.py +64 -0
  124. package/agent/prompt_builder.py +1457 -0
  125. package/agent/prompt_caching.py +79 -0
  126. package/agent/rate_limit_tracker.py +246 -0
  127. package/agent/redact.py +403 -0
  128. package/agent/retry_utils.py +57 -0
  129. package/agent/shell_hooks.py +837 -0
  130. package/agent/skill_commands.py +502 -0
  131. package/agent/skill_preprocessing.py +131 -0
  132. package/agent/skill_utils.py +512 -0
  133. package/agent/subdirectory_hints.py +224 -0
  134. package/agent/think_scrubber.py +386 -0
  135. package/agent/title_generator.py +171 -0
  136. package/agent/tool_guardrails.py +458 -0
  137. package/agent/tool_result_classification.py +26 -0
  138. package/agent/trajectory.py +56 -0
  139. package/agent/transports/__init__.py +68 -0
  140. package/agent/transports/__pycache__/__init__.cpython-312.pyc +0 -0
  141. package/agent/transports/__pycache__/anthropic.cpython-312.pyc +0 -0
  142. package/agent/transports/__pycache__/base.cpython-312.pyc +0 -0
  143. package/agent/transports/__pycache__/bedrock.cpython-312.pyc +0 -0
  144. package/agent/transports/__pycache__/chat_completions.cpython-312.pyc +0 -0
  145. package/agent/transports/__pycache__/codex.cpython-312.pyc +0 -0
  146. package/agent/transports/__pycache__/types.cpython-312.pyc +0 -0
  147. package/agent/transports/anthropic.py +179 -0
  148. package/agent/transports/base.py +89 -0
  149. package/agent/transports/bedrock.py +154 -0
  150. package/agent/transports/chat_completions.py +614 -0
  151. package/agent/transports/codex.py +283 -0
  152. package/agent/transports/codex_app_server.py +368 -0
  153. package/agent/transports/codex_app_server_session.py +810 -0
  154. package/agent/transports/codex_event_projector.py +312 -0
  155. package/agent/transports/hermes_tools_mcp_server.py +233 -0
  156. package/agent/transports/types.py +162 -0
  157. package/agent/usage_pricing.py +877 -0
  158. package/agent/video_gen_provider.py +300 -0
  159. package/agent/video_gen_registry.py +117 -0
  160. package/agent/web_search_provider.py +221 -0
  161. package/agent/web_search_registry.py +262 -0
  162. package/assets/banner.png +0 -0
  163. package/batch_runner.py +1303 -0
  164. package/bin/calvyn.js +67 -0
  165. package/calvyn_bootstrap.py +130 -0
  166. package/calvyn_constants.py +346 -0
  167. package/calvyn_logging.py +390 -0
  168. package/calvyn_state.py +2967 -0
  169. package/calvyn_time.py +105 -0
  170. package/cli.py +14160 -0
  171. package/cron/__init__.py +42 -0
  172. package/cron/__pycache__/__init__.cpython-312.pyc +0 -0
  173. package/cron/__pycache__/jobs.cpython-312.pyc +0 -0
  174. package/cron/__pycache__/scheduler.cpython-312.pyc +0 -0
  175. package/cron/jobs.py +1160 -0
  176. package/cron/scheduler.py +1832 -0
  177. package/gateway/__init__.py +35 -0
  178. package/gateway/__pycache__/__init__.cpython-312.pyc +0 -0
  179. package/gateway/__pycache__/channel_directory.cpython-312.pyc +0 -0
  180. package/gateway/__pycache__/config.cpython-312.pyc +0 -0
  181. package/gateway/__pycache__/delivery.cpython-312.pyc +0 -0
  182. package/gateway/__pycache__/display_config.cpython-312.pyc +0 -0
  183. package/gateway/__pycache__/hooks.cpython-312.pyc +0 -0
  184. package/gateway/__pycache__/pairing.cpython-312.pyc +0 -0
  185. package/gateway/__pycache__/platform_registry.cpython-312.pyc +0 -0
  186. package/gateway/__pycache__/restart.cpython-312.pyc +0 -0
  187. package/gateway/__pycache__/run.cpython-312.pyc +0 -0
  188. package/gateway/__pycache__/runtime_footer.cpython-312.pyc +0 -0
  189. package/gateway/__pycache__/session.cpython-312.pyc +0 -0
  190. package/gateway/__pycache__/session_context.cpython-312.pyc +0 -0
  191. package/gateway/__pycache__/shutdown_forensics.cpython-312.pyc +0 -0
  192. package/gateway/__pycache__/slash_access.cpython-312.pyc +0 -0
  193. package/gateway/__pycache__/status.cpython-312.pyc +0 -0
  194. package/gateway/__pycache__/stream_consumer.cpython-312.pyc +0 -0
  195. package/gateway/__pycache__/whatsapp_identity.cpython-312.pyc +0 -0
  196. package/gateway/assets/telegram-botfather-threads-settings.jpg +0 -0
  197. package/gateway/builtin_hooks/__init__.py +1 -0
  198. package/gateway/channel_directory.py +357 -0
  199. package/gateway/config.py +1873 -0
  200. package/gateway/delivery.py +258 -0
  201. package/gateway/display_config.py +206 -0
  202. package/gateway/hooks.py +210 -0
  203. package/gateway/mirror.py +179 -0
  204. package/gateway/pairing.py +322 -0
  205. package/gateway/platform_registry.py +260 -0
  206. package/gateway/platforms/ADDING_A_PLATFORM.md +374 -0
  207. package/gateway/platforms/__init__.py +45 -0
  208. package/gateway/platforms/__pycache__/__init__.cpython-312.pyc +0 -0
  209. package/gateway/platforms/__pycache__/base.cpython-312.pyc +0 -0
  210. package/gateway/platforms/__pycache__/helpers.cpython-312.pyc +0 -0
  211. package/gateway/platforms/__pycache__/telegram.cpython-312.pyc +0 -0
  212. package/gateway/platforms/__pycache__/telegram_network.cpython-312.pyc +0 -0
  213. package/gateway/platforms/__pycache__/yuanbao.cpython-312.pyc +0 -0
  214. package/gateway/platforms/__pycache__/yuanbao_media.cpython-312.pyc +0 -0
  215. package/gateway/platforms/__pycache__/yuanbao_proto.cpython-312.pyc +0 -0
  216. package/gateway/platforms/_http_client_limits.py +84 -0
  217. package/gateway/platforms/api_server.py +3488 -0
  218. package/gateway/platforms/base.py +3747 -0
  219. package/gateway/platforms/bluebubbles.py +937 -0
  220. package/gateway/platforms/dingtalk.py +1473 -0
  221. package/gateway/platforms/discord.py +5584 -0
  222. package/gateway/platforms/email.py +773 -0
  223. package/gateway/platforms/feishu.py +5059 -0
  224. package/gateway/platforms/feishu_comment.py +1382 -0
  225. package/gateway/platforms/feishu_comment_rules.py +430 -0
  226. package/gateway/platforms/helpers.py +279 -0
  227. package/gateway/platforms/homeassistant.py +449 -0
  228. package/gateway/platforms/matrix.py +2777 -0
  229. package/gateway/platforms/mattermost.py +852 -0
  230. package/gateway/platforms/msgraph_webhook.py +397 -0
  231. package/gateway/platforms/qqbot/__init__.py +91 -0
  232. package/gateway/platforms/qqbot/adapter.py +3072 -0
  233. package/gateway/platforms/qqbot/chunked_upload.py +602 -0
  234. package/gateway/platforms/qqbot/constants.py +74 -0
  235. package/gateway/platforms/qqbot/crypto.py +45 -0
  236. package/gateway/platforms/qqbot/keyboards.py +473 -0
  237. package/gateway/platforms/qqbot/onboard.py +220 -0
  238. package/gateway/platforms/qqbot/utils.py +71 -0
  239. package/gateway/platforms/signal.py +1518 -0
  240. package/gateway/platforms/signal_rate_limit.py +369 -0
  241. package/gateway/platforms/slack.py +3028 -0
  242. package/gateway/platforms/sms.py +377 -0
  243. package/gateway/platforms/telegram.py +4836 -0
  244. package/gateway/platforms/telegram_network.py +249 -0
  245. package/gateway/platforms/webhook.py +806 -0
  246. package/gateway/platforms/wecom.py +1610 -0
  247. package/gateway/platforms/wecom_callback.py +403 -0
  248. package/gateway/platforms/wecom_crypto.py +142 -0
  249. package/gateway/platforms/weixin.py +2170 -0
  250. package/gateway/platforms/whatsapp.py +1283 -0
  251. package/gateway/platforms/yuanbao.py +4873 -0
  252. package/gateway/platforms/yuanbao_media.py +645 -0
  253. package/gateway/platforms/yuanbao_proto.py +1209 -0
  254. package/gateway/platforms/yuanbao_sticker.py +558 -0
  255. package/gateway/restart.py +20 -0
  256. package/gateway/run.py +17074 -0
  257. package/gateway/runtime_footer.py +150 -0
  258. package/gateway/session.py +1399 -0
  259. package/gateway/session_context.py +156 -0
  260. package/gateway/shutdown_forensics.py +462 -0
  261. package/gateway/slash_access.py +229 -0
  262. package/gateway/status.py +972 -0
  263. package/gateway/sticker_cache.py +111 -0
  264. package/gateway/stream_consumer.py +1286 -0
  265. package/gateway/whatsapp_identity.py +156 -0
  266. package/hermes_cli/__init__.py +47 -0
  267. package/hermes_cli/__pycache__/__init__.cpython-312.pyc +0 -0
  268. package/hermes_cli/__pycache__/_parser.cpython-312.pyc +0 -0
  269. package/hermes_cli/__pycache__/auth.cpython-312.pyc +0 -0
  270. package/hermes_cli/__pycache__/banner.cpython-312.pyc +0 -0
  271. package/hermes_cli/__pycache__/browser_connect.cpython-312.pyc +0 -0
  272. package/hermes_cli/__pycache__/callbacks.cpython-312.pyc +0 -0
  273. package/hermes_cli/__pycache__/checkpoints.cpython-312.pyc +0 -0
  274. package/hermes_cli/__pycache__/cli_output.cpython-312.pyc +0 -0
  275. package/hermes_cli/__pycache__/codex_models.cpython-312.pyc +0 -0
  276. package/hermes_cli/__pycache__/codex_runtime_switch.cpython-312.pyc +0 -0
  277. package/hermes_cli/__pycache__/colors.cpython-312.pyc +0 -0
  278. package/hermes_cli/__pycache__/commands.cpython-312.pyc +0 -0
  279. package/hermes_cli/__pycache__/config.cpython-312.pyc +0 -0
  280. package/hermes_cli/__pycache__/copilot_auth.cpython-312.pyc +0 -0
  281. package/hermes_cli/__pycache__/curator.cpython-312.pyc +0 -0
  282. package/hermes_cli/__pycache__/curses_ui.cpython-312.pyc +0 -0
  283. package/hermes_cli/__pycache__/debug.cpython-312.pyc +0 -0
  284. package/hermes_cli/__pycache__/default_soul.cpython-312.pyc +0 -0
  285. package/hermes_cli/__pycache__/env_loader.cpython-312.pyc +0 -0
  286. package/hermes_cli/__pycache__/fallback_cmd.cpython-312.pyc +0 -0
  287. package/hermes_cli/__pycache__/gateway.cpython-312.pyc +0 -0
  288. package/hermes_cli/__pycache__/gateway_windows.cpython-312.pyc +0 -0
  289. package/hermes_cli/__pycache__/goals.cpython-312.pyc +0 -0
  290. package/hermes_cli/__pycache__/inventory.cpython-312.pyc +0 -0
  291. package/hermes_cli/__pycache__/kanban.cpython-312.pyc +0 -0
  292. package/hermes_cli/__pycache__/kanban_db.cpython-312.pyc +0 -0
  293. package/hermes_cli/__pycache__/main.cpython-312.pyc +0 -0
  294. package/hermes_cli/__pycache__/model_catalog.cpython-312.pyc +0 -0
  295. package/hermes_cli/__pycache__/model_normalize.cpython-312.pyc +0 -0
  296. package/hermes_cli/__pycache__/model_switch.cpython-312.pyc +0 -0
  297. package/hermes_cli/__pycache__/models.cpython-312.pyc +0 -0
  298. package/hermes_cli/__pycache__/nous_subscription.cpython-312.pyc +0 -0
  299. package/hermes_cli/__pycache__/pairing.cpython-312.pyc +0 -0
  300. package/hermes_cli/__pycache__/platforms.cpython-312.pyc +0 -0
  301. package/hermes_cli/__pycache__/plugins.cpython-312.pyc +0 -0
  302. package/hermes_cli/__pycache__/profiles.cpython-312.pyc +0 -0
  303. package/hermes_cli/__pycache__/providers.cpython-312.pyc +0 -0
  304. package/hermes_cli/__pycache__/pt_input_extras.cpython-312.pyc +0 -0
  305. package/hermes_cli/__pycache__/runtime_provider.cpython-312.pyc +0 -0
  306. package/hermes_cli/__pycache__/security_advisories.cpython-312.pyc +0 -0
  307. package/hermes_cli/__pycache__/setup.cpython-312.pyc +0 -0
  308. package/hermes_cli/__pycache__/skills_hub.cpython-312.pyc +0 -0
  309. package/hermes_cli/__pycache__/skin_engine.cpython-312.pyc +0 -0
  310. package/hermes_cli/__pycache__/stdio.cpython-312.pyc +0 -0
  311. package/hermes_cli/__pycache__/timeouts.cpython-312.pyc +0 -0
  312. package/hermes_cli/__pycache__/tips.cpython-312.pyc +0 -0
  313. package/hermes_cli/__pycache__/tools_config.cpython-312.pyc +0 -0
  314. package/hermes_cli/__pycache__/voice.cpython-312.pyc +0 -0
  315. package/hermes_cli/_parser.py +365 -0
  316. package/hermes_cli/_subprocess_compat.py +175 -0
  317. package/hermes_cli/auth.py +6299 -0
  318. package/hermes_cli/auth_commands.py +749 -0
  319. package/hermes_cli/azure_detect.py +300 -0
  320. package/hermes_cli/backup.py +938 -0
  321. package/hermes_cli/banner.py +703 -0
  322. package/hermes_cli/browser_connect.py +139 -0
  323. package/hermes_cli/callbacks.py +243 -0
  324. package/hermes_cli/checkpoints.py +244 -0
  325. package/hermes_cli/claw.py +810 -0
  326. package/hermes_cli/cli_output.py +78 -0
  327. package/hermes_cli/clipboard.py +495 -0
  328. package/hermes_cli/codex_models.py +198 -0
  329. package/hermes_cli/codex_runtime_plugin_migration.py +757 -0
  330. package/hermes_cli/codex_runtime_switch.py +266 -0
  331. package/hermes_cli/colors.py +38 -0
  332. package/hermes_cli/commands.py +1728 -0
  333. package/hermes_cli/completion.py +315 -0
  334. package/hermes_cli/config.py +5382 -0
  335. package/hermes_cli/copilot_auth.py +392 -0
  336. package/hermes_cli/cron.py +313 -0
  337. package/hermes_cli/curator.py +598 -0
  338. package/hermes_cli/curses_ui.py +472 -0
  339. package/hermes_cli/debug.py +747 -0
  340. package/hermes_cli/default_soul.py +11 -0
  341. package/hermes_cli/dep_ensure.py +107 -0
  342. package/hermes_cli/dingtalk_auth.py +293 -0
  343. package/hermes_cli/doctor.py +1863 -0
  344. package/hermes_cli/dump.py +326 -0
  345. package/hermes_cli/env_loader.py +175 -0
  346. package/hermes_cli/fallback_cmd.py +361 -0
  347. package/hermes_cli/gateway.py +5422 -0
  348. package/hermes_cli/gateway_windows.py +692 -0
  349. package/hermes_cli/goals.py +757 -0
  350. package/hermes_cli/hooks.py +385 -0
  351. package/hermes_cli/inventory.py +240 -0
  352. package/hermes_cli/kanban.py +2252 -0
  353. package/hermes_cli/kanban_db.py +4840 -0
  354. package/hermes_cli/kanban_diagnostics.py +776 -0
  355. package/hermes_cli/kanban_specify.py +266 -0
  356. package/hermes_cli/logs.py +391 -0
  357. package/hermes_cli/main.py +12396 -0
  358. package/hermes_cli/mcp_config.py +781 -0
  359. package/hermes_cli/memory_setup.py +465 -0
  360. package/hermes_cli/model_catalog.py +330 -0
  361. package/hermes_cli/model_normalize.py +473 -0
  362. package/hermes_cli/model_switch.py +1777 -0
  363. package/hermes_cli/models.py +3789 -0
  364. package/hermes_cli/nous_subscription.py +799 -0
  365. package/hermes_cli/oneshot.py +351 -0
  366. package/hermes_cli/pairing.py +115 -0
  367. package/hermes_cli/platforms.py +83 -0
  368. package/hermes_cli/plugins.py +1562 -0
  369. package/hermes_cli/plugins_cmd.py +1587 -0
  370. package/hermes_cli/profile_distribution.py +703 -0
  371. package/hermes_cli/profiles.py +1319 -0
  372. package/hermes_cli/providers.py +720 -0
  373. package/hermes_cli/proxy/__init__.py +20 -0
  374. package/hermes_cli/proxy/adapters/__init__.py +35 -0
  375. package/hermes_cli/proxy/adapters/base.py +94 -0
  376. package/hermes_cli/proxy/adapters/nous_portal.py +137 -0
  377. package/hermes_cli/proxy/cli.py +141 -0
  378. package/hermes_cli/proxy/server.py +265 -0
  379. package/hermes_cli/pt_input_extras.py +83 -0
  380. package/hermes_cli/pty_bridge.py +237 -0
  381. package/hermes_cli/relaunch.py +205 -0
  382. package/hermes_cli/runtime_provider.py +1428 -0
  383. package/hermes_cli/security_advisories.py +452 -0
  384. package/hermes_cli/setup.py +3559 -0
  385. package/hermes_cli/skills_config.py +177 -0
  386. package/hermes_cli/skills_hub.py +1595 -0
  387. package/hermes_cli/skin_engine.py +929 -0
  388. package/hermes_cli/slack_cli.py +160 -0
  389. package/hermes_cli/status.py +550 -0
  390. package/hermes_cli/stdio.py +252 -0
  391. package/hermes_cli/timeouts.py +82 -0
  392. package/hermes_cli/tips.py +487 -0
  393. package/hermes_cli/tools_config.py +3151 -0
  394. package/hermes_cli/uninstall.py +681 -0
  395. package/hermes_cli/vercel_auth.py +70 -0
  396. package/hermes_cli/voice.py +846 -0
  397. package/hermes_cli/web_server.py +4438 -0
  398. package/hermes_cli/webhook.py +275 -0
  399. package/locales/af.yaml +350 -0
  400. package/locales/de.yaml +350 -0
  401. package/locales/en.yaml +365 -0
  402. package/locales/es.yaml +350 -0
  403. package/locales/fr.yaml +350 -0
  404. package/locales/ga.yaml +354 -0
  405. package/locales/hu.yaml +350 -0
  406. package/locales/it.yaml +350 -0
  407. package/locales/ja.yaml +350 -0
  408. package/locales/ko.yaml +350 -0
  409. package/locales/pt.yaml +350 -0
  410. package/locales/ru.yaml +350 -0
  411. package/locales/tr.yaml +350 -0
  412. package/locales/uk.yaml +350 -0
  413. package/locales/zh-hant.yaml +350 -0
  414. package/locales/zh.yaml +350 -0
  415. package/mcp_serve.py +898 -0
  416. package/model_tools.py +899 -0
  417. package/optional-skills/DESCRIPTION.md +24 -0
  418. package/optional-skills/autonomous-ai-agents/DESCRIPTION.md +2 -0
  419. package/optional-skills/autonomous-ai-agents/blackbox/SKILL.md +144 -0
  420. package/optional-skills/autonomous-ai-agents/honcho/SKILL.md +431 -0
  421. package/optional-skills/blockchain/evm/SKILL.md +211 -0
  422. package/optional-skills/blockchain/evm/scripts/evm_client.py +1508 -0
  423. package/optional-skills/blockchain/hyperliquid/SKILL.md +211 -0
  424. package/optional-skills/blockchain/hyperliquid/scripts/hyperliquid_client.py +1660 -0
  425. package/optional-skills/blockchain/solana/SKILL.md +208 -0
  426. package/optional-skills/blockchain/solana/scripts/solana_client.py +698 -0
  427. package/optional-skills/communication/DESCRIPTION.md +1 -0
  428. package/optional-skills/communication/one-three-one-rule/SKILL.md +104 -0
  429. package/optional-skills/creative/blender-mcp/SKILL.md +117 -0
  430. package/optional-skills/creative/concept-diagrams/SKILL.md +362 -0
  431. package/optional-skills/creative/concept-diagrams/examples/apartment-floor-plan-conversion.md +244 -0
  432. package/optional-skills/creative/concept-diagrams/examples/automated-password-reset-flow.md +276 -0
  433. package/optional-skills/creative/concept-diagrams/examples/autonomous-llm-research-agent-flow.md +240 -0
  434. package/optional-skills/creative/concept-diagrams/examples/banana-journey-tree-to-smoothie.md +161 -0
  435. package/optional-skills/creative/concept-diagrams/examples/commercial-aircraft-structure.md +209 -0
  436. package/optional-skills/creative/concept-diagrams/examples/cpu-ooo-microarchitecture.md +236 -0
  437. package/optional-skills/creative/concept-diagrams/examples/electricity-grid-flow.md +182 -0
  438. package/optional-skills/creative/concept-diagrams/examples/feature-film-production-pipeline.md +172 -0
  439. package/optional-skills/creative/concept-diagrams/examples/hospital-emergency-department-flow.md +165 -0
  440. package/optional-skills/creative/concept-diagrams/examples/ml-benchmark-grouped-bar-chart.md +114 -0
  441. package/optional-skills/creative/concept-diagrams/examples/place-order-uml-sequence.md +325 -0
  442. package/optional-skills/creative/concept-diagrams/examples/smart-city-infrastructure.md +173 -0
  443. package/optional-skills/creative/concept-diagrams/examples/smartphone-layer-anatomy.md +154 -0
  444. package/optional-skills/creative/concept-diagrams/examples/sn2-reaction-mechanism.md +247 -0
  445. package/optional-skills/creative/concept-diagrams/examples/wind-turbine-structure.md +338 -0
  446. package/optional-skills/creative/concept-diagrams/references/dashboard-patterns.md +43 -0
  447. package/optional-skills/creative/concept-diagrams/references/infrastructure-patterns.md +144 -0
  448. package/optional-skills/creative/concept-diagrams/references/physical-shape-cookbook.md +42 -0
  449. package/optional-skills/creative/concept-diagrams/templates/template.html +174 -0
  450. package/optional-skills/creative/hyperframes/SKILL.md +191 -0
  451. package/optional-skills/creative/hyperframes/references/cli.md +185 -0
  452. package/optional-skills/creative/hyperframes/references/composition.md +129 -0
  453. package/optional-skills/creative/hyperframes/references/features.md +289 -0
  454. package/optional-skills/creative/hyperframes/references/gsap.md +136 -0
  455. package/optional-skills/creative/hyperframes/references/troubleshooting.md +137 -0
  456. package/optional-skills/creative/hyperframes/references/website-to-video.md +145 -0
  457. package/optional-skills/creative/hyperframes/scripts/setup.sh +135 -0
  458. package/optional-skills/creative/kanban-video-orchestrator/SKILL.md +207 -0
  459. package/optional-skills/creative/kanban-video-orchestrator/assets/brief.md.tmpl +79 -0
  460. package/optional-skills/creative/kanban-video-orchestrator/assets/setup.sh.tmpl +185 -0
  461. package/optional-skills/creative/kanban-video-orchestrator/assets/soul.md.tmpl +38 -0
  462. package/optional-skills/creative/kanban-video-orchestrator/references/examples.md +227 -0
  463. package/optional-skills/creative/kanban-video-orchestrator/references/intake.md +166 -0
  464. package/optional-skills/creative/kanban-video-orchestrator/references/kanban-setup.md +276 -0
  465. package/optional-skills/creative/kanban-video-orchestrator/references/monitoring.md +180 -0
  466. package/optional-skills/creative/kanban-video-orchestrator/references/role-archetypes.md +298 -0
  467. package/optional-skills/creative/kanban-video-orchestrator/references/tool-matrix.md +317 -0
  468. package/optional-skills/creative/kanban-video-orchestrator/scripts/bootstrap_pipeline.py +501 -0
  469. package/optional-skills/creative/kanban-video-orchestrator/scripts/monitor.py +195 -0
  470. package/optional-skills/creative/meme-generation/EXAMPLES.md +46 -0
  471. package/optional-skills/creative/meme-generation/SKILL.md +130 -0
  472. package/optional-skills/creative/meme-generation/scripts/generate_meme.py +471 -0
  473. package/optional-skills/creative/meme-generation/scripts/templates.json +97 -0
  474. package/optional-skills/devops/cli/SKILL.md +156 -0
  475. package/optional-skills/devops/cli/references/app-discovery.md +112 -0
  476. package/optional-skills/devops/cli/references/authentication.md +59 -0
  477. package/optional-skills/devops/cli/references/cli-reference.md +104 -0
  478. package/optional-skills/devops/cli/references/running-apps.md +171 -0
  479. package/optional-skills/devops/docker-management/SKILL.md +281 -0
  480. package/optional-skills/devops/pinggy-tunnel/SKILL.md +309 -0
  481. package/optional-skills/devops/watchers/SKILL.md +112 -0
  482. package/optional-skills/devops/watchers/scripts/_watermark.py +148 -0
  483. package/optional-skills/devops/watchers/scripts/watch_github.py +168 -0
  484. package/optional-skills/devops/watchers/scripts/watch_http_json.py +131 -0
  485. package/optional-skills/devops/watchers/scripts/watch_rss.py +121 -0
  486. package/optional-skills/dogfood/DESCRIPTION.md +3 -0
  487. package/optional-skills/dogfood/adversarial-ux-test/SKILL.md +191 -0
  488. package/optional-skills/email/agentmail/SKILL.md +126 -0
  489. package/optional-skills/finance/3-statement-model/SKILL.md +433 -0
  490. package/optional-skills/finance/3-statement-model/references/formatting.md +118 -0
  491. package/optional-skills/finance/3-statement-model/references/formulas.md +292 -0
  492. package/optional-skills/finance/3-statement-model/references/sec-filings.md +125 -0
  493. package/optional-skills/finance/comps-analysis/SKILL.md +662 -0
  494. package/optional-skills/finance/dcf-model/SKILL.md +1270 -0
  495. package/optional-skills/finance/dcf-model/TROUBLESHOOTING.md +40 -0
  496. package/optional-skills/finance/dcf-model/requirements.txt +7 -0
  497. package/optional-skills/finance/dcf-model/scripts/validate_dcf.py +292 -0
  498. package/optional-skills/finance/excel-author/SKILL.md +244 -0
  499. package/optional-skills/finance/excel-author/scripts/recalc.py +88 -0
  500. package/optional-skills/finance/lbo-model/SKILL.md +291 -0
  501. package/optional-skills/finance/merger-model/SKILL.md +144 -0
  502. package/optional-skills/finance/pptx-author/SKILL.md +173 -0
  503. package/optional-skills/finance/stocks/SKILL.md +95 -0
  504. package/optional-skills/finance/stocks/scripts/stocks_client.py +755 -0
  505. package/optional-skills/health/DESCRIPTION.md +1 -0
  506. package/optional-skills/health/fitness-nutrition/SKILL.md +256 -0
  507. package/optional-skills/health/fitness-nutrition/references/FORMULAS.md +100 -0
  508. package/optional-skills/health/fitness-nutrition/scripts/body_calc.py +210 -0
  509. package/optional-skills/health/fitness-nutrition/scripts/nutrition_search.py +86 -0
  510. package/optional-skills/health/neuroskill-bci/SKILL.md +459 -0
  511. package/optional-skills/health/neuroskill-bci/references/api.md +286 -0
  512. package/optional-skills/health/neuroskill-bci/references/metrics.md +220 -0
  513. package/optional-skills/health/neuroskill-bci/references/protocols.md +452 -0
  514. package/optional-skills/mcp/DESCRIPTION.md +3 -0
  515. package/optional-skills/mcp/fastmcp/SKILL.md +300 -0
  516. package/optional-skills/mcp/fastmcp/references/fastmcp-cli.md +110 -0
  517. package/optional-skills/mcp/fastmcp/scripts/scaffold_fastmcp.py +56 -0
  518. package/optional-skills/mcp/fastmcp/templates/api_wrapper.py +54 -0
  519. package/optional-skills/mcp/fastmcp/templates/database_server.py +77 -0
  520. package/optional-skills/mcp/fastmcp/templates/file_processor.py +55 -0
  521. package/optional-skills/mcp/mcporter/SKILL.md +123 -0
  522. package/optional-skills/migration/DESCRIPTION.md +2 -0
  523. package/optional-skills/migration/openclaw-migration/SKILL.md +298 -0
  524. package/optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py +3136 -0
  525. package/optional-skills/mlops/accelerate/SKILL.md +336 -0
  526. package/optional-skills/mlops/accelerate/references/custom-plugins.md +453 -0
  527. package/optional-skills/mlops/accelerate/references/megatron-integration.md +489 -0
  528. package/optional-skills/mlops/accelerate/references/performance.md +525 -0
  529. package/optional-skills/mlops/chroma/SKILL.md +410 -0
  530. package/optional-skills/mlops/chroma/references/integration.md +38 -0
  531. package/optional-skills/mlops/clip/SKILL.md +257 -0
  532. package/optional-skills/mlops/clip/references/applications.md +207 -0
  533. package/optional-skills/mlops/faiss/SKILL.md +225 -0
  534. package/optional-skills/mlops/faiss/references/index_types.md +280 -0
  535. package/optional-skills/mlops/flash-attention/SKILL.md +367 -0
  536. package/optional-skills/mlops/flash-attention/references/benchmarks.md +215 -0
  537. package/optional-skills/mlops/flash-attention/references/transformers-integration.md +293 -0
  538. package/optional-skills/mlops/guidance/SKILL.md +576 -0
  539. package/optional-skills/mlops/guidance/references/backends.md +554 -0
  540. package/optional-skills/mlops/guidance/references/constraints.md +674 -0
  541. package/optional-skills/mlops/guidance/references/examples.md +767 -0
  542. package/optional-skills/mlops/huggingface-tokenizers/SKILL.md +520 -0
  543. package/optional-skills/mlops/huggingface-tokenizers/references/algorithms.md +653 -0
  544. package/optional-skills/mlops/huggingface-tokenizers/references/integration.md +637 -0
  545. package/optional-skills/mlops/huggingface-tokenizers/references/pipeline.md +723 -0
  546. package/optional-skills/mlops/huggingface-tokenizers/references/training.md +565 -0
  547. package/optional-skills/mlops/inference/outlines/SKILL.md +656 -0
  548. package/optional-skills/mlops/inference/outlines/references/backends.md +615 -0
  549. package/optional-skills/mlops/inference/outlines/references/examples.md +773 -0
  550. package/optional-skills/mlops/inference/outlines/references/json_generation.md +652 -0
  551. package/optional-skills/mlops/instructor/SKILL.md +744 -0
  552. package/optional-skills/mlops/instructor/references/examples.md +107 -0
  553. package/optional-skills/mlops/instructor/references/providers.md +70 -0
  554. package/optional-skills/mlops/instructor/references/validation.md +606 -0
  555. package/optional-skills/mlops/lambda-labs/SKILL.md +549 -0
  556. package/optional-skills/mlops/lambda-labs/references/advanced-usage.md +611 -0
  557. package/optional-skills/mlops/lambda-labs/references/troubleshooting.md +530 -0
  558. package/optional-skills/mlops/llava/SKILL.md +308 -0
  559. package/optional-skills/mlops/llava/references/training.md +197 -0
  560. package/optional-skills/mlops/modal/SKILL.md +345 -0
  561. package/optional-skills/mlops/modal/references/advanced-usage.md +503 -0
  562. package/optional-skills/mlops/modal/references/troubleshooting.md +494 -0
  563. package/optional-skills/mlops/nemo-curator/SKILL.md +387 -0
  564. package/optional-skills/mlops/nemo-curator/references/deduplication.md +87 -0
  565. package/optional-skills/mlops/nemo-curator/references/filtering.md +102 -0
  566. package/optional-skills/mlops/peft/SKILL.md +435 -0
  567. package/optional-skills/mlops/peft/references/advanced-usage.md +514 -0
  568. package/optional-skills/mlops/peft/references/troubleshooting.md +480 -0
  569. package/optional-skills/mlops/pinecone/SKILL.md +362 -0
  570. package/optional-skills/mlops/pinecone/references/deployment.md +181 -0
  571. package/optional-skills/mlops/pytorch-fsdp/SKILL.md +130 -0
  572. package/optional-skills/mlops/pytorch-fsdp/references/index.md +7 -0
  573. package/optional-skills/mlops/pytorch-fsdp/references/other.md +4261 -0
  574. package/optional-skills/mlops/pytorch-lightning/SKILL.md +350 -0
  575. package/optional-skills/mlops/pytorch-lightning/references/callbacks.md +436 -0
  576. package/optional-skills/mlops/pytorch-lightning/references/distributed.md +490 -0
  577. package/optional-skills/mlops/pytorch-lightning/references/hyperparameter-tuning.md +556 -0
  578. package/optional-skills/mlops/qdrant/SKILL.md +497 -0
  579. package/optional-skills/mlops/qdrant/references/advanced-usage.md +648 -0
  580. package/optional-skills/mlops/qdrant/references/troubleshooting.md +631 -0
  581. package/optional-skills/mlops/saelens/SKILL.md +390 -0
  582. package/optional-skills/mlops/saelens/references/README.md +69 -0
  583. package/optional-skills/mlops/saelens/references/api.md +333 -0
  584. package/optional-skills/mlops/saelens/references/tutorials.md +318 -0
  585. package/optional-skills/mlops/simpo/SKILL.md +223 -0
  586. package/optional-skills/mlops/simpo/references/datasets.md +478 -0
  587. package/optional-skills/mlops/simpo/references/hyperparameters.md +452 -0
  588. package/optional-skills/mlops/simpo/references/loss-functions.md +350 -0
  589. package/optional-skills/mlops/slime/SKILL.md +468 -0
  590. package/optional-skills/mlops/slime/references/api-reference.md +392 -0
  591. package/optional-skills/mlops/slime/references/troubleshooting.md +386 -0
  592. package/optional-skills/mlops/stable-diffusion/SKILL.md +523 -0
  593. package/optional-skills/mlops/stable-diffusion/references/advanced-usage.md +716 -0
  594. package/optional-skills/mlops/stable-diffusion/references/troubleshooting.md +555 -0
  595. package/optional-skills/mlops/tensorrt-llm/SKILL.md +191 -0
  596. package/optional-skills/mlops/tensorrt-llm/references/multi-gpu.md +298 -0
  597. package/optional-skills/mlops/tensorrt-llm/references/optimization.md +242 -0
  598. package/optional-skills/mlops/tensorrt-llm/references/serving.md +470 -0
  599. package/optional-skills/mlops/torchtitan/SKILL.md +362 -0
  600. package/optional-skills/mlops/torchtitan/references/checkpoint.md +181 -0
  601. package/optional-skills/mlops/torchtitan/references/custom-models.md +258 -0
  602. package/optional-skills/mlops/torchtitan/references/float8.md +133 -0
  603. package/optional-skills/mlops/torchtitan/references/fsdp.md +126 -0
  604. package/optional-skills/mlops/training/axolotl/SKILL.md +166 -0
  605. package/optional-skills/mlops/training/axolotl/references/api.md +5548 -0
  606. package/optional-skills/mlops/training/axolotl/references/dataset-formats.md +1029 -0
  607. package/optional-skills/mlops/training/axolotl/references/index.md +15 -0
  608. package/optional-skills/mlops/training/axolotl/references/other.md +3563 -0
  609. package/optional-skills/mlops/training/trl-fine-tuning/SKILL.md +463 -0
  610. package/optional-skills/mlops/training/trl-fine-tuning/references/dpo-variants.md +227 -0
  611. package/optional-skills/mlops/training/trl-fine-tuning/references/grpo-training.md +504 -0
  612. package/optional-skills/mlops/training/trl-fine-tuning/references/online-rl.md +82 -0
  613. package/optional-skills/mlops/training/trl-fine-tuning/references/reward-modeling.md +122 -0
  614. package/optional-skills/mlops/training/trl-fine-tuning/references/sft-training.md +168 -0
  615. package/optional-skills/mlops/training/trl-fine-tuning/templates/basic_grpo_training.py +228 -0
  616. package/optional-skills/mlops/training/unsloth/SKILL.md +84 -0
  617. package/optional-skills/mlops/training/unsloth/references/index.md +7 -0
  618. package/optional-skills/mlops/training/unsloth/references/llms-full.md +16799 -0
  619. package/optional-skills/mlops/training/unsloth/references/llms-txt.md +12044 -0
  620. package/optional-skills/mlops/training/unsloth/references/llms.md +82 -0
  621. package/optional-skills/mlops/whisper/SKILL.md +321 -0
  622. package/optional-skills/mlops/whisper/references/languages.md +189 -0
  623. package/optional-skills/productivity/canvas/SKILL.md +98 -0
  624. package/optional-skills/productivity/canvas/scripts/canvas_api.py +157 -0
  625. package/optional-skills/productivity/here-now/SKILL.md +217 -0
  626. package/optional-skills/productivity/here-now/scripts/drive.sh +406 -0
  627. package/optional-skills/productivity/here-now/scripts/publish.sh +445 -0
  628. package/optional-skills/productivity/memento-flashcards/SKILL.md +324 -0
  629. package/optional-skills/productivity/memento-flashcards/scripts/memento_cards.py +353 -0
  630. package/optional-skills/productivity/memento-flashcards/scripts/youtube_quiz.py +88 -0
  631. package/optional-skills/productivity/shop-app/SKILL.md +340 -0
  632. package/optional-skills/productivity/shopify/SKILL.md +373 -0
  633. package/optional-skills/productivity/siyuan/SKILL.md +298 -0
  634. package/optional-skills/productivity/telephony/SKILL.md +418 -0
  635. package/optional-skills/productivity/telephony/scripts/telephony.py +1343 -0
  636. package/optional-skills/research/bioinformatics/SKILL.md +235 -0
  637. package/optional-skills/research/darwinian-evolver/SKILL.md +199 -0
  638. package/optional-skills/research/darwinian-evolver/scripts/parrot_openrouter.py +218 -0
  639. package/optional-skills/research/darwinian-evolver/scripts/show_snapshot.py +69 -0
  640. package/optional-skills/research/darwinian-evolver/templates/custom_problem_template.py +240 -0
  641. package/optional-skills/research/domain-intel/SKILL.md +97 -0
  642. package/optional-skills/research/domain-intel/scripts/domain_intel.py +397 -0
  643. package/optional-skills/research/drug-discovery/SKILL.md +227 -0
  644. package/optional-skills/research/drug-discovery/references/ADMET_REFERENCE.md +66 -0
  645. package/optional-skills/research/drug-discovery/scripts/chembl_target.py +53 -0
  646. package/optional-skills/research/drug-discovery/scripts/ro5_screen.py +44 -0
  647. package/optional-skills/research/duckduckgo-search/SKILL.md +238 -0
  648. package/optional-skills/research/duckduckgo-search/scripts/duckduckgo.sh +28 -0
  649. package/optional-skills/research/gitnexus-explorer/SKILL.md +214 -0
  650. package/optional-skills/research/gitnexus-explorer/scripts/proxy.mjs +92 -0
  651. package/optional-skills/research/osint-investigation/SKILL.md +277 -0
  652. package/optional-skills/research/osint-investigation/references/sources/courtlistener.md +98 -0
  653. package/optional-skills/research/osint-investigation/references/sources/gdelt.md +104 -0
  654. package/optional-skills/research/osint-investigation/references/sources/icij-offshore.md +104 -0
  655. package/optional-skills/research/osint-investigation/references/sources/nyc-acris.md +90 -0
  656. package/optional-skills/research/osint-investigation/references/sources/ofac-sdn.md +92 -0
  657. package/optional-skills/research/osint-investigation/references/sources/opencorporates.md +103 -0
  658. package/optional-skills/research/osint-investigation/references/sources/sec-edgar.md +83 -0
  659. package/optional-skills/research/osint-investigation/references/sources/senate-ld.md +89 -0
  660. package/optional-skills/research/osint-investigation/references/sources/usaspending.md +97 -0
  661. package/optional-skills/research/osint-investigation/references/sources/wayback.md +93 -0
  662. package/optional-skills/research/osint-investigation/references/sources/wikipedia.md +107 -0
  663. package/optional-skills/research/osint-investigation/scripts/_http.py +82 -0
  664. package/optional-skills/research/osint-investigation/scripts/_normalize.py +67 -0
  665. package/optional-skills/research/osint-investigation/scripts/build_findings.py +221 -0
  666. package/optional-skills/research/osint-investigation/scripts/entity_resolution.py +228 -0
  667. package/optional-skills/research/osint-investigation/scripts/fetch_courtlistener.py +149 -0
  668. package/optional-skills/research/osint-investigation/scripts/fetch_gdelt.py +162 -0
  669. package/optional-skills/research/osint-investigation/scripts/fetch_icij_offshore.py +234 -0
  670. package/optional-skills/research/osint-investigation/scripts/fetch_nyc_acris.py +203 -0
  671. package/optional-skills/research/osint-investigation/scripts/fetch_ofac_sdn.py +175 -0
  672. package/optional-skills/research/osint-investigation/scripts/fetch_opencorporates.py +192 -0
  673. package/optional-skills/research/osint-investigation/scripts/fetch_sec_edgar.py +184 -0
  674. package/optional-skills/research/osint-investigation/scripts/fetch_senate_ld.py +146 -0
  675. package/optional-skills/research/osint-investigation/scripts/fetch_usaspending.py +170 -0
  676. package/optional-skills/research/osint-investigation/scripts/fetch_wayback.py +142 -0
  677. package/optional-skills/research/osint-investigation/scripts/fetch_wikipedia.py +267 -0
  678. package/optional-skills/research/osint-investigation/scripts/timing_analysis.py +253 -0
  679. package/optional-skills/research/osint-investigation/templates/source-template.md +59 -0
  680. package/optional-skills/research/parallel-cli/SKILL.md +391 -0
  681. package/optional-skills/research/qmd/SKILL.md +441 -0
  682. package/optional-skills/research/scrapling/SKILL.md +336 -0
  683. package/optional-skills/research/searxng-search/SKILL.md +212 -0
  684. package/optional-skills/research/searxng-search/scripts/searxng.sh +22 -0
  685. package/optional-skills/security/1password/SKILL.md +163 -0
  686. package/optional-skills/security/1password/references/cli-examples.md +31 -0
  687. package/optional-skills/security/1password/references/get-started.md +21 -0
  688. package/optional-skills/security/DESCRIPTION.md +3 -0
  689. package/optional-skills/security/oss-forensics/SKILL.md +423 -0
  690. package/optional-skills/security/oss-forensics/references/evidence-types.md +89 -0
  691. package/optional-skills/security/oss-forensics/references/github-archive-guide.md +184 -0
  692. package/optional-skills/security/oss-forensics/references/investigation-templates.md +131 -0
  693. package/optional-skills/security/oss-forensics/references/recovery-techniques.md +164 -0
  694. package/optional-skills/security/oss-forensics/scripts/evidence-store.py +313 -0
  695. package/optional-skills/security/oss-forensics/templates/forensic-report.md +151 -0
  696. package/optional-skills/security/oss-forensics/templates/malicious-package-report.md +43 -0
  697. package/optional-skills/security/sherlock/SKILL.md +193 -0
  698. package/optional-skills/software-development/rest-graphql-debug/SKILL.md +514 -0
  699. package/optional-skills/web-development/DESCRIPTION.md +5 -0
  700. package/optional-skills/web-development/page-agent/SKILL.md +190 -0
  701. package/package.json +78 -0
  702. package/plugins/__init__.py +1 -0
  703. package/plugins/__pycache__/__init__.cpython-312.pyc +0 -0
  704. package/plugins/context_engine/__init__.py +219 -0
  705. package/plugins/disk-cleanup/README.md +51 -0
  706. package/plugins/disk-cleanup/__init__.py +316 -0
  707. package/plugins/disk-cleanup/disk_cleanup.py +497 -0
  708. package/plugins/disk-cleanup/plugin.yaml +7 -0
  709. package/plugins/example-dashboard/dashboard/manifest.json +14 -0
  710. package/plugins/example-dashboard/dashboard/plugin_api.py +17 -0
  711. package/plugins/google_meet/README.md +131 -0
  712. package/plugins/google_meet/SKILL.md +148 -0
  713. package/plugins/google_meet/__init__.py +103 -0
  714. package/plugins/google_meet/audio_bridge.py +244 -0
  715. package/plugins/google_meet/cli.py +479 -0
  716. package/plugins/google_meet/meet_bot.py +852 -0
  717. package/plugins/google_meet/node/__init__.py +54 -0
  718. package/plugins/google_meet/node/cli.py +125 -0
  719. package/plugins/google_meet/node/client.py +107 -0
  720. package/plugins/google_meet/node/protocol.py +124 -0
  721. package/plugins/google_meet/node/registry.py +113 -0
  722. package/plugins/google_meet/node/server.py +201 -0
  723. package/plugins/google_meet/plugin.yaml +16 -0
  724. package/plugins/google_meet/process_manager.py +324 -0
  725. package/plugins/google_meet/realtime/__init__.py +10 -0
  726. package/plugins/google_meet/realtime/openai_client.py +332 -0
  727. package/plugins/google_meet/tools.py +348 -0
  728. package/plugins/hermes-achievements/LICENSE +21 -0
  729. package/plugins/hermes-achievements/README.md +150 -0
  730. package/plugins/hermes-achievements/dashboard/dist/index.js +732 -0
  731. package/plugins/hermes-achievements/dashboard/dist/style.css +146 -0
  732. package/plugins/hermes-achievements/dashboard/manifest.json +11 -0
  733. package/plugins/hermes-achievements/dashboard/plugin_api.py +1062 -0
  734. package/plugins/hermes-achievements/docs/achievements-performance-implementation-plan.md +157 -0
  735. package/plugins/hermes-achievements/docs/achievements-performance-implementation-spec.md +219 -0
  736. package/plugins/hermes-achievements/docs/achievements-performance-spec.md +174 -0
  737. package/plugins/hermes-achievements/docs/assets/achievements-dashboard-hd.png +0 -0
  738. package/plugins/hermes-achievements/docs/assets/achievements-tier-showcase-hd.png +0 -0
  739. package/plugins/hermes-achievements/tests/test_achievement_engine.py +156 -0
  740. package/plugins/image_gen/openai/__init__.py +303 -0
  741. package/plugins/image_gen/openai/__pycache__/__init__.cpython-312.pyc +0 -0
  742. package/plugins/image_gen/openai/plugin.yaml +7 -0
  743. package/plugins/image_gen/openai-codex/__init__.py +378 -0
  744. package/plugins/image_gen/openai-codex/__pycache__/__init__.cpython-312.pyc +0 -0
  745. package/plugins/image_gen/openai-codex/plugin.yaml +5 -0
  746. package/plugins/image_gen/xai/__init__.py +316 -0
  747. package/plugins/image_gen/xai/__pycache__/__init__.cpython-312.pyc +0 -0
  748. package/plugins/image_gen/xai/plugin.yaml +7 -0
  749. package/plugins/kanban/dashboard/dist/index.js +3143 -0
  750. package/plugins/kanban/dashboard/dist/style.css +1500 -0
  751. package/plugins/kanban/dashboard/manifest.json +14 -0
  752. package/plugins/kanban/dashboard/plugin_api.py +1612 -0
  753. package/plugins/kanban/systemd/hermes-kanban-dispatcher.service +32 -0
  754. package/plugins/memory/__init__.py +408 -0
  755. package/plugins/memory/byterover/README.md +41 -0
  756. package/plugins/memory/byterover/__init__.py +384 -0
  757. package/plugins/memory/byterover/plugin.yaml +9 -0
  758. package/plugins/memory/hindsight/README.md +138 -0
  759. package/plugins/memory/hindsight/__init__.py +1758 -0
  760. package/plugins/memory/hindsight/plugin.yaml +8 -0
  761. package/plugins/memory/holographic/README.md +36 -0
  762. package/plugins/memory/holographic/__init__.py +409 -0
  763. package/plugins/memory/holographic/holographic.py +203 -0
  764. package/plugins/memory/holographic/plugin.yaml +5 -0
  765. package/plugins/memory/holographic/retrieval.py +593 -0
  766. package/plugins/memory/holographic/store.py +579 -0
  767. package/plugins/memory/honcho/README.md +328 -0
  768. package/plugins/memory/honcho/__init__.py +1329 -0
  769. package/plugins/memory/honcho/cli.py +1452 -0
  770. package/plugins/memory/honcho/client.py +784 -0
  771. package/plugins/memory/honcho/plugin.yaml +7 -0
  772. package/plugins/memory/honcho/session.py +1255 -0
  773. package/plugins/memory/mem0/README.md +38 -0
  774. package/plugins/memory/mem0/__init__.py +374 -0
  775. package/plugins/memory/mem0/plugin.yaml +5 -0
  776. package/plugins/memory/openviking/README.md +40 -0
  777. package/plugins/memory/openviking/__init__.py +945 -0
  778. package/plugins/memory/openviking/plugin.yaml +9 -0
  779. package/plugins/memory/retaindb/README.md +40 -0
  780. package/plugins/memory/retaindb/__init__.py +767 -0
  781. package/plugins/memory/retaindb/plugin.yaml +7 -0
  782. package/plugins/memory/supermemory/README.md +99 -0
  783. package/plugins/memory/supermemory/__init__.py +792 -0
  784. package/plugins/memory/supermemory/plugin.yaml +5 -0
  785. package/plugins/model-providers/README.md +70 -0
  786. package/plugins/model-providers/ai-gateway/__init__.py +43 -0
  787. package/plugins/model-providers/ai-gateway/__pycache__/__init__.cpython-312.pyc +0 -0
  788. package/plugins/model-providers/ai-gateway/plugin.yaml +5 -0
  789. package/plugins/model-providers/alibaba/__init__.py +13 -0
  790. package/plugins/model-providers/alibaba/__pycache__/__init__.cpython-312.pyc +0 -0
  791. package/plugins/model-providers/alibaba/plugin.yaml +5 -0
  792. package/plugins/model-providers/alibaba-coding-plan/__init__.py +21 -0
  793. package/plugins/model-providers/alibaba-coding-plan/__pycache__/__init__.cpython-312.pyc +0 -0
  794. package/plugins/model-providers/alibaba-coding-plan/plugin.yaml +5 -0
  795. package/plugins/model-providers/anthropic/__init__.py +52 -0
  796. package/plugins/model-providers/anthropic/__pycache__/__init__.cpython-312.pyc +0 -0
  797. package/plugins/model-providers/anthropic/plugin.yaml +5 -0
  798. package/plugins/model-providers/arcee/__init__.py +13 -0
  799. package/plugins/model-providers/arcee/__pycache__/__init__.cpython-312.pyc +0 -0
  800. package/plugins/model-providers/arcee/plugin.yaml +5 -0
  801. package/plugins/model-providers/azure-foundry/__init__.py +21 -0
  802. package/plugins/model-providers/azure-foundry/__pycache__/__init__.cpython-312.pyc +0 -0
  803. package/plugins/model-providers/azure-foundry/plugin.yaml +5 -0
  804. package/plugins/model-providers/bedrock/__init__.py +29 -0
  805. package/plugins/model-providers/bedrock/__pycache__/__init__.cpython-312.pyc +0 -0
  806. package/plugins/model-providers/bedrock/plugin.yaml +5 -0
  807. package/plugins/model-providers/copilot/__init__.py +58 -0
  808. package/plugins/model-providers/copilot/__pycache__/__init__.cpython-312.pyc +0 -0
  809. package/plugins/model-providers/copilot/plugin.yaml +5 -0
  810. package/plugins/model-providers/copilot-acp/__init__.py +34 -0
  811. package/plugins/model-providers/copilot-acp/__pycache__/__init__.cpython-312.pyc +0 -0
  812. package/plugins/model-providers/copilot-acp/plugin.yaml +5 -0
  813. package/plugins/model-providers/custom/__init__.py +68 -0
  814. package/plugins/model-providers/custom/__pycache__/__init__.cpython-312.pyc +0 -0
  815. package/plugins/model-providers/custom/plugin.yaml +5 -0
  816. package/plugins/model-providers/deepseek/__init__.py +99 -0
  817. package/plugins/model-providers/deepseek/__pycache__/__init__.cpython-312.pyc +0 -0
  818. package/plugins/model-providers/deepseek/plugin.yaml +5 -0
  819. package/plugins/model-providers/gemini/__init__.py +72 -0
  820. package/plugins/model-providers/gemini/__pycache__/__init__.cpython-312.pyc +0 -0
  821. package/plugins/model-providers/gemini/plugin.yaml +5 -0
  822. package/plugins/model-providers/gmi/__init__.py +31 -0
  823. package/plugins/model-providers/gmi/__pycache__/__init__.cpython-312.pyc +0 -0
  824. package/plugins/model-providers/gmi/plugin.yaml +5 -0
  825. package/plugins/model-providers/huggingface/__init__.py +20 -0
  826. package/plugins/model-providers/huggingface/__pycache__/__init__.cpython-312.pyc +0 -0
  827. package/plugins/model-providers/huggingface/plugin.yaml +5 -0
  828. package/plugins/model-providers/kilocode/__init__.py +14 -0
  829. package/plugins/model-providers/kilocode/__pycache__/__init__.cpython-312.pyc +0 -0
  830. package/plugins/model-providers/kilocode/plugin.yaml +5 -0
  831. package/plugins/model-providers/kimi-coding/__init__.py +71 -0
  832. package/plugins/model-providers/kimi-coding/__pycache__/__init__.cpython-312.pyc +0 -0
  833. package/plugins/model-providers/kimi-coding/plugin.yaml +5 -0
  834. package/plugins/model-providers/minimax/__init__.py +45 -0
  835. package/plugins/model-providers/minimax/__pycache__/__init__.cpython-312.pyc +0 -0
  836. package/plugins/model-providers/minimax/plugin.yaml +5 -0
  837. package/plugins/model-providers/nous/__init__.py +54 -0
  838. package/plugins/model-providers/nous/__pycache__/__init__.cpython-312.pyc +0 -0
  839. package/plugins/model-providers/nous/plugin.yaml +5 -0
  840. package/plugins/model-providers/novita/__init__.py +27 -0
  841. package/plugins/model-providers/novita/__pycache__/__init__.cpython-312.pyc +0 -0
  842. package/plugins/model-providers/novita/plugin.yaml +5 -0
  843. package/plugins/model-providers/nvidia/__init__.py +21 -0
  844. package/plugins/model-providers/nvidia/__pycache__/__init__.cpython-312.pyc +0 -0
  845. package/plugins/model-providers/nvidia/plugin.yaml +5 -0
  846. package/plugins/model-providers/ollama-cloud/__init__.py +14 -0
  847. package/plugins/model-providers/ollama-cloud/__pycache__/__init__.cpython-312.pyc +0 -0
  848. package/plugins/model-providers/ollama-cloud/plugin.yaml +5 -0
  849. package/plugins/model-providers/openai-codex/__init__.py +15 -0
  850. package/plugins/model-providers/openai-codex/__pycache__/__init__.cpython-312.pyc +0 -0
  851. package/plugins/model-providers/openai-codex/plugin.yaml +5 -0
  852. package/plugins/model-providers/opencode-zen/__init__.py +30 -0
  853. package/plugins/model-providers/opencode-zen/__pycache__/__init__.cpython-312.pyc +0 -0
  854. package/plugins/model-providers/opencode-zen/plugin.yaml +5 -0
  855. package/plugins/model-providers/openrouter/__init__.py +115 -0
  856. package/plugins/model-providers/openrouter/__pycache__/__init__.cpython-312.pyc +0 -0
  857. package/plugins/model-providers/openrouter/plugin.yaml +5 -0
  858. package/plugins/model-providers/qwen-oauth/__init__.py +82 -0
  859. package/plugins/model-providers/qwen-oauth/__pycache__/__init__.cpython-312.pyc +0 -0
  860. package/plugins/model-providers/qwen-oauth/plugin.yaml +5 -0
  861. package/plugins/model-providers/stepfun/__init__.py +14 -0
  862. package/plugins/model-providers/stepfun/__pycache__/__init__.cpython-312.pyc +0 -0
  863. package/plugins/model-providers/stepfun/plugin.yaml +5 -0
  864. package/plugins/model-providers/xai/__init__.py +15 -0
  865. package/plugins/model-providers/xai/__pycache__/__init__.cpython-312.pyc +0 -0
  866. package/plugins/model-providers/xai/plugin.yaml +5 -0
  867. package/plugins/model-providers/xiaomi/__init__.py +14 -0
  868. package/plugins/model-providers/xiaomi/__pycache__/__init__.cpython-312.pyc +0 -0
  869. package/plugins/model-providers/xiaomi/plugin.yaml +5 -0
  870. package/plugins/model-providers/zai/__init__.py +21 -0
  871. package/plugins/model-providers/zai/__pycache__/__init__.cpython-312.pyc +0 -0
  872. package/plugins/model-providers/zai/plugin.yaml +5 -0
  873. package/plugins/observability/langfuse/README.md +53 -0
  874. package/plugins/observability/langfuse/__init__.py +1004 -0
  875. package/plugins/observability/langfuse/plugin.yaml +14 -0
  876. package/plugins/platforms/google_chat/__init__.py +3 -0
  877. package/plugins/platforms/google_chat/__pycache__/__init__.cpython-312.pyc +0 -0
  878. package/plugins/platforms/google_chat/__pycache__/adapter.cpython-312.pyc +0 -0
  879. package/plugins/platforms/google_chat/adapter.py +3343 -0
  880. package/plugins/platforms/google_chat/oauth.py +639 -0
  881. package/plugins/platforms/google_chat/plugin.yaml +39 -0
  882. package/plugins/platforms/irc/__init__.py +3 -0
  883. package/plugins/platforms/irc/__pycache__/__init__.cpython-312.pyc +0 -0
  884. package/plugins/platforms/irc/__pycache__/adapter.cpython-312.pyc +0 -0
  885. package/plugins/platforms/irc/adapter.py +969 -0
  886. package/plugins/platforms/irc/plugin.yaml +54 -0
  887. package/plugins/platforms/line/__init__.py +3 -0
  888. package/plugins/platforms/line/__pycache__/__init__.cpython-312.pyc +0 -0
  889. package/plugins/platforms/line/__pycache__/adapter.cpython-312.pyc +0 -0
  890. package/plugins/platforms/line/adapter.py +1639 -0
  891. package/plugins/platforms/line/plugin.yaml +65 -0
  892. package/plugins/platforms/simplex/__init__.py +3 -0
  893. package/plugins/platforms/simplex/__pycache__/__init__.cpython-312.pyc +0 -0
  894. package/plugins/platforms/simplex/__pycache__/adapter.cpython-312.pyc +0 -0
  895. package/plugins/platforms/simplex/adapter.py +746 -0
  896. package/plugins/platforms/simplex/plugin.yaml +37 -0
  897. package/plugins/platforms/teams/__init__.py +3 -0
  898. package/plugins/platforms/teams/__pycache__/__init__.cpython-312.pyc +0 -0
  899. package/plugins/platforms/teams/__pycache__/adapter.cpython-312.pyc +0 -0
  900. package/plugins/platforms/teams/adapter.py +1188 -0
  901. package/plugins/platforms/teams/plugin.yaml +48 -0
  902. package/plugins/spotify/__init__.py +66 -0
  903. package/plugins/spotify/__pycache__/__init__.cpython-312.pyc +0 -0
  904. package/plugins/spotify/__pycache__/client.cpython-312.pyc +0 -0
  905. package/plugins/spotify/__pycache__/tools.cpython-312.pyc +0 -0
  906. package/plugins/spotify/client.py +435 -0
  907. package/plugins/spotify/plugin.yaml +13 -0
  908. package/plugins/spotify/tools.py +454 -0
  909. package/plugins/teams_pipeline/__init__.py +23 -0
  910. package/plugins/teams_pipeline/cli.py +463 -0
  911. package/plugins/teams_pipeline/meetings.py +333 -0
  912. package/plugins/teams_pipeline/models.py +350 -0
  913. package/plugins/teams_pipeline/pipeline.py +692 -0
  914. package/plugins/teams_pipeline/plugin.yaml +9 -0
  915. package/plugins/teams_pipeline/runtime.py +135 -0
  916. package/plugins/teams_pipeline/store.py +194 -0
  917. package/plugins/teams_pipeline/subscriptions.py +249 -0
  918. package/plugins/video_gen/fal/__init__.py +523 -0
  919. package/plugins/video_gen/fal/__pycache__/__init__.cpython-312.pyc +0 -0
  920. package/plugins/video_gen/fal/plugin.yaml +7 -0
  921. package/plugins/video_gen/xai/__init__.py +441 -0
  922. package/plugins/video_gen/xai/__pycache__/__init__.cpython-312.pyc +0 -0
  923. package/plugins/video_gen/xai/plugin.yaml +7 -0
  924. package/plugins/web/__init__.py +7 -0
  925. package/plugins/web/__pycache__/__init__.cpython-312.pyc +0 -0
  926. package/plugins/web/brave_free/__init__.py +14 -0
  927. package/plugins/web/brave_free/__pycache__/__init__.cpython-312.pyc +0 -0
  928. package/plugins/web/brave_free/__pycache__/provider.cpython-312.pyc +0 -0
  929. package/plugins/web/brave_free/plugin.yaml +7 -0
  930. package/plugins/web/brave_free/provider.py +137 -0
  931. package/plugins/web/ddgs/__init__.py +15 -0
  932. package/plugins/web/ddgs/__pycache__/__init__.cpython-312.pyc +0 -0
  933. package/plugins/web/ddgs/__pycache__/provider.cpython-312.pyc +0 -0
  934. package/plugins/web/ddgs/plugin.yaml +7 -0
  935. package/plugins/web/ddgs/provider.py +104 -0
  936. package/plugins/web/exa/__init__.py +15 -0
  937. package/plugins/web/exa/__pycache__/__init__.cpython-312.pyc +0 -0
  938. package/plugins/web/exa/__pycache__/provider.cpython-312.pyc +0 -0
  939. package/plugins/web/exa/plugin.yaml +7 -0
  940. package/plugins/web/exa/provider.py +212 -0
  941. package/plugins/web/firecrawl/__init__.py +28 -0
  942. package/plugins/web/firecrawl/__pycache__/__init__.cpython-312.pyc +0 -0
  943. package/plugins/web/firecrawl/__pycache__/provider.cpython-312.pyc +0 -0
  944. package/plugins/web/firecrawl/plugin.yaml +7 -0
  945. package/plugins/web/firecrawl/provider.py +773 -0
  946. package/plugins/web/parallel/__init__.py +16 -0
  947. package/plugins/web/parallel/__pycache__/__init__.cpython-312.pyc +0 -0
  948. package/plugins/web/parallel/__pycache__/provider.cpython-312.pyc +0 -0
  949. package/plugins/web/parallel/plugin.yaml +7 -0
  950. package/plugins/web/parallel/provider.py +291 -0
  951. package/plugins/web/searxng/__init__.py +15 -0
  952. package/plugins/web/searxng/__pycache__/__init__.cpython-312.pyc +0 -0
  953. package/plugins/web/searxng/__pycache__/provider.cpython-312.pyc +0 -0
  954. package/plugins/web/searxng/plugin.yaml +7 -0
  955. package/plugins/web/searxng/provider.py +140 -0
  956. package/plugins/web/tavily/__init__.py +15 -0
  957. package/plugins/web/tavily/__pycache__/__init__.cpython-312.pyc +0 -0
  958. package/plugins/web/tavily/__pycache__/provider.cpython-312.pyc +0 -0
  959. package/plugins/web/tavily/plugin.yaml +7 -0
  960. package/plugins/web/tavily/provider.py +285 -0
  961. package/providers/README.md +78 -0
  962. package/providers/__init__.py +192 -0
  963. package/providers/__pycache__/__init__.cpython-312.pyc +0 -0
  964. package/providers/__pycache__/base.cpython-312.pyc +0 -0
  965. package/providers/base.py +184 -0
  966. package/pyproject.toml +255 -0
  967. package/run_agent.py +16409 -0
  968. package/scripts/benchmark_browser_eval.py +138 -0
  969. package/scripts/build_model_catalog.py +95 -0
  970. package/scripts/build_skills_index.py +325 -0
  971. package/scripts/check-windows-footguns.py +624 -0
  972. package/scripts/contributor_audit.py +473 -0
  973. package/scripts/discord-voice-doctor.py +396 -0
  974. package/scripts/hermes-gateway +416 -0
  975. package/scripts/install.cmd +28 -0
  976. package/scripts/install.ps1 +1611 -0
  977. package/scripts/install.sh +2007 -0
  978. package/scripts/install_psutil_android.py +117 -0
  979. package/scripts/keystroke_diagnostic.py +81 -0
  980. package/scripts/kill_modal.sh +34 -0
  981. package/scripts/lib/node-bootstrap.sh +238 -0
  982. package/scripts/lint_diff.py +207 -0
  983. package/scripts/postinstall.js +150 -0
  984. package/scripts/profile-tui.py +626 -0
  985. package/scripts/release.py +1680 -0
  986. package/scripts/run_tests.sh +129 -0
  987. package/scripts/sample_and_compress.py +409 -0
  988. package/scripts/setup_open_webui.sh +349 -0
  989. package/scripts/whatsapp-bridge/allowlist.js +88 -0
  990. package/scripts/whatsapp-bridge/allowlist.test.mjs +80 -0
  991. package/scripts/whatsapp-bridge/bridge.js +729 -0
  992. package/scripts/whatsapp-bridge/package-lock.json +2141 -0
  993. package/scripts/whatsapp-bridge/package.json +19 -0
  994. package/skills/apple/DESCRIPTION.md +2 -0
  995. package/skills/apple/apple-notes/SKILL.md +90 -0
  996. package/skills/apple/apple-reminders/SKILL.md +98 -0
  997. package/skills/apple/findmy/SKILL.md +131 -0
  998. package/skills/apple/imessage/SKILL.md +102 -0
  999. package/skills/apple/macos-computer-use/SKILL.md +201 -0
  1000. package/skills/autonomous-ai-agents/DESCRIPTION.md +3 -0
  1001. package/skills/autonomous-ai-agents/claude-code/SKILL.md +745 -0
  1002. package/skills/autonomous-ai-agents/codex/SKILL.md +130 -0
  1003. package/skills/autonomous-ai-agents/hermes-agent/SKILL.md +1014 -0
  1004. package/skills/autonomous-ai-agents/opencode/SKILL.md +219 -0
  1005. package/skills/creative/DESCRIPTION.md +3 -0
  1006. package/skills/creative/architecture-diagram/SKILL.md +148 -0
  1007. package/skills/creative/architecture-diagram/templates/template.html +319 -0
  1008. package/skills/creative/ascii-art/SKILL.md +322 -0
  1009. package/skills/creative/ascii-video/README.md +290 -0
  1010. package/skills/creative/ascii-video/SKILL.md +241 -0
  1011. package/skills/creative/ascii-video/references/architecture.md +802 -0
  1012. package/skills/creative/ascii-video/references/composition.md +892 -0
  1013. package/skills/creative/ascii-video/references/effects.md +1865 -0
  1014. package/skills/creative/ascii-video/references/inputs.md +685 -0
  1015. package/skills/creative/ascii-video/references/optimization.md +688 -0
  1016. package/skills/creative/ascii-video/references/scenes.md +1011 -0
  1017. package/skills/creative/ascii-video/references/shaders.md +1385 -0
  1018. package/skills/creative/ascii-video/references/troubleshooting.md +367 -0
  1019. package/skills/creative/baoyu-comic/PORT_NOTES.md +77 -0
  1020. package/skills/creative/baoyu-comic/SKILL.md +247 -0
  1021. package/skills/creative/baoyu-comic/references/analysis-framework.md +176 -0
  1022. package/skills/creative/baoyu-comic/references/art-styles/chalk.md +101 -0
  1023. package/skills/creative/baoyu-comic/references/art-styles/ink-brush.md +97 -0
  1024. package/skills/creative/baoyu-comic/references/art-styles/ligne-claire.md +75 -0
  1025. package/skills/creative/baoyu-comic/references/art-styles/manga.md +93 -0
  1026. package/skills/creative/baoyu-comic/references/art-styles/minimalist.md +84 -0
  1027. package/skills/creative/baoyu-comic/references/art-styles/realistic.md +89 -0
  1028. package/skills/creative/baoyu-comic/references/auto-selection.md +71 -0
  1029. package/skills/creative/baoyu-comic/references/base-prompt.md +98 -0
  1030. package/skills/creative/baoyu-comic/references/character-template.md +180 -0
  1031. package/skills/creative/baoyu-comic/references/layouts/cinematic.md +23 -0
  1032. package/skills/creative/baoyu-comic/references/layouts/dense.md +23 -0
  1033. package/skills/creative/baoyu-comic/references/layouts/four-panel.md +40 -0
  1034. package/skills/creative/baoyu-comic/references/layouts/mixed.md +23 -0
  1035. package/skills/creative/baoyu-comic/references/layouts/splash.md +23 -0
  1036. package/skills/creative/baoyu-comic/references/layouts/standard.md +23 -0
  1037. package/skills/creative/baoyu-comic/references/layouts/webtoon.md +30 -0
  1038. package/skills/creative/baoyu-comic/references/ohmsha-guide.md +85 -0
  1039. package/skills/creative/baoyu-comic/references/partial-workflows.md +106 -0
  1040. package/skills/creative/baoyu-comic/references/presets/concept-story.md +121 -0
  1041. package/skills/creative/baoyu-comic/references/presets/four-panel.md +107 -0
  1042. package/skills/creative/baoyu-comic/references/presets/ohmsha.md +114 -0
  1043. package/skills/creative/baoyu-comic/references/presets/shoujo.md +116 -0
  1044. package/skills/creative/baoyu-comic/references/presets/wuxia.md +110 -0
  1045. package/skills/creative/baoyu-comic/references/storyboard-template.md +143 -0
  1046. package/skills/creative/baoyu-comic/references/tones/action.md +110 -0
  1047. package/skills/creative/baoyu-comic/references/tones/dramatic.md +95 -0
  1048. package/skills/creative/baoyu-comic/references/tones/energetic.md +105 -0
  1049. package/skills/creative/baoyu-comic/references/tones/neutral.md +63 -0
  1050. package/skills/creative/baoyu-comic/references/tones/romantic.md +100 -0
  1051. package/skills/creative/baoyu-comic/references/tones/vintage.md +104 -0
  1052. package/skills/creative/baoyu-comic/references/tones/warm.md +94 -0
  1053. package/skills/creative/baoyu-comic/references/workflow.md +401 -0
  1054. package/skills/creative/baoyu-infographic/PORT_NOTES.md +43 -0
  1055. package/skills/creative/baoyu-infographic/SKILL.md +237 -0
  1056. package/skills/creative/baoyu-infographic/references/analysis-framework.md +182 -0
  1057. package/skills/creative/baoyu-infographic/references/base-prompt.md +43 -0
  1058. package/skills/creative/baoyu-infographic/references/layouts/bento-grid.md +41 -0
  1059. package/skills/creative/baoyu-infographic/references/layouts/binary-comparison.md +48 -0
  1060. package/skills/creative/baoyu-infographic/references/layouts/bridge.md +41 -0
  1061. package/skills/creative/baoyu-infographic/references/layouts/circular-flow.md +41 -0
  1062. package/skills/creative/baoyu-infographic/references/layouts/comic-strip.md +41 -0
  1063. package/skills/creative/baoyu-infographic/references/layouts/comparison-matrix.md +41 -0
  1064. package/skills/creative/baoyu-infographic/references/layouts/dashboard.md +41 -0
  1065. package/skills/creative/baoyu-infographic/references/layouts/dense-modules.md +72 -0
  1066. package/skills/creative/baoyu-infographic/references/layouts/funnel.md +41 -0
  1067. package/skills/creative/baoyu-infographic/references/layouts/hierarchical-layers.md +48 -0
  1068. package/skills/creative/baoyu-infographic/references/layouts/hub-spoke.md +41 -0
  1069. package/skills/creative/baoyu-infographic/references/layouts/iceberg.md +41 -0
  1070. package/skills/creative/baoyu-infographic/references/layouts/isometric-map.md +41 -0
  1071. package/skills/creative/baoyu-infographic/references/layouts/jigsaw.md +41 -0
  1072. package/skills/creative/baoyu-infographic/references/layouts/linear-progression.md +48 -0
  1073. package/skills/creative/baoyu-infographic/references/layouts/periodic-table.md +41 -0
  1074. package/skills/creative/baoyu-infographic/references/layouts/story-mountain.md +41 -0
  1075. package/skills/creative/baoyu-infographic/references/layouts/structural-breakdown.md +48 -0
  1076. package/skills/creative/baoyu-infographic/references/layouts/tree-branching.md +41 -0
  1077. package/skills/creative/baoyu-infographic/references/layouts/venn-diagram.md +41 -0
  1078. package/skills/creative/baoyu-infographic/references/layouts/winding-roadmap.md +41 -0
  1079. package/skills/creative/baoyu-infographic/references/structured-content-template.md +244 -0
  1080. package/skills/creative/baoyu-infographic/references/styles/aged-academia.md +36 -0
  1081. package/skills/creative/baoyu-infographic/references/styles/bold-graphic.md +36 -0
  1082. package/skills/creative/baoyu-infographic/references/styles/chalkboard.md +61 -0
  1083. package/skills/creative/baoyu-infographic/references/styles/claymation.md +29 -0
  1084. package/skills/creative/baoyu-infographic/references/styles/corporate-memphis.md +29 -0
  1085. package/skills/creative/baoyu-infographic/references/styles/craft-handmade.md +44 -0
  1086. package/skills/creative/baoyu-infographic/references/styles/cyberpunk-neon.md +29 -0
  1087. package/skills/creative/baoyu-infographic/references/styles/hand-drawn-edu.md +63 -0
  1088. package/skills/creative/baoyu-infographic/references/styles/ikea-manual.md +29 -0
  1089. package/skills/creative/baoyu-infographic/references/styles/kawaii.md +29 -0
  1090. package/skills/creative/baoyu-infographic/references/styles/knolling.md +29 -0
  1091. package/skills/creative/baoyu-infographic/references/styles/lego-brick.md +29 -0
  1092. package/skills/creative/baoyu-infographic/references/styles/morandi-journal.md +60 -0
  1093. package/skills/creative/baoyu-infographic/references/styles/origami.md +29 -0
  1094. package/skills/creative/baoyu-infographic/references/styles/pixel-art.md +29 -0
  1095. package/skills/creative/baoyu-infographic/references/styles/pop-laboratory.md +48 -0
  1096. package/skills/creative/baoyu-infographic/references/styles/retro-pop-grid.md +47 -0
  1097. package/skills/creative/baoyu-infographic/references/styles/storybook-watercolor.md +29 -0
  1098. package/skills/creative/baoyu-infographic/references/styles/subway-map.md +29 -0
  1099. package/skills/creative/baoyu-infographic/references/styles/technical-schematic.md +36 -0
  1100. package/skills/creative/baoyu-infographic/references/styles/ui-wireframe.md +29 -0
  1101. package/skills/creative/claude-design/SKILL.md +591 -0
  1102. package/skills/creative/comfyui/SKILL.md +612 -0
  1103. package/skills/creative/comfyui/references/official-cli.md +255 -0
  1104. package/skills/creative/comfyui/references/rest-api.md +312 -0
  1105. package/skills/creative/comfyui/references/template-integrity.md +243 -0
  1106. package/skills/creative/comfyui/references/workflow-format.md +226 -0
  1107. package/skills/creative/comfyui/scripts/_common.py +835 -0
  1108. package/skills/creative/comfyui/scripts/auto_fix_deps.py +225 -0
  1109. package/skills/creative/comfyui/scripts/check_deps.py +437 -0
  1110. package/skills/creative/comfyui/scripts/comfyui_setup.sh +286 -0
  1111. package/skills/creative/comfyui/scripts/extract_schema.py +315 -0
  1112. package/skills/creative/comfyui/scripts/fetch_logs.py +158 -0
  1113. package/skills/creative/comfyui/scripts/hardware_check.py +497 -0
  1114. package/skills/creative/comfyui/scripts/health_check.py +223 -0
  1115. package/skills/creative/comfyui/scripts/run_batch.py +243 -0
  1116. package/skills/creative/comfyui/scripts/run_workflow.py +796 -0
  1117. package/skills/creative/comfyui/scripts/ws_monitor.py +267 -0
  1118. package/skills/creative/comfyui/tests/README.md +50 -0
  1119. package/skills/creative/comfyui/tests/conftest.py +64 -0
  1120. package/skills/creative/comfyui/tests/pytest.ini +5 -0
  1121. package/skills/creative/comfyui/tests/test_check_deps.py +68 -0
  1122. package/skills/creative/comfyui/tests/test_cloud_integration.py +95 -0
  1123. package/skills/creative/comfyui/tests/test_common.py +447 -0
  1124. package/skills/creative/comfyui/tests/test_extract_schema.py +185 -0
  1125. package/skills/creative/comfyui/tests/test_run_workflow.py +213 -0
  1126. package/skills/creative/comfyui/workflows/README.md +86 -0
  1127. package/skills/creative/comfyui/workflows/animatediff_video.json +64 -0
  1128. package/skills/creative/comfyui/workflows/flux_dev_txt2img.json +78 -0
  1129. package/skills/creative/comfyui/workflows/sd15_txt2img.json +49 -0
  1130. package/skills/creative/comfyui/workflows/sdxl_img2img.json +54 -0
  1131. package/skills/creative/comfyui/workflows/sdxl_inpaint.json +59 -0
  1132. package/skills/creative/comfyui/workflows/sdxl_txt2img.json +49 -0
  1133. package/skills/creative/comfyui/workflows/upscale_4x.json +27 -0
  1134. package/skills/creative/comfyui/workflows/wan_video_t2v.json +69 -0
  1135. package/skills/creative/creative-ideation/SKILL.md +152 -0
  1136. package/skills/creative/creative-ideation/references/full-prompt-library.md +110 -0
  1137. package/skills/creative/design-md/SKILL.md +199 -0
  1138. package/skills/creative/design-md/templates/starter.md +99 -0
  1139. package/skills/creative/excalidraw/SKILL.md +199 -0
  1140. package/skills/creative/excalidraw/references/colors.md +44 -0
  1141. package/skills/creative/excalidraw/references/dark-mode.md +68 -0
  1142. package/skills/creative/excalidraw/references/examples.md +141 -0
  1143. package/skills/creative/excalidraw/scripts/upload.py +133 -0
  1144. package/skills/creative/humanizer/LICENSE +21 -0
  1145. package/skills/creative/humanizer/SKILL.md +578 -0
  1146. package/skills/creative/manim-video/README.md +23 -0
  1147. package/skills/creative/manim-video/SKILL.md +269 -0
  1148. package/skills/creative/manim-video/references/animation-design-thinking.md +161 -0
  1149. package/skills/creative/manim-video/references/animations.md +282 -0
  1150. package/skills/creative/manim-video/references/camera-and-3d.md +135 -0
  1151. package/skills/creative/manim-video/references/decorations.md +202 -0
  1152. package/skills/creative/manim-video/references/equations.md +216 -0
  1153. package/skills/creative/manim-video/references/graphs-and-data.md +163 -0
  1154. package/skills/creative/manim-video/references/mobjects.md +333 -0
  1155. package/skills/creative/manim-video/references/paper-explainer.md +255 -0
  1156. package/skills/creative/manim-video/references/production-quality.md +190 -0
  1157. package/skills/creative/manim-video/references/rendering.md +185 -0
  1158. package/skills/creative/manim-video/references/scene-planning.md +118 -0
  1159. package/skills/creative/manim-video/references/troubleshooting.md +135 -0
  1160. package/skills/creative/manim-video/references/updaters-and-trackers.md +260 -0
  1161. package/skills/creative/manim-video/references/visual-design.md +124 -0
  1162. package/skills/creative/manim-video/scripts/setup.sh +14 -0
  1163. package/skills/creative/p5js/README.md +64 -0
  1164. package/skills/creative/p5js/SKILL.md +556 -0
  1165. package/skills/creative/p5js/references/animation.md +439 -0
  1166. package/skills/creative/p5js/references/color-systems.md +352 -0
  1167. package/skills/creative/p5js/references/core-api.md +410 -0
  1168. package/skills/creative/p5js/references/export-pipeline.md +566 -0
  1169. package/skills/creative/p5js/references/interaction.md +398 -0
  1170. package/skills/creative/p5js/references/shapes-and-geometry.md +300 -0
  1171. package/skills/creative/p5js/references/troubleshooting.md +532 -0
  1172. package/skills/creative/p5js/references/typography.md +302 -0
  1173. package/skills/creative/p5js/references/visual-effects.md +895 -0
  1174. package/skills/creative/p5js/references/webgl-and-3d.md +423 -0
  1175. package/skills/creative/p5js/scripts/export-frames.js +179 -0
  1176. package/skills/creative/p5js/scripts/render.sh +108 -0
  1177. package/skills/creative/p5js/scripts/serve.sh +28 -0
  1178. package/skills/creative/p5js/scripts/setup.sh +87 -0
  1179. package/skills/creative/p5js/templates/viewer.html +395 -0
  1180. package/skills/creative/pixel-art/ATTRIBUTION.md +54 -0
  1181. package/skills/creative/pixel-art/SKILL.md +218 -0
  1182. package/skills/creative/pixel-art/references/palettes.md +49 -0
  1183. package/skills/creative/pixel-art/scripts/__init__.py +0 -0
  1184. package/skills/creative/pixel-art/scripts/palettes.py +167 -0
  1185. package/skills/creative/pixel-art/scripts/pixel_art.py +162 -0
  1186. package/skills/creative/pixel-art/scripts/pixel_art_video.py +345 -0
  1187. package/skills/creative/popular-web-designs/SKILL.md +214 -0
  1188. package/skills/creative/popular-web-designs/templates/airbnb.md +259 -0
  1189. package/skills/creative/popular-web-designs/templates/airtable.md +102 -0
  1190. package/skills/creative/popular-web-designs/templates/apple.md +326 -0
  1191. package/skills/creative/popular-web-designs/templates/bmw.md +193 -0
  1192. package/skills/creative/popular-web-designs/templates/cal.md +272 -0
  1193. package/skills/creative/popular-web-designs/templates/claude.md +325 -0
  1194. package/skills/creative/popular-web-designs/templates/clay.md +317 -0
  1195. package/skills/creative/popular-web-designs/templates/clickhouse.md +294 -0
  1196. package/skills/creative/popular-web-designs/templates/cohere.md +279 -0
  1197. package/skills/creative/popular-web-designs/templates/coinbase.md +142 -0
  1198. package/skills/creative/popular-web-designs/templates/composio.md +320 -0
  1199. package/skills/creative/popular-web-designs/templates/cursor.md +322 -0
  1200. package/skills/creative/popular-web-designs/templates/elevenlabs.md +278 -0
  1201. package/skills/creative/popular-web-designs/templates/expo.md +294 -0
  1202. package/skills/creative/popular-web-designs/templates/figma.md +233 -0
  1203. package/skills/creative/popular-web-designs/templates/framer.md +259 -0
  1204. package/skills/creative/popular-web-designs/templates/hashicorp.md +291 -0
  1205. package/skills/creative/popular-web-designs/templates/ibm.md +345 -0
  1206. package/skills/creative/popular-web-designs/templates/intercom.md +159 -0
  1207. package/skills/creative/popular-web-designs/templates/kraken.md +138 -0
  1208. package/skills/creative/popular-web-designs/templates/linear.app.md +380 -0
  1209. package/skills/creative/popular-web-designs/templates/lovable.md +311 -0
  1210. package/skills/creative/popular-web-designs/templates/minimax.md +270 -0
  1211. package/skills/creative/popular-web-designs/templates/mintlify.md +339 -0
  1212. package/skills/creative/popular-web-designs/templates/miro.md +121 -0
  1213. package/skills/creative/popular-web-designs/templates/mistral.ai.md +274 -0
  1214. package/skills/creative/popular-web-designs/templates/mongodb.md +279 -0
  1215. package/skills/creative/popular-web-designs/templates/notion.md +322 -0
  1216. package/skills/creative/popular-web-designs/templates/nvidia.md +306 -0
  1217. package/skills/creative/popular-web-designs/templates/ollama.md +280 -0
  1218. package/skills/creative/popular-web-designs/templates/opencode.ai.md +294 -0
  1219. package/skills/creative/popular-web-designs/templates/pinterest.md +243 -0
  1220. package/skills/creative/popular-web-designs/templates/posthog.md +269 -0
  1221. package/skills/creative/popular-web-designs/templates/raycast.md +281 -0
  1222. package/skills/creative/popular-web-designs/templates/replicate.md +274 -0
  1223. package/skills/creative/popular-web-designs/templates/resend.md +316 -0
  1224. package/skills/creative/popular-web-designs/templates/revolut.md +198 -0
  1225. package/skills/creative/popular-web-designs/templates/runwayml.md +257 -0
  1226. package/skills/creative/popular-web-designs/templates/sanity.md +370 -0
  1227. package/skills/creative/popular-web-designs/templates/sentry.md +275 -0
  1228. package/skills/creative/popular-web-designs/templates/spacex.md +207 -0
  1229. package/skills/creative/popular-web-designs/templates/spotify.md +259 -0
  1230. package/skills/creative/popular-web-designs/templates/stripe.md +335 -0
  1231. package/skills/creative/popular-web-designs/templates/supabase.md +268 -0
  1232. package/skills/creative/popular-web-designs/templates/superhuman.md +265 -0
  1233. package/skills/creative/popular-web-designs/templates/together.ai.md +276 -0
  1234. package/skills/creative/popular-web-designs/templates/uber.md +308 -0
  1235. package/skills/creative/popular-web-designs/templates/vercel.md +323 -0
  1236. package/skills/creative/popular-web-designs/templates/voltagent.md +336 -0
  1237. package/skills/creative/popular-web-designs/templates/warp.md +266 -0
  1238. package/skills/creative/popular-web-designs/templates/webflow.md +105 -0
  1239. package/skills/creative/popular-web-designs/templates/wise.md +186 -0
  1240. package/skills/creative/popular-web-designs/templates/x.ai.md +270 -0
  1241. package/skills/creative/popular-web-designs/templates/zapier.md +341 -0
  1242. package/skills/creative/pretext/SKILL.md +220 -0
  1243. package/skills/creative/pretext/references/patterns.md +258 -0
  1244. package/skills/creative/pretext/templates/donut-orbit.html +1468 -0
  1245. package/skills/creative/pretext/templates/hello-orb-flow.html +95 -0
  1246. package/skills/creative/sketch/SKILL.md +218 -0
  1247. package/skills/creative/songwriting-and-ai-music/SKILL.md +287 -0
  1248. package/skills/creative/touchdesigner-mcp/SKILL.md +356 -0
  1249. package/skills/creative/touchdesigner-mcp/references/3d-scene.md +275 -0
  1250. package/skills/creative/touchdesigner-mcp/references/animation.md +221 -0
  1251. package/skills/creative/touchdesigner-mcp/references/audio-reactive.md +175 -0
  1252. package/skills/creative/touchdesigner-mcp/references/dat-scripting.md +352 -0
  1253. package/skills/creative/touchdesigner-mcp/references/external-data.md +322 -0
  1254. package/skills/creative/touchdesigner-mcp/references/geometry-comp.md +121 -0
  1255. package/skills/creative/touchdesigner-mcp/references/glsl.md +151 -0
  1256. package/skills/creative/touchdesigner-mcp/references/layout-compositor.md +131 -0
  1257. package/skills/creative/touchdesigner-mcp/references/mcp-tools.md +382 -0
  1258. package/skills/creative/touchdesigner-mcp/references/midi-osc.md +211 -0
  1259. package/skills/creative/touchdesigner-mcp/references/network-patterns.md +966 -0
  1260. package/skills/creative/touchdesigner-mcp/references/operator-tips.md +106 -0
  1261. package/skills/creative/touchdesigner-mcp/references/operators.md +239 -0
  1262. package/skills/creative/touchdesigner-mcp/references/panel-ui.md +281 -0
  1263. package/skills/creative/touchdesigner-mcp/references/particles.md +245 -0
  1264. package/skills/creative/touchdesigner-mcp/references/pitfalls.md +704 -0
  1265. package/skills/creative/touchdesigner-mcp/references/postfx.md +183 -0
  1266. package/skills/creative/touchdesigner-mcp/references/projection-mapping.md +211 -0
  1267. package/skills/creative/touchdesigner-mcp/references/python-api.md +463 -0
  1268. package/skills/creative/touchdesigner-mcp/references/replicator.md +198 -0
  1269. package/skills/creative/touchdesigner-mcp/references/troubleshooting.md +244 -0
  1270. package/skills/creative/touchdesigner-mcp/scripts/setup.sh +115 -0
  1271. package/skills/data-science/DESCRIPTION.md +3 -0
  1272. package/skills/data-science/jupyter-live-kernel/SKILL.md +167 -0
  1273. package/skills/devops/kanban-orchestrator/SKILL.md +189 -0
  1274. package/skills/devops/kanban-worker/SKILL.md +184 -0
  1275. package/skills/devops/webhook-subscriptions/SKILL.md +204 -0
  1276. package/skills/diagramming/DESCRIPTION.md +3 -0
  1277. package/skills/dogfood/SKILL.md +162 -0
  1278. package/skills/dogfood/references/issue-taxonomy.md +109 -0
  1279. package/skills/dogfood/templates/dogfood-report-template.md +86 -0
  1280. package/skills/domain/DESCRIPTION.md +24 -0
  1281. package/skills/email/DESCRIPTION.md +3 -0
  1282. package/skills/email/himalaya/SKILL.md +299 -0
  1283. package/skills/email/himalaya/references/configuration.md +227 -0
  1284. package/skills/email/himalaya/references/message-composition.md +199 -0
  1285. package/skills/gaming/DESCRIPTION.md +3 -0
  1286. package/skills/gaming/minecraft-modpack-server/SKILL.md +187 -0
  1287. package/skills/gaming/pokemon-player/SKILL.md +216 -0
  1288. package/skills/gifs/DESCRIPTION.md +3 -0
  1289. package/skills/github/DESCRIPTION.md +3 -0
  1290. package/skills/github/codebase-inspection/SKILL.md +116 -0
  1291. package/skills/github/github-auth/SKILL.md +247 -0
  1292. package/skills/github/github-auth/scripts/gh-env.sh +66 -0
  1293. package/skills/github/github-code-review/SKILL.md +481 -0
  1294. package/skills/github/github-code-review/references/review-output-template.md +74 -0
  1295. package/skills/github/github-issues/SKILL.md +370 -0
  1296. package/skills/github/github-issues/templates/bug-report.md +35 -0
  1297. package/skills/github/github-issues/templates/feature-request.md +31 -0
  1298. package/skills/github/github-pr-workflow/SKILL.md +367 -0
  1299. package/skills/github/github-pr-workflow/references/ci-troubleshooting.md +183 -0
  1300. package/skills/github/github-pr-workflow/references/conventional-commits.md +71 -0
  1301. package/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +35 -0
  1302. package/skills/github/github-pr-workflow/templates/pr-body-feature.md +33 -0
  1303. package/skills/github/github-repo-management/SKILL.md +516 -0
  1304. package/skills/github/github-repo-management/references/github-api-cheatsheet.md +161 -0
  1305. package/skills/index-cache/anthropics_skills_skills_.json +1 -0
  1306. package/skills/index-cache/claude_marketplace_anthropics_skills.json +1 -0
  1307. package/skills/index-cache/lobehub_index.json +1 -0
  1308. package/skills/index-cache/openai_skills_skills_.json +1 -0
  1309. package/skills/inference-sh/DESCRIPTION.md +19 -0
  1310. package/skills/mcp/DESCRIPTION.md +3 -0
  1311. package/skills/mcp/native-mcp/SKILL.md +357 -0
  1312. package/skills/media/DESCRIPTION.md +3 -0
  1313. package/skills/media/gif-search/SKILL.md +91 -0
  1314. package/skills/media/heartmula/SKILL.md +171 -0
  1315. package/skills/media/songsee/SKILL.md +83 -0
  1316. package/skills/media/spotify/SKILL.md +135 -0
  1317. package/skills/media/youtube-content/SKILL.md +73 -0
  1318. package/skills/media/youtube-content/references/output-formats.md +56 -0
  1319. package/skills/media/youtube-content/scripts/fetch_transcript.py +124 -0
  1320. package/skills/mlops/DESCRIPTION.md +3 -0
  1321. package/skills/mlops/evaluation/DESCRIPTION.md +3 -0
  1322. package/skills/mlops/evaluation/lm-evaluation-harness/SKILL.md +498 -0
  1323. package/skills/mlops/evaluation/lm-evaluation-harness/references/api-evaluation.md +490 -0
  1324. package/skills/mlops/evaluation/lm-evaluation-harness/references/benchmark-guide.md +488 -0
  1325. package/skills/mlops/evaluation/lm-evaluation-harness/references/custom-tasks.md +602 -0
  1326. package/skills/mlops/evaluation/lm-evaluation-harness/references/distributed-eval.md +519 -0
  1327. package/skills/mlops/evaluation/weights-and-biases/SKILL.md +594 -0
  1328. package/skills/mlops/evaluation/weights-and-biases/references/artifacts.md +584 -0
  1329. package/skills/mlops/evaluation/weights-and-biases/references/integrations.md +700 -0
  1330. package/skills/mlops/evaluation/weights-and-biases/references/sweeps.md +847 -0
  1331. package/skills/mlops/huggingface-hub/SKILL.md +81 -0
  1332. package/skills/mlops/inference/DESCRIPTION.md +3 -0
  1333. package/skills/mlops/inference/llama-cpp/SKILL.md +249 -0
  1334. package/skills/mlops/inference/llama-cpp/references/advanced-usage.md +504 -0
  1335. package/skills/mlops/inference/llama-cpp/references/hub-discovery.md +168 -0
  1336. package/skills/mlops/inference/llama-cpp/references/optimization.md +89 -0
  1337. package/skills/mlops/inference/llama-cpp/references/quantization.md +243 -0
  1338. package/skills/mlops/inference/llama-cpp/references/server.md +150 -0
  1339. package/skills/mlops/inference/llama-cpp/references/troubleshooting.md +442 -0
  1340. package/skills/mlops/inference/obliteratus/SKILL.md +342 -0
  1341. package/skills/mlops/inference/obliteratus/references/analysis-modules.md +166 -0
  1342. package/skills/mlops/inference/obliteratus/references/methods-guide.md +141 -0
  1343. package/skills/mlops/inference/obliteratus/templates/abliteration-config.yaml +33 -0
  1344. package/skills/mlops/inference/obliteratus/templates/analysis-study.yaml +40 -0
  1345. package/skills/mlops/inference/obliteratus/templates/batch-abliteration.yaml +41 -0
  1346. package/skills/mlops/inference/vllm/SKILL.md +372 -0
  1347. package/skills/mlops/inference/vllm/references/optimization.md +226 -0
  1348. package/skills/mlops/inference/vllm/references/quantization.md +284 -0
  1349. package/skills/mlops/inference/vllm/references/server-deployment.md +255 -0
  1350. package/skills/mlops/inference/vllm/references/troubleshooting.md +447 -0
  1351. package/skills/mlops/models/DESCRIPTION.md +3 -0
  1352. package/skills/mlops/models/audiocraft/SKILL.md +568 -0
  1353. package/skills/mlops/models/audiocraft/references/advanced-usage.md +666 -0
  1354. package/skills/mlops/models/audiocraft/references/troubleshooting.md +504 -0
  1355. package/skills/mlops/models/segment-anything/SKILL.md +506 -0
  1356. package/skills/mlops/models/segment-anything/references/advanced-usage.md +589 -0
  1357. package/skills/mlops/models/segment-anything/references/troubleshooting.md +484 -0
  1358. package/skills/mlops/research/DESCRIPTION.md +3 -0
  1359. package/skills/mlops/research/dspy/SKILL.md +594 -0
  1360. package/skills/mlops/research/dspy/references/examples.md +663 -0
  1361. package/skills/mlops/research/dspy/references/modules.md +475 -0
  1362. package/skills/mlops/research/dspy/references/optimizers.md +566 -0
  1363. package/skills/mlops/training/DESCRIPTION.md +3 -0
  1364. package/skills/mlops/vector-databases/DESCRIPTION.md +3 -0
  1365. package/skills/note-taking/DESCRIPTION.md +3 -0
  1366. package/skills/note-taking/obsidian/SKILL.md +61 -0
  1367. package/skills/productivity/DESCRIPTION.md +3 -0
  1368. package/skills/productivity/airtable/SKILL.md +229 -0
  1369. package/skills/productivity/google-workspace/SKILL.md +335 -0
  1370. package/skills/productivity/google-workspace/references/gmail-search-syntax.md +63 -0
  1371. package/skills/productivity/google-workspace/scripts/_hermes_home.py +43 -0
  1372. package/skills/productivity/google-workspace/scripts/google_api.py +1221 -0
  1373. package/skills/productivity/google-workspace/scripts/gws_bridge.py +108 -0
  1374. package/skills/productivity/google-workspace/scripts/setup.py +454 -0
  1375. package/skills/productivity/linear/SKILL.md +380 -0
  1376. package/skills/productivity/linear/scripts/linear_api.py +445 -0
  1377. package/skills/productivity/maps/SKILL.md +195 -0
  1378. package/skills/productivity/maps/scripts/maps_client.py +1298 -0
  1379. package/skills/productivity/nano-pdf/SKILL.md +52 -0
  1380. package/skills/productivity/notion/SKILL.md +448 -0
  1381. package/skills/productivity/notion/references/block-types.md +112 -0
  1382. package/skills/productivity/ocr-and-documents/DESCRIPTION.md +3 -0
  1383. package/skills/productivity/ocr-and-documents/SKILL.md +172 -0
  1384. package/skills/productivity/ocr-and-documents/scripts/extract_marker.py +87 -0
  1385. package/skills/productivity/ocr-and-documents/scripts/extract_pymupdf.py +98 -0
  1386. package/skills/productivity/powerpoint/LICENSE.txt +30 -0
  1387. package/skills/productivity/powerpoint/SKILL.md +237 -0
  1388. package/skills/productivity/powerpoint/editing.md +205 -0
  1389. package/skills/productivity/powerpoint/pptxgenjs.md +420 -0
  1390. package/skills/productivity/powerpoint/scripts/__init__.py +0 -0
  1391. package/skills/productivity/powerpoint/scripts/add_slide.py +195 -0
  1392. package/skills/productivity/powerpoint/scripts/clean.py +286 -0
  1393. package/skills/productivity/powerpoint/scripts/office/helpers/__init__.py +0 -0
  1394. package/skills/productivity/powerpoint/scripts/office/helpers/merge_runs.py +199 -0
  1395. package/skills/productivity/powerpoint/scripts/office/helpers/simplify_redlines.py +197 -0
  1396. package/skills/productivity/powerpoint/scripts/office/pack.py +159 -0
  1397. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  1398. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  1399. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  1400. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  1401. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  1402. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  1403. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  1404. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  1405. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  1406. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  1407. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  1408. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  1409. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  1410. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  1411. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  1412. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  1413. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  1414. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  1415. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  1416. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  1417. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  1418. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  1419. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  1420. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  1421. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  1422. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  1423. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  1424. package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-contentTypes.xsd +42 -0
  1425. package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-coreProperties.xsd +50 -0
  1426. package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-digSig.xsd +49 -0
  1427. package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-relationships.xsd +33 -0
  1428. package/skills/productivity/powerpoint/scripts/office/schemas/mce/mc.xsd +75 -0
  1429. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  1430. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  1431. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  1432. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  1433. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  1434. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  1435. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  1436. package/skills/productivity/teams-meeting-pipeline/SKILL.md +116 -0
  1437. package/skills/red-teaming/godmode/SKILL.md +404 -0
  1438. package/skills/red-teaming/godmode/references/jailbreak-templates.md +128 -0
  1439. package/skills/red-teaming/godmode/references/refusal-detection.md +142 -0
  1440. package/skills/red-teaming/godmode/scripts/auto_jailbreak.py +769 -0
  1441. package/skills/red-teaming/godmode/scripts/godmode_race.py +530 -0
  1442. package/skills/red-teaming/godmode/scripts/load_godmode.py +45 -0
  1443. package/skills/red-teaming/godmode/scripts/parseltongue.py +550 -0
  1444. package/skills/red-teaming/godmode/templates/prefill-subtle.json +10 -0
  1445. package/skills/red-teaming/godmode/templates/prefill.json +18 -0
  1446. package/skills/research/DESCRIPTION.md +3 -0
  1447. package/skills/research/arxiv/SKILL.md +282 -0
  1448. package/skills/research/arxiv/scripts/search_arxiv.py +114 -0
  1449. package/skills/research/blogwatcher/SKILL.md +137 -0
  1450. package/skills/research/llm-wiki/SKILL.md +507 -0
  1451. package/skills/research/polymarket/SKILL.md +77 -0
  1452. package/skills/research/polymarket/references/api-endpoints.md +220 -0
  1453. package/skills/research/polymarket/scripts/polymarket.py +284 -0
  1454. package/skills/research/research-paper-writing/SKILL.md +2377 -0
  1455. package/skills/research/research-paper-writing/references/autoreason-methodology.md +394 -0
  1456. package/skills/research/research-paper-writing/references/checklists.md +434 -0
  1457. package/skills/research/research-paper-writing/references/citation-workflow.md +564 -0
  1458. package/skills/research/research-paper-writing/references/experiment-patterns.md +728 -0
  1459. package/skills/research/research-paper-writing/references/human-evaluation.md +476 -0
  1460. package/skills/research/research-paper-writing/references/paper-types.md +481 -0
  1461. package/skills/research/research-paper-writing/references/reviewer-guidelines.md +433 -0
  1462. package/skills/research/research-paper-writing/references/sources.md +191 -0
  1463. package/skills/research/research-paper-writing/references/writing-guide.md +474 -0
  1464. package/skills/research/research-paper-writing/templates/README.md +251 -0
  1465. package/skills/research/research-paper-writing/templates/aaai2026/README.md +534 -0
  1466. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026-unified-supp.tex +144 -0
  1467. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026-unified-template.tex +952 -0
  1468. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.bib +111 -0
  1469. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.bst +1493 -0
  1470. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.sty +315 -0
  1471. package/skills/research/research-paper-writing/templates/acl/README.md +50 -0
  1472. package/skills/research/research-paper-writing/templates/acl/acl.sty +312 -0
  1473. package/skills/research/research-paper-writing/templates/acl/acl_latex.tex +377 -0
  1474. package/skills/research/research-paper-writing/templates/acl/acl_lualatex.tex +101 -0
  1475. package/skills/research/research-paper-writing/templates/acl/acl_natbib.bst +1940 -0
  1476. package/skills/research/research-paper-writing/templates/acl/anthology.bib.txt +26 -0
  1477. package/skills/research/research-paper-writing/templates/acl/custom.bib +70 -0
  1478. package/skills/research/research-paper-writing/templates/acl/formatting.md +326 -0
  1479. package/skills/research/research-paper-writing/templates/colm2025/README.md +3 -0
  1480. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.bib +11 -0
  1481. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.bst +1440 -0
  1482. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.pdf +0 -0
  1483. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.sty +218 -0
  1484. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.tex +305 -0
  1485. package/skills/research/research-paper-writing/templates/colm2025/fancyhdr.sty +485 -0
  1486. package/skills/research/research-paper-writing/templates/colm2025/math_commands.tex +508 -0
  1487. package/skills/research/research-paper-writing/templates/colm2025/natbib.sty +1246 -0
  1488. package/skills/research/research-paper-writing/templates/iclr2026/fancyhdr.sty +485 -0
  1489. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.bib +24 -0
  1490. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.bst +1440 -0
  1491. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.pdf +0 -0
  1492. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.sty +246 -0
  1493. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.tex +414 -0
  1494. package/skills/research/research-paper-writing/templates/iclr2026/math_commands.tex +508 -0
  1495. package/skills/research/research-paper-writing/templates/iclr2026/natbib.sty +1246 -0
  1496. package/skills/research/research-paper-writing/templates/icml2026/algorithm.sty +79 -0
  1497. package/skills/research/research-paper-writing/templates/icml2026/algorithmic.sty +201 -0
  1498. package/skills/research/research-paper-writing/templates/icml2026/example_paper.bib +75 -0
  1499. package/skills/research/research-paper-writing/templates/icml2026/example_paper.pdf +0 -0
  1500. package/skills/research/research-paper-writing/templates/icml2026/example_paper.tex +662 -0
  1501. package/skills/research/research-paper-writing/templates/icml2026/fancyhdr.sty +864 -0
  1502. package/skills/research/research-paper-writing/templates/icml2026/icml2026.bst +1443 -0
  1503. package/skills/research/research-paper-writing/templates/icml2026/icml2026.sty +767 -0
  1504. package/skills/research/research-paper-writing/templates/icml2026/icml_numpapers.pdf +0 -0
  1505. package/skills/research/research-paper-writing/templates/neurips2025/Makefile +36 -0
  1506. package/skills/research/research-paper-writing/templates/neurips2025/extra_pkgs.tex +53 -0
  1507. package/skills/research/research-paper-writing/templates/neurips2025/main.tex +38 -0
  1508. package/skills/research/research-paper-writing/templates/neurips2025/neurips.sty +382 -0
  1509. package/skills/smart-home/DESCRIPTION.md +3 -0
  1510. package/skills/smart-home/openhue/SKILL.md +109 -0
  1511. package/skills/social-media/DESCRIPTION.md +3 -0
  1512. package/skills/social-media/xurl/SKILL.md +414 -0
  1513. package/skills/software-development/debugging-hermes-tui-commands/SKILL.md +152 -0
  1514. package/skills/software-development/hermes-agent-skill-authoring/SKILL.md +165 -0
  1515. package/skills/software-development/node-inspect-debugger/SKILL.md +319 -0
  1516. package/skills/software-development/plan/SKILL.md +58 -0
  1517. package/skills/software-development/python-debugpy/SKILL.md +375 -0
  1518. package/skills/software-development/requesting-code-review/SKILL.md +280 -0
  1519. package/skills/software-development/spike/SKILL.md +197 -0
  1520. package/skills/software-development/subagent-driven-development/SKILL.md +352 -0
  1521. package/skills/software-development/subagent-driven-development/references/context-budget-discipline.md +53 -0
  1522. package/skills/software-development/subagent-driven-development/references/gates-taxonomy.md +93 -0
  1523. package/skills/software-development/systematic-debugging/SKILL.md +367 -0
  1524. package/skills/software-development/test-driven-development/SKILL.md +343 -0
  1525. package/skills/software-development/writing-plans/SKILL.md +297 -0
  1526. package/skills/yuanbao/SKILL.md +108 -0
  1527. package/tools/__init__.py +25 -0
  1528. package/tools/__pycache__/__init__.cpython-312.pyc +0 -0
  1529. package/tools/__pycache__/approval.cpython-312.pyc +0 -0
  1530. package/tools/__pycache__/binary_extensions.cpython-312.pyc +0 -0
  1531. package/tools/__pycache__/browser_camofox.cpython-312.pyc +0 -0
  1532. package/tools/__pycache__/browser_camofox_state.cpython-312.pyc +0 -0
  1533. package/tools/__pycache__/browser_cdp_tool.cpython-312.pyc +0 -0
  1534. package/tools/__pycache__/browser_dialog_tool.cpython-312.pyc +0 -0
  1535. package/tools/__pycache__/browser_supervisor.cpython-312.pyc +0 -0
  1536. package/tools/__pycache__/browser_tool.cpython-312.pyc +0 -0
  1537. package/tools/__pycache__/budget_config.cpython-312.pyc +0 -0
  1538. package/tools/__pycache__/checkpoint_manager.cpython-312.pyc +0 -0
  1539. package/tools/__pycache__/clarify_gateway.cpython-312.pyc +0 -0
  1540. package/tools/__pycache__/clarify_tool.cpython-312.pyc +0 -0
  1541. package/tools/__pycache__/code_execution_tool.cpython-312.pyc +0 -0
  1542. package/tools/__pycache__/computer_use_tool.cpython-312.pyc +0 -0
  1543. package/tools/__pycache__/cronjob_tools.cpython-312.pyc +0 -0
  1544. package/tools/__pycache__/debug_helpers.cpython-312.pyc +0 -0
  1545. package/tools/__pycache__/delegate_tool.cpython-312.pyc +0 -0
  1546. package/tools/__pycache__/discord_tool.cpython-312.pyc +0 -0
  1547. package/tools/__pycache__/feishu_doc_tool.cpython-312.pyc +0 -0
  1548. package/tools/__pycache__/feishu_drive_tool.cpython-312.pyc +0 -0
  1549. package/tools/__pycache__/file_operations.cpython-312.pyc +0 -0
  1550. package/tools/__pycache__/file_state.cpython-312.pyc +0 -0
  1551. package/tools/__pycache__/file_tools.cpython-312.pyc +0 -0
  1552. package/tools/__pycache__/homeassistant_tool.cpython-312.pyc +0 -0
  1553. package/tools/__pycache__/image_generation_tool.cpython-312.pyc +0 -0
  1554. package/tools/__pycache__/interrupt.cpython-312.pyc +0 -0
  1555. package/tools/__pycache__/kanban_tools.cpython-312.pyc +0 -0
  1556. package/tools/__pycache__/lazy_deps.cpython-312.pyc +0 -0
  1557. package/tools/__pycache__/managed_tool_gateway.cpython-312.pyc +0 -0
  1558. package/tools/__pycache__/mcp_tool.cpython-312.pyc +0 -0
  1559. package/tools/__pycache__/memory_tool.cpython-312.pyc +0 -0
  1560. package/tools/__pycache__/mixture_of_agents_tool.cpython-312.pyc +0 -0
  1561. package/tools/__pycache__/openrouter_client.cpython-312.pyc +0 -0
  1562. package/tools/__pycache__/process_registry.cpython-312.pyc +0 -0
  1563. package/tools/__pycache__/registry.cpython-312.pyc +0 -0
  1564. package/tools/__pycache__/schema_sanitizer.cpython-312.pyc +0 -0
  1565. package/tools/__pycache__/send_message_tool.cpython-312.pyc +0 -0
  1566. package/tools/__pycache__/session_search_tool.cpython-312.pyc +0 -0
  1567. package/tools/__pycache__/skill_manager_tool.cpython-312.pyc +0 -0
  1568. package/tools/__pycache__/skill_provenance.cpython-312.pyc +0 -0
  1569. package/tools/__pycache__/skill_usage.cpython-312.pyc +0 -0
  1570. package/tools/__pycache__/skills_guard.cpython-312.pyc +0 -0
  1571. package/tools/__pycache__/skills_sync.cpython-312.pyc +0 -0
  1572. package/tools/__pycache__/skills_tool.cpython-312.pyc +0 -0
  1573. package/tools/__pycache__/slash_confirm.cpython-312.pyc +0 -0
  1574. package/tools/__pycache__/terminal_tool.cpython-312.pyc +0 -0
  1575. package/tools/__pycache__/tirith_security.cpython-312.pyc +0 -0
  1576. package/tools/__pycache__/todo_tool.cpython-312.pyc +0 -0
  1577. package/tools/__pycache__/tool_backend_helpers.cpython-312.pyc +0 -0
  1578. package/tools/__pycache__/tool_result_storage.cpython-312.pyc +0 -0
  1579. package/tools/__pycache__/tts_tool.cpython-312.pyc +0 -0
  1580. package/tools/__pycache__/url_safety.cpython-312.pyc +0 -0
  1581. package/tools/__pycache__/video_generation_tool.cpython-312.pyc +0 -0
  1582. package/tools/__pycache__/vision_tools.cpython-312.pyc +0 -0
  1583. package/tools/__pycache__/voice_mode.cpython-312.pyc +0 -0
  1584. package/tools/__pycache__/web_tools.cpython-312.pyc +0 -0
  1585. package/tools/__pycache__/website_policy.cpython-312.pyc +0 -0
  1586. package/tools/__pycache__/x_search_tool.cpython-312.pyc +0 -0
  1587. package/tools/__pycache__/xai_http.cpython-312.pyc +0 -0
  1588. package/tools/__pycache__/yuanbao_tools.cpython-312.pyc +0 -0
  1589. package/tools/ansi_strip.py +44 -0
  1590. package/tools/approval.py +1392 -0
  1591. package/tools/binary_extensions.py +42 -0
  1592. package/tools/browser_camofox.py +700 -0
  1593. package/tools/browser_camofox_state.py +48 -0
  1594. package/tools/browser_cdp_tool.py +569 -0
  1595. package/tools/browser_dialog_tool.py +148 -0
  1596. package/tools/browser_providers/__init__.py +10 -0
  1597. package/tools/browser_providers/__pycache__/__init__.cpython-312.pyc +0 -0
  1598. package/tools/browser_providers/__pycache__/base.cpython-312.pyc +0 -0
  1599. package/tools/browser_providers/__pycache__/browser_use.cpython-312.pyc +0 -0
  1600. package/tools/browser_providers/__pycache__/browserbase.cpython-312.pyc +0 -0
  1601. package/tools/browser_providers/__pycache__/firecrawl.cpython-312.pyc +0 -0
  1602. package/tools/browser_providers/base.py +59 -0
  1603. package/tools/browser_providers/browser_use.py +225 -0
  1604. package/tools/browser_providers/browserbase.py +222 -0
  1605. package/tools/browser_providers/firecrawl.py +112 -0
  1606. package/tools/browser_supervisor.py +1457 -0
  1607. package/tools/browser_tool.py +3676 -0
  1608. package/tools/budget_config.py +51 -0
  1609. package/tools/checkpoint_manager.py +1639 -0
  1610. package/tools/clarify_gateway.py +278 -0
  1611. package/tools/clarify_tool.py +141 -0
  1612. package/tools/code_execution_tool.py +1782 -0
  1613. package/tools/computer_use/__init__.py +43 -0
  1614. package/tools/computer_use/__pycache__/__init__.cpython-312.pyc +0 -0
  1615. package/tools/computer_use/__pycache__/backend.cpython-312.pyc +0 -0
  1616. package/tools/computer_use/__pycache__/schema.cpython-312.pyc +0 -0
  1617. package/tools/computer_use/__pycache__/tool.cpython-312.pyc +0 -0
  1618. package/tools/computer_use/backend.py +150 -0
  1619. package/tools/computer_use/cua_backend.py +682 -0
  1620. package/tools/computer_use/schema.py +191 -0
  1621. package/tools/computer_use/tool.py +521 -0
  1622. package/tools/computer_use_tool.py +39 -0
  1623. package/tools/credential_files.py +437 -0
  1624. package/tools/cronjob_tools.py +719 -0
  1625. package/tools/debug_helpers.py +106 -0
  1626. package/tools/delegate_tool.py +2797 -0
  1627. package/tools/discord_tool.py +959 -0
  1628. package/tools/env_passthrough.py +145 -0
  1629. package/tools/environments/__init__.py +14 -0
  1630. package/tools/environments/__pycache__/__init__.cpython-312.pyc +0 -0
  1631. package/tools/environments/__pycache__/base.cpython-312.pyc +0 -0
  1632. package/tools/environments/__pycache__/docker.cpython-312.pyc +0 -0
  1633. package/tools/environments/__pycache__/file_sync.cpython-312.pyc +0 -0
  1634. package/tools/environments/__pycache__/local.cpython-312.pyc +0 -0
  1635. package/tools/environments/__pycache__/managed_modal.cpython-312.pyc +0 -0
  1636. package/tools/environments/__pycache__/modal.cpython-312.pyc +0 -0
  1637. package/tools/environments/__pycache__/modal_utils.cpython-312.pyc +0 -0
  1638. package/tools/environments/__pycache__/singularity.cpython-312.pyc +0 -0
  1639. package/tools/environments/__pycache__/ssh.cpython-312.pyc +0 -0
  1640. package/tools/environments/base.py +844 -0
  1641. package/tools/environments/daytona.py +270 -0
  1642. package/tools/environments/docker.py +656 -0
  1643. package/tools/environments/file_sync.py +400 -0
  1644. package/tools/environments/local.py +658 -0
  1645. package/tools/environments/managed_modal.py +282 -0
  1646. package/tools/environments/modal.py +479 -0
  1647. package/tools/environments/modal_utils.py +199 -0
  1648. package/tools/environments/singularity.py +263 -0
  1649. package/tools/environments/ssh.py +295 -0
  1650. package/tools/environments/vercel_sandbox.py +655 -0
  1651. package/tools/feishu_doc_tool.py +138 -0
  1652. package/tools/feishu_drive_tool.py +431 -0
  1653. package/tools/file_operations.py +1825 -0
  1654. package/tools/file_state.py +332 -0
  1655. package/tools/file_tools.py +1172 -0
  1656. package/tools/fuzzy_match.py +703 -0
  1657. package/tools/homeassistant_tool.py +513 -0
  1658. package/tools/image_generation_tool.py +1098 -0
  1659. package/tools/interrupt.py +98 -0
  1660. package/tools/kanban_tools.py +1139 -0
  1661. package/tools/lazy_deps.py +608 -0
  1662. package/tools/managed_tool_gateway.py +168 -0
  1663. package/tools/mcp_oauth.py +633 -0
  1664. package/tools/mcp_oauth_manager.py +607 -0
  1665. package/tools/mcp_tool.py +3483 -0
  1666. package/tools/memory_tool.py +584 -0
  1667. package/tools/microsoft_graph_auth.py +245 -0
  1668. package/tools/microsoft_graph_client.py +408 -0
  1669. package/tools/mixture_of_agents_tool.py +542 -0
  1670. package/tools/neutts_samples/jo.txt +1 -0
  1671. package/tools/neutts_samples/jo.wav +0 -0
  1672. package/tools/neutts_synth.py +104 -0
  1673. package/tools/openrouter_client.py +33 -0
  1674. package/tools/osv_check.py +155 -0
  1675. package/tools/patch_parser.py +592 -0
  1676. package/tools/path_security.py +43 -0
  1677. package/tools/process_registry.py +1534 -0
  1678. package/tools/registry.py +589 -0
  1679. package/tools/schema_sanitizer.py +370 -0
  1680. package/tools/send_message_tool.py +1900 -0
  1681. package/tools/session_search_tool.py +613 -0
  1682. package/tools/skill_manager_tool.py +932 -0
  1683. package/tools/skill_provenance.py +78 -0
  1684. package/tools/skill_usage.py +610 -0
  1685. package/tools/skills_guard.py +932 -0
  1686. package/tools/skills_hub.py +3263 -0
  1687. package/tools/skills_sync.py +432 -0
  1688. package/tools/skills_tool.py +1569 -0
  1689. package/tools/slash_confirm.py +167 -0
  1690. package/tools/terminal_tool.py +2376 -0
  1691. package/tools/tirith_security.py +775 -0
  1692. package/tools/todo_tool.py +277 -0
  1693. package/tools/tool_backend_helpers.py +144 -0
  1694. package/tools/tool_output_limits.py +92 -0
  1695. package/tools/tool_result_storage.py +232 -0
  1696. package/tools/transcription_tools.py +936 -0
  1697. package/tools/tts_tool.py +2285 -0
  1698. package/tools/url_safety.py +330 -0
  1699. package/tools/video_generation_tool.py +561 -0
  1700. package/tools/vision_tools.py +1422 -0
  1701. package/tools/voice_mode.py +1019 -0
  1702. package/tools/web_tools.py +1551 -0
  1703. package/tools/website_policy.py +283 -0
  1704. package/tools/x_search_tool.py +424 -0
  1705. package/tools/xai_http.py +83 -0
  1706. package/tools/yuanbao_tools.py +736 -0
  1707. package/toolset_distributions.py +364 -0
  1708. package/toolsets.py +866 -0
  1709. package/trajectory_compressor.py +1509 -0
  1710. package/tui_gateway/__init__.py +0 -0
  1711. package/tui_gateway/entry.py +251 -0
  1712. package/tui_gateway/event_publisher.py +126 -0
  1713. package/tui_gateway/render.py +49 -0
  1714. package/tui_gateway/server.py +6623 -0
  1715. package/tui_gateway/slash_worker.py +76 -0
  1716. package/tui_gateway/transport.py +219 -0
  1717. package/tui_gateway/ws.py +178 -0
  1718. package/utils.py +361 -0
@@ -0,0 +1,1728 @@
1
+ """Слэш-команды и автодополнение для Calvyn Code.
2
+
3
+ Central registry for all slash commands. Every consumer -- CLI help, gateway
4
+ dispatch, Telegram BotCommands, Slack subcommand mapping, autocomplete --
5
+ derives its data from ``COMMAND_REGISTRY``.
6
+
7
+ To add a command: add a ``CommandDef`` entry to ``COMMAND_REGISTRY``.
8
+ To add an alias: set ``aliases=("short",)`` on the existing ``CommandDef``.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import logging
14
+ import os
15
+ import re
16
+ import shutil
17
+ import subprocess
18
+ import time
19
+ from collections.abc import Callable, Mapping
20
+ from dataclasses import dataclass
21
+ from typing import Any
22
+
23
+ from utils import is_truthy_value
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+ # prompt_toolkit is an optional CLI dependency — only needed for
28
+ # SlashCommandCompleter and SlashCommandAutoSuggest. Gateway and test
29
+ # environments that lack it must still be able to import this module
30
+ # for resolve_command, gateway_help_lines, and COMMAND_REGISTRY.
31
+ try:
32
+ from prompt_toolkit.auto_suggest import AutoSuggest, Suggestion
33
+ from prompt_toolkit.completion import Completer, Completion
34
+ except ImportError: # pragma: no cover
35
+ AutoSuggest = object # type: ignore[assignment,misc]
36
+ Completer = object # type: ignore[assignment,misc]
37
+ Suggestion = None # type: ignore[assignment]
38
+ Completion = None # type: ignore[assignment]
39
+
40
+
41
+ # ---------------------------------------------------------------------------
42
+ # CommandDef dataclass
43
+ # ---------------------------------------------------------------------------
44
+
45
+ @dataclass(frozen=True)
46
+ class CommandDef:
47
+ """Definition of a single slash command."""
48
+
49
+ name: str # canonical name without slash: "background"
50
+ description: str # human-readable description
51
+ category: str # "Session", "Configuration", etc.
52
+ aliases: tuple[str, ...] = () # alternative names: ("bg",)
53
+ args_hint: str = "" # argument placeholder: "<prompt>", "[name]"
54
+ subcommands: tuple[str, ...] = () # tab-completable subcommands
55
+ cli_only: bool = False # only available in CLI
56
+ gateway_only: bool = False # only available in gateway/messaging
57
+ gateway_config_gate: str | None = None # config dotpath; when truthy, overrides cli_only for gateway
58
+
59
+
60
+ # ---------------------------------------------------------------------------
61
+ # Central registry -- single source of truth
62
+ # ---------------------------------------------------------------------------
63
+
64
+ COMMAND_REGISTRY: list[CommandDef] = [
65
+ # Session
66
+ CommandDef("new", "Начать новую сессию", "Session",
67
+ aliases=("reset",), args_hint="[name]"),
68
+ CommandDef("topic", "Включить или посмотреть topic-сессии в Telegram", "Session",
69
+ gateway_only=True, args_hint="[off|help|session-id]"),
70
+ CommandDef("clear", "Очистить экран и начать новую сессию", "Session",
71
+ cli_only=True),
72
+ CommandDef("redraw", "Перерисовать интерфейс заново", "Session",
73
+ cli_only=True),
74
+ CommandDef("history", "Показать историю диалога", "Session",
75
+ cli_only=True),
76
+ CommandDef("save", "Сохранить текущий диалог", "Session",
77
+ cli_only=True),
78
+ CommandDef("retry", "Повторить последний запрос", "Session"),
79
+ CommandDef("undo", "Убрать последний обмен сообщениями", "Session"),
80
+ CommandDef("title", "Поставить название текущей сессии", "Session",
81
+ args_hint="[name]"),
82
+ CommandDef("handoff", "Передать эту сессию в мессенджер", "Session",
83
+ args_hint="<platform>", cli_only=True),
84
+ CommandDef("branch", "Ответвить текущую сессию", "Session",
85
+ aliases=("fork",), args_hint="[name]"),
86
+ CommandDef("compress", "Сжать контекст диалога вручную", "Session",
87
+ args_hint="[focus topic]"),
88
+ CommandDef("rollback", "Показать или восстановить точки отката", "Session",
89
+ args_hint="[number]"),
90
+ CommandDef("snapshot", "Создать или восстановить снимок состояния", "Session",
91
+ cli_only=True, aliases=("snap",), args_hint="[create|restore <id>|prune]"),
92
+ CommandDef("stop", "Остановить фоновые процессы", "Session"),
93
+ CommandDef("approve", "Разрешить ожидающую опасную команду", "Session",
94
+ gateway_only=True, args_hint="[session|always]"),
95
+ CommandDef("deny", "Запретить ожидающую опасную команду", "Session",
96
+ gateway_only=True),
97
+ CommandDef("background", "Запустить задачу в фоне", "Session",
98
+ aliases=("bg", "btw"), args_hint="<prompt>"),
99
+ CommandDef("agents", "Показать активные агенты и задачи", "Session",
100
+ aliases=("tasks",)),
101
+ CommandDef("queue", "Поставить сообщение в очередь на следующий ход, без прерывания", "Session",
102
+ aliases=("q",), args_hint="<prompt>"),
103
+ CommandDef("steer", "Вставить сообщение после следующего вызова инструмента, без прерывания", "Session",
104
+ args_hint="<prompt>"),
105
+ CommandDef("goal", "Поставить постоянную цель, над которой Calvyn будет работать до результата", "Session",
106
+ args_hint="[text | pause | resume | clear | status]"),
107
+ CommandDef("subgoal", "Добавить или поменять доп условия для активной цели", "Session",
108
+ args_hint="[text | remove N | clear]"),
109
+ CommandDef("status", "Показать инфу о сессии", "Session"),
110
+ CommandDef("whoami", "Показать свой доступ к slash-командам (админ / пользователь)", "Info"),
111
+ CommandDef("profile", "Показать имя активного профиля и домашнюю папку", "Info"),
112
+ CommandDef("sethome", "Set this chat as the home channel", "Session",
113
+ gateway_only=True, aliases=("set-home",)),
114
+ CommandDef("resume", "Продолжить ранее названную сессию", "Session",
115
+ args_hint="[name]"),
116
+
117
+ # Configuration
118
+ CommandDef("sessions", "Посмотреть и продолжить прошлые сессии", "Session"),
119
+
120
+ # Configuration
121
+ CommandDef("config", "Показать текущие настройки", "Configuration",
122
+ cli_only=True),
123
+ CommandDef("model", "Переключить модель для этой сессии", "Configuration",
124
+ aliases=("provider",), args_hint="[model] [--provider name] [--global]"),
125
+ CommandDef("codex-runtime", "Включить или выключить runtime app-сервера для моделей OpenAI/Codex",
126
+ "Configuration", args_hint="[auto|codex_app_server]"),
127
+ CommandDef("gquota", "Показать расход квоты Google Gemini Code Assist", "Info",
128
+ cli_only=True),
129
+
130
+ CommandDef("personality", "Выбрать готовый стиль общения", "Configuration",
131
+ args_hint="[name]"),
132
+ CommandDef("statusbar", "Показать или скрыть строку статуса с контекстом и моделью", "Configuration",
133
+ cli_only=True, aliases=("sb",)),
134
+ CommandDef("verbose", "Переключать показ прогресса инструментов: выкл -> новое -> всё -> verbose",
135
+ "Configuration", cli_only=True,
136
+ gateway_config_gate="display.tool_progress_command"),
137
+ CommandDef("footer", "Показать или скрыть футер с метаданными на финальных ответах",
138
+ "Configuration", args_hint="[on|off|status]",
139
+ subcommands=("on", "off", "status")),
140
+ CommandDef("yolo", "Включить YOLO-режим (пропускать все подтверждения опасных команд)",
141
+ "Configuration"),
142
+ CommandDef("reasoning", "Управлять глубиной рассуждений и тем, как она показывается", "Configuration",
143
+ args_hint="[level|show|hide]",
144
+ subcommands=("none", "minimal", "low", "medium", "high", "xhigh", "show", "hide", "on", "off")),
145
+ CommandDef("fast", "Включить быстрый режим — OpenAI Priority Processing / Anthropic Fast Mode (Normal/Fast)", "Configuration",
146
+ args_hint="[normal|fast|status]",
147
+ subcommands=("normal", "fast", "status", "on", "off")),
148
+ CommandDef("skin", "Показать или сменить тему интерфейса", "Configuration",
149
+ cli_only=True, args_hint="[name]"),
150
+ CommandDef("indicator", "Выбрать стиль индикатора занятости в TUI", "Configuration",
151
+ cli_only=True, args_hint="[kaomoji|emoji|unicode|ascii]",
152
+ subcommands=("kaomoji", "emoji", "unicode", "ascii")),
153
+ CommandDef("voice", "Включить или выключить голосовой режим", "Configuration",
154
+ args_hint="[on|off|tts|status]", subcommands=("on", "off", "tts", "status")),
155
+ CommandDef("busy", "Настроить, что делает Enter, когда Calvyn занят", "Configuration",
156
+ cli_only=True, args_hint="[queue|steer|interrupt|status]",
157
+ subcommands=("queue", "steer", "interrupt", "status")),
158
+
159
+ # Tools & Skills
160
+ CommandDef("tools", "Управлять инструментами: /tools [list|disable|enable] [name...]", "Tools & Skills",
161
+ args_hint="[list|disable|enable] [name...]", cli_only=True),
162
+ CommandDef("toolsets", "Показать доступные наборы инструментов", "Tools & Skills",
163
+ cli_only=True),
164
+ CommandDef("skills", "Искать, ставить, смотреть и управлять skills",
165
+ "Tools & Skills", cli_only=True,
166
+ subcommands=("search", "browse", "inspect", "install")),
167
+ CommandDef("cron", "Управлять запланированными задачами", "Tools & Skills",
168
+ cli_only=True, args_hint="[subcommand]",
169
+ subcommands=("list", "add", "create", "edit", "pause", "resume", "run", "remove")),
170
+ CommandDef("curator", "Фоновое обслуживание skills (status, run, pin, archive, list-archived)",
171
+ "Tools & Skills", args_hint="[subcommand]",
172
+ subcommands=("status", "run", "pause", "resume", "pin", "unpin", "restore", "list-archived")),
173
+ CommandDef("kanban", "Доска для совместной работы по профилям (задачи, связи, комменты)",
174
+ "Tools & Skills", args_hint="[subcommand]",
175
+ subcommands=("list", "ls", "show", "create", "assign", "link", "unlink",
176
+ "claim", "comment", "complete", "block", "unblock", "archive",
177
+ "tail", "dispatch", "context", "init", "gc")),
178
+ CommandDef("reload", "Перечитать переменные из .env в текущую сессию", "Tools & Skills",
179
+ cli_only=True),
180
+ CommandDef("reload-mcp", "Перезагрузить MCP-серверы из конфига", "Tools & Skills",
181
+ aliases=("reload_mcp",)),
182
+ CommandDef("reload-skills", "Снова просканировать ~/.hermes/skills/ на новые или удаленные skills",
183
+ "Tools & Skills", aliases=("reload_skills",)),
184
+ CommandDef("browser", "Подключить браузерные инструменты к открытому Chrome через CDP", "Tools & Skills",
185
+ cli_only=True, args_hint="[connect|disconnect|status]",
186
+ subcommands=("connect", "disconnect", "status")),
187
+ CommandDef("plugins", "Показать установленные плагины и их статус",
188
+ "Tools & Skills", cli_only=True),
189
+
190
+ # Info
191
+ CommandDef("commands", "Открыть все команды и skills постранично", "Info",
192
+ gateway_only=True, args_hint="[page]"),
193
+ CommandDef("help", "Показать доступные команды", "Info"),
194
+ CommandDef("restart", "Аккуратно перезапустить gateway после завершения активных задач", "Session",
195
+ gateway_only=True),
196
+ CommandDef("usage", "Показать расход токенов и лимиты", "Info"),
197
+ CommandDef("insights", "Показать статистику использования", "Info",
198
+ args_hint="[days]"),
199
+ CommandDef("platforms", "Показать статус платформ и шлюзов", "Info",
200
+ cli_only=True, aliases=("gateway",)),
201
+ CommandDef("platform", "Пауза запуск или список проблемной платформы", "Info",
202
+ gateway_only=True, args_hint="<pause|resume|list> [name]"),
203
+ CommandDef("copy", "Скопировать последний ответ в буфер", "Info",
204
+ cli_only=True, args_hint="[number]"),
205
+ CommandDef("paste", "Прикрепить картинку из буфера", "Info",
206
+ cli_only=True),
207
+ CommandDef("image", "Прикрепить локальную картинку к следующему запросу", "Info",
208
+ cli_only=True, args_hint="<path>"),
209
+ CommandDef("update", "Обновить Calvyn Code до новой версии", "Info",
210
+ gateway_only=True),
211
+ CommandDef("debug", "Отправить debug-отчет и получить ссылку", "Info"),
212
+
213
+ # Exit
214
+ CommandDef("quit", "Выйти из консоли", "Exit",
215
+ cli_only=True, aliases=("exit",)),
216
+ ]
217
+
218
+
219
+ # ---------------------------------------------------------------------------
220
+ # Derived lookups -- rebuilt once at import time, refreshed by rebuild_lookups()
221
+ # ---------------------------------------------------------------------------
222
+
223
+ def _build_command_lookup() -> dict[str, CommandDef]:
224
+ """Map every name and alias to its CommandDef."""
225
+ lookup: dict[str, CommandDef] = {}
226
+ for cmd in COMMAND_REGISTRY:
227
+ lookup[cmd.name] = cmd
228
+ for alias in cmd.aliases:
229
+ lookup[alias] = cmd
230
+ return lookup
231
+
232
+
233
+ _COMMAND_LOOKUP: dict[str, CommandDef] = _build_command_lookup()
234
+
235
+
236
+ def resolve_command(name: str) -> CommandDef | None:
237
+ """Resolve a command name or alias to its CommandDef.
238
+
239
+ Accepts names with or without the leading slash.
240
+ """
241
+ return _COMMAND_LOOKUP.get(name.lower().lstrip("/"))
242
+
243
+
244
+ def _build_description(cmd: CommandDef) -> str:
245
+ """Build a CLI-facing description string including usage hint."""
246
+ if cmd.args_hint:
247
+ return f"{cmd.description} (usage: /{cmd.name} {cmd.args_hint})"
248
+ return cmd.description
249
+
250
+
251
+ # Backwards-compatible flat dict: "/command" -> description
252
+ COMMANDS: dict[str, str] = {}
253
+ for _cmd in COMMAND_REGISTRY:
254
+ if not _cmd.gateway_only:
255
+ COMMANDS[f"/{_cmd.name}"] = _build_description(_cmd)
256
+ for _alias in _cmd.aliases:
257
+ COMMANDS[f"/{_alias}"] = f"{_cmd.description} (alias for /{_cmd.name})"
258
+
259
+ # Backwards-compatible categorized dict
260
+ COMMANDS_BY_CATEGORY: dict[str, dict[str, str]] = {}
261
+ for _cmd in COMMAND_REGISTRY:
262
+ if not _cmd.gateway_only:
263
+ _cat = COMMANDS_BY_CATEGORY.setdefault(_cmd.category, {})
264
+ _cat[f"/{_cmd.name}"] = COMMANDS[f"/{_cmd.name}"]
265
+ for _alias in _cmd.aliases:
266
+ _cat[f"/{_alias}"] = COMMANDS[f"/{_alias}"]
267
+
268
+
269
+ # Subcommands lookup: "/cmd" -> ["sub1", "sub2", ...]
270
+ SUBCOMMANDS: dict[str, list[str]] = {}
271
+ for _cmd in COMMAND_REGISTRY:
272
+ if _cmd.subcommands:
273
+ SUBCOMMANDS[f"/{_cmd.name}"] = list(_cmd.subcommands)
274
+
275
+ # Also extract subcommands hinted in args_hint via pipe-separated patterns
276
+ # e.g. args_hint="[on|off|tts|status]" for commands that don't have explicit subcommands.
277
+ # NOTE: If a command already has explicit subcommands, this fallback is skipped.
278
+ # Use the `subcommands` field on CommandDef for intentional tab-completable args.
279
+ _PIPE_SUBS_RE = re.compile(r"[a-z]+(?:\|[a-z]+)+")
280
+ for _cmd in COMMAND_REGISTRY:
281
+ key = f"/{_cmd.name}"
282
+ if key in SUBCOMMANDS or not _cmd.args_hint:
283
+ continue
284
+ m = _PIPE_SUBS_RE.search(_cmd.args_hint)
285
+ if m:
286
+ SUBCOMMANDS[key] = m.group(0).split("|")
287
+
288
+
289
+ # ---------------------------------------------------------------------------
290
+ # Gateway helpers
291
+ # ---------------------------------------------------------------------------
292
+
293
+ # Set of all command names + aliases recognized by the gateway.
294
+ # Includes config-gated commands so the gateway can dispatch them
295
+ # (the handler checks the config gate at runtime).
296
+ GATEWAY_KNOWN_COMMANDS: frozenset[str] = frozenset(
297
+ name
298
+ for cmd in COMMAND_REGISTRY
299
+ if not cmd.cli_only or cmd.gateway_config_gate
300
+ for name in (cmd.name, *cmd.aliases)
301
+ )
302
+
303
+
304
+ def is_gateway_known_command(name: str | None) -> bool:
305
+ """Return True if ``name`` resolves to a gateway-dispatchable slash command.
306
+
307
+ This covers both built-in commands (``GATEWAY_KNOWN_COMMANDS`` derived
308
+ from ``COMMAND_REGISTRY``) and plugin-registered commands, which are
309
+ looked up lazily so importing this module never forces plugin
310
+ discovery. Gateway code uses this to decide whether to emit
311
+ ``command:<name>`` hooks — plugin commands get the same lifecycle
312
+ events as built-ins.
313
+ """
314
+ if not name:
315
+ return False
316
+ if name in GATEWAY_KNOWN_COMMANDS:
317
+ return True
318
+ for plugin_name, _description, _args_hint in _iter_plugin_command_entries():
319
+ if plugin_name == name:
320
+ return True
321
+ return False
322
+
323
+
324
+ # Commands with explicit Level-2 running-agent handlers in gateway/run.py.
325
+ # Listed here for introspection / tests; semantically a subset of
326
+ # "all resolvable commands" — which is the real bypass set (see
327
+ # should_bypass_active_session below).
328
+ ACTIVE_SESSION_BYPASS_COMMANDS: frozenset[str] = frozenset(
329
+ {
330
+ "agents",
331
+ "approve",
332
+ "background",
333
+ "commands",
334
+ "deny",
335
+ "help",
336
+ "new",
337
+ "profile",
338
+ "queue",
339
+ "restart",
340
+ "status",
341
+ "steer",
342
+ "stop",
343
+ "update",
344
+ }
345
+ )
346
+
347
+
348
+ def should_bypass_active_session(command_name: str | None) -> bool:
349
+ """Return True for any resolvable slash command.
350
+
351
+ Rationale: every gateway-registered slash command either has a
352
+ specific Level-2 handler in gateway/run.py (/stop, /new, /model,
353
+ /approve, etc.) or reaches the running-agent catch-all that returns
354
+ a "busy — wait or /stop first" response. In both paths the command
355
+ is dispatched, not queued.
356
+
357
+ Queueing is always wrong for a recognized slash command because the
358
+ safety net in gateway.run discards any command text that reaches
359
+ the pending queue — which meant a mid-run /model (or /reasoning,
360
+ /voice, /insights, /title, /resume, /retry, /undo, /compress,
361
+ /usage, /reload-mcp, /sethome, /reset) would silently
362
+ interrupt the agent AND get discarded, producing a zero-char
363
+ response. See issue #5057 / PRs #6252, #10370, #4665.
364
+
365
+ ACTIVE_SESSION_BYPASS_COMMANDS remains the subset of commands with
366
+ explicit Level-2 handlers; the rest fall through to the catch-all.
367
+ """
368
+ return resolve_command(command_name) is not None if command_name else False
369
+
370
+
371
+ def _resolve_config_gates() -> set[str]:
372
+ """Return canonical names of commands whose ``gateway_config_gate`` is truthy.
373
+
374
+ Reads ``config.yaml`` and walks the dot-separated key path for each
375
+ config-gated command. Returns an empty set on any error so callers
376
+ degrade gracefully.
377
+ """
378
+ gated = [c for c in COMMAND_REGISTRY if c.gateway_config_gate]
379
+ if not gated:
380
+ return set()
381
+ try:
382
+ from hermes_cli.config import read_raw_config
383
+ cfg = read_raw_config()
384
+ except Exception:
385
+ return set()
386
+ result: set[str] = set()
387
+ for cmd in gated:
388
+ val: Any = cfg
389
+ for key in cmd.gateway_config_gate.split("."):
390
+ if isinstance(val, dict):
391
+ val = val.get(key)
392
+ else:
393
+ val = None
394
+ break
395
+ if is_truthy_value(val, default=False):
396
+ result.add(cmd.name)
397
+ return result
398
+
399
+
400
+ def _is_gateway_available(cmd: CommandDef, config_overrides: set[str] | None = None) -> bool:
401
+ """Check if *cmd* should appear in gateway surfaces (help, menus, mappings).
402
+
403
+ Unconditionally available when ``cli_only`` is False. When ``cli_only``
404
+ is True but ``gateway_config_gate`` is set, the command is available only
405
+ when the config value is truthy. Pass *config_overrides* (from
406
+ ``_resolve_config_gates()``) to avoid re-reading config for every command.
407
+ """
408
+ if not cmd.cli_only:
409
+ return True
410
+ if cmd.gateway_config_gate:
411
+ overrides = config_overrides if config_overrides is not None else _resolve_config_gates()
412
+ return cmd.name in overrides
413
+ return False
414
+
415
+
416
+ def _requires_argument(args_hint: str) -> bool:
417
+ """Return True when selecting a command without text would be incomplete."""
418
+ return args_hint.strip().startswith("<")
419
+
420
+
421
+ def gateway_help_lines() -> list[str]:
422
+ """Generate gateway help text lines from the registry."""
423
+ overrides = _resolve_config_gates()
424
+ lines: list[str] = []
425
+ for cmd in COMMAND_REGISTRY:
426
+ if not _is_gateway_available(cmd, overrides):
427
+ continue
428
+ args = f" {cmd.args_hint}" if cmd.args_hint else ""
429
+ alias_parts: list[str] = []
430
+ for a in cmd.aliases:
431
+ # Skip internal aliases like reload_mcp (underscore variant)
432
+ if a.replace("-", "_") == cmd.name.replace("-", "_") and a != cmd.name:
433
+ continue
434
+ alias_parts.append(f"`/{a}`")
435
+ alias_note = f" (alias: {', '.join(alias_parts)})" if alias_parts else ""
436
+ lines.append(f"`/{cmd.name}{args}` -- {cmd.description}{alias_note}")
437
+ return lines
438
+
439
+
440
+ def _iter_plugin_command_entries() -> list[tuple[str, str, str]]:
441
+ """Yield (name, description, args_hint) tuples for all plugin slash commands.
442
+
443
+ Plugin commands are registered via
444
+ :func:`hermes_cli.plugins.PluginContext.register_command`. They behave
445
+ like ``CommandDef`` entries for gateway surfacing: they appear in the
446
+ Telegram command menu, in Slack's ``/hermes`` subcommand mapping, and
447
+ (via :func:`gateway.platforms.discord._register_slash_commands`) in
448
+ Discord's native slash command picker.
449
+
450
+ Lookup is lazy so importing this module never forces plugin discovery
451
+ (which can trigger filesystem scans and environment-dependent
452
+ behavior).
453
+ """
454
+ try:
455
+ from hermes_cli.plugins import get_plugin_commands
456
+ except Exception:
457
+ return []
458
+ try:
459
+ commands = get_plugin_commands() or {}
460
+ except Exception:
461
+ return []
462
+ entries: list[tuple[str, str, str]] = []
463
+ for name, meta in commands.items():
464
+ if not isinstance(name, str) or not isinstance(meta, dict):
465
+ continue
466
+ description = str(meta.get("description") or f"Run /{name}")
467
+ args_hint = str(meta.get("args_hint") or "").strip()
468
+ entries.append((name, description, args_hint))
469
+ return entries
470
+
471
+
472
+ def telegram_bot_commands() -> list[tuple[str, str]]:
473
+ """Return (command_name, description) pairs for Telegram setMyCommands.
474
+
475
+ Telegram command names cannot contain hyphens, so they are replaced with
476
+ underscores. Aliases are skipped -- Telegram shows one menu entry per
477
+ canonical command.
478
+
479
+ Built-in commands that require arguments (e.g. /queue, /steer, /background)
480
+ are **included** because their handlers return usage text when selected
481
+ without a payload, making them discoverable via autocomplete.
482
+
483
+ Plugin-registered slash commands that require arguments are **excluded**
484
+ because plugins may not provide a no-arg usage fallback.
485
+ """
486
+ overrides = _resolve_config_gates()
487
+ result: list[tuple[str, str]] = []
488
+ for cmd in COMMAND_REGISTRY:
489
+ if not _is_gateway_available(cmd, overrides):
490
+ continue
491
+ # Built-in arg-taking commands are included — their handlers show
492
+ # usage text when invoked without arguments, and hiding them from
493
+ # the menu hurts discoverability (issue #24312).
494
+ tg_name = _sanitize_telegram_name(cmd.name)
495
+ if tg_name:
496
+ result.append((tg_name, cmd.description))
497
+ for name, description, args_hint in _iter_plugin_command_entries():
498
+ if _requires_argument(args_hint):
499
+ continue
500
+ tg_name = _sanitize_telegram_name(name)
501
+ if tg_name:
502
+ result.append((tg_name, description))
503
+ return result
504
+
505
+
506
+ _CMD_NAME_LIMIT = 32
507
+ """Max command name length shared by Telegram and Discord."""
508
+
509
+ # Backward-compat alias — tests and external code may reference the old name.
510
+ _TG_NAME_LIMIT = _CMD_NAME_LIMIT
511
+
512
+ # Telegram Bot API allows only lowercase a-z, 0-9, and underscores in
513
+ # command names. This regex strips everything else after initial conversion.
514
+ _TG_INVALID_CHARS = re.compile(r"[^a-z0-9_]")
515
+ _TG_MULTI_UNDERSCORE = re.compile(r"_{2,}")
516
+
517
+
518
+ def _sanitize_telegram_name(raw: str) -> str:
519
+ """Convert a command/skill/plugin name to a valid Telegram command name.
520
+
521
+ Telegram requires: 1-32 chars, lowercase a-z, digits 0-9, underscores only.
522
+ Steps: lowercase → replace hyphens with underscores → strip all other
523
+ invalid characters → collapse consecutive underscores → strip leading/
524
+ trailing underscores.
525
+ """
526
+ name = raw.lower().replace("-", "_")
527
+ name = _TG_INVALID_CHARS.sub("", name)
528
+ name = _TG_MULTI_UNDERSCORE.sub("_", name)
529
+ return name.strip("_")
530
+
531
+
532
+ def _clamp_command_names(
533
+ entries: list[tuple[str, ...]],
534
+ reserved: set[str],
535
+ ) -> list[tuple[str, ...]]:
536
+ """Enforce 32-char command name limit with collision avoidance.
537
+
538
+ Both Telegram and Discord cap slash command names at 32 characters.
539
+ Names exceeding the limit are truncated. If truncation creates a duplicate
540
+ (against *reserved* names or earlier entries in the same batch), the name is
541
+ shortened to 31 chars and a digit ``0``-``9`` is appended to differentiate.
542
+ If all 10 digit slots are taken the entry is silently dropped.
543
+
544
+ Accepts tuples of any length >= 2. Extra elements beyond ``(name, desc)``
545
+ (e.g. ``cmd_key``) are passed through unchanged, so callers can attach
546
+ metadata that survives the rename.
547
+ """
548
+ used: set[str] = set(reserved)
549
+ result: list[tuple] = []
550
+ for entry in entries:
551
+ name, desc, *extra = entry
552
+ if len(name) > _CMD_NAME_LIMIT:
553
+ candidate = name[:_CMD_NAME_LIMIT]
554
+ if candidate in used:
555
+ prefix = name[:_CMD_NAME_LIMIT - 1]
556
+ for digit in range(10):
557
+ candidate = f"{prefix}{digit}"
558
+ if candidate not in used:
559
+ break
560
+ else:
561
+ # All 10 digit slots exhausted — skip entry
562
+ continue
563
+ name = candidate
564
+ if name in used:
565
+ continue
566
+ used.add(name)
567
+ result.append((name, desc, *extra))
568
+ return result
569
+
570
+
571
+ # Backward-compat alias.
572
+ _clamp_telegram_names = _clamp_command_names
573
+
574
+
575
+ # ---------------------------------------------------------------------------
576
+ # Shared skill/plugin collection for gateway platforms
577
+ # ---------------------------------------------------------------------------
578
+
579
+ def _collect_gateway_skill_entries(
580
+ platform: str,
581
+ max_slots: int,
582
+ reserved_names: set[str],
583
+ desc_limit: int = 100,
584
+ sanitize_name: "Callable[[str], str] | None" = None,
585
+ ) -> tuple[list[tuple[str, str, str]], int]:
586
+ """Collect plugin + skill entries for a gateway platform.
587
+
588
+ Priority order:
589
+ 1. Plugin slash commands (take precedence over skills)
590
+ 2. Built-in skill commands (fill remaining slots, alphabetical)
591
+
592
+ Only skills are trimmed when the cap is reached.
593
+ Hub-installed skills are excluded. Per-platform disabled skills are
594
+ excluded.
595
+
596
+ Args:
597
+ platform: Platform identifier for per-platform skill filtering
598
+ (``"telegram"``, ``"discord"``, etc.).
599
+ max_slots: Maximum number of entries to return (remaining slots after
600
+ built-in/core commands).
601
+ reserved_names: Names already taken by built-in commands. Mutated
602
+ in-place as new names are added.
603
+ desc_limit: Max description length (40 for Telegram, 100 for Discord).
604
+ sanitize_name: Optional name transform applied before clamping, e.g.
605
+ :func:`_sanitize_telegram_name` for Telegram. May return an
606
+ empty string to signal "skip this entry".
607
+
608
+ Returns:
609
+ ``(entries, hidden_count)`` where *entries* is a list of
610
+ ``(name, description, cmd_key)`` triples and *hidden_count* is the
611
+ number of skill entries dropped due to the cap. ``cmd_key`` is the
612
+ original ``/skill-name`` key from :func:`get_skill_commands`.
613
+ """
614
+ all_entries: list[tuple[str, str, str]] = []
615
+
616
+ # --- Tier 1: Plugin slash commands (never trimmed) ---------------------
617
+ plugin_pairs: list[tuple[str, str]] = []
618
+ try:
619
+ from hermes_cli.plugins import get_plugin_commands
620
+ plugin_cmds = get_plugin_commands()
621
+ for cmd_name in sorted(plugin_cmds):
622
+ name = sanitize_name(cmd_name) if sanitize_name else cmd_name
623
+ if not name:
624
+ continue
625
+ desc = plugin_cmds[cmd_name].get("description", "Plugin command")
626
+ if len(desc) > desc_limit:
627
+ desc = desc[:desc_limit - 3] + "..."
628
+ plugin_pairs.append((name, desc))
629
+ except Exception:
630
+ pass
631
+
632
+ plugin_pairs = _clamp_command_names(plugin_pairs, reserved_names)
633
+ reserved_names.update(n for n, _ in plugin_pairs)
634
+ # Plugins have no cmd_key — use empty string as placeholder
635
+ for n, d in plugin_pairs:
636
+ all_entries.append((n, d, ""))
637
+
638
+ # --- Tier 2: Built-in skill commands (trimmed at cap) -----------------
639
+ _platform_disabled: set[str] = set()
640
+ try:
641
+ from agent.skill_utils import get_disabled_skill_names
642
+ _platform_disabled = get_disabled_skill_names(platform=platform)
643
+ except Exception:
644
+ pass
645
+
646
+ skill_triples: list[tuple[str, str, str]] = []
647
+ try:
648
+ from agent.skill_commands import get_skill_commands
649
+ from tools.skills_tool import SKILLS_DIR
650
+ from agent.skill_utils import get_external_skills_dirs
651
+ _skills_dir = str(SKILLS_DIR.resolve())
652
+ _hub_dir = str((SKILLS_DIR / ".hub").resolve()).rstrip("/") + "/"
653
+ # Build set of allowed directory prefixes: local skills dir + any
654
+ # user-configured ``skills.external_dirs``. Ensure each prefix ends
655
+ # with ``/`` so ``/my-skills`` does not also match ``/my-skills-extra``.
656
+ # Without this widening, external skills are visible in
657
+ # ``hermes skills list`` and the agent's ``/skill-name`` dispatch but
658
+ # silently excluded from gateway slash menus (#8110).
659
+ _allowed_prefixes = [_skills_dir.rstrip("/") + "/"]
660
+ _allowed_prefixes.extend(
661
+ str(d).rstrip("/") + "/" for d in get_external_skills_dirs()
662
+ )
663
+ skill_cmds = get_skill_commands()
664
+ for cmd_key in sorted(skill_cmds):
665
+ info = skill_cmds[cmd_key]
666
+ skill_path = info.get("skill_md_path", "")
667
+ if not skill_path:
668
+ continue
669
+ if not any(skill_path.startswith(prefix) for prefix in _allowed_prefixes):
670
+ continue
671
+ if skill_path.startswith(_hub_dir):
672
+ continue
673
+ skill_name = info.get("name", "")
674
+ if skill_name in _platform_disabled:
675
+ continue
676
+ raw_name = cmd_key.lstrip("/")
677
+ name = sanitize_name(raw_name) if sanitize_name else raw_name
678
+ if not name:
679
+ continue
680
+ desc = info.get("description", "")
681
+ if len(desc) > desc_limit:
682
+ desc = desc[:desc_limit - 3] + "..."
683
+ skill_triples.append((name, desc, cmd_key))
684
+ except Exception:
685
+ pass
686
+
687
+ # Clamp names; cmd_key is passed through as extra payload so it survives
688
+ # any clamp-induced renames.
689
+ skill_triples = _clamp_command_names(skill_triples, reserved_names)
690
+
691
+ # Skills fill remaining slots — only tier that gets trimmed
692
+ remaining = max(0, max_slots - len(all_entries))
693
+ hidden_count = max(0, len(skill_triples) - remaining)
694
+ for n, d, k in skill_triples[:remaining]:
695
+ all_entries.append((n, d, k))
696
+
697
+ return all_entries[:max_slots], hidden_count
698
+
699
+
700
+ # ---------------------------------------------------------------------------
701
+ # Platform-specific wrappers
702
+ # ---------------------------------------------------------------------------
703
+
704
+ def telegram_menu_commands(max_commands: int = 100) -> tuple[list[tuple[str, str]], int]:
705
+ """Return Telegram menu commands capped to the Bot API limit.
706
+
707
+ Priority order (higher priority = never bumped by overflow):
708
+ 1. Core CommandDef commands (always included)
709
+ 2. Plugin slash commands (take precedence over skills)
710
+ 3. Built-in skill commands (fill remaining slots, alphabetical)
711
+
712
+ Skills are the only tier that gets trimmed when the cap is hit.
713
+ User-installed hub skills are excluded — accessible via /skills.
714
+ Skills disabled for the ``"telegram"`` platform (via ``hermes skills
715
+ config``) are excluded from the menu entirely.
716
+
717
+ Returns:
718
+ (menu_commands, hidden_count) where hidden_count is the number of
719
+ skill commands omitted due to the cap.
720
+ """
721
+ core_commands = list(telegram_bot_commands())
722
+ reserved_names = {n for n, _ in core_commands}
723
+ all_commands = list(core_commands)
724
+
725
+ remaining_slots = max(0, max_commands - len(all_commands))
726
+ entries, hidden_count = _collect_gateway_skill_entries(
727
+ platform="telegram",
728
+ max_slots=remaining_slots,
729
+ reserved_names=reserved_names,
730
+ desc_limit=40,
731
+ sanitize_name=_sanitize_telegram_name,
732
+ )
733
+ # Drop the cmd_key — Telegram only needs (name, desc) pairs.
734
+ all_commands.extend((n, d) for n, d, _k in entries)
735
+ return all_commands[:max_commands], hidden_count
736
+
737
+
738
+ def discord_skill_commands(
739
+ max_slots: int,
740
+ reserved_names: set[str],
741
+ ) -> tuple[list[tuple[str, str, str]], int]:
742
+ """Return skill entries for Discord slash command registration.
743
+
744
+ Same priority and filtering logic as :func:`telegram_menu_commands`
745
+ (plugins > skills, hub excluded, per-platform disabled excluded), but
746
+ adapted for Discord's constraints:
747
+
748
+ - Hyphens are allowed in names (no ``-`` → ``_`` sanitization)
749
+ - Descriptions capped at 100 chars (Discord's per-field max)
750
+
751
+ Args:
752
+ max_slots: Available command slots (100 minus existing built-in count).
753
+ reserved_names: Names of already-registered built-in commands.
754
+
755
+ Returns:
756
+ ``(entries, hidden_count)`` where *entries* is a list of
757
+ ``(discord_name, description, cmd_key)`` triples. ``cmd_key`` is
758
+ the original ``/skill-name`` key needed for the slash handler callback.
759
+ """
760
+ return _collect_gateway_skill_entries(
761
+ platform="discord",
762
+ max_slots=max_slots,
763
+ reserved_names=set(reserved_names), # copy — don't mutate caller's set
764
+ desc_limit=100,
765
+ )
766
+
767
+
768
+ def discord_skill_commands_by_category(
769
+ reserved_names: set[str],
770
+ ) -> tuple[dict[str, list[tuple[str, str, str]]], list[tuple[str, str, str]], int]:
771
+ """Return skill entries organized by category for Discord ``/skill`` autocomplete.
772
+
773
+ Skills whose directory is nested at least 2 levels under a scan root
774
+ (e.g. ``creative/ascii-art/SKILL.md``) are grouped by their top-level
775
+ category. Root-level skills (e.g. ``dogfood/SKILL.md``) are returned as
776
+ *uncategorized*.
777
+
778
+ Scan roots include the local ``SKILLS_DIR`` **and** any configured
779
+ ``skills.external_dirs`` — matching the widened filter applied to the
780
+ flat ``discord_skill_commands()`` collector in #18741. Without this
781
+ parity, external-dir skills are visible via ``hermes skills list`` and
782
+ the agent's ``/skill-name`` dispatch but silently absent from Discord's
783
+ ``/skill`` autocomplete.
784
+
785
+ Filtering mirrors :func:`discord_skill_commands`: hub skills excluded,
786
+ per-platform disabled excluded, names clamped to 32 chars, descriptions
787
+ clamped to 100 chars.
788
+
789
+ The legacy 25-group × 25-subcommand caps (from the old nested
790
+ ``/skill <cat> <name>`` layout) are **not** applied — the live caller
791
+ (``_register_skill_group`` in ``gateway/platforms/discord.py``, refactored
792
+ in PR #11580) flattens these results and feeds them into a single
793
+ autocomplete callback, which scales to thousands of entries without any
794
+ per-command payload concerns. ``hidden_count`` is retained in the return
795
+ tuple for backward compatibility and still reports skills dropped for
796
+ other reasons (32-char clamp collision vs a reserved name).
797
+
798
+ Returns:
799
+ ``(categories, uncategorized, hidden_count)``
800
+
801
+ - *categories*: ``{category_name: [(name, description, cmd_key), ...]}``
802
+ - *uncategorized*: ``[(name, description, cmd_key), ...]``
803
+ - *hidden_count*: skills dropped due to name clamp collisions
804
+ against already-registered command names.
805
+ """
806
+ from pathlib import Path as _P
807
+
808
+ _platform_disabled: set[str] = set()
809
+ try:
810
+ from agent.skill_utils import get_disabled_skill_names
811
+ _platform_disabled = get_disabled_skill_names(platform="discord")
812
+ except Exception:
813
+ pass
814
+
815
+ # Collect raw skill data --------------------------------------------------
816
+ categories: dict[str, list[tuple[str, str, str]]] = {}
817
+ uncategorized: list[tuple[str, str, str]] = []
818
+ # Map clamped-32-char-name → what it came from, so we can emit an
819
+ # actionable warning on collision. Reserved (gateway-builtin) command
820
+ # names are marked with a sentinel so the warning distinguishes
821
+ # "skill collided with a reserved command" from "two skills collided
822
+ # on the 32-char clamp" — the latter is the rename-worthy case.
823
+ _names_used: dict[str, str] = dict.fromkeys(reserved_names, "<reserved>")
824
+ hidden = 0
825
+
826
+ try:
827
+ from agent.skill_commands import get_skill_commands
828
+ from agent.skill_utils import get_external_skills_dirs
829
+ from tools.skills_tool import SKILLS_DIR
830
+
831
+ _skills_dir = SKILLS_DIR.resolve()
832
+ _hub_dir = (SKILLS_DIR / ".hub").resolve()
833
+ # Build list of (resolved_root, is_local) tuples. Each external dir
834
+ # becomes its own scan root for category derivation — a skill at
835
+ # ``<external>/mlops/foo/SKILL.md`` is still categorized as "mlops".
836
+ _scan_roots: list[_P] = [_skills_dir]
837
+ try:
838
+ for ext in get_external_skills_dirs():
839
+ try:
840
+ _scan_roots.append(_P(ext).resolve())
841
+ except Exception:
842
+ continue
843
+ except Exception:
844
+ pass
845
+ skill_cmds = get_skill_commands()
846
+
847
+ for cmd_key in sorted(skill_cmds):
848
+ info = skill_cmds[cmd_key]
849
+ skill_path = info.get("skill_md_path", "")
850
+ if not skill_path:
851
+ continue
852
+ sp = _P(skill_path).resolve()
853
+ # Hub skills are loaded via the skill hub, not surfaced as
854
+ # slash commands.
855
+ if str(sp).startswith(str(_hub_dir)):
856
+ continue
857
+ # Accept skill if it lives under any scan root; record the
858
+ # matching root so we can derive the category correctly.
859
+ matched_root: _P | None = None
860
+ for root in _scan_roots:
861
+ try:
862
+ sp.relative_to(root)
863
+ except ValueError:
864
+ continue
865
+ matched_root = root
866
+ break
867
+ if matched_root is None:
868
+ continue
869
+
870
+ skill_name = info.get("name", "")
871
+ if skill_name in _platform_disabled:
872
+ continue
873
+
874
+ raw_name = cmd_key.lstrip("/")
875
+ # Clamp to 32 chars (Discord per-command name limit)
876
+ discord_name = raw_name[:32]
877
+ if discord_name in _names_used:
878
+ # Two skills whose first 32 chars are identical. One wins
879
+ # (the first one seen, which is alphabetical because the
880
+ # caller iterates ``sorted(skill_cmds)``); the other is
881
+ # dropped from Discord's /skill autocomplete.
882
+ #
883
+ # Silently counting this as ``hidden`` (the old behavior)
884
+ # meant skill authors had no way to discover the drop —
885
+ # their skill just didn't appear in the picker. Emit a
886
+ # WARNING naming both sides so the author can rename the
887
+ # losing skill's frontmatter name to something with a
888
+ # distinct 32-char prefix.
889
+ prior = _names_used[discord_name]
890
+ if prior == "<reserved>":
891
+ logger.warning(
892
+ "Discord /skill: %r (from %r) collides on its 32-char "
893
+ "clamp with a reserved gateway command name %r — the "
894
+ "skill will not appear in the /skill autocomplete. "
895
+ "Rename the skill's frontmatter ``name:`` to differ "
896
+ "in its first 32 chars.",
897
+ discord_name, cmd_key, discord_name,
898
+ )
899
+ else:
900
+ logger.warning(
901
+ "Discord /skill: %r and %r both clamp to %r on "
902
+ "Discord's 32-char command-name limit — only %r "
903
+ "will appear in the /skill autocomplete. Rename "
904
+ "one skill's frontmatter ``name:`` to differ in "
905
+ "its first 32 chars.",
906
+ prior, cmd_key, discord_name, prior,
907
+ )
908
+ hidden += 1
909
+ continue
910
+ _names_used[discord_name] = cmd_key
911
+
912
+ desc = info.get("description", "")
913
+ if len(desc) > 100:
914
+ desc = desc[:97] + "..."
915
+
916
+ # Determine category from the relative path within the matched
917
+ # scan root. e.g. creative/ascii-art/SKILL.md → ("creative", ...)
918
+ rel = sp.parent.relative_to(matched_root)
919
+ parts = rel.parts
920
+ if len(parts) >= 2:
921
+ cat = parts[0]
922
+ categories.setdefault(cat, []).append((discord_name, desc, cmd_key))
923
+ else:
924
+ uncategorized.append((discord_name, desc, cmd_key))
925
+ except Exception:
926
+ pass
927
+
928
+ return categories, uncategorized, hidden
929
+
930
+
931
+ # ---------------------------------------------------------------------------
932
+ # Slack native slash commands
933
+ # ---------------------------------------------------------------------------
934
+
935
+ # Slack slash command name constraints: lowercase a-z, 0-9, hyphens,
936
+ # underscores. Max 32 chars. Slack app manifest accepts up to 50 slash
937
+ # commands per app.
938
+ _SLACK_MAX_SLASH_COMMANDS = 50
939
+ _SLACK_NAME_LIMIT = 32
940
+ _SLACK_INVALID_CHARS = re.compile(r"[^a-z0-9_\-]")
941
+ _SLACK_RESERVED_COMMANDS = frozenset({
942
+ # Built-in Slack slash commands that cannot be registered by apps.
943
+ # https://slack.com/help/articles/201259356-Use-built-in-slash-commands
944
+ "me", "status", "away", "dnd", "shrug", "remind", "msg", "feed",
945
+ "who", "collapse", "expand", "leave", "join", "open", "search",
946
+ "topic", "mute", "pro", "shortcuts",
947
+ })
948
+
949
+
950
+ def _sanitize_slack_name(raw: str) -> str:
951
+ """Convert a command name to a valid Slack slash command name.
952
+
953
+ Slack allows lowercase a-z, digits, hyphens, and underscores. Max 32
954
+ chars. Uppercase is lowercased; invalid chars are stripped.
955
+ """
956
+ name = raw.lower()
957
+ name = _SLACK_INVALID_CHARS.sub("", name)
958
+ name = name.strip("-_")
959
+ return name[:_SLACK_NAME_LIMIT]
960
+
961
+
962
+ def slack_native_slashes() -> list[tuple[str, str, str]]:
963
+ """Return (slash_name, description, usage_hint) triples for Slack.
964
+
965
+ Every gateway-available command in ``COMMAND_REGISTRY`` is surfaced as
966
+ a standalone Slack slash command (e.g. ``/btw``, ``/stop``, ``/model``),
967
+ matching Discord's and Telegram's model where every command is a
968
+ first-class slash and not a ``/hermes <verb>`` subcommand.
969
+
970
+ Both canonical names and aliases are included so users can type any
971
+ documented form (e.g. ``/background``, ``/bg``, and ``/btw`` all work).
972
+ Plugin-registered slash commands are included too.
973
+
974
+ Commands whose sanitized name collides with a Slack built-in
975
+ (e.g. ``/status``, ``/me``, ``/join``) are silently skipped. Users
976
+ can still reach them via ``/hermes <command>``.
977
+
978
+ Results are clamped to Slack's 50-command limit with duplicate-name
979
+ avoidance. ``/hermes`` is always reserved as the first entry so the
980
+ legacy ``/hermes <subcommand>`` form keeps working for anything that
981
+ gets dropped by the clamp or for free-form questions.
982
+ """
983
+ overrides = _resolve_config_gates()
984
+ entries: list[tuple[str, str, str]] = []
985
+ seen: set[str] = set()
986
+
987
+ # Reserve /hermes as the catch-all top-level command.
988
+ entries.append(("hermes", "Talk to Hermes or run a subcommand", "[subcommand] [args]"))
989
+ seen.add("hermes")
990
+
991
+ def _add(name: str, desc: str, hint: str) -> None:
992
+ slack_name = _sanitize_slack_name(name)
993
+ if not slack_name or slack_name in seen:
994
+ return
995
+ if slack_name in _SLACK_RESERVED_COMMANDS:
996
+ return
997
+ if len(entries) >= _SLACK_MAX_SLASH_COMMANDS:
998
+ return
999
+ # Slack description cap is 2000 chars; keep it short.
1000
+ entries.append((slack_name, desc[:140], hint[:100]))
1001
+ seen.add(slack_name)
1002
+
1003
+ # First pass: canonical names (so they win slots if we hit the cap).
1004
+ for cmd in COMMAND_REGISTRY:
1005
+ if not _is_gateway_available(cmd, overrides):
1006
+ continue
1007
+ _add(cmd.name, cmd.description, cmd.args_hint or "")
1008
+
1009
+ # Second pass: aliases.
1010
+ for cmd in COMMAND_REGISTRY:
1011
+ if not _is_gateway_available(cmd, overrides):
1012
+ continue
1013
+ for alias in cmd.aliases:
1014
+ # Skip aliases that only differ from canonical by case/punctuation
1015
+ # normalization (already covered by _add dedup).
1016
+ _add(alias, f"Alias for /{cmd.name} — {cmd.description}", cmd.args_hint or "")
1017
+
1018
+ # Third pass: plugin commands.
1019
+ for name, description, args_hint in _iter_plugin_command_entries():
1020
+ _add(name, description, args_hint or "")
1021
+
1022
+ return entries
1023
+
1024
+
1025
+ def slack_app_manifest(request_url: str = "https://hermes-agent.local/slack/commands") -> dict[str, Any]:
1026
+ """Generate a Slack app manifest with all gateway commands as slashes.
1027
+
1028
+ ``request_url`` is required by Slack's manifest schema for every slash
1029
+ command, but in Socket Mode (which we use) Slack ignores it and routes
1030
+ the command event through the WebSocket. A placeholder URL is fine.
1031
+
1032
+ The returned dict is the ``features.slash_commands`` portion only —
1033
+ callers compose it into a full manifest (or merge into an existing
1034
+ one). Keeping it narrow avoids coupling us to the rest of the manifest
1035
+ schema (display_information, oauth_config, settings, etc.) which users
1036
+ set up once in the Slack UI and rarely change.
1037
+ """
1038
+ slashes = []
1039
+ for name, desc, usage in slack_native_slashes():
1040
+ entry = {
1041
+ "command": f"/{name}",
1042
+ "description": desc or f"Run /{name}",
1043
+ "should_escape": False,
1044
+ "url": request_url,
1045
+ }
1046
+ if usage:
1047
+ entry["usage_hint"] = usage
1048
+ slashes.append(entry)
1049
+ return {"features": {"slash_commands": slashes}}
1050
+
1051
+
1052
+ def slack_subcommand_map() -> dict[str, str]:
1053
+ """Return subcommand -> /command mapping for Slack /hermes handler.
1054
+
1055
+ Maps both canonical names and aliases so /hermes bg do stuff works
1056
+ the same as /hermes background do stuff.
1057
+
1058
+ Plugin-registered slash commands are included so ``/hermes <plugin-cmd>``
1059
+ routes through the plugin handler.
1060
+ """
1061
+ overrides = _resolve_config_gates()
1062
+ mapping: dict[str, str] = {}
1063
+ for cmd in COMMAND_REGISTRY:
1064
+ if not _is_gateway_available(cmd, overrides):
1065
+ continue
1066
+ mapping[cmd.name] = f"/{cmd.name}"
1067
+ for alias in cmd.aliases:
1068
+ mapping[alias] = f"/{alias}"
1069
+ for name, _description, _args_hint in _iter_plugin_command_entries():
1070
+ if name not in mapping:
1071
+ mapping[name] = f"/{name}"
1072
+ return mapping
1073
+
1074
+
1075
+ # ---------------------------------------------------------------------------
1076
+ # Autocomplete
1077
+ # ---------------------------------------------------------------------------
1078
+
1079
+
1080
+ # Per-process cache for /model<space> LM Studio autocomplete. Probing on
1081
+ # every keystroke would block the UI; a short TTL keeps it live without
1082
+ # hammering the server.
1083
+ _LMSTUDIO_COMPLETION_CACHE: tuple[float, list[str]] | None = None
1084
+
1085
+
1086
+ def _lmstudio_completion_models() -> list[str]:
1087
+ """Locally-loaded LM Studio models for /model autocomplete (cached, gated)."""
1088
+ global _LMSTUDIO_COMPLETION_CACHE
1089
+ # Gate: don't probe 127.0.0.1 on every keystroke for users who don't use LM Studio.
1090
+ if not (os.environ.get("LM_API_KEY") or os.environ.get("LM_BASE_URL")):
1091
+ try:
1092
+ from hermes_cli.auth import _load_auth_store
1093
+ store = _load_auth_store() or {}
1094
+ if "lmstudio" not in (store.get("providers") or {}) \
1095
+ and "lmstudio" not in (store.get("credential_pool") or {}):
1096
+ return []
1097
+ except Exception:
1098
+ return []
1099
+ now = time.time()
1100
+ if _LMSTUDIO_COMPLETION_CACHE and (now - _LMSTUDIO_COMPLETION_CACHE[0]) < 30.0:
1101
+ return _LMSTUDIO_COMPLETION_CACHE[1]
1102
+ try:
1103
+ from hermes_cli.models import fetch_lmstudio_models
1104
+ models = fetch_lmstudio_models(
1105
+ api_key=os.environ.get("LM_API_KEY", ""),
1106
+ base_url=os.environ.get("LM_BASE_URL") or "http://127.0.0.1:1234/v1",
1107
+ timeout=0.8,
1108
+ )
1109
+ except Exception:
1110
+ models = []
1111
+ _LMSTUDIO_COMPLETION_CACHE = (now, models)
1112
+ return models
1113
+
1114
+
1115
+ class SlashCommandCompleter(Completer):
1116
+ """Autocomplete for built-in slash commands, subcommands, and skill commands."""
1117
+
1118
+ def __init__(
1119
+ self,
1120
+ skill_commands_provider: Callable[[], Mapping[str, dict[str, Any]]] | None = None,
1121
+ command_filter: Callable[[str], bool] | None = None,
1122
+ ) -> None:
1123
+ self._skill_commands_provider = skill_commands_provider
1124
+ self._command_filter = command_filter
1125
+ # Cached project file list for fuzzy @ completions
1126
+ self._file_cache: list[str] = []
1127
+ self._file_cache_time: float = 0.0
1128
+ self._file_cache_cwd: str = ""
1129
+
1130
+ def _command_allowed(self, slash_command: str) -> bool:
1131
+ if self._command_filter is None:
1132
+ return True
1133
+ try:
1134
+ return bool(self._command_filter(slash_command))
1135
+ except Exception:
1136
+ return True
1137
+
1138
+ def _iter_skill_commands(self) -> Mapping[str, dict[str, Any]]:
1139
+ if self._skill_commands_provider is None:
1140
+ return {}
1141
+ try:
1142
+ return self._skill_commands_provider() or {}
1143
+ except Exception:
1144
+ return {}
1145
+
1146
+ # Commands that open pickers when run without arguments.
1147
+ # These should NOT receive a trailing space in completions because:
1148
+ # - The TUI's submit handler applies completions on Enter if input differs
1149
+ # - Adding space makes "/model" → "/model " which blocks picker execution
1150
+ _PICKER_COMMANDS = frozenset({"model", "skin", "personality"})
1151
+
1152
+ @staticmethod
1153
+ def _completion_text(cmd_name: str, word: str) -> str:
1154
+ """Return replacement text for a completion.
1155
+
1156
+ When the user has already typed the full command exactly (``/help``),
1157
+ returning ``help`` would be a no-op and prompt_toolkit suppresses the
1158
+ menu. Appending a trailing space keeps the dropdown visible and makes
1159
+ backspacing retrigger it naturally.
1160
+
1161
+ However, commands that open pickers (model, skin, personality) should
1162
+ NOT get a trailing space — the TUI would apply the completion on Enter
1163
+ and block the picker from opening.
1164
+ """
1165
+ if cmd_name != word:
1166
+ return cmd_name
1167
+ # Don't add space for picker commands — allows Enter to execute them
1168
+ if cmd_name in SlashCommandCompleter._PICKER_COMMANDS:
1169
+ return cmd_name
1170
+ return f"{cmd_name} "
1171
+
1172
+ @staticmethod
1173
+ def _extract_path_word(text: str) -> str | None:
1174
+ """Extract the current word if it looks like a file path.
1175
+
1176
+ Returns the path-like token under the cursor, or None if the
1177
+ current word doesn't look like a path. A word is path-like when
1178
+ it starts with ``./``, ``../``, ``~/``, ``/``, or contains a
1179
+ ``/`` separator (e.g. ``src/main.py``).
1180
+ """
1181
+ if not text:
1182
+ return None
1183
+ # Walk backwards to find the start of the current "word".
1184
+ # Words are delimited by spaces, but paths can contain almost anything.
1185
+ i = len(text) - 1
1186
+ while i >= 0 and text[i] != " ":
1187
+ i -= 1
1188
+ word = text[i + 1:]
1189
+ if not word:
1190
+ return None
1191
+ # Only trigger path completion for path-like tokens
1192
+ if word.startswith(("./", "../", "~/", "/")) or "/" in word:
1193
+ return word
1194
+ return None
1195
+
1196
+ @staticmethod
1197
+ def _path_completions(word: str, limit: int = 30):
1198
+ """Yield Completion objects for file paths matching *word*."""
1199
+ expanded = os.path.expanduser(word)
1200
+ # Split into directory part and prefix to match inside it
1201
+ if expanded.endswith("/"):
1202
+ search_dir = expanded
1203
+ prefix = ""
1204
+ else:
1205
+ search_dir = os.path.dirname(expanded) or "."
1206
+ prefix = os.path.basename(expanded)
1207
+
1208
+ try:
1209
+ entries = os.listdir(search_dir)
1210
+ except OSError:
1211
+ return
1212
+
1213
+ count = 0
1214
+ prefix_lower = prefix.lower()
1215
+ for entry in sorted(entries):
1216
+ if prefix and not entry.lower().startswith(prefix_lower):
1217
+ continue
1218
+ if count >= limit:
1219
+ break
1220
+
1221
+ full_path = os.path.join(search_dir, entry)
1222
+ is_dir = os.path.isdir(full_path)
1223
+
1224
+ # Build the completion text (what replaces the typed word)
1225
+ if word.startswith("~"):
1226
+ display_path = "~/" + os.path.relpath(full_path, os.path.expanduser("~"))
1227
+ elif os.path.isabs(word):
1228
+ display_path = full_path
1229
+ else:
1230
+ # Keep relative
1231
+ display_path = os.path.relpath(full_path)
1232
+
1233
+ if is_dir:
1234
+ display_path += "/"
1235
+
1236
+ suffix = "/" if is_dir else ""
1237
+ meta = "dir" if is_dir else _file_size_label(full_path)
1238
+
1239
+ yield Completion(
1240
+ display_path,
1241
+ start_position=-len(word),
1242
+ display=entry + suffix,
1243
+ display_meta=meta,
1244
+ )
1245
+ count += 1
1246
+
1247
+ @staticmethod
1248
+ def _extract_context_word(text: str) -> str | None:
1249
+ """Extract a bare ``@`` token for context reference completions."""
1250
+ if not text:
1251
+ return None
1252
+ # Walk backwards to find the start of the current word
1253
+ i = len(text) - 1
1254
+ while i >= 0 and text[i] != " ":
1255
+ i -= 1
1256
+ word = text[i + 1:]
1257
+ if not word.startswith("@"):
1258
+ return None
1259
+ return word
1260
+
1261
+ def _context_completions(self, word: str, limit: int = 30):
1262
+ """Yield Claude Code-style @ context completions.
1263
+
1264
+ Bare ``@`` or ``@partial`` shows static references and matching
1265
+ files/folders. ``@file:path`` and ``@folder:path`` are handled
1266
+ by the existing path completion path.
1267
+ """
1268
+ lowered = word.lower()
1269
+
1270
+ # Static context references
1271
+ _STATIC_REFS = (
1272
+ ("@diff", "Git working tree diff"),
1273
+ ("@staged", "Git staged diff"),
1274
+ ("@file:", "Attach a file"),
1275
+ ("@folder:", "Attach a folder"),
1276
+ ("@git:", "Git log with diffs (e.g. @git:5)"),
1277
+ ("@url:", "Fetch web content"),
1278
+ )
1279
+ for candidate, meta in _STATIC_REFS:
1280
+ if candidate.lower().startswith(lowered) and candidate.lower() != lowered:
1281
+ yield Completion(
1282
+ candidate,
1283
+ start_position=-len(word),
1284
+ display=candidate,
1285
+ display_meta=meta,
1286
+ )
1287
+
1288
+ # If the user typed @file: / @folder: (or just @file / @folder with
1289
+ # no colon yet), delegate to path completions. Accepting the bare
1290
+ # form lets the picker surface directories as soon as the user has
1291
+ # typed `@folder`, without requiring them to first accept the static
1292
+ # `@folder:` hint and re-trigger completion.
1293
+ for prefix in ("@file:", "@folder:"):
1294
+ bare = prefix[:-1]
1295
+
1296
+ if word == bare or word.startswith(prefix):
1297
+ want_dir = prefix == "@folder:"
1298
+ path_part = '' if word == bare else word[len(prefix):]
1299
+ expanded = os.path.expanduser(path_part)
1300
+
1301
+ if not expanded or expanded == ".":
1302
+ search_dir, match_prefix = ".", ""
1303
+ elif expanded.endswith("/"):
1304
+ search_dir, match_prefix = expanded, ""
1305
+ else:
1306
+ search_dir = os.path.dirname(expanded) or "."
1307
+ match_prefix = os.path.basename(expanded)
1308
+
1309
+ try:
1310
+ entries = os.listdir(search_dir)
1311
+ except OSError:
1312
+ return
1313
+
1314
+ count = 0
1315
+ prefix_lower = match_prefix.lower()
1316
+ for entry in sorted(entries):
1317
+ if match_prefix and not entry.lower().startswith(prefix_lower):
1318
+ continue
1319
+ full_path = os.path.join(search_dir, entry)
1320
+ is_dir = os.path.isdir(full_path)
1321
+ # `@folder:` must only surface directories; `@file:` only
1322
+ # regular files. Without this filter `@folder:` listed
1323
+ # every .env / .gitignore in the cwd, defeating the
1324
+ # explicit prefix and confusing users expecting a
1325
+ # directory picker.
1326
+ if want_dir != is_dir:
1327
+ continue
1328
+ if count >= limit:
1329
+ break
1330
+ display_path = os.path.relpath(full_path)
1331
+ suffix = "/" if is_dir else ""
1332
+ meta = "dir" if is_dir else _file_size_label(full_path)
1333
+ completion = f"{prefix}{display_path}{suffix}"
1334
+ yield Completion(
1335
+ completion,
1336
+ start_position=-len(word),
1337
+ display=entry + suffix,
1338
+ display_meta=meta,
1339
+ )
1340
+ count += 1
1341
+ return
1342
+
1343
+ # Bare @ or @partial — fuzzy project-wide file search
1344
+ query = word[1:] # strip the @
1345
+ yield from self._fuzzy_file_completions(word, query, limit)
1346
+
1347
+ def _get_project_files(self) -> list[str]:
1348
+ """Return cached list of project files (refreshed every 5s)."""
1349
+ cwd = os.getcwd()
1350
+ now = time.monotonic()
1351
+ if (
1352
+ self._file_cache
1353
+ and self._file_cache_cwd == cwd
1354
+ and now - self._file_cache_time < 5.0
1355
+ ):
1356
+ return self._file_cache
1357
+
1358
+ files: list[str] = []
1359
+ # Try rg first (fast, respects .gitignore), then fd, then find.
1360
+ for cmd in [
1361
+ ["rg", "--files", "--sortr=modified", cwd],
1362
+ ["rg", "--files", cwd],
1363
+ ["fd", "--type", "f", "--base-directory", cwd],
1364
+ ]:
1365
+ tool = cmd[0]
1366
+ if not shutil.which(tool):
1367
+ continue
1368
+ try:
1369
+ proc = subprocess.run(
1370
+ cmd, capture_output=True, text=True, timeout=2,
1371
+ cwd=cwd, encoding="utf-8", errors="replace",
1372
+ )
1373
+ if proc.returncode == 0 and proc.stdout and proc.stdout.strip():
1374
+ raw = proc.stdout.strip().split("\n")
1375
+ # Store relative paths
1376
+ for p in raw[:5000]:
1377
+ rel = os.path.relpath(p, cwd) if os.path.isabs(p) else p
1378
+ files.append(rel)
1379
+ break
1380
+ except (subprocess.TimeoutExpired, OSError):
1381
+ continue
1382
+
1383
+ self._file_cache = files
1384
+ self._file_cache_time = now
1385
+ self._file_cache_cwd = cwd
1386
+ return files
1387
+
1388
+ @staticmethod
1389
+ def _score_path(filepath: str, query: str) -> int:
1390
+ """Score a file path against a fuzzy query. Higher = better match."""
1391
+ if not query:
1392
+ return 1 # show everything when query is empty
1393
+
1394
+ filename = os.path.basename(filepath)
1395
+ lower_file = filename.lower()
1396
+ lower_path = filepath.lower()
1397
+ lower_q = query.lower()
1398
+
1399
+ # Exact filename match
1400
+ if lower_file == lower_q:
1401
+ return 100
1402
+ # Filename starts with query
1403
+ if lower_file.startswith(lower_q):
1404
+ return 80
1405
+ # Filename contains query as substring
1406
+ if lower_q in lower_file:
1407
+ return 60
1408
+ # Full path contains query
1409
+ if lower_q in lower_path:
1410
+ return 40
1411
+ # Initials / abbreviation match: e.g. "fo" matches "file_operations"
1412
+ # Check if query chars appear in order in filename
1413
+ qi = 0
1414
+ for c in lower_file:
1415
+ if qi < len(lower_q) and c == lower_q[qi]:
1416
+ qi += 1
1417
+ if qi == len(lower_q):
1418
+ # Bonus if matches land on word boundaries (after _, -, /, .)
1419
+ boundary_hits = 0
1420
+ qi = 0
1421
+ prev = "_" # treat start as boundary
1422
+ for c in lower_file:
1423
+ if qi < len(lower_q) and c == lower_q[qi]:
1424
+ if prev in "_-./":
1425
+ boundary_hits += 1
1426
+ qi += 1
1427
+ prev = c
1428
+ if boundary_hits >= len(lower_q) * 0.5:
1429
+ return 35
1430
+ return 25
1431
+ return 0
1432
+
1433
+ def _fuzzy_file_completions(self, word: str, query: str, limit: int = 20):
1434
+ """Yield fuzzy file completions for bare @query."""
1435
+ files = self._get_project_files()
1436
+
1437
+ if not query:
1438
+ # No query — show recently modified files (already sorted by mtime)
1439
+ for fp in files[:limit]:
1440
+ is_dir = fp.endswith("/")
1441
+ filename = os.path.basename(fp)
1442
+ kind = "folder" if is_dir else "file"
1443
+ meta = "dir" if is_dir else _file_size_label(
1444
+ os.path.join(os.getcwd(), fp)
1445
+ )
1446
+ yield Completion(
1447
+ f"@{kind}:{fp}",
1448
+ start_position=-len(word),
1449
+ display=filename,
1450
+ display_meta=meta,
1451
+ )
1452
+ return
1453
+
1454
+ # Score and rank
1455
+ scored = []
1456
+ for fp in files:
1457
+ s = self._score_path(fp, query)
1458
+ if s > 0:
1459
+ scored.append((s, fp))
1460
+ scored.sort(key=lambda x: (-x[0], x[1]))
1461
+
1462
+ for _, fp in scored[:limit]:
1463
+ is_dir = fp.endswith("/")
1464
+ filename = os.path.basename(fp)
1465
+ kind = "folder" if is_dir else "file"
1466
+ meta = "dir" if is_dir else _file_size_label(
1467
+ os.path.join(os.getcwd(), fp)
1468
+ )
1469
+ yield Completion(
1470
+ f"@{kind}:{fp}",
1471
+ start_position=-len(word),
1472
+ display=filename,
1473
+ display_meta=f"{fp} {meta}" if meta else fp,
1474
+ )
1475
+
1476
+ @staticmethod
1477
+ def _skin_completions(sub_text: str, sub_lower: str):
1478
+ """Yield completions for /skin from available skins."""
1479
+ try:
1480
+ from hermes_cli.skin_engine import list_skins
1481
+ for s in list_skins():
1482
+ name = s["name"]
1483
+ if name.startswith(sub_lower) and name != sub_lower:
1484
+ yield Completion(
1485
+ name,
1486
+ start_position=-len(sub_text),
1487
+ display=name,
1488
+ display_meta=s.get("description", "") or s.get("source", ""),
1489
+ )
1490
+ except Exception:
1491
+ pass
1492
+
1493
+ @staticmethod
1494
+ def _personality_completions(sub_text: str, sub_lower: str):
1495
+ """Yield completions for /personality from configured personalities."""
1496
+ try:
1497
+ from hermes_cli.config import load_config
1498
+ personalities = load_config().get("agent", {}).get("personalities", {})
1499
+ if "none".startswith(sub_lower) and "none" != sub_lower:
1500
+ yield Completion(
1501
+ "none",
1502
+ start_position=-len(sub_text),
1503
+ display="none",
1504
+ display_meta="clear personality overlay",
1505
+ )
1506
+ for name, prompt in personalities.items():
1507
+ if name.startswith(sub_lower) and name != sub_lower:
1508
+ if isinstance(prompt, dict):
1509
+ meta = prompt.get("description") or prompt.get("system_prompt", "")[:50]
1510
+ else:
1511
+ meta = str(prompt)[:50]
1512
+ yield Completion(
1513
+ name,
1514
+ start_position=-len(sub_text),
1515
+ display=name,
1516
+ display_meta=meta,
1517
+ )
1518
+ except Exception:
1519
+ pass
1520
+
1521
+ def _model_completions(self, sub_text: str, sub_lower: str):
1522
+ """Yield completions for /model from config aliases + built-in aliases."""
1523
+ seen = set()
1524
+ # Config-based direct aliases (preferred — include provider info)
1525
+ try:
1526
+ from hermes_cli.model_switch import (
1527
+ _ensure_direct_aliases, DIRECT_ALIASES, MODEL_ALIASES,
1528
+ )
1529
+ _ensure_direct_aliases()
1530
+ for name, da in DIRECT_ALIASES.items():
1531
+ if name.startswith(sub_lower) and name != sub_lower:
1532
+ seen.add(name)
1533
+ yield Completion(
1534
+ name,
1535
+ start_position=-len(sub_text),
1536
+ display=name,
1537
+ display_meta=f"{da.model} ({da.provider})",
1538
+ )
1539
+ # Built-in catalog aliases not already covered
1540
+ for name in sorted(MODEL_ALIASES.keys()):
1541
+ if name in seen:
1542
+ continue
1543
+ if name.startswith(sub_lower) and name != sub_lower:
1544
+ identity = MODEL_ALIASES[name]
1545
+ yield Completion(
1546
+ name,
1547
+ start_position=-len(sub_text),
1548
+ display=name,
1549
+ display_meta=f"{identity.vendor}/{identity.family}",
1550
+ )
1551
+ except Exception:
1552
+ pass
1553
+ # LM Studio: surface locally-loaded models. Gated on the user actually
1554
+ # having LM Studio configured (env var or auth-store entry) so we
1555
+ # don't probe 127.0.0.1 on every keystroke for users who don't use it.
1556
+ for name in _lmstudio_completion_models():
1557
+ if name in seen:
1558
+ continue
1559
+ if name.startswith(sub_lower) and name != sub_lower:
1560
+ yield Completion(
1561
+ name,
1562
+ start_position=-len(sub_text),
1563
+ display=name,
1564
+ display_meta="LM Studio",
1565
+ )
1566
+
1567
+ def get_completions(self, document, complete_event):
1568
+ text = document.text_before_cursor
1569
+ if not text.startswith("/"):
1570
+ # Try @ context completion (Claude Code-style)
1571
+ ctx_word = self._extract_context_word(text)
1572
+ if ctx_word is not None:
1573
+ yield from self._context_completions(ctx_word)
1574
+ return
1575
+ # Try file path completion for non-slash input
1576
+ path_word = self._extract_path_word(text)
1577
+ if path_word is not None:
1578
+ yield from self._path_completions(path_word)
1579
+ return
1580
+
1581
+ # Check if we're completing a subcommand (base command already typed)
1582
+ parts = text.split(maxsplit=1)
1583
+ base_cmd = parts[0].lower()
1584
+ if len(parts) > 1 or (len(parts) == 1 and text.endswith(" ")):
1585
+ sub_text = parts[1] if len(parts) > 1 else ""
1586
+ sub_lower = sub_text.lower()
1587
+
1588
+ # Dynamic completions for commands with runtime lists
1589
+ if " " not in sub_text:
1590
+ if base_cmd == "/model":
1591
+ yield from self._model_completions(sub_text, sub_lower)
1592
+ return
1593
+ if base_cmd == "/skin":
1594
+ yield from self._skin_completions(sub_text, sub_lower)
1595
+ return
1596
+ if base_cmd == "/personality":
1597
+ yield from self._personality_completions(sub_text, sub_lower)
1598
+ return
1599
+
1600
+ # Static subcommand completions
1601
+ if " " not in sub_text and base_cmd in SUBCOMMANDS and self._command_allowed(base_cmd):
1602
+ for sub in SUBCOMMANDS[base_cmd]:
1603
+ if sub.startswith(sub_lower) and sub != sub_lower:
1604
+ yield Completion(
1605
+ sub,
1606
+ start_position=-len(sub_text),
1607
+ display=sub,
1608
+ )
1609
+ return
1610
+
1611
+ word = text[1:]
1612
+
1613
+ for cmd, desc in COMMANDS.items():
1614
+ if not self._command_allowed(cmd):
1615
+ continue
1616
+ cmd_name = cmd[1:]
1617
+ if cmd_name.startswith(word):
1618
+ yield Completion(
1619
+ self._completion_text(cmd_name, word),
1620
+ start_position=-len(word),
1621
+ display=cmd,
1622
+ display_meta=desc,
1623
+ )
1624
+
1625
+ for cmd, info in self._iter_skill_commands().items():
1626
+ cmd_name = cmd[1:]
1627
+ if cmd_name.startswith(word):
1628
+ description = str(info.get("description", "Skill command"))
1629
+ short_desc = description[:50] + ("..." if len(description) > 50 else "")
1630
+ yield Completion(
1631
+ self._completion_text(cmd_name, word),
1632
+ start_position=-len(word),
1633
+ display=cmd,
1634
+ display_meta=f"⚡ {short_desc}",
1635
+ )
1636
+
1637
+ # Plugin-registered slash commands
1638
+ try:
1639
+ from hermes_cli.plugins import get_plugin_commands
1640
+ for cmd_name, cmd_info in get_plugin_commands().items():
1641
+ if cmd_name.startswith(word):
1642
+ desc = str(cmd_info.get("description", "Plugin command"))
1643
+ short_desc = desc[:50] + ("..." if len(desc) > 50 else "")
1644
+ yield Completion(
1645
+ self._completion_text(cmd_name, word),
1646
+ start_position=-len(word),
1647
+ display=f"/{cmd_name}",
1648
+ display_meta=f"🔌 {short_desc}",
1649
+ )
1650
+ except Exception:
1651
+ pass
1652
+
1653
+
1654
+ # ---------------------------------------------------------------------------
1655
+ # Inline auto-suggest (ghost text) for slash commands
1656
+ # ---------------------------------------------------------------------------
1657
+
1658
+ class SlashCommandAutoSuggest(AutoSuggest):
1659
+ """Inline ghost-text suggestions for slash commands and their subcommands.
1660
+
1661
+ Shows the rest of a command or subcommand in dim text as you type.
1662
+ Falls back to history-based suggestions for non-slash input.
1663
+ """
1664
+
1665
+ def __init__(
1666
+ self,
1667
+ history_suggest: AutoSuggest | None = None,
1668
+ completer: SlashCommandCompleter | None = None,
1669
+ ) -> None:
1670
+ self._history = history_suggest
1671
+ self._completer = completer # Reuse its model cache
1672
+
1673
+ def get_suggestion(self, buffer, document):
1674
+ text = document.text_before_cursor
1675
+
1676
+ # Only suggest for slash commands
1677
+ if not text.startswith("/"):
1678
+ # Fall back to history for regular text
1679
+ if self._history:
1680
+ return self._history.get_suggestion(buffer, document)
1681
+ return None
1682
+
1683
+ parts = text.split(maxsplit=1)
1684
+ base_cmd = parts[0].lower()
1685
+
1686
+ if len(parts) == 1 and not text.endswith(" "):
1687
+ # Still typing the command name: /upd → suggest "ate"
1688
+ word = text[1:].lower()
1689
+ for cmd in COMMANDS:
1690
+ if self._completer is not None and not self._completer._command_allowed(cmd):
1691
+ continue
1692
+ cmd_name = cmd[1:] # strip leading /
1693
+ if cmd_name.startswith(word) and cmd_name != word:
1694
+ return Suggestion(cmd_name[len(word):])
1695
+ return None
1696
+
1697
+ # Command is complete — suggest subcommands or model names
1698
+ sub_text = parts[1] if len(parts) > 1 else ""
1699
+ sub_lower = sub_text.lower()
1700
+
1701
+ # Static subcommands
1702
+ if self._completer is not None and not self._completer._command_allowed(base_cmd):
1703
+ return None
1704
+ if base_cmd in SUBCOMMANDS and SUBCOMMANDS[base_cmd]:
1705
+ if " " not in sub_text:
1706
+ for sub in SUBCOMMANDS[base_cmd]:
1707
+ if sub.startswith(sub_lower) and sub != sub_lower:
1708
+ return Suggestion(sub[len(sub_text):])
1709
+
1710
+ # Fall back to history
1711
+ if self._history:
1712
+ return self._history.get_suggestion(buffer, document)
1713
+ return None
1714
+
1715
+
1716
+ def _file_size_label(path: str) -> str:
1717
+ """Return a compact human-readable file size, or '' on error."""
1718
+ try:
1719
+ size = os.path.getsize(path)
1720
+ except OSError:
1721
+ return ""
1722
+ if size < 1024:
1723
+ return f"{size}B"
1724
+ if size < 1024 * 1024:
1725
+ return f"{size / 1024:.0f}K"
1726
+ if size < 1024 * 1024 * 1024:
1727
+ return f"{size / (1024 * 1024):.1f}M"
1728
+ return f"{size / (1024 * 1024 * 1024):.1f}G"