@codemcp/workflows 3.1.21

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 (159) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.vibe/conversation-state.sqlite +0 -0
  3. package/LICENSE +674 -0
  4. package/dist/index.d.ts +9 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +74 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/notification-service.d.ts +14 -0
  9. package/dist/notification-service.d.ts.map +1 -0
  10. package/dist/notification-service.js +18 -0
  11. package/dist/notification-service.js.map +1 -0
  12. package/dist/resource-handlers/conversation-state.d.ts +15 -0
  13. package/dist/resource-handlers/conversation-state.d.ts.map +1 -0
  14. package/dist/resource-handlers/conversation-state.js +40 -0
  15. package/dist/resource-handlers/conversation-state.js.map +1 -0
  16. package/dist/resource-handlers/development-plan.d.ts +14 -0
  17. package/dist/resource-handlers/development-plan.d.ts.map +1 -0
  18. package/dist/resource-handlers/development-plan.js +31 -0
  19. package/dist/resource-handlers/development-plan.js.map +1 -0
  20. package/dist/resource-handlers/index.d.ts +24 -0
  21. package/dist/resource-handlers/index.d.ts.map +1 -0
  22. package/dist/resource-handlers/index.js +62 -0
  23. package/dist/resource-handlers/index.js.map +1 -0
  24. package/dist/resource-handlers/system-prompt.d.ts +15 -0
  25. package/dist/resource-handlers/system-prompt.d.ts.map +1 -0
  26. package/dist/resource-handlers/system-prompt.js +40 -0
  27. package/dist/resource-handlers/system-prompt.js.map +1 -0
  28. package/dist/resource-handlers/workflow-resource.d.ts +15 -0
  29. package/dist/resource-handlers/workflow-resource.d.ts.map +1 -0
  30. package/dist/resource-handlers/workflow-resource.js +85 -0
  31. package/dist/resource-handlers/workflow-resource.js.map +1 -0
  32. package/dist/response-renderer.d.ts +30 -0
  33. package/dist/response-renderer.d.ts.map +1 -0
  34. package/dist/response-renderer.js +94 -0
  35. package/dist/response-renderer.js.map +1 -0
  36. package/dist/server-config.d.ts +34 -0
  37. package/dist/server-config.d.ts.map +1 -0
  38. package/dist/server-config.js +486 -0
  39. package/dist/server-config.js.map +1 -0
  40. package/dist/server-helpers.d.ts +62 -0
  41. package/dist/server-helpers.d.ts.map +1 -0
  42. package/dist/server-helpers.js +156 -0
  43. package/dist/server-helpers.js.map +1 -0
  44. package/dist/server-implementation.d.ts +74 -0
  45. package/dist/server-implementation.d.ts.map +1 -0
  46. package/dist/server-implementation.js +201 -0
  47. package/dist/server-implementation.js.map +1 -0
  48. package/dist/server.d.ts +6 -0
  49. package/dist/server.d.ts.map +1 -0
  50. package/dist/server.js +5 -0
  51. package/dist/server.js.map +1 -0
  52. package/dist/tool-handlers/base-tool-handler.d.ts +50 -0
  53. package/dist/tool-handlers/base-tool-handler.d.ts.map +1 -0
  54. package/dist/tool-handlers/base-tool-handler.js +74 -0
  55. package/dist/tool-handlers/base-tool-handler.js.map +1 -0
  56. package/dist/tool-handlers/conduct-review.d.ts +49 -0
  57. package/dist/tool-handlers/conduct-review.d.ts.map +1 -0
  58. package/dist/tool-handlers/conduct-review.js +105 -0
  59. package/dist/tool-handlers/conduct-review.js.map +1 -0
  60. package/dist/tool-handlers/get-tool-info.d.ts +76 -0
  61. package/dist/tool-handlers/get-tool-info.d.ts.map +1 -0
  62. package/dist/tool-handlers/get-tool-info.js +168 -0
  63. package/dist/tool-handlers/get-tool-info.js.map +1 -0
  64. package/dist/tool-handlers/index.d.ts +42 -0
  65. package/dist/tool-handlers/index.d.ts.map +1 -0
  66. package/dist/tool-handlers/index.js +74 -0
  67. package/dist/tool-handlers/index.js.map +1 -0
  68. package/dist/tool-handlers/install-workflow.d.ts +48 -0
  69. package/dist/tool-handlers/install-workflow.d.ts.map +1 -0
  70. package/dist/tool-handlers/install-workflow.js +131 -0
  71. package/dist/tool-handlers/install-workflow.js.map +1 -0
  72. package/dist/tool-handlers/list-workflows.d.ts +47 -0
  73. package/dist/tool-handlers/list-workflows.d.ts.map +1 -0
  74. package/dist/tool-handlers/list-workflows.js +58 -0
  75. package/dist/tool-handlers/list-workflows.js.map +1 -0
  76. package/dist/tool-handlers/no-idea.d.ts +41 -0
  77. package/dist/tool-handlers/no-idea.d.ts.map +1 -0
  78. package/dist/tool-handlers/no-idea.js +29 -0
  79. package/dist/tool-handlers/no-idea.js.map +1 -0
  80. package/dist/tool-handlers/proceed-to-phase.d.ts +39 -0
  81. package/dist/tool-handlers/proceed-to-phase.d.ts.map +1 -0
  82. package/dist/tool-handlers/proceed-to-phase.js +109 -0
  83. package/dist/tool-handlers/proceed-to-phase.js.map +1 -0
  84. package/dist/tool-handlers/reset-development.d.ts +31 -0
  85. package/dist/tool-handlers/reset-development.d.ts.map +1 -0
  86. package/dist/tool-handlers/reset-development.js +48 -0
  87. package/dist/tool-handlers/reset-development.js.map +1 -0
  88. package/dist/tool-handlers/resume-workflow.d.ts +88 -0
  89. package/dist/tool-handlers/resume-workflow.d.ts.map +1 -0
  90. package/dist/tool-handlers/resume-workflow.js +213 -0
  91. package/dist/tool-handlers/resume-workflow.js.map +1 -0
  92. package/dist/tool-handlers/setup-project-docs.d.ts +36 -0
  93. package/dist/tool-handlers/setup-project-docs.d.ts.map +1 -0
  94. package/dist/tool-handlers/setup-project-docs.js +136 -0
  95. package/dist/tool-handlers/setup-project-docs.js.map +1 -0
  96. package/dist/tool-handlers/start-development.d.ts +82 -0
  97. package/dist/tool-handlers/start-development.d.ts.map +1 -0
  98. package/dist/tool-handlers/start-development.js +448 -0
  99. package/dist/tool-handlers/start-development.js.map +1 -0
  100. package/dist/tool-handlers/whats-next.d.ts +42 -0
  101. package/dist/tool-handlers/whats-next.d.ts.map +1 -0
  102. package/dist/tool-handlers/whats-next.js +118 -0
  103. package/dist/tool-handlers/whats-next.js.map +1 -0
  104. package/dist/types.d.ts +114 -0
  105. package/dist/types.d.ts.map +1 -0
  106. package/dist/types.js +5 -0
  107. package/dist/types.js.map +1 -0
  108. package/package.json +29 -0
  109. package/src/index.ts +93 -0
  110. package/src/notification-service.ts +23 -0
  111. package/src/resource-handlers/conversation-state.ts +55 -0
  112. package/src/resource-handlers/development-plan.ts +48 -0
  113. package/src/resource-handlers/index.ts +73 -0
  114. package/src/resource-handlers/system-prompt.ts +55 -0
  115. package/src/resource-handlers/workflow-resource.ts +126 -0
  116. package/src/response-renderer.ts +116 -0
  117. package/src/server-config.ts +744 -0
  118. package/src/server-helpers.ts +225 -0
  119. package/src/server-implementation.ts +277 -0
  120. package/src/server.ts +9 -0
  121. package/src/tool-handlers/base-tool-handler.ts +141 -0
  122. package/src/tool-handlers/conduct-review.ts +191 -0
  123. package/src/tool-handlers/get-tool-info.ts +274 -0
  124. package/src/tool-handlers/index.ts +117 -0
  125. package/src/tool-handlers/install-workflow.ts +185 -0
  126. package/src/tool-handlers/list-workflows.ts +94 -0
  127. package/src/tool-handlers/no-idea.ts +47 -0
  128. package/src/tool-handlers/proceed-to-phase.ts +205 -0
  129. package/src/tool-handlers/reset-development.ts +90 -0
  130. package/src/tool-handlers/resume-workflow.ts +380 -0
  131. package/src/tool-handlers/setup-project-docs.ts +226 -0
  132. package/src/tool-handlers/start-development.ts +685 -0
  133. package/src/tool-handlers/whats-next.ts +235 -0
  134. package/src/types.ts +130 -0
  135. package/test/e2e/core-functionality.test.ts +176 -0
  136. package/test/e2e/mcp-contract.test.ts +540 -0
  137. package/test/e2e/plan-management.test.ts +331 -0
  138. package/test/e2e/state-management.test.ts +392 -0
  139. package/test/e2e/workflow-integration.test.ts +506 -0
  140. package/test/unit/commit-behaviour-interface.test.ts +244 -0
  141. package/test/unit/conduct-review.test.ts +151 -0
  142. package/test/unit/reset-functionality.test.ts +72 -0
  143. package/test/unit/resume-workflow.test.ts +192 -0
  144. package/test/unit/server-tools.test.ts +311 -0
  145. package/test/unit/setup-project-docs-handler.test.ts +267 -0
  146. package/test/unit/start-development-artifact-detection.test.ts +387 -0
  147. package/test/unit/start-development-gitignore.test.ts +178 -0
  148. package/test/unit/system-prompt-resource.test.ts +101 -0
  149. package/test/unit/tool-handlers/no-idea.test.ts +40 -0
  150. package/test/utils/e2e-test-setup.ts +453 -0
  151. package/test/utils/run-server-in-dir.sh +27 -0
  152. package/test/utils/temp-files.ts +308 -0
  153. package/test/utils/test-access.ts +79 -0
  154. package/test/utils/test-helpers.ts +286 -0
  155. package/test/utils/test-setup.ts +78 -0
  156. package/tsconfig.build.json +9 -0
  157. package/tsconfig.build.tsbuildinfo +1 -0
  158. package/tsconfig.json +12 -0
  159. package/vitest.config.ts +17 -0
