@ncoderz/awa 1.8.1 → 1.8.3

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/index.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  renumberCommand,
11
11
  scan,
12
12
  scanMarkers
13
- } from "./chunk-EL7ZWFXO.js";
13
+ } from "./chunk-2VUVSW6T.js";
14
14
  import {
15
15
  ConfigError,
16
16
  DiffError,
@@ -28,7 +28,7 @@ import {
28
28
  rmDir,
29
29
  walkDirectory,
30
30
  writeTextFile
31
- } from "./chunk-LRQWZCYL.js";
31
+ } from "./chunk-GOIBZQFJ.js";
32
32
 
33
33
  // src/cli/index.ts
34
34
  import { Command, Option } from "commander";
@@ -36,7 +36,7 @@ import { Command, Option } from "commander";
36
36
  // src/_generated/package_info.ts
37
37
  var PACKAGE_INFO = {
38
38
  "name": "@ncoderz/awa",
39
- "version": "1.8.1",
39
+ "version": "1.8.3",
40
40
  "author": "Richard Sewell <richard.sewell@ncoderz.com>",
41
41
  "license": "BSD-3-Clause",
42
42
  "description": "awa is an Agent Workflow for AIs. It is also a CLI tool to powerfully manage agent workflow files using templates."
@@ -1820,11 +1820,19 @@ function buildCheckConfig(fileConfig, cliOptions) {
1820
1820
  const allowWarnings = cliOptions.allowWarnings === true ? true : typeof section?.["allow-warnings"] === "boolean" ? section["allow-warnings"] : DEFAULT_CHECK_CONFIG.allowWarnings;
1821
1821
  const specOnly = cliOptions.specOnly === true ? true : typeof section?.["spec-only"] === "boolean" ? section["spec-only"] : DEFAULT_CHECK_CONFIG.specOnly;
1822
1822
  const fix = cliOptions.fix === false ? false : DEFAULT_CHECK_CONFIG.fix;
1823
+ const extraSpecGlobs = toStringArray(section?.["extra-spec-globs"]) ?? [
1824
+ ...DEFAULT_CHECK_CONFIG.extraSpecGlobs
1825
+ ];
1826
+ const extraSpecIgnore = toStringArray(section?.["extra-spec-ignore"]) ?? [
1827
+ ...DEFAULT_CHECK_CONFIG.extraSpecIgnore
1828
+ ];
1823
1829
  return {
1824
1830
  specGlobs,
1825
1831
  codeGlobs,
1826
1832
  specIgnore,
1827
1833
  codeIgnore,
1834
+ extraSpecGlobs,
1835
+ extraSpecIgnore,
1828
1836
  ignoreMarkers,
1829
1837
  markers,
1830
1838
  idPattern,
@@ -3548,18 +3556,18 @@ async function executeRenames(renames, sourceCode, targetCode, dryRun) {
3548
3556
  }
3549
3557
  return renames;
3550
3558
  }
3551
- async function findStaleRefs(sourceCode, specFiles) {
3559
+ async function findStaleRefs(sourceCode, filePaths) {
3552
3560
  const stale = [];
3553
3561
  const pattern = new RegExp(`\\b${sourceCode}-\\d`, "g");
3554
- for (const sf of specFiles) {
3562
+ for (const filePath of filePaths) {
3555
3563
  let content;
3556
3564
  try {
3557
- content = await readFile8(sf.filePath, "utf-8");
3565
+ content = await readFile8(filePath, "utf-8");
3558
3566
  } catch {
3559
3567
  continue;
3560
3568
  }
3561
3569
  if (pattern.test(content)) {
3562
- stale.push(sf.filePath);
3570
+ stale.push(filePath);
3563
3571
  }
3564
3572
  pattern.lastIndex = 0;
3565
3573
  }
@@ -3716,7 +3724,7 @@ function findHighestPropertyNumber(designFiles) {
3716
3724
  async function mergeCommand(options) {
3717
3725
  try {
3718
3726
  validateMerge(options.sourceCode, options.targetCode);
3719
- const { markers, specs } = await scan(options.config);
3727
+ const { markers, specs, config } = await scan(options.config);
3720
3728
  const dryRun = options.dryRun === true;
3721
3729
  if (!hasAnySpecFile(specs.specFiles, options.targetCode)) {
3722
3730
  throw new MergeError(
@@ -3732,7 +3740,7 @@ async function mergeCommand(options) {
3732
3740
  let affectedFiles = [];
3733
3741
  let totalReplacements = 0;
3734
3742
  if (!recodeNoChange) {
3735
- const result2 = await propagate(map, specs, markers, dryRun);
3743
+ const result2 = await propagate(map, specs, markers, config, dryRun);
3736
3744
  affectedFiles = result2.affectedFiles;
3737
3745
  totalReplacements = result2.totalReplacements;
3738
3746
  }
@@ -3744,10 +3752,13 @@ async function mergeCommand(options) {
3744
3752
  );
3745
3753
  const movedSourcePaths = new Set(moves.map((m) => m.sourceFile));
3746
3754
  const propagatedPaths = new Set(affectedFiles.map((af) => af.filePath));
3747
- const nonSourceFiles = specs.specFiles.filter(
3748
- (sf) => !movedSourcePaths.has(sf.filePath) && !propagatedPaths.has(sf.filePath)
3755
+ const specFilePaths = specs.specFiles.map((sf) => sf.filePath);
3756
+ const combinedIgnore = [...config.specIgnore, ...config.extraSpecIgnore];
3757
+ const extraFiles = await collectFiles(config.extraSpecGlobs, combinedIgnore);
3758
+ const allFiles = [.../* @__PURE__ */ new Set([...specFilePaths, ...extraFiles])].filter(
3759
+ (p) => !movedSourcePaths.has(p) && !propagatedPaths.has(p)
3749
3760
  );
3750
- const staleRefs = await findStaleRefs(options.sourceCode, nonSourceFiles);
3761
+ const staleRefs = await findStaleRefs(options.sourceCode, allFiles);
3751
3762
  const noChange = recodeNoChange && moves.length === 0;
3752
3763
  const result = {
3753
3764
  sourceCode: options.sourceCode,
@@ -3764,7 +3775,7 @@ async function mergeCommand(options) {
3764
3775
  return 2;
3765
3776
  }
3766
3777
  if (options.renumber && !dryRun && !noChange) {
3767
- const { renumberCommand: renumberCommand2 } = await import("./renumber-TLBGOWZM.js");
3778
+ const { renumberCommand: renumberCommand2 } = await import("./renumber-TGDI47IS.js");
3768
3779
  await renumberCommand2({
3769
3780
  code: options.targetCode,
3770
3781
  dryRun: false,
@@ -3872,7 +3883,7 @@ function formatJson3(result) {
3872
3883
  // src/commands/recode.ts
3873
3884
  async function recodeCommand(options) {
3874
3885
  try {
3875
- const { markers, specs } = await scan(options.config);
3886
+ const { markers, specs, config } = await scan(options.config);
3876
3887
  const dryRun = options.dryRun === true;
3877
3888
  const { map, noChange: recodeNoChange } = buildRecodeMap(
3878
3889
  options.sourceCode,
@@ -3882,7 +3893,7 @@ async function recodeCommand(options) {
3882
3893
  let affectedFiles = [];
3883
3894
  let totalReplacements = 0;
3884
3895
  if (!recodeNoChange) {
3885
- const result2 = await propagate(map, specs, markers, dryRun);
3896
+ const result2 = await propagate(map, specs, markers, config, dryRun);
3886
3897
  affectedFiles = result2.affectedFiles;
3887
3898
  totalReplacements = result2.totalReplacements;
3888
3899
  }
@@ -3895,11 +3906,15 @@ async function recodeCommand(options) {
3895
3906
  );
3896
3907
  }
3897
3908
  await executeRenames(renames, options.sourceCode, options.targetCode, dryRun);
3909
+ const renamedPaths = new Set(renames.map((r) => r.oldPath));
3898
3910
  const propagatedPaths = new Set(affectedFiles.map((af) => af.filePath));
3899
- const nonSourceFiles = specs.specFiles.filter(
3900
- (sf) => !renames.some((r) => r.oldPath === sf.filePath) && !propagatedPaths.has(sf.filePath)
3911
+ const specFilePaths = specs.specFiles.map((sf) => sf.filePath);
3912
+ const combinedIgnore = [...config.specIgnore, ...config.extraSpecIgnore];
3913
+ const extraFiles = await collectFiles(config.extraSpecGlobs, combinedIgnore);
3914
+ const allFiles = [.../* @__PURE__ */ new Set([...specFilePaths, ...extraFiles])].filter(
3915
+ (p) => !renamedPaths.has(p) && !propagatedPaths.has(p)
3901
3916
  );
3902
- const staleRefs = await findStaleRefs(options.sourceCode, nonSourceFiles);
3917
+ const staleRefs = await findStaleRefs(options.sourceCode, allFiles);
3903
3918
  const noChange = recodeNoChange && renames.length === 0;
3904
3919
  const result = {
3905
3920
  sourceCode: options.sourceCode,
@@ -5393,6 +5408,15 @@ async function writeCache(latestVersion) {
5393
5408
  }
5394
5409
  }
5395
5410
 
5411
+ // src/cli/option-source.ts
5412
+ function cliProvidedOption(command, options, key) {
5413
+ const source = command.getOptionValueSource(key);
5414
+ if (source === "cli" || source === "env") {
5415
+ return options[key];
5416
+ }
5417
+ return void 0;
5418
+ }
5419
+
5396
5420
  // src/cli/index.ts
5397
5421
  var version = PACKAGE_INFO.version;
5398
5422
  var program = new Command();
@@ -5411,24 +5435,25 @@ function configureGenerateCommand(cmd) {
5411
5435
  ).option("-c, --config <path>", "Path to configuration file").option("--refresh", "Force refresh of cached Git templates", false).option("--all-targets", "Process all named targets from config", false).option("--target <name>", "Process a specific named target from config").option(
5412
5436
  "--overlay <path...>",
5413
5437
  "Overlay directory paths applied over base template (repeatable)"
5414
- ).option("--json", "Output results as JSON (implies --dry-run)", false).option("--summary", "Output compact one-line summary", false).action(async (output, options) => {
5438
+ ).option("--json", "Output results as JSON (implies --dry-run)", false).option("--summary", "Output compact one-line summary", false).action(async (output, options, command) => {
5439
+ const allTargets = cliProvidedOption(command, options, "allTargets");
5415
5440
  const cliOptions = {
5416
5441
  output,
5417
- template: options.template,
5418
- features: options.features,
5419
- preset: options.preset,
5420
- removeFeatures: options.removeFeatures,
5421
- force: options.force,
5422
- dryRun: options.dryRun,
5423
- delete: options.delete,
5424
- config: options.config,
5425
- refresh: options.refresh,
5426
- all: options.allTargets,
5427
- allTargets: options.allTargets,
5428
- target: options.target,
5429
- overlay: options.overlay || [],
5430
- json: options.json,
5431
- summary: options.summary
5442
+ template: cliProvidedOption(command, options, "template"),
5443
+ features: cliProvidedOption(command, options, "features"),
5444
+ preset: cliProvidedOption(command, options, "preset"),
5445
+ removeFeatures: cliProvidedOption(command, options, "removeFeatures"),
5446
+ force: cliProvidedOption(command, options, "force"),
5447
+ dryRun: cliProvidedOption(command, options, "dryRun"),
5448
+ delete: cliProvidedOption(command, options, "delete"),
5449
+ config: cliProvidedOption(command, options, "config"),
5450
+ refresh: cliProvidedOption(command, options, "refresh"),
5451
+ all: allTargets,
5452
+ allTargets,
5453
+ target: cliProvidedOption(command, options, "target"),
5454
+ overlay: cliProvidedOption(command, options, "overlay"),
5455
+ json: cliProvidedOption(command, options, "json"),
5456
+ summary: cliProvidedOption(command, options, "summary")
5432
5457
  };
5433
5458
  await generateCommand(cliOptions);
5434
5459
  });
@@ -5438,24 +5463,25 @@ configureGenerateCommand(program.command("init"));
5438
5463
  template.command("diff").description("Compare template output with existing target directory").argument("[target]", "Target directory to compare against (optional if specified in config)").option("-t, --template <source>", "Template source (local path or Git repository)").option("-f, --features <flag...>", "Feature flags (can be specified multiple times)").option("--preset <name...>", "Preset names to enable (can be specified multiple times)").option(
5439
5464
  "--remove-features <flag...>",
5440
5465
  "Feature flags to remove (can be specified multiple times)"
5441
- ).option("-c, --config <path>", "Path to configuration file").option("--refresh", "Force refresh of cached Git templates", false).option("--list-unknown", "Include target-only files in diff results", false).option("--all-targets", "Process all named targets from config", false).option("--target <name>", "Process a specific named target from config").option("-w, --watch", "Watch template directory for changes and re-run diff", false).option("--overlay <path...>", "Overlay directory paths applied over base template (repeatable)").option("--json", "Output results as JSON", false).option("--summary", "Output compact one-line summary", false).action(async (target, options) => {
5466
+ ).option("-c, --config <path>", "Path to configuration file").option("--refresh", "Force refresh of cached Git templates", false).option("--list-unknown", "Include target-only files in diff results", false).option("--all-targets", "Process all named targets from config", false).option("--target <name>", "Process a specific named target from config").option("-w, --watch", "Watch template directory for changes and re-run diff", false).option("--overlay <path...>", "Overlay directory paths applied over base template (repeatable)").option("--json", "Output results as JSON", false).option("--summary", "Output compact one-line summary", false).action(async (target, options, command) => {
5467
+ const allTargets = cliProvidedOption(command, options, "allTargets");
5442
5468
  const cliOptions = {
5443
5469
  output: target,
5444
5470
  // Use target as output for consistency
5445
- template: options.template,
5446
- features: options.features,
5447
- preset: options.preset,
5448
- removeFeatures: options.removeFeatures,
5449
- config: options.config,
5450
- refresh: options.refresh,
5451
- listUnknown: options.listUnknown,
5452
- all: options.allTargets,
5453
- allTargets: options.allTargets,
5454
- target: options.target,
5455
- watch: options.watch,
5456
- overlay: options.overlay || [],
5457
- json: options.json,
5458
- summary: options.summary
5471
+ template: cliProvidedOption(command, options, "template"),
5472
+ features: cliProvidedOption(command, options, "features"),
5473
+ preset: cliProvidedOption(command, options, "preset"),
5474
+ removeFeatures: cliProvidedOption(command, options, "removeFeatures"),
5475
+ config: cliProvidedOption(command, options, "config"),
5476
+ refresh: cliProvidedOption(command, options, "refresh"),
5477
+ listUnknown: cliProvidedOption(command, options, "listUnknown"),
5478
+ all: allTargets,
5479
+ allTargets,
5480
+ target: cliProvidedOption(command, options, "target"),
5481
+ watch: cliProvidedOption(command, options, "watch"),
5482
+ overlay: cliProvidedOption(command, options, "overlay"),
5483
+ json: cliProvidedOption(command, options, "json"),
5484
+ summary: cliProvidedOption(command, options, "summary")
5459
5485
  };
5460
5486
  const exitCode = await diffCommand(cliOptions);
5461
5487
  process.exit(exitCode);
@@ -5475,41 +5501,41 @@ program.command("check").description(
5475
5501
  ).option(
5476
5502
  "--no-fix",
5477
5503
  "Skip regeneration of Requirements Traceability sections in DESIGN and TASK files"
5478
- ).action(async (options) => {
5504
+ ).action(async (options, command) => {
5479
5505
  const cliOptions = {
5480
- config: options.config,
5481
- specIgnore: options.specIgnore,
5482
- codeIgnore: options.codeIgnore,
5483
- format: options.format,
5484
- json: options.json,
5485
- summary: options.summary,
5486
- allowWarnings: options.allowWarnings,
5487
- specOnly: options.specOnly,
5488
- fix: options.fix
5506
+ config: cliProvidedOption(command, options, "config"),
5507
+ specIgnore: cliProvidedOption(command, options, "specIgnore"),
5508
+ codeIgnore: cliProvidedOption(command, options, "codeIgnore"),
5509
+ format: cliProvidedOption(command, options, "format"),
5510
+ json: cliProvidedOption(command, options, "json"),
5511
+ summary: cliProvidedOption(command, options, "summary"),
5512
+ allowWarnings: cliProvidedOption(command, options, "allowWarnings"),
5513
+ specOnly: cliProvidedOption(command, options, "specOnly"),
5514
+ fix: cliProvidedOption(command, options, "fix")
5489
5515
  };
5490
5516
  const exitCode = await checkCommand(cliOptions);
5491
5517
  process.exit(exitCode);
5492
5518
  });
5493
- template.command("features").description("Discover feature flags available in a template").option("-t, --template <source>", "Template source (local path or Git repository)").option("-c, --config <path>", "Path to configuration file").option("--refresh", "Force refresh of cached Git templates", false).option("--overlay <path...>", "Overlay directory paths applied over base template (repeatable)").option("--json", "Output results as JSON", false).option("--summary", "Output compact one-line summary", false).action(async (options) => {
5519
+ template.command("features").description("Discover feature flags available in a template").option("-t, --template <source>", "Template source (local path or Git repository)").option("-c, --config <path>", "Path to configuration file").option("--refresh", "Force refresh of cached Git templates", false).option("--overlay <path...>", "Overlay directory paths applied over base template (repeatable)").option("--json", "Output results as JSON", false).option("--summary", "Output compact one-line summary", false).action(async (options, command) => {
5494
5520
  const exitCode = await featuresCommand({
5495
- template: options.template,
5496
- config: options.config,
5497
- refresh: options.refresh,
5498
- json: options.json,
5499
- summary: options.summary,
5500
- overlay: options.overlay || []
5521
+ template: cliProvidedOption(command, options, "template"),
5522
+ config: cliProvidedOption(command, options, "config"),
5523
+ refresh: cliProvidedOption(command, options, "refresh"),
5524
+ json: cliProvidedOption(command, options, "json"),
5525
+ summary: cliProvidedOption(command, options, "summary"),
5526
+ overlay: cliProvidedOption(command, options, "overlay")
5501
5527
  });
5502
5528
  process.exit(exitCode);
5503
5529
  });
5504
- template.command("test").description("Run template test fixtures to verify expected output").option("-t, --template <source>", "Template source (local path or Git repository)").option("-c, --config <path>", "Path to configuration file").option("--update-snapshots", "Update stored snapshots with current rendered output", false).option("--refresh", "Force refresh of cached Git templates", false).option("--overlay <path...>", "Overlay directory paths applied over base template (repeatable)").option("--json", "Output results as JSON", false).option("--summary", "Output compact one-line summary", false).action(async (options) => {
5530
+ template.command("test").description("Run template test fixtures to verify expected output").option("-t, --template <source>", "Template source (local path or Git repository)").option("-c, --config <path>", "Path to configuration file").option("--update-snapshots", "Update stored snapshots with current rendered output", false).option("--refresh", "Force refresh of cached Git templates", false).option("--overlay <path...>", "Overlay directory paths applied over base template (repeatable)").option("--json", "Output results as JSON", false).option("--summary", "Output compact one-line summary", false).action(async (options, command) => {
5505
5531
  const testOptions = {
5506
- template: options.template,
5507
- config: options.config,
5508
- updateSnapshots: options.updateSnapshots,
5509
- refresh: options.refresh,
5510
- json: options.json,
5511
- summary: options.summary,
5512
- overlay: options.overlay || []
5532
+ template: cliProvidedOption(command, options, "template"),
5533
+ config: cliProvidedOption(command, options, "config"),
5534
+ updateSnapshots: cliProvidedOption(command, options, "updateSnapshots") ?? false,
5535
+ refresh: cliProvidedOption(command, options, "refresh"),
5536
+ json: cliProvidedOption(command, options, "json"),
5537
+ summary: cliProvidedOption(command, options, "summary"),
5538
+ overlay: cliProvidedOption(command, options, "overlay")
5513
5539
  };
5514
5540
  const exitCode = await testCommand(testOptions);
5515
5541
  process.exit(exitCode);
@@ -5606,7 +5632,7 @@ var isDisabledByEnv = !!process.env.NO_UPDATE_NOTIFIER;
5606
5632
  if (!isJsonOrSummary && isTTY && !isDisabledByEnv) {
5607
5633
  updateCheckPromise = (async () => {
5608
5634
  try {
5609
- const { configLoader: configLoader2 } = await import("./config-EJIXC7D7.js");
5635
+ const { configLoader: configLoader2 } = await import("./config-SJLBJX77.js");
5610
5636
  const configPath = process.argv.indexOf("-c") !== -1 ? process.argv[process.argv.indexOf("-c") + 1] : process.argv.indexOf("--config") !== -1 ? process.argv[process.argv.indexOf("--config") + 1] : void 0;
5611
5637
  const fileConfig = await configLoader2.load(configPath ?? null);
5612
5638
  const updateCheckConfig = fileConfig?.["update-check"];