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,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Summary Tracker
|
|
3
|
+
*
|
|
4
|
+
* Provides real-time 1-2 word progress summaries of what agents are doing,
|
|
5
|
+
* suitable for display in CLI/UI progress indicators.
|
|
6
|
+
*/
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
function extractFilename(filePath) {
|
|
9
|
+
if (typeof filePath !== 'string' || filePath.length === 0)
|
|
10
|
+
return undefined;
|
|
11
|
+
return path.basename(filePath);
|
|
12
|
+
}
|
|
13
|
+
function extractCommand(command) {
|
|
14
|
+
if (typeof command !== 'string' || command.length === 0)
|
|
15
|
+
return undefined;
|
|
16
|
+
// Truncate long commands to first 40 chars
|
|
17
|
+
const trimmed = command.trim();
|
|
18
|
+
return trimmed.length > 40 ? `${trimmed.substring(0, 40)}…` : trimmed;
|
|
19
|
+
}
|
|
20
|
+
function extractQuery(query) {
|
|
21
|
+
if (typeof query !== 'string' || query.length === 0)
|
|
22
|
+
return undefined;
|
|
23
|
+
const trimmed = query.trim();
|
|
24
|
+
return trimmed.length > 30 ? `${trimmed.substring(0, 30)}…` : trimmed;
|
|
25
|
+
}
|
|
26
|
+
function isRecord(value) {
|
|
27
|
+
return typeof value === 'object' && value !== null;
|
|
28
|
+
}
|
|
29
|
+
function toArgs(input) {
|
|
30
|
+
return isRecord(input) ? input : {};
|
|
31
|
+
}
|
|
32
|
+
export class AgentSummaryTracker {
|
|
33
|
+
summaries = new Map();
|
|
34
|
+
broadcaster;
|
|
35
|
+
registerSSEBroadcaster(broadcaster) {
|
|
36
|
+
this.broadcaster = broadcaster;
|
|
37
|
+
}
|
|
38
|
+
start(sessionId) {
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
const summary = {
|
|
41
|
+
sessionId,
|
|
42
|
+
status: 'idle',
|
|
43
|
+
currentAction: 'Starting',
|
|
44
|
+
stepCount: 0,
|
|
45
|
+
tokensUsed: 0,
|
|
46
|
+
startedAt: now,
|
|
47
|
+
updatedAt: now,
|
|
48
|
+
};
|
|
49
|
+
this.summaries.set(sessionId, summary);
|
|
50
|
+
this.broadcaster?.('agent:summary', summary);
|
|
51
|
+
}
|
|
52
|
+
update(sessionId, updates) {
|
|
53
|
+
const existing = this.summaries.get(sessionId);
|
|
54
|
+
if (!existing)
|
|
55
|
+
return;
|
|
56
|
+
const updated = {
|
|
57
|
+
...existing,
|
|
58
|
+
...updates,
|
|
59
|
+
sessionId, // always preserve original sessionId
|
|
60
|
+
updatedAt: Date.now(),
|
|
61
|
+
};
|
|
62
|
+
this.summaries.set(sessionId, updated);
|
|
63
|
+
this.broadcaster?.('agent:summary', updated);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Auto-generate a human-readable summary from a tool call.
|
|
67
|
+
*
|
|
68
|
+
* Examples:
|
|
69
|
+
* read_file({ path: '/src/auth.ts' }) → "Reading auth.ts"
|
|
70
|
+
* write_file({ path: '/src/fix.ts' }) → "Writing fix.ts"
|
|
71
|
+
* bash({ command: 'npm test' }) → "Running npm test"
|
|
72
|
+
* search_files({ query: 'login' }) → "Searching for 'login'"
|
|
73
|
+
* git_commit({ message: 'fix: auth' }) → "Committing changes"
|
|
74
|
+
* complete_task → "Completing task"
|
|
75
|
+
* default → "Using {toolName}"
|
|
76
|
+
*/
|
|
77
|
+
summarizeToolCall(sessionId, toolName, args) {
|
|
78
|
+
const argsRecord = toArgs(args);
|
|
79
|
+
// File reads
|
|
80
|
+
if (toolName === 'read_file' || toolName === 'Read') {
|
|
81
|
+
const filename = extractFilename(argsRecord['path'] ?? argsRecord['file_path']);
|
|
82
|
+
return filename ? `Reading ${filename}` : 'Reading file';
|
|
83
|
+
}
|
|
84
|
+
// File writes
|
|
85
|
+
if (toolName === 'write_file' || toolName === 'Write' || toolName === 'create_file') {
|
|
86
|
+
const filename = extractFilename(argsRecord['path'] ?? argsRecord['file_path']);
|
|
87
|
+
return filename ? `Writing ${filename}` : 'Writing file';
|
|
88
|
+
}
|
|
89
|
+
// File edits
|
|
90
|
+
if (toolName === 'edit_file' || toolName === 'Edit' || toolName === 'str_replace_editor') {
|
|
91
|
+
const filename = extractFilename(argsRecord['path'] ?? argsRecord['file_path']);
|
|
92
|
+
return filename ? `Editing ${filename}` : 'Editing file';
|
|
93
|
+
}
|
|
94
|
+
// Bash/shell execution
|
|
95
|
+
if (toolName === 'bash' || toolName === 'Bash' || toolName === 'execute_command' || toolName === 'run_command') {
|
|
96
|
+
const cmd = extractCommand(argsRecord['command'] ?? argsRecord['cmd']);
|
|
97
|
+
return cmd ? `Running ${cmd}` : 'Running command';
|
|
98
|
+
}
|
|
99
|
+
// File search / glob
|
|
100
|
+
if (toolName === 'search_files' || toolName === 'Glob' || toolName === 'glob') {
|
|
101
|
+
const query = extractQuery(argsRecord['query'] ?? argsRecord['pattern']);
|
|
102
|
+
return query ? `Searching for '${query}'` : 'Searching files';
|
|
103
|
+
}
|
|
104
|
+
// Content search / grep
|
|
105
|
+
if (toolName === 'grep' || toolName === 'Grep' || toolName === 'search_content') {
|
|
106
|
+
const query = extractQuery(argsRecord['query'] ?? argsRecord['pattern']);
|
|
107
|
+
return query ? `Searching for '${query}'` : 'Searching content';
|
|
108
|
+
}
|
|
109
|
+
// Git operations
|
|
110
|
+
if (toolName === 'git_commit' || toolName === 'git_push') {
|
|
111
|
+
return 'Committing changes';
|
|
112
|
+
}
|
|
113
|
+
if (toolName === 'git_status') {
|
|
114
|
+
return 'Checking git status';
|
|
115
|
+
}
|
|
116
|
+
if (toolName === 'git_diff') {
|
|
117
|
+
return 'Reviewing changes';
|
|
118
|
+
}
|
|
119
|
+
// Task completion
|
|
120
|
+
if (toolName === 'complete_task') {
|
|
121
|
+
return 'Completing task';
|
|
122
|
+
}
|
|
123
|
+
// Web fetch / browse
|
|
124
|
+
if (toolName === 'web_fetch' || toolName === 'WebFetch' || toolName === 'fetch_url' || toolName === 'browse') {
|
|
125
|
+
const url = argsRecord['url'] ?? argsRecord['href'];
|
|
126
|
+
if (typeof url === 'string' && url.length > 0) {
|
|
127
|
+
try {
|
|
128
|
+
const { hostname } = new URL(url);
|
|
129
|
+
return `Fetching ${hostname}`;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// malformed URL - fall through to default
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return 'Fetching URL';
|
|
136
|
+
}
|
|
137
|
+
// Task tool — spawn sub-agent
|
|
138
|
+
if (toolName === 'Task' || toolName === 'task') {
|
|
139
|
+
return 'Spawning agent';
|
|
140
|
+
}
|
|
141
|
+
// Default fallback: humanize camelCase/snake_case tool name
|
|
142
|
+
const humanized = toolName
|
|
143
|
+
.replace(/_/g, ' ')
|
|
144
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
145
|
+
.toLowerCase();
|
|
146
|
+
return `Using ${humanized}`;
|
|
147
|
+
}
|
|
148
|
+
get(sessionId) {
|
|
149
|
+
return this.summaries.get(sessionId);
|
|
150
|
+
}
|
|
151
|
+
getAll() {
|
|
152
|
+
return Array.from(this.summaries.values());
|
|
153
|
+
}
|
|
154
|
+
end(sessionId) {
|
|
155
|
+
const existing = this.summaries.get(sessionId);
|
|
156
|
+
if (existing) {
|
|
157
|
+
this.broadcaster?.('agent:summary', {
|
|
158
|
+
...existing,
|
|
159
|
+
status: 'idle',
|
|
160
|
+
currentAction: 'Done',
|
|
161
|
+
updatedAt: Date.now(),
|
|
162
|
+
ended: true,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
this.summaries.delete(sessionId);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Singleton instance
|
|
169
|
+
let tracker;
|
|
170
|
+
export function getAgentSummaryTracker() {
|
|
171
|
+
if (!tracker) {
|
|
172
|
+
tracker = new AgentSummaryTracker();
|
|
173
|
+
}
|
|
174
|
+
return tracker;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=agent-summary.js.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-Memory Extractor
|
|
3
|
+
*
|
|
4
|
+
* Extracts durable insights from conversation turns using local
|
|
5
|
+
* keyword/pattern matching — no LLM calls required.
|
|
6
|
+
*
|
|
7
|
+
* Memories are stored at .profclaw/memory/entries.json
|
|
8
|
+
*/
|
|
9
|
+
export type MemoryType = 'decision' | 'preference' | 'context' | 'pattern' | 'error_fix';
|
|
10
|
+
export interface MemoryEntry {
|
|
11
|
+
id: string;
|
|
12
|
+
type: MemoryType;
|
|
13
|
+
content: string;
|
|
14
|
+
source: {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
turnIndex: number;
|
|
17
|
+
};
|
|
18
|
+
createdAt: number;
|
|
19
|
+
/** 0-1, decays over time via prune() */
|
|
20
|
+
relevance: number;
|
|
21
|
+
}
|
|
22
|
+
export interface TurnInput {
|
|
23
|
+
userMessage: string;
|
|
24
|
+
assistantResponse: string;
|
|
25
|
+
toolCalls?: Array<{
|
|
26
|
+
name: string;
|
|
27
|
+
args: unknown;
|
|
28
|
+
result: unknown;
|
|
29
|
+
}>;
|
|
30
|
+
sessionId: string;
|
|
31
|
+
turnIndex: number;
|
|
32
|
+
}
|
|
33
|
+
export declare class AutoMemoryExtractor {
|
|
34
|
+
private memoryDir;
|
|
35
|
+
private entries;
|
|
36
|
+
/** Tool sequence tracking keyed by sequence fingerprint */
|
|
37
|
+
private toolSequences;
|
|
38
|
+
constructor(projectRoot?: string);
|
|
39
|
+
extractFromTurn(turn: TurnInput): MemoryEntry[];
|
|
40
|
+
search(query: string, limit?: number): MemoryEntry[];
|
|
41
|
+
getAll(): MemoryEntry[];
|
|
42
|
+
save(): void;
|
|
43
|
+
load(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Remove entries that are too old or too low relevance.
|
|
46
|
+
* Also applies time-based decay to remaining entries.
|
|
47
|
+
* Returns the count of pruned entries.
|
|
48
|
+
*/
|
|
49
|
+
prune(maxAgeMs?: number, minRelevance?: number): number;
|
|
50
|
+
private entriesFilePath;
|
|
51
|
+
private ensureDir;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns the process-level singleton AutoMemoryExtractor, rooted at cwd().
|
|
55
|
+
*/
|
|
56
|
+
export declare function getAutoMemoryExtractor(): AutoMemoryExtractor;
|
|
57
|
+
/** Exported for test injection. */
|
|
58
|
+
export declare function _resetAutoMemoryExtractorSingleton(): void;
|
|
59
|
+
//# sourceMappingURL=auto-memory.d.ts.map
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-Memory Extractor
|
|
3
|
+
*
|
|
4
|
+
* Extracts durable insights from conversation turns using local
|
|
5
|
+
* keyword/pattern matching — no LLM calls required.
|
|
6
|
+
*
|
|
7
|
+
* Memories are stored at .profclaw/memory/entries.json
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import { randomUUID } from 'node:crypto';
|
|
12
|
+
const EXTRACTION_RULES = [
|
|
13
|
+
// Decision: "no, use X instead" / "don't do X" / "use X not Y"
|
|
14
|
+
{
|
|
15
|
+
type: 'decision',
|
|
16
|
+
userPatterns: [
|
|
17
|
+
/\bno[,.]?\s+use\s+(.+?)\s+instead\b/i,
|
|
18
|
+
/\bdon['']?t\s+use\s+(.+?)[\.,]/i,
|
|
19
|
+
/\buse\s+(.+?)\s+(?:not|instead of)\s+(.+?)[\.,]/i,
|
|
20
|
+
/\bplease\s+(?:use|switch to)\s+(.+?)\s+instead\b/i,
|
|
21
|
+
/\bthat'?s?\s+(?:wrong|incorrect)[,.]?\s+(?:it\s+should\s+be|use)\s+(.+?)[\.,]/i,
|
|
22
|
+
],
|
|
23
|
+
format: (userMsg) => `Decision: ${userMsg.trim()}`,
|
|
24
|
+
},
|
|
25
|
+
// Preference: "I prefer X" / "I like X" / "always use X"
|
|
26
|
+
{
|
|
27
|
+
type: 'preference',
|
|
28
|
+
userPatterns: [
|
|
29
|
+
/\bI\s+prefer\s+(.+?)[\.,]/i,
|
|
30
|
+
/\bI\s+(?:always|usually)\s+use\s+(.+?)[\.,]/i,
|
|
31
|
+
/\bI\s+like\s+(?:to\s+use\s+)?(.+?)[\.,]/i,
|
|
32
|
+
/\balways\s+use\s+(.+?)[\.,]/i,
|
|
33
|
+
/\bmy\s+preferred\s+(.+?)\s+is\s+(.+?)[\.,]/i,
|
|
34
|
+
],
|
|
35
|
+
format: (userMsg) => `Preference: ${userMsg.trim()}`,
|
|
36
|
+
},
|
|
37
|
+
// Context: "this project uses X" / "we use X" / "the stack is X"
|
|
38
|
+
{
|
|
39
|
+
type: 'context',
|
|
40
|
+
userPatterns: [
|
|
41
|
+
/\bthis\s+project\s+uses?\s+(.+?)[\.,]/i,
|
|
42
|
+
/\bwe\s+(?:use|are using)\s+(.+?)[\.,]/i,
|
|
43
|
+
/\bthe\s+stack\s+is\s+(.+?)[\.,]/i,
|
|
44
|
+
/\bour\s+(?:app|service|backend|frontend)\s+(?:uses?|runs?)\s+(.+?)[\.,]/i,
|
|
45
|
+
/\bbuilt\s+(?:with|on|using)\s+(.+?)[\.,]/i,
|
|
46
|
+
],
|
|
47
|
+
format: (userMsg) => `Context: ${userMsg.trim()}`,
|
|
48
|
+
},
|
|
49
|
+
// Error fix: "the fix was X" / "the issue was X" / "solved by X"
|
|
50
|
+
{
|
|
51
|
+
type: 'error_fix',
|
|
52
|
+
userPatterns: [
|
|
53
|
+
/\bthe\s+(?:fix|solution)\s+(?:was|is)\s+(.+?)[\.,]/i,
|
|
54
|
+
/\bthe\s+(?:issue|problem|bug)\s+(?:was|is)\s+(.+?)[\.,]/i,
|
|
55
|
+
/\bsolved\s+by\s+(.+?)[\.,]/i,
|
|
56
|
+
/\bfixed\s+(?:by|with|using)\s+(.+?)[\.,]/i,
|
|
57
|
+
],
|
|
58
|
+
assistantPatterns: [
|
|
59
|
+
/\bthe\s+(?:fix|issue|problem)\s+(?:was|is)\s+(.+?)[\.,]/i,
|
|
60
|
+
/\bthis\s+(?:was\s+caused|happened)\s+(?:by|because)\s+(.+?)[\.,]/i,
|
|
61
|
+
/\broot\s+cause[:\s]+(.+?)[\.,]/i,
|
|
62
|
+
],
|
|
63
|
+
format: (userMsg, assistantMsg, match) => {
|
|
64
|
+
const src = match ? assistantMsg : userMsg;
|
|
65
|
+
return `Error fix: ${src.trim()}`;
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
// Context: assistant explains project facts
|
|
69
|
+
{
|
|
70
|
+
type: 'context',
|
|
71
|
+
assistantPatterns: [
|
|
72
|
+
/\bthis\s+project\s+uses?\s+(.+?)[\.,]/i,
|
|
73
|
+
/\byou(?:'re|\s+are)\s+using\s+(.+?)[\.,]/i,
|
|
74
|
+
],
|
|
75
|
+
format: (_userMsg, assistantMsg) => `Context: ${assistantMsg.trim()}`,
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
const PATTERN_THRESHOLD = 3;
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// AutoMemoryExtractor
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
let _instance = null;
|
|
83
|
+
export class AutoMemoryExtractor {
|
|
84
|
+
memoryDir;
|
|
85
|
+
entries;
|
|
86
|
+
/** Tool sequence tracking keyed by sequence fingerprint */
|
|
87
|
+
toolSequences;
|
|
88
|
+
constructor(projectRoot) {
|
|
89
|
+
const root = projectRoot ?? process.cwd();
|
|
90
|
+
this.memoryDir = path.join(root, '.profclaw', 'memory');
|
|
91
|
+
this.entries = [];
|
|
92
|
+
this.toolSequences = new Map();
|
|
93
|
+
this.load();
|
|
94
|
+
}
|
|
95
|
+
// -------------------------------------------------------------------------
|
|
96
|
+
// Core: extract memories from a completed turn
|
|
97
|
+
// -------------------------------------------------------------------------
|
|
98
|
+
extractFromTurn(turn) {
|
|
99
|
+
const extracted = [];
|
|
100
|
+
const { userMessage, assistantResponse, toolCalls, sessionId, turnIndex } = turn;
|
|
101
|
+
// Apply each rule
|
|
102
|
+
for (const rule of EXTRACTION_RULES) {
|
|
103
|
+
let matchedUser = null;
|
|
104
|
+
let matchedAssistant = null;
|
|
105
|
+
if (rule.userPatterns) {
|
|
106
|
+
for (const pat of rule.userPatterns) {
|
|
107
|
+
const m = userMessage.match(pat);
|
|
108
|
+
if (m) {
|
|
109
|
+
matchedUser = m;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (rule.assistantPatterns) {
|
|
115
|
+
for (const pat of rule.assistantPatterns) {
|
|
116
|
+
const m = assistantResponse.match(pat);
|
|
117
|
+
if (m) {
|
|
118
|
+
matchedAssistant = m;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Determine if the rule fires
|
|
124
|
+
let fires = false;
|
|
125
|
+
let matchRef = null;
|
|
126
|
+
if (rule.userPatterns && rule.assistantPatterns) {
|
|
127
|
+
// Both required when both pattern sets are defined and requireBoth is true
|
|
128
|
+
if (rule.requireBoth) {
|
|
129
|
+
fires = matchedUser !== null && matchedAssistant !== null;
|
|
130
|
+
matchRef = matchedAssistant;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
fires = matchedUser !== null || matchedAssistant !== null;
|
|
134
|
+
matchRef = matchedAssistant ?? matchedUser;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else if (rule.userPatterns) {
|
|
138
|
+
fires = matchedUser !== null;
|
|
139
|
+
matchRef = matchedUser;
|
|
140
|
+
}
|
|
141
|
+
else if (rule.assistantPatterns) {
|
|
142
|
+
fires = matchedAssistant !== null;
|
|
143
|
+
matchRef = matchedAssistant;
|
|
144
|
+
}
|
|
145
|
+
if (!fires)
|
|
146
|
+
continue;
|
|
147
|
+
const content = rule.format(userMessage, assistantResponse, matchRef);
|
|
148
|
+
// Avoid duplicate entries with identical content
|
|
149
|
+
if (this.entries.some((e) => e.content === content))
|
|
150
|
+
continue;
|
|
151
|
+
const entry = {
|
|
152
|
+
id: randomUUID(),
|
|
153
|
+
type: rule.type,
|
|
154
|
+
content,
|
|
155
|
+
source: { sessionId, turnIndex },
|
|
156
|
+
createdAt: Date.now(),
|
|
157
|
+
relevance: 1.0,
|
|
158
|
+
};
|
|
159
|
+
extracted.push(entry);
|
|
160
|
+
this.entries.push(entry);
|
|
161
|
+
}
|
|
162
|
+
// Pattern memory: detect repeated tool sequences
|
|
163
|
+
if (toolCalls && toolCalls.length >= 2) {
|
|
164
|
+
const sequence = toolCalls.map((tc) => tc.name).join(' → ');
|
|
165
|
+
const existing = this.toolSequences.get(sequence);
|
|
166
|
+
if (existing) {
|
|
167
|
+
existing.count += 1;
|
|
168
|
+
existing.lastTurnIndex = turnIndex;
|
|
169
|
+
if (existing.count === PATTERN_THRESHOLD) {
|
|
170
|
+
const content = `Pattern: tool chain "${sequence}" used ${existing.count}+ times`;
|
|
171
|
+
if (!this.entries.some((e) => e.content === content)) {
|
|
172
|
+
const entry = {
|
|
173
|
+
id: randomUUID(),
|
|
174
|
+
type: 'pattern',
|
|
175
|
+
content,
|
|
176
|
+
source: { sessionId, turnIndex },
|
|
177
|
+
createdAt: Date.now(),
|
|
178
|
+
relevance: 1.0,
|
|
179
|
+
};
|
|
180
|
+
extracted.push(entry);
|
|
181
|
+
this.entries.push(entry);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
this.toolSequences.set(sequence, {
|
|
187
|
+
sequence,
|
|
188
|
+
count: 1,
|
|
189
|
+
lastTurnIndex: turnIndex,
|
|
190
|
+
sessionId,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (extracted.length > 0) {
|
|
195
|
+
this.save();
|
|
196
|
+
}
|
|
197
|
+
return extracted;
|
|
198
|
+
}
|
|
199
|
+
// -------------------------------------------------------------------------
|
|
200
|
+
// Search: keyword matching + relevance scoring
|
|
201
|
+
// -------------------------------------------------------------------------
|
|
202
|
+
search(query, limit = 10) {
|
|
203
|
+
if (!query.trim())
|
|
204
|
+
return this.entries.slice(0, limit);
|
|
205
|
+
const words = query
|
|
206
|
+
.toLowerCase()
|
|
207
|
+
.split(/\s+/)
|
|
208
|
+
.filter((w) => w.length >= 2);
|
|
209
|
+
const scored = this.entries.map((entry) => {
|
|
210
|
+
const lower = entry.content.toLowerCase();
|
|
211
|
+
const matchCount = words.filter((w) => lower.includes(w)).length;
|
|
212
|
+
const score = (matchCount / Math.max(words.length, 1)) * entry.relevance;
|
|
213
|
+
return { entry, score };
|
|
214
|
+
});
|
|
215
|
+
return scored
|
|
216
|
+
.filter(({ score }) => score > 0)
|
|
217
|
+
.sort((a, b) => b.score - a.score)
|
|
218
|
+
.slice(0, limit)
|
|
219
|
+
.map(({ entry }) => entry);
|
|
220
|
+
}
|
|
221
|
+
// -------------------------------------------------------------------------
|
|
222
|
+
// Accessors
|
|
223
|
+
// -------------------------------------------------------------------------
|
|
224
|
+
getAll() {
|
|
225
|
+
return [...this.entries];
|
|
226
|
+
}
|
|
227
|
+
// -------------------------------------------------------------------------
|
|
228
|
+
// Persistence
|
|
229
|
+
// -------------------------------------------------------------------------
|
|
230
|
+
save() {
|
|
231
|
+
try {
|
|
232
|
+
this.ensureDir();
|
|
233
|
+
const filePath = this.entriesFilePath();
|
|
234
|
+
fs.writeFileSync(filePath, JSON.stringify({ entries: this.entries, sequences: Array.from(this.toolSequences.entries()) }, null, 2), 'utf8');
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
console.error('[AutoMemoryExtractor] Failed to save:', err);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
load() {
|
|
241
|
+
const filePath = this.entriesFilePath();
|
|
242
|
+
if (!fs.existsSync(filePath))
|
|
243
|
+
return;
|
|
244
|
+
try {
|
|
245
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
246
|
+
const parsed = JSON.parse(raw);
|
|
247
|
+
this.entries = Array.isArray(parsed.entries) ? parsed.entries : [];
|
|
248
|
+
if (Array.isArray(parsed.sequences)) {
|
|
249
|
+
this.toolSequences = new Map(parsed.sequences);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
console.error('[AutoMemoryExtractor] Failed to load:', err);
|
|
254
|
+
this.entries = [];
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// -------------------------------------------------------------------------
|
|
258
|
+
// Pruning
|
|
259
|
+
// -------------------------------------------------------------------------
|
|
260
|
+
/**
|
|
261
|
+
* Remove entries that are too old or too low relevance.
|
|
262
|
+
* Also applies time-based decay to remaining entries.
|
|
263
|
+
* Returns the count of pruned entries.
|
|
264
|
+
*/
|
|
265
|
+
prune(maxAgeMs = 30 * 24 * 60 * 60 * 1000, minRelevance = 0.1) {
|
|
266
|
+
const now = Date.now();
|
|
267
|
+
const before = this.entries.length;
|
|
268
|
+
this.entries = this.entries
|
|
269
|
+
.map((e) => {
|
|
270
|
+
// Exponential decay: half-life = maxAgeMs / 2
|
|
271
|
+
const ageFraction = (now - e.createdAt) / maxAgeMs;
|
|
272
|
+
const decayed = e.relevance * Math.exp(-Math.LN2 * ageFraction);
|
|
273
|
+
return { ...e, relevance: Math.max(0, decayed) };
|
|
274
|
+
})
|
|
275
|
+
.filter((e) => {
|
|
276
|
+
const tooOld = now - e.createdAt > maxAgeMs;
|
|
277
|
+
const tooWeak = e.relevance < minRelevance;
|
|
278
|
+
return !tooOld && !tooWeak;
|
|
279
|
+
});
|
|
280
|
+
const pruned = before - this.entries.length;
|
|
281
|
+
if (pruned > 0)
|
|
282
|
+
this.save();
|
|
283
|
+
return pruned;
|
|
284
|
+
}
|
|
285
|
+
// -------------------------------------------------------------------------
|
|
286
|
+
// Private helpers
|
|
287
|
+
// -------------------------------------------------------------------------
|
|
288
|
+
entriesFilePath() {
|
|
289
|
+
return path.join(this.memoryDir, 'entries.json');
|
|
290
|
+
}
|
|
291
|
+
ensureDir() {
|
|
292
|
+
if (!fs.existsSync(this.memoryDir)) {
|
|
293
|
+
fs.mkdirSync(this.memoryDir, { recursive: true });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Returns the process-level singleton AutoMemoryExtractor, rooted at cwd().
|
|
299
|
+
*/
|
|
300
|
+
export function getAutoMemoryExtractor() {
|
|
301
|
+
if (!_instance) {
|
|
302
|
+
_instance = new AutoMemoryExtractor();
|
|
303
|
+
}
|
|
304
|
+
return _instance;
|
|
305
|
+
}
|
|
306
|
+
/** Exported for test injection. */
|
|
307
|
+
export function _resetAutoMemoryExtractorSingleton() {
|
|
308
|
+
_instance = null;
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=auto-memory.js.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint Manager
|
|
3
|
+
*
|
|
4
|
+
* Saves and restores executor state so long-running agentic sessions can be
|
|
5
|
+
* interrupted and resumed without losing progress. Checkpoints live at
|
|
6
|
+
* .profclaw/checkpoints/<sessionId>.json relative to the project root (or the
|
|
7
|
+
* current working directory when no root is supplied).
|
|
8
|
+
*/
|
|
9
|
+
import type { ModelMessage } from 'ai';
|
|
10
|
+
export interface ExecutorCheckpoint {
|
|
11
|
+
/** Session that produced this checkpoint */
|
|
12
|
+
sessionId: string;
|
|
13
|
+
/** Human-readable description of the original task */
|
|
14
|
+
taskDescription?: string;
|
|
15
|
+
/** How many steps have been executed so far */
|
|
16
|
+
currentStep: number;
|
|
17
|
+
/** Expected total steps (best-effort estimate) */
|
|
18
|
+
totalSteps: number;
|
|
19
|
+
/** Full message history up to this point */
|
|
20
|
+
messages: ModelMessage[];
|
|
21
|
+
/** Cumulative tokens consumed */
|
|
22
|
+
tokensUsed: number;
|
|
23
|
+
/** Estimated dollar cost so far */
|
|
24
|
+
estimatedCost: number;
|
|
25
|
+
/** Every tool call made so far: name, success flag, and the step it ran in */
|
|
26
|
+
toolCallHistory: Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
success: boolean;
|
|
29
|
+
step: number;
|
|
30
|
+
}>;
|
|
31
|
+
/** Files that have already been processed (for file-iteration tasks) */
|
|
32
|
+
completedFiles?: string[];
|
|
33
|
+
/** Free-text description of what still needs to happen */
|
|
34
|
+
remainingWork?: string;
|
|
35
|
+
/** Unix epoch ms — when the checkpoint was first created */
|
|
36
|
+
createdAt: number;
|
|
37
|
+
/** Unix epoch ms — when the checkpoint was last saved */
|
|
38
|
+
updatedAt: number;
|
|
39
|
+
}
|
|
40
|
+
/** Lightweight summary returned by list() */
|
|
41
|
+
export interface CheckpointSummary {
|
|
42
|
+
sessionId: string;
|
|
43
|
+
taskDescription?: string;
|
|
44
|
+
step: number;
|
|
45
|
+
updatedAt: number;
|
|
46
|
+
}
|
|
47
|
+
export declare class CheckpointManager {
|
|
48
|
+
private readonly checkpointsDir;
|
|
49
|
+
constructor(projectRoot?: string);
|
|
50
|
+
private filePath;
|
|
51
|
+
private ensureDir;
|
|
52
|
+
/**
|
|
53
|
+
* Persist a checkpoint to disk. Creates .profclaw/checkpoints/ if needed.
|
|
54
|
+
*/
|
|
55
|
+
save(checkpoint: ExecutorCheckpoint): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Load a previously saved checkpoint. Returns null when none exists.
|
|
58
|
+
*/
|
|
59
|
+
load(sessionId: string): Promise<ExecutorCheckpoint | null>;
|
|
60
|
+
/**
|
|
61
|
+
* List all checkpoints, sorted newest first.
|
|
62
|
+
*/
|
|
63
|
+
list(): Promise<CheckpointSummary[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Delete a checkpoint after the session has completed successfully.
|
|
66
|
+
*/
|
|
67
|
+
remove(sessionId: string): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Find a resumable checkpoint whose taskDescription loosely matches the
|
|
70
|
+
* given description (case-insensitive substring + word overlap heuristic).
|
|
71
|
+
* Returns the most recently updated match, or null if nothing qualifies.
|
|
72
|
+
*/
|
|
73
|
+
findResumable(taskDescription: string): Promise<ExecutorCheckpoint | null>;
|
|
74
|
+
}
|
|
75
|
+
export declare function getCheckpointManager(projectRoot?: string): CheckpointManager;
|
|
76
|
+
//# sourceMappingURL=checkpoint-manager.d.ts.map
|