workflow-agent-cli 2.9.0 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -19,8 +19,8 @@ import {
19
19
  import {
20
20
  hasConfig,
21
21
  loadConfig,
22
- validateScopeDefinitions
23
- } from "../chunk-DEAF7P4L.js";
22
+ loadConfigSafe
23
+ } from "../chunk-UWJ2ZGEI.js";
24
24
  import {
25
25
  SCRIPT_CATEGORIES,
26
26
  TOTAL_SCRIPTS,
@@ -31,7 +31,11 @@ import {
31
31
  installMandatoryTemplates,
32
32
  templateMetadata,
33
33
  updateTemplates
34
- } from "../chunk-Y5N3JJTU.js";
34
+ } from "../chunk-YEOQZ7XC.js";
35
+ import {
36
+ autoFixConfigFile,
37
+ validateScopeDefinitions
38
+ } from "../chunk-YELUGXOM.js";
35
39
 
36
40
  // src/cli/index.ts
37
41
  import { Command } from "commander";
@@ -359,11 +363,11 @@ async function initCommand(options) {
359
363
  if (!existsSync(workflowDir)) {
360
364
  await mkdir(workflowDir, { recursive: true });
361
365
  }
362
- const shouldGenerateGuidelines = await p.confirm({
366
+ const shouldGenerateGuidelines = options.yes || isNonInteractive ? true : await p.confirm({
363
367
  message: "Generate workflow guidelines from templates?",
364
368
  initialValue: true
365
369
  });
366
- if (p.isCancel(shouldGenerateGuidelines)) {
370
+ if (!isNonInteractive && p.isCancel(shouldGenerateGuidelines)) {
367
371
  p.cancel("Initialization cancelled");
368
372
  process.exit(0);
369
373
  }
@@ -403,11 +407,11 @@ Reason: ${error instanceof Error ? error.message : String(error)}`
403
407
  );
404
408
  }
405
409
  }
406
- const shouldAutoSetup = options.yes ? true : await p.confirm({
410
+ const shouldAutoSetup = options.yes || isNonInteractive ? true : await p.confirm({
407
411
  message: "Set up linting, formatting, testing, and CI automatically?",
408
412
  initialValue: true
409
413
  });
410
- if (p.isCancel(shouldAutoSetup)) {
414
+ if (!isNonInteractive && p.isCancel(shouldAutoSetup)) {
411
415
  p.cancel("Initialization cancelled");
412
416
  process.exit(0);
413
417
  }
@@ -590,38 +594,318 @@ async function suggestCommand(feedback, options = {}) {
590
594
 
591
595
  // src/cli/commands/doctor.ts
592
596
  import chalk5 from "chalk";
593
- async function doctorCommand() {
597
+ import { existsSync as existsSync3 } from "fs";
598
+ import { join as join3 } from "path";
599
+
600
+ // src/utils/hooks.ts
601
+ import { existsSync as existsSync2 } from "fs";
602
+ import { readFile, writeFile as writeFile2, unlink, chmod, rename, mkdir as mkdir2 } from "fs/promises";
603
+ import { join as join2 } from "path";
604
+ function getGitHooksDir(projectPath = process.cwd()) {
605
+ return join2(projectPath, ".git", "hooks");
606
+ }
607
+ function hasGitRepo(projectPath = process.cwd()) {
608
+ return existsSync2(join2(projectPath, ".git"));
609
+ }
610
+ function generatePreCommitHook(config) {
611
+ const checks = config?.preCommit || ["validate-branch", "check-guidelines"];
612
+ const checkCommands = checks.map((check) => {
613
+ switch (check) {
614
+ case "validate-branch":
615
+ return " workflow validate branch";
616
+ case "validate-commit":
617
+ return " workflow validate commit";
618
+ case "check-guidelines":
619
+ return " workflow doctor --check-guidelines-only 2>/dev/null || true";
620
+ case "validate-scopes":
621
+ return " workflow config validate";
622
+ default:
623
+ return "";
624
+ }
625
+ }).filter(Boolean).join("\n");
626
+ return `#!/bin/sh
627
+ # Workflow Agent pre-commit hook
628
+ # Auto-generated - do not edit manually
629
+ # To reinstall: workflow hooks install
630
+ # To uninstall: workflow hooks uninstall
631
+
632
+ # Skip in CI environment
633
+ if [ -n "\${CI:-}" ] || [ -n "\${GITHUB_ACTIONS:-}" ] || [ -n "\${GITLAB_CI:-}" ]; then
634
+ exit 0
635
+ fi
636
+
637
+ # Run workflow checks
638
+ ${checkCommands}
639
+
640
+ # Run original hook if it exists
641
+ if [ -f ".git/hooks/pre-commit.original" ]; then
642
+ .git/hooks/pre-commit.original "$@"
643
+ fi
644
+ `;
645
+ }
646
+ function generateCommitMsgHook(config) {
647
+ const checks = config?.commitMsg || ["validate-commit"];
648
+ const checkCommands = checks.map((check) => {
649
+ switch (check) {
650
+ case "validate-commit":
651
+ return ' workflow validate commit "$(cat "$1")"';
652
+ default:
653
+ return "";
654
+ }
655
+ }).filter(Boolean).join("\n");
656
+ return `#!/bin/sh
657
+ # Workflow Agent commit-msg hook
658
+ # Auto-generated - do not edit manually
659
+ # To reinstall: workflow hooks install
660
+ # To uninstall: workflow hooks uninstall
661
+
662
+ # Skip in CI environment
663
+ if [ -n "\${CI:-}" ] || [ -n "\${GITHUB_ACTIONS:-}" ] || [ -n "\${GITLAB_CI:-}" ]; then
664
+ exit 0
665
+ fi
666
+
667
+ # Run workflow checks
668
+ ${checkCommands}
669
+
670
+ # Run original hook if it exists
671
+ if [ -f ".git/hooks/commit-msg.original" ]; then
672
+ .git/hooks/commit-msg.original "$@"
673
+ fi
674
+ `;
675
+ }
676
+ async function isWorkflowHook(hookPath) {
677
+ try {
678
+ const content = await readFile(hookPath, "utf-8");
679
+ return content.includes("Workflow Agent") && content.includes("Auto-generated");
680
+ } catch {
681
+ return false;
682
+ }
683
+ }
684
+ async function getHookStatus(hookType, projectPath = process.cwd()) {
685
+ const hooksDir = getGitHooksDir(projectPath);
686
+ const hookPath = join2(hooksDir, hookType);
687
+ const originalPath = join2(hooksDir, `${hookType}.original`);
688
+ const status = {
689
+ installed: false,
690
+ hookType,
691
+ hasExistingHook: false,
692
+ wrappedOriginal: false
693
+ };
694
+ if (!existsSync2(hookPath)) {
695
+ return status;
696
+ }
697
+ status.hasExistingHook = true;
698
+ if (await isWorkflowHook(hookPath)) {
699
+ status.installed = true;
700
+ status.wrappedOriginal = existsSync2(originalPath);
701
+ }
702
+ return status;
703
+ }
704
+ async function getAllHooksStatus(projectPath = process.cwd()) {
705
+ return Promise.all([
706
+ getHookStatus("pre-commit", projectPath),
707
+ getHookStatus("commit-msg", projectPath)
708
+ ]);
709
+ }
710
+ async function installSingleHook(hookType, config, projectPath = process.cwd()) {
711
+ const hooksDir = getGitHooksDir(projectPath);
712
+ const hookPath = join2(hooksDir, hookType);
713
+ const originalPath = join2(hooksDir, `${hookType}.original`);
714
+ const result = {
715
+ success: false,
716
+ hookType,
717
+ wrappedExisting: false
718
+ };
719
+ try {
720
+ if (!existsSync2(hooksDir)) {
721
+ await mkdir2(hooksDir, { recursive: true });
722
+ }
723
+ if (existsSync2(hookPath)) {
724
+ const isOurs = await isWorkflowHook(hookPath);
725
+ if (!isOurs) {
726
+ await rename(hookPath, originalPath);
727
+ result.wrappedExisting = true;
728
+ }
729
+ }
730
+ const hookContent = hookType === "pre-commit" ? generatePreCommitHook(config) : generateCommitMsgHook(config);
731
+ await writeFile2(hookPath, hookContent, "utf-8");
732
+ await chmod(hookPath, 493);
733
+ result.success = true;
734
+ } catch (error) {
735
+ result.error = error instanceof Error ? error.message : String(error);
736
+ }
737
+ return result;
738
+ }
739
+ async function installHooks(config, projectPath = process.cwd()) {
740
+ if (!hasGitRepo(projectPath)) {
741
+ return [
742
+ {
743
+ success: false,
744
+ hookType: "pre-commit",
745
+ wrappedExisting: false,
746
+ error: "No git repository found. Run git init first."
747
+ }
748
+ ];
749
+ }
750
+ const results = await Promise.all([
751
+ installSingleHook("pre-commit", config, projectPath),
752
+ installSingleHook("commit-msg", config, projectPath)
753
+ ]);
754
+ return results;
755
+ }
756
+ async function uninstallSingleHook(hookType, projectPath = process.cwd()) {
757
+ const hooksDir = getGitHooksDir(projectPath);
758
+ const hookPath = join2(hooksDir, hookType);
759
+ const originalPath = join2(hooksDir, `${hookType}.original`);
760
+ const result = {
761
+ success: false,
762
+ hookType,
763
+ wrappedExisting: false
764
+ };
765
+ try {
766
+ if (!existsSync2(hookPath)) {
767
+ result.success = true;
768
+ return result;
769
+ }
770
+ const isOurs = await isWorkflowHook(hookPath);
771
+ if (!isOurs) {
772
+ result.error = "Hook is not managed by Workflow Agent";
773
+ return result;
774
+ }
775
+ await unlink(hookPath);
776
+ if (existsSync2(originalPath)) {
777
+ await rename(originalPath, hookPath);
778
+ result.wrappedExisting = true;
779
+ }
780
+ result.success = true;
781
+ } catch (error) {
782
+ result.error = error instanceof Error ? error.message : String(error);
783
+ }
784
+ return result;
785
+ }
786
+ async function uninstallHooks(projectPath = process.cwd()) {
787
+ return Promise.all([
788
+ uninstallSingleHook("pre-commit", projectPath),
789
+ uninstallSingleHook("commit-msg", projectPath)
790
+ ]);
791
+ }
792
+
793
+ // src/cli/commands/doctor.ts
794
+ async function doctorCommand(options) {
594
795
  console.log(chalk5.bold.cyan("\n\u{1F3E5} Workflow Agent Health Check\n"));
595
- const config = await loadConfig();
596
- if (!config) {
796
+ const result = await loadConfigSafe();
797
+ if (!result.configPath && !result.rawConfig) {
597
798
  console.error(chalk5.red("\u2717 No workflow configuration found"));
598
799
  console.log(chalk5.yellow(" Run: workflow init"));
599
800
  process.exit(1);
600
801
  }
802
+ if (!result.valid && result.issues.length > 0) {
803
+ console.log(chalk5.yellow("\u26A0 Configuration has validation issues:\n"));
804
+ for (const issue of result.issues) {
805
+ console.log(chalk5.red(` \u2717 ${issue.path}: ${issue.message}`));
806
+ if (issue.currentValue !== void 0) {
807
+ console.log(chalk5.dim(` Current value: ${JSON.stringify(issue.currentValue)}`));
808
+ }
809
+ if (issue.suggestedFix) {
810
+ console.log(chalk5.green(` Suggested fix: ${issue.suggestedFix.description}`));
811
+ console.log(chalk5.dim(` New value: ${JSON.stringify(issue.suggestedFix.newValue)}`));
812
+ }
813
+ }
814
+ const hasAutoFixes = result.issues.some((i) => i.suggestedFix);
815
+ if (hasAutoFixes) {
816
+ if (options?.fix) {
817
+ console.log(chalk5.cyan("\n\u{1F527} Attempting to auto-fix issues...\n"));
818
+ const fixResult = await autoFixConfigFile();
819
+ if (fixResult.success) {
820
+ console.log(chalk5.green("\u2713 Configuration fixed successfully!\n"));
821
+ for (const change of fixResult.changes) {
822
+ console.log(chalk5.dim(` \u2022 ${change}`));
823
+ }
824
+ console.log(chalk5.cyan("\n Run 'workflow doctor' again to verify.\n"));
825
+ process.exit(0);
826
+ } else {
827
+ console.log(chalk5.red(`\u2717 Auto-fix failed: ${fixResult.error}`));
828
+ process.exit(1);
829
+ }
830
+ } else {
831
+ console.log(chalk5.cyan("\n\u{1F4A1} Auto-fix available!"));
832
+ console.log(chalk5.dim(" Run: workflow doctor --fix\n"));
833
+ }
834
+ }
835
+ process.exit(1);
836
+ }
837
+ const config = result.config;
601
838
  console.log(chalk5.green("\u2713 Configuration loaded successfully"));
602
839
  console.log(chalk5.dim(` Project: ${config.projectName}`));
603
840
  console.log(chalk5.dim(` Scopes: ${config.scopes.length} configured`));
604
841
  console.log(chalk5.dim(` Enforcement: ${config.enforcement}`));
605
842
  console.log(chalk5.dim(` Language: ${config.language}`));
606
- console.log(chalk5.cyan("\n\u{1F4A1} Suggestions:\n"));
607
- console.log(chalk5.dim(" \u2022 Health check analysis coming soon"));
608
- console.log(chalk5.dim(" \u2022 Git history analysis coming soon"));
609
- console.log(chalk5.dim(" \u2022 Optimization recommendations coming soon"));
843
+ const cwd = process.cwd();
844
+ const guidelinesDir = join3(cwd, "guidelines");
845
+ const mandatoryFiles = getMandatoryTemplateFilenames();
846
+ const missingFiles = [];
847
+ console.log(chalk5.cyan("\n\u{1F4DA} Guidelines Check:\n"));
848
+ for (const filename of mandatoryFiles) {
849
+ const filePath = join3(guidelinesDir, filename);
850
+ if (existsSync3(filePath)) {
851
+ console.log(chalk5.green(`\u2713 ${filename}`));
852
+ } else {
853
+ console.log(chalk5.red(`\u2717 ${filename} (missing)`));
854
+ missingFiles.push(filename);
855
+ }
856
+ }
857
+ if (missingFiles.length === 0) {
858
+ console.log(
859
+ chalk5.green(`
860
+ \u2713 All ${mandatoryFiles.length} mandatory guidelines present`)
861
+ );
862
+ } else {
863
+ console.log(
864
+ chalk5.red(
865
+ `
866
+ \u2717 Missing ${missingFiles.length} mandatory guideline(s)`
867
+ )
868
+ );
869
+ }
870
+ if (options?.checkGuidelinesOnly) {
871
+ process.exit(missingFiles.length > 0 ? 1 : 0);
872
+ }
873
+ console.log(chalk5.cyan("\n\u{1F517} Git Hooks Check:\n"));
874
+ if (!hasGitRepo(cwd)) {
875
+ console.log(chalk5.yellow("\u26A0 No git repository found"));
876
+ console.log(chalk5.dim(" Run: git init"));
877
+ } else {
878
+ const hooksStatus = getAllHooksStatus(cwd);
879
+ for (const status of hooksStatus) {
880
+ if (status.installed) {
881
+ console.log(chalk5.green(`\u2713 ${status.hookType}: installed`));
882
+ } else {
883
+ console.log(chalk5.yellow(`\u26A0 ${status.hookType}: not installed`));
884
+ }
885
+ }
886
+ const allInstalled = hooksStatus.every((s) => s.installed);
887
+ if (!allInstalled) {
888
+ console.log(chalk5.dim("\n Run: workflow hooks install"));
889
+ }
890
+ }
891
+ if (missingFiles.length > 0) {
892
+ process.exit(1);
893
+ }
610
894
  }
611
895
 
612
896
  // src/cli/commands/setup.ts
613
897
  import * as p3 from "@clack/prompts";
614
898
  import chalk6 from "chalk";
615
- import { readFileSync, writeFileSync, existsSync as existsSync2 } from "fs";
616
- import { join as join2, dirname as dirname2 } from "path";
899
+ import { readFileSync, writeFileSync, existsSync as existsSync4 } from "fs";
900
+ import { join as join4, dirname as dirname2 } from "path";
617
901
  import { fileURLToPath as fileURLToPath2 } from "url";
618
902
  var __filename2 = fileURLToPath2(import.meta.url);
619
903
  var __dirname2 = dirname2(__filename2);
620
904
  async function setupCommand() {
621
905
  p3.intro(chalk6.bgBlue(" workflow-agent setup "));
622
906
  const cwd = process.cwd();
623
- const packageJsonPath = join2(cwd, "package.json");
624
- if (!existsSync2(packageJsonPath)) {
907
+ const packageJsonPath = join4(cwd, "package.json");
908
+ if (!existsSync4(packageJsonPath)) {
625
909
  p3.cancel("No package.json found in current directory");
626
910
  process.exit(1);
627
911
  }
@@ -686,8 +970,8 @@ async function setupCommand() {
686
970
  console.log(chalk6.dim("\nRun them with:"));
687
971
  console.log(chalk6.dim(" pnpm run workflow:init"));
688
972
  console.log(chalk6.dim(" npm run workflow:init\n"));
689
- const guidelinesDir = join2(cwd, "guidelines");
690
- if (!existsSync2(guidelinesDir)) {
973
+ const guidelinesDir = join4(cwd, "guidelines");
974
+ if (!existsSync4(guidelinesDir)) {
691
975
  const templatesDir = findTemplatesDirectory(__dirname2);
692
976
  if (templatesDir) {
693
977
  const templateResult = installMandatoryTemplates(cwd, templatesDir, {
@@ -705,7 +989,7 @@ async function setupCommand() {
705
989
  }
706
990
  }
707
991
  }
708
- if (existsSync2(guidelinesDir)) {
992
+ if (existsSync4(guidelinesDir)) {
709
993
  const result = generateCopilotInstructions(cwd, { silent: false });
710
994
  if (result.success) {
711
995
  const status = result.isNew ? "Generated" : "Updated";
@@ -724,14 +1008,14 @@ async function setupCommand() {
724
1008
  // src/cli/commands/scope-create.ts
725
1009
  import * as p4 from "@clack/prompts";
726
1010
  import chalk7 from "chalk";
727
- import { existsSync as existsSync3 } from "fs";
728
- import { writeFile as writeFile2, mkdir as mkdir2, readFile } from "fs/promises";
729
- import { join as join3 } from "path";
1011
+ import { existsSync as existsSync5 } from "fs";
1012
+ import { writeFile as writeFile3, mkdir as mkdir3, readFile as readFile2 } from "fs/promises";
1013
+ import { join as join5 } from "path";
730
1014
  async function scopeCreateCommand(options) {
731
1015
  console.log(chalk7.bold.cyan("\n\u{1F3A8} Create Custom Scope Package\n"));
732
1016
  const cwd = process.cwd();
733
1017
  const isNonInteractive = !!(options.name && options.scopes && options.presetName);
734
- const isMonorepo2 = existsSync3(join3(cwd, "pnpm-workspace.yaml"));
1018
+ const isMonorepo2 = existsSync5(join5(cwd, "pnpm-workspace.yaml"));
735
1019
  if (isMonorepo2) {
736
1020
  console.log(chalk7.dim("\u2713 Detected monorepo workspace\n"));
737
1021
  }
@@ -877,7 +1161,7 @@ async function scopeCreateCommand(options) {
877
1161
  if (options.outputDir) {
878
1162
  outputDir = options.outputDir;
879
1163
  } else if (isMonorepo2) {
880
- outputDir = join3(cwd, "packages", `scopes-${packageName}`);
1164
+ outputDir = join5(cwd, "packages", `scopes-${packageName}`);
881
1165
  } else {
882
1166
  const customDir = await p4.text({
883
1167
  message: "Output directory:",
@@ -888,9 +1172,9 @@ async function scopeCreateCommand(options) {
888
1172
  p4.cancel("Operation cancelled");
889
1173
  process.exit(0);
890
1174
  }
891
- outputDir = join3(cwd, customDir);
1175
+ outputDir = join5(cwd, customDir);
892
1176
  }
893
- if (existsSync3(outputDir)) {
1177
+ if (existsSync5(outputDir)) {
894
1178
  const shouldOverwrite = await p4.confirm({
895
1179
  message: `Directory ${outputDir} already exists. Overwrite?`,
896
1180
  initialValue: false
@@ -903,7 +1187,7 @@ async function scopeCreateCommand(options) {
903
1187
  const spinner10 = p4.spinner();
904
1188
  spinner10.start("Creating package structure...");
905
1189
  try {
906
- await mkdir2(join3(outputDir, "src"), { recursive: true });
1190
+ await mkdir3(join5(outputDir, "src"), { recursive: true });
907
1191
  const packageJson = {
908
1192
  name: `@workflow/scopes-${packageName}`,
909
1193
  version: "1.0.0",
@@ -943,8 +1227,8 @@ async function scopeCreateCommand(options) {
943
1227
  access: "public"
944
1228
  }
945
1229
  };
946
- await writeFile2(
947
- join3(outputDir, "package.json"),
1230
+ await writeFile3(
1231
+ join5(outputDir, "package.json"),
948
1232
  JSON.stringify(packageJson, null, 2),
949
1233
  "utf-8"
950
1234
  );
@@ -956,8 +1240,8 @@ async function scopeCreateCommand(options) {
956
1240
  },
957
1241
  include: ["src/**/*"]
958
1242
  };
959
- await writeFile2(
960
- join3(outputDir, "tsconfig.json"),
1243
+ await writeFile3(
1244
+ join5(outputDir, "tsconfig.json"),
961
1245
  JSON.stringify(tsconfig, null, 2),
962
1246
  "utf-8"
963
1247
  );
@@ -971,7 +1255,7 @@ export default defineConfig({
971
1255
  sourcemap: true,
972
1256
  });
973
1257
  `;
974
- await writeFile2(join3(outputDir, "tsup.config.ts"), tsupConfig, "utf-8");
1258
+ await writeFile3(join5(outputDir, "tsup.config.ts"), tsupConfig, "utf-8");
975
1259
  const indexTs = `import type { Scope } from '@hawkinside_out/workflow-agent/config';
976
1260
 
977
1261
  export const scopes: Scope[] = ${JSON.stringify(scopes, null, 2)};
@@ -985,7 +1269,7 @@ export const preset = {
985
1269
 
986
1270
  export default preset;
987
1271
  `;
988
- await writeFile2(join3(outputDir, "src", "index.ts"), indexTs, "utf-8");
1272
+ await writeFile3(join5(outputDir, "src", "index.ts"), indexTs, "utf-8");
989
1273
  if (!options.noTest) {
990
1274
  const testFile = `import { describe, it, expect } from 'vitest';
991
1275
  import { scopes, preset } from './index.js';
@@ -1026,16 +1310,16 @@ describe('${presetName} Scope Preset', () => {
1026
1310
  });
1027
1311
  });
1028
1312
  `;
1029
- await writeFile2(
1030
- join3(outputDir, "src", "index.test.ts"),
1313
+ await writeFile3(
1314
+ join5(outputDir, "src", "index.test.ts"),
1031
1315
  testFile,
1032
1316
  "utf-8"
1033
1317
  );
1034
1318
  }
1035
1319
  spinner10.stop("\u2713 Package structure created");
1036
1320
  if (isMonorepo2) {
1037
- const workspaceFile = join3(cwd, "pnpm-workspace.yaml");
1038
- const workspaceContent = await readFile(workspaceFile, "utf-8");
1321
+ const workspaceFile = join5(cwd, "pnpm-workspace.yaml");
1322
+ const workspaceContent = await readFile2(workspaceFile, "utf-8");
1039
1323
  const packagePath = `packages/scopes-${packageName}`;
1040
1324
  if (!workspaceContent.includes(packagePath) && !workspaceContent.includes("packages/*")) {
1041
1325
  console.log(
@@ -1093,9 +1377,9 @@ describe('${presetName} Scope Preset', () => {
1093
1377
  // src/cli/commands/scope-migrate.ts
1094
1378
  import * as p5 from "@clack/prompts";
1095
1379
  import chalk8 from "chalk";
1096
- import { existsSync as existsSync4 } from "fs";
1097
- import { writeFile as writeFile3, mkdir as mkdir3, readFile as readFile2 } from "fs/promises";
1098
- import { join as join4 } from "path";
1380
+ import { existsSync as existsSync6 } from "fs";
1381
+ import { writeFile as writeFile4, mkdir as mkdir4, readFile as readFile3 } from "fs/promises";
1382
+ import { join as join6 } from "path";
1099
1383
  async function scopeMigrateCommand(options) {
1100
1384
  console.log(chalk8.bold.cyan("\n\u{1F504} Migrate Scopes to Custom Package\n"));
1101
1385
  const cwd = process.cwd();
@@ -1139,7 +1423,7 @@ async function scopeMigrateCommand(options) {
1139
1423
  p5.cancel("Migration cancelled");
1140
1424
  process.exit(0);
1141
1425
  }
1142
- const isMonorepo2 = existsSync4(join4(cwd, "pnpm-workspace.yaml"));
1426
+ const isMonorepo2 = existsSync6(join6(cwd, "pnpm-workspace.yaml"));
1143
1427
  if (isMonorepo2) {
1144
1428
  console.log(chalk8.dim("\n\u2713 Detected monorepo workspace\n"));
1145
1429
  }
@@ -1189,7 +1473,7 @@ async function scopeMigrateCommand(options) {
1189
1473
  if (options.outputDir) {
1190
1474
  outputDir = options.outputDir;
1191
1475
  } else if (isMonorepo2) {
1192
- outputDir = join4(cwd, "packages", `scopes-${packageName}`);
1476
+ outputDir = join6(cwd, "packages", `scopes-${packageName}`);
1193
1477
  } else {
1194
1478
  const customDir = await p5.text({
1195
1479
  message: "Output directory:",
@@ -1200,9 +1484,9 @@ async function scopeMigrateCommand(options) {
1200
1484
  p5.cancel("Migration cancelled");
1201
1485
  process.exit(0);
1202
1486
  }
1203
- outputDir = join4(cwd, customDir);
1487
+ outputDir = join6(cwd, customDir);
1204
1488
  }
1205
- if (existsSync4(outputDir)) {
1489
+ if (existsSync6(outputDir)) {
1206
1490
  const shouldOverwrite = await p5.confirm({
1207
1491
  message: `Directory ${outputDir} already exists. Overwrite?`,
1208
1492
  initialValue: false
@@ -1215,7 +1499,7 @@ async function scopeMigrateCommand(options) {
1215
1499
  const spinner10 = p5.spinner();
1216
1500
  spinner10.start("Migrating scopes to package...");
1217
1501
  try {
1218
- await mkdir3(join4(outputDir, "src"), { recursive: true });
1502
+ await mkdir4(join6(outputDir, "src"), { recursive: true });
1219
1503
  const packageJson = {
1220
1504
  name: `@workflow/scopes-${packageName}`,
1221
1505
  version: "1.0.0",
@@ -1255,8 +1539,8 @@ async function scopeMigrateCommand(options) {
1255
1539
  access: "public"
1256
1540
  }
1257
1541
  };
1258
- await writeFile3(
1259
- join4(outputDir, "package.json"),
1542
+ await writeFile4(
1543
+ join6(outputDir, "package.json"),
1260
1544
  JSON.stringify(packageJson, null, 2),
1261
1545
  "utf-8"
1262
1546
  );
@@ -1268,8 +1552,8 @@ async function scopeMigrateCommand(options) {
1268
1552
  },
1269
1553
  include: ["src/**/*"]
1270
1554
  };
1271
- await writeFile3(
1272
- join4(outputDir, "tsconfig.json"),
1555
+ await writeFile4(
1556
+ join6(outputDir, "tsconfig.json"),
1273
1557
  JSON.stringify(tsconfig, null, 2),
1274
1558
  "utf-8"
1275
1559
  );
@@ -1283,7 +1567,7 @@ export default defineConfig({
1283
1567
  sourcemap: true,
1284
1568
  });
1285
1569
  `;
1286
- await writeFile3(join4(outputDir, "tsup.config.ts"), tsupConfig, "utf-8");
1570
+ await writeFile4(join6(outputDir, "tsup.config.ts"), tsupConfig, "utf-8");
1287
1571
  const indexTs = `import type { Scope } from '@hawkinside_out/workflow-agent/config';
1288
1572
 
1289
1573
  export const scopes: Scope[] = ${JSON.stringify(config.scopes, null, 2)};
@@ -1297,7 +1581,7 @@ export const preset = {
1297
1581
 
1298
1582
  export default preset;
1299
1583
  `;
1300
- await writeFile3(join4(outputDir, "src", "index.ts"), indexTs, "utf-8");
1584
+ await writeFile4(join6(outputDir, "src", "index.ts"), indexTs, "utf-8");
1301
1585
  const testFile = `import { describe, it, expect } from 'vitest';
1302
1586
  import { scopes, preset } from './index.js';
1303
1587
  import { ScopeSchema } from '@hawkinside_out/workflow-agent/config';
@@ -1340,11 +1624,11 @@ describe('${presetName} Scope Preset (Migrated)', () => {
1340
1624
  });
1341
1625
  });
1342
1626
  `;
1343
- await writeFile3(join4(outputDir, "src", "index.test.ts"), testFile, "utf-8");
1627
+ await writeFile4(join6(outputDir, "src", "index.test.ts"), testFile, "utf-8");
1344
1628
  spinner10.stop("\u2713 Package created from migrated scopes");
1345
1629
  if (isMonorepo2) {
1346
- const workspaceFile = join4(cwd, "pnpm-workspace.yaml");
1347
- const workspaceContent = await readFile2(workspaceFile, "utf-8");
1630
+ const workspaceFile = join6(cwd, "pnpm-workspace.yaml");
1631
+ const workspaceContent = await readFile3(workspaceFile, "utf-8");
1348
1632
  const packagePath = `packages/scopes-${packageName}`;
1349
1633
  if (!workspaceContent.includes(packagePath) && !workspaceContent.includes("packages/*")) {
1350
1634
  console.log(
@@ -1360,7 +1644,7 @@ describe('${presetName} Scope Preset (Migrated)', () => {
1360
1644
  initialValue: false
1361
1645
  });
1362
1646
  if (!p5.isCancel(keepConfig) && !keepConfig) {
1363
- const configPath = join4(cwd, "workflow.config.json");
1647
+ const configPath = join6(cwd, "workflow.config.json");
1364
1648
  const updatedConfig = {
1365
1649
  ...config,
1366
1650
  scopes: [],
@@ -1368,7 +1652,7 @@ describe('${presetName} Scope Preset (Migrated)', () => {
1368
1652
  preset: `scopes-${packageName}`
1369
1653
  // Reference the new package
1370
1654
  };
1371
- await writeFile3(
1655
+ await writeFile4(
1372
1656
  configPath,
1373
1657
  JSON.stringify(updatedConfig, null, 2),
1374
1658
  "utf-8"
@@ -1796,14 +2080,14 @@ function formatAuditReportColored(report) {
1796
2080
  // src/cli/commands/advisory.ts
1797
2081
  import * as p7 from "@clack/prompts";
1798
2082
  import chalk11 from "chalk";
1799
- import { existsSync as existsSync6 } from "fs";
1800
- import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
1801
- import { join as join6 } from "path";
2083
+ import { existsSync as existsSync8 } from "fs";
2084
+ import { readFile as readFile5, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
2085
+ import { join as join8 } from "path";
1802
2086
 
1803
2087
  // src/utils/advisory-analyzer.ts
1804
- import { existsSync as existsSync5 } from "fs";
1805
- import { readFile as readFile3 } from "fs/promises";
1806
- import { join as join5 } from "path";
2088
+ import { existsSync as existsSync7 } from "fs";
2089
+ import { readFile as readFile4 } from "fs/promises";
2090
+ import { join as join7 } from "path";
1807
2091
  import fg from "fast-glob";
1808
2092
  var AdvisoryAnalyzer = class {
1809
2093
  options;
@@ -2247,11 +2531,11 @@ var AdvisoryAnalyzer = class {
2247
2531
  // Helper Methods
2248
2532
  // ============================================================================
2249
2533
  async readPackageJson() {
2250
- const pkgPath = join5(this.options.cwd, "package.json");
2251
- if (!existsSync5(pkgPath)) {
2534
+ const pkgPath = join7(this.options.cwd, "package.json");
2535
+ if (!existsSync7(pkgPath)) {
2252
2536
  throw new Error("package.json not found");
2253
2537
  }
2254
- const content = await readFile3(pkgPath, "utf-8");
2538
+ const content = await readFile4(pkgPath, "utf-8");
2255
2539
  return JSON.parse(content);
2256
2540
  }
2257
2541
  async countFiles() {
@@ -3619,11 +3903,11 @@ async function advisoryCommand(options) {
3619
3903
  let comparisonReport;
3620
3904
  let comparator;
3621
3905
  if (options.compare) {
3622
- const comparisonPath = options.compare.endsWith(".json") ? join6(cwd, options.compare) : join6(cwd, options.compare, "analysis.json");
3623
- if (existsSync6(comparisonPath)) {
3906
+ const comparisonPath = options.compare.endsWith(".json") ? join8(cwd, options.compare) : join8(cwd, options.compare, "analysis.json");
3907
+ if (existsSync8(comparisonPath)) {
3624
3908
  spinner10.start("Comparing with previous report...");
3625
3909
  try {
3626
- const previousContent = await readFile4(comparisonPath, "utf-8");
3910
+ const previousContent = await readFile5(comparisonPath, "utf-8");
3627
3911
  const previousAnalysis = JSON.parse(previousContent);
3628
3912
  comparator = new ReportComparator(previousAnalysis, analysis);
3629
3913
  comparisonReport = comparator.compare();
@@ -3648,8 +3932,8 @@ async function advisoryCommand(options) {
3648
3932
  console.log(chalk11.dim("\n--dry-run mode: No files written.\n"));
3649
3933
  return;
3650
3934
  }
3651
- const fullOutputDir = join6(cwd, outputDir);
3652
- await mkdir4(fullOutputDir, { recursive: true });
3935
+ const fullOutputDir = join8(cwd, outputDir);
3936
+ await mkdir5(fullOutputDir, { recursive: true });
3653
3937
  spinner10.start("Generating reports...");
3654
3938
  try {
3655
3939
  const timestamp = options.timestamp ? (/* @__PURE__ */ new Date()).toISOString().split("T")[0] : "";
@@ -3674,24 +3958,24 @@ async function advisoryCommand(options) {
3674
3958
  console.log(chalk11.green("\u{1F4DD} Reports written to:"));
3675
3959
  const suffix = options.timestamp ? `-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}` : "";
3676
3960
  if (options.format === "json") {
3677
- console.log(chalk11.dim(` ${join6(outputDir, `analysis${suffix}.json`)}`));
3678
- console.log(chalk11.dim(` ${join6(outputDir, `questions${suffix}.json`)}`));
3961
+ console.log(chalk11.dim(` ${join8(outputDir, `analysis${suffix}.json`)}`));
3962
+ console.log(chalk11.dim(` ${join8(outputDir, `questions${suffix}.json`)}`));
3679
3963
  } else {
3680
3964
  console.log(
3681
- chalk11.dim(` ${join6(outputDir, `EXECUTIVE_SUMMARY${suffix}.md`)}`)
3965
+ chalk11.dim(` ${join8(outputDir, `EXECUTIVE_SUMMARY${suffix}.md`)}`)
3682
3966
  );
3683
3967
  console.log(
3684
- chalk11.dim(` ${join6(outputDir, `TECHNOLOGY_AUDIT${suffix}.md`)}`)
3968
+ chalk11.dim(` ${join8(outputDir, `TECHNOLOGY_AUDIT${suffix}.md`)}`)
3685
3969
  );
3686
3970
  console.log(
3687
- chalk11.dim(` ${join6(outputDir, `STRATEGIC_ROADMAP${suffix}.md`)}`)
3971
+ chalk11.dim(` ${join8(outputDir, `STRATEGIC_ROADMAP${suffix}.md`)}`)
3688
3972
  );
3689
3973
  console.log(
3690
- chalk11.dim(` ${join6(outputDir, `BOARD_QUESTIONS${suffix}.md`)}`)
3974
+ chalk11.dim(` ${join8(outputDir, `BOARD_QUESTIONS${suffix}.md`)}`)
3691
3975
  );
3692
3976
  if (comparisonReport) {
3693
3977
  console.log(
3694
- chalk11.dim(` ${join6(outputDir, `DIFF_REPORT${suffix}.md`)}`)
3978
+ chalk11.dim(` ${join8(outputDir, `DIFF_REPORT${suffix}.md`)}`)
3695
3979
  );
3696
3980
  }
3697
3981
  }
@@ -3784,47 +4068,47 @@ function displayComparisonSummary(comparison) {
3784
4068
  }
3785
4069
  async function writeAnalysisJson(outputDir, analysis, questions, timestamp) {
3786
4070
  const suffix = timestamp ? `-${timestamp}` : "";
3787
- await writeFile4(
3788
- join6(outputDir, `analysis${suffix}.json`),
4071
+ await writeFile5(
4072
+ join8(outputDir, `analysis${suffix}.json`),
3789
4073
  JSON.stringify(analysis, null, 2),
3790
4074
  "utf-8"
3791
4075
  );
3792
- await writeFile4(
3793
- join6(outputDir, `questions${suffix}.json`),
4076
+ await writeFile5(
4077
+ join8(outputDir, `questions${suffix}.json`),
3794
4078
  JSON.stringify(questions, null, 2),
3795
4079
  "utf-8"
3796
4080
  );
3797
4081
  }
3798
4082
  async function writeMarkdownReports(outputDir, analysis, questions, comparator, timestamp) {
3799
4083
  const suffix = timestamp ? `-${timestamp}` : "";
3800
- await writeFile4(
3801
- join6(outputDir, `analysis.json`),
4084
+ await writeFile5(
4085
+ join8(outputDir, `analysis.json`),
3802
4086
  JSON.stringify(analysis, null, 2),
3803
4087
  "utf-8"
3804
4088
  );
3805
- await writeFile4(
3806
- join6(outputDir, `EXECUTIVE_SUMMARY${suffix}.md`),
4089
+ await writeFile5(
4090
+ join8(outputDir, `EXECUTIVE_SUMMARY${suffix}.md`),
3807
4091
  generateExecutiveSummary(analysis, questions),
3808
4092
  "utf-8"
3809
4093
  );
3810
- await writeFile4(
3811
- join6(outputDir, `TECHNOLOGY_AUDIT${suffix}.md`),
4094
+ await writeFile5(
4095
+ join8(outputDir, `TECHNOLOGY_AUDIT${suffix}.md`),
3812
4096
  generateTechnologyAudit(analysis),
3813
4097
  "utf-8"
3814
4098
  );
3815
- await writeFile4(
3816
- join6(outputDir, `STRATEGIC_ROADMAP${suffix}.md`),
4099
+ await writeFile5(
4100
+ join8(outputDir, `STRATEGIC_ROADMAP${suffix}.md`),
3817
4101
  generateStrategicRoadmap(analysis, questions),
3818
4102
  "utf-8"
3819
4103
  );
3820
- await writeFile4(
3821
- join6(outputDir, `BOARD_QUESTIONS${suffix}.md`),
4104
+ await writeFile5(
4105
+ join8(outputDir, `BOARD_QUESTIONS${suffix}.md`),
3822
4106
  generateBoardQuestions(questions),
3823
4107
  "utf-8"
3824
4108
  );
3825
4109
  if (comparator) {
3826
- await writeFile4(
3827
- join6(outputDir, `DIFF_REPORT${suffix}.md`),
4110
+ await writeFile5(
4111
+ join8(outputDir, `DIFF_REPORT${suffix}.md`),
3828
4112
  comparator.generateMarkdownSummary(),
3829
4113
  "utf-8"
3830
4114
  );
@@ -4441,20 +4725,20 @@ function checkCIThresholds(analysis, config) {
4441
4725
  // src/cli/commands/generate-instructions.ts
4442
4726
  import * as p8 from "@clack/prompts";
4443
4727
  import chalk12 from "chalk";
4444
- import { existsSync as existsSync7 } from "fs";
4445
- import { join as join7 } from "path";
4728
+ import { existsSync as existsSync9 } from "fs";
4729
+ import { join as join9 } from "path";
4446
4730
  async function generateInstructionsCommand(options) {
4447
4731
  p8.intro(chalk12.bgBlue(" workflow-agent generate-instructions "));
4448
4732
  const cwd = process.cwd();
4449
- const guidelinesDir = join7(cwd, "guidelines");
4450
- const outputPath = join7(cwd, ".github", "copilot-instructions.md");
4451
- if (!existsSync7(guidelinesDir)) {
4733
+ const guidelinesDir = join9(cwd, "guidelines");
4734
+ const outputPath = join9(cwd, ".github", "copilot-instructions.md");
4735
+ if (!existsSync9(guidelinesDir)) {
4452
4736
  p8.cancel(
4453
4737
  "No guidelines directory found. Run 'workflow init' first to generate guidelines."
4454
4738
  );
4455
4739
  process.exit(1);
4456
4740
  }
4457
- if (existsSync7(outputPath) && !options.force) {
4741
+ if (existsSync9(outputPath) && !options.force) {
4458
4742
  const shouldRegenerate = await p8.confirm({
4459
4743
  message: ".github/copilot-instructions.md already exists. Regenerate? (Custom content will be preserved)",
4460
4744
  initialValue: true
@@ -4514,8 +4798,8 @@ Reason: ${error instanceof Error ? error.message : String(error)}`
4514
4798
  // src/cli/commands/update-templates.ts
4515
4799
  import * as p9 from "@clack/prompts";
4516
4800
  import chalk13 from "chalk";
4517
- import { existsSync as existsSync8 } from "fs";
4518
- import { join as join8, dirname as dirname3 } from "path";
4801
+ import { existsSync as existsSync10 } from "fs";
4802
+ import { join as join10, dirname as dirname3 } from "path";
4519
4803
  import { fileURLToPath as fileURLToPath3 } from "url";
4520
4804
  var __filename3 = fileURLToPath3(import.meta.url);
4521
4805
  var __dirname3 = dirname3(__filename3);
@@ -4523,13 +4807,13 @@ async function updateTemplatesCommand(options) {
4523
4807
  const { force = false, skip = false } = options;
4524
4808
  p9.intro(chalk13.bgBlue(" workflow-agent update-templates "));
4525
4809
  const cwd = process.cwd();
4526
- const guidelinesDir = join8(cwd, "guidelines");
4810
+ const guidelinesDir = join10(cwd, "guidelines");
4527
4811
  const templatesDir = findTemplatesDirectory(__dirname3);
4528
4812
  if (!templatesDir) {
4529
4813
  p9.cancel("Could not find templates directory");
4530
4814
  process.exit(1);
4531
4815
  }
4532
- const guidelinesExist = existsSync8(guidelinesDir);
4816
+ const guidelinesExist = existsSync10(guidelinesDir);
4533
4817
  if (!guidelinesExist) {
4534
4818
  console.log(chalk13.yellow("\n\u26A0\uFE0F No guidelines directory found."));
4535
4819
  console.log(chalk13.dim("Run 'workflow-agent init' to set up guidelines.\n"));
@@ -4818,8 +5102,124 @@ Fixed: ${fixedCount}, Skipped: ${skippedCount}`)
4818
5102
  }
4819
5103
  }
4820
5104
 
4821
- // src/cli/commands/learn.ts
5105
+ // src/cli/commands/hooks.ts
4822
5106
  import chalk15 from "chalk";
5107
+ async function hooksCommand(action) {
5108
+ const cwd = process.cwd();
5109
+ switch (action) {
5110
+ case "install":
5111
+ await installHooksAction(cwd);
5112
+ break;
5113
+ case "uninstall":
5114
+ await uninstallHooksAction(cwd);
5115
+ break;
5116
+ case "status":
5117
+ await statusHooksAction(cwd);
5118
+ break;
5119
+ default:
5120
+ console.error(chalk15.red(`Unknown action: ${action}`));
5121
+ console.log(chalk15.dim("Available actions: install, uninstall, status"));
5122
+ process.exit(1);
5123
+ }
5124
+ }
5125
+ async function installHooksAction(cwd) {
5126
+ console.log(chalk15.bold.cyan("\n\u{1F517} Installing Workflow Agent Git Hooks\n"));
5127
+ if (!hasGitRepo(cwd)) {
5128
+ console.error(chalk15.red("\u2717 No git repository found"));
5129
+ console.log(chalk15.yellow(" Run: git init"));
5130
+ process.exit(1);
5131
+ }
5132
+ const config = await loadConfig();
5133
+ const hooksConfig = config?.hooks;
5134
+ const results = await installHooks(hooksConfig, cwd);
5135
+ let hasErrors = false;
5136
+ for (const result of results) {
5137
+ if (result.success) {
5138
+ if (result.wrappedExisting) {
5139
+ console.log(
5140
+ chalk15.green(
5141
+ `\u2713 Installed ${result.hookType} hook (wrapped existing hook)`
5142
+ )
5143
+ );
5144
+ } else {
5145
+ console.log(chalk15.green(`\u2713 Installed ${result.hookType} hook`));
5146
+ }
5147
+ } else {
5148
+ console.error(
5149
+ chalk15.red(`\u2717 Failed to install ${result.hookType}: ${result.error}`)
5150
+ );
5151
+ hasErrors = true;
5152
+ }
5153
+ }
5154
+ if (!hasErrors) {
5155
+ console.log(chalk15.green("\n\u2713 Git hooks installed successfully"));
5156
+ console.log(chalk15.dim("\nHooks will run automatically on commit."));
5157
+ console.log(chalk15.dim("They will be skipped in CI environments."));
5158
+ } else {
5159
+ process.exit(1);
5160
+ }
5161
+ }
5162
+ async function uninstallHooksAction(cwd) {
5163
+ console.log(chalk15.bold.cyan("\n\u{1F513} Uninstalling Workflow Agent Git Hooks\n"));
5164
+ if (!hasGitRepo(cwd)) {
5165
+ console.error(chalk15.red("\u2717 No git repository found"));
5166
+ process.exit(1);
5167
+ }
5168
+ const results = await uninstallHooks(cwd);
5169
+ let hasErrors = false;
5170
+ for (const result of results) {
5171
+ if (result.success) {
5172
+ if (result.wrappedExisting) {
5173
+ console.log(
5174
+ chalk15.green(`\u2713 Removed ${result.hookType} hook (restored original)`)
5175
+ );
5176
+ } else {
5177
+ console.log(chalk15.green(`\u2713 Removed ${result.hookType} hook`));
5178
+ }
5179
+ } else if (result.error) {
5180
+ console.error(
5181
+ chalk15.red(`\u2717 Failed to remove ${result.hookType}: ${result.error}`)
5182
+ );
5183
+ hasErrors = true;
5184
+ }
5185
+ }
5186
+ if (!hasErrors) {
5187
+ console.log(chalk15.green("\n\u2713 Git hooks uninstalled successfully"));
5188
+ } else {
5189
+ process.exit(1);
5190
+ }
5191
+ }
5192
+ async function statusHooksAction(cwd) {
5193
+ console.log(chalk15.bold.cyan("\n\u{1F4CA} Workflow Agent Git Hooks Status\n"));
5194
+ if (!hasGitRepo(cwd)) {
5195
+ console.error(chalk15.red("\u2717 No git repository found"));
5196
+ process.exit(1);
5197
+ }
5198
+ const statuses = await getAllHooksStatus(cwd);
5199
+ for (const status of statuses) {
5200
+ const icon = status.installed ? "\u2713" : "\u2717";
5201
+ const color = status.installed ? chalk15.green : chalk15.yellow;
5202
+ let message = `${icon} ${status.hookType}`;
5203
+ if (status.installed) {
5204
+ message += " - installed";
5205
+ if (status.wrappedOriginal) {
5206
+ message += " (wrapping original hook)";
5207
+ }
5208
+ } else if (status.hasExistingHook) {
5209
+ message += " - existing hook (not managed by Workflow Agent)";
5210
+ } else {
5211
+ message += " - not installed";
5212
+ }
5213
+ console.log(color(message));
5214
+ }
5215
+ const allInstalled = statuses.every((s) => s.installed);
5216
+ if (!allInstalled) {
5217
+ console.log(chalk15.dim("\nTo install hooks: workflow hooks install"));
5218
+ }
5219
+ }
5220
+
5221
+ // src/cli/commands/learn.ts
5222
+ import chalk16 from "chalk";
4823
5223
  import * as p11 from "@clack/prompts";
4824
5224
  import {
4825
5225
  PatternStore as PatternStore2,
@@ -4843,7 +5243,7 @@ function formatTags(tags) {
4843
5243
  async function learnRecordCommand(options) {
4844
5244
  const cwd = getWorkspacePath();
4845
5245
  const store = new PatternStore2(cwd);
4846
- console.log(chalk15.cyan("\n\u{1F4DA} Record a Learning Pattern\n"));
5246
+ console.log(chalk16.cyan("\n\u{1F4DA} Record a Learning Pattern\n"));
4847
5247
  let patternType = options.type;
4848
5248
  if (!patternType) {
4849
5249
  const typeChoice = await p11.select({
@@ -5008,14 +5408,14 @@ async function learnRecordCommand(options) {
5008
5408
  };
5009
5409
  const result = await store.saveFixPattern(fixPattern);
5010
5410
  if (result.success) {
5011
- console.log(chalk15.green("\n\u2705 Fix pattern recorded successfully!\n"));
5012
- console.log(chalk15.dim(` ID: ${fixPattern.id}`));
5013
- console.log(chalk15.dim(` Name: ${name}`));
5014
- console.log(chalk15.dim(` Category: ${category}`));
5015
- console.log(chalk15.dim(` Framework: ${framework} ${version}`));
5411
+ console.log(chalk16.green("\n\u2705 Fix pattern recorded successfully!\n"));
5412
+ console.log(chalk16.dim(` ID: ${fixPattern.id}`));
5413
+ console.log(chalk16.dim(` Name: ${name}`));
5414
+ console.log(chalk16.dim(` Category: ${category}`));
5415
+ console.log(chalk16.dim(` Framework: ${framework} ${version}`));
5016
5416
  } else {
5017
- console.log(chalk15.red("\n\u274C Failed to record pattern"));
5018
- console.log(chalk15.dim(` Error: ${result.error}`));
5417
+ console.log(chalk16.red("\n\u274C Failed to record pattern"));
5418
+ console.log(chalk16.dim(` Error: ${result.error}`));
5019
5419
  process.exit(1);
5020
5420
  }
5021
5421
  } else {
@@ -5062,13 +5462,13 @@ async function learnRecordCommand(options) {
5062
5462
  };
5063
5463
  const result = await store.saveBlueprint(blueprint);
5064
5464
  if (result.success) {
5065
- console.log(chalk15.green("\n\u2705 Blueprint recorded successfully!\n"));
5066
- console.log(chalk15.dim(` ID: ${blueprint.id}`));
5067
- console.log(chalk15.dim(` Name: ${name}`));
5068
- console.log(chalk15.dim(` Framework: ${framework} ${version}`));
5465
+ console.log(chalk16.green("\n\u2705 Blueprint recorded successfully!\n"));
5466
+ console.log(chalk16.dim(` ID: ${blueprint.id}`));
5467
+ console.log(chalk16.dim(` Name: ${name}`));
5468
+ console.log(chalk16.dim(` Framework: ${framework} ${version}`));
5069
5469
  } else {
5070
- console.log(chalk15.red("\n\u274C Failed to record blueprint"));
5071
- console.log(chalk15.dim(` Error: ${result.error}`));
5470
+ console.log(chalk16.red("\n\u274C Failed to record blueprint"));
5471
+ console.log(chalk16.dim(` Error: ${result.error}`));
5072
5472
  process.exit(1);
5073
5473
  }
5074
5474
  }
@@ -5078,7 +5478,7 @@ async function learnListCommand(options) {
5078
5478
  const store = new PatternStore2(cwd);
5079
5479
  const patternType = options.type ?? "all";
5080
5480
  const showDeprecated = options.deprecated ?? false;
5081
- console.log(chalk15.cyan("\n\u{1F4DA} Recorded Learning Patterns\n"));
5481
+ console.log(chalk16.cyan("\n\u{1F4DA} Recorded Learning Patterns\n"));
5082
5482
  if (patternType === "all" || patternType === "fix") {
5083
5483
  const fixResult = await store.listFixPatterns({
5084
5484
  tags: options.tag ? [{ category: "framework", name: options.tag }] : void 0,
@@ -5086,29 +5486,29 @@ async function learnListCommand(options) {
5086
5486
  includeDeprecated: showDeprecated
5087
5487
  });
5088
5488
  if (fixResult.success && fixResult.data && fixResult.data.length > 0) {
5089
- console.log(chalk15.bold.yellow("\u{1F527} Fix Patterns:\n"));
5489
+ console.log(chalk16.bold.yellow("\u{1F527} Fix Patterns:\n"));
5090
5490
  for (const pattern of fixResult.data) {
5091
5491
  const isDeprecated = pattern.deprecatedAt !== void 0;
5092
5492
  const statusIcon = isDeprecated ? "\u26A0\uFE0F" : "\u2713";
5093
- const nameColor = isDeprecated ? chalk15.dim : chalk15.white;
5493
+ const nameColor = isDeprecated ? chalk16.dim : chalk16.white;
5094
5494
  console.log(` ${statusIcon} ${nameColor(pattern.name)}`);
5095
- console.log(chalk15.dim(` ID: ${pattern.id}`));
5096
- console.log(chalk15.dim(` Category: ${pattern.category}`));
5495
+ console.log(chalk16.dim(` ID: ${pattern.id}`));
5496
+ console.log(chalk16.dim(` Category: ${pattern.category}`));
5097
5497
  console.log(
5098
- chalk15.dim(` Created: ${formatDate(pattern.createdAt)}`)
5498
+ chalk16.dim(` Created: ${formatDate(pattern.createdAt)}`)
5099
5499
  );
5100
5500
  console.log(
5101
- chalk15.dim(
5501
+ chalk16.dim(
5102
5502
  ` Success Rate: ${(pattern.metrics.successRate * 100).toFixed(0)}% (${pattern.metrics.successes}/${pattern.metrics.applications})`
5103
5503
  )
5104
5504
  );
5105
5505
  if (pattern.tags.length > 0) {
5106
- console.log(chalk15.dim(` Tags: ${formatTags(pattern.tags)}`));
5506
+ console.log(chalk16.dim(` Tags: ${formatTags(pattern.tags)}`));
5107
5507
  }
5108
5508
  console.log("");
5109
5509
  }
5110
5510
  } else if (patternType === "fix") {
5111
- console.log(chalk15.dim(" No fix patterns found.\n"));
5511
+ console.log(chalk16.dim(" No fix patterns found.\n"));
5112
5512
  }
5113
5513
  }
5114
5514
  if (patternType === "all" || patternType === "blueprint") {
@@ -5118,46 +5518,46 @@ async function learnListCommand(options) {
5118
5518
  includeDeprecated: showDeprecated
5119
5519
  });
5120
5520
  if (bpResult.success && bpResult.data && bpResult.data.length > 0) {
5121
- console.log(chalk15.bold.blue("\u{1F4D0} Blueprints:\n"));
5521
+ console.log(chalk16.bold.blue("\u{1F4D0} Blueprints:\n"));
5122
5522
  for (const blueprint of bpResult.data) {
5123
5523
  const isDeprecated = blueprint.deprecatedAt !== void 0;
5124
5524
  const statusIcon = isDeprecated ? "\u26A0\uFE0F" : "\u2713";
5125
- const nameColor = isDeprecated ? chalk15.dim : chalk15.white;
5525
+ const nameColor = isDeprecated ? chalk16.dim : chalk16.white;
5126
5526
  console.log(` ${statusIcon} ${nameColor(blueprint.name)}`);
5127
- console.log(chalk15.dim(` ID: ${blueprint.id}`));
5128
- console.log(chalk15.dim(` Language: ${blueprint.stack.language}`));
5527
+ console.log(chalk16.dim(` ID: ${blueprint.id}`));
5528
+ console.log(chalk16.dim(` Language: ${blueprint.stack.language}`));
5129
5529
  console.log(
5130
- chalk15.dim(` Created: ${formatDate(blueprint.createdAt)}`)
5530
+ chalk16.dim(` Created: ${formatDate(blueprint.createdAt)}`)
5131
5531
  );
5132
5532
  console.log(
5133
- chalk15.dim(
5533
+ chalk16.dim(
5134
5534
  ` Success Rate: ${(blueprint.metrics.successRate * 100).toFixed(0)}% (${blueprint.metrics.successes}/${blueprint.metrics.applications})`
5135
5535
  )
5136
5536
  );
5137
5537
  if (blueprint.tags.length > 0) {
5138
- console.log(chalk15.dim(` Tags: ${formatTags(blueprint.tags)}`));
5538
+ console.log(chalk16.dim(` Tags: ${formatTags(blueprint.tags)}`));
5139
5539
  }
5140
5540
  console.log("");
5141
5541
  }
5142
5542
  } else if (patternType === "blueprint") {
5143
- console.log(chalk15.dim(" No blueprints found.\n"));
5543
+ console.log(chalk16.dim(" No blueprints found.\n"));
5144
5544
  }
5145
5545
  }
5146
5546
  const stats = await store.getStats();
5147
5547
  const totalPatterns = stats.totalFixes + stats.totalBlueprints;
5148
5548
  const totalDeprecated = stats.deprecatedFixes + stats.deprecatedBlueprints;
5149
- console.log(chalk15.dim("\u2501".repeat(40)));
5150
- console.log(chalk15.dim(`Total: ${totalPatterns} patterns`));
5151
- console.log(chalk15.dim(` Fix Patterns: ${stats.totalFixes}`));
5152
- console.log(chalk15.dim(` Blueprints: ${stats.totalBlueprints}`));
5153
- console.log(chalk15.dim(` Deprecated: ${totalDeprecated}`));
5549
+ console.log(chalk16.dim("\u2501".repeat(40)));
5550
+ console.log(chalk16.dim(`Total: ${totalPatterns} patterns`));
5551
+ console.log(chalk16.dim(` Fix Patterns: ${stats.totalFixes}`));
5552
+ console.log(chalk16.dim(` Blueprints: ${stats.totalBlueprints}`));
5553
+ console.log(chalk16.dim(` Deprecated: ${totalDeprecated}`));
5154
5554
  console.log("");
5155
5555
  }
5156
5556
  async function learnApplyCommand(patternId, options) {
5157
5557
  const cwd = getWorkspacePath();
5158
5558
  const store = new PatternStore2(cwd);
5159
5559
  const telemetry = new TelemetryCollector2(cwd);
5160
- console.log(chalk15.cyan("\n\u{1F527} Apply Learning Pattern\n"));
5560
+ console.log(chalk16.cyan("\n\u{1F527} Apply Learning Pattern\n"));
5161
5561
  let pattern = await store.getFixPattern(patternId);
5162
5562
  let patternType = "fix";
5163
5563
  if (!pattern.success || !pattern.data) {
@@ -5166,21 +5566,21 @@ async function learnApplyCommand(patternId, options) {
5166
5566
  pattern = bpResult;
5167
5567
  patternType = "blueprint";
5168
5568
  } else {
5169
- console.log(chalk15.red(`
5569
+ console.log(chalk16.red(`
5170
5570
  \u274C Pattern not found: ${patternId}`));
5171
5571
  console.log(
5172
- chalk15.dim(" Use 'workflow learn:list' to see available patterns")
5572
+ chalk16.dim(" Use 'workflow learn:list' to see available patterns")
5173
5573
  );
5174
5574
  process.exit(1);
5175
5575
  }
5176
5576
  }
5177
5577
  const patternData = pattern.data;
5178
- console.log(chalk15.white(` Pattern: ${patternData.name}`));
5179
- console.log(chalk15.dim(` Type: ${patternType}`));
5180
- console.log(chalk15.dim(` Description: ${patternData.description}`));
5578
+ console.log(chalk16.white(` Pattern: ${patternData.name}`));
5579
+ console.log(chalk16.dim(` Type: ${patternType}`));
5580
+ console.log(chalk16.dim(` Description: ${patternData.description}`));
5181
5581
  if (options.dryRun) {
5182
5582
  console.log(
5183
- chalk15.yellow("\n\u{1F4CB} DRY-RUN MODE: No changes will be applied\n")
5583
+ chalk16.yellow("\n\u{1F4CB} DRY-RUN MODE: No changes will be applied\n")
5184
5584
  );
5185
5585
  }
5186
5586
  const framework = options.framework ?? patternData.compatibility.frameworks[0]?.name ?? "unknown";
@@ -5188,27 +5588,27 @@ async function learnApplyCommand(patternId, options) {
5188
5588
  await telemetry.recordApplication(patternId, patternType, framework, version);
5189
5589
  if (patternType === "fix") {
5190
5590
  const fixPattern = patternData;
5191
- console.log(chalk15.cyan("\n\u{1F4CB} Solution Steps:\n"));
5591
+ console.log(chalk16.cyan("\n\u{1F4CB} Solution Steps:\n"));
5192
5592
  if (fixPattern.solution.steps) {
5193
5593
  for (let i = 0; i < fixPattern.solution.steps.length; i++) {
5194
5594
  const step = fixPattern.solution.steps[i];
5195
5595
  console.log(
5196
- chalk15.white(` ${i + 1}. [${step.action}] ${step.description}`)
5596
+ chalk16.white(` ${i + 1}. [${step.action}] ${step.description}`)
5197
5597
  );
5198
5598
  if (step.file) {
5199
- console.log(chalk15.dim(` File: ${step.file}`));
5599
+ console.log(chalk16.dim(` File: ${step.file}`));
5200
5600
  }
5201
5601
  }
5202
5602
  }
5203
5603
  } else {
5204
5604
  const blueprint = patternData;
5205
- console.log(chalk15.cyan("\n\u{1F4CB} Setup Steps:\n"));
5605
+ console.log(chalk16.cyan("\n\u{1F4CB} Setup Steps:\n"));
5206
5606
  if (blueprint.setup.steps) {
5207
5607
  for (let i = 0; i < blueprint.setup.steps.length; i++) {
5208
5608
  const step = blueprint.setup.steps[i];
5209
- console.log(chalk15.white(` ${i + 1}. ${step.description}`));
5609
+ console.log(chalk16.white(` ${i + 1}. ${step.description}`));
5210
5610
  if (step.command) {
5211
- console.log(chalk15.dim(` Command: ${step.command}`));
5611
+ console.log(chalk16.dim(` Command: ${step.command}`));
5212
5612
  }
5213
5613
  }
5214
5614
  }
@@ -5225,7 +5625,7 @@ async function learnApplyCommand(patternId, options) {
5225
5625
  if (confirmed) {
5226
5626
  await store.updatePatternMetrics(patternId, patternType, true);
5227
5627
  await telemetry.recordSuccess(patternId, patternType, framework, version);
5228
- console.log(chalk15.green("\n\u2705 Pattern marked as successfully applied!"));
5628
+ console.log(chalk16.green("\n\u2705 Pattern marked as successfully applied!"));
5229
5629
  } else {
5230
5630
  await store.updatePatternMetrics(patternId, patternType, false);
5231
5631
  await telemetry.recordFailure(
@@ -5236,7 +5636,7 @@ async function learnApplyCommand(patternId, options) {
5236
5636
  "unknown"
5237
5637
  );
5238
5638
  console.log(
5239
- chalk15.yellow("\n\u26A0\uFE0F Pattern application marked as unsuccessful.")
5639
+ chalk16.yellow("\n\u26A0\uFE0F Pattern application marked as unsuccessful.")
5240
5640
  );
5241
5641
  }
5242
5642
  }
@@ -5244,32 +5644,32 @@ async function learnApplyCommand(patternId, options) {
5244
5644
  async function learnSyncCommand(options) {
5245
5645
  const cwd = getWorkspacePath();
5246
5646
  const contributorManager = new ContributorManager2(cwd);
5247
- console.log(chalk15.cyan("\n\u{1F504} Sync Learning Patterns\n"));
5647
+ console.log(chalk16.cyan("\n\u{1F504} Sync Learning Patterns\n"));
5248
5648
  const config = await contributorManager.getConfig();
5249
5649
  if (!config.success || !config.data?.syncOptIn) {
5250
- console.log(chalk15.yellow("\u26A0\uFE0F Sync is not enabled.\n"));
5251
- console.log(chalk15.dim(" To enable sync, run:"));
5252
- console.log(chalk15.dim(" workflow learn:config --enable-sync\n"));
5650
+ console.log(chalk16.yellow("\u26A0\uFE0F Sync is not enabled.\n"));
5651
+ console.log(chalk16.dim(" To enable sync, run:"));
5652
+ console.log(chalk16.dim(" workflow learn:config --enable-sync\n"));
5253
5653
  console.log(
5254
- chalk15.dim(
5654
+ chalk16.dim(
5255
5655
  " This allows you to share anonymized patterns with the community."
5256
5656
  )
5257
5657
  );
5258
5658
  process.exit(0);
5259
5659
  }
5260
5660
  if (options.dryRun) {
5261
- console.log(chalk15.yellow("\u{1F4CB} DRY-RUN MODE: No changes will be synced\n"));
5661
+ console.log(chalk16.yellow("\u{1F4CB} DRY-RUN MODE: No changes will be synced\n"));
5262
5662
  }
5263
5663
  const store = new PatternStore2(cwd);
5264
5664
  const anonymizer = new PatternAnonymizer();
5265
5665
  const { fixes, blueprints } = await store.getPatternsForSync();
5266
5666
  console.log(
5267
- chalk15.dim(
5667
+ chalk16.dim(
5268
5668
  ` Patterns ready to sync: ${fixes.length} fixes, ${blueprints.length} blueprints`
5269
5669
  )
5270
5670
  );
5271
5671
  if (options.push) {
5272
- console.log(chalk15.cyan("\n\u{1F4E4} Pushing patterns...\n"));
5672
+ console.log(chalk16.cyan("\n\u{1F4E4} Pushing patterns...\n"));
5273
5673
  let anonymizedFixes = 0;
5274
5674
  let anonymizedBlueprints = 0;
5275
5675
  for (const fix of fixes) {
@@ -5277,7 +5677,7 @@ async function learnSyncCommand(options) {
5277
5677
  if (result.success) {
5278
5678
  anonymizedFixes++;
5279
5679
  if (!options.dryRun) {
5280
- console.log(chalk15.dim(` \u2713 Anonymized: ${fix.name}`));
5680
+ console.log(chalk16.dim(` \u2713 Anonymized: ${fix.name}`));
5281
5681
  }
5282
5682
  }
5283
5683
  }
@@ -5286,73 +5686,73 @@ async function learnSyncCommand(options) {
5286
5686
  if (result.success) {
5287
5687
  anonymizedBlueprints++;
5288
5688
  if (!options.dryRun) {
5289
- console.log(chalk15.dim(` \u2713 Anonymized: ${bp.name}`));
5689
+ console.log(chalk16.dim(` \u2713 Anonymized: ${bp.name}`));
5290
5690
  }
5291
5691
  }
5292
5692
  }
5293
5693
  console.log(
5294
- chalk15.green(
5694
+ chalk16.green(
5295
5695
  `
5296
5696
  \u2705 Ready to push ${anonymizedFixes} fixes and ${anonymizedBlueprints} blueprints`
5297
5697
  )
5298
5698
  );
5299
- console.log(chalk15.dim(" (Registry push not yet implemented)"));
5699
+ console.log(chalk16.dim(" (Registry push not yet implemented)"));
5300
5700
  }
5301
5701
  if (options.pull) {
5302
- console.log(chalk15.cyan("\n\u{1F4E5} Pulling patterns from registry...\n"));
5303
- console.log(chalk15.dim(" (Registry pull not yet implemented)"));
5702
+ console.log(chalk16.cyan("\n\u{1F4E5} Pulling patterns from registry...\n"));
5703
+ console.log(chalk16.dim(" (Registry pull not yet implemented)"));
5304
5704
  }
5305
5705
  if (!options.push && !options.pull) {
5306
5706
  console.log(
5307
- chalk15.dim(" Specify --push to upload or --pull to download patterns.\n")
5707
+ chalk16.dim(" Specify --push to upload or --pull to download patterns.\n")
5308
5708
  );
5309
5709
  }
5310
5710
  }
5311
5711
  async function learnConfigCommand(options) {
5312
5712
  const cwd = getWorkspacePath();
5313
5713
  const contributorManager = new ContributorManager2(cwd);
5314
- console.log(chalk15.cyan("\n\u2699\uFE0F Learning Configuration\n"));
5714
+ console.log(chalk16.cyan("\n\u2699\uFE0F Learning Configuration\n"));
5315
5715
  if (options.enableSync) {
5316
5716
  const result = await contributorManager.enableSync();
5317
5717
  if (result.success) {
5318
- console.log(chalk15.green("\u2705 Sync enabled"));
5718
+ console.log(chalk16.green("\u2705 Sync enabled"));
5319
5719
  console.log(
5320
- chalk15.dim(" Your patterns will be anonymized before sharing.")
5720
+ chalk16.dim(" Your patterns will be anonymized before sharing.")
5321
5721
  );
5322
5722
  } else {
5323
- console.log(chalk15.red(`\u274C Failed: ${result.error}`));
5723
+ console.log(chalk16.red(`\u274C Failed: ${result.error}`));
5324
5724
  }
5325
5725
  return;
5326
5726
  }
5327
5727
  if (options.disableSync) {
5328
5728
  const result = await contributorManager.disableSync();
5329
5729
  if (result.success) {
5330
- console.log(chalk15.green("\u2705 Sync disabled"));
5730
+ console.log(chalk16.green("\u2705 Sync disabled"));
5331
5731
  } else {
5332
- console.log(chalk15.red(`\u274C Failed: ${result.error}`));
5732
+ console.log(chalk16.red(`\u274C Failed: ${result.error}`));
5333
5733
  }
5334
5734
  return;
5335
5735
  }
5336
5736
  if (options.enableTelemetry) {
5337
5737
  const result = await contributorManager.enableTelemetry();
5338
5738
  if (result.success) {
5339
- console.log(chalk15.green("\u2705 Telemetry enabled"));
5739
+ console.log(chalk16.green("\u2705 Telemetry enabled"));
5340
5740
  console.log(
5341
- chalk15.dim(
5741
+ chalk16.dim(
5342
5742
  " Anonymous usage data helps improve pattern recommendations."
5343
5743
  )
5344
5744
  );
5345
5745
  } else {
5346
- console.log(chalk15.red(`\u274C Failed: ${result.error}`));
5746
+ console.log(chalk16.red(`\u274C Failed: ${result.error}`));
5347
5747
  }
5348
5748
  return;
5349
5749
  }
5350
5750
  if (options.disableTelemetry) {
5351
5751
  const result = await contributorManager.disableTelemetry();
5352
5752
  if (result.success) {
5353
- console.log(chalk15.green("\u2705 Telemetry disabled"));
5753
+ console.log(chalk16.green("\u2705 Telemetry disabled"));
5354
5754
  } else {
5355
- console.log(chalk15.red(`\u274C Failed: ${result.error}`));
5755
+ console.log(chalk16.red(`\u274C Failed: ${result.error}`));
5356
5756
  }
5357
5757
  return;
5358
5758
  }
@@ -5367,36 +5767,36 @@ async function learnConfigCommand(options) {
5367
5767
  }
5368
5768
  const result = await contributorManager.resetId();
5369
5769
  if (result.success) {
5370
- console.log(chalk15.green("\u2705 Contributor ID reset"));
5371
- console.log(chalk15.dim(` New ID: ${result.data?.id}`));
5770
+ console.log(chalk16.green("\u2705 Contributor ID reset"));
5771
+ console.log(chalk16.dim(` New ID: ${result.data?.id}`));
5372
5772
  } else {
5373
- console.log(chalk15.red(`\u274C Failed: ${result.error}`));
5773
+ console.log(chalk16.red(`\u274C Failed: ${result.error}`));
5374
5774
  }
5375
5775
  return;
5376
5776
  }
5377
5777
  const config = await contributorManager.getConfig();
5378
5778
  if (config.success && config.data) {
5379
- console.log(chalk15.white(" Current Settings:\n"));
5380
- console.log(chalk15.dim(` Contributor ID: ${config.data.id}`));
5381
- console.log(chalk15.dim(` Created: ${formatDate(config.data.createdAt)}`));
5779
+ console.log(chalk16.white(" Current Settings:\n"));
5780
+ console.log(chalk16.dim(` Contributor ID: ${config.data.id}`));
5781
+ console.log(chalk16.dim(` Created: ${formatDate(config.data.createdAt)}`));
5382
5782
  console.log(
5383
- chalk15.dim(` Sync Enabled: ${config.data.syncOptIn ? "Yes" : "No"}`)
5783
+ chalk16.dim(` Sync Enabled: ${config.data.syncOptIn ? "Yes" : "No"}`)
5384
5784
  );
5385
5785
  console.log(
5386
- chalk15.dim(
5786
+ chalk16.dim(
5387
5787
  ` Telemetry Enabled: ${config.data.telemetryEnabled ? "Yes" : "No"}`
5388
5788
  )
5389
5789
  );
5390
5790
  if (config.data.syncEnabledAt) {
5391
5791
  console.log(
5392
- chalk15.dim(
5792
+ chalk16.dim(
5393
5793
  ` Sync Enabled At: ${formatDate(config.data.syncEnabledAt)}`
5394
5794
  )
5395
5795
  );
5396
5796
  }
5397
5797
  } else {
5398
5798
  console.log(
5399
- chalk15.dim(
5799
+ chalk16.dim(
5400
5800
  " No configuration found. Settings will be created on first use.\n"
5401
5801
  )
5402
5802
  );
@@ -5405,7 +5805,7 @@ async function learnConfigCommand(options) {
5405
5805
  async function learnDeprecateCommand(patternId, reason) {
5406
5806
  const cwd = getWorkspacePath();
5407
5807
  const store = new PatternStore2(cwd);
5408
- console.log(chalk15.cyan("\n\u26A0\uFE0F Deprecate Pattern\n"));
5808
+ console.log(chalk16.cyan("\n\u26A0\uFE0F Deprecate Pattern\n"));
5409
5809
  let patternType = "fix";
5410
5810
  let pattern = await store.getFixPattern(patternId);
5411
5811
  if (!pattern.success || !pattern.data) {
@@ -5414,13 +5814,13 @@ async function learnDeprecateCommand(patternId, reason) {
5414
5814
  pattern = bpResult;
5415
5815
  patternType = "blueprint";
5416
5816
  } else {
5417
- console.log(chalk15.red(`
5817
+ console.log(chalk16.red(`
5418
5818
  \u274C Pattern not found: ${patternId}`));
5419
5819
  process.exit(1);
5420
5820
  }
5421
5821
  }
5422
- console.log(chalk15.white(` Pattern: ${pattern.data.name}`));
5423
- console.log(chalk15.dim(` Reason: ${reason}`));
5822
+ console.log(chalk16.white(` Pattern: ${pattern.data.name}`));
5823
+ console.log(chalk16.dim(` Reason: ${reason}`));
5424
5824
  const confirmed = await p11.confirm({
5425
5825
  message: "Are you sure you want to deprecate this pattern?",
5426
5826
  initialValue: false
@@ -5431,9 +5831,9 @@ async function learnDeprecateCommand(patternId, reason) {
5431
5831
  }
5432
5832
  const result = await store.deprecatePattern(patternId, patternType, reason);
5433
5833
  if (result.success) {
5434
- console.log(chalk15.green("\n\u2705 Pattern deprecated successfully"));
5834
+ console.log(chalk16.green("\n\u2705 Pattern deprecated successfully"));
5435
5835
  } else {
5436
- console.log(chalk15.red(`
5836
+ console.log(chalk16.red(`
5437
5837
  \u274C Failed: ${result.error}`));
5438
5838
  process.exit(1);
5439
5839
  }
@@ -5442,31 +5842,31 @@ async function learnStatsCommand() {
5442
5842
  const cwd = getWorkspacePath();
5443
5843
  const store = new PatternStore2(cwd);
5444
5844
  const telemetry = new TelemetryCollector2(cwd);
5445
- console.log(chalk15.cyan("\n\u{1F4CA} Learning Statistics\n"));
5845
+ console.log(chalk16.cyan("\n\u{1F4CA} Learning Statistics\n"));
5446
5846
  const storeStats = await store.getStats();
5447
5847
  const totalPatterns = storeStats.totalFixes + storeStats.totalBlueprints;
5448
5848
  const totalDeprecated = storeStats.deprecatedFixes + storeStats.deprecatedBlueprints;
5449
- console.log(chalk15.bold.white(" Patterns:\n"));
5450
- console.log(chalk15.dim(` Total: ${totalPatterns}`));
5451
- console.log(chalk15.dim(` Fix Patterns: ${storeStats.totalFixes}`));
5452
- console.log(chalk15.dim(` Blueprints: ${storeStats.totalBlueprints}`));
5453
- console.log(chalk15.dim(` Deprecated: ${totalDeprecated}`));
5849
+ console.log(chalk16.bold.white(" Patterns:\n"));
5850
+ console.log(chalk16.dim(` Total: ${totalPatterns}`));
5851
+ console.log(chalk16.dim(` Fix Patterns: ${storeStats.totalFixes}`));
5852
+ console.log(chalk16.dim(` Blueprints: ${storeStats.totalBlueprints}`));
5853
+ console.log(chalk16.dim(` Deprecated: ${totalDeprecated}`));
5454
5854
  const telemetryStats = await telemetry.getStats();
5455
- console.log(chalk15.bold.white("\n Telemetry:\n"));
5456
- console.log(chalk15.dim(` Pending Events: ${telemetryStats.pendingEvents}`));
5855
+ console.log(chalk16.bold.white("\n Telemetry:\n"));
5856
+ console.log(chalk16.dim(` Pending Events: ${telemetryStats.pendingEvents}`));
5457
5857
  console.log(
5458
- chalk15.dim(` Total Events Sent: ${telemetryStats.totalEventsSent}`)
5858
+ chalk16.dim(` Total Events Sent: ${telemetryStats.totalEventsSent}`)
5459
5859
  );
5460
5860
  if (telemetryStats.lastFlushAt) {
5461
5861
  console.log(
5462
- chalk15.dim(` Last Flush: ${formatDate(telemetryStats.lastFlushAt)}`)
5862
+ chalk16.dim(` Last Flush: ${formatDate(telemetryStats.lastFlushAt)}`)
5463
5863
  );
5464
5864
  }
5465
5865
  console.log("");
5466
5866
  }
5467
5867
 
5468
5868
  // src/cli/commands/solution.ts
5469
- import chalk16 from "chalk";
5869
+ import chalk17 from "chalk";
5470
5870
  import * as p12 from "@clack/prompts";
5471
5871
  import * as path2 from "path";
5472
5872
  import {
@@ -5509,7 +5909,7 @@ function truncate(str, maxLen) {
5509
5909
  async function solutionCaptureCommand(options) {
5510
5910
  const cwd = getWorkspacePath2();
5511
5911
  const store = new PatternStore3(cwd);
5512
- console.log(chalk16.cyan("\n\u{1F4E6} Capture Solution Pattern\n"));
5912
+ console.log(chalk17.cyan("\n\u{1F4E6} Capture Solution Pattern\n"));
5513
5913
  let targetPath = options.path;
5514
5914
  if (!targetPath) {
5515
5915
  const pathInput = await p12.text({
@@ -5617,22 +6017,22 @@ async function solutionCaptureCommand(options) {
5617
6017
  keywords
5618
6018
  );
5619
6019
  spinner10.stop("Solution analyzed");
5620
- console.log(chalk16.green("\n\u2713 Solution captured successfully!\n"));
5621
- console.log(chalk16.dim("\u2500".repeat(50)));
5622
- console.log(`${chalk16.bold("Name:")} ${pattern.name}`);
6020
+ console.log(chalk17.green("\n\u2713 Solution captured successfully!\n"));
6021
+ console.log(chalk17.dim("\u2500".repeat(50)));
6022
+ console.log(`${chalk17.bold("Name:")} ${pattern.name}`);
5623
6023
  console.log(
5624
- `${chalk16.bold("Category:")} ${formatCategory(pattern.category)}`
6024
+ `${chalk17.bold("Category:")} ${formatCategory(pattern.category)}`
5625
6025
  );
5626
6026
  console.log(
5627
- `${chalk16.bold("Files:")} ${pattern.implementation.files.length}`
6027
+ `${chalk17.bold("Files:")} ${pattern.implementation.files.length}`
5628
6028
  );
5629
6029
  console.log(
5630
- `${chalk16.bold("Dependencies:")} ${pattern.implementation.dependencies.length}`
6030
+ `${chalk17.bold("Dependencies:")} ${pattern.implementation.dependencies.length}`
5631
6031
  );
5632
6032
  console.log(
5633
- `${chalk16.bold("Framework:")} ${pattern.compatibility.framework || "generic"}`
6033
+ `${chalk17.bold("Framework:")} ${pattern.compatibility.framework || "generic"}`
5634
6034
  );
5635
- console.log(chalk16.dim("\u2500".repeat(50)));
6035
+ console.log(chalk17.dim("\u2500".repeat(50)));
5636
6036
  const confirm10 = await p12.confirm({
5637
6037
  message: "Save this solution pattern?",
5638
6038
  initialValue: true
@@ -5642,12 +6042,12 @@ async function solutionCaptureCommand(options) {
5642
6042
  process.exit(0);
5643
6043
  }
5644
6044
  await store.saveSolution(pattern);
5645
- console.log(chalk16.green(`
6045
+ console.log(chalk17.green(`
5646
6046
  \u2713 Solution saved with ID: ${pattern.id}
5647
6047
  `));
5648
6048
  } catch (error) {
5649
6049
  spinner10.stop("Analysis failed");
5650
- console.error(chalk16.red(`
6050
+ console.error(chalk17.red(`
5651
6051
  \u2717 Error: ${error.message}
5652
6052
  `));
5653
6053
  process.exit(1);
@@ -5656,7 +6056,7 @@ async function solutionCaptureCommand(options) {
5656
6056
  async function solutionSearchCommand(query, options) {
5657
6057
  const cwd = getWorkspacePath2();
5658
6058
  const store = new PatternStore3(cwd);
5659
- console.log(chalk16.cyan("\n\u{1F50D} Search Solution Patterns\n"));
6059
+ console.log(chalk17.cyan("\n\u{1F50D} Search Solution Patterns\n"));
5660
6060
  const keywords = query.split(/\s+/).filter((k) => k.length > 0);
5661
6061
  const result = await store.searchSolutions(keywords, {
5662
6062
  category: options.category,
@@ -5664,39 +6064,39 @@ async function solutionSearchCommand(query, options) {
5664
6064
  limit: options.limit ?? 10
5665
6065
  });
5666
6066
  if (!result.success || !result.data) {
5667
- console.error(chalk16.red(`
6067
+ console.error(chalk17.red(`
5668
6068
  \u2717 Search failed: ${result.error}
5669
6069
  `));
5670
6070
  return;
5671
6071
  }
5672
6072
  const solutions = result.data;
5673
6073
  if (solutions.length === 0) {
5674
- console.log(chalk16.yellow("No solutions found matching your query.\n"));
5675
- console.log(chalk16.dim("Try different keywords or fewer filters."));
6074
+ console.log(chalk17.yellow("No solutions found matching your query.\n"));
6075
+ console.log(chalk17.dim("Try different keywords or fewer filters."));
5676
6076
  return;
5677
6077
  }
5678
- console.log(chalk16.green(`Found ${solutions.length} solution(s):
6078
+ console.log(chalk17.green(`Found ${solutions.length} solution(s):
5679
6079
  `));
5680
- console.log(chalk16.dim("\u2500".repeat(70)));
6080
+ console.log(chalk17.dim("\u2500".repeat(70)));
5681
6081
  for (const solution of solutions) {
5682
6082
  console.log(
5683
- `${chalk16.bold(solution.name)} ${chalk16.dim(`(${solution.id.slice(0, 8)})`)}`
6083
+ `${chalk17.bold(solution.name)} ${chalk17.dim(`(${solution.id.slice(0, 8)})`)}`
5684
6084
  );
5685
6085
  console.log(` ${formatCategory(solution.category)}`);
5686
- console.log(` ${chalk16.dim(truncate(solution.description, 60))}`);
6086
+ console.log(` ${chalk17.dim(truncate(solution.description, 60))}`);
5687
6087
  console.log(
5688
6088
  ` Files: ${solution.implementation.files.length} | Framework: ${solution.compatibility.framework || "generic"} | Uses: ${solution.metrics.applications}`
5689
6089
  );
5690
- console.log(chalk16.dim("\u2500".repeat(70)));
6090
+ console.log(chalk17.dim("\u2500".repeat(70)));
5691
6091
  }
5692
6092
  console.log(
5693
- chalk16.dim("\nUse 'workflow solution:apply <id>' to apply a solution.")
6093
+ chalk17.dim("\nUse 'workflow solution:apply <id>' to apply a solution.")
5694
6094
  );
5695
6095
  }
5696
6096
  async function solutionListCommand(options) {
5697
6097
  const cwd = getWorkspacePath2();
5698
6098
  const store = new PatternStore3(cwd);
5699
- console.log(chalk16.cyan("\n\u{1F4CB} Solution Patterns\n"));
6099
+ console.log(chalk17.cyan("\n\u{1F4CB} Solution Patterns\n"));
5700
6100
  const result = await store.listSolutions({
5701
6101
  category: options.category,
5702
6102
  framework: options.framework,
@@ -5704,20 +6104,20 @@ async function solutionListCommand(options) {
5704
6104
  limit: options.limit ?? 20
5705
6105
  });
5706
6106
  if (!result.success || !result.data) {
5707
- console.error(chalk16.red(`
6107
+ console.error(chalk17.red(`
5708
6108
  \u2717 List failed: ${result.error}
5709
6109
  `));
5710
6110
  return;
5711
6111
  }
5712
6112
  const solutions = result.data;
5713
6113
  if (solutions.length === 0) {
5714
- console.log(chalk16.yellow("No solutions found.\n"));
6114
+ console.log(chalk17.yellow("No solutions found.\n"));
5715
6115
  console.log(
5716
- chalk16.dim("Use 'workflow solution:capture' to capture a solution.")
6116
+ chalk17.dim("Use 'workflow solution:capture' to capture a solution.")
5717
6117
  );
5718
6118
  return;
5719
6119
  }
5720
- console.log(chalk16.green(`${solutions.length} solution(s):
6120
+ console.log(chalk17.green(`${solutions.length} solution(s):
5721
6121
  `));
5722
6122
  const byCategory = /* @__PURE__ */ new Map();
5723
6123
  for (const solution of solutions) {
@@ -5726,24 +6126,24 @@ async function solutionListCommand(options) {
5726
6126
  byCategory.set(solution.category, list);
5727
6127
  }
5728
6128
  for (const [category, items] of byCategory) {
5729
- console.log(chalk16.bold(`
6129
+ console.log(chalk17.bold(`
5730
6130
  ${formatCategory(category)}`));
5731
- console.log(chalk16.dim("\u2500".repeat(50)));
6131
+ console.log(chalk17.dim("\u2500".repeat(50)));
5732
6132
  for (const solution of items) {
5733
- const deprecated = solution.deprecatedAt ? chalk16.red(" [DEPRECATED]") : "";
6133
+ const deprecated = solution.deprecatedAt ? chalk17.red(" [DEPRECATED]") : "";
5734
6134
  console.log(
5735
- ` ${chalk16.cyan(solution.id.slice(0, 8))} ${solution.name}${deprecated}`
6135
+ ` ${chalk17.cyan(solution.id.slice(0, 8))} ${solution.name}${deprecated}`
5736
6136
  );
5737
- console.log(` ${chalk16.dim(truncate(solution.description, 50))}`);
6137
+ console.log(` ${chalk17.dim(truncate(solution.description, 50))}`);
5738
6138
  console.log(
5739
- chalk16.dim(
6139
+ chalk17.dim(
5740
6140
  ` Created: ${formatDate2(solution.createdAt)} | Files: ${solution.implementation.files.length}`
5741
6141
  )
5742
6142
  );
5743
6143
  }
5744
6144
  }
5745
6145
  console.log(
5746
- chalk16.dim(
6146
+ chalk17.dim(
5747
6147
  "\nUse 'workflow solution:search <query>' to find specific solutions."
5748
6148
  )
5749
6149
  );
@@ -5751,10 +6151,10 @@ ${formatCategory(category)}`));
5751
6151
  async function solutionApplyCommand(solutionId, options) {
5752
6152
  const cwd = getWorkspacePath2();
5753
6153
  const store = new PatternStore3(cwd);
5754
- console.log(chalk16.cyan("\n\u{1F680} Apply Solution Pattern\n"));
6154
+ console.log(chalk17.cyan("\n\u{1F680} Apply Solution Pattern\n"));
5755
6155
  const result = await store.getSolution(solutionId);
5756
6156
  if (!result.success || !result.data) {
5757
- console.error(chalk16.red(`
6157
+ console.error(chalk17.red(`
5758
6158
  \u2717 Solution not found: ${solutionId}
5759
6159
  `));
5760
6160
  process.exit(1);
@@ -5762,7 +6162,7 @@ async function solutionApplyCommand(solutionId, options) {
5762
6162
  const solution = result.data;
5763
6163
  if (solution.deprecatedAt) {
5764
6164
  console.log(
5765
- chalk16.yellow(
6165
+ chalk17.yellow(
5766
6166
  `\u26A0\uFE0F This solution is deprecated: ${solution.deprecationReason || "No reason provided"}
5767
6167
  `
5768
6168
  )
@@ -5776,34 +6176,34 @@ async function solutionApplyCommand(solutionId, options) {
5776
6176
  process.exit(0);
5777
6177
  }
5778
6178
  }
5779
- console.log(chalk16.bold(`Solution: ${solution.name}`));
5780
- console.log(chalk16.dim(solution.description));
6179
+ console.log(chalk17.bold(`Solution: ${solution.name}`));
6180
+ console.log(chalk17.dim(solution.description));
5781
6181
  console.log();
5782
- console.log(chalk16.bold("Files to create:"));
6182
+ console.log(chalk17.bold("Files to create:"));
5783
6183
  const filesToApply = options.includeTests ? solution.implementation.files : solution.implementation.files.filter(
5784
6184
  (f) => f.role !== "test"
5785
6185
  );
5786
6186
  for (const file of filesToApply) {
5787
- console.log(chalk16.dim(` \u2022 ${file.path} (${file.role})`));
6187
+ console.log(chalk17.dim(` \u2022 ${file.path} (${file.role})`));
5788
6188
  }
5789
6189
  console.log();
5790
6190
  if (solution.implementation.dependencies.length > 0) {
5791
- console.log(chalk16.bold("Dependencies to install:"));
6191
+ console.log(chalk17.bold("Dependencies to install:"));
5792
6192
  for (const dep of solution.implementation.dependencies) {
5793
- console.log(chalk16.dim(` \u2022 ${dep.name}@${dep.version}`));
6193
+ console.log(chalk17.dim(` \u2022 ${dep.name}@${dep.version}`));
5794
6194
  }
5795
6195
  console.log();
5796
6196
  }
5797
6197
  if (solution.implementation.envVars.length > 0) {
5798
- console.log(chalk16.bold("Environment variables needed:"));
6198
+ console.log(chalk17.bold("Environment variables needed:"));
5799
6199
  for (const env of solution.implementation.envVars) {
5800
- const required = env.required ? chalk16.red("*") : "";
5801
- console.log(chalk16.dim(` \u2022 ${env.name}${required}`));
6200
+ const required = env.required ? chalk17.red("*") : "";
6201
+ console.log(chalk17.dim(` \u2022 ${env.name}${required}`));
5802
6202
  }
5803
6203
  console.log();
5804
6204
  }
5805
6205
  if (options.dryRun) {
5806
- console.log(chalk16.yellow("Dry run mode - no files were created.\n"));
6206
+ console.log(chalk17.yellow("Dry run mode - no files were created.\n"));
5807
6207
  return;
5808
6208
  }
5809
6209
  const confirm10 = await p12.confirm({
@@ -5828,19 +6228,19 @@ async function solutionApplyCommand(solutionId, options) {
5828
6228
  }
5829
6229
  await store.updateSolutionMetrics(solution.id, true);
5830
6230
  spinner10.stop("Solution applied");
5831
- console.log(chalk16.green(`
6231
+ console.log(chalk17.green(`
5832
6232
  \u2713 Solution applied successfully!
5833
6233
  `));
5834
- console.log(chalk16.dim(`Created ${filesToApply.length} file(s).`));
6234
+ console.log(chalk17.dim(`Created ${filesToApply.length} file(s).`));
5835
6235
  if (solution.implementation.dependencies.length > 0) {
5836
- console.log(chalk16.cyan("\nNext step: Install dependencies with:"));
6236
+ console.log(chalk17.cyan("\nNext step: Install dependencies with:"));
5837
6237
  const deps = solution.implementation.dependencies.map((d) => `${d.name}@${d.version}`).join(" ");
5838
- console.log(chalk16.dim(` npm install ${deps}`));
6238
+ console.log(chalk17.dim(` npm install ${deps}`));
5839
6239
  }
5840
6240
  } catch (error) {
5841
6241
  spinner10.stop("Application failed");
5842
6242
  await store.updateSolutionMetrics(solution.id, false);
5843
- console.error(chalk16.red(`
6243
+ console.error(chalk17.red(`
5844
6244
  \u2717 Error: ${error.message}
5845
6245
  `));
5846
6246
  process.exit(1);
@@ -5849,16 +6249,16 @@ async function solutionApplyCommand(solutionId, options) {
5849
6249
  async function solutionDeprecateCommand(solutionId, reason) {
5850
6250
  const cwd = getWorkspacePath2();
5851
6251
  const store = new PatternStore3(cwd);
5852
- console.log(chalk16.cyan("\n\u26A0\uFE0F Deprecate Solution Pattern\n"));
6252
+ console.log(chalk17.cyan("\n\u26A0\uFE0F Deprecate Solution Pattern\n"));
5853
6253
  const result = await store.getSolution(solutionId);
5854
6254
  if (!result.success || !result.data) {
5855
- console.error(chalk16.red(`
6255
+ console.error(chalk17.red(`
5856
6256
  \u2717 Solution not found: ${solutionId}
5857
6257
  `));
5858
6258
  process.exit(1);
5859
6259
  }
5860
6260
  const solution = result.data;
5861
- console.log(`Solution: ${chalk16.bold(solution.name)}`);
6261
+ console.log(`Solution: ${chalk17.bold(solution.name)}`);
5862
6262
  console.log(`Reason: ${reason}
5863
6263
  `);
5864
6264
  const confirm10 = await p12.confirm({
@@ -5870,27 +6270,27 @@ async function solutionDeprecateCommand(solutionId, reason) {
5870
6270
  process.exit(0);
5871
6271
  }
5872
6272
  await store.deprecateSolution(solutionId, reason);
5873
- console.log(chalk16.green(`
6273
+ console.log(chalk17.green(`
5874
6274
  \u2713 Solution deprecated.
5875
6275
  `));
5876
6276
  }
5877
6277
  async function solutionStatsCommand() {
5878
6278
  const cwd = getWorkspacePath2();
5879
6279
  const store = new PatternStore3(cwd);
5880
- console.log(chalk16.cyan("\n\u{1F4CA} Solution Pattern Statistics\n"));
6280
+ console.log(chalk17.cyan("\n\u{1F4CA} Solution Pattern Statistics\n"));
5881
6281
  const stats = await store.getStats();
5882
- console.log(chalk16.dim("\u2500".repeat(40)));
5883
- console.log(`${chalk16.bold("Solutions:")} ${stats.totalSolutions}`);
6282
+ console.log(chalk17.dim("\u2500".repeat(40)));
6283
+ console.log(`${chalk17.bold("Solutions:")} ${stats.totalSolutions}`);
5884
6284
  console.log(` Active: ${stats.totalSolutions - stats.deprecatedSolutions}`);
5885
6285
  console.log(` Deprecated: ${stats.deprecatedSolutions}`);
5886
6286
  console.log(` Private: ${stats.privateSolutions}`);
5887
6287
  console.log(` Synced: ${stats.syncedSolutions}`);
5888
- console.log(chalk16.dim("\u2500".repeat(40)));
5889
- console.log(`${chalk16.bold("Fixes:")} ${stats.totalFixes}`);
5890
- console.log(`${chalk16.bold("Blueprints:")} ${stats.totalBlueprints}`);
5891
- console.log(chalk16.dim("\u2500".repeat(40)));
6288
+ console.log(chalk17.dim("\u2500".repeat(40)));
6289
+ console.log(`${chalk17.bold("Fixes:")} ${stats.totalFixes}`);
6290
+ console.log(`${chalk17.bold("Blueprints:")} ${stats.totalBlueprints}`);
6291
+ console.log(chalk17.dim("\u2500".repeat(40)));
5892
6292
  console.log(`
5893
- ${chalk16.bold("By Category:")}`);
6293
+ ${chalk17.bold("By Category:")}`);
5894
6294
  const listResult = await store.listSolutions({ limit: 1e3 });
5895
6295
  if (listResult.success && listResult.data) {
5896
6296
  const categories = /* @__PURE__ */ new Map();
@@ -5921,12 +6321,40 @@ program.command("validate <type>").description("Validate branch name, commit mes
5921
6321
  "Offer improvement suggestions on validation errors"
5922
6322
  ).action(validateCommand);
5923
6323
  program.command("config <action>").description("Manage workflow configuration").argument("<action>", "Action: get, set, add, remove").argument("[key]", "Config key").argument("[value]", "Config value").action(configCommand);
6324
+ program.command("config:fix").description("Automatically fix common configuration validation issues").action(async () => {
6325
+ const chalk18 = (await import("chalk")).default;
6326
+ const { autoFixConfigFile: autoFixConfigFile2 } = await import("../config/index.js");
6327
+ console.log(chalk18.bold.cyan("\n\u{1F527} Workflow Configuration Auto-Fix\n"));
6328
+ const result = await autoFixConfigFile2();
6329
+ if (result.success) {
6330
+ if (result.changes.length === 0) {
6331
+ console.log(chalk18.green("\u2713 Configuration is already valid!"));
6332
+ } else {
6333
+ console.log(chalk18.green("\u2713 Configuration fixed successfully!\n"));
6334
+ console.log(chalk18.dim("Changes made:"));
6335
+ for (const change of result.changes) {
6336
+ console.log(chalk18.dim(` \u2022 ${change}`));
6337
+ }
6338
+ console.log();
6339
+ }
6340
+ process.exit(0);
6341
+ } else {
6342
+ if (result.configPath) {
6343
+ console.log(chalk18.red(`\u2717 Failed to fix configuration: ${result.error}`));
6344
+ } else {
6345
+ console.log(chalk18.red("\u2717 No workflow configuration file found"));
6346
+ console.log(chalk18.yellow(" Run: workflow init"));
6347
+ }
6348
+ process.exit(1);
6349
+ }
6350
+ });
5924
6351
  program.command("suggest").description("Submit an improvement suggestion").argument("<feedback>", "Your improvement suggestion").option("--author <author>", "Your name or username").option(
5925
6352
  "--category <category>",
5926
6353
  "Category: feature, bug, documentation, performance, other"
5927
6354
  ).action(suggestCommand);
5928
6355
  program.command("setup").description("Add workflow scripts to package.json").action(setupCommand);
5929
- program.command("doctor").description("Run health check and get optimization suggestions").action(doctorCommand);
6356
+ program.command("doctor").description("Run health check and get optimization suggestions").option("--check-guidelines-only", "Only check guidelines presence").option("--fix", "Automatically fix validation issues in configuration").action(doctorCommand);
6357
+ program.command("hooks <action>").description("Manage git hooks").action(hooksCommand);
5930
6358
  program.command("scope:create").description("Create a custom scope package").option("--name <name>", 'Package name (e.g., "fintech", "gaming")').option(
5931
6359
  "--scopes <scopes>",
5932
6360
  "Comma-separated scopes (format: name:description:emoji:category)"