specweave 0.22.2 → 0.22.3

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 +162 -13
  2. package/dist/src/cli/commands/repair-status-desync.d.ts +69 -0
  3. package/dist/src/cli/commands/repair-status-desync.d.ts.map +1 -0
  4. package/dist/src/cli/commands/repair-status-desync.js +221 -0
  5. package/dist/src/cli/commands/repair-status-desync.js.map +1 -0
  6. package/dist/src/cli/commands/validate-status-sync.d.ts +52 -0
  7. package/dist/src/cli/commands/validate-status-sync.d.ts.map +1 -0
  8. package/dist/src/cli/commands/validate-status-sync.js +176 -0
  9. package/dist/src/cli/commands/validate-status-sync.js.map +1 -0
  10. package/dist/src/cli/update-status-line.d.ts +16 -0
  11. package/dist/src/cli/update-status-line.d.ts.map +1 -0
  12. package/dist/src/cli/update-status-line.js +44 -0
  13. package/dist/src/cli/update-status-line.js.map +1 -0
  14. package/dist/src/core/increment/completion-validator.d.ts +56 -0
  15. package/dist/src/core/increment/completion-validator.d.ts.map +1 -0
  16. package/dist/src/core/increment/completion-validator.js +102 -0
  17. package/dist/src/core/increment/completion-validator.js.map +1 -0
  18. package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
  19. package/dist/src/core/increment/metadata-manager.js +10 -0
  20. package/dist/src/core/increment/metadata-manager.js.map +1 -1
  21. package/dist/src/core/increment/spec-frontmatter-updater.d.ts +78 -0
  22. package/dist/src/core/increment/spec-frontmatter-updater.d.ts.map +1 -0
  23. package/dist/src/core/increment/spec-frontmatter-updater.js +152 -0
  24. package/dist/src/core/increment/spec-frontmatter-updater.js.map +1 -0
  25. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  26. package/dist/src/core/living-docs/living-docs-sync.js +2 -1
  27. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  28. package/dist/src/core/status-line/status-line-manager.d.ts +3 -2
  29. package/dist/src/core/status-line/status-line-manager.d.ts.map +1 -1
  30. package/dist/src/core/status-line/status-line-manager.js +40 -17
  31. package/dist/src/core/status-line/status-line-manager.js.map +1 -1
  32. package/dist/src/core/status-line/status-line-updater.d.ts +67 -0
  33. package/dist/src/core/status-line/status-line-updater.d.ts.map +1 -0
  34. package/dist/src/core/status-line/status-line-updater.js +203 -0
  35. package/dist/src/core/status-line/status-line-updater.js.map +1 -0
  36. package/dist/src/core/status-line/types.d.ts +19 -5
  37. package/dist/src/core/status-line/types.d.ts.map +1 -1
  38. package/dist/src/core/status-line/types.js +3 -3
  39. package/dist/src/core/status-line/types.js.map +1 -1
  40. package/package.json +1 -1
  41. package/plugins/specweave/commands/specweave-done.md +60 -4
  42. package/plugins/specweave/commands/specweave-reopen.md +29 -2
  43. package/plugins/specweave/commands/specweave-sync-docs.md +71 -4
  44. package/plugins/specweave/commands/specweave-update-status.md +151 -0
  45. package/plugins/specweave/hooks/lib/update-status-line.sh +34 -6
  46. package/plugins/specweave/hooks/user-prompt-submit.sh +21 -0
  47. package/plugins/specweave/hooks/validate-increment-completion.sh +113 -0
  48. package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
  49. package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +21 -0
  50. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
  51. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -170
  52. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +0 -3222
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Status Line Updater
3
+ *
4
+ * Synchronously updates status line cache by scanning spec.md files.
5
+ * Equivalent to update-status-line.sh but runs SYNCHRONOUSLY.
6
+ *
7
+ * Purpose: Force-refresh status line when it appears stale
8
+ *
9
+ * Architecture:
10
+ * 1. Scan all spec.md files for open increments (status = active/planning/in-progress)
11
+ * 2. Sort by creation date (oldest first)
12
+ * 3. Select first as current increment
13
+ * 4. Parse tasks.md for progress (use TaskCounter for accuracy)
14
+ * 5. Write cache atomically (.specweave/state/status-line.json)
15
+ *
16
+ * Performance: ~50-100ms (acceptable for user-facing commands)
17
+ */
18
+ import fs from 'fs-extra';
19
+ import * as path from 'path';
20
+ import { TaskCounter } from './task-counter.js';
21
+ /**
22
+ * Maximum number of active increments to display in status line
23
+ * Aligned with ActiveIncrementManager maximum
24
+ */
25
+ const MAX_ACTIVE_INCREMENTS_DISPLAY = 2;
26
+ /**
27
+ * Status Line Updater
28
+ *
29
+ * Provides synchronous status line cache updates.
30
+ */
31
+ export class StatusLineUpdater {
32
+ constructor(rootDir = process.cwd()) {
33
+ this.rootDir = rootDir;
34
+ }
35
+ /**
36
+ * Update status line cache synchronously
37
+ *
38
+ * This is the main entry point for force-refreshing the status line.
39
+ * NOW supports up to 2 active increments (aligned with ActiveIncrementManager).
40
+ */
41
+ async update() {
42
+ // Step 1: Find all open increments (scan spec.md)
43
+ const openIncrements = await this.findOpenIncrements();
44
+ // Step 2: Sort by creation date (oldest first)
45
+ const sorted = openIncrements.sort((a, b) => {
46
+ const aTime = new Date(a.created).getTime();
47
+ const bTime = new Date(b.created).getTime();
48
+ return aTime - bTime; // Ascending (oldest first)
49
+ });
50
+ // Step 3: Take up to MAX_ACTIVE_INCREMENTS_DISPLAY active increments
51
+ const activeIds = sorted.slice(0, MAX_ACTIVE_INCREMENTS_DISPLAY);
52
+ // Step 4: Parse tasks.md for EACH active increment
53
+ const activeIncrements = await Promise.all(activeIds.map(async (inc) => {
54
+ const progress = await this.parseTaskProgress(inc.id);
55
+ return {
56
+ id: inc.id,
57
+ name: inc.id, // Format: "0043-spec-md-desync-fix"
58
+ completed: progress.completed,
59
+ total: progress.total,
60
+ percentage: progress.percentage
61
+ };
62
+ }));
63
+ // Step 5: Build cache object
64
+ const cache = {
65
+ activeIncrements,
66
+ openCount: openIncrements.length,
67
+ lastUpdate: new Date().toISOString(),
68
+ // BACKWARD COMPATIBILITY: Set 'current' to first active increment
69
+ current: activeIncrements[0] || null,
70
+ // Add default state message when no active increments
71
+ message: openIncrements.length === 0
72
+ ? 'No active increments. Start with /specweave:increment "feature name"'
73
+ : undefined
74
+ };
75
+ // Step 6: Write cache atomically
76
+ await this.writeCache(cache);
77
+ }
78
+ /**
79
+ * Find all open increments by scanning spec.md files
80
+ *
81
+ * Logic:
82
+ * - Scan .specweave/increments/[id]/spec.md
83
+ * - Parse YAML frontmatter for status field
84
+ * - Filter: status === 'active' || 'planning' || 'in-progress'
85
+ * - Extract: {id, created, status}
86
+ */
87
+ async findOpenIncrements() {
88
+ const incrementsDir = path.join(this.rootDir, '.specweave/increments');
89
+ if (!await fs.pathExists(incrementsDir)) {
90
+ return [];
91
+ }
92
+ const entries = await fs.readdir(incrementsDir);
93
+ const openIncrements = [];
94
+ for (const entry of entries) {
95
+ // Skip special directories (_archive, etc.)
96
+ if (entry.startsWith('_')) {
97
+ continue;
98
+ }
99
+ const specPath = path.join(incrementsDir, entry, 'spec.md');
100
+ if (await fs.pathExists(specPath)) {
101
+ const specContent = await fs.readFile(specPath, 'utf-8');
102
+ const metadata = this.parseSpecMetadata(specContent);
103
+ // Check if increment is open (active, planning, or in-progress)
104
+ // ONLY accepts official IncrementStatus enum values
105
+ if (metadata.status === 'active' ||
106
+ metadata.status === 'planning' ||
107
+ metadata.status === 'in-progress') {
108
+ openIncrements.push({
109
+ id: entry,
110
+ created: metadata.created || '1970-01-01',
111
+ status: metadata.status
112
+ });
113
+ }
114
+ }
115
+ }
116
+ return openIncrements;
117
+ }
118
+ /**
119
+ * Parse spec.md YAML frontmatter
120
+ *
121
+ * Extracts: status, created
122
+ */
123
+ parseSpecMetadata(content) {
124
+ const metadata = {
125
+ status: '',
126
+ created: '1970-01-01'
127
+ };
128
+ // Extract YAML frontmatter (between --- markers)
129
+ const frontmatterMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
130
+ if (!frontmatterMatch) {
131
+ return metadata;
132
+ }
133
+ const frontmatter = frontmatterMatch[1];
134
+ // Parse status field
135
+ const statusMatch = frontmatter.match(/^status:\s*(.+)$/m);
136
+ if (statusMatch) {
137
+ metadata.status = statusMatch[1].trim();
138
+ }
139
+ // Parse created field
140
+ const createdMatch = frontmatter.match(/^created:\s*(.+)$/m);
141
+ if (createdMatch) {
142
+ metadata.created = createdMatch[1].trim();
143
+ }
144
+ return metadata;
145
+ }
146
+ /**
147
+ * Parse tasks.md for progress
148
+ *
149
+ * Uses TaskCounter for accurate counting (fixes overcounting bug)
150
+ */
151
+ async parseTaskProgress(incrementId) {
152
+ const tasksPath = path.join(this.rootDir, '.specweave/increments', incrementId, 'tasks.md');
153
+ if (!await fs.pathExists(tasksPath)) {
154
+ return { completed: 0, total: 0, percentage: 0 };
155
+ }
156
+ try {
157
+ const tasksContent = await fs.readFile(tasksPath, 'utf-8');
158
+ const counts = TaskCounter.countTasks(tasksContent);
159
+ return {
160
+ completed: counts.completed,
161
+ total: counts.total,
162
+ percentage: counts.percentage
163
+ };
164
+ }
165
+ catch (error) {
166
+ // Graceful degradation: If TaskCounter fails, return zeros
167
+ console.warn(`⚠️ Failed to parse tasks.md for ${incrementId}:`, error);
168
+ return { completed: 0, total: 0, percentage: 0 };
169
+ }
170
+ }
171
+ /**
172
+ * Write cache atomically
173
+ *
174
+ * Uses temp file → rename pattern to prevent corruption
175
+ */
176
+ async writeCache(cache) {
177
+ const cacheFile = path.join(this.rootDir, '.specweave/state/status-line.json');
178
+ const cacheDir = path.dirname(cacheFile);
179
+ // Ensure state directory exists
180
+ await fs.ensureDir(cacheDir);
181
+ // Atomic write: temp file → rename
182
+ const tempFile = `${cacheFile}.tmp`;
183
+ await fs.writeFile(tempFile, JSON.stringify(cache, null, 2), 'utf-8');
184
+ await fs.rename(tempFile, cacheFile);
185
+ }
186
+ /**
187
+ * Get current cache (for testing)
188
+ */
189
+ async getCurrentCache() {
190
+ const cacheFile = path.join(this.rootDir, '.specweave/state/status-line.json');
191
+ if (!await fs.pathExists(cacheFile)) {
192
+ return null;
193
+ }
194
+ try {
195
+ const content = await fs.readFile(cacheFile, 'utf-8');
196
+ return JSON.parse(content);
197
+ }
198
+ catch {
199
+ return null;
200
+ }
201
+ }
202
+ }
203
+ //# sourceMappingURL=status-line-updater.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-line-updater.js","sourceRoot":"","sources":["../../../../src/core/status-line/status-line-updater.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoBhD;;;GAGG;AACH,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAExC;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAC5B,YAAoB,UAAkB,OAAO,CAAC,GAAG,EAAE;QAA/B,YAAO,GAAP,OAAO,CAAwB;IAAG,CAAC;IAEvD;;;;;OAKG;IACH,KAAK,CAAC,MAAM;QACV,kDAAkD;QAClD,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAEvD,+CAA+C;QAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;YAC5C,OAAO,KAAK,GAAG,KAAK,CAAC,CAAC,2BAA2B;QACnD,CAAC,CAAC,CAAC;QAEH,qEAAqE;QACrE,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,6BAA6B,CAAC,CAAC;QAEjE,mDAAmD;QACnD,MAAM,gBAAgB,GAAuB,MAAM,OAAO,CAAC,GAAG,CAC5D,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAC1B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACtD,OAAO;gBACL,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,oCAAoC;gBAClD,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;aAChC,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,6BAA6B;QAC7B,MAAM,KAAK,GAAoB;YAC7B,gBAAgB;YAChB,SAAS,EAAE,cAAc,CAAC,MAAM;YAChC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAEpC,kEAAkE;YAClE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,IAAI;YAEpC,sDAAsD;YACtD,OAAO,EAAE,cAAc,CAAC,MAAM,KAAK,CAAC;gBAClC,CAAC,CAAC,sEAAsE;gBACxE,CAAC,CAAC,SAAS;SACd,CAAC;QAEF,iCAAiC;QACjC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,kBAAkB;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;QAEvE,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAChD,MAAM,cAAc,GAAoB,EAAE,CAAC;QAE3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,4CAA4C;YAC5C,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,SAAS;YACX,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;YAE5D,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAClC,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;gBAErD,gEAAgE;gBAChE,oDAAoD;gBACpD,IACE,QAAQ,CAAC,MAAM,KAAK,QAAQ;oBAC5B,QAAQ,CAAC,MAAM,KAAK,UAAU;oBAC9B,QAAQ,CAAC,MAAM,KAAK,aAAa,EACjC,CAAC;oBACD,cAAc,CAAC,IAAI,CAAC;wBAClB,EAAE,EAAE,KAAK;wBACT,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,YAAY;wBACzC,MAAM,EAAE,QAAQ,CAAC,MAAM;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACK,iBAAiB,CAAC,OAAe;QACvC,MAAM,QAAQ,GAAwC;YACpD,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,YAAY;SACtB,CAAC;QAEF,iDAAiD;QACjD,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACnE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAExC,qBAAqB;QACrB,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC3D,IAAI,WAAW,EAAE,CAAC;YAChB,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,CAAC;QAED,sBAAsB;QACtB,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAC7D,IAAI,YAAY,EAAE,CAAC;YACjB,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,iBAAiB,CAAC,WAAmB;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QAE5F,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QACnD,CAAC;QAED,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC3D,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YAEpD,OAAO;gBACL,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,2DAA2D;YAC3D,OAAO,CAAC,IAAI,CAAC,oCAAoC,WAAW,GAAG,EAAE,KAAK,CAAC,CAAC;YACxE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QACnD,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,UAAU,CAAC,KAAsB;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mCAAmC,CAAC,CAAC;QAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzC,gCAAgC;QAChC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAE7B,mCAAmC;QACnC,MAAM,QAAQ,GAAG,GAAG,SAAS,MAAM,CAAC;QACpC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACtE,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mCAAmC,CAAC,CAAC;QAE/E,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACtD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
@@ -1,16 +1,26 @@
1
1
  /**
2
- * Status Line Types (Simplified)
2
+ * Status Line Types
3
3
  *
4
- * Ultra-simple status line with cached progress.
5
- * Shows: [increment-name] ████░░░░ X/Y tasks (Z open)
4
+ * Supports displaying multiple active increments (up to 2).
5
+ * Shows: [inc-1] ████░░░░ X/Y | [inc-2] ██████░░ A/B (Z open)
6
6
  */
