specweave 0.21.3 → 0.22.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.
Files changed (59) hide show
  1. package/CLAUDE.md +198 -6
  2. package/README.md +33 -3
  3. package/dist/plugins/specweave-github/lib/CodeValidator.d.ts +101 -0
  4. package/dist/plugins/specweave-github/lib/CodeValidator.d.ts.map +1 -0
  5. package/dist/plugins/specweave-github/lib/CodeValidator.js +219 -0
  6. package/dist/plugins/specweave-github/lib/CodeValidator.js.map +1 -0
  7. package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.d.ts +182 -0
  8. package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.d.ts.map +1 -0
  9. package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js +603 -0
  10. package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js.map +1 -0
  11. package/dist/plugins/specweave-github/lib/types.d.ts +34 -0
  12. package/dist/plugins/specweave-github/lib/types.d.ts.map +1 -1
  13. package/dist/src/cli/commands/init.d.ts.map +1 -1
  14. package/dist/src/cli/commands/init.js +60 -5
  15. package/dist/src/cli/commands/init.js.map +1 -1
  16. package/dist/src/config/types.d.ts +8 -8
  17. package/dist/src/core/living-docs/CompletionPropagator.d.ts.map +1 -1
  18. package/dist/src/core/living-docs/CompletionPropagator.js +4 -3
  19. package/dist/src/core/living-docs/CompletionPropagator.js.map +1 -1
  20. package/dist/src/core/living-docs/SpecDistributor.d.ts +5 -0
  21. package/dist/src/core/living-docs/SpecDistributor.d.ts.map +1 -1
  22. package/dist/src/core/living-docs/SpecDistributor.js +12 -0
  23. package/dist/src/core/living-docs/SpecDistributor.js.map +1 -1
  24. package/dist/src/core/living-docs/project-detector.d.ts.map +1 -1
  25. package/dist/src/core/living-docs/project-detector.js +38 -0
  26. package/dist/src/core/living-docs/project-detector.js.map +1 -1
  27. package/dist/src/core/types/config.d.ts +23 -0
  28. package/dist/src/core/types/config.d.ts.map +1 -1
  29. package/dist/src/core/types/config.js +10 -0
  30. package/dist/src/core/types/config.js.map +1 -1
  31. package/dist/src/init/ArchitecturePresenter.d.ts +47 -0
  32. package/dist/src/init/ArchitecturePresenter.d.ts.map +1 -0
  33. package/dist/src/init/ArchitecturePresenter.js +180 -0
  34. package/dist/src/init/ArchitecturePresenter.js.map +1 -0
  35. package/dist/src/init/InitFlow.d.ts.map +1 -1
  36. package/dist/src/init/InitFlow.js +30 -1
  37. package/dist/src/init/InitFlow.js.map +1 -1
  38. package/dist/src/init/architecture/CostEstimator.d.ts +52 -0
  39. package/dist/src/init/architecture/CostEstimator.d.ts.map +1 -0
  40. package/dist/src/init/architecture/CostEstimator.js +107 -0
  41. package/dist/src/init/architecture/CostEstimator.js.map +1 -0
  42. package/dist/src/init/architecture/InfrastructureMapper.d.ts +41 -0
  43. package/dist/src/init/architecture/InfrastructureMapper.d.ts.map +1 -0
  44. package/dist/src/init/architecture/InfrastructureMapper.js +140 -0
  45. package/dist/src/init/architecture/InfrastructureMapper.js.map +1 -0
  46. package/dist/src/init/architecture/ProjectGenerator.d.ts +44 -0
  47. package/dist/src/init/architecture/ProjectGenerator.d.ts.map +1 -0
  48. package/dist/src/init/architecture/ProjectGenerator.js +216 -0
  49. package/dist/src/init/architecture/ProjectGenerator.js.map +1 -0
  50. package/dist/src/init/research/src/config/types.d.ts +8 -8
  51. package/package.json +9 -8
  52. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
  53. package/plugins/specweave-github/lib/CodeValidator.js +195 -0
  54. package/plugins/specweave-github/lib/CodeValidator.ts +284 -0
  55. package/plugins/specweave-github/lib/ThreeLayerSyncManager.js +545 -0
  56. package/plugins/specweave-github/lib/ThreeLayerSyncManager.ts +809 -0
  57. package/plugins/specweave-github/lib/types.ts +38 -0
  58. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1200 -0
  59. package/src/templates/AGENTS.md.template +22 -1
