@iservu-inc/adf-cli 0.4.34 → 0.4.35

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/CHANGELOG.md CHANGED
@@ -5,6 +5,94 @@ All notable changes to `@iservu-inc/adf-cli` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.35] - 2025-10-04
9
+
10
+ ### 🔧 MAJOR FIX: Windsurf Configuration - Activation Modes & Content Generation
11
+
12
+ **Fixed: Empty/Useless Windsurf Files**
13
+ - **Problem:** Generated Windsurf files had wrong activation modes and empty content
14
+ - **Issues:**
15
+ 1. Rules had `Manual` activation (useless) instead of `Always On`
16
+ 2. Workflows had no activation mode frontmatter
17
+ 3. Content showed "Not provided" instead of actual answers
18
+ 4. Not reading session data to extract meaningful information
19
+
20
+ **Solution:**
21
+ 1. **Added Proper Frontmatter with Activation Modes:**
22
+ - Rules: `trigger: always_on` (default for most rules)
23
+ - Workflows: `trigger: manual` with descriptions
24
+ - Follows Windsurf best practices
25
+
26
+ 2. **Reads Actual Session Answers:**
27
+ - New `loadSessionAnswers()` loads `_progress.json`
28
+ - Extracts real answers from interview session
29
+ - Falls back gracefully if data unavailable
30
+
31
+ 3. **Intelligent Content Parsing:**
32
+ - New `parseImplementationBlueprint()` extracts structured sections
33
+ - New `extractSubsection()` finds content by keywords
34
+ - New `extractTechStackFromAnswers()` finds tech mentions
35
+ - New `extractWhatBuildingFromAnswers()` finds project goals
36
+
37
+ **Before v0.4.35 (Broken):**
38
+ ```markdown
39
+ # Architecture - adf-test-project
40
+
41
+ ## Implementation Blueprint
42
+ Not provided
43
+
44
+ ## Data Model
45
+ Not provided
46
+ ```
47
+
48
+ **After v0.4.35 (Fixed):**
49
+ ```markdown
50
+ ---
51
+ trigger: always_on
52
+ ---
53
+
54
+ # Architecture - adf-test-project
55
+
56
+ ## Implementation Blueprint
57
+
58
+ ### Implementation Steps
59
+ **Project Goal:**
60
+ A performance website with nextjs frontend, postgres database...
61
+
62
+ ### Technical Approach
63
+ **Tech Stack:**
64
+ Next.js for frontend and backend, PostgreSQL for database...
65
+ ```
66
+
67
+ **Code Changes:**
68
+ - windsurf-generator.js:217-289 - Added frontmatter to project-context rule
69
+ - windsurf-generator.js:296-359 - Added frontmatter & parsing to architecture rule
70
+ - windsurf-generator.js:381-437 - Added frontmatter to coding-standards rule
71
+ - windsurf-generator.js:465-545 - Added frontmatter & descriptions to workflows
72
+ - windsurf-generator.js:633-754 - NEW helper methods for answer parsing
73
+
74
+ **New Helper Methods:**
75
+ - `loadSessionAnswers()` - Reads _progress.json
76
+ - `parseImplementationBlueprint()` - Parses blueprint into sections
77
+ - `extractSubsection()` - Finds content by keyword matching
78
+ - `extractTechStackFromAnswers()` - Detects tech stack in answers
79
+ - `extractWhatBuildingFromAnswers()` - Finds project goals
80
+
81
+ **Activation Modes Guide:**
82
+ - **Always On:** Default for rules - always active
83
+ - **Glob:** For file/pattern matching (not used yet)
84
+ - **Manual:** For workflows - user must activate
85
+ - **Model Decide:** AI chooses when to activate (requires description)
86
+
87
+ **Impact:**
88
+ - ✅ Windsurf rules now work properly with `Always On` activation
89
+ - ✅ Files contain actual project information, not placeholders
90
+ - ✅ Workflows have proper frontmatter with descriptions
91
+ - ✅ Better content extraction from session answers
92
+ - ✅ Fallback to PRP/specification if answers unavailable
93
+
94
+ ---
95
+
8
96
  ## [0.4.34] - 2025-10-04
9
97
 
10
98
  ### ✨ Feature: Multi-Tool Deployment Selection
