@iservu-inc/adf-cli 0.1.6 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.project/chats/complete/2025-10-03_ADF-CLI-QUALITY-BASED-PROGRESS-AND-RESUME.md +399 -0
- package/.project/chats/current/2025-10-03_AGENTS-MD-AND-TOOL-GENERATORS.md +699 -0
- package/.project/docs/architecture/SYSTEM-DESIGN.md +369 -0
- package/.project/docs/frameworks/FRAMEWORK-METHODOLOGIES.md +449 -0
- package/.project/docs/goals/PROJECT-VISION.md +112 -0
- package/.project/docs/tool-integrations/IDE-CUSTOMIZATIONS.md +578 -0
- package/.project/docs/tool-integrations/RESEARCH-FINDINGS.md +828 -0
- package/CHANGELOG.md +292 -0
- package/jest.config.js +20 -0
- package/lib/commands/deploy.js +122 -3
- package/lib/commands/init.js +41 -113
- package/lib/frameworks/answer-quality-analyzer.js +216 -0
- package/lib/frameworks/interviewer.js +447 -0
- package/lib/frameworks/output-generators.js +345 -0
- package/lib/frameworks/progress-tracker.js +239 -0
- package/lib/frameworks/questions.js +664 -0
- package/lib/frameworks/session-manager.js +100 -0
- package/lib/generators/agents-md-generator.js +388 -0
- package/lib/generators/cursor-generator.js +374 -0
- package/lib/generators/index.js +98 -0
- package/lib/generators/tool-config-generator.js +188 -0
- package/lib/generators/vscode-generator.js +403 -0
- package/lib/generators/windsurf-generator.js +596 -0
- package/package.json +10 -5
- package/tests/agents-md-generator.test.js +245 -0
- package/tests/answer-quality-analyzer.test.js +173 -0
- package/tests/cursor-generator.test.js +326 -0
- package/tests/progress-tracker.test.js +205 -0
- package/tests/session-manager.test.js +162 -0
- package/tests/vscode-generator.test.js +436 -0
- package/tests/windsurf-generator.test.js +320 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const WindsurfGenerator = require('../lib/generators/windsurf-generator');
|
|
4
|
+
|
|
5
|
+
const TEST_PROJECT_PATH = path.join(__dirname, 'test-project-windsurf');
|
|
6
|
+
const TEST_SESSION_PATH = path.join(TEST_PROJECT_PATH, '.adf', 'sessions', 'test-session');
|
|
7
|
+
|
|
8
|
+
describe('WindsurfGenerator', () => {
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
// Clean up test directories
|
|
11
|
+
await fs.remove(TEST_PROJECT_PATH);
|
|
12
|
+
await fs.ensureDir(TEST_PROJECT_PATH);
|
|
13
|
+
await fs.ensureDir(TEST_SESSION_PATH);
|
|
14
|
+
await fs.ensureDir(path.join(TEST_SESSION_PATH, 'outputs'));
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(async () => {
|
|
18
|
+
// Clean up after tests
|
|
19
|
+
await fs.remove(TEST_PROJECT_PATH);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('PRP Framework', () => {
|
|
23
|
+
it('should generate Windsurf configurations from PRP output', async () => {
|
|
24
|
+
// Create mock PRP output
|
|
25
|
+
const prpContent = `# Product Requirement Prompt (PRP)
|
|
26
|
+
|
|
27
|
+
## 1. Goal Definition
|
|
28
|
+
Build a React dashboard that displays real-time analytics from PostgreSQL database.
|
|
29
|
+
|
|
30
|
+
## 2. Business Justification
|
|
31
|
+
This will help users make data-driven decisions and improve productivity.
|
|
32
|
+
|
|
33
|
+
## 3. Contextual Intelligence
|
|
34
|
+
### Technology Stack
|
|
35
|
+
- Frontend: React 18, TypeScript
|
|
36
|
+
- Backend: Node.js, Express
|
|
37
|
+
- Database: PostgreSQL
|
|
38
|
+
|
|
39
|
+
## 4. Implementation Blueprint
|
|
40
|
+
### File Structure
|
|
41
|
+
- src/components/Dashboard/
|
|
42
|
+
- src/api/analytics/
|
|
43
|
+
|
|
44
|
+
### Core Logic
|
|
45
|
+
1. Fetch data from analytics API
|
|
46
|
+
2. Process and aggregate
|
|
47
|
+
3. Render charts
|
|
48
|
+
|
|
49
|
+
## 5. Validation
|
|
50
|
+
### Success Criteria
|
|
51
|
+
- Dashboard loads in <2s
|
|
52
|
+
- All charts render correctly
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
await fs.writeFile(
|
|
56
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prp.md'),
|
|
57
|
+
prpContent,
|
|
58
|
+
'utf-8'
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// Create metadata
|
|
62
|
+
await fs.writeJson(path.join(TEST_SESSION_PATH, '_metadata.json'), {
|
|
63
|
+
framework: 'rapid',
|
|
64
|
+
projectName: 'Test Analytics Dashboard'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Generate Windsurf configs
|
|
68
|
+
const generator = new WindsurfGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'rapid');
|
|
69
|
+
const generated = await generator.generate();
|
|
70
|
+
|
|
71
|
+
// Verify .windsurfrules was created
|
|
72
|
+
const legacyPath = path.join(TEST_PROJECT_PATH, '.windsurfrules');
|
|
73
|
+
expect(await fs.pathExists(legacyPath)).toBe(true);
|
|
74
|
+
|
|
75
|
+
const legacyContent = await fs.readFile(legacyPath, 'utf-8');
|
|
76
|
+
expect(legacyContent).toContain('Test Analytics Dashboard');
|
|
77
|
+
expect(legacyContent).toContain('Project Goal');
|
|
78
|
+
expect(legacyContent).toContain('React dashboard');
|
|
79
|
+
expect(legacyContent).toContain('Tech Stack');
|
|
80
|
+
expect(legacyContent).toContain('AI Behavior');
|
|
81
|
+
expect(legacyContent).toContain('.adf/sessions/test-session/outputs/prp.md');
|
|
82
|
+
|
|
83
|
+
// Verify modern rules files (PRP only generates 2: project-context and architecture)
|
|
84
|
+
expect(generated.rules).toHaveLength(2);
|
|
85
|
+
|
|
86
|
+
// Verify project-context.md
|
|
87
|
+
const contextPath = path.join(TEST_PROJECT_PATH, '.windsurf', 'rules', 'project-context.md');
|
|
88
|
+
expect(await fs.pathExists(contextPath)).toBe(true);
|
|
89
|
+
const contextContent = await fs.readFile(contextPath, 'utf-8');
|
|
90
|
+
expect(contextContent).toContain('Project Context');
|
|
91
|
+
expect(contextContent).toContain('Goal');
|
|
92
|
+
|
|
93
|
+
// Verify architecture.md
|
|
94
|
+
const archPath = path.join(TEST_PROJECT_PATH, '.windsurf', 'rules', 'architecture.md');
|
|
95
|
+
expect(await fs.pathExists(archPath)).toBe(true);
|
|
96
|
+
|
|
97
|
+
// Verify workflows
|
|
98
|
+
expect(generated.workflows).toHaveLength(1); // Only review-requirements for rapid
|
|
99
|
+
|
|
100
|
+
const reviewWorkflowPath = path.join(TEST_PROJECT_PATH, '.windsurf', 'workflows', 'review-requirements.md');
|
|
101
|
+
expect(await fs.pathExists(reviewWorkflowPath)).toBe(true);
|
|
102
|
+
const reviewContent = await fs.readFile(reviewWorkflowPath, 'utf-8');
|
|
103
|
+
expect(reviewContent).toContain('Review Requirements');
|
|
104
|
+
expect(reviewContent).toContain('Steps');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('Balanced Framework', () => {
|
|
109
|
+
it('should generate Windsurf configurations from Balanced outputs', async () => {
|
|
110
|
+
// Create mock outputs
|
|
111
|
+
const constitutionContent = `# Constitution
|
|
112
|
+
|
|
113
|
+
## Core Principles
|
|
114
|
+
1. User privacy is paramount
|
|
115
|
+
2. Performance over features
|
|
116
|
+
|
|
117
|
+
## Constraints
|
|
118
|
+
- No third-party analytics
|
|
119
|
+
- WCAG 2.1 AA compliance
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
const specificationContent = `# Specification
|
|
123
|
+
|
|
124
|
+
## Overview
|
|
125
|
+
A comprehensive user management system.
|
|
126
|
+
|
|
127
|
+
## Architecture
|
|
128
|
+
Microservices architecture with API gateway.
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
const planContent = `# Technical Plan
|
|
132
|
+
|
|
133
|
+
## Technology Stack
|
|
134
|
+
- React 18
|
|
135
|
+
- Node.js 20
|
|
136
|
+
- PostgreSQL 15
|
|
137
|
+
|
|
138
|
+
## Code Style
|
|
139
|
+
- Use TypeScript strict mode
|
|
140
|
+
- Follow Airbnb style guide
|
|
141
|
+
`;
|
|
142
|
+
|
|
143
|
+
await fs.writeFile(
|
|
144
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'constitution.md'),
|
|
145
|
+
constitutionContent,
|
|
146
|
+
'utf-8'
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
await fs.writeFile(
|
|
150
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'specification.md'),
|
|
151
|
+
specificationContent,
|
|
152
|
+
'utf-8'
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
await fs.writeFile(
|
|
156
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'plan.md'),
|
|
157
|
+
planContent,
|
|
158
|
+
'utf-8'
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
await fs.writeJson(path.join(TEST_SESSION_PATH, '_metadata.json'), {
|
|
162
|
+
framework: 'balanced',
|
|
163
|
+
projectName: 'User Management System'
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Generate Windsurf configs
|
|
167
|
+
const generator = new WindsurfGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'balanced');
|
|
168
|
+
const generated = await generator.generate();
|
|
169
|
+
|
|
170
|
+
// Verify .windsurfrules
|
|
171
|
+
const legacyPath = path.join(TEST_PROJECT_PATH, '.windsurfrules');
|
|
172
|
+
const legacyContent = await fs.readFile(legacyPath, 'utf-8');
|
|
173
|
+
expect(legacyContent).toContain('Core Principles');
|
|
174
|
+
expect(legacyContent).toContain('User privacy is paramount');
|
|
175
|
+
expect(legacyContent).toContain('Constraints');
|
|
176
|
+
expect(legacyContent).toContain('constitution.md');
|
|
177
|
+
expect(legacyContent).toContain('specification.md');
|
|
178
|
+
expect(legacyContent).toContain('plan.md');
|
|
179
|
+
|
|
180
|
+
// Verify workflows (Balanced should have 2 workflows)
|
|
181
|
+
expect(generated.workflows).toHaveLength(2);
|
|
182
|
+
|
|
183
|
+
const implementWorkflowPath = path.join(TEST_PROJECT_PATH, '.windsurf', 'workflows', 'implement-feature.md');
|
|
184
|
+
expect(await fs.pathExists(implementWorkflowPath)).toBe(true);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
describe('BMAD Framework', () => {
|
|
189
|
+
it('should generate Windsurf configurations from BMAD outputs', async () => {
|
|
190
|
+
// Create mock outputs
|
|
191
|
+
const prdContent = `# Product Requirements Document
|
|
192
|
+
|
|
193
|
+
## Executive Summary
|
|
194
|
+
A complete e-commerce platform for small businesses.
|
|
195
|
+
|
|
196
|
+
## Goals and Objectives
|
|
197
|
+
- Enable online sales
|
|
198
|
+
- Provide analytics
|
|
199
|
+
|
|
200
|
+
## Technical Requirements
|
|
201
|
+
- RESTful API
|
|
202
|
+
- Payment gateway integration
|
|
203
|
+
`;
|
|
204
|
+
|
|
205
|
+
const architectureContent = `# System Architecture
|
|
206
|
+
|
|
207
|
+
## System Overview
|
|
208
|
+
Modular monolith architecture with separate domains.
|
|
209
|
+
|
|
210
|
+
## Components
|
|
211
|
+
- Order Management
|
|
212
|
+
- Inventory System
|
|
213
|
+
- Payment Processing
|
|
214
|
+
`;
|
|
215
|
+
|
|
216
|
+
await fs.writeFile(
|
|
217
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prd.md'),
|
|
218
|
+
prdContent,
|
|
219
|
+
'utf-8'
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
await fs.writeFile(
|
|
223
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'architecture.md'),
|
|
224
|
+
architectureContent,
|
|
225
|
+
'utf-8'
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
await fs.writeJson(path.join(TEST_SESSION_PATH, '_metadata.json'), {
|
|
229
|
+
framework: 'comprehensive',
|
|
230
|
+
projectName: 'E-commerce Platform'
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Generate Windsurf configs
|
|
234
|
+
const generator = new WindsurfGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'comprehensive');
|
|
235
|
+
const generated = await generator.generate();
|
|
236
|
+
|
|
237
|
+
// Verify .windsurfrules
|
|
238
|
+
const legacyPath = path.join(TEST_PROJECT_PATH, '.windsurfrules');
|
|
239
|
+
const legacyContent = await fs.readFile(legacyPath, 'utf-8');
|
|
240
|
+
expect(legacyContent).toContain('E-commerce Platform');
|
|
241
|
+
expect(legacyContent).toContain('Product Overview');
|
|
242
|
+
expect(legacyContent).toContain('e-commerce platform');
|
|
243
|
+
expect(legacyContent).toContain('prd.md');
|
|
244
|
+
expect(legacyContent).toContain('architecture.md');
|
|
245
|
+
|
|
246
|
+
// Verify workflows (BMAD should have 2 workflows)
|
|
247
|
+
expect(generated.workflows).toHaveLength(2);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
describe('Character Limits', () => {
|
|
252
|
+
it('should respect 12,000 character limit per rule file', async () => {
|
|
253
|
+
// Create a very long PRP
|
|
254
|
+
const longContent = `# PRP\n\n## 1. Goal Definition\n${'x'.repeat(5000)}\n\n## 4. Implementation Blueprint\n${'y'.repeat(5000)}`;
|
|
255
|
+
|
|
256
|
+
await fs.writeFile(
|
|
257
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prp.md'),
|
|
258
|
+
longContent,
|
|
259
|
+
'utf-8'
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
const generator = new WindsurfGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'rapid');
|
|
263
|
+
await generator.generate();
|
|
264
|
+
|
|
265
|
+
// Verify each rule file is under 12,000 characters
|
|
266
|
+
const rulesDir = path.join(TEST_PROJECT_PATH, '.windsurf', 'rules');
|
|
267
|
+
const ruleFiles = await fs.readdir(rulesDir);
|
|
268
|
+
|
|
269
|
+
for (const file of ruleFiles) {
|
|
270
|
+
const content = await fs.readFile(path.join(rulesDir, file), 'utf-8');
|
|
271
|
+
expect(content.length).toBeLessThan(12000);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
describe('Template Variables', () => {
|
|
277
|
+
it('should replace session ID in paths', async () => {
|
|
278
|
+
const prpContent = '# PRP\n\n## 1. Goal Definition\nTest project';
|
|
279
|
+
|
|
280
|
+
await fs.writeFile(
|
|
281
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prp.md'),
|
|
282
|
+
prpContent,
|
|
283
|
+
'utf-8'
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const generator = new WindsurfGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'rapid');
|
|
287
|
+
await generator.generate();
|
|
288
|
+
|
|
289
|
+
const legacyContent = await fs.readFile(
|
|
290
|
+
path.join(TEST_PROJECT_PATH, '.windsurfrules'),
|
|
291
|
+
'utf-8'
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
// Should contain the actual session ID, not a template variable
|
|
295
|
+
expect(legacyContent).toContain('test-session');
|
|
296
|
+
expect(legacyContent).not.toContain('{SESSION_ID}');
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('should include ADF CLI version', async () => {
|
|
300
|
+
const prpContent = '# PRP\n\n## 1. Goal Definition\nTest';
|
|
301
|
+
|
|
302
|
+
await fs.writeFile(
|
|
303
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prp.md'),
|
|
304
|
+
prpContent,
|
|
305
|
+
'utf-8'
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
const generator = new WindsurfGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'rapid');
|
|
309
|
+
await generator.generate();
|
|
310
|
+
|
|
311
|
+
const legacyContent = await fs.readFile(
|
|
312
|
+
path.join(TEST_PROJECT_PATH, '.windsurfrules'),
|
|
313
|
+
'utf-8'
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
expect(legacyContent).toContain('Generated by');
|
|
317
|
+
expect(legacyContent).toContain('ADF CLI');
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
});
|