@ncoderz/awa 1.7.0 → 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.
|
|
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
|
|
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,
|
|
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
|
|
366
|
-
const
|
|
360
|
+
function buildReqFileMaps(specFiles) {
|
|
361
|
+
const idToReqFile = /* @__PURE__ */ new Map();
|
|
362
|
+
const codeToReqFilesSet = /* @__PURE__ */ new Map();
|
|
367
363
|
for (const sf of specFiles) {
|
|
368
|
-
|
|
369
|
-
|
|
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
|
|
382
|
+
return { idToReqFile, codeToReqFiles };
|
|
373
383
|
}
|
|
374
|
-
function
|
|
375
|
-
const
|
|
376
|
-
|
|
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,
|
|
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,
|
|
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,14 +495,14 @@ function generateDesignSection(grouped, acToComponents, acToProperties) {
|
|
|
475
495
|
}
|
|
476
496
|
return lines.join("\n");
|
|
477
497
|
}
|
|
478
|
-
async function fixTaskMatrix(filePath,
|
|
498
|
+
async function fixTaskMatrix(filePath, reqFileMaps, specs, crossRefPatterns) {
|
|
479
499
|
let content;
|
|
480
500
|
try {
|
|
481
501
|
content = await readFile2(filePath, "utf-8");
|
|
482
502
|
} catch {
|
|
483
503
|
return false;
|
|
484
504
|
}
|
|
485
|
-
const { tasks,
|
|
505
|
+
const { tasks, sourceDesigns } = parseTaskFileData(content, crossRefPatterns);
|
|
486
506
|
const acToTasks = /* @__PURE__ */ new Map();
|
|
487
507
|
for (const task of tasks) {
|
|
488
508
|
for (const acId of task.implements) {
|
|
@@ -499,15 +519,6 @@ async function fixTaskMatrix(filePath, codeToReqFile, specs, crossRefPatterns) {
|
|
|
499
519
|
idToTestTasks.set(testId, existing);
|
|
500
520
|
}
|
|
501
521
|
}
|
|
502
|
-
const sourceAcIds = /* @__PURE__ */ new Set();
|
|
503
|
-
for (const reqName of sourceReqs) {
|
|
504
|
-
const reqCode = extractCodeFromFileName(reqName);
|
|
505
|
-
for (const sf of specs.specFiles) {
|
|
506
|
-
if (sf.code === reqCode && /\bREQ-/.test(basename(sf.filePath))) {
|
|
507
|
-
for (const acId of sf.acIds) sourceAcIds.add(acId);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
522
|
const sourcePropertyIds = /* @__PURE__ */ new Set();
|
|
512
523
|
for (const designName of sourceDesigns) {
|
|
513
524
|
const designCode = extractCodeFromFileName(designName);
|
|
@@ -517,24 +528,9 @@ async function fixTaskMatrix(filePath, codeToReqFile, specs, crossRefPatterns) {
|
|
|
517
528
|
}
|
|
518
529
|
}
|
|
519
530
|
}
|
|
520
|
-
const allRefIds = /* @__PURE__ */ new Set([...acToTasks.keys(), ...idToTestTasks.keys()]);
|
|
521
|
-
const uncovered = [];
|
|
522
|
-
for (const acId of sourceAcIds) {
|
|
523
|
-
if (!allRefIds.has(acId)) uncovered.push(acId);
|
|
524
|
-
}
|
|
525
|
-
for (const propId of sourcePropertyIds) {
|
|
526
|
-
if (!allRefIds.has(propId)) uncovered.push(propId);
|
|
527
|
-
}
|
|
528
|
-
uncovered.sort(compareIds);
|
|
529
531
|
const allIdsForMatrix = [.../* @__PURE__ */ new Set([...acToTasks.keys(), ...idToTestTasks.keys()])];
|
|
530
|
-
const grouped = groupByReqFile(allIdsForMatrix,
|
|
531
|
-
const newSection = generateTaskSection(
|
|
532
|
-
grouped,
|
|
533
|
-
acToTasks,
|
|
534
|
-
idToTestTasks,
|
|
535
|
-
sourcePropertyIds,
|
|
536
|
-
uncovered
|
|
537
|
-
);
|
|
532
|
+
const grouped = groupByReqFile(allIdsForMatrix, reqFileMaps);
|
|
533
|
+
const newSection = generateTaskSection(grouped, acToTasks, idToTestTasks, sourcePropertyIds);
|
|
538
534
|
const newContent = replaceTraceabilitySection(content, newSection);
|
|
539
535
|
if (newContent === content) return false;
|
|
540
536
|
await writeFile(filePath, newContent, "utf-8");
|
|
@@ -601,7 +597,7 @@ function parseTaskFileData(content, crossRefPatterns) {
|
|
|
601
597
|
}
|
|
602
598
|
return { tasks, sourceReqs, sourceDesigns };
|
|
603
599
|
}
|
|
604
|
-
function generateTaskSection(grouped, acToTasks, idToTestTasks, propertyIds
|
|
600
|
+
function generateTaskSection(grouped, acToTasks, idToTestTasks, propertyIds) {
|
|
605
601
|
const lines = [];
|
|
606
602
|
const reqFiles = [...grouped.keys()].sort();
|
|
607
603
|
for (const reqFile of reqFiles) {
|
|
@@ -626,15 +622,12 @@ function generateTaskSection(grouped, acToTasks, idToTestTasks, propertyIds, unc
|
|
|
626
622
|
}
|
|
627
623
|
lines.push("");
|
|
628
624
|
}
|
|
629
|
-
|
|
630
|
-
lines.push(`UNCOVERED: ${uncoveredStr}`);
|
|
631
|
-
return lines.join("\n");
|
|
625
|
+
return lines.join("\n").trimEnd();
|
|
632
626
|
}
|
|
633
|
-
function groupByReqFile(ids,
|
|
627
|
+
function groupByReqFile(ids, maps) {
|
|
634
628
|
const groups = /* @__PURE__ */ new Map();
|
|
635
629
|
for (const id of ids) {
|
|
636
|
-
const
|
|
637
|
-
const reqFile = codeToReqFile.get(code);
|
|
630
|
+
const reqFile = resolveReqFile(id, maps);
|
|
638
631
|
if (!reqFile) continue;
|
|
639
632
|
const existing = groups.get(reqFile) ?? [];
|
|
640
633
|
existing.push(id);
|