specweave 0.23.2 → 0.23.5

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 (106) hide show
  1. package/CLAUDE.md +367 -0
  2. package/dist/plugins/specweave/lib/utils/fs-native.d.ts +133 -0
  3. package/dist/plugins/specweave/lib/utils/fs-native.d.ts.map +1 -0
  4. package/dist/plugins/specweave/lib/utils/fs-native.js +224 -0
  5. package/dist/plugins/specweave/lib/utils/fs-native.js.map +1 -0
  6. package/dist/plugins/specweave-github/lib/github-client-v2.js +1 -1
  7. package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
  8. package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -1
  9. package/dist/plugins/specweave-github/lib/github-feature-sync.js +52 -20
  10. package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
  11. package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts.map +1 -1
  12. package/dist/plugins/specweave-github/lib/user-story-issue-builder.js +24 -0
  13. package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -1
  14. package/dist/src/cli/helpers/init/initial-increment-generator.d.ts.map +1 -1
  15. package/dist/src/cli/helpers/init/initial-increment-generator.js +2 -1
  16. package/dist/src/cli/helpers/init/initial-increment-generator.js.map +1 -1
  17. package/dist/src/core/ac-test-validator-cli.d.ts +16 -0
  18. package/dist/src/core/ac-test-validator-cli.d.ts.map +1 -0
  19. package/dist/src/core/ac-test-validator-cli.js +118 -0
  20. package/dist/src/core/ac-test-validator-cli.js.map +1 -0
  21. package/dist/src/core/ac-test-validator.d.ts +111 -0
  22. package/dist/src/core/ac-test-validator.d.ts.map +1 -0
  23. package/dist/src/core/ac-test-validator.js +292 -0
  24. package/dist/src/core/ac-test-validator.js.map +1 -0
  25. package/dist/src/core/increment/desync-detector.d.ts +142 -0
  26. package/dist/src/core/increment/desync-detector.d.ts.map +1 -0
  27. package/dist/src/core/increment/desync-detector.js +270 -0
  28. package/dist/src/core/increment/desync-detector.js.map +1 -0
  29. package/dist/src/core/increment/metadata-manager.d.ts +8 -4
  30. package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
  31. package/dist/src/core/increment/metadata-manager.js +45 -21
  32. package/dist/src/core/increment/metadata-manager.js.map +1 -1
  33. package/dist/src/core/qa/qa-runner.js +9 -2
  34. package/dist/src/core/qa/qa-runner.js.map +1 -1
  35. package/dist/src/sync/sync-coordinator.d.ts +1 -1
  36. package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
  37. package/dist/src/sync/sync-coordinator.js +40 -2
  38. package/dist/src/sync/sync-coordinator.js.map +1 -1
  39. package/dist/src/utils/fs-native.d.ts +133 -0
  40. package/dist/src/utils/fs-native.d.ts.map +1 -0
  41. package/dist/src/utils/fs-native.js +224 -0
  42. package/dist/src/utils/fs-native.js.map +1 -0
  43. package/package.json +1 -1
  44. package/plugins/specweave/.claude-plugin/plugin.json +12 -0
  45. package/plugins/specweave/agents/AGENTS-INDEX.md +216 -0
  46. package/plugins/specweave/agents/architect/AGENT.md +17 -0
  47. package/plugins/specweave/agents/code-standards-detective/AGENT.md +16 -0
  48. package/plugins/specweave/agents/docs-writer/AGENT.md +16 -0
  49. package/plugins/specweave/agents/increment-quality-judge-v2/AGENT.md +704 -0
  50. package/plugins/specweave/agents/infrastructure/AGENT.md +16 -0
  51. package/plugins/specweave/agents/performance/AGENT.md +16 -0
  52. package/plugins/specweave/agents/pm/AGENT.md +17 -0
  53. package/plugins/specweave/agents/qa-lead/AGENT.md +15 -0
  54. package/plugins/specweave/agents/reflective-reviewer/AGENT.md +16 -0
  55. package/plugins/specweave/agents/security/AGENT.md +16 -0
  56. package/plugins/specweave/agents/tdd-orchestrator/AGENT.md +16 -0
  57. package/plugins/specweave/agents/tech-lead/AGENT.md +16 -0
  58. package/plugins/specweave/agents/test-aware-planner/AGENT.md +16 -0
  59. package/plugins/specweave/agents/translator/AGENT.md +13 -0
  60. package/plugins/specweave/commands/specweave-done.md +14 -0
  61. package/plugins/specweave/commands/specweave-qa.md +11 -1
  62. package/plugins/specweave/commands/specweave-sync-status.md +356 -0
  63. package/plugins/specweave/commands/specweave-validate.md +10 -1
  64. package/plugins/specweave/hooks/pre-task-completion.sh +196 -0
  65. package/plugins/specweave/lib/hooks/git-diff-analyzer.js +3 -3
  66. package/plugins/specweave/lib/hooks/git-diff-analyzer.ts +3 -3
  67. package/plugins/specweave/lib/hooks/invoke-translator-skill.js +3 -2
  68. package/plugins/specweave/lib/hooks/invoke-translator-skill.ts +3 -2
  69. package/plugins/specweave/lib/hooks/prepare-reflection-context.js +3 -3
  70. package/plugins/specweave/lib/hooks/prepare-reflection-context.ts +3 -3
  71. package/plugins/specweave/lib/hooks/reflection-config-loader.js +4 -4
  72. package/plugins/specweave/lib/hooks/reflection-config-loader.ts +4 -4
  73. package/plugins/specweave/lib/hooks/reflection-storage.js +9 -9
  74. package/plugins/specweave/lib/hooks/reflection-storage.ts +9 -9
  75. package/plugins/specweave/lib/hooks/sync-cache.js +9 -8
  76. package/plugins/specweave/lib/hooks/sync-living-docs.js +57 -6
  77. package/plugins/specweave/lib/hooks/sync-us-tasks.js +6 -6
  78. package/plugins/specweave/lib/hooks/translate-file.js +3 -2
  79. package/plugins/specweave/lib/hooks/translate-file.ts +3 -2
  80. package/plugins/specweave/lib/hooks/translate-living-docs.js +4 -3
  81. package/plugins/specweave/lib/hooks/translate-living-docs.ts +4 -3
  82. package/plugins/specweave/lib/hooks/update-tasks-md.js +3 -3
  83. package/plugins/specweave/lib/hooks/update-tasks-md.ts +3 -3
  84. package/plugins/specweave/lib/utils/fs-native.js +182 -0
  85. package/plugins/specweave/lib/utils/fs-native.ts +283 -0
  86. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.d.ts +8 -4
  87. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +45 -21
  88. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -1
  89. package/plugins/specweave/skills/SKILLS-INDEX.md +26 -2
  90. package/plugins/specweave/skills/increment-planner/SKILL.md +2 -2
  91. package/plugins/specweave-ado/commands/specweave-ado-close-workitem.md +1 -1
  92. package/plugins/specweave-ado/commands/specweave-ado-create-workitem.md +1 -1
  93. package/plugins/specweave-ado/commands/specweave-ado-status.md +1 -1
  94. package/plugins/specweave-ado/commands/specweave-ado-sync.md +1 -1
  95. package/plugins/specweave-diagrams/agents/diagrams-architect/AGENT.md +1 -1
  96. package/plugins/specweave-diagrams/skills/diagrams-generator/SKILL.md +4 -4
  97. package/plugins/specweave-github/lib/github-client-v2.js +2 -1
  98. package/plugins/specweave-github/lib/github-client-v2.ts +1 -1
  99. package/plugins/specweave-github/lib/github-feature-sync.js +30 -17
  100. package/plugins/specweave-github/lib/github-feature-sync.ts +54 -24
  101. package/plugins/specweave-github/lib/user-story-issue-builder.js +24 -0
  102. package/plugins/specweave-github/lib/user-story-issue-builder.ts +33 -0
  103. package/plugins/specweave-mobile/README.md +1 -1
  104. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +72 -0
  105. package/src/templates/CLAUDE.md.template +13 -0
  106. package/plugins/specweave/skills/task-builder/README.md +0 -84
