@e0ipso/ai-task-manager 1.26.3 → 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.
@@ -2,245 +2,137 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
- const { findTaskManagerRoot } = require('./shared-utils.cjs');
5
+ const sharedUtils = require('./shared-utils.cjs');
6
+ const {
7
+ findTaskManagerRoot,
8
+ findPlanById,
9
+ countTasks,
10
+ checkBlueprintExists,
11
+ getAllPlans,
12
+ validatePlanFile,
13
+ checkStandardRootShortcut,
14
+ resolvePlan
15
+ } = sharedUtils;
6
16
 
7
17
  /**
8
18
  * Error logging utility
19
+ * @private
9
20
  * @param {string} message - Error message
10
21
  * @param {...any} args - Additional arguments to log
11
22
  */
12
- function errorLog(message, ...args) {
23
+ function _errorLog(message, ...args) {
13
24
  console.error(`[ERROR] ${message}`, ...args);
14
25
  }
15
26
 
16
- /**
17
- * Find plan file and directory for a given plan ID
18
- * @param {string|number} planId - Plan ID to search for
19
- * @returns {Object|null} Object with planFile and planDir, or null if not found
20
- */
21
- function findPlanById(planId) {
22
- const taskManagerRoot = findTaskManagerRoot();
23
-
24
- if (!taskManagerRoot) {
25
- errorLog('No .ai/task-manager directory found in current directory or any parent directory.');
26
- return null;
27
- }
28
-
29
- // Convert planId to numeric for flexible matching (handles both "2" and "02")
30
- const numericPlanId = parseInt(planId, 10);
31
-
32
- if (isNaN(numericPlanId)) {
33
- errorLog(`Invalid plan ID: ${planId}. Plan ID must be numeric.`);
34
- return null;
35
- }
36
-
37
- const plansDir = path.join(taskManagerRoot, 'plans');
38
- const archiveDir = path.join(taskManagerRoot, 'archive');
39
-
40
- // Search both plans and archive directories
41
- for (const dir of [plansDir, archiveDir]) {
42
- if (!fs.existsSync(dir)) {
43
- continue;
44
- }
45
-
46
- try {
47
- const entries = fs.readdirSync(dir, { withFileTypes: true });
48
-
49
- for (const entry of entries) {
50
- // Match directory pattern: [plan-id]--* (with flexible ID matching)
51
- if (entry.isDirectory()) {
52
- // Extract numeric ID from directory name, stripping leading zeros
53
- const dirMatch = entry.name.match(/^0*(\d+)--/);
54
- if (dirMatch && parseInt(dirMatch[1], 10) === numericPlanId) {
55
- const planDirPath = path.join(dir, entry.name);
56
-
57
- try {
58
- const planDirEntries = fs.readdirSync(planDirPath, { withFileTypes: true });
59
-
60
- // Look for plan file: plan-[plan-id]--*.md (with flexible ID matching)
61
- for (const planEntry of planDirEntries) {
62
- if (planEntry.isFile()) {
63
- // Extract numeric ID from filename, stripping leading zeros
64
- const fileMatch = planEntry.name.match(/^plan-0*(\d+)--.*\.md$/);
65
- if (fileMatch && parseInt(fileMatch[1], 10) === numericPlanId) {
66
- const planFilePath = path.join(planDirPath, planEntry.name);
67
-
68
- return {
69
- planFile: planFilePath,
70
- planDir: planDirPath
71
- };
72
- }
73
- }
74
- }
75
- } catch (err) {
76
- errorLog(`Failed to read plan directory ${planDirPath}: ${err.message}`);
77
- }
78
- }
79
- }
80
- }
81
- } catch (err) {
82
- errorLog(`Failed to read directory ${dir}: ${err.message}`);
83
- }
84
- }
85
-
86
- return null;
87
- }
88
-
89
- /**
90
- * Count task files in a plan's tasks directory
91
- * @param {string} planDir - Plan directory path
92
- * @returns {number} Number of task files found
93
- */
94
- function countTasks(planDir) {
95
- const tasksDir = path.join(planDir, 'tasks');
96
-
97
- if (!fs.existsSync(tasksDir)) {
98
- return 0;
99
- }
100
-
101
- try {
102
- const stats = fs.lstatSync(tasksDir);
103
- if (!stats.isDirectory()) {
104
- return 0;
105
- }
106
-
107
- const files = fs.readdirSync(tasksDir).filter(f => f.endsWith('.md'));
108
- return files.length;
109
- } catch (err) {
110
- errorLog(`Failed to read tasks directory ${tasksDir}: ${err.message}`);
111
- return 0;
112
- }
113
- }
114
-
115
- /**
116
- * Check if execution blueprint section exists in plan file
117
- * @param {string} planFile - Path to plan file
118
- * @returns {boolean} True if blueprint section exists, false otherwise
119
- */
120
- function checkBlueprintExists(planFile) {
121
- try {
122
- const planContent = fs.readFileSync(planFile, 'utf8');
123
- const blueprintExists = /^## Execution Blueprint/m.test(planContent);
124
- return blueprintExists;
125
- } catch (err) {
126
- errorLog(`Failed to read plan file ${planFile}: ${err.message}`);
127
- return false;
128
- }
129
- }
130
-
131
27
  /**
132
28
  * List available plans for error messaging
29
+ * @private
30
+ * @param {string} [taskManagerRoot] - Optional task manager root path
133
31
  * @returns {string[]} Array of plan directory names
134
32
  */
135
- function listAvailablePlans() {
136
- const taskManagerRoot = findTaskManagerRoot();
137
-
138
- if (!taskManagerRoot) {
139
- return [];
140
- }
141
-
142
- const plansDir = path.join(taskManagerRoot, 'plans');
143
- const archiveDir = path.join(taskManagerRoot, 'archive');
144
- const plans = [];
145
-
146
- for (const dir of [plansDir, archiveDir]) {
147
- if (!fs.existsSync(dir)) {
148
- continue;
149
- }
150
-
151
- try {
152
- const entries = fs.readdirSync(dir, { withFileTypes: true });
153
- for (const entry of entries) {
154
- if (entry.isDirectory() && entry.name.match(/^\d+--/)) {
155
- plans.push(entry.name);
156
- }
157
- }
158
- } catch (err) {
159
- // Silently continue
160
- }
161
- }
162
-
163
- return plans.sort((a, b) => {
164
- const aId = parseInt(a.match(/^(\d+)--/)[1], 10);
165
- const bId = parseInt(b.match(/^(\d+)--/)[1], 10);
166
- return aId - bId;
167
- });
33
+ function _listAvailablePlans(taskManagerRoot) {
34
+ const plans = getAllPlans(taskManagerRoot);
35
+ return plans
36
+ .map(p => p.name)
37
+ .sort((a, b) => {
38
+ const aIdMatch = a.match(/^(\d+)--/);
39
+ const bIdMatch = b.match(/^(\d+)--/);
40
+ if (!aIdMatch || !bIdMatch) return 0;
41
+ return parseInt(aIdMatch[1], 10) - parseInt(bIdMatch[1], 10);
42
+ });
168
43
  }
169
44
 
170
45
  /**
171
46
  * Validate plan blueprint and output JSON or specific field
172
- * @param {string|number} planId - Plan ID to validate
173
- * @param {string} [fieldName] - Optional field name to extract (planFile, planDir, taskCount, blueprintExists)
47
+ * @private
48
+ * @param {string|number} inputId - Plan ID or absolute path to validate
49
+ * @param {string} [fieldName] - Optional field name to extract (planFile, planDir, taskCount, blueprintExists, taskManagerRoot, planId)
50
+ * @param {string} [startPath] - Optional start path for finding task manager root
174
51
  */
175
- function validatePlanBlueprint(planId, fieldName) {
176
- if (!planId) {
177
- errorLog('Plan ID is required');
178
- errorLog('');
179
- errorLog('Usage: node validate-plan-blueprint.cjs <plan-id> [field-name]');
180
- errorLog('');
181
- errorLog('Examples:');
182
- errorLog(' node validate-plan-blueprint.cjs 47 # Output full JSON');
183
- errorLog(' node validate-plan-blueprint.cjs 47 planFile # Output just the plan file path');
184
- errorLog(' node validate-plan-blueprint.cjs 47 planDir # Output just the plan directory');
185
- errorLog(' node validate-plan-blueprint.cjs 47 taskCount # Output just the task count');
186
- errorLog(' node validate-plan-blueprint.cjs 47 blueprintExists # Output yes/no');
52
+ function _validatePlanBlueprint(inputId, fieldName, startPath = process.cwd()) {
53
+ if (!inputId) {
54
+ _errorLog('Plan ID or absolute path is required');
55
+ _errorLog('');
56
+ _errorLog('Usage: node validate-plan-blueprint.cjs <plan-id-or-path> [field-name]');
57
+ _errorLog('');
58
+ _errorLog('Examples:');
59
+ _errorLog(' node validate-plan-blueprint.cjs 47 # Output full JSON');
60
+ _errorLog(' node validate-plan-blueprint.cjs /path/to/plan.md # Output full JSON for specific file');
61
+ _errorLog(' node validate-plan-blueprint.cjs 47 planFile # Output just the plan file path');
62
+ _errorLog(' node validate-plan-blueprint.cjs 47 blueprintExists # Output yes/no');
63
+ process.exit(1);
64
+ }
65
+
66
+ // Check if input is numeric (allowing padded zeros) - if not a number or path, it's invalid
67
+ const numericInput = parseInt(inputId, 10);
68
+ const isNumeric = !isNaN(numericInput);
69
+ const isAbsolutePath = inputId.startsWith('/');
70
+
71
+ if (!isNumeric && !isAbsolutePath) {
72
+ _errorLog(`Invalid plan ID: "${inputId}" is not a valid number`);
187
73
  process.exit(1);
188
74
  }
189
75
 
190
- const planInfo = findPlanById(planId);
76
+ const resolved = resolvePlan(inputId, startPath);
191
77
 
192
- if (!planInfo) {
193
- errorLog(`Plan ID ${planId} not found`);
194
- errorLog('');
78
+ if (!resolved) {
79
+ _errorLog(`Plan ID ${inputId} not found or invalid`);
80
+ _errorLog('');
195
81
 
196
- const availablePlans = listAvailablePlans();
82
+ const tmRoot = findTaskManagerRoot(startPath);
83
+ const availablePlans = _listAvailablePlans(tmRoot);
197
84
  if (availablePlans.length > 0) {
198
- errorLog('Available plans:');
85
+ _errorLog('Available plans:');
199
86
  availablePlans.forEach(plan => {
200
- errorLog(` ${plan}`);
87
+ _errorLog(` ${plan}`);
201
88
  });
202
- } else {
203
- errorLog('No plans found in .ai/task-manager/{plans,archive}/');
204
89
  }
205
90
 
206
- errorLog('');
207
- errorLog('Please verify:');
208
- errorLog(' 1. You are in the correct project directory');
209
- errorLog(' 2. The plan exists in .ai/task-manager/plans/ or .ai/task-manager/archive/');
210
- errorLog(' 3. The plan directory follows the naming pattern: [plan-id]--[name]');
211
- errorLog(' 4. The plan file follows the naming pattern: plan-[plan-id]--[name].md');
212
91
  process.exit(1);
213
92
  }
214
93
 
215
- const { planFile, planDir } = planInfo;
94
+ const {
95
+ planFile,
96
+ planDir,
97
+ taskManagerRoot,
98
+ planId
99
+ } = resolved;
100
+
216
101
  const taskCount = countTasks(planDir);
217
102
  const blueprintExists = checkBlueprintExists(planFile);
218
103
 
219
104
  const result = {
220
105
  planFile,
221
106
  planDir,
107
+ taskManagerRoot,
108
+ planId,
222
109
  taskCount,
223
110
  blueprintExists: blueprintExists ? 'yes' : 'no'
224
111
  };
225
112
 
226
113
  // If field name is provided, output just that field
227
114
  if (fieldName) {
228
- const validFields = ['planFile', 'planDir', 'taskCount', 'blueprintExists'];
115
+ const validFields = ['planFile', 'planDir', 'taskCount', 'blueprintExists', 'taskManagerRoot', 'planId'];
229
116
  if (!validFields.includes(fieldName)) {
230
- errorLog(`Invalid field name: ${fieldName}`);
231
- errorLog(`Valid fields: ${validFields.join(', ')}`);
117
+ _errorLog(`Invalid field name: ${fieldName}`);
118
+ _errorLog(`Valid fields: ${validFields.join(', ')}`);
232
119
  process.exit(1);
233
120
  }
234
121
  // Use process.stdout.write to avoid util.inspect colorization
235
- // Convert to string explicitly to ensure plain text output
236
122
  process.stdout.write(String(result[fieldName]) + '\n');
237
123
  } else {
238
- // Output full JSON for backward compatibility
124
+ // Output full JSON
239
125
  console.log(JSON.stringify(result, null, 2));
240
126
  }
241
127
  }
242
128
 
243
129
  // Main execution
244
- const planId = process.argv[2];
245
- const fieldName = process.argv[3];
246
- validatePlanBlueprint(planId, fieldName);
130
+ if (require.main === module) {
131
+ const planId = process.argv[2];
132
+ const fieldName = process.argv[3];
133
+ _validatePlanBlueprint(planId, fieldName);
134
+ }
135
+
136
+ module.exports = {
137
+ _validatePlanBlueprint
138
+ };
@@ -4,8 +4,8 @@ description: Create a comprehensive plan to accomplish the request from the user
4
4
  ---
5
5
  # Comprehensive Plan Creation
6
6
 
7
- You are a strategic planning specialist who creates actionable plan documents that balance comprehensive context with
8
- disciplined scope control. Your role is to think hard to create detailed, actionable plans based on user input while
7
+ You are a strategic planning specialist who creates actionable plan documents that balance comprehensive context with
8
+ disciplined scope control. Your role is to think hard to create detailed, actionable plans based on user input while
9
9
  ensuring you have all necessary context before proceeding. Use the plan-creator sub-agent for this if it is available.
10
10
 
11
11
  ## Assistant Configuration
@@ -132,10 +132,22 @@ The schema for this frontmatter is:
132
132
  ```
133
133
 
134
134
  ### Plan ID Generation
135
- Execute this script to determine the plan ID:
135
+
136
+ First, discover the task manager root directory:
137
+
138
+ ```bash
139
+ root=$(node -e 'const fs=require("fs"),path=require("path");const f=p=>{const t=path.join(p,".ai/task-manager");const m=path.join(t,".init-metadata.json");try{if(JSON.parse(fs.readFileSync(m)).version){console.log(path.resolve(t));process.exit(0)}}catch(e){};const d=path.dirname(p);if(d!==p)f(d)};f(process.cwd());process.exit(1)')
140
+
141
+ if [ -z "$root" ]; then
142
+ echo "Error: Could not find task manager root directory (.ai/task-manager)"
143
+ exit 1
144
+ fi
145
+ ```
146
+
147
+ Then execute this script to determine the plan ID:
136
148
 
137
149
  ```bash
138
- node .ai/task-manager/config/scripts/get-next-plan-id.cjs
150
+ next_id=$(node $root/config/scripts/get-next-plan-id.cjs)
139
151
  ```
140
152
 
141
153
  **Key formatting:**
@@ -44,12 +44,25 @@ Before proceeding with execution, validate that tasks exist and the execution bl
44
44
 
45
45
  **Validation Steps:**
46
46
 
47
+ First, discover the task manager root directory:
48
+
49
+ ```bash
50
+ root=$(node -e 'const fs=require("fs"),path=require("path");const f=p=>{const t=path.join(p,".ai/task-manager");const m=path.join(t,".init-metadata.json");try{if(JSON.parse(fs.readFileSync(m)).version){console.log(path.resolve(t));process.exit(0)}}catch(e){};const d=path.dirname(p);if(d!==p)f(d)};f(process.cwd());process.exit(1)')
51
+
52
+ if [ -z "$root" ]; then
53
+ echo "Error: Could not find task manager root directory (.ai/task-manager)"
54
+ exit 1
55
+ fi
56
+ ```
57
+
58
+ Then extract validation results:
59
+
47
60
  ```bash
48
61
  # Extract validation results directly from script
49
- plan_file=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs $1 planFile)
50
- plan_dir=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs $1 planDir)
51
- task_count=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs $1 taskCount)
52
- blueprint_exists=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs $1 blueprintExists)
62
+ plan_file=$(node $root/config/scripts/validate-plan-blueprint.cjs $1 planFile)
63
+ plan_dir=$(node $root/config/scripts/validate-plan-blueprint.cjs $1 planDir)
64
+ task_count=$(node $root/config/scripts/validate-plan-blueprint.cjs $1 taskCount)
65
+ blueprint_exists=$(node $root/config/scripts/validate-plan-blueprint.cjs $1 blueprintExists)
53
66
  ```
54
67
 
55
68
  4. **Automatic task generation**:
@@ -57,21 +57,32 @@ fi
57
57
 
58
58
  ## Execution Process
59
59
 
60
- ### 1. Plan and Task Location
60
+ ### 1. Root Discovery and Plan Location
61
61
 
62
- Locate the plan directory using the established find pattern:
62
+ First, discover the task manager root directory:
63
+
64
+ ```bash
65
+ root=$(node -e 'const fs=require("fs"),path=require("path");const f=p=>{const t=path.join(p,".ai/task-manager");const m=path.join(t,".init-metadata.json");try{if(JSON.parse(fs.readFileSync(m)).version){console.log(path.resolve(t));process.exit(0)}}catch(e){};const d=path.dirname(p);if(d!==p)f(d)};f(process.cwd());process.exit(1)')
66
+
67
+ if [ -z "$root" ]; then
68
+ echo "Error: Could not find task manager root directory (.ai/task-manager)"
69
+ exit 1
70
+ fi
71
+ ```
72
+
73
+ Then locate the plan directory using the discovered root:
63
74
 
64
75
  ```bash
65
76
  plan_id="$1"
66
77
  task_id="$2"
67
78
 
68
79
  # Find plan directory
69
- plan_dir=$(find .ai/task-manager/{plans,archive} -type d -name "${plan_id}--*" 2>/dev/null | head -1)
80
+ plan_dir=$(find $root/{plans,archive} -type d -name "${plan_id}--*" 2>/dev/null | head -1)
70
81
 
71
82
  if [ -z "$plan_dir" ]; then
72
83
  echo "Error: Plan with ID ${plan_id} not found"
73
84
  echo "Available plans:"
74
- find .ai/task-manager/plans -name "*--*" -type d | head -5
85
+ find $root/plans -name "*--*" -type d | head -5
75
86
  exit 1
76
87
  fi
77
88
 
@@ -147,7 +158,7 @@ Use the dependency checking script to validate all dependencies:
147
158
 
148
159
  ```bash
149
160
  # Call the dependency checking script
150
- if ! node .ai/task-manager/config/scripts/check-task-dependencies.cjs "$plan_id" "$task_id"; then
161
+ if ! node $root/config/scripts/check-task-dependencies.cjs "$plan_id" "$task_id"; then
151
162
  echo ""
152
163
  echo "Task execution blocked by unresolved dependencies."
153
164
  echo "Please complete the required dependencies first."
@@ -145,9 +145,20 @@ created: 2025-09-01
145
145
 
146
146
  #### Plan ID Generation
147
147
 
148
- **Auto-generate the next plan ID:**
148
+ First, discover the task manager root directory:
149
+
150
+ ```bash
151
+ root=$(node -e 'const fs=require("fs"),path=require("path");const f=p=>{const t=path.join(p,".ai/task-manager");const m=path.join(t,".init-metadata.json");try{if(JSON.parse(fs.readFileSync(m)).version){console.log(path.resolve(t));process.exit(0)}}catch(e){};const d=path.dirname(p);if(d!==p)f(d)};f(process.cwd());process.exit(1)')
152
+
153
+ if [ -z "$root" ]; then
154
+ echo "Error: Could not find task manager root directory (.ai/task-manager)"
155
+ exit 1
156
+ fi
157
+ ```
158
+
159
+ Then auto-generate the next plan ID:
149
160
  ```bash
150
- node .ai/task-manager/config/scripts/get-next-plan-id.cjs
161
+ node $root/config/scripts/get-next-plan-id.cjs
151
162
  ```
152
163
 
153
164
  **Key formatting:**
@@ -272,7 +283,7 @@ Use the task template in .ai/task-manager/config/templates/TASK_TEMPLATE.md
272
283
  When creating tasks, you need to determine the next available task ID for the specified plan. Use this bash command to automatically generate the correct ID:
273
284
 
274
285
  ```bash
275
- node .ai/task-manager/config/scripts/get-next-task-id.cjs [PLAN_ID from Step 1]
286
+ node $root/config/scripts/get-next-task-id.cjs [PLAN_ID from Step 1]
276
287
  ```
277
288
 
278
289
  #### Step 4: POST_TASK_GENERATION_ALL hook
@@ -337,12 +348,14 @@ Before proceeding with execution, validate that tasks exist and the execution bl
337
348
 
338
349
  **Validation Steps:**
339
350
 
351
+ Use the task manager root discovered in Step 1 to extract validation results:
352
+
340
353
  ```bash
341
354
  # Extract validation results directly from script
342
- plan_file=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs [planId] planFile)
343
- plan_dir=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs [planId] planDir)
344
- task_count=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs [planId] taskCount)
345
- blueprint_exists=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs [planId] blueprintExists)
355
+ plan_file=$(node $root/config/scripts/validate-plan-blueprint.cjs [planId] planFile)
356
+ plan_dir=$(node $root/config/scripts/validate-plan-blueprint.cjs [planId] planDir)
357
+ task_count=$(node $root/config/scripts/validate-plan-blueprint.cjs [planId] taskCount)
358
+ blueprint_exists=$(node $root/config/scripts/validate-plan-blueprint.cjs [planId] blueprintExists)
346
359
  ```
347
360
 
348
361
  If either `$task_count` is 0 or `$blueprint_exists` is "no":
@@ -38,9 +38,22 @@ Use your internal Todo task tool to track the following process:
38
38
 
39
39
  - A plan document. Extract it with the following command.
40
40
 
41
+ First, discover the task manager root directory:
42
+
43
+ ```bash
44
+ root=$(node -e 'const fs=require("fs"),path=require("path");const f=p=>{const t=path.join(p,".ai/task-manager");const m=path.join(t,".init-metadata.json");try{if(JSON.parse(fs.readFileSync(m)).version){console.log(path.resolve(t));process.exit(0)}}catch(e){};const d=path.dirname(p);if(d!==p)f(d)};f(process.cwd());process.exit(1)')
45
+
46
+ if [ -z "$root" ]; then
47
+ echo "Error: Could not find task manager root directory (.ai/task-manager)"
48
+ exit 1
49
+ fi
50
+ ```
51
+
52
+ Then extract validation results:
53
+
41
54
  ```bash
