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.
- package/LICENSE +21 -0
- package/README.md +15 -15
- package/dist/{auto-fix-7WAESKYO.js → auto-fix-WGRYEFLJ.js} +2 -2
- package/dist/{chunk-IWFUJ2DS.js → chunk-DWHIY7R4.js} +20 -9
- package/dist/chunk-DWHIY7R4.js.map +1 -0
- package/dist/{chunk-MMPXQG3O.js → chunk-K42R54II.js} +156 -57
- package/dist/chunk-K42R54II.js.map +1 -0
- package/dist/{chunk-XGS2VFBP.js → chunk-KJFRMHQU.js} +783 -18
- package/dist/chunk-KJFRMHQU.js.map +1 -0
- package/dist/{chunk-YELUGXOM.js → chunk-NPJJZHJG.js} +1 -1
- package/dist/chunk-NPJJZHJG.js.map +1 -0
- package/dist/{chunk-UWJ2ZGEI.js → chunk-OH6TK27N.js} +3 -3
- package/dist/{chunk-D36IFZUZ.js → chunk-PLVOGB6Y.js} +15 -4
- package/dist/chunk-PLVOGB6Y.js.map +1 -0
- package/dist/{chunk-ZLDJ2OGO.js → chunk-WK7D2AVV.js} +11 -3
- package/dist/{chunk-ZLDJ2OGO.js.map → chunk-WK7D2AVV.js.map} +1 -1
- package/dist/cli/index.js +1016 -315
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.js +2 -2
- package/dist/index.d.ts +78 -56
- package/dist/index.js +22 -10
- package/dist/scripts/postinstall.js +1 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/sync-HHQM3GKR.js +7 -0
- package/dist/validators/index.js +1 -1
- package/dist/verify-OIHY7SGG.js +8 -0
- package/package.json +30 -31
- package/dist/chunk-3ADL5QDN.js +0 -396
- package/dist/chunk-3ADL5QDN.js.map +0 -1
- package/dist/chunk-D36IFZUZ.js.map +0 -1
- package/dist/chunk-IWFUJ2DS.js.map +0 -1
- package/dist/chunk-MMPXQG3O.js.map +0 -1
- package/dist/chunk-XGS2VFBP.js.map +0 -1
- package/dist/chunk-YELUGXOM.js.map +0 -1
- package/dist/sync-ON7M53OC.js +0 -7
- package/dist/verify-TX6LFMI6.js +0 -8
- /package/dist/{auto-fix-7WAESKYO.js.map → auto-fix-WGRYEFLJ.js.map} +0 -0
- /package/dist/{chunk-UWJ2ZGEI.js.map → chunk-OH6TK27N.js.map} +0 -0
- /package/dist/{sync-ON7M53OC.js.map → sync-HHQM3GKR.js.map} +0 -0
- /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-
|
|
8
|
+
} from "../chunk-WK7D2AVV.js";
|
|
16
9
|
import {
|
|
17
10
|
hasConfig,
|
|
18
11
|
loadConfig,
|
|
19
12
|
loadConfigSafe
|
|
20
|
-
} from "../chunk-
|
|
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-
|
|
25
|
+
} from "../chunk-DWHIY7R4.js";
|
|
33
26
|
import {
|
|
34
27
|
autoFixConfigFile,
|
|
35
28
|
validateScopeDefinitions
|
|
36
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-NPJJZHJG.js";
|
|
37
30
|
import {
|
|
38
31
|
verifyCommand
|
|
39
|
-
} from "../chunk-
|
|
40
|
-
import
|
|
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-
|
|
42
|
+
} from "../chunk-K42R54II.js";
|
|
44
43
|
|
|
45
44
|
// src/cli/index.ts
|
|
46
45
|
import { Command as Command7 } from "commander";
|
|
47
|
-
import
|
|
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
|
|
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(
|
|
815
|
+
console.log(
|
|
816
|
+
chalk5.dim(` Current value: ${JSON.stringify(issue.currentValue)}`)
|
|
817
|
+
);
|
|
817
818
|
}
|
|
818
819
|
if (issue.suggestedFix) {
|
|
819
|
-
console.log(
|
|
820
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
5188
|
+
const path5 = await import("path");
|
|
5156
5189
|
const cwd = process.cwd();
|
|
5157
|
-
const gitDir =
|
|
5158
|
-
const hooksDir =
|
|
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 =
|
|
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(
|
|
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-
|
|
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(
|
|
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(
|
|
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) => ({
|
|
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(
|
|
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(
|
|
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(
|
|
5864
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
5916
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
6121
|
+
const existingNames = (existingResult.data || []).map(
|
|
6122
|
+
(s) => s.name.toLowerCase()
|
|
6123
|
+
);
|
|
6050
6124
|
const opportunities = [];
|
|
6051
6125
|
const patterns = [
|
|
6052
|
-
{
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
{
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
6102
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
6125
|
-
|
|
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(
|
|
6149
|
-
|
|
6308
|
+
console.log(
|
|
6309
|
+
chalk18.green(`
|
|
6310
|
+
\u2713 Migrated ${migrated} solutions to ${targetLabel}`)
|
|
6311
|
+
);
|
|
6150
6312
|
if (!targetPrivate) {
|
|
6151
|
-
console.log(
|
|
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(
|
|
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(
|
|
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: "
|
|
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: "
|
|
6491
|
-
{ value: "compatibility", label: "\u{1F517} Compatibility" },
|
|
6669
|
+
{ value: "migration", label: "\u{1F504} Migration" },
|
|
6492
6670
|
{ value: "deprecation", label: "\u26A0\uFE0F Deprecation" },
|
|
6493
|
-
{ value: "
|
|
6494
|
-
{ value: "
|
|
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(
|
|
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
|
|
6940
|
+
let fixPattern;
|
|
6941
|
+
let blueprintPattern;
|
|
6770
6942
|
let patternType = "fix";
|
|
6771
|
-
|
|
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
|
-
|
|
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 =
|
|
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?.
|
|
6795
|
-
const version = options.version ?? patternData.compatibility?.
|
|
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.
|
|
6807
|
-
console.log(chalk20.dim(`
|
|
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 (
|
|
6815
|
-
for (let i = 0; i <
|
|
6816
|
-
const step =
|
|
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(
|
|
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
|
|
7167
|
+
for (const pattern of fixesToUpdate) {
|
|
6992
7168
|
const result2 = await store.saveFixPattern({
|
|
6993
|
-
...
|
|
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
|
|
7036
|
-
|
|
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
|
-
|
|
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
|
|
7051
|
-
|
|
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: ${
|
|
7235
|
+
console.log(chalk20.dim(` Name: ${patternInfo.name}`));
|
|
7056
7236
|
return;
|
|
7057
7237
|
}
|
|
7058
|
-
console.log(chalk20.white(` Pattern: ${
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
7103
|
-
|
|
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: ${
|
|
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(
|
|
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,
|
|
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(
|
|
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
|
-
|
|
7645
|
+
react: [{ category: "framework", name: "react" }],
|
|
7446
7646
|
"react-dom": [{ category: "framework", name: "react" }],
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
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
|
-
|
|
7455
|
-
|
|
7654
|
+
astro: [{ category: "framework", name: "astro" }],
|
|
7655
|
+
remix: [{ category: "framework", name: "remix" }],
|
|
7456
7656
|
// Backend Frameworks
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
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
|
-
|
|
7662
|
+
hapi: [{ category: "framework", name: "hapi" }],
|
|
7463
7663
|
// Testing
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
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
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
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
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
"
|
|
7484
|
-
|
|
7485
|
-
|
|
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": [
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
"@
|
|
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: "
|
|
7494
|
-
"@radix-ui/react-dropdown-menu": [{ category: "
|
|
7495
|
-
"@shadcn/ui": [{ category: "
|
|
7496
|
-
"@chakra-ui/react": [{ category: "
|
|
7497
|
-
"@mantine/core": [{ category: "
|
|
7498
|
-
"@headlessui/react": [{ category: "
|
|
7499
|
-
|
|
7500
|
-
"@mui/material": [{ category: "
|
|
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
|
-
|
|
7503
|
-
"styled-components": [{ category: "
|
|
7504
|
-
"@emotion/react": [{ category: "
|
|
7505
|
-
|
|
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": [
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
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": [
|
|
7516
|
-
|
|
7517
|
-
|
|
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
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
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
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
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
|
-
|
|
7530
|
-
"date-fns": [{ category: "
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
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
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
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
|
-
|
|
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(
|
|
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("
|
|
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("
|
|
7950
|
+
addTag("testing", "testing");
|
|
7629
7951
|
}
|
|
7630
7952
|
if (fileName.includes("config") || fileName.startsWith(".")) {
|
|
7631
|
-
addTag("
|
|
7953
|
+
addTag("file-type", "configuration");
|
|
7632
7954
|
}
|
|
7633
7955
|
if (filePath.includes("/components/") || filePath.includes("\\components\\")) {
|
|
7634
|
-
addTag("
|
|
7956
|
+
addTag("ui", "component");
|
|
7635
7957
|
}
|
|
7636
7958
|
if (filePath.includes("/hooks/") || filePath.includes("\\hooks\\") || fileName.startsWith("use")) {
|
|
7637
|
-
addTag("
|
|
7959
|
+
addTag("pattern", "hooks");
|
|
7638
7960
|
}
|
|
7639
7961
|
if (filePath.includes("/api/") || filePath.includes("\\api\\") || filePath.includes("/routes/")) {
|
|
7640
|
-
addTag("
|
|
7962
|
+
addTag("api", "api");
|
|
7641
7963
|
}
|
|
7642
7964
|
if (filePath.includes("/utils/") || filePath.includes("\\utils\\") || filePath.includes("/lib/")) {
|
|
7643
|
-
addTag("
|
|
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)
|
|
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)
|
|
7741
|
-
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
8152
|
-
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
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(
|
|
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(
|
|
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(
|
|
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-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
8828
|
+
const path5 = await import("path");
|
|
8426
8829
|
const cwd = process.cwd();
|
|
8427
|
-
const configFiles = [
|
|
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 =
|
|
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
|
|
8875
|
+
const path5 = await import("path");
|
|
8469
8876
|
const cwd = process.cwd();
|
|
8470
|
-
const configFiles = [
|
|
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 =
|
|
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(
|
|
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-
|
|
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(
|
|
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(
|
|
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(
|
|
8962
|
+
console.log(
|
|
8963
|
+
` ${emoji} ${chalk22.green(scope.padEnd(15))} ${bar} ${count}`
|
|
8964
|
+
);
|
|
8544
8965
|
}
|
|
8545
8966
|
if (unscoped > 0) {
|
|
8546
|
-
console.log(
|
|
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(
|
|
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(
|
|
9317
|
+
readFileSync3(join13(__dirname4, "../../package.json"), "utf-8")
|
|
8649
9318
|
);
|
|
8650
9319
|
function deprecationWarning(oldCmd, newCmd) {
|
|
8651
|
-
console.warn(
|
|
8652
|
-
|
|
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
|
-
${
|
|
8668
|
-
${
|
|
9354
|
+
${chalk24.bold("Examples:")}
|
|
9355
|
+
${chalk24.dim("# Enable sync")}
|
|
8669
9356
|
$ workflow sync --enable-sync
|
|
8670
9357
|
|
|
8671
|
-
${
|
|
9358
|
+
${chalk24.dim("# Disable sync")}
|
|
8672
9359
|
$ workflow sync --disable-sync
|
|
8673
9360
|
|
|
8674
|
-
${
|
|
9361
|
+
${chalk24.dim("# Interactive sync (prompts for direction)")}
|
|
8675
9362
|
$ workflow sync
|
|
8676
9363
|
|
|
8677
|
-
${
|
|
9364
|
+
${chalk24.dim("# Push local patterns to registry")}
|
|
8678
9365
|
$ workflow sync --push
|
|
8679
9366
|
|
|
8680
|
-
${
|
|
9367
|
+
${chalk24.dim("# Pull patterns from registry")}
|
|
8681
9368
|
$ workflow sync --pull
|
|
8682
9369
|
|
|
8683
|
-
${
|
|
9370
|
+
${chalk24.dim("# Sync solutions only")}
|
|
8684
9371
|
$ workflow sync --solutions --push
|
|
8685
9372
|
|
|
8686
|
-
${
|
|
9373
|
+
${chalk24.dim("# Include private patterns in push")}
|
|
8687
9374
|
$ workflow sync --solutions --push --include-private
|
|
8688
9375
|
|
|
8689
|
-
${
|
|
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
|
|
9390
|
+
const chalk25 = (await import("chalk")).default;
|
|
8704
9391
|
const { autoFixConfigFile: autoFixConfigFile2 } = await import("../config/index.js");
|
|
8705
|
-
console.log(
|
|
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(
|
|
9396
|
+
console.log(chalk25.green("\u2713 Configuration is already valid!"));
|
|
8710
9397
|
} else {
|
|
8711
|
-
console.log(
|
|
8712
|
-
console.log(
|
|
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(
|
|
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(
|
|
9408
|
+
console.log(
|
|
9409
|
+
chalk25.red(`\u2717 Failed to fix configuration: ${result.error}`)
|
|
9410
|
+
);
|
|
8722
9411
|
} else {
|
|
8723
|
-
console.log(
|
|
8724
|
-
console.log(
|
|
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").
|
|
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(
|
|
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(
|
|
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(
|
|
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 () => {
|