@rasensio/aidlc 1.3.0 → 1.4.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 (47) hide show
  1. package/dist/commands/gate.d.ts.map +1 -1
  2. package/dist/commands/gate.js +17 -0
  3. package/dist/commands/gate.js.map +1 -1
  4. package/dist/commands/status.d.ts.map +1 -1
  5. package/dist/commands/status.js +30 -2
  6. package/dist/commands/status.js.map +1 -1
  7. package/dist/commands/transition.d.ts.map +1 -1
  8. package/dist/commands/transition.js +21 -0
  9. package/dist/commands/transition.js.map +1 -1
  10. package/dist/core/gate.d.ts +7 -0
  11. package/dist/core/gate.d.ts.map +1 -1
  12. package/dist/core/gate.js.map +1 -1
  13. package/dist/core/types.d.ts +10 -1
  14. package/dist/core/types.d.ts.map +1 -1
  15. package/dist/traceability/cache.d.ts +21 -0
  16. package/dist/traceability/cache.d.ts.map +1 -0
  17. package/dist/traceability/cache.js +106 -0
  18. package/dist/traceability/cache.js.map +1 -0
  19. package/dist/traceability/coverage-block.d.ts +21 -0
  20. package/dist/traceability/coverage-block.d.ts.map +1 -0
  21. package/dist/traceability/coverage-block.js +41 -0
  22. package/dist/traceability/coverage-block.js.map +1 -0
  23. package/dist/traceability/gate-criterion.d.ts +34 -0
  24. package/dist/traceability/gate-criterion.d.ts.map +1 -0
  25. package/dist/traceability/gate-criterion.js +128 -0
  26. package/dist/traceability/gate-criterion.js.map +1 -0
  27. package/dist/traceability/matrix.d.ts +35 -0
  28. package/dist/traceability/matrix.d.ts.map +1 -0
  29. package/dist/traceability/matrix.js +93 -0
  30. package/dist/traceability/matrix.js.map +1 -0
  31. package/dist/traceability/parser.d.ts +27 -0
  32. package/dist/traceability/parser.d.ts.map +1 -0
  33. package/dist/traceability/parser.js +101 -0
  34. package/dist/traceability/parser.js.map +1 -0
  35. package/dist/traceability/scanner.d.ts +62 -0
  36. package/dist/traceability/scanner.d.ts.map +1 -0
  37. package/dist/traceability/scanner.js +198 -0
  38. package/dist/traceability/scanner.js.map +1 -0
  39. package/dist/traceability/types.d.ts +77 -0
  40. package/dist/traceability/types.d.ts.map +1 -0
  41. package/dist/traceability/types.js +8 -0
  42. package/dist/traceability/types.js.map +1 -0
  43. package/package.json +2 -2
  44. package/dist/commands/setup.d.ts +0 -24
  45. package/dist/commands/setup.d.ts.map +0 -1
  46. package/dist/commands/setup.js +0 -262
  47. package/dist/commands/setup.js.map +0 -1
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Test-file discovery and AC-reference scanning (FR2).
3
+ *
4
+ * Own walker + glob translator instead of `fs.globSync`: stdlib glob
5
+ * semantics are release-dependent while the Node floor is 22.13; the pinned
6
+ * semantics here are enforced by this module's tests (NFR1, design DD2).
7
+ *
8
+ * Pinned semantics (design Data Flow 4):
9
+ * - `**` matches zero or more path segments
10
+ * - `*` / `?` match within a segment, never a leading dot
11
+ * - dot-files and dot-directories are never traversed
12
+ * - exclusions (node_modules, .git, dist, build, .aidlc) prune before
13
+ * descent at any depth, regardless of glob source (AC-6/AC-7, DD4)
14
+ * - symlinks are never followed (AC-8, NFR3)
15
+ * - emitted paths are posix-separated and project-root-relative (design F7)
16
+ *
17
+ * Requirements: traceability-ids/AC-5..AC-8, AC-24, AC-25
18
+ */
19
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
20
+ import { isAbsolute, join, sep } from 'node:path';
21
+ /** D1 default test globs. */
22
+ export const DEFAULT_TEST_GLOBS = ['**/*.test.*', '**/*.spec.*', '**/test/**', '**/tests/**'];
23
+ /** Unconditional exclusions — directory-name filters applied before descent. */
24
+ const EXCLUDED_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.aidlc']);
25
+ /** Scan caps (NFR2, AC-8). */
26
+ export const MAX_SCANNED_FILES = 10_000;
27
+ const MAX_FILE_BYTES = 1024 * 1024;
28
+ const BINARY_SNIFF_BYTES = 8 * 1024;
29
+ // Reference tokens (AC-5, AC-24, AC-25): case-sensitive, literal digits,
30
+ // symmetric boundaries — `AC-1-bis` is not a reference to AC-1 (design F8);
31
+ // `https://example.com/AC-6` is not a qualified reference (design F9).
32
+ const QUALIFIED_RE = /(?<![\w./:-])([a-z0-9-]+)\/AC-([1-9][0-9]*)(?![\w-])/g;
33
+ const BARE_RE = /(?<![\w/-])AC-([1-9][0-9]*)(?![\w-])/g;
34
+ // ---------------------------------------------------------------------------
35
+ // Glob translation
36
+ // ---------------------------------------------------------------------------
37
+ const GLOB_UNSUPPORTED = /[{}()!+@]|\[/;
38
+ /**
39
+ * Translate one glob into a RegExp over posix relative paths, or null when
40
+ * the pattern uses unsupported syntax (braces, extglobs, character classes).
41
+ */
42
+ export function translateGlob(pattern) {
43
+ if (GLOB_UNSUPPORTED.test(pattern))
44
+ return null;
45
+ const segments = pattern.split('/').filter((s) => s.length > 0);
46
+ const parts = [];
47
+ for (const seg of segments) {
48
+ if (seg === '**') {
49
+ // Zero or more whole segments (each not starting with a dot).
50
+ parts.push('(?:[^./][^/]*/)*');
51
+ continue;
52
+ }
53
+ let re = '';
54
+ for (const ch of seg) {
55
+ if (ch === '*')
56
+ re += '[^/]*';
57
+ else if (ch === '?')
58
+ re += '[^/]';
59
+ else
60
+ re += ch.replace(/[.\\^$|#+()[\]{}]/g, '\\$&');
61
+ }
62
+ // `*`/`?` never match a leading dot.
63
+ if (seg.startsWith('*') || seg.startsWith('?'))
64
+ re = `(?!\\.)${re}`;
65
+ parts.push(`${re}/`);
66
+ }
67
+ let source = parts.join('');
68
+ if (source.endsWith('/'))
69
+ source = source.slice(0, -1);
70
+ // A trailing `**` also matches files in any subdirectory.
71
+ if (segments[segments.length - 1] === '**')
72
+ source += '[^/]*(?:/[^/]+)*';
73
+ return new RegExp(`^${source}$`);
74
+ }
75
+ /**
76
+ * Validate configured globs (AC-7): absolute or `..`-containing patterns and
77
+ * unsupported syntax are rejected with a warning naming the glob.
78
+ */
79
+ export function validateGlobs(patterns) {
80
+ const matchers = [];
81
+ const warnings = [];
82
+ for (const pattern of patterns) {
83
+ if (isAbsolute(pattern)) {
84
+ warnings.push(`glob "${pattern}" rejected: absolute`);
85
+ continue;
86
+ }
87
+ if (pattern.split('/').includes('..')) {
88
+ warnings.push(`glob "${pattern}" rejected: escapes project root`);
89
+ continue;
90
+ }
91
+ const matcher = translateGlob(pattern);
92
+ if (!matcher) {
93
+ warnings.push(`glob "${pattern}" rejected: unsupported syntax`);
94
+ continue;
95
+ }
96
+ matchers.push(matcher);
97
+ }
98
+ return { matchers, warnings };
99
+ }
100
+ /** Recursively collect candidate files under root (pinned semantics above). */
101
+ function walk(root, relDir, out) {
102
+ let entries;
103
+ try {
104
+ entries = readdirSync(relDir === '' ? root : join(root, ...relDir.split('/')), {
105
+ withFileTypes: true,
106
+ });
107
+ }
108
+ catch {
109
+ return;
110
+ }
111
+ entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
112
+ for (const entry of entries) {
113
+ if (entry.name.startsWith('.') || EXCLUDED_DIRS.has(entry.name))
114
+ continue;
115
+ const rel = relDir === '' ? entry.name : `${relDir}/${entry.name}`;
116
+ // Dirent type checks never follow symlinks (lstat semantics).
117
+ if (entry.isDirectory())
118
+ walk(root, rel, out);
119
+ else if (entry.isFile())
120
+ out.push(rel);
121
+ }
122
+ }
123
+ /**
124
+ * Discover test files by glob against the project root.
125
+ *
126
+ * @param projectRoot - Directory containing `.aidlc/`.
127
+ * @param globs - Effective glob list (defaults or config).
128
+ */
129
+ export function discoverTestFiles(projectRoot, globs) {
130
+ const { matchers, warnings } = validateGlobs(globs);
131
+ const all = [];
132
+ walk(projectRoot, '', all);
133
+ const files = all.filter((f) => matchers.some((m) => m.test(f)));
134
+ if (files.length > MAX_SCANNED_FILES) {
135
+ warnings.push(`scanning truncated at ${MAX_SCANNED_FILES} files; coverage may be under-reported`);
136
+ files.length = MAX_SCANNED_FILES;
137
+ }
138
+ return { files, warnings };
139
+ }
140
+ /** Scan one file's content for AC reference tokens (qualified, then bare). */
141
+ export function scanContent(content, path) {
142
+ const refs = [];
143
+ const lines = content.split('\n');
144
+ for (let i = 0; i < lines.length; i++) {
145
+ const line = lines[i];
146
+ for (const m of line.matchAll(QUALIFIED_RE)) {
147
+ refs.push({ acId: Number(m[2]), instance: m[1], path, line: i + 1, source: 'scan' });
148
+ }
149
+ // Bare tokens inside qualified ones are blocked by `/` in the lookbehind
150
+ // — that guard, not token consumption, prevents double-counting (F8).
151
+ for (const m of line.matchAll(BARE_RE)) {
152
+ refs.push({ acId: Number(m[1]), instance: null, path, line: i + 1, source: 'scan' });
153
+ }
154
+ }
155
+ return refs;
156
+ }
157
+ /**
158
+ * Scan discovered files, skipping unreadable/oversize/binary files with a
159
+ * warning (AC-8). Never throws.
160
+ */
161
+ export function scanFiles(projectRoot, files) {
162
+ const refs = [];
163
+ const warnings = [];
164
+ for (const rel of files) {
165
+ const abs = join(projectRoot, ...rel.split('/'));
166
+ let size;
167
+ try {
168
+ size = statSync(abs).size;
169
+ }
170
+ catch {
171
+ warnings.push(`skipped ${rel}: unreadable`);
172
+ continue;
173
+ }
174
+ if (size > MAX_FILE_BYTES) {
175
+ warnings.push(`skipped ${rel}: too large`);
176
+ continue;
177
+ }
178
+ let buf;
179
+ try {
180
+ buf = readFileSync(abs);
181
+ }
182
+ catch {
183
+ warnings.push(`skipped ${rel}: unreadable`);
184
+ continue;
185
+ }
186
+ if (buf.subarray(0, BINARY_SNIFF_BYTES).includes(0)) {
187
+ warnings.push(`skipped ${rel}: binary`);
188
+ continue;
189
+ }
190
+ refs.push(...scanContent(buf.toString('utf8'), rel));
191
+ }
192
+ return { refs, warnings };
193
+ }
194
+ /** Convert a native relative path to the canonical posix form (design F7). */
195
+ export function toPosix(relPath) {
196
+ return sep === '/' ? relPath : relPath.split(sep).join('/');
197
+ }
198
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/traceability/scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGlD,6BAA6B;AAC7B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;AAE9F,gFAAgF;AAChF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEnF,8BAA8B;AAC9B,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACxC,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC;AACnC,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,CAAC;AAEpC,yEAAyE;AACzE,4EAA4E;AAC5E,uEAAuE;AACvE,MAAM,YAAY,GAAG,uDAAuD,CAAC;AAC7E,MAAM,OAAO,GAAG,uCAAuC,CAAC;AAExD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAExC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,8DAA8D;YAC9D,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,EAAE,KAAK,GAAG;gBAAE,EAAE,IAAI,OAAO,CAAC;iBACzB,IAAI,EAAE,KAAK,GAAG;gBAAE,EAAE,IAAI,MAAM,CAAC;;gBAC7B,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACtD,CAAC;QACD,qCAAqC;QACrC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,EAAE,GAAG,UAAU,EAAE,EAAE,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,0DAA0D;IAC1D,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI;QAAE,MAAM,IAAI,kBAAkB,CAAC;IACzE,OAAO,IAAI,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,QAAkB;IAC9C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,sBAAsB,CAAC,CAAC;YACtD,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,kCAAkC,CAAC,CAAC;YAClE,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,gCAAgC,CAAC,CAAC;YAChE,SAAS;QACX,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAYD,+EAA+E;AAC/E,SAAS,IAAI,CAAC,IAAY,EAAE,MAAc,EAAE,GAAa;IACvD,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE;YAC7E,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC1E,MAAM,GAAG,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACnE,8DAA8D;QAC9D,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;aACzC,IAAI,KAAK,CAAC,MAAM,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB,EAAE,KAAe;IACpE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CACX,yBAAyB,iBAAiB,wCAAwC,CACnF,CAAC;QACF,KAAK,CAAC,MAAM,GAAG,iBAAiB,CAAC;IACnC,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAWD,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,IAAY;IACvD,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,yEAAyE;QACzE,sEAAsE;QACtE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,WAAmB,EAAE,KAAe;IAC5D,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,IAAI,GAAG,cAAc,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,CAAC;YACxC,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Traceability types: AC definitions, references, and the coverage matrix
3
+ * exposed via `aidlc gate --json` (traceability-ids AC-15).
4
+ *
5
+ * Design: design.md (traceability-ids) §Interfaces
6
+ */
7
+ /** A single acceptance-criterion definition parsed from requirements.md. */
8
+ export interface AcDefinition {
9
+ /** n in AC-n (≥1, no leading zeros). */
10
+ id: number;
11
+ /** Owning instance name. */
12
+ instance: string;
13
+ /** 1-based line number in requirements.md. */
14
+ line: number;
15
+ status: 'active' | 'retired';
16
+ /** YYYY-MM-DD, present when retired. */
17
+ retiredDate?: string;
18
+ /** AC number this criterion was superseded by, when stated. */
19
+ supersededBy?: number;
20
+ }
21
+ /** Parse result for one instance's requirements.md. */
22
+ export interface ParsedRequirements {
23
+ /** First occurrence wins on duplicates (AC-4). */
24
+ defs: AcDefinition[];
25
+ /** Duplicates, near-misses, sequence gaps (AC-4, AC-22, AC-23). */
26
+ warnings: string[];
27
+ /**
28
+ * Lines matching the loose AC pattern (defs + near-misses). Drives the
29
+ * applicability tri-state (DD7): 0 → criterion silent; >0 with no defs →
30
+ * warnings-only result.
31
+ */
32
+ acShapedLines: number;
33
+ }
34
+ /** One AC reference found in a test file or coverage block. */
35
+ export interface AcReference {
36
+ acId: number;
37
+ /** Qualified instance name, or null for a bare token. */
38
+ instance: string | null;
39
+ /** Posix-separated, project-root-relative path. */
40
+ path: string;
41
+ /** 1-based line number. */
42
+ line: number;
43
+ source: 'scan' | 'block';
44
+ }
45
+ /** Per-AC row of the coverage matrix (AC-15). */
46
+ export interface AcCoverageEntry {
47
+ id: number;
48
+ status: 'covered' | 'uncovered' | 'retired';
49
+ /** Sorted by path (NFR4). */
50
+ refs: {
51
+ path: string;
52
+ source: 'scan' | 'block';
53
+ }[];
54
+ }
55
+ /** Full traceability result attached to GateCheckResult (AC-15). */
56
+ export interface TraceabilityResult {
57
+ /** Posix-separated, project-root-relative requirements.md path. */
58
+ requirementsPath: string;
59
+ /** Sorted by id (NFR4). */
60
+ entries: AcCoverageEntry[];
61
+ /** Ordered by phase, then path, then line (NFR4). */
62
+ warnings: string[];
63
+ /** Active AC ids with zero references — drives gate failure (AC-11). */
64
+ uncoveredActive: number[];
65
+ }
66
+ /** Coverage summary for the `aidlc status` column (AC-17). */
67
+ export interface CoverageSummary {
68
+ covered: number;
69
+ total: number;
70
+ stale: number;
71
+ }
72
+ /** Tolerantly-read `traceability:` section of .aidlc/config.yaml. */
73
+ export interface TraceabilityConfig {
74
+ /** Replaces the default test globs when present (AC-7). */
75
+ test_globs?: string[];
76
+ }
77
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/traceability/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,uDAAuD;AACvD,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;IAC5C,6BAA6B;IAC7B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,EAAE,CAAC;CACpD;AAED,oEAAoE;AACpE,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,qDAAqD;IACrD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,wEAAwE;IACxE,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Traceability types: AC definitions, references, and the coverage matrix
3
+ * exposed via `aidlc gate --json` (traceability-ids AC-15).
4
+ *
5
+ * Design: design.md (traceability-ids) §Interfaces
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/traceability/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rasensio/aidlc",
3
- "version": "1.3.0",
3
+ "version": "1.4.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.3.0"
27
+ "@rasensio/aidlc-content": "1.4.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "22.15.32",
@@ -1,24 +0,0 @@
1
- /**
2
- * `aidlc setup` command — interactive setup or update of AIDLC configuration.
3
- *
4
- * Behavior:
5
- * - Detect existing `.aidlc/config.yaml` → update mode vs fresh-setup mode.
6
- * - In interactive mode: use @clack/prompts to collect SetupAnswers.
7
- * - In non-interactive mode (`--non-interactive`): use empty answers (preserve
8
- * existing or apply defaults).
9
- * - Call `computeSetup(existingConfig, answers)` to produce the config.
10
- * - Write the result to `.aidlc/config.yaml` using `saveYaml`.
11
- * - Run `aidlc init` for each configured platform.
12
- * - Run `aidlc discover` to generate context docs.
13
- * - Print summary.
14
- *
15
- * Requirements: 21.1, 21.9, 7.8
16
- *
17
- * @module
18
- */
19
- import { Command } from 'commander';
20
- /**
21
- * Register the `aidlc setup` command on the given commander program.
22
- */
23
- export declare function registerSetup(program: Command): void;
24
- //# sourceMappingURL=setup.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsLpC;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQpD"}
@@ -1,262 +0,0 @@
1
- /**
2
- * `aidlc setup` command — interactive setup or update of AIDLC configuration.
3
- *
4
- * Behavior:
5
- * - Detect existing `.aidlc/config.yaml` → update mode vs fresh-setup mode.
6
- * - In interactive mode: use @clack/prompts to collect SetupAnswers.
7
- * - In non-interactive mode (`--non-interactive`): use empty answers (preserve
8
- * existing or apply defaults).
9
- * - Call `computeSetup(existingConfig, answers)` to produce the config.
10
- * - Write the result to `.aidlc/config.yaml` using `saveYaml`.
11
- * - Run `aidlc init` for each configured platform.
12
- * - Run `aidlc discover` to generate context docs.
13
- * - Print summary.
14
- *
15
- * Requirements: 21.1, 21.9, 7.8
16
- *
17
- * @module
18
- */
19
- import { Command } from 'commander';
20
- import { existsSync } from 'node:fs';
21
- import { join } from 'node:path';
22
- import * as clack from '@clack/prompts';
23
- import { computeSetup } from '../setup/setup-compute.js';
24
- import { loadYaml, saveYaml } from '../state/yaml-helpers.js';
25
- // ---------------------------------------------------------------------------
26
- // Constants
27
- // ---------------------------------------------------------------------------
28
- /**
29
- * Mapping from complexity to default scope and template (Req 21.5).
30
- */
31
- const COMPLEXITY_DEFAULTS = {
32
- simple: { scope: 'micro', template: 'micro-task' },
33
- moderate: { scope: 'standard', template: 'quick-feature' },
34
- complex: { scope: 'full', template: 'full-feature' },
35
- };
36
- // ---------------------------------------------------------------------------
37
- // Helpers
38
- // ---------------------------------------------------------------------------
39
- /**
40
- * Load existing config from `.aidlc/config.yaml`, or null if it doesn't exist.
41
- */
42
- function loadExistingConfig(projectRoot) {
43
- const configPath = join(projectRoot, '.aidlc', 'config.yaml');
44
- if (!existsSync(configPath)) {
45
- return null;
46
- }
47
- try {
48
- return loadYaml(configPath);
49
- }
50
- catch {
51
- // Malformed config → treat as fresh setup
52
- return null;
53
- }
54
- }
55
- /**
56
- * Collect answers interactively using @clack/prompts.
57
- */
58
- async function collectInteractiveAnswers(existing) {
59
- clack.intro('aidlc setup');
60
- if (existing) {
61
- clack.note(`Existing configuration found. Current platforms: ${existing.platforms.join(', ') || 'none'}\n` +
62
- `Scope: ${existing.defaults.scope}, Template: ${existing.defaults.template}`, 'Update mode');
63
- }
64
- // Project type
65
- const projectType = await clack.select({
66
- message: 'What kind of project is this?',
67
- options: [
68
- { value: 'web-app', label: 'web-app', hint: 'Frontend or full-stack web application (React, Next.js, etc.)' },
69
- { value: 'api', label: 'api', hint: 'Backend service or REST/GraphQL API' },
70
- { value: 'cli', label: 'cli', hint: 'Command-line tool or terminal utility' },
71
- { value: 'library', label: 'library', hint: 'Reusable package or SDK consumed by other projects' },
72
- { value: 'service', label: 'service', hint: 'Background worker, MCP server, daemon, or long-running process' },
73
- { value: 'monorepo', label: 'monorepo', hint: 'Multiple packages/apps in one repo (apps, APIs, libraries, etc.)' },
74
- { value: 'other', label: 'other', hint: 'Something else — docs site, infra config, or anything not listed above' },
75
- ],
76
- });
77
- if (clack.isCancel(projectType))
78
- return null;
79
- // Complexity
80
- const complexity = await clack.select({
81
- message: 'How complex is this project? (determines which lifecycle phases are used)',
82
- options: [
83
- {
84
- value: 'simple',
85
- label: 'simple',
86
- hint: 'Small tasks — skip straight to implementation and testing',
87
- },
88
- {
89
- value: 'moderate',
90
- label: 'moderate',
91
- hint: 'Typical features — includes requirements, design, implementation, and testing',
92
- },
93
- {
94
- value: 'complex',
95
- label: 'complex',
96
- hint: 'Large features — full lifecycle from ideation through maintenance with review gates',
97
- },
98
- ],
99
- });
100
- if (clack.isCancel(complexity))
101
- return null;
102
- // Platforms
103
- const platforms = await clack.multiselect({
104
- message: 'Which AI coding platforms will you use? (generates config files for each)',
105
- options: [
106
- { value: 'claude-code', label: 'claude-code', hint: 'Anthropic Claude Code (CLAUDE.md)' },
107
- { value: 'codex', label: 'codex', hint: 'OpenAI Codex CLI (AGENTS.md)' },
108
- { value: 'cursor', label: 'cursor', hint: 'Cursor IDE (.cursor/rules/)' },
109
- { value: 'kiro', label: 'kiro', hint: 'Kiro IDE (.kiro/steering/)' },
110
- { value: 'windsurf', label: 'windsurf', hint: 'Windsurf IDE (.windsurfrules)' },
111
- ],
112
- required: false,
113
- });
114
- if (clack.isCancel(platforms))
115
- return null;
116
- // Default template
117
- const template = await clack.select({
118
- message: 'Default workflow template (defines the phases and artifacts for each lifecycle run):',
119
- options: [
120
- {
121
- value: 'micro-task',
122
- label: 'micro-task',
123
- hint: 'Minimal: implementation → testing only',
124
- },
125
- {
126
- value: 'quick-feature',
127
- label: 'quick-feature',
128
- hint: 'Standard: requirements → design → implementation → testing → deployment',
129
- },
130
- {
131
- value: 'full-feature',
132
- label: 'full-feature',
133
- hint: 'Complete: ideation through maintenance with adversarial review gates',
134
- },
135
- {
136
- value: 'bugfix',
137
- label: 'bugfix',
138
- hint: 'Bug fixes: reproduction → requirements → implementation → testing → deployment',
139
- },
140
- {
141
- value: 'spike',
142
- label: 'spike',
143
- hint: 'Research/exploration: ideation → findings documentation',
144
- },
145
- ],
146
- initialValue: COMPLEXITY_DEFAULTS[complexity]?.template ?? 'micro-task',
147
- });
148
- if (clack.isCancel(template))
149
- return null;
150
- // Default scope
151
- const scope = await clack.select({
152
- message: 'Default scope (controls how many lifecycle phases are active per run):',
153
- options: [
154
- {
155
- value: 'full',
156
- label: 'full',
157
- hint: 'All phases enabled — ideation, requirements, design, implementation, testing, deployment, maintenance',
158
- },
159
- {
160
- value: 'standard',
161
- label: 'standard',
162
- hint: 'Core phases — requirements, design, implementation, testing, deployment',
163
- },
164
- {
165
- value: 'micro',
166
- label: 'micro',
167
- hint: 'Minimal — implementation and testing only (fastest)',
168
- },
169
- ],
170
- initialValue: COMPLEXITY_DEFAULTS[complexity]?.scope ?? 'micro',
171
- });
172
- if (clack.isCancel(scope))
173
- return null;
174
- return {
175
- projectType: projectType,
176
- complexity: complexity,
177
- platforms: platforms,
178
- template: template,
179
- scope: scope,
180
- };
181
- }
182
- // ---------------------------------------------------------------------------
183
- // Command registration
184
- // ---------------------------------------------------------------------------
185
- /**
186
- * Register the `aidlc setup` command on the given commander program.
187
- */
188
- export function registerSetup(program) {
189
- program
190
- .command('setup')
191
- .description('Interactive setup or update of AIDLC configuration')
192
- .option('--non-interactive', 'Skip prompts, use defaults or existing config')
193
- .action(async (opts) => {
194
- await runSetup(opts);
195
- });
196
- }
197
- // ---------------------------------------------------------------------------
198
- // Core logic
199
- // ---------------------------------------------------------------------------
200
- async function runSetup(opts) {
201
- const projectRoot = process.cwd();
202
- const configPath = join(projectRoot, '.aidlc', 'config.yaml');
203
- // Load existing config
204
- const existing = loadExistingConfig(projectRoot);
205
- const isUpdate = existing !== null;
206
- let answers;
207
- if (opts.nonInteractive) {
208
- // Non-interactive: use empty answers (preserve existing or apply defaults)
209
- answers = {};
210
- }
211
- else {
212
- // Interactive: collect answers via prompts
213
- const collected = await collectInteractiveAnswers(existing);
214
- if (collected === null) {
215
- process.stderr.write('Setup cancelled.\n');
216
- process.exitCode = 1;
217
- return;
218
- }
219
- answers = collected;
220
- }
221
- // Compute the resulting config
222
- const config = computeSetup(existing, answers);
223
- // Write `.aidlc/config.yaml`
224
- saveYaml(configPath, config);
225
- // Run `aidlc init` for each configured platform
226
- if (config.platforms.length > 0) {
227
- const { registerInit } = await import('./init.js');
228
- for (const platform of config.platforms) {
229
- process.stderr.write(`Running init for platform: ${platform}\n`);
230
- const initProgram = new Command();
231
- initProgram.exitOverride();
232
- registerInit(initProgram);
233
- try {
234
- await initProgram.parseAsync(['init', '--platform', platform], { from: 'user' });
235
- }
236
- catch {
237
- // commander throws on exitOverride; non-fatal for setup
238
- }
239
- }
240
- }
241
- // Run discover to generate context docs
242
- process.stderr.write('Running discover...\n');
243
- try {
244
- const { registerDiscover } = await import('./discover.js');
245
- const discoverProgram = new Command();
246
- discoverProgram.exitOverride();
247
- registerDiscover(discoverProgram);
248
- await discoverProgram.parseAsync(['discover'], { from: 'user' });
249
- }
250
- catch {
251
- // Non-fatal: discover may fail on empty projects
252
- }
253
- // Print summary
254
- process.stdout.write(`\n${isUpdate ? 'Configuration updated' : 'Setup complete'}:\n`);
255
- process.stdout.write(` Config: ${configPath}\n`);
256
- process.stdout.write(` Scope: ${config.defaults.scope}\n`);
257
- process.stdout.write(` Template: ${config.defaults.template}\n`);
258
- process.stdout.write(` Platforms: ${config.platforms.length > 0 ? config.platforms.join(', ') : 'none'}\n`);
259
- process.stdout.write(` Actions: ${config.actions.length > 0 ? config.actions.join(', ') : 'none'}\n`);
260
- process.stdout.write('\n');
261
- }
262
- //# sourceMappingURL=setup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}