task-o-matic 0.0.12 ā 0.0.13
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/tasks/create.d.ts.map +1 -1
- package/dist/commands/tasks/create.js +6 -13
- package/dist/commands/tasks/document/add.d.ts +3 -0
- package/dist/commands/tasks/document/add.d.ts.map +1 -0
- package/dist/commands/tasks/document/add.js +35 -0
- package/dist/commands/tasks/document/analyze.d.ts +3 -0
- package/dist/commands/tasks/document/analyze.d.ts.map +1 -0
- package/dist/commands/tasks/document/analyze.js +49 -0
- package/dist/commands/tasks/document/get.d.ts +3 -0
- package/dist/commands/tasks/document/get.d.ts.map +1 -0
- package/dist/commands/tasks/document/get.js +29 -0
- package/dist/commands/tasks/document/index.d.ts +8 -0
- package/dist/commands/tasks/document/index.d.ts.map +1 -0
- package/dist/commands/tasks/document/index.js +13 -0
- package/dist/commands/tasks/enhance.d.ts.map +1 -1
- package/dist/commands/tasks/enhance.js +64 -61
- package/dist/commands/tasks/execute-loop.d.ts.map +1 -1
- package/dist/commands/tasks/execute-loop.js +64 -90
- package/dist/commands/tasks/execute.d.ts.map +1 -1
- package/dist/commands/tasks/execute.js +52 -16
- package/dist/commands/tasks/plan/create.d.ts +3 -0
- package/dist/commands/tasks/plan/create.d.ts.map +1 -0
- package/dist/commands/tasks/plan/create.js +37 -0
- package/dist/commands/tasks/plan/delete.d.ts +3 -0
- package/dist/commands/tasks/plan/delete.d.ts.map +1 -0
- package/dist/commands/tasks/plan/delete.js +14 -0
- package/dist/commands/tasks/plan/get.d.ts +3 -0
- package/dist/commands/tasks/plan/get.d.ts.map +1 -0
- package/dist/commands/tasks/plan/get.js +24 -0
- package/dist/commands/tasks/plan/index.d.ts +10 -0
- package/dist/commands/tasks/plan/index.d.ts.map +1 -0
- package/dist/commands/tasks/plan/index.js +17 -0
- package/dist/commands/tasks/plan/list.d.ts +3 -0
- package/dist/commands/tasks/plan/list.d.ts.map +1 -0
- package/dist/commands/tasks/plan/list.js +21 -0
- package/dist/commands/tasks/plan/set.d.ts +3 -0
- package/dist/commands/tasks/plan/set.d.ts.map +1 -0
- package/dist/commands/tasks/plan/set.js +33 -0
- package/dist/commands/tasks/split.d.ts.map +1 -1
- package/dist/commands/tasks/split.js +65 -60
- package/dist/lib/git-utils.d.ts +45 -0
- package/dist/lib/git-utils.d.ts.map +1 -0
- package/dist/lib/git-utils.js +160 -0
- package/dist/lib/task-execution-core.d.ts +7 -0
- package/dist/lib/task-execution-core.d.ts.map +1 -0
- package/dist/lib/task-execution-core.js +360 -0
- package/dist/lib/task-execution.d.ts +4 -0
- package/dist/lib/task-execution.d.ts.map +1 -1
- package/dist/lib/task-execution.js +31 -149
- package/dist/lib/task-loop-execution.d.ts +1 -19
- package/dist/lib/task-loop-execution.d.ts.map +1 -1
- package/dist/lib/task-loop-execution.js +50 -585
- package/dist/lib/task-planning.d.ts +28 -0
- package/dist/lib/task-planning.d.ts.map +1 -0
- package/dist/lib/task-planning.js +109 -0
- package/dist/lib/task-review.d.ts +27 -0
- package/dist/lib/task-review.d.ts.map +1 -0
- package/dist/lib/task-review.js +106 -0
- package/dist/lib/validation.d.ts +20 -3
- package/dist/lib/validation.d.ts.map +1 -1
- package/dist/lib/validation.js +39 -10
- package/dist/test/task-loop-git.test.js +6 -6
- package/dist/types/cli-options.d.ts +138 -0
- package/dist/types/cli-options.d.ts.map +1 -0
- package/dist/types/cli-options.js +6 -0
- package/dist/types/index.d.ts +38 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/bulk-operations.d.ts +51 -0
- package/dist/utils/bulk-operations.d.ts.map +1 -0
- package/dist/utils/bulk-operations.js +68 -0
- package/dist/utils/cli-validators.d.ts +54 -0
- package/dist/utils/cli-validators.d.ts.map +1 -0
- package/dist/utils/cli-validators.js +75 -0
- package/dist/utils/command-error-handler.d.ts +32 -0
- package/dist/utils/command-error-handler.d.ts.map +1 -0
- package/dist/utils/command-error-handler.js +52 -0
- package/dist/utils/confirmation.d.ts +19 -0
- package/dist/utils/confirmation.d.ts.map +1 -0
- package/dist/utils/confirmation.js +39 -0
- package/dist/utils/display-helpers.d.ts +81 -0
- package/dist/utils/display-helpers.d.ts.map +1 -0
- package/dist/utils/display-helpers.js +109 -0
- package/dist/utils/model-executor-parser.d.ts +38 -0
- package/dist/utils/model-executor-parser.d.ts.map +1 -0
- package/dist/utils/model-executor-parser.js +67 -0
- package/dist/utils/progress-tracking.d.ts +28 -0
- package/dist/utils/progress-tracking.d.ts.map +1 -0
- package/dist/utils/progress-tracking.js +43 -0
- package/package.json +1 -1
- package/dist/commands/tasks/document.d.ts +0 -5
- package/dist/commands/tasks/document.d.ts.map +0 -1
- package/dist/commands/tasks/document.js +0 -118
- package/dist/commands/tasks/plan.d.ts +0 -7
- package/dist/commands/tasks/plan.d.ts.map +0 -1
- package/dist/commands/tasks/plan.js +0 -131
|
@@ -7,6 +7,8 @@ exports.executeCommand = void 0;
|
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const task_execution_1 = require("../../lib/task-execution");
|
|
10
|
+
const model_executor_parser_1 = require("../../utils/model-executor-parser");
|
|
11
|
+
const command_error_handler_1 = require("../../utils/command-error-handler");
|
|
10
12
|
exports.executeCommand = new commander_1.Command("execute")
|
|
11
13
|
.description("Execute a task using an external coding assistant")
|
|
12
14
|
.requiredOption("--id <id>", "Task ID to execute")
|
|
@@ -15,23 +17,57 @@ exports.executeCommand = new commander_1.Command("execute")
|
|
|
15
17
|
.option("-m, --model <model>", "Model to use with the executor")
|
|
16
18
|
.option("--continue-session", "Continue the last session (for error feedback)", false)
|
|
17
19
|
.option("--dry", "Show what would be executed without running it")
|
|
18
|
-
.option("--validate <command>", "Validation command to run after execution (can be used multiple times)", (value, previous = []) => {
|
|
20
|
+
.option("--validate <command>", "Validation/verification command to run after execution (can be used multiple times)", (value, previous = []) => {
|
|
19
21
|
return [...previous, value];
|
|
20
22
|
})
|
|
21
|
-
.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
.option("--verify <command>", "Alias for --validate (verification command)", (value, previous = []) => {
|
|
24
|
+
return [...previous, value];
|
|
25
|
+
})
|
|
26
|
+
.option("--max-retries <number>", "Maximum number of retries (opt-in, enables retry logic)", (value) => parseInt(value, 10))
|
|
27
|
+
.option("--try-models <models>", "Progressive model/executor configs for retries (e.g., 'gpt-4o-mini,claude:sonnet-4')")
|
|
28
|
+
.option("--plan", "Generate an implementation plan before execution", false)
|
|
29
|
+
.option("--plan-model <model>", "Model/executor to use for planning (e.g., 'opencode:gpt-4o' or 'gpt-4o')")
|
|
30
|
+
.option("--review-plan", "Pause for human review of the plan", false)
|
|
31
|
+
.option("--review", "Run AI review after execution", false)
|
|
32
|
+
.option("--review-model <model>", "Model/executor to use for review (e.g., 'opencode:gpt-4o' or 'gpt-4o')")
|
|
33
|
+
.option("--auto-commit", "Automatically commit changes after execution", false)
|
|
34
|
+
.action((0, command_error_handler_1.wrapCommandHandler)("Task execution", async (options) => {
|
|
35
|
+
// Validate executor tool
|
|
36
|
+
if (!(0, model_executor_parser_1.validateExecutor)(options.tool)) {
|
|
37
|
+
console.error(chalk_1.default.red(`Invalid tool: ${options.tool}. Must be one of: ${model_executor_parser_1.VALID_EXECUTORS.join(", ")}`));
|
|
35
38
|
process.exit(1);
|
|
36
39
|
}
|
|
37
|
-
|
|
40
|
+
// Combine both --validate and --verify options
|
|
41
|
+
const validations = [
|
|
42
|
+
...(options.validate || []),
|
|
43
|
+
...(options.verify || []),
|
|
44
|
+
];
|
|
45
|
+
// Parse tryModels if provided
|
|
46
|
+
let tryModels;
|
|
47
|
+
if (options.tryModels) {
|
|
48
|
+
try {
|
|
49
|
+
tryModels = (0, model_executor_parser_1.parseTryModels)(options.tryModels);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.error(chalk_1.default.red(`Failed to parse --try-models: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
await (0, task_execution_1.executeTask)({
|
|
57
|
+
taskId: options.id,
|
|
58
|
+
tool: options.tool,
|
|
59
|
+
message: options.message,
|
|
60
|
+
model: options.model,
|
|
61
|
+
continueSession: options.continueSession,
|
|
62
|
+
dry: options.dry,
|
|
63
|
+
validate: validations,
|
|
64
|
+
maxRetries: options.maxRetries,
|
|
65
|
+
tryModels,
|
|
66
|
+
plan: options.plan,
|
|
67
|
+
planModel: options.planModel,
|
|
68
|
+
reviewPlan: options.reviewPlan,
|
|
69
|
+
review: options.review,
|
|
70
|
+
reviewModel: options.reviewModel,
|
|
71
|
+
autoCommit: options.autoCommit,
|
|
72
|
+
});
|
|
73
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,WAAW,SAmCnB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
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.planCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const tasks_1 = require("../../../services/tasks");
|
|
10
|
+
const streaming_options_1 = require("../../../utils/streaming-options");
|
|
11
|
+
const plan_1 = require("../../../cli/display/plan");
|
|
12
|
+
const progress_tracking_1 = require("../../../utils/progress-tracking");
|
|
13
|
+
const command_error_handler_1 = require("../../../utils/command-error-handler");
|
|
14
|
+
exports.planCommand = new commander_1.Command("plan")
|
|
15
|
+
.description("Create detailed implementation plan for a task or subtask")
|
|
16
|
+
.requiredOption("--id <id>", "Task or subtask ID to plan")
|
|
17
|
+
.option("--stream", "Show streaming AI output during planning")
|
|
18
|
+
.option("--ai-provider <provider>", "AI provider override")
|
|
19
|
+
.option("--ai-model <model>", "AI model override")
|
|
20
|
+
.option("--ai-key <key>", "AI API key override")
|
|
21
|
+
.option("--ai-provider-url <url>", "AI provider URL override")
|
|
22
|
+
.option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
|
|
23
|
+
.action((0, command_error_handler_1.wrapCommandHandler)("Task planning", async (options) => {
|
|
24
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Planning");
|
|
25
|
+
const result = await (0, progress_tracking_1.withProgressTracking)(async () => {
|
|
26
|
+
return await tasks_1.taskService.planTask(options.id, {
|
|
27
|
+
aiProvider: options.aiProvider,
|
|
28
|
+
aiModel: options.aiModel,
|
|
29
|
+
aiKey: options.aiKey,
|
|
30
|
+
aiProviderUrl: options.aiProviderUrl,
|
|
31
|
+
aiReasoning: options.reasoning,
|
|
32
|
+
}, streamingOptions);
|
|
33
|
+
});
|
|
34
|
+
// Display the plan
|
|
35
|
+
(0, plan_1.displayPlanCreation)(options.id, result.task.title);
|
|
36
|
+
console.log(chalk_1.default.cyan(result.plan));
|
|
37
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,iBAAiB,SAMzB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deletePlanCommand = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const tasks_1 = require("../../../services/tasks");
|
|
6
|
+
const plan_1 = require("../../../cli/display/plan");
|
|
7
|
+
const command_error_handler_1 = require("../../../utils/command-error-handler");
|
|
8
|
+
exports.deletePlanCommand = new commander_1.Command("delete-plan")
|
|
9
|
+
.description("Delete implementation plan for a task")
|
|
10
|
+
.requiredOption("--id <id>", "Task ID")
|
|
11
|
+
.action((0, command_error_handler_1.wrapCommandHandler)("Delete plan", async (options) => {
|
|
12
|
+
const success = await tasks_1.taskService.deleteTaskPlan(options.id);
|
|
13
|
+
(0, plan_1.displayPlanDeletion)(options.id, success);
|
|
14
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,cAAc,SAuBtB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
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.getPlanCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const tasks_1 = require("../../../services/tasks");
|
|
10
|
+
const plan_1 = require("../../../cli/display/plan");
|
|
11
|
+
const command_error_handler_1 = require("../../../utils/command-error-handler");
|
|
12
|
+
exports.getPlanCommand = new commander_1.Command("get-plan")
|
|
13
|
+
.description("View existing implementation plan for a task or subtask")
|
|
14
|
+
.requiredOption("--id <id>", "Task or subtask ID")
|
|
15
|
+
.action((0, command_error_handler_1.wrapCommandHandler)("Get plan", async (options) => {
|
|
16
|
+
const plan = await tasks_1.taskService.getTaskPlan(options.id);
|
|
17
|
+
if (!plan) {
|
|
18
|
+
console.log(chalk_1.default.yellow(`ā ļø No plan found for task/subtask ${options.id}`));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const task = await tasks_1.taskService.getTask(options.id);
|
|
22
|
+
const taskTitle = task ? task.title : options.id;
|
|
23
|
+
(0, plan_1.displayPlanView)(taskTitle, options.id, plan.plan, plan.createdAt, plan.updatedAt);
|
|
24
|
+
}));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan command submodules
|
|
3
|
+
* Each command is in its own file for better organization
|
|
4
|
+
*/
|
|
5
|
+
export { planCommand } from "./create";
|
|
6
|
+
export { getPlanCommand } from "./get";
|
|
7
|
+
export { listPlanCommand } from "./list";
|
|
8
|
+
export { deletePlanCommand } from "./delete";
|
|
9
|
+
export { setPlanCommand } from "./set";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Plan command submodules
|
|
4
|
+
* Each command is in its own file for better organization
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.setPlanCommand = exports.deletePlanCommand = exports.listPlanCommand = exports.getPlanCommand = exports.planCommand = void 0;
|
|
8
|
+
var create_1 = require("./create");
|
|
9
|
+
Object.defineProperty(exports, "planCommand", { enumerable: true, get: function () { return create_1.planCommand; } });
|
|
10
|
+
var get_1 = require("./get");
|
|
11
|
+
Object.defineProperty(exports, "getPlanCommand", { enumerable: true, get: function () { return get_1.getPlanCommand; } });
|
|
12
|
+
var list_1 = require("./list");
|
|
13
|
+
Object.defineProperty(exports, "listPlanCommand", { enumerable: true, get: function () { return list_1.listPlanCommand; } });
|
|
14
|
+
var delete_1 = require("./delete");
|
|
15
|
+
Object.defineProperty(exports, "deletePlanCommand", { enumerable: true, get: function () { return delete_1.deletePlanCommand; } });
|
|
16
|
+
var set_1 = require("./set");
|
|
17
|
+
Object.defineProperty(exports, "setPlanCommand", { enumerable: true, get: function () { return set_1.setPlanCommand; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,eAAe,SAiBvB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listPlanCommand = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const tasks_1 = require("../../../services/tasks");
|
|
6
|
+
const plan_1 = require("../../../cli/display/plan");
|
|
7
|
+
const command_error_handler_1 = require("../../../utils/command-error-handler");
|
|
8
|
+
exports.listPlanCommand = new commander_1.Command("list-plan")
|
|
9
|
+
.description("List all available implementation plans")
|
|
10
|
+
.action((0, command_error_handler_1.wrapCommandHandler)("List plans", async () => {
|
|
11
|
+
const plans = await tasks_1.taskService.listTaskPlans();
|
|
12
|
+
// Get task titles for each plan
|
|
13
|
+
const plansWithTitles = await Promise.all(plans.map(async (plan) => {
|
|
14
|
+
const task = await tasks_1.taskService.getTask(plan.taskId);
|
|
15
|
+
return {
|
|
16
|
+
...plan,
|
|
17
|
+
taskTitle: task ? task.title : plan.taskId,
|
|
18
|
+
};
|
|
19
|
+
}));
|
|
20
|
+
(0, plan_1.displayPlanList)(plansWithTitles);
|
|
21
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,cAAc,SAiCtB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
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.setPlanCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const tasks_1 = require("../../../services/tasks");
|
|
10
|
+
const command_error_handler_1 = require("../../../utils/command-error-handler");
|
|
11
|
+
exports.setPlanCommand = new commander_1.Command("set-plan")
|
|
12
|
+
.description("Set implementation plan for a task")
|
|
13
|
+
.requiredOption("--id <id>", "Task ID")
|
|
14
|
+
.option("--plan <text>", "Plan text (use quotes for multi-line)")
|
|
15
|
+
.option("--plan-file <path>", "Path to file containing the plan")
|
|
16
|
+
.action((0, command_error_handler_1.wrapCommandHandler)("Set plan", async (options) => {
|
|
17
|
+
const task = await tasks_1.taskService.getTask(options.id);
|
|
18
|
+
if (!task) {
|
|
19
|
+
throw new Error(`Task with ID ${options.id} not found`);
|
|
20
|
+
}
|
|
21
|
+
if (!options.plan && !options.planFile) {
|
|
22
|
+
throw new Error("Either --plan or --plan-file must be specified");
|
|
23
|
+
}
|
|
24
|
+
if (options.plan && options.planFile) {
|
|
25
|
+
throw new Error("Cannot specify both --plan and --plan-file");
|
|
26
|
+
}
|
|
27
|
+
const result = await tasks_1.taskService.setTaskPlan(options.id, options.plan || undefined, options.planFile || undefined);
|
|
28
|
+
console.log(chalk_1.default.green(`ā Plan set for task: ${task.title} (${options.id})`));
|
|
29
|
+
console.log(chalk_1.default.gray(` Plan file: ${result.planFile}`));
|
|
30
|
+
if (options.planFile) {
|
|
31
|
+
console.log(chalk_1.default.gray(` Source file: ${options.planFile}`));
|
|
32
|
+
}
|
|
33
|
+
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/split.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/split.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,YAAY,SAsHpB,CAAC"}
|
|
@@ -7,14 +7,21 @@ exports.splitCommand = void 0;
|
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const tasks_1 = require("../../services/tasks");
|
|
10
|
-
const hooks_1 = require("../../lib/hooks");
|
|
11
10
|
const streaming_options_1 = require("../../utils/streaming-options");
|
|
12
|
-
const progress_1 = require("../../cli/display/progress");
|
|
13
11
|
const task_1 = require("../../cli/display/task");
|
|
12
|
+
const progress_tracking_1 = require("../../utils/progress-tracking");
|
|
13
|
+
const cli_validators_1 = require("../../utils/cli-validators");
|
|
14
|
+
const bulk_operations_1 = require("../../utils/bulk-operations");
|
|
15
|
+
const confirmation_1 = require("../../utils/confirmation");
|
|
16
|
+
const command_error_handler_1 = require("../../utils/command-error-handler");
|
|
14
17
|
exports.splitCommand = new commander_1.Command("split")
|
|
15
18
|
.description("Split a task into smaller subtasks using AI")
|
|
16
19
|
.option("--task-id <id>", "Task ID to split")
|
|
17
20
|
.option("--all", "Split all existing tasks that don't have subtasks")
|
|
21
|
+
.option("--status <status>", "Filter tasks by status (todo/in-progress/completed)")
|
|
22
|
+
.option("--tag <tag>", "Filter tasks by tag")
|
|
23
|
+
.option("--dry", "Preview what would be split without making changes")
|
|
24
|
+
.option("--force", "Skip confirmation prompt for bulk operations")
|
|
18
25
|
.option("--stream", "Show streaming AI output during breakdown")
|
|
19
26
|
.option("--ai-provider <provider>", "AI provider override")
|
|
20
27
|
.option("--ai-model <model>", "AI model override")
|
|
@@ -22,74 +29,72 @@ exports.splitCommand = new commander_1.Command("split")
|
|
|
22
29
|
.option("--ai-provider-url <url>", "AI provider URL override")
|
|
23
30
|
.option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
|
|
24
31
|
.option("--tools", "Enable filesystem tools for project analysis")
|
|
25
|
-
.action(async (options) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
.action((0, command_error_handler_1.wrapCommandHandler)("Task splitting", async (options) => {
|
|
33
|
+
// Validate mutual exclusivity (only if no filters provided)
|
|
34
|
+
if (!options.status && !options.tag) {
|
|
35
|
+
(0, cli_validators_1.validateMutuallyExclusive)(options, "taskId", "all", "task-id", "all");
|
|
36
|
+
}
|
|
37
|
+
const splitSingleTask = async (taskId) => {
|
|
38
|
+
if (options.dry) {
|
|
39
|
+
const task = await tasks_1.taskService.getTask(taskId);
|
|
40
|
+
console.log(chalk_1.default.blue(`[DRY RUN] Would split: ${task?.title || taskId}`));
|
|
41
|
+
return;
|
|
32
42
|
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
(
|
|
37
|
-
};
|
|
38
|
-
hooks_1.hooks.on("task:progress", progressHandler);
|
|
39
|
-
try {
|
|
40
|
-
const result = await tasks_1.taskService.splitTask(taskId, {
|
|
43
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Task breakdown");
|
|
44
|
+
try {
|
|
45
|
+
const result = await (0, progress_tracking_1.withProgressTracking)(async () => {
|
|
46
|
+
return await tasks_1.taskService.splitTask(taskId, {
|
|
41
47
|
aiProvider: options.aiProvider,
|
|
42
48
|
aiModel: options.aiModel,
|
|
43
49
|
aiKey: options.aiKey,
|
|
44
50
|
aiProviderUrl: options.aiProviderUrl,
|
|
45
51
|
aiReasoning: options.reasoning,
|
|
46
52
|
}, undefined, undefined, streamingOptions, options.tools);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
catch (error) {
|
|
58
|
-
if (error instanceof Error && error.message.includes("already has")) {
|
|
59
|
-
console.log(chalk_1.default.yellow(`ā ļø ${error.message}`));
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
throw error;
|
|
63
|
-
}
|
|
64
|
-
finally {
|
|
65
|
-
hooks_1.hooks.off("task:progress", progressHandler);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
if (options.taskId) {
|
|
69
|
-
await splitSingleTask(options.taskId);
|
|
53
|
+
});
|
|
54
|
+
(0, task_1.displaySubtaskCreation)(result.subtasks);
|
|
55
|
+
// Display AI metadata
|
|
56
|
+
console.log(chalk_1.default.gray(`\nš AI Splitting Details:`));
|
|
57
|
+
console.log(chalk_1.default.gray(` Provider: ${result.metadata.aiProvider}`));
|
|
58
|
+
console.log(chalk_1.default.gray(` Model: ${result.metadata.aiModel}`));
|
|
59
|
+
console.log(chalk_1.default.gray(` Subtasks created: ${result.subtasks.length}`));
|
|
60
|
+
console.log(chalk_1.default.gray(` Confidence: ${result.metadata.confidence
|
|
61
|
+
? (result.metadata.confidence * 100).toFixed(1)
|
|
62
|
+
: "N/A"}%`));
|
|
70
63
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
console.log(chalk_1.default.yellow("No tasks found to split."));
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error instanceof Error && error.message.includes("already has")) {
|
|
66
|
+
console.log(chalk_1.default.yellow(`ā ļø ${error.message}`));
|
|
75
67
|
return;
|
|
76
68
|
}
|
|
77
|
-
|
|
78
|
-
for (let i = 0; i < allTasks.length; i++) {
|
|
79
|
-
const task = allTasks[i];
|
|
80
|
-
console.log(chalk_1.default.cyan(`\n[${i + 1}/${allTasks.length}] Splitting: ${task.title}`));
|
|
81
|
-
try {
|
|
82
|
-
await splitSingleTask(task.id);
|
|
83
|
-
}
|
|
84
|
-
catch (error) {
|
|
85
|
-
console.log(chalk_1.default.red(`ā Failed to split task ${task.id}: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
console.log(chalk_1.default.green(`\nā Bulk splitting complete! Processed ${allTasks.length} tasks.`));
|
|
69
|
+
throw error;
|
|
89
70
|
}
|
|
71
|
+
};
|
|
72
|
+
if (options.taskId) {
|
|
73
|
+
await splitSingleTask(options.taskId);
|
|
90
74
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
75
|
+
else {
|
|
76
|
+
// Build filters for bulk operation
|
|
77
|
+
const filters = {};
|
|
78
|
+
if (options.status)
|
|
79
|
+
filters.status = options.status;
|
|
80
|
+
if (options.tag)
|
|
81
|
+
filters.tag = options.tag;
|
|
82
|
+
// Get task count for confirmation
|
|
83
|
+
const tasks = await tasks_1.taskService.listTasks(filters);
|
|
84
|
+
if (tasks.length === 0) {
|
|
85
|
+
console.log(chalk_1.default.yellow("No tasks found matching the filters"));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Confirm bulk operation
|
|
89
|
+
const confirmed = await (0, confirmation_1.confirmBulkOperation)("split", tasks.length, options.force);
|
|
90
|
+
if (!confirmed) {
|
|
91
|
+
console.log(chalk_1.default.yellow("Operation cancelled"));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
await (0, bulk_operations_1.executeBulkOperation)((taskId) => splitSingleTask(taskId), {
|
|
95
|
+
operationName: "Splitting",
|
|
96
|
+
operationEmoji: "š§",
|
|
97
|
+
filters,
|
|
98
|
+
});
|
|
94
99
|
}
|
|
95
|
-
});
|
|
100
|
+
}));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git state captured before and after execution
|
|
3
|
+
*/
|
|
4
|
+
export interface GitState {
|
|
5
|
+
beforeHead: string;
|
|
6
|
+
afterHead: string;
|
|
7
|
+
hasUncommittedChanges: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Commit information extracted from git state
|
|
11
|
+
*/
|
|
12
|
+
export interface CommitInfo {
|
|
13
|
+
message: string;
|
|
14
|
+
files: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Capture git state (HEAD commit and uncommitted changes)
|
|
18
|
+
*/
|
|
19
|
+
export declare function captureGitState(execFn?: (command: string) => Promise<{
|
|
20
|
+
stdout: string;
|
|
21
|
+
stderr: string;
|
|
22
|
+
}>): Promise<Partial<GitState>>;
|
|
23
|
+
/**
|
|
24
|
+
* Extract commit message and file list from git state
|
|
25
|
+
* This function analyzes the actual git state to generate appropriate commit info
|
|
26
|
+
*/
|
|
27
|
+
export declare function extractCommitInfo(taskId: string, taskTitle: string, executionMessage: string, gitState: GitState, execFn?: (command: string) => Promise<{
|
|
28
|
+
stdout: string;
|
|
29
|
+
stderr: string;
|
|
30
|
+
}>, aiOps?: any): Promise<CommitInfo>;
|
|
31
|
+
/**
|
|
32
|
+
* Auto-commit changes using the provided commit info
|
|
33
|
+
*/
|
|
34
|
+
export declare function autoCommit(commitInfo: CommitInfo, execFn?: (command: string) => Promise<{
|
|
35
|
+
stdout: string;
|
|
36
|
+
stderr: string;
|
|
37
|
+
}>): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Commit a specific file with a custom message
|
|
40
|
+
*/
|
|
41
|
+
export declare function commitFile(filePath: string, message: string, execFn?: (command: string) => Promise<{
|
|
42
|
+
stdout: string;
|
|
43
|
+
stderr: string;
|
|
44
|
+
}>): Promise<void>;
|
|
45
|
+
//# sourceMappingURL=git-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/lib/git-utils.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAc5B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,EAClB,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,EAC5D,KAAK,GAAE,GAAuB,GAC7B,OAAO,CAAC,UAAU,CAAC,CA6GrB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,UAAU,EACtB,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,IAAI,CAAC,CAef"}
|