aiag-cli 1.0.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 (65) hide show
  1. package/LICENSE +41 -0
  2. package/README.md +150 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +80 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/commit.d.ts +6 -0
  8. package/dist/commands/commit.d.ts.map +1 -0
  9. package/dist/commands/commit.js +90 -0
  10. package/dist/commands/commit.js.map +1 -0
  11. package/dist/commands/complete.d.ts +6 -0
  12. package/dist/commands/complete.d.ts.map +1 -0
  13. package/dist/commands/complete.js +73 -0
  14. package/dist/commands/complete.js.map +1 -0
  15. package/dist/commands/init.d.ts +7 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +164 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/next.d.ts +7 -0
  20. package/dist/commands/next.d.ts.map +1 -0
  21. package/dist/commands/next.js +77 -0
  22. package/dist/commands/next.js.map +1 -0
  23. package/dist/commands/session.d.ts +3 -0
  24. package/dist/commands/session.d.ts.map +1 -0
  25. package/dist/commands/session.js +65 -0
  26. package/dist/commands/session.js.map +1 -0
  27. package/dist/commands/status.d.ts +7 -0
  28. package/dist/commands/status.d.ts.map +1 -0
  29. package/dist/commands/status.js +78 -0
  30. package/dist/commands/status.js.map +1 -0
  31. package/dist/commands/test.d.ts +7 -0
  32. package/dist/commands/test.d.ts.map +1 -0
  33. package/dist/commands/test.js +170 -0
  34. package/dist/commands/test.js.map +1 -0
  35. package/dist/index.d.ts +12 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +13 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/types.d.ts +53 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +9 -0
  42. package/dist/types.js.map +1 -0
  43. package/dist/utils/agentSelection.d.ts +28 -0
  44. package/dist/utils/agentSelection.d.ts.map +1 -0
  45. package/dist/utils/agentSelection.js +66 -0
  46. package/dist/utils/agentSelection.js.map +1 -0
  47. package/dist/utils/featureList.d.ts +109 -0
  48. package/dist/utils/featureList.d.ts.map +1 -0
  49. package/dist/utils/featureList.js +465 -0
  50. package/dist/utils/featureList.js.map +1 -0
  51. package/dist/utils/output.d.ts +71 -0
  52. package/dist/utils/output.d.ts.map +1 -0
  53. package/dist/utils/output.js +115 -0
  54. package/dist/utils/output.js.map +1 -0
  55. package/dist/utils/progress.d.ts +31 -0
  56. package/dist/utils/progress.d.ts.map +1 -0
  57. package/dist/utils/progress.js +165 -0
  58. package/dist/utils/progress.js.map +1 -0
  59. package/dist/utils/prompts.d.ts +50 -0
  60. package/dist/utils/prompts.d.ts.map +1 -0
  61. package/dist/utils/prompts.js +111 -0
  62. package/dist/utils/prompts.js.map +1 -0
  63. package/package.json +56 -0
  64. package/templates/coding.md +142 -0
  65. package/templates/initializer.md +125 -0
