specweave 0.15.1 → 0.16.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.
Files changed (52) hide show
  1. package/CLAUDE.md +38 -0
  2. package/dist/cli/commands/init.d.ts.map +1 -1
  3. package/dist/cli/commands/init.js +162 -3
  4. package/dist/cli/commands/init.js.map +1 -1
  5. package/dist/cli/helpers/github/increment-profile-selector.d.ts +47 -0
  6. package/dist/cli/helpers/github/increment-profile-selector.d.ts.map +1 -0
  7. package/dist/cli/helpers/github/increment-profile-selector.js +186 -0
  8. package/dist/cli/helpers/github/increment-profile-selector.js.map +1 -0
  9. package/dist/cli/helpers/github/profile-manager.d.ts +119 -0
  10. package/dist/cli/helpers/github/profile-manager.d.ts.map +1 -0
  11. package/dist/cli/helpers/github/profile-manager.js +311 -0
  12. package/dist/cli/helpers/github/profile-manager.js.map +1 -0
  13. package/dist/cli/helpers/issue-tracker/github-multi-repo.d.ts +81 -0
  14. package/dist/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +1 -0
  15. package/dist/cli/helpers/issue-tracker/github-multi-repo.js +385 -0
  16. package/dist/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -0
  17. package/dist/cli/helpers/issue-tracker/github.d.ts +13 -0
  18. package/dist/cli/helpers/issue-tracker/github.d.ts.map +1 -1
  19. package/dist/cli/helpers/issue-tracker/github.js +38 -143
  20. package/dist/cli/helpers/issue-tracker/github.js.map +1 -1
  21. package/dist/cli/helpers/issue-tracker/index.d.ts.map +1 -1
  22. package/dist/cli/helpers/issue-tracker/index.js +126 -43
  23. package/dist/cli/helpers/issue-tracker/index.js.map +1 -1
  24. package/dist/cli/helpers/issue-tracker/utils.d.ts +8 -0
  25. package/dist/cli/helpers/issue-tracker/utils.d.ts.map +1 -1
  26. package/dist/cli/helpers/issue-tracker/utils.js +46 -0
  27. package/dist/cli/helpers/issue-tracker/utils.js.map +1 -1
  28. package/dist/core/increment/active-increment-manager.d.ts +79 -0
  29. package/dist/core/increment/active-increment-manager.d.ts.map +1 -0
  30. package/dist/core/increment/active-increment-manager.js +153 -0
  31. package/dist/core/increment/active-increment-manager.js.map +1 -0
  32. package/dist/core/increment/metadata-manager.d.ts +2 -0
  33. package/dist/core/increment/metadata-manager.d.ts.map +1 -1
  34. package/dist/core/increment/metadata-manager.js +15 -0
  35. package/dist/core/increment/metadata-manager.js.map +1 -1
  36. package/dist/utils/git-detector.d.ts +84 -0
  37. package/dist/utils/git-detector.d.ts.map +1 -0
  38. package/dist/utils/git-detector.js +233 -0
  39. package/dist/utils/git-detector.js.map +1 -0
  40. package/package.json +2 -2
  41. package/plugins/specweave/commands/specweave-done.md +109 -1
  42. package/plugins/specweave/hooks/lib/update-status-line.sh +30 -4
  43. package/plugins/specweave/hooks/post-increment-planning.sh +50 -5
  44. package/plugins/specweave/hooks/user-prompt-submit.sh +77 -21
  45. package/plugins/specweave/skills/increment-planner/SKILL.md +12 -5
  46. package/plugins/specweave/skills/increment-planner/scripts/feature-utils.js +26 -5
  47. package/plugins/specweave-ado/skills/ado-sync/SKILL.md +2 -2
  48. package/plugins/specweave-figma/ARCHITECTURE.md +1 -1
  49. package/plugins/specweave-figma/README.md +1 -1
  50. package/plugins/specweave-ml/README.md +1 -1
  51. package/src/templates/CLAUDE.md.template +8 -9
  52. package/plugins/specweave-github/hooks/post-increment-done.sh +0 -224
