task-o-matic 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/commands/prd.js +4 -0
  2. package/dist/commands/prompt.d.ts.map +1 -1
  3. package/dist/commands/prompt.js +69 -61
  4. package/dist/commands/tasks.js +93 -1
  5. package/dist/lib/ai-service/ai-operations.d.ts +5 -3
  6. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
  7. package/dist/lib/ai-service/ai-operations.js +189 -20
  8. package/dist/lib/ai-service/filesystem-tools.d.ts +69 -0
  9. package/dist/lib/ai-service/filesystem-tools.d.ts.map +1 -0
  10. package/dist/lib/ai-service/filesystem-tools.js +70 -0
  11. package/dist/lib/ai-service/json-parser.d.ts +13 -0
  12. package/dist/lib/ai-service/json-parser.d.ts.map +1 -1
  13. package/dist/lib/ai-service/json-parser.js +66 -5
  14. package/dist/lib/executors/claude-code-executor.d.ts +6 -0
  15. package/dist/lib/executors/claude-code-executor.d.ts.map +1 -0
  16. package/dist/lib/executors/claude-code-executor.js +41 -0
  17. package/dist/lib/executors/codex-executor.d.ts +6 -0
  18. package/dist/lib/executors/codex-executor.d.ts.map +1 -0
  19. package/dist/lib/executors/codex-executor.js +41 -0
  20. package/dist/lib/executors/executor-factory.d.ts.map +1 -1
  21. package/dist/lib/executors/executor-factory.js +6 -3
  22. package/dist/lib/executors/gemini-executor.d.ts +6 -0
  23. package/dist/lib/executors/gemini-executor.d.ts.map +1 -0
  24. package/dist/lib/executors/gemini-executor.js +41 -0
  25. package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
  26. package/dist/lib/executors/opencode-executor.js +2 -3
  27. package/dist/lib/prompt-builder.d.ts +8 -0
  28. package/dist/lib/prompt-builder.d.ts.map +1 -1
  29. package/dist/lib/prompt-builder.js +98 -0
  30. package/dist/lib/task-execution.d.ts.map +1 -1
  31. package/dist/lib/task-execution.js +44 -14
  32. package/dist/services/prd.d.ts +2 -0
  33. package/dist/services/prd.d.ts.map +1 -1
  34. package/dist/services/prd.js +4 -4
  35. package/dist/services/tasks.d.ts +10 -1
  36. package/dist/services/tasks.d.ts.map +1 -1
  37. package/dist/services/tasks.js +97 -2
  38. package/package.json +1 -1
@@ -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;;;OAGG;IACH,qBAAqB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC;CA4B3D"}
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 jsonMatch = text.match(/\{[\s\S]*\}/);
13
- if (!jsonMatch) {
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
- const jsonStr = jsonMatch[0];
21
- const parsed = JSON.parse(jsonStr);
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,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"}