@e0ipso/ai-task-manager 1.26.2 → 1.26.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/ai-task-manager/config/scripts/check-task-dependencies.cjs +212 -300
- package/templates/ai-task-manager/config/scripts/find-root.cjs +10 -0
- package/templates/ai-task-manager/config/scripts/get-next-plan-id.cjs +22 -404
- package/templates/ai-task-manager/config/scripts/get-next-task-id.cjs +29 -108
- package/templates/ai-task-manager/config/scripts/shared-utils.cjs +418 -0
- package/templates/ai-task-manager/config/scripts/validate-plan-blueprint.cjs +79 -274
- package/templates/assistant/commands/tasks/create-plan.md +16 -4
- package/templates/assistant/commands/tasks/execute-blueprint.md +17 -4
- package/templates/assistant/commands/tasks/execute-task.md +16 -5
- package/templates/assistant/commands/tasks/full-workflow.md +20 -7
- package/templates/assistant/commands/tasks/generate-tasks.md +15 -2
- package/templates/assistant/commands/tasks/refine-plan.md +16 -5
package/package.json
CHANGED
|
@@ -9,349 +9,261 @@
|
|
|
9
9
|
|
|
10
10
|
const fs = require('fs-extra');
|
|
11
11
|
const path = require('path');
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
resolvePlan,
|
|
14
|
+
parseFrontmatter
|
|
15
|
+
} = require('./shared-utils.cjs');
|
|
13
16
|
|
|
14
17
|
// Chalk instance - loaded dynamically to handle ESM module
|
|
15
18
|
let chalkInstance = null;
|
|
16
19
|
|
|
17
20
|
// Initialize chalk instance dynamically
|
|
18
|
-
async function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
async function _initChalk() {
|
|
22
|
+
if (chalkInstance) return chalkInstance;
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const {
|
|
26
|
+
default: chalk
|
|
27
|
+
} = await import('chalk');
|
|
28
|
+
chalkInstance = chalk;
|
|
29
|
+
} catch (_error) {
|
|
30
|
+
// Chalk not available, will fall back to plain console output
|
|
31
|
+
chalkInstance = null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return chalkInstance;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
// Color functions for output
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
const _printError = (message, chalk) => {
|
|
39
|
+
const formattedMessage = chalk?.red(`ERROR: ${message}`) || `ERROR: ${message}`;
|
|
40
|
+
console.error(formattedMessage);
|
|
36
41
|
};
|
|
37
42
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
const _printSuccess = (message, chalk) => {
|
|
44
|
+
const formattedMessage = chalk?.green(`✓ ${message}`) || `✓ ${message}`;
|
|
45
|
+
console.log(formattedMessage);
|
|
41
46
|
};
|
|
42
47
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
const _printWarning = (message, chalk) => {
|
|
49
|
+
const formattedMessage = chalk?.yellow(`⚠ ${message}`) || `⚠ ${message}`;
|
|
50
|
+
console.log(formattedMessage);
|
|
46
51
|
};
|
|
47
52
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// Function to find plan directory
|
|
53
|
-
const findPlanDirectory = (planId) => {
|
|
54
|
-
const searchLocations = [
|
|
55
|
-
'.ai/task-manager/plans',
|
|
56
|
-
'.ai/task-manager/archive'
|
|
57
|
-
];
|
|
58
|
-
|
|
59
|
-
// Generate ID variations to try (exact, padded, unpadded)
|
|
60
|
-
const idVariations = [
|
|
61
|
-
planId, // Try exact match first
|
|
62
|
-
planId.padStart(2, '0'), // Try padded version (3 → 03)
|
|
63
|
-
planId.replace(/^0+/, '') || '0' // Try unpadded version (03 → 3)
|
|
64
|
-
];
|
|
65
|
-
|
|
66
|
-
// Remove duplicates from variations array
|
|
67
|
-
const uniqueVariations = [...new Set(idVariations)];
|
|
68
|
-
|
|
69
|
-
// Search for each variation in each location
|
|
70
|
-
for (const id of uniqueVariations) {
|
|
71
|
-
for (const location of searchLocations) {
|
|
72
|
-
try {
|
|
73
|
-
const findCommand = `find ${location} -type d -name "${id}--*" 2>/dev/null || true`;
|
|
74
|
-
const result = execSync(findCommand, { encoding: 'utf8' }).trim();
|
|
75
|
-
const directories = result.split('\n').filter(dir => dir.length > 0);
|
|
76
|
-
|
|
77
|
-
if (directories.length > 0) {
|
|
78
|
-
return directories[0]; // Early return on first match
|
|
79
|
-
}
|
|
80
|
-
} catch (error) {
|
|
81
|
-
// Continue trying other variations/locations
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return null; // No matches found
|
|
53
|
+
const _printInfo = (message) => {
|
|
54
|
+
console.log(message);
|
|
88
55
|
};
|
|
89
56
|
|
|
90
57
|
// Function to find task file with padded/unpadded ID handling
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (!fs.existsSync(taskDir)) {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Try exact match first
|
|
99
|
-
let pattern = `${taskId}--*.md`;
|
|
100
|
-
let files = fs.readdirSync(taskDir).filter(file => {
|
|
101
|
-
const regex = new RegExp(`^${taskId}--.*\\.md$`);
|
|
102
|
-
return regex.test(file);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
if (files.length > 0) {
|
|
106
|
-
return path.join(taskDir, files[0]);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Try with zero-padding if direct match fails
|
|
110
|
-
const paddedTaskId = taskId.padStart(2, '0');
|
|
111
|
-
if (paddedTaskId !== taskId) {
|
|
112
|
-
pattern = `${paddedTaskId}--*.md`;
|
|
113
|
-
files = fs.readdirSync(taskDir).filter(file => {
|
|
114
|
-
const regex = new RegExp(`^${paddedTaskId}--.*\\.md$`);
|
|
115
|
-
return regex.test(file);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
if (files.length > 0) {
|
|
119
|
-
return path.join(taskDir, files[0]);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Try removing potential zero-padding from taskId
|
|
124
|
-
const unpaddedTaskId = taskId.replace(/^0+/, '') || '0';
|
|
125
|
-
if (unpaddedTaskId !== taskId) {
|
|
126
|
-
pattern = `${unpaddedTaskId}--*.md`;
|
|
127
|
-
files = fs.readdirSync(taskDir).filter(file => {
|
|
128
|
-
const regex = new RegExp(`^${unpaddedTaskId}--.*\\.md$`);
|
|
129
|
-
return regex.test(file);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
if (files.length > 0) {
|
|
133
|
-
return path.join(taskDir, files[0]);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Try with zero-padding of unpadded version
|
|
137
|
-
const repaddedTaskId = unpaddedTaskId.padStart(2, '0');
|
|
138
|
-
pattern = `${repaddedTaskId}--*.md`;
|
|
139
|
-
files = fs.readdirSync(taskDir).filter(file => {
|
|
140
|
-
const regex = new RegExp(`^${repaddedTaskId}--.*\\.md$`);
|
|
141
|
-
return regex.test(file);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
if (files.length > 0) {
|
|
145
|
-
return path.join(taskDir, files[0]);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
58
|
+
const _findTaskFile = (planDir, taskId) => {
|
|
59
|
+
const taskDir = path.join(planDir, 'tasks');
|
|
148
60
|
|
|
61
|
+
if (!fs.existsSync(taskDir)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const variations = [
|
|
66
|
+
taskId,
|
|
67
|
+
taskId.padStart(2, '0'),
|
|
68
|
+
taskId.replace(/^0+/, '') || '0'
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
const uniqueVariations = [...new Set(variations)];
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const files = fs.readdirSync(taskDir);
|
|
75
|
+
const found = uniqueVariations.reduce((acc, v) => {
|
|
76
|
+
if (acc) return acc;
|
|
77
|
+
const match = files.find(f => f.startsWith(`${v}--`) && f.endsWith('.md'));
|
|
78
|
+
return match ? path.join(taskDir, match) : null;
|
|
79
|
+
}, null);
|
|
80
|
+
return found;
|
|
81
|
+
} catch (err) {
|
|
149
82
|
return null;
|
|
83
|
+
}
|
|
150
84
|
};
|
|
151
85
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
86
|
+
|
|
87
|
+
// Function to extract dependencies from frontmatter
|
|
88
|
+
const _extractDependencies = (frontmatter) => {
|
|
89
|
+
const lines = frontmatter.split('\n');
|
|
90
|
+
const dependencies = [];
|
|
91
|
+
let inDependenciesSection = false;
|
|
92
|
+
|
|
93
|
+
for (let i = 0; i < lines.length; i++) {
|
|
94
|
+
const line = lines[i];
|
|
95
|
+
|
|
96
|
+
// Check for dependencies line
|
|
97
|
+
if (line.match(/^dependencies:/)) {
|
|
98
|
+
inDependenciesSection = true;
|
|
99
|
+
|
|
100
|
+
// Check if dependencies are on the same line (array syntax)
|
|
101
|
+
const arrayMatch = line.match(/\[(.*)\]/);
|
|
102
|
+
if (arrayMatch) {
|
|
103
|
+
const deps = arrayMatch[1]
|
|
104
|
+
.split(',')
|
|
105
|
+
.map(dep => dep.trim().replace(/['"]/g, ''))
|
|
106
|
+
.filter(dep => dep.length > 0);
|
|
107
|
+
dependencies.push(...deps);
|
|
108
|
+
inDependenciesSection = false;
|
|
109
|
+
}
|
|
110
|
+
continue;
|
|
175
111
|
}
|
|
176
112
|
|
|
177
|
-
|
|
178
|
-
|
|
113
|
+
// If we're in dependencies section and hit a non-indented line that's not a list item, exit
|
|
114
|
+
if (inDependenciesSection && line.match(/^[^ ]/) && !line.match(/^[ \t]*-/)) {
|
|
115
|
+
inDependenciesSection = false;
|
|
116
|
+
}
|
|
179
117
|
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
for (let i = 0; i < lines.length; i++) {
|
|
187
|
-
const line = lines[i];
|
|
188
|
-
|
|
189
|
-
// Check for dependencies line
|
|
190
|
-
if (line.match(/^dependencies:/)) {
|
|
191
|
-
inDependenciesSection = true;
|
|
192
|
-
|
|
193
|
-
// Check if dependencies are on the same line (array syntax)
|
|
194
|
-
const arrayMatch = line.match(/\[(.*)\]/);
|
|
195
|
-
if (arrayMatch) {
|
|
196
|
-
const deps = arrayMatch[1]
|
|
197
|
-
.split(',')
|
|
198
|
-
.map(dep => dep.trim().replace(/['"]/g, ''))
|
|
199
|
-
.filter(dep => dep.length > 0);
|
|
200
|
-
dependencies.push(...deps);
|
|
201
|
-
inDependenciesSection = false;
|
|
202
|
-
}
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// If we're in dependencies section and hit a non-indented line that's not a list item, exit
|
|
207
|
-
if (inDependenciesSection && line.match(/^[^ ]/) && !line.match(/^[ \t]*-/)) {
|
|
208
|
-
inDependenciesSection = false;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Parse list format dependencies
|
|
212
|
-
if (inDependenciesSection && line.match(/^[ \t]*-/)) {
|
|
213
|
-
const dep = line.replace(/^[ \t]*-[ \t]*/, '').replace(/[ \t]*$/, '').replace(/['"]/g, '');
|
|
214
|
-
if (dep.length > 0) {
|
|
215
|
-
dependencies.push(dep);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
118
|
+
// Parse list format dependencies
|
|
119
|
+
if (inDependenciesSection && line.match(/^[ \t]*-/)) {
|
|
120
|
+
const dep = line.replace(/^[ \t]*-[ \t]*/, '').replace(/[ \t]*$/, '').replace(/['"]/g, '');
|
|
121
|
+
if (dep.length > 0) {
|
|
122
|
+
dependencies.push(dep);
|
|
123
|
+
}
|
|
218
124
|
}
|
|
125
|
+
}
|
|
219
126
|
|
|
220
|
-
|
|
127
|
+
return dependencies;
|
|
221
128
|
};
|
|
222
129
|
|
|
223
130
|
// Function to extract status from frontmatter
|
|
224
|
-
const
|
|
225
|
-
|
|
131
|
+
const _extractStatus = (frontmatter) => {
|
|
132
|
+
const lines = frontmatter.split('\n');
|
|
226
133
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
134
|
+
for (const line of lines) {
|
|
135
|
+
if (line.match(/^status:/)) {
|
|
136
|
+
return line.replace(/^status:[ \t]*/, '').replace(/^["']/, '').replace(/["']$/, '').trim();
|
|
231
137
|
}
|
|
138
|
+
}
|
|
232
139
|
|
|
233
|
-
|
|
140
|
+
return null;
|
|
234
141
|
};
|
|
235
142
|
|
|
236
143
|
// Main function
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
144
|
+
const _main = async (startPath = process.cwd()) => {
|
|
145
|
+
// Initialize chalk
|
|
146
|
+
const chalk = await _initChalk();
|
|
147
|
+
|
|
148
|
+
// Check arguments
|
|
149
|
+
if (process.argv.length !== 4) {
|
|
150
|
+
_printError('Invalid number of arguments', chalk);
|
|
151
|
+
console.log('Usage: node check-task-dependencies.cjs <plan-id-or-path> <task-id>');
|
|
152
|
+
console.log('Example: node check-task-dependencies.cjs 16 03');
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const inputId = process.argv[2];
|
|
157
|
+
const taskId = process.argv[3];
|
|
158
|
+
|
|
159
|
+
const resolved = resolvePlan(inputId, startPath);
|
|
160
|
+
|
|
161
|
+
if (!resolved) {
|
|
162
|
+
_printError(`Plan "${inputId}" not found or invalid`, chalk);
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const {
|
|
167
|
+
planDir,
|
|
168
|
+
planId
|
|
169
|
+
} = resolved;
|
|
170
|
+
_printInfo(`Found plan directory: ${planDir}`);
|
|
171
|
+
|
|
172
|
+
// Find task file
|
|
173
|
+
const taskFile = _findTaskFile(planDir, taskId);
|
|
174
|
+
|
|
175
|
+
if (!taskFile || !fs.existsSync(taskFile)) {
|
|
176
|
+
_printError(`Task with ID ${taskId} not found in plan ${planId}`, chalk);
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
_printInfo(`Checking task: ${path.basename(taskFile)}`);
|
|
181
|
+
console.log('');
|
|
182
|
+
|
|
183
|
+
// Read and parse task file
|
|
184
|
+
const taskContent = fs.readFileSync(taskFile, 'utf8');
|
|
185
|
+
const frontmatter = parseFrontmatter(taskContent);
|
|
186
|
+
const dependencies = _extractDependencies(frontmatter);
|
|
187
|
+
|
|
188
|
+
// Check if there are any dependencies
|
|
189
|
+
if (dependencies.length === 0) {
|
|
190
|
+
_printSuccess('Task has no dependencies - ready to execute!', chalk);
|
|
191
|
+
process.exit(0);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Display dependencies
|
|
195
|
+
_printInfo('Task dependencies found:');
|
|
196
|
+
dependencies.forEach(dep => {
|
|
197
|
+
console.log(` - Task ${dep}`);
|
|
198
|
+
});
|
|
199
|
+
console.log('');
|
|
200
|
+
|
|
201
|
+
// Check each dependency
|
|
202
|
+
let allResolved = true;
|
|
203
|
+
let unresolvedDeps = [];
|
|
204
|
+
let resolvedCount = 0;
|
|
205
|
+
const totalDeps = dependencies.length;
|
|
206
|
+
|
|
207
|
+
_printInfo('Checking dependency status...');
|
|
208
|
+
console.log('');
|
|
209
|
+
|
|
210
|
+
for (const depId of dependencies) {
|
|
211
|
+
// Find dependency task file
|
|
212
|
+
const depFile = _findTaskFile(planDir, depId);
|
|
213
|
+
|
|
214
|
+
if (!depFile || !fs.existsSync(depFile)) {
|
|
215
|
+
_printError(`Dependency task ${depId} not found`, chalk);
|
|
216
|
+
allResolved = false;
|
|
217
|
+
unresolvedDeps.push(`${depId} (not found)`);
|
|
218
|
+
continue;
|
|
282
219
|
}
|
|
283
220
|
|
|
284
|
-
//
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
});
|
|
289
|
-
console.log('');
|
|
290
|
-
|
|
291
|
-
// Check each dependency
|
|
292
|
-
let allResolved = true;
|
|
293
|
-
let unresolvedDeps = [];
|
|
294
|
-
let resolvedCount = 0;
|
|
295
|
-
const totalDeps = dependencies.length;
|
|
296
|
-
|
|
297
|
-
printInfo('Checking dependency status...');
|
|
298
|
-
console.log('');
|
|
299
|
-
|
|
300
|
-
for (const depId of dependencies) {
|
|
301
|
-
// Find dependency task file
|
|
302
|
-
const depFile = findTaskFile(planDir, depId);
|
|
303
|
-
|
|
304
|
-
if (!depFile || !fs.existsSync(depFile)) {
|
|
305
|
-
printError(`Dependency task ${depId} not found`, chalk);
|
|
306
|
-
allResolved = false;
|
|
307
|
-
unresolvedDeps.push(`${depId} (not found)`);
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// Extract status from dependency task
|
|
312
|
-
const depContent = fs.readFileSync(depFile, 'utf8');
|
|
313
|
-
const depFrontmatter = parseFrontmatter(depContent);
|
|
314
|
-
const status = extractStatus(depFrontmatter);
|
|
315
|
-
|
|
316
|
-
// Check if status is completed
|
|
317
|
-
if (status === 'completed') {
|
|
318
|
-
printSuccess(`Task ${depId} - Status: completed ✓`, chalk);
|
|
319
|
-
resolvedCount++;
|
|
320
|
-
} else {
|
|
321
|
-
printWarning(`Task ${depId} - Status: ${status || 'unknown'} ✗`, chalk);
|
|
322
|
-
allResolved = false;
|
|
323
|
-
unresolvedDeps.push(`${depId} (${status || 'unknown'})`);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
221
|
+
// Extract status from dependency task
|
|
222
|
+
const depContent = fs.readFileSync(depFile, 'utf8');
|
|
223
|
+
const depFrontmatter = parseFrontmatter(depContent);
|
|
224
|
+
const status = _extractStatus(depFrontmatter);
|
|
326
225
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
printInfo(`Total dependencies: ${totalDeps}`);
|
|
332
|
-
printInfo(`Resolved: ${resolvedCount}`);
|
|
333
|
-
printInfo(`Unresolved: ${totalDeps - resolvedCount}`);
|
|
334
|
-
console.log('');
|
|
335
|
-
|
|
336
|
-
if (allResolved) {
|
|
337
|
-
printSuccess(`All dependencies are resolved! Task ${taskId} is ready to execute.`, chalk);
|
|
338
|
-
process.exit(0);
|
|
226
|
+
// Check if status is completed
|
|
227
|
+
if (status === 'completed') {
|
|
228
|
+
_printSuccess(`Task ${depId} - Status: completed ✓`, chalk);
|
|
229
|
+
resolvedCount++;
|
|
339
230
|
} else {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
});
|
|
344
|
-
printInfo('Please complete the dependencies before executing this task.');
|
|
345
|
-
process.exit(1);
|
|
231
|
+
_printWarning(`Task ${depId} - Status: ${status || 'unknown'} ✗`, chalk);
|
|
232
|
+
allResolved = false;
|
|
233
|
+
unresolvedDeps.push(`${depId} (${status || 'unknown'})`);
|
|
346
234
|
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
console.log('');
|
|
238
|
+
_printInfo('=========================================');
|
|
239
|
+
_printInfo('Dependency Check Summary');
|
|
240
|
+
_printInfo('=========================================');
|
|
241
|
+
_printInfo(`Total dependencies: ${totalDeps}`);
|
|
242
|
+
_printInfo(`Resolved: ${resolvedCount}`);
|
|
243
|
+
_printInfo(`Unresolved: ${totalDeps - resolvedCount}`);
|
|
244
|
+
console.log('');
|
|
245
|
+
|
|
246
|
+
if (allResolved) {
|
|
247
|
+
_printSuccess(`All dependencies are resolved! Task ${taskId} is ready to execute.`, chalk);
|
|
248
|
+
process.exit(0);
|
|
249
|
+
} else {
|
|
250
|
+
_printError(`Task ${taskId} has unresolved dependencies:`, chalk);
|
|
251
|
+
unresolvedDeps.forEach(dep => {
|
|
252
|
+
console.log(dep);
|
|
253
|
+
});
|
|
254
|
+
_printInfo('Please complete the dependencies before executing this task.');
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
347
257
|
};
|
|
348
258
|
|
|
349
259
|
// Run the script
|
|
350
260
|
if (require.main === module) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
261
|
+
_main().catch((error) => {
|
|
262
|
+
console.error('Script execution failed:', error);
|
|
263
|
+
process.exit(1);
|
|
264
|
+
});
|
|
355
265
|
}
|
|
356
266
|
|
|
357
|
-
module.exports = {
|
|
267
|
+
module.exports = {
|
|
268
|
+
_main
|
|
269
|
+
};
|