super-subagents 1.0.1
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/.windsurf/plans/persist-tasks-by-cwd.md +113 -0
- package/CHANGELOG.md +10 -0
- package/CLAUDE.md +67 -0
- package/README.md +124 -0
- package/build/config/timeouts.d.ts +12 -0
- package/build/config/timeouts.d.ts.map +1 -0
- package/build/config/timeouts.js +21 -0
- package/build/config/timeouts.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +116 -0
- package/build/index.js.map +1 -0
- package/build/models.d.ts +11 -0
- package/build/models.d.ts.map +1 -0
- package/build/models.js +22 -0
- package/build/models.js.map +1 -0
- package/build/services/client-context.d.ts +31 -0
- package/build/services/client-context.d.ts.map +1 -0
- package/build/services/client-context.js +44 -0
- package/build/services/client-context.js.map +1 -0
- package/build/services/copilot-switch.d.ts +36 -0
- package/build/services/copilot-switch.d.ts.map +1 -0
- package/build/services/copilot-switch.js +226 -0
- package/build/services/copilot-switch.js.map +1 -0
- package/build/services/process-spawner.d.ts +9 -0
- package/build/services/process-spawner.d.ts.map +1 -0
- package/build/services/process-spawner.js +475 -0
- package/build/services/process-spawner.js.map +1 -0
- package/build/services/retry-queue.d.ts +35 -0
- package/build/services/retry-queue.d.ts.map +1 -0
- package/build/services/retry-queue.js +125 -0
- package/build/services/retry-queue.js.map +1 -0
- package/build/services/task-manager.d.ts +124 -0
- package/build/services/task-manager.d.ts.map +1 -0
- package/build/services/task-manager.js +584 -0
- package/build/services/task-manager.js.map +1 -0
- package/build/services/task-persistence.d.ts +29 -0
- package/build/services/task-persistence.d.ts.map +1 -0
- package/build/services/task-persistence.js +158 -0
- package/build/services/task-persistence.js.map +1 -0
- package/build/templates/index.d.ts +11 -0
- package/build/templates/index.d.ts.map +1 -0
- package/build/templates/index.js +30 -0
- package/build/templates/index.js.map +1 -0
- package/build/tools/batch-spawn.d.ts +69 -0
- package/build/tools/batch-spawn.d.ts.map +1 -0
- package/build/tools/batch-spawn.js +150 -0
- package/build/tools/batch-spawn.js.map +1 -0
- package/build/tools/cancel-task.d.ts +21 -0
- package/build/tools/cancel-task.d.ts.map +1 -0
- package/build/tools/cancel-task.js +44 -0
- package/build/tools/cancel-task.js.map +1 -0
- package/build/tools/clear-tasks.d.ts +21 -0
- package/build/tools/clear-tasks.d.ts.map +1 -0
- package/build/tools/clear-tasks.js +43 -0
- package/build/tools/clear-tasks.js.map +1 -0
- package/build/tools/force-start.d.ts +21 -0
- package/build/tools/force-start.d.ts.map +1 -0
- package/build/tools/force-start.js +38 -0
- package/build/tools/force-start.js.map +1 -0
- package/build/tools/get-status.d.ts +31 -0
- package/build/tools/get-status.d.ts.map +1 -0
- package/build/tools/get-status.js +384 -0
- package/build/tools/get-status.js.map +1 -0
- package/build/tools/list-tasks.d.ts +26 -0
- package/build/tools/list-tasks.d.ts.map +1 -0
- package/build/tools/list-tasks.js +74 -0
- package/build/tools/list-tasks.js.map +1 -0
- package/build/tools/recover-task.d.ts +29 -0
- package/build/tools/recover-task.d.ts.map +1 -0
- package/build/tools/recover-task.js +91 -0
- package/build/tools/recover-task.js.map +1 -0
- package/build/tools/resume-task.d.ts +29 -0
- package/build/tools/resume-task.d.ts.map +1 -0
- package/build/tools/resume-task.js +43 -0
- package/build/tools/resume-task.js.map +1 -0
- package/build/tools/retry-task.d.ts +21 -0
- package/build/tools/retry-task.d.ts.map +1 -0
- package/build/tools/retry-task.js +52 -0
- package/build/tools/retry-task.js.map +1 -0
- package/build/tools/simulate-rate-limit.d.ts +25 -0
- package/build/tools/simulate-rate-limit.d.ts.map +1 -0
- package/build/tools/simulate-rate-limit.js +69 -0
- package/build/tools/simulate-rate-limit.js.map +1 -0
- package/build/tools/spawn-task.d.ts +57 -0
- package/build/tools/spawn-task.d.ts.map +1 -0
- package/build/tools/spawn-task.js +113 -0
- package/build/tools/spawn-task.js.map +1 -0
- package/build/tools/stream-output.d.ts +29 -0
- package/build/tools/stream-output.d.ts.map +1 -0
- package/build/tools/stream-output.js +96 -0
- package/build/tools/stream-output.js.map +1 -0
- package/build/types.d.ts +75 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +12 -0
- package/build/types.js.map +1 -0
- package/build/utils/format.d.ts +29 -0
- package/build/utils/format.d.ts.map +1 -0
- package/build/utils/format.js +81 -0
- package/build/utils/format.js.map +1 -0
- package/build/utils/sanitize.d.ts +63 -0
- package/build/utils/sanitize.d.ts.map +1 -0
- package/build/utils/sanitize.js +28 -0
- package/build/utils/sanitize.js.map +1 -0
- package/build/utils/task-id-generator.d.ts +10 -0
- package/build/utils/task-id-generator.d.ts.map +1 -0
- package/build/utils/task-id-generator.js +22 -0
- package/build/utils/task-id-generator.js.map +1 -0
- package/docs/timeout-durability.md +28 -0
- package/package.json +39 -0
- package/plans/timeout-durability/00-overview.md +38 -0
- package/plans/timeout-durability/01-analysis.md +37 -0
- package/plans/timeout-durability/decisions.md +22 -0
- package/plans/timeout-durability/resources.md +24 -0
- package/plans/timeout-durability/step-01-timeout-flow.md +27 -0
- package/plans/timeout-durability/step-02-root-cause-map.md +26 -0
- package/plans/timeout-durability/step-03-state-schema.md +26 -0
- package/plans/timeout-durability/step-04-messaging-recovery.md +27 -0
- package/src/config/timeouts.ts +22 -0
- package/src/index.ts +129 -0
- package/src/models.ts +23 -0
- package/src/services/client-context.ts +49 -0
- package/src/services/copilot-switch.ts +269 -0
- package/src/services/process-spawner.ts +548 -0
- package/src/services/retry-queue.ts +151 -0
- package/src/services/task-manager.ts +667 -0
- package/src/services/task-persistence.ts +175 -0
- package/src/templates/index.ts +35 -0
- package/src/templates/super-coder.mdx +519 -0
- package/src/templates/super-planner.mdx +558 -0
- package/src/templates/super-researcher.mdx +394 -0
- package/src/templates/super-tester.mdx +688 -0
- package/src/tools/batch-spawn.ts +179 -0
- package/src/tools/cancel-task.ts +58 -0
- package/src/tools/clear-tasks.ts +52 -0
- package/src/tools/force-start.ts +48 -0
- package/src/tools/get-status.ts +480 -0
- package/src/tools/list-tasks.ts +83 -0
- package/src/tools/recover-task.ts +112 -0
- package/src/tools/resume-task.ts +51 -0
- package/src/tools/retry-task.ts +72 -0
- package/src/tools/simulate-rate-limit.ts +84 -0
- package/src/tools/spawn-task.ts +135 -0
- package/src/tools/stream-output.ts +101 -0
- package/src/types.ts +86 -0
- package/src/utils/format.ts +83 -0
- package/src/utils/sanitize.ts +35 -0
- package/src/utils/task-id-generator.ts +25 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
import { generateTaskId, normalizeTaskId } from '../utils/task-id-generator.js';
|
|
2
|
+
import { TaskStatus } from '../types.js';
|
|
3
|
+
import { saveTasks, loadTasks } from './task-persistence.js';
|
|
4
|
+
import { shouldRetryNow, hasExceededMaxRetries } from './retry-queue.js';
|
|
5
|
+
import { TASK_STALL_WARN_MS } from '../config/timeouts.js';
|
|
6
|
+
const MAX_TASKS = 100;
|
|
7
|
+
/**
|
|
8
|
+
* Check if adding dependencies would create a circular dependency
|
|
9
|
+
* @param newTaskId - The ID of the task being created
|
|
10
|
+
* @param dependsOn - Array of task IDs this task depends on
|
|
11
|
+
* @param tasks - Map of all existing tasks
|
|
12
|
+
* @returns true if circular dependency would be created
|
|
13
|
+
*/
|
|
14
|
+
function hasCircularDependency(newTaskId, dependsOn, tasks) {
|
|
15
|
+
const visited = new Set();
|
|
16
|
+
const toCheck = [...dependsOn];
|
|
17
|
+
while (toCheck.length > 0) {
|
|
18
|
+
const depId = toCheck.pop();
|
|
19
|
+
const normalizedDepId = normalizeTaskId(depId);
|
|
20
|
+
if (normalizedDepId === normalizeTaskId(newTaskId)) {
|
|
21
|
+
return true; // Circular dependency found
|
|
22
|
+
}
|
|
23
|
+
if (visited.has(normalizedDepId)) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
visited.add(normalizedDepId);
|
|
27
|
+
const depTask = tasks.get(normalizedDepId);
|
|
28
|
+
if (depTask?.dependsOn) {
|
|
29
|
+
toCheck.push(...depTask.dependsOn);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if all dependencies for a task are satisfied (completed successfully)
|
|
36
|
+
*/
|
|
37
|
+
function areDependenciesSatisfied(task, tasks) {
|
|
38
|
+
if (!task.dependsOn || task.dependsOn.length === 0) {
|
|
39
|
+
return { satisfied: true, missing: [], failed: [], pending: [] };
|
|
40
|
+
}
|
|
41
|
+
const missing = [];
|
|
42
|
+
const failed = [];
|
|
43
|
+
const pending = [];
|
|
44
|
+
for (const depId of task.dependsOn) {
|
|
45
|
+
const normalizedDepId = normalizeTaskId(depId);
|
|
46
|
+
const depTask = tasks.get(normalizedDepId);
|
|
47
|
+
if (!depTask) {
|
|
48
|
+
missing.push(depId);
|
|
49
|
+
}
|
|
50
|
+
else if (depTask.status === TaskStatus.COMPLETED) {
|
|
51
|
+
// Good - dependency completed successfully
|
|
52
|
+
}
|
|
53
|
+
else if (depTask.status === TaskStatus.FAILED || depTask.status === TaskStatus.CANCELLED) {
|
|
54
|
+
failed.push(depId);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// PENDING, WAITING, RUNNING, RATE_LIMITED
|
|
58
|
+
pending.push(depId);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const satisfied = missing.length === 0 && failed.length === 0 && pending.length === 0;
|
|
62
|
+
return { satisfied, missing, failed, pending };
|
|
63
|
+
}
|
|
64
|
+
const TASK_TTL_MS = 60 * 60 * 1000;
|
|
65
|
+
const CLEANUP_INTERVAL_MS = 5 * 60 * 1000;
|
|
66
|
+
const HEALTH_CHECK_INTERVAL_MS = 5 * 1000; // Check process health every 5 seconds
|
|
67
|
+
const MAX_OUTPUT_LINES = 2000;
|
|
68
|
+
/**
|
|
69
|
+
* Check if a process is actually alive using signal 0
|
|
70
|
+
*/
|
|
71
|
+
function isProcessAlive(pid) {
|
|
72
|
+
if (!pid)
|
|
73
|
+
return false;
|
|
74
|
+
try {
|
|
75
|
+
process.kill(pid, 0); // Signal 0 = check if process exists
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
class TaskManager {
|
|
83
|
+
tasks = new Map();
|
|
84
|
+
cleanupInterval = null;
|
|
85
|
+
healthCheckInterval = null;
|
|
86
|
+
currentCwd = null;
|
|
87
|
+
persistTimeout = null;
|
|
88
|
+
persistDebounceMs = 100;
|
|
89
|
+
outputPersistDebounceMs = 1000;
|
|
90
|
+
lastPersistTrigger = 'state';
|
|
91
|
+
retryCallback = null;
|
|
92
|
+
executeCallback = null;
|
|
93
|
+
constructor() {
|
|
94
|
+
this.startCleanup();
|
|
95
|
+
this.startHealthCheck();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Set the current workspace and load persisted tasks
|
|
99
|
+
* Also triggers auto-retry for rate-limited tasks
|
|
100
|
+
*/
|
|
101
|
+
setCwd(cwd) {
|
|
102
|
+
this.currentCwd = cwd;
|
|
103
|
+
const loadedTasks = loadTasks(cwd);
|
|
104
|
+
// Load tasks into the map
|
|
105
|
+
for (const task of loadedTasks) {
|
|
106
|
+
const normalizedId = normalizeTaskId(task.id);
|
|
107
|
+
this.tasks.set(normalizedId, task);
|
|
108
|
+
}
|
|
109
|
+
// Run cleanup on loaded tasks (removes expired ones)
|
|
110
|
+
this.cleanup();
|
|
111
|
+
// Process rate-limited tasks for auto-retry
|
|
112
|
+
this.processRateLimitedTasks();
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Register a callback to be called when a rate-limited task should be retried
|
|
116
|
+
* Callback should return the new task ID
|
|
117
|
+
*/
|
|
118
|
+
onRetry(callback) {
|
|
119
|
+
this.retryCallback = callback;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Register a callback to execute a waiting task when dependencies are satisfied
|
|
123
|
+
*/
|
|
124
|
+
onExecute(callback) {
|
|
125
|
+
this.executeCallback = callback;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Process waiting tasks and start those with satisfied dependencies
|
|
129
|
+
*/
|
|
130
|
+
processWaitingTasks() {
|
|
131
|
+
const waitingTasks = Array.from(this.tasks.values())
|
|
132
|
+
.filter(t => t.status === TaskStatus.WAITING);
|
|
133
|
+
if (waitingTasks.length === 0) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
for (const task of waitingTasks) {
|
|
137
|
+
const { satisfied } = areDependenciesSatisfied(task, this.tasks);
|
|
138
|
+
if (satisfied && this.executeCallback) {
|
|
139
|
+
console.error(`[task-manager] Dependencies satisfied for ${task.id}, starting execution`);
|
|
140
|
+
this.executeCallback(task).catch(err => {
|
|
141
|
+
console.error(`[task-manager] Failed to execute task ${task.id}:`, err);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Validate dependencies for a new task
|
|
148
|
+
* Returns error message if invalid, null if valid
|
|
149
|
+
*/
|
|
150
|
+
validateDependencies(dependsOn, newTaskId) {
|
|
151
|
+
if (!dependsOn || dependsOn.length === 0) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
// Check if all dependencies exist
|
|
155
|
+
for (const depId of dependsOn) {
|
|
156
|
+
const normalizedDepId = normalizeTaskId(depId);
|
|
157
|
+
if (!this.tasks.has(normalizedDepId)) {
|
|
158
|
+
return `Dependency task '${depId}' not found`;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Check for circular dependencies (only if newTaskId provided)
|
|
162
|
+
if (newTaskId && hasCircularDependency(newTaskId, dependsOn, this.tasks)) {
|
|
163
|
+
return 'Circular dependency detected';
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get dependency status info for a task
|
|
169
|
+
*/
|
|
170
|
+
getDependencyStatus(taskId) {
|
|
171
|
+
const task = this.getTask(taskId);
|
|
172
|
+
if (!task || !task.dependsOn) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
return areDependenciesSatisfied(task, this.tasks);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Force start a waiting task, bypassing failed/missing dependencies
|
|
179
|
+
*/
|
|
180
|
+
async forceStartTask(taskId) {
|
|
181
|
+
const normalizedId = normalizeTaskId(taskId);
|
|
182
|
+
const task = this.tasks.get(normalizedId);
|
|
183
|
+
if (!task) {
|
|
184
|
+
return { success: false, error: 'Task not found' };
|
|
185
|
+
}
|
|
186
|
+
if (task.status !== TaskStatus.WAITING) {
|
|
187
|
+
return { success: false, error: `Task is not waiting (status: ${task.status})` };
|
|
188
|
+
}
|
|
189
|
+
if (!this.executeCallback) {
|
|
190
|
+
return { success: false, error: 'No execute callback registered' };
|
|
191
|
+
}
|
|
192
|
+
const bypassedDeps = task.dependsOn || [];
|
|
193
|
+
// Clear dependencies and execute
|
|
194
|
+
console.error(`[task-manager] Force starting ${task.id}, bypassing deps: ${bypassedDeps.join(', ')}`);
|
|
195
|
+
// Execute the task
|
|
196
|
+
await this.executeCallback(task);
|
|
197
|
+
return {
|
|
198
|
+
success: true,
|
|
199
|
+
taskId: task.id,
|
|
200
|
+
bypassedDeps,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Process rate-limited tasks and trigger retries for those ready
|
|
205
|
+
*/
|
|
206
|
+
processRateLimitedTasks() {
|
|
207
|
+
const rateLimitedTasks = Array.from(this.tasks.values())
|
|
208
|
+
.filter(t => t.status === TaskStatus.RATE_LIMITED);
|
|
209
|
+
if (rateLimitedTasks.length === 0) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
console.error(`[task-manager] Found ${rateLimitedTasks.length} rate-limited task(s)`);
|
|
213
|
+
for (const task of rateLimitedTasks) {
|
|
214
|
+
// Check if max retries exceeded
|
|
215
|
+
if (hasExceededMaxRetries(task)) {
|
|
216
|
+
console.error(`[task-manager] Task ${task.id} exceeded max retries, marking as failed`);
|
|
217
|
+
this.updateTask(task.id, {
|
|
218
|
+
status: TaskStatus.FAILED,
|
|
219
|
+
error: `Max retries (${task.retryInfo?.maxRetries}) exceeded for rate limit`,
|
|
220
|
+
});
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
// Check if ready for retry
|
|
224
|
+
if (shouldRetryNow(task)) {
|
|
225
|
+
console.error(`[task-manager] Auto-retrying task ${task.id} (attempt ${(task.retryInfo?.retryCount ?? 0) + 1})`);
|
|
226
|
+
if (this.retryCallback) {
|
|
227
|
+
// Mark original task as failed (retried) - new task will be created
|
|
228
|
+
this.updateTask(task.id, {
|
|
229
|
+
status: TaskStatus.FAILED,
|
|
230
|
+
error: `Auto-retried as new task (attempt ${(task.retryInfo?.retryCount ?? 0) + 1}/${task.retryInfo?.maxRetries ?? 6})`,
|
|
231
|
+
});
|
|
232
|
+
this.retryCallback(task);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
console.error(`[task-manager] No retry callback registered, task ${task.id} will wait`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
const nextRetry = task.retryInfo?.nextRetryTime;
|
|
240
|
+
const waitMs = nextRetry ? new Date(nextRetry).getTime() - Date.now() : 0;
|
|
241
|
+
const waitMin = Math.ceil(waitMs / 60000);
|
|
242
|
+
console.error(`[task-manager] Task ${task.id} not ready for retry, waiting ${waitMin} more minutes`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get all rate-limited tasks
|
|
248
|
+
*/
|
|
249
|
+
getRateLimitedTasks() {
|
|
250
|
+
return Array.from(this.tasks.values())
|
|
251
|
+
.filter(t => t.status === TaskStatus.RATE_LIMITED);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Expedite all rate-limited tasks by moving their next retry time up.
|
|
255
|
+
* Called after a successful Copilot account switch so stalled tasks benefit.
|
|
256
|
+
* Tasks are staggered to avoid thundering herd.
|
|
257
|
+
*/
|
|
258
|
+
expediteRateLimitedTasks(baseDelayMs = 5000) {
|
|
259
|
+
const rateLimitedTasks = Array.from(this.tasks.values())
|
|
260
|
+
.filter(t => t.status === TaskStatus.RATE_LIMITED && t.retryInfo);
|
|
261
|
+
if (rateLimitedTasks.length === 0) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
console.error(`[task-manager] Expediting ${rateLimitedTasks.length} rate-limited task(s) after account switch`);
|
|
265
|
+
let delay = baseDelayMs;
|
|
266
|
+
for (const task of rateLimitedTasks) {
|
|
267
|
+
if (task.retryInfo) {
|
|
268
|
+
this.updateTask(task.id, {
|
|
269
|
+
retryInfo: {
|
|
270
|
+
...task.retryInfo,
|
|
271
|
+
nextRetryTime: new Date(Date.now() + delay).toISOString(),
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
delay += 2000; // Stagger by 2 seconds per task
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Schedule retry processing after the base delay
|
|
278
|
+
setTimeout(() => this.processRateLimitedTasks(), baseDelayMs);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Clear all tasks from memory (used by clear_tasks tool)
|
|
282
|
+
*/
|
|
283
|
+
clearAllTasks() {
|
|
284
|
+
const count = this.tasks.size;
|
|
285
|
+
this.tasks.clear();
|
|
286
|
+
return count;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Manually trigger retry of a rate-limited task
|
|
290
|
+
* Returns the new task ID on success
|
|
291
|
+
*/
|
|
292
|
+
async triggerManualRetry(taskId) {
|
|
293
|
+
const normalizedId = normalizeTaskId(taskId);
|
|
294
|
+
const task = this.tasks.get(normalizedId);
|
|
295
|
+
if (!task) {
|
|
296
|
+
return { success: false, error: 'Task not found' };
|
|
297
|
+
}
|
|
298
|
+
if (task.status !== TaskStatus.RATE_LIMITED) {
|
|
299
|
+
return { success: false, error: `Task is not rate-limited (status: ${task.status})` };
|
|
300
|
+
}
|
|
301
|
+
if (!this.retryCallback) {
|
|
302
|
+
return { success: false, error: 'No retry callback registered' };
|
|
303
|
+
}
|
|
304
|
+
// Mark original task as failed (manually retried)
|
|
305
|
+
this.updateTask(task.id, {
|
|
306
|
+
status: TaskStatus.FAILED,
|
|
307
|
+
error: `Manually retried (attempt ${(task.retryInfo?.retryCount ?? 0) + 1}/${task.retryInfo?.maxRetries ?? 6})`,
|
|
308
|
+
});
|
|
309
|
+
// Trigger the retry callback - it will spawn a new task and return its ID
|
|
310
|
+
const newTaskId = await this.retryCallback(task);
|
|
311
|
+
return {
|
|
312
|
+
success: true,
|
|
313
|
+
newTaskId: newTaskId || 'unknown',
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Persist tasks to disk (debounced)
|
|
318
|
+
*/
|
|
319
|
+
schedulePersist(trigger = 'state') {
|
|
320
|
+
if (!this.currentCwd) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
// Clear existing timeout
|
|
324
|
+
if (this.persistTimeout) {
|
|
325
|
+
clearTimeout(this.persistTimeout);
|
|
326
|
+
}
|
|
327
|
+
// Use longer debounce for output-only changes (high frequency)
|
|
328
|
+
const debounceMs = trigger === 'output' && this.lastPersistTrigger === 'output'
|
|
329
|
+
? this.outputPersistDebounceMs
|
|
330
|
+
: this.persistDebounceMs;
|
|
331
|
+
this.lastPersistTrigger = trigger;
|
|
332
|
+
this.persistTimeout = setTimeout(() => {
|
|
333
|
+
this.persistNow();
|
|
334
|
+
}, debounceMs);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Persist tasks immediately
|
|
338
|
+
*/
|
|
339
|
+
persistNow() {
|
|
340
|
+
if (!this.currentCwd) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const tasks = Array.from(this.tasks.values());
|
|
344
|
+
saveTasks(this.currentCwd, tasks);
|
|
345
|
+
}
|
|
346
|
+
startCleanup() {
|
|
347
|
+
this.cleanupInterval = setInterval(() => {
|
|
348
|
+
this.cleanup();
|
|
349
|
+
}, CLEANUP_INTERVAL_MS);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Start periodic health check for running processes
|
|
353
|
+
* Detects zombie processes that exited without proper status update
|
|
354
|
+
*/
|
|
355
|
+
startHealthCheck() {
|
|
356
|
+
this.healthCheckInterval = setInterval(() => {
|
|
357
|
+
this.checkProcessHealth();
|
|
358
|
+
}, HEALTH_CHECK_INTERVAL_MS);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Check all RUNNING tasks to verify their processes are still alive
|
|
362
|
+
*/
|
|
363
|
+
checkProcessHealth() {
|
|
364
|
+
for (const task of this.tasks.values()) {
|
|
365
|
+
if (task.status === TaskStatus.RUNNING && task.pid) {
|
|
366
|
+
if (!isProcessAlive(task.pid)) {
|
|
367
|
+
console.error(`[task-manager] Health check: detected dead process for task ${task.id} (pid=${task.pid})`);
|
|
368
|
+
this.updateTask(task.id, {
|
|
369
|
+
status: TaskStatus.FAILED,
|
|
370
|
+
endTime: new Date().toISOString(),
|
|
371
|
+
error: 'Process exited unexpectedly (detected via health check)',
|
|
372
|
+
process: undefined,
|
|
373
|
+
timeoutReason: 'process_dead',
|
|
374
|
+
timeoutContext: {
|
|
375
|
+
pidAlive: false,
|
|
376
|
+
lastHeartbeatAt: task.lastHeartbeatAt,
|
|
377
|
+
lastOutputAt: task.lastOutputAt,
|
|
378
|
+
detectedBy: 'health_check',
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
const now = Date.now();
|
|
384
|
+
const lastHeartbeat = task.lastHeartbeatAt ? new Date(task.lastHeartbeatAt).getTime() : 0;
|
|
385
|
+
if (now - lastHeartbeat >= HEALTH_CHECK_INTERVAL_MS) {
|
|
386
|
+
this.updateTask(task.id, { lastHeartbeatAt: new Date(now).toISOString() });
|
|
387
|
+
}
|
|
388
|
+
if (task.lastOutputAt) {
|
|
389
|
+
const lastOutputAgeMs = now - new Date(task.lastOutputAt).getTime();
|
|
390
|
+
if (lastOutputAgeMs >= TASK_STALL_WARN_MS && task.timeoutReason !== 'stall') {
|
|
391
|
+
this.updateTask(task.id, {
|
|
392
|
+
timeoutReason: 'stall',
|
|
393
|
+
timeoutContext: {
|
|
394
|
+
lastOutputAt: task.lastOutputAt,
|
|
395
|
+
lastOutputAgeMs,
|
|
396
|
+
lastHeartbeatAt: task.lastHeartbeatAt,
|
|
397
|
+
detectedBy: 'health_check',
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
cleanup() {
|
|
407
|
+
const now = Date.now();
|
|
408
|
+
const toDelete = [];
|
|
409
|
+
for (const [id, task] of this.tasks) {
|
|
410
|
+
if (task.status === TaskStatus.COMPLETED ||
|
|
411
|
+
task.status === TaskStatus.FAILED ||
|
|
412
|
+
task.status === TaskStatus.CANCELLED) {
|
|
413
|
+
const endTime = task.endTime ? new Date(task.endTime).getTime() : 0;
|
|
414
|
+
if (now - endTime > TASK_TTL_MS) {
|
|
415
|
+
toDelete.push(id);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
for (const id of toDelete) {
|
|
420
|
+
this.tasks.delete(id);
|
|
421
|
+
}
|
|
422
|
+
if (this.tasks.size > MAX_TASKS) {
|
|
423
|
+
const sorted = Array.from(this.tasks.entries())
|
|
424
|
+
.filter(([_, t]) => t.status !== TaskStatus.RUNNING && t.status !== TaskStatus.PENDING)
|
|
425
|
+
.sort((a, b) => new Date(a[1].startTime).getTime() - new Date(b[1].startTime).getTime());
|
|
426
|
+
const toRemove = sorted.slice(0, this.tasks.size - MAX_TASKS);
|
|
427
|
+
for (const [id] of toRemove) {
|
|
428
|
+
this.tasks.delete(id);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
createTask(prompt, cwd, model, options) {
|
|
433
|
+
const id = generateTaskId();
|
|
434
|
+
const normalizedId = normalizeTaskId(id);
|
|
435
|
+
// Determine initial status based on dependencies
|
|
436
|
+
let initialStatus = TaskStatus.PENDING;
|
|
437
|
+
const dependsOn = options?.dependsOn?.filter(d => d.trim()) || [];
|
|
438
|
+
const labels = options?.labels?.filter(l => l.trim()) || [];
|
|
439
|
+
if (dependsOn.length > 0) {
|
|
440
|
+
// Check if all dependencies are already completed
|
|
441
|
+
const { satisfied } = areDependenciesSatisfied({ dependsOn }, this.tasks);
|
|
442
|
+
initialStatus = satisfied ? TaskStatus.PENDING : TaskStatus.WAITING;
|
|
443
|
+
}
|
|
444
|
+
const startTime = new Date().toISOString();
|
|
445
|
+
const task = {
|
|
446
|
+
id,
|
|
447
|
+
status: initialStatus,
|
|
448
|
+
prompt,
|
|
449
|
+
output: [],
|
|
450
|
+
startTime,
|
|
451
|
+
lastHeartbeatAt: startTime,
|
|
452
|
+
cwd,
|
|
453
|
+
model,
|
|
454
|
+
autonomous: options?.autonomous,
|
|
455
|
+
isResume: options?.isResume,
|
|
456
|
+
retryInfo: options?.retryInfo,
|
|
457
|
+
dependsOn: dependsOn.length > 0 ? dependsOn : undefined,
|
|
458
|
+
labels: labels.length > 0 ? labels : undefined,
|
|
459
|
+
provider: options?.provider,
|
|
460
|
+
fallbackAttempted: options?.fallbackAttempted,
|
|
461
|
+
switchAttempted: options?.switchAttempted,
|
|
462
|
+
};
|
|
463
|
+
this.tasks.set(normalizedId, task);
|
|
464
|
+
this.schedulePersist('state');
|
|
465
|
+
return task;
|
|
466
|
+
}
|
|
467
|
+
getTask(id) {
|
|
468
|
+
const normalizedId = normalizeTaskId(id);
|
|
469
|
+
return this.tasks.get(normalizedId) || null;
|
|
470
|
+
}
|
|
471
|
+
updateTask(id, updates) {
|
|
472
|
+
const normalizedId = normalizeTaskId(id);
|
|
473
|
+
const task = this.tasks.get(normalizedId);
|
|
474
|
+
if (!task) {
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
const previousStatus = task.status;
|
|
478
|
+
const updated = { ...task, ...updates };
|
|
479
|
+
this.tasks.set(normalizedId, updated);
|
|
480
|
+
this.schedulePersist('state');
|
|
481
|
+
// When a task completes, check if any waiting tasks can now run
|
|
482
|
+
if (updates.status === TaskStatus.COMPLETED && previousStatus !== TaskStatus.COMPLETED) {
|
|
483
|
+
this.processWaitingTasks();
|
|
484
|
+
}
|
|
485
|
+
return updated;
|
|
486
|
+
}
|
|
487
|
+
appendOutput(id, line) {
|
|
488
|
+
const normalizedId = normalizeTaskId(id);
|
|
489
|
+
const task = this.tasks.get(normalizedId);
|
|
490
|
+
if (task) {
|
|
491
|
+
const now = new Date().toISOString();
|
|
492
|
+
task.lastOutputAt = now;
|
|
493
|
+
task.lastHeartbeatAt = now;
|
|
494
|
+
if (task.timeoutReason === 'stall') {
|
|
495
|
+
task.timeoutReason = undefined;
|
|
496
|
+
task.timeoutContext = undefined;
|
|
497
|
+
}
|
|
498
|
+
task.output.push(line);
|
|
499
|
+
if (task.output.length > MAX_OUTPUT_LINES) {
|
|
500
|
+
task.output = task.output.slice(-MAX_OUTPUT_LINES);
|
|
501
|
+
}
|
|
502
|
+
if (!task.sessionId) {
|
|
503
|
+
const sessionMatch = line.match(/(?:Session ID:|session[_-]?id[=:]?)\s*([a-zA-Z0-9_-]+)/i);
|
|
504
|
+
if (sessionMatch) {
|
|
505
|
+
task.sessionId = sessionMatch[1];
|
|
506
|
+
this.schedulePersist('state');
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
this.schedulePersist('output');
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
getAllTasks(statusFilter) {
|
|
514
|
+
const tasks = Array.from(this.tasks.values());
|
|
515
|
+
if (statusFilter) {
|
|
516
|
+
return tasks.filter(t => t.status === statusFilter);
|
|
517
|
+
}
|
|
518
|
+
return tasks;
|
|
519
|
+
}
|
|
520
|
+
cancelTask(id) {
|
|
521
|
+
const normalizedId = normalizeTaskId(id);
|
|
522
|
+
const task = this.tasks.get(normalizedId);
|
|
523
|
+
if (!task) {
|
|
524
|
+
return { success: false, error: 'Task not found' };
|
|
525
|
+
}
|
|
526
|
+
if (task.status !== TaskStatus.RUNNING && task.status !== TaskStatus.PENDING && task.status !== TaskStatus.WAITING) {
|
|
527
|
+
return { success: false, error: `Task is not cancellable (status: ${task.status})` };
|
|
528
|
+
}
|
|
529
|
+
let alreadyDead = false;
|
|
530
|
+
if (task.process) {
|
|
531
|
+
// First check if process is actually alive
|
|
532
|
+
if (task.pid && !isProcessAlive(task.pid)) {
|
|
533
|
+
alreadyDead = true;
|
|
534
|
+
console.error(`[task-manager] Cancel: process for task ${task.id} was already dead (pid=${task.pid})`);
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
try {
|
|
538
|
+
task.process.kill('SIGTERM');
|
|
539
|
+
}
|
|
540
|
+
catch (err) {
|
|
541
|
+
// Process may already be dead
|
|
542
|
+
alreadyDead = true;
|
|
543
|
+
console.error(`[task-manager] Cancel: kill failed for task ${task.id}: ${err}`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
task.status = TaskStatus.CANCELLED;
|
|
548
|
+
task.endTime = new Date().toISOString();
|
|
549
|
+
if (alreadyDead) {
|
|
550
|
+
task.error = 'Process had already exited before cancellation';
|
|
551
|
+
}
|
|
552
|
+
task.process = undefined;
|
|
553
|
+
this.schedulePersist('state');
|
|
554
|
+
return { success: true, alreadyDead };
|
|
555
|
+
}
|
|
556
|
+
shutdown() {
|
|
557
|
+
if (this.cleanupInterval) {
|
|
558
|
+
clearInterval(this.cleanupInterval);
|
|
559
|
+
this.cleanupInterval = null;
|
|
560
|
+
}
|
|
561
|
+
if (this.healthCheckInterval) {
|
|
562
|
+
clearInterval(this.healthCheckInterval);
|
|
563
|
+
this.healthCheckInterval = null;
|
|
564
|
+
}
|
|
565
|
+
if (this.persistTimeout) {
|
|
566
|
+
clearTimeout(this.persistTimeout);
|
|
567
|
+
this.persistTimeout = null;
|
|
568
|
+
}
|
|
569
|
+
for (const task of this.tasks.values()) {
|
|
570
|
+
if (task.process && task.status === TaskStatus.RUNNING) {
|
|
571
|
+
try {
|
|
572
|
+
task.process.kill('SIGTERM');
|
|
573
|
+
}
|
|
574
|
+
catch {
|
|
575
|
+
// Ignore
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
// Final persist before shutdown
|
|
580
|
+
this.persistNow();
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
export const taskManager = new TaskManager();
|
|
584
|
+
//# sourceMappingURL=task-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-manager.js","sourceRoot":"","sources":["../../src/services/task-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAa,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB;;;;;;GAMG;AACH,SAAS,qBAAqB,CAAC,SAAiB,EAAE,SAAmB,EAAE,KAA6B;IAClG,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,OAAO,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAG,CAAC;QAC7B,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAE/C,IAAI,eAAe,KAAK,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,OAAO,IAAI,CAAC,CAAC,4BAA4B;QAC3C,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YACjC,SAAS;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAE7B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC3C,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAAC,IAAe,EAAE,KAA6B;IAC9E,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACnE,CAAC;IAED,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAE3C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,SAAS,EAAE,CAAC;YACnD,2CAA2C;QAC7C,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,SAAS,EAAE,CAAC;YAC3F,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,0CAA0C;YAC1C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;IACtF,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC;AACD,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAC1C,MAAM,wBAAwB,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,uCAAuC;AAClF,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B;;GAEG;AACH,SAAS,cAAc,CAAC,GAAuB;IAC7C,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,qCAAqC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,WAAW;IACP,KAAK,GAA2B,IAAI,GAAG,EAAE,CAAC;IAC1C,eAAe,GAA0B,IAAI,CAAC;IAC9C,mBAAmB,GAA0B,IAAI,CAAC;IAClD,UAAU,GAAkB,IAAI,CAAC;IACjC,cAAc,GAA0B,IAAI,CAAC;IAC7C,iBAAiB,GAAG,GAAG,CAAC;IACxB,uBAAuB,GAAG,IAAI,CAAC;IAC/B,kBAAkB,GAAuB,OAAO,CAAC;IACjD,aAAa,GAA8D,IAAI,CAAC;IAChF,eAAe,GAAgD,IAAI,CAAC;IAE5E;QACE,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAEnC,0BAA0B;QAC1B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,qDAAqD;QACrD,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,4CAA4C;QAC5C,IAAI,CAAC,uBAAuB,EAAE,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,QAA0D;QAChE,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,QAA4C;QACpD,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;IAClC,CAAC;IAED;;OAEG;IACK,mBAAmB;QACzB,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;aACjD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC;QAEhD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAChC,MAAM,EAAE,SAAS,EAAE,GAAG,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAEjE,IAAI,SAAS,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACtC,OAAO,CAAC,KAAK,CAAC,6CAA6C,IAAI,CAAC,EAAE,sBAAsB,CAAC,CAAC;gBAC1F,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACrC,OAAO,CAAC,KAAK,CAAC,yCAAyC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC1E,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,oBAAoB,CAAC,SAAmB,EAAE,SAAkB;QAC1D,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kCAAkC;QAClC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC9B,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;YAC/C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;gBACrC,OAAO,oBAAoB,KAAK,aAAa,CAAC;YAChD,CAAC;QACH,CAAC;QAED,+DAA+D;QAC/D,IAAI,SAAS,IAAI,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,OAAO,8BAA8B,CAAC;QACxC,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,MAAc;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,MAAc;QACjC,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAE1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QACrD,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gCAAgC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACnF,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC;QACrE,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QAE1C,iCAAiC;QACjC,OAAO,CAAC,KAAK,CAAC,iCAAiC,IAAI,CAAC,EAAE,qBAAqB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEtG,mBAAmB;QACnB,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAEjC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,YAAY;SACb,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,uBAAuB;QAC7B,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;aACrD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,YAAY,CAAC,CAAC;QAErD,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,wBAAwB,gBAAgB,CAAC,MAAM,uBAAuB,CAAC,CAAC;QAEtF,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;YACpC,gCAAgC;YAChC,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChC,OAAO,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,EAAE,0CAA0C,CAAC,CAAC;gBACxF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE;oBACvB,MAAM,EAAE,UAAU,CAAC,MAAM;oBACzB,KAAK,EAAE,gBAAgB,IAAI,CAAC,SAAS,EAAE,UAAU,2BAA2B;iBAC7E,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,2BAA2B;YAC3B,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,qCAAqC,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAEjH,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;oBACvB,oEAAoE;oBACpE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE;wBACvB,MAAM,EAAE,UAAU,CAAC,MAAM;wBACzB,KAAK,EAAE,qCAAqC,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,UAAU,IAAI,CAAC,GAAG;qBACxH,CAAC,CAAC;oBACH,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,qDAAqD,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;gBAC1F,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;gBAChD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;gBAC1C,OAAO,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,EAAE,iCAAiC,OAAO,eAAe,CAAC,CAAC;YACvG,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;aACnC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,YAAY,CAAC,CAAC;IACvD,CAAC;IAED;;;;OAIG;IACH,wBAAwB,CAAC,cAAsB,IAAI;QACjD,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;aACrD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,YAAY,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;QAEpE,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,6BAA6B,gBAAgB,CAAC,MAAM,4CAA4C,CAAC,CAAC;QAEhH,IAAI,KAAK,GAAG,WAAW,CAAC;QACxB,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE;oBACvB,SAAS,EAAE;wBACT,GAAG,IAAI,CAAC,SAAS;wBACjB,aAAa,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,WAAW,EAAE;qBAC1D;iBACF,CAAC,CAAC;gBACH,KAAK,IAAI,IAAI,CAAC,CAAC,gCAAgC;YACjD,CAAC;QACH,CAAC;QAED,iDAAiD;QACjD,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,WAAW,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,aAAa;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB,CAAC,MAAc;QACrC,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAE1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QACrD,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,YAAY,EAAE,CAAC;YAC5C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACxF,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;QACnE,CAAC;QAED,kDAAkD;QAClD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE;YACvB,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,KAAK,EAAE,6BAA6B,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,UAAU,IAAI,CAAC,GAAG;SAChH,CAAC,CAAC;QAEH,0EAA0E;QAC1E,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEjD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,SAAS,IAAI,SAAS;SAClC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,UAA8B,OAAO;QAC3D,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,yBAAyB;QACzB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpC,CAAC;QAED,+DAA+D;QAC/D,MAAM,UAAU,GAAG,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,kBAAkB,KAAK,QAAQ;YAC7E,CAAC,CAAC,IAAI,CAAC,uBAAuB;YAC9B,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAE3B,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC;QAElC,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC,EAAE,UAAU,CAAC,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,UAAU;QAChB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;YACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACK,gBAAgB;QACtB,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE;YAC1C,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACnD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9B,OAAO,CAAC,KAAK,CAAC,+DAA+D,IAAI,CAAC,EAAE,SAAS,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;oBAC1G,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE;wBACvB,MAAM,EAAE,UAAU,CAAC,MAAM;wBACzB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACjC,KAAK,EAAE,yDAAyD;wBAChE,OAAO,EAAE,SAAS;wBAClB,aAAa,EAAE,cAAc;wBAC7B,cAAc,EAAE;4BACd,QAAQ,EAAE,KAAK;4BACf,eAAe,EAAE,IAAI,CAAC,eAAe;4BACrC,YAAY,EAAE,IAAI,CAAC,YAAY;4BAC/B,UAAU,EAAE,cAAc;yBAC3B;qBACF,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACvB,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC1F,IAAI,GAAG,GAAG,aAAa,IAAI,wBAAwB,EAAE,CAAC;wBACpD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;oBAC7E,CAAC;oBACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBACtB,MAAM,eAAe,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;wBACpE,IAAI,eAAe,IAAI,kBAAkB,IAAI,IAAI,CAAC,aAAa,KAAK,OAAO,EAAE,CAAC;4BAC5E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE;gCACvB,aAAa,EAAE,OAAO;gCACtB,cAAc,EAAE;oCACd,YAAY,EAAE,IAAI,CAAC,YAAY;oCAC/B,eAAe;oCACf,eAAe,EAAE,IAAI,CAAC,eAAe;oCACrC,UAAU,EAAE,cAAc;iCAC3B;6BACF,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,SAAS;gBACpC,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM;gBACjC,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,SAAS,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpE,IAAI,GAAG,GAAG,OAAO,GAAG,WAAW,EAAE,CAAC;oBAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;iBAC5C,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,CAAC;iBACtF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAE3F,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;YAC9D,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,QAAQ,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,UAAU,CAAC,MAAc,EAAE,GAAY,EAAE,KAAc,EAAE,OAA+O;QACtS,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QAEzC,iDAAiD;QACjD,IAAI,aAAa,GAAG,UAAU,CAAC,OAAO,CAAC;QACvC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QAClE,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QAE5D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,kDAAkD;YAClD,MAAM,EAAE,SAAS,EAAE,GAAG,wBAAwB,CAAC,EAAE,SAAS,EAAe,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACvF,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;QACtE,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAc;YACtB,EAAE;YACF,MAAM,EAAE,aAAa;YACrB,MAAM;YACN,MAAM,EAAE,EAAE;YACV,SAAS;YACT,eAAe,EAAE,SAAS;YAC1B,GAAG;YACH,KAAK;YACL,UAAU,EAAE,OAAO,EAAE,UAAU;YAC/B,QAAQ,EAAE,OAAO,EAAE,QAAQ;YAC3B,SAAS,EAAE,OAAO,EAAE,SAAS;YAC7B,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACvD,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YAC9C,QAAQ,EAAE,OAAO,EAAE,QAAQ;YAC3B,iBAAiB,EAAE,OAAO,EAAE,iBAAiB;YAC7C,eAAe,EAAE,OAAO,EAAE,eAAe;SAC1C,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,MAAM,YAAY,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED,UAAU,CAAC,EAAU,EAAE,OAA2B;QAChD,MAAM,YAAY,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;QACnC,MAAM,OAAO,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAE9B,gEAAgE;QAChE,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,SAAS,IAAI,cAAc,KAAK,UAAU,CAAC,SAAS,EAAE,CAAC;YACvF,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,YAAY,CAAC,EAAU,EAAE,IAAY;QACnC,MAAM,YAAY,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1C,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC;YACxB,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC;YAC3B,IAAI,IAAI,CAAC,aAAa,KAAK,OAAO,EAAE,CAAC;gBACnC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;gBAC/B,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;YAClC,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEvB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;gBAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,CAAC;YACrD,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;gBAC3F,IAAI,YAAY,EAAE,CAAC;oBACjB,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;oBACjC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;oBAC9B,OAAO;gBACT,CAAC;YACH,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,WAAW,CAAC,YAAyB;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,UAAU,CAAC,EAAU;QACnB,MAAM,YAAY,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QACrD,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;YACnH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACvF,CAAC;QAED,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,2CAA2C;YAC3C,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1C,WAAW,GAAG,IAAI,CAAC;gBACnB,OAAO,CAAC,KAAK,CAAC,2CAA2C,IAAI,CAAC,EAAE,0BAA0B,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;YACzG,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC;oBACH,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC/B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,8BAA8B;oBAC9B,WAAW,GAAG,IAAI,CAAC;oBACnB,OAAO,CAAC,KAAK,CAAC,+CAA+C,IAAI,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;gBAClF,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACxC,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC,KAAK,GAAG,gDAAgD,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACxC,CAAC;IAED,QAAQ;QACN,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACpC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;QAED,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,aAAa,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACxC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;gBACvD,IAAI,CAAC;oBACH,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC/B,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { TaskState } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get the storage directory path (~/.super-agents/)
|
|
4
|
+
*/
|
|
5
|
+
export declare function getStorageDir(): string;
|
|
6
|
+
/**
|
|
7
|
+
* Get MD5 hash of a string
|
|
8
|
+
*/
|
|
9
|
+
export declare function hashCwd(cwd: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Get the storage file path for a given cwd
|
|
12
|
+
* Returns: ~/.super-agents/{md5(cwd)}.json
|
|
13
|
+
*/
|
|
14
|
+
export declare function getStoragePath(cwd: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Save tasks to disk with atomic write
|
|
17
|
+
*/
|
|
18
|
+
export declare function saveTasks(cwd: string, tasks: TaskState[]): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Load tasks from disk
|
|
21
|
+
* Returns empty array if file doesn't exist or is corrupted
|
|
22
|
+
* Marks orphaned running tasks as failed
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadTasks(cwd: string): TaskState[];
|
|
25
|
+
/**
|
|
26
|
+
* Delete storage file for a cwd (for testing/cleanup)
|
|
27
|
+
*/
|
|
28
|
+
export declare function deleteStorage(cwd: string): boolean;
|
|
29
|
+
//# sourceMappingURL=task-persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-persistence.d.ts","sourceRoot":"","sources":["../../src/services/task-persistence.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAc,MAAM,aAAa,CAAC;AAIpD;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAmED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CA8BlE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CAsBlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAYlD"}
|