7
7
  export interface StatusLineCache {
8
- /** Current active/in-progress increment (null if none) */
9
- current: CurrentIncrement | null;
8
+ /** NEW: Array of active increments (up to 2) */
9
+ activeIncrements: CurrentIncrement[];
10
10
  /** Total number of open increments (active/in-progress/planning) */
11
11
  openCount: number;
12
12
  /** ISO timestamp of last cache update */
13
13
  lastUpdate: string;
14
+ /**
15
+ * DEPRECATED: Use activeIncrements[0] instead
16
+ * Kept for backward compatibility with old code
17
+ */
18
+ current?: CurrentIncrement | null;
19
+ /**
20
+ * Optional message to display when no active increments
21
+ * Used for user guidance when openCount === 0
22
+ */
23
+ message?: string;
14
24
  }
15
25
  export interface CurrentIncrement {
16
26
  /** Increment ID (e.g., "0031-external-tool-status-sync") */
@@ -23,6 +33,10 @@ export interface CurrentIncrement {
23
33
  total: number;
24
34
  /** Completion percentage (0-100) */
25
35
  percentage: number;
36
+ /** Number of completed acceptance criteria (NEW) */
37
+ acsCompleted?: number;
38
+ /** Total number of acceptance criteria (NEW) */
39
+ acsTotal?: number;
26
40
  }
27
41
  export interface StatusLineConfig {
28
42
  /** Enable status line rendering */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/status-line/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAEjC,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAElB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IAEX,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IAEb,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAElB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IAEd,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IAEjB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IAEpB,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,0BAA0B,EAAE,gBAKxC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/status-line/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IAErC,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAElB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAElC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IAEX,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IAEb,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAElB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IAEd,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IAEnB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IAEjB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IAEpB,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,0BAA0B,EAAE,gBAKxC,CAAC"}
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Status Line Types (Simplified)
2
+ * Status Line Types
3
3
  *
4
- * Ultra-simple status line with cached progress.
5
- * Shows: [increment-name] ████░░░░ X/Y tasks (Z open)
4
+ * Supports displaying multiple active increments (up to 2).
5
+ * Shows: [inc-1] ████░░░░ X/Y | [inc-2] ██████░░ A/B (Z open)
6
6
  */
7
7
  export const DEFAULT_STATUS_LINE_CONFIG = {
8
8
  enabled: true,
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/status-line/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4CH,MAAM,CAAC,MAAM,0BAA0B,GAAqB;IAC1D,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,KAAK,EAAE,oCAAoC;IACxD,gBAAgB,EAAE,CAAC;IACnB,aAAa,EAAE,EAAE;CAClB,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/status-line/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8DH,MAAM,CAAC,MAAM,0BAA0B,GAAqB;IAC1D,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,KAAK,EAAE,oCAAoC;IACxD,gBAAgB,EAAE,CAAC;IACnB,aAAa,EAAE,EAAE;CAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specweave",
3
- "version": "0.22.2",
3
+ "version": "0.22.3",
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",
@@ -51,7 +51,63 @@ You are acting as the Product Manager to validate increment completion before cl
51
51
  🎯 Validating readiness for closure...
52
52
  ```
53
53
 
54
- ### Step 2: PM Validation (3 Gates)
54
+ ### Step 2: Automated Completion Validation (Gate 0)
55
+
56
+ **🔥 CRITICAL: Automated validation runs BEFORE PM validation to catch obvious issues!**
57
+
58
+ **BEFORE** invoking the PM agent, run automated validation using `IncrementCompletionValidator`:
59
+
60
+ ```typescript
61
+ import { IncrementCompletionValidator } from '../../../src/core/increment/completion-validator.js';
62
+
63
+ // Validate increment is ready for completion
64
+ const validation = await IncrementCompletionValidator.validateCompletion(incrementId);
65
+
66
+ if (!validation.isValid) {
67
+ // BLOCK completion and show errors
68
+ console.error('❌ CANNOT CLOSE INCREMENT - Automated validation failed');
69
+ console.error('');
70
+ validation.errors.forEach(err => console.error(` • ${err}`));
71
+ console.error('');
72
+ console.error('Fix these issues before running /specweave:done again');
73
+ process.exit(1);
74
+ }
75
+ ```
76
+
77
+ **Example validation output** (FAIL):
78
+ ```
79
+ ❌ CANNOT CLOSE INCREMENT - Automated validation failed
80
+
81
+ • 17 acceptance criteria still open
82
+ • 13 tasks still pending
83
+
84
+ Fix these issues before running /specweave:done again
85
+ ```
86
+
87
+ **Example validation output** (PASS):
88
+ ```
89
+ ✅ Automated validation passed
90
+ • All acceptance criteria completed
91
+ • All tasks completed
92
+
93
+ Proceeding to PM validation...
94
+ ```
95
+
96
+ **What Gate 0 validates**:
97
+ - [ ] All acceptance criteria are checked (`- [x] **AC-...`)
98
+ - [ ] All tasks are completed (`**Status**: [x] completed`)
99
+ - [ ] Required files exist (`spec.md`, `tasks.md`)
100
+
101
+ **Why Gate 0 matters**:
102
+ - **Prevents false completion**: Can't mark increment "completed" with open work
103
+ - **Fast feedback**: Fails immediately (< 1s) vs waiting for PM agent (30s+)
104
+ - **Data integrity**: Ensures status matches reality (no spec.md desync)
105
+
106
+ **CRITICAL**: Gate 0 is MANDATORY and CANNOT be bypassed. If validation fails, increment stays "in-progress" and command exits.
107
+
108
+ ---
109
+
110
+ ### Step 3: PM Validation (3 Gates)
55
111
 
56
112
  **🔥 CRITICAL: PM agent MUST validate all 3 gates before allowing closure!**
57
113
 
@@ -288,7 +344,7 @@ Recommendation: ❌ CANNOT close increment
288
344
  • Estimated effort: 1-2 hours
289
345
  ```
290
346
 
291
- ### Step 3: PM Decision
347
+ ### Step 4: PM Decision
292
348
 
293
349
  **Based on 3-gate validation**:
294
350
 
@@ -326,7 +382,7 @@ Closing increment 0001-user-authentication...
326
382
  🎉 Increment 0001 closed successfully!
327
383
  ```
328
384
 
329
- ### Step 4: Post-Closure Sync (AUTOMATIC)
385
+ ### Step 5: Post-Closure Sync (AUTOMATIC)
330
386
 
331
387
  **CRITICAL**: After increment closes, automatically perform these syncs:
332
388
 
@@ -651,7 +707,7 @@ Increment remains: in-progress
651
707
  Try again after fixing blockers: /specweave:done 0001
652
708
  ```
653
709
 
654
- ### Step 4: Handle Incomplete Work
710
+ ### Step 6: Handle Incomplete Work
655
711
 
656
712
  **If increment cannot close due to scope creep**:
657
713
 
@@ -13,7 +13,10 @@ Reopen completed work when issues are discovered after completion.
13
13
  ## Quick Start
14
14
 
15
15
  ```bash
16
- # Reopen entire increment
16
+ # Reopen entire increment (natural language - RECOMMENDED)
17
+ /specweave:reopen 0043 Bug found in AC sync implementation
18
+
19
+ # OR with explicit --reason flag
17
20
  /specweave:reopen 0031 --reason "GitHub sync failing"
18
21
 
19
22
  # Reopen specific task
@@ -23,6 +26,23 @@ Reopen completed work when issues are discovered after completion.
23
26
  /specweave:reopen 0031 --user-story US-001 --reason "Acceptance criteria not met"
24
27
  ```
25
28
 
29
+ ### Natural Language Syntax (NEW!)
30
+
31
+ You can now use natural language without the `--reason` flag:
32
+
33
+ ```bash
34
+ # ✅ WORKS: Natural language (everything after increment ID is the reason)
35
+ /specweave:reopen 0043 Bug found in implementation, need to fix
36
+
37
+ # ✅ WORKS: Traditional syntax with flag
38
+ /specweave:reopen 0043 --reason "Bug found in implementation"
39
+
40
+ # ✅ WORKS: With task ID
41
+ /specweave:reopen 0043 --task T-005 Found edge case not covered
42
+ ```
43
+
44
+ **How it works**: All text after the increment ID (and any flags) is treated as the reason. No quotes needed!
45
+
26
46
  ## Smart Detection First!
27
47
 
28
48
  **Before using this command manually**, try reporting your issue naturally:
@@ -119,11 +139,18 @@ Use `--force` to bypass WIP limit checks (use sparingly!).
119
139
  | Parameter | Required | Description |
120
140
  |-----------|----------|-------------|
121
141
  | `<increment-id>` | Yes | Increment to reopen (e.g., `0031` or `0031-external-tool-status-sync`) |
122
- | `--reason <text>` | Yes | Why reopening (for audit trail) |
142
+ | `--reason <text>` | Optional* | Why reopening (for audit trail). *Can use natural language instead! |
123
143
  | `--task <id>` | No | Reopen specific task (e.g., `T-003`) |
124
144
  | `--user-story <id>` | No | Reopen user story + related tasks (e.g., `US-001`) |
125
145
  | `--force` | No | Bypass WIP limit checks |
126
146
 
147
+ **Natural Language**: If `--reason` is not provided, all remaining text is used as the reason.
148
+
149
+ Examples:
150
+ - `/specweave:reopen 0043 Bug found` → reason = "Bug found"
151
+ - `/specweave:reopen 0043 --task T-005 Edge case` → reason = "Edge case"
152
+ - `/specweave:reopen 0043 --reason "Formal reason"` → reason = "Formal reason" (explicit)
153
+
127
154
  ## WIP Limit Validation
128
155
 
129
156
  The command automatically checks WIP limits before reopening increments.
@@ -243,6 +243,57 @@ Synchronize living documentation in `.specweave/docs/` with learnings and decisi
243
243
 
244
244
  ### Execution Steps:
245
245
 
246
+ #### 0. 🔄 SYNC LIVING SPECS (User Stories, ACs, Tasks) - CRITICAL FIRST STEP
247
+
248
+ **🚨 MANDATORY: This MUST run FIRST before syncing strategic docs!**
249
+
250
+ Execute the living specs sync using the TypeScript CLI:
251
+
252
+ ```typescript
253
+ import { syncSpecs } from './dist/src/cli/commands/sync-specs.js';
254
+
255
+ console.log('═══════════════════════════════════════════════════════');
256
+ console.log('📋 STEP 0: SYNCING LIVING SPECS');
257
+ console.log('═══════════════════════════════════════════════════════\n');
258
+ console.log('🔄 Syncing user stories, acceptance criteria, and tasks...\n');
259
+
260
+ // Call sync-specs to sync living docs structure
261
+ await syncSpecs(['{increment_id}']);
262
+
263
+ console.log('\n✅ Living specs synced successfully!');
264
+ console.log(' - User stories created/updated in .specweave/docs/internal/specs/');
265
+ console.log(' - Acceptance criteria synchronized with completion status');
266
+ console.log(' - Tasks linked to user stories\n');
267
+ ```
268
+
269
+ **What this step does**:
270
+ - ✅ Parses increment spec.md and extracts user stories with ACs
271
+ - ✅ Syncs AC completion status from spec.md to user story files
272
+ - ✅ Updates task mappings in user story files
273
+ - ✅ Creates/updates feature files and README
274
+ - ✅ Ensures living specs are in sync BEFORE strategic docs
275
+
276
+ **Output**:
277
+ ```
278
+ 🎯 Target increment: {increment_id}
279
+ 📁 Increment path: .specweave/increments/{increment_id}
280
+ 🔄 Mode: Specs-only sync (Universal Hierarchy)
281
+
282
+ Processing...
283
+ 📚 Syncing {increment_id} → {FS-XXX}...
284
+ ✅ Synced 3 tasks to US-001
285
+ ✅ Synced 2 tasks to US-002
286
+
287
+ ✅ Synced {increment_id} → {FS-XXX}
288
+ Created: 5 files
289
+
290
+ ═══════════════════════════════════════════════════════
291
+ ```
292
+
293
+ **CRITICAL**: If this step fails, STOP and report error. Do not proceed to strategic docs sync.
294
+
295
+ ---
296
+
246
297
  #### 1. Analyze Increment Artifacts
247
298
 
248
299
  ```bash
@@ -510,7 +561,16 @@ Increment: {increment_id} ({title})
510
561
  Status: {status} → Documentation Updated
511
562
 
512
563
  ───────────────────────────────────────────────────────
513
- 📊 CHANGES SUMMARY
564
+ 📋 LIVING SPECS SYNCED (Step 0)
565
+ ───────────────────────────────────────────────────────
566
+
567
+ ✅ User Stories: {count} created/updated in .specweave/docs/internal/specs/
568
+ ✅ Acceptance Criteria: Synchronized with completion status from spec.md
569
+ ✅ Tasks: Linked to user stories with completion tracking
570
+ ✅ Feature Files: Created/updated in .specweave/docs/internal/specs/_features/
571
+
572
+ ───────────────────────────────────────────────────────
573
+ 📊 STRATEGIC DOCS CHANGES (Steps 1-5)
514
574
  ───────────────────────────────────────────────────────
515
575
 
516
576
  Created:
@@ -544,20 +604,27 @@ To restore: cp {file}.backup {file}
544
604
  ───────────────────────────────────────────────────────
545
605
 
546
606
  1. Review updated documentation:
607
+ - Living specs: .specweave/docs/internal/specs/
547
608
  - Public docs: .specweave/docs/public/
548
609
  - Internal docs: .specweave/docs/internal/
549
610
  - New ADRs: .specweave/docs/internal/architecture/adr/
550
611
 
551
- 2. (Optional) Generate Docusaurus site:
612
+ 2. Verify living specs sync:
613
+ - Check user story files for updated AC checkboxes
614
+ - Verify tasks are linked correctly
615
+ - Confirm feature files are up to date
616
+
617
+ 3. (Optional) Generate Docusaurus site:
552
618
  - Use 'docusaurus' skill to publish updated docs
553
619
 
554
- 3. Commit changes:
620
+ 4. Commit changes:
555
621
  git add .specweave/docs/
556
622
  git commit -m "docs: sync from increment {increment_id}"
557
623
 
558
624
  ═══════════════════════════════════════════════════════
559
625
 
560
- Documentation is now in sync with increment {increment_id}! 🎉
626
+ ALL documentation is now in sync with increment {increment_id}! 🎉
627
+ (Living specs + Strategic docs)
561
628
  ```
562
629
 
563
630
  ---