speccrew 0.1.0
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/.speccrew/agents/speccrew-feature-designer.md +142 -0
- package/.speccrew/agents/speccrew-product-manager.md +61 -0
- package/.speccrew/agents/speccrew-system-designer.md +200 -0
- package/.speccrew/agents/speccrew-system-developer.md +238 -0
- package/.speccrew/agents/speccrew-task-worker.md +80 -0
- package/.speccrew/agents/speccrew-team-leader.md +92 -0
- package/.speccrew/agents/speccrew-test-manager.md +313 -0
- package/.speccrew/skills/speccrew-create-agents/SKILL.md +98 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/designer-agent.md +54 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/dev-agent.md +79 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/test-agent.md +80 -0
- package/.speccrew/skills/speccrew-dev-backend/SKILL.md +205 -0
- package/.speccrew/skills/speccrew-dev-backend/templates/TASK-RECORD-TEMPLATE.md +118 -0
- package/.speccrew/skills/speccrew-dev-desktop/SKILL.md +258 -0
- package/.speccrew/skills/speccrew-dev-desktop/templates/TASK-RECORD-TEMPLATE.md +161 -0
- package/.speccrew/skills/speccrew-dev-frontend/SKILL.md +202 -0
- package/.speccrew/skills/speccrew-dev-frontend/templates/TASK-RECORD-TEMPLATE.md +115 -0
- package/.speccrew/skills/speccrew-dev-mobile/SKILL.md +200 -0
- package/.speccrew/skills/speccrew-dev-mobile/templates/TASK-RECORD-TEMPLATE.md +125 -0
- package/.speccrew/skills/speccrew-fd-api-contract/SKILL.md +73 -0
- package/.speccrew/skills/speccrew-fd-api-contract/templates/API-CONTRACT-TEMPLATE.md +96 -0
- package/.speccrew/skills/speccrew-fd-feature-design/SKILL.md +395 -0
- package/.speccrew/skills/speccrew-fd-feature-design/templates/FEATURE-SPEC-TEMPLATE.md +387 -0
- package/.speccrew/skills/speccrew-get-timestamp/SKILL.md +80 -0
- package/.speccrew/skills/speccrew-get-timestamp/scripts/get-timestamp.js +35 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/SKILL.md +1116 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-FASTAPI.md +462 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-JAVA.md +480 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-NET.md +464 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE.md +480 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/MODULE-OVERVIEW-TEMPLATE.md +367 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/SKILL.md +667 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/STATUS-FORMATS.md +74 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/batch-orchestrator.js +176 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/get-next-batch.js +150 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/get-pending-features.js +106 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/mark-stale.js +249 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/process-batch-results.js +848 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/update-feature-status.js +226 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/SKILL.md +264 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/examples/features.json +34 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js +867 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/test-inventory.js +26 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/SKILL.md +165 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/apply-module-mapping.js +208 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/extract-module-summary.js +180 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/reindex-modules.js +358 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/SKILL.md +1055 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-DESKTOP.md +303 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-ELECTRON.md +327 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-MINIAPP.md +292 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-MOBILE.md +281 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI.md +324 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/SKILL.md +270 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/COMPONENT-PATTERN-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/LAYOUT-PATTERN-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/PAGE-TYPE-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-graph-query/SKILL.md +229 -0
- package/.speccrew/skills/speccrew-knowledge-graph-query/scripts/graph-query.js +549 -0
- package/.speccrew/skills/speccrew-knowledge-graph-write/SKILL.md +181 -0
- package/.speccrew/skills/speccrew-knowledge-graph-write/scripts/graph-write.js +651 -0
- package/.speccrew/skills/speccrew-knowledge-module-summarize/SKILL.md +305 -0
- package/.speccrew/skills/speccrew-knowledge-module-summarize/templates/MODULE-OVERVIEW-TEMPLATE.md +400 -0
- package/.speccrew/skills/speccrew-knowledge-system-summarize/SKILL.md +351 -0
- package/.speccrew/skills/speccrew-knowledge-system-summarize/templates/SYSTEM-OVERVIEW-TEMPLATE.md +294 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/SKILL.md +683 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/STATUS-FORMATS.md +550 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/templates/techs-manifest-EXAMPLE.json +35 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/SKILL.md +1087 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/ARCHITECTURE-TEMPLATE.md +240 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/COLOR-SYSTEM-TEMPLATE.md +68 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/COMPONENT-LIBRARY-TEMPLATE.md +86 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-BUILD-TEMPLATE.md +466 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DATA-TEMPLATE.md +432 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DESIGN-TEMPLATE.md +1209 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DEV-TEMPLATE.md +1433 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-SYSTEM-TEST-TEMPLATE.md +1052 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-UNIT-TEST-TEMPLATE.md +946 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/INDEX-TEMPLATE.md +29 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/PAGE-LAYOUTS-TEMPLATE.md +69 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/PAGE-TYPE-SUMMARY-TEMPLATE.md +74 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/TECH-STACK-TEMPLATE.md +232 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate-conventions/SKILL.md +628 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate-ui-style/SKILL.md +392 -0
- package/.speccrew/skills/speccrew-knowledge-techs-index/SKILL.md +489 -0
- package/.speccrew/skills/speccrew-knowledge-techs-index/templates/INDEX-TEMPLATE.md +243 -0
- package/.speccrew/skills/speccrew-knowledge-techs-init/SKILL.md +269 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/SKILL.md +562 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/BUSINESS-COMPONENTS-TEMPLATE.md +171 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMMON-COMPONENTS-TEMPLATE.md +177 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMPONENT-INDIVIDUAL-TEMPLATE.md +80 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMPONENT-LIBRARY-TEMPLATE.md +118 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/LAYOUT-INDIVIDUAL-TEMPLATE.md +97 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/LAYOUT-PATTERNS-TEMPLATE.md +208 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/NAVIGATION-PATTERNS-TEMPLATE.md +157 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/PAGE-TYPE-INDIVIDUAL-TEMPLATE.md +123 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/PAGE-TYPE-SUMMARY-TEMPLATE.md +58 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/SPACING-TEMPLATE.md +119 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/STYLE-SYSTEM-TEMPLATE.md +117 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/TYPOGRAPHY-TEMPLATE.md +107 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/UI-STYLE-GUIDE-TEMPLATE.md +171 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/SKILL.md +434 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/templates/BIZS-MODELING-TEMPLATE.md +332 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/templates/PRD-TEMPLATE.md +200 -0
- package/.speccrew/skills/speccrew-pm-requirement-assess/SKILL.md +195 -0
- package/.speccrew/skills/speccrew-project-diagnosis/SKILL.md +208 -0
- package/.speccrew/skills/speccrew-project-diagnosis/templates/DIAGNOSIS-REPORT-TEMPLATE.md +202 -0
- package/.speccrew/skills/speccrew-sd-backend/SKILL.md +188 -0
- package/.speccrew/skills/speccrew-sd-backend/templates/INDEX-TEMPLATE.md +85 -0
- package/.speccrew/skills/speccrew-sd-backend/templates/SD-BACKEND-TEMPLATE.md +269 -0
- package/.speccrew/skills/speccrew-sd-desktop/SKILL.md +192 -0
- package/.speccrew/skills/speccrew-sd-desktop/templates/INDEX-TEMPLATE.md +271 -0
- package/.speccrew/skills/speccrew-sd-desktop/templates/SD-DESKTOP-TEMPLATE.md +673 -0
- package/.speccrew/skills/speccrew-sd-frontend/SKILL.md +176 -0
- package/.speccrew/skills/speccrew-sd-frontend/templates/INDEX-TEMPLATE.md +184 -0
- package/.speccrew/skills/speccrew-sd-frontend/templates/SD-FRONTEND-TEMPLATE.md +382 -0
- package/.speccrew/skills/speccrew-sd-mobile/SKILL.md +189 -0
- package/.speccrew/skills/speccrew-sd-mobile/templates/INDEX-TEMPLATE.md +219 -0
- package/.speccrew/skills/speccrew-sd-mobile/templates/SD-MOBILE-TEMPLATE.md +534 -0
- package/.speccrew/skills/speccrew-test-case-design/SKILL.md +284 -0
- package/.speccrew/skills/speccrew-test-case-design/templates/TEST-CASE-DESIGN-TEMPLATE.md +263 -0
- package/.speccrew/skills/speccrew-test-code-gen/SKILL.md +313 -0
- package/.speccrew/skills/speccrew-test-code-gen/templates/TEST-CODE-PLAN-TEMPLATE.md +180 -0
- package/.speccrew/skills/speccrew-test-execute/SKILL.md +283 -0
- package/.speccrew/skills/speccrew-test-execute/templates/BUG-REPORT-TEMPLATE.md +50 -0
- package/.speccrew/skills/speccrew-test-execute/templates/TEST-REPORT-TEMPLATE.md +57 -0
- package/.speccrew/skills/speccrew-workflow-diagnose/SKILL.md +155 -0
- package/LICENSE +21 -0
- package/README.ar.md +318 -0
- package/README.en.md +318 -0
- package/README.es.md +318 -0
- package/README.md +340 -0
- package/bin/cli.js +62 -0
- package/lib/commands/doctor.js +138 -0
- package/lib/commands/init.js +231 -0
- package/lib/commands/list.js +114 -0
- package/lib/commands/uninstall.js +117 -0
- package/lib/commands/update.js +351 -0
- package/lib/ide-adapters.js +73 -0
- package/lib/utils.js +104 -0
- package/package.json +28 -0
- package/workspace-template/docs/configs/document-templates.json +667 -0
- package/workspace-template/docs/configs/platform-mapping.json +194 -0
- package/workspace-template/docs/configs/tech-stack-mappings.json +313 -0
- package/workspace-template/docs/configs/validation-rules.json +87 -0
- package/workspace-template/docs/rules/mermaid-rule.md +114 -0
- package/workspace-template/docs/solutions/Agent/346/212/200/350/203/275/345/256/232/344/271/211+/351/234/200/346/261/202/346/226/207/346/241/243+UML/344/275/277/347/224/250/346/250/241/346/235/277/357/274/210ISA-95/345/205/255/346/256/265/345/274/217/350/236/215/345/220/210/347/211/210/357/274/211.md +586 -0
- package/workspace-template/docs/solutions/agent-knowledge-map.md +238 -0
- package/workspace-template/docs/solutions/bizs-knowledge-pipeline.md +678 -0
- package/workspace-template/docs/solutions/harness.md +410 -0
- package/workspace-template/docs/solutions/knowledge-incremental-sync-spec.md +943 -0
- package/workspace-template/docs/solutions/techs-knowledge-pipeline.md +803 -0
- package/workspace-template/docs/solutions/workspace-structure.md +318 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Mark features as stale (pending re-analysis) for specified paths.
|
|
5
|
+
*
|
|
6
|
+
* Scans all features-*.json files in the SyncStatePath directory and marks
|
|
7
|
+
* features as stale when their sourcePath matches one of the provided paths.
|
|
8
|
+
* Matching supports exact path match or directory prefix match (when a
|
|
9
|
+
* directory path is provided, all features under that directory are marked).
|
|
10
|
+
*
|
|
11
|
+
* Resets the following fields for matched features:
|
|
12
|
+
* - analyzed = false
|
|
13
|
+
* - status = "pending" (if the field exists)
|
|
14
|
+
* - startedAt = null
|
|
15
|
+
* - completedAt = null
|
|
16
|
+
* - analysisNotes = null
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const path = require('path');
|
|
21
|
+
|
|
22
|
+
// Parse command line arguments
|
|
23
|
+
function parseArgs() {
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
const result = {
|
|
26
|
+
syncStatePath: null,
|
|
27
|
+
paths: []
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < args.length; i++) {
|
|
31
|
+
const arg = args[i];
|
|
32
|
+
switch (arg) {
|
|
33
|
+
case '--syncStatePath':
|
|
34
|
+
case '-SyncStatePath':
|
|
35
|
+
result.syncStatePath = args[++i];
|
|
36
|
+
break;
|
|
37
|
+
case '--paths':
|
|
38
|
+
case '-Paths':
|
|
39
|
+
// Support comma-separated paths or multiple --paths arguments
|
|
40
|
+
const pathsValue = args[++i];
|
|
41
|
+
if (pathsValue) {
|
|
42
|
+
result.paths.push(...pathsValue.split(',').map(p => p.trim()).filter(p => p));
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Helper function to safely set property on object
|
|
52
|
+
function setFeatureProperty(obj, propertyName, value) {
|
|
53
|
+
obj[propertyName] = value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Helper function to safely remove property from object
|
|
57
|
+
function removeFeatureProperty(obj, propertyName) {
|
|
58
|
+
if (propertyName in obj) {
|
|
59
|
+
delete obj[propertyName];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Helper function to normalize path for comparison
|
|
64
|
+
// - Convert backslashes to forward slashes
|
|
65
|
+
// - Remove trailing slashes
|
|
66
|
+
// - Convert to lowercase for case-insensitive comparison (Windows)
|
|
67
|
+
function normalizePath(inputPath) {
|
|
68
|
+
if (!inputPath) {
|
|
69
|
+
return '';
|
|
70
|
+
}
|
|
71
|
+
let normalized = inputPath.replace(/\\/g, '/');
|
|
72
|
+
normalized = normalized.replace(/\/$/, '');
|
|
73
|
+
return normalized.toLowerCase();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function main() {
|
|
77
|
+
try {
|
|
78
|
+
const args = parseArgs();
|
|
79
|
+
|
|
80
|
+
if (!args.syncStatePath) {
|
|
81
|
+
console.error('Error: --syncStatePath is required');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (args.paths.length === 0) {
|
|
86
|
+
console.error('Error: --paths is required');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Validate SyncStatePath exists
|
|
91
|
+
const resolvedSyncStatePath = path.resolve(args.syncStatePath);
|
|
92
|
+
if (!fs.existsSync(resolvedSyncStatePath)) {
|
|
93
|
+
console.error(`SyncStatePath not found: ${args.syncStatePath}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Normalize input paths for matching
|
|
98
|
+
const normalizedInputPaths = args.paths.map(p => normalizePath(p));
|
|
99
|
+
|
|
100
|
+
// Find all features-*.json files
|
|
101
|
+
const featureFiles = fs.readdirSync(resolvedSyncStatePath).filter(f => {
|
|
102
|
+
return f.startsWith('features-') && f.endsWith('.json') && fs.statSync(path.join(resolvedSyncStatePath, f)).isFile();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (featureFiles.length === 0) {
|
|
106
|
+
// No feature files found, output empty result
|
|
107
|
+
const result = {
|
|
108
|
+
totalAffected: 0,
|
|
109
|
+
features: []
|
|
110
|
+
};
|
|
111
|
+
console.log(JSON.stringify(result, null, 2));
|
|
112
|
+
process.exit(0);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const affectedFeatures = [];
|
|
116
|
+
|
|
117
|
+
for (const fileName of featureFiles) {
|
|
118
|
+
const filePath = path.join(resolvedSyncStatePath, fileName);
|
|
119
|
+
const lockPath = `${filePath}.lock`;
|
|
120
|
+
const maxRetries = 30;
|
|
121
|
+
let retryCount = 0;
|
|
122
|
+
let lockAcquired = false;
|
|
123
|
+
|
|
124
|
+
// Acquire file lock
|
|
125
|
+
while (!lockAcquired && retryCount < maxRetries) {
|
|
126
|
+
try {
|
|
127
|
+
// Try to create lock file exclusively
|
|
128
|
+
const fd = fs.openSync(lockPath, 'wx');
|
|
129
|
+
fs.closeSync(fd);
|
|
130
|
+
lockAcquired = true;
|
|
131
|
+
} catch (error) {
|
|
132
|
+
retryCount++;
|
|
133
|
+
if (retryCount >= maxRetries) {
|
|
134
|
+
const errorMsg = `Failed to acquire file lock for '${fileName}' after ${maxRetries} attempts (waited ${maxRetries} seconds). The file may be locked by another process.`;
|
|
135
|
+
console.warn(errorMsg);
|
|
136
|
+
// Continue to next file instead of exiting
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
if (retryCount % 5 === 0) {
|
|
140
|
+
console.warn(`Waiting for file lock on '${fileName}'... (attempt ${retryCount} of ${maxRetries})`);
|
|
141
|
+
}
|
|
142
|
+
// Wait 1 second before retry
|
|
143
|
+
const start = Date.now();
|
|
144
|
+
while (Date.now() - start < 1000) {
|
|
145
|
+
// Busy wait
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Skip this file if lock could not be acquired
|
|
151
|
+
if (!lockAcquired) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
// Read the JSON file
|
|
157
|
+
const rawContent = fs.readFileSync(filePath, 'utf8');
|
|
158
|
+
const content = JSON.parse(rawContent);
|
|
159
|
+
let fileModified = false;
|
|
160
|
+
|
|
161
|
+
if (content.features && Array.isArray(content.features)) {
|
|
162
|
+
for (let i = 0; i < content.features.length; i++) {
|
|
163
|
+
const feature = content.features[i];
|
|
164
|
+
const featureSourcePath = feature.sourcePath;
|
|
165
|
+
|
|
166
|
+
if (!featureSourcePath) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const normalizedFeaturePath = normalizePath(featureSourcePath);
|
|
171
|
+
|
|
172
|
+
// Check if any input path matches this feature
|
|
173
|
+
let matched = false;
|
|
174
|
+
for (const inputPath of normalizedInputPaths) {
|
|
175
|
+
// Exact match or directory prefix match
|
|
176
|
+
if (normalizedFeaturePath === inputPath) {
|
|
177
|
+
matched = true;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
// Directory prefix match: input path is a directory and feature path starts with it
|
|
181
|
+
if (normalizedFeaturePath.startsWith(`${inputPath}/`)) {
|
|
182
|
+
matched = true;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (matched) {
|
|
188
|
+
// Reset fields
|
|
189
|
+
setFeatureProperty(feature, 'analyzed', false);
|
|
190
|
+
|
|
191
|
+
// Only set status if the field already exists
|
|
192
|
+
if ('status' in feature) {
|
|
193
|
+
setFeatureProperty(feature, 'status', 'pending');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Clear timestamp fields
|
|
197
|
+
removeFeatureProperty(feature, 'startedAt');
|
|
198
|
+
removeFeatureProperty(feature, 'completedAt');
|
|
199
|
+
removeFeatureProperty(feature, 'analysisNotes');
|
|
200
|
+
|
|
201
|
+
content.features[i] = feature;
|
|
202
|
+
fileModified = true;
|
|
203
|
+
|
|
204
|
+
// Add to affected list
|
|
205
|
+
affectedFeatures.push({
|
|
206
|
+
sourcePath: featureSourcePath,
|
|
207
|
+
module: feature.module,
|
|
208
|
+
sourceFile: fileName
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Update counters and write back if modified
|
|
215
|
+
if (fileModified) {
|
|
216
|
+
content.analyzedCount = content.features.filter(f => f.analyzed === true).length;
|
|
217
|
+
content.pendingCount = content.features.filter(f => f.analyzed === false).length;
|
|
218
|
+
|
|
219
|
+
// Atomic write: temp file + rename
|
|
220
|
+
const tempFile = `${filePath}.tmp`;
|
|
221
|
+
fs.writeFileSync(tempFile, JSON.stringify(content, null, 2), 'utf8');
|
|
222
|
+
fs.renameSync(tempFile, filePath);
|
|
223
|
+
}
|
|
224
|
+
} finally {
|
|
225
|
+
// Release lock - remove lock file
|
|
226
|
+
try {
|
|
227
|
+
if (fs.existsSync(lockPath)) {
|
|
228
|
+
fs.unlinkSync(lockPath);
|
|
229
|
+
}
|
|
230
|
+
} catch (e) {
|
|
231
|
+
// Ignore cleanup errors
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Output result as JSON
|
|
237
|
+
const result = {
|
|
238
|
+
totalAffected: affectedFeatures.length,
|
|
239
|
+
features: affectedFeatures
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
console.log(JSON.stringify(result, null, 2));
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.error(`Error: ${error.message}`);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
main();
|