workflow-agent-cli 2.23.0 → 2.23.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -15
- package/dist/{auto-fix-7WAESKYO.js → auto-fix-WGRYEFLJ.js} +2 -2
- package/dist/{chunk-IWFUJ2DS.js → chunk-DWHIY7R4.js} +20 -9
- package/dist/chunk-DWHIY7R4.js.map +1 -0
- package/dist/{chunk-D36IFZUZ.js → chunk-EHRI6BI6.js} +15 -4
- package/dist/chunk-EHRI6BI6.js.map +1 -0
- package/dist/{chunk-M6RHIUSM.js → chunk-K42R54II.js} +147 -54
- package/dist/chunk-K42R54II.js.map +1 -0
- package/dist/{chunk-XGS2VFBP.js → chunk-MBRMT5ZG.js} +865 -18
- package/dist/chunk-MBRMT5ZG.js.map +1 -0
- package/dist/{chunk-YELUGXOM.js → chunk-NPJJZHJG.js} +1 -1
- package/dist/chunk-NPJJZHJG.js.map +1 -0
- package/dist/{chunk-UWJ2ZGEI.js → chunk-OH6TK27N.js} +3 -3
- package/dist/{chunk-ZLDJ2OGO.js → chunk-WK7D2AVV.js} +11 -3
- package/dist/{chunk-ZLDJ2OGO.js.map → chunk-WK7D2AVV.js.map} +1 -1
- package/dist/cli/index.js +771 -285
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.js +2 -2
- package/dist/index.d.ts +87 -56
- package/dist/index.js +26 -10
- package/dist/scripts/postinstall.js +1 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/sync-HHQM3GKR.js +7 -0
- package/dist/validators/index.js +1 -1
- package/dist/verify-PA7R6FBJ.js +8 -0
- package/package.json +2 -2
- package/dist/chunk-3ADL5QDN.js +0 -396
- package/dist/chunk-3ADL5QDN.js.map +0 -1
- package/dist/chunk-D36IFZUZ.js.map +0 -1
- package/dist/chunk-IWFUJ2DS.js.map +0 -1
- package/dist/chunk-M6RHIUSM.js.map +0 -1
- package/dist/chunk-XGS2VFBP.js.map +0 -1
- package/dist/chunk-YELUGXOM.js.map +0 -1
- package/dist/sync-6T5TD4QS.js +0 -7
- package/dist/verify-TX6LFMI6.js +0 -8
- /package/dist/{auto-fix-7WAESKYO.js.map → auto-fix-WGRYEFLJ.js.map} +0 -0
- /package/dist/{chunk-UWJ2ZGEI.js.map → chunk-OH6TK27N.js.map} +0 -0
- /package/dist/{sync-6T5TD4QS.js.map → sync-HHQM3GKR.js.map} +0 -0
- /package/dist/{verify-TX6LFMI6.js.map → verify-PA7R6FBJ.js.map} +0 -0
package/dist/chunk-3ADL5QDN.js
DELETED
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
// src/utils/check-runner.ts
|
|
2
|
-
import { execa } from "execa";
|
|
3
|
-
import chalk from "chalk";
|
|
4
|
-
import { existsSync, readFileSync } from "fs";
|
|
5
|
-
import { join } from "path";
|
|
6
|
-
var QUALITY_CHECKS = [
|
|
7
|
-
{
|
|
8
|
-
name: "typecheck",
|
|
9
|
-
displayName: "Type Check",
|
|
10
|
-
command: "pnpm",
|
|
11
|
-
args: ["typecheck"],
|
|
12
|
-
canAutoFix: false,
|
|
13
|
-
// TypeScript errors need manual/LLM fix
|
|
14
|
-
requiredScript: "typecheck",
|
|
15
|
-
fallbackCommand: ["tsc", "--noEmit"]
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: "lint",
|
|
19
|
-
displayName: "Lint",
|
|
20
|
-
command: "pnpm",
|
|
21
|
-
args: ["lint"],
|
|
22
|
-
fixCommand: "pnpm",
|
|
23
|
-
fixArgs: ["lint", "--fix"],
|
|
24
|
-
canAutoFix: true,
|
|
25
|
-
requiredScript: "lint"
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
name: "format",
|
|
29
|
-
displayName: "Format",
|
|
30
|
-
command: "pnpm",
|
|
31
|
-
args: ["format", "--check"],
|
|
32
|
-
fixCommand: "pnpm",
|
|
33
|
-
fixArgs: ["format"],
|
|
34
|
-
canAutoFix: true,
|
|
35
|
-
requiredScript: "format"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
name: "test",
|
|
39
|
-
displayName: "Tests",
|
|
40
|
-
command: "pnpm",
|
|
41
|
-
args: ["test"],
|
|
42
|
-
canAutoFix: false,
|
|
43
|
-
// Tests need manual/LLM fix
|
|
44
|
-
requiredScript: "test"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: "build",
|
|
48
|
-
displayName: "Build",
|
|
49
|
-
command: "pnpm",
|
|
50
|
-
args: ["build"],
|
|
51
|
-
canAutoFix: false,
|
|
52
|
-
// Build errors need manual/LLM fix
|
|
53
|
-
requiredScript: "build"
|
|
54
|
-
}
|
|
55
|
-
];
|
|
56
|
-
function getAvailableScripts(cwd) {
|
|
57
|
-
const packageJsonPath = join(cwd, "package.json");
|
|
58
|
-
if (!existsSync(packageJsonPath)) {
|
|
59
|
-
return /* @__PURE__ */ new Set();
|
|
60
|
-
}
|
|
61
|
-
try {
|
|
62
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
63
|
-
return new Set(Object.keys(packageJson.scripts || {}));
|
|
64
|
-
} catch {
|
|
65
|
-
return /* @__PURE__ */ new Set();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
async function commandExists(cmd) {
|
|
69
|
-
try {
|
|
70
|
-
await execa("which", [cmd]);
|
|
71
|
-
return true;
|
|
72
|
-
} catch {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
async function getApplicableChecks(cwd) {
|
|
77
|
-
const availableScripts = getAvailableScripts(cwd);
|
|
78
|
-
const applicableChecks = [];
|
|
79
|
-
for (const check of QUALITY_CHECKS) {
|
|
80
|
-
if (!check.requiredScript) {
|
|
81
|
-
applicableChecks.push(check);
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
if (availableScripts.has(check.requiredScript)) {
|
|
85
|
-
applicableChecks.push(check);
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
if (check.fallbackCommand && check.fallbackCommand.length > 0) {
|
|
89
|
-
const fallbackCmd = check.fallbackCommand[0];
|
|
90
|
-
if (await commandExists(fallbackCmd)) {
|
|
91
|
-
applicableChecks.push({
|
|
92
|
-
...check,
|
|
93
|
-
command: fallbackCmd,
|
|
94
|
-
args: check.fallbackCommand.slice(1)
|
|
95
|
-
});
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return applicableChecks;
|
|
101
|
-
}
|
|
102
|
-
async function runCheck(check, cwd) {
|
|
103
|
-
const startTime = Date.now();
|
|
104
|
-
try {
|
|
105
|
-
const result = await execa(check.command, check.args, {
|
|
106
|
-
cwd,
|
|
107
|
-
reject: false,
|
|
108
|
-
all: true
|
|
109
|
-
});
|
|
110
|
-
const duration = Date.now() - startTime;
|
|
111
|
-
if (result.exitCode === 0) {
|
|
112
|
-
return {
|
|
113
|
-
check,
|
|
114
|
-
success: true,
|
|
115
|
-
output: result.all || "",
|
|
116
|
-
duration
|
|
117
|
-
};
|
|
118
|
-
} else {
|
|
119
|
-
return {
|
|
120
|
-
check,
|
|
121
|
-
success: false,
|
|
122
|
-
output: result.all || "",
|
|
123
|
-
error: result.stderr || result.all || "Check failed",
|
|
124
|
-
duration
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
} catch (error) {
|
|
128
|
-
const duration = Date.now() - startTime;
|
|
129
|
-
const execaError = error;
|
|
130
|
-
return {
|
|
131
|
-
check,
|
|
132
|
-
success: false,
|
|
133
|
-
output: execaError.all?.toString() || execaError.message || "",
|
|
134
|
-
error: execaError.message,
|
|
135
|
-
duration
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
async function applyFix(check, cwd) {
|
|
140
|
-
if (!check.canAutoFix || !check.fixCommand) {
|
|
141
|
-
return { success: false, output: "Check does not support auto-fix" };
|
|
142
|
-
}
|
|
143
|
-
try {
|
|
144
|
-
const result = await execa(check.fixCommand, check.fixArgs || [], {
|
|
145
|
-
cwd,
|
|
146
|
-
reject: false,
|
|
147
|
-
all: true
|
|
148
|
-
});
|
|
149
|
-
return {
|
|
150
|
-
success: result.exitCode === 0,
|
|
151
|
-
output: result.all || ""
|
|
152
|
-
};
|
|
153
|
-
} catch (error) {
|
|
154
|
-
const execaError = error;
|
|
155
|
-
return {
|
|
156
|
-
success: false,
|
|
157
|
-
output: execaError.message
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
function formatFixCommand(check) {
|
|
162
|
-
if (!check.fixCommand) return "";
|
|
163
|
-
return `${check.fixCommand} ${(check.fixArgs || []).join(" ")}`;
|
|
164
|
-
}
|
|
165
|
-
async function runAllChecks(cwd, options = {}) {
|
|
166
|
-
const {
|
|
167
|
-
maxRetries = 10,
|
|
168
|
-
autoFix = true,
|
|
169
|
-
dryRun = false,
|
|
170
|
-
onProgress
|
|
171
|
-
} = options;
|
|
172
|
-
const log = (message, type = "info") => {
|
|
173
|
-
if (onProgress) {
|
|
174
|
-
onProgress(message, type);
|
|
175
|
-
} else {
|
|
176
|
-
switch (type) {
|
|
177
|
-
case "success":
|
|
178
|
-
console.log(chalk.green(message));
|
|
179
|
-
break;
|
|
180
|
-
case "error":
|
|
181
|
-
console.log(chalk.red(message));
|
|
182
|
-
break;
|
|
183
|
-
case "warning":
|
|
184
|
-
console.log(chalk.yellow(message));
|
|
185
|
-
break;
|
|
186
|
-
default:
|
|
187
|
-
console.log(message);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
let attempt = 0;
|
|
192
|
-
let fixesApplied = 0;
|
|
193
|
-
const appliedFixes = [];
|
|
194
|
-
const pendingFixes = [];
|
|
195
|
-
const applicableChecks = await getApplicableChecks(cwd);
|
|
196
|
-
const skippedChecks = QUALITY_CHECKS.filter(
|
|
197
|
-
(qc) => !applicableChecks.some((ac) => ac.name === qc.name)
|
|
198
|
-
);
|
|
199
|
-
if (skippedChecks.length > 0) {
|
|
200
|
-
log(`
|
|
201
|
-
\u23ED\uFE0F Skipping checks (scripts not found): ${skippedChecks.map((c) => c.displayName).join(", ")}`, "warning");
|
|
202
|
-
}
|
|
203
|
-
if (applicableChecks.length === 0) {
|
|
204
|
-
log(`
|
|
205
|
-
\u26A0\uFE0F No applicable checks found. Add scripts to package.json: typecheck, lint, format, test, build`, "warning");
|
|
206
|
-
return {
|
|
207
|
-
success: true,
|
|
208
|
-
results: [],
|
|
209
|
-
totalAttempts: 0,
|
|
210
|
-
fixesApplied: 0,
|
|
211
|
-
appliedFixes: []
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
while (attempt < maxRetries) {
|
|
215
|
-
attempt++;
|
|
216
|
-
log(`
|
|
217
|
-
${"\u2501".repeat(50)}`, "info");
|
|
218
|
-
log(`\u{1F504} Validation Cycle ${attempt}/${maxRetries}`, "info");
|
|
219
|
-
log(`${"\u2501".repeat(50)}
|
|
220
|
-
`, "info");
|
|
221
|
-
const results = [];
|
|
222
|
-
let allPassed = true;
|
|
223
|
-
let fixAppliedThisCycle = false;
|
|
224
|
-
for (let i = 0; i < applicableChecks.length; i++) {
|
|
225
|
-
const check = applicableChecks[i];
|
|
226
|
-
const stepNum = i + 1;
|
|
227
|
-
const totalSteps = applicableChecks.length;
|
|
228
|
-
log(`\u{1F4CB} Step ${stepNum}/${totalSteps}: ${check.displayName}...`, "info");
|
|
229
|
-
const result = await runCheck(check, cwd);
|
|
230
|
-
results.push(result);
|
|
231
|
-
if (result.success) {
|
|
232
|
-
log(`\u2705 ${check.displayName} passed (${result.duration}ms)`, "success");
|
|
233
|
-
} else {
|
|
234
|
-
allPassed = false;
|
|
235
|
-
log(`\u274C ${check.displayName} failed`, "error");
|
|
236
|
-
if (autoFix && check.canAutoFix && check.fixCommand) {
|
|
237
|
-
if (dryRun) {
|
|
238
|
-
log(
|
|
239
|
-
`\u{1F527} [DRY-RUN] Would run: ${formatFixCommand(check)}`,
|
|
240
|
-
"warning"
|
|
241
|
-
);
|
|
242
|
-
pendingFixes.push({ check, command: formatFixCommand(check) });
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
245
|
-
log(`\u{1F527} Attempting auto-fix for ${check.displayName}...`, "warning");
|
|
246
|
-
const fixResult = await applyFix(check, cwd);
|
|
247
|
-
if (fixResult.success) {
|
|
248
|
-
log(`\u2728 Auto-fix applied for ${check.displayName}`, "success");
|
|
249
|
-
fixesApplied++;
|
|
250
|
-
appliedFixes.push({
|
|
251
|
-
checkName: check.name,
|
|
252
|
-
displayName: check.displayName,
|
|
253
|
-
command: formatFixCommand(check),
|
|
254
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
255
|
-
});
|
|
256
|
-
fixAppliedThisCycle = true;
|
|
257
|
-
log(
|
|
258
|
-
`
|
|
259
|
-
\u{1F504} Fix applied - restarting all checks to verify...`,
|
|
260
|
-
"warning"
|
|
261
|
-
);
|
|
262
|
-
break;
|
|
263
|
-
} else {
|
|
264
|
-
log(`\u26A0\uFE0F Auto-fix failed for ${check.displayName}`, "error");
|
|
265
|
-
log(` Manual intervention required`, "error");
|
|
266
|
-
if (result.error) {
|
|
267
|
-
const errorPreview = result.error.slice(0, 500);
|
|
268
|
-
log(`
|
|
269
|
-
${chalk.dim(errorPreview)}`, "error");
|
|
270
|
-
if (result.error.length > 500) {
|
|
271
|
-
log(
|
|
272
|
-
chalk.dim(
|
|
273
|
-
`... (${result.error.length - 500} more characters)`
|
|
274
|
-
),
|
|
275
|
-
"error"
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
return {
|
|
280
|
-
success: false,
|
|
281
|
-
results,
|
|
282
|
-
totalAttempts: attempt,
|
|
283
|
-
fixesApplied,
|
|
284
|
-
appliedFixes
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
} else {
|
|
288
|
-
if (check.canAutoFix) {
|
|
289
|
-
log(
|
|
290
|
-
`\u26A0\uFE0F ${check.displayName} can be fixed with: ${formatFixCommand(check)}`,
|
|
291
|
-
"warning"
|
|
292
|
-
);
|
|
293
|
-
} else {
|
|
294
|
-
log(`\u26A0\uFE0F ${check.displayName} requires manual fix`, "error");
|
|
295
|
-
}
|
|
296
|
-
if (result.error) {
|
|
297
|
-
const errorPreview = result.error.slice(0, 500);
|
|
298
|
-
log(`
|
|
299
|
-
${chalk.dim(errorPreview)}`, "error");
|
|
300
|
-
if (result.error.length > 500) {
|
|
301
|
-
log(
|
|
302
|
-
chalk.dim(`... (${result.error.length - 500} more characters)`),
|
|
303
|
-
"error"
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
if (!dryRun) {
|
|
308
|
-
return {
|
|
309
|
-
success: false,
|
|
310
|
-
results,
|
|
311
|
-
totalAttempts: attempt,
|
|
312
|
-
fixesApplied,
|
|
313
|
-
appliedFixes
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
if (dryRun && pendingFixes.length > 0) {
|
|
320
|
-
log(`
|
|
321
|
-
${"\u2501".repeat(50)}`, "info");
|
|
322
|
-
log(`\u{1F4CB} DRY-RUN SUMMARY`, "info");
|
|
323
|
-
log(`${"\u2501".repeat(50)}`, "info");
|
|
324
|
-
log(`
|
|
325
|
-
The following fixes would be applied:`, "warning");
|
|
326
|
-
for (const fix of pendingFixes) {
|
|
327
|
-
log(` \u2022 ${fix.check.displayName}: ${fix.command}`, "info");
|
|
328
|
-
}
|
|
329
|
-
log(`
|
|
330
|
-
Run without --dry-run to apply fixes.`, "info");
|
|
331
|
-
return {
|
|
332
|
-
success: false,
|
|
333
|
-
results,
|
|
334
|
-
totalAttempts: attempt,
|
|
335
|
-
fixesApplied: 0,
|
|
336
|
-
appliedFixes: [],
|
|
337
|
-
pendingFixes
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
if (allPassed) {
|
|
341
|
-
return {
|
|
342
|
-
success: true,
|
|
343
|
-
results,
|
|
344
|
-
totalAttempts: attempt,
|
|
345
|
-
fixesApplied,
|
|
346
|
-
appliedFixes
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
if (!fixAppliedThisCycle) {
|
|
350
|
-
return {
|
|
351
|
-
success: false,
|
|
352
|
-
results,
|
|
353
|
-
totalAttempts: attempt,
|
|
354
|
-
fixesApplied,
|
|
355
|
-
appliedFixes
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
log(`
|
|
360
|
-
\u274C Maximum retries (${maxRetries}) exceeded`, "error");
|
|
361
|
-
return {
|
|
362
|
-
success: false,
|
|
363
|
-
results: [],
|
|
364
|
-
totalAttempts: attempt,
|
|
365
|
-
fixesApplied,
|
|
366
|
-
appliedFixes
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
async function hasUncommittedChanges(cwd) {
|
|
370
|
-
try {
|
|
371
|
-
const result = await execa("git", ["status", "--porcelain"], { cwd });
|
|
372
|
-
return result.stdout.trim().length > 0;
|
|
373
|
-
} catch {
|
|
374
|
-
return false;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
async function stageAllChanges(cwd) {
|
|
378
|
-
try {
|
|
379
|
-
await execa("git", ["add", "-A"], { cwd });
|
|
380
|
-
return true;
|
|
381
|
-
} catch {
|
|
382
|
-
return false;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
export {
|
|
387
|
-
QUALITY_CHECKS,
|
|
388
|
-
getAvailableScripts,
|
|
389
|
-
getApplicableChecks,
|
|
390
|
-
runCheck,
|
|
391
|
-
applyFix,
|
|
392
|
-
runAllChecks,
|
|
393
|
-
hasUncommittedChanges,
|
|
394
|
-
stageAllChanges
|
|
395
|
-
};
|
|
396
|
-
//# sourceMappingURL=chunk-3ADL5QDN.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/check-runner.ts"],"sourcesContent":["/**\n * Check Runner - Orchestrates quality checks with fix-and-revalidate pattern\n *\n * Pattern: Run check → If fails, fix → Re-run ALL checks from start\n * This ensures fixes don't introduce new issues in earlier checks.\n */\n\nimport { execa, type ExecaError } from \"execa\";\nimport chalk from \"chalk\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface CheckDefinition {\n name: string;\n displayName: string;\n command: string;\n args: string[];\n fixCommand?: string;\n fixArgs?: string[];\n canAutoFix: boolean;\n /** The npm script name this check depends on (e.g., \"typecheck\", \"lint\") */\n requiredScript?: string;\n /** Fallback command if the script doesn't exist (e.g., [\"tsc\", \"--noEmit\"]) */\n fallbackCommand?: string[];\n}\n\nexport interface CheckResult {\n check: CheckDefinition;\n success: boolean;\n output: string;\n error?: string;\n duration: number;\n}\n\nexport interface AppliedFix {\n checkName: string;\n displayName: string;\n command: string;\n timestamp: Date;\n}\n\nexport interface RunAllChecksResult {\n success: boolean;\n results: CheckResult[];\n totalAttempts: number;\n fixesApplied: number;\n appliedFixes: AppliedFix[];\n pendingFixes?: Array<{ check: CheckDefinition; command: string }>;\n}\n\nexport type ProgressType = \"info\" | \"success\" | \"error\" | \"warning\";\n\nexport interface CheckRunnerOptions {\n maxRetries?: number;\n autoFix?: boolean;\n dryRun?: boolean;\n onProgress?: (message: string, type: ProgressType) => void;\n}\n\n/**\n * Standard quality checks in recommended order\n * Order: typecheck → lint → format → test → build\n * Type errors cascade, so we fix them first\n */\nexport const QUALITY_CHECKS: CheckDefinition[] = [\n {\n name: \"typecheck\",\n displayName: \"Type Check\",\n command: \"pnpm\",\n args: [\"typecheck\"],\n canAutoFix: false, // TypeScript errors need manual/LLM fix\n requiredScript: \"typecheck\",\n fallbackCommand: [\"tsc\", \"--noEmit\"],\n },\n {\n name: \"lint\",\n displayName: \"Lint\",\n command: \"pnpm\",\n args: [\"lint\"],\n fixCommand: \"pnpm\",\n fixArgs: [\"lint\", \"--fix\"],\n canAutoFix: true,\n requiredScript: \"lint\",\n },\n {\n name: \"format\",\n displayName: \"Format\",\n command: \"pnpm\",\n args: [\"format\", \"--check\"],\n fixCommand: \"pnpm\",\n fixArgs: [\"format\"],\n canAutoFix: true,\n requiredScript: \"format\",\n },\n {\n name: \"test\",\n displayName: \"Tests\",\n command: \"pnpm\",\n args: [\"test\"],\n canAutoFix: false, // Tests need manual/LLM fix\n requiredScript: \"test\",\n },\n {\n name: \"build\",\n displayName: \"Build\",\n command: \"pnpm\",\n args: [\"build\"],\n canAutoFix: false, // Build errors need manual/LLM fix\n requiredScript: \"build\",\n },\n];\n\n/**\n * Get available scripts from the target project's package.json\n */\nexport function getAvailableScripts(cwd: string): Set<string> {\n const packageJsonPath = join(cwd, \"package.json\");\n \n if (!existsSync(packageJsonPath)) {\n return new Set();\n }\n \n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n return new Set(Object.keys(packageJson.scripts || {}));\n } catch {\n return new Set();\n }\n}\n\n/**\n * Check if a command exists in PATH\n */\nasync function commandExists(cmd: string): Promise<boolean> {\n try {\n await execa(\"which\", [cmd]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get applicable checks for the target project\n * Filters out checks for scripts that don't exist, uses fallbacks when available\n */\nexport async function getApplicableChecks(cwd: string): Promise<CheckDefinition[]> {\n const availableScripts = getAvailableScripts(cwd);\n const applicableChecks: CheckDefinition[] = [];\n \n for (const check of QUALITY_CHECKS) {\n // If no required script, always include\n if (!check.requiredScript) {\n applicableChecks.push(check);\n continue;\n }\n \n // If the script exists in package.json, use the pnpm command\n if (availableScripts.has(check.requiredScript)) {\n applicableChecks.push(check);\n continue;\n }\n \n // If there's a fallback command and it exists, use that\n if (check.fallbackCommand && check.fallbackCommand.length > 0) {\n const fallbackCmd = check.fallbackCommand[0];\n if (await commandExists(fallbackCmd)) {\n applicableChecks.push({\n ...check,\n command: fallbackCmd,\n args: check.fallbackCommand.slice(1),\n });\n continue;\n }\n }\n \n // Script doesn't exist and no valid fallback - skip this check\n // (will be logged as skipped in runAllChecks)\n }\n \n return applicableChecks;\n}\n\n/**\n * Run a single check\n */\nexport async function runCheck(\n check: CheckDefinition,\n cwd: string,\n): Promise<CheckResult> {\n const startTime = Date.now();\n\n try {\n const result = await execa(check.command, check.args, {\n cwd,\n reject: false,\n all: true,\n });\n\n const duration = Date.now() - startTime;\n\n if (result.exitCode === 0) {\n return {\n check,\n success: true,\n output: result.all || \"\",\n duration,\n };\n } else {\n return {\n check,\n success: false,\n output: result.all || \"\",\n error: result.stderr || result.all || \"Check failed\",\n duration,\n };\n }\n } catch (error) {\n const duration = Date.now() - startTime;\n const execaError = error as ExecaError;\n\n return {\n check,\n success: false,\n output: execaError.all?.toString() || execaError.message || \"\",\n error: execaError.message,\n duration,\n };\n }\n}\n\n/**\n * Apply fix for a check that supports auto-fix\n */\nexport async function applyFix(\n check: CheckDefinition,\n cwd: string,\n): Promise<{ success: boolean; output: string }> {\n if (!check.canAutoFix || !check.fixCommand) {\n return { success: false, output: \"Check does not support auto-fix\" };\n }\n\n try {\n const result = await execa(check.fixCommand, check.fixArgs || [], {\n cwd,\n reject: false,\n all: true,\n });\n\n return {\n success: result.exitCode === 0,\n output: result.all || \"\",\n };\n } catch (error) {\n const execaError = error as ExecaError;\n return {\n success: false,\n output: execaError.message,\n };\n }\n}\n\n/**\n * Format a fix command for display\n */\nfunction formatFixCommand(check: CheckDefinition): string {\n if (!check.fixCommand) return \"\";\n return `${check.fixCommand} ${(check.fixArgs || []).join(\" \")}`;\n}\n\n/**\n * Run all quality checks with fix-and-revalidate pattern\n *\n * When a check fails and can be auto-fixed:\n * 1. Apply the fix\n * 2. Re-run ALL checks from the beginning\n * 3. Repeat until all pass or max retries reached\n *\n * @param cwd - Working directory\n * @param options - Configuration options\n */\nexport async function runAllChecks(\n cwd: string,\n options: CheckRunnerOptions = {},\n): Promise<RunAllChecksResult> {\n const {\n maxRetries = 10,\n autoFix = true,\n dryRun = false,\n onProgress,\n } = options;\n\n const log = (message: string, type: ProgressType = \"info\") => {\n if (onProgress) {\n onProgress(message, type);\n } else {\n // Default console output with colors\n switch (type) {\n case \"success\":\n console.log(chalk.green(message));\n break;\n case \"error\":\n console.log(chalk.red(message));\n break;\n case \"warning\":\n console.log(chalk.yellow(message));\n break;\n default:\n console.log(message);\n }\n }\n };\n\n let attempt = 0;\n let fixesApplied = 0;\n const appliedFixes: AppliedFix[] = [];\n const pendingFixes: Array<{ check: CheckDefinition; command: string }> = [];\n\n // Get applicable checks for this project (filters out missing scripts)\n const applicableChecks = await getApplicableChecks(cwd);\n \n // Log skipped checks\n const skippedChecks = QUALITY_CHECKS.filter(\n qc => !applicableChecks.some(ac => ac.name === qc.name)\n );\n if (skippedChecks.length > 0) {\n log(`\\n⏭️ Skipping checks (scripts not found): ${skippedChecks.map(c => c.displayName).join(\", \")}`, \"warning\");\n }\n \n if (applicableChecks.length === 0) {\n log(`\\n⚠️ No applicable checks found. Add scripts to package.json: typecheck, lint, format, test, build`, \"warning\");\n return {\n success: true,\n results: [],\n totalAttempts: 0,\n fixesApplied: 0,\n appliedFixes: [],\n };\n }\n\n while (attempt < maxRetries) {\n attempt++;\n\n log(`\\n${\"━\".repeat(50)}`, \"info\");\n log(`🔄 Validation Cycle ${attempt}/${maxRetries}`, \"info\");\n log(`${\"━\".repeat(50)}\\n`, \"info\");\n\n const results: CheckResult[] = [];\n let allPassed = true;\n let fixAppliedThisCycle = false;\n\n // Run each check in order\n for (let i = 0; i < applicableChecks.length; i++) {\n const check = applicableChecks[i];\n const stepNum = i + 1;\n const totalSteps = applicableChecks.length;\n\n log(`📋 Step ${stepNum}/${totalSteps}: ${check.displayName}...`, \"info\");\n\n const result = await runCheck(check, cwd);\n results.push(result);\n\n if (result.success) {\n log(`✅ ${check.displayName} passed (${result.duration}ms)`, \"success\");\n } else {\n allPassed = false;\n log(`❌ ${check.displayName} failed`, \"error\");\n\n // Try to auto-fix if possible\n if (autoFix && check.canAutoFix && check.fixCommand) {\n if (dryRun) {\n // In dry-run mode, just record what would be fixed\n log(\n `🔧 [DRY-RUN] Would run: ${formatFixCommand(check)}`,\n \"warning\",\n );\n pendingFixes.push({ check, command: formatFixCommand(check) });\n\n // Continue to next check to show all issues\n continue;\n }\n\n log(`🔧 Attempting auto-fix for ${check.displayName}...`, \"warning\");\n\n const fixResult = await applyFix(check, cwd);\n\n if (fixResult.success) {\n log(`✨ Auto-fix applied for ${check.displayName}`, \"success\");\n fixesApplied++;\n appliedFixes.push({\n checkName: check.name,\n displayName: check.displayName,\n command: formatFixCommand(check),\n timestamp: new Date(),\n });\n fixAppliedThisCycle = true;\n\n // IMPORTANT: Re-run ALL checks from the beginning\n log(\n `\\n🔄 Fix applied - restarting all checks to verify...`,\n \"warning\",\n );\n break; // Exit the for loop to restart from the beginning\n } else {\n log(`⚠️ Auto-fix failed for ${check.displayName}`, \"error\");\n log(` Manual intervention required`, \"error\");\n\n // Show error details\n if (result.error) {\n const errorPreview = result.error.slice(0, 500);\n log(`\\n${chalk.dim(errorPreview)}`, \"error\");\n if (result.error.length > 500) {\n log(\n chalk.dim(\n `... (${result.error.length - 500} more characters)`,\n ),\n \"error\",\n );\n }\n }\n\n return {\n success: false,\n results,\n totalAttempts: attempt,\n fixesApplied,\n appliedFixes,\n };\n }\n } else {\n // Cannot auto-fix this check\n if (check.canAutoFix) {\n log(\n `⚠️ ${check.displayName} can be fixed with: ${formatFixCommand(check)}`,\n \"warning\",\n );\n } else {\n log(`⚠️ ${check.displayName} requires manual fix`, \"error\");\n }\n\n // Show error details\n if (result.error) {\n const errorPreview = result.error.slice(0, 500);\n log(`\\n${chalk.dim(errorPreview)}`, \"error\");\n if (result.error.length > 500) {\n log(\n chalk.dim(`... (${result.error.length - 500} more characters)`),\n \"error\",\n );\n }\n }\n\n if (!dryRun) {\n return {\n success: false,\n results,\n totalAttempts: attempt,\n fixesApplied,\n appliedFixes,\n };\n }\n }\n }\n }\n\n // Handle dry-run completion\n if (dryRun && pendingFixes.length > 0) {\n log(`\\n${\"━\".repeat(50)}`, \"info\");\n log(`📋 DRY-RUN SUMMARY`, \"info\");\n log(`${\"━\".repeat(50)}`, \"info\");\n log(`\\nThe following fixes would be applied:`, \"warning\");\n for (const fix of pendingFixes) {\n log(` • ${fix.check.displayName}: ${fix.command}`, \"info\");\n }\n log(`\\nRun without --dry-run to apply fixes.`, \"info\");\n\n return {\n success: false,\n results,\n totalAttempts: attempt,\n fixesApplied: 0,\n appliedFixes: [],\n pendingFixes,\n };\n }\n\n // If all checks passed, we're done!\n if (allPassed) {\n return {\n success: true,\n results,\n totalAttempts: attempt,\n fixesApplied,\n appliedFixes,\n };\n }\n\n // If no fix was applied this cycle but we still failed, we're stuck\n if (!fixAppliedThisCycle) {\n return {\n success: false,\n results,\n totalAttempts: attempt,\n fixesApplied,\n appliedFixes,\n };\n }\n\n // Otherwise, continue to next cycle (fix was applied, need to re-verify)\n }\n\n // Max retries exceeded\n log(`\\n❌ Maximum retries (${maxRetries}) exceeded`, \"error\");\n\n return {\n success: false,\n results: [],\n totalAttempts: attempt,\n fixesApplied,\n appliedFixes,\n };\n}\n\n/**\n * Check if there are uncommitted changes in git\n */\nexport async function hasUncommittedChanges(cwd: string): Promise<boolean> {\n try {\n const result = await execa(\"git\", [\"status\", \"--porcelain\"], { cwd });\n return result.stdout.trim().length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Stage all changes in git\n */\nexport async function stageAllChanges(cwd: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"add\", \"-A\"], { cwd });\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/verify.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport {\n runAllChecks,\n hasUncommittedChanges,\n stageAllChanges,\n type RunAllChecksResult,\n} from \"../../utils/check-runner.js\";\nimport { execa } from \"execa\";\nimport {\n PatternStore,\n TelemetryCollector,\n ContributorManager,\n type FixPattern,\n} from \"@hawkinside_out/workflow-improvement-tracker\";\n\ninterface VerifyOptions {\n fix?: boolean;\n maxRetries?: string;\n commit?: boolean;\n dryRun?: boolean;\n learn?: boolean;\n}\n\n/**\n * Verify command - Run all quality checks with fix-and-revalidate pattern\n *\n * Pattern: Run check → If fails, fix → Re-run ALL checks from start\n * This ensures fixes don't introduce new issues in earlier checks.\n */\nexport async function verifyCommand(options: VerifyOptions) {\n const cwd = process.cwd();\n const maxRetries = options.maxRetries ? parseInt(options.maxRetries, 10) : 10;\n const autoFix = options.fix ?? false;\n const shouldCommit = options.commit ?? false;\n const dryRun = options.dryRun ?? false;\n const learnFromFixes = options.learn ?? false;\n\n console.log(chalk.bold.cyan(\"\\n🔍 Workflow Agent Quality Verification\\n\"));\n\n if (dryRun) {\n console.log(chalk.yellow(\"📋 DRY-RUN MODE: No changes will be applied\\n\"));\n }\n\n console.log(chalk.dim(` Auto-fix: ${autoFix ? \"enabled\" : \"disabled\"}`));\n console.log(chalk.dim(` Max retries: ${maxRetries}`));\n console.log(chalk.dim(` Commit on success: ${shouldCommit ? \"yes\" : \"no\"}`));\n console.log(chalk.dim(` Dry-run: ${dryRun ? \"yes\" : \"no\"}`));\n console.log(\n chalk.dim(` Learn from fixes: ${learnFromFixes ? \"yes\" : \"no\"}`),\n );\n\n const startTime = Date.now();\n\n const result = await runAllChecks(cwd, {\n maxRetries,\n autoFix,\n dryRun,\n });\n\n const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);\n\n console.log(`\\n${\"━\".repeat(50)}`);\n\n if (result.success) {\n console.log(chalk.bold.green(\"\\n✅ ALL QUALITY CHECKS PASSED!\\n\"));\n console.log(chalk.dim(` Total time: ${totalTime}s`));\n console.log(chalk.dim(` Validation cycles: ${result.totalAttempts}`));\n console.log(chalk.dim(` Fixes applied: ${result.fixesApplied}`));\n\n // Auto-record successful fix patterns if learning is enabled\n if (learnFromFixes && result.fixesApplied > 0 && !dryRun) {\n await recordSuccessfulFixes(cwd, result);\n }\n\n // Handle commit if requested\n if (shouldCommit) {\n const hasChanges = await hasUncommittedChanges(cwd);\n\n if (hasChanges) {\n console.log(chalk.cyan(\"\\n📦 Staging and committing changes...\\n\"));\n\n const staged = await stageAllChanges(cwd);\n if (!staged) {\n console.log(chalk.red(\"❌ Failed to stage changes\"));\n process.exit(1);\n }\n\n try {\n await execa(\n \"git\",\n [\"commit\", \"-m\", \"chore: auto-fix quality issues\"],\n { cwd },\n );\n console.log(chalk.green(\"✅ Changes committed successfully\"));\n } catch (error) {\n console.log(chalk.red(\"❌ Failed to commit changes\"));\n console.log(chalk.dim((error as Error).message));\n process.exit(1);\n }\n } else {\n console.log(chalk.dim(\"\\n No changes to commit.\"));\n }\n }\n\n console.log(chalk.cyan(\"\\n💡 Next steps:\\n\"));\n console.log(chalk.dim(\" 1. git add .\"));\n console.log(\n chalk.dim(' 2. git commit -m \"<type>(<scope>): <description>\"'),\n );\n console.log(chalk.dim(\" 3. git push origin <branch-name>\"));\n console.log(\"\");\n\n process.exit(0);\n } else {\n console.log(chalk.bold.red(\"\\n❌ QUALITY CHECKS FAILED\\n\"));\n console.log(chalk.dim(` Total time: ${totalTime}s`));\n console.log(chalk.dim(` Validation cycles: ${result.totalAttempts}`));\n console.log(chalk.dim(` Fixes applied: ${result.fixesApplied}`));\n\n if (result.pendingFixes && result.pendingFixes.length > 0) {\n console.log(chalk.yellow(\"\\n📋 Pending fixes (dry-run):\"));\n for (const fix of result.pendingFixes) {\n console.log(chalk.dim(` • ${fix.check.displayName}: ${fix.command}`));\n }\n }\n\n console.log(\n chalk.yellow(\"\\n⚠️ Please fix the errors above and run again.\"),\n );\n console.log(\n chalk.dim(\" Run with --fix to auto-fix lint and format issues.\"),\n );\n console.log(\"\");\n\n process.exit(1);\n }\n}\n\n// ============================================\n// Auto-Record Learning Pattern\n// ============================================\n\n/**\n * Record successful fix patterns for learning\n * Called after verify succeeds with auto-fixes applied\n */\nasync function recordSuccessfulFixes(\n cwd: string,\n result: RunAllChecksResult,\n): Promise<void> {\n try {\n // Check if telemetry is enabled\n const contributorManager = new ContributorManager(cwd);\n const telemetryEnabled = await contributorManager.isTelemetryEnabled();\n\n if (!telemetryEnabled) {\n // Silently skip if telemetry is disabled\n return;\n }\n\n const store = new PatternStore(cwd);\n const telemetry = new TelemetryCollector(cwd);\n\n // Get package.json to determine framework\n let framework = \"unknown\";\n let frameworkVersion = \"0.0.0\";\n\n try {\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n const packageJsonPath = path.join(cwd, \"package.json\");\n const packageJson = JSON.parse(\n await fs.promises.readFile(packageJsonPath, \"utf-8\"),\n );\n\n // Detect framework from dependencies\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n if (deps[\"next\"]) {\n framework = \"next\";\n frameworkVersion = deps[\"next\"].replace(/[\\^~]/, \"\");\n } else if (deps[\"react\"]) {\n framework = \"react\";\n frameworkVersion = deps[\"react\"].replace(/[\\^~]/, \"\");\n } else if (deps[\"vue\"]) {\n framework = \"vue\";\n frameworkVersion = deps[\"vue\"].replace(/[\\^~]/, \"\");\n } else if (deps[\"express\"]) {\n framework = \"express\";\n frameworkVersion = deps[\"express\"].replace(/[\\^~]/, \"\");\n }\n } catch {\n // Ignore package.json read errors\n }\n\n // Record telemetry for each fix applied\n if (result.appliedFixes && result.appliedFixes.length > 0) {\n console.log(\n chalk.cyan(\"\\n📚 Recording successful fixes for learning...\\n\"),\n );\n\n for (const fix of result.appliedFixes) {\n // Create or find existing pattern for this fix type\n const patternName = `Auto-fix: ${fix.displayName}`;\n const patternId = crypto.randomUUID();\n\n // Check if we already have a pattern for this fix type\n const existingPatterns = await store.listFixPatterns({\n tags: [{ category: \"tool\", name: fix.checkName }],\n });\n\n if (\n existingPatterns.success &&\n existingPatterns.data &&\n existingPatterns.data.length > 0\n ) {\n // Update metrics on existing pattern\n const existingPattern = existingPatterns.data[0];\n await store.updateFixMetrics(existingPattern.id, true);\n await telemetry.recordSuccess(\n existingPattern.id,\n \"fix\",\n framework,\n frameworkVersion,\n );\n console.log(chalk.dim(` ✓ Updated: ${existingPattern.name}`));\n } else {\n // Create new pattern\n const now = new Date().toISOString();\n const newPattern: FixPattern = {\n id: patternId,\n name: patternName,\n description: `Auto-fix pattern for ${fix.displayName} using command: ${fix.command}`,\n category: \"config\",\n tags: [\n { category: \"tool\", name: fix.checkName },\n { category: \"framework\", name: framework },\n ],\n trigger: {\n errorPattern: fix.checkName,\n errorMessage: `${fix.checkName} check failed`,\n filePattern: \"**/*\",\n },\n solution: {\n type: \"command\",\n steps: [\n {\n order: 1,\n action: \"run\",\n target: fix.command,\n description: `Run ${fix.command}`,\n },\n ],\n },\n compatibility: {\n framework,\n frameworkVersion: `>=${frameworkVersion}`,\n runtime: \"node\",\n runtimeVersion: \">=18.0.0\",\n dependencies: [],\n },\n metrics: {\n applications: 1,\n successes: 1,\n failures: 0,\n successRate: 100,\n lastUsed: now,\n lastSuccessful: now,\n },\n source: \"verify-fix\",\n isPrivate: true,\n createdAt: now,\n updatedAt: now,\n };\n\n const saveResult = await store.saveFixPattern(newPattern);\n if (saveResult.success) {\n await telemetry.recordSuccess(\n patternId,\n \"fix\",\n framework,\n frameworkVersion,\n );\n console.log(chalk.dim(` ✓ Recorded: ${patternName}`));\n console.log(chalk.dim(` Path: .workflow/patterns/fixes/${newPattern.id}.json`));\n }\n }\n }\n\n console.log(\n chalk.dim(`\\n Use 'workflow learn:list' to see recorded patterns.`),\n );\n }\n } catch (error) {\n // Don't fail the verify command if learning fails\n console.log(\n chalk.dim(\n `\\n Note: Could not record learning patterns: ${(error as Error).message}`,\n ),\n );\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/scripts/copilot-instructions-generator.ts","../src/scripts/workflow-scripts.ts","../src/scripts/template-installer.ts","../src/templates/metadata.ts"],"sourcesContent":["/**\n * Copilot Instructions Generator\n *\n * Generates .github/copilot-instructions.md from the project's guidelines directory.\n * This file serves as the Single Source of Truth for AI agents (GitHub Copilot, Claude, etc.)\n * when working on the codebase.\n *\n * Features:\n * - Reads all markdown files from guidelines/\n * - Extracts key rules and summaries from each guideline\n * - Loads project config from workflow.config.json\n * - Preserves custom user content between markers\n * - Provides links to full guideline documents\n */\n\nimport { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from \"fs\";\nimport { join, basename } from \"path\";\n\n// Markers for custom user content that should be preserved on regeneration\nconst CUSTOM_START_MARKER = \"<!-- CUSTOM START -->\";\nconst CUSTOM_END_MARKER = \"<!-- CUSTOM END -->\";\nconst GENERATED_MARKER = \"<!-- AUTO-GENERATED BY WORKFLOW-AGENT - DO NOT EDIT ABOVE THIS LINE -->\";\n\ninterface WorkflowConfig {\n projectName?: string;\n scopes?: Array<{ name: string; description: string; emoji?: string }>;\n enforcement?: string;\n language?: string;\n}\n\ninterface GuidelineSummary {\n filename: string;\n title: string;\n description: string;\n keyRules: string[];\n}\n\n/**\n * Extract title from markdown content (first H1)\n */\nfunction extractTitle(content: string): string {\n const match = content.match(/^#\\s+(.+)$/m);\n return match ? match[1].trim() : \"Untitled\";\n}\n\n/**\n * Extract description from markdown content (first paragraph after title)\n */\nfunction extractDescription(content: string): string {\n // Look for content after the first heading, before the next heading or section\n const lines = content.split(\"\\n\");\n let foundTitle = false;\n let description = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"# \")) {\n foundTitle = true;\n continue;\n }\n if (foundTitle) {\n // Skip empty lines and blockquotes at start\n if (line.trim() === \"\" || line.startsWith(\">\")) {\n if (description) break; // End if we already have content\n continue;\n }\n // Stop at next heading or horizontal rule\n if (line.startsWith(\"#\") || line.startsWith(\"---\") || line.startsWith(\"##\")) {\n break;\n }\n description += line.trim() + \" \";\n // Take only first meaningful paragraph\n if (description.length > 150) break;\n }\n }\n\n return description.trim().slice(0, 200) + (description.length > 200 ? \"...\" : \"\");\n}\n\n/**\n * Rewrite markdown links to include ../guidelines/ prefix\n * Transforms links like [FILE.md](FILE.md) to [FILE.md](../guidelines/FILE.md)\n */\nfunction rewriteGuidelineLinks(text: string): string {\n // Match markdown links: [text](file.md) where file.md is a .md file without path\n return text.replace(\n /\\[([^\\]]+)\\]\\(([A-Z_]+\\.md)\\)/g,\n (match, linkText, filename) => {\n // Only rewrite if it's just the filename (no path)\n if (!filename.includes(\"/\")) {\n return `[${linkText}](../guidelines/${filename})`;\n }\n return match;\n }\n );\n}\n\n/**\n * Extract key rules from markdown content\n * Looks for lists, bold text, and important patterns\n */\nfunction extractKeyRules(content: string, maxRules: number = 5): string[] {\n const rules: string[] = [];\n\n // Pattern 1: Look for \"MUST\", \"NEVER\", \"ALWAYS\", \"REQUIRED\" in bold or emphasized\n const emphasisPatterns = [\n /\\*\\*(?:MUST|NEVER|ALWAYS|REQUIRED)[^*]+\\*\\*/gi,\n /(?:^|\\n)\\s*[-*]\\s+\\*\\*[^*]+\\*\\*/gm,\n ];\n\n for (const pattern of emphasisPatterns) {\n const matches = content.match(pattern);\n if (matches) {\n for (const match of matches.slice(0, 2)) {\n const cleaned = match.replace(/\\*\\*/g, \"\").replace(/^[-*]\\s*/, \"\").trim();\n if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {\n rules.push(cleaned);\n }\n }\n }\n }\n\n // Pattern 2: Look for numbered or bulleted rules under headings containing \"Rules\", \"Requirements\", \"Guidelines\"\n const rulesSectionMatch = content.match(/##\\s+(?:.*(?:Rules?|Requirements?|Guidelines?|Standards?)[^\\n]*)\\n([\\s\\S]*?)(?=\\n##|\\n#|$)/i);\n if (rulesSectionMatch) {\n const section = rulesSectionMatch[1];\n const listItems = section.match(/^\\s*[-*\\d.]+\\s+(.+)$/gm);\n if (listItems) {\n for (const item of listItems.slice(0, 3)) {\n const cleaned = item.replace(/^[-*\\d.]+\\s*/, \"\").trim();\n if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {\n rules.push(cleaned);\n }\n }\n }\n }\n\n // Pattern 3: Look for key points under \"Important\", \"Critical\", \"Key\"\n const importantMatch = content.match(/(?:Important|Critical|Key|Essential)[:\\s]+([^\\n]+)/gi);\n if (importantMatch) {\n for (const match of importantMatch.slice(0, 2)) {\n const cleaned = match.replace(/^(?:Important|Critical|Key|Essential)[:\\s]+/i, \"\").trim();\n if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {\n rules.push(cleaned);\n }\n }\n }\n\n // Fallback: Get first few list items if we don't have enough rules\n if (rules.length < 2) {\n const listItems = content.match(/^\\s*[-*]\\s+(.+)$/gm);\n if (listItems) {\n for (const item of listItems.slice(0, 3)) {\n const cleaned = item.replace(/^[-*]\\s*/, \"\").trim();\n if (cleaned.length > 15 && cleaned.length < 150 && !rules.includes(cleaned)) {\n rules.push(cleaned);\n }\n }\n }\n }\n\n return rules.slice(0, maxRules);\n}\n\n/**\n * Parse a guideline markdown file and extract summary\n */\nfunction parseGuideline(filePath: string): GuidelineSummary | null {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const filename = basename(filePath);\n\n // Skip template example and non-guideline files\n if (filename.startsWith(\"_\") || filename === \"Guidelines.md\") {\n return null;\n }\n\n return {\n filename,\n title: extractTitle(content),\n description: extractDescription(content),\n keyRules: extractKeyRules(content),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Load workflow config from project root\n */\nfunction loadWorkflowConfig(projectRoot: string): WorkflowConfig | null {\n const configPath = join(projectRoot, \"workflow.config.json\");\n if (!existsSync(configPath)) {\n return null;\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\");\n return JSON.parse(content) as WorkflowConfig;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract preserved custom content from existing file\n */\nfunction extractCustomContent(existingContent: string): string | null {\n const startIndex = existingContent.indexOf(CUSTOM_START_MARKER);\n const endIndex = existingContent.indexOf(CUSTOM_END_MARKER);\n\n if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {\n return existingContent.slice(\n startIndex + CUSTOM_START_MARKER.length,\n endIndex\n ).trim();\n }\n\n return null;\n}\n\n/**\n * Generate the copilot-instructions.md content\n */\nfunction generateInstructionsContent(\n config: WorkflowConfig | null,\n guidelines: GuidelineSummary[],\n customContent: string | null\n): string {\n const projectName = config?.projectName || \"this project\";\n const scopes = config?.scopes || [];\n\n let content = `# Copilot Instructions for ${projectName}\n\n> **This file is the Single Source of Truth for AI agents working on this codebase.**\n> It is auto-generated from the \\`guidelines/\\` directory by workflow-agent-cli.\n> Last generated: ${new Date().toISOString().split(\"T\")[0]}\n\n${GENERATED_MARKER}\n\n## Project Overview\n\n`;\n\n if (config) {\n content += `- **Project Name**: ${projectName}\\n`;\n content += `- **Enforcement Level**: ${config.enforcement || \"strict\"}\\n`;\n if (scopes.length > 0) {\n content += `- **Available Scopes**: ${scopes.map(s => `\\`${s.name}\\``).join(\", \")}\\n`;\n }\n content += \"\\n\";\n }\n\n // Add scope reference if available\n if (scopes.length > 0) {\n content += `### Valid Scopes for Commits and Branches\n\n| Scope | Description |\n|-------|-------------|\n`;\n for (const scope of scopes.slice(0, 15)) {\n content += `| \\`${scope.name}\\` | ${scope.description} |\\n`;\n }\n if (scopes.length > 15) {\n content += `| ... | See workflow.config.json for all ${scopes.length} scopes |\\n`;\n }\n content += \"\\n\";\n }\n\n // Add guidelines summaries\n if (guidelines.length > 0) {\n content += `## Guidelines Summary\n\nThe following guidelines govern development on this project. **Read the linked documents for full details.**\n\n`;\n\n // Group by importance (mandatory templates first)\n const mandatoryFiles = [\n \"AGENT_EDITING_INSTRUCTIONS.md\",\n \"BRANCHING_STRATEGY.md\",\n \"TESTING_STRATEGY.md\",\n \"SINGLE_SOURCE_OF_TRUTH.md\",\n \"PATTERN_ANALYSIS_WORKFLOW.md\",\n \"SELF_IMPROVEMENT_MANDATE.md\",\n ];\n\n const sortedGuidelines = [...guidelines].sort((a, b) => {\n const aIndex = mandatoryFiles.indexOf(a.filename);\n const bIndex = mandatoryFiles.indexOf(b.filename);\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return a.title.localeCompare(b.title);\n });\n\n for (const guideline of sortedGuidelines) {\n content += `### ${guideline.title}\n\n📄 [See full details](../guidelines/${guideline.filename})\n\n${guideline.description}\n\n`;\n if (guideline.keyRules.length > 0) {\n content += `**Key Rules:**\n`;\n for (const rule of guideline.keyRules) {\n // Rewrite any markdown links to include ../guidelines/ prefix\n content += `- ${rewriteGuidelineLinks(rule)}\\n`;\n }\n content += \"\\n\";\n }\n }\n }\n\n // Add quick reference section\n content += `## Quick Reference\n\n### Branch Naming Convention\n\\`\\`\\`\n<type>/<scope>/<short-description>\n\\`\\`\\`\n\n**Types**: \\`feature\\`, \\`fix\\`, \\`chore\\`, \\`docs\\`, \\`refactor\\`, \\`test\\`, \\`perf\\`\n\n### Commit Message Format\n\\`\\`\\`\n<type>(<scope>): <description>\n\n[optional body]\n\n[optional footer]\n\\`\\`\\`\n\n### Before Making Changes\n1. Read the relevant guideline document in \\`guidelines/\\`\n2. Check for existing patterns in \\`workflow:solution:search\\`\n3. Create an implementation plan for multi-file changes\n4. Ensure tests are added for new functionality\n\n### Before Committing\n1. Run \\`pnpm run workflow:verify\\` to validate all changes\n2. Ensure branch name follows convention\n3. Ensure commit message follows conventional commits format\n\n`;\n\n // Add custom content section\n content += `## Project-Specific Instructions\n\n${CUSTOM_START_MARKER}\n${customContent || `\n<!-- \nAdd your project-specific instructions here.\nThis section will be preserved when the file is regenerated.\n\nExamples:\n- Specific coding patterns unique to this project\n- Custom review requirements\n- Domain-specific terminology\n- Team-specific workflows\n-->\n`}\n${CUSTOM_END_MARKER}\n\n---\n\n*This file was generated by [workflow-agent-cli](https://www.npmjs.com/package/workflow-agent-cli). Run \\`pnpm run workflow:generate-instructions\\` to regenerate.*\n`;\n\n return content;\n}\n\n/**\n * Result of generating copilot instructions\n */\nexport interface GenerateResult {\n success: boolean;\n filePath: string | null;\n guidelinesCount: number;\n isNew: boolean;\n preservedCustomContent: boolean;\n error?: string;\n}\n\n/**\n * Generate .github/copilot-instructions.md from guidelines directory\n *\n * @param projectRoot - Root directory of the project\n * @param options - Generation options\n * @returns Result of the generation\n */\nexport function generateCopilotInstructions(\n projectRoot: string,\n options: { force?: boolean; silent?: boolean } = {}\n): GenerateResult {\n const { force: _force = false, silent = false } = options;\n\n const guidelinesDir = join(projectRoot, \"guidelines\");\n const githubDir = join(projectRoot, \".github\");\n const outputPath = join(githubDir, \"copilot-instructions.md\");\n\n // Check if guidelines directory exists\n if (!existsSync(guidelinesDir)) {\n if (!silent) {\n // Guidelines don't exist yet - skip silently during postinstall\n }\n return {\n success: false,\n filePath: null,\n guidelinesCount: 0,\n isNew: false,\n preservedCustomContent: false,\n error: \"No guidelines directory found. Run 'workflow init' first.\",\n };\n }\n\n // Read all markdown files from guidelines\n const files = readdirSync(guidelinesDir).filter(f => f.endsWith(\".md\"));\n if (files.length === 0) {\n return {\n success: false,\n filePath: null,\n guidelinesCount: 0,\n isNew: false,\n preservedCustomContent: false,\n error: \"No markdown files found in guidelines directory.\",\n };\n }\n\n // Parse each guideline\n const guidelines: GuidelineSummary[] = [];\n for (const file of files) {\n const summary = parseGuideline(join(guidelinesDir, file));\n if (summary) {\n guidelines.push(summary);\n }\n }\n\n // Load workflow config\n const config = loadWorkflowConfig(projectRoot);\n\n // Check for existing file and extract custom content\n let customContent: string | null = null;\n let isNew = true;\n\n if (existsSync(outputPath)) {\n isNew = false;\n const existingContent = readFileSync(outputPath, \"utf-8\");\n customContent = extractCustomContent(existingContent);\n }\n\n // Generate the content\n const content = generateInstructionsContent(config, guidelines, customContent);\n\n // Ensure .github directory exists\n if (!existsSync(githubDir)) {\n mkdirSync(githubDir, { recursive: true });\n }\n\n // Write the file\n writeFileSync(outputPath, content, \"utf-8\");\n\n return {\n success: true,\n filePath: outputPath,\n guidelinesCount: guidelines.length,\n isNew,\n preservedCustomContent: customContent !== null,\n };\n}\n\n/**\n * Check if copilot instructions need regeneration\n * (e.g., guidelines have been modified since last generation)\n */\nexport function needsRegeneration(projectRoot: string): boolean {\n const guidelinesDir = join(projectRoot, \"guidelines\");\n const outputPath = join(projectRoot, \".github\", \"copilot-instructions.md\");\n\n if (!existsSync(outputPath)) {\n return existsSync(guidelinesDir);\n }\n\n // For now, always regenerate to ensure latest content\n // Future: could compare file modification times\n return true;\n}\n","/**\n * Shared workflow scripts definition\n * Used by postinstall.ts and setup.ts to ensure consistency\n *\n * Version 2.22.0: Simplified to single \"workflow\" script\n * Users run commands directly: npm run workflow -- init\n */\n\n/**\n * Current version of the workflow scripts schema\n * Used for tracking which version installed the scripts\n */\nexport const WORKFLOW_SCRIPTS_VERSION = \"2.22.0\";\n\n/**\n * The valid top-level commands for the workflow CLI\n * Run with: npm run workflow -- <command> [subcommand] [options]\n */\nexport const VALID_COMMANDS = [\n \"version\",\n \"init\",\n \"validate\",\n \"config\",\n \"suggest\",\n \"setup\",\n \"doctor\",\n \"scope\",\n \"verify\",\n \"pre-commit\",\n \"learn\",\n \"solution\",\n \"sync\",\n \"docs\",\n] as const;\n\nexport type ValidCommand = (typeof VALID_COMMANDS)[number];\n\n/**\n * Validates that a script name is the expected \"workflow\" script\n * @param scriptName - The script name to validate\n * @returns true if valid, false otherwise\n */\nexport function validateScriptName(scriptName: string): boolean {\n return scriptName === \"workflow\";\n}\n\n/**\n * Finds old workflow scripts that should be removed\n * @param scripts - Object with script names as keys\n * @returns Array of old workflow script names that should be removed\n */\nexport function validateAllScripts(scripts: Record<string, string>): string[] {\n return Object.keys(scripts).filter(\n (name) =>\n (name.startsWith(\"workflow:\") || name.startsWith(\"workflow-\")) &&\n name !== \"workflow\"\n );\n}\n\n/**\n * Deprecated scripts that should be removed from package.json\n * These are replaced by the single \"workflow\" script\n */\nexport const DEPRECATED_SCRIPTS = [\n // Old colon-style scope commands\n \"workflow:scope:create\",\n \"workflow:scope:migrate\",\n\n // Old colon-style learn commands\n \"workflow:learn\",\n \"workflow:learn:record\",\n \"workflow:learn:list\",\n \"workflow:learn:apply\",\n \"workflow:learn:publish\",\n \"workflow:learn:sync\",\n \"workflow:learn:sync:push\",\n \"workflow:learn:sync:pull\",\n \"workflow:learn:config\",\n \"workflow:learn:deprecate\",\n \"workflow:learn:stats\",\n\n // Old colon-style solution commands\n \"workflow:solution\",\n \"workflow:solution:capture\",\n \"workflow:solution:search\",\n \"workflow:solution:list\",\n \"workflow:solution:apply\",\n \"workflow:solution:deprecate\",\n \"workflow:solution:stats\",\n\n // Old advisory commands\n \"workflow:advisory\",\n \"workflow:advisory:quick\",\n \"workflow:advisory:standard\",\n \"workflow:advisory:comprehensive\",\n \"workflow:advisory:executive\",\n \"workflow:advisory:ci\",\n\n // Old standalone commands\n \"workflow:generate-instructions\",\n \"workflow:update-templates\",\n \"workflow:update-templates:force\",\n\n // Old colon-style docs commands\n \"workflow:docs:validate\",\n \"workflow:docs:validate:fix\",\n\n // Old verify shortcuts\n \"verify\",\n \"verify:fix\",\n \"pre-commit\",\n\n // Old colon-style verify\n \"workflow:verify:fix\",\n\n // Old hooks commands\n \"workflow:hooks\",\n \"workflow:hooks-install\",\n \"workflow:hooks-uninstall\",\n \"workflow:hooks-test\",\n \"workflow:hooks:install\",\n \"workflow:hooks:uninstall\",\n \"workflow:hooks:status\",\n\n // Old auto-setup\n \"workflow:auto-setup\",\n\n // v2.21.x dash-style scripts (deprecated in favor of single \"workflow\" command)\n \"workflow:version\",\n \"workflow:init\",\n \"workflow:validate\",\n \"workflow:config\",\n \"workflow:config-show\",\n \"workflow:config-set\",\n \"workflow:suggest\",\n \"workflow:setup\",\n \"workflow:setup-auto\",\n \"workflow:doctor\",\n \"workflow:scope\",\n \"workflow:scope-list\",\n \"workflow:scope-create\",\n \"workflow:scope-migrate\",\n \"workflow:scope-add\",\n \"workflow:scope-remove\",\n \"workflow:scope-sync\",\n \"workflow:scope-analyze\",\n \"workflow:scope-hooks\",\n \"workflow:scope-hooks-status\",\n \"workflow:scope-hooks-install\",\n \"workflow:scope-hooks-uninstall\",\n \"workflow:scope-hooks-test\",\n \"workflow:verify\",\n \"workflow:verify-fix\",\n \"workflow:pre-commit\",\n \"workflow:learn-list\",\n \"workflow:learn-analyze\",\n \"workflow:learn-capture\",\n \"workflow:learn-apply\",\n \"workflow:learn-export\",\n \"workflow:learn-import\",\n \"workflow:learn-status\",\n \"workflow:learn-stats\",\n \"workflow:learn-clean\",\n \"workflow:learn-config\",\n \"workflow:learn-config-enable\",\n \"workflow:learn-config-disable\",\n \"workflow:learn-sync\",\n \"workflow:learn-sync-push\",\n \"workflow:learn-sync-pull\",\n \"workflow:solution-list\",\n \"workflow:solution-create\",\n \"workflow:solution-show\",\n \"workflow:solution-search\",\n \"workflow:solution-apply\",\n \"workflow:solution-export\",\n \"workflow:solution-import\",\n \"workflow:solution-analyze\",\n \"workflow:sync\",\n \"workflow:sync-status\",\n \"workflow:sync-push\",\n \"workflow:sync-pull\",\n \"workflow:docs\",\n \"workflow:docs-validate\",\n \"workflow:docs-validate-fix\",\n \"workflow:docs-advisory\",\n \"workflow:docs-advisory-quick\",\n \"workflow:docs-advisory-standard\",\n \"workflow:docs-advisory-comprehensive\",\n \"workflow:docs-advisory-executive\",\n \"workflow:docs-advisory-ci\",\n \"workflow:docs-generate\",\n \"workflow:docs-update\",\n \"workflow:docs-update-force\",\n] as const;\n\nexport type DeprecatedScriptName = (typeof DEPRECATED_SCRIPTS)[number];\n\n/**\n * The only script that should be added to package.json\n * Users run commands with: npm run workflow -- init\n */\nexport const WORKFLOW_SCRIPTS = {\n workflow: \"workflow-agent\",\n} as const;\n\nexport type WorkflowScriptName = keyof typeof WORKFLOW_SCRIPTS;\n\n/**\n * Script categories - simplified\n */\nexport const SCRIPT_CATEGORIES = {\n Main: [\"workflow\"],\n} as const;\n\nexport const TOTAL_SCRIPTS = Object.keys(WORKFLOW_SCRIPTS).length;\n\n","/**\n * Silent template installer for postinstall and non-interactive contexts\n *\n * This module provides functions to copy mandatory templates without\n * user interaction, suitable for use in postinstall scripts.\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"fs\";\nimport { readdirSync } from \"fs\";\nimport { join, basename } from \"path\";\nimport { getMandatoryTemplateFilenames } from \"../templates/metadata.js\";\n\nexport interface InstallTemplatesOptions {\n /** Force overwrite existing files */\n force?: boolean;\n /** Skip if guidelines directory already exists */\n skipIfExists?: boolean;\n /** Silent mode - no console output */\n silent?: boolean;\n /** Only install mandatory templates (default: true) */\n mandatoryOnly?: boolean;\n}\n\nexport interface InstallTemplatesResult {\n success: boolean;\n installed: string[];\n skipped: string[];\n updated: string[];\n errors: string[];\n guidelinesExisted: boolean;\n}\n\n/**\n * Get project name from package.json or directory name\n */\nfunction getProjectName(projectRoot: string): string {\n try {\n const pkgPath = join(projectRoot, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n return pkg.name || basename(projectRoot);\n }\n } catch {\n // Ignore errors, fall back to directory name\n }\n return basename(projectRoot);\n}\n\n/**\n * Simple template variable substitution using {{variable}} syntax\n */\nfunction renderTemplate(\n template: string,\n context: Record<string, string>,\n): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (match, key) => {\n return context[key] ?? match;\n });\n}\n\n/**\n * Build default template context from project info\n * Uses generic defaults when no workflow.config.json exists\n */\nfunction buildDefaultContext(projectRoot: string): Record<string, string> {\n const projectName = getProjectName(projectRoot);\n\n return {\n projectName,\n framework: \"unknown\",\n scopes: \"feat, fix, docs, refactor, test, chore\",\n scopeList: `- **feat** - New features\n- **fix** - Bug fixes\n- **docs** - Documentation\n- **refactor** - Code refactoring\n- **test** - Testing\n- **chore** - Maintenance`,\n pathStructure: \"N/A\",\n enforcement: \"strict\",\n year: new Date().getFullYear().toString(),\n };\n}\n\n/**\n * Find the templates directory relative to this module\n * Works in both development and installed contexts\n */\nexport function findTemplatesDirectory(callerDirname: string): string | null {\n // When installed: dist/scripts/template-installer.js -> ../../templates\n // Try multiple possible locations\n const possiblePaths = [\n join(callerDirname, \"../../templates\"),\n join(callerDirname, \"../templates\"),\n join(callerDirname, \"templates\"),\n ];\n\n for (const templatePath of possiblePaths) {\n if (existsSync(templatePath)) {\n return templatePath;\n }\n }\n\n return null;\n}\n\n/**\n * Install mandatory templates to a project's guidelines directory\n * Designed for non-interactive use (postinstall, CI, etc.)\n */\nexport function installMandatoryTemplates(\n projectRoot: string,\n templatesDir: string,\n options: InstallTemplatesOptions = {},\n): InstallTemplatesResult {\n const {\n force = false,\n skipIfExists = true,\n silent = false,\n mandatoryOnly = true,\n } = options;\n\n const result: InstallTemplatesResult = {\n success: true,\n installed: [],\n skipped: [],\n updated: [],\n errors: [],\n guidelinesExisted: false,\n };\n\n const guidelinesDir = join(projectRoot, \"guidelines\");\n result.guidelinesExisted = existsSync(guidelinesDir);\n\n // Skip if guidelines exists and skipIfExists is true\n if (result.guidelinesExisted && skipIfExists && !force) {\n if (!silent) {\n console.log(\" Guidelines directory already exists, skipping templates\");\n }\n return result;\n }\n\n // Get list of templates to install\n const mandatoryFiles = getMandatoryTemplateFilenames();\n\n // Check templates directory exists\n if (!existsSync(templatesDir)) {\n result.success = false;\n result.errors.push(`Templates directory not found: ${templatesDir}`);\n return result;\n }\n\n // Get available template files\n let availableFiles: string[];\n try {\n availableFiles = readdirSync(templatesDir).filter((f) => f.endsWith(\".md\"));\n } catch (error) {\n result.success = false;\n result.errors.push(`Failed to read templates directory: ${error}`);\n return result;\n }\n\n // Determine which files to install\n const filesToInstall = mandatoryOnly\n ? availableFiles.filter((f) => mandatoryFiles.includes(f))\n : availableFiles;\n\n if (filesToInstall.length === 0) {\n result.success = false;\n result.errors.push(\"No template files found to install\");\n return result;\n }\n\n // Build template context\n const context = buildDefaultContext(projectRoot);\n\n // Create guidelines directory\n try {\n mkdirSync(guidelinesDir, { recursive: true });\n } catch (error) {\n result.success = false;\n result.errors.push(`Failed to create guidelines directory: ${error}`);\n return result;\n }\n\n // Copy each template\n for (const filename of filesToInstall) {\n const sourcePath = join(templatesDir, filename);\n const destPath = join(guidelinesDir, filename);\n\n const fileExists = existsSync(destPath);\n\n // Skip if file exists and not forcing\n if (fileExists && !force) {\n result.skipped.push(filename);\n continue;\n }\n\n try {\n const template = readFileSync(sourcePath, \"utf-8\");\n const rendered = renderTemplate(template, context);\n writeFileSync(destPath, rendered, \"utf-8\");\n\n if (fileExists) {\n result.updated.push(filename);\n } else {\n result.installed.push(filename);\n }\n } catch (error) {\n result.errors.push(`Failed to install ${filename}: ${error}`);\n }\n }\n\n // Log results if not silent\n if (!silent) {\n if (result.installed.length > 0) {\n console.log(\n `\\n✓ Installed ${result.installed.length} guideline templates:`,\n );\n for (const file of result.installed) {\n console.log(` - ${file}`);\n }\n }\n if (result.updated.length > 0) {\n console.log(`\\n✓ Updated ${result.updated.length} guideline templates:`);\n for (const file of result.updated) {\n console.log(` - ${file}`);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Update templates - reinstall templates with option to force or skip existing\n */\nexport function updateTemplates(\n projectRoot: string,\n templatesDir: string,\n options: { force?: boolean; silent?: boolean } = {},\n): InstallTemplatesResult {\n return installMandatoryTemplates(projectRoot, templatesDir, {\n ...options,\n skipIfExists: false, // Don't skip - we want to update\n mandatoryOnly: false, // Install all templates during update\n });\n}\n","/**\n * Template metadata defining mandatory vs optional guidelines\n * and their associated validators for enforcement\n *\n * @fileoverview This module defines which guidelines are mandatory for projects\n * using the workflow agent. Mandatory guidelines MUST be present and cannot be\n * skipped during project initialization.\n *\n * TODO: Ensure all new templates have associated unit tests in metadata.test.ts\n */\n\nexport type TemplateCategory = \"workflow\" | \"documentation\" | \"development\";\n\nexport type ValidatorType =\n | \"branch-name\"\n | \"commit-message\"\n | \"pr-title\"\n | \"implementation-plan\"\n | \"test-coverage\"\n | \"file-exists\";\n\nexport interface TemplateMetadata {\n /** Template filename */\n filename: string;\n /** Human-readable name */\n displayName: string;\n /** Whether this template is mandatory (cannot be skipped during init) */\n mandatory: boolean;\n /** Category for grouping */\n category: TemplateCategory;\n /** Associated validators that enforce this template's rules */\n validators: ValidatorType[];\n /** Brief description of what this template covers */\n description: string;\n}\n\n/**\n * Metadata for all available templates\n * Templates marked as mandatory will be auto-generated during init\n * and checked by the doctor command\n */\nexport const templateMetadata: Record<string, TemplateMetadata> = {\n \"AGENT_EDITING_INSTRUCTIONS.md\": {\n filename: \"AGENT_EDITING_INSTRUCTIONS.md\",\n displayName: \"Agent Editing Instructions\",\n mandatory: true,\n category: \"workflow\",\n validators: [\"implementation-plan\"],\n description:\n \"Core rules for AI agents: implementation plans, coding standards, architecture\",\n },\n \"BRANCHING_STRATEGY.md\": {\n filename: \"BRANCHING_STRATEGY.md\",\n displayName: \"Branching Strategy\",\n mandatory: true,\n category: \"workflow\",\n validators: [\"branch-name\", \"pr-title\"],\n description:\n \"Git branch naming conventions, PR requirements, merge policies\",\n },\n \"TESTING_STRATEGY.md\": {\n filename: \"TESTING_STRATEGY.md\",\n displayName: \"Testing Strategy\",\n mandatory: true,\n category: \"development\",\n validators: [\"test-coverage\"],\n description:\n \"Testing pyramid, Vitest/Playwright patterns, when tests are required\",\n },\n \"SELF_IMPROVEMENT_MANDATE.md\": {\n filename: \"SELF_IMPROVEMENT_MANDATE.md\",\n displayName: \"Self-Improvement Mandate\",\n mandatory: true,\n category: \"workflow\",\n validators: [],\n description: \"Continuous improvement tracking, changelog requirements\",\n },\n \"PATTERN_ANALYSIS_WORKFLOW.md\": {\n filename: \"PATTERN_ANALYSIS_WORKFLOW.md\",\n displayName: \"Pattern Analysis Workflow\",\n mandatory: true,\n category: \"workflow\",\n validators: [],\n description:\n \"AI agent workflow for analyzing codebases, extracting patterns, and updating the central pattern store\",\n },\n \"SINGLE_SOURCE_OF_TRUTH.md\": {\n filename: \"SINGLE_SOURCE_OF_TRUTH.md\",\n displayName: \"Single Source of Truth\",\n mandatory: true,\n category: \"workflow\",\n validators: [],\n description:\n \"Canonical code locations, service patterns, avoiding duplication\",\n },\n \"COMPONENT_LIBRARY.md\": {\n filename: \"COMPONENT_LIBRARY.md\",\n displayName: \"Component Library\",\n mandatory: false,\n category: \"development\",\n validators: [],\n description: \"UI component patterns, design tokens, decision tree\",\n },\n \"DEPLOYMENT_STRATEGY.md\": {\n filename: \"DEPLOYMENT_STRATEGY.md\",\n displayName: \"Deployment Strategy\",\n mandatory: false,\n category: \"development\",\n validators: [],\n description: \"Deployment workflow, environments, migrations, rollback\",\n },\n \"LIBRARY_INVENTORY.md\": {\n filename: \"LIBRARY_INVENTORY.md\",\n displayName: \"Library Inventory\",\n mandatory: true,\n category: \"development\",\n validators: [],\n description: \"Dependency catalog, approved libraries, new library process\",\n },\n \"SCOPE_CREATION_WORKFLOW.md\": {\n filename: \"SCOPE_CREATION_WORKFLOW.md\",\n displayName: \"Scope Creation Workflow\",\n mandatory: false,\n category: \"workflow\",\n validators: [],\n description: \"Workflow for AI agents creating custom scopes\",\n },\n \"CUSTOM_SCOPE_TEMPLATE.md\": {\n filename: \"CUSTOM_SCOPE_TEMPLATE.md\",\n displayName: \"Custom Scope Template\",\n mandatory: false,\n category: \"workflow\",\n validators: [],\n description: \"Template for defining custom scope packages\",\n },\n \"PROJECT_TEMPLATE_README.md\": {\n filename: \"PROJECT_TEMPLATE_README.md\",\n displayName: \"Project Template README\",\n mandatory: false,\n category: \"documentation\",\n validators: [],\n description: \"Meta-document describing project structure\",\n },\n \"Guidelines.md\": {\n filename: \"Guidelines.md\",\n displayName: \"Custom Guidelines\",\n mandatory: false,\n category: \"documentation\",\n validators: [],\n description: \"Placeholder for custom user guidelines\",\n },\n};\n\n/**\n * Get all mandatory templates\n */\nexport function getMandatoryTemplates(): TemplateMetadata[] {\n return Object.values(templateMetadata).filter((t) => t.mandatory);\n}\n\n/**\n * Get all optional templates\n */\nexport function getOptionalTemplates(): TemplateMetadata[] {\n return Object.values(templateMetadata).filter((t) => !t.mandatory);\n}\n\n/**\n * Get templates by category\n */\nexport function getTemplatesByCategory(\n category: TemplateCategory,\n): TemplateMetadata[] {\n return Object.values(templateMetadata).filter((t) => t.category === category);\n}\n\n/**\n * Get template metadata by filename\n */\nexport function getTemplateMetadata(\n filename: string,\n): TemplateMetadata | undefined {\n return templateMetadata[filename];\n}\n\n/**\n * Check if a template is mandatory\n */\nexport function isTemplateMandatory(filename: string): boolean {\n return templateMetadata[filename]?.mandatory ?? false;\n}\n\n/**\n * Get mandatory template filenames\n */\nexport function getMandatoryTemplateFilenames(): string[] {\n return getMandatoryTemplates().map((t) => t.filename);\n}\n"],"mappings":"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","names":["existsSync","readFileSync","writeFileSync","mkdirSync","readdirSync","join","basename","join","existsSync","readFileSync","basename","readdirSync","mkdirSync","writeFileSync"]}
|