workflow-agent-cli 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -5,13 +5,16 @@ import {
5
5
  validatePRTitle
6
6
  } from "../chunk-X2NQJ2ZY.js";
7
7
  import {
8
+ DEFAULT_RESERVED_SCOPE_NAMES,
8
9
  hasConfig,
9
10
  loadConfig,
10
- validateScopeDefinitions
11
- } from "../chunk-4BIDFDSR.js";
11
+ validateConfig,
12
+ validateScopeDefinitions,
13
+ validateScopeName
14
+ } from "../chunk-B27W7GWP.js";
12
15
 
13
16
  // src/cli/index.ts
14
- import { Command } from "commander";
17
+ import { Command as Command2 } from "commander";
15
18
 
16
19
  // src/cli/commands/init.ts
17
20
  import * as p from "@clack/prompts";
@@ -346,6 +349,8 @@ function generatePreCommitHook(config) {
346
349
  return " workflow validate commit";
347
350
  case "check-guidelines":
348
351
  return " workflow doctor --check-guidelines-only 2>/dev/null || true";
352
+ case "validate-scopes":
353
+ return " workflow config validate";
349
354
  default:
350
355
  return "";
351
356
  }
@@ -1141,10 +1146,299 @@ async function validateCommand(type, value, _options = {}) {
1141
1146
  }
1142
1147
 
1143
1148
  // src/cli/commands/config.ts
1149
+ import { Command } from "commander";
1150
+ import { join as join5 } from "path";
1151
+ import { existsSync as existsSync5, writeFileSync } from "fs";
1152
+ import prompts from "prompts";
1144
1153
  import chalk3 from "chalk";