package/CLAUDE.md CHANGED
@@ -10,6 +10,37 @@ For **contributors to SpecWeave itself** (not users).
10
10
 
11
11
  ## 🚨 CRITICAL SAFETY RULES
12
12
 
13
+ ### 0. Thinking-Before-Acting Discipline (META RULE!)
14
+
15
+ **ALWAYS act on your reasoning BEFORE attempting operations that will fail.**
16
+
17
+ **Anti-pattern**: Running commands you know will fail, then fixing the issue.
18
+
19
+ ```typescript
20
+ // ❌ WRONG: Attempt → Predictable failure → Fix
21
+ node -e "require('./dist/file.js')" // Fails (you saw this coming!)
22
+ npm run rebuild // Then fix
23
+
24
+ // ✅ CORRECT: Recognize dependency → Fix → Attempt
25
+ npm run rebuild // Fix first
26
+ node -e "require('./dist/file.js')" // Then succeed
27
+ ```
28
+
29
+ **Why**: Wastes time, creates confusion, makes execution harder to follow.
30
+
31
+ **How to avoid**:
32
+ 1. **Read your own thinking process** - What dependencies did you identify?
33
+ 2. **Order operations logically** - Prerequisites BEFORE dependent operations
34
+ 3. **Catch predictable failures** - If you know it will fail, don't run it yet
35
+
36
+ **Example patterns to watch for**:
37
+ - Running code before compilation (`tsc`, `npm run build`)
38
+ - Database queries before migrations/setup
39
+ - API calls before authentication
40
+ - File operations before directory creation
41
+
42
+ ---
43
+
13
44
  ### 1. Local Development Setup