@@ -214,7 +214,11 @@ ${this.extractSection(this.outputs.architecture || '', 'System Overview') || 'Se
214
214
  let content;
215
215
  if (this.framework === 'rapid') {
216
216
  const sections = this.outputs.sections || {};
217
- content = `# Project Context - ${projectName}
217
+ content = `---
218
+ trigger: always_on
219
+ ---
220
+
221
+ # Project Context - ${projectName}
218
222
 
219
223
  ## Goal
220
224
 
@@ -235,7 +239,11 @@ All requirements are documented in: \`.adf/sessions/${this.getSessionId()}/outpu
235
239
  Read this file before implementing any features.
236
240
  `;
237
241
  } else if (this.framework === 'balanced') {
238
- content = `# Project Context - ${projectName}
242
+ content = `---
243
+ trigger: always_on
244
+ ---
245
+
246
+ # Project Context - ${projectName}
239
247
 
240
248
  ## Overview
241
249
 
@@ -257,7 +265,11 @@ Review these files before implementing:
257
265
  - Technical Plan: \`.adf/sessions/${this.getSessionId()}/outputs/plan.md\`
258
266
  `;
259
267
  } else {
260
- content = `# Project Context - ${projectName}
268
+ content = `---
269
+ trigger: always_on
270
+ ---
271
+
272
+ # Project Context - ${projectName}
261
273
 
262
274
  ## Product Overview
263
275
 
@@ -282,21 +294,52 @@ Review these files before implementing:
282
294
  async generateArchitectureRule() {
283
295
  const projectName = this.getProjectName();
284
296
 
297
+ // Load actual session answers for better content
298
+ const answers = await this.loadSessionAnswers();
299
+
285
300
  let content;
286
301
  if (this.framework === 'rapid') {
287
302
  const sections = this.outputs.sections || {};
288
- content = `# Architecture - ${projectName}
303
+ const blueprint = sections['4._implementation_blueprint'] || sections['implementation_blueprint'];
304
+
305
+ // Parse blueprint into structured sections
306
+ const parsed = this.parseImplementationBlueprint(blueprint || '', answers);
307
+
308
+ content = `---
309
+ trigger: always_on
310
+ ---
311
+
312
+ # Architecture - ${projectName}
289
313
 
290
314
  ## Implementation Blueprint
291
315
 
292
- ${sections['4._implementation_blueprint'] || sections['implementation_blueprint'] || 'See PRP'}
316
+ ### Implementation Steps
317
+ ${parsed.steps || 'Not provided'}
318
+
319
+ ### Data Model
320
+ ${parsed.dataModel || 'Not provided'}
321
+
322
+ ### API Design
323
+ ${parsed.apiDesign || 'Not provided'}
324
+
325
+ ### Edge Cases & Error Handling
326
+ ${parsed.errorHandling || 'Not provided'}
327
+
328
+ ### Technical Approach
329
+ ${parsed.technicalApproach || 'Not provided'}
330
+
331
+ ---
293
332
 
294
333
  ## Reference
295
334
 
296
335
  Full implementation details: \`.adf/sessions/${this.getSessionId()}/outputs/prp.md\`
297
336
  `;
298
337
  } else if (this.framework === 'balanced') {
299
- content = `# Architecture - ${projectName}
338
+ content = `---
339
+ trigger: always_on
340
+ ---
341
+
342
+ # Architecture - ${projectName}
300
343
 
301
344
  ${this.extractSection(this.outputs.specification || '', 'Architecture') || 'See specification'}
302
345
 
@@ -309,7 +352,11 @@ ${this.extractSection(this.outputs.plan || '', 'Architecture') || 'See technical
309
352
  Full architecture: \`.adf/sessions/${this.getSessionId()}/outputs/specification.md\`
310
353
  `;
311
354
  } else {
312
- content = `# Architecture - ${projectName}
355
+ content = `---
356
+ trigger: always_on
357
+ ---
358
+
359
+ # Architecture - ${projectName}
313
360
 
314
361
  ${this.extractSection(this.outputs.architecture || '', 'System Overview') || 'See architecture.md'}
315
362
 
@@ -331,7 +378,11 @@ Full architecture: \`.adf/sessions/${this.getSessionId()}/outputs/architecture.m
331
378
 
332
379
  let content;
333
380
  if (this.framework === 'rapid') {
334
- content = `# Coding Standards - ${projectName}
381
+ content = `---
382
+ trigger: always_on
383
+ ---
384
+
385
+ # Coding Standards - ${projectName}
335
386
 
336
387
  ## General Guidelines
337
388
 
@@ -346,7 +397,11 @@ Full architecture: \`.adf/sessions/${this.getSessionId()}/outputs/architecture.m
346
397
  See implementation blueprint in: \`.adf/sessions/${this.getSessionId()}/outputs/prp.md\`
347
398
  `;
348
399
  } else if (this.framework === 'balanced') {
349
- content = `# Coding Standards - ${projectName}
400
+ content = `---
401
+ trigger: always_on
402
+ ---
403
+
404
+ # Coding Standards - ${projectName}
350
405
 
351
406
  ${this.extractSection(this.outputs.plan || '', 'Code Style') || this.extractSection(this.outputs.plan || '', 'Coding Standards') || ''}
352
407
 
@@ -359,7 +414,11 @@ ${this.extractSection(this.outputs.constitution || '', 'Core Principles') || 'Fo
359
414
  Full standards: \`.adf/sessions/${this.getSessionId()}/outputs/plan.md\`
360
415
  `;
361
416
  } else {
362
- content = `# Coding Standards - ${projectName}
417
+ content = `---
418
+ trigger: always_on
419
+ ---
420
+
421
+ # Coding Standards - ${projectName}
363
422
 
364
423
  ${this.extractSection(this.outputs.prd || '', 'Code Quality') || ''}
365
424
 
@@ -403,7 +462,12 @@ Full requirements: \`.adf/sessions/${this.getSessionId()}/outputs/prd.md\`
403
462
  let content;
404
463
 
405
464
  if (this.framework === 'rapid') {
406
- content = `# Review Requirements
465
+ content = `---
466
+ trigger: manual
467
+ description: Review project requirements before implementing
468
+ ---
469
+
470
+ # Review Requirements
407
471
 
408
472
  Use this workflow to review requirements before implementing.
409
473
 
@@ -424,7 +488,12 @@ Use this workflow to review requirements before implementing.
424
488
  - How will success be measured?
425
489
  `;
426
490
  } else if (this.framework === 'balanced') {
427
- content = `# Review Requirements
491
+ content = `---
492
+ trigger: manual
493
+ description: Review project requirements before implementing
494
+ ---
495
+
496
+ # Review Requirements
428
497
 
429
498
  Use this workflow to review requirements before implementing.
430
499
 
@@ -447,7 +516,12 @@ Use this workflow to review requirements before implementing.
447
516
  - Are there any dependencies?
448
517
  `;
449
518
  } else {
450
- content = `# Review Requirements
519
+ content = `---
520
+ trigger: manual
521
+ description: Review project requirements before implementing
522
+ ---
523
+
524
+ # Review Requirements
451
525
 
452
526
  Use this workflow to review requirements before implementing.
453
527
 
@@ -477,7 +551,12 @@ Use this workflow to review requirements before implementing.
477
551
  let content;
478
552
 
479
553
  if (this.framework === 'balanced') {
480
- content = `# Implement Feature
554
+ content = `---
555
+ trigger: manual
556
+ description: Workflow for implementing a new feature
557
+ ---
558
+
559
+ # Implement Feature
481
560
 
482
561
  Use this workflow when implementing a feature.
483
562
 
@@ -511,7 +590,12 @@ Use this workflow when implementing a feature.
511
590
  - Tasks: \`.adf/sessions/${this.getSessionId()}/outputs/tasks.md\`
512
591
  `;
513
592
  } else {
514
- content = `# Implement User Story
593
+ content = `---
594
+ trigger: manual
595
+ description: Workflow for implementing a user story
596
+ ---
597
+
598
+ # Implement User Story
515
599
 
516
600
  Use this workflow when implementing a user story.
517
601
 
@@ -591,6 +675,132 @@ Use this workflow when implementing a user story.
591
675
  return '0.3.0';
592
676
  }
593
677
  }
678
+
679
+ /**
680
+ * Load session answers from _progress.json
681
+ */
682
+ async loadSessionAnswers() {
683
+ const fs = require('fs-extra');
684
+ const progressPath = path.join(this.sessionPath, '_progress.json');
685
+
686
+ try {
687
+ if (await fs.pathExists(progressPath)) {
688
+ const progress = await fs.readJson(progressPath);
689
+ return progress.answers || {};
690
+ }
691
+ } catch (error) {
692
+ // Fall back to empty if can't load
693
+ }
694
+
695
+ return {};
696
+ }
697
+
698
+ /**
699
+ * Parse implementation blueprint into structured sections
700
+ */
701
+ parseImplementationBlueprint(blueprint, answers) {
702
+ const parsed = {
703
+ steps: null,
704
+ dataModel: null,
705
+ apiDesign: null,
706
+ errorHandling: null,
707
+ technicalApproach: null
708
+ };
709
+
710
+ // If blueprint exists, parse it
711
+ if (blueprint && blueprint.length > 20) {
712
+ parsed.steps = this.extractSubsection(blueprint, ['implementation steps', 'steps to implement', 'development steps']);
713
+ parsed.dataModel = this.extractSubsection(blueprint, ['data model', 'database schema', 'data structure']);
714
+ parsed.apiDesign = this.extractSubsection(blueprint, ['api design', 'api endpoints', 'routes']);
715
+ parsed.errorHandling = this.extractSubsection(blueprint, ['error handling', 'edge cases']);
716
+ parsed.technicalApproach = this.extractSubsection(blueprint, ['technical approach', 'architecture', 'approach']);
717
+ }
718
+
719
+ // If still empty, try to extract from answers
720
+ if (!parsed.steps && answers) {
721
+ // Look for tech stack, implementation details in any answer
722
+ const techStack = this.extractTechStackFromAnswers(answers);
723
+ const whatBuilding = this.extractWhatBuildingFromAnswers(answers);
724
+
725
+ if (techStack) {
726
+ parsed.technicalApproach = `**Tech Stack:**\n${techStack}`;
727
+ }
728
+
729
+ if (whatBuilding) {
730
+ parsed.steps = `**Project Goal:**\n${whatBuilding}`;
731
+ }
732
+ }
733
+
734
+ return parsed;
735
+ }
736
+
737
+ /**
738
+ * Extract subsection from content by looking for keywords
739
+ */
740
+ extractSubsection(content, keywords) {
741
+ const lines = content.split('\n');
742
+ let inSection = false;
743
+ let sectionContent = [];
744
+
745
+ for (let i = 0; i < lines.length; i++) {
746
+ const line = lines[i];
747
+ const lowerLine = line.toLowerCase();
748
+
749
+ // Check if this line is a heading matching our keywords
750
+ if (line.match(/^#{2,4}\s+/)) {
751
+ const headingText = line.replace(/^#{2,4}\s+/, '').toLowerCase();
752
+
753
+ if (keywords.some(kw => headingText.includes(kw))) {
754
+ inSection = true;
755
+ continue;
756
+ } else if (inSection) {
757
+ // Hit a new heading, stop
758
+ break;
759
+ }
760
+ }
761
+
762
+ if (inSection && line.trim()) {
763
+ sectionContent.push(line);
764
+ }
765
+ }
766
+
767
+ const result = sectionContent.join('\n').trim();
768
+ return result.length > 10 ? result : null;
769
+ }
770
+
771
+ /**
772
+ * Extract tech stack from any answer
773
+ */
774
+ extractTechStackFromAnswers(answers) {
775
+ for (const [questionId, answer] of Object.entries(answers)) {
776
+ if (typeof answer === 'string') {
777
+ const lower = answer.toLowerCase();
778
+ // Look for mentions of frameworks, languages, databases
779
+ if (lower.includes('react') || lower.includes('vue') || lower.includes('angular') ||
780
+ lower.includes('node') || lower.includes('python') || lower.includes('next') ||
781
+ lower.includes('postgres') || lower.includes('mongo') || lower.includes('mysql')) {
782
+ return answer;
783
+ }
784
+ }
785
+ }
786
+ return null;
787
+ }
788
+
789
+ /**
790
+ * Extract "what are you building" from any answer
791
+ */
792
+ extractWhatBuildingFromAnswers(answers) {
793
+ for (const [questionId, answer] of Object.entries(answers)) {
794
+ if (questionId.toLowerCase().includes('goal') ||
795
+ questionId.toLowerCase().includes('building') ||
796
+ questionId.toLowerCase().includes('project')) {
797
+ if (typeof answer === 'string' && answer.length > 20) {
798
+ return answer;
799
+ }
800
+ }
801
+ }
802
+ return null;
803
+ }
594
804
  }
595
805
 
596
806
  module.exports = WindsurfGenerator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iservu-inc/adf-cli",
3
- "version": "0.4.34",
3
+ "version": "0.4.35",
4
4
  "description": "CLI tool for AgentDevFramework - AI-assisted development framework with multi-provider AI support",
5
5
  "main": "index.js",
6
6
  "bin": {