package/CLAUDE.md CHANGED
@@ -24,21 +24,23 @@ Users receive a different CLAUDE.md via the template system.
24
24
  /SESSION-SUMMARY-2025-10-28.md # NO! Goes to increment reports/
25
25
  /ADR-006-DEEP-ANALYSIS.md # NO! Goes to .specweave/docs/internal/architecture/adr/
26
26
  /ANALYSIS-MULTI-TOOL-COMPARISON.md # NO! Goes to increment reports/
27
+ /QUICK-START.md # NO! Goes to increment reports/
27
28
  /migration-helper.sh # NO! Goes to increment scripts/
28
29
  /execution.log # NO! Goes to increment logs/
29
30
 
30
31
  ✅ CORRECT - INCREMENT FOLDERS:
31
32
  .specweave/increments/0004-plugin-architecture/
32
- ├── spec.md # Spec files (core 3)
33
+ ├── spec.md # ⚠️ ONLY THESE 3 FILES in root!
33
34
  ├── plan.md
34
35
  ├── tasks.md # Tasks with embedded tests
35
- ├── reports/ # ✅ PUT REPORTS HERE!
36
+ ├── reports/ # ✅ ALL REPORTS HERE!
36
37
  │ ├── PLUGIN-MIGRATION-COMPLETE.md # ✅ Completion reports
37
38
  │ ├── SESSION-SUMMARY.md # ✅ Session summaries
39
+ │ ├── QUICK-START.md # ✅ Quick start guides
38
40
  │ └── ANALYSIS-*.md # ✅ Analysis files
39
- ├── scripts/ # ✅ PUT SCRIPTS HERE!
41
+ ├── scripts/ # ✅ ALL SCRIPTS HERE!
40
42
  │ └── migration-helper.sh # ✅ Helper scripts
41
- └── logs/ # ✅ PUT LOGS HERE!
43
+ └── logs/ # ✅ ALL LOGS HERE!
42
44
  └── execution.log # ✅ Execution logs
43
45
 
44
46
  .specweave/docs/internal/architecture/ # ✅ PUT ADRS/DIAGRAMS HERE!
@@ -48,6 +50,105 @@ Users receive a different CLAUDE.md via the template system.
48
50
 
49
51
  **Before committing, ALWAYS check**: `git status` - If you see `.md` files in root, MOVE THEM!
50
52
 
