workflow-agent-cli 2.17.0 → 2.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -324,7 +324,7 @@ async function initCommand(options) {
324
324
  scopes = presetModule.scopes || presetModule.default.scopes;
325
325
  const spinner10 = p.spinner();
326
326
  spinner10.start(`Loading ${presetModule.default?.name || preset} preset`);
327
- await new Promise((resolve2) => setTimeout(resolve2, 500));
327
+ await new Promise((resolve3) => setTimeout(resolve3, 500));
328
328
  spinner10.stop(`\u2713 Loaded ${scopes.length} scopes from preset`);
329
329
  } catch (error) {
330
330
  console.log(
@@ -5235,8 +5235,7 @@ import {
5235
5235
  TelemetryCollector as TelemetryCollector2,
5236
5236
  FixPatternSchema,
5237
5237
  BlueprintSchema,
5238
- SolutionPatternSchema,
5239
- createDefaultMetrics
5238
+ SolutionPatternSchema
5240
5239
  } from "@hawkinside_out/workflow-improvement-tracker";
5241
5240
 
5242
5241
  // src/sync/registry-client.ts
@@ -5380,7 +5379,7 @@ var RegistryClient = class {
5380
5379
  }
5381
5380
  if (attempt < this.retries) {
5382
5381
  await new Promise(
5383
- (resolve2) => setTimeout(resolve2, Math.pow(2, attempt) * 1e3)
5382
+ (resolve3) => setTimeout(resolve3, Math.pow(2, attempt) * 1e3)
5384
5383
  );
5385
5384
  }
5386
5385
  }
@@ -5834,8 +5833,8 @@ async function learnApplyCommand(patternId, options) {
5834
5833
  chalk16.yellow("\n\u{1F4CB} DRY-RUN MODE: No changes will be applied\n")
5835
5834
  );
5836
5835
  }
5837
- const framework = options.framework ?? patternData.compatibility.frameworks[0]?.name ?? "unknown";
5838
- const version = options.version ?? patternData.compatibility.frameworks[0]?.version ?? "0.0.0";
5836
+ const framework = options.framework ?? patternData.compatibility?.frameworks?.[0]?.name ?? "unknown";
5837
+ const version = options.version ?? patternData.compatibility?.frameworks?.[0]?.version ?? "0.0.0";
5839
5838
  await telemetry.recordApplication(patternId, patternType, framework, version);
5840
5839
  if (patternType === "fix") {
5841
5840
  const fixPattern = patternData;
@@ -6723,6 +6722,457 @@ function tryAutoFix(data, type, issues) {
6723
6722
  }
6724
6723
  return { fixable: false };
6725
6724
  }
