@rasensio/aidlc 1.4.0 → 1.6.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 (86) hide show
  1. package/dist/commands/claim.d.ts +8 -6
  2. package/dist/commands/claim.d.ts.map +1 -1
  3. package/dist/commands/claim.js +49 -41
  4. package/dist/commands/claim.js.map +1 -1
  5. package/dist/commands/gate.d.ts.map +1 -1
  6. package/dist/commands/gate.js +20 -2
  7. package/dist/commands/gate.js.map +1 -1
  8. package/dist/commands/init.js +13 -0
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/start.d.ts.map +1 -1
  11. package/dist/commands/start.js +145 -4
  12. package/dist/commands/start.js.map +1 -1
  13. package/dist/commands/status.d.ts.map +1 -1
  14. package/dist/commands/status.js +110 -3
  15. package/dist/commands/status.js.map +1 -1
  16. package/dist/commands/transition.d.ts.map +1 -1
  17. package/dist/commands/transition.js +39 -4
  18. package/dist/commands/transition.js.map +1 -1
  19. package/dist/commands/update.d.ts.map +1 -1
  20. package/dist/commands/update.js +13 -0
  21. package/dist/commands/update.js.map +1 -1
  22. package/dist/concurrency/claim-store.d.ts +44 -0
  23. package/dist/concurrency/claim-store.d.ts.map +1 -0
  24. package/dist/concurrency/claim-store.js +273 -0
  25. package/dist/concurrency/claim-store.js.map +1 -0
  26. package/dist/concurrency/common-dir.d.ts +25 -0
  27. package/dist/concurrency/common-dir.d.ts.map +1 -0
  28. package/dist/concurrency/common-dir.js +81 -0
  29. package/dist/concurrency/common-dir.js.map +1 -0
  30. package/dist/concurrency/detect.d.ts +23 -0
  31. package/dist/concurrency/detect.d.ts.map +1 -0
  32. package/dist/concurrency/detect.js +59 -0
  33. package/dist/concurrency/detect.js.map +1 -0
  34. package/dist/concurrency/gitattributes.d.ts +23 -0
  35. package/dist/concurrency/gitattributes.d.ts.map +1 -0
  36. package/dist/concurrency/gitattributes.js +52 -0
  37. package/dist/concurrency/gitattributes.js.map +1 -0
  38. package/dist/concurrency/registry.d.ts +48 -0
  39. package/dist/concurrency/registry.d.ts.map +1 -0
  40. package/dist/concurrency/registry.js +163 -0
  41. package/dist/concurrency/registry.js.map +1 -0
  42. package/dist/concurrency/session-id.d.ts +22 -0
  43. package/dist/concurrency/session-id.d.ts.map +1 -0
  44. package/dist/concurrency/session-id.js +35 -0
  45. package/dist/concurrency/session-id.js.map +1 -0
  46. package/dist/concurrency/types.d.ts +39 -0
  47. package/dist/concurrency/types.d.ts.map +1 -0
  48. package/dist/concurrency/types.js +12 -0
  49. package/dist/concurrency/types.js.map +1 -0
  50. package/dist/concurrency/worktree.d.ts +49 -0
  51. package/dist/concurrency/worktree.d.ts.map +1 -0
  52. package/dist/concurrency/worktree.js +169 -0
  53. package/dist/concurrency/worktree.js.map +1 -0
  54. package/dist/core/gate.d.ts +19 -1
  55. package/dist/core/gate.d.ts.map +1 -1
  56. package/dist/core/gate.js +18 -1
  57. package/dist/core/gate.js.map +1 -1
  58. package/dist/core/lifecycle.d.ts.map +1 -1
  59. package/dist/core/lifecycle.js +7 -3
  60. package/dist/core/lifecycle.js.map +1 -1
  61. package/dist/core/types.d.ts +16 -1
  62. package/dist/core/types.d.ts.map +1 -1
  63. package/dist/cost/ledger.d.ts.map +1 -1
  64. package/dist/cost/ledger.js +6 -0
  65. package/dist/cost/ledger.js.map +1 -1
  66. package/dist/cost/sessions.d.ts +6 -1
  67. package/dist/cost/sessions.d.ts.map +1 -1
  68. package/dist/cost/sessions.js +10 -1
  69. package/dist/cost/sessions.js.map +1 -1
  70. package/dist/tasks/gate-criterion.d.ts +42 -0
  71. package/dist/tasks/gate-criterion.d.ts.map +1 -0
  72. package/dist/tasks/gate-criterion.js +180 -0
  73. package/dist/tasks/gate-criterion.js.map +1 -0
  74. package/dist/tasks/parser.d.ts +30 -0
  75. package/dist/tasks/parser.d.ts.map +1 -0
  76. package/dist/tasks/parser.js +200 -0
  77. package/dist/tasks/parser.js.map +1 -0
  78. package/dist/tasks/status.d.ts +20 -0
  79. package/dist/tasks/status.d.ts.map +1 -0
  80. package/dist/tasks/status.js +41 -0
  81. package/dist/tasks/status.js.map +1 -0
  82. package/dist/tasks/types.d.ts +90 -0
  83. package/dist/tasks/types.d.ts.map +1 -0
  84. package/dist/tasks/types.js +9 -0
  85. package/dist/tasks/types.js.map +1 -0
  86. package/package.json +2 -2
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Task-line parser: closed grammar over tasks.md (FR1).
3
+ *
4
+ * Accepted forms (column-0 dash bullets only; indented task-shaped lines are
5
+ * near-misses, F7):
6
+ * - [ ] T<n>: <title>
7
+ * - [ ] T<n>: <title> (AC-1, other-instance/AC-2)
8
+ * - [x] T<n>: <title> (AC-3)
9
+ * - [>] T<n>: <title> [(AC-list)] (deferred YYYY-MM-DD: <reason>)
10
+ *
11
+ * Structural groups are extracted right-to-left (DD2): trailing parenthesized
12
+ * groups are structural when their content is deferral-shaped, keyword-colon,
13
+ * or AC-shaped; the first non-structural group ends the unwind (title prose).
14
+ * An AC-shaped group failing the strict list grammar is a near-miss (F5) —
15
+ * intended refs must never silently drop. Unrecognized keyword-colon groups
16
+ * (e.g. the reserved v2 `owner:`) keep the task and warn (AC-29).
17
+ *
18
+ * Anything task-shaped that fails the strict grammar warns rather than
19
+ * silently dropping out of gate coverage (AC-5).
20
+ *
21
+ * Requirements: task-breakdown/AC-1..AC-5, AC-29
22
+ */
23
+ // Loose: any bullet (numbered included, like the AC lint) + checkbox-ish +
24
+ // T<n>-ish token → near-miss candidate (AC-5). Keeps leading whitespace so
25
+ // indented task-shaped lines warn (F7).
26
+ const TASK_SHAPED_RE = /^\s*(?:[-*+]|\d+\.)\s+\[[^\]]?\]\s*T\d+/i;
27
+ // Strict prefix: column-0 dash bullet, exact checkbox, exact ID, colon,
28
+ // non-empty rest (F13).
29
+ const TASK_PREFIX_RE = /^-\s+\[( |x|>)\]\s+T([1-9][0-9]*):\s+(\S.*)$/;
30
+ // A trailing parenthesized group is structural when its content starts with
31
+ // a deferral keyword, a lowercase keyword-colon, or an AC token (F1, F11).
32
+ const STRUCTURAL_SHAPED_RE = /^(?:deferred[ :]|[a-z][a-z-]*:|AC-\d|[a-z0-9-]+\/AC-\d)/;
33
+ const DEFERRAL_RE = /^deferred (\d{4}-\d{2}-\d{2}): (.+)$/;
34
+ const AC_ITEM = String.raw `(?:([a-z0-9-]+)\/)?AC-([1-9][0-9]*)`;
35
+ const AC_LIST_RE = new RegExp(String.raw `^${AC_ITEM}(?:,\s*${AC_ITEM})*$`);
36
+ const AC_ITEM_G = new RegExp(AC_ITEM, 'g');
37
+ // Groups that begin with an AC token belong to the AC-list grammar; failing
38
+ // it is a near-miss (F5), not an AC-29 unrecognized token.
39
+ const AC_SHAPED_GROUP_RE = /^(?:AC-\d|[a-z0-9-]+\/AC-\d)/;
40
+ const STATE_BY_MARKER = { ' ': 'open', x: 'done', '>': 'deferred' };
41
+ // Most-blocking wins on duplicate IDs with conflicting states (AC-3, DD3).
42
+ const BLOCK_RANK = { open: 0, deferred: 1, done: 2 };
43
+ function excerpt(line) {
44
+ const trimmed = line.trim();
45
+ return trimmed.length > 60 ? `${trimmed.slice(0, 57)}...` : trimmed;
46
+ }
47
+ /**
48
+ * Unwind trailing parenthesized groups right-to-left (DD2), classifying each
49
+ * against the normative order `<title> [(AC-list)] [(deferral)]`.
50
+ */
51
+ function extractGroups(rest) {
52
+ const result = {
53
+ title: rest,
54
+ acList: null,
55
+ deferral: null,
56
+ unrecognized: [],
57
+ nearMiss: null,
58
+ };
59
+ const groups = [];
60
+ let remainder = rest;
61
+ for (;;) {
62
+ const m = /^(.*?)\s*\(([^()]*)\)$/.exec(remainder);
63
+ if (!m || !STRUCTURAL_SHAPED_RE.test(m[2]))
64
+ break;
65
+ groups.unshift(m[2]);
66
+ remainder = m[1];
67
+ }
68
+ result.title = remainder;
69
+ // Groups are now in left-to-right order; enforce [AC-list] [deferral].
70
+ let sawDeferral = false;
71
+ for (const content of groups) {
72
+ if (content.startsWith('deferred')) {
73
+ const d = DEFERRAL_RE.exec(content);
74
+ if (!d) {
75
+ result.nearMiss = 'malformed deferral marker';
76
+ return result;
77
+ }
78
+ if (result.deferral) {
79
+ result.nearMiss = 'duplicate deferral marker';
80
+ return result;
81
+ }
82
+ result.deferral = { date: d[1], reason: d[2] };
83
+ sawDeferral = true;
84
+ continue;
85
+ }
86
+ if (sawDeferral) {
87
+ result.nearMiss = 'structural group after the deferral marker';
88
+ return result;
89
+ }
90
+ if (AC_SHAPED_GROUP_RE.test(content)) {
91
+ if (!AC_LIST_RE.test(content)) {
92
+ result.nearMiss = 'malformed AC list';
93
+ return result;
94
+ }
95
+ if (result.acList !== null) {
96
+ result.nearMiss = 'duplicate AC list';
97
+ return result;
98
+ }
99
+ result.acList = content;
100
+ continue;
101
+ }
102
+ // Keyword-colon group with an unrecognized keyword: keep and warn (AC-29).
103
+ result.unrecognized.push(content);
104
+ }
105
+ if (result.title.length === 0) {
106
+ result.nearMiss = 'empty title';
107
+ }
108
+ return result;
109
+ }
110
+ function parseAcRefs(acList) {
111
+ const refs = [];
112
+ for (const m of acList.matchAll(AC_ITEM_G)) {
113
+ refs.push({ instance: m[1] ?? null, id: Number(m[2]) });
114
+ }
115
+ return refs;
116
+ }
117
+ /**
118
+ * Parse one tasks.md for task lines.
119
+ *
120
+ * @param content - File content (UTF-8). Never throws.
121
+ */
122
+ export function parseTasks(content) {
123
+ const warnings = [];
124
+ const malformedDeferrals = [];
125
+ const byId = new Map();
126
+ let taskShapedLines = 0;
127
+ const lines = content.split('\n');
128
+ for (let i = 0; i < lines.length; i++) {
129
+ const line = lines[i];
130
+ const lineNo = i + 1;
131
+ if (!TASK_SHAPED_RE.test(line))
132
+ continue;
133
+ taskShapedLines++;
134
+ const prefix = TASK_PREFIX_RE.exec(line);
135
+ if (!prefix) {
136
+ warnings.push(`line ${lineNo}: "${excerpt(line)}" resembles a task but does not match the grammar`);
137
+ continue;
138
+ }
139
+ const state = STATE_BY_MARKER[prefix[1]];
140
+ const id = Number(prefix[2]);
141
+ const groups = extractGroups(prefix[3]);
142
+ if (groups.nearMiss) {
143
+ // A [>] line whose deferral itself is malformed is the AC-2 parse
144
+ // error, not an ordinary near-miss — it must fail the gate.
145
+ if (state === 'deferred' && groups.nearMiss.includes('deferral')) {
146
+ malformedDeferrals.push({ id, line: lineNo });
147
+ warnings.push(`line ${lineNo}: task T${id} has a malformed deferral marker`);
148
+ }
149
+ else {
150
+ warnings.push(`line ${lineNo}: "${excerpt(line)}" — ${groups.nearMiss}`);
151
+ }
152
+ continue;
153
+ }
154
+ if (state === 'deferred' && !groups.deferral) {
155
+ malformedDeferrals.push({ id, line: lineNo });
156
+ warnings.push(`line ${lineNo}: task T${id} is deferred without a (deferred YYYY-MM-DD: reason) marker`);
157
+ continue;
158
+ }
159
+ if (state !== 'deferred' && groups.deferral) {
160
+ warnings.push(`line ${lineNo}: "${excerpt(line)}" — deferral marker on a ${state} task`);
161
+ continue;
162
+ }
163
+ for (const token of groups.unrecognized) {
164
+ warnings.push(`line ${lineNo}: task T${id} has an unrecognized trailing token "(${token})"`);
165
+ }
166
+ const task = {
167
+ id,
168
+ state,
169
+ title: groups.title,
170
+ acRefs: groups.acList ? parseAcRefs(groups.acList) : [],
171
+ line: lineNo,
172
+ ...(groups.deferral && {
173
+ deferReason: groups.deferral.reason,
174
+ deferDate: groups.deferral.date,
175
+ }),
176
+ };
177
+ const existing = byId.get(id);
178
+ if (existing) {
179
+ warnings.push(`duplicate T${id}: lines ${existing.line} and ${lineNo} (${existing.state === task.state
180
+ ? 'first occurrence wins'
181
+ : 'most-blocking state wins'})`);
182
+ if (BLOCK_RANK[task.state] < BLOCK_RANK[existing.state]) {
183
+ byId.set(id, task);
184
+ }
185
+ continue;
186
+ }
187
+ byId.set(id, task);
188
+ }
189
+ // Sequence gaps (AC-4), over parsed ids.
190
+ if (byId.size > 0) {
191
+ const maxId = Math.max(...byId.keys());
192
+ for (let n = 1; n <= maxId; n++) {
193
+ if (!byId.has(n))
194
+ warnings.push(`T${n} is never defined (sequence gap)`);
195
+ }
196
+ }
197
+ const tasks = [...byId.values()].sort((a, b) => a.id - b.id);
198
+ return { tasks, malformedDeferrals, warnings, taskShapedLines };
199
+ }
200
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/tasks/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Task summary for the `aidlc status` column (task-breakdown AC-21).
3
+ *
4
+ * One file read per task-bearing instance, no glob, no cache (NFR4/DD4 —
5
+ * unlike traceability, there is no repo scan to amortize). Phase visibility
6
+ * (design-or-later, with an implementation anchor for templates without a
7
+ * design phase, F3) is checked by the caller, matching the
8
+ * `isTestingOrLater` precedent.
9
+ */
10
+ import type { TasksSummary } from './types.js';
11
+ /**
12
+ * Read and summarize one instance's tasks.md.
13
+ *
14
+ * @returns null when the file is absent, unreadable, or defines no tasks —
15
+ * the column renders `-`.
16
+ */
17
+ export declare function tasksForStatus(projectRoot: string, instanceName: string): TasksSummary | null;
18
+ /** Format for the status table: `done/total`, plus ` ▸n` when deferred (AC-21). */
19
+ export declare function formatTasks(summary: TasksSummary): string;
20
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/tasks/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAc7F;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAGzD"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Task summary for the `aidlc status` column (task-breakdown AC-21).
3
+ *
4
+ * One file read per task-bearing instance, no glob, no cache (NFR4/DD4 —
5
+ * unlike traceability, there is no repo scan to amortize). Phase visibility
6
+ * (design-or-later, with an implementation anchor for templates without a
7
+ * design phase, F3) is checked by the caller, matching the
8
+ * `isTestingOrLater` precedent.
9
+ */
10
+ import { readFileSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ import { parseTasks } from './parser.js';
13
+ /**
14
+ * Read and summarize one instance's tasks.md.
15
+ *
16
+ * @returns null when the file is absent, unreadable, or defines no tasks —
17
+ * the column renders `-`.
18
+ */
19
+ export function tasksForStatus(projectRoot, instanceName) {
20
+ let content;
21
+ try {
22
+ content = readFileSync(join(projectRoot, '.aidlc', 'state', instanceName, 'tasks.md'), 'utf8');
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ const { tasks } = parseTasks(content);
28
+ if (tasks.length === 0)
29
+ return null;
30
+ return {
31
+ done: tasks.filter((t) => t.state === 'done').length,
32
+ deferred: tasks.filter((t) => t.state === 'deferred').length,
33
+ total: tasks.length,
34
+ };
35
+ }
36
+ /** Format for the status table: `done/total`, plus ` ▸n` when deferred (AC-21). */
37
+ export function formatTasks(summary) {
38
+ const base = `${summary.done}/${summary.total}`;
39
+ return summary.deferred > 0 ? `${base} ▸${summary.deferred}` : base;
40
+ }
41
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/tasks/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,YAAoB;IACtE,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;IACjG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,MAAM;QACpD,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,MAAM;QAC5D,KAAK,EAAE,KAAK,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,WAAW,CAAC,OAAqB;IAC/C,MAAM,IAAI,GAAG,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAChD,OAAO,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACtE,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Tasks types: task lines parsed from tasks.md, the gate-criterion result
3
+ * exposed via `aidlc gate --json` (task-breakdown AC-19), and the status
4
+ * column summary (AC-21).
5
+ *
6
+ * Design: design.md (task-breakdown) §1
7
+ */
8
+ export type TaskState = 'open' | 'done' | 'deferred';
9
+ /** One AC reference in a task line's AC list. */
10
+ export interface TaskAcRef {
11
+ /** n in AC-n (≥1, no leading zeros). */
12
+ id: number;
13
+ /**
14
+ * Qualified instance name, or null for a bare token. Bare refs resolve to
15
+ * the owning instance (DD8) — never traceability's uniqueness rule.
16
+ */
17
+ instance: string | null;
18
+ }
19
+ /** A single task line parsed from tasks.md (FR1). */
20
+ export interface TaskLine {
21
+ /** n in T<n> (≥1, no leading zeros). */
22
+ id: number;
23
+ state: TaskState;
24
+ /** Non-empty title prose (empty titles are near-misses). */
25
+ title: string;
26
+ acRefs: TaskAcRef[];
27
+ /** Present iff state === 'deferred'. */
28
+ deferReason?: string;
29
+ /** YYYY-MM-DD, shape-validated only; present iff state === 'deferred'. */
30
+ deferDate?: string;
31
+ /** 1-based line number in tasks.md. */
32
+ line: number;
33
+ }
34
+ /** Parse result for one instance's tasks.md. */
35
+ export interface ParsedTasks {
36
+ /** Ordered by id (NFR3); most-blocking state wins on duplicates (AC-3). */
37
+ tasks: TaskLine[];
38
+ /**
39
+ * `[>]` lines without a well-formed deferral marker (AC-2) — these force
40
+ * the criterion unsatisfied, unlike ordinary near-misses. Only lines whose
41
+ * strict prefix (id included) parsed can land here; a `[>]` line with a
42
+ * broken prefix is an ordinary near-miss (AC-5).
43
+ */
44
+ malformedDeferrals: {
45
+ id: number;
46
+ line: number;
47
+ }[];
48
+ /** Duplicates, near-misses, sequence gaps — ordered by line (NFR3). */
49
+ warnings: string[];
50
+ /**
51
+ * Lines matching the loose task pattern (tasks + malformed + near-misses).
52
+ * Drives the applicability tri-state (DD7): 0 → criterion silent for
53
+ * opt-in instances; >0 with no tasks → warnings-only result.
54
+ */
55
+ taskShapedLines: number;
56
+ }
57
+ /** Per-task row of the gate JSON `tasks` field (AC-19). */
58
+ export interface TaskEntry {
59
+ id: number;
60
+ state: TaskState;
61
+ title: string;
62
+ /** Rendered as written: `AC-3` or `other-instance/AC-3`. */
63
+ acRefs: string[];
64
+ deferReason?: string;
65
+ }
66
+ /** Full tasks result attached to GateCheckResult (AC-19). */
67
+ export interface TasksResult {
68
+ /** Posix-separated, project-root-relative tasks.md path. */
69
+ tasksPath: string;
70
+ /** Sorted by id (NFR3). */
71
+ entries: TaskEntry[];
72
+ /** Ordered by line (NFR3). */
73
+ warnings: string[];
74
+ /** Open ([ ]) task ids — drive gate failure (AC-11). */
75
+ openTasks: number[];
76
+ /** Malformed-deferral task ids (AC-2) — also drive gate failure. */
77
+ malformed: number[];
78
+ /** Set when the AC-17 (file) / AC-28 (empty) backstop fails the gate. */
79
+ missing?: 'file' | 'empty';
80
+ }
81
+ /** Task summary for the `aidlc status` column (AC-21). */
82
+ export interface TasksSummary {
83
+ /** [x] count — deferred is NOT counted here. */
84
+ done: number;
85
+ /** [>] count, rendered as ` ▸n` when > 0. */
86
+ deferred: number;
87
+ /** All task lines, deferred included. */
88
+ total: number;
89
+ }
90
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tasks/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAErD,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,qDAAqD;AACrD,MAAM,WAAW,QAAQ;IACvB,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,CAAC;IACjB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB;;;;;OAKG;IACH,kBAAkB,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnD,uEAAuE;IACvE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,2DAA2D;AAC3D,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,6DAA6D;AAC7D,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,wDAAwD;IACxD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oEAAoE;IACpE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Tasks types: task lines parsed from tasks.md, the gate-criterion result
3
+ * exposed via `aidlc gate --json` (task-breakdown AC-19), and the status
4
+ * column summary (AC-21).
5
+ *
6
+ * Design: design.md (task-breakdown) §1
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tasks/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rasensio/aidlc",
3
- "version": "1.4.0",
3
+ "version": "1.6.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.4.0"
27
+ "@rasensio/aidlc-content": "1.6.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "22.15.32",