workflow-agent-cli 2.20.1 → 2.21.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/dist/cli/index.js CHANGED
@@ -3,12 +3,9 @@ import {
3
3
  analyzeProject,
4
4
  detectPackageManager,
5
5
  generateAuditReport,
6
- hasUncommittedChanges,
7
6
  isMonorepo,
8
- runAllChecks,
9
- runAllSetups,
10
- stageAllChanges
11
- } from "../chunk-6NWQLGHI.js";
7
+ runAllSetups
8
+ } from "../chunk-XGS2VFBP.js";
12
9
  import {
13
10
  applyReferenceFix,
14
11
  validateBranchName,
@@ -33,17 +30,21 @@ import {
33
30
  installMandatoryTemplates,
34
31
  templateMetadata,
35
32
  updateTemplates
36
- } from "../chunk-CIGGRLZU.js";
33
+ } from "../chunk-YR2X64TH.js";
37
34
  import {
38
35
  autoFixConfigFile,
39
36
  validateScopeDefinitions
40
37
  } from "../chunk-YELUGXOM.js";
38
+ import {
39
+ verifyCommand
40
+ } from "../chunk-OMHCXETM.js";
41
+ import "../chunk-KVM6A42U.js";
41
42
  import {
42
43
  syncCommand
43
44
  } from "../chunk-WXHRDBAB.js";
44
45
 
45
46
  // src/cli/index.ts
46
- import { Command as Command6 } from "commander";
47
+ import { Command as Command7 } from "commander";
47
48
  import chalk23 from "chalk";
48
49
 
49
50
  // src/cli/commands/init.ts
@@ -904,6 +905,9 @@ async function doctorCommand(options) {
904
905
  }
905
906
  }
906
907
 
908
+ // src/cli/commands/setup/index.ts
909
+ import { Command } from "commander";
910
+
907
911
  // src/cli/commands/setup.ts
908
912
  import * as p3 from "@clack/prompts";
909
913
  import chalk6 from "chalk";
@@ -1041,21 +1045,176 @@ async function setupCommand() {
1041
1045
  }
1042
1046
  }
1043
1047
 
1044
- // src/cli/commands/scope-create.ts
1048
+ // src/cli/commands/auto-setup-command.ts
1045
1049
  import * as p4 from "@clack/prompts";
1046
1050
  import chalk7 from "chalk";
1051
+ async function autoSetupCommand(options) {
1052
+ console.log(chalk7.bold.cyan("\n\u{1F527} Workflow Agent Auto-Setup\n"));
1053
+ const cwd = process.cwd();
1054
+ const spinner10 = p4.spinner();
1055
+ spinner10.start("Analyzing project...");
1056
+ let report;
1057
+ try {
1058
+ report = await generateAuditReport(cwd);
1059
+ spinner10.stop("\u2713 Project analysis complete");
1060
+ } catch (error) {
1061
+ spinner10.stop("\u2717 Failed to analyze project");
1062
+ console.error(
1063
+ chalk7.red(
1064
+ `Error: ${error instanceof Error ? error.message : String(error)}`
1065
+ )
1066
+ );
1067
+ process.exit(1);
1068
+ }
1069
+ console.log("\n" + formatAuditReportColored(report));
1070
+ if (options.audit) {
1071
+ console.log(chalk7.dim("\n--audit mode: No changes applied.\n"));
1072
+ return;
1073
+ }
1074
+ if (report.totalChanges === 0 && report.allDevDependencies.length === 0) {
1075
+ p4.outro(chalk7.green("\u2713 Project is already fully configured!"));
1076
+ return;
1077
+ }
1078
+ if (!options.yes) {
1079
+ const shouldProceed = await p4.confirm({
1080
+ message: `Apply ${report.totalChanges} changes and install ${report.allDevDependencies.length} packages?`,
1081
+ initialValue: true
1082
+ });
1083
+ if (p4.isCancel(shouldProceed) || !shouldProceed) {
1084
+ p4.cancel("Setup cancelled");
1085
+ process.exit(0);
1086
+ }
1087
+ } else {
1088
+ console.log(chalk7.dim("\n--yes mode: Auto-approving all changes.\n"));
1089
+ }
1090
+ console.log("");
1091
+ const setupSpinner = p4.spinner();
1092
+ const stepMessages = [];
1093
+ const results = await runAllSetups(cwd, (step, status) => {
1094
+ if (status === "start") {
1095
+ setupSpinner.start(step);
1096
+ } else if (status === "done") {
1097
+ setupSpinner.stop(`\u2713 ${step}`);
1098
+ stepMessages.push(`\u2713 ${step}`);
1099
+ } else {
1100
+ setupSpinner.stop(`\u2717 ${step}`);
1101
+ stepMessages.push(`\u2717 ${step}`);
1102
+ }
1103
+ });
1104
+ const successCount = results.filter((r) => r.success).length;
1105
+ const failCount = results.filter((r) => !r.success).length;
1106
+ console.log("");
1107
+ if (failCount === 0) {
1108
+ p4.outro(
1109
+ chalk7.green(
1110
+ `\u2713 Auto-setup complete! (${successCount} configurations applied)`
1111
+ )
1112
+ );
1113
+ } else {
1114
+ p4.outro(
1115
+ chalk7.yellow(
1116
+ `\u26A0 Setup completed with issues: ${successCount} succeeded, ${failCount} failed`
1117
+ )
1118
+ );
1119
+ }
1120
+ console.log(chalk7.dim("\nNext steps:"));
1121
+ console.log(chalk7.dim(" 1. Review the generated configuration files"));
1122
+ console.log(chalk7.dim(" 2. Run: pnpm verify (or npm/yarn)"));
1123
+ console.log(chalk7.dim(" 3. Commit your changes\n"));
1124
+ }
1125
+ function formatAuditReportColored(report) {
1126
+ const lines = [];
1127
+ lines.push(chalk7.bold("\u{1F4CB} Audit Report\n"));
1128
+ lines.push(chalk7.dim(`Framework: ${report.analysis.framework}`));
1129
+ lines.push(chalk7.dim(`Package Manager: ${report.analysis.packageManager}`));
1130
+ lines.push(
1131
+ chalk7.dim(`TypeScript: ${report.analysis.isTypeScript ? "Yes" : "No"}`)
1132
+ );
1133
+ lines.push(
1134
+ chalk7.dim(`Monorepo: ${report.analysis.isMonorepo ? "Yes" : "No"}`)
1135
+ );
1136
+ lines.push("");
1137
+ for (const plan of report.plans) {
1138
+ const hasChanges = plan.changes.some((c) => c.type !== "unchanged");
1139
+ const icon = hasChanges ? "\u{1F527}" : "\u2713";
1140
+ const titleColor = hasChanges ? chalk7.yellow : chalk7.green;
1141
+ lines.push(
1142
+ titleColor(
1143
+ `${icon} ${plan.name.charAt(0).toUpperCase() + plan.name.slice(1)} - ${plan.description}`
1144
+ )
1145
+ );
1146
+ for (const change of plan.changes) {
1147
+ let symbol;
1148
+ let line;
1149
+ switch (change.type) {
1150
+ case "add":
1151
+ symbol = chalk7.green("+");
1152
+ line = chalk7.green(change.description);
1153
+ break;
1154
+ case "modify":
1155
+ symbol = chalk7.yellow("~");
1156
+ line = chalk7.yellow(change.description);
1157
+ if (change.key && change.oldValue !== void 0 && change.newValue !== void 0) {
1158
+ line += chalk7.dim(
1159
+ ` (${String(change.oldValue)} \u2192 ${String(change.newValue)})`
1160
+ );
1161
+ }
1162
+ break;
1163
+ case "unchanged":
1164
+ default:
1165
+ symbol = chalk7.dim("=");
1166
+ line = chalk7.dim(change.description);
1167
+ }
1168
+ lines.push(` ${symbol} ${line}`);
1169
+ }
1170
+ if (plan.devDependencies.length > 0) {
1171
+ lines.push(
1172
+ chalk7.blue(` \u{1F4E6} Install: ${plan.devDependencies.join(", ")}`)
1173
+ );
1174
+ }
1175
+ lines.push("");
1176
+ }
1177
+ if (report.allDevDependencies.length > 0) {
1178
+ lines.push(chalk7.bold("Dependencies to install (batched):"));
1179
+ const pm = report.analysis.packageManager;
1180
+ const cmd = pm === "npm" ? "npm install" : pm === "yarn" ? "yarn add" : `${pm} add`;
1181
+ lines.push(
1182
+ chalk7.cyan(` ${cmd} -D ${report.allDevDependencies.join(" ")}`)
1183
+ );
1184
+ lines.push("");
1185
+ }
1186
+ lines.push(
1187
+ chalk7.bold(
1188
+ `Total: ${report.totalChanges} changes, ${report.allDevDependencies.length} packages`
1189
+ )
1190
+ );
1191
+ return lines.join("\n");
1192
+ }
1193
+
1194
+ // src/cli/commands/setup/index.ts
1195
+ function createSetupCommand() {
1196
+ const setupCmd = new Command("setup").description("Setup and configuration commands");
1197
+ setupCmd.action(setupCommand);
1198
+ setupCmd.command("scripts").description("Add workflow scripts to package.json").action(setupCommand);
1199
+ setupCmd.command("auto").description("Automatically configure linting, formatting, testing, and CI").option("-y, --yes", "Auto-approve all prompts").option("--audit", "Show audit report without applying changes").action(autoSetupCommand);
1200
+ return setupCmd;
1201
+ }
1202
+
1203
+ // src/cli/commands/scope-create.ts
1204
+ import * as p5 from "@clack/prompts";
1205
+ import chalk8 from "chalk";
1047
1206
  import { existsSync as existsSync5 } from "fs";
1048
1207
  import { writeFile as writeFile3, mkdir as mkdir3, readFile as readFile2 } from "fs/promises";
1049
1208
  import { join as join5 } from "path";
