vibeman 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/dist/api.js +49 -0
  2. package/dist/cli.js +135 -0
  3. package/dist/ui/index-gnk6rhxs.js +9 -0
  4. package/dist/ui/index.html +10 -0
  5. package/dist/ui/index.js +2 -0
  6. package/package.json +10 -46
  7. package/README.md +0 -12
  8. package/dist/index.js +0 -114
  9. package/dist/runtime/api/.tsbuildinfo +0 -1
  10. package/dist/runtime/api/agent/agent-service.d.ts +0 -229
  11. package/dist/runtime/api/agent/agent-service.js +0 -963
  12. package/dist/runtime/api/agent/ai-providers/amp-cli-provider.d.ts +0 -38
  13. package/dist/runtime/api/agent/ai-providers/amp-cli-provider.js +0 -268
  14. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +0 -61
  15. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +0 -362
  16. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +0 -36
  17. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +0 -375
  18. package/dist/runtime/api/agent/ai-providers/gemini-cli-provider.d.ts +0 -24
  19. package/dist/runtime/api/agent/ai-providers/gemini-cli-provider.js +0 -291
  20. package/dist/runtime/api/agent/ai-providers/index.d.ts +0 -9
  21. package/dist/runtime/api/agent/ai-providers/index.js +0 -9
  22. package/dist/runtime/api/agent/ai-providers/types.d.ts +0 -185
  23. package/dist/runtime/api/agent/ai-providers/types.js +0 -5
  24. package/dist/runtime/api/agent/amp-cli-provider.test.d.ts +0 -1
  25. package/dist/runtime/api/agent/amp-cli-provider.test.js +0 -99
  26. package/dist/runtime/api/agent/codex-cli-provider.test.d.ts +0 -1
  27. package/dist/runtime/api/agent/codex-cli-provider.test.js +0 -172
  28. package/dist/runtime/api/agent/core-agent-service.d.ts +0 -119
  29. package/dist/runtime/api/agent/core-agent-service.js +0 -267
  30. package/dist/runtime/api/agent/parsers.d.ts +0 -16
  31. package/dist/runtime/api/agent/parsers.js +0 -308
  32. package/dist/runtime/api/agent/prompt-service.d.ts +0 -30
  33. package/dist/runtime/api/agent/prompt-service.js +0 -452
  34. package/dist/runtime/api/agent/prompt-service.test.d.ts +0 -1
  35. package/dist/runtime/api/agent/prompt-service.test.js +0 -265
  36. package/dist/runtime/api/agent/routing-policy.d.ts +0 -171
  37. package/dist/runtime/api/agent/routing-policy.js +0 -196
  38. package/dist/runtime/api/agent/routing-policy.test.d.ts +0 -1
  39. package/dist/runtime/api/agent/routing-policy.test.js +0 -63
  40. package/dist/runtime/api/api/router-helpers.d.ts +0 -32
  41. package/dist/runtime/api/api/router-helpers.js +0 -31
  42. package/dist/runtime/api/api/routers/ai.d.ts +0 -200
  43. package/dist/runtime/api/api/routers/ai.js +0 -396
  44. package/dist/runtime/api/api/routers/executions.d.ts +0 -93
  45. package/dist/runtime/api/api/routers/executions.js +0 -94
  46. package/dist/runtime/api/api/routers/git.d.ts +0 -45
  47. package/dist/runtime/api/api/routers/git.js +0 -35
  48. package/dist/runtime/api/api/routers/provider-config.d.ts +0 -199
  49. package/dist/runtime/api/api/routers/provider-config.js +0 -252
  50. package/dist/runtime/api/api/routers/settings.d.ts +0 -158
  51. package/dist/runtime/api/api/routers/settings.js +0 -129
  52. package/dist/runtime/api/api/routers/tasks.d.ts +0 -141
  53. package/dist/runtime/api/api/routers/tasks.js +0 -238
  54. package/dist/runtime/api/api/routers/workflows.d.ts +0 -275
  55. package/dist/runtime/api/api/routers/workflows.js +0 -311
  56. package/dist/runtime/api/api/routers/worktrees.d.ts +0 -101
  57. package/dist/runtime/api/api/routers/worktrees.js +0 -80
  58. package/dist/runtime/api/api/trpc.d.ts +0 -118
  59. package/dist/runtime/api/api/trpc.js +0 -34
  60. package/dist/runtime/api/index.d.ts +0 -9
  61. package/dist/runtime/api/index.js +0 -117
  62. package/dist/runtime/api/lib/id-generator.d.ts +0 -70
  63. package/dist/runtime/api/lib/id-generator.js +0 -123
  64. package/dist/runtime/api/lib/local-config.d.ts +0 -335
  65. package/dist/runtime/api/lib/local-config.js +0 -304
  66. package/dist/runtime/api/lib/logger.d.ts +0 -11
  67. package/dist/runtime/api/lib/logger.js +0 -188
  68. package/dist/runtime/api/lib/provider-detection.d.ts +0 -61
  69. package/dist/runtime/api/lib/provider-detection.js +0 -326
  70. package/dist/runtime/api/lib/server/agent-service-singleton.d.ts +0 -6
  71. package/dist/runtime/api/lib/server/agent-service-singleton.js +0 -27
  72. package/dist/runtime/api/lib/server/bootstrap.d.ts +0 -38
  73. package/dist/runtime/api/lib/server/bootstrap.js +0 -197
  74. package/dist/runtime/api/lib/server/git-service-singleton.d.ts +0 -6
  75. package/dist/runtime/api/lib/server/git-service-singleton.js +0 -47
  76. package/dist/runtime/api/lib/server/project-root.d.ts +0 -2
  77. package/dist/runtime/api/lib/server/project-root.js +0 -61
  78. package/dist/runtime/api/lib/server/task-service-singleton.d.ts +0 -7
  79. package/dist/runtime/api/lib/server/task-service-singleton.js +0 -58
  80. package/dist/runtime/api/lib/server/vibeman-info.d.ts +0 -5
  81. package/dist/runtime/api/lib/server/vibeman-info.js +0 -85
  82. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.d.ts +0 -7
  83. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.js +0 -57
  84. package/dist/runtime/api/lib/trpc/server.d.ts +0 -965
  85. package/dist/runtime/api/lib/trpc/server.js +0 -11
  86. package/dist/runtime/api/lib/trpc/ws-server.d.ts +0 -8
  87. package/dist/runtime/api/lib/trpc/ws-server.js +0 -33
  88. package/dist/runtime/api/persistence/database-service.d.ts +0 -14
  89. package/dist/runtime/api/persistence/database-service.js +0 -74
  90. package/dist/runtime/api/persistence/execution-log-persistence.d.ts +0 -90
  91. package/dist/runtime/api/persistence/execution-log-persistence.js +0 -426
  92. package/dist/runtime/api/persistence/execution-log-persistence.test.d.ts +0 -1
  93. package/dist/runtime/api/persistence/execution-log-persistence.test.js +0 -170
  94. package/dist/runtime/api/router.d.ts +0 -968
  95. package/dist/runtime/api/router.js +0 -34
  96. package/dist/runtime/api/settings-service.d.ts +0 -110
  97. package/dist/runtime/api/settings-service.js +0 -678
  98. package/dist/runtime/api/tasks/file-watcher.d.ts +0 -23
  99. package/dist/runtime/api/tasks/file-watcher.js +0 -88
  100. package/dist/runtime/api/tasks/task-file-parser.d.ts +0 -14
  101. package/dist/runtime/api/tasks/task-file-parser.js +0 -180
  102. package/dist/runtime/api/tasks/task-service.d.ts +0 -36
  103. package/dist/runtime/api/tasks/task-service.js +0 -173
  104. package/dist/runtime/api/tasks/task-updater.d.ts +0 -62
  105. package/dist/runtime/api/tasks/task-updater.js +0 -260
  106. package/dist/runtime/api/tasks/task-updater.test.d.ts +0 -1
  107. package/dist/runtime/api/tasks/task-updater.test.js +0 -303
  108. package/dist/runtime/api/types/index.d.ts +0 -186
  109. package/dist/runtime/api/types/index.js +0 -1
  110. package/dist/runtime/api/types/settings.d.ts +0 -105
  111. package/dist/runtime/api/types/settings.js +0 -2
  112. package/dist/runtime/api/types.d.ts +0 -2
  113. package/dist/runtime/api/types.js +0 -1
  114. package/dist/runtime/api/utils/env.d.ts +0 -6
  115. package/dist/runtime/api/utils/env.js +0 -12
  116. package/dist/runtime/api/utils/stripNextEnv.d.ts +0 -7
  117. package/dist/runtime/api/utils/stripNextEnv.js +0 -22
  118. package/dist/runtime/api/utils/title-slug.d.ts +0 -6
  119. package/dist/runtime/api/utils/title-slug.js +0 -77
  120. package/dist/runtime/api/utils/url.d.ts +0 -2
  121. package/dist/runtime/api/utils/url.js +0 -19
  122. package/dist/runtime/api/vcs/git-history-service.d.ts +0 -57
  123. package/dist/runtime/api/vcs/git-history-service.js +0 -228
  124. package/dist/runtime/api/vcs/git-service.d.ts +0 -136
  125. package/dist/runtime/api/vcs/git-service.js +0 -307
  126. package/dist/runtime/api/vcs/worktree-service.d.ts +0 -93
  127. package/dist/runtime/api/vcs/worktree-service.js +0 -518
  128. package/dist/runtime/api/vcs/worktree-service.test.d.ts +0 -1
  129. package/dist/runtime/api/vcs/worktree-service.test.js +0 -20
  130. package/dist/runtime/api/workflows/quality-pipeline.d.ts +0 -58
  131. package/dist/runtime/api/workflows/quality-pipeline.js +0 -401
  132. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +0 -406
  133. package/dist/runtime/api/workflows/vibing-orchestrator.js +0 -2462
  134. package/dist/runtime/api/workflows/workflow-effects.d.ts +0 -45
  135. package/dist/runtime/api/workflows/workflow-effects.js +0 -49
  136. package/dist/runtime/api/workflows/workflow-reconciler.d.ts +0 -65
  137. package/dist/runtime/api/workflows/workflow-reconciler.js +0 -226
  138. package/dist/runtime/api/workflows/workflow-reducer.d.ts +0 -26
  139. package/dist/runtime/api/workflows/workflow-reducer.js +0 -288
  140. package/dist/runtime/api/workflows/workflow-reducer.test.d.ts +0 -1
  141. package/dist/runtime/api/workflows/workflow-reducer.test.js +0 -247
  142. package/dist/runtime/api/workflows/workflow-schema.d.ts +0 -546
  143. package/dist/runtime/api/workflows/workflow-schema.js +0 -256
  144. package/dist/runtime/web/.next/BUILD_ID +0 -1
  145. package/dist/runtime/web/.next/app-build-manifest.json +0 -66
  146. package/dist/runtime/web/.next/app-path-routes-manifest.json +0 -8
  147. package/dist/runtime/web/.next/build-manifest.json +0 -33
  148. package/dist/runtime/web/.next/package.json +0 -1
  149. package/dist/runtime/web/.next/prerender-manifest.json +0 -61
  150. package/dist/runtime/web/.next/react-loadable-manifest.json +0 -8
  151. package/dist/runtime/web/.next/required-server-files.json +0 -334
  152. package/dist/runtime/web/.next/routes-manifest.json +0 -70
  153. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js +0 -1
  154. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js.nft.json +0 -1
  155. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route_client-reference-manifest.js +0 -1
  156. package/dist/runtime/web/.next/server/app/_not-found/page.js +0 -2
  157. package/dist/runtime/web/.next/server/app/_not-found/page.js.nft.json +0 -1
  158. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  159. package/dist/runtime/web/.next/server/app/_not-found.html +0 -7
  160. package/dist/runtime/web/.next/server/app/_not-found.meta +0 -8
  161. package/dist/runtime/web/.next/server/app/_not-found.rsc +0 -22
  162. package/dist/runtime/web/.next/server/app/api/health/route.js +0 -1
  163. package/dist/runtime/web/.next/server/app/api/health/route.js.nft.json +0 -1
  164. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +0 -1
  165. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +0 -1
  166. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js.nft.json +0 -1
  167. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +0 -1
  168. package/dist/runtime/web/.next/server/app/api/upload/route.js +0 -1
  169. package/dist/runtime/web/.next/server/app/api/upload/route.js.nft.json +0 -1
  170. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +0 -1
  171. package/dist/runtime/web/.next/server/app/index.html +0 -7
  172. package/dist/runtime/web/.next/server/app/index.meta +0 -7
  173. package/dist/runtime/web/.next/server/app/index.rsc +0 -27
  174. package/dist/runtime/web/.next/server/app/page.js +0 -112
  175. package/dist/runtime/web/.next/server/app/page.js.nft.json +0 -1
  176. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +0 -1
  177. package/dist/runtime/web/.next/server/app-paths-manifest.json +0 -8
  178. package/dist/runtime/web/.next/server/chunks/210.js +0 -1
  179. package/dist/runtime/web/.next/server/chunks/291.js +0 -18
  180. package/dist/runtime/web/.next/server/chunks/552.js +0 -22
  181. package/dist/runtime/web/.next/server/chunks/780.js +0 -1
  182. package/dist/runtime/web/.next/server/chunks/905.js +0 -6
  183. package/dist/runtime/web/.next/server/chunks/98.js +0 -1
  184. package/dist/runtime/web/.next/server/functions-config-manifest.json +0 -4
  185. package/dist/runtime/web/.next/server/middleware-build-manifest.js +0 -1
  186. package/dist/runtime/web/.next/server/middleware-manifest.json +0 -6
  187. package/dist/runtime/web/.next/server/middleware-react-loadable-manifest.js +0 -1
  188. package/dist/runtime/web/.next/server/next-font-manifest.js +0 -1
  189. package/dist/runtime/web/.next/server/next-font-manifest.json +0 -1
  190. package/dist/runtime/web/.next/server/pages/404.html +0 -7
  191. package/dist/runtime/web/.next/server/pages/500.html +0 -1
  192. package/dist/runtime/web/.next/server/pages/_app.js +0 -1
  193. package/dist/runtime/web/.next/server/pages/_app.js.nft.json +0 -1
  194. package/dist/runtime/web/.next/server/pages/_document.js +0 -1
  195. package/dist/runtime/web/.next/server/pages/_document.js.nft.json +0 -1
  196. package/dist/runtime/web/.next/server/pages/_error.js +0 -19
  197. package/dist/runtime/web/.next/server/pages/_error.js.nft.json +0 -1
  198. package/dist/runtime/web/.next/server/pages-manifest.json +0 -6
  199. package/dist/runtime/web/.next/server/server-reference-manifest.js +0 -1
  200. package/dist/runtime/web/.next/server/server-reference-manifest.json +0 -1
  201. package/dist/runtime/web/.next/server/webpack-runtime.js +0 -1
  202. package/dist/runtime/web/.next/static/LJFZk_8tvKFN_Ee4HqUuM/_buildManifest.js +0 -1
  203. package/dist/runtime/web/.next/static/LJFZk_8tvKFN_Ee4HqUuM/_ssgManifest.js +0 -1
  204. package/dist/runtime/web/.next/static/chunks/05c91ade-7d09b2b280adffd1.js +0 -1
  205. package/dist/runtime/web/.next/static/chunks/201-51bef3fa8c832e2e.js +0 -1
  206. package/dist/runtime/web/.next/static/chunks/524-89747ed9b0294f8a.js +0 -1
  207. package/dist/runtime/web/.next/static/chunks/554-8bec6e9cca6acc67.js +0 -1
  208. package/dist/runtime/web/.next/static/chunks/764.86e9503a69d45a85.js +0 -1
  209. package/dist/runtime/web/.next/static/chunks/7ab4dc20-239138e0ae7af24a.js +0 -1
  210. package/dist/runtime/web/.next/static/chunks/905-342391e3d3a3678f.js +0 -20
  211. package/dist/runtime/web/.next/static/chunks/a8a5ce16-4edea7df2d9b544a.js +0 -79
  212. package/dist/runtime/web/.next/static/chunks/ad74d572-4c1b162e2c15acaa.js +0 -1
  213. package/dist/runtime/web/.next/static/chunks/app/.vibeman/assets/images/[...path]/route-7b752a8641f96c1f.js +0 -1
  214. package/dist/runtime/web/.next/static/chunks/app/_not-found/page-34e66b251c2b5044.js +0 -1
  215. package/dist/runtime/web/.next/static/chunks/app/api/health/route-7b752a8641f96c1f.js +0 -1
  216. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-7b752a8641f96c1f.js +0 -1
  217. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-7b752a8641f96c1f.js +0 -1
  218. package/dist/runtime/web/.next/static/chunks/app/layout-df9ac93cb02b2385.js +0 -1
  219. package/dist/runtime/web/.next/static/chunks/app/page-6610743f7de5f92a.js +0 -1
  220. package/dist/runtime/web/.next/static/chunks/c25e0690-e9b798b8de667da1.js +0 -1
  221. package/dist/runtime/web/.next/static/chunks/framework-57157ec4d37f64aa.js +0 -1
  222. package/dist/runtime/web/.next/static/chunks/main-app-156cc0c60371bd78.js +0 -1
  223. package/dist/runtime/web/.next/static/chunks/main-df25d367c47b1fec.js +0 -1
  224. package/dist/runtime/web/.next/static/chunks/pages/_app-9f629a5e1131d19f.js +0 -1
  225. package/dist/runtime/web/.next/static/chunks/pages/_error-9238238274c7efcd.js +0 -1
  226. package/dist/runtime/web/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  227. package/dist/runtime/web/.next/static/chunks/webpack-cd50e39b423d1808.js +0 -1
  228. package/dist/runtime/web/.next/static/css/2728291c68f99cb1.css +0 -3
  229. package/dist/runtime/web/.next/static/css/4fbf378a264bd4ea.css +0 -1
  230. package/dist/runtime/web/.next/static/css/521bd69cc298cd1a.css +0 -1
  231. package/dist/runtime/web/.next/static/css/537e22821e101b87.css +0 -1
  232. package/dist/runtime/web/.next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  233. package/dist/runtime/web/.next/static/media/21350d82a1f187e9-s.woff2 +0 -0
  234. package/dist/runtime/web/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  235. package/dist/runtime/web/.next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  236. package/dist/runtime/web/.next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  237. package/dist/runtime/web/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  238. package/dist/runtime/web/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  239. package/dist/runtime/web/package.json +0 -65
  240. package/dist/runtime/web/server.js +0 -44
  241. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,228 +0,0 @@
