task-o-matic-core 0.1.4 → 0.1.5-beta.2
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/README.md +946 -222
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/lib/ai-service/prd-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/prd-operations.js +3 -36
- package/dist/lib/benchmark/executor.d.ts +93 -0
- package/dist/lib/benchmark/executor.d.ts.map +1 -0
- package/dist/lib/benchmark/executor.js +395 -0
- package/dist/lib/benchmark/index.d.ts +16 -0
- package/dist/lib/benchmark/index.d.ts.map +1 -0
- package/dist/lib/benchmark/index.js +36 -0
- package/dist/lib/benchmark/metrics-collector.d.ts +84 -0
- package/dist/lib/benchmark/metrics-collector.d.ts.map +1 -0
- package/dist/lib/benchmark/metrics-collector.js +297 -0
- package/dist/lib/benchmark/operations/index.d.ts +70 -0
- package/dist/lib/benchmark/operations/index.d.ts.map +1 -0
- package/dist/lib/benchmark/operations/index.js +298 -0
- package/dist/lib/benchmark/orchestrator.d.ts +88 -0
- package/dist/lib/benchmark/orchestrator.d.ts.map +1 -0
- package/dist/lib/benchmark/orchestrator.js +337 -0
- package/dist/lib/benchmark/store.d.ts +140 -0
- package/dist/lib/benchmark/store.d.ts.map +1 -0
- package/dist/lib/benchmark/store.js +417 -0
- package/dist/lib/benchmark/types.d.ts +243 -60
- package/dist/lib/benchmark/types.d.ts.map +1 -1
- package/dist/lib/benchmark/types.js +7 -0
- package/dist/lib/benchmark/worktree-manager.d.ts +127 -0
- package/dist/lib/benchmark/worktree-manager.d.ts.map +1 -0
- package/dist/lib/benchmark/worktree-manager.js +325 -0
- package/dist/lib/benchmark/worktree-pool.d.ts +97 -0
- package/dist/lib/benchmark/worktree-pool.d.ts.map +1 -0
- package/dist/lib/benchmark/worktree-pool.js +198 -0
- package/dist/lib/executors/opencode-executor.js +5 -5
- package/dist/lib/index.d.ts +0 -5
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -7
- package/dist/lib/task-execution-core.js +17 -1
- package/dist/lib/task-review.d.ts +7 -0
- package/dist/lib/task-review.d.ts.map +1 -1
- package/dist/lib/task-review.js +30 -10
- package/dist/services/prd.d.ts.map +1 -1
- package/dist/services/prd.js +20 -44
- package/dist/services/tasks.d.ts.map +1 -1
- package/dist/services/tasks.js +12 -54
- package/dist/test/benchmark/metrics.test.d.ts +7 -0
- package/dist/test/benchmark/metrics.test.d.ts.map +1 -0
- package/dist/test/benchmark/metrics.test.js +267 -0
- package/dist/test/benchmark/orchestrator.test.d.ts +12 -0
- package/dist/test/benchmark/orchestrator.test.d.ts.map +1 -0
- package/dist/test/benchmark/orchestrator.test.js +316 -0
- package/dist/test/benchmark/store.test.d.ts +7 -0
- package/dist/test/benchmark/store.test.d.ts.map +1 -0
- package/dist/test/benchmark/store.test.js +356 -0
- package/dist/test/benchmark/worktree.test.d.ts +7 -0
- package/dist/test/benchmark/worktree.test.d.ts.map +1 -0
- package/dist/test/benchmark/worktree.test.js +347 -0
- package/dist/test/lib/task-review.test.d.ts +2 -0
- package/dist/test/lib/task-review.test.d.ts.map +1 -0
- package/dist/test/lib/task-review.test.js +178 -0
- package/dist/test/services/task-service.test.js +31 -8
- package/package.json +2 -2
- package/dist/lib/benchmark/registry.d.ts +0 -11
- package/dist/lib/benchmark/registry.d.ts.map +0 -1
- package/dist/lib/benchmark/registry.js +0 -212
- package/dist/lib/benchmark/runner.d.ts +0 -6
- package/dist/lib/benchmark/runner.d.ts.map +0 -1
- package/dist/lib/benchmark/runner.js +0 -150
- package/dist/lib/benchmark/storage.d.ts +0 -13
- package/dist/lib/benchmark/storage.d.ts.map +0 -1
- package/dist/lib/benchmark/storage.js +0 -100
- package/dist/services/benchmark.d.ts +0 -26
- package/dist/services/benchmark.d.ts.map +0 -1
- package/dist/services/benchmark.js +0 -343
- package/dist/services/workflow-benchmark.d.ts +0 -34
- package/dist/services/workflow-benchmark.d.ts.map +0 -1
- package/dist/services/workflow-benchmark.js +0 -318
package/README.md
CHANGED
|
@@ -1,29 +1,53 @@
|
|
|
1
|
-
# task-o-matic-core
|
|
1
|
+
# ⛑️ task-o-matic-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**The infrastructure foundation for your survival toolkit**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ⚠️ ENGINEERING BULLETIN
|
|
8
|
+
|
|
9
|
+
_Engineers, the core library is the backbone of our entire operation. It's not just a package—it's the foundation upon which we build bunkers, manage supplies, and deploy AI assistance in this post-apocalyptic development landscape._
|
|
10
|
+
|
|
11
|
+
_Think of `task-o-matic-core` as your blueprint for building custom command interfaces, TUI applications, web dashboards, or any other tool you need to manage projects. All the power, none of the CLI wrapper._
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
_[The preceding message was brought to you by the Department of Engineering Standards. Remember: Clean architecture is survival architecture.]_
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 📦 OVERVIEW
|
|
18
|
+
|
|
19
|
+
`task-o-matic-core` is the foundational library providing all core functionality for task management, PRD processing, AI operations, and workflow automation. It's framework-agnostic and can be integrated into any Node.js application.
|
|
20
|
+
|
|
21
|
+
**Key Features:**
|
|
22
|
+
- 🤖 **AI-Powered Task Management**: Create, enhance, split, and manage tasks with AI
|
|
23
|
+
- 📋 **PRD Processing**: Parse, refine, version, and rework Product Requirements Documents
|
|
24
|
+
- 🎯 **Workflow Automation**: Complete project lifecycle orchestration
|
|
25
|
+
- 📊 **Benchmark System**: Compare AI model performance across operations
|
|
26
|
+
- 💾 **Local Storage**: File-based persistence in `.task-o-matic/` directory
|
|
27
|
+
- 🌊 **Streaming Support**: Real-time AI response streaming
|
|
28
|
+
- 🔧 **Multi-Provider AI**: OpenAI, Anthropic, OpenRouter, custom endpoints
|
|
29
|
+
- 📚 **Context7 Integration**: Up-to-date library documentation fetching
|
|
30
|
+
- 🎭 **Framework-Agnostic**: Use in CLI, TUI, web apps, or custom tools
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 📦 INSTALLATION
|
|
10
35
|
|
|
11
36
|
```bash
|
|
12
37
|
npm install task-o-matic-core
|
|
13
38
|
```
|
|
14
39
|
|
|
15
|
-
|
|
40
|
+
```bash
|
|
41
|
+
bun add task-o-matic-core
|
|
42
|
+
```
|
|
16
43
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- 🌊 **Streaming Support**: Real-time AI response streaming
|
|
23
|
-
- 🔧 **Multi-Provider AI**: Support for OpenAI, Anthropic, OpenRouter, and custom providers
|
|
24
|
-
- 🎭 **Framework-Agnostic**: Use in CLI, TUI, web apps, or any Node.js project
|
|
44
|
+
```bash
|
|
45
|
+
pnpm add task-o-matic-core
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
25
49
|
|
|
26
|
-
##
|
|
50
|
+
## 🚀 QUICK START: ENGINEERING MODE
|
|
27
51
|
|
|
28
52
|
### Basic Task Management
|
|
29
53
|
|
|
@@ -32,10 +56,10 @@ import { TaskService } from "task-o-matic-core";
|
|
|
32
56
|
|
|
33
57
|
const taskService = new TaskService();
|
|
34
58
|
|
|
35
|
-
// Create
|
|
59
|
+
// Create task with AI enhancement
|
|
36
60
|
const result = await taskService.createTask({
|
|
37
|
-
title: "
|
|
38
|
-
content: "
|
|
61
|
+
title: "Install water filtration system",
|
|
62
|
+
content: "Implement water purification for bunker section B",
|
|
39
63
|
aiEnhance: true,
|
|
40
64
|
aiOptions: {
|
|
41
65
|
aiProvider: "anthropic",
|
|
@@ -60,7 +84,7 @@ import { WorkflowService } from "task-o-matic-core";
|
|
|
60
84
|
const workflowService = new WorkflowService();
|
|
61
85
|
|
|
62
86
|
const result = await workflowService.initializeProject({
|
|
63
|
-
projectName: "
|
|
87
|
+
projectName: "vault-manager",
|
|
64
88
|
initMethod: "quick",
|
|
65
89
|
bootstrap: true,
|
|
66
90
|
aiOptions: {
|
|
@@ -78,96 +102,368 @@ const result = await workflowService.initializeProject({
|
|
|
78
102
|
console.log("Project initialized:", result.projectName);
|
|
79
103
|
```
|
|
80
104
|
|
|
81
|
-
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 🏗️ CORE SERVICES
|
|
82
108
|
|
|
83
109
|
### TaskService
|
|
84
110
|
|
|
85
|
-
Manages task lifecycle including creation, enhancement, splitting, and execution.
|
|
111
|
+
Manages task lifecycle including creation, enhancement, splitting, planning, and execution.
|
|
86
112
|
|
|
87
|
-
|
|
88
|
-
import { TaskService } from "task-o-matic-core";
|
|
113
|
+
#### Constructor
|
|
89
114
|
|
|
115
|
+
```typescript
|
|
90
116
|
const taskService = new TaskService();
|
|
117
|
+
```
|
|
91
118
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
119
|
+
#### Core CRUD Operations
|
|
120
|
+
|
|
121
|
+
**createTask**
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
const result = await taskService.createTask({
|
|
125
|
+
title: "Add emergency alert system",
|
|
126
|
+
content: "Implement real-time emergency notifications",
|
|
127
|
+
parentId: "task-123", // Optional: parent task ID
|
|
128
|
+
effort: "4h", // Optional: effort estimate
|
|
129
|
+
aiEnhance: true, // Enable AI enhancement
|
|
97
130
|
aiOptions: {
|
|
98
|
-
aiProvider: "
|
|
99
|
-
aiModel: "
|
|
100
|
-
aiKey: process.env.
|
|
131
|
+
aiProvider: "anthropic",
|
|
132
|
+
aiModel: "claude-3-5-sonnet",
|
|
133
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
134
|
+
},
|
|
135
|
+
streamingOptions: {
|
|
136
|
+
enabled: true,
|
|
137
|
+
onChunk: (chunk) => console.log(chunk),
|
|
138
|
+
onFinish: ({ text }) => console.log("Enhanced:", text),
|
|
139
|
+
},
|
|
140
|
+
callbacks: {
|
|
141
|
+
onProgress: (event) => console.log(event.message),
|
|
101
142
|
},
|
|
102
143
|
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**listTasks**
|
|
103
147
|
|
|
104
|
-
|
|
148
|
+
```typescript
|
|
149
|
+
// Get all tasks
|
|
105
150
|
const tasks = await taskService.listTasks();
|
|
106
151
|
|
|
107
|
-
//
|
|
108
|
-
const
|
|
152
|
+
// Filter by status
|
|
153
|
+
const todoTasks = await taskService.listTasks({ status: "todo" });
|
|
154
|
+
|
|
155
|
+
// Filter by tag
|
|
156
|
+
const criticalTasks = await taskService.listTasks({ tag: "critical" });
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**getTask**
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const task = await taskService.getTask("task-id-here");
|
|
163
|
+
console.log(task.title, task.status);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**getTaskContent**
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const content = await taskService.getTaskContent("task-id-here");
|
|
170
|
+
// Returns task content as string (for large tasks stored separately)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**getTaskAIMetadata**
|
|
109
174
|
|
|
110
|
-
|
|
111
|
-
const
|
|
175
|
+
```typescript
|
|
176
|
+
const metadata = await taskService.getTaskAIMetadata("task-id-here");
|
|
177
|
+
// Returns AI metadata: who enhanced, when, with which model
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**updateTask**
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const updated = await taskService.updateTask("task-id-here", {
|
|
184
|
+
title: "New title",
|
|
185
|
+
description: "New description",
|
|
112
186
|
status: "in-progress",
|
|
187
|
+
effort: "8h",
|
|
188
|
+
tags: ["critical", "security"],
|
|
113
189
|
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**setTaskStatus**
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
await taskService.setTaskStatus("task-id-here", "completed");
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**deleteTask**
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
await taskService.deleteTask("task-id-here", {
|
|
202
|
+
cascade: true, // Delete all subtasks
|
|
203
|
+
force: false, // Require confirmation (in TUI context)
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Tag Operations
|
|
208
|
+
|
|
209
|
+
**addTags**
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
await taskService.addTags("task-id-here", ["urgent", "security"]);
|
|
213
|
+
```
|
|
114
214
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
215
|
+
**removeTags**
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
await taskService.removeTags("task-id-here", ["deprecated"]);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### Task Navigation
|
|
222
|
+
|
|
223
|
+
**getNextTask**
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
const nextTask = await taskService.getNextTask({
|
|
227
|
+
status: "todo",
|
|
228
|
+
tag: "critical",
|
|
229
|
+
effort: "2-4h", // Filter by effort range
|
|
230
|
+
priority: "effort", // Sort by: newest, oldest, effort
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**getTaskTree**
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// Get full task tree
|
|
238
|
+
const fullTree = await taskService.getTaskTree();
|
|
239
|
+
|
|
240
|
+
// Get subtree starting from specific task
|
|
241
|
+
const subtree = await taskService.getTaskTree("task-id-here");
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**getSubtasks**
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const subtasks = await taskService.getSubtasks("task-id-here");
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
#### AI Operations
|
|
251
|
+
|
|
252
|
+
**enhanceTask**
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
const result = await taskService.enhanceTask("task-id-here", {
|
|
256
|
+
aiOptions: {
|
|
257
|
+
aiProvider: "anthropic",
|
|
258
|
+
aiModel: "claude-3-5-sonnet",
|
|
259
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
260
|
+
reasoning: 5000, // Enable reasoning tokens
|
|
261
|
+
},
|
|
262
|
+
streamingOptions: {
|
|
263
|
+
enabled: true,
|
|
264
|
+
onChunk: (chunk) => tuiTextArea.append(chunk),
|
|
265
|
+
onFinish: ({ text }) => tuiStatusBar.success("Enhanced!"),
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**splitTask**
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
const result = await taskService.splitTask("task-id-here", {
|
|
118
274
|
aiOptions: {
|
|
119
275
|
aiProvider: "anthropic",
|
|
120
276
|
aiModel: "claude-3-5-sonnet",
|
|
121
277
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
278
|
+
models: [ // Multi-AI splitting
|
|
279
|
+
{ provider: "anthropic", model: "claude-3.5-sonnet" },
|
|
280
|
+
{ provider: "openai", model: "gpt-4o" },
|
|
281
|
+
],
|
|
282
|
+
combineAI: { provider: "anthropic", model: "claude-3.5-sonnet" },
|
|
122
283
|
},
|
|
284
|
+
promptOverride: "Split into 2-4 hour tasks",
|
|
285
|
+
messageOverride: "Focus on security aspects",
|
|
286
|
+
streamingOptions: { enabled: true },
|
|
287
|
+
enableFilesystemTools: true, // Enable AI to read project files
|
|
123
288
|
});
|
|
289
|
+
// Supports splitting tasks that already have subtasks (creating sub-subtasks)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**documentTask**
|
|
124
293
|
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
294
|
+
```typescript
|
|
295
|
+
const result = await taskService.documentTask("task-id-here", {
|
|
296
|
+
force: false, // Skip if recent documentation exists
|
|
128
297
|
aiOptions: {
|
|
129
298
|
aiProvider: "anthropic",
|
|
130
299
|
aiModel: "claude-3-5-sonnet",
|
|
131
300
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
132
301
|
},
|
|
302
|
+
streamingOptions: { enabled: true },
|
|
133
303
|
});
|
|
134
304
|
```
|
|
135
305
|
|
|
136
|
-
|
|
306
|
+
**planTask**
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
const result = await taskService.planTask("task-id-here", {
|
|
310
|
+
aiOptions: {
|
|
311
|
+
aiProvider: "anthropic",
|
|
312
|
+
aiModel: "claude-3-5-sonnet",
|
|
313
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
314
|
+
},
|
|
315
|
+
streamingOptions: { enabled: true },
|
|
316
|
+
});
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### Documentation Operations
|
|
320
|
+
|
|
321
|
+
**getTaskDocumentation**
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
const docs = await taskService.getTaskDocumentation("task-id-here");
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**addTaskDocumentationFromFile**
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
await taskService.addTaskDocumentationFromFile("task-id-here", "./docs/api.md");
|
|
331
|
+
```
|
|
137
332
|
|
|
138
|
-
|
|
333
|
+
**setTaskPlan**
|
|
139
334
|
|
|
140
335
|
```typescript
|
|
141
|
-
|
|
336
|
+
// Set from text
|
|
337
|
+
await taskService.setTaskPlan("task-id-here", {
|
|
338
|
+
planText: "Step 1: Setup\nStep 2: Implement\nStep 3: Test",
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// Set from file
|
|
342
|
+
await taskService.setTaskPlan("task-id-here", {
|
|
343
|
+
planFilePath: "./plans/implementation.md",
|
|
344
|
+
});
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
#### Plan Operations
|
|
348
|
+
|
|
349
|
+
**getTaskPlan**
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
const plan = await taskService.getTaskPlan("task-id-here");
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**listTaskPlans**
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
const plans = await taskService.listTaskPlans();
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**deleteTaskPlan**
|
|
142
362
|
|
|
363
|
+
```typescript
|
|
364
|
+
await taskService.deleteTaskPlan("task-id-here");
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
### PRDService
|
|
370
|
+
|
|
371
|
+
Handles Product Requirements Document parsing, refinement, question generation, and versioning.
|
|
372
|
+
|
|
373
|
+
#### Constructor
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
143
376
|
const prdService = new PRDService();
|
|
377
|
+
```
|
|
144
378
|
|
|
145
|
-
|
|
146
|
-
|
|
379
|
+
#### PRD Operations
|
|
380
|
+
|
|
381
|
+
**parsePRD**
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
const result = await prdService.parsePRD({
|
|
147
385
|
file: "./requirements.md",
|
|
386
|
+
workingDirectory: process.cwd(),
|
|
387
|
+
enableFilesystemTools: true,
|
|
148
388
|
aiOptions: {
|
|
149
389
|
aiProvider: "anthropic",
|
|
150
390
|
aiModel: "claude-3-5-sonnet",
|
|
151
391
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
392
|
+
models: [ // Multi-AI parsing
|
|
393
|
+
{ provider: "anthropic", model: "claude-3.5-sonnet" },
|
|
394
|
+
{ provider: "openai", model: "gpt-4o" },
|
|
395
|
+
],
|
|
396
|
+
combineAI: { provider: "anthropic", model: "claude-3.5-sonnet" },
|
|
152
397
|
},
|
|
398
|
+
promptOverride: "Focus on security features",
|
|
399
|
+
messageOverride: "Include emergency protocols",
|
|
400
|
+
streamingOptions: { enabled: true },
|
|
153
401
|
callbacks: {
|
|
154
|
-
onProgress: (event) =>
|
|
155
|
-
|
|
156
|
-
|
|
402
|
+
onProgress: (event) => console.log(event.message),
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
console.log("PRD parsed:", result.prd);
|
|
407
|
+
console.log("Tasks generated:", result.tasks);
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**generateQuestions**
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
const result = await prdService.generateQuestions({
|
|
414
|
+
file: "./requirements.md",
|
|
415
|
+
workingDirectory: process.cwd(),
|
|
416
|
+
enableFilesystemTools: true,
|
|
417
|
+
aiOptions: {
|
|
418
|
+
aiProvider: "anthropic",
|
|
419
|
+
aiModel: "claude-3-5-sonnet",
|
|
420
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
421
|
+
},
|
|
422
|
+
streamingOptions: { enabled: true },
|
|
423
|
+
callbacks: {
|
|
424
|
+
onProgress: (event) => console.log(event.message),
|
|
157
425
|
},
|
|
158
426
|
});
|
|
159
427
|
|
|
160
|
-
console.log("
|
|
428
|
+
console.log("Questions:", result.questions);
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**reworkPRD**
|
|
161
432
|
|
|
162
|
-
|
|
163
|
-
const
|
|
433
|
+
```typescript
|
|
434
|
+
const result = await prdService.reworkPRD({
|
|
435
|
+
file: "./requirements.md",
|
|
436
|
+
feedback: "Add more details about security requirements and emergency procedures",
|
|
437
|
+
output: "./reworked-requirements.md",
|
|
438
|
+
workingDirectory: process.cwd(),
|
|
439
|
+
enableFilesystemTools: true,
|
|
440
|
+
aiOptions: {
|
|
441
|
+
aiProvider: "anthropic",
|
|
442
|
+
aiModel: "claude-3-5-sonnet",
|
|
443
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
444
|
+
},
|
|
445
|
+
streamingOptions: { enabled: true },
|
|
446
|
+
callbacks: {
|
|
447
|
+
onProgress: (event) => console.log(event.message),
|
|
448
|
+
},
|
|
449
|
+
});
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**refinePRDWithQuestions**
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
const result = await prdService.refinePRDWithQuestions({
|
|
164
456
|
file: "./requirements.md",
|
|
165
457
|
questionMode: "ai", // or "user" for interactive
|
|
166
|
-
|
|
167
|
-
|
|
458
|
+
answers: { // Only for user mode
|
|
459
|
+
"q1": "Answer to question 1",
|
|
460
|
+
"q2": "Answer to question 2",
|
|
461
|
+
},
|
|
462
|
+
questionAIOptions: { // Only for AI mode
|
|
168
463
|
aiProvider: "openrouter",
|
|
169
464
|
aiModel: "anthropic/claude-3-opus",
|
|
170
465
|
aiReasoning: "enabled", // Enable reasoning for better answers
|
|
466
|
+
aiKey: process.env.OPENROUTER_API_KEY,
|
|
171
467
|
},
|
|
172
468
|
workingDirectory: process.cwd(),
|
|
173
469
|
aiOptions: {
|
|
@@ -175,195 +471,407 @@ const refineResult = await prdService.refinePRDWithQuestions({
|
|
|
175
471
|
aiModel: "claude-3-5-sonnet",
|
|
176
472
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
177
473
|
},
|
|
474
|
+
streamingOptions: { enabled: true },
|
|
178
475
|
callbacks: {
|
|
179
|
-
onProgress: (event) =>
|
|
180
|
-
console.log(event.message);
|
|
181
|
-
},
|
|
476
|
+
onProgress: (event) => console.log(event.message),
|
|
182
477
|
},
|
|
183
478
|
});
|
|
184
479
|
|
|
185
|
-
console.log(`Refined PRD with ${
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
480
|
+
console.log(`Refined PRD with ${result.questions.length} questions`);
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
**generatePRD**
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
const result = await prdService.generatePRD({
|
|
487
|
+
description: "Build a vault management system for tracking supplies, residents, and security",
|
|
488
|
+
outputDir: "./prds",
|
|
489
|
+
filename: "vault-manager-prd.md",
|
|
490
|
+
aiOptions: {
|
|
491
|
+
aiProvider: "anthropic",
|
|
492
|
+
aiModel: "claude-3-5-sonnet",
|
|
493
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
494
|
+
},
|
|
495
|
+
streamingOptions: { enabled: true },
|
|
496
|
+
callbacks: {
|
|
497
|
+
onProgress: (event) => console.log(event.message),
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
**combinePRDs**
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
const result = await prdService.combinePRDs({
|
|
506
|
+
prds: ["./prds/prd1.md", "./prds/prd2.md"],
|
|
507
|
+
originalDescription: "Original vault manager description",
|
|
508
|
+
outputDir: "./prds",
|
|
509
|
+
filename: "combined-prd.md",
|
|
510
|
+
aiOptions: {
|
|
511
|
+
aiProvider: "anthropic",
|
|
512
|
+
aiModel: "claude-3-5-sonnet",
|
|
513
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
514
|
+
},
|
|
515
|
+
streamingOptions: { enabled: true },
|
|
516
|
+
callbacks: {
|
|
517
|
+
onProgress: (event) => console.log(event.message),
|
|
518
|
+
},
|
|
189
519
|
});
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
**suggestStack**
|
|
190
523
|
|
|
191
|
-
|
|
192
|
-
const
|
|
524
|
+
```typescript
|
|
525
|
+
const result = await prdService.suggestStack({
|
|
193
526
|
file: "./requirements.md",
|
|
194
|
-
|
|
527
|
+
// or
|
|
528
|
+
content: "Vault management system with real-time tracking",
|
|
529
|
+
projectName: "vault-manager",
|
|
530
|
+
output: "./stack-suggestion.json",
|
|
531
|
+
workingDirectory: process.cwd(),
|
|
532
|
+
save: true, // Save to .task-o-matic/stack.json
|
|
195
533
|
aiOptions: {
|
|
196
534
|
aiProvider: "anthropic",
|
|
197
535
|
aiModel: "claude-3-5-sonnet",
|
|
198
536
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
199
537
|
},
|
|
538
|
+
streamingOptions: { enabled: true },
|
|
539
|
+
callbacks: {
|
|
540
|
+
onProgress: (event) => console.log(event.message),
|
|
541
|
+
},
|
|
200
542
|
});
|
|
543
|
+
|
|
544
|
+
console.log("Suggested stack:", result.stack);
|
|
201
545
|
```
|
|
202
546
|
|
|
203
|
-
|
|
547
|
+
**generateFromCodebase**
|
|
204
548
|
|
|
205
|
-
|
|
549
|
+
```typescript
|
|
550
|
+
const result = await prdService.generateFromCodebase({
|
|
551
|
+
workingDirectory: process.cwd(),
|
|
552
|
+
outputFile: "./generated-prd.md",
|
|
553
|
+
enableFilesystemTools: true,
|
|
554
|
+
aiOptions: {
|
|
555
|
+
aiProvider: "anthropic",
|
|
556
|
+
aiModel: "claude-3-5-sonnet",
|
|
557
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
558
|
+
},
|
|
559
|
+
streamingOptions: { enabled: true },
|
|
560
|
+
callbacks: {
|
|
561
|
+
onProgress: (event) => console.log(event.message),
|
|
562
|
+
},
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
console.log("Generated PRD from codebase:", result.prd);
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
#### PRD Versioning
|
|
569
|
+
|
|
570
|
+
**createVersion**
|
|
206
571
|
|
|
207
572
|
```typescript
|
|
208
|
-
|
|
573
|
+
const result = await prdService.createVersion({
|
|
574
|
+
file: "./requirements.md",
|
|
575
|
+
message: "Added emergency response section",
|
|
576
|
+
changes: [
|
|
577
|
+
{ type: "add", section: "Emergency Protocols" },
|
|
578
|
+
{ type: "modify", section: "Security", description: "Added biometric auth" },
|
|
579
|
+
],
|
|
580
|
+
implementedTasks: ["task-123", "task-456"],
|
|
581
|
+
workingDirectory: process.cwd(),
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
console.log("Version created:", result.version);
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
**getHistory**
|
|
588
|
+
|
|
589
|
+
```typescript
|
|
590
|
+
const history = await prdService.getHistory({
|
|
591
|
+
file: "./requirements.md",
|
|
592
|
+
workingDirectory: process.cwd(),
|
|
593
|
+
});
|
|
209
594
|
|
|
595
|
+
history.versions.forEach((version) => {
|
|
596
|
+
console.log(`Version ${version.number}: ${version.message}`);
|
|
597
|
+
console.log(`Created: ${new Date(version.timestamp).toISOString()}`);
|
|
598
|
+
console.log(`Changes: ${version.changes.length}`);
|
|
599
|
+
});
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
---
|
|
603
|
+
|
|
604
|
+
### WorkflowService
|
|
605
|
+
|
|
606
|
+
Provides complete project lifecycle management from initialization to task generation and execution.
|
|
607
|
+
|
|
608
|
+
#### Constructor
|
|
609
|
+
|
|
610
|
+
```typescript
|
|
210
611
|
const workflowService = new WorkflowService();
|
|
612
|
+
```
|
|
211
613
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
614
|
+
#### Workflow Methods
|
|
615
|
+
|
|
616
|
+
**initializeProject**
|
|
617
|
+
|
|
618
|
+
```typescript
|
|
619
|
+
const result = await workflowService.initializeProject({
|
|
620
|
+
projectName: "vault-manager",
|
|
621
|
+
projectDir: process.cwd(),
|
|
622
|
+
initMethod: "ai", // "quick", "custom", or "ai"
|
|
623
|
+
projectDescription: "Comprehensive vault management system",
|
|
624
|
+
stackConfig: {
|
|
625
|
+
frontend: "next",
|
|
626
|
+
backend: "hono",
|
|
627
|
+
database: "postgres",
|
|
628
|
+
auth: true,
|
|
629
|
+
},
|
|
216
630
|
bootstrap: true,
|
|
631
|
+
includeDocs: true,
|
|
217
632
|
aiOptions: {
|
|
218
633
|
aiProvider: "anthropic",
|
|
219
634
|
aiModel: "claude-3-5-sonnet",
|
|
220
635
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
221
636
|
},
|
|
637
|
+
streamingOptions: { enabled: true },
|
|
222
638
|
callbacks: {
|
|
223
|
-
onProgress: (event) => {
|
|
224
|
-
console.log(`Progress: ${event.message}`);
|
|
225
|
-
},
|
|
639
|
+
onProgress: (event) => console.log(`Progress: ${event.message}`),
|
|
226
640
|
},
|
|
227
641
|
});
|
|
228
642
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
643
|
+
console.log("Project initialized:", result.projectName);
|
|
644
|
+
console.log("PRD created:", result.prdPath);
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
**definePRD**
|
|
648
|
+
|
|
649
|
+
```typescript
|
|
650
|
+
const result = await workflowService.definePRD({
|
|
651
|
+
method: "ai", // "upload", "manual", "ai", or "skip"
|
|
652
|
+
prdDescription: "Vault management system with real-time tracking",
|
|
653
|
+
projectDir: process.cwd(),
|
|
654
|
+
multiGeneration: true,
|
|
655
|
+
multiGenerationModels: [
|
|
656
|
+
{ provider: "anthropic", model: "claude-3.5-sonnet" },
|
|
657
|
+
{ provider: "openai", model: "gpt-4o" },
|
|
658
|
+
],
|
|
659
|
+
combineAI: { provider: "anthropic", model: "claude-3.5-sonnet" },
|
|
233
660
|
aiOptions: {
|
|
234
661
|
aiProvider: "anthropic",
|
|
235
662
|
aiModel: "claude-3-5-sonnet",
|
|
236
663
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
237
664
|
},
|
|
665
|
+
streamingOptions: { enabled: true },
|
|
238
666
|
callbacks: {
|
|
239
|
-
onProgress: (event) =>
|
|
240
|
-
console.log(event.message);
|
|
241
|
-
},
|
|
667
|
+
onProgress: (event) => console.log(event.message),
|
|
242
668
|
},
|
|
243
669
|
});
|
|
244
670
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
671
|
+
console.log("PRD defined:", result.prdPath);
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
**refinePRD**
|
|
675
|
+
|
|
676
|
+
```typescript
|
|
677
|
+
const result = await workflowService.refinePRD({
|
|
678
|
+
method: "ai", // "manual", "ai", or "skip"
|
|
679
|
+
prdFile: "./requirements.md",
|
|
680
|
+
feedback: "Add more security protocols and emergency procedures",
|
|
681
|
+
projectDir: process.cwd(),
|
|
248
682
|
aiOptions: {
|
|
249
683
|
aiProvider: "anthropic",
|
|
250
684
|
aiModel: "claude-3-5-sonnet",
|
|
251
685
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
252
686
|
},
|
|
687
|
+
streamingOptions: { enabled: true },
|
|
253
688
|
callbacks: {
|
|
254
|
-
onProgress: (event) =>
|
|
255
|
-
console.log(event.message);
|
|
256
|
-
},
|
|
689
|
+
onProgress: (event) => console.log(event.message),
|
|
257
690
|
},
|
|
258
691
|
});
|
|
259
692
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
693
|
+
console.log("PRD refined:", result.prdPath);
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
**generateTasks**
|
|
697
|
+
|
|
698
|
+
```typescript
|
|
699
|
+
const result = await workflowService.generateTasks({
|
|
700
|
+
prdFile: "./requirements.md",
|
|
701
|
+
method: "standard", // "standard" or "ai"
|
|
702
|
+
customInstructions: "Break down into 2-4 hour tasks focused on MVP",
|
|
703
|
+
projectDir: process.cwd(),
|
|
263
704
|
aiOptions: {
|
|
264
705
|
aiProvider: "anthropic",
|
|
265
706
|
aiModel: "claude-3-5-sonnet",
|
|
266
707
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
267
708
|
},
|
|
709
|
+
streamingOptions: { enabled: true },
|
|
268
710
|
callbacks: {
|
|
269
|
-
onProgress: (event) =>
|
|
270
|
-
console.log(event.message);
|
|
271
|
-
},
|
|
711
|
+
onProgress: (event) => console.log(event.message),
|
|
272
712
|
},
|
|
273
713
|
});
|
|
274
714
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
715
|
+
console.log(`Generated ${result.tasks.length} tasks`);
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
**splitTasks**
|
|
719
|
+
|
|
720
|
+
```typescript
|
|
721
|
+
const result = await workflowService.splitTasks({
|
|
722
|
+
taskIds: ["task-1", "task-2", "task-3"],
|
|
723
|
+
splitMethod: "custom", // "interactive", "standard", or "custom"
|
|
724
|
+
customInstructions: "Split into 2-4 hour chunks",
|
|
278
725
|
aiOptions: {
|
|
279
726
|
aiProvider: "anthropic",
|
|
280
727
|
aiModel: "claude-3-5-sonnet",
|
|
281
728
|
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
282
729
|
},
|
|
730
|
+
streamingOptions: { enabled: true },
|
|
283
731
|
callbacks: {
|
|
284
|
-
onProgress: (event) =>
|
|
285
|
-
console.log(event.message);
|
|
286
|
-
},
|
|
732
|
+
onProgress: (event) => console.log(event.message),
|
|
287
733
|
},
|
|
288
734
|
});
|
|
289
|
-
```
|
|
290
735
|
|
|
291
|
-
|
|
736
|
+
console.log(`Split ${result.splits} tasks`);
|
|
737
|
+
```
|
|
292
738
|
|
|
293
|
-
|
|
739
|
+
**continueProject**
|
|
294
740
|
|
|
295
741
|
```typescript
|
|
296
|
-
|
|
742
|
+
const result = await workflowService.continueProject({
|
|
743
|
+
projectDir: process.cwd(),
|
|
744
|
+
action: "update-prd", // ContinueAction options
|
|
745
|
+
aiOptions: {
|
|
746
|
+
aiProvider: "anthropic",
|
|
747
|
+
aiModel: "claude-3-5-sonnet",
|
|
748
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
749
|
+
},
|
|
750
|
+
streamingOptions: { enabled: true },
|
|
751
|
+
callbacks: {
|
|
752
|
+
onProgress: (event) => console.log(event.message),
|
|
753
|
+
},
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
console.log("Project continued:", result.status);
|
|
757
|
+
```
|
|
297
758
|
|
|
298
|
-
|
|
759
|
+
**executeTasks**
|
|
299
760
|
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
761
|
+
```typescript
|
|
762
|
+
const { success, result } = await workflowService.executeTasks({
|
|
763
|
+
options: {
|
|
764
|
+
status: "todo",
|
|
765
|
+
tool: "opencode",
|
|
766
|
+
maxRetries: 3,
|
|
767
|
+
tryModels: [
|
|
768
|
+
{ provider: "openai", model: "gpt-4o-mini" },
|
|
769
|
+
{ provider: "openai", model: "gpt-4o" },
|
|
770
|
+
{ provider: "anthropic", model: "claude-3.5-sonnet" },
|
|
771
|
+
],
|
|
772
|
+
verify: "bun test",
|
|
773
|
+
plan: true,
|
|
774
|
+
review: true,
|
|
775
|
+
autoCommit: true,
|
|
776
|
+
},
|
|
777
|
+
callbacks: {
|
|
778
|
+
onProgress: (event) => console.log(event.message),
|
|
305
779
|
},
|
|
306
|
-
models: [
|
|
307
|
-
{
|
|
308
|
-
provider: "openai",
|
|
309
|
-
model: "gpt-4o",
|
|
310
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
311
|
-
},
|
|
312
|
-
{
|
|
313
|
-
provider: "anthropic",
|
|
314
|
-
model: "claude-3-5-sonnet",
|
|
315
|
-
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
316
|
-
},
|
|
317
|
-
],
|
|
318
|
-
concurrency: 2,
|
|
319
|
-
delay: 1000,
|
|
320
780
|
});
|
|
321
781
|
|
|
322
|
-
console.log(
|
|
782
|
+
console.log(`Executed ${result.completed} tasks successfully`);
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
---
|
|
786
|
+
|
|
787
|
+
### BenchmarkOrchestrator
|
|
788
|
+
|
|
789
|
+
Compare AI model performance using parallel git worktrees.
|
|
790
|
+
|
|
791
|
+
#### Constructor
|
|
792
|
+
|
|
793
|
+
```typescript
|
|
794
|
+
const benchmark = new BenchmarkOrchestrator();
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
#### Run Benchmark
|
|
323
798
|
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
type:
|
|
327
|
-
|
|
328
|
-
|
|
799
|
+
```typescript
|
|
800
|
+
const run = await benchmark.run(
|
|
801
|
+
"operation", // type: execution, execute-loop, operation, workflow
|
|
802
|
+
{
|
|
803
|
+
operationId: "prd-parse",
|
|
804
|
+
params: { file: "./requirements.md" }
|
|
329
805
|
},
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
provider: "openai",
|
|
333
|
-
model: "
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
806
|
+
{
|
|
807
|
+
models: [
|
|
808
|
+
{ provider: "openai", model: "gpt-4o" },
|
|
809
|
+
{ provider: "anthropic", model: "claude-3-5-sonnet" }
|
|
810
|
+
],
|
|
811
|
+
concurrency: 2,
|
|
812
|
+
keepWorktrees: true
|
|
813
|
+
},
|
|
814
|
+
(event) => {
|
|
815
|
+
console.log(`[${event.modelId}] ${event.type}: ${event.message || ""}`);
|
|
816
|
+
}
|
|
817
|
+
);
|
|
818
|
+
|
|
819
|
+
console.log("Run ID:", run.id);
|
|
820
|
+
console.log("Results:", run.results);
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
#### Management Methods
|
|
824
|
+
|
|
825
|
+
**listRuns**
|
|
826
|
+
|
|
827
|
+
```typescript
|
|
828
|
+
const runs = await benchmark.listRuns({ limit: 10 });
|
|
344
829
|
```
|
|
345
830
|
|
|
346
|
-
|
|
831
|
+
**getRun**
|
|
832
|
+
|
|
833
|
+
```typescript
|
|
834
|
+
const run = await benchmark.getRun("run-id-123");
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
**listWorktrees**
|
|
838
|
+
|
|
839
|
+
```typescript
|
|
840
|
+
const worktrees = await benchmark.listWorktrees();
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
**cleanupRun**
|
|
844
|
+
|
|
845
|
+
```typescript
|
|
846
|
+
await benchmark.cleanupRun("run-id-123");
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
851
|
+
## 🌊 STREAMING SUPPORT
|
|
347
852
|
|
|
348
853
|
Stream AI responses in real-time for better user experience.
|
|
349
854
|
|
|
855
|
+
### Basic Streaming
|
|
856
|
+
|
|
350
857
|
```typescript
|
|
351
858
|
import { TaskService } from "task-o-matic-core";
|
|
352
859
|
|
|
353
860
|
const taskService = new TaskService();
|
|
354
861
|
|
|
355
|
-
// Create task with streaming
|
|
356
862
|
const result = await taskService.createTask({
|
|
357
|
-
title: "Add
|
|
863
|
+
title: "Add emergency alert system",
|
|
358
864
|
aiEnhance: true,
|
|
359
865
|
streamingOptions: {
|
|
360
866
|
enabled: true,
|
|
361
867
|
onChunk: (chunk) => {
|
|
362
|
-
|
|
363
|
-
|
|
868
|
+
console.log("Streaming:", chunk);
|
|
869
|
+
},
|
|
870
|
+
onReasoning: (text) => {
|
|
871
|
+
console.log("AI thinking:", text); // For OpenRouter reasoning models
|
|
364
872
|
},
|
|
365
873
|
onFinish: ({ text }) => {
|
|
366
|
-
console.log("Streaming complete
|
|
874
|
+
console.log("Streaming complete:", text.length, "characters");
|
|
367
875
|
},
|
|
368
876
|
},
|
|
369
877
|
aiOptions: {
|
|
@@ -374,41 +882,71 @@ const result = await taskService.createTask({
|
|
|
374
882
|
});
|
|
375
883
|
```
|
|
376
884
|
|
|
377
|
-
|
|
885
|
+
### TUI Integration Example
|
|
378
886
|
|
|
379
887
|
```typescript
|
|
380
888
|
import { TaskService } from "task-o-matic-core";
|
|
381
|
-
import type { ProgressCallback } from "task-o-matic-core";
|
|
382
889
|
|
|
383
890
|
const taskService = new TaskService();
|
|
384
891
|
|
|
385
892
|
// Progress callback for TUI updates
|
|
386
|
-
const
|
|
893
|
+
const callbacks = {
|
|
387
894
|
onProgress: (event) => {
|
|
388
|
-
// Update your TUI with progress
|
|
389
895
|
tuiStatusBar.update(event.message);
|
|
390
896
|
},
|
|
391
897
|
};
|
|
392
898
|
|
|
393
899
|
// Create task with streaming
|
|
394
900
|
const result = await taskService.createTask({
|
|
395
|
-
title: "
|
|
901
|
+
title: "Implement biometric authentication",
|
|
396
902
|
aiEnhance: true,
|
|
397
903
|
streamingOptions: {
|
|
398
904
|
enabled: true,
|
|
399
905
|
onChunk: (chunk) => {
|
|
400
906
|
// Update TUI in real-time
|
|
401
907
|
tuiTextArea.append(chunk);
|
|
908
|
+
tuiLayout.render();
|
|
909
|
+
},
|
|
910
|
+
onReasoning: (text) => {
|
|
911
|
+
tuiStatusBar.update(`AI thinking: ${text.substring(0, 50)}...`);
|
|
402
912
|
},
|
|
403
913
|
onFinish: ({ text }) => {
|
|
404
|
-
tuiStatusBar.success("Task enhanced!");
|
|
914
|
+
tuiStatusBar.success("Task enhanced successfully!");
|
|
915
|
+
tuiLayout.render();
|
|
405
916
|
},
|
|
406
917
|
},
|
|
407
|
-
callbacks
|
|
918
|
+
callbacks,
|
|
408
919
|
});
|
|
409
920
|
```
|
|
410
921
|
|
|
411
|
-
|
|
922
|
+
---
|
|
923
|
+
|
|
924
|
+
## 📚 CONTEXT7 INTEGRATION
|
|
925
|
+
|
|
926
|
+
Access up-to-date library documentation automatically.
|
|
927
|
+
|
|
928
|
+
```typescript
|
|
929
|
+
import { TaskService } from "task-o-matic-core";
|
|
930
|
+
|
|
931
|
+
const taskService = new TaskService();
|
|
932
|
+
|
|
933
|
+
// Task enhancement will fetch relevant docs
|
|
934
|
+
const result = await taskService.enhanceTask("task-id-here", {
|
|
935
|
+
aiOptions: {
|
|
936
|
+
aiProvider: "anthropic",
|
|
937
|
+
aiModel: "claude-3-5-sonnet",
|
|
938
|
+
aiKey: process.env.ANTHROPIC_API_KEY,
|
|
939
|
+
},
|
|
940
|
+
// Context7 will automatically fetch docs for libraries in your stack
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
// Documentation is cached in .task-o-matic/docs/{library-name}/
|
|
944
|
+
// Subsequent calls use cached docs for performance
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
---
|
|
948
|
+
|
|
949
|
+
## 🔧 UTILITY FUNCTIONS
|
|
412
950
|
|
|
413
951
|
Access core utilities directly:
|
|
414
952
|
|
|
@@ -416,13 +954,18 @@ Access core utilities directly:
|
|
|
416
954
|
import {
|
|
417
955
|
getStorage,
|
|
418
956
|
getAIOperations,
|
|
957
|
+
getModelProvider,
|
|
958
|
+
getContextBuilder,
|
|
419
959
|
buildAIConfig,
|
|
420
960
|
configManager,
|
|
961
|
+
logger,
|
|
421
962
|
} from "task-o-matic-core";
|
|
422
963
|
|
|
423
964
|
// Get singleton instances
|
|
424
965
|
const storage = getStorage();
|
|
425
966
|
const aiOps = getAIOperations();
|
|
967
|
+
const modelProvider = getModelProvider();
|
|
968
|
+
const contextBuilder = getContextBuilder();
|
|
426
969
|
|
|
427
970
|
// Build AI configuration
|
|
428
971
|
const aiConfig = buildAIConfig({
|
|
@@ -437,38 +980,99 @@ const allTasks = await storage.getAllTasks();
|
|
|
437
980
|
// Use config manager
|
|
438
981
|
await configManager.load();
|
|
439
982
|
const aiProvider = configManager.getAIProvider();
|
|
983
|
+
|
|
984
|
+
// Use logger
|
|
985
|
+
logger.info("Starting project initialization");
|
|
986
|
+
logger.error("Failed to parse PRD", { error });
|
|
440
987
|
```
|
|
441
988
|
|
|
442
|
-
|
|
989
|
+
---
|
|
990
|
+
|
|
991
|
+
## 📝 TYPESCRIPT TYPES
|
|
443
992
|
|
|
444
993
|
Full TypeScript type definitions are included:
|
|
445
994
|
|
|
446
995
|
```typescript
|
|
447
996
|
import type {
|
|
997
|
+
// Core Types
|
|
448
998
|
Task,
|
|
999
|
+
CreateTaskOptions,
|
|
1000
|
+
CreateTaskResult,
|
|
1001
|
+
EnhanceTaskResult,
|
|
1002
|
+
SplitTaskResult,
|
|
1003
|
+
PlanTaskResult,
|
|
1004
|
+
DocumentTaskResult,
|
|
1005
|
+
DeleteTaskResult,
|
|
1006
|
+
TaskListResponse,
|
|
1007
|
+
TaskAIMetadata,
|
|
1008
|
+
TaskDocumentation,
|
|
1009
|
+
|
|
1010
|
+
// AI Types
|
|
449
1011
|
AIConfig,
|
|
1012
|
+
AIOptions,
|
|
450
1013
|
StreamingOptions,
|
|
451
|
-
|
|
1014
|
+
StreamingCallbacks,
|
|
1015
|
+
ProviderConfig,
|
|
1016
|
+
AIServiceResponse,
|
|
1017
|
+
|
|
1018
|
+
// PRD Types
|
|
452
1019
|
PRDParseResult,
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
1020
|
+
PRDFromCodebaseResult,
|
|
1021
|
+
SuggestStackResult,
|
|
1022
|
+
PRDChange,
|
|
1023
|
+
PRDVersion,
|
|
1024
|
+
PRDVersionData,
|
|
1025
|
+
|
|
1026
|
+
// Workflow Types
|
|
456
1027
|
InitializeResult,
|
|
457
1028
|
DefinePRDResult,
|
|
458
1029
|
RefinePRDResult,
|
|
459
1030
|
GenerateTasksResult,
|
|
460
1031
|
SplitTasksResult,
|
|
461
|
-
|
|
462
|
-
|
|
1032
|
+
ContinueResult,
|
|
1033
|
+
WorkflowOptions,
|
|
1034
|
+
ContinueAction,
|
|
1035
|
+
|
|
1036
|
+
// Benchmark Types
|
|
1037
|
+
BenchmarkOrchestrator,
|
|
463
1038
|
BenchmarkConfig,
|
|
464
1039
|
BenchmarkResult,
|
|
465
|
-
|
|
1040
|
+
BenchmarkRun,
|
|
1041
|
+
BenchmarkProgressEvent,
|
|
1042
|
+
|
|
1043
|
+
// Execution Types
|
|
1044
|
+
ExecuteTaskOptions,
|
|
1045
|
+
ExecutionResult,
|
|
1046
|
+
ExecuteLoopOptions,
|
|
1047
|
+
ExecuteLoopResult,
|
|
1048
|
+
ExecuteLoopConfig,
|
|
1049
|
+
TaskExecutionResult,
|
|
1050
|
+
|
|
1051
|
+
// Callback Types
|
|
466
1052
|
ProgressCallback,
|
|
467
1053
|
StorageCallbacks,
|
|
1054
|
+
|
|
1055
|
+
// Project Analysis Types
|
|
1056
|
+
ProjectAnalysis,
|
|
1057
|
+
ProjectAnalysisOptions,
|
|
1058
|
+
ProjectAnalysisResult,
|
|
1059
|
+
DetectedStack,
|
|
1060
|
+
ProjectStructure,
|
|
1061
|
+
|
|
1062
|
+
// Error Types
|
|
1063
|
+
TaskOMaticError,
|
|
1064
|
+
|
|
1065
|
+
// Services
|
|
1066
|
+
TaskService,
|
|
1067
|
+
WorkflowService,
|
|
1068
|
+
PRDService,
|
|
1069
|
+
BenchmarkOrchestrator,
|
|
468
1070
|
} from "task-o-matic-core";
|
|
469
1071
|
```
|
|
470
1072
|
|
|
471
|
-
|
|
1073
|
+
---
|
|
1074
|
+
|
|
1075
|
+
## 🤖 AI PROVIDERS
|
|
472
1076
|
|
|
473
1077
|
### Supported Providers
|
|
474
1078
|
|
|
@@ -496,11 +1100,12 @@ const anthropicConfig = buildAIConfig({
|
|
|
496
1100
|
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
497
1101
|
});
|
|
498
1102
|
|
|
499
|
-
// OpenRouter
|
|
1103
|
+
// OpenRouter with reasoning
|
|
500
1104
|
const openrouterConfig = buildAIConfig({
|
|
501
1105
|
provider: "openrouter",
|
|
502
1106
|
model: "anthropic/claude-3.5-sonnet",
|
|
503
1107
|
apiKey: process.env.OPENROUTER_API_KEY,
|
|
1108
|
+
reasoning: 5000, // Enable extended reasoning
|
|
504
1109
|
});
|
|
505
1110
|
|
|
506
1111
|
// Custom provider
|
|
@@ -514,32 +1119,85 @@ const customConfig = buildAIConfig({
|
|
|
514
1119
|
|
|
515
1120
|
### Model Recommendations
|
|
516
1121
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
- **
|
|
520
|
-
- **
|
|
1122
|
+
Based on extensive field testing:
|
|
1123
|
+
|
|
1124
|
+
- **PRD Parsing**: `anthropic:claude-3.5-sonnet` or `openai:gpt-4o`
|
|
1125
|
+
- **Task Enhancement**: `openai:gpt-4o-mini` or `anthropic:claude-3-haiku`
|
|
1126
|
+
- **Task Breakdown**: `anthropic:claude-3.5-sonnet`
|
|
1127
|
+
- **Workflow Testing**: Use benchmarking. Let the data decide.
|
|
521
1128
|
|
|
522
|
-
|
|
1129
|
+
### Multi-AI Operations
|
|
1130
|
+
|
|
1131
|
+
Let multiple AI models work together for superior results:
|
|
1132
|
+
|
|
1133
|
+
```typescript
|
|
1134
|
+
const result = await taskService.splitTask("task-id-here", {
|
|
1135
|
+
aiOptions: {
|
|
1136
|
+
models: [
|
|
1137
|
+
{ provider: "anthropic", model: "claude-3.5-sonnet", aiKey: key1 },
|
|
1138
|
+
{ provider: "openai", model: "gpt-4o", aiKey: key2 },
|
|
1139
|
+
],
|
|
1140
|
+
combineAI: {
|
|
1141
|
+
provider: "anthropic",
|
|
1142
|
+
model: "claude-3.5-sonnet",
|
|
1143
|
+
aiKey: key1,
|
|
1144
|
+
},
|
|
1145
|
+
},
|
|
1146
|
+
});
|
|
1147
|
+
|
|
1148
|
+
// Multiple models approach the problem from different angles
|
|
1149
|
+
// The combineAI model synthesizes the best results
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
---
|
|
1153
|
+
|
|
1154
|
+
## 💾 STORAGE STRUCTURE
|
|
523
1155
|
|
|
524
1156
|
All data is stored locally in the `.task-o-matic/` directory:
|
|
525
1157
|
|
|
526
1158
|
```
|
|
527
1159
|
your-project/
|
|
528
1160
|
├── .task-o-matic/
|
|
529
|
-
│ ├── config.json
|
|
530
|
-
│ ├──
|
|
531
|
-
│ ├──
|
|
532
|
-
│
|
|
533
|
-
│
|
|
534
|
-
│ ├──
|
|
1161
|
+
│ ├── config.json # AI configuration
|
|
1162
|
+
│ ├── stack.json # Detected technology stack (cached)
|
|
1163
|
+
│ ├── bts-config.json # Better-T-Stack configuration
|
|
1164
|
+
│ ├── mcp.json # Context7/MCP configuration
|
|
1165
|
+
│ ├── tasks.json # Main tasks database
|
|
1166
|
+
│ ├── ai-metadata.json # AI metadata for all tasks
|
|
1167
|
+
│ │
|
|
1168
|
+
│ ├── tasks/ # Task content files
|
|
1169
|
+
│ │ ├── {task-id}.md
|
|
1170
|
+
│ │ └── enhanced/
|
|
1171
|
+
│ │ └── {task-id}.md
|
|
1172
|
+
│ │
|
|
1173
|
+
│ ├── plans/ # Implementation plans
|
|
1174
|
+
│ │ └── {task-id}.json
|
|
1175
|
+
│ │
|
|
1176
|
+
│ ├── docs/ # Documentation
|
|
1177
|
+
│ │ ├── tasks/ # Task-specific documentation
|
|
1178
|
+
│ │ └── {library-name}/ # Context7 library docs (cached)
|
|
1179
|
+
│ │
|
|
1180
|
+
│ ├── prd/ # PRD versions and logs
|
|
1181
|
+
│ │ ├── versions/ # PRD versioning history
|
|
1182
|
+
│ │ │ ├── v1.json
|
|
1183
|
+
│ │ │ ├── v2.json
|
|
1184
|
+
│ │ │ └── ...
|
|
535
1185
|
│ │ ├── parsed-prd.json
|
|
536
|
-
│ │ └──
|
|
537
|
-
│
|
|
538
|
-
│
|
|
1186
|
+
│ │ └── (user prd files)
|
|
1187
|
+
│ │
|
|
1188
|
+
│ └── logs/ # Operation logs
|
|
539
1189
|
└── your-project-files...
|
|
540
1190
|
```
|
|
541
1191
|
|
|
542
|
-
|
|
1192
|
+
**Key notes:**
|
|
1193
|
+
- Tasks with content >200 characters are stored as separate files
|
|
1194
|
+
- AI metadata tracks who enhanced what, when, and with which model
|
|
1195
|
+
- PRD versioning lets you track evolution over time
|
|
1196
|
+
- Documentation from Context7 is cached to avoid repeated API calls
|
|
1197
|
+
|
|
1198
|
+
---
|
|
1199
|
+
|
|
1200
|
+
## ⚠️ ERROR HANDLING
|
|
543
1201
|
|
|
544
1202
|
```typescript
|
|
545
1203
|
import { TaskService, TaskOMaticError } from "task-o-matic-core";
|
|
@@ -561,86 +1219,152 @@ try {
|
|
|
561
1219
|
console.error(`TaskOMatic Error: ${error.message}`);
|
|
562
1220
|
console.error(`Code: ${error.code}`);
|
|
563
1221
|
console.error(`Details:`, error.details);
|
|
1222
|
+
console.error(`Suggestions:`, error.suggestions);
|
|
564
1223
|
} else {
|
|
565
1224
|
console.error(`Unexpected error:`, error);
|
|
566
1225
|
}
|
|
567
1226
|
}
|
|
568
1227
|
```
|
|
569
1228
|
|
|
570
|
-
|
|
1229
|
+
### Standard Error Helpers
|
|
1230
|
+
|
|
1231
|
+
```typescript
|
|
1232
|
+
import {
|
|
1233
|
+
isTaskOMaticError,
|
|
1234
|
+
formatTaskNotFoundError,
|
|
1235
|
+
formatInvalidStatusTransitionError,
|
|
1236
|
+
formatStorageError,
|
|
1237
|
+
formatAIOperationError,
|
|
1238
|
+
} from "task-o-matic-core";
|
|
1239
|
+
|
|
1240
|
+
// Check if error is TaskOMaticError
|
|
1241
|
+
if (isTaskOMaticError(error)) {
|
|
1242
|
+
// Handle accordingly
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
// Create standard errors
|
|
1246
|
+
throw formatTaskNotFoundError("task-id-here");
|
|
1247
|
+
|
|
1248
|
+
throw formatInvalidStatusTransitionError("todo", "completed");
|
|
1249
|
+
|
|
1250
|
+
throw formatStorageError("getAllTasks", new Error("File not found"));
|
|
1251
|
+
|
|
1252
|
+
throw formatAIOperationError("enhanceTask", new Error("API timeout"));
|
|
1253
|
+
```
|
|
1254
|
+
|
|
1255
|
+
---
|
|
1256
|
+
|
|
1257
|
+
## 🪝 HOOKS SYSTEM
|
|
571
1258
|
|
|
572
1259
|
Register hooks to customize behavior:
|
|
573
1260
|
|
|
574
1261
|
```typescript
|
|
575
|
-
import { registerLoggerHooks } from "task-o-matic-core";
|
|
1262
|
+
import { hooks, registerLoggerHooks } from "task-o-matic-core";
|
|
576
1263
|
|
|
577
1264
|
// Register logger hooks
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
1265
|
+
hooks.onLog = (level, message) => {
|
|
1266
|
+
console.log(`[${level}] ${message}`);
|
|
1267
|
+
};
|
|
1268
|
+
|
|
1269
|
+
hooks.onError = (error) => {
|
|
1270
|
+
console.error(`Error:`, error);
|
|
1271
|
+
// Send to external monitoring
|
|
1272
|
+
externalMonitoring.logError(error);
|
|
1273
|
+
};
|
|
1274
|
+
|
|
1275
|
+
hooks.onProgress = (event) => {
|
|
1276
|
+
// Update your UI
|
|
1277
|
+
ui.updateProgress(event.message);
|
|
1278
|
+
};
|
|
1279
|
+
```
|
|
1280
|
+
|
|
1281
|
+
---
|
|
1282
|
+
|
|
1283
|
+
## 🧪 TESTING
|
|
1284
|
+
|
|
1285
|
+
The core library provides test utilities:
|
|
1286
|
+
|
|
1287
|
+
```typescript
|
|
1288
|
+
import {
|
|
1289
|
+
resetServiceInstances,
|
|
1290
|
+
injectTestInstances,
|
|
1291
|
+
} from "task-o-matic-core";
|
|
1292
|
+
|
|
1293
|
+
// Reset all singleton instances (useful for tests)
|
|
1294
|
+
resetServiceInstances();
|
|
1295
|
+
|
|
1296
|
+
// Inject mock instances for testing
|
|
1297
|
+
injectTestInstances({
|
|
1298
|
+
storage: mockStorage,
|
|
1299
|
+
aiOperations: mockAIOperations,
|
|
585
1300
|
});
|
|
586
1301
|
```
|
|
587
1302
|
|
|
588
|
-
|
|
1303
|
+
---
|
|
1304
|
+
|
|
1305
|
+
## 🛠️ DEVELOPMENT
|
|
589
1306
|
|
|
590
1307
|
### Building from Source
|
|
591
1308
|
|
|
592
1309
|
```bash
|
|
593
|
-
# Clone
|
|
1310
|
+
# Clone repository
|
|
594
1311
|
git clone https://github.com/DimitriGilbert/task-o-matic.git
|
|
595
1312
|
cd task-o-matic
|
|
596
|
-
npm install
|
|
597
1313
|
|
|
598
|
-
#
|
|
1314
|
+
# Install dependencies
|
|
1315
|
+
bun install
|
|
1316
|
+
|
|
1317
|
+
# Build core package
|
|
599
1318
|
cd packages/core
|
|
600
|
-
|
|
1319
|
+
bun run build
|
|
601
1320
|
|
|
602
1321
|
# Type checking
|
|
603
|
-
|
|
1322
|
+
bun run check-types
|
|
604
1323
|
|
|
605
1324
|
# Run tests
|
|
606
|
-
|
|
1325
|
+
bun run test
|
|
607
1326
|
```
|
|
608
1327
|
|
|
609
|
-
###
|
|
1328
|
+
### Running Specific Tests
|
|
610
1329
|
|
|
611
1330
|
```bash
|
|
612
|
-
#
|
|
613
|
-
|
|
1331
|
+
# From project root
|
|
1332
|
+
cd packages/core
|
|
1333
|
+
npx mocha -r tsx/cjs src/test/test-setup.ts src/test/path/to/your.test.ts
|
|
614
1334
|
|
|
615
1335
|
# Run specific test file
|
|
616
|
-
|
|
1336
|
+
bun run test -- --grep "TaskService"
|
|
617
1337
|
```
|
|
618
1338
|
|
|
619
|
-
|
|
1339
|
+
---
|
|
620
1340
|
|
|
621
|
-
|
|
1341
|
+
## 📚 FURTHER READING: ENGINEERING MANUALS
|
|
622
1342
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
- [
|
|
626
|
-
- [
|
|
627
|
-
- [
|
|
628
|
-
- [
|
|
629
|
-
- [
|
|
630
|
-
- [
|
|
1343
|
+
For detailed documentation:
|
|
1344
|
+
|
|
1345
|
+
- [Configuration Guide](../../docs/configuration.md)
|
|
1346
|
+
- [Task Management Guide](../../docs/tasks.md)
|
|
1347
|
+
- [PRD Processing Guide](../../docs/prd.md)
|
|
1348
|
+
- [Workflow Command Guide](../../docs/workflow-command.md)
|
|
1349
|
+
- [AI Integration Guide](../../docs/ai-integration.md)
|
|
1350
|
+
- [Project Initialization Guide](../../docs/projects.md)
|
|
1351
|
+
- [Streaming Output Guide](../../docs/streaming.md)
|
|
1352
|
+
- [Model Benchmarking Guide](../../docs/FO/benchmark/overview.md)
|
|
1353
|
+
- [CLI Command Reference](../cli/README.md)
|
|
1354
|
+
|
|
1355
|
+
---
|
|
631
1356
|
|
|
632
|
-
##
|
|
1357
|
+
## 🏁 FINAL REMINDER
|
|
633
1358
|
|
|
634
|
-
|
|
1359
|
+
**Remember:** Clean architecture is survival architecture. The core library is your blueprint—build whatever interface you need on top of it.
|
|
635
1360
|
|
|
636
|
-
|
|
1361
|
+
You now have everything you need to integrate task management into your custom applications. Build well, engineer.
|
|
637
1362
|
|
|
638
|
-
|
|
639
|
-
2. Create a feature branch
|
|
640
|
-
3. Make your changes
|
|
641
|
-
4. Add tests if applicable
|
|
642
|
-
5. Submit a pull request
|
|
1363
|
+
[Stay modular. Stay clean. Survive.]
|
|
643
1364
|
|
|
644
1365
|
---
|
|
645
1366
|
|
|
646
|
-
**
|
|
1367
|
+
**DOCUMENT CONTROL:**
|
|
1368
|
+
- **Version:** 1.0
|
|
1369
|
+
- **Clearance:** Engineering Personnel
|
|
1370
|
+
- **Classification:** For Builders' Eyes Only
|