task-o-matic 0.0.2 → 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 (35) 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/executors/claude-code-executor.d.ts +6 -0
  12. package/dist/lib/executors/claude-code-executor.d.ts.map +1 -0
  13. package/dist/lib/executors/claude-code-executor.js +41 -0
  14. package/dist/lib/executors/codex-executor.d.ts +6 -0
  15. package/dist/lib/executors/codex-executor.d.ts.map +1 -0
  16. package/dist/lib/executors/codex-executor.js +41 -0
  17. package/dist/lib/executors/executor-factory.d.ts.map +1 -1
  18. package/dist/lib/executors/executor-factory.js +6 -3
  19. package/dist/lib/executors/gemini-executor.d.ts +6 -0
  20. package/dist/lib/executors/gemini-executor.d.ts.map +1 -0
  21. package/dist/lib/executors/gemini-executor.js +41 -0
  22. package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
  23. package/dist/lib/executors/opencode-executor.js +2 -3
  24. package/dist/lib/prompt-builder.d.ts +8 -0
  25. package/dist/lib/prompt-builder.d.ts.map +1 -1
  26. package/dist/lib/prompt-builder.js +98 -0
  27. package/dist/lib/task-execution.d.ts.map +1 -1
  28. package/dist/lib/task-execution.js +44 -14
  29. package/dist/services/prd.d.ts +2 -0
  30. package/dist/services/prd.d.ts.map +1 -1
  31. package/dist/services/prd.js +4 -4
  32. package/dist/services/tasks.d.ts +10 -1
  33. package/dist/services/tasks.d.ts.map +1 -1
  34. package/dist/services/tasks.js +97 -2
  35. package/package.json +1 -1
