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,11 +11,47 @@
|
|
|
11
11
|
import { Command } from 'commander';
|
|
12
12
|
import chalk from 'chalk';
|
|
13
13
|
import figlet from 'figlet';
|
|
14
|
-
import { select, search, input, Separator } from '@inquirer/prompts';
|
|
14
|
+
import { select, search, input, confirm, Separator } from '@inquirer/prompts';
|
|
15
15
|
import { existsSync, writeFileSync, readFileSync } from 'node:fs';
|
|
16
16
|
import { join } from 'node:path';
|
|
17
17
|
import { execSync } from 'node:child_process';
|
|
18
18
|
import { success, error, info, warn, spinner } from '../utils/output.js';
|
|
19
|
+
import { PROVIDER_CATALOG, PROVIDER_ENV_KEYS } from '../providers.js';
|
|
20
|
+
/** Returns true if an env var name should have its value masked. */
|
|
21
|
+
function isSensitiveKey(key) {
|
|
22
|
+
return key.includes('KEY') || key.includes('TOKEN') || key.includes('SECRET');
|
|
23
|
+
}
|
|
24
|
+
/** Mask an API key for display — shows first 8 chars and last 4, dots in between. */
|
|
25
|
+
function maskApiKey(key) {
|
|
26
|
+
if (key.length <= 12)
|
|
27
|
+
return key.slice(0, 4) + '•'.repeat(key.length - 4);
|
|
28
|
+
return key.slice(0, 8) + '•'.repeat(8) + key.slice(-4);
|
|
29
|
+
}
|
|
30
|
+
/** Format a generated env file for display with sensitive values masked. */
|
|
31
|
+
function formatEnvPreview(content) {
|
|
32
|
+
return content.split('\n')
|
|
33
|
+
.map(line => {
|
|
34
|
+
if (line.startsWith('#') || line.trim() === '')
|
|
35
|
+
return chalk.dim(` ${line}`);
|
|
36
|
+
const eqIndex = line.indexOf('=');
|
|
37
|
+
if (eqIndex === -1)
|
|
38
|
+
return chalk.dim(` ${line}`);
|
|
39
|
+
const key = line.slice(0, eqIndex);
|
|
40
|
+
const value = line.slice(eqIndex + 1);
|
|
41
|
+
if (isSensitiveKey(key)) {
|
|
42
|
+
return ` ${chalk.cyan(key)}=${chalk.yellow(maskApiKey(value))}`;
|
|
43
|
+
}
|
|
44
|
+
return ` ${chalk.cyan(key)}=${chalk.white(value)}`;
|
|
45
|
+
})
|
|
46
|
+
.join('\n');
|
|
47
|
+
}
|
|
48
|
+
/** Render a step header with progress bar. */
|
|
49
|
+
function stepHeader(step, total, title) {
|
|
50
|
+
const barLen = 20;
|
|
51
|
+
const filled = Math.round((step / total) * barLen);
|
|
52
|
+
const bar = chalk.cyan('━'.repeat(filled)) + chalk.dim('━'.repeat(barLen - filled));
|
|
53
|
+
console.log(`\n ${bar} ${chalk.dim(`${step}/${total}`)} ${chalk.bold.white(title)}\n`);
|
|
54
|
+
}
|
|
19
55
|
const DETECT_TIMEOUT_MS = 5000;
|
|
20
56
|
/** Wrap a detection check with a timeout so a hung service doesn't block onboarding. */
|
|
21
57
|
async function withTimeout(promise, fallback, timeoutMs = DETECT_TIMEOUT_MS) {
|
|
@@ -140,13 +176,96 @@ function generateEnvFile(opts) {
|
|
|
140
176
|
}
|
|
141
177
|
return lines.join('\n');
|
|
142
178
|
}
|
|
179
|
+
const KEY_FORMAT_PREFIXES = {
|
|
180
|
+
anthropic: 'sk-ant-',
|
|
181
|
+
openai: 'sk-',
|
|
182
|
+
groq: 'gsk_',
|
|
183
|
+
};
|
|
184
|
+
async function validateProviderKey(providerKey, apiKey) {
|
|
185
|
+
// Fast-fail: format check for known prefix patterns
|
|
186
|
+
const expectedPrefix = KEY_FORMAT_PREFIXES[providerKey];
|
|
187
|
+
if (expectedPrefix && !apiKey.startsWith(expectedPrefix)) {
|
|
188
|
+
return {
|
|
189
|
+
valid: false,
|
|
190
|
+
error: `Key should start with "${expectedPrefix}"`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
// Ollama uses a local URL, no key validation needed
|
|
194
|
+
if (providerKey === 'ollama') {
|
|
195
|
+
return { valid: true };
|
|
196
|
+
}
|
|
197
|
+
// Lightweight API call to verify the key works
|
|
198
|
+
try {
|
|
199
|
+
let response;
|
|
200
|
+
if (providerKey === 'anthropic') {
|
|
201
|
+
response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
202
|
+
method: 'POST',
|
|
203
|
+
signal: AbortSignal.timeout(5000),
|
|
204
|
+
headers: {
|
|
205
|
+
'x-api-key': apiKey,
|
|
206
|
+
'anthropic-version': '2023-06-01',
|
|
207
|
+
'content-type': 'application/json',
|
|
208
|
+
},
|
|
209
|
+
body: JSON.stringify({
|
|
210
|
+
model: 'claude-3-haiku-20240307',
|
|
211
|
+
max_tokens: 1,
|
|
212
|
+
messages: [{ role: 'user', content: 'hi' }],
|
|
213
|
+
}),
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
else if (providerKey === 'openai') {
|
|
217
|
+
response = await fetch('https://api.openai.com/v1/models', {
|
|
218
|
+
signal: AbortSignal.timeout(5000),
|
|
219
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else if (providerKey === 'google') {
|
|
223
|
+
response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${encodeURIComponent(apiKey)}`, { signal: AbortSignal.timeout(5000) });
|
|
224
|
+
}
|
|
225
|
+
else if (providerKey === 'groq') {
|
|
226
|
+
response = await fetch('https://api.groq.com/openai/v1/models', {
|
|
227
|
+
signal: AbortSignal.timeout(5000),
|
|
228
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
// Provider not supported for live validation — skip
|
|
233
|
+
return { valid: true };
|
|
234
|
+
}
|
|
235
|
+
if (response.ok) {
|
|
236
|
+
return { valid: true };
|
|
237
|
+
}
|
|
238
|
+
// Parse error message from response body when possible
|
|
239
|
+
let detail;
|
|
240
|
+
try {
|
|
241
|
+
const body = (await response.json());
|
|
242
|
+
detail = body?.error?.message ?? (typeof body?.message === 'string' ? body.message : undefined);
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// ignore parse failure
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
valid: false,
|
|
249
|
+
error: detail ?? `HTTP ${response.status}`,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
if (err instanceof Error && err.name === 'TimeoutError') {
|
|
254
|
+
return { valid: false, error: 'Request timed out (5s)' };
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
valid: false,
|
|
258
|
+
error: err instanceof Error ? err.message : 'Network error',
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
143
262
|
// Interactive Onboarding
|
|
144
263
|
async function runInteractive() {
|
|
145
264
|
const banner = figlet.textSync('profClaw', { font: 'Standard' });
|
|
146
265
|
console.log(chalk.cyan(banner));
|
|
147
266
|
console.log(chalk.dim(' Onboarding Wizard\n'));
|
|
148
267
|
// Step 1: Detect environment
|
|
149
|
-
|
|
268
|
+
stepHeader(1, 6, 'Environment Detection');
|
|
150
269
|
const spin = spinner('Scanning environment...');
|
|
151
270
|
spin.start();
|
|
152
271
|
const env = await detectEnvironment();
|
|
@@ -220,8 +339,8 @@ async function runInteractive() {
|
|
|
220
339
|
const recommended = recommendMode(env);
|
|
221
340
|
console.log('');
|
|
222
341
|
console.log(` ${chalk.cyan('Recommended mode:')} ${chalk.bold(recommended)}`);
|
|
223
|
-
// Step 2: Choose mode
|
|
224
|
-
|
|
342
|
+
// Step 2: Choose mode
|
|
343
|
+
stepHeader(2, 6, 'Deployment Mode');
|
|
225
344
|
let mode;
|
|
226
345
|
try {
|
|
227
346
|
mode = await select({
|
|
@@ -252,47 +371,25 @@ async function runInteractive() {
|
|
|
252
371
|
process.exit(0);
|
|
253
372
|
}
|
|
254
373
|
success(`Mode: ${mode}`);
|
|
255
|
-
// Step 3: AI Provider
|
|
256
|
-
|
|
374
|
+
// Step 3: AI Provider
|
|
375
|
+
stepHeader(3, 6, 'AI Provider');
|
|
257
376
|
let anthropicKey;
|
|
258
377
|
let openaiKey;
|
|
259
378
|
let ollamaUrl;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
379
|
+
// Check all provider env vars (not just Anthropic/OpenAI)
|
|
380
|
+
let detectedProviderName = null;
|
|
381
|
+
for (const p of PROVIDER_CATALOG) {
|
|
382
|
+
const val = process.env[p.envVar];
|
|
383
|
+
if (val && val !== '' && !val.startsWith('sk-ant-xxxx') && !val.startsWith('sk-xxxx')) {
|
|
384
|
+
detectedProviderName = p.name;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (detectedProviderName) {
|
|
389
|
+
info(`AI provider already configured from environment (${detectedProviderName}).`);
|
|
264
390
|
}
|
|
265
391
|
else {
|
|
266
|
-
|
|
267
|
-
const providers = [
|
|
268
|
-
{ key: 'anthropic', name: 'Anthropic', models: 'Claude 4.x, 3.5 Sonnet', envVar: 'ANTHROPIC_API_KEY', category: 'Popular', tag: 'recommended' },
|
|
269
|
-
{ key: 'openai', name: 'OpenAI', models: 'GPT-4o, o1, o3', envVar: 'OPENAI_API_KEY', category: 'Popular', tag: '' },
|
|
270
|
-
{ key: 'google', name: 'Google AI', models: 'Gemini 2.x, Flash', envVar: 'GOOGLE_GENERATIVE_AI_API_KEY', category: 'Popular', tag: '' },
|
|
271
|
-
{ key: 'ollama', name: 'Ollama', models: 'Llama, Mistral, Qwen', envVar: 'OLLAMA_BASE_URL', category: 'Popular', tag: env.hasOllama ? 'detected' : 'free, local' },
|
|
272
|
-
{ key: 'groq', name: 'Groq', models: 'Llama, Mixtral', envVar: 'GROQ_API_KEY', category: 'Fast Inference', tag: 'fast' },
|
|
273
|
-
{ key: 'cerebras', name: 'Cerebras', models: 'Llama 3.3 70B', envVar: 'CEREBRAS_API_KEY', category: 'Fast Inference', tag: 'fast' },
|
|
274
|
-
{ key: 'fireworks', name: 'Fireworks', models: 'Llama, Mixtral', envVar: 'FIREWORKS_API_KEY', category: 'Fast Inference', tag: '' },
|
|
275
|
-
{ key: 'together', name: 'Together', models: 'Open models', envVar: 'TOGETHER_API_KEY', category: 'Fast Inference', tag: '' },
|
|
276
|
-
{ key: 'azure', name: 'Azure OpenAI', models: 'GPT-4o', envVar: 'AZURE_OPENAI_API_KEY', category: 'Enterprise', tag: 'enterprise' },
|
|
277
|
-
{ key: 'bedrock', name: 'AWS Bedrock', models: 'Claude, Titan, Llama', envVar: 'AWS_ACCESS_KEY_ID', category: 'Enterprise', tag: 'enterprise' },
|
|
278
|
-
{ key: 'watsonx', name: 'IBM Watsonx', models: 'Granite, Llama', envVar: 'WATSONX_API_KEY', category: 'Enterprise', tag: 'enterprise' },
|
|
279
|
-
{ key: 'deepseek', name: 'DeepSeek', models: 'V3, R1 (reasoning)', envVar: 'DEEPSEEK_API_KEY', category: 'More Providers', tag: '' },
|
|
280
|
-
{ key: 'mistral', name: 'Mistral', models: 'Large, Codestral', envVar: 'MISTRAL_API_KEY', category: 'More Providers', tag: '' },
|
|
281
|
-
{ key: 'xai', name: 'xAI', models: 'Grok', envVar: 'XAI_API_KEY', category: 'More Providers', tag: '' },
|
|
282
|
-
{ key: 'perplexity', name: 'Perplexity', models: 'Sonar (search)', envVar: 'PERPLEXITY_API_KEY', category: 'More Providers', tag: 'search' },
|
|
283
|
-
{ key: 'cohere', name: 'Cohere', models: 'Command R+', envVar: 'COHERE_API_KEY', category: 'More Providers', tag: '' },
|
|
284
|
-
{ key: 'openrouter', name: 'OpenRouter', models: 'Any model (proxy)', envVar: 'OPENROUTER_API_KEY', category: 'Aggregators', tag: 'multi-model' },
|
|
285
|
-
{ key: 'replicate', name: 'Replicate', models: 'Open-source models', envVar: 'REPLICATE_API_TOKEN', category: 'Aggregators', tag: '' },
|
|
286
|
-
{ key: 'github-models', name: 'GitHub Models', models: 'Azure-backed', envVar: 'GITHUB_TOKEN', category: 'Aggregators', tag: '' },
|
|
287
|
-
{ key: 'huggingface', name: 'HuggingFace', models: 'Inference API', envVar: 'HF_TOKEN', category: 'Aggregators', tag: '' },
|
|
288
|
-
{ key: 'nvidia-nim', name: 'NVIDIA NIM', models: 'Llama, Nemotron', envVar: 'NVIDIA_NIM_API_KEY', category: 'Aggregators', tag: '' },
|
|
289
|
-
{ key: 'zhipu', name: 'Zhipu AI', models: 'GLM-4, GLM-5', envVar: 'ZHIPU_API_KEY', category: 'Asia', tag: '' },
|
|
290
|
-
{ key: 'moonshot', name: 'Moonshot', models: 'Kimi (128K context)', envVar: 'MOONSHOT_API_KEY', category: 'Asia', tag: '' },
|
|
291
|
-
{ key: 'qwen', name: 'Qwen', models: 'Qwen Max, Plus', envVar: 'QWEN_API_KEY', category: 'Asia', tag: '' },
|
|
292
|
-
{ key: 'minimax', name: 'MiniMax', models: 'abab series', envVar: 'MINIMAX_API_KEY', category: 'Asia', tag: '' },
|
|
293
|
-
{ key: 'volcengine', name: 'Volcengine', models: 'Doubao (Bytedance)', envVar: 'VOLCENGINE_API_KEY', category: 'Asia', tag: '' },
|
|
294
|
-
{ key: 'qianfan', name: 'Qianfan', models: 'ERNIE (Baidu)', envVar: 'QIANFAN_API_KEY', category: 'Asia', tag: '' },
|
|
295
|
-
];
|
|
392
|
+
const providers = PROVIDER_CATALOG;
|
|
296
393
|
// Check which providers have keys in env
|
|
297
394
|
const detected = new Set();
|
|
298
395
|
for (const p of providers) {
|
|
@@ -306,6 +403,7 @@ async function runInteractive() {
|
|
|
306
403
|
try {
|
|
307
404
|
chosenProvider = await search({
|
|
308
405
|
message: 'Select AI provider (type to filter, arrows to navigate)',
|
|
406
|
+
pageSize: 15,
|
|
309
407
|
source: (term) => {
|
|
310
408
|
const results = [];
|
|
311
409
|
const filter = (term || '').toLowerCase();
|
|
@@ -377,108 +475,174 @@ async function runInteractive() {
|
|
|
377
475
|
success(`${chosen.name} already configured from ${chosen.envVar}`);
|
|
378
476
|
}
|
|
379
477
|
else {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
478
|
+
let configured = false;
|
|
479
|
+
while (!configured) {
|
|
480
|
+
let keyInput;
|
|
481
|
+
try {
|
|
482
|
+
keyInput = await input({
|
|
483
|
+
message: chosen.envVar,
|
|
484
|
+
theme: { prefix: ' ' },
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
warn('Input cancelled, skipping provider.');
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
if (!keyInput) {
|
|
492
|
+
warn('No key provided, skipping.');
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
const verifySpin = spinner('Verifying API key...');
|
|
496
|
+
verifySpin.start();
|
|
497
|
+
const validation = await validateProviderKey(chosen.key, keyInput);
|
|
498
|
+
verifySpin.stop();
|
|
499
|
+
if (validation.valid) {
|
|
386
500
|
if (chosen.key === 'anthropic')
|
|
387
501
|
anthropicKey = keyInput;
|
|
388
502
|
else if (chosen.key === 'openai')
|
|
389
503
|
openaiKey = keyInput;
|
|
390
|
-
else
|
|
504
|
+
else
|
|
391
505
|
process.env[chosen.envVar] = keyInput;
|
|
392
|
-
}
|
|
393
506
|
success(`${chosen.name} configured.`);
|
|
507
|
+
configured = true;
|
|
394
508
|
}
|
|
395
509
|
else {
|
|
396
|
-
|
|
510
|
+
error(`Invalid key: ${validation.error ?? 'verification failed'}`);
|
|
511
|
+
let retry = false;
|
|
512
|
+
try {
|
|
513
|
+
retry = await confirm({
|
|
514
|
+
message: 'Re-enter the key?',
|
|
515
|
+
default: true,
|
|
516
|
+
theme: { prefix: ' ' },
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
catch {
|
|
520
|
+
// cancelled
|
|
521
|
+
}
|
|
522
|
+
if (!retry) {
|
|
523
|
+
warn(`Skipping ${chosen.name}.`);
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
397
526
|
}
|
|
398
527
|
}
|
|
399
|
-
catch {
|
|
400
|
-
warn('Input cancelled, skipping provider.');
|
|
401
|
-
}
|
|
402
528
|
}
|
|
403
529
|
}
|
|
404
530
|
else {
|
|
405
531
|
info('AI provider skipped. Configure later: profclaw provider');
|
|
406
532
|
}
|
|
407
533
|
}
|
|
534
|
+
// Collect extra env vars that were set during provider selection
|
|
535
|
+
const extraEnvVars = {};
|
|
536
|
+
if (!anthropicKey && !openaiKey && !ollamaUrl) {
|
|
537
|
+
for (const key of PROVIDER_ENV_KEYS) {
|
|
538
|
+
if (process.env[key])
|
|
539
|
+
extraEnvVars[key] = process.env[key];
|
|
540
|
+
}
|
|
541
|
+
}
|
|
408
542
|
// Step 4: Generate .env
|
|
409
|
-
|
|
543
|
+
stepHeader(4, 6, 'Configuration');
|
|
544
|
+
const envPath = join(process.cwd(), '.env');
|
|
410
545
|
if (!env.existingEnv) {
|
|
411
546
|
const envContent = generateEnvFile({
|
|
412
547
|
mode,
|
|
413
548
|
anthropicKey,
|
|
414
549
|
openaiKey,
|
|
415
550
|
ollamaUrl,
|
|
551
|
+
extraEnvVars,
|
|
416
552
|
});
|
|
417
|
-
|
|
553
|
+
console.log(chalk.bold.white('\n Configuration Preview:\n'));
|
|
554
|
+
console.log(formatEnvPreview(envContent));
|
|
555
|
+
console.log('');
|
|
556
|
+
let writeConfirmed = true;
|
|
418
557
|
try {
|
|
419
|
-
|
|
420
|
-
|
|
558
|
+
writeConfirmed = await confirm({
|
|
559
|
+
message: 'Write this configuration to .env?',
|
|
560
|
+
default: true,
|
|
561
|
+
theme: { prefix: ' ' },
|
|
562
|
+
});
|
|
421
563
|
}
|
|
422
|
-
catch
|
|
423
|
-
|
|
424
|
-
|
|
564
|
+
catch { /* Ctrl+C — keep default true */ }
|
|
565
|
+
if (!writeConfirmed) {
|
|
566
|
+
warn('Skipped .env write. You can create it manually.');
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
try {
|
|
570
|
+
writeFileSync(envPath, envContent, { mode: 0o600 });
|
|
571
|
+
success('.env file created.');
|
|
572
|
+
}
|
|
573
|
+
catch (err) {
|
|
574
|
+
error(`Failed to write .env: ${err instanceof Error ? err.message : 'unknown'}`);
|
|
575
|
+
info('Create .env manually with the values above.');
|
|
576
|
+
}
|
|
425
577
|
}
|
|
426
578
|
}
|
|
427
579
|
else {
|
|
428
|
-
info('.env file already exists. Updating PROFCLAW_MODE...');
|
|
429
|
-
const envPath = join(process.cwd(), '.env');
|
|
430
580
|
let content = readFileSync(envPath, 'utf-8');
|
|
581
|
+
// Update mode
|
|
431
582
|
if (content.includes('PROFCLAW_MODE=')) {
|
|
432
583
|
content = content.replace(/PROFCLAW_MODE=\w+/, `PROFCLAW_MODE=${mode}`);
|
|
433
584
|
}
|
|
434
585
|
else {
|
|
435
586
|
content += `\nPROFCLAW_MODE=${mode}\n`;
|
|
436
587
|
}
|
|
437
|
-
|
|
438
|
-
|
|
588
|
+
// Add provider keys to existing .env
|
|
589
|
+
const keysToWrite = { ...extraEnvVars };
|
|
590
|
+
if (anthropicKey)
|
|
591
|
+
keysToWrite['ANTHROPIC_API_KEY'] = anthropicKey;
|
|
592
|
+
if (openaiKey)
|
|
593
|
+
keysToWrite['OPENAI_API_KEY'] = openaiKey;
|
|
594
|
+
if (ollamaUrl)
|
|
595
|
+
keysToWrite['OLLAMA_BASE_URL'] = ollamaUrl;
|
|
596
|
+
// Show preview of what will change
|
|
597
|
+
const allUpdates = { PROFCLAW_MODE: mode, ...keysToWrite };
|
|
598
|
+
console.log(chalk.bold.white('\n Changes to existing .env:\n'));
|
|
599
|
+
for (const [key, value] of Object.entries(allUpdates)) {
|
|
600
|
+
const masked = isSensitiveKey(key) ? maskApiKey(value) : value;
|
|
601
|
+
const action = content.includes(`${key}=`) ? chalk.yellow('update') : chalk.green('add');
|
|
602
|
+
console.log(` [${action}] ${chalk.cyan(key)}=${chalk.white(masked)}`);
|
|
603
|
+
}
|
|
604
|
+
console.log('');
|
|
605
|
+
let writeConfirmed = true;
|
|
606
|
+
try {
|
|
607
|
+
writeConfirmed = await confirm({
|
|
608
|
+
message: 'Apply these changes to .env?',
|
|
609
|
+
default: true,
|
|
610
|
+
theme: { prefix: ' ' },
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
catch { /* Ctrl+C — keep default true */ }
|
|
614
|
+
if (!writeConfirmed) {
|
|
615
|
+
warn('Skipped .env update. You can edit it manually.');
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
for (const [key, value] of Object.entries(keysToWrite)) {
|
|
619
|
+
if (content.includes(`${key}=`)) {
|
|
620
|
+
content = content.replace(new RegExp(`${key}=.*`), `${key}=${value}`);
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
content += `${key}=${value}\n`;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
writeFileSync(envPath, content);
|
|
627
|
+
const keyCount = Object.keys(keysToWrite).length;
|
|
628
|
+
if (keyCount > 0) {
|
|
629
|
+
success(`PROFCLAW_MODE=${mode} + ${keyCount} provider key(s) saved to .env`);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
success(`PROFCLAW_MODE=${mode} set in .env`);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
439
635
|
}
|
|
440
|
-
//
|
|
441
|
-
|
|
442
|
-
info('Launching setup wizard for admin account and provider configuration...\n');
|
|
636
|
+
// Steps 5-6: Delegate to setup wizard for admin account + registration
|
|
637
|
+
// Setup continues the step numbering (5/6, 6/6) and shows summary + server start
|
|
443
638
|
try {
|
|
444
639
|
const { setupCommand } = await import('./setup.js');
|
|
445
640
|
const setupCmd = setupCommand();
|
|
446
|
-
await setupCmd.parseAsync(['node', 'setup']);
|
|
641
|
+
await setupCmd.parseAsync(['node', 'setup', '--from-onboard']);
|
|
447
642
|
}
|
|
448
643
|
catch (err) {
|
|
449
644
|
error(`Setup wizard failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
450
645
|
info('You can run it again later: profclaw setup');
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
// Step 6: Post-setup validation
|
|
454
|
-
console.log(chalk.bold.white('\n Step 6: Validation\n'));
|
|
455
|
-
const postSpin = spinner('Validating installation...');
|
|
456
|
-
postSpin.start();
|
|
457
|
-
const checks = [];
|
|
458
|
-
// Check .env exists
|
|
459
|
-
const envExists = existsSync(join(process.cwd(), '.env'));
|
|
460
|
-
checks.push({ label: '.env file', ok: envExists });
|
|
461
|
-
// Check config exists
|
|
462
|
-
const configExists = existsSync(join(process.cwd(), 'config', 'settings.yml'));
|
|
463
|
-
checks.push({ label: 'config/settings.yml', ok: configExists });
|
|
464
|
-
// Check database was created
|
|
465
|
-
const dbExists = existsSync(join(process.cwd(), 'data', 'profclaw.db'));
|
|
466
|
-
checks.push({ label: 'Database', ok: dbExists });
|
|
467
|
-
postSpin.stop();
|
|
468
|
-
for (const check of checks) {
|
|
469
|
-
const icon = check.ok ? chalk.green(' +') : chalk.red(' -');
|
|
470
|
-
console.log(`${icon} ${check.label}: ${check.ok ? 'OK' : 'missing'}`);
|
|
471
|
-
}
|
|
472
|
-
const allPassed = checks.every((c) => c.ok);
|
|
473
|
-
if (allPassed) {
|
|
474
|
-
console.log('');
|
|
475
|
-
success('Onboarding complete! Start the server:');
|
|
476
|
-
console.log(`\n ${chalk.cyan.bold('profclaw serve')}\n`);
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
479
|
-
console.log('');
|
|
480
|
-
warn('Some checks did not pass. You may need to run setup again:');
|
|
481
|
-
console.log(`\n ${chalk.cyan('profclaw setup')}\n`);
|
|
482
646
|
}
|
|
483
647
|
}
|
|
484
648
|
// Non-Interactive Onboarding
|
|
@@ -538,6 +702,7 @@ export function onboardCommand() {
|
|
|
538
702
|
else {
|
|
539
703
|
await runInteractive();
|
|
540
704
|
}
|
|
705
|
+
process.exit(0);
|
|
541
706
|
}
|
|
542
707
|
catch (err) {
|
|
543
708
|
error(err instanceof Error ? err.message : 'Onboarding failed');
|
|
@@ -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
|