@clawpump/claw-agent 0.1.5 → 0.1.7

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 (1212) hide show
  1. package/agent/.dockerignore +67 -0
  2. package/agent/.envrc +1 -1
  3. package/agent/.gitattributes +8 -0
  4. package/agent/AGENTS.md +216 -4
  5. package/agent/CONTRIBUTING.md +46 -8
  6. package/agent/Dockerfile +78 -35
  7. package/agent/MANIFEST.in +2 -0
  8. package/agent/README.md +12 -5
  9. package/agent/README.ur-pk.md +261 -0
  10. package/agent/README.zh-CN.md +11 -8
  11. package/agent/SECURITY.md +5 -4
  12. package/agent/acp_adapter/provenance.py +127 -0
  13. package/agent/acp_adapter/server.py +112 -5
  14. package/agent/acp_adapter/session.py +1 -6
  15. package/agent/acp_registry/agent.json +2 -2
  16. package/agent/agent/account_usage.py +313 -1
  17. package/agent/agent/agent_init.py +140 -37
  18. package/agent/agent/agent_runtime_helpers.py +342 -83
  19. package/agent/agent/anthropic_adapter.py +320 -33
  20. package/agent/agent/auxiliary_client.py +525 -105
  21. package/agent/agent/background_review.py +157 -19
  22. package/agent/agent/bedrock_adapter.py +71 -6
  23. package/agent/agent/billing_view.py +295 -0
  24. package/agent/agent/chat_completion_helpers.py +229 -4
  25. package/agent/agent/codex_responses_adapter.py +86 -10
  26. package/agent/agent/codex_runtime.py +153 -1
  27. package/agent/agent/coding_context.py +738 -0
  28. package/agent/agent/context_compressor.py +392 -44
  29. package/agent/agent/context_references.py +34 -1
  30. package/agent/agent/conversation_compression.py +159 -22
  31. package/agent/agent/conversation_loop.py +643 -908
  32. package/agent/agent/copilot_acp_client.py +4 -11
  33. package/agent/agent/credential_pool.py +5 -3
  34. package/agent/agent/credits_tracker.py +794 -0
  35. package/agent/agent/curator.py +91 -18
  36. package/agent/agent/curator_backup.py +26 -10
  37. package/agent/agent/display.py +42 -1
  38. package/agent/agent/error_classifier.py +52 -3
  39. package/agent/agent/errors.py +3 -0
  40. package/agent/agent/file_safety.py +0 -17
  41. package/agent/agent/gemini_native_adapter.py +31 -1
  42. package/agent/agent/i18n.py +48 -4
  43. package/agent/agent/image_gen_provider.py +74 -5
  44. package/agent/agent/image_routing.py +29 -0
  45. package/agent/agent/insights.py +8 -17
  46. package/agent/agent/lsp/install.py +3 -0
  47. package/agent/agent/memory_manager.py +326 -31
  48. package/agent/agent/message_content.py +50 -0
  49. package/agent/agent/model_metadata.py +214 -3
  50. package/agent/agent/moonshot_schema.py +8 -1
  51. package/agent/agent/onboarding.py +60 -0
  52. package/agent/agent/prompt_builder.py +327 -37
  53. package/agent/agent/redact.py +1 -0
  54. package/agent/agent/runtime_cwd.py +34 -5
  55. package/agent/agent/secret_scope.py +205 -0
  56. package/agent/agent/secret_sources/bitwarden.py +34 -2
  57. package/agent/agent/skill_commands.py +90 -1
  58. package/agent/agent/skill_preprocessing.py +1 -0
  59. package/agent/agent/skill_utils.py +209 -36
  60. package/agent/agent/ssl_guard.py +94 -0
  61. package/agent/agent/system_prompt.py +133 -5
  62. package/agent/agent/tool_executor.py +496 -70
  63. package/agent/agent/transports/anthropic.py +83 -21
  64. package/agent/agent/transports/chat_completions.py +94 -5
  65. package/agent/agent/transports/codex.py +67 -2
  66. package/agent/agent/transports/codex_app_server.py +1 -0
  67. package/agent/agent/transports/codex_app_server_session.py +30 -0
  68. package/agent/agent/transports/types.py +12 -0
  69. package/agent/agent/turn_context.py +408 -0
  70. package/agent/agent/turn_finalizer.py +428 -0
  71. package/agent/agent/turn_retry_state.py +68 -0
  72. package/agent/agent/usage_pricing.py +3 -0
  73. package/agent/apps/bootstrap-installer/package.json +6 -5
  74. package/agent/apps/bootstrap-installer/src/routes/failure.tsx +12 -5
  75. package/agent/apps/bootstrap-installer/src/routes/progress.tsx +1 -3
  76. package/agent/apps/bootstrap-installer/src/store.ts +3 -2
  77. package/agent/apps/bootstrap-installer/src-tauri/src/bootstrap.rs +172 -7
  78. package/agent/apps/bootstrap-installer/src-tauri/src/events.rs +14 -1
  79. package/agent/apps/bootstrap-installer/src-tauri/src/paths.rs +29 -0
  80. package/agent/apps/bootstrap-installer/src-tauri/src/powershell.rs +93 -3
  81. package/agent/apps/bootstrap-installer/src-tauri/src/update.rs +695 -39
  82. package/agent/apps/bootstrap-installer/tsconfig.json +3 -4
  83. package/agent/apps/desktop/DESIGN.md +167 -0
  84. package/agent/apps/desktop/README.md +20 -16
  85. package/agent/apps/desktop/assets/icon.icns +0 -0
  86. package/agent/apps/desktop/assets/icon.ico +0 -0
  87. package/agent/apps/desktop/assets/icon.png +0 -0
  88. package/agent/apps/desktop/electron/backend-env.cjs +112 -0
  89. package/agent/apps/desktop/electron/backend-env.test.cjs +111 -0
  90. package/agent/apps/desktop/electron/backend-probes.test.cjs +3 -1
  91. package/agent/apps/desktop/electron/backend-ready.cjs +66 -0
  92. package/agent/apps/desktop/electron/bootstrap-platform.cjs +52 -0
  93. package/agent/apps/desktop/electron/bootstrap-platform.test.cjs +59 -1
  94. package/agent/apps/desktop/electron/bootstrap-runner.cjs +176 -38
  95. package/agent/apps/desktop/electron/bootstrap-runner.test.cjs +112 -1
  96. package/agent/apps/desktop/electron/connection-config.cjs +288 -0
  97. package/agent/apps/desktop/electron/connection-config.test.cjs +396 -0
  98. package/agent/apps/desktop/electron/dashboard-token.cjs +99 -0
  99. package/agent/apps/desktop/electron/dashboard-token.test.cjs +142 -0
  100. package/agent/apps/desktop/electron/desktop-uninstall.cjs +232 -0
  101. package/agent/apps/desktop/electron/desktop-uninstall.test.cjs +246 -0
  102. package/agent/apps/desktop/electron/entitlements.mac.inherit.plist +2 -0
  103. package/agent/apps/desktop/electron/fs-read-dir.cjs +109 -0
  104. package/agent/apps/desktop/electron/fs-read-dir.test.cjs +364 -0
  105. package/agent/apps/desktop/electron/gateway-ws-probe.cjs +188 -0
  106. package/agent/apps/desktop/electron/gateway-ws-probe.test.cjs +122 -0
  107. package/agent/apps/desktop/electron/git-root.cjs +54 -0
  108. package/agent/apps/desktop/electron/git-root.test.cjs +40 -0
  109. package/agent/apps/desktop/electron/git-worktrees.cjs +174 -0
  110. package/agent/apps/desktop/electron/hardening.cjs +123 -28
  111. package/agent/apps/desktop/electron/hardening.test.cjs +163 -0
  112. package/agent/apps/desktop/electron/main.cjs +3121 -331
  113. package/agent/apps/desktop/electron/oauth-net-request.cjs +20 -0
  114. package/agent/apps/desktop/electron/oauth-net-request.test.cjs +34 -0
  115. package/agent/apps/desktop/electron/preload.cjs +52 -2
  116. package/agent/apps/desktop/electron/session-windows.cjs +124 -0
  117. package/agent/apps/desktop/electron/session-windows.test.cjs +199 -0
  118. package/agent/apps/desktop/electron/update-rebuild.cjs +29 -0
  119. package/agent/apps/desktop/electron/update-rebuild.test.cjs +55 -0
  120. package/agent/apps/desktop/electron/update-remote.cjs +56 -0
  121. package/agent/apps/desktop/electron/update-remote.test.cjs +78 -0
  122. package/agent/apps/desktop/electron/vscode-marketplace.cjs +331 -0
  123. package/agent/apps/desktop/electron/vscode-marketplace.test.cjs +113 -0
  124. package/agent/apps/desktop/electron/windows-child-process.test.cjs +57 -0
  125. package/agent/apps/desktop/electron/windows-user-env.cjs +76 -0
  126. package/agent/apps/desktop/electron/windows-user-env.test.cjs +90 -0
  127. package/agent/apps/desktop/electron/workspace-cwd.cjs +38 -0
  128. package/agent/apps/desktop/electron/workspace-cwd.test.cjs +45 -0
  129. package/agent/apps/desktop/eslint.config.mjs +0 -3
  130. package/agent/apps/desktop/index.html +27 -2
  131. package/agent/apps/desktop/package.json +31 -11
  132. package/agent/apps/desktop/pr-assets/session-source-folders.png +0 -0
  133. package/agent/apps/desktop/public/apple-touch-icon.png +0 -0
  134. package/agent/apps/desktop/public/nous-girl.jpg +0 -0
  135. package/agent/apps/desktop/scripts/assert-dist-built.cjs +70 -0
  136. package/agent/apps/desktop/scripts/assert-dist-built.test.cjs +84 -0
  137. package/agent/apps/desktop/scripts/before-pack.cjs +78 -0
  138. package/agent/apps/desktop/scripts/before-pack.test.cjs +53 -0
  139. package/agent/apps/desktop/scripts/diag-scroll-reset.mjs +229 -0
  140. package/agent/apps/desktop/scripts/patch-electron-builder-mac-binary.cjs +64 -0
  141. package/agent/apps/desktop/scripts/run-electron-builder.cjs +57 -0
  142. package/agent/apps/desktop/src/app/agents/index.tsx +53 -45
  143. package/agent/apps/desktop/src/app/artifacts/index.tsx +102 -83
  144. package/agent/apps/desktop/src/app/chat/chat-drop-overlay.tsx +29 -8
  145. package/agent/apps/desktop/src/app/chat/chat-swap-overlay.tsx +47 -0
  146. package/agent/apps/desktop/src/app/chat/composer/attachments.tsx +81 -45
  147. package/agent/apps/desktop/src/app/chat/composer/completion-drawer.tsx +13 -24
  148. package/agent/apps/desktop/src/app/chat/composer/context-menu.tsx +138 -88
  149. package/agent/apps/desktop/src/app/chat/composer/controls.tsx +138 -90
  150. package/agent/apps/desktop/src/app/chat/composer/enter-submit-dom-race.test.tsx +218 -0
  151. package/agent/apps/desktop/src/app/chat/composer/focus.ts +32 -0
  152. package/agent/apps/desktop/src/app/chat/composer/help-hint.tsx +38 -25
  153. package/agent/apps/desktop/src/app/chat/composer/hooks/use-live-completion-adapter.ts +7 -0
  154. package/agent/apps/desktop/src/app/chat/composer/hooks/use-mic-recorder.ts +22 -12
  155. package/agent/apps/desktop/src/app/chat/composer/hooks/use-slash-completions.ts +142 -14
  156. package/agent/apps/desktop/src/app/chat/composer/hooks/use-voice-conversation.ts +14 -11
  157. package/agent/apps/desktop/src/app/chat/composer/hooks/use-voice-recorder.ts +9 -6
  158. package/agent/apps/desktop/src/app/chat/composer/ime-composition-dom-repro.test.tsx +108 -0
  159. package/agent/apps/desktop/src/app/chat/composer/index.tsx +930 -180
  160. package/agent/apps/desktop/src/app/chat/composer/inline-refs.ts +136 -32
  161. package/agent/apps/desktop/src/app/chat/composer/model-pill.tsx +86 -0
  162. package/agent/apps/desktop/src/app/chat/composer/queue-panel.tsx +54 -75
  163. package/agent/apps/desktop/src/app/chat/composer/rich-editor.test.ts +117 -1
  164. package/agent/apps/desktop/src/app/chat/composer/rich-editor.ts +117 -6
  165. package/agent/apps/desktop/src/app/chat/composer/slash-nav-dom-repro.test.tsx +186 -0
  166. package/agent/apps/desktop/src/app/chat/composer/status-stack/index.tsx +202 -0
  167. package/agent/apps/desktop/src/app/chat/composer/status-stack/status-row.tsx +155 -0
  168. package/agent/apps/desktop/src/app/chat/composer/text-utils.test.ts +104 -0
  169. package/agent/apps/desktop/src/app/chat/composer/text-utils.ts +37 -9
  170. package/agent/apps/desktop/src/app/chat/composer/trigger-popover.test.tsx +50 -0
  171. package/agent/apps/desktop/src/app/chat/composer/trigger-popover.tsx +105 -40
  172. package/agent/apps/desktop/src/app/chat/composer/types.ts +5 -0
  173. package/agent/apps/desktop/src/app/chat/composer/url-dialog.tsx +11 -15
  174. package/agent/apps/desktop/src/app/chat/composer/voice-activity.tsx +8 -4
  175. package/agent/apps/desktop/src/app/chat/hooks/use-composer-actions.test.ts +57 -0
  176. package/agent/apps/desktop/src/app/chat/hooks/use-composer-actions.ts +70 -16
  177. package/agent/apps/desktop/src/app/chat/hooks/use-file-drop-zone.ts +52 -16
  178. package/agent/apps/desktop/src/app/chat/index.tsx +234 -81
  179. package/agent/apps/desktop/src/app/chat/perf-probe.tsx +69 -21
  180. package/agent/apps/desktop/src/app/chat/right-rail/preview-console.tsx +44 -40
  181. package/agent/apps/desktop/src/app/chat/right-rail/preview-file.tsx +71 -25
  182. package/agent/apps/desktop/src/app/chat/right-rail/preview-pane.test.tsx +40 -1
  183. package/agent/apps/desktop/src/app/chat/right-rail/preview-pane.tsx +55 -53
  184. package/agent/apps/desktop/src/app/chat/right-rail/preview.tsx +35 -17
  185. package/agent/apps/desktop/src/app/chat/scroll-to-bottom-button.test.tsx +67 -0
  186. package/agent/apps/desktop/src/app/chat/scroll-to-bottom-button.tsx +74 -0
  187. package/agent/apps/desktop/src/app/chat/sidebar/cron-jobs-section.tsx +356 -0
  188. package/agent/apps/desktop/src/app/chat/sidebar/index.tsx +1189 -364
  189. package/agent/apps/desktop/src/app/chat/sidebar/load-more-row.tsx +30 -0
  190. package/agent/apps/desktop/src/app/chat/sidebar/order.test.ts +21 -0
  191. package/agent/apps/desktop/src/app/chat/sidebar/order.ts +17 -0
  192. package/agent/apps/desktop/src/app/chat/sidebar/profile-switcher.tsx +524 -0
  193. package/agent/apps/desktop/src/app/chat/sidebar/session-actions-menu.tsx +80 -45
  194. package/agent/apps/desktop/src/app/chat/sidebar/session-row.tsx +120 -25
  195. package/agent/apps/desktop/src/app/chat/sidebar/virtual-session-list.tsx +7 -13
  196. package/agent/apps/desktop/src/app/chat/sidebar/workspace-groups.test.ts +149 -0
  197. package/agent/apps/desktop/src/app/chat/sidebar/workspace-groups.ts +326 -0
  198. package/agent/apps/desktop/src/app/chat/thread-loading.ts +7 -2
  199. package/agent/apps/desktop/src/app/command-center/index.tsx +320 -581
  200. package/agent/apps/desktop/src/app/command-palette/index.tsx +681 -0
  201. package/agent/apps/desktop/src/app/command-palette/marketplace-theme-page.tsx +157 -0
  202. package/agent/apps/desktop/src/app/cron/index.tsx +392 -324
  203. package/agent/apps/desktop/src/app/cron/job-state.ts +29 -0
  204. package/agent/apps/desktop/src/app/desktop-controller.tsx +618 -123
  205. package/agent/apps/desktop/src/app/floating-hud.ts +22 -0
  206. package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-boot.test.tsx +265 -0
  207. package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-boot.ts +260 -14
  208. package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-request.ts +48 -4
  209. package/agent/apps/desktop/src/app/hooks/use-keybinds.ts +270 -0
  210. package/agent/apps/desktop/src/app/hooks/use-refresh-hotkey.ts +45 -0
  211. package/agent/apps/desktop/src/app/layout-constants.ts +19 -0
  212. package/agent/apps/desktop/src/app/messaging/index.tsx +136 -241
  213. package/agent/apps/desktop/src/app/messaging/platform-icon.tsx +95 -0
  214. package/agent/apps/desktop/src/app/model-visibility-overlay.tsx +31 -0
  215. package/agent/apps/desktop/src/app/overlays/overlay-search-input.tsx +18 -62
  216. package/agent/apps/desktop/src/app/overlays/overlay-split-layout.tsx +59 -7
  217. package/agent/apps/desktop/src/app/overlays/overlay-view.tsx +9 -5
  218. package/agent/apps/desktop/src/app/page-search-shell.tsx +42 -20
  219. package/agent/apps/desktop/src/app/profiles/create-profile-dialog.tsx +165 -0
  220. package/agent/apps/desktop/src/app/profiles/delete-profile-dialog.tsx +65 -0
  221. package/agent/apps/desktop/src/app/profiles/index.tsx +174 -199
  222. package/agent/apps/desktop/src/app/profiles/rename-profile-dialog.tsx +125 -0
  223. package/agent/apps/desktop/src/app/right-sidebar/files/dnd-manager.ts +27 -0
  224. package/agent/apps/desktop/src/app/right-sidebar/files/ipc.test.ts +100 -0
  225. package/agent/apps/desktop/src/app/right-sidebar/files/ipc.ts +12 -18
  226. package/agent/apps/desktop/src/app/right-sidebar/files/remote-picker.tsx +177 -0
  227. package/agent/apps/desktop/src/app/right-sidebar/files/tree.tsx +35 -21
  228. package/agent/apps/desktop/src/app/right-sidebar/files/use-project-tree.test.ts +75 -3
  229. package/agent/apps/desktop/src/app/right-sidebar/files/use-project-tree.ts +152 -5
  230. package/agent/apps/desktop/src/app/right-sidebar/index.test.tsx +75 -0
  231. package/agent/apps/desktop/src/app/right-sidebar/index.tsx +166 -129
  232. package/agent/apps/desktop/src/app/right-sidebar/store.ts +19 -4
  233. package/agent/apps/desktop/src/app/right-sidebar/terminal/buffer.ts +65 -0
  234. package/agent/apps/desktop/src/app/right-sidebar/terminal/index.tsx +29 -34
  235. package/agent/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx +18 -6
  236. package/agent/apps/desktop/src/app/right-sidebar/terminal/selection.ts +93 -32
  237. package/agent/apps/desktop/src/app/right-sidebar/terminal/use-terminal-session.ts +381 -119
  238. package/agent/apps/desktop/src/app/routes.ts +9 -0
  239. package/agent/apps/desktop/src/app/session/hooks/use-cwd-actions.ts +17 -7
  240. package/agent/apps/desktop/src/app/session/hooks/use-message-stream.ts +365 -47
  241. package/agent/apps/desktop/src/app/session/hooks/use-model-controls.test.tsx +198 -0
  242. package/agent/apps/desktop/src/app/session/hooks/use-model-controls.ts +70 -34
  243. package/agent/apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx +1061 -0
  244. package/agent/apps/desktop/src/app/session/hooks/use-prompt-actions.ts +1143 -165
  245. package/agent/apps/desktop/src/app/session/hooks/use-route-resume.test.tsx +341 -2
  246. package/agent/apps/desktop/src/app/session/hooks/use-route-resume.ts +176 -5
  247. package/agent/apps/desktop/src/app/session/hooks/use-session-actions.test.tsx +259 -0
  248. package/agent/apps/desktop/src/app/session/hooks/use-session-actions.ts +452 -149
  249. package/agent/apps/desktop/src/app/session/hooks/use-session-state-cache.test.tsx +327 -0
  250. package/agent/apps/desktop/src/app/session/hooks/use-session-state-cache.ts +133 -4
  251. package/agent/apps/desktop/src/app/session-picker-overlay.tsx +32 -0
  252. package/agent/apps/desktop/src/app/session-switcher.tsx +107 -0
  253. package/agent/apps/desktop/src/app/settings/about-settings.tsx +45 -36
  254. package/agent/apps/desktop/src/app/settings/appearance-settings.tsx +243 -162
  255. package/agent/apps/desktop/src/app/settings/config-settings.tsx +86 -66
  256. package/agent/apps/desktop/src/app/settings/constants.ts +459 -122
  257. package/agent/apps/desktop/src/app/settings/credential-key-ui.tsx +373 -0
  258. package/agent/apps/desktop/src/app/settings/env-credentials.tsx +198 -0
  259. package/agent/apps/desktop/src/app/settings/env-var-actions-menu.tsx +136 -0
  260. package/agent/apps/desktop/src/app/settings/field-copy.ts +56 -0
  261. package/agent/apps/desktop/src/app/settings/gateway-settings.tsx +385 -72
  262. package/agent/apps/desktop/src/app/settings/helpers.test.ts +156 -1
  263. package/agent/apps/desktop/src/app/settings/helpers.ts +30 -2
  264. package/agent/apps/desktop/src/app/settings/index.tsx +118 -84
  265. package/agent/apps/desktop/src/app/settings/keys-settings.tsx +62 -419
  266. package/agent/apps/desktop/src/app/settings/mcp-settings.tsx +65 -60
  267. package/agent/apps/desktop/src/app/settings/model-settings.test.tsx +129 -5
  268. package/agent/apps/desktop/src/app/settings/model-settings.tsx +370 -65
  269. package/agent/apps/desktop/src/app/settings/notifications-settings.tsx +150 -0
  270. package/agent/apps/desktop/src/app/settings/primitives.tsx +5 -11
  271. package/agent/apps/desktop/src/app/settings/provider-config-panel.test.tsx +142 -0
  272. package/agent/apps/desktop/src/app/settings/provider-config-panel.tsx +182 -0
  273. package/agent/apps/desktop/src/app/settings/providers-settings.test.tsx +171 -0
  274. package/agent/apps/desktop/src/app/settings/providers-settings.tsx +471 -0
  275. package/agent/apps/desktop/src/app/settings/sessions-settings.tsx +183 -71
  276. package/agent/apps/desktop/src/app/settings/toolset-config-panel.test.tsx +135 -1
  277. package/agent/apps/desktop/src/app/settings/toolset-config-panel.tsx +180 -57
  278. package/agent/apps/desktop/src/app/settings/types.ts +9 -6
  279. package/agent/apps/desktop/src/app/settings/uninstall-section.tsx +185 -0
  280. package/agent/apps/desktop/src/app/settings/use-deep-link-highlight.ts +60 -0
  281. package/agent/apps/desktop/src/app/shell/app-shell.tsx +59 -13
  282. package/agent/apps/desktop/src/app/shell/gateway-menu-panel.tsx +37 -32
  283. package/agent/apps/desktop/src/app/shell/hooks/use-overlay-routing.ts +6 -3
  284. package/agent/apps/desktop/src/app/shell/hooks/use-statusbar-items.tsx +212 -53
  285. package/agent/apps/desktop/src/app/shell/keybind-panel.tsx +215 -0
  286. package/agent/apps/desktop/src/app/shell/model-edit-submenu.test.tsx +84 -0
  287. package/agent/apps/desktop/src/app/shell/model-edit-submenu.tsx +244 -0
  288. package/agent/apps/desktop/src/app/shell/model-menu-panel.tsx +392 -0
  289. package/agent/apps/desktop/src/app/shell/statusbar-controls.tsx +23 -33
  290. package/agent/apps/desktop/src/app/shell/titlebar-controls.tsx +79 -95
  291. package/agent/apps/desktop/src/app/shell/titlebar.ts +8 -2
  292. package/agent/apps/desktop/src/app/skills/index.test.tsx +11 -0
  293. package/agent/apps/desktop/src/app/skills/index.tsx +79 -64
  294. package/agent/apps/desktop/src/app/types.ts +85 -0
  295. package/agent/apps/desktop/src/app/updates-overlay.tsx +110 -105
  296. package/agent/apps/desktop/src/components/assistant-ui/ansi-text.tsx +34 -0
  297. package/agent/apps/desktop/src/components/assistant-ui/block-direction.test.tsx +129 -0
  298. package/agent/apps/desktop/src/components/assistant-ui/clarify-tool.tsx +102 -81
  299. package/agent/apps/desktop/src/components/assistant-ui/directive-text.tsx +92 -15
  300. package/agent/apps/desktop/src/components/assistant-ui/markdown-text.test.ts +38 -0
  301. package/agent/apps/desktop/src/components/assistant-ui/markdown-text.tsx +304 -45
  302. package/agent/apps/desktop/src/components/assistant-ui/message-render-boundary.test.tsx +80 -0
  303. package/agent/apps/desktop/src/components/assistant-ui/message-render-boundary.tsx +48 -0
  304. package/agent/apps/desktop/src/components/assistant-ui/streaming.test.tsx +142 -90
  305. package/agent/apps/desktop/src/components/assistant-ui/thread-list.tsx +337 -0
  306. package/agent/apps/desktop/src/components/assistant-ui/thread.tsx +667 -190
  307. package/agent/apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx +299 -0
  308. package/agent/apps/desktop/src/components/assistant-ui/tool-approval.test.tsx +133 -0
  309. package/agent/apps/desktop/src/components/assistant-ui/tool-approval.tsx +239 -0
  310. package/agent/apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts +31 -0
  311. package/agent/apps/desktop/src/components/assistant-ui/tool-fallback-model.ts +152 -134
  312. package/agent/apps/desktop/src/components/assistant-ui/tool-fallback.tsx +142 -150
  313. package/agent/apps/desktop/src/components/assistant-ui/tooltip-icon-button.tsx +14 -12
  314. package/agent/apps/desktop/src/components/assistant-ui/user-message-edit.test.tsx +141 -0
  315. package/agent/apps/desktop/src/components/assistant-ui/user-message-text.tsx +152 -0
  316. package/agent/apps/desktop/src/components/boot-failure-overlay.tsx +150 -33
  317. package/agent/apps/desktop/src/components/boot-failure-reauth.test.ts +100 -0
  318. package/agent/apps/desktop/src/components/boot-failure-reauth.ts +81 -0
  319. package/agent/apps/desktop/src/components/brand-mark.tsx +19 -0
  320. package/agent/apps/desktop/src/components/chat/code-card.tsx +1 -1
  321. package/agent/apps/desktop/src/components/chat/composer-dock.ts +31 -0
  322. package/agent/apps/desktop/src/components/chat/diff-lines.tsx +1 -1
  323. package/agent/apps/desktop/src/components/chat/disclosure-row.tsx +13 -3
  324. package/agent/apps/desktop/src/components/chat/expandable-block.tsx +52 -0
  325. package/agent/apps/desktop/src/components/chat/generated-image-result.tsx +174 -0
  326. package/agent/apps/desktop/src/components/chat/image-generation-placeholder.tsx +70 -37
  327. package/agent/apps/desktop/src/components/chat/intro.tsx +8 -7
  328. package/agent/apps/desktop/src/components/chat/preview-attachment.tsx +4 -2
  329. package/agent/apps/desktop/src/components/chat/shiki-highlighter.test.ts +37 -0
  330. package/agent/apps/desktop/src/components/chat/shiki-highlighter.tsx +96 -22
  331. package/agent/apps/desktop/src/components/chat/status-row.tsx +70 -0
  332. package/agent/apps/desktop/src/components/chat/status-section.tsx +42 -0
  333. package/agent/apps/desktop/src/components/chat/terminal-output.tsx +54 -0
  334. package/agent/apps/desktop/src/components/chat/zoomable-image.tsx +70 -109
  335. package/agent/apps/desktop/src/components/desktop-install-overlay.tsx +154 -84
  336. package/agent/apps/desktop/src/components/desktop-onboarding-overlay.test.tsx +38 -8
  337. package/agent/apps/desktop/src/components/desktop-onboarding-overlay.tsx +789 -233
  338. package/agent/apps/desktop/src/components/error-boundary.tsx +77 -0
  339. package/agent/apps/desktop/src/components/gateway-connecting-overlay.test.tsx +144 -0
  340. package/agent/apps/desktop/src/components/gateway-connecting-overlay.tsx +7 -1
  341. package/agent/apps/desktop/src/components/haptics-provider.tsx +24 -0
  342. package/agent/apps/desktop/src/components/language-switcher.test.tsx +53 -0
  343. package/agent/apps/desktop/src/components/language-switcher.tsx +175 -0
  344. package/agent/apps/desktop/src/components/model-picker.tsx +42 -40
  345. package/agent/apps/desktop/src/components/model-visibility-dialog.tsx +166 -0
  346. package/agent/apps/desktop/src/components/notifications.tsx +48 -27
  347. package/agent/apps/desktop/src/components/pane-shell/index.ts +1 -1
  348. package/agent/apps/desktop/src/components/pane-shell/pane-shell.tsx +146 -9
  349. package/agent/apps/desktop/src/components/prompt-overlays.tsx +234 -0
  350. package/agent/apps/desktop/src/components/session-picker.tsx +108 -0
  351. package/agent/apps/desktop/src/components/ui/action-status.tsx +25 -0
  352. package/agent/apps/desktop/src/components/ui/badge.tsx +35 -0
  353. package/agent/apps/desktop/src/components/ui/button.tsx +37 -13
  354. package/agent/apps/desktop/src/components/ui/confirm-dialog.tsx +109 -0
  355. package/agent/apps/desktop/src/components/ui/control.ts +25 -0
  356. package/agent/apps/desktop/src/components/ui/copy-button.test.tsx +36 -0
  357. package/agent/apps/desktop/src/components/ui/copy-button.tsx +38 -27
  358. package/agent/apps/desktop/src/components/ui/dialog.tsx +39 -11
  359. package/agent/apps/desktop/src/components/ui/dropdown-menu.tsx +98 -24
  360. package/agent/apps/desktop/src/components/ui/error-state.tsx +50 -0
  361. package/agent/apps/desktop/src/components/ui/fade-text.tsx +9 -2
  362. package/agent/apps/desktop/src/components/ui/{braille-spinner.tsx → glyph-spinner.tsx} +15 -13
  363. package/agent/apps/desktop/src/components/ui/input.tsx +5 -2
  364. package/agent/apps/desktop/src/components/ui/kbd.tsx +83 -12
  365. package/agent/apps/desktop/src/components/ui/log-view.tsx +19 -0
  366. package/agent/apps/desktop/src/components/ui/pagination.tsx +12 -5
  367. package/agent/apps/desktop/src/components/ui/popover.tsx +44 -0
  368. package/agent/apps/desktop/src/components/ui/search-field.tsx +80 -0
  369. package/agent/apps/desktop/src/components/ui/segmented-control.tsx +51 -0
  370. package/agent/apps/desktop/src/components/ui/select.tsx +10 -3
  371. package/agent/apps/desktop/src/components/ui/sheet.tsx +8 -2
  372. package/agent/apps/desktop/src/components/ui/sidebar.tsx +18 -25
  373. package/agent/apps/desktop/src/components/ui/switch.tsx +38 -15
  374. package/agent/apps/desktop/src/components/ui/textarea.tsx +4 -11
  375. package/agent/apps/desktop/src/components/ui/tool-icon.tsx +65 -0
  376. package/agent/apps/desktop/src/components/ui/tooltip.tsx +31 -4
  377. package/agent/apps/desktop/src/fonts/JetBrainsMono-Bold.woff2 +0 -0
  378. package/agent/apps/desktop/src/fonts/JetBrainsMono-Italic.woff2 +0 -0
  379. package/agent/apps/desktop/src/fonts/JetBrainsMono-Regular.woff2 +0 -0
  380. package/agent/apps/desktop/src/global.d.ts +181 -4
  381. package/agent/apps/desktop/src/hermes.test.ts +60 -0
  382. package/agent/apps/desktop/src/hermes.ts +190 -13
  383. package/agent/apps/desktop/src/hooks/use-image-download.ts +85 -0
  384. package/agent/apps/desktop/src/hooks/use-resize-observer.ts +13 -4
  385. package/agent/apps/desktop/src/hooks/use-worktree-info.ts +68 -0
  386. package/agent/apps/desktop/src/i18n/catalog.ts +12 -0
  387. package/agent/apps/desktop/src/i18n/context.test.tsx +232 -0
  388. package/agent/apps/desktop/src/i18n/context.tsx +183 -0
  389. package/agent/apps/desktop/src/i18n/define-locale.ts +41 -0
  390. package/agent/apps/desktop/src/i18n/en.ts +1921 -0
  391. package/agent/apps/desktop/src/i18n/index.ts +20 -0
  392. package/agent/apps/desktop/src/i18n/ja.ts +2053 -0
  393. package/agent/apps/desktop/src/i18n/languages.test.ts +43 -0
  394. package/agent/apps/desktop/src/i18n/languages.ts +86 -0
  395. package/agent/apps/desktop/src/i18n/runtime.test.ts +75 -0
  396. package/agent/apps/desktop/src/i18n/runtime.ts +53 -0
  397. package/agent/apps/desktop/src/i18n/types.ts +1559 -0
  398. package/agent/apps/desktop/src/i18n/zh-hant.ts +1992 -0
  399. package/agent/apps/desktop/src/i18n/zh.ts +2099 -0
  400. package/agent/apps/desktop/src/lib/ansi.test.ts +123 -0
  401. package/agent/apps/desktop/src/lib/ansi.ts +186 -0
  402. package/agent/apps/desktop/src/lib/chat-messages.test.ts +79 -0
  403. package/agent/apps/desktop/src/lib/chat-messages.ts +68 -29
  404. package/agent/apps/desktop/src/lib/chat-runtime.test.ts +65 -1
  405. package/agent/apps/desktop/src/lib/chat-runtime.ts +39 -3
  406. package/agent/apps/desktop/src/lib/completion-sound.ts +519 -0
  407. package/agent/apps/desktop/src/lib/desktop-fs.test.ts +116 -0
  408. package/agent/apps/desktop/src/lib/desktop-fs.ts +113 -0
  409. package/agent/apps/desktop/src/lib/desktop-slash-commands.test.ts +89 -6
  410. package/agent/apps/desktop/src/lib/desktop-slash-commands.ts +270 -131
  411. package/agent/apps/desktop/src/lib/external-link.test.tsx +27 -0
  412. package/agent/apps/desktop/src/lib/external-link.tsx +9 -2
  413. package/agent/apps/desktop/src/lib/gateway-events.test.ts +27 -0
  414. package/agent/apps/desktop/src/lib/gateway-events.ts +16 -0
  415. package/agent/apps/desktop/src/lib/gateway-ws-url.test.ts +78 -0
  416. package/agent/apps/desktop/src/lib/gateway-ws-url.ts +91 -0
  417. package/agent/apps/desktop/src/lib/generated-images.test.ts +97 -0
  418. package/agent/apps/desktop/src/lib/generated-images.ts +116 -0
  419. package/agent/apps/desktop/src/lib/haptics.ts +17 -0
  420. package/agent/apps/desktop/src/lib/icons.ts +10 -2
  421. package/agent/apps/desktop/src/lib/keybinds/actions.ts +137 -0
  422. package/agent/apps/desktop/src/lib/keybinds/combo.test.ts +86 -0
  423. package/agent/apps/desktop/src/lib/keybinds/combo.ts +195 -0
  424. package/agent/apps/desktop/src/lib/local-preview.ts +23 -2
  425. package/agent/apps/desktop/src/lib/markdown-preprocess.ts +20 -7
  426. package/agent/apps/desktop/src/lib/media.remote.test.ts +90 -0
  427. package/agent/apps/desktop/src/lib/media.ts +40 -1
  428. package/agent/apps/desktop/src/lib/model-status-label.test.ts +59 -0
  429. package/agent/apps/desktop/src/lib/model-status-label.ts +122 -0
  430. package/agent/apps/desktop/src/lib/mutable-ref.ts +6 -0
  431. package/agent/apps/desktop/src/lib/profile-color.ts +58 -0
  432. package/agent/apps/desktop/src/lib/query-client.ts +13 -0
  433. package/agent/apps/desktop/src/lib/remend-tail.test.ts +105 -0
  434. package/agent/apps/desktop/src/lib/remend-tail.ts +108 -0
  435. package/agent/apps/desktop/src/lib/session-export.ts +6 -3
  436. package/agent/apps/desktop/src/lib/session-ids.test.ts +44 -0
  437. package/agent/apps/desktop/src/lib/session-ids.ts +26 -0
  438. package/agent/apps/desktop/src/lib/session-search.test.ts +66 -0
  439. package/agent/apps/desktop/src/lib/session-search.ts +21 -0
  440. package/agent/apps/desktop/src/lib/session-source.ts +126 -0
  441. package/agent/apps/desktop/src/lib/storage.test.ts +25 -0
  442. package/agent/apps/desktop/src/lib/storage.ts +35 -1
  443. package/agent/apps/desktop/src/lib/todos.test.ts +46 -1
  444. package/agent/apps/desktop/src/lib/todos.ts +37 -0
  445. package/agent/apps/desktop/src/lib/tool-result-summary.ts +5 -1
  446. package/agent/apps/desktop/src/lib/update-copy.test.ts +38 -0
  447. package/agent/apps/desktop/src/lib/update-copy.ts +44 -0
  448. package/agent/apps/desktop/src/lib/use-enter-animation.ts +2 -2
  449. package/agent/apps/desktop/src/lib/yolo-session.ts +50 -0
  450. package/agent/apps/desktop/src/main.tsx +19 -19
  451. package/agent/apps/desktop/src/store/boot.ts +4 -3
  452. package/agent/apps/desktop/src/store/clarify.test.ts +81 -0
  453. package/agent/apps/desktop/src/store/clarify.ts +50 -13
  454. package/agent/apps/desktop/src/store/command-palette.ts +20 -0
  455. package/agent/apps/desktop/src/store/compaction.test.ts +53 -0
  456. package/agent/apps/desktop/src/store/compaction.ts +38 -0
  457. package/agent/apps/desktop/src/store/completion-sound.ts +32 -0
  458. package/agent/apps/desktop/src/store/composer-input-history.test.ts +147 -0
  459. package/agent/apps/desktop/src/store/composer-input-history.ts +158 -0
  460. package/agent/apps/desktop/src/store/composer-queue.test.ts +68 -0
  461. package/agent/apps/desktop/src/store/composer-queue.ts +76 -0
  462. package/agent/apps/desktop/src/store/composer-status.test.ts +99 -0
  463. package/agent/apps/desktop/src/store/composer-status.ts +277 -0
  464. package/agent/apps/desktop/src/store/composer.test.ts +106 -0
  465. package/agent/apps/desktop/src/store/composer.ts +116 -0
  466. package/agent/apps/desktop/src/store/cron.ts +19 -0
  467. package/agent/apps/desktop/src/store/gateway.ts +280 -6
  468. package/agent/apps/desktop/src/store/keybinds.ts +143 -0
  469. package/agent/apps/desktop/src/store/layout.ts +107 -9
  470. package/agent/apps/desktop/src/store/model-presets.test.ts +51 -0
  471. package/agent/apps/desktop/src/store/model-presets.ts +86 -0
  472. package/agent/apps/desktop/src/store/model-visibility.test.ts +99 -0
  473. package/agent/apps/desktop/src/store/model-visibility.ts +161 -0
  474. package/agent/apps/desktop/src/store/native-notifications.test.ts +192 -0
  475. package/agent/apps/desktop/src/store/native-notifications.ts +203 -0
  476. package/agent/apps/desktop/src/store/notifications.ts +10 -7
  477. package/agent/apps/desktop/src/store/onboarding.test.ts +271 -1
  478. package/agent/apps/desktop/src/store/onboarding.ts +268 -38
  479. package/agent/apps/desktop/src/store/preview.ts +10 -1
  480. package/agent/apps/desktop/src/store/profile.test.ts +89 -0
  481. package/agent/apps/desktop/src/store/profile.ts +395 -0
  482. package/agent/apps/desktop/src/store/prompts.test.ts +127 -0
  483. package/agent/apps/desktop/src/store/prompts.ts +117 -0
  484. package/agent/apps/desktop/src/store/session-switcher.test.ts +115 -0
  485. package/agent/apps/desktop/src/store/session-switcher.ts +128 -0
  486. package/agent/apps/desktop/src/store/session-sync.ts +25 -0
  487. package/agent/apps/desktop/src/store/session.test.ts +268 -2
  488. package/agent/apps/desktop/src/store/session.ts +392 -18
  489. package/agent/apps/desktop/src/store/subagents.ts +3 -0
  490. package/agent/apps/desktop/src/store/system-actions.ts +48 -0
  491. package/agent/apps/desktop/src/store/thread-scroll.ts +58 -5
  492. package/agent/apps/desktop/src/store/todos.test.ts +47 -0
  493. package/agent/apps/desktop/src/store/todos.ts +64 -0
  494. package/agent/apps/desktop/src/store/tool-dismiss.ts +45 -0
  495. package/agent/apps/desktop/src/store/translucency.ts +38 -0
  496. package/agent/apps/desktop/src/store/updates.test.ts +187 -2
  497. package/agent/apps/desktop/src/store/updates.ts +268 -18
  498. package/agent/apps/desktop/src/store/windows.test.ts +143 -0
  499. package/agent/apps/desktop/src/store/windows.ts +115 -0
  500. package/agent/apps/desktop/src/styles.css +510 -119
  501. package/agent/apps/desktop/src/themes/color.ts +142 -0
  502. package/agent/apps/desktop/src/themes/context.tsx +128 -75
  503. package/agent/apps/desktop/src/themes/install.test.ts +119 -0
  504. package/agent/apps/desktop/src/themes/install.ts +95 -0
  505. package/agent/apps/desktop/src/themes/presets.test.ts +33 -0
  506. package/agent/apps/desktop/src/themes/presets.ts +13 -4
  507. package/agent/apps/desktop/src/themes/profile-theme.test.ts +41 -0
  508. package/agent/apps/desktop/src/themes/types.ts +35 -0
  509. package/agent/apps/desktop/src/themes/user-themes.test.ts +63 -0
  510. package/agent/apps/desktop/src/themes/user-themes.ts +122 -0
  511. package/agent/apps/desktop/src/themes/vscode.test.ts +171 -0
  512. package/agent/apps/desktop/src/themes/vscode.ts +343 -0
  513. package/agent/apps/desktop/src/types/hermes.ts +138 -1
  514. package/agent/apps/desktop/tsconfig.json +2 -2
  515. package/agent/apps/desktop/vite.config.ts +18 -0
  516. package/agent/apps/shared/package.json +1 -1
  517. package/agent/apps/shared/src/json-rpc-gateway.ts +63 -2
  518. package/agent/apps/shared/tsconfig.json +2 -2
  519. package/agent/cli-config.yaml.example +78 -1
  520. package/agent/cli.py +2177 -3162
  521. package/agent/cron/blueprint_catalog.py +713 -0
  522. package/agent/cron/jobs.py +226 -110
  523. package/agent/cron/scheduler.py +468 -193
  524. package/agent/cron/scheduler_provider.py +177 -0
  525. package/agent/cron/scripts/__init__.py +1 -0
  526. package/agent/cron/scripts/classify_items.py +226 -0
  527. package/agent/cron/suggestion_catalog.py +154 -0
  528. package/agent/cron/suggestions.py +257 -0
  529. package/agent/docs/chronos-managed-cron-contract.md +196 -0
  530. package/agent/docs/design/profile-builder.md +146 -0
  531. package/agent/docs/middleware/README.md +260 -0
  532. package/agent/docs/observability/README.md +316 -0
  533. package/agent/docs/plans/2026-06-09-003-fix-telegram-stream-overflow-continuations-plan.md +240 -0
  534. package/agent/docs/rca-ssl-cacert-post-git-pull.md +54 -0
  535. package/agent/docs/relay-connector-contract.md +285 -0
  536. package/agent/gateway/authz_mixin.py +536 -0
  537. package/agent/gateway/channel_directory.py +65 -3
  538. package/agent/gateway/config.py +222 -12
  539. package/agent/gateway/display_config.py +10 -0
  540. package/agent/gateway/hooks.py +17 -0
  541. package/agent/gateway/kanban_watchers.py +1146 -0
  542. package/agent/gateway/message_timestamps.py +166 -0
  543. package/agent/gateway/platforms/ADDING_A_PLATFORM.md +29 -0
  544. package/agent/gateway/platforms/api_server.py +216 -38
  545. package/agent/gateway/platforms/base.py +210 -58
  546. package/agent/gateway/platforms/email.py +122 -12
  547. package/agent/gateway/platforms/feishu.py +80 -11
  548. package/agent/gateway/platforms/feishu_meeting_invite.py +212 -0
  549. package/agent/gateway/platforms/matrix.py +1498 -297
  550. package/agent/gateway/platforms/qqbot/adapter.py +6 -0
  551. package/agent/gateway/platforms/signal.py +8 -0
  552. package/agent/gateway/platforms/slack.py +308 -12
  553. package/agent/gateway/platforms/telegram.py +831 -24
  554. package/agent/gateway/platforms/webhook.py +109 -21
  555. package/agent/gateway/platforms/weixin.py +113 -2
  556. package/agent/gateway/platforms/whatsapp.py +94 -288
  557. package/agent/gateway/platforms/whatsapp_cloud.py +1956 -0
  558. package/agent/gateway/platforms/whatsapp_common.py +367 -0
  559. package/agent/gateway/platforms/yuanbao.py +608 -191
  560. package/agent/gateway/platforms/yuanbao_proto.py +232 -23
  561. package/agent/gateway/relay/__init__.py +375 -0
  562. package/agent/gateway/relay/adapter.py +222 -0
  563. package/agent/gateway/relay/auth.py +168 -0
  564. package/agent/gateway/relay/descriptor.py +118 -0
  565. package/agent/gateway/relay/transport.py +101 -0
  566. package/agent/gateway/relay/ws_transport.py +327 -0
  567. package/agent/gateway/response_filters.py +53 -0
  568. package/agent/gateway/rich_sent_store.py +80 -0
  569. package/agent/gateway/run.py +2940 -5001
  570. package/agent/gateway/session.py +109 -8
  571. package/agent/gateway/session_context.py +22 -4
  572. package/agent/gateway/slash_commands.py +3854 -0
  573. package/agent/gateway/status.py +141 -21
  574. package/agent/gateway/stream_consumer.py +288 -31
  575. package/agent/hermes-already-has-routines.md +1 -1
  576. package/agent/hermes_cli/__init__.py +62 -17
  577. package/agent/hermes_cli/_parser.py +30 -0
  578. package/agent/hermes_cli/_subprocess_compat.py +61 -0
  579. package/agent/hermes_cli/active_sessions.py +320 -0
  580. package/agent/hermes_cli/auth.py +707 -59
  581. package/agent/hermes_cli/auth_commands.py +39 -22
  582. package/agent/hermes_cli/backup.py +109 -7
  583. package/agent/hermes_cli/banner.py +88 -0
  584. package/agent/hermes_cli/blueprint_cmd.py +318 -0
  585. package/agent/hermes_cli/cli_agent_setup_mixin.py +684 -0
  586. package/agent/hermes_cli/cli_commands_mixin.py +2293 -0
  587. package/agent/hermes_cli/commands.py +215 -91
  588. package/agent/hermes_cli/config.py +967 -130
  589. package/agent/hermes_cli/container_boot.py +76 -11
  590. package/agent/hermes_cli/cron.py +5 -11
  591. package/agent/hermes_cli/curator.py +21 -0
  592. package/agent/hermes_cli/dashboard_auth/__init__.py +2 -0
  593. package/agent/hermes_cli/dashboard_auth/base.py +62 -0
  594. package/agent/hermes_cli/dashboard_auth/cookies.py +32 -19
  595. package/agent/hermes_cli/dashboard_auth/login_page.py +156 -6
  596. package/agent/hermes_cli/dashboard_auth/middleware.py +28 -4
  597. package/agent/hermes_cli/dashboard_auth/prefix.py +46 -2
  598. package/agent/hermes_cli/dashboard_auth/public_paths.py +6 -0
  599. package/agent/hermes_cli/dashboard_auth/routes.py +158 -2
  600. package/agent/hermes_cli/dashboard_auth/ws_tickets.py +85 -11
  601. package/agent/hermes_cli/dashboard_register.py +427 -0
  602. package/agent/hermes_cli/debug.py +155 -50
  603. package/agent/hermes_cli/doctor.py +255 -14
  604. package/agent/hermes_cli/dump.py +60 -6
  605. package/agent/hermes_cli/env_loader.py +33 -0
  606. package/agent/hermes_cli/gateway.py +755 -103
  607. package/agent/hermes_cli/gateway_enroll.py +250 -0
  608. package/agent/hermes_cli/gateway_windows.py +254 -11
  609. package/agent/hermes_cli/gui_uninstall.py +285 -0
  610. package/agent/hermes_cli/inventory.py +105 -4
  611. package/agent/hermes_cli/kanban.py +58 -71
  612. package/agent/hermes_cli/kanban_db.py +391 -14
  613. package/agent/hermes_cli/kanban_decompose.py +2 -2
  614. package/agent/hermes_cli/kanban_specify.py +3 -1
  615. package/agent/hermes_cli/logs.py +2 -0
  616. package/agent/hermes_cli/main.py +2889 -5287
  617. package/agent/hermes_cli/managed_scope.py +214 -0
  618. package/agent/hermes_cli/managed_uv.py +254 -0
  619. package/agent/hermes_cli/mcp_catalog.py +6 -3
  620. package/agent/hermes_cli/mcp_config.py +145 -21
  621. package/agent/hermes_cli/mcp_security.py +96 -0
  622. package/agent/hermes_cli/mcp_startup.py +32 -3
  623. package/agent/hermes_cli/memory_providers.py +149 -0
  624. package/agent/hermes_cli/memory_setup.py +97 -42
  625. package/agent/hermes_cli/middleware.py +313 -0
  626. package/agent/hermes_cli/model_catalog.py +31 -0
  627. package/agent/hermes_cli/model_cost_guard.py +134 -0
  628. package/agent/hermes_cli/model_normalize.py +2 -1
  629. package/agent/hermes_cli/model_setup_flows.py +2759 -0
  630. package/agent/hermes_cli/model_switch.py +242 -27
  631. package/agent/hermes_cli/models.py +284 -44
  632. package/agent/hermes_cli/nous_account.py +33 -6
  633. package/agent/hermes_cli/nous_billing.py +406 -0
  634. package/agent/hermes_cli/nous_subscription.py +202 -5
  635. package/agent/hermes_cli/platforms.py +1 -0
  636. package/agent/hermes_cli/plugins.py +218 -18
  637. package/agent/hermes_cli/plugins_cmd.py +249 -105
  638. package/agent/hermes_cli/portal_cli.py +56 -16
  639. package/agent/hermes_cli/profile_distribution.py +6 -1
  640. package/agent/hermes_cli/profiles.py +283 -32
  641. package/agent/hermes_cli/provider_catalog.py +170 -0
  642. package/agent/hermes_cli/providers.py +4 -1
  643. package/agent/hermes_cli/pty_bridge.py +53 -4
  644. package/agent/hermes_cli/runtime_provider.py +216 -34
  645. package/agent/hermes_cli/secret_prompt.py +4 -4
  646. package/agent/hermes_cli/secrets_cli.py +24 -0
  647. package/agent/hermes_cli/send_cmd.py +28 -2
  648. package/agent/hermes_cli/service_manager.py +166 -19
  649. package/agent/hermes_cli/session_listing.py +97 -0
  650. package/agent/hermes_cli/setup.py +158 -94
  651. package/agent/hermes_cli/setup_whatsapp_cloud.py +541 -0
  652. package/agent/hermes_cli/skills_config.py +8 -2
  653. package/agent/hermes_cli/skills_hub.py +149 -7
  654. package/agent/hermes_cli/status.py +2 -2
  655. package/agent/hermes_cli/subcommands/__init__.py +18 -0
  656. package/agent/hermes_cli/subcommands/_shared.py +29 -0
  657. package/agent/hermes_cli/subcommands/acp.py +52 -0
  658. package/agent/hermes_cli/subcommands/auth.py +109 -0
  659. package/agent/hermes_cli/subcommands/backup.py +38 -0
  660. package/agent/hermes_cli/subcommands/claw.py +92 -0
  661. package/agent/hermes_cli/subcommands/config.py +49 -0
  662. package/agent/hermes_cli/subcommands/cron.py +163 -0
  663. package/agent/hermes_cli/subcommands/dashboard.py +143 -0
  664. package/agent/hermes_cli/subcommands/debug.py +77 -0
  665. package/agent/hermes_cli/subcommands/doctor.py +35 -0
  666. package/agent/hermes_cli/subcommands/dump.py +28 -0
  667. package/agent/hermes_cli/subcommands/gateway.py +332 -0
  668. package/agent/hermes_cli/subcommands/gui.py +63 -0
  669. package/agent/hermes_cli/subcommands/hooks.py +77 -0
  670. package/agent/hermes_cli/subcommands/import_cmd.py +31 -0
  671. package/agent/hermes_cli/subcommands/insights.py +25 -0
  672. package/agent/hermes_cli/subcommands/login.py +78 -0
  673. package/agent/hermes_cli/subcommands/logout.py +28 -0
  674. package/agent/hermes_cli/subcommands/logs.py +78 -0
  675. package/agent/hermes_cli/subcommands/mcp.py +108 -0
  676. package/agent/hermes_cli/subcommands/memory.py +53 -0
  677. package/agent/hermes_cli/subcommands/model.py +72 -0
  678. package/agent/hermes_cli/subcommands/pairing.py +36 -0
  679. package/agent/hermes_cli/subcommands/plugins.py +94 -0
  680. package/agent/hermes_cli/subcommands/postinstall.py +23 -0
  681. package/agent/hermes_cli/subcommands/profile.py +203 -0
  682. package/agent/hermes_cli/subcommands/prompt_size.py +36 -0
  683. package/agent/hermes_cli/subcommands/security.py +62 -0
  684. package/agent/hermes_cli/subcommands/setup.py +58 -0
  685. package/agent/hermes_cli/subcommands/skills.py +298 -0
  686. package/agent/hermes_cli/subcommands/slack.py +60 -0
  687. package/agent/hermes_cli/subcommands/status.py +28 -0
  688. package/agent/hermes_cli/subcommands/tools.py +95 -0
  689. package/agent/hermes_cli/subcommands/uninstall.py +41 -0
  690. package/agent/hermes_cli/subcommands/update.py +70 -0
  691. package/agent/hermes_cli/subcommands/version.py +18 -0
  692. package/agent/hermes_cli/subcommands/webhook.py +76 -0
  693. package/agent/hermes_cli/subcommands/whatsapp.py +22 -0
  694. package/agent/hermes_cli/suggestions_cmd.py +153 -0
  695. package/agent/hermes_cli/telegram_managed_bot.py +358 -0
  696. package/agent/hermes_cli/tips.py +3 -4
  697. package/agent/hermes_cli/tools_config.py +155 -28
  698. package/agent/hermes_cli/uninstall.py +231 -35
  699. package/agent/hermes_cli/web_server.py +6190 -973
  700. package/agent/hermes_cli/win_pty_bridge.py +179 -0
  701. package/agent/hermes_cli/write_approval_commands.py +209 -0
  702. package/agent/hermes_constants.py +164 -33
  703. package/agent/hermes_logging.py +74 -2
  704. package/agent/hermes_state.py +919 -106
  705. package/agent/hermes_time.py +20 -0
  706. package/agent/locales/af.yaml +23 -0
  707. package/agent/locales/de.yaml +23 -0
  708. package/agent/locales/en.yaml +20 -0
  709. package/agent/locales/es.yaml +23 -0
  710. package/agent/locales/fr.yaml +23 -0
  711. package/agent/locales/ga.yaml +23 -0
  712. package/agent/locales/hu.yaml +23 -0
  713. package/agent/locales/it.yaml +23 -0
  714. package/agent/locales/ja.yaml +23 -0
  715. package/agent/locales/ko.yaml +23 -0
  716. package/agent/locales/pt.yaml +23 -0
  717. package/agent/locales/ru.yaml +23 -0
  718. package/agent/locales/tr.yaml +23 -0
  719. package/agent/locales/uk.yaml +23 -0
  720. package/agent/locales/zh-hant.yaml +23 -0
  721. package/agent/locales/zh.yaml +23 -0
  722. package/agent/model_tools.py +204 -40
  723. package/agent/optional-mcps/clawpump/manifest.yaml +4 -2
  724. package/agent/optional-mcps/clawpump-stdio/manifest.yaml +2 -0
  725. package/agent/optional-mcps/unreal-engine/manifest.yaml +54 -0
  726. package/agent/optional-skills/blockchain/hyperliquid/SKILL.md +2 -2
  727. package/agent/optional-skills/blockchain/hyperliquid/scripts/hyperliquid_client.py +1 -1
  728. package/agent/optional-skills/creative/kanban-video-orchestrator/SKILL.md +1 -1
  729. package/agent/optional-skills/creative/kanban-video-orchestrator/assets/setup.sh.tmpl +4 -3
  730. package/agent/optional-skills/creative/kanban-video-orchestrator/references/kanban-setup.md +6 -4
  731. package/agent/optional-skills/creative/kanban-video-orchestrator/references/tool-matrix.md +2 -2
  732. package/agent/{skills/software-development → optional-skills/devops}/hermes-s6-container-supervision/SKILL.md +2 -0
  733. package/agent/optional-skills/devops/watchers/SKILL.md +1 -1
  734. package/agent/optional-skills/devops/watchers/scripts/watch_github.py +2 -1
  735. package/agent/optional-skills/payments/mpp-agent/SKILL.md +124 -0
  736. package/agent/optional-skills/payments/stripe-link-cli/SKILL.md +184 -0
  737. package/agent/optional-skills/payments/stripe-projects/SKILL.md +120 -0
  738. package/agent/optional-skills/productivity/canvas/SKILL.md +1 -1
  739. package/agent/optional-skills/productivity/canvas/scripts/canvas_api.py +4 -1
  740. package/agent/optional-skills/productivity/shop/SKILL.md +224 -0
  741. package/agent/optional-skills/productivity/shop/references/catalog-mcp.md +236 -0
  742. package/agent/optional-skills/productivity/shop/references/direct-api.md +278 -0
  743. package/agent/optional-skills/productivity/shop/references/legal.md +3 -0
  744. package/agent/optional-skills/productivity/shop/references/safety.md +36 -0
  745. package/agent/optional-skills/productivity/shopify/SKILL.md +1 -1
  746. package/agent/optional-skills/productivity/siyuan/SKILL.md +1 -1
  747. package/agent/optional-skills/productivity/telephony/SKILL.md +4 -4
  748. package/agent/optional-skills/productivity/telephony/scripts/telephony.py +15 -15
  749. package/agent/optional-skills/security/1password/SKILL.md +1 -1
  750. package/agent/{skills/red-teaming → optional-skills/security}/godmode/SKILL.md +3 -4
  751. package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/auto_jailbreak.py +3 -1
  752. package/agent/optional-skills/software-development/rest-graphql-debug/SKILL.md +1 -1
  753. package/agent/{skills → optional-skills}/software-development/subagent-driven-development/SKILL.md +5 -5
  754. package/agent/package-lock.json +4082 -7907
  755. package/agent/package.json +18 -3
  756. package/agent/plugins/browser/firecrawl/provider.py +4 -1
  757. package/agent/plugins/cron/__init__.py +344 -0
  758. package/agent/plugins/cron/chronos/__init__.py +241 -0
  759. package/agent/plugins/cron/chronos/_nas_client.py +123 -0
  760. package/agent/plugins/cron/chronos/plugin.yaml +9 -0
  761. package/agent/plugins/cron/chronos/verify.py +103 -0
  762. package/agent/plugins/dashboard_auth/basic/__init__.py +491 -0
  763. package/agent/plugins/dashboard_auth/basic/plugin.yaml +7 -0
  764. package/agent/plugins/dashboard_auth/nous/__init__.py +12 -14
  765. package/agent/plugins/dashboard_auth/self_hosted/__init__.py +736 -0
  766. package/agent/plugins/dashboard_auth/self_hosted/plugin.yaml +8 -0
  767. package/agent/plugins/disk-cleanup/disk_cleanup.py +100 -20
  768. package/agent/plugins/google_meet/audio_bridge.py +4 -0
  769. package/agent/plugins/google_meet/meet_bot.py +7 -1
  770. package/agent/plugins/hermes-achievements/dashboard/dist/index.js +9 -15
  771. package/agent/plugins/image_gen/fal/__init__.py +35 -6
  772. package/agent/plugins/image_gen/krea/__init__.py +56 -13
  773. package/agent/plugins/image_gen/openai/__init__.py +122 -24
  774. package/agent/plugins/image_gen/openai-codex/__init__.py +28 -2
  775. package/agent/plugins/image_gen/xai/__init__.py +92 -12
  776. package/agent/plugins/kanban/dashboard/dist/index.js +63 -48
  777. package/agent/plugins/kanban/dashboard/plugin_api.py +39 -35
  778. package/agent/plugins/memory/__init__.py +48 -5
  779. package/agent/plugins/memory/byterover/__init__.py +1 -0
  780. package/agent/plugins/memory/hindsight/README.md +1 -1
  781. package/agent/plugins/memory/hindsight/__init__.py +138 -24
  782. package/agent/plugins/memory/hindsight/plugin.yaml +1 -1
  783. package/agent/plugins/memory/honcho/README.md +13 -10
  784. package/agent/plugins/memory/honcho/cli.py +247 -122
  785. package/agent/plugins/memory/honcho/client.py +112 -102
  786. package/agent/plugins/memory/openviking/README.md +12 -1
  787. package/agent/plugins/memory/openviking/__init__.py +2281 -107
  788. package/agent/plugins/memory/openviking/plugin.yaml +1 -2
  789. package/agent/plugins/memory/supermemory/README.md +22 -10
  790. package/agent/plugins/memory/supermemory/__init__.py +142 -37
  791. package/agent/plugins/memory/supermemory/plugin.yaml +1 -1
  792. package/agent/plugins/model-providers/anthropic/__init__.py +1 -0
  793. package/agent/plugins/model-providers/bedrock/__init__.py +1 -0
  794. package/agent/plugins/model-providers/copilot-acp/__init__.py +1 -0
  795. package/agent/plugins/model-providers/custom/__init__.py +8 -2
  796. package/agent/plugins/model-providers/kimi-coding/__init__.py +16 -7
  797. package/agent/plugins/model-providers/minimax/__init__.py +60 -8
  798. package/agent/plugins/model-providers/opencode-zen/__init__.py +12 -3
  799. package/agent/plugins/model-providers/openrouter/__init__.py +75 -4
  800. package/agent/plugins/model-providers/xiaomi/__init__.py +2 -0
  801. package/agent/plugins/model-providers/zai/__init__.py +1 -0
  802. package/agent/plugins/observability/langfuse/__init__.py +147 -14
  803. package/agent/plugins/observability/nemo_relay/README.md +559 -0
  804. package/agent/plugins/observability/nemo_relay/__init__.py +962 -0
  805. package/agent/plugins/observability/nemo_relay/plugin.yaml +20 -0
  806. package/agent/plugins/platforms/discord/adapter.py +932 -61
  807. package/agent/plugins/platforms/discord/voice_mixer.py +379 -0
  808. package/agent/plugins/platforms/google_chat/adapter.py +9 -3
  809. package/agent/plugins/platforms/google_chat/oauth.py +1 -1
  810. package/agent/plugins/platforms/homeassistant/__init__.py +3 -0
  811. package/agent/{gateway/platforms/homeassistant.py → plugins/platforms/homeassistant/adapter.py} +128 -0
  812. package/agent/plugins/platforms/homeassistant/plugin.yaml +22 -0
  813. package/agent/plugins/platforms/irc/adapter.py +4 -1
  814. package/agent/plugins/platforms/line/adapter.py +16 -1
  815. package/agent/plugins/platforms/mattermost/adapter.py +100 -24
  816. package/agent/plugins/platforms/photon/README.md +179 -0
  817. package/agent/plugins/platforms/photon/__init__.py +4 -0
  818. package/agent/plugins/platforms/photon/adapter.py +1586 -0
  819. package/agent/plugins/platforms/photon/auth.py +1046 -0
  820. package/agent/plugins/platforms/photon/cli.py +439 -0
  821. package/agent/plugins/platforms/photon/plugin.yaml +88 -0
  822. package/agent/plugins/platforms/photon/sidecar/README.md +52 -0
  823. package/agent/plugins/platforms/photon/sidecar/index.mjs +720 -0
  824. package/agent/plugins/platforms/photon/sidecar/package-lock.json +1730 -0
  825. package/agent/plugins/platforms/photon/sidecar/package.json +25 -0
  826. package/agent/plugins/platforms/photon/sidecar/patch-spectrum-mixed-attachments.mjs +155 -0
  827. package/agent/plugins/platforms/raft/__init__.py +3 -0
  828. package/agent/plugins/platforms/raft/adapter.py +774 -0
  829. package/agent/plugins/platforms/raft/plugin.yaml +19 -0
  830. package/agent/plugins/platforms/simplex/adapter.py +777 -220
  831. package/agent/plugins/platforms/simplex/plugin.yaml +21 -2
  832. package/agent/plugins/platforms/teams/adapter.py +175 -5
  833. package/agent/plugins/plugin_utils.py +135 -0
  834. package/agent/plugins/video_gen/fal/__init__.py +10 -3
  835. package/agent/plugins/web/searxng/provider.py +15 -2
  836. package/agent/plugins/web/xai/provider.py +2 -2
  837. package/agent/providers/base.py +22 -3
  838. package/agent/pyproject.toml +115 -21
  839. package/agent/run_agent.py +733 -39
  840. package/agent/scripts/build_skills_index.py +51 -19
  841. package/agent/scripts/check_subprocess_stdin.py +177 -0
  842. package/agent/scripts/contributor_audit.py +2 -0
  843. package/agent/scripts/docker_config_migrate.py +67 -0
  844. package/agent/scripts/install.cmd +3 -3
  845. package/agent/scripts/install.ps1 +580 -154
  846. package/agent/scripts/install.sh +402 -185
  847. package/agent/scripts/lib/node-bootstrap.sh +39 -4
  848. package/agent/scripts/release.py +183 -0
  849. package/agent/scripts/run_tests.sh +1 -0
  850. package/agent/scripts/run_tests_parallel.py +18 -23
  851. package/agent/scripts/whatsapp-bridge/bridge.js +25 -4
  852. package/agent/setup.py +59 -0
  853. package/agent/skills/autonomous-ai-agents/codex/SKILL.md +19 -0
  854. package/agent/skills/autonomous-ai-agents/hermes-agent/SKILL.md +10 -3
  855. package/agent/skills/{mcp/native-mcp/SKILL.md → autonomous-ai-agents/hermes-agent/references/native-mcp.md} +0 -13
  856. package/agent/skills/{devops/webhook-subscriptions/SKILL.md → autonomous-ai-agents/hermes-agent/references/webhooks.md} +1 -11
  857. package/agent/skills/clawpump/SKILL.md +4 -1
  858. package/agent/skills/devops/kanban-orchestrator/SKILL.md +1 -0
  859. package/agent/skills/devops/kanban-worker/SKILL.md +1 -0
  860. package/agent/skills/github/github-auth/SKILL.md +2 -2
  861. package/agent/skills/github/github-auth/scripts/gh-env.sh +2 -2
  862. package/agent/skills/github/github-code-review/SKILL.md +2 -2
  863. package/agent/skills/github/github-issues/SKILL.md +2 -2
  864. package/agent/skills/github/github-pr-workflow/SKILL.md +2 -2
  865. package/agent/skills/github/github-repo-management/SKILL.md +2 -2
  866. package/agent/skills/media/gif-search/SKILL.md +1 -1
  867. package/agent/skills/media/youtube-content/SKILL.md +10 -7
  868. package/agent/skills/media/youtube-content/scripts/fetch_transcript.py +3 -3
  869. package/agent/skills/note-taking/obsidian/SKILL.md +1 -1
  870. package/agent/skills/productivity/airtable/SKILL.md +2 -2
  871. package/agent/skills/productivity/google-workspace/scripts/setup.py +33 -7
  872. package/agent/skills/productivity/notion/SKILL.md +2 -2
  873. package/agent/skills/productivity/teams-meeting-pipeline/SKILL.md +1 -1
  874. package/agent/skills/research/llm-wiki/SKILL.md +1 -1
  875. package/agent/skills/social-media/xurl/SKILL.md +9 -0
  876. package/agent/skills/software-development/hermes-agent-skill-authoring/SKILL.md +1 -1
  877. package/agent/skills/software-development/plan/SKILL.md +285 -5
  878. package/agent/skills/software-development/requesting-code-review/SKILL.md +2 -2
  879. package/agent/skills/software-development/simplify-code/SKILL.md +212 -0
  880. package/agent/skills/software-development/spike/SKILL.md +2 -2
  881. package/agent/skills/software-development/systematic-debugging/SKILL.md +1 -1
  882. package/agent/skills/software-development/test-driven-development/SKILL.md +1 -1
  883. package/agent/tools/approval.py +302 -4
  884. package/agent/tools/async_delegation.py +386 -0
  885. package/agent/tools/blueprints.py +325 -0
  886. package/agent/tools/browser_cdp_tool.py +3 -3
  887. package/agent/tools/browser_tool.py +34 -6
  888. package/agent/tools/checkpoint_manager.py +31 -1
  889. package/agent/tools/clarify_tool.py +55 -5
  890. package/agent/tools/code_execution_tool.py +31 -14
  891. package/agent/tools/computer_use/cua_backend.py +81 -3
  892. package/agent/tools/computer_use/tool.py +79 -5
  893. package/agent/tools/computer_use/vision_routing.py +55 -3
  894. package/agent/tools/credential_files.py +31 -12
  895. package/agent/tools/cronjob_tools.py +30 -20
  896. package/agent/tools/delegate_tool.py +356 -31
  897. package/agent/tools/env_probe.py +1 -0
  898. package/agent/tools/environments/docker.py +163 -8
  899. package/agent/tools/environments/file_sync.py +2 -1
  900. package/agent/tools/environments/local.py +74 -23
  901. package/agent/tools/environments/singularity.py +4 -1
  902. package/agent/tools/environments/ssh.py +78 -11
  903. package/agent/tools/file_operations.py +277 -41
  904. package/agent/tools/file_tools.py +166 -28
  905. package/agent/tools/image_generation_tool.py +515 -29
  906. package/agent/tools/kanban_tools.py +99 -0
  907. package/agent/tools/lazy_deps.py +33 -2
  908. package/agent/tools/mcp_oauth.py +5 -5
  909. package/agent/tools/mcp_oauth_manager.py +7 -5
  910. package/agent/tools/mcp_tool.py +840 -33
  911. package/agent/tools/memory_tool.py +335 -38
  912. package/agent/tools/osv_check.py +15 -1
  913. package/agent/tools/process_registry.py +155 -11
  914. package/agent/tools/read_extract.py +248 -0
  915. package/agent/tools/read_terminal_tool.py +93 -0
  916. package/agent/tools/schema_sanitizer.py +38 -0
  917. package/agent/tools/send_message_tool.py +163 -49
  918. package/agent/tools/session_search_tool.py +189 -7
  919. package/agent/tools/skill_manager_tool.py +202 -3
  920. package/agent/tools/skill_usage.py +52 -4
  921. package/agent/tools/skills_hub.py +184 -44
  922. package/agent/tools/skills_sync.py +232 -5
  923. package/agent/tools/skills_tool.py +125 -11
  924. package/agent/tools/terminal_tool.py +148 -26
  925. package/agent/tools/tirith_security.py +2 -0
  926. package/agent/tools/todo_tool.py +32 -1
  927. package/agent/tools/transcription_tools.py +13 -5
  928. package/agent/tools/tts_tool.py +332 -38
  929. package/agent/tools/url_safety.py +52 -1
  930. package/agent/tools/vision_tools.py +124 -39
  931. package/agent/tools/voice_mode.py +4 -3
  932. package/agent/tools/web_tools.py +45 -15
  933. package/agent/tools/write_approval.py +493 -0
  934. package/agent/toolsets.py +34 -10
  935. package/agent/trajectory_compressor.py +81 -10
  936. package/agent/tui_gateway/entry.py +43 -6
  937. package/agent/tui_gateway/server.py +3335 -330
  938. package/agent/tui_gateway/slash_worker.py +61 -0
  939. package/agent/tui_gateway/ws.py +67 -9
  940. package/agent/ui-tui/eslint.config.mjs +0 -4
  941. package/agent/ui-tui/package.json +6 -6
  942. package/agent/ui-tui/packages/hermes-ink/package.json +1 -1
  943. package/agent/ui-tui/packages/hermes-ink/src/ink/app-mouse.test.ts +34 -1
  944. package/agent/ui-tui/packages/hermes-ink/src/ink/app-rawmode-mouse.test.ts +91 -0
  945. package/agent/ui-tui/packages/hermes-ink/src/ink/components/App.tsx +35 -2
  946. package/agent/ui-tui/packages/hermes-ink/src/ink/events/input-event.ts +4 -11
  947. package/agent/ui-tui/packages/hermes-ink/src/ink/parse-keypress.test.ts +23 -57
  948. package/agent/ui-tui/packages/hermes-ink/src/ink/parse-keypress.ts +11 -135
  949. package/agent/ui-tui/packages/hermes-ink/src/ink/termio/tokenize.test.ts +185 -0
  950. package/agent/ui-tui/packages/hermes-ink/src/ink/termio/tokenize.ts +37 -3
  951. package/agent/ui-tui/packages/hermes-ink/src/utils/execFileNoThrow.ts +5 -5
  952. package/agent/ui-tui/src/__tests__/appChromeStatusRule.test.tsx +217 -0
  953. package/agent/ui-tui/src/__tests__/appChromeStatusRuleDevCredits.test.tsx +73 -0
  954. package/agent/ui-tui/src/__tests__/approvalAction.test.ts +11 -0
  955. package/agent/ui-tui/src/__tests__/billingCommand.test.ts +301 -0
  956. package/agent/ui-tui/src/__tests__/blockLayout.test.ts +122 -0
  957. package/agent/ui-tui/src/__tests__/brandingMcpCount.test.ts +111 -0
  958. package/agent/ui-tui/src/__tests__/completionApply.test.ts +51 -0
  959. package/agent/ui-tui/src/__tests__/createGatewayEventHandler.test.ts +487 -2
  960. package/agent/ui-tui/src/__tests__/createSlashHandler.test.ts +54 -0
  961. package/agent/ui-tui/src/__tests__/creditsCommand.test.ts +144 -0
  962. package/agent/ui-tui/src/__tests__/gatewayClient.test.ts +120 -99
  963. package/agent/ui-tui/src/__tests__/gracefulExit.test.ts +11 -0
  964. package/agent/ui-tui/src/__tests__/memoryMonitor.test.ts +102 -0
  965. package/agent/ui-tui/src/__tests__/paths.test.ts +41 -1
  966. package/agent/ui-tui/src/__tests__/terminalModes.test.ts +22 -0
  967. package/agent/ui-tui/src/__tests__/text.test.ts +23 -0
  968. package/agent/ui-tui/src/__tests__/textInputFastEcho.test.ts +37 -0
  969. package/agent/ui-tui/src/__tests__/turnControllerNotice.test.ts +43 -0
  970. package/agent/ui-tui/src/__tests__/useInputHandlers.test.ts +38 -1
  971. package/agent/ui-tui/src/__tests__/virtualHeights.test.ts +8 -0
  972. package/agent/ui-tui/src/app/createGatewayEventHandler.ts +102 -7
  973. package/agent/ui-tui/src/app/interfaces.ts +64 -1
  974. package/agent/ui-tui/src/app/overlayStore.ts +18 -2
  975. package/agent/ui-tui/src/app/slash/commands/billing.ts +332 -0
  976. package/agent/ui-tui/src/app/slash/commands/core.ts +31 -2
  977. package/agent/ui-tui/src/app/slash/commands/credits.ts +57 -0
  978. package/agent/ui-tui/src/app/slash/commands/ops.ts +28 -0
  979. package/agent/ui-tui/src/app/slash/commands/session.ts +32 -4
  980. package/agent/ui-tui/src/app/slash/registry.ts +4 -0
  981. package/agent/ui-tui/src/app/turnController.ts +145 -2
  982. package/agent/ui-tui/src/app/uiStore.ts +2 -0
  983. package/agent/ui-tui/src/app/useInputHandlers.ts +42 -4
  984. package/agent/ui-tui/src/app/useMainApp.ts +54 -8
  985. package/agent/ui-tui/src/app/useSessionLifecycle.ts +40 -31
  986. package/agent/ui-tui/src/app/useSubmission.ts +23 -31
  987. package/agent/ui-tui/src/components/appChrome.tsx +112 -5
  988. package/agent/ui-tui/src/components/appLayout.tsx +9 -0
  989. package/agent/ui-tui/src/components/appOverlays.tsx +25 -1
  990. package/agent/ui-tui/src/components/billingOverlay.tsx +684 -0
  991. package/agent/ui-tui/src/components/branding.tsx +15 -3
  992. package/agent/ui-tui/src/components/messageLine.tsx +25 -3
  993. package/agent/ui-tui/src/components/pluginsHub.tsx +238 -0
  994. package/agent/ui-tui/src/components/prompts.tsx +31 -17
  995. package/agent/ui-tui/src/components/streamingAssistant.tsx +63 -55
  996. package/agent/ui-tui/src/components/textInput.tsx +16 -0
  997. package/agent/ui-tui/src/config/env.ts +12 -0
  998. package/agent/ui-tui/src/config/limits.ts +13 -0
  999. package/agent/ui-tui/src/domain/blockLayout.ts +146 -0
  1000. package/agent/ui-tui/src/domain/paths.ts +24 -0
  1001. package/agent/ui-tui/src/domain/slash.ts +40 -0
  1002. package/agent/ui-tui/src/entry.tsx +35 -4
  1003. package/agent/ui-tui/src/gatewayClient.ts +22 -10
  1004. package/agent/ui-tui/src/gatewayTypes.ts +130 -1
  1005. package/agent/ui-tui/src/lib/gracefulExit.ts +24 -4
  1006. package/agent/ui-tui/src/lib/memory.test.ts +162 -0
  1007. package/agent/ui-tui/src/lib/memory.ts +60 -1
  1008. package/agent/ui-tui/src/lib/memoryMonitor.ts +79 -4
  1009. package/agent/ui-tui/src/lib/osc52.ts +1 -1
  1010. package/agent/ui-tui/src/lib/text.test.ts +32 -1
  1011. package/agent/ui-tui/src/lib/text.ts +29 -2
  1012. package/agent/ui-tui/src/lib/virtualHeights.ts +13 -0
  1013. package/agent/ui-tui/src/types.ts +5 -0
  1014. package/agent/ui-tui/tsconfig.build.json +0 -1
  1015. package/agent/ui-tui/tsconfig.json +2 -1
  1016. package/agent/utils.py +66 -2
  1017. package/agent/uv.lock +300 -684
  1018. package/agent/web/index.html +2 -2
  1019. package/agent/web/package.json +11 -6
  1020. package/agent/web/public/claw-bg.webp +0 -0
  1021. package/agent/web/public/claw-logo.webp +0 -0
  1022. package/agent/web/src/App.tsx +138 -48
  1023. package/agent/web/src/components/AutomationBlueprints.tsx +225 -0
  1024. package/agent/web/src/components/Backdrop.tsx +15 -0
  1025. package/agent/web/src/components/ChatSessionList.tsx +260 -0
  1026. package/agent/web/src/components/ChatSidebar.tsx +262 -78
  1027. package/agent/web/src/components/ConfirmDialog.tsx +122 -0
  1028. package/agent/web/src/components/ModelPickerDialog.tsx +111 -16
  1029. package/agent/web/src/components/ModelReloadConfirm.tsx +40 -0
  1030. package/agent/web/src/components/ProfileScopeBanner.tsx +30 -0
  1031. package/agent/web/src/components/ProfileSwitcher.tsx +67 -0
  1032. package/agent/web/src/components/ReasoningPicker.tsx +167 -0
  1033. package/agent/web/src/components/SkillEditorDialog.tsx +215 -0
  1034. package/agent/web/src/components/ThemeSwitcher.tsx +119 -4
  1035. package/agent/web/src/components/ToolsetConfigDrawer.tsx +457 -0
  1036. package/agent/web/src/contexts/PageHeaderProvider.tsx +7 -4
  1037. package/agent/web/src/contexts/ProfileProvider.tsx +137 -0
  1038. package/agent/web/src/contexts/SystemActions.tsx +6 -8
  1039. package/agent/web/src/contexts/profile-context.ts +19 -0
  1040. package/agent/web/src/contexts/useProfileScope.ts +6 -0
  1041. package/agent/web/src/i18n/af.ts +5 -4
  1042. package/agent/web/src/i18n/de.ts +5 -4
  1043. package/agent/web/src/i18n/en.ts +58 -4
  1044. package/agent/web/src/i18n/es.ts +5 -3
  1045. package/agent/web/src/i18n/fr.ts +5 -3
  1046. package/agent/web/src/i18n/ga.ts +5 -4
  1047. package/agent/web/src/i18n/hu.ts +5 -4
  1048. package/agent/web/src/i18n/it.ts +5 -4
  1049. package/agent/web/src/i18n/ja.ts +5 -4
  1050. package/agent/web/src/i18n/ko.ts +5 -4
  1051. package/agent/web/src/i18n/pt.ts +5 -3
  1052. package/agent/web/src/i18n/ru.ts +5 -4
  1053. package/agent/web/src/i18n/tr.ts +5 -4
  1054. package/agent/web/src/i18n/types.ts +59 -1
  1055. package/agent/web/src/i18n/uk.ts +5 -3
  1056. package/agent/web/src/i18n/zh-hant.ts +5 -4
  1057. package/agent/web/src/i18n/zh.ts +5 -4
  1058. package/agent/web/src/index.css +2 -2
  1059. package/agent/web/src/lib/api.ts +819 -52
  1060. package/agent/web/src/lib/dashboard-flags.ts +16 -7
  1061. package/agent/web/src/lib/reasoning-effort.test.ts +48 -0
  1062. package/agent/web/src/lib/reasoning-effort.ts +36 -0
  1063. package/agent/web/src/lib/session-refresh.test.ts +21 -0
  1064. package/agent/web/src/lib/session-refresh.ts +26 -0
  1065. package/agent/web/src/pages/ChannelsPage.tsx +529 -68
  1066. package/agent/web/src/pages/ChatPage.tsx +249 -56
  1067. package/agent/web/src/pages/ConfigPage.tsx +11 -1
  1068. package/agent/web/src/pages/CronPage.tsx +219 -31
  1069. package/agent/web/src/pages/EnvPage.tsx +25 -6
  1070. package/agent/web/src/pages/FilesPage.tsx +525 -0
  1071. package/agent/web/src/pages/McpPage.tsx +80 -3
  1072. package/agent/web/src/pages/ModelsPage.tsx +97 -12
  1073. package/agent/web/src/pages/PluginsPage.tsx +1 -1
  1074. package/agent/web/src/pages/ProfileBuilderPage.tsx +611 -0
  1075. package/agent/web/src/pages/ProfilesPage.tsx +1038 -172
  1076. package/agent/web/src/pages/SessionsPage.tsx +144 -13
  1077. package/agent/web/src/pages/SkillsPage.tsx +851 -70
  1078. package/agent/web/src/pages/SystemPage.tsx +340 -4
  1079. package/agent/web/src/pages/WalletPage.tsx +401 -0
  1080. package/agent/web/src/pages/WebhooksPage.tsx +145 -15
  1081. package/agent/web/src/pages/X402Page.tsx +207 -0
  1082. package/agent/web/src/plugins/registry.ts +28 -11
  1083. package/agent/web/src/plugins/sdk.d.ts +160 -0
  1084. package/agent/web/src/themes/context.tsx +112 -5
  1085. package/agent/web/src/themes/fonts.ts +167 -0
  1086. package/agent/web/src/themes/index.ts +7 -0
  1087. package/agent/web/tsconfig.app.json +0 -1
  1088. package/agent/web/vite.config.ts +1 -8
  1089. package/agent/web/vitest.config.ts +16 -0
  1090. package/package.json +1 -1
  1091. package/agent/apps/desktop/package-lock.json +0 -18363
  1092. package/agent/apps/desktop/src/app/chat/composer/skin-slash-popover.tsx +0 -56
  1093. package/agent/apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx +0 -382
  1094. package/agent/apps/desktop/src/components/assistant-ui/todo-tool.tsx +0 -109
  1095. package/agent/apps/desktop/src/components/chat/generated-image-context.tsx +0 -19
  1096. package/agent/optional-skills/productivity/shop-app/SKILL.md +0 -340
  1097. package/agent/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md +0 -277
  1098. package/agent/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md +0 -57
  1099. package/agent/skills/diagramming/DESCRIPTION.md +0 -3
  1100. package/agent/skills/domain/DESCRIPTION.md +0 -24
  1101. package/agent/skills/gifs/DESCRIPTION.md +0 -3
  1102. package/agent/skills/inference-sh/DESCRIPTION.md +0 -19
  1103. package/agent/skills/mcp/DESCRIPTION.md +0 -3
  1104. package/agent/skills/media/spotify/SKILL.md +0 -135
  1105. package/agent/skills/mlops/training/DESCRIPTION.md +0 -3
  1106. package/agent/skills/mlops/vector-databases/DESCRIPTION.md +0 -3
  1107. package/agent/skills/productivity/linear/SKILL.md +0 -380
  1108. package/agent/skills/productivity/linear/scripts/linear_api.py +0 -445
  1109. package/agent/skills/software-development/debugging-hermes-tui-commands/SKILL.md +0 -152
  1110. package/agent/skills/software-development/writing-plans/SKILL.md +0 -297
  1111. package/agent/ui-tui/package-lock.json +0 -7449
  1112. package/agent/ui-tui/packages/hermes-ink/package-lock.json +0 -1289
  1113. package/agent/web/package-lock.json +0 -8887
  1114. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/PORT_NOTES.md +0 -0
  1115. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/SKILL.md +0 -0
  1116. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/prompts/system.md +0 -0
  1117. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/macaron.md +0 -0
  1118. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/mono-ink.md +0 -0
  1119. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/neon.md +0 -0
  1120. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/warm.md +0 -0
  1121. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/prompt-construction.md +0 -0
  1122. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/style-presets.md +0 -0
  1123. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/blueprint.md +0 -0
  1124. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/chalkboard.md +0 -0
  1125. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/editorial.md +0 -0
  1126. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/elegant.md +0 -0
  1127. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/fantasy-animation.md +0 -0
  1128. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/flat-doodle.md +0 -0
  1129. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/flat.md +0 -0
  1130. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/ink-notes.md +0 -0
  1131. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/intuition-machine.md +0 -0
  1132. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/minimal.md +0 -0
  1133. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/nature.md +0 -0
  1134. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/notion.md +0 -0
  1135. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/pixel-art.md +0 -0
  1136. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/playful.md +0 -0
  1137. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/retro.md +0 -0
  1138. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/scientific.md +0 -0
  1139. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/screen-print.md +0 -0
  1140. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/sketch-notes.md +0 -0
  1141. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/sketch.md +0 -0
  1142. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/vector-illustration.md +0 -0
  1143. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/vintage.md +0 -0
  1144. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/warm.md +0 -0
  1145. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/watercolor.md +0 -0
  1146. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles.md +0 -0
  1147. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/usage.md +0 -0
  1148. /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/workflow.md +0 -0
  1149. /package/agent/{skills → optional-skills}/creative/baoyu-comic/PORT_NOTES.md +0 -0
  1150. /package/agent/{skills → optional-skills}/creative/baoyu-comic/SKILL.md +0 -0
  1151. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/analysis-framework.md +0 -0
  1152. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/chalk.md +0 -0
  1153. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/ink-brush.md +0 -0
  1154. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/ligne-claire.md +0 -0
  1155. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/manga.md +0 -0
  1156. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/minimalist.md +0 -0
  1157. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/realistic.md +0 -0
  1158. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/auto-selection.md +0 -0
  1159. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/base-prompt.md +0 -0
  1160. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/character-template.md +0 -0
  1161. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/cinematic.md +0 -0
  1162. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/dense.md +0 -0
  1163. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/four-panel.md +0 -0
  1164. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/mixed.md +0 -0
  1165. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/splash.md +0 -0
  1166. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/standard.md +0 -0
  1167. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/webtoon.md +0 -0
  1168. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/ohmsha-guide.md +0 -0
  1169. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/partial-workflows.md +0 -0
  1170. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/concept-story.md +0 -0
  1171. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/four-panel.md +0 -0
  1172. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/ohmsha.md +0 -0
  1173. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/shoujo.md +0 -0
  1174. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/wuxia.md +0 -0
  1175. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/storyboard-template.md +0 -0
  1176. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/action.md +0 -0
  1177. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/dramatic.md +0 -0
  1178. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/energetic.md +0 -0
  1179. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/neutral.md +0 -0
  1180. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/romantic.md +0 -0
  1181. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/vintage.md +0 -0
  1182. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/warm.md +0 -0
  1183. /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/workflow.md +0 -0
  1184. /package/agent/{skills → optional-skills}/creative/creative-ideation/SKILL.md +0 -0
  1185. /package/agent/{skills → optional-skills}/creative/creative-ideation/references/full-prompt-library.md +0 -0
  1186. /package/agent/{skills → optional-skills}/creative/pixel-art/ATTRIBUTION.md +0 -0
  1187. /package/agent/{skills → optional-skills}/creative/pixel-art/SKILL.md +0 -0
  1188. /package/agent/{skills → optional-skills}/creative/pixel-art/references/palettes.md +0 -0
  1189. /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/__init__.py +0 -0
  1190. /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/palettes.py +0 -0
  1191. /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/pixel_art.py +0 -0
  1192. /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/pixel_art_video.py +0 -0
  1193. /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/SKILL.md +0 -0
  1194. /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/references/analysis-modules.md +0 -0
  1195. /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/references/methods-guide.md +0 -0
  1196. /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/abliteration-config.yaml +0 -0
  1197. /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/analysis-study.yaml +0 -0
  1198. /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/batch-abliteration.yaml +0 -0
  1199. /package/agent/{skills → optional-skills}/mlops/research/DESCRIPTION.md +0 -0
  1200. /package/agent/{skills → optional-skills}/mlops/research/dspy/SKILL.md +0 -0
  1201. /package/agent/{skills → optional-skills}/mlops/research/dspy/references/examples.md +0 -0
  1202. /package/agent/{skills → optional-skills}/mlops/research/dspy/references/modules.md +0 -0
  1203. /package/agent/{skills → optional-skills}/mlops/research/dspy/references/optimizers.md +0 -0
  1204. /package/agent/{skills/red-teaming → optional-skills/security}/godmode/references/jailbreak-templates.md +0 -0
  1205. /package/agent/{skills/red-teaming → optional-skills/security}/godmode/references/refusal-detection.md +0 -0
  1206. /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/godmode_race.py +0 -0
  1207. /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/load_godmode.py +0 -0
  1208. /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/parseltongue.py +0 -0
  1209. /package/agent/{skills/red-teaming → optional-skills/security}/godmode/templates/prefill-subtle.json +0 -0
  1210. /package/agent/{skills/red-teaming → optional-skills/security}/godmode/templates/prefill.json +0 -0
  1211. /package/agent/{skills → optional-skills}/software-development/subagent-driven-development/references/context-budget-discipline.md +0 -0
  1212. /package/agent/{skills → optional-skills}/software-development/subagent-driven-development/references/gates-taxonomy.md +0 -0