14
45
 
15
46
  **SpecWeave uses Claude Code's GitHub marketplace** for plugin management. This is the **cross-platform, simple approach** that works on macOS, Linux, and Windows.
@@ -314,6 +345,90 @@ npx tsx src/core/status-line-validator.ts
314
345
 
315
346
  **Incident Reference**: 2025-11-20 - Status line showed 21/52 tasks when actually 26/52 were complete (10% desync). Root cause: Tasks marked complete without using TodoWrite, so hooks never fired. Added validation layer and tests to prevent future occurrences.
316
347
 
348
+ ### 7b. GitHub Duplicate Prevention (CRITICAL!)
349
+
350
+ **CRITICAL**: External tool items (GitHub issues, JIRA tickets, ADO work items) MUST NEVER be duplicated.
351
+
352
+ **Rule**: ALWAYS use DuplicateDetector for GitHub issue creation.
353
+
354
+ **Why This Matters**:
355
+ - GitHub search has eventual consistency (2-5 second lag)
356
+ - Race conditions can create duplicates if sync runs multiple times quickly
357
+ - Manual search with `--limit 1` hides duplicates
358
+
359
+ **The ONLY Way to Create GitHub Issues**:
360
+ ```typescript
361
+ import { DuplicateDetector } from './duplicate-detector.js';
362
+
363
+ // ✅ CORRECT: Use DuplicateDetector.createWithProtection()
364
+ const titlePattern = `[${featureId}][${userStory.id}]`; // e.g., "[FS-047][US-001]"
365
+ const result = await DuplicateDetector.createWithProtection({
366
+ title: issueContent.title,
367
+ body: issueContent.body,
368
+ titlePattern,
369
+ labels: issueContent.labels,
370
+ milestone: milestoneTitle,
371
+ repo: `${owner}/${repo}`
372
+ });
373
+
374
+ // Provides automatic:
375
+ // ✅ Phase 1 (Detection): Search for existing before create
376
+ // ✅ Phase 2 (Verification): Count-check after creation
377
+ // ✅ Phase 3 (Reflection): Auto-close duplicates, keep oldest
378
+
379
+ // ❌ WRONG: Manual gh issue create (no duplicate protection!)
380
+ execSync('gh issue create --title "..." --body "..."');
381
+ ```
382
+
383
+ **3-Phase Protection**:
384
+ 1. **Detection** - Search GitHub for existing issues BEFORE creating
385
+ 2. **Verification** - Count-check AFTER creation (handles eventual consistency)
386
+ 3. **Reflection** - Auto-close duplicates if detected, keep oldest
387
+
388
+ **Search Limits** (CRITICAL!):
389
+ ```typescript
390
+ // ❌ WRONG: --limit 1 hides duplicates!
391
+ gh issue list --search "[FS-047][US-001] in:title" --limit 1
392
+ // Returns ONLY 1 result even if 10 duplicates exist!
393
+
394
+ // ✅ CORRECT: --limit 50 detects duplicates
395
+ gh issue list --search "[FS-047][US-001] in:title" --limit 50
396
+ // Returns up to 50 results, enabling duplicate detection
397
+ ```
398
+
399
+ **Cleanup Existing Duplicates**:
400
+ ```bash
401
+ # Preview what will be cleaned up:
402
+ bash scripts/cleanup-duplicate-github-issues.sh --dry-run
403
+
404
+ # Actually close duplicates (keeps oldest):
405
+ bash scripts/cleanup-duplicate-github-issues.sh
406
+ ```
407
+
408
+ **Validation**:
409
+ ```bash
410
+ # Check for duplicates:
411
+ gh issue list --json title,createdAt --limit 100 | \
412
+ jq -r '.[] | .title' | sort | uniq -d
413
+
414
+ # If output is empty → No duplicates! ✅
415
+ # If output shows titles → Duplicates exist, investigate!
416
+ ```
417
+
418
+ **Why This Matters**:
419
+ - Incident 2025-11-20: 10+ duplicate User Story issues created
420
+ - Root Cause #1: Race condition (GitHub search eventual consistency lag)
421
+ - Root Cause #2: `--limit 1` bug (hid duplicates in search results)
422
+ - Root Cause #3: No post-create verification
423
+ - **Fix**: DuplicateDetector integration (github-feature-sync.ts:149-227)
424
+
425
+ **Protected Files**:
426
+ - `plugins/specweave-github/lib/github-feature-sync.ts` - Uses DuplicateDetector
427
+ - `plugins/specweave-github/lib/duplicate-detector.ts` - 3-phase protection
428
+ - `plugins/specweave-github/lib/github-client-v2.ts` - Fixed --limit 50
429
+
430
+ **Incident Reference**: 2025-11-20 - Duplicate GitHub issues for User Stories ([SP-US-006], [SP-US-007], etc.). Root cause: Race conditions + --limit 1 bug + missing DuplicateDetector integration. Fixed by implementing 3-phase protection. See `.specweave/increments/0047-us-task-linkage/reports/DUPLICATE-GITHUB-ISSUES-ROOT-CAUSE.md`.
431
+
317
432
  ### 8. NEVER Use `console.*` in Production Code
