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.
- package/dist/commands/prd.js +4 -0
- package/dist/commands/prompt.d.ts.map +1 -1
- package/dist/commands/prompt.js +69 -61
- package/dist/commands/tasks.js +93 -1
- package/dist/lib/ai-service/ai-operations.d.ts +5 -3
- package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/ai-operations.js +189 -20
- package/dist/lib/ai-service/filesystem-tools.d.ts +69 -0
- package/dist/lib/ai-service/filesystem-tools.d.ts.map +1 -0
- package/dist/lib/ai-service/filesystem-tools.js +70 -0
- package/dist/lib/executors/claude-code-executor.d.ts +6 -0
- package/dist/lib/executors/claude-code-executor.d.ts.map +1 -0
- package/dist/lib/executors/claude-code-executor.js +41 -0
- package/dist/lib/executors/codex-executor.d.ts +6 -0
- package/dist/lib/executors/codex-executor.d.ts.map +1 -0
- package/dist/lib/executors/codex-executor.js +41 -0
- package/dist/lib/executors/executor-factory.d.ts.map +1 -1
- package/dist/lib/executors/executor-factory.js +6 -3
- package/dist/lib/executors/gemini-executor.d.ts +6 -0
- package/dist/lib/executors/gemini-executor.d.ts.map +1 -0
- package/dist/lib/executors/gemini-executor.js +41 -0
- package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
- package/dist/lib/executors/opencode-executor.js +2 -3
- package/dist/lib/prompt-builder.d.ts +8 -0
- package/dist/lib/prompt-builder.d.ts.map +1 -1
- package/dist/lib/prompt-builder.js +98 -0
- package/dist/lib/task-execution.d.ts.map +1 -1
- package/dist/lib/task-execution.js +44 -14
- package/dist/services/prd.d.ts +2 -0
- package/dist/services/prd.d.ts.map +1 -1
- package/dist/services/prd.js +4 -4
- package/dist/services/tasks.d.ts +10 -1
- package/dist/services/tasks.d.ts.map +1 -1
- package/dist/services/tasks.js +97 -2
- 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 @@
|
|
|
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 @@
|
|
|
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;
|
|
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
|
-
|
|
14
|
+
return new claude_code_executor_1.ClaudeCodeExecutor();
|
|
12
15
|
case "gemini":
|
|
13
|
-
|
|
16
|
+
return new gemini_executor_1.GeminiExecutor();
|
|
14
17
|
case "codex":
|
|
15
|
-
|
|
18
|
+
return new codex_executor_1.CodexExecutor();
|
|
16
19
|
default:
|
|
17
20
|
throw new Error(`Unknown executor tool: ${tool}`);
|
|
18
21
|
}
|
|
@@ -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;
|
|
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(
|
|
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;
|
|
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;
|
|
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
|
-
|
|
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
|
-
|
|
27
|
+
messageParts.push(`# Task Plan\n\n${planData.plan}\n`);
|
|
23
28
|
}
|
|
24
29
|
else {
|
|
25
|
-
|
|
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");
|
package/dist/services/prd.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/services/prd.js
CHANGED
|
@@ -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...',
|