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,260 +0,0 @@
1
- import fs from 'fs/promises';
2
- import path from 'path';
3
- import matter from 'gray-matter';
4
- import { log } from '../lib/logger.js';
5
- import { getVibeDir } from '../lib/server/project-root.js';
6
- /**
7
- * Updates task markdown files when workflows reach review readiness.
8
- * Handles status updates, todo marking, and implementation summary generation.
9
- */
10
- export class TaskUpdater {
11
- constructor(vibeDir) {
12
- this.tasksDir = path.join(vibeDir || getVibeDir(), 'tasks');
13
- }
14
- /**
15
- * Main entry point: Update task for review readiness
16
- */
17
- async updateTaskForReviewReadiness(taskId, context = {}) {
18
- try {
19
- const taskFilePath = path.join(this.tasksDir, `${taskId}.md`);
20
- // Check if task file exists
21
- try {
22
- await fs.access(taskFilePath);
23
- }
24
- catch (error) {
25
- log.error('Task file not found', { taskId, taskFilePath }, 'task-updater');
26
- throw new Error(`Task file not found: ${taskId}`);
27
- }
28
- // Read and parse the task file
29
- const fileContent = await fs.readFile(taskFilePath, 'utf-8');
30
- const parsed = matter(fileContent);
31
- // Update YAML front-matter status
32
- const updatedFrontMatter = this.updateStatusToReview(parsed.data);
33
- // Process markdown content
34
- const updatedContent = this.processMarkdownContent(parsed.content, context);
35
- // Write back atomically
36
- await this.writeTaskFileAtomically(taskFilePath, updatedFrontMatter, updatedContent);
37
- log.info('Task updated for review readiness', { taskId }, 'task-updater');
38
- }
39
- catch (error) {
40
- log.error('Failed to update task for review readiness', error, 'task-updater');
41
- throw error;
42
- }
43
- }
44
- /**
45
- * Update YAML front-matter to set status to 'review'
46
- */
47
- updateStatusToReview(frontMatter) {
48
- const updated = { ...frontMatter };
49
- // Only update if not already 'done' (preserve completed tasks) - case insensitive
50
- if (updated.status?.toLowerCase() !== 'done') {
51
- updated.status = 'Review';
52
- }
53
- return updated;
54
- }
55
- /**
56
- * Process markdown content: mark todos and add/update implementation summary
57
- */
58
- processMarkdownContent(content, context) {
59
- let processedContent = content;
60
- // Step 1: Mark implementation todos as completed
61
- processedContent = this.markImplementationTodos(processedContent);
62
- // Step 2: Add or update implementation summary
63
- processedContent = this.upsertImplementationSummary(processedContent, context);
64
- return processedContent;
65
- }
66
- /**
67
- * Mark implementation-related todos as completed
68
- */
69
- markImplementationTodos(content) {
70
- const lines = content.split('\n');
71
- let inEligibleSection = false;
72
- let currentSection = '';
73
- const processedLines = lines.map((line) => {
74
- // Track current section
75
- const headerMatch = line.match(/^##\s+(.+)$/i);
76
- if (headerMatch) {
77
- currentSection = headerMatch[1].toLowerCase().trim();
78
- inEligibleSection = this.isEligibleTodoSection(currentSection);
79
- return line;
80
- }
81
- // Reset section tracking on other headers
82
- if (line.match(/^#\s+/)) {
83
- inEligibleSection = false;
84
- currentSection = '';
85
- return line;
86
- }
87
- // Mark todos in eligible sections
88
- if (inEligibleSection && line.match(/^[\s]*-\s+\[\s*\]\s+/)) {
89
- return line.replace(/^([\s]*-\s+)\[\s*\](\s+.*)$/, '$1[x]$2');
90
- }
91
- return line;
92
- });
93
- return processedLines.join('\n');
94
- }
95
- /**
96
- * Check if a section is eligible for todo marking
97
- */
98
- isEligibleTodoSection(sectionName) {
99
- const eligibleSections = [
100
- 'implementation',
101
- 'implementation tasks',
102
- 'tasks',
103
- 'todo',
104
- 'implementation notes',
105
- ];
106
- // Check for exact matches or partial matches
107
- return eligibleSections.some((eligible) => sectionName.includes(eligible) || eligible.includes(sectionName));
108
- }
109
- /**
110
- * Add or update the implementation summary section
111
- */
112
- upsertImplementationSummary(content, context) {
113
- const summary = this.generateImplementationSummary(context);
114
- const summarySection = this.buildImplementationSummarySection(summary);
115
- // Check if implementation summary already exists
116
- const startMarker = '<!-- IMPLEMENTATION_SUMMARY_START -->';
117
- const endMarker = '<!-- IMPLEMENTATION_SUMMARY_END -->';
118
- const startIndex = content.indexOf(startMarker);
119
- const endIndex = content.indexOf(endMarker);
120
- if (startIndex !== -1 && endIndex !== -1) {
121
- // Replace existing summary
122
- const before = content.substring(0, startIndex);
123
- const after = content.substring(endIndex + endMarker.length);
124
- return before + summarySection + after;
125
- }
126
- else {
127
- // Add new summary at the beginning of content (after first header if any)
128
- const lines = content.split('\n');
129
- let insertIndex = 0;
130
- // Find insertion point after description or first header
131
- for (let i = 0; i < lines.length; i++) {
132
- if (lines[i].match(/^##\s+/)) {
133
- insertIndex = i;
134
- break;
135
- }
136
- }
137
- const before = lines.slice(0, insertIndex).join('\n');
138
- const after = lines.slice(insertIndex).join('\n');
139
- const separator = insertIndex > 0 && before.trim() ? '\n\n' : '';
140
- return before + separator + summarySection + '\n\n' + after;
141
- }
142
- }
143
- /**
144
- * Generate implementation summary from context
145
- */
146
- generateImplementationSummary(context) {
147
- const filesChanged = context.filesModified || [];
148
- const keyLogic = context.keyChanges || [];
149
- // Generate tests info
150
- let testsInfo = 'No test information available';
151
- if (context.testsAdded) {
152
- testsInfo = context.testsPassed
153
- ? 'New tests added and passing'
154
- : 'New tests added (status unknown)';
155
- }
156
- else if (context.testsPassed !== undefined) {
157
- testsInfo = context.testsPassed ? 'Existing tests passing' : 'Test failures detected';
158
- }
159
- // Generate quality notes
160
- let qualityNotes = 'Quality checks not run';
161
- if (context.qualityChecksPassed !== undefined) {
162
- qualityNotes = context.qualityChecksPassed
163
- ? 'All quality checks passed'
164
- : 'Quality check failures';
165
- }
166
- if (context.buildPassed !== undefined) {
167
- qualityNotes += context.buildPassed ? ', build successful' : ', build failures detected';
168
- }
169
- if (context.aiReviewScore !== undefined) {
170
- qualityNotes += `, AI review score: ${context.aiReviewScore}`;
171
- }
172
- // Identify remaining risks (only for actual failures, not missing data)
173
- const remainingRisks = [];
174
- if (context.testsPassed === false)
175
- remainingRisks.push('Test failures need investigation');
176
- if (context.qualityChecksPassed === false)
177
- remainingRisks.push('Quality check issues need resolution');
178
- if (context.buildPassed === false)
179
- remainingRisks.push('Build issues need fixing');
180
- if (context.aiReviewScore !== undefined && context.aiReviewScore < 70) {
181
- remainingRisks.push('AI review score below threshold');
182
- }
183
- return {
184
- filesChanged: filesChanged.slice(0, 10), // Limit to 10 files for readability
185
- keyLogic,
186
- testsInfo,
187
- qualityNotes,
188
- remainingRisks,
189
- };
190
- }
191
- /**
192
- * Build the implementation summary markdown section
193
- */
194
- buildImplementationSummarySection(summary) {
195
- const sections = [];
196
- sections.push('<!-- IMPLEMENTATION_SUMMARY_START -->');
197
- sections.push('## Implementation Summary');
198
- sections.push('');
199
- // Files changed
200
- if (summary.filesChanged.length > 0) {
201
- sections.push(`- **Files Modified:** ${summary.filesChanged.length} files updated`);
202
- sections.push('- **Key Files:**');
203
- summary.filesChanged.forEach((file) => {
204
- sections.push(` - \`${file}\``);
205
- });
206
- }
207
- else {
208
- sections.push('- **Files Modified:** No file changes tracked');
209
- }
210
- // Key logic changes
211
- if (summary.keyLogic.length > 0) {
212
- sections.push('- **Key Changes:**');
213
- summary.keyLogic.forEach((change) => {
214
- sections.push(` - ${change}`);
215
- });
216
- }
217
- // Tests and quality
218
- sections.push(`- **Tests:** ${summary.testsInfo}`);
219
- sections.push(`- **Quality Checks:** ${summary.qualityNotes}`);
220
- // Remaining risks
221
- if (summary.remainingRisks.length > 0) {
222
- sections.push('- **Review Notes:** Issues requiring attention:');
223
- summary.remainingRisks.forEach((risk) => {
224
- sections.push(` - ⚠️ ${risk}`);
225
- });
226
- }
227
- else {
228
- sections.push('- **Review Notes:** Ready for manual review and approval');
229
- }
230
- sections.push('');
231
- sections.push('<!-- IMPLEMENTATION_SUMMARY_END -->');
232
- return sections.join('\n');
233
- }
234
- /**
235
- * Write task file atomically using temporary file
236
- */
237
- async writeTaskFileAtomically(filePath, frontMatter, content) {
238
- const tempPath = filePath + '.tmp';
239
- try {
240
- // Normalize content to ensure clean formatting
241
- const normalizedContent = content.replace(/^[\r\n]+/, '').replace(/[\r\n]*$/, '\n');
242
- // Build complete file content
243
- const fileContent = matter.stringify(normalizedContent, frontMatter);
244
- // Write to temporary file first
245
- await fs.writeFile(tempPath, fileContent, 'utf-8');
246
- // Atomic rename
247
- await fs.rename(tempPath, filePath);
248
- }
249
- catch (error) {
250
- // Clean up temp file if it exists
251
- try {
252
- await fs.unlink(tempPath);
253
- }
254
- catch {
255
- // Ignore cleanup errors
256
- }
257
- throw error;
258
- }
259
- }
260
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,303 +0,0 @@
1
- import { describe, beforeEach, afterEach, test, expect, vi } from 'vitest';
2
- import fs from 'fs/promises';
3
- import path from 'path';
4
- import { TaskUpdater } from './task-updater.js';
5
- // Mock fs and path
6
- vi.mock('fs/promises');
7
- vi.mock('../lib/logger.js', () => ({
8
- log: {
9
- info: vi.fn(),
10
- error: vi.fn(),
11
- debug: vi.fn(),
12
- },
13
- }));
14
- vi.mock('../lib/server/project-root.js', () => ({
15
- getVibeDir: vi.fn(() => '/test/vibe'),
16
- }));
17
- const mockFs = fs;
18
- describe('TaskUpdater', () => {
19
- let taskUpdater;
20
- const testTasksDir = '/test/vibe/tasks';
21
- beforeEach(() => {
22
- vi.clearAllMocks();
23
- taskUpdater = new TaskUpdater('/test/vibe');
24
- });
25
- afterEach(() => {
26
- vi.restoreAllMocks();
27
- });
28
- describe('updateTaskForReviewReadiness', () => {
29
- const sampleTaskContent = `---
30
- id: TEST-TASK-123
31
- title: Test Task
32
- type: feature
33
- status: in-progress
34
- tags: ''
35
- priority: medium
36
- ---
37
-
38
- ## Description
39
- This is a test task.
40
-
41
- ## Implementation Tasks
42
- - [ ] Implement feature A
43
- - [ ] Add tests for feature A
44
- - [x] Already completed task
45
-
46
- ## Acceptance Criteria
47
- - [ ] Feature works correctly
48
- - [ ] Tests pass
49
- `;
50
- beforeEach(() => {
51
- mockFs.access = vi.fn().mockResolvedValue(undefined);
52
- mockFs.readFile = vi.fn().mockResolvedValue(sampleTaskContent);
53
- mockFs.writeFile = vi.fn().mockResolvedValue(undefined);
54
- mockFs.rename = vi.fn().mockResolvedValue(undefined);
55
- mockFs.unlink = vi.fn().mockResolvedValue(undefined);
56
- });
57
- test('should update task status to review', async () => {
58
- const context = {
59
- filesModified: ['src/feature.ts', 'tests/feature.test.ts'],
60
- keyChanges: ['Added new feature A', 'Implemented core logic'],
61
- testsPassed: true,
62
- qualityChecksPassed: true,
63
- };
64
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-123', context);
65
- expect(mockFs.access).toHaveBeenCalledWith(path.join(testTasksDir, 'TEST-TASK-123.md'));
66
- expect(mockFs.readFile).toHaveBeenCalledWith(path.join(testTasksDir, 'TEST-TASK-123.md'), 'utf-8');
67
- expect(mockFs.writeFile).toHaveBeenCalled();
68
- expect(mockFs.rename).toHaveBeenCalled();
69
- const writeCall = mockFs.writeFile.mock.calls[0];
70
- const writtenContent = writeCall[1];
71
- // Verify status changed to Review
72
- expect(writtenContent).toContain('status: Review');
73
- // Verify todos are marked as completed
74
- expect(writtenContent).toContain('- [x] Implement feature A');
75
- expect(writtenContent).toContain('- [x] Add tests for feature A');
76
- // Verify acceptance criteria unchanged
77
- expect(writtenContent).toContain('- [ ] Feature works correctly');
78
- expect(writtenContent).toContain('- [ ] Tests pass');
79
- // Verify implementation summary added
80
- expect(writtenContent).toContain('## Implementation Summary');
81
- expect(writtenContent).toContain('IMPLEMENTATION_SUMMARY_START');
82
- expect(writtenContent).toContain('IMPLEMENTATION_SUMMARY_END');
83
- });
84
- test('should not change status if already done', async () => {
85
- const doneTaskContent = sampleTaskContent.replace('status: in-progress', 'status: done');
86
- mockFs.readFile = vi.fn().mockResolvedValue(doneTaskContent);
87
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-123', {});
88
- const writeCall = mockFs.writeFile.mock.calls[0];
89
- const writtenContent = writeCall[1];
90
- expect(writtenContent).toContain('status: done');
91
- expect(writtenContent).not.toContain('status: Review');
92
- });
93
- test('should not change status if already Done (case insensitive)', async () => {
94
- const doneTaskContent = sampleTaskContent.replace('status: in-progress', 'status: Done');
95
- mockFs.readFile = vi.fn().mockResolvedValue(doneTaskContent);
96
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-123', {});
97
- const writeCall = mockFs.writeFile.mock.calls[0];
98
- const writtenContent = writeCall[1];
99
- expect(writtenContent).toContain('status: Done');
100
- expect(writtenContent).not.toContain('status: Review');
101
- });
102
- test('should handle missing task file', async () => {
103
- mockFs.access = vi.fn().mockRejectedValue(new Error('File not found'));
104
- await expect(taskUpdater.updateTaskForReviewReadiness('NONEXISTENT-TASK', {})).rejects.toThrow('Task file not found: NONEXISTENT-TASK');
105
- });
106
- test('should mark only implementation todos, not acceptance criteria', async () => {
107
- const taskWithMixedTodos = `---
108
- id: TEST-TASK-456
109
- title: Mixed Todos Task
110
- type: feature
111
- status: in-progress
112
- tags: ''
113
- priority: medium
114
- ---
115
-
116
- ## Implementation
117
- - [ ] Task 1
118
- - [ ] Task 2
119
-
120
- ## Implementation Tasks
121
- - [ ] Task 3
122
- - [ ] Task 4
123
-
124
- ## Acceptance Criteria
125
- - [ ] AC 1
126
- - [ ] AC 2
127
-
128
- ## Random Section
129
- - [ ] Should not be marked
130
- `;
131
- mockFs.readFile = vi.fn().mockResolvedValue(taskWithMixedTodos);
132
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-456', {});
133
- const writeCall = mockFs.writeFile.mock.calls[0];
134
- const writtenContent = writeCall[1];
135
- // Implementation todos should be marked
136
- expect(writtenContent).toContain('- [x] Task 1');
137
- expect(writtenContent).toContain('- [x] Task 2');
138
- expect(writtenContent).toContain('- [x] Task 3');
139
- expect(writtenContent).toContain('- [x] Task 4');
140
- // Acceptance criteria should remain unchanged
141
- expect(writtenContent).toContain('- [ ] AC 1');
142
- expect(writtenContent).toContain('- [ ] AC 2');
143
- // Random section should remain unchanged
144
- expect(writtenContent).toContain('- [ ] Should not be marked');
145
- });
146
- test('should update existing implementation summary', async () => {
147
- const taskWithExistingSummary = `---
148
- id: TEST-TASK-789
149
- title: Task with Existing Summary
150
- type: feature
151
- status: in-progress
152
- tags: ''
153
- priority: medium
154
- ---
155
-
156
- ## Description
157
- Task description
158
-
159
- <!-- IMPLEMENTATION_SUMMARY_START -->
160
- ## Implementation Summary
161
- Old summary content
162
- <!-- IMPLEMENTATION_SUMMARY_END -->
163
-
164
- ## Implementation
165
- - [ ] Task 1
166
- `;
167
- mockFs.readFile = vi.fn().mockResolvedValue(taskWithExistingSummary);
168
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-789', {
169
- filesModified: ['newfile.ts'],
170
- keyChanges: ['New implementation'],
171
- });
172
- const writeCall = mockFs.writeFile.mock.calls[0];
173
- const writtenContent = writeCall[1];
174
- // Should have new summary, not old
175
- expect(writtenContent).not.toContain('Old summary content');
176
- expect(writtenContent).toContain('**Files Modified:** 1 files updated');
177
- expect(writtenContent).toContain('newfile.ts');
178
- expect(writtenContent).toContain('New implementation');
179
- });
180
- test('should handle atomic write failure by cleaning up temp file', async () => {
181
- mockFs.writeFile = vi.fn().mockRejectedValue(new Error('Write failed'));
182
- mockFs.unlink = vi.fn().mockResolvedValue(undefined);
183
- await expect(taskUpdater.updateTaskForReviewReadiness('TEST-TASK-123', {})).rejects.toThrow('Write failed');
184
- expect(mockFs.unlink).toHaveBeenCalledWith(path.join(testTasksDir, 'TEST-TASK-123.md.tmp'));
185
- });
186
- test('should generate comprehensive implementation summary', async () => {
187
- const context = {
188
- filesModified: ['src/feature.ts', 'tests/feature.test.ts', 'docs/feature.md'],
189
- keyChanges: ['Added feature A', 'Improved performance', 'Fixed edge case'],
190
- testsAdded: true,
191
- testsPassed: true,
192
- buildPassed: true,
193
- qualityChecksPassed: true,
194
- aiReviewScore: 85,
195
- workflowId: 'workflow-123',
196
- };
197
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-123', context);
198
- const writeCall = mockFs.writeFile.mock.calls[0];
199
- const writtenContent = writeCall[1];
200
- // Verify summary content
201
- expect(writtenContent).toContain('**Files Modified:** 3 files updated');
202
- expect(writtenContent).toContain('src/feature.ts');
203
- expect(writtenContent).toContain('tests/feature.test.ts');
204
- expect(writtenContent).toContain('docs/feature.md');
205
- expect(writtenContent).toContain('**Key Changes:**');
206
- expect(writtenContent).toContain('Added feature A');
207
- expect(writtenContent).toContain('Improved performance');
208
- expect(writtenContent).toContain('Fixed edge case');
209
- expect(writtenContent).toContain('**Tests:** New tests added and passing');
210
- expect(writtenContent).toContain('**Quality Checks:** All quality checks passed');
211
- expect(writtenContent).toContain('AI review score: 85');
212
- expect(writtenContent).toContain('Ready for manual review and approval');
213
- });
214
- test('should identify review risks when quality checks fail', async () => {
215
- const context = {
216
- filesModified: ['src/feature.ts'],
217
- testsPassed: false,
218
- buildPassed: false,
219
- qualityChecksPassed: false,
220
- aiReviewScore: 45,
221
- };
222
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-123', context);
223
- const writeCall = mockFs.writeFile.mock.calls[0];
224
- const writtenContent = writeCall[1];
225
- expect(writtenContent).toContain('**Review Notes:** Issues requiring attention:');
226
- expect(writtenContent).toContain('⚠️ Test failures need investigation');
227
- expect(writtenContent).toContain('⚠️ Quality check issues need resolution');
228
- expect(writtenContent).toContain('⚠️ Build issues need fixing');
229
- expect(writtenContent).toContain('⚠️ AI review score below threshold');
230
- });
231
- test('should identify AI review score of 0 as risk', async () => {
232
- const context = {
233
- filesModified: ['src/feature.ts'],
234
- testsPassed: true,
235
- buildPassed: true,
236
- qualityChecksPassed: true,
237
- aiReviewScore: 0,
238
- };
239
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-123', context);
240
- const writeCall = mockFs.writeFile.mock.calls[0];
241
- const writtenContent = writeCall[1];
242
- expect(writtenContent).toContain('**Review Notes:** Issues requiring attention:');
243
- expect(writtenContent).toContain('⚠️ AI review score below threshold');
244
- });
245
- test('should handle edge case with no eligible todo sections', async () => {
246
- const taskWithoutTodos = `---
247
- id: TEST-TASK-NO-TODOS
248
- title: Task Without Implementation Todos
249
- type: feature
250
- status: in-progress
251
- tags: ''
252
- priority: medium
253
- ---
254
-
255
- ## Description
256
- This task has no implementation todos.
257
-
258
- ## Acceptance Criteria
259
- - [ ] Should work
260
- - [ ] Should be tested
261
- `;
262
- mockFs.readFile = vi.fn().mockResolvedValue(taskWithoutTodos);
263
- await taskUpdater.updateTaskForReviewReadiness('TEST-TASK-NO-TODOS', {});
264
- const writeCall = mockFs.writeFile.mock.calls[0];
265
- const writtenContent = writeCall[1];
266
- // Status should still be updated
267
- expect(writtenContent).toContain('status: Review');
268
- // Implementation summary should still be added
269
- expect(writtenContent).toContain('## Implementation Summary');
270
- // Acceptance criteria should remain unchanged
271
- expect(writtenContent).toContain('- [ ] Should work');
272
- expect(writtenContent).toContain('- [ ] Should be tested');
273
- });
274
- test('should handle nested todo lists in implementation sections', async () => {
275
- const taskWithNestedTodos = `---
276
- id: TEST-NESTED
277
- title: Task with Nested Todos
278
- type: feature
279
- status: in-progress
280
- tags: ''
281
- priority: medium
282
- ---
283
-
284
- ## Implementation Tasks
285
- - [ ] Main task 1
286
- - [ ] Subtask 1.1
287
- - [ ] Subtask 1.2
288
- - [ ] Main task 2
289
- - [ ] Subtask 2.1
290
- `;
291
- mockFs.readFile = vi.fn().mockResolvedValue(taskWithNestedTodos);
292
- await taskUpdater.updateTaskForReviewReadiness('TEST-NESTED', {});
293
- const writeCall = mockFs.writeFile.mock.calls[0];
294
- const writtenContent = writeCall[1];
295
- // All todos should be marked, preserving indentation
296
- expect(writtenContent).toContain('- [x] Main task 1');
297
- expect(writtenContent).toContain(' - [x] Subtask 1.1');
298
- expect(writtenContent).toContain(' - [x] Subtask 1.2');
299
- expect(writtenContent).toContain('- [x] Main task 2');
300
- expect(writtenContent).toContain(' - [x] Subtask 2.1');
301
- });
302
- });
303
- });