task-o-matic 0.0.1 → 0.0.3

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 (38) hide show
  1. package/dist/commands/prd.js +4 -0
  2. package/dist/commands/prompt.d.ts.map +1 -1
  3. package/dist/commands/prompt.js +69 -61
  4. package/dist/commands/tasks.js +93 -1
  5. package/dist/lib/ai-service/ai-operations.d.ts +5 -3
  6. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
  7. package/dist/lib/ai-service/ai-operations.js +189 -20
  8. package/dist/lib/ai-service/filesystem-tools.d.ts +69 -0
  9. package/dist/lib/ai-service/filesystem-tools.d.ts.map +1 -0
  10. package/dist/lib/ai-service/filesystem-tools.js +70 -0
  11. package/dist/lib/ai-service/json-parser.d.ts +13 -0
  12. package/dist/lib/ai-service/json-parser.d.ts.map +1 -1
  13. package/dist/lib/ai-service/json-parser.js +66 -5
  14. package/dist/lib/executors/claude-code-executor.d.ts +6 -0
  15. package/dist/lib/executors/claude-code-executor.d.ts.map +1 -0
  16. package/dist/lib/executors/claude-code-executor.js +41 -0
  17. package/dist/lib/executors/codex-executor.d.ts +6 -0
  18. package/dist/lib/executors/codex-executor.d.ts.map +1 -0
  19. package/dist/lib/executors/codex-executor.js +41 -0
  20. package/dist/lib/executors/executor-factory.d.ts.map +1 -1
  21. package/dist/lib/executors/executor-factory.js +6 -3
  22. package/dist/lib/executors/gemini-executor.d.ts +6 -0
  23. package/dist/lib/executors/gemini-executor.d.ts.map +1 -0
  24. package/dist/lib/executors/gemini-executor.js +41 -0
  25. package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
  26. package/dist/lib/executors/opencode-executor.js +2 -3
  27. package/dist/lib/prompt-builder.d.ts +8 -0
  28. package/dist/lib/prompt-builder.d.ts.map +1 -1
  29. package/dist/lib/prompt-builder.js +98 -0
  30. package/dist/lib/task-execution.d.ts.map +1 -1
  31. package/dist/lib/task-execution.js +44 -14
  32. package/dist/services/prd.d.ts +2 -0
  33. package/dist/services/prd.d.ts.map +1 -1
  34. package/dist/services/prd.js +4 -4
  35. package/dist/services/tasks.d.ts +10 -1
  36. package/dist/services/tasks.d.ts.map +1 -1
  37. package/dist/services/tasks.js +97 -2
  38. package/package.json +1 -1
@@ -24,6 +24,7 @@ exports.prdCommand
24
24
  .option("--ai-provider-url <url>", "AI provider URL override")