@@ -0,0 +1,66 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ const AIAG_DIR = '.aiag';
4
+ /**
5
+ * Determine which agent type should be active based on project state
6
+ *
7
+ * - Initializer Agent: When .aiag/ directory does NOT exist
8
+ * - Coding Agent: When .aiag/ directory exists
9
+ */
10
+ export function getAgentType(cwd = process.cwd()) {
11
+ const aiagPath = path.join(cwd, AIAG_DIR);
12
+ return fs.existsSync(aiagPath) ? 'coding' : 'initializer';
13
+ }
14
+ /**
15
+ * Check if AIAG project is initialized
16
+ */
17
+ export function isAiagInitialized(cwd = process.cwd()) {
18
+ const aiagPath = path.join(cwd, AIAG_DIR);
19
+ return fs.existsSync(aiagPath);
20
+ }
21
+ /**
22
+ * Get agent description for display
23
+ */
24
+ export function getAgentDescription(agentType) {
25
+ switch (agentType) {
26
+ case 'initializer':
27
+ return 'Initializer Agent - Sets up new AIAG project structure';
28
+ case 'coding':
29
+ return 'Coding Agent - Implements features one at a time';
30
+ }
31
+ }
32
+ /**
33
+ * Get agent prompt template path
34
+ */
35
+ export function getAgentTemplatePath(agentType, cwd = process.cwd()) {
36
+ const templatesDir = path.join(cwd, AIAG_DIR, 'templates');
37
+ if (!fs.existsSync(templatesDir)) {
38
+ return null;
39
+ }
40
+ const templateFile = agentType === 'initializer' ? 'initializer.md' : 'coding.md';
41
+ const templatePath = path.join(templatesDir, templateFile);
42
+ return fs.existsSync(templatePath) ? templatePath : null;
43
+ }
44
+ /**
45
+ * Validate that the correct agent is being used based on project state
46
+ */
47
+ export function validateAgentContext(expectedAgent, cwd = process.cwd()) {
48
+ const currentAgent = getAgentType(cwd);
49
+ if (currentAgent === expectedAgent) {
50
+ return { valid: true, message: 'Agent context is valid' };
51
+ }
52
+ if (expectedAgent === 'initializer' && currentAgent === 'coding') {
53
+ return {
54
+ valid: false,
55
+ message: 'AIAG is already initialized. Use Coding Agent instead.',
56
+ };
57
+ }
58
+ if (expectedAgent === 'coding' && currentAgent === 'initializer') {
59
+ return {
60
+ valid: false,
61
+ message: 'AIAG not initialized. Run "aiag init" first or use Initializer Agent.',
62
+ };
63
+ }
64
+ return { valid: false, message: 'Unknown agent context error' };
65
+ }
66
+ //# sourceMappingURL=agentSelection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentSelection.js","sourceRoot":"","sources":["../../src/utils/agentSelection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B,MAAM,QAAQ,GAAG,OAAO,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1C,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1C,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAoB;IACtD,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,aAAa;YAChB,OAAO,wDAAwD,CAAC;QAClE,KAAK,QAAQ;YACX,OAAO,kDAAkD,CAAC;IAC9D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAAoB,EACpB,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAE3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,SAAS,KAAK,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC;IAClF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAE3D,OAAO,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,aAAwB,EACxB,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAEvC,IAAI,YAAY,KAAK,aAAa,EAAE,CAAC;QACnC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC;IAC5D,CAAC;IAED,IAAI,aAAa,KAAK,aAAa,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,wDAAwD;SAClE,CAAC;IACJ,CAAC;IAED,IAAI,aAAa,KAAK,QAAQ,IAAI,YAAY,KAAK,aAAa,EAAE,CAAC;QACjE,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,uEAAuE;SACjF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC;AAClE,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { FeatureList, Feature, FeatureCategory } from '../types.js';
2
+ export interface ValidationResult {
3
+ valid: boolean;
4
+ errors: string[];
5
+ }
6
+ /**
7
+ * Validate project object schema
8
+ */
9
+ export declare function validateProject(project: unknown): ValidationResult;
10
+ /**
11
+ * Validate a single feature object schema
12
+ */
13
+ export declare function validateFeature(feature: unknown, index: number): ValidationResult;
14
+ /**
15
+ * Validate the entire feature_list.json schema
16
+ */
17
+ export declare function validateFeatureList(data: unknown): ValidationResult;
18
+ /**
19
+ * Get the path to feature_list.json
20
+ */
21
+ export declare function getFeatureListPath(baseDir?: string): string;
22
+ /**
23
+ * Check if .aiag directory exists
24
+ */
25
+ export declare function aiagExists(baseDir?: string): boolean;
26
+ /**
27
+ * Read feature_list.json
28
+ */
29
+ export declare function readFeatureList(baseDir?: string): FeatureList | null;
30
+ /**
31
+ * Write feature_list.json
32
+ */
33
+ export declare function writeFeatureList(data: FeatureList, baseDir?: string): boolean;
34
+ /**
35
+ * Get feature by ID
36
+ */
37
+ export declare function getFeatureById(id: string, baseDir?: string): Feature | null;
38
+ /**
39
+ * Update feature passes status
40
+ */
41
+ export declare function updateFeaturePasses(id: string, passes: boolean, baseDir?: string): boolean;
42
+ /**
43
+ * Get incomplete features sorted by priority
44
+ */
45
+ export declare function getIncompleteFeatures(baseDir?: string): Feature[];
46
+ /**
47
+ * Get next feature to work on
48
+ */
49
+ export declare function getNextFeature(category?: FeatureCategory, baseDir?: string): Feature | null;
50
+ /**
51
+ * Get progress statistics
52
+ */
53
+ export declare function getProgress(baseDir?: string): {
54
+ total: number;
55
+ completed: number;
56
+ percentage: number;
57
+ byCategory: Record<string, {
58
+ total: number;
59
+ completed: number;
60
+ }>;
61
+ };
62
+ /**
63
+ * Get recently completed features
64
+ */
65
+ export declare function getRecentlyCompleted(count?: number, baseDir?: string): Feature[];
66
+ /**
67
+ * Generate next feature ID for a category
68
+ */
69
+ export declare function generateFeatureId(category: FeatureCategory, baseDir?: string): string;
70
+ /**
71
+ * Check if a feature ID already exists
72
+ */
73
+ export declare function featureIdExists(id: string, baseDir?: string): boolean;
74
+ /**
75
+ * Get all feature IDs for a category
76
+ */
77
+ export declare function getFeatureIdsByCategory(category: FeatureCategory, baseDir?: string): string[];
78
+ /**
79
+ * Get dependencies for a feature
80
+ */
81
+ export declare function getFeatureDependencies(featureId: string, baseDir?: string): string[];
82
+ /**
83
+ * Check if all dependencies of a feature are satisfied (passes: true)
84
+ */
85
+ export declare function areDependenciesSatisfied(featureId: string, baseDir?: string): {
86
+ satisfied: boolean;
87
+ unsatisfied: string[];
88
+ };
89
+ /**
90
+ * Get features that depend on a given feature
91
+ */
92
+ export declare function getDependentFeatures(featureId: string, baseDir?: string): string[];
93
+ /**
94
+ * Get dependency graph for visualization
95
+ */
96
+ export declare function getDependencyGraph(baseDir?: string): Map<string, {
97
+ dependsOn: string[];
98
+ dependedBy: string[];
99
+ }>;
100
+ /**
101
+ * Check for circular dependencies
102
+ */
103
+ export declare function hasCircularDependency(featureId: string, baseDir?: string): boolean;
104
+ /**
105
+ * Get features sorted by dependency order (topological sort)
106
+ * Features with no dependencies come first
107
+ */
108
+ export declare function getFeaturesByDependencyOrder(baseDir?: string): Feature[];
109
+ //# sourceMappingURL=featureList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureList.d.ts","sourceRoot":"","sources":["../../src/utils/featureList.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,465 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { PRIORITY_ORDER, } from '../types.js';
4
+ const AIAG_DIR = '.aiag';
5
+ const FEATURE_LIST_FILE = 'feature_list.json';
6
+ // Valid categories and priorities for validation
7
+ const VALID_CATEGORIES = [
8
+ 'core',
9
+ 'cli',
10
+ 'api',
11
+ 'ui',
12
+ 'auth',
13
+ 'data',
14
+ 'test',
15
+ 'docs',
16
+ 'devops',
17
+ 'claude',
18
+ 'agent',
19
+ 'feature',
20
+ ];
21
+ const VALID_PRIORITIES = ['critical', 'high', 'medium', 'low'];
22
+ /**
23
+ * Validate project object schema
24
+ */
25
+ export function validateProject(project) {
26
+ const errors = [];
27
+ if (!project || typeof project !== 'object') {
28
+ return { valid: false, errors: ['project must be an object'] };
29
+ }
30
+ const p = project;
31
+ // Required string fields
32
+ if (typeof p.name !== 'string' || p.name.length === 0) {
33
+ errors.push('project.name must be a non-empty string');
34
+ }
35
+ if (typeof p.version !== 'string' || p.version.length === 0) {
36
+ errors.push('project.version must be a non-empty string');
37
+ }
38
+ if (typeof p.description !== 'string') {
39
+ errors.push('project.description must be a string');
40
+ }
41
+ // Required number fields
42
+ if (typeof p.totalFeatures !== 'number' || p.totalFeatures < 0) {
43
+ errors.push('project.totalFeatures must be a non-negative number');
44
+ }
45
+ if (typeof p.completedFeatures !== 'number' || p.completedFeatures < 0) {
46
+ errors.push('project.completedFeatures must be a non-negative number');
47
+ }
48
+ // Logical validation
49
+ if (typeof p.totalFeatures === 'number' &&
50
+ typeof p.completedFeatures === 'number' &&
51
+ p.completedFeatures > p.totalFeatures) {
52
+ errors.push('project.completedFeatures cannot exceed project.totalFeatures');
53
+ }
54
+ return { valid: errors.length === 0, errors };
55
+ }
56
+ /**
57
+ * Validate a single feature object schema
58
+ */
59
+ export function validateFeature(feature, index) {
60
+ const errors = [];
61
+ const prefix = `features[${index}]`;
62
+ if (!feature || typeof feature !== 'object') {
63
+ return { valid: false, errors: [`${prefix} must be an object`] };
64
+ }
65
+ const f = feature;
66
+ // Required: id (string, format: CATEGORY-NNN)
67
+ if (typeof f.id !== 'string' || f.id.length === 0) {
68
+ errors.push(`${prefix}.id must be a non-empty string`);
69
+ }
70
+ else if (!/^[A-Z]+-\d{3}$/.test(f.id)) {
71
+ errors.push(`${prefix}.id must match format CATEGORY-NNN (e.g., CORE-001)`);
72
+ }
73
+ // Required: category (valid category)
74
+ if (typeof f.category !== 'string') {
75
+ errors.push(`${prefix}.category must be a string`);
76
+ }
77
+ else if (!VALID_CATEGORIES.includes(f.category)) {
78
+ errors.push(`${prefix}.category must be one of: ${VALID_CATEGORIES.join(', ')}`);
79
+ }
80
+ // Required: priority (valid priority)
81
+ if (typeof f.priority !== 'string') {
82
+ errors.push(`${prefix}.priority must be a string`);
83
+ }
84
+ else if (!VALID_PRIORITIES.includes(f.priority)) {
85
+ errors.push(`${prefix}.priority must be one of: ${VALID_PRIORITIES.join(', ')}`);
86
+ }
87
+ // Required: description (non-empty string)
88
+ if (typeof f.description !== 'string' || f.description.length === 0) {
89
+ errors.push(`${prefix}.description must be a non-empty string`);
90
+ }
91
+ // Required: acceptanceCriteria (array of strings)
92
+ if (!Array.isArray(f.acceptanceCriteria)) {
93
+ errors.push(`${prefix}.acceptanceCriteria must be an array`);
94
+ }
95
+ else if (f.acceptanceCriteria.length === 0) {
96
+ errors.push(`${prefix}.acceptanceCriteria must have at least one criterion`);
97
+ }
98
+ else {
99
+ for (let i = 0; i < f.acceptanceCriteria.length; i++) {
100
+ if (typeof f.acceptanceCriteria[i] !== 'string') {
101
+ errors.push(`${prefix}.acceptanceCriteria[${i}] must be a string`);
102
+ }
103
+ }
104
+ }
105
+ // Required: passes (boolean)
106
+ if (typeof f.passes !== 'boolean') {
107
+ errors.push(`${prefix}.passes must be a boolean`);
108
+ }
109
+ // Optional: testCommand (string if present)
110
+ if (f.testCommand !== undefined && typeof f.testCommand !== 'string') {
111
+ errors.push(`${prefix}.testCommand must be a string if provided`);
112
+ }
113
+ // Optional: lastTestedAt (string or null)
114
+ if (f.lastTestedAt !== undefined &&
115
+ f.lastTestedAt !== null &&
116
+ typeof f.lastTestedAt !== 'string') {
117
+ errors.push(`${prefix}.lastTestedAt must be a string or null`);
118
+ }
119
+ // Optional: implementedBy (string or null)
120
+ if (f.implementedBy !== undefined &&
121
+ f.implementedBy !== null &&
122
+ typeof f.implementedBy !== 'string') {
123
+ errors.push(`${prefix}.implementedBy must be a string or null`);
124
+ }
125
+ // Optional: notes (string if present)
126
+ if (f.notes !== undefined && typeof f.notes !== 'string') {
127
+ errors.push(`${prefix}.notes must be a string if provided`);
128
+ }
129
+ return { valid: errors.length === 0, errors };
130
+ }
131
+ /**
132
+ * Validate the entire feature_list.json schema
133
+ */
134
+ export function validateFeatureList(data) {
135
+ const errors = [];
136
+ if (!data || typeof data !== 'object') {
137
+ return { valid: false, errors: ['feature_list must be an object'] };
138
+ }
139
+ const d = data;
140
+ // Validate project
141
+ const projectResult = validateProject(d.project);
142
+ errors.push(...projectResult.errors);
143
+ // Validate features array
144
+ if (!Array.isArray(d.features)) {
145
+ errors.push('features must be an array');
146
+ }
147
+ else {
148
+ // Check for duplicate IDs
149
+ const ids = new Set();
150
+ for (let i = 0; i < d.features.length; i++) {
151
+ const featureResult = validateFeature(d.features[i], i);
152
+ errors.push(...featureResult.errors);
153
+ // Check duplicate IDs
154
+ const feature = d.features[i];
155
+ if (typeof feature.id === 'string') {
156
+ if (ids.has(feature.id)) {
157
+ errors.push(`Duplicate feature ID: ${feature.id}`);
158
+ }
159
+ ids.add(feature.id);
160
+ }
161
+ }
162
+ }
163
+ return { valid: errors.length === 0, errors };
164
+ }
165
+ /**
166
+ * Get the path to feature_list.json
167
+ */
168
+ export function getFeatureListPath(baseDir = process.cwd()) {
169
+ return path.join(baseDir, AIAG_DIR, FEATURE_LIST_FILE);
170
+ }
171
+ /**
172
+ * Check if .aiag directory exists
173
+ */
174
+ export function aiagExists(baseDir = process.cwd()) {
175
+ return fs.existsSync(path.join(baseDir, AIAG_DIR));
176
+ }
177
+ /**
178
+ * Read feature_list.json
179
+ */
180
+ export function readFeatureList(baseDir = process.cwd()) {
181
+ const filePath = getFeatureListPath(baseDir);
182
+ if (!fs.existsSync(filePath)) {
183
+ return null;
184
+ }
185
+ try {
186
+ const content = fs.readFileSync(filePath, 'utf-8');
187
+ return JSON.parse(content);
188
+ }
189
+ catch (error) {
190
+ console.error('Error reading feature_list.json:', error);
191
+ return null;
192
+ }
193
+ }
194
+ /**
195
+ * Write feature_list.json
196
+ */
197
+ export function writeFeatureList(data, baseDir = process.cwd()) {
198
+ const filePath = getFeatureListPath(baseDir);
199
+ try {
200
+ // Update counts
201
+ data.project.totalFeatures = data.features.length;
202
+ data.project.completedFeatures = data.features.filter((f) => f.passes).length;
203
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
204
+ return true;
205
+ }
206
+ catch (error) {
207
+ console.error('Error writing feature_list.json:', error);
208
+ return false;
209
+ }
210
+ }
211
+ /**
212
+ * Get feature by ID
213
+ */
214
+ export function getFeatureById(id, baseDir = process.cwd()) {
215
+ const data = readFeatureList(baseDir);
216
+ if (!data)
217
+ return null;
218
+ return data.features.find((f) => f.id === id) || null;
219
+ }
220
+ /**
221
+ * Update feature passes status
222
+ */
223
+ export function updateFeaturePasses(id, passes, baseDir = process.cwd()) {
224
+ const data = readFeatureList(baseDir);
225
+ if (!data)
226
+ return false;
227
+ const feature = data.features.find((f) => f.id === id);
228
+ if (!feature)
229
+ return false;
230
+ feature.passes = passes;
231
+ feature.lastTestedAt = new Date().toISOString();
232
+ return writeFeatureList(data, baseDir);
233
+ }
234
+ /**
235
+ * Get incomplete features sorted by priority
236
+ */
237
+ export function getIncompleteFeatures(baseDir = process.cwd()) {
238
+ const data = readFeatureList(baseDir);
239
+ if (!data)
240
+ return [];
241
+ return data.features
242
+ .filter((f) => !f.passes)
243
+ .sort((a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]);
244
+ }
245
+ /**
246
+ * Get next feature to work on
247
+ */
248
+ export function getNextFeature(category, baseDir = process.cwd()) {
249
+ let features = getIncompleteFeatures(baseDir);
250
+ if (category) {
251
+ features = features.filter((f) => f.category === category);
252
+ }
253
+ return features[0] || null;
254
+ }
255
+ /**
256
+ * Get progress statistics
257
+ */
258
+ export function getProgress(baseDir = process.cwd()) {
259
+ const data = readFeatureList(baseDir);
260
+ if (!data) {
261
+ return { total: 0, completed: 0, percentage: 0, byCategory: {} };
262
+ }
263
+ const total = data.features.length;
264
+ const completed = data.features.filter((f) => f.passes).length;
265
+ const percentage = total > 0 ? Math.round((completed / total) * 100) : 0;
266
+ const byCategory = {};
267
+ for (const feature of data.features) {
268
+ if (!byCategory[feature.category]) {
269
+ byCategory[feature.category] = { total: 0, completed: 0 };
270
+ }
271
+ byCategory[feature.category].total++;
272
+ if (feature.passes) {
273
+ byCategory[feature.category].completed++;
274
+ }
275
+ }
276
+ return { total, completed, percentage, byCategory };
277
+ }
278
+ /**
279
+ * Get recently completed features
280
+ */
281
+ export function getRecentlyCompleted(count = 5, baseDir = process.cwd()) {
282
+ const data = readFeatureList(baseDir);
283
+ if (!data)
284
+ return [];
285
+ return data.features
286
+ .filter((f) => f.passes && f.lastTestedAt)
287
+ .sort((a, b) => {
288
+ const dateA = new Date(a.lastTestedAt).getTime();
289
+ const dateB = new Date(b.lastTestedAt).getTime();
290
+ return dateB - dateA;
291
+ })
292
+ .slice(0, count);
293
+ }
294
+ /**
295
+ * Generate next feature ID for a category
296
+ */
297
+ export function generateFeatureId(category, baseDir = process.cwd()) {
298
+ const data = readFeatureList(baseDir);
299
+ const prefix = category.toUpperCase();
300
+ if (!data) {
301
+ return `${prefix}-001`;
302
+ }
303
+ // Find all existing IDs for this category
304
+ const existingIds = data.features
305
+ .filter((f) => f.id.startsWith(prefix + '-'))
306
+ .map((f) => {
307
+ const num = parseInt(f.id.split('-')[1], 10);
308
+ return isNaN(num) ? 0 : num;
309
+ });
310
+ // Find next available number
311
+ const maxNum = existingIds.length > 0 ? Math.max(...existingIds) : 0;
312
+ const nextNum = maxNum + 1;
313
+ // Format with leading zeros (3 digits)
314
+ return `${prefix}-${nextNum.toString().padStart(3, '0')}`;
315
+ }
316
+ /**
317
+ * Check if a feature ID already exists
318
+ */
319
+ export function featureIdExists(id, baseDir = process.cwd()) {
320
+ const data = readFeatureList(baseDir);
321
+ if (!data)
322
+ return false;
323
+ return data.features.some((f) => f.id === id);
324
+ }
325
+ /**
326
+ * Get all feature IDs for a category
327
+ */
328
+ export function getFeatureIdsByCategory(category, baseDir = process.cwd()) {
329
+ const data = readFeatureList(baseDir);
330
+ if (!data)
331
+ return [];
332
+ const prefix = category.toUpperCase();
333
+ return data.features
334
+ .filter((f) => f.id.startsWith(prefix + '-'))
335
+ .map((f) => f.id)
336
+ .sort();
337
+ }
338
+ /**
339
+ * Get dependencies for a feature
340
+ */
341
+ export function getFeatureDependencies(featureId, baseDir = process.cwd()) {
342
+ const feature = getFeatureById(featureId, baseDir);
343
+ if (!feature || !feature.dependsOn)
344
+ return [];
345
+ return feature.dependsOn;
346
+ }
347
+ /**
348
+ * Check if all dependencies of a feature are satisfied (passes: true)
349
+ */
350
+ export function areDependenciesSatisfied(featureId, baseDir = process.cwd()) {
351
+ const dependencies = getFeatureDependencies(featureId, baseDir);
352
+ if (dependencies.length === 0) {
353
+ return { satisfied: true, unsatisfied: [] };
354
+ }
355
+ const unsatisfied = [];
356
+ for (const depId of dependencies) {
357
+ const dep = getFeatureById(depId, baseDir);
358
+ if (!dep) {
359
+ unsatisfied.push(`${depId} (not found)`);
360
+ }
361
+ else if (!dep.passes) {
362
+ unsatisfied.push(depId);
363
+ }
364
+ }
365
+ return {
366
+ satisfied: unsatisfied.length === 0,
367
+ unsatisfied,
368
+ };
369
+ }
370
+ /**
371
+ * Get features that depend on a given feature
372
+ */
373
+ export function getDependentFeatures(featureId, baseDir = process.cwd()) {
374
+ const data = readFeatureList(baseDir);
375
+ if (!data)
376
+ return [];
377
+ return data.features
378
+ .filter((f) => f.dependsOn && f.dependsOn.includes(featureId))
379
+ .map((f) => f.id);
380
+ }
381
+ /**
382
+ * Get dependency graph for visualization
383
+ */
384
+ export function getDependencyGraph(baseDir = process.cwd()) {
385
+ const data = readFeatureList(baseDir);
386
+ if (!data)
387
+ return new Map();
388
+ const graph = new Map();
389
+ // Initialize all features
390
+ for (const feature of data.features) {
391
+ graph.set(feature.id, {
392
+ dependsOn: feature.dependsOn || [],
393
+ dependedBy: [],
394
+ });
395
+ }
396
+ // Build reverse dependencies
397
+ for (const feature of data.features) {
398
+ if (feature.dependsOn) {
399
+ for (const depId of feature.dependsOn) {
400
+ const depNode = graph.get(depId);
401
+ if (depNode) {
402
+ depNode.dependedBy.push(feature.id);
403
+ }
404
+ }
405
+ }
406
+ }
407
+ return graph;
408
+ }
409
+ /**
410
+ * Check for circular dependencies
411
+ */
412
+ export function hasCircularDependency(featureId, baseDir = process.cwd()) {
413
+ const visited = new Set();
414
+ const recursionStack = new Set();
415
+ function dfs(id) {
416
+ visited.add(id);
417
+ recursionStack.add(id);
418
+ const deps = getFeatureDependencies(id, baseDir);
419
+ for (const depId of deps) {
420
+ if (!visited.has(depId)) {
421
+ if (dfs(depId))
422
+ return true;
423
+ }
424
+ else if (recursionStack.has(depId)) {
425
+ return true;
426
+ }
427
+ }
428
+ recursionStack.delete(id);
429
+ return false;
430
+ }
431
+ return dfs(featureId);
432
+ }
433
+ /**
434
+ * Get features sorted by dependency order (topological sort)
435
+ * Features with no dependencies come first
436
+ */
437
+ export function getFeaturesByDependencyOrder(baseDir = process.cwd()) {
438
+ const data = readFeatureList(baseDir);
439
+ if (!data)
440
+ return [];
441
+ const result = [];
442
+ const visited = new Set();
443
+ const featureMap = new Map(data.features.map((f) => [f.id, f]));
444
+ function visit(id) {
445
+ if (visited.has(id))
446
+ return;
447
+ visited.add(id);
448
+ const feature = featureMap.get(id);
449
+ if (!feature)
450
+ return;
451
+ // Visit dependencies first
452
+ if (feature.dependsOn) {
453
+ for (const depId of feature.dependsOn) {
454
+ visit(depId);
455
+ }
456
+ }
457
+ result.push(feature);
458
+ }
459
+ // Visit all features
460
+ for (const feature of data.features) {
461
+ visit(feature.id);
462
+ }
463
+ return result;
464
+ }
465
+ //# sourceMappingURL=featureList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureList.js","sourceRoot":"","sources":["../../src/utils/featureList.ts"],"names":[],"mappings":"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"}