cclaw-cli 0.51.3 → 0.51.4

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.
@@ -1633,25 +1633,34 @@ export async function lintArtifact(projectRoot, stage, track = "standard") {
1633
1633
  // IDs all fail the lint; absence of the section remains advisory so
1634
1634
  // scope stays optional for small/quick tracks.
1635
1635
  if (headingPresent(sections, "Locked Decisions (D-XX)")) {
1636
- const decisionIds = extractDecisionIds(lockedDecisionsBody);
1637
- const bulletLines = lockedDecisionsBody
1636
+ const listDecisionLines = lockedDecisionsBody
1638
1637
  .split(/\r?\n/u)
1639
1638
  .map((line) => line.trim())
1640
- .filter((line) => /^(?:[-*]|\|)\s+\S/u.test(line));
1641
- const orphanBullets = bulletLines.filter((line) => !/\bD-\d+\b/u.test(line));
1639
+ .filter((line) => /^[-*]\s+\S/u.test(line));
1640
+ const tableDecisionRows = getMarkdownTableRows(lockedDecisionsBody);
1641
+ const tableDecisionLines = tableDecisionRows.map((row) => row.join(" | "));
1642
+ const decisionLines = [...listDecisionLines, ...tableDecisionLines];
1643
+ const orphanDecisionLines = decisionLines.filter((line) => !/\bD-\d+\b/u.test(line));
1644
+ const rowDecisionIds = [
1645
+ ...listDecisionLines.map((line) => /\bD-\d+\b/u.exec(line)?.[0]),
1646
+ ...tableDecisionRows.map((row) => /\bD-\d+\b/u.exec(row[0] ?? "")?.[0])
1647
+ ].filter((id) => typeof id === "string");
1642
1648
  const duplicateIds = (() => {
1643
- const all = lockedDecisionsBody.match(/\bD-\d+\b/gu) ?? [];
1644
1649
  const counts = new Map();
1645
- for (const id of all)
1650
+ for (const id of rowDecisionIds)
1646
1651
  counts.set(id, (counts.get(id) ?? 0) + 1);
1647
1652
  return [...counts.entries()].filter(([, n]) => n > 1).map(([id]) => id);
1648
1653
  })();
1649
1654
  const issues = [];
1650
- if (decisionIds.length === 0 && bulletLines.length === 0) {
1655
+ if (rowDecisionIds.length === 0 && decisionLines.length === 0) {
1651
1656
  issues.push("section is empty");
1652
1657
  }
1653
- if (orphanBullets.length > 0) {
1654
- issues.push(`${orphanBullets.length} bullet(s) missing a D-XX ID`);
1658
+ if (orphanDecisionLines.length > 0) {
1659
+ const examples = orphanDecisionLines
1660
+ .slice(0, 3)
1661
+ .map((line) => `\`${line.slice(0, 120)}\``)
1662
+ .join(", ");
1663
+ issues.push(`${orphanDecisionLines.length} decision row(s) missing a D-XX ID${examples.length > 0 ? `: ${examples}` : ""}`);
1655
1664
  }
1656
1665
  if (duplicateIds.length > 0) {
1657
1666
  issues.push(`duplicate IDs: ${duplicateIds.join(", ")}`);
@@ -1662,7 +1671,7 @@ export async function lintArtifact(projectRoot, stage, track = "standard") {
1662
1671
  rule: "Locked Decisions section must list each decision with a unique stable D-XX ID.",
1663
1672
  found: issues.length === 0,
1664
1673
  details: issues.length === 0
1665
- ? `${decisionIds.length} decision ID(s) recorded with no duplicates.`
1674
+ ? `${rowDecisionIds.length} decision ID(s) recorded with no duplicates.`
1666
1675
  : issues.join("; ")
1667
1676
  });
1668
1677
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "0.51.3",
3
+ "version": "0.51.4",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {