@codemcp/workflows 4.7.0 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/components/beads/beads-instruction-generator.d.ts +48 -0
- package/dist/components/beads/beads-instruction-generator.d.ts.map +1 -0
- package/dist/components/beads/beads-instruction-generator.js +182 -0
- package/dist/components/beads/beads-instruction-generator.js.map +1 -0
- package/dist/components/beads/beads-plan-manager.d.ts +66 -0
- package/dist/components/beads/beads-plan-manager.d.ts.map +1 -0
- package/dist/components/beads/beads-plan-manager.js +288 -0
- package/dist/components/beads/beads-plan-manager.js.map +1 -0
- package/dist/components/beads/beads-task-backend-client.d.ts +43 -0
- package/dist/components/beads/beads-task-backend-client.d.ts.map +1 -0
- package/dist/components/beads/beads-task-backend-client.js +178 -0
- package/dist/components/beads/beads-task-backend-client.js.map +1 -0
- package/dist/components/server-components-factory.d.ts +39 -0
- package/dist/components/server-components-factory.d.ts.map +1 -0
- package/dist/components/server-components-factory.js +62 -0
- package/dist/components/server-components-factory.js.map +1 -0
- package/dist/server-config.d.ts.map +1 -1
- package/dist/server-config.js +8 -4
- package/dist/server-config.js.map +1 -1
- package/dist/server-implementation.d.ts +1 -1
- package/dist/tool-handlers/get-tool-info.d.ts.map +1 -1
- package/dist/tool-handlers/get-tool-info.js +2 -1
- package/dist/tool-handlers/get-tool-info.js.map +1 -1
- package/dist/tool-handlers/proceed-to-phase.d.ts +5 -0
- package/dist/tool-handlers/proceed-to-phase.d.ts.map +1 -1
- package/dist/tool-handlers/proceed-to-phase.js +95 -0
- package/dist/tool-handlers/proceed-to-phase.js.map +1 -1
- package/dist/tool-handlers/start-development.d.ts.map +1 -1
- package/dist/tool-handlers/start-development.js +7 -3
- package/dist/tool-handlers/start-development.js.map +1 -1
- package/dist/tool-handlers/whats-next.d.ts +0 -12
- package/dist/tool-handlers/whats-next.d.ts.map +1 -1
- package/dist/tool-handlers/whats-next.js +1 -88
- package/dist/tool-handlers/whats-next.js.map +1 -1
- package/dist/types.d.ts +7 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/version-info.d.ts +30 -0
- package/dist/version-info.d.ts.map +1 -0
- package/dist/version-info.js +178 -0
- package/dist/version-info.js.map +1 -0
- package/package.json +2 -2
- package/src/components/beads/beads-instruction-generator.ts +261 -0
- package/src/components/beads/beads-plan-manager.ts +358 -0
- package/src/components/beads/beads-task-backend-client.ts +232 -0
- package/src/components/server-components-factory.ts +86 -0
- package/src/server-config.ts +9 -4
- package/src/tool-handlers/get-tool-info.ts +2 -1
- package/src/tool-handlers/proceed-to-phase.ts +140 -0
- package/src/tool-handlers/start-development.ts +14 -3
- package/src/tool-handlers/whats-next.ts +4 -117
- package/src/types.ts +7 -4
- package/src/version-info.ts +213 -0
- package/test/e2e/component-substitution.test.ts +208 -0
- package/test/unit/beads-instruction-generator.test.ts +847 -0
- package/test/unit/beads-phase-task-id-integration.test.ts +557 -0
- package/test/unit/server-components-factory.test.ts +279 -0
- package/test/unit/setup-project-docs-handler.test.ts +3 -2
- package/test/utils/e2e-test-setup.ts +0 -1
- package/test/utils/temp-files.ts +12 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -0,0 +1,847 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BeadsInstructionGenerator Content Validation Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for validating that BeadsInstructionGenerator generates the correct
|
|
5
|
+
* beads-specific instruction content and does not contain markdown-specific content.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
9
|
+
import { BeadsInstructionGenerator } from '../../src/components/beads/beads-instruction-generator.js';
|
|
10
|
+
import type {
|
|
11
|
+
InstructionContext,
|
|
12
|
+
ConversationContext,
|
|
13
|
+
} from '@codemcp/workflows-core';
|
|
14
|
+
|
|
15
|
+
describe('BeadsInstructionGenerator Content Validation', () => {
|
|
16
|
+
let beadsInstructionGenerator: BeadsInstructionGenerator;
|
|
17
|
+
let mockInstructionContext: InstructionContext;
|
|
18
|
+
let mockConversationContext: ConversationContext;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
beadsInstructionGenerator = new BeadsInstructionGenerator();
|
|
22
|
+
|
|
23
|
+
// Set up mock contexts
|
|
24
|
+
mockConversationContext = {
|
|
25
|
+
conversationId: 'test-conversation',
|
|
26
|
+
projectPath: '/test/project',
|
|
27
|
+
planFilePath: '/test/project/.vibe/plan.md',
|
|
28
|
+
gitBranch: 'main',
|
|
29
|
+
currentPhase: 'design',
|
|
30
|
+
workflowName: 'epcc',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
mockInstructionContext = {
|
|
34
|
+
phase: 'design',
|
|
35
|
+
conversationContext: mockConversationContext,
|
|
36
|
+
transitionReason: 'test transition',
|
|
37
|
+
isModeled: false,
|
|
38
|
+
planFileExists: true,
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe('Beads-Specific Content Must Be Present', () => {
|
|
43
|
+
it('should generate complete beads task management header structure', async () => {
|
|
44
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
45
|
+
'Work on design tasks.',
|
|
46
|
+
mockInstructionContext
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Verify ALL beads-specific elements are present
|
|
50
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
51
|
+
expect(result.instructions).toContain('Use bd CLI tool exclusively');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should contain core beads CLI commands with proper formatting', async () => {
|
|
55
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
56
|
+
'Work on tasks.',
|
|
57
|
+
mockInstructionContext
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Verify specific beads CLI commands are present
|
|
61
|
+
expect(result.instructions).toContain(
|
|
62
|
+
'bd list --parent <phase-task-id> --status open'
|
|
63
|
+
);
|
|
64
|
+
expect(result.instructions).toContain(
|
|
65
|
+
"bd create 'Task title' --parent <phase-task-id> -p 2"
|
|
66
|
+
);
|
|
67
|
+
expect(result.instructions).toContain(
|
|
68
|
+
'bd update <task-id> --status in_progress'
|
|
69
|
+
);
|
|
70
|
+
expect(result.instructions).toContain('bd close <task-id>');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should contain beads-specific task management prohibition', async () => {
|
|
74
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
75
|
+
'Work on tasks.',
|
|
76
|
+
mockInstructionContext
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Verify beads-specific prohibition
|
|
80
|
+
expect(result.instructions).toContain(
|
|
81
|
+
'Do NOT enter tasks in the plan file, use beads CLI exclusively'
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should contain beads-specific reminders section', async () => {
|
|
86
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
87
|
+
'Work on tasks.',
|
|
88
|
+
mockInstructionContext
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Verify beads-specific reminders
|
|
92
|
+
expect(result.instructions).toContain(
|
|
93
|
+
'Use ONLY bd CLI tool for task management - do not use your own task management tools'
|
|
94
|
+
);
|
|
95
|
+
expect(result.instructions).toContain(
|
|
96
|
+
'Call whats_next() after the next user message to maintain the development workflow'
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should contain beads plan file guidance', async () => {
|
|
101
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
102
|
+
'Work on tasks.',
|
|
103
|
+
mockInstructionContext
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// Verify beads-specific plan file guidance
|
|
107
|
+
expect(result.planFileGuidance).toContain(
|
|
108
|
+
'Using beads CLI for task management - plan file serves as context only'
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should use proper beads terminology and structure', async () => {
|
|
113
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
114
|
+
'Work on tasks.',
|
|
115
|
+
mockInstructionContext
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Verify beads terminology
|
|
119
|
+
expect(result.instructions).toContain('ready tasks');
|
|
120
|
+
expect(result.instructions).toContain('phase-task-id');
|
|
121
|
+
expect(result.instructions).toContain('Current Phase:');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe('Anti-Contamination (Should NOT contain markdown-specific content)', () => {
|
|
126
|
+
it('should never contain markdown task management instructions', async () => {
|
|
127
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
128
|
+
'Work on tasks.',
|
|
129
|
+
mockInstructionContext
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// Should NOT contain markdown-specific content
|
|
133
|
+
expect(result.instructions).not.toContain(
|
|
134
|
+
'Mark completed tasks with [x]'
|
|
135
|
+
);
|
|
136
|
+
expect(result.instructions).not.toContain(
|
|
137
|
+
'Use ONLY the development plan for task management'
|
|
138
|
+
);
|
|
139
|
+
expect(result.instructions).not.toContain(
|
|
140
|
+
'Work on the tasks listed in the Design section'
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should never contain markdown plan file task instructions', async () => {
|
|
145
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
146
|
+
'Work on tasks.',
|
|
147
|
+
mockInstructionContext
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Should NOT contain markdown plan file task management
|
|
151
|
+
expect(result.instructions).not.toContain(
|
|
152
|
+
'Mark completed tasks with [x] as you finish them'
|
|
153
|
+
);
|
|
154
|
+
expect(result.instructions).not.toContain(
|
|
155
|
+
'focus on the "Design" section'
|
|
156
|
+
);
|
|
157
|
+
expect(result.instructions).not.toContain(
|
|
158
|
+
'focus on the "Design" section'
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should not include markdown-style task format examples', async () => {
|
|
163
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
164
|
+
'Work on tasks.',
|
|
165
|
+
mockInstructionContext
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
// Should NOT contain markdown task formatting
|
|
169
|
+
expect(result.instructions).not.toContain('- [ ]');
|
|
170
|
+
expect(result.instructions).not.toContain('- [x]');
|
|
171
|
+
expect(result.instructions).not.toContain('Check your plan file at');
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should provide exclusive beads guidance without markdown contamination', async () => {
|
|
175
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
176
|
+
'Complex task management scenario',
|
|
177
|
+
mockInstructionContext
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
// Comprehensive check against markdown contamination
|
|
181
|
+
const markdownTerms = [
|
|
182
|
+
'Mark completed tasks with [x]',
|
|
183
|
+
'Use ONLY the development plan for task management',
|
|
184
|
+
'Work on the tasks listed in',
|
|
185
|
+
'focus on the "Design" section',
|
|
186
|
+
'Mark completed tasks with [x] as you finish them',
|
|
187
|
+
'Check your plan file at',
|
|
188
|
+
'- [ ]',
|
|
189
|
+
'- [x]',
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
for (const term of markdownTerms) {
|
|
193
|
+
expect(
|
|
194
|
+
result.instructions,
|
|
195
|
+
`Should not contain markdown term: "${term}"`
|
|
196
|
+
).not.toContain(term);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe('Phase-Specific Content Validation', () => {
|
|
202
|
+
it('should generate phase-specific beads instructions for different phases', async () => {
|
|
203
|
+
const phases = ['explore', 'plan', 'code', 'commit'];
|
|
204
|
+
|
|
205
|
+
for (const phase of phases) {
|
|
206
|
+
const context = { ...mockInstructionContext, phase };
|
|
207
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
208
|
+
`${phase} instructions`,
|
|
209
|
+
context
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
// All phases should have consistent beads structure
|
|
213
|
+
expect(
|
|
214
|
+
result.instructions,
|
|
215
|
+
`Phase ${phase} should have BD CLI header`
|
|
216
|
+
).toContain('🔧 BD CLI Task Management:');
|
|
217
|
+
expect(
|
|
218
|
+
result.instructions,
|
|
219
|
+
`Phase ${phase} should have beads CLI commands`
|
|
220
|
+
).toContain('bd list --parent');
|
|
221
|
+
expect(
|
|
222
|
+
result.instructions,
|
|
223
|
+
`Phase ${phase} should not have markdown content`
|
|
224
|
+
).not.toContain('Mark completed tasks with [x]');
|
|
225
|
+
|
|
226
|
+
// Should reference the correct phase
|
|
227
|
+
expect(result.instructions).toContain(`Current Phase: ${phase}`);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should customize beads guidance based on phase context', async () => {
|
|
232
|
+
// Test design phase
|
|
233
|
+
const designResult = await beadsInstructionGenerator.generateInstructions(
|
|
234
|
+
'Design phase instructions',
|
|
235
|
+
{ ...mockInstructionContext, phase: 'design' }
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
expect(designResult.instructions).toContain(
|
|
239
|
+
'You are in the design phase'
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
// Test implementation phase
|
|
243
|
+
const implResult = await beadsInstructionGenerator.generateInstructions(
|
|
244
|
+
'Implementation phase instructions',
|
|
245
|
+
{ ...mockInstructionContext, phase: 'implementation' }
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
expect(implResult.instructions).toContain(
|
|
249
|
+
'You are in the implementation phase'
|
|
250
|
+
);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
describe('Variable Substitution in Beads Context', () => {
|
|
255
|
+
it('should properly substitute variables while maintaining beads structure', async () => {
|
|
256
|
+
const instructionsWithVariables =
|
|
257
|
+
'Review the design in $DESIGN_DOC and implement according to $ARCHITECTURE_DOC.';
|
|
258
|
+
|
|
259
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
260
|
+
instructionsWithVariables,
|
|
261
|
+
mockInstructionContext
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
// Should contain substituted paths
|
|
265
|
+
expect(result.instructions).toContain(
|
|
266
|
+
'/test/project/.vibe/docs/design.md'
|
|
267
|
+
);
|
|
268
|
+
expect(result.instructions).toContain(
|
|
269
|
+
'/test/project/.vibe/docs/architecture.md'
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
// Should still be in beads format
|
|
273
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
274
|
+
expect(result.instructions).not.toContain(
|
|
275
|
+
'Mark completed tasks with [x]'
|
|
276
|
+
);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('should handle multiple variable occurrences in beads context', async () => {
|
|
280
|
+
const baseInstructions =
|
|
281
|
+
'Check $DESIGN_DOC for details. Update $DESIGN_DOC with new information.';
|
|
282
|
+
|
|
283
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
284
|
+
baseInstructions,
|
|
285
|
+
mockInstructionContext
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
const designDocPath = '/test/project/.vibe/docs/design.md';
|
|
289
|
+
const occurrences = (
|
|
290
|
+
result.instructions.match(
|
|
291
|
+
new RegExp(designDocPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')
|
|
292
|
+
) || []
|
|
293
|
+
).length;
|
|
294
|
+
expect(occurrences).toBe(2);
|
|
295
|
+
expect(result.instructions).not.toContain('$DESIGN_DOC');
|
|
296
|
+
|
|
297
|
+
// Still beads format
|
|
298
|
+
expect(result.instructions).toContain('bd CLI tool exclusively');
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
describe('Plan File Handling in Beads Mode', () => {
|
|
303
|
+
it('should handle non-existent plan file in beads mode', async () => {
|
|
304
|
+
const contextNoPlan = {
|
|
305
|
+
...mockInstructionContext,
|
|
306
|
+
planFileExists: false,
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
310
|
+
'Test instructions',
|
|
311
|
+
contextNoPlan
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
// Should still use beads structure
|
|
315
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
316
|
+
expect(result.instructions).toContain(
|
|
317
|
+
'Plan file will be created when you first update it'
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
// Should not revert to markdown mode
|
|
321
|
+
expect(result.instructions).not.toContain('Check your plan file at');
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should maintain beads structure regardless of plan file state', async () => {
|
|
325
|
+
const contextWithPlan = {
|
|
326
|
+
...mockInstructionContext,
|
|
327
|
+
planFileExists: true,
|
|
328
|
+
};
|
|
329
|
+
const contextWithoutPlan = {
|
|
330
|
+
...mockInstructionContext,
|
|
331
|
+
planFileExists: false,
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
const resultWithPlan =
|
|
335
|
+
await beadsInstructionGenerator.generateInstructions(
|
|
336
|
+
'Test instructions with plan',
|
|
337
|
+
contextWithPlan
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
const resultWithoutPlan =
|
|
341
|
+
await beadsInstructionGenerator.generateInstructions(
|
|
342
|
+
'Test instructions without plan',
|
|
343
|
+
contextWithoutPlan
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
// Both should have beads structure
|
|
347
|
+
expect(resultWithPlan.instructions).toContain(
|
|
348
|
+
'🔧 BD CLI Task Management:'
|
|
349
|
+
);
|
|
350
|
+
expect(resultWithoutPlan.instructions).toContain(
|
|
351
|
+
'🔧 BD CLI Task Management:'
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
// Neither should have markdown structure
|
|
355
|
+
expect(resultWithPlan.instructions).not.toContain(
|
|
356
|
+
'Check your plan file at'
|
|
357
|
+
);
|
|
358
|
+
expect(resultWithoutPlan.instructions).not.toContain(
|
|
359
|
+
'Check your plan file at'
|
|
360
|
+
);
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
describe('Beads Mode Consistency', () => {
|
|
365
|
+
it('should provide consistent beads instructions across multiple generations', async () => {
|
|
366
|
+
// Multiple instruction generations should be consistent
|
|
367
|
+
const results = await Promise.all([
|
|
368
|
+
beadsInstructionGenerator.generateInstructions(
|
|
369
|
+
'Test 1',
|
|
370
|
+
mockInstructionContext
|
|
371
|
+
),
|
|
372
|
+
beadsInstructionGenerator.generateInstructions(
|
|
373
|
+
'Test 2',
|
|
374
|
+
mockInstructionContext
|
|
375
|
+
),
|
|
376
|
+
beadsInstructionGenerator.generateInstructions(
|
|
377
|
+
'Test 3',
|
|
378
|
+
mockInstructionContext
|
|
379
|
+
),
|
|
380
|
+
]);
|
|
381
|
+
|
|
382
|
+
for (let index = 0; index < results.length; index++) {
|
|
383
|
+
const result = results[index];
|
|
384
|
+
expect(
|
|
385
|
+
result.instructions,
|
|
386
|
+
`Result ${index + 1} should be beads mode`
|
|
387
|
+
).toContain('🔧 BD CLI Task Management:');
|
|
388
|
+
expect(
|
|
389
|
+
result.instructions,
|
|
390
|
+
`Result ${index + 1} should not have markdown content`
|
|
391
|
+
).not.toContain('Mark completed tasks with [x]');
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it('should never accidentally switch to markdown mode in beads backend', async () => {
|
|
396
|
+
// Simulate sequential instruction generation
|
|
397
|
+
for (let i = 0; i < 5; i++) {
|
|
398
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
399
|
+
`Sequential test ${i}`,
|
|
400
|
+
mockInstructionContext
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
expect(
|
|
404
|
+
result.instructions,
|
|
405
|
+
`Sequential result ${i + 1} should be beads mode`
|
|
406
|
+
).toContain('🔧 BD CLI Task Management:');
|
|
407
|
+
expect(
|
|
408
|
+
result.instructions,
|
|
409
|
+
`Sequential result ${i + 1} should not have markdown content`
|
|
410
|
+
).not.toContain('Check your plan file at');
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it('should maintain beads backend protection even with markdown-like instruction content', async () => {
|
|
415
|
+
// Test with instructions that contain markdown-like content
|
|
416
|
+
const trickInstructions =
|
|
417
|
+
'Create a plan file with [x] checkboxes and markdown task management.';
|
|
418
|
+
|
|
419
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
420
|
+
trickInstructions,
|
|
421
|
+
mockInstructionContext
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
// Should still be beads mode despite markdown-like content in instructions
|
|
425
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
426
|
+
expect(result.instructions).toContain('Use bd CLI tool exclusively');
|
|
427
|
+
expect(result.instructions).not.toContain(
|
|
428
|
+
'Mark completed tasks with [x]'
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
// Original instructions should be preserved
|
|
432
|
+
expect(result.instructions).toContain(trickInstructions);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it('should handle long complex instructions without corruption', async () => {
|
|
436
|
+
const longInstructions = `
|
|
437
|
+
This is a very long set of instructions that includes multiple paragraphs,
|
|
438
|
+
complex formatting, and various edge cases that might trigger unexpected
|
|
439
|
+
behavior in the instruction generation system. We need to ensure that
|
|
440
|
+
even with complex inputs, the beads backend protection remains active.
|
|
441
|
+
|
|
442
|
+
## Complex Requirements
|
|
443
|
+
- Implement markdown-style task lists
|
|
444
|
+
- Create plan file management systems
|
|
445
|
+
- Build [x] checkbox interfaces
|
|
446
|
+
- Design traditional task tracking
|
|
447
|
+
|
|
448
|
+
The system should remain in beads mode regardless of these requirements.
|
|
449
|
+
`.trim();
|
|
450
|
+
|
|
451
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
452
|
+
longInstructions,
|
|
453
|
+
mockInstructionContext
|
|
454
|
+
);
|
|
455
|
+
|
|
456
|
+
// Core beads structure should be preserved
|
|
457
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
458
|
+
expect(result.instructions).toContain('Use bd CLI tool exclusively');
|
|
459
|
+
expect(result.instructions).toContain('bd list --parent');
|
|
460
|
+
|
|
461
|
+
// Should not contain markdown mode elements
|
|
462
|
+
expect(result.instructions).not.toContain(
|
|
463
|
+
'Mark completed tasks with [x]'
|
|
464
|
+
);
|
|
465
|
+
expect(result.instructions).not.toContain('Check your plan file at');
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
describe('Metadata Validation', () => {
|
|
470
|
+
it('should return correct metadata in beads mode', async () => {
|
|
471
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
472
|
+
'Test instructions',
|
|
473
|
+
mockInstructionContext
|
|
474
|
+
);
|
|
475
|
+
|
|
476
|
+
expect(result.metadata).toEqual({
|
|
477
|
+
phase: 'design',
|
|
478
|
+
planFilePath: '/test/project/.vibe/plan.md',
|
|
479
|
+
transitionReason: 'test transition',
|
|
480
|
+
isModeled: false,
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// Plan file guidance should be beads-specific
|
|
484
|
+
expect(result.planFileGuidance).toContain(
|
|
485
|
+
'beads CLI for task management'
|
|
486
|
+
);
|
|
487
|
+
expect(result.planFileGuidance).not.toContain('markdown');
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it('should handle modeled vs non-modeled transitions in beads mode', async () => {
|
|
491
|
+
// Test modeled transition
|
|
492
|
+
const modeledContext: InstructionContext = {
|
|
493
|
+
...mockInstructionContext,
|
|
494
|
+
isModeled: true,
|
|
495
|
+
transitionReason: 'Model-driven transition',
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
const modeledResult =
|
|
499
|
+
await beadsInstructionGenerator.generateInstructions(
|
|
500
|
+
'Modeled instructions',
|
|
501
|
+
modeledContext
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
expect(modeledResult.metadata.isModeled).toBe(true);
|
|
505
|
+
expect(modeledResult.instructions).toContain('Model-driven transition');
|
|
506
|
+
expect(modeledResult.instructions).toContain(
|
|
507
|
+
'🔧 BD CLI Task Management:'
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
// Test non-modeled transition
|
|
511
|
+
const nonModeledContext: InstructionContext = {
|
|
512
|
+
...mockInstructionContext,
|
|
513
|
+
isModeled: false,
|
|
514
|
+
transitionReason: 'Manual transition',
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
const nonModeledResult =
|
|
518
|
+
await beadsInstructionGenerator.generateInstructions(
|
|
519
|
+
'Manual instructions',
|
|
520
|
+
nonModeledContext
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
expect(nonModeledResult.metadata.isModeled).toBe(false);
|
|
524
|
+
expect(nonModeledResult.instructions).toContain(
|
|
525
|
+
'🔧 BD CLI Task Management:'
|
|
526
|
+
);
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
describe('Sequential Generation Consistency', () => {
|
|
531
|
+
it('should never accidentally switch to markdown mode in beads backend during sequential generation', async () => {
|
|
532
|
+
// Multiple instruction generations should be consistent - matching markdown test pattern
|
|
533
|
+
const results = await Promise.all([
|
|
534
|
+
beadsInstructionGenerator.generateInstructions(
|
|
535
|
+
'Test 1',
|
|
536
|
+
mockInstructionContext
|
|
537
|
+
),
|
|
538
|
+
beadsInstructionGenerator.generateInstructions(
|
|
539
|
+
'Test 2',
|
|
540
|
+
mockInstructionContext
|
|
541
|
+
),
|
|
542
|
+
beadsInstructionGenerator.generateInstructions(
|
|
543
|
+
'Test 3',
|
|
544
|
+
mockInstructionContext
|
|
545
|
+
),
|
|
546
|
+
]);
|
|
547
|
+
|
|
548
|
+
for (let index = 0; index < results.length; index++) {
|
|
549
|
+
const result = results[index];
|
|
550
|
+
expect(
|
|
551
|
+
result.instructions,
|
|
552
|
+
`Result ${index + 1} should be beads mode`
|
|
553
|
+
).toContain('🔧 BD CLI Task Management:');
|
|
554
|
+
expect(
|
|
555
|
+
result.instructions,
|
|
556
|
+
`Result ${index + 1} should not have markdown content`
|
|
557
|
+
).not.toContain('Mark completed tasks with [x]');
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
it('should handle stressful instruction generation patterns without mode switching', async () => {
|
|
562
|
+
// Simulate sequential instruction generation that might trigger race conditions
|
|
563
|
+
for (let i = 0; i < 5; i++) {
|
|
564
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
565
|
+
`Sequential test ${i}`,
|
|
566
|
+
mockInstructionContext
|
|
567
|
+
);
|
|
568
|
+
|
|
569
|
+
expect(
|
|
570
|
+
result.instructions,
|
|
571
|
+
`Sequential result ${i + 1} should be beads mode`
|
|
572
|
+
).toContain('🔧 BD CLI Task Management:');
|
|
573
|
+
expect(
|
|
574
|
+
result.instructions,
|
|
575
|
+
`Sequential result ${i + 1} should not have markdown content`
|
|
576
|
+
).not.toContain('Mark completed tasks with [x]');
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
describe('Stress Testing and Race Conditions', () => {
|
|
582
|
+
it('should handle rapid concurrent instruction generation without corruption', async () => {
|
|
583
|
+
// Stress test for race conditions - matching markdown test coverage
|
|
584
|
+
const concurrentPromises = Array.from({ length: 10 }, (_, i) =>
|
|
585
|
+
beadsInstructionGenerator.generateInstructions(
|
|
586
|
+
`Concurrent test ${i}`,
|
|
587
|
+
mockInstructionContext
|
|
588
|
+
)
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
const results = await Promise.all(concurrentPromises);
|
|
592
|
+
|
|
593
|
+
for (let index = 0; index < results.length; index++) {
|
|
594
|
+
const result = results[index];
|
|
595
|
+
expect(
|
|
596
|
+
result.instructions,
|
|
597
|
+
`Concurrent result ${index + 1} should be beads mode`
|
|
598
|
+
).toContain('🔧 BD CLI Task Management:');
|
|
599
|
+
expect(
|
|
600
|
+
result.instructions,
|
|
601
|
+
`Concurrent result ${index + 1} should have beads CLI commands`
|
|
602
|
+
).toContain('Use bd CLI tool exclusively');
|
|
603
|
+
expect(
|
|
604
|
+
result.instructions,
|
|
605
|
+
`Concurrent result ${index + 1} should not have markdown contamination`
|
|
606
|
+
).not.toContain('Check your plan file at');
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
it('should maintain beads structure under memory pressure conditions', async () => {
|
|
611
|
+
// Create large instruction content to test memory handling
|
|
612
|
+
const largeInstructions = Array.from(
|
|
613
|
+
{ length: 1000 },
|
|
614
|
+
(_, i) =>
|
|
615
|
+
`Instruction line ${i} with complex requirements and detailed specifications.`
|
|
616
|
+
).join('\n');
|
|
617
|
+
|
|
618
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
619
|
+
largeInstructions,
|
|
620
|
+
mockInstructionContext
|
|
621
|
+
);
|
|
622
|
+
|
|
623
|
+
// Core beads structure should be preserved even with large content
|
|
624
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
625
|
+
expect(result.instructions).toContain('Use bd CLI tool exclusively');
|
|
626
|
+
expect(result.instructions).toContain('bd list --parent');
|
|
627
|
+
|
|
628
|
+
// Should not contain markdown mode elements
|
|
629
|
+
expect(result.instructions).not.toContain(
|
|
630
|
+
'Mark completed tasks with [x]'
|
|
631
|
+
);
|
|
632
|
+
expect(result.instructions).not.toContain('Check your plan file at');
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
describe('Complex Instruction Handling', () => {
|
|
637
|
+
it('should handle deeply nested instruction structures without corruption', async () => {
|
|
638
|
+
const complexInstructions = `
|
|
639
|
+
## Primary Objective
|
|
640
|
+
Complete the following complex multi-layered tasks:
|
|
641
|
+
|
|
642
|
+
### Layer 1: Analysis
|
|
643
|
+
- Analyze existing markdown-based systems
|
|
644
|
+
- Review plan file management approaches
|
|
645
|
+
- Document [x] checkbox patterns
|
|
646
|
+
|
|
647
|
+
### Layer 2: Implementation
|
|
648
|
+
- Implement beads CLI integration
|
|
649
|
+
- Create hierarchical task structures
|
|
650
|
+
- Build robust error handling
|
|
651
|
+
|
|
652
|
+
### Layer 3: Validation
|
|
653
|
+
- Test cross-backend compatibility
|
|
654
|
+
- Verify anti-contamination measures
|
|
655
|
+
- Validate task management isolation
|
|
656
|
+
|
|
657
|
+
All work must maintain strict backend separation.
|
|
658
|
+
`.trim();
|
|
659
|
+
|
|
660
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
661
|
+
complexInstructions,
|
|
662
|
+
mockInstructionContext
|
|
663
|
+
);
|
|
664
|
+
|
|
665
|
+
// Core beads structure should be preserved
|
|
666
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
667
|
+
expect(result.instructions).toContain('Use bd CLI tool exclusively');
|
|
668
|
+
expect(result.instructions).toContain('bd list --parent');
|
|
669
|
+
|
|
670
|
+
// Should not contain markdown mode elements despite markdown-like content
|
|
671
|
+
expect(result.instructions).not.toContain(
|
|
672
|
+
'Mark completed tasks with [x]'
|
|
673
|
+
);
|
|
674
|
+
expect(result.instructions).not.toContain('Check your plan file at');
|
|
675
|
+
expect(result.instructions).not.toContain(
|
|
676
|
+
'Use ONLY the development plan for task management'
|
|
677
|
+
);
|
|
678
|
+
|
|
679
|
+
// Original complex instructions should be preserved
|
|
680
|
+
expect(result.instructions).toContain('Primary Objective');
|
|
681
|
+
expect(result.instructions).toContain('Layer 1: Analysis');
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
it('should handle instructions with embedded beads and markdown terminology', async () => {
|
|
685
|
+
const trickInstructions = `
|
|
686
|
+
Create a new system that:
|
|
687
|
+
- Uses markdown files for documentation
|
|
688
|
+
- Implements [x] checkbox tracking
|
|
689
|
+
- Has bd CLI-like commands but for different purposes
|
|
690
|
+
- Manages plan files with markdown syntax
|
|
691
|
+
- Creates beads-style hierarchical structures
|
|
692
|
+
|
|
693
|
+
This should test anti-contamination thoroughly.
|
|
694
|
+
`.trim();
|
|
695
|
+
|
|
696
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
697
|
+
trickInstructions,
|
|
698
|
+
mockInstructionContext
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
// Should maintain beads mode despite confusing terminology
|
|
702
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
703
|
+
expect(result.instructions).toContain('Use bd CLI tool exclusively');
|
|
704
|
+
expect(result.instructions).not.toContain(
|
|
705
|
+
'Mark completed tasks with [x]'
|
|
706
|
+
);
|
|
707
|
+
|
|
708
|
+
// Original instructions should be preserved
|
|
709
|
+
expect(result.instructions).toContain('Create a new system that:');
|
|
710
|
+
});
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
describe('Enhanced Plan File Integration', () => {
|
|
714
|
+
it('should handle plan file creation guidance consistently', async () => {
|
|
715
|
+
const contextNoPlan = {
|
|
716
|
+
...mockInstructionContext,
|
|
717
|
+
planFileExists: false,
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
721
|
+
'Start working with non-existent plan file',
|
|
722
|
+
contextNoPlan
|
|
723
|
+
);
|
|
724
|
+
|
|
725
|
+
// Should provide creation guidance while maintaining beads structure
|
|
726
|
+
expect(result.instructions).toContain(
|
|
727
|
+
'Plan file will be created when you first update it'
|
|
728
|
+
);
|
|
729
|
+
expect(result.instructions).toContain('🔧 BD CLI Task Management:');
|
|
730
|
+
expect(result.instructions).toContain('Use bd CLI tool exclusively');
|
|
731
|
+
|
|
732
|
+
// Should not revert to markdown mode for missing files
|
|
733
|
+
expect(result.instructions).not.toContain('Check your plan file at');
|
|
734
|
+
expect(result.instructions).not.toContain(
|
|
735
|
+
'Mark completed tasks with [x]'
|
|
736
|
+
);
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
it('should maintain beads guidance regardless of plan file state changes', async () => {
|
|
740
|
+
// Test with plan file existing
|
|
741
|
+
const resultWithPlan =
|
|
742
|
+
await beadsInstructionGenerator.generateInstructions(
|
|
743
|
+
'Work with existing plan',
|
|
744
|
+
{ ...mockInstructionContext, planFileExists: true }
|
|
745
|
+
);
|
|
746
|
+
|
|
747
|
+
// Test with plan file missing
|
|
748
|
+
const resultWithoutPlan =
|
|
749
|
+
await beadsInstructionGenerator.generateInstructions(
|
|
750
|
+
'Work without plan',
|
|
751
|
+
{ ...mockInstructionContext, planFileExists: false }
|
|
752
|
+
);
|
|
753
|
+
|
|
754
|
+
// Both should maintain beads structure
|
|
755
|
+
expect(resultWithPlan.instructions).toContain(
|
|
756
|
+
'🔧 BD CLI Task Management:'
|
|
757
|
+
);
|
|
758
|
+
expect(resultWithoutPlan.instructions).toContain(
|
|
759
|
+
'🔧 BD CLI Task Management:'
|
|
760
|
+
);
|
|
761
|
+
|
|
762
|
+
expect(resultWithPlan.instructions).toContain(
|
|
763
|
+
'Use bd CLI tool exclusively'
|
|
764
|
+
);
|
|
765
|
+
expect(resultWithoutPlan.instructions).toContain(
|
|
766
|
+
'Use bd CLI tool exclusively'
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
// Neither should have markdown contamination
|
|
770
|
+
expect(resultWithPlan.instructions).not.toContain(
|
|
771
|
+
'Check your plan file at'
|
|
772
|
+
);
|
|
773
|
+
expect(resultWithoutPlan.instructions).not.toContain(
|
|
774
|
+
'Check your plan file at'
|
|
775
|
+
);
|
|
776
|
+
});
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
describe('Backend Availability and Robustness', () => {
|
|
780
|
+
it('should maintain consistent beads structure regardless of external conditions', async () => {
|
|
781
|
+
// Test multiple scenarios that might affect backend behavior
|
|
782
|
+
const scenarios = [
|
|
783
|
+
{ name: 'basic', context: mockInstructionContext },
|
|
784
|
+
{
|
|
785
|
+
name: 'no-plan',
|
|
786
|
+
context: { ...mockInstructionContext, planFileExists: false },
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
name: 'modeled',
|
|
790
|
+
context: { ...mockInstructionContext, isModeled: true },
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
name: 'different-phase',
|
|
794
|
+
context: { ...mockInstructionContext, phase: 'implementation' },
|
|
795
|
+
},
|
|
796
|
+
];
|
|
797
|
+
|
|
798
|
+
for (const scenario of scenarios) {
|
|
799
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
800
|
+
`Test scenario: ${scenario.name}`,
|
|
801
|
+
scenario.context
|
|
802
|
+
);
|
|
803
|
+
|
|
804
|
+
expect(
|
|
805
|
+
result.instructions,
|
|
806
|
+
`Scenario ${scenario.name} should have beads structure`
|
|
807
|
+
).toContain('🔧 BD CLI Task Management:');
|
|
808
|
+
expect(
|
|
809
|
+
result.instructions,
|
|
810
|
+
`Scenario ${scenario.name} should have beads CLI commands`
|
|
811
|
+
).toContain('Use bd CLI tool exclusively');
|
|
812
|
+
expect(
|
|
813
|
+
result.instructions,
|
|
814
|
+
`Scenario ${scenario.name} should not have markdown contamination`
|
|
815
|
+
).not.toContain('Mark completed tasks with [x]');
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
it('should handle edge case instruction patterns without degradation', async () => {
|
|
820
|
+
const edgeCases = [
|
|
821
|
+
'', // Empty instructions
|
|
822
|
+
'.', // Minimal instructions
|
|
823
|
+
Array.from({ length: 50 }, () => 'Repeat instruction content').join(
|
|
824
|
+
' '
|
|
825
|
+
), // Repetitive content
|
|
826
|
+
'🔧 BD CLI Task Management: fake header', // Instructions containing beads-like headers
|
|
827
|
+
'Check your plan file and mark tasks [x]', // Instructions with markdown terminology
|
|
828
|
+
];
|
|
829
|
+
|
|
830
|
+
for (const edgeCase of edgeCases) {
|
|
831
|
+
const result = await beadsInstructionGenerator.generateInstructions(
|
|
832
|
+
edgeCase,
|
|
833
|
+
mockInstructionContext
|
|
834
|
+
);
|
|
835
|
+
|
|
836
|
+
expect(
|
|
837
|
+
result.instructions,
|
|
838
|
+
`Edge case "${edgeCase.substring(0, 20)}..." should maintain beads structure`
|
|
839
|
+
).toContain('🔧 BD CLI Task Management:');
|
|
840
|
+
expect(
|
|
841
|
+
result.instructions,
|
|
842
|
+
`Edge case "${edgeCase.substring(0, 20)}..." should not have markdown contamination`
|
|
843
|
+
).not.toContain('Check your plan file at');
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
});
|
|
847
|
+
});
|