workflow-agent-cli 2.22.11 → 2.23.1

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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -15
  3. package/dist/{auto-fix-7WAESKYO.js → auto-fix-WGRYEFLJ.js} +2 -2
  4. package/dist/{chunk-IWFUJ2DS.js → chunk-DWHIY7R4.js} +20 -9
  5. package/dist/chunk-DWHIY7R4.js.map +1 -0
  6. package/dist/{chunk-MMPXQG3O.js → chunk-K42R54II.js} +156 -57
  7. package/dist/chunk-K42R54II.js.map +1 -0
  8. package/dist/{chunk-XGS2VFBP.js → chunk-KJFRMHQU.js} +783 -18
  9. package/dist/chunk-KJFRMHQU.js.map +1 -0
  10. package/dist/{chunk-YELUGXOM.js → chunk-NPJJZHJG.js} +1 -1
  11. package/dist/chunk-NPJJZHJG.js.map +1 -0
  12. package/dist/{chunk-UWJ2ZGEI.js → chunk-OH6TK27N.js} +3 -3
  13. package/dist/{chunk-D36IFZUZ.js → chunk-PLVOGB6Y.js} +15 -4
  14. package/dist/chunk-PLVOGB6Y.js.map +1 -0
  15. package/dist/{chunk-ZLDJ2OGO.js → chunk-WK7D2AVV.js} +11 -3
  16. package/dist/{chunk-ZLDJ2OGO.js.map → chunk-WK7D2AVV.js.map} +1 -1
  17. package/dist/cli/index.js +1016 -315
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/config/index.js +2 -2
  20. package/dist/index.d.ts +78 -56
  21. package/dist/index.js +22 -10
  22. package/dist/scripts/postinstall.js +1 -1
  23. package/dist/scripts/postinstall.js.map +1 -1
  24. package/dist/sync-HHQM3GKR.js +7 -0
  25. package/dist/validators/index.js +1 -1
  26. package/dist/verify-OIHY7SGG.js +8 -0
  27. package/package.json +30 -31
  28. package/dist/chunk-3ADL5QDN.js +0 -396
  29. package/dist/chunk-3ADL5QDN.js.map +0 -1
  30. package/dist/chunk-D36IFZUZ.js.map +0 -1
  31. package/dist/chunk-IWFUJ2DS.js.map +0 -1
  32. package/dist/chunk-MMPXQG3O.js.map +0 -1
  33. package/dist/chunk-XGS2VFBP.js.map +0 -1
  34. package/dist/chunk-YELUGXOM.js.map +0 -1
  35. package/dist/sync-ON7M53OC.js +0 -7
  36. package/dist/verify-TX6LFMI6.js +0 -8
  37. /package/dist/{auto-fix-7WAESKYO.js.map → auto-fix-WGRYEFLJ.js.map} +0 -0
  38. /package/dist/{chunk-UWJ2ZGEI.js.map → chunk-OH6TK27N.js.map} +0 -0
  39. /package/dist/{sync-ON7M53OC.js.map → sync-HHQM3GKR.js.map} +0 -0
  40. /package/dist/{verify-TX6LFMI6.js.map → verify-OIHY7SGG.js.map} +0 -0
package/dist/cli/index.js CHANGED
@@ -1,23 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- analyzeProject,
4
- detectPackageManager,
5
- generateAuditReport,
6
- isMonorepo,
7
- runAllSetups
8
- } from "../chunk-XGS2VFBP.js";
9
2
  import {
10
3
  applyReferenceFix,
11
4
  validateBranchName,
12
5
  validateCommitMessage,
13
6
  validateDocumentReferences,
14
7
  validatePRTitle
15
- } from "../chunk-ZLDJ2OGO.js";
8
+ } from "../chunk-WK7D2AVV.js";
16
9
  import {
17
10
  hasConfig,
18
11
  loadConfig,
19
12
  loadConfigSafe
20
- } from "../chunk-UWJ2ZGEI.js";
13
+ } from "../chunk-OH6TK27N.js";
21
14
  import {
22
15
  DEPRECATED_SCRIPTS,
23
16
  WORKFLOW_SCRIPTS,
@@ -29,25 +22,31 @@ import {
29
22
  templateMetadata,
30
23
  updateTemplates,
31
24
  validateAllScripts
32
- } from "../chunk-IWFUJ2DS.js";
25
+ } from "../chunk-DWHIY7R4.js";
33
26
  import {
34
27
  autoFixConfigFile,
35
28
  validateScopeDefinitions
36
- } from "../chunk-YELUGXOM.js";
29
+ } from "../chunk-NPJJZHJG.js";
37
30
  import {
38
31
  verifyCommand
39
- } from "../chunk-D36IFZUZ.js";
40
- import "../chunk-3ADL5QDN.js";
32
+ } from "../chunk-PLVOGB6Y.js";
33
+ import {
34
+ analyzeProject,
35
+ detectPackageManager,
36
+ generateAuditReport,
37
+ isMonorepo,
38
+ runAllSetups
39
+ } from "../chunk-KJFRMHQU.js";
41
40
  import {
42
41
  syncCommand
43
- } from "../chunk-MMPXQG3O.js";
42
+ } from "../chunk-K42R54II.js";
44
43
 
45
44
  // src/cli/index.ts
46
45
  import { Command as Command7 } from "commander";
47
- import chalk23 from "chalk";
46
+ import chalk24 from "chalk";
48
47
  import { readFileSync as readFileSync3 } from "fs";
49
48
  import { fileURLToPath as fileURLToPath4 } from "url";
50
- import { dirname as dirname5, join as join12 } from "path";
49
+ import { dirname as dirname5, join as join13 } from "path";
51
50
 
52
51
  // src/cli/commands/init.ts
53
52
  import * as p from "@clack/prompts";
