commandmate 0.1.5 → 0.1.7

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 (341) 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/3jNZMmFnQhc5G7met-OU4/_buildManifest.js +1 -0
  178. package/.next/static/3jNZMmFnQhc5G7met-OU4/_ssgManifest.js +1 -0
  179. package/.next/static/chunks/0dbeb660.3e800dfbd28be3bd.js +53 -0
  180. package/.next/static/chunks/1015.0eaa4da7f61149bc.js +59 -0
  181. package/.next/static/chunks/1098.49268c9fe1b028fa.js +1 -0
  182. package/.next/static/chunks/13.feeafc7cc620f8c4.js +1 -0
  183. package/.next/static/chunks/1423.7b1e8bf760d28078.js +1 -0
  184. package/.next/static/chunks/1582.9f8590f71ff798ca.js +55 -0
  185. package/.next/static/chunks/1817.a66d96cedb761daa.js +262 -0
  186. package/.next/static/chunks/2117-d845c2cd62e344a6.js +2 -0
  187. package/.next/static/chunks/2398.0b21e4eb7006a230.js +93 -0
  188. package/.next/static/chunks/2526.8ac62b527c9ab703.js +43 -0
  189. package/.next/static/chunks/2626.2125083a1ff3b80a.js +29 -0
  190. package/.next/static/chunks/2689.720a4874b02d4211.js +174 -0
  191. package/.next/static/chunks/2853-d11a80b03c9a1640.js +1 -0
  192. package/.next/static/chunks/2957-327e43ef4c12808f.js +1 -0
  193. package/.next/static/chunks/2cdb6380.35626fc6e41bbba4.js +136 -0
  194. package/.next/static/chunks/30d07d85-393352a92199f695.js +3 -0
  195. package/.next/static/chunks/3559.f073f72c4466ce0e.js +1 -0
  196. package/.next/static/chunks/3574.7a94c27e6a496a56.js +63 -0
  197. package/.next/static/chunks/383.20683891c9a5f2c4.js +4 -0
  198. package/.next/static/chunks/3843.3fdda732987f7bb8.js +1 -0
  199. package/.next/static/chunks/3852.822389f445c9b427.js +1 -0
  200. package/.next/static/chunks/3991.4bc063cb5be3a86c.js +1 -0
  201. package/.next/static/chunks/4212.52c1bb34fc97d0d0.js +131 -0
  202. package/.next/static/chunks/4327.3b84aa049900fdeb.js +60 -0
  203. package/.next/static/chunks/4362.7bd6f0282e49d79b.js +1 -0
  204. package/.next/static/chunks/4721.40615a5f4f32b5fb.js +1 -0
  205. package/.next/static/chunks/4851-45df4d388db5623f.js +1 -0
  206. package/.next/static/chunks/5112.17318d1c6b28044b.js +1 -0
  207. package/.next/static/chunks/5126.93fa4e797d609286.js +56 -0
  208. package/.next/static/chunks/5387.47590ac4ef66c864.js +5 -0
  209. package/.next/static/chunks/5813.4483664ba482beb1.js +1 -0
  210. package/.next/static/chunks/6143.1450875bd03a2366.js +36 -0
  211. package/.next/static/chunks/6406.9653f0d41ab85059.js +1 -0
  212. package/.next/static/chunks/656.d72f25ce819bd77e.js +149 -0
  213. package/.next/static/chunks/6678.492e73ca42b2a273.js +62 -0
  214. package/.next/static/chunks/6725-f7607851b7d57eb1.js +1 -0
  215. package/.next/static/chunks/6792.3c01ac4dda4b5c6d.js +1 -0
  216. package/.next/static/chunks/7004.808cbf327ef5955e.js +1 -0
  217. package/.next/static/chunks/7290.09ef84cf94f90c4d.js +1 -0
  218. package/.next/static/chunks/7415.6b481c2baf363262.js +148 -0
  219. package/.next/static/chunks/7648-325564a6e12a3257.js +1 -0
  220. package/.next/static/chunks/7665.47fccad04449a8f9.js +215 -0
  221. package/.next/static/chunks/7753.6bdce86b7fde3d10.js +166 -0
  222. package/.next/static/chunks/8125.245a9df052d274fb.js +1 -0
  223. package/.next/static/chunks/816-7e340dad784be28c.js +1 -0
  224. package/.next/static/chunks/8288.4883743fa40672e2.js +24 -0
  225. package/.next/static/chunks/8522.1607e96011c66877.js +1 -0
  226. package/.next/static/chunks/8772.863c564498d88487.js +1 -0
  227. package/.next/static/chunks/8841.dadeb1ece8e46004.js +1 -0
  228. package/.next/static/chunks/8885.f8d9912b40d74811.js +1 -0
  229. package/.next/static/chunks/90542734.c1553d0fe7fc14fc.js +1 -0
  230. package/.next/static/chunks/9365-733d8c05712d2888.js +1 -0
  231. package/.next/static/chunks/9552.b7dfb7903ead934b.js +1 -0
  232. package/.next/static/chunks/9834.295b45635ce04f5e.js +24 -0
  233. package/.next/static/chunks/app/_not-found/page-a9d04e58c81115ec.js +1 -0
  234. package/.next/static/chunks/app/layout-37e55f11dcc8b1bf.js +1 -0
  235. package/.next/static/chunks/app/page-9cd00de9cc0abc43.js +1 -0
  236. package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-9e5adf57cbbbdf05.js +1 -0
  237. package/.next/static/chunks/app/worktrees/[id]/page-8c6676303b63fdaf.js +1 -0
  238. package/.next/static/chunks/app/worktrees/[id]/simple-terminal/page-16feb3e86e42f4d1.js +1 -0
  239. package/.next/static/chunks/app/worktrees/[id]/terminal/page-be802baffc84dbd2.js +1 -0
  240. package/.next/static/chunks/d3ac728e.6c9c508274d4d2d5.js +1 -0
  241. package/.next/static/chunks/fd9d1056-bbe86e4ae099d5cd.js +1 -0
  242. package/.next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
  243. package/.next/static/chunks/main-a960f4a5e1a2f598.js +1 -0
  244. package/.next/static/chunks/main-app-420d93e43682fee5.js +1 -0
  245. package/.next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
  246. package/.next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
  247. package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  248. package/.next/static/chunks/webpack-3fc79fab9bb738d7.js +1 -0
  249. package/.next/static/css/5eacd01f773eed7f.css +11 -0
  250. package/.next/static/css/85fa6dafca566008.css +1 -0
  251. package/.next/static/css/e174aa24f94ce607.css +3 -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/cli/commands/init.d.ts +1 -0
  297. package/dist/cli/commands/init.d.ts.map +1 -1
  298. package/dist/cli/commands/init.js +143 -27
  299. package/dist/cli/types/index.d.ts +18 -0
  300. package/dist/cli/types/index.d.ts.map +1 -1
  301. package/dist/cli/utils/env-setup.d.ts +25 -0
  302. package/dist/cli/utils/env-setup.d.ts.map +1 -1
  303. package/dist/cli/utils/env-setup.js +56 -1
  304. package/dist/cli/utils/prompt.d.ts +68 -0
  305. package/dist/cli/utils/prompt.d.ts.map +1 -0
  306. package/dist/cli/utils/prompt.js +208 -0
  307. package/dist/server/server.js +123 -0
  308. package/dist/server/src/lib/claude-output.js +33 -0
  309. package/dist/server/src/lib/claude-session.js +312 -0
  310. package/dist/server/src/lib/cli-patterns.js +137 -0
  311. package/dist/server/src/lib/cli-session.js +73 -0
  312. package/dist/server/src/lib/cli-tools/base.js +51 -0
  313. package/dist/server/src/lib/cli-tools/claude.js +65 -0
  314. package/dist/server/src/lib/cli-tools/codex.js +132 -0
  315. package/dist/server/src/lib/cli-tools/gemini.js +122 -0
  316. package/dist/server/src/lib/cli-tools/index.js +22 -0
  317. package/dist/server/src/lib/cli-tools/manager.js +143 -0
  318. package/dist/server/src/lib/cli-tools/types.js +5 -0
  319. package/dist/server/src/lib/conversation-logger.js +25 -0
  320. package/dist/server/src/lib/db-instance.js +51 -0
  321. package/dist/server/src/lib/db-migrations.js +777 -0
  322. package/dist/server/src/lib/db.js +835 -0
  323. package/dist/server/src/lib/env.js +179 -0
  324. package/dist/server/src/lib/log-manager.js +234 -0
  325. package/dist/server/src/lib/logger.js +232 -0
  326. package/dist/server/src/lib/prompt-detector.js +285 -0
  327. package/dist/server/src/lib/response-poller.js +638 -0
  328. package/dist/server/src/lib/tmux.js +299 -0
  329. package/dist/server/src/lib/worktrees.js +231 -0
  330. package/dist/server/src/lib/ws-server.js +323 -0
  331. package/dist/server/src/types/clone.js +39 -0
  332. package/dist/server/src/types/conversation.js +9 -0
  333. package/dist/server/src/types/external-apps.js +6 -0
  334. package/dist/server/src/types/infinite-messages.js +65 -0
  335. package/dist/server/src/types/markdown-editor.js +94 -0
  336. package/dist/server/src/types/models.js +5 -0
  337. package/dist/server/src/types/sidebar.js +89 -0
  338. package/dist/server/src/types/slash-commands.js +47 -0
  339. package/dist/server/src/types/ui-actions.js +8 -0
  340. package/dist/server/src/types/ui-state.js +62 -0
  341. package/package.json +8 -4
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ /**
3
+ * Common CLI tool patterns for response detection
4
+ * Shared between response-poller.ts and API routes
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.GEMINI_PROMPT_PATTERN = exports.CODEX_SEPARATOR_PATTERN = exports.CODEX_PROMPT_PATTERN = exports.CLAUDE_SEPARATOR_PATTERN = exports.CLAUDE_PROMPT_PATTERN = exports.CODEX_THINKING_PATTERN = exports.CLAUDE_THINKING_PATTERN = exports.CLAUDE_SPINNER_CHARS = void 0;
8
+ exports.detectThinking = detectThinking;
9
+ exports.getCliToolPatterns = getCliToolPatterns;
10
+ exports.stripAnsi = stripAnsi;
11
+ const logger_1 = require("./logger");
12
+ const logger = (0, logger_1.createLogger)('cli-patterns');
13
+ /**
14
+ * Claude CLI spinner characters (expanded set)
15
+ * These are shown when Claude is thinking/processing
16
+ */
17
+ exports.CLAUDE_SPINNER_CHARS = [
18
+ '✻', '✽', '⏺', '·', '∴', '✢', '✳', '✶',
19
+ '⦿', '◉', '●', '○', '◌', '◎', '⊙', '⊚',
20
+ '⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏', // Braille spinner
21
+ ];
22
+ /**
23
+ * Claude thinking pattern
24
+ * Matches spinner character followed by activity text ending with …
25
+ * The text can contain spaces (e.g., "Verifying implementation (dead code detection)…")
26
+ */
27
+ exports.CLAUDE_THINKING_PATTERN = new RegExp(`[${exports.CLAUDE_SPINNER_CHARS.join('')}]\\s+.+…|to interrupt\\)`, 'm');
28
+ /**
29
+ * Codex thinking pattern
30
+ * Matches activity indicators like "• Planning", "• Searching", etc.
31
+ */
32
+ exports.CODEX_THINKING_PATTERN = /•\s*(Planning|Searching|Exploring|Running|Thinking|Working|Reading|Writing|Analyzing)/m;
33
+ /**
34
+ * Claude prompt pattern (waiting for input)
35
+ * Supports both legacy '>' and new '❯' (U+276F) prompt characters
36
+ */
37
+ exports.CLAUDE_PROMPT_PATTERN = /^[>❯]\s*$/m;
38
+ /**
39
+ * Claude separator pattern
40
+ */
41
+ exports.CLAUDE_SEPARATOR_PATTERN = /^─{10,}$/m;
42
+ /**
43
+ * Codex prompt pattern
44
+ */
45
+ exports.CODEX_PROMPT_PATTERN = /^›\s+.+/m;
46
+ /**
47
+ * Codex separator pattern
48
+ */
49
+ exports.CODEX_SEPARATOR_PATTERN = /^─.*Worked for.*─+$/m;
50
+ /**
51
+ * Gemini shell prompt pattern
52
+ */
53
+ exports.GEMINI_PROMPT_PATTERN = /^(%|\$|.*@.*[%$#])\s*$/m;
54
+ /**
55
+ * Detect if CLI tool is showing "thinking" indicator
56
+ */
57
+ function detectThinking(cliToolId, content) {
58
+ const log = logger.withContext({ cliToolId });
59
+ log.debug('detectThinking:check', { contentLength: content.length });
60
+ let result;
61
+ switch (cliToolId) {
62
+ case 'claude':
63
+ result = exports.CLAUDE_THINKING_PATTERN.test(content);
64
+ break;
65
+ case 'codex':
66
+ result = exports.CODEX_THINKING_PATTERN.test(content);
67
+ break;
68
+ case 'gemini':
69
+ // Gemini doesn't have a thinking indicator in one-shot mode
70
+ result = false;
71
+ break;
72
+ default:
73
+ result = exports.CLAUDE_THINKING_PATTERN.test(content);
74
+ }
75
+ log.debug('detectThinking:result', { isThinking: result });
76
+ return result;
77
+ }
78
+ /**
79
+ * Get CLI tool patterns for response extraction
80
+ */
81
+ function getCliToolPatterns(cliToolId) {
82
+ switch (cliToolId) {
83
+ case 'claude':
84
+ return {
85
+ promptPattern: exports.CLAUDE_PROMPT_PATTERN,
86
+ separatorPattern: exports.CLAUDE_SEPARATOR_PATTERN,
87
+ thinkingPattern: exports.CLAUDE_THINKING_PATTERN,
88
+ skipPatterns: [
89
+ /^─{10,}$/, // Separator lines
90
+ /^[>❯]\s*$/, // Prompt line (legacy '>' and new '❯')
91
+ exports.CLAUDE_THINKING_PATTERN, // Thinking indicators
92
+ /^\s*[⎿⏋]\s+Tip:/, // Tip lines
93
+ /^\s*Tip:/, // Tip lines
94
+ /^\s*\?\s*for shortcuts/, // Shortcuts hint
95
+ /to interrupt\)/, // Part of "esc to interrupt" message
96
+ ],
97
+ };
98
+ case 'codex':
99
+ return {
100
+ promptPattern: exports.CODEX_PROMPT_PATTERN,
101
+ separatorPattern: exports.CODEX_SEPARATOR_PATTERN,
102
+ thinkingPattern: exports.CODEX_THINKING_PATTERN,
103
+ skipPatterns: [
104
+ /^─.*─+$/, // Separator lines
105
+ /^›\s*$/, // Empty prompt line
106
+ /^›\s+(Implement|Find and fix|Type)/, // New prompt suggestions
107
+ exports.CODEX_THINKING_PATTERN, // Activity indicators
108
+ /^\s*\d+%\s+context left/, // Context indicator
109
+ /^\s*for shortcuts$/, // Shortcuts hint
110
+ /╭─+╮/, // Box drawing (top)
111
+ /╰─+╯/, // Box drawing (bottom)
112
+ ],
113
+ };
114
+ case 'gemini':
115
+ return {
116
+ promptPattern: exports.GEMINI_PROMPT_PATTERN,
117
+ separatorPattern: /^gemini\s+--\s+/m,
118
+ thinkingPattern: /(?!)/m, // Never matches - one-shot execution
119
+ skipPatterns: [
120
+ /^gemini\s+--\s+/, // Command line itself
121
+ exports.GEMINI_PROMPT_PATTERN, // Shell prompt lines
122
+ /^\s*$/, // Empty lines
123
+ ],
124
+ };
125
+ default:
126
+ // Default to Claude patterns
127
+ return getCliToolPatterns('claude');
128
+ }
129
+ }
130
+ /**
131
+ * Strip ANSI escape codes from a string
132
+ * Optimized version at module level for performance
133
+ */
134
+ const ANSI_PATTERN = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\[[0-9;]*m/g;
135
+ function stripAnsi(str) {
136
+ return str.replace(ANSI_PATTERN, '');
137
+ }
@@ -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; } });