specweave 0.23.1 → 0.23.2

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.
@@ -73,28 +73,6 @@
73
73
  "email": "anton.abyzov@gmail.com"
74
74
  }
75
75
  },
76
- {
77
- "name": "specweave-figma",
78
- "description": "Figma design system - MCP integration, design tokens, code generation",
79
- "source": "./plugins/specweave-figma",
80
- "category": "development",
81
- "version": "1.0.0",
82
- "author": {
83
- "name": "Anton Abyzov",
84
- "email": "anton.abyzov@gmail.com"
85
- }
86
- },
87
- {
88
- "name": "specweave-frontend",
89
- "description": "Frontend development - React, Vue, Angular, Next.js, design systems",
90
- "source": "./plugins/specweave-frontend",
91
- "category": "development",
92
- "version": "1.0.0",
93
- "author": {
94
- "name": "Anton Abyzov",
95
- "email": "anton.abyzov@gmail.com"
96
- }
97
- },
98
76
  {
99
77
  "name": "specweave-backend",
100
78
  "description": "Backend development - Node.js, Python, .NET, REST APIs",
@@ -128,28 +106,6 @@
128
106
  "email": "anton.abyzov@gmail.com"
129
107
  }
130
108
  },
131
- {
132
- "name": "specweave-testing",
133
- "description": "Test execution infrastructure - Playwright E2E, browser automation, visual regression",
134
- "source": "./plugins/specweave-testing",
135
- "category": "development",
136
- "version": "1.0.0",
137
- "author": {
138
- "name": "Anton Abyzov",
139
- "email": "anton.abyzov@gmail.com"
140
- }
141
- },
142
- {
143
- "name": "specweave-docs",
144
- "description": "Documentation - Docusaurus generation, spec-driven workflows",
145
- "source": "./plugins/specweave-docs",
146
- "category": "productivity",
147
- "version": "1.0.0",
148
- "author": {
149
- "name": "Anton Abyzov",
150
- "email": "anton.abyzov@gmail.com"
151
- }
152
- },
153
109
  {
154
110
  "name": "specweave-docs-preview",
155
111
  "description": "Interactive documentation preview - Launch Docusaurus dev server with hot reload, auto-generated sidebar, Mermaid diagrams. Build static sites for deployment.",
@@ -161,50 +117,6 @@
161
117
  "email": "anton.abyzov@gmail.com"
162
118
  }
163
119
  },