@@ -0,0 +1,69 @@
1
+ export declare const readFileTool: import("ai").Tool<{
2
+ filePath: string;
3
+ }, {
4
+ success: boolean;
5
+ content: string;
6
+ path: string;
7
+ size: number;
8
+ error?: undefined;
9
+ } | {
10
+ success: boolean;
11
+ error: string;
12
+ content?: undefined;
13
+ path?: undefined;
14
+ size?: undefined;
15
+ }>;
16
+ export declare const listDirectoryTool: import("ai").Tool<{
17
+ dirPath: string;
18
+ }, {
19
+ success: boolean;
20
+ contents: {
21
+ name: string;
22
+ type: string;
23
+ path: string;
24
+ size: number | undefined;
25
+ }[];
26
+ directory: string;
27
+ error?: undefined;
28
+ } | {
29
+ success: boolean;
30
+ error: string;
31
+ contents: never[];
32
+ directory?: undefined;
33
+ }>;
34
+ export declare const filesystemTools: {
35
+ readFile: import("ai").Tool<{
36
+ filePath: string;
37
+ }, {
38
+ success: boolean;
39
+ content: string;
40
+ path: string;
41
+ size: number;
42
+ error?: undefined;
43
+ } | {
44
+ success: boolean;
45
+ error: string;
46
+ content?: undefined;
47
+ path?: undefined;
48
+ size?: undefined;
49
+ }>;
50
+ listDirectory: import("ai").Tool<{
51
+ dirPath: string;
52
+ }, {
53
+ success: boolean;
54
+ contents: {
55
+ name: string;
56
+ type: string;
57
+ path: string;
58
+ size: number | undefined;
59
+ }[];
60
+ directory: string;
61
+ error?: undefined;
62
+ } | {
63
+ success: boolean;
64
+ error: string;
65
+ contents: never[];
66
+ directory?: undefined;
67
+ }>;
68
+ };
69
+ //# sourceMappingURL=filesystem-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-tools.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/filesystem-tools.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;EAwBvB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;EAoC5B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAG3B,CAAC"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filesystemTools = exports.listDirectoryTool = exports.readFileTool = void 0;
4
+ const ai_1 = require("ai");
5
+ const v3_1 = require("zod/v3");
6
+ const promises_1 = require("fs/promises");
7
+ const path_1 = require("path");
8
+ exports.readFileTool = (0, ai_1.tool)({
9
+ description: "Read the contents of a file",
10
+ inputSchema: v3_1.z.object({
11
+ filePath: v3_1.z.string().describe("Path to the file to read"),
12
+ }),
13
+ execute: async ({ filePath }) => {
14
+ try {
15
+ const resolvedPath = (0, path_1.resolve)(filePath);
16
+ const content = await (0, promises_1.readFile)(resolvedPath, 'utf-8');
17
+ const stats = await (0, promises_1.stat)(resolvedPath);
18
+ return {
19
+ success: true,
20
+ content,
21
+ path: (0, path_1.relative)(process.cwd(), resolvedPath),
22
+ size: stats.size,
23
+ };
24
+ }
25
+ catch (error) {
26
+ return {
27
+ success: false,
28
+ error: error instanceof Error ? error.message : "Unknown error",
29
+ };
30
+ }
31
+ },
32
+ });
33
+ exports.listDirectoryTool = (0, ai_1.tool)({
34
+ description: "List contents of a directory",
35
+ inputSchema: v3_1.z.object({
36
+ dirPath: v3_1.z.string().describe("Directory path to list"),
37
+ }),
38
+ execute: async ({ dirPath }) => {
39
+ try {
40
+ const resolvedPath = (0, path_1.resolve)(dirPath);
41
+ const entries = await (0, promises_1.readdir)(resolvedPath, { withFileTypes: true });
42
+ const contents = await Promise.all(entries.map(async (entry) => {
43
+ const fullPath = (0, path_1.join)(resolvedPath, entry.name);
44
+ const stats = await (0, promises_1.stat)(fullPath);
45
+ return {
46
+ name: entry.name,
47
+ type: entry.isDirectory() ? "directory" : "file",
48
+ path: (0, path_1.relative)(process.cwd(), fullPath),
49
+ size: entry.isFile() ? stats.size : undefined,
50
+ };
51
+ }));
52
+ return {
53
+ success: true,
54
+ contents,
55
+ directory: (0, path_1.relative)(process.cwd(), resolvedPath),
56
+ };
57
+ }
58
+ catch (error) {
59
+ return {
60
+ success: false,
61
+ error: error instanceof Error ? error.message : "Unknown error",
62
+ contents: [],
63
+ };
64
+ }
65
+ },
66
+ });
67
+ exports.filesystemTools = {
68
+ readFile: exports.readFileTool,
69
+ listDirectory: exports.listDirectoryTool,
70
+ };
@@ -0,0 +1,6 @@
1
+ import { ExternalExecutor } from "../../types";
2
+ export declare class ClaudeCodeExecutor implements ExternalExecutor {
3
+ name: string;
4
+ execute(message: string, dry?: boolean): Promise<void>;
5
+ }
6
+ //# sourceMappingURL=claude-code-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/claude-code-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,qBAAa,kBAAmB,YAAW,gBAAgB;IACzD,IAAI,SAAY;IAEV,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CA+BpE"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ClaudeCodeExecutor = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const child_process_1 = require("child_process");
9
+ class ClaudeCodeExecutor {
10
+ name = "claude";
11
+ async execute(message, dry = false) {
12
+ if (dry) {
13
+ console.log(chalk_1.default.cyan(`🔧 Using executor: ${this.name}`));
14
+ console.log(chalk_1.default.cyan(`claude -p "${message}"`));
15
+ return;
16
+ }
17
+ // Launch claude and wait for it to complete
18
+ const child = (0, child_process_1.spawn)("claude", ["-p", message], {
19
+ stdio: "inherit", // Give tool full terminal control
20
+ });
21
+ // Wait for completion (blocking)
22
+ await new Promise((resolve, reject) => {
23
+ child.on("close", (code) => {
24
+ if (code === 0) {
25
+ console.log("✅ Claude Code execution completed successfully");
26
+ resolve();
27
+ }
28
+ else {
29
+ const error = new Error(`Claude Code exited with code ${code}`);
30
+ console.error(`❌ ${error.message}`);
31
+ reject(error);
32
+ }
33
+ });
34
+ child.on("error", (error) => {
35
+ console.error(`❌ Failed to launch Claude Code: ${error.message}`);
36
+ reject(error);
37
+ });
38
+ });
39
+ }
40
+ }
41
+ exports.ClaudeCodeExecutor = ClaudeCodeExecutor;
@@ -0,0 +1,6 @@
1
+ import { ExternalExecutor } from "../../types";
2
+ export declare class CodexExecutor implements ExternalExecutor {
3
+ name: string;
4
+ execute(message: string, dry?: boolean): Promise<void>;
5
+ }
6
+ //# sourceMappingURL=codex-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/codex-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,qBAAa,aAAc,YAAW,gBAAgB;IACpD,IAAI,SAAW;IAET,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CA+BpE"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CodexExecutor = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const child_process_1 = require("child_process");
9
+ class CodexExecutor {
10
+ name = "codex";
11
+ async execute(message, dry = false) {
12
+ if (dry) {
13
+ console.log(chalk_1.default.cyan(`🔧 Using executor: ${this.name}`));
14
+ console.log(chalk_1.default.cyan(`codex exec "${message}"`));
15
+ return;
16
+ }
17
+ // Launch codex and wait for it to complete
18
+ const child = (0, child_process_1.spawn)("codex", ["exec", message], {
19
+ stdio: "inherit", // Give tool full terminal control
20
+ });
21
+ // Wait for completion (blocking)
22
+ await new Promise((resolve, reject) => {
23
+ child.on("close", (code) => {
24
+ if (code === 0) {
25
+ console.log("✅ Codex CLI execution completed successfully");
26
+ resolve();
27
+ }
28
+ else {
29
+ const error = new Error(`Codex CLI exited with code ${code}`);
30
+ console.error(`❌ ${error.message}`);
31
+ reject(error);
32
+ }
33
+ });
34
+ child.on("error", (error) => {
35
+ console.error(`❌ Failed to launch Codex CLI: ${error.message}`);
36
+ reject(error);
37
+ });
38
+ });
39
+ }
40
+ }
41
+ exports.CodexExecutor = CodexExecutor;
@@ -1 +1 @@
1
- {"version":3,"file":"executor-factory.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/executor-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG7D,qBAAa,eAAe;IAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,GAAE,YAAyB,GAAG,gBAAgB;CAcjE"}
1
+ {"version":3,"file":"executor-factory.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/executor-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM7D,qBAAa,eAAe;IAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,GAAE,YAAyB,GAAG,gBAAgB;CAcjE"}
@@ -2,17 +2,20 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ExecutorFactory = void 0;
4
4
  const opencode_executor_1 = require("./opencode-executor");
