specweave 1.0.252 → 1.0.254
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 +24 -24
- package/README.md +161 -0
- package/dist/src/cli/commands/docs.d.ts.map +1 -1
- package/dist/src/cli/commands/docs.js +59 -55
- package/dist/src/cli/commands/docs.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +31 -3
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/init/path-utils.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/path-utils.js +12 -1
- package/dist/src/cli/helpers/init/path-utils.js.map +1 -1
- package/dist/src/cli/helpers/init/smart-defaults.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/smart-defaults.js +7 -1
- package/dist/src/cli/helpers/init/smart-defaults.js.map +1 -1
- package/dist/src/cli/helpers/init/types.d.ts +6 -0
- package/dist/src/cli/helpers/init/types.d.ts.map +1 -1
- package/dist/src/core/config/types.d.ts +2 -0
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts.map +1 -1
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js +5 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts +21 -0
- package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.js +61 -107
- package/dist/src/core/lazy-loading/llm-plugin-detector.js.map +1 -1
- package/dist/src/core/living-docs/enterprise/history-analyzer.d.ts.map +1 -1
- package/dist/src/core/living-docs/enterprise/history-analyzer.js +1 -3
- package/dist/src/core/living-docs/enterprise/history-analyzer.js.map +1 -1
- package/dist/src/core/living-docs/governance/java-standards-parser.d.ts.map +1 -1
- package/dist/src/core/living-docs/governance/java-standards-parser.js +37 -18
- package/dist/src/core/living-docs/governance/java-standards-parser.js.map +1 -1
- package/dist/src/core/living-docs/operations/ops-generator.js +2 -2
- package/dist/src/core/living-docs/operations/ops-generator.js.map +1 -1
- package/dist/src/core/repo-structure/prefix-validator.d.ts +25 -0
- package/dist/src/core/repo-structure/prefix-validator.d.ts.map +1 -0
- package/dist/src/core/repo-structure/prefix-validator.js +47 -0
- package/dist/src/core/repo-structure/prefix-validator.js.map +1 -0
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts +4 -0
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/core/repo-structure/role-prefix-collector.d.ts +45 -0
- package/dist/src/core/repo-structure/role-prefix-collector.d.ts.map +1 -0
- package/dist/src/core/repo-structure/role-prefix-collector.js +106 -0
- package/dist/src/core/repo-structure/role-prefix-collector.js.map +1 -0
- package/dist/src/core/scheduler/schedule-persistence.d.ts +1 -0
- package/dist/src/core/scheduler/schedule-persistence.d.ts.map +1 -1
- package/dist/src/core/scheduler/schedule-persistence.js +8 -0
- package/dist/src/core/scheduler/schedule-persistence.js.map +1 -1
- package/dist/src/core/sync/sync-audit-logger.d.ts.map +1 -1
- package/dist/src/core/sync/sync-audit-logger.js +3 -1
- package/dist/src/core/sync/sync-audit-logger.js.map +1 -1
- package/dist/src/hooks/platform.d.ts +13 -1
- package/dist/src/hooks/platform.d.ts.map +1 -1
- package/dist/src/hooks/platform.js +35 -2
- package/dist/src/hooks/platform.js.map +1 -1
- package/dist/src/hooks/session-start.js +7 -0
- package/dist/src/hooks/session-start.js.map +1 -1
- package/dist/src/sync/story-router.d.ts +36 -0
- package/dist/src/sync/story-router.d.ts.map +1 -0
- package/dist/src/sync/story-router.js +56 -0
- package/dist/src/sync/story-router.js.map +1 -0
- package/dist/src/utils/state-cleanup.d.ts +19 -0
- package/dist/src/utils/state-cleanup.d.ts.map +1 -0
- package/dist/src/utils/state-cleanup.js +61 -0
- package/dist/src/utils/state-cleanup.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/hooks/user-prompt-submit.sh +29 -7
- package/src/templates/CLAUDE.md.template +22 -128
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../../src/hooks/platform.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAS,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAMlE;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAaD;;GAEG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAKtC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAUD,wBAAgB,cAAc,IAAI,SAAS,CAyB1C;AAED
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../../src/hooks/platform.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAS,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAMlE;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAaD;;GAEG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAKtC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAUD,wBAAgB,cAAc,IAAI,SAAS,CAyB1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAiB/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,YAAiB,GACzB,YAAY,GAAG,IAAI,CAoBrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,MAAM,EAAO,EACnB,GAAG,CAAC,EAAE,MAAM,GACX,YAAY,GAAG,IAAI,CA0BrB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAUpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAyBtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAuBhE;AAED;;;;GAIG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAK5B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,SAAM,GAAG,OAAO;IA2CxC;;OAEG;IACH,OAAO,IAAI,IAAI;CAUhB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAEzD;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAepD"}
|
|
@@ -77,7 +77,11 @@ export function checkWslStatus() {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
|
-
* Find project root by looking for .specweave directory
|
|
80
|
+
* Find project root by looking for .specweave directory WITH config.json
|
|
81
|
+
*
|
|
82
|
+
* A valid SpecWeave project must have .specweave/config.json.
|
|
83
|
+
* Stale .specweave/ folders (with only logs/state from runtime code)
|
|
84
|
+
* are NOT valid project roots and must be skipped.
|
|
81
85
|
*
|
|
82
86
|
* @param startDir - Directory to start searching from
|
|
83
87
|
* @returns Project root path or null if not found
|
|
@@ -87,7 +91,9 @@ export function findProjectRoot(startDir = process.cwd()) {
|
|
|
87
91
|
const root = path.parse(current).root;
|
|
88
92
|
while (current !== root) {
|
|
89
93
|
const specweavePath = path.join(current, '.specweave');
|
|
90
|
-
if (fs.existsSync(specweavePath) &&
|
|
94
|
+
if (fs.existsSync(specweavePath) &&
|
|
95
|
+
fs.statSync(specweavePath).isDirectory() &&
|
|
96
|
+
fs.existsSync(path.join(specweavePath, 'config.json'))) {
|
|
91
97
|
return current;
|
|
92
98
|
}
|
|
93
99
|
current = path.dirname(current);
|
|
@@ -183,6 +189,10 @@ export function readJsonSafe(filePath) {
|
|
|
183
189
|
/**
|
|
184
190
|
* Write JSON file safely with atomic write
|
|
185
191
|
*
|
|
192
|
+
* SAFETY: Only creates directories if the parent .specweave/ already exists.
|
|
193
|
+
* This prevents accidentally creating stale .specweave/ folders in arbitrary
|
|
194
|
+
* directories when code runs from a non-project CWD.
|
|
195
|
+
*
|
|
186
196
|
* @param filePath - Path to JSON file
|
|
187
197
|
* @param data - Data to write
|
|
188
198
|
* @returns true if successful, false otherwise
|
|
@@ -190,6 +200,15 @@ export function readJsonSafe(filePath) {
|
|
|
190
200
|
export function writeJsonSafe(filePath, data) {
|
|
191
201
|
try {
|
|
192
202
|
const dir = path.dirname(filePath);
|
|
203
|
+
// Guard: don't create .specweave/ from scratch
|
|
204
|
+
const specweaveDir = filePath.split(path.sep).reduce((acc, part, i, parts) => {
|
|
205
|
+
if (part === '.specweave')
|
|
206
|
+
return parts.slice(0, i + 1).join(path.sep);
|
|
207
|
+
return acc;
|
|
208
|
+
}, '');
|
|
209
|
+
if (specweaveDir && !fs.existsSync(specweaveDir)) {
|
|
210
|
+
return false; // .specweave/ doesn't exist — refuse to create stale folder
|
|
211
|
+
}
|
|
193
212
|
if (!fs.existsSync(dir)) {
|
|
194
213
|
fs.mkdirSync(dir, { recursive: true });
|
|
195
214
|
}
|
|
@@ -206,12 +225,26 @@ export function writeJsonSafe(filePath, data) {
|
|
|
206
225
|
/**
|
|
207
226
|
* Append to log file (creates directory if needed)
|
|
208
227
|
*
|
|
228
|
+
* SAFETY: Only creates directories if the parent .specweave/ already exists.
|
|
229
|
+
* This prevents accidentally creating stale .specweave/ folders in arbitrary
|
|
230
|
+
* directories when hooks run from a non-project CWD.
|
|
231
|
+
*
|
|
209
232
|
* @param logPath - Path to log file
|
|
210
233
|
* @param message - Message to append
|
|
211
234
|
*/
|
|
212
235
|
export function appendLog(logPath, message) {
|
|
213
236
|
try {
|
|
214
237
|
const dir = path.dirname(logPath);
|
|
238
|
+
// Guard: don't create .specweave/ from scratch — only create subdirs
|
|
239
|
+
// if .specweave/ already exists (i.e., this is a real project root)
|
|
240
|
+
const specweaveDir = logPath.split(path.sep).reduce((acc, part, i, parts) => {
|
|
241
|
+
if (part === '.specweave')
|
|
242
|
+
return parts.slice(0, i + 1).join(path.sep);
|
|
243
|
+
return acc;
|
|
244
|
+
}, '');
|
|
245
|
+
if (specweaveDir && !fs.existsSync(specweaveDir)) {
|
|
246
|
+
return; // .specweave/ doesn't exist — skip to avoid creating stale folder
|
|
247
|
+
}
|
|
215
248
|
if (!fs.existsSync(dir)) {
|
|
216
249
|
fs.mkdirSync(dir, { recursive: true });
|
|
217
250
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../../src/hooks/platform.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAA8B,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,0FAA0F;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAgBpD;;GAEG;AACH,MAAM,YAAY,GAAG;IACnB,QAAQ,EAAE,OAAO,CAAC,QAA2B;IAC7C,SAAS,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;IACvC,OAAO,EAAE,OAAO,CAAC,QAAQ,KAAK,QAAQ;IACtC,OAAO,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;IACrC,OAAO,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;CACtC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,YAAY,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7C,IAAI,YAAY,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IACzC,IAAI,YAAY,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IACzC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,YAAY,CAAC,SAAS,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO;IACrB,OAAO,YAAY,CAAC,OAAO,CAAC;AAC9B,CAAC;AAED;;;;;GAKG;AACH,IAAI,cAAc,GAAqB,IAAI,CAAC;AAE5C,MAAM,UAAU,cAAc;IAC5B,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5B,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;QAC5B,cAAc,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACtC,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,CAAC;QACH,0BAA0B;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,aAAa,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAC1F,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,cAAc,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YACtC,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,iEAAiE;QACjE,cAAc,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QACrC,OAAO,cAAc,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,cAAc,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACtC,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../../src/hooks/platform.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ import * as path from 'path';
|
|
|
16
16
|
import * as fs from 'fs';
|
|
17
17
|
import { fileURLToPath } from 'url';
|
|
18
18
|
import { findProjectRoot, spawnNodeBackground, outputHookResult, consumeStdin, appendLog, } from './platform.js';
|
|
19
|
+
import { cleanOrphanedStateFiles } from '../utils/state-cleanup.js';
|
|
19
20
|
// Proper cross-platform URL-to-path conversion
|
|
20
21
|
const __filename = fileURLToPath(import.meta.url);
|
|
21
22
|
const __dirname = path.dirname(__filename);
|
|
@@ -43,6 +44,12 @@ async function main() {
|
|
|
43
44
|
// Consume stdin (required by hook protocol)
|
|
44
45
|
await consumeStdin();
|
|
45
46
|
const logFile = path.join(projectRoot, '.specweave', 'logs', 'session-start.log');
|
|
47
|
+
// v1.0.254: Clean up orphaned state files on session start
|
|
48
|
+
const stateDir = path.join(projectRoot, '.specweave', 'state');
|
|
49
|
+
const cleaned = cleanOrphanedStateFiles(stateDir);
|
|
50
|
+
if (cleaned > 0) {
|
|
51
|
+
appendLog(logFile, `Cleaned ${cleaned} orphaned state files`);
|
|
52
|
+
}
|
|
46
53
|
const distHooksDir = path.join(projectRoot, 'node_modules', 'specweave', 'dist', 'hooks');
|
|
47
54
|
// Check for processor script
|
|
48
55
|
// First try: built hooks in dist (production)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../../src/hooks/session-start.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,SAAS,GACV,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../../src/hooks/session-start.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,SAAS,GACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,+CAA+C;AAC/C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C;;GAEG;AACH,SAAS,eAAe;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,0BAA0B;IAC1B,IAAI,eAAe,EAAE,EAAE,CAAC;QACtB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,oBAAoB;IACpB,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,4CAA4C;IAC5C,MAAM,YAAY,EAAE,CAAC;IAErB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAElF,2DAA2D;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,SAAS,CAAC,OAAO,EAAE,WAAW,OAAO,uBAAuB,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAE1F,6BAA6B;IAC7B,8CAA8C;IAC9C,2DAA2D;IAC3D,IAAI,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC9D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,uEAAuE;QACvE,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACzD,CAAC;IAED,+CAA+C;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,mBAAmB,CAAC,eAAe,EAAE,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC;QAC9E,IAAI,KAAK,EAAE,CAAC;YACV,SAAS,CAAC,OAAO,EAAE,2BAA2B,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,IAAI,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,sBAAsB,CAAC,CAAC;IACtE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,uEAAuE;QACvE,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;IACjE,CAAC;IAED,wDAAwD;IACxD,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,wCAAwC;YACxC,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;YACtD,IAAI,OAAO,eAAe,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;gBAC7D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;gBACrE,IAAI,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;oBACnC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;oBAC1E,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,CAAC,OAAO,EAAE,2BAA2B,GAAG,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,gBAAgB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,WAAW;AACX,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,yCAAyC;AAC5D,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story Router
|
|
3
|
+
*
|
|
4
|
+
* Routes user stories to repos by prefix matching.
|
|
5
|
+
* Format: US-{PREFIX}-{NUM} → matches repo with that prefix.
|
|
6
|
+
* Falls back to first repo (or custom default) when no match.
|
|
7
|
+
*/
|
|
8
|
+
import type { ChildRepoConfig } from '../core/config/types.js';
|
|
9
|
+
export interface StoryRoutingResult {
|
|
10
|
+
/** Matched repo ID, or null if no repos available */
|
|
11
|
+
repoId: string | null;
|
|
12
|
+
/** Whether routing was an explicit prefix match */
|
|
13
|
+
matched: boolean;
|
|
14
|
+
/** Reason for routing decision (useful for debugging) */
|
|
15
|
+
reason: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extract prefix from a user story ID.
|
|
19
|
+
*
|
|
20
|
+
* Supports: US-FE-001, US-SHARED-042, us-be-007 (case-insensitive)
|
|
21
|
+
* Returns null for: US-001 (no prefix), STORY-123 (wrong format)
|
|
22
|
+
*
|
|
23
|
+
* @param storyId - The story identifier (e.g., "US-FE-001")
|
|
24
|
+
* @returns Extracted prefix in uppercase, or null
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractPrefix(storyId: string): string | null;
|
|
27
|
+
/**
|
|
28
|
+
* Route a user story to a repo by prefix matching.
|
|
29
|
+
*
|
|
30
|
+
* @param storyId - Story identifier (e.g., "US-FE-001")
|
|
31
|
+
* @param childRepos - Available repos with prefix config
|
|
32
|
+
* @param defaultRepoId - Optional explicit default repo ID
|
|
33
|
+
* @returns Routing result with repoId, matched flag, and reason
|
|
34
|
+
*/
|
|
35
|
+
export declare function routeByPrefix(storyId: string, childRepos: ChildRepoConfig[], defaultRepoId?: string): StoryRoutingResult;
|
|
36
|
+
//# sourceMappingURL=story-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-router.d.ts","sourceRoot":"","sources":["../../../src/sync/story-router.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,mDAAmD;IACnD,OAAO,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ5D;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,eAAe,EAAE,EAC7B,aAAa,CAAC,EAAE,MAAM,GACrB,kBAAkB,CA0BpB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story Router
|
|
3
|
+
*
|
|
4
|
+
* Routes user stories to repos by prefix matching.
|
|
5
|
+
* Format: US-{PREFIX}-{NUM} → matches repo with that prefix.
|
|
6
|
+
* Falls back to first repo (or custom default) when no match.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Extract prefix from a user story ID.
|
|
10
|
+
*
|
|
11
|
+
* Supports: US-FE-001, US-SHARED-042, us-be-007 (case-insensitive)
|
|
12
|
+
* Returns null for: US-001 (no prefix), STORY-123 (wrong format)
|
|
13
|
+
*
|
|
14
|
+
* @param storyId - The story identifier (e.g., "US-FE-001")
|
|
15
|
+
* @returns Extracted prefix in uppercase, or null
|
|
16
|
+
*/
|
|
17
|
+
export function extractPrefix(storyId) {
|
|
18
|
+
if (!storyId)
|
|
19
|
+
return null;
|
|
20
|
+
// Match US-{PREFIX}-{NUM} where PREFIX is 2-6 letters
|
|
21
|
+
const match = storyId.match(/^US-([A-Za-z]{2,6})-\d+/i);
|
|
22
|
+
if (!match)
|
|
23
|
+
return null;
|
|
24
|
+
return match[1].toUpperCase();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Route a user story to a repo by prefix matching.
|
|
28
|
+
*
|
|
29
|
+
* @param storyId - Story identifier (e.g., "US-FE-001")
|
|
30
|
+
* @param childRepos - Available repos with prefix config
|
|
31
|
+
* @param defaultRepoId - Optional explicit default repo ID
|
|
32
|
+
* @returns Routing result with repoId, matched flag, and reason
|
|
33
|
+
*/
|
|
34
|
+
export function routeByPrefix(storyId, childRepos, defaultRepoId) {
|
|
35
|
+
if (childRepos.length === 0) {
|
|
36
|
+
return { repoId: null, matched: false, reason: 'No repos configured' };
|
|
37
|
+
}
|
|
38
|
+
const fallbackId = defaultRepoId
|
|
39
|
+
? (childRepos.find(r => r.id === defaultRepoId)?.id ?? childRepos[0].id)
|
|
40
|
+
: childRepos[0].id;
|
|
41
|
+
const prefix = extractPrefix(storyId);
|
|
42
|
+
if (!prefix) {
|
|
43
|
+
return { repoId: fallbackId, matched: false, reason: 'No prefix in story ID' };
|
|
44
|
+
}
|
|
45
|
+
// Try exact prefix match
|
|
46
|
+
const matched = childRepos.find(r => r.prefix && r.prefix.toUpperCase() === prefix);
|
|
47
|
+
if (matched) {
|
|
48
|
+
return { repoId: matched.id, matched: true, reason: `Matched prefix ${prefix}` };
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
repoId: fallbackId,
|
|
52
|
+
matched: false,
|
|
53
|
+
reason: `Unknown prefix "${prefix}" — using default`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=story-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-router.js","sourceRoot":"","sources":["../../../src/sync/story-router.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,sDAAsD;IACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,UAA6B,EAC7B,aAAsB;IAEtB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;IACzE,CAAC;IAED,MAAM,UAAU,GAAG,aAAa;QAC9B,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,aAAa,CAAC,EAAE,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAErB,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IACjF,CAAC;IAED,yBAAyB;IACzB,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;IACpF,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,MAAM,EAAE,EAAE,CAAC;IACnF,CAAC;IAED,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,mBAAmB,MAAM,mBAAmB;KACrD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State directory cleanup utility (v1.0.254)
|
|
3
|
+
*
|
|
4
|
+
* Removes orphaned marker files from .specweave/state/ that accumulate
|
|
5
|
+
* over time and are never cleaned up. These don't cause functional issues
|
|
6
|
+
* but contribute to state directory bloat.
|
|
7
|
+
*
|
|
8
|
+
* Called from session-start hook to run once per session.
|
|
9
|
+
*
|
|
10
|
+
* @module utils/state-cleanup
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Remove orphaned state marker files older than 7 days.
|
|
14
|
+
*
|
|
15
|
+
* @param stateDir - Path to .specweave/state/ directory
|
|
16
|
+
* @returns Number of files removed
|
|
17
|
+
*/
|
|
18
|
+
export declare function cleanOrphanedStateFiles(stateDir: string): number;
|
|
19
|
+
//# sourceMappingURL=state-cleanup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-cleanup.d.ts","sourceRoot":"","sources":["../../../src/utils/state-cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgChE"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State directory cleanup utility (v1.0.254)
|
|
3
|
+
*
|
|
4
|
+
* Removes orphaned marker files from .specweave/state/ that accumulate
|
|
5
|
+
* over time and are never cleaned up. These don't cause functional issues
|
|
6
|
+
* but contribute to state directory bloat.
|
|
7
|
+
*
|
|
8
|
+
* Called from session-start hook to run once per session.
|
|
9
|
+
*
|
|
10
|
+
* @module utils/state-cleanup
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
/** Patterns of orphaned marker files to clean up */
|
|
15
|
+
const ORPHAN_PATTERNS = [
|
|
16
|
+
/^\.prev-status-/,
|
|
17
|
+
/^\.github-sync-/,
|
|
18
|
+
/^\.living-specs-/,
|
|
19
|
+
];
|
|
20
|
+
/** Files older than this (in ms) are eligible for cleanup */
|
|
21
|
+
const MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
22
|
+
/**
|
|
23
|
+
* Remove orphaned state marker files older than 7 days.
|
|
24
|
+
*
|
|
25
|
+
* @param stateDir - Path to .specweave/state/ directory
|
|
26
|
+
* @returns Number of files removed
|
|
27
|
+
*/
|
|
28
|
+
export function cleanOrphanedStateFiles(stateDir) {
|
|
29
|
+
if (!fs.existsSync(stateDir))
|
|
30
|
+
return 0;
|
|
31
|
+
let removed = 0;
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
try {
|
|
34
|
+
const entries = fs.readdirSync(stateDir);
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
// Check if filename matches any orphan pattern
|
|
37
|
+
const isOrphan = ORPHAN_PATTERNS.some(pattern => pattern.test(entry));
|
|
38
|
+
if (!isOrphan)
|
|
39
|
+
continue;
|
|
40
|
+
const filePath = path.join(stateDir, entry);
|
|
41
|
+
try {
|
|
42
|
+
const stat = fs.statSync(filePath);
|
|
43
|
+
if (!stat.isFile())
|
|
44
|
+
continue;
|
|
45
|
+
const age = now - stat.mtimeMs;
|
|
46
|
+
if (age > MAX_AGE_MS) {
|
|
47
|
+
fs.unlinkSync(filePath);
|
|
48
|
+
removed++;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Skip files we can't stat or delete
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Directory read failed — not critical
|
|
58
|
+
}
|
|
59
|
+
return removed;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=state-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-cleanup.js","sourceRoot":"","sources":["../../../src/utils/state-cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,oDAAoD;AACpD,MAAM,eAAe,GAAG;IACtB,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;CACnB,CAAC;AAEF,6DAA6D;AAC7D,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;AAErD;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,CAAC;IAEvC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,+CAA+C;YAC/C,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,IAAI,CAAC,QAAQ;gBAAE,SAAS;YAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5C,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;oBAAE,SAAS;gBAE7B,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC/B,IAAI,GAAG,GAAG,UAAU,EAAE,CAAC;oBACrB,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACxB,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,uCAAuC;IACzC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.254",
|
|
4
4
|
"description": "Spec-driven development framework for AI coding agents. First-class support for Claude Code — compatible with any LLM-powered coding tool. Living documentation, autonomous execution, quality gates, and multilingual support (9 languages).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -371,17 +371,40 @@ escape_json_early() {
|
|
|
371
371
|
fi
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
# v1.0.254: Prompt safety limits to prevent "Prompt is too long" errors
|
|
375
|
+
# These must match the constants in src/core/lazy-loading/llm-plugin-detector.ts
|
|
376
|
+
MAX_ADDITIONAL_CONTEXT_LENGTH=8000
|
|
377
|
+
MAX_SKILL_FIRST_PROMPT_LENGTH=2000
|
|
378
|
+
|
|
374
379
|
# Helper: Output approve response with context (Claude Code hook format v1.0.166)
|
|
375
380
|
# CRITICAL: systemMessage is NOT a valid field for UserPromptSubmit hooks!
|
|
376
381
|
# Use hookSpecificOutput.additionalContext instead.
|
|
377
382
|
# See: https://docs.claude.com/en/docs/claude-code/hooks
|
|
383
|
+
#
|
|
384
|
+
# v1.0.254: Added size guard — truncates additionalContext if it exceeds
|
|
385
|
+
# MAX_ADDITIONAL_CONTEXT_LENGTH to prevent "Prompt is too long" errors.
|
|
378
386
|
output_approve_with_context() {
|
|
379
387
|
local context="$1"
|
|
388
|
+
# v1.0.254: Safety truncation to prevent prompt overflow
|
|
389
|
+
if [[ ${#context} -gt $MAX_ADDITIONAL_CONTEXT_LENGTH ]]; then
|
|
390
|
+
context="${context:0:$MAX_ADDITIONAL_CONTEXT_LENGTH}... [context truncated for safety]"
|
|
391
|
+
fi
|
|
380
392
|
local escaped
|
|
381
393
|
escaped=$(escape_json_early "$context")
|
|
382
394
|
printf '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":"%s"}}\n' "$escaped"
|
|
383
395
|
}
|
|
384
396
|
|
|
397
|
+
# Helper: Truncate and escape a prompt for SKILL FIRST args (v1.0.254)
|
|
398
|
+
# Truncates to MAX_SKILL_FIRST_PROMPT_LENGTH, escapes for JSON embedding.
|
|
399
|
+
# Args: $1=raw prompt text
|
|
400
|
+
# Returns: Escaped, truncated prompt on stdout
|
|
401
|
+
truncate_and_escape_prompt() {
|
|
402
|
+
local prompt="$1"
|
|
403
|
+
local truncated="${prompt:0:$MAX_SKILL_FIRST_PROMPT_LENGTH}"
|
|
404
|
+
[[ ${#prompt} -gt $MAX_SKILL_FIRST_PROMPT_LENGTH ]] && truncated="${truncated}... [truncated - see original prompt above]"
|
|
405
|
+
printf '%s' "$truncated" | sed 's/\\/\\\\/g; s/"/\\"/g; s/ /\\t/g' | tr '\n' ' '
|
|
406
|
+
}
|
|
407
|
+
|
|
385
408
|
# Helper: Get skill memory content for injection (v1.0.198)
|
|
386
409
|
# Reads .specweave/skill-memories/{skill}.md and extracts learnings.
|
|
387
410
|
# Args: $1=full skill name (e.g., "sw:pm", "sw-frontend:frontend-architect")
|
|
@@ -1386,12 +1409,11 @@ Task({
|
|
|
1386
1409
|
[[ -n "$INC_NAME" ]] && CMD="/sw:increment \"$INC_NAME\""
|
|
1387
1410
|
|
|
1388
1411
|
# v1.0.169: Call sw:increment-planner DIRECTLY (not wrapper)
|
|
1389
|
-
# Pass
|
|
1412
|
+
# Pass user prompt so skill can extract context
|
|
1390
1413
|
# INC_MANDATORY comes from detect-intent LLM response
|
|
1391
1414
|
if [[ "$INC_MANDATORY" == "true" ]]; then
|
|
1392
|
-
#
|
|
1393
|
-
|
|
1394
|
-
ESCAPED_PROMPT=$(printf '%s' "$PROMPT" | sed 's/\\/\\\\/g; s/"/\\"/g; s/ /\\t/g' | tr '\n' ' ')
|
|
1415
|
+
# v1.0.254: Truncate + escape to prevent "Prompt is too long"
|
|
1416
|
+
ESCAPED_PROMPT=$(truncate_and_escape_prompt "$PROMPT")
|
|
1395
1417
|
|
|
1396
1418
|
# v1.0.243: Smart interview gate — LLM assesses prompt completeness
|
|
1397
1419
|
# before blindly calling increment-planner. If details are missing,
|
|
@@ -1466,7 +1488,7 @@ See CLAUDE.md section \"MANDATORY: Skill Chaining\" for full pattern."
|
|
|
1466
1488
|
exit 0
|
|
1467
1489
|
else
|
|
1468
1490
|
# v1.0.169: Also suggest direct skill call for non-mandatory
|
|
1469
|
-
ESCAPED_PROMPT_SUGGEST=$(
|
|
1491
|
+
ESCAPED_PROMPT_SUGGEST=$(truncate_and_escape_prompt "$PROMPT")
|
|
1470
1492
|
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}💡 **Increment Suggestion**: This looks like new feature work.
|
|
1471
1493
|
|
|
1472
1494
|
Consider creating an increment first:
|
|
@@ -1488,7 +1510,7 @@ Or via command: \`$CMD\`
|
|
|
1488
1510
|
|
|
1489
1511
|
hotfix)
|
|
1490
1512
|
# v1.0.169: Direct skill call for hotfix too
|
|
1491
|
-
ESCAPED_PROMPT_HOTFIX=$(
|
|
1513
|
+
ESCAPED_PROMPT_HOTFIX=$(truncate_and_escape_prompt "$PROMPT")
|
|
1492
1514
|
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}🚨 **Hotfix Detected**: Urgent production issue.
|
|
1493
1515
|
|
|
1494
1516
|
Create a hotfix increment:
|
|
@@ -1530,7 +1552,7 @@ specweave resume <id> # Reopen it
|
|
|
1530
1552
|
small_fix)
|
|
1531
1553
|
# v1.0.241: small_fix still suggests increment (non-mandatory)
|
|
1532
1554
|
# Previously small_fix fell through with no output at all
|
|
1533
|
-
ESCAPED_PROMPT_SMALLFIX=$(
|
|
1555
|
+
ESCAPED_PROMPT_SMALLFIX=$(truncate_and_escape_prompt "$PROMPT")
|
|
1534
1556
|
CMD_SMALLFIX="/sw:increment"
|
|
1535
1557
|
[[ -n "$INC_NAME" ]] && CMD_SMALLFIX="/sw:increment \"$INC_NAME\""
|
|
1536
1558
|
|
|
@@ -532,143 +532,37 @@ MCP supports lazy-loading (auto mode) - tools load on-demand when >10% context.
|
|
|
532
532
|
<!-- /SECTION -->
|
|
533
533
|
|
|
534
534
|
<!-- SECTION:non-claude -->
|
|
535
|
-
##
|
|
535
|
+
## Using SpecWeave with Other AI Tools
|
|
536
536
|
|
|
537
|
-
**
|
|
537
|
+
**Not using Claude Code?** See **AGENTS.md** for complete instructions on using SpecWeave with Cursor, Copilot, Windsurf, Aider, and other AI coding assistants.
|
|
538
538
|
|
|
539
|
-
###
|
|
539
|
+
### Key Differences for Non-Claude Tools
|
|
540
|
+
|
|
541
|
+
| Feature | Claude Code | Other Tools |
|
|
542
|
+
|---------|-------------|-------------|
|
|
543
|
+
| **Hooks** | Automatic | Manual sync required (see AGENTS.md) |
|
|
544
|
+
| **Commands** | Slash syntax works | Read command .md files |
|
|
545
|
+
| **Skills** | Auto-activate | Load .md files manually |
|
|
546
|
+
| **Task tracking** | Auto-updates | Manual checkbox updates |
|
|
547
|
+
|
|
548
|
+
### Quick Start (Non-Claude)
|
|
540
549
|
|
|
541
550
|
```bash
|
|
542
|
-
# Install SpecWeave
|
|
551
|
+
# 1. Install SpecWeave globally
|
|
543
552
|
npm install -g specweave
|
|
544
553
|
|
|
545
|
-
# Initialize project
|
|
554
|
+
# 2. Initialize your project
|
|
546
555
|
specweave init .
|
|
547
556
|
|
|
548
|
-
#
|
|
549
|
-
|
|
550
|
-
# Or on Windows PowerShell:
|
|
551
|
-
~\.specweave\scripts\install-plugins.ps1 -Target generic
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
### Manual Context Loading (Cursor, Windsurf, Aider, etc.)
|
|
555
|
-
|
|
556
|
-
If your AI tool doesn't have a plugin system, manually include these files in context:
|
|
557
|
-
|
|
558
|
-
**Essential files to include in EVERY session:**
|
|
559
|
-
1. `CLAUDE.md` (this file) - Framework rules and workflow
|
|
560
|
-
2. `.specweave/increments/####-*/tasks.md` - Current work items
|
|
561
|
-
3. `.specweave/increments/####-*/spec.md` - Requirements and ACs
|
|
562
|
-
|
|
563
|
-
**Copy-paste starter prompt:**
|
|
564
|
-
```
|
|
565
|
-
I'm using SpecWeave for spec-driven development. Here are my current files:
|
|
566
|
-
|
|
567
|
-
[PASTE CLAUDE.md CONTENT]
|
|
568
|
-
|
|
569
|
-
[PASTE CURRENT tasks.md CONTENT]
|
|
570
|
-
|
|
571
|
-
[PASTE CURRENT spec.md CONTENT]
|
|
572
|
-
|
|
573
|
-
Follow SpecWeave workflow: update tasks.md checkboxes when done, update spec.md ACs.
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
### Tool-Specific Setup
|
|
577
|
-
|
|
578
|
-
**Cursor IDE:**
|
|
579
|
-
- Add `.specweave/` to workspace folders
|
|
580
|
-
- Include `CLAUDE.md` in `.cursorrules`
|
|
581
|
-
- Use `@file` to reference spec.md and tasks.md
|
|
582
|
-
|
|
583
|
-
**Windsurf:**
|
|
584
|
-
- Add this file content to cascade rules
|
|
585
|
-
- Reference increment files with `/file` command
|
|
586
|
-
|
|
587
|
-
**Aider:**
|
|
588
|
-
- Add CLAUDE.md to `.aider.conf.yml`:
|
|
589
|
-
```yaml
|
|
590
|
-
read:
|
|
591
|
-
- CLAUDE.md
|
|
592
|
-
- .specweave/increments/*/spec.md
|
|
593
|
-
- .specweave/increments/*/tasks.md
|
|
594
|
-
```
|
|
595
|
-
|
|
596
|
-
**Continue.dev:**
|
|
597
|
-
- Add to `.continue/config.json`:
|
|
598
|
-
```json
|
|
599
|
-
{
|
|
600
|
-
"contextProviders": [{
|
|
601
|
-
"name": "file",
|
|
602
|
-
"params": { "path": "CLAUDE.md" }
|
|
603
|
-
}]
|
|
604
|
-
}
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
**GitHub Copilot:**
|
|
608
|
-
- Add to `.github/copilot-instructions.md`:
|
|
609
|
-
```
|
|
610
|
-
Follow SpecWeave workflow from CLAUDE.md.
|
|
611
|
-
Check .specweave/increments/ for current tasks.
|
|
612
|
-
Update tasks.md when completing work.
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
### Hook Simulation (CRITICAL for Non-Claude Tools)
|
|
616
|
-
|
|
617
|
-
Claude Code runs hooks automatically. **You must trigger these manually:**
|
|
618
|
-
|
|
619
|
-
| When | What To Do |
|
|
620
|
-
|------|------------|
|
|
621
|
-
| **After EVERY task** | Update tasks.md `[ ]→[x]` + spec.md ACs `[ ]→[x]` + `/sw:sync-tasks` |
|
|
622
|
-
| **After all ACs done** | `/sw:sync-docs update` to sync living docs |
|
|
623
|
-
| **On increment close** | `/sw:validate {id}` then `/sw:done {id}` |
|
|
624
|
-
| **Session start** | Check `specweave jobs` + `/sw:progress` for current state |
|
|
625
|
-
|
|
626
|
-
**Full hook simulation guide:** See `AGENTS.md` for detailed instructions.
|
|
627
|
-
|
|
628
|
-
### Replicating SpecWeave Behaviors
|
|
629
|
-
|
|
630
|
-
| SpecWeave Feature | Manual Equivalent |
|
|
631
|
-
|-------------------|-------------------|
|
|
632
|
-
| `/sw:increment` | Create `spec.md` + `tasks.md` (every US needs `**Project**:` field!) |
|
|
633
|
-
| `/sw:do` | Read tasks.md, work on pending tasks, update checkboxes |
|
|
634
|
-
| `/sw:done` | `/sw:validate` then close |
|
|
635
|
-
| Auto mode | Loop: read tasks.md → work → update → test → repeat |
|
|
636
|
-
|
|
637
|
-
**Task format for any AI:**
|
|
638
|
-
```markdown
|
|
639
|
-
### T-001: Task Title
|
|
640
|
-
**Status**: [ ] pending
|
|
641
|
-
**Acceptance**: Given X, When Y, Then Z
|
|
642
|
-
|
|
643
|
-
Implementation notes here.
|
|
557
|
+
# 3. Read AGENTS.md for your specific tool
|
|
558
|
+
cat AGENTS.md # or open in your editor
|
|
644
559
|
```
|
|
645
560
|
|
|
646
|
-
**
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
```bash
|
|
653
|
-
# Pseudo-code for any AI tool with API access
|
|
654
|
-
while tasks_pending():
|
|
655
|
-
tasks = read_file("tasks.md")
|
|
656
|
-
current_task = get_first_pending(tasks)
|
|
657
|
-
|
|
658
|
-
# Have AI work on task
|
|
659
|
-
result = ai.complete(f"Complete this task: {current_task}")
|
|
660
|
-
|
|
661
|
-
# Update files
|
|
662
|
-
update_task_status(current_task, "completed")
|
|
663
|
-
|
|
664
|
-
# Run tests
|
|
665
|
-
if not run_tests():
|
|
666
|
-
ai.complete("Fix failing tests")
|
|
667
|
-
|
|
668
|
-
# Max iterations safety
|
|
669
|
-
if iterations > 100:
|
|
670
|
-
break
|
|
671
|
-
```
|
|
561
|
+
**Essential workflow for ANY AI tool:**
|
|
562
|
+
1. After completing a task → Update `tasks.md`: `[ ]` → `[x]`
|
|
563
|
+
2. If task satisfies ACs → Update `spec.md`: `[ ] AC-XX` → `[x] AC-XX`
|
|
564
|
+
3. Run `/sw:sync-tasks` to update progress cache
|
|
565
|
+
4. When all tasks done → Run `/sw:done {id}` to close increment
|
|
672
566
|
|
|
673
|
-
**
|
|
567
|
+
**Full guide with hook simulation, tool-specific setup, and workflows**: See **AGENTS.md**
|
|
674
568
|
<!-- /SECTION -->
|