6725
+ var LIBRARY_TAG_MAP = {
6726
+ // Frontend Frameworks
6727
+ "react": [{ category: "framework", name: "react" }],
6728
+ "react-dom": [{ category: "framework", name: "react" }],
6729
+ "next": [{ category: "framework", name: "next" }],
6730
+ "vue": [{ category: "framework", name: "vue" }],
6731
+ "nuxt": [{ category: "framework", name: "nuxt" }],
6732
+ "svelte": [{ category: "framework", name: "svelte" }],
6733
+ "@sveltejs/kit": [{ category: "framework", name: "sveltekit" }],
6734
+ "solid-js": [{ category: "framework", name: "solid" }],
6735
+ "@angular/core": [{ category: "framework", name: "angular" }],
6736
+ "astro": [{ category: "framework", name: "astro" }],
6737
+ "remix": [{ category: "framework", name: "remix" }],
6738
+ // Backend Frameworks
6739
+ "express": [{ category: "framework", name: "express" }],
6740
+ "fastify": [{ category: "framework", name: "fastify" }],
6741
+ "hono": [{ category: "framework", name: "hono" }],
6742
+ "koa": [{ category: "framework", name: "koa" }],
6743
+ "@nestjs/core": [{ category: "framework", name: "nestjs" }],
6744
+ "hapi": [{ category: "framework", name: "hapi" }],
6745
+ // Testing
6746
+ "vitest": [{ category: "tooling", name: "vitest" }, { category: "category", name: "testing" }],
6747
+ "jest": [{ category: "tooling", name: "jest" }, { category: "category", name: "testing" }],
6748
+ "@testing-library/react": [{ category: "tooling", name: "testing-library" }],
6749
+ "playwright": [{ category: "tooling", name: "playwright" }, { category: "category", name: "e2e" }],
6750
+ "cypress": [{ category: "tooling", name: "cypress" }, { category: "category", name: "e2e" }],
6751
+ // State Management
6752
+ "zustand": [{ category: "tooling", name: "zustand" }, { category: "category", name: "state" }],
6753
+ "redux": [{ category: "tooling", name: "redux" }, { category: "category", name: "state" }],
6754
+ "@reduxjs/toolkit": [{ category: "tooling", name: "redux-toolkit" }, { category: "category", name: "state" }],
6755
+ "jotai": [{ category: "tooling", name: "jotai" }, { category: "category", name: "state" }],
6756
+ "recoil": [{ category: "tooling", name: "recoil" }, { category: "category", name: "state" }],
6757
+ "mobx": [{ category: "tooling", name: "mobx" }, { category: "category", name: "state" }],
6758
+ "pinia": [{ category: "tooling", name: "pinia" }, { category: "category", name: "state" }],
6759
+ "xstate": [{ category: "tooling", name: "xstate" }, { category: "category", name: "state-machine" }],
6760
+ // Database & ORM
6761
+ "prisma": [{ category: "tooling", name: "prisma" }, { category: "category", name: "database" }],
6762
+ "@prisma/client": [{ category: "tooling", name: "prisma" }, { category: "category", name: "database" }],
6763
+ "drizzle-orm": [{ category: "tooling", name: "drizzle" }, { category: "category", name: "database" }],
6764
+ "typeorm": [{ category: "tooling", name: "typeorm" }, { category: "category", name: "database" }],
6765
+ "mongoose": [{ category: "tooling", name: "mongoose" }, { category: "category", name: "mongodb" }],
6766
+ "knex": [{ category: "tooling", name: "knex" }, { category: "category", name: "database" }],
6767
+ "sequelize": [{ category: "tooling", name: "sequelize" }, { category: "category", name: "database" }],
6768
+ // Authentication
6769
+ "next-auth": [{ category: "tooling", name: "next-auth" }, { category: "category", name: "auth" }],
6770
+ "@auth/core": [{ category: "tooling", name: "authjs" }, { category: "category", name: "auth" }],
6771
+ "passport": [{ category: "tooling", name: "passport" }, { category: "category", name: "auth" }],
6772
+ "lucia": [{ category: "tooling", name: "lucia" }, { category: "category", name: "auth" }],
6773
+ "@clerk/nextjs": [{ category: "tooling", name: "clerk" }, { category: "category", name: "auth" }],
6774
+ // UI Libraries
6775
+ "@radix-ui/react-dialog": [{ category: "tooling", name: "radix-ui" }],
6776
+ "@radix-ui/react-dropdown-menu": [{ category: "tooling", name: "radix-ui" }],
6777
+ "@shadcn/ui": [{ category: "tooling", name: "shadcn" }],
6778
+ "@chakra-ui/react": [{ category: "tooling", name: "chakra-ui" }],
6779
+ "@mantine/core": [{ category: "tooling", name: "mantine" }],
6780
+ "@headlessui/react": [{ category: "tooling", name: "headlessui" }],
6781
+ "antd": [{ category: "tooling", name: "antd" }],
6782
+ "@mui/material": [{ category: "tooling", name: "material-ui" }],
6783
+ // Styling
6784
+ "tailwindcss": [{ category: "tooling", name: "tailwind" }],
6785
+ "styled-components": [{ category: "tooling", name: "styled-components" }],
6786
+ "@emotion/react": [{ category: "tooling", name: "emotion" }],
6787
+ "sass": [{ category: "tooling", name: "sass" }],
6788
+ // API & Data Fetching
6789
+ "@tanstack/react-query": [{ category: "tooling", name: "tanstack-query" }, { category: "category", name: "data-fetching" }],
6790
+ "swr": [{ category: "tooling", name: "swr" }, { category: "category", name: "data-fetching" }],
6791
+ "@trpc/server": [{ category: "tooling", name: "trpc" }, { category: "category", name: "api" }],
6792
+ "@trpc/client": [{ category: "tooling", name: "trpc" }, { category: "category", name: "api" }],
6793
+ "graphql": [{ category: "tooling", name: "graphql" }, { category: "category", name: "api" }],
6794
+ "@apollo/client": [{ category: "tooling", name: "apollo" }, { category: "category", name: "graphql" }],
6795
+ "axios": [{ category: "tooling", name: "axios" }],
6796
+ // Form Libraries
6797
+ "react-hook-form": [{ category: "tooling", name: "react-hook-form" }, { category: "category", name: "forms" }],
6798
+ "formik": [{ category: "tooling", name: "formik" }, { category: "category", name: "forms" }],
6799
+ "@tanstack/react-form": [{ category: "tooling", name: "tanstack-form" }, { category: "category", name: "forms" }],
6800
+ // Validation
6801
+ "zod": [{ category: "tooling", name: "zod" }, { category: "category", name: "validation" }],
6802
+ "yup": [{ category: "tooling", name: "yup" }, { category: "category", name: "validation" }],
6803
+ "valibot": [{ category: "tooling", name: "valibot" }, { category: "category", name: "validation" }],
6804
+ // Build Tools
6805
+ "vite": [{ category: "tooling", name: "vite" }],
6806
+ "esbuild": [{ category: "tooling", name: "esbuild" }],
6807
+ "tsup": [{ category: "tooling", name: "tsup" }],
6808
+ "webpack": [{ category: "tooling", name: "webpack" }],
6809
+ "turbo": [{ category: "tooling", name: "turborepo" }],
6810
+ // Utilities
6811
+ "lodash": [{ category: "tooling", name: "lodash" }],
6812
+ "date-fns": [{ category: "tooling", name: "date-fns" }],
6813
+ "dayjs": [{ category: "tooling", name: "dayjs" }],
6814
+ "uuid": [{ category: "tooling", name: "uuid" }],
6815
+ "nanoid": [{ category: "tooling", name: "nanoid" }],
6816
+ // CLI & Developer Tools
6817
+ "commander": [{ category: "tooling", name: "commander" }, { category: "category", name: "cli" }],
6818
+ "yargs": [{ category: "tooling", name: "yargs" }, { category: "category", name: "cli" }],
6819
+ "@clack/prompts": [{ category: "tooling", name: "clack" }, { category: "category", name: "cli" }],
6820
+ "inquirer": [{ category: "tooling", name: "inquirer" }, { category: "category", name: "cli" }],
6821
+ "chalk": [{ category: "tooling", name: "chalk" }],
6822
+ // Runtime & Languages
6823
+ "typescript": [{ category: "language", name: "typescript" }]
6824
+ };
6825
+ function inferPatternName(filePaths) {
6826
+ if (filePaths.length === 1) {
6827
+ const fileName = path2.basename(filePaths[0]);
6828
+ const nameWithoutExt = fileName.replace(/\.[^.]+$/, "");
6829
+ return nameWithoutExt.replace(/[-_]/g, " ").replace(/([A-Z])/g, " $1").trim().split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ");
6830
+ }
6831
+ const dirs = filePaths.map((p13) => path2.dirname(p13));
6832
+ const uniqueDirs = [...new Set(dirs)];
6833
+ if (uniqueDirs.length === 1 && uniqueDirs[0] !== ".") {
6834
+ const dirName = path2.basename(uniqueDirs[0]);
6835
+ return dirName.replace(/[-_]/g, " ").replace(/([A-Z])/g, " $1").trim().split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ") + " Pattern";
6836
+ }
6837
+ const fileNames = filePaths.map((p13) => path2.basename(p13).replace(/\.[^.]+$/, ""));
6838
+ if (fileNames.length > 0) {
6839
+ let commonPrefix = fileNames[0];
6840
+ for (const name of fileNames.slice(1)) {
6841
+ while (!name.startsWith(commonPrefix) && commonPrefix.length > 0) {
6842
+ commonPrefix = commonPrefix.slice(0, -1);
6843
+ }
6844
+ }
6845
+ if (commonPrefix.length > 2) {
6846
+ return commonPrefix.replace(/[-_]/g, " ").replace(/([A-Z])/g, " $1").trim().split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ") + " Pattern";
6847
+ }
6848
+ }
6849
+ return `Multi-file Pattern (${filePaths.length} files)`;
6850
+ }
6851
+ async function inferTagsFromDependencies(cwd) {
6852
+ const tags = [];
6853
+ const seenTags = /* @__PURE__ */ new Set();
6854
+ const packageJsonPath = path2.join(cwd, "package.json");
6855
+ if (!fs2.existsSync(packageJsonPath)) {
6856
+ return tags;
6857
+ }
6858
+ try {
6859
+ const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
6860
+ const allDeps = {
6861
+ ...packageJson.dependencies,
6862
+ ...packageJson.devDependencies
6863
+ };
6864
+ for (const dep of Object.keys(allDeps)) {
6865
+ const mappedTags = LIBRARY_TAG_MAP[dep];
6866
+ if (mappedTags) {
6867
+ for (const tag of mappedTags) {
6868
+ const key = `${tag.category}:${tag.name}`;
6869
+ if (!seenTags.has(key)) {
6870
+ seenTags.add(key);
6871
+ tags.push(tag);
6872
+ }
6873
+ }
6874
+ }
6875
+ }
6876
+ } catch {
6877
+ }
6878
+ return tags;
6879
+ }
6880
+ function inferTagsFromContent(filePaths) {
6881
+ const tags = [];
6882
+ const seenTags = /* @__PURE__ */ new Set();
6883
+ const addTag = (category, name) => {
6884
+ const key = `${category}:${name}`;
6885
+ if (!seenTags.has(key)) {
6886
+ seenTags.add(key);
6887
+ tags.push({ category, name });
6888
+ }
6889
+ };
6890
+ for (const filePath of filePaths) {
6891
+ const ext = path2.extname(filePath).toLowerCase();
6892
+ const fileName = path2.basename(filePath).toLowerCase();
6893
+ if (ext === ".ts" || ext === ".tsx") {
6894
+ addTag("language", "typescript");
6895
+ } else if (ext === ".js" || ext === ".jsx" || ext === ".mjs" || ext === ".cjs") {
6896
+ addTag("language", "javascript");
6897
+ } else if (ext === ".py") {
6898
+ addTag("language", "python");
6899
+ } else if (ext === ".go") {
6900
+ addTag("language", "go");
6901
+ } else if (ext === ".rs") {
6902
+ addTag("language", "rust");
6903
+ } else if (ext === ".css" || ext === ".scss" || ext === ".sass") {
6904
+ addTag("tooling", "css");
6905
+ }
6906
+ if (ext === ".tsx" || ext === ".jsx") {
6907
+ addTag("framework", "react");
6908
+ }
6909
+ if (fileName.includes(".test.") || fileName.includes(".spec.") || fileName.startsWith("test_")) {
6910
+ addTag("category", "testing");
6911
+ }
6912
+ if (fileName.includes("config") || fileName.startsWith(".")) {
6913
+ addTag("category", "configuration");
6914
+ }
6915
+ if (filePath.includes("/components/") || filePath.includes("\\components\\")) {
6916
+ addTag("category", "component");
6917
+ }
6918
+ if (filePath.includes("/hooks/") || filePath.includes("\\hooks\\") || fileName.startsWith("use")) {
6919
+ addTag("category", "hooks");
6920
+ }
6921
+ if (filePath.includes("/api/") || filePath.includes("\\api\\") || filePath.includes("/routes/")) {
6922
+ addTag("category", "api");
6923
+ }
6924
+ if (filePath.includes("/utils/") || filePath.includes("\\utils\\") || filePath.includes("/lib/")) {
6925
+ addTag("category", "utilities");
6926
+ }
6927
+ }
6928
+ return tags;
6929
+ }
6930
+ async function learnCaptureCommand(paths, options) {
6931
+ const cwd = getWorkspacePath();
6932
+ const store = new PatternStore2(cwd);
6933
+ console.log(chalk16.cyan("\n\u{1F4F8} Capture Files as Blueprint\n"));
6934
+ const resolvedPaths = [];
6935
+ const relativePaths = [];
6936
+ for (const inputPath of paths) {
6937
+ const absolutePath = path2.isAbsolute(inputPath) ? inputPath : path2.resolve(cwd, inputPath);
6938
+ if (!fs2.existsSync(absolutePath)) {
6939
+ console.log(chalk16.red(`\u2717 File not found: ${inputPath}`));
6940
+ process.exit(1);
6941
+ }
6942
+ const stat = fs2.statSync(absolutePath);
6943
+ if (stat.isDirectory()) {
6944
+ const files2 = getAllFilesInDir(absolutePath);
6945
+ for (const file of files2) {
6946
+ resolvedPaths.push(file);
6947
+ relativePaths.push(path2.relative(cwd, file));
6948
+ }
6949
+ } else {
6950
+ resolvedPaths.push(absolutePath);
6951
+ relativePaths.push(path2.relative(cwd, absolutePath));
6952
+ }
6953
+ }
6954
+ if (resolvedPaths.length === 0) {
6955
+ console.log(chalk16.red("\u2717 No files found to capture"));
6956
+ process.exit(1);
6957
+ }
6958
+ console.log(chalk16.dim(`Found ${resolvedPaths.length} file(s) to capture:
6959
+ `));
6960
+ for (const relPath of relativePaths.slice(0, 10)) {
6961
+ console.log(chalk16.dim(` \u2022 ${relPath}`));
6962
+ }
6963
+ if (relativePaths.length > 10) {
6964
+ console.log(chalk16.dim(` ... and ${relativePaths.length - 10} more`));
6965
+ }
6966
+ console.log();
6967
+ const depTags = await inferTagsFromDependencies(cwd);
6968
+ const contentTags = inferTagsFromContent(relativePaths);
6969
+ const allInferredTags = [...depTags, ...contentTags];
6970
+ const seenTagKeys = /* @__PURE__ */ new Set();
6971
+ const uniqueTags = [];
6972
+ for (const tag of allInferredTags) {
6973
+ const key = `${tag.category}:${tag.name}`;
6974
+ if (!seenTagKeys.has(key)) {
6975
+ seenTagKeys.add(key);
6976
+ uniqueTags.push(tag);
6977
+ }
6978
+ }
6979
+ if (options.tags) {
6980
+ const tagPairs = options.tags.split(",").map((t) => t.trim());
6981
+ for (const pair of tagPairs) {
6982
+ const [cat, val] = pair.split(":");
6983
+ if (cat && val) {
6984
+ const key = `${cat}:${val}`;
6985
+ if (!seenTagKeys.has(key)) {
6986
+ seenTagKeys.add(key);
6987
+ uniqueTags.push({
6988
+ category: cat,
6989
+ name: val
6990
+ });
6991
+ }
6992
+ }
6993
+ }
6994
+ }
6995
+ let name = options.name;
6996
+ if (!name) {
6997
+ const inferredName = inferPatternName(relativePaths);
6998
+ console.log(chalk16.dim(`Inferred name: "${inferredName}"`));
6999
+ const nameInput = await p11.text({
7000
+ message: "Pattern name:",
7001
+ placeholder: inferredName,
7002
+ initialValue: inferredName,
7003
+ validate: (value) => {
7004
+ if (!value || value.length < 3) return "Name must be at least 3 characters";
7005
+ if (value.length > 100) return "Name must be less than 100 characters";
7006
+ return void 0;
7007
+ }
7008
+ });
7009
+ if (p11.isCancel(nameInput)) {
7010
+ p11.cancel("Capture cancelled");
7011
+ process.exit(0);
7012
+ }
7013
+ name = nameInput;
7014
+ }
7015
+ let description = options.description;
7016
+ if (!description) {
7017
+ const descInput = await p11.text({
7018
+ message: "Description:",
7019
+ placeholder: "What does this pattern provide?",
7020
+ validate: (value) => {
7021
+ if (!value || value.length < 10) return "Description must be at least 10 characters";
7022
+ if (value.length > 500) return "Description must be less than 500 characters";
7023
+ return void 0;
7024
+ }
7025
+ });
7026
+ if (p11.isCancel(descInput)) {
7027
+ p11.cancel("Capture cancelled");
7028
+ process.exit(0);
7029
+ }
7030
+ description = descInput;
7031
+ }
7032
+ let framework = options.framework;
7033
+ if (!framework) {
7034
+ const frameworkTag = uniqueTags.find((t) => t.category === "framework");
7035
+ framework = frameworkTag?.name || "general";
7036
+ }
7037
+ if (uniqueTags.length > 0) {
7038
+ console.log(chalk16.dim("\nInferred tags:"));
7039
+ console.log(chalk16.dim(` ${formatTags(uniqueTags)}`));
7040
+ }
7041
+ const files = [];
7042
+ for (let i = 0; i < resolvedPaths.length; i++) {
7043
+ const absolutePath = resolvedPaths[i];
7044
+ const relativePath = relativePaths[i];
7045
+ const content = fs2.readFileSync(absolutePath, "utf-8");
7046
+ const ext = path2.extname(relativePath).slice(1);
7047
+ const languageMap = {
7048
+ ts: "typescript",
7049
+ tsx: "typescript",
7050
+ js: "javascript",
7051
+ jsx: "javascript",
7052
+ mjs: "javascript",
7053
+ cjs: "javascript",
7054
+ py: "python",
7055
+ go: "go",
7056
+ rs: "rust",
7057
+ css: "css",
7058
+ scss: "scss",
7059
+ html: "html",
7060
+ json: "json",
7061
+ yaml: "yaml",
7062
+ yml: "yaml",
7063
+ md: "markdown",
7064
+ mdx: "mdx",
7065
+ sql: "sql",
7066
+ sh: "bash",
7067
+ bash: "bash",
7068
+ zsh: "bash"
7069
+ };
7070
+ files.push({
7071
+ path: relativePath,
7072
+ content,
7073
+ language: languageMap[ext] || ext || "text"
7074
+ });
7075
+ }
7076
+ const languageCounts = {};
7077
+ for (const file of files) {
7078
+ languageCounts[file.language] = (languageCounts[file.language] || 0) + 1;
7079
+ }
7080
+ const primaryLanguage = Object.entries(languageCounts).sort((a, b) => b[1] - a[1])[0]?.[0] || "typescript";
7081
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7082
+ const contributorManager = new ContributorManager2(cwd);
7083
+ const contributorResult = await contributorManager.getOrCreateId();
7084
+ const contributorId = contributorResult.success && contributorResult.data ? contributorResult.data : void 0;
7085
+ const keyFiles = files.map((f) => ({
7086
+ path: f.path,
7087
+ purpose: `${f.language} file`,
7088
+ content: f.content
7089
+ }));
7090
+ const blueprint = {
7091
+ id: crypto.randomUUID(),
7092
+ name,
7093
+ description,
7094
+ tags: uniqueTags,
7095
+ stack: {
7096
+ framework,
7097
+ language: primaryLanguage,
7098
+ runtime: "node",
7099
+ packageManager: "pnpm",
7100
+ dependencies: [],
7101
+ devDependencies: []
7102
+ },
7103
+ structure: {
7104
+ directories: [...new Set(files.map((f) => path2.dirname(f.path)).filter((d) => d !== "."))],
7105
+ keyFiles
7106
+ },
7107
+ setup: {
7108
+ prerequisites: [],
7109
+ steps: [],
7110
+ configs: []
7111
+ },
7112
+ compatibility: {
7113
+ framework,
7114
+ frameworkVersion: ">=1.0.0",
7115
+ runtime: "node",
7116
+ runtimeVersion: ">=18.0.0",
7117
+ dependencies: []
7118
+ },
7119
+ metrics: {
7120
+ applications: 0,
7121
+ successes: 0,
7122
+ failures: 0,
7123
+ successRate: 0
7124
+ },
7125
+ relatedPatterns: [],
7126
+ isPrivate: true,
7127
+ contributorId,
7128
+ createdAt: now,
7129
+ updatedAt: now
7130
+ };
7131
+ if (options.dryRun) {
7132
+ console.log(chalk16.yellow("\n\u{1F50D} Dry Run - Would capture:\n"));
7133
+ console.log(chalk16.bold(`Name: ${name}`));
7134
+ console.log(chalk16.dim(`Description: ${description}`));
7135
+ console.log(chalk16.dim(`Framework: ${framework}`));
7136
+ console.log(chalk16.dim(`Tags: ${formatTags(uniqueTags)}`));
7137
+ console.log(chalk16.dim(`Files: ${files.length}`));
7138
+ console.log(chalk16.dim(`ID: ${blueprint.id}`));
7139
+ console.log(chalk16.yellow("\n\u26A0\uFE0F No changes made (dry run)"));
7140
+ return;
7141
+ }
7142
+ const result = await store.saveBlueprint(blueprint);
7143
+ if (!result.success) {
7144
+ console.log(chalk16.red(`
7145
+ \u2717 Failed to save blueprint: ${result.error}`));
7146
+ process.exit(1);
7147
+ }
7148
+ console.log(chalk16.green("\n\u2713 Blueprint captured successfully!\n"));
7149
+ console.log(chalk16.bold(`ID: ${blueprint.id}`));
7150
+ console.log(chalk16.dim(`Name: ${name}`));
7151
+ console.log(chalk16.dim(`Files: ${files.length}`));
7152
+ console.log(chalk16.dim(`Tags: ${formatTags(uniqueTags)}`));
7153
+ console.log(chalk16.dim(`
7154
+ To apply this pattern:`));
7155
+ console.log(chalk16.cyan(` pnpm workflow:learn:apply ${blueprint.id}`));
7156
+ console.log(chalk16.dim(`
7157
+ To publish to registry:`));
7158
+ console.log(chalk16.cyan(` pnpm workflow:learn:publish ${blueprint.id}`));
7159
+ }
7160
+ function getAllFilesInDir(dirPath) {
7161
+ const files = [];
7162
+ const entries = fs2.readdirSync(dirPath, { withFileTypes: true });
7163
+ for (const entry of entries) {
7164
+ const fullPath = path2.join(dirPath, entry.name);
7165
+ if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
7166
+ continue;
7167
+ }
7168
+ if (entry.isDirectory()) {
7169
+ files.push(...getAllFilesInDir(fullPath));
7170
+ } else {
7171
+ files.push(fullPath);
7172
+ }
7173
+ }
7174
+ return files;
7175
+ }
6726
7176
 