@@ -0,0 +1,331 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import {
3
+ TempProject,
4
+ createTempProjectWithDefaultStateMachine,
5
+ } from '../utils/temp-files';
6
+ import {
7
+ DirectServerInterface,
8
+ createSuiteIsolatedE2EScenario,
9
+ assertToolSuccess,
10
+ initializeDevelopment,
11
+ } from '../utils/e2e-test-setup';
12
+ import { promises as fs } from 'node:fs';
13
+ import path from 'node:path';
14
+
15
+ vi.unmock('fs');
16
+ vi.unmock('fs/promises');
17
+
18
+ /**
19
+ * Plan Management Tests
20
+ *
21
+ * Tests plan file functionality including:
22
+ * - Plan file creation and structure
23
+ * - Content management and updates
24
+ * - File path handling and organization
25
+ * - Integration with development phases
26
+ */
27
+ describe('Plan Management', () => {
28
+ let client: DirectServerInterface;
29
+ let tempProject: TempProject;
30
+ let cleanup: () => Promise<void>;
31
+
32
+ beforeEach(async () => {
33
+ const scenario = await createSuiteIsolatedE2EScenario({
34
+ suiteName: 'plan-management',
35
+ tempProjectFactory: createTempProjectWithDefaultStateMachine,
36
+ });
37
+ client = scenario.client;
38
+ tempProject = scenario.tempProject;
39
+ cleanup = scenario.cleanup;
40
+
41
+ // Initialize development with default workflow before each test
42
+ await initializeDevelopment(client);
43
+ });
44
+
45
+ afterEach(async () => {
46
+ if (cleanup) {
47
+ await cleanup();
48
+ }
49
+ });
50
+
51
+ describe('Plan File Creation', () => {
52
+ it('should create plan file on first conversation', async () => {
53
+ const result = await client.callTool('whats_next', {
54
+ user_input: 'implement new feature',
55
+ });
56
+ const response = assertToolSuccess(result);
57
+
58
+ expect(response.plan_file_path).toBeTruthy();
59
+ expect(response.plan_file_path).toMatch(/\.md$/);
60
+
61
+ // Verify file exists
62
+ const planExists = await fs
63
+ .access(response.plan_file_path)
64
+ .then(() => true)
65
+ .catch(() => false);
66
+ expect(planExists).toBe(true);
67
+ });
68
+
69
+ it('should use absolute paths for plan files', async () => {
70
+ const result = await client.callTool('whats_next', {
71
+ user_input: 'test absolute paths',
72
+ });
73
+ const response = assertToolSuccess(result);
74
+
75
+ expect(path.isAbsolute(response.plan_file_path)).toBe(true);
76
+ expect(response.plan_file_path).toContain(tempProject.projectPath);
77
+ });
78
+
79
+ it('should create plan files in .vibe directory', async () => {
80
+ const result = await client.callTool('whats_next', {
81
+ user_input: 'test vibe directory',
82
+ });
83
+ const response = assertToolSuccess(result);
84
+
85
+ expect(response.plan_file_path).toContain('.vibe');
86
+
87
+ // Verify .vibe directory exists
88
+ const vibeDir = path.dirname(response.plan_file_path);
89
+ const vibeDirExists = await fs
90
+ .access(vibeDir)
91
+ .then(() => true)
92
+ .catch(() => false);
93
+ expect(vibeDirExists).toBe(true);
94
+ });
95
+ });
96
+
97
+ describe('Plan File Structure', () => {
98
+ it('should create well-structured markdown plan', async () => {
99
+ await client.callTool('whats_next', {
100
+ user_input: 'create structured plan',
101
+ });
102
+
103
+ const planResource = await client.readResource('plan://current');
104
+ const planContent = planResource.contents[0].text;
105
+
106
+ expect(planContent).toContain('# Development Plan');
107
+ expect(planContent).toContain('## Goal');
108
+ expect(planContent).toContain('## Requirements');
109
+ expect(planContent).toContain('## Key Decisions');
110
+ });
111
+
112
+ it('should include phase-specific sections', async () => {
113
+ // Start in requirements phase
114
+ await client.callTool('whats_next', {
115
+ user_input: 'requirements phase test',
116
+ });
117
+
118
+ // Move to design phase
119
+ await client.callTool('proceed_to_phase', {
120
+ target_phase: 'design',
121
+ reason: 'test design section',
122
+ review_state: 'not-required',
123
+ });
124
+
125
+ const planResource = await client.readResource('plan://current');
126
+ const planContent = planResource.contents[0].text;
127
+
128
+ expect(planContent).toContain('## Design');
129
+ expect(planContent).toContain('## Requirements');
130
+ });
131
+
132
+ it('should maintain consistent markdown formatting', async () => {
133
+ await client.callTool('whats_next', {
134
+ user_input: 'test formatting',
135
+ });
136
+
137
+ const planResource = await client.readResource('plan://current');
138
+ const planContent = planResource.contents[0].text;
139
+
140
+ // Check for proper markdown structure
141
+ expect(planContent).toMatch(/^# /m); // H1 headers
142
+ expect(planContent).toMatch(/^## /m); // H2 headers
143
+ expect(planContent).toMatch(/^- \[ \]/m); // Task checkboxes
144
+ });
145
+ });
146
+
147
+ describe('Plan File Updates', () => {
148
+ it('should update plan file across phase transitions', async () => {
149
+ // Get initial plan content
150
+ const initialPlan = await client.readResource('plan://current');
151
+ const initialContent = initialPlan.contents[0].text;
152
+
153
+ // Transition to design
154
+ await client.callTool('proceed_to_phase', {
155
+ target_phase: 'design',
156
+ reason: 'move to design',
157
+ review_state: 'not-required',
158
+ });
159
+
160
+ // Get updated plan content
161
+ const updatedPlan = await client.readResource('plan://current');
162
+ const updatedContent = updatedPlan.contents[0].text;
163
+
164
+ // Plan should be updated with design phase information
165
+ expect(updatedContent).toContain('## Design');
166
+ expect(updatedContent.length).toBeGreaterThanOrEqual(
167
+ initialContent.length
168
+ );
169
+ });
170
+
171
+ it('should preserve existing plan content when updating', async () => {
172
+ const result = await client.callTool('whats_next', {
173
+ user_input: 'preserve content test',
174
+ });
175
+ const response = assertToolSuccess(result);
176
+
177
+ // Manually add content to plan file
178
+ const customContent = '\n\n## Custom Section\n- Custom task\n';
179
+ await fs.appendFile(response.plan_file_path, customContent);
180
+
181
+ // Make another call that would update the plan
182
+ await client.callTool('proceed_to_phase', {
183
+ target_phase: 'implementation',
184
+ reason: 'test preservation',
185
+ review_state: 'not-required',
186
+ });
187
+
188
+ const planResource = await client.readResource('plan://current');
189
+ const planContent = planResource.contents[0].text;
190
+
191
+ // Custom content should still be present
192
+ expect(planContent).toContain('## Custom Section');
193
+ expect(planContent).toContain('- Custom task');
194
+ });
195
+
196
+ it('should handle concurrent plan file access', async () => {
197
+ await client.callTool('whats_next', { user_input: 'concurrent test' });
198
+
199
+ // Make multiple rapid calls that would update the plan
200
+ const promises = [
201
+ client.callTool('proceed_to_phase', {
202
+ target_phase: 'design',
203
+ reason: 'test1',
204
+ review_state: 'not-required',
205
+ }),
206
+ client.callTool('proceed_to_phase', {
207
+ target_phase: 'implementation',
208
+ reason: 'test2',
209
+ review_state: 'not-required',
210
+ }),
211
+ client.callTool('whats_next', { user_input: 'update plan' }),
212
+ ];
213
+
214
+ const results = await Promise.all(promises);
215
+
216
+ // All operations should succeed
217
+ for (const result of results) {
218
+ expect(result).toBeTruthy();
219
+ }
220
+
221
+ // Plan file should still be accessible and valid
222
+ const planResource = await client.readResource('plan://current');
223
+ expect(planResource.contents[0].text).toContain('# Development Plan');
224
+ });
225
+ });
226
+
227
+ describe('Plan File Organization', () => {
228
+ it('should organize plan files by branch when applicable', async () => {
229
+ const result = await client.callTool('whats_next', {
230
+ user_input: 'branch organization test',
231
+ });
232
+ const response = assertToolSuccess(result);
233
+
234
+ // Plan file path should reflect current branch context
235
+ expect(response.plan_file_path).toContain('development-plan');
236
+ expect(response.plan_file_path).toMatch(/\.md$/);
237
+ });
238
+
239
+ it('should handle special characters in project paths', async () => {
240
+ // This test verifies the system handles various path scenarios
241
+ const result = await client.callTool('whats_next', {
242
+ user_input: 'special characters test',
243
+ });
244
+ const response = assertToolSuccess(result);
245
+
246
+ expect(path.isAbsolute(response.plan_file_path)).toBe(true);
247
+
248
+ // File should be creatable and accessible
249
+ const planExists = await fs
250
+ .access(response.plan_file_path)
251
+ .then(() => true)
252
+ .catch(() => false);
253
+ expect(planExists).toBe(true);
254
+ });
255
+
256
+ it('should maintain plan file consistency across sessions', async () => {
257
+ // First session
258
+ const first = await client.callTool('whats_next', {
259
+ user_input: 'session consistency test',
260
+ });
261
+ const firstResponse = assertToolSuccess(first);
262
+ const firstPlanPath = firstResponse.plan_file_path;
263
+
264
+ // Second call in same session
265
+ const second = await client.callTool('whats_next', {
266
+ user_input: 'continue session',
267
+ });
268
+ const secondResponse = assertToolSuccess(second);
269
+
270
+ // Should use same plan file
271
+ expect(secondResponse.plan_file_path).toBe(firstPlanPath);
272
+ });
273
+ });
274
+
275
+ describe('Plan Content Integration', () => {
276
+ it('should integrate plan content with phase instructions', async () => {
277
+ let result = await client.callTool('whats_next', {
278
+ user_input: 'integration test',
279
+ });
280
+ let response = assertToolSuccess(result);
281
+
282
+ // Instructions should reference plan file updates
283
+ expect(response.instructions).toContain('plan');
284
+ expect(response.plan_file_path).toBeTruthy();
285
+
286
+ const planResource = await client.readResource('plan://current');
287
+ const planContent = planResource.contents[0].text;
288
+
289
+ // Plan should contain relevant phase information of all but the initial phase
290
+ result = await client.callTool('proceed_to_phase', {
291
+ target_phase: 'requirements',
292
+ reason: 'Starting specification',
293
+ review_state: 'not-required',
294
+ });
295
+ response = assertToolSuccess(result);
296
+
297
+ expect(planContent).toContain(response.phase);
298
+ });
299
+
300
+ it('should provide contextual plan guidance', async () => {
301
+ await client.callTool('whats_next', {
302
+ user_input: 'contextual guidance test',
303
+ });
304
+
305
+ await client.callTool('proceed_to_phase', {
306
+ target_phase: 'qa',
307
+ reason: 'test qa guidance',
308
+ review_state: 'not-required',
309
+ });
310
+
311
+ const planResource = await client.readResource('plan://current');
312
+ const planContent = planResource.contents[0].text;
313
+
314
+ // Plan should contain QA-specific content
315
+ expect(planContent).toContain('## Qa');
316
+ });
317
+
318
+ it('should track task completion in plan file', async () => {
319
+ await client.callTool('whats_next', {
320
+ user_input: 'task tracking test',
321
+ });
322
+
323
+ const planResource = await client.readResource('plan://current');
324
+ const planContent = planResource.contents[0].text;
325
+
326
+ // Should contain task checkboxes
327
+ expect(planContent).toMatch(/- \[ \]/); // Uncompleted tasks
328
+ // May contain completed tasks depending on phase logic
329
+ });
330
+ });
331
+ });