workflow-agent-cli 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-HKRWHFVI.js → chunk-2WUPMAH3.js} +283 -3
- package/dist/chunk-2WUPMAH3.js.map +1 -0
- package/dist/cli/index.js +444 -277
- package/dist/cli/index.js.map +1 -1
- package/dist/scripts/postinstall.js +23 -3
- package/dist/scripts/postinstall.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-HKRWHFVI.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -23,8 +23,13 @@ import {
|
|
|
23
23
|
SCRIPT_CATEGORIES,
|
|
24
24
|
TOTAL_SCRIPTS,
|
|
25
25
|
WORKFLOW_SCRIPTS,
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
findTemplatesDirectory,
|
|
27
|
+
generateCopilotInstructions,
|
|
28
|
+
getMandatoryTemplateFilenames,
|
|
29
|
+
installMandatoryTemplates,
|
|
30
|
+
templateMetadata,
|
|
31
|
+
updateTemplates
|
|
32
|
+
} from "../chunk-2WUPMAH3.js";
|
|
28
33
|
|
|
29
34
|
// src/cli/index.ts
|
|
30
35
|
import { Command } from "commander";
|
|
@@ -311,10 +316,10 @@ async function initCommand(options) {
|
|
|
311
316
|
try {
|
|
312
317
|
const presetModule = await import(`@workflow/scopes-${preset}`);
|
|
313
318
|
scopes = presetModule.scopes || presetModule.default.scopes;
|
|
314
|
-
const
|
|
315
|
-
|
|
319
|
+
const spinner9 = p.spinner();
|
|
320
|
+
spinner9.start(`Loading ${presetModule.default?.name || preset} preset`);
|
|
316
321
|
await new Promise((resolve2) => setTimeout(resolve2, 500));
|
|
317
|
-
|
|
322
|
+
spinner9.stop(`\u2713 Loaded ${scopes.length} scopes from preset`);
|
|
318
323
|
} catch (error) {
|
|
319
324
|
console.log(
|
|
320
325
|
chalk.yellow(
|
|
@@ -361,8 +366,8 @@ async function initCommand(options) {
|
|
|
361
366
|
process.exit(0);
|
|
362
367
|
}
|
|
363
368
|
if (shouldGenerateGuidelines) {
|
|
364
|
-
const
|
|
365
|
-
|
|
369
|
+
const spinner9 = p.spinner();
|
|
370
|
+
spinner9.start("Generating guidelines...");
|
|
366
371
|
try {
|
|
367
372
|
const templatesDir = join(__dirname, "../../templates");
|
|
368
373
|
await validateTemplateDirectory(templatesDir);
|
|
@@ -374,7 +379,7 @@ async function initCommand(options) {
|
|
|
374
379
|
guidelinesDir,
|
|
375
380
|
context
|
|
376
381
|
);
|
|
377
|
-
|
|
382
|
+
spinner9.stop(`\u2713 Generated ${renderedFiles.length} guideline documents`);
|
|
378
383
|
const instructionsSpinner = p.spinner();
|
|
379
384
|
instructionsSpinner.start("Generating AI agent instructions...");
|
|
380
385
|
const result = generateCopilotInstructions(cwd, { silent: true });
|
|
@@ -384,7 +389,7 @@ async function initCommand(options) {
|
|
|
384
389
|
instructionsSpinner.stop("\u26A0\uFE0F Could not generate copilot instructions");
|
|
385
390
|
}
|
|
386
391
|
} catch (error) {
|
|
387
|
-
|
|
392
|
+
spinner9.stop("\u26A0\uFE0F Could not generate guidelines");
|
|
388
393
|
console.log(
|
|
389
394
|
chalk.yellow(
|
|
390
395
|
`
|
|
@@ -606,7 +611,10 @@ async function doctorCommand() {
|
|
|
606
611
|
import * as p3 from "@clack/prompts";
|
|
607
612
|
import chalk6 from "chalk";
|
|
608
613
|
import { readFileSync, writeFileSync, existsSync as existsSync2 } from "fs";
|
|
609
|
-
import { join as join2 } from "path";
|
|
614
|
+
import { join as join2, dirname as dirname2 } from "path";
|
|
615
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
616
|
+
var __filename2 = fileURLToPath2(import.meta.url);
|
|
617
|
+
var __dirname2 = dirname2(__filename2);
|
|
610
618
|
async function setupCommand() {
|
|
611
619
|
p3.intro(chalk6.bgBlue(" workflow-agent setup "));
|
|
612
620
|
const cwd = process.cwd();
|
|
@@ -677,6 +685,24 @@ async function setupCommand() {
|
|
|
677
685
|
console.log(chalk6.dim(" pnpm run workflow:init"));
|
|
678
686
|
console.log(chalk6.dim(" npm run workflow:init\n"));
|
|
679
687
|
const guidelinesDir = join2(cwd, "guidelines");
|
|
688
|
+
if (!existsSync2(guidelinesDir)) {
|
|
689
|
+
const templatesDir = findTemplatesDirectory(__dirname2);
|
|
690
|
+
if (templatesDir) {
|
|
691
|
+
const templateResult = installMandatoryTemplates(cwd, templatesDir, {
|
|
692
|
+
silent: false,
|
|
693
|
+
skipIfExists: true,
|
|
694
|
+
mandatoryOnly: true
|
|
695
|
+
});
|
|
696
|
+
if (templateResult.installed.length > 0) {
|
|
697
|
+
console.log(
|
|
698
|
+
chalk6.green(
|
|
699
|
+
`
|
|
700
|
+
\u2713 Installed ${templateResult.installed.length} mandatory guideline templates`
|
|
701
|
+
)
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
680
706
|
if (existsSync2(guidelinesDir)) {
|
|
681
707
|
const result = generateCopilotInstructions(cwd, { silent: false });
|
|
682
708
|
if (result.success) {
|
|
@@ -872,8 +898,8 @@ async function scopeCreateCommand(options) {
|
|
|
872
898
|
process.exit(0);
|
|
873
899
|
}
|
|
874
900
|
}
|
|
875
|
-
const
|
|
876
|
-
|
|
901
|
+
const spinner9 = p4.spinner();
|
|
902
|
+
spinner9.start("Creating package structure...");
|
|
877
903
|
try {
|
|
878
904
|
await mkdir2(join3(outputDir, "src"), { recursive: true });
|
|
879
905
|
const packageJson = {
|
|
@@ -1004,7 +1030,7 @@ describe('${presetName} Scope Preset', () => {
|
|
|
1004
1030
|
"utf-8"
|
|
1005
1031
|
);
|
|
1006
1032
|
}
|
|
1007
|
-
|
|
1033
|
+
spinner9.stop("\u2713 Package structure created");
|
|
1008
1034
|
if (isMonorepo2) {
|
|
1009
1035
|
const workspaceFile = join3(cwd, "pnpm-workspace.yaml");
|
|
1010
1036
|
const workspaceContent = await readFile(workspaceFile, "utf-8");
|
|
@@ -1056,7 +1082,7 @@ describe('${presetName} Scope Preset', () => {
|
|
|
1056
1082
|
);
|
|
1057
1083
|
}
|
|
1058
1084
|
} catch (error) {
|
|
1059
|
-
|
|
1085
|
+
spinner9.stop("\u2717 Failed to create package");
|
|
1060
1086
|
console.error(chalk7.red("\nError:"), error);
|
|
1061
1087
|
process.exit(1);
|
|
1062
1088
|
}
|
|
@@ -1184,8 +1210,8 @@ async function scopeMigrateCommand(options) {
|
|
|
1184
1210
|
process.exit(0);
|
|
1185
1211
|
}
|
|
1186
1212
|
}
|
|
1187
|
-
const
|
|
1188
|
-
|
|
1213
|
+
const spinner9 = p5.spinner();
|
|
1214
|
+
spinner9.start("Migrating scopes to package...");
|
|
1189
1215
|
try {
|
|
1190
1216
|
await mkdir3(join4(outputDir, "src"), { recursive: true });
|
|
1191
1217
|
const packageJson = {
|
|
@@ -1313,7 +1339,7 @@ describe('${presetName} Scope Preset (Migrated)', () => {
|
|
|
1313
1339
|
});
|
|
1314
1340
|
`;
|
|
1315
1341
|
await writeFile3(join4(outputDir, "src", "index.test.ts"), testFile, "utf-8");
|
|
1316
|
-
|
|
1342
|
+
spinner9.stop("\u2713 Package created from migrated scopes");
|
|
1317
1343
|
if (isMonorepo2) {
|
|
1318
1344
|
const workspaceFile = join4(cwd, "pnpm-workspace.yaml");
|
|
1319
1345
|
const workspaceContent = await readFile2(workspaceFile, "utf-8");
|
|
@@ -1385,7 +1411,7 @@ describe('${presetName} Scope Preset (Migrated)', () => {
|
|
|
1385
1411
|
)
|
|
1386
1412
|
);
|
|
1387
1413
|
} catch (error) {
|
|
1388
|
-
|
|
1414
|
+
spinner9.stop("\u2717 Migration failed");
|
|
1389
1415
|
console.error(chalk8.red("\nError:"), error);
|
|
1390
1416
|
process.exit(1);
|
|
1391
1417
|
}
|
|
@@ -1625,14 +1651,14 @@ import chalk10 from "chalk";
|
|
|
1625
1651
|
async function autoSetupCommand(options) {
|
|
1626
1652
|
console.log(chalk10.bold.cyan("\n\u{1F527} Workflow Agent Auto-Setup\n"));
|
|
1627
1653
|
const cwd = process.cwd();
|
|
1628
|
-
const
|
|
1629
|
-
|
|
1654
|
+
const spinner9 = p6.spinner();
|
|
1655
|
+
spinner9.start("Analyzing project...");
|
|
1630
1656
|
let report;
|
|
1631
1657
|
try {
|
|
1632
1658
|
report = await generateAuditReport(cwd);
|
|
1633
|
-
|
|
1659
|
+
spinner9.stop("\u2713 Project analysis complete");
|
|
1634
1660
|
} catch (error) {
|
|
1635
|
-
|
|
1661
|
+
spinner9.stop("\u2717 Failed to analyze project");
|
|
1636
1662
|
console.error(
|
|
1637
1663
|
chalk10.red(
|
|
1638
1664
|
`Error: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -2808,7 +2834,7 @@ var QuestionGenerator = class {
|
|
|
2808
2834
|
category: "Platform Strategy",
|
|
2809
2835
|
question: `Are our platform choices (${technology.platforms.join(", ")}) aligned with target market and growth plans?`,
|
|
2810
2836
|
context: `Currently deployed on ${technology.platforms.join(" + ")}`,
|
|
2811
|
-
findings: technology.platforms.map((
|
|
2837
|
+
findings: technology.platforms.map((p12) => `Supports ${p12} platform`),
|
|
2812
2838
|
recommendations: [
|
|
2813
2839
|
"Validate platform coverage matches user demographics",
|
|
2814
2840
|
"Assess cross-platform development efficiency",
|
|
@@ -2870,7 +2896,7 @@ var QuestionGenerator = class {
|
|
|
2870
2896
|
category: "Business Alignment",
|
|
2871
2897
|
question: `How is our authentication solution (${authCat.packages.join(", ")}) supporting user onboarding and security requirements?`,
|
|
2872
2898
|
context: `Using ${authCat.packages.join(" + ")} for authentication`,
|
|
2873
|
-
findings: authCat.packages.map((
|
|
2899
|
+
findings: authCat.packages.map((p12) => `Auth provider: ${p12}`),
|
|
2874
2900
|
recommendations: [
|
|
2875
2901
|
"Measure authentication success rates and friction points",
|
|
2876
2902
|
"Ensure compliance with security standards (SOC2, GDPR, etc.)",
|
|
@@ -2922,12 +2948,12 @@ var QuestionGenerator = class {
|
|
|
2922
2948
|
});
|
|
2923
2949
|
}
|
|
2924
2950
|
if (packages.outdated && packages.outdated.length > 10) {
|
|
2925
|
-
const breakingCount = packages.outdated.filter((
|
|
2951
|
+
const breakingCount = packages.outdated.filter((p12) => p12.breaking).length;
|
|
2926
2952
|
questions.push({
|
|
2927
2953
|
category: "Technical Debt",
|
|
2928
2954
|
question: `How should we prioritize updating ${packages.outdated.length} outdated packages${breakingCount > 0 ? ` (${breakingCount} with breaking changes)` : ""}?`,
|
|
2929
2955
|
context: "Dependency audit found outdated packages",
|
|
2930
|
-
findings: packages.outdated.slice(0, 5).map((
|
|
2956
|
+
findings: packages.outdated.slice(0, 5).map((p12) => `${p12.name}: ${p12.current} \u2192 ${p12.latest}`),
|
|
2931
2957
|
recommendations: [
|
|
2932
2958
|
"Create update roadmap starting with non-breaking changes",
|
|
2933
2959
|
"Test breaking changes in feature branches",
|
|
@@ -3237,10 +3263,10 @@ var ReportComparator = class {
|
|
|
3237
3263
|
*/
|
|
3238
3264
|
comparePackages() {
|
|
3239
3265
|
const baselineProduction = new Map(
|
|
3240
|
-
this.baseline.packages.production.map((
|
|
3266
|
+
this.baseline.packages.production.map((p12) => [p12.name, p12])
|
|
3241
3267
|
);
|
|
3242
3268
|
const currentProduction = new Map(
|
|
3243
|
-
this.current.packages.production.map((
|
|
3269
|
+
this.current.packages.production.map((p12) => [p12.name, p12])
|
|
3244
3270
|
);
|
|
3245
3271
|
const added = [];
|
|
3246
3272
|
const removed = [];
|
|
@@ -3272,10 +3298,10 @@ var ReportComparator = class {
|
|
|
3272
3298
|
}
|
|
3273
3299
|
}
|
|
3274
3300
|
const baselineDev = new Map(
|
|
3275
|
-
this.baseline.packages.development.map((
|
|
3301
|
+
this.baseline.packages.development.map((p12) => [p12.name, p12])
|
|
3276
3302
|
);
|
|
3277
3303
|
const currentDev = new Map(
|
|
3278
|
-
this.current.packages.development.map((
|
|
3304
|
+
this.current.packages.development.map((p12) => [p12.name, p12])
|
|
3279
3305
|
);
|
|
3280
3306
|
for (const [name, pkg] of currentDev) {
|
|
3281
3307
|
if (!baselineDev.has(name)) {
|
|
@@ -3563,20 +3589,20 @@ async function advisoryCommand(options) {
|
|
|
3563
3589
|
includeHealth,
|
|
3564
3590
|
excludePatterns: advisoryConfig?.excludePatterns
|
|
3565
3591
|
});
|
|
3566
|
-
const
|
|
3592
|
+
const spinner9 = p7.spinner();
|
|
3567
3593
|
const depthLabels = {
|
|
3568
3594
|
executive: "executive summary",
|
|
3569
3595
|
quick: "quick scan",
|
|
3570
3596
|
standard: "standard analysis",
|
|
3571
3597
|
comprehensive: "comprehensive analysis"
|
|
3572
3598
|
};
|
|
3573
|
-
|
|
3599
|
+
spinner9.start(`Running ${depthLabels[depth]}...`);
|
|
3574
3600
|
let analysis;
|
|
3575
3601
|
try {
|
|
3576
3602
|
analysis = await analyzer.analyze();
|
|
3577
|
-
|
|
3603
|
+
spinner9.stop(`\u2713 Analysis complete`);
|
|
3578
3604
|
} catch (error) {
|
|
3579
|
-
|
|
3605
|
+
spinner9.stop("\u2717 Analysis failed");
|
|
3580
3606
|
console.error(
|
|
3581
3607
|
chalk11.red(
|
|
3582
3608
|
`Error: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -3593,17 +3619,17 @@ async function advisoryCommand(options) {
|
|
|
3593
3619
|
if (options.compare) {
|
|
3594
3620
|
const comparisonPath = options.compare.endsWith(".json") ? join6(cwd, options.compare) : join6(cwd, options.compare, "analysis.json");
|
|
3595
3621
|
if (existsSync6(comparisonPath)) {
|
|
3596
|
-
|
|
3622
|
+
spinner9.start("Comparing with previous report...");
|
|
3597
3623
|
try {
|
|
3598
3624
|
const previousContent = await readFile4(comparisonPath, "utf-8");
|
|
3599
3625
|
const previousAnalysis = JSON.parse(previousContent);
|
|
3600
3626
|
comparator = new ReportComparator(previousAnalysis, analysis);
|
|
3601
3627
|
comparisonReport = comparator.compare();
|
|
3602
|
-
|
|
3628
|
+
spinner9.stop("\u2713 Comparison complete");
|
|
3603
3629
|
console.log("");
|
|
3604
3630
|
displayComparisonSummary(comparisonReport);
|
|
3605
3631
|
} catch (error) {
|
|
3606
|
-
|
|
3632
|
+
spinner9.stop("\u26A0 Comparison failed");
|
|
3607
3633
|
console.warn(chalk11.yellow(`Could not compare reports: ${error}`));
|
|
3608
3634
|
}
|
|
3609
3635
|
} else {
|
|
@@ -3622,7 +3648,7 @@ async function advisoryCommand(options) {
|
|
|
3622
3648
|
}
|
|
3623
3649
|
const fullOutputDir = join6(cwd, outputDir);
|
|
3624
3650
|
await mkdir4(fullOutputDir, { recursive: true });
|
|
3625
|
-
|
|
3651
|
+
spinner9.start("Generating reports...");
|
|
3626
3652
|
try {
|
|
3627
3653
|
const timestamp = options.timestamp ? (/* @__PURE__ */ new Date()).toISOString().split("T")[0] : "";
|
|
3628
3654
|
if (options.format === "json") {
|
|
@@ -3636,9 +3662,9 @@ async function advisoryCommand(options) {
|
|
|
3636
3662
|
timestamp
|
|
3637
3663
|
);
|
|
3638
3664
|
}
|
|
3639
|
-
|
|
3665
|
+
spinner9.stop("\u2713 Reports generated");
|
|
3640
3666
|
} catch (error) {
|
|
3641
|
-
|
|
3667
|
+
spinner9.stop("\u2717 Failed to write reports");
|
|
3642
3668
|
console.error(chalk11.red(`Error: ${error}`));
|
|
3643
3669
|
process.exit(1);
|
|
3644
3670
|
}
|
|
@@ -4436,8 +4462,8 @@ async function generateInstructionsCommand(options) {
|
|
|
4436
4462
|
process.exit(0);
|
|
4437
4463
|
}
|
|
4438
4464
|
}
|
|
4439
|
-
const
|
|
4440
|
-
|
|
4465
|
+
const spinner9 = p8.spinner();
|
|
4466
|
+
spinner9.start("Generating AI agent instructions from guidelines...");
|
|
4441
4467
|
try {
|
|
4442
4468
|
const result = generateCopilotInstructions(cwd, {
|
|
4443
4469
|
force: true,
|
|
@@ -4445,7 +4471,7 @@ async function generateInstructionsCommand(options) {
|
|
|
4445
4471
|
});
|
|
4446
4472
|
if (result.success) {
|
|
4447
4473
|
const status = result.isNew ? "Generated" : "Regenerated";
|
|
4448
|
-
|
|
4474
|
+
spinner9.stop(
|
|
4449
4475
|
chalk12.green(
|
|
4450
4476
|
`\u2713 ${status} .github/copilot-instructions.md from ${result.guidelinesCount} guidelines`
|
|
4451
4477
|
)
|
|
@@ -4461,12 +4487,12 @@ async function generateInstructionsCommand(options) {
|
|
|
4461
4487
|
)
|
|
4462
4488
|
);
|
|
4463
4489
|
} else {
|
|
4464
|
-
|
|
4490
|
+
spinner9.stop(chalk12.red("\u2717 Failed to generate instructions"));
|
|
4465
4491
|
console.log(chalk12.yellow(`
|
|
4466
4492
|
Reason: ${result.error}`));
|
|
4467
4493
|
}
|
|
4468
4494
|
} catch (error) {
|
|
4469
|
-
|
|
4495
|
+
spinner9.stop(chalk12.red("\u2717 Error generating instructions"));
|
|
4470
4496
|
console.log(
|
|
4471
4497
|
chalk12.yellow(
|
|
4472
4498
|
`
|
|
@@ -4483,9 +4509,149 @@ Reason: ${error instanceof Error ? error.message : String(error)}`
|
|
|
4483
4509
|
console.log(chalk12.dim(" - Preserves custom instructions you add between markers\n"));
|
|
4484
4510
|
}
|
|
4485
4511
|
|
|
4486
|
-
// src/cli/commands/
|
|
4487
|
-
import chalk13 from "chalk";
|
|
4512
|
+
// src/cli/commands/update-templates.ts
|
|
4488
4513
|
import * as p9 from "@clack/prompts";
|
|
4514
|
+
import chalk13 from "chalk";
|
|
4515
|
+
import { existsSync as existsSync8 } from "fs";
|
|
4516
|
+
import { join as join8, dirname as dirname3 } from "path";
|
|
4517
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4518
|
+
var __filename3 = fileURLToPath3(import.meta.url);
|
|
4519
|
+
var __dirname3 = dirname3(__filename3);
|
|
4520
|
+
async function updateTemplatesCommand(options) {
|
|
4521
|
+
const { force = false, skip = false } = options;
|
|
4522
|
+
p9.intro(chalk13.bgBlue(" workflow-agent update-templates "));
|
|
4523
|
+
const cwd = process.cwd();
|
|
4524
|
+
const guidelinesDir = join8(cwd, "guidelines");
|
|
4525
|
+
const templatesDir = findTemplatesDirectory(__dirname3);
|
|
4526
|
+
if (!templatesDir) {
|
|
4527
|
+
p9.cancel("Could not find templates directory");
|
|
4528
|
+
process.exit(1);
|
|
4529
|
+
}
|
|
4530
|
+
const guidelinesExist = existsSync8(guidelinesDir);
|
|
4531
|
+
if (!guidelinesExist) {
|
|
4532
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F No guidelines directory found."));
|
|
4533
|
+
console.log(chalk13.dim("Run 'workflow-agent init' to set up guidelines.\n"));
|
|
4534
|
+
p9.outro(chalk13.yellow("No templates to update"));
|
|
4535
|
+
return;
|
|
4536
|
+
}
|
|
4537
|
+
const mandatoryFiles = getMandatoryTemplateFilenames();
|
|
4538
|
+
const allTemplates = Object.keys(templateMetadata).filter(
|
|
4539
|
+
(f) => f !== "_TEMPLATE_EXAMPLE.md"
|
|
4540
|
+
);
|
|
4541
|
+
console.log(chalk13.cyan("\n\u{1F4CB} Available templates:\n"));
|
|
4542
|
+
console.log(chalk13.bold(" Mandatory templates:"));
|
|
4543
|
+
for (const file of mandatoryFiles) {
|
|
4544
|
+
const meta = templateMetadata[file];
|
|
4545
|
+
console.log(chalk13.dim(` - ${file}`));
|
|
4546
|
+
if (meta?.description) {
|
|
4547
|
+
console.log(chalk13.dim(` ${meta.description}`));
|
|
4548
|
+
}
|
|
4549
|
+
}
|
|
4550
|
+
const optionalFiles = allTemplates.filter(
|
|
4551
|
+
(f) => !mandatoryFiles.includes(f)
|
|
4552
|
+
);
|
|
4553
|
+
if (optionalFiles.length > 0) {
|
|
4554
|
+
console.log(chalk13.bold("\n Optional templates:"));
|
|
4555
|
+
for (const file of optionalFiles) {
|
|
4556
|
+
const meta = templateMetadata[file];
|
|
4557
|
+
console.log(chalk13.dim(` - ${file}`));
|
|
4558
|
+
if (meta?.description) {
|
|
4559
|
+
console.log(chalk13.dim(` ${meta.description}`));
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4563
|
+
console.log("");
|
|
4564
|
+
if (skip) {
|
|
4565
|
+
p9.outro(chalk13.yellow("Skipped template update (--skip flag)"));
|
|
4566
|
+
return;
|
|
4567
|
+
}
|
|
4568
|
+
if (!force) {
|
|
4569
|
+
const shouldContinue = await p9.confirm({
|
|
4570
|
+
message: force ? "Force update all templates? (existing files will be overwritten)" : "Update templates? (existing files will be skipped unless --force is used)",
|
|
4571
|
+
initialValue: true
|
|
4572
|
+
});
|
|
4573
|
+
if (p9.isCancel(shouldContinue) || !shouldContinue) {
|
|
4574
|
+
p9.cancel("Template update cancelled");
|
|
4575
|
+
process.exit(0);
|
|
4576
|
+
}
|
|
4577
|
+
}
|
|
4578
|
+
const spinner9 = p9.spinner();
|
|
4579
|
+
spinner9.start("Updating templates...");
|
|
4580
|
+
let result;
|
|
4581
|
+
try {
|
|
4582
|
+
result = updateTemplates(cwd, templatesDir, {
|
|
4583
|
+
force,
|
|
4584
|
+
silent: true
|
|
4585
|
+
});
|
|
4586
|
+
} catch (error) {
|
|
4587
|
+
spinner9.stop("\u274C Failed to update templates");
|
|
4588
|
+
console.log(
|
|
4589
|
+
chalk13.red(
|
|
4590
|
+
`
|
|
4591
|
+
Error: ${error instanceof Error ? error.message : String(error)}`
|
|
4592
|
+
)
|
|
4593
|
+
);
|
|
4594
|
+
process.exit(1);
|
|
4595
|
+
}
|
|
4596
|
+
const totalChanges = result.installed.length + result.updated.length;
|
|
4597
|
+
if (totalChanges === 0 && result.skipped.length > 0) {
|
|
4598
|
+
spinner9.stop("No changes needed");
|
|
4599
|
+
console.log(
|
|
4600
|
+
chalk13.dim(
|
|
4601
|
+
`
|
|
4602
|
+
${result.skipped.length} files already up to date (use --force to overwrite)`
|
|
4603
|
+
)
|
|
4604
|
+
);
|
|
4605
|
+
} else {
|
|
4606
|
+
spinner9.stop(`\u2713 Template update complete`);
|
|
4607
|
+
if (result.installed.length > 0) {
|
|
4608
|
+
console.log(chalk13.green(`
|
|
4609
|
+
New templates installed:`));
|
|
4610
|
+
for (const file of result.installed) {
|
|
4611
|
+
console.log(chalk13.dim(` + ${file}`));
|
|
4612
|
+
}
|
|
4613
|
+
}
|
|
4614
|
+
if (result.updated.length > 0) {
|
|
4615
|
+
console.log(chalk13.yellow(`
|
|
4616
|
+
Templates updated:`));
|
|
4617
|
+
for (const file of result.updated) {
|
|
4618
|
+
console.log(chalk13.dim(` ~ ${file}`));
|
|
4619
|
+
}
|
|
4620
|
+
}
|
|
4621
|
+
if (result.skipped.length > 0) {
|
|
4622
|
+
console.log(chalk13.dim(`
|
|
4623
|
+
Skipped (already exists):`));
|
|
4624
|
+
for (const file of result.skipped) {
|
|
4625
|
+
console.log(chalk13.dim(` - ${file}`));
|
|
4626
|
+
}
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
if (result.errors.length > 0) {
|
|
4630
|
+
console.log(chalk13.red(`
|
|
4631
|
+
Errors:`));
|
|
4632
|
+
for (const error of result.errors) {
|
|
4633
|
+
console.log(chalk13.red(` ! ${error}`));
|
|
4634
|
+
}
|
|
4635
|
+
}
|
|
4636
|
+
if (totalChanges > 0) {
|
|
4637
|
+
console.log("");
|
|
4638
|
+
const instructionsResult = generateCopilotInstructions(cwd, {
|
|
4639
|
+
silent: true
|
|
4640
|
+
});
|
|
4641
|
+
if (instructionsResult.success) {
|
|
4642
|
+
console.log(
|
|
4643
|
+
chalk13.green(
|
|
4644
|
+
`\u2713 Regenerated .github/copilot-instructions.md from ${instructionsResult.guidelinesCount} guidelines`
|
|
4645
|
+
)
|
|
4646
|
+
);
|
|
4647
|
+
}
|
|
4648
|
+
}
|
|
4649
|
+
p9.outro(chalk13.green("Done!"));
|
|
4650
|
+
}
|
|
4651
|
+
|
|
4652
|
+
// src/cli/commands/learn.ts
|
|
4653
|
+
import chalk14 from "chalk";
|
|
4654
|
+
import * as p10 from "@clack/prompts";
|
|
4489
4655
|
import {
|
|
4490
4656
|
PatternStore as PatternStore2,
|
|
4491
4657
|
ContributorManager as ContributorManager2,
|
|
@@ -4508,10 +4674,10 @@ function formatTags(tags) {
|
|
|
4508
4674
|
async function learnRecordCommand(options) {
|
|
4509
4675
|
const cwd = getWorkspacePath();
|
|
4510
4676
|
const store = new PatternStore2(cwd);
|
|
4511
|
-
console.log(
|
|
4677
|
+
console.log(chalk14.cyan("\n\u{1F4DA} Record a Learning Pattern\n"));
|
|
4512
4678
|
let patternType = options.type;
|
|
4513
4679
|
if (!patternType) {
|
|
4514
|
-
const typeChoice = await
|
|
4680
|
+
const typeChoice = await p10.select({
|
|
4515
4681
|
message: "What type of pattern are you recording?",
|
|
4516
4682
|
options: [
|
|
4517
4683
|
{
|
|
@@ -4524,15 +4690,15 @@ async function learnRecordCommand(options) {
|
|
|
4524
4690
|
}
|
|
4525
4691
|
]
|
|
4526
4692
|
});
|
|
4527
|
-
if (
|
|
4528
|
-
|
|
4693
|
+
if (p10.isCancel(typeChoice)) {
|
|
4694
|
+
p10.cancel("Recording cancelled");
|
|
4529
4695
|
process.exit(0);
|
|
4530
4696
|
}
|
|
4531
4697
|
patternType = typeChoice;
|
|
4532
4698
|
}
|
|
4533
4699
|
let name = options.name;
|
|
4534
4700
|
if (!name) {
|
|
4535
|
-
const nameInput = await
|
|
4701
|
+
const nameInput = await p10.text({
|
|
4536
4702
|
message: "Pattern name:",
|
|
4537
4703
|
placeholder: "e.g., Next.js App Router Migration",
|
|
4538
4704
|
validate: (value) => {
|
|
@@ -4542,15 +4708,15 @@ async function learnRecordCommand(options) {
|
|
|
4542
4708
|
return void 0;
|
|
4543
4709
|
}
|
|
4544
4710
|
});
|
|
4545
|
-
if (
|
|
4546
|
-
|
|
4711
|
+
if (p10.isCancel(nameInput)) {
|
|
4712
|
+
p10.cancel("Recording cancelled");
|
|
4547
4713
|
process.exit(0);
|
|
4548
4714
|
}
|
|
4549
4715
|
name = nameInput;
|
|
4550
4716
|
}
|
|
4551
4717
|
let description = options.description;
|
|
4552
4718
|
if (!description) {
|
|
4553
|
-
const descInput = await
|
|
4719
|
+
const descInput = await p10.text({
|
|
4554
4720
|
message: "Description:",
|
|
4555
4721
|
placeholder: "What does this pattern solve?",
|
|
4556
4722
|
validate: (value) => {
|
|
@@ -4561,40 +4727,40 @@ async function learnRecordCommand(options) {
|
|
|
4561
4727
|
return void 0;
|
|
4562
4728
|
}
|
|
4563
4729
|
});
|
|
4564
|
-
if (
|
|
4565
|
-
|
|
4730
|
+
if (p10.isCancel(descInput)) {
|
|
4731
|
+
p10.cancel("Recording cancelled");
|
|
4566
4732
|
process.exit(0);
|
|
4567
4733
|
}
|
|
4568
4734
|
description = descInput;
|
|
4569
4735
|
}
|
|
4570
4736
|
let framework = options.framework;
|
|
4571
4737
|
if (!framework) {
|
|
4572
|
-
const fwInput = await
|
|
4738
|
+
const fwInput = await p10.text({
|
|
4573
4739
|
message: "Framework:",
|
|
4574
4740
|
placeholder: "e.g., next, react, vue, express"
|
|
4575
4741
|
});
|
|
4576
|
-
if (
|
|
4577
|
-
|
|
4742
|
+
if (p10.isCancel(fwInput)) {
|
|
4743
|
+
p10.cancel("Recording cancelled");
|
|
4578
4744
|
process.exit(0);
|
|
4579
4745
|
}
|
|
4580
4746
|
framework = fwInput;
|
|
4581
4747
|
}
|
|
4582
4748
|
let version = options.version;
|
|
4583
4749
|
if (!version) {
|
|
4584
|
-
const versionInput = await
|
|
4750
|
+
const versionInput = await p10.text({
|
|
4585
4751
|
message: "Framework version (semver range):",
|
|
4586
4752
|
placeholder: "e.g., >=14.0.0, ^18.0.0",
|
|
4587
4753
|
initialValue: ">=1.0.0"
|
|
4588
4754
|
});
|
|
4589
|
-
if (
|
|
4590
|
-
|
|
4755
|
+
if (p10.isCancel(versionInput)) {
|
|
4756
|
+
p10.cancel("Recording cancelled");
|
|
4591
4757
|
process.exit(0);
|
|
4592
4758
|
}
|
|
4593
4759
|
version = versionInput;
|
|
4594
4760
|
}
|
|
4595
4761
|
let category = options.category;
|
|
4596
4762
|
if (patternType === "fix" && !category) {
|
|
4597
|
-
const catChoice = await
|
|
4763
|
+
const catChoice = await p10.select({
|
|
4598
4764
|
message: "Category:",
|
|
4599
4765
|
options: [
|
|
4600
4766
|
{ value: "migration", label: "\u{1F504} Migration" },
|
|
@@ -4609,8 +4775,8 @@ async function learnRecordCommand(options) {
|
|
|
4609
4775
|
{ value: "other", label: "\u{1F4E6} Other" }
|
|
4610
4776
|
]
|
|
4611
4777
|
});
|
|
4612
|
-
if (
|
|
4613
|
-
|
|
4778
|
+
if (p10.isCancel(catChoice)) {
|
|
4779
|
+
p10.cancel("Recording cancelled");
|
|
4614
4780
|
process.exit(0);
|
|
4615
4781
|
}
|
|
4616
4782
|
category = catChoice;
|
|
@@ -4673,14 +4839,14 @@ async function learnRecordCommand(options) {
|
|
|
4673
4839
|
};
|
|
4674
4840
|
const result = await store.saveFixPattern(fixPattern);
|
|
4675
4841
|
if (result.success) {
|
|
4676
|
-
console.log(
|
|
4677
|
-
console.log(
|
|
4678
|
-
console.log(
|
|
4679
|
-
console.log(
|
|
4680
|
-
console.log(
|
|
4842
|
+
console.log(chalk14.green("\n\u2705 Fix pattern recorded successfully!\n"));
|
|
4843
|
+
console.log(chalk14.dim(` ID: ${fixPattern.id}`));
|
|
4844
|
+
console.log(chalk14.dim(` Name: ${name}`));
|
|
4845
|
+
console.log(chalk14.dim(` Category: ${category}`));
|
|
4846
|
+
console.log(chalk14.dim(` Framework: ${framework} ${version}`));
|
|
4681
4847
|
} else {
|
|
4682
|
-
console.log(
|
|
4683
|
-
console.log(
|
|
4848
|
+
console.log(chalk14.red("\n\u274C Failed to record pattern"));
|
|
4849
|
+
console.log(chalk14.dim(` Error: ${result.error}`));
|
|
4684
4850
|
process.exit(1);
|
|
4685
4851
|
}
|
|
4686
4852
|
} else {
|
|
@@ -4727,13 +4893,13 @@ async function learnRecordCommand(options) {
|
|
|
4727
4893
|
};
|
|
4728
4894
|
const result = await store.saveBlueprint(blueprint);
|
|
4729
4895
|
if (result.success) {
|
|
4730
|
-
console.log(
|
|
4731
|
-
console.log(
|
|
4732
|
-
console.log(
|
|
4733
|
-
console.log(
|
|
4896
|
+
console.log(chalk14.green("\n\u2705 Blueprint recorded successfully!\n"));
|
|
4897
|
+
console.log(chalk14.dim(` ID: ${blueprint.id}`));
|
|
4898
|
+
console.log(chalk14.dim(` Name: ${name}`));
|
|
4899
|
+
console.log(chalk14.dim(` Framework: ${framework} ${version}`));
|
|
4734
4900
|
} else {
|
|
4735
|
-
console.log(
|
|
4736
|
-
console.log(
|
|
4901
|
+
console.log(chalk14.red("\n\u274C Failed to record blueprint"));
|
|
4902
|
+
console.log(chalk14.dim(` Error: ${result.error}`));
|
|
4737
4903
|
process.exit(1);
|
|
4738
4904
|
}
|
|
4739
4905
|
}
|
|
@@ -4743,7 +4909,7 @@ async function learnListCommand(options) {
|
|
|
4743
4909
|
const store = new PatternStore2(cwd);
|
|
4744
4910
|
const patternType = options.type ?? "all";
|
|
4745
4911
|
const showDeprecated = options.deprecated ?? false;
|
|
4746
|
-
console.log(
|
|
4912
|
+
console.log(chalk14.cyan("\n\u{1F4DA} Recorded Learning Patterns\n"));
|
|
4747
4913
|
if (patternType === "all" || patternType === "fix") {
|
|
4748
4914
|
const fixResult = await store.listFixPatterns({
|
|
4749
4915
|
tags: options.tag ? [{ category: "framework", name: options.tag }] : void 0,
|
|
@@ -4751,29 +4917,29 @@ async function learnListCommand(options) {
|
|
|
4751
4917
|
includeDeprecated: showDeprecated
|
|
4752
4918
|
});
|
|
4753
4919
|
if (fixResult.success && fixResult.data && fixResult.data.length > 0) {
|
|
4754
|
-
console.log(
|
|
4920
|
+
console.log(chalk14.bold.yellow("\u{1F527} Fix Patterns:\n"));
|
|
4755
4921
|
for (const pattern of fixResult.data) {
|
|
4756
4922
|
const isDeprecated = pattern.deprecatedAt !== void 0;
|
|
4757
4923
|
const statusIcon = isDeprecated ? "\u26A0\uFE0F" : "\u2713";
|
|
4758
|
-
const nameColor = isDeprecated ?
|
|
4924
|
+
const nameColor = isDeprecated ? chalk14.dim : chalk14.white;
|
|
4759
4925
|
console.log(` ${statusIcon} ${nameColor(pattern.name)}`);
|
|
4760
|
-
console.log(
|
|
4761
|
-
console.log(
|
|
4926
|
+
console.log(chalk14.dim(` ID: ${pattern.id}`));
|
|
4927
|
+
console.log(chalk14.dim(` Category: ${pattern.category}`));
|
|
4762
4928
|
console.log(
|
|
4763
|
-
|
|
4929
|
+
chalk14.dim(` Created: ${formatDate(pattern.createdAt)}`)
|
|
4764
4930
|
);
|
|
4765
4931
|
console.log(
|
|
4766
|
-
|
|
4932
|
+
chalk14.dim(
|
|
4767
4933
|
` Success Rate: ${(pattern.metrics.successRate * 100).toFixed(0)}% (${pattern.metrics.successes}/${pattern.metrics.applications})`
|
|
4768
4934
|
)
|
|
4769
4935
|
);
|
|
4770
4936
|
if (pattern.tags.length > 0) {
|
|
4771
|
-
console.log(
|
|
4937
|
+
console.log(chalk14.dim(` Tags: ${formatTags(pattern.tags)}`));
|
|
4772
4938
|
}
|
|
4773
4939
|
console.log("");
|
|
4774
4940
|
}
|
|
4775
4941
|
} else if (patternType === "fix") {
|
|
4776
|
-
console.log(
|
|
4942
|
+
console.log(chalk14.dim(" No fix patterns found.\n"));
|
|
4777
4943
|
}
|
|
4778
4944
|
}
|
|
4779
4945
|
if (patternType === "all" || patternType === "blueprint") {
|
|
@@ -4783,46 +4949,46 @@ async function learnListCommand(options) {
|
|
|
4783
4949
|
includeDeprecated: showDeprecated
|
|
4784
4950
|
});
|
|
4785
4951
|
if (bpResult.success && bpResult.data && bpResult.data.length > 0) {
|
|
4786
|
-
console.log(
|
|
4952
|
+
console.log(chalk14.bold.blue("\u{1F4D0} Blueprints:\n"));
|
|
4787
4953
|
for (const blueprint of bpResult.data) {
|
|
4788
4954
|
const isDeprecated = blueprint.deprecatedAt !== void 0;
|
|
4789
4955
|
const statusIcon = isDeprecated ? "\u26A0\uFE0F" : "\u2713";
|
|
4790
|
-
const nameColor = isDeprecated ?
|
|
4956
|
+
const nameColor = isDeprecated ? chalk14.dim : chalk14.white;
|
|
4791
4957
|
console.log(` ${statusIcon} ${nameColor(blueprint.name)}`);
|
|
4792
|
-
console.log(
|
|
4793
|
-
console.log(
|
|
4958
|
+
console.log(chalk14.dim(` ID: ${blueprint.id}`));
|
|
4959
|
+
console.log(chalk14.dim(` Language: ${blueprint.stack.language}`));
|
|
4794
4960
|
console.log(
|
|
4795
|
-
|
|
4961
|
+
chalk14.dim(` Created: ${formatDate(blueprint.createdAt)}`)
|
|
4796
4962
|
);
|
|
4797
4963
|
console.log(
|
|
4798
|
-
|
|
4964
|
+
chalk14.dim(
|
|
4799
4965
|
` Success Rate: ${(blueprint.metrics.successRate * 100).toFixed(0)}% (${blueprint.metrics.successes}/${blueprint.metrics.applications})`
|
|
4800
4966
|
)
|
|
4801
4967
|
);
|
|
4802
4968
|
if (blueprint.tags.length > 0) {
|
|
4803
|
-
console.log(
|
|
4969
|
+
console.log(chalk14.dim(` Tags: ${formatTags(blueprint.tags)}`));
|
|
4804
4970
|
}
|
|
4805
4971
|
console.log("");
|
|
4806
4972
|
}
|
|
4807
4973
|
} else if (patternType === "blueprint") {
|
|
4808
|
-
console.log(
|
|
4974
|
+
console.log(chalk14.dim(" No blueprints found.\n"));
|
|
4809
4975
|
}
|
|
4810
4976
|
}
|
|
4811
4977
|
const stats = await store.getStats();
|
|
4812
4978
|
const totalPatterns = stats.totalFixes + stats.totalBlueprints;
|
|
4813
4979
|
const totalDeprecated = stats.deprecatedFixes + stats.deprecatedBlueprints;
|
|
4814
|
-
console.log(
|
|
4815
|
-
console.log(
|
|
4816
|
-
console.log(
|
|
4817
|
-
console.log(
|
|
4818
|
-
console.log(
|
|
4980
|
+
console.log(chalk14.dim("\u2501".repeat(40)));
|
|
4981
|
+
console.log(chalk14.dim(`Total: ${totalPatterns} patterns`));
|
|
4982
|
+
console.log(chalk14.dim(` Fix Patterns: ${stats.totalFixes}`));
|
|
4983
|
+
console.log(chalk14.dim(` Blueprints: ${stats.totalBlueprints}`));
|
|
4984
|
+
console.log(chalk14.dim(` Deprecated: ${totalDeprecated}`));
|
|
4819
4985
|
console.log("");
|
|
4820
4986
|
}
|
|
4821
4987
|
async function learnApplyCommand(patternId, options) {
|
|
4822
4988
|
const cwd = getWorkspacePath();
|
|
4823
4989
|
const store = new PatternStore2(cwd);
|
|
4824
4990
|
const telemetry = new TelemetryCollector2(cwd);
|
|
4825
|
-
console.log(
|
|
4991
|
+
console.log(chalk14.cyan("\n\u{1F527} Apply Learning Pattern\n"));
|
|
4826
4992
|
let pattern = await store.getFixPattern(patternId);
|
|
4827
4993
|
let patternType = "fix";
|
|
4828
4994
|
if (!pattern.success || !pattern.data) {
|
|
@@ -4831,21 +4997,21 @@ async function learnApplyCommand(patternId, options) {
|
|
|
4831
4997
|
pattern = bpResult;
|
|
4832
4998
|
patternType = "blueprint";
|
|
4833
4999
|
} else {
|
|
4834
|
-
console.log(
|
|
5000
|
+
console.log(chalk14.red(`
|
|
4835
5001
|
\u274C Pattern not found: ${patternId}`));
|
|
4836
5002
|
console.log(
|
|
4837
|
-
|
|
5003
|
+
chalk14.dim(" Use 'workflow learn:list' to see available patterns")
|
|
4838
5004
|
);
|
|
4839
5005
|
process.exit(1);
|
|
4840
5006
|
}
|
|
4841
5007
|
}
|
|
4842
5008
|
const patternData = pattern.data;
|
|
4843
|
-
console.log(
|
|
4844
|
-
console.log(
|
|
4845
|
-
console.log(
|
|
5009
|
+
console.log(chalk14.white(` Pattern: ${patternData.name}`));
|
|
5010
|
+
console.log(chalk14.dim(` Type: ${patternType}`));
|
|
5011
|
+
console.log(chalk14.dim(` Description: ${patternData.description}`));
|
|
4846
5012
|
if (options.dryRun) {
|
|
4847
5013
|
console.log(
|
|
4848
|
-
|
|
5014
|
+
chalk14.yellow("\n\u{1F4CB} DRY-RUN MODE: No changes will be applied\n")
|
|
4849
5015
|
);
|
|
4850
5016
|
}
|
|
4851
5017
|
const framework = options.framework ?? patternData.compatibility.frameworks[0]?.name ?? "unknown";
|
|
@@ -4853,44 +5019,44 @@ async function learnApplyCommand(patternId, options) {
|
|
|
4853
5019
|
await telemetry.recordApplication(patternId, patternType, framework, version);
|
|
4854
5020
|
if (patternType === "fix") {
|
|
4855
5021
|
const fixPattern = patternData;
|
|
4856
|
-
console.log(
|
|
5022
|
+
console.log(chalk14.cyan("\n\u{1F4CB} Solution Steps:\n"));
|
|
4857
5023
|
if (fixPattern.solution.steps) {
|
|
4858
5024
|
for (let i = 0; i < fixPattern.solution.steps.length; i++) {
|
|
4859
5025
|
const step = fixPattern.solution.steps[i];
|
|
4860
5026
|
console.log(
|
|
4861
|
-
|
|
5027
|
+
chalk14.white(` ${i + 1}. [${step.action}] ${step.description}`)
|
|
4862
5028
|
);
|
|
4863
5029
|
if (step.file) {
|
|
4864
|
-
console.log(
|
|
5030
|
+
console.log(chalk14.dim(` File: ${step.file}`));
|
|
4865
5031
|
}
|
|
4866
5032
|
}
|
|
4867
5033
|
}
|
|
4868
5034
|
} else {
|
|
4869
5035
|
const blueprint = patternData;
|
|
4870
|
-
console.log(
|
|
5036
|
+
console.log(chalk14.cyan("\n\u{1F4CB} Setup Steps:\n"));
|
|
4871
5037
|
if (blueprint.setup.steps) {
|
|
4872
5038
|
for (let i = 0; i < blueprint.setup.steps.length; i++) {
|
|
4873
5039
|
const step = blueprint.setup.steps[i];
|
|
4874
|
-
console.log(
|
|
5040
|
+
console.log(chalk14.white(` ${i + 1}. ${step.description}`));
|
|
4875
5041
|
if (step.command) {
|
|
4876
|
-
console.log(
|
|
5042
|
+
console.log(chalk14.dim(` Command: ${step.command}`));
|
|
4877
5043
|
}
|
|
4878
5044
|
}
|
|
4879
5045
|
}
|
|
4880
5046
|
}
|
|
4881
5047
|
if (!options.dryRun) {
|
|
4882
|
-
const confirmed = await
|
|
5048
|
+
const confirmed = await p10.confirm({
|
|
4883
5049
|
message: "Mark this pattern as successfully applied?",
|
|
4884
5050
|
initialValue: true
|
|
4885
5051
|
});
|
|
4886
|
-
if (
|
|
4887
|
-
|
|
5052
|
+
if (p10.isCancel(confirmed)) {
|
|
5053
|
+
p10.cancel("Application cancelled");
|
|
4888
5054
|
process.exit(0);
|
|
4889
5055
|
}
|
|
4890
5056
|
if (confirmed) {
|
|
4891
5057
|
await store.updatePatternMetrics(patternId, patternType, true);
|
|
4892
5058
|
await telemetry.recordSuccess(patternId, patternType, framework, version);
|
|
4893
|
-
console.log(
|
|
5059
|
+
console.log(chalk14.green("\n\u2705 Pattern marked as successfully applied!"));
|
|
4894
5060
|
} else {
|
|
4895
5061
|
await store.updatePatternMetrics(patternId, patternType, false);
|
|
4896
5062
|
await telemetry.recordFailure(
|
|
@@ -4901,7 +5067,7 @@ async function learnApplyCommand(patternId, options) {
|
|
|
4901
5067
|
"unknown"
|
|
4902
5068
|
);
|
|
4903
5069
|
console.log(
|
|
4904
|
-
|
|
5070
|
+
chalk14.yellow("\n\u26A0\uFE0F Pattern application marked as unsuccessful.")
|
|
4905
5071
|
);
|
|
4906
5072
|
}
|
|
4907
5073
|
}
|
|
@@ -4909,32 +5075,32 @@ async function learnApplyCommand(patternId, options) {
|
|
|
4909
5075
|
async function learnSyncCommand(options) {
|
|
4910
5076
|
const cwd = getWorkspacePath();
|
|
4911
5077
|
const contributorManager = new ContributorManager2(cwd);
|
|
4912
|
-
console.log(
|
|
5078
|
+
console.log(chalk14.cyan("\n\u{1F504} Sync Learning Patterns\n"));
|
|
4913
5079
|
const config = await contributorManager.getConfig();
|
|
4914
5080
|
if (!config.success || !config.data?.syncOptIn) {
|
|
4915
|
-
console.log(
|
|
4916
|
-
console.log(
|
|
4917
|
-
console.log(
|
|
5081
|
+
console.log(chalk14.yellow("\u26A0\uFE0F Sync is not enabled.\n"));
|
|
5082
|
+
console.log(chalk14.dim(" To enable sync, run:"));
|
|
5083
|
+
console.log(chalk14.dim(" workflow learn:config --enable-sync\n"));
|
|
4918
5084
|
console.log(
|
|
4919
|
-
|
|
5085
|
+
chalk14.dim(
|
|
4920
5086
|
" This allows you to share anonymized patterns with the community."
|
|
4921
5087
|
)
|
|
4922
5088
|
);
|
|
4923
5089
|
process.exit(0);
|
|
4924
5090
|
}
|
|
4925
5091
|
if (options.dryRun) {
|
|
4926
|
-
console.log(
|
|
5092
|
+
console.log(chalk14.yellow("\u{1F4CB} DRY-RUN MODE: No changes will be synced\n"));
|
|
4927
5093
|
}
|
|
4928
5094
|
const store = new PatternStore2(cwd);
|
|
4929
5095
|
const anonymizer = new PatternAnonymizer();
|
|
4930
5096
|
const { fixes, blueprints } = await store.getPatternsForSync();
|
|
4931
5097
|
console.log(
|
|
4932
|
-
|
|
5098
|
+
chalk14.dim(
|
|
4933
5099
|
` Patterns ready to sync: ${fixes.length} fixes, ${blueprints.length} blueprints`
|
|
4934
5100
|
)
|
|
4935
5101
|
);
|
|
4936
5102
|
if (options.push) {
|
|
4937
|
-
console.log(
|
|
5103
|
+
console.log(chalk14.cyan("\n\u{1F4E4} Pushing patterns...\n"));
|
|
4938
5104
|
let anonymizedFixes = 0;
|
|
4939
5105
|
let anonymizedBlueprints = 0;
|
|
4940
5106
|
for (const fix of fixes) {
|
|
@@ -4942,7 +5108,7 @@ async function learnSyncCommand(options) {
|
|
|
4942
5108
|
if (result.success) {
|
|
4943
5109
|
anonymizedFixes++;
|
|
4944
5110
|
if (!options.dryRun) {
|
|
4945
|
-
console.log(
|
|
5111
|
+
console.log(chalk14.dim(` \u2713 Anonymized: ${fix.name}`));
|
|
4946
5112
|
}
|
|
4947
5113
|
}
|
|
4948
5114
|
}
|
|
@@ -4951,117 +5117,117 @@ async function learnSyncCommand(options) {
|
|
|
4951
5117
|
if (result.success) {
|
|
4952
5118
|
anonymizedBlueprints++;
|
|
4953
5119
|
if (!options.dryRun) {
|
|
4954
|
-
console.log(
|
|
5120
|
+
console.log(chalk14.dim(` \u2713 Anonymized: ${bp.name}`));
|
|
4955
5121
|
}
|
|
4956
5122
|
}
|
|
4957
5123
|
}
|
|
4958
5124
|
console.log(
|
|
4959
|
-
|
|
5125
|
+
chalk14.green(
|
|
4960
5126
|
`
|
|
4961
5127
|
\u2705 Ready to push ${anonymizedFixes} fixes and ${anonymizedBlueprints} blueprints`
|
|
4962
5128
|
)
|
|
4963
5129
|
);
|
|
4964
|
-
console.log(
|
|
5130
|
+
console.log(chalk14.dim(" (Registry push not yet implemented)"));
|
|
4965
5131
|
}
|
|
4966
5132
|
if (options.pull) {
|
|
4967
|
-
console.log(
|
|
4968
|
-
console.log(
|
|
5133
|
+
console.log(chalk14.cyan("\n\u{1F4E5} Pulling patterns from registry...\n"));
|
|
5134
|
+
console.log(chalk14.dim(" (Registry pull not yet implemented)"));
|
|
4969
5135
|
}
|
|
4970
5136
|
if (!options.push && !options.pull) {
|
|
4971
5137
|
console.log(
|
|
4972
|
-
|
|
5138
|
+
chalk14.dim(" Specify --push to upload or --pull to download patterns.\n")
|
|
4973
5139
|
);
|
|
4974
5140
|
}
|
|
4975
5141
|
}
|
|
4976
5142
|
async function learnConfigCommand(options) {
|
|
4977
5143
|
const cwd = getWorkspacePath();
|
|
4978
5144
|
const contributorManager = new ContributorManager2(cwd);
|
|
4979
|
-
console.log(
|
|
5145
|
+
console.log(chalk14.cyan("\n\u2699\uFE0F Learning Configuration\n"));
|
|
4980
5146
|
if (options.enableSync) {
|
|
4981
5147
|
const result = await contributorManager.enableSync();
|
|
4982
5148
|
if (result.success) {
|
|
4983
|
-
console.log(
|
|
5149
|
+
console.log(chalk14.green("\u2705 Sync enabled"));
|
|
4984
5150
|
console.log(
|
|
4985
|
-
|
|
5151
|
+
chalk14.dim(" Your patterns will be anonymized before sharing.")
|
|
4986
5152
|
);
|
|
4987
5153
|
} else {
|
|
4988
|
-
console.log(
|
|
5154
|
+
console.log(chalk14.red(`\u274C Failed: ${result.error}`));
|
|
4989
5155
|
}
|
|
4990
5156
|
return;
|
|
4991
5157
|
}
|
|
4992
5158
|
if (options.disableSync) {
|
|
4993
5159
|
const result = await contributorManager.disableSync();
|
|
4994
5160
|
if (result.success) {
|
|
4995
|
-
console.log(
|
|
5161
|
+
console.log(chalk14.green("\u2705 Sync disabled"));
|
|
4996
5162
|
} else {
|
|
4997
|
-
console.log(
|
|
5163
|
+
console.log(chalk14.red(`\u274C Failed: ${result.error}`));
|
|
4998
5164
|
}
|
|
4999
5165
|
return;
|
|
5000
5166
|
}
|
|
5001
5167
|
if (options.enableTelemetry) {
|
|
5002
5168
|
const result = await contributorManager.enableTelemetry();
|
|
5003
5169
|
if (result.success) {
|
|
5004
|
-
console.log(
|
|
5170
|
+
console.log(chalk14.green("\u2705 Telemetry enabled"));
|
|
5005
5171
|
console.log(
|
|
5006
|
-
|
|
5172
|
+
chalk14.dim(
|
|
5007
5173
|
" Anonymous usage data helps improve pattern recommendations."
|
|
5008
5174
|
)
|
|
5009
5175
|
);
|
|
5010
5176
|
} else {
|
|
5011
|
-
console.log(
|
|
5177
|
+
console.log(chalk14.red(`\u274C Failed: ${result.error}`));
|
|
5012
5178
|
}
|
|
5013
5179
|
return;
|
|
5014
5180
|
}
|
|
5015
5181
|
if (options.disableTelemetry) {
|
|
5016
5182
|
const result = await contributorManager.disableTelemetry();
|
|
5017
5183
|
if (result.success) {
|
|
5018
|
-
console.log(
|
|
5184
|
+
console.log(chalk14.green("\u2705 Telemetry disabled"));
|
|
5019
5185
|
} else {
|
|
5020
|
-
console.log(
|
|
5186
|
+
console.log(chalk14.red(`\u274C Failed: ${result.error}`));
|
|
5021
5187
|
}
|
|
5022
5188
|
return;
|
|
5023
5189
|
}
|
|
5024
5190
|
if (options.resetId) {
|
|
5025
|
-
const confirmed = await
|
|
5191
|
+
const confirmed = await p10.confirm({
|
|
5026
5192
|
message: "Are you sure you want to reset your contributor ID? This cannot be undone.",
|
|
5027
5193
|
initialValue: false
|
|
5028
5194
|
});
|
|
5029
|
-
if (
|
|
5030
|
-
|
|
5195
|
+
if (p10.isCancel(confirmed) || !confirmed) {
|
|
5196
|
+
p10.cancel("Reset cancelled");
|
|
5031
5197
|
return;
|
|
5032
5198
|
}
|
|
5033
5199
|
const result = await contributorManager.resetId();
|
|
5034
5200
|
if (result.success) {
|
|
5035
|
-
console.log(
|
|
5036
|
-
console.log(
|
|
5201
|
+
console.log(chalk14.green("\u2705 Contributor ID reset"));
|
|
5202
|
+
console.log(chalk14.dim(` New ID: ${result.data?.id}`));
|
|
5037
5203
|
} else {
|
|
5038
|
-
console.log(
|
|
5204
|
+
console.log(chalk14.red(`\u274C Failed: ${result.error}`));
|
|
5039
5205
|
}
|
|
5040
5206
|
return;
|
|
5041
5207
|
}
|
|
5042
5208
|
const config = await contributorManager.getConfig();
|
|
5043
5209
|
if (config.success && config.data) {
|
|
5044
|
-
console.log(
|
|
5045
|
-
console.log(
|
|
5046
|
-
console.log(
|
|
5210
|
+
console.log(chalk14.white(" Current Settings:\n"));
|
|
5211
|
+
console.log(chalk14.dim(` Contributor ID: ${config.data.id}`));
|
|
5212
|
+
console.log(chalk14.dim(` Created: ${formatDate(config.data.createdAt)}`));
|
|
5047
5213
|
console.log(
|
|
5048
|
-
|
|
5214
|
+
chalk14.dim(` Sync Enabled: ${config.data.syncOptIn ? "Yes" : "No"}`)
|
|
5049
5215
|
);
|
|
5050
5216
|
console.log(
|
|
5051
|
-
|
|
5217
|
+
chalk14.dim(
|
|
5052
5218
|
` Telemetry Enabled: ${config.data.telemetryEnabled ? "Yes" : "No"}`
|
|
5053
5219
|
)
|
|
5054
5220
|
);
|
|
5055
5221
|
if (config.data.syncEnabledAt) {
|
|
5056
5222
|
console.log(
|
|
5057
|
-
|
|
5223
|
+
chalk14.dim(
|
|
5058
5224
|
` Sync Enabled At: ${formatDate(config.data.syncEnabledAt)}`
|
|
5059
5225
|
)
|
|
5060
5226
|
);
|
|
5061
5227
|
}
|
|
5062
5228
|
} else {
|
|
5063
5229
|
console.log(
|
|
5064
|
-
|
|
5230
|
+
chalk14.dim(
|
|
5065
5231
|
" No configuration found. Settings will be created on first use.\n"
|
|
5066
5232
|
)
|
|
5067
5233
|
);
|
|
@@ -5070,7 +5236,7 @@ async function learnConfigCommand(options) {
|
|
|
5070
5236
|
async function learnDeprecateCommand(patternId, reason) {
|
|
5071
5237
|
const cwd = getWorkspacePath();
|
|
5072
5238
|
const store = new PatternStore2(cwd);
|
|
5073
|
-
console.log(
|
|
5239
|
+
console.log(chalk14.cyan("\n\u26A0\uFE0F Deprecate Pattern\n"));
|
|
5074
5240
|
let patternType = "fix";
|
|
5075
5241
|
let pattern = await store.getFixPattern(patternId);
|
|
5076
5242
|
if (!pattern.success || !pattern.data) {
|
|
@@ -5079,26 +5245,26 @@ async function learnDeprecateCommand(patternId, reason) {
|
|
|
5079
5245
|
pattern = bpResult;
|
|
5080
5246
|
patternType = "blueprint";
|
|
5081
5247
|
} else {
|
|
5082
|
-
console.log(
|
|
5248
|
+
console.log(chalk14.red(`
|
|
5083
5249
|
\u274C Pattern not found: ${patternId}`));
|
|
5084
5250
|
process.exit(1);
|
|
5085
5251
|
}
|
|
5086
5252
|
}
|
|
5087
|
-
console.log(
|
|
5088
|
-
console.log(
|
|
5089
|
-
const confirmed = await
|
|
5253
|
+
console.log(chalk14.white(` Pattern: ${pattern.data.name}`));
|
|
5254
|
+
console.log(chalk14.dim(` Reason: ${reason}`));
|
|
5255
|
+
const confirmed = await p10.confirm({
|
|
5090
5256
|
message: "Are you sure you want to deprecate this pattern?",
|
|
5091
5257
|
initialValue: false
|
|
5092
5258
|
});
|
|
5093
|
-
if (
|
|
5094
|
-
|
|
5259
|
+
if (p10.isCancel(confirmed) || !confirmed) {
|
|
5260
|
+
p10.cancel("Deprecation cancelled");
|
|
5095
5261
|
return;
|
|
5096
5262
|
}
|
|
5097
5263
|
const result = await store.deprecatePattern(patternId, patternType, reason);
|
|
5098
5264
|
if (result.success) {
|
|
5099
|
-
console.log(
|
|
5265
|
+
console.log(chalk14.green("\n\u2705 Pattern deprecated successfully"));
|
|
5100
5266
|
} else {
|
|
5101
|
-
console.log(
|
|
5267
|
+
console.log(chalk14.red(`
|
|
5102
5268
|
\u274C Failed: ${result.error}`));
|
|
5103
5269
|
process.exit(1);
|
|
5104
5270
|
}
|
|
@@ -5107,32 +5273,32 @@ async function learnStatsCommand() {
|
|
|
5107
5273
|
const cwd = getWorkspacePath();
|
|
5108
5274
|
const store = new PatternStore2(cwd);
|
|
5109
5275
|
const telemetry = new TelemetryCollector2(cwd);
|
|
5110
|
-
console.log(
|
|
5276
|
+
console.log(chalk14.cyan("\n\u{1F4CA} Learning Statistics\n"));
|
|
5111
5277
|
const storeStats = await store.getStats();
|
|
5112
5278
|
const totalPatterns = storeStats.totalFixes + storeStats.totalBlueprints;
|
|
5113
5279
|
const totalDeprecated = storeStats.deprecatedFixes + storeStats.deprecatedBlueprints;
|
|
5114
|
-
console.log(
|
|
5115
|
-
console.log(
|
|
5116
|
-
console.log(
|
|
5117
|
-
console.log(
|
|
5118
|
-
console.log(
|
|
5280
|
+
console.log(chalk14.bold.white(" Patterns:\n"));
|
|
5281
|
+
console.log(chalk14.dim(` Total: ${totalPatterns}`));
|
|
5282
|
+
console.log(chalk14.dim(` Fix Patterns: ${storeStats.totalFixes}`));
|
|
5283
|
+
console.log(chalk14.dim(` Blueprints: ${storeStats.totalBlueprints}`));
|
|
5284
|
+
console.log(chalk14.dim(` Deprecated: ${totalDeprecated}`));
|
|
5119
5285
|
const telemetryStats = await telemetry.getStats();
|
|
5120
|
-
console.log(
|
|
5121
|
-
console.log(
|
|
5286
|
+
console.log(chalk14.bold.white("\n Telemetry:\n"));
|
|
5287
|
+
console.log(chalk14.dim(` Pending Events: ${telemetryStats.pendingEvents}`));
|
|
5122
5288
|
console.log(
|
|
5123
|
-
|
|
5289
|
+
chalk14.dim(` Total Events Sent: ${telemetryStats.totalEventsSent}`)
|
|
5124
5290
|
);
|
|
5125
5291
|
if (telemetryStats.lastFlushAt) {
|
|
5126
5292
|
console.log(
|
|
5127
|
-
|
|
5293
|
+
chalk14.dim(` Last Flush: ${formatDate(telemetryStats.lastFlushAt)}`)
|
|
5128
5294
|
);
|
|
5129
5295
|
}
|
|
5130
5296
|
console.log("");
|
|
5131
5297
|
}
|
|
5132
5298
|
|
|
5133
5299
|
// src/cli/commands/solution.ts
|
|
5134
|
-
import
|
|
5135
|
-
import * as
|
|
5300
|
+
import chalk15 from "chalk";
|
|
5301
|
+
import * as p11 from "@clack/prompts";
|
|
5136
5302
|
import * as path2 from "path";
|
|
5137
5303
|
import {
|
|
5138
5304
|
PatternStore as PatternStore3,
|
|
@@ -5174,10 +5340,10 @@ function truncate(str, maxLen) {
|
|
|
5174
5340
|
async function solutionCaptureCommand(options) {
|
|
5175
5341
|
const cwd = getWorkspacePath2();
|
|
5176
5342
|
const store = new PatternStore3(cwd);
|
|
5177
|
-
console.log(
|
|
5343
|
+
console.log(chalk15.cyan("\n\u{1F4E6} Capture Solution Pattern\n"));
|
|
5178
5344
|
let targetPath = options.path;
|
|
5179
5345
|
if (!targetPath) {
|
|
5180
|
-
const pathInput = await
|
|
5346
|
+
const pathInput = await p11.text({
|
|
5181
5347
|
message: "Path to the solution directory:",
|
|
5182
5348
|
placeholder: "./src/auth",
|
|
5183
5349
|
validate: (val) => {
|
|
@@ -5185,8 +5351,8 @@ async function solutionCaptureCommand(options) {
|
|
|
5185
5351
|
return void 0;
|
|
5186
5352
|
}
|
|
5187
5353
|
});
|
|
5188
|
-
if (
|
|
5189
|
-
|
|
5354
|
+
if (p11.isCancel(pathInput)) {
|
|
5355
|
+
p11.cancel("Operation cancelled");
|
|
5190
5356
|
process.exit(0);
|
|
5191
5357
|
}
|
|
5192
5358
|
targetPath = pathInput;
|
|
@@ -5194,7 +5360,7 @@ async function solutionCaptureCommand(options) {
|
|
|
5194
5360
|
const absolutePath = path2.isAbsolute(targetPath) ? targetPath : path2.resolve(cwd, targetPath);
|
|
5195
5361
|
let name = options.name;
|
|
5196
5362
|
if (!name) {
|
|
5197
|
-
const nameInput = await
|
|
5363
|
+
const nameInput = await p11.text({
|
|
5198
5364
|
message: "Solution name:",
|
|
5199
5365
|
placeholder: "JWT Authentication",
|
|
5200
5366
|
validate: (val) => {
|
|
@@ -5202,15 +5368,15 @@ async function solutionCaptureCommand(options) {
|
|
|
5202
5368
|
return void 0;
|
|
5203
5369
|
}
|
|
5204
5370
|
});
|
|
5205
|
-
if (
|
|
5206
|
-
|
|
5371
|
+
if (p11.isCancel(nameInput)) {
|
|
5372
|
+
p11.cancel("Operation cancelled");
|
|
5207
5373
|
process.exit(0);
|
|
5208
5374
|
}
|
|
5209
5375
|
name = nameInput;
|
|
5210
5376
|
}
|
|
5211
5377
|
let description = options.description;
|
|
5212
5378
|
if (!description) {
|
|
5213
|
-
const descInput = await
|
|
5379
|
+
const descInput = await p11.text({
|
|
5214
5380
|
message: "Solution description:",
|
|
5215
5381
|
placeholder: "Complete JWT-based authentication with refresh tokens",
|
|
5216
5382
|
validate: (val) => {
|
|
@@ -5219,15 +5385,15 @@ async function solutionCaptureCommand(options) {
|
|
|
5219
5385
|
return void 0;
|
|
5220
5386
|
}
|
|
5221
5387
|
});
|
|
5222
|
-
if (
|
|
5223
|
-
|
|
5388
|
+
if (p11.isCancel(descInput)) {
|
|
5389
|
+
p11.cancel("Operation cancelled");
|
|
5224
5390
|
process.exit(0);
|
|
5225
5391
|
}
|
|
5226
5392
|
description = descInput;
|
|
5227
5393
|
}
|
|
5228
5394
|
let category = options.category;
|
|
5229
5395
|
if (!category) {
|
|
5230
|
-
const categoryChoice = await
|
|
5396
|
+
const categoryChoice = await p11.select({
|
|
5231
5397
|
message: "Solution category:",
|
|
5232
5398
|
options: [
|
|
5233
5399
|
{ value: "auth", label: "\u{1F510} Authentication" },
|
|
@@ -5246,8 +5412,8 @@ async function solutionCaptureCommand(options) {
|
|
|
5246
5412
|
{ value: "other", label: "\u{1F4E6} Other" }
|
|
5247
5413
|
]
|
|
5248
5414
|
});
|
|
5249
|
-
if (
|
|
5250
|
-
|
|
5415
|
+
if (p11.isCancel(categoryChoice)) {
|
|
5416
|
+
p11.cancel("Operation cancelled");
|
|
5251
5417
|
process.exit(0);
|
|
5252
5418
|
}
|
|
5253
5419
|
category = categoryChoice;
|
|
@@ -5256,20 +5422,20 @@ async function solutionCaptureCommand(options) {
|
|
|
5256
5422
|
if (options.keywords) {
|
|
5257
5423
|
keywords = options.keywords.split(",").map((k) => k.trim());
|
|
5258
5424
|
} else {
|
|
5259
|
-
const keywordsInput = await
|
|
5425
|
+
const keywordsInput = await p11.text({
|
|
5260
5426
|
message: "Keywords (comma-separated):",
|
|
5261
5427
|
placeholder: "jwt, authentication, login, refresh-token"
|
|
5262
5428
|
});
|
|
5263
|
-
if (
|
|
5264
|
-
|
|
5429
|
+
if (p11.isCancel(keywordsInput)) {
|
|
5430
|
+
p11.cancel("Operation cancelled");
|
|
5265
5431
|
process.exit(0);
|
|
5266
5432
|
}
|
|
5267
5433
|
if (keywordsInput) {
|
|
5268
5434
|
keywords = keywordsInput.split(",").map((k) => k.trim());
|
|
5269
5435
|
}
|
|
5270
5436
|
}
|
|
5271
|
-
const
|
|
5272
|
-
|
|
5437
|
+
const spinner9 = p11.spinner();
|
|
5438
|
+
spinner9.start("Analyzing solution...");
|
|
5273
5439
|
const analyzer = new CodeAnalyzer({
|
|
5274
5440
|
anonymize: options.anonymize ?? false
|
|
5275
5441
|
});
|
|
@@ -5281,38 +5447,38 @@ async function solutionCaptureCommand(options) {
|
|
|
5281
5447
|
category,
|
|
5282
5448
|
keywords
|
|
5283
5449
|
);
|
|
5284
|
-
|
|
5285
|
-
console.log(
|
|
5286
|
-
console.log(
|
|
5287
|
-
console.log(`${
|
|
5450
|
+
spinner9.stop("Solution analyzed");
|
|
5451
|
+
console.log(chalk15.green("\n\u2713 Solution captured successfully!\n"));
|
|
5452
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
5453
|
+
console.log(`${chalk15.bold("Name:")} ${pattern.name}`);
|
|
5288
5454
|
console.log(
|
|
5289
|
-
`${
|
|
5455
|
+
`${chalk15.bold("Category:")} ${formatCategory(pattern.category)}`
|
|
5290
5456
|
);
|
|
5291
5457
|
console.log(
|
|
5292
|
-
`${
|
|
5458
|
+
`${chalk15.bold("Files:")} ${pattern.implementation.files.length}`
|
|
5293
5459
|
);
|
|
5294
5460
|
console.log(
|
|
5295
|
-
`${
|
|
5461
|
+
`${chalk15.bold("Dependencies:")} ${pattern.implementation.dependencies.length}`
|
|
5296
5462
|
);
|
|
5297
5463
|
console.log(
|
|
5298
|
-
`${
|
|
5464
|
+
`${chalk15.bold("Framework:")} ${pattern.compatibility.framework || "generic"}`
|
|
5299
5465
|
);
|
|
5300
|
-
console.log(
|
|
5301
|
-
const
|
|
5466
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
5467
|
+
const confirm10 = await p11.confirm({
|
|
5302
5468
|
message: "Save this solution pattern?",
|
|
5303
5469
|
initialValue: true
|
|
5304
5470
|
});
|
|
5305
|
-
if (
|
|
5306
|
-
|
|
5471
|
+
if (p11.isCancel(confirm10) || !confirm10) {
|
|
5472
|
+
p11.cancel("Solution not saved");
|
|
5307
5473
|
process.exit(0);
|
|
5308
5474
|
}
|
|
5309
5475
|
await store.saveSolution(pattern);
|
|
5310
|
-
console.log(
|
|
5476
|
+
console.log(chalk15.green(`
|
|
5311
5477
|
\u2713 Solution saved with ID: ${pattern.id}
|
|
5312
5478
|
`));
|
|
5313
5479
|
} catch (error) {
|
|
5314
|
-
|
|
5315
|
-
console.error(
|
|
5480
|
+
spinner9.stop("Analysis failed");
|
|
5481
|
+
console.error(chalk15.red(`
|
|
5316
5482
|
\u2717 Error: ${error.message}
|
|
5317
5483
|
`));
|
|
5318
5484
|
process.exit(1);
|
|
@@ -5321,7 +5487,7 @@ async function solutionCaptureCommand(options) {
|
|
|
5321
5487
|
async function solutionSearchCommand(query, options) {
|
|
5322
5488
|
const cwd = getWorkspacePath2();
|
|
5323
5489
|
const store = new PatternStore3(cwd);
|
|
5324
|
-
console.log(
|
|
5490
|
+
console.log(chalk15.cyan("\n\u{1F50D} Search Solution Patterns\n"));
|
|
5325
5491
|
const keywords = query.split(/\s+/).filter((k) => k.length > 0);
|
|
5326
5492
|
const result = await store.searchSolutions(keywords, {
|
|
5327
5493
|
category: options.category,
|
|
@@ -5329,39 +5495,39 @@ async function solutionSearchCommand(query, options) {
|
|
|
5329
5495
|
limit: options.limit ?? 10
|
|
5330
5496
|
});
|
|
5331
5497
|
if (!result.success || !result.data) {
|
|
5332
|
-
console.error(
|
|
5498
|
+
console.error(chalk15.red(`
|
|
5333
5499
|
\u2717 Search failed: ${result.error}
|
|
5334
5500
|
`));
|
|
5335
5501
|
return;
|
|
5336
5502
|
}
|
|
5337
5503
|
const solutions = result.data;
|
|
5338
5504
|
if (solutions.length === 0) {
|
|
5339
|
-
console.log(
|
|
5340
|
-
console.log(
|
|
5505
|
+
console.log(chalk15.yellow("No solutions found matching your query.\n"));
|
|
5506
|
+
console.log(chalk15.dim("Try different keywords or fewer filters."));
|
|
5341
5507
|
return;
|
|
5342
5508
|
}
|
|
5343
|
-
console.log(
|
|
5509
|
+
console.log(chalk15.green(`Found ${solutions.length} solution(s):
|
|
5344
5510
|
`));
|
|
5345
|
-
console.log(
|
|
5511
|
+
console.log(chalk15.dim("\u2500".repeat(70)));
|
|
5346
5512
|
for (const solution of solutions) {
|
|
5347
5513
|
console.log(
|
|
5348
|
-
`${
|
|
5514
|
+
`${chalk15.bold(solution.name)} ${chalk15.dim(`(${solution.id.slice(0, 8)})`)}`
|
|
5349
5515
|
);
|
|
5350
5516
|
console.log(` ${formatCategory(solution.category)}`);
|
|
5351
|
-
console.log(` ${
|
|
5517
|
+
console.log(` ${chalk15.dim(truncate(solution.description, 60))}`);
|
|
5352
5518
|
console.log(
|
|
5353
5519
|
` Files: ${solution.implementation.files.length} | Framework: ${solution.compatibility.framework || "generic"} | Uses: ${solution.metrics.applications}`
|
|
5354
5520
|
);
|
|
5355
|
-
console.log(
|
|
5521
|
+
console.log(chalk15.dim("\u2500".repeat(70)));
|
|
5356
5522
|
}
|
|
5357
5523
|
console.log(
|
|
5358
|
-
|
|
5524
|
+
chalk15.dim("\nUse 'workflow solution:apply <id>' to apply a solution.")
|
|
5359
5525
|
);
|
|
5360
5526
|
}
|
|
5361
5527
|
async function solutionListCommand(options) {
|
|
5362
5528
|
const cwd = getWorkspacePath2();
|
|
5363
5529
|
const store = new PatternStore3(cwd);
|
|
5364
|
-
console.log(
|
|
5530
|
+
console.log(chalk15.cyan("\n\u{1F4CB} Solution Patterns\n"));
|
|
5365
5531
|
const result = await store.listSolutions({
|
|
5366
5532
|
category: options.category,
|
|
5367
5533
|
framework: options.framework,
|
|
@@ -5369,20 +5535,20 @@ async function solutionListCommand(options) {
|
|
|
5369
5535
|
limit: options.limit ?? 20
|
|
5370
5536
|
});
|
|
5371
5537
|
if (!result.success || !result.data) {
|
|
5372
|
-
console.error(
|
|
5538
|
+
console.error(chalk15.red(`
|
|
5373
5539
|
\u2717 List failed: ${result.error}
|
|
5374
5540
|
`));
|
|
5375
5541
|
return;
|
|
5376
5542
|
}
|
|
5377
5543
|
const solutions = result.data;
|
|
5378
5544
|
if (solutions.length === 0) {
|
|
5379
|
-
console.log(
|
|
5545
|
+
console.log(chalk15.yellow("No solutions found.\n"));
|
|
5380
5546
|
console.log(
|
|
5381
|
-
|
|
5547
|
+
chalk15.dim("Use 'workflow solution:capture' to capture a solution.")
|
|
5382
5548
|
);
|
|
5383
5549
|
return;
|
|
5384
5550
|
}
|
|
5385
|
-
console.log(
|
|
5551
|
+
console.log(chalk15.green(`${solutions.length} solution(s):
|
|
5386
5552
|
`));
|
|
5387
5553
|
const byCategory = /* @__PURE__ */ new Map();
|
|
5388
5554
|
for (const solution of solutions) {
|
|
@@ -5391,24 +5557,24 @@ async function solutionListCommand(options) {
|
|
|
5391
5557
|
byCategory.set(solution.category, list);
|
|
5392
5558
|
}
|
|
5393
5559
|
for (const [category, items] of byCategory) {
|
|
5394
|
-
console.log(
|
|
5560
|
+
console.log(chalk15.bold(`
|
|
5395
5561
|
${formatCategory(category)}`));
|
|
5396
|
-
console.log(
|
|
5562
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
5397
5563
|
for (const solution of items) {
|
|
5398
|
-
const deprecated = solution.deprecatedAt ?
|
|
5564
|
+
const deprecated = solution.deprecatedAt ? chalk15.red(" [DEPRECATED]") : "";
|
|
5399
5565
|
console.log(
|
|
5400
|
-
` ${
|
|
5566
|
+
` ${chalk15.cyan(solution.id.slice(0, 8))} ${solution.name}${deprecated}`
|
|
5401
5567
|
);
|
|
5402
|
-
console.log(` ${
|
|
5568
|
+
console.log(` ${chalk15.dim(truncate(solution.description, 50))}`);
|
|
5403
5569
|
console.log(
|
|
5404
|
-
|
|
5570
|
+
chalk15.dim(
|
|
5405
5571
|
` Created: ${formatDate2(solution.createdAt)} | Files: ${solution.implementation.files.length}`
|
|
5406
5572
|
)
|
|
5407
5573
|
);
|
|
5408
5574
|
}
|
|
5409
5575
|
}
|
|
5410
5576
|
console.log(
|
|
5411
|
-
|
|
5577
|
+
chalk15.dim(
|
|
5412
5578
|
"\nUse 'workflow solution:search <query>' to find specific solutions."
|
|
5413
5579
|
)
|
|
5414
5580
|
);
|
|
@@ -5416,10 +5582,10 @@ ${formatCategory(category)}`));
|
|
|
5416
5582
|
async function solutionApplyCommand(solutionId, options) {
|
|
5417
5583
|
const cwd = getWorkspacePath2();
|
|
5418
5584
|
const store = new PatternStore3(cwd);
|
|
5419
|
-
console.log(
|
|
5585
|
+
console.log(chalk15.cyan("\n\u{1F680} Apply Solution Pattern\n"));
|
|
5420
5586
|
const result = await store.getSolution(solutionId);
|
|
5421
5587
|
if (!result.success || !result.data) {
|
|
5422
|
-
console.error(
|
|
5588
|
+
console.error(chalk15.red(`
|
|
5423
5589
|
\u2717 Solution not found: ${solutionId}
|
|
5424
5590
|
`));
|
|
5425
5591
|
process.exit(1);
|
|
@@ -5427,60 +5593,60 @@ async function solutionApplyCommand(solutionId, options) {
|
|
|
5427
5593
|
const solution = result.data;
|
|
5428
5594
|
if (solution.deprecatedAt) {
|
|
5429
5595
|
console.log(
|
|
5430
|
-
|
|
5596
|
+
chalk15.yellow(
|
|
5431
5597
|
`\u26A0\uFE0F This solution is deprecated: ${solution.deprecationReason || "No reason provided"}
|
|
5432
5598
|
`
|
|
5433
5599
|
)
|
|
5434
5600
|
);
|
|
5435
|
-
const proceed = await
|
|
5601
|
+
const proceed = await p11.confirm({
|
|
5436
5602
|
message: "Do you want to continue?",
|
|
5437
5603
|
initialValue: false
|
|
5438
5604
|
});
|
|
5439
|
-
if (
|
|
5440
|
-
|
|
5605
|
+
if (p11.isCancel(proceed) || !proceed) {
|
|
5606
|
+
p11.cancel("Operation cancelled");
|
|
5441
5607
|
process.exit(0);
|
|
5442
5608
|
}
|
|
5443
5609
|
}
|
|
5444
|
-
console.log(
|
|
5445
|
-
console.log(
|
|
5610
|
+
console.log(chalk15.bold(`Solution: ${solution.name}`));
|
|
5611
|
+
console.log(chalk15.dim(solution.description));
|
|
5446
5612
|
console.log();
|
|
5447
|
-
console.log(
|
|
5613
|
+
console.log(chalk15.bold("Files to create:"));
|
|
5448
5614
|
const filesToApply = options.includeTests ? solution.implementation.files : solution.implementation.files.filter(
|
|
5449
5615
|
(f) => f.role !== "test"
|
|
5450
5616
|
);
|
|
5451
5617
|
for (const file of filesToApply) {
|
|
5452
|
-
console.log(
|
|
5618
|
+
console.log(chalk15.dim(` \u2022 ${file.path} (${file.role})`));
|
|
5453
5619
|
}
|
|
5454
5620
|
console.log();
|
|
5455
5621
|
if (solution.implementation.dependencies.length > 0) {
|
|
5456
|
-
console.log(
|
|
5622
|
+
console.log(chalk15.bold("Dependencies to install:"));
|
|
5457
5623
|
for (const dep of solution.implementation.dependencies) {
|
|
5458
|
-
console.log(
|
|
5624
|
+
console.log(chalk15.dim(` \u2022 ${dep.name}@${dep.version}`));
|
|
5459
5625
|
}
|
|
5460
5626
|
console.log();
|
|
5461
5627
|
}
|
|
5462
5628
|
if (solution.implementation.envVars.length > 0) {
|
|
5463
|
-
console.log(
|
|
5629
|
+
console.log(chalk15.bold("Environment variables needed:"));
|
|
5464
5630
|
for (const env of solution.implementation.envVars) {
|
|
5465
|
-
const required = env.required ?
|
|
5466
|
-
console.log(
|
|
5631
|
+
const required = env.required ? chalk15.red("*") : "";
|
|
5632
|
+
console.log(chalk15.dim(` \u2022 ${env.name}${required}`));
|
|
5467
5633
|
}
|
|
5468
5634
|
console.log();
|
|
5469
5635
|
}
|
|
5470
5636
|
if (options.dryRun) {
|
|
5471
|
-
console.log(
|
|
5637
|
+
console.log(chalk15.yellow("Dry run mode - no files were created.\n"));
|
|
5472
5638
|
return;
|
|
5473
5639
|
}
|
|
5474
|
-
const
|
|
5640
|
+
const confirm10 = await p11.confirm({
|
|
5475
5641
|
message: "Apply this solution?",
|
|
5476
5642
|
initialValue: true
|
|
5477
5643
|
});
|
|
5478
|
-
if (
|
|
5479
|
-
|
|
5644
|
+
if (p11.isCancel(confirm10) || !confirm10) {
|
|
5645
|
+
p11.cancel("Operation cancelled");
|
|
5480
5646
|
process.exit(0);
|
|
5481
5647
|
}
|
|
5482
|
-
const
|
|
5483
|
-
|
|
5648
|
+
const spinner9 = p11.spinner();
|
|
5649
|
+
spinner9.start("Applying solution...");
|
|
5484
5650
|
try {
|
|
5485
5651
|
const outputDir = options.output || cwd;
|
|
5486
5652
|
const fs2 = await import("fs");
|
|
@@ -5492,20 +5658,20 @@ async function solutionApplyCommand(solutionId, options) {
|
|
|
5492
5658
|
await fs2.promises.writeFile(filePath, file.content);
|
|
5493
5659
|
}
|
|
5494
5660
|
await store.updateSolutionMetrics(solution.id, true);
|
|
5495
|
-
|
|
5496
|
-
console.log(
|
|
5661
|
+
spinner9.stop("Solution applied");
|
|
5662
|
+
console.log(chalk15.green(`
|
|
5497
5663
|
\u2713 Solution applied successfully!
|
|
5498
5664
|
`));
|
|
5499
|
-
console.log(
|
|
5665
|
+
console.log(chalk15.dim(`Created ${filesToApply.length} file(s).`));
|
|
5500
5666
|
if (solution.implementation.dependencies.length > 0) {
|
|
5501
|
-
console.log(
|
|
5667
|
+
console.log(chalk15.cyan("\nNext step: Install dependencies with:"));
|
|
5502
5668
|
const deps = solution.implementation.dependencies.map((d) => `${d.name}@${d.version}`).join(" ");
|
|
5503
|
-
console.log(
|
|
5669
|
+
console.log(chalk15.dim(` npm install ${deps}`));
|
|
5504
5670
|
}
|
|
5505
5671
|
} catch (error) {
|
|
5506
|
-
|
|
5672
|
+
spinner9.stop("Application failed");
|
|
5507
5673
|
await store.updateSolutionMetrics(solution.id, false);
|
|
5508
|
-
console.error(
|
|
5674
|
+
console.error(chalk15.red(`
|
|
5509
5675
|
\u2717 Error: ${error.message}
|
|
5510
5676
|
`));
|
|
5511
5677
|
process.exit(1);
|
|
@@ -5514,48 +5680,48 @@ async function solutionApplyCommand(solutionId, options) {
|
|
|
5514
5680
|
async function solutionDeprecateCommand(solutionId, reason) {
|
|
5515
5681
|
const cwd = getWorkspacePath2();
|
|
5516
5682
|
const store = new PatternStore3(cwd);
|
|
5517
|
-
console.log(
|
|
5683
|
+
console.log(chalk15.cyan("\n\u26A0\uFE0F Deprecate Solution Pattern\n"));
|
|
5518
5684
|
const result = await store.getSolution(solutionId);
|
|
5519
5685
|
if (!result.success || !result.data) {
|
|
5520
|
-
console.error(
|
|
5686
|
+
console.error(chalk15.red(`
|
|
5521
5687
|
\u2717 Solution not found: ${solutionId}
|
|
5522
5688
|
`));
|
|
5523
5689
|
process.exit(1);
|
|
5524
5690
|
}
|
|
5525
5691
|
const solution = result.data;
|
|
5526
|
-
console.log(`Solution: ${
|
|
5692
|
+
console.log(`Solution: ${chalk15.bold(solution.name)}`);
|
|
5527
5693
|
console.log(`Reason: ${reason}
|
|
5528
5694
|
`);
|
|
5529
|
-
const
|
|
5695
|
+
const confirm10 = await p11.confirm({
|
|
5530
5696
|
message: "Deprecate this solution?",
|
|
5531
5697
|
initialValue: false
|
|
5532
5698
|
});
|
|
5533
|
-
if (
|
|
5534
|
-
|
|
5699
|
+
if (p11.isCancel(confirm10) || !confirm10) {
|
|
5700
|
+
p11.cancel("Operation cancelled");
|
|
5535
5701
|
process.exit(0);
|
|
5536
5702
|
}
|
|
5537
5703
|
await store.deprecateSolution(solutionId, reason);
|
|
5538
|
-
console.log(
|
|
5704
|
+
console.log(chalk15.green(`
|
|
5539
5705
|
\u2713 Solution deprecated.
|
|
5540
5706
|
`));
|
|
5541
5707
|
}
|
|
5542
5708
|
async function solutionStatsCommand() {
|
|
5543
5709
|
const cwd = getWorkspacePath2();
|
|
5544
5710
|
const store = new PatternStore3(cwd);
|
|
5545
|
-
console.log(
|
|
5711
|
+
console.log(chalk15.cyan("\n\u{1F4CA} Solution Pattern Statistics\n"));
|
|
5546
5712
|
const stats = await store.getStats();
|
|
5547
|
-
console.log(
|
|
5548
|
-
console.log(`${
|
|
5713
|
+
console.log(chalk15.dim("\u2500".repeat(40)));
|
|
5714
|
+
console.log(`${chalk15.bold("Solutions:")} ${stats.totalSolutions}`);
|
|
5549
5715
|
console.log(` Active: ${stats.totalSolutions - stats.deprecatedSolutions}`);
|
|
5550
5716
|
console.log(` Deprecated: ${stats.deprecatedSolutions}`);
|
|
5551
5717
|
console.log(` Private: ${stats.privateSolutions}`);
|
|
5552
5718
|
console.log(` Synced: ${stats.syncedSolutions}`);
|
|
5553
|
-
console.log(
|
|
5554
|
-
console.log(`${
|
|
5555
|
-
console.log(`${
|
|
5556
|
-
console.log(
|
|
5719
|
+
console.log(chalk15.dim("\u2500".repeat(40)));
|
|
5720
|
+
console.log(`${chalk15.bold("Fixes:")} ${stats.totalFixes}`);
|
|
5721
|
+
console.log(`${chalk15.bold("Blueprints:")} ${stats.totalBlueprints}`);
|
|
5722
|
+
console.log(chalk15.dim("\u2500".repeat(40)));
|
|
5557
5723
|
console.log(`
|
|
5558
|
-
${
|
|
5724
|
+
${chalk15.bold("By Category:")}`);
|
|
5559
5725
|
const listResult = await store.listSolutions({ limit: 1e3 });
|
|
5560
5726
|
if (listResult.success && listResult.data) {
|
|
5561
5727
|
const categories = /* @__PURE__ */ new Map();
|
|
@@ -5607,6 +5773,7 @@ program.command("advisory").description("Generate advisory board analysis and do
|
|
|
5607
5773
|
"Output format: markdown, json (default: markdown)"
|
|
5608
5774
|
).option("--timestamp", "Append timestamp to filenames").option("--include-health", "Include code health metrics from verify/doctor").option("--ci", "CI mode with exit codes on high-risk findings").option("--compare <path>", "Compare with previous report").action(advisoryCommand);
|
|
5609
5775
|
program.command("generate-instructions").description("Generate .github/copilot-instructions.md from guidelines").option("--force", "Regenerate without confirmation").action(generateInstructionsCommand);
|
|
5776
|
+
program.command("update-templates").description("Update guideline templates from the latest package version").option("--force", "Overwrite existing template files").option("--skip", "Skip the update (useful in CI)").action(updateTemplatesCommand);
|
|
5610
5777
|
program.command("learn:record").description("Record a new pattern from a successful implementation").option("--name <name>", "Pattern name").option("--description <desc>", "Pattern description").option(
|
|
5611
5778
|
"--category <cat>",
|
|
5612
5779
|
"Category (migration, security, performance, etc.)"
|