1145
- async function configCommand(action, key, value) {
1146
- console.log(chalk3.yellow("Config command not yet implemented"));
1147
- console.log({ action, key, value });
1154
+ function createConfigCommand() {
1155
+ const command = new Command("config").description("Manage workflow configuration").option("-f, --force", "Skip validation checks").option("--cwd <path>", "Working directory", process.cwd());
1156
+ command.command("validate").description("Validate workflow configuration").action(async (options) => {
1157
+ const opts = command.opts();
1158
+ await validateConfigAction(opts);
1159
+ });
1160
+ command.command("add").description("Add configuration items").argument("<type>", "Type to add (scope)").action(async (type, options) => {
1161
+ const opts = command.opts();
1162
+ if (type === "scope") {
1163
+ await addScopeAction(opts);
1164
+ } else {
1165
+ console.error(chalk3.red(`Unknown type: ${type}. Currently only "scope" is supported.`));
1166
+ process.exit(1);
1167
+ }
1168
+ });
1169
+ command.command("remove").description("Remove configuration items").argument("<type>", "Type to remove (scope)").argument("<name>", "Name of the item to remove").action(async (type, name, options) => {
1170
+ const opts = command.opts();
1171
+ if (type === "scope") {
1172
+ await removeScopeAction(name, opts);
1173
+ } else {
1174
+ console.error(chalk3.red(`Unknown type: ${type}. Currently only "scope" is supported.`));
1175
+ process.exit(1);
1176
+ }
1177
+ });
1178
+ command.command("list").description("List configuration items").argument("[type]", "Type to list (scopes, reserved, all)", "all").action(async (type, options) => {
1179
+ const opts = command.opts();
1180
+ await listConfigAction(type, opts);
1181
+ });
1182
+ command.command("get").description("Get a configuration value").argument("<path>", "Configuration path (e.g., scopes[0].name)").action(async (path2, options) => {
1183
+ const opts = command.opts();
1184
+ await getConfigValue(path2, opts);
1185
+ });
1186
+ command.command("set").description("Set a configuration value").argument("<path>", "Configuration path (e.g., reservedScopeNames)").argument("<value>", "Value to set").action(async (path2, value, options) => {
1187
+ const opts = command.opts();
1188
+ await setConfigValue(path2, value, opts);
1189
+ });
1190
+ return command;
1191
+ }
1192
+ async function validateConfigAction(opts) {
1193
+ console.log(chalk3.blue("\u{1F50D} Validating workflow configuration..."));
1194
+ const result = await validateConfig(opts.cwd || process.cwd());
1195
+ if (result.valid) {
1196
+ console.log(chalk3.green("\u2713 Configuration is valid"));
1197
+ process.exit(0);
1198
+ } else {
1199
+ console.log(chalk3.red("\u2717 Configuration has errors:\n"));
1200
+ result.errors.forEach((err) => {
1201
+ console.log(chalk3.red(` \u2022 ${err}`));
1202
+ });
1203
+ if (result.warnings.length > 0) {
1204
+ console.log(chalk3.yellow("\n\u26A0 Warnings:\n"));
1205
+ result.warnings.forEach((warn) => {
1206
+ console.log(chalk3.yellow(` \u2022 ${warn}`));
1207
+ });
1208
+ }
1209
+ console.log(chalk3.gray("\n\u{1F4A1} Fix these issues in workflow.config.json"));
1210
+ process.exit(1);
1211
+ }
1212
+ }
1213
+ async function addScopeAction(opts) {
1214
+ const cwd = opts.cwd || process.cwd();
1215
+ const configPath = join5(cwd, "workflow.config.json");
1216
+ if (!existsSync5(configPath)) {
1217
+ console.error(chalk3.red("No workflow.config.json found. Run: workflow init"));
1218
+ process.exit(1);
1219
+ }
1220
+ const config = await loadConfig(cwd);
1221
+ if (!config) {
1222
+ console.error(chalk3.red("Failed to load configuration"));
1223
+ process.exit(1);
1224
+ }
1225
+ const reservedNames = config.reservedScopeNames || DEFAULT_RESERVED_SCOPE_NAMES;
1226
+ const existingNames = config.scopes.map((s) => s.name);
1227
+ const response = await prompts([
1228
+ {
1229
+ type: "text",
1230
+ name: "name",
1231
+ message: "Scope name:",
1232
+ validate: (value) => {
1233
+ if (!value) return "Name is required";
1234
+ if (existingNames.includes(value)) return `Scope "${value}" already exists`;
1235
+ const validation = validateScopeName(value, reservedNames);
1236
+ if (!validation.valid) {
1237
+ return validation.error + (validation.suggestion ? ` Try: ${validation.suggestion}` : "");
1238
+ }
1239
+ return true;
1240
+ }
1241
+ },
1242
+ {
1243
+ type: "text",
1244
+ name: "description",
1245
+ message: "Description:",
1246
+ validate: (value) => value ? true : "Description is required"
1247
+ },
1248
+ {
1249
+ type: "multiselect",
1250
+ name: "allowedTypes",
1251
+ message: "Allowed commit types (space to select, enter to continue):",
1252
+ choices: [
1253
+ { title: "feat", value: "feat", selected: true },
1254
+ { title: "fix", value: "fix", selected: true },
1255
+ { title: "docs", value: "docs", selected: false },
1256
+ { title: "style", value: "style", selected: false },
1257
+ { title: "refactor", value: "refactor", selected: false },
1258
+ { title: "perf", value: "perf", selected: false },
1259
+ { title: "test", value: "test", selected: false },
1260
+ { title: "build", value: "build", selected: false },
1261
+ { title: "ci", value: "ci", selected: false },
1262
+ { title: "chore", value: "chore", selected: false },
1263
+ { title: "revert", value: "revert", selected: false }
1264
+ ],
1265
+ min: 1
1266
+ },
1267
+ {
1268
+ type: "text",
1269
+ name: "mandatoryGuidelines",
1270
+ message: "Mandatory guidelines (comma-separated, or press enter to skip):",
1271
+ initial: ""
1272
+ }
1273
+ ]);
1274
+ if (!response.name) {
1275
+ console.log(chalk3.yellow("Cancelled"));
1276
+ process.exit(0);
1277
+ }
1278
+ if (!opts.force) {
1279
+ const validation = validateScopeName(response.name, reservedNames);
1280
+ if (!validation.valid) {
1281
+ console.error(chalk3.red(`
1282
+ \u2717 ${validation.error}`));
1283
+ if (validation.suggestion) {
1284
+ console.log(chalk3.yellow(`\u{1F4A1} Suggestion: ${validation.suggestion}`));
1285
+ }
1286
+ console.log(chalk3.gray("\nUse --force to override this check"));
1287
+ process.exit(1);
1288
+ }
1289
+ }
1290
+ const newScope = {
1291
+ name: response.name,
1292
+ description: response.description,
1293
+ allowedTypes: response.allowedTypes
1294
+ };
1295
+ if (response.mandatoryGuidelines) {
1296
+ const guidelines = response.mandatoryGuidelines.split(",").map((g) => g.trim()).filter((g) => g.length > 0);
1297
+ if (guidelines.length > 0) {
1298
+ newScope.mandatoryGuidelines = guidelines;
1299
+ }
1300
+ }
1301
+ config.scopes.push(newScope);
1302
+ const configContent = JSON.stringify(config, null, 2) + "\n";
1303
+ writeFileSync(configPath, configContent, "utf-8");
1304
+ console.log(chalk3.green(`
1305
+ \u2713 Added scope: ${response.name}`));
1306
+ console.log(chalk3.gray(` Description: ${response.description}`));
1307
+ console.log(chalk3.gray(` Types: ${response.allowedTypes.join(", ")}`));
1308
+ if (newScope.mandatoryGuidelines) {
1309
+ console.log(chalk3.gray(` Guidelines: ${newScope.mandatoryGuidelines.join(", ")}`));
1310
+ }
1311
+ }
1312
+ async function removeScopeAction(name, opts) {
1313
+ const cwd = opts.cwd || process.cwd();
1314
+ const configPath = join5(cwd, "workflow.config.json");
1315
+ if (!existsSync5(configPath)) {
1316
+ console.error(chalk3.red("No workflow.config.json found"));
1317
+ process.exit(1);
1318
+ }
1319
+ const config = await loadConfig(cwd);
1320
+ if (!config) {
1321
+ console.error(chalk3.red("Failed to load configuration"));
1322
+ process.exit(1);
1323
+ }
1324
+ const scopeIndex = config.scopes.findIndex((s) => s.name === name);
1325
+ if (scopeIndex === -1) {
1326
+ console.error(chalk3.red(`Scope "${name}" not found`));
1327
+ process.exit(1);
1328
+ }
1329
+ const response = await prompts({
1330
+ type: "confirm",
1331
+ name: "confirmed",
1332
+ message: `Remove scope "${name}"?`,
1333
+ initial: false
1334
+ });
1335
+ if (!response.confirmed) {
1336
+ console.log(chalk3.yellow("Cancelled"));
1337
+ process.exit(0);
1338
+ }
1339
+ config.scopes.splice(scopeIndex, 1);
1340
+ const configContent = JSON.stringify(config, null, 2) + "\n";
1341
+ writeFileSync(configPath, configContent, "utf-8");
1342
+ console.log(chalk3.green(`\u2713 Removed scope: ${name}`));
1343
+ }
1344
+ async function listConfigAction(type, opts) {
1345
+ const cwd = opts.cwd || process.cwd();
1346
+ const config = await loadConfig(cwd);
1347
+ if (!config) {
1348
+ console.error(chalk3.red("No configuration found"));
1349
+ process.exit(1);
1350
+ }
1351
+ if (type === "scopes" || type === "all") {
1352
+ console.log(chalk3.blue("\n\u{1F4CB} Scopes:"));
1353
+ if (config.scopes.length === 0) {
1354
+ console.log(chalk3.gray(" (none)"));
1355
+ } else {
1356
+ config.scopes.forEach((scope, index) => {
1357
+ console.log(chalk3.green(`
1358
+ ${index + 1}. ${scope.name}`));
1359
+ console.log(chalk3.gray(` ${scope.description}`));
1360
+ console.log(chalk3.gray(` Types: ${scope.allowedTypes.join(", ")}`));
1361
+ if (scope.mandatoryGuidelines && scope.mandatoryGuidelines.length > 0) {
1362
+ console.log(chalk3.gray(` Guidelines: ${scope.mandatoryGuidelines.join(", ")}`));
1363
+ }
1364
+ });
1365
+ }
1366
+ }
1367
+ if (type === "reserved" || type === "all") {
1368
+ const reserved = config.reservedScopeNames || DEFAULT_RESERVED_SCOPE_NAMES;
1369
+ console.log(chalk3.blue("\n\u{1F6AB} Reserved Scope Names:"));
1370
+ console.log(chalk3.gray(` ${reserved.join(", ")}`));
1371
+ console.log(chalk3.gray('\n \u{1F4A1} Configure in workflow.config.json: "reservedScopeNames"'));
1372
+ }
1373
+ }
1374
+ async function getConfigValue(path2, opts) {
1375
+ const cwd = opts.cwd || process.cwd();
1376
+ const config = await loadConfig(cwd);
1377
+ if (!config) {
1378
+ console.error(chalk3.red("No configuration found"));
1379
+ process.exit(1);
1380
+ }
1381
+ const value = resolvePath(config, path2);
1382
+ if (value === void 0) {
1383
+ console.error(chalk3.red(`Path not found: ${path2}`));
1384
+ process.exit(1);
1385
+ }
1386
+ console.log(JSON.stringify(value, null, 2));
1387
+ }
1388
+ async function setConfigValue(path2, value, opts) {
1389
+ const cwd = opts.cwd || process.cwd();
1390
+ const configPath = join5(cwd, "workflow.config.json");
1391
+ if (!existsSync5(configPath)) {
1392
+ console.error(chalk3.red("No workflow.config.json found"));
1393
+ process.exit(1);
1394
+ }
1395
+ const config = await loadConfig(cwd);
1396
+ if (!config) {
1397
+ console.error(chalk3.red("Failed to load configuration"));
1398
+ process.exit(1);
1399
+ }
1400
+ let parsedValue;
1401
+ try {
1402
+ parsedValue = JSON.parse(value);
1403
+ } catch {
1404
+ parsedValue = value;
1405
+ }
1406
+ setPath(config, path2, parsedValue);
1407
+ if (!opts.force) {
1408
+ const validation = await validateConfig(cwd);
1409
+ if (!validation.valid) {
1410
+ console.error(chalk3.red("\u2717 Invalid configuration after change:"));
1411
+ validation.errors.forEach((err) => console.error(chalk3.red(` \u2022 ${err}`)));
1412
+ console.log(chalk3.gray("\nUse --force to skip validation"));
1413
+ process.exit(1);
1414
+ }
1415
+ }
1416
+ const configContent = JSON.stringify(config, null, 2) + "\n";
1417
+ writeFileSync(configPath, configContent, "utf-8");
1418
+ console.log(chalk3.green(`\u2713 Set ${path2} = ${JSON.stringify(parsedValue)}`));
1419
+ }
1420
+ function resolvePath(obj, path2) {
1421
+ const parts = path2.split(/[\.\[\]]+/).filter(Boolean);
1422
+ let current = obj;
1423
+ for (const part of parts) {
1424
+ if (current === void 0 || current === null) {
1425
+ return void 0;
1426
+ }
1427
+ current = current[part];
1428
+ }
1429
+ return current;
1430
+ }
1431
+ function setPath(obj, path2, value) {
1432
+ const parts = path2.split(/[\.\[\]]+/).filter(Boolean);
1433
+ let current = obj;
1434
+ for (let i = 0; i < parts.length - 1; i++) {
1435
+ const part = parts[i];
1436
+ if (current[part] === void 0) {
1437
+ current[part] = {};
1438
+ }
1439
+ current = current[part];
1440
+ }
1441
+ current[parts[parts.length - 1]] = value;
1148
1442
  }
1149
1443
 
1150
1444
  // src/cli/commands/suggest.ts
@@ -1192,9 +1486,9 @@ async function suggestCommand(feedback, options = {}) {
1192
1486
  import chalk5 from "chalk";
1193
1487
 
1194
1488
  // src/validators/guidelines.ts
1195
- import { existsSync as existsSync5 } from "fs";
1489
+ import { existsSync as existsSync6 } from "fs";
1196
1490
  import { readFile as readFile3, readdir } from "fs/promises";
1197
- import { join as join5 } from "path";
1491
+ import { join as join6 } from "path";
1198
1492
  function getEffectiveMandatoryTemplates(guidelinesConfig) {
1199
1493
  const coreMandatory = getMandatoryTemplateFilenames();
1200
1494
  if (!guidelinesConfig) {
@@ -1214,7 +1508,7 @@ function getEffectiveMandatoryTemplates(guidelinesConfig) {
1214
1508
  return mandatory;
1215
1509
  }
1216
1510
  async function validateGuidelinesExist(projectPath = process.cwd(), config) {
1217
- const guidelinesDir = join5(projectPath, "guidelines");
1511
+ const guidelinesDir = join6(projectPath, "guidelines");
1218
1512
  const result = {
1219
1513
  valid: true,
1220
1514
  missingMandatory: [],
@@ -1222,7 +1516,7 @@ async function validateGuidelinesExist(projectPath = process.cwd(), config) {
1222
1516
  presentOptional: [],
1223
1517
  errors: []
1224
1518
  };
1225
- if (!existsSync5(guidelinesDir)) {
1519
+ if (!existsSync6(guidelinesDir)) {
1226
1520
  const mandatory2 = getEffectiveMandatoryTemplates(config?.guidelines);
1227
1521
  result.valid = false;
1228
1522
  result.missingMandatory = mandatory2;
@@ -1260,7 +1554,7 @@ async function validateGuidelinesExist(projectPath = process.cwd(), config) {
1260
1554
  return result;
1261
1555
  }
1262
1556
  async function validateGitHubActionsSetup(projectPath = process.cwd()) {
1263
- const workflowsDir = join5(projectPath, ".github", "workflows");
1557
+ const workflowsDir = join6(projectPath, ".github", "workflows");
1264
1558
  const result = {
1265
1559
  valid: true,
1266
1560
  hasWorkflowFile: false,
@@ -1272,7 +1566,7 @@ async function validateGitHubActionsSetup(projectPath = process.cwd()) {
1272
1566
  errors: [],
1273
1567
  warnings: []
1274
1568
  };
1275
- if (!existsSync5(workflowsDir)) {
1569
+ if (!existsSync6(workflowsDir)) {
1276
1570
  result.valid = false;
1277
1571
  result.errors.push("GitHub Actions workflows directory does not exist. Run: workflow github:setup");
1278
1572
  return result;
@@ -1293,7 +1587,7 @@ async function validateGitHubActionsSetup(projectPath = process.cwd()) {
1293
1587
  return result;
1294
1588
  }
1295
1589
  result.hasWorkflowFile = true;
1296
- const workflowPath = join5(workflowsDir, ciWorkflows[0]);
1590
+ const workflowPath = join6(workflowsDir, ciWorkflows[0]);
1297
1591
  let workflowContent = "";
1298
1592
  try {
1299
1593
  workflowContent = await readFile3(workflowPath, "utf-8");
@@ -1472,8 +1766,8 @@ async function doctorCommand(options = {}) {
1472
1766
  // src/cli/commands/setup.ts
1473
1767
  import * as p3 from "@clack/prompts";
1474
1768
  import chalk6 from "chalk";
1475
- import { readFileSync, writeFileSync, existsSync as existsSync6 } from "fs";
1476
- import { join as join6 } from "path";
1769
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync7 } from "fs";
1770
+ import { join as join7 } from "path";
1477
1771
  var WORKFLOW_SCRIPTS = {
1478
1772
  "workflow:init": "workflow-agent init",
1479
1773
  "workflow:validate": "workflow-agent validate",
@@ -1483,12 +1777,12 @@ var WORKFLOW_SCRIPTS = {
1483
1777
  async function setupCommand() {
1484
1778
  p3.intro(chalk6.bgBlue(" workflow-agent setup "));
1485
1779
  const cwd = process.cwd();
1486
- const packageJsonPath = join6(cwd, "package.json");
1487
- if (!existsSync6(packageJsonPath)) {
1780
+ const packageJsonPath = join7(cwd, "package.json");
1781
+ if (!existsSync7(packageJsonPath)) {
1488
1782
  p3.cancel("No package.json found in current directory");
1489
1783
  process.exit(1);
1490
1784
  }
1491
- const packageJsonContent = readFileSync(packageJsonPath, "utf-8");
1785
+ const packageJsonContent = readFileSync2(packageJsonPath, "utf-8");
1492
1786
  const packageJson = JSON.parse(packageJsonContent);
1493
1787
  if (!packageJson.scripts) {
1494
1788
  packageJson.scripts = {};
@@ -1527,7 +1821,7 @@ async function setupCommand() {
1527
1821
  for (const [scriptName, scriptCommand] of Object.entries(scriptsToAdd)) {
1528
1822
  packageJson.scripts[scriptName] = scriptCommand;
1529
1823
  }
1530
- writeFileSync(
1824
+ writeFileSync2(
1531
1825
  packageJsonPath,
1532
1826
  JSON.stringify(packageJson, null, 2) + "\n",
1533
1827
  "utf-8"
@@ -1541,14 +1835,14 @@ async function setupCommand() {
1541
1835
  // src/cli/commands/scope-create.ts
1542
1836
  import * as p4 from "@clack/prompts";
1543
1837
  import chalk7 from "chalk";
1544
- import { existsSync as existsSync7 } from "fs";
1838
+ import { existsSync as existsSync8 } from "fs";
1545
1839
  import { writeFile as writeFile4, mkdir as mkdir4, readFile as readFile4 } from "fs/promises";
1546
- import { join as join7 } from "path";
1840
+ import { join as join8 } from "path";
1547
1841
  async function scopeCreateCommand(options) {
1548
1842
  console.log(chalk7.bold.cyan("\n\u{1F3A8} Create Custom Scope Package\n"));
1549
1843
  const cwd = process.cwd();
1550
1844
  const isNonInteractive = !!(options.name && options.scopes && options.presetName);
1551
- const isMonorepo2 = existsSync7(join7(cwd, "pnpm-workspace.yaml"));
1845
+ const isMonorepo2 = existsSync8(join8(cwd, "pnpm-workspace.yaml"));
1552
1846
  if (isMonorepo2) {
1553
1847
  console.log(chalk7.dim("\u2713 Detected monorepo workspace\n"));
1554
1848
  }
@@ -1683,7 +1977,7 @@ async function scopeCreateCommand(options) {
1683
1977
  if (options.outputDir) {
1684
1978
  outputDir = options.outputDir;
1685
1979
  } else if (isMonorepo2) {
1686
- outputDir = join7(cwd, "packages", `scopes-${packageName}`);
1980
+ outputDir = join8(cwd, "packages", `scopes-${packageName}`);
1687
1981
  } else {
1688
1982
  const customDir = await p4.text({
1689
1983
  message: "Output directory:",
@@ -1694,9 +1988,9 @@ async function scopeCreateCommand(options) {
1694
1988
  p4.cancel("Operation cancelled");
1695
1989
  process.exit(0);
1696
1990
  }
1697
- outputDir = join7(cwd, customDir);
1991
+ outputDir = join8(cwd, customDir);
1698
1992
  }
1699
- if (existsSync7(outputDir)) {
1993
+ if (existsSync8(outputDir)) {
1700
1994
  const shouldOverwrite = await p4.confirm({
1701
1995
  message: `Directory ${outputDir} already exists. Overwrite?`,
1702
1996
  initialValue: false
@@ -1709,7 +2003,7 @@ async function scopeCreateCommand(options) {
1709
2003
  const spinner5 = p4.spinner();
1710
2004
  spinner5.start("Creating package structure...");
1711
2005
  try {
1712
- await mkdir4(join7(outputDir, "src"), { recursive: true });
2006
+ await mkdir4(join8(outputDir, "src"), { recursive: true });
1713
2007
  const packageJson = {
1714
2008
  name: `@workflow/scopes-${packageName}`,
1715
2009
  version: "1.0.0",
@@ -1750,7 +2044,7 @@ async function scopeCreateCommand(options) {
1750
2044
  }
1751
2045
  };
1752
2046
  await writeFile4(
1753
- join7(outputDir, "package.json"),
2047
+ join8(outputDir, "package.json"),
1754
2048
  JSON.stringify(packageJson, null, 2),
1755
2049
  "utf-8"
1756
2050
  );
@@ -1763,7 +2057,7 @@ async function scopeCreateCommand(options) {
1763
2057
  include: ["src/**/*"]
1764
2058
  };
1765
2059
  await writeFile4(
1766
- join7(outputDir, "tsconfig.json"),
2060
+ join8(outputDir, "tsconfig.json"),
1767
2061
  JSON.stringify(tsconfig, null, 2),
1768
2062
  "utf-8"
1769
2063
  );
@@ -1777,7 +2071,7 @@ export default defineConfig({
1777
2071
  sourcemap: true,
1778
2072
  });
1779
2073
  `;
1780
- await writeFile4(join7(outputDir, "tsup.config.ts"), tsupConfig, "utf-8");
2074
+ await writeFile4(join8(outputDir, "tsup.config.ts"), tsupConfig, "utf-8");
1781
2075
  const indexTs = `import type { Scope } from '@hawkinside_out/workflow-agent/config';
1782
2076
 
1783
2077
  export const scopes: Scope[] = ${JSON.stringify(scopes, null, 2)};
@@ -1791,7 +2085,7 @@ export const preset = {
1791
2085
 
1792
2086
  export default preset;
1793
2087
  `;
1794
- await writeFile4(join7(outputDir, "src", "index.ts"), indexTs, "utf-8");
2088
+ await writeFile4(join8(outputDir, "src", "index.ts"), indexTs, "utf-8");
1795
2089
  if (!options.noTest) {
1796
2090
  const testFile = `import { describe, it, expect } from 'vitest';
1797
2091
  import { scopes, preset } from './index.js';
@@ -1832,11 +2126,11 @@ describe('${presetName} Scope Preset', () => {
1832
2126
  });
1833
2127
  });
1834
2128
  `;
1835
- await writeFile4(join7(outputDir, "src", "index.test.ts"), testFile, "utf-8");
2129
+ await writeFile4(join8(outputDir, "src", "index.test.ts"), testFile, "utf-8");
1836
2130
  }
1837
2131
  spinner5.stop("\u2713 Package structure created");
1838
2132
  if (isMonorepo2) {
1839
- const workspaceFile = join7(cwd, "pnpm-workspace.yaml");
2133
+ const workspaceFile = join8(cwd, "pnpm-workspace.yaml");
1840
2134
  const workspaceContent = await readFile4(workspaceFile, "utf-8");
1841
2135
  const packagePath = `packages/scopes-${packageName}`;
1842
2136
  if (!workspaceContent.includes(packagePath) && !workspaceContent.includes("packages/*")) {
@@ -1881,9 +2175,9 @@ describe('${presetName} Scope Preset', () => {
1881
2175
  // src/cli/commands/scope-migrate.ts
1882
2176
  import * as p5 from "@clack/prompts";
1883
2177
  import chalk8 from "chalk";
1884
- import { existsSync as existsSync8 } from "fs";
2178
+ import { existsSync as existsSync9 } from "fs";
1885
2179
  import { writeFile as writeFile5, mkdir as mkdir5, readFile as readFile5 } from "fs/promises";
1886
- import { join as join8 } from "path";
2180
+ import { join as join9 } from "path";
1887
2181
  async function scopeMigrateCommand(options) {
1888
2182
  console.log(chalk8.bold.cyan("\n\u{1F504} Migrate Scopes to Custom Package\n"));
1889
2183
  const cwd = process.cwd();
@@ -1921,7 +2215,7 @@ async function scopeMigrateCommand(options) {
1921
2215
  p5.cancel("Migration cancelled");
1922
2216
  process.exit(0);
1923
2217
  }
1924
- const isMonorepo2 = existsSync8(join8(cwd, "pnpm-workspace.yaml"));
2218
+ const isMonorepo2 = existsSync9(join9(cwd, "pnpm-workspace.yaml"));
1925
2219
  if (isMonorepo2) {
1926
2220
  console.log(chalk8.dim("\n\u2713 Detected monorepo workspace\n"));
1927
2221
  }
@@ -1967,7 +2261,7 @@ async function scopeMigrateCommand(options) {
1967
2261
  if (options.outputDir) {
1968
2262
  outputDir = options.outputDir;
1969
2263
  } else if (isMonorepo2) {
1970
- outputDir = join8(cwd, "packages", `scopes-${packageName}`);
2264
+ outputDir = join9(cwd, "packages", `scopes-${packageName}`);
1971
2265
  } else {
1972
2266
  const customDir = await p5.text({
1973
2267
  message: "Output directory:",
@@ -1978,9 +2272,9 @@ async function scopeMigrateCommand(options) {
1978
2272
  p5.cancel("Migration cancelled");
1979
2273
  process.exit(0);
1980
2274
  }
1981
- outputDir = join8(cwd, customDir);
2275
+ outputDir = join9(cwd, customDir);
1982
2276
  }
1983
- if (existsSync8(outputDir)) {
2277
+ if (existsSync9(outputDir)) {
1984
2278
  const shouldOverwrite = await p5.confirm({
1985
2279
  message: `Directory ${outputDir} already exists. Overwrite?`,
1986
2280
  initialValue: false
@@ -1993,7 +2287,7 @@ async function scopeMigrateCommand(options) {
1993
2287
  const spinner5 = p5.spinner();
1994
2288
  spinner5.start("Migrating scopes to package...");
1995
2289
  try {
1996
- await mkdir5(join8(outputDir, "src"), { recursive: true });
2290
+ await mkdir5(join9(outputDir, "src"), { recursive: true });
1997
2291
  const packageJson = {
1998
2292
  name: `@workflow/scopes-${packageName}`,
1999
2293
  version: "1.0.0",
@@ -2034,7 +2328,7 @@ async function scopeMigrateCommand(options) {
2034
2328
  }
2035
2329
  };
2036
2330
  await writeFile5(
2037
- join8(outputDir, "package.json"),
2331
+ join9(outputDir, "package.json"),
2038
2332
  JSON.stringify(packageJson, null, 2),
2039
2333
  "utf-8"
2040
2334
  );
@@ -2047,7 +2341,7 @@ async function scopeMigrateCommand(options) {
2047
2341
  include: ["src/**/*"]
2048
2342
  };
2049
2343
  await writeFile5(
2050
- join8(outputDir, "tsconfig.json"),
2344
+ join9(outputDir, "tsconfig.json"),
2051
2345
  JSON.stringify(tsconfig, null, 2),
2052
2346
  "utf-8"
2053
2347
  );
@@ -2061,7 +2355,7 @@ export default defineConfig({
2061
2355
  sourcemap: true,
2062
2356
  });
2063
2357
  `;
2064
- await writeFile5(join8(outputDir, "tsup.config.ts"), tsupConfig, "utf-8");
2358
+ await writeFile5(join9(outputDir, "tsup.config.ts"), tsupConfig, "utf-8");
2065
2359
  const indexTs = `import type { Scope } from '@hawkinside_out/workflow-agent/config';
2066
2360
 
2067
2361
  export const scopes: Scope[] = ${JSON.stringify(config.scopes, null, 2)};
@@ -2075,7 +2369,7 @@ export const preset = {
2075
2369
 
2076
2370
  export default preset;
2077
2371
  `;
2078
- await writeFile5(join8(outputDir, "src", "index.ts"), indexTs, "utf-8");
2372
+ await writeFile5(join9(outputDir, "src", "index.ts"), indexTs, "utf-8");
2079
2373
  const testFile = `import { describe, it, expect } from 'vitest';
2080
2374
  import { scopes, preset } from './index.js';
2081
2375
  import { ScopeSchema } from '@hawkinside_out/workflow-agent/config';
@@ -2118,10 +2412,10 @@ describe('${presetName} Scope Preset (Migrated)', () => {
2118
2412
  });
2119
2413
  });
2120
2414
  `;
2121
- await writeFile5(join8(outputDir, "src", "index.test.ts"), testFile, "utf-8");
2415
+ await writeFile5(join9(outputDir, "src", "index.test.ts"), testFile, "utf-8");
2122
2416
  spinner5.stop("\u2713 Package created from migrated scopes");
2123
2417
  if (isMonorepo2) {
2124
- const workspaceFile = join8(cwd, "pnpm-workspace.yaml");
2418
+ const workspaceFile = join9(cwd, "pnpm-workspace.yaml");
2125
2419
  const workspaceContent = await readFile5(workspaceFile, "utf-8");
2126
2420
  const packagePath = `packages/scopes-${packageName}`;
2127
2421
  if (!workspaceContent.includes(packagePath) && !workspaceContent.includes("packages/*")) {
@@ -2136,7 +2430,7 @@ describe('${presetName} Scope Preset (Migrated)', () => {
2136
2430
  initialValue: false
2137
2431
  });
2138
2432
  if (!p5.isCancel(keepConfig) && !keepConfig) {
2139
- const configPath = join8(cwd, "workflow.config.json");
2433
+ const configPath = join9(cwd, "workflow.config.json");
2140
2434
  const updatedConfig = {
2141
2435
  ...config,
2142
2436
  scopes: [],
@@ -2415,11 +2709,11 @@ async function checkAction(cwd) {
2415
2709
  }
2416
2710
 
2417
2711
  // src/cli/index.ts
2418
- var program = new Command();
2712
+ var program = new Command2();
2419
2713
  program.name("workflow").description("A self-evolving workflow management system for AI agent development").version("1.0.0");
2420
2714
  program.command("init").description("Initialize workflow in current project").option("--migrate", "Auto-detect existing patterns and migrate").option("--workspace", "Initialize for multiple repositories").option("--preset <preset>", "Preset to use (saas, library, api, ecommerce, cms, custom)").option("--name <name>", "Project name").option("-y, --yes", "Skip confirmation prompts").action(initCommand);
2421
2715
  program.command("validate <type>").description("Validate branch name, commit message, or PR title").argument("<type>", "What to validate: branch, commit, or pr").argument("[value]", "Value to validate (defaults to current branch/HEAD commit)").option("--suggest-on-error", "Offer improvement suggestions on validation errors").action(validateCommand);
2422
- 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);
2716
+ program.addCommand(createConfigCommand());
2423
2717
  program.command("suggest").description("Submit an improvement suggestion").argument("<feedback>", "Your improvement suggestion").option("--author <author>", "Your name or username").option("--category <category>", "Category: feature, bug, documentation, performance, other").action(suggestCommand);
2424
2718
  program.command("setup").description("Add workflow scripts to package.json").action(setupCommand);
2425
2719
  program.command("doctor").description("Run health check and get optimization suggestions").option("--check-guidelines-only", "Only check mandatory guidelines exist (exits 0 or 1)").action(doctorCommand);