workflow-agent-cli 2.6.0 → 2.7.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 +415 -0
- package/dist/chunk-HKRWHFVI.js.map +1 -0
- package/dist/cli/index.js +369 -271
- package/dist/cli/index.js.map +1 -1
- package/dist/scripts/postinstall.js +16 -2
- package/dist/scripts/postinstall.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-LN5OAWEQ.js +0 -92
- package/dist/chunk-LN5OAWEQ.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -22,8 +22,9 @@ import {
|
|
|
22
22
|
import {
|
|
23
23
|
SCRIPT_CATEGORIES,
|
|
24
24
|
TOTAL_SCRIPTS,
|
|
25
|
-
WORKFLOW_SCRIPTS
|
|
26
|
-
|
|
25
|
+
WORKFLOW_SCRIPTS,
|
|
26
|
+
generateCopilotInstructions
|
|
27
|
+
} from "../chunk-HKRWHFVI.js";
|
|
27
28
|
|
|
28
29
|
// src/cli/index.ts
|
|
29
30
|
import { Command } from "commander";
|
|
@@ -310,10 +311,10 @@ async function initCommand(options) {
|
|
|
310
311
|
try {
|
|
311
312
|
const presetModule = await import(`@workflow/scopes-${preset}`);
|
|
312
313
|
scopes = presetModule.scopes || presetModule.default.scopes;
|
|
313
|
-
const
|
|
314
|
-
|
|
314
|
+
const spinner8 = p.spinner();
|
|
315
|
+
spinner8.start(`Loading ${presetModule.default?.name || preset} preset`);
|
|
315
316
|
await new Promise((resolve2) => setTimeout(resolve2, 500));
|
|
316
|
-
|
|
317
|
+
spinner8.stop(`\u2713 Loaded ${scopes.length} scopes from preset`);
|
|
317
318
|
} catch (error) {
|
|
318
319
|
console.log(
|
|
319
320
|
chalk.yellow(
|
|
@@ -360,8 +361,8 @@ async function initCommand(options) {
|
|
|
360
361
|
process.exit(0);
|
|
361
362
|
}
|
|
362
363
|
if (shouldGenerateGuidelines) {
|
|
363
|
-
const
|
|
364
|
-
|
|
364
|
+
const spinner8 = p.spinner();
|
|
365
|
+
spinner8.start("Generating guidelines...");
|
|
365
366
|
try {
|
|
366
367
|
const templatesDir = join(__dirname, "../../templates");
|
|
367
368
|
await validateTemplateDirectory(templatesDir);
|
|
@@ -373,9 +374,17 @@ async function initCommand(options) {
|
|
|
373
374
|
guidelinesDir,
|
|
374
375
|
context
|
|
375
376
|
);
|
|
376
|
-
|
|
377
|
+
spinner8.stop(`\u2713 Generated ${renderedFiles.length} guideline documents`);
|
|
378
|
+
const instructionsSpinner = p.spinner();
|
|
379
|
+
instructionsSpinner.start("Generating AI agent instructions...");
|
|
380
|
+
const result = generateCopilotInstructions(cwd, { silent: true });
|
|
381
|
+
if (result.success) {
|
|
382
|
+
instructionsSpinner.stop(`\u2713 Generated .github/copilot-instructions.md`);
|
|
383
|
+
} else {
|
|
384
|
+
instructionsSpinner.stop("\u26A0\uFE0F Could not generate copilot instructions");
|
|
385
|
+
}
|
|
377
386
|
} catch (error) {
|
|
378
|
-
|
|
387
|
+
spinner8.stop("\u26A0\uFE0F Could not generate guidelines");
|
|
379
388
|
console.log(
|
|
380
389
|
chalk.yellow(
|
|
381
390
|
`
|
|
@@ -667,6 +676,21 @@ async function setupCommand() {
|
|
|
667
676
|
console.log(chalk6.dim("\nRun them with:"));
|
|
668
677
|
console.log(chalk6.dim(" pnpm run workflow:init"));
|
|
669
678
|
console.log(chalk6.dim(" npm run workflow:init\n"));
|
|
679
|
+
const guidelinesDir = join2(cwd, "guidelines");
|
|
680
|
+
if (existsSync2(guidelinesDir)) {
|
|
681
|
+
const result = generateCopilotInstructions(cwd, { silent: false });
|
|
682
|
+
if (result.success) {
|
|
683
|
+
const status = result.isNew ? "Generated" : "Updated";
|
|
684
|
+
console.log(
|
|
685
|
+
chalk6.green(
|
|
686
|
+
`\u2713 ${status} .github/copilot-instructions.md from ${result.guidelinesCount} guidelines`
|
|
687
|
+
)
|
|
688
|
+
);
|
|
689
|
+
if (result.preservedCustomContent) {
|
|
690
|
+
console.log(chalk6.dim(" (Custom content preserved)"));
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
670
694
|
}
|
|
671
695
|
|
|
672
696
|
// src/cli/commands/scope-create.ts
|
|
@@ -848,8 +872,8 @@ async function scopeCreateCommand(options) {
|
|
|
848
872
|
process.exit(0);
|
|
849
873
|
}
|
|
850
874
|
}
|
|
851
|
-
const
|
|
852
|
-
|
|
875
|
+
const spinner8 = p4.spinner();
|
|
876
|
+
spinner8.start("Creating package structure...");
|
|
853
877
|
try {
|
|
854
878
|
await mkdir2(join3(outputDir, "src"), { recursive: true });
|
|
855
879
|
const packageJson = {
|
|
@@ -980,7 +1004,7 @@ describe('${presetName} Scope Preset', () => {
|
|
|
980
1004
|
"utf-8"
|
|
981
1005
|
);
|
|
982
1006
|
}
|
|
983
|
-
|
|
1007
|
+
spinner8.stop("\u2713 Package structure created");
|
|
984
1008
|
if (isMonorepo2) {
|
|
985
1009
|
const workspaceFile = join3(cwd, "pnpm-workspace.yaml");
|
|
986
1010
|
const workspaceContent = await readFile(workspaceFile, "utf-8");
|
|
@@ -1032,7 +1056,7 @@ describe('${presetName} Scope Preset', () => {
|
|
|
1032
1056
|
);
|
|
1033
1057
|
}
|
|
1034
1058
|
} catch (error) {
|
|
1035
|
-
|
|
1059
|
+
spinner8.stop("\u2717 Failed to create package");
|
|
1036
1060
|
console.error(chalk7.red("\nError:"), error);
|
|
1037
1061
|
process.exit(1);
|
|
1038
1062
|
}
|
|
@@ -1160,8 +1184,8 @@ async function scopeMigrateCommand(options) {
|
|
|
1160
1184
|
process.exit(0);
|
|
1161
1185
|
}
|
|
1162
1186
|
}
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1187
|
+
const spinner8 = p5.spinner();
|
|
1188
|
+
spinner8.start("Migrating scopes to package...");
|
|
1165
1189
|
try {
|
|
1166
1190
|
await mkdir3(join4(outputDir, "src"), { recursive: true });
|
|
1167
1191
|
const packageJson = {
|
|
@@ -1289,7 +1313,7 @@ describe('${presetName} Scope Preset (Migrated)', () => {
|
|
|
1289
1313
|
});
|
|
1290
1314
|
`;
|
|
1291
1315
|
await writeFile3(join4(outputDir, "src", "index.test.ts"), testFile, "utf-8");
|
|
1292
|
-
|
|
1316
|
+
spinner8.stop("\u2713 Package created from migrated scopes");
|
|
1293
1317
|
if (isMonorepo2) {
|
|
1294
1318
|
const workspaceFile = join4(cwd, "pnpm-workspace.yaml");
|
|
1295
1319
|
const workspaceContent = await readFile2(workspaceFile, "utf-8");
|
|
@@ -1361,7 +1385,7 @@ describe('${presetName} Scope Preset (Migrated)', () => {
|
|
|
1361
1385
|
)
|
|
1362
1386
|
);
|
|
1363
1387
|
} catch (error) {
|
|
1364
|
-
|
|
1388
|
+
spinner8.stop("\u2717 Migration failed");
|
|
1365
1389
|
console.error(chalk8.red("\nError:"), error);
|
|
1366
1390
|
process.exit(1);
|
|
1367
1391
|
}
|
|
@@ -1601,14 +1625,14 @@ import chalk10 from "chalk";
|
|
|
1601
1625
|
async function autoSetupCommand(options) {
|
|
1602
1626
|
console.log(chalk10.bold.cyan("\n\u{1F527} Workflow Agent Auto-Setup\n"));
|
|
1603
1627
|
const cwd = process.cwd();
|
|
1604
|
-
const
|
|
1605
|
-
|
|
1628
|
+
const spinner8 = p6.spinner();
|
|
1629
|
+
spinner8.start("Analyzing project...");
|
|
1606
1630
|
let report;
|
|
1607
1631
|
try {
|
|
1608
1632
|
report = await generateAuditReport(cwd);
|
|
1609
|
-
|
|
1633
|
+
spinner8.stop("\u2713 Project analysis complete");
|
|
1610
1634
|
} catch (error) {
|
|
1611
|
-
|
|
1635
|
+
spinner8.stop("\u2717 Failed to analyze project");
|
|
1612
1636
|
console.error(
|
|
1613
1637
|
chalk10.red(
|
|
1614
1638
|
`Error: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -2784,7 +2808,7 @@ var QuestionGenerator = class {
|
|
|
2784
2808
|
category: "Platform Strategy",
|
|
2785
2809
|
question: `Are our platform choices (${technology.platforms.join(", ")}) aligned with target market and growth plans?`,
|
|
2786
2810
|
context: `Currently deployed on ${technology.platforms.join(" + ")}`,
|
|
2787
|
-
findings: technology.platforms.map((
|
|
2811
|
+
findings: technology.platforms.map((p11) => `Supports ${p11} platform`),
|
|
2788
2812
|
recommendations: [
|
|
2789
2813
|
"Validate platform coverage matches user demographics",
|
|
2790
2814
|
"Assess cross-platform development efficiency",
|
|
@@ -2846,7 +2870,7 @@ var QuestionGenerator = class {
|
|
|
2846
2870
|
category: "Business Alignment",
|
|
2847
2871
|
question: `How is our authentication solution (${authCat.packages.join(", ")}) supporting user onboarding and security requirements?`,
|
|
2848
2872
|
context: `Using ${authCat.packages.join(" + ")} for authentication`,
|
|
2849
|
-
findings: authCat.packages.map((
|
|
2873
|
+
findings: authCat.packages.map((p11) => `Auth provider: ${p11}`),
|
|
2850
2874
|
recommendations: [
|
|
2851
2875
|
"Measure authentication success rates and friction points",
|
|
2852
2876
|
"Ensure compliance with security standards (SOC2, GDPR, etc.)",
|
|
@@ -2898,12 +2922,12 @@ var QuestionGenerator = class {
|
|
|
2898
2922
|
});
|
|
2899
2923
|
}
|
|
2900
2924
|
if (packages.outdated && packages.outdated.length > 10) {
|
|
2901
|
-
const breakingCount = packages.outdated.filter((
|
|
2925
|
+
const breakingCount = packages.outdated.filter((p11) => p11.breaking).length;
|
|
2902
2926
|
questions.push({
|
|
2903
2927
|
category: "Technical Debt",
|
|
2904
2928
|
question: `How should we prioritize updating ${packages.outdated.length} outdated packages${breakingCount > 0 ? ` (${breakingCount} with breaking changes)` : ""}?`,
|
|
2905
2929
|
context: "Dependency audit found outdated packages",
|
|
2906
|
-
findings: packages.outdated.slice(0, 5).map((
|
|
2930
|
+
findings: packages.outdated.slice(0, 5).map((p11) => `${p11.name}: ${p11.current} \u2192 ${p11.latest}`),
|
|
2907
2931
|
recommendations: [
|
|
2908
2932
|
"Create update roadmap starting with non-breaking changes",
|
|
2909
2933
|
"Test breaking changes in feature branches",
|
|
@@ -3213,10 +3237,10 @@ var ReportComparator = class {
|
|
|
3213
3237
|
*/
|
|
3214
3238
|
comparePackages() {
|
|
3215
3239
|
const baselineProduction = new Map(
|
|
3216
|
-
this.baseline.packages.production.map((
|
|
3240
|
+
this.baseline.packages.production.map((p11) => [p11.name, p11])
|
|
3217
3241
|
);
|
|
3218
3242
|
const currentProduction = new Map(
|
|
3219
|
-
this.current.packages.production.map((
|
|
3243
|
+
this.current.packages.production.map((p11) => [p11.name, p11])
|
|
3220
3244
|
);
|
|
3221
3245
|
const added = [];
|
|
3222
3246
|
const removed = [];
|
|
@@ -3248,10 +3272,10 @@ var ReportComparator = class {
|
|
|
3248
3272
|
}
|
|
3249
3273
|
}
|
|
3250
3274
|
const baselineDev = new Map(
|
|
3251
|
-
this.baseline.packages.development.map((
|
|
3275
|
+
this.baseline.packages.development.map((p11) => [p11.name, p11])
|
|
3252
3276
|
);
|
|
3253
3277
|
const currentDev = new Map(
|
|
3254
|
-
this.current.packages.development.map((
|
|
3278
|
+
this.current.packages.development.map((p11) => [p11.name, p11])
|
|
3255
3279
|
);
|
|
3256
3280
|
for (const [name, pkg] of currentDev) {
|
|
3257
3281
|
if (!baselineDev.has(name)) {
|
|
@@ -3539,20 +3563,20 @@ async function advisoryCommand(options) {
|
|
|
3539
3563
|
includeHealth,
|
|
3540
3564
|
excludePatterns: advisoryConfig?.excludePatterns
|
|
3541
3565
|
});
|
|
3542
|
-
const
|
|
3566
|
+
const spinner8 = p7.spinner();
|
|
3543
3567
|
const depthLabels = {
|
|
3544
3568
|
executive: "executive summary",
|
|
3545
3569
|
quick: "quick scan",
|
|
3546
3570
|
standard: "standard analysis",
|
|
3547
3571
|
comprehensive: "comprehensive analysis"
|
|
3548
3572
|
};
|
|
3549
|
-
|
|
3573
|
+
spinner8.start(`Running ${depthLabels[depth]}...`);
|
|
3550
3574
|
let analysis;
|
|
3551
3575
|
try {
|
|
3552
3576
|
analysis = await analyzer.analyze();
|
|
3553
|
-
|
|
3577
|
+
spinner8.stop(`\u2713 Analysis complete`);
|
|
3554
3578
|
} catch (error) {
|
|
3555
|
-
|
|
3579
|
+
spinner8.stop("\u2717 Analysis failed");
|
|
3556
3580
|
console.error(
|
|
3557
3581
|
chalk11.red(
|
|
3558
3582
|
`Error: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -3569,17 +3593,17 @@ async function advisoryCommand(options) {
|
|
|
3569
3593
|
if (options.compare) {
|
|
3570
3594
|
const comparisonPath = options.compare.endsWith(".json") ? join6(cwd, options.compare) : join6(cwd, options.compare, "analysis.json");
|
|
3571
3595
|
if (existsSync6(comparisonPath)) {
|
|
3572
|
-
|
|
3596
|
+
spinner8.start("Comparing with previous report...");
|
|
3573
3597
|
try {
|
|
3574
3598
|
const previousContent = await readFile4(comparisonPath, "utf-8");
|
|
3575
3599
|
const previousAnalysis = JSON.parse(previousContent);
|
|
3576
3600
|
comparator = new ReportComparator(previousAnalysis, analysis);
|
|
3577
3601
|
comparisonReport = comparator.compare();
|
|
3578
|
-
|
|
3602
|
+
spinner8.stop("\u2713 Comparison complete");
|
|
3579
3603
|
console.log("");
|
|
3580
3604
|
displayComparisonSummary(comparisonReport);
|
|
3581
3605
|
} catch (error) {
|
|
3582
|
-
|
|
3606
|
+
spinner8.stop("\u26A0 Comparison failed");
|
|
3583
3607
|
console.warn(chalk11.yellow(`Could not compare reports: ${error}`));
|
|
3584
3608
|
}
|
|
3585
3609
|
} else {
|
|
@@ -3598,7 +3622,7 @@ async function advisoryCommand(options) {
|
|
|
3598
3622
|
}
|
|
3599
3623
|
const fullOutputDir = join6(cwd, outputDir);
|
|
3600
3624
|
await mkdir4(fullOutputDir, { recursive: true });
|
|
3601
|
-
|
|
3625
|
+
spinner8.start("Generating reports...");
|
|
3602
3626
|
try {
|
|
3603
3627
|
const timestamp = options.timestamp ? (/* @__PURE__ */ new Date()).toISOString().split("T")[0] : "";
|
|
3604
3628
|
if (options.format === "json") {
|
|
@@ -3612,9 +3636,9 @@ async function advisoryCommand(options) {
|
|
|
3612
3636
|
timestamp
|
|
3613
3637
|
);
|
|
3614
3638
|
}
|
|
3615
|
-
|
|
3639
|
+
spinner8.stop("\u2713 Reports generated");
|
|
3616
3640
|
} catch (error) {
|
|
3617
|
-
|
|
3641
|
+
spinner8.stop("\u2717 Failed to write reports");
|
|
3618
3642
|
console.error(chalk11.red(`Error: ${error}`));
|
|
3619
3643
|
process.exit(1);
|
|
3620
3644
|
}
|
|
@@ -4386,9 +4410,82 @@ function checkCIThresholds(analysis, config) {
|
|
|
4386
4410
|
return 0;
|
|
4387
4411
|
}
|
|
4388
4412
|
|
|
4389
|
-
// src/cli/commands/
|
|
4390
|
-
import chalk12 from "chalk";
|
|
4413
|
+
// src/cli/commands/generate-instructions.ts
|
|
4391
4414
|
import * as p8 from "@clack/prompts";
|
|
4415
|
+
import chalk12 from "chalk";
|
|
4416
|
+
import { existsSync as existsSync7 } from "fs";
|
|
4417
|
+
import { join as join7 } from "path";
|
|
4418
|
+
async function generateInstructionsCommand(options) {
|
|
4419
|
+
p8.intro(chalk12.bgBlue(" workflow-agent generate-instructions "));
|
|
4420
|
+
const cwd = process.cwd();
|
|
4421
|
+
const guidelinesDir = join7(cwd, "guidelines");
|
|
4422
|
+
const outputPath = join7(cwd, ".github", "copilot-instructions.md");
|
|
4423
|
+
if (!existsSync7(guidelinesDir)) {
|
|
4424
|
+
p8.cancel(
|
|
4425
|
+
"No guidelines directory found. Run 'workflow init' first to generate guidelines."
|
|
4426
|
+
);
|
|
4427
|
+
process.exit(1);
|
|
4428
|
+
}
|
|
4429
|
+
if (existsSync7(outputPath) && !options.force) {
|
|
4430
|
+
const shouldRegenerate = await p8.confirm({
|
|
4431
|
+
message: ".github/copilot-instructions.md already exists. Regenerate? (Custom content will be preserved)",
|
|
4432
|
+
initialValue: true
|
|
4433
|
+
});
|
|
4434
|
+
if (p8.isCancel(shouldRegenerate) || !shouldRegenerate) {
|
|
4435
|
+
p8.cancel("Generation cancelled");
|
|
4436
|
+
process.exit(0);
|
|
4437
|
+
}
|
|
4438
|
+
}
|
|
4439
|
+
const spinner8 = p8.spinner();
|
|
4440
|
+
spinner8.start("Generating AI agent instructions from guidelines...");
|
|
4441
|
+
try {
|
|
4442
|
+
const result = generateCopilotInstructions(cwd, {
|
|
4443
|
+
force: true,
|
|
4444
|
+
silent: false
|
|
4445
|
+
});
|
|
4446
|
+
if (result.success) {
|
|
4447
|
+
const status = result.isNew ? "Generated" : "Regenerated";
|
|
4448
|
+
spinner8.stop(
|
|
4449
|
+
chalk12.green(
|
|
4450
|
+
`\u2713 ${status} .github/copilot-instructions.md from ${result.guidelinesCount} guidelines`
|
|
4451
|
+
)
|
|
4452
|
+
);
|
|
4453
|
+
if (result.preservedCustomContent) {
|
|
4454
|
+
console.log(chalk12.dim(" Custom content between markers was preserved."));
|
|
4455
|
+
}
|
|
4456
|
+
console.log(chalk12.dim(`
|
|
4457
|
+
Output: ${result.filePath}`));
|
|
4458
|
+
console.log(
|
|
4459
|
+
chalk12.dim(
|
|
4460
|
+
"\n \u{1F4A1} Tip: Add project-specific instructions between the CUSTOM markers."
|
|
4461
|
+
)
|
|
4462
|
+
);
|
|
4463
|
+
} else {
|
|
4464
|
+
spinner8.stop(chalk12.red("\u2717 Failed to generate instructions"));
|
|
4465
|
+
console.log(chalk12.yellow(`
|
|
4466
|
+
Reason: ${result.error}`));
|
|
4467
|
+
}
|
|
4468
|
+
} catch (error) {
|
|
4469
|
+
spinner8.stop(chalk12.red("\u2717 Error generating instructions"));
|
|
4470
|
+
console.log(
|
|
4471
|
+
chalk12.yellow(
|
|
4472
|
+
`
|
|
4473
|
+
Reason: ${error instanceof Error ? error.message : String(error)}`
|
|
4474
|
+
)
|
|
4475
|
+
);
|
|
4476
|
+
process.exit(1);
|
|
4477
|
+
}
|
|
4478
|
+
p8.outro(chalk12.green("\u2713 AI agent instructions ready!"));
|
|
4479
|
+
console.log(chalk12.dim("\nThe .github/copilot-instructions.md file:"));
|
|
4480
|
+
console.log(chalk12.dim(" - Is read by GitHub Copilot and other AI agents"));
|
|
4481
|
+
console.log(chalk12.dim(" - Summarizes all guidelines with links to full docs"));
|
|
4482
|
+
console.log(chalk12.dim(" - Includes your project scopes and conventions"));
|
|
4483
|
+
console.log(chalk12.dim(" - Preserves custom instructions you add between markers\n"));
|
|
4484
|
+
}
|
|
4485
|
+
|
|
4486
|
+
// src/cli/commands/learn.ts
|
|
4487
|
+
import chalk13 from "chalk";
|
|
4488
|
+
import * as p9 from "@clack/prompts";
|
|
4392
4489
|
import {
|
|
4393
4490
|
PatternStore as PatternStore2,
|
|
4394
4491
|
ContributorManager as ContributorManager2,
|
|
@@ -4411,10 +4508,10 @@ function formatTags(tags) {
|
|
|
4411
4508
|
async function learnRecordCommand(options) {
|
|
4412
4509
|
const cwd = getWorkspacePath();
|
|
4413
4510
|
const store = new PatternStore2(cwd);
|
|
4414
|
-
console.log(
|
|
4511
|
+
console.log(chalk13.cyan("\n\u{1F4DA} Record a Learning Pattern\n"));
|
|
4415
4512
|
let patternType = options.type;
|
|
4416
4513
|
if (!patternType) {
|
|
4417
|
-
const typeChoice = await
|
|
4514
|
+
const typeChoice = await p9.select({
|
|
4418
4515
|
message: "What type of pattern are you recording?",
|
|
4419
4516
|
options: [
|
|
4420
4517
|
{
|
|
@@ -4427,15 +4524,15 @@ async function learnRecordCommand(options) {
|
|
|
4427
4524
|
}
|
|
4428
4525
|
]
|
|
4429
4526
|
});
|
|
4430
|
-
if (
|
|
4431
|
-
|
|
4527
|
+
if (p9.isCancel(typeChoice)) {
|
|
4528
|
+
p9.cancel("Recording cancelled");
|
|
4432
4529
|
process.exit(0);
|
|
4433
4530
|
}
|
|
4434
4531
|
patternType = typeChoice;
|
|
4435
4532
|
}
|
|
4436
4533
|
let name = options.name;
|
|
4437
4534
|
if (!name) {
|
|
4438
|
-
const nameInput = await
|
|
4535
|
+
const nameInput = await p9.text({
|
|
4439
4536
|
message: "Pattern name:",
|
|
4440
4537
|
placeholder: "e.g., Next.js App Router Migration",
|
|
4441
4538
|
validate: (value) => {
|
|
@@ -4445,15 +4542,15 @@ async function learnRecordCommand(options) {
|
|
|
4445
4542
|
return void 0;
|
|
4446
4543
|
}
|
|
4447
4544
|
});
|
|
4448
|
-
if (
|
|
4449
|
-
|
|
4545
|
+
if (p9.isCancel(nameInput)) {
|
|
4546
|
+
p9.cancel("Recording cancelled");
|
|
4450
4547
|
process.exit(0);
|
|
4451
4548
|
}
|
|
4452
4549
|
name = nameInput;
|
|
4453
4550
|
}
|
|
4454
4551
|
let description = options.description;
|
|
4455
4552
|
if (!description) {
|
|
4456
|
-
const descInput = await
|
|
4553
|
+
const descInput = await p9.text({
|
|
4457
4554
|
message: "Description:",
|
|
4458
4555
|
placeholder: "What does this pattern solve?",
|
|
4459
4556
|
validate: (value) => {
|
|
@@ -4464,40 +4561,40 @@ async function learnRecordCommand(options) {
|
|
|
4464
4561
|
return void 0;
|
|
4465
4562
|
}
|
|
4466
4563
|
});
|
|
4467
|
-
if (
|
|
4468
|
-
|
|
4564
|
+
if (p9.isCancel(descInput)) {
|
|
4565
|
+
p9.cancel("Recording cancelled");
|
|
4469
4566
|
process.exit(0);
|
|
4470
4567
|
}
|
|
4471
4568
|
description = descInput;
|
|
4472
4569
|
}
|
|
4473
4570
|
let framework = options.framework;
|
|
4474
4571
|
if (!framework) {
|
|
4475
|
-
const fwInput = await
|
|
4572
|
+
const fwInput = await p9.text({
|
|
4476
4573
|
message: "Framework:",
|
|
4477
4574
|
placeholder: "e.g., next, react, vue, express"
|
|
4478
4575
|
});
|
|
4479
|
-
if (
|
|
4480
|
-
|
|
4576
|
+
if (p9.isCancel(fwInput)) {
|
|
4577
|
+
p9.cancel("Recording cancelled");
|
|
4481
4578
|
process.exit(0);
|
|
4482
4579
|
}
|
|
4483
4580
|
framework = fwInput;
|
|
4484
4581
|
}
|
|
4485
4582
|
let version = options.version;
|
|
4486
4583
|
if (!version) {
|
|
4487
|
-
const versionInput = await
|
|
4584
|
+
const versionInput = await p9.text({
|
|
4488
4585
|
message: "Framework version (semver range):",
|
|
4489
4586
|
placeholder: "e.g., >=14.0.0, ^18.0.0",
|
|
4490
4587
|
initialValue: ">=1.0.0"
|
|
4491
4588
|
});
|
|
4492
|
-
if (
|
|
4493
|
-
|
|
4589
|
+
if (p9.isCancel(versionInput)) {
|
|
4590
|
+
p9.cancel("Recording cancelled");
|
|
4494
4591
|
process.exit(0);
|
|
4495
4592
|
}
|
|
4496
4593
|
version = versionInput;
|
|
4497
4594
|
}
|
|
4498
4595
|
let category = options.category;
|
|
4499
4596
|
if (patternType === "fix" && !category) {
|
|
4500
|
-
const catChoice = await
|
|
4597
|
+
const catChoice = await p9.select({
|
|
4501
4598
|
message: "Category:",
|
|
4502
4599
|
options: [
|
|
4503
4600
|
{ value: "migration", label: "\u{1F504} Migration" },
|
|
@@ -4512,8 +4609,8 @@ async function learnRecordCommand(options) {
|
|
|
4512
4609
|
{ value: "other", label: "\u{1F4E6} Other" }
|
|
4513
4610
|
]
|
|
4514
4611
|
});
|
|
4515
|
-
if (
|
|
4516
|
-
|
|
4612
|
+
if (p9.isCancel(catChoice)) {
|
|
4613
|
+
p9.cancel("Recording cancelled");
|
|
4517
4614
|
process.exit(0);
|
|
4518
4615
|
}
|
|
4519
4616
|
category = catChoice;
|
|
@@ -4576,14 +4673,14 @@ async function learnRecordCommand(options) {
|
|
|
4576
4673
|
};
|
|
4577
4674
|
const result = await store.saveFixPattern(fixPattern);
|
|
4578
4675
|
if (result.success) {
|
|
4579
|
-
console.log(
|
|
4580
|
-
console.log(
|
|
4581
|
-
console.log(
|
|
4582
|
-
console.log(
|
|
4583
|
-
console.log(
|
|
4676
|
+
console.log(chalk13.green("\n\u2705 Fix pattern recorded successfully!\n"));
|
|
4677
|
+
console.log(chalk13.dim(` ID: ${fixPattern.id}`));
|
|
4678
|
+
console.log(chalk13.dim(` Name: ${name}`));
|
|
4679
|
+
console.log(chalk13.dim(` Category: ${category}`));
|
|
4680
|
+
console.log(chalk13.dim(` Framework: ${framework} ${version}`));
|
|
4584
4681
|
} else {
|
|
4585
|
-
console.log(
|
|
4586
|
-
console.log(
|
|
4682
|
+
console.log(chalk13.red("\n\u274C Failed to record pattern"));
|
|
4683
|
+
console.log(chalk13.dim(` Error: ${result.error}`));
|
|
4587
4684
|
process.exit(1);
|
|
4588
4685
|
}
|
|
4589
4686
|
} else {
|
|
@@ -4630,13 +4727,13 @@ async function learnRecordCommand(options) {
|
|
|
4630
4727
|
};
|
|
4631
4728
|
const result = await store.saveBlueprint(blueprint);
|
|
4632
4729
|
if (result.success) {
|
|
4633
|
-
console.log(
|
|
4634
|
-
console.log(
|
|
4635
|
-
console.log(
|
|
4636
|
-
console.log(
|
|
4730
|
+
console.log(chalk13.green("\n\u2705 Blueprint recorded successfully!\n"));
|
|
4731
|
+
console.log(chalk13.dim(` ID: ${blueprint.id}`));
|
|
4732
|
+
console.log(chalk13.dim(` Name: ${name}`));
|
|
4733
|
+
console.log(chalk13.dim(` Framework: ${framework} ${version}`));
|
|
4637
4734
|
} else {
|
|
4638
|
-
console.log(
|
|
4639
|
-
console.log(
|
|
4735
|
+
console.log(chalk13.red("\n\u274C Failed to record blueprint"));
|
|
4736
|
+
console.log(chalk13.dim(` Error: ${result.error}`));
|
|
4640
4737
|
process.exit(1);
|
|
4641
4738
|
}
|
|
4642
4739
|
}
|
|
@@ -4646,7 +4743,7 @@ async function learnListCommand(options) {
|
|
|
4646
4743
|
const store = new PatternStore2(cwd);
|
|
4647
4744
|
const patternType = options.type ?? "all";
|
|
4648
4745
|
const showDeprecated = options.deprecated ?? false;
|
|
4649
|
-
console.log(
|
|
4746
|
+
console.log(chalk13.cyan("\n\u{1F4DA} Recorded Learning Patterns\n"));
|
|
4650
4747
|
if (patternType === "all" || patternType === "fix") {
|
|
4651
4748
|
const fixResult = await store.listFixPatterns({
|
|
4652
4749
|
tags: options.tag ? [{ category: "framework", name: options.tag }] : void 0,
|
|
@@ -4654,29 +4751,29 @@ async function learnListCommand(options) {
|
|
|
4654
4751
|
includeDeprecated: showDeprecated
|
|
4655
4752
|
});
|
|
4656
4753
|
if (fixResult.success && fixResult.data && fixResult.data.length > 0) {
|
|
4657
|
-
console.log(
|
|
4754
|
+
console.log(chalk13.bold.yellow("\u{1F527} Fix Patterns:\n"));
|
|
4658
4755
|
for (const pattern of fixResult.data) {
|
|
4659
4756
|
const isDeprecated = pattern.deprecatedAt !== void 0;
|
|
4660
4757
|
const statusIcon = isDeprecated ? "\u26A0\uFE0F" : "\u2713";
|
|
4661
|
-
const nameColor = isDeprecated ?
|
|
4758
|
+
const nameColor = isDeprecated ? chalk13.dim : chalk13.white;
|
|
4662
4759
|
console.log(` ${statusIcon} ${nameColor(pattern.name)}`);
|
|
4663
|
-
console.log(
|
|
4664
|
-
console.log(
|
|
4760
|
+
console.log(chalk13.dim(` ID: ${pattern.id}`));
|
|
4761
|
+
console.log(chalk13.dim(` Category: ${pattern.category}`));
|
|
4665
4762
|
console.log(
|
|
4666
|
-
|
|
4763
|
+
chalk13.dim(` Created: ${formatDate(pattern.createdAt)}`)
|
|
4667
4764
|
);
|
|
4668
4765
|
console.log(
|
|
4669
|
-
|
|
4766
|
+
chalk13.dim(
|
|
4670
4767
|
` Success Rate: ${(pattern.metrics.successRate * 100).toFixed(0)}% (${pattern.metrics.successes}/${pattern.metrics.applications})`
|
|
4671
4768
|
)
|
|
4672
4769
|
);
|
|
4673
4770
|
if (pattern.tags.length > 0) {
|
|
4674
|
-
console.log(
|
|
4771
|
+
console.log(chalk13.dim(` Tags: ${formatTags(pattern.tags)}`));
|
|
4675
4772
|
}
|
|
4676
4773
|
console.log("");
|
|
4677
4774
|
}
|
|
4678
4775
|
} else if (patternType === "fix") {
|
|
4679
|
-
console.log(
|
|
4776
|
+
console.log(chalk13.dim(" No fix patterns found.\n"));
|
|
4680
4777
|
}
|
|
4681
4778
|
}
|
|
4682
4779
|
if (patternType === "all" || patternType === "blueprint") {
|
|
@@ -4686,46 +4783,46 @@ async function learnListCommand(options) {
|
|
|
4686
4783
|
includeDeprecated: showDeprecated
|
|
4687
4784
|
});
|
|
4688
4785
|
if (bpResult.success && bpResult.data && bpResult.data.length > 0) {
|
|
4689
|
-
console.log(
|
|
4786
|
+
console.log(chalk13.bold.blue("\u{1F4D0} Blueprints:\n"));
|
|
4690
4787
|
for (const blueprint of bpResult.data) {
|
|
4691
4788
|
const isDeprecated = blueprint.deprecatedAt !== void 0;
|
|
4692
4789
|
const statusIcon = isDeprecated ? "\u26A0\uFE0F" : "\u2713";
|
|
4693
|
-
const nameColor = isDeprecated ?
|
|
4790
|
+
const nameColor = isDeprecated ? chalk13.dim : chalk13.white;
|
|
4694
4791
|
console.log(` ${statusIcon} ${nameColor(blueprint.name)}`);
|
|
4695
|
-
console.log(
|
|
4696
|
-
console.log(
|
|
4792
|
+
console.log(chalk13.dim(` ID: ${blueprint.id}`));
|
|
4793
|
+
console.log(chalk13.dim(` Language: ${blueprint.stack.language}`));
|
|
4697
4794
|
console.log(
|
|
4698
|
-
|
|
4795
|
+
chalk13.dim(` Created: ${formatDate(blueprint.createdAt)}`)
|
|
4699
4796
|
);
|
|
4700
4797
|
console.log(
|
|
4701
|
-
|
|
4798
|
+
chalk13.dim(
|
|
4702
4799
|
` Success Rate: ${(blueprint.metrics.successRate * 100).toFixed(0)}% (${blueprint.metrics.successes}/${blueprint.metrics.applications})`
|
|
4703
4800
|
)
|
|
4704
4801
|
);
|
|
4705
4802
|
if (blueprint.tags.length > 0) {
|
|
4706
|
-
console.log(
|
|
4803
|
+
console.log(chalk13.dim(` Tags: ${formatTags(blueprint.tags)}`));
|
|
4707
4804
|
}
|
|
4708
4805
|
console.log("");
|
|
4709
4806
|
}
|
|
4710
4807
|
} else if (patternType === "blueprint") {
|
|
4711
|
-
console.log(
|
|
4808
|
+
console.log(chalk13.dim(" No blueprints found.\n"));
|
|
4712
4809
|
}
|
|
4713
4810
|
}
|
|
4714
4811
|
const stats = await store.getStats();
|
|
4715
4812
|
const totalPatterns = stats.totalFixes + stats.totalBlueprints;
|
|
4716
4813
|
const totalDeprecated = stats.deprecatedFixes + stats.deprecatedBlueprints;
|
|
4717
|
-
console.log(
|
|
4718
|
-
console.log(
|
|
4719
|
-
console.log(
|
|
4720
|
-
console.log(
|
|
4721
|
-
console.log(
|
|
4814
|
+
console.log(chalk13.dim("\u2501".repeat(40)));
|
|
4815
|
+
console.log(chalk13.dim(`Total: ${totalPatterns} patterns`));
|
|
4816
|
+
console.log(chalk13.dim(` Fix Patterns: ${stats.totalFixes}`));
|
|
4817
|
+
console.log(chalk13.dim(` Blueprints: ${stats.totalBlueprints}`));
|
|
4818
|
+
console.log(chalk13.dim(` Deprecated: ${totalDeprecated}`));
|
|
4722
4819
|
console.log("");
|
|
4723
4820
|
}
|
|
4724
4821
|
async function learnApplyCommand(patternId, options) {
|
|
4725
4822
|
const cwd = getWorkspacePath();
|
|
4726
4823
|
const store = new PatternStore2(cwd);
|
|
4727
4824
|
const telemetry = new TelemetryCollector2(cwd);
|
|
4728
|
-
console.log(
|
|
4825
|
+
console.log(chalk13.cyan("\n\u{1F527} Apply Learning Pattern\n"));
|
|
4729
4826
|
let pattern = await store.getFixPattern(patternId);
|
|
4730
4827
|
let patternType = "fix";
|
|
4731
4828
|
if (!pattern.success || !pattern.data) {
|
|
@@ -4734,21 +4831,21 @@ async function learnApplyCommand(patternId, options) {
|
|
|
4734
4831
|
pattern = bpResult;
|
|
4735
4832
|
patternType = "blueprint";
|
|
4736
4833
|
} else {
|
|
4737
|
-
console.log(
|
|
4834
|
+
console.log(chalk13.red(`
|
|
4738
4835
|
\u274C Pattern not found: ${patternId}`));
|
|
4739
4836
|
console.log(
|
|
4740
|
-
|
|
4837
|
+
chalk13.dim(" Use 'workflow learn:list' to see available patterns")
|
|
4741
4838
|
);
|
|
4742
4839
|
process.exit(1);
|
|
4743
4840
|
}
|
|
4744
4841
|
}
|
|
4745
4842
|
const patternData = pattern.data;
|
|
4746
|
-
console.log(
|
|
4747
|
-
console.log(
|
|
4748
|
-
console.log(
|
|
4843
|
+
console.log(chalk13.white(` Pattern: ${patternData.name}`));
|
|
4844
|
+
console.log(chalk13.dim(` Type: ${patternType}`));
|
|
4845
|
+
console.log(chalk13.dim(` Description: ${patternData.description}`));
|
|
4749
4846
|
if (options.dryRun) {
|
|
4750
4847
|
console.log(
|
|
4751
|
-
|
|
4848
|
+
chalk13.yellow("\n\u{1F4CB} DRY-RUN MODE: No changes will be applied\n")
|
|
4752
4849
|
);
|
|
4753
4850
|
}
|
|
4754
4851
|
const framework = options.framework ?? patternData.compatibility.frameworks[0]?.name ?? "unknown";
|
|
@@ -4756,44 +4853,44 @@ async function learnApplyCommand(patternId, options) {
|
|
|
4756
4853
|
await telemetry.recordApplication(patternId, patternType, framework, version);
|
|
4757
4854
|
if (patternType === "fix") {
|
|
4758
4855
|
const fixPattern = patternData;
|
|
4759
|
-
console.log(
|
|
4856
|
+
console.log(chalk13.cyan("\n\u{1F4CB} Solution Steps:\n"));
|
|
4760
4857
|
if (fixPattern.solution.steps) {
|
|
4761
4858
|
for (let i = 0; i < fixPattern.solution.steps.length; i++) {
|
|
4762
4859
|
const step = fixPattern.solution.steps[i];
|
|
4763
4860
|
console.log(
|
|
4764
|
-
|
|
4861
|
+
chalk13.white(` ${i + 1}. [${step.action}] ${step.description}`)
|
|
4765
4862
|
);
|
|
4766
4863
|
if (step.file) {
|
|
4767
|
-
console.log(
|
|
4864
|
+
console.log(chalk13.dim(` File: ${step.file}`));
|
|
4768
4865
|
}
|
|
4769
4866
|
}
|
|
4770
4867
|
}
|
|
4771
4868
|
} else {
|
|
4772
4869
|
const blueprint = patternData;
|
|
4773
|
-
console.log(
|
|
4870
|
+
console.log(chalk13.cyan("\n\u{1F4CB} Setup Steps:\n"));
|
|
4774
4871
|
if (blueprint.setup.steps) {
|
|
4775
4872
|
for (let i = 0; i < blueprint.setup.steps.length; i++) {
|
|
4776
4873
|
const step = blueprint.setup.steps[i];
|
|
4777
|
-
console.log(
|
|
4874
|
+
console.log(chalk13.white(` ${i + 1}. ${step.description}`));
|
|
4778
4875
|
if (step.command) {
|
|
4779
|
-
console.log(
|
|
4876
|
+
console.log(chalk13.dim(` Command: ${step.command}`));
|
|
4780
4877
|
}
|
|
4781
4878
|
}
|
|
4782
4879
|
}
|
|
4783
4880
|
}
|
|
4784
4881
|
if (!options.dryRun) {
|
|
4785
|
-
const confirmed = await
|
|
4882
|
+
const confirmed = await p9.confirm({
|
|
4786
4883
|
message: "Mark this pattern as successfully applied?",
|
|
4787
4884
|
initialValue: true
|
|
4788
4885
|
});
|
|
4789
|
-
if (
|
|
4790
|
-
|
|
4886
|
+
if (p9.isCancel(confirmed)) {
|
|
4887
|
+
p9.cancel("Application cancelled");
|
|
4791
4888
|
process.exit(0);
|
|
4792
4889
|
}
|
|
4793
4890
|
if (confirmed) {
|
|
4794
4891
|
await store.updatePatternMetrics(patternId, patternType, true);
|
|
4795
4892
|
await telemetry.recordSuccess(patternId, patternType, framework, version);
|
|
4796
|
-
console.log(
|
|
4893
|
+
console.log(chalk13.green("\n\u2705 Pattern marked as successfully applied!"));
|
|
4797
4894
|
} else {
|
|
4798
4895
|
await store.updatePatternMetrics(patternId, patternType, false);
|
|
4799
4896
|
await telemetry.recordFailure(
|
|
@@ -4804,7 +4901,7 @@ async function learnApplyCommand(patternId, options) {
|
|
|
4804
4901
|
"unknown"
|
|
4805
4902
|
);
|
|
4806
4903
|
console.log(
|
|
4807
|
-
|
|
4904
|
+
chalk13.yellow("\n\u26A0\uFE0F Pattern application marked as unsuccessful.")
|
|
4808
4905
|
);
|
|
4809
4906
|
}
|
|
4810
4907
|
}
|
|
@@ -4812,32 +4909,32 @@ async function learnApplyCommand(patternId, options) {
|
|
|
4812
4909
|
async function learnSyncCommand(options) {
|
|
4813
4910
|
const cwd = getWorkspacePath();
|
|
4814
4911
|
const contributorManager = new ContributorManager2(cwd);
|
|
4815
|
-
console.log(
|
|
4912
|
+
console.log(chalk13.cyan("\n\u{1F504} Sync Learning Patterns\n"));
|
|
4816
4913
|
const config = await contributorManager.getConfig();
|
|
4817
4914
|
if (!config.success || !config.data?.syncOptIn) {
|
|
4818
|
-
console.log(
|
|
4819
|
-
console.log(
|
|
4820
|
-
console.log(
|
|
4915
|
+
console.log(chalk13.yellow("\u26A0\uFE0F Sync is not enabled.\n"));
|
|
4916
|
+
console.log(chalk13.dim(" To enable sync, run:"));
|
|
4917
|
+
console.log(chalk13.dim(" workflow learn:config --enable-sync\n"));
|
|
4821
4918
|
console.log(
|
|
4822
|
-
|
|
4919
|
+
chalk13.dim(
|
|
4823
4920
|
" This allows you to share anonymized patterns with the community."
|
|
4824
4921
|
)
|
|
4825
4922
|
);
|
|
4826
4923
|
process.exit(0);
|
|
4827
4924
|
}
|
|
4828
4925
|
if (options.dryRun) {
|
|
4829
|
-
console.log(
|
|
4926
|
+
console.log(chalk13.yellow("\u{1F4CB} DRY-RUN MODE: No changes will be synced\n"));
|
|
4830
4927
|
}
|
|
4831
4928
|
const store = new PatternStore2(cwd);
|
|
4832
4929
|
const anonymizer = new PatternAnonymizer();
|
|
4833
4930
|
const { fixes, blueprints } = await store.getPatternsForSync();
|
|
4834
4931
|
console.log(
|
|
4835
|
-
|
|
4932
|
+
chalk13.dim(
|
|
4836
4933
|
` Patterns ready to sync: ${fixes.length} fixes, ${blueprints.length} blueprints`
|
|
4837
4934
|
)
|
|
4838
4935
|
);
|
|
4839
4936
|
if (options.push) {
|
|
4840
|
-
console.log(
|
|
4937
|
+
console.log(chalk13.cyan("\n\u{1F4E4} Pushing patterns...\n"));
|
|
4841
4938
|
let anonymizedFixes = 0;
|
|
4842
4939
|
let anonymizedBlueprints = 0;
|
|
4843
4940
|
for (const fix of fixes) {
|
|
@@ -4845,7 +4942,7 @@ async function learnSyncCommand(options) {
|
|
|
4845
4942
|
if (result.success) {
|
|
4846
4943
|
anonymizedFixes++;
|
|
4847
4944
|
if (!options.dryRun) {
|
|
4848
|
-
console.log(
|
|
4945
|
+
console.log(chalk13.dim(` \u2713 Anonymized: ${fix.name}`));
|
|
4849
4946
|
}
|
|
4850
4947
|
}
|
|
4851
4948
|
}
|
|
@@ -4854,117 +4951,117 @@ async function learnSyncCommand(options) {
|
|
|
4854
4951
|
if (result.success) {
|
|
4855
4952
|
anonymizedBlueprints++;
|
|
4856
4953
|
if (!options.dryRun) {
|
|
4857
|
-
console.log(
|
|
4954
|
+
console.log(chalk13.dim(` \u2713 Anonymized: ${bp.name}`));
|
|
4858
4955
|
}
|
|
4859
4956
|
}
|
|
4860
4957
|
}
|
|
4861
4958
|
console.log(
|
|
4862
|
-
|
|
4959
|
+
chalk13.green(
|
|
4863
4960
|
`
|
|
4864
4961
|
\u2705 Ready to push ${anonymizedFixes} fixes and ${anonymizedBlueprints} blueprints`
|
|
4865
4962
|
)
|
|
4866
4963
|
);
|
|
4867
|
-
console.log(
|
|
4964
|
+
console.log(chalk13.dim(" (Registry push not yet implemented)"));
|
|
4868
4965
|
}
|
|
4869
4966
|
if (options.pull) {
|
|
4870
|
-
console.log(
|
|
4871
|
-
console.log(
|
|
4967
|
+
console.log(chalk13.cyan("\n\u{1F4E5} Pulling patterns from registry...\n"));
|
|
4968
|
+
console.log(chalk13.dim(" (Registry pull not yet implemented)"));
|
|
4872
4969
|
}
|
|
4873
4970
|
if (!options.push && !options.pull) {
|
|
4874
4971
|
console.log(
|
|
4875
|
-
|
|
4972
|
+
chalk13.dim(" Specify --push to upload or --pull to download patterns.\n")
|
|
4876
4973
|
);
|
|
4877
4974
|
}
|
|
4878
4975
|
}
|
|
4879
4976
|
async function learnConfigCommand(options) {
|
|
4880
4977
|
const cwd = getWorkspacePath();
|
|
4881
4978
|
const contributorManager = new ContributorManager2(cwd);
|
|
4882
|
-
console.log(
|
|
4979
|
+
console.log(chalk13.cyan("\n\u2699\uFE0F Learning Configuration\n"));
|
|
4883
4980
|
if (options.enableSync) {
|
|
4884
4981
|
const result = await contributorManager.enableSync();
|
|
4885
4982
|
if (result.success) {
|
|
4886
|
-
console.log(
|
|
4983
|
+
console.log(chalk13.green("\u2705 Sync enabled"));
|
|
4887
4984
|
console.log(
|
|
4888
|
-
|
|
4985
|
+
chalk13.dim(" Your patterns will be anonymized before sharing.")
|
|
4889
4986
|
);
|
|
4890
4987
|
} else {
|
|
4891
|
-
console.log(
|
|
4988
|
+
console.log(chalk13.red(`\u274C Failed: ${result.error}`));
|
|
4892
4989
|
}
|
|
4893
4990
|
return;
|
|
4894
4991
|
}
|
|
4895
4992
|
if (options.disableSync) {
|
|
4896
4993
|
const result = await contributorManager.disableSync();
|
|
4897
4994
|
if (result.success) {
|
|
4898
|
-
console.log(
|
|
4995
|
+
console.log(chalk13.green("\u2705 Sync disabled"));
|
|
4899
4996
|
} else {
|
|
4900
|
-
console.log(
|
|
4997
|
+
console.log(chalk13.red(`\u274C Failed: ${result.error}`));
|
|
4901
4998
|
}
|
|
4902
4999
|
return;
|
|
4903
5000
|
}
|
|
4904
5001
|
if (options.enableTelemetry) {
|
|
4905
5002
|
const result = await contributorManager.enableTelemetry();
|
|
4906
5003
|
if (result.success) {
|
|
4907
|
-
console.log(
|
|
5004
|
+
console.log(chalk13.green("\u2705 Telemetry enabled"));
|
|
4908
5005
|
console.log(
|
|
4909
|
-
|
|
5006
|
+
chalk13.dim(
|
|
4910
5007
|
" Anonymous usage data helps improve pattern recommendations."
|
|
4911
5008
|
)
|
|
4912
5009
|
);
|
|
4913
5010
|
} else {
|
|
4914
|
-
console.log(
|
|
5011
|
+
console.log(chalk13.red(`\u274C Failed: ${result.error}`));
|
|
4915
5012
|
}
|
|
4916
5013
|
return;
|
|
4917
5014
|
}
|
|
4918
5015
|
if (options.disableTelemetry) {
|
|
4919
5016
|
const result = await contributorManager.disableTelemetry();
|
|
4920
5017
|
if (result.success) {
|
|
4921
|
-
console.log(
|
|
5018
|
+
console.log(chalk13.green("\u2705 Telemetry disabled"));
|
|
4922
5019
|
} else {
|
|
4923
|
-
console.log(
|
|
5020
|
+
console.log(chalk13.red(`\u274C Failed: ${result.error}`));
|
|
4924
5021
|
}
|
|
4925
5022
|
return;
|
|
4926
5023
|
}
|
|
4927
5024
|
if (options.resetId) {
|
|
4928
|
-
const confirmed = await
|
|
5025
|
+
const confirmed = await p9.confirm({
|
|
4929
5026
|
message: "Are you sure you want to reset your contributor ID? This cannot be undone.",
|
|
4930
5027
|
initialValue: false
|
|
4931
5028
|
});
|
|
4932
|
-
if (
|
|
4933
|
-
|
|
5029
|
+
if (p9.isCancel(confirmed) || !confirmed) {
|
|
5030
|
+
p9.cancel("Reset cancelled");
|
|
4934
5031
|
return;
|
|
4935
5032
|
}
|
|
4936
5033
|
const result = await contributorManager.resetId();
|
|
4937
5034
|
if (result.success) {
|
|
4938
|
-
console.log(
|
|
4939
|
-
console.log(
|
|
5035
|
+
console.log(chalk13.green("\u2705 Contributor ID reset"));
|
|
5036
|
+
console.log(chalk13.dim(` New ID: ${result.data?.id}`));
|
|
4940
5037
|
} else {
|
|
4941
|
-
console.log(
|
|
5038
|
+
console.log(chalk13.red(`\u274C Failed: ${result.error}`));
|
|
4942
5039
|
}
|
|
4943
5040
|
return;
|
|
4944
5041
|
}
|
|
4945
5042
|
const config = await contributorManager.getConfig();
|
|
4946
5043
|
if (config.success && config.data) {
|
|
4947
|
-
console.log(
|
|
4948
|
-
console.log(
|
|
4949
|
-
console.log(
|
|
5044
|
+
console.log(chalk13.white(" Current Settings:\n"));
|
|
5045
|
+
console.log(chalk13.dim(` Contributor ID: ${config.data.id}`));
|
|
5046
|
+
console.log(chalk13.dim(` Created: ${formatDate(config.data.createdAt)}`));
|
|
4950
5047
|
console.log(
|
|
4951
|
-
|
|
5048
|
+
chalk13.dim(` Sync Enabled: ${config.data.syncOptIn ? "Yes" : "No"}`)
|
|
4952
5049
|
);
|
|
4953
5050
|
console.log(
|
|
4954
|
-
|
|
5051
|
+
chalk13.dim(
|
|
4955
5052
|
` Telemetry Enabled: ${config.data.telemetryEnabled ? "Yes" : "No"}`
|
|
4956
5053
|
)
|
|
4957
5054
|
);
|
|
4958
5055
|
if (config.data.syncEnabledAt) {
|
|
4959
5056
|
console.log(
|
|
4960
|
-
|
|
5057
|
+
chalk13.dim(
|
|
4961
5058
|
` Sync Enabled At: ${formatDate(config.data.syncEnabledAt)}`
|
|
4962
5059
|
)
|
|
4963
5060
|
);
|
|
4964
5061
|
}
|
|
4965
5062
|
} else {
|
|
4966
5063
|
console.log(
|
|
4967
|
-
|
|
5064
|
+
chalk13.dim(
|
|
4968
5065
|
" No configuration found. Settings will be created on first use.\n"
|
|
4969
5066
|
)
|
|
4970
5067
|
);
|
|
@@ -4973,7 +5070,7 @@ async function learnConfigCommand(options) {
|
|
|
4973
5070
|
async function learnDeprecateCommand(patternId, reason) {
|
|
4974
5071
|
const cwd = getWorkspacePath();
|
|
4975
5072
|
const store = new PatternStore2(cwd);
|
|
4976
|
-
console.log(
|
|
5073
|
+
console.log(chalk13.cyan("\n\u26A0\uFE0F Deprecate Pattern\n"));
|
|
4977
5074
|
let patternType = "fix";
|
|
4978
5075
|
let pattern = await store.getFixPattern(patternId);
|
|
4979
5076
|
if (!pattern.success || !pattern.data) {
|
|
@@ -4982,26 +5079,26 @@ async function learnDeprecateCommand(patternId, reason) {
|
|
|
4982
5079
|
pattern = bpResult;
|
|
4983
5080
|
patternType = "blueprint";
|
|
4984
5081
|
} else {
|
|
4985
|
-
console.log(
|
|
5082
|
+
console.log(chalk13.red(`
|
|
4986
5083
|
\u274C Pattern not found: ${patternId}`));
|
|
4987
5084
|
process.exit(1);
|
|
4988
5085
|
}
|
|
4989
5086
|
}
|
|
4990
|
-
console.log(
|
|
4991
|
-
console.log(
|
|
4992
|
-
const confirmed = await
|
|
5087
|
+
console.log(chalk13.white(` Pattern: ${pattern.data.name}`));
|
|
5088
|
+
console.log(chalk13.dim(` Reason: ${reason}`));
|
|
5089
|
+
const confirmed = await p9.confirm({
|
|
4993
5090
|
message: "Are you sure you want to deprecate this pattern?",
|
|
4994
5091
|
initialValue: false
|
|
4995
5092
|
});
|
|
4996
|
-
if (
|
|
4997
|
-
|
|
5093
|
+
if (p9.isCancel(confirmed) || !confirmed) {
|
|
5094
|
+
p9.cancel("Deprecation cancelled");
|
|
4998
5095
|
return;
|
|
4999
5096
|
}
|
|
5000
5097
|
const result = await store.deprecatePattern(patternId, patternType, reason);
|
|
5001
5098
|
if (result.success) {
|
|
5002
|
-
console.log(
|
|
5099
|
+
console.log(chalk13.green("\n\u2705 Pattern deprecated successfully"));
|
|
5003
5100
|
} else {
|
|
5004
|
-
console.log(
|
|
5101
|
+
console.log(chalk13.red(`
|
|
5005
5102
|
\u274C Failed: ${result.error}`));
|
|
5006
5103
|
process.exit(1);
|
|
5007
5104
|
}
|
|
@@ -5010,32 +5107,32 @@ async function learnStatsCommand() {
|
|
|
5010
5107
|
const cwd = getWorkspacePath();
|
|
5011
5108
|
const store = new PatternStore2(cwd);
|
|
5012
5109
|
const telemetry = new TelemetryCollector2(cwd);
|
|
5013
|
-
console.log(
|
|
5110
|
+
console.log(chalk13.cyan("\n\u{1F4CA} Learning Statistics\n"));
|
|
5014
5111
|
const storeStats = await store.getStats();
|
|
5015
5112
|
const totalPatterns = storeStats.totalFixes + storeStats.totalBlueprints;
|
|
5016
5113
|
const totalDeprecated = storeStats.deprecatedFixes + storeStats.deprecatedBlueprints;
|
|
5017
|
-
console.log(
|
|
5018
|
-
console.log(
|
|
5019
|
-
console.log(
|
|
5020
|
-
console.log(
|
|
5021
|
-
console.log(
|
|
5114
|
+
console.log(chalk13.bold.white(" Patterns:\n"));
|
|
5115
|
+
console.log(chalk13.dim(` Total: ${totalPatterns}`));
|
|
5116
|
+
console.log(chalk13.dim(` Fix Patterns: ${storeStats.totalFixes}`));
|
|
5117
|
+
console.log(chalk13.dim(` Blueprints: ${storeStats.totalBlueprints}`));
|
|
5118
|
+
console.log(chalk13.dim(` Deprecated: ${totalDeprecated}`));
|
|
5022
5119
|
const telemetryStats = await telemetry.getStats();
|
|
5023
|
-
console.log(
|
|
5024
|
-
console.log(
|
|
5120
|
+
console.log(chalk13.bold.white("\n Telemetry:\n"));
|
|
5121
|
+
console.log(chalk13.dim(` Pending Events: ${telemetryStats.pendingEvents}`));
|
|
5025
5122
|
console.log(
|
|
5026
|
-
|
|
5123
|
+
chalk13.dim(` Total Events Sent: ${telemetryStats.totalEventsSent}`)
|
|
5027
5124
|
);
|
|
5028
5125
|
if (telemetryStats.lastFlushAt) {
|
|
5029
5126
|
console.log(
|
|
5030
|
-
|
|
5127
|
+
chalk13.dim(` Last Flush: ${formatDate(telemetryStats.lastFlushAt)}`)
|
|
5031
5128
|
);
|
|
5032
5129
|
}
|
|
5033
5130
|
console.log("");
|
|
5034
5131
|
}
|
|
5035
5132
|
|
|
5036
5133
|
// src/cli/commands/solution.ts
|
|
5037
|
-
import
|
|
5038
|
-
import * as
|
|
5134
|
+
import chalk14 from "chalk";
|
|
5135
|
+
import * as p10 from "@clack/prompts";
|
|
5039
5136
|
import * as path2 from "path";
|
|
5040
5137
|
import {
|
|
5041
5138
|
PatternStore as PatternStore3,
|
|
@@ -5077,10 +5174,10 @@ function truncate(str, maxLen) {
|
|
|
5077
5174
|
async function solutionCaptureCommand(options) {
|
|
5078
5175
|
const cwd = getWorkspacePath2();
|
|
5079
5176
|
const store = new PatternStore3(cwd);
|
|
5080
|
-
console.log(
|
|
5177
|
+
console.log(chalk14.cyan("\n\u{1F4E6} Capture Solution Pattern\n"));
|
|
5081
5178
|
let targetPath = options.path;
|
|
5082
5179
|
if (!targetPath) {
|
|
5083
|
-
const pathInput = await
|
|
5180
|
+
const pathInput = await p10.text({
|
|
5084
5181
|
message: "Path to the solution directory:",
|
|
5085
5182
|
placeholder: "./src/auth",
|
|
5086
5183
|
validate: (val) => {
|
|
@@ -5088,8 +5185,8 @@ async function solutionCaptureCommand(options) {
|
|
|
5088
5185
|
return void 0;
|
|
5089
5186
|
}
|
|
5090
5187
|
});
|
|
5091
|
-
if (
|
|
5092
|
-
|
|
5188
|
+
if (p10.isCancel(pathInput)) {
|
|
5189
|
+
p10.cancel("Operation cancelled");
|
|
5093
5190
|
process.exit(0);
|
|
5094
5191
|
}
|
|
5095
5192
|
targetPath = pathInput;
|
|
@@ -5097,7 +5194,7 @@ async function solutionCaptureCommand(options) {
|
|
|
5097
5194
|
const absolutePath = path2.isAbsolute(targetPath) ? targetPath : path2.resolve(cwd, targetPath);
|
|
5098
5195
|
let name = options.name;
|
|
5099
5196
|
if (!name) {
|
|
5100
|
-
const nameInput = await
|
|
5197
|
+
const nameInput = await p10.text({
|
|
5101
5198
|
message: "Solution name:",
|
|
5102
5199
|
placeholder: "JWT Authentication",
|
|
5103
5200
|
validate: (val) => {
|
|
@@ -5105,15 +5202,15 @@ async function solutionCaptureCommand(options) {
|
|
|
5105
5202
|
return void 0;
|
|
5106
5203
|
}
|
|
5107
5204
|
});
|
|
5108
|
-
if (
|
|
5109
|
-
|
|
5205
|
+
if (p10.isCancel(nameInput)) {
|
|
5206
|
+
p10.cancel("Operation cancelled");
|
|
5110
5207
|
process.exit(0);
|
|
5111
5208
|
}
|
|
5112
5209
|
name = nameInput;
|
|
5113
5210
|
}
|
|
5114
5211
|
let description = options.description;
|
|
5115
5212
|
if (!description) {
|
|
5116
|
-
const descInput = await
|
|
5213
|
+
const descInput = await p10.text({
|
|
5117
5214
|
message: "Solution description:",
|
|
5118
5215
|
placeholder: "Complete JWT-based authentication with refresh tokens",
|
|
5119
5216
|
validate: (val) => {
|
|
@@ -5122,15 +5219,15 @@ async function solutionCaptureCommand(options) {
|
|
|
5122
5219
|
return void 0;
|
|
5123
5220
|
}
|
|
5124
5221
|
});
|
|
5125
|
-
if (
|
|
5126
|
-
|
|
5222
|
+
if (p10.isCancel(descInput)) {
|
|
5223
|
+
p10.cancel("Operation cancelled");
|
|
5127
5224
|
process.exit(0);
|
|
5128
5225
|
}
|
|
5129
5226
|
description = descInput;
|
|
5130
5227
|
}
|
|
5131
5228
|
let category = options.category;
|
|
5132
5229
|
if (!category) {
|
|
5133
|
-
const categoryChoice = await
|
|
5230
|
+
const categoryChoice = await p10.select({
|
|
5134
5231
|
message: "Solution category:",
|
|
5135
5232
|
options: [
|
|
5136
5233
|
{ value: "auth", label: "\u{1F510} Authentication" },
|
|
@@ -5149,8 +5246,8 @@ async function solutionCaptureCommand(options) {
|
|
|
5149
5246
|
{ value: "other", label: "\u{1F4E6} Other" }
|
|
5150
5247
|
]
|
|
5151
5248
|
});
|
|
5152
|
-
if (
|
|
5153
|
-
|
|
5249
|
+
if (p10.isCancel(categoryChoice)) {
|
|
5250
|
+
p10.cancel("Operation cancelled");
|
|
5154
5251
|
process.exit(0);
|
|
5155
5252
|
}
|
|
5156
5253
|
category = categoryChoice;
|
|
@@ -5159,20 +5256,20 @@ async function solutionCaptureCommand(options) {
|
|
|
5159
5256
|
if (options.keywords) {
|
|
5160
5257
|
keywords = options.keywords.split(",").map((k) => k.trim());
|
|
5161
5258
|
} else {
|
|
5162
|
-
const keywordsInput = await
|
|
5259
|
+
const keywordsInput = await p10.text({
|
|
5163
5260
|
message: "Keywords (comma-separated):",
|
|
5164
5261
|
placeholder: "jwt, authentication, login, refresh-token"
|
|
5165
5262
|
});
|
|
5166
|
-
if (
|
|
5167
|
-
|
|
5263
|
+
if (p10.isCancel(keywordsInput)) {
|
|
5264
|
+
p10.cancel("Operation cancelled");
|
|
5168
5265
|
process.exit(0);
|
|
5169
5266
|
}
|
|
5170
5267
|
if (keywordsInput) {
|
|
5171
5268
|
keywords = keywordsInput.split(",").map((k) => k.trim());
|
|
5172
5269
|
}
|
|
5173
5270
|
}
|
|
5174
|
-
const
|
|
5175
|
-
|
|
5271
|
+
const spinner8 = p10.spinner();
|
|
5272
|
+
spinner8.start("Analyzing solution...");
|
|
5176
5273
|
const analyzer = new CodeAnalyzer({
|
|
5177
5274
|
anonymize: options.anonymize ?? false
|
|
5178
5275
|
});
|
|
@@ -5184,38 +5281,38 @@ async function solutionCaptureCommand(options) {
|
|
|
5184
5281
|
category,
|
|
5185
5282
|
keywords
|
|
5186
5283
|
);
|
|
5187
|
-
|
|
5188
|
-
console.log(
|
|
5189
|
-
console.log(
|
|
5190
|
-
console.log(`${
|
|
5284
|
+
spinner8.stop("Solution analyzed");
|
|
5285
|
+
console.log(chalk14.green("\n\u2713 Solution captured successfully!\n"));
|
|
5286
|
+
console.log(chalk14.dim("\u2500".repeat(50)));
|
|
5287
|
+
console.log(`${chalk14.bold("Name:")} ${pattern.name}`);
|
|
5191
5288
|
console.log(
|
|
5192
|
-
`${
|
|
5289
|
+
`${chalk14.bold("Category:")} ${formatCategory(pattern.category)}`
|
|
5193
5290
|
);
|
|
5194
5291
|
console.log(
|
|
5195
|
-
`${
|
|
5292
|
+
`${chalk14.bold("Files:")} ${pattern.implementation.files.length}`
|
|
5196
5293
|
);
|
|
5197
5294
|
console.log(
|
|
5198
|
-
`${
|
|
5295
|
+
`${chalk14.bold("Dependencies:")} ${pattern.implementation.dependencies.length}`
|
|
5199
5296
|
);
|
|
5200
5297
|
console.log(
|
|
5201
|
-
`${
|
|
5298
|
+
`${chalk14.bold("Framework:")} ${pattern.compatibility.framework || "generic"}`
|
|
5202
5299
|
);
|
|
5203
|
-
console.log(
|
|
5204
|
-
const
|
|
5300
|
+
console.log(chalk14.dim("\u2500".repeat(50)));
|
|
5301
|
+
const confirm9 = await p10.confirm({
|
|
5205
5302
|
message: "Save this solution pattern?",
|
|
5206
5303
|
initialValue: true
|
|
5207
5304
|
});
|
|
5208
|
-
if (
|
|
5209
|
-
|
|
5305
|
+
if (p10.isCancel(confirm9) || !confirm9) {
|
|
5306
|
+
p10.cancel("Solution not saved");
|
|
5210
5307
|
process.exit(0);
|
|
5211
5308
|
}
|
|
5212
5309
|
await store.saveSolution(pattern);
|
|
5213
|
-
console.log(
|
|
5310
|
+
console.log(chalk14.green(`
|
|
5214
5311
|
\u2713 Solution saved with ID: ${pattern.id}
|
|
5215
5312
|
`));
|
|
5216
5313
|
} catch (error) {
|
|
5217
|
-
|
|
5218
|
-
console.error(
|
|
5314
|
+
spinner8.stop("Analysis failed");
|
|
5315
|
+
console.error(chalk14.red(`
|
|
5219
5316
|
\u2717 Error: ${error.message}
|
|
5220
5317
|
`));
|
|
5221
5318
|
process.exit(1);
|
|
@@ -5224,7 +5321,7 @@ async function solutionCaptureCommand(options) {
|
|
|
5224
5321
|
async function solutionSearchCommand(query, options) {
|
|
5225
5322
|
const cwd = getWorkspacePath2();
|
|
5226
5323
|
const store = new PatternStore3(cwd);
|
|
5227
|
-
console.log(
|
|
5324
|
+
console.log(chalk14.cyan("\n\u{1F50D} Search Solution Patterns\n"));
|
|
5228
5325
|
const keywords = query.split(/\s+/).filter((k) => k.length > 0);
|
|
5229
5326
|
const result = await store.searchSolutions(keywords, {
|
|
5230
5327
|
category: options.category,
|
|
@@ -5232,39 +5329,39 @@ async function solutionSearchCommand(query, options) {
|
|
|
5232
5329
|
limit: options.limit ?? 10
|
|
5233
5330
|
});
|
|
5234
5331
|
if (!result.success || !result.data) {
|
|
5235
|
-
console.error(
|
|
5332
|
+
console.error(chalk14.red(`
|
|
5236
5333
|
\u2717 Search failed: ${result.error}
|
|
5237
5334
|
`));
|
|
5238
5335
|
return;
|
|
5239
5336
|
}
|
|
5240
5337
|
const solutions = result.data;
|
|
5241
5338
|
if (solutions.length === 0) {
|
|
5242
|
-
console.log(
|
|
5243
|
-
console.log(
|
|
5339
|
+
console.log(chalk14.yellow("No solutions found matching your query.\n"));
|
|
5340
|
+
console.log(chalk14.dim("Try different keywords or fewer filters."));
|
|
5244
5341
|
return;
|
|
5245
5342
|
}
|
|
5246
|
-
console.log(
|
|
5343
|
+
console.log(chalk14.green(`Found ${solutions.length} solution(s):
|
|
5247
5344
|
`));
|
|
5248
|
-
console.log(
|
|
5345
|
+
console.log(chalk14.dim("\u2500".repeat(70)));
|
|
5249
5346
|
for (const solution of solutions) {
|
|
5250
5347
|
console.log(
|
|
5251
|
-
`${
|
|
5348
|
+
`${chalk14.bold(solution.name)} ${chalk14.dim(`(${solution.id.slice(0, 8)})`)}`
|
|
5252
5349
|
);
|
|
5253
5350
|
console.log(` ${formatCategory(solution.category)}`);
|
|
5254
|
-
console.log(` ${
|
|
5351
|
+
console.log(` ${chalk14.dim(truncate(solution.description, 60))}`);
|
|
5255
5352
|
console.log(
|
|
5256
5353
|
` Files: ${solution.implementation.files.length} | Framework: ${solution.compatibility.framework || "generic"} | Uses: ${solution.metrics.applications}`
|
|
5257
5354
|
);
|
|
5258
|
-
console.log(
|
|
5355
|
+
console.log(chalk14.dim("\u2500".repeat(70)));
|
|
5259
5356
|
}
|
|
5260
5357
|
console.log(
|
|
5261
|
-
|
|
5358
|
+
chalk14.dim("\nUse 'workflow solution:apply <id>' to apply a solution.")
|
|
5262
5359
|
);
|
|
5263
5360
|
}
|
|
5264
5361
|
async function solutionListCommand(options) {
|
|
5265
5362
|
const cwd = getWorkspacePath2();
|
|
5266
5363
|
const store = new PatternStore3(cwd);
|
|
5267
|
-
console.log(
|
|
5364
|
+
console.log(chalk14.cyan("\n\u{1F4CB} Solution Patterns\n"));
|
|
5268
5365
|
const result = await store.listSolutions({
|
|
5269
5366
|
category: options.category,
|
|
5270
5367
|
framework: options.framework,
|
|
@@ -5272,20 +5369,20 @@ async function solutionListCommand(options) {
|
|
|
5272
5369
|
limit: options.limit ?? 20
|
|
5273
5370
|
});
|
|
5274
5371
|
if (!result.success || !result.data) {
|
|
5275
|
-
console.error(
|
|
5372
|
+
console.error(chalk14.red(`
|
|
5276
5373
|
\u2717 List failed: ${result.error}
|
|
5277
5374
|
`));
|
|
5278
5375
|
return;
|
|
5279
5376
|
}
|
|
5280
5377
|
const solutions = result.data;
|
|
5281
5378
|
if (solutions.length === 0) {
|
|
5282
|
-
console.log(
|
|
5379
|
+
console.log(chalk14.yellow("No solutions found.\n"));
|
|
5283
5380
|
console.log(
|
|
5284
|
-
|
|
5381
|
+
chalk14.dim("Use 'workflow solution:capture' to capture a solution.")
|
|
5285
5382
|
);
|
|
5286
5383
|
return;
|
|
5287
5384
|
}
|
|
5288
|
-
console.log(
|
|
5385
|
+
console.log(chalk14.green(`${solutions.length} solution(s):
|
|
5289
5386
|
`));
|
|
5290
5387
|
const byCategory = /* @__PURE__ */ new Map();
|
|
5291
5388
|
for (const solution of solutions) {
|
|
@@ -5294,24 +5391,24 @@ async function solutionListCommand(options) {
|
|
|
5294
5391
|
byCategory.set(solution.category, list);
|
|
5295
5392
|
}
|
|
5296
5393
|
for (const [category, items] of byCategory) {
|
|
5297
|
-
console.log(
|
|
5394
|
+
console.log(chalk14.bold(`
|
|
5298
5395
|
${formatCategory(category)}`));
|
|
5299
|
-
console.log(
|
|
5396
|
+
console.log(chalk14.dim("\u2500".repeat(50)));
|
|
5300
5397
|
for (const solution of items) {
|
|
5301
|
-
const deprecated = solution.deprecatedAt ?
|
|
5398
|
+
const deprecated = solution.deprecatedAt ? chalk14.red(" [DEPRECATED]") : "";
|
|
5302
5399
|
console.log(
|
|
5303
|
-
` ${
|
|
5400
|
+
` ${chalk14.cyan(solution.id.slice(0, 8))} ${solution.name}${deprecated}`
|
|
5304
5401
|
);
|
|
5305
|
-
console.log(` ${
|
|
5402
|
+
console.log(` ${chalk14.dim(truncate(solution.description, 50))}`);
|
|
5306
5403
|
console.log(
|
|
5307
|
-
|
|
5404
|
+
chalk14.dim(
|
|
5308
5405
|
` Created: ${formatDate2(solution.createdAt)} | Files: ${solution.implementation.files.length}`
|
|
5309
5406
|
)
|
|
5310
5407
|
);
|
|
5311
5408
|
}
|
|
5312
5409
|
}
|
|
5313
5410
|
console.log(
|
|
5314
|
-
|
|
5411
|
+
chalk14.dim(
|
|
5315
5412
|
"\nUse 'workflow solution:search <query>' to find specific solutions."
|
|
5316
5413
|
)
|
|
5317
5414
|
);
|
|
@@ -5319,10 +5416,10 @@ ${formatCategory(category)}`));
|
|
|
5319
5416
|
async function solutionApplyCommand(solutionId, options) {
|
|
5320
5417
|
const cwd = getWorkspacePath2();
|
|
5321
5418
|
const store = new PatternStore3(cwd);
|
|
5322
|
-
console.log(
|
|
5419
|
+
console.log(chalk14.cyan("\n\u{1F680} Apply Solution Pattern\n"));
|
|
5323
5420
|
const result = await store.getSolution(solutionId);
|
|
5324
5421
|
if (!result.success || !result.data) {
|
|
5325
|
-
console.error(
|
|
5422
|
+
console.error(chalk14.red(`
|
|
5326
5423
|
\u2717 Solution not found: ${solutionId}
|
|
5327
5424
|
`));
|
|
5328
5425
|
process.exit(1);
|
|
@@ -5330,60 +5427,60 @@ async function solutionApplyCommand(solutionId, options) {
|
|
|
5330
5427
|
const solution = result.data;
|
|
5331
5428
|
if (solution.deprecatedAt) {
|
|
5332
5429
|
console.log(
|
|
5333
|
-
|
|
5430
|
+
chalk14.yellow(
|
|
5334
5431
|
`\u26A0\uFE0F This solution is deprecated: ${solution.deprecationReason || "No reason provided"}
|
|
5335
5432
|
`
|
|
5336
5433
|
)
|
|
5337
5434
|
);
|
|
5338
|
-
const proceed = await
|
|
5435
|
+
const proceed = await p10.confirm({
|
|
5339
5436
|
message: "Do you want to continue?",
|
|
5340
5437
|
initialValue: false
|
|
5341
5438
|
});
|
|
5342
|
-
if (
|
|
5343
|
-
|
|
5439
|
+
if (p10.isCancel(proceed) || !proceed) {
|
|
5440
|
+
p10.cancel("Operation cancelled");
|
|
5344
5441
|
process.exit(0);
|
|
5345
5442
|
}
|
|
5346
5443
|
}
|
|
5347
|
-
console.log(
|
|
5348
|
-
console.log(
|
|
5444
|
+
console.log(chalk14.bold(`Solution: ${solution.name}`));
|
|
5445
|
+
console.log(chalk14.dim(solution.description));
|
|
5349
5446
|
console.log();
|
|
5350
|
-
console.log(
|
|
5447
|
+
console.log(chalk14.bold("Files to create:"));
|
|
5351
5448
|
const filesToApply = options.includeTests ? solution.implementation.files : solution.implementation.files.filter(
|
|
5352
5449
|
(f) => f.role !== "test"
|
|
5353
5450
|
);
|
|
5354
5451
|
for (const file of filesToApply) {
|
|
5355
|
-
console.log(
|
|
5452
|
+
console.log(chalk14.dim(` \u2022 ${file.path} (${file.role})`));
|
|
5356
5453
|
}
|
|
5357
5454
|
console.log();
|
|
5358
5455
|
if (solution.implementation.dependencies.length > 0) {
|
|
5359
|
-
console.log(
|
|
5456
|
+
console.log(chalk14.bold("Dependencies to install:"));
|
|
5360
5457
|
for (const dep of solution.implementation.dependencies) {
|
|
5361
|
-
console.log(
|
|
5458
|
+
console.log(chalk14.dim(` \u2022 ${dep.name}@${dep.version}`));
|
|
5362
5459
|
}
|
|
5363
5460
|
console.log();
|
|
5364
5461
|
}
|
|
5365
5462
|
if (solution.implementation.envVars.length > 0) {
|
|
5366
|
-
console.log(
|
|
5463
|
+
console.log(chalk14.bold("Environment variables needed:"));
|
|
5367
5464
|
for (const env of solution.implementation.envVars) {
|
|
5368
|
-
const required = env.required ?
|
|
5369
|
-
console.log(
|
|
5465
|
+
const required = env.required ? chalk14.red("*") : "";
|
|
5466
|
+
console.log(chalk14.dim(` \u2022 ${env.name}${required}`));
|
|
5370
5467
|
}
|
|
5371
5468
|
console.log();
|
|
5372
5469
|
}
|
|
5373
5470
|
if (options.dryRun) {
|
|
5374
|
-
console.log(
|
|
5471
|
+
console.log(chalk14.yellow("Dry run mode - no files were created.\n"));
|
|
5375
5472
|
return;
|
|
5376
5473
|
}
|
|
5377
|
-
const
|
|
5474
|
+
const confirm9 = await p10.confirm({
|
|
5378
5475
|
message: "Apply this solution?",
|
|
5379
5476
|
initialValue: true
|
|
5380
5477
|
});
|
|
5381
|
-
if (
|
|
5382
|
-
|
|
5478
|
+
if (p10.isCancel(confirm9) || !confirm9) {
|
|
5479
|
+
p10.cancel("Operation cancelled");
|
|
5383
5480
|
process.exit(0);
|
|
5384
5481
|
}
|
|
5385
|
-
const
|
|
5386
|
-
|
|
5482
|
+
const spinner8 = p10.spinner();
|
|
5483
|
+
spinner8.start("Applying solution...");
|
|
5387
5484
|
try {
|
|
5388
5485
|
const outputDir = options.output || cwd;
|
|
5389
5486
|
const fs2 = await import("fs");
|
|
@@ -5395,20 +5492,20 @@ async function solutionApplyCommand(solutionId, options) {
|
|
|
5395
5492
|
await fs2.promises.writeFile(filePath, file.content);
|
|
5396
5493
|
}
|
|
5397
5494
|
await store.updateSolutionMetrics(solution.id, true);
|
|
5398
|
-
|
|
5399
|
-
console.log(
|
|
5495
|
+
spinner8.stop("Solution applied");
|
|
5496
|
+
console.log(chalk14.green(`
|
|
5400
5497
|
\u2713 Solution applied successfully!
|
|
5401
5498
|
`));
|
|
5402
|
-
console.log(
|
|
5499
|
+
console.log(chalk14.dim(`Created ${filesToApply.length} file(s).`));
|
|
5403
5500
|
if (solution.implementation.dependencies.length > 0) {
|
|
5404
|
-
console.log(
|
|
5501
|
+
console.log(chalk14.cyan("\nNext step: Install dependencies with:"));
|
|
5405
5502
|
const deps = solution.implementation.dependencies.map((d) => `${d.name}@${d.version}`).join(" ");
|
|
5406
|
-
console.log(
|
|
5503
|
+
console.log(chalk14.dim(` npm install ${deps}`));
|
|
5407
5504
|
}
|
|
5408
5505
|
} catch (error) {
|
|
5409
|
-
|
|
5506
|
+
spinner8.stop("Application failed");
|
|
5410
5507
|
await store.updateSolutionMetrics(solution.id, false);
|
|
5411
|
-
console.error(
|
|
5508
|
+
console.error(chalk14.red(`
|
|
5412
5509
|
\u2717 Error: ${error.message}
|
|
5413
5510
|
`));
|
|
5414
5511
|
process.exit(1);
|
|
@@ -5417,48 +5514,48 @@ async function solutionApplyCommand(solutionId, options) {
|
|
|
5417
5514
|
async function solutionDeprecateCommand(solutionId, reason) {
|
|
5418
5515
|
const cwd = getWorkspacePath2();
|
|
5419
5516
|
const store = new PatternStore3(cwd);
|
|
5420
|
-
console.log(
|
|
5517
|
+
console.log(chalk14.cyan("\n\u26A0\uFE0F Deprecate Solution Pattern\n"));
|
|
5421
5518
|
const result = await store.getSolution(solutionId);
|
|
5422
5519
|
if (!result.success || !result.data) {
|
|
5423
|
-
console.error(
|
|
5520
|
+
console.error(chalk14.red(`
|
|
5424
5521
|
\u2717 Solution not found: ${solutionId}
|
|
5425
5522
|
`));
|
|
5426
5523
|
process.exit(1);
|
|
5427
5524
|
}
|
|
5428
5525
|
const solution = result.data;
|
|
5429
|
-
console.log(`Solution: ${
|
|
5526
|
+
console.log(`Solution: ${chalk14.bold(solution.name)}`);
|
|
5430
5527
|
console.log(`Reason: ${reason}
|
|
5431
5528
|
`);
|
|
5432
|
-
const
|
|
5529
|
+
const confirm9 = await p10.confirm({
|
|
5433
5530
|
message: "Deprecate this solution?",
|
|
5434
5531
|
initialValue: false
|
|
5435
5532
|
});
|
|
5436
|
-
if (
|
|
5437
|
-
|
|
5533
|
+
if (p10.isCancel(confirm9) || !confirm9) {
|
|
5534
|
+
p10.cancel("Operation cancelled");
|
|
5438
5535
|
process.exit(0);
|
|
5439
5536
|
}
|
|
5440
5537
|
await store.deprecateSolution(solutionId, reason);
|
|
5441
|
-
console.log(
|
|
5538
|
+
console.log(chalk14.green(`
|
|
5442
5539
|
\u2713 Solution deprecated.
|
|
5443
5540
|
`));
|
|
5444
5541
|
}
|
|
5445
5542
|
async function solutionStatsCommand() {
|
|
5446
5543
|
const cwd = getWorkspacePath2();
|
|
5447
5544
|
const store = new PatternStore3(cwd);
|
|
5448
|
-
console.log(
|
|
5545
|
+
console.log(chalk14.cyan("\n\u{1F4CA} Solution Pattern Statistics\n"));
|
|
5449
5546
|
const stats = await store.getStats();
|
|
5450
|
-
console.log(
|
|
5451
|
-
console.log(`${
|
|
5547
|
+
console.log(chalk14.dim("\u2500".repeat(40)));
|
|
5548
|
+
console.log(`${chalk14.bold("Solutions:")} ${stats.totalSolutions}`);
|
|
5452
5549
|
console.log(` Active: ${stats.totalSolutions - stats.deprecatedSolutions}`);
|
|
5453
5550
|
console.log(` Deprecated: ${stats.deprecatedSolutions}`);
|
|
5454
5551
|
console.log(` Private: ${stats.privateSolutions}`);
|
|
5455
5552
|
console.log(` Synced: ${stats.syncedSolutions}`);
|
|
5456
|
-
console.log(
|
|
5457
|
-
console.log(`${
|
|
5458
|
-
console.log(`${
|
|
5459
|
-
console.log(
|
|
5553
|
+
console.log(chalk14.dim("\u2500".repeat(40)));
|
|
5554
|
+
console.log(`${chalk14.bold("Fixes:")} ${stats.totalFixes}`);
|
|
5555
|
+
console.log(`${chalk14.bold("Blueprints:")} ${stats.totalBlueprints}`);
|
|
5556
|
+
console.log(chalk14.dim("\u2500".repeat(40)));
|
|
5460
5557
|
console.log(`
|
|
5461
|
-
${
|
|
5558
|
+
${chalk14.bold("By Category:")}`);
|
|
5462
5559
|
const listResult = await store.listSolutions({ limit: 1e3 });
|
|
5463
5560
|
if (listResult.success && listResult.data) {
|
|
5464
5561
|
const categories = /* @__PURE__ */ new Map();
|
|
@@ -5509,6 +5606,7 @@ program.command("advisory").description("Generate advisory board analysis and do
|
|
|
5509
5606
|
"--format <type>",
|
|
5510
5607
|
"Output format: markdown, json (default: markdown)"
|
|
5511
5608
|
).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
|
+
program.command("generate-instructions").description("Generate .github/copilot-instructions.md from guidelines").option("--force", "Regenerate without confirmation").action(generateInstructionsCommand);
|
|
5512
5610
|
program.command("learn:record").description("Record a new pattern from a successful implementation").option("--name <name>", "Pattern name").option("--description <desc>", "Pattern description").option(
|
|
5513
5611
|
"--category <cat>",
|
|
5514
5612
|
"Category (migration, security, performance, etc.)"
|