task-o-matic 0.0.13 → 0.0.15

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 (144) hide show
  1. package/dist/cli/display/progress.d.ts +15 -2
  2. package/dist/cli/display/progress.d.ts.map +1 -1
  3. package/dist/cli/display/progress.js +72 -4
  4. package/dist/commands/benchmark.d.ts.map +1 -1
  5. package/dist/commands/benchmark.js +11 -3
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +60 -12
  8. package/dist/commands/prd.js +7 -1
  9. package/dist/commands/tasks/delete.d.ts.map +1 -1
  10. package/dist/commands/tasks/delete.js +2 -1
  11. package/dist/commands/tasks/document/add.d.ts.map +1 -1
  12. package/dist/commands/tasks/document/add.js +5 -4
  13. package/dist/commands/tasks/document/get.d.ts.map +1 -1
  14. package/dist/commands/tasks/document/get.js +2 -1
  15. package/dist/commands/tasks/list.js +2 -2
  16. package/dist/commands/tasks/next.js +4 -4
  17. package/dist/commands/tasks/plan/set.d.ts.map +1 -1
  18. package/dist/commands/tasks/plan/set.js +11 -3
  19. package/dist/commands/tasks/show.d.ts.map +1 -1
  20. package/dist/commands/tasks/show.js +2 -1
  21. package/dist/commands/tasks/status.d.ts.map +1 -1
  22. package/dist/commands/tasks/status.js +4 -3
  23. package/dist/commands/tasks/update.d.ts.map +1 -1
  24. package/dist/commands/tasks/update.js +7 -1
  25. package/dist/lib/ai-service/ai-operations.d.ts +1 -1
  26. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
  27. package/dist/lib/ai-service/base-operations.d.ts +22 -0
  28. package/dist/lib/ai-service/base-operations.d.ts.map +1 -1
  29. package/dist/lib/ai-service/base-operations.js +29 -1
  30. package/dist/lib/ai-service/model-provider.d.ts.map +1 -1
  31. package/dist/lib/ai-service/model-provider.js +37 -6
  32. package/dist/lib/ai-service/task-operations.d.ts +2 -1
  33. package/dist/lib/ai-service/task-operations.d.ts.map +1 -1
  34. package/dist/lib/ai-service/task-operations.js +135 -173
  35. package/dist/lib/benchmark/registry.d.ts.map +1 -1
  36. package/dist/lib/benchmark/registry.js +6 -10
  37. package/dist/lib/better-t-stack-cli.d.ts +36 -21
  38. package/dist/lib/better-t-stack-cli.d.ts.map +1 -1
  39. package/dist/lib/better-t-stack-cli.js +212 -33
  40. package/dist/lib/bootstrap/cli-bootstrap.d.ts +14 -0
  41. package/dist/lib/bootstrap/cli-bootstrap.d.ts.map +1 -0
  42. package/dist/lib/bootstrap/cli-bootstrap.js +325 -0
  43. package/dist/lib/bootstrap/index.d.ts +4 -0
  44. package/dist/lib/bootstrap/index.d.ts.map +1 -0
  45. package/dist/lib/bootstrap/index.js +19 -0
  46. package/dist/lib/bootstrap/medusa-bootstrap.d.ts +14 -0
  47. package/dist/lib/bootstrap/medusa-bootstrap.d.ts.map +1 -0
  48. package/dist/lib/bootstrap/medusa-bootstrap.js +218 -0
  49. package/dist/lib/bootstrap/opentui-bootstrap.d.ts +11 -0
  50. package/dist/lib/bootstrap/opentui-bootstrap.d.ts.map +1 -0
  51. package/dist/lib/bootstrap/opentui-bootstrap.js +342 -0
  52. package/dist/lib/config-validation.d.ts +215 -0
  53. package/dist/lib/config-validation.d.ts.map +1 -0
  54. package/dist/lib/config-validation.js +246 -0
  55. package/dist/lib/config.d.ts +14 -0
  56. package/dist/lib/config.d.ts.map +1 -1
  57. package/dist/lib/config.js +37 -5
  58. package/dist/lib/storage/file-system.d.ts.map +1 -1
  59. package/dist/lib/storage/file-system.js +81 -21
  60. package/dist/lib/task-execution-core.d.ts.map +1 -1
  61. package/dist/lib/task-execution-core.js +3 -2
  62. package/dist/services/prd.d.ts +17 -0
  63. package/dist/services/prd.d.ts.map +1 -1
  64. package/dist/services/prd.js +67 -60
  65. package/dist/services/tasks.d.ts +317 -3
  66. package/dist/services/tasks.d.ts.map +1 -1
  67. package/dist/services/tasks.js +531 -185
  68. package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
  69. package/dist/services/workflow-ai-assistant.js +19 -6
  70. package/dist/test/lib/ai-service/task-operations.test.d.ts +2 -0
  71. package/dist/test/lib/ai-service/task-operations.test.d.ts.map +1 -0
  72. package/dist/test/lib/ai-service/task-operations.test.js +362 -0
  73. package/dist/test/mocks/mock-ai-operations.d.ts +15 -0
  74. package/dist/test/mocks/mock-ai-operations.d.ts.map +1 -0
  75. package/dist/test/mocks/mock-ai-operations.js +107 -0
  76. package/dist/test/mocks/mock-context-builder.d.ts +10 -0
  77. package/dist/test/mocks/mock-context-builder.d.ts.map +1 -0
  78. package/dist/test/mocks/mock-context-builder.js +81 -0
  79. package/dist/test/mocks/mock-model-provider.d.ts +7 -0
  80. package/dist/test/mocks/mock-model-provider.d.ts.map +1 -0
  81. package/dist/test/mocks/mock-model-provider.js +21 -0
  82. package/dist/test/mocks/mock-service-factory.d.ts +11 -0
  83. package/dist/test/mocks/mock-service-factory.d.ts.map +1 -0
  84. package/dist/test/mocks/mock-service-factory.js +61 -0
  85. package/dist/test/mocks/mock-storage.d.ts +50 -0
  86. package/dist/test/mocks/mock-storage.d.ts.map +1 -0
  87. package/dist/test/mocks/mock-storage.js +145 -0
  88. package/dist/test/services/task-service.test.d.ts +2 -0
  89. package/dist/test/services/task-service.test.d.ts.map +1 -0
  90. package/dist/test/services/task-service.test.js +352 -0
  91. package/dist/test/test-mock-setup.d.ts +26 -0
  92. package/dist/test/test-mock-setup.d.ts.map +1 -0
  93. package/dist/test/test-mock-setup.js +41 -0
  94. package/dist/test/test-setup.d.ts +9 -0
  95. package/dist/test/test-setup.d.ts.map +1 -0
  96. package/dist/test/test-setup.js +44 -0
  97. package/dist/test/test-utils.d.ts +22 -0
  98. package/dist/test/test-utils.d.ts.map +1 -0
  99. package/dist/test/test-utils.js +37 -0
  100. package/dist/test/utils/ai-operation-utility.test.d.ts +2 -0
  101. package/dist/test/utils/ai-operation-utility.test.d.ts.map +1 -0
  102. package/dist/test/utils/ai-operation-utility.test.js +290 -0
  103. package/dist/test/utils/error-handling.test.d.ts +2 -0
  104. package/dist/test/utils/error-handling.test.d.ts.map +1 -0
  105. package/dist/test/utils/error-handling.test.js +231 -0
  106. package/dist/types/index.d.ts +36 -1
  107. package/dist/types/index.d.ts.map +1 -1
  108. package/dist/types/results.d.ts +60 -6
  109. package/dist/types/results.d.ts.map +1 -1
  110. package/dist/utils/ai-operation-utility.d.ts +142 -0
  111. package/dist/utils/ai-operation-utility.d.ts.map +1 -0
  112. package/dist/utils/ai-operation-utility.js +288 -0
  113. package/dist/utils/ai-service-factory.d.ts +10 -0
  114. package/dist/utils/ai-service-factory.d.ts.map +1 -1
  115. package/dist/utils/ai-service-factory.js +19 -1
  116. package/dist/utils/cli-validators.d.ts +2 -2
  117. package/dist/utils/cli-validators.d.ts.map +1 -1
  118. package/dist/utils/cli-validators.js +7 -6
  119. package/dist/utils/error-utils.d.ts +70 -0
  120. package/dist/utils/error-utils.d.ts.map +1 -0
  121. package/dist/utils/error-utils.js +104 -0
  122. package/dist/utils/file-utils.d.ts +49 -0
  123. package/dist/utils/file-utils.d.ts.map +1 -0
  124. package/dist/utils/file-utils.js +82 -0
  125. package/dist/utils/id-generator.d.ts +92 -0
  126. package/dist/utils/id-generator.d.ts.map +1 -0
  127. package/dist/utils/id-generator.js +146 -0
  128. package/dist/utils/model-executor-parser.d.ts +1 -1
  129. package/dist/utils/model-executor-parser.d.ts.map +1 -1
  130. package/dist/utils/model-executor-parser.js +3 -2
  131. package/dist/utils/stack-formatter.d.ts +2 -1
  132. package/dist/utils/stack-formatter.d.ts.map +1 -1
  133. package/dist/utils/stack-formatter.js +8 -2
  134. package/dist/utils/storage-utils.d.ts +49 -0
  135. package/dist/utils/storage-utils.d.ts.map +1 -0
  136. package/dist/utils/storage-utils.js +80 -0
  137. package/dist/utils/streaming-utils.d.ts +38 -0
  138. package/dist/utils/streaming-utils.d.ts.map +1 -0
  139. package/dist/utils/streaming-utils.js +56 -0
  140. package/dist/utils/task-o-matic-error.d.ts +206 -0
  141. package/dist/utils/task-o-matic-error.d.ts.map +1 -0
  142. package/dist/utils/task-o-matic-error.js +304 -0
  143. package/docs/agents/cli.md +58 -149
  144. package/package.json +2 -2
@@ -0,0 +1,352 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const assert = __importStar(require("assert"));
37
+ const tasks_1 = require("../../services/tasks");
38
+ const test_utils_1 = require("../test-utils");
39
+ const test_mock_setup_1 = require("../test-mock-setup");
40
+ describe("TaskService", () => {
41
+ let taskService;
42
+ beforeEach(() => {
43
+ // Reset mocks to ensure clean state for each test
44
+ (0, test_mock_setup_1.resetMocks)();
45
+ // Create a new TaskService instance
46
+ taskService = new tasks_1.TaskService();
47
+ });
48
+ describe("createTask", () => {
49
+ it("should create a basic task without AI enhancement", async () => {
50
+ const taskData = (0, test_utils_1.createTestTaskData)();
51
+ const result = await taskService.createTask({
52
+ title: taskData.title,
53
+ content: taskData.description,
54
+ effort: taskData.effort,
55
+ });
56
+ assert.strictEqual(result.success, true);
57
+ assert.ok(result.task);
58
+ assert.strictEqual(result.task.title, taskData.title);
59
+ assert.strictEqual(result.task.description, taskData.description);
60
+ assert.strictEqual(result.task.status, "todo");
61
+ assert.strictEqual(result.task.estimatedEffort, taskData.effort);
62
+ });
63
+ it("should create a task with AI enhancement", async () => {
64
+ const taskData = (0, test_utils_1.createTestTaskData)();
65
+ const result = await taskService.createTask({
66
+ title: taskData.title,
67
+ content: taskData.description,
68
+ effort: taskData.effort,
69
+ aiEnhance: true,
70
+ });
71
+ assert.strictEqual(result.success, true);
72
+ assert.ok(result.task);
73
+ assert.strictEqual(result.task.title, taskData.title);
74
+ // Check that the content field (not description) has the AI enhancement
75
+ assert.ok((result.task.content || "").includes("🤖 Enhanced with AI documentation"));
76
+ assert.ok(result.aiMetadata);
77
+ assert.strictEqual(result.aiMetadata?.aiGenerated, true);
78
+ });
79
+ it("should handle context building failures gracefully", async () => {
80
+ const taskData = (0, test_utils_1.createTestTaskData)();
81
+ // The mock context builder will work normally, but we test that
82
+ // the task creation is resilient to potential context building issues
83
+ const result = await taskService.createTask({
84
+ title: taskData.title,
85
+ content: taskData.description,
86
+ effort: taskData.effort,
87
+ aiEnhance: true,
88
+ });
89
+ assert.strictEqual(result.success, true);
90
+ assert.ok(result.task);
91
+ assert.strictEqual(result.task.title, taskData.title);
92
+ });
93
+ });
94
+ describe("updateTask", () => {
95
+ it("should update task properties", async () => {
96
+ // Create a task first
97
+ const taskData = (0, test_utils_1.createTestTaskData)();
98
+ const createResult = await taskService.createTask({
99
+ title: taskData.title,
100
+ content: taskData.description,
101
+ });
102
+ const taskId = createResult.task.id;
103
+ // Update the task
104
+ const updatedTask = await taskService.updateTask(taskId, {
105
+ title: "Updated Title",
106
+ status: "in-progress",
107
+ tags: ["urgent", "important"],
108
+ });
109
+ assert.strictEqual(updatedTask.title, "Updated Title");
110
+ assert.strictEqual(updatedTask.status, "in-progress");
111
+ assert.deepStrictEqual(updatedTask.tags, ["urgent", "important"]);
112
+ });
113
+ it("should validate status transitions", async () => {
114
+ // Create a task
115
+ const taskData = (0, test_utils_1.createTestTaskData)();
116
+ const createResult = await taskService.createTask({
117
+ title: taskData.title,
118
+ });
119
+ const taskId = createResult.task.id;
120
+ // Valid transition: todo -> completed is allowed
121
+ const updatedTask = await taskService.updateTask(taskId, {
122
+ status: "completed",
123
+ });
124
+ assert.strictEqual(updatedTask.status, "completed");
125
+ // Now test an invalid transition: completed -> completed (same status should not error, but let's test a truly invalid one)
126
+ // Actually, looking at the valid transitions, all transitions are allowed from any status
127
+ // So let's test that valid transitions work
128
+ await taskService.updateTask(taskId, {
129
+ status: "in-progress",
130
+ });
131
+ const task = await taskService.getTask(taskId);
132
+ assert.strictEqual(task?.status, "in-progress");
133
+ });
134
+ it("should handle string tags and convert to array", async () => {
135
+ // Create a task
136
+ const taskData = (0, test_utils_1.createTestTaskData)();
137
+ const createResult = await taskService.createTask({
138
+ title: taskData.title,
139
+ });
140
+ const taskId = createResult.task.id;
141
+ // Update with string tags
142
+ const updatedTask = await taskService.updateTask(taskId, {
143
+ tags: "urgent, important, bugfix",
144
+ });
145
+ assert.deepStrictEqual(updatedTask.tags, [
146
+ "urgent",
147
+ "important",
148
+ "bugfix",
149
+ ]);
150
+ });
151
+ });
152
+ describe("deleteTask", () => {
153
+ it("should delete a task successfully", async () => {
154
+ // Create a task
155
+ const taskData = (0, test_utils_1.createTestTaskData)();
156
+ const createResult = await taskService.createTask({
157
+ title: taskData.title,
158
+ });
159
+ const taskId = createResult.task.id;
160
+ // Delete the task
161
+ const deleteResult = await taskService.deleteTask(taskId);
162
+ assert.strictEqual(deleteResult.success, true);
163
+ assert.strictEqual(deleteResult.deleted.length, 1);
164
+ assert.strictEqual(deleteResult.deleted[0].id, taskId);
165
+ // Verify task is gone
166
+ const deletedTask = await taskService.getTask(taskId);
167
+ assert.strictEqual(deletedTask, null);
168
+ });
169
+ it("should handle cascade deletion of subtasks", async () => {
170
+ // Create parent task
171
+ const parentResult = await taskService.createTask({
172
+ title: "Parent Task",
173
+ });
174
+ const parentId = parentResult.task.id;
175
+ // Create subtasks
176
+ const subtask1 = await taskService.createTask({
177
+ title: "Subtask 1",
178
+ parentId: parentId,
179
+ });
180
+ const subtask2 = await taskService.createTask({
181
+ title: "Subtask 2",
182
+ parentId: parentId,
183
+ });
184
+ // Delete parent with cascade
185
+ const deleteResult = await taskService.deleteTask(parentId, {
186
+ cascade: true,
187
+ });
188
+ assert.strictEqual(deleteResult.success, true);
189
+ assert.strictEqual(deleteResult.deleted.length, 3); // parent + 2 subtasks
190
+ });
191
+ it("should throw error when task has subtasks and no cascade/force", async () => {
192
+ // Create parent task
193
+ const parentResult = await taskService.createTask({
194
+ title: "Parent Task",
195
+ });
196
+ const parentId = parentResult.task.id;
197
+ // Create subtask
198
+ await taskService.createTask({
199
+ title: "Subtask 1",
200
+ parentId: parentId,
201
+ });
202
+ // Try to delete without cascade or force
203
+ await assert.rejects(async () => {
204
+ await taskService.deleteTask(parentId);
205
+ }, (err) => {
206
+ assert.ok(err.message.includes("subtasks"));
207
+ return true;
208
+ });
209
+ });
210
+ });
211
+ describe("listTasks", () => {
212
+ it("should list all top-level tasks", async () => {
213
+ // Create some tasks
214
+ await taskService.createTask({ title: "Task 1" });
215
+ await taskService.createTask({ title: "Task 2" });
216
+ await taskService.createTask({ title: "Task 3" });
217
+ const tasks = await taskService.listTasks({});
218
+ assert.strictEqual(tasks.length, 3);
219
+ assert.ok(tasks.every((task) => !task.parentId));
220
+ });
221
+ it("should filter tasks by status", async () => {
222
+ // Create tasks with different statuses
223
+ const task1 = await taskService.createTask({ title: "Task 1" });
224
+ await taskService.updateTask(task1.task.id, { status: "in-progress" });
225
+ const task2 = await taskService.createTask({ title: "Task 2" });
226
+ await taskService.updateTask(task2.task.id, { status: "completed" });
227
+ const task3 = await taskService.createTask({ title: "Task 3" });
228
+ const inProgressTasks = await taskService.listTasks({
229
+ status: "in-progress",
230
+ });
231
+ const completedTasks = await taskService.listTasks({
232
+ status: "completed",
233
+ });
234
+ assert.strictEqual(inProgressTasks.length, 1);
235
+ assert.strictEqual(completedTasks.length, 1);
236
+ });
237
+ it("should filter tasks by tag", async () => {
238
+ // Create tasks with different tags
239
+ const task1 = await taskService.createTask({ title: "Task 1" });
240
+ await taskService.updateTask(task1.task.id, {
241
+ tags: ["frontend", "urgent"],
242
+ });
243
+ const task2 = await taskService.createTask({ title: "Task 2" });
244
+ await taskService.updateTask(task2.task.id, { tags: ["backend"] });
245
+ const task3 = await taskService.createTask({ title: "Task 3" });
246
+ const frontendTasks = await taskService.listTasks({ tag: "frontend" });
247
+ const backendTasks = await taskService.listTasks({ tag: "backend" });
248
+ assert.strictEqual(frontendTasks.length, 1);
249
+ assert.strictEqual(backendTasks.length, 1);
250
+ });
251
+ });
252
+ describe("getTaskTree", () => {
253
+ it("should return task tree for specific task", async () => {
254
+ // Create parent task
255
+ const parentResult = await taskService.createTask({
256
+ title: "Parent Task",
257
+ });
258
+ const parentId = parentResult.task.id;
259
+ // Create subtasks
260
+ const subtask1 = await taskService.createTask({
261
+ title: "Subtask 1",
262
+ parentId: parentId,
263
+ });
264
+ const subtask2 = await taskService.createTask({
265
+ title: "Subtask 2",
266
+ parentId: parentId,
267
+ });
268
+ // Create sub-subtask
269
+ const subSubtask = await taskService.createTask({
270
+ title: "Sub-Subtask 1",
271
+ parentId: subtask1.task.id,
272
+ });
273
+ const tree = await taskService.getTaskTree(parentId);
274
+ assert.strictEqual(tree.length, 4); // parent + 2 subtasks + 1 sub-subtask
275
+ assert.strictEqual(tree[0].id, parentId);
276
+ });
277
+ it("should return all tasks when no rootId provided", async () => {
278
+ // Create some tasks
279
+ await taskService.createTask({ title: "Task 1" });
280
+ await taskService.createTask({ title: "Task 2" });
281
+ await taskService.createTask({ title: "Task 3" });
282
+ const allTasks = await taskService.getTaskTree();
283
+ assert.strictEqual(allTasks.length, 3);
284
+ });
285
+ });
286
+ describe("enhanceTask", () => {
287
+ it("should enhance task with AI documentation", async () => {
288
+ // Create a task
289
+ const taskData = (0, test_utils_1.createTestTaskData)();
290
+ const createResult = await taskService.createTask({
291
+ title: taskData.title,
292
+ content: taskData.description,
293
+ });
294
+ const taskId = createResult.task.id;
295
+ // Enhance the task
296
+ const enhanceResult = await taskService.enhanceTask(taskId);
297
+ assert.strictEqual(enhanceResult.success, true);
298
+ assert.ok(enhanceResult.enhancedContent);
299
+ assert.ok(enhanceResult.enhancedContent.includes("🤖 Enhanced with AI documentation"));
300
+ assert.ok(enhanceResult.stats);
301
+ assert.ok(enhanceResult.metadata);
302
+ });
303
+ it("should throw error for non-existent task", async () => {
304
+ await assert.rejects(async () => {
305
+ await taskService.enhanceTask("non-existent-id");
306
+ }, (err) => {
307
+ assert.ok(err.message.includes("not found"));
308
+ return true;
309
+ });
310
+ });
311
+ });
312
+ describe("splitTask", () => {
313
+ it("should split task into subtasks", async () => {
314
+ // Create a task
315
+ const taskData = (0, test_utils_1.createTestTaskData)();
316
+ const createResult = await taskService.createTask({
317
+ title: taskData.title,
318
+ content: taskData.description,
319
+ });
320
+ const taskId = createResult.task.id;
321
+ // Split the task
322
+ const splitResult = await taskService.splitTask(taskId);
323
+ assert.strictEqual(splitResult.success, true);
324
+ assert.strictEqual(splitResult.subtasks.length, 2);
325
+ assert.ok(splitResult.stats);
326
+ assert.ok(splitResult.metadata);
327
+ // Verify subtasks were created
328
+ const subtasks = await taskService.getSubtasks(taskId);
329
+ assert.strictEqual(subtasks.length, 2);
330
+ });
331
+ it("should throw error if task already has subtasks", async () => {
332
+ // Create a task
333
+ const taskData = (0, test_utils_1.createTestTaskData)();
334
+ const createResult = await taskService.createTask({
335
+ title: taskData.title,
336
+ });
337
+ const taskId = createResult.task.id;
338
+ // Create a subtask
339
+ await taskService.createTask({
340
+ title: "Existing Subtask",
341
+ parentId: taskId,
342
+ });
343
+ // Try to split task that already has subtasks
344
+ await assert.rejects(async () => {
345
+ await taskService.splitTask(taskId);
346
+ }, (err) => {
347
+ assert.ok(err.message.includes("already has"));
348
+ return true;
349
+ });
350
+ });
351
+ });
352
+ });
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Test Mock Setup - Provides mock instances for ai-service-factory
3
+ * Uses the injectTestInstances function to inject mocks
4
+ */
5
+ import { MockStorage } from "./mocks/mock-storage";
6
+ import { MockAIOperations } from "./mocks/mock-ai-operations";
7
+ import { MockModelProvider } from "./mocks/mock-model-provider";
8
+ import { MockContextBuilder } from "./mocks/mock-context-builder";
9
+ export declare let mockStorage: MockStorage;
10
+ export declare let mockAIOperations: MockAIOperations;
11
+ export declare let mockModelProvider: MockModelProvider;
12
+ export declare let mockContextBuilder: MockContextBuilder;
13
+ /**
14
+ * Initialize fresh mock instances and inject them into the service factory
15
+ */
16
+ export declare function resetMocks(): void;
17
+ /**
18
+ * Get current mock instances for test assertions
19
+ */
20
+ export declare function getMocks(): {
21
+ storage: MockStorage;
22
+ aiOperations: MockAIOperations;
23
+ modelProvider: MockModelProvider;
24
+ contextBuilder: MockContextBuilder;
25
+ };
26
+ //# sourceMappingURL=test-mock-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-mock-setup.d.ts","sourceRoot":"","sources":["../../src/test/test-mock-setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAIlE,eAAO,IAAI,WAAW,EAAE,WAAW,CAAC;AACpC,eAAO,IAAI,gBAAgB,EAAE,gBAAgB,CAAC;AAC9C,eAAO,IAAI,iBAAiB,EAAE,iBAAiB,CAAC;AAChD,eAAO,IAAI,kBAAkB,EAAE,kBAAkB,CAAC;AAElD;;GAEG;AACH,wBAAgB,UAAU,SAazB;AAED;;GAEG;AACH,wBAAgB,QAAQ;;;;;EAOvB"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * Test Mock Setup - Provides mock instances for ai-service-factory
4
+ * Uses the injectTestInstances function to inject mocks
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.mockContextBuilder = exports.mockModelProvider = exports.mockAIOperations = exports.mockStorage = void 0;
8
+ exports.resetMocks = resetMocks;
9
+ exports.getMocks = getMocks;
10
+ const mock_storage_1 = require("./mocks/mock-storage");
11
+ const mock_ai_operations_1 = require("./mocks/mock-ai-operations");
12
+ const mock_model_provider_1 = require("./mocks/mock-model-provider");
13
+ const mock_context_builder_1 = require("./mocks/mock-context-builder");
14
+ const ai_service_factory_1 = require("../utils/ai-service-factory");
15
+ /**
16
+ * Initialize fresh mock instances and inject them into the service factory
17
+ */
18
+ function resetMocks() {
19
+ exports.mockStorage = new mock_storage_1.MockStorage();
20
+ exports.mockAIOperations = new mock_ai_operations_1.MockAIOperations(); // Cast to any to avoid type issues
21
+ exports.mockModelProvider = new mock_model_provider_1.MockModelProvider();
22
+ exports.mockContextBuilder = new mock_context_builder_1.MockContextBuilder(exports.mockStorage);
23
+ // Inject mocks into the service factory
24
+ (0, ai_service_factory_1.injectTestInstances)({
25
+ storage: exports.mockStorage,
26
+ aiOperations: exports.mockAIOperations,
27
+ modelProvider: exports.mockModelProvider,
28
+ contextBuilder: exports.mockContextBuilder,
29
+ });
30
+ }
31
+ /**
32
+ * Get current mock instances for test assertions
33
+ */
34
+ function getMocks() {
35
+ return {
36
+ storage: exports.mockStorage,
37
+ aiOperations: exports.mockAIOperations,
38
+ modelProvider: exports.mockModelProvider,
39
+ contextBuilder: exports.mockContextBuilder,
40
+ };
41
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Test Setup - Global test configuration and cleanup
3
+ * This file sets up the test environment to ensure proper isolation and configuration
4
+ */
5
+ export declare function setupTestEnvironment(): {
6
+ config: import("../lib/config").Config;
7
+ workingDir: string;
8
+ };
9
+ //# sourceMappingURL=test-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../../src/test/test-setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsCH,wBAAgB,oBAAoB;;;EAMnC"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /**
3
+ * Test Setup - Global test configuration and cleanup
4
+ * This file sets up the test environment to ensure proper isolation and configuration
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.setupTestEnvironment = setupTestEnvironment;
8
+ const config_1 = require("../lib/config");
9
+ const hooks_1 = require("../lib/hooks");
10
+ const test_mock_setup_1 = require("./test-mock-setup");
11
+ // Global test setup
12
+ before(async function () {
13
+ // Set up a test working directory
14
+ const testDir = process.cwd();
15
+ config_1.configManager.setWorkingDirectory(testDir);
16
+ // Set up a minimal test configuration (no need to load from disk)
17
+ config_1.configManager.setConfig({
18
+ ai: {
19
+ provider: "openrouter",
20
+ model: "anthropic/claude-3-5-sonnet",
21
+ maxTokens: 4000,
22
+ temperature: 0.7,
23
+ apiKey: "test-key",
24
+ },
25
+ workingDirectory: testDir,
26
+ });
27
+ // Reset mocks to ensure clean state
28
+ (0, test_mock_setup_1.resetMocks)();
29
+ });
30
+ // Clean up between tests
31
+ afterEach(function () {
32
+ // Reset mocks to ensure clean state
33
+ (0, test_mock_setup_1.resetMocks)();
34
+ // Clean up hooks to prevent interference
35
+ hooks_1.hooks.clear();
36
+ });
37
+ // Additional test utilities
38
+ function setupTestEnvironment() {
39
+ // This can be called in individual tests for additional setup
40
+ return {
41
+ config: config_1.configManager.getConfig(),
42
+ workingDir: config_1.configManager.getWorkingDirectory(),
43
+ };
44
+ }
@@ -0,0 +1,22 @@
1
+ import { MockStorage } from "./mocks/mock-storage";
2
+ import { MockAIOperations } from "./mocks/mock-ai-operations";
3
+ import { MockModelProvider } from "./mocks/mock-model-provider";
4
+ import { MockContextBuilder } from "./mocks/mock-context-builder";
5
+ export interface TestContext {
6
+ storage: MockStorage;
7
+ aiOperations: MockAIOperations;
8
+ modelProvider: MockModelProvider;
9
+ contextBuilder: MockContextBuilder;
10
+ }
11
+ export declare function createTestContext(): TestContext;
12
+ export declare function createTestTaskData(): {
13
+ title: string;
14
+ description: string;
15
+ content: string;
16
+ effort: "medium";
17
+ };
18
+ export declare function createTestPRDData(): {
19
+ description: string;
20
+ content: string;
21
+ };
22
+ //# sourceMappingURL=test-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/test/test-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,aAAa,EAAE,iBAAiB,CAAC;IACjC,cAAc,EAAE,kBAAkB,CAAC;CACpC;AAED,wBAAgB,iBAAiB,IAAI,WAAW,CAc/C;AAED,wBAAgB,kBAAkB;;;;;EAOjC;AAED,wBAAgB,iBAAiB;;;EAMhC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTestContext = createTestContext;
4
+ exports.createTestTaskData = createTestTaskData;
5
+ exports.createTestPRDData = createTestPRDData;
6
+ const mock_service_factory_1 = require("./mocks/mock-service-factory");
7
+ const mock_storage_1 = require("./mocks/mock-storage");
8
+ const mock_ai_operations_1 = require("./mocks/mock-ai-operations");
9
+ const mock_model_provider_1 = require("./mocks/mock-model-provider");
10
+ const mock_context_builder_1 = require("./mocks/mock-context-builder");
11
+ function createTestContext() {
12
+ (0, mock_service_factory_1.resetMockServices)();
13
+ const storage = new mock_storage_1.MockStorage();
14
+ const aiOperations = new mock_ai_operations_1.MockAIOperations();
15
+ const modelProvider = new mock_model_provider_1.MockModelProvider();
16
+ const contextBuilder = new mock_context_builder_1.MockContextBuilder(storage);
17
+ return {
18
+ storage,
19
+ aiOperations,
20
+ modelProvider,
21
+ contextBuilder,
22
+ };
23
+ }
24
+ function createTestTaskData() {
25
+ return {
26
+ title: "Test Task",
27
+ description: "This is a test task description",
28
+ content: "Full content for the test task",
29
+ effort: "medium",
30
+ };
31
+ }
32
+ function createTestPRDData() {
33
+ return {
34
+ description: "Test PRD description",
35
+ content: "# Test PRD\n\nThis is a test PRD document with multiple sections.\n\n## Features\n- Feature 1\n- Feature 2\n\n## Requirements\n- Requirement 1\n- Requirement 2",
36
+ };
37
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ai-operation-utility.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-operation-utility.test.d.ts","sourceRoot":"","sources":["../../../src/test/utils/ai-operation-utility.test.ts"],"names":[],"mappings":""}