specweave 0.3.13 → 0.4.1

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 (168) hide show
  1. package/CLAUDE.md +506 -17
  2. package/README.md +100 -58
  3. package/bin/install-all.sh +9 -2
  4. package/bin/install-hooks.sh +57 -0
  5. package/bin/specweave.js +16 -0
  6. package/dist/adapters/adapter-base.d.ts +21 -0
  7. package/dist/adapters/adapter-base.d.ts.map +1 -1
  8. package/dist/adapters/adapter-base.js +28 -0
  9. package/dist/adapters/adapter-base.js.map +1 -1
  10. package/dist/adapters/adapter-interface.d.ts +41 -0
  11. package/dist/adapters/adapter-interface.d.ts.map +1 -1
  12. package/dist/adapters/claude/adapter.d.ts +36 -0
  13. package/dist/adapters/claude/adapter.d.ts.map +1 -1
  14. package/dist/adapters/claude/adapter.js +135 -0
  15. package/dist/adapters/claude/adapter.js.map +1 -1
  16. package/dist/adapters/copilot/adapter.d.ts +25 -0
  17. package/dist/adapters/copilot/adapter.d.ts.map +1 -1
  18. package/dist/adapters/copilot/adapter.js +112 -0
  19. package/dist/adapters/copilot/adapter.js.map +1 -1
  20. package/dist/adapters/cursor/adapter.d.ts +36 -0
  21. package/dist/adapters/cursor/adapter.d.ts.map +1 -1
  22. package/dist/adapters/cursor/adapter.js +140 -0
  23. package/dist/adapters/cursor/adapter.js.map +1 -1
  24. package/dist/adapters/generic/adapter.d.ts +25 -0
  25. package/dist/adapters/generic/adapter.d.ts.map +1 -1
  26. package/dist/adapters/generic/adapter.js +111 -0
  27. package/dist/adapters/generic/adapter.js.map +1 -1
  28. package/dist/cli/commands/init.d.ts.map +1 -1
  29. package/dist/cli/commands/init.js +103 -1
  30. package/dist/cli/commands/init.js.map +1 -1
  31. package/dist/cli/commands/plugin.d.ts +37 -0
  32. package/dist/cli/commands/plugin.d.ts.map +1 -0
  33. package/dist/cli/commands/plugin.js +296 -0
  34. package/dist/cli/commands/plugin.js.map +1 -0
  35. package/dist/core/agent-model-manager.d.ts +52 -0
  36. package/dist/core/agent-model-manager.d.ts.map +1 -0
  37. package/dist/core/agent-model-manager.js +120 -0
  38. package/dist/core/agent-model-manager.js.map +1 -0
  39. package/dist/core/cost-tracker.d.ts +108 -0
  40. package/dist/core/cost-tracker.d.ts.map +1 -0
  41. package/dist/core/cost-tracker.js +281 -0
  42. package/dist/core/cost-tracker.js.map +1 -0
  43. package/dist/core/model-selector.d.ts +57 -0
  44. package/dist/core/model-selector.d.ts.map +1 -0
  45. package/dist/core/model-selector.js +115 -0
  46. package/dist/core/model-selector.js.map +1 -0
  47. package/dist/core/phase-detector.d.ts +62 -0
  48. package/dist/core/phase-detector.d.ts.map +1 -0
  49. package/dist/core/phase-detector.js +229 -0
  50. package/dist/core/phase-detector.js.map +1 -0
  51. package/dist/core/plugin-detector.d.ts +96 -0
  52. package/dist/core/plugin-detector.d.ts.map +1 -0
  53. package/dist/core/plugin-detector.js +349 -0
  54. package/dist/core/plugin-detector.js.map +1 -0
  55. package/dist/core/plugin-loader.d.ts +111 -0
  56. package/dist/core/plugin-loader.d.ts.map +1 -0
  57. package/dist/core/plugin-loader.js +319 -0
  58. package/dist/core/plugin-loader.js.map +1 -0
  59. package/dist/core/plugin-manager.d.ts +144 -0
  60. package/dist/core/plugin-manager.d.ts.map +1 -0
  61. package/dist/core/plugin-manager.js +393 -0
  62. package/dist/core/plugin-manager.js.map +1 -0
  63. package/dist/core/schemas/plugin-manifest.schema.json +253 -0
  64. package/dist/core/types/plugin.d.ts +252 -0
  65. package/dist/core/types/plugin.d.ts.map +1 -0
  66. package/dist/core/types/plugin.js +48 -0
  67. package/dist/core/types/plugin.js.map +1 -0
  68. package/dist/integrations/jira/jira-mapper.d.ts +2 -2
  69. package/dist/integrations/jira/jira-mapper.js +2 -2
  70. package/dist/types/cost-tracking.d.ts +43 -0
  71. package/dist/types/cost-tracking.d.ts.map +1 -0
  72. package/dist/types/cost-tracking.js +8 -0
  73. package/dist/types/cost-tracking.js.map +1 -0
  74. package/dist/types/model-selection.d.ts +53 -0
  75. package/dist/types/model-selection.d.ts.map +1 -0
  76. package/dist/types/model-selection.js +12 -0
  77. package/dist/types/model-selection.js.map +1 -0
  78. package/dist/utils/cost-reporter.d.ts +58 -0
  79. package/dist/utils/cost-reporter.d.ts.map +1 -0
  80. package/dist/utils/cost-reporter.js +224 -0
  81. package/dist/utils/cost-reporter.js.map +1 -0
  82. package/dist/utils/pricing-constants.d.ts +70 -0
  83. package/dist/utils/pricing-constants.d.ts.map +1 -0
  84. package/dist/utils/pricing-constants.js +71 -0
  85. package/dist/utils/pricing-constants.js.map +1 -0
  86. package/package.json +13 -9
  87. package/src/adapters/adapter-base.ts +33 -0
  88. package/src/adapters/adapter-interface.ts +46 -0
  89. package/src/adapters/claude/adapter.ts +164 -0
  90. package/src/adapters/copilot/adapter.ts +138 -0
  91. package/src/adapters/cursor/adapter.ts +170 -0
  92. package/src/adapters/generic/adapter.ts +137 -0
  93. package/src/agents/architect/AGENT.md +3 -0
  94. package/src/agents/code-reviewer.md +156 -0
  95. package/src/agents/data-scientist/AGENT.md +181 -0
  96. package/src/agents/database-optimizer/AGENT.md +147 -0
  97. package/src/agents/devops/AGENT.md +3 -0
  98. package/src/agents/diagrams-architect/AGENT.md +3 -0
  99. package/src/agents/docs-writer/AGENT.md +3 -0
  100. package/src/agents/kubernetes-architect/AGENT.md +142 -0
  101. package/src/agents/ml-engineer/AGENT.md +150 -0
  102. package/src/agents/mlops-engineer/AGENT.md +201 -0
  103. package/src/agents/network-engineer/AGENT.md +149 -0
  104. package/src/agents/observability-engineer/AGENT.md +213 -0
  105. package/src/agents/payment-integration/AGENT.md +35 -0
  106. package/src/agents/performance/AGENT.md +3 -0
  107. package/src/agents/performance-engineer/AGENT.md +153 -0
  108. package/src/agents/pm/AGENT.md +3 -0
  109. package/src/agents/qa-lead/AGENT.md +3 -0
  110. package/src/agents/security/AGENT.md +3 -0
  111. package/src/agents/sre/AGENT.md +3 -0
  112. package/src/agents/tdd-orchestrator/AGENT.md +169 -0
  113. package/src/agents/tech-lead/AGENT.md +3 -0
  114. package/src/commands/specweave.costs.md +261 -0
  115. package/src/commands/specweave.increment.md +48 -4
  116. package/src/commands/specweave.ml-pipeline.md +292 -0
  117. package/src/commands/specweave.monitor-setup.md +501 -0
  118. package/src/commands/specweave.slo-implement.md +1055 -0
  119. package/src/commands/specweave.sync-github.md +1 -1
  120. package/src/commands/specweave.tdd-cycle.md +199 -0
  121. package/src/commands/specweave.tdd-green.md +842 -0
  122. package/src/commands/specweave.tdd-red.md +135 -0
  123. package/src/commands/specweave.tdd-refactor.md +165 -0
  124. package/src/hooks/post-increment-plugin-detect.sh +142 -0
  125. package/src/hooks/post-task-completion.sh +53 -11
  126. package/src/hooks/pre-task-plugin-detect.sh +96 -0
  127. package/src/skills/SKILLS-INDEX.md +18 -10
  128. package/src/skills/billing-automation/SKILL.md +559 -0
  129. package/src/skills/distributed-tracing/SKILL.md +438 -0
  130. package/src/skills/e2e-playwright/README.md +1 -1
  131. package/src/skills/e2e-playwright/package.json +1 -1
  132. package/src/skills/gitops-workflow/SKILL.md +285 -0
  133. package/src/skills/gitops-workflow/references/argocd-setup.md +134 -0
  134. package/src/skills/gitops-workflow/references/sync-policies.md +131 -0
  135. package/src/skills/grafana-dashboards/SKILL.md +369 -0
  136. package/src/skills/helm-chart-scaffolding/SKILL.md +544 -0
  137. package/src/skills/helm-chart-scaffolding/assets/Chart.yaml.template +42 -0
  138. package/src/skills/helm-chart-scaffolding/assets/values.yaml.template +185 -0
  139. package/src/skills/helm-chart-scaffolding/references/chart-structure.md +500 -0
  140. package/src/skills/helm-chart-scaffolding/scripts/validate-chart.sh +244 -0
  141. package/src/skills/k8s-manifest-generator/SKILL.md +511 -0
  142. package/src/skills/k8s-manifest-generator/assets/configmap-template.yaml +296 -0
  143. package/src/skills/k8s-manifest-generator/assets/deployment-template.yaml +203 -0
  144. package/src/skills/k8s-manifest-generator/assets/service-template.yaml +171 -0
  145. package/src/skills/k8s-manifest-generator/references/deployment-spec.md +753 -0
  146. package/src/skills/k8s-manifest-generator/references/service-spec.md +724 -0
  147. package/src/skills/k8s-security-policies/SKILL.md +334 -0
  148. package/src/skills/k8s-security-policies/assets/network-policy-template.yaml +177 -0
  149. package/src/skills/k8s-security-policies/references/rbac-patterns.md +187 -0
  150. package/src/skills/ml-pipeline-workflow/SKILL.md +245 -0
  151. package/src/skills/paypal-integration/SKILL.md +467 -0
  152. package/src/skills/pci-compliance/SKILL.md +466 -0
  153. package/src/skills/prometheus-configuration/SKILL.md +392 -0
  154. package/src/skills/slo-implementation/SKILL.md +329 -0
  155. package/src/skills/stripe-integration/SKILL.md +442 -0
  156. package/src/skills/tdd-workflow/SKILL.md +378 -0
  157. package/src/templates/README.md.template +1 -1
  158. package/src/skills/bmad-method-expert/SKILL.md +0 -626
  159. package/src/skills/bmad-method-expert/scripts/analyze-project.js +0 -318
  160. package/src/skills/bmad-method-expert/scripts/check-setup.js +0 -208
  161. package/src/skills/bmad-method-expert/scripts/generate-template.js +0 -1149
  162. package/src/skills/bmad-method-expert/scripts/validate-documents.js +0 -340
  163. package/src/skills/context-optimizer/SKILL.md +0 -588
  164. package/src/skills/figma-designer/SKILL.md +0 -149
  165. package/src/skills/figma-implementer/SKILL.md +0 -148
  166. package/src/skills/figma-mcp-connector/SKILL.md +0 -136
  167. package/src/skills/figma-to-code/SKILL.md +0 -128
  168. package/src/skills/spec-kit-expert/SKILL.md +0 -1010