5
+ const claude_code_executor_1 = require("./claude-code-executor");
6
+ const gemini_executor_1 = require("./gemini-executor");
7
+ const codex_executor_1 = require("./codex-executor");
5
8
  class ExecutorFactory {
6
9
  static create(tool = "opencode") {
7
10
  switch (tool) {
8
11
  case "opencode":
9
12
  return new opencode_executor_1.OpencodeExecutor();
10
13
  case "claude":
11
- throw new Error("Claude executor not implemented yet");
14
+ return new claude_code_executor_1.ClaudeCodeExecutor();
12
15
  case "gemini":
13
- throw new Error("Gemini executor not implemented yet");
16
+ return new gemini_executor_1.GeminiExecutor();
14
17
  case "codex":
15
- throw new Error("Codex executor not implemented yet");
18
+ return new codex_executor_1.CodexExecutor();
16
19
  default:
17
20
  throw new Error(`Unknown executor tool: ${tool}`);
18
21
  }
@@ -0,0 +1,6 @@
1
+ import { ExternalExecutor } from "../../types";
2
+ export declare class GeminiExecutor implements ExternalExecutor {
3
+ name: string;
4
+ execute(message: string, dry?: boolean): Promise<void>;
5
+ }
6
+ //# sourceMappingURL=gemini-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/gemini-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,qBAAa,cAAe,YAAW,gBAAgB;IACrD,IAAI,SAAY;IAEV,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CA+BpE"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GeminiExecutor = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const child_process_1 = require("child_process");
9
+ class GeminiExecutor {
10
+ name = "gemini";
11
+ async execute(message, dry = false) {
12
+ if (dry) {
13
+ console.log(chalk_1.default.cyan(`🔧 Using executor: ${this.name}`));
14
+ console.log(chalk_1.default.cyan(`gemini -p "${message}"`));
15
+ return;
16
+ }
17
+ // Launch gemini and wait for it to complete
18
+ const child = (0, child_process_1.spawn)("gemini", ["-p", message], {
19
+ stdio: "inherit", // Give tool full terminal control
20
+ });
21
+ // Wait for completion (blocking)
22
+ await new Promise((resolve, reject) => {
23
+ child.on("close", (code) => {
24
+ if (code === 0) {
25
+ console.log("✅ Gemini CLI execution completed successfully");
26
+ resolve();
27
+ }
28
+ else {
29
+ const error = new Error(`Gemini CLI exited with code ${code}`);
30
+ console.error(`❌ ${error.message}`);
31
+ reject(error);
32
+ }
33
+ });
34
+ child.on("error", (error) => {
35
+ console.error(`❌ Failed to launch Gemini CLI: ${error.message}`);
36
+ reject(error);
37
+ });
38
+ });
39
+ }
40
+ }
41
+ exports.GeminiExecutor = GeminiExecutor;
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/opencode-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,aAAa,CAAC;AAIhE,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,IAAI,SAAc;IAEZ,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAsCpE"}
1
+ {"version":3,"file":"opencode-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/opencode-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,aAAa,CAAC;AAIhE,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,IAAI,SAAc;IAEZ,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAmCpE"}
@@ -9,12 +9,11 @@ const child_process_1 = require("child_process");
9
9
  class OpencodeExecutor {
10
10
  name = "opencode";
11
11
  async execute(message, dry = false) {
12
- const command = `opencode run "${message}"`;
13
12
  if (dry) {
14
- console.log(chalk_1.default.cyan(command));
13
+ console.log(chalk_1.default.cyan(`🔧 Using executor: ${this.name}`));
14
+ console.log(chalk_1.default.cyan(`opencode -p "${message}"`));
15
15
  return;
16
16
  }
17
- console.log(`🚀 Launching opencode with message: ${message}`);
18
17
  // Launch opencode and wait for it to complete
19
18
  const child = (0, child_process_1.spawn)("opencode", ["-p", message], {
20
19
  stdio: "inherit", // Give tool full terminal control
@@ -46,5 +46,13 @@ export declare class PromptBuilder {
46
46
  * Detect stack info using ContextBuilder (proper BTS config loading)
47
47
  */
48
48
  static detectStackInfo(projectPath?: string): Promise<string>;
49
+ /**
50
+ * Build comprehensive project context for external executors
51
+ */
52
+ static buildFullProjectContext(projectPath: string): Promise<string>;
53
+ /**
54
+ * Format prompt for specific executor
55
+ */
56
+ static formatForExecutor(prompt: string, executor: "opencode" | "claude" | "gemini" | "codex"): string;
49
57
  }
50
58
  //# sourceMappingURL=prompt-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/lib/prompt-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAKnE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,qBAAa,aAAa;IACxB;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,mBAAmB;IAyEtE;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM;IAI5B;;OAEG;IACH,MAAM,CAAC,iBAAiB,CACtB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GACvB,cAAc,GAAG,IAAI;IAKxB;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAO/C;;OAEG;WACU,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAiBhE;;OAEG;WACU,gBAAgB,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC;IAmClB;;OAEG;WACU,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAsCpE"}
1
+ {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/lib/prompt-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMnE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,qBAAa,aAAa;IACxB;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,mBAAmB;IAyEtE;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM;IAI5B;;OAEG;IACH,MAAM,CAAC,iBAAiB,CACtB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GACvB,cAAc,GAAG,IAAI;IAKxB;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAO/C;;OAEG;WACU,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAiBhE;;OAEG;WACU,gBAAgB,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC;IAmClB;;OAEG;WACU,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuCnE;;OAEG;WACU,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmF1E;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM;CAmBvG"}
@@ -5,6 +5,7 @@ const prompt_registry_1 = require("./prompt-registry");
5
5
  const fs_1 = require("fs");
6
6
  const config_1 = require("./config");
7
7
  const context_builder_1 = require("./context-builder");
8
+ const path_1 = require("path");
8
9
  class PromptBuilder {
9
10
  /**
10
11
  * Build a prompt with variable replacement
@@ -167,5 +168,102 @@ class PromptBuilder {
167
168
  return "Not detected";
168
169
  }
169
170
  }
171
+ /**
172
+ * Build comprehensive project context for external executors
173
+ */
174
+ static async buildFullProjectContext(projectPath) {
175
+ const contextParts = [];
176
+ contextParts.push("**Project Context:**");
177
+ // Detect package.json and dependencies
178
+ const packageJsonPath = (0, path_1.join)(projectPath, "package.json");
179
+ if ((0, fs_1.existsSync)(packageJsonPath)) {
180
+ try {
181
+ const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, "utf-8"));
182
+ const deps = Object.keys(packageJson.dependencies || {});
183
+ const devDeps = Object.keys(packageJson.devDependencies || {});
184
+ contextParts.push(`\n**Dependencies:**`);
185
+ if (deps.length > 0) {
186
+ contextParts.push(`- Production: ${deps.slice(0, 10).join(", ")}${deps.length > 10 ? ` (+${deps.length - 10} more)` : ""}`);
187
+ }
188
+ if (devDeps.length > 0) {
189
+ contextParts.push(`- Development: ${devDeps.slice(0, 10).join(", ")}${devDeps.length > 10 ? ` (+${devDeps.length - 10} more)` : ""}`);
190
+ }
191
+ if (packageJson.scripts) {
192
+ const scripts = Object.keys(packageJson.scripts);
193
+ contextParts.push(`\n**Available Scripts:** ${scripts.join(", ")}`);
194
+ }
195
+ }
196
+ catch (error) {
197
+ console.warn("Could not parse package.json:", error);
198
+ }
199
+ }
200
+ // Detect project structure
201
+ try {
202
+ const files = (0, fs_1.readdirSync)(projectPath);
203
+ const directories = files.filter((f) => {
204
+ try {
205
+ const stat = (0, fs_1.statSync)((0, path_1.join)(projectPath, f));
206
+ return stat.isDirectory() && !f.startsWith(".");
207
+ }
208
+ catch {
209
+ return false;
210
+ }
211
+ });
212
+ if (directories.length > 0) {
213
+ contextParts.push(`\n**Project Structure:** ${directories.join(", ")}`);
214
+ }
215
+ // Detect configuration files
216
+ const configFiles = files.filter((f) => f.match(/\.(config|rc)\.(js|ts|json|yaml|yml)$/) ||
217
+ ["tsconfig.json", "next.config.js", "vite.config.ts", "tailwind.config.js"].includes(f));
218
+ if (configFiles.length > 0) {
219
+ contextParts.push(`\n**Configuration Files:** ${configFiles.join(", ")}`);
220
+ }
221
+ }
222
+ catch (error) {
223
+ console.warn("Could not read project structure:", error);
224
+ }
225
+ // Detect frameworks and tools
226
+ const detectedTools = [];
227
+ if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, "next.config.js")) || (0, fs_1.existsSync)((0, path_1.join)(projectPath, "next.config.ts"))) {
228
+ detectedTools.push("Next.js");
229
+ }
230
+ if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, "vite.config.ts")) || (0, fs_1.existsSync)((0, path_1.join)(projectPath, "vite.config.js"))) {
231
+ detectedTools.push("Vite");
232
+ }
233
+ if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, "tailwind.config.js")) || (0, fs_1.existsSync)((0, path_1.join)(projectPath, "tailwind.config.ts"))) {
234
+ detectedTools.push("Tailwind CSS");
235
+ }
236
+ if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, "convex"))) {
237
+ detectedTools.push("Convex");
238
+ }
239
+ if ((0, fs_1.existsSync)((0, path_1.join)(projectPath, "turbo.json"))) {
240
+ detectedTools.push("Turborepo");
241
+ }
242
+ if (detectedTools.length > 0) {
243
+ contextParts.push(`\n**Detected Tools:** ${detectedTools.join(", ")}`);
244
+ }
245
+ return contextParts.join("\n");
246
+ }
247
+ /**
248
+ * Format prompt for specific executor
249
+ */
250
+ static formatForExecutor(prompt, executor) {
251
+ // Most executors work well with plain text prompts
252
+ // This method exists for future customization if needed
253
+ switch (executor) {
254
+ case "claude":
255
+ // Claude Code works well with structured markdown
256
+ return prompt;
257
+ case "gemini":
258
+ // Gemini CLI supports file references with @
259
+ return prompt;
260
+ case "codex":
261
+ // Codex CLI supports structured prompts
262
+ return prompt;
263
+ case "opencode":
264
+ default:
265
+ return prompt;
266
+ }
267
+ }
170
268
  }
