@prmichaelsen/task-mcp 0.2.0

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 (142) hide show
  1. package/.env.example +19 -0
  2. package/AGENT.md +1165 -0
  3. package/CHANGELOG.md +72 -0
  4. package/agent/commands/acp.commit.md +511 -0
  5. package/agent/commands/acp.init.md +376 -0
  6. package/agent/commands/acp.package-install.md +347 -0
  7. package/agent/commands/acp.proceed.md +311 -0
  8. package/agent/commands/acp.report.md +392 -0
  9. package/agent/commands/acp.status.md +280 -0
  10. package/agent/commands/acp.sync.md +323 -0
  11. package/agent/commands/acp.update.md +301 -0
  12. package/agent/commands/acp.validate.md +385 -0
  13. package/agent/commands/acp.version-check-for-updates.md +275 -0
  14. package/agent/commands/acp.version-check.md +190 -0
  15. package/agent/commands/acp.version-update.md +288 -0
  16. package/agent/commands/command.template.md +273 -0
  17. package/agent/commands/git.commit.md +511 -0
  18. package/agent/commands/git.init.md +513 -0
  19. package/agent/design/.gitkeep +0 -0
  20. package/agent/design/acp-task-execution-requirements.md +555 -0
  21. package/agent/design/api-dto-design.md +394 -0
  22. package/agent/design/code-extraction-guide.md +827 -0
  23. package/agent/design/design.template.md +136 -0
  24. package/agent/design/requirements.template.md +387 -0
  25. package/agent/design/rest-api-integration.md +489 -0
  26. package/agent/design/sdk-export-requirements.md +549 -0
  27. package/agent/milestones/.gitkeep +0 -0
  28. package/agent/milestones/milestone-1-{title}.template.md +206 -0
  29. package/agent/milestones/milestone-2-task-infrastructure.md +232 -0
  30. package/agent/milestones/milestone-4-autonomous-execution.md +235 -0
  31. package/agent/patterns/.gitkeep +0 -0
  32. package/agent/patterns/bootstrap.md +1271 -0
  33. package/agent/patterns/bootstrap.template.md +1237 -0
  34. package/agent/patterns/pattern.template.md +364 -0
  35. package/agent/progress.template.yaml +158 -0
  36. package/agent/progress.yaml +375 -0
  37. package/agent/scripts/check-for-updates.sh +88 -0
  38. package/agent/scripts/install.sh +157 -0
  39. package/agent/scripts/uninstall.sh +75 -0
  40. package/agent/scripts/update.sh +139 -0
  41. package/agent/scripts/version.sh +35 -0
  42. package/agent/tasks/.gitkeep +0 -0
  43. package/agent/tasks/task-1-{title}.template.md +225 -0
  44. package/agent/tasks/task-86-task-data-model-schemas.md +143 -0
  45. package/agent/tasks/task-87-task-database-service.md +220 -0
  46. package/agent/tasks/task-88-firebase-client-wrapper.md +139 -0
  47. package/agent/tasks/task-88-task-execution-engine.md +277 -0
  48. package/agent/tasks/task-89-mcp-server-implementation.md +197 -0
  49. package/agent/tasks/task-90-build-configuration.md +146 -0
  50. package/agent/tasks/task-91-deployment-configuration.md +128 -0
  51. package/coverage/base.css +224 -0
  52. package/coverage/block-navigation.js +87 -0
  53. package/coverage/favicon.png +0 -0
  54. package/coverage/index.html +191 -0
  55. package/coverage/lcov-report/base.css +224 -0
  56. package/coverage/lcov-report/block-navigation.js +87 -0
  57. package/coverage/lcov-report/favicon.png +0 -0
  58. package/coverage/lcov-report/index.html +191 -0
  59. package/coverage/lcov-report/prettify.css +1 -0
  60. package/coverage/lcov-report/prettify.js +2 -0
  61. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  62. package/coverage/lcov-report/sorter.js +210 -0
  63. package/coverage/lcov-report/src/client.ts.html +1030 -0
  64. package/coverage/lcov-report/src/constant/collections.ts.html +469 -0
  65. package/coverage/lcov-report/src/constant/index.html +116 -0
  66. package/coverage/lcov-report/src/dto/index.html +116 -0
  67. package/coverage/lcov-report/src/dto/transformers.ts.html +568 -0
  68. package/coverage/lcov-report/src/index.html +146 -0
  69. package/coverage/lcov-report/src/schemas/index.html +116 -0
  70. package/coverage/lcov-report/src/schemas/task.ts.html +547 -0
  71. package/coverage/lcov-report/src/server-factory.ts.html +418 -0
  72. package/coverage/lcov-report/src/server.ts.html +289 -0
  73. package/coverage/lcov-report/src/services/index.html +116 -0
  74. package/coverage/lcov-report/src/services/task-database.service.ts.html +1495 -0
  75. package/coverage/lcov-report/src/tools/index.html +236 -0
  76. package/coverage/lcov-report/src/tools/index.ts.html +292 -0
  77. package/coverage/lcov-report/src/tools/task-add-message.ts.html +277 -0
  78. package/coverage/lcov-report/src/tools/task-complete-task-item.ts.html +343 -0
  79. package/coverage/lcov-report/src/tools/task-create-milestone.ts.html +286 -0
  80. package/coverage/lcov-report/src/tools/task-create-task-item.ts.html +358 -0
  81. package/coverage/lcov-report/src/tools/task-get-next-step.ts.html +460 -0
  82. package/coverage/lcov-report/src/tools/task-get-status.ts.html +316 -0
  83. package/coverage/lcov-report/src/tools/task-report-completion.ts.html +343 -0
  84. package/coverage/lcov-report/src/tools/task-update-progress.ts.html +232 -0
  85. package/coverage/lcov.info +974 -0
  86. package/coverage/prettify.css +1 -0
  87. package/coverage/prettify.js +2 -0
  88. package/coverage/sort-arrow-sprite.png +0 -0
  89. package/coverage/sorter.js +210 -0
  90. package/coverage/src/client.ts.html +1030 -0
  91. package/coverage/src/constant/collections.ts.html +469 -0
  92. package/coverage/src/constant/index.html +116 -0
  93. package/coverage/src/dto/index.html +116 -0
  94. package/coverage/src/dto/transformers.ts.html +568 -0
  95. package/coverage/src/index.html +146 -0
  96. package/coverage/src/schemas/index.html +116 -0
  97. package/coverage/src/schemas/task.ts.html +547 -0
  98. package/coverage/src/server-factory.ts.html +418 -0
  99. package/coverage/src/server.ts.html +289 -0
  100. package/coverage/src/services/index.html +116 -0
  101. package/coverage/src/services/task-database.service.ts.html +1495 -0
  102. package/coverage/src/tools/index.html +236 -0
  103. package/coverage/src/tools/index.ts.html +292 -0
  104. package/coverage/src/tools/task-add-message.ts.html +277 -0
  105. package/coverage/src/tools/task-complete-task-item.ts.html +343 -0
  106. package/coverage/src/tools/task-create-milestone.ts.html +286 -0
  107. package/coverage/src/tools/task-create-task-item.ts.html +358 -0
  108. package/coverage/src/tools/task-get-next-step.ts.html +460 -0
  109. package/coverage/src/tools/task-get-status.ts.html +316 -0
  110. package/coverage/src/tools/task-report-completion.ts.html +343 -0
  111. package/coverage/src/tools/task-update-progress.ts.html +232 -0
  112. package/firestore.rules +95 -0
  113. package/jest.config.js +31 -0
  114. package/package.json +67 -0
  115. package/src/client.spec.ts +199 -0
  116. package/src/client.ts +315 -0
  117. package/src/constant/collections.ts +128 -0
  118. package/src/dto/index.ts +47 -0
  119. package/src/dto/task-api.dto.ts +219 -0
  120. package/src/dto/transformers.spec.ts +462 -0
  121. package/src/dto/transformers.ts +161 -0
  122. package/src/schemas/task.ts +154 -0
  123. package/src/server-factory.spec.ts +70 -0
  124. package/src/server-factory.ts +111 -0
  125. package/src/server.ts +68 -0
  126. package/src/services/task-database.service.e2e.ts +116 -0
  127. package/src/services/task-database.service.spec.ts +479 -0
  128. package/src/services/task-database.service.ts +470 -0
  129. package/src/test-schemas.ts +161 -0
  130. package/src/tools/index.ts +69 -0
  131. package/src/tools/task-add-message.ts +64 -0
  132. package/src/tools/task-complete-task-item.ts +86 -0
  133. package/src/tools/task-create-milestone.ts +67 -0
  134. package/src/tools/task-create-task-item.ts +91 -0
  135. package/src/tools/task-get-next-step.spec.ts +136 -0
  136. package/src/tools/task-get-next-step.ts +125 -0
  137. package/src/tools/task-get-status.spec.ts +213 -0
  138. package/src/tools/task-get-status.ts +77 -0
  139. package/src/tools/task-report-completion.ts +86 -0
  140. package/src/tools/task-update-progress.ts +49 -0
  141. package/src/tools/tools.spec.ts +194 -0
  142. package/tsconfig.json +31 -0
