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.
- 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/ai-service/json-parser.d.ts +13 -0
- package/dist/lib/ai-service/json-parser.d.ts.map +1 -1
- package/dist/lib/ai-service/json-parser.js +66 -5
- 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
|
+
};
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { JSONParseResult } from "../../types";
|
|
2
2
|
export declare class JSONParser {
|
|
3
|
+
/**
|
|
4
|
+
* Extracts JSON from text that may contain markdown codeblocks or other formatting
|
|
5
|
+
*/
|
|
6
|
+
private extractJSONString;
|
|
7
|
+
/**
|
|
8
|
+
* Normalizes object keys to handle case variations (e.g., "Tasks" -> "tasks")
|
|
9
|
+
*/
|
|
10
|
+
private normalizeKeys;
|
|
3
11
|
/**
|
|
4
12
|
* Parses JSON from AI text response with improved error handling
|
|
13
|
+
* Now supports:
|
|
14
|
+
* - Extracting from markdown codeblocks (```json, ```JSON, or ```)
|
|
15
|
+
* - Case-insensitive property names (Tasks -> tasks, Summary -> summary)
|
|
16
|
+
* - Multiple extraction strategies
|
|
17
|
+
*
|
|
5
18
|
* @deprecated Use generateObject instead for structured output
|
|
6
19
|
*/
|
|
7
20
|
parseJSONFromResponse<T>(text: string): JSONParseResult<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-parser.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/json-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,qBAAa,UAAU;IACrB
|
|
1
|
+
{"version":3,"file":"json-parser.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/json-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,qBAAa,UAAU;IACrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmCzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAsBrB;;;;;;;;OAQG;IACH,qBAAqB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC;CAgC3D"}
|
|
@@ -2,23 +2,84 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.JSONParser = void 0;
|
|
4
4
|
class JSONParser {
|
|
5
|
+
/**
|
|
6
|
+
* Extracts JSON from text that may contain markdown codeblocks or other formatting
|
|
7
|
+
*/
|
|
8
|
+
extractJSONString(text) {
|
|
9
|
+
// Strategy 1: Try to extract from markdown codeblock (```json ... ``` or ``` ... ```)
|
|
10
|
+
const codeblockPatterns = [
|
|
11
|
+
/```json\s*([\s\S]*?)```/i,
|
|
12
|
+
/```JSON\s*([\s\S]*?)```/i,
|
|
13
|
+
/```\s*([\s\S]*?)```/,
|
|
14
|
+
];
|
|
15
|
+
for (const pattern of codeblockPatterns) {
|
|
16
|
+
const match = text.match(pattern);
|
|
17
|
+
if (match && match[1]) {
|
|
18
|
+
const extracted = match[1].trim();
|
|
19
|
+
// Verify it looks like JSON (starts with { or [)
|
|
20
|
+
if (extracted.startsWith("{") || extracted.startsWith("[")) {
|
|
21
|
+
return extracted;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Strategy 2: Try to extract JSON object/array directly
|
|
26
|
+
const directPatterns = [
|
|
27
|
+
/\{[\s\S]*\}/, // Object
|
|
28
|
+
/\[[\s\S]*\]/, // Array
|
|
29
|
+
];
|
|
30
|
+
for (const pattern of directPatterns) {
|
|
31
|
+
const match = text.match(pattern);
|
|
32
|
+
if (match) {
|
|
33
|
+
return match[0];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Normalizes object keys to handle case variations (e.g., "Tasks" -> "tasks")
|
|
40
|
+
*/
|
|
41
|
+
normalizeKeys(obj) {
|
|
42
|
+
if (obj === null || obj === undefined) {
|
|
43
|
+
return obj;
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(obj)) {
|
|
46
|
+
return obj.map((item) => this.normalizeKeys(item));
|
|
47
|
+
}
|
|
48
|
+
if (typeof obj === "object") {
|
|
49
|
+
const normalized = {};
|
|
50
|
+
for (const key in obj) {
|
|
51
|
+
// Convert first letter to lowercase
|
|
52
|
+
const normalizedKey = key.charAt(0).toLowerCase() + key.slice(1);
|
|
53
|
+
normalized[normalizedKey] = this.normalizeKeys(obj[key]);
|
|
54
|
+
}
|
|
55
|
+
return normalized;
|
|
56
|
+
}
|
|
57
|
+
return obj;
|
|
58
|
+
}
|
|
5
59
|
/**
|
|
6
60
|
* Parses JSON from AI text response with improved error handling
|
|
61
|
+
* Now supports:
|
|
62
|
+
* - Extracting from markdown codeblocks (```json, ```JSON, or ```)
|
|
63
|
+
* - Case-insensitive property names (Tasks -> tasks, Summary -> summary)
|
|
64
|
+
* - Multiple extraction strategies
|
|
65
|
+
*
|
|
7
66
|
* @deprecated Use generateObject instead for structured output
|
|
8
67
|
*/
|
|
9
68
|
parseJSONFromResponse(text) {
|
|
10
69
|
try {
|
|
11
70
|
// Try to extract JSON from the response (handle various formats)
|
|
12
|
-
const
|
|
13
|
-
if (!
|
|
71
|
+
const jsonStr = this.extractJSONString(text);
|
|
72
|
+
if (!jsonStr) {
|
|
14
73
|
return {
|
|
15
74
|
success: false,
|
|
16
|
-
error: "Could not extract JSON from AI response",
|
|
75
|
+
error: "Could not extract JSON from AI response. No JSON object or codeblock found.",
|
|
17
76
|
rawText: text,
|
|
18
77
|
};
|
|
19
78
|
}
|
|
20
|
-
|
|
21
|
-
|
|
79
|
+
// Parse the JSON
|
|
80
|
+
let parsed = JSON.parse(jsonStr);
|
|
81
|
+
// Normalize keys to handle case variations (Tasks -> tasks, etc.)
|
|
82
|
+
parsed = this.normalizeKeys(parsed);
|
|
22
83
|
return {
|
|
23
84
|
success: true,
|
|
24
85
|
data: parsed,
|
|
@@ -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"}
|