164
- {
165
- "name": "specweave-tooling",
166
- "description": "SpecWeave tooling - skill creation, skill routing",
167
- "source": "./plugins/specweave-tooling",
168
- "category": "development",
169
- "version": "1.0.0",
170
- "author": {
171
- "name": "Anton Abyzov",
172
- "email": "anton.abyzov@gmail.com"
173
- }
174
- },
175
- {
176
- "name": "specweave-alternatives",
177
- "description": "Framework alternative experts - Compare SpecWeave with BMAD, spec-kit, openspec. Gap analysis and recommendations.",
178
- "source": "./plugins/specweave-alternatives",
179
- "category": "learning",
180
- "version": "1.0.0",
181
- "author": {
182
- "name": "Anton Abyzov",
183
- "email": "anton.abyzov@gmail.com"
184
- }
185
- },
186
- {
187
- "name": "specweave-ui",
188
- "description": "UI components and design systems - Reusable component libraries",
189
- "source": "./plugins/specweave-ui",
190
- "category": "development",
191
- "version": "1.0.0",
192
- "author": {
193
- "name": "Anton Abyzov",
194
- "email": "anton.abyzov@gmail.com"
195
- }
196
- },
197
- {
198
- "name": "specweave-cost-optimizer",
199
- "description": "Cost optimization - cloud platform comparison, cost breakdown",
200
- "source": "./plugins/specweave-cost-optimizer",
201
- "category": "productivity",
202
- "version": "1.0.0",
203
- "author": {
204
- "name": "Anton Abyzov",
205
- "email": "anton.abyzov@gmail.com"
206
- }
207
- },
208
120
  {
209
121
  "name": "specweave-diagrams",
210
122
  "description": "Architecture diagrams - Mermaid, C4 Model, sequence, ER diagrams",
package/CLAUDE.md CHANGED
@@ -662,6 +662,106 @@ const isArchived = archivedList.some(item => item === searchId);
662
662
 
663
663
  **See Also**: `.specweave/increments/0047-us-task-linkage/reports/CRITICAL-ARCHIVING-BUGS-FIX.md`
664
664
 
665
+ ### 14. Marketplace Plugin Completeness (CRITICAL!)
666
+
667
+ **NEVER add incomplete plugins to `.claude-plugin/marketplace.json`**
668
+
669
+ **Rule**: ONLY plugins with complete implementation (agents/, commands/, or lib/) may be listed in marketplace.json.
670
+
671
+ **Why This Matters**:
672
+ When users install `npm i -g specweave`, Claude Code loads ALL plugins listed in marketplace.json. Incomplete plugins (skeleton-only with just skills/) cause loading errors that confuse users and damage the framework's reputation.
673
+
674
+ **Incomplete Plugin Definition**:
675
+ A plugin is considered INCOMPLETE if it ONLY has:
676
+ - `.claude-plugin/` directory
677
+ - `skills/` directory
678
+
679
+ A plugin is COMPLETE if it has ANY of:
680
+ - `agents/` directory (specialized Claude Code agents)
681
+ - `commands/` directory (slash commands)
682
+ - `lib/` directory (shared utilities, TypeScript implementations)
683
+
684
+ **Validation Process** (MANDATORY before ANY marketplace.json changes):
685
+
686
+ ```bash
687
+ # 1. Run validation script
688
+ bash scripts/validate-marketplace-plugins.sh
689
+
690
+ # Expected output: "✅ VALIDATION PASSED!"
691
+ # If FAILED: Remove incomplete plugins from marketplace.json
692
+ ```
693
+
694
+ **Examples**:
695
+
696
+ ```bash
697
+ # ✅ COMPLETE plugins (may be listed in marketplace.json):
698
+ plugins/specweave-github/
699
+ ├── .claude-plugin/
700
+ ├── agents/ ← Has agents
701
+ ├── commands/ ← Has commands
702
+ ├── lib/ ← Has lib
703
+ └── skills/
704
+
705
+ plugins/specweave-kafka/
706
+ ├── .claude-plugin/
707
+ ├── agents/ ← Has agents
708
+ ├── lib/ ← Has lib
709
+ └── skills/
710
+
711
+ # ✗ INCOMPLETE plugins (MUST NOT be listed in marketplace.json):
712
+ plugins/specweave-cost-optimizer/
713
+ ├── .claude-plugin/
714
+ └── skills/ ← ONLY skills!
715
+
716
+ plugins/specweave-figma/
717
+ ├── .claude-plugin/
718
+ └── skills/ ← ONLY skills!
719
+ ```
720
+
721
+ **Adding New Plugins**:
722
+
723
+ ```bash
724
+ # 1. Create plugin with COMPLETE structure
725
+ mkdir -p plugins/specweave-newplugin/{.claude-plugin,agents,skills}
726
+
727
+ # 2. Implement at least ONE of: agents/, commands/, or lib/
728
+ # (Don't just create empty directories!)
729
+
730
+ # 3. Add to marketplace.json
731
+ vim .claude-plugin/marketplace.json
732
+
733
+ # 4. VALIDATE (this is CRITICAL!)
734
+ bash scripts/validate-marketplace-plugins.sh
735
+
736
+ # 5. Update bin/fix-marketplace-errors.sh
737
+ vim bin/fix-marketplace-errors.sh
738
+ # Add "specweave-newplugin" to plugins=(...) array
739
+
740
+ # 6. Commit
741
+ git add .claude-plugin/marketplace.json bin/fix-marketplace-errors.sh
742
+ git commit -m "feat: add specweave-newplugin to marketplace"
743
+ ```
744
+
745
+ **Pre-Commit Hook** (TODO - add this):
746
+ ```bash
747
+ # .git/hooks/pre-commit should run:
748
+ bash scripts/validate-marketplace-plugins.sh
749
+ # Block commit if validation fails
750
+ ```
751
+
752
+ **Incident History**:
753
+ - **2025-11-20**: Global npm install caused 8 incomplete plugins to fail loading, generating confusing errors for users. Root cause: marketplace.json listed skeleton plugins that weren't ready for distribution.
754
+
755
+ **Prevention**:
756
+ 1. Run `bash scripts/validate-marketplace-plugins.sh` before EVERY marketplace.json change
757
+ 2. NEVER add plugins to marketplace.json until they have agents/, commands/, or lib/
758
+ 3. Update bin/fix-marketplace-errors.sh whenever marketplace.json changes
759
+ 4. Test global npm install (`npm pack && npm i -g ./specweave-*.tgz`) before releases
760
+
761
+ **See Also**:
762
+ - Validation script: `scripts/validate-marketplace-plugins.sh`
763
+ - Fix script: `bin/fix-marketplace-errors.sh`
764
+
665
765
  ---
666
766
 
667
767
  ## Project Structure
@@ -63,6 +63,8 @@ else
63
63
  fi
64
64
 
65
65
  print_info "Step 6: Installing SpecWeave plugins..."
66
+ # IMPORTANT: Only list COMPLETE plugins (those with agents/, commands/, or lib/)
67
+ # NEVER add plugins that only have skills/ directory - they will fail to load!
66
68
  plugins=(
67
69
  "specweave"
68
70
  "specweave-github"
@@ -70,19 +72,17 @@ plugins=(
70
72
  "specweave-ado"
71
73
  "specweave-kubernetes"
72
74
  "specweave-infrastructure"
73
- "specweave-figma"
74
- "specweave-frontend"
75
75
  "specweave-backend"
76
76
  "specweave-payments"
77
77
  "specweave-ml"
78
- "specweave-testing"
79
- "specweave-docs"
80
- "specweave-tooling"
81
- "specweave-alternatives"
82
- "specweave-ui"
83
- "specweave-cost-optimizer"
84
78
  "specweave-diagrams"
85
79
  "specweave-docs-preview"
80
+ "specweave-release"
81
+ "specweave-mobile"
82
+ "specweave-kafka"
83
+ "specweave-kafka-streams"
84
+ "specweave-confluent"
85
+ "specweave-n8n"
86
86
  )
87
87
 
88
88
  installed=0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specweave",
3
- "version": "0.23.1",
3
+ "version": "0.23.2",
4
4
  "description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -38,6 +38,11 @@
38
38
  "type": "command",
39
39
  "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-edit-spec.sh",
40
40
  "timeout": 5
41
+ },
42
+ {
43
+ "type": "command",
44
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-metadata-change.sh",
45
+ "timeout": 10
41
46
  }
42
47
  ]