@@ -0,0 +1,220 @@
1
+ # Task 87: Task Database Service
2
+
3
+ **Milestone**: Milestone 1 - Task Infrastructure
4
+ **Estimated Time**: 12 hours
5
+ **Dependencies**: Task 86 (Task Data Model and Schemas)
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Create a database service for task CRUD operations, task message operations, and progress tracking. This service will handle all Firestore interactions for tasks.
13
+
14
+ ## Steps
15
+
16
+ ### 1. Create TaskDatabaseService Class
17
+
18
+ Create `src/services/task-database.service.ts` with methods for:
19
+ - Creating tasks
20
+ - Reading tasks
21
+ - Updating tasks
22
+ - Deleting tasks
23
+ - Listing user tasks
24
+
25
+ ### 2. Implement Task Message Operations
26
+
27
+ Add methods for:
28
+ - Adding messages to task
29
+ - Getting task messages
30
+ - Updating message
31
+ - Deleting message
32
+
33
+ ### 3. Implement Progress Operations
34
+
35
+ Add methods for:
36
+ - Updating overall progress
37
+ - Creating milestone
38
+ - Updating milestone
39
+ - Completing milestone
40
+ - Creating task item
41
+ - Updating task item
42
+ - Completing task item
43
+
44
+ ### 4. Add Query Methods
45
+
46
+ Add methods for:
47
+ - Get tasks by status
48
+ - Get active tasks
49
+ - Get completed tasks
50
+ - Search tasks by title
51
+
52
+ ### 5. Write Unit Tests
53
+
54
+ Create `src/services/__tests__/task-database.service.spec.ts`:
55
+ - Test CRUD operations with mocked Firestore
56
+ - Test progress operations
57
+ - Test query methods
58
+ - Test error handling
59
+
60
+ ### 6. Write E2E Tests
61
+
62
+ Create `src/services/__tests__/task-database.service.e2e.ts`:
63
+ - Test with real Firestore emulator
64
+ - Test concurrent operations
65
+ - Test transaction handling
66
+
67
+ ## Verification
68
+
69
+ - [ ] All CRUD operations work
70
+ - [ ] Task messages can be added/retrieved
71
+ - [ ] Progress can be updated
72
+ - [ ] Milestones can be managed
73
+ - [ ] Task items can be managed
74
+ - [ ] Query methods return correct results
75
+ - [ ] User isolation is enforced
76
+ - [ ] Unit tests pass
77
+ - [ ] E2E tests pass
78
+ - [ ] Error handling works correctly
79
+
80
+ ## Example Service Structure
81
+
82
+ ```typescript
83
+ // src/services/task-database.service.ts
84
+ import { getDocument, setDocument, addDocument, queryDocuments } from '@prmichaelsen/firebase-admin-sdk-v8'
85
+ import { getUserTasks, getUserTaskMessages } from '@/constant/collections'
86
+ import { TaskSchema, type Task, type Milestone, type TaskItem } from '@/schemas/task'
87
+
88
+ export class TaskDatabaseService {
89
+ /**
90
+ * Create a new task
91
+ */
92
+ static async createTask(
93
+ userId: string,
94
+ title: string,
95
+ description: string,
96
+ config?: Partial<Task['config']>
97
+ ): Promise<Task> {
98
+ const now = new Date().toISOString()
99
+
100
+ const task: Omit<Task, 'id'> = {
101
+ user_id: userId,
102
+ title,
103
+ description,
104
+ status: 'not_started',
105
+ created_at: now,
106
+ updated_at: now,
107
+ progress: {
108
+ current_milestone: '',
109
+ current_task: '',
110
+ overall_percentage: 0,
111
+ milestones: [],
112
+ tasks: {}
113
+ },
114
+ execution: {
115
+ api_messages: [],
116
+ task_messages: [],
117
+ tool_results: []
118
+ },
119
+ config: {
120
+ model: config?.model || 'us.anthropic.claude-sonnet-4-5-20250929-v1:0',
121
+ system_prompt: config?.system_prompt || '',
122
+ auto_approve: config?.auto_approve ?? true,
123
+ max_iterations: config?.max_iterations || 100,
124
+ timeout_minutes: config?.timeout_minutes || 120
125
+ }
126
+ }
127
+
128
+ const tasksPath = getUserTasks(userId)
129
+ const docRef = await addDocument(tasksPath, task)
130
+
131
+ return {
132
+ id: docRef.id,
133
+ ...task
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Get a task by ID
139
+ */
140
+ static async getTask(userId: string, taskId: string): Promise<Task | null> {
141
+ const tasksPath = getUserTasks(userId)
142
+ const doc = await getDocument(tasksPath, taskId)
143
+
144
+ if (!doc) return null
145
+
146
+ const result = TaskSchema.safeParse({ id: taskId, ...doc })
147
+ return result.success ? result.data : null
148
+ }
149
+
150
+ /**
151
+ * Update task status
152
+ */
153
+ static async updateTaskStatus(
154
+ userId: string,
155
+ taskId: string,
156
+ status: Task['status']
157
+ ): Promise<void> {
158
+ const tasksPath = getUserTasks(userId)
159
+ await setDocument(tasksPath, taskId, {
160
+ status,
161
+ updated_at: new Date().toISOString()
162
+ }, { merge: true })
163
+ }
164
+
165
+ /**
166
+ * Create a milestone
167
+ */
168
+ static async createMilestone(
169
+ userId: string,
170
+ taskId: string,
171
+ milestone: Milestone
172
+ ): Promise<void> {
173
+ const task = await this.getTask(userId, taskId)
174
+ if (!task) throw new Error('Task not found')
175
+
176
+ task.progress.milestones.push(milestone)
177
+
178
+ const tasksPath = getUserTasks(userId)
179
+ await setDocument(tasksPath, taskId, {
180
+ progress: task.progress,
181
+ updated_at: new Date().toISOString()
182
+ }, { merge: true })
183
+ }
184
+
185
+ /**
186
+ * Add message to task
187
+ */
188
+ static async addMessage(
189
+ userId: string,
190
+ taskId: string,
191
+ role: 'user' | 'assistant' | 'system',
192
+ content: string,
193
+ metadata?: any
194
+ ): Promise<string> {
195
+ const messagesPath = getUserTaskMessages(userId, taskId)
196
+ const message = {
197
+ task_id: taskId,
198
+ role,
199
+ content,
200
+ timestamp: new Date().toISOString(),
201
+ metadata
202
+ }
203
+
204
+ const docRef = await addDocument(messagesPath, message)
205
+ return docRef.id
206
+ }
207
+
208
+ // ... more methods
209
+ }
210
+ ```
211
+
212
+ ## Files to Create
213
+
214
+ - `src/services/task-database.service.ts`
215
+ - `src/services/__tests__/task-database.service.spec.ts`
216
+ - `src/services/__tests__/task-database.service.e2e.ts`
217
+
218
+ ---
219
+
220
+ **Next Task**: [Task 88: Task Execution Engine](task-88-task-execution-engine.md)
@@ -0,0 +1,139 @@
1
+ # Task 88: Firebase Client Wrapper & MCP Tools Foundation
2
+
3
+ **Milestone**: Milestone 2 - MCP Server Foundation
4
+ **Estimated Time**: 16 hours (revised from original scope)
5
+ **Dependencies**: Task 87 (Task Database Service)
6
+ **Status**: Not Started
7
+ **Last Updated**: 2026-02-16
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ **REVISED**: Create Firebase Admin SDK client wrapper and foundational MCP tools for task-mcp server. This task was originally scoped for agentbase.me TaskExecutor but has been revised to match task-mcp's role as an MCP tool server that provides instructions to tenant platforms.
14
+
15
+ **Original Scope** (archived): TaskExecutor with Bedrock integration for agentbase.me
16
+ **Revised Scope**: Firebase client + core MCP tools for task-mcp server
17
+
18
+ ---
19
+
20
+ ## Steps
21
+
22
+ ### 1. Create Firebase Client Wrapper
23
+
24
+ Create `src/client.ts`:
25
+ - Wrapper around TaskDatabaseService
26
+ - Service account authentication
27
+ - User-scoped operations
28
+ - Connection management
29
+ - Error handling
30
+
31
+ ### 2. Create Core MCP Tool: task_get_status
32
+
33
+ Create `src/tools/task-get-status.ts`:
34
+ - Get current task status and progress
35
+ - Return milestone and task information
36
+ - Show overall progress percentage
37
+
38
+ ### 3. Create Core MCP Tool: task_get_next_step
39
+
40
+ Create `src/tools/task-get-next-step.ts`:
41
+ - Find current task item from progress
42
+ - Return instructions for what to do next
43
+ - Include steps and verification criteria
44
+
45
+ ### 4. Create Core MCP Tool: task_update_progress
46
+
47
+ Create `src/tools/task-update-progress.ts`:
48
+ - Update overall progress percentage
49
+ - Update milestone progress
50
+ - Recalculate completion metrics
51
+
52
+ ### 5. Create Core MCP Tool: task_complete_task_item
53
+
54
+ Create `src/tools/task-complete-task-item.ts`:
55
+ - Mark a task item as complete
56
+ - Update milestone progress
57
+ - Move to next task if available
58
+
59
+ ### 6. Create Core MCP Tool: task_create_milestone
60
+
61
+ Create `src/tools/task-create-milestone.ts`:
62
+ - Add a new milestone to task
63
+ - Initialize milestone with tasks
64
+ - Update progress tracking
65
+
66
+ ### 7. Create Core MCP Tool: task_create_task_item
67
+
68
+ Create `src/tools/task-create-task-item.ts`:
69
+ - Add a task item to a milestone
70
+ - Update milestone task count
71
+ - Return confirmation
72
+
73
+ ### 8. Create Core MCP Tool: task_report_completion
74
+
75
+ Create `src/tools/task-report-completion.ts`:
76
+ - Agent reports task item completion
77
+ - Update progress
78
+ - Get next instructions
79
+
80
+ ### 9. Create Core MCP Tool: task_add_message
81
+
82
+ Create `src/tools/task-add-message.ts`:
83
+ - Add message to task thread
84
+ - Support user, assistant, system roles
85
+ - Return message ID
86
+
87
+ ### 10. Create Tools Index
88
+
89
+ Create `src/tools/index.ts`:
90
+ - Export all tool definitions
91
+ - Export all tool handlers
92
+ - Create tool registry
93
+
94
+ ### 11. Write Unit Tests
95
+
96
+ Create colocated test for each tool:
97
+ - Test tool definitions
98
+ - Test handlers with mocked client
99
+ - Test error handling
100
+ - Verify JSON responses
101
+
102
+ ## Verification
103
+
104
+ - [ ] FirebaseClient wrapper created
105
+ - [ ] All 8 core tools implemented
106
+ - [ ] Each tool has definition and handler
107
+ - [ ] Tools return JSON strings
108
+ - [ ] Error handling works correctly
109
+ - [ ] Unit tests pass for all tools
110
+ - [ ] Tools follow MCP Bootstrap Pattern
111
+ - [ ] TypeScript compiles without errors
112
+
113
+ ## Notes on Revision
114
+
115
+ **Why Revised**: Original task described TaskExecutor for agentbase.me with Bedrock integration. However, task-mcp is an MCP server that exposes tools, not an execution engine. The execution happens in the tenant platform (agentbase.me).
116
+
117
+ **Architecture Clarification**:
118
+ - task-mcp provides **instructions** via MCP tools
119
+ - Tenant platform's agent **executes** those instructions
120
+ - Agent reports back to task-mcp via tools
121
+ - task-mcp tracks progress in Firestore
122
+
123
+ ## Files to Create
124
+
125
+ - `src/client.ts` + `.spec.ts`
126
+ - `src/tools/task-get-status.ts` + `.spec.ts`
127
+ - `src/tools/task-get-next-step.ts` + `.spec.ts`
128
+ - `src/tools/task-update-progress.ts` + `.spec.ts`
129
+ - `src/tools/task-complete-task-item.ts` + `.spec.ts`
130
+ - `src/tools/task-create-milestone.ts` + `.spec.ts`
131
+ - `src/tools/task-create-task-item.ts` + `.spec.ts`
132
+ - `src/tools/task-report-completion.ts` + `.spec.ts`
133
+ - `src/tools/task-add-message.ts` + `.spec.ts`
134
+ - `src/tools/index.ts`
135
+ - `.env.example`
136
+
137
+ ---
138
+
139
+ **Next Task**: [Task 89: MCP Server Implementation](task-89-mcp-server-implementation.md)
@@ -0,0 +1,277 @@
1
+ # Task 88: Task Execution Engine
2
+
3
+ **Milestone**: Milestone 1 - Task Infrastructure
4
+ **Estimated Time**: 16 hours
5
+ **Dependencies**: Task 87 (Task Database Service)
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Create a simplified task execution engine adapted from Roo Code's Task class. This engine manages task lifecycle (start, pause, resume, stop), streams API responses, coordinates tool execution, and persists state to Firestore.
13
+
14
+ ## Steps
15
+
16
+ ### 1. Create TaskExecutor Class
17
+
18
+ Create `src/lib/task-execution/TaskExecutor.ts`:
19
+ - Initialize with task ID and user ID
20
+ - Load task state from Firestore
21
+ - Manage execution lifecycle
22
+ - Stream API responses from Bedrock
23
+ - Coordinate tool execution
24
+ - Emit events for UI updates
25
+
26
+ ### 2. Create TaskLifecycle Manager
27
+
28
+ Create `src/lib/task-execution/TaskLifecycle.ts`:
29
+ - Handle start/pause/resume/stop transitions
30
+ - Validate state transitions
31
+ - Update task status in Firestore
32
+ - Emit lifecycle events
33
+
34
+ ### 3. Create TaskPersistence Layer
35
+
36
+ Create `src/lib/task-execution/TaskPersistence.ts`:
37
+ - Save API messages to Firestore
38
+ - Save task messages to Firestore
39
+ - Save tool results to Firestore
40
+ - Load execution state from Firestore
41
+ - Implement checkpoint/resume logic
42
+
43
+ ### 4. Integrate with Bedrock Chat
44
+
45
+ Adapt existing Bedrock chat integration:
46
+ - Use `streamChatResponse` from `src/lib/chat/bedrock.ts`
47
+ - Pass task-specific tools
48
+ - Handle tool execution results
49
+ - Stream responses to task thread
50
+
51
+ ### 5. Implement Event System
52
+
53
+ Create event emitter for:
54
+ - `task:started`
55
+ - `task:paused`
56
+ - `task:resumed`
57
+ - `task:stopped`
58
+ - `task:completed`
59
+ - `task:error`
60
+ - `task:progress_update`
61
+ - `task:message`
62
+
63
+ ### 6. Write Tests
64
+
65
+ Create tests for:
66
+ - Task lifecycle transitions
67
+ - API streaming
68
+ - Tool execution
69
+ - State persistence
70
+ - Error handling
71
+ - Event emission
72
+
73
+ ## Verification
74
+
75
+ - [ ] Can start task execution
76
+ - [ ] Can pause task execution
77
+ - [ ] Can resume task execution
78
+ - [ ] Can stop task execution
79
+ - [ ] API responses stream correctly
80
+ - [ ] Tools execute correctly
81
+ - [ ] State persists to Firestore
82
+ - [ ] Events emit correctly
83
+ - [ ] Errors handled gracefully
84
+ - [ ] Tests pass
85
+
86
+ ## Example TaskExecutor Structure
87
+
88
+ ```typescript
89
+ // src/lib/task-execution/TaskExecutor.ts
90
+ import { EventEmitter } from 'events'
91
+ import { TaskDatabaseService } from '@/services/task-database.service'
92
+ import { streamChatResponse } from '@/lib/chat/bedrock'
93
+ import { createBedrockClient } from '@/lib/chat/bedrock'
94
+ import type { Task } from '@/schemas/task'
95
+
96
+ export class TaskExecutor extends EventEmitter {
97
+ private taskId: string
98
+ private userId: string
99
+ private task: Task | null = null
100
+ private isRunning = false
101
+ private isPaused = false
102
+ private abortController: AbortController | null = null
103
+
104
+ constructor(taskId: string, userId: string) {
105
+ super()
106
+ this.taskId = taskId
107
+ this.userId = userId
108
+ }
109
+
110
+ /**
111
+ * Start task execution
112
+ */
113
+ async start(): Promise<void> {
114
+ // Load task from Firestore
115
+ this.task = await TaskDatabaseService.getTask(this.userId, this.taskId)
116
+ if (!this.task) {
117
+ throw new Error('Task not found')
118
+ }
119
+
120
+ // Update status
121
+ await TaskDatabaseService.updateTaskStatus(this.userId, this.taskId, 'in_progress')
122
+ this.task.status = 'in_progress'
123
+
124
+ // Emit event
125
+ this.emit('task:started', { taskId: this.taskId })
126
+
127
+ // Start execution loop
128
+ this.isRunning = true
129
+ await this.executionLoop()
130
+ }
131
+
132
+ /**
133
+ * Pause task execution
134
+ */
135
+ async pause(): Promise<void> {
136
+ this.isPaused = true
137
+ this.abortController?.abort()
138
+
139
+ await TaskDatabaseService.updateTaskStatus(this.userId, this.taskId, 'paused')
140
+ this.emit('task:paused', { taskId: this.taskId })
141
+ }
142
+
143
+ /**
144
+ * Resume task execution
145
+ */
146
+ async resume(): Promise<void> {
147
+ this.isPaused = false
148
+ await TaskDatabaseService.updateTaskStatus(this.userId, this.taskId, 'in_progress')
149
+ this.emit('task:resumed', { taskId: this.taskId })
150
+
151
+ await this.executionLoop()
152
+ }
153
+
154
+ /**
155
+ * Stop task execution
156
+ */
157
+ async stop(): Promise<void> {
158
+ this.isRunning = false
159
+ this.abortController?.abort()
160
+
161
+ await TaskDatabaseService.updateTaskStatus(this.userId, this.taskId, 'paused')
162
+ this.emit('task:stopped', { taskId: this.taskId })
163
+ }
164
+
165
+ /**
166
+ * Main execution loop
167
+ */
168
+ private async executionLoop(): Promise<void> {
169
+ while (this.isRunning && !this.isPaused) {
170
+ try {
171
+ // Get current milestone and task
172
+ const currentMilestone = this.getCurrentMilestone()
173
+ const currentTask = this.getCurrentTask()
174
+
175
+ if (!currentTask) {
176
+ // All tasks complete
177
+ await this.complete()
178
+ break
179
+ }
180
+
181
+ // Execute task
182
+ await this.executeTask(currentTask)
183
+
184
+ // Update progress
185
+ await this.updateProgress()
186
+
187
+ } catch (error) {
188
+ await this.handleError(error)
189
+ break
190
+ }
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Execute a single task
196
+ */
197
+ private async executeTask(taskItem: any): Promise<void> {
198
+ // Create Bedrock client
199
+ const bedrock = createBedrockClient()
200
+
201
+ // Prepare messages
202
+ const messages = this.prepareMessages()
203
+
204
+ // Prepare tools
205
+ const tools = this.prepareTools()
206
+
207
+ // Stream response
208
+ this.abortController = new AbortController()
209
+
210
+ const result = await streamChatResponse(
211
+ bedrock,
212
+ messages,
213
+ tools,
214
+ {
215
+ maxTokens: 4096,
216
+ temperature: 0.7,
217
+ systemPrompt: this.task!.config.system_prompt
218
+ },
219
+ (chunk) => {
220
+ // Emit chunk event
221
+ this.emit('task:message', {
222
+ taskId: this.taskId,
223
+ role: 'assistant',
224
+ content: chunk,
225
+ streaming: true
226
+ })
227
+ },
228
+ (toolCall) => {
229
+ // Handle tool call
230
+ this.emit('task:tool_call', {
231
+ taskId: this.taskId,
232
+ toolCall
233
+ })
234
+ }
235
+ )
236
+
237
+ // Save result
238
+ await this.saveResult(result)
239
+ }
240
+
241
+ /**
242
+ * Complete task
243
+ */
244
+ private async complete(): Promise<void> {
245
+ await TaskDatabaseService.updateTaskStatus(this.userId, this.taskId, 'completed')
246
+ this.isRunning = false
247
+ this.emit('task:completed', { taskId: this.taskId })
248
+ }
249
+
250
+ /**
251
+ * Handle error
252
+ */
253
+ private async handleError(error: any): Promise<void> {
254
+ await TaskDatabaseService.updateTaskStatus(this.userId, this.taskId, 'failed')
255
+ this.isRunning = false
256
+ this.emit('task:error', {
257
+ taskId: this.taskId,
258
+ error: error instanceof Error ? error.message : String(error)
259
+ })
260
+ }
261
+
262
+ // ... more methods
263
+ }
264
+ ```
265
+
266
+ ## Files to Create
267
+
268
+ - `src/lib/task-execution/TaskExecutor.ts`
269
+ - `src/lib/task-execution/TaskLifecycle.ts`
270
+ - `src/lib/task-execution/TaskPersistence.ts`
271
+ - `src/lib/task-execution/__tests__/TaskExecutor.spec.ts`
272
+ - `src/lib/task-execution/__tests__/TaskLifecycle.spec.ts`
273
+ - `src/lib/task-execution/__tests__/TaskPersistence.spec.ts`
274
+
275
+ ---
276
+
277
+ **Next Task**: [Task 89: Task API Endpoints](task-89-task-api-endpoints.md)