@@ -149,12 +149,19 @@ User: "I want to build real-time price tracking"
149
149
 
150
150
  increment-planner skill
151
151
 
152
- STEP 1: Scan existing docs
152
+ STEP 1: Determine increment number and check for duplicates
153
+ ├─ Use the Bash tool to run: node plugins/specweave/skills/increment-planner/scripts/feature-utils.js next
154
+ ├─ Get next available increment number (e.g., "0021")
155
+ ├─ Get short name from user description
156
+ ├─ Check if increment already exists using: node plugins/specweave/skills/increment-planner/scripts/feature-utils.js check-increment {number}
157
+ └─ If duplicate found, STOP and tell user: "Increment {number} already exists! Please use the existing increment."
158
+
159
+ STEP 2: Scan existing docs
153
160
  ├─ Read .specweave/docs/internal/strategy/ (existing requirements)
154
161
  ├─ Read .specweave/docs/internal/architecture/adr/ (existing decisions)
155
162
  └─ Pass existing context to agents
156
163
 
157
- STEP 2: Invoke PM Agent (🚨 MANDATORY - USE TASK TOOL)
164
+ STEP 3: Invoke PM Agent (🚨 MANDATORY - USE TASK TOOL)
158
165
 
159
166
  YOU MUST USE THE TASK TOOL - DO NOT SKIP:
160
167
 