43
48
  },
@@ -48,6 +53,11 @@
48
53
  "type": "command",
49
54
  "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-write-spec.sh",
50
55
  "timeout": 5
56
+ },
57
+ {
58
+ "type": "command",
59
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-metadata-change.sh",
60
+ "timeout": 10
51
61
  }
52
62
  ]
53
63
  }
@@ -0,0 +1,160 @@
1
+ #!/bin/bash
2
+ #
3
+ # Post-Metadata-Change Hook: Dispatcher for Increment Lifecycle Events
4
+ #
5
+ # Triggers: After Write/Edit modifies metadata.json
6
+ # Purpose: Detect WHAT changed in metadata and call appropriate lifecycle hook
7
+ #
8
+ # Architecture:
9
+ # - metadata.json is the source of truth for increment state
10
+ # - Different state changes require different actions:
11
+ # * status: "completed" → Call post-increment-completion.sh
12
+ # * status: "paused"|"resumed"|"abandoned" → Call post-increment-status-change.sh
13
+ # * other changes → Update status line only
14
+ #
15
+ # This fixes the critical bug where status line never updates on increment closure
16
+ # because post-increment-completion.sh was orphaned (never registered or called).
17
+ #
18
+ # Related Incident: 2025-11-20 - Increment 0047 completed but status line still shows active
19
+ # Root Cause: metadata.json writes don't trigger status line refresh
20
+ # Fix: This hook dispatches to post-increment-completion.sh which updates status line
21
+
22
+ set -e
23
+
24
+ # Find project root
25
+ find_project_root() {
26
+ local dir="$PWD"
27
+ while [[ "$dir" != "/" ]]; do
28
+ if [[ -d "$dir/.specweave" ]]; then
29
+ echo "$dir"
30
+ return 0
31
+ fi
32
+ dir=$(dirname "$dir")
33
+ done
34
+ echo "$PWD"
35
+ }
36
+
37
+ PROJECT_ROOT=$(find_project_root)
38
+ LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
39
+ DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
40
+ HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
41
+
42
+ # Ensure logs directory exists
43
+ mkdir -p "$LOGS_DIR" 2>/dev/null || true
44
+
45
+ # Extract modified file from environment variables (Claude Code provides this)
46
+ MODIFIED_FILE=""
47
+
48
+ # Method 1: TOOL_USE_CONTENT environment variable (primary for Write)
49
+ if [[ -n "${TOOL_USE_CONTENT:-}" ]]; then
50
+ MODIFIED_FILE="$TOOL_USE_CONTENT"
51
+ fi
52
+
53
+ # Method 2: TOOL_RESULT environment variable (fallback)
54
+ if [[ -z "$MODIFIED_FILE" ]] && [[ -n "${TOOL_RESULT:-}" ]]; then
55
+ MODIFIED_FILE=$(echo "$TOOL_RESULT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
56
+ fi
57
+
58
+ # Method 3: Parse tool use arguments (last resort for Edit)
59
+ if [[ -z "$MODIFIED_FILE" ]] && [[ -n "${TOOL_USE_ARGS:-}" ]]; then
60
+ MODIFIED_FILE=$(echo "$TOOL_USE_ARGS" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
61
+ fi
62
+
63
+ echo "[$(date)] post-metadata-change: Detected file: ${MODIFIED_FILE:-<none>}" >> "$DEBUG_LOG" 2>/dev/null || true
64
+
65
+ # Check if this is a metadata.json change in an increment folder
66
+ if [[ -z "$MODIFIED_FILE" ]] || [[ "$MODIFIED_FILE" != *"/metadata.json" ]] || [[ "$MODIFIED_FILE" != *"/.specweave/increments/"* ]]; then
67
+ # Not a metadata.json change in increments folder - exit silently
68
+ exit 0
69
+ fi
70
+
71
+ # Exclude archived increments (shouldn't affect status line)
72
+ if [[ "$MODIFIED_FILE" == *"/_archive/"* ]]; then
73
+ echo "[$(date)] post-metadata-change: Archived increment - skipping" >> "$DEBUG_LOG" 2>/dev/null || true
74
+ exit 0
75
+ fi
76
+
77
+ echo "[$(date)] post-metadata-change: metadata.json changed - analyzing..." >> "$DEBUG_LOG" 2>/dev/null || true
78
+
79
+ # Extract increment ID from path
80
+ # Path format: /path/to/project/.specweave/increments/0047-name/metadata.json
81
+ INCREMENT_ID=$(echo "$MODIFIED_FILE" | grep -o '\.specweave/increments/[^/]*' | sed 's/\.specweave\/increments\///')
82
+
83
+ if [[ -z "$INCREMENT_ID" ]]; then
84
+ echo "[$(date)] post-metadata-change: Could not extract increment ID from path: $MODIFIED_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
85
+ exit 0
86
+ fi
87
+
88
+ echo "[$(date)] post-metadata-change: Increment ID: $INCREMENT_ID" >> "$DEBUG_LOG" 2>/dev/null || true
89
+
90
+ # Read the metadata.json to detect what changed
91
+ METADATA_PATH="$PROJECT_ROOT/.specweave/increments/$INCREMENT_ID/metadata.json"
92
+
93
+ if [[ ! -f "$METADATA_PATH" ]]; then
94
+ echo "[$(date)] post-metadata-change: metadata.json not found at $METADATA_PATH" >> "$DEBUG_LOG" 2>/dev/null || true
95
+ exit 0
96
+ fi
97
+
98
+ # Check if jq is available for parsing JSON
99
+ if ! command -v jq &> /dev/null; then
100
+ echo "[$(date)] post-metadata-change: jq not found - updating status line as fallback" >> "$DEBUG_LOG" 2>/dev/null || true
101
+ bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
102
+ exit 0
103
+ fi
104
+
105
+ # Extract current status
106
+ CURRENT_STATUS=$(jq -r '.status // "unknown"' "$METADATA_PATH" 2>/dev/null)
107
+
108
+ echo "[$(date)] post-metadata-change: Current status: $CURRENT_STATUS" >> "$DEBUG_LOG" 2>/dev/null || true
109
+
110
+ # Dispatch to appropriate lifecycle hook based on status
111
+ case "$CURRENT_STATUS" in
112
+ completed)
113
+ # Increment completed - call post-increment-completion.sh
114
+ # This hook handles:
115
+ # - Closing GitHub issues
116
+ # - Syncing living docs
117
+ # - Updating status line
118
+ echo "[$(date)] post-metadata-change: Increment completed - calling post-increment-completion.sh" >> "$DEBUG_LOG" 2>/dev/null || true
119
+
120
+ if [[ -x "$HOOK_DIR/post-increment-completion.sh" ]]; then
121
+ bash "$HOOK_DIR/post-increment-completion.sh" "$INCREMENT_ID" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
122
+ echo "[$(date)] post-metadata-change: post-increment-completion.sh failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
123
+ }
124
+ else
125
+ echo "[$(date)] post-metadata-change: post-increment-completion.sh not found or not executable" >> "$DEBUG_LOG" 2>/dev/null || true
126
+ # Fallback: Update status line directly
127
+ bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
128
+ fi
129
+ ;;
130
+
131
+ paused|resumed|abandoned)
132
+ # Status change - call post-increment-status-change.sh
133
+ # Note: This typically gets called manually by /specweave:pause commands
134
+ # But we handle it here for completeness
135
+ echo "[$(date)] post-metadata-change: Status changed to $CURRENT_STATUS - calling post-increment-status-change.sh" >> "$DEBUG_LOG" 2>/dev/null || true
136
+
137
+ if [[ -x "$HOOK_DIR/post-increment-status-change.sh" ]]; then
138
+ # Extract reason if available
139
+ REASON=$(jq -r '.statusReason // "Not specified"' "$METADATA_PATH" 2>/dev/null)
140
+ bash "$HOOK_DIR/post-increment-status-change.sh" "$INCREMENT_ID" "$CURRENT_STATUS" "$REASON" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
141
+ echo "[$(date)] post-metadata-change: post-increment-status-change.sh failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
142
+ }
143
+ else
144
+ echo "[$(date)] post-metadata-change: post-increment-status-change.sh not found" >> "$DEBUG_LOG" 2>/dev/null || true
145
+ # Fallback: Update status line directly
146
+ bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
147
+ fi
148
+ ;;
149
+
150
+ *)
151
+ # Other metadata changes (e.g., task completion count, AC count)
152
+ # Just update status line to reflect new progress
153
+ echo "[$(date)] post-metadata-change: Status is $CURRENT_STATUS - updating status line only" >> "$DEBUG_LOG" 2>/dev/null || true
154
+ bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
155
+ ;;
156
+ esac
157
+
158
+ echo "[$(date)] post-metadata-change: Complete" >> "$DEBUG_LOG" 2>/dev/null || true
159
+
160
+ exit 0