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.
Files changed (477) hide show
  1. package/.env.example +14 -2
  2. package/CHANGELOG.md +37 -0
  3. package/CONTRIBUTING.md +20 -0
  4. package/Dockerfile +39 -23
  5. package/README.md +174 -40
  6. package/dist/agents/agent-summary.d.ts +44 -0
  7. package/dist/agents/agent-summary.js +176 -0
  8. package/dist/agents/auto-memory.d.ts +59 -0
  9. package/dist/agents/auto-memory.js +310 -0
  10. package/dist/agents/checkpoint-manager.d.ts +76 -0
  11. package/dist/agents/checkpoint-manager.js +156 -0
  12. package/dist/agents/circuit-breaker.d.ts +54 -0
  13. package/dist/agents/circuit-breaker.js +153 -0
  14. package/dist/agents/context-compactor.d.ts +70 -0
  15. package/dist/agents/context-compactor.js +361 -0
  16. package/dist/agents/conversation-branch.d.ts +55 -0
  17. package/dist/agents/conversation-branch.js +115 -0
  18. package/dist/agents/error-recovery.d.ts +44 -0
  19. package/dist/agents/error-recovery.js +197 -0
  20. package/dist/agents/events.d.ts +76 -0
  21. package/dist/agents/events.js +8 -0
  22. package/dist/agents/executor.d.ts +35 -1
  23. package/dist/agents/executor.js +573 -124
  24. package/dist/agents/file-snapshots.d.ts +72 -0
  25. package/dist/agents/file-snapshots.js +182 -0
  26. package/dist/agents/index.d.ts +2 -0
  27. package/dist/agents/orchestrator.d.ts +183 -0
  28. package/dist/agents/orchestrator.js +495 -0
  29. package/dist/agents/permissions.d.ts +63 -0
  30. package/dist/agents/permissions.js +138 -0
  31. package/dist/agents/plan-mode.d.ts +71 -0
  32. package/dist/agents/plan-mode.js +186 -0
  33. package/dist/agents/prompt-suggestions.d.ts +33 -0
  34. package/dist/agents/prompt-suggestions.js +208 -0
  35. package/dist/agents/rate-limit-monitor.d.ts +56 -0
  36. package/dist/agents/rate-limit-monitor.js +224 -0
  37. package/dist/agents/result-store.d.ts +37 -0
  38. package/dist/agents/result-store.js +104 -0
  39. package/dist/agents/session-diff.d.ts +43 -0
  40. package/dist/agents/session-diff.js +258 -0
  41. package/dist/agents/tool-loader.d.ts +65 -0
  42. package/dist/agents/tool-loader.js +273 -0
  43. package/dist/agents/transcript.d.ts +96 -0
  44. package/dist/agents/transcript.js +267 -0
  45. package/dist/agents/worktree-manager.d.ts +80 -0
  46. package/dist/agents/worktree-manager.js +203 -0
  47. package/dist/auth/middleware.js +14 -0
  48. package/dist/chat/agentic-executor.d.ts +7 -0
  49. package/dist/chat/agentic-executor.js +253 -30
  50. package/dist/chat/conversations.d.ts +2 -0
  51. package/dist/chat/conversations.js +8 -0
  52. package/dist/chat/execution/executor.d.ts +8 -0
  53. package/dist/chat/execution/executor.js +157 -103
  54. package/dist/chat/execution/index.js +5 -1
  55. package/dist/chat/execution/tool-router.js +40 -14
  56. package/dist/chat/execution/tools/canvas.d.ts +2 -2
  57. package/dist/chat/execution/tools/code-tools.d.ts +66 -0
  58. package/dist/chat/execution/tools/code-tools.js +353 -0
  59. package/dist/chat/execution/tools/complete-task.d.ts +2 -2
  60. package/dist/chat/execution/tools/cron-tool.d.ts +26 -10
  61. package/dist/chat/execution/tools/cron-tool.js +48 -3
  62. package/dist/chat/execution/tools/decompose-task.d.ts +58 -0
  63. package/dist/chat/execution/tools/decompose-task.js +166 -0
  64. package/dist/chat/execution/tools/exec.d.ts +5 -2
  65. package/dist/chat/execution/tools/exec.js +294 -155
  66. package/dist/chat/execution/tools/feed-tools.d.ts +77 -0
  67. package/dist/chat/execution/tools/feed-tools.js +142 -0
  68. package/dist/chat/execution/tools/file-ops.d.ts +1 -1
  69. package/dist/chat/execution/tools/github.d.ts +2 -2
  70. package/dist/chat/execution/tools/index.d.ts +14 -2
  71. package/dist/chat/execution/tools/index.js +86 -12
  72. package/dist/chat/execution/tools/integrations.d.ts +8 -8
  73. package/dist/chat/execution/tools/multi-patch.d.ts +53 -0
  74. package/dist/chat/execution/tools/multi-patch.js +373 -0
  75. package/dist/chat/execution/tools/openai-image-gen.d.ts +2 -2
  76. package/dist/chat/execution/tools/plan-tools.d.ts +80 -0
  77. package/dist/chat/execution/tools/plan-tools.js +134 -0
  78. package/dist/chat/execution/tools/profclaw-ops.d.ts +6 -6
  79. package/dist/chat/execution/tools/repl-tool.d.ts +46 -0
  80. package/dist/chat/execution/tools/repl-tool.js +207 -0
  81. package/dist/chat/execution/tools/sessions-send.d.ts +2 -2
  82. package/dist/chat/execution/tools/slack-actions.d.ts +2 -2
  83. package/dist/chat/execution/tools/system.d.ts +4 -4
  84. package/dist/chat/execution/tools/todo-tool.d.ts +72 -0
  85. package/dist/chat/execution/tools/todo-tool.js +152 -0
  86. package/dist/chat/execution/tools/tool-search.d.ts +50 -0
  87. package/dist/chat/execution/tools/tool-search.js +155 -0
  88. package/dist/chat/execution/types.d.ts +21 -14
  89. package/dist/chat/execution/workflows/executor.d.ts +11 -0
  90. package/dist/chat/execution/workflows/executor.js +99 -1
  91. package/dist/chat/execution/workflows/types.d.ts +35 -2
  92. package/dist/chat/format/index.d.ts +1 -0
  93. package/dist/chat/format/index.js +1 -0
  94. package/dist/chat/format/markdown-convert.d.ts +23 -0
  95. package/dist/chat/format/markdown-convert.js +149 -0
  96. package/dist/chat/index.d.ts +1 -1
  97. package/dist/chat/index.js +1 -1
  98. package/dist/chat/message-handler.js +58 -6
  99. package/dist/chat/proactive/index.d.ts +62 -0
  100. package/dist/chat/proactive/index.js +147 -0
  101. package/dist/chat/prompt-adapter.js +2 -0
  102. package/dist/chat/providers/irc/index.d.ts +2 -2
  103. package/dist/chat/providers/telegram/index.d.ts +2 -0
  104. package/dist/chat/providers/telegram/index.js +21 -2
  105. package/dist/chat/system-prompts.d.ts +3 -3
  106. package/dist/chat/system-prompts.js +116 -61
  107. package/dist/chat/tools.d.ts +6 -6
  108. package/dist/cli/commands/auth.js +64 -1
  109. package/dist/cli/commands/chat.js +1327 -138
  110. package/dist/cli/commands/doctor.js +222 -16
  111. package/dist/cli/commands/history.d.ts +3 -0
  112. package/dist/cli/commands/history.js +138 -0
  113. package/dist/cli/commands/import.d.ts +44 -0
  114. package/dist/cli/commands/import.js +526 -0
  115. package/dist/cli/commands/init.d.ts +13 -0
  116. package/dist/cli/commands/init.js +381 -0
  117. package/dist/cli/commands/onboard.js +210 -30
  118. package/dist/cli/commands/plan.d.ts +13 -0
  119. package/dist/cli/commands/plan.js +184 -0
  120. package/dist/cli/commands/serve.d.ts +7 -0
  121. package/dist/cli/commands/serve.js +77 -18
  122. package/dist/cli/commands/setup.js +84 -3
  123. package/dist/cli/commands/status.js +54 -0
  124. package/dist/cli/commands/tools.js +13 -13
  125. package/dist/cli/commands/tui.js +26 -1
  126. package/dist/cli/index.js +19 -0
  127. package/dist/cli/ink/App.d.ts +13 -0
  128. package/dist/cli/ink/App.js +6 -0
  129. package/dist/cli/ink/ChatApp.d.ts +60 -0
  130. package/dist/cli/ink/ChatApp.js +325 -0
  131. package/dist/cli/ink/DashboardApp.d.ts +3 -0
  132. package/dist/cli/ink/DashboardApp.js +143 -0
  133. package/dist/cli/ink/components/AgentStatus.d.ts +17 -0
  134. package/dist/cli/ink/components/AgentStatus.js +33 -0
  135. package/dist/cli/ink/components/ChannelList.d.ts +17 -0
  136. package/dist/cli/ink/components/ChannelList.js +33 -0
  137. package/dist/cli/ink/components/ConnectionStatus.d.ts +19 -0
  138. package/dist/cli/ink/components/ConnectionStatus.js +50 -0
  139. package/dist/cli/ink/components/CostBar.d.ts +19 -0
  140. package/dist/cli/ink/components/CostBar.js +35 -0
  141. package/dist/cli/ink/components/HookStatus.d.ts +15 -0
  142. package/dist/cli/ink/components/HookStatus.js +7 -0
  143. package/dist/cli/ink/components/PermissionPrompt.d.ts +21 -0
  144. package/dist/cli/ink/components/PermissionPrompt.js +51 -0
  145. package/dist/cli/ink/components/PlanView.d.ts +23 -0
  146. package/dist/cli/ink/components/PlanView.js +26 -0
  147. package/dist/cli/ink/components/ProviderList.d.ts +16 -0
  148. package/dist/cli/ink/components/ProviderList.js +16 -0
  149. package/dist/cli/ink/components/SessionHeader.d.ts +15 -0
  150. package/dist/cli/ink/components/SessionHeader.js +15 -0
  151. package/dist/cli/ink/components/StreamingMessage.d.ts +20 -0
  152. package/dist/cli/ink/components/StreamingMessage.js +27 -0
  153. package/dist/cli/ink/components/SuggestionBar.d.ts +15 -0
  154. package/dist/cli/ink/components/SuggestionBar.js +28 -0
  155. package/dist/cli/ink/components/SystemHealth.d.ts +20 -0
  156. package/dist/cli/ink/components/SystemHealth.js +39 -0
  157. package/dist/cli/ink/components/TaskList.d.ts +17 -0
  158. package/dist/cli/ink/components/TaskList.js +59 -0
  159. package/dist/cli/ink/components/ToolCall.d.ts +17 -0
  160. package/dist/cli/ink/components/ToolCall.js +43 -0
  161. package/dist/cli/ink/index.d.ts +23 -0
  162. package/dist/cli/ink/index.js +15 -0
  163. package/dist/cli/ink/keybindings.d.ts +35 -0
  164. package/dist/cli/ink/keybindings.js +105 -0
  165. package/dist/cli/ink/markdown-renderer.d.ts +47 -0
  166. package/dist/cli/ink/markdown-renderer.js +380 -0
  167. package/dist/cli/ink/output-styles.d.ts +39 -0
  168. package/dist/cli/ink/output-styles.js +119 -0
  169. package/dist/cli/interactive/auto-serve.d.ts +38 -0
  170. package/dist/cli/interactive/auto-serve.js +209 -0
  171. package/dist/cli/interactive/index.d.ts +25 -0
  172. package/dist/cli/interactive/index.js +23 -0
  173. package/dist/cli/interactive/picker.d.ts +28 -0
  174. package/dist/cli/interactive/picker.js +153 -0
  175. package/dist/cli/interactive/renderer.d.ts +26 -0
  176. package/dist/cli/interactive/renderer.js +555 -0
  177. package/dist/cli/interactive/repl.d.ts +14 -0
  178. package/dist/cli/interactive/repl.js +1516 -0
  179. package/dist/cli/interactive/stream-client.d.ts +59 -0
  180. package/dist/cli/interactive/stream-client.js +506 -0
  181. package/dist/cli/interactive/types.d.ts +121 -0
  182. package/dist/cli/interactive/types.js +10 -0
  183. package/dist/cli/utils/api.d.ts +9 -0
  184. package/dist/cli/utils/api.js +58 -2
  185. package/dist/cron/natural-language.d.ts +54 -0
  186. package/dist/cron/natural-language.js +569 -0
  187. package/dist/cron/scheduler.d.ts +34 -4
  188. package/dist/cron/scheduler.js +141 -9
  189. package/dist/cron/templates.d.ts +1 -1
  190. package/dist/cron/templates.js +219 -0
  191. package/dist/feeds/feed-engine.d.ts +149 -0
  192. package/dist/feeds/feed-engine.js +600 -0
  193. package/dist/feeds/index.d.ts +9 -0
  194. package/dist/feeds/index.js +8 -0
  195. package/dist/gateway/router.js +6 -1
  196. package/dist/hooks/built-in/audit-log.d.ts +11 -0
  197. package/dist/hooks/built-in/audit-log.js +84 -0
  198. package/dist/hooks/built-in/cost-warning.d.ts +10 -0
  199. package/dist/hooks/built-in/cost-warning.js +59 -0
  200. package/dist/hooks/built-in/dangerous-tool.d.ts +32 -0
  201. package/dist/hooks/built-in/dangerous-tool.js +80 -0
  202. package/dist/hooks/built-in/index.d.ts +14 -0
  203. package/dist/hooks/built-in/index.js +20 -0
  204. package/dist/hooks/index.d.ts +3 -0
  205. package/dist/hooks/index.js +6 -0
  206. package/dist/hooks/loader.d.ts +17 -0
  207. package/dist/hooks/loader.js +142 -0
  208. package/dist/hooks/registry.d.ts +62 -0
  209. package/dist/hooks/registry.js +127 -0
  210. package/dist/integrations/web-search.js +6 -3
  211. package/dist/memory/index.d.ts +1 -0
  212. package/dist/memory/index.js +2 -0
  213. package/dist/memory/memory-service.js +14 -13
  214. package/dist/memory/observational.d.ts +62 -0
  215. package/dist/memory/observational.js +396 -0
  216. package/dist/middleware/content-filter.d.ts +22 -0
  217. package/dist/middleware/content-filter.js +69 -0
  218. package/dist/middleware/request-validator.d.ts +159 -0
  219. package/dist/middleware/request-validator.js +93 -0
  220. package/dist/plugins/sdk.d.ts +22 -0
  221. package/dist/plugins/sdk.js +17 -1
  222. package/dist/projects/types.d.ts +10 -10
  223. package/dist/providers/ai-sdk.d.ts +11 -0
  224. package/dist/providers/ai-sdk.js +78 -19
  225. package/dist/providers/core/models.js +67 -1
  226. package/dist/providers/core/types.d.ts +3 -0
  227. package/dist/providers/index.d.ts +1 -0
  228. package/dist/providers/index.js +1 -0
  229. package/dist/providers/smart-router.d.ts +118 -0
  230. package/dist/providers/smart-router.js +685 -0
  231. package/dist/providers/types.d.ts +16 -16
  232. package/dist/routes/agents.js +50 -0
  233. package/dist/routes/auth.js +8 -1
  234. package/dist/routes/chat.js +259 -14
  235. package/dist/routes/costs.js +32 -0
  236. package/dist/routes/cron.js +80 -5
  237. package/dist/routes/feeds.d.ts +10 -0
  238. package/dist/routes/feeds.js +168 -0
  239. package/dist/routes/mcp.js +21 -0
  240. package/dist/routes/memory.js +130 -0
  241. package/dist/routes/skills.js +129 -0
  242. package/dist/routes/teams.d.ts +9 -0
  243. package/dist/routes/teams.js +210 -0
  244. package/dist/routes/tools.js +14 -0
  245. package/dist/routes/users.js +2 -0
  246. package/dist/server/route-loader.js +3 -1
  247. package/dist/server/stream-bridge.d.ts +19 -0
  248. package/dist/server/stream-bridge.js +38 -0
  249. package/dist/server.js +310 -36
  250. package/dist/skills/marketplace.d.ts +87 -0
  251. package/dist/skills/marketplace.js +268 -0
  252. package/dist/storage/index.d.ts +14 -0
  253. package/dist/storage/index.js +64 -3
  254. package/dist/storage/schema.d.ts +4 -4
  255. package/dist/storage/schema.js +1 -1
  256. package/dist/teams/index.d.ts +110 -0
  257. package/dist/teams/index.js +365 -0
  258. package/dist/tickets/types.d.ts +39 -39
  259. package/dist/types/summary.d.ts +5 -5
  260. package/dist/utils/auto-update.d.ts +23 -0
  261. package/dist/utils/auto-update.js +157 -0
  262. package/dist/utils/offline-detect.d.ts +55 -0
  263. package/dist/utils/offline-detect.js +121 -0
  264. package/dist/utils/pid-file.d.ts +36 -0
  265. package/dist/utils/pid-file.js +125 -0
  266. package/dist/utils/prevent-sleep.d.ts +27 -0
  267. package/dist/utils/prevent-sleep.js +95 -0
  268. package/dist/utils/sanitizer.d.ts +57 -0
  269. package/dist/utils/sanitizer.js +174 -0
  270. package/docker-compose.yml +13 -137
  271. package/package.json +31 -6
  272. package/skills/deploy-cloudflare/SKILL.md +62 -0
  273. package/skills/deploy-vercel/SKILL.md +67 -0
  274. package/skills/docker-deploy/SKILL.md +158 -0
  275. package/skills/full-stack-builder/SKILL.md +92 -0
  276. package/skills/humanizer/SKILL.md +488 -0
  277. package/skills/profclaw-assistant/SKILL.md +85 -56
  278. package/ui/dist/assets/ActivityView-Da6HQ8ws.js +1 -0
  279. package/ui/dist/assets/AgentList-H58R0kX3.js +1 -0
  280. package/ui/dist/assets/AnalyticsDashboard-B28AeRsc.js +1 -0
  281. package/ui/dist/assets/AreaChart-DwLzeAQ8.js +1 -0
  282. package/ui/dist/assets/CartesianChart-piKQsTAR.js +36 -0
  283. package/ui/dist/assets/ChatView-Dbj8rxU5.js +10 -0
  284. package/ui/dist/assets/CostsDashboard-C6F5df0F.js +1 -0
  285. package/ui/dist/assets/EstimateSelect-wga0rUKX.js +1 -0
  286. package/ui/dist/assets/FeedDashboard-Ef6FEzEf.js +1 -0
  287. package/ui/dist/assets/FloatingChatbot-0yhkUeCq.js +2 -0
  288. package/ui/dist/assets/InviteCodeManagement-tUXfx4Bc.js +2 -0
  289. package/ui/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  290. package/ui/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  291. package/ui/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  292. package/ui/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  293. package/ui/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  294. package/ui/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  295. package/ui/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  296. package/ui/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  297. package/ui/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  298. package/ui/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  299. package/ui/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  300. package/ui/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  301. package/ui/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  302. package/ui/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  303. package/ui/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  304. package/ui/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  305. package/ui/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  306. package/ui/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  307. package/ui/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  308. package/ui/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  309. package/ui/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  310. package/ui/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  311. package/ui/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  312. package/ui/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  313. package/ui/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  314. package/ui/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  315. package/ui/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  316. package/ui/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  317. package/ui/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  318. package/ui/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  319. package/ui/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  320. package/ui/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  321. package/ui/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  322. package/ui/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  323. package/ui/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  324. package/ui/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  325. package/ui/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  326. package/ui/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  327. package/ui/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  328. package/ui/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  329. package/ui/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  330. package/ui/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  331. package/ui/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  332. package/ui/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  333. package/ui/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  334. package/ui/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  335. package/ui/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  336. package/ui/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  337. package/ui/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  338. package/ui/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  339. package/ui/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  340. package/ui/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  341. package/ui/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  342. package/ui/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  343. package/ui/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  344. package/ui/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  345. package/ui/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  346. package/ui/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  347. package/ui/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  348. package/ui/dist/assets/MarketplacePage-DGrLtolR.js +1 -0
  349. package/ui/dist/assets/{ProjectDetail--gPfvATB.js → ProjectDetail-BgWvA6UP.js} +2 -2
  350. package/ui/dist/assets/ProjectIcon-TDuliqwg.js +1 -0
  351. package/ui/dist/assets/ProjectList-DXgM4187.js +1 -0
  352. package/ui/dist/assets/{Settings-1kaf7VHE.js → Settings-xA8Zhi3p.js} +3 -3
  353. package/ui/dist/assets/StatusIndicator-B8vfFAxg.js +1 -0
  354. package/ui/dist/assets/{SummaryDetail-DV3AmONk.js → SummaryDetail-eedRfTtF.js} +2 -2
  355. package/ui/dist/assets/SummaryList-CLNX2P84.js +1 -0
  356. package/ui/dist/assets/TaskDetail-BtWclNiR.js +1 -0
  357. package/ui/dist/assets/TaskList-JjODAgSc.js +1 -0
  358. package/ui/dist/assets/TeamsPage-CBK5iAyx.js +1 -0
  359. package/ui/dist/assets/TicketBoard-C9aJNNYp.js +1 -0
  360. package/ui/dist/assets/TicketDetail-CV5JmL31.js +1 -0
  361. package/ui/dist/assets/TicketList-68V4lzUz.js +1 -0
  362. package/ui/dist/assets/UserManagement-DKTb6UpE.js +2 -0
  363. package/ui/dist/assets/ViewSwitcher-BvdQht2Y.js +1 -0
  364. package/ui/dist/assets/alert-dialog-O6qBOv_f.js +1 -0
  365. package/ui/dist/assets/{archive-BsLa7brF.js → archive-CX7UvZpf.js} +1 -1
  366. package/ui/dist/assets/badge-BbfnwDJP.js +1 -0
  367. package/ui/dist/assets/{bug-CmZI7jqM.js → bug-3WX0394-.js} +1 -1
  368. package/ui/dist/assets/{calendar-Bf0t2B82.js → calendar-buq77TaS.js} +1 -1
  369. package/ui/dist/assets/{chevron-up-CoUsOvZj.js → chevron-up-4ymsBJRo.js} +1 -1
  370. package/ui/dist/assets/{circle-x-Dgw11LgT.js → circle-x-ByXtwR6Y.js} +1 -1
  371. package/ui/dist/assets/constants-CVdDh7p0.js +1 -0
  372. package/ui/dist/assets/{cpu-DiPMQICV.js → cpu-CiuoCeDY.js} +1 -1
  373. package/ui/dist/assets/{database-BwTfupDi.js → database-BWXSBg5a.js} +1 -1
  374. package/ui/dist/assets/dialog-lDg4NvMV.js +1 -0
  375. package/ui/dist/assets/dollar-sign-Dmijd6DP.js +1 -0
  376. package/ui/dist/assets/{ellipsis-UJx4Xnf6.js → ellipsis-vT-5SVIp.js} +1 -1
  377. package/ui/dist/assets/{ellipsis-vertical-DoULYEKn.js → ellipsis-vertical-B4tAX_bL.js} +1 -1
  378. package/ui/dist/assets/feature-markdown-DBo5Q7uq.js +289 -0
  379. package/ui/dist/assets/{file-code-B2UrJLwi.js → file-code-ChOWdKXf.js} +1 -1
  380. package/ui/dist/assets/{folder-open-BJi577JH.js → folder-open-CkOUbIiP.js} +1 -1
  381. package/ui/dist/assets/{funnel-PkaD_HSR.js → funnel-uZkoSPP-.js} +1 -1
  382. package/ui/dist/assets/{git-branch-C_K30am0.js → git-branch-CwvUxj7C.js} +1 -1
  383. package/ui/dist/assets/{git-commit-horizontal-IT6ecxWQ.js → git-commit-horizontal-lxPzCvhD.js} +1 -1
  384. package/ui/dist/assets/{globe-f-jjCa_g.js → globe-D_WpJdsj.js} +1 -1
  385. package/ui/dist/assets/{hash-DNEv8Elo.js → hash-CA0hJ7vh.js} +1 -1
  386. package/ui/dist/assets/{history-BQSBo_1Q.js → history-CEWMLELs.js} +1 -1
  387. package/ui/dist/assets/inbox-ehtOptTV.js +1 -0
  388. package/ui/dist/assets/{index-nS3EErDg.js → index-C1rhbml4.js} +3 -3
  389. package/ui/dist/assets/index-CR8gfCHv.js +1 -0
  390. package/ui/dist/assets/index-DVXMpWai.js +1 -0
  391. package/ui/dist/assets/index-DaDJMM2v.js +1 -0
  392. package/ui/dist/assets/index-Djdq_0xu.js +1 -0
  393. package/ui/dist/assets/index-M46Gcb8K.css +1 -0
  394. package/ui/dist/assets/index-sEBN7w8J.js +109 -0
  395. package/ui/dist/assets/layers-C6Mhf8Nk.js +1 -0
  396. package/ui/dist/assets/{layout-dashboard-CcKt1hXw.js → layout-dashboard-BRUM0kpT.js} +1 -1
  397. package/ui/dist/assets/{lightbulb-Jhp7FvbU.js → lightbulb-CN2q1O5l.js} +1 -1
  398. package/ui/dist/assets/{link-2-DdO7ostF.js → link-2-CC4E28yJ.js} +1 -1
  399. package/ui/dist/assets/markdown-renderer-C6ENbB0u.js +10 -0
  400. package/ui/dist/assets/markdown-renderer-CfVKi3_s.css +1 -0
  401. package/ui/dist/assets/{message-square-CBgH65X7.js → message-square-Bbb241am.js} +1 -1
  402. package/ui/dist/assets/package-CwT3IzFx.js +1 -0
  403. package/ui/dist/assets/{pencil-CYXCEPQh.js → pencil-CDmiHzoj.js} +1 -1
  404. package/ui/dist/assets/{play-d1ONaH0-.js → play-tjy5jMQX.js} +1 -1
  405. package/ui/dist/assets/popover-CFHZf3pE.js +1 -0
  406. package/ui/dist/assets/progress-BboUHuLf.js +1 -0
  407. package/ui/dist/assets/{rocket-DhvUetsk.js → rocket--8ZHgdXJ.js} +1 -1
  408. package/ui/dist/assets/select-n108rXny.js +1 -0
  409. package/ui/dist/assets/{send-P0r5D7td.js → send-Cu7MR2Qh.js} +1 -1
  410. package/ui/dist/assets/server-DmodxZp-.js +1 -0
  411. package/ui/dist/assets/{settings-2-ocj5uHGx.js → settings-2-CkRNqkxj.js} +1 -1
  412. package/ui/dist/assets/sheet-7aUJkyzU.js +1 -0
  413. package/ui/dist/assets/{shield-check-DfVdE34l.js → shield-check-ViI3nMKE.js} +1 -1
  414. package/ui/dist/assets/{shield-off-8l0J6R-8.js → shield-off-DN3tagkn.js} +1 -1
  415. package/ui/dist/assets/skeleton-C0E1Nfro.js +1 -0
  416. package/ui/dist/assets/{smartphone-77_g3SQn.js → smartphone-5FghiXpA.js} +1 -1
  417. package/ui/dist/assets/{square-Ckzsr3Rn.js → square-DiNSx8K7.js} +1 -1
  418. package/ui/dist/assets/star-DhdFVidS.js +1 -0
  419. package/ui/dist/assets/switch-CIgVbZqQ.js +1 -0
  420. package/ui/dist/assets/table-BC56FVMV.js +1 -0
  421. package/ui/dist/assets/{tag-C35mgoEv.js → tag-CH_vQliw.js} +1 -1
  422. package/ui/dist/assets/textarea-CxDiKFXZ.js +1 -0
  423. package/ui/dist/assets/{timer-DHJBS2w1.js → timer-CdGVTb60.js} +1 -1
  424. package/ui/dist/assets/tooltip-BuW9A5UO.js +1 -0
  425. package/ui/dist/assets/{trash-2-keO5tKPE.js → trash-2-CucZJL0N.js} +1 -1
  426. package/ui/dist/assets/trending-down-BCezC1z2.js +1 -0
  427. package/ui/dist/assets/{trending-up-BBv8KbrY.js → trending-up-C5OYX2k2.js} +1 -1
  428. package/ui/dist/assets/vendor-query-C0p7b53x.js +4 -0
  429. package/ui/dist/assets/vendor-react-Mc5_kfYG.js +12 -0
  430. package/ui/dist/assets/vendor-ui-CXPAUBFv.js +51 -0
  431. package/ui/dist/assets/{wand-sparkles-BusQ52ZK.js → wand-sparkles-BaH6pJnc.js} +1 -1
  432. package/ui/dist/assets/{wrench-02YaOSiK.js → wrench-CjxjP6ok.js} +1 -1
  433. package/ui/dist/index.html +5 -2
  434. package/ui/dist/assets/ActivityView-BeshZXmE.js +0 -1
  435. package/ui/dist/assets/AgentList-QVHeldPi.js +0 -1
  436. package/ui/dist/assets/AnalyticsDashboard-C9R97dXE.js +0 -1
  437. package/ui/dist/assets/AreaChart-B73gaiVQ.js +0 -1
  438. package/ui/dist/assets/CartesianChart-CXYL2R-A.js +0 -36
  439. package/ui/dist/assets/ChatView-qjZErlrp.js +0 -10
  440. package/ui/dist/assets/CostsDashboard-O4DCLy1i.js +0 -1
  441. package/ui/dist/assets/EstimateSelect-1hQf4Osk.js +0 -1
  442. package/ui/dist/assets/FloatingChatbot-BZBzrJxd.js +0 -2
  443. package/ui/dist/assets/InviteCodeManagement-LEoGqYeA.js +0 -2
  444. package/ui/dist/assets/ProjectIcon-Chd_ofsw.js +0 -1
  445. package/ui/dist/assets/ProjectList-BvUfVB6c.js +0 -4
  446. package/ui/dist/assets/StatusIndicator-pRfkNcdV.js +0 -1
  447. package/ui/dist/assets/SummaryList-B6kXiTxL.js +0 -1
  448. package/ui/dist/assets/TaskDetail-CV6CzbOS.js +0 -1
  449. package/ui/dist/assets/TaskList-DL7brQKd.js +0 -1
  450. package/ui/dist/assets/TicketBoard-CrkkFj7C.js +0 -1
  451. package/ui/dist/assets/TicketDetail-hnnYclpD.js +0 -1
  452. package/ui/dist/assets/TicketList-CsDAyQCL.js +0 -1
  453. package/ui/dist/assets/UserManagement-BGFQyTSr.js +0 -2
  454. package/ui/dist/assets/ViewSwitcher-CnL0OqA8.js +0 -1
  455. package/ui/dist/assets/alert-dialog-SKM6Gjz4.js +0 -7
  456. package/ui/dist/assets/badge-CVHH1a-v.js +0 -1
  457. package/ui/dist/assets/brain-6o_RHVpe.js +0 -1
  458. package/ui/dist/assets/constants-Q5Zivl-a.js +0 -1
  459. package/ui/dist/assets/dialog-BUqN9Psj.js +0 -1
  460. package/ui/dist/assets/index-BUmnwPQr.js +0 -1
  461. package/ui/dist/assets/index-BfF5G4Cw.js +0 -1
  462. package/ui/dist/assets/index-C8N375c2.js +0 -1
  463. package/ui/dist/assets/index-CuxnqVVz.css +0 -1
  464. package/ui/dist/assets/index-CzMM3QOk.js +0 -1
  465. package/ui/dist/assets/index-lJlNPFVJ.js +0 -67
  466. package/ui/dist/assets/layers-jFqVrWMD.js +0 -1
  467. package/ui/dist/assets/markdown-renderer-n1ToC4XQ.js +0 -36
  468. package/ui/dist/assets/popover-CrmZgoWu.js +0 -1
  469. package/ui/dist/assets/progress-uv4SPkL5.js +0 -1
  470. package/ui/dist/assets/select-CeQ8AHGy.js +0 -1
  471. package/ui/dist/assets/server-CVHTZB72.js +0 -1
  472. package/ui/dist/assets/sheet-DuQExSho.js +0 -1
  473. package/ui/dist/assets/skeleton-TFiFJ3nB.js +0 -1
  474. package/ui/dist/assets/switch-CAePkd6k.js +0 -1
  475. package/ui/dist/assets/table-ZjAZ7hkt.js +0 -1
  476. package/ui/dist/assets/textarea-DsVPnSgR.js +0 -1
  477. package/ui/dist/assets/tooltip-BYmQ331W.js +0 -1
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Rate Limit Monitor
3
+ *
4
+ * Tracks API rate limit state per provider by parsing standard x-ratelimit-*
5
+ * response headers. Surfaces warnings when usage thresholds are reached and
6
+ * can suggest alternative providers when limits are critical.
7
+ */
8
+ // === Constants ===
9
+ const THRESHOLD_INFO = 0.75;
10
+ const THRESHOLD_WARNING = 0.90;
11
+ const THRESHOLD_CRITICAL = 0.95;
12
+ // Provider preference order for suggesting alternatives (prefer local)
13
+ const PROVIDER_PREFERENCE = ['ollama', 'anthropic', 'openai', 'azure', 'google', 'cerebras'];
14
+ function defaultState(provider) {
15
+ return {
16
+ provider,
17
+ model: 'unknown',
18
+ requestsUsed: 0,
19
+ tokensUsed: 0,
20
+ warningLevel: 'none',
21
+ };
22
+ }
23
+ /**
24
+ * Parse a reset timestamp header value.
25
+ * Accepts either a Unix timestamp (seconds) or a relative duration like "1m30s".
26
+ */
27
+ function parseResetHeader(value) {
28
+ const trimmed = value.trim();
29
+ // ISO 8601 / epoch seconds (pure number)
30
+ const asNumber = Number(trimmed);
31
+ if (!isNaN(asNumber) && asNumber > 0) {
32
+ // If it looks like seconds since epoch (> year 2000), treat as epoch seconds
33
+ if (asNumber > 1_000_000_000) {
34
+ return asNumber * 1000; // convert to ms
35
+ }
36
+ // Otherwise treat as seconds from now
37
+ return Date.now() + asNumber * 1000;
38
+ }
39
+ // Relative duration: e.g. "1m30s", "45s", "2m"
40
+ const durationMatch = trimmed.match(/^(?:(\d+)m)?(?:(\d+(?:\.\d+)?)s)?$/);
41
+ if (durationMatch) {
42
+ const minutes = parseInt(durationMatch[1] ?? '0', 10);
43
+ const seconds = parseFloat(durationMatch[2] ?? '0');
44
+ const totalMs = (minutes * 60 + seconds) * 1000;
45
+ if (totalMs > 0) {
46
+ return Date.now() + totalMs;
47
+ }
48
+ }
49
+ return undefined;
50
+ }
51
+ function computeWarningLevel(used, limit) {
52
+ const ratio = used / limit;
53
+ if (ratio >= THRESHOLD_CRITICAL)
54
+ return 'critical';
55
+ if (ratio >= THRESHOLD_WARNING)
56
+ return 'warning';
57
+ if (ratio >= THRESHOLD_INFO)
58
+ return 'info';
59
+ return 'none';
60
+ }
61
+ // === RateLimitMonitor ===
62
+ export class RateLimitMonitor {
63
+ states;
64
+ constructor() {
65
+ this.states = new Map();
66
+ }
67
+ /**
68
+ * Update rate limit state from API response headers.
69
+ * Parses the standard x-ratelimit-* header set used by OpenAI-compatible APIs
70
+ * and Anthropic:
71
+ * x-ratelimit-limit-requests
72
+ * x-ratelimit-remaining-requests
73
+ * x-ratelimit-limit-tokens
74
+ * x-ratelimit-remaining-tokens
75
+ * x-ratelimit-reset-requests
76
+ * x-ratelimit-reset-tokens
77
+ */
78
+ updateFromHeaders(provider, headers) {
79
+ const state = this.getOrCreate(provider);
80
+ const limitRequests = headers['x-ratelimit-limit-requests'];
81
+ const remainingRequests = headers['x-ratelimit-remaining-requests'];
82
+ const limitTokens = headers['x-ratelimit-limit-tokens'];
83
+ const remainingTokens = headers['x-ratelimit-remaining-tokens'];
84
+ const resetRequests = headers['x-ratelimit-reset-requests'];
85
+ const resetTokens = headers['x-ratelimit-reset-tokens'];
86
+ if (limitRequests !== undefined) {
87
+ state.requestsLimit = parseInt(limitRequests, 10);
88
+ }
89
+ if (remainingRequests !== undefined && state.requestsLimit !== undefined) {
90
+ const remaining = parseInt(remainingRequests, 10);
91
+ state.requestsUsed = state.requestsLimit - remaining;
92
+ }
93
+ if (limitTokens !== undefined) {
94
+ state.tokensLimit = parseInt(limitTokens, 10);
95
+ }
96
+ if (remainingTokens !== undefined && state.tokensLimit !== undefined) {
97
+ const remaining = parseInt(remainingTokens, 10);
98
+ state.tokensUsed = state.tokensLimit - remaining;
99
+ }
100
+ // Pick the earliest reset timestamp if both are present
101
+ const resetMs = [resetRequests, resetTokens]
102
+ .filter((v) => v !== undefined)
103
+ .map(parseResetHeader)
104
+ .filter((v) => v !== undefined)
105
+ .sort((a, b) => a - b)[0];
106
+ if (resetMs !== undefined) {
107
+ state.resetAt = resetMs;
108
+ }
109
+ // Recalculate warning level — use whichever ratio is higher
110
+ let highestLevel = 'none';
111
+ if (state.requestsLimit && state.requestsLimit > 0) {
112
+ const reqLevel = computeWarningLevel(state.requestsUsed, state.requestsLimit);
113
+ if (levelIndex(reqLevel) > levelIndex(highestLevel)) {
114
+ highestLevel = reqLevel;
115
+ }
116
+ }
117
+ if (state.tokensLimit && state.tokensLimit > 0) {
118
+ const tokLevel = computeWarningLevel(state.tokensUsed, state.tokensLimit);
119
+ if (levelIndex(tokLevel) > levelIndex(highestLevel)) {
120
+ highestLevel = tokLevel;
121
+ }
122
+ }
123
+ state.warningLevel = highestLevel;
124
+ }
125
+ /** Get current rate limit state for a provider. */
126
+ getState(provider) {
127
+ return this.states.get(provider);
128
+ }
129
+ /**
130
+ * Check whether the user should be warned about rate limit usage.
131
+ * Returns the highest-severity warning across requests and tokens.
132
+ */
133
+ shouldWarn(provider) {
134
+ const state = this.states.get(provider);
135
+ if (!state || state.warningLevel === 'none') {
136
+ return { warn: false, message: '', level: 'none' };
137
+ }
138
+ const parts = [];
139
+ if (state.requestsLimit && state.requestsLimit > 0) {
140
+ const pct = Math.round((state.requestsUsed / state.requestsLimit) * 100);
141
+ parts.push(`${pct}% of request quota used`);
142
+ }
143
+ if (state.tokensLimit && state.tokensLimit > 0) {
144
+ const pct = Math.round((state.tokensUsed / state.tokensLimit) * 100);
145
+ parts.push(`${pct}% of token quota used`);
146
+ }
147
+ let resetNote = '';
148
+ if (state.resetAt) {
149
+ const remainMs = state.resetAt - Date.now();
150
+ if (remainMs > 0) {
151
+ const remainSec = Math.ceil(remainMs / 1000);
152
+ const mins = Math.floor(remainSec / 60);
153
+ const secs = remainSec % 60;
154
+ resetNote = mins > 0
155
+ ? ` (resets in ${mins}m ${secs}s)`
156
+ : ` (resets in ${secs}s)`;
157
+ }
158
+ }
159
+ const prefix = state.warningLevel === 'critical'
160
+ ? 'Rate limit critical'
161
+ : state.warningLevel === 'warning'
162
+ ? 'Approaching rate limit'
163
+ : 'Rate limit notice';
164
+ const message = `${prefix} [${provider}]: ${parts.join(', ')}${resetNote}`;
165
+ return {
166
+ warn: true,
167
+ message,
168
+ level: state.warningLevel,
169
+ };
170
+ }
171
+ /**
172
+ * Suggest an alternative provider when the given provider is at a high usage level.
173
+ * Returns undefined if no switch is recommended.
174
+ */
175
+ suggestAlternative(provider, availableProviders) {
176
+ const state = this.states.get(provider);
177
+ if (!state || levelIndex(state.warningLevel) < levelIndex('warning')) {
178
+ return undefined;
179
+ }
180
+ // Find a provider with no warning or lower warning level
181
+ const candidates = availableProviders
182
+ .filter(p => p !== provider)
183
+ .sort((a, b) => {
184
+ // Prefer low-warning providers first, then follow preference order
185
+ const aLevel = levelIndex(this.states.get(a)?.warningLevel ?? 'none');
186
+ const bLevel = levelIndex(this.states.get(b)?.warningLevel ?? 'none');
187
+ if (aLevel !== bLevel)
188
+ return aLevel - bLevel;
189
+ return PROVIDER_PREFERENCE.indexOf(a) - PROVIDER_PREFERENCE.indexOf(b);
190
+ });
191
+ return candidates[0];
192
+ }
193
+ /** Return a snapshot of all tracked provider states. */
194
+ getAll() {
195
+ return Array.from(this.states.values()).map(s => ({ ...s }));
196
+ }
197
+ // Private helpers
198
+ getOrCreate(provider) {
199
+ let state = this.states.get(provider);
200
+ if (!state) {
201
+ state = defaultState(provider);
202
+ this.states.set(provider, state);
203
+ }
204
+ return state;
205
+ }
206
+ }
207
+ // Numeric ordering of warning levels (for comparison)
208
+ function levelIndex(level) {
209
+ switch (level) {
210
+ case 'none': return 0;
211
+ case 'info': return 1;
212
+ case 'warning': return 2;
213
+ case 'critical': return 3;
214
+ }
215
+ }
216
+ // === Singleton ===
217
+ let _monitor;
218
+ export function getRateLimitMonitor() {
219
+ if (!_monitor) {
220
+ _monitor = new RateLimitMonitor();
221
+ }
222
+ return _monitor;
223
+ }
224
+ //# sourceMappingURL=rate-limit-monitor.js.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Result Store
3
+ *
4
+ * Manages large tool results by spilling them to disk when they exceed the
5
+ * inline size limit. This prevents context windows from being flooded by
6
+ * large tool outputs (e.g. file reads, API dumps).
7
+ */
8
+ export interface StoredResult {
9
+ /** Summary string (or full result if small enough) that goes into context */
10
+ inline: string;
11
+ /** Path to the temp file containing the full result, if spilled */
12
+ fullPath?: string;
13
+ /** Original serialized byte length */
14
+ originalSize: number;
15
+ /** Whether the stored content was truncated */
16
+ truncated: boolean;
17
+ }
18
+ export declare class ResultStore {
19
+ private results;
20
+ private tempDir;
21
+ constructor(sessionId: string);
22
+ /**
23
+ * Store a tool result. Small results stay inline; large results spill to
24
+ * disk and return a summary pointing to the temp file.
25
+ */
26
+ store(toolCallId: string, result: unknown): Promise<StoredResult>;
27
+ /**
28
+ * Retrieve a previously stored result by its tool call ID.
29
+ */
30
+ retrieve(toolCallId: string): StoredResult | undefined;
31
+ /**
32
+ * Delete all temp files created during this session.
33
+ */
34
+ cleanup(): Promise<void>;
35
+ private writeTempFile;
36
+ }
37
+ //# sourceMappingURL=result-store.d.ts.map
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Result Store
3
+ *
4
+ * Manages large tool results by spilling them to disk when they exceed the
5
+ * inline size limit. This prevents context windows from being flooded by
6
+ * large tool outputs (e.g. file reads, API dumps).
7
+ */
8
+ import { writeFile, unlink, mkdir } from "node:fs/promises";
9
+ import { tmpdir } from "node:os";
10
+ import { join } from "node:path";
11
+ import { randomUUID } from "node:crypto";
12
+ import { logger } from "../utils/logger.js";
13
+ /** Results <= 50KB stay inline in the context window */
14
+ const MAX_INLINE_SIZE = 50_000;
15
+ /** Results > 5MB get truncated before saving */
16
+ const MAX_TOTAL_SIZE = 5_000_000;
17
+ /** Number of chars to include in the inline preview */
18
+ const PREVIEW_LENGTH = 500;
19
+ export class ResultStore {
20
+ results = new Map();
21
+ tempDir;
22
+ constructor(sessionId) {
23
+ this.tempDir = join(tmpdir(), `profclaw-results-${sessionId}`);
24
+ }
25
+ /**
26
+ * Store a tool result. Small results stay inline; large results spill to
27
+ * disk and return a summary pointing to the temp file.
28
+ */
29
+ async store(toolCallId, result) {
30
+ const serialized = JSON.stringify(result);
31
+ const size = Buffer.byteLength(serialized, "utf8");
32
+ let stored;
33
+ if (size <= MAX_INLINE_SIZE) {
34
+ // Small enough — keep it in context as-is
35
+ stored = {
36
+ inline: serialized,
37
+ originalSize: size,
38
+ truncated: false,
39
+ };
40
+ }
41
+ else {
42
+ // Needs to spill to disk
43
+ const truncated = size > MAX_TOTAL_SIZE;
44
+ const content = truncated
45
+ ? serialized.slice(0, MAX_TOTAL_SIZE)
46
+ : serialized;
47
+ const filePath = await this.writeTempFile(toolCallId, content);
48
+ const preview = serialized.slice(0, PREVIEW_LENGTH);
49
+ const sizeLabel = truncated
50
+ ? `${MAX_TOTAL_SIZE.toLocaleString()} bytes (truncated from ${size.toLocaleString()} bytes)`
51
+ : `${size.toLocaleString()} bytes`;
52
+ stored = {
53
+ inline: `[Result stored: ${sizeLabel}. Use retrieve_result tool to access full data. Preview: ${preview}...]`,
54
+ fullPath: filePath,
55
+ originalSize: size,
56
+ truncated,
57
+ };
58
+ logger.debug("[ResultStore] Spilled large result to disk", {
59
+ toolCallId,
60
+ size,
61
+ truncated,
62
+ filePath,
63
+ });
64
+ }
65
+ this.results.set(toolCallId, stored);
66
+ return stored;
67
+ }
68
+ /**
69
+ * Retrieve a previously stored result by its tool call ID.
70
+ */
71
+ retrieve(toolCallId) {
72
+ return this.results.get(toolCallId);
73
+ }
74
+ /**
75
+ * Delete all temp files created during this session.
76
+ */
77
+ async cleanup() {
78
+ const deletions = [];
79
+ for (const [id, stored] of this.results.entries()) {
80
+ if (stored.fullPath) {
81
+ deletions.push(unlink(stored.fullPath).catch((err) => {
82
+ logger.warn("[ResultStore] Failed to delete temp file", {
83
+ id,
84
+ path: stored.fullPath,
85
+ error: err instanceof Error ? err.message : String(err),
86
+ });
87
+ }));
88
+ }
89
+ }
90
+ await Promise.all(deletions);
91
+ this.results.clear();
92
+ logger.debug("[ResultStore] Cleaned up temp files", {
93
+ count: deletions.length,
94
+ });
95
+ }
96
+ async writeTempFile(toolCallId, content) {
97
+ await mkdir(this.tempDir, { recursive: true });
98
+ const fileName = `${toolCallId}-${randomUUID()}.json`;
99
+ const filePath = join(this.tempDir, fileName);
100
+ await writeFile(filePath, content, "utf8");
101
+ return filePath;
102
+ }
103
+ }
104
+ //# sourceMappingURL=result-store.js.map
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Session Diff Tracker
3
+ *
4
+ * Records original file contents before the agent makes any edits so that
5
+ * a unified diff of all changes can be produced at any time (e.g. /diff).
6
+ */
7
+ export type FileChangeStatus = 'modified' | 'created' | 'deleted';
8
+ export declare class SessionDiffTracker {
9
+ private originals;
10
+ constructor();
11
+ /**
12
+ * Record the original content of a file before the agent touches it.
13
+ * Only the first call per file path is honoured — subsequent calls are
14
+ * ignored so the "before" state remains the pre-session state.
15
+ */
16
+ recordOriginal(filePath: string, content: string): void;
17
+ /**
18
+ * Record that a file was created during this session (it did not exist before).
19
+ */
20
+ recordCreated(filePath: string): void;
21
+ /**
22
+ * Generate a unified diff for all modified files.
23
+ * Returns an empty string if nothing has changed.
24
+ */
25
+ generateDiff(): Promise<string>;
26
+ /**
27
+ * Return a list of changed files with their status.
28
+ */
29
+ getChangedFiles(): Array<{
30
+ path: string;
31
+ status: FileChangeStatus;
32
+ }>;
33
+ /**
34
+ * Generate a unified diff for a single file.
35
+ * Returns an empty string if the file content is unchanged.
36
+ */
37
+ getFileDiff(filePath: string): Promise<string>;
38
+ }
39
+ /**
40
+ * Returns the process-level singleton SessionDiffTracker.
41
+ */
42
+ export declare function getSessionDiffTracker(): SessionDiffTracker;
43
+ //# sourceMappingURL=session-diff.d.ts.map
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Session Diff Tracker
3
+ *
4
+ * Records original file contents before the agent makes any edits so that
5
+ * a unified diff of all changes can be produced at any time (e.g. /diff).
6
+ */
7
+ import fs from 'node:fs/promises';
8
+ let defaultTracker = null;
9
+ export class SessionDiffTracker {
10
+ originals;
11
+ constructor() {
12
+ this.originals = new Map();
13
+ }
14
+ /**
15
+ * Record the original content of a file before the agent touches it.
16
+ * Only the first call per file path is honoured — subsequent calls are
17
+ * ignored so the "before" state remains the pre-session state.
18
+ */
19
+ recordOriginal(filePath, content) {
20
+ if (!this.originals.has(filePath)) {
21
+ this.originals.set(filePath, { originalContent: content, created: false });
22
+ }
23
+ }
24
+ /**
25
+ * Record that a file was created during this session (it did not exist before).
26
+ */
27
+ recordCreated(filePath) {
28
+ if (!this.originals.has(filePath)) {
29
+ this.originals.set(filePath, { originalContent: null, created: true });
30
+ }
31
+ }
32
+ /**
33
+ * Generate a unified diff for all modified files.
34
+ * Returns an empty string if nothing has changed.
35
+ */
36
+ async generateDiff() {
37
+ const parts = [];
38
+ for (const filePath of this.originals.keys()) {
39
+ const diff = await this.getFileDiff(filePath);
40
+ if (diff) {
41
+ parts.push(diff);
42
+ }
43
+ }
44
+ return parts.join('\n');
45
+ }
46
+ /**
47
+ * Return a list of changed files with their status.
48
+ */
49
+ getChangedFiles() {
50
+ const result = [];
51
+ for (const [filePath, tracked] of this.originals.entries()) {
52
+ if (tracked.created) {
53
+ result.push({ path: filePath, status: 'created' });
54
+ }
55
+ else {
56
+ result.push({ path: filePath, status: 'modified' });
57
+ }
58
+ }
59
+ return result;
60
+ }
61
+ /**
62
+ * Generate a unified diff for a single file.
63
+ * Returns an empty string if the file content is unchanged.
64
+ */
65
+ async getFileDiff(filePath) {
66
+ const tracked = this.originals.get(filePath);
67
+ if (!tracked)
68
+ return '';
69
+ let currentContent;
70
+ try {
71
+ currentContent = await fs.readFile(filePath, 'utf-8');
72
+ }
73
+ catch {
74
+ currentContent = null;
75
+ }
76
+ const originalContent = tracked.originalContent ?? '';
77
+ const newContent = currentContent ?? '';
78
+ if (originalContent === newContent)
79
+ return '';
80
+ const aLabel = tracked.created ? '/dev/null' : `a/${filePath}`;
81
+ const bLabel = currentContent === null ? '/dev/null' : `b/${filePath}`;
82
+ return buildUnifiedDiff(aLabel, bLabel, originalContent, newContent);
83
+ }
84
+ }
85
+ /**
86
+ * Returns the process-level singleton SessionDiffTracker.
87
+ */
88
+ export function getSessionDiffTracker() {
89
+ if (!defaultTracker) {
90
+ defaultTracker = new SessionDiffTracker();
91
+ }
92
+ return defaultTracker;
93
+ }
94
+ // ---------------------------------------------------------------------------
95
+ // Minimal unified diff implementation (no external dependencies)
96
+ // ---------------------------------------------------------------------------
97
+ function buildUnifiedDiff(aLabel, bLabel, oldText, newText) {
98
+ const oldLines = oldText === '' ? [] : oldText.split('\n');
99
+ const newLines = newText === '' ? [] : newText.split('\n');
100
+ const hunks = computeHunks(oldLines, newLines);
101
+ if (hunks.length === 0)
102
+ return '';
103
+ const header = [`--- ${aLabel}`, `+++ ${bLabel}`];
104
+ const body = hunks.map(renderHunk);
105
+ return [...header, ...body].join('\n') + '\n';
106
+ }
107
+ const CONTEXT = 3;
108
+ function computeHunks(oldLines, newLines) {
109
+ // Myers-style LCS diff
110
+ const edit = shortestEditScript(oldLines, newLines);
111
+ // Group edits into hunks with context
112
+ const hunks = [];
113
+ // Build flat edit list
114
+ const ops = [];
115
+ let oi = 0;
116
+ let ni = 0;
117
+ for (const [type, content] of edit) {
118
+ if (type === '=') {
119
+ ops.push({ type: '=', oldIdx: oi, newIdx: ni, content });
120
+ oi++;
121
+ ni++;
122
+ }
123
+ else if (type === '-') {
124
+ ops.push({ type: '-', oldIdx: oi, newIdx: ni, content });
125
+ oi++;
126
+ }
127
+ else {
128
+ ops.push({ type: '+', oldIdx: oi, newIdx: ni, content });
129
+ ni++;
130
+ }
131
+ }
132
+ // Find change ranges
133
+ const changeIndices = ops
134
+ .map((op, i) => (op.type !== '=' ? i : -1))
135
+ .filter((i) => i !== -1);
136
+ if (changeIndices.length === 0)
137
+ return [];
138
+ // Merge ranges with context into hunks
139
+ let start = Math.max(0, changeIndices[0] - CONTEXT);
140
+ let end = Math.min(ops.length - 1, changeIndices[0] + CONTEXT);
141
+ const ranges = [];
142
+ for (let k = 1; k < changeIndices.length; k++) {
143
+ const ci = changeIndices[k];
144
+ if (ci - CONTEXT <= end + 1) {
145
+ end = Math.min(ops.length - 1, ci + CONTEXT);
146
+ }
147
+ else {
148
+ ranges.push([start, end]);
149
+ start = Math.max(0, ci - CONTEXT);
150
+ end = Math.min(ops.length - 1, ci + CONTEXT);
151
+ }
152
+ }
153
+ ranges.push([start, end]);
154
+ for (const [s, e] of ranges) {
155
+ const slice = ops.slice(s, e + 1);
156
+ const oldStart = (slice.find((op) => op.type !== '+')?.oldIdx ?? 0) + 1;
157
+ const newStart = (slice.find((op) => op.type !== '-')?.newIdx ?? 0) + 1;
158
+ const oldCount = slice.filter((op) => op.type !== '+').length;
159
+ const newCount = slice.filter((op) => op.type !== '-').length;
160
+ const header = `@@ -${oldStart},${oldCount} +${newStart},${newCount} @@`;
161
+ const lines = slice.map((op) => {
162
+ if (op.type === '=')
163
+ return ` ${op.content}`;
164
+ if (op.type === '-')
165
+ return `-${op.content}`;
166
+ return `+${op.content}`;
167
+ });
168
+ hunks.push({ header, lines });
169
+ }
170
+ return hunks;
171
+ }
172
+ function renderHunk(hunk) {
173
+ return [hunk.header, ...hunk.lines].join('\n');
174
+ }
175
+ /**
176
+ * Produce a minimal edit script using the Myers diff algorithm.
177
+ * Returns an array of [type, line] tuples where type is '+', '-', or '='.
178
+ */
179
+ function shortestEditScript(oldLines, newLines) {
180
+ const n = oldLines.length;
181
+ const m = newLines.length;
182
+ const max = n + m;
183
+ if (max === 0)
184
+ return [];
185
+ // v[k] stores the furthest-reaching x position for diagonal k
186
+ const v = new Array(2 * max + 1).fill(0);
187
+ const trace = [];
188
+ outer: for (let d = 0; d <= max; d++) {
189
+ trace.push([...v]);
190
+ for (let k = -d; k <= d; k += 2) {
191
+ const ki = k + max;
192
+ let x;
193
+ if (k === -d || (k !== d && v[ki - 1] < v[ki + 1])) {
194
+ x = v[ki + 1];
195
+ }
196
+ else {
197
+ x = v[ki - 1] + 1;
198
+ }
199
+ let y = x - k;
200
+ while (x < n && y < m && oldLines[x] === newLines[y]) {
201
+ x++;
202
+ y++;
203
+ }
204
+ v[ki] = x;
205
+ if (x >= n && y >= m) {
206
+ break outer;
207
+ }
208
+ }
209
+ }
210
+ // Backtrack to reconstruct the edit path
211
+ const edits = [];
212
+ let x = n;
213
+ let y = m;
214
+ for (let d = trace.length - 1; d >= 0 && (x > 0 || y > 0); d--) {
215
+ const vPrev = trace[d];
216
+ const k = x - y;
217
+ const ki = k + max;
218
+ let prevK;
219
+ if (k === -d || (k !== d && vPrev[ki - 1] < vPrev[ki + 1])) {
220
+ prevK = k + 1;
221
+ }
222
+ else {
223
+ prevK = k - 1;
224
+ }
225
+ const prevX = vPrev[prevK + max];
226
+ const prevY = prevX - prevK;
227
+ while (x > prevX + 1 && y > prevY + 1) {
228
+ edits.unshift(['=', oldLines[x - 1]]);
229
+ x--;
230
+ y--;
231
+ }
232
+ if (d > 0) {
233
+ if (x > prevX && y > prevY) {
234
+ edits.unshift(['=', oldLines[x - 1]]);
235
+ x--;
236
+ y--;
237
+ }
238
+ else if (x > prevX) {
239
+ edits.unshift(['-', oldLines[x - 1]]);
240
+ x--;
241
+ }
242
+ else if (y > prevY) {
243
+ edits.unshift(['+', newLines[y - 1]]);
244
+ y--;
245
+ }
246
+ }
247
+ }
248
+ while (x > 0) {
249
+ edits.unshift(['-', oldLines[x - 1]]);
250
+ x--;
251
+ }
252
+ while (y > 0) {
253
+ edits.unshift(['+', newLines[y - 1]]);
254
+ y--;
255
+ }
256
+ return edits;
257
+ }
258
+ //# sourceMappingURL=session-diff.js.map