318
433
 
319
434
  **Rule**: ALL `src/` code MUST use logger abstraction, NEVER `console.log/error/warn`.
@@ -378,6 +493,74 @@ export async function myCommand(options: CommandOptions = {}) {
378
493
  - Pre-commit hook: `scripts/pre-commit-console-check.sh`
379
494
  - See: `.specweave/increments/0046-console-elimination/` for migration pattern
380
495
 
496
+ ### 8a. NEVER Use `fs-extra` (Native fs Migration)
497
+
498
+ **Rule**: ALL code MUST use native Node.js `fs` module, NEVER `fs-extra`.
499
+
500
+ **Why**: `fs-extra` causes hook failures when not installed. Native fs is faster, smaller, and always available.
501
+
502
+ **Migration completed**: 2025-11-20 - All hooks converted to native fs
503
+
504
+ **Correct usage**:
505
+ ```typescript
506
+ // ✅ CORRECT - Native fs (sync operations)
507
+ import { existsSync, readFileSync, statSync } from 'fs';
508
+
509
+ if (existsSync(configPath)) {
510
+ const content = readFileSync(configPath, 'utf-8');
511
+ const stats = statSync(configPath);
512
+ }
513
+ ```
514
+
515
+ ```typescript
516
+ // ✅ CORRECT - Native fs (async operations)
517
+ import { promises as fs } from 'fs';
518
+
519
+ const content = await fs.readFile(configPath, 'utf-8');
520
+ await fs.mkdir(dir, { recursive: true });
521
+ await fs.writeFile(filePath, content, 'utf-8');
522
+ ```
523
+
524
+ ```typescript
525
+ // ✅ CORRECT - Custom utilities (from utils/fs-native.js)
526
+ import { mkdirpSync, writeJsonSync, readJsonSync } from '../utils/fs-native.js';
527
+
528
+ mkdirpSync(dir); // Create directory recursively
529
+ writeJsonSync(path, data); // Write JSON file
530
+ const config = readJsonSync(configPath); // Read JSON file
531
+ ```
532
+
533
+ **Migration guide (fs-extra → native fs)**:
534
+ ```typescript
535
+ // ❌ WRONG (fs-extra)
536
+ import fs from 'fs-extra';
537
+
538
+ fs.existsSync(path); → existsSync(path)
539
+ fs.readFileSync(path, 'utf-8'); → readFileSync(path, 'utf-8')
540
+ fs.statSync(path); → statSync(path)
541
+ await fs.readFile(path, 'utf-8'); → await fs.readFile(path, 'utf-8')
542
+ await fs.ensureDir(dir); → await fs.mkdir(dir, { recursive: true })
543
+ OR mkdirpSync(dir) for sync
544
+ await fs.writeFile(path, content); → await fs.writeFile(path, content, 'utf-8')
545
+ fs.removeSync(path); → removeSync(path) from fs-native.js
546
+ await fs.copy(src, dest); → await fs.cp(src, dest, { recursive: true })
547
+ ```
548
+
549
+ **Prevention**:
550
+ 1. **Pre-commit hook**: `scripts/pre-commit-fs-extra-check.sh` blocks fs-extra imports
551
+ 2. **Installation**: Hook installed automatically via `bash scripts/install-git-hooks.sh`
552
+ 3. **Legacy marker**: Add `// legacy fs-extra` comment to bypass check (temporary only)
553
+
554
+ **Testing**:
555
+ ```bash
556
+ # Verify no fs-extra in hooks
557
+ grep -r "from 'fs-extra'" plugins/*/lib/hooks/*.js
558
+
559
+ # Should return nothing (empty output)
560
+ ```
561
+
562
+ **Incident Reference**: 2025-11-20 - Hook failures due to fs-extra dependency. All hooks converted to native fs. Pre-commit hook added to prevent regression.
563
+
381
564
  ### 9. Coding Standards
382
565
 
383
566
  **Full standards**: `.specweave/docs/internal/governance/coding-standards.md`
@@ -762,6 +945,190 @@ bash scripts/validate-marketplace-plugins.sh
762
945
  - Validation script: `scripts/validate-marketplace-plugins.sh`
763
946
  - Fix script: `bin/fix-marketplace-errors.sh`
764
947
 
948
+ ### 15. Skills vs Agents: Understanding the Distinction (CRITICAL!)
949
+
950
+ **NEVER confuse skills with agents** - They are different components with different invocation methods.
951
+
952
+ **The Problem**:
953
+ Empty agent directories cause "Agent type not found" errors when someone tries to invoke them. This happened with `specweave:increment-quality-judge-v2` which existed as a skill but had an empty agent directory.
954
+
955
+ **Key Differences**:
956
+
957
+ | Aspect | Skills | Agents |
958
+ |--------|--------|--------|
959
+ | **Location** | `plugins/*/skills/name/SKILL.md` | `plugins/*/agents/name/AGENT.md` |
960
+ | **Invocation** | Skill tool or slash commands | Task tool with `subagent_type` |
961
+ | **Activation** | Automatic (based on keywords) | Explicit (you call them) |
962
+ | **Required File** | `SKILL.md` with YAML frontmatter | `AGENT.md` or agent config |
963
+ | **Purpose** | Expand context with knowledge | Execute multi-step tasks |
964
+
965
+ **Correct Invocation Examples**:
966
+
967
+ ```typescript
968
+ // ✅ CORRECT: Invoking a skill
969
+ Skill({ skill: "increment-quality-judge-v2" });
970
+ // OR use slash command:
971
+ /specweave:qa 0047
972
+
973
+ // ✅ CORRECT: Invoking an agent
974
+ Task({
975
+ subagent_type: "specweave:qa-lead:qa-lead",
976
+ prompt: "Create test plan for increment 0047"
977
+ });
978
+
979
+ // ❌ WRONG: Trying to invoke skill as agent
980
+ Task({
981
+ subagent_type: "specweave:increment-quality-judge-v2", // ERROR!
982
+ prompt: "Quality assessment"
983
+ });
984
+ ```
985
+
986
+ **Agent Naming Convention** (CRITICAL!):
987
+
988
+ Claude Code agents follow a strict naming pattern for `subagent_type`:
989
+
990
+ **Directory-based agents**: `{plugin-name}:{directory-name}:{name-from-yaml}`
991
+
992
+ Examples:
993
+ - Agent at `plugins/specweave/agents/qa-lead/AGENT.md` with `name: qa-lead`
994
+ → Invoke as: `specweave:qa-lead:qa-lead`
995
+ - Agent at `plugins/specweave/agents/pm/AGENT.md` with `name: pm`
996
+ → Invoke as: `specweave:pm:pm`
997
+ - Agent at `plugins/specweave/agents/architect/AGENT.md` with `name: architect`
998
+ → Invoke as: `specweave:architect:architect`
999
+
1000
+ **Why the "duplication"?**
1001
+ The pattern is `{plugin}:{directory}:{yaml-name}`. When the directory name matches the YAML `name` field (best practice), it creates the appearance of duplication: `qa-lead:qa-lead`.
1002
+
1003
+ **File-based agents** (legacy pattern):
1004
+ - Agent at `plugins/specweave/agents/code-reviewer.md`
1005
+ → Invoke as: `specweave:code-reviewer` (no duplication)
1006
+
1007
+ **How to find the correct agent type**:
1008
+ ```bash
1009
+ # List all available agents
1010
+ ls -la plugins/specweave/agents/
1011
+
1012
+ # Check YAML name field
1013
+ head -5 plugins/specweave/agents/qa-lead/AGENT.md
1014
+ # Output: name: qa-lead
1015
+
1016
+ # Construct agent type: specweave:qa-lead:qa-lead
1017
+ ```
1018
+
1019
+ **Common Mistakes**:
1020
+ ```typescript
1021
+ // ❌ WRONG: Missing the directory/name duplication
1022
+ Task({ subagent_type: "specweave:qa-lead", ... });
1023
+ // Error: Agent type 'specweave:qa-lead' not found
1024
+
1025
+ // ✅ CORRECT: Full pattern with duplication
1026
+ Task({ subagent_type: "specweave:qa-lead:qa-lead", ... });
1027
+ ```
1028
+
1029
+ **Directory Structure Requirements**:
1030
+
1031
+ ```bash
1032
+ # ✅ CORRECT: Skill with SKILL.md
1033
+ plugins/specweave/skills/increment-quality-judge-v2/
1034
+ └── SKILL.md (with YAML frontmatter)
1035
+
1036
+ # ✅ CORRECT: Agent with AGENT.md
1037
+ plugins/specweave/agents/qa-lead/
1038
+ └── AGENT.md
1039
+
1040
+ # ❌ WRONG: Empty agent directory
1041
+ plugins/specweave/agents/increment-quality-judge-v2/
1042
+ (empty - no AGENT.md!)
1043
+
1044
+ # ❌ WRONG: Skill missing SKILL.md
1045
+ plugins/specweave/skills/my-skill/
1046
+ └── some-file.txt (not SKILL.md!)
1047
+ ```
1048
+
1049
+ **SKILL.md Format** (MANDATORY):
1050
+ ```yaml
1051
+ ---
1052
+ name: skill-name
1053
+ description: What it does AND trigger keywords. Include all variations.
1054
+ ---
1055
+
1056
+ # Skill Content
1057
+
1058
+ Your skill documentation here...
1059
+ ```
1060
+
1061
+ **Validation** (MANDATORY before commits):
1062
+
1063
+ ```bash
1064
+ # Check for empty/invalid directories
1065
+ bash scripts/validate-plugin-directories.sh
1066
+
1067
+ # Auto-fix empty directories
1068
+ bash scripts/validate-plugin-directories.sh --fix
1069
+
1070
+ # This catches:
1071
+ # - Empty agent/skill directories
1072
+ # - Missing SKILL.md files
1073
+ # - Missing YAML frontmatter
1074
+ # - Invalid plugin structures
1075
+ ```
1076
+
1077
+ **Common Mistakes**:
1078
+
1079
+ 1. **Creating empty agent directories during scaffolding**
1080
+ ```bash
1081
+ # ❌ WRONG
1082
+ mkdir -p plugins/specweave/agents/new-agent
1083
+ git add . && git commit # Empty directory!
1084
+
1085
+ # ✅ CORRECT
1086
+ mkdir -p plugins/specweave/agents/new-agent
1087
+ echo "---" > plugins/specweave/agents/new-agent/AGENT.md
1088
+ # ... add agent content ...
1089
+ git add . && git commit
1090
+ ```
1091
+
1092
+ 2. **Copying skill as agent without changing structure**
1093
+ - Skills need `SKILL.md` with YAML
1094
+ - Agents need `AGENT.md` or config
1095
+ - Don't copy-paste between them!
1096
+
1097
+ 3. **Using wrong invocation method**
1098
+ - Check available skills: Skills list in context
1099
+ - Check available agents: Error message shows all agents
1100
+ - Skills → Skill tool or slash commands
1101
+ - Agents → Task tool
1102
+
1103
+ **When to Use Skills vs Agents**:
1104
+
1105
+ **Use Skills when**:
1106
+ - Providing domain knowledge (e.g., Kafka best practices)
1107
+ - Expanding Claude's context with project-specific info
1108
+ - Explaining concepts, patterns, frameworks
1109
+ - Want automatic activation based on keywords
1110
+
1111
+ **Use Agents when**:
1112
+ - Need multi-step task execution (e.g., generate docs)
1113
+ - Require specialized sub-agent capabilities
1114
+ - Building complex workflows with tools
1115
+ - Want explicit control over when they run
1116
+
1117
+ **Incident History**:
1118
+ - **2025-11-20**: `specweave:increment-quality-judge-v2` agent invocation failed because only skill existed. Empty agent directory caused "Agent type not found" error. Fixed by removing empty directory and documenting distinction.
1119
+
1120
+ **Prevention**:
1121
+ 1. Run `bash scripts/validate-plugin-directories.sh` before commits
1122
+ 2. Never create empty agent/skill directories
1123
+ 3. Always include required files (SKILL.md, AGENT.md)
1124
+ 4. Test invocation method matches component type
1125
+ 5. Use pre-commit hook (blocks invalid structures)
1126
+
1127
+ **See Also**:
1128
+ - Validation script: `scripts/validate-plugin-directories.sh`
1129
+ - Skills index: `plugins/specweave/skills/SKILLS-INDEX.md`
1130
+ - Claude Code Skills docs: `~/CLAUDE.md` (Personal skills reference)
1131
+
765
1132
  ---
766
1133
 
767
1134
  ## Project Structure
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Native Node.js fs API Helpers
3
+ *
4
+ * Drop-in replacements for fs-extra methods using only Node.js stdlib.
5
+ * All methods use native Node.js 20+ APIs with no external dependencies.
6
+ *
7
+ * Migration from fs-extra:
8
+ * - import fs from 'fs-extra' → import * as fs from './utils/fs-native.js'
9
+ * - All fs-extra methods work as drop-in replacements
10
+ *
11
+ * Benefits:
12
+ * - Zero bundle overhead (no npm packages)
13
+ * - Works in marketplace (no node_modules needed)
14
+ * - Faster startup (native APIs)
15
+ * - Better debugging (native stack traces)
16
+ */
17
+ import { promises as fsPromises, existsSync, mkdirSync, readFileSync, writeFileSync, statSync, readdirSync, rmSync, unlinkSync } from 'fs';
18
+ /**
19
+ * Ensures that a directory exists. If the directory does not exist, it is created.
20
+ * @param dirPath - The directory path to ensure
21
+ */
22
+ export declare function ensureDir(dirPath: string): Promise<void>;
23
+ /**
24
+ * Synchronous version of ensureDir
25
+ */
26
+ export declare function ensureDirSync(dirPath: string): void;
27
+ /**
28
+ * Alias for ensureDirSync (fs-extra compatibility)
29
+ */
30
+ export declare function mkdirpSync(dirPath: string): void;
31
+ /**
32
+ * Check if a path exists
33
+ * @param filePath - The path to check
34
+ */
35
+ export declare function pathExists(filePath: string): Promise<boolean>;
36
+ /**
37
+ * Synchronous version of pathExists
38
+ */
39
+ export { existsSync };
40
+ /**
41
+ * Read a JSON file and parse it
42
+ * @param filePath - The JSON file path
43
+ */
44
+ export declare function readJson(filePath: string): Promise<any>;
45
+ /**
46
+ * Synchronous version of readJson
47
+ */
48
+ export declare function readJsonSync(filePath: string): any;
49
+ /**
50
+ * Write a JSON file with formatting
51
+ * @param filePath - The JSON file path
52
+ * @param data - The data to write
53
+ * @param options - Options (spaces for indentation)
54
+ */
55
+ export declare function writeJson(filePath: string, data: any, options?: {
56
+ spaces?: number;
57
+ }): Promise<void>;
58
+ /**
59
+ * Synchronous version of writeJson
60
+ */
61
+ export declare function writeJsonSync(filePath: string, data: any, options?: {
62
+ spaces?: number;
63
+ }): void;
64
+ /**
65
+ * Remove a file or directory (recursively)
66
+ * @param targetPath - The path to remove
67
+ */
68
+ export declare function remove(targetPath: string): Promise<void>;
69
+ /**
70
+ * Synchronous version of remove
71
+ */
72
+ export declare function removeSync(targetPath: string): void;
73
+ /**
74
+ * Copy a file or directory
75
+ * @param src - Source path
76
+ * @param dest - Destination path
77
+ * @param options - Copy options
78
+ */
79
+ export declare function copy(src: string, dest: string, options?: {
80
+ overwrite?: boolean;
81
+ filter?: (src: string) => boolean;
82
+ }): Promise<void>;
83
+ /**
84
+ * Synchronous version of copy
85
+ */
86
+ export declare function copySync(src: string, dest: string, options?: {
87
+ overwrite?: boolean;
88
+ filter?: (src: string) => boolean;
89
+ }): void;
90
+ /**
91
+ * Ensure a file exists (create if it doesn't)
92
+ * @param filePath - The file path
93
+ */
94
+ export declare function ensureFile(filePath: string): Promise<void>;
95
+ /**
96
+ * Synchronous version of ensureFile
97
+ */
98
+ export declare function ensureFileSync(filePath: string): void;
99
+ export declare const readFile: typeof fsPromises.readFile, writeFile: typeof fsPromises.writeFile, appendFile: typeof fsPromises.appendFile, stat: typeof fsPromises.stat, readdir: typeof fsPromises.readdir, access: typeof fsPromises.access, unlink: typeof fsPromises.unlink, rmdir: typeof fsPromises.rmdir, rename: typeof fsPromises.rename, chmod: typeof fsPromises.chmod;
100
+ export { readFileSync, writeFileSync, statSync, readdirSync, unlinkSync, mkdirSync, rmSync, };
101
+ declare const _default: {
102
+ ensureDir: typeof ensureDir;
103
+ pathExists: typeof pathExists;
104
+ readJson: typeof readJson;
105
+ writeJson: typeof writeJson;
106
+ remove: typeof remove;
107
+ copy: typeof copy;
108
+ ensureFile: typeof ensureFile;
109
+ readFile: typeof fsPromises.readFile;
110
+ writeFile: typeof fsPromises.writeFile;
111
+ appendFile: typeof fsPromises.appendFile;
112
+ stat: typeof fsPromises.stat;
113
+ readdir: typeof fsPromises.readdir;
114
+ access: typeof fsPromises.access;
115
+ unlink: typeof fsPromises.unlink;
116
+ ensureDirSync: typeof ensureDirSync;
117
+ mkdirpSync: typeof mkdirpSync;
118
+ existsSync: typeof existsSync;
119
+ readJsonSync: typeof readJsonSync;
120
+ writeJsonSync: typeof writeJsonSync;
121
+ removeSync: typeof removeSync;
122
+ copySync: typeof copySync;
123
+ ensureFileSync: typeof ensureFileSync;
124
+ readFileSync: typeof readFileSync;
125
+ writeFileSync: typeof writeFileSync;
126
+ statSync: import("fs").StatSyncFn;
127
+ readdirSync: typeof readdirSync;
128
+ unlinkSync: typeof unlinkSync;
129
+ mkdirSync: typeof mkdirSync;
130
+ rmSync: typeof rmSync;
131
+ };
132
+ export default _default;
133
+ //# sourceMappingURL=fs-native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-native.d.ts","sourceRoot":"","sources":["../../../../../plugins/specweave/lib/utils/fs-native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAgB,MAAM,IAAI,CAAC;AAIzJ;;;GAGG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAInD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnE;AAED;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAG7D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAGlD;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,EACT,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,EACT,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5B,IAAI,CAIN;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAInD;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GACnE,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GACnE,IAAI,CA4BN;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKrD;AAGD,eAAO,MACL,QAAQ,8BACR,SAAS,+BACT,UAAU,gCACV,IAAI,0BACJ,OAAO,6BACP,MAAM,4BACN,MAAM,4BACN,KAAK,2BACL,MAAM,4BACN,KAAK,yBACO,CAAC;AAGf,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,WAAW,EACX,UAAU,EACV,SAAS,EACT,MAAM,GACP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGF,wBAiCE"}