53
+ ### 📁 Increment Structure Rules (MANDATORY)
54
+
55
+ **ONLY 3 files allowed in increment root**:
56
+ 1. ✅ `spec.md` - Specification
57
+ 2. ✅ `plan.md` - Implementation plan
58
+ 3. ✅ `tasks.md` - Tasks with embedded tests
59
+
60
+ **Everything else MUST be in subfolders**:
61
+ - `reports/` - Session summaries, completion reports, analysis files, quick-start guides
62
+ - `scripts/` - Helper scripts, migrations, utilities
63
+ - `logs/` - Execution logs, debug output, temp files
64
+
65
+ **Examples of files that belong in subfolders**:
66
+ - `QUICK-START.md` → `reports/QUICK-START.md`
67
+ - `SESSION-NOTES.md` → `reports/SESSION-NOTES.md`
68
+ - `ULTRATHINK-*.md` → `reports/ULTRATHINK-*.md`
69
+ - `validation.sh` → `scripts/validation.sh`
70
+ - `debug.log` → `logs/debug.log`
71
+
72
+ **Why this matters**:
73
+ - ✅ Clean, predictable structure
74
+ - ✅ Easy to find files by type
75
+ - ✅ No increment root clutter
76
+ - ✅ Consistent across all increments
77
+
78
+ ---
79
+
80
+ ## 🛡️ CRITICAL: NEVER DELETE .specweave/ DIRECTORIES!
81
+
82
+ **⛔ MASS DELETION PROTECTION IS ACTIVE ⛔**
83
+
84
+ **PROTECTED DIRECTORIES**:
85
+ - `.specweave/docs/` - All project documentation (internal + public)
86
+ - `.specweave/increments/` - All increment history and specifications
87
+
88
+ **WHAT THIS MEANS**:
89
+ - ❌ **NEVER** run `rm -rf .specweave/docs` or `rm -rf .specweave/increments`
90
+ - ❌ **NEVER** delete more than 50 files in these directories at once
91
+ - ✅ Pre-commit hook will **BLOCK** accidental mass deletions
92
+ - ✅ If intentional, bypass with `git commit --no-verify`
93
+
94
+ **WHY THIS EXISTS**:
95
+ On 2025-11-17, an accidental mass deletion occurred (1,200+ files). All files were recovered via `git restore`, but this protection prevents future incidents.
96
+
97
+ **IF YOU ACCIDENTALLY DELETE**:
98
+ ```bash
99
+ # Immediately restore:
100
+ git restore .specweave/
101
+
102
+ # Verify restoration:
103
+ git status
104
+ ```
105
+
106
+ **See**: `.specweave/increments/0039/reports/ACCIDENTAL-DELETION-RECOVERY-2025-11-17.md`
107
+
108
+ ---
109
+
110
+ ## ⚠️ CRITICAL: NEVER USE `specweave init . --force` FOR REINSTALLS!
111
+
112
+ **⛔ COMMON MISTAKE THAT DELETES ALL DATA ⛔**
113
+
114
+ **THE DANGER**:
115
+ ```bash
116
+ # ❌ DANGEROUS (deletes ALL increments and docs):
117
+ specweave init . --force
118
+
119
+ # What --force actually does:
120
+ # 1. Skips all confirmation prompts
121
+ # 2. AUTOMATICALLY DELETES .specweave/ entirely
122
+ # 3. Loses all increments, docs, and history
123
+ # 4. No backup unless you create one manually
124
+ ```
125
+
126
+ **SAFE ALTERNATIVES**:
127
+ ```bash
128
+ # ✅ SAFE - Update files, keep all data:
129
+ specweave init .
130
+ # When prompted, select: "Continue working"
131
+
132
+ # ✅ SAFE - Always interactive, never deletes:
133
+ npx specweave init .
134
+ ```
135
+
136
+ **WHY THIS MATTERS**:
137
+ - Documentation used to recommend `--force` for troubleshooting (FIXED in v0.21.4+)
138
+ - Users followed the docs and lost all their work
139
+ - Now `--force` has multiple safeguards:
140
+ - ⚠️ BIG RED WARNING before deletion
141
+ - ✅ ALWAYS requires confirmation (even in force mode)
142
+ - 📦 Automatic backup created before deletion
143
+ - 🔒 Pre-commit hook blocks accidental commits
144
+
145
+ **IF YOU NEED A FRESH START**:
146
+ 1. Backup first: `cp -r .specweave .specweave.backup-$(date +%Y%m%d)`
147
+ 2. Run: `specweave init .` (select "Fresh start" option)
148
+ 3. Or: `specweave init . --force` (requires confirmation + creates auto-backup)
149
+
150
+ **NEVER use `--force` unless you want to DELETE EVERYTHING!**
151
+
51
152
  ---
52
153
 
53
154
  ## Tool Support
@@ -353,12 +454,103 @@ npm run build # Compile TypeScript
353
454
 
354
455
  ### Testing
355
456
 
