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,555 @@
1
+ /**
2
+ * Terminal Renderer - Polished CLI Output
3
+ *
4
+ * Design inspired by Claude Code, OpenClaw, Charm.sh, and clig.dev:
5
+ *
6
+ * - Response text indented 2 spaces for visual separation from prompt
7
+ * - Tool calls framed with thin Unicode box-drawing lines
8
+ * - Markdown rendered inline (bold, code, lists, headings, quotes)
9
+ * - Streaming markdown: lines formatted as they complete
10
+ * - Syntax highlighting for common languages in code blocks
11
+ * - Word-wrap respects terminal width
12
+ * - Color used intentionally: cyan for links, gold for code, dim for chrome
13
+ * - Progress within 100ms (spinner starts immediately)
14
+ * - Errors are actionable, not cryptic
15
+ * - Respects NO_COLOR env var
16
+ * - Cost/time shown only when meaningful
17
+ *
18
+ * @package profclaw-interactive (future standalone)
19
+ */
20
+ import chalk from 'chalk';
21
+ // Unicode box-drawing and symbols
22
+ const H_LINE = '\u2500'; // -
23
+ const V_LINE = '\u2502'; // |
24
+ const T_LEFT = '\u251c'; // |-
25
+ const B_LEFT = '\u2514'; // |_
26
+ const DOT = '\u00b7'; // .
27
+ const ARROW = '\u25b8'; // >
28
+ const CHECK = '\u2713'; // v
29
+ const CROSS = '\u2717'; // x
30
+ const CIRCLE = '\u25cf'; // o
31
+ const GEAR = '\u2699'; // gear
32
+ const ELLIP = '\u2026'; // ...
33
+ const LINK_ICON = '\u2197'; // arrow NE (link indicator)
34
+ // Respect NO_COLOR (clig.dev recommendation)
35
+ const noColor = !!process.env.NO_COLOR;
36
+ // Get terminal width
37
+ function getWidth() {
38
+ return process.stdout.columns || 80;
39
+ }
40
+ // Strip ANSI escape sequences for measuring visible length
41
+ function stripAnsi(str) {
42
+ return str.replace(/\x1b\[[0-9;]*m/g, '');
43
+ }
44
+ // Themed colors (OpenClaw-inspired palette, dark mode focused)
45
+ const theme = {
46
+ gold: noColor ? (s) => s : chalk.hex('#F6C453'),
47
+ mint: noColor ? (s) => s : chalk.hex('#7DD3A5'),
48
+ coral: noColor ? (s) => s : chalk.hex('#F97066'),
49
+ cream: noColor ? (s) => s : chalk.hex('#E8E3D5'),
50
+ code: noColor ? (s) => s : chalk.hex('#F0C987'),
51
+ link: noColor ? (s) => s : chalk.hex('#8CC8FF'),
52
+ border: noColor ? (s) => s : chalk.hex('#3C414B'),
53
+ dim: noColor ? (s) => s : chalk.dim,
54
+ bold: noColor ? (s) => s : chalk.bold,
55
+ italic: noColor ? (s) => s : chalk.italic,
56
+ // Syntax highlighting colors
57
+ keyword: noColor ? (s) => s : chalk.hex('#C792EA'),
58
+ string: noColor ? (s) => s : chalk.hex('#C3E88D'),
59
+ number: noColor ? (s) => s : chalk.hex('#F78C6C'),
60
+ comment: noColor ? (s) => s : chalk.hex('#546E7A'),
61
+ func: noColor ? (s) => s : chalk.hex('#82AAFF'),
62
+ type: noColor ? (s) => s : chalk.hex('#FFCB6B'),
63
+ };
64
+ // Word-wrap a single visible line at terminal width
65
+ function wrapText(text, indent) {
66
+ const maxWidth = getWidth() - indent - 2; // 2 for safety margin
67
+ if (maxWidth <= 20)
68
+ return text; // Don't wrap on tiny terminals
69
+ const visibleLen = stripAnsi(text).length;
70
+ if (visibleLen <= maxWidth)
71
+ return text;
72
+ // Simple word-boundary wrap for plain text
73
+ const words = text.split(/(\s+)/);
74
+ const lines = [];
75
+ let currentLine = '';
76
+ let currentLen = 0;
77
+ for (const word of words) {
78
+ const wordLen = stripAnsi(word).length;
79
+ if (currentLen + wordLen > maxWidth && currentLine.length > 0) {
80
+ lines.push(currentLine);
81
+ currentLine = word.trimStart();
82
+ currentLen = stripAnsi(currentLine).length;
83
+ }
84
+ else {
85
+ currentLine += word;
86
+ currentLen += wordLen;
87
+ }
88
+ }
89
+ if (currentLine)
90
+ lines.push(currentLine);
91
+ const pad = ' '.repeat(indent);
92
+ return lines.join(`\n${pad}`);
93
+ }
94
+ // Draw separator lines
95
+ function separator(label) {
96
+ const w = Math.min(getWidth() - 4, 68);
97
+ const line = theme.border(H_LINE.repeat(w));
98
+ if (!label)
99
+ return ` ${line}`;
100
+ const padded = ` ${label} `;
101
+ const plainLen = stripAnsi(padded).length;
102
+ const side = Math.max(2, Math.floor((w - plainLen) / 2));
103
+ const right = Math.max(2, w - side - plainLen);
104
+ return ` ${theme.border(H_LINE.repeat(side))}${padded}${theme.border(H_LINE.repeat(right))}`;
105
+ }
106
+ // Syntax highlighting for code blocks (built-in, no external deps)
107
+ const JS_KEYWORDS = /\b(const|let|var|function|async|await|return|if|else|for|while|do|switch|case|break|continue|try|catch|finally|throw|new|delete|typeof|instanceof|import|export|from|default|class|extends|super|this|yield|of|in|static|get|set|enum|interface|type|implements|declare|abstract|readonly|as|is|keyof|infer|satisfies)\b/g;
108
+ const PY_KEYWORDS = /\b(def|class|if|elif|else|for|while|try|except|finally|with|as|import|from|return|yield|raise|pass|break|continue|and|or|not|in|is|lambda|global|nonlocal|True|False|None|async|await|self)\b/g;
109
+ const COMMON_TYPES = /\b(string|number|boolean|void|null|undefined|any|never|unknown|object|Array|Map|Set|Promise|Record|Partial|Required|Readonly|Pick|Omit|int|float|str|bool|list|dict|tuple)\b/g;
110
+ export function highlightCode(line, lang) {
111
+ if (noColor)
112
+ return line;
113
+ let result = line;
114
+ // Comments (single-line)
115
+ const commentMatch = result.match(/^(\s*)(\/\/.*|#.*)$/);
116
+ if (commentMatch) {
117
+ return commentMatch[1] + theme.comment(commentMatch[2]);
118
+ }
119
+ // Strings (simple - single/double/backtick quoted)
120
+ result = result.replace(/(["'`])(?:(?!\1|\\).|\\.)*?\1/g, (m) => theme.string(m));
121
+ // Numbers
122
+ result = result.replace(/\b(\d+\.?\d*)\b/g, (m) => theme.number(m));
123
+ // Keywords based on language
124
+ const isPython = lang === 'python' || lang === 'py';
125
+ const keywordRe = isPython ? PY_KEYWORDS : JS_KEYWORDS;
126
+ result = result.replace(keywordRe, (m) => theme.keyword(m));
127
+ // Types
128
+ result = result.replace(COMMON_TYPES, (m) => theme.type(m));
129
+ // Function calls
130
+ result = result.replace(/\b([a-zA-Z_]\w*)\s*\(/g, (_, name) => theme.func(name) + '(');
131
+ return result;
132
+ }
133
+ // Link rendering constants
134
+ const LINK_BRACKET_L = '\u276a'; // box bracket left (heavy)
135
+ const LINK_BRACKET_R = '\u276b'; // box bracket right (heavy)
136
+ /**
137
+ * OSC 8 clickable hyperlink for terminals that support it.
138
+ * Format: ESC ] 8 ; params ; uri ST text ESC ] 8 ; ; ST
139
+ * Supported: iTerm2, Windows Terminal, GNOME Terminal, Konsole, foot, WezTerm, etc.
140
+ * Falls back to plain text + URL for non-TTY or NO_COLOR.
141
+ */
142
+ function hyperlink(url, displayText) {
143
+ // Ensure full URL
144
+ const fullUrl = url.startsWith('http') ? url : `https://${url}`;
145
+ if (noColor || !process.stdout.isTTY)
146
+ return displayText;
147
+ return `\x1b]8;;${fullUrl}\x07${displayText}\x1b]8;;\x07`;
148
+ }
149
+ /** Extract readable domain + path from a URL */
150
+ function shortDomain(url) {
151
+ try {
152
+ const fullUrl = url.startsWith('http') ? url : `https://${url}`;
153
+ const parsed = new URL(fullUrl);
154
+ const host = parsed.hostname.replace(/^www\./, '');
155
+ const path = parsed.pathname;
156
+ if (path && path !== '/') {
157
+ // Shorten long paths: show first + last segment
158
+ const segments = path.split('/').filter(Boolean);
159
+ if (segments.length > 2) {
160
+ return `${host}/${segments[0]}/${ELLIP}/${segments[segments.length - 1]}`;
161
+ }
162
+ if (path.length < 40)
163
+ return `${host}${path}`;
164
+ return `${host}/${segments[0]}/${ELLIP}`;
165
+ }
166
+ return host;
167
+ }
168
+ catch {
169
+ return url.length > 40 ? url.slice(0, 37) + ELLIP : url;
170
+ }
171
+ }
172
+ /**
173
+ * Render a link with a clear visual box treatment.
174
+ * Output: ` [link icon] Label domain.com/path `
175
+ * The entire label is an OSC 8 clickable hyperlink in supporting terminals.
176
+ */
177
+ function renderLink(label, url) {
178
+ const domain = shortDomain(url);
179
+ // Clickable label text
180
+ const styledLabel = hyperlink(url, theme.link(chalk.bold.underline(label)));
181
+ // Domain hint - dimmed, with link arrow icon
182
+ const domainHint = theme.dim(`${LINK_ICON} ${domain}`);
183
+ // Visual bracket treatment to make links pop
184
+ return `${theme.link(LINK_BRACKET_L)} ${styledLabel} ${domainHint} ${theme.link(LINK_BRACKET_R)}`;
185
+ }
186
+ /**
187
+ * Render a bare URL with clickable domain display.
188
+ * Output: ` [link icon] domain.com/path `
189
+ */
190
+ function renderBareUrl(url) {
191
+ const domain = shortDomain(url);
192
+ const styledDomain = hyperlink(url, theme.link(chalk.underline(domain)));
193
+ return `${theme.link(LINK_ICON)} ${styledDomain}`;
194
+ }
195
+ // Inline markdown formatting
196
+ function fmt(text) {
197
+ if (noColor)
198
+ return text;
199
+ // Bold
200
+ text = text.replace(/\*\*(.+?)\*\*/g, (_, c) => chalk.bold(c));
201
+ // Italic
202
+ text = text.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, (_, c) => chalk.italic(c));
203
+ text = text.replace(/(?<!_)_([^_]+)_(?!_)/g, (_, c) => chalk.italic(c));
204
+ // Inline code
205
+ text = text.replace(/`([^`]+)`/g, (_, c) => theme.code(c));
206
+ // Strikethrough
207
+ text = text.replace(/~~(.+?)~~/g, (_, c) => chalk.strikethrough.dim(c));
208
+ // Use a placeholder to prevent double-matching URLs in markdown links vs bare URLs
209
+ const linkPlaceholders = [];
210
+ // 1. Markdown links [text](url) - highest priority
211
+ text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => {
212
+ const idx = linkPlaceholders.length;
213
+ linkPlaceholders.push(renderLink(label, url));
214
+ return `\x00LINK${idx}\x00`;
215
+ });
216
+ // 2. Contextual phrase + URL patterns:
217
+ // "details here https://..." / "view it here: https://..." / "click here https://..."
218
+ // Merge the phrase and URL into one styled link
219
+ text = text.replace(/((?:click |view |see |read |check |visit |details |full details |more )?here|this (?:link|page|article|site|resource))([.:,]?\s*)(https?:\/\/[^\s,;)>\]"']+[^\s,;)>\]"'.!?])/gi, (_match, phrase, sep, url) => {
220
+ const idx = linkPlaceholders.length;
221
+ linkPlaceholders.push(renderLink(phrase.trim(), url));
222
+ return `\x00LINK${idx}\x00`;
223
+ });
224
+ // 3. URL + contextual phrase patterns (reversed):
225
+ // "https://... (here)" / "https://... - click here"
226
+ text = text.replace(/(https?:\/\/[^\s,;)>\]"']+[^\s,;)>\]"'.!?])\s*[-(\s]*\b(here|this (?:link|page))\b[)\s]*/gi, (_match, url, phrase) => {
227
+ const idx = linkPlaceholders.length;
228
+ linkPlaceholders.push(renderLink(phrase.trim(), url));
229
+ return `\x00LINK${idx}\x00`;
230
+ });
231
+ // 4. Bare URLs with protocol: https://... http://...
232
+ text = text.replace(/(https?:\/\/[^\s,;)>\]"']+[^\s,;)>\]"'.!?])/g, (url) => {
233
+ const idx = linkPlaceholders.length;
234
+ linkPlaceholders.push(renderBareUrl(url));
235
+ return `\x00LINK${idx}\x00`;
236
+ });
237
+ // 5. Common bare domains without protocol: example.com/path
238
+ text = text.replace(/(?<=\s|^)((?:[a-zA-Z0-9-]+\.)+(?:com|org|net|io|dev|ai|co|app|gov|edu|info|me)(?:\/[^\s,;)>\]"']*[^\s,;)>\]"'.!?])?)/g, (url) => {
239
+ const idx = linkPlaceholders.length;
240
+ linkPlaceholders.push(renderBareUrl(url));
241
+ return `\x00LINK${idx}\x00`;
242
+ });
243
+ // 6. Orphan link phrases with no URL - highlight as missing/broken link
244
+ // "You can view the full details here." where "here" has no URL nearby
245
+ text = text.replace(/\b((?:click |view |see |read |check (?:it )?|visit )?here|this (?:link|page|article))\b(?!\x00)/gi, (phrase) => {
246
+ // Only style if no placeholder follows (i.e., no URL was found nearby)
247
+ return theme.link(chalk.underline(phrase)) + theme.dim(` ${LINK_ICON}?`);
248
+ });
249
+ // Restore placeholders
250
+ for (let i = 0; i < linkPlaceholders.length; i++) {
251
+ text = text.replace(`\x00LINK${i}\x00`, linkPlaceholders[i]);
252
+ }
253
+ return text;
254
+ }
255
+ // Render a single line with markdown
256
+ function renderLine(line, inCode, codeLang) {
257
+ if (inCode) {
258
+ const highlighted = highlightCode(line, codeLang || '');
259
+ return ` ${theme.border(V_LINE)} ${highlighted}`;
260
+ }
261
+ // Headings
262
+ if (line.startsWith('### '))
263
+ return ` ${theme.bold(fmt(line.slice(4)))}`;
264
+ if (line.startsWith('## '))
265
+ return ` ${theme.bold(fmt(line.slice(3)))}`;
266
+ if (line.startsWith('# '))
267
+ return ` ${theme.bold(chalk.underline(fmt(line.slice(2))))}`;
268
+ // Block quotes
269
+ if (line.startsWith('> ')) {
270
+ return ` ${theme.border(V_LINE)} ${theme.italic(fmt(line.slice(2)))}`;
271
+ }
272
+ // Bullet lists
273
+ const bullet = line.match(/^(\s*)([-*])\s(.*)/);
274
+ if (bullet) {
275
+ const indent = bullet[1];
276
+ return ` ${indent}${theme.dim(ARROW)} ${wrapText(fmt(bullet[3]), 4 + indent.length)}`;
277
+ }
278
+ // Numbered lists
279
+ const num = line.match(/^(\s*)(\d+\.)\s(.*)/);
280
+ if (num) {
281
+ return ` ${num[1]}${theme.dim(num[2])} ${wrapText(fmt(num[3]), 4 + num[1].length + num[2].length)}`;
282
+ }
283
+ // Horizontal rule
284
+ if (line.match(/^[-*_]{3,}$/))
285
+ return separator();
286
+ // Empty line
287
+ if (line.trim() === '')
288
+ return '';
289
+ // Normal text with word-wrap
290
+ return ` ${wrapText(fmt(line), 2)}`;
291
+ }
292
+ // Public helpers
293
+ export function formatElapsed(ms) {
294
+ if (ms < 1000)
295
+ return `${ms}ms`;
296
+ if (ms < 60000)
297
+ return `${(ms / 1000).toFixed(1)}s`;
298
+ const mins = Math.floor(ms / 60000);
299
+ const secs = Math.floor((ms % 60000) / 1000);
300
+ return `${mins}m ${secs}s`;
301
+ }
302
+ export function formatTokens(count) {
303
+ if (count >= 1000000)
304
+ return `${(count / 1000000).toFixed(1)}M`;
305
+ if (count >= 1000)
306
+ return `${(count / 1000).toFixed(1)}K`;
307
+ return count.toString();
308
+ }
309
+ function truncStr(str, max) {
310
+ if (str.length <= max)
311
+ return str;
312
+ return str.slice(0, max - 1) + ELLIP;
313
+ }
314
+ // Full markdown block rendering (for post-stream fallback)
315
+ export function renderMarkdownLite(text) {
316
+ const lines = text.split('\n');
317
+ const out = [];
318
+ let inCode = false;
319
+ let codeLang = '';
320
+ for (const line of lines) {
321
+ if (line.startsWith('```')) {
322
+ if (inCode) {
323
+ inCode = false;
324
+ out.push(` ${theme.border(B_LEFT + H_LINE.repeat(3))}`);
325
+ codeLang = '';
326
+ }
327
+ else {
328
+ inCode = true;
329
+ codeLang = line.slice(3).trim();
330
+ out.push(` ${theme.border(T_LEFT + H_LINE.repeat(3))} ${theme.dim(codeLang)}`);
331
+ }
332
+ continue;
333
+ }
334
+ out.push(renderLine(line, inCode, codeLang));
335
+ }
336
+ return out.join('\n');
337
+ }
338
+ // Renderer Implementation
339
+ export function createRenderer() {
340
+ // Streaming markdown state
341
+ let streamBuf = '';
342
+ let streamLineCount = 0;
343
+ let partialLine = ''; // Incomplete line being streamed
344
+ let inCodeBlock = false; // Track code block state across lines
345
+ let codeLang = ''; // Current code block language
346
+ let firstLineDone = false; // Track if we've started outputting
347
+ // Thinking state
348
+ let thinkingBuf = '';
349
+ return {
350
+ userMessage() {
351
+ // Don't echo - user knows what they typed
352
+ },
353
+ assistantStart() {
354
+ console.log('');
355
+ streamBuf = '';
356
+ streamLineCount = 0;
357
+ partialLine = '';
358
+ inCodeBlock = false;
359
+ codeLang = '';
360
+ firstLineDone = false;
361
+ },
362
+ assistantDelta(chunk) {
363
+ streamBuf += chunk;
364
+ // Streaming markdown: process complete lines immediately
365
+ const combined = partialLine + chunk;
366
+ const lines = combined.split('\n');
367
+ // Last element is the incomplete line (may be empty string if chunk ended with \n)
368
+ partialLine = lines.pop() || '';
369
+ // Render each complete line with markdown formatting
370
+ for (const line of lines) {
371
+ // Code block fence detection
372
+ if (line.startsWith('```')) {
373
+ if (inCodeBlock) {
374
+ inCodeBlock = false;
375
+ process.stdout.write(` ${theme.border(B_LEFT + H_LINE.repeat(3))}\n`);
376
+ codeLang = '';
377
+ }
378
+ else {
379
+ inCodeBlock = true;
380
+ codeLang = line.slice(3).trim();
381
+ process.stdout.write(` ${theme.border(T_LEFT + H_LINE.repeat(3))} ${theme.dim(codeLang)}\n`);
382
+ }
383
+ streamLineCount++;
384
+ continue;
385
+ }
386
+ const rendered = renderLine(line, inCodeBlock, codeLang);
387
+ process.stdout.write(rendered + '\n');
388
+ streamLineCount++;
389
+ firstLineDone = true;
390
+ }
391
+ // Write partial line raw (will be overwritten when line completes)
392
+ if (partialLine) {
393
+ if (inCodeBlock) {
394
+ process.stdout.write(`\r\x1b[K ${theme.border(V_LINE)} ${highlightCode(partialLine, codeLang)}`);
395
+ }
396
+ else {
397
+ process.stdout.write(`\r\x1b[K ${fmt(partialLine)}`);
398
+ }
399
+ }
400
+ },
401
+ assistantEnd() {
402
+ if (streamBuf.length === 0)
403
+ return;
404
+ // Flush any remaining partial line
405
+ if (partialLine) {
406
+ const rendered = renderLine(partialLine, inCodeBlock, codeLang);
407
+ process.stdout.write(`\r\x1b[K${rendered}\n`);
408
+ partialLine = '';
409
+ }
410
+ else if (firstLineDone) {
411
+ // Just ensure we end with a newline
412
+ }
413
+ streamBuf = '';
414
+ streamLineCount = 0;
415
+ inCodeBlock = false;
416
+ codeLang = '';
417
+ },
418
+ thinkingStart() {
419
+ thinkingBuf = '';
420
+ process.stdout.write(theme.dim(` ${CIRCLE} thinking`));
421
+ },
422
+ thinkingDelta(chunk) {
423
+ if (!chunk || chunk.trim() === '') {
424
+ process.stdout.write(theme.dim('.'));
425
+ return;
426
+ }
427
+ // First real content - clear the "thinking..." line
428
+ if (thinkingBuf === '') {
429
+ process.stdout.write('\r\x1b[K');
430
+ console.log(theme.dim(` ${CIRCLE} thinking:`));
431
+ }
432
+ thinkingBuf += chunk;
433
+ const lines = chunk.split('\n');
434
+ for (let i = 0; i < lines.length; i++) {
435
+ if (i > 0)
436
+ process.stdout.write('\n');
437
+ if (lines[i]) {
438
+ process.stdout.write(theme.dim(theme.italic(` ${lines[i]}`)));
439
+ }
440
+ }
441
+ },
442
+ thinkingEnd() {
443
+ process.stdout.write('\n');
444
+ if (thinkingBuf) {
445
+ console.log(theme.dim(` ${CIRCLE} done thinking`));
446
+ }
447
+ thinkingBuf = '';
448
+ },
449
+ toolCall(name, args) {
450
+ const firstVal = Object.values(args)[0];
451
+ const preview = firstVal ? truncStr(String(firstVal), 36) : '';
452
+ const label = preview
453
+ ? `${theme.gold(GEAR + ' ' + name)} ${theme.dim(preview)}`
454
+ : theme.gold(GEAR + ' ' + name);
455
+ console.log(separator(label));
456
+ // Show key arguments for common tools
457
+ const entries = Object.entries(args);
458
+ if (entries.length > 1) {
459
+ const maxArgs = 3;
460
+ for (let i = 0; i < Math.min(entries.length, maxArgs); i++) {
461
+ const [key, val] = entries[i];
462
+ const valStr = truncStr(String(val), 50);
463
+ console.log(theme.dim(` ${theme.border(V_LINE)} ${key}: ${valStr}`));
464
+ }
465
+ if (entries.length > maxArgs) {
466
+ console.log(theme.dim(` ${theme.border(V_LINE)} +${entries.length - maxArgs} more`));
467
+ }
468
+ }
469
+ },
470
+ toolResult(name, result, success, durationMs) {
471
+ const icon = success ? theme.mint(CHECK) : theme.coral(CROSS);
472
+ const dur = durationMs ? theme.dim(` ${formatElapsed(durationMs)}`) : '';
473
+ const statusText = success ? '' : theme.coral(' failed');
474
+ // Show result preview for verbose mode
475
+ if (result !== undefined && result !== null) {
476
+ const resultStr = typeof result === 'string' ? result : JSON.stringify(result);
477
+ if (!success) {
478
+ // Show error details
479
+ const errPreview = truncStr(resultStr, 80);
480
+ console.log(` ${icon}${statusText}${dur}`);
481
+ console.log(theme.coral(` ${theme.border(V_LINE)} ${errPreview}`));
482
+ }
483
+ else {
484
+ // Show success with brief preview
485
+ const preview = truncStr(resultStr, 60);
486
+ if (preview.length > 5 && resultStr.length > 10) {
487
+ console.log(` ${icon}${dur} ${theme.dim(preview)}`);
488
+ }
489
+ else {
490
+ console.log(` ${icon}${dur}`);
491
+ }
492
+ }
493
+ }
494
+ else {
495
+ console.log(` ${icon}${statusText}${dur}`);
496
+ }
497
+ console.log(separator());
498
+ },
499
+ usage(usage, durationMs) {
500
+ const parts = [];
501
+ if (durationMs)
502
+ parts.push(formatElapsed(durationMs));
503
+ if (usage.totalTokens) {
504
+ parts.push(`${formatTokens(usage.promptTokens)} in ${DOT} ${formatTokens(usage.completionTokens)} out`);
505
+ }
506
+ if (usage.cost !== undefined && usage.cost > 0)
507
+ parts.push(`$${usage.cost.toFixed(4)}`);
508
+ if (parts.length > 0) {
509
+ console.log('');
510
+ console.log(theme.dim(` ${parts.join(` ${DOT} `)}`));
511
+ }
512
+ },
513
+ error(message) {
514
+ console.log(` ${theme.coral(CROSS)} ${message}`);
515
+ },
516
+ info(message) {
517
+ console.log(theme.dim(` ${message}`));
518
+ },
519
+ success(message) {
520
+ console.log(` ${theme.mint(CHECK)} ${message}`);
521
+ },
522
+ warn(message) {
523
+ console.log(` ${theme.gold('!')} ${message}`);
524
+ },
525
+ divider() {
526
+ console.log(separator());
527
+ },
528
+ clear() {
529
+ console.clear();
530
+ },
531
+ statusLine(text) {
532
+ // Write to bottom of terminal using ANSI save/restore cursor
533
+ if (process.stdout.isTTY) {
534
+ const rows = process.stdout.rows || 24;
535
+ process.stdout.write(`\x1b7`); // Save cursor
536
+ process.stdout.write(`\x1b[${rows};1H`); // Move to bottom row
537
+ process.stdout.write(`\x1b[2K`); // Clear line
538
+ process.stdout.write(theme.dim(text));
539
+ process.stdout.write(`\x1b8`); // Restore cursor
540
+ }
541
+ },
542
+ sessionFooter(state) {
543
+ const parts = [];
544
+ if (state.sessionTokens > 0)
545
+ parts.push(`${formatTokens(state.sessionTokens)} tokens`);
546
+ if (state.sessionCost > 0)
547
+ parts.push(`$${state.sessionCost.toFixed(4)}`);
548
+ parts.push(`${state.messageCount} msg${state.messageCount !== 1 ? 's' : ''}`);
549
+ if (state.model)
550
+ parts.push(state.model);
551
+ console.log(theme.dim(` ${parts.join(` ${DOT} `)}`));
552
+ },
553
+ };
554
+ }
555
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Interactive REPL Engine
3
+ *
4
+ * Claude-like interactive chat with streaming, tool display,
5
+ * slash commands, and session management.
6
+ *
7
+ * Self-contained module - depends only on Node.js builtins,
8
+ * chalk, ora, and the stream-client/renderer siblings.
9
+ *
10
+ * @package profclaw-interactive (future standalone)
11
+ */
12
+ import type { InteractiveOptions } from './types.js';
13
+ export declare function startInteractiveREPL(options: InteractiveOptions): Promise<void>;
14
+ //# sourceMappingURL=repl.d.ts.map