6727
7177
  // src/cli/commands/solution.ts
6728
7178
  import chalk17 from "chalk";
@@ -7172,14 +7622,11 @@ program.command("init").description("Initialize workflow in current project").op
7172
7622
  "--preset <preset>",
7173
7623
  "Preset to use (saas, library, api, ecommerce, cms, custom)"
7174
7624
  ).option("--name <name>", "Project name").option("-y, --yes", "Skip confirmation prompts").action(initCommand);
7175
- program.command("validate <type>").description("Validate branch name, commit message, or PR title").argument("<type>", "What to validate: branch, commit, or pr").argument(
7176
- "[value]",
7177
- "Value to validate (defaults to current branch/HEAD commit)"
7178
- ).option(
7625
+ program.command("validate <type> [value]").description("Validate branch name, commit message, or PR title").option(
7179
7626
  "--suggest-on-error",
7180
7627
  "Offer improvement suggestions on validation errors"
7181
7628
  ).action(validateCommand);
7182
- program.command("config <action>").description("Manage workflow configuration").argument("<action>", "Action: get, set, add, remove").argument("[key]", "Config key").argument("[value]", "Config value").action(configCommand);
7629
+ program.command("config <action> [key] [value]").description("Manage workflow configuration").action(configCommand);
7183
7630
  program.command("config:fix").description("Automatically fix common configuration validation issues").action(async () => {
7184
7631
  const chalk18 = (await import("chalk")).default;
7185
7632
  const { autoFixConfigFile: autoFixConfigFile2 } = await import("../config/index.js");
@@ -7244,10 +7691,11 @@ program.command("learn:record").description("Record a new pattern from a success
7244
7691
  "Category (migration, security, performance, etc.)"
7245
7692
  ).option("--framework <fw>", "Framework (next, react, vue, etc.)").option("--version <ver>", "Framework version range").option("--tags <tags>", "Comma-separated tags (category:value)").option("--type <type>", "Pattern type (fix, blueprint)").action(learnRecordCommand);
7246
7693
  program.command("learn:list").description("List recorded learning patterns").option("--type <type>", "Filter by type (fix, blueprint, all)").option("--framework <fw>", "Filter by framework").option("--tag <tag>", "Filter by tag").option("--deprecated", "Include deprecated patterns").action(learnListCommand);
7247
- program.command("learn:apply <patternId>").description("Apply a pattern to the current project").argument("<patternId>", "Pattern ID to apply").option("--framework <fw>", "Override framework").option("--version <ver>", "Override version").option("--dry-run", "Preview without applying").action(learnApplyCommand);
7694
+ program.command("learn:apply <patternId>").description("Apply a pattern to the current project").option("--framework <fw>", "Override framework").option("--version <ver>", "Override version").option("--dry-run", "Preview without applying").action(learnApplyCommand);
7695
+ program.command("learn:capture <paths...>").description("Capture files as a blueprint pattern with auto-inferred metadata").option("--name <name>", "Pattern name (inferred from paths if omitted)").option("--description <desc>", "Pattern description").option("--framework <fw>", "Override inferred framework").option("--tags <tags>", "Additional tags (comma-separated, e.g., 'framework:react,language:typescript')").option("--dry-run", "Preview what would be captured without saving").action(learnCaptureCommand);
7248
7696
  program.command("learn:sync").description("Sync patterns with remote registry").option("--push", "Push local patterns to registry").option("--pull", "Pull patterns from registry").option("--dry-run", "Preview without syncing").action(learnSyncCommand);
7249
7697
  program.command("learn:config").description("Configure learning settings").option("--enable-sync", "Enable pattern sync").option("--disable-sync", "Disable pattern sync").option("--enable-telemetry", "Enable anonymous telemetry").option("--disable-telemetry", "Disable telemetry").option("--reset-id", "Reset contributor ID").option("--show", "Show current configuration").action(learnConfigCommand);
7250
- program.command("learn:deprecate <patternId> <reason>").description("Deprecate an outdated pattern").argument("<patternId>", "Pattern ID to deprecate").argument("<reason>", "Reason for deprecation").action(learnDeprecateCommand);
7698
+ program.command("learn:deprecate <patternId> <reason>").description("Deprecate an outdated pattern").action(learnDeprecateCommand);
7251
7699
  program.command("learn:publish [patternId]").description("Mark pattern(s) as public for syncing").option("--private", "Mark as private instead of public").option("--all", "Apply to all patterns").option("-y, --yes", "Skip confirmation prompts").action(learnPublishCommand);
7252
7700
  program.command("learn:stats").description("Show learning statistics").action(learnStatsCommand);
7253
7701
  program.command("learn:validate").description("Validate pattern files and optionally auto-fix common issues").option(
@@ -7259,10 +7707,10 @@ program.command("solution:capture").description("Capture a solution pattern from
7259
7707
  "--category <cat>",
7260
7708
  "Category (auth, api, database, ui, testing, deployment, integration, performance, security, other)"
7261
7709
  ).option("--keywords <kw>", "Comma-separated keywords").option("--path <path>", "Path to the solution directory").option("--anonymize", "Anonymize sensitive data in code").action(solutionCaptureCommand);
7262
- program.command("solution:search <query>").description("Search for solution patterns").argument("<query>", "Search query (keywords, problem description)").option("--category <cat>", "Filter by category").option("--framework <fw>", "Filter by framework").option("--limit <n>", "Maximum results", "10").action(solutionSearchCommand);
7710
+ program.command("solution:search <query>").description("Search for solution patterns").option("--category <cat>", "Filter by category").option("--framework <fw>", "Filter by framework").option("--limit <n>", "Maximum results", "10").action(solutionSearchCommand);
7263
7711
  program.command("solution:list").description("List all solution patterns").option("--category <cat>", "Filter by category").option("--framework <fw>", "Filter by framework").option("--deprecated", "Include deprecated solutions").option("--limit <n>", "Maximum results", "20").action(solutionListCommand);
7264
- program.command("solution:apply <solutionId>").description("Apply a solution pattern to the current project").argument("<solutionId>", "Solution ID to apply").option("--output <dir>", "Output directory").option("--dry-run", "Preview without applying").option("--include-tests", "Include test files").action(solutionApplyCommand);
7265
- program.command("solution:deprecate <solutionId> <reason>").description("Deprecate a solution pattern").argument("<solutionId>", "Solution ID to deprecate").argument("<reason>", "Reason for deprecation").action(solutionDeprecateCommand);
7712
+ program.command("solution:apply <solutionId>").description("Apply a solution pattern to the current project").option("--output <dir>", "Output directory").option("--dry-run", "Preview without applying").option("--include-tests", "Include test files").action(solutionApplyCommand);
7713
+ program.command("solution:deprecate <solutionId> <reason>").description("Deprecate a solution pattern").action(solutionDeprecateCommand);
7266
7714
  program.command("solution:stats").description("Show solution pattern statistics").action(solutionStatsCommand);
7267
7715
  program.parse();
7268
7716
  //# sourceMappingURL=index.js.map