457
+ **Test Framework**: **Vitest** (migrated from Jest on 2025-11-17)
458
+
356
459
  ```bash
357
- npm test # Unit tests
358
- npm run test:integration # Integration tests (includes build verification)
460
+ npm test # Smoke tests (quick validation)
461
+ npm run test:unit # Unit tests with Vitest
462
+ npm run test:integration # Integration tests with Vitest
359
463
  npm run test:e2e # E2E tests (Playwright)
464
+ npm run test:all # All tests
465
+ npm run test:coverage # Coverage report
466
+ ```
467
+
468
+ **Why Vitest?**
469
+ - ✅ ESM-native (no tsconfig hacks)
470
+ - ✅ Faster than Jest
471
+ - ✅ Better TypeScript integration
472
+ - ✅ Native import.meta.url support
473
+ - ✅ Modern, actively maintained
474
+
475
+ **Test Organization** (4 categories):
476
+ - `tests/unit/` - Pure logic tests (no I/O) - **Vitest**
477
+ - `tests/plugin-validation/` - Plugin structure contracts
478
+ - `tests/integration/` - 4 semantic categories - **Vitest**:
479
+ - `external-tools/` - GitHub, JIRA, ADO, Kafka sync
480
+ - `core/` - Core framework + workflows
481
+ - `generators/` - Code generation (frontend, backend, ML)
482
+ - `features/` - Feature plugins (Figma, i18n, diagrams, etc.)
483
+ - `tests/e2e/` - Full user scenarios - **Playwright**
484
+
485
+ **Writing Tests**:
486
+ ```typescript
487
+ // Import from vitest (NOT jest)
488
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
489
+
490
+ // Mocking
491
+ vi.mock('fs/promises');
492
+ const mockFn = vi.fn();
493
+ vi.clearAllMocks();
494
+ ```
495
+
496
+ **Details**: `.specweave/docs/internal/architecture/TEST-ORGANIZATION-PROPOSAL.md`
497
+
498
+ ### Test Isolation (CRITICAL - Prevents .specweave/ Deletion!)
499
+
500
+ **🚨 MANDATORY FOR ALL TESTS creating .specweave/ structures:**
501
+
502
+ **THE PROBLEM**: Tests using `process.cwd()` can accidentally delete the project `.specweave/` folder containing all your work!
503
+
504
+ **CORRECT PATTERN** (ALWAYS use this):
505
+ ```typescript
506
+ import * as os from 'os';
507
+ import * as path from 'path';
508
+
509
+ // ✅ SAFE: Uses isolated temp directory
510
+ const testRoot = path.join(os.tmpdir(), 'test-name-' + Date.now());
511
+ ```
512
+
513
+ **DANGEROUS PATTERN** (NEVER use this):
514
+ ```typescript
515
+ // ❌ DANGER: Creates directories in project root!
516
+ const testRoot = path.join(process.cwd(), '.test-something');
517
+ const testPath = path.join(__dirname, '..', '.specweave', 'increments');
360
518
  ```
361
519
 
520
+ **Why This Matters**:
521
+ 1. Tests create mock `.specweave/` structures for testing
522
+ 2. Cleanup uses `fs.rm(testRoot, { recursive: true })`
523
+ 3. If `testRoot` points to project root → **DELETES REAL .specweave/!**
524
+ 4. You lose all increments, docs, and history
525
+
526
+ **Use Test Utilities** (RECOMMENDED):
527
+ ```typescript
528
+ import { createIsolatedTestDir, createSpecweaveStructure } from '../test-utils/isolated-test-dir';
529
+
530
+ test('my test', async () => {
531
+ const { testDir, cleanup } = await createIsolatedTestDir('my-test');
532
+
533
+ try {
534
+ // Setup .specweave structure in isolated directory
535
+ await createSpecweaveStructure(testDir);
536
+
537
+ // Test code here - NEVER touches project .specweave/
538
+ const incrementPath = path.join(testDir, '.specweave', 'increments', '0001-test');
539
+ // ...
540
+ } finally {
541
+ await cleanup(); // ALWAYS cleanup
542
+ }
543
+ });
544
+ ```
545
+
546
+ **Protection Layers**:
547
+ 1. ✅ **Pre-commit hook**: Blocks commits with dangerous test patterns
548
+ 2. ✅ **Test utilities**: `tests/test-utils/isolated-test-dir.ts`
549
+ 3. ✅ **Documentation**: This section
550
+
551
+ **Related Incident**: 2025-11-17 - Multiple `.specweave/` deletions traced to dangerous test patterns
552
+ **Root Cause Analysis**: `.specweave/increments/0037/reports/DELETION-ROOT-CAUSE-2025-11-17.md`
553
+
362
554
  ### Build Health Checks
363
555
 
