@rasensio/aidlc 1.26.1 → 1.27.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.
Files changed (73) hide show
  1. package/dist/commands/cost.d.ts +7 -0
  2. package/dist/commands/cost.d.ts.map +1 -1
  3. package/dist/commands/cost.js +137 -0
  4. package/dist/commands/cost.js.map +1 -1
  5. package/dist/commands/discover.d.ts.map +1 -1
  6. package/dist/commands/discover.js +11 -3
  7. package/dist/commands/discover.js.map +1 -1
  8. package/dist/commands/review.d.ts +15 -2
  9. package/dist/commands/review.d.ts.map +1 -1
  10. package/dist/commands/review.js +163 -9
  11. package/dist/commands/review.js.map +1 -1
  12. package/dist/commands/start.d.ts.map +1 -1
  13. package/dist/commands/start.js +27 -66
  14. package/dist/commands/start.js.map +1 -1
  15. package/dist/commands/transition.d.ts.map +1 -1
  16. package/dist/commands/transition.js +45 -8
  17. package/dist/commands/transition.js.map +1 -1
  18. package/dist/commands/update.d.ts.map +1 -1
  19. package/dist/commands/update.js +8 -2
  20. package/dist/commands/update.js.map +1 -1
  21. package/dist/core/lifecycle.d.ts.map +1 -1
  22. package/dist/core/lifecycle.js +30 -1
  23. package/dist/core/lifecycle.js.map +1 -1
  24. package/dist/cost/context.d.ts +72 -0
  25. package/dist/cost/context.d.ts.map +1 -0
  26. package/dist/cost/context.js +155 -0
  27. package/dist/cost/context.js.map +1 -0
  28. package/dist/cost/dedupe-history.d.ts +98 -0
  29. package/dist/cost/dedupe-history.d.ts.map +1 -0
  30. package/dist/cost/dedupe-history.js +275 -0
  31. package/dist/cost/dedupe-history.js.map +1 -0
  32. package/dist/cost/ledger.d.ts.map +1 -1
  33. package/dist/cost/ledger.js +11 -5
  34. package/dist/cost/ledger.js.map +1 -1
  35. package/dist/cost/providers/claude-code.d.ts +13 -1
  36. package/dist/cost/providers/claude-code.d.ts.map +1 -1
  37. package/dist/cost/providers/claude-code.js +112 -10
  38. package/dist/cost/providers/claude-code.js.map +1 -1
  39. package/dist/cost/rates.d.ts +16 -1
  40. package/dist/cost/rates.d.ts.map +1 -1
  41. package/dist/cost/rates.js +21 -0
  42. package/dist/cost/rates.js.map +1 -1
  43. package/dist/cost/recorder.d.ts.map +1 -1
  44. package/dist/cost/recorder.js +3 -0
  45. package/dist/cost/recorder.js.map +1 -1
  46. package/dist/cost/report.d.ts +30 -0
  47. package/dist/cost/report.d.ts.map +1 -1
  48. package/dist/cost/report.js +96 -5
  49. package/dist/cost/report.js.map +1 -1
  50. package/dist/cost/sync.d.ts +18 -0
  51. package/dist/cost/sync.d.ts.map +1 -1
  52. package/dist/cost/sync.js +1 -1
  53. package/dist/cost/sync.js.map +1 -1
  54. package/dist/cost/types.d.ts +40 -0
  55. package/dist/cost/types.d.ts.map +1 -1
  56. package/dist/cost/types.js +15 -0
  57. package/dist/cost/types.js.map +1 -1
  58. package/dist/discover/scanner.d.ts +20 -2
  59. package/dist/discover/scanner.d.ts.map +1 -1
  60. package/dist/discover/scanner.js +80 -14
  61. package/dist/discover/scanner.js.map +1 -1
  62. package/dist/doctor/migrations/findings-filename.d.ts +77 -0
  63. package/dist/doctor/migrations/findings-filename.d.ts.map +1 -0
  64. package/dist/doctor/migrations/findings-filename.js +189 -0
  65. package/dist/doctor/migrations/findings-filename.js.map +1 -0
  66. package/dist/doctor/migrations/index.d.ts.map +1 -1
  67. package/dist/doctor/migrations/index.js +8 -0
  68. package/dist/doctor/migrations/index.js.map +1 -1
  69. package/dist/review/findings-naming.d.ts +112 -0
  70. package/dist/review/findings-naming.d.ts.map +1 -0
  71. package/dist/review/findings-naming.js +132 -0
  72. package/dist/review/findings-naming.js.map +1 -0
  73. package/package.json +2 -2