@@ -0,0 +1,257 @@
1
+ """Suggested cron jobs — proposed automations the user accepts with one tap.
2
+
3
+ A *suggestion* is a ready-to-run cron job spec that Hermes surfaces to the
4
+ user, who accepts it (creates the real cron job) or dismisses it (latched so
5
+ it is never re-offered). This is the single surface every automation proposal
6
+ flows through, regardless of where it came from:
7
+
8
+ * ``catalog`` — a curated starter automation (daily briefing, important-mail
9
+ monitor, weekly digest, ...).
10
+ * ``blueprint`` — the user installed a skill that carries a ``blueprint:`` block
11
+ (see ``tools/blueprints.py``); installing it registers a
12
+ suggestion instead of auto-scheduling.
13
+ * ``usage`` — the background self-improvement review noticed a recurring
14
+ ask that a scheduled job would serve.
15
+ * ``integration`` — the user connected an account (Gmail, GitHub, ...) and
16
+ the obvious automations for that surface are offered.
17
+
18
+ Accepting a suggestion just calls the existing ``cron.jobs.create_job`` with
19
+ the stored ``job_spec`` — there is NO second job engine. Suggestions never
20
+ auto-create jobs; acceptance is always explicit (consent-first). Dismissed
21
+ suggestions latch by a stable ``dedup_key`` so the same proposal is not
22
+ re-offered after the user says no.
23
+
24
+ Storage mirrors ``cron/jobs.py``: ``~/.hermes/cron/suggestions.json``, atomic
25
+ writes, an in-process lock, and 0600 perms.
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ import json
31
+ import logging
32
+ import os
33
+ import tempfile
34
+ import threading
35
+ import uuid
36
+ from pathlib import Path
37
+ from typing import Any, Dict, List, Optional
38
+
39
+ from hermes_constants import get_hermes_home
40
+ from hermes_time import now as _hermes_now
41
+ from utils import atomic_replace
42
+
43
+ logger = logging.getLogger(__name__)
44
+
45
+ CRON_DIR = get_hermes_home().resolve() / "cron"
46
+ SUGGESTIONS_FILE = CRON_DIR / "suggestions.json"
47
+
48
+ # In-process lock protecting load->modify->save cycles (the background review
49
+ # fork and the main agent can both write).
50
+ _suggestions_lock = threading.Lock()
51
+
52
+ # Cap pending suggestions so the list never becomes a nag wall. When full,
53
+ # new suggestions are dropped (the user should clear the backlog first).
54
+ MAX_PENDING = 5
55
+
56
+ VALID_SOURCES = frozenset({"catalog", "blueprint", "usage", "integration"})
57
+ _STATUS_PENDING = "pending"
58
+ _STATUS_ACCEPTED = "accepted"
59
+ _STATUS_DISMISSED = "dismissed"
60
+
61
+
62
+ def _secure_file(path: Path) -> None:
63
+ try:
64
+ os.chmod(path, 0o600)
65
+ except OSError:
66
+ pass
67
+
68
+
69
+ def _ensure_dir() -> None:
70
+ CRON_DIR.mkdir(parents=True, exist_ok=True)
71
+
72
+
73
+ def _load_raw() -> Dict[str, Any]:
74
+ if not SUGGESTIONS_FILE.exists():
75
+ return {"suggestions": []}
76
+ try:
77
+ with open(SUGGESTIONS_FILE, "r", encoding="utf-8") as f:
78
+ data = json.load(f)
79
+ except (json.JSONDecodeError, OSError) as e:
80
+ logger.warning("suggestions.json unreadable (%s); starting empty", e)
81
+ return {"suggestions": []}
82
+ if isinstance(data, dict) and isinstance(data.get("suggestions"), list):
83
+ return data
84
+ if isinstance(data, list):
85
+ return {"suggestions": data}
86
+ logger.warning("suggestions.json malformed; starting empty")
87
+ return {"suggestions": []}
88
+
89
+
90
+ def _save_raw(suggestions: List[Dict[str, Any]]) -> None:
91
+ _ensure_dir()
92
+ fd, tmp_path = tempfile.mkstemp(dir=str(SUGGESTIONS_FILE.parent), suffix=".tmp", prefix=".sugg_")
93
+ try:
94
+ with os.fdopen(fd, "w", encoding="utf-8") as f:
95
+ json.dump(
96
+ {"suggestions": suggestions, "updated_at": _hermes_now().isoformat()},
97
+ f,
98
+ indent=2,
99
+ )
100
+ f.flush()
101
+ os.fsync(f.fileno())
102
+ atomic_replace(tmp_path, SUGGESTIONS_FILE)
103
+ _secure_file(SUGGESTIONS_FILE)
104
+ except BaseException:
105
+ try:
106
+ os.unlink(tmp_path)
107
+ except OSError:
108
+ pass
109
+ raise
110
+
111
+
112
+ def load_suggestions() -> List[Dict[str, Any]]:
113
+ """Return all suggestion records (any status)."""
114
+ return _load_raw().get("suggestions", [])
115
+
116
+
117
+ def list_pending() -> List[Dict[str, Any]]:
118
+ """Return pending suggestions in creation order (oldest first)."""
119
+ return [s for s in load_suggestions() if s.get("status") == _STATUS_PENDING]
120
+
121
+
122
+ def add_suggestion(
123
+ *,
124
+ title: str,
125
+ description: str,
126
+ source: str,
127
+ job_spec: Dict[str, Any],
128
+ dedup_key: str,
129
+ ) -> Optional[Dict[str, Any]]:
130
+ """Register a pending suggestion. Returns the record, or None if skipped.
131
+
132
+ Skipped when: the source is unknown, the same ``dedup_key`` was already
133
+ dismissed or accepted (never re-offer), an identical pending suggestion
134
+ exists, or the pending list is full (``MAX_PENDING``).
135
+
136
+ ``job_spec`` is a dict of kwargs for ``cron.jobs.create_job`` — accepting
137
+ the suggestion passes it straight through, so there is no second schema to
138
+ keep in sync.
139
+ """
140
+ if source not in VALID_SOURCES:
141
+ raise ValueError(f"unknown suggestion source: {source!r}")
142
+ if not title.strip() or not dedup_key.strip():
143
+ raise ValueError("title and dedup_key are required")
144
+
145
+ with _suggestions_lock:
146
+ suggestions = _load_raw().get("suggestions", [])
147
+
148
+ # Never re-offer something the user already saw and decided on, and
149
+ # never duplicate a still-pending proposal.
150
+ for existing in suggestions:
151
+ if existing.get("dedup_key") == dedup_key:
152
+ if existing.get("status") in (_STATUS_DISMISSED, _STATUS_ACCEPTED):
153
+ return None
154
+ if existing.get("status") == _STATUS_PENDING:
155
+ return None
156
+
157
+ pending_count = sum(1 for s in suggestions if s.get("status") == _STATUS_PENDING)
158
+ if pending_count >= MAX_PENDING:
159
+ logger.info("Suggestion backlog full (%d); dropping %r", MAX_PENDING, title)
160
+ return None
161
+
162
+ record = {
163
+ "id": uuid.uuid4().hex[:12],
164
+ "title": title.strip(),
165
+ "description": description.strip(),
166
+ "source": source,
167
+ "job_spec": job_spec,
168
+ "dedup_key": dedup_key.strip(),
169
+ "status": _STATUS_PENDING,
170
+ "created_at": _hermes_now().isoformat(),
171
+ }
172
+ suggestions.append(record)
173
+ _save_raw(suggestions)
174
+ return record
175
+
176
+
177
+ def get_suggestion(ref: str) -> Optional[Dict[str, Any]]:
178
+ """Resolve a suggestion by id, 1-based pending index, or title (exact)."""
179
+ suggestions = load_suggestions()
180
+ # By id.
181
+ for s in suggestions:
182
+ if s.get("id") == ref:
183
+ return s
184
+ # By 1-based pending index.
185
+ if ref.isdigit():
186
+ pending = [s for s in suggestions if s.get("status") == _STATUS_PENDING]
187
+ idx = int(ref) - 1
188
+ if 0 <= idx < len(pending):
189
+ return pending[idx]
190
+ # By exact title (case-insensitive).
191
+ for s in suggestions:
192
+ if s.get("title", "").lower() == ref.lower():
193
+ return s
194
+ return None
195
+
196
+
197
+ def _set_status(suggestion_id: str, status: str) -> bool:
198
+ with _suggestions_lock:
199
+ suggestions = _load_raw().get("suggestions", [])
200
+ changed = False
201
+ for s in suggestions:
202
+ if s.get("id") == suggestion_id:
203
+ s["status"] = status
204
+ s["resolved_at"] = _hermes_now().isoformat()
205
+ changed = True
206
+ break
207
+ if changed:
208
+ _save_raw(suggestions)
209
+ return changed
210
+
211
+
212
+ def dismiss_suggestion(ref: str) -> bool:
213
+ """Dismiss a suggestion (latched — never re-offered for its dedup_key)."""
214
+ s = get_suggestion(ref)
215
+ if not s:
216
+ return False
217
+ return _set_status(s["id"], _STATUS_DISMISSED)
218
+
219
+
220
+ def accept_suggestion(ref: str, *, origin: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
221
+ """Accept a suggestion: create the real cron job from its ``job_spec``.
222
+
223
+ Returns the created cron job dict, or None if the suggestion isn't found /
224
+ not pending. The job_spec is passed straight to ``cron.jobs.create_job``;
225
+ an ``origin`` (platform/chat) is merged so "origin" delivery routes back to
226
+ the chat where the user accepted.
227
+ """
228
+ s = get_suggestion(ref)
229
+ if not s or s.get("status") != _STATUS_PENDING:
230
+ return None
231
+
232
+ from cron.jobs import create_job
233
+
234
+ spec = dict(s.get("job_spec") or {})
235
+ if origin is not None and "origin" not in spec:
236
+ spec["origin"] = origin
237
+
238
+ job = create_job(**spec)
239
+ _set_status(s["id"], _STATUS_ACCEPTED)
240
+ return job
241
+
242
+
243
+ def clear_resolved() -> int:
244
+ """Drop accepted/dismissed records from disk. Returns the count removed.
245
+
246
+ Pending suggestions and the dedup memory of dismissed ones are the only
247
+ things that matter long-term, but dismissed records must be RETAINED for
248
+ their dedup_key (so they aren't re-offered). This only prunes ACCEPTED
249
+ records, which have served their purpose once the job exists.
250
+ """
251
+ with _suggestions_lock:
252
+ suggestions = _load_raw().get("suggestions", [])
253
+ kept = [s for s in suggestions if s.get("status") != _STATUS_ACCEPTED]
254
+ removed = len(suggestions) - len(kept)
255
+ if removed:
256
+ _save_raw(kept)
257
+ return removed
@@ -0,0 +1,196 @@
1
+ # Chronos managed-cron — agent ↔ NAS wire contract
2
+
3
+ **Status:** authoritative wire spec for the Chronos cron provider.
4
+ **Audience:** the NAS-side implementer of the `agent-cron` endpoints
5
+ (`nous-account-service`) and anyone debugging the managed-cron path.
6
+
7
+ Chronos lets a hosted Hermes gateway **scale to zero** while idle and still
8
+ fire cron jobs. Instead of an in-process 60-second ticker, the agent asks NAS
9
+ to arm exactly **one external one-shot per job at that job's real next-fire
10
+ time**. NAS calls the agent back at fire time over an authenticated webhook;
11
+ the agent runs the job and re-arms the next one-shot. Between fires the agent
12
+ process can be fully stopped — it wakes only on a genuine fire.
13
+
14
+ The external scheduler NAS uses to implement the one-shots is an **internal NAS
15
+ implementation detail**. The agent never talks to it, never holds its
16
+ credentials, and never names it. The agent only knows the three NAS endpoints
17
+ below.
18
+
19
+ ```
20
+ create/update/pause/resume/remove a cron job (agent side)
21
+
22
+
23
+ ChronosCronScheduler.reconcile() ── agent computes next_run_at
24
+ │ POST {portal}/api/agent-cron/provision (auth: agent's Nous access token)
25
+
26
+ NAS arms a one-shot for fire_at ── NAS owns the scheduler + its creds
27
+
28
+ ⏰ at fire_at
29
+
30
+ scheduler → POST {portal}/api/agent-cron/relay (auth: scheduler signature, NAS-verified)
31
+
32
+
33
+ NAS mints a short-lived agent-audience JWT (purpose=cron_fire)
34
+ │ POST {agent_callback_url}/api/cron/fire (auth: that JWT)
35
+
36
+ agent verifies the NAS JWT → store CAS claim → run_one_job → re-arm next one-shot
37
+ ```
38
+
39
+ ## Trust model (read this first)
40
+
41
+ | Hop | Who calls whom | Auth mechanism | Verified by |
42
+ |---|---|---|---|
43
+ | 1 | agent → NAS (`provision`/`cancel`/`list`) | the agent's existing **Nous Portal access token** (Bearer) | NAS (its normal agent-token path) |
44
+ | 2 | scheduler → NAS (`relay`) | the scheduler's request **signature** | NAS (the signature path it already has) |
45
+ | 3 | NAS → agent (`/api/cron/fire`) | a **short-lived NAS-minted JWT** (`aud=agent:{instance_id}`, `purpose=cron_fire`) | agent (PyJWT against NAS JWKS) |
46
+
47
+ Why NAS-mediated rather than scheduler→agent direct: the scheduler signs with
48
+ **NAS's** keys, which the agent does not (and should not) hold. The agent can
49
+ only verify a **NAS-minted** token — a trust path it already has. This keeps
50
+ all scheduler credentials inside NAS. (Full rationale: the plan's DQ-4.)
51
+
52
+ No new secret is introduced on the agent: hop 1 reuses the token the agent
53
+ already uses for the portal, and hop 3 reuses the NAS-JWT verification the agent
54
+ already performs.
55
+
56
+ ---
57
+
58
+ ## Endpoint 1 — `POST /api/agent-cron/provision` (agent → NAS)
59
+
60
+ Arm (or re-arm, idempotently) exactly one one-shot for a job.
61
+
62
+ - **Auth:** `Authorization: Bearer <agent Nous access token>`. NAS validates via
63
+ its normal agent-token path and scopes the row to the calling agent/org.
64
+ - **Request body:**
65
+ ```json
66
+ {
67
+ "job_id": "ab12cd34",
68
+ "fire_at": "2026-06-18T12:34:56+00:00",
69
+ "agent_callback_url": "https://agent-xyz.fly.dev",
70
+ "dedup_key": "ab12cd34:2026-06-18T12:34:56+00:00"
71
+ }
72
+ ```
73
+ - `fire_at` — ISO 8601, **agent-computed**. May be sub-minute in the future;
74
+ NAS must honor second-granularity (the agent owns the time, so there is no
75
+ 1-minute scheduler floor).
76
+ - `agent_callback_url` — the agent's own publicly-reachable base URL. NAS
77
+ POSTs `{agent_callback_url}/api/cron/fire` at fire time.
78
+ - `dedup_key` — `"{job_id}:{fire_at}"`. NAS **upserts by `(agent_id, job_id)`**
79
+ so re-arming the same fire is idempotent (no duplicate one-shots). A new
80
+ `fire_at` for the same `job_id` replaces the prior arm.
81
+ - **Action:** arm one one-shot to fire at `fire_at`, destined for the NAS
82
+ **relay** route (Endpoint 3) — NOT the agent directly, so NAS stays in the
83
+ loop to mint the agent JWT. Persist `(agent_id, job_id, schedule_id,
84
+ agent_callback_url)`.
85
+ - **Response:** `200 {"schedule_id": "<opaque>"}`.
86
+
87
+ ## Endpoint 2 — `POST /api/agent-cron/cancel` (agent → NAS)
88
+
89
+ - **Auth:** same as Endpoint 1.
90
+ - **Body:** `{"job_id": "ab12cd34"}`.
91
+ - **Action:** cancel the armed one-shot for `(agent_id, job_id)` and delete the
92
+ row. Idempotent — cancelling an unknown job is a 200 no-op.
93
+ - **Response:** `200 {"ok": true}`.
94
+
95
+ ## Endpoint 3 — `POST /api/agent-cron/relay` (scheduler → NAS, the fire relay)
96
+
97
+ - **Auth:** the scheduler's request **signature**, verified by NAS with the
98
+ signature path it already has. This is the trust boundary for the fire — a
99
+ forged relay call must be rejected here.
100
+ - **Action:**
101
+ 1. Look up `(agent_id, job_id) → agent_callback_url` from the persisted row.
102
+ 2. Mint a **short-lived** JWT: `aud = "agent:{instance_id}"`,
103
+ `iss = {portal_url}`, `purpose = "cron_fire"`, small `exp` (≈60–120s),
104
+ signed with NAS's normal asymmetric signing key (published via JWKS).
105
+ 3. `POST {agent_callback_url}/api/cron/fire` with
106
+ `Authorization: Bearer <that JWT>` and body `{"job_id": "...", "fire_at": "..."}`.
107
+ 4. Treat a non-2xx agent response as a **retryable** failure (let the
108
+ scheduler retry the relay). The agent's store CAS de-dupes a double fire,
109
+ so retries are safe.
110
+ - **Response to the scheduler:** 2xx once the agent POST is accepted (202), so
111
+ the scheduler does not retry a delivered fire.
112
+
113
+ ---
114
+
115
+ ## Inbound `POST /api/cron/fire` (NAS → agent) — agent side, already implemented
116
+
117
+ This is the agent endpoint NAS calls in Endpoint 3 step 3. Served by the
118
+ **dashboard app** (`hermes_cli/web_server.py`) — the agent's always-reachable
119
+ public HTTP surface on hosted deployments (the gateway may be idle/scaled down);
120
+ it is in `PUBLIC_API_PATHS` so the dashboard cookie gate lets the bearer-JWT
121
+ callback through to the verifier. (Also registered on the optional
122
+ `APIServerAdapter` for self-host API-server deployments.) The verifier is
123
+ `plugins/cron/chronos/verify.py`.
124
+
125
+ - **Auth:** `Authorization: Bearer <NAS-minted JWT>`. The agent verifies:
126
+ - signature against the NAS JWKS (`cron.chronos.nas_jwks_url`),
127
+ - `aud` == `cron.chronos.expected_audience` (this agent's
128
+ `agent:{instance_id}`),
129
+ - `iss` == `cron.chronos.portal_url`,
130
+ - `exp` / `nbf` (30s leeway),
131
+ - `purpose == "cron_fire"` — a general agent JWT (no/other purpose) is
132
+ rejected so it can't be replayed against this endpoint.
133
+ - **Body:** `{"job_id": "ab12cd34", "fire_at": "..."}` (only `job_id` is used).
134
+ - **Behavior:**
135
+ - invalid/missing/forged/expired/wrong-aud/wrong-purpose token → **401**, no
136
+ execution.
137
+ - missing `job_id` → **400**.
138
+ - valid → **202 `{"status": "accepted", "job_id": "..."}`** immediately, and
139
+ the job runs in the background. 202-before-run means a long agent turn never
140
+ trips the relay's HTTP timeout.
141
+ - **At-most-once:** the agent claims the job with a store-level compare-and-set
142
+ (`claim_job_for_fire`) before running. A relay/scheduler retry that arrives
143
+ while the first fire is in flight (or after it completed) loses the claim and
144
+ does not double-run.
145
+
146
+ ---
147
+
148
+ ## At-most-once & re-arm semantics
149
+
150
+ - **Recurring (cron/interval):** on fire, the agent advances `next_run_at`
151
+ (under its store lock) as part of the claim, runs the job, then re-provisions
152
+ a one-shot for the new `next_run_at`. A duplicate relay for the old `fire_at`
153
+ finds the claim taken / time advanced and is dropped.
154
+ - **One-shot (`30m`, `+90s`, etc.):** fires once; `mark_job_run` marks it
155
+ completed. No re-arm.
156
+ - **`repeat.times = N`:** `mark_job_run` deletes the job at the limit, so
157
+ `get_job` returns `None` after the final fire → the agent does **not** re-arm
158
+ → the schedule stops cleanly with no orphaned one-shot.
159
+ - **Multi-replica agents:** the store CAS makes the fire at-most-once across N
160
+ gateway replicas sharing one `HERMES_HOME` — exactly one replica runs each
161
+ fire.
162
+
163
+ ## Reconcile (self-healing)
164
+
165
+ The agent reconciles desired (`jobs.json`) vs armed on:
166
+ - `start()` (gateway boot / wake),
167
+ - every successful job mutation (`on_jobs_changed`),
168
+ - piggybacked after each fire (re-arm).
169
+
170
+ Reconcile arms missing/changed-time jobs and cancels orphans. A missed
171
+ provision (transient NAS error) self-heals on the next reconcile. There is **no
172
+ periodic wake** of a sleeping agent — that would negate scale-to-zero.
173
+
174
+ ## Config (agent side)
175
+
176
+ All non-secret (`cron.chronos.*` in `config.yaml`); the agent holds no scheduler
177
+ credentials. For hosted agents NAS sets these at provision time:
178
+
179
+ | key | meaning |
180
+ |---|---|
181
+ | `cron.provider` | `"chronos"` to activate (empty = built-in ticker) |
182
+ | `cron.chronos.portal_url` | NAS base URL (also the expected JWT `iss`) |
183
+ | `cron.chronos.callback_url` | the agent's own public base URL for NAS→agent fires |
184
+ | `cron.chronos.expected_audience` | this agent's JWT `aud` (`agent:{instance_id}`) |
185
+ | `cron.chronos.nas_jwks_url` | NAS JWKS for verifying the fire JWT |
186
+
187
+ If `callback_url` / `portal_url` is blank or the agent has no Nous login,
188
+ `is_available()` returns False and the resolver falls back to the built-in
189
+ in-process ticker — cron never loses its trigger.
190
+
191
+ ## Escape hatch (not default)
192
+
193
+ The inbound `/api/cron/fire` verifier is pluggable (`get_fire_verifier()`). If
194
+ relay volume through NAS ever saturates, a direct scheduler→agent mode with a
195
+ per-job NAS-minted cron-key can replace the NAS-JWT verifier with **no change to
196
+ the webhook handler**. NAS-mediated (this contract) is the default.
@@ -0,0 +1,146 @@
1
+ # Profile Builder — Dashboard-Native, Full-Featured Profile Creation
2
+
3
+ Status: design proposal (not yet implemented)
4
+ Author: drafted for Teknium
5
+ Supersedes: PR #31781 (prompt_toolkit `hermes profile wizard`)
6
+
7
+ ## Why this, not the CLI wizard
8
+
9
+ PR #31781 added a keyboard-driven `hermes profile wizard` in the terminal.
10
+ The decision is to **not** build the profile-creation experience in the CLI.
11
+ The dashboard already owns mature, separate pages for every element a profile
12
+ needs, and a profile is just a HERMES_HOME directory — so the dashboard is the
13
+ right home for a full-featured builder, and it can reuse everything that
14
+ already exists.
15
+
16
+ A profile = a full `~/.hermes/profiles/<name>/` directory with its own:
17
+ - `config.yaml` — holds `model`/`provider`, `mcp_servers`, enabled skills
18
+ - `skills/` — physical SKILL.md files (built-in seed + optional + hub installs)
19
+ - `.env` — secrets
20
+ - `SOUL.md` / `USER.md` — identity
21
+
22
+ So per-profile scoping of Model, MCPs, and Skills is **native** — no data-model
23
+ change needed. The gap is purely UX: creation today is a thin modal
24
+ (name + clone + model + description), and you can only compose skills/MCPs
25
+ *after* the profile exists, by visiting other pages and remembering to scope
26
+ them.
27
+
28
+ ## What already exists (reuse, don't rebuild)
29
+
30
+ | Element | Existing page | Existing API | Profile-scopable? |
31
+ |---|---|---|---|
32
+ | Name / Description | ProfilesPage create modal | `POST /api/profiles` (`create_profile`) | yes (args) |
33
+ | Model + Provider | ModelsPage | `_write_profile_model(profile_dir, …)` | yes — HERMES_HOME override, already wired into create endpoint |
34
+ | MCPs | McpPage | `mcp_config._save_mcp_server` + `/api/mcp/catalog` | yes — wrap with HERMES_HOME override |
35
+ | Skills (built-in/optional) | SkillsPage | `GET /api/skills`, `/api/skills/toggle` | yes — config write |
36
+ | Skills (hub) | SkillsPage | `/api/skills/hub/search`, `/api/skills/hub/install` | **only via subprocess** — see seam #1 |
37
+
38
+ ## Two architectural seams found while grounding this design
39
+
40
+ These are load-bearing — they change the implementation, not just the polish.
41
+
42
+ ### Seam #1 — hub-skill install cannot use the HERMES_HOME override
43
+
44
+ `tools/skills_hub.py` binds `SKILLS_DIR = HERMES_HOME / "skills"` at **module
45
+ import time**. The context-local `set_hermes_home_override()` swap (which makes
46
+ `_write_profile_model` and the MCP write land in the target profile) does NOT
47
+ retroactively rebind that already-imported module global. So a data-layer wrap
48
+ of hub install would write into the dashboard's *own* active profile, not the
49
+ new one.
50
+
51
+ The correct mechanism is the existing subprocess path: `_spawn_hermes_action`
52
+ runs `python -m hermes_cli.main <subcommand>`, and `_apply_profile_override()`
53
+ re-reads `sys.argv` at import in the fresh child. Prepend `-p <profile>`:
54
+
55
+ ```python
56
+ _spawn_hermes_action(["-p", profile, "skills", "install", identifier], "skills-install")
57
+ ```
58
+
59
+ A fresh subprocess re-imports `skills_hub` with the profile's HERMES_HOME bound
60
+ from the start, so `SKILLS_DIR` resolves to `<profile>/skills/`. Correct by
61
+ construction.
62
+
63
+ ### Seam #2 — hub installs are async, so create cannot be fully atomic
64
+
65
+ Built-in/optional skill enabling and MCP writes are **synchronous config ops**
66
+ and can be part of the create call. Hub installs are long-running git fetches
67
+ spawned detached (`_spawn_hermes_action` returns a PID immediately). So the
68
+ create flow is:
69
+
70
+ 1. `create_profile()` — make the dir (synchronous)
71
+ 2. write model (synchronous, HERMES_HOME override)
72
+ 3. write selected MCP servers (synchronous, HERMES_HOME override)
73
+ 4. seed/enable selected built-in + optional skills (synchronous)
74
+ 5. spawn `hermes -p <profile> skills install <id>` per hub skill (async, returns PIDs)
75
+
76
+ Steps 1–4 commit before the response; step 5 returns a list of action PIDs the
77
+ UI polls (same pattern as today's SkillsPage hub install). The builder's
78
+ "Review → Create" returns `{ok, name, path, hub_installs: [{id, pid}]}` and the
79
+ final screen shows live install progress for the hub skills.
80
+
81
+ ## Proposed backend change (small, follows existing patterns)
82
+
83
+ Extend `ProfileCreate` and the create endpoint — no new endpoints, no rewrite:
84
+
85
+ ```python
86
+ class ProfileCreate(BaseModel):
87
+ name: str
88
+ clone_from: Optional[str] = None
89
+ # Backward compatibility for older dashboard/desktop clients.
90
+ clone_from_default: bool = False
91
+ clone_all: bool = False
92
+ no_skills: bool = False
93
+ description: Optional[str] = None
94
+ provider: Optional[str] = None
95
+ model: Optional[str] = None
96
+ # NEW — all optional, all best-effort post-create (profile already exists)
97
+ mcp_servers: List[MCPServerCreate] = [] # synchronous, HERMES_HOME override
98
+ builtin_skills: List[str] = [] # synchronous enable/seed
99
+ hub_skills: List[str] = [] # async spawn, returns PIDs
100
+ ```
101
+
102
+ The endpoint already does best-effort post-create steps (`seed_profile_skills`,
103
+ `_write_profile_model`). Add two more best-effort blocks (MCP write, hub-skill
104
+ spawn) in the same style — a failure in any of them must not 500 the create,
105
+ since the profile dir already exists and the user can fix it from the relevant
106
+ page afterward. Mirror `_write_profile_model`'s HERMES_HOME-override helper for
107
+ the MCP write (`_write_profile_mcp_servers(profile_dir, servers)`).
108
+
109
+ ## Proposed frontend — dedicated builder page `/profiles/new`
110
+
111
+ A full page (not the cramped modal), stepped, each step reusing the existing
112
+ page's component + API, targeted at the new profile:
113
+
114
+ ```
115
+ ① Identity Name + Description (+ optional clone-from existing profile)
116
+ ② Model Provider + model picker (reuse ModelsPage picker)
117
+ ③ Skills Tabs: Built-in · Optional · Hub-search
118
+ multi-select; "Start from default bundle" preset button
119
+ ④ MCPs Tabs: Catalog browse · Manual add (reuse McpPage form)
120
+ ⑤ Review Blueprint preview → Create
121
+ → progress screen for async hub installs
122
+ ```
123
+
124
+ Nothing writes to disk until ⑤.
125
+
126
+ ## Open product decisions (need Teknium)
127
+
128
+ 1. **Skills seeding default.** Fresh profiles auto-seed the default bundle
129
+ today. In the builder, should the skill step **replace** the bundle (pick
130
+ exactly what you want; offer a "start from default bundle" preset) or
131
+ **augment** it? Recommendation: replace + preset button.
132
+
133
+ 2. **Page vs richer modal.** Dedicated `/profiles/new` page (room to grow:
134
+ SOUL editing, multi-agent fleets later) vs a bigger create modal on
135
+ ProfilesPage. Recommendation: dedicated page — matches "full-featured / way
136
+ more options."
137
+
138
+ ## Verification plan (when built)
139
+
140
+ - Backend E2E with isolated HERMES_HOME: POST a full create body
141
+ (name + model + 2 MCPs + 3 builtin skills + 1 hub skill), assert the new
142
+ profile dir has the model in config.yaml, both MCP servers in config.yaml,
143
+ the builtin skills enabled, and a spawned PID for the hub skill. Negative:
144
+ a bad MCP entry must not 500 the create.
145
+ - `cd web && npm run build` (no JS test suite in web/).
146
+ - Targeted: `pytest tests/<web_server profile tests> -k profile_create`.