@@ -0,0 +1,135 @@
1
+ Write comprehensive failing tests following TDD red phase principles.
2
+
3
+ [Extended thinking: Generates failing tests that properly define expected behavior using test-automator agent.]
4
+
5
+ ## Role
6
+
7
+ Generate failing tests using Task tool with subagent_type="unit-testing::test-automator".
8
+
9
+ ## Prompt Template
10
+
11
+ "Generate comprehensive FAILING tests for: $ARGUMENTS
12
+
13
+ ## Core Requirements
14
+
15
+ 1. **Test Structure**
16
+ - Framework-appropriate setup (Jest/pytest/JUnit/Go/RSpec)
17
+ - Arrange-Act-Assert pattern
18
+ - should_X_when_Y naming convention
19
+ - Isolated fixtures with no interdependencies
20
+
21
+ 2. **Behavior Coverage**
22
+ - Happy path scenarios
23
+ - Edge cases (empty, null, boundary values)
24
+ - Error handling and exceptions
25
+ - Concurrent access (if applicable)
26
+
27
+ 3. **Failure Verification**
28
+ - Tests MUST fail when run
29
+ - Failures for RIGHT reasons (not syntax/import errors)
30
+ - Meaningful diagnostic error messages
31
+ - No cascading failures
32
+
33
+ 4. **Test Categories**
34
+ - Unit: Isolated component behavior
35
+ - Integration: Component interaction
36
+ - Contract: API/interface contracts
37
+ - Property: Mathematical invariants
38
+
39
+ ## Framework Patterns
40
+
41
+ **JavaScript/TypeScript (Jest/Vitest)**
42
+ - Mock dependencies with `vi.fn()` or `jest.fn()`
43
+ - Use `@testing-library` for React components
44
+ - Property tests with `fast-check`
45
+
46
+ **Python (pytest)**
47
+ - Fixtures with appropriate scopes
48
+ - Parametrize for multiple test cases
49
+ - Hypothesis for property-based tests
50
+
51
+ **Go**
52
+ - Table-driven tests with subtests
53
+ - `t.Parallel()` for parallel execution
54
+ - Use `testify/assert` for cleaner assertions
55
+
56
+ **Ruby (RSpec)**
57
+ - `let` for lazy loading, `let!` for eager
58
+ - Contexts for different scenarios
59
+ - Shared examples for common behavior
60
+
61
+ ## Quality Checklist
62
+
63
+ - Readable test names documenting intent
64
+ - One behavior per test
65
+ - No implementation leakage
66
+ - Meaningful test data (not 'foo'/'bar')
67
+ - Tests serve as living documentation
68
+
69
+ ## Anti-Patterns to Avoid
70
+
71
+ - Tests passing immediately
72
+ - Testing implementation vs behavior
73
+ - Complex setup code
74
+ - Multiple responsibilities per test
75
+ - Brittle tests tied to specifics
76
+
77
+ ## Edge Case Categories
78
+
79
+ - **Null/Empty**: undefined, null, empty string/array/object
80
+ - **Boundaries**: min/max values, single element, capacity limits
81
+ - **Special Cases**: Unicode, whitespace, special characters
82
+ - **State**: Invalid transitions, concurrent modifications
83
+ - **Errors**: Network failures, timeouts, permissions
84
+
85
+ ## Output Requirements
86
+
87
+ - Complete test files with imports
88
+ - Documentation of test purpose
89
+ - Commands to run and verify failures
90
+ - Metrics: test count, coverage areas
91
+ - Next steps for green phase"
92
+
93
+ ## Validation
94
+
95
+ After generation:
96
+ 1. Run tests - confirm they fail
97
+ 2. Verify helpful failure messages
98
+ 3. Check test independence
99
+ 4. Ensure comprehensive coverage
100
+
101
+ ## Example (Minimal)
102
+
103
+ ```typescript
104
+ // auth.service.test.ts
105
+ describe('AuthService', () => {
106
+ let authService: AuthService;
107
+ let mockUserRepo: jest.Mocked<UserRepository>;
108
+
109
+ beforeEach(() => {
110
+ mockUserRepo = { findByEmail: jest.fn() } as any;
111
+ authService = new AuthService(mockUserRepo);
112
+ });
113
+
114
+ it('should_return_token_when_valid_credentials', async () => {
115
+ const user = { id: '1', email: 'test@example.com', passwordHash: 'hashed' };
116
+ mockUserRepo.findByEmail.mockResolvedValue(user);
117
+
118
+ const result = await authService.authenticate('test@example.com', 'pass');
119
+
120
+ expect(result.success).toBe(true);
121
+ expect(result.token).toBeDefined();
122
+ });
123
+
124
+ it('should_fail_when_user_not_found', async () => {
125
+ mockUserRepo.findByEmail.mockResolvedValue(null);
126
+
127
+ const result = await authService.authenticate('none@example.com', 'pass');
128
+
129
+ expect(result.success).toBe(false);
130
+ expect(result.error).toBe('INVALID_CREDENTIALS');
131
+ });
132
+ });
133
+ ```
134
+
135
+ Test requirements: $ARGUMENTS
@@ -0,0 +1,165 @@
1
+ Refactor code with confidence using comprehensive test safety net:
2
+
3
+ [Extended thinking: This tool uses the tdd-orchestrator agent (opus model) for sophisticated refactoring while maintaining all tests green. It applies design patterns, improves code quality, and optimizes performance with the safety of comprehensive test coverage.]
4
+
5
+ ## Usage
6
+
7
+ Use Task tool with subagent_type="tdd-orchestrator" to perform safe refactoring.
8
+
9
+ Prompt: "Refactor this code while keeping all tests green: $ARGUMENTS. Apply TDD refactor phase:
10
+
11
+ ## Core Process
12
+
13
+ **1. Pre-Assessment**
14
+ - Run tests to establish green baseline
15
+ - Analyze code smells and test coverage
16
+ - Document current performance metrics
17
+ - Create incremental refactoring plan
18
+
19
+ **2. Code Smell Detection**
20
+ - Duplicated code → Extract methods/classes
21
+ - Long methods → Decompose into focused functions
22
+ - Large classes → Split responsibilities
23
+ - Long parameter lists → Parameter objects
24
+ - Feature Envy → Move methods to appropriate classes
25
+ - Primitive Obsession → Value objects
26
+ - Switch statements → Polymorphism
27
+ - Dead code → Remove
28
+
29
+ **3. Design Patterns**
30
+ - Apply Creational (Factory, Builder, Singleton)
31
+ - Apply Structural (Adapter, Facade, Decorator)
32
+ - Apply Behavioral (Strategy, Observer, Command)
33
+ - Apply Domain (Repository, Service, Value Objects)
34
+ - Use patterns only where they add clear value
35
+
36
+ **4. SOLID Principles**
37
+ - Single Responsibility: One reason to change
38
+ - Open/Closed: Open for extension, closed for modification
39
+ - Liskov Substitution: Subtypes substitutable
40
+ - Interface Segregation: Small, focused interfaces
41
+ - Dependency Inversion: Depend on abstractions
42
+
43
+ **5. Refactoring Techniques**
44
+ - Extract Method/Variable/Interface
45
+ - Inline unnecessary indirection
46
+ - Rename for clarity
47
+ - Move Method/Field to appropriate classes
48
+ - Replace Magic Numbers with constants
49
+ - Encapsulate fields
50
+ - Replace Conditional with Polymorphism
51
+ - Introduce Null Object
52
+
53
+ **6. Performance Optimization**
54
+ - Profile to identify bottlenecks
55
+ - Optimize algorithms and data structures
56
+ - Implement caching where beneficial
57
+ - Reduce database queries (N+1 elimination)
58
+ - Lazy loading and pagination
59
+ - Always measure before and after
60
+
61
+ **7. Incremental Steps**
62
+ - Make small, atomic changes
63
+ - Run tests after each modification
64
+ - Commit after each successful refactoring
65
+ - Keep refactoring separate from behavior changes
66
+ - Use scaffolding when needed
67
+
68
+ **8. Architecture Evolution**
69
+ - Layer separation and dependency management
70
+ - Module boundaries and interface definition
71
+ - Event-driven patterns for decoupling
72
+ - Database access pattern optimization
73
+
74
+ **9. Safety Verification**
75
+ - Run full test suite after each change
76
+ - Performance regression testing
77
+ - Mutation testing for test effectiveness
78
+ - Rollback plan for major changes
79
+
80
+ **10. Advanced Patterns**
81
+ - Strangler Fig: Gradual legacy replacement
82
+ - Branch by Abstraction: Large-scale changes
83
+ - Parallel Change: Expand-contract pattern
84
+ - Mikado Method: Dependency graph navigation
85
+
86
+ ## Output Requirements
87
+
88
+ - Refactored code with improvements applied
89
+ - Test results (all green)
90
+ - Before/after metrics comparison
91
+ - Applied refactoring techniques list
92
+ - Performance improvement measurements
93
+ - Remaining technical debt assessment
94
+
95
+ ## Safety Checklist
96
+
97
+ Before committing:
98
+ - ✓ All tests pass (100% green)
99
+ - ✓ No functionality regression
100
+ - ✓ Performance metrics acceptable
101
+ - ✓ Code coverage maintained/improved
102
+ - ✓ Documentation updated
103
+
104
+ ## Recovery Protocol
105
+
106
+ If tests fail:
107
+ - Immediately revert last change
108
+ - Identify breaking refactoring
109
+ - Apply smaller incremental changes
110
+ - Use version control for safe experimentation
111
+
112
+ ## Example: Extract Method Pattern
113
+
114
+ **Before:**
115
+ ```typescript
116
+ class OrderProcessor {
117
+ processOrder(order: Order): ProcessResult {
118
+ // Validation
119
+ if (!order.customerId || order.items.length === 0) {
120
+ return { success: false, error: "Invalid order" };
121
+ }
122
+
123
+ // Calculate totals
124
+ let subtotal = 0;
125
+ for (const item of order.items) {
126
+ subtotal += item.price * item.quantity;
127
+ }
128
+ let total = subtotal + (subtotal * 0.08) + (subtotal > 100 ? 0 : 15);
129
+
130
+ // Process payment...
131
+ // Update inventory...
132
+ // Send confirmation...
133
+ }
134
+ }
135
+ ```
136
+
137
+ **After:**
138
+ ```typescript
139
+ class OrderProcessor {
140
+ async processOrder(order: Order): Promise<ProcessResult> {
141
+ const validation = this.validateOrder(order);
142
+ if (!validation.isValid) return ProcessResult.failure(validation.error);
143
+
144
+ const orderTotal = OrderTotal.calculate(order);
145
+ const inventoryCheck = await this.inventoryService.checkAvailability(order.items);
146
+ if (!inventoryCheck.available) return ProcessResult.failure(inventoryCheck.reason);
147
+
148
+ await this.paymentService.processPayment(order.paymentMethod, orderTotal.total);
149
+ await this.inventoryService.reserveItems(order.items);
150
+ await this.notificationService.sendOrderConfirmation(order, orderTotal);
151
+
152
+ return ProcessResult.success(order.id, orderTotal.total);
153
+ }
154
+
155
+ private validateOrder(order: Order): ValidationResult {
156
+ if (!order.customerId) return ValidationResult.invalid("Customer ID required");
157
+ if (order.items.length === 0) return ValidationResult.invalid("Order must contain items");
158
+ return ValidationResult.valid();
159
+ }
160
+ }
161
+ ```
162
+
163
+ **Applied:** Extract Method, Value Objects, Dependency Injection, Async patterns
164
+
165
+ Code to refactor: $ARGUMENTS"
@@ -0,0 +1,142 @@
1
+ #!/bin/bash
2
+
3
+ #
4
+ # Post-Increment Plugin Detection Hook (T-021)
5
+ #
6
+ # Runs AFTER increment completion to suggest plugins based on git diff
7
+ # This is Phase 4 of the 4-phase plugin detection system
8
+ #
9
+ # Trigger: After `/specweave.done` completes an increment
10
+ # Output: Plugin suggestions for NEXT increment
11
+ #
12
+
13
+ # Exit on error
14
+ set -e
15
+
16
+ # Get project root (assumes hook runs from project directory)
17
+ PROJECT_ROOT=$(pwd)
18
+
19
+ # Colors for output
20
+ GREEN='\033[0;32m'
21
+ YELLOW='\033[1;33m'
22
+ CYAN='\033[0;36m'
23
+ GRAY='\033[0;37m'
24
+ MAGENTA='\033[0;35m'
25
+ NC='\033[0m' # No Color
26
+
27
+ # Check if SpecWeave is installed
28
+ if ! command -v specweave &> /dev/null; then
29
+ # Silent exit if SpecWeave not installed (development mode)
30
+ exit 0
31
+ fi
32
+
33
+ # Check if git repository exists
34
+ if [ ! -d ".git" ]; then
35
+ # Not a git repo, skip detection
36
+ exit 0
37
+ fi
38
+
39
+ # Get completed increment number (passed as argument)
40
+ INCREMENT_NUM="$1"
41
+
42
+ if [ -z "$INCREMENT_NUM" ]; then
43
+ # No increment number provided, skip
44
+ exit 0
45
+ fi
46
+
47
+ # Get git diff since last increment tag (or HEAD if no tags)
48
+ LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~10")
49
+ GIT_DIFF=$(git diff --name-only "$LAST_TAG"..HEAD 2>/dev/null || echo "")
50
+
51
+ if [ -z "$GIT_DIFF" ]; then
52
+ # No changes detected, skip
53
+ exit 0
54
+ fi
55
+
56
+ # Also check package.json changes for new dependencies
57
+ PACKAGE_JSON_CHANGED=false
58
+ if echo "$GIT_DIFF" | grep -q "package.json"; then
59
+ PACKAGE_JSON_CHANGED=true
60
+ fi
61
+
62
+ # Keyword-based plugin detection from file changes
63
+ declare -A PLUGIN_PATTERNS=(
64
+ ["specweave-github"]=".github/|github-"
65
+ ["specweave-kubernetes"]="kubernetes/|k8s/|helm/|\.yaml$"
66
+ ["specweave-frontend-stack"]="components/|pages/|app/|\.tsx$|\.jsx$"
67
+ ["specweave-backend-stack"]="api/|server/|routes/|controllers/"
68
+ ["specweave-ml-ops"]="models/|training/|\.ipynb$|\.h5$|\.pkl$"
69
+ ["specweave-payment-processing"]="payments/|billing/|stripe"
70
+ ["specweave-figma"]="\.figma|design/|mockups/"
71
+ ["specweave-observability"]="prometheus/|grafana/|monitoring/"
72
+ ["specweave-diagrams"]="diagrams/|\.mmd$|architecture/"
73
+ )
74
+
75
+ # Dependency-based detection (if package.json changed)
76
+ declare -A DEPENDENCY_PLUGINS=(
77
+ ["specweave-frontend-stack"]="react|vue|angular|next"
78
+ ["specweave-backend-stack"]="express|fastapi|django|nestjs"
79
+ ["specweave-payment-processing"]="stripe|paypal"
80
+ ["specweave-ml-ops"]="tensorflow|pytorch|scikit-learn"
81
+ ["specweave-observability"]="prometheus-client|@opentelemetry"
82
+ )
83
+
84
+ # Detect plugins based on file patterns
85
+ SUGGESTED_PLUGINS=()
86
+
87
+ # Check file patterns
88
+ for plugin in "${!PLUGIN_PATTERNS[@]}"; do
89
+ pattern="${PLUGIN_PATTERNS[$plugin]}"
90
+
91
+ if echo "$GIT_DIFF" | grep -qi -E "$pattern"; then
92
+ # Check if plugin is already enabled
93
+ if ! specweave plugin list --enabled 2>/dev/null | grep -q "$plugin"; then
94
+ if [[ ! " ${SUGGESTED_PLUGINS[@]} " =~ " ${plugin} " ]]; then
95
+ SUGGESTED_PLUGINS+=("$plugin")
96
+ fi
97
+ fi
98
+ fi
99
+ done
100
+
101
+ # Check package.json dependencies if it changed
102
+ if [ "$PACKAGE_JSON_CHANGED" = true ] && [ -f "package.json" ]; then
103
+ DEPENDENCIES=$(cat package.json | grep -A 100 '"dependencies"' | grep -A 100 '"devDependencies"' || echo "")
104
+
105
+ for plugin in "${!DEPENDENCY_PLUGINS[@]}"; do
106
+ keywords="${DEPENDENCY_PLUGINS[$plugin]}"
107
+
108
+ if echo "$DEPENDENCIES" | grep -qi -E "$keywords"; then
109
+ if ! specweave plugin list --enabled 2>/dev/null | grep -q "$plugin"; then
110
+ if [[ ! " ${SUGGESTED_PLUGINS[@]} " =~ " ${plugin} " ]]; then
111
+ SUGGESTED_PLUGINS+=("$plugin")
112
+ fi
113
+ fi
114
+ fi
115
+ done
116
+ fi
117
+
118
+ # Output suggestions if any found
119
+ if [ ${#SUGGESTED_PLUGINS[@]} -gt 0 ]; then
120
+ echo ""
121
+ echo -e "${MAGENTA}══════════════════════════════════════════════════════${NC}"
122
+ echo -e "${CYAN}💡 Plugin Suggestions for Next Increment${NC}"
123
+ echo -e "${MAGENTA}══════════════════════════════════════════════════════${NC}"
124
+ echo ""
125
+ echo -e "${GRAY}Increment ${INCREMENT_NUM} introduced changes that suggest:${NC}"
126
+ echo ""
127
+
128
+ for plugin in "${SUGGESTED_PLUGINS[@]}"; do
129
+ echo -e " ✨ ${GREEN}${plugin}${NC}"
130
+ done
131
+
132
+ echo ""
133
+ echo -e "${YELLOW}Consider enabling these plugins for your next increment:${NC}"
134
+ echo -e "${CYAN} specweave plugin enable <name>${NC}"
135
+ echo ""
136
+ echo -e "${GRAY}Plugins will auto-activate skills and agents for better support${NC}"
137
+ echo -e "${MAGENTA}══════════════════════════════════════════════════════${NC}"
138
+ echo ""
139
+ fi
140
+
141
+ # Always exit successfully (non-blocking)
142
+ exit 0
@@ -4,9 +4,10 @@
4
4
  # Runs automatically after ANY task is marked complete via TodoWrite
5
5
  #
6
6
  # Actions:
7
- # 1. Play completion sound (synchronously, not background)
8
- # 2. Output JSON systemMessage reminding to update docs
9
- # 3. Log completion
7
+ # 1. Check if ALL tasks are completed (parse stdin JSON)
8
+ # 2. Play completion sound ONLY if all tasks done
9
+ # 3. Output JSON systemMessage reminding to update docs
10
+ # 4. Log completion
10
11
  #
11
12
  # DEBOUNCING: Prevents rapid duplicate fires (Claude Code calls hooks twice)
12
13
 
@@ -42,16 +43,43 @@ fi
42
43
  # Save current timestamp
43
44
  echo "$CURRENT_TIME" > "$LAST_FIRE_FILE"
44
45
 
46
+ # Read stdin to temporary file
47
+ STDIN_DATA=$(mktemp)
48
+ cat > "$STDIN_DATA"
49
+
45
50
  # DEBUG: Log hook invocation
46
51
  echo "[$(date)] Hook invoked! PWD=$PWD Args=$*" >> .specweave/logs/hooks-debug.log 2>/dev/null || true
47
52
  echo "[$(date)] Hook stdin:" >> .specweave/logs/hooks-debug.log 2>/dev/null || true
48
- cat >> .specweave/logs/hooks-debug.log 2>/dev/null || true
53
+ cat "$STDIN_DATA" >> .specweave/logs/hooks-debug.log 2>/dev/null || true
54
+
55
+ # Parse JSON to check if ALL tasks are completed
56
+ # Extract todos array and check for any non-completed tasks
57
+ ALL_COMPLETED=false
58
+
59
+ if command -v jq >/dev/null 2>&1; then
60
+ # Use jq if available (more reliable)
61
+ PENDING_COUNT=$(jq -r '.tool_input.todos // [] | map(select(.status != "completed")) | length' "$STDIN_DATA" 2>/dev/null || echo "1")
62
+
63
+ if [ "$PENDING_COUNT" = "0" ]; then
64
+ ALL_COMPLETED=true
65
+ fi
66
+ else
67
+ # Fallback: Simple grep check (less reliable but works without jq)
68
+ if grep -q '"status":"pending"\|"status":"in_progress"' "$STDIN_DATA" 2>/dev/null; then
69
+ ALL_COMPLETED=false
70
+ else
71
+ # No pending/in_progress found - likely all completed
72
+ ALL_COMPLETED=true
73
+ fi
74
+ fi
49
75
 
50
- # 1. Play notification sound SYNCHRONOUSLY (cross-platform)
76
+ # Clean up temp file
77
+ rm -f "$STDIN_DATA"
78
+
79
+ # 1. Play notification sound ONLY if ALL tasks are completed
51
80
  play_sound() {
52
81
  case "$(uname -s)" in
53
82
  Darwin)
54
- # Play synchronously (remove &)
55
83
  afplay /System/Library/Sounds/Glass.aiff 2>/dev/null || true
56
84
  ;;
57
85
  Linux)
@@ -64,16 +92,30 @@ play_sound() {
64
92
  esac
65
93
  }
66
94
 
67
- # Play sound FIRST (synchronously)
68
- play_sound
95
+ # Play sound ONLY if all tasks completed
96
+ if [ "$ALL_COMPLETED" = "true" ]; then
97
+ echo "[$(date)] 🎉 ALL TASKS COMPLETED - Playing sound!" >> .specweave/logs/hooks-debug.log 2>/dev/null || true
98
+ play_sound
99
+ else
100
+ echo "[$(date)] Task completed, but more tasks remain (no sound)" >> .specweave/logs/hooks-debug.log 2>/dev/null || true
101
+ fi
69
102
 
70
103
  # 2. Log completion
71
- echo "[$(date)] Task completed" >> .specweave/logs/tasks.log 2>/dev/null || true
104
+ echo "[$(date)] Task completed (All done: $ALL_COMPLETED)" >> .specweave/logs/tasks.log 2>/dev/null || true
72
105
 
73
106
  # 3. Output JSON to instruct Claude (systemMessage is shown to user)
74
- cat <<EOF
107
+ if [ "$ALL_COMPLETED" = "true" ]; then
108
+ cat <<EOF
75
109
  {
76
110
  "continue": true,
77
- "systemMessage": "🔔 Task completed! Remember to update documentation with inline edits to CLAUDE.md and README.md as needed."
111
+ "systemMessage": "🎉 ALL TASKS COMPLETED! Remember to update documentation with inline edits to CLAUDE.md and README.md as needed."
78
112
  }
79
113
  EOF
114
+ else
115
+ cat <<EOF
116
+ {
117
+ "continue": true,
118
+ "systemMessage": "✅ Task completed. More tasks remaining - keep going!"
119
+ }
120
+ EOF
121
+ fi
@@ -0,0 +1,96 @@
1
+ #!/bin/bash
2
+
3
+ #
4
+ # Pre-Task Plugin Detection Hook (T-020)
5
+ #
6
+ # Runs BEFORE task execution to suggest plugins based on task description
7
+ # This is Phase 3 of the 4-phase plugin detection system
8
+ #
9
+ # Trigger: Before executing any task via `/specweave.do`
10
+ # Output: Non-blocking plugin suggestions
11
+ #
12
+
13
+ # Exit on error
14
+ set -e
15
+
16
+ # Get project root (assumes hook runs from project directory)
17
+ PROJECT_ROOT=$(pwd)
18
+
19
+ # Colors for output
20
+ GREEN='\033[0;32m'
21
+ YELLOW='\033[1;33m'
22
+ CYAN='\033[0;36m'
23
+ GRAY='\033[0;37m'
24
+ NC='\033[0m' # No Color
25
+
26
+ # Check if SpecWeave is installed
27
+ if ! command -v specweave &> /dev/null; then
28
+ # Silent exit if SpecWeave not installed (development mode)
29
+ exit 0
30
+ fi
31
+
32
+ # Get current task being executed (passed as argument)
33
+ TASK_FILE="$1"
34
+
35
+ if [ -z "$TASK_FILE" ] || [ ! -f "$TASK_FILE" ]; then
36
+ # No task file provided, skip detection
37
+ exit 0
38
+ fi
39
+
40
+ # Extract task description
41
+ TASK_DESCRIPTION=$(grep -A 5 "^### T-[0-9]" "$TASK_FILE" | head -1 || echo "")
42
+
43
+ if [ -z "$TASK_DESCRIPTION" ]; then
44
+ # No description found, skip
45
+ exit 0
46
+ fi
47
+
48
+ # Keyword-based plugin detection
49
+ declare -A PLUGIN_KEYWORDS=(
50
+ ["specweave-github"]="github|gh|issue|pull request|pr"
51
+ ["specweave-kubernetes"]="kubernetes|k8s|kubectl|helm|pod|deployment"
52
+ ["specweave-frontend-stack"]="react|vue|angular|nextjs|frontend|ui|component"
53
+ ["specweave-backend-stack"]="express|fastapi|django|flask|nestjs|backend|api|server"
54
+ ["specweave-ml-ops"]="tensorflow|pytorch|sklearn|ml|machine learning|model|training"
55
+ ["specweave-payment-processing"]="stripe|paypal|payment|billing|subscription"
56
+ ["specweave-figma"]="figma|design|mockup|prototype"
57
+ ["specweave-jira"]="jira|atlassian|ticket"
58
+ ["specweave-observability"]="prometheus|grafana|datadog|monitoring|metrics|tracing"
59
+ )
60
+
61
+ # Detect plugins based on keywords
62
+ SUGGESTED_PLUGINS=()
63
+
64
+ for plugin in "${!PLUGIN_KEYWORDS[@]}"; do
65
+ keywords="${PLUGIN_KEYWORDS[$plugin]}"
66
+
67
+ # Check if any keyword matches (case-insensitive)
68
+ if echo "$TASK_DESCRIPTION" | grep -qi -E "$keywords"; then
69
+ # Check if plugin is already enabled
70
+ if ! specweave plugin list --enabled 2>/dev/null | grep -q "$plugin"; then
71
+ SUGGESTED_PLUGINS+=("$plugin")
72
+ fi
73
+ fi
74
+ done
75
+
76
+ # Output suggestions if any found
77
+ if [ ${#SUGGESTED_PLUGINS[@]} -gt 0 ]; then
78
+ echo ""
79
+ echo -e "${CYAN}💡 Plugin Detection${NC}"
80
+ echo ""
81
+ echo -e "${GRAY}Task mentions: ${TASK_DESCRIPTION}${NC}"
82
+ echo ""
83
+ echo -e "${YELLOW}Suggested plugins:${NC}"
84
+
85
+ for plugin in "${SUGGESTED_PLUGINS[@]}"; do
86
+ echo -e " • ${GREEN}${plugin}${NC}"
87
+ done
88
+
89
+ echo ""
90
+ echo -e "${GRAY}This task might benefit from these plugins.${NC}"
91
+ echo -e "${GRAY}Run: ${CYAN}specweave plugin enable <name>${GRAY} to install${NC}"
92
+ echo ""
93
+ fi
94
+
95
+ # Always exit successfully (non-blocking)
96
+ exit 0