1
- import { simpleGit } from 'simple-git';
2
- import { getProjectRoot } from '../lib/server/project-root.js';
3
- import { log } from '../lib/logger.js';
4
- import path from 'path';
5
- export class GitHistoryService {
6
- constructor(projectRoot = getProjectRoot()) {
7
- this.projectRoot = projectRoot;
8
- this.git = simpleGit(projectRoot);
9
- }
10
- /**
11
- * Get the history of changes for a specific task file
12
- */
13
- async getTaskHistory(taskId, limit = 50) {
14
- try {
15
- const taskFilePath = path.join('.vibeman', 'tasks', `${taskId}.md`);
16
- // Check if the task file exists in the current working directory
17
- const taskExists = await this.git.raw(['ls-files', taskFilePath]).then((output) => output.trim().length > 0, () => false);
18
- if (!taskExists) {
19
- // File doesn't exist in Git, return empty history
20
- return [];
21
- }
22
- // Use --follow to track file through renames and --no-merges to avoid merge commits
23
- const logResult = await this.git.raw([
24
- 'log',
25
- '--follow',
26
- '--no-merges',
27
- '--pretty=format:%H|%h|%an|%ad|%s',
28
- '--date=iso',
29
- `--max-count=${limit}`,
30
- '--',
31
- taskFilePath,
32
- ]);
33
- if (!logResult.trim()) {
34
- return [];
35
- }
36
- const commits = logResult.trim().split('\n');
37
- const history = [];
38
- for (const commitLine of commits) {
39
- const [hash, shortHash, author, dateStr, ...messageParts] = commitLine.split('|');
40
- const message = messageParts.join('|'); // Rejoin in case message contains |
41
- if (!hash || !shortHash || !author || !dateStr) {
42
- continue;
43
- }
44
- try {
45
- // Get the diff stats for this specific file in this commit
46
- const stats = await this.getCommitStats(hash, taskFilePath);
47
- history.push({
48
- commitHash: hash,
49
- shortHash,
50
- author,
51
- date: new Date(dateStr),
52
- message,
53
- changes: stats,
54
- });
55
- }
56
- catch (error) {
57
- log.warn('Failed to get stats for commit', { hash, error }, 'git-history-service');
58
- // Add entry without stats
59
- history.push({
60
- commitHash: hash,
61
- shortHash,
62
- author,
63
- date: new Date(dateStr),
64
- message,
65
- changes: { additions: 0, deletions: 0 },
66
- });
67
- }
68
- }
69
- return history;
70
- }
71
- catch (error) {
72
- log.error('Failed to get task history', { taskId, error }, 'git-history-service');
73
- throw new Error(`Failed to retrieve history for task ${taskId}: ${String(error)}`);
74
- }
75
- }
76
- /**
77
- * Get the content of a task file at a specific commit
78
- */
79
- async getTaskVersionContent(taskId, commitHash) {
80
- try {
81
- const taskFilePath = path.join('.vibeman', 'tasks', `${taskId}.md`);
82
- // Get the file content at the specific commit
83
- const content = await this.git.show([`${commitHash}:${taskFilePath}`]);
84
- // Get commit information
85
- const commitInfo = await this.git.raw([
86
- 'show',
87
- '--pretty=format:%an|%ad',
88
- '--date=iso',
89
- '--no-patch',
90
- commitHash,
91
- ]);
92
- const [author, dateStr] = commitInfo.trim().split('|');
93
- return {
94
- commitHash,
95
- content,
96
- date: new Date(dateStr),
97
- author: author || 'Unknown',
98
- };
99
- }
100
- catch (error) {
101
- log.error('Failed to get task version content', { taskId, commitHash, error }, 'git-history-service');
102
- throw new Error(`Failed to retrieve content for task ${taskId} at commit ${commitHash}: ${String(error)}`);
103
- }
104
- }
105
- /**
106
- * Get the diff between two versions of a task file
107
- */
108
- async getTaskDiff(taskId, fromHash, toHash) {
109
- try {
110
- const taskFilePath = path.join('.vibeman', 'tasks', `${taskId}.md`);
111
- // Get the diff between two commits for the specific file
112
- const diff = await this.git.raw(['diff', `${fromHash}..${toHash}`, '--', taskFilePath]);
113
- // Get diff stats
114
- const stats = await this.git.raw([
115
- 'diff',
116
- '--numstat',
117
- `${fromHash}..${toHash}`,
118
- '--',
119
- taskFilePath,
120
- ]);
121
- let additions = 0;
122
- let deletions = 0;
123
- if (stats.trim()) {
124
- const [addStr, delStr] = stats.trim().split('\t');
125
- additions = parseInt(addStr, 10) || 0;
126
- deletions = parseInt(delStr, 10) || 0;
127
- }
128
- return {
129
- fromHash,
130
- toHash,
131
- diff,
132
- additions,
133
- deletions,
134
- };
135
- }
136
- catch (error) {
137
- log.error('Failed to get task diff', { taskId, fromHash, toHash, error }, 'git-history-service');
138
- throw new Error(`Failed to get diff for task ${taskId} between ${fromHash} and ${toHash}: ${String(error)}`);
139
- }
140
- }
141
- /**
142
- * Check if Git repository exists and is properly configured
143
- */
144
- async isGitRepositoryAvailable() {
145
- try {
146
- const isRepo = await this.git.checkIsRepo();
147
- return isRepo;
148
- }
149
- catch {
150
- return false;
151
- }
152
- }
153
- /**
154
- * Get commit statistics for a specific file in a commit
155
- */
156
- async getCommitStats(commitHash, filePath) {
157
- try {
158
- // Get the parent commit hash
159
- const parentHash = await this.git.raw(['rev-parse', `${commitHash}^`]).catch(() => {
160
- // This is likely the initial commit, compare against empty tree
161
- return '4b825dc642cb6eb9a060e54bf8d69288fbee4904'; // Git's empty tree hash
162
- });
163
- const stats = await this.git.raw([
164
- 'diff',
165
- '--numstat',
166
- parentHash.trim(),
167
- commitHash,
168
- '--',
169
- filePath,
170
- ]);
171
- if (!stats.trim()) {
172
- return { additions: 0, deletions: 0 };
173
- }
174
- const [addStr, delStr] = stats.trim().split('\t');
175
- return {
176
- additions: parseInt(addStr, 10) || 0,
177
- deletions: parseInt(delStr, 10) || 0,
178
- };
179
- }
180
- catch {
181
- return { additions: 0, deletions: 0 };
182
- }
183
- }
184
- /**
185
- * Check if a task file has been renamed or moved by tracking it through Git history
186
- */
187
- async getTaskFileRenames(taskId) {
188
- try {
189
- const taskFilePath = path.join('.vibeman', 'tasks', `${taskId}.md`);
190
- // Use git log --follow --name-status to track renames
191
- const logResult = await this.git.raw([
192
- 'log',
193
- '--follow',
194
- '--name-status',
195
- '--pretty=format:%H',
196
- '--',
197
- taskFilePath,
198
- ]);
199
- const renames = [];
200
- const lines = logResult.trim().split('\n');
201
- let currentCommit = '';
202
- for (const line of lines) {
203
- if (line.match(/^[a-f0-9]{40}$/)) {
204
- // This is a commit hash
205
- currentCommit = line;
206
- }
207
- else if (line.startsWith('R') && currentCommit) {
208
- // This is a rename operation (R100, R090, etc.)
209
- const parts = line.split('\t');
210
- if (parts.length >= 3) {
211
- const oldPath = parts[1];
212
- const newPath = parts[2];
213
- renames.push({
214
- oldPath,
215
- newPath,
216
- commitHash: currentCommit,
217
- });
218
- }
219
- }
220
- }
221
- return renames;
222
- }
223
- catch (error) {
224
- log.warn('Failed to get task file renames', { taskId, error }, 'git-history-service');
225
- return [];
226
- }
227
- }
228
- }
@@ -1,136 +0,0 @@
1
- import { SimpleGit, VersionResult } from 'simple-git';
2
- import { Task } from '../types/index.js';
3
- export interface GitConfig {
4
- remoteUrl?: string;
5
- defaultBranch?: string;
6
- }
7
- export interface BranchInfo {
8
- name: string;
9
- exists: boolean;
10
- isCurrentBranch: boolean;
11
- }
12
- export interface CommitInfo {
13
- hash: string;
14
- message: string;
15
- author: string;
16
- date: Date;
17
- }
18
- export interface WorktreeCreationResult {
19
- path: string;
20
- branchName: string;
21
- existed: boolean;
22
- }
23
- export declare class GitService {
24
- private git;
25
- private config;
26
- private projectRoot;
27
- constructor(projectRoot?: string, config?: GitConfig);
28
- getProjectRoot(): string;
29
- /**
30
- * Validate Git repository exists and is properly configured
31
- */
32
- initializeRepository(): Promise<void>;
33
- /**
34
- * Get current Git status
35
- */
36
- getStatus(): Promise<{
37
- current: string;
38
- staged: string[];
39
- modified: string[];
40
- untracked: string[];
41
- ahead: number;
42
- behind: number;
43
- }>;
44
- /**
45
- * Generate branch name from task
46
- */
47
- generateBranchName(task: Task): string;
48
- /**
49
- * Create a new branch for a task
50
- */
51
- createBranch(task: Task, baseBranch?: string): Promise<BranchInfo>;
52
- /**
53
- * Stage and commit changes
54
- */
55
- commitChanges(task: Task, message?: string, files?: string[]): Promise<CommitInfo>;
56
- /**
57
- * Generate standardized commit message
58
- */
59
- generateCommitMessage(task: Task): string;
60
- /**
61
- * Get commit history for current branch
62
- */
63
- getCommitHistory(maxCount?: number): Promise<CommitInfo[]>;
64
- /**
65
- * Get Git version information
66
- */
67
- getGitVersion(): Promise<VersionResult>;
68
- /**
69
- * Check whether a path is ignored by git.
70
- */
71
- isIgnored(relativePath: string): Promise<boolean>;
72
- /**
73
- * Get the current HEAD commit hash
74
- */
75
- getHeadCommitHash(short?: boolean): Promise<string>;
76
- /**
77
- * List all worktrees in the repository
78
- */
79
- listWorktrees(): Promise<{
80
- path: string;
81
- branch: string;
82
- prunable?: boolean;
83
- }[]>;
84
- /**
85
- * Parse git worktree list output
86
- */
87
- private parseWorktreeList;
88
- /**
89
- * Create a new worktree
90
- */
91
- createWorktree(worktreePath: string, branchName: string, branchExists?: boolean): Promise<void>;
92
- /**
93
- * Remove a worktree
94
- */
95
- removeWorktree(worktreePath: string, force?: boolean): Promise<void>;
96
- /**
97
- * Prune stale worktrees
98
- */
99
- pruneWorktrees(): Promise<void>;
100
- /**
101
- * Delete a local branch
102
- */
103
- deleteLocalBranch(branchName: string, force?: boolean): Promise<void>;
104
- /**
105
- * Check if branch exists locally
106
- */
107
- branchExists(branchName: string): Promise<boolean>;
108
- /**
109
- * Sync with remote repository
110
- */
111
- syncWithRemote(branchName?: string): Promise<void>;
112
- /**
113
- * Get Git instance for a specific directory
114
- */
115
- getGitInstance(directory: string): SimpleGit;
116
- /**
117
- * Check Git status for a specific directory
118
- */
119
- getGitStatus(directory: string): Promise<{
120
- modified: string[];
121
- staged: string[];
122
- not_added: string[];
123
- }>;
124
- /**
125
- * Check if directory has uncommitted changes
126
- */
127
- hasUncommittedChanges(directory?: string): Promise<boolean>;
128
- /**
129
- * Get log for a specific directory/worktree
130
- */
131
- getLog(directory: string, options: string[]): Promise<any>;
132
- /**
133
- * Push branch from specific directory
134
- */
135
- pushFromDirectory(directory: string, remote: string, branchName: string, options?: string[]): Promise<void>;
136
- }
@@ -1,307 +0,0 @@
1
- import { simpleGit } from 'simple-git';
2
- import { log } from '../lib/logger.js';
3
- import { getProjectRoot } from '../lib/server/project-root.js';
4
- export class GitService {
5
- constructor(projectRoot = getProjectRoot(), config = {}) {
6
- this.projectRoot = projectRoot;
7
- this.config = config;
8
- this.git = simpleGit(projectRoot);
9
- }
10
- getProjectRoot() {
11
- return this.projectRoot;
12
- }
13
- /**
14
- * Validate Git repository exists and is properly configured
15
- */
16
- async initializeRepository() {
17
- const isRepo = await this.git.checkIsRepo();
18
- if (!isRepo) {
19
- const error = new Error(`Directory ${this.projectRoot} is not a Git repository. Please run 'git init' first.`);
20
- log.error('Git repository not found', error, 'git-service');
21
- throw error;
22
- }
23
- // Set up basic Git configuration if not present
24
- try {
25
- await this.git.raw(['config', 'user.name']);
26
- }
27
- catch {
28
- await this.git.addConfig('user.name', 'Vibeman');
29
- await this.git.addConfig('user.email', 'vibeman@localhost');
30
- log.info('Set default Git user configuration', undefined, 'git-service');
31
- }
32
- }
33
- /**
34
- * Get current Git status
35
- */
36
- async getStatus() {
37
- const status = await this.git.status();
38
- return {
39
- current: status.current || 'main',
40
- staged: status.staged,
41
- modified: status.modified,
42
- untracked: status.not_added,
43
- ahead: status.ahead,
44
- behind: status.behind,
45
- };
46
- }
47
- /**
48
- * Generate branch name from task
49
- */
50
- generateBranchName(task) {
51
- const typePrefix = {
52
- feature: 'feat',
53
- bug: 'fix',
54
- chore: 'chore',
55
- refactor: 'refactor',
56
- test: 'test',
57
- doc: 'docs',
58
- }[task.type];
59
- // Keep branch concise and deterministic, use only the task id
60
- return `${typePrefix}/${task.id.toLowerCase()}`;
61
- }
62
- /**
63
- * Create a new branch for a task
64
- */
65
- async createBranch(task, baseBranch) {
66
- const branchName = this.generateBranchName(task);
67
- const base = baseBranch || this.config.defaultBranch || 'main';
68
- // Check if branch already exists
69
- const branches = await this.git.branchLocal();
70
- const exists = branches.all.includes(branchName);
71
- if (exists) {
72
- log.info('Branch already exists', { branchName }, 'git-service');
73
- await this.git.checkout(branchName);
74
- return {
75
- name: branchName,
76
- exists: true,
77
- isCurrentBranch: true,
78
- };
79
- }
80
- // Ensure we're on the base branch and it's up to date
81
- try {
82
- await this.git.checkout(base);
83
- await this.git.pull('origin', base);
84
- }
85
- catch (error) {
86
- log.warn('Could not update base branch', error, 'git-service');
87
- }
88
- // Create and checkout new branch
89
- await this.git.checkoutLocalBranch(branchName);
90
- log.info('Created and checked out branch', { branchName }, 'git-service');
91
- return {
92
- name: branchName,
93
- exists: false,
94
- isCurrentBranch: true,
95
- };
96
- }
97
- /**
98
- * Stage and commit changes
99
- */
100
- async commitChanges(task, message, files = ['.']) {
101
- // Stage only the specified files
102
- for (const file of files) {
103
- await this.git.add(file);
104
- }
105
- // Generate commit message if not provided
106
- const commitMessage = message || this.generateCommitMessage(task);
107
- // Commit only the specified files (avoid committing other pre-staged changes)
108
- const result = await this.git.commit(commitMessage, files);
109
- log.info('Committed changes', { commit: result.commit }, 'git-service');
110
- return {
111
- hash: result.commit,
112
- message: commitMessage,
113
- author: 'Vibeman',
114
- date: new Date(),
115
- };
116
- }
117
- /**
118
- * Generate standardized commit message
119
- */
120
- generateCommitMessage(task) {
121
- const typeMap = {
122
- feature: 'feat',
123
- bug: 'fix',
124
- chore: 'chore',
125
- refactor: 'refactor',
126
- test: 'test',
127
- doc: 'docs',
128
- };
129
- const type = typeMap[task.type];
130
- const scope = task.tags.length > 0 ? `(${task.tags[0]})` : '';
131
- return `${type}${scope}: ${task.title}\n\n${task.id}: ${task.title}\n\nImplemented via Vibeman`;
132
- }
133
- /**
134
- * Get commit history for current branch
135
- */
136
- async getCommitHistory(maxCount = 10) {
137
- const log = await this.git.log({ maxCount });
138
- return log.all.map((commit) => ({
139
- hash: commit.hash,
140
- message: commit.message,
141
- author: commit.author_name,
142
- date: new Date(commit.date),
143
- }));
144
- }
145
- /**
146
- * Get Git version information
147
- */
148
- async getGitVersion() {
149
- return await this.git.version();
150
- }
151
- /**
152
- * Check whether a path is ignored by git.
153
- */
154
- async isIgnored(relativePath) {
155
- try {
156
- await this.git.raw(['check-ignore', '-q', relativePath]);
157
- return true;
158
- }
159
- catch (error) {
160
- return false;
161
- }
162
- }
163
- /**
164
- * Get the current HEAD commit hash
165
- */
166
- async getHeadCommitHash(short = true) {
167
- const args = short ? ['--short', 'HEAD'] : ['HEAD'];
168
- const hash = await this.git.revparse(args);
169
- return hash.trim();
170
- }
171
- /**
172
- * List all worktrees in the repository
173
- */
174
- async listWorktrees() {
175
- const worktreeList = await this.git.raw(['worktree', 'list', '--porcelain']);
176
- return this.parseWorktreeList(worktreeList);
177
- }
178
- /**
179
- * Parse git worktree list output
180
- */
181
- parseWorktreeList(output) {
182
- const lines = output.trim().split('\n');
183
- const worktrees = [];
184
- let currentWorktree = {};
185
- for (const line of lines) {
186
- if (line.startsWith('worktree ')) {
187
- if (currentWorktree.path) {
188
- worktrees.push(currentWorktree);
189
- }
190
- currentWorktree = { path: line.substring(9) };
191
- }
192
- else if (line.startsWith('branch ')) {
193
- const ref = line.substring(7);
194
- // Strip refs/heads/ prefix if present for readability
195
- currentWorktree.branch = ref.startsWith('refs/heads/') ? ref.substring(11) : ref;
196
- }
197
- else if (line.startsWith('prunable')) {
198
- currentWorktree.prunable = true;
199
- }
200
- }
201
- if (currentWorktree.path) {
202
- worktrees.push(currentWorktree);
203
- }
204
- return worktrees;
205
- }
206
- /**
207
- * Create a new worktree
208
- */
209
- async createWorktree(worktreePath, branchName, branchExists) {
210
- if (branchExists) {
211
- // Create worktree attached to existing branch (no -b)
212
- await this.git.raw(['worktree', 'add', worktreePath, branchName]);
213
- }
214
- else {
215
- // Create worktree and new branch
216
- await this.git.raw(['worktree', 'add', worktreePath, '-b', branchName]);
217
- }
218
- }
219
- /**
220
- * Remove a worktree
221
- */
222
- async removeWorktree(worktreePath, force = false) {
223
- const args = ['worktree', 'remove', worktreePath];
224
- if (force)
225
- args.push('--force');
226
- await this.git.raw(args);
227
- }
228
- /**
229
- * Prune stale worktrees
230
- */
231
- async pruneWorktrees() {
232
- await this.git.raw(['worktree', 'prune']);
233
- }
234
- /**
235
- * Delete a local branch
236
- */
237
- async deleteLocalBranch(branchName, force = false) {
238
- await this.git.deleteLocalBranch(branchName, force);
239
- }
240
- /**
241
- * Check if branch exists locally
242
- */
243
- async branchExists(branchName) {
244
- const localBranches = await this.git.branchLocal();
245
- return !!localBranches.all.find((b) => b === branchName);
246
- }
247
- /**
248
- * Sync with remote repository
249
- */
250
- async syncWithRemote(branchName) {
251
- try {
252
- const status = await this.git.status();
253
- const currentBranch = branchName || status.current;
254
- if (currentBranch && currentBranch !== 'HEAD') {
255
- await this.git.fetch();
256
- log.info('Synced with remote repository', undefined, 'git-service');
257
- }
258
- }
259
- catch (error) {
260
- log.warn('Could not sync with remote', error, 'git-service');
261
- }
262
- }
263
- /**
264
- * Get Git instance for a specific directory
265
- */
266
- getGitInstance(directory) {
267
- return simpleGit(directory);
268
- }
269
- /**
270
- * Check Git status for a specific directory
271
- */
272
- async getGitStatus(directory) {
273
- const git = this.getGitInstance(directory);
274
- const status = await git.status();
275
- return {
276
- modified: status.modified,
277
- staged: status.staged,
278
- not_added: status.not_added,
279
- };
280
- }
281
- /**
282
- * Check if directory has uncommitted changes
283
- */
284
- async hasUncommittedChanges(directory = this.projectRoot) {
285
- try {
286
- const status = await this.getGitStatus(directory);
287
- return status.modified.length > 0 || status.staged.length > 0 || status.not_added.length > 0;
288
- }
289
- catch {
290
- return false;
291
- }
292
- }
293
- /**
294
- * Get log for a specific directory/worktree
295
- */
296
- async getLog(directory, options) {
297
- const git = this.getGitInstance(directory);
298
- return await git.log(options);
299
- }
300
- /**
301
- * Push branch from specific directory
302
- */
303
- async pushFromDirectory(directory, remote, branchName, options = []) {
304
- const git = this.getGitInstance(directory);
305
- await git.push(remote, branchName, options);
306
- }
307
- }