25
25
  .option("--ai-reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
26
26
  .option("--stream", "Show streaming AI output during parsing")
27
+ .option("--tools", "Enable filesystem tools for project analysis")
27
28
  .action(async (options) => {
28
29
  try {
29
30
  // Determine working directory from current process location
@@ -33,6 +34,7 @@ exports.prdCommand
33
34
  const result = await prd_1.prdService.parsePRD({
34
35
  file: options.file,
35
36
  workingDirectory, // Pass working directory explicitly to service
37
+ enableFilesystemTools: options.tools,
36
38
  aiOptions: {
37
39
  aiProvider: options.aiProvider,
38
40
  aiModel: options.aiModel,
@@ -94,6 +96,7 @@ exports.prdCommand
94
96
  .option("--ai-provider-url <url>", "AI provider URL override")
95
97
  .option("--ai-reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
96
98
  .option("--stream", "Show streaming AI output during rework")
99
+ .option("--tools", "Enable filesystem tools for project analysis")
97
100
  .action(async (options) => {
98
101
  try {
99
102
  // Determine working directory from current process location
@@ -105,6 +108,7 @@ exports.prdCommand
105
108
  feedback: options.feedback,
106
109
  output: options.output,
107
110
  workingDirectory, // Pass working directory explicitly to service
111
+ enableFilesystemTools: options.tools,
108
112
  aiOptions: {
109
113
  aiProvider: options.aiProvider,
110
114
  aiModel: options.aiModel,
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/commands/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,eAAO,MAAM,aAAa,SAkOtB,CAAC"}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/commands/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,eAAO,MAAM,aAAa,SAyPtB,CAAC"}
@@ -21,6 +21,8 @@ exports.promptCommand = new commander_1.Command("prompt")
21
21
  .option("--var <key=value>", "Custom variable in format key=value (can be used multiple times)", (value, previous = []) => {
22
22
  return [...previous, value];
23
23
  }, [])
24
+ .option("--full-context", "Include comprehensive project context (file structure, dependencies, etc.)", false)
25
+ .option("--executor <type>", "Format output for specific executor: opencode, claude, gemini, codex")
24
26
  .action(async (name, options) => {
25
27
  try {
26
28
  // Handle list option
@@ -55,91 +57,92 @@ exports.promptCommand = new commander_1.Command("prompt")
55
57
  console.error('Error: --type must be either "system" or "user"');
56
58
  (0, process_1.exit)(1);
57
59
  }
58
- // Build variables object
60
+ // Build variables object with AUTOMATIC DETECTION FIRST (like all other commands)
59
61
  const variables = {};
60
- // Parse custom variables (--var key=value)
61
- if (options.var) {
62
- for (const varPair of options.var) {
63
- const [key, ...valueParts] = varPair.split("=");
64
- if (!key || valueParts.length === 0) {
65
- console.error(`Error: Invalid variable format: ${varPair}. Expected format: key=value`);
66
- (0, process_1.exit)(1);
67
- }
68
- variables[key] = valueParts.join("=");
69
- }
70
- }
71
- // Handle PRD content
72
- let prdContent = options.prdContent;
62
+ // STEP 1: AUTO-DETECT EVERYTHING (default behavior)
63
+ // Auto-detect PRD content ALWAYS
64
+ const autoPrdContent = await prompt_builder_1.PromptBuilder.autoDetectPRDContent();
65
+ if (autoPrdContent) {
66
+ variables.PRD_CONTENT = autoPrdContent;
67
+ }
68
+ // Auto-detect stack info ALWAYS
69
+ const autoStackInfo = await prompt_builder_1.PromptBuilder.detectStackInfo(process.cwd());
70
+ if (autoStackInfo !== "Not detected") {
71
+ variables.STACK_INFO = autoStackInfo;
72
+ }
73
+ // STEP 2: OVERRIDE with explicit options if provided
74
+ // Override PRD if explicitly provided
73
75
  if (options.prdFile) {
74
- prdContent = prompt_builder_1.PromptBuilder.loadPRDContent(options.prdFile);
76
+ variables.PRD_CONTENT = prompt_builder_1.PromptBuilder.loadPRDContent(options.prdFile);
75
77
  }
76
- if (prdContent) {
77
- variables.PRD_CONTENT = prdContent;
78
+ else if (options.prdContent) {
79
+ variables.PRD_CONTENT = options.prdContent;
78
80
  }
79
- else if (!prdContent && !variables.PRD_CONTENT) {
80
- // Auto-detect PRD content if not provided
81
- prdContent = await prompt_builder_1.PromptBuilder.autoDetectPRDContent();
82
- if (prdContent) {
83
- variables.PRD_CONTENT = prdContent;
84
- }
81
+ // Override stack if explicitly provided
82
+ if (options.stackInfo) {
83
+ variables.STACK_INFO = options.stackInfo;
85
84
  }
86
85
  // Handle task information
87
- let taskDescription = options.taskDescription;
88
- if (options.taskFile) {
89
- taskDescription = await prompt_builder_1.PromptBuilder.buildTaskContext("", "", options.taskFile);
90
- }
91
86
  if (options.taskTitle) {
92
87
  variables.TASK_TITLE = options.taskTitle;
93
88
  }
94
- if (taskDescription) {
95
- variables.TASK_DESCRIPTION = taskDescription;
89
+ if (options.taskFile) {
90
+ variables.TASK_DESCRIPTION = await prompt_builder_1.PromptBuilder.buildTaskContext(options.taskTitle || "", "", options.taskFile);
91
+ }
92
+ else if (options.taskDescription) {
93
+ variables.TASK_DESCRIPTION = options.taskDescription;
96
94
  }
97
- // If we have both title and description, build rich context
95
+ // Build rich task context if we have title and description
98
96
  if (options.taskTitle && (options.taskDescription || options.taskFile)) {
99
- const richContext = await prompt_builder_1.PromptBuilder.buildTaskContext(options.taskTitle, options.taskDescription, options.taskFile);
100
- variables.TASK_CONTEXT = richContext;
97
+ variables.TASK_CONTEXT = await prompt_builder_1.PromptBuilder.buildTaskContext(options.taskTitle, options.taskDescription, options.taskFile);
101
98
  }
102
- // Handle stack info (don't auto-detect if custom var provided)
103
- if (options.stackInfo) {
104
- variables.STACK_INFO = options.stackInfo;
99
+ // Handle user feedback
100
+ if (options.userFeedback) {
101
+ variables.USER_FEEDBACK = options.userFeedback;
105
102
  }
106
- else if (!variables.STACK_INFO) {
107
- // Auto-detect stack info from current directory
108
- const stackInfo = await prompt_builder_1.PromptBuilder.detectStackInfo(process.cwd());
109
- if (stackInfo !== "Not detected") {
110
- variables.STACK_INFO = stackInfo;
103
+ // Build comprehensive CONTEXT_INFO (combining everything)
104
+ const contextParts = [];
105
+ // Add stack info if available
106
+ if (variables.STACK_INFO) {
107
+ contextParts.push(`**Technology Stack:** ${variables.STACK_INFO}`);
108
+ }
109
+ // Add PRD content if available
110
+ if (variables.PRD_CONTENT) {
111
+ contextParts.push(`**Product Requirements:**\n${variables.PRD_CONTENT}`);
112
+ }
113
+ // Add full context if requested
114
+ if (options.fullContext) {
115
+ const fullContext = await prompt_builder_1.PromptBuilder.buildFullProjectContext(process.cwd());
116
+ if (fullContext) {
117
+ contextParts.push(fullContext);
111
118
  }
112
119
  }
113
- // Build CONTEXT_INFO from stack and PRD if not explicitly provided
114
- if (!options.contextInfo && !variables.CONTEXT_INFO) {
115
- const contextParts = [];
116
- // Add stack info if available
117
- if (variables.STACK_INFO) {
118
- contextParts.push(`**Technology Stack:** ${variables.STACK_INFO}`);
119
- }
120
- // Add PRD content if available
121
- if (variables.PRD_CONTENT) {
122
- contextParts.push(`**Product Requirements:**\n${variables.PRD_CONTENT}`);
123
- }
124
- // Set combined context info
125
- if (contextParts.length > 0) {
126
- variables.CONTEXT_INFO = contextParts.join('\n\n');
127
- }
120
+ // Set combined context info
121
+ if (contextParts.length > 0) {
122
+ variables.CONTEXT_INFO = contextParts.join('\n\n');
128
123
  }
129
- // Handle other variables
124
+ // Override context info if explicitly provided
130
125
  if (options.contextInfo) {
131
126
  variables.CONTEXT_INFO = options.contextInfo;
132
127
  }
133
- if (options.userFeedback) {
134
- variables.USER_FEEDBACK = options.userFeedback;
128
+ // STEP 3: FINAL OVERRIDE with custom --var variables (highest priority)
129
+ if (options.var) {
130
+ for (const varPair of options.var) {
131
+ const [key, ...valueParts] = varPair.split("=");
132
+ if (!key || valueParts.length === 0) {
133
+ console.error(`Error: Invalid variable format: ${varPair}. Expected format: key=value`);
134
+ (0, process_1.exit)(1);
135
+ }
136
+ variables[key] = valueParts.join("=");
137
+ }
135
138
  }
136
139
  // Build the prompt
137
140
  const result = prompt_builder_1.PromptBuilder.buildPrompt({
138
- name,
141
+ name: name, // name is checked above, will not be undefined here
139
142
  type: options.type,
140
143
  variables,
141
144
  });
142
- if (!result.success) {
145
+ if (!result.success || !result.prompt) {
143
146
  console.error(`Error: ${result.error}`);
144
147
  if (result.missingVariables && result.missingVariables.length > 0) {
145
148
  console.error("\nMissing required variables:");
@@ -159,8 +162,13 @@ exports.promptCommand = new commander_1.Command("prompt")
159
162
  }
160
163
  (0, process_1.exit)(1);
161
164
  }
165
+ // Format output based on executor if specified
166
+ let outputPrompt = result.prompt;
167
+ if (options.executor) {
168
+ outputPrompt = prompt_builder_1.PromptBuilder.formatForExecutor(result.prompt, options.executor);
169
+ }
162
170
  // Output the built prompt
163
- console.log(result.prompt);
171
+ console.log(outputPrompt);
164
172
  }
165
173
  catch (error) {
166
174
  console.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -225,6 +225,7 @@ exports.tasksCommand
225
225
  .option("--ai-key <key>", "AI API key override")
226
226
  .option("--ai-provider-url <url>", "AI provider URL override")
227
227
  .option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
228
+ .option("--tools", "Enable filesystem tools for project analysis")
228
229
  .action(async (options) => {
229
230
  try {
230
231
  if (!options.taskId && !options.all) {
@@ -245,7 +246,7 @@ exports.tasksCommand
245
246
  }, undefined, undefined, streamingOptions, {
246
247
  onProgress: progress_1.displayProgress,
247
248
  onError: progress_1.displayError,
248
- });
249
+ }, options.tools);
249
250
  (0, task_1.displaySubtaskCreation)(result.subtasks);
250
251
  // Display AI metadata
251
252
  console.log(chalk_1.default.gray(`\n📊 AI Splitting Details:`));
@@ -597,3 +598,94 @@ exports.tasksCommand
597
598
  process.exit(1);
598
599
  }
599
600
  });
601
+ // Get task documentation
602
+ exports.tasksCommand
603
+ .command("get-documentation")
604
+ .description("Get existing documentation for a task")
605
+ .requiredOption("--id <id>", "Task ID")
606
+ .action(async (options) => {
607
+ try {
608
+ const task = await tasks_1.taskService.getTask(options.id);
609
+ if (!task) {
610
+ throw new Error(`Task with ID ${options.id} not found`);
611
+ }
612
+ const documentation = await tasks_1.taskService.getTaskDocumentation(options.id);
613
+ if (!documentation) {
614
+ console.log(chalk_1.default.yellow(`⚠️ No documentation found for task ${options.id}`));
615
+ console.log(chalk_1.default.gray(` Task: ${task.title}`));
616
+ return;
617
+ }
618
+ console.log(chalk_1.default.blue(`\n📖 Documentation for Task: ${task.title} (${options.id})`));
619
+ console.log(chalk_1.default.gray(` File: .task-o-matic/docs/tasks/${options.id}.md`));
620
+ console.log("");
621
+ console.log(documentation);
622
+ }
623
+ catch (error) {
624
+ (0, progress_1.displayError)(error);
625
+ process.exit(1);
626
+ }
627
+ });
628
+ // Add documentation from file
629
+ exports.tasksCommand
630
+ .command("add-documentation")
631
+ .description("Add documentation to a task from a file")
632
+ .requiredOption("--id <id>", "Task ID")
633
+ .requiredOption("--doc-file <path>", "Path to documentation file")
634
+ .option("--overwrite", "Overwrite existing documentation")
635
+ .action(async (options) => {
636
+ try {
637
+ const task = await tasks_1.taskService.getTask(options.id);
638
+ if (!task) {
639
+ throw new Error(`Task with ID ${options.id} not found`);
640
+ }
641
+ // Check if documentation already exists
642
+ const existingDoc = await tasks_1.taskService.getTaskDocumentation(options.id);
643
+ if (existingDoc && !options.overwrite) {
644
+ console.log(chalk_1.default.yellow(`⚠️ Documentation already exists for task ${options.id}`));
645
+ console.log(chalk_1.default.gray(` Use --overwrite to replace existing documentation`));
646
+ return;
647
+ }
648
+ const result = await tasks_1.taskService.addTaskDocumentationFromFile(options.id, options.docFile);
649
+ console.log(chalk_1.default.green(`✓ Documentation added to task: ${task.title} (${options.id})`));
650
+ console.log(chalk_1.default.gray(` Source file: ${options.docFile}`));
651
+ console.log(chalk_1.default.gray(` Saved to: ${result.filePath}`));
652
+ if (options.overwrite) {
653
+ console.log(chalk_1.default.cyan(` Previous documentation was overwritten`));
654
+ }
655
+ }
656
+ catch (error) {
657
+ (0, progress_1.displayError)(error);
658
+ process.exit(1);
659
+ }
660
+ });
661
+ // Set task plan
662
+ exports.tasksCommand
663
+ .command("set-plan")
664
+ .description("Set implementation plan for a task")
665
+ .requiredOption("--id <id>", "Task ID")
666
+ .option("--plan <text>", "Plan text (use quotes for multi-line)")
667
+ .option("--plan-file <path>", "Path to file containing the plan")
668
+ .action(async (options) => {
669
+ try {
670
+ const task = await tasks_1.taskService.getTask(options.id);
671
+ if (!task) {
672
+ throw new Error(`Task with ID ${options.id} not found`);
673
+ }
674
+ if (!options.plan && !options.planFile) {
675
+ throw new Error("Either --plan or --plan-file must be specified");
676
+ }
677
+ if (options.plan && options.planFile) {
678
+ throw new Error("Cannot specify both --plan and --plan-file");
679
+ }
680
+ const result = await tasks_1.taskService.setTaskPlan(options.id, options.plan || undefined, options.planFile || undefined);
681
+ console.log(chalk_1.default.green(`✓ Plan set for task: ${task.title} (${options.id})`));
682
+ console.log(chalk_1.default.gray(` Plan file: ${result.planFile}`));
683
+ if (options.planFile) {
684
+ console.log(chalk_1.default.gray(` Source file: ${options.planFile}`));
685
+ }
686
+ }
687
+ catch (error) {
688
+ (0, progress_1.displayError)(error);
689
+ process.exit(1);
690
+ }
691
+ });
@@ -5,14 +5,16 @@ export declare class AIOperations {
5
5
  private retryHandler;
6
6
  private modelProvider;
7
7
  streamText(prompt: string, config?: Partial<AIConfig>, systemPrompt?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<string>;
8
- parsePRD(prdContent: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, workingDirectory?: string): Promise<AIPRDParseResult>;
9
- breakdownTask(task: Task, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, fullContent?: string, stackInfo?: string, existingSubtasks?: Task[]): Promise<Array<{
8
+ parsePRD(prdContent: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, workingDirectory?: string, // Working directory passed from service layer
9
+ enableFilesystemTools?: boolean): Promise<AIPRDParseResult>;
10
+ breakdownTask(task: Task, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, fullContent?: string, stackInfo?: string, existingSubtasks?: Task[], enableFilesystemTools?: boolean): Promise<Array<{
10
11
  title: string;
11
12
  content: string;
12
13
  estimatedEffort?: string;
13
14
  }>>;
14
15
  enhanceTask(title: string, description?: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, taskId?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<string>;
15
- reworkPRD(prdContent: string, feedback: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, workingDirectory?: string): Promise<string>;
16
+ reworkPRD(prdContent: string, feedback: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, workingDirectory?: string, // Working directory passed from service layer
17
+ enableFilesystemTools?: boolean): Promise<string>;
16
18
  enhanceTaskWithDocumentation(taskId: string, taskTitle: string, taskDescription: string, stackInfo?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, config?: Partial<AIConfig>, existingResearch?: Record<string, Array<{
17
19
  query: string;
18
20
  doc: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ai-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/ai-operations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/ai-operations.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ const json_parser_1 = require("./json-parser");
11
11
  const mcp_client_1 = require("./mcp-client");
12
12
  const retry_handler_1 = require("./retry-handler");
13
13
  const model_provider_1 = require("./model-provider");
14
+ const filesystem_tools_1 = require("./filesystem-tools");
14
15
  class AIOperations {
15
16
  jsonParser = new json_parser_1.JSONParser();
16
17
  context7Client = new mcp_client_1.Context7Client();
@@ -81,7 +82,8 @@ class AIOperations {
81
82
  return fullText;
82
83
  }, retryConfig, "AI streaming");
83
84
  }
84
- async parsePRD(prdContent, config, promptOverride, userMessage, streamingOptions, retryConfig, workingDirectory) {
85
+ async parsePRD(prdContent, config, promptOverride, userMessage, streamingOptions, retryConfig, workingDirectory, // Working directory passed from service layer
86
+ enableFilesystemTools) {
85
87
  return this.retryHandler.executeWithRetry(async () => {
86
88
  // Get stack context for better PRD parsing using PromptBuilder
87
89
  // Pass working directory explicitly to avoid process.cwd() issues
@@ -118,8 +120,50 @@ class AIOperations {
118
120
  }
119
121
  enhancedPrompt = promptResult.prompt; // TypeScript: prompt is guaranteed when success is true
120
122
  }
121
- const response = await this.streamText("", // empty prompt since we use messages
122
- config, prompts_1.PRD_PARSING_SYSTEM_PROMPT, userMessage || enhancedPrompt, streamingOptions, { maxAttempts: 1 });
123
+ let response;
124
+ if (enableFilesystemTools) {
125
+ // Use filesystem tools when enabled
126
+ const model = this.modelProvider.getModel({ ...this.modelProvider.getAIConfig(), ...config });
127
+ const allTools = {
128
+ ...filesystem_tools_1.filesystemTools,
129
+ };
130
+ const result = await (0, ai_1.streamText)({
131
+ model,
132
+ tools: allTools, // Filesystem tools for project analysis
133
+ system: prompts_1.PRD_PARSING_SYSTEM_PROMPT + `
134
+
135
+ You have access to filesystem tools that allow you to:
136
+ - readFile: Read the contents of any file in the project
137
+ - listDirectory: List contents of directories
138
+
139
+ Use these tools to understand the project structure, existing code patterns, and dependencies when parsing the PRD and creating tasks.`,
140
+ messages: [{ role: "user", content: userMessage || enhancedPrompt }],
141
+ maxRetries: 0,
142
+ onChunk: streamingOptions?.onChunk
143
+ ? ({ chunk }) => {
144
+ if (chunk.type === "text-delta") {
145
+ streamingOptions.onChunk(chunk.text);
146
+ }
147
+ }
148
+ : undefined,
149
+ onFinish: streamingOptions?.onFinish
150
+ ? ({ text, finishReason, usage }) => {
151
+ streamingOptions.onFinish({
152
+ text,
153
+ finishReason,
154
+ usage,
155
+ isAborted: false,
156
+ });
157
+ }
158
+ : undefined,
159
+ });
160
+ response = await result.text;
161
+ }
162
+ else {
163
+ // Use standard streamText without tools
164
+ response = await this.streamText("", // empty prompt since we use messages
165
+ config, prompts_1.PRD_PARSING_SYSTEM_PROMPT, userMessage || enhancedPrompt, streamingOptions, { maxAttempts: 1 });
166
+ }
123
167
  // Parse JSON from response using proper typing
124
168
  const parseResult = this.jsonParser.parseJSONFromResponse(response);
125
169
  if (!parseResult.success) {
@@ -167,7 +211,7 @@ class AIOperations {
167
211
  };
168
212
  }, retryConfig, "PRD parsing");
169
213
  }
170
- async breakdownTask(task, config, promptOverride, userMessage, streamingOptions, retryConfig, fullContent, stackInfo, existingSubtasks) {
214
+ async breakdownTask(task, config, promptOverride, userMessage, streamingOptions, retryConfig, fullContent, stackInfo, existingSubtasks, enableFilesystemTools) {
171
215
  return this.retryHandler.executeWithRetry(async () => {
172
216
  // Use PromptBuilder if no prompt override provided
173
217
  let prompt;
@@ -205,8 +249,50 @@ class AIOperations {
205
249
  }
206
250
  prompt = promptResult.prompt;
207
251
  }
208
- const response = await this.streamText("", // empty prompt since we use messages
209
- config, prompts_1.TASK_BREAKDOWN_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
252
+ let response;
253
+ if (enableFilesystemTools) {
254
+ // Use filesystem tools when enabled
255
+ const model = this.modelProvider.getModel({ ...this.modelProvider.getAIConfig(), ...config });
256
+ const allTools = {
257
+ ...filesystem_tools_1.filesystemTools,
258
+ };
259
+ const result = await (0, ai_1.streamText)({
260
+ model,
261
+ tools: allTools, // Filesystem tools for project analysis
262
+ system: prompts_1.TASK_BREAKDOWN_SYSTEM_PROMPT + `
263
+
264
+ You have access to filesystem tools that allow you to:
265
+ - readFile: Read the contents of any file in the project
266
+ - listDirectory: List contents of directories
267
+
268
+ Use these tools to understand the project structure, existing code, and dependencies when breaking down tasks into subtasks.`,
269
+ messages: [{ role: "user", content: userMessage || prompt }],
270
+ maxRetries: 0,
271
+ onChunk: streamingOptions?.onChunk
272
+ ? ({ chunk }) => {
273
+ if (chunk.type === "text-delta") {
274
+ streamingOptions.onChunk(chunk.text);
275
+ }
276
+ }
277
+ : undefined,
278
+ onFinish: streamingOptions?.onFinish
279
+ ? ({ text, finishReason, usage }) => {
280
+ streamingOptions.onFinish({
281
+ text,
282
+ finishReason,
283
+ usage,
284
+ isAborted: false,
285
+ });
286
+ }
287
+ : undefined,
288
+ });
289
+ response = await result.text;
290
+ }
291
+ else {
292
+ // Use standard streamText without tools
293
+ response = await this.streamText("", // empty prompt since we use messages
294
+ config, prompts_1.TASK_BREAKDOWN_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
295
+ }
210
296
  // Parse JSON from response using proper typing
211
297
  const parseResult = this.jsonParser.parseJSONFromResponse(response);
212
298
  if (!parseResult.success) {
@@ -275,7 +361,8 @@ class AIOperations {
275
361
  config, prompts_1.TASK_ENHANCEMENT_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
276
362
  }, retryConfig, "Task enhancement");
277
363
  }
278
- async reworkPRD(prdContent, feedback, config, promptOverride, userMessage, streamingOptions, retryConfig, workingDirectory) {
364
+ async reworkPRD(prdContent, feedback, config, promptOverride, userMessage, streamingOptions, retryConfig, workingDirectory, // Working directory passed from service layer
365
+ enableFilesystemTools) {
279
366
  return this.retryHandler.executeWithRetry(async () => {
280
367
  // Get stack context for better PRD rework using PromptBuilder
281
368
  // Pass working directory explicitly to avoid process.cwd() issues
@@ -313,8 +400,49 @@ class AIOperations {
313
400
  }
314
401
  prompt = promptResult.prompt;
315
402
  }
316
- return this.streamText("", // empty prompt since we use messages
317
- config, prompts_1.PRD_REWORK_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
403
+ if (enableFilesystemTools) {
404
+ // Use filesystem tools when enabled
405
+ const model = this.modelProvider.getModel({ ...this.modelProvider.getAIConfig(), ...config });
406
+ const allTools = {
407
+ ...filesystem_tools_1.filesystemTools,
408
+ };
409
+ const result = await (0, ai_1.streamText)({
410
+ model,
411
+ tools: allTools, // Filesystem tools for project analysis
412
+ system: prompts_1.PRD_REWORK_SYSTEM_PROMPT + `
413
+
414
+ You have access to filesystem tools that allow you to:
415
+ - readFile: Read the contents of any file in the project
416
+ - listDirectory: List contents of directories
417
+
418
+ Use these tools to understand the current project structure, existing code patterns, and dependencies when reworking the PRD based on feedback.`,
419
+ messages: [{ role: "user", content: userMessage || prompt }],
420
+ maxRetries: 0,
421
+ onChunk: streamingOptions?.onChunk
422
+ ? ({ chunk }) => {
423
+ if (chunk.type === "text-delta") {
424
+ streamingOptions.onChunk(chunk.text);
425
+ }
426
+ }
427
+ : undefined,
428
+ onFinish: streamingOptions?.onFinish
429
+ ? ({ text, finishReason, usage }) => {
430
+ streamingOptions.onFinish({
431
+ text,
432
+ finishReason,
433
+ usage,
434
+ isAborted: false,
435
+ });
436
+ }
437
+ : undefined,
438
+ });
439
+ return await result.text;
440
+ }
441
+ else {
442
+ // Use standard streamText without tools
443
+ return this.streamText("", // empty prompt since we use messages
444
+ config, prompts_1.PRD_REWORK_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
445
+ }
318
446
  }, retryConfig, "PRD rework");
319
447
  }
320
448
  // Context7 Integration Methods
@@ -365,22 +493,28 @@ class AIOperations {
365
493
  throw new Error(`Failed to build task enhancement prompt: ${promptResult.error}`);
366
494
  }
367
495
  const prompt = promptResult.prompt;
368
- // Merge Context7 MCP tools with custom research tools
496
+ // Merge Context7 MCP tools with filesystem tools
369
497
  const allTools = {
370
498
  ...mcpTools,
371
- // ...customResearchTools,
499
+ ...filesystem_tools_1.filesystemTools,
372
500
  };
373
- const result = (0, ai_1.streamText)({
501
+ const result = await (0, ai_1.streamText)({
374
502
  model,
375
- tools: allTools, // Context7 MCP tools + custom research tools
503
+ tools: allTools, // Context7 MCP tools + filesystem tools
376
504
  system: prompts_1.TASK_ENHANCEMENT_SYSTEM_PROMPT +
377
505
  `
378
506
 
379
- You have access to Context7 documentation tools.
507
+ You have access to Context7 documentation tools and filesystem tools.
508
+
509
+ ## Available Tools:
510
+ - Context7 MCP tools (context7_resolve_library_id, context7_get_library_docs) for library documentation
511
+ - readFile: Read the contents of any file in the project
512
+ - listDirectory: List contents of directories
380
513
 
381
514
  ## Research Strategy:
382
- 1. Use Context7 MCP tools (context7_resolve_library_id, context7_get_library_docs) for any new research needed
383
- 2. Synthesize information from all sources to enhance the task
515
+ 1. Use Context7 MCP tools for library documentation research
516
+ 2. Use filesystem tools to understand project structure, existing code, and dependencies
517
+ 3. Synthesize information from all sources to enhance the task
384
518
 
385
519
  Technology stack context: ${stackInfo || "Not specified"}
386
520
 
@@ -484,7 +618,7 @@ ${existingResearchContext}`,
484
618
  const allTools = {
485
619
  ...mcpTools,
486
620
  };
487
- const result = (0, ai_1.streamText)({
621
+ const result = await (0, ai_1.streamText)({
488
622
  model,
489
623
  tools: allTools,
490
624
  system: `You are an expert developer.\nYou have access to Context7 MCP tools for documentation research.\nFetch documentation relevant to the task in the project context and create a document giving that knowledge to the AI assistant that will implement the task.`,
@@ -638,10 +772,45 @@ Please provide a 2-3 sentence summary of what documentation is available and how
638
772
  }
639
773
  prompt = promptResult.prompt;
640
774
  }
641
- const response = await this.streamText("", // empty prompt since we use messages
642
- config, prompts_1.TASK_PLANNING_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
775
+ const model = this.modelProvider.getModel({ ...this.modelProvider.getAIConfig(), ...config });
776
+ // Get MCP tools and merge with filesystem tools
777
+ const mcpTools = await this.context7Client.getMCPTools();
778
+ const allTools = {
779
+ ...mcpTools,
780
+ ...filesystem_tools_1.filesystemTools,
781
+ };
782
+ const result = (0, ai_1.streamText)({
783
+ model,
784
+ tools: allTools, // Context7 MCP tools + filesystem tools
785
+ system: prompts_1.TASK_PLANNING_SYSTEM_PROMPT + `
786
+
787
+ You have access to filesystem tools that allow you to:
788
+ - readFile: Read the contents of any file in the project
789
+ - listDirectory: List contents of directories
790
+
791
+ Use these tools to understand the project structure, existing code, and dependencies when creating implementation plans.`,
792
+ messages: [{ role: "user", content: userMessage || prompt }],
793
+ maxRetries: 0,
794
+ onChunk: streamingOptions?.onChunk
795
+ ? ({ chunk }) => {
796
+ if (chunk.type === "text-delta") {
797
+ streamingOptions.onChunk(chunk.text);
798
+ }
799
+ }
800
+ : undefined,
801
+ onFinish: streamingOptions?.onFinish
802
+ ? ({ text, finishReason, usage }) => {
803
+ streamingOptions.onFinish({
804
+ text,
805
+ finishReason,
806
+ usage,
807
+ isAborted: false,
808
+ });
809
+ }
810
+ : undefined,
811
+ });
643
812
  // Return the plan text directly - no JSON parsing needed
644
- return response;
813
+ return (await result).text;
645
814
  }, retryConfig, "Task planning");
646
815
  }
647
816
  }