profclaw 0.0.1-beta.3 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +14 -2
- package/CHANGELOG.md +54 -34
- package/CONTRIBUTING.md +23 -5
- package/Dockerfile +39 -23
- package/README.md +271 -72
- package/dist/agents/agent-summary.d.ts +44 -0
- package/dist/agents/agent-summary.js +176 -0
- package/dist/agents/auto-memory.d.ts +59 -0
- package/dist/agents/auto-memory.js +310 -0
- package/dist/agents/checkpoint-manager.d.ts +76 -0
- package/dist/agents/checkpoint-manager.js +156 -0
- package/dist/agents/circuit-breaker.d.ts +54 -0
- package/dist/agents/circuit-breaker.js +153 -0
- package/dist/agents/context-compactor.d.ts +70 -0
- package/dist/agents/context-compactor.js +361 -0
- package/dist/agents/conversation-branch.d.ts +55 -0
- package/dist/agents/conversation-branch.js +115 -0
- package/dist/agents/error-recovery.d.ts +44 -0
- package/dist/agents/error-recovery.js +197 -0
- package/dist/agents/events.d.ts +76 -0
- package/dist/agents/events.js +8 -0
- package/dist/agents/executor.d.ts +35 -1
- package/dist/agents/executor.js +573 -124
- package/dist/agents/file-snapshots.d.ts +72 -0
- package/dist/agents/file-snapshots.js +182 -0
- package/dist/agents/index.d.ts +2 -0
- package/dist/agents/orchestrator.d.ts +183 -0
- package/dist/agents/orchestrator.js +495 -0
- package/dist/agents/permissions.d.ts +63 -0
- package/dist/agents/permissions.js +138 -0
- package/dist/agents/plan-mode.d.ts +71 -0
- package/dist/agents/plan-mode.js +186 -0
- package/dist/agents/prompt-suggestions.d.ts +33 -0
- package/dist/agents/prompt-suggestions.js +208 -0
- package/dist/agents/rate-limit-monitor.d.ts +56 -0
- package/dist/agents/rate-limit-monitor.js +224 -0
- package/dist/agents/result-store.d.ts +37 -0
- package/dist/agents/result-store.js +104 -0
- package/dist/agents/session-diff.d.ts +43 -0
- package/dist/agents/session-diff.js +258 -0
- package/dist/agents/tool-loader.d.ts +65 -0
- package/dist/agents/tool-loader.js +273 -0
- package/dist/agents/transcript.d.ts +96 -0
- package/dist/agents/transcript.js +267 -0
- package/dist/agents/worktree-manager.d.ts +80 -0
- package/dist/agents/worktree-manager.js +203 -0
- package/dist/auth/middleware.js +14 -0
- package/dist/chat/agentic-executor.d.ts +7 -0
- package/dist/chat/agentic-executor.js +253 -30
- package/dist/chat/conversations.d.ts +2 -0
- package/dist/chat/conversations.js +8 -0
- package/dist/chat/execution/executor.d.ts +8 -0
- package/dist/chat/execution/executor.js +157 -103
- package/dist/chat/execution/index.js +5 -1
- package/dist/chat/execution/tool-router.js +40 -14
- package/dist/chat/execution/tools/canvas.d.ts +2 -2
- package/dist/chat/execution/tools/code-tools.d.ts +66 -0
- package/dist/chat/execution/tools/code-tools.js +353 -0
- package/dist/chat/execution/tools/complete-task.d.ts +2 -2
- package/dist/chat/execution/tools/cron-tool.d.ts +26 -10
- package/dist/chat/execution/tools/cron-tool.js +48 -3
- package/dist/chat/execution/tools/decompose-task.d.ts +58 -0
- package/dist/chat/execution/tools/decompose-task.js +166 -0
- package/dist/chat/execution/tools/exec.d.ts +5 -2
- package/dist/chat/execution/tools/exec.js +294 -155
- package/dist/chat/execution/tools/feed-tools.d.ts +77 -0
- package/dist/chat/execution/tools/feed-tools.js +142 -0
- package/dist/chat/execution/tools/file-ops.d.ts +1 -1
- package/dist/chat/execution/tools/github.d.ts +2 -2
- package/dist/chat/execution/tools/index.d.ts +15 -3
- package/dist/chat/execution/tools/index.js +125 -12
- package/dist/chat/execution/tools/integrations.d.ts +8 -8
- package/dist/chat/execution/tools/multi-patch.d.ts +53 -0
- package/dist/chat/execution/tools/multi-patch.js +373 -0
- package/dist/chat/execution/tools/openai-image-gen.d.ts +2 -2
- package/dist/chat/execution/tools/plan-tools.d.ts +80 -0
- package/dist/chat/execution/tools/plan-tools.js +134 -0
- package/dist/chat/execution/tools/profclaw-ops.d.ts +6 -6
- package/dist/chat/execution/tools/repl-tool.d.ts +46 -0
- package/dist/chat/execution/tools/repl-tool.js +207 -0
- package/dist/chat/execution/tools/sessions-send.d.ts +2 -2
- package/dist/chat/execution/tools/slack-actions.d.ts +2 -2
- package/dist/chat/execution/tools/system.d.ts +4 -4
- package/dist/chat/execution/tools/todo-tool.d.ts +72 -0
- package/dist/chat/execution/tools/todo-tool.js +152 -0
- package/dist/chat/execution/tools/tool-search.d.ts +50 -0
- package/dist/chat/execution/tools/tool-search.js +155 -0
- package/dist/chat/execution/types.d.ts +21 -14
- package/dist/chat/execution/workflows/executor.d.ts +11 -0
- package/dist/chat/execution/workflows/executor.js +99 -1
- package/dist/chat/execution/workflows/types.d.ts +35 -2
- package/dist/chat/format/index.d.ts +1 -0
- package/dist/chat/format/index.js +1 -0
- package/dist/chat/format/markdown-convert.d.ts +23 -0
- package/dist/chat/format/markdown-convert.js +149 -0
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.js +1 -1
- package/dist/chat/message-handler.js +58 -6
- package/dist/chat/proactive/index.d.ts +62 -0
- package/dist/chat/proactive/index.js +147 -0
- package/dist/chat/prompt-adapter.js +2 -0
- package/dist/chat/providers/irc/index.d.ts +2 -2
- package/dist/chat/providers/slack/index.d.ts +2 -2
- package/dist/chat/providers/telegram/index.d.ts +2 -0
- package/dist/chat/providers/telegram/index.js +21 -2
- package/dist/chat/system-prompts.d.ts +3 -3
- package/dist/chat/system-prompts.js +116 -61
- package/dist/chat/tools.d.ts +6 -6
- package/dist/cli/commands/auth.js +64 -1
- package/dist/cli/commands/chat.js +1327 -138
- package/dist/cli/commands/doctor.js +222 -16
- package/dist/cli/commands/history.d.ts +3 -0
- package/dist/cli/commands/history.js +138 -0
- package/dist/cli/commands/import.d.ts +44 -0
- package/dist/cli/commands/import.js +526 -0
- package/dist/cli/commands/init.d.ts +13 -0
- package/dist/cli/commands/init.js +381 -0
- package/dist/cli/commands/models.js +39 -26
- package/dist/cli/commands/onboard.js +263 -98
- package/dist/cli/commands/plan.d.ts +13 -0
- package/dist/cli/commands/plan.js +184 -0
- package/dist/cli/commands/serve.d.ts +7 -0
- package/dist/cli/commands/serve.js +77 -18
- package/dist/cli/commands/setup.js +375 -91
- package/dist/cli/commands/status.js +54 -0
- package/dist/cli/commands/tools.js +13 -13
- package/dist/cli/commands/tui.js +26 -1
- package/dist/cli/index.js +19 -6
- package/dist/cli/ink/App.d.ts +13 -0
- package/dist/cli/ink/App.js +6 -0
- package/dist/cli/ink/ChatApp.d.ts +60 -0
- package/dist/cli/ink/ChatApp.js +325 -0
- package/dist/cli/ink/DashboardApp.d.ts +3 -0
- package/dist/cli/ink/DashboardApp.js +143 -0
- package/dist/cli/ink/components/AgentStatus.d.ts +17 -0
- package/dist/cli/ink/components/AgentStatus.js +33 -0
- package/dist/cli/ink/components/ChannelList.d.ts +17 -0
- package/dist/cli/ink/components/ChannelList.js +33 -0
- package/dist/cli/ink/components/ConnectionStatus.d.ts +19 -0
- package/dist/cli/ink/components/ConnectionStatus.js +50 -0
- package/dist/cli/ink/components/CostBar.d.ts +19 -0
- package/dist/cli/ink/components/CostBar.js +35 -0
- package/dist/cli/ink/components/HookStatus.d.ts +15 -0
- package/dist/cli/ink/components/HookStatus.js +7 -0
- package/dist/cli/ink/components/PermissionPrompt.d.ts +21 -0
- package/dist/cli/ink/components/PermissionPrompt.js +51 -0
- package/dist/cli/ink/components/PlanView.d.ts +23 -0
- package/dist/cli/ink/components/PlanView.js +26 -0
- package/dist/cli/ink/components/ProviderList.d.ts +16 -0
- package/dist/cli/ink/components/ProviderList.js +16 -0
- package/dist/cli/ink/components/SessionHeader.d.ts +15 -0
- package/dist/cli/ink/components/SessionHeader.js +15 -0
- package/dist/cli/ink/components/StreamingMessage.d.ts +20 -0
- package/dist/cli/ink/components/StreamingMessage.js +27 -0
- package/dist/cli/ink/components/SuggestionBar.d.ts +15 -0
- package/dist/cli/ink/components/SuggestionBar.js +28 -0
- package/dist/cli/ink/components/SystemHealth.d.ts +20 -0
- package/dist/cli/ink/components/SystemHealth.js +39 -0
- package/dist/cli/ink/components/TaskList.d.ts +17 -0
- package/dist/cli/ink/components/TaskList.js +59 -0
- package/dist/cli/ink/components/ToolCall.d.ts +17 -0
- package/dist/cli/ink/components/ToolCall.js +43 -0
- package/dist/cli/ink/index.d.ts +23 -0
- package/dist/cli/ink/index.js +15 -0
- package/dist/cli/ink/keybindings.d.ts +35 -0
- package/dist/cli/ink/keybindings.js +105 -0
- package/dist/cli/ink/markdown-renderer.d.ts +47 -0
- package/dist/cli/ink/markdown-renderer.js +380 -0
- package/dist/cli/ink/output-styles.d.ts +39 -0
- package/dist/cli/ink/output-styles.js +119 -0
- package/dist/cli/interactive/auto-serve.d.ts +38 -0
- package/dist/cli/interactive/auto-serve.js +209 -0
- package/dist/cli/interactive/index.d.ts +25 -0
- package/dist/cli/interactive/index.js +23 -0
- package/dist/cli/interactive/picker.d.ts +28 -0
- package/dist/cli/interactive/picker.js +153 -0
- package/dist/cli/interactive/renderer.d.ts +26 -0
- package/dist/cli/interactive/renderer.js +555 -0
- package/dist/cli/interactive/repl.d.ts +14 -0
- package/dist/cli/interactive/repl.js +1516 -0
- package/dist/cli/interactive/stream-client.d.ts +59 -0
- package/dist/cli/interactive/stream-client.js +506 -0
- package/dist/cli/interactive/types.d.ts +121 -0
- package/dist/cli/interactive/types.js +10 -0
- package/dist/cli/providers.d.ts +15 -0
- package/dist/cli/providers.js +41 -0
- package/dist/cli/utils/api.d.ts +9 -0
- package/dist/cli/utils/api.js +58 -2
- package/dist/core/deployment.js +2 -0
- package/dist/cron/natural-language.d.ts +54 -0
- package/dist/cron/natural-language.js +569 -0
- package/dist/cron/scheduler.d.ts +34 -4
- package/dist/cron/scheduler.js +141 -9
- package/dist/cron/templates.d.ts +1 -1
- package/dist/cron/templates.js +219 -0
- package/dist/feeds/feed-engine.d.ts +149 -0
- package/dist/feeds/feed-engine.js +600 -0
- package/dist/feeds/index.d.ts +9 -0
- package/dist/feeds/index.js +8 -0
- package/dist/gateway/router.js +6 -1
- package/dist/hooks/built-in/audit-log.d.ts +11 -0
- package/dist/hooks/built-in/audit-log.js +84 -0
- package/dist/hooks/built-in/cost-warning.d.ts +10 -0
- package/dist/hooks/built-in/cost-warning.js +59 -0
- package/dist/hooks/built-in/dangerous-tool.d.ts +32 -0
- package/dist/hooks/built-in/dangerous-tool.js +80 -0
- package/dist/hooks/built-in/index.d.ts +14 -0
- package/dist/hooks/built-in/index.js +20 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/loader.d.ts +17 -0
- package/dist/hooks/loader.js +142 -0
- package/dist/hooks/registry.d.ts +62 -0
- package/dist/hooks/registry.js +127 -0
- package/dist/integrations/web-search.js +6 -3
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.js +2 -0
- package/dist/memory/memory-service.js +14 -13
- package/dist/memory/observational.d.ts +62 -0
- package/dist/memory/observational.js +396 -0
- package/dist/middleware/content-filter.d.ts +22 -0
- package/dist/middleware/content-filter.js +69 -0
- package/dist/middleware/request-validator.d.ts +159 -0
- package/dist/middleware/request-validator.js +93 -0
- package/dist/plugins/sdk.d.ts +22 -0
- package/dist/plugins/sdk.js +17 -1
- package/dist/projects/types.d.ts +10 -10
- package/dist/providers/ai-sdk.d.ts +11 -0
- package/dist/providers/ai-sdk.js +97 -18
- package/dist/providers/core/models.js +67 -1
- package/dist/providers/core/types.d.ts +3 -0
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.js +1 -0
- package/dist/providers/smart-router.d.ts +118 -0
- package/dist/providers/smart-router.js +685 -0
- package/dist/providers/types.d.ts +16 -16
- package/dist/routes/agents.js +50 -0
- package/dist/routes/auth.js +8 -1
- package/dist/routes/channels.d.ts +12 -0
- package/dist/routes/channels.js +166 -0
- package/dist/routes/chat.js +259 -14
- package/dist/routes/costs.js +32 -0
- package/dist/routes/cron.js +80 -5
- package/dist/routes/feeds.d.ts +10 -0
- package/dist/routes/feeds.js +168 -0
- package/dist/routes/mcp.js +21 -0
- package/dist/routes/memory.js +130 -0
- package/dist/routes/skills.js +129 -0
- package/dist/routes/teams.d.ts +9 -0
- package/dist/routes/teams.js +210 -0
- package/dist/routes/tools.js +14 -0
- package/dist/routes/users.js +2 -0
- package/dist/server/route-loader.js +4 -1
- package/dist/server/stream-bridge.d.ts +19 -0
- package/dist/server/stream-bridge.js +38 -0
- package/dist/server.js +421 -141
- package/dist/skills/marketplace.d.ts +87 -0
- package/dist/skills/marketplace.js +268 -0
- package/dist/storage/index.d.ts +14 -0
- package/dist/storage/index.js +64 -3
- package/dist/storage/schema.d.ts +4 -4
- package/dist/storage/schema.js +1 -1
- package/dist/teams/index.d.ts +110 -0
- package/dist/teams/index.js +365 -0
- package/dist/tickets/types.d.ts +39 -39
- package/dist/types/summary.d.ts +5 -5
- package/dist/utils/auto-update.d.ts +23 -0
- package/dist/utils/auto-update.js +157 -0
- package/dist/utils/offline-detect.d.ts +55 -0
- package/dist/utils/offline-detect.js +121 -0
- package/dist/utils/pid-file.d.ts +36 -0
- package/dist/utils/pid-file.js +125 -0
- package/dist/utils/prevent-sleep.d.ts +27 -0
- package/dist/utils/prevent-sleep.js +95 -0
- package/dist/utils/sanitizer.d.ts +57 -0
- package/dist/utils/sanitizer.js +174 -0
- package/docker-compose.yml +13 -137
- package/package.json +31 -6
- package/skills/deploy-cloudflare/SKILL.md +62 -0
- package/skills/deploy-vercel/SKILL.md +67 -0
- package/skills/docker-deploy/SKILL.md +158 -0
- package/skills/full-stack-builder/SKILL.md +92 -0
- package/skills/git-workflow/SKILL.md +3 -3
- package/skills/humanizer/SKILL.md +488 -0
- package/skills/profclaw-assistant/SKILL.md +85 -56
- package/ui/dist/assets/ActivityView-Da6HQ8ws.js +1 -0
- package/ui/dist/assets/AgentList-H58R0kX3.js +1 -0
- package/ui/dist/assets/AnalyticsDashboard-B28AeRsc.js +1 -0
- package/ui/dist/assets/AreaChart-DwLzeAQ8.js +1 -0
- package/ui/dist/assets/CartesianChart-piKQsTAR.js +36 -0
- package/ui/dist/assets/ChatView-Dbj8rxU5.js +10 -0
- package/ui/dist/assets/CostsDashboard-C6F5df0F.js +1 -0
- package/ui/dist/assets/EstimateSelect-wga0rUKX.js +1 -0
- package/ui/dist/assets/FeedDashboard-Ef6FEzEf.js +1 -0
- package/ui/dist/assets/FloatingChatbot-0yhkUeCq.js +2 -0
- package/ui/dist/assets/InviteCodeManagement-tUXfx4Bc.js +2 -0
- package/ui/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/ui/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/ui/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/ui/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/ui/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/ui/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/ui/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/ui/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/ui/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/ui/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/ui/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/ui/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/ui/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/ui/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/ui/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/ui/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/ui/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/ui/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/ui/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/ui/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/ui/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/ui/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/ui/dist/assets/MarketplacePage-DGrLtolR.js +1 -0
- package/ui/dist/assets/{ProjectDetail-DlYUcOss.js → ProjectDetail-BgWvA6UP.js} +2 -2
- package/ui/dist/assets/ProjectIcon-TDuliqwg.js +1 -0
- package/ui/dist/assets/ProjectList-DXgM4187.js +1 -0
- package/ui/dist/assets/{Settings-CgPqzUvj.js → Settings-xA8Zhi3p.js} +3 -3
- package/ui/dist/assets/StatusIndicator-B8vfFAxg.js +1 -0
- package/ui/dist/assets/{SummaryDetail-CwLAfHgJ.js → SummaryDetail-eedRfTtF.js} +2 -2
- package/ui/dist/assets/SummaryList-CLNX2P84.js +1 -0
- package/ui/dist/assets/TaskDetail-BtWclNiR.js +1 -0
- package/ui/dist/assets/TaskList-JjODAgSc.js +1 -0
- package/ui/dist/assets/TeamsPage-CBK5iAyx.js +1 -0
- package/ui/dist/assets/TicketBoard-C9aJNNYp.js +1 -0
- package/ui/dist/assets/TicketDetail-CV5JmL31.js +1 -0
- package/ui/dist/assets/TicketList-68V4lzUz.js +1 -0
- package/ui/dist/assets/UserManagement-DKTb6UpE.js +2 -0
- package/ui/dist/assets/ViewSwitcher-BvdQht2Y.js +1 -0
- package/ui/dist/assets/alert-dialog-O6qBOv_f.js +1 -0
- package/ui/dist/assets/{archive-CGck7gxR.js → archive-CX7UvZpf.js} +1 -1
- package/ui/dist/assets/badge-BbfnwDJP.js +1 -0
- package/ui/dist/assets/{bug-DqSGPUUE.js → bug-3WX0394-.js} +1 -1
- package/ui/dist/assets/{calendar-BuZ4zbPW.js → calendar-buq77TaS.js} +1 -1
- package/ui/dist/assets/{chevron-up-DcJ4LL_N.js → chevron-up-4ymsBJRo.js} +1 -1
- package/ui/dist/assets/{circle-x-C78PNZjF.js → circle-x-ByXtwR6Y.js} +1 -1
- package/ui/dist/assets/constants-CVdDh7p0.js +1 -0
- package/ui/dist/assets/{cpu-Ck6AoG8c.js → cpu-CiuoCeDY.js} +1 -1
- package/ui/dist/assets/{database-CA2w8Lvt.js → database-BWXSBg5a.js} +1 -1
- package/ui/dist/assets/dialog-lDg4NvMV.js +1 -0
- package/ui/dist/assets/dollar-sign-Dmijd6DP.js +1 -0
- package/ui/dist/assets/{ellipsis-FhHKRbfl.js → ellipsis-vT-5SVIp.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-CO0UqE4-.js → ellipsis-vertical-B4tAX_bL.js} +1 -1
- package/ui/dist/assets/feature-markdown-DBo5Q7uq.js +289 -0
- package/ui/dist/assets/{file-code-ChnhYYj1.js → file-code-ChOWdKXf.js} +1 -1
- package/ui/dist/assets/{folder-open-CHwA1-ve.js → folder-open-CkOUbIiP.js} +1 -1
- package/ui/dist/assets/{funnel-ByEjRFNB.js → funnel-uZkoSPP-.js} +1 -1
- package/ui/dist/assets/{git-branch-GTOPQgU4.js → git-branch-CwvUxj7C.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-F5M84Kut.js → git-commit-horizontal-lxPzCvhD.js} +1 -1
- package/ui/dist/assets/{globe-CQWfr7hT.js → globe-D_WpJdsj.js} +1 -1
- package/ui/dist/assets/{hash-nKC9gtLg.js → hash-CA0hJ7vh.js} +1 -1
- package/ui/dist/assets/{history-DfFSA9xJ.js → history-CEWMLELs.js} +1 -1
- package/ui/dist/assets/inbox-ehtOptTV.js +1 -0
- package/ui/dist/assets/{index-a4Fxq0Hb.js → index-C1rhbml4.js} +3 -3
- package/ui/dist/assets/index-CR8gfCHv.js +1 -0
- package/ui/dist/assets/index-DVXMpWai.js +1 -0
- package/ui/dist/assets/index-DaDJMM2v.js +1 -0
- package/ui/dist/assets/index-Djdq_0xu.js +1 -0
- package/ui/dist/assets/index-M46Gcb8K.css +1 -0
- package/ui/dist/assets/index-sEBN7w8J.js +109 -0
- package/ui/dist/assets/layers-C6Mhf8Nk.js +1 -0
- package/ui/dist/assets/{layout-dashboard-WmgjMhWF.js → layout-dashboard-BRUM0kpT.js} +1 -1
- package/ui/dist/assets/{lightbulb-Bo8hEr7B.js → lightbulb-CN2q1O5l.js} +1 -1
- package/ui/dist/assets/{link-2-YqrpQXBH.js → link-2-CC4E28yJ.js} +1 -1
- package/ui/dist/assets/markdown-renderer-C6ENbB0u.js +10 -0
- package/ui/dist/assets/markdown-renderer-CfVKi3_s.css +1 -0
- package/ui/dist/assets/{message-square-CD0H5hot.js → message-square-Bbb241am.js} +1 -1
- package/ui/dist/assets/package-CwT3IzFx.js +1 -0
- package/ui/dist/assets/{pencil-DpFnj5dn.js → pencil-CDmiHzoj.js} +1 -1
- package/ui/dist/assets/{play-DVgea_jT.js → play-tjy5jMQX.js} +1 -1
- package/ui/dist/assets/popover-CFHZf3pE.js +1 -0
- package/ui/dist/assets/progress-BboUHuLf.js +1 -0
- package/ui/dist/assets/{rocket-BFxPYGx9.js → rocket--8ZHgdXJ.js} +1 -1
- package/ui/dist/assets/select-n108rXny.js +1 -0
- package/ui/dist/assets/{send-eYnW_7n-.js → send-Cu7MR2Qh.js} +1 -1
- package/ui/dist/assets/server-DmodxZp-.js +1 -0
- package/ui/dist/assets/{settings-2-scXUOuE_.js → settings-2-CkRNqkxj.js} +1 -1
- package/ui/dist/assets/sheet-7aUJkyzU.js +1 -0
- package/ui/dist/assets/{shield-check-PEr7nmVw.js → shield-check-ViI3nMKE.js} +1 -1
- package/ui/dist/assets/{shield-off-CLtXio62.js → shield-off-DN3tagkn.js} +1 -1
- package/ui/dist/assets/skeleton-C0E1Nfro.js +1 -0
- package/ui/dist/assets/{smartphone-DusFfY0U.js → smartphone-5FghiXpA.js} +1 -1
- package/ui/dist/assets/{square-e1yxB2eR.js → square-DiNSx8K7.js} +1 -1
- package/ui/dist/assets/star-DhdFVidS.js +1 -0
- package/ui/dist/assets/switch-CIgVbZqQ.js +1 -0
- package/ui/dist/assets/table-BC56FVMV.js +1 -0
- package/ui/dist/assets/{tag-tAwMmQ9G.js → tag-CH_vQliw.js} +1 -1
- package/ui/dist/assets/textarea-CxDiKFXZ.js +1 -0
- package/ui/dist/assets/{timer-Vel1N3RP.js → timer-CdGVTb60.js} +1 -1
- package/ui/dist/assets/tooltip-BuW9A5UO.js +1 -0
- package/ui/dist/assets/{trash-2-eM-CNwsZ.js → trash-2-CucZJL0N.js} +1 -1
- package/ui/dist/assets/trending-down-BCezC1z2.js +1 -0
- package/ui/dist/assets/{trending-up-BGafmjRo.js → trending-up-C5OYX2k2.js} +1 -1
- package/ui/dist/assets/vendor-query-C0p7b53x.js +4 -0
- package/ui/dist/assets/vendor-react-Mc5_kfYG.js +12 -0
- package/ui/dist/assets/vendor-ui-CXPAUBFv.js +51 -0
- package/ui/dist/assets/{wand-sparkles-DPvcd9Pi.js → wand-sparkles-BaH6pJnc.js} +1 -1
- package/ui/dist/assets/{wrench-B8s3zYVV.js → wrench-CjxjP6ok.js} +1 -1
- package/ui/dist/index.html +5 -2
- package/dist/chat/auto-reply.d.ts +0 -90
- package/dist/chat/auto-reply.js +0 -272
- package/dist/chat/execution/pty.d.ts +0 -92
- package/dist/chat/execution/pty.js +0 -285
- package/dist/chat/execution/tools/glinr-ops.d.ts +0 -202
- package/dist/chat/execution/tools/glinr-ops.js +0 -694
- package/dist/cli/commands/browser.d.ts +0 -3
- package/dist/cli/commands/browser.js +0 -138
- package/dist/cli/commands/canvas.d.ts +0 -3
- package/dist/cli/commands/canvas.js +0 -155
- package/dist/cli/commands/nodes.d.ts +0 -3
- package/dist/cli/commands/nodes.js +0 -193
- package/dist/diagnostics/exporters.d.ts +0 -21
- package/dist/diagnostics/exporters.js +0 -138
- package/dist/diagnostics/index.d.ts +0 -10
- package/dist/diagnostics/index.js +0 -9
- package/dist/diagnostics/middleware.d.ts +0 -12
- package/dist/diagnostics/middleware.js +0 -58
- package/dist/diagnostics/tracer.d.ts +0 -133
- package/dist/diagnostics/tracer.js +0 -257
- package/dist/discovery/index.d.ts +0 -8
- package/dist/discovery/index.js +0 -7
- package/dist/discovery/mdns.d.ts +0 -40
- package/dist/discovery/mdns.js +0 -249
- package/dist/plugins/registry.d.ts +0 -122
- package/dist/plugins/registry.js +0 -352
- package/dist/plugins/sandbox.d.ts +0 -77
- package/dist/plugins/sandbox.js +0 -287
- package/dist/plugins/search/brave.d.ts +0 -9
- package/dist/plugins/search/brave.js +0 -157
- package/dist/plugins/search/duckduckgo.d.ts +0 -9
- package/dist/plugins/search/duckduckgo.js +0 -171
- package/dist/plugins/search/index.d.ts +0 -13
- package/dist/plugins/search/index.js +0 -23
- package/dist/plugins/search/searxng.d.ts +0 -9
- package/dist/plugins/search/searxng.js +0 -170
- package/dist/plugins/search/serper.d.ts +0 -9
- package/dist/plugins/search/serper.js +0 -135
- package/dist/plugins/search/tavily.d.ts +0 -9
- package/dist/plugins/search/tavily.js +0 -146
- package/dist/providers/adapters/anthropic.d.ts +0 -26
- package/dist/providers/adapters/anthropic.js +0 -306
- package/dist/providers/adapters/base.d.ts +0 -53
- package/dist/providers/adapters/base.js +0 -99
- package/dist/providers/adapters/ollama.d.ts +0 -30
- package/dist/providers/adapters/ollama.js +0 -292
- package/dist/utils/ai-cache.d.ts +0 -72
- package/dist/utils/ai-cache.js +0 -204
- package/dist/utils/file-lock.d.ts +0 -85
- package/dist/utils/file-lock.js +0 -204
- package/ui/dist/assets/ActivityView-DIPQSJ_d.js +0 -1
- package/ui/dist/assets/AgentList-CqyaYrcq.js +0 -1
- package/ui/dist/assets/AnalyticsDashboard-C-mjuGHT.js +0 -1
- package/ui/dist/assets/AreaChart-CfYWmbtr.js +0 -1
- package/ui/dist/assets/CartesianChart-BaQ3It0c.js +0 -36
- package/ui/dist/assets/ChatView-DxxQy6pl.js +0 -10
- package/ui/dist/assets/CostsDashboard-CDBBcGkg.js +0 -1
- package/ui/dist/assets/EstimateSelect-CDjf5qKl.js +0 -1
- package/ui/dist/assets/FloatingChatbot-CZHjvJIe.js +0 -2
- package/ui/dist/assets/InviteCodeManagement-DTm-IPTm.js +0 -2
- package/ui/dist/assets/ProjectIcon-BMRpnM04.js +0 -1
- package/ui/dist/assets/ProjectList-D85TN0i0.js +0 -4
- package/ui/dist/assets/StatusIndicator-yig0uZEA.js +0 -1
- package/ui/dist/assets/SummaryList-BvS5Idnu.js +0 -1
- package/ui/dist/assets/TaskDetail-zarC1fOt.js +0 -1
- package/ui/dist/assets/TaskList-CyJq3ANE.js +0 -1
- package/ui/dist/assets/TicketBoard-BlWr3-iH.js +0 -1
- package/ui/dist/assets/TicketDetail-DmqWKj2W.js +0 -1
- package/ui/dist/assets/TicketList-Scj4pMWa.js +0 -1
- package/ui/dist/assets/UserManagement-BH7uG7dw.js +0 -2
- package/ui/dist/assets/ViewSwitcher-3HzZUdWn.js +0 -1
- package/ui/dist/assets/alert-dialog-DWPb2IfQ.js +0 -7
- package/ui/dist/assets/badge-DEmc3Z_l.js +0 -1
- package/ui/dist/assets/brain-CfFdLVqb.js +0 -1
- package/ui/dist/assets/constants-DhDjZe4P.js +0 -1
- package/ui/dist/assets/dialog-BOdGWhgE.js +0 -1
- package/ui/dist/assets/index--JkIxVXb.js +0 -67
- package/ui/dist/assets/index-Ca3vk7Gq.js +0 -1
- package/ui/dist/assets/index-DHGvP9mp.js +0 -1
- package/ui/dist/assets/index-DeI8lKRR.js +0 -1
- package/ui/dist/assets/index-WclMPci1.css +0 -1
- package/ui/dist/assets/index-Z4-RtZcs.js +0 -1
- package/ui/dist/assets/layers-DFeLExSa.js +0 -1
- package/ui/dist/assets/markdown-renderer-Croje6Xe.js +0 -36
- package/ui/dist/assets/popover-JXecfWG5.js +0 -1
- package/ui/dist/assets/progress-C1ghf1Fu.js +0 -1
- package/ui/dist/assets/select-MADP8m6Q.js +0 -1
- package/ui/dist/assets/server-CPMaysH8.js +0 -1
- package/ui/dist/assets/sheet-r6NSOxi-.js +0 -1
- package/ui/dist/assets/skeleton-C9oEzNlU.js +0 -1
- package/ui/dist/assets/switch-tNs0n-kz.js +0 -1
- package/ui/dist/assets/table-CXxtLicg.js +0 -1
- package/ui/dist/assets/textarea-BjiEeIWh.js +0 -1
- package/ui/dist/assets/tooltip-ZMwtfr1J.js +0 -1
|
@@ -11,14 +11,28 @@
|
|
|
11
11
|
import { Command } from 'commander';
|
|
12
12
|
import chalk from 'chalk';
|
|
13
13
|
import figlet from 'figlet';
|
|
14
|
-
import { select, input, password as passwordPrompt, confirm } from '@inquirer/prompts';
|
|
14
|
+
import { select, search, input, password as passwordPrompt, confirm, Separator } from '@inquirer/prompts';
|
|
15
15
|
import { randomUUID } from 'crypto';
|
|
16
16
|
import { eq } from 'drizzle-orm';
|
|
17
|
-
import {
|
|
17
|
+
import { spawn, execFile } from 'child_process';
|
|
18
|
+
import { existsSync, mkdirSync, openSync } from 'node:fs';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { promisify } from 'node:util';
|
|
21
|
+
import * as os from 'os';
|
|
22
|
+
import { createServer } from 'net';
|
|
23
|
+
import { initStorage, getDb, closeStorage, saveProviderConfig, loadAllProviderConfigs } from '../../storage/index.js';
|
|
18
24
|
import { users, inviteCodes } from '../../storage/schema.js';
|
|
25
|
+
import { PROVIDER_CATALOG } from '../providers.js';
|
|
19
26
|
import { hashPassword, validatePasswordStrength, generateRecoveryCodes, hashRecoveryCodes, generateInviteCode, hashInviteCode, } from '../../auth/password.js';
|
|
20
27
|
import { updateSettings } from '../../settings/index.js';
|
|
21
28
|
import { success, error, info, warn, spinner } from '../utils/output.js';
|
|
29
|
+
/** Render a step header with progress bar. */
|
|
30
|
+
function stepHeader(step, total, title) {
|
|
31
|
+
const barLen = 20;
|
|
32
|
+
const filled = Math.round((step / total) * barLen);
|
|
33
|
+
const bar = chalk.cyan('━'.repeat(filled)) + chalk.dim('━'.repeat(barLen - filled));
|
|
34
|
+
console.log(`\n ${bar} ${chalk.dim(`${step}/${total}`)} ${chalk.bold.white(title)}\n`);
|
|
35
|
+
}
|
|
22
36
|
// Helpers
|
|
23
37
|
function showBanner() {
|
|
24
38
|
const banner = figlet.textSync('profClaw', {
|
|
@@ -122,32 +136,46 @@ function hasEnvKey(key) {
|
|
|
122
136
|
return !!val && val !== '' && !val.startsWith('sk-ant-xxxx') && !val.startsWith('sk-xxxx');
|
|
123
137
|
}
|
|
124
138
|
// Step 1: System Check
|
|
139
|
+
async function detectConfiguredProvider() {
|
|
140
|
+
// Check env vars first
|
|
141
|
+
for (const p of PROVIDER_CATALOG) {
|
|
142
|
+
if (hasEnvKey(p.envVar))
|
|
143
|
+
return p.name;
|
|
144
|
+
}
|
|
145
|
+
// Check database (saved via saveProviderConfig)
|
|
146
|
+
try {
|
|
147
|
+
const saved = await loadAllProviderConfigs();
|
|
148
|
+
const enabled = saved.find(s => s.enabled);
|
|
149
|
+
if (enabled) {
|
|
150
|
+
const match = PROVIDER_CATALOG.find(p => p.key === enabled.type);
|
|
151
|
+
return match ? `${match.name} (saved)` : enabled.type;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch { /* db not ready yet */ }
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
125
157
|
async function stepSystemCheck(db) {
|
|
126
|
-
console.log(chalk.bold.white('\n Step 1: System Check\n'));
|
|
127
158
|
const spin = spinner('Checking system...');
|
|
128
159
|
spin.start();
|
|
129
160
|
const redisOk = await checkRedis();
|
|
130
161
|
const hasAdmin = await checkAdminExists(db);
|
|
131
|
-
const
|
|
132
|
-
const
|
|
162
|
+
const providerName = await detectConfiguredProvider();
|
|
163
|
+
const hasProvider = !!providerName;
|
|
133
164
|
spin.stop();
|
|
134
|
-
const mark = (ok) => (ok ? chalk.green('
|
|
165
|
+
const mark = (ok) => (ok ? chalk.green(' \u2713') : chalk.red(' \u2717'));
|
|
135
166
|
console.log(`${mark(redisOk)} Redis: ${redisOk ? 'connected' : 'not reachable'}`);
|
|
136
167
|
console.log(`${mark(hasAdmin)} Admin account: ${hasAdmin ? 'exists' : 'not created'}`);
|
|
137
|
-
console.log(`${mark(
|
|
138
|
-
hasOpenAIKey ? 'OpenAI key found' :
|
|
139
|
-
'not configured'}`);
|
|
168
|
+
console.log(`${mark(hasProvider)} AI provider: ${providerName || 'not configured'}`);
|
|
140
169
|
if (!redisOk) {
|
|
141
170
|
warn('Redis is required for task processing.');
|
|
142
171
|
info('Start Redis: docker compose up redis -d');
|
|
143
172
|
}
|
|
144
|
-
return { redisOk, hasAdmin,
|
|
173
|
+
return { redisOk, hasAdmin, hasProvider, providerName };
|
|
145
174
|
}
|
|
146
175
|
// Step 2: AI Provider
|
|
147
176
|
async function stepAiProvider(status) {
|
|
148
|
-
if (status.
|
|
149
|
-
|
|
150
|
-
info(`AI provider already configured (${provider} from env).`);
|
|
177
|
+
if (status.hasProvider) {
|
|
178
|
+
info(`AI provider already configured (${status.providerName}).`);
|
|
151
179
|
try {
|
|
152
180
|
const reconfigure = await confirm({
|
|
153
181
|
message: 'Reconfigure AI provider?',
|
|
@@ -155,22 +183,63 @@ async function stepAiProvider(status) {
|
|
|
155
183
|
theme,
|
|
156
184
|
});
|
|
157
185
|
if (!reconfigure)
|
|
158
|
-
return '
|
|
186
|
+
return status.providerName || 'configured';
|
|
159
187
|
}
|
|
160
188
|
catch {
|
|
161
|
-
return '
|
|
189
|
+
return status.providerName || 'configured';
|
|
162
190
|
}
|
|
163
191
|
}
|
|
192
|
+
// Detect which providers already have keys
|
|
193
|
+
const detected = new Set();
|
|
194
|
+
for (const p of PROVIDER_CATALOG) {
|
|
195
|
+
if (process.env[p.envVar])
|
|
196
|
+
detected.add(p.key);
|
|
197
|
+
}
|
|
198
|
+
// Check Ollama service
|
|
199
|
+
const ollamaRunning = await checkOllama(process.env.OLLAMA_BASE_URL || 'http://localhost:11434');
|
|
200
|
+
if (ollamaRunning)
|
|
201
|
+
detected.add('ollama');
|
|
164
202
|
let choice;
|
|
165
203
|
try {
|
|
166
|
-
choice = await
|
|
167
|
-
message: 'Select AI
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
204
|
+
choice = await search({
|
|
205
|
+
message: 'Select AI provider (type to filter, arrows to navigate)',
|
|
206
|
+
pageSize: 15,
|
|
207
|
+
source: (term) => {
|
|
208
|
+
const results = [];
|
|
209
|
+
const filter = (term || '').toLowerCase();
|
|
210
|
+
let lastCategory = '';
|
|
211
|
+
for (const p of PROVIDER_CATALOG) {
|
|
212
|
+
if (filter && ![p.name, p.key, p.models, p.category, p.tag]
|
|
213
|
+
.some(s => s.toLowerCase().includes(filter))) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (p.category !== lastCategory) {
|
|
217
|
+
if (results.length > 0)
|
|
218
|
+
results.push(new Separator());
|
|
219
|
+
results.push(new Separator(chalk.bold.cyan(` ${p.category} `)));
|
|
220
|
+
lastCategory = p.category;
|
|
221
|
+
}
|
|
222
|
+
const det = detected.has(p.key) ? chalk.green(' *') : '';
|
|
223
|
+
const ollamaTag = p.key === 'ollama' && ollamaRunning ? 'detected' : p.tag;
|
|
224
|
+
const tag = ollamaTag ? ` ${chalk.dim(`[${ollamaTag}]`)}` : '';
|
|
225
|
+
results.push({
|
|
226
|
+
name: `${p.name.padEnd(16)} ${chalk.dim(p.models)}${tag}${det}`,
|
|
227
|
+
value: p.key,
|
|
228
|
+
description: p.envVar,
|
|
229
|
+
short: p.name,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
if (!filter || 'skip'.includes(filter)) {
|
|
233
|
+
results.push(new Separator());
|
|
234
|
+
results.push({
|
|
235
|
+
name: chalk.dim('Skip for now'),
|
|
236
|
+
value: 'skip',
|
|
237
|
+
description: 'Configure later in Settings',
|
|
238
|
+
short: 'Skip',
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return results;
|
|
242
|
+
},
|
|
174
243
|
theme,
|
|
175
244
|
});
|
|
176
245
|
}
|
|
@@ -181,58 +250,61 @@ async function stepAiProvider(status) {
|
|
|
181
250
|
info('AI provider skipped. You can configure it later in Settings.');
|
|
182
251
|
return 'skip';
|
|
183
252
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
253
|
+
const chosen = PROVIDER_CATALOG.find(p => p.key === choice);
|
|
254
|
+
if (!chosen)
|
|
255
|
+
return 'skip';
|
|
256
|
+
console.log(`\n ${chalk.bold(chosen.name)} selected`);
|
|
257
|
+
console.log(chalk.dim(` Env var: ${chosen.envVar}`));
|
|
258
|
+
// Ollama special case
|
|
259
|
+
if (chosen.key === 'ollama') {
|
|
260
|
+
const ollamaUrl = process.env.OLLAMA_BASE_URL || 'http://localhost:11434';
|
|
261
|
+
const spin = spinner(`Checking Ollama at ${ollamaUrl}...`);
|
|
262
|
+
spin.start();
|
|
263
|
+
const ollamaOk = await checkOllama(ollamaUrl);
|
|
264
|
+
spin.stop();
|
|
265
|
+
if (ollamaOk) {
|
|
266
|
+
success(`Ollama reachable at ${ollamaUrl}`);
|
|
267
|
+
await saveProviderConfig({ type: 'ollama', apiKey: ollamaUrl, enabled: true });
|
|
268
|
+
await updateSettings({
|
|
269
|
+
integrations: { ollamaEndpoint: ollamaUrl },
|
|
270
|
+
plugins: { ollama: { enabled: true, autoStart: false } },
|
|
271
|
+
});
|
|
272
|
+
success('Ollama provider configured.');
|
|
194
273
|
}
|
|
195
|
-
|
|
196
|
-
|
|
274
|
+
else {
|
|
275
|
+
warn(`Ollama not reachable at ${ollamaUrl}`);
|
|
276
|
+
info('Start Ollama: docker compose --profile ai up -d');
|
|
277
|
+
info('Then re-run: profclaw setup');
|
|
278
|
+
await saveProviderConfig({ type: 'ollama', apiKey: ollamaUrl, enabled: true });
|
|
197
279
|
}
|
|
280
|
+
return 'ollama';
|
|
198
281
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
warn('No key provided, skipping.');
|
|
204
|
-
return 'skip';
|
|
205
|
-
}
|
|
206
|
-
await saveProviderConfig({ type: 'openai', apiKey, enabled: true });
|
|
207
|
-
success('OpenAI provider configured.');
|
|
208
|
-
return 'openai';
|
|
209
|
-
}
|
|
210
|
-
catch {
|
|
211
|
-
return 'skip';
|
|
212
|
-
}
|
|
282
|
+
// Already detected
|
|
283
|
+
if (detected.has(chosen.key)) {
|
|
284
|
+
success(`${chosen.name} already configured from ${chosen.envVar}`);
|
|
285
|
+
return chosen.key;
|
|
213
286
|
}
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const ollamaOk = await checkOllama(ollamaUrl);
|
|
219
|
-
spin.stop();
|
|
220
|
-
if (ollamaOk) {
|
|
221
|
-
success(`Ollama reachable at ${ollamaUrl}`);
|
|
222
|
-
await saveProviderConfig({ type: 'ollama', apiKey: ollamaUrl, enabled: true });
|
|
223
|
-
await updateSettings({
|
|
224
|
-
integrations: { ollamaEndpoint: ollamaUrl },
|
|
225
|
-
plugins: { ollama: { enabled: true, autoStart: false } },
|
|
226
|
-
});
|
|
227
|
-
success('Ollama provider configured.');
|
|
287
|
+
// Prompt for API key
|
|
288
|
+
let apiKey;
|
|
289
|
+
try {
|
|
290
|
+
apiKey = await input({ message: chosen.envVar, theme });
|
|
228
291
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
292
|
+
catch {
|
|
293
|
+
return 'skip';
|
|
294
|
+
}
|
|
295
|
+
if (!apiKey) {
|
|
296
|
+
warn('No key provided, skipping.');
|
|
297
|
+
return 'skip';
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
await saveProviderConfig({ type: chosen.key, apiKey, enabled: true });
|
|
301
|
+
success(`${chosen.name} provider configured.`);
|
|
302
|
+
return chosen.key;
|
|
303
|
+
}
|
|
304
|
+
catch (err) {
|
|
305
|
+
error(`Failed to save: ${err instanceof Error ? err.message : 'unknown'}`);
|
|
306
|
+
return 'skip';
|
|
234
307
|
}
|
|
235
|
-
return 'ollama';
|
|
236
308
|
}
|
|
237
309
|
// Step 3: Admin Account
|
|
238
310
|
async function createAdminUser(db, name, email, password) {
|
|
@@ -267,7 +339,6 @@ async function stepAdminAccount(db) {
|
|
|
267
339
|
error('Database not available. Cannot create admin account.');
|
|
268
340
|
return null;
|
|
269
341
|
}
|
|
270
|
-
console.log(chalk.bold.white('\n Step 3: Admin Account\n'));
|
|
271
342
|
const existingAdmins = await getExistingAdmins(db);
|
|
272
343
|
if (existingAdmins.length > 0) {
|
|
273
344
|
console.log(chalk.dim(' Existing admin accounts:'));
|
|
@@ -414,7 +485,6 @@ async function stepAdminAccount(db) {
|
|
|
414
485
|
}
|
|
415
486
|
// Step 4: Registration Mode
|
|
416
487
|
async function stepRegistrationMode(db) {
|
|
417
|
-
console.log(chalk.bold.white('\n Step 4: Registration Mode\n'));
|
|
418
488
|
let mode;
|
|
419
489
|
try {
|
|
420
490
|
mode = await select({
|
|
@@ -472,7 +542,6 @@ async function stepRegistrationMode(db) {
|
|
|
472
542
|
}
|
|
473
543
|
// Step 5: GitHub OAuth (optional)
|
|
474
544
|
async function stepGitHubOAuth() {
|
|
475
|
-
console.log(chalk.bold.white('\n Step 5: GitHub OAuth (Optional)\n'));
|
|
476
545
|
let configure;
|
|
477
546
|
try {
|
|
478
547
|
configure = await confirm({
|
|
@@ -519,19 +588,186 @@ async function stepGitHubOAuth() {
|
|
|
519
588
|
return true;
|
|
520
589
|
}
|
|
521
590
|
// Step 6: Summary
|
|
522
|
-
|
|
523
|
-
|
|
591
|
+
const execFileAsync = promisify(execFile);
|
|
592
|
+
async function runQuickHealthCheck() {
|
|
593
|
+
const results = [];
|
|
594
|
+
// 1. Node.js version
|
|
595
|
+
const nodeVersion = process.version;
|
|
596
|
+
const nodeMajor = parseInt(nodeVersion.slice(1).split('.')[0], 10);
|
|
597
|
+
results.push({
|
|
598
|
+
label: 'Node.js',
|
|
599
|
+
status: nodeMajor >= 20 ? 'pass' : 'warn',
|
|
600
|
+
detail: nodeMajor >= 20 ? nodeVersion : `${nodeVersion} (v20+ recommended)`,
|
|
601
|
+
});
|
|
602
|
+
// 2. Config files
|
|
603
|
+
const cwd = process.cwd();
|
|
604
|
+
const settingsExists = existsSync(join(cwd, 'config', 'settings.yml'));
|
|
605
|
+
const envExists = existsSync(join(cwd, '.env'));
|
|
606
|
+
const configStatus = settingsExists && envExists ? 'pass' : settingsExists || envExists ? 'warn' : 'fail';
|
|
607
|
+
const configDetail = settingsExists && envExists
|
|
608
|
+
? 'settings.yml + .env found'
|
|
609
|
+
: settingsExists
|
|
610
|
+
? 'settings.yml found, .env missing'
|
|
611
|
+
: envExists
|
|
612
|
+
? '.env found, settings.yml missing'
|
|
613
|
+
: 'settings.yml and .env not found';
|
|
614
|
+
results.push({ label: 'Config', status: configStatus, detail: configDetail });
|
|
615
|
+
// 3. Database — initStorage() already ran, so if we get here the DB is initialized
|
|
616
|
+
results.push({ label: 'Database', status: 'pass', detail: 'Initialized' });
|
|
617
|
+
// 4. Memory
|
|
618
|
+
const freeBytes = os.freemem();
|
|
619
|
+
const freeMb = freeBytes / 1024 / 1024;
|
|
620
|
+
const freeGb = freeBytes / 1024 / 1024 / 1024;
|
|
621
|
+
const memDetail = freeGb >= 1 ? `${freeGb.toFixed(1)} GB free` : `${Math.round(freeMb)} MB free`;
|
|
622
|
+
results.push({
|
|
623
|
+
label: 'Memory',
|
|
624
|
+
status: freeMb >= 256 ? 'pass' : 'warn',
|
|
625
|
+
detail: freeMb >= 256 ? memDetail : `${memDetail} (low)`,
|
|
626
|
+
});
|
|
627
|
+
// 5. Disk — df on cwd
|
|
628
|
+
let diskDetail = 'unavailable';
|
|
629
|
+
let diskStatus = 'warn';
|
|
630
|
+
try {
|
|
631
|
+
const { stdout } = await execFileAsync('df', ['-k', cwd]);
|
|
632
|
+
const lines = stdout.trim().split('\n');
|
|
633
|
+
if (lines.length >= 2) {
|
|
634
|
+
const parts = lines[1].trim().split(/\s+/);
|
|
635
|
+
// df -k columns: Filesystem 1K-blocks Used Available Use% Mounted (macOS/Linux may vary)
|
|
636
|
+
const availIdx = parts.length >= 4 ? (parts.length === 6 ? 3 : parts.length - 3) : -1;
|
|
637
|
+
const useIdx = parts.length >= 5 ? parts.length - 2 : -1;
|
|
638
|
+
if (availIdx !== -1 && useIdx !== -1) {
|
|
639
|
+
const availKb = parseInt(parts[availIdx], 10);
|
|
640
|
+
const usePercent = parts[useIdx];
|
|
641
|
+
const availGb = availKb / 1024 / 1024;
|
|
642
|
+
diskDetail = `${availGb.toFixed(0)} GB free (${usePercent} used)`;
|
|
643
|
+
diskStatus = availGb >= 1 ? 'pass' : 'warn';
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
catch { /* df not available */ }
|
|
648
|
+
results.push({ label: 'Disk', status: diskStatus, detail: diskDetail });
|
|
649
|
+
// Render
|
|
650
|
+
const icon = (s) => s === 'pass' ? chalk.green('\u2713') : s === 'warn' ? chalk.yellow('\u26a0') : chalk.red('\u2717');
|
|
651
|
+
const labelWidth = 12;
|
|
652
|
+
console.log('');
|
|
653
|
+
console.log(chalk.bold.white(' Quick Health Check'));
|
|
654
|
+
console.log(' ' + '\u2500'.repeat(44));
|
|
655
|
+
for (const r of results) {
|
|
656
|
+
const label = r.label.padEnd(labelWidth);
|
|
657
|
+
console.log(` ${icon(r.status)} ${chalk.dim(label)} ${r.detail}`);
|
|
658
|
+
}
|
|
659
|
+
console.log(' ' + '\u2500'.repeat(44));
|
|
660
|
+
const passed = results.filter(r => r.status === 'pass').length;
|
|
661
|
+
const total = results.length;
|
|
662
|
+
const summary = passed === total ? chalk.green(`${passed}/${total} checks passed`) : chalk.yellow(`${passed}/${total} checks passed`);
|
|
663
|
+
console.log(` ${summary}`);
|
|
664
|
+
}
|
|
665
|
+
function checkPortAvailable(port) {
|
|
666
|
+
return new Promise((resolve) => {
|
|
667
|
+
const server = createServer();
|
|
668
|
+
server.once('error', () => resolve(false));
|
|
669
|
+
server.once('listening', () => { server.close(); resolve(true); });
|
|
670
|
+
server.listen(port);
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
async function showSummaryAndOffer(results) {
|
|
674
|
+
const port = parseInt(process.env.PORT || '3000', 10);
|
|
524
675
|
console.log(chalk.bold.white('\n Setup Complete!\n'));
|
|
525
|
-
console.log(' ' + '
|
|
526
|
-
const mark = (ok) => (ok ? chalk.green('
|
|
676
|
+
console.log(' ' + '\u2500'.repeat(44));
|
|
677
|
+
const mark = (ok) => (ok ? chalk.green('\u2713') : chalk.yellow('\u2717'));
|
|
527
678
|
console.log(` ${mark(results.redisOk)} Redis: ${results.redisOk ? 'connected' : 'not connected'}`);
|
|
528
679
|
console.log(` ${mark(results.aiProvider !== 'skip')} AI: ${results.aiProvider === 'skip' ? 'not configured' : results.aiProvider}`);
|
|
529
680
|
console.log(` ${mark(!!results.adminEmail)} Admin: ${results.adminEmail || 'not created'}`);
|
|
530
681
|
console.log(` ${mark(true)} Registration: ${results.registrationMode}${results.inviteCodes.length ? ` (${results.inviteCodes.length} codes)` : ''}`);
|
|
531
682
|
console.log(` ${mark(results.githubOAuth)} GitHub OAuth: ${results.githubOAuth ? 'configured' : 'skipped'}`);
|
|
532
|
-
console.log(' ' + '
|
|
683
|
+
console.log(' ' + '\u2500'.repeat(44));
|
|
684
|
+
await runQuickHealthCheck();
|
|
685
|
+
// Check if server is already running
|
|
686
|
+
const portFree = await checkPortAvailable(port);
|
|
687
|
+
const serverRunning = !portFree;
|
|
688
|
+
if (serverRunning) {
|
|
689
|
+
// Server already running - just show the URL
|
|
690
|
+
console.log('');
|
|
691
|
+
success(`Server already running on port ${port}`);
|
|
692
|
+
console.log(`\n ${chalk.cyan.bold(`http://localhost:${port}`)}\n`);
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
// Offer to start the server
|
|
696
|
+
console.log('');
|
|
697
|
+
let startServer = false;
|
|
698
|
+
try {
|
|
699
|
+
startServer = await confirm({
|
|
700
|
+
message: 'Start the server now?',
|
|
701
|
+
default: true,
|
|
702
|
+
theme,
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
catch { /* Ctrl+C */ }
|
|
706
|
+
if (startServer) {
|
|
707
|
+
console.log('');
|
|
708
|
+
const startSpin = spinner('Starting server...');
|
|
709
|
+
startSpin.start();
|
|
710
|
+
// Determine runtime
|
|
711
|
+
const distPath = 'dist/server.js';
|
|
712
|
+
const useCompiled = existsSync(distPath);
|
|
713
|
+
const cmd = useCompiled ? 'node' : 'npx';
|
|
714
|
+
const args = useCompiled ? [distPath] : ['tsx', 'src/server.ts'];
|
|
715
|
+
// Redirect server output to log file (keep terminal clean)
|
|
716
|
+
const logDir = join(process.cwd(), 'data');
|
|
717
|
+
if (!existsSync(logDir))
|
|
718
|
+
mkdirSync(logDir, { recursive: true });
|
|
719
|
+
const logPath = join(logDir, 'server.log');
|
|
720
|
+
const logFd = openSync(logPath, 'a');
|
|
721
|
+
const child = spawn(cmd, args, {
|
|
722
|
+
stdio: ['ignore', logFd, logFd],
|
|
723
|
+
detached: true,
|
|
724
|
+
env: { ...process.env, PORT: String(port) },
|
|
725
|
+
});
|
|
726
|
+
child.unref();
|
|
727
|
+
// Wait for server to start, polling health check
|
|
728
|
+
let serverOk = false;
|
|
729
|
+
for (let i = 0; i < 5; i++) {
|
|
730
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
731
|
+
try {
|
|
732
|
+
const res = await fetch(`http://localhost:${port}/health`, {
|
|
733
|
+
signal: AbortSignal.timeout(2000),
|
|
734
|
+
});
|
|
735
|
+
if (res.ok) {
|
|
736
|
+
serverOk = true;
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
catch { /* not ready yet */ }
|
|
741
|
+
}
|
|
742
|
+
startSpin.stop();
|
|
743
|
+
if (serverOk) {
|
|
744
|
+
success(`Server running on port ${port}`);
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
warn('Server starting in background (health check pending)');
|
|
748
|
+
}
|
|
749
|
+
console.log(`\n ${chalk.cyan.bold(`http://localhost:${port}`)}`);
|
|
750
|
+
console.log('');
|
|
751
|
+
console.log(chalk.dim(' Server is running in the background.'));
|
|
752
|
+
console.log(chalk.dim(` Stop: ${chalk.white('profclaw daemon stop')} or ${chalk.white(`kill $(lsof -ti :${port})`)}`));
|
|
753
|
+
console.log(chalk.dim(` Logs: ${chalk.white(`tail -f ${logPath}`)}`));
|
|
754
|
+
console.log(chalk.dim(` Status: ${chalk.white('profclaw doctor')}`));
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
console.log('');
|
|
758
|
+
console.log(` Start later with: ${chalk.cyan.bold('profclaw serve')}`);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
// Always show helpful next steps
|
|
533
762
|
console.log('');
|
|
534
|
-
console.log(
|
|
763
|
+
console.log(chalk.bold.white(' Next Steps'));
|
|
764
|
+
console.log(' ' + '\u2500'.repeat(44));
|
|
765
|
+
console.log(` ${chalk.cyan('profclaw doctor')} Health check (12 tests)`);
|
|
766
|
+
console.log(` ${chalk.cyan('profclaw chat quick')} ${chalk.dim('"hi"')} Chat with AI`);
|
|
767
|
+
console.log(` ${chalk.cyan('profclaw task list')} View agent tasks`);
|
|
768
|
+
console.log(` ${chalk.cyan('profclaw tools list')} Available tools`);
|
|
769
|
+
console.log(` ${chalk.cyan('profclaw provider test')} Test AI provider`);
|
|
770
|
+
console.log(` ${chalk.cyan('profclaw --help')} All commands`);
|
|
535
771
|
console.log('');
|
|
536
772
|
}
|
|
537
773
|
// Non-Interactive Mode
|
|
@@ -657,6 +893,7 @@ export function setupCommand() {
|
|
|
657
893
|
.option('--admin-name <name>', 'Admin display name (non-interactive)')
|
|
658
894
|
.option('--ai-provider <provider>', 'AI provider: anthropic, openai, ollama, skip (non-interactive)')
|
|
659
895
|
.option('--registration-mode <mode>', 'Registration mode: invite, open (non-interactive)')
|
|
896
|
+
.option('--from-onboard', 'Called from onboard wizard (skip AI provider)')
|
|
660
897
|
.action(async (options) => {
|
|
661
898
|
try {
|
|
662
899
|
// Non-interactive mode
|
|
@@ -668,42 +905,89 @@ export function setupCommand() {
|
|
|
668
905
|
aiProvider: options.aiProvider,
|
|
669
906
|
registrationMode: options.registrationMode,
|
|
670
907
|
});
|
|
671
|
-
|
|
908
|
+
await closeStorage();
|
|
909
|
+
process.exit(0);
|
|
672
910
|
}
|
|
911
|
+
const fromOnboard = !!options.fromOnboard;
|
|
673
912
|
// Interactive mode
|
|
674
|
-
|
|
913
|
+
if (!fromOnboard)
|
|
914
|
+
showBanner();
|
|
915
|
+
// Suppress initialization noise ([INFO] Initializing LibSQL storage, etc.)
|
|
916
|
+
const _origLog = console.log;
|
|
917
|
+
console.log = (...args) => {
|
|
918
|
+
const msg = String(args[0] || '');
|
|
919
|
+
if (msg.includes('[INFO]') || msg.includes('[DEBUG]'))
|
|
920
|
+
return;
|
|
921
|
+
_origLog.apply(console, args);
|
|
922
|
+
};
|
|
675
923
|
const spin = spinner('Initializing...');
|
|
676
924
|
spin.start();
|
|
677
925
|
await initStorage();
|
|
678
926
|
const db = getDb();
|
|
679
927
|
spin.stop();
|
|
928
|
+
// Restore console
|
|
929
|
+
console.log = _origLog;
|
|
680
930
|
if (!db) {
|
|
681
931
|
error('Failed to initialize database.');
|
|
682
932
|
process.exit(1);
|
|
683
933
|
}
|
|
684
|
-
//
|
|
685
|
-
|
|
686
|
-
//
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
//
|
|
934
|
+
// Dynamic step numbering
|
|
935
|
+
// Standalone: 5 steps (System Check, AI Provider, Admin, Registration, GitHub OAuth)
|
|
936
|
+
// From onboard: continues at step 5 of 6 (onboard did 1-4)
|
|
937
|
+
const totalSteps = fromOnboard ? 6 : 5;
|
|
938
|
+
let step = fromOnboard ? 4 : 0;
|
|
939
|
+
// System Check (skip if from onboard - already done)
|
|
940
|
+
let status;
|
|
941
|
+
if (fromOnboard) {
|
|
942
|
+
// Quick silent check
|
|
943
|
+
const redisOk = await checkRedis();
|
|
944
|
+
const hasAdmin = await checkAdminExists(db);
|
|
945
|
+
const providerName = await detectConfiguredProvider();
|
|
946
|
+
status = { redisOk, hasAdmin, hasProvider: !!providerName, providerName };
|
|
947
|
+
}
|
|
948
|
+
else {
|
|
949
|
+
step++;
|
|
950
|
+
stepHeader(step, totalSteps, 'System Check');
|
|
951
|
+
status = await stepSystemCheck(db);
|
|
952
|
+
}
|
|
953
|
+
// AI Provider (skip if from onboard - already configured)
|
|
954
|
+
let aiProvider = 'skip';
|
|
955
|
+
if (!fromOnboard) {
|
|
956
|
+
step++;
|
|
957
|
+
stepHeader(step, totalSteps, 'AI Provider');
|
|
958
|
+
aiProvider = await stepAiProvider(status);
|
|
959
|
+
}
|
|
960
|
+
// Admin Account
|
|
961
|
+
step++;
|
|
962
|
+
stepHeader(step, totalSteps, 'Admin Account');
|
|
690
963
|
const adminEmail = await stepAdminAccount(db);
|
|
691
|
-
//
|
|
964
|
+
// Registration Mode
|
|
965
|
+
step++;
|
|
966
|
+
stepHeader(step, totalSteps, 'Registration Mode');
|
|
692
967
|
const regResult = await stepRegistrationMode(db);
|
|
693
|
-
//
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
968
|
+
// GitHub OAuth (skip if from onboard to keep it shorter)
|
|
969
|
+
let githubOAuth = false;
|
|
970
|
+
if (!fromOnboard) {
|
|
971
|
+
step++;
|
|
972
|
+
stepHeader(step, totalSteps, 'GitHub OAuth');
|
|
973
|
+
githubOAuth = await stepGitHubOAuth();
|
|
974
|
+
}
|
|
975
|
+
// Summary + offer to start server
|
|
976
|
+
await showSummaryAndOffer({
|
|
697
977
|
redisOk: status.redisOk,
|
|
698
978
|
aiProvider,
|
|
699
979
|
adminEmail,
|
|
700
980
|
registrationMode: regResult.mode,
|
|
701
981
|
inviteCodes: regResult.codes,
|
|
702
982
|
githubOAuth,
|
|
983
|
+
fromOnboard,
|
|
703
984
|
});
|
|
985
|
+
await closeStorage();
|
|
986
|
+
process.exit(0);
|
|
704
987
|
}
|
|
705
988
|
catch (err) {
|
|
706
989
|
error(err instanceof Error ? err.message : 'Setup failed');
|
|
990
|
+
await closeStorage();
|
|
707
991
|
process.exit(1);
|
|
708
992
|
}
|
|
709
993
|
});
|
|
@@ -2,6 +2,25 @@ import { Command } from 'commander';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { api } from '../utils/api.js';
|
|
4
4
|
import { spinner } from '../utils/output.js';
|
|
5
|
+
import { isServerRunning } from '../../utils/pid-file.js';
|
|
6
|
+
function formatUptime(seconds) {
|
|
7
|
+
if (seconds < 60) {
|
|
8
|
+
return `${seconds}s`;
|
|
9
|
+
}
|
|
10
|
+
if (seconds < 3600) {
|
|
11
|
+
const m = Math.floor(seconds / 60);
|
|
12
|
+
const s = seconds % 60;
|
|
13
|
+
return `${m}m ${s}s`;
|
|
14
|
+
}
|
|
15
|
+
if (seconds < 86400) {
|
|
16
|
+
const h = Math.floor(seconds / 3600);
|
|
17
|
+
const m = Math.floor((seconds % 3600) / 60);
|
|
18
|
+
return `${h}h ${m}m`;
|
|
19
|
+
}
|
|
20
|
+
const d = Math.floor(seconds / 86400);
|
|
21
|
+
const h = Math.floor((seconds % 86400) / 3600);
|
|
22
|
+
return `${d}d ${h}h`;
|
|
23
|
+
}
|
|
5
24
|
export function statusCommand() {
|
|
6
25
|
const cmd = new Command('status')
|
|
7
26
|
.description('System status overview')
|
|
@@ -35,6 +54,41 @@ export function statusCommand() {
|
|
|
35
54
|
? chalk.green('healthy')
|
|
36
55
|
: chalk.red('unhealthy');
|
|
37
56
|
console.log(`\nprofClaw v${version} | Mode: ${mode} | Status: ${statusText}\n`);
|
|
57
|
+
// PID / port from PID file (fast local read) or health endpoint
|
|
58
|
+
const pidInfo = isServerRunning();
|
|
59
|
+
const pid = health.data?.process?.pid ?? pidInfo.pid;
|
|
60
|
+
const port = health.data?.process?.port ?? pidInfo.port;
|
|
61
|
+
if (pid !== undefined) {
|
|
62
|
+
console.log(`${chalk.bold('Process')} PID ${pid}${port ? `, port ${port}` : ''}`);
|
|
63
|
+
}
|
|
64
|
+
// Uptime
|
|
65
|
+
if (health.data?.uptime !== undefined) {
|
|
66
|
+
console.log(`${chalk.bold('Uptime')} ${formatUptime(health.data.uptime)}`);
|
|
67
|
+
}
|
|
68
|
+
// SSE clients
|
|
69
|
+
if (health.data?.sseClients !== undefined) {
|
|
70
|
+
console.log(`${chalk.bold('SSE Clients')} ${health.data.sseClients}`);
|
|
71
|
+
}
|
|
72
|
+
// Active agent sessions
|
|
73
|
+
if (health.data?.activeSessions !== undefined) {
|
|
74
|
+
console.log(`${chalk.bold('Sessions')} ${health.data.activeSessions} active`);
|
|
75
|
+
}
|
|
76
|
+
// Queue depth
|
|
77
|
+
if (health.data?.queueDepth !== undefined) {
|
|
78
|
+
const q = health.data.queueDepth;
|
|
79
|
+
console.log(`${chalk.bold('Queue')} ${q.pending} pending, ${q.running} running`);
|
|
80
|
+
}
|
|
81
|
+
// Memory and CPU
|
|
82
|
+
if (health.data?.process !== undefined) {
|
|
83
|
+
const p = health.data.process;
|
|
84
|
+
const load = p.cpuLoadAvg.length > 0 ? p.cpuLoadAvg[0].toFixed(2) : '?';
|
|
85
|
+
console.log(`${chalk.bold('Resources')} ${p.memoryMb} MB RSS | CPU load ${load}`);
|
|
86
|
+
}
|
|
87
|
+
// Last error
|
|
88
|
+
if (health.data?.lastError) {
|
|
89
|
+
console.log(`${chalk.bold('Last error')} ${chalk.red(health.data.lastError)}`);
|
|
90
|
+
}
|
|
91
|
+
console.log('');
|
|
38
92
|
if (providers.ok && providers.data) {
|
|
39
93
|
const active = providers.data.providers.filter((p) => p.enabled || p.configured);
|
|
40
94
|
const healthySummary = active
|