364
556
  **CRITICAL**: TypeScript ES Modules require specific practices:
package/README.md CHANGED
@@ -232,8 +232,18 @@ Claude implements Task 1:
232
232
  # Install SpecWeave
233
233
  npm install -g specweave
234
234
 
235
- # Initialize new project
235
+ # Initialize with Strategic Init (AI-powered research)
236
236
  specweave init my-project
237
+
238
+ # Strategic Init guides you through 6 phases:
239
+ # Phase 1: Vision & Market Research
240
+ # Phase 2: Scaling & Performance Goals
241
+ # Phase 3: Data & Compliance Detection
242
+ # Phase 4: Budget & Cloud Credits
243
+ # Phase 5: Methodology & Organization
244
+ # Phase 6: Repository Selection (optional)
245
+
246
+ # Result: Architecture recommendation, team plan, cost estimates
237
247
  cd my-project
238
248
 
239
249
  # Start building
@@ -242,6 +252,15 @@ cd my-project
242
252
  /specweave:done 0001 # Complete increment
243
253
  ```
244
254
 
255
+ ### Multi-Project Setup
256
+ ```bash
257
+ # Initialize with multiple projects
258
+ specweave init --projects backend,frontend,mobile
259
+
260
+ # Tasks automatically split by project keyword detection
261
+ # Each project gets its own user stories and GitHub issues
262
+ ```
263
+
245
264
  ### Brownfield (Existing Project)
246
265
  ```bash
247
266
  # Initialize SpecWeave in existing project
@@ -255,7 +274,7 @@ specweave init .
255
274
  /specweave:increment "Add dark mode"
