vibetree 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/bin/vibetree.js +17 -54
  2. package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/package.json +2 -2
  3. package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/package.json +2 -2
  4. package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/package.json +2 -2
  5. package/.vibetree/worktrees/3020aa56-a7a7-46c4-a452-b558cf6eadfd/server/router.ts +274 -0
  6. package/.vibetree/worktrees/32fa1562-8457-4084-b833-db88c38d249e/client/dist/assets/{index-ZqVhjef4.js → index-LGdAMmu9.js} +39 -39
  7. package/.vibetree/worktrees/32fa1562-8457-4084-b833-db88c38d249e/client/dist/assets/index-O9kV9afk.css +32 -0
  8. package/.vibetree/worktrees/32fa1562-8457-4084-b833-db88c38d249e/client/dist/index.html +2 -2
  9. package/.vibetree/worktrees/32fa1562-8457-4084-b833-db88c38d249e/client/src/App.tsx +0 -27
  10. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/.github/workflows/lint.yml +26 -0
  11. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/.github/workflows/test.yml +29 -0
  12. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/.node-version +1 -0
  13. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/bin/vibetree.js +84 -0
  14. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/.eslintrc.cjs +21 -0
  15. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/index.html +16 -0
  16. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/package.json +40 -0
  17. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/postcss.config.js +6 -0
  18. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/public/favicon.svg +28 -0
  19. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/App.tsx +161 -0
  20. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/components/ConfirmationModal.tsx +33 -0
  21. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/components/CreateTaskModal.tsx +62 -0
  22. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/components/KanbanBoard.tsx +111 -0
  23. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/components/LanguageSelector.tsx +67 -0
  24. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/components/RepoModal.tsx +155 -0
  25. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/components/TaskDetail.tsx +165 -0
  26. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/context/TaskContext.tsx +91 -0
  27. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/context/TerminalContext.tsx +89 -0
  28. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/i18n/config.ts +36 -0
  29. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/i18n/locales/en.json +64 -0
  30. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/i18n/locales/ja.json +64 -0
  31. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/i18n/locales/ko.json +64 -0
  32. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/i18n/locales/zh.json +64 -0
  33. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/index.css +31 -0
  34. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/main.tsx +11 -0
  35. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/trpc.ts +4 -0
  36. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/src/types.ts +39 -0
  37. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/tailwind.config.js +22 -0
  38. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/tsconfig.json +25 -0
  39. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/tsconfig.node.json +11 -0
  40. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/client/vite.config.ts +29 -0
  41. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/package.json +69 -0
  42. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/README_TESTS.md +118 -0
  43. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/config.js +45 -0
  44. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/db.js +208 -0
  45. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/git.js +100 -0
  46. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/index.js +121 -0
  47. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/router.js +278 -0
  48. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/tasks.js +7 -0
  49. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/terminal.js +203 -0
  50. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/trpc.js +7 -0
  51. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/types.js +2 -0
  52. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/dist/vitest.config.js +19 -0
  53. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/package.json +44 -0
  54. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/tsconfig.json +20 -0
  55. package/.vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server/vitest.config.ts +18 -0
  56. package/bin/vibetree.js +17 -54
  57. package/client/package.json +2 -2
  58. package/client/src/App.tsx +1 -0
  59. package/client/src/trpc.ts +1 -1
  60. package/client/vite.config.ts +10 -0
  61. package/package.json +2 -2
  62. package/server/dist/api/router.js +278 -0
  63. package/server/dist/api/trpc.js +7 -0
  64. package/server/dist/config/index.js +45 -0
  65. package/server/dist/db.js +3 -2
  66. package/server/dist/index.js +6 -6
  67. package/server/dist/services/db.js +209 -0
  68. package/server/dist/services/git.js +100 -0
  69. package/server/dist/services/tasks.js +7 -0
  70. package/server/dist/services/terminal.js +203 -0
  71. package/server/dist/src/api/router.js +278 -0
  72. package/server/dist/src/api/trpc.js +7 -0
  73. package/server/dist/src/config/index.js +45 -0
  74. package/server/dist/src/index.js +121 -0
  75. package/server/dist/src/services/db.js +209 -0
  76. package/server/dist/src/services/git.js +100 -0
  77. package/server/dist/src/services/tasks.js +7 -0
  78. package/server/dist/src/services/terminal.js +203 -0
  79. package/server/dist/src/types/index.js +2 -0
  80. package/server/dist/types/index.js +2 -0
  81. package/server/package.json +2 -2
  82. package/server/{router.ts → src/api/router.ts} +5 -5
  83. package/server/src/api/trpc.ts +16 -0
  84. package/server/src/config/index.ts +43 -0
  85. package/server/src/index.ts +112 -0
  86. package/server/src/services/db.ts +217 -0
  87. package/server/src/services/git.ts +108 -0
  88. package/server/src/services/tasks.ts +8 -0
  89. package/server/src/services/terminal.ts +181 -0
  90. package/server/src/types/index.ts +33 -0
  91. package/server/tsconfig.json +3 -3
  92. package/.vibetree/worktrees/32fa1562-8457-4084-b833-db88c38d249e/client/dist/assets/index-CID86LBU.css +0 -32
  93. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/.github/workflows/lint.yml +0 -0
  94. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/.github/workflows/test.yml +0 -0
  95. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/.node-version +0 -0
  96. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/.eslintrc.cjs +0 -0
  97. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/index.html +0 -0
  98. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/postcss.config.js +0 -0
  99. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/public/favicon.svg +0 -0
  100. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/App.tsx +0 -0
  101. /package/.vibetree/worktrees/{32fa1562-8457-4084-b833-db88c38d249e → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/assets/react.svg +0 -0
  102. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/components/ConfirmationModal.tsx +0 -0
  103. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/components/CreateTaskModal.tsx +0 -0
  104. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/components/KanbanBoard.tsx +0 -0
  105. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/components/LanguageSelector.tsx +0 -0
  106. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/components/RepoModal.tsx +0 -0
  107. /package/.vibetree/worktrees/{32fa1562-8457-4084-b833-db88c38d249e → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/components/Tabs.tsx +0 -0
  108. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/components/TaskDetail.tsx +0 -0
  109. /package/.vibetree/worktrees/{32fa1562-8457-4084-b833-db88c38d249e → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/components/TerminalView.tsx +0 -0
  110. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/context/TaskContext.tsx +0 -0
  111. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/context/TerminalContext.tsx +0 -0
  112. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/i18n/config.ts +0 -0
  113. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/i18n/locales/en.json +0 -0
  114. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/i18n/locales/ja.json +0 -0
  115. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/i18n/locales/ko.json +0 -0
  116. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/i18n/locales/zh.json +0 -0
  117. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/index.css +0 -0
  118. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/main.tsx +0 -0
  119. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/trpc.ts +0 -0
  120. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/src/types.ts +0 -0
  121. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/tailwind.config.js +0 -0
  122. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/tsconfig.json +0 -0
  123. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/tsconfig.node.json +0 -0
  124. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/client/vite.config.ts +0 -0
  125. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/README_TESTS.md +0 -0
  126. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/config.test.ts +0 -0
  127. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/config.ts +0 -0
  128. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/db.test.ts +0 -0
  129. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/db.ts +0 -0
  130. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/git.test.ts +0 -0
  131. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/git.ts +0 -0
  132. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/index.ts +0 -0
  133. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/router.test.ts +0 -0
  134. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/tasks.test.ts +0 -0
  135. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/tasks.ts +0 -0
  136. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/terminal.ts +0 -0
  137. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/trpc.ts +0 -0
  138. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/tsconfig.json +0 -0
  139. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/types.ts +0 -0
  140. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 3020aa56-a7a7-46c4-a452-b558cf6eadfd}/server/vitest.config.ts +0 -0
  141. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 46276a4e-dc74-4ca3-acd1-96feb2ecf3ad}/client/src/assets/react.svg +0 -0
  142. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 46276a4e-dc74-4ca3-acd1-96feb2ecf3ad}/client/src/components/Tabs.tsx +0 -0
  143. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 46276a4e-dc74-4ca3-acd1-96feb2ecf3ad}/client/src/components/TerminalView.tsx +0 -0
  144. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/config.test.ts +0 -0
  145. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/config.ts +0 -0
  146. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/db.test.ts +0 -0
  147. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/db.ts +0 -0
  148. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/git.test.ts +0 -0
  149. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/git.ts +0 -0
  150. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/index.ts +0 -0
  151. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/router.test.ts +0 -0
  152. /package/.vibetree/worktrees/{d9baadc6-9864-472d-afa8-ee208877e85f → 46276a4e-dc74-4ca3-acd1-96feb2ecf3ad}/server/router.ts +0 -0
  153. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/tasks.test.ts +0 -0
  154. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/tasks.ts +0 -0
  155. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/terminal.ts +0 -0
  156. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/trpc.ts +0 -0
  157. /package/{server → .vibetree/worktrees/46276a4e-dc74-4ca3-acd1-96feb2ecf3ad/server}/types.ts +0 -0
