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.
- package/CLAUDE.md +367 -0
- package/dist/plugins/specweave/lib/utils/fs-native.d.ts +133 -0
- package/dist/plugins/specweave/lib/utils/fs-native.d.ts.map +1 -0
- package/dist/plugins/specweave/lib/utils/fs-native.js +224 -0
- package/dist/plugins/specweave/lib/utils/fs-native.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.js +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +52 -20
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js +24 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -1
- package/dist/src/cli/helpers/init/initial-increment-generator.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/initial-increment-generator.js +2 -1
- package/dist/src/cli/helpers/init/initial-increment-generator.js.map +1 -1
- package/dist/src/core/ac-test-validator-cli.d.ts +16 -0
- package/dist/src/core/ac-test-validator-cli.d.ts.map +1 -0
- package/dist/src/core/ac-test-validator-cli.js +118 -0
- package/dist/src/core/ac-test-validator-cli.js.map +1 -0
- package/dist/src/core/ac-test-validator.d.ts +111 -0
- package/dist/src/core/ac-test-validator.d.ts.map +1 -0
- package/dist/src/core/ac-test-validator.js +292 -0
- package/dist/src/core/ac-test-validator.js.map +1 -0
- package/dist/src/core/increment/desync-detector.d.ts +142 -0
- package/dist/src/core/increment/desync-detector.d.ts.map +1 -0
- package/dist/src/core/increment/desync-detector.js +270 -0
- package/dist/src/core/increment/desync-detector.js.map +1 -0
- package/dist/src/core/increment/metadata-manager.d.ts +8 -4
- package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +45 -21
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/qa/qa-runner.js +9 -2
- package/dist/src/core/qa/qa-runner.js.map +1 -1
- package/dist/src/sync/sync-coordinator.d.ts +1 -1
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +40 -2
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/utils/fs-native.d.ts +133 -0
- package/dist/src/utils/fs-native.d.ts.map +1 -0
- package/dist/src/utils/fs-native.js +224 -0
- package/dist/src/utils/fs-native.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +12 -0
- package/plugins/specweave/agents/AGENTS-INDEX.md +216 -0
- package/plugins/specweave/agents/architect/AGENT.md +17 -0
- package/plugins/specweave/agents/code-standards-detective/AGENT.md +16 -0
- package/plugins/specweave/agents/docs-writer/AGENT.md +16 -0
- package/plugins/specweave/agents/increment-quality-judge-v2/AGENT.md +704 -0
- package/plugins/specweave/agents/infrastructure/AGENT.md +16 -0
- package/plugins/specweave/agents/performance/AGENT.md +16 -0
- package/plugins/specweave/agents/pm/AGENT.md +17 -0
- package/plugins/specweave/agents/qa-lead/AGENT.md +15 -0
- package/plugins/specweave/agents/reflective-reviewer/AGENT.md +16 -0
- package/plugins/specweave/agents/security/AGENT.md +16 -0
- package/plugins/specweave/agents/tdd-orchestrator/AGENT.md +16 -0
- package/plugins/specweave/agents/tech-lead/AGENT.md +16 -0
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +16 -0
- package/plugins/specweave/agents/translator/AGENT.md +13 -0
- package/plugins/specweave/commands/specweave-done.md +14 -0
- package/plugins/specweave/commands/specweave-qa.md +11 -1
- package/plugins/specweave/commands/specweave-sync-status.md +356 -0
- package/plugins/specweave/commands/specweave-validate.md +10 -1
- package/plugins/specweave/hooks/pre-task-completion.sh +196 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.js +3 -3
- package/plugins/specweave/lib/hooks/git-diff-analyzer.ts +3 -3
- package/plugins/specweave/lib/hooks/invoke-translator-skill.js +3 -2
- package/plugins/specweave/lib/hooks/invoke-translator-skill.ts +3 -2
- package/plugins/specweave/lib/hooks/prepare-reflection-context.js +3 -3
- package/plugins/specweave/lib/hooks/prepare-reflection-context.ts +3 -3
- package/plugins/specweave/lib/hooks/reflection-config-loader.js +4 -4
- package/plugins/specweave/lib/hooks/reflection-config-loader.ts +4 -4
- package/plugins/specweave/lib/hooks/reflection-storage.js +9 -9
- package/plugins/specweave/lib/hooks/reflection-storage.ts +9 -9
- package/plugins/specweave/lib/hooks/sync-cache.js +9 -8
- package/plugins/specweave/lib/hooks/sync-living-docs.js +57 -6
- package/plugins/specweave/lib/hooks/sync-us-tasks.js +6 -6
- package/plugins/specweave/lib/hooks/translate-file.js +3 -2
- package/plugins/specweave/lib/hooks/translate-file.ts +3 -2
- package/plugins/specweave/lib/hooks/translate-living-docs.js +4 -3
- package/plugins/specweave/lib/hooks/translate-living-docs.ts +4 -3
- package/plugins/specweave/lib/hooks/update-tasks-md.js +3 -3
- package/plugins/specweave/lib/hooks/update-tasks-md.ts +3 -3
- package/plugins/specweave/lib/utils/fs-native.js +182 -0
- package/plugins/specweave/lib/utils/fs-native.ts +283 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.d.ts +8 -4
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +45 -21
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -1
- package/plugins/specweave/skills/SKILLS-INDEX.md +26 -2
- package/plugins/specweave/skills/increment-planner/SKILL.md +2 -2
- package/plugins/specweave-ado/commands/specweave-ado-close-workitem.md +1 -1
- package/plugins/specweave-ado/commands/specweave-ado-create-workitem.md +1 -1
- package/plugins/specweave-ado/commands/specweave-ado-status.md +1 -1
- package/plugins/specweave-ado/commands/specweave-ado-sync.md +1 -1
- package/plugins/specweave-diagrams/agents/diagrams-architect/AGENT.md +1 -1
- package/plugins/specweave-diagrams/skills/diagrams-generator/SKILL.md +4 -4
- package/plugins/specweave-github/lib/github-client-v2.js +2 -1
- package/plugins/specweave-github/lib/github-client-v2.ts +1 -1
- package/plugins/specweave-github/lib/github-feature-sync.js +30 -17
- package/plugins/specweave-github/lib/github-feature-sync.ts +54 -24
- package/plugins/specweave-github/lib/user-story-issue-builder.js +24 -0
- package/plugins/specweave-github/lib/user-story-issue-builder.ts +33 -0
- package/plugins/specweave-mobile/README.md +1 -1
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +72 -0
- package/src/templates/CLAUDE.md.template +13 -0
- 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"}
|