profclaw 2.0.0 → 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 +37 -0
- package/CONTRIBUTING.md +20 -0
- package/Dockerfile +39 -23
- package/README.md +174 -40
- 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 +14 -2
- package/dist/chat/execution/tools/index.js +86 -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/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/onboard.js +210 -30
- 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 +84 -3
- 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 -0
- 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/utils/api.d.ts +9 -0
- package/dist/cli/utils/api.js +58 -2
- 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 +78 -19
- 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/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 +3 -1
- package/dist/server/stream-bridge.d.ts +19 -0
- package/dist/server/stream-bridge.js +38 -0
- package/dist/server.js +310 -36
- 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/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--gPfvATB.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-1kaf7VHE.js → Settings-xA8Zhi3p.js} +3 -3
- package/ui/dist/assets/StatusIndicator-B8vfFAxg.js +1 -0
- package/ui/dist/assets/{SummaryDetail-DV3AmONk.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-BsLa7brF.js → archive-CX7UvZpf.js} +1 -1
- package/ui/dist/assets/badge-BbfnwDJP.js +1 -0
- package/ui/dist/assets/{bug-CmZI7jqM.js → bug-3WX0394-.js} +1 -1
- package/ui/dist/assets/{calendar-Bf0t2B82.js → calendar-buq77TaS.js} +1 -1
- package/ui/dist/assets/{chevron-up-CoUsOvZj.js → chevron-up-4ymsBJRo.js} +1 -1
- package/ui/dist/assets/{circle-x-Dgw11LgT.js → circle-x-ByXtwR6Y.js} +1 -1
- package/ui/dist/assets/constants-CVdDh7p0.js +1 -0
- package/ui/dist/assets/{cpu-DiPMQICV.js → cpu-CiuoCeDY.js} +1 -1
- package/ui/dist/assets/{database-BwTfupDi.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-UJx4Xnf6.js → ellipsis-vT-5SVIp.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-DoULYEKn.js → ellipsis-vertical-B4tAX_bL.js} +1 -1
- package/ui/dist/assets/feature-markdown-DBo5Q7uq.js +289 -0
- package/ui/dist/assets/{file-code-B2UrJLwi.js → file-code-ChOWdKXf.js} +1 -1
- package/ui/dist/assets/{folder-open-BJi577JH.js → folder-open-CkOUbIiP.js} +1 -1
- package/ui/dist/assets/{funnel-PkaD_HSR.js → funnel-uZkoSPP-.js} +1 -1
- package/ui/dist/assets/{git-branch-C_K30am0.js → git-branch-CwvUxj7C.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-IT6ecxWQ.js → git-commit-horizontal-lxPzCvhD.js} +1 -1
- package/ui/dist/assets/{globe-f-jjCa_g.js → globe-D_WpJdsj.js} +1 -1
- package/ui/dist/assets/{hash-DNEv8Elo.js → hash-CA0hJ7vh.js} +1 -1
- package/ui/dist/assets/{history-BQSBo_1Q.js → history-CEWMLELs.js} +1 -1
- package/ui/dist/assets/inbox-ehtOptTV.js +1 -0
- package/ui/dist/assets/{index-nS3EErDg.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-CcKt1hXw.js → layout-dashboard-BRUM0kpT.js} +1 -1
- package/ui/dist/assets/{lightbulb-Jhp7FvbU.js → lightbulb-CN2q1O5l.js} +1 -1
- package/ui/dist/assets/{link-2-DdO7ostF.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-CBgH65X7.js → message-square-Bbb241am.js} +1 -1
- package/ui/dist/assets/package-CwT3IzFx.js +1 -0
- package/ui/dist/assets/{pencil-CYXCEPQh.js → pencil-CDmiHzoj.js} +1 -1
- package/ui/dist/assets/{play-d1ONaH0-.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-DhvUetsk.js → rocket--8ZHgdXJ.js} +1 -1
- package/ui/dist/assets/select-n108rXny.js +1 -0
- package/ui/dist/assets/{send-P0r5D7td.js → send-Cu7MR2Qh.js} +1 -1
- package/ui/dist/assets/server-DmodxZp-.js +1 -0
- package/ui/dist/assets/{settings-2-ocj5uHGx.js → settings-2-CkRNqkxj.js} +1 -1
- package/ui/dist/assets/sheet-7aUJkyzU.js +1 -0
- package/ui/dist/assets/{shield-check-DfVdE34l.js → shield-check-ViI3nMKE.js} +1 -1
- package/ui/dist/assets/{shield-off-8l0J6R-8.js → shield-off-DN3tagkn.js} +1 -1
- package/ui/dist/assets/skeleton-C0E1Nfro.js +1 -0
- package/ui/dist/assets/{smartphone-77_g3SQn.js → smartphone-5FghiXpA.js} +1 -1
- package/ui/dist/assets/{square-Ckzsr3Rn.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-C35mgoEv.js → tag-CH_vQliw.js} +1 -1
- package/ui/dist/assets/textarea-CxDiKFXZ.js +1 -0
- package/ui/dist/assets/{timer-DHJBS2w1.js → timer-CdGVTb60.js} +1 -1
- package/ui/dist/assets/tooltip-BuW9A5UO.js +1 -0
- package/ui/dist/assets/{trash-2-keO5tKPE.js → trash-2-CucZJL0N.js} +1 -1
- package/ui/dist/assets/trending-down-BCezC1z2.js +1 -0
- package/ui/dist/assets/{trending-up-BBv8KbrY.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-BusQ52ZK.js → wand-sparkles-BaH6pJnc.js} +1 -1
- package/ui/dist/assets/{wrench-02YaOSiK.js → wrench-CjxjP6ok.js} +1 -1
- package/ui/dist/index.html +5 -2
- package/ui/dist/assets/ActivityView-BeshZXmE.js +0 -1
- package/ui/dist/assets/AgentList-QVHeldPi.js +0 -1
- package/ui/dist/assets/AnalyticsDashboard-C9R97dXE.js +0 -1
- package/ui/dist/assets/AreaChart-B73gaiVQ.js +0 -1
- package/ui/dist/assets/CartesianChart-CXYL2R-A.js +0 -36
- package/ui/dist/assets/ChatView-qjZErlrp.js +0 -10
- package/ui/dist/assets/CostsDashboard-O4DCLy1i.js +0 -1
- package/ui/dist/assets/EstimateSelect-1hQf4Osk.js +0 -1
- package/ui/dist/assets/FloatingChatbot-BZBzrJxd.js +0 -2
- package/ui/dist/assets/InviteCodeManagement-LEoGqYeA.js +0 -2
- package/ui/dist/assets/ProjectIcon-Chd_ofsw.js +0 -1
- package/ui/dist/assets/ProjectList-BvUfVB6c.js +0 -4
- package/ui/dist/assets/StatusIndicator-pRfkNcdV.js +0 -1
- package/ui/dist/assets/SummaryList-B6kXiTxL.js +0 -1
- package/ui/dist/assets/TaskDetail-CV6CzbOS.js +0 -1
- package/ui/dist/assets/TaskList-DL7brQKd.js +0 -1
- package/ui/dist/assets/TicketBoard-CrkkFj7C.js +0 -1
- package/ui/dist/assets/TicketDetail-hnnYclpD.js +0 -1
- package/ui/dist/assets/TicketList-CsDAyQCL.js +0 -1
- package/ui/dist/assets/UserManagement-BGFQyTSr.js +0 -2
- package/ui/dist/assets/ViewSwitcher-CnL0OqA8.js +0 -1
- package/ui/dist/assets/alert-dialog-SKM6Gjz4.js +0 -7
- package/ui/dist/assets/badge-CVHH1a-v.js +0 -1
- package/ui/dist/assets/brain-6o_RHVpe.js +0 -1
- package/ui/dist/assets/constants-Q5Zivl-a.js +0 -1
- package/ui/dist/assets/dialog-BUqN9Psj.js +0 -1
- package/ui/dist/assets/index-BUmnwPQr.js +0 -1
- package/ui/dist/assets/index-BfF5G4Cw.js +0 -1
- package/ui/dist/assets/index-C8N375c2.js +0 -1
- package/ui/dist/assets/index-CuxnqVVz.css +0 -1
- package/ui/dist/assets/index-CzMM3QOk.js +0 -1
- package/ui/dist/assets/index-lJlNPFVJ.js +0 -67
- package/ui/dist/assets/layers-jFqVrWMD.js +0 -1
- package/ui/dist/assets/markdown-renderer-n1ToC4XQ.js +0 -36
- package/ui/dist/assets/popover-CrmZgoWu.js +0 -1
- package/ui/dist/assets/progress-uv4SPkL5.js +0 -1
- package/ui/dist/assets/select-CeQ8AHGy.js +0 -1
- package/ui/dist/assets/server-CVHTZB72.js +0 -1
- package/ui/dist/assets/sheet-DuQExSho.js +0 -1
- package/ui/dist/assets/skeleton-TFiFJ3nB.js +0 -1
- package/ui/dist/assets/switch-CAePkd6k.js +0 -1
- package/ui/dist/assets/table-ZjAZ7hkt.js +0 -1
- package/ui/dist/assets/textarea-DsVPnSgR.js +0 -1
- package/ui/dist/assets/tooltip-BYmQ331W.js +0 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Mode CLI Commands
|
|
3
|
+
*
|
|
4
|
+
* View and manage agent plans created during plan-mode sessions.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* profclaw plan list
|
|
8
|
+
* profclaw plan show <id>
|
|
9
|
+
* profclaw plan approve <id>
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
export declare function planCommands(): Command;
|
|
13
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Mode CLI Commands
|
|
3
|
+
*
|
|
4
|
+
* View and manage agent plans created during plan-mode sessions.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* profclaw plan list
|
|
8
|
+
* profclaw plan show <id>
|
|
9
|
+
* profclaw plan approve <id>
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import { planManager } from '../../agents/plan-mode.js';
|
|
14
|
+
import { createTable, formatRelativeTime, success, error, warn, truncate, } from '../utils/output.js';
|
|
15
|
+
// ─── Status formatting ───────────────────────────────────────────────────────
|
|
16
|
+
const PLAN_STATUS_COLORS = {
|
|
17
|
+
draft: chalk.yellow,
|
|
18
|
+
approved: chalk.blue,
|
|
19
|
+
in_progress: chalk.cyan,
|
|
20
|
+
completed: chalk.green,
|
|
21
|
+
rejected: chalk.red,
|
|
22
|
+
};
|
|
23
|
+
const STEP_STATUS_SYMBOLS = {
|
|
24
|
+
pending: chalk.dim('○'),
|
|
25
|
+
in_progress: chalk.cyan('◑'),
|
|
26
|
+
completed: chalk.green('●'),
|
|
27
|
+
skipped: chalk.gray('–'),
|
|
28
|
+
};
|
|
29
|
+
function formatPlanStatus(status) {
|
|
30
|
+
const colorFn = PLAN_STATUS_COLORS[status] ?? chalk.white;
|
|
31
|
+
return colorFn(status.toUpperCase().replace('_', ' '));
|
|
32
|
+
}
|
|
33
|
+
// ─── Command builder ─────────────────────────────────────────────────────────
|
|
34
|
+
export function planCommands() {
|
|
35
|
+
const plan = new Command('plan').description('Manage agent implementation plans');
|
|
36
|
+
// ── list ──────────────────────────────────────────────────────────────────
|
|
37
|
+
plan
|
|
38
|
+
.command('list')
|
|
39
|
+
.alias('ls')
|
|
40
|
+
.description('List all plans')
|
|
41
|
+
.option('-s, --status <status>', 'Filter by status (draft|approved|in_progress|completed|rejected)')
|
|
42
|
+
.option('--json', 'Output as JSON')
|
|
43
|
+
.action((options) => {
|
|
44
|
+
let plans = planManager.list();
|
|
45
|
+
if (options.status) {
|
|
46
|
+
plans = plans.filter((p) => p.status === options.status);
|
|
47
|
+
}
|
|
48
|
+
if (options.json) {
|
|
49
|
+
console.log(JSON.stringify(plans, null, 2));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (plans.length === 0) {
|
|
53
|
+
console.log(chalk.dim('No plans found.'));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const table = createTable(['ID', 'Title', 'Status', 'Steps', 'Created']);
|
|
57
|
+
for (const p of plans) {
|
|
58
|
+
const doneSteps = p.steps.filter((s) => s.status === 'completed' || s.status === 'skipped').length;
|
|
59
|
+
table.push([
|
|
60
|
+
p.id.slice(0, 8),
|
|
61
|
+
truncate(p.title, 40),
|
|
62
|
+
formatPlanStatus(p.status),
|
|
63
|
+
`${doneSteps}/${p.steps.length}`,
|
|
64
|
+
formatRelativeTime(new Date(p.createdAt)),
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
console.log(table.toString());
|
|
68
|
+
console.log(chalk.dim(`\n${plans.length} plan(s) total`));
|
|
69
|
+
});
|
|
70
|
+
// ── show ──────────────────────────────────────────────────────────────────
|
|
71
|
+
plan
|
|
72
|
+
.command('show <id>')
|
|
73
|
+
.alias('get')
|
|
74
|
+
.description('Show plan details and step list')
|
|
75
|
+
.option('--json', 'Output as JSON')
|
|
76
|
+
.action((id, options) => {
|
|
77
|
+
// Support partial ID prefix matching
|
|
78
|
+
const allPlans = planManager.list();
|
|
79
|
+
const found = allPlans.find((p) => p.id === id || p.id.startsWith(id));
|
|
80
|
+
if (!found) {
|
|
81
|
+
error(`Plan not found: ${id}`);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
if (options.json) {
|
|
85
|
+
console.log(JSON.stringify(found, null, 2));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log(chalk.bold(`Plan: ${found.id}`));
|
|
90
|
+
console.log(`Title: ${found.title}`);
|
|
91
|
+
console.log(`Status: ${formatPlanStatus(found.status)}`);
|
|
92
|
+
console.log(`Created: ${formatRelativeTime(new Date(found.createdAt))}`);
|
|
93
|
+
if (found.approvedAt) {
|
|
94
|
+
console.log(`Approved: ${formatRelativeTime(new Date(found.approvedAt))}`);
|
|
95
|
+
}
|
|
96
|
+
if (found.completedAt) {
|
|
97
|
+
console.log(`Completed: ${formatRelativeTime(new Date(found.completedAt))}`);
|
|
98
|
+
}
|
|
99
|
+
if (found.rejectionReason) {
|
|
100
|
+
console.log(`Rejection reason: ${chalk.red(found.rejectionReason)}`);
|
|
101
|
+
}
|
|
102
|
+
if (found.taskId) {
|
|
103
|
+
console.log(`Task ID: ${found.taskId}`);
|
|
104
|
+
}
|
|
105
|
+
console.log('');
|
|
106
|
+
console.log(chalk.bold('Steps:'));
|
|
107
|
+
for (const step of found.steps) {
|
|
108
|
+
const symbol = STEP_STATUS_SYMBOLS[step.status];
|
|
109
|
+
const effort = step.estimatedEffort ? chalk.dim(` [${step.estimatedEffort}]`) : '';
|
|
110
|
+
console.log(` ${symbol} ${step.index}. ${step.description}${effort}`);
|
|
111
|
+
if (step.files && step.files.length > 0) {
|
|
112
|
+
for (const f of step.files) {
|
|
113
|
+
console.log(` ${chalk.dim(f)}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
console.log('');
|
|
118
|
+
});
|
|
119
|
+
// ── approve ───────────────────────────────────────────────────────────────
|
|
120
|
+
plan
|
|
121
|
+
.command('approve <id>')
|
|
122
|
+
.description('Approve a pending plan so the agent can begin implementation')
|
|
123
|
+
.option('--json', 'Output as JSON')
|
|
124
|
+
.action((id, options) => {
|
|
125
|
+
const allPlans = planManager.list();
|
|
126
|
+
const found = allPlans.find((p) => p.id === id || p.id.startsWith(id));
|
|
127
|
+
if (!found) {
|
|
128
|
+
error(`Plan not found: ${id}`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
if (found.status !== 'draft') {
|
|
132
|
+
warn(`Plan ${found.id.slice(0, 8)} is already ${found.status}, cannot approve.`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const approved = planManager.approve(found.id);
|
|
137
|
+
if (options.json) {
|
|
138
|
+
console.log(JSON.stringify(approved, null, 2));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
success(`Plan approved: ${approved.id.slice(0, 8)} — "${approved.title}"`);
|
|
142
|
+
console.log(chalk.dim('The agent will now begin implementation.'));
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
error(err instanceof Error ? err.message : 'Failed to approve plan');
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
// ── reject ────────────────────────────────────────────────────────────────
|
|
150
|
+
plan
|
|
151
|
+
.command('reject <id>')
|
|
152
|
+
.description('Reject a pending plan')
|
|
153
|
+
.option('-r, --reason <reason>', 'Reason for rejection')
|
|
154
|
+
.option('--json', 'Output as JSON')
|
|
155
|
+
.action((id, options) => {
|
|
156
|
+
const allPlans = planManager.list();
|
|
157
|
+
const found = allPlans.find((p) => p.id === id || p.id.startsWith(id));
|
|
158
|
+
if (!found) {
|
|
159
|
+
error(`Plan not found: ${id}`);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
if (found.status !== 'draft') {
|
|
163
|
+
warn(`Plan ${found.id.slice(0, 8)} is already ${found.status}, cannot reject.`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
const rejected = planManager.reject(found.id, options.reason);
|
|
168
|
+
if (options.json) {
|
|
169
|
+
console.log(JSON.stringify(rejected, null, 2));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
console.log(chalk.red('✗') + ` Plan rejected: ${rejected.id.slice(0, 8)}`);
|
|
173
|
+
if (options.reason) {
|
|
174
|
+
console.log(chalk.dim(`Reason: ${options.reason}`));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
error(err instanceof Error ? err.message : 'Failed to reject plan');
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
return plan;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
export declare function checkPortAvailable(port: number): Promise<boolean>;
|
|
3
|
+
/**
|
|
4
|
+
* Try to find an available port starting at `startPort`.
|
|
5
|
+
* Attempts up to MAX_PORT_ATTEMPTS consecutive ports.
|
|
6
|
+
* Returns the available port, or null if all attempts fail.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolvePort(startPort: number): Promise<number | null>;
|
|
2
9
|
export declare function serveCommand(): Command;
|
|
3
10
|
//# sourceMappingURL=serve.d.ts.map
|
|
@@ -5,23 +5,21 @@ import { spawn } from 'child_process';
|
|
|
5
5
|
import { resolve } from 'path';
|
|
6
6
|
import { existsSync } from 'fs';
|
|
7
7
|
import { createServer } from 'net';
|
|
8
|
+
import * as readline from 'readline';
|
|
8
9
|
import { success, error, info, warn } from '../utils/output.js';
|
|
10
|
+
import { isServerRunning, killExistingServer } from '../../utils/pid-file.js';
|
|
9
11
|
const MAX_RESTART_ATTEMPTS = 5;
|
|
12
|
+
const MAX_PORT_ATTEMPTS = 3;
|
|
10
13
|
const BASE_BACKOFF_MS = 1000;
|
|
11
14
|
const MAX_BACKOFF_MS = 30000;
|
|
12
15
|
const CRASH_WINDOW_MS = 10000;
|
|
13
16
|
const HEALTH_CHECK_DELAY_MS = 3000;
|
|
14
17
|
const HEALTH_CHECK_TIMEOUT_MS = 5000;
|
|
15
|
-
function checkPortAvailable(port) {
|
|
18
|
+
export function checkPortAvailable(port) {
|
|
16
19
|
return new Promise((resolve) => {
|
|
17
20
|
const server = createServer();
|
|
18
21
|
server.once('error', (err) => {
|
|
19
|
-
|
|
20
|
-
resolve(false);
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
resolve(true);
|
|
24
|
-
}
|
|
22
|
+
resolve(err.code !== 'EADDRINUSE');
|
|
25
23
|
});
|
|
26
24
|
server.once('listening', () => {
|
|
27
25
|
server.close();
|
|
@@ -30,6 +28,21 @@ function checkPortAvailable(port) {
|
|
|
30
28
|
server.listen(port, '127.0.0.1');
|
|
31
29
|
});
|
|
32
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Try to find an available port starting at `startPort`.
|
|
33
|
+
* Attempts up to MAX_PORT_ATTEMPTS consecutive ports.
|
|
34
|
+
* Returns the available port, or null if all attempts fail.
|
|
35
|
+
*/
|
|
36
|
+
export async function resolvePort(startPort) {
|
|
37
|
+
for (let offset = 0; offset < MAX_PORT_ATTEMPTS; offset++) {
|
|
38
|
+
const candidate = startPort + offset;
|
|
39
|
+
const available = await checkPortAvailable(candidate);
|
|
40
|
+
if (available) {
|
|
41
|
+
return candidate;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
33
46
|
async function healthCheck(port) {
|
|
34
47
|
try {
|
|
35
48
|
const res = await fetch(`http://localhost:${port}/health`, {
|
|
@@ -58,19 +71,46 @@ export function serveCommand() {
|
|
|
58
71
|
console.log(chalk.cyan(banner));
|
|
59
72
|
console.log(chalk.dim(' AI Agent Task Orchestrator\n'));
|
|
60
73
|
const port = parseInt(options.port, 10);
|
|
61
|
-
// Pre-flight: check
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
74
|
+
// Pre-flight: check for an existing server instance via PID file
|
|
75
|
+
const running = isServerRunning();
|
|
76
|
+
if (running.running && running.pid !== undefined) {
|
|
77
|
+
warn(`A profClaw server is already running (PID ${running.pid}, port ${running.port}).`);
|
|
78
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
79
|
+
const answer = await new Promise((resolve) => {
|
|
80
|
+
rl.question(' Kill the existing server and start a new one? [y/N] ', (ans) => {
|
|
81
|
+
rl.close();
|
|
82
|
+
resolve(ans.trim().toLowerCase());
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
if (answer === 'y' || answer === 'yes') {
|
|
86
|
+
const killed = killExistingServer();
|
|
87
|
+
if (killed) {
|
|
88
|
+
success('Existing server stopped.');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
error('Could not stop the existing server within 5 seconds. Aborting.');
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
info('Aborted. The existing server is still running.');
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Pre-flight: find an available port (retry up to MAX_PORT_ATTEMPTS)
|
|
101
|
+
const actualPort = await resolvePort(port);
|
|
102
|
+
if (actualPort === null) {
|
|
103
|
+
error(`Ports ${port}–${port + MAX_PORT_ATTEMPTS - 1} are all in use.`);
|
|
104
|
+
info(`Free a port or specify a different one: ${chalk.cyan(`profclaw serve -p <port>`)}`);
|
|
68
105
|
process.exit(1);
|
|
69
106
|
}
|
|
107
|
+
if (actualPort !== port) {
|
|
108
|
+
warn(`Port ${port} in use, started on port ${actualPort}`);
|
|
109
|
+
}
|
|
70
110
|
// Set environment variables
|
|
71
111
|
const env = {
|
|
72
112
|
...process.env,
|
|
73
|
-
PORT:
|
|
113
|
+
PORT: String(actualPort),
|
|
74
114
|
ENABLE_CRON: options.cron === false ? 'false' : 'true',
|
|
75
115
|
};
|
|
76
116
|
// Determine the project root
|
|
@@ -92,7 +132,7 @@ export function serveCommand() {
|
|
|
92
132
|
command = 'npx';
|
|
93
133
|
args = ['tsx', 'src/server.ts'];
|
|
94
134
|
}
|
|
95
|
-
console.log(chalk.blue(`Starting server on port ${
|
|
135
|
+
console.log(chalk.blue(`Starting server on port ${actualPort}...\n`));
|
|
96
136
|
}
|
|
97
137
|
const autoRestart = options.restart !== false && !options.dev;
|
|
98
138
|
const state = {
|
|
@@ -154,9 +194,28 @@ export function serveCommand() {
|
|
|
154
194
|
setTimeout(async () => {
|
|
155
195
|
if (state.shuttingDown)
|
|
156
196
|
return;
|
|
157
|
-
const healthy = await healthCheck(
|
|
197
|
+
const healthy = await healthCheck(actualPort);
|
|
158
198
|
if (healthy) {
|
|
159
|
-
success(`Server healthy on port ${
|
|
199
|
+
success(`Server healthy on port ${actualPort}`);
|
|
200
|
+
// WS-1.3: detect first-run (no admin users) and print setup prompt
|
|
201
|
+
try {
|
|
202
|
+
const res = await fetch(`http://localhost:${actualPort}/`, {
|
|
203
|
+
redirect: 'manual',
|
|
204
|
+
signal: AbortSignal.timeout(HEALTH_CHECK_TIMEOUT_MS),
|
|
205
|
+
});
|
|
206
|
+
if (res.status === 302) {
|
|
207
|
+
const location = res.headers.get('location') || '';
|
|
208
|
+
if (location.includes('/setup')) {
|
|
209
|
+
console.log('');
|
|
210
|
+
console.log(chalk.yellow(' First run detected.'));
|
|
211
|
+
console.log(chalk.yellow(` Visit ${chalk.cyan(`http://localhost:${port}/setup`)} to configure profClaw`));
|
|
212
|
+
console.log('');
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Non-critical — ignore
|
|
218
|
+
}
|
|
160
219
|
}
|
|
161
220
|
else {
|
|
162
221
|
warn('Server may not be fully ready yet. Check logs above.');
|
|
@@ -14,11 +14,13 @@ import figlet from 'figlet';
|
|
|
14
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 { spawn } from 'child_process';
|
|
17
|
+
import { spawn, execFile } from 'child_process';
|
|
18
18
|
import { existsSync, mkdirSync, openSync } from 'node:fs';
|
|
19
19
|
import { join } from 'node:path';
|
|
20
|
+
import { promisify } from 'node:util';
|
|
21
|
+
import * as os from 'os';
|
|
20
22
|
import { createServer } from 'net';
|
|
21
|
-
import { initStorage, getDb, saveProviderConfig, loadAllProviderConfigs } from '../../storage/index.js';
|
|
23
|
+
import { initStorage, getDb, closeStorage, saveProviderConfig, loadAllProviderConfigs } from '../../storage/index.js';
|
|
22
24
|
import { users, inviteCodes } from '../../storage/schema.js';
|
|
23
25
|
import { PROVIDER_CATALOG } from '../providers.js';
|
|
24
26
|
import { hashPassword, validatePasswordStrength, generateRecoveryCodes, hashRecoveryCodes, generateInviteCode, hashInviteCode, } from '../../auth/password.js';
|
|
@@ -586,6 +588,80 @@ async function stepGitHubOAuth() {
|
|
|
586
588
|
return true;
|
|
587
589
|
}
|
|
588
590
|
// Step 6: Summary
|
|
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
|
+
}
|
|
589
665
|
function checkPortAvailable(port) {
|
|
590
666
|
return new Promise((resolve) => {
|
|
591
667
|
const server = createServer();
|
|
@@ -605,6 +681,7 @@ async function showSummaryAndOffer(results) {
|
|
|
605
681
|
console.log(` ${mark(true)} Registration: ${results.registrationMode}${results.inviteCodes.length ? ` (${results.inviteCodes.length} codes)` : ''}`);
|
|
606
682
|
console.log(` ${mark(results.githubOAuth)} GitHub OAuth: ${results.githubOAuth ? 'configured' : 'skipped'}`);
|
|
607
683
|
console.log(' ' + '\u2500'.repeat(44));
|
|
684
|
+
await runQuickHealthCheck();
|
|
608
685
|
// Check if server is already running
|
|
609
686
|
const portFree = await checkPortAvailable(port);
|
|
610
687
|
const serverRunning = !portFree;
|
|
@@ -828,7 +905,8 @@ export function setupCommand() {
|
|
|
828
905
|
aiProvider: options.aiProvider,
|
|
829
906
|
registrationMode: options.registrationMode,
|
|
830
907
|
});
|
|
831
|
-
|
|
908
|
+
await closeStorage();
|
|
909
|
+
process.exit(0);
|
|
832
910
|
}
|
|
833
911
|
const fromOnboard = !!options.fromOnboard;
|
|
834
912
|
// Interactive mode
|
|
@@ -904,9 +982,12 @@ export function setupCommand() {
|
|
|
904
982
|
githubOAuth,
|
|
905
983
|
fromOnboard,
|
|
906
984
|
});
|
|
985
|
+
await closeStorage();
|
|
986
|
+
process.exit(0);
|
|
907
987
|
}
|
|
908
988
|
catch (err) {
|
|
909
989
|
error(err instanceof Error ? err.message : 'Setup failed');
|
|
990
|
+
await closeStorage();
|
|
910
991
|
process.exit(1);
|
|
911
992
|
}
|
|
912
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
|
|
@@ -11,9 +11,9 @@ import { registerBuiltinTools } from '../../chat/execution/tools/index.js';
|
|
|
11
11
|
import { getToolRegistry } from '../../chat/execution/registry.js';
|
|
12
12
|
// Lazy initialization - only register tools when a tools command actually runs
|
|
13
13
|
let toolsInitialized = false;
|
|
14
|
-
function getRegistry() {
|
|
14
|
+
async function getRegistry() {
|
|
15
15
|
if (!toolsInitialized) {
|
|
16
|
-
registerBuiltinTools();
|
|
16
|
+
await registerBuiltinTools();
|
|
17
17
|
toolsInitialized = true;
|
|
18
18
|
}
|
|
19
19
|
return getToolRegistry();
|
|
@@ -93,7 +93,7 @@ export function toolsCommands() {
|
|
|
93
93
|
.option('--json', 'Output as JSON')
|
|
94
94
|
.option('-c, --category <cat>', 'Filter by category')
|
|
95
95
|
.action(async (options) => {
|
|
96
|
-
const registry = getRegistry();
|
|
96
|
+
const registry = await getRegistry();
|
|
97
97
|
let toolList = registry.list();
|
|
98
98
|
if (options.category) {
|
|
99
99
|
toolList = toolList.filter((t) => t.category === options.category);
|
|
@@ -145,7 +145,7 @@ export function toolsCommands() {
|
|
|
145
145
|
.description('Show detailed information about a tool')
|
|
146
146
|
.option('--json', 'Output as JSON')
|
|
147
147
|
.action(async (name, options) => {
|
|
148
|
-
const registry = getRegistry();
|
|
148
|
+
const registry = await getRegistry();
|
|
149
149
|
const tool = registry.get(name);
|
|
150
150
|
if (!tool) {
|
|
151
151
|
error(`Tool '${name}' not found`);
|
|
@@ -192,7 +192,7 @@ export function toolsCommands() {
|
|
|
192
192
|
.option('--json', 'Output result as JSON')
|
|
193
193
|
.option('-y, --yes', 'Skip approval for moderate tools')
|
|
194
194
|
.action(async (name, options) => {
|
|
195
|
-
const registry = getRegistry();
|
|
195
|
+
const registry = await getRegistry();
|
|
196
196
|
const tool = registry.get(name);
|
|
197
197
|
if (!tool) {
|
|
198
198
|
error(`Tool '${name}' not found`);
|
|
@@ -270,7 +270,7 @@ export function toolsCommands() {
|
|
|
270
270
|
.option('--json', 'Output as JSON')
|
|
271
271
|
.action(async (commandParts, options) => {
|
|
272
272
|
const command = commandParts.join(' ');
|
|
273
|
-
const registry = getRegistry();
|
|
273
|
+
const registry = await getRegistry();
|
|
274
274
|
const tool = registry.get('exec');
|
|
275
275
|
if (!tool) {
|
|
276
276
|
error('exec tool not found');
|
|
@@ -308,7 +308,7 @@ export function toolsCommands() {
|
|
|
308
308
|
.option('-s, --short', 'Short format')
|
|
309
309
|
.option('-w, --workdir <path>', 'Repository path')
|
|
310
310
|
.action(async (options) => {
|
|
311
|
-
const registry = getRegistry();
|
|
311
|
+
const registry = await getRegistry();
|
|
312
312
|
const tool = registry.get('git_status');
|
|
313
313
|
if (!tool) {
|
|
314
314
|
error('git_status tool not found');
|
|
@@ -332,7 +332,7 @@ export function toolsCommands() {
|
|
|
332
332
|
.option('-t, --type <type>', 'Info type: all, cpu, memory, os, network', 'all')
|
|
333
333
|
.option('--json', 'Output as JSON')
|
|
334
334
|
.action(async (options) => {
|
|
335
|
-
const registry = getRegistry();
|
|
335
|
+
const registry = await getRegistry();
|
|
336
336
|
const tool = registry.get('system_info');
|
|
337
337
|
if (!tool) {
|
|
338
338
|
error('system_info tool not found');
|
|
@@ -359,7 +359,7 @@ export function toolsCommands() {
|
|
|
359
359
|
.description('Shortcut: Show environment variables')
|
|
360
360
|
.option('-f, --filter <pattern>', 'Filter by pattern')
|
|
361
361
|
.action(async (name, options) => {
|
|
362
|
-
const registry = getRegistry();
|
|
362
|
+
const registry = await getRegistry();
|
|
363
363
|
const tool = registry.get('env');
|
|
364
364
|
if (!tool) {
|
|
365
365
|
error('env tool not found');
|
|
@@ -381,7 +381,7 @@ export function toolsCommands() {
|
|
|
381
381
|
.command('which <command>')
|
|
382
382
|
.description('Shortcut: Find command location')
|
|
383
383
|
.action(async (command) => {
|
|
384
|
-
const registry = getRegistry();
|
|
384
|
+
const registry = await getRegistry();
|
|
385
385
|
const tool = registry.get('which');
|
|
386
386
|
if (!tool) {
|
|
387
387
|
error('which tool not found');
|
|
@@ -403,7 +403,7 @@ export function toolsCommands() {
|
|
|
403
403
|
.description('Shortcut: Read a file')
|
|
404
404
|
.option('-l, --lines <n>', 'Max lines to read', '100')
|
|
405
405
|
.action(async (filePath, options) => {
|
|
406
|
-
const registry = getRegistry();
|
|
406
|
+
const registry = await getRegistry();
|
|
407
407
|
const tool = registry.get('read_file');
|
|
408
408
|
if (!tool) {
|
|
409
409
|
error('read_file tool not found');
|
|
@@ -431,7 +431,7 @@ export function toolsCommands() {
|
|
|
431
431
|
.option('-p, --path <dir>', 'Search directory', '.')
|
|
432
432
|
.option('-t, --type <type>', 'File type: file, directory, both', 'file')
|
|
433
433
|
.action(async (pattern, options) => {
|
|
434
|
-
const registry = getRegistry();
|
|
434
|
+
const registry = await getRegistry();
|
|
435
435
|
const tool = registry.get('search_files');
|
|
436
436
|
if (!tool) {
|
|
437
437
|
error('search_files tool not found');
|
|
@@ -469,7 +469,7 @@ export function toolsCommands() {
|
|
|
469
469
|
.option('-i, --ignore-case', 'Case insensitive')
|
|
470
470
|
.option('-c, --context <n>', 'Context lines', '0')
|
|
471
471
|
.action(async (pattern, searchPath, options) => {
|
|
472
|
-
const registry = getRegistry();
|
|
472
|
+
const registry = await getRegistry();
|
|
473
473
|
const tool = registry.get('grep');
|
|
474
474
|
if (!tool) {
|
|
475
475
|
error('grep tool not found');
|