@@ -4,77 +4,40 @@ const path = require('path');
4
4
  const { spawn, spawnSync } = require('child_process');
5
5
  const yargs = require('yargs/yargs');
6
6
  const { hideBin } = require('yargs/helpers');
7
- const prompts = require('prompts');
8
7
  // const open = require('open'); // Moved to dynamic import
9
8
 
10
- const argv = yargs(hideBin(process.argv))
11
- .option('repo', {
12
- alias: 'r',
13
- type: 'string',
14
- description: 'Path to target repository',
15
- })
16
- .option('ai', {
17
- alias: 'a',
18
- type: 'string',
19
- choices: ['claude', 'codex', 'gemini'],
20
- description: 'AI tool to use',
21
- })
22
- .argv;
9
+ const argv = yargs(hideBin(process.argv)).argv;
23
10
 
24
- (async () => {
25
- const PORT = process.env.VIBETREE_PORT || 5179;
26
-
27
- // 1. Resolve Repo Path
28
- let repoPath = argv.repo ? path.resolve(argv.repo) : process.cwd();
29
-
30
- if (!fs.existsSync(repoPath) || !fs.statSync(repoPath).isDirectory()) {
31
- console.error(`Error: Repository path does not exist: ${repoPath}`);
32
- process.exit(1);
33
- }
34
-
35
- // 2. Resolve AI Tool
36
- const configPath = path.join(repoPath, '.vibetree', 'config.json');
37
- let config = {};
38
- if (fs.existsSync(configPath)) {
39
- try {
40
- config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
41
- } catch (e) { }
11
+ async function verifyNativeModules(pkgRoot) {
12
+ try {
13
+ require(require.resolve('node-pty', { paths: [path.join(pkgRoot, 'node_modules'), pkgRoot] }));
14
+ require(require.resolve('better-sqlite3', { paths: [path.join(pkgRoot, 'node_modules'), pkgRoot] }));
15
+ } catch (e) {
16
+ if (e.code === 'ERR_DLOPEN_FAILED' || (e.message && e.message.includes('Node.js version'))) {
17
+ console.log('\x1b[33m%s\x1b[0m', 'Binary mismatch detected. Rebuilding native modules for your Node.js version...');
18
+ spawnSync('npm', ['rebuild', 'node-pty', 'better-sqlite3'], { cwd: pkgRoot, stdio: 'inherit', shell: true });
19
+ }
42
20
  }
21
+ }
43
22
 
44
- let aiTool = argv.ai || config.aiTool;
23
+ (async () => {
24
+ const pkgRoot = path.join(__dirname, '..');
45
25
 
46
- if (!aiTool) {
47
- const response = await prompts({
48
- type: 'select',
49
- name: 'aiTool',
50
- message: 'Select AI tool to use:',
51
- choices: [
52
- { title: 'Claude', value: 'claude' },
53
- { title: 'Codex (OpenAI)', value: 'codex' },
54
- { title: 'Gemini', value: 'gemini' },
55
- ],
56
- });
57
- aiTool = response.aiTool;
26
+ // Verify native modules before proceeding
27
+ await verifyNativeModules(pkgRoot);
58
28
 
59
- // Save preference
60
- const vibeDir = path.join(repoPath, '.vibetree');
61
- if (!fs.existsSync(vibeDir)) fs.mkdirSync(vibeDir, { recursive: true });
62
- fs.writeFileSync(path.join(vibeDir, 'config.json'), JSON.stringify({ aiTool }, null, 2));
63
- }
29
+ const PORT = process.env.VIBETREE_PORT || 5179;
30
+ const repoPath = process.cwd();
64
31
 
65
32
  console.log(`Starting VibeTree...`);
66
- console.log(`Repository: ${repoPath}`);
67
- console.log(`AI Tool: ${aiTool}`);
68
33
  console.log(`Port: ${PORT}`);
69
34
 
70
35
  // 3. Start Server
71
- const pkgRoot = path.join(__dirname, '..');
72
36
  const serverPath = path.join(pkgRoot, 'server', 'dist', 'index.js');
73
37
  const clientPath = path.join(pkgRoot, 'client', 'dist');
74
38
  const env = {
75
39
  ...process.env,
76
40
  REPO_PATH: repoPath,
77
- AI_TOOL: aiTool,
78
41
  VIBETREE_PORT: PORT,
79
42
  };
80
43
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "client",
3
3
  "private": true,
4
- "version": "1.1.1",
4
+ "version": "1.2.1",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -37,4 +37,4 @@
37
37
  "tailwindcss": "^3.4.19",
38
38
  "vite": "^5.1.0"
39
39
  }
40
- }
40
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibetree",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Local task management with Git worktrees and AI integration",
5
5
  "main": "bin/vibetree.js",
6
6
  "bin": {
@@ -66,4 +66,4 @@
66
66
  "tailwindcss": "^3.4.19",
67
67
  "vite": "^5.1.0"
68
68
  }
69
- }
69
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "server",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -41,4 +41,4 @@
41
41
  "@vitest/ui": "^4.0.18",
42
42
  "vitest": "^4.0.18"
43
43
  }
44
- }
44
+ }
@@ -0,0 +1,274 @@
1
+ import { z } from 'zod';
2
+ import { router, publicProcedure } from './trpc';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ import { Task } from './types';
5
+ import { createWorktree, runGit } from './git';
6
+ import { exec } from 'child_process';
7
+ import util from 'util';
8
+ import os from 'os';
9
+ import path from 'path';
10
+ import fs from 'fs';
11
+ import { saveConfig } from './config';
12
+ import {
13
+ getRepositories,
14
+ getRepositoryByPath,
15
+ addRepository,
16
+ getTasks,
17
+ getTaskById,
18
+ createTask,
19
+ updateTask,
20
+ deleteTask,
21
+ normalizePath
22
+ } from './db';
23
+
24
+ const execAsync = util.promisify(exec);
25
+
26
+ function slugify(text: string): string {
27
+ return text
28
+ .toString()
29
+ .normalize('NFD')
30
+ .replace(/[\u0300-\u036f]/g, '')
31
+ .toLowerCase()
32
+ .trim()
33
+ .replace(/\s+/g, '-')
34
+ .replace(/[^\w-]+/g, '')
35
+ .replace(/--+/g, '-');
36
+ }
37
+
38
+ export const appRouter = router({
39
+ // Config Procedures
40
+ getConfig: publicProcedure.query(({ ctx }) => {
41
+ return ctx.getState();
42
+ }),
43
+ updateConfig: publicProcedure
44
+ .input(z.object({
45
+ repoPath: z.string().optional(),
46
+ aiTool: z.string().optional(),
47
+ copyFiles: z.string().optional(),
48
+ }))
49
+ .mutation(async ({ input, ctx }) => {
50
+ const state = ctx.getState();
51
+ if (input.repoPath !== undefined) {
52
+ if (input.repoPath && !fs.existsSync(input.repoPath)) {
53
+ throw new Error('Path does not exist');
54
+ }
55
+ const normalized = normalizePath(input.repoPath || '');
56
+ state.repoPath = normalized;
57
+ if (normalized) {
58
+ addRepository(normalized, input.copyFiles);
59
+ }
60
+ }
61
+ if (input.aiTool !== undefined) state.aiTool = input.aiTool;
62
+ if (input.copyFiles !== undefined) {
63
+ state.copyFiles = input.copyFiles;
64
+ // Update copyFiles for active repo if it exists
65
+ const repo = getRepositoryByPath(state.repoPath);
66
+ if (repo) {
67
+ const { updateRepository } = await import('./db');
68
+ updateRepository(repo.id, { copyFiles: input.copyFiles });
69
+ }
70
+ }
71
+
72
+ await saveConfig(state);
73
+ return state;
74
+ }),
75
+
76
+ getRepositories: publicProcedure.query(async () => {
77
+ return getRepositories();
78
+ }),
79
+
80
+ addRepository: publicProcedure
81
+ .input(z.object({ path: z.string(), copyFiles: z.string().optional() }))
82
+ .mutation(async ({ input }) => {
83
+ return addRepository(input.path, input.copyFiles);
84
+ }),
85
+
86
+ // Task Procedures
87
+ getTasks: publicProcedure
88
+ .input(z.object({ repoPath: z.string() }))
89
+ .query(async ({ input }) => {
90
+ const repo = getRepositoryByPath(input.repoPath);
91
+ if (!repo) return [];
92
+ return getTasks(repo.id);
93
+ }),
94
+ createTask: publicProcedure
95
+ .input(z.object({
96
+ repoPath: z.string(),
97
+ title: z.string(),
98
+ description: z.string().optional(),
99
+ }))
100
+ .mutation(async ({ input, ctx }) => {
101
+ let repo = getRepositoryByPath(input.repoPath);
102
+ if (!repo) {
103
+ repo = addRepository(input.repoPath);
104
+ }
105
+
106
+ const slug = slugify(input.title);
107
+ const shortHash = uuidv4().split('-')[0];
108
+ const branchName = `feature/task-${slug.substring(0, 50)}-${shortHash}`;
109
+
110
+ const newTask = createTask(repo.id, {
111
+ title: input.title,
112
+ description: input.description || '',
113
+ branchName: branchName
114
+ });
115
+
116
+ // Handle side effects (worktree, terminal, AI)
117
+ if (input.repoPath && ctx.createWorktree && ctx.ensureTerminalForTask && ctx.runAiForTask) {
118
+ try {
119
+ console.log(`[tRPC] Creating worktree for task ${newTask.id} in ${input.repoPath}`);
120
+ await ctx.createWorktree(input.repoPath, newTask.id, newTask.branchName || '');
121
+
122
+ console.log(`[tRPC] Ensuring terminal for task ${newTask.id}`);
123
+ await ctx.ensureTerminalForTask(newTask.id, input.repoPath);
124
+
125
+ console.log(`[tRPC] Running AI for task ${newTask.id}`);
126
+ ctx.runAiForTask(newTask.id, input.repoPath).catch(e => console.error(`[tRPC] runAiForTask error:`, e));
127
+ } catch (e) {
128
+ console.error(`[tRPC] Side effects failed for task ${newTask.id}:`, e);
129
+ }
130
+ }
131
+
132
+ return newTask;
133
+ }),
134
+ updateTask: publicProcedure
135
+ .input(z.object({
136
+ repoPath: z.string(),
137
+ id: z.string(),
138
+ updates: z.object({
139
+ title: z.string().optional(),
140
+ description: z.string().optional(),
141
+ }),
142
+ }))
143
+ .mutation(async ({ input }) => {
144
+ const task = getTaskById(input.id);
145
+ if (!task) throw new Error('Task not found');
146
+ return updateTask(input.id, input.updates);
147
+ }),
148
+ deleteTask: publicProcedure
149
+ .input(z.object({ repoPath: z.string(), taskId: z.string() }))
150
+ .mutation(async ({ input, ctx }) => {
151
+ const task = getTaskById(input.taskId);
152
+ if (!task) throw new Error('Task not found');
153
+
154
+ // Cleanup side effects
155
+ if (ctx.shutdownTerminalForTask) {
156
+ console.log(`[tRPC] Shutting down terminal for task ${input.taskId}`);
157
+ await ctx.shutdownTerminalForTask(input.taskId);
158
+ }
159
+ if (input.repoPath && ctx.removeWorktree) {
160
+ console.log(`[tRPC] Removing worktree and branch for task ${input.taskId} (${task.branchName})`);
161
+ try {
162
+ await ctx.removeWorktree(input.repoPath, input.taskId, task.branchName);
163
+ } catch (e) {
164
+ console.error(`[tRPC] Failed to remove worktree/branch:`, e);
165
+ }
166
+ }
167
+
168
+ deleteTask(input.taskId);
169
+ return { success: true };
170
+ }),
171
+
172
+ // Git Procedures
173
+ getGitStatus: publicProcedure
174
+ .input(z.object({ repoPath: z.string(), taskId: z.string().optional() }))
175
+ .query(async ({ input }) => {
176
+ const cwd = input.taskId ? path.join(input.repoPath, '.vibetree', 'worktrees', input.taskId) : input.repoPath;
177
+ const branch = await runGit('git branch --show-current', cwd, input.repoPath);
178
+ const status = await runGit('git status --short', cwd, input.repoPath);
179
+ return { branch, status };
180
+ }),
181
+ getGitDiff: publicProcedure
182
+ .input(z.object({ repoPath: z.string(), taskId: z.string().optional() }))
183
+ .query(async ({ input }) => {
184
+ const cwd = input.taskId ? path.join(input.repoPath, '.vibetree', 'worktrees', input.taskId) : input.repoPath;
185
+ const diff = await runGit('git diff', cwd, input.repoPath);
186
+ return { diff };
187
+ }),
188
+ createCommit: publicProcedure
189
+ .input(z.object({
190
+ repoPath: z.string(),
191
+ taskId: z.string().optional(),
192
+ message: z.string(),
193
+ }))
194
+ .mutation(async ({ input }) => {
195
+ const cwd = input.taskId ? path.join(input.repoPath, '.vibetree', 'worktrees', input.taskId) : input.repoPath;
196
+ await runGit('git add .', cwd, input.repoPath);
197
+ await runGit(`git commit -m "${input.message}"`, cwd, input.repoPath);
198
+ return { success: true };
199
+ }),
200
+ getWorktreePath: publicProcedure
201
+ .input(z.object({ repoPath: z.string(), taskId: z.string() }))
202
+ .query(({ input }) => {
203
+ const worktreePath = path.join(input.repoPath, '.vibetree', 'worktrees', input.taskId);
204
+ return { path: worktreePath };
205
+ }),
206
+
207
+ // System Procedures
208
+ openDirectory: publicProcedure
209
+ .input(z.object({ path: z.string() }))
210
+ .mutation(async ({ input }) => {
211
+ let command: string;
212
+ switch (os.platform()) {
213
+ case 'darwin':
214
+ command = `open "${input.path}"`;
215
+ break;
216
+ case 'win32':
217
+ command = `start "" "${input.path}"`;
218
+ break;
219
+ default:
220
+ command = `xdg-open "${input.path}"`;
221
+ break;
222
+ }
223
+ await execAsync(command);
224
+ return { success: true };
225
+ }),
226
+ pickFolder: publicProcedure.mutation(async () => {
227
+ let command: string | undefined;
228
+ if (os.platform() === 'darwin') {
229
+ command = `osascript -e 'POSIX path of (choose folder with prompt "Select a Git Repository")'`;
230
+ } else if (os.platform() === 'win32') {
231
+ command = `powershell -Command "Add-Type -AssemblyName System.Windows.Forms; $f = New-Object System.Windows.Forms.FolderBrowserDialog; $f.ShowDialog() | Out-Null; $f.SelectedPath"`;
232
+ } else {
233
+ throw new Error('Directory picker not supported on this platform');
234
+ }
235
+
236
+ const { stdout } = await execAsync(command);
237
+ const resultPath = stdout.trim();
238
+ return resultPath ? { path: resultPath } : { canceled: true };
239
+ }),
240
+ getAiTools: publicProcedure.query(async () => {
241
+ const tools = ['claude', 'codex', 'gemini'];
242
+ const results: Record<string, boolean> = {};
243
+ const commonPaths = [
244
+ '/opt/homebrew/bin',
245
+ '/usr/local/bin',
246
+ '/usr/bin',
247
+ '/bin',
248
+ (process.env.HOME || '') + '/.local/bin',
249
+ (process.env.HOME || '') + '/bin',
250
+ ];
251
+ const envPath = process.env.PATH || '';
252
+ const extendedPath = commonPaths.join(path.delimiter) + path.delimiter + envPath;
253
+
254
+ for (const tool of tools) {
255
+ let found = false;
256
+ try {
257
+ const cmd = os.platform() === 'win32' ? `where ${tool}` : `which ${tool}`;
258
+ const { stdout } = await execAsync(cmd, { env: { ...process.env, PATH: extendedPath } });
259
+ if (stdout.trim()) found = true;
260
+ } catch { }
261
+
262
+ if (!found) {
263
+ for (const p of commonPaths) {
264
+ const binaryPath = path.join(p, tool + (os.platform() === 'win32' ? '.exe' : ''));
265
+ if (fs.existsSync(binaryPath)) { found = true; break; }
266
+ }
267
+ }
268
+ results[tool] = found;
269
+ }
270
+ return results;
271
+ }),
272
+ });
273
+
274
+ export type AppRouter = typeof appRouter;