@@ -0,0 +1,132 @@
1
+ /**
2
+ * The one place that decides how an artifact name and a findings filename map to
3
+ * each other.
4
+ *
5
+ * Before this module there were two independent derivations of the same key, and
6
+ * they disagreed. `aidlc review <instance> <artifact>` wrote
7
+ * `` `${artifactArg}.review.md` `` from the argument as typed, while
8
+ * `loadFindings` keyed its index on `file.replace('.review.md', '')` and
9
+ * `checkReviewGate` looked up the template's artifact name — `requirements.md`.
10
+ * Type `requirements`, which is the phase name and what the skill's prose calls
11
+ * the artifact, and the review was written, parsed, counted and summarised
12
+ * correctly while the gate reported "no findings file".
13
+ *
14
+ * The cost was not hypothetical: **11 findings files across 6 completed
15
+ * instances** sat under the legacy spelling, every one of them a `full-feature`
16
+ * instance and every one on `requirements` or `design` — the only two phases any
17
+ * template gates. Eleven adversarial reviews, none of which counted toward the
18
+ * gate they were run for.
19
+ *
20
+ * ## Why both directions live here
21
+ *
22
+ * Fixing only the writer would leave those 11 files dead. Fixing only the reader
23
+ * would leave two spellings valid forever, which is what the roadmap item warned
24
+ * against. So this module owns the mapping and both callers derive from it — a
25
+ * second derivation anywhere else is the regression, which is why
26
+ * `test/findings-naming.test.ts` asserts the inverse property rather than a list
27
+ * of literals.
28
+ *
29
+ * The convenient part is that the inverse is nearly free:
30
+ *
31
+ * ```
32
+ * artifactFromFindingsFile('requirements.review.md') === 'requirements.md'
33
+ * artifactFromFindingsFile('requirements.md.review.md') === 'requirements.md'
34
+ * ```
35
+ *
36
+ * Strip the suffix, then canonicalize. Both spellings on disk converge on one
37
+ * key, so the legacy files start counting with no compatibility branch at any
38
+ * call site — nothing downstream has to know which spelling it is looking at.
39
+ *
40
+ * ## Why `<artifact>.md.review.md` is canonical
41
+ *
42
+ * The doubled `.md` is ugly, and it is the spelling that already works:
43
+ * `checkReviewGate` looks up the template's artifact name, so the gate needs no
44
+ * change to find these files. It is also the majority on disk — 31 files against
45
+ * 11 — and every instance from `agent-portability` (2026-08-21) onward writes it.
46
+ * Choosing the prettier spelling would move 31 files to stop 11 from moving.
47
+ *
48
+ * Requirements: AC-1, AC-2, AC-3, AC-4, AC-5, AC-10
49
+ *
50
+ * @module
51
+ */
52
+ /**
53
+ * The suffix that marks a file as review findings.
54
+ *
55
+ * Exported because the doctor migration and `loadFindings` both filter on it, and
56
+ * a literal `'.review.md'` in either would be a second declaration of the fact
57
+ * this module exists to hold once.
58
+ */
59
+ export const FINDINGS_SUFFIX = '.review.md';
60
+ /** The extension every artifact a template declares carries. */
61
+ const ARTIFACT_EXT = '.md';
62
+ /**
63
+ * Resolve an artifact argument to the filename a template declares for it.
64
+ *
65
+ * `requirements` and `requirements.md` both yield `requirements.md`. That is the
66
+ * whole fix for the writer side: the argument a human or agent naturally types is
67
+ * the phase name, and the extension is load-bearing in a way nothing told them.
68
+ *
69
+ * A string already ending in {@link FINDINGS_SUFFIX} is returned unchanged rather
70
+ * than having `.md` appended. Deciding whether such an argument is legal is
71
+ * policy, and policy belongs in the caller's allowlist — this function's job is
72
+ * the mapping, and quietly producing `x.review.md.md` would be worse than either
73
+ * accepting or refusing it.
74
+ *
75
+ * @param arg - Artifact argument, with or without its extension.
76
+ * @returns The artifact filename, e.g. `requirements.md`.
77
+ */
78
+ export function canonicalArtifactName(arg) {
79
+ if (arg.endsWith(FINDINGS_SUFFIX))
80
+ return arg;
81
+ return arg.endsWith(ARTIFACT_EXT) ? arg : `${arg}${ARTIFACT_EXT}`;
82
+ }
83
+ /**
84
+ * The canonical findings filename for an artifact argument.
85
+ *
86
+ * @param arg - Artifact argument, with or without its extension.
87
+ * @returns e.g. `requirements.md.review.md`.
88
+ */
89
+ export function findingsFilename(arg) {
90
+ return `${canonicalArtifactName(arg)}${FINDINGS_SUFFIX}`;
91
+ }
92
+ /**
93
+ * The artifact a findings file reviews, under one spelling regardless of how the
94
+ * file itself is spelled.
95
+ *
96
+ * Both the canonical `requirements.md.review.md` and the legacy
97
+ * `requirements.review.md` resolve to `requirements.md`. This is the reader-side
98
+ * half of the fix and the reason the 11 orphaned files need no migration in order
99
+ * to start counting — the migration only tidies the names.
100
+ *
101
+ * @param file - A filename, not a path.
102
+ * @returns The artifact filename, or `null` when `file` is not a findings file or
103
+ * carries no name before the suffix.
104
+ */
105
+ export function artifactFromFindingsFile(file) {
106
+ if (!file.endsWith(FINDINGS_SUFFIX))
107
+ return null;
108
+ const stem = file.slice(0, -FINDINGS_SUFFIX.length);
109
+ if (stem.length === 0)
110
+ return null;
111
+ return canonicalArtifactName(stem);
112
+ }
113
+ /**
114
+ * Whether a findings filename is already the canonical spelling for the artifact
115
+ * it reviews.
116
+ *
117
+ * The predicate the doctor migration selects on: false means the file is legacy
118
+ * and can be renamed without touching its contents. A non-findings filename is
119
+ * not canonical *and* not legacy, so callers must filter on
120
+ * {@link FINDINGS_SUFFIX} first — this returns false for those, which is the safe
121
+ * direction for a rename planner but would be the wrong answer to "should I
122
+ * ignore this file?".
123
+ *
124
+ * @param file - A filename, not a path.
125
+ */
126
+ export function isCanonicalFindingsFile(file) {
127
+ const artifact = artifactFromFindingsFile(file);
128
+ if (artifact === null)
129
+ return false;
130
+ return file === `${artifact}${FINDINGS_SUFFIX}`;
131
+ }
132
+ //# sourceMappingURL=findings-naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findings-naming.js","sourceRoot":"","sources":["../../src/review/findings-naming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC;AAE5C,gEAAgE;AAChE,MAAM,YAAY,GAAG,KAAK,CAAC;AAE3B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC;QAAE,OAAO,GAAG,CAAC;IAC9C,OAAO,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,YAAY,EAAE,CAAC;AACpE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,eAAe,EAAE,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,IAAI,KAAK,GAAG,QAAQ,GAAG,eAAe,EAAE,CAAC;AAClD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rasensio/aidlc",
3
- "version": "1.26.1",
3
+ "version": "1.27.0",
4
4
  "description": "AI Development Lifecycle Framework — structured lifecycle guidance for AI coding agents across platforms",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
@@ -24,7 +24,7 @@
24
24
  "commander": "15.0.0",
25
25
  "picomatch": "4.0.5",
26
26
  "yaml": "2.9.0",
27
- "@rasensio/aidlc-content": "1.26.1"
27
+ "@rasensio/aidlc-content": "1.27.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "22.15.32",