171
269
  exports.PromptBuilder = PromptBuilder;
@@ -1 +1 @@
1
- {"version":3,"file":"task-execution.d.ts","sourceRoot":"","sources":["../../src/lib/task-execution.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAgB,MAAM,UAAU,CAAC;AA2H5D,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4D5E"}
1
+ {"version":3,"file":"task-execution.d.ts","sourceRoot":"","sources":["../../src/lib/task-execution.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAgB,MAAM,UAAU,CAAC;AAoK5D,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwD5E"}
@@ -7,6 +7,7 @@ exports.executeTask = executeTask;
7
7
  const tasks_1 = require("../services/tasks");
8
8
  const executor_factory_1 = require("./executors/executor-factory");
9
9
  const validation_1 = require("./validation");
10
+ const context_builder_1 = require("./context-builder");
10
11
  const chalk_1 = __importDefault(require("chalk"));
11
12
  async function executeSingleTask(taskId, tool, dry) {
12
13
  // Load task
@@ -15,19 +16,54 @@ async function executeSingleTask(taskId, tool, dry) {
15
16
  throw new Error(`Task with ID ${taskId} not found`);
16
17
  }
17
18
  console.log(chalk_1.default.blue(`🎯 ${dry ? "DRY RUN" : "Executing"} task: ${task.title} (${taskId})`));
18
- // Build execution message
19
- let executionMessage;
19
+ // Build comprehensive execution message with full context
20
+ const contextBuilder = new context_builder_1.ContextBuilder();
21
+ const taskContext = await contextBuilder.buildContext(taskId);
22
+ // Build execution message with ALL context
23
+ const messageParts = [];
24
+ // Add task plan if available
20
25
  const planData = await tasks_1.taskService.getTaskPlan(taskId);
21
26
  if (planData) {
22
- executionMessage = `Execute this task plan:\n\n${planData.plan}`;
27
+ messageParts.push(`# Task Plan\n\n${planData.plan}\n`);
23
28
  }
24
29
  else {
25
- executionMessage = `Execute this task: ${task.title}\n\nDescription: ${task.description || "No description"}`;
30
+ messageParts.push(`# Task: ${task.title}\n\n${task.description || "No description"}\n`);
26
31
  }
32
+ // Add PRD context if available
33
+ if (taskContext.prdContent) {
34
+ messageParts.push(`\n# Product Requirements Document\n\n${taskContext.prdContent}\n`);
35
+ }
36
+ // Add stack/technology context
37
+ if (taskContext.stack) {
38
+ messageParts.push(`\n# Technology Stack\n\n`);
39
+ messageParts.push(`- **Project**: ${taskContext.stack.projectName}\n`);
40
+ messageParts.push(`- **Frontend**: ${taskContext.stack.frontend}\n`);
41
+ messageParts.push(`- **Backend**: ${taskContext.stack.backend}\n`);
42
+ if (taskContext.stack.database !== "none") {
43
+ messageParts.push(`- **Database**: ${taskContext.stack.database}\n`);
44
+ }
45
+ if (taskContext.stack.orm !== "none") {
46
+ messageParts.push(`- **ORM**: ${taskContext.stack.orm}\n`);
47
+ }
48
+ messageParts.push(`- **Auth**: ${taskContext.stack.auth}\n`);
49
+ if (taskContext.stack.addons.length > 0) {
50
+ messageParts.push(`- **Addons**: ${taskContext.stack.addons.join(", ")}\n`);
51
+ }
52
+ messageParts.push(`- **Package Manager**: ${taskContext.stack.packageManager}\n`);
53
+ }
54
+ // Add documentation context if available
55
+ if (taskContext.documentation) {
56
+ messageParts.push(`\n# Documentation Context\n\n`);
57
+ messageParts.push(`${taskContext.documentation.recap}\n`);
58
+ if (taskContext.documentation.files.length > 0) {
59
+ messageParts.push(`\n**Relevant Documentation Files**:\n`);
60
+ taskContext.documentation.files.forEach((file) => {
61
+ messageParts.push(`- ${file.path}\n`);
62
+ });
63
+ }
64
+ }
65
+ const executionMessage = messageParts.join('');
27
66
  if (!dry) {
28
- // console.log(chalk.yellow(`📝 Message that would be sent:`));
29
- // console.log(chalk.cyan(executionMessage));
30
- // } else {
31
67
  // Update task status to in-progress
32
68
  await tasks_1.taskService.setTaskStatus(taskId, "in-progress");
33
69
  console.log(chalk_1.default.yellow("⏳ Task status updated to in-progress"));
@@ -35,7 +71,6 @@ async function executeSingleTask(taskId, tool, dry) {
35
71
  try {
36
72
  // Create executor and run
37
73
  const executor = executor_factory_1.ExecutorFactory.create(tool);
38
- console.log(chalk_1.default.cyan(`🔧 Using executor: ${executor.name}`));
39
74
  await executor.execute(executionMessage, dry);
40
75
  if (!dry) {
41
76
  // Update task status to completed
@@ -95,17 +130,12 @@ async function executeTask(options) {
95
130
  throw new Error(`Task with ID ${taskId} not found`);
96
131
  }
97
132
  console.log(chalk_1.default.blue(`🎯 ${dry ? "DRY RUN - Would execute" : "Executing"} task with custom message: ${task.title} (${taskId})`));
98
- if (dry) {
99
- console.log(chalk_1.default.yellow(`📝 Custom message that would be sent:`));
100
- console.log(chalk_1.default.cyan(message));
101
- }
102
- else {
133
+ if (!dry) {
103
134
  await tasks_1.taskService.setTaskStatus(taskId, "in-progress");
104
135
  console.log(chalk_1.default.yellow("⏳ Task status updated to in-progress"));
105
136
  }
106
137
  try {
107
138
  const executor = executor_factory_1.ExecutorFactory.create(tool);
108
- console.log(chalk_1.default.cyan(`🔧 Using executor: ${executor.name}`));
109
139
  await executor.execute(message, dry);
110
140
  if (!dry) {
111
141
  await tasks_1.taskService.setTaskStatus(taskId, "completed");
@@ -10,6 +10,7 @@ export declare class PRDService {
10
10
  parsePRD(input: {
11
11
  file: string;
12
12
  workingDirectory?: string;
13
+ enableFilesystemTools?: boolean;
13
14
  aiOptions?: AIOptions;
14
15
  promptOverride?: string;
15
16
  messageOverride?: string;
@@ -21,6 +22,7 @@ export declare class PRDService {
21
22
  feedback: string;
22
23
  output?: string;
23
24
  workingDirectory?: string;
25
+ enableFilesystemTools?: boolean;
24
26
  aiOptions?: AIOptions;
25
27
  promptOverride?: string;
26
28
  messageOverride?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"prd.d.ts","sourceRoot":"","sources":["../../src/services/prd.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAY,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,qBAAa,UAAU;IAEf,QAAQ,CAAC,KAAK,EAAE;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;QACpC,SAAS,CAAC,EAAE,gBAAgB,CAAC;KAC9B,GAAG,OAAO,CAAC,cAAc,CAAC;IA+KrB,SAAS,CAAC,KAAK,EAAE;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;QACpC,SAAS,CAAC,EAAE,gBAAgB,CAAC;KAC9B,GAAG,OAAO,CAAC,MAAM,CAAC;CA4DpB;AAGD,eAAO,MAAM,UAAU,YAAmB,CAAC"}
1
+ {"version":3,"file":"prd.d.ts","sourceRoot":"","sources":["../../src/services/prd.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAY,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,qBAAa,UAAU;IAEf,QAAQ,CAAC,KAAK,EAAE;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;QACpC,SAAS,CAAC,EAAE,gBAAgB,CAAC;KAC9B,GAAG,OAAO,CAAC,cAAc,CAAC;IAgLrB,SAAS,CAAC,KAAK,EAAE;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;QACpC,SAAS,CAAC,EAAE,gBAAgB,CAAC;KAC9B,GAAG,OAAO,CAAC,MAAM,CAAC;CA6DpB;AAGD,eAAO,MAAM,UAAU,YAAmB,CAAC"}
@@ -69,8 +69,8 @@ class PRDService {
69
69
  });
70
70
  const stepStart2 = Date.now();
71
71
  const result = await (0, ai_service_factory_1.getAIOperations)().parsePRD(prdContent, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, // retryConfig
72
- workingDir // Pass working directory to AI operations
73
- );
72
+ workingDir, // Pass working directory to AI operations
73
+ input.enableFilesystemTools);
74
74
  steps.push({
75
75
  step: 'AI Parsing',
76
76
  status: 'completed',
@@ -171,8 +171,8 @@ class PRDService {
171
171
  message: 'Calling AI to improve PRD...',
172
172
  });
173
173
  const improvedPRD = await (0, ai_service_factory_1.getAIOperations)().reworkPRD(prdContent, input.feedback, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, // retryConfig
174
- workingDir // Pass working directory to AI operations
175
- );
174
+ workingDir, // Pass working directory to AI operations
175
+ input.enableFilesystemTools);
176
176
  input.callbacks?.onProgress?.({
177
177
  type: 'progress',
178
178
  message: 'Saving improved PRD...',