256
275
  ```
257
276
 
258
- **[→ Complete Quickstart Guide](https://spec-weave.com/docs/guides/getting-started/quickstart)**
277
+ **[→ Complete Quickstart Guide](https://spec-weave.com/docs/guides/getting-started/quickstart)** | **[→ Strategic Init Guide](https://spec-weave.com/docs/guides/strategic-init)**
259
278
 
260
279
  ---
261
280
 
@@ -296,12 +315,23 @@ specweave init .
296
315
 
297
316
  ## Key Features
298
317
 
318
+ ### Strategic Init - AI-Powered Architecture Planning (NEW!)
319
+
320
+ - 🎯 **Research-Driven Discovery** - Answer 6 phases of questions about your product
321
+ - 🏗️ **Architecture Recommendations** - Tech stack, scaling strategy, cost projections
322
+ - 🔒 **Compliance Detection** - Auto-detects 30+ standards (HIPAA, GDPR, SOC2, etc.)
323
+ - 👥 **Smart Team Planning** - Current and future team structure, hiring roadmap
324
+ - ☁️ **Cloud Credits Discovery** - AWS Activate, Azure Startup, GCP eligibility
325
+ - 📦 **Repository Selection** - Batch select 1-100+ repos with intelligent routing
326
+
327
+ ### Production Features
328
+
299
329
  - 🤖 **AI-Native Enterprise Sync** - Claude updates JIRA/GitHub/ADO automatically (bidirectional!)
300
330
  - 📚 **Living Documentation** - Auto-updates after every task (no manual sync!)
301
331
  - 🧪 **Test-Aware Planning** - Embedded tests in BDD format (Given/When/Then)
302
332
  - 🎯 **Disciplined Progress** - Can't start increment N+1 until N is DONE
303
333
  - ⏸️ **Intelligent Pausing** - Auto-detects blockers, pauses with context, resumes when ready
304
- - 🔄 **Smart Reopen (NEW!)** - Report "broken" → Auto-detects what to reopen, respects WIP limits
334
+ - 🔄 **Smart Reopen** - Report "broken" → Auto-detects what to reopen, respects WIP limits
305
335
  - 👥 **Multi-Project Tracking** - Unlimited JIRA/ADO/GitHub repos, intelligent routing
306
336
  - 🤖 **AI Agents** - PM, Architect, Quality Judge guide your work
307
337
  - 🔧 **CI/CD Auto-Fix** - Workflow failures auto-fixed by Claude (just mention `@claude`)
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Code Validator
3
+ *
4
+ * Validates that completed tasks have actual code implementation.
5
+ * Prevents marking tasks as complete when:
6
+ * - Files don't exist
7
+ * - Files are empty or have trivial content
8
+ * - Implementation is incomplete
9
+ *
10
+ * Used by ThreeLayerSyncManager to enforce code-completion discipline.
11
+ *
12
+ * @module CodeValidator
13
+ */
14
+ /**
15
+ * File validation result
16
+ */
17
+ export interface FileValidationResult {
18
+ path: string;
19
+ exists: boolean;
20
+ hasContent: boolean;
21
+ lineCount: number;
22
+ reason?: string;
23
+ }
24
+ /**
25
+ * Task validation result
26
+ */
27
+ export interface TaskValidationResult {
28
+ taskId: string;
29
+ valid: boolean;
30
+ files: FileValidationResult[];
31
+ reason?: string;
32
+ }
33
+ /**
34
+ * CodeValidator options
35
+ */
36
+ export interface CodeValidatorOptions {
37
+ minLines?: number;
38
+ minChars?: number;
39
+ projectRoot?: string;
40
+ }
41
+ export declare class CodeValidator {
42
+ private options;
43
+ constructor(options?: CodeValidatorOptions);
44
+ /**
45
+ * Validate that code exists for a task
46
+ *
47
+ * Extracts file paths from task description and verifies:
48
+ * 1. Files exist
49
+ * 2. Files have meaningful content
50
+ * 3. Files are not just stubs
51
+ *
52
+ * @param taskDescription - Task description with file paths
53
+ * @param taskId - Task ID for error messages
54
+ * @returns Validation result
55
+ */
56
+ validateTask(taskDescription: string, taskId: string): Promise<TaskValidationResult>;
57
+ /**
58
+ * Validate a single file
59
+ *
60
+ * @param filePath - Path to file (relative or absolute)
61
+ * @returns File validation result
62
+ */
63
+ validateFile(filePath: string): Promise<FileValidationResult>;
64
+ /**
65
+ * Extract file paths from task description
66
+ *
67
+ * Supports multiple formats:
68
+ * - **Files**: src/foo.ts, src/bar.ts
69
+ * - **Files to create**: src/foo.ts
70
+ * - **Files to modify**: src/bar.ts
71
+ * - Inline code blocks with file paths
72
+ *
73
+ * @param description - Task description text
74
+ * @returns Array of file paths
75
+ */
76
+ extractFilePaths(description: string): string[];
77
+ /**
78
+ * Batch validate multiple tasks
79
+ *
80
+ * @param tasks - Array of {taskId, description}
81
+ * @returns Array of validation results
82
+ */
83
+ validateTasks(tasks: Array<{
84
+ taskId: string;
85
+ description: string;
86
+ }>): Promise<TaskValidationResult[]>;
87
+ /**
88
+ * Get summary of validation results
89
+ *
90
+ * @param results - Array of task validation results
91
+ * @returns Summary statistics
92
+ */
93
+ summarizeResults(results: TaskValidationResult[]): {
94
+ total: number;
95
+ valid: number;
96
+ invalid: number;
97
+ noFiles: number;
98
+ invalidTasks: string[];
99
+ };
100
+ }
101
+ //# sourceMappingURL=CodeValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeValidator.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/CodeValidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAiC;gBAEpC,OAAO,GAAE,oBAAyB;IAQ9C;;;;;;;;;;;OAWG;IACG,YAAY,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAsC1F;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA4EnE;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE;IAuC/C;;;;;OAKG;IACG,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAS3G;;;;;OAKG;IACH,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG;QACjD,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB;CAeF"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Code Validator
3
+ *
4
+ * Validates that completed tasks have actual code implementation.
5
+ * Prevents marking tasks as complete when:
6
+ * - Files don't exist
7
+ * - Files are empty or have trivial content
8
+ * - Implementation is incomplete
9
+ *
10
+ * Used by ThreeLayerSyncManager to enforce code-completion discipline.
11
+ *
12
+ * @module CodeValidator
13
+ */
14
+ import fs from 'fs-extra';
15
+ import path from 'path';
16
+ export class CodeValidator {
17
+ constructor(options = {}) {
18
+ this.options = {
19
+ minLines: options.minLines ?? 3,
20
+ minChars: options.minChars ?? 50,
21
+ projectRoot: options.projectRoot ?? process.cwd()
22
+ };
23
+ }
24
+ /**
25
+ * Validate that code exists for a task
26
+ *
27
+ * Extracts file paths from task description and verifies:
28
+ * 1. Files exist
29
+ * 2. Files have meaningful content
30
+ * 3. Files are not just stubs
31
+ *
32
+ * @param taskDescription - Task description with file paths
33
+ * @param taskId - Task ID for error messages
34
+ * @returns Validation result
35
+ */
36
+ async validateTask(taskDescription, taskId) {
37
+ const filePaths = this.extractFilePaths(taskDescription);
38
+ if (filePaths.length === 0) {
39
+ // No file paths specified - consider it valid (task might be non-code)
40
+ return {
41
+ taskId,
42
+ valid: true,
43
+ files: [],
44
+ reason: 'No file paths specified in task description'
45
+ };
46
+ }
47
+ const fileResults = [];
48
+ let allValid = true;
49
+ const reasons = [];
50
+ for (const filePath of filePaths) {
51
+ const result = await this.validateFile(filePath);
52
+ fileResults.push(result);
53
+ if (!result.exists) {
54
+ allValid = false;
55
+ reasons.push(`File not found: ${filePath}`);
56
+ }
57
+ else if (!result.hasContent) {
58
+ allValid = false;
59
+ reasons.push(`File has no meaningful content: ${filePath} (${result.reason})`);
60
+ }
61
+ }
62
+ return {
63
+ taskId,
64
+ valid: allValid,
65
+ files: fileResults,
66
+ reason: reasons.length > 0 ? reasons.join('; ') : undefined
67
+ };
68
+ }
69
+ /**
70
+ * Validate a single file
71
+ *
72
+ * @param filePath - Path to file (relative or absolute)
73
+ * @returns File validation result
74
+ */
75
+ async validateFile(filePath) {
76
+ // Resolve relative paths
77
+ const absolutePath = path.isAbsolute(filePath)
78
+ ? filePath
79
+ : path.join(this.options.projectRoot, filePath);
80
+ // Check if file exists
81
+ const exists = await fs.pathExists(absolutePath);
82
+ if (!exists) {
83
+ return {
84
+ path: filePath,
85
+ exists: false,
86
+ hasContent: false,
87
+ lineCount: 0,
88
+ reason: 'File does not exist'
89
+ };
90
+ }
91
+ // Read file content
92
+ const content = await fs.readFile(absolutePath, 'utf-8');
93
+ const lines = content.split('\n');
94
+ const nonEmptyLines = lines.filter(line => line.trim().length > 0);
95
+ // Check line count
96
+ if (nonEmptyLines.length < this.options.minLines) {
97
+ return {
98
+ path: filePath,
99
+ exists: true,
100
+ hasContent: false,
101
+ lineCount: nonEmptyLines.length,
102
+ reason: `Only ${nonEmptyLines.length} non-empty lines (minimum: ${this.options.minLines})`
103
+ };
104
+ }
105
+ // Check character count
106
+ const trimmedContent = content.trim();
107
+ if (trimmedContent.length < this.options.minChars) {
108
+ return {
109
+ path: filePath,
110
+ exists: true,
111
+ hasContent: false,
112
+ lineCount: nonEmptyLines.length,
113
+ reason: `Only ${trimmedContent.length} characters (minimum: ${this.options.minChars})`
114
+ };
115
+ }
116
+ // Check for stub patterns (common placeholder patterns)
117
+ const stubPatterns = [
118
+ /^\/\/\s*TODO:/i,
119
+ /^#\s*TODO:/i,
120
+ /^\s*throw new Error\(['"]Not implemented['"]\)/i,
121
+ /^\s*return null;?\s*$/m,
122
+ /^\s*pass\s*$/m, // Python
123
+ /^\s*\.\.\.$/m // TypeScript
124
+ ];
125
+ const isStub = stubPatterns.some(pattern => pattern.test(trimmedContent));
126
+ if (isStub) {
127
+ return {
128
+ path: filePath,
129
+ exists: true,
130
+ hasContent: false,
131
+ lineCount: nonEmptyLines.length,
132
+ reason: 'File contains stub/placeholder code'
133
+ };
134
+ }
135
+ // All checks passed
136
+ return {
137
+ path: filePath,
138
+ exists: true,
139
+ hasContent: true,
140
+ lineCount: nonEmptyLines.length
141
+ };
142
+ }
143
+ /**
144
+ * Extract file paths from task description
145
+ *
146
+ * Supports multiple formats:
147
+ * - **Files**: src/foo.ts, src/bar.ts
148
+ * - **Files to create**: src/foo.ts
149
+ * - **Files to modify**: src/bar.ts
150
+ * - Inline code blocks with file paths
151
+ *
152
+ * @param description - Task description text
153
+ * @returns Array of file paths
154
+ */
155
+ extractFilePaths(description) {
156
+ const paths = new Set();
157
+ // Pattern 1: **Files**: path1, path2, path3
158
+ const filesMatch = description.match(/\*\*Files\*\*:\s*([^\n]+)/i);
159
+ if (filesMatch) {
160
+ const filePaths = filesMatch[1].split(',').map(p => p.trim());
161
+ filePaths.forEach(p => paths.add(p));
162
+ }
163
+ // Pattern 2: **Files to create**: path1, path2
164
+ const createMatch = description.match(/\*\*Files to create\*\*:\s*([^\n]+)/i);
165
+ if (createMatch) {
166
+ const filePaths = createMatch[1].split(',').map(p => p.trim());
167
+ filePaths.forEach(p => paths.add(p));
168
+ }
169
+ // Pattern 3: **Files to modify**: path1, path2
170
+ const modifyMatch = description.match(/\*\*Files to modify\*\*:\s*([^\n]+)/i);
171
+ if (modifyMatch) {
172
+ const filePaths = modifyMatch[1].split(',').map(p => p.trim());
173
+ filePaths.forEach(p => paths.add(p));
174
+ }
175
+ // Pattern 4: Inline file references (e.g., `src/foo/bar.ts`)
176
+ const inlineMatches = description.matchAll(/`([a-zA-Z0-9_\-./]+\.(ts|js|tsx|jsx|py|java|go|rs|cpp|c|h))`/g);
177
+ for (const match of inlineMatches) {
178
+ paths.add(match[1]);
179
+ }
180
+ // Pattern 5: Markdown list items with file paths
181
+ const listMatches = description.matchAll(/^[-*]\s+([a-zA-Z0-9_\-./]+\.(ts|js|tsx|jsx|py|java|go|rs|cpp|c|h))/gm);
182
+ for (const match of listMatches) {
183
+ paths.add(match[1]);
184
+ }
185
+ return Array.from(paths);
186
+ }
187
+ /**
188
+ * Batch validate multiple tasks
189
+ *
190
+ * @param tasks - Array of {taskId, description}
191
+ * @returns Array of validation results
192
+ */
193
+ async validateTasks(tasks) {
194
+ // Use parallel validation for performance
195
+ const validationPromises = tasks.map(task => this.validateTask(task.description, task.taskId));
196
+ return Promise.all(validationPromises);
197
+ }
198
+ /**
199
+ * Get summary of validation results
200
+ *
201
+ * @param results - Array of task validation results
202
+ * @returns Summary statistics
203
+ */
204
+ summarizeResults(results) {
205
+ const total = results.length;
206
+ const valid = results.filter(r => r.valid).length;
207
+ const invalid = results.filter(r => !r.valid).length;
208
+ const noFiles = results.filter(r => r.files.length === 0).length;
209
+ const invalidTasks = results.filter(r => !r.valid).map(r => r.taskId);
210
+ return {
211
+ total,
212
+ valid,
213
+ invalid,
214
+ noFiles,
215
+ invalidTasks
216
+ };
217
+ }
218
+ }
219
+ //# sourceMappingURL=CodeValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeValidator.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/CodeValidator.ts"],"names":[],"mappings":"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"}