42
55
  # Extract validation results directly from script
43
- plan_file=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs $1 planFile)
56
+ plan_file=$(node $root/config/scripts/validate-plan-blueprint.cjs $1 planFile)
44
57
  ```
45
58
 
46
59
  ### Input Error Handling
@@ -243,7 +256,7 @@ Use the task template in .ai/task-manager/config/templates/TASK_TEMPLATE.md
243
256
  When creating tasks, you need to determine the next available task ID for the specified plan. Use this bash command to automatically generate the correct ID:
244
257
 
245
258
  ```bash
246
- node .ai/task-manager/config/scripts/get-next-task-id.cjs $1
259
+ node $root/config/scripts/get-next-task-id.cjs $1
247
260
  ```
248
261
 
249
262
  ### Validation Checklist
@@ -4,9 +4,9 @@ description: Review the plan with the provided ID, gather clarifications, and re
4
4
  ---
5
5
  # Plan Review and Refinement
6
6
 
7
- You are a strategic planning specialist who specializes in interrogating existing plans, uncovering blind spots, and
8
- refining the document so that task generators receive the clearest possible instructions. Treat the current plan as the
9
- work product of another assistant: your responsibility is to pressure test it, request any missing information from the
7
+ You are a strategic planning specialist who specializes in interrogating existing plans, uncovering blind spots, and
8
+ refining the document so that task generators receive the clearest possible instructions. Treat the current plan as the
9
+ work product of another assistant: your responsibility is to pressure test it, request any missing information from the
10
10
  user, and update the plan with the refinements. Use the plan-creator sub-agent for this if it is available.
11
11
 
12
12
  ## Assistant Configuration
@@ -34,11 +34,22 @@ If the plan ID is missing, immediately stop and show an error explaining correct
34
34
 
35
35
  ### Plan Discovery and Validation
36
36
 
37
- Obtain the plan using the plan ID using the following script:
37
+ First, discover the task manager root directory:
38
+
39
+ ```bash
40
+ root=$(node -e 'const fs=require("fs"),path=require("path");const f=p=>{const t=path.join(p,".ai/task-manager");const m=path.join(t,".init-metadata.json");try{if(JSON.parse(fs.readFileSync(m)).version){console.log(path.resolve(t));process.exit(0)}}catch(e){};const d=path.dirname(p);if(d!==p)f(d)};f(process.cwd());process.exit(1)')
41
+
42
+ if [ -z "$root" ]; then
43
+ echo "Error: Could not find task manager root directory (.ai/task-manager)"
44
+ exit 1
45
+ fi
46
+ ```
47
+
48
+ Then obtain the plan using the plan ID:
38
49
 
39
50
  ```bash
40
51
  # Extract validation results directly from script
41
- plan_file=$(node .ai/task-manager/config/scripts/validate-plan-blueprint.cjs $1 planFile)
52
+ plan_file=$(node $root/config/scripts/validate-plan-blueprint.cjs $1 planFile)
42
53
  ```
43
54
 
44
55
  ## Process Checklist