@ncoderz/awa 1.7.1 → 1.7.2

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
@@ -24,7 +24,7 @@ import { Command, Option } from "commander";
24
24
  // src/_generated/package_info.ts
25
25
  var PACKAGE_INFO = {
26
26
  "name": "@ncoderz/awa",
27
- "version": "1.7.1",
27
+ "version": "1.7.2",
28
28
  "author": "Richard Sewell <richard.sewell@ncoderz.com>",
29
29
  "license": "MIT",
30
30
  "description": "awa is an Agent Workflow for AIs. It is also a CLI tool to powerfully manage agent workflow files using templates."
@@ -340,20 +340,15 @@ async function collectCodeFiles(codeGlobs, ignore) {
340
340
  import { readFile as readFile2, writeFile } from "fs/promises";
341
341
  import { basename } from "path";
342
342
  async function fixMatrices(specs, crossRefPatterns) {
343
- const codeToReqFile = buildCodeToReqFileMap(specs.specFiles);
343
+ const reqFileMaps = buildReqFileMaps(specs.specFiles);
344
344
  const fileResults = [];
345
345
  for (const specFile of specs.specFiles) {
346
346
  const fileName = basename(specFile.filePath);
347
347
  if (fileName.startsWith("DESIGN-")) {
348
- const changed = await fixDesignMatrix(specFile.filePath, codeToReqFile, crossRefPatterns);
348
+ const changed = await fixDesignMatrix(specFile.filePath, reqFileMaps, crossRefPatterns);
349
349
  fileResults.push({ filePath: specFile.filePath, changed });
350
350
  } else if (fileName.startsWith("TASK-")) {
351
- const changed = await fixTaskMatrix(
352
- specFile.filePath,
353
- codeToReqFile,
354
- specs,
355
- crossRefPatterns
356
- );
351
+ const changed = await fixTaskMatrix(specFile.filePath, reqFileMaps, specs, crossRefPatterns);
357
352
  fileResults.push({ filePath: specFile.filePath, changed });
358
353
  }
359
354
  }
@@ -362,20 +357,45 @@ async function fixMatrices(specs, crossRefPatterns) {
362
357
  fileResults
363
358
  };
364
359
  }
365
- function buildCodeToReqFileMap(specFiles) {
366
- const map = /* @__PURE__ */ new Map();
360
+ function buildReqFileMaps(specFiles) {
361
+ const idToReqFile = /* @__PURE__ */ new Map();
362
+ const codeToReqFilesSet = /* @__PURE__ */ new Map();
367
363
  for (const sf of specFiles) {
368
- if (/\bREQ-/.test(basename(sf.filePath)) && sf.code) {
369
- map.set(sf.code, basename(sf.filePath));
364
+ const fileName = basename(sf.filePath);
365
+ if (!/\bREQ-/.test(fileName)) continue;
366
+ for (const reqId of sf.requirementIds) {
367
+ idToReqFile.set(reqId, fileName);
368
+ }
369
+ for (const acId of sf.acIds) {
370
+ idToReqFile.set(acId, fileName);
370
371
  }
372
+ if (sf.code) {
373
+ const existing = codeToReqFilesSet.get(sf.code) ?? /* @__PURE__ */ new Set();
374
+ existing.add(fileName);
375
+ codeToReqFilesSet.set(sf.code, existing);
376
+ }
377
+ }
378
+ const codeToReqFiles = /* @__PURE__ */ new Map();
379
+ for (const [code, files] of codeToReqFilesSet) {
380
+ codeToReqFiles.set(code, [...files].sort());
371
381
  }
372
- return map;
382
+ return { idToReqFile, codeToReqFiles };
373
383
  }
374
- function getCodePrefix(id) {
375
- const match = /^([A-Z][A-Z0-9]*)[-_]/.exec(id);
376
- return match?.[1] ?? "";
384
+ function resolveReqFile(id, maps) {
385
+ const direct = maps.idToReqFile.get(id);
386
+ if (direct) return direct;
387
+ const acMatch = /^(.+)_AC-\d+$/.exec(id);
388
+ if (acMatch?.[1]) {
389
+ return maps.idToReqFile.get(acMatch[1]);
390
+ }
391
+ const propMatch = /^([A-Z][A-Z0-9]*)_P-\d+$/.exec(id);
392
+ if (propMatch?.[1]) {
393
+ const files = maps.codeToReqFiles.get(propMatch[1]);
394
+ return files?.[0];
395
+ }
396
+ return void 0;
377
397
  }
378
- async function fixDesignMatrix(filePath, codeToReqFile, crossRefPatterns) {
398
+ async function fixDesignMatrix(filePath, reqFileMaps, crossRefPatterns) {
379
399
  let content;
380
400
  try {
381
401
  content = await readFile2(filePath, "utf-8");
@@ -400,7 +420,7 @@ async function fixDesignMatrix(filePath, codeToReqFile, crossRefPatterns) {
400
420
  }
401
421
  }
402
422
  const allAcIds = [...acToComponents.keys()];
403
- const grouped = groupByReqFile(allAcIds, codeToReqFile);
423
+ const grouped = groupByReqFile(allAcIds, reqFileMaps);
404
424
  const newSection = generateDesignSection(grouped, acToComponents, acToProperties);
405
425
  const newContent = replaceTraceabilitySection(content, newSection);
406
426
  if (newContent === content) return false;
@@ -475,7 +495,7 @@ function generateDesignSection(grouped, acToComponents, acToProperties) {
475
495
  }
476
496
  return lines.join("\n");
477
497
  }
478
- async function fixTaskMatrix(filePath, codeToReqFile, specs, crossRefPatterns) {
498
+ async function fixTaskMatrix(filePath, reqFileMaps, specs, crossRefPatterns) {
479
499
  let content;
480
500
  try {
481
501
  content = await readFile2(filePath, "utf-8");
@@ -509,7 +529,7 @@ async function fixTaskMatrix(filePath, codeToReqFile, specs, crossRefPatterns) {
509
529
  }
510
530
  }
511
531
  const allIdsForMatrix = [.../* @__PURE__ */ new Set([...acToTasks.keys(), ...idToTestTasks.keys()])];
512
- const grouped = groupByReqFile(allIdsForMatrix, codeToReqFile);
532
+ const grouped = groupByReqFile(allIdsForMatrix, reqFileMaps);
513
533
  const newSection = generateTaskSection(grouped, acToTasks, idToTestTasks, sourcePropertyIds);
514
534
  const newContent = replaceTraceabilitySection(content, newSection);
515
535
  if (newContent === content) return false;
@@ -604,11 +624,10 @@ function generateTaskSection(grouped, acToTasks, idToTestTasks, propertyIds) {
604
624
  }
605
625
  return lines.join("\n").trimEnd();
606
626
  }
607
- function groupByReqFile(ids, codeToReqFile) {
627
+ function groupByReqFile(ids, maps) {
608
628
  const groups = /* @__PURE__ */ new Map();
609
629
  for (const id of ids) {
610
- const code = getCodePrefix(id);
611
- const reqFile = codeToReqFile.get(code);
630
+ const reqFile = resolveReqFile(id, maps);
612
631
  if (!reqFile) continue;
613
632
  const existing = groups.get(reqFile) ?? [];
614
633
  existing.push(id);