commandmate 0.1.5 → 0.1.6

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 (330) hide show
  1. package/.next/BUILD_ID +1 -0
  2. package/.next/app-build-manifest.json +72 -0
  3. package/.next/app-path-routes-manifest.json +1 -0
  4. package/.next/build-manifest.json +32 -0
  5. package/.next/cache/.tsbuildinfo +1 -0
  6. package/.next/cache/config.json +7 -0
  7. package/.next/cache/webpack/client-production/0.pack +0 -0
  8. package/.next/cache/webpack/client-production/1.pack +0 -0
  9. package/.next/cache/webpack/client-production/2.pack +0 -0
  10. package/.next/cache/webpack/client-production/index.pack +0 -0
  11. package/.next/cache/webpack/client-production/index.pack.old +0 -0
  12. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  13. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  14. package/.next/cache/webpack/server-production/0.pack +0 -0
  15. package/.next/cache/webpack/server-production/index.pack +0 -0
  16. package/.next/export-marker.json +1 -0
  17. package/.next/images-manifest.json +1 -0
  18. package/.next/next-minimal-server.js.nft.json +1 -0
  19. package/.next/next-server.js.nft.json +1 -0
  20. package/.next/package.json +1 -0
  21. package/.next/prerender-manifest.json +1 -0
  22. package/.next/react-loadable-manifest.json +249 -0
  23. package/.next/required-server-files.json +1 -0
  24. package/.next/routes-manifest.json +1 -0
  25. package/.next/server/app/_not-found/page.js +1 -0
  26. package/.next/server/app/_not-found/page.js.nft.json +1 -0
  27. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  28. package/.next/server/app/_not-found.html +1 -0
  29. package/.next/server/app/_not-found.meta +6 -0
  30. package/.next/server/app/_not-found.rsc +10 -0
  31. package/.next/server/app/api/external-apps/[id]/health/route.js +45 -0
  32. package/.next/server/app/api/external-apps/[id]/health/route.js.nft.json +1 -0
  33. package/.next/server/app/api/external-apps/[id]/route.js +45 -0
  34. package/.next/server/app/api/external-apps/[id]/route.js.nft.json +1 -0
  35. package/.next/server/app/api/external-apps/route.js +45 -0
  36. package/.next/server/app/api/external-apps/route.js.nft.json +1 -0
  37. package/.next/server/app/api/hooks/claude-done/route.js +19 -0
  38. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -0
  39. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -0
  40. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -0
  41. package/.next/server/app/api/repositories/clone/route.js +1 -0
  42. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -0
  43. package/.next/server/app/api/repositories/route.js +1 -0
  44. package/.next/server/app/api/repositories/route.js.nft.json +1 -0
  45. package/.next/server/app/api/repositories/scan/route.js +1 -0
  46. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -0
  47. package/.next/server/app/api/repositories/sync/route.js +1 -0
  48. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -0
  49. package/.next/server/app/api/slash-commands/route.js +1 -0
  50. package/.next/server/app/api/slash-commands/route.js.nft.json +1 -0
  51. package/.next/server/app/api/slash-commands.body +1 -0
  52. package/.next/server/app/api/slash-commands.meta +1 -0
  53. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -0
  54. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -0
  55. package/.next/server/app/api/worktrees/[id]/capture/route.js +2 -0
  56. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -0
  57. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -0
  58. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +1 -0
  59. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -0
  60. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -0
  61. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -0
  62. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +1 -0
  63. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -0
  64. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -0
  65. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -0
  66. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -0
  67. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -0
  68. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -0
  69. package/.next/server/app/api/worktrees/[id]/logs/route.js +19 -0
  70. package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -0
  71. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -0
  72. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +1 -0
  73. package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -0
  74. package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +1 -0
  75. package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -0
  76. package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +1 -0
  77. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -0
  78. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -0
  79. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -0
  80. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -0
  81. package/.next/server/app/api/worktrees/[id]/route.js +1 -0
  82. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -0
  83. package/.next/server/app/api/worktrees/[id]/search/route.js +1 -0
  84. package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -0
  85. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -0
  86. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -0
  87. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -0
  88. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -0
  89. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -0
  90. package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -0
  91. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -0
  92. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -0
  93. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js +1 -0
  94. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -0
  95. package/.next/server/app/api/worktrees/[id]/tree/route.js +1 -0
  96. package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +1 -0
  97. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js +1 -0
  98. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -0
  99. package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -0
  100. package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -0
  101. package/.next/server/app/api/worktrees/route.js +1 -0
  102. package/.next/server/app/api/worktrees/route.js.nft.json +1 -0
  103. package/.next/server/app/apple-icon.png/route.js +1 -0
  104. package/.next/server/app/apple-icon.png/route.js.nft.json +1 -0
  105. package/.next/server/app/apple-icon.png.body +0 -0
  106. package/.next/server/app/apple-icon.png.meta +1 -0
  107. package/.next/server/app/icon.png/route.js +1 -0
  108. package/.next/server/app/icon.png/route.js.nft.json +1 -0
  109. package/.next/server/app/icon.png.body +0 -0
  110. package/.next/server/app/icon.png.meta +1 -0
  111. package/.next/server/app/index.html +9 -0
  112. package/.next/server/app/index.meta +5 -0
  113. package/.next/server/app/index.rsc +8 -0
  114. package/.next/server/app/page.js +16 -0
  115. package/.next/server/app/page.js.nft.json +1 -0
  116. package/.next/server/app/page_client-reference-manifest.js +1 -0
  117. package/.next/server/app/proxy/[...path]/route.js +45 -0
  118. package/.next/server/app/proxy/[...path]/route.js.nft.json +1 -0
  119. package/.next/server/app/worktrees/[id]/files/[...path]/page.js +1 -0
  120. package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -0
  121. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -0
  122. package/.next/server/app/worktrees/[id]/page.js +21 -0
  123. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -0
  124. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -0
  125. package/.next/server/app/worktrees/[id]/simple-terminal/page.js +4 -0
  126. package/.next/server/app/worktrees/[id]/simple-terminal/page.js.nft.json +1 -0
  127. package/.next/server/app/worktrees/[id]/simple-terminal/page_client-reference-manifest.js +1 -0
  128. package/.next/server/app/worktrees/[id]/terminal/page.js +6 -0
  129. package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -0
  130. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -0
  131. package/.next/server/app-paths-manifest.json +46 -0
  132. package/.next/server/chunks/1318.js +29 -0
  133. package/.next/server/chunks/1528.js +1 -0
  134. package/.next/server/chunks/1682.js +6 -0
  135. package/.next/server/chunks/2518.js +12 -0
  136. package/.next/server/chunks/3053.js +1 -0
  137. package/.next/server/chunks/3673.js +1 -0
  138. package/.next/server/chunks/3853.js +1 -0
  139. package/.next/server/chunks/434.js +1 -0
  140. package/.next/server/chunks/4471.js +2 -0
  141. package/.next/server/chunks/4893.js +2 -0
  142. package/.next/server/chunks/5972.js +12 -0
  143. package/.next/server/chunks/6550.js +1 -0
  144. package/.next/server/chunks/6621.js +1 -0
  145. package/.next/server/chunks/7213.js +1 -0
  146. package/.next/server/chunks/7425.js +500 -0
  147. package/.next/server/chunks/8585.js +1 -0
  148. package/.next/server/chunks/8887.js +1 -0
  149. package/.next/server/chunks/8948.js +2 -0
  150. package/.next/server/chunks/9703.js +31 -0
  151. package/.next/server/chunks/9723.js +19 -0
  152. package/.next/server/chunks/font-manifest.json +1 -0
  153. package/.next/server/edge-runtime-webpack.js +2 -0
  154. package/.next/server/edge-runtime-webpack.js.map +1 -0
  155. package/.next/server/font-manifest.json +1 -0
  156. package/.next/server/functions-config-manifest.json +1 -0
  157. package/.next/server/interception-route-rewrite-manifest.js +1 -0
  158. package/.next/server/middleware-build-manifest.js +1 -0
  159. package/.next/server/middleware-manifest.json +32 -0
  160. package/.next/server/middleware-react-loadable-manifest.js +1 -0
  161. package/.next/server/next-font-manifest.js +1 -0
  162. package/.next/server/next-font-manifest.json +1 -0
  163. package/.next/server/pages/404.html +1 -0
  164. package/.next/server/pages/500.html +1 -0
  165. package/.next/server/pages/_app.js +1 -0
  166. package/.next/server/pages/_app.js.nft.json +1 -0
  167. package/.next/server/pages/_document.js +1 -0
  168. package/.next/server/pages/_document.js.nft.json +1 -0
  169. package/.next/server/pages/_error.js +1 -0
  170. package/.next/server/pages/_error.js.nft.json +1 -0
  171. package/.next/server/pages-manifest.json +1 -0
  172. package/.next/server/server-reference-manifest.js +1 -0
  173. package/.next/server/server-reference-manifest.json +1 -0
  174. package/.next/server/src/middleware.js +14 -0
  175. package/.next/server/src/middleware.js.map +1 -0
  176. package/.next/server/webpack-runtime.js +1 -0
  177. package/.next/static/chunks/0dbeb660.3e800dfbd28be3bd.js +53 -0
  178. package/.next/static/chunks/1015.0eaa4da7f61149bc.js +59 -0
  179. package/.next/static/chunks/1098.49268c9fe1b028fa.js +1 -0
  180. package/.next/static/chunks/13.feeafc7cc620f8c4.js +1 -0
  181. package/.next/static/chunks/1423.7b1e8bf760d28078.js +1 -0
  182. package/.next/static/chunks/1582.9f8590f71ff798ca.js +55 -0
  183. package/.next/static/chunks/1817.a66d96cedb761daa.js +262 -0
  184. package/.next/static/chunks/2117-d845c2cd62e344a6.js +2 -0
  185. package/.next/static/chunks/2398.0b21e4eb7006a230.js +93 -0
  186. package/.next/static/chunks/2526.8ac62b527c9ab703.js +43 -0
  187. package/.next/static/chunks/2626.2125083a1ff3b80a.js +29 -0
  188. package/.next/static/chunks/2689.720a4874b02d4211.js +174 -0
  189. package/.next/static/chunks/2853-d11a80b03c9a1640.js +1 -0
  190. package/.next/static/chunks/2957-327e43ef4c12808f.js +1 -0
  191. package/.next/static/chunks/2cdb6380.35626fc6e41bbba4.js +136 -0
  192. package/.next/static/chunks/30d07d85-393352a92199f695.js +3 -0
  193. package/.next/static/chunks/3559.f073f72c4466ce0e.js +1 -0
  194. package/.next/static/chunks/3574.7a94c27e6a496a56.js +63 -0
  195. package/.next/static/chunks/383.20683891c9a5f2c4.js +4 -0
  196. package/.next/static/chunks/3843.3fdda732987f7bb8.js +1 -0
  197. package/.next/static/chunks/3852.822389f445c9b427.js +1 -0
  198. package/.next/static/chunks/3991.4bc063cb5be3a86c.js +1 -0
  199. package/.next/static/chunks/4212.52c1bb34fc97d0d0.js +131 -0
  200. package/.next/static/chunks/4327.3b84aa049900fdeb.js +60 -0
  201. package/.next/static/chunks/4362.7bd6f0282e49d79b.js +1 -0
  202. package/.next/static/chunks/4721.40615a5f4f32b5fb.js +1 -0
  203. package/.next/static/chunks/4851-45df4d388db5623f.js +1 -0
  204. package/.next/static/chunks/5112.17318d1c6b28044b.js +1 -0
  205. package/.next/static/chunks/5126.93fa4e797d609286.js +56 -0
  206. package/.next/static/chunks/5387.47590ac4ef66c864.js +5 -0
  207. package/.next/static/chunks/5813.4483664ba482beb1.js +1 -0
  208. package/.next/static/chunks/6143.1450875bd03a2366.js +36 -0
  209. package/.next/static/chunks/6406.9653f0d41ab85059.js +1 -0
  210. package/.next/static/chunks/656.d72f25ce819bd77e.js +149 -0
  211. package/.next/static/chunks/6678.492e73ca42b2a273.js +62 -0
  212. package/.next/static/chunks/6725-f7607851b7d57eb1.js +1 -0
  213. package/.next/static/chunks/6792.3c01ac4dda4b5c6d.js +1 -0
  214. package/.next/static/chunks/7004.808cbf327ef5955e.js +1 -0
  215. package/.next/static/chunks/7290.09ef84cf94f90c4d.js +1 -0
  216. package/.next/static/chunks/7415.6b481c2baf363262.js +148 -0
  217. package/.next/static/chunks/7648-325564a6e12a3257.js +1 -0
  218. package/.next/static/chunks/7665.47fccad04449a8f9.js +215 -0
  219. package/.next/static/chunks/7753.6bdce86b7fde3d10.js +166 -0
  220. package/.next/static/chunks/8125.245a9df052d274fb.js +1 -0
  221. package/.next/static/chunks/816-7e340dad784be28c.js +1 -0
  222. package/.next/static/chunks/8288.4883743fa40672e2.js +24 -0
  223. package/.next/static/chunks/8522.1607e96011c66877.js +1 -0
  224. package/.next/static/chunks/8772.863c564498d88487.js +1 -0
  225. package/.next/static/chunks/8841.dadeb1ece8e46004.js +1 -0
  226. package/.next/static/chunks/8885.f8d9912b40d74811.js +1 -0
  227. package/.next/static/chunks/90542734.c1553d0fe7fc14fc.js +1 -0
  228. package/.next/static/chunks/9365-733d8c05712d2888.js +1 -0
  229. package/.next/static/chunks/9552.b7dfb7903ead934b.js +1 -0
  230. package/.next/static/chunks/9834.295b45635ce04f5e.js +24 -0
  231. package/.next/static/chunks/app/_not-found/page-a9d04e58c81115ec.js +1 -0
  232. package/.next/static/chunks/app/layout-37e55f11dcc8b1bf.js +1 -0
  233. package/.next/static/chunks/app/page-9cd00de9cc0abc43.js +1 -0
  234. package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-9e5adf57cbbbdf05.js +1 -0
  235. package/.next/static/chunks/app/worktrees/[id]/page-8c6676303b63fdaf.js +1 -0
  236. package/.next/static/chunks/app/worktrees/[id]/simple-terminal/page-16feb3e86e42f4d1.js +1 -0
  237. package/.next/static/chunks/app/worktrees/[id]/terminal/page-be802baffc84dbd2.js +1 -0
  238. package/.next/static/chunks/d3ac728e.6c9c508274d4d2d5.js +1 -0
  239. package/.next/static/chunks/fd9d1056-bbe86e4ae099d5cd.js +1 -0
  240. package/.next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
  241. package/.next/static/chunks/main-a960f4a5e1a2f598.js +1 -0
  242. package/.next/static/chunks/main-app-420d93e43682fee5.js +1 -0
  243. package/.next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
  244. package/.next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
  245. package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  246. package/.next/static/chunks/webpack-3fc79fab9bb738d7.js +1 -0
  247. package/.next/static/css/5eacd01f773eed7f.css +11 -0
  248. package/.next/static/css/85fa6dafca566008.css +1 -0
  249. package/.next/static/css/e174aa24f94ce607.css +3 -0
  250. package/.next/static/pQTquVjewvoJa7BML07ip/_buildManifest.js +1 -0
  251. package/.next/static/pQTquVjewvoJa7BML07ip/_ssgManifest.js +1 -0
  252. package/.next/trace +5 -0
  253. package/.next/types/app/api/external-apps/[id]/health/route.ts +343 -0
  254. package/.next/types/app/api/external-apps/[id]/route.ts +343 -0
  255. package/.next/types/app/api/external-apps/route.ts +343 -0
  256. package/.next/types/app/api/hooks/claude-done/route.ts +343 -0
  257. package/.next/types/app/api/repositories/clone/[jobId]/route.ts +343 -0
  258. package/.next/types/app/api/repositories/clone/route.ts +343 -0
  259. package/.next/types/app/api/repositories/route.ts +343 -0
  260. package/.next/types/app/api/repositories/scan/route.ts +343 -0
  261. package/.next/types/app/api/repositories/sync/route.ts +343 -0
  262. package/.next/types/app/api/slash-commands/route.ts +343 -0
  263. package/.next/types/app/api/worktrees/[id]/auto-yes/route.ts +343 -0
  264. package/.next/types/app/api/worktrees/[id]/capture/route.ts +343 -0
  265. package/.next/types/app/api/worktrees/[id]/cli-tool/route.ts +343 -0
  266. package/.next/types/app/api/worktrees/[id]/current-output/route.ts +343 -0
  267. package/.next/types/app/api/worktrees/[id]/files/[...path]/route.ts +343 -0
  268. package/.next/types/app/api/worktrees/[id]/interrupt/route.ts +343 -0
  269. package/.next/types/app/api/worktrees/[id]/kill-session/route.ts +343 -0
  270. package/.next/types/app/api/worktrees/[id]/logs/[filename]/route.ts +343 -0
  271. package/.next/types/app/api/worktrees/[id]/logs/route.ts +343 -0
  272. package/.next/types/app/api/worktrees/[id]/memos/[memoId]/route.ts +343 -0
  273. package/.next/types/app/api/worktrees/[id]/memos/route.ts +343 -0
  274. package/.next/types/app/api/worktrees/[id]/messages/route.ts +343 -0
  275. package/.next/types/app/api/worktrees/[id]/prompt-response/route.ts +343 -0
  276. package/.next/types/app/api/worktrees/[id]/respond/route.ts +343 -0
  277. package/.next/types/app/api/worktrees/[id]/route.ts +343 -0
  278. package/.next/types/app/api/worktrees/[id]/search/route.ts +343 -0
  279. package/.next/types/app/api/worktrees/[id]/send/route.ts +343 -0
  280. package/.next/types/app/api/worktrees/[id]/slash-commands/route.ts +343 -0
  281. package/.next/types/app/api/worktrees/[id]/start-polling/route.ts +343 -0
  282. package/.next/types/app/api/worktrees/[id]/terminal/route.ts +343 -0
  283. package/.next/types/app/api/worktrees/[id]/tree/[...path]/route.ts +343 -0
  284. package/.next/types/app/api/worktrees/[id]/tree/route.ts +343 -0
  285. package/.next/types/app/api/worktrees/[id]/upload/[...path]/route.ts +343 -0
  286. package/.next/types/app/api/worktrees/[id]/viewed/route.ts +343 -0
  287. package/.next/types/app/api/worktrees/route.ts +343 -0
  288. package/.next/types/app/page.ts +79 -0
  289. package/.next/types/app/proxy/[...path]/route.ts +343 -0
  290. package/.next/types/app/worktrees/[id]/files/[...path]/page.ts +79 -0
  291. package/.next/types/app/worktrees/[id]/page.ts +79 -0
  292. package/.next/types/app/worktrees/[id]/simple-terminal/page.ts +79 -0
  293. package/.next/types/app/worktrees/[id]/terminal/page.ts +79 -0
  294. package/.next/types/package.json +1 -0
  295. package/README.md +39 -8
  296. package/dist/server/server.js +123 -0
  297. package/dist/server/src/lib/claude-output.js +33 -0
  298. package/dist/server/src/lib/claude-session.js +312 -0
  299. package/dist/server/src/lib/cli-patterns.js +137 -0
  300. package/dist/server/src/lib/cli-session.js +73 -0
  301. package/dist/server/src/lib/cli-tools/base.js +51 -0
  302. package/dist/server/src/lib/cli-tools/claude.js +65 -0
  303. package/dist/server/src/lib/cli-tools/codex.js +132 -0
  304. package/dist/server/src/lib/cli-tools/gemini.js +122 -0
  305. package/dist/server/src/lib/cli-tools/index.js +22 -0
  306. package/dist/server/src/lib/cli-tools/manager.js +143 -0
  307. package/dist/server/src/lib/cli-tools/types.js +5 -0
  308. package/dist/server/src/lib/conversation-logger.js +25 -0
  309. package/dist/server/src/lib/db-instance.js +51 -0
  310. package/dist/server/src/lib/db-migrations.js +777 -0
  311. package/dist/server/src/lib/db.js +835 -0
  312. package/dist/server/src/lib/env.js +179 -0
  313. package/dist/server/src/lib/log-manager.js +234 -0
  314. package/dist/server/src/lib/logger.js +232 -0
  315. package/dist/server/src/lib/prompt-detector.js +285 -0
  316. package/dist/server/src/lib/response-poller.js +638 -0
  317. package/dist/server/src/lib/tmux.js +299 -0
  318. package/dist/server/src/lib/worktrees.js +231 -0
  319. package/dist/server/src/lib/ws-server.js +323 -0
  320. package/dist/server/src/types/clone.js +39 -0
  321. package/dist/server/src/types/conversation.js +9 -0
  322. package/dist/server/src/types/external-apps.js +6 -0
  323. package/dist/server/src/types/infinite-messages.js +65 -0
  324. package/dist/server/src/types/markdown-editor.js +94 -0
  325. package/dist/server/src/types/models.js +5 -0
  326. package/dist/server/src/types/sidebar.js +89 -0
  327. package/dist/server/src/types/slash-commands.js +47 -0
  328. package/dist/server/src/types/ui-actions.js +8 -0
  329. package/dist/server/src/types/ui-state.js +62 -0
  330. package/package.json +8 -4
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ /**
3
+ * Generic CLI session management
4
+ * Manages CLI tool sessions (Claude, Codex, Gemini) within tmux
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isSessionRunning = isSessionRunning;
8
+ exports.captureSessionOutput = captureSessionOutput;
9
+ exports.getSessionName = getSessionName;
10
+ const tmux_1 = require("./tmux");
11
+ const manager_1 = require("./cli-tools/manager");
12
+ const logger_1 = require("./logger");
13
+ const logger = (0, logger_1.createLogger)('cli-session');
14
+ /**
15
+ * Check if CLI tool session is running
16
+ *
17
+ * @param worktreeId - Worktree ID
18
+ * @param cliToolId - CLI tool ID (claude, codex, gemini)
19
+ * @returns True if session exists and is running
20
+ */
21
+ async function isSessionRunning(worktreeId, cliToolId) {
22
+ const manager = manager_1.CLIToolManager.getInstance();
23
+ const cliTool = manager.getTool(cliToolId);
24
+ const sessionName = cliTool.getSessionName(worktreeId);
25
+ return await (0, tmux_1.hasSession)(sessionName);
26
+ }
27
+ /**
28
+ * Capture CLI session output
29
+ *
30
+ * @param worktreeId - Worktree ID
31
+ * @param cliToolId - CLI tool ID (claude, codex, gemini)
32
+ * @param lines - Number of lines to capture (default: 1000)
33
+ * @returns Captured output
34
+ */
35
+ async function captureSessionOutput(worktreeId, cliToolId, lines = 1000) {
36
+ const log = logger.withContext({ worktreeId, cliToolId });
37
+ log.debug('captureSessionOutput:start', { requestedLines: lines });
38
+ const manager = manager_1.CLIToolManager.getInstance();
39
+ const cliTool = manager.getTool(cliToolId);
40
+ const sessionName = cliTool.getSessionName(worktreeId);
41
+ // Check if session exists
42
+ const exists = await (0, tmux_1.hasSession)(sessionName);
43
+ if (!exists) {
44
+ log.debug('captureSessionOutput:sessionNotFound', { sessionName });
45
+ throw new Error(`${cliTool.name} session ${sessionName} does not exist`);
46
+ }
47
+ try {
48
+ const output = await (0, tmux_1.capturePane)(sessionName, { startLine: -lines });
49
+ const actualLines = output.split('\n').length;
50
+ log.debug('captureSessionOutput:success', {
51
+ actualLines,
52
+ lastFewLines: output.split('\n').slice(-3).join(' | '),
53
+ });
54
+ return output;
55
+ }
56
+ catch (error) {
57
+ const errorMessage = error instanceof Error ? error.message : String(error);
58
+ log.error('captureSessionOutput:failed', { error: errorMessage });
59
+ throw new Error(`Failed to capture ${cliTool.name} output: ${errorMessage}`);
60
+ }
61
+ }
62
+ /**
63
+ * Get session name for a CLI tool and worktree
64
+ *
65
+ * @param worktreeId - Worktree ID
66
+ * @param cliToolId - CLI tool ID
67
+ * @returns Session name
68
+ */
69
+ function getSessionName(worktreeId, cliToolId) {
70
+ const manager = manager_1.CLIToolManager.getInstance();
71
+ const cliTool = manager.getTool(cliToolId);
72
+ return cliTool.getSessionName(worktreeId);
73
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * Base implementation for CLI tools
4
+ * Provides common functionality for all CLI tool implementations
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.BaseCLITool = void 0;
8
+ const child_process_1 = require("child_process");
9
+ const util_1 = require("util");
10
+ const tmux_1 = require("../tmux");
11
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
12
+ /**
13
+ * Abstract base class for CLI tools
14
+ * Implements common functionality and defines abstract methods for specific implementations
15
+ */
16
+ class BaseCLITool {
17
+ /**
18
+ * Check if CLI tool is installed
19
+ * Uses 'which' command to check if the tool is available in PATH
20
+ */
21
+ async isInstalled() {
22
+ try {
23
+ await execAsync(`which ${this.command}`, { timeout: 5000 });
24
+ return true;
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ /**
31
+ * Generate session name for a worktree
32
+ * Format: mcbd-{cli_tool_id}-{worktree_id}
33
+ *
34
+ * @param worktreeId - Worktree ID
35
+ * @returns Session name
36
+ */
37
+ getSessionName(worktreeId) {
38
+ return `mcbd-${this.id}-${worktreeId}`;
39
+ }
40
+ /**
41
+ * Interrupt processing by sending Escape key
42
+ * Default implementation: send Escape key to tmux session
43
+ *
44
+ * @param worktreeId - Worktree ID
45
+ */
46
+ async interrupt(worktreeId) {
47
+ const sessionName = this.getSessionName(worktreeId);
48
+ await (0, tmux_1.sendSpecialKey)(sessionName, 'Escape');
49
+ }
50
+ }
51
+ exports.BaseCLITool = BaseCLITool;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * Claude Code CLI tool implementation
4
+ * Wraps existing claude-session functionality into the ICLITool interface
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ClaudeTool = void 0;
8
+ const base_1 = require("./base");
9
+ const claude_session_1 = require("../claude-session");
10
+ /**
11
+ * Claude Code CLI tool implementation
12
+ * Uses existing claude-session module for compatibility
13
+ */
14
+ class ClaudeTool extends base_1.BaseCLITool {
15
+ id = 'claude';
16
+ name = 'Claude Code';
17
+ command = 'claude';
18
+ /**
19
+ * Check if Claude CLI is installed
20
+ * Uses existing isClaudeInstalled function for compatibility
21
+ */
22
+ async isInstalled() {
23
+ return await (0, claude_session_1.isClaudeInstalled)();
24
+ }
25
+ /**
26
+ * Check if Claude session is running for a worktree
27
+ *
28
+ * @param worktreeId - Worktree ID
29
+ * @returns True if session is running
30
+ */
31
+ async isRunning(worktreeId) {
32
+ return await (0, claude_session_1.isClaudeRunning)(worktreeId);
33
+ }
34
+ /**
35
+ * Start a new Claude session for a worktree
36
+ *
37
+ * @param worktreeId - Worktree ID
38
+ * @param worktreePath - Worktree path
39
+ */
40
+ async startSession(worktreeId, worktreePath) {
41
+ const options = {
42
+ worktreeId,
43
+ worktreePath,
44
+ };
45
+ await (0, claude_session_1.startClaudeSession)(options);
46
+ }
47
+ /**
48
+ * Send a message to Claude session
49
+ *
50
+ * @param worktreeId - Worktree ID
51
+ * @param message - Message to send
52
+ */
53
+ async sendMessage(worktreeId, message) {
54
+ await (0, claude_session_1.sendMessageToClaude)(worktreeId, message);
55
+ }
56
+ /**
57
+ * Kill Claude session
58
+ *
59
+ * @param worktreeId - Worktree ID
60
+ */
61
+ async killSession(worktreeId) {
62
+ await (0, claude_session_1.stopClaudeSession)(worktreeId);
63
+ }
64
+ }
65
+ exports.ClaudeTool = ClaudeTool;
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * Codex CLI tool implementation
4
+ * Provides integration with OpenAI's Codex CLI
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.CodexTool = void 0;
8
+ const base_1 = require("./base");
9
+ const tmux_1 = require("../tmux");
10
+ const child_process_1 = require("child_process");
11
+ const util_1 = require("util");
12
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
13
+ /**
14
+ * Codex CLI tool implementation
15
+ * Manages Codex sessions using tmux
16
+ */
17
+ class CodexTool extends base_1.BaseCLITool {
18
+ id = 'codex';
19
+ name = 'Codex CLI';
20
+ command = 'codex';
21
+ /**
22
+ * Check if Codex session is running for a worktree
23
+ *
24
+ * @param worktreeId - Worktree ID
25
+ * @returns True if session is running
26
+ */
27
+ async isRunning(worktreeId) {
28
+ const sessionName = this.getSessionName(worktreeId);
29
+ return await (0, tmux_1.hasSession)(sessionName);
30
+ }
31
+ /**
32
+ * Start a new Codex session for a worktree
33
+ *
34
+ * @param worktreeId - Worktree ID
35
+ * @param worktreePath - Worktree path
36
+ */
37
+ async startSession(worktreeId, worktreePath) {
38
+ // Check if Codex is installed
39
+ const codexAvailable = await this.isInstalled();
40
+ if (!codexAvailable) {
41
+ throw new Error('Codex CLI is not installed or not in PATH');
42
+ }
43
+ const sessionName = this.getSessionName(worktreeId);
44
+ // Check if session already exists
45
+ const exists = await (0, tmux_1.hasSession)(sessionName);
46
+ if (exists) {
47
+ console.log(`Codex session ${sessionName} already exists`);
48
+ return;
49
+ }
50
+ try {
51
+ // Create tmux session with large history buffer for Codex output
52
+ await (0, tmux_1.createSession)({
53
+ sessionName,
54
+ workingDirectory: worktreePath,
55
+ historyLimit: 50000,
56
+ });
57
+ // Wait a moment for the session to be created
58
+ await new Promise((resolve) => setTimeout(resolve, 100));
59
+ // Start Codex CLI in interactive mode
60
+ await (0, tmux_1.sendKeys)(sessionName, 'codex', true);
61
+ // Wait for Codex to initialize (and potentially show update notification)
62
+ await new Promise((resolve) => setTimeout(resolve, 3000));
63
+ // Auto-skip update notification if present (select option 2: Skip)
64
+ await (0, tmux_1.sendKeys)(sessionName, '2', true);
65
+ // Wait a moment for the selection to process
66
+ await new Promise((resolve) => setTimeout(resolve, 500));
67
+ console.log(`✓ Started Codex session: ${sessionName}`);
68
+ }
69
+ catch (error) {
70
+ const errorMessage = error instanceof Error ? error.message : String(error);
71
+ throw new Error(`Failed to start Codex session: ${errorMessage}`);
72
+ }
73
+ }
74
+ /**
75
+ * Send a message to Codex session
76
+ *
77
+ * @param worktreeId - Worktree ID
78
+ * @param message - Message to send
79
+ */
80
+ async sendMessage(worktreeId, message) {
81
+ const sessionName = this.getSessionName(worktreeId);
82
+ // Check if session exists
83
+ const exists = await (0, tmux_1.hasSession)(sessionName);
84
+ if (!exists) {
85
+ throw new Error(`Codex session ${sessionName} does not exist. Start the session first.`);
86
+ }
87
+ try {
88
+ // Send message to Codex (without Enter)
89
+ await (0, tmux_1.sendKeys)(sessionName, message, false);
90
+ // Wait a moment for the text to be typed
91
+ await new Promise((resolve) => setTimeout(resolve, 100));
92
+ // Send Enter key separately
93
+ await execAsync(`tmux send-keys -t "${sessionName}" C-m`);
94
+ // Wait a moment for the message to be processed
95
+ await new Promise((resolve) => setTimeout(resolve, 200));
96
+ console.log(`✓ Sent message to Codex session: ${sessionName}`);
97
+ }
98
+ catch (error) {
99
+ const errorMessage = error instanceof Error ? error.message : String(error);
100
+ throw new Error(`Failed to send message to Codex: ${errorMessage}`);
101
+ }
102
+ }
103
+ /**
104
+ * Kill Codex session
105
+ *
106
+ * @param worktreeId - Worktree ID
107
+ */
108
+ async killSession(worktreeId) {
109
+ const sessionName = this.getSessionName(worktreeId);
110
+ try {
111
+ // Send Ctrl+D to exit Codex gracefully
112
+ const exists = await (0, tmux_1.hasSession)(sessionName);
113
+ if (exists) {
114
+ // Send Ctrl+D (ASCII 4)
115
+ await execAsync(`tmux send-keys -t "${sessionName}" C-d`);
116
+ // Wait a moment for Codex to exit
117
+ await new Promise((resolve) => setTimeout(resolve, 500));
118
+ }
119
+ // Kill the tmux session
120
+ const killed = await (0, tmux_1.killSession)(sessionName);
121
+ if (killed) {
122
+ console.log(`✓ Stopped Codex session: ${sessionName}`);
123
+ }
124
+ }
125
+ catch (error) {
126
+ const errorMessage = error instanceof Error ? error.message : String(error);
127
+ console.error(`Error stopping Codex session: ${errorMessage}`);
128
+ throw error;
129
+ }
130
+ }
131
+ }
132
+ exports.CodexTool = CodexTool;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * Gemini CLI tool implementation
4
+ * Provides integration with Google's Gemini CLI
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.GeminiTool = void 0;
8
+ const base_1 = require("./base");
9
+ const tmux_1 = require("../tmux");
10
+ const child_process_1 = require("child_process");
11
+ const util_1 = require("util");
12
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
13
+ /**
14
+ * Gemini CLI tool implementation
15
+ * Manages Gemini sessions using tmux
16
+ */
17
+ class GeminiTool extends base_1.BaseCLITool {
18
+ id = 'gemini';
19
+ name = 'Gemini CLI';
20
+ command = 'gemini';
21
+ /**
22
+ * Check if Gemini session is running for a worktree
23
+ *
24
+ * @param worktreeId - Worktree ID
25
+ * @returns True if session is running
26
+ */
27
+ async isRunning(worktreeId) {
28
+ const sessionName = this.getSessionName(worktreeId);
29
+ return await (0, tmux_1.hasSession)(sessionName);
30
+ }
31
+ /**
32
+ * Start a new Gemini session for a worktree
33
+ * Note: Gemini uses non-interactive mode, so we just create a tmux session
34
+ * for running one-shot commands
35
+ *
36
+ * @param worktreeId - Worktree ID
37
+ * @param worktreePath - Worktree path
38
+ */
39
+ async startSession(worktreeId, worktreePath) {
40
+ // Check if Gemini is installed
41
+ const geminiAvailable = await this.isInstalled();
42
+ if (!geminiAvailable) {
43
+ throw new Error('Gemini CLI is not installed or not in PATH');
44
+ }
45
+ const sessionName = this.getSessionName(worktreeId);
46
+ // Check if session already exists
47
+ const exists = await (0, tmux_1.hasSession)(sessionName);
48
+ if (exists) {
49
+ console.log(`Gemini session ${sessionName} already exists`);
50
+ return;
51
+ }
52
+ try {
53
+ // Create tmux session for running Gemini commands
54
+ await (0, tmux_1.createSession)({
55
+ sessionName,
56
+ workingDirectory: worktreePath,
57
+ historyLimit: 50000,
58
+ });
59
+ console.log(`✓ Started Gemini session: ${sessionName}`);
60
+ }
61
+ catch (error) {
62
+ const errorMessage = error instanceof Error ? error.message : String(error);
63
+ throw new Error(`Failed to start Gemini session: ${errorMessage}`);
64
+ }
65
+ }
66
+ /**
67
+ * Send a message to Gemini session (non-interactive mode)
68
+ * Executes a one-shot Gemini command and captures the output
69
+ *
70
+ * @param worktreeId - Worktree ID
71
+ * @param message - Message to send
72
+ */
73
+ async sendMessage(worktreeId, message) {
74
+ const sessionName = this.getSessionName(worktreeId);
75
+ // Check if session exists
76
+ const exists = await (0, tmux_1.hasSession)(sessionName);
77
+ if (!exists) {
78
+ throw new Error(`Gemini session ${sessionName} does not exist. Start the session first.`);
79
+ }
80
+ try {
81
+ // Escape the message for shell execution
82
+ const escapedMessage = message.replace(/'/g, "'\\''");
83
+ // Execute Gemini in non-interactive mode using stdin piping
84
+ // This approach bypasses the TUI and executes in one-shot mode
85
+ await (0, tmux_1.sendKeys)(sessionName, `echo '${escapedMessage}' | gemini`, true);
86
+ console.log(`✓ Sent message to Gemini session: ${sessionName}`);
87
+ }
88
+ catch (error) {
89
+ const errorMessage = error instanceof Error ? error.message : String(error);
90
+ throw new Error(`Failed to send message to Gemini: ${errorMessage}`);
91
+ }
92
+ }
93
+ /**
94
+ * Kill Gemini session
95
+ *
96
+ * @param worktreeId - Worktree ID
97
+ */
98
+ async killSession(worktreeId) {
99
+ const sessionName = this.getSessionName(worktreeId);
100
+ try {
101
+ // Send Ctrl+D to exit Gemini gracefully
102
+ const exists = await (0, tmux_1.hasSession)(sessionName);
103
+ if (exists) {
104
+ // Send Ctrl+D (ASCII 4)
105
+ await execAsync(`tmux send-keys -t "${sessionName}" C-d`);
106
+ // Wait a moment for Gemini to exit
107
+ await new Promise((resolve) => setTimeout(resolve, 500));
108
+ }
109
+ // Kill the tmux session
110
+ const killed = await (0, tmux_1.killSession)(sessionName);
111
+ if (killed) {
112
+ console.log(`✓ Stopped Gemini session: ${sessionName}`);
113
+ }
114
+ }
115
+ catch (error) {
116
+ const errorMessage = error instanceof Error ? error.message : String(error);
117
+ console.error(`Error stopping Gemini session: ${errorMessage}`);
118
+ throw error;
119
+ }
120
+ }
121
+ }
122
+ exports.GeminiTool = GeminiTool;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * CLI Tools Module
4
+ * Provides abstraction layer for multiple SWE CLI tools (Claude, Codex, Gemini)
5
+ *
6
+ * @module cli-tools
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CLIToolManager = exports.GeminiTool = exports.CodexTool = exports.ClaudeTool = exports.BaseCLITool = void 0;
10
+ // Export base class
11
+ var base_1 = require("./base");
12
+ Object.defineProperty(exports, "BaseCLITool", { enumerable: true, get: function () { return base_1.BaseCLITool; } });
13
+ // Export CLI tool implementations
14
+ var claude_1 = require("./claude");
15
+ Object.defineProperty(exports, "ClaudeTool", { enumerable: true, get: function () { return claude_1.ClaudeTool; } });
16
+ var codex_1 = require("./codex");
17
+ Object.defineProperty(exports, "CodexTool", { enumerable: true, get: function () { return codex_1.CodexTool; } });
18
+ var gemini_1 = require("./gemini");
19
+ Object.defineProperty(exports, "GeminiTool", { enumerable: true, get: function () { return gemini_1.GeminiTool; } });
20
+ // Export CLI tool manager
21
+ var manager_1 = require("./manager");
22
+ Object.defineProperty(exports, "CLIToolManager", { enumerable: true, get: function () { return manager_1.CLIToolManager; } });
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ /**
3
+ * CLI Tool Manager
4
+ * Singleton class to manage multiple CLI tools (Claude, Codex, Gemini)
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.CLIToolManager = void 0;
8
+ const claude_1 = require("./claude");
9
+ const codex_1 = require("./codex");
10
+ const gemini_1 = require("./gemini");
11
+ /**
12
+ * CLI Tool Manager (Singleton)
13
+ * Provides centralized access to all CLI tools
14
+ */
15
+ class CLIToolManager {
16
+ static instance;
17
+ tools;
18
+ /**
19
+ * Private constructor for Singleton pattern
20
+ */
21
+ constructor() {
22
+ this.tools = new Map();
23
+ // Initialize all tools
24
+ this.tools.set('claude', new claude_1.ClaudeTool());
25
+ this.tools.set('codex', new codex_1.CodexTool());
26
+ this.tools.set('gemini', new gemini_1.GeminiTool());
27
+ }
28
+ /**
29
+ * Get singleton instance
30
+ *
31
+ * @returns CLIToolManager instance
32
+ */
33
+ static getInstance() {
34
+ if (!CLIToolManager.instance) {
35
+ CLIToolManager.instance = new CLIToolManager();
36
+ }
37
+ return CLIToolManager.instance;
38
+ }
39
+ /**
40
+ * Get a specific CLI tool by type
41
+ *
42
+ * @param type - CLI tool type
43
+ * @returns CLI tool instance
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const manager = CLIToolManager.getInstance();
48
+ * const claude = manager.getTool('claude');
49
+ * await claude.startSession('my-worktree', '/path/to/worktree');
50
+ * ```
51
+ */
52
+ getTool(type) {
53
+ const tool = this.tools.get(type);
54
+ if (!tool) {
55
+ throw new Error(`CLI tool '${type}' not found`);
56
+ }
57
+ return tool;
58
+ }
59
+ /**
60
+ * Get all CLI tools
61
+ *
62
+ * @returns Array of all CLI tool instances
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const manager = CLIToolManager.getInstance();
67
+ * const allTools = manager.getAllTools();
68
+ * console.log(allTools.map(t => t.name)); // ['Claude Code', 'Codex CLI', 'Gemini CLI']
69
+ * ```
70
+ */
71
+ getAllTools() {
72
+ return Array.from(this.tools.values());
73
+ }
74
+ /**
75
+ * Get information about a specific tool including installation status
76
+ *
77
+ * @param type - CLI tool type
78
+ * @returns Tool information with installation status
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const manager = CLIToolManager.getInstance();
83
+ * const info = await manager.getToolInfo('claude');
84
+ * if (info.installed) {
85
+ * console.log(`${info.name} is installed`);
86
+ * }
87
+ * ```
88
+ */
89
+ async getToolInfo(type) {
90
+ const tool = this.getTool(type);
91
+ const installed = await tool.isInstalled();
92
+ return {
93
+ id: tool.id,
94
+ name: tool.name,
95
+ command: tool.command,
96
+ installed,
97
+ };
98
+ }
99
+ /**
100
+ * Get information about all tools including installation status
101
+ *
102
+ * @returns Array of tool information for all tools
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const manager = CLIToolManager.getInstance();
107
+ * const allInfo = await manager.getAllToolsInfo();
108
+ * allInfo.forEach(info => {
109
+ * console.log(`${info.name}: ${info.installed ? 'installed' : 'not installed'}`);
110
+ * });
111
+ * ```
112
+ */
113
+ async getAllToolsInfo() {
114
+ const tools = this.getAllTools();
115
+ const infoPromises = tools.map(async (tool) => {
116
+ const installed = await tool.isInstalled();
117
+ return {
118
+ id: tool.id,
119
+ name: tool.name,
120
+ command: tool.command,
121
+ installed,
122
+ };
123
+ });
124
+ return Promise.all(infoPromises);
125
+ }
126
+ /**
127
+ * Get only installed tools
128
+ *
129
+ * @returns Array of tool information for installed tools only
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const manager = CLIToolManager.getInstance();
134
+ * const installed = await manager.getInstalledTools();
135
+ * console.log(`${installed.length} tools installed`);
136
+ * ```
137
+ */
138
+ async getInstalledTools() {
139
+ const allInfo = await this.getAllToolsInfo();
140
+ return allInfo.filter(info => info.installed);
141
+ }
142
+ }
143
+ exports.CLIToolManager = CLIToolManager;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * Type definitions and interfaces for CLI tools
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /**
3
+ * Conversation logging helper
4
+ * Ensures Claude responses are paired with the latest user input before writing markdown logs
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.recordClaudeConversation = recordClaudeConversation;
8
+ const db_1 = require("./db");
9
+ const log_manager_1 = require("./log-manager");
10
+ /**
11
+ * Persist the latest Claude response alongside the most recent user prompt.
12
+ * Errors are swallowed so the calling API route can continue responding.
13
+ */
14
+ async function recordClaudeConversation(db, worktreeId, claudeResponse, cliToolId = 'claude') {
15
+ const lastUserMessage = (0, db_1.getLastUserMessage)(db, worktreeId);
16
+ if (!lastUserMessage) {
17
+ return;
18
+ }
19
+ try {
20
+ await (0, log_manager_1.createLog)(worktreeId, lastUserMessage.content, claudeResponse, cliToolId);
21
+ }
22
+ catch (error) {
23
+ console.error('[recordClaudeConversation] Failed to create log file:', error);
24
+ }
25
+ }