1050
1209
  async function scopeCreateCommand(options) {
1051
- console.log(chalk7.bold.cyan("\n\u{1F3A8} Create Custom Scope Package\n"));
1210
+ console.log(chalk8.bold.cyan("\n\u{1F3A8} Create Custom Scope Package\n"));
1052
1211
  const cwd = process.cwd();
1053
1212
  const isNonInteractive = !!(options.name && options.scopes && options.presetName);
1054
1213
  const isMonorepo2 = existsSync5(join5(cwd, "pnpm-workspace.yaml"));
1055
1214
  if (isMonorepo2) {
1056
- console.log(chalk7.dim("\u2713 Detected monorepo workspace\n"));
1215
+ console.log(chalk8.dim("\u2713 Detected monorepo workspace\n"));
1057
1216
  }
1058
- const packageNameInput = isNonInteractive ? options.name : await p4.text({
1217
+ const packageNameInput = isNonInteractive ? options.name : await p5.text({
1059
1218
  message: 'What is the package name? (e.g., "fintech", "gaming", "healthcare")',
1060
1219
  placeholder: "my-custom-scope",
1061
1220
  validate: (value) => {
@@ -1067,12 +1226,12 @@ async function scopeCreateCommand(options) {
1067
1226
  return void 0;
1068
1227
  }
1069
1228
  });
1070
- if (!isNonInteractive && p4.isCancel(packageNameInput)) {
1071
- p4.cancel("Operation cancelled");
1229
+ if (!isNonInteractive && p5.isCancel(packageNameInput)) {
1230
+ p5.cancel("Operation cancelled");
1072
1231
  process.exit(0);
1073
1232
  }
1074
1233
  const packageName = packageNameInput;
1075
- const presetNameInput = isNonInteractive ? options.presetName : await p4.text({
1234
+ const presetNameInput = isNonInteractive ? options.presetName : await p5.text({
1076
1235
  message: 'What is the preset display name? (e.g., "FinTech Application", "Gaming Platform")',
1077
1236
  placeholder: "My Custom Preset",
1078
1237
  validate: (value) => {
@@ -1080,8 +1239,8 @@ async function scopeCreateCommand(options) {
1080
1239
  return void 0;
1081
1240
  }
1082
1241
  });
1083
- if (!isNonInteractive && p4.isCancel(presetNameInput)) {
1084
- p4.cancel("Operation cancelled");
1242
+ if (!isNonInteractive && p5.isCancel(presetNameInput)) {
1243
+ p5.cancel("Operation cancelled");
1085
1244
  process.exit(0);
1086
1245
  }
1087
1246
  const presetName = presetNameInput;
@@ -1099,11 +1258,11 @@ async function scopeCreateCommand(options) {
1099
1258
  }
1100
1259
  } else {
1101
1260
  console.log(
1102
- chalk7.dim("\nAdd scopes to your preset (aim for 8-15 scopes):\n")
1261
+ chalk8.dim("\nAdd scopes to your preset (aim for 8-15 scopes):\n")
1103
1262
  );
1104
1263
  let addMore = true;
1105
1264
  while (addMore) {
1106
- const scopeName = await p4.text({
1265
+ const scopeName = await p5.text({
1107
1266
  message: `Scope #${scopes.length + 1} - Name:`,
1108
1267
  placeholder: "auth",
1109
1268
  validate: (value) => {
@@ -1116,10 +1275,10 @@ async function scopeCreateCommand(options) {
1116
1275
  return void 0;
1117
1276
  }
1118
1277
  });
1119
- if (p4.isCancel(scopeName)) {
1278
+ if (p5.isCancel(scopeName)) {
1120
1279
  break;
1121
1280
  }
1122
- const scopeDescription = await p4.text({
1281
+ const scopeDescription = await p5.text({
1123
1282
  message: "Description:",
1124
1283
  placeholder: "Authentication and authorization",
1125
1284
  validate: (value) => {
@@ -1128,17 +1287,17 @@ async function scopeCreateCommand(options) {
1128
1287
  return void 0;
1129
1288
  }
1130
1289
  });
1131
- if (p4.isCancel(scopeDescription)) {
1290
+ if (p5.isCancel(scopeDescription)) {
1132
1291
  break;
1133
1292
  }
1134
- const scopeEmoji = await p4.text({
1293
+ const scopeEmoji = await p5.text({
1135
1294
  message: "Emoji (optional):",
1136
1295
  placeholder: "\u{1F510}"
1137
1296
  });
1138
- if (p4.isCancel(scopeEmoji)) {
1297
+ if (p5.isCancel(scopeEmoji)) {
1139
1298
  break;
1140
1299
  }
1141
- const scopeCategory = await p4.select({
1300
+ const scopeCategory = await p5.select({
1142
1301
  message: "Category (optional):",
1143
1302
  options: [
1144
1303
  { value: "auth", label: "Authentication & Authorization" },
@@ -1151,7 +1310,7 @@ async function scopeCreateCommand(options) {
1151
1310
  { value: "", label: "None" }
1152
1311
  ]
1153
1312
  });
1154
- if (p4.isCancel(scopeCategory)) {
1313
+ if (p5.isCancel(scopeCategory)) {
1155
1314
  break;
1156
1315
  }
1157
1316
  scopes.push({
@@ -1160,15 +1319,15 @@ async function scopeCreateCommand(options) {
1160
1319
  emoji: scopeEmoji ? scopeEmoji : void 0,
1161
1320
  category: scopeCategory ? scopeCategory : void 0
1162
1321
  });
1163
- console.log(chalk7.green(`
1322
+ console.log(chalk8.green(`
1164
1323
  \u2713 Added scope: ${scopeName}
1165
1324
  `));
1166
1325
  if (scopes.length >= 3) {
1167
- addMore = await p4.confirm({
1326
+ addMore = await p5.confirm({
1168
1327
  message: `You have ${scopes.length} scopes. Add another?`,
1169
1328
  initialValue: scopes.length < 10
1170
1329
  });
1171
- if (p4.isCancel(addMore)) {
1330
+ if (p5.isCancel(addMore)) {
1172
1331
  break;
1173
1332
  }
1174
1333
  if (!addMore) break;
@@ -1176,20 +1335,20 @@ async function scopeCreateCommand(options) {
1176
1335
  }
1177
1336
  }
1178
1337
  if (scopes.length === 0) {
1179
- p4.cancel("No scopes defined. Operation cancelled.");
1338
+ p5.cancel("No scopes defined. Operation cancelled.");
1180
1339
  process.exit(1);
1181
1340
  }
1182
1341
  const validation = validateScopeDefinitions(scopes);
1183
1342
  if (!validation.valid) {
1184
- console.log(chalk7.red("\n\u2717 Scope validation failed:\n"));
1343
+ console.log(chalk8.red("\n\u2717 Scope validation failed:\n"));
1185
1344
  validation.errors.forEach(
1186
- (error) => console.log(chalk7.red(` \u2022 ${error}`))
1345
+ (error) => console.log(chalk8.red(` \u2022 ${error}`))
1187
1346
  );
1188
- p4.cancel("Operation cancelled");
1347
+ p5.cancel("Operation cancelled");
1189
1348
  process.exit(1);
1190
1349
  }
1191
1350
  console.log(
1192
- chalk7.green(`
1351
+ chalk8.green(`
1193
1352
  \u2713 ${scopes.length} scopes validated successfully
1194
1353
  `)
1195
1354
  );
@@ -1199,28 +1358,28 @@ async function scopeCreateCommand(options) {
1199
1358
  } else if (isMonorepo2) {
1200
1359
  outputDir = join5(cwd, "packages", `scopes-${packageName}`);
1201
1360
  } else {
1202
- const customDir = await p4.text({
1361
+ const customDir = await p5.text({
1203
1362
  message: "Output directory:",
1204
1363
  placeholder: `./scopes-${packageName}`,
1205
1364
  defaultValue: `./scopes-${packageName}`
1206
1365
  });
1207
- if (p4.isCancel(customDir)) {
1208
- p4.cancel("Operation cancelled");
1366
+ if (p5.isCancel(customDir)) {
1367
+ p5.cancel("Operation cancelled");
1209
1368
  process.exit(0);
1210
1369
  }
1211
1370
  outputDir = join5(cwd, customDir);
1212
1371
  }
1213
1372
  if (existsSync5(outputDir)) {
1214
- const shouldOverwrite = await p4.confirm({
1373
+ const shouldOverwrite = await p5.confirm({
1215
1374
  message: `Directory ${outputDir} already exists. Overwrite?`,
1216
1375
  initialValue: false
1217
1376
  });
1218
- if (p4.isCancel(shouldOverwrite) || !shouldOverwrite) {
1219
- p4.cancel("Operation cancelled");
1377
+ if (p5.isCancel(shouldOverwrite) || !shouldOverwrite) {
1378
+ p5.cancel("Operation cancelled");
1220
1379
  process.exit(0);
1221
1380
  }
1222
1381
  }
1223
- const spinner10 = p4.spinner();
1382
+ const spinner10 = p5.spinner();
1224
1383
  spinner10.start("Creating package structure...");
1225
1384
  try {
1226
1385
  await mkdir3(join5(outputDir, "src"), { recursive: true });
@@ -1359,111 +1518,111 @@ describe('${presetName} Scope Preset', () => {
1359
1518
  const packagePath = `packages/scopes-${packageName}`;
1360
1519
  if (!workspaceContent.includes(packagePath) && !workspaceContent.includes("packages/*")) {
1361
1520
  console.log(
1362
- chalk7.yellow("\n\u26A0\uFE0F Add the following to pnpm-workspace.yaml:")
1521
+ chalk8.yellow("\n\u26A0\uFE0F Add the following to pnpm-workspace.yaml:")
1363
1522
  );
1364
- console.log(chalk7.dim(` - '${packagePath}'`));
1523
+ console.log(chalk8.dim(` - '${packagePath}'`));
1365
1524
  } else {
1366
- console.log(chalk7.green("\n\u2713 Package will be included in workspace"));
1525
+ console.log(chalk8.green("\n\u2713 Package will be included in workspace"));
1367
1526
  }
1368
1527
  }
1369
1528
  console.log(
1370
- chalk7.green.bold("\n\u2728 Custom scope package created successfully!\n")
1529
+ chalk8.green.bold("\n\u2728 Custom scope package created successfully!\n")
1371
1530
  );
1372
- console.log(chalk7.bold("Package details:"));
1373
- console.log(chalk7.dim(` Location: ${outputDir}`));
1374
- console.log(chalk7.dim(` Package: @workflow/scopes-${packageName}`));
1375
- console.log(chalk7.dim(` Scopes: ${scopes.length} defined
1531
+ console.log(chalk8.bold("Package details:"));
1532
+ console.log(chalk8.dim(` Location: ${outputDir}`));
1533
+ console.log(chalk8.dim(` Package: @workflow/scopes-${packageName}`));
1534
+ console.log(chalk8.dim(` Scopes: ${scopes.length} defined
1376
1535
  `));
1377
- console.log(chalk7.bold("Next steps:\n"));
1378
- console.log(chalk7.dim(` 1. cd ${outputDir}`));
1379
- console.log(chalk7.dim(` 2. pnpm install`));
1380
- console.log(chalk7.dim(` 3. pnpm build`));
1536
+ console.log(chalk8.bold("Next steps:\n"));
1537
+ console.log(chalk8.dim(` 1. cd ${outputDir}`));
1538
+ console.log(chalk8.dim(` 2. pnpm install`));
1539
+ console.log(chalk8.dim(` 3. pnpm build`));
1381
1540
  if (!options.noTest) {
1382
- console.log(chalk7.dim(` 4. pnpm test`));
1541
+ console.log(chalk8.dim(` 4. pnpm test`));
1383
1542
  }
1384
1543
  console.log(
1385
- chalk7.dim(
1544
+ chalk8.dim(
1386
1545
  ` ${!options.noTest ? "5" : "4"}. Update repository URL in package.json`
1387
1546
  )
1388
1547
  );
1389
- const shouldPublish = isNonInteractive ? false : await p4.confirm({
1548
+ const shouldPublish = isNonInteractive ? false : await p5.confirm({
1390
1549
  message: "\nWould you like instructions for publishing to npm?",
1391
1550
  initialValue: false
1392
1551
  });
1393
- if (shouldPublish && !p4.isCancel(shouldPublish)) {
1394
- console.log(chalk7.bold("\n\u{1F4E6} Publishing instructions:\n"));
1552
+ if (shouldPublish && !p5.isCancel(shouldPublish)) {
1553
+ console.log(chalk8.bold("\n\u{1F4E6} Publishing instructions:\n"));
1395
1554
  console.log(
1396
- chalk7.dim(" 1. npm login (or configure .npmrc with your registry)")
1555
+ chalk8.dim(" 1. npm login (or configure .npmrc with your registry)")
1397
1556
  );
1398
- console.log(chalk7.dim(" 2. Update version in package.json as needed"));
1399
- console.log(chalk7.dim(" 3. pnpm publish --access public"));
1557
+ console.log(chalk8.dim(" 2. Update version in package.json as needed"));
1558
+ console.log(chalk8.dim(" 3. pnpm publish --access public"));
1400
1559
  console.log(
1401
- chalk7.dim(
1560
+ chalk8.dim(
1402
1561
  " 4. Use in other projects: pnpm add @workflow/scopes-" + packageName + "\n"
1403
1562
  )
1404
1563
  );
1405
1564
  }
1406
1565
  } catch (error) {
1407
1566
  spinner10.stop("\u2717 Failed to create package");
1408
- console.error(chalk7.red("\nError:"), error);
1567
+ console.error(chalk8.red("\nError:"), error);
1409
1568
  process.exit(1);
1410
1569
  }
1411
1570
  }
1412
1571
 
1413
1572
  // src/cli/commands/scope-migrate.ts
1414
- import * as p5 from "@clack/prompts";
1415
- import chalk8 from "chalk";
1573
+ import * as p6 from "@clack/prompts";
1574
+ import chalk9 from "chalk";
1416
1575
  import { existsSync as existsSync6 } from "fs";
1417
1576
  import { writeFile as writeFile4, mkdir as mkdir4, readFile as readFile3 } from "fs/promises";
1418
1577
  import { join as join6 } from "path";
1419
1578
  async function scopeMigrateCommand(options) {
1420
- console.log(chalk8.bold.cyan("\n\u{1F504} Migrate Scopes to Custom Package\n"));
1579
+ console.log(chalk9.bold.cyan("\n\u{1F504} Migrate Scopes to Custom Package\n"));
1421
1580
  const cwd = process.cwd();
1422
1581
  if (!hasConfig(cwd)) {
1423
- p5.cancel("No workflow.config.json found in current directory");
1582
+ p6.cancel("No workflow.config.json found in current directory");
1424
1583
  process.exit(1);
1425
1584
  }
1426
1585
  let config = null;
1427
1586
  try {
1428
1587
  config = await loadConfig(cwd);
1429
1588
  } catch (error) {
1430
- console.error(chalk8.red("Failed to load config:"), error);
1589
+ console.error(chalk9.red("Failed to load config:"), error);
1431
1590
  process.exit(1);
1432
1591
  }
1433
1592
  if (!config) {
1434
- p5.cancel("Failed to load configuration");
1593
+ p6.cancel("Failed to load configuration");
1435
1594
  process.exit(1);
1436
1595
  }
1437
1596
  if (!config.scopes || config.scopes.length === 0) {
1438
- p5.cancel("No scopes found in workflow.config.json");
1597
+ p6.cancel("No scopes found in workflow.config.json");
1439
1598
  process.exit(1);
1440
1599
  }
1441
1600
  console.log(
1442
- chalk8.dim(`Found ${config.scopes.length} scopes in workflow.config.json
1601
+ chalk9.dim(`Found ${config.scopes.length} scopes in workflow.config.json
1443
1602
  `)
1444
1603
  );
1445
- console.log(chalk8.bold("Current scopes:"));
1604
+ console.log(chalk9.bold("Current scopes:"));
1446
1605
  config.scopes.forEach((scope, i) => {
1447
1606
  console.log(
1448
- chalk8.dim(
1607
+ chalk9.dim(
1449
1608
  ` ${i + 1}. ${scope.emoji || "\u2022"} ${scope.name} - ${scope.description}`
1450
1609
  )
1451
1610
  );
1452
1611
  });
1453
1612
  console.log();
1454
- const shouldContinue = await p5.confirm({
1613
+ const shouldContinue = await p6.confirm({
1455
1614
  message: "Migrate these scopes to a custom package?",
1456
1615
  initialValue: true
1457
1616
  });
1458
- if (p5.isCancel(shouldContinue) || !shouldContinue) {
1459
- p5.cancel("Migration cancelled");
1617
+ if (p6.isCancel(shouldContinue) || !shouldContinue) {
1618
+ p6.cancel("Migration cancelled");
1460
1619
  process.exit(0);
1461
1620
  }
1462
1621
  const isMonorepo2 = existsSync6(join6(cwd, "pnpm-workspace.yaml"));
1463
1622
  if (isMonorepo2) {
1464
- console.log(chalk8.dim("\n\u2713 Detected monorepo workspace\n"));
1623
+ console.log(chalk9.dim("\n\u2713 Detected monorepo workspace\n"));
1465
1624
  }
1466
- const packageNameInput = options.name || await p5.text({
1625
+ const packageNameInput = options.name || await p6.text({
1467
1626
  message: "Package name for the scope preset:",
1468
1627
  placeholder: config.projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-"),
1469
1628
  validate: (value) => {
@@ -1475,33 +1634,33 @@ async function scopeMigrateCommand(options) {
1475
1634
  return void 0;
1476
1635
  }
1477
1636
  });
1478
- if (p5.isCancel(packageNameInput)) {
1479
- p5.cancel("Migration cancelled");
1637
+ if (p6.isCancel(packageNameInput)) {
1638
+ p6.cancel("Migration cancelled");
1480
1639
  process.exit(0);
1481
1640
  }
1482
1641
  const packageName = packageNameInput;
1483
- const presetNameInput = await p5.text({
1642
+ const presetNameInput = await p6.text({
1484
1643
  message: "Preset display name:",
1485
1644
  placeholder: config.projectName,
1486
1645
  defaultValue: config.projectName
1487
1646
  });
1488
- if (p5.isCancel(presetNameInput)) {
1489
- p5.cancel("Migration cancelled");
1647
+ if (p6.isCancel(presetNameInput)) {
1648
+ p6.cancel("Migration cancelled");
1490
1649
  process.exit(0);
1491
1650
  }
1492
1651
  const presetName = presetNameInput;
1493
1652
  const validation = validateScopeDefinitions(config.scopes);
1494
1653
  if (!validation.valid) {
1495
- console.log(chalk8.yellow("\n\u26A0\uFE0F Scope validation warnings:\n"));
1654
+ console.log(chalk9.yellow("\n\u26A0\uFE0F Scope validation warnings:\n"));
1496
1655
  validation.errors.forEach(
1497
- (error) => console.log(chalk8.yellow(` \u2022 ${error}`))
1656
+ (error) => console.log(chalk9.yellow(` \u2022 ${error}`))
1498
1657
  );
1499
- const shouldFix = await p5.confirm({
1658
+ const shouldFix = await p6.confirm({
1500
1659
  message: "Some scopes have validation issues. Continue anyway?",
1501
1660
  initialValue: false
1502
1661
  });
1503
- if (p5.isCancel(shouldFix) || !shouldFix) {
1504
- p5.cancel("Migration cancelled. Please fix validation errors first.");
1662
+ if (p6.isCancel(shouldFix) || !shouldFix) {
1663
+ p6.cancel("Migration cancelled. Please fix validation errors first.");
1505
1664
  process.exit(1);
1506
1665
  }
1507
1666
  }
@@ -1511,28 +1670,28 @@ async function scopeMigrateCommand(options) {
1511
1670
  } else if (isMonorepo2) {
1512
1671
  outputDir = join6(cwd, "packages", `scopes-${packageName}`);
1513
1672
  } else {
1514
- const customDir = await p5.text({
1673
+ const customDir = await p6.text({
1515
1674
  message: "Output directory:",
1516
1675
  placeholder: `./scopes-${packageName}`,
1517
1676
  defaultValue: `./scopes-${packageName}`
1518
1677
  });
1519
- if (p5.isCancel(customDir)) {
1520
- p5.cancel("Migration cancelled");
1678
+ if (p6.isCancel(customDir)) {
1679
+ p6.cancel("Migration cancelled");
1521
1680
  process.exit(0);
1522
1681
  }
1523
1682
  outputDir = join6(cwd, customDir);
1524
1683
  }
1525
1684
  if (existsSync6(outputDir)) {
1526
- const shouldOverwrite = await p5.confirm({
1685
+ const shouldOverwrite = await p6.confirm({
1527
1686
  message: `Directory ${outputDir} already exists. Overwrite?`,
1528
1687
  initialValue: false
1529
1688
  });
1530
- if (p5.isCancel(shouldOverwrite) || !shouldOverwrite) {
1531
- p5.cancel("Migration cancelled");
1689
+ if (p6.isCancel(shouldOverwrite) || !shouldOverwrite) {
1690
+ p6.cancel("Migration cancelled");
1532
1691
  process.exit(0);
1533
1692
  }
1534
1693
  }
1535
- const spinner10 = p5.spinner();
1694
+ const spinner10 = p6.spinner();
1536
1695
  spinner10.start("Migrating scopes to package...");
1537
1696
  try {
1538
1697
  await mkdir4(join6(outputDir, "src"), { recursive: true });
@@ -1668,18 +1827,18 @@ describe('${presetName} Scope Preset (Migrated)', () => {
1668
1827
  const packagePath = `packages/scopes-${packageName}`;
1669
1828
  if (!workspaceContent.includes(packagePath) && !workspaceContent.includes("packages/*")) {
1670
1829
  console.log(
1671
- chalk8.yellow("\n\u26A0\uFE0F Add the following to pnpm-workspace.yaml:")
1830
+ chalk9.yellow("\n\u26A0\uFE0F Add the following to pnpm-workspace.yaml:")
1672
1831
  );
1673
- console.log(chalk8.dim(` - '${packagePath}'`));
1832
+ console.log(chalk9.dim(` - '${packagePath}'`));
1674
1833
  } else {
1675
- console.log(chalk8.green("\n\u2713 Package will be included in workspace"));
1834
+ console.log(chalk9.green("\n\u2713 Package will be included in workspace"));
1676
1835
  }
1677
1836
  }
1678
- const keepConfig = options.keepConfig ?? await p5.confirm({
1837
+ const keepConfig = options.keepConfig ?? await p6.confirm({
1679
1838
  message: "Remove migrated scopes from workflow.config.json?",
1680
1839
  initialValue: false
1681
1840
  });
1682
- if (!p5.isCancel(keepConfig) && !keepConfig) {
1841
+ if (!p6.isCancel(keepConfig) && !keepConfig) {
1683
1842
  const configPath = join6(cwd, "workflow.config.json");
1684
1843
  const updatedConfig = {
1685
1844
  ...config,
@@ -1693,428 +1852,78 @@ describe('${presetName} Scope Preset (Migrated)', () => {
1693
1852
  JSON.stringify(updatedConfig, null, 2),
1694
1853
  "utf-8"
1695
1854
  );
1696
- console.log(chalk8.green("\u2713 Updated workflow.config.json"));
1697
- console.log(chalk8.dim(" \u2022 Cleared inline scopes"));
1855
+ console.log(chalk9.green("\u2713 Updated workflow.config.json"));
1856
+ console.log(chalk9.dim(" \u2022 Cleared inline scopes"));
1698
1857
  console.log(
1699
- chalk8.dim(` \u2022 Added preset reference: scopes-${packageName}
1858
+ chalk9.dim(` \u2022 Added preset reference: scopes-${packageName}
1700
1859
  `)
1701
1860
  );
1702
1861
  }
1703
- console.log(chalk8.green.bold("\n\u2728 Migration completed successfully!\n"));
1704
- console.log(chalk8.bold("Package details:"));
1705
- console.log(chalk8.dim(` Location: ${outputDir}`));
1706
- console.log(chalk8.dim(` Package: @workflow/scopes-${packageName}`));
1707
- console.log(chalk8.dim(` Scopes: ${config.scopes.length} migrated
1862
+ console.log(chalk9.green.bold("\n\u2728 Migration completed successfully!\n"));
1863
+ console.log(chalk9.bold("Package details:"));
1864
+ console.log(chalk9.dim(` Location: ${outputDir}`));
1865
+ console.log(chalk9.dim(` Package: @workflow/scopes-${packageName}`));
1866
+ console.log(chalk9.dim(` Scopes: ${config.scopes.length} migrated
1708
1867
  `));
1709
- console.log(chalk8.bold("Next steps:\n"));
1710
- console.log(chalk8.dim(` 1. cd ${outputDir}`));
1711
- console.log(chalk8.dim(` 2. pnpm install`));
1712
- console.log(chalk8.dim(` 3. pnpm build`));
1713
- console.log(chalk8.dim(` 4. pnpm test`));
1714
- console.log(chalk8.dim(` 5. Update repository URL in package.json
1868
+ console.log(chalk9.bold("Next steps:\n"));
1869
+ console.log(chalk9.dim(` 1. cd ${outputDir}`));
1870
+ console.log(chalk9.dim(` 2. pnpm install`));
1871
+ console.log(chalk9.dim(` 3. pnpm build`));
1872
+ console.log(chalk9.dim(` 4. pnpm test`));
1873
+ console.log(chalk9.dim(` 5. Update repository URL in package.json
1715
1874
  `));
1716
1875
  if (!keepConfig) {
1717
- console.log(chalk8.bold("To use the migrated scopes:\n"));
1876
+ console.log(chalk9.bold("To use the migrated scopes:\n"));
1718
1877
  console.log(
1719
- chalk8.dim(
1878
+ chalk9.dim(
1720
1879
  ` 1. Install the package: pnpm add -w @workflow/scopes-${packageName}`
1721
1880
  )
1722
1881
  );
1723
- console.log(
1724
- chalk8.dim(
1725
- ` 2. The preset is already referenced in workflow.config.json
1726
- `
1727
- )
1728
- );
1729
- }
1730
- console.log(
1731
- chalk8.dim(
1732
- "\u{1F4A1} Tip: You can now reuse this scope package across multiple projects!\n"
1733
- )
1734
- );
1735
- } catch (error) {
1736
- spinner10.stop("\u2717 Migration failed");
1737
- console.error(chalk8.red("\nError:"), error);
1738
- process.exit(1);
1739
- }
1740
- }
1741
-
1742
- // src/cli/commands/verify.ts
1743
- import chalk9 from "chalk";
1744
- import { execa as execa2 } from "execa";
1745
- import {
1746
- PatternStore,
1747
- TelemetryCollector,
1748
- ContributorManager
1749
- } from "@hawkinside_out/workflow-improvement-tracker";
1750
- async function verifyCommand(options) {
1751
- const cwd = process.cwd();
1752
- const maxRetries = options.maxRetries ? parseInt(options.maxRetries, 10) : 10;
1753
- const autoFix = options.fix ?? false;
1754
- const shouldCommit = options.commit ?? false;
1755
- const dryRun = options.dryRun ?? false;
1756
- const learnFromFixes = options.learn ?? false;
1757
- console.log(chalk9.bold.cyan("\n\u{1F50D} Workflow Agent Quality Verification\n"));
1758
- if (dryRun) {
1759
- console.log(chalk9.yellow("\u{1F4CB} DRY-RUN MODE: No changes will be applied\n"));
1760
- }
1761
- console.log(chalk9.dim(` Auto-fix: ${autoFix ? "enabled" : "disabled"}`));
1762
- console.log(chalk9.dim(` Max retries: ${maxRetries}`));
1763
- console.log(chalk9.dim(` Commit on success: ${shouldCommit ? "yes" : "no"}`));
1764
- console.log(chalk9.dim(` Dry-run: ${dryRun ? "yes" : "no"}`));
1765
- console.log(
1766
- chalk9.dim(` Learn from fixes: ${learnFromFixes ? "yes" : "no"}`)
1767
- );
1768
- const startTime = Date.now();
1769
- const result = await runAllChecks(cwd, {
1770
- maxRetries,
1771
- autoFix,
1772
- dryRun
1773
- });
1774
- const totalTime = ((Date.now() - startTime) / 1e3).toFixed(2);
1775
- console.log(`
1776
- ${"\u2501".repeat(50)}`);
1777
- if (result.success) {
1778
- console.log(chalk9.bold.green("\n\u2705 ALL QUALITY CHECKS PASSED!\n"));
1779
- console.log(chalk9.dim(` Total time: ${totalTime}s`));
1780
- console.log(chalk9.dim(` Validation cycles: ${result.totalAttempts}`));
1781
- console.log(chalk9.dim(` Fixes applied: ${result.fixesApplied}`));
1782
- if (learnFromFixes && result.fixesApplied > 0 && !dryRun) {
1783
- await recordSuccessfulFixes(cwd, result);
1784
- }
1785
- if (shouldCommit) {
1786
- const hasChanges = await hasUncommittedChanges(cwd);
1787
- if (hasChanges) {
1788
- console.log(chalk9.cyan("\n\u{1F4E6} Staging and committing changes...\n"));
1789
- const staged = await stageAllChanges(cwd);
1790
- if (!staged) {
1791
- console.log(chalk9.red("\u274C Failed to stage changes"));
1792
- process.exit(1);
1793
- }
1794
- try {
1795
- await execa2(
1796
- "git",
1797
- ["commit", "-m", "chore: auto-fix quality issues"],
1798
- { cwd }
1799
- );
1800
- console.log(chalk9.green("\u2705 Changes committed successfully"));
1801
- } catch (error) {
1802
- console.log(chalk9.red("\u274C Failed to commit changes"));
1803
- console.log(chalk9.dim(error.message));
1804
- process.exit(1);
1805
- }
1806
- } else {
1807
- console.log(chalk9.dim("\n No changes to commit."));
1808
- }
1809
- }
1810
- console.log(chalk9.cyan("\n\u{1F4A1} Next steps:\n"));
1811
- console.log(chalk9.dim(" 1. git add ."));
1812
- console.log(
1813
- chalk9.dim(' 2. git commit -m "<type>(<scope>): <description>"')
1814
- );
1815
- console.log(chalk9.dim(" 3. git push origin <branch-name>"));
1816
- console.log("");
1817
- process.exit(0);
1818
- } else {
1819
- console.log(chalk9.bold.red("\n\u274C QUALITY CHECKS FAILED\n"));
1820
- console.log(chalk9.dim(` Total time: ${totalTime}s`));
1821
- console.log(chalk9.dim(` Validation cycles: ${result.totalAttempts}`));
1822
- console.log(chalk9.dim(` Fixes applied: ${result.fixesApplied}`));
1823
- if (result.pendingFixes && result.pendingFixes.length > 0) {
1824
- console.log(chalk9.yellow("\n\u{1F4CB} Pending fixes (dry-run):"));
1825
- for (const fix of result.pendingFixes) {
1826
- console.log(chalk9.dim(` \u2022 ${fix.check.displayName}: ${fix.command}`));
1827
- }
1828
- }
1829
- console.log(
1830
- chalk9.yellow("\n\u26A0\uFE0F Please fix the errors above and run again.")
1831
- );
1832
- console.log(
1833
- chalk9.dim(" Run with --fix to auto-fix lint and format issues.")
1834
- );
1835
- console.log("");
1836
- process.exit(1);
1837
- }
1838
- }
1839
- async function recordSuccessfulFixes(cwd, result) {
1840
- try {
1841
- const contributorManager = new ContributorManager(cwd);
1842
- const telemetryEnabled = await contributorManager.isTelemetryEnabled();
1843
- if (!telemetryEnabled) {
1844
- return;
1845
- }
1846
- const store = new PatternStore(cwd);
1847
- const telemetry = new TelemetryCollector(cwd);
1848
- let framework = "unknown";
1849
- let frameworkVersion = "0.0.0";
1850
- try {
1851
- const fs3 = await import("fs");
1852
- const path4 = await import("path");
1853
- const packageJsonPath = path4.join(cwd, "package.json");
1854
- const packageJson = JSON.parse(
1855
- await fs3.promises.readFile(packageJsonPath, "utf-8")
1856
- );
1857
- const deps = {
1858
- ...packageJson.dependencies,
1859
- ...packageJson.devDependencies
1860
- };
1861
- if (deps["next"]) {
1862
- framework = "next";
1863
- frameworkVersion = deps["next"].replace(/[\^~]/, "");
1864
- } else if (deps["react"]) {
1865
- framework = "react";
1866
- frameworkVersion = deps["react"].replace(/[\^~]/, "");
1867
- } else if (deps["vue"]) {
1868
- framework = "vue";
1869
- frameworkVersion = deps["vue"].replace(/[\^~]/, "");
1870
- } else if (deps["express"]) {
1871
- framework = "express";
1872
- frameworkVersion = deps["express"].replace(/[\^~]/, "");
1873
- }
1874
- } catch {
1875
- }
1876
- if (result.appliedFixes && result.appliedFixes.length > 0) {
1877
- console.log(
1878
- chalk9.cyan("\n\u{1F4DA} Recording successful fixes for learning...\n")
1879
- );
1880
- for (const fix of result.appliedFixes) {
1881
- const patternName = `Auto-fix: ${fix.displayName}`;
1882
- const patternId = crypto.randomUUID();
1883
- const existingPatterns = await store.listFixPatterns({
1884
- tags: [{ category: "tool", name: fix.checkName }]
1885
- });
1886
- if (existingPatterns.success && existingPatterns.data && existingPatterns.data.length > 0) {
1887
- const existingPattern = existingPatterns.data[0];
1888
- await store.updateFixMetrics(existingPattern.id, true);
1889
- await telemetry.recordSuccess(
1890
- existingPattern.id,
1891
- "fix",
1892
- framework,
1893
- frameworkVersion
1894
- );
1895
- console.log(chalk9.dim(` \u2713 Updated: ${existingPattern.name}`));
1896
- } else {
1897
- const now = (/* @__PURE__ */ new Date()).toISOString();
1898
- const newPattern = {
1899
- id: patternId,
1900
- name: patternName,
1901
- description: `Auto-fix pattern for ${fix.displayName} using command: ${fix.command}`,
1902
- category: "config",
1903
- tags: [
1904
- { category: "tool", name: fix.checkName },
1905
- { category: "framework", name: framework }
1906
- ],
1907
- trigger: {
1908
- errorPattern: fix.checkName,
1909
- errorMessage: `${fix.checkName} check failed`,
1910
- filePattern: "**/*"
1911
- },
1912
- solution: {
1913
- type: "command",
1914
- steps: [
1915
- {
1916
- order: 1,
1917
- action: "run",
1918
- target: fix.command,
1919
- description: `Run ${fix.command}`
1920
- }
1921
- ]
1922
- },
1923
- compatibility: {
1924
- framework,
1925
- frameworkVersion: `>=${frameworkVersion}`,
1926
- runtime: "node",
1927
- runtimeVersion: ">=18.0.0",
1928
- dependencies: []
1929
- },
1930
- metrics: {
1931
- applications: 1,
1932
- successes: 1,
1933
- failures: 0,
1934
- successRate: 100,
1935
- lastUsed: now,
1936
- lastSuccessful: now
1937
- },
1938
- source: "verify-fix",
1939
- isPrivate: true,
1940
- createdAt: now,
1941
- updatedAt: now
1942
- };
1943
- const saveResult = await store.saveFixPattern(newPattern);
1944
- if (saveResult.success) {
1945
- await telemetry.recordSuccess(
1946
- patternId,
1947
- "fix",
1948
- framework,
1949
- frameworkVersion
1950
- );
1951
- console.log(chalk9.dim(` \u2713 Recorded: ${patternName}`));
1952
- }
1953
- }
1954
- }
1955
- console.log(
1956
- chalk9.dim(`
1957
- Use 'workflow learn:list' to see recorded patterns.`)
1958
- );
1959
- }
1960
- } catch (error) {
1961
- console.log(
1962
- chalk9.dim(
1963
- `
1964
- Note: Could not record learning patterns: ${error.message}`
1965
- )
1966
- );
1967
- }
1968
- }
1969
-
1970
- // src/cli/commands/auto-setup-command.ts
1971
- import * as p6 from "@clack/prompts";
1972
- import chalk10 from "chalk";
1973
- async function autoSetupCommand(options) {
1974
- console.log(chalk10.bold.cyan("\n\u{1F527} Workflow Agent Auto-Setup\n"));
1975
- const cwd = process.cwd();
1976
- const spinner10 = p6.spinner();
1977
- spinner10.start("Analyzing project...");
1978
- let report;
1979
- try {
1980
- report = await generateAuditReport(cwd);
1981
- spinner10.stop("\u2713 Project analysis complete");
1982
- } catch (error) {
1983
- spinner10.stop("\u2717 Failed to analyze project");
1984
- console.error(
1985
- chalk10.red(
1986
- `Error: ${error instanceof Error ? error.message : String(error)}`
1987
- )
1988
- );
1989
- process.exit(1);
1990
- }
1991
- console.log("\n" + formatAuditReportColored(report));
1992
- if (options.audit) {
1993
- console.log(chalk10.dim("\n--audit mode: No changes applied.\n"));
1994
- return;
1995
- }
1996
- if (report.totalChanges === 0 && report.allDevDependencies.length === 0) {
1997
- p6.outro(chalk10.green("\u2713 Project is already fully configured!"));
1998
- return;
1999
- }
2000
- if (!options.yes) {
2001
- const shouldProceed = await p6.confirm({
2002
- message: `Apply ${report.totalChanges} changes and install ${report.allDevDependencies.length} packages?`,
2003
- initialValue: true
2004
- });
2005
- if (p6.isCancel(shouldProceed) || !shouldProceed) {
2006
- p6.cancel("Setup cancelled");
2007
- process.exit(0);
2008
- }
2009
- } else {
2010
- console.log(chalk10.dim("\n--yes mode: Auto-approving all changes.\n"));
2011
- }
2012
- console.log("");
2013
- const setupSpinner = p6.spinner();
2014
- const stepMessages = [];
2015
- const results = await runAllSetups(cwd, (step, status) => {
2016
- if (status === "start") {
2017
- setupSpinner.start(step);
2018
- } else if (status === "done") {
2019
- setupSpinner.stop(`\u2713 ${step}`);
2020
- stepMessages.push(`\u2713 ${step}`);
2021
- } else {
2022
- setupSpinner.stop(`\u2717 ${step}`);
2023
- stepMessages.push(`\u2717 ${step}`);
2024
- }
2025
- });
2026
- const successCount = results.filter((r) => r.success).length;
2027
- const failCount = results.filter((r) => !r.success).length;
2028
- console.log("");
2029
- if (failCount === 0) {
2030
- p6.outro(
2031
- chalk10.green(
2032
- `\u2713 Auto-setup complete! (${successCount} configurations applied)`
2033
- )
2034
- );
2035
- } else {
2036
- p6.outro(
2037
- chalk10.yellow(
2038
- `\u26A0 Setup completed with issues: ${successCount} succeeded, ${failCount} failed`
2039
- )
2040
- );
2041
- }
2042
- console.log(chalk10.dim("\nNext steps:"));
2043
- console.log(chalk10.dim(" 1. Review the generated configuration files"));
2044
- console.log(chalk10.dim(" 2. Run: pnpm verify (or npm/yarn)"));
2045
- console.log(chalk10.dim(" 3. Commit your changes\n"));
2046
- }
2047
- function formatAuditReportColored(report) {
2048
- const lines = [];
2049
- lines.push(chalk10.bold("\u{1F4CB} Audit Report\n"));
2050
- lines.push(chalk10.dim(`Framework: ${report.analysis.framework}`));
2051
- lines.push(chalk10.dim(`Package Manager: ${report.analysis.packageManager}`));
2052
- lines.push(
2053
- chalk10.dim(`TypeScript: ${report.analysis.isTypeScript ? "Yes" : "No"}`)
2054
- );
2055
- lines.push(
2056
- chalk10.dim(`Monorepo: ${report.analysis.isMonorepo ? "Yes" : "No"}`)
2057
- );
2058
- lines.push("");
2059
- for (const plan of report.plans) {
2060
- const hasChanges = plan.changes.some((c) => c.type !== "unchanged");
2061
- const icon = hasChanges ? "\u{1F527}" : "\u2713";
2062
- const titleColor = hasChanges ? chalk10.yellow : chalk10.green;
2063
- lines.push(
2064
- titleColor(
2065
- `${icon} ${plan.name.charAt(0).toUpperCase() + plan.name.slice(1)} - ${plan.description}`
2066
- )
2067
- );
2068
- for (const change of plan.changes) {
2069
- let symbol;
2070
- let line;
2071
- switch (change.type) {
2072
- case "add":
2073
- symbol = chalk10.green("+");
2074
- line = chalk10.green(change.description);
2075
- break;
2076
- case "modify":
2077
- symbol = chalk10.yellow("~");
2078
- line = chalk10.yellow(change.description);
2079
- if (change.key && change.oldValue !== void 0 && change.newValue !== void 0) {
2080
- line += chalk10.dim(
2081
- ` (${String(change.oldValue)} \u2192 ${String(change.newValue)})`
2082
- );
2083
- }
2084
- break;
2085
- case "unchanged":
2086
- default:
2087
- symbol = chalk10.dim("=");
2088
- line = chalk10.dim(change.description);
2089
- }
2090
- lines.push(` ${symbol} ${line}`);
2091
- }
2092
- if (plan.devDependencies.length > 0) {
2093
- lines.push(
2094
- chalk10.blue(` \u{1F4E6} Install: ${plan.devDependencies.join(", ")}`)
2095
- );
1882
+ console.log(
1883
+ chalk9.dim(
1884
+ ` 2. The preset is already referenced in workflow.config.json
1885
+ `
1886
+ )
1887
+ );
2096
1888
  }
2097
- lines.push("");
2098
- }
2099
- if (report.allDevDependencies.length > 0) {
2100
- lines.push(chalk10.bold("Dependencies to install (batched):"));
2101
- const pm = report.analysis.packageManager;
2102
- const cmd = pm === "npm" ? "npm install" : pm === "yarn" ? "yarn add" : `${pm} add`;
2103
- lines.push(
2104
- chalk10.cyan(` ${cmd} -D ${report.allDevDependencies.join(" ")}`)
1889
+ console.log(
1890
+ chalk9.dim(
1891
+ "\u{1F4A1} Tip: You can now reuse this scope package across multiple projects!\n"
1892
+ )
2105
1893
  );
2106
- lines.push("");
1894
+ } catch (error) {
1895
+ spinner10.stop("\u2717 Migration failed");
1896
+ console.error(chalk9.red("\nError:"), error);
1897
+ process.exit(1);
2107
1898
  }
2108
- lines.push(
2109
- chalk10.bold(
2110
- `Total: ${report.totalChanges} changes, ${report.allDevDependencies.length} packages`
2111
- )
2112
- );
2113
- return lines.join("\n");
1899
+ }
1900
+
1901
+ // src/cli/commands/pre-commit.ts
1902
+ import chalk10 from "chalk";
1903
+ async function preCommitCommand(options) {
1904
+ const stagedOnly = options.stagedOnly ?? true;
1905
+ const dryRun = options.dryRun ?? false;
1906
+ const maxRetries = options.maxRetries ?? "5";
1907
+ console.log(chalk10.bold.cyan("\n\u{1F512} Pre-Commit Quality Check\n"));
1908
+ if (dryRun) {
1909
+ console.log(chalk10.yellow("\u{1F4CB} DRY-RUN MODE: No changes will be applied\n"));
1910
+ }
1911
+ if (stagedOnly) {
1912
+ console.log(chalk10.dim(" Checking staged files only...\n"));
1913
+ }
1914
+ await verifyCommand({
1915
+ fix: true,
1916
+ maxRetries,
1917
+ commit: false,
1918
+ // Never auto-commit in pre-commit
1919
+ dryRun,
1920
+ learn: false
1921
+ // Skip learning in pre-commit for speed
1922
+ });
2114
1923
  }
2115
1924
 
2116
1925
  // src/cli/commands/docs/index.ts
2117
- import { Command } from "commander";
1926
+ import { Command as Command2 } from "commander";
2118
1927
  import chalk15 from "chalk";
2119
1928
 
2120
1929
  // src/cli/commands/docs-validate.ts
@@ -5145,7 +4954,7 @@ function checkCIThresholds(analysis, config) {
5145
4954
 
5146
4955
  // src/cli/commands/docs/index.ts
5147
4956
  function createDocsCommand() {
5148
- const docsCmd = new Command("docs").description("Manage documentation and guidelines").addHelpText(
4957
+ const docsCmd = new Command2("docs").description("Manage documentation and guidelines").addHelpText(
5149
4958
  "after",
5150
4959
  `
5151
4960
  ${chalk15.bold("Examples:")}
@@ -5218,7 +5027,7 @@ ${chalk15.bold("Examples:")}
5218
5027
  }
5219
5028
 
5220
5029
  // src/cli/commands/hooks/index.ts
5221
- import { Command as Command2 } from "commander";
5030
+ import { Command as Command3 } from "commander";
5222
5031
  import chalk17 from "chalk";
5223
5032
 
5224
5033
  // src/cli/commands/hooks.ts
@@ -5337,62 +5146,8 @@ async function statusHooksAction(cwd) {
5337
5146
  }
5338
5147
  }
5339
5148
 
5340
- // src/cli/commands/hooks/index.ts
5341
- async function installAction() {
5342
- return hooksCommand("install");
5343
- }
5344
- async function uninstallAction() {
5345
- return hooksCommand("uninstall");
5346
- }
5347
- async function statusAction() {
5348
- return hooksCommand("status");
5349
- }
5350
- function createHooksCommand() {
5351
- const hooksCmd = new Command2("hooks").description("Manage git hooks for the project").addHelpText(
5352
- "after",
5353
- `
5354
- ${chalk17.bold("Examples:")}
5355
- $ workflow hooks install ${chalk17.dim("# Install git hooks")}
5356
- $ workflow hooks uninstall ${chalk17.dim("# Remove git hooks")}
5357
- $ workflow hooks status ${chalk17.dim("# Check hooks status")}
5358
- `
5359
- ).action(() => {
5360
- hooksCmd.help();
5361
- });
5362
- hooksCmd.command("install").description("Install git hooks for the project").addHelpText(
5363
- "after",
5364
- `
5365
- ${chalk17.bold("Details:")}
5366
- Installs pre-commit and commit-msg hooks that:
5367
- - Validate branch names
5368
- - Validate commit message format
5369
- - Run quality checks before commit
5370
-
5371
- If existing hooks are found, they will be wrapped
5372
- so both the original and workflow hooks run.
5373
- `
5374
- ).action(installAction);
5375
- hooksCmd.command("uninstall").description("Remove installed git hooks").addHelpText(
5376
- "after",
5377
- `
5378
- ${chalk17.bold("Details:")}
5379
- Removes workflow agent hooks from the project.
5380
- If original hooks were wrapped, they will be restored.
5381
- `
5382
- ).action(uninstallAction);
5383
- hooksCmd.command("status").description("Show current hooks installation status").addHelpText(
5384
- "after",
5385
- `
5386
- ${chalk17.bold("Details:")}
5387
- Shows which git hooks are installed and whether
5388
- they are managed by workflow agent.
5389
- `
5390
- ).action(statusAction);
5391
- return hooksCmd;
5392
- }
5393
-
5394
5149
  // src/cli/commands/solution/index.ts
5395
- import { Command as Command3 } from "commander";
5150
+ import { Command as Command4 } from "commander";
5396
5151
  import chalk19 from "chalk";
5397
5152
 
5398
5153
  // src/cli/commands/solution.ts
@@ -5400,7 +5155,7 @@ import chalk18 from "chalk";
5400
5155
  import * as p11 from "@clack/prompts";
5401
5156
  import * as path2 from "path";
5402
5157
  import {
5403
- PatternStore as PatternStore2,
5158
+ PatternStore,
5404
5159
  CodeAnalyzer
5405
5160
  } from "@hawkinside_out/workflow-improvement-tracker";
5406
5161
  function getWorkspacePath() {
@@ -5438,7 +5193,8 @@ function truncate(str, maxLen) {
5438
5193
  }
5439
5194
  async function solutionCaptureCommand(options) {
5440
5195
  const cwd = getWorkspacePath();
5441
- const store = new PatternStore2(cwd);
5196
+ const store = new PatternStore(cwd);
5197
+ await store.initialize();
5442
5198
  console.log(chalk18.cyan("\n\u{1F4E6} Capture Solution Pattern\n"));
5443
5199
  let targetPath = options.path;
5444
5200
  if (!targetPath) {
@@ -5586,7 +5342,8 @@ async function solutionCaptureCommand(options) {
5586
5342
  }
5587
5343
  async function solutionSearchCommand(query, options) {
5588
5344
  const cwd = getWorkspacePath();
5589
- const store = new PatternStore2(cwd);
5345
+ const store = new PatternStore(cwd);
5346
+ await store.initialize();
5590
5347
  console.log(chalk18.cyan("\n\u{1F50D} Search Solution Patterns\n"));
5591
5348
  const keywords = query.split(/\s+/).filter((k) => k.length > 0);
5592
5349
  const result = await store.searchSolutions(keywords, {
@@ -5626,7 +5383,8 @@ async function solutionSearchCommand(query, options) {
5626
5383
  }
5627
5384
  async function solutionListCommand(options) {
5628
5385
  const cwd = getWorkspacePath();
5629
- const store = new PatternStore2(cwd);
5386
+ const store = new PatternStore(cwd);
5387
+ await store.initialize();
5630
5388
  console.log(chalk18.cyan("\n\u{1F4CB} Solution Patterns\n"));
5631
5389
  const result = await store.listSolutions({
5632
5390
  category: options.category,
@@ -5681,7 +5439,8 @@ ${formatCategory(category)}`));
5681
5439
  }
5682
5440
  async function solutionApplyCommand(solutionId, options) {
5683
5441
  const cwd = getWorkspacePath();
5684
- const store = new PatternStore2(cwd);
5442
+ const store = new PatternStore(cwd);
5443
+ await store.initialize();
5685
5444
  console.log(chalk18.cyan("\n\u{1F680} Apply Solution Pattern\n"));
5686
5445
  const result = await store.getSolution(solutionId);
5687
5446
  if (!result.success || !result.data) {
@@ -5779,7 +5538,8 @@ async function solutionApplyCommand(solutionId, options) {
5779
5538
  }
5780
5539
  async function solutionDeprecateCommand(solutionId, reason) {
5781
5540
  const cwd = getWorkspacePath();
5782
- const store = new PatternStore2(cwd);
5541
+ const store = new PatternStore(cwd);
5542
+ await store.initialize();
5783
5543
  console.log(chalk18.cyan("\n\u26A0\uFE0F Deprecate Solution Pattern\n"));
5784
5544
  const result = await store.getSolution(solutionId);
5785
5545
  if (!result.success || !result.data) {
@@ -5807,7 +5567,8 @@ async function solutionDeprecateCommand(solutionId, reason) {
5807
5567
  }
5808
5568
  async function solutionStatsCommand() {
5809
5569
  const cwd = getWorkspacePath();
5810
- const store = new PatternStore2(cwd);
5570
+ const store = new PatternStore(cwd);
5571
+ await store.initialize();
5811
5572
  console.log(chalk18.cyan("\n\u{1F4CA} Solution Pattern Statistics\n"));
5812
5573
  const stats = await store.getStats();
5813
5574
  console.log(chalk18.dim("\u2500".repeat(40)));
@@ -5834,20 +5595,363 @@ ${chalk18.bold("By Category:")}`);
5834
5595
  }
5835
5596
  console.log();
5836
5597
  }
5598
+ async function solutionCreateCommand(options) {
5599
+ const cwd = getWorkspacePath();
5600
+ const store = new PatternStore(cwd);
5601
+ await store.initialize();
5602
+ console.log(chalk18.cyan("\n\u2728 Create Solution Pattern\n"));
5603
+ let name = options.name;
5604
+ if (!name) {
5605
+ const nameInput = await p11.text({
5606
+ message: "Solution name:",
5607
+ placeholder: "My Custom Solution",
5608
+ validate: (val) => {
5609
+ if (!val || val.length < 3) return "Name must be at least 3 characters";
5610
+ return void 0;
5611
+ }
5612
+ });
5613
+ if (p11.isCancel(nameInput)) {
5614
+ p11.cancel("Operation cancelled");
5615
+ process.exit(0);
5616
+ }
5617
+ name = nameInput;
5618
+ }
5619
+ let description = options.description;
5620
+ if (!description) {
5621
+ const descInput = await p11.text({
5622
+ message: "Solution description:",
5623
+ placeholder: "A description of what this solution does",
5624
+ validate: (val) => {
5625
+ if (!val || val.length < 10)
5626
+ return "Description must be at least 10 characters";
5627
+ return void 0;
5628
+ }
5629
+ });
5630
+ if (p11.isCancel(descInput)) {
5631
+ p11.cancel("Operation cancelled");
5632
+ process.exit(0);
5633
+ }
5634
+ description = descInput;
5635
+ }
5636
+ let category = options.category;
5637
+ if (!category) {
5638
+ const categoryChoice = await p11.select({
5639
+ message: "Solution category:",
5640
+ options: [
5641
+ { value: "auth", label: "\u{1F510} Authentication" },
5642
+ { value: "api", label: "\u{1F310} API" },
5643
+ { value: "database", label: "\u{1F4BE} Database" },
5644
+ { value: "ui", label: "\u{1F3A8} UI/Components" },
5645
+ { value: "testing", label: "\u{1F9EA} Testing" },
5646
+ { value: "deployment", label: "\u{1F680} Deployment" },
5647
+ { value: "integrations", label: "\u{1F517} Integrations" },
5648
+ { value: "performance", label: "\u26A1 Performance" },
5649
+ { value: "security", label: "\u{1F6E1}\uFE0F Security" },
5650
+ { value: "other", label: "\u{1F4E6} Other" }
5651
+ ]
5652
+ });
5653
+ if (p11.isCancel(categoryChoice)) {
5654
+ p11.cancel("Operation cancelled");
5655
+ process.exit(0);
5656
+ }
5657
+ category = categoryChoice;
5658
+ }
5659
+ let keywords = [];
5660
+ if (options.keywords) {
5661
+ keywords = options.keywords.split(",").map((k) => k.trim());
5662
+ } else {
5663
+ const keywordsInput = await p11.text({
5664
+ message: "Keywords (comma-separated):",
5665
+ placeholder: "auth, jwt, login"
5666
+ });
5667
+ if (p11.isCancel(keywordsInput)) {
5668
+ p11.cancel("Operation cancelled");
5669
+ process.exit(0);
5670
+ }
5671
+ if (keywordsInput) {
5672
+ keywords = keywordsInput.split(",").map((k) => k.trim());
5673
+ }
5674
+ }
5675
+ const framework = options.framework || "generic";
5676
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5677
+ const solution = {
5678
+ id: crypto.randomUUID(),
5679
+ name,
5680
+ description,
5681
+ category,
5682
+ keywords,
5683
+ implementation: {
5684
+ files: [],
5685
+ dependencies: [],
5686
+ devDependencies: [],
5687
+ envVars: []
5688
+ },
5689
+ compatibility: {
5690
+ framework,
5691
+ frameworkVersion: ">=1.0.0",
5692
+ runtime: "node",
5693
+ runtimeVersion: ">=18.0.0",
5694
+ dependencies: []
5695
+ },
5696
+ metrics: {
5697
+ applications: 0,
5698
+ successes: 0,
5699
+ failures: 0,
5700
+ successRate: 0
5701
+ },
5702
+ isPrivate: true,
5703
+ createdAt: now,
5704
+ updatedAt: now
5705
+ };
5706
+ await store.saveSolution(solution);
5707
+ console.log(chalk18.green("\n\u2713 Solution pattern created!\n"));
5708
+ console.log(chalk18.dim(` ID: ${solution.id}`));
5709
+ console.log(chalk18.dim(` Name: ${name}`));
5710
+ console.log(chalk18.dim(` Category: ${category}`));
5711
+ console.log(chalk18.dim(`
5712
+ Add files using 'workflow solution capture --path <dir>'`));
5713
+ }
5714
+ async function solutionShowCommand(solutionId) {
5715
+ const cwd = getWorkspacePath();
5716
+ const store = new PatternStore(cwd);
5717
+ await store.initialize();
5718
+ console.log(chalk18.cyan("\n\u{1F4CB} Solution Details\n"));
5719
+ const result = await store.getSolution(solutionId);
5720
+ if (!result.success || !result.data) {
5721
+ console.error(chalk18.red(`
5722
+ \u2717 Solution not found: ${solutionId}
5723
+ `));
5724
+ process.exit(1);
5725
+ }
5726
+ const solution = result.data;
5727
+ console.log(chalk18.dim("\u2500".repeat(60)));
5728
+ console.log(chalk18.bold(`Name: ${solution.name}`));
5729
+ console.log(`ID: ${chalk18.dim(solution.id)}`);
5730
+ console.log(`Category: ${formatCategory(solution.category)}`);
5731
+ console.log(`Description: ${solution.description}`);
5732
+ console.log(chalk18.dim("\u2500".repeat(60)));
5733
+ console.log(chalk18.bold("\nCompatibility:"));
5734
+ console.log(` Framework: ${solution.compatibility.framework || "generic"}`);
5735
+ console.log(` Version: ${solution.compatibility.frameworkVersion}`);
5736
+ console.log(` Runtime: ${solution.compatibility.runtime} ${solution.compatibility.runtimeVersion}`);
5737
+ console.log(chalk18.bold("\nImplementation:"));
5738
+ console.log(` Files: ${solution.implementation.files.length}`);
5739
+ for (const file of solution.implementation.files) {
5740
+ console.log(chalk18.dim(` \u2022 ${file.path} (${file.role})`));
5741
+ }
5742
+ if (solution.implementation.dependencies.length > 0) {
5743
+ console.log(` Dependencies: ${solution.implementation.dependencies.length}`);
5744
+ for (const dep of solution.implementation.dependencies) {
5745
+ console.log(chalk18.dim(` \u2022 ${dep.name}@${dep.version}`));
5746
+ }
5747
+ }
5748
+ if (solution.implementation.envVars.length > 0) {
5749
+ console.log(` Environment Variables: ${solution.implementation.envVars.length}`);
5750
+ for (const env of solution.implementation.envVars) {
5751
+ const required = env.required ? chalk18.red("*") : "";
5752
+ console.log(chalk18.dim(` \u2022 ${env.name}${required}`));
5753
+ }
5754
+ }
5755
+ console.log(chalk18.bold("\nMetrics:"));
5756
+ console.log(` Applications: ${solution.metrics.applications}`);
5757
+ console.log(` Success Rate: ${(solution.metrics.successRate * 100).toFixed(1)}%`);
5758
+ console.log(chalk18.bold("\nMetadata:"));
5759
+ console.log(` Created: ${formatDate(solution.createdAt)}`);
5760
+ console.log(` Updated: ${formatDate(solution.updatedAt)}`);
5761
+ console.log(` Private: ${solution.isPrivate ? "Yes" : "No"}`);
5762
+ if (solution.deprecatedAt) {
5763
+ console.log(chalk18.red(` Deprecated: ${formatDate(solution.deprecatedAt)}`));
5764
+ console.log(chalk18.dim(` Reason: ${solution.deprecationReason || "No reason provided"}`));
5765
+ }
5766
+ console.log();
5767
+ }
5768
+ async function solutionExportCommand(options) {
5769
+ const cwd = getWorkspacePath();
5770
+ const store = new PatternStore(cwd);
5771
+ await store.initialize();
5772
+ const format = options.format ?? "json";
5773
+ const outputPath = options.output ?? `solutions-export.${format}`;
5774
+ console.log(chalk18.cyan("\n\u{1F4E4} Exporting Solution Patterns\n"));
5775
+ const result = await store.listSolutions({
5776
+ solutionCategory: options.category,
5777
+ limit: 1e3
5778
+ });
5779
+ if (!result.success || !result.data) {
5780
+ console.error(chalk18.red(`
5781
+ \u2717 Export failed: ${result.error}
5782
+ `));
5783
+ process.exit(1);
5784
+ }
5785
+ const solutions = result.data;
5786
+ if (solutions.length === 0) {
5787
+ console.log(chalk18.yellow(" No solutions to export"));
5788
+ return;
5789
+ }
5790
+ const fs3 = await import("fs");
5791
+ const pathModule = await import("path");
5792
+ let output;
5793
+ if (format === "yaml") {
5794
+ output = `# Workflow Agent Solutions Export
5795
+ # Exported: ${(/* @__PURE__ */ new Date()).toISOString()}
5796
+
5797
+ solutions:
5798
+ `;
5799
+ for (const solution of solutions) {
5800
+ output += ` - id: ${solution.id}
5801
+ `;
5802
+ output += ` name: "${solution.name}"
5803
+ `;
5804
+ output += ` category: ${solution.category}
5805
+ `;
5806
+ output += ` description: "${solution.description}"
5807
+
5808
+ `;
5809
+ }
5810
+ } else {
5811
+ output = JSON.stringify(
5812
+ {
5813
+ version: "1.0",
5814
+ exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
5815
+ solutions
5816
+ },
5817
+ null,
5818
+ 2
5819
+ );
5820
+ }
5821
+ const fullOutputPath = pathModule.default.isAbsolute(outputPath) ? outputPath : pathModule.default.join(cwd, outputPath);
5822
+ await fs3.promises.writeFile(fullOutputPath, output, "utf-8");
5823
+ console.log(chalk18.green(` \u2713 Exported ${solutions.length} solutions
5824
+ `));
5825
+ console.log(chalk18.dim(` Output: ${fullOutputPath}`));
5826
+ console.log(chalk18.dim(` Format: ${format.toUpperCase()}`));
5827
+ }
5828
+ async function solutionImportCommand(file, options) {
5829
+ const cwd = getWorkspacePath();
5830
+ const store = new PatternStore(cwd);
5831
+ await store.initialize();
5832
+ const dryRun = options.dryRun ?? false;
5833
+ const merge = options.merge ?? true;
5834
+ console.log(chalk18.cyan("\n\u{1F4E5} Importing Solution Patterns\n"));
5835
+ const fs3 = await import("fs");
5836
+ const pathModule = await import("path");
5837
+ const filePath = pathModule.default.isAbsolute(file) ? file : pathModule.default.join(cwd, file);
5838
+ if (!fs3.existsSync(filePath)) {
5839
+ console.log(chalk18.red(` \u2717 File not found: ${filePath}`));
5840
+ process.exit(1);
5841
+ }
5842
+ const content = await fs3.promises.readFile(filePath, "utf-8");
5843
+ let importData;
5844
+ try {
5845
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
5846
+ console.log(chalk18.yellow(" YAML import not fully supported, treating as JSON"));
5847
+ }
5848
+ importData = JSON.parse(content);
5849
+ } catch {
5850
+ console.log(chalk18.red(" \u2717 Failed to parse import file"));
5851
+ process.exit(1);
5852
+ }
5853
+ const solutions = importData.solutions || [];
5854
+ if (solutions.length === 0) {
5855
+ console.log(chalk18.yellow(" No solutions found in import file"));
5856
+ return;
5857
+ }
5858
+ console.log(chalk18.dim(` Found ${solutions.length} solutions
5859
+ `));
5860
+ if (dryRun) {
5861
+ console.log(chalk18.yellow(" \u{1F50D} Dry run - no changes will be made\n"));
5862
+ for (const solution of solutions) {
5863
+ console.log(chalk18.dim(` Would import: ${solution.name} (${solution.id})`));
5864
+ }
5865
+ return;
5866
+ }
5867
+ let imported = 0;
5868
+ let skipped = 0;
5869
+ for (const solution of solutions) {
5870
+ const existing = await store.getSolution(solution.id);
5871
+ if (existing.success && existing.data && !merge) {
5872
+ console.log(chalk18.yellow(` Skipped (exists): ${solution.name}`));
5873
+ skipped++;
5874
+ continue;
5875
+ }
5876
+ await store.saveSolution(solution);
5877
+ console.log(chalk18.green(` \u2713 Imported: ${solution.name}`));
5878
+ imported++;
5879
+ }
5880
+ console.log(chalk18.green(`
5881
+ \u2713 Import complete`));
5882
+ console.log(chalk18.dim(` Imported: ${imported}`));
5883
+ console.log(chalk18.dim(` Skipped: ${skipped}`));
5884
+ }
5885
+ async function solutionAnalyzeCommand() {
5886
+ const cwd = getWorkspacePath();
5887
+ const store = new PatternStore(cwd);
5888
+ await store.initialize();
5889
+ const fs3 = await import("fs");
5890
+ const pathModule = await import("path");
5891
+ console.log(chalk18.cyan("\n\u{1F50D} Analyzing Codebase for Solution Patterns\n"));
5892
+ const existingResult = await store.listSolutions({ limit: 1e3 });
5893
+ const existingNames = (existingResult.data || []).map((s) => s.name.toLowerCase());
5894
+ const opportunities = [];
5895
+ const patterns = [
5896
+ { path: "src/auth", name: "Authentication Module", category: "auth", desc: "Authentication implementation" },
5897
+ { path: "src/lib/auth", name: "Auth Library", category: "auth", desc: "Authentication utilities" },
5898
+ { path: "src/api", name: "API Layer", category: "api", desc: "API routing structure" },
5899
+ { path: "app/api", name: "Next.js API Routes", category: "api", desc: "Next.js API implementation" },
5900
+ { path: "src/db", name: "Database Layer", category: "database", desc: "Database connection and queries" },
5901
+ { path: "src/lib/db", name: "Database Utilities", category: "database", desc: "Database helper functions" },
5902
+ { path: "src/components/ui", name: "UI Components", category: "ui", desc: "Reusable UI components" },
5903
+ { path: "src/hooks", name: "Custom Hooks", category: "ui", desc: "React custom hooks" },
5904
+ { path: "__tests__", name: "Testing Setup", category: "testing", desc: "Test configuration and utilities" },
5905
+ { path: ".github/workflows", name: "CI/CD Pipeline", category: "deployment", desc: "GitHub Actions workflows" },
5906
+ { path: "src/integrations", name: "Integrations", category: "integrations", desc: "Third-party integrations" },
5907
+ { path: "src/middleware", name: "Middleware", category: "security", desc: "Request middleware and guards" }
5908
+ ];
5909
+ for (const pattern of patterns) {
5910
+ const fullPath = pathModule.default.join(cwd, pattern.path);
5911
+ if (fs3.existsSync(fullPath) && !existingNames.includes(pattern.name.toLowerCase())) {
5912
+ opportunities.push({
5913
+ name: pattern.name,
5914
+ category: pattern.category,
5915
+ description: pattern.desc,
5916
+ path: pattern.path
5917
+ });
5918
+ }
5919
+ }
5920
+ if (opportunities.length === 0) {
5921
+ console.log(chalk18.green(" \u2713 No new solution opportunities found"));
5922
+ console.log(chalk18.dim("\n Your solutions seem well-captured!"));
5923
+ return;
5924
+ }
5925
+ console.log(chalk18.bold(` Found ${opportunities.length} potential solutions:
5926
+ `));
5927
+ for (const opp of opportunities) {
5928
+ console.log(` ${formatCategory(opp.category)}`);
5929
+ console.log(chalk18.bold(` ${opp.name}`));
5930
+ console.log(chalk18.dim(` ${opp.description}`));
5931
+ console.log(chalk18.dim(` Path: ${opp.path}
5932
+ `));
5933
+ }
5934
+ console.log(chalk18.dim(" To capture a solution:"));
5935
+ console.log(chalk18.cyan(" workflow solution capture --path <path> --name <name>"));
5936
+ }
5837
5937
 
5838
5938
  // src/cli/commands/solution/index.ts
5839
5939
  function createSolutionCommand() {
5840
- const solutionCmd = new Command3("solution").description("Manage solution patterns for code reuse").addHelpText(
5940
+ const solutionCmd = new Command4("solution").description("Manage solution patterns for code reuse").addHelpText(
5841
5941
  "after",
5842
5942
  `
5843
5943
  ${chalk19.bold("Examples:")}
5844
- $ workflow solution capture ${chalk19.dim("# Interactive solution capture")}
5845
- $ workflow solution capture --path ./src/auth ${chalk19.dim("# Capture from specific path")}
5944
+ $ workflow solution capture --path ./src/auth ${chalk19.dim("# Capture from path")}
5945
+ $ workflow solution create --name "My Auth" ${chalk19.dim("# Create manually")}
5946
+ $ workflow solution show abc123 ${chalk19.dim("# Show solution details")}
5846
5947
  $ workflow solution search "jwt auth" ${chalk19.dim("# Search solutions")}
5847
5948
  $ workflow solution list ${chalk19.dim("# List all solutions")}
5848
5949
  $ workflow solution list --category auth ${chalk19.dim("# List by category")}
5849
5950
  $ workflow solution apply abc123 ${chalk19.dim("# Apply a solution")}
5850
5951
  $ workflow solution apply abc123 --dry-run ${chalk19.dim("# Preview application")}
5952
+ $ workflow solution export --format json ${chalk19.dim("# Export solutions")}
5953
+ $ workflow solution import solutions.json ${chalk19.dim("# Import solutions")}
5954
+ $ workflow solution analyze ${chalk19.dim("# Find opportunities")}
5851
5955
  $ workflow solution stats ${chalk19.dim("# Show statistics")}
5852
5956
  `
5853
5957
  ).action(() => {
@@ -5867,7 +5971,22 @@ ${chalk19.bold("Examples:")}
5867
5971
  $ workflow solution capture --anonymize ${chalk19.dim("# Anonymize secrets")}
5868
5972
  $ workflow solution capture --private ${chalk19.dim("# Keep private")}
5869
5973
  `
5870
- ).action(solutionCaptureCommand);
5974
+ ).action(solutionCaptureCommand);
5975
+ solutionCmd.command("create").description("Create a new solution pattern manually").option("--name <name>", "Solution name").option("--description <desc>", "Solution description").option("--category <cat>", "Category").option("--keywords <kw>", "Comma-separated keywords").option("--framework <fw>", "Target framework").addHelpText(
5976
+ "after",
5977
+ `
5978
+ ${chalk19.bold("Examples:")}
5979
+ $ workflow solution create ${chalk19.dim("# Interactive mode")}
5980
+ $ workflow solution create --name "Custom Auth" ${chalk19.dim("# With name")}
5981
+ `
5982
+ ).action(solutionCreateCommand);
5983
+ solutionCmd.command("show <solutionId>").description("Display details of a specific solution pattern").addHelpText(
5984
+ "after",
5985
+ `
5986
+ ${chalk19.bold("Examples:")}
5987
+ $ workflow solution show abc123 ${chalk19.dim("# Show by ID")}
5988
+ `
5989
+ ).action(solutionShowCommand);
5871
5990
  solutionCmd.command("search <query>").description("Search for solution patterns").option("--category <cat>", "Filter by category").option("--framework <fw>", "Filter by framework").option("--limit <n>", "Maximum results", "10").addHelpText(
5872
5991
  "after",
5873
5992
  `
@@ -5898,6 +6017,36 @@ ${chalk19.bold("Examples:")}
5898
6017
  $ workflow solution apply abc123 --include-tests ${chalk19.dim("# Include test files")}
5899
6018
  `
5900
6019
  ).action(solutionApplyCommand);
6020
+ solutionCmd.command("export").description("Export solution patterns to a file").option("-o, --output <path>", "Output file path", "solutions-export.json").option("-f, --format <format>", "Output format (json, yaml)", "json").option("--category <cat>", "Filter by category").addHelpText(
6021
+ "after",
6022
+ `
6023
+ ${chalk19.bold("Examples:")}
6024
+ $ workflow solution export ${chalk19.dim("# Export all as JSON")}
6025
+ $ workflow solution export --format yaml ${chalk19.dim("# Export as YAML")}
6026
+ $ workflow solution export --category auth ${chalk19.dim("# Export auth only")}
6027
+ $ workflow solution export -o backup.json ${chalk19.dim("# Custom output path")}
6028
+ `
6029
+ ).action(solutionExportCommand);
6030
+ solutionCmd.command("import <file>").description("Import solution patterns from a file").option("-f, --format <format>", "Input format (json, yaml)", "json").option("--dry-run", "Preview import without making changes").option("--no-merge", "Skip existing solutions instead of merging").addHelpText(
6031
+ "after",
6032
+ `
6033
+ ${chalk19.bold("Examples:")}
6034
+ $ workflow solution import solutions.json ${chalk19.dim("# Import from JSON")}
6035
+ $ workflow solution import backup.json --dry-run ${chalk19.dim("# Preview import")}
6036
+ `
6037
+ ).action(solutionImportCommand);
6038
+ solutionCmd.command("analyze").description("Analyze codebase for potential solution patterns").addHelpText(
6039
+ "after",
6040
+ `
6041
+ ${chalk19.bold("Details:")}
6042
+ Scans your codebase for common patterns that could be
6043
+ captured as reusable solutions, such as:
6044
+ - Authentication modules
6045
+ - API layers
6046
+ - Database utilities
6047
+ - UI component libraries
6048
+ `
6049
+ ).action(solutionAnalyzeCommand);
5901
6050
  solutionCmd.command("deprecate <solutionId> <reason>").description("Deprecate a solution pattern").addHelpText(
5902
6051
  "after",
5903
6052
  `
@@ -5917,7 +6066,7 @@ ${chalk19.bold("Examples:")}
5917
6066
  }
5918
6067
 
5919
6068
  // src/cli/commands/learn/index.ts
5920
- import { Command as Command4 } from "commander";
6069
+ import { Command as Command5 } from "commander";
5921
6070
  import chalk21 from "chalk";
5922
6071
 
5923
6072
  // src/cli/commands/learn.ts
@@ -5926,10 +6075,10 @@ import * as p12 from "@clack/prompts";
5926
6075
  import * as fs2 from "fs";
5927
6076
  import * as path3 from "path";
5928
6077
  import {
5929
- PatternStore as PatternStore3,
5930
- ContributorManager as ContributorManager2,
6078
+ PatternStore as PatternStore2,
6079
+ ContributorManager,
5931
6080
  PatternAnonymizer,
5932
- TelemetryCollector as TelemetryCollector2,
6081
+ TelemetryCollector,
5933
6082
  FixPatternSchema,
5934
6083
  BlueprintSchema,
5935
6084
  SolutionPatternSchema
@@ -5949,7 +6098,8 @@ function formatTags(tags) {
5949
6098
  }
5950
6099
  async function learnRecordCommand(options) {
5951
6100
  const cwd = getWorkspacePath2();
5952
- const store = new PatternStore3(cwd);
6101
+ const store = new PatternStore2(cwd);
6102
+ await store.initialize();
5953
6103
  console.log(chalk20.cyan("\n\u{1F4DA} Record a Learning Pattern\n"));
5954
6104
  let patternType = options.type;
5955
6105
  if (!patternType) {
@@ -6182,7 +6332,8 @@ async function learnRecordCommand(options) {
6182
6332
  }
6183
6333
  async function learnListCommand(options) {
6184
6334
  const cwd = getWorkspacePath2();
6185
- const store = new PatternStore3(cwd);
6335
+ const store = new PatternStore2(cwd);
6336
+ await store.initialize();
6186
6337
  const patternType = options.type ?? "all";
6187
6338
  const showDeprecated = options.deprecated ?? false;
6188
6339
  console.log(chalk20.cyan("\n\u{1F4DA} Recorded Learning Patterns\n"));
@@ -6314,8 +6465,9 @@ async function learnListCommand(options) {
6314
6465
  }
6315
6466
  async function learnApplyCommand(patternId, options) {
6316
6467
  const cwd = getWorkspacePath2();
6317
- const store = new PatternStore3(cwd);
6318
- const telemetry = new TelemetryCollector2(cwd);
6468
+ const store = new PatternStore2(cwd);
6469
+ await store.initialize();
6470
+ const telemetry = new TelemetryCollector(cwd);
6319
6471
  console.log(chalk20.cyan("\n\u{1F527} Apply Learning Pattern\n"));
6320
6472
  let pattern = await store.getFixPattern(patternId);
6321
6473
  let patternType = "fix";
@@ -6402,7 +6554,7 @@ async function learnApplyCommand(patternId, options) {
6402
6554
  }
6403
6555
  async function learnConfigCommand(options) {
6404
6556
  const cwd = getWorkspacePath2();
6405
- const contributorManager = new ContributorManager2(cwd);
6557
+ const contributorManager = new ContributorManager(cwd);
6406
6558
  console.log(chalk20.cyan("\n\u2699\uFE0F Learning Configuration\n"));
6407
6559
  if (options.enableSync) {
6408
6560
  const result = await contributorManager.enableSync();
@@ -6496,7 +6648,8 @@ async function learnConfigCommand(options) {
6496
6648
  }
6497
6649
  async function learnPublishCommand(patternId, options) {
6498
6650
  const cwd = getWorkspacePath2();
6499
- const store = new PatternStore3(cwd);
6651
+ const store = new PatternStore2(cwd);
6652
+ await store.initialize();
6500
6653
  const makePrivate = options.private ?? false;
6501
6654
  const actionWord = makePrivate ? "private" : "public";
6502
6655
  const emoji = makePrivate ? "\u{1F512}" : "\u{1F310}";
@@ -6645,7 +6798,8 @@ ${emoji} Mark Pattern(s) ${actionWord}
6645
6798
  }
6646
6799
  async function learnDeprecateCommand(patternId, reason) {
6647
6800
  const cwd = getWorkspacePath2();
6648
- const store = new PatternStore3(cwd);
6801
+ const store = new PatternStore2(cwd);
6802
+ await store.initialize();
6649
6803
  console.log(chalk20.cyan("\n\u26A0\uFE0F Deprecate Pattern\n"));
6650
6804
  let patternType = "fix";
6651
6805
  let pattern = await store.getFixPattern(patternId);
@@ -6681,8 +6835,9 @@ async function learnDeprecateCommand(patternId, reason) {
6681
6835
  }
6682
6836
  async function learnStatsCommand() {
6683
6837
  const cwd = getWorkspacePath2();
6684
- const store = new PatternStore3(cwd);
6685
- const telemetry = new TelemetryCollector2(cwd);
6838
+ const store = new PatternStore2(cwd);
6839
+ await store.initialize();
6840
+ const telemetry = new TelemetryCollector(cwd);
6686
6841
  console.log(chalk20.cyan("\n\u{1F4CA} Learning Statistics\n"));
6687
6842
  const storeStats = await store.getStats();
6688
6843
  const totalPatterns = storeStats.totalFixes + storeStats.totalBlueprints;
@@ -7195,7 +7350,8 @@ function inferTagsFromContent(filePaths) {
7195
7350
  }
7196
7351
  async function learnCaptureCommand(paths, options) {
7197
7352
  const cwd = getWorkspacePath2();
7198
- const store = new PatternStore3(cwd);
7353
+ const store = new PatternStore2(cwd);
7354
+ await store.initialize();
7199
7355
  console.log(chalk20.cyan("\n\u{1F4F8} Capture Files as Blueprint\n"));
7200
7356
  const resolvedPaths = [];
7201
7357
  const relativePaths = [];
@@ -7345,7 +7501,7 @@ async function learnCaptureCommand(paths, options) {
7345
7501
  }
7346
7502
  const primaryLanguage = Object.entries(languageCounts).sort((a, b) => b[1] - a[1])[0]?.[0] || "typescript";
7347
7503
  const now = (/* @__PURE__ */ new Date()).toISOString();
7348
- const contributorManager = new ContributorManager2(cwd);
7504
+ const contributorManager = new ContributorManager(cwd);
7349
7505
  const contributorResult = await contributorManager.getOrCreateId();
7350
7506
  const contributorId = contributorResult.success && contributorResult.data ? contributorResult.data : void 0;
7351
7507
  const keyFiles = files.map((f) => ({
@@ -7439,10 +7595,340 @@ function getAllFilesInDir(dirPath) {
7439
7595
  }
7440
7596
  return files;
7441
7597
  }
7598
+ async function learnAnalyzeCommand(options) {
7599
+ const cwd = getWorkspacePath2();
7600
+ const store = new PatternStore2(cwd);
7601
+ await store.initialize();
7602
+ const verbose = options.verbose ?? false;
7603
+ console.log(chalk20.cyan("\n\u{1F50D} Analyzing Codebase for Learning Opportunities\n"));
7604
+ const fixResult = await store.listFixPatterns({});
7605
+ const bpResult = await store.listBlueprints({});
7606
+ const existingPatterns = [
7607
+ ...(fixResult.data || []).map((p13) => p13.name.toLowerCase()),
7608
+ ...(bpResult.data || []).map((p13) => p13.name.toLowerCase())
7609
+ ];
7610
+ const opportunities = [];
7611
+ const authPaths = ["src/auth", "src/lib/auth", "lib/auth", "app/api/auth"];
7612
+ for (const authPath of authPaths) {
7613
+ if (fs2.existsSync(path3.join(cwd, authPath))) {
7614
+ if (!existingPatterns.some((p13) => p13.includes("auth"))) {
7615
+ opportunities.push({
7616
+ type: "blueprint",
7617
+ name: "Authentication Module",
7618
+ description: "Capture your authentication implementation as a reusable pattern",
7619
+ path: authPath
7620
+ });
7621
+ }
7622
+ }
7623
+ }
7624
+ const apiPaths = ["src/api", "app/api", "pages/api", "src/routes"];
7625
+ for (const apiPath of apiPaths) {
7626
+ if (fs2.existsSync(path3.join(cwd, apiPath))) {
7627
+ if (!existingPatterns.some((p13) => p13.includes("api"))) {
7628
+ opportunities.push({
7629
+ type: "blueprint",
7630
+ name: "API Structure",
7631
+ description: "Capture your API routing structure as a blueprint",
7632
+ path: apiPath
7633
+ });
7634
+ }
7635
+ }
7636
+ }
7637
+ const componentPaths = ["src/components", "components", "src/ui"];
7638
+ for (const compPath of componentPaths) {
7639
+ if (fs2.existsSync(path3.join(cwd, compPath))) {
7640
+ if (!existingPatterns.some((p13) => p13.includes("component"))) {
7641
+ opportunities.push({
7642
+ type: "blueprint",
7643
+ name: "Component Library",
7644
+ description: "Capture your component structure as a reusable pattern",
7645
+ path: compPath
7646
+ });
7647
+ }
7648
+ }
7649
+ }
7650
+ const testPaths = ["__tests__", "test", "tests", "src/__tests__"];
7651
+ for (const testPath of testPaths) {
7652
+ if (fs2.existsSync(path3.join(cwd, testPath))) {
7653
+ if (!existingPatterns.some((p13) => p13.includes("test"))) {
7654
+ opportunities.push({
7655
+ type: "blueprint",
7656
+ name: "Testing Structure",
7657
+ description: "Capture your testing setup as a blueprint",
7658
+ path: testPath
7659
+ });
7660
+ }
7661
+ }
7662
+ }
7663
+ if (opportunities.length === 0) {
7664
+ console.log(chalk20.green(" \u2713 No new learning opportunities identified"));
7665
+ console.log(chalk20.dim("\n Your patterns seem well-captured!"));
7666
+ return;
7667
+ }
7668
+ console.log(chalk20.bold(` Found ${opportunities.length} potential learning opportunities:
7669
+ `));
7670
+ for (const opp of opportunities) {
7671
+ const icon = opp.type === "blueprint" ? "\u{1F4D0}" : "\u{1F527}";
7672
+ console.log(` ${icon} ${chalk20.green(opp.name)}`);
7673
+ console.log(chalk20.dim(` ${opp.description}`));
7674
+ if (opp.path && verbose) {
7675
+ console.log(chalk20.dim(` Path: ${opp.path}`));
7676
+ }
7677
+ console.log("");
7678
+ }
7679
+ console.log(chalk20.dim(" To capture a pattern:"));
7680
+ console.log(chalk20.cyan(" workflow learn capture <path> --name <name>"));
7681
+ }
7682
+ async function learnExportCommand(options) {
7683
+ const cwd = getWorkspacePath2();
7684
+ const store = new PatternStore2(cwd);
7685
+ await store.initialize();
7686
+ const format = options.format ?? "json";
7687
+ const patternType = options.type ?? "all";
7688
+ const outputPath = options.output ?? `patterns-export.${format}`;
7689
+ console.log(chalk20.cyan("\n\u{1F4E4} Exporting Learning Patterns\n"));
7690
+ const exportData = {
7691
+ fixes: [],
7692
+ blueprints: []
7693
+ };
7694
+ if (patternType === "all" || patternType === "fix") {
7695
+ const fixResult = await store.listFixPatterns({});
7696
+ if (fixResult.success && fixResult.data) {
7697
+ exportData.fixes = fixResult.data;
7698
+ }
7699
+ }
7700
+ if (patternType === "all" || patternType === "blueprint") {
7701
+ const bpResult = await store.listBlueprints({});
7702
+ if (bpResult.success && bpResult.data) {
7703
+ exportData.blueprints = bpResult.data;
7704
+ }
7705
+ }
7706
+ const totalCount = exportData.fixes.length + exportData.blueprints.length;
7707
+ if (totalCount === 0) {
7708
+ console.log(chalk20.yellow(" No patterns to export"));
7709
+ return;
7710
+ }
7711
+ let output;
7712
+ if (format === "yaml") {
7713
+ output = `# Workflow Agent Patterns Export
7714
+ # Exported: ${(/* @__PURE__ */ new Date()).toISOString()}
7715
+
7716
+ `;
7717
+ output += `fixes:
7718
+ `;
7719
+ for (const fix of exportData.fixes) {
7720
+ output += ` - id: ${fix.id}
7721
+ `;
7722
+ output += ` name: "${fix.name}"
7723
+ `;
7724
+ output += ` category: ${fix.category}
7725
+ `;
7726
+ output += ` description: "${fix.description}"
7727
+
7728
+ `;
7729
+ }
7730
+ output += `blueprints:
7731
+ `;
7732
+ for (const bp of exportData.blueprints) {
7733
+ output += ` - id: ${bp.id}
7734
+ `;
7735
+ output += ` name: "${bp.name}"
7736
+ `;
7737
+ output += ` description: "${bp.description}"
7738
+
7739
+ `;
7740
+ }
7741
+ } else {
7742
+ output = JSON.stringify(
7743
+ {
7744
+ version: "1.0",
7745
+ exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
7746
+ ...exportData
7747
+ },
7748
+ null,
7749
+ 2
7750
+ );
7751
+ }
7752
+ const fullOutputPath = path3.isAbsolute(outputPath) ? outputPath : path3.join(cwd, outputPath);
7753
+ await fs2.promises.writeFile(fullOutputPath, output, "utf-8");
7754
+ console.log(chalk20.green(` \u2713 Exported ${totalCount} patterns
7755
+ `));
7756
+ console.log(chalk20.dim(` Fix patterns: ${exportData.fixes.length}`));
7757
+ console.log(chalk20.dim(` Blueprints: ${exportData.blueprints.length}`));
7758
+ console.log(chalk20.dim(` Output: ${fullOutputPath}`));
7759
+ console.log(chalk20.dim(` Format: ${format.toUpperCase()}`));
7760
+ }
7761
+ async function learnImportCommand(file, options) {
7762
+ const cwd = getWorkspacePath2();
7763
+ const store = new PatternStore2(cwd);
7764
+ await store.initialize();
7765
+ const dryRun = options.dryRun ?? false;
7766
+ const merge = options.merge ?? true;
7767
+ console.log(chalk20.cyan("\n\u{1F4E5} Importing Learning Patterns\n"));
7768
+ const filePath = path3.isAbsolute(file) ? file : path3.join(cwd, file);
7769
+ if (!fs2.existsSync(filePath)) {
7770
+ console.log(chalk20.red(` \u2717 File not found: ${filePath}`));
7771
+ process.exit(1);
7772
+ }
7773
+ const content = await fs2.promises.readFile(filePath, "utf-8");
7774
+ let importData;
7775
+ try {
7776
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
7777
+ console.log(chalk20.yellow(" YAML import not fully supported, treating as JSON"));
7778
+ }
7779
+ importData = JSON.parse(content);
7780
+ } catch {
7781
+ console.log(chalk20.red(" \u2717 Failed to parse import file"));
7782
+ process.exit(1);
7783
+ }
7784
+ const fixes = importData.fixes || [];
7785
+ const blueprints = importData.blueprints || [];
7786
+ const totalCount = fixes.length + blueprints.length;
7787
+ if (totalCount === 0) {
7788
+ console.log(chalk20.yellow(" No patterns found in import file"));
7789
+ return;
7790
+ }
7791
+ console.log(chalk20.dim(` Found ${fixes.length} fix patterns`));
7792
+ console.log(chalk20.dim(` Found ${blueprints.length} blueprints
7793
+ `));
7794
+ if (dryRun) {
7795
+ console.log(chalk20.yellow(" \u{1F50D} Dry run - no changes will be made\n"));
7796
+ for (const fix of fixes) {
7797
+ console.log(chalk20.dim(` Would import fix: ${fix.name} (${fix.id})`));
7798
+ }
7799
+ for (const bp of blueprints) {
7800
+ console.log(chalk20.dim(` Would import blueprint: ${bp.name} (${bp.id})`));
7801
+ }
7802
+ return;
7803
+ }
7804
+ let imported = 0;
7805
+ let skipped = 0;
7806
+ for (const fix of fixes) {
7807
+ const existing = await store.getFixPattern(fix.id);
7808
+ if (existing.success && existing.data && !merge) {
7809
+ console.log(chalk20.yellow(` Skipped (exists): ${fix.name}`));
7810
+ skipped++;
7811
+ continue;
7812
+ }
7813
+ const result = await store.saveFixPattern(fix);
7814
+ if (result.success) {
7815
+ console.log(chalk20.green(` \u2713 Imported: ${fix.name}`));
7816
+ imported++;
7817
+ } else {
7818
+ console.log(chalk20.red(` \u2717 Failed: ${fix.name}`));
7819
+ }
7820
+ }
7821
+ for (const bp of blueprints) {
7822
+ const existing = await store.getBlueprint(bp.id);
7823
+ if (existing.success && existing.data && !merge) {
7824
+ console.log(chalk20.yellow(` Skipped (exists): ${bp.name}`));
7825
+ skipped++;
7826
+ continue;
7827
+ }
7828
+ const result = await store.saveBlueprint(bp);
7829
+ if (result.success) {
7830
+ console.log(chalk20.green(` \u2713 Imported: ${bp.name}`));
7831
+ imported++;
7832
+ } else {
7833
+ console.log(chalk20.red(` \u2717 Failed: ${bp.name}`));
7834
+ }
7835
+ }
7836
+ console.log(chalk20.green(`
7837
+ \u2713 Import complete`));
7838
+ console.log(chalk20.dim(` Imported: ${imported}`));
7839
+ console.log(chalk20.dim(` Skipped: ${skipped}`));
7840
+ }
7841
+ async function learnCleanCommand(options) {
7842
+ const cwd = getWorkspacePath2();
7843
+ const store = new PatternStore2(cwd);
7844
+ await store.initialize();
7845
+ const dryRun = options.dryRun ?? false;
7846
+ const cleanDeprecated = options.deprecated ?? false;
7847
+ const cleanStale = options.stale ?? false;
7848
+ const cleanAll = options.all ?? false;
7849
+ console.log(chalk20.cyan("\n\u{1F9F9} Cleaning Learning Patterns\n"));
7850
+ if (!cleanDeprecated && !cleanStale && !cleanAll) {
7851
+ console.log(chalk20.yellow(" Specify what to clean:"));
7852
+ console.log(chalk20.dim(" --deprecated Remove deprecated patterns"));
7853
+ console.log(chalk20.dim(" --stale Remove patterns not used in 90+ days"));
7854
+ console.log(chalk20.dim(" --all Remove all patterns (use with caution!)"));
7855
+ return;
7856
+ }
7857
+ const toRemove = [];
7858
+ const fixResult = await store.listFixPatterns({ includeDeprecated: true });
7859
+ const bpResult = await store.listBlueprints({ includeDeprecated: true });
7860
+ const fixes = fixResult.data || [];
7861
+ const blueprints = bpResult.data || [];
7862
+ const now = Date.now();
7863
+ const staleDays = 90;
7864
+ const staleThreshold = now - staleDays * 24 * 60 * 60 * 1e3;
7865
+ for (const fix of fixes) {
7866
+ if (cleanAll) {
7867
+ toRemove.push({ id: fix.id, name: fix.name, type: "fix", reason: "all" });
7868
+ } else if (cleanDeprecated && fix.deprecatedAt) {
7869
+ toRemove.push({ id: fix.id, name: fix.name, type: "fix", reason: "deprecated" });
7870
+ } else if (cleanStale) {
7871
+ const lastUsed = new Date(fix.updatedAt).getTime();
7872
+ if (lastUsed < staleThreshold) {
7873
+ toRemove.push({ id: fix.id, name: fix.name, type: "fix", reason: "stale" });
7874
+ }
7875
+ }
7876
+ }
7877
+ for (const bp of blueprints) {
7878
+ if (cleanAll) {
7879
+ toRemove.push({ id: bp.id, name: bp.name, type: "blueprint", reason: "all" });
7880
+ } else if (cleanDeprecated && bp.deprecatedAt) {
7881
+ toRemove.push({ id: bp.id, name: bp.name, type: "blueprint", reason: "deprecated" });
7882
+ } else if (cleanStale) {
7883
+ const lastUsed = new Date(bp.updatedAt).getTime();
7884
+ if (lastUsed < staleThreshold) {
7885
+ toRemove.push({ id: bp.id, name: bp.name, type: "blueprint", reason: "stale" });
7886
+ }
7887
+ }
7888
+ }
7889
+ if (toRemove.length === 0) {
7890
+ console.log(chalk20.green(" \u2713 Nothing to clean"));
7891
+ return;
7892
+ }
7893
+ console.log(chalk20.bold(` Found ${toRemove.length} patterns to remove:
7894
+ `));
7895
+ for (const item of toRemove) {
7896
+ const icon = item.type === "fix" ? "\u{1F527}" : "\u{1F4D0}";
7897
+ console.log(` ${icon} ${item.name} (${item.reason})`);
7898
+ }
7899
+ if (dryRun) {
7900
+ console.log(chalk20.yellow("\n \u{1F50D} Dry run - no changes made"));
7901
+ return;
7902
+ }
7903
+ const confirmed = await p12.confirm({
7904
+ message: `Remove ${toRemove.length} patterns? This cannot be undone.`,
7905
+ initialValue: false
7906
+ });
7907
+ if (p12.isCancel(confirmed) || !confirmed) {
7908
+ p12.cancel("Clean cancelled");
7909
+ return;
7910
+ }
7911
+ let removed = 0;
7912
+ const patternsPath = path3.join(cwd, ".workflow", "patterns");
7913
+ for (const item of toRemove) {
7914
+ const dir = item.type === "fix" ? "fixes" : "blueprints";
7915
+ const filePath = path3.join(patternsPath, dir, `${item.id}.json`);
7916
+ try {
7917
+ if (fs2.existsSync(filePath)) {
7918
+ await fs2.promises.unlink(filePath);
7919
+ removed++;
7920
+ }
7921
+ } catch {
7922
+ console.log(chalk20.red(` \u2717 Failed to remove: ${item.name}`));
7923
+ }
7924
+ }
7925
+ console.log(chalk20.green(`
7926
+ \u2713 Removed ${removed} patterns`));
7927
+ }
7442
7928
 
7443
7929
  // src/cli/commands/learn/index.ts
7444
7930
  function createLearnCommand() {
7445
- const learnCmd = new Command4("learn").description("Manage learning patterns for AI-assisted development").addHelpText(
7931
+ const learnCmd = new Command5("learn").description("Manage learning patterns for AI-assisted development").addHelpText(
7446
7932
  "after",
7447
7933
  `
7448
7934
  ${chalk21.bold("Examples:")}
@@ -7450,9 +7936,13 @@ ${chalk21.bold("Examples:")}
7450
7936
  $ workflow learn list --type blueprint ${chalk21.dim("# List blueprints only")}
7451
7937
  $ workflow learn apply abc123 --dry-run ${chalk21.dim("# Preview pattern application")}
7452
7938
  $ workflow learn capture ./src/auth --name auth ${chalk21.dim("# Capture as blueprint")}
7939
+ $ workflow learn analyze ${chalk21.dim("# Find learning opportunities")}
7940
+ $ workflow learn export --format json ${chalk21.dim("# Export patterns")}
7941
+ $ workflow learn import patterns.json ${chalk21.dim("# Import patterns")}
7453
7942
  $ workflow learn sync --push ${chalk21.dim("# Push patterns to registry")}
7454
7943
  $ workflow learn config --show ${chalk21.dim("# Show current configuration")}
7455
7944
  $ workflow learn stats ${chalk21.dim("# Show learning statistics")}
7945
+ $ workflow learn clean --deprecated ${chalk21.dim("# Clean deprecated patterns")}
7456
7946
  $ workflow learn validate --fix ${chalk21.dim("# Auto-fix pattern issues")}
7457
7947
  `
7458
7948
  ).action(() => {
@@ -7550,6 +8040,42 @@ ${chalk21.bold("Examples:")}
7550
8040
  $ workflow learn stats ${chalk21.dim("# Show all statistics")}
7551
8041
  `
7552
8042
  ).action(learnStatsCommand);
8043
+ learnCmd.command("analyze").description("Analyze codebase for learning opportunities").option("-v, --verbose", "Show detailed output including paths").addHelpText(
8044
+ "after",
8045
+ `
8046
+ ${chalk21.bold("Examples:")}
8047
+ $ workflow learn analyze ${chalk21.dim("# Find learning opportunities")}
8048
+ $ workflow learn analyze --verbose ${chalk21.dim("# Show paths and details")}
8049
+ `
8050
+ ).action(learnAnalyzeCommand);
8051
+ learnCmd.command("export").description("Export learning patterns to a file").option("-o, --output <path>", "Output file path", "patterns-export.json").option("-f, --format <format>", "Output format (json, yaml)", "json").option("-t, --type <type>", "Pattern type to export (fix, blueprint, all)", "all").addHelpText(
8052
+ "after",
8053
+ `
8054
+ ${chalk21.bold("Examples:")}
8055
+ $ workflow learn export ${chalk21.dim("# Export all as JSON")}
8056
+ $ workflow learn export --format yaml ${chalk21.dim("# Export as YAML")}
8057
+ $ workflow learn export --type fix ${chalk21.dim("# Export only fixes")}
8058
+ $ workflow learn export -o backup.json ${chalk21.dim("# Custom output path")}
8059
+ `
8060
+ ).action(learnExportCommand);
8061
+ learnCmd.command("import <file>").description("Import learning patterns from a file").option("-f, --format <format>", "Input format (json, yaml)", "json").option("--dry-run", "Preview import without making changes").option("--no-merge", "Skip existing patterns instead of merging").addHelpText(
8062
+ "after",
8063
+ `
8064
+ ${chalk21.bold("Examples:")}
8065
+ $ workflow learn import patterns.json ${chalk21.dim("# Import from JSON")}
8066
+ $ workflow learn import backup.json --dry-run ${chalk21.dim("# Preview import")}
8067
+ $ workflow learn import patterns.yaml --format yaml ${chalk21.dim("# Import from YAML")}
8068
+ `
8069
+ ).action(learnImportCommand);
8070
+ learnCmd.command("clean").description("Clean old or stale learning patterns").option("--deprecated", "Remove deprecated patterns").option("--stale", "Remove patterns not used in 90+ days").option("--all", "Remove all patterns (use with caution!)").option("--dry-run", "Preview what would be removed").addHelpText(
8071
+ "after",
8072
+ `
8073
+ ${chalk21.bold("Examples:")}
8074
+ $ workflow learn clean --deprecated ${chalk21.dim("# Remove deprecated")}
8075
+ $ workflow learn clean --stale ${chalk21.dim("# Remove stale patterns")}
8076
+ $ workflow learn clean --all --dry-run ${chalk21.dim("# Preview full clean")}
8077
+ `
8078
+ ).action(learnCleanCommand);
7553
8079
  learnCmd.command("validate").description("Validate pattern files and optionally auto-fix common issues").option("-t, --type <type>", "Pattern type to validate (fix, blueprint, solution, all)", "all").option("-f, --file <path>", "Validate a specific file by path").option("--fix", "Automatically fix common issues").option("-v, --verbose", "Show detailed validation output").addHelpText(
7554
8080
  "after",
7555
8081
  `
@@ -7565,19 +8091,250 @@ ${chalk21.bold("Examples:")}
7565
8091
  }
7566
8092
 
7567
8093
  // src/cli/commands/scope/index.ts
7568
- import { Command as Command5 } from "commander";
8094
+ import { Command as Command6 } from "commander";
7569
8095
  import chalk22 from "chalk";
8096
+ async function scopeListCommand() {
8097
+ console.log(chalk22.bold.cyan("\n\u{1F4CB} Available Scopes\n"));
8098
+ const config = await loadConfig();
8099
+ const scopes = config?.scopes || [];
8100
+ if (scopes.length === 0) {
8101
+ console.log(chalk22.yellow(" No scopes configured."));
8102
+ console.log(chalk22.dim("\n Add scopes with: workflow scope add <name>"));
8103
+ console.log(chalk22.dim(" Or create a custom scope: workflow scope create"));
8104
+ return;
8105
+ }
8106
+ const byCategory = {};
8107
+ for (const scope of scopes) {
8108
+ const cat = scope.category || "other";
8109
+ if (!byCategory[cat]) byCategory[cat] = [];
8110
+ byCategory[cat].push(scope);
8111
+ }
8112
+ for (const [category, categoryScopes] of Object.entries(byCategory)) {
8113
+ console.log(chalk22.bold(` ${category.charAt(0).toUpperCase() + category.slice(1)}:`));
8114
+ for (const scope of categoryScopes) {
8115
+ const emoji = scope.emoji || "\u{1F4E6}";
8116
+ console.log(` ${emoji} ${chalk22.green(scope.name)} - ${scope.description || "No description"}`);
8117
+ }
8118
+ console.log("");
8119
+ }
8120
+ console.log(chalk22.dim(` Total: ${scopes.length} scopes`));
8121
+ }
8122
+ async function scopeAddCommand(name, options) {
8123
+ console.log(chalk22.bold.cyan(`
8124
+ \u2795 Adding Scope: ${name}
8125
+ `));
8126
+ const fs3 = await import("fs");
8127
+ const path4 = await import("path");
8128
+ const cwd = process.cwd();
8129
+ const configFiles = ["workflow.config.json", "workflow.config.js", ".workflowrc.json"];
8130
+ let configPath = null;
8131
+ for (const file of configFiles) {
8132
+ const fullPath = path4.join(cwd, file);
8133
+ if (fs3.existsSync(fullPath)) {
8134
+ configPath = fullPath;
8135
+ break;
8136
+ }
8137
+ }
8138
+ if (!configPath) {
8139
+ console.log(chalk22.red("\u2717 No workflow configuration file found"));
8140
+ console.log(chalk22.yellow(" Run: workflow init"));
8141
+ process.exit(1);
8142
+ }
8143
+ const configContent = fs3.readFileSync(configPath, "utf-8");
8144
+ const config = JSON.parse(configContent);
8145
+ if (!config.scopes) {
8146
+ config.scopes = [];
8147
+ }
8148
+ const existing = config.scopes.find((s) => s.name === name);
8149
+ if (existing) {
8150
+ console.log(chalk22.yellow(` Scope "${name}" already exists`));
8151
+ process.exit(1);
8152
+ }
8153
+ const newScope = {
8154
+ name,
8155
+ description: options.description || `${name} related changes`,
8156
+ emoji: options.emoji || "\u{1F4E6}",
8157
+ category: options.category || "feature"
8158
+ };
8159
+ config.scopes.push(newScope);
8160
+ fs3.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
8161
+ console.log(chalk22.green(`\u2713 Added scope: ${newScope.emoji} ${name}`));
8162
+ console.log(chalk22.dim(` Description: ${newScope.description}`));
8163
+ console.log(chalk22.dim(` Category: ${newScope.category}`));
8164
+ }
8165
+ async function scopeRemoveCommand(name) {
8166
+ console.log(chalk22.bold.cyan(`
8167
+ \u2796 Removing Scope: ${name}
8168
+ `));
8169
+ const fs3 = await import("fs");
8170
+ const path4 = await import("path");
8171
+ const cwd = process.cwd();
8172
+ const configFiles = ["workflow.config.json", "workflow.config.js", ".workflowrc.json"];
8173
+ let configPath = null;
8174
+ for (const file of configFiles) {
8175
+ const fullPath = path4.join(cwd, file);
8176
+ if (fs3.existsSync(fullPath)) {
8177
+ configPath = fullPath;
8178
+ break;
8179
+ }
8180
+ }
8181
+ if (!configPath) {
8182
+ console.log(chalk22.red("\u2717 No workflow configuration file found"));
8183
+ process.exit(1);
8184
+ }
8185
+ const configContent = fs3.readFileSync(configPath, "utf-8");
8186
+ const config = JSON.parse(configContent);
8187
+ if (!config.scopes || config.scopes.length === 0) {
8188
+ console.log(chalk22.yellow(" No scopes configured"));
8189
+ process.exit(1);
8190
+ }
8191
+ const index = config.scopes.findIndex((s) => s.name === name);
8192
+ if (index === -1) {
8193
+ console.log(chalk22.yellow(` Scope "${name}" not found`));
8194
+ process.exit(1);
8195
+ }
8196
+ const removed = config.scopes.splice(index, 1)[0];
8197
+ fs3.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
8198
+ console.log(chalk22.green(`\u2713 Removed scope: ${removed.emoji || "\u{1F4E6}"} ${name}`));
8199
+ }
8200
+ async function scopeSyncCommand(options) {
8201
+ console.log(chalk22.bold.cyan("\n\u{1F504} Syncing Scopes\n"));
8202
+ const { syncCommand: syncCommand2 } = await import("../sync-MNHQ6AIQ.js");
8203
+ await syncCommand2({
8204
+ ...options,
8205
+ scopes: true,
8206
+ learn: false,
8207
+ solutions: false
8208
+ });
8209
+ }
8210
+ async function scopeAnalyzeCommand() {
8211
+ console.log(chalk22.bold.cyan("\n\u{1F50D} Analyzing Scope Usage\n"));
8212
+ const { execa: execa2 } = await import("execa");
8213
+ const cwd = process.cwd();
8214
+ try {
8215
+ const { stdout } = await execa2("git", ["log", "--oneline", "-50", "--format=%s"], { cwd });
8216
+ const commits = stdout.split("\n").filter(Boolean);
8217
+ const config = await loadConfig();
8218
+ const scopes = config?.scopes || [];
8219
+ const scopeNames = scopes.map((s) => s.name);
8220
+ const usage = {};
8221
+ let unscoped = 0;
8222
+ let invalidScopes = [];
8223
+ for (const commit of commits) {
8224
+ const match = commit.match(/^\w+\(([^)]+)\):/);
8225
+ if (match) {
8226
+ const scope = match[1];
8227
+ if (scopeNames.includes(scope)) {
8228
+ usage[scope] = (usage[scope] || 0) + 1;
8229
+ } else {
8230
+ if (!invalidScopes.includes(scope)) {
8231
+ invalidScopes.push(scope);
8232
+ }
8233
+ }
8234
+ } else if (commit.match(/^\w+:/)) {
8235
+ unscoped++;
8236
+ }
8237
+ }
8238
+ console.log(chalk22.bold(" Scope Usage (last 50 commits):"));
8239
+ console.log("");
8240
+ const sortedUsage = Object.entries(usage).sort((a, b) => b[1] - a[1]);
8241
+ for (const [scope, count] of sortedUsage) {
8242
+ const scopeConfig = scopes.find((s) => s.name === scope);
8243
+ const emoji = scopeConfig?.emoji || "\u{1F4E6}";
8244
+ const bar = "\u2588".repeat(Math.min(count, 20));
8245
+ console.log(` ${emoji} ${chalk22.green(scope.padEnd(15))} ${bar} ${count}`);
8246
+ }
8247
+ if (unscoped > 0) {
8248
+ console.log(` ${chalk22.yellow("(unscoped)".padEnd(17))} ${"\u2591".repeat(Math.min(unscoped, 20))} ${unscoped}`);
8249
+ }
8250
+ const unusedScopes = scopeNames.filter((name) => !usage[name]);
8251
+ if (unusedScopes.length > 0) {
8252
+ console.log(chalk22.yellow("\n Unused scopes (consider removing):"));
8253
+ for (const name of unusedScopes) {
8254
+ console.log(chalk22.dim(` \u2022 ${name}`));
8255
+ }
8256
+ }
8257
+ if (invalidScopes.length > 0) {
8258
+ console.log(chalk22.yellow("\n Unknown scopes (consider adding):"));
8259
+ for (const name of invalidScopes) {
8260
+ console.log(chalk22.dim(` \u2022 ${name}`));
8261
+ }
8262
+ }
8263
+ console.log("");
8264
+ } catch {
8265
+ console.log(chalk22.yellow(" Unable to analyze git history"));
8266
+ console.log(chalk22.dim(" Make sure you're in a git repository with commit history"));
8267
+ }
8268
+ }
8269
+ async function hooksTestCommand(options) {
8270
+ console.log(chalk22.bold.cyan("\n\u{1F9EA} Testing Git Hooks\n"));
8271
+ const fs3 = await import("fs");
8272
+ const path4 = await import("path");
8273
+ const cwd = process.cwd();
8274
+ const gitDir = path4.join(cwd, ".git");
8275
+ const hooksDir = path4.join(gitDir, "hooks");
8276
+ if (!fs3.existsSync(gitDir)) {
8277
+ console.log(chalk22.red("\u2717 Not a git repository"));
8278
+ process.exit(1);
8279
+ }
8280
+ if (!fs3.existsSync(hooksDir)) {
8281
+ console.log(chalk22.yellow(" No hooks directory found"));
8282
+ console.log(chalk22.dim(" Run: workflow scope hooks install"));
8283
+ process.exit(1);
8284
+ }
8285
+ const hookTypes = ["pre-commit", "commit-msg"];
8286
+ let allInstalled = true;
8287
+ for (const hookType of hookTypes) {
8288
+ const hookPath = path4.join(hooksDir, hookType);
8289
+ const exists = fs3.existsSync(hookPath);
8290
+ const isExecutable = exists && (fs3.statSync(hookPath).mode & 73) !== 0;
8291
+ const isWorkflowHook2 = exists && fs3.readFileSync(hookPath, "utf-8").includes("workflow-agent");
8292
+ if (exists && isExecutable && isWorkflowHook2) {
8293
+ console.log(chalk22.green(` \u2713 ${hookType} - installed and executable`));
8294
+ } else if (exists && !isWorkflowHook2) {
8295
+ console.log(chalk22.yellow(` \u26A0 ${hookType} - exists but not managed by workflow-agent`));
8296
+ allInstalled = false;
8297
+ } else if (exists && !isExecutable) {
8298
+ console.log(chalk22.red(` \u2717 ${hookType} - exists but not executable`));
8299
+ allInstalled = false;
8300
+ } else {
8301
+ console.log(chalk22.red(` \u2717 ${hookType} - not installed`));
8302
+ allInstalled = false;
8303
+ }
8304
+ }
8305
+ if (options.dryRun) {
8306
+ console.log(chalk22.bold.cyan("\n Dry-run hook simulation:\n"));
8307
+ console.log(chalk22.dim(" Simulating pre-commit hook..."));
8308
+ const { verifyCommand: verifyCommand2 } = await import("../verify-2PDVNYWV.js");
8309
+ try {
8310
+ await verifyCommand2({ fix: false, dryRun: true, maxRetries: "1" });
8311
+ } catch {
8312
+ }
8313
+ }
8314
+ if (!allInstalled) {
8315
+ console.log(chalk22.yellow("\n Some hooks are not properly installed"));
8316
+ console.log(chalk22.dim(" Run: workflow scope hooks install"));
8317
+ process.exit(1);
8318
+ }
8319
+ console.log(chalk22.green("\n\u2713 All hooks are properly installed"));
8320
+ }
7570
8321
  function createScopeCommand() {
7571
- const scopeCmd = new Command5("scope").description("Manage custom scope packages").addHelpText(
8322
+ const scopeCmd = new Command6("scope").description("Manage custom scope packages and git hooks").addHelpText(
7572
8323
  "after",
7573
8324
  `
7574
8325
  ${chalk22.bold("Examples:")}
7575
- $ workflow scope create --name fintech ${chalk22.dim("# Create fintech scope package")}
7576
- $ workflow scope migrate --name my-scopes ${chalk22.dim("# Migrate inline to package")}
8326
+ $ workflow scope list ${chalk22.dim("# List available scopes")}
8327
+ $ workflow scope create --name fintech ${chalk22.dim("# Create fintech scope package")}
8328
+ $ workflow scope migrate --name my-scopes ${chalk22.dim("# Migrate inline to package")}
8329
+ $ workflow scope add auth ${chalk22.dim("# Add auth scope")}
8330
+ $ workflow scope remove legacy ${chalk22.dim("# Remove legacy scope")}
8331
+ $ workflow scope analyze ${chalk22.dim("# Analyze scope usage")}
8332
+ $ workflow scope hooks install ${chalk22.dim("# Install git hooks")}
7577
8333
  `
7578
8334
  ).action(() => {
7579
- scopeCmd.help();
8335
+ scopeListCommand();
7580
8336
  });
8337
+ scopeCmd.command("list").description("List available scopes").action(scopeListCommand);
7581
8338
  scopeCmd.command("create").description("Create a custom scope package").option("--name <name>", 'Package name (e.g., "fintech", "gaming")').option(
7582
8339
  "--scopes <scopes>",
7583
8340
  "Comma-separated scopes (format: name:description:emoji:category)"
@@ -7601,6 +8358,57 @@ ${chalk22.bold("Examples:")}
7601
8358
  $ workflow scope migrate --keep-config ${chalk22.dim("# Keep inline copy")}
7602
8359
  `
7603
8360
  ).action(scopeMigrateCommand);
8361
+ scopeCmd.command("add <name>").description("Add a scope to the project configuration").option("--description <desc>", "Scope description").option("--emoji <emoji>", "Scope emoji").option("--category <cat>", "Scope category (feature, fix, core, etc.)").addHelpText(
8362
+ "after",
8363
+ `
8364
+ ${chalk22.bold("Examples:")}
8365
+ $ workflow scope add auth ${chalk22.dim("# Add auth scope")}
8366
+ $ workflow scope add payments --emoji \u{1F4B3} ${chalk22.dim("# With emoji")}
8367
+ $ workflow scope add api --category core ${chalk22.dim("# With category")}
8368
+ `
8369
+ ).action(scopeAddCommand);
8370
+ scopeCmd.command("remove <name>").description("Remove a scope from the project configuration").addHelpText(
8371
+ "after",
8372
+ `
8373
+ ${chalk22.bold("Examples:")}
8374
+ $ workflow scope remove legacy ${chalk22.dim("# Remove scope")}
8375
+ `
8376
+ ).action(scopeRemoveCommand);
8377
+ scopeCmd.command("sync").description("Sync scopes with the community registry").option("--push", "Push local scopes to registry").option("--pull", "Pull scopes from registry").option("--dry-run", "Preview without syncing").addHelpText(
8378
+ "after",
8379
+ `
8380
+ ${chalk22.bold("Examples:")}
8381
+ $ workflow scope sync --push ${chalk22.dim("# Push to registry")}
8382
+ $ workflow scope sync --pull ${chalk22.dim("# Pull from registry")}
8383
+ $ workflow scope sync --dry-run ${chalk22.dim("# Preview changes")}
8384
+ `
8385
+ ).action(scopeSyncCommand);
8386
+ scopeCmd.command("analyze").description("Analyze scope usage in the project").addHelpText(
8387
+ "after",
8388
+ `
8389
+ ${chalk22.bold("Details:")}
8390
+ Analyzes recent git commits to show:
8391
+ - Which scopes are used most frequently
8392
+ - Unused scopes that could be removed
8393
+ - Unknown scopes that could be added
8394
+ `
8395
+ ).action(scopeAnalyzeCommand);
8396
+ const hooksCmd = scopeCmd.command("hooks").description("Manage git hooks for the project").addHelpText(
8397
+ "after",
8398
+ `
8399
+ ${chalk22.bold("Examples:")}
8400
+ $ workflow scope hooks install ${chalk22.dim("# Install git hooks")}
8401
+ $ workflow scope hooks uninstall ${chalk22.dim("# Remove git hooks")}
8402
+ $ workflow scope hooks test ${chalk22.dim("# Verify installation")}
8403
+ $ workflow scope hooks test --dry-run ${chalk22.dim("# Test with simulation")}
8404
+ `
8405
+ ).action(() => {
8406
+ hooksCommand("status");
8407
+ });
8408
+ hooksCmd.command("install").description("Install git hooks for the project").action(() => hooksCommand("install"));
8409
+ hooksCmd.command("uninstall").description("Remove installed git hooks").action(() => hooksCommand("uninstall"));
8410
+ hooksCmd.command("status").description("Show current hooks installation status").action(() => hooksCommand("status"));
8411
+ hooksCmd.command("test").description("Test that hooks are properly installed").option("--dry-run", "Simulate hook execution without making changes").action(hooksTestCommand);
7604
8412
  return scopeCmd;
7605
8413
  }
7606
8414
 
@@ -7610,7 +8418,7 @@ function deprecationWarning(oldCmd, newCmd) {
7610
8418
  console.warn(chalk23.yellow(` Use: ${newCmd}
7611
8419
  `));
7612
8420
  }
7613
- var program = new Command6();
8421
+ var program = new Command7();
7614
8422
  program.name("workflow").description(
7615
8423
  "A self-evolving workflow management system for AI agent development"
7616
8424
  ).version("1.0.0");
@@ -7618,7 +8426,6 @@ program.addCommand(createDocsCommand());
7618
8426
  program.addCommand(createSolutionCommand());
7619
8427
  program.addCommand(createLearnCommand());
7620
8428
  program.addCommand(createScopeCommand());
7621
- program.addCommand(createHooksCommand());
7622
8429
  program.command("sync").description("Sync patterns and solutions with the community registry").option("--push", "Push local patterns to registry").option("--pull", "Pull patterns from registry").option("--solutions", "Include solution patterns").option("--learn", "Include learning patterns (default)").option("--scopes", "Sync custom scope packages").option("--all", "Sync everything").option("--dry-run", "Preview without syncing").addHelpText(
7623
8430
  "after",
7624
8431
  `
@@ -7679,18 +8486,18 @@ program.command("suggest").description("Submit an improvement suggestion").argum
7679
8486
  "--category <category>",
7680
8487
  "Category: feature, bug, documentation, performance, other"
7681
8488
  ).action(suggestCommand);
7682
- program.command("setup").description("Add workflow scripts to package.json").action(setupCommand);
8489
+ program.addCommand(createSetupCommand());
7683
8490
  program.command("doctor").description("Run health check and get optimization suggestions").option("--check-guidelines-only", "Only check guidelines presence").option("--fix", "Automatically fix validation issues in configuration").action(doctorCommand);
7684
- program.command("hooks:install", { hidden: true }).description("[DEPRECATED] Use: workflow hooks install").action(async () => {
7685
- deprecationWarning("workflow hooks:install", "workflow hooks install");
8491
+ program.command("hooks:install", { hidden: true }).description("[DEPRECATED] Use: workflow scope hooks install").action(async () => {
8492
+ deprecationWarning("workflow hooks:install", "workflow scope hooks install");
7686
8493
  return hooksCommand("install");
7687
8494
  });
7688
- program.command("hooks:uninstall", { hidden: true }).description("[DEPRECATED] Use: workflow hooks uninstall").action(async () => {
7689
- deprecationWarning("workflow hooks:uninstall", "workflow hooks uninstall");
8495
+ program.command("hooks:uninstall", { hidden: true }).description("[DEPRECATED] Use: workflow scope hooks uninstall").action(async () => {
8496
+ deprecationWarning("workflow hooks:uninstall", "workflow scope hooks uninstall");
7690
8497
  return hooksCommand("uninstall");
7691
8498
  });
7692
- program.command("hooks:status", { hidden: true }).description("[DEPRECATED] Use: workflow hooks status").action(async () => {
7693
- deprecationWarning("workflow hooks:status", "workflow hooks status");
8499
+ program.command("hooks:status", { hidden: true }).description("[DEPRECATED] Use: workflow scope hooks status").action(async () => {
8500
+ deprecationWarning("workflow hooks:status", "workflow scope hooks status");
7694
8501
  return hooksCommand("status");
7695
8502
  });
7696
8503
  program.command("scope:create", { hidden: true }).description("[DEPRECATED] Use: workflow scope create").option("--name <name>", 'Package name (e.g., "fintech", "gaming")').option(
@@ -7705,7 +8512,11 @@ program.command("scope:migrate", { hidden: true }).description("[DEPRECATED] Use
7705
8512
  return scopeMigrateCommand(options);
7706
8513
  });
7707
8514
  program.command("verify").description("Run all quality checks with fix-and-revalidate pattern").option("--fix", "Enable auto-fix for lint and format issues").option("--max-retries <n>", "Maximum retry cycles (default: 10)", "10").option("--commit", "Commit changes if all checks pass").option("--dry-run", "Preview fixes without applying them").option("--learn", "Record successful fixes as learning patterns").action(verifyCommand);
7708
- program.command("auto-setup").description("Automatically configure linting, formatting, testing, and CI").option("-y, --yes", "Auto-approve all prompts").option("--audit", "Show audit report without applying changes").action(autoSetupCommand);
8515
+ program.command("pre-commit").description("Run pre-commit checks (alias for verify --fix --staged)").option("--dry-run", "Preview fixes without applying them").action(preCommitCommand);
8516
+ program.command("auto-setup", { hidden: true }).description("[DEPRECATED] Use: workflow setup auto").option("-y, --yes", "Auto-approve all prompts").option("--audit", "Show audit report without applying changes").action(async (options) => {
8517
+ deprecationWarning("workflow auto-setup", "workflow setup auto");
8518
+ return autoSetupCommand(options);
8519
+ });
7709
8520
  program.command("advisory", { hidden: true }).description("[DEPRECATED] Use: workflow docs advisory").option("--depth <level>", "Analysis depth").option("--output <path>", "Output directory").option("--interactive", "Enable interactive mode").option("--dry-run", "Preview analysis without writing files").option("--format <type>", "Output format").option("--timestamp", "Append timestamp to filenames").option("--include-health", "Include code health metrics").option("--ci", "CI mode with exit codes").option("--compare <path>", "Compare with previous report").action(async (options) => {
7710
8521
  deprecationWarning("workflow advisory", "workflow docs advisory");
7711
8522
  return advisoryCommand(options);