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.
- package/.next/BUILD_ID +1 -0
- package/.next/app-build-manifest.json +72 -0
- package/.next/app-path-routes-manifest.json +1 -0
- package/.next/build-manifest.json +32 -0
- package/.next/cache/.tsbuildinfo +1 -0
- package/.next/cache/config.json +7 -0
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/1.pack +0 -0
- package/.next/cache/webpack/client-production/2.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/export-marker.json +1 -0
- package/.next/images-manifest.json +1 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +1 -0
- package/.next/react-loadable-manifest.json +249 -0
- package/.next/required-server-files.json +1 -0
- package/.next/routes-manifest.json +1 -0
- package/.next/server/app/_not-found/page.js +1 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_not-found.html +1 -0
- package/.next/server/app/_not-found.meta +6 -0
- package/.next/server/app/_not-found.rsc +10 -0
- package/.next/server/app/api/external-apps/[id]/health/route.js +45 -0
- package/.next/server/app/api/external-apps/[id]/health/route.js.nft.json +1 -0
- package/.next/server/app/api/external-apps/[id]/route.js +45 -0
- package/.next/server/app/api/external-apps/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/external-apps/route.js +45 -0
- package/.next/server/app/api/external-apps/route.js.nft.json +1 -0
- package/.next/server/app/api/hooks/claude-done/route.js +19 -0
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -0
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -0
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -0
- package/.next/server/app/api/repositories/clone/route.js +1 -0
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -0
- package/.next/server/app/api/repositories/route.js +1 -0
- package/.next/server/app/api/repositories/route.js.nft.json +1 -0
- package/.next/server/app/api/repositories/scan/route.js +1 -0
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -0
- package/.next/server/app/api/repositories/sync/route.js +1 -0
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -0
- package/.next/server/app/api/slash-commands/route.js +1 -0
- package/.next/server/app/api/slash-commands/route.js.nft.json +1 -0
- package/.next/server/app/api/slash-commands.body +1 -0
- package/.next/server/app/api/slash-commands.meta +1 -0
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/capture/route.js +2 -0
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/logs/route.js +19 -0
- package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/search/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/tree/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/route.js +1 -0
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -0
- package/.next/server/app/apple-icon.png/route.js +1 -0
- package/.next/server/app/apple-icon.png/route.js.nft.json +1 -0
- package/.next/server/app/apple-icon.png.body +0 -0
- package/.next/server/app/apple-icon.png.meta +1 -0
- package/.next/server/app/icon.png/route.js +1 -0
- package/.next/server/app/icon.png/route.js.nft.json +1 -0
- package/.next/server/app/icon.png.body +0 -0
- package/.next/server/app/icon.png.meta +1 -0
- package/.next/server/app/index.html +9 -0
- package/.next/server/app/index.meta +5 -0
- package/.next/server/app/index.rsc +8 -0
- package/.next/server/app/page.js +16 -0
- package/.next/server/app/page.js.nft.json +1 -0
- package/.next/server/app/page_client-reference-manifest.js +1 -0
- package/.next/server/app/proxy/[...path]/route.js +45 -0
- package/.next/server/app/proxy/[...path]/route.js.nft.json +1 -0
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js +1 -0
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -0
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/worktrees/[id]/page.js +21 -0
- package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -0
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/worktrees/[id]/simple-terminal/page.js +4 -0
- package/.next/server/app/worktrees/[id]/simple-terminal/page.js.nft.json +1 -0
- package/.next/server/app/worktrees/[id]/simple-terminal/page_client-reference-manifest.js +1 -0
- package/.next/server/app/worktrees/[id]/terminal/page.js +6 -0
- package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -0
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -0
- package/.next/server/app-paths-manifest.json +46 -0
- package/.next/server/chunks/1318.js +29 -0
- package/.next/server/chunks/1528.js +1 -0
- package/.next/server/chunks/1682.js +6 -0
- package/.next/server/chunks/2518.js +12 -0
- package/.next/server/chunks/3053.js +1 -0
- package/.next/server/chunks/3673.js +1 -0
- package/.next/server/chunks/3853.js +1 -0
- package/.next/server/chunks/434.js +1 -0
- package/.next/server/chunks/4471.js +2 -0
- package/.next/server/chunks/4893.js +2 -0
- package/.next/server/chunks/5972.js +12 -0
- package/.next/server/chunks/6550.js +1 -0
- package/.next/server/chunks/6621.js +1 -0
- package/.next/server/chunks/7213.js +1 -0
- package/.next/server/chunks/7425.js +500 -0
- package/.next/server/chunks/8585.js +1 -0
- package/.next/server/chunks/8887.js +1 -0
- package/.next/server/chunks/8948.js +2 -0
- package/.next/server/chunks/9703.js +31 -0
- package/.next/server/chunks/9723.js +19 -0
- package/.next/server/chunks/font-manifest.json +1 -0
- package/.next/server/edge-runtime-webpack.js +2 -0
- package/.next/server/edge-runtime-webpack.js.map +1 -0
- package/.next/server/font-manifest.json +1 -0
- package/.next/server/functions-config-manifest.json +1 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -0
- package/.next/server/middleware-manifest.json +32 -0
- package/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +1 -0
- package/.next/server/pages/404.html +1 -0
- package/.next/server/pages/500.html +1 -0
- package/.next/server/pages/_app.js +1 -0
- package/.next/server/pages/_app.js.nft.json +1 -0
- package/.next/server/pages/_document.js +1 -0
- package/.next/server/pages/_document.js.nft.json +1 -0
- package/.next/server/pages/_error.js +1 -0
- package/.next/server/pages/_error.js.nft.json +1 -0
- package/.next/server/pages-manifest.json +1 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +1 -0
- package/.next/server/src/middleware.js +14 -0
- package/.next/server/src/middleware.js.map +1 -0
- package/.next/server/webpack-runtime.js +1 -0
- package/.next/static/3jNZMmFnQhc5G7met-OU4/_buildManifest.js +1 -0
- package/.next/static/3jNZMmFnQhc5G7met-OU4/_ssgManifest.js +1 -0
- package/.next/static/chunks/0dbeb660.3e800dfbd28be3bd.js +53 -0
- package/.next/static/chunks/1015.0eaa4da7f61149bc.js +59 -0
- package/.next/static/chunks/1098.49268c9fe1b028fa.js +1 -0
- package/.next/static/chunks/13.feeafc7cc620f8c4.js +1 -0
- package/.next/static/chunks/1423.7b1e8bf760d28078.js +1 -0
- package/.next/static/chunks/1582.9f8590f71ff798ca.js +55 -0
- package/.next/static/chunks/1817.a66d96cedb761daa.js +262 -0
- package/.next/static/chunks/2117-d845c2cd62e344a6.js +2 -0
- package/.next/static/chunks/2398.0b21e4eb7006a230.js +93 -0
- package/.next/static/chunks/2526.8ac62b527c9ab703.js +43 -0
- package/.next/static/chunks/2626.2125083a1ff3b80a.js +29 -0
- package/.next/static/chunks/2689.720a4874b02d4211.js +174 -0
- package/.next/static/chunks/2853-d11a80b03c9a1640.js +1 -0
- package/.next/static/chunks/2957-327e43ef4c12808f.js +1 -0
- package/.next/static/chunks/2cdb6380.35626fc6e41bbba4.js +136 -0
- package/.next/static/chunks/30d07d85-393352a92199f695.js +3 -0
- package/.next/static/chunks/3559.f073f72c4466ce0e.js +1 -0
- package/.next/static/chunks/3574.7a94c27e6a496a56.js +63 -0
- package/.next/static/chunks/383.20683891c9a5f2c4.js +4 -0
- package/.next/static/chunks/3843.3fdda732987f7bb8.js +1 -0
- package/.next/static/chunks/3852.822389f445c9b427.js +1 -0
- package/.next/static/chunks/3991.4bc063cb5be3a86c.js +1 -0
- package/.next/static/chunks/4212.52c1bb34fc97d0d0.js +131 -0
- package/.next/static/chunks/4327.3b84aa049900fdeb.js +60 -0
- package/.next/static/chunks/4362.7bd6f0282e49d79b.js +1 -0
- package/.next/static/chunks/4721.40615a5f4f32b5fb.js +1 -0
- package/.next/static/chunks/4851-45df4d388db5623f.js +1 -0
- package/.next/static/chunks/5112.17318d1c6b28044b.js +1 -0
- package/.next/static/chunks/5126.93fa4e797d609286.js +56 -0
- package/.next/static/chunks/5387.47590ac4ef66c864.js +5 -0
- package/.next/static/chunks/5813.4483664ba482beb1.js +1 -0
- package/.next/static/chunks/6143.1450875bd03a2366.js +36 -0
- package/.next/static/chunks/6406.9653f0d41ab85059.js +1 -0
- package/.next/static/chunks/656.d72f25ce819bd77e.js +149 -0
- package/.next/static/chunks/6678.492e73ca42b2a273.js +62 -0
- package/.next/static/chunks/6725-f7607851b7d57eb1.js +1 -0
- package/.next/static/chunks/6792.3c01ac4dda4b5c6d.js +1 -0
- package/.next/static/chunks/7004.808cbf327ef5955e.js +1 -0
- package/.next/static/chunks/7290.09ef84cf94f90c4d.js +1 -0
- package/.next/static/chunks/7415.6b481c2baf363262.js +148 -0
- package/.next/static/chunks/7648-325564a6e12a3257.js +1 -0
- package/.next/static/chunks/7665.47fccad04449a8f9.js +215 -0
- package/.next/static/chunks/7753.6bdce86b7fde3d10.js +166 -0
- package/.next/static/chunks/8125.245a9df052d274fb.js +1 -0
- package/.next/static/chunks/816-7e340dad784be28c.js +1 -0
- package/.next/static/chunks/8288.4883743fa40672e2.js +24 -0
- package/.next/static/chunks/8522.1607e96011c66877.js +1 -0
- package/.next/static/chunks/8772.863c564498d88487.js +1 -0
- package/.next/static/chunks/8841.dadeb1ece8e46004.js +1 -0
- package/.next/static/chunks/8885.f8d9912b40d74811.js +1 -0
- package/.next/static/chunks/90542734.c1553d0fe7fc14fc.js +1 -0
- package/.next/static/chunks/9365-733d8c05712d2888.js +1 -0
- package/.next/static/chunks/9552.b7dfb7903ead934b.js +1 -0
- package/.next/static/chunks/9834.295b45635ce04f5e.js +24 -0
- package/.next/static/chunks/app/_not-found/page-a9d04e58c81115ec.js +1 -0
- package/.next/static/chunks/app/layout-37e55f11dcc8b1bf.js +1 -0
- package/.next/static/chunks/app/page-9cd00de9cc0abc43.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-9e5adf57cbbbdf05.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-8c6676303b63fdaf.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/simple-terminal/page-16feb3e86e42f4d1.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-be802baffc84dbd2.js +1 -0
- package/.next/static/chunks/d3ac728e.6c9c508274d4d2d5.js +1 -0
- package/.next/static/chunks/fd9d1056-bbe86e4ae099d5cd.js +1 -0
- package/.next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
- package/.next/static/chunks/main-a960f4a5e1a2f598.js +1 -0
- package/.next/static/chunks/main-app-420d93e43682fee5.js +1 -0
- package/.next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
- package/.next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
- package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/static/chunks/webpack-3fc79fab9bb738d7.js +1 -0
- package/.next/static/css/5eacd01f773eed7f.css +11 -0
- package/.next/static/css/85fa6dafca566008.css +1 -0
- package/.next/static/css/e174aa24f94ce607.css +3 -0
- package/.next/trace +5 -0
- package/.next/types/app/api/external-apps/[id]/health/route.ts +343 -0
- package/.next/types/app/api/external-apps/[id]/route.ts +343 -0
- package/.next/types/app/api/external-apps/route.ts +343 -0
- package/.next/types/app/api/hooks/claude-done/route.ts +343 -0
- package/.next/types/app/api/repositories/clone/[jobId]/route.ts +343 -0
- package/.next/types/app/api/repositories/clone/route.ts +343 -0
- package/.next/types/app/api/repositories/route.ts +343 -0
- package/.next/types/app/api/repositories/scan/route.ts +343 -0
- package/.next/types/app/api/repositories/sync/route.ts +343 -0
- package/.next/types/app/api/slash-commands/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/auto-yes/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/capture/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/cli-tool/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/current-output/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/files/[...path]/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/interrupt/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/kill-session/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/logs/[filename]/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/logs/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/memos/[memoId]/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/memos/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/messages/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/prompt-response/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/respond/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/search/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/send/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/slash-commands/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/start-polling/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/terminal/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/tree/[...path]/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/tree/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/upload/[...path]/route.ts +343 -0
- package/.next/types/app/api/worktrees/[id]/viewed/route.ts +343 -0
- package/.next/types/app/api/worktrees/route.ts +343 -0
- package/.next/types/app/page.ts +79 -0
- package/.next/types/app/proxy/[...path]/route.ts +343 -0
- package/.next/types/app/worktrees/[id]/files/[...path]/page.ts +79 -0
- package/.next/types/app/worktrees/[id]/page.ts +79 -0
- package/.next/types/app/worktrees/[id]/simple-terminal/page.ts +79 -0
- package/.next/types/app/worktrees/[id]/terminal/page.ts +79 -0
- package/.next/types/package.json +1 -0
- package/README.md +39 -8
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +143 -27
- package/dist/cli/types/index.d.ts +18 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/env-setup.d.ts +25 -0
- package/dist/cli/utils/env-setup.d.ts.map +1 -1
- package/dist/cli/utils/env-setup.js +56 -1
- package/dist/cli/utils/prompt.d.ts +68 -0
- package/dist/cli/utils/prompt.d.ts.map +1 -0
- package/dist/cli/utils/prompt.js +208 -0
- package/dist/server/server.js +123 -0
- package/dist/server/src/lib/claude-output.js +33 -0
- package/dist/server/src/lib/claude-session.js +312 -0
- package/dist/server/src/lib/cli-patterns.js +137 -0
- package/dist/server/src/lib/cli-session.js +73 -0
- package/dist/server/src/lib/cli-tools/base.js +51 -0
- package/dist/server/src/lib/cli-tools/claude.js +65 -0
- package/dist/server/src/lib/cli-tools/codex.js +132 -0
- package/dist/server/src/lib/cli-tools/gemini.js +122 -0
- package/dist/server/src/lib/cli-tools/index.js +22 -0
- package/dist/server/src/lib/cli-tools/manager.js +143 -0
- package/dist/server/src/lib/cli-tools/types.js +5 -0
- package/dist/server/src/lib/conversation-logger.js +25 -0
- package/dist/server/src/lib/db-instance.js +51 -0
- package/dist/server/src/lib/db-migrations.js +777 -0
- package/dist/server/src/lib/db.js +835 -0
- package/dist/server/src/lib/env.js +179 -0
- package/dist/server/src/lib/log-manager.js +234 -0
- package/dist/server/src/lib/logger.js +232 -0
- package/dist/server/src/lib/prompt-detector.js +285 -0
- package/dist/server/src/lib/response-poller.js +638 -0
- package/dist/server/src/lib/tmux.js +299 -0
- package/dist/server/src/lib/worktrees.js +231 -0
- package/dist/server/src/lib/ws-server.js +323 -0
- package/dist/server/src/types/clone.js +39 -0
- package/dist/server/src/types/conversation.js +9 -0
- package/dist/server/src/types/external-apps.js +6 -0
- package/dist/server/src/types/infinite-messages.js +65 -0
- package/dist/server/src/types/markdown-editor.js +94 -0
- package/dist/server/src/types/models.js +5 -0
- package/dist/server/src/types/sidebar.js +89 -0
- package/dist/server/src/types/slash-commands.js +47 -0
- package/dist/server/src/types/ui-actions.js +8 -0
- package/dist/server/src/types/ui-state.js +62 -0
- 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; } });
|