specweave 0.23.12 → 0.23.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +55 -0
- package/dist/src/core/progress/error-logger.d.ts +58 -0
- package/dist/src/core/progress/error-logger.d.ts.map +1 -0
- package/dist/src/core/progress/error-logger.js +99 -0
- package/dist/src/core/progress/error-logger.js.map +1 -0
- package/dist/src/core/spec-detector.d.ts +5 -0
- package/dist/src/core/spec-detector.d.ts.map +1 -1
- package/dist/src/core/spec-detector.js +91 -33
- package/dist/src/core/spec-detector.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/hooks/docs-changed.sh +9 -1
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/human-input-required.sh +9 -1
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +6 -1
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh +6 -1
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +7 -1
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-implementation.sh +9 -1
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +9 -1
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh +9 -1
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh +9 -2
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh +9 -1
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-github/.claude-plugin/plugin.json +15 -1
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +16 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +62 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh +9 -1
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +48 -0
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +0 -21
- package/plugins/specweave-alternatives/skills/bmad-method-expert/SKILL.md +0 -626
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/analyze-project.js +0 -318
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/check-setup.js +0 -208
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/generate-template.js +0 -1149
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/validate-documents.js +0 -340
- package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +0 -1010
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-cost-optimizer/skills/cost-optimizer/SKILL.md +0 -190
- package/plugins/specweave-docs/.claude-plugin/plugin.json +0 -19
- package/plugins/specweave-docs/skills/docusaurus/SKILL.md +0 -613
- package/plugins/specweave-docs/skills/spec-driven-brainstorming/README.md +0 -264
- package/plugins/specweave-docs/skills/spec-driven-brainstorming/SKILL.md +0 -439
- package/plugins/specweave-docs/skills/spec-driven-debugging/README.md +0 -479
- package/plugins/specweave-docs/skills/spec-driven-debugging/SKILL.md +0 -652
- package/plugins/specweave-figma/.claude-plugin/.mcp.json +0 -12
- package/plugins/specweave-figma/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-figma/ARCHITECTURE.md +0 -453
- package/plugins/specweave-figma/README.md +0 -728
- package/plugins/specweave-figma/skills/figma-to-code/SKILL.md +0 -632
- package/plugins/specweave-figma/skills/figma-to-code/test-1-token-generation.yaml +0 -29
- package/plugins/specweave-figma/skills/figma-to-code/test-2-component-generation.yaml +0 -27
- package/plugins/specweave-figma/skills/figma-to-code/test-3-typescript-generation.yaml +0 -28
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +0 -21
- package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +0 -107
- package/plugins/specweave-frontend/skills/frontend/SKILL.md +0 -177
- package/plugins/specweave-frontend/skills/nextjs/SKILL.md +0 -176
- package/plugins/specweave-testing/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-testing/skills/e2e-playwright/README.md +0 -506
- package/plugins/specweave-testing/skills/e2e-playwright/SKILL.md +0 -457
- package/plugins/specweave-testing/skills/e2e-playwright/execute.js +0 -373
- package/plugins/specweave-testing/skills/e2e-playwright/lib/utils.js +0 -514
- package/plugins/specweave-testing/skills/e2e-playwright/package.json +0 -33
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +0 -19
- package/plugins/specweave-tooling/skills/skill-creator/LICENSE.txt +0 -202
- package/plugins/specweave-tooling/skills/skill-creator/SKILL.md +0 -209
- package/plugins/specweave-tooling/skills/skill-creator/scripts/init_skill.py +0 -303
- package/plugins/specweave-tooling/skills/skill-creator/scripts/package_skill.py +0 -110
- package/plugins/specweave-tooling/skills/skill-creator/scripts/quick_validate.py +0 -65
- package/plugins/specweave-tooling/skills/skill-router/SKILL.md +0 -479
- package/plugins/specweave-ui/.claude-plugin/plugin.json +0 -26
- package/plugins/specweave-ui/.mcp.json +0 -10
- package/plugins/specweave-ui/README.md +0 -492
- package/plugins/specweave-ui/skills/browser-automation/SKILL.md +0 -676
package/CLAUDE.md
CHANGED
|
@@ -252,6 +252,61 @@ Feature FS-048 → GitHub Milestone "FS-048: Feature Title"
|
|
|
252
252
|
|
|
253
253
|
---
|
|
254
254
|
|
|
255
|
+
### 10a. NO Increment-to-Increment References (ADR-0061) ⛔
|
|
256
|
+
|
|
257
|
+
**CRITICAL ARCHITECTURAL RULE**: Increments NEVER reference other increments!
|
|
258
|
+
|
|
259
|
+
**The Only Allowed Flow**:
|
|
260
|
+
```
|
|
261
|
+
INCREMENT (metadata.json: feature_id) → FEATURE → USER STORIES
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**❌ FORBIDDEN**:
|
|
265
|
+
```yaml
|
|
266
|
+
# In user story frontmatter
|
|
267
|
+
---
|
|
268
|
+
id: US-001
|
|
269
|
+
feature: FS-048
|
|
270
|
+
increments: [0050-external-tool-import] # ❌ NEVER DO THIS!
|
|
271
|
+
---
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
```markdown
|
|
275
|
+
# In user story content
|
|
276
|
+
Implemented in increment 0050-external-tool-import ❌ NEVER DO THIS!
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**✅ CORRECT**:
|
|
280
|
+
```yaml
|
|
281
|
+
# Increment metadata.json
|
|
282
|
+
{
|
|
283
|
+
"feature_id": "FS-048" ✅ Forward reference only
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
# User story frontmatter
|
|
287
|
+
---
|
|
288
|
+
id: US-001
|
|
289
|
+
feature: FS-048 ✅ No increment reference needed!
|
|
290
|
+
---
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Why This Matters**:
|
|
294
|
+
|
|
295
|
+
1. **Hooks Break Without This**: The GitHub sync hook reads increment metadata → finds feature_id → finds all user stories for that feature → creates GitHub issues. If user stories required increment references, this creates circular dependencies and hooks detect 0 specs.
|
|
296
|
+
|
|
297
|
+
2. **Clean Separation**: Living docs (user stories) are permanent. Increments are temporary implementations. User stories should never know about increments.
|
|
298
|
+
|
|
299
|
+
3. **Multi-Increment Support**: Multiple increments can implement the same feature (Phase 1a, 1b, 1c). Each auto-syncs ALL user stories without duplication.
|
|
300
|
+
|
|
301
|
+
**Enforcement**:
|
|
302
|
+
- Pre-commit hook validates NO increment references in living docs
|
|
303
|
+
- Spec-detector ignores reverse references (defensive)
|
|
304
|
+
- **See**: ADR-0061 for complete architectural rationale
|
|
305
|
+
|
|
306
|
+
**Incident**: 2025-11-22 - Hooks appeared broken (0 specs detected, 0 GitHub issues created) due to old spec-detector logic requiring reverse references. Fixed in v0.24.0+.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
255
310
|
### 11. Task Format with US Linkage (v0.23.0+)
|
|
256
311
|
|
|
257
312
|
**Required fields**:
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Logger - Comprehensive error logging for batch operations
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - File-based error logging
|
|
6
|
+
* - Timestamped error records
|
|
7
|
+
* - Structured error format
|
|
8
|
+
* - Automatic log directory creation
|
|
9
|
+
*
|
|
10
|
+
* @module core/progress/error-logger
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Error log entry
|
|
14
|
+
*/
|
|
15
|
+
export interface ErrorLogEntry {
|
|
16
|
+
timestamp: string;
|
|
17
|
+
projectKey: string;
|
|
18
|
+
error: string;
|
|
19
|
+
suggestion?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Error logger options
|
|
23
|
+
*/
|
|
24
|
+
export interface ErrorLoggerOptions {
|
|
25
|
+
/** Log file path (default: .specweave/logs/import-errors.log) */
|
|
26
|
+
logFile?: string;
|
|
27
|
+
/** Project root directory */
|
|
28
|
+
projectRoot?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Log error to file
|
|
32
|
+
*
|
|
33
|
+
* @param projectKey Project identifier
|
|
34
|
+
* @param error Error object or message
|
|
35
|
+
* @param options Logger options
|
|
36
|
+
*/
|
|
37
|
+
export declare function logError(projectKey: string, error: Error | string, options?: ErrorLoggerOptions): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Read error log
|
|
40
|
+
*
|
|
41
|
+
* @param options Logger options
|
|
42
|
+
* @returns Array of error log entries
|
|
43
|
+
*/
|
|
44
|
+
export declare function readErrorLog(options?: ErrorLoggerOptions): Promise<ErrorLogEntry[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Clear error log
|
|
47
|
+
*
|
|
48
|
+
* @param options Logger options
|
|
49
|
+
*/
|
|
50
|
+
export declare function clearErrorLog(options?: ErrorLoggerOptions): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Get error count from log
|
|
53
|
+
*
|
|
54
|
+
* @param options Logger options
|
|
55
|
+
* @returns Number of errors in log
|
|
56
|
+
*/
|
|
57
|
+
export declare function getErrorCount(options?: ErrorLoggerOptions): Promise<number>;
|
|
58
|
+
//# sourceMappingURL=error-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-logger.d.ts","sourceRoot":"","sources":["../../../../src/core/progress/error-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AASD;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,KAAK,GAAG,MAAM,EACrB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA4B7F;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOnF;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Logger - Comprehensive error logging for batch operations
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - File-based error logging
|
|
6
|
+
* - Timestamped error records
|
|
7
|
+
* - Structured error format
|
|
8
|
+
* - Automatic log directory creation
|
|
9
|
+
*
|
|
10
|
+
* @module core/progress/error-logger
|
|
11
|
+
*/
|
|
12
|
+
import { promises as fs } from 'fs';
|
|
13
|
+
import { join } from 'path';
|
|
14
|
+
import { existsSync } from 'fs';
|
|
15
|
+
import { mkdirpSync } from '../../utils/fs-native.js';
|
|
16
|
+
/**
|
|
17
|
+
* Get default error log file path
|
|
18
|
+
*/
|
|
19
|
+
function getDefaultLogPath(projectRoot) {
|
|
20
|
+
return join(projectRoot, '.specweave', 'logs', 'import-errors.log');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Log error to file
|
|
24
|
+
*
|
|
25
|
+
* @param projectKey Project identifier
|
|
26
|
+
* @param error Error object or message
|
|
27
|
+
* @param options Logger options
|
|
28
|
+
*/
|
|
29
|
+
export async function logError(projectKey, error, options = {}) {
|
|
30
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
31
|
+
const logFile = options.logFile ?? getDefaultLogPath(projectRoot);
|
|
32
|
+
const logDir = join(projectRoot, '.specweave', 'logs');
|
|
33
|
+
// Ensure log directory exists
|
|
34
|
+
mkdirpSync(logDir);
|
|
35
|
+
// Create error entry
|
|
36
|
+
const entry = {
|
|
37
|
+
timestamp: new Date().toISOString(),
|
|
38
|
+
projectKey,
|
|
39
|
+
error: error instanceof Error ? error.message : error
|
|
40
|
+
};
|
|
41
|
+
// Format log line
|
|
42
|
+
const logLine = `[${entry.timestamp}] ${entry.projectKey}: ${entry.error}\n`;
|
|
43
|
+
// Append to log file
|
|
44
|
+
await fs.appendFile(logFile, logLine, 'utf-8');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Read error log
|
|
48
|
+
*
|
|
49
|
+
* @param options Logger options
|
|
50
|
+
* @returns Array of error log entries
|
|
51
|
+
*/
|
|
52
|
+
export async function readErrorLog(options = {}) {
|
|
53
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
54
|
+
const logFile = options.logFile ?? getDefaultLogPath(projectRoot);
|
|
55
|
+
if (!existsSync(logFile)) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const content = await fs.readFile(logFile, 'utf-8');
|
|
59
|
+
const lines = content.split('\n').filter(line => line.trim());
|
|
60
|
+
return lines.map(line => {
|
|
61
|
+
// Parse log line: [timestamp] projectKey: error
|
|
62
|
+
const match = line.match(/^\[([^\]]+)\]\s+([^:]+):\s+(.+)$/);
|
|
63
|
+
if (!match) {
|
|
64
|
+
return {
|
|
65
|
+
timestamp: new Date().toISOString(),
|
|
66
|
+
projectKey: 'UNKNOWN',
|
|
67
|
+
error: line
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
timestamp: match[1],
|
|
72
|
+
projectKey: match[2].trim(),
|
|
73
|
+
error: match[3].trim()
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Clear error log
|
|
79
|
+
*
|
|
80
|
+
* @param options Logger options
|
|
81
|
+
*/
|
|
82
|
+
export async function clearErrorLog(options = {}) {
|
|
83
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
84
|
+
const logFile = options.logFile ?? getDefaultLogPath(projectRoot);
|
|
85
|
+
if (existsSync(logFile)) {
|
|
86
|
+
await fs.unlink(logFile);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get error count from log
|
|
91
|
+
*
|
|
92
|
+
* @param options Logger options
|
|
93
|
+
* @returns Number of errors in log
|
|
94
|
+
*/
|
|
95
|
+
export async function getErrorCount(options = {}) {
|
|
96
|
+
const entries = await readErrorLog(options);
|
|
97
|
+
return entries.length;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=error-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-logger.js","sourceRoot":"","sources":["../../../../src/core/progress/error-logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,11 @@ export interface MultiSpecDetectionResult {
|
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Detect all specs referenced in an increment
|
|
32
|
+
*
|
|
33
|
+
* CRITICAL ARCHITECTURE (v0.24.0+):
|
|
34
|
+
* - Increments NEVER reference other increments
|
|
35
|
+
* - Flow: INCREMENT (feature_id) → FEATURE → USER STORIES
|
|
36
|
+
* - Detection: Read increment metadata.json → Find feature_id → Find all user stories with that feature
|
|
32
37
|
*/
|
|
33
38
|
export declare function detectSpecsInIncrement(incrementPath: string, config?: any): Promise<MultiSpecDetectionResult>;
|
|
34
39
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-detector.d.ts","sourceRoot":"","sources":["../../../src/core/spec-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,UAAU,EAAE,cAAc,CAAC;IAE3B,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IAEb,mDAAmD;IACnD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,yBAAyB;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IAEtB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,6CAA6C;IAC7C,WAAW,EAAE,OAAO,CAAC;IAErB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED
|
|
1
|
+
{"version":3,"file":"spec-detector.d.ts","sourceRoot":"","sources":["../../../src/core/spec-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,UAAU,EAAE,cAAc,CAAC;IAE3B,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IAEb,mDAAmD;IACnD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,yBAAyB;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IAEtB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,6CAA6C;IAC7C,WAAW,EAAE,OAAO,CAAC;IAErB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,GAAQ,GACf,OAAO,CAAC,wBAAwB,CAAC,CA+CnC;AAiJD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,wCAAwC,CACtD,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,MAAW,EACxB,MAAM,GAAE,GAAQ,GACf,sBAAsB,CA8DxB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,MAAW,EACxB,MAAM,GAAE,GAAQ,GACf,MAAM,CAGR;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,GAAQ,GACf,OAAO,CAwBT"}
|
|
@@ -12,8 +12,61 @@ import matter from 'gray-matter';
|
|
|
12
12
|
import { detectSpecIdentifier } from './spec-identifier-detector.js';
|
|
13
13
|
/**
|
|
14
14
|
* Detect all specs referenced in an increment
|
|
15
|
+
*
|
|
16
|
+
* CRITICAL ARCHITECTURE (v0.24.0+):
|
|
17
|
+
* - Increments NEVER reference other increments
|
|
18
|
+
* - Flow: INCREMENT (feature_id) → FEATURE → USER STORIES
|
|
19
|
+
* - Detection: Read increment metadata.json → Find feature_id → Find all user stories with that feature
|
|
15
20
|
*/
|
|
16
21
|
export async function detectSpecsInIncrement(incrementPath, config = {}) {
|
|
22
|
+
const specs = [];
|
|
23
|
+
// STEP 1: Read increment metadata to get feature_id
|
|
24
|
+
const metadataPath = path.join(incrementPath, 'metadata.json');
|
|
25
|
+
if (!fs.existsSync(metadataPath)) {
|
|
26
|
+
// Fallback: try spec.md frontmatter
|
|
27
|
+
const specPath = path.join(incrementPath, 'spec.md');
|
|
28
|
+
if (fs.existsSync(specPath)) {
|
|
29
|
+
const specContent = fs.readFileSync(specPath, 'utf-8');
|
|
30
|
+
const { data: frontmatter } = matter(specContent);
|
|
31
|
+
// No feature_id in frontmatter either - return empty
|
|
32
|
+
if (!frontmatter.feature_id) {
|
|
33
|
+
return {
|
|
34
|
+
specs: [],
|
|
35
|
+
isMultiSpec: false,
|
|
36
|
+
projects: []
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// Use feature_id from spec.md frontmatter
|
|
40
|
+
return await detectSpecsByFeatureId(frontmatter.feature_id, config);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
specs: [],
|
|
44
|
+
isMultiSpec: false,
|
|
45
|
+
projects: []
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf-8'));
|
|
49
|
+
const featureId = metadata.feature_id;
|
|
50
|
+
if (!featureId) {
|
|
51
|
+
// No feature_id - return empty (increment is standalone)
|
|
52
|
+
return {
|
|
53
|
+
specs: [],
|
|
54
|
+
isMultiSpec: false,
|
|
55
|
+
projects: []
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// STEP 2: Find all user stories for this feature_id
|
|
59
|
+
return await detectSpecsByFeatureId(featureId, config);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Detect all user stories for a given feature_id
|
|
63
|
+
*
|
|
64
|
+
* ARCHITECTURE:
|
|
65
|
+
* - Scans .specweave/docs/internal/specs/{project}/{feature}/
|
|
66
|
+
* - Finds all user story files with feature: {featureId} in frontmatter
|
|
67
|
+
* - Returns detected specs ready for GitHub sync
|
|
68
|
+
*/
|
|
69
|
+
async function detectSpecsByFeatureId(featureId, config = {}) {
|
|
17
70
|
const specs = [];
|
|
18
71
|
// 1. Check for specs in living docs folder
|
|
19
72
|
const specsFolder = path.join(process.cwd(), '.specweave/docs/internal/specs');
|
|
@@ -28,49 +81,54 @@ export async function detectSpecsInIncrement(incrementPath, config = {}) {
|
|
|
28
81
|
const projectFolders = fs.readdirSync(specsFolder);
|
|
29
82
|
for (const projectFolder of projectFolders) {
|
|
30
83
|
const projectPath = path.join(specsFolder, projectFolder);
|
|
31
|
-
// Skip if not a directory
|
|
32
|
-
if (!fs.statSync(projectPath).isDirectory()) {
|
|
84
|
+
// Skip if not a directory or _features folder
|
|
85
|
+
if (!fs.statSync(projectPath).isDirectory() || projectFolder === '_features') {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
// 3. Scan for feature-specific folders (e.g., FS-048/)
|
|
89
|
+
const featureFolderPath = path.join(projectPath, featureId);
|
|
90
|
+
if (!fs.existsSync(featureFolderPath) || !fs.statSync(featureFolderPath).isDirectory()) {
|
|
33
91
|
continue;
|
|
34
92
|
}
|
|
35
|
-
//
|
|
36
|
-
const specFiles = fs.readdirSync(
|
|
93
|
+
// 4. Scan all user story files in this feature folder
|
|
94
|
+
const specFiles = fs.readdirSync(featureFolderPath).filter(f => f.endsWith('.md') && f.startsWith('us-'));
|
|
37
95
|
for (const specFile of specFiles) {
|
|
38
|
-
const specPath = path.join(
|
|
96
|
+
const specPath = path.join(featureFolderPath, specFile);
|
|
39
97
|
const specContent = fs.readFileSync(specPath, 'utf-8');
|
|
40
98
|
const { data: frontmatter, content } = matter(specContent);
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// 5. Detect identifier for this spec
|
|
45
|
-
const title = frontmatter.title || extractTitle(content);
|
|
46
|
-
const specContentObj = {
|
|
47
|
-
content: specContent,
|
|
48
|
-
frontmatter,
|
|
49
|
-
title,
|
|
50
|
-
project: projectFolder,
|
|
51
|
-
path: specPath
|
|
52
|
-
};
|
|
53
|
-
const identifier = detectSpecIdentifier(specContentObj, {
|
|
54
|
-
existingSpecs: specs.map(s => s.identifier.full),
|
|
55
|
-
preferTitleSlug: config.specs?.preferTitleSlug ?? true,
|
|
56
|
-
minSlugLength: config.specs?.minSlugLength ?? 5
|
|
57
|
-
});
|
|
58
|
-
// 6. Check if sync is enabled for this project
|
|
59
|
-
const projectConfig = config.specs?.projects?.[projectFolder];
|
|
60
|
-
const syncEnabled = projectConfig?.syncEnabled !== false;
|
|
61
|
-
specs.push({
|
|
62
|
-
identifier,
|
|
63
|
-
project: projectFolder,
|
|
64
|
-
path: specPath,
|
|
65
|
-
syncEnabled
|
|
66
|
-
});
|
|
99
|
+
// 5. Verify this user story belongs to the feature
|
|
100
|
+
if (frontmatter.feature !== featureId) {
|
|
101
|
+
continue;
|
|
67
102
|
}
|
|
103
|
+
// 6. Detect identifier for this spec
|
|
104
|
+
const title = frontmatter.title || extractTitle(content);
|
|
105
|
+
const specContentObj = {
|
|
106
|
+
content: specContent,
|
|
107
|
+
frontmatter,
|
|
108
|
+
title,
|
|
109
|
+
project: projectFolder,
|
|
110
|
+
path: specPath
|
|
111
|
+
};
|
|
112
|
+
const identifier = detectSpecIdentifier(specContentObj, {
|
|
113
|
+
existingSpecs: specs.map(s => s.identifier.full),
|
|
114
|
+
preferTitleSlug: config.specs?.preferTitleSlug ?? true,
|
|
115
|
+
minSlugLength: config.specs?.minSlugLength ?? 5
|
|
116
|
+
});
|
|
117
|
+
// 7. Check if sync is enabled for this project
|
|
118
|
+
const projectConfig = config.specs?.projects?.[projectFolder];
|
|
119
|
+
const syncEnabled = projectConfig?.syncEnabled !== false;
|
|
120
|
+
specs.push({
|
|
121
|
+
identifier,
|
|
122
|
+
project: projectFolder,
|
|
123
|
+
path: specPath,
|
|
124
|
+
syncEnabled
|
|
125
|
+
});
|
|
68
126
|
}
|
|
69
127
|
}
|
|
70
|
-
//
|
|
128
|
+
// 8. Determine if multi-spec
|
|
71
129
|
const isMultiSpec = specs.length > 1;
|
|
72
130
|
const projects = [...new Set(specs.map(s => s.project))];
|
|
73
|
-
//
|
|
131
|
+
// 9. Find primary spec (first non-parent spec)
|
|
74
132
|
const primary = specs.find(s => s.project !== '_parent') || specs[0];
|
|
75
133
|
return {
|
|
76
134
|
specs,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-detector.js","sourceRoot":"","sources":["../../../src/core/spec-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAe,MAAM,+BAA+B,CAAC;AA+BlF
|
|
1
|
+
{"version":3,"file":"spec-detector.js","sourceRoot":"","sources":["../../../src/core/spec-detector.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.16",
|
|
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",
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
# Detects if documentation was changed during implementation
|
|
6
6
|
# Triggers review workflow if needed
|
|
7
7
|
|
|
8
|
-
set
|
|
8
|
+
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
9
|
+
|
|
10
|
+
# EMERGENCY KILL SWITCH
|
|
11
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
9
14
|
|
|
10
15
|
# Find project root by searching upward for .specweave/ directory
|
|
11
16
|
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
@@ -77,3 +82,6 @@ if [ -n "$DOC_CHANGES" ]; then
|
|
|
77
82
|
mkdir -p "$LOGS_DIR"
|
|
78
83
|
echo "[$(date)] Documentation changed: $DOC_CHANGES" >> "$LOGS_DIR/hooks.log"
|
|
79
84
|
fi
|
|
85
|
+
|
|
86
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
87
|
+
exit 0
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Docs-Changed Hook
|
|
4
|
+
# Runs after file changes are detected
|
|
5
|
+
# Detects if documentation was changed during implementation
|
|
6
|
+
# Triggers review workflow if needed
|
|
7
|
+
|
|
8
|
+
set -e
|
|
9
|
+
|
|
10
|
+
# Find project root by searching upward for .specweave/ directory
|
|
11
|
+
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
12
|
+
find_project_root() {
|
|
13
|
+
local dir="$1"
|
|
14
|
+
while [ "$dir" != "/" ]; do
|
|
15
|
+
if [ -d "$dir/.specweave" ]; then
|
|
16
|
+
echo "$dir"
|
|
17
|
+
return 0
|
|
18
|
+
fi
|
|
19
|
+
dir="$(dirname "$dir")"
|
|
20
|
+
done
|
|
21
|
+
# Fallback: try current directory
|
|
22
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
23
|
+
pwd
|
|
24
|
+
else
|
|
25
|
+
echo "$(pwd)"
|
|
26
|
+
fi
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
30
|
+
cd "$PROJECT_ROOT"
|
|
31
|
+
|
|
32
|
+
# Colors
|
|
33
|
+
RED='\033[0;31m'
|
|
34
|
+
YELLOW='\033[1;33m'
|
|
35
|
+
NC='\033[0m'
|
|
36
|
+
|
|
37
|
+
# Get changed files (git)
|
|
38
|
+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
39
|
+
# Not a git repository, skip
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
CHANGED_FILES=$(git diff --name-only HEAD 2>/dev/null || echo "")
|
|
44
|
+
|
|
45
|
+
if [ -z "$CHANGED_FILES" ]; then
|
|
46
|
+
# No changes
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Check if any documentation files changed
|
|
51
|
+
DOC_CHANGES=$(echo "$CHANGED_FILES" | grep -E '\.specweave/(docs|increments/.*/.*\.md)' || true)
|
|
52
|
+
|
|
53
|
+
if [ -n "$DOC_CHANGES" ]; then
|
|
54
|
+
echo -e "${RED}⚠️ Documentation changed during implementation${NC}"
|
|
55
|
+
echo ""
|
|
56
|
+
echo "📋 Files changed:"
|
|
57
|
+
echo "$DOC_CHANGES" | sed 's/^/ /'
|
|
58
|
+
echo ""
|
|
59
|
+
echo -e "${YELLOW}🔔 Recommended actions:${NC}"
|
|
60
|
+
echo " 1. Review documentation changes"
|
|
61
|
+
echo " 2. Update tasks.md if architecture changed"
|
|
62
|
+
echo " 3. Type /review-docs to see full impact"
|
|
63
|
+
echo ""
|
|
64
|
+
|
|
65
|
+
# Play notification sound
|
|
66
|
+
case "$(uname -s)" in
|
|
67
|
+
Darwin)
|
|
68
|
+
afplay /System/Library/Sounds/Ping.aiff 2>/dev/null &
|
|
69
|
+
;;
|
|
70
|
+
Linux)
|
|
71
|
+
paplay /usr/share/sounds/freedesktop/stereo/dialog-warning.oga 2>/dev/null || true
|
|
72
|
+
;;
|
|
73
|
+
esac
|
|
74
|
+
|
|
75
|
+
# Log to hooks log
|
|
76
|
+
LOGS_DIR=".specweave/logs"
|
|
77
|
+
mkdir -p "$LOGS_DIR"
|
|
78
|
+
echo "[$(date)] Documentation changed: $DOC_CHANGES" >> "$LOGS_DIR/hooks.log"
|
|
79
|
+
fi
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
# 2. Log the question/requirement
|
|
9
9
|
# 3. Record in current increment's work log (if applicable)
|
|
10
10
|
|
|
11
|
-
set
|
|
11
|
+
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
12
|
+
|
|
13
|
+
# EMERGENCY KILL SWITCH
|
|
14
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
12
17
|
|
|
13
18
|
# Find project root by searching upward for .specweave/ directory
|
|
14
19
|
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
@@ -73,3 +78,6 @@ if [ -n "$CURRENT_WORK" ] && [ -d "$CURRENT_WORK" ]; then
|
|
|
73
78
|
fi
|
|
74
79
|
|
|
75
80
|
echo "✅ Hook complete"
|
|
81
|
+
|
|
82
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
83
|
+
exit 0
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Human-Input-Required Hook
|
|
4
|
+
# Runs when Claude needs clarification or approval
|
|
5
|
+
#
|
|
6
|
+
# Actions:
|
|
7
|
+
# 1. Play notification sound (Ping.aiff)
|
|
8
|
+
# 2. Log the question/requirement
|
|
9
|
+
# 3. Record in current increment's work log (if applicable)
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
# Find project root by searching upward for .specweave/ directory
|
|
14
|
+
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
15
|
+
find_project_root() {
|
|
16
|
+
local dir="$1"
|
|
17
|
+
while [ "$dir" != "/" ]; do
|
|
18
|
+
if [ -d "$dir/.specweave" ]; then
|
|
19
|
+
echo "$dir"
|
|
20
|
+
return 0
|
|
21
|
+
fi
|
|
22
|
+
dir="$(dirname "$dir")"
|
|
23
|
+
done
|
|
24
|
+
# Fallback: try current directory
|
|
25
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
26
|
+
pwd
|
|
27
|
+
else
|
|
28
|
+
echo "$(pwd)"
|
|
29
|
+
fi
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
33
|
+
cd "$PROJECT_ROOT"
|
|
34
|
+
|
|
35
|
+
# Get question/requirement (passed as argument or default)
|
|
36
|
+
QUESTION="${1:-User input required}"
|
|
37
|
+
|
|
38
|
+
echo "❓ Human input required"
|
|
39
|
+
|
|
40
|
+
# 1. Play notification sound (cross-platform)
|
|
41
|
+
play_sound() {
|
|
42
|
+
case "$(uname -s)" in
|
|
43
|
+
Darwin)
|
|
44
|
+
afplay /System/Library/Sounds/Ping.aiff 2>/dev/null &
|
|
45
|
+
;;
|
|
46
|
+
Linux)
|
|
47
|
+
paplay /usr/share/sounds/freedesktop/stereo/dialog-question.oga 2>/dev/null || \
|
|
48
|
+
aplay /usr/share/sounds/alsa/Side_Left.wav 2>/dev/null || true
|
|
49
|
+
;;
|
|
50
|
+
MINGW*|MSYS*|CYGWIN*)
|
|
51
|
+
powershell -c "(New-Object Media.SoundPlayer 'C:\Windows\Media\notify.wav').PlaySync();" 2>/dev/null || true
|
|
52
|
+
;;
|
|
53
|
+
esac
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
play_sound &
|
|
57
|
+
|
|
58
|
+
# 2. Log to main hooks log
|
|
59
|
+
LOGS_DIR=".specweave/logs"
|
|
60
|
+
mkdir -p "$LOGS_DIR"
|
|
61
|
+
echo "[$(date)] Human input required: $QUESTION" >> "$LOGS_DIR/hooks.log"
|
|
62
|
+
|
|
63
|
+
# 3. Log to current work context (if exists)
|
|
64
|
+
CURRENT_WORK=$(find .specweave/work -maxdepth 1 -type d -name "current-*" | head -1 || true)
|
|
65
|
+
|
|
66
|
+
if [ -n "$CURRENT_WORK" ] && [ -d "$CURRENT_WORK" ]; then
|
|
67
|
+
echo "" >> "$CURRENT_WORK/notes.md"
|
|
68
|
+
echo "## Input Required ($(date +%Y-%m-%d\ %H:%M))" >> "$CURRENT_WORK/notes.md"
|
|
69
|
+
echo "" >> "$CURRENT_WORK/notes.md"
|
|
70
|
+
echo "$QUESTION" >> "$CURRENT_WORK/notes.md"
|
|
71
|
+
echo "" >> "$CURRENT_WORK/notes.md"
|
|
72
|
+
echo "📝 Logged to $CURRENT_WORK/notes.md"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
echo "✅ Hook complete"
|