@@ -206,7 +213,7 @@ Task(
206
213
 
207
214
  Wait for PM agent to complete!
208
215
 
209
- STEP 3: Invoke Architect Agent (🚨 MANDATORY - USE TASK TOOL)
216
+ STEP 4: Invoke Architect Agent (🚨 MANDATORY - USE TASK TOOL)
210
217
 
211
218
  YOU MUST USE THE TASK TOOL - DO NOT SKIP:
212
219
 
@@ -239,7 +246,7 @@ Task(
239
246
 
240
247
  Wait for Architect agent to complete!
241
248
 
242
- STEP 4: Invoke Test-Aware Planner Agent (🚨 MANDATORY - USE TASK TOOL)
249
+ STEP 5: Invoke Test-Aware Planner Agent (🚨 MANDATORY - USE TASK TOOL)
243
250
 
244
251
  YOU MUST USE THE TASK TOOL - DO NOT SKIP:
245
252
 
@@ -275,7 +282,7 @@ Task(
275
282
 
276
283
  Wait for test-aware-planner agent to complete!
277
284
 
278
- STEP 5: Validate Living Docs and Increment Files
285
+ STEP 6: Validate Living Docs and Increment Files
279
286
  ├─ Check .specweave/docs/internal/specs/spec-{number}-{name}/spec.md exists (SOURCE OF TRUTH)
280
287
  ├─ Check living spec.md contains ALL user stories, requirements, AC-IDs (with AC-IDs)
281
288
  ├─ Check .specweave/docs/internal/architecture/adr/ has ≥3 ADRs
@@ -3,8 +3,12 @@
3
3
  * Supports increment-planner skill with auto-numbering and name generation
4
4
  */
5
5
 
6
- const fs = require('fs');
7
- const path = require('path');
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ import { fileURLToPath } from 'url';
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
8
12
 
9
13
  /**
10
14
  * Stop words to filter from feature descriptions
@@ -198,7 +202,7 @@ function parseFeatureDescription(description) {
198
202
  };
199
203
  }
200
204
 
201
- module.exports = {
205
+ export {
202
206
  generateShortName,
203
207
  getNextFeatureNumber,
204
208
  featureExists,
@@ -210,8 +214,8 @@ module.exports = {
210
214
  STOP_WORDS
211
215
  };
212
216
 
213
- // CLI usage
214
- if (require.main === module) {
217
+ // CLI usage - check if this file is being run directly
218
+ if (import.meta.url === `file://${process.argv[1]}`) {
215
219
  const args = process.argv.slice(2);
216
220
 
217
221
  if (args.length === 0) {
@@ -219,6 +223,7 @@ if (require.main === module) {
219
223
  console.log(' node feature-utils.js shortname "feature description"');
220
224
  console.log(' node feature-utils.js next [features-dir]');
221
225
  console.log(' node feature-utils.js parse "feature description"');
226
+ console.log(' node feature-utils.js check-increment <number> [features-dir]');
222
227
  process.exit(0);
223
228
  }
224
229
 
@@ -243,6 +248,22 @@ if (require.main === module) {
243
248
  }
244
249
  break;
245
250
 
251
+ case 'check-increment':
252
+ if (args[1]) {
253
+ const incrementNumber = args[1];
254
+ const checkDir = args[2] || '.specweave/increments';
255
+ if (incrementNumberExists(incrementNumber, checkDir)) {
256
+ console.error(`ERROR: Increment ${incrementNumber} already exists!`);
257
+ process.exit(1);
258
+ } else {
259
+ console.log(`OK: Increment ${incrementNumber} is available`);
260
+ }
261
+ } else {
262
+ console.error('Error: Increment number required');
263
+ process.exit(1);
264
+ }
265
+ break;
266
+
246
267
  default:
247
268
  console.error(`Unknown command: ${command}`);
248
269
  process.exit(1);
@@ -47,7 +47,7 @@ description: Bidirectional synchronization between SpecWeave increments and Azur
47
47
  /plugin list --installed | grep specweave-ado
48
48
 
49
49
  # Install if needed
50
- /plugin install specweave-ado@specweave
50
+ /plugin install specweave-ado
51
51
  ```
52
52
 
53
53
  ### 2. Azure DevOps Personal Access Token (PAT)
@@ -403,4 +403,4 @@ Sync Enabled: ✅
403
403
 
404
404
  **Status**: Ready to use
405
405
  **Version**: 0.1.0
406
- **Plugin**: specweave-ado@specweave
406
+ **Plugin**: specweave-ado
@@ -287,7 +287,7 @@ specweave plugin install figma
287
287
  **Via Claude Code**:
288
288
  ```bash
289
289
  /plugin marketplace add specweave/marketplace
290
- /plugin install specweave-figma@specweave
290
+ /plugin install specweave-figma
291
291
  ```
292
292
 
293
293
  ### Verify Installation
@@ -102,7 +102,7 @@ specweave plugin list
102
102
  /plugin marketplace add https://raw.githubusercontent.com/anton-abyzov/specweave/main/marketplace/.claude-plugin/marketplace.json
103
103
 
104
104
  # Install figma plugin
105
- /plugin install specweave-figma@specweave
105
+ /plugin install specweave-figma
106
106
 
107
107
  # Verify
108
108
  /plugin list
@@ -28,7 +28,7 @@ Brings the same engineering discipline to ML that SpecWeave brings to software:
28
28
 
29
29
  ```bash
30
30
  # Install SpecWeave ML plugin
31
- /plugin install specweave-ml@specweave
31
+ /plugin install specweave-ml
32
32
 
33
33
  # Verify installation
34
34
  /plugin list
@@ -208,11 +208,10 @@ Both approaches work perfectly - use whichever feels more natural!
208
208
  ### Increment Structure
209
209
 
210
210
  ```
211
- .specweave/increments/0001-user-auth/
211
+ .specweave/increments/0001-user-auth/ # ⚠️ ID must be unique!
212
212
  ├── spec.md # WHAT & WHY
213
213
  ├── plan.md # HOW
214
- ├── tasks.md # Implementation steps
215
- ├── tests.md # Test strategy
214
+ ├── tasks.md # Implementation steps with embedded tests
216
215
  ├── context-manifest.yaml # Selective context loading
217
216
  ├── logs/ # ✅ Execution logs, errors, AI sessions
218
217
  ├── scripts/ # ✅ Helper scripts, migrations, setup
@@ -278,12 +277,11 @@ Config: Auto-detected from project files
278
277
  │ │ │ ├── operations/ # Runbooks, monitoring
279
278
  │ │ │ └── governance/ # Security, compliance
280
279
  │ │ └── public/ # Published docs
281
- │ ├── increments/ # Features (auto-numbered)
282
- │ │ └── 0001-feature-name/
283
- │ │ ├── spec.md
284
- │ │ ├── plan.md
285
- │ │ ├── tasks.md
286
- │ │ ├── tests.md
280
+ │ ├── increments/ # Features (auto-numbered, UNIQUE IDs)
281
+ │ │ └── 0001-feature-name/ # ⚠️ Each ID must be unique (0001-9999)
282
+ │ │ ├── spec.md # What we're building
283
+ │ │ ├── plan.md # How we'll build it
284
+ │ │ ├── tasks.md # Tasks with embedded tests
287
285
  │ │ ├── logs/ # ✅ Put logs here
288
286
  │ │ ├── scripts/ # ✅ Put scripts here
289
287
  │ │ └── reports/ # ✅ Put reports here
@@ -436,6 +434,7 @@ Plugins are detected and suggested during `specweave init` based on:
436
434
  4. **Validated**: Every increment validated before closure
437
435
  5. **Traceable**: All work traces back to specs and requirements
438
436
  6. **Clean Organization**: All supporting files in increment folders, never root
437
+ 7. **No Duplicate Increments**: Each increment must have a unique 4-digit ID (0001-9999)
439
438
 
440
439
  ---
441
440
 
@@ -1,224 +0,0 @@
1
- #!/bin/bash
2
- # Post-Increment-Done Hook - GitHub Plugin
3
- #
4
- # Purpose: Automatically syncs living docs spec to GitHub Project when increment closes
5
- #
6
- # Triggered by: /specweave:done command completion
7
- # Event: PostSlashCommand (commandName: "specweave:done")
8
- #
9
- # Flow:
10
- # 1. Increment closes → PM validates
11
- # 2. Hook fires automatically
12
- # 3. Syncs living docs spec to GitHub Project
13
- # 4. Closes GitHub Issue (if exists)
14
- #
15
- # Configuration (.specweave/config.json):
16
- # "hooks": {
17
- # "post_increment_done": {
18
- # "sync_to_github_project": true,
19
- # "close_github_issue": true,
20
- # "update_living_docs_first": true
21
- # }
22
- # }
23
-
24
- set -e
25
-
26
- # ============================================================================
27
- # Configuration & Logging
28
- # ============================================================================
29
-
30
- INCREMENT_ID="$1"
31
- HOOK_NAME="post-increment-done"
32
- LOG_DIR=".specweave/logs"
33
- LOG_FILE="${LOG_DIR}/hooks-debug.log"
34
- CONFIG_FILE=".specweave/config.json"
35
-
36
- # Ensure log directory exists
37
- mkdir -p "${LOG_DIR}"
38
-
39
- # Logging function
40
- log() {
41
- local level="$1"
42
- shift
43
- local message="$*"
44
- local timestamp
45
- timestamp=$(date '+%Y-%m-%d %H:%M:%S')
46
- echo "[${timestamp}] [${HOOK_NAME}] [${level}] ${message}" | tee -a "${LOG_FILE}"
47
- }
48
-
49
- log "INFO" "=========================================="
50
- log "INFO" "Post-Increment-Done Hook Started"
51
- log "INFO" "Increment: ${INCREMENT_ID}"
52
- log "INFO" "=========================================="
53
-
54
- # ============================================================================
55
- # Validation & Configuration
56
- # ============================================================================
57
-
58
- # Check if increment ID provided
59
- if [ -z "$INCREMENT_ID" ]; then
60
- log "ERROR" "No increment ID provided to hook"
61
- exit 0
62
- fi
63
-
64
- # Normalize increment ID to 4-digit format
65
- # First strip leading zeros to avoid octal interpretation (0019 → 19)
66
- INCREMENT_ID_NUM=$(echo "$INCREMENT_ID" | sed 's/^0*//')
67
- # Then normalize to 4-digit format (19 → 0019)
68
- INCREMENT_ID=$(printf "%04d" "$INCREMENT_ID_NUM" 2>/dev/null || echo "$INCREMENT_ID")
69
-
70
- # Find increment directory (format: 0019-name or 0019)
71
- INCREMENT_DIR=$(find .specweave/increments/ -maxdepth 1 -type d -name "${INCREMENT_ID}*" | head -1)
72
-
73
- if [ -z "$INCREMENT_DIR" ] || [ ! -d "$INCREMENT_DIR" ]; then
74
- log "WARN" "Increment directory not found for ID: ${INCREMENT_ID}"
75
- exit 0
76
- fi
77
-
78
- log "INFO" "Found increment directory: ${INCREMENT_DIR}"
79
-
80
- # Read configuration
81
- if [ ! -f "$CONFIG_FILE" ]; then
82
- log "WARN" "Config file not found: ${CONFIG_FILE}"
83
- exit 0
84
- fi
85
-
86
- # Check if GitHub Project sync is enabled
87
- SYNC_ENABLED=$(node -pe "
88
- try {
89
- const config = require('./${CONFIG_FILE}');
90
- config.hooks?.post_increment_done?.sync_to_github_project || false;
91
- } catch (e) {
92
- false;
93
- }
94
- " 2>/dev/null || echo "false")
95
-
96
- log "INFO" "GitHub Project sync enabled: ${SYNC_ENABLED}"
97
-
98
- if [ "$SYNC_ENABLED" != "true" ]; then
99
- log "INFO" "GitHub Project sync disabled, skipping"
100
- exit 0
101
- fi
102
-
103
- # Check if GitHub CLI is available
104
- if ! command -v gh &> /dev/null; then
105
- log "WARN" "GitHub CLI (gh) not found, skipping sync"
106
- exit 0
107
- fi
108
-
109
- # Check if gh is authenticated
110
- if ! gh auth status &> /dev/null; then
111
- log "WARN" "GitHub CLI not authenticated, skipping sync"
112
- exit 0
113
- fi
114
-
115
- # ============================================================================
116
- # Find Living Docs Spec
117
- # ============================================================================
118
-
119
- log "INFO" "Finding living docs spec for increment ${INCREMENT_ID}..."
120
-
121
- # Pattern 1: spec-NNNN-name.md (e.g., spec-0018-strict-increment-discipline.md)
122
- SPEC_FILE=$(find .specweave/docs/internal/specs/ -name "spec-${INCREMENT_ID}*.md" 2>/dev/null | head -1)
123
-
124
- # Pattern 2: spec-NNN-name.md (e.g., spec-018-strict-increment-discipline.md)
125
- if [ -z "$SPEC_FILE" ]; then
126
- INCREMENT_ID_3DIGIT=$(printf "%03d" "$INCREMENT_ID" 2>/dev/null || echo "$INCREMENT_ID")
127
- SPEC_FILE=$(find .specweave/docs/internal/specs/ -name "spec-${INCREMENT_ID_3DIGIT}*.md" 2>/dev/null | head -1)
128
- fi
129
-
130
- # Pattern 3: Check increment spec.md for living docs reference
131
- if [ -z "$SPEC_FILE" ] && [ -f "${INCREMENT_DIR}/spec.md" ]; then
132
- log "INFO" "Checking increment spec.md for living docs reference..."
133
- SPEC_REFERENCE=$(grep -E "Living Docs:.*spec-[0-9]+" "${INCREMENT_DIR}/spec.md" | grep -oE "spec-[0-9]+-[a-z-]+" | head -1)
134
- if [ -n "$SPEC_REFERENCE" ]; then
135
- SPEC_FILE=$(find .specweave/docs/internal/specs/ -name "${SPEC_REFERENCE}.md" 2>/dev/null | head -1)
136
- fi
137
- fi
138
-
139
- if [ -z "$SPEC_FILE" ]; then
140
- log "WARN" "No living docs spec found for increment ${INCREMENT_ID}"
141
- log "INFO" "This is OK for bug/hotfix increments that don't create new specs"
142
- exit 0
143
- fi
144
-
145
- log "INFO" "Found living docs spec: ${SPEC_FILE}"
146
-
147
- # ============================================================================
148
- # Sync to GitHub Project
149
- # ============================================================================
150
-
151
- log "INFO" "🔄 Syncing living docs spec to GitHub Project..."
152
-
153
- # Extract spec ID from filename (e.g., spec-018-name.md → 018)
154
- SPEC_ID=$(basename "$SPEC_FILE" | grep -oE "spec-[0-9]+" | grep -oE "[0-9]+")
155
-
156
- log "INFO" "Spec ID: ${SPEC_ID}"
157
-
158
- # Call the sync-spec command
159
- # NOTE: This assumes /specweave-github:sync-spec command exists
160
- # If not implemented yet, this will gracefully fail
161
- if npx specweave sync-spec "$SPEC_FILE" >> "${LOG_FILE}" 2>&1; then
162
- log "INFO" "✅ GitHub Project synced successfully"
163
- else
164
- log "WARN" "Failed to sync to GitHub Project (command may not exist yet)"
165
- log "INFO" "Manual sync: /specweave-github:sync-spec ${SPEC_FILE}"
166
- fi
167
-
168
- # ============================================================================
169
- # Close GitHub Issue (Optional)
170
- # ============================================================================
171
-
172
- CLOSE_ISSUE=$(node -pe "
173
- try {
174
- const config = require('./${CONFIG_FILE}');
175
- config.hooks?.post_increment_done?.close_github_issue || false;
176
- } catch (e) {
177
- false;
178
- }
179
- " 2>/dev/null || echo "false")
180
-
181
- log "INFO" "Close GitHub issue enabled: ${CLOSE_ISSUE}"
182
-
183
- if [ "$CLOSE_ISSUE" = "true" ]; then
184
- # Check if increment has GitHub issue metadata
185
- METADATA_FILE="${INCREMENT_DIR}/.metadata.json"
186
-
187
- if [ -f "$METADATA_FILE" ]; then
188
- ISSUE_NUMBER=$(node -pe "
189
- try {
190
- const metadata = require('./${METADATA_FILE}');
191
- metadata.github?.issue || '';
192
- } catch (e) {
193
- '';
194
- }
195
- " 2>/dev/null || echo "")
196
-
197
- if [ -n "$ISSUE_NUMBER" ]; then
198
- log "INFO" "Closing GitHub issue #${ISSUE_NUMBER}..."
199
-
200
- # Close issue via gh CLI
201
- if gh issue close "$ISSUE_NUMBER" --comment "✅ Increment ${INCREMENT_ID} completed and closed" >> "${LOG_FILE}" 2>&1; then
202
- log "INFO" "✅ GitHub issue #${ISSUE_NUMBER} closed"
203
- else
204
- log "WARN" "Failed to close GitHub issue #${ISSUE_NUMBER}"
205
- fi
206
- else
207
- log "INFO" "No GitHub issue found in metadata"
208
- fi
209
- else
210
- log "INFO" "No metadata file found: ${METADATA_FILE}"
211
- fi
212
- fi
213
-
214
- # ============================================================================
215
- # Completion
216
- # ============================================================================
217
-
218
- log "INFO" "=========================================="
219
- log "INFO" "Post-Increment-Done Hook Completed"
220
- log "INFO" "Increment: ${INCREMENT_ID}"
221
- log "INFO" "Spec: ${SPEC_FILE}"
222
- log "INFO" "=========================================="
223
-
224
- exit 0