@@ -813,11 +812,19 @@ async function doctorCommand(options) {
813
812
  for (const issue of result.issues) {
814
813
  console.log(chalk5.red(` \u2717 ${issue.path}: ${issue.message}`));
815
814
  if (issue.currentValue !== void 0) {
816
- console.log(chalk5.dim(` Current value: ${JSON.stringify(issue.currentValue)}`));
815
+ console.log(
816
+ chalk5.dim(` Current value: ${JSON.stringify(issue.currentValue)}`)
817
+ );
817
818
  }
818
819
  if (issue.suggestedFix) {
819
- console.log(chalk5.green(` Suggested fix: ${issue.suggestedFix.description}`));
820
- console.log(chalk5.dim(` New value: ${JSON.stringify(issue.suggestedFix.newValue)}`));
820
+ console.log(
821
+ chalk5.green(` Suggested fix: ${issue.suggestedFix.description}`)
822
+ );
823
+ console.log(
824
+ chalk5.dim(
825
+ ` New value: ${JSON.stringify(issue.suggestedFix.newValue)}`
826
+ )
827
+ );
821
828
  }
822
829
  }
823
830
  const hasAutoFixes = result.issues.some((i) => i.suggestedFix);
@@ -830,7 +837,9 @@ async function doctorCommand(options) {
830
837
  for (const change of fixResult.changes) {
831
838
  console.log(chalk5.dim(` \u2022 ${change}`));
832
839
  }
833
- console.log(chalk5.cyan("\n Run 'workflow doctor' again to verify.\n"));
840
+ console.log(
841
+ chalk5.cyan("\n Run 'workflow doctor' again to verify.\n")
842
+ );
834
843
  process.exit(0);
835
844
  } else {
836
845
  console.log(chalk5.red(`\u2717 Auto-fix failed: ${fixResult.error}`));
@@ -865,15 +874,15 @@ async function doctorCommand(options) {
865
874
  }
866
875
  if (missingFiles.length === 0) {
867
876
  console.log(
868
- chalk5.green(`
869
- \u2713 All ${mandatoryFiles.length} mandatory guidelines present`)
877
+ chalk5.green(
878
+ `
879
+ \u2713 All ${mandatoryFiles.length} mandatory guidelines present`
880
+ )
870
881
  );
871
882
  } else {
872
883
  console.log(
873
- chalk5.red(
874
- `
875
- \u2717 Missing ${missingFiles.length} mandatory guideline(s)`
876
- )
884
+ chalk5.red(`
885
+ \u2717 Missing ${missingFiles.length} mandatory guideline(s)`)
877
886
  );
878
887
  }
879
888
  if (options?.checkGuidelinesOnly) {
@@ -899,7 +908,11 @@ async function doctorCommand(options) {
899
908
  }
900
909
  } catch (error) {
901
910
  console.log(chalk5.yellow("\u26A0 Could not check hooks status"));
902
- console.log(chalk5.dim(` ${error instanceof Error ? error.message : "Unknown error"}`));
911
+ console.log(
912
+ chalk5.dim(
913
+ ` ${error instanceof Error ? error.message : "Unknown error"}`
914
+ )
915
+ );
903
916
  }
904
917
  }
905
918
  if (missingFiles.length > 0) {
@@ -960,9 +973,7 @@ async function setupCommand() {
960
973
  }
961
974
  const hasChanges = scriptAdded || scriptUpdated || removedScripts.length > 0;
962
975
  if (!hasChanges) {
963
- p3.outro(
964
- chalk6.green(`\u2713 Workflow script is already configured!`)
965
- );
976
+ p3.outro(chalk6.green(`\u2713 Workflow script is already configured!`));
966
977
  return;
967
978
  }
968
979
  writeFileSync(
@@ -983,8 +994,10 @@ async function setupCommand() {
983
994
  }
984
995
  if (removedScripts.length > 0) {
985
996
  console.log(
986
- chalk6.yellow(`
987
- \u26A0\uFE0F Removed ${removedScripts.length} deprecated scripts`)
997
+ chalk6.yellow(
998
+ `
999
+ \u26A0\uFE0F Removed ${removedScripts.length} deprecated scripts`
1000
+ )
988
1001
  );
989
1002
  console.log(
990
1003
  chalk6.dim(
@@ -1186,7 +1199,9 @@ function formatAuditReportColored(report) {
1186
1199
 
1187
1200
  // src/cli/commands/setup/index.ts
1188
1201
  function createSetupCommand() {
1189
- const setupCmd = new Command("setup").description("Setup and configuration commands");
1202
+ const setupCmd = new Command("setup").description(
1203
+ "Setup and configuration commands"
1204
+ );
1190
1205
  setupCmd.action(setupCommand);
1191
1206
  setupCmd.command("scripts").description("Add workflow scripts to package.json").action(setupCommand);
1192
1207
  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);
@@ -1973,13 +1988,19 @@ async function docsValidateCommand(options) {
1973
1988
  console.log(chalk11.dim(` ${broken.rawLink}`));
1974
1989
  console.log(chalk11.dim(` Target: ${broken.targetPath}`));
1975
1990
  if (broken.suggestions.length > 0) {
1976
- console.log(chalk11.dim(` Suggestions: ${broken.suggestions.slice(0, 3).join(", ")}`));
1991
+ console.log(
1992
+ chalk11.dim(
1993
+ ` Suggestions: ${broken.suggestions.slice(0, 3).join(", ")}`
1994
+ )
1995
+ );
1977
1996
  }
1978
1997
  console.log("");
1979
1998
  }
1980
1999
  if (!fix) {
1981
2000
  console.log(
1982
- chalk11.yellow("\u{1F4A1} Run with --fix flag to interactively fix broken references")
2001
+ chalk11.yellow(
2002
+ "\u{1F4A1} Run with --fix flag to interactively fix broken references"
2003
+ )
1983
2004
  );
1984
2005
  p7.outro(chalk11.red("Validation failed"));
1985
2006
  process.exit(1);
@@ -2055,7 +2076,9 @@ Fixed: ${fixedCount}, Skipped: ${skippedCount}`)
2055
2076
  }
2056
2077
  try {
2057
2078
  await applyReferenceFix(broken.file, broken.rawLink, newPath);
2058
- console.log(chalk11.green(` \u2705 Fixed: ${broken.targetPath} \u2192 ${newPath}`));
2079
+ console.log(
2080
+ chalk11.green(` \u2705 Fixed: ${broken.targetPath} \u2192 ${newPath}`)
2081
+ );
2059
2082
  fixedCount++;
2060
2083
  } catch (error) {
2061
2084
  console.log(
@@ -2128,7 +2151,9 @@ async function docsGenerateCommand(options) {
2128
2151
  )
2129
2152
  );
2130
2153
  if (result.preservedCustomContent) {
2131
- console.log(chalk12.dim(" Custom content between markers was preserved."));
2154
+ console.log(
2155
+ chalk12.dim(" Custom content between markers was preserved.")
2156
+ );
2132
2157
  }
2133
2158
  console.log(chalk12.dim(`
2134
2159
  Output: ${result.filePath}`));
@@ -2155,9 +2180,13 @@ Reason: ${error instanceof Error ? error.message : String(error)}`
2155
2180
  p8.outro(chalk12.green("\u2713 AI agent instructions ready!"));
2156
2181
  console.log(chalk12.dim("\nThe .github/copilot-instructions.md file:"));
2157
2182
  console.log(chalk12.dim(" - Is read by GitHub Copilot and other AI agents"));
2158
- console.log(chalk12.dim(" - Summarizes all guidelines with links to full docs"));
2183
+ console.log(
2184
+ chalk12.dim(" - Summarizes all guidelines with links to full docs")
2185
+ );
2159
2186
  console.log(chalk12.dim(" - Includes your project scopes and conventions"));
2160
- console.log(chalk12.dim(" - Preserves custom instructions you add between markers\n"));
2187
+ console.log(
2188
+ chalk12.dim(" - Preserves custom instructions you add between markers\n")
2189
+ );
2161
2190
  }
2162
2191
 
2163
2192
  // src/cli/commands/docs/update.ts
@@ -2198,9 +2227,7 @@ async function docsUpdateCommand(options) {
2198
2227
  console.log(chalk13.dim(` ${meta.description}`));
2199
2228
  }
2200
2229
  }
2201
- const optionalFiles = allTemplates.filter(
2202
- (f) => !mandatoryFiles.includes(f)
2203
- );
2230
+ const optionalFiles = allTemplates.filter((f) => !mandatoryFiles.includes(f));
2204
2231
  if (optionalFiles.length > 0) {
2205
2232
  console.log(chalk13.bold("\n Optional templates:"));
2206
2233
  for (const file of optionalFiles) {
@@ -4094,7 +4121,7 @@ async function advisoryCommand(options) {
4094
4121
  const analyzer = new AdvisoryAnalyzer({
4095
4122
  depth,
4096
4123
  cwd,
4097
- config,
4124
+ config: config ?? void 0,
4098
4125
  includeHealth,
4099
4126
  excludePatterns: advisoryConfig?.excludePatterns
4100
4127
  });
@@ -5004,7 +5031,13 @@ ${chalk15.bold("Examples:")}
5004
5031
  docsCmd.command("advisory").description("Generate advisory board analysis and documentation").option(
5005
5032
  "--depth <level>",
5006
5033
  "Analysis depth: executive, quick, standard, comprehensive"
5007
- ).option("--output <path>", "Output directory (default: docs/advisory)").option("--interactive", "Enable interactive mode").option("--dry-run", "Preview analysis without writing files").option("--format <type>", "Output format: markdown, json (default: markdown)").option("--timestamp", "Append timestamp to filenames").option("--include-health", "Include code health metrics from verify/doctor").option("--ci", "CI mode with exit codes on high-risk findings").option("--compare <path>", "Compare with previous report").addHelpText(
5034
+ ).option("--output <path>", "Output directory (default: docs/advisory)").option("--interactive", "Enable interactive mode").option("--dry-run", "Preview analysis without writing files").option(
5035
+ "--format <type>",
5036
+ "Output format: markdown, json (default: markdown)"
5037
+ ).option("--timestamp", "Append timestamp to filenames").option(
5038
+ "--include-health",
5039
+ "Include code health metrics from verify/doctor"
5040
+ ).option("--ci", "CI mode with exit codes on high-risk findings").option("--compare <path>", "Compare with previous report").addHelpText(
5008
5041
  "after",
5009
5042
  `
5010
5043
  ${chalk15.bold("Examples:")}
@@ -5152,10 +5185,10 @@ async function statusAction() {
5152
5185
  async function testAction(options) {
5153
5186
  console.log(chalk17.bold.cyan("\n\u{1F9EA} Testing Git Hooks\n"));
5154
5187
  const fs3 = await import("fs");
5155
- const path4 = await import("path");
5188
+ const path5 = await import("path");
5156
5189
  const cwd = process.cwd();
5157
- const gitDir = path4.join(cwd, ".git");
5158
- const hooksDir = path4.join(gitDir, "hooks");
5190
+ const gitDir = path5.join(cwd, ".git");
5191
+ const hooksDir = path5.join(gitDir, "hooks");
5159
5192
  if (!fs3.existsSync(gitDir)) {
5160
5193
  console.log(chalk17.red("\u2717 Not a git repository"));
5161
5194
  process.exit(1);
@@ -5168,14 +5201,18 @@ async function testAction(options) {
5168
5201
  const hookTypes = ["pre-commit", "commit-msg"];
5169
5202
  let allInstalled = true;
5170
5203
  for (const hookType of hookTypes) {
5171
- const hookPath = path4.join(hooksDir, hookType);
5204
+ const hookPath = path5.join(hooksDir, hookType);
5172
5205
  const exists = fs3.existsSync(hookPath);
5173
5206
  const isExecutable = exists && (fs3.statSync(hookPath).mode & 73) !== 0;
5174
5207
  const isWorkflowHook2 = exists && fs3.readFileSync(hookPath, "utf-8").toLowerCase().includes("workflow");
5175
5208
  if (exists && isExecutable && isWorkflowHook2) {
5176
5209
  console.log(chalk17.green(` \u2713 ${hookType} - installed and executable`));
5177
5210
  } else if (exists && !isWorkflowHook2) {
5178
- console.log(chalk17.yellow(` \u26A0 ${hookType} - exists but not managed by workflow-agent`));
5211
+ console.log(
5212
+ chalk17.yellow(
5213
+ ` \u26A0 ${hookType} - exists but not managed by workflow-agent`
5214
+ )
5215
+ );
5179
5216
  allInstalled = false;
5180
5217
  } else if (exists && !isExecutable) {
5181
5218
  console.log(chalk17.red(` \u2717 ${hookType} - exists but not executable`));
@@ -5188,7 +5225,7 @@ async function testAction(options) {
5188
5225
  if (options.dryRun) {
5189
5226
  console.log(chalk17.bold.cyan("\n Dry-run hook simulation:\n"));
5190
5227
  console.log(chalk17.dim(" Simulating pre-commit hook..."));
5191
- const { verifyCommand: verifyCommand2 } = await import("../verify-TX6LFMI6.js");
5228
+ const { verifyCommand: verifyCommand2 } = await import("../verify-OIHY7SGG.js");
5192
5229
  try {
5193
5230
  await verifyCommand2({ fix: false, dryRun: true, maxRetries: "1" });
5194
5231
  } catch {
@@ -5446,14 +5483,20 @@ async function solutionCaptureCommand(options) {
5446
5483
  }
5447
5484
  const saveResult = await store.saveSolution(pattern);
5448
5485
  if (!saveResult.success) {
5449
- console.error(chalk18.red(`
5486
+ console.error(
5487
+ chalk18.red(`
5450
5488
  \u2717 Failed to save solution: ${saveResult.error}
5451
- `));
5489
+ `)
5490
+ );
5452
5491
  process.exit(1);
5453
5492
  }
5454
- console.log(chalk18.green(`
5493
+ console.log(
5494
+ chalk18.green(
5495
+ `
5455
5496
  \u2713 Solution saved: .workflow/patterns/solutions/${pattern.id}.json
5456
- `));
5497
+ `
5498
+ )
5499
+ );
5457
5500
  } catch (error) {
5458
5501
  spinner10.stop("Analysis failed");
5459
5502
  console.error(chalk18.red(`
@@ -5801,12 +5844,13 @@ async function solutionCreateCommand(options) {
5801
5844
  name,
5802
5845
  description,
5803
5846
  category,
5804
- tags: keywords.map((k) => ({ name: k, category })),
5847
+ tags: keywords.map((k) => ({
5848
+ name: k,
5849
+ category: "custom"
5850
+ })),
5805
5851
  problem: {
5806
5852
  description,
5807
5853
  keywords,
5808
- symptoms: [],
5809
- impact: "To be documented",
5810
5854
  errorPatterns: []
5811
5855
  },
5812
5856
  implementation: {
@@ -5851,17 +5895,23 @@ async function solutionCreateCommand(options) {
5851
5895
  };
5852
5896
  const saveResult = await store.saveSolution(solution);
5853
5897
  if (!saveResult.success) {
5854
- console.error(chalk18.red(`
5898
+ console.error(
5899
+ chalk18.red(`
5855
5900
  \u2717 Failed to save solution: ${saveResult.error}
5856
- `));
5901
+ `)
5902
+ );
5857
5903
  process.exit(1);
5858
5904
  }
5859
5905
  console.log(chalk18.green("\n\u2713 Solution pattern created!\n"));
5860
- console.log(chalk18.dim(` Path: .workflow/patterns/solutions/${solution.id}.json`));
5906
+ console.log(
5907
+ chalk18.dim(` Path: .workflow/patterns/solutions/${solution.id}.json`)
5908
+ );
5861
5909
  console.log(chalk18.dim(` Name: ${name}`));
5862
5910
  console.log(chalk18.dim(` Category: ${category}`));
5863
- console.log(chalk18.dim(`
5864
- Add files using 'workflow solution capture --path <dir>'`));
5911
+ console.log(
5912
+ chalk18.dim(`
5913
+ Add files using 'workflow solution capture --path <dir>'`)
5914
+ );
5865
5915
  }
5866
5916
  async function solutionShowCommand(solutionId) {
5867
5917
  const cwd = getWorkspacePath();
@@ -5885,20 +5935,26 @@ async function solutionShowCommand(solutionId) {
5885
5935
  console.log(chalk18.bold("\nCompatibility:"));
5886
5936
  console.log(` Framework: ${solution.compatibility.framework || "generic"}`);
5887
5937
  console.log(` Version: ${solution.compatibility.frameworkVersion}`);
5888
- console.log(` Runtime: ${solution.compatibility.runtime} ${solution.compatibility.runtimeVersion}`);
5938
+ console.log(
5939
+ ` Runtime: ${solution.compatibility.runtime} ${solution.compatibility.runtimeVersion}`
5940
+ );
5889
5941
  console.log(chalk18.bold("\nImplementation:"));
5890
5942
  console.log(` Files: ${solution.implementation.files.length}`);
5891
5943
  for (const file of solution.implementation.files) {
5892
5944
  console.log(chalk18.dim(` \u2022 ${file.path} (${file.role})`));
5893
5945
  }
5894
5946
  if (solution.implementation.dependencies.length > 0) {
5895
- console.log(` Dependencies: ${solution.implementation.dependencies.length}`);
5947
+ console.log(
5948
+ ` Dependencies: ${solution.implementation.dependencies.length}`
5949
+ );
5896
5950
  for (const dep of solution.implementation.dependencies) {
5897
5951
  console.log(chalk18.dim(` \u2022 ${dep.name}@${dep.version}`));
5898
5952
  }
5899
5953
  }
5900
5954
  if (solution.implementation.envVars.length > 0) {
5901
- console.log(` Environment Variables: ${solution.implementation.envVars.length}`);
5955
+ console.log(
5956
+ ` Environment Variables: ${solution.implementation.envVars.length}`
5957
+ );
5902
5958
  for (const env of solution.implementation.envVars) {
5903
5959
  const required = env.required ? chalk18.red("*") : "";
5904
5960
  console.log(chalk18.dim(` \u2022 ${env.name}${required}`));
@@ -5906,14 +5962,22 @@ async function solutionShowCommand(solutionId) {
5906
5962
  }
5907
5963
  console.log(chalk18.bold("\nMetrics:"));
5908
5964
  console.log(` Applications: ${solution.metrics.applications}`);
5909
- console.log(` Success Rate: ${(solution.metrics.successRate * 100).toFixed(1)}%`);
5965
+ console.log(
5966
+ ` Success Rate: ${(solution.metrics.successRate * 100).toFixed(1)}%`
5967
+ );
5910
5968
  console.log(chalk18.bold("\nMetadata:"));
5911
5969
  console.log(` Created: ${formatDate(solution.createdAt)}`);
5912
5970
  console.log(` Updated: ${formatDate(solution.updatedAt)}`);
5913
5971
  console.log(` Private: ${solution.isPrivate ? "Yes" : "No"}`);
5914
5972
  if (solution.deprecatedAt) {
5915
- console.log(chalk18.red(` Deprecated: ${formatDate(solution.deprecatedAt)}`));
5916
- console.log(chalk18.dim(` Reason: ${solution.deprecationReason || "No reason provided"}`));
5973
+ console.log(
5974
+ chalk18.red(` Deprecated: ${formatDate(solution.deprecatedAt)}`)
5975
+ );
5976
+ console.log(
5977
+ chalk18.dim(
5978
+ ` Reason: ${solution.deprecationReason || "No reason provided"}`
5979
+ )
5980
+ );
5917
5981
  }
5918
5982
  console.log();
5919
5983
  }
@@ -5995,7 +6059,9 @@ async function solutionImportCommand(file, options) {
5995
6059
  let importData;
5996
6060
  try {
5997
6061
  if (file.endsWith(".yaml") || file.endsWith(".yml")) {
5998
- console.log(chalk18.yellow(" YAML import not fully supported, treating as JSON"));
6062
+ console.log(
6063
+ chalk18.yellow(" YAML import not fully supported, treating as JSON")
6064
+ );
5999
6065
  }
6000
6066
  importData = JSON.parse(content);
6001
6067
  } catch {
@@ -6012,7 +6078,9 @@ async function solutionImportCommand(file, options) {
6012
6078
  if (dryRun) {
6013
6079
  console.log(chalk18.yellow(" \u{1F50D} Dry run - no changes will be made\n"));
6014
6080
  for (const solution of solutions) {
6015
- console.log(chalk18.dim(` Would import: ${solution.name} (${solution.id})`));
6081
+ console.log(
6082
+ chalk18.dim(` Would import: ${solution.name} (${solution.id})`)
6083
+ );
6016
6084
  }
6017
6085
  return;
6018
6086
  }
@@ -6027,7 +6095,11 @@ async function solutionImportCommand(file, options) {
6027
6095
  }
6028
6096
  const saveResult = await store.saveSolution(solution);
6029
6097
  if (!saveResult.success) {
6030
- console.log(chalk18.red(` \u2717 Failed to import: ${solution.name} - ${saveResult.error}`));
6098
+ console.log(
6099
+ chalk18.red(
6100
+ ` \u2717 Failed to import: ${solution.name} - ${saveResult.error}`
6101
+ )
6102
+ );
6031
6103
  continue;
6032
6104
  }
6033
6105
  console.log(chalk18.green(` \u2713 Imported: ${solution.name}`));
@@ -6046,21 +6118,83 @@ async function solutionAnalyzeCommand() {
6046
6118
  const pathModule = await import("path");
6047
6119
  console.log(chalk18.cyan("\n\u{1F50D} Analyzing Codebase for Solution Patterns\n"));
6048
6120
  const existingResult = await store.listSolutions({ limit: 1e3 });
6049
- const existingNames = (existingResult.data || []).map((s) => s.name.toLowerCase());
6121
+ const existingNames = (existingResult.data || []).map(
6122
+ (s) => s.name.toLowerCase()
6123
+ );
6050
6124
  const opportunities = [];
6051
6125
  const patterns = [
6052
- { path: "src/auth", name: "Authentication Module", category: "auth", desc: "Authentication implementation" },
6053
- { path: "src/lib/auth", name: "Auth Library", category: "auth", desc: "Authentication utilities" },
6054
- { path: "src/api", name: "API Layer", category: "api", desc: "API routing structure" },
6055
- { path: "app/api", name: "Next.js API Routes", category: "api", desc: "Next.js API implementation" },
6056
- { path: "src/db", name: "Database Layer", category: "database", desc: "Database connection and queries" },
6057
- { path: "src/lib/db", name: "Database Utilities", category: "database", desc: "Database helper functions" },
6058
- { path: "src/components/ui", name: "UI Components", category: "ui", desc: "Reusable UI components" },
6059
- { path: "src/hooks", name: "Custom Hooks", category: "ui", desc: "React custom hooks" },
6060
- { path: "__tests__", name: "Testing Setup", category: "testing", desc: "Test configuration and utilities" },
6061
- { path: ".github/workflows", name: "CI/CD Pipeline", category: "deployment", desc: "GitHub Actions workflows" },
6062
- { path: "src/integrations", name: "Integrations", category: "integrations", desc: "Third-party integrations" },
6063
- { path: "src/middleware", name: "Middleware", category: "security", desc: "Request middleware and guards" }
6126
+ {
6127
+ path: "src/auth",
6128
+ name: "Authentication Module",
6129
+ category: "auth",
6130
+ desc: "Authentication implementation"
6131
+ },
6132
+ {
6133
+ path: "src/lib/auth",
6134
+ name: "Auth Library",
6135
+ category: "auth",
6136
+ desc: "Authentication utilities"
6137
+ },
6138
+ {
6139
+ path: "src/api",
6140
+ name: "API Layer",
6141
+ category: "api",
6142
+ desc: "API routing structure"
6143
+ },
6144
+ {
6145
+ path: "app/api",
6146
+ name: "Next.js API Routes",
6147
+ category: "api",
6148
+ desc: "Next.js API implementation"
6149
+ },
6150
+ {
6151
+ path: "src/db",
6152
+ name: "Database Layer",
6153
+ category: "database",
6154
+ desc: "Database connection and queries"
6155
+ },
6156
+ {
6157
+ path: "src/lib/db",
6158
+ name: "Database Utilities",
6159
+ category: "database",
6160
+ desc: "Database helper functions"
6161
+ },
6162
+ {
6163
+ path: "src/components/ui",
6164
+ name: "UI Components",
6165
+ category: "ui",
6166
+ desc: "Reusable UI components"
6167
+ },
6168
+ {
6169
+ path: "src/hooks",
6170
+ name: "Custom Hooks",
6171
+ category: "ui",
6172
+ desc: "React custom hooks"
6173
+ },
6174
+ {
6175
+ path: "__tests__",
6176
+ name: "Testing Setup",
6177
+ category: "testing",
6178
+ desc: "Test configuration and utilities"
6179
+ },
6180
+ {
6181
+ path: ".github/workflows",
6182
+ name: "CI/CD Pipeline",
6183
+ category: "deployment",
6184
+ desc: "GitHub Actions workflows"
6185
+ },
6186
+ {
6187
+ path: "src/integrations",
6188
+ name: "Integrations",
6189
+ category: "integrations",
6190
+ desc: "Third-party integrations"
6191
+ },
6192
+ {
6193
+ path: "src/middleware",
6194
+ name: "Middleware",
6195
+ category: "security",
6196
+ desc: "Request middleware and guards"
6197
+ }
6064
6198
  ];
6065
6199
  for (const pattern of patterns) {
6066
6200
  const fullPath = pathModule.default.join(cwd, pattern.path);
@@ -6078,8 +6212,10 @@ async function solutionAnalyzeCommand() {
6078
6212
  console.log(chalk18.dim("\n Your solutions seem well-captured!"));
6079
6213
  return;
6080
6214
  }
6081
- console.log(chalk18.bold(` Found ${opportunities.length} potential solutions:
6082
- `));
6215
+ console.log(
6216
+ chalk18.bold(` Found ${opportunities.length} potential solutions:
6217
+ `)
6218
+ );
6083
6219
  for (const opp of opportunities) {
6084
6220
  console.log(` ${formatCategory(opp.category)}`);
6085
6221
  console.log(chalk18.bold(` ${opp.name}`));
@@ -6088,7 +6224,9 @@ async function solutionAnalyzeCommand() {
6088
6224
  `));
6089
6225
  }
6090
6226
  console.log(chalk18.dim(" To capture a solution:"));
6091
- console.log(chalk18.cyan(" workflow solution capture --path <path> --name <name>"));
6227
+ console.log(
6228
+ chalk18.cyan(" workflow solution capture --path <path> --name <name>")
6229
+ );
6092
6230
  }
6093
6231
  async function solutionMigrateCommand(options) {
6094
6232
  const cwd = getWorkspacePath();
@@ -6098,8 +6236,16 @@ async function solutionMigrateCommand(options) {
6098
6236
  if (!options.public && !options.private) {
6099
6237
  console.log(chalk18.yellow(" Please specify --public or --private"));
6100
6238
  console.log(chalk18.dim("\n Examples:"));
6101
- console.log(chalk18.dim(" workflow solution migrate --public # Make all solutions public"));
6102
- console.log(chalk18.dim(" workflow solution migrate --private # Make all solutions private"));
6239
+ console.log(
6240
+ chalk18.dim(
6241
+ " workflow solution migrate --public # Make all solutions public"
6242
+ )
6243
+ );
6244
+ console.log(
6245
+ chalk18.dim(
6246
+ " workflow solution migrate --private # Make all solutions private"
6247
+ )
6248
+ );
6103
6249
  return;
6104
6250
  }
6105
6251
  const targetPrivate = options.private ?? false;
@@ -6112,17 +6258,31 @@ async function solutionMigrateCommand(options) {
6112
6258
  const solutions = result.data;
6113
6259
  const toMigrate = solutions.filter((s) => s.isPrivate !== targetPrivate);
6114
6260
  if (toMigrate.length === 0) {
6115
- console.log(chalk18.green(` \u2713 All ${solutions.length} solutions are already ${targetLabel}`));
6261
+ console.log(
6262
+ chalk18.green(
6263
+ ` \u2713 All ${solutions.length} solutions are already ${targetLabel}`
6264
+ )
6265
+ );
6116
6266
  return;
6117
6267
  }
6118
- console.log(chalk18.dim(` Found ${toMigrate.length} solutions to make ${targetLabel}:
6119
- `));
6268
+ console.log(
6269
+ chalk18.dim(
6270
+ ` Found ${toMigrate.length} solutions to make ${targetLabel}:
6271
+ `
6272
+ )
6273
+ );
6120
6274
  for (const solution of toMigrate) {
6121
- console.log(chalk18.dim(` \u2022 ${solution.name} (${solution.id.slice(0, 8)})`));
6275
+ console.log(
6276
+ chalk18.dim(` \u2022 ${solution.name} (${solution.id.slice(0, 8)})`)
6277
+ );
6122
6278
  }
6123
6279
  if (options.dryRun) {
6124
- console.log(chalk18.yellow(`
6125
- [DRY-RUN] Would migrate ${toMigrate.length} solutions to ${targetLabel}`));
6280
+ console.log(
6281
+ chalk18.yellow(
6282
+ `
6283
+ [DRY-RUN] Would migrate ${toMigrate.length} solutions to ${targetLabel}`
6284
+ )
6285
+ );
6126
6286
  return;
6127
6287
  }
6128
6288
  const confirm10 = await p11.confirm({
@@ -6145,10 +6305,16 @@ async function solutionMigrateCommand(options) {
6145
6305
  migrated++;
6146
6306
  }
6147
6307
  }
6148
- console.log(chalk18.green(`
6149
- \u2713 Migrated ${migrated} solutions to ${targetLabel}`));
6308
+ console.log(
6309
+ chalk18.green(`
6310
+ \u2713 Migrated ${migrated} solutions to ${targetLabel}`)
6311
+ );
6150
6312
  if (!targetPrivate) {
6151
- console.log(chalk18.dim(" These solutions can now be synced with 'workflow sync --solutions --push'"));
6313
+ console.log(
6314
+ chalk18.dim(
6315
+ " These solutions can now be synced with 'workflow sync --solutions --push'"
6316
+ )
6317
+ );
6152
6318
  }
6153
6319
  }
6154
6320
  async function solutionEditCommand(solutionId, options) {
@@ -6195,7 +6361,9 @@ async function solutionEditCommand(solutionId, options) {
6195
6361
  console.log(chalk18.dim(" --private Make private"));
6196
6362
  return;
6197
6363
  }
6198
- console.log(chalk18.dim(` Solution: ${solution.name} (${solution.id.slice(0, 8)})`));
6364
+ console.log(
6365
+ chalk18.dim(` Solution: ${solution.name} (${solution.id.slice(0, 8)})`)
6366
+ );
6199
6367
  console.log(chalk18.dim(" Changes:"));
6200
6368
  for (const change of changes) {
6201
6369
  console.log(chalk18.dim(` \u2022 ${change}`));
@@ -6205,7 +6373,11 @@ async function solutionEditCommand(solutionId, options) {
6205
6373
  if (saveResult.success) {
6206
6374
  console.log(chalk18.green("\n \u2713 Solution updated"));
6207
6375
  if (options.public) {
6208
- console.log(chalk18.dim(" This solution can now be synced with 'workflow sync --solutions --push'"));
6376
+ console.log(
6377
+ chalk18.dim(
6378
+ " This solution can now be synced with 'workflow sync --solutions --push'"
6379
+ )
6380
+ );
6209
6381
  }
6210
6382
  } else {
6211
6383
  console.log(chalk18.red(`
@@ -6377,7 +6549,8 @@ import {
6377
6549
  TelemetryCollector,
6378
6550
  FixPatternSchema,
6379
6551
  BlueprintSchema,
6380
- SolutionPatternSchema
6552
+ SolutionPatternSchema,
6553
+ createDefaultMetrics
6381
6554
  } from "@hawkinside_out/workflow-improvement-tracker";
6382
6555
  function getWorkspacePath2() {
6383
6556
  return process.cwd();
@@ -6485,16 +6658,18 @@ async function learnRecordCommand(options) {
6485
6658
  const catChoice = await p12.select({
6486
6659
  message: "Category:",
6487
6660
  options: [
6488
- { value: "migration", label: "\u{1F504} Migration" },
6661
+ { value: "lint", label: "\u{1F527} Lint Error" },
6662
+ { value: "type-error", label: "\u{1F537} Type Error" },
6663
+ { value: "dependency", label: "\u{1F4E6} Dependency" },
6664
+ { value: "config", label: "\u2699\uFE0F Configuration" },
6665
+ { value: "runtime", label: "\u{1F3C3} Runtime" },
6666
+ { value: "build", label: "\u{1F3D7}\uFE0F Build" },
6667
+ { value: "test", label: "\u{1F9EA} Test" },
6489
6668
  { value: "security", label: "\u{1F512} Security" },
6490
- { value: "performance", label: "\u26A1 Performance" },
6491
- { value: "compatibility", label: "\u{1F517} Compatibility" },
6669
+ { value: "migration", label: "\u{1F504} Migration" },
6492
6670
  { value: "deprecation", label: "\u26A0\uFE0F Deprecation" },
6493
- { value: "configuration", label: "\u2699\uFE0F Configuration" },
6494
- { value: "best-practice", label: "\u2728 Best Practice" },
6495
- { value: "error-handling", label: "\u{1F6A8} Error Handling" },
6496
- { value: "testing", label: "\u{1F9EA} Testing" },
6497
- { value: "other", label: "\u{1F4E6} Other" }
6671
+ { value: "performance", label: "\u26A1 Performance" },
6672
+ { value: "compatibility", label: "\u{1F517} Compatibility" }
6498
6673
  ]
6499
6674
  });
6500
6675
  if (p12.isCancel(catChoice)) {
@@ -6619,7 +6794,9 @@ async function learnRecordCommand(options) {
6619
6794
  console.log(chalk20.dim(` ID: ${blueprint.id}`));
6620
6795
  console.log(chalk20.dim(` Name: ${name}`));
6621
6796
  console.log(chalk20.dim(` Framework: ${framework} ${version}`));
6622
- console.log(chalk20.dim(` Path: .workflow/patterns/blueprints/${blueprint.id}.json`));
6797
+ console.log(
6798
+ chalk20.dim(` Path: .workflow/patterns/blueprints/${blueprint.id}.json`)
6799
+ );
6623
6800
  } else {
6624
6801
  console.log(chalk20.red("\n\u274C Failed to record blueprint"));
6625
6802
  console.log(chalk20.dim(` Error: ${result.error}`));
@@ -6714,15 +6891,11 @@ async function learnListCommand(options) {
6714
6891
  \u26A0\uFE0F ${totalInvalid} pattern(s) failed schema validation and were skipped:`
6715
6892
  )
6716
6893
  );
6717
- console.log(
6718
- chalk20.dim(` Fix patterns: ${stats.invalidFixes} invalid`)
6719
- );
6894
+ console.log(chalk20.dim(` Fix patterns: ${stats.invalidFixes} invalid`));
6720
6895
  console.log(
6721
6896
  chalk20.dim(` Blueprints: ${stats.invalidBlueprints} invalid`)
6722
6897
  );
6723
- console.log(
6724
- chalk20.dim(` Solutions: ${stats.invalidSolutions} invalid`)
6725
- );
6898
+ console.log(chalk20.dim(` Solutions: ${stats.invalidSolutions} invalid`));
6726
6899
  const validationErrors = store.getValidationErrors();
6727
6900
  if (validationErrors.length > 0) {
6728
6901
  console.log(chalk20.yellow("\n Validation errors:"));
@@ -6741,9 +6914,7 @@ async function learnListCommand(options) {
6741
6914
  }
6742
6915
  if (validationErrors.length > 5) {
6743
6916
  console.log(
6744
- chalk20.dim(
6745
- ` ... and ${validationErrors.length - 5} more errors`
6746
- )
6917
+ chalk20.dim(` ... and ${validationErrors.length - 5} more errors`)
6747
6918
  );
6748
6919
  }
6749
6920
  }
@@ -6766,12 +6937,17 @@ async function learnApplyCommand(patternId, options) {
6766
6937
  await store.initialize();
6767
6938
  const telemetry = new TelemetryCollector(cwd);
6768
6939
  console.log(chalk20.cyan("\n\u{1F527} Apply Learning Pattern\n"));
6769
- let pattern = await store.getFixPattern(patternId);
6940
+ let fixPattern;
6941
+ let blueprintPattern;
6770
6942
  let patternType = "fix";
6771
- if (!pattern.success || !pattern.data) {
6943
+ const fixResult = await store.getFixPattern(patternId);
6944
+ if (fixResult.success && fixResult.data) {
6945
+ fixPattern = fixResult.data;
6946
+ patternType = "fix";
6947
+ } else {
6772
6948
  const bpResult = await store.getBlueprint(patternId);
6773
6949
  if (bpResult.success && bpResult.data) {
6774
- pattern = bpResult;
6950
+ blueprintPattern = bpResult.data;
6775
6951
  patternType = "blueprint";
6776
6952
  } else {
6777
6953
  console.log(chalk20.red(`
@@ -6782,7 +6958,7 @@ async function learnApplyCommand(patternId, options) {
6782
6958
  process.exit(1);
6783
6959
  }
6784
6960
  }
6785
- const patternData = pattern.data;
6961
+ const patternData = fixPattern ?? blueprintPattern;
6786
6962
  console.log(chalk20.white(` Pattern: ${patternData.name}`));
6787
6963
  console.log(chalk20.dim(` Type: ${patternType}`));
6788
6964
  console.log(chalk20.dim(` Description: ${patternData.description}`));
@@ -6791,11 +6967,10 @@ async function learnApplyCommand(patternId, options) {
6791
6967
  chalk20.yellow("\n\u{1F4CB} DRY-RUN MODE: No changes will be applied\n")
6792
6968
  );
6793
6969
  }
6794
- const framework = options.framework ?? patternData.compatibility?.frameworks?.[0]?.name ?? "unknown";
6795
- const version = options.version ?? patternData.compatibility?.frameworks?.[0]?.version ?? "0.0.0";
6970
+ const framework = options.framework ?? patternData.compatibility?.framework ?? "unknown";
6971
+ const version = options.version ?? patternData.compatibility?.frameworkVersion ?? "0.0.0";
6796
6972
  await telemetry.recordApplication(patternId, patternType, framework, version);
6797
- if (patternType === "fix") {
6798
- const fixPattern = patternData;
6973
+ if (patternType === "fix" && fixPattern) {
6799
6974
  console.log(chalk20.cyan("\n\u{1F4CB} Solution Steps:\n"));
6800
6975
  if (fixPattern.solution.steps) {
6801
6976
  for (let i = 0; i < fixPattern.solution.steps.length; i++) {
@@ -6803,17 +6978,16 @@ async function learnApplyCommand(patternId, options) {
6803
6978
  console.log(
6804
6979
  chalk20.white(` ${i + 1}. [${step.action}] ${step.description}`)
6805
6980
  );
6806
- if (step.file) {
6807
- console.log(chalk20.dim(` File: ${step.file}`));
6981
+ if (step.target) {
6982
+ console.log(chalk20.dim(` Target: ${step.target}`));
6808
6983
  }
6809
6984
  }
6810
6985
  }
6811
- } else {
6812
- const blueprint = patternData;
6986
+ } else if (blueprintPattern) {
6813
6987
  console.log(chalk20.cyan("\n\u{1F4CB} Setup Steps:\n"));
6814
- if (blueprint.setup.steps) {
6815
- for (let i = 0; i < blueprint.setup.steps.length; i++) {
6816
- const step = blueprint.setup.steps[i];
6988
+ if (blueprintPattern.setup.steps) {
6989
+ for (let i = 0; i < blueprintPattern.setup.steps.length; i++) {
6990
+ const step = blueprintPattern.setup.steps[i];
6817
6991
  console.log(chalk20.white(` ${i + 1}. ${step.description}`));
6818
6992
  if (step.command) {
6819
6993
  console.log(chalk20.dim(` Command: ${step.command}`));
@@ -6965,7 +7139,9 @@ ${emoji} Mark Pattern(s) ${actionWord}
6965
7139
  const totalToUpdate = fixesToUpdate.length + blueprintsToUpdate.length;
6966
7140
  if (totalToUpdate === 0) {
6967
7141
  console.log(
6968
- chalk20.yellow(` All patterns are already ${actionWord}. Nothing to do.`)
7142
+ chalk20.yellow(
7143
+ ` All patterns are already ${actionWord}. Nothing to do.`
7144
+ )
6969
7145
  );
6970
7146
  return;
6971
7147
  }
@@ -6988,9 +7164,9 @@ ${emoji} Mark Pattern(s) ${actionWord}
6988
7164
  }
6989
7165
  let successCount = 0;
6990
7166
  let failCount = 0;
6991
- for (const pattern2 of fixesToUpdate) {
7167
+ for (const pattern of fixesToUpdate) {
6992
7168
  const result2 = await store.saveFixPattern({
6993
- ...pattern2,
7169
+ ...pattern,
6994
7170
  isPrivate: makePrivate,
6995
7171
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
6996
7172
  });
@@ -7026,17 +7202,20 @@ ${emoji} Mark Pattern(s) ${actionWord}
7026
7202
  console.log(
7027
7203
  chalk20.dim(" Usage: workflow learn:publish <patternId> [--private]")
7028
7204
  );
7029
- console.log(
7030
- chalk20.dim(" workflow learn:publish --all [--private]")
7031
- );
7205
+ console.log(chalk20.dim(" workflow learn:publish --all [--private]"));
7032
7206
  process.exit(1);
7033
7207
  }
7034
7208
  let patternType = "fix";
7035
- let pattern = await store.getFixPattern(patternId);
7036
- if (!pattern.success || !pattern.data) {
7209
+ let fixPatternData;
7210
+ let blueprintData;
7211
+ const fixResult = await store.getFixPattern(patternId);
7212
+ if (fixResult.success && fixResult.data) {
7213
+ fixPatternData = fixResult.data;
7214
+ patternType = "fix";
7215
+ } else {
7037
7216
  const bpResult = await store.getBlueprint(patternId);
7038
7217
  if (bpResult.success && bpResult.data) {
7039
- pattern = bpResult;
7218
+ blueprintData = bpResult.data;
7040
7219
  patternType = "blueprint";
7041
7220
  } else {
7042
7221
  console.log(chalk20.red(`
@@ -7047,15 +7226,16 @@ ${emoji} Mark Pattern(s) ${actionWord}
7047
7226
  process.exit(1);
7048
7227
  }
7049
7228
  }
7050
- const currentStatus = pattern.data.isPrivate ? "private" : "public";
7051
- if (pattern.data.isPrivate === makePrivate) {
7229
+ const patternInfo = fixPatternData ?? blueprintData;
7230
+ const currentStatus = patternInfo.isPrivate ? "private" : "public";
7231
+ if (patternInfo.isPrivate === makePrivate) {
7052
7232
  console.log(
7053
7233
  chalk20.yellow(` Pattern is already ${actionWord}. Nothing to do.`)
7054
7234
  );
7055
- console.log(chalk20.dim(` Name: ${pattern.data.name}`));
7235
+ console.log(chalk20.dim(` Name: ${patternInfo.name}`));
7056
7236
  return;
7057
7237
  }
7058
- console.log(chalk20.white(` Pattern: ${pattern.data.name}`));
7238
+ console.log(chalk20.white(` Pattern: ${patternInfo.name}`));
7059
7239
  console.log(chalk20.dim(` Type: ${patternType}`));
7060
7240
  console.log(chalk20.dim(` Current: ${currentStatus} \u2192 ${actionWord}`));
7061
7241
  if (!options.yes) {
@@ -7068,16 +7248,24 @@ ${emoji} Mark Pattern(s) ${actionWord}
7068
7248
  return;
7069
7249
  }
7070
7250
  }
7071
- const updatedPattern = {
7072
- ...pattern.data,
7073
- isPrivate: makePrivate,
7074
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
7075
- };
7076
7251
  let result;
7077
- if (patternType === "fix") {
7078
- result = await store.saveFixPattern(updatedPattern);
7252
+ if (patternType === "fix" && fixPatternData) {
7253
+ const updatedFix = {
7254
+ ...fixPatternData,
7255
+ isPrivate: makePrivate,
7256
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
7257
+ };
7258
+ result = await store.saveFixPattern(updatedFix);
7259
+ } else if (blueprintData) {
7260
+ const updatedBlueprint = {
7261
+ ...blueprintData,
7262
+ isPrivate: makePrivate,
7263
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
7264
+ };
7265
+ result = await store.saveBlueprint(updatedBlueprint);
7079
7266
  } else {
7080
- result = await store.saveBlueprint(updatedPattern);
7267
+ console.log(chalk20.red("\n\u274C Unexpected error: pattern data not found"));
7268
+ process.exit(1);
7081
7269
  }
7082
7270
  if (result.success) {
7083
7271
  console.log(chalk20.green(`
@@ -7099,19 +7287,23 @@ async function learnDeprecateCommand(patternId, reason) {
7099
7287
  await store.initialize();
7100
7288
  console.log(chalk20.cyan("\n\u26A0\uFE0F Deprecate Pattern\n"));
7101
7289
  let patternType = "fix";
7102
- let pattern = await store.getFixPattern(patternId);
7103
- if (!pattern.success || !pattern.data) {
7290
+ let patternName;
7291
+ const fixResult = await store.getFixPattern(patternId);
7292
+ if (fixResult.success && fixResult.data) {
7293
+ patternType = "fix";
7294
+ patternName = fixResult.data.name;
7295
+ } else {
7104
7296
  const bpResult = await store.getBlueprint(patternId);
7105
7297
  if (bpResult.success && bpResult.data) {
7106
- pattern = bpResult;
7107
7298
  patternType = "blueprint";
7299
+ patternName = bpResult.data.name;
7108
7300
  } else {
7109
7301
  console.log(chalk20.red(`
7110
7302
  \u274C Pattern not found: ${patternId}`));
7111
7303
  process.exit(1);
7112
7304
  }
7113
7305
  }
7114
- console.log(chalk20.white(` Pattern: ${pattern.data.name}`));
7306
+ console.log(chalk20.white(` Pattern: ${patternName}`));
7115
7307
  console.log(chalk20.dim(` Reason: ${reason}`));
7116
7308
  const confirmed = await p12.confirm({
7117
7309
  message: "Are you sure you want to deprecate this pattern?",
@@ -7286,7 +7478,13 @@ async function validatePatternDirectory(dirPath, type, schema, verbose) {
7286
7478
  for (const file of files) {
7287
7479
  if (!file.endsWith(".json")) continue;
7288
7480
  const filePath = path3.join(dirPath, file);
7289
- const result = await validatePatternFile(filePath, file, type, schema, verbose);
7481
+ const result = await validatePatternFile(
7482
+ filePath,
7483
+ file,
7484
+ type,
7485
+ schema,
7486
+ verbose
7487
+ );
7290
7488
  results.push(result);
7291
7489
  if (verbose) {
7292
7490
  if (result.valid) {
@@ -7342,7 +7540,7 @@ async function validateSingleFile(filePath, verbose) {
7342
7540
  }
7343
7541
  return validatePatternFile(filePath, fileName, type, schema, verbose);
7344
7542
  }
7345
- async function validatePatternFile(filePath, fileName, type, schema, verbose) {
7543
+ async function validatePatternFile(filePath, fileName, type, schema, _verbose) {
7346
7544
  try {
7347
7545
  const content = await fs2.promises.readFile(filePath, "utf-8");
7348
7546
  const data = JSON.parse(content);
@@ -7359,7 +7557,11 @@ async function validatePatternFile(filePath, fileName, type, schema, verbose) {
7359
7557
  const errors = validation.error.issues.map(
7360
7558
  (i) => `${i.path.join(".")}: ${i.message}`
7361
7559
  );
7362
- const { fixable, fixedData } = tryAutoFix(data, type, validation.error.issues);
7560
+ const { fixable, fixedData } = tryAutoFix(
7561
+ data,
7562
+ type,
7563
+ validation.error.issues
7564
+ );
7363
7565
  return {
7364
7566
  file: fileName,
7365
7567
  type,
@@ -7373,9 +7575,7 @@ async function validatePatternFile(filePath, fileName, type, schema, verbose) {
7373
7575
  file: fileName,
7374
7576
  type,
7375
7577
  valid: false,
7376
- errors: [
7377
- error instanceof Error ? error.message : "Failed to parse JSON"
7378
- ],
7578
+ errors: [error instanceof Error ? error.message : "Failed to parse JSON"],
7379
7579
  fixable: false
7380
7580
  };
7381
7581
  }
@@ -7442,103 +7642,223 @@ function tryAutoFix(data, type, issues) {
7442
7642
  }
7443
7643
  var LIBRARY_TAG_MAP = {
7444
7644
  // Frontend Frameworks
7445
- "react": [{ category: "framework", name: "react" }],
7645
+ react: [{ category: "framework", name: "react" }],
7446
7646
  "react-dom": [{ category: "framework", name: "react" }],
7447
- "next": [{ category: "framework", name: "next" }],
7448
- "vue": [{ category: "framework", name: "vue" }],
7449
- "nuxt": [{ category: "framework", name: "nuxt" }],
7450
- "svelte": [{ category: "framework", name: "svelte" }],
7647
+ next: [{ category: "framework", name: "next" }],
7648
+ vue: [{ category: "framework", name: "vue" }],
7649
+ nuxt: [{ category: "framework", name: "nuxt" }],
7650
+ svelte: [{ category: "framework", name: "svelte" }],
7451
7651
  "@sveltejs/kit": [{ category: "framework", name: "sveltekit" }],
7452
7652
  "solid-js": [{ category: "framework", name: "solid" }],
7453
7653
  "@angular/core": [{ category: "framework", name: "angular" }],
7454
- "astro": [{ category: "framework", name: "astro" }],
7455
- "remix": [{ category: "framework", name: "remix" }],
7654
+ astro: [{ category: "framework", name: "astro" }],
7655
+ remix: [{ category: "framework", name: "remix" }],
7456
7656
  // Backend Frameworks
7457
- "express": [{ category: "framework", name: "express" }],
7458
- "fastify": [{ category: "framework", name: "fastify" }],
7459
- "hono": [{ category: "framework", name: "hono" }],
7460
- "koa": [{ category: "framework", name: "koa" }],
7657
+ express: [{ category: "framework", name: "express" }],
7658
+ fastify: [{ category: "framework", name: "fastify" }],
7659
+ hono: [{ category: "framework", name: "hono" }],
7660
+ koa: [{ category: "framework", name: "koa" }],
7461
7661
  "@nestjs/core": [{ category: "framework", name: "nestjs" }],
7462
- "hapi": [{ category: "framework", name: "hapi" }],
7662
+ hapi: [{ category: "framework", name: "hapi" }],
7463
7663
  // Testing
7464
- "vitest": [{ category: "tooling", name: "vitest" }, { category: "category", name: "testing" }],
7465
- "jest": [{ category: "tooling", name: "jest" }, { category: "category", name: "testing" }],
7466
- "@testing-library/react": [{ category: "tooling", name: "testing-library" }],
7467
- "playwright": [{ category: "tooling", name: "playwright" }, { category: "category", name: "e2e" }],
7468
- "cypress": [{ category: "tooling", name: "cypress" }, { category: "category", name: "e2e" }],
7664
+ vitest: [
7665
+ { category: "tool", name: "vitest" },
7666
+ { category: "testing", name: "testing" }
7667
+ ],
7668
+ jest: [
7669
+ { category: "tool", name: "jest" },
7670
+ { category: "testing", name: "testing" }
7671
+ ],
7672
+ "@testing-library/react": [{ category: "tool", name: "testing-library" }],
7673
+ playwright: [
7674
+ { category: "tool", name: "playwright" },
7675
+ { category: "testing", name: "e2e" }
7676
+ ],
7677
+ cypress: [
7678
+ { category: "tool", name: "cypress" },
7679
+ { category: "testing", name: "e2e" }
7680
+ ],
7469
7681
  // State Management
7470
- "zustand": [{ category: "tooling", name: "zustand" }, { category: "category", name: "state" }],
7471
- "redux": [{ category: "tooling", name: "redux" }, { category: "category", name: "state" }],
7472
- "@reduxjs/toolkit": [{ category: "tooling", name: "redux-toolkit" }, { category: "category", name: "state" }],
7473
- "jotai": [{ category: "tooling", name: "jotai" }, { category: "category", name: "state" }],
7474
- "recoil": [{ category: "tooling", name: "recoil" }, { category: "category", name: "state" }],
7475
- "mobx": [{ category: "tooling", name: "mobx" }, { category: "category", name: "state" }],
7476
- "pinia": [{ category: "tooling", name: "pinia" }, { category: "category", name: "state" }],
7477
- "xstate": [{ category: "tooling", name: "xstate" }, { category: "category", name: "state-machine" }],
7682
+ zustand: [
7683
+ { category: "tool", name: "zustand" },
7684
+ { category: "state", name: "state" }
7685
+ ],
7686
+ redux: [
7687
+ { category: "tool", name: "redux" },
7688
+ { category: "state", name: "state" }
7689
+ ],
7690
+ "@reduxjs/toolkit": [
7691
+ { category: "tool", name: "redux-toolkit" },
7692
+ { category: "state", name: "state" }
7693
+ ],
7694
+ jotai: [
7695
+ { category: "tool", name: "jotai" },
7696
+ { category: "state", name: "state" }
7697
+ ],
7698
+ recoil: [
7699
+ { category: "tool", name: "recoil" },
7700
+ { category: "state", name: "state" }
7701
+ ],
7702
+ mobx: [
7703
+ { category: "tool", name: "mobx" },
7704
+ { category: "state", name: "state" }
7705
+ ],
7706
+ pinia: [
7707
+ { category: "tool", name: "pinia" },
7708
+ { category: "state", name: "state" }
7709
+ ],
7710
+ xstate: [
7711
+ { category: "tool", name: "xstate" },
7712
+ { category: "state", name: "state-machine" }
7713
+ ],
7478
7714
  // Database & ORM
7479
- "prisma": [{ category: "tooling", name: "prisma" }, { category: "category", name: "database" }],
7480
- "@prisma/client": [{ category: "tooling", name: "prisma" }, { category: "category", name: "database" }],
7481
- "drizzle-orm": [{ category: "tooling", name: "drizzle" }, { category: "category", name: "database" }],
7482
- "typeorm": [{ category: "tooling", name: "typeorm" }, { category: "category", name: "database" }],
7483
- "mongoose": [{ category: "tooling", name: "mongoose" }, { category: "category", name: "mongodb" }],
7484
- "knex": [{ category: "tooling", name: "knex" }, { category: "category", name: "database" }],
7485
- "sequelize": [{ category: "tooling", name: "sequelize" }, { category: "category", name: "database" }],
7715
+ prisma: [
7716
+ { category: "tool", name: "prisma" },
7717
+ { category: "database", name: "database" }
7718
+ ],
7719
+ "@prisma/client": [
7720
+ { category: "tool", name: "prisma" },
7721
+ { category: "database", name: "database" }
7722
+ ],
7723
+ "drizzle-orm": [
7724
+ { category: "tool", name: "drizzle" },
7725
+ { category: "database", name: "database" }
7726
+ ],
7727
+ typeorm: [
7728
+ { category: "tool", name: "typeorm" },
7729
+ { category: "database", name: "database" }
7730
+ ],
7731
+ mongoose: [
7732
+ { category: "tool", name: "mongoose" },
7733
+ { category: "database", name: "mongodb" }
7734
+ ],
7735
+ knex: [
7736
+ { category: "tool", name: "knex" },
7737
+ { category: "database", name: "database" }
7738
+ ],
7739
+ sequelize: [
7740
+ { category: "tool", name: "sequelize" },
7741
+ { category: "database", name: "database" }
7742
+ ],
7486
7743
  // Authentication
7487
- "next-auth": [{ category: "tooling", name: "next-auth" }, { category: "category", name: "auth" }],
7488
- "@auth/core": [{ category: "tooling", name: "authjs" }, { category: "category", name: "auth" }],
7489
- "passport": [{ category: "tooling", name: "passport" }, { category: "category", name: "auth" }],
7490
- "lucia": [{ category: "tooling", name: "lucia" }, { category: "category", name: "auth" }],
7491
- "@clerk/nextjs": [{ category: "tooling", name: "clerk" }, { category: "category", name: "auth" }],
7744
+ "next-auth": [
7745
+ { category: "tool", name: "next-auth" },
7746
+ { category: "auth", name: "auth" }
7747
+ ],
7748
+ "@auth/core": [
7749
+ { category: "tool", name: "authjs" },
7750
+ { category: "auth", name: "auth" }
7751
+ ],
7752
+ passport: [
7753
+ { category: "tool", name: "passport" },
7754
+ { category: "auth", name: "auth" }
7755
+ ],
7756
+ lucia: [
7757
+ { category: "tool", name: "lucia" },
7758
+ { category: "auth", name: "auth" }
7759
+ ],
7760
+ "@clerk/nextjs": [
7761
+ { category: "tool", name: "clerk" },
7762
+ { category: "auth", name: "auth" }
7763
+ ],
7492
7764
  // UI Libraries
7493
- "@radix-ui/react-dialog": [{ category: "tooling", name: "radix-ui" }],
7494
- "@radix-ui/react-dropdown-menu": [{ category: "tooling", name: "radix-ui" }],
7495
- "@shadcn/ui": [{ category: "tooling", name: "shadcn" }],
7496
- "@chakra-ui/react": [{ category: "tooling", name: "chakra-ui" }],
7497
- "@mantine/core": [{ category: "tooling", name: "mantine" }],
7498
- "@headlessui/react": [{ category: "tooling", name: "headlessui" }],
7499
- "antd": [{ category: "tooling", name: "antd" }],
7500
- "@mui/material": [{ category: "tooling", name: "material-ui" }],
7765
+ "@radix-ui/react-dialog": [{ category: "tool", name: "radix-ui" }],
7766
+ "@radix-ui/react-dropdown-menu": [{ category: "tool", name: "radix-ui" }],
7767
+ "@shadcn/ui": [{ category: "tool", name: "shadcn" }],
7768
+ "@chakra-ui/react": [{ category: "tool", name: "chakra-ui" }],
7769
+ "@mantine/core": [{ category: "tool", name: "mantine" }],
7770
+ "@headlessui/react": [{ category: "tool", name: "headlessui" }],
7771
+ antd: [{ category: "tool", name: "antd" }],
7772
+ "@mui/material": [{ category: "tool", name: "material-ui" }],
7501
7773
  // Styling
7502
- "tailwindcss": [{ category: "tooling", name: "tailwind" }],
7503
- "styled-components": [{ category: "tooling", name: "styled-components" }],
7504
- "@emotion/react": [{ category: "tooling", name: "emotion" }],
7505
- "sass": [{ category: "tooling", name: "sass" }],
7774
+ tailwindcss: [{ category: "tool", name: "tailwind" }],
7775
+ "styled-components": [{ category: "tool", name: "styled-components" }],
7776
+ "@emotion/react": [{ category: "tool", name: "emotion" }],
7777
+ sass: [{ category: "tool", name: "sass" }],
7506
7778
  // API & Data Fetching
7507
- "@tanstack/react-query": [{ category: "tooling", name: "tanstack-query" }, { category: "category", name: "data-fetching" }],
7508
- "swr": [{ category: "tooling", name: "swr" }, { category: "category", name: "data-fetching" }],
7509
- "@trpc/server": [{ category: "tooling", name: "trpc" }, { category: "category", name: "api" }],
7510
- "@trpc/client": [{ category: "tooling", name: "trpc" }, { category: "category", name: "api" }],
7511
- "graphql": [{ category: "tooling", name: "graphql" }, { category: "category", name: "api" }],
7512
- "@apollo/client": [{ category: "tooling", name: "apollo" }, { category: "category", name: "graphql" }],
7513
- "axios": [{ category: "tooling", name: "axios" }],
7779
+ "@tanstack/react-query": [
7780
+ { category: "tool", name: "tanstack-query" },
7781
+ { category: "api", name: "data-fetching" }
7782
+ ],
7783
+ swr: [
7784
+ { category: "tool", name: "swr" },
7785
+ { category: "api", name: "data-fetching" }
7786
+ ],
7787
+ "@trpc/server": [
7788
+ { category: "tool", name: "trpc" },
7789
+ { category: "api", name: "api" }
7790
+ ],
7791
+ "@trpc/client": [
7792
+ { category: "tool", name: "trpc" },
7793
+ { category: "api", name: "api" }
7794
+ ],
7795
+ graphql: [
7796
+ { category: "tool", name: "graphql" },
7797
+ { category: "api", name: "api" }
7798
+ ],
7799
+ "@apollo/client": [
7800
+ { category: "tool", name: "apollo" },
7801
+ { category: "api", name: "graphql" }
7802
+ ],
7803
+ axios: [{ category: "tool", name: "axios" }],
7514
7804
  // Form Libraries
7515
- "react-hook-form": [{ category: "tooling", name: "react-hook-form" }, { category: "category", name: "forms" }],
7516
- "formik": [{ category: "tooling", name: "formik" }, { category: "category", name: "forms" }],
7517
- "@tanstack/react-form": [{ category: "tooling", name: "tanstack-form" }, { category: "category", name: "forms" }],
7805
+ "react-hook-form": [
7806
+ { category: "tool", name: "react-hook-form" },
7807
+ { category: "feature", name: "forms" }
7808
+ ],
7809
+ formik: [
7810
+ { category: "tool", name: "formik" },
7811
+ { category: "feature", name: "forms" }
7812
+ ],
7813
+ "@tanstack/react-form": [
7814
+ { category: "tool", name: "tanstack-form" },
7815
+ { category: "feature", name: "forms" }
7816
+ ],
7518
7817
  // Validation
7519
- "zod": [{ category: "tooling", name: "zod" }, { category: "category", name: "validation" }],
7520
- "yup": [{ category: "tooling", name: "yup" }, { category: "category", name: "validation" }],
7521
- "valibot": [{ category: "tooling", name: "valibot" }, { category: "category", name: "validation" }],
7818
+ zod: [
7819
+ { category: "tool", name: "zod" },
7820
+ { category: "feature", name: "validation" }
7821
+ ],
7822
+ yup: [
7823
+ { category: "tool", name: "yup" },
7824
+ { category: "feature", name: "validation" }
7825
+ ],
7826
+ valibot: [
7827
+ { category: "tool", name: "valibot" },
7828
+ { category: "feature", name: "validation" }
7829
+ ],
7522
7830
  // Build Tools
7523
- "vite": [{ category: "tooling", name: "vite" }],
7524
- "esbuild": [{ category: "tooling", name: "esbuild" }],
7525
- "tsup": [{ category: "tooling", name: "tsup" }],
7526
- "webpack": [{ category: "tooling", name: "webpack" }],
7527
- "turbo": [{ category: "tooling", name: "turborepo" }],
7831
+ vite: [{ category: "tool", name: "vite" }],
7832
+ esbuild: [{ category: "tool", name: "esbuild" }],
7833
+ tsup: [{ category: "tool", name: "tsup" }],
7834
+ webpack: [{ category: "tool", name: "webpack" }],
7835
+ turbo: [{ category: "tool", name: "turborepo" }],
7528
7836
  // Utilities
7529
- "lodash": [{ category: "tooling", name: "lodash" }],
7530
- "date-fns": [{ category: "tooling", name: "date-fns" }],
7531
- "dayjs": [{ category: "tooling", name: "dayjs" }],
7532
- "uuid": [{ category: "tooling", name: "uuid" }],
7533
- "nanoid": [{ category: "tooling", name: "nanoid" }],
7837
+ lodash: [{ category: "tool", name: "lodash" }],
7838
+ "date-fns": [{ category: "tool", name: "date-fns" }],
7839
+ dayjs: [{ category: "tool", name: "dayjs" }],
7840
+ uuid: [{ category: "tool", name: "uuid" }],
7841
+ nanoid: [{ category: "tool", name: "nanoid" }],
7534
7842
  // CLI & Developer Tools
7535
- "commander": [{ category: "tooling", name: "commander" }, { category: "category", name: "cli" }],
7536
- "yargs": [{ category: "tooling", name: "yargs" }, { category: "category", name: "cli" }],
7537
- "@clack/prompts": [{ category: "tooling", name: "clack" }, { category: "category", name: "cli" }],
7538
- "inquirer": [{ category: "tooling", name: "inquirer" }, { category: "category", name: "cli" }],
7539
- "chalk": [{ category: "tooling", name: "chalk" }],
7843
+ commander: [
7844
+ { category: "tool", name: "commander" },
7845
+ { category: "feature", name: "cli" }
7846
+ ],
7847
+ yargs: [
7848
+ { category: "tool", name: "yargs" },
7849
+ { category: "feature", name: "cli" }
7850
+ ],
7851
+ "@clack/prompts": [
7852
+ { category: "tool", name: "clack" },
7853
+ { category: "feature", name: "cli" }
7854
+ ],
7855
+ inquirer: [
7856
+ { category: "tool", name: "inquirer" },
7857
+ { category: "feature", name: "cli" }
7858
+ ],
7859
+ chalk: [{ category: "tool", name: "chalk" }],
7540
7860
  // Runtime & Languages
7541
- "typescript": [{ category: "language", name: "typescript" }]
7861
+ typescript: [{ category: "language", name: "typescript" }]
7542
7862
  };
7543
7863
  function inferPatternName(filePaths) {
7544
7864
  if (filePaths.length === 1) {
@@ -7552,7 +7872,9 @@ function inferPatternName(filePaths) {
7552
7872
  const dirName = path3.basename(uniqueDirs[0]);
7553
7873
  return dirName.replace(/[-_]/g, " ").replace(/([A-Z])/g, " $1").trim().split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ") + " Pattern";
7554
7874
  }
7555
- const fileNames = filePaths.map((p13) => path3.basename(p13).replace(/\.[^.]+$/, ""));
7875
+ const fileNames = filePaths.map(
7876
+ (p13) => path3.basename(p13).replace(/\.[^.]+$/, "")
7877
+ );
7556
7878
  if (fileNames.length > 0) {
7557
7879
  let commonPrefix = fileNames[0];
7558
7880
  for (const name of fileNames.slice(1)) {
@@ -7619,28 +7941,28 @@ function inferTagsFromContent(filePaths) {
7619
7941
  } else if (ext === ".rs") {
7620
7942
  addTag("language", "rust");
7621
7943
  } else if (ext === ".css" || ext === ".scss" || ext === ".sass") {
7622
- addTag("tooling", "css");
7944
+ addTag("file-type", "css");
7623
7945
  }
7624
7946
  if (ext === ".tsx" || ext === ".jsx") {
7625
7947
  addTag("framework", "react");
7626
7948
  }
7627
7949
  if (fileName.includes(".test.") || fileName.includes(".spec.") || fileName.startsWith("test_")) {
7628
- addTag("category", "testing");
7950
+ addTag("testing", "testing");
7629
7951
  }
7630
7952
  if (fileName.includes("config") || fileName.startsWith(".")) {
7631
- addTag("category", "configuration");
7953
+ addTag("file-type", "configuration");
7632
7954
  }
7633
7955
  if (filePath.includes("/components/") || filePath.includes("\\components\\")) {
7634
- addTag("category", "component");
7956
+ addTag("ui", "component");
7635
7957
  }
7636
7958
  if (filePath.includes("/hooks/") || filePath.includes("\\hooks\\") || fileName.startsWith("use")) {
7637
- addTag("category", "hooks");
7959
+ addTag("pattern", "hooks");
7638
7960
  }
7639
7961
  if (filePath.includes("/api/") || filePath.includes("\\api\\") || filePath.includes("/routes/")) {
7640
- addTag("category", "api");
7962
+ addTag("api", "api");
7641
7963
  }
7642
7964
  if (filePath.includes("/utils/") || filePath.includes("\\utils\\") || filePath.includes("/lib/")) {
7643
- addTag("category", "utilities");
7965
+ addTag("library", "utilities");
7644
7966
  }
7645
7967
  }
7646
7968
  return tags;
@@ -7720,7 +8042,8 @@ async function learnCaptureCommand(paths, options) {
7720
8042
  placeholder: inferredName,
7721
8043
  initialValue: inferredName,
7722
8044
  validate: (value) => {
7723
- if (!value || value.length < 3) return "Name must be at least 3 characters";
8045
+ if (!value || value.length < 3)
8046
+ return "Name must be at least 3 characters";
7724
8047
  if (value.length > 100) return "Name must be less than 100 characters";
7725
8048
  return void 0;
7726
8049
  }
@@ -7737,8 +8060,10 @@ async function learnCaptureCommand(paths, options) {
7737
8060
  message: "Description:",
7738
8061
  placeholder: "What does this pattern provide?",
7739
8062
  validate: (value) => {
7740
- if (!value || value.length < 10) return "Description must be at least 10 characters";
7741
- if (value.length > 500) return "Description must be less than 500 characters";
8063
+ if (!value || value.length < 10)
8064
+ return "Description must be at least 10 characters";
8065
+ if (value.length > 500)
8066
+ return "Description must be less than 500 characters";
7742
8067
  return void 0;
7743
8068
  }
7744
8069
  });
@@ -7796,7 +8121,18 @@ async function learnCaptureCommand(paths, options) {
7796
8121
  for (const file of files) {
7797
8122
  languageCounts[file.language] = (languageCounts[file.language] || 0) + 1;
7798
8123
  }
7799
- const primaryLanguage = Object.entries(languageCounts).sort((a, b) => b[1] - a[1])[0]?.[0] || "typescript";
8124
+ const detectedLanguage = Object.entries(languageCounts).sort((a, b) => b[1] - a[1])[0]?.[0] || "typescript";
8125
+ const validLanguages = [
8126
+ "typescript",
8127
+ "javascript",
8128
+ "python",
8129
+ "go",
8130
+ "rust",
8131
+ "other"
8132
+ ];
8133
+ const primaryLanguage = validLanguages.includes(
8134
+ detectedLanguage
8135
+ ) ? detectedLanguage : "other";
7800
8136
  const now = (/* @__PURE__ */ new Date()).toISOString();
7801
8137
  const contributorManager = new ContributorManager2(cwd);
7802
8138
  const contributorResult = await contributorManager.getOrCreateId();
@@ -7806,6 +8142,13 @@ async function learnCaptureCommand(paths, options) {
7806
8142
  purpose: `${f.language} file`,
7807
8143
  content: f.content
7808
8144
  }));
8145
+ const uniqueDirs = [
8146
+ ...new Set(files.map((f) => path3.dirname(f.path)).filter((d) => d !== "."))
8147
+ ];
8148
+ const directories = uniqueDirs.map((dir) => ({
8149
+ path: dir,
8150
+ purpose: `Directory for ${path3.basename(dir)} files`
8151
+ }));
7809
8152
  const blueprint = {
7810
8153
  id: crypto.randomUUID(),
7811
8154
  name,
@@ -7820,7 +8163,7 @@ async function learnCaptureCommand(paths, options) {
7820
8163
  devDependencies: []
7821
8164
  },
7822
8165
  structure: {
7823
- directories: [...new Set(files.map((f) => path3.dirname(f.path)).filter((d) => d !== "."))],
8166
+ directories,
7824
8167
  keyFiles
7825
8168
  },
7826
8169
  setup: {
@@ -7869,7 +8212,9 @@ async function learnCaptureCommand(paths, options) {
7869
8212
  console.log(chalk20.dim(`Name: ${name}`));
7870
8213
  console.log(chalk20.dim(`Files: ${files.length}`));
7871
8214
  console.log(chalk20.dim(`Tags: ${formatTags(uniqueTags)}`));
7872
- console.log(chalk20.dim(`Path: .workflow/patterns/blueprints/${blueprint.id}.json`));
8215
+ console.log(
8216
+ chalk20.dim(`Path: .workflow/patterns/blueprints/${blueprint.id}.json`)
8217
+ );
7873
8218
  console.log(chalk20.dim(`
7874
8219
  To apply this pattern:`));
7875
8220
  console.log(chalk20.cyan(` pnpm workflow:learn:apply ${blueprint.id}`));
@@ -7898,7 +8243,9 @@ async function learnAnalyzeCommand(options) {
7898
8243
  const store = new PatternStore2(cwd);
7899
8244
  await store.initialize();
7900
8245
  const verbose = options.verbose ?? false;
7901
- console.log(chalk20.cyan("\n\u{1F50D} Analyzing Codebase for Learning Opportunities\n"));
8246
+ console.log(
8247
+ chalk20.cyan("\n\u{1F50D} Analyzing Codebase for Learning Opportunities\n")
8248
+ );
7902
8249
  const fixResult = await store.listFixPatterns({});
7903
8250
  const bpResult = await store.listBlueprints({});
7904
8251
  const existingPatterns = [
@@ -7963,8 +8310,12 @@ async function learnAnalyzeCommand(options) {
7963
8310
  console.log(chalk20.dim("\n Your patterns seem well-captured!"));
7964
8311
  return;
7965
8312
  }
7966
- console.log(chalk20.bold(` Found ${opportunities.length} potential learning opportunities:
7967
- `));
8313
+ console.log(
8314
+ chalk20.bold(
8315
+ ` Found ${opportunities.length} potential learning opportunities:
8316
+ `
8317
+ )
8318
+ );
7968
8319
  for (const opp of opportunities) {
7969
8320
  const icon = opp.type === "blueprint" ? "\u{1F4D0}" : "\u{1F527}";
7970
8321
  console.log(` ${icon} ${chalk20.green(opp.name)}`);
@@ -8072,7 +8423,9 @@ async function learnImportCommand(file, options) {
8072
8423
  let importData;
8073
8424
  try {
8074
8425
  if (file.endsWith(".yaml") || file.endsWith(".yml")) {
8075
- console.log(chalk20.yellow(" YAML import not fully supported, treating as JSON"));
8426
+ console.log(
8427
+ chalk20.yellow(" YAML import not fully supported, treating as JSON")
8428
+ );
8076
8429
  }
8077
8430
  importData = JSON.parse(content);
8078
8431
  } catch {
@@ -8095,7 +8448,9 @@ async function learnImportCommand(file, options) {
8095
8448
  console.log(chalk20.dim(` Would import fix: ${fix.name} (${fix.id})`));
8096
8449
  }
8097
8450
  for (const bp of blueprints) {
8098
- console.log(chalk20.dim(` Would import blueprint: ${bp.name} (${bp.id})`));
8451
+ console.log(
8452
+ chalk20.dim(` Would import blueprint: ${bp.name} (${bp.id})`)
8453
+ );
8099
8454
  }
8100
8455
  return;
8101
8456
  }
@@ -8148,8 +8503,12 @@ async function learnCleanCommand(options) {
8148
8503
  if (!cleanDeprecated && !cleanStale && !cleanAll) {
8149
8504
  console.log(chalk20.yellow(" Specify what to clean:"));
8150
8505
  console.log(chalk20.dim(" --deprecated Remove deprecated patterns"));
8151
- console.log(chalk20.dim(" --stale Remove patterns not used in 90+ days"));
8152
- console.log(chalk20.dim(" --all Remove all patterns (use with caution!)"));
8506
+ console.log(
8507
+ chalk20.dim(" --stale Remove patterns not used in 90+ days")
8508
+ );
8509
+ console.log(
8510
+ chalk20.dim(" --all Remove all patterns (use with caution!)")
8511
+ );
8153
8512
  return;
8154
8513
  }
8155
8514
  const toRemove = [];
@@ -8164,23 +8523,48 @@ async function learnCleanCommand(options) {
8164
8523
  if (cleanAll) {
8165
8524
  toRemove.push({ id: fix.id, name: fix.name, type: "fix", reason: "all" });
8166
8525
  } else if (cleanDeprecated && fix.deprecatedAt) {
8167
- toRemove.push({ id: fix.id, name: fix.name, type: "fix", reason: "deprecated" });
8526
+ toRemove.push({
8527
+ id: fix.id,
8528
+ name: fix.name,
8529
+ type: "fix",
8530
+ reason: "deprecated"
8531
+ });
8168
8532
  } else if (cleanStale) {
8169
8533
  const lastUsed = new Date(fix.updatedAt).getTime();
8170
8534
  if (lastUsed < staleThreshold) {
8171
- toRemove.push({ id: fix.id, name: fix.name, type: "fix", reason: "stale" });
8535
+ toRemove.push({
8536
+ id: fix.id,
8537
+ name: fix.name,
8538
+ type: "fix",
8539
+ reason: "stale"
8540
+ });
8172
8541
  }
8173
8542
  }
8174
8543
  }
8175
8544
  for (const bp of blueprints) {
8176
8545
  if (cleanAll) {
8177
- toRemove.push({ id: bp.id, name: bp.name, type: "blueprint", reason: "all" });
8546
+ toRemove.push({
8547
+ id: bp.id,
8548
+ name: bp.name,
8549
+ type: "blueprint",
8550
+ reason: "all"
8551
+ });
8178
8552
  } else if (cleanDeprecated && bp.deprecatedAt) {
8179
- toRemove.push({ id: bp.id, name: bp.name, type: "blueprint", reason: "deprecated" });
8553
+ toRemove.push({
8554
+ id: bp.id,
8555
+ name: bp.name,
8556
+ type: "blueprint",
8557
+ reason: "deprecated"
8558
+ });
8180
8559
  } else if (cleanStale) {
8181
8560
  const lastUsed = new Date(bp.updatedAt).getTime();
8182
8561
  if (lastUsed < staleThreshold) {
8183
- toRemove.push({ id: bp.id, name: bp.name, type: "blueprint", reason: "stale" });
8562
+ toRemove.push({
8563
+ id: bp.id,
8564
+ name: bp.name,
8565
+ type: "blueprint",
8566
+ reason: "stale"
8567
+ });
8184
8568
  }
8185
8569
  }
8186
8570
  }
@@ -8246,7 +8630,10 @@ ${chalk21.bold("Examples:")}
8246
8630
  ).action(() => {
8247
8631
  learnCmd.help();
8248
8632
  });
8249
- learnCmd.command("record").description("Record a new pattern from a successful implementation").option("--name <name>", "Pattern name").option("--description <desc>", "Pattern description").option("--category <cat>", "Category (migration, security, performance, etc.)").option("--framework <fw>", "Framework (next, react, vue, etc.)").option("--version <ver>", "Framework version range").option("--tags <tags>", "Comma-separated tags (category:value)").option("--type <type>", "Pattern type (fix, blueprint)").addHelpText(
8633
+ learnCmd.command("record").description("Record a new pattern from a successful implementation").option("--name <name>", "Pattern name").option("--description <desc>", "Pattern description").option(
8634
+ "--category <cat>",
8635
+ "Category (migration, security, performance, etc.)"
8636
+ ).option("--framework <fw>", "Framework (next, react, vue, etc.)").option("--version <ver>", "Framework version range").option("--tags <tags>", "Comma-separated tags (category:value)").option("--type <type>", "Pattern type (fix, blueprint)").addHelpText(
8250
8637
  "after",
8251
8638
  `
8252
8639
  ${chalk21.bold("Examples:")}
@@ -8276,7 +8663,9 @@ ${chalk21.bold("Examples:")}
8276
8663
  $ workflow learn apply abc123 --framework react ${chalk21.dim("# Override framework")}
8277
8664
  `
8278
8665
  ).action(learnApplyCommand);
8279
- learnCmd.command("capture <paths...>").description("Capture files as a blueprint pattern with auto-inferred metadata").option("--name <name>", "Pattern name (inferred from paths if omitted)").option("--description <desc>", "Pattern description").option("--framework <fw>", "Override inferred framework").option("--tags <tags>", "Additional tags (comma-separated)").option("--dry-run", "Preview what would be captured without saving").addHelpText(
8666
+ learnCmd.command("capture <paths...>").description(
8667
+ "Capture files as a blueprint pattern with auto-inferred metadata"
8668
+ ).option("--name <name>", "Pattern name (inferred from paths if omitted)").option("--description <desc>", "Pattern description").option("--framework <fw>", "Override inferred framework").option("--tags <tags>", "Additional tags (comma-separated)").option("--dry-run", "Preview what would be captured without saving").addHelpText(
8280
8669
  "after",
8281
8670
  `
8282
8671
  ${chalk21.bold("Examples:")}
@@ -8286,7 +8675,9 @@ ${chalk21.bold("Examples:")}
8286
8675
  $ workflow learn capture ./hooks --tags "react,hooks" ${chalk21.dim("# With tags")}
8287
8676
  `
8288
8677
  ).action(learnCaptureCommand);
8289
- learnCmd.command("sync").description("Sync patterns with remote registry (alias for: workflow sync --learn)").option("--push", "Push local patterns to registry").option("--pull", "Pull patterns from registry").option("--dry-run", "Preview without syncing").addHelpText(
8678
+ learnCmd.command("sync").description(
8679
+ "Sync patterns with remote registry (alias for: workflow sync --learn)"
8680
+ ).option("--push", "Push local patterns to registry").option("--pull", "Pull patterns from registry").option("--dry-run", "Preview without syncing").addHelpText(
8290
8681
  "after",
8291
8682
  `
8292
8683
  ${chalk21.bold("Examples:")}
@@ -8300,7 +8691,7 @@ ${chalk21.bold("Pro Tip:")}
8300
8691
  $ workflow sync --all ${chalk21.dim("# Sync everything")}
8301
8692
  `
8302
8693
  ).action(async (options) => {
8303
- const { syncCommand: syncCommand2 } = await import("../sync-ON7M53OC.js");
8694
+ const { syncCommand: syncCommand2 } = await import("../sync-HHQM3GKR.js");
8304
8695
  return syncCommand2({ ...options, learn: true });
8305
8696
  });
8306
8697
  learnCmd.command("config").description("Configure learning settings").option("--enable-sync", "Enable pattern sync").option("--disable-sync", "Disable pattern sync").option("--enable-telemetry", "Enable anonymous telemetry").option("--disable-telemetry", "Disable telemetry").option("--reset-id", "Reset contributor ID").option("--show", "Show current configuration").addHelpText(
@@ -8346,7 +8737,11 @@ ${chalk21.bold("Examples:")}
8346
8737
  $ workflow learn analyze --verbose ${chalk21.dim("# Show paths and details")}
8347
8738
  `
8348
8739
  ).action(learnAnalyzeCommand);
8349
- 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(
8740
+ 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(
8741
+ "-t, --type <type>",
8742
+ "Pattern type to export (fix, blueprint, all)",
8743
+ "all"
8744
+ ).addHelpText(
8350
8745
  "after",
8351
8746
  `
8352
8747
  ${chalk21.bold("Examples:")}
@@ -8374,7 +8769,11 @@ ${chalk21.bold("Examples:")}
8374
8769
  $ workflow learn clean --all --dry-run ${chalk21.dim("# Preview full clean")}
8375
8770
  `
8376
8771
  ).action(learnCleanCommand);
8377
- 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(
8772
+ learnCmd.command("validate").description("Validate pattern files and optionally auto-fix common issues").option(
8773
+ "-t, --type <type>",
8774
+ "Pattern type to validate (fix, blueprint, solution, all)",
8775
+ "all"
8776
+ ).option("-f, --file <path>", "Validate a specific file by path").option("--fix", "Automatically fix common issues").option("-v, --verbose", "Show detailed validation output").addHelpText(
8378
8777
  "after",
8379
8778
  `
8380
8779
  ${chalk21.bold("Examples:")}
@@ -8408,10 +8807,14 @@ async function scopeListCommand() {
8408
8807
  byCategory[cat].push(scope);
8409
8808
  }
8410
8809
  for (const [category, categoryScopes] of Object.entries(byCategory)) {
8411
- console.log(chalk22.bold(` ${category.charAt(0).toUpperCase() + category.slice(1)}:`));
8810
+ console.log(
8811
+ chalk22.bold(` ${category.charAt(0).toUpperCase() + category.slice(1)}:`)
8812
+ );
8412
8813
  for (const scope of categoryScopes) {
8413
8814
  const emoji = scope.emoji || "\u{1F4E6}";
8414
- console.log(` ${emoji} ${chalk22.green(scope.name)} - ${scope.description || "No description"}`);
8815
+ console.log(
8816
+ ` ${emoji} ${chalk22.green(scope.name)} - ${scope.description || "No description"}`
8817
+ );
8415
8818
  }
8416
8819
  console.log("");
8417
8820
  }
@@ -8422,12 +8825,16 @@ async function scopeAddCommand(name, options) {
8422
8825
  \u2795 Adding Scope: ${name}
8423
8826
  `));
8424
8827
  const fs3 = await import("fs");
8425
- const path4 = await import("path");
8828
+ const path5 = await import("path");
8426
8829
  const cwd = process.cwd();
8427
- const configFiles = ["workflow.config.json", "workflow.config.js", ".workflowrc.json"];
8830
+ const configFiles = [
8831
+ "workflow.config.json",
8832
+ "workflow.config.js",
8833
+ ".workflowrc.json"
8834
+ ];
8428
8835
  let configPath = null;
8429
8836
  for (const file of configFiles) {
8430
- const fullPath = path4.join(cwd, file);
8837
+ const fullPath = path5.join(cwd, file);
8431
8838
  if (fs3.existsSync(fullPath)) {
8432
8839
  configPath = fullPath;
8433
8840
  break;
@@ -8465,12 +8872,16 @@ async function scopeRemoveCommand(name) {
8465
8872
  \u2796 Removing Scope: ${name}
8466
8873
  `));
8467
8874
  const fs3 = await import("fs");
8468
- const path4 = await import("path");
8875
+ const path5 = await import("path");
8469
8876
  const cwd = process.cwd();
8470
- const configFiles = ["workflow.config.json", "workflow.config.js", ".workflowrc.json"];
8877
+ const configFiles = [
8878
+ "workflow.config.json",
8879
+ "workflow.config.js",
8880
+ ".workflowrc.json"
8881
+ ];
8471
8882
  let configPath = null;
8472
8883
  for (const file of configFiles) {
8473
- const fullPath = path4.join(cwd, file);
8884
+ const fullPath = path5.join(cwd, file);
8474
8885
  if (fs3.existsSync(fullPath)) {
8475
8886
  configPath = fullPath;
8476
8887
  break;
@@ -8486,7 +8897,9 @@ async function scopeRemoveCommand(name) {
8486
8897
  console.log(chalk22.yellow(" No scopes configured"));
8487
8898
  process.exit(1);
8488
8899
  }
8489
- const index = config.scopes.findIndex((s) => s.name === name);
8900
+ const index = config.scopes.findIndex(
8901
+ (s) => s.name === name
8902
+ );
8490
8903
  if (index === -1) {
8491
8904
  console.log(chalk22.yellow(` Scope "${name}" not found`));
8492
8905
  process.exit(1);
@@ -8497,7 +8910,7 @@ async function scopeRemoveCommand(name) {
8497
8910
  }
8498
8911
  async function scopeSyncCommand(options) {
8499
8912
  console.log(chalk22.bold.cyan("\n\u{1F504} Syncing Scopes\n"));
8500
- const { syncCommand: syncCommand2 } = await import("../sync-ON7M53OC.js");
8913
+ const { syncCommand: syncCommand2 } = await import("../sync-HHQM3GKR.js");
8501
8914
  await syncCommand2({
8502
8915
  ...options,
8503
8916
  scopes: true,
@@ -8510,7 +8923,11 @@ async function scopeAnalyzeCommand() {
8510
8923
  const { execa: execa2 } = await import("execa");
8511
8924
  const cwd = process.cwd();
8512
8925
  try {
8513
- const { stdout } = await execa2("git", ["log", "--oneline", "-50", "--format=%s"], { cwd });
8926
+ const { stdout } = await execa2(
8927
+ "git",
8928
+ ["log", "--oneline", "-50", "--format=%s"],
8929
+ { cwd }
8930
+ );
8514
8931
  const commits = stdout.split("\n").filter(Boolean);
8515
8932
  const config = await loadConfig();
8516
8933
  const scopes = config?.scopes || [];
@@ -8537,13 +8954,19 @@ async function scopeAnalyzeCommand() {
8537
8954
  console.log("");
8538
8955
  const sortedUsage = Object.entries(usage).sort((a, b) => b[1] - a[1]);
8539
8956
  for (const [scope, count] of sortedUsage) {
8540
- const scopeConfig = scopes.find((s) => s.name === scope);
8957
+ const scopeConfig = scopes.find(
8958
+ (s) => s.name === scope
8959
+ );
8541
8960
  const emoji = scopeConfig?.emoji || "\u{1F4E6}";
8542
8961
  const bar = "\u2588".repeat(Math.min(count, 20));
8543
- console.log(` ${emoji} ${chalk22.green(scope.padEnd(15))} ${bar} ${count}`);
8962
+ console.log(
8963
+ ` ${emoji} ${chalk22.green(scope.padEnd(15))} ${bar} ${count}`
8964
+ );
8544
8965
  }
8545
8966
  if (unscoped > 0) {
8546
- console.log(` ${chalk22.yellow("(unscoped)".padEnd(17))} ${"\u2591".repeat(Math.min(unscoped, 20))} ${unscoped}`);
8967
+ console.log(
8968
+ ` ${chalk22.yellow("(unscoped)".padEnd(17))} ${"\u2591".repeat(Math.min(unscoped, 20))} ${unscoped}`
8969
+ );
8547
8970
  }
8548
8971
  const unusedScopes = scopeNames.filter((name) => !usage[name]);
8549
8972
  if (unusedScopes.length > 0) {
@@ -8561,7 +8984,9 @@ async function scopeAnalyzeCommand() {
8561
8984
  console.log("");
8562
8985
  } catch {
8563
8986
  console.log(chalk22.yellow(" Unable to analyze git history"));
8564
- console.log(chalk22.dim(" Make sure you're in a git repository with commit history"));
8987
+ console.log(
8988
+ chalk22.dim(" Make sure you're in a git repository with commit history")
8989
+ );
8565
8990
  }
8566
8991
  }
8567
8992
  function createScopeCommand() {
@@ -8641,15 +9066,261 @@ ${chalk22.bold("Details:")}
8641
9066
  return scopeCmd;
8642
9067
  }
8643
9068
 
9069
+ // src/cli/commands/migrate.ts
9070
+ import chalk23 from "chalk";
9071
+ import * as path4 from "path";
9072
+ import {
9073
+ PatternStore as PatternStore3,
9074
+ PATTERNS_DIR
9075
+ } from "@hawkinside_out/workflow-improvement-tracker";
9076
+ async function migrateCommand(subcommand, options) {
9077
+ if (subcommand === "filenames") {
9078
+ await migrateFilenames(options);
9079
+ } else {
9080
+ console.error(chalk23.red(`Unknown migrate subcommand: ${subcommand}`));
9081
+ console.log(chalk23.dim("\nAvailable subcommands:"));
9082
+ console.log(
9083
+ chalk23.dim(" filenames Migrate pattern files to slugified names")
9084
+ );
9085
+ process.exit(1);
9086
+ }
9087
+ }
9088
+ async function migrateFilenames(options) {
9089
+ const isDryRun = options.dryRun || false;
9090
+ const targetType = options.type || "all";
9091
+ console.log(chalk23.bold.cyan("\n\u{1F4E6} Migrate Pattern Filenames\n"));
9092
+ if (isDryRun) {
9093
+ console.log(chalk23.yellow("\u{1F50D} DRY RUN MODE - No files will be modified\n"));
9094
+ }
9095
+ const cwd = process.cwd();
9096
+ const store = new PatternStore3(cwd);
9097
+ await store.initialize();
9098
+ const fixesPath = path4.join(cwd, PATTERNS_DIR, "fixes");
9099
+ const blueprintsPath = path4.join(cwd, PATTERNS_DIR, "blueprints");
9100
+ const solutionsPath = path4.join(cwd, PATTERNS_DIR, "solutions");
9101
+ function slugify(text8) {
9102
+ const slug = text8.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
9103
+ return slug.substring(0, 50);
9104
+ }
9105
+ function getFilePath(basePath, id, name) {
9106
+ if (name) {
9107
+ const slug = slugify(name);
9108
+ return path4.join(basePath, `${slug}-${id}.json`);
9109
+ }
9110
+ return path4.join(basePath, `${id}.json`);
9111
+ }
9112
+ let totalProcessed = 0;
9113
+ let totalMigrated = 0;
9114
+ let totalFailed = 0;
9115
+ let totalSkipped = 0;
9116
+ const results = [];
9117
+ if (targetType === "fix" || targetType === "all") {
9118
+ console.log(chalk23.bold("Fixes:"));
9119
+ const fixesResult = await store.listFixPatterns({
9120
+ includeDeprecated: true
9121
+ });
9122
+ if (fixesResult.success && fixesResult.data) {
9123
+ for (const fix of fixesResult.data) {
9124
+ totalProcessed++;
9125
+ try {
9126
+ const oldPath = getFilePath(fixesPath, fix.id);
9127
+ const newPath = getFilePath(fixesPath, fix.id, fix.name);
9128
+ if (oldPath === newPath) {
9129
+ console.log(chalk23.dim(` \u2298 ${fix.name} - already migrated`));
9130
+ results.push({
9131
+ type: "fix",
9132
+ name: fix.name,
9133
+ oldPath,
9134
+ newPath,
9135
+ status: "skipped"
9136
+ });
9137
+ totalSkipped++;
9138
+ continue;
9139
+ }
9140
+ if (!isDryRun) {
9141
+ await store.saveFixPattern(fix);
9142
+ }
9143
+ console.log(chalk23.green(` \u2713 ${fix.name}`));
9144
+ console.log(chalk23.dim(` ${oldPath} \u2192 ${newPath}`));
9145
+ results.push({
9146
+ type: "fix",
9147
+ name: fix.name,
9148
+ oldPath,
9149
+ newPath,
9150
+ status: "success"
9151
+ });
9152
+ totalMigrated++;
9153
+ } catch (error) {
9154
+ console.log(chalk23.red(` \u2717 ${fix.name} - ${error}`));
9155
+ results.push({
9156
+ type: "fix",
9157
+ name: fix.name,
9158
+ oldPath: "",
9159
+ newPath: "",
9160
+ status: "failed",
9161
+ error: String(error)
9162
+ });
9163
+ totalFailed++;
9164
+ }
9165
+ }
9166
+ }
9167
+ console.log();
9168
+ }
9169
+ if (targetType === "blueprint" || targetType === "all") {
9170
+ console.log(chalk23.bold("Blueprints:"));
9171
+ const blueprintsResult = await store.listBlueprints({
9172
+ includeDeprecated: true
9173
+ });
9174
+ if (blueprintsResult.success && blueprintsResult.data) {
9175
+ for (const blueprint of blueprintsResult.data) {
9176
+ totalProcessed++;
9177
+ try {
9178
+ const oldPath = getFilePath(blueprintsPath, blueprint.id);
9179
+ const newPath = getFilePath(
9180
+ blueprintsPath,
9181
+ blueprint.id,
9182
+ blueprint.name
9183
+ );
9184
+ if (oldPath === newPath) {
9185
+ console.log(chalk23.dim(` \u2298 ${blueprint.name} - already migrated`));
9186
+ results.push({
9187
+ type: "blueprint",
9188
+ name: blueprint.name,
9189
+ oldPath,
9190
+ newPath,
9191
+ status: "skipped"
9192
+ });
9193
+ totalSkipped++;
9194
+ continue;
9195
+ }
9196
+ if (!isDryRun) {
9197
+ await store.saveBlueprint(blueprint);
9198
+ }
9199
+ console.log(chalk23.green(` \u2713 ${blueprint.name}`));
9200
+ console.log(chalk23.dim(` ${oldPath} \u2192 ${newPath}`));
9201
+ results.push({
9202
+ type: "blueprint",
9203
+ name: blueprint.name,
9204
+ oldPath,
9205
+ newPath,
9206
+ status: "success"
9207
+ });
9208
+ totalMigrated++;
9209
+ } catch (error) {
9210
+ console.log(chalk23.red(` \u2717 ${blueprint.name} - ${error}`));
9211
+ results.push({
9212
+ type: "blueprint",
9213
+ name: blueprint.name,
9214
+ oldPath: "",
9215
+ newPath: "",
9216
+ status: "failed",
9217
+ error: String(error)
9218
+ });
9219
+ totalFailed++;
9220
+ }
9221
+ }
9222
+ }
9223
+ console.log();
9224
+ }
9225
+ if (targetType === "solution" || targetType === "all") {
9226
+ console.log(chalk23.bold("Solutions:"));
9227
+ const solutionsResult = await store.listSolutions({
9228
+ includeDeprecated: true
9229
+ });
9230
+ if (solutionsResult.success && solutionsResult.data) {
9231
+ for (const solution of solutionsResult.data) {
9232
+ totalProcessed++;
9233
+ try {
9234
+ const oldPath = getFilePath(solutionsPath, solution.id);
9235
+ const newPath = getFilePath(
9236
+ solutionsPath,
9237
+ solution.id,
9238
+ solution.name
9239
+ );
9240
+ if (oldPath === newPath) {
9241
+ console.log(chalk23.dim(` \u2298 ${solution.name} - already migrated`));
9242
+ results.push({
9243
+ type: "solution",
9244
+ name: solution.name,
9245
+ oldPath,
9246
+ newPath,
9247
+ status: "skipped"
9248
+ });
9249
+ totalSkipped++;
9250
+ continue;
9251
+ }
9252
+ if (!isDryRun) {
9253
+ await store.saveSolution(solution);
9254
+ }
9255
+ console.log(chalk23.green(` \u2713 ${solution.name}`));
9256
+ console.log(chalk23.dim(` ${oldPath} \u2192 ${newPath}`));
9257
+ results.push({
9258
+ type: "solution",
9259
+ name: solution.name,
9260
+ oldPath,
9261
+ newPath,
9262
+ status: "success"
9263
+ });
9264
+ totalMigrated++;
9265
+ } catch (error) {
9266
+ console.log(chalk23.red(` \u2717 ${solution.name} - ${error}`));
9267
+ results.push({
9268
+ type: "solution",
9269
+ name: solution.name,
9270
+ oldPath: "",
9271
+ newPath: "",
9272
+ status: "failed",
9273
+ error: String(error)
9274
+ });
9275
+ totalFailed++;
9276
+ }
9277
+ }
9278
+ }
9279
+ console.log();
9280
+ }
9281
+ console.log(chalk23.bold("Summary:"));
9282
+ console.log(chalk23.dim(` Total patterns: ${totalProcessed}`));
9283
+ if (totalMigrated > 0) {
9284
+ console.log(chalk23.green(` \u2713 Migrated: ${totalMigrated}`));
9285
+ }
9286
+ if (totalSkipped > 0) {
9287
+ console.log(chalk23.dim(` \u2298 Already migrated: ${totalSkipped}`));
9288
+ }
9289
+ if (totalFailed > 0) {
9290
+ console.log(chalk23.red(` \u2717 Failed: ${totalFailed}`));
9291
+ }
9292
+ if (isDryRun && totalMigrated > 0) {
9293
+ console.log(
9294
+ chalk23.yellow(
9295
+ "\n\u26A0\uFE0F This was a dry run. Run without --dry-run to apply changes."
9296
+ )
9297
+ );
9298
+ } else if (!isDryRun && totalMigrated > 0) {
9299
+ console.log(chalk23.green("\n\u2713 Migration complete!"));
9300
+ } else if (totalSkipped === totalProcessed) {
9301
+ console.log(chalk23.dim("\n\u2713 All patterns already use slugified filenames."));
9302
+ }
9303
+ if (totalFailed > 0) {
9304
+ console.log(
9305
+ chalk23.red(
9306
+ "\n\u26A0\uFE0F Some patterns failed to migrate. Check the errors above."
9307
+ )
9308
+ );
9309
+ process.exit(1);
9310
+ }
9311
+ }
9312
+
8644
9313
  // src/cli/index.ts
8645
9314
  var __filename4 = fileURLToPath4(import.meta.url);
8646
9315
  var __dirname4 = dirname5(__filename4);
8647
9316
  var packageJson = JSON.parse(
8648
- readFileSync3(join12(__dirname4, "../../package.json"), "utf-8")
9317
+ readFileSync3(join13(__dirname4, "../../package.json"), "utf-8")
8649
9318
  );
8650
9319
  function deprecationWarning(oldCmd, newCmd) {
8651
- console.warn(chalk23.yellow(`\u26A0\uFE0F "${oldCmd}" is deprecated and will be removed in v2.0.`));
8652
- console.warn(chalk23.yellow(` Use: ${newCmd}
9320
+ console.warn(
9321
+ chalk24.yellow(`\u26A0\uFE0F "${oldCmd}" is deprecated and will be removed in v2.0.`)
9322
+ );
9323
+ console.warn(chalk24.yellow(` Use: ${newCmd}
8653
9324
  `));
8654
9325
  }
8655
9326
  var program = new Command7();
@@ -8660,33 +9331,49 @@ program.addCommand(createDocsCommand());
8660
9331
  program.addCommand(createSolutionCommand());
8661
9332
  program.addCommand(createLearnCommand());
8662
9333
  program.addCommand(createScopeCommand());
9334
+ program.command("migrate <subcommand>").description("Migrate patterns and configurations").option("--dry-run", "Preview without making changes").option(
9335
+ "--type <type>",
9336
+ "Pattern type to migrate (fix, blueprint, solution, or all)",
9337
+ "all"
9338
+ ).addHelpText(
9339
+ "after",
9340
+ `
9341
+ ${chalk24.bold("Subcommands:")}
9342
+ filenames ${chalk24.dim("# Migrate to slugified filenames")}
9343
+
9344
+ ${chalk24.bold("Examples:")}
9345
+ $ workflow migrate filenames --dry-run ${chalk24.dim("# Preview migration")}
9346
+ $ workflow migrate filenames ${chalk24.dim("# Migrate all patterns")}
9347
+ $ workflow migrate filenames --type fix ${chalk24.dim("# Migrate only fixes")}
9348
+ `
9349
+ ).action(migrateCommand);
8663
9350
  program.addCommand(createHooksCommand());
8664
9351
  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").option("--enable-sync", "Enable pattern sync").option("--disable-sync", "Disable pattern sync").option("--include-private", "Include private patterns in push").addHelpText(
8665
9352
  "after",
8666
9353
  `
8667
- ${chalk23.bold("Examples:")}
8668
- ${chalk23.dim("# Enable sync")}
9354
+ ${chalk24.bold("Examples:")}
9355
+ ${chalk24.dim("# Enable sync")}
8669
9356
  $ workflow sync --enable-sync
8670
9357
 
8671
- ${chalk23.dim("# Disable sync")}
9358
+ ${chalk24.dim("# Disable sync")}
8672
9359
  $ workflow sync --disable-sync
8673
9360
 
8674
- ${chalk23.dim("# Interactive sync (prompts for direction)")}
9361
+ ${chalk24.dim("# Interactive sync (prompts for direction)")}
8675
9362
  $ workflow sync
8676
9363
 
8677
- ${chalk23.dim("# Push local patterns to registry")}
9364
+ ${chalk24.dim("# Push local patterns to registry")}
8678
9365
  $ workflow sync --push
8679
9366
 
8680
- ${chalk23.dim("# Pull patterns from registry")}
9367
+ ${chalk24.dim("# Pull patterns from registry")}
8681
9368
  $ workflow sync --pull
8682
9369
 
8683
- ${chalk23.dim("# Sync solutions only")}
9370
+ ${chalk24.dim("# Sync solutions only")}
8684
9371
  $ workflow sync --solutions --push
8685
9372
 
8686
- ${chalk23.dim("# Include private patterns in push")}
9373
+ ${chalk24.dim("# Include private patterns in push")}
8687
9374
  $ workflow sync --solutions --push --include-private
8688
9375
 
8689
- ${chalk23.dim("# Preview what would be synced")}
9376
+ ${chalk24.dim("# Preview what would be synced")}
8690
9377
  $ workflow sync --all --dry-run
8691
9378
  `
8692
9379
  ).action(syncCommand);
@@ -8700,28 +9387,30 @@ program.command("validate <type> [value]").description("Validate branch name, co
8700
9387
  ).action(validateCommand);
8701
9388
  program.command("config <action> [key] [value]").description("Manage workflow configuration").action(configCommand);
8702
9389
  program.command("config:fix").description("Automatically fix common configuration validation issues").action(async () => {
8703
- const chalk24 = (await import("chalk")).default;
9390
+ const chalk25 = (await import("chalk")).default;
8704
9391
  const { autoFixConfigFile: autoFixConfigFile2 } = await import("../config/index.js");
8705
- console.log(chalk24.bold.cyan("\n\u{1F527} Workflow Configuration Auto-Fix\n"));
9392
+ console.log(chalk25.bold.cyan("\n\u{1F527} Workflow Configuration Auto-Fix\n"));
8706
9393
  const result = await autoFixConfigFile2();
8707
9394
  if (result.success) {
8708
9395
  if (result.changes.length === 0) {
8709
- console.log(chalk24.green("\u2713 Configuration is already valid!"));
9396
+ console.log(chalk25.green("\u2713 Configuration is already valid!"));
8710
9397
  } else {
8711
- console.log(chalk24.green("\u2713 Configuration fixed successfully!\n"));
8712
- console.log(chalk24.dim("Changes made:"));
9398
+ console.log(chalk25.green("\u2713 Configuration fixed successfully!\n"));
9399
+ console.log(chalk25.dim("Changes made:"));
8713
9400
  for (const change of result.changes) {
8714
- console.log(chalk24.dim(` \u2022 ${change}`));
9401
+ console.log(chalk25.dim(` \u2022 ${change}`));
8715
9402
  }
8716
9403
  console.log();
8717
9404
  }
8718
9405
  process.exit(0);
8719
9406
  } else {
8720
9407
  if (result.configPath) {
8721
- console.log(chalk24.red(`\u2717 Failed to fix configuration: ${result.error}`));
9408
+ console.log(
9409
+ chalk25.red(`\u2717 Failed to fix configuration: ${result.error}`)
9410
+ );
8722
9411
  } else {
8723
- console.log(chalk24.red("\u2717 No workflow configuration file found"));
8724
- console.log(chalk24.yellow(" Run: workflow init"));
9412
+ console.log(chalk25.red("\u2717 No workflow configuration file found"));
9413
+ console.log(chalk25.yellow(" Run: workflow init"));
8725
9414
  }
8726
9415
  process.exit(1);
8727
9416
  }
@@ -8755,7 +9444,10 @@ program.command("scope:migrate", { hidden: true }).description("[DEPRECATED] Use
8755
9444
  deprecationWarning("workflow scope:migrate", "workflow scope migrate");
8756
9445
  return scopeMigrateCommand(options);
8757
9446
  });
8758
- 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);
9447
+ 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").option(
9448
+ "--no-platform-checks",
9449
+ "Skip platform-specific checks (Shopify, WordPress, etc.)"
9450
+ ).action(verifyCommand);
8759
9451
  program.command("pre-commit").description("Run pre-commit checks (alias for verify --fix --staged)").option("--dry-run", "Preview fixes without applying them").action(preCommitCommand);
8760
9452
  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) => {
8761
9453
  deprecationWarning("workflow auto-setup", "workflow setup auto");
@@ -8766,7 +9458,10 @@ program.command("advisory", { hidden: true }).description("[DEPRECATED] Use: wor
8766
9458
  return advisoryCommand(options);
8767
9459
  });
8768
9460
  program.command("generate-instructions", { hidden: true }).description("[DEPRECATED] Use: workflow docs generate").option("--force", "Regenerate without confirmation").action(async (options) => {
8769
- deprecationWarning("workflow generate-instructions", "workflow docs generate");
9461
+ deprecationWarning(
9462
+ "workflow generate-instructions",
9463
+ "workflow docs generate"
9464
+ );
8770
9465
  return docsGenerateCommand(options);
8771
9466
  });
8772
9467
  program.command("update-templates", { hidden: true }).description("[DEPRECATED] Use: workflow docs update").option("--force", "Overwrite existing template files").option("--skip", "Skip the update").action(async (options) => {
@@ -8824,7 +9519,10 @@ program.command("learn:validate", { hidden: true }).description("[DEPRECATED] Us
8824
9519
  return learnValidateCommand(options);
8825
9520
  });
8826
9521
  program.command("solution:capture", { hidden: true }).description("[DEPRECATED] Use: workflow solution capture").option("--name <name>", "Solution name").option("--description <desc>", "Solution description").option("--category <cat>", "Category").option("--keywords <kw>", "Comma-separated keywords").option("--path <path>", "Path to the solution directory").option("--anonymize", "Anonymize sensitive data").option("--private", "Keep solution private").action(async (options) => {
8827
- deprecationWarning("workflow solution:capture", "workflow solution capture");
9522
+ deprecationWarning(
9523
+ "workflow solution:capture",
9524
+ "workflow solution capture"
9525
+ );
8828
9526
  return solutionCaptureCommand(options);
8829
9527
  });
8830
9528
  program.command("solution:search <query>", { hidden: true }).description("[DEPRECATED] Use: workflow solution search").option("--category <cat>", "Filter by category").option("--framework <fw>", "Filter by framework").option("--limit <n>", "Maximum results", "10").action(async (query, options) => {
@@ -8840,7 +9538,10 @@ program.command("solution:apply <solutionId>", { hidden: true }).description("[D
8840
9538
  return solutionApplyCommand(solutionId, options);
8841
9539
  });
8842
9540
  program.command("solution:deprecate <solutionId> <reason>", { hidden: true }).description("[DEPRECATED] Use: workflow solution deprecate").action(async (solutionId, reason) => {
8843
- deprecationWarning("workflow solution:deprecate", "workflow solution deprecate");
9541
+ deprecationWarning(
9542
+ "workflow solution:deprecate",
9543
+ "workflow solution deprecate"
9544
+ );
8844
9545
  return solutionDeprecateCommand(solutionId, reason);
8845
9546
  });
8846
9547
  program.command("solution:stats", { hidden: true }).description("[DEPRECATED] Use: workflow solution stats").action(async () => {