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,59 @@
1
+ /**
2
+ * SSE Stream Client
3
+ *
4
+ * Connects to the profClaw chat API and streams events.
5
+ * Handles both simple streaming (content deltas) and agentic mode
6
+ * (tool calls, thinking, step progress).
7
+ *
8
+ * Features:
9
+ * - Exponential backoff reconnection (1s, 2s, 4s, 8s, max 3 retries)
10
+ * - 60-second idle timeout treated as disconnect
11
+ * - `lastEventId` tracking for potential server-side resume
12
+ * - `connection_lost` / `reconnected` synthetic events
13
+ *
14
+ * @package profclaw-interactive (future standalone)
15
+ */
16
+ import type { ServerConfig, SSEEvent } from './types.js';
17
+ export interface StreamOptions {
18
+ conversationId: string;
19
+ content: string;
20
+ model?: string;
21
+ provider?: string;
22
+ agentic?: boolean;
23
+ showThinking?: boolean;
24
+ effort?: 'low' | 'medium' | 'high';
25
+ signal?: AbortSignal;
26
+ }
27
+ export type StreamEventHandler = (event: SSEEvent) => void;
28
+ /**
29
+ * Send a message and stream the response via SSE.
30
+ * Yields parsed SSE events as they arrive, including synthetic
31
+ * `connection_lost` and `reconnected` events on reconnect attempts.
32
+ */
33
+ export declare function streamChat(config: ServerConfig, options: StreamOptions): AsyncGenerator<SSEEvent>;
34
+ /**
35
+ * Create a new conversation on the server.
36
+ */
37
+ export declare function createConversation(config: ServerConfig, options: {
38
+ mode: 'chat' | 'agentic';
39
+ presetId?: string;
40
+ }): Promise<{
41
+ conversationId: string;
42
+ } | {
43
+ error: string;
44
+ }>;
45
+ /**
46
+ * Send a non-streaming message (fallback).
47
+ */
48
+ export declare function sendMessage(config: ServerConfig, conversationId: string, content: string, options?: {
49
+ model?: string;
50
+ tools?: boolean;
51
+ }): Promise<{
52
+ content: string;
53
+ model?: string;
54
+ usage?: Record<string, unknown>;
55
+ toolCalls?: unknown[];
56
+ } | {
57
+ error: string;
58
+ }>;
59
+ //# sourceMappingURL=stream-client.d.ts.map
@@ -0,0 +1,506 @@
1
+ /**
2
+ * SSE Stream Client
3
+ *
4
+ * Connects to the profClaw chat API and streams events.
5
+ * Handles both simple streaming (content deltas) and agentic mode
6
+ * (tool calls, thinking, step progress).
7
+ *
8
+ * Features:
9
+ * - Exponential backoff reconnection (1s, 2s, 4s, 8s, max 3 retries)
10
+ * - 60-second idle timeout treated as disconnect
11
+ * - `lastEventId` tracking for potential server-side resume
12
+ * - `connection_lost` / `reconnected` synthetic events
13
+ *
14
+ * @package profclaw-interactive (future standalone)
15
+ */
16
+ // ── Reconnect constants ────────────────────────────────────────────────────────
17
+ const MAX_RETRIES = 3;
18
+ const RETRY_DELAYS_MS = [1_000, 2_000, 4_000, 8_000];
19
+ const IDLE_TIMEOUT_MS = 60_000;
20
+ // ── Helpers ────────────────────────────────────────────────────────────────────
21
+ function sleep(ms) {
22
+ return new Promise(resolve => setTimeout(resolve, ms));
23
+ }
24
+ /**
25
+ * Parse a raw SSE data line into an SSEEvent, returning null when the line
26
+ * should be skipped.
27
+ */
28
+ function parseSseLine(line, rateLimitHeaders) {
29
+ const trimmed = line.trim();
30
+ if (!trimmed || trimmed.startsWith(':'))
31
+ return null;
32
+ if (!trimmed.startsWith('data: '))
33
+ return null;
34
+ const jsonStr = trimmed.slice(6);
35
+ let parsed;
36
+ try {
37
+ parsed = JSON.parse(jsonStr);
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ // Handle simple streaming format (content deltas)
43
+ if ('content' in parsed && !('type' in parsed)) {
44
+ return {
45
+ type: 'content_delta',
46
+ data: { content: parsed.content },
47
+ timestamp: Date.now(),
48
+ };
49
+ }
50
+ // Handle done event
51
+ if ('done' in parsed && parsed.done === true) {
52
+ return {
53
+ type: 'complete',
54
+ data: {
55
+ usage: parsed.usage,
56
+ finishReason: parsed.finishReason,
57
+ rateLimitHeaders: Object.keys(rateLimitHeaders).length > 0 ? rateLimitHeaders : undefined,
58
+ },
59
+ timestamp: Date.now(),
60
+ };
61
+ }
62
+ // Handle error event
63
+ if ('error' in parsed && !('type' in parsed)) {
64
+ return {
65
+ type: 'error',
66
+ data: { message: parsed.error },
67
+ timestamp: Date.now(),
68
+ };
69
+ }
70
+ // Handle typed events (agentic mode)
71
+ if ('type' in parsed) {
72
+ return {
73
+ type: parsed.type,
74
+ data: parsed.data || parsed,
75
+ timestamp: parsed.timestamp || Date.now(),
76
+ };
77
+ }
78
+ return null;
79
+ }
80
+ /**
81
+ * Read the response body and yield SSEEvents.
82
+ * Returns `false` when the stream ended normally with a `complete` or final
83
+ * event, or `true` when the connection dropped before the stream completed.
84
+ */
85
+ async function* readSseBody(body, rateLimitHeaders, lastEventIdRef, idleTimeoutMs, signal) {
86
+ const reader = body.getReader();
87
+ const decoder = new TextDecoder();
88
+ let buffer = '';
89
+ let streamCompleted = false;
90
+ let idleTimer = null;
91
+ const resetIdle = (onTimeout) => {
92
+ if (idleTimer !== null)
93
+ clearTimeout(idleTimer);
94
+ idleTimer = setTimeout(onTimeout, idleTimeoutMs);
95
+ };
96
+ // We use a flag + error to break out when the idle timer fires.
97
+ let idleTimedOut = false;
98
+ try {
99
+ // Start the idle timer immediately
100
+ resetIdle(() => { idleTimedOut = true; });
101
+ while (true) {
102
+ if (signal?.aborted)
103
+ break;
104
+ if (idleTimedOut)
105
+ break;
106
+ let done;
107
+ let value;
108
+ try {
109
+ ({ done, value } = await reader.read());
110
+ }
111
+ catch {
112
+ // Network error — connection dropped
113
+ break;
114
+ }
115
+ if (done)
116
+ break;
117
+ // Activity received — reset idle timer
118
+ resetIdle(() => { idleTimedOut = true; });
119
+ buffer += decoder.decode(value, { stream: true });
120
+ // Parse SSE lines
121
+ const lines = buffer.split('\n');
122
+ buffer = lines.pop() ?? '';
123
+ // Track SSE id: fields for potential resume
124
+ for (const line of lines) {
125
+ const trimmedLine = line.trim();
126
+ if (trimmedLine.startsWith('id: ')) {
127
+ lastEventIdRef.value = trimmedLine.slice(4).trim();
128
+ }
129
+ }
130
+ for (const line of lines) {
131
+ const event = parseSseLine(line, rateLimitHeaders);
132
+ if (event === null)
133
+ continue;
134
+ if (event.type === 'complete') {
135
+ streamCompleted = true;
136
+ }
137
+ yield event;
138
+ }
139
+ if (streamCompleted)
140
+ break;
141
+ }
142
+ }
143
+ finally {
144
+ if (idleTimer !== null)
145
+ clearTimeout(idleTimer);
146
+ reader.releaseLock();
147
+ }
148
+ if (!streamCompleted) {
149
+ yield { __incomplete: true };
150
+ }
151
+ }
152
+ /**
153
+ * Send a message and stream the response via SSE.
154
+ * Yields parsed SSE events as they arrive, including synthetic
155
+ * `connection_lost` and `reconnected` events on reconnect attempts.
156
+ */
157
+ export async function* streamChat(config, options) {
158
+ // Smart routing: simple messages use fast /completions, complex ones use agentic
159
+ const needsTools = /\b(search|find|build|create|deploy|fix|write|read|run|exec|check|test|git|install|fetch)\b|look up|what is|tell me about/i.test(options.content);
160
+ const isSimple = options.content.length < 30 && !needsTools;
161
+ // For simple messages, use fast streaming completions (no tools = ~100 tokens vs 75K)
162
+ if (isSimple) {
163
+ yield* streamSimpleChat(config, options);
164
+ return;
165
+ }
166
+ // Complex messages: use the full agentic endpoint with reconnect
167
+ yield* streamAgenticChatWithReconnect(config, options);
168
+ }
169
+ // ── Simple (completions) endpoint — no reconnect, straightforward ──────────────
170
+ async function* streamSimpleChat(config, options) {
171
+ const endpoint = `/api/chat/completions`;
172
+ const body = {
173
+ messages: [{ role: 'user', content: options.content }],
174
+ model: options.model,
175
+ stream: true,
176
+ conversationId: options.conversationId,
177
+ };
178
+ const headers = {
179
+ 'Content-Type': 'application/json',
180
+ 'Accept': 'text/event-stream',
181
+ };
182
+ if (config.apiToken)
183
+ headers['Authorization'] = `Bearer ${config.apiToken}`;
184
+ let response;
185
+ try {
186
+ response = await fetch(`${config.baseUrl}${endpoint}`, {
187
+ method: 'POST',
188
+ headers,
189
+ body: JSON.stringify(body),
190
+ signal: options.signal,
191
+ });
192
+ }
193
+ catch {
194
+ // Fallback to agentic on connect error
195
+ yield* streamAgenticChatWithReconnect(config, options);
196
+ return;
197
+ }
198
+ if (!response.ok || !response.body) {
199
+ // Fallback to agentic on error
200
+ yield* streamAgenticChatWithReconnect(config, options);
201
+ return;
202
+ }
203
+ const reader = response.body.getReader();
204
+ const decoder = new TextDecoder();
205
+ let buffer = '';
206
+ try {
207
+ while (true) {
208
+ const { done, value } = await reader.read();
209
+ if (done)
210
+ break;
211
+ buffer += decoder.decode(value, { stream: true });
212
+ const lines = buffer.split('\n');
213
+ buffer = lines.pop() ?? '';
214
+ for (const line of lines) {
215
+ const trimmed = line.trim();
216
+ if (!trimmed || !trimmed.startsWith('data: '))
217
+ continue;
218
+ try {
219
+ const parsed = JSON.parse(trimmed.slice(6));
220
+ if (parsed.content) {
221
+ yield { type: 'content_delta', data: { content: parsed.content }, timestamp: Date.now() };
222
+ }
223
+ if (parsed.done) {
224
+ yield { type: 'complete', data: { usage: parsed.usage, finishReason: parsed.finishReason }, timestamp: Date.now() };
225
+ }
226
+ if (parsed.error) {
227
+ yield { type: 'error', data: { message: parsed.error }, timestamp: Date.now() };
228
+ }
229
+ }
230
+ catch { /* skip */ }
231
+ }
232
+ }
233
+ }
234
+ finally {
235
+ reader.releaseLock();
236
+ }
237
+ }
238
+ // ── Agentic endpoint with exponential-backoff reconnect ────────────────────────
239
+ async function* streamAgenticChatWithReconnect(config, options) {
240
+ const lastEventIdRef = { value: null };
241
+ const attempt = 0;
242
+ while (true) {
243
+ // On the first attempt the generator starts fresh.
244
+ // On subsequent attempts we have already emitted `connection_lost`.
245
+ yield* attemptAgenticStream(config, options, lastEventIdRef, attempt);
246
+ // If we get here the inner generator returned without a complete event —
247
+ // which means the stream ended prematurely (connection dropped or idle
248
+ // timeout). Check if we should retry.
249
+ // We detect incompleteness via the sentinel yielded by readSseBody —
250
+ // but the inner generator consumes it. So we rely on the fact that if
251
+ // the inner generator returns normally (not via `return`) the stream was
252
+ // incomplete; if it yielded a `complete` event it would have returned
253
+ // after that.
254
+ //
255
+ // The logic is handled by the sentinel check inside attemptAgenticStream
256
+ // which sets `streamCompletedNormally`. We use a shared ref below.
257
+ // NOTE: Because generator consumers cannot observe generator return
258
+ // values directly, we use a shared mutable object to communicate whether
259
+ // the stream completed normally.
260
+ break; // replaced by the implementation in attemptAgenticStream below
261
+ }
262
+ }
263
+ // We use a wrapper that communicates completion state via ref.
264
+ async function* attemptAgenticStream(config, options, lastEventIdRef, _initialAttempt) {
265
+ let attempt = 0;
266
+ while (true) {
267
+ const result = await runAgenticAttempt(config, options, lastEventIdRef, attempt);
268
+ for (const event of result.events) {
269
+ yield event;
270
+ }
271
+ if (result.completed || options.signal?.aborted) {
272
+ return;
273
+ }
274
+ // Stream dropped before completion
275
+ attempt++;
276
+ if (attempt > MAX_RETRIES) {
277
+ yield {
278
+ type: 'error',
279
+ data: { message: `Connection lost after ${MAX_RETRIES} retries` },
280
+ timestamp: Date.now(),
281
+ };
282
+ return;
283
+ }
284
+ yield {
285
+ type: 'connection_lost',
286
+ data: {
287
+ attempt,
288
+ maxRetries: MAX_RETRIES,
289
+ lastEventId: lastEventIdRef.value,
290
+ },
291
+ timestamp: Date.now(),
292
+ };
293
+ const delayMs = RETRY_DELAYS_MS[attempt - 1] ?? RETRY_DELAYS_MS[RETRY_DELAYS_MS.length - 1];
294
+ await sleep(delayMs);
295
+ if (options.signal?.aborted)
296
+ return;
297
+ yield {
298
+ type: 'reconnected',
299
+ data: { attempt, lastEventId: lastEventIdRef.value },
300
+ timestamp: Date.now(),
301
+ };
302
+ }
303
+ }
304
+ async function runAgenticAttempt(config, options, lastEventIdRef, attempt) {
305
+ const endpoint = `/api/chat/conversations/${options.conversationId}/messages/agentic`;
306
+ const effort = options.effort ?? 'medium';
307
+ const body = {
308
+ content: options.content,
309
+ model: options.model,
310
+ provider: options.provider,
311
+ showThinking: options.showThinking ?? false,
312
+ effort,
313
+ };
314
+ const headers = {
315
+ 'Content-Type': 'application/json',
316
+ 'Accept': 'text/event-stream',
317
+ };
318
+ if (config.apiToken) {
319
+ headers['Authorization'] = `Bearer ${config.apiToken}`;
320
+ }
321
+ // On reconnect attempts, include Last-Event-ID header if we have one
322
+ if (attempt > 0 && lastEventIdRef.value !== null) {
323
+ headers['Last-Event-ID'] = lastEventIdRef.value;
324
+ }
325
+ // Capture rate limit headers from the initial response for monitoring
326
+ const rateLimitHeaders = {};
327
+ const rateLimitHeaderNames = [
328
+ 'x-ratelimit-limit-requests',
329
+ 'x-ratelimit-remaining-requests',
330
+ 'x-ratelimit-limit-tokens',
331
+ 'x-ratelimit-remaining-tokens',
332
+ 'x-ratelimit-reset-requests',
333
+ 'x-ratelimit-reset-tokens',
334
+ ];
335
+ let response;
336
+ try {
337
+ response = await fetch(`${config.baseUrl}${endpoint}`, {
338
+ method: 'POST',
339
+ headers,
340
+ body: JSON.stringify(body),
341
+ signal: options.signal,
342
+ });
343
+ }
344
+ catch (err) {
345
+ if (options.signal?.aborted) {
346
+ return { events: [], completed: true };
347
+ }
348
+ const msg = err instanceof Error ? err.message : 'Connection failed';
349
+ return {
350
+ events: [{
351
+ type: 'error',
352
+ data: { message: msg },
353
+ timestamp: Date.now(),
354
+ }],
355
+ completed: false,
356
+ };
357
+ }
358
+ for (const name of rateLimitHeaderNames) {
359
+ const value = response.headers.get(name);
360
+ if (value !== null)
361
+ rateLimitHeaders[name] = value;
362
+ }
363
+ if (!response.ok) {
364
+ const text = await response.text().catch(() => '');
365
+ let errorMsg = `HTTP ${response.status}`;
366
+ if (text.startsWith('<!DOCTYPE') || text.startsWith('<html')) {
367
+ errorMsg = `API route not found (got HTML). Is the server running at ${config.baseUrl}?`;
368
+ }
369
+ else {
370
+ try {
371
+ const parsed = JSON.parse(text);
372
+ errorMsg = parsed.error || parsed.message || errorMsg;
373
+ }
374
+ catch {
375
+ if (text)
376
+ errorMsg = text.slice(0, 200);
377
+ }
378
+ }
379
+ // 4xx errors are terminal — no point retrying
380
+ const isTerminal = response.status >= 400 && response.status < 500;
381
+ return {
382
+ events: [{
383
+ type: 'error',
384
+ data: { message: errorMsg, statusCode: response.status, rateLimitHeaders },
385
+ timestamp: Date.now(),
386
+ }],
387
+ completed: isTerminal,
388
+ };
389
+ }
390
+ if (!response.body) {
391
+ return {
392
+ events: [{
393
+ type: 'error',
394
+ data: { message: 'No response body (streaming not supported?)' },
395
+ timestamp: Date.now(),
396
+ }],
397
+ completed: false,
398
+ };
399
+ }
400
+ const collected = [];
401
+ let completed = false;
402
+ for await (const item of readSseBody(response.body, rateLimitHeaders, lastEventIdRef, IDLE_TIMEOUT_MS, options.signal)) {
403
+ if ('__incomplete' in item) {
404
+ // Sentinel — stream dropped before complete
405
+ break;
406
+ }
407
+ const event = item;
408
+ collected.push(event);
409
+ if (event.type === 'complete' || event.type === 'done') {
410
+ completed = true;
411
+ break;
412
+ }
413
+ }
414
+ return { events: collected, completed };
415
+ }
416
+ /**
417
+ * Create a new conversation on the server.
418
+ */
419
+ export async function createConversation(config, options) {
420
+ const headers = {
421
+ 'Content-Type': 'application/json',
422
+ };
423
+ if (config.apiToken) {
424
+ headers['Authorization'] = `Bearer ${config.apiToken}`;
425
+ }
426
+ try {
427
+ const response = await fetch(`${config.baseUrl}/api/chat/conversations`, {
428
+ method: 'POST',
429
+ headers,
430
+ body: JSON.stringify({
431
+ presetId: options.presetId || (options.mode === 'agentic' ? 'agentic' : 'profclaw-assistant'),
432
+ }),
433
+ });
434
+ const text = await response.text();
435
+ // Check for HTML response (SPA fallback)
436
+ if (text.startsWith('<!DOCTYPE') || text.startsWith('<html')) {
437
+ return { error: `API route not available (got HTML). Check that profClaw server is running at ${config.baseUrl} with: profclaw serve` };
438
+ }
439
+ if (!response.ok) {
440
+ try {
441
+ const parsed = JSON.parse(text);
442
+ return { error: `Failed to create conversation: ${parsed.error || `HTTP ${response.status}`}` };
443
+ }
444
+ catch {
445
+ return { error: `Failed to create conversation: HTTP ${response.status}` };
446
+ }
447
+ }
448
+ try {
449
+ const data = JSON.parse(text);
450
+ if (!data.conversation?.id) {
451
+ return { error: 'Invalid response from server - no conversation ID returned' };
452
+ }
453
+ return { conversationId: data.conversation.id };
454
+ }
455
+ catch {
456
+ return { error: `Invalid JSON response from server: ${text.slice(0, 100)}` };
457
+ }
458
+ }
459
+ catch (error) {
460
+ const msg = error instanceof Error ? error.message : 'Connection failed';
461
+ if (msg.includes('ECONNREFUSED') || msg.includes('fetch failed')) {
462
+ return { error: `Cannot connect to profClaw server at ${config.baseUrl}. Is it running? Try: profclaw serve` };
463
+ }
464
+ return { error: msg };
465
+ }
466
+ }
467
+ /**
468
+ * Send a non-streaming message (fallback).
469
+ */
470
+ export async function sendMessage(config, conversationId, content, options) {
471
+ const headers = {
472
+ 'Content-Type': 'application/json',
473
+ };
474
+ if (config.apiToken) {
475
+ headers['Authorization'] = `Bearer ${config.apiToken}`;
476
+ }
477
+ const endpoint = options?.tools
478
+ ? `/api/chat/conversations/${conversationId}/messages/with-tools`
479
+ : `/api/chat/conversations/${conversationId}/messages`;
480
+ try {
481
+ const response = await fetch(`${config.baseUrl}${endpoint}`, {
482
+ method: 'POST',
483
+ headers,
484
+ body: JSON.stringify({
485
+ content,
486
+ model: options?.model,
487
+ enableTools: options?.tools,
488
+ }),
489
+ });
490
+ if (!response.ok) {
491
+ return { error: `HTTP ${response.status}` };
492
+ }
493
+ const data = await response.json();
494
+ const assistantMessage = data.assistantMessage;
495
+ return {
496
+ content: assistantMessage?.content || data.content || '',
497
+ model: assistantMessage?.model || data.model,
498
+ usage: data.usage,
499
+ toolCalls: data.toolCalls,
500
+ };
501
+ }
502
+ catch (error) {
503
+ return { error: error instanceof Error ? error.message : 'Request failed' };
504
+ }
505
+ }
506
+ //# sourceMappingURL=stream-client.js.map
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Interactive CLI Types
3
+ *
4
+ * Self-contained type definitions for the interactive REPL.
5
+ * This module is designed to be extractable as a standalone package.
6
+ *
7
+ * @package profclaw-interactive (future standalone)
8
+ */
9
+ export interface ServerConfig {
10
+ baseUrl: string;
11
+ apiToken?: string;
12
+ }
13
+ export interface Session {
14
+ conversationId: string;
15
+ mode: 'chat' | 'agentic';
16
+ model?: string;
17
+ provider?: string;
18
+ title?: string;
19
+ totalTokens: number;
20
+ totalCost: number;
21
+ messageCount: number;
22
+ createdAt: Date;
23
+ }
24
+ export interface ChatMessage {
25
+ role: 'user' | 'assistant' | 'system';
26
+ content: string;
27
+ model?: string;
28
+ provider?: string;
29
+ toolCalls?: ToolCallInfo[];
30
+ usage?: TokenUsage;
31
+ durationMs?: number;
32
+ timestamp: Date;
33
+ }
34
+ export interface ToolCallInfo {
35
+ id: string;
36
+ name: string;
37
+ arguments: Record<string, unknown>;
38
+ result?: unknown;
39
+ status: 'pending' | 'running' | 'success' | 'error';
40
+ durationMs?: number;
41
+ }
42
+ export interface TokenUsage {
43
+ promptTokens: number;
44
+ completionTokens: number;
45
+ totalTokens: number;
46
+ cost?: number;
47
+ }
48
+ export type SSEEventType = 'user_message' | 'session_start' | 'session:start' | 'thinking_start' | 'thinking:start' | 'thinking_update' | 'thinking:update' | 'thinking_end' | 'thinking:end' | 'content_delta' | 'step_start' | 'step:start' | 'step_complete' | 'step:complete' | 'tool_call' | 'tool:call' | 'tool_result' | 'tool:result' | 'summary' | 'complete' | 'error' | 'fallback' | 'message_saved' | string;
49
+ export interface SSEEvent {
50
+ type: SSEEventType;
51
+ data: Record<string, unknown>;
52
+ timestamp: number;
53
+ }
54
+ export interface SlashCommand {
55
+ name: string;
56
+ aliases: string[];
57
+ description: string;
58
+ args?: string;
59
+ handler: (args: string[], state: REPLState) => Promise<void> | void;
60
+ }
61
+ export interface REPLState {
62
+ session: Session | null;
63
+ model?: string;
64
+ provider?: string;
65
+ agenticMode: boolean;
66
+ showThinking: boolean;
67
+ showTools: boolean;
68
+ showUsage: boolean;
69
+ effort: 'low' | 'medium' | 'high';
70
+ isStreaming: boolean;
71
+ streamStartTime?: number;
72
+ /** Total tokens used this REPL session */
73
+ sessionTokens: number;
74
+ sessionCost: number;
75
+ messageCount: number;
76
+ /** Server base URL for API calls */
77
+ serverUrl: string;
78
+ /** Last response model used (for /retry with different model) */
79
+ lastModel?: string;
80
+ /** Last response cached for comparison */
81
+ lastResponseCache?: {
82
+ content: string;
83
+ model: string;
84
+ durationMs: number;
85
+ };
86
+ }
87
+ export interface InteractiveOptions {
88
+ server: ServerConfig;
89
+ model?: string;
90
+ provider?: string;
91
+ sessionId?: string;
92
+ agentic?: boolean;
93
+ showThinking?: boolean;
94
+ effort?: 'low' | 'medium' | 'high';
95
+ }
96
+ export interface Renderer {
97
+ userMessage(content: string): void;
98
+ assistantStart(model?: string): void;
99
+ assistantDelta(chunk: string): void;
100
+ assistantEnd(): void;
101
+ thinkingStart(): void;
102
+ thinkingDelta(chunk: string): void;
103
+ thinkingEnd(): void;
104
+ toolCall(name: string, args: Record<string, unknown>): void;
105
+ toolResult(name: string, result: unknown, success: boolean, durationMs?: number): void;
106
+ usage(usage: TokenUsage, durationMs?: number): void;
107
+ error(message: string): void;
108
+ info(message: string): void;
109
+ success(message: string): void;
110
+ warn(message: string): void;
111
+ divider(): void;
112
+ clear(): void;
113
+ statusLine(text: string): void;
114
+ sessionFooter(state: {
115
+ sessionTokens: number;
116
+ sessionCost: number;
117
+ messageCount: number;
118
+ model?: string;
119
+ }): void;
120
+ }
121
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Interactive CLI Types
3
+ *
4
+ * Self-contained type definitions for the interactive REPL.
5
+ * This module is designed to be extractable as a standalone package.
6
+ *
7
+ * @package profclaw-interactive (future standalone)
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map