@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.
- package/agent/.dockerignore +67 -0
- package/agent/.envrc +1 -1
- package/agent/.gitattributes +8 -0
- package/agent/AGENTS.md +216 -4
- package/agent/CONTRIBUTING.md +46 -8
- package/agent/Dockerfile +78 -35
- package/agent/MANIFEST.in +2 -0
- package/agent/README.md +12 -5
- package/agent/README.ur-pk.md +261 -0
- package/agent/README.zh-CN.md +11 -8
- package/agent/SECURITY.md +5 -4
- package/agent/acp_adapter/provenance.py +127 -0
- package/agent/acp_adapter/server.py +112 -5
- package/agent/acp_adapter/session.py +1 -6
- package/agent/acp_registry/agent.json +2 -2
- package/agent/agent/account_usage.py +313 -1
- package/agent/agent/agent_init.py +140 -37
- package/agent/agent/agent_runtime_helpers.py +342 -83
- package/agent/agent/anthropic_adapter.py +320 -33
- package/agent/agent/auxiliary_client.py +525 -105
- package/agent/agent/background_review.py +157 -19
- package/agent/agent/bedrock_adapter.py +71 -6
- package/agent/agent/billing_view.py +295 -0
- package/agent/agent/chat_completion_helpers.py +229 -4
- package/agent/agent/codex_responses_adapter.py +86 -10
- package/agent/agent/codex_runtime.py +153 -1
- package/agent/agent/coding_context.py +738 -0
- package/agent/agent/context_compressor.py +392 -44
- package/agent/agent/context_references.py +34 -1
- package/agent/agent/conversation_compression.py +159 -22
- package/agent/agent/conversation_loop.py +643 -908
- package/agent/agent/copilot_acp_client.py +4 -11
- package/agent/agent/credential_pool.py +5 -3
- package/agent/agent/credits_tracker.py +794 -0
- package/agent/agent/curator.py +91 -18
- package/agent/agent/curator_backup.py +26 -10
- package/agent/agent/display.py +42 -1
- package/agent/agent/error_classifier.py +52 -3
- package/agent/agent/errors.py +3 -0
- package/agent/agent/file_safety.py +0 -17
- package/agent/agent/gemini_native_adapter.py +31 -1
- package/agent/agent/i18n.py +48 -4
- package/agent/agent/image_gen_provider.py +74 -5
- package/agent/agent/image_routing.py +29 -0
- package/agent/agent/insights.py +8 -17
- package/agent/agent/lsp/install.py +3 -0
- package/agent/agent/memory_manager.py +326 -31
- package/agent/agent/message_content.py +50 -0
- package/agent/agent/model_metadata.py +214 -3
- package/agent/agent/moonshot_schema.py +8 -1
- package/agent/agent/onboarding.py +60 -0
- package/agent/agent/prompt_builder.py +327 -37
- package/agent/agent/redact.py +1 -0
- package/agent/agent/runtime_cwd.py +34 -5
- package/agent/agent/secret_scope.py +205 -0
- package/agent/agent/secret_sources/bitwarden.py +34 -2
- package/agent/agent/skill_commands.py +90 -1
- package/agent/agent/skill_preprocessing.py +1 -0
- package/agent/agent/skill_utils.py +209 -36
- package/agent/agent/ssl_guard.py +94 -0
- package/agent/agent/system_prompt.py +133 -5
- package/agent/agent/tool_executor.py +496 -70
- package/agent/agent/transports/anthropic.py +83 -21
- package/agent/agent/transports/chat_completions.py +94 -5
- package/agent/agent/transports/codex.py +67 -2
- package/agent/agent/transports/codex_app_server.py +1 -0
- package/agent/agent/transports/codex_app_server_session.py +30 -0
- package/agent/agent/transports/types.py +12 -0
- package/agent/agent/turn_context.py +408 -0
- package/agent/agent/turn_finalizer.py +428 -0
- package/agent/agent/turn_retry_state.py +68 -0
- package/agent/agent/usage_pricing.py +3 -0
- package/agent/apps/bootstrap-installer/package.json +6 -5
- package/agent/apps/bootstrap-installer/src/routes/failure.tsx +12 -5
- package/agent/apps/bootstrap-installer/src/routes/progress.tsx +1 -3
- package/agent/apps/bootstrap-installer/src/store.ts +3 -2
- package/agent/apps/bootstrap-installer/src-tauri/src/bootstrap.rs +172 -7
- package/agent/apps/bootstrap-installer/src-tauri/src/events.rs +14 -1
- package/agent/apps/bootstrap-installer/src-tauri/src/paths.rs +29 -0
- package/agent/apps/bootstrap-installer/src-tauri/src/powershell.rs +93 -3
- package/agent/apps/bootstrap-installer/src-tauri/src/update.rs +695 -39
- package/agent/apps/bootstrap-installer/tsconfig.json +3 -4
- package/agent/apps/desktop/DESIGN.md +167 -0
- package/agent/apps/desktop/README.md +20 -16
- package/agent/apps/desktop/assets/icon.icns +0 -0
- package/agent/apps/desktop/assets/icon.ico +0 -0
- package/agent/apps/desktop/assets/icon.png +0 -0
- package/agent/apps/desktop/electron/backend-env.cjs +112 -0
- package/agent/apps/desktop/electron/backend-env.test.cjs +111 -0
- package/agent/apps/desktop/electron/backend-probes.test.cjs +3 -1
- package/agent/apps/desktop/electron/backend-ready.cjs +66 -0
- package/agent/apps/desktop/electron/bootstrap-platform.cjs +52 -0
- package/agent/apps/desktop/electron/bootstrap-platform.test.cjs +59 -1
- package/agent/apps/desktop/electron/bootstrap-runner.cjs +176 -38
- package/agent/apps/desktop/electron/bootstrap-runner.test.cjs +112 -1
- package/agent/apps/desktop/electron/connection-config.cjs +288 -0
- package/agent/apps/desktop/electron/connection-config.test.cjs +396 -0
- package/agent/apps/desktop/electron/dashboard-token.cjs +99 -0
- package/agent/apps/desktop/electron/dashboard-token.test.cjs +142 -0
- package/agent/apps/desktop/electron/desktop-uninstall.cjs +232 -0
- package/agent/apps/desktop/electron/desktop-uninstall.test.cjs +246 -0
- package/agent/apps/desktop/electron/entitlements.mac.inherit.plist +2 -0
- package/agent/apps/desktop/electron/fs-read-dir.cjs +109 -0
- package/agent/apps/desktop/electron/fs-read-dir.test.cjs +364 -0
- package/agent/apps/desktop/electron/gateway-ws-probe.cjs +188 -0
- package/agent/apps/desktop/electron/gateway-ws-probe.test.cjs +122 -0
- package/agent/apps/desktop/electron/git-root.cjs +54 -0
- package/agent/apps/desktop/electron/git-root.test.cjs +40 -0
- package/agent/apps/desktop/electron/git-worktrees.cjs +174 -0
- package/agent/apps/desktop/electron/hardening.cjs +123 -28
- package/agent/apps/desktop/electron/hardening.test.cjs +163 -0
- package/agent/apps/desktop/electron/main.cjs +3121 -331
- package/agent/apps/desktop/electron/oauth-net-request.cjs +20 -0
- package/agent/apps/desktop/electron/oauth-net-request.test.cjs +34 -0
- package/agent/apps/desktop/electron/preload.cjs +52 -2
- package/agent/apps/desktop/electron/session-windows.cjs +124 -0
- package/agent/apps/desktop/electron/session-windows.test.cjs +199 -0
- package/agent/apps/desktop/electron/update-rebuild.cjs +29 -0
- package/agent/apps/desktop/electron/update-rebuild.test.cjs +55 -0
- package/agent/apps/desktop/electron/update-remote.cjs +56 -0
- package/agent/apps/desktop/electron/update-remote.test.cjs +78 -0
- package/agent/apps/desktop/electron/vscode-marketplace.cjs +331 -0
- package/agent/apps/desktop/electron/vscode-marketplace.test.cjs +113 -0
- package/agent/apps/desktop/electron/windows-child-process.test.cjs +57 -0
- package/agent/apps/desktop/electron/windows-user-env.cjs +76 -0
- package/agent/apps/desktop/electron/windows-user-env.test.cjs +90 -0
- package/agent/apps/desktop/electron/workspace-cwd.cjs +38 -0
- package/agent/apps/desktop/electron/workspace-cwd.test.cjs +45 -0
- package/agent/apps/desktop/eslint.config.mjs +0 -3
- package/agent/apps/desktop/index.html +27 -2
- package/agent/apps/desktop/package.json +31 -11
- package/agent/apps/desktop/pr-assets/session-source-folders.png +0 -0
- package/agent/apps/desktop/public/apple-touch-icon.png +0 -0
- package/agent/apps/desktop/public/nous-girl.jpg +0 -0
- package/agent/apps/desktop/scripts/assert-dist-built.cjs +70 -0
- package/agent/apps/desktop/scripts/assert-dist-built.test.cjs +84 -0
- package/agent/apps/desktop/scripts/before-pack.cjs +78 -0
- package/agent/apps/desktop/scripts/before-pack.test.cjs +53 -0
- package/agent/apps/desktop/scripts/diag-scroll-reset.mjs +229 -0
- package/agent/apps/desktop/scripts/patch-electron-builder-mac-binary.cjs +64 -0
- package/agent/apps/desktop/scripts/run-electron-builder.cjs +57 -0
- package/agent/apps/desktop/src/app/agents/index.tsx +53 -45
- package/agent/apps/desktop/src/app/artifacts/index.tsx +102 -83
- package/agent/apps/desktop/src/app/chat/chat-drop-overlay.tsx +29 -8
- package/agent/apps/desktop/src/app/chat/chat-swap-overlay.tsx +47 -0
- package/agent/apps/desktop/src/app/chat/composer/attachments.tsx +81 -45
- package/agent/apps/desktop/src/app/chat/composer/completion-drawer.tsx +13 -24
- package/agent/apps/desktop/src/app/chat/composer/context-menu.tsx +138 -88
- package/agent/apps/desktop/src/app/chat/composer/controls.tsx +138 -90
- package/agent/apps/desktop/src/app/chat/composer/enter-submit-dom-race.test.tsx +218 -0
- package/agent/apps/desktop/src/app/chat/composer/focus.ts +32 -0
- package/agent/apps/desktop/src/app/chat/composer/help-hint.tsx +38 -25
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-live-completion-adapter.ts +7 -0
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-mic-recorder.ts +22 -12
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-slash-completions.ts +142 -14
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-voice-conversation.ts +14 -11
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-voice-recorder.ts +9 -6
- package/agent/apps/desktop/src/app/chat/composer/ime-composition-dom-repro.test.tsx +108 -0
- package/agent/apps/desktop/src/app/chat/composer/index.tsx +930 -180
- package/agent/apps/desktop/src/app/chat/composer/inline-refs.ts +136 -32
- package/agent/apps/desktop/src/app/chat/composer/model-pill.tsx +86 -0
- package/agent/apps/desktop/src/app/chat/composer/queue-panel.tsx +54 -75
- package/agent/apps/desktop/src/app/chat/composer/rich-editor.test.ts +117 -1
- package/agent/apps/desktop/src/app/chat/composer/rich-editor.ts +117 -6
- package/agent/apps/desktop/src/app/chat/composer/slash-nav-dom-repro.test.tsx +186 -0
- package/agent/apps/desktop/src/app/chat/composer/status-stack/index.tsx +202 -0
- package/agent/apps/desktop/src/app/chat/composer/status-stack/status-row.tsx +155 -0
- package/agent/apps/desktop/src/app/chat/composer/text-utils.test.ts +104 -0
- package/agent/apps/desktop/src/app/chat/composer/text-utils.ts +37 -9
- package/agent/apps/desktop/src/app/chat/composer/trigger-popover.test.tsx +50 -0
- package/agent/apps/desktop/src/app/chat/composer/trigger-popover.tsx +105 -40
- package/agent/apps/desktop/src/app/chat/composer/types.ts +5 -0
- package/agent/apps/desktop/src/app/chat/composer/url-dialog.tsx +11 -15
- package/agent/apps/desktop/src/app/chat/composer/voice-activity.tsx +8 -4
- package/agent/apps/desktop/src/app/chat/hooks/use-composer-actions.test.ts +57 -0
- package/agent/apps/desktop/src/app/chat/hooks/use-composer-actions.ts +70 -16
- package/agent/apps/desktop/src/app/chat/hooks/use-file-drop-zone.ts +52 -16
- package/agent/apps/desktop/src/app/chat/index.tsx +234 -81
- package/agent/apps/desktop/src/app/chat/perf-probe.tsx +69 -21
- package/agent/apps/desktop/src/app/chat/right-rail/preview-console.tsx +44 -40
- package/agent/apps/desktop/src/app/chat/right-rail/preview-file.tsx +71 -25
- package/agent/apps/desktop/src/app/chat/right-rail/preview-pane.test.tsx +40 -1
- package/agent/apps/desktop/src/app/chat/right-rail/preview-pane.tsx +55 -53
- package/agent/apps/desktop/src/app/chat/right-rail/preview.tsx +35 -17
- package/agent/apps/desktop/src/app/chat/scroll-to-bottom-button.test.tsx +67 -0
- package/agent/apps/desktop/src/app/chat/scroll-to-bottom-button.tsx +74 -0
- package/agent/apps/desktop/src/app/chat/sidebar/cron-jobs-section.tsx +356 -0
- package/agent/apps/desktop/src/app/chat/sidebar/index.tsx +1189 -364
- package/agent/apps/desktop/src/app/chat/sidebar/load-more-row.tsx +30 -0
- package/agent/apps/desktop/src/app/chat/sidebar/order.test.ts +21 -0
- package/agent/apps/desktop/src/app/chat/sidebar/order.ts +17 -0
- package/agent/apps/desktop/src/app/chat/sidebar/profile-switcher.tsx +524 -0
- package/agent/apps/desktop/src/app/chat/sidebar/session-actions-menu.tsx +80 -45
- package/agent/apps/desktop/src/app/chat/sidebar/session-row.tsx +120 -25
- package/agent/apps/desktop/src/app/chat/sidebar/virtual-session-list.tsx +7 -13
- package/agent/apps/desktop/src/app/chat/sidebar/workspace-groups.test.ts +149 -0
- package/agent/apps/desktop/src/app/chat/sidebar/workspace-groups.ts +326 -0
- package/agent/apps/desktop/src/app/chat/thread-loading.ts +7 -2
- package/agent/apps/desktop/src/app/command-center/index.tsx +320 -581
- package/agent/apps/desktop/src/app/command-palette/index.tsx +681 -0
- package/agent/apps/desktop/src/app/command-palette/marketplace-theme-page.tsx +157 -0
- package/agent/apps/desktop/src/app/cron/index.tsx +392 -324
- package/agent/apps/desktop/src/app/cron/job-state.ts +29 -0
- package/agent/apps/desktop/src/app/desktop-controller.tsx +618 -123
- package/agent/apps/desktop/src/app/floating-hud.ts +22 -0
- package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-boot.test.tsx +265 -0
- package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-boot.ts +260 -14
- package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-request.ts +48 -4
- package/agent/apps/desktop/src/app/hooks/use-keybinds.ts +270 -0
- package/agent/apps/desktop/src/app/hooks/use-refresh-hotkey.ts +45 -0
- package/agent/apps/desktop/src/app/layout-constants.ts +19 -0
- package/agent/apps/desktop/src/app/messaging/index.tsx +136 -241
- package/agent/apps/desktop/src/app/messaging/platform-icon.tsx +95 -0
- package/agent/apps/desktop/src/app/model-visibility-overlay.tsx +31 -0
- package/agent/apps/desktop/src/app/overlays/overlay-search-input.tsx +18 -62
- package/agent/apps/desktop/src/app/overlays/overlay-split-layout.tsx +59 -7
- package/agent/apps/desktop/src/app/overlays/overlay-view.tsx +9 -5
- package/agent/apps/desktop/src/app/page-search-shell.tsx +42 -20
- package/agent/apps/desktop/src/app/profiles/create-profile-dialog.tsx +165 -0
- package/agent/apps/desktop/src/app/profiles/delete-profile-dialog.tsx +65 -0
- package/agent/apps/desktop/src/app/profiles/index.tsx +174 -199
- package/agent/apps/desktop/src/app/profiles/rename-profile-dialog.tsx +125 -0
- package/agent/apps/desktop/src/app/right-sidebar/files/dnd-manager.ts +27 -0
- package/agent/apps/desktop/src/app/right-sidebar/files/ipc.test.ts +100 -0
- package/agent/apps/desktop/src/app/right-sidebar/files/ipc.ts +12 -18
- package/agent/apps/desktop/src/app/right-sidebar/files/remote-picker.tsx +177 -0
- package/agent/apps/desktop/src/app/right-sidebar/files/tree.tsx +35 -21
- package/agent/apps/desktop/src/app/right-sidebar/files/use-project-tree.test.ts +75 -3
- package/agent/apps/desktop/src/app/right-sidebar/files/use-project-tree.ts +152 -5
- package/agent/apps/desktop/src/app/right-sidebar/index.test.tsx +75 -0
- package/agent/apps/desktop/src/app/right-sidebar/index.tsx +166 -129
- package/agent/apps/desktop/src/app/right-sidebar/store.ts +19 -4
- package/agent/apps/desktop/src/app/right-sidebar/terminal/buffer.ts +65 -0
- package/agent/apps/desktop/src/app/right-sidebar/terminal/index.tsx +29 -34
- package/agent/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx +18 -6
- package/agent/apps/desktop/src/app/right-sidebar/terminal/selection.ts +93 -32
- package/agent/apps/desktop/src/app/right-sidebar/terminal/use-terminal-session.ts +381 -119
- package/agent/apps/desktop/src/app/routes.ts +9 -0
- package/agent/apps/desktop/src/app/session/hooks/use-cwd-actions.ts +17 -7
- package/agent/apps/desktop/src/app/session/hooks/use-message-stream.ts +365 -47
- package/agent/apps/desktop/src/app/session/hooks/use-model-controls.test.tsx +198 -0
- package/agent/apps/desktop/src/app/session/hooks/use-model-controls.ts +70 -34
- package/agent/apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx +1061 -0
- package/agent/apps/desktop/src/app/session/hooks/use-prompt-actions.ts +1143 -165
- package/agent/apps/desktop/src/app/session/hooks/use-route-resume.test.tsx +341 -2
- package/agent/apps/desktop/src/app/session/hooks/use-route-resume.ts +176 -5
- package/agent/apps/desktop/src/app/session/hooks/use-session-actions.test.tsx +259 -0
- package/agent/apps/desktop/src/app/session/hooks/use-session-actions.ts +452 -149
- package/agent/apps/desktop/src/app/session/hooks/use-session-state-cache.test.tsx +327 -0
- package/agent/apps/desktop/src/app/session/hooks/use-session-state-cache.ts +133 -4
- package/agent/apps/desktop/src/app/session-picker-overlay.tsx +32 -0
- package/agent/apps/desktop/src/app/session-switcher.tsx +107 -0
- package/agent/apps/desktop/src/app/settings/about-settings.tsx +45 -36
- package/agent/apps/desktop/src/app/settings/appearance-settings.tsx +243 -162
- package/agent/apps/desktop/src/app/settings/config-settings.tsx +86 -66
- package/agent/apps/desktop/src/app/settings/constants.ts +459 -122
- package/agent/apps/desktop/src/app/settings/credential-key-ui.tsx +373 -0
- package/agent/apps/desktop/src/app/settings/env-credentials.tsx +198 -0
- package/agent/apps/desktop/src/app/settings/env-var-actions-menu.tsx +136 -0
- package/agent/apps/desktop/src/app/settings/field-copy.ts +56 -0
- package/agent/apps/desktop/src/app/settings/gateway-settings.tsx +385 -72
- package/agent/apps/desktop/src/app/settings/helpers.test.ts +156 -1
- package/agent/apps/desktop/src/app/settings/helpers.ts +30 -2
- package/agent/apps/desktop/src/app/settings/index.tsx +118 -84
- package/agent/apps/desktop/src/app/settings/keys-settings.tsx +62 -419
- package/agent/apps/desktop/src/app/settings/mcp-settings.tsx +65 -60
- package/agent/apps/desktop/src/app/settings/model-settings.test.tsx +129 -5
- package/agent/apps/desktop/src/app/settings/model-settings.tsx +370 -65
- package/agent/apps/desktop/src/app/settings/notifications-settings.tsx +150 -0
- package/agent/apps/desktop/src/app/settings/primitives.tsx +5 -11
- package/agent/apps/desktop/src/app/settings/provider-config-panel.test.tsx +142 -0
- package/agent/apps/desktop/src/app/settings/provider-config-panel.tsx +182 -0
- package/agent/apps/desktop/src/app/settings/providers-settings.test.tsx +171 -0
- package/agent/apps/desktop/src/app/settings/providers-settings.tsx +471 -0
- package/agent/apps/desktop/src/app/settings/sessions-settings.tsx +183 -71
- package/agent/apps/desktop/src/app/settings/toolset-config-panel.test.tsx +135 -1
- package/agent/apps/desktop/src/app/settings/toolset-config-panel.tsx +180 -57
- package/agent/apps/desktop/src/app/settings/types.ts +9 -6
- package/agent/apps/desktop/src/app/settings/uninstall-section.tsx +185 -0
- package/agent/apps/desktop/src/app/settings/use-deep-link-highlight.ts +60 -0
- package/agent/apps/desktop/src/app/shell/app-shell.tsx +59 -13
- package/agent/apps/desktop/src/app/shell/gateway-menu-panel.tsx +37 -32
- package/agent/apps/desktop/src/app/shell/hooks/use-overlay-routing.ts +6 -3
- package/agent/apps/desktop/src/app/shell/hooks/use-statusbar-items.tsx +212 -53
- package/agent/apps/desktop/src/app/shell/keybind-panel.tsx +215 -0
- package/agent/apps/desktop/src/app/shell/model-edit-submenu.test.tsx +84 -0
- package/agent/apps/desktop/src/app/shell/model-edit-submenu.tsx +244 -0
- package/agent/apps/desktop/src/app/shell/model-menu-panel.tsx +392 -0
- package/agent/apps/desktop/src/app/shell/statusbar-controls.tsx +23 -33
- package/agent/apps/desktop/src/app/shell/titlebar-controls.tsx +79 -95
- package/agent/apps/desktop/src/app/shell/titlebar.ts +8 -2
- package/agent/apps/desktop/src/app/skills/index.test.tsx +11 -0
- package/agent/apps/desktop/src/app/skills/index.tsx +79 -64
- package/agent/apps/desktop/src/app/types.ts +85 -0
- package/agent/apps/desktop/src/app/updates-overlay.tsx +110 -105
- package/agent/apps/desktop/src/components/assistant-ui/ansi-text.tsx +34 -0
- package/agent/apps/desktop/src/components/assistant-ui/block-direction.test.tsx +129 -0
- package/agent/apps/desktop/src/components/assistant-ui/clarify-tool.tsx +102 -81
- package/agent/apps/desktop/src/components/assistant-ui/directive-text.tsx +92 -15
- package/agent/apps/desktop/src/components/assistant-ui/markdown-text.test.ts +38 -0
- package/agent/apps/desktop/src/components/assistant-ui/markdown-text.tsx +304 -45
- package/agent/apps/desktop/src/components/assistant-ui/message-render-boundary.test.tsx +80 -0
- package/agent/apps/desktop/src/components/assistant-ui/message-render-boundary.tsx +48 -0
- package/agent/apps/desktop/src/components/assistant-ui/streaming.test.tsx +142 -90
- package/agent/apps/desktop/src/components/assistant-ui/thread-list.tsx +337 -0
- package/agent/apps/desktop/src/components/assistant-ui/thread.tsx +667 -190
- package/agent/apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx +299 -0
- package/agent/apps/desktop/src/components/assistant-ui/tool-approval.test.tsx +133 -0
- package/agent/apps/desktop/src/components/assistant-ui/tool-approval.tsx +239 -0
- package/agent/apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts +31 -0
- package/agent/apps/desktop/src/components/assistant-ui/tool-fallback-model.ts +152 -134
- package/agent/apps/desktop/src/components/assistant-ui/tool-fallback.tsx +142 -150
- package/agent/apps/desktop/src/components/assistant-ui/tooltip-icon-button.tsx +14 -12
- package/agent/apps/desktop/src/components/assistant-ui/user-message-edit.test.tsx +141 -0
- package/agent/apps/desktop/src/components/assistant-ui/user-message-text.tsx +152 -0
- package/agent/apps/desktop/src/components/boot-failure-overlay.tsx +150 -33
- package/agent/apps/desktop/src/components/boot-failure-reauth.test.ts +100 -0
- package/agent/apps/desktop/src/components/boot-failure-reauth.ts +81 -0
- package/agent/apps/desktop/src/components/brand-mark.tsx +19 -0
- package/agent/apps/desktop/src/components/chat/code-card.tsx +1 -1
- package/agent/apps/desktop/src/components/chat/composer-dock.ts +31 -0
- package/agent/apps/desktop/src/components/chat/diff-lines.tsx +1 -1
- package/agent/apps/desktop/src/components/chat/disclosure-row.tsx +13 -3
- package/agent/apps/desktop/src/components/chat/expandable-block.tsx +52 -0
- package/agent/apps/desktop/src/components/chat/generated-image-result.tsx +174 -0
- package/agent/apps/desktop/src/components/chat/image-generation-placeholder.tsx +70 -37
- package/agent/apps/desktop/src/components/chat/intro.tsx +8 -7
- package/agent/apps/desktop/src/components/chat/preview-attachment.tsx +4 -2
- package/agent/apps/desktop/src/components/chat/shiki-highlighter.test.ts +37 -0
- package/agent/apps/desktop/src/components/chat/shiki-highlighter.tsx +96 -22
- package/agent/apps/desktop/src/components/chat/status-row.tsx +70 -0
- package/agent/apps/desktop/src/components/chat/status-section.tsx +42 -0
- package/agent/apps/desktop/src/components/chat/terminal-output.tsx +54 -0
- package/agent/apps/desktop/src/components/chat/zoomable-image.tsx +70 -109
- package/agent/apps/desktop/src/components/desktop-install-overlay.tsx +154 -84
- package/agent/apps/desktop/src/components/desktop-onboarding-overlay.test.tsx +38 -8
- package/agent/apps/desktop/src/components/desktop-onboarding-overlay.tsx +789 -233
- package/agent/apps/desktop/src/components/error-boundary.tsx +77 -0
- package/agent/apps/desktop/src/components/gateway-connecting-overlay.test.tsx +144 -0
- package/agent/apps/desktop/src/components/gateway-connecting-overlay.tsx +7 -1
- package/agent/apps/desktop/src/components/haptics-provider.tsx +24 -0
- package/agent/apps/desktop/src/components/language-switcher.test.tsx +53 -0
- package/agent/apps/desktop/src/components/language-switcher.tsx +175 -0
- package/agent/apps/desktop/src/components/model-picker.tsx +42 -40
- package/agent/apps/desktop/src/components/model-visibility-dialog.tsx +166 -0
- package/agent/apps/desktop/src/components/notifications.tsx +48 -27
- package/agent/apps/desktop/src/components/pane-shell/index.ts +1 -1
- package/agent/apps/desktop/src/components/pane-shell/pane-shell.tsx +146 -9
- package/agent/apps/desktop/src/components/prompt-overlays.tsx +234 -0
- package/agent/apps/desktop/src/components/session-picker.tsx +108 -0
- package/agent/apps/desktop/src/components/ui/action-status.tsx +25 -0
- package/agent/apps/desktop/src/components/ui/badge.tsx +35 -0
- package/agent/apps/desktop/src/components/ui/button.tsx +37 -13
- package/agent/apps/desktop/src/components/ui/confirm-dialog.tsx +109 -0
- package/agent/apps/desktop/src/components/ui/control.ts +25 -0
- package/agent/apps/desktop/src/components/ui/copy-button.test.tsx +36 -0
- package/agent/apps/desktop/src/components/ui/copy-button.tsx +38 -27
- package/agent/apps/desktop/src/components/ui/dialog.tsx +39 -11
- package/agent/apps/desktop/src/components/ui/dropdown-menu.tsx +98 -24
- package/agent/apps/desktop/src/components/ui/error-state.tsx +50 -0
- package/agent/apps/desktop/src/components/ui/fade-text.tsx +9 -2
- package/agent/apps/desktop/src/components/ui/{braille-spinner.tsx → glyph-spinner.tsx} +15 -13
- package/agent/apps/desktop/src/components/ui/input.tsx +5 -2
- package/agent/apps/desktop/src/components/ui/kbd.tsx +83 -12
- package/agent/apps/desktop/src/components/ui/log-view.tsx +19 -0
- package/agent/apps/desktop/src/components/ui/pagination.tsx +12 -5
- package/agent/apps/desktop/src/components/ui/popover.tsx +44 -0
- package/agent/apps/desktop/src/components/ui/search-field.tsx +80 -0
- package/agent/apps/desktop/src/components/ui/segmented-control.tsx +51 -0
- package/agent/apps/desktop/src/components/ui/select.tsx +10 -3
- package/agent/apps/desktop/src/components/ui/sheet.tsx +8 -2
- package/agent/apps/desktop/src/components/ui/sidebar.tsx +18 -25
- package/agent/apps/desktop/src/components/ui/switch.tsx +38 -15
- package/agent/apps/desktop/src/components/ui/textarea.tsx +4 -11
- package/agent/apps/desktop/src/components/ui/tool-icon.tsx +65 -0
- package/agent/apps/desktop/src/components/ui/tooltip.tsx +31 -4
- package/agent/apps/desktop/src/fonts/JetBrainsMono-Bold.woff2 +0 -0
- package/agent/apps/desktop/src/fonts/JetBrainsMono-Italic.woff2 +0 -0
- package/agent/apps/desktop/src/fonts/JetBrainsMono-Regular.woff2 +0 -0
- package/agent/apps/desktop/src/global.d.ts +181 -4
- package/agent/apps/desktop/src/hermes.test.ts +60 -0
- package/agent/apps/desktop/src/hermes.ts +190 -13
- package/agent/apps/desktop/src/hooks/use-image-download.ts +85 -0
- package/agent/apps/desktop/src/hooks/use-resize-observer.ts +13 -4
- package/agent/apps/desktop/src/hooks/use-worktree-info.ts +68 -0
- package/agent/apps/desktop/src/i18n/catalog.ts +12 -0
- package/agent/apps/desktop/src/i18n/context.test.tsx +232 -0
- package/agent/apps/desktop/src/i18n/context.tsx +183 -0
- package/agent/apps/desktop/src/i18n/define-locale.ts +41 -0
- package/agent/apps/desktop/src/i18n/en.ts +1921 -0
- package/agent/apps/desktop/src/i18n/index.ts +20 -0
- package/agent/apps/desktop/src/i18n/ja.ts +2053 -0
- package/agent/apps/desktop/src/i18n/languages.test.ts +43 -0
- package/agent/apps/desktop/src/i18n/languages.ts +86 -0
- package/agent/apps/desktop/src/i18n/runtime.test.ts +75 -0
- package/agent/apps/desktop/src/i18n/runtime.ts +53 -0
- package/agent/apps/desktop/src/i18n/types.ts +1559 -0
- package/agent/apps/desktop/src/i18n/zh-hant.ts +1992 -0
- package/agent/apps/desktop/src/i18n/zh.ts +2099 -0
- package/agent/apps/desktop/src/lib/ansi.test.ts +123 -0
- package/agent/apps/desktop/src/lib/ansi.ts +186 -0
- package/agent/apps/desktop/src/lib/chat-messages.test.ts +79 -0
- package/agent/apps/desktop/src/lib/chat-messages.ts +68 -29
- package/agent/apps/desktop/src/lib/chat-runtime.test.ts +65 -1
- package/agent/apps/desktop/src/lib/chat-runtime.ts +39 -3
- package/agent/apps/desktop/src/lib/completion-sound.ts +519 -0
- package/agent/apps/desktop/src/lib/desktop-fs.test.ts +116 -0
- package/agent/apps/desktop/src/lib/desktop-fs.ts +113 -0
- package/agent/apps/desktop/src/lib/desktop-slash-commands.test.ts +89 -6
- package/agent/apps/desktop/src/lib/desktop-slash-commands.ts +270 -131
- package/agent/apps/desktop/src/lib/external-link.test.tsx +27 -0
- package/agent/apps/desktop/src/lib/external-link.tsx +9 -2
- package/agent/apps/desktop/src/lib/gateway-events.test.ts +27 -0
- package/agent/apps/desktop/src/lib/gateway-events.ts +16 -0
- package/agent/apps/desktop/src/lib/gateway-ws-url.test.ts +78 -0
- package/agent/apps/desktop/src/lib/gateway-ws-url.ts +91 -0
- package/agent/apps/desktop/src/lib/generated-images.test.ts +97 -0
- package/agent/apps/desktop/src/lib/generated-images.ts +116 -0
- package/agent/apps/desktop/src/lib/haptics.ts +17 -0
- package/agent/apps/desktop/src/lib/icons.ts +10 -2
- package/agent/apps/desktop/src/lib/keybinds/actions.ts +137 -0
- package/agent/apps/desktop/src/lib/keybinds/combo.test.ts +86 -0
- package/agent/apps/desktop/src/lib/keybinds/combo.ts +195 -0
- package/agent/apps/desktop/src/lib/local-preview.ts +23 -2
- package/agent/apps/desktop/src/lib/markdown-preprocess.ts +20 -7
- package/agent/apps/desktop/src/lib/media.remote.test.ts +90 -0
- package/agent/apps/desktop/src/lib/media.ts +40 -1
- package/agent/apps/desktop/src/lib/model-status-label.test.ts +59 -0
- package/agent/apps/desktop/src/lib/model-status-label.ts +122 -0
- package/agent/apps/desktop/src/lib/mutable-ref.ts +6 -0
- package/agent/apps/desktop/src/lib/profile-color.ts +58 -0
- package/agent/apps/desktop/src/lib/query-client.ts +13 -0
- package/agent/apps/desktop/src/lib/remend-tail.test.ts +105 -0
- package/agent/apps/desktop/src/lib/remend-tail.ts +108 -0
- package/agent/apps/desktop/src/lib/session-export.ts +6 -3
- package/agent/apps/desktop/src/lib/session-ids.test.ts +44 -0
- package/agent/apps/desktop/src/lib/session-ids.ts +26 -0
- package/agent/apps/desktop/src/lib/session-search.test.ts +66 -0
- package/agent/apps/desktop/src/lib/session-search.ts +21 -0
- package/agent/apps/desktop/src/lib/session-source.ts +126 -0
- package/agent/apps/desktop/src/lib/storage.test.ts +25 -0
- package/agent/apps/desktop/src/lib/storage.ts +35 -1
- package/agent/apps/desktop/src/lib/todos.test.ts +46 -1
- package/agent/apps/desktop/src/lib/todos.ts +37 -0
- package/agent/apps/desktop/src/lib/tool-result-summary.ts +5 -1
- package/agent/apps/desktop/src/lib/update-copy.test.ts +38 -0
- package/agent/apps/desktop/src/lib/update-copy.ts +44 -0
- package/agent/apps/desktop/src/lib/use-enter-animation.ts +2 -2
- package/agent/apps/desktop/src/lib/yolo-session.ts +50 -0
- package/agent/apps/desktop/src/main.tsx +19 -19
- package/agent/apps/desktop/src/store/boot.ts +4 -3
- package/agent/apps/desktop/src/store/clarify.test.ts +81 -0
- package/agent/apps/desktop/src/store/clarify.ts +50 -13
- package/agent/apps/desktop/src/store/command-palette.ts +20 -0
- package/agent/apps/desktop/src/store/compaction.test.ts +53 -0
- package/agent/apps/desktop/src/store/compaction.ts +38 -0
- package/agent/apps/desktop/src/store/completion-sound.ts +32 -0
- package/agent/apps/desktop/src/store/composer-input-history.test.ts +147 -0
- package/agent/apps/desktop/src/store/composer-input-history.ts +158 -0
- package/agent/apps/desktop/src/store/composer-queue.test.ts +68 -0
- package/agent/apps/desktop/src/store/composer-queue.ts +76 -0
- package/agent/apps/desktop/src/store/composer-status.test.ts +99 -0
- package/agent/apps/desktop/src/store/composer-status.ts +277 -0
- package/agent/apps/desktop/src/store/composer.test.ts +106 -0
- package/agent/apps/desktop/src/store/composer.ts +116 -0
- package/agent/apps/desktop/src/store/cron.ts +19 -0
- package/agent/apps/desktop/src/store/gateway.ts +280 -6
- package/agent/apps/desktop/src/store/keybinds.ts +143 -0
- package/agent/apps/desktop/src/store/layout.ts +107 -9
- package/agent/apps/desktop/src/store/model-presets.test.ts +51 -0
- package/agent/apps/desktop/src/store/model-presets.ts +86 -0
- package/agent/apps/desktop/src/store/model-visibility.test.ts +99 -0
- package/agent/apps/desktop/src/store/model-visibility.ts +161 -0
- package/agent/apps/desktop/src/store/native-notifications.test.ts +192 -0
- package/agent/apps/desktop/src/store/native-notifications.ts +203 -0
- package/agent/apps/desktop/src/store/notifications.ts +10 -7
- package/agent/apps/desktop/src/store/onboarding.test.ts +271 -1
- package/agent/apps/desktop/src/store/onboarding.ts +268 -38
- package/agent/apps/desktop/src/store/preview.ts +10 -1
- package/agent/apps/desktop/src/store/profile.test.ts +89 -0
- package/agent/apps/desktop/src/store/profile.ts +395 -0
- package/agent/apps/desktop/src/store/prompts.test.ts +127 -0
- package/agent/apps/desktop/src/store/prompts.ts +117 -0
- package/agent/apps/desktop/src/store/session-switcher.test.ts +115 -0
- package/agent/apps/desktop/src/store/session-switcher.ts +128 -0
- package/agent/apps/desktop/src/store/session-sync.ts +25 -0
- package/agent/apps/desktop/src/store/session.test.ts +268 -2
- package/agent/apps/desktop/src/store/session.ts +392 -18
- package/agent/apps/desktop/src/store/subagents.ts +3 -0
- package/agent/apps/desktop/src/store/system-actions.ts +48 -0
- package/agent/apps/desktop/src/store/thread-scroll.ts +58 -5
- package/agent/apps/desktop/src/store/todos.test.ts +47 -0
- package/agent/apps/desktop/src/store/todos.ts +64 -0
- package/agent/apps/desktop/src/store/tool-dismiss.ts +45 -0
- package/agent/apps/desktop/src/store/translucency.ts +38 -0
- package/agent/apps/desktop/src/store/updates.test.ts +187 -2
- package/agent/apps/desktop/src/store/updates.ts +268 -18
- package/agent/apps/desktop/src/store/windows.test.ts +143 -0
- package/agent/apps/desktop/src/store/windows.ts +115 -0
- package/agent/apps/desktop/src/styles.css +510 -119
- package/agent/apps/desktop/src/themes/color.ts +142 -0
- package/agent/apps/desktop/src/themes/context.tsx +128 -75
- package/agent/apps/desktop/src/themes/install.test.ts +119 -0
- package/agent/apps/desktop/src/themes/install.ts +95 -0
- package/agent/apps/desktop/src/themes/presets.test.ts +33 -0
- package/agent/apps/desktop/src/themes/presets.ts +13 -4
- package/agent/apps/desktop/src/themes/profile-theme.test.ts +41 -0
- package/agent/apps/desktop/src/themes/types.ts +35 -0
- package/agent/apps/desktop/src/themes/user-themes.test.ts +63 -0
- package/agent/apps/desktop/src/themes/user-themes.ts +122 -0
- package/agent/apps/desktop/src/themes/vscode.test.ts +171 -0
- package/agent/apps/desktop/src/themes/vscode.ts +343 -0
- package/agent/apps/desktop/src/types/hermes.ts +138 -1
- package/agent/apps/desktop/tsconfig.json +2 -2
- package/agent/apps/desktop/vite.config.ts +18 -0
- package/agent/apps/shared/package.json +1 -1
- package/agent/apps/shared/src/json-rpc-gateway.ts +63 -2
- package/agent/apps/shared/tsconfig.json +2 -2
- package/agent/cli-config.yaml.example +78 -1
- package/agent/cli.py +2177 -3162
- package/agent/cron/blueprint_catalog.py +713 -0
- package/agent/cron/jobs.py +226 -110
- package/agent/cron/scheduler.py +468 -193
- package/agent/cron/scheduler_provider.py +177 -0
- package/agent/cron/scripts/__init__.py +1 -0
- package/agent/cron/scripts/classify_items.py +226 -0
- package/agent/cron/suggestion_catalog.py +154 -0
- package/agent/cron/suggestions.py +257 -0
- package/agent/docs/chronos-managed-cron-contract.md +196 -0
- package/agent/docs/design/profile-builder.md +146 -0
- package/agent/docs/middleware/README.md +260 -0
- package/agent/docs/observability/README.md +316 -0
- package/agent/docs/plans/2026-06-09-003-fix-telegram-stream-overflow-continuations-plan.md +240 -0
- package/agent/docs/rca-ssl-cacert-post-git-pull.md +54 -0
- package/agent/docs/relay-connector-contract.md +285 -0
- package/agent/gateway/authz_mixin.py +536 -0
- package/agent/gateway/channel_directory.py +65 -3
- package/agent/gateway/config.py +222 -12
- package/agent/gateway/display_config.py +10 -0
- package/agent/gateway/hooks.py +17 -0
- package/agent/gateway/kanban_watchers.py +1146 -0
- package/agent/gateway/message_timestamps.py +166 -0
- package/agent/gateway/platforms/ADDING_A_PLATFORM.md +29 -0
- package/agent/gateway/platforms/api_server.py +216 -38
- package/agent/gateway/platforms/base.py +210 -58
- package/agent/gateway/platforms/email.py +122 -12
- package/agent/gateway/platforms/feishu.py +80 -11
- package/agent/gateway/platforms/feishu_meeting_invite.py +212 -0
- package/agent/gateway/platforms/matrix.py +1498 -297
- package/agent/gateway/platforms/qqbot/adapter.py +6 -0
- package/agent/gateway/platforms/signal.py +8 -0
- package/agent/gateway/platforms/slack.py +308 -12
- package/agent/gateway/platforms/telegram.py +831 -24
- package/agent/gateway/platforms/webhook.py +109 -21
- package/agent/gateway/platforms/weixin.py +113 -2
- package/agent/gateway/platforms/whatsapp.py +94 -288
- package/agent/gateway/platforms/whatsapp_cloud.py +1956 -0
- package/agent/gateway/platforms/whatsapp_common.py +367 -0
- package/agent/gateway/platforms/yuanbao.py +608 -191
- package/agent/gateway/platforms/yuanbao_proto.py +232 -23
- package/agent/gateway/relay/__init__.py +375 -0
- package/agent/gateway/relay/adapter.py +222 -0
- package/agent/gateway/relay/auth.py +168 -0
- package/agent/gateway/relay/descriptor.py +118 -0
- package/agent/gateway/relay/transport.py +101 -0
- package/agent/gateway/relay/ws_transport.py +327 -0
- package/agent/gateway/response_filters.py +53 -0
- package/agent/gateway/rich_sent_store.py +80 -0
- package/agent/gateway/run.py +2940 -5001
- package/agent/gateway/session.py +109 -8
- package/agent/gateway/session_context.py +22 -4
- package/agent/gateway/slash_commands.py +3854 -0
- package/agent/gateway/status.py +141 -21
- package/agent/gateway/stream_consumer.py +288 -31
- package/agent/hermes-already-has-routines.md +1 -1
- package/agent/hermes_cli/__init__.py +62 -17
- package/agent/hermes_cli/_parser.py +30 -0
- package/agent/hermes_cli/_subprocess_compat.py +61 -0
- package/agent/hermes_cli/active_sessions.py +320 -0
- package/agent/hermes_cli/auth.py +707 -59
- package/agent/hermes_cli/auth_commands.py +39 -22
- package/agent/hermes_cli/backup.py +109 -7
- package/agent/hermes_cli/banner.py +88 -0
- package/agent/hermes_cli/blueprint_cmd.py +318 -0
- package/agent/hermes_cli/cli_agent_setup_mixin.py +684 -0
- package/agent/hermes_cli/cli_commands_mixin.py +2293 -0
- package/agent/hermes_cli/commands.py +215 -91
- package/agent/hermes_cli/config.py +967 -130
- package/agent/hermes_cli/container_boot.py +76 -11
- package/agent/hermes_cli/cron.py +5 -11
- package/agent/hermes_cli/curator.py +21 -0
- package/agent/hermes_cli/dashboard_auth/__init__.py +2 -0
- package/agent/hermes_cli/dashboard_auth/base.py +62 -0
- package/agent/hermes_cli/dashboard_auth/cookies.py +32 -19
- package/agent/hermes_cli/dashboard_auth/login_page.py +156 -6
- package/agent/hermes_cli/dashboard_auth/middleware.py +28 -4
- package/agent/hermes_cli/dashboard_auth/prefix.py +46 -2
- package/agent/hermes_cli/dashboard_auth/public_paths.py +6 -0
- package/agent/hermes_cli/dashboard_auth/routes.py +158 -2
- package/agent/hermes_cli/dashboard_auth/ws_tickets.py +85 -11
- package/agent/hermes_cli/dashboard_register.py +427 -0
- package/agent/hermes_cli/debug.py +155 -50
- package/agent/hermes_cli/doctor.py +255 -14
- package/agent/hermes_cli/dump.py +60 -6
- package/agent/hermes_cli/env_loader.py +33 -0
- package/agent/hermes_cli/gateway.py +755 -103
- package/agent/hermes_cli/gateway_enroll.py +250 -0
- package/agent/hermes_cli/gateway_windows.py +254 -11
- package/agent/hermes_cli/gui_uninstall.py +285 -0
- package/agent/hermes_cli/inventory.py +105 -4
- package/agent/hermes_cli/kanban.py +58 -71
- package/agent/hermes_cli/kanban_db.py +391 -14
- package/agent/hermes_cli/kanban_decompose.py +2 -2
- package/agent/hermes_cli/kanban_specify.py +3 -1
- package/agent/hermes_cli/logs.py +2 -0
- package/agent/hermes_cli/main.py +2889 -5287
- package/agent/hermes_cli/managed_scope.py +214 -0
- package/agent/hermes_cli/managed_uv.py +254 -0
- package/agent/hermes_cli/mcp_catalog.py +6 -3
- package/agent/hermes_cli/mcp_config.py +145 -21
- package/agent/hermes_cli/mcp_security.py +96 -0
- package/agent/hermes_cli/mcp_startup.py +32 -3
- package/agent/hermes_cli/memory_providers.py +149 -0
- package/agent/hermes_cli/memory_setup.py +97 -42
- package/agent/hermes_cli/middleware.py +313 -0
- package/agent/hermes_cli/model_catalog.py +31 -0
- package/agent/hermes_cli/model_cost_guard.py +134 -0
- package/agent/hermes_cli/model_normalize.py +2 -1
- package/agent/hermes_cli/model_setup_flows.py +2759 -0
- package/agent/hermes_cli/model_switch.py +242 -27
- package/agent/hermes_cli/models.py +284 -44
- package/agent/hermes_cli/nous_account.py +33 -6
- package/agent/hermes_cli/nous_billing.py +406 -0
- package/agent/hermes_cli/nous_subscription.py +202 -5
- package/agent/hermes_cli/platforms.py +1 -0
- package/agent/hermes_cli/plugins.py +218 -18
- package/agent/hermes_cli/plugins_cmd.py +249 -105
- package/agent/hermes_cli/portal_cli.py +56 -16
- package/agent/hermes_cli/profile_distribution.py +6 -1
- package/agent/hermes_cli/profiles.py +283 -32
- package/agent/hermes_cli/provider_catalog.py +170 -0
- package/agent/hermes_cli/providers.py +4 -1
- package/agent/hermes_cli/pty_bridge.py +53 -4
- package/agent/hermes_cli/runtime_provider.py +216 -34
- package/agent/hermes_cli/secret_prompt.py +4 -4
- package/agent/hermes_cli/secrets_cli.py +24 -0
- package/agent/hermes_cli/send_cmd.py +28 -2
- package/agent/hermes_cli/service_manager.py +166 -19
- package/agent/hermes_cli/session_listing.py +97 -0
- package/agent/hermes_cli/setup.py +158 -94
- package/agent/hermes_cli/setup_whatsapp_cloud.py +541 -0
- package/agent/hermes_cli/skills_config.py +8 -2
- package/agent/hermes_cli/skills_hub.py +149 -7
- package/agent/hermes_cli/status.py +2 -2
- package/agent/hermes_cli/subcommands/__init__.py +18 -0
- package/agent/hermes_cli/subcommands/_shared.py +29 -0
- package/agent/hermes_cli/subcommands/acp.py +52 -0
- package/agent/hermes_cli/subcommands/auth.py +109 -0
- package/agent/hermes_cli/subcommands/backup.py +38 -0
- package/agent/hermes_cli/subcommands/claw.py +92 -0
- package/agent/hermes_cli/subcommands/config.py +49 -0
- package/agent/hermes_cli/subcommands/cron.py +163 -0
- package/agent/hermes_cli/subcommands/dashboard.py +143 -0
- package/agent/hermes_cli/subcommands/debug.py +77 -0
- package/agent/hermes_cli/subcommands/doctor.py +35 -0
- package/agent/hermes_cli/subcommands/dump.py +28 -0
- package/agent/hermes_cli/subcommands/gateway.py +332 -0
- package/agent/hermes_cli/subcommands/gui.py +63 -0
- package/agent/hermes_cli/subcommands/hooks.py +77 -0
- package/agent/hermes_cli/subcommands/import_cmd.py +31 -0
- package/agent/hermes_cli/subcommands/insights.py +25 -0
- package/agent/hermes_cli/subcommands/login.py +78 -0
- package/agent/hermes_cli/subcommands/logout.py +28 -0
- package/agent/hermes_cli/subcommands/logs.py +78 -0
- package/agent/hermes_cli/subcommands/mcp.py +108 -0
- package/agent/hermes_cli/subcommands/memory.py +53 -0
- package/agent/hermes_cli/subcommands/model.py +72 -0
- package/agent/hermes_cli/subcommands/pairing.py +36 -0
- package/agent/hermes_cli/subcommands/plugins.py +94 -0
- package/agent/hermes_cli/subcommands/postinstall.py +23 -0
- package/agent/hermes_cli/subcommands/profile.py +203 -0
- package/agent/hermes_cli/subcommands/prompt_size.py +36 -0
- package/agent/hermes_cli/subcommands/security.py +62 -0
- package/agent/hermes_cli/subcommands/setup.py +58 -0
- package/agent/hermes_cli/subcommands/skills.py +298 -0
- package/agent/hermes_cli/subcommands/slack.py +60 -0
- package/agent/hermes_cli/subcommands/status.py +28 -0
- package/agent/hermes_cli/subcommands/tools.py +95 -0
- package/agent/hermes_cli/subcommands/uninstall.py +41 -0
- package/agent/hermes_cli/subcommands/update.py +70 -0
- package/agent/hermes_cli/subcommands/version.py +18 -0
- package/agent/hermes_cli/subcommands/webhook.py +76 -0
- package/agent/hermes_cli/subcommands/whatsapp.py +22 -0
- package/agent/hermes_cli/suggestions_cmd.py +153 -0
- package/agent/hermes_cli/telegram_managed_bot.py +358 -0
- package/agent/hermes_cli/tips.py +3 -4
- package/agent/hermes_cli/tools_config.py +155 -28
- package/agent/hermes_cli/uninstall.py +231 -35
- package/agent/hermes_cli/web_server.py +6190 -973
- package/agent/hermes_cli/win_pty_bridge.py +179 -0
- package/agent/hermes_cli/write_approval_commands.py +209 -0
- package/agent/hermes_constants.py +164 -33
- package/agent/hermes_logging.py +74 -2
- package/agent/hermes_state.py +919 -106
- package/agent/hermes_time.py +20 -0
- package/agent/locales/af.yaml +23 -0
- package/agent/locales/de.yaml +23 -0
- package/agent/locales/en.yaml +20 -0
- package/agent/locales/es.yaml +23 -0
- package/agent/locales/fr.yaml +23 -0
- package/agent/locales/ga.yaml +23 -0
- package/agent/locales/hu.yaml +23 -0
- package/agent/locales/it.yaml +23 -0
- package/agent/locales/ja.yaml +23 -0
- package/agent/locales/ko.yaml +23 -0
- package/agent/locales/pt.yaml +23 -0
- package/agent/locales/ru.yaml +23 -0
- package/agent/locales/tr.yaml +23 -0
- package/agent/locales/uk.yaml +23 -0
- package/agent/locales/zh-hant.yaml +23 -0
- package/agent/locales/zh.yaml +23 -0
- package/agent/model_tools.py +204 -40
- package/agent/optional-mcps/clawpump/manifest.yaml +4 -2
- package/agent/optional-mcps/clawpump-stdio/manifest.yaml +2 -0
- package/agent/optional-mcps/unreal-engine/manifest.yaml +54 -0
- package/agent/optional-skills/blockchain/hyperliquid/SKILL.md +2 -2
- package/agent/optional-skills/blockchain/hyperliquid/scripts/hyperliquid_client.py +1 -1
- package/agent/optional-skills/creative/kanban-video-orchestrator/SKILL.md +1 -1
- package/agent/optional-skills/creative/kanban-video-orchestrator/assets/setup.sh.tmpl +4 -3
- package/agent/optional-skills/creative/kanban-video-orchestrator/references/kanban-setup.md +6 -4
- package/agent/optional-skills/creative/kanban-video-orchestrator/references/tool-matrix.md +2 -2
- package/agent/{skills/software-development → optional-skills/devops}/hermes-s6-container-supervision/SKILL.md +2 -0
- package/agent/optional-skills/devops/watchers/SKILL.md +1 -1
- package/agent/optional-skills/devops/watchers/scripts/watch_github.py +2 -1
- package/agent/optional-skills/payments/mpp-agent/SKILL.md +124 -0
- package/agent/optional-skills/payments/stripe-link-cli/SKILL.md +184 -0
- package/agent/optional-skills/payments/stripe-projects/SKILL.md +120 -0
- package/agent/optional-skills/productivity/canvas/SKILL.md +1 -1
- package/agent/optional-skills/productivity/canvas/scripts/canvas_api.py +4 -1
- package/agent/optional-skills/productivity/shop/SKILL.md +224 -0
- package/agent/optional-skills/productivity/shop/references/catalog-mcp.md +236 -0
- package/agent/optional-skills/productivity/shop/references/direct-api.md +278 -0
- package/agent/optional-skills/productivity/shop/references/legal.md +3 -0
- package/agent/optional-skills/productivity/shop/references/safety.md +36 -0
- package/agent/optional-skills/productivity/shopify/SKILL.md +1 -1
- package/agent/optional-skills/productivity/siyuan/SKILL.md +1 -1
- package/agent/optional-skills/productivity/telephony/SKILL.md +4 -4
- package/agent/optional-skills/productivity/telephony/scripts/telephony.py +15 -15
- package/agent/optional-skills/security/1password/SKILL.md +1 -1
- package/agent/{skills/red-teaming → optional-skills/security}/godmode/SKILL.md +3 -4
- package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/auto_jailbreak.py +3 -1
- package/agent/optional-skills/software-development/rest-graphql-debug/SKILL.md +1 -1
- package/agent/{skills → optional-skills}/software-development/subagent-driven-development/SKILL.md +5 -5
- package/agent/package-lock.json +4082 -7907
- package/agent/package.json +18 -3
- package/agent/plugins/browser/firecrawl/provider.py +4 -1
- package/agent/plugins/cron/__init__.py +344 -0
- package/agent/plugins/cron/chronos/__init__.py +241 -0
- package/agent/plugins/cron/chronos/_nas_client.py +123 -0
- package/agent/plugins/cron/chronos/plugin.yaml +9 -0
- package/agent/plugins/cron/chronos/verify.py +103 -0
- package/agent/plugins/dashboard_auth/basic/__init__.py +491 -0
- package/agent/plugins/dashboard_auth/basic/plugin.yaml +7 -0
- package/agent/plugins/dashboard_auth/nous/__init__.py +12 -14
- package/agent/plugins/dashboard_auth/self_hosted/__init__.py +736 -0
- package/agent/plugins/dashboard_auth/self_hosted/plugin.yaml +8 -0
- package/agent/plugins/disk-cleanup/disk_cleanup.py +100 -20
- package/agent/plugins/google_meet/audio_bridge.py +4 -0
- package/agent/plugins/google_meet/meet_bot.py +7 -1
- package/agent/plugins/hermes-achievements/dashboard/dist/index.js +9 -15
- package/agent/plugins/image_gen/fal/__init__.py +35 -6
- package/agent/plugins/image_gen/krea/__init__.py +56 -13
- package/agent/plugins/image_gen/openai/__init__.py +122 -24
- package/agent/plugins/image_gen/openai-codex/__init__.py +28 -2
- package/agent/plugins/image_gen/xai/__init__.py +92 -12
- package/agent/plugins/kanban/dashboard/dist/index.js +63 -48
- package/agent/plugins/kanban/dashboard/plugin_api.py +39 -35
- package/agent/plugins/memory/__init__.py +48 -5
- package/agent/plugins/memory/byterover/__init__.py +1 -0
- package/agent/plugins/memory/hindsight/README.md +1 -1
- package/agent/plugins/memory/hindsight/__init__.py +138 -24
- package/agent/plugins/memory/hindsight/plugin.yaml +1 -1
- package/agent/plugins/memory/honcho/README.md +13 -10
- package/agent/plugins/memory/honcho/cli.py +247 -122
- package/agent/plugins/memory/honcho/client.py +112 -102
- package/agent/plugins/memory/openviking/README.md +12 -1
- package/agent/plugins/memory/openviking/__init__.py +2281 -107
- package/agent/plugins/memory/openviking/plugin.yaml +1 -2
- package/agent/plugins/memory/supermemory/README.md +22 -10
- package/agent/plugins/memory/supermemory/__init__.py +142 -37
- package/agent/plugins/memory/supermemory/plugin.yaml +1 -1
- package/agent/plugins/model-providers/anthropic/__init__.py +1 -0
- package/agent/plugins/model-providers/bedrock/__init__.py +1 -0
- package/agent/plugins/model-providers/copilot-acp/__init__.py +1 -0
- package/agent/plugins/model-providers/custom/__init__.py +8 -2
- package/agent/plugins/model-providers/kimi-coding/__init__.py +16 -7
- package/agent/plugins/model-providers/minimax/__init__.py +60 -8
- package/agent/plugins/model-providers/opencode-zen/__init__.py +12 -3
- package/agent/plugins/model-providers/openrouter/__init__.py +75 -4
- package/agent/plugins/model-providers/xiaomi/__init__.py +2 -0
- package/agent/plugins/model-providers/zai/__init__.py +1 -0
- package/agent/plugins/observability/langfuse/__init__.py +147 -14
- package/agent/plugins/observability/nemo_relay/README.md +559 -0
- package/agent/plugins/observability/nemo_relay/__init__.py +962 -0
- package/agent/plugins/observability/nemo_relay/plugin.yaml +20 -0
- package/agent/plugins/platforms/discord/adapter.py +932 -61
- package/agent/plugins/platforms/discord/voice_mixer.py +379 -0
- package/agent/plugins/platforms/google_chat/adapter.py +9 -3
- package/agent/plugins/platforms/google_chat/oauth.py +1 -1
- package/agent/plugins/platforms/homeassistant/__init__.py +3 -0
- package/agent/{gateway/platforms/homeassistant.py → plugins/platforms/homeassistant/adapter.py} +128 -0
- package/agent/plugins/platforms/homeassistant/plugin.yaml +22 -0
- package/agent/plugins/platforms/irc/adapter.py +4 -1
- package/agent/plugins/platforms/line/adapter.py +16 -1
- package/agent/plugins/platforms/mattermost/adapter.py +100 -24
- package/agent/plugins/platforms/photon/README.md +179 -0
- package/agent/plugins/platforms/photon/__init__.py +4 -0
- package/agent/plugins/platforms/photon/adapter.py +1586 -0
- package/agent/plugins/platforms/photon/auth.py +1046 -0
- package/agent/plugins/platforms/photon/cli.py +439 -0
- package/agent/plugins/platforms/photon/plugin.yaml +88 -0
- package/agent/plugins/platforms/photon/sidecar/README.md +52 -0
- package/agent/plugins/platforms/photon/sidecar/index.mjs +720 -0
- package/agent/plugins/platforms/photon/sidecar/package-lock.json +1730 -0
- package/agent/plugins/platforms/photon/sidecar/package.json +25 -0
- package/agent/plugins/platforms/photon/sidecar/patch-spectrum-mixed-attachments.mjs +155 -0
- package/agent/plugins/platforms/raft/__init__.py +3 -0
- package/agent/plugins/platforms/raft/adapter.py +774 -0
- package/agent/plugins/platforms/raft/plugin.yaml +19 -0
- package/agent/plugins/platforms/simplex/adapter.py +777 -220
- package/agent/plugins/platforms/simplex/plugin.yaml +21 -2
- package/agent/plugins/platforms/teams/adapter.py +175 -5
- package/agent/plugins/plugin_utils.py +135 -0
- package/agent/plugins/video_gen/fal/__init__.py +10 -3
- package/agent/plugins/web/searxng/provider.py +15 -2
- package/agent/plugins/web/xai/provider.py +2 -2
- package/agent/providers/base.py +22 -3
- package/agent/pyproject.toml +115 -21
- package/agent/run_agent.py +733 -39
- package/agent/scripts/build_skills_index.py +51 -19
- package/agent/scripts/check_subprocess_stdin.py +177 -0
- package/agent/scripts/contributor_audit.py +2 -0
- package/agent/scripts/docker_config_migrate.py +67 -0
- package/agent/scripts/install.cmd +3 -3
- package/agent/scripts/install.ps1 +580 -154
- package/agent/scripts/install.sh +402 -185
- package/agent/scripts/lib/node-bootstrap.sh +39 -4
- package/agent/scripts/release.py +183 -0
- package/agent/scripts/run_tests.sh +1 -0
- package/agent/scripts/run_tests_parallel.py +18 -23
- package/agent/scripts/whatsapp-bridge/bridge.js +25 -4
- package/agent/setup.py +59 -0
- package/agent/skills/autonomous-ai-agents/codex/SKILL.md +19 -0
- package/agent/skills/autonomous-ai-agents/hermes-agent/SKILL.md +10 -3
- package/agent/skills/{mcp/native-mcp/SKILL.md → autonomous-ai-agents/hermes-agent/references/native-mcp.md} +0 -13
- package/agent/skills/{devops/webhook-subscriptions/SKILL.md → autonomous-ai-agents/hermes-agent/references/webhooks.md} +1 -11
- package/agent/skills/clawpump/SKILL.md +4 -1
- package/agent/skills/devops/kanban-orchestrator/SKILL.md +1 -0
- package/agent/skills/devops/kanban-worker/SKILL.md +1 -0
- package/agent/skills/github/github-auth/SKILL.md +2 -2
- package/agent/skills/github/github-auth/scripts/gh-env.sh +2 -2
- package/agent/skills/github/github-code-review/SKILL.md +2 -2
- package/agent/skills/github/github-issues/SKILL.md +2 -2
- package/agent/skills/github/github-pr-workflow/SKILL.md +2 -2
- package/agent/skills/github/github-repo-management/SKILL.md +2 -2
- package/agent/skills/media/gif-search/SKILL.md +1 -1
- package/agent/skills/media/youtube-content/SKILL.md +10 -7
- package/agent/skills/media/youtube-content/scripts/fetch_transcript.py +3 -3
- package/agent/skills/note-taking/obsidian/SKILL.md +1 -1
- package/agent/skills/productivity/airtable/SKILL.md +2 -2
- package/agent/skills/productivity/google-workspace/scripts/setup.py +33 -7
- package/agent/skills/productivity/notion/SKILL.md +2 -2
- package/agent/skills/productivity/teams-meeting-pipeline/SKILL.md +1 -1
- package/agent/skills/research/llm-wiki/SKILL.md +1 -1
- package/agent/skills/social-media/xurl/SKILL.md +9 -0
- package/agent/skills/software-development/hermes-agent-skill-authoring/SKILL.md +1 -1
- package/agent/skills/software-development/plan/SKILL.md +285 -5
- package/agent/skills/software-development/requesting-code-review/SKILL.md +2 -2
- package/agent/skills/software-development/simplify-code/SKILL.md +212 -0
- package/agent/skills/software-development/spike/SKILL.md +2 -2
- package/agent/skills/software-development/systematic-debugging/SKILL.md +1 -1
- package/agent/skills/software-development/test-driven-development/SKILL.md +1 -1
- package/agent/tools/approval.py +302 -4
- package/agent/tools/async_delegation.py +386 -0
- package/agent/tools/blueprints.py +325 -0
- package/agent/tools/browser_cdp_tool.py +3 -3
- package/agent/tools/browser_tool.py +34 -6
- package/agent/tools/checkpoint_manager.py +31 -1
- package/agent/tools/clarify_tool.py +55 -5
- package/agent/tools/code_execution_tool.py +31 -14
- package/agent/tools/computer_use/cua_backend.py +81 -3
- package/agent/tools/computer_use/tool.py +79 -5
- package/agent/tools/computer_use/vision_routing.py +55 -3
- package/agent/tools/credential_files.py +31 -12
- package/agent/tools/cronjob_tools.py +30 -20
- package/agent/tools/delegate_tool.py +356 -31
- package/agent/tools/env_probe.py +1 -0
- package/agent/tools/environments/docker.py +163 -8
- package/agent/tools/environments/file_sync.py +2 -1
- package/agent/tools/environments/local.py +74 -23
- package/agent/tools/environments/singularity.py +4 -1
- package/agent/tools/environments/ssh.py +78 -11
- package/agent/tools/file_operations.py +277 -41
- package/agent/tools/file_tools.py +166 -28
- package/agent/tools/image_generation_tool.py +515 -29
- package/agent/tools/kanban_tools.py +99 -0
- package/agent/tools/lazy_deps.py +33 -2
- package/agent/tools/mcp_oauth.py +5 -5
- package/agent/tools/mcp_oauth_manager.py +7 -5
- package/agent/tools/mcp_tool.py +840 -33
- package/agent/tools/memory_tool.py +335 -38
- package/agent/tools/osv_check.py +15 -1
- package/agent/tools/process_registry.py +155 -11
- package/agent/tools/read_extract.py +248 -0
- package/agent/tools/read_terminal_tool.py +93 -0
- package/agent/tools/schema_sanitizer.py +38 -0
- package/agent/tools/send_message_tool.py +163 -49
- package/agent/tools/session_search_tool.py +189 -7
- package/agent/tools/skill_manager_tool.py +202 -3
- package/agent/tools/skill_usage.py +52 -4
- package/agent/tools/skills_hub.py +184 -44
- package/agent/tools/skills_sync.py +232 -5
- package/agent/tools/skills_tool.py +125 -11
- package/agent/tools/terminal_tool.py +148 -26
- package/agent/tools/tirith_security.py +2 -0
- package/agent/tools/todo_tool.py +32 -1
- package/agent/tools/transcription_tools.py +13 -5
- package/agent/tools/tts_tool.py +332 -38
- package/agent/tools/url_safety.py +52 -1
- package/agent/tools/vision_tools.py +124 -39
- package/agent/tools/voice_mode.py +4 -3
- package/agent/tools/web_tools.py +45 -15
- package/agent/tools/write_approval.py +493 -0
- package/agent/toolsets.py +34 -10
- package/agent/trajectory_compressor.py +81 -10
- package/agent/tui_gateway/entry.py +43 -6
- package/agent/tui_gateway/server.py +3335 -330
- package/agent/tui_gateway/slash_worker.py +61 -0
- package/agent/tui_gateway/ws.py +67 -9
- package/agent/ui-tui/eslint.config.mjs +0 -4
- package/agent/ui-tui/package.json +6 -6
- package/agent/ui-tui/packages/hermes-ink/package.json +1 -1
- package/agent/ui-tui/packages/hermes-ink/src/ink/app-mouse.test.ts +34 -1
- package/agent/ui-tui/packages/hermes-ink/src/ink/app-rawmode-mouse.test.ts +91 -0
- package/agent/ui-tui/packages/hermes-ink/src/ink/components/App.tsx +35 -2
- package/agent/ui-tui/packages/hermes-ink/src/ink/events/input-event.ts +4 -11
- package/agent/ui-tui/packages/hermes-ink/src/ink/parse-keypress.test.ts +23 -57
- package/agent/ui-tui/packages/hermes-ink/src/ink/parse-keypress.ts +11 -135
- package/agent/ui-tui/packages/hermes-ink/src/ink/termio/tokenize.test.ts +185 -0
- package/agent/ui-tui/packages/hermes-ink/src/ink/termio/tokenize.ts +37 -3
- package/agent/ui-tui/packages/hermes-ink/src/utils/execFileNoThrow.ts +5 -5
- package/agent/ui-tui/src/__tests__/appChromeStatusRule.test.tsx +217 -0
- package/agent/ui-tui/src/__tests__/appChromeStatusRuleDevCredits.test.tsx +73 -0
- package/agent/ui-tui/src/__tests__/approvalAction.test.ts +11 -0
- package/agent/ui-tui/src/__tests__/billingCommand.test.ts +301 -0
- package/agent/ui-tui/src/__tests__/blockLayout.test.ts +122 -0
- package/agent/ui-tui/src/__tests__/brandingMcpCount.test.ts +111 -0
- package/agent/ui-tui/src/__tests__/completionApply.test.ts +51 -0
- package/agent/ui-tui/src/__tests__/createGatewayEventHandler.test.ts +487 -2
- package/agent/ui-tui/src/__tests__/createSlashHandler.test.ts +54 -0
- package/agent/ui-tui/src/__tests__/creditsCommand.test.ts +144 -0
- package/agent/ui-tui/src/__tests__/gatewayClient.test.ts +120 -99
- package/agent/ui-tui/src/__tests__/gracefulExit.test.ts +11 -0
- package/agent/ui-tui/src/__tests__/memoryMonitor.test.ts +102 -0
- package/agent/ui-tui/src/__tests__/paths.test.ts +41 -1
- package/agent/ui-tui/src/__tests__/terminalModes.test.ts +22 -0
- package/agent/ui-tui/src/__tests__/text.test.ts +23 -0
- package/agent/ui-tui/src/__tests__/textInputFastEcho.test.ts +37 -0
- package/agent/ui-tui/src/__tests__/turnControllerNotice.test.ts +43 -0
- package/agent/ui-tui/src/__tests__/useInputHandlers.test.ts +38 -1
- package/agent/ui-tui/src/__tests__/virtualHeights.test.ts +8 -0
- package/agent/ui-tui/src/app/createGatewayEventHandler.ts +102 -7
- package/agent/ui-tui/src/app/interfaces.ts +64 -1
- package/agent/ui-tui/src/app/overlayStore.ts +18 -2
- package/agent/ui-tui/src/app/slash/commands/billing.ts +332 -0
- package/agent/ui-tui/src/app/slash/commands/core.ts +31 -2
- package/agent/ui-tui/src/app/slash/commands/credits.ts +57 -0
- package/agent/ui-tui/src/app/slash/commands/ops.ts +28 -0
- package/agent/ui-tui/src/app/slash/commands/session.ts +32 -4
- package/agent/ui-tui/src/app/slash/registry.ts +4 -0
- package/agent/ui-tui/src/app/turnController.ts +145 -2
- package/agent/ui-tui/src/app/uiStore.ts +2 -0
- package/agent/ui-tui/src/app/useInputHandlers.ts +42 -4
- package/agent/ui-tui/src/app/useMainApp.ts +54 -8
- package/agent/ui-tui/src/app/useSessionLifecycle.ts +40 -31
- package/agent/ui-tui/src/app/useSubmission.ts +23 -31
- package/agent/ui-tui/src/components/appChrome.tsx +112 -5
- package/agent/ui-tui/src/components/appLayout.tsx +9 -0
- package/agent/ui-tui/src/components/appOverlays.tsx +25 -1
- package/agent/ui-tui/src/components/billingOverlay.tsx +684 -0
- package/agent/ui-tui/src/components/branding.tsx +15 -3
- package/agent/ui-tui/src/components/messageLine.tsx +25 -3
- package/agent/ui-tui/src/components/pluginsHub.tsx +238 -0
- package/agent/ui-tui/src/components/prompts.tsx +31 -17
- package/agent/ui-tui/src/components/streamingAssistant.tsx +63 -55
- package/agent/ui-tui/src/components/textInput.tsx +16 -0
- package/agent/ui-tui/src/config/env.ts +12 -0
- package/agent/ui-tui/src/config/limits.ts +13 -0
- package/agent/ui-tui/src/domain/blockLayout.ts +146 -0
- package/agent/ui-tui/src/domain/paths.ts +24 -0
- package/agent/ui-tui/src/domain/slash.ts +40 -0
- package/agent/ui-tui/src/entry.tsx +35 -4
- package/agent/ui-tui/src/gatewayClient.ts +22 -10
- package/agent/ui-tui/src/gatewayTypes.ts +130 -1
- package/agent/ui-tui/src/lib/gracefulExit.ts +24 -4
- package/agent/ui-tui/src/lib/memory.test.ts +162 -0
- package/agent/ui-tui/src/lib/memory.ts +60 -1
- package/agent/ui-tui/src/lib/memoryMonitor.ts +79 -4
- package/agent/ui-tui/src/lib/osc52.ts +1 -1
- package/agent/ui-tui/src/lib/text.test.ts +32 -1
- package/agent/ui-tui/src/lib/text.ts +29 -2
- package/agent/ui-tui/src/lib/virtualHeights.ts +13 -0
- package/agent/ui-tui/src/types.ts +5 -0
- package/agent/ui-tui/tsconfig.build.json +0 -1
- package/agent/ui-tui/tsconfig.json +2 -1
- package/agent/utils.py +66 -2
- package/agent/uv.lock +300 -684
- package/agent/web/index.html +2 -2
- package/agent/web/package.json +11 -6
- package/agent/web/public/claw-bg.webp +0 -0
- package/agent/web/public/claw-logo.webp +0 -0
- package/agent/web/src/App.tsx +138 -48
- package/agent/web/src/components/AutomationBlueprints.tsx +225 -0
- package/agent/web/src/components/Backdrop.tsx +15 -0
- package/agent/web/src/components/ChatSessionList.tsx +260 -0
- package/agent/web/src/components/ChatSidebar.tsx +262 -78
- package/agent/web/src/components/ConfirmDialog.tsx +122 -0
- package/agent/web/src/components/ModelPickerDialog.tsx +111 -16
- package/agent/web/src/components/ModelReloadConfirm.tsx +40 -0
- package/agent/web/src/components/ProfileScopeBanner.tsx +30 -0
- package/agent/web/src/components/ProfileSwitcher.tsx +67 -0
- package/agent/web/src/components/ReasoningPicker.tsx +167 -0
- package/agent/web/src/components/SkillEditorDialog.tsx +215 -0
- package/agent/web/src/components/ThemeSwitcher.tsx +119 -4
- package/agent/web/src/components/ToolsetConfigDrawer.tsx +457 -0
- package/agent/web/src/contexts/PageHeaderProvider.tsx +7 -4
- package/agent/web/src/contexts/ProfileProvider.tsx +137 -0
- package/agent/web/src/contexts/SystemActions.tsx +6 -8
- package/agent/web/src/contexts/profile-context.ts +19 -0
- package/agent/web/src/contexts/useProfileScope.ts +6 -0
- package/agent/web/src/i18n/af.ts +5 -4
- package/agent/web/src/i18n/de.ts +5 -4
- package/agent/web/src/i18n/en.ts +58 -4
- package/agent/web/src/i18n/es.ts +5 -3
- package/agent/web/src/i18n/fr.ts +5 -3
- package/agent/web/src/i18n/ga.ts +5 -4
- package/agent/web/src/i18n/hu.ts +5 -4
- package/agent/web/src/i18n/it.ts +5 -4
- package/agent/web/src/i18n/ja.ts +5 -4
- package/agent/web/src/i18n/ko.ts +5 -4
- package/agent/web/src/i18n/pt.ts +5 -3
- package/agent/web/src/i18n/ru.ts +5 -4
- package/agent/web/src/i18n/tr.ts +5 -4
- package/agent/web/src/i18n/types.ts +59 -1
- package/agent/web/src/i18n/uk.ts +5 -3
- package/agent/web/src/i18n/zh-hant.ts +5 -4
- package/agent/web/src/i18n/zh.ts +5 -4
- package/agent/web/src/index.css +2 -2
- package/agent/web/src/lib/api.ts +819 -52
- package/agent/web/src/lib/dashboard-flags.ts +16 -7
- package/agent/web/src/lib/reasoning-effort.test.ts +48 -0
- package/agent/web/src/lib/reasoning-effort.ts +36 -0
- package/agent/web/src/lib/session-refresh.test.ts +21 -0
- package/agent/web/src/lib/session-refresh.ts +26 -0
- package/agent/web/src/pages/ChannelsPage.tsx +529 -68
- package/agent/web/src/pages/ChatPage.tsx +249 -56
- package/agent/web/src/pages/ConfigPage.tsx +11 -1
- package/agent/web/src/pages/CronPage.tsx +219 -31
- package/agent/web/src/pages/EnvPage.tsx +25 -6
- package/agent/web/src/pages/FilesPage.tsx +525 -0
- package/agent/web/src/pages/McpPage.tsx +80 -3
- package/agent/web/src/pages/ModelsPage.tsx +97 -12
- package/agent/web/src/pages/PluginsPage.tsx +1 -1
- package/agent/web/src/pages/ProfileBuilderPage.tsx +611 -0
- package/agent/web/src/pages/ProfilesPage.tsx +1038 -172
- package/agent/web/src/pages/SessionsPage.tsx +144 -13
- package/agent/web/src/pages/SkillsPage.tsx +851 -70
- package/agent/web/src/pages/SystemPage.tsx +340 -4
- package/agent/web/src/pages/WalletPage.tsx +401 -0
- package/agent/web/src/pages/WebhooksPage.tsx +145 -15
- package/agent/web/src/pages/X402Page.tsx +207 -0
- package/agent/web/src/plugins/registry.ts +28 -11
- package/agent/web/src/plugins/sdk.d.ts +160 -0
- package/agent/web/src/themes/context.tsx +112 -5
- package/agent/web/src/themes/fonts.ts +167 -0
- package/agent/web/src/themes/index.ts +7 -0
- package/agent/web/tsconfig.app.json +0 -1
- package/agent/web/vite.config.ts +1 -8
- package/agent/web/vitest.config.ts +16 -0
- package/package.json +1 -1
- package/agent/apps/desktop/package-lock.json +0 -18363
- package/agent/apps/desktop/src/app/chat/composer/skin-slash-popover.tsx +0 -56
- package/agent/apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx +0 -382
- package/agent/apps/desktop/src/components/assistant-ui/todo-tool.tsx +0 -109
- package/agent/apps/desktop/src/components/chat/generated-image-context.tsx +0 -19
- package/agent/optional-skills/productivity/shop-app/SKILL.md +0 -340
- package/agent/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md +0 -277
- package/agent/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md +0 -57
- package/agent/skills/diagramming/DESCRIPTION.md +0 -3
- package/agent/skills/domain/DESCRIPTION.md +0 -24
- package/agent/skills/gifs/DESCRIPTION.md +0 -3
- package/agent/skills/inference-sh/DESCRIPTION.md +0 -19
- package/agent/skills/mcp/DESCRIPTION.md +0 -3
- package/agent/skills/media/spotify/SKILL.md +0 -135
- package/agent/skills/mlops/training/DESCRIPTION.md +0 -3
- package/agent/skills/mlops/vector-databases/DESCRIPTION.md +0 -3
- package/agent/skills/productivity/linear/SKILL.md +0 -380
- package/agent/skills/productivity/linear/scripts/linear_api.py +0 -445
- package/agent/skills/software-development/debugging-hermes-tui-commands/SKILL.md +0 -152
- package/agent/skills/software-development/writing-plans/SKILL.md +0 -297
- package/agent/ui-tui/package-lock.json +0 -7449
- package/agent/ui-tui/packages/hermes-ink/package-lock.json +0 -1289
- package/agent/web/package-lock.json +0 -8887
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/PORT_NOTES.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/prompts/system.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/macaron.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/mono-ink.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/neon.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/warm.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/prompt-construction.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/style-presets.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/blueprint.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/chalkboard.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/editorial.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/elegant.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/fantasy-animation.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/flat-doodle.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/flat.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/ink-notes.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/intuition-machine.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/minimal.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/nature.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/notion.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/pixel-art.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/playful.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/retro.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/scientific.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/screen-print.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/sketch-notes.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/sketch.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/vector-illustration.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/vintage.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/warm.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/watercolor.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/usage.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/workflow.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/PORT_NOTES.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/analysis-framework.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/chalk.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/ink-brush.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/ligne-claire.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/manga.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/minimalist.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/realistic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/auto-selection.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/base-prompt.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/character-template.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/cinematic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/dense.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/four-panel.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/mixed.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/splash.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/standard.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/webtoon.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/ohmsha-guide.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/partial-workflows.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/concept-story.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/four-panel.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/ohmsha.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/shoujo.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/wuxia.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/storyboard-template.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/action.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/dramatic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/energetic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/neutral.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/romantic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/vintage.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/warm.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/workflow.md +0 -0
- /package/agent/{skills → optional-skills}/creative/creative-ideation/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/creative/creative-ideation/references/full-prompt-library.md +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/ATTRIBUTION.md +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/references/palettes.md +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/__init__.py +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/palettes.py +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/pixel_art.py +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/pixel_art_video.py +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/SKILL.md +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/references/analysis-modules.md +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/references/methods-guide.md +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/abliteration-config.yaml +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/analysis-study.yaml +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/batch-abliteration.yaml +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/DESCRIPTION.md +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/dspy/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/dspy/references/examples.md +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/dspy/references/modules.md +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/dspy/references/optimizers.md +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/references/jailbreak-templates.md +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/references/refusal-detection.md +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/godmode_race.py +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/load_godmode.py +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/parseltongue.py +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/templates/prefill-subtle.json +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/templates/prefill.json +0 -0
- /package/agent/{skills → optional-skills}/software-development/subagent-driven-development/references/context-budget-discipline.md +0 -0
- /package/agent/{skills → optional-skills}/software-development/subagent-driven-development/references/gates-taxonomy.md +0 -0
package/agent/scripts/install.sh
CHANGED
|
@@ -413,6 +413,25 @@ get_command_link_display_dir() {
|
|
|
413
413
|
fi
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
+
# Point a Hermes-managed Node's `npm install -g` at a directory that is on
|
|
417
|
+
# PATH. npm's default global prefix for a bundled Node is the Node dir itself,
|
|
418
|
+
# so global package binaries land in $HERMES_HOME/node/bin — which is NOT on
|
|
419
|
+
# PATH (only the command link dir is) and is wiped on every Node upgrade.
|
|
420
|
+
# Redirecting the prefix to the link dir's parent makes global bins resolve to
|
|
421
|
+
# the command link dir (node/npm/npx live there too, already on PATH) and
|
|
422
|
+
# survive upgrades. Scoped to the managed Node via its prefix-local global
|
|
423
|
+
# npmrc, so the user's other Node installs and their ~/.npmrc are untouched.
|
|
424
|
+
# Hermes's own global installs pass an explicit --prefix and are unaffected.
|
|
425
|
+
# Idempotent and a no-op when there is no Hermes-managed npm, so calling it on
|
|
426
|
+
# every install run repairs pre-existing installs, not just fresh ones.
|
|
427
|
+
configure_managed_node_npm_prefix() {
|
|
428
|
+
[ -x "$HERMES_HOME/node/bin/npm" ] || return 0
|
|
429
|
+
local link_dir
|
|
430
|
+
link_dir="$(get_command_link_dir)"
|
|
431
|
+
mkdir -p "$HERMES_HOME/node/etc"
|
|
432
|
+
printf 'prefix=%s\n' "$(dirname "$link_dir")" > "$HERMES_HOME/node/etc/npmrc"
|
|
433
|
+
}
|
|
434
|
+
|
|
416
435
|
get_hermes_command_path() {
|
|
417
436
|
local link_dir
|
|
418
437
|
link_dir="$(get_command_link_dir)"
|
|
@@ -475,39 +494,22 @@ install_uv() {
|
|
|
475
494
|
return 0
|
|
476
495
|
fi
|
|
477
496
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
#
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
UV_VERSION=$($UV_CMD --version 2>/dev/null)
|
|
484
|
-
log_success "uv found ($UV_VERSION)"
|
|
485
|
-
return 0
|
|
486
|
-
fi
|
|
497
|
+
# Hermes owns its own uv at $HERMES_HOME/bin/uv. Always install there —
|
|
498
|
+
# no PATH probing, no conda guards, no multi-location resolution chains.
|
|
499
|
+
# The runtime update path (hermes_cli/managed_uv.py) looks in the same
|
|
500
|
+
# place, so install.sh and `hermes update` stay in sync.
|
|
501
|
+
local _managed_uv="$HERMES_HOME/bin/uv"
|
|
487
502
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
UV_CMD="$HOME/.local/bin/uv"
|
|
503
|
+
if [ -x "$_managed_uv" ]; then
|
|
504
|
+
UV_CMD="$_managed_uv"
|
|
491
505
|
UV_VERSION=$($UV_CMD --version 2>/dev/null)
|
|
492
|
-
log_success "uv found
|
|
506
|
+
log_success "Managed uv found ($UV_VERSION)"
|
|
493
507
|
return 0
|
|
494
508
|
fi
|
|
495
509
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
UV_CMD="$HOME/.cargo/bin/uv"
|
|
499
|
-
UV_VERSION=$($UV_CMD --version 2>/dev/null)
|
|
500
|
-
log_success "uv found at ~/.cargo/bin ($UV_VERSION)"
|
|
501
|
-
return 0
|
|
502
|
-
fi
|
|
510
|
+
log_info "Installing managed uv into $HERMES_HOME/bin ..."
|
|
511
|
+
mkdir -p "$HERMES_HOME/bin"
|
|
503
512
|
|
|
504
|
-
# Install uv
|
|
505
|
-
log_info "Installing uv (fast Python package manager)..."
|
|
506
|
-
# Capture installer output so a failure shows the user WHY (network,
|
|
507
|
-
# glibc mismatch on old distros, missing curl, ~/.local/bin not
|
|
508
|
-
# writable, disk full, corp proxy / TLS interception, etc.) instead
|
|
509
|
-
# of the previous "✗ Failed to install uv" with zero diagnostic.
|
|
510
|
-
#
|
|
511
513
|
# Two-stage: download the installer, then run it. Piping
|
|
512
514
|
# `curl | sh` masks curl failures (sh exits 0 on empty stdin)
|
|
513
515
|
# and conflates network errors with installer errors.
|
|
@@ -522,26 +524,22 @@ install_uv() {
|
|
|
522
524
|
rm -f "$_uv_install_log" "$_uv_installer"
|
|
523
525
|
exit 1
|
|
524
526
|
fi
|
|
525
|
-
|
|
527
|
+
# UV_UNMANAGED_INSTALL tells the astral installer to place the binary
|
|
528
|
+
# directly into $HERMES_HOME/bin instead of ~/.local/bin.
|
|
529
|
+
if UV_UNMANAGED_INSTALL="$HERMES_HOME/bin" sh "$_uv_installer" >>"$_uv_install_log" 2>&1; then
|
|
526
530
|
rm -f "$_uv_installer"
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
UV_CMD="$HOME/.local/bin/uv"
|
|
530
|
-
elif [ -x "$HOME/.cargo/bin/uv" ]; then
|
|
531
|
-
UV_CMD="$HOME/.cargo/bin/uv"
|
|
532
|
-
elif command -v uv &> /dev/null; then
|
|
533
|
-
UV_CMD="uv"
|
|
531
|
+
if [ -x "$_managed_uv" ]; then
|
|
532
|
+
UV_CMD="$_managed_uv"
|
|
534
533
|
else
|
|
535
|
-
log_error "uv installer reported success but binary not found
|
|
534
|
+
log_error "uv installer reported success but binary not found at $_managed_uv"
|
|
536
535
|
log_info "Installer output:"
|
|
537
536
|
sed 's/^/ /' "$_uv_install_log" >&2
|
|
538
|
-
log_info "Try adding ~/.local/bin to your PATH and re-running"
|
|
539
537
|
rm -f "$_uv_install_log"
|
|
540
538
|
exit 1
|
|
541
539
|
fi
|
|
542
540
|
rm -f "$_uv_install_log"
|
|
543
541
|
UV_VERSION=$($UV_CMD --version 2>/dev/null)
|
|
544
|
-
log_success "uv installed ($UV_VERSION)"
|
|
542
|
+
log_success "Managed uv installed ($UV_VERSION)"
|
|
545
543
|
else
|
|
546
544
|
log_error "Failed to install uv"
|
|
547
545
|
log_info "Installer output:"
|
|
@@ -579,7 +577,6 @@ check_python() {
|
|
|
579
577
|
if PYTHON_PATH="$("$UV_CMD" python find "$PYTHON_VERSION" 2>/dev/null)"; then
|
|
580
578
|
PYTHON_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)"
|
|
581
579
|
log_success "Python found: $PYTHON_FOUND_VERSION"
|
|
582
|
-
ensure_fts5
|
|
583
580
|
return 0
|
|
584
581
|
fi
|
|
585
582
|
|
|
@@ -589,7 +586,6 @@ check_python() {
|
|
|
589
586
|
PYTHON_PATH="$("$UV_CMD" python find "$PYTHON_VERSION")"
|
|
590
587
|
PYTHON_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)"
|
|
591
588
|
log_success "Python installed: $PYTHON_FOUND_VERSION"
|
|
592
|
-
ensure_fts5
|
|
593
589
|
else
|
|
594
590
|
log_error "Failed to install Python $PYTHON_VERSION"
|
|
595
591
|
log_info "Install Python $PYTHON_VERSION manually, then re-run this script"
|
|
@@ -597,104 +593,6 @@ check_python() {
|
|
|
597
593
|
fi
|
|
598
594
|
}
|
|
599
595
|
|
|
600
|
-
# Probe whether $1 (a python executable) links a SQLite with the FTS5
|
|
601
|
-
# module compiled in. Hermes' session store (hermes_state.py) creates FTS5
|
|
602
|
-
# virtual tables for full-text session search; a SQLite without FTS5 makes
|
|
603
|
-
# the bundled-python path unusable for that feature. Returns 0 if FTS5 works.
|
|
604
|
-
_python_has_fts5() {
|
|
605
|
-
"$1" - <<'PY' 2>/dev/null
|
|
606
|
-
import sqlite3, sys
|
|
607
|
-
try:
|
|
608
|
-
sqlite3.connect(":memory:").execute("CREATE VIRTUAL TABLE t USING fts5(x)")
|
|
609
|
-
except Exception:
|
|
610
|
-
sys.exit(1)
|
|
611
|
-
PY
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
# Reinstall $PYTHON_VERSION with the current uv and re-resolve PYTHON_PATH.
|
|
615
|
-
# Returns 0 if the resulting interpreter ships FTS5.
|
|
616
|
-
_reinstall_python_with_fts5() {
|
|
617
|
-
local uv_bin="$1"
|
|
618
|
-
"$uv_bin" python install "$PYTHON_VERSION" --reinstall >/dev/null 2>&1 || return 1
|
|
619
|
-
PYTHON_PATH="$("$uv_bin" python find "$PYTHON_VERSION" 2>/dev/null)"
|
|
620
|
-
PYTHON_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)"
|
|
621
|
-
[ -n "${PYTHON_PATH:-}" ] && _python_has_fts5 "$PYTHON_PATH"
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
_warn_no_fts5() {
|
|
625
|
-
# Could not obtain an FTS5-capable interpreter (offline, pinned env, etc.).
|
|
626
|
-
# Install proceeds — Hermes degrades gracefully and disables only full-text
|
|
627
|
-
# session search — but warn so it isn't a silent gap.
|
|
628
|
-
log_warn "Could not obtain an FTS5-capable Python. Hermes will run, but"
|
|
629
|
-
log_warn "full-text session search will be disabled until FTS5 is present."
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
# Guarantee the resolved uv-managed interpreter ships FTS5. uv's Python
|
|
633
|
-
# distributions only gained FTS5 in mid-2025 (python-build-standalone #694),
|
|
634
|
-
# but WHICH builds a given uv can install is baked into the uv binary's
|
|
635
|
-
# download manifest — so a stale uv (e.g. `pip install uv==0.7.20`) only knows
|
|
636
|
-
# about pre-FTS5 builds, and even `uv python install --reinstall` just pulls the
|
|
637
|
-
# same FTS5-less interpreter. A plain reinstall with an old uv is therefore a
|
|
638
|
-
# no-op for FTS5. To actually fix everyone's install, we escalate uv itself:
|
|
639
|
-
#
|
|
640
|
-
# 1. reinstall with the current $UV_CMD (handles a stale *interpreter* under
|
|
641
|
-
# an already-current uv)
|
|
642
|
-
# 2. if still no FTS5, bring uv up to date (`uv self update`) and reinstall —
|
|
643
|
-
# this is what fixes a stale standalone uv
|
|
644
|
-
# 3. if uv can't self-update (pip/apt/brew-managed uv refuses), install a
|
|
645
|
-
# fresh standalone uv via the official installer into a temp dir and use
|
|
646
|
-
# THAT to reinstall — this fixes package-manager-managed stale uv
|
|
647
|
-
#
|
|
648
|
-
# Pythons live in uv's shared store, so a fresh uv's --reinstall overwrites the
|
|
649
|
-
# stale interpreter in place and the installer's later `uv python find` resolves
|
|
650
|
-
# to it. Keeps session search working without bundling a second SQLite or asking
|
|
651
|
-
# the user to do anything.
|
|
652
|
-
ensure_fts5() {
|
|
653
|
-
[ -n "${PYTHON_PATH:-}" ] || return 0
|
|
654
|
-
if _python_has_fts5 "$PYTHON_PATH"; then
|
|
655
|
-
return 0
|
|
656
|
-
fi
|
|
657
|
-
# Termux / non-uv installs have nothing to escalate.
|
|
658
|
-
[ -n "${UV_CMD:-}" ] || { _warn_no_fts5; return 0; }
|
|
659
|
-
|
|
660
|
-
log_warn "Resolved Python's SQLite lacks the FTS5 module (session search needs it)."
|
|
661
|
-
log_info "Reinstalling a current Python $PYTHON_VERSION with FTS5 via uv..."
|
|
662
|
-
if _reinstall_python_with_fts5 "$UV_CMD"; then
|
|
663
|
-
log_success "FTS5 available ($PYTHON_FOUND_VERSION)"
|
|
664
|
-
return 0
|
|
665
|
-
fi
|
|
666
|
-
|
|
667
|
-
# Still no FTS5 — the uv binary itself is too old to know about FTS5-capable
|
|
668
|
-
# Python builds. Try to update uv in place.
|
|
669
|
-
log_info "uv is too old to provide an FTS5-capable Python — updating uv..."
|
|
670
|
-
if "$UV_CMD" self update >/dev/null 2>&1; then
|
|
671
|
-
if _reinstall_python_with_fts5 "$UV_CMD"; then
|
|
672
|
-
log_success "FTS5 available ($PYTHON_FOUND_VERSION)"
|
|
673
|
-
return 0
|
|
674
|
-
fi
|
|
675
|
-
fi
|
|
676
|
-
|
|
677
|
-
# `uv self update` is unavailable on externally-managed uv (pip/apt/brew),
|
|
678
|
-
# which is exactly the case the user hit (`pip install uv==0.7.20`). Install
|
|
679
|
-
# a fresh standalone uv into a temp dir and use it just for the reinstall.
|
|
680
|
-
log_info "Installing an up-to-date standalone uv to obtain an FTS5 Python..."
|
|
681
|
-
local _tmp_uv_dir _fresh_uv
|
|
682
|
-
_tmp_uv_dir="$(mktemp -d 2>/dev/null || echo "/tmp/hermes-fresh-uv.$$")"
|
|
683
|
-
mkdir -p "$_tmp_uv_dir"
|
|
684
|
-
if curl -LsSf https://astral.sh/uv/install.sh 2>/dev/null \
|
|
685
|
-
| env UV_INSTALL_DIR="$_tmp_uv_dir" UV_UNMANAGED_INSTALL="$_tmp_uv_dir" sh >/dev/null 2>&1; then
|
|
686
|
-
_fresh_uv="$_tmp_uv_dir/uv"
|
|
687
|
-
if [ -x "$_fresh_uv" ] && _reinstall_python_with_fts5 "$_fresh_uv"; then
|
|
688
|
-
log_success "FTS5 available ($PYTHON_FOUND_VERSION)"
|
|
689
|
-
rm -rf "$_tmp_uv_dir"
|
|
690
|
-
return 0
|
|
691
|
-
fi
|
|
692
|
-
fi
|
|
693
|
-
rm -rf "$_tmp_uv_dir"
|
|
694
|
-
|
|
695
|
-
_warn_no_fts5
|
|
696
|
-
}
|
|
697
|
-
|
|
698
596
|
# Best-effort automatic git provisioning, mirroring install.ps1's Install-Git
|
|
699
597
|
# (which downloads PortableGit on Windows). git is required to clone the repo,
|
|
700
598
|
# and a fresh "normie" machine with no developer tools won't have it. Returns 0
|
|
@@ -823,26 +721,48 @@ check_git() {
|
|
|
823
721
|
exit 1
|
|
824
722
|
}
|
|
825
723
|
|
|
724
|
+
# The desktop build runs Vite ^8, which refuses to start on Node outside
|
|
725
|
+
# `^20.19 || >=22.12` — older Node lacks `node:util.styleText`, so `vite build`
|
|
726
|
+
# crashes with a SyntaxError that surfaces only as the opaque "Build desktop
|
|
727
|
+
# app … exit code 1" install failure. Returns 0 when the given `node --version`
|
|
728
|
+
# string clears that floor; anything below it is replaced with the Hermes-
|
|
729
|
+
# managed Node $NODE_VERSION LTS.
|
|
730
|
+
node_satisfies_build() {
|
|
731
|
+
local ver="${1#v}"
|
|
732
|
+
local major="${ver%%.*}"
|
|
733
|
+
local minor="${ver#*.}"; minor="${minor%%.*}"
|
|
734
|
+
case "$major" in ''|*[!0-9]*) return 1 ;; esac
|
|
735
|
+
case "$minor" in ''|*[!0-9]*) minor=0 ;; esac
|
|
736
|
+
if [ "$major" -eq 20 ] && [ "$minor" -ge 19 ]; then return 0; fi
|
|
737
|
+
if [ "$major" -ge 22 ] && { [ "$major" -gt 22 ] || [ "$minor" -ge 12 ]; }; then return 0; fi
|
|
738
|
+
return 1
|
|
739
|
+
}
|
|
740
|
+
|
|
826
741
|
check_node() {
|
|
827
742
|
log_info "Checking Node.js (for browser tools)..."
|
|
828
743
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
744
|
+
# Repair pre-existing Hermes-managed installs where `npm install -g` lands
|
|
745
|
+
# off PATH. No-op when there's no managed Node, so this is safe to run on
|
|
746
|
+
# every install — including re-runs that skip the Node (re)install below.
|
|
747
|
+
configure_managed_node_npm_prefix
|
|
748
|
+
|
|
749
|
+
if command -v node &> /dev/null && node_satisfies_build "$(node --version)"; then
|
|
750
|
+
log_success "Node.js $(node --version) found"
|
|
832
751
|
HAS_NODE=true
|
|
833
752
|
return 0
|
|
834
753
|
fi
|
|
835
754
|
|
|
836
|
-
#
|
|
837
|
-
if [ -x "$HERMES_HOME/node/bin/node" ]; then
|
|
755
|
+
# Prefer a Hermes-managed Node from a previous run over a too-old system one.
|
|
756
|
+
if [ -x "$HERMES_HOME/node/bin/node" ] && node_satisfies_build "$("$HERMES_HOME/node/bin/node" --version)"; then
|
|
838
757
|
export PATH="$HERMES_HOME/node/bin:$PATH"
|
|
839
|
-
|
|
840
|
-
log_success "Node.js $found_ver found (Hermes-managed)"
|
|
758
|
+
log_success "Node.js $("$HERMES_HOME/node/bin/node" --version) found (Hermes-managed)"
|
|
841
759
|
HAS_NODE=true
|
|
842
760
|
return 0
|
|
843
761
|
fi
|
|
844
762
|
|
|
845
|
-
if
|
|
763
|
+
if command -v node &> /dev/null; then
|
|
764
|
+
log_warn "Node.js $(node --version) is too old for the desktop build (need ^20.19 or >=22.12) — installing Hermes-managed Node $NODE_VERSION LTS..."
|
|
765
|
+
elif [ "$DISTRO" = "termux" ]; then
|
|
846
766
|
log_info "Node.js not found — installing Node.js via pkg..."
|
|
847
767
|
else
|
|
848
768
|
log_info "Node.js not found — installing Node.js $NODE_VERSION LTS..."
|
|
@@ -940,16 +860,22 @@ install_node() {
|
|
|
940
860
|
return 0
|
|
941
861
|
fi
|
|
942
862
|
|
|
943
|
-
# Place into ~/.hermes/node/ and symlink binaries
|
|
863
|
+
# Place into ~/.hermes/node/ and symlink binaries into the same bin dir
|
|
864
|
+
# the hermes command uses (get_command_link_dir): /usr/local/bin for root
|
|
865
|
+
# FHS installs, $PREFIX/bin on Termux, ~/.local/bin otherwise.
|
|
944
866
|
rm -rf "$HERMES_HOME/node"
|
|
945
867
|
mkdir -p "$HERMES_HOME"
|
|
946
868
|
mv "$extracted_dir" "$HERMES_HOME/node"
|
|
947
869
|
rm -rf "$tmp_dir"
|
|
948
870
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
ln -sf "$HERMES_HOME/node/bin/
|
|
871
|
+
local node_link_dir
|
|
872
|
+
node_link_dir="$(get_command_link_dir)"
|
|
873
|
+
mkdir -p "$node_link_dir"
|
|
874
|
+
ln -sf "$HERMES_HOME/node/bin/node" "$node_link_dir/node"
|
|
875
|
+
ln -sf "$HERMES_HOME/node/bin/npm" "$node_link_dir/npm"
|
|
876
|
+
ln -sf "$HERMES_HOME/node/bin/npx" "$node_link_dir/npx"
|
|
877
|
+
|
|
878
|
+
configure_managed_node_npm_prefix
|
|
953
879
|
|
|
954
880
|
export PATH="$HERMES_HOME/node/bin:$PATH"
|
|
955
881
|
|
|
@@ -1192,6 +1118,18 @@ show_manual_install_hint() {
|
|
|
1192
1118
|
clone_repo() {
|
|
1193
1119
|
log_info "Installing to $INSTALL_DIR..."
|
|
1194
1120
|
|
|
1121
|
+
# An interrupted previous clone leaves a .git with no initial commit, where
|
|
1122
|
+
# the update path's `git stash` / `git checkout` abort with "You do not
|
|
1123
|
+
# have the initial commit yet" and fail the install (#40998). Move such a
|
|
1124
|
+
# partial checkout aside -- never delete it, in case it holds something the
|
|
1125
|
+
# user wants -- so the fresh-clone path below can proceed.
|
|
1126
|
+
if [ -d "$INSTALL_DIR/.git" ] && ! git -C "$INSTALL_DIR" rev-parse --verify HEAD >/dev/null 2>&1; then
|
|
1127
|
+
backup_dir="${INSTALL_DIR}.broken-$(date -u +%Y%m%d-%H%M%S)"
|
|
1128
|
+
log_warn "Existing checkout at $INSTALL_DIR has no commits (interrupted clone)."
|
|
1129
|
+
log_warn "Moving it aside to $backup_dir before re-cloning."
|
|
1130
|
+
mv "$INSTALL_DIR" "$backup_dir"
|
|
1131
|
+
fi
|
|
1132
|
+
|
|
1195
1133
|
if [ -d "$INSTALL_DIR" ]; then
|
|
1196
1134
|
if [ -d "$INSTALL_DIR/.git" ]; then
|
|
1197
1135
|
log_info "Existing installation found, updating..."
|
|
@@ -1199,6 +1137,19 @@ clone_repo() {
|
|
|
1199
1137
|
|
|
1200
1138
|
local autostash_ref=""
|
|
1201
1139
|
if [ -n "$(git status --porcelain)" ]; then
|
|
1140
|
+
# A previously interrupted update can leave the index with
|
|
1141
|
+
# unmerged entries. In that state `git stash` aborts with
|
|
1142
|
+
# "could not write index" and the later `git checkout` aborts
|
|
1143
|
+
# with "you need to resolve your current index first", failing
|
|
1144
|
+
# the whole install at the repository stage. Clear the conflict
|
|
1145
|
+
# markers with `git reset` first -- this keeps working-tree
|
|
1146
|
+
# changes (they're still stashed just below) and only drops the
|
|
1147
|
+
# index-level conflict state. Mirrors the `hermes update` path
|
|
1148
|
+
# (#4735).
|
|
1149
|
+
if [ -n "$(git ls-files --unmerged)" ]; then
|
|
1150
|
+
log_info "Clearing unmerged index entries from a previous conflict..."
|
|
1151
|
+
git reset -q
|
|
1152
|
+
fi
|
|
1202
1153
|
local stash_name
|
|
1203
1154
|
stash_name="hermes-install-autostash-$(date -u +%Y%m%d-%H%M%S)"
|
|
1204
1155
|
log_info "Local changes detected, stashing before update..."
|
|
@@ -1206,7 +1157,12 @@ clone_repo() {
|
|
|
1206
1157
|
autostash_ref="stash@{0}"
|
|
1207
1158
|
fi
|
|
1208
1159
|
|
|
1209
|
-
git fetch origin
|
|
1160
|
+
# Fetch only the target branch. A bare `git fetch origin` pulls
|
|
1161
|
+
# every ref, and this repo carries thousands of auto-generated
|
|
1162
|
+
# branches — on a non-single-branch checkout that turns each update
|
|
1163
|
+
# into a multi-minute download that can stall the installer.
|
|
1164
|
+
git remote set-branches origin "$BRANCH" 2>/dev/null || true
|
|
1165
|
+
git fetch origin "$BRANCH"
|
|
1210
1166
|
git checkout "$BRANCH"
|
|
1211
1167
|
git pull --ff-only origin "$BRANCH"
|
|
1212
1168
|
|
|
@@ -1252,12 +1208,12 @@ clone_repo() {
|
|
|
1252
1208
|
# so SSH fails fast instead of hanging when no key is configured.
|
|
1253
1209
|
log_info "Trying SSH clone..."
|
|
1254
1210
|
if GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=5" \
|
|
1255
|
-
git clone --branch "$BRANCH" "$REPO_URL_SSH" "$INSTALL_DIR" 2>/dev/null; then
|
|
1211
|
+
git clone --depth 1 --branch "$BRANCH" "$REPO_URL_SSH" "$INSTALL_DIR" 2>/dev/null; then
|
|
1256
1212
|
log_success "Cloned via SSH"
|
|
1257
1213
|
else
|
|
1258
1214
|
rm -rf "$INSTALL_DIR" 2>/dev/null # Clean up partial SSH clone
|
|
1259
1215
|
log_info "SSH failed, trying HTTPS..."
|
|
1260
|
-
if git clone --branch "$BRANCH" "$REPO_URL_HTTPS" "$INSTALL_DIR"; then
|
|
1216
|
+
if git clone --depth 1 --branch "$BRANCH" "$REPO_URL_HTTPS" "$INSTALL_DIR"; then
|
|
1261
1217
|
log_success "Cloned via HTTPS"
|
|
1262
1218
|
else
|
|
1263
1219
|
log_error "Failed to clone repository"
|
|
@@ -1308,12 +1264,33 @@ setup_venv() {
|
|
|
1308
1264
|
# uv creates the venv and pins the Python version in one step
|
|
1309
1265
|
$UV_CMD venv venv --python "$PYTHON_VERSION"
|
|
1310
1266
|
|
|
1267
|
+
# Neutralize any inherited UV_PYTHON (e.g. UV_PYTHON=3.14 left in the
|
|
1268
|
+
# user's shell env). uv honours UV_PYTHON over an existing venv for the
|
|
1269
|
+
# later `uv sync` / `uv pip install` tiers, so without this it would
|
|
1270
|
+
# silently delete this 3.11 venv and recreate it at the inherited
|
|
1271
|
+
# version — building Rust transitives that have no wheel for that
|
|
1272
|
+
# version from source via maturin, which fails. Pinning UV_PYTHON to the
|
|
1273
|
+
# interpreter we just created forces every subsequent uv command onto it.
|
|
1274
|
+
if [ -x "$INSTALL_DIR/venv/bin/python" ]; then
|
|
1275
|
+
export UV_PYTHON="$INSTALL_DIR/venv/bin/python"
|
|
1276
|
+
fi
|
|
1277
|
+
|
|
1311
1278
|
log_success "Virtual environment ready (Python $PYTHON_VERSION)"
|
|
1312
1279
|
}
|
|
1313
1280
|
|
|
1314
1281
|
install_deps() {
|
|
1315
1282
|
log_info "Installing dependencies..."
|
|
1316
1283
|
|
|
1284
|
+
# Re-pin UV_PYTHON to the venv interpreter. setup_venv already does this,
|
|
1285
|
+
# but the bootstrap runs install stages (`venv`, `python-deps`) as separate
|
|
1286
|
+
# processes, so an export from setup_venv does NOT survive into a separate
|
|
1287
|
+
# python-deps invocation. Re-deriving it here covers that path. Without it,
|
|
1288
|
+
# an inherited UV_PYTHON=3.14 makes the uv sync/pip tiers below recreate the
|
|
1289
|
+
# venv at 3.14 and fail the maturin source build (no cp314 wheels yet).
|
|
1290
|
+
if [ "$DISTRO" != "termux" ] && [ -x "$INSTALL_DIR/venv/bin/python" ]; then
|
|
1291
|
+
export UV_PYTHON="$INSTALL_DIR/venv/bin/python"
|
|
1292
|
+
fi
|
|
1293
|
+
|
|
1317
1294
|
if [ "$DISTRO" = "termux" ]; then
|
|
1318
1295
|
if [ "$USE_VENV" = true ]; then
|
|
1319
1296
|
export VIRTUAL_ENV="$INSTALL_DIR/venv"
|
|
@@ -2343,10 +2320,148 @@ postinstall_mode() {
|
|
|
2343
2320
|
fi
|
|
2344
2321
|
}
|
|
2345
2322
|
|
|
2346
|
-
#
|
|
2323
|
+
# Clear the cached Electron download + any half-written unpacked output so the
|
|
2324
|
+
# next `npm run pack` re-downloads and re-stages from scratch. A corrupt zip in
|
|
2325
|
+
# the per-user Electron download cache - most often a partial/resumed download
|
|
2326
|
+
# that leaves concatenated junk - makes electron-builder's `unpack-electron`
|
|
2327
|
+
# extract a tree MISSING the electron binary, so the `electron`->`Hermes` rename
|
|
2328
|
+
# dies with ENOENT and every re-run repeats the broken extraction forever. This
|
|
2329
|
+
# is the bash sibling of install.ps1's Clear-ElectronBuildCache and the Python
|
|
2330
|
+
# _purge_electron_build_cache() used by `hermes desktop`; install.sh was the only
|
|
2331
|
+
# build path lacking it. Echoes the removed paths (one per line); best-effort.
|
|
2332
|
+
clear_electron_build_cache() {
|
|
2333
|
+
local desktop_dir="$1"
|
|
2334
|
+
local removed=""
|
|
2335
|
+
|
|
2336
|
+
# Per-user Electron download cache dirs, honoring the overrides @electron/get
|
|
2337
|
+
# respects, then the platform defaults (macOS: ~/Library/Caches/electron,
|
|
2338
|
+
# Linux: $XDG_CACHE_HOME/electron or ~/.cache/electron).
|
|
2339
|
+
local cache_dirs=()
|
|
2340
|
+
[ -n "${electron_config_cache:-}" ] && cache_dirs+=("$electron_config_cache")
|
|
2341
|
+
[ -n "${ELECTRON_CACHE:-}" ] && cache_dirs+=("$ELECTRON_CACHE")
|
|
2342
|
+
if [ "$OS" = "macos" ]; then
|
|
2343
|
+
cache_dirs+=("$HOME/Library/Caches/electron")
|
|
2344
|
+
else
|
|
2345
|
+
[ -n "${XDG_CACHE_HOME:-}" ] && cache_dirs+=("$XDG_CACHE_HOME/electron")
|
|
2346
|
+
cache_dirs+=("$HOME/.cache/electron")
|
|
2347
|
+
fi
|
|
2348
|
+
|
|
2349
|
+
local dir zip
|
|
2350
|
+
for dir in "${cache_dirs[@]}"; do
|
|
2351
|
+
[ -d "$dir" ] || continue
|
|
2352
|
+
# Recurse: the bad copy may be the top-level zip OR a copy inside an
|
|
2353
|
+
# @electron/get hash subdir.
|
|
2354
|
+
while IFS= read -r zip; do
|
|
2355
|
+
[ -n "$zip" ] || continue
|
|
2356
|
+
if rm -f "$zip" 2>/dev/null; then
|
|
2357
|
+
removed="$removed$zip
|
|
2358
|
+
"
|
|
2359
|
+
fi
|
|
2360
|
+
done <<EOF
|
|
2361
|
+
$(find "$dir" -type f -name 'electron-*.zip' 2>/dev/null)
|
|
2362
|
+
EOF
|
|
2363
|
+
done
|
|
2364
|
+
|
|
2365
|
+
# A half-written unpacked dir from an interrupted prior pack poisons the
|
|
2366
|
+
# rename even after the zip is fixed (mac-arm64-unpacked / linux-unpacked).
|
|
2367
|
+
local release_dir="$desktop_dir/release"
|
|
2368
|
+
if [ -d "$release_dir" ]; then
|
|
2369
|
+
local unpacked
|
|
2370
|
+
while IFS= read -r unpacked; do
|
|
2371
|
+
[ -n "$unpacked" ] || continue
|
|
2372
|
+
if rm -rf "$unpacked" 2>/dev/null; then
|
|
2373
|
+
removed="$removed$unpacked
|
|
2374
|
+
"
|
|
2375
|
+
fi
|
|
2376
|
+
done <<EOF
|
|
2377
|
+
$(find "$release_dir" -maxdepth 1 -type d -name '*-unpacked' 2>/dev/null)
|
|
2378
|
+
EOF
|
|
2379
|
+
fi
|
|
2380
|
+
|
|
2381
|
+
printf '%s' "$removed"
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
# Run the desktop pack in $1 (the apps/desktop dir). `npm run pack` = tsc +
|
|
2385
|
+
# vite build + electron-builder --dir, producing an unpacked app for the
|
|
2386
|
+
# current OS. Signing auto-discovery is disabled so electron-builder falls back
|
|
2387
|
+
# to an ad-hoc signature instead of grabbing an unrelated Developer ID from the
|
|
2388
|
+
# keychain (a real signed/notarized .dmg needs Apple credentials — a separate
|
|
2389
|
+
# release concern). Optional $2 = an ELECTRON_MIRROR base URL for this attempt,
|
|
2390
|
+
# used as a fallback when the default GitHub release download is blocked.
|
|
2391
|
+
_desktop_pack() {
|
|
2392
|
+
local desktop_dir="$1"
|
|
2393
|
+
local mirror="${2:-}"
|
|
2394
|
+
if [ -n "$mirror" ]; then
|
|
2395
|
+
( cd "$desktop_dir" && ELECTRON_MIRROR="$mirror" CSC_IDENTITY_AUTO_DISCOVERY=false npm run pack )
|
|
2396
|
+
else
|
|
2397
|
+
( cd "$desktop_dir" && CSC_IDENTITY_AUTO_DISCOVERY=false npm run pack )
|
|
2398
|
+
fi
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
# Last-resort Electron mirror after GitHub download fails (#47266).
|
|
2402
|
+
DESKTOP_ELECTRON_FALLBACK_MIRROR="https://npmmirror.com/mirrors/electron/"
|
|
2403
|
+
|
|
2404
|
+
# Electron package dir — workspace-local nest first, then root hoist.
|
|
2405
|
+
_electron_dir() {
|
|
2406
|
+
local install_dir="$1"
|
|
2407
|
+
if [ -d "$install_dir/apps/desktop/node_modules/electron" ]; then
|
|
2408
|
+
printf '%s\n' "$install_dir/apps/desktop/node_modules/electron"
|
|
2409
|
+
else
|
|
2410
|
+
printf '%s\n' "$install_dir/node_modules/electron"
|
|
2411
|
+
fi
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
# True when dist/ holds a usable Electron binary (#38673 / run-electron-builder.cjs).
|
|
2415
|
+
_electron_dist_ok() {
|
|
2416
|
+
local install_dir="$1"
|
|
2417
|
+
local electron_dir
|
|
2418
|
+
electron_dir="$(_electron_dir "$install_dir")"
|
|
2419
|
+
if [ "$OS" = "macos" ]; then
|
|
2420
|
+
[ -e "$electron_dir/dist/Electron.app/Contents/MacOS/Electron" ]
|
|
2421
|
+
else
|
|
2422
|
+
[ -e "$electron_dir/dist/electron" ]
|
|
2423
|
+
fi
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
# Best-effort: run electron/install.js to populate dist/ (optional mirror).
|
|
2427
|
+
_restore_electron_dist() {
|
|
2428
|
+
local install_dir="$1"
|
|
2429
|
+
local mirror="${2:-}"
|
|
2430
|
+
local electron_dir
|
|
2431
|
+
electron_dir="$(_electron_dir "$install_dir")"
|
|
2432
|
+
_electron_dist_ok "$install_dir" && return 0
|
|
2433
|
+
|
|
2434
|
+
[ -f "$electron_dir/install.js" ] || return 1
|
|
2435
|
+
command -v node >/dev/null 2>&1 || return 1
|
|
2436
|
+
|
|
2437
|
+
rm -rf "$electron_dir/dist" 2>/dev/null || true
|
|
2438
|
+
rm -f "$electron_dir/path.txt" 2>/dev/null || true
|
|
2439
|
+
|
|
2440
|
+
if [ -n "$mirror" ]; then
|
|
2441
|
+
( cd "$electron_dir" && ELECTRON_MIRROR="$mirror" node install.js ) || true
|
|
2442
|
+
else
|
|
2443
|
+
( cd "$electron_dir" && node install.js ) || true
|
|
2444
|
+
fi
|
|
2445
|
+
_electron_dist_ok "$install_dir"
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
_electron_pkg_staged_missing_dist() {
|
|
2449
|
+
local install_dir="$1"
|
|
2450
|
+
local electron_dir
|
|
2451
|
+
electron_dir="$(_electron_dir "$install_dir")"
|
|
2452
|
+
[ -f "$electron_dir/package.json" ] && [ -f "$electron_dir/install.js" ] && ! _electron_dist_ok "$install_dir"
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
_restore_electron_dist_with_fallback() {
|
|
2456
|
+
local install_dir="$1"
|
|
2457
|
+
_restore_electron_dist "$install_dir" \
|
|
2458
|
+
|| { [ -z "${ELECTRON_MIRROR:-}" ] && _restore_electron_dist "$install_dir" "$DESKTOP_ELECTRON_FALLBACK_MIRROR"; }
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
# Build apps/desktop into a launchable native app. Mirrors install.ps1's
|
|
2347
2462
|
# Install-Desktop: a root-level npm install so the apps/* workspace resolves
|
|
2348
2463
|
# the desktop's own deps (Electron ~150MB), then `npm run pack`
|
|
2349
|
-
# (electron-builder --dir) which emits
|
|
2464
|
+
# (electron-builder --dir) which emits an unpacked app for the current OS. Only invoked
|
|
2350
2465
|
# via the 'desktop' stage / --include-desktop, which the Electron app's own
|
|
2351
2466
|
# first-launch bootstrap never requests (it must not rebuild itself).
|
|
2352
2467
|
install_desktop() {
|
|
@@ -2356,11 +2471,12 @@ install_desktop() {
|
|
|
2356
2471
|
# (--include-desktop / 'desktop' stage), so a missing toolchain is a hard
|
|
2357
2472
|
# failure, not a silent skip — a silent skip yields a "complete" install
|
|
2358
2473
|
# with no app and a confusing "couldn't find a built desktop" at launch.
|
|
2359
|
-
#
|
|
2360
|
-
#
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2474
|
+
# Always re-resolve Node here. Stages run in separate processes, so we can't
|
|
2475
|
+
# trust an earlier check; more importantly check_node now enforces the build
|
|
2476
|
+
# floor (^20.19 || >=22.12) and prepends the Hermes-managed Node to PATH, so
|
|
2477
|
+
# the build never runs on a too-old system Node — the cause of the opaque
|
|
2478
|
+
# "Build desktop app … exit code 1" failure (Vite crashes on old Node).
|
|
2479
|
+
check_node
|
|
2364
2480
|
if ! command -v npm >/dev/null 2>&1; then
|
|
2365
2481
|
log_error "Cannot build desktop app: Node.js / npm unavailable"
|
|
2366
2482
|
log_info "Install Node.js and retry: cd $desktop_dir && npm run pack"
|
|
@@ -2374,42 +2490,133 @@ install_desktop() {
|
|
|
2374
2490
|
# 1. Root workspace install so apps/desktop's deps (Electron, Vite,
|
|
2375
2491
|
# node-pty prebuilds) resolve. The browser-tools install runs in the
|
|
2376
2492
|
# repo-root package workspace, which does not pull apps/* deps.
|
|
2493
|
+
#
|
|
2494
|
+
# Prefer `npm ci`: it deletes node_modules and reinstalls from the
|
|
2495
|
+
# lockfile, so it always produces a complete tree. Bare `npm install`
|
|
2496
|
+
# can report "up to date" against a stale node_modules/.package-lock.json
|
|
2497
|
+
# marker while node_modules is actually empty (Windows workspace-hoisting
|
|
2498
|
+
# flake) — leaving tsc/typescript unresolved and `npm run pack`'s
|
|
2499
|
+
# `tsc -b` failing with no obvious cause. Fall back to `npm install`
|
|
2500
|
+
# only if `npm ci` is unavailable or the lockfile is out of sync.
|
|
2377
2501
|
log_info "Installing desktop workspace dependencies (includes Electron ~150MB, 1-3min)..."
|
|
2378
|
-
( cd "$INSTALL_DIR" && npm
|
|
2502
|
+
if ( cd "$INSTALL_DIR" && npm ci ) || ( cd "$INSTALL_DIR" && npm install ); then
|
|
2503
|
+
log_success "Desktop workspace dependencies installed"
|
|
2504
|
+
elif _electron_pkg_staged_missing_dist "$INSTALL_DIR"; then
|
|
2505
|
+
log_warn "Desktop dependency install failed with a missing Electron dist; attempting self-heal..."
|
|
2506
|
+
_restore_electron_dist_with_fallback "$INSTALL_DIR" || true
|
|
2507
|
+
else
|
|
2379
2508
|
log_error "Desktop workspace npm install failed"
|
|
2509
|
+
# Common cause: a previous 'sudo npm'/'sudo npx' left root-owned files in
|
|
2510
|
+
# ~/.npm, so this non-root install can't write the shared cache. npm hides
|
|
2511
|
+
# it behind a confusing EEXIST / "File exists" message while the real errno
|
|
2512
|
+
# is EACCES (-13). Point the user at the fix instead of a raw npm trace.
|
|
2513
|
+
log_info "If the errors above mention EACCES / 'permission denied' / EEXIST while"
|
|
2514
|
+
log_info "writing the npm cache, your ~/.npm likely holds root-owned files from an"
|
|
2515
|
+
log_info "earlier 'sudo npm' or 'sudo npx'. Reclaim ownership and retry:"
|
|
2516
|
+
log_info " sudo chown -R \"\$(id -un)\" ~/.npm && npm cache verify"
|
|
2517
|
+
log_info "Then re-run this installer, or build manually:"
|
|
2518
|
+
log_info " cd \"$INSTALL_DIR\" && npm ci && cd apps/desktop && npm run pack"
|
|
2380
2519
|
return 1
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
#
|
|
2385
|
-
#
|
|
2386
|
-
#
|
|
2387
|
-
#
|
|
2388
|
-
#
|
|
2389
|
-
#
|
|
2520
|
+
fi
|
|
2521
|
+
|
|
2522
|
+
# 2. Build, with up to three escalating attempts so a transient/blocked
|
|
2523
|
+
# Electron download self-heals instead of failing the whole install:
|
|
2524
|
+
# a) plain `npm run pack` (downloads Electron from GitHub),
|
|
2525
|
+
# b) on failure, purge a corrupt cached zip + stale unpacked dir and
|
|
2526
|
+
# retry (matches install.ps1 / `hermes desktop`),
|
|
2527
|
+
# c) on still-failing, fall back to a public Electron mirror — this is
|
|
2528
|
+
# the GitHub-blocked/throttled case (the repeating "retrying" log).
|
|
2390
2529
|
log_info "Building desktop app (this takes 1-3 minutes)..."
|
|
2391
|
-
|
|
2530
|
+
local pack_ok=false
|
|
2531
|
+
if _desktop_pack "$desktop_dir"; then
|
|
2532
|
+
pack_ok=true
|
|
2533
|
+
else
|
|
2534
|
+
local purged=""
|
|
2535
|
+
local restored=false
|
|
2536
|
+
if ! _electron_dist_ok "$INSTALL_DIR"; then
|
|
2537
|
+
purged="$(clear_electron_build_cache "$desktop_dir")"
|
|
2538
|
+
if _restore_electron_dist "$INSTALL_DIR"; then restored=true; fi
|
|
2539
|
+
fi
|
|
2540
|
+
if [ "$restored" = true ]; then
|
|
2541
|
+
log_warn "Desktop build failed; refreshed the Electron download and retrying once..."
|
|
2542
|
+
if _desktop_pack "$desktop_dir"; then
|
|
2543
|
+
pack_ok=true
|
|
2544
|
+
fi
|
|
2545
|
+
fi
|
|
2546
|
+
fi
|
|
2547
|
+
|
|
2548
|
+
# (c) GitHub blocked → mirror fallback (#47266).
|
|
2549
|
+
if [ "$pack_ok" = false ] && [ -z "${ELECTRON_MIRROR:-}" ]; then
|
|
2550
|
+
log_warn "Desktop build still failing — the Electron download from GitHub looks blocked."
|
|
2551
|
+
log_warn "Re-downloading Electron via a public mirror ($DESKTOP_ELECTRON_FALLBACK_MIRROR), then rebuilding..."
|
|
2552
|
+
log_warn " (set ELECTRON_MIRROR yourself to use a different/trusted mirror)"
|
|
2553
|
+
_electron_dist_ok "$INSTALL_DIR" || _restore_electron_dist "$INSTALL_DIR" "$DESKTOP_ELECTRON_FALLBACK_MIRROR" || true
|
|
2554
|
+
if _desktop_pack "$desktop_dir" "$DESKTOP_ELECTRON_FALLBACK_MIRROR"; then
|
|
2555
|
+
pack_ok=true
|
|
2556
|
+
fi
|
|
2557
|
+
fi
|
|
2558
|
+
|
|
2559
|
+
if [ "$pack_ok" = false ]; then
|
|
2392
2560
|
log_error "Desktop app build failed"
|
|
2393
|
-
|
|
2561
|
+
# If the log shows repeated "retrying" lines fetching the Electron zip,
|
|
2562
|
+
# the binary download is blocked/throttled (firewall, proxy, region) and
|
|
2563
|
+
# the mirror fallback above also couldn't reach a host. Try a mirror you
|
|
2564
|
+
# trust and rebuild (@electron/get honors ELECTRON_MIRROR):
|
|
2565
|
+
log_info "If the log shows Electron download retries, rebuild via a reachable mirror:"
|
|
2566
|
+
log_info " ELECTRON_MIRROR=<mirror-base-url> \\"
|
|
2567
|
+
log_info " bash -c 'cd \"$desktop_dir\" && CSC_IDENTITY_AUTO_DISCOVERY=false npm run pack'"
|
|
2568
|
+
log_info "Otherwise build manually: cd $desktop_dir && npm run pack"
|
|
2394
2569
|
return 1
|
|
2395
|
-
|
|
2570
|
+
fi
|
|
2396
2571
|
|
|
2397
2572
|
local app=""
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
"$desktop_dir/release/
|
|
2402
|
-
|
|
2403
|
-
app="$cand"
|
|
2404
|
-
break
|
|
2573
|
+
if [ "$OS" = "linux" ]; then
|
|
2574
|
+
if [ -x "$desktop_dir/release/linux-unpacked/Hermes" ]; then
|
|
2575
|
+
app="$desktop_dir/release/linux-unpacked/Hermes"
|
|
2576
|
+
elif [ -x "$desktop_dir/release/linux-unpacked/hermes" ]; then
|
|
2577
|
+
app="$desktop_dir/release/linux-unpacked/hermes"
|
|
2405
2578
|
fi
|
|
2406
|
-
|
|
2579
|
+
else
|
|
2580
|
+
local cand
|
|
2581
|
+
for cand in \
|
|
2582
|
+
"$desktop_dir/release/mac-arm64/Hermes.app" \
|
|
2583
|
+
"$desktop_dir/release/mac/Hermes.app"; do
|
|
2584
|
+
if [ -d "$cand" ]; then
|
|
2585
|
+
app="$cand"
|
|
2586
|
+
break
|
|
2587
|
+
fi
|
|
2588
|
+
done
|
|
2589
|
+
fi
|
|
2407
2590
|
if [ -z "$app" ]; then
|
|
2408
|
-
log_error "Desktop build completed but no
|
|
2591
|
+
log_error "Desktop build completed but no app was found under $desktop_dir/release/"
|
|
2409
2592
|
return 1
|
|
2410
2593
|
fi
|
|
2411
2594
|
log_success "Desktop app built: $app"
|
|
2412
2595
|
|
|
2596
|
+
# Linux: Electron's chrome-sandbox helper needs root:root 4755 or the
|
|
2597
|
+
# sandboxed renderer will abort on startup. Check the file is a regular
|
|
2598
|
+
# file (not a symlink) before chown/chmod so we don't follow an
|
|
2599
|
+
# attacker-controlled link to an arbitrary path.
|
|
2600
|
+
if [ "$OS" = "linux" ]; then
|
|
2601
|
+
local sandbox="$desktop_dir/release/linux-unpacked/chrome-sandbox"
|
|
2602
|
+
if [ -f "$sandbox" ] && [ ! -L "$sandbox" ]; then
|
|
2603
|
+
if [ "$(id -u)" -eq 0 ]; then
|
|
2604
|
+
chown root:root "$sandbox" && chmod 4755 "$sandbox" || {
|
|
2605
|
+
log_error "Cannot configure Electron sandbox helper: $sandbox"
|
|
2606
|
+
return 1
|
|
2607
|
+
}
|
|
2608
|
+
elif command -v sudo >/dev/null 2>&1; then
|
|
2609
|
+
sudo chown root:root "$sandbox" && sudo chmod 4755 "$sandbox" || {
|
|
2610
|
+
log_error "Cannot configure Electron sandbox helper (sudo failed): $sandbox"
|
|
2611
|
+
return 1
|
|
2612
|
+
}
|
|
2613
|
+
else
|
|
2614
|
+
log_error "Cannot configure Electron sandbox helper without sudo: $sandbox"
|
|
2615
|
+
return 1
|
|
2616
|
+
fi
|
|
2617
|
+
fi
|
|
2618
|
+
fi
|
|
2619
|
+
|
|
2413
2620
|
# macOS: make the locally-built (ad-hoc) app relaunchable after an in-place
|
|
2414
2621
|
# self-update. An ad-hoc bundle has no stable Designated Requirement, so a
|
|
2415
2622
|
# later in-place rebuild (new cdhash) plus the inherited quarantine flag
|
|
@@ -2525,7 +2732,12 @@ run_stage_body() {
|
|
|
2525
2732
|
detect_os
|
|
2526
2733
|
resolve_install_layout
|
|
2527
2734
|
print_success
|
|
2528
|
-
|
|
2735
|
+
# Code-scoped stamp: write next to the install tree, not into
|
|
2736
|
+
# $HERMES_HOME. $HERMES_HOME is a shared data dir (it can be
|
|
2737
|
+
# bind-mounted into a Docker gateway too), so a stamp there gets
|
|
2738
|
+
# clobbered by the container's 'docker' stamp and wrongly blocks
|
|
2739
|
+
# 'hermes update' on this host install. See detect_install_method().
|
|
2740
|
+
echo "git" > "$INSTALL_DIR/.install_method"
|
|
2529
2741
|
;;
|
|
2530
2742
|
*)
|
|
2531
2743
|
log_error "Unknown stage: $stage"
|
|
@@ -2604,7 +2816,12 @@ main() {
|
|
|
2604
2816
|
|
|
2605
2817
|
print_success
|
|
2606
2818
|
|
|
2607
|
-
|
|
2819
|
+
# Code-scoped stamp: write next to the install tree, not into $HERMES_HOME.
|
|
2820
|
+
# $HERMES_HOME is a shared data dir (it can be bind-mounted into a Docker
|
|
2821
|
+
# gateway too), so a stamp there gets clobbered by the container's 'docker'
|
|
2822
|
+
# stamp and wrongly blocks 'hermes update' on this host install.
|
|
2823
|
+
# See detect_install_method().
|
|
2824
|
+
echo "git" > "$INSTALL_DIR/.install_method"
|
|
2608
2825
|
}
|
|
2609
2826
|
|
|
2610
2827
|
if [ "$MANIFEST_MODE" = true ]; then
|