@e0ipso/ai-task-manager 1.19.0 → 1.21.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.
@@ -1,229 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
-
6
- // Enable debug logging via environment variable
7
- const DEBUG = process.env.DEBUG === 'true';
8
-
9
- /**
10
- * Debug logging utility
11
- * @param {string} message - Debug message
12
- * @param {...any} args - Additional arguments to log
13
- */
14
- function debugLog(message, ...args) {
15
- if (DEBUG) {
16
- console.error(`[DEBUG] ${message}`, ...args);
17
- }
18
- }
19
-
20
- /**
21
- * Error logging utility
22
- * @param {string} message - Error message
23
- * @param {...any} args - Additional arguments to log
24
- */
25
- function errorLog(message, ...args) {
26
- console.error(`[ERROR] ${message}`, ...args);
27
- }
28
-
29
- /**
30
- * Find the task manager root directory by traversing up from current working directory
31
- * @returns {string|null} Path to task manager root or null if not found
32
- */
33
- function findTaskManagerRoot() {
34
- let currentPath = process.cwd();
35
- const filesystemRoot = path.parse(currentPath).root;
36
-
37
- debugLog(`Starting search for task manager root from: ${currentPath}`);
38
-
39
- while (currentPath !== filesystemRoot) {
40
- const taskManagerPlansPath = path.join(currentPath, '.ai', 'task-manager', 'plans');
41
- debugLog(`Checking for task manager at: ${taskManagerPlansPath}`);
42
-
43
- try {
44
- if (fs.existsSync(taskManagerPlansPath)) {
45
- const stats = fs.lstatSync(taskManagerPlansPath);
46
- if (stats.isDirectory()) {
47
- const taskManagerRoot = path.join(currentPath, '.ai', 'task-manager');
48
- debugLog(`Found valid task manager root at: ${taskManagerRoot}`);
49
- return taskManagerRoot;
50
- }
51
- }
52
- } catch (err) {
53
- debugLog(`Filesystem error checking ${taskManagerPlansPath}: ${err.message}`);
54
- }
55
-
56
- const parentPath = path.dirname(currentPath);
57
- if (parentPath === currentPath) {
58
- break;
59
- }
60
-
61
- currentPath = parentPath;
62
- }
63
-
64
- debugLog(`Task manager root not found in any parent directory`);
65
- return null;
66
- }
67
-
68
- /**
69
- * Find plan file by ID in plans or archive directories
70
- * @param {string} taskManagerRoot - Path to task manager root
71
- * @param {string} planId - Plan ID to find
72
- * @returns {string|null} Path to plan file or null if not found
73
- */
74
- function findPlanFile(taskManagerRoot, planId) {
75
- const plansDir = path.join(taskManagerRoot, 'plans');
76
- const archiveDir = path.join(taskManagerRoot, 'archive');
77
-
78
- debugLog(`Searching for plan ${planId} in ${plansDir} and ${archiveDir}`);
79
-
80
- for (const dir of [plansDir, archiveDir]) {
81
- if (!fs.existsSync(dir)) {
82
- debugLog(`Directory does not exist: ${dir}`);
83
- continue;
84
- }
85
-
86
- try {
87
- const entries = fs.readdirSync(dir, { withFileTypes: true });
88
-
89
- for (const entry of entries) {
90
- if (entry.isDirectory() && entry.name.match(/^\d+--/)) {
91
- // Check if directory matches plan ID
92
- const dirMatch = entry.name.match(/^(\d+)--/);
93
- if (dirMatch && dirMatch[1] === planId) {
94
- const planDirPath = path.join(dir, entry.name);
95
- debugLog(`Found plan directory: ${planDirPath}`);
96
-
97
- // Look for plan file inside directory
98
- try {
99
- const planDirEntries = fs.readdirSync(planDirPath, { withFileTypes: true });
100
-
101
- for (const planEntry of planDirEntries) {
102
- if (planEntry.isFile() && planEntry.name.match(/^plan-\d+--.*\.md$/)) {
103
- const planFilePath = path.join(planDirPath, planEntry.name);
104
- debugLog(`Found plan file: ${planFilePath}`);
105
- return planFilePath;
106
- }
107
- }
108
- } catch (err) {
109
- debugLog(`Failed to read plan directory ${planDirPath}: ${err.message}`);
110
- }
111
- }
112
- } else if (entry.isFile() && entry.name.match(/^plan-\d+--.*\.md$/)) {
113
- // Legacy: direct plan file in plans/archive directory
114
- const filenameMatch = entry.name.match(/^plan-(\d+)--/);
115
- if (filenameMatch && filenameMatch[1] === planId) {
116
- const planFilePath = path.join(dir, entry.name);
117
- debugLog(`Found legacy plan file: ${planFilePath}`);
118
- return planFilePath;
119
- }
120
- }
121
- }
122
- } catch (err) {
123
- errorLog(`Failed to read directory ${dir}: ${err.message}`);
124
- }
125
- }
126
-
127
- return null;
128
- }
129
-
130
- /**
131
- * Extract a field value from YAML frontmatter
132
- * @param {string} frontmatter - YAML frontmatter text
133
- * @param {string} fieldName - Field name to extract
134
- * @param {string} defaultValue - Default value if field not found
135
- * @returns {string} Field value or default
136
- */
137
- function extractField(frontmatter, fieldName, defaultValue = 'manual') {
138
- debugLog(`Extracting field: ${fieldName}`);
139
-
140
- // Pattern to match field with various formatting:
141
- // - field: value
142
- // - field: "value"
143
- // - field: 'value'
144
- // - "field": value
145
- // - field : value (extra spaces)
146
- const regex = new RegExp(`^\\s*["']?${fieldName}["']?\\s*:\\s*(.+)$`, 'm');
147
- const match = frontmatter.match(regex);
148
-
149
- if (!match) {
150
- debugLog(`Field ${fieldName} not found, using default: ${defaultValue}`);
151
- return defaultValue;
152
- }
153
-
154
- // Clean up value: remove quotes and trim
155
- let value = match[1].trim();
156
- value = value.replace(/^['"]|['"]$/g, '');
157
-
158
- debugLog(`Extracted ${fieldName}: ${value}`);
159
- return value || defaultValue;
160
- }
161
-
162
- /**
163
- * Main function to get approval methods from plan file
164
- */
165
- function main() {
166
- // Get plan ID from command line
167
- const planId = process.argv[2];
168
- if (!planId) {
169
- errorLog('Error: Plan ID is required');
170
- console.error('Usage: node get-approval-methods.cjs <plan-id>');
171
- process.exit(1);
172
- }
173
-
174
- debugLog(`Looking for plan ID: ${planId}`);
175
-
176
- // Find task manager root
177
- const taskManagerRoot = findTaskManagerRoot();
178
- if (!taskManagerRoot) {
179
- errorLog('No .ai/task-manager directory found in current directory or any parent directory.');
180
- errorLog('Please ensure you are in a project with task manager initialized.');
181
- errorLog(`Current working directory: ${process.cwd()}`);
182
- process.exit(1);
183
- }
184
-
185
- // Find plan file
186
- const planFile = findPlanFile(taskManagerRoot, planId);
187
- if (!planFile) {
188
- errorLog(`Plan file for ID ${planId} not found in plans or archive directories.`);
189
- process.exit(1);
190
- }
191
-
192
- debugLog(`Reading plan file: ${planFile}`);
193
-
194
- // Read plan file
195
- let content;
196
- try {
197
- content = fs.readFileSync(planFile, 'utf8');
198
- } catch (err) {
199
- errorLog(`Failed to read plan file ${planFile}: ${err.message}`);
200
- process.exit(1);
201
- }
202
-
203
- // Extract YAML frontmatter
204
- const frontmatterRegex = /^---\s*\r?\n([\s\S]*?)\r?\n---/;
205
- const match = content.match(frontmatterRegex);
206
-
207
- if (!match) {
208
- errorLog('No YAML frontmatter found in plan file');
209
- process.exit(1);
210
- }
211
-
212
- const frontmatter = match[1];
213
- debugLog(`Found frontmatter:\n${frontmatter}`);
214
-
215
- // Extract approval method fields
216
- const approvalMethodPlan = extractField(frontmatter, 'approval_method_plan');
217
- const approvalMethodTasks = extractField(frontmatter, 'approval_method_tasks');
218
-
219
- // Output JSON
220
- const result = {
221
- approval_method_plan: approvalMethodPlan,
222
- approval_method_tasks: approvalMethodTasks
223
- };
224
-
225
- console.log(JSON.stringify(result, null, 2));
226
- }
227
-
228
- // Run main function
229
- main();