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,361 @@
1
+ /**
2
+ * Context Compactor
3
+ *
4
+ * Compresses old conversation turns into a structured markdown summary when
5
+ * the estimated token count crosses a configurable threshold.
6
+ *
7
+ * Two modes:
8
+ * - Local heuristic (default): pure extraction, no LLM calls.
9
+ * - LLM-powered (opt-in): uses an injected apiCall function to produce a
10
+ * richer natural-language summary.
11
+ */
12
+ // ─── Internals ────────────────────────────────────────────────────────────────
13
+ const DEFAULT_CONFIG = {
14
+ maxContextTokens: 100_000,
15
+ compactionThreshold: 70_000,
16
+ preserveRecentTurns: 5,
17
+ summaryMaxTokens: 2_000,
18
+ };
19
+ /** Rough character-to-token ratio used throughout (4 chars ≈ 1 token). */
20
+ const CHARS_PER_TOKEN = 4;
21
+ // ─── Helper utilities ─────────────────────────────────────────────────────────
22
+ function messageToText(message) {
23
+ if (typeof message.content === "string") {
24
+ return message.content;
25
+ }
26
+ if (Array.isArray(message.content)) {
27
+ return message.content
28
+ .map((part) => {
29
+ if (typeof part === "string")
30
+ return part;
31
+ // TextPart
32
+ if (typeof part === "object" &&
33
+ part !== null &&
34
+ "type" in part &&
35
+ part.type === "text" &&
36
+ "text" in part) {
37
+ return String(part.text);
38
+ }
39
+ // ToolCallPart
40
+ if (typeof part === "object" &&
41
+ part !== null &&
42
+ "type" in part &&
43
+ part.type === "tool-call") {
44
+ const tc = part;
45
+ return `[tool_call: ${tc.toolName}(${JSON.stringify(tc.args ?? {})})]`;
46
+ }
47
+ // ToolResultPart
48
+ if (typeof part === "object" &&
49
+ part !== null &&
50
+ "type" in part &&
51
+ part.type === "tool-result") {
52
+ const tr = part;
53
+ return `[tool_result: ${tr.toolName ?? "unknown"} → ${JSON.stringify(tr.result ?? null)}]`;
54
+ }
55
+ return JSON.stringify(part);
56
+ })
57
+ .join(" ");
58
+ }
59
+ return "";
60
+ }
61
+ /** Extract file paths that were read or written during a set of messages. */
62
+ function extractFilePaths(messages) {
63
+ const paths = new Set();
64
+ const filePattern = /(?:read|write|edit|create|modify)\s+([`"']?[\w./\-_]+\.[a-zA-Z]+[`"']?)/gi;
65
+ for (const msg of messages) {
66
+ const text = messageToText(msg);
67
+ let match;
68
+ while ((match = filePattern.exec(text)) !== null) {
69
+ paths.add(match[1].replace(/[`"']/g, ""));
70
+ }
71
+ }
72
+ return Array.from(paths);
73
+ }
74
+ function extractToolCalls(messages) {
75
+ const calls = [];
76
+ for (const msg of messages) {
77
+ if (!Array.isArray(msg.content))
78
+ continue;
79
+ for (const part of msg.content) {
80
+ if (typeof part !== "object" ||
81
+ part === null ||
82
+ !("type" in part)) {
83
+ continue;
84
+ }
85
+ const typed = part;
86
+ if (typed.type === "tool-call") {
87
+ const tc = part;
88
+ const argKeys = Object.keys(tc.args ?? {}).slice(0, 3).join(", ");
89
+ calls.push({
90
+ name: tc.toolName,
91
+ argsSummary: argKeys ? `{${argKeys}}` : "(no args)",
92
+ outcome: "called",
93
+ });
94
+ }
95
+ if (typed.type === "tool-result") {
96
+ const tr = part;
97
+ const last = [...calls].reverse().find((c) => c.name === (tr.toolName ?? ""));
98
+ const resultText = typeof tr.result === "string"
99
+ ? tr.result.slice(0, 120)
100
+ : JSON.stringify(tr.result ?? null).slice(0, 120);
101
+ if (last) {
102
+ last.outcome = tr.isError === true ? `error: ${resultText}` : `ok: ${resultText}`;
103
+ }
104
+ else {
105
+ calls.push({
106
+ name: tr.toolName ?? "unknown",
107
+ argsSummary: "",
108
+ outcome: tr.isError === true ? `error: ${resultText}` : `ok: ${resultText}`,
109
+ });
110
+ }
111
+ }
112
+ }
113
+ }
114
+ return calls;
115
+ }
116
+ /** Extract the apparent user goals from user-role messages. */
117
+ function extractUserGoals(messages) {
118
+ const goals = [];
119
+ for (const msg of messages) {
120
+ if (msg.role !== "user")
121
+ continue;
122
+ const text = messageToText(msg).trim();
123
+ if (text.length > 0) {
124
+ // Keep only the first 200 chars per turn to stay concise
125
+ goals.push(text.slice(0, 200) + (text.length > 200 ? "…" : ""));
126
+ }
127
+ }
128
+ return goals;
129
+ }
130
+ /** Build a structured markdown summary capped at approximately maxTokens. */
131
+ function buildSummary(messages, maxTokens) {
132
+ const maxChars = maxTokens * CHARS_PER_TOKEN;
133
+ const userGoals = extractUserGoals(messages);
134
+ const toolCalls = extractToolCalls(messages);
135
+ const filePaths = extractFilePaths(messages);
136
+ const lines = [
137
+ "# Conversation Summary (compacted context)",
138
+ "",
139
+ "## User Requests / Goals",
140
+ ];
141
+ if (userGoals.length > 0) {
142
+ for (const goal of userGoals) {
143
+ lines.push(`- ${goal}`);
144
+ }
145
+ }
146
+ else {
147
+ lines.push("- (no explicit user messages in compacted range)");
148
+ }
149
+ lines.push("", "## Tool Calls & Outcomes");
150
+ if (toolCalls.length > 0) {
151
+ for (const tc of toolCalls) {
152
+ lines.push(`- **${tc.name}** ${tc.argsSummary} → ${tc.outcome}`);
153
+ }
154
+ }
155
+ else {
156
+ lines.push("- (no tool calls in compacted range)");
157
+ }
158
+ lines.push("", "## Files Read / Written / Modified");
159
+ if (filePaths.length > 0) {
160
+ for (const fp of filePaths) {
161
+ lines.push(`- \`${fp}\``);
162
+ }
163
+ }
164
+ else {
165
+ lines.push("- (no file operations detected)");
166
+ }
167
+ lines.push("", "## Key Decisions");
168
+ // Look for assistant messages that contain decision-like keywords
169
+ const decisions = [];
170
+ for (const msg of messages) {
171
+ if (msg.role !== "assistant")
172
+ continue;
173
+ const text = messageToText(msg).trim();
174
+ if (/decided|chosen|using|selected|approach|strategy|plan/i.test(text) &&
175
+ text.length > 20) {
176
+ decisions.push(text.slice(0, 200) + (text.length > 200 ? "…" : ""));
177
+ }
178
+ }
179
+ if (decisions.length > 0) {
180
+ for (const d of decisions) {
181
+ lines.push(`- ${d}`);
182
+ }
183
+ }
184
+ else {
185
+ lines.push("- (no explicit decisions recorded)");
186
+ }
187
+ const full = lines.join("\n");
188
+ // Trim to maxChars if necessary
189
+ return full.length > maxChars ? full.slice(0, maxChars) + "\n…(truncated)" : full;
190
+ }
191
+ // ─── ContextCompactor ─────────────────────────────────────────────────────────
192
+ export class ContextCompactor {
193
+ config;
194
+ constructor(config) {
195
+ this.config = { ...DEFAULT_CONFIG, ...config };
196
+ }
197
+ /**
198
+ * Estimate the token count for a list of messages using the 4-chars-per-token
199
+ * heuristic.
200
+ */
201
+ estimateTokens(messages) {
202
+ let totalChars = 0;
203
+ for (const msg of messages) {
204
+ totalChars += messageToText(msg).length;
205
+ // Add a small overhead per message for role + formatting
206
+ totalChars += 10;
207
+ }
208
+ return Math.ceil(totalChars / CHARS_PER_TOKEN);
209
+ }
210
+ /**
211
+ * Compact the message list if it exceeds the compaction threshold.
212
+ *
213
+ * Strategy:
214
+ * 1. Identify the most-recent N turns to preserve verbatim.
215
+ * 2. Summarise all older messages into a single system-role summary message.
216
+ * 3. Return the summary + preserved recent messages.
217
+ *
218
+ * When `config.useLLM` is true and `apiCall` is provided, delegates to
219
+ * `compactWithLLM()` for a richer natural-language summary.
220
+ * Falls back to local heuristic summarisation if the LLM call fails.
221
+ */
222
+ async compact(messages, apiCall) {
223
+ if (this.config.useLLM && apiCall !== undefined) {
224
+ try {
225
+ return await this.compactWithLLM(messages, apiCall);
226
+ }
227
+ catch (err) {
228
+ console.error("[ContextCompactor] LLM compaction failed, falling back to local:", err);
229
+ // Fall through to local compaction below
230
+ }
231
+ }
232
+ return this._compactLocal(messages);
233
+ }
234
+ /**
235
+ * Compact using an injected LLM call for richer summarisation.
236
+ *
237
+ * The `apiCall` function is supplied by the caller so this class remains
238
+ * free of any specific API client dependency.
239
+ */
240
+ async compactWithLLM(messages, apiCall) {
241
+ const originalTokens = this.estimateTokens(messages);
242
+ if (originalTokens < this.config.compactionThreshold) {
243
+ return {
244
+ messages,
245
+ compacted: false,
246
+ originalTokens,
247
+ compactedTokens: originalTokens,
248
+ turnsCompacted: 0,
249
+ };
250
+ }
251
+ const systemMessages = messages.filter((m) => m.role === "system");
252
+ const conversational = messages.filter((m) => m.role !== "system");
253
+ const turnsToPreserve = this.config.preserveRecentTurns * 2;
254
+ const splitAt = Math.max(0, conversational.length - turnsToPreserve);
255
+ const toCompact = conversational.slice(0, splitAt);
256
+ const toPreserve = conversational.slice(splitAt);
257
+ const turnsCompacted = toCompact.length;
258
+ if (turnsCompacted === 0) {
259
+ return {
260
+ messages,
261
+ compacted: false,
262
+ originalTokens,
263
+ compactedTokens: originalTokens,
264
+ turnsCompacted: 0,
265
+ };
266
+ }
267
+ // Build a transcript of the messages to be compacted
268
+ const transcript = toCompact
269
+ .map((m) => {
270
+ const role = m.role.toUpperCase();
271
+ const text = messageToText(m);
272
+ return `[${role}]: ${text}`;
273
+ })
274
+ .join("\n\n");
275
+ const prompt = [
276
+ "Summarize this conversation concisely. Include:",
277
+ "- Key decisions made",
278
+ "- Files modified and why",
279
+ "- Tool results and outcomes",
280
+ "- Current task status",
281
+ "Keep it under 500 words.",
282
+ "",
283
+ "--- CONVERSATION START ---",
284
+ transcript,
285
+ "--- CONVERSATION END ---",
286
+ ].join("\n");
287
+ const llmSummary = await apiCall(prompt);
288
+ const summaryText = `# Conversation Summary (LLM-compacted context)\n\n${llmSummary}`;
289
+ const summaryMessage = {
290
+ role: "system",
291
+ content: summaryText,
292
+ };
293
+ const compactedMessages = [
294
+ ...systemMessages,
295
+ summaryMessage,
296
+ ...toPreserve,
297
+ ];
298
+ const compactedTokens = this.estimateTokens(compactedMessages);
299
+ return {
300
+ messages: compactedMessages,
301
+ compacted: true,
302
+ originalTokens,
303
+ compactedTokens,
304
+ turnsCompacted,
305
+ };
306
+ }
307
+ /** Local heuristic compaction (no LLM). */
308
+ _compactLocal(messages) {
309
+ const originalTokens = this.estimateTokens(messages);
310
+ if (originalTokens < this.config.compactionThreshold) {
311
+ return {
312
+ messages,
313
+ compacted: false,
314
+ originalTokens,
315
+ compactedTokens: originalTokens,
316
+ turnsCompacted: 0,
317
+ };
318
+ }
319
+ // Separate system messages (always kept verbatim at the front) from the
320
+ // conversational messages that can be compacted.
321
+ const systemMessages = messages.filter((m) => m.role === "system");
322
+ const conversational = messages.filter((m) => m.role !== "system");
323
+ // A "turn" is a contiguous user+assistant exchange. For simplicity we treat
324
+ // each individual message as one turn unit here; the preserve count is in
325
+ // terms of individual messages (not user+assistant pairs).
326
+ const turnsToPreserve = this.config.preserveRecentTurns * 2; // user + assistant per turn
327
+ const splitAt = Math.max(0, conversational.length - turnsToPreserve);
328
+ const toCompact = conversational.slice(0, splitAt);
329
+ const toPreserve = conversational.slice(splitAt);
330
+ const turnsCompacted = toCompact.length;
331
+ if (turnsCompacted === 0) {
332
+ // Nothing old enough to compact
333
+ return {
334
+ messages,
335
+ compacted: false,
336
+ originalTokens,
337
+ compactedTokens: originalTokens,
338
+ turnsCompacted: 0,
339
+ };
340
+ }
341
+ const summaryText = buildSummary(toCompact, this.config.summaryMaxTokens);
342
+ const summaryMessage = {
343
+ role: "system",
344
+ content: summaryText,
345
+ };
346
+ const compactedMessages = [
347
+ ...systemMessages,
348
+ summaryMessage,
349
+ ...toPreserve,
350
+ ];
351
+ const compactedTokens = this.estimateTokens(compactedMessages);
352
+ return {
353
+ messages: compactedMessages,
354
+ compacted: true,
355
+ originalTokens,
356
+ compactedTokens,
357
+ turnsCompacted,
358
+ };
359
+ }
360
+ }
361
+ //# sourceMappingURL=context-compactor.js.map
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Conversation Branching
3
+ *
4
+ * Allows forking a conversation at any turn to explore alternative paths.
5
+ * Branches are persisted to .profclaw/branches/branches.json.
6
+ * The transcript for the parent conversation is read from the existing
7
+ * TranscriptStore (JSONL files at .profclaw/transcripts/).
8
+ */
9
+ export interface Branch {
10
+ id: string;
11
+ parentId: string;
12
+ forkTurnIndex: number;
13
+ title?: string;
14
+ createdAt: number;
15
+ }
16
+ interface BranchMessage {
17
+ role: string;
18
+ content: string;
19
+ }
20
+ export declare class ConversationBrancher {
21
+ private branches;
22
+ private branchDir;
23
+ private transcriptStore;
24
+ constructor(projectRoot?: string);
25
+ /**
26
+ * Fork a conversation at a specific turn index.
27
+ * The new Branch records which turn we branched from so the caller
28
+ * can replay context up to that point.
29
+ */
30
+ fork(conversationId: string, turnIndex: number, title?: string): Branch;
31
+ /**
32
+ * List all branches whose parentId matches `conversationId`,
33
+ * sorted newest first.
34
+ */
35
+ listBranches(conversationId: string): Branch[];
36
+ /**
37
+ * Return the messages from the parent conversation up to (and including)
38
+ * `branch.forkTurnIndex`. Only user/assistant entries are included.
39
+ *
40
+ * "Turn" here means a user+assistant exchange pair, so turn N covers
41
+ * transcript entries 0..2N+1. We expose the raw forkTurnIndex as a
42
+ * transcript entry index for simplicity.
43
+ */
44
+ getBaseMessages(branch: Branch): BranchMessage[];
45
+ save(): void;
46
+ load(): void;
47
+ private ensureDir;
48
+ private indexPath;
49
+ }
50
+ /**
51
+ * Returns the shared singleton ConversationBrancher instance.
52
+ */
53
+ export declare function getConversationBrancher(): ConversationBrancher;
54
+ export {};
55
+ //# sourceMappingURL=conversation-branch.d.ts.map
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Conversation Branching
3
+ *
4
+ * Allows forking a conversation at any turn to explore alternative paths.
5
+ * Branches are persisted to .profclaw/branches/branches.json.
6
+ * The transcript for the parent conversation is read from the existing
7
+ * TranscriptStore (JSONL files at .profclaw/transcripts/).
8
+ */
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ import { randomUUID } from 'crypto';
12
+ import { TranscriptStore } from './transcript.js';
13
+ // ── Singleton ─────────────────────────────────────────────────────────────────
14
+ let _instance = null;
15
+ // ── Class ─────────────────────────────────────────────────────────────────────
16
+ export class ConversationBrancher {
17
+ branches;
18
+ branchDir;
19
+ transcriptStore;
20
+ constructor(projectRoot) {
21
+ const root = projectRoot ?? process.cwd();
22
+ this.branchDir = path.join(root, '.profclaw', 'branches');
23
+ this.branches = new Map();
24
+ this.transcriptStore = new TranscriptStore(root);
25
+ this.load();
26
+ }
27
+ // ── Public API ──────────────────────────────────────────────────────────────
28
+ /**
29
+ * Fork a conversation at a specific turn index.
30
+ * The new Branch records which turn we branched from so the caller
31
+ * can replay context up to that point.
32
+ */
33
+ fork(conversationId, turnIndex, title) {
34
+ const branch = {
35
+ id: randomUUID(),
36
+ parentId: conversationId,
37
+ forkTurnIndex: turnIndex,
38
+ title,
39
+ createdAt: Date.now(),
40
+ };
41
+ this.branches.set(branch.id, branch);
42
+ this.save();
43
+ return branch;
44
+ }
45
+ /**
46
+ * List all branches whose parentId matches `conversationId`,
47
+ * sorted newest first.
48
+ */
49
+ listBranches(conversationId) {
50
+ return Array.from(this.branches.values())
51
+ .filter(b => b.parentId === conversationId)
52
+ .sort((a, b) => b.createdAt - a.createdAt);
53
+ }
54
+ /**
55
+ * Return the messages from the parent conversation up to (and including)
56
+ * `branch.forkTurnIndex`. Only user/assistant entries are included.
57
+ *
58
+ * "Turn" here means a user+assistant exchange pair, so turn N covers
59
+ * transcript entries 0..2N+1. We expose the raw forkTurnIndex as a
60
+ * transcript entry index for simplicity.
61
+ */
62
+ getBaseMessages(branch) {
63
+ const entries = this.transcriptStore.getSession(branch.parentId);
64
+ const conversationEntries = entries.filter(e => e.type === 'user' || e.type === 'assistant');
65
+ const sliced = conversationEntries.slice(0, branch.forkTurnIndex + 1);
66
+ return sliced.map(e => ({
67
+ role: e.type === 'user' ? 'user' : 'assistant',
68
+ content: e.content,
69
+ }));
70
+ }
71
+ // ── Persistence ─────────────────────────────────────────────────────────────
72
+ save() {
73
+ this.ensureDir();
74
+ const filePath = this.indexPath();
75
+ const data = Array.from(this.branches.values());
76
+ try {
77
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
78
+ }
79
+ catch (err) {
80
+ console.error('[ConversationBrancher] Failed to save branches:', err);
81
+ }
82
+ }
83
+ load() {
84
+ const filePath = this.indexPath();
85
+ if (!fs.existsSync(filePath))
86
+ return;
87
+ try {
88
+ const raw = fs.readFileSync(filePath, 'utf8');
89
+ const data = JSON.parse(raw);
90
+ this.branches = new Map(data.map(b => [b.id, b]));
91
+ }
92
+ catch (err) {
93
+ console.error('[ConversationBrancher] Failed to load branches:', err);
94
+ }
95
+ }
96
+ // ── Private helpers ─────────────────────────────────────────────────────────
97
+ ensureDir() {
98
+ if (!fs.existsSync(this.branchDir)) {
99
+ fs.mkdirSync(this.branchDir, { recursive: true });
100
+ }
101
+ }
102
+ indexPath() {
103
+ return path.join(this.branchDir, 'branches.json');
104
+ }
105
+ }
106
+ /**
107
+ * Returns the shared singleton ConversationBrancher instance.
108
+ */
109
+ export function getConversationBrancher() {
110
+ if (!_instance) {
111
+ _instance = new ConversationBrancher();
112
+ }
113
+ return _instance;
114
+ }
115
+ //# sourceMappingURL=conversation-branch.js.map
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Error Recovery Advisor
3
+ *
4
+ * Analyzes API errors and returns an ordered list of recovery actions.
5
+ * The caller drives the actual recovery; this module is purely advisory.
6
+ */
7
+ export interface RecoveryAction {
8
+ type: 'retry' | 'switch_provider' | 'switch_model' | 'reduce_context' | 'wait' | 'abort';
9
+ description: string;
10
+ provider?: string;
11
+ model?: string;
12
+ waitMs?: number;
13
+ }
14
+ export interface ErrorInput {
15
+ code?: string;
16
+ message: string;
17
+ provider: string;
18
+ model: string;
19
+ statusCode?: number;
20
+ }
21
+ export interface RecoveryContext {
22
+ availableProviders: string[];
23
+ retryCount: number;
24
+ maxRetries: number;
25
+ }
26
+ export declare class ErrorRecoveryAdvisor {
27
+ /**
28
+ * Analyze an error and return an ordered list of recommended recovery actions.
29
+ *
30
+ * Rules applied (in priority order):
31
+ * 401 / 403 → abort (auth errors cannot be retried)
32
+ * 429 (rate limit) → wait + switch_provider (if available) + retry
33
+ * 503 (server overloaded) → wait + retry
34
+ * 400 (bad request) → reduce_context or switch_model
35
+ * ECONNREFUSED / ENOTFOUND → switch_provider
36
+ * timeout → wait briefly + retry with reduce_context hint
37
+ * context_length_exceeded → reduce_context + switch_model
38
+ * content filter → switch_model
39
+ * generic retry-eligible → retry (up to maxRetries)
40
+ */
41
+ advise(error: ErrorInput, context: RecoveryContext): RecoveryAction[];
42
+ }
43
+ export declare function getErrorRecoveryAdvisor(): ErrorRecoveryAdvisor;
44
+ //# sourceMappingURL=error-recovery.d.ts.map