profclaw 2.0.0 → 2.4.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.
Files changed (519) hide show
  1. package/.env.example +14 -2
  2. package/CHANGELOG.md +52 -0
  3. package/CONTRIBUTING.md +20 -0
  4. package/Dockerfile +39 -23
  5. package/README.md +178 -41
  6. package/config/pricing.yml +26 -2
  7. package/dist/agents/agent-summary.d.ts +44 -0
  8. package/dist/agents/agent-summary.js +176 -0
  9. package/dist/agents/auto-memory.d.ts +59 -0
  10. package/dist/agents/auto-memory.js +310 -0
  11. package/dist/agents/checkpoint-manager.d.ts +76 -0
  12. package/dist/agents/checkpoint-manager.js +156 -0
  13. package/dist/agents/circuit-breaker.d.ts +54 -0
  14. package/dist/agents/circuit-breaker.js +153 -0
  15. package/dist/agents/command-sandbox.d.ts +93 -0
  16. package/dist/agents/command-sandbox.js +235 -0
  17. package/dist/agents/context-compactor.d.ts +70 -0
  18. package/dist/agents/context-compactor.js +361 -0
  19. package/dist/agents/conversation-branch.d.ts +55 -0
  20. package/dist/agents/conversation-branch.js +115 -0
  21. package/dist/agents/error-recovery.d.ts +44 -0
  22. package/dist/agents/error-recovery.js +197 -0
  23. package/dist/agents/events.d.ts +76 -0
  24. package/dist/agents/events.js +8 -0
  25. package/dist/agents/executor-runner.d.ts +135 -0
  26. package/dist/agents/executor-runner.js +303 -0
  27. package/dist/agents/executor.d.ts +37 -1
  28. package/dist/agents/executor.js +606 -124
  29. package/dist/agents/file-snapshots.d.ts +72 -0
  30. package/dist/agents/file-snapshots.js +182 -0
  31. package/dist/agents/index.d.ts +2 -0
  32. package/dist/agents/orchestrator.d.ts +183 -0
  33. package/dist/agents/orchestrator.js +495 -0
  34. package/dist/agents/output-truncator.d.ts +59 -0
  35. package/dist/agents/output-truncator.js +128 -0
  36. package/dist/agents/permissions.d.ts +63 -0
  37. package/dist/agents/permissions.js +138 -0
  38. package/dist/agents/plan-mode.d.ts +71 -0
  39. package/dist/agents/plan-mode.js +186 -0
  40. package/dist/agents/prompt-suggestions.d.ts +33 -0
  41. package/dist/agents/prompt-suggestions.js +208 -0
  42. package/dist/agents/rate-limit-monitor.d.ts +56 -0
  43. package/dist/agents/rate-limit-monitor.js +224 -0
  44. package/dist/agents/receipt/receipt-cli.d.ts +43 -0
  45. package/dist/agents/receipt/receipt-cli.js +82 -0
  46. package/dist/agents/receipt/receipt-types.d.ts +136 -0
  47. package/dist/agents/receipt/receipt-types.js +19 -0
  48. package/dist/agents/receipt/receipt-verify.d.ts +19 -0
  49. package/dist/agents/receipt/receipt-verify.js +176 -0
  50. package/dist/agents/receipt/receipt-view.d.ts +29 -0
  51. package/dist/agents/receipt/receipt-view.js +227 -0
  52. package/dist/agents/receipt/receipt-writer.d.ts +47 -0
  53. package/dist/agents/receipt/receipt-writer.js +186 -0
  54. package/dist/agents/result-store.d.ts +43 -0
  55. package/dist/agents/result-store.js +145 -0
  56. package/dist/agents/session-diff.d.ts +49 -0
  57. package/dist/agents/session-diff.js +249 -0
  58. package/dist/agents/tool-loader.d.ts +65 -0
  59. package/dist/agents/tool-loader.js +273 -0
  60. package/dist/agents/tool-selector.d.ts +123 -0
  61. package/dist/agents/tool-selector.js +321 -0
  62. package/dist/agents/transcript.d.ts +96 -0
  63. package/dist/agents/transcript.js +267 -0
  64. package/dist/agents/verified-run-git.d.ts +49 -0
  65. package/dist/agents/verified-run-git.js +82 -0
  66. package/dist/agents/verified-run.d.ts +149 -0
  67. package/dist/agents/verified-run.js +402 -0
  68. package/dist/agents/verifier.d.ts +64 -0
  69. package/dist/agents/verifier.js +186 -0
  70. package/dist/agents/worktree-manager.d.ts +80 -0
  71. package/dist/agents/worktree-manager.js +203 -0
  72. package/dist/agents/worktree-tools.d.ts +47 -0
  73. package/dist/agents/worktree-tools.js +246 -0
  74. package/dist/auth/middleware.js +14 -0
  75. package/dist/chat/agentic-executor.d.ts +7 -0
  76. package/dist/chat/agentic-executor.js +263 -32
  77. package/dist/chat/conversations.d.ts +2 -0
  78. package/dist/chat/conversations.js +8 -0
  79. package/dist/chat/execution/executor.d.ts +8 -0
  80. package/dist/chat/execution/executor.js +157 -103
  81. package/dist/chat/execution/index.js +5 -1
  82. package/dist/chat/execution/sandbox.d.ts +8 -0
  83. package/dist/chat/execution/sandbox.js +25 -1
  84. package/dist/chat/execution/tool-router.js +40 -14
  85. package/dist/chat/execution/tools/canvas.d.ts +2 -2
  86. package/dist/chat/execution/tools/code-tools.d.ts +66 -0
  87. package/dist/chat/execution/tools/code-tools.js +353 -0
  88. package/dist/chat/execution/tools/complete-task.d.ts +2 -2
  89. package/dist/chat/execution/tools/cron-tool.d.ts +26 -10
  90. package/dist/chat/execution/tools/cron-tool.js +48 -3
  91. package/dist/chat/execution/tools/decompose-task.d.ts +58 -0
  92. package/dist/chat/execution/tools/decompose-task.js +166 -0
  93. package/dist/chat/execution/tools/exec.d.ts +5 -2
  94. package/dist/chat/execution/tools/exec.js +294 -155
  95. package/dist/chat/execution/tools/feed-tools.d.ts +77 -0
  96. package/dist/chat/execution/tools/feed-tools.js +142 -0
  97. package/dist/chat/execution/tools/file-ops.d.ts +1 -1
  98. package/dist/chat/execution/tools/github.d.ts +2 -2
  99. package/dist/chat/execution/tools/index.d.ts +14 -2
  100. package/dist/chat/execution/tools/index.js +86 -12
  101. package/dist/chat/execution/tools/integrations.d.ts +8 -8
  102. package/dist/chat/execution/tools/multi-patch.d.ts +53 -0
  103. package/dist/chat/execution/tools/multi-patch.js +373 -0
  104. package/dist/chat/execution/tools/openai-image-gen.d.ts +2 -2
  105. package/dist/chat/execution/tools/plan-tools.d.ts +80 -0
  106. package/dist/chat/execution/tools/plan-tools.js +134 -0
  107. package/dist/chat/execution/tools/profclaw-ops.d.ts +6 -6
  108. package/dist/chat/execution/tools/repl-tool.d.ts +46 -0
  109. package/dist/chat/execution/tools/repl-tool.js +207 -0
  110. package/dist/chat/execution/tools/sessions-send.d.ts +2 -2
  111. package/dist/chat/execution/tools/slack-actions.d.ts +2 -2
  112. package/dist/chat/execution/tools/system.d.ts +4 -4
  113. package/dist/chat/execution/tools/todo-tool.d.ts +72 -0
  114. package/dist/chat/execution/tools/todo-tool.js +152 -0
  115. package/dist/chat/execution/tools/tool-search.d.ts +50 -0
  116. package/dist/chat/execution/tools/tool-search.js +155 -0
  117. package/dist/chat/execution/tools/tts-speak.d.ts +2 -2
  118. package/dist/chat/execution/types.d.ts +21 -14
  119. package/dist/chat/execution/workflows/executor.d.ts +11 -0
  120. package/dist/chat/execution/workflows/executor.js +99 -1
  121. package/dist/chat/execution/workflows/types.d.ts +35 -2
  122. package/dist/chat/format/index.d.ts +1 -0
  123. package/dist/chat/format/index.js +1 -0
  124. package/dist/chat/format/markdown-convert.d.ts +23 -0
  125. package/dist/chat/format/markdown-convert.js +149 -0
  126. package/dist/chat/index.d.ts +1 -1
  127. package/dist/chat/index.js +1 -1
  128. package/dist/chat/message-handler.js +58 -6
  129. package/dist/chat/meta-tool-handlers.d.ts +18 -0
  130. package/dist/chat/meta-tool-handlers.js +51 -0
  131. package/dist/chat/proactive/index.d.ts +62 -0
  132. package/dist/chat/proactive/index.js +147 -0
  133. package/dist/chat/prompt-adapter.js +2 -0
  134. package/dist/chat/providers/irc/index.d.ts +2 -2
  135. package/dist/chat/providers/telegram/index.d.ts +2 -0
  136. package/dist/chat/providers/telegram/index.js +21 -2
  137. package/dist/chat/system-prompts.d.ts +3 -3
  138. package/dist/chat/system-prompts.js +121 -61
  139. package/dist/chat/tool-handler.d.ts +2 -0
  140. package/dist/chat/tool-handler.js +47 -3
  141. package/dist/chat/tools.d.ts +6 -6
  142. package/dist/cli/commands/auth.js +64 -1
  143. package/dist/cli/commands/chat.js +1327 -138
  144. package/dist/cli/commands/doctor.js +222 -16
  145. package/dist/cli/commands/history.d.ts +3 -0
  146. package/dist/cli/commands/history.js +138 -0
  147. package/dist/cli/commands/import.d.ts +44 -0
  148. package/dist/cli/commands/import.js +526 -0
  149. package/dist/cli/commands/init.d.ts +13 -0
  150. package/dist/cli/commands/init.js +381 -0
  151. package/dist/cli/commands/onboard.js +210 -30
  152. package/dist/cli/commands/plan.d.ts +13 -0
  153. package/dist/cli/commands/plan.js +184 -0
  154. package/dist/cli/commands/receipt.d.ts +7 -0
  155. package/dist/cli/commands/receipt.js +90 -0
  156. package/dist/cli/commands/run.d.ts +28 -0
  157. package/dist/cli/commands/run.js +204 -0
  158. package/dist/cli/commands/serve.d.ts +7 -0
  159. package/dist/cli/commands/serve.js +77 -18
  160. package/dist/cli/commands/setup.js +84 -3
  161. package/dist/cli/commands/status.js +54 -0
  162. package/dist/cli/commands/tools.js +13 -13
  163. package/dist/cli/commands/tui.js +26 -1
  164. package/dist/cli/index.js +23 -0
  165. package/dist/cli/ink/App.d.ts +13 -0
  166. package/dist/cli/ink/App.js +6 -0
  167. package/dist/cli/ink/ChatApp.d.ts +60 -0
  168. package/dist/cli/ink/ChatApp.js +325 -0
  169. package/dist/cli/ink/DashboardApp.d.ts +3 -0
  170. package/dist/cli/ink/DashboardApp.js +143 -0
  171. package/dist/cli/ink/components/AgentStatus.d.ts +17 -0
  172. package/dist/cli/ink/components/AgentStatus.js +33 -0
  173. package/dist/cli/ink/components/ChannelList.d.ts +17 -0
  174. package/dist/cli/ink/components/ChannelList.js +33 -0
  175. package/dist/cli/ink/components/ConnectionStatus.d.ts +19 -0
  176. package/dist/cli/ink/components/ConnectionStatus.js +50 -0
  177. package/dist/cli/ink/components/CostBar.d.ts +19 -0
  178. package/dist/cli/ink/components/CostBar.js +35 -0
  179. package/dist/cli/ink/components/HookStatus.d.ts +15 -0
  180. package/dist/cli/ink/components/HookStatus.js +7 -0
  181. package/dist/cli/ink/components/PermissionPrompt.d.ts +21 -0
  182. package/dist/cli/ink/components/PermissionPrompt.js +51 -0
  183. package/dist/cli/ink/components/PlanView.d.ts +23 -0
  184. package/dist/cli/ink/components/PlanView.js +26 -0
  185. package/dist/cli/ink/components/ProviderList.d.ts +16 -0
  186. package/dist/cli/ink/components/ProviderList.js +16 -0
  187. package/dist/cli/ink/components/SessionHeader.d.ts +15 -0
  188. package/dist/cli/ink/components/SessionHeader.js +15 -0
  189. package/dist/cli/ink/components/StreamingMessage.d.ts +20 -0
  190. package/dist/cli/ink/components/StreamingMessage.js +27 -0
  191. package/dist/cli/ink/components/SuggestionBar.d.ts +15 -0
  192. package/dist/cli/ink/components/SuggestionBar.js +28 -0
  193. package/dist/cli/ink/components/SystemHealth.d.ts +20 -0
  194. package/dist/cli/ink/components/SystemHealth.js +39 -0
  195. package/dist/cli/ink/components/TaskList.d.ts +17 -0
  196. package/dist/cli/ink/components/TaskList.js +59 -0
  197. package/dist/cli/ink/components/ToolCall.d.ts +17 -0
  198. package/dist/cli/ink/components/ToolCall.js +43 -0
  199. package/dist/cli/ink/index.d.ts +23 -0
  200. package/dist/cli/ink/index.js +15 -0
  201. package/dist/cli/ink/keybindings.d.ts +35 -0
  202. package/dist/cli/ink/keybindings.js +105 -0
  203. package/dist/cli/ink/markdown-renderer.d.ts +47 -0
  204. package/dist/cli/ink/markdown-renderer.js +380 -0
  205. package/dist/cli/ink/output-styles.d.ts +39 -0
  206. package/dist/cli/ink/output-styles.js +119 -0
  207. package/dist/cli/interactive/auto-serve.d.ts +38 -0
  208. package/dist/cli/interactive/auto-serve.js +209 -0
  209. package/dist/cli/interactive/index.d.ts +25 -0
  210. package/dist/cli/interactive/index.js +23 -0
  211. package/dist/cli/interactive/picker.d.ts +28 -0
  212. package/dist/cli/interactive/picker.js +153 -0
  213. package/dist/cli/interactive/renderer.d.ts +26 -0
  214. package/dist/cli/interactive/renderer.js +555 -0
  215. package/dist/cli/interactive/repl.d.ts +14 -0
  216. package/dist/cli/interactive/repl.js +1516 -0
  217. package/dist/cli/interactive/stream-client.d.ts +59 -0
  218. package/dist/cli/interactive/stream-client.js +506 -0
  219. package/dist/cli/interactive/types.d.ts +121 -0
  220. package/dist/cli/interactive/types.js +10 -0
  221. package/dist/cli/utils/api.d.ts +9 -0
  222. package/dist/cli/utils/api.js +58 -2
  223. package/dist/costs/token-tracker.d.ts +10 -1
  224. package/dist/costs/token-tracker.js +37 -5
  225. package/dist/cron/natural-language.d.ts +54 -0
  226. package/dist/cron/natural-language.js +569 -0
  227. package/dist/cron/scheduler.d.ts +34 -4
  228. package/dist/cron/scheduler.js +141 -9
  229. package/dist/cron/templates.d.ts +1 -1
  230. package/dist/cron/templates.js +219 -0
  231. package/dist/feeds/feed-engine.d.ts +149 -0
  232. package/dist/feeds/feed-engine.js +600 -0
  233. package/dist/feeds/index.d.ts +9 -0
  234. package/dist/feeds/index.js +8 -0
  235. package/dist/gateway/router.js +6 -1
  236. package/dist/hooks/built-in/audit-log.d.ts +11 -0
  237. package/dist/hooks/built-in/audit-log.js +84 -0
  238. package/dist/hooks/built-in/cost-warning.d.ts +10 -0
  239. package/dist/hooks/built-in/cost-warning.js +59 -0
  240. package/dist/hooks/built-in/dangerous-tool.d.ts +32 -0
  241. package/dist/hooks/built-in/dangerous-tool.js +80 -0
  242. package/dist/hooks/built-in/index.d.ts +14 -0
  243. package/dist/hooks/built-in/index.js +20 -0
  244. package/dist/hooks/index.d.ts +3 -0
  245. package/dist/hooks/index.js +6 -0
  246. package/dist/hooks/loader.d.ts +17 -0
  247. package/dist/hooks/loader.js +142 -0
  248. package/dist/hooks/registry.d.ts +62 -0
  249. package/dist/hooks/registry.js +127 -0
  250. package/dist/integrations/web-search.js +6 -3
  251. package/dist/memory/index.d.ts +1 -0
  252. package/dist/memory/index.js +2 -0
  253. package/dist/memory/memory-service.js +14 -13
  254. package/dist/memory/observational.d.ts +62 -0
  255. package/dist/memory/observational.js +396 -0
  256. package/dist/middleware/content-filter.d.ts +22 -0
  257. package/dist/middleware/content-filter.js +69 -0
  258. package/dist/middleware/request-validator.d.ts +159 -0
  259. package/dist/middleware/request-validator.js +93 -0
  260. package/dist/plugins/sdk.d.ts +22 -0
  261. package/dist/plugins/sdk.js +17 -1
  262. package/dist/projects/types.d.ts +10 -10
  263. package/dist/providers/ai-sdk.d.ts +11 -0
  264. package/dist/providers/ai-sdk.js +111 -56
  265. package/dist/providers/core/models.js +114 -6
  266. package/dist/providers/core/types.d.ts +7 -0
  267. package/dist/providers/index.d.ts +1 -0
  268. package/dist/providers/index.js +1 -0
  269. package/dist/providers/prompt-cache.d.ts +68 -0
  270. package/dist/providers/prompt-cache.js +165 -0
  271. package/dist/providers/smart-router.d.ts +118 -0
  272. package/dist/providers/smart-router.js +693 -0
  273. package/dist/providers/types.d.ts +16 -16
  274. package/dist/routes/agents.js +50 -0
  275. package/dist/routes/auth.js +8 -1
  276. package/dist/routes/chat.js +280 -18
  277. package/dist/routes/costs.js +32 -0
  278. package/dist/routes/cron.js +80 -5
  279. package/dist/routes/feeds.d.ts +10 -0
  280. package/dist/routes/feeds.js +168 -0
  281. package/dist/routes/mcp.js +21 -0
  282. package/dist/routes/memory.js +130 -0
  283. package/dist/routes/skills.js +129 -0
  284. package/dist/routes/teams.d.ts +9 -0
  285. package/dist/routes/teams.js +210 -0
  286. package/dist/routes/tools.js +14 -0
  287. package/dist/routes/users.js +2 -0
  288. package/dist/server/route-loader.js +3 -1
  289. package/dist/server/stream-bridge.d.ts +19 -0
  290. package/dist/server/stream-bridge.js +38 -0
  291. package/dist/server.js +313 -36
  292. package/dist/skills/marketplace.d.ts +87 -0
  293. package/dist/skills/marketplace.js +268 -0
  294. package/dist/storage/index.d.ts +14 -0
  295. package/dist/storage/index.js +64 -3
  296. package/dist/storage/schema.d.ts +4 -4
  297. package/dist/storage/schema.js +1 -1
  298. package/dist/teams/index.d.ts +110 -0
  299. package/dist/teams/index.js +365 -0
  300. package/dist/tickets/types.d.ts +39 -39
  301. package/dist/types/summary.d.ts +5 -5
  302. package/dist/utils/auto-update.d.ts +23 -0
  303. package/dist/utils/auto-update.js +157 -0
  304. package/dist/utils/offline-detect.d.ts +55 -0
  305. package/dist/utils/offline-detect.js +121 -0
  306. package/dist/utils/pid-file.d.ts +36 -0
  307. package/dist/utils/pid-file.js +125 -0
  308. package/dist/utils/prevent-sleep.d.ts +27 -0
  309. package/dist/utils/prevent-sleep.js +95 -0
  310. package/dist/utils/sanitizer.d.ts +57 -0
  311. package/dist/utils/sanitizer.js +174 -0
  312. package/docker-compose.yml +13 -137
  313. package/package.json +31 -6
  314. package/skills/deploy-cloudflare/SKILL.md +62 -0
  315. package/skills/deploy-vercel/SKILL.md +67 -0
  316. package/skills/docker-deploy/SKILL.md +158 -0
  317. package/skills/full-stack-builder/SKILL.md +92 -0
  318. package/skills/humanizer/SKILL.md +488 -0
  319. package/skills/profclaw-assistant/SKILL.md +85 -56
  320. package/ui/dist/assets/ActivityView-Da6HQ8ws.js +1 -0
  321. package/ui/dist/assets/AgentList-H58R0kX3.js +1 -0
  322. package/ui/dist/assets/AnalyticsDashboard-B28AeRsc.js +1 -0
  323. package/ui/dist/assets/AreaChart-DwLzeAQ8.js +1 -0
  324. package/ui/dist/assets/CartesianChart-piKQsTAR.js +36 -0
  325. package/ui/dist/assets/ChatView-Dbj8rxU5.js +10 -0
  326. package/ui/dist/assets/CostsDashboard-C6F5df0F.js +1 -0
  327. package/ui/dist/assets/EstimateSelect-wga0rUKX.js +1 -0
  328. package/ui/dist/assets/FeedDashboard-Ef6FEzEf.js +1 -0
  329. package/ui/dist/assets/FloatingChatbot-0yhkUeCq.js +2 -0
  330. package/ui/dist/assets/InviteCodeManagement-tUXfx4Bc.js +2 -0
  331. package/ui/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  332. package/ui/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  333. package/ui/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  334. package/ui/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  335. package/ui/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  336. package/ui/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  337. package/ui/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  338. package/ui/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  339. package/ui/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  340. package/ui/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  341. package/ui/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  342. package/ui/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  343. package/ui/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  344. package/ui/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  345. package/ui/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  346. package/ui/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  347. package/ui/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  348. package/ui/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  349. package/ui/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  350. package/ui/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  351. package/ui/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  352. package/ui/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  353. package/ui/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  354. package/ui/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  355. package/ui/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  356. package/ui/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  357. package/ui/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  358. package/ui/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  359. package/ui/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  360. package/ui/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  361. package/ui/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  362. package/ui/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  363. package/ui/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  364. package/ui/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  365. package/ui/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  366. package/ui/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  367. package/ui/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  368. package/ui/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  369. package/ui/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  370. package/ui/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  371. package/ui/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  372. package/ui/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  373. package/ui/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  374. package/ui/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  375. package/ui/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  376. package/ui/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  377. package/ui/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  378. package/ui/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  379. package/ui/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  380. package/ui/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  381. package/ui/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  382. package/ui/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  383. package/ui/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  384. package/ui/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  385. package/ui/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  386. package/ui/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  387. package/ui/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  388. package/ui/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  389. package/ui/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  390. package/ui/dist/assets/MarketplacePage-DGrLtolR.js +1 -0
  391. package/ui/dist/assets/{ProjectDetail--gPfvATB.js → ProjectDetail-BgWvA6UP.js} +2 -2
  392. package/ui/dist/assets/ProjectIcon-TDuliqwg.js +1 -0
  393. package/ui/dist/assets/ProjectList-DXgM4187.js +1 -0
  394. package/ui/dist/assets/{Settings-1kaf7VHE.js → Settings-xA8Zhi3p.js} +3 -3
  395. package/ui/dist/assets/StatusIndicator-B8vfFAxg.js +1 -0
  396. package/ui/dist/assets/{SummaryDetail-DV3AmONk.js → SummaryDetail-eedRfTtF.js} +2 -2
  397. package/ui/dist/assets/SummaryList-CLNX2P84.js +1 -0
  398. package/ui/dist/assets/TaskDetail-BtWclNiR.js +1 -0
  399. package/ui/dist/assets/TaskList-JjODAgSc.js +1 -0
  400. package/ui/dist/assets/TeamsPage-CBK5iAyx.js +1 -0
  401. package/ui/dist/assets/TicketBoard-C9aJNNYp.js +1 -0
  402. package/ui/dist/assets/TicketDetail-CV5JmL31.js +1 -0
  403. package/ui/dist/assets/TicketList-68V4lzUz.js +1 -0
  404. package/ui/dist/assets/UserManagement-DKTb6UpE.js +2 -0
  405. package/ui/dist/assets/ViewSwitcher-BvdQht2Y.js +1 -0
  406. package/ui/dist/assets/alert-dialog-O6qBOv_f.js +1 -0
  407. package/ui/dist/assets/{archive-BsLa7brF.js → archive-CX7UvZpf.js} +1 -1
  408. package/ui/dist/assets/badge-BbfnwDJP.js +1 -0
  409. package/ui/dist/assets/{bug-CmZI7jqM.js → bug-3WX0394-.js} +1 -1
  410. package/ui/dist/assets/{calendar-Bf0t2B82.js → calendar-buq77TaS.js} +1 -1
  411. package/ui/dist/assets/{chevron-up-CoUsOvZj.js → chevron-up-4ymsBJRo.js} +1 -1
  412. package/ui/dist/assets/{circle-x-Dgw11LgT.js → circle-x-ByXtwR6Y.js} +1 -1
  413. package/ui/dist/assets/constants-CVdDh7p0.js +1 -0
  414. package/ui/dist/assets/{cpu-DiPMQICV.js → cpu-CiuoCeDY.js} +1 -1
  415. package/ui/dist/assets/{database-BwTfupDi.js → database-BWXSBg5a.js} +1 -1
  416. package/ui/dist/assets/dialog-lDg4NvMV.js +1 -0
  417. package/ui/dist/assets/dollar-sign-Dmijd6DP.js +1 -0
  418. package/ui/dist/assets/{ellipsis-UJx4Xnf6.js → ellipsis-vT-5SVIp.js} +1 -1
  419. package/ui/dist/assets/{ellipsis-vertical-DoULYEKn.js → ellipsis-vertical-B4tAX_bL.js} +1 -1
  420. package/ui/dist/assets/feature-markdown-DBo5Q7uq.js +289 -0
  421. package/ui/dist/assets/{file-code-B2UrJLwi.js → file-code-ChOWdKXf.js} +1 -1
  422. package/ui/dist/assets/{folder-open-BJi577JH.js → folder-open-CkOUbIiP.js} +1 -1
  423. package/ui/dist/assets/{funnel-PkaD_HSR.js → funnel-uZkoSPP-.js} +1 -1
  424. package/ui/dist/assets/{git-branch-C_K30am0.js → git-branch-CwvUxj7C.js} +1 -1
  425. package/ui/dist/assets/{git-commit-horizontal-IT6ecxWQ.js → git-commit-horizontal-lxPzCvhD.js} +1 -1
  426. package/ui/dist/assets/{globe-f-jjCa_g.js → globe-D_WpJdsj.js} +1 -1
  427. package/ui/dist/assets/{hash-DNEv8Elo.js → hash-CA0hJ7vh.js} +1 -1
  428. package/ui/dist/assets/{history-BQSBo_1Q.js → history-CEWMLELs.js} +1 -1
  429. package/ui/dist/assets/inbox-ehtOptTV.js +1 -0
  430. package/ui/dist/assets/{index-nS3EErDg.js → index-C1rhbml4.js} +3 -3
  431. package/ui/dist/assets/index-CR8gfCHv.js +1 -0
  432. package/ui/dist/assets/index-DVXMpWai.js +1 -0
  433. package/ui/dist/assets/index-DaDJMM2v.js +1 -0
  434. package/ui/dist/assets/index-Djdq_0xu.js +1 -0
  435. package/ui/dist/assets/index-M46Gcb8K.css +1 -0
  436. package/ui/dist/assets/index-sEBN7w8J.js +109 -0
  437. package/ui/dist/assets/layers-C6Mhf8Nk.js +1 -0
  438. package/ui/dist/assets/{layout-dashboard-CcKt1hXw.js → layout-dashboard-BRUM0kpT.js} +1 -1
  439. package/ui/dist/assets/{lightbulb-Jhp7FvbU.js → lightbulb-CN2q1O5l.js} +1 -1
  440. package/ui/dist/assets/{link-2-DdO7ostF.js → link-2-CC4E28yJ.js} +1 -1
  441. package/ui/dist/assets/markdown-renderer-C6ENbB0u.js +10 -0
  442. package/ui/dist/assets/markdown-renderer-CfVKi3_s.css +1 -0
  443. package/ui/dist/assets/{message-square-CBgH65X7.js → message-square-Bbb241am.js} +1 -1
  444. package/ui/dist/assets/package-CwT3IzFx.js +1 -0
  445. package/ui/dist/assets/{pencil-CYXCEPQh.js → pencil-CDmiHzoj.js} +1 -1
  446. package/ui/dist/assets/{play-d1ONaH0-.js → play-tjy5jMQX.js} +1 -1
  447. package/ui/dist/assets/popover-CFHZf3pE.js +1 -0
  448. package/ui/dist/assets/progress-BboUHuLf.js +1 -0
  449. package/ui/dist/assets/{rocket-DhvUetsk.js → rocket--8ZHgdXJ.js} +1 -1
  450. package/ui/dist/assets/select-n108rXny.js +1 -0
  451. package/ui/dist/assets/{send-P0r5D7td.js → send-Cu7MR2Qh.js} +1 -1
  452. package/ui/dist/assets/server-DmodxZp-.js +1 -0
  453. package/ui/dist/assets/{settings-2-ocj5uHGx.js → settings-2-CkRNqkxj.js} +1 -1
  454. package/ui/dist/assets/sheet-7aUJkyzU.js +1 -0
  455. package/ui/dist/assets/{shield-check-DfVdE34l.js → shield-check-ViI3nMKE.js} +1 -1
  456. package/ui/dist/assets/{shield-off-8l0J6R-8.js → shield-off-DN3tagkn.js} +1 -1
  457. package/ui/dist/assets/skeleton-C0E1Nfro.js +1 -0
  458. package/ui/dist/assets/{smartphone-77_g3SQn.js → smartphone-5FghiXpA.js} +1 -1
  459. package/ui/dist/assets/{square-Ckzsr3Rn.js → square-DiNSx8K7.js} +1 -1
  460. package/ui/dist/assets/star-DhdFVidS.js +1 -0
  461. package/ui/dist/assets/switch-CIgVbZqQ.js +1 -0
  462. package/ui/dist/assets/table-BC56FVMV.js +1 -0
  463. package/ui/dist/assets/{tag-C35mgoEv.js → tag-CH_vQliw.js} +1 -1
  464. package/ui/dist/assets/textarea-CxDiKFXZ.js +1 -0
  465. package/ui/dist/assets/{timer-DHJBS2w1.js → timer-CdGVTb60.js} +1 -1
  466. package/ui/dist/assets/tooltip-BuW9A5UO.js +1 -0
  467. package/ui/dist/assets/{trash-2-keO5tKPE.js → trash-2-CucZJL0N.js} +1 -1
  468. package/ui/dist/assets/trending-down-BCezC1z2.js +1 -0
  469. package/ui/dist/assets/{trending-up-BBv8KbrY.js → trending-up-C5OYX2k2.js} +1 -1
  470. package/ui/dist/assets/vendor-query-C0p7b53x.js +4 -0
  471. package/ui/dist/assets/vendor-react-Mc5_kfYG.js +12 -0
  472. package/ui/dist/assets/vendor-ui-CXPAUBFv.js +51 -0
  473. package/ui/dist/assets/{wand-sparkles-BusQ52ZK.js → wand-sparkles-BaH6pJnc.js} +1 -1
  474. package/ui/dist/assets/{wrench-02YaOSiK.js → wrench-CjxjP6ok.js} +1 -1
  475. package/ui/dist/index.html +5 -2
  476. package/ui/dist/assets/ActivityView-BeshZXmE.js +0 -1
  477. package/ui/dist/assets/AgentList-QVHeldPi.js +0 -1
  478. package/ui/dist/assets/AnalyticsDashboard-C9R97dXE.js +0 -1
  479. package/ui/dist/assets/AreaChart-B73gaiVQ.js +0 -1
  480. package/ui/dist/assets/CartesianChart-CXYL2R-A.js +0 -36
  481. package/ui/dist/assets/ChatView-qjZErlrp.js +0 -10
  482. package/ui/dist/assets/CostsDashboard-O4DCLy1i.js +0 -1
  483. package/ui/dist/assets/EstimateSelect-1hQf4Osk.js +0 -1
  484. package/ui/dist/assets/FloatingChatbot-BZBzrJxd.js +0 -2
  485. package/ui/dist/assets/InviteCodeManagement-LEoGqYeA.js +0 -2
  486. package/ui/dist/assets/ProjectIcon-Chd_ofsw.js +0 -1
  487. package/ui/dist/assets/ProjectList-BvUfVB6c.js +0 -4
  488. package/ui/dist/assets/StatusIndicator-pRfkNcdV.js +0 -1
  489. package/ui/dist/assets/SummaryList-B6kXiTxL.js +0 -1
  490. package/ui/dist/assets/TaskDetail-CV6CzbOS.js +0 -1
  491. package/ui/dist/assets/TaskList-DL7brQKd.js +0 -1
  492. package/ui/dist/assets/TicketBoard-CrkkFj7C.js +0 -1
  493. package/ui/dist/assets/TicketDetail-hnnYclpD.js +0 -1
  494. package/ui/dist/assets/TicketList-CsDAyQCL.js +0 -1
  495. package/ui/dist/assets/UserManagement-BGFQyTSr.js +0 -2
  496. package/ui/dist/assets/ViewSwitcher-CnL0OqA8.js +0 -1
  497. package/ui/dist/assets/alert-dialog-SKM6Gjz4.js +0 -7
  498. package/ui/dist/assets/badge-CVHH1a-v.js +0 -1
  499. package/ui/dist/assets/brain-6o_RHVpe.js +0 -1
  500. package/ui/dist/assets/constants-Q5Zivl-a.js +0 -1
  501. package/ui/dist/assets/dialog-BUqN9Psj.js +0 -1
  502. package/ui/dist/assets/index-BUmnwPQr.js +0 -1
  503. package/ui/dist/assets/index-BfF5G4Cw.js +0 -1
  504. package/ui/dist/assets/index-C8N375c2.js +0 -1
  505. package/ui/dist/assets/index-CuxnqVVz.css +0 -1
  506. package/ui/dist/assets/index-CzMM3QOk.js +0 -1
  507. package/ui/dist/assets/index-lJlNPFVJ.js +0 -67
  508. package/ui/dist/assets/layers-jFqVrWMD.js +0 -1
  509. package/ui/dist/assets/markdown-renderer-n1ToC4XQ.js +0 -36
  510. package/ui/dist/assets/popover-CrmZgoWu.js +0 -1
  511. package/ui/dist/assets/progress-uv4SPkL5.js +0 -1
  512. package/ui/dist/assets/select-CeQ8AHGy.js +0 -1
  513. package/ui/dist/assets/server-CVHTZB72.js +0 -1
  514. package/ui/dist/assets/sheet-DuQExSho.js +0 -1
  515. package/ui/dist/assets/skeleton-TFiFJ3nB.js +0 -1
  516. package/ui/dist/assets/switch-CAePkd6k.js +0 -1
  517. package/ui/dist/assets/table-ZjAZ7hkt.js +0 -1
  518. package/ui/dist/assets/textarea-DsVPnSgR.js +0 -1
  519. package/ui/dist/assets/tooltip-BYmQ331W.js +0 -1
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Tool Selector
3
+ *
4
+ * Sends only the tool schemas that are likely needed on a given turn instead
5
+ * of every registered tool. Selection is a cheap, deterministic heuristic (no
6
+ * LLM call): a small core set, plus groups whose keywords appear in the user
7
+ * message or whose tools were used recently. The model can request more groups
8
+ * with the `load_tools` meta-tool.
9
+ *
10
+ * Cache stability: within a session the set of loaded groups only grows, and
11
+ * the output is always sorted by tool name, so the tool prefix of the prompt
12
+ * stays byte-identical between turns unless a new group is genuinely needed.
13
+ *
14
+ * Env:
15
+ * PROFCLAW_TOOL_SELECTION off/0/false/no disables (default on)
16
+ * PROFCLAW_TOOL_SELECTION_MIN_TOOLS skip selection when the tool count is at
17
+ * or below this number (default 12)
18
+ * PROFCLAW_TOOL_SELECTION_KEEP_UNGROUPED
19
+ * keep tools that match no group, such as
20
+ * MCP or plugin tools (default true)
21
+ */
22
+ import { z } from 'zod';
23
+ import { zodToJsonSchema } from 'zod-to-json-schema';
24
+ export const LOAD_TOOLS_NAME = 'load_tools';
25
+ export const FETCH_RESULT_NAME = 'fetch_result';
26
+ /** Tools that are always sent. Keep this small. */
27
+ export const CORE_TOOL_NAMES = [
28
+ 'read_file',
29
+ 'write_file',
30
+ 'edit_file',
31
+ 'search_files',
32
+ 'grep',
33
+ 'exec',
34
+ 'complete_task',
35
+ ];
36
+ // Groups
37
+ export const TOOL_GROUPS = [
38
+ {
39
+ name: 'git',
40
+ description: 'git status/diff/log/branch/stash/remote/commit, PRs',
41
+ tools: ['git_*', 'create_pr', 'github_pr'],
42
+ keywords: /\b(git|commit|branch|stash|rebase|merge|diff|pull request|pr|github|checkout|push)\b/,
43
+ },
44
+ {
45
+ name: 'dev',
46
+ description: 'run tests, lint, build, typecheck, format, REPL, project info',
47
+ tools: ['test_run', 'lint', 'build', 'format', 'typecheck', 'project_info', 'repl_execute'],
48
+ keywords: /\b(test|tests|lint|build|compile|typecheck|type check|tsc|format|prettier|eslint|repl|ci)\b/,
49
+ },
50
+ {
51
+ name: 'files_extra',
52
+ description: 'directory tree, multi-file patch, patch apply, image analysis',
53
+ tools: ['directory_tree', 'multi_patch', 'patch_apply', 'image_analyze'],
54
+ keywords: /\b(tree|directory|folder|patch|refactor|rename|image|screenshot|picture|photo)\b/,
55
+ },
56
+ {
57
+ name: 'web',
58
+ description: 'web search, fetch a URL, understand a link',
59
+ tools: ['web_fetch', 'web_search', 'link_understand'],
60
+ keywords: /(https?:\/\/|\b(web|website|url|link|search online|google|internet|news|latest|docs?|documentation|browse)\b)/,
61
+ },
62
+ {
63
+ name: 'browser',
64
+ description: 'browser automation: navigate, click, fill, screenshot',
65
+ tools: ['browser_*'],
66
+ keywords: /\b(browser|playwright|click|navigate|scrape|webpage|web page|page)\b/,
67
+ },
68
+ {
69
+ name: 'memory',
70
+ description: 'search and read long-term memory',
71
+ tools: ['memory_*'],
72
+ keywords: /\b(memory|memories|remember|recall|earlier|previous(ly)?|last time|we discussed)\b/,
73
+ },
74
+ {
75
+ name: 'tasks',
76
+ description: 'tickets, projects, todos, task decomposition',
77
+ tools: [
78
+ 'create_ticket', 'update_ticket', 'get_ticket', 'list_tickets',
79
+ 'create_project', 'list_projects', 'todo_read', 'todo_write', 'decompose_task',
80
+ ],
81
+ keywords: /\b(ticket|tickets|project|projects|todo|todos|task list|backlog|issue|decompose|plan)\b/,
82
+ },
83
+ {
84
+ name: 'sessions',
85
+ description: 'sessions, sub-agents, agent messaging',
86
+ tools: [
87
+ 'sessions_*', 'list_sessions', 'spawn_session', 'send_message', 'receive_messages',
88
+ 'agents_list', 'session_status', 'subagent_orchestrate',
89
+ ],
90
+ keywords: /\b(session|sessions|agent|agents|sub-?agent|spawn|delegate|orchestrate|parallel)\b/,
91
+ },
92
+ {
93
+ name: 'cron',
94
+ description: 'scheduled jobs: create, list, pause, trigger, delete',
95
+ tools: ['cron_*'],
96
+ keywords: /\b(cron|schedule|scheduled|recurring|every (day|hour|week|minute)|daily|hourly|timer)\b/,
97
+ },
98
+ {
99
+ name: 'feeds',
100
+ description: 'RSS/feed subscriptions and digests',
101
+ tools: ['feed_*'],
102
+ keywords: /\b(feed|feeds|rss|atom|digest|subscribe|newsletter)\b/,
103
+ },
104
+ {
105
+ name: 'messaging',
106
+ description: 'Slack, Discord, Telegram, notifications, clipboard',
107
+ tools: ['slack_actions', 'discord_actions', 'telegram_actions', 'notify', 'clipboard_*'],
108
+ keywords: /\b(slack|discord|telegram|notify|notification|clipboard|copy to|paste)\b/,
109
+ },
110
+ {
111
+ name: 'media',
112
+ description: 'image generation, text to speech, canvas',
113
+ tools: ['openai_image_gen', 'tts_speak', 'canvas_*'],
114
+ keywords: /\b(generate an? image|image generation|draw|illustrat\w*|tts|speak|speech|voice|audio|canvas|render)\b/,
115
+ },
116
+ {
117
+ name: 'system',
118
+ description: 'system info, env vars, processes, which, path info, db maintenance',
119
+ tools: ['system_info', 'env', 'env_vars', 'process_list', 'path_info', 'which', 'db_maintenance'],
120
+ keywords: /\b(system|env|environment|process|processes|cpu|memory usage|disk|port|installed|which|path|maintenance|vacuum)\b/,
121
+ },
122
+ ];
123
+ // Config
124
+ function isOff(value) {
125
+ return ['off', '0', 'false', 'no'].includes((value ?? '').toLowerCase());
126
+ }
127
+ export function isToolSelectionEnabled() {
128
+ return !isOff(process.env.PROFCLAW_TOOL_SELECTION);
129
+ }
130
+ function minToolsThreshold() {
131
+ const parsed = Number.parseInt(process.env.PROFCLAW_TOOL_SELECTION_MIN_TOOLS ?? '', 10);
132
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : 12;
133
+ }
134
+ function keepUngrouped() {
135
+ return !isOff(process.env.PROFCLAW_TOOL_SELECTION_KEEP_UNGROUPED);
136
+ }
137
+ // Matching helpers
138
+ function matchesPattern(name, pattern) {
139
+ return pattern.endsWith('*') ? name.startsWith(pattern.slice(0, -1)) : name === pattern;
140
+ }
141
+ /** Group name a tool belongs to, or undefined for core/ungrouped tools. */
142
+ export function groupOfTool(name) {
143
+ for (const group of TOOL_GROUPS) {
144
+ if (group.tools.some((p) => matchesPattern(name, p)))
145
+ return group.name;
146
+ }
147
+ return undefined;
148
+ }
149
+ function isCore(name) {
150
+ return CORE_TOOL_NAMES.includes(name) || name === LOAD_TOOLS_NAME || name === FETCH_RESULT_NAME;
151
+ }
152
+ // Session state
153
+ export class ToolSelectorSession {
154
+ /** Groups loaded so far. Only ever grows, which keeps the prefix stable. */
155
+ loaded = new Set();
156
+ getLoadedGroups() {
157
+ return Array.from(this.loaded).sort();
158
+ }
159
+ /** Mark groups loaded. Returns the names that were valid. */
160
+ loadGroups(names) {
161
+ const valid = [];
162
+ for (const raw of names) {
163
+ const name = raw.trim().toLowerCase();
164
+ if (TOOL_GROUPS.some((g) => g.name === name)) {
165
+ this.loaded.add(name);
166
+ valid.push(name);
167
+ }
168
+ }
169
+ return valid;
170
+ }
171
+ /** Keep the group of a tool that was just executed loaded. */
172
+ noteToolUse(toolName) {
173
+ const group = groupOfTool(toolName);
174
+ if (group)
175
+ this.loaded.add(group);
176
+ }
177
+ /** Add groups whose keywords match the user message. */
178
+ noteMessage(message) {
179
+ const text = message.toLowerCase();
180
+ const hit = [];
181
+ for (const group of TOOL_GROUPS) {
182
+ if (group.keywords.test(text)) {
183
+ this.loaded.add(group.name);
184
+ hit.push(group.name);
185
+ }
186
+ }
187
+ return hit;
188
+ }
189
+ /**
190
+ * Select tools for this turn. Output is sorted by name and, apart from
191
+ * newly loaded groups, identical across calls in the same session.
192
+ */
193
+ select(all, message = '') {
194
+ if (!isToolSelectionEnabled() || all.length <= minToolsThreshold()) {
195
+ return [...all].sort(byName);
196
+ }
197
+ if (message)
198
+ this.noteMessage(message);
199
+ const keepOther = keepUngrouped();
200
+ const picked = all.filter((tool) => {
201
+ if (isCore(tool.name))
202
+ return true;
203
+ const group = groupOfTool(tool.name);
204
+ if (group === undefined)
205
+ return keepOther;
206
+ return this.loaded.has(group);
207
+ });
208
+ return picked.sort(byName);
209
+ }
210
+ }
211
+ function byName(a, b) {
212
+ return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
213
+ }
214
+ // Session registry (keyed by conversation)
215
+ const MAX_SESSIONS = 500;
216
+ const sessions = new Map();
217
+ export function getToolSelectorSession(sessionId) {
218
+ let session = sessions.get(sessionId);
219
+ if (!session) {
220
+ if (sessions.size >= MAX_SESSIONS) {
221
+ const oldest = sessions.keys().next().value;
222
+ if (oldest !== undefined)
223
+ sessions.delete(oldest);
224
+ }
225
+ session = new ToolSelectorSession();
226
+ sessions.set(sessionId, session);
227
+ }
228
+ return session;
229
+ }
230
+ export function resetToolSelectorSessions() {
231
+ sessions.clear();
232
+ }
233
+ // Meta tools
234
+ const LoadToolsSchema = z.object({
235
+ groups: z.array(z.string()).describe('Group names to load'),
236
+ invoke: z
237
+ .object({ tool: z.string(), args: z.record(z.string(), z.unknown()).optional() })
238
+ .optional()
239
+ .describe('Optionally call one of the loaded tools right now'),
240
+ });
241
+ const FetchResultSchema = z.object({
242
+ result_id: z.string(),
243
+ offset: z.number().int().min(0).optional(),
244
+ length: z.number().int().min(1).optional(),
245
+ });
246
+ export function parseLoadToolsArgs(args) {
247
+ const parsed = LoadToolsSchema.safeParse(args);
248
+ return parsed.success ? parsed.data : null;
249
+ }
250
+ export function parseFetchResultArgs(args) {
251
+ const parsed = FetchResultSchema.safeParse(args);
252
+ return parsed.success ? parsed.data : null;
253
+ }
254
+ /** Stable, compact meta-tool definitions. Description text must not vary. */
255
+ export function getMetaTools(includeFetchResult) {
256
+ const groupList = TOOL_GROUPS.map((g) => `${g.name} (${g.description})`).join('; ');
257
+ const tools = [
258
+ {
259
+ name: LOAD_TOOLS_NAME,
260
+ description: `Load more tool groups when you need a tool you do not have. Groups: ${groupList}. ` +
261
+ 'Returns the tool schemas; they are available from the next turn, or use invoke to call one now.',
262
+ parameters: LoadToolsSchema,
263
+ },
264
+ ];
265
+ if (includeFetchResult) {
266
+ tools.push({
267
+ name: FETCH_RESULT_NAME,
268
+ description: 'Read a char range of a truncated tool result by its result_id.',
269
+ parameters: FetchResultSchema,
270
+ });
271
+ }
272
+ return tools;
273
+ }
274
+ // Token estimate
275
+ /** Rough tokens for one tool schema as sent to the provider (about 4 chars per token). */
276
+ export function estimateToolTokens(tool) {
277
+ let schema = '{}';
278
+ try {
279
+ schema = JSON.stringify(zodToJsonSchema(tool.parameters, { $refStrategy: 'none' }));
280
+ }
281
+ catch {
282
+ // fall through with an empty schema
283
+ }
284
+ return Math.ceil((tool.name.length + tool.description.length + schema.length) / 4);
285
+ }
286
+ export function estimateToolsTokens(tools) {
287
+ return tools.reduce((sum, t) => sum + estimateToolTokens(t), 0);
288
+ }
289
+ /** Compact JSON schema for a tool, used in load_tools results. */
290
+ export function describeTool(tool) {
291
+ let parameters = {};
292
+ try {
293
+ parameters = zodToJsonSchema(tool.parameters, { $refStrategy: 'none' });
294
+ }
295
+ catch {
296
+ // keep empty schema
297
+ }
298
+ return { name: tool.name, description: tool.description, parameters };
299
+ }
300
+ /** Tools belonging to a named group, sorted by name. */
301
+ export function toolsInGroup(all, groupName) {
302
+ const group = TOOL_GROUPS.find((g) => g.name === groupName);
303
+ if (!group)
304
+ return [];
305
+ return all.filter((t) => group.tools.some((p) => matchesPattern(t.name, p))).sort(byName);
306
+ }
307
+ // Request-level entry point
308
+ /**
309
+ * Select tools for one agentic request and append the meta-tools. When
310
+ * selection is disabled the input list is returned unchanged.
311
+ */
312
+ export function selectToolsForRequest(tools, sessionId, message) {
313
+ if (!isToolSelectionEnabled() || tools.length <= minToolsThreshold()) {
314
+ return [...tools];
315
+ }
316
+ const session = getToolSelectorSession(sessionId);
317
+ const selected = session.select(tools, message);
318
+ const withMeta = [...selected, ...getMetaTools(true)];
319
+ return withMeta.sort(byName);
320
+ }
321
+ //# sourceMappingURL=tool-selector.js.map
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Transcript Persistence
3
+ *
4
+ * Saves all conversations to JSONL files for searchable history and session resumption.
5
+ * Files are stored at .profclaw/transcripts/{sessionId}.jsonl
6
+ * Index is stored at .profclaw/transcripts/index.json
7
+ */
8
+ import * as os from 'os';
9
+ export interface TranscriptEntry {
10
+ timestamp: number;
11
+ sessionId: string;
12
+ type: 'user' | 'assistant' | 'tool_call' | 'tool_result' | 'system' | 'error';
13
+ content: string;
14
+ metadata?: {
15
+ toolName?: string;
16
+ toolCallId?: string;
17
+ model?: string;
18
+ tokensUsed?: number;
19
+ duration?: number;
20
+ };
21
+ }
22
+ export interface SessionMeta {
23
+ sessionId: string;
24
+ title: string;
25
+ startedAt: number;
26
+ lastActivityAt: number;
27
+ messageCount: number;
28
+ tokensUsed: number;
29
+ model?: string;
30
+ }
31
+ export declare class TranscriptStore {
32
+ private transcriptsDir;
33
+ private sessionsIndex;
34
+ private indexDirty;
35
+ private indexTimer;
36
+ constructor(projectRoot?: string);
37
+ /**
38
+ * Append a single entry to the session's JSONL file.
39
+ */
40
+ append(entry: TranscriptEntry): void;
41
+ /**
42
+ * Read all entries for a session from its JSONL file.
43
+ */
44
+ getSession(sessionId: string): TranscriptEntry[];
45
+ /**
46
+ * List sessions sorted by lastActivityAt descending.
47
+ */
48
+ listSessions(options?: {
49
+ limit?: number;
50
+ offset?: number;
51
+ }): SessionMeta[];
52
+ /**
53
+ * Full-text search across transcript entries.
54
+ * Returns matching entries with their session ID and line number.
55
+ */
56
+ search(query: string, options?: {
57
+ sessionId?: string;
58
+ limit?: number;
59
+ }): Array<{
60
+ entry: TranscriptEntry;
61
+ sessionId: string;
62
+ lineNumber: number;
63
+ }>;
64
+ /**
65
+ * Get or create session metadata. Uses firstMessage to auto-generate a title
66
+ * if the session doesn't yet exist.
67
+ */
68
+ getOrCreateMeta(sessionId: string, firstMessage?: string): SessionMeta;
69
+ /**
70
+ * Merge partial updates into an existing session's metadata.
71
+ */
72
+ updateMeta(sessionId: string, updates: Partial<SessionMeta>): void;
73
+ /**
74
+ * Delete a session's JSONL file and remove it from the index.
75
+ */
76
+ deleteSession(sessionId: string): void;
77
+ flush(): void;
78
+ private markIndexDirty;
79
+ private sessionFilePath;
80
+ private indexFilePath;
81
+ private ensureDir;
82
+ private loadIndex;
83
+ private saveIndex;
84
+ /**
85
+ * Generate a human-readable title from the first 50 chars of a message.
86
+ * Strips newlines, trims whitespace.
87
+ */
88
+ private generateTitle;
89
+ }
90
+ /**
91
+ * Returns the process-level singleton TranscriptStore, rooted at cwd().
92
+ */
93
+ export declare function getTranscriptStore(): TranscriptStore;
94
+ export declare function _resetTranscriptStoreSingleton(): void;
95
+ export { os };
96
+ //# sourceMappingURL=transcript.d.ts.map
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Transcript Persistence
3
+ *
4
+ * Saves all conversations to JSONL files for searchable history and session resumption.
5
+ * Files are stored at .profclaw/transcripts/{sessionId}.jsonl
6
+ * Index is stored at .profclaw/transcripts/index.json
7
+ */
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import * as os from 'os';
11
+ let _instance = null;
12
+ export class TranscriptStore {
13
+ transcriptsDir;
14
+ sessionsIndex;
15
+ indexDirty = false;
16
+ indexTimer = null;
17
+ constructor(projectRoot) {
18
+ const root = projectRoot ?? process.cwd();
19
+ this.transcriptsDir = path.join(root, '.profclaw', 'transcripts');
20
+ this.sessionsIndex = new Map();
21
+ this.loadIndex();
22
+ }
23
+ /**
24
+ * Append a single entry to the session's JSONL file.
25
+ */
26
+ append(entry) {
27
+ this.ensureDir();
28
+ const filePath = this.sessionFilePath(entry.sessionId);
29
+ const line = JSON.stringify(entry) + '\n';
30
+ try {
31
+ fs.appendFileSync(filePath, line, 'utf8');
32
+ }
33
+ catch (err) {
34
+ console.error('[TranscriptStore] Failed to append entry:', err);
35
+ return;
36
+ }
37
+ // Update session metadata
38
+ const meta = this.getOrCreateMeta(entry.sessionId);
39
+ meta.lastActivityAt = entry.timestamp;
40
+ meta.messageCount += 1;
41
+ if (entry.metadata?.tokensUsed) {
42
+ meta.tokensUsed += entry.metadata.tokensUsed;
43
+ }
44
+ if (entry.metadata?.model && !meta.model) {
45
+ meta.model = entry.metadata.model;
46
+ }
47
+ this.sessionsIndex.set(entry.sessionId, meta);
48
+ this.markIndexDirty();
49
+ }
50
+ /**
51
+ * Read all entries for a session from its JSONL file.
52
+ */
53
+ getSession(sessionId) {
54
+ const filePath = this.sessionFilePath(sessionId);
55
+ if (!fs.existsSync(filePath)) {
56
+ return [];
57
+ }
58
+ try {
59
+ const raw = fs.readFileSync(filePath, 'utf8');
60
+ const entries = [];
61
+ for (const line of raw.split('\n')) {
62
+ const trimmed = line.trim();
63
+ if (!trimmed)
64
+ continue;
65
+ try {
66
+ entries.push(JSON.parse(trimmed));
67
+ }
68
+ catch {
69
+ // Skip malformed lines
70
+ }
71
+ }
72
+ return entries;
73
+ }
74
+ catch (err) {
75
+ console.error(`[TranscriptStore] Failed to read session ${sessionId}:`, err);
76
+ return [];
77
+ }
78
+ }
79
+ /**
80
+ * List sessions sorted by lastActivityAt descending.
81
+ */
82
+ listSessions(options) {
83
+ const all = Array.from(this.sessionsIndex.values()).sort((a, b) => b.lastActivityAt - a.lastActivityAt);
84
+ const offset = options?.offset ?? 0;
85
+ const limit = options?.limit ?? all.length;
86
+ return all.slice(offset, offset + limit);
87
+ }
88
+ /**
89
+ * Full-text search across transcript entries.
90
+ * Returns matching entries with their session ID and line number.
91
+ */
92
+ search(query, options) {
93
+ const results = [];
94
+ const lowerQuery = query.toLowerCase();
95
+ const limit = options?.limit ?? 50;
96
+ const sessionIds = options?.sessionId
97
+ ? [options.sessionId]
98
+ : Array.from(this.sessionsIndex.keys());
99
+ for (const sessionId of sessionIds) {
100
+ if (results.length >= limit)
101
+ break;
102
+ const filePath = this.sessionFilePath(sessionId);
103
+ if (!fs.existsSync(filePath))
104
+ continue;
105
+ let raw;
106
+ try {
107
+ raw = fs.readFileSync(filePath, 'utf8');
108
+ }
109
+ catch {
110
+ continue;
111
+ }
112
+ const lines = raw.split('\n');
113
+ for (let i = 0; i < lines.length; i++) {
114
+ if (results.length >= limit)
115
+ break;
116
+ const line = lines[i].trim();
117
+ if (!line)
118
+ continue;
119
+ if (line.toLowerCase().includes(lowerQuery)) {
120
+ try {
121
+ const entry = JSON.parse(line);
122
+ results.push({ entry, sessionId, lineNumber: i + 1 });
123
+ }
124
+ catch {
125
+ // Skip malformed lines
126
+ }
127
+ }
128
+ }
129
+ }
130
+ return results;
131
+ }
132
+ /**
133
+ * Get or create session metadata. Uses firstMessage to auto-generate a title
134
+ * if the session doesn't yet exist.
135
+ */
136
+ getOrCreateMeta(sessionId, firstMessage) {
137
+ const existing = this.sessionsIndex.get(sessionId);
138
+ if (existing)
139
+ return existing;
140
+ const now = Date.now();
141
+ const meta = {
142
+ sessionId,
143
+ title: firstMessage ? this.generateTitle(firstMessage) : `Session ${sessionId.slice(0, 8)}`,
144
+ startedAt: now,
145
+ lastActivityAt: now,
146
+ messageCount: 0,
147
+ tokensUsed: 0,
148
+ };
149
+ this.sessionsIndex.set(sessionId, meta);
150
+ this.saveIndex();
151
+ return meta;
152
+ }
153
+ /**
154
+ * Merge partial updates into an existing session's metadata.
155
+ */
156
+ updateMeta(sessionId, updates) {
157
+ const existing = this.sessionsIndex.get(sessionId);
158
+ if (!existing)
159
+ return;
160
+ this.sessionsIndex.set(sessionId, { ...existing, ...updates, sessionId });
161
+ this.saveIndex();
162
+ }
163
+ /**
164
+ * Delete a session's JSONL file and remove it from the index.
165
+ */
166
+ deleteSession(sessionId) {
167
+ const filePath = this.sessionFilePath(sessionId);
168
+ if (fs.existsSync(filePath)) {
169
+ try {
170
+ fs.unlinkSync(filePath);
171
+ }
172
+ catch (err) {
173
+ console.error(`[TranscriptStore] Failed to delete session file ${sessionId}:`, err);
174
+ }
175
+ }
176
+ this.sessionsIndex.delete(sessionId);
177
+ this.saveIndex();
178
+ }
179
+ flush() {
180
+ if (this.indexTimer) {
181
+ clearTimeout(this.indexTimer);
182
+ this.indexTimer = null;
183
+ }
184
+ if (this.indexDirty) {
185
+ this.saveIndex();
186
+ this.indexDirty = false;
187
+ }
188
+ }
189
+ // ---------------------------------------------------------------------------
190
+ // Private helpers
191
+ // ---------------------------------------------------------------------------
192
+ markIndexDirty() {
193
+ this.indexDirty = true;
194
+ if (!this.indexTimer) {
195
+ this.indexTimer = setTimeout(() => {
196
+ this.indexTimer = null;
197
+ if (this.indexDirty) {
198
+ this.saveIndex();
199
+ this.indexDirty = false;
200
+ }
201
+ }, 1000);
202
+ }
203
+ }
204
+ sessionFilePath(sessionId) {
205
+ return path.join(this.transcriptsDir, `${sessionId}.jsonl`);
206
+ }
207
+ indexFilePath() {
208
+ return path.join(this.transcriptsDir, 'index.json');
209
+ }
210
+ ensureDir() {
211
+ if (!fs.existsSync(this.transcriptsDir)) {
212
+ fs.mkdirSync(this.transcriptsDir, { recursive: true });
213
+ }
214
+ }
215
+ loadIndex() {
216
+ const indexPath = this.indexFilePath();
217
+ if (!fs.existsSync(indexPath))
218
+ return;
219
+ try {
220
+ const raw = fs.readFileSync(indexPath, 'utf8');
221
+ const sessions = JSON.parse(raw);
222
+ for (const session of sessions) {
223
+ this.sessionsIndex.set(session.sessionId, session);
224
+ }
225
+ }
226
+ catch (err) {
227
+ console.error('[TranscriptStore] Failed to load index:', err);
228
+ }
229
+ }
230
+ saveIndex() {
231
+ this.ensureDir();
232
+ const indexPath = this.indexFilePath();
233
+ const sessions = Array.from(this.sessionsIndex.values());
234
+ try {
235
+ fs.writeFileSync(indexPath, JSON.stringify(sessions, null, 2), 'utf8');
236
+ }
237
+ catch (err) {
238
+ console.error('[TranscriptStore] Failed to save index:', err);
239
+ }
240
+ }
241
+ /**
242
+ * Generate a human-readable title from the first 50 chars of a message.
243
+ * Strips newlines, trims whitespace.
244
+ */
245
+ generateTitle(message) {
246
+ const cleaned = message.replace(/[\r\n\t]+/g, ' ').trim();
247
+ if (cleaned.length <= 50)
248
+ return cleaned;
249
+ return cleaned.slice(0, 47) + '...';
250
+ }
251
+ }
252
+ /**
253
+ * Returns the process-level singleton TranscriptStore, rooted at cwd().
254
+ */
255
+ export function getTranscriptStore() {
256
+ if (!_instance) {
257
+ _instance = new TranscriptStore();
258
+ }
259
+ return _instance;
260
+ }
261
+ // Exported for test injection
262
+ export function _resetTranscriptStoreSingleton() {
263
+ _instance = null;
264
+ }
265
+ // Re-export os for use in tests (avoids test-only imports from module internals)
266
+ export { os };
267
+ //# sourceMappingURL=transcript.js.map