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
@@ -1,16 +1,50 @@
1
1
  import { Task, TaskAIMetadata, DocumentationDetection } from "./index";
2
- export interface OperationResult<T = any> {
3
- success: boolean;
4
- data?: T;
5
- error?: string;
2
+ /**
3
+ * Generic operation result using discriminated union pattern.
4
+ * Prevents invalid states like { success: true, error: "..." }
5
+ *
6
+ * Note: This type uses discriminated unions for operations that may return
7
+ * either success or failure. Most task operations throw exceptions on error
8
+ * instead of returning error results.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const result: OperationResult<Task> =
13
+ * condition
14
+ * ? { success: true, data: task }
15
+ * : { success: false, error: "Task not found" };
16
+ *
17
+ * if (result.success) {
18
+ * console.log(result.data.title); // ✓ TypeScript knows data exists
19
+ * } else {
20
+ * console.error(result.error); // ✓ TypeScript knows error exists
21
+ * }
22
+ * ```
23
+ */
24
+ export type OperationResult<T = any> = {
25
+ success: true;
26
+ data: T;
6
27
  stats?: Record<string, any>;
7
28
  metadata?: Record<string, any>;
8
- }
29
+ } | {
30
+ success: false;
31
+ error: string;
32
+ stats?: Record<string, any>;
33
+ metadata?: Record<string, any>;
34
+ };
35
+ /**
36
+ * Result of task creation operation.
37
+ * Always returns success; throws exception on error.
38
+ */
9
39
  export interface CreateTaskResult {
10
40
  success: true;
11
41
  task: Task;
12
42
  aiMetadata?: TaskAIMetadata;
13
43
  }
44
+ /**
45
+ * Result of task enhancement operation.
46
+ * Always returns success; throws exception on error.
47
+ */
14
48
  export interface EnhanceTaskResult {
15
49
  success: true;
16
50
  task: Task;
@@ -33,6 +67,10 @@ export interface EnhanceTaskResult {
33
67
  confidence: number;
34
68
  };
35
69
  }
70
+ /**
71
+ * Result of task splitting operation.
72
+ * Always returns success; throws exception on error.
73
+ */
36
74
  export interface SplitTaskResult {
37
75
  success: true;
38
76
  task: Task;
@@ -54,6 +92,10 @@ export interface SplitTaskResult {
54
92
  confidence?: number;
55
93
  };
56
94
  }
95
+ /**
96
+ * Result of task planning operation.
97
+ * Always returns success; throws exception on error.
98
+ */
57
99
  export interface PlanTaskResult {
58
100
  success: true;
59
101
  task: Task;
@@ -73,6 +115,10 @@ export interface PlanTaskResult {
73
115
  aiModel: string;
74
116
  };
75
117
  }
118
+ /**
119
+ * Result of task documentation operation.
120
+ * Always returns success; throws exception on error.
121
+ */
76
122
  export interface DocumentTaskResult {
77
123
  success: true;
78
124
  task: Task;
@@ -82,13 +128,21 @@ export interface DocumentTaskResult {
82
128
  duration: number;
83
129
  };
84
130
  }
131
+ /**
132
+ * Result of task deletion operation.
133
+ * Always returns success; throws exception on error.
134
+ */
85
135
  export interface DeleteTaskResult {
86
136
  success: true;
87
137
  deleted: Task[];
88
138
  orphanedSubtasks: Task[];
89
139
  }
140
+ /**
141
+ * Result of PRD parsing operation.
142
+ * Always returns success; throws exception on error.
143
+ */
90
144
  export interface PRDParseResult {
91
- success: boolean;
145
+ success: true;
92
146
  prd: {
93
147
  overview: string;
94
148
  objectives: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../src/types/results.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../src/types/results.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ import type { ToolSet } from "ai";
2
+ import { AIConfig, StreamingOptions, RetryConfig } from "../types";
3
+ import { BaseOperations } from "../lib/ai-service/base-operations";
4
+ export interface AIOperationResult<T> {
5
+ result: T;
6
+ metrics: {
7
+ duration: number;
8
+ tokenUsage?: {
9
+ prompt: number;
10
+ completion: number;
11
+ total: number;
12
+ };
13
+ timeToFirstToken?: number;
14
+ };
15
+ }
16
+ export interface AIOperationOptions {
17
+ streamingOptions?: StreamingOptions;
18
+ retryConfig?: Partial<RetryConfig>;
19
+ aiConfig?: Partial<AIConfig>;
20
+ enableFilesystemTools?: boolean;
21
+ context?: Record<string, unknown>;
22
+ maxRetries?: number;
23
+ }
24
+ /**
25
+ * AIOperationUtility - Centralized utility for AI operations with metrics and error handling
26
+ *
27
+ * Extends BaseOperations to inherit core AI functionality (streamText, model provider, etc.)
28
+ * and adds standardized metrics collection, error handling, and retry logic.
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const utility = new AIOperationUtility();
33
+ *
34
+ * // Execute operation with metrics
35
+ * const result = await utility.executeAIOperation(
36
+ * "Task breakdown",
37
+ * async () => performBreakdown(task),
38
+ * {
39
+ * maxRetries: 3,
40
+ * streamingOptions: { onChunk: console.log }
41
+ * }
42
+ * );
43
+ *
44
+ * console.log(result.metrics.duration);
45
+ * console.log(result.metrics.timeToFirstToken);
46
+ * ```
47
+ */
48
+ export declare class AIOperationUtility extends BaseOperations {
49
+ /**
50
+ * Execute an AI operation with standardized metrics, error handling, and streaming support
51
+ *
52
+ * This method wraps AI operations to provide:
53
+ * - Automatic retry logic with configurable attempts
54
+ * - Metrics collection (duration, token usage, time to first token)
55
+ * - Error handling with TaskOMaticError wrapping
56
+ * - Streaming support with metrics capture
57
+ *
58
+ * @param operationName - Human-readable name for the operation (used in errors)
59
+ * @param operation - The async operation to execute
60
+ * @param options - Configuration options for retry, streaming, and AI config
61
+ * @returns Promise resolving to AIOperationResult with result and metrics
62
+ * @throws {TaskOMaticError} If operation fails after all retry attempts
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * try {
67
+ * const result = await utility.executeAIOperation(
68
+ * "Task enhancement",
69
+ * async () => enhanceTask(task),
70
+ * { maxRetries: 2 }
71
+ * );
72
+ * console.log(`Operation took ${result.metrics.duration}ms`);
73
+ * } catch (error) {
74
+ * if (error instanceof TaskOMaticError) {
75
+ * console.error(error.getDetails());
76
+ * }
77
+ * }
78
+ * ```
79
+ */
80
+ executeAIOperation<T>(operationName: string, operation: () => Promise<T>, options?: AIOperationOptions): Promise<AIOperationResult<T>>;
81
+ /**
82
+ * Standardized streaming text operation with tool support
83
+ *
84
+ * This method provides a unified interface for AI text generation with:
85
+ * - Optional tool integration (filesystem, MCP, etc.)
86
+ * - Streaming support with callbacks
87
+ * - Context7 documentation caching
88
+ * - Metrics collection
89
+ * - Error handling
90
+ *
91
+ * @param systemPrompt - System prompt for the AI
92
+ * @param userMessage - User message/prompt
93
+ * @param config - Optional AI configuration overrides
94
+ * @param streamingOptions - Optional streaming callbacks
95
+ * @param tools - Optional tool set to provide to the AI
96
+ * @returns Promise resolving to the generated text
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const result = await utility.streamTextWithTools(
101
+ * "You are a helpful assistant",
102
+ * "Explain quantum computing",
103
+ * undefined,
104
+ * { onChunk: (chunk) => console.log(chunk) },
105
+ * filesystemTools
106
+ * );
107
+ * ```
108
+ */
109
+ streamTextWithTools(systemPrompt: string, userMessage: string, config?: Partial<AIConfig>, streamingOptions?: StreamingOptions, tools?: ToolSet): Promise<string>;
110
+ /**
111
+ * Wrap streaming options to capture metrics
112
+ *
113
+ * @private
114
+ */
115
+ private wrapStreamingOptions;
116
+ /**
117
+ * Create streaming configuration with Context7 handling and callbacks
118
+ *
119
+ * This method creates a unified streaming configuration that:
120
+ * - Always handles Context7 tool-result events (even without streaming UI)
121
+ * - Forwards text-delta events to onChunk callback
122
+ * - Forwards reasoning-delta events to onReasoning callback
123
+ * - Handles errors with onError callback
124
+ * - Provides onFinish callback with completion data
125
+ *
126
+ * @private
127
+ */
128
+ private createStreamingConfig;
129
+ /**
130
+ * Extract token usage from AI result
131
+ *
132
+ * @private
133
+ */
134
+ private extractTokenUsageFromResult;
135
+ /**
136
+ * Get error message from any error type
137
+ *
138
+ * @private
139
+ */
140
+ private getErrorMessage;
141
+ }
142
+ //# sourceMappingURL=ai-operation-utility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-operation-utility.d.ts","sourceRoot":"","sources":["../../src/utils/ai-operation-utility.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAGnE,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,MAAM,EAAE,CAAC,CAAC;IACV,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE;YACX,MAAM,EAAE,MAAM,CAAC;YACf,UAAU,EAAE,MAAM,CAAC;YACnB,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QACF,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;IACpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACG,kBAAkB,CAAC,CAAC,EACxB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAmEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC;IAgClB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAgC5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,qBAAqB;IAsD7B;;;;OAIG;IACH,OAAO,CAAC,2BAA2B;IAiBnC;;;;OAIG;IACH,OAAO,CAAC,eAAe;CASxB"}
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AIOperationUtility = void 0;
4
+ const ai_1 = require("ai");
5
+ const base_operations_1 = require("../lib/ai-service/base-operations");
6
+ const task_o_matic_error_1 = require("./task-o-matic-error");
7
+ /**
8
+ * AIOperationUtility - Centralized utility for AI operations with metrics and error handling
9
+ *
10
+ * Extends BaseOperations to inherit core AI functionality (streamText, model provider, etc.)
11
+ * and adds standardized metrics collection, error handling, and retry logic.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const utility = new AIOperationUtility();
16
+ *
17
+ * // Execute operation with metrics
18
+ * const result = await utility.executeAIOperation(
19
+ * "Task breakdown",
20
+ * async () => performBreakdown(task),
21
+ * {
22
+ * maxRetries: 3,
23
+ * streamingOptions: { onChunk: console.log }
24
+ * }
25
+ * );
26
+ *
27
+ * console.log(result.metrics.duration);
28
+ * console.log(result.metrics.timeToFirstToken);
29
+ * ```
30
+ */
31
+ class AIOperationUtility extends base_operations_1.BaseOperations {
32
+ /**
33
+ * Execute an AI operation with standardized metrics, error handling, and streaming support
34
+ *
35
+ * This method wraps AI operations to provide:
36
+ * - Automatic retry logic with configurable attempts
37
+ * - Metrics collection (duration, token usage, time to first token)
38
+ * - Error handling with TaskOMaticError wrapping
39
+ * - Streaming support with metrics capture
40
+ *
41
+ * @param operationName - Human-readable name for the operation (used in errors)
42
+ * @param operation - The async operation to execute
43
+ * @param options - Configuration options for retry, streaming, and AI config
44
+ * @returns Promise resolving to AIOperationResult with result and metrics
45
+ * @throws {TaskOMaticError} If operation fails after all retry attempts
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * try {
50
+ * const result = await utility.executeAIOperation(
51
+ * "Task enhancement",
52
+ * async () => enhanceTask(task),
53
+ * { maxRetries: 2 }
54
+ * );
55
+ * console.log(`Operation took ${result.metrics.duration}ms`);
56
+ * } catch (error) {
57
+ * if (error instanceof TaskOMaticError) {
58
+ * console.error(error.getDetails());
59
+ * }
60
+ * }
61
+ * ```
62
+ */
63
+ async executeAIOperation(operationName, operation, options = {}) {
64
+ const startTime = Date.now();
65
+ let timeToFirstToken;
66
+ // Create wrapped streaming options to capture metrics
67
+ const wrappedStreamingOptions = this.wrapStreamingOptions(options.streamingOptions, startTime, (time) => {
68
+ timeToFirstToken = time;
69
+ });
70
+ try {
71
+ // Execute with retry logic
72
+ const result = await this.retryHandler.executeWithRetry(async () => {
73
+ // Execute operation - note: operations should use the streaming options
74
+ // passed through the closure, not directly from options
75
+ return await operation();
76
+ }, {
77
+ maxAttempts: options.maxRetries || options.retryConfig?.maxAttempts || 2,
78
+ ...options.retryConfig,
79
+ }, operationName);
80
+ const duration = Date.now() - startTime;
81
+ return {
82
+ result,
83
+ metrics: {
84
+ duration,
85
+ timeToFirstToken,
86
+ tokenUsage: this.extractTokenUsageFromResult(result),
87
+ },
88
+ };
89
+ }
90
+ catch (error) {
91
+ const duration = Date.now() - startTime;
92
+ const typedError = error instanceof Error ? error : new Error(String(error));
93
+ // THROW error instead of returning it
94
+ throw new task_o_matic_error_1.TaskOMaticError(`AI operation failed: ${operationName}`, {
95
+ code: "AI_OPERATION_FAILED",
96
+ context: JSON.stringify({
97
+ operation: operationName,
98
+ duration,
99
+ error: this.getErrorMessage(typedError),
100
+ }),
101
+ cause: typedError,
102
+ suggestions: [
103
+ "Check AI configuration",
104
+ "Verify network connectivity",
105
+ "Review operation parameters",
106
+ "Check API keys and endpoints",
107
+ ],
108
+ metadata: {
109
+ operationName,
110
+ duration,
111
+ attemptedRetries: options.maxRetries || 2,
112
+ },
113
+ });
114
+ }
115
+ }
116
+ /**
117
+ * Standardized streaming text operation with tool support
118
+ *
119
+ * This method provides a unified interface for AI text generation with:
120
+ * - Optional tool integration (filesystem, MCP, etc.)
121
+ * - Streaming support with callbacks
122
+ * - Context7 documentation caching
123
+ * - Metrics collection
124
+ * - Error handling
125
+ *
126
+ * @param systemPrompt - System prompt for the AI
127
+ * @param userMessage - User message/prompt
128
+ * @param config - Optional AI configuration overrides
129
+ * @param streamingOptions - Optional streaming callbacks
130
+ * @param tools - Optional tool set to provide to the AI
131
+ * @returns Promise resolving to the generated text
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const result = await utility.streamTextWithTools(
136
+ * "You are a helpful assistant",
137
+ * "Explain quantum computing",
138
+ * undefined,
139
+ * { onChunk: (chunk) => console.log(chunk) },
140
+ * filesystemTools
141
+ * );
142
+ * ```
143
+ */
144
+ async streamTextWithTools(systemPrompt, userMessage, config, streamingOptions, tools) {
145
+ const aiConfig = this.mergeAIConfig(config);
146
+ const model = this.modelProvider.getModel(aiConfig);
147
+ // Create streaming configuration with Context7 handling and callbacks
148
+ const streamConfig = this.createStreamingConfig(streamingOptions);
149
+ const result = await (0, ai_1.streamText)({
150
+ model,
151
+ tools: tools || {},
152
+ system: systemPrompt,
153
+ messages: [{ role: "user", content: userMessage }],
154
+ maxRetries: 0,
155
+ ...streamConfig,
156
+ ...(aiConfig.provider === "openrouter" &&
157
+ aiConfig.reasoning &&
158
+ aiConfig.reasoning.maxTokens
159
+ ? {
160
+ providerOptions: {
161
+ openrouter: {
162
+ reasoning: {
163
+ max_tokens: aiConfig.reasoning.maxTokens,
164
+ },
165
+ },
166
+ },
167
+ }
168
+ : {}),
169
+ });
170
+ return await result.text;
171
+ }
172
+ /**
173
+ * Wrap streaming options to capture metrics
174
+ *
175
+ * @private
176
+ */
177
+ wrapStreamingOptions(streamingOptions, startTime, onFirstToken) {
178
+ if (!streamingOptions) {
179
+ return undefined;
180
+ }
181
+ let firstTokenCaptured = false;
182
+ return {
183
+ ...streamingOptions,
184
+ onChunk: (chunk) => {
185
+ if (!firstTokenCaptured && chunk.trim()) {
186
+ onFirstToken(Date.now() - startTime);
187
+ firstTokenCaptured = true;
188
+ }
189
+ streamingOptions.onChunk?.(chunk);
190
+ },
191
+ onFinish: (result) => {
192
+ streamingOptions.onFinish?.(result);
193
+ },
194
+ onReasoning: (reasoning) => {
195
+ streamingOptions.onReasoning?.(reasoning);
196
+ },
197
+ onError: (error) => {
198
+ streamingOptions.onError?.(error);
199
+ },
200
+ };
201
+ }
202
+ /**
203
+ * Create streaming configuration with Context7 handling and callbacks
204
+ *
205
+ * This method creates a unified streaming configuration that:
206
+ * - Always handles Context7 tool-result events (even without streaming UI)
207
+ * - Forwards text-delta events to onChunk callback
208
+ * - Forwards reasoning-delta events to onReasoning callback
209
+ * - Handles errors with onError callback
210
+ * - Provides onFinish callback with completion data
211
+ *
212
+ * @private
213
+ */
214
+ createStreamingConfig(streamingOptions) {
215
+ return {
216
+ onChunk: streamingOptions?.onChunk || streamingOptions?.onReasoning
217
+ ? (event) => {
218
+ // Handle Context7 tool results ALWAYS (critical for caching)
219
+ if (event.chunk?.type === "tool-result" &&
220
+ event.chunk?.toolName === "get-library-docs") {
221
+ const docs = event.chunk.output;
222
+ if (docs && typeof docs === "object" && "content" in docs) {
223
+ this.context7Client.saveContext7Documentation(event.chunk.input?.context7CompatibleLibraryID || "unknown", docs.content, event.chunk.input?.topic || "general");
224
+ }
225
+ else if (docs && typeof docs === "string") {
226
+ this.context7Client.saveContext7Documentation(event.chunk.input?.context7CompatibleLibraryID || "unknown", docs, event.chunk.input?.topic || "general");
227
+ }
228
+ }
229
+ // Forward text deltas to user callback
230
+ if (event.chunk?.type === "text-delta") {
231
+ streamingOptions?.onChunk?.(event.chunk.text);
232
+ }
233
+ // Forward reasoning deltas to user callback
234
+ if (event.chunk?.type === "reasoning-delta") {
235
+ streamingOptions?.onReasoning?.(event.chunk.text);
236
+ }
237
+ }
238
+ : undefined,
239
+ onFinish: streamingOptions?.onFinish
240
+ ? (event) => {
241
+ streamingOptions.onFinish({
242
+ text: event.text,
243
+ finishReason: event.finishReason,
244
+ usage: event.usage,
245
+ isAborted: false,
246
+ });
247
+ }
248
+ : undefined,
249
+ onError: streamingOptions?.onError
250
+ ? (event) => {
251
+ streamingOptions.onError(event.error);
252
+ }
253
+ : undefined,
254
+ };
255
+ }
256
+ /**
257
+ * Extract token usage from AI result
258
+ *
259
+ * @private
260
+ */
261
+ extractTokenUsageFromResult(result) {
262
+ if (result && result.usage) {
263
+ return {
264
+ prompt: result.usage.prompt_tokens || 0,
265
+ completion: result.usage.completion_tokens || 0,
266
+ total: result.usage.total_tokens || 0,
267
+ };
268
+ }
269
+ return undefined;
270
+ }
271
+ /**
272
+ * Get error message from any error type
273
+ *
274
+ * @private
275
+ */
276
+ getErrorMessage(error) {
277
+ if (error instanceof Error) {
278
+ return error.message;
279
+ }
280
+ else if (typeof error === "string") {
281
+ return error;
282
+ }
283
+ else {
284
+ return "Unknown error";
285
+ }
286
+ }
287
+ }
288
+ exports.AIOperationUtility = AIOperationUtility;
@@ -21,4 +21,14 @@ export declare function getModelProvider(): ModelProvider;
21
21
  export declare function getStorage(): TaskRepository;
22
22
  export declare function getContextBuilder(): ContextBuilder;
23
23
  export declare function resetServiceInstances(): void;
24
+ /**
25
+ * FOR TESTING ONLY: Inject mock instances
26
+ * This allows tests to provide mock implementations without complex module mocking
27
+ */
28
+ export declare function injectTestInstances(instances: {
29
+ storage?: TaskRepository;
30
+ aiOperations?: AIOperations;
31
+ modelProvider?: ModelProvider;
32
+ contextBuilder?: ContextBuilder;
33
+ }): void;
24
34
  //# sourceMappingURL=ai-service-factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-service-factory.d.ts","sourceRoot":"","sources":["../../src/utils/ai-service-factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1E,OAAO,EAAiB,eAAe,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEpE,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAOD;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAgB,eAAe,IAAI,YAAY,CAK9C;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED,wBAAgB,UAAU,IAAI,cAAc,CAkB3C;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAMlD;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAK5C"}
1
+ {"version":3,"file":"ai-service-factory.d.ts","sourceRoot":"","sources":["../../src/utils/ai-service-factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1E,OAAO,EAAiB,eAAe,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAMpE,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAOD;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAgB,eAAe,IAAI,YAAY,CAK9C;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED,wBAAgB,UAAU,IAAI,cAAc,CAsB3C;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAMlD;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAK5C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE;IAC7C,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,GAAG,IAAI,CAKP"}
@@ -6,12 +6,14 @@ exports.getModelProvider = getModelProvider;
6
6
  exports.getStorage = getStorage;
7
7
  exports.getContextBuilder = getContextBuilder;
8
8
  exports.resetServiceInstances = resetServiceInstances;
9
+ exports.injectTestInstances = injectTestInstances;
9
10
  const file_system_1 = require("../lib/storage/file-system");
10
11
  const context_builder_1 = require("../lib/context-builder");
11
12
  const fs_1 = require("fs");
12
13
  const config_1 = require("../lib/config");
13
14
  const ai_operations_1 = require("../lib/ai-service/ai-operations");
14
15
  const model_provider_1 = require("../lib/ai-service/model-provider");
16
+ const task_o_matic_error_1 = require("./task-o-matic-error");
15
17
  let aiOperations = null;
16
18
  let modelProvider = null;
17
19
  let storage = null;
@@ -60,7 +62,9 @@ function getStorage() {
60
62
  const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
61
63
  // Note: This check relies on FS. Web apps should call initializeServices first.
62
64
  if (!(0, fs_1.existsSync)(taskOMaticDir)) {
63
- throw new Error(`Not a task-o-matic project. Run 'task-o-matic init' first.`);
65
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.CONFIGURATION_ERROR, "Not a task-o-matic project. Run 'task-o-matic init' first.", {
66
+ suggestions: ["Run `task-o-matic init` in your project root."],
67
+ });
64
68
  }
65
69
  storage = new file_system_1.FileSystemStorage();
66
70
  }
@@ -79,3 +83,17 @@ function resetServiceInstances() {
79
83
  storage = null;
80
84
  contextBuilder = null;
81
85
  }
86
+ /**
87
+ * FOR TESTING ONLY: Inject mock instances
88
+ * This allows tests to provide mock implementations without complex module mocking
89
+ */
90
+ function injectTestInstances(instances) {
91
+ if (instances.storage)
92
+ storage = instances.storage;
93
+ if (instances.aiOperations)
94
+ aiOperations = instances.aiOperations;
95
+ if (instances.modelProvider)
96
+ modelProvider = instances.modelProvider;
97
+ if (instances.contextBuilder)
98
+ contextBuilder = instances.contextBuilder;
99
+ }
@@ -6,7 +6,7 @@
6
6
  * @param field2 - Second field name in options
7
7
  * @param field1Label - Display label for first field (defaults to field1)
8
8
  * @param field2Label - Display label for second field (defaults to field2)
9
- * @throws Error if neither or both fields are provided
9
+ * @throws TaskOMaticError if neither or both fields are provided
10
10
  *
11
11
  * @example
12
12
  * ```typescript
@@ -26,7 +26,7 @@ export interface FieldSpec {
26
26
  *
27
27
  * @param options - The command options object
28
28
  * @param fields - Array of field specifications
29
- * @throws Error if none or multiple fields are provided
29
+ * @throws TaskOMaticError if none or multiple fields are provided
30
30
  *
31
31
  * @example
32
32
  * ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"cli-validators.d.ts","sourceRoot":"","sources":["../../src/utils/cli-validators.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,WAAW,GAAE,MAAe,EAC5B,WAAW,GAAE,MAAe,GAC3B,IAAI,CAcN;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,GAAG,EACZ,GAAG,MAAM,EAAE,SAAS,EAAE,GACrB,IAAI,CAWN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKtD"}
1
+ {"version":3,"file":"cli-validators.d.ts","sourceRoot":"","sources":["../../src/utils/cli-validators.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,WAAW,GAAE,MAAe,EAC5B,WAAW,GAAE,MAAe,GAC3B,IAAI,CAgBN;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,GAAG,EACZ,GAAG,MAAM,EAAE,SAAS,EAAE,GACrB,IAAI,CAiBN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKtD"}