spawnee 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 spencech
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,265 @@
1
+ # spawnee
2
+
3
+ Spawn and orchestrate Cursor Cloud Agents from task templates with dependency resolution, parallel execution, and automatic retries.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g spawnee
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Initialize a config file
15
+ spawnee init
16
+
17
+ # Edit .spawneerc.json with your API key
18
+
19
+ # Validate a template
20
+ spawnee validate my-tasks.yaml
21
+
22
+ # Dry run (preview without spawning agents)
23
+ spawnee run my-tasks.yaml --dry-run
24
+
25
+ # Execute the template
26
+ spawnee run my-tasks.yaml
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ spawnee supports three configuration methods with the following priority (highest to lowest):
32
+
33
+ 1. **CLI flags** - Override everything
34
+ 2. **Environment variables** - Override config file and defaults
35
+ 3. **Config file** (`.spawneerc.json`) - Override defaults
36
+ 4. **Built-in defaults**
37
+
38
+ ### Configuration Options
39
+
40
+ | Option | CLI Flag | Environment Variable | Config Key | Default |
41
+ |--------|----------|---------------------|------------|---------|
42
+ | API Key | `--api-key, -k` | `SPAWNEE_API_KEY` | `apiKey` | (required) |
43
+ | API Base URL | `--api-url` | `SPAWNEE_API_URL` | `apiBaseUrl` | `https://api.cursor.com` |
44
+ | Max Concurrent | `--concurrency, -c` | `SPAWNEE_CONCURRENCY` | `maxConcurrent` | `10` |
45
+ | Poll Interval | `--poll-interval` | `SPAWNEE_POLL_INTERVAL` | `pollInterval` | `15000` (ms) |
46
+ | Default Timeout | `--timeout, -t` | `SPAWNEE_TIMEOUT` | `defaultTimeout` | `3600000` (ms) |
47
+ | State File | `--state-file` | `SPAWNEE_STATE_FILE` | `stateFile` | `.spawnee-state.json` |
48
+ | Config File | `--config` | `SPAWNEE_CONFIG` | - | `.spawneerc.json` |
49
+ | Verbose | `--verbose, -v` | `SPAWNEE_VERBOSE` | `verbose` | `false` |
50
+
51
+ ### Config File
52
+
53
+ Create a `.spawneerc.json` file in your project root:
54
+
55
+ ```json
56
+ {
57
+ "apiKey": "your-cursor-api-key",
58
+ "apiBaseUrl": "https://api.cursor.com",
59
+ "maxConcurrent": 10,
60
+ "pollInterval": 15000,
61
+ "defaultTimeout": 3600000,
62
+ "stateFile": ".spawnee-state.json",
63
+ "verbose": false
64
+ }
65
+ ```
66
+
67
+ Or generate one with:
68
+
69
+ ```bash
70
+ spawnee init
71
+ ```
72
+
73
+ ### Environment Variables
74
+
75
+ ```bash
76
+ export SPAWNEE_API_KEY="your-cursor-api-key"
77
+ export SPAWNEE_CONCURRENCY=5
78
+ export SPAWNEE_TIMEOUT=7200000
79
+ export SPAWNEE_VERBOSE=true
80
+ ```
81
+
82
+ ### CLI Flags
83
+
84
+ ```bash
85
+ spawnee run my-tasks.yaml \
86
+ --api-key "your-key" \
87
+ --concurrency 5 \
88
+ --timeout 7200000 \
89
+ --poll-interval 10000 \
90
+ --state-file ".my-state.json" \
91
+ --verbose
92
+ ```
93
+
94
+ ## Commands
95
+
96
+ ### `spawnee run <template>`
97
+
98
+ Execute a task template.
99
+
100
+ ```bash
101
+ spawnee run my-tasks.yaml [options]
102
+ ```
103
+
104
+ **Options:**
105
+ - `-k, --api-key <key>` - Cursor API key
106
+ - `--api-url <url>` - API base URL
107
+ - `-c, --concurrency <n>` - Max concurrent agents
108
+ - `-t, --timeout <ms>` - Default task timeout
109
+ - `--poll-interval <ms>` - Status poll interval
110
+ - `--state-file <path>` - State file for persistence
111
+ - `-d, --dry-run` - Preview without spawning agents
112
+ - `--no-persist` - Disable state persistence
113
+ - `-v, --verbose` - Enable verbose output
114
+
115
+ ### `spawnee validate <template>`
116
+
117
+ Validate a task template without running it.
118
+
119
+ ```bash
120
+ spawnee validate my-tasks.yaml
121
+ ```
122
+
123
+ ### `spawnee status`
124
+
125
+ Check status of running agents.
126
+
127
+ ```bash
128
+ spawnee status [options]
129
+ ```
130
+
131
+ **Options:**
132
+ - `-k, --api-key <key>` - Cursor API key
133
+ - `--api-url <url>` - API base URL
134
+
135
+ ### `spawnee cancel <agent-id>`
136
+
137
+ Cancel a running agent.
138
+
139
+ ```bash
140
+ spawnee cancel abc123def456
141
+ ```
142
+
143
+ ### `spawnee init`
144
+
145
+ Create a `.spawneerc.json` config file.
146
+
147
+ ```bash
148
+ spawnee init # Create config file
149
+ spawnee init --force # Overwrite existing
150
+ ```
151
+
152
+ ### `spawnee config`
153
+
154
+ Show the resolved configuration (useful for debugging).
155
+
156
+ ```bash
157
+ spawnee config
158
+ ```
159
+
160
+ ## Task Templates
161
+
162
+ Templates can be JSON or YAML. Here's a complete example:
163
+
164
+ ```yaml
165
+ name: "My Task Plan"
166
+ repository:
167
+ url: "https://github.com/your-org/your-repo"
168
+ branch: "main"
169
+ baseBranch: "develop"
170
+
171
+ defaults:
172
+ model: "auto"
173
+ timeout: 3600000
174
+ retries: 2
175
+
176
+ context:
177
+ instructions: |
178
+ You are implementing features for a Node.js application.
179
+ Follow existing code patterns and conventions.
180
+ files:
181
+ - "README.md"
182
+ - "package.json"
183
+
184
+ tasks:
185
+ - id: "setup"
186
+ name: "Project Setup"
187
+ priority: 100
188
+ branch: "feature/setup"
189
+ prompt: |
190
+ Initialize the project structure:
191
+ 1. Create necessary directories
192
+ 2. Set up configuration files
193
+
194
+ - id: "feature-a"
195
+ name: "Feature A"
196
+ dependsOn: ["setup"]
197
+ priority: 80
198
+ branch: "feature/a"
199
+ prompt: |
200
+ Implement Feature A with tests.
201
+ files:
202
+ - "src/features/"
203
+
204
+ - id: "feature-b"
205
+ name: "Feature B"
206
+ dependsOn: ["setup"]
207
+ priority: 80
208
+ branch: "feature/b"
209
+ prompt: |
210
+ Implement Feature B with tests.
211
+
212
+ - id: "integration"
213
+ name: "Integration"
214
+ dependsOn: ["feature-a", "feature-b"]
215
+ priority: 60
216
+ branch: "feature/integration"
217
+ prompt: |
218
+ Integrate features and add integration tests.
219
+ validation:
220
+ command: "npm test"
221
+ successPattern: "passed"
222
+ ```
223
+
224
+ ### Template Schema
225
+
226
+ **Required fields:**
227
+ - `name` - Template name
228
+ - `repository.url` - GitHub repository URL
229
+ - `tasks` - Array of tasks
230
+
231
+ **Task fields:**
232
+ - `id` (required) - Unique task identifier
233
+ - `name` (required) - Human-readable name
234
+ - `prompt` (required) - Instructions for the agent
235
+ - `dependsOn` - Array of task IDs this task depends on
236
+ - `priority` - Higher runs first (default: 0)
237
+ - `branch` - Git branch for the task
238
+ - `files` - Files to include in context
239
+ - `timeout` - Task-specific timeout (ms)
240
+ - `retries` - Max retry attempts
241
+ - `complete` - Mark as already complete (skip)
242
+ - `validation.command` - Command to verify completion
243
+ - `validation.successPattern` - Expected output pattern
244
+
245
+ ## Features
246
+
247
+ - **Dependency Resolution** - Tasks run in correct order based on `dependsOn`
248
+ - **Parallel Execution** - Independent tasks run concurrently (up to `maxConcurrent`)
249
+ - **Automatic Retries** - Failed tasks retry with configurable attempts
250
+ - **State Persistence** - Resume interrupted runs from where they left off
251
+ - **Validation** - Optional command validation for task completion
252
+ - **Dry Run** - Preview task graph without spawning agents
253
+
254
+ ## Limits
255
+
256
+ - Maximum 256 concurrent agents per API key
257
+ - Usage-based pricing (same as Cursor Background Agents)
258
+
259
+ ## Getting Your API Key
260
+
261
+ Get your Cursor API key from: **Cursor Dashboard → Integrations → User API Keys**
262
+
263
+ ## License
264
+
265
+ MIT
@@ -0,0 +1,45 @@
1
+ import { EventEmitter } from 'events';
2
+ import { TaskInput } from './task-queue.js';
3
+ import { StateStore } from '../storage/state-store.js';
4
+ import { Config } from '../utils/config.js';
5
+ export interface OrchestratorOptions {
6
+ config: Config;
7
+ stateStore?: StateStore;
8
+ repository: string;
9
+ baseBranch: string;
10
+ globalContext?: string;
11
+ globalFiles?: string[];
12
+ }
13
+ export declare class Orchestrator extends EventEmitter {
14
+ private client;
15
+ private queue;
16
+ private stateStore?;
17
+ private logger;
18
+ private options;
19
+ private activeAgents;
20
+ private timeouts;
21
+ private isRunning;
22
+ private templateName;
23
+ constructor(options: OrchestratorOptions);
24
+ private setupEventHandlers;
25
+ loadTasks(templateName: string, tasks: TaskInput[]): void;
26
+ start(): Promise<void>;
27
+ private trySpawnAgents;
28
+ private spawnAgent;
29
+ private buildPrompt;
30
+ private handleAgentComplete;
31
+ private handleAgentFailed;
32
+ private clearTimeout;
33
+ private clearAllTimeouts;
34
+ private saveState;
35
+ stop(): Promise<void>;
36
+ getStatus(): {
37
+ isRunning: boolean;
38
+ queue: Record<string, number>;
39
+ activeAgents: Array<{
40
+ agentId: string;
41
+ taskId: string;
42
+ }>;
43
+ };
44
+ sendFollowUp(taskId: string, message: string): Promise<void>;
45
+ }
@@ -0,0 +1,240 @@
1
+ import { EventEmitter } from 'events';
2
+ import { CursorClient } from '../cursor/client.js';
3
+ import { TaskQueue } from './task-queue.js';
4
+ import { Logger } from '../utils/logger.js';
5
+ export class Orchestrator extends EventEmitter {
6
+ client;
7
+ queue;
8
+ stateStore;
9
+ logger;
10
+ options;
11
+ activeAgents = new Map(); // agentId -> taskId
12
+ timeouts = new Map();
13
+ isRunning = false;
14
+ templateName = '';
15
+ constructor(options) {
16
+ super();
17
+ this.options = options;
18
+ this.client = new CursorClient(options.config.apiKey, options.config.apiBaseUrl);
19
+ this.queue = new TaskQueue();
20
+ this.stateStore = options.stateStore;
21
+ this.logger = new Logger('Orchestrator');
22
+ this.setupEventHandlers();
23
+ }
24
+ setupEventHandlers() {
25
+ this.queue.on('taskReady', () => this.trySpawnAgents());
26
+ this.queue.on('taskCompleted', (task) => {
27
+ this.logger.success(`Task completed: ${task.id}`);
28
+ this.emit('taskCompleted', task);
29
+ this.saveState();
30
+ });
31
+ this.queue.on('taskFailed', (task) => {
32
+ this.logger.error(`Task failed: ${task.id} - ${task.error}`);
33
+ this.emit('taskFailed', task);
34
+ this.saveState();
35
+ });
36
+ this.queue.on('taskRetry', (task) => {
37
+ this.logger.warn(`Retrying task: ${task.id} (attempt ${task.attempts + 1})`);
38
+ this.emit('taskRetry', task);
39
+ });
40
+ this.queue.on('allComplete', (results) => {
41
+ this.isRunning = false;
42
+ this.client.stopAllMonitoring();
43
+ this.clearAllTimeouts();
44
+ this.logger.info('All tasks complete');
45
+ this.emit('complete', results);
46
+ this.stateStore?.clear();
47
+ });
48
+ this.client.on('completed', ({ agentId, ...agent }) => {
49
+ this.handleAgentComplete(agentId, agent);
50
+ });
51
+ this.client.on('failed', ({ agentId, ...agent }) => {
52
+ const errorMsg = agent.summary || 'Agent failed';
53
+ this.handleAgentFailed(agentId, errorMsg);
54
+ });
55
+ this.client.on('cancelled', ({ agentId }) => {
56
+ this.handleAgentFailed(agentId, 'Agent was stopped');
57
+ });
58
+ this.client.on('error', ({ agentId, error }) => {
59
+ this.logger.error(`Agent ${agentId} error: ${error.message}`);
60
+ });
61
+ }
62
+ loadTasks(templateName, tasks) {
63
+ this.templateName = templateName;
64
+ this.queue.addTasks(tasks);
65
+ const completedCount = tasks.filter(t => t.complete).length;
66
+ const activeCount = tasks.length - completedCount;
67
+ this.logger.info(`Loaded ${tasks.length} tasks from "${templateName}"${completedCount > 0 ? ` (${completedCount} already completed, ${activeCount} active)` : ''}`);
68
+ }
69
+ async start() {
70
+ if (this.isRunning)
71
+ throw new Error('Orchestrator is already running');
72
+ this.isRunning = true;
73
+ this.logger.info('Starting orchestration...');
74
+ this.emit('started', this.queue.getStatus());
75
+ await this.saveState();
76
+ await this.trySpawnAgents();
77
+ }
78
+ async trySpawnAgents() {
79
+ if (!this.isRunning)
80
+ return;
81
+ const availableSlots = this.options.config.maxConcurrent - this.activeAgents.size;
82
+ if (availableSlots <= 0)
83
+ return;
84
+ const readyTasks = this.queue.getReadyTasks().slice(0, availableSlots);
85
+ for (const task of readyTasks) {
86
+ try {
87
+ await this.spawnAgent(task);
88
+ }
89
+ catch (error) {
90
+ this.logger.error(`Failed to spawn agent for ${task.id}: ${error}`);
91
+ this.queue.markFailed(task.id, error.message);
92
+ }
93
+ }
94
+ }
95
+ async spawnAgent(task) {
96
+ const prompt = this.buildPrompt(task);
97
+ this.logger.info(`Spawning agent for task: ${task.id}`);
98
+ const agent = await this.client.createAgent({
99
+ prompt,
100
+ repository: this.options.repository,
101
+ branchName: task.branch || `task/${task.id}`,
102
+ ref: this.options.baseBranch,
103
+ autoCreatePr: true,
104
+ });
105
+ this.activeAgents.set(agent.id, task.id);
106
+ this.queue.markRunning(task.id, agent.id);
107
+ this.client.startMonitoring(agent.id, this.options.config.pollInterval);
108
+ const timeout = task.timeout || this.options.config.defaultTimeout;
109
+ const timer = setTimeout(() => {
110
+ if (!this.activeAgents.has(agent.id))
111
+ return;
112
+ this.logger.warn(`Task ${task.id} timed out`);
113
+ this.client.stopAgent(agent.id).catch(() => { });
114
+ this.handleAgentFailed(agent.id, 'Timeout exceeded');
115
+ }, timeout);
116
+ this.timeouts.set(agent.id, timer);
117
+ this.emit('agentSpawned', { taskId: task.id, agentId: agent.id });
118
+ await this.saveState();
119
+ }
120
+ buildPrompt(task) {
121
+ const parts = [];
122
+ if (this.options.globalContext) {
123
+ parts.push(`## Global Instructions\n${this.options.globalContext}`);
124
+ }
125
+ if (this.options.globalFiles?.length) {
126
+ parts.push(`## Reference Files\n${this.options.globalFiles.map(f => `- ${f}`).join('\n')}`);
127
+ }
128
+ // Add dependency context - reference previous agents' work
129
+ if (task.dependsOn.length > 0) {
130
+ const dependencyInfo = [];
131
+ for (const depId of task.dependsOn) {
132
+ const depTask = this.queue.getTask(depId);
133
+ if (depTask?.result) {
134
+ const branchInfo = depTask.result.branch ? ` (branch: ${depTask.result.branch})` : '';
135
+ const prInfo = depTask.result.pullRequestUrl ? `\n PR: ${depTask.result.pullRequestUrl}` : '';
136
+ dependencyInfo.push(`- **${depTask.name}**${branchInfo}${prInfo}`);
137
+ }
138
+ else if (depTask) {
139
+ dependencyInfo.push(`- **${depTask.name}** (in progress)`);
140
+ }
141
+ }
142
+ if (dependencyInfo.length > 0) {
143
+ parts.push(`## Dependencies\nThis task depends on the following completed tasks:\n${dependencyInfo.join('\n')}\n\nPlease review the work from these dependencies before proceeding. If they created documentation or files, reference those in your work.`);
144
+ }
145
+ }
146
+ if (task.files?.length) {
147
+ parts.push(`## Task-Specific Files\n${task.files.map(f => `- ${f}`).join('\n')}`);
148
+ }
149
+ parts.push(`## Task\n${task.prompt}`);
150
+ if (task.validation) {
151
+ parts.push(`## Validation\nAfter completing the task, verify by running:\n\`${task.validation.command}\`\nExpected output should match: ${task.validation.successPattern}`);
152
+ }
153
+ return parts.join('\n\n');
154
+ }
155
+ handleAgentComplete(agentId, agent) {
156
+ const taskId = this.activeAgents.get(agentId);
157
+ if (!taskId)
158
+ return;
159
+ this.activeAgents.delete(agentId);
160
+ this.clearTimeout(agentId);
161
+ this.queue.markCompleted(taskId, {
162
+ branch: agent.target?.branchName,
163
+ pullRequestUrl: agent.target?.prUrl
164
+ });
165
+ this.trySpawnAgents();
166
+ }
167
+ handleAgentFailed(agentId, error) {
168
+ const taskId = this.activeAgents.get(agentId);
169
+ if (!taskId)
170
+ return;
171
+ this.activeAgents.delete(agentId);
172
+ this.clearTimeout(agentId);
173
+ this.client.stopMonitoring(agentId);
174
+ this.queue.markFailed(taskId, error);
175
+ this.trySpawnAgents();
176
+ }
177
+ clearTimeout(agentId) {
178
+ const timer = this.timeouts.get(agentId);
179
+ if (!timer)
180
+ return;
181
+ clearTimeout(timer);
182
+ this.timeouts.delete(agentId);
183
+ }
184
+ clearAllTimeouts() {
185
+ for (const timer of this.timeouts.values())
186
+ clearTimeout(timer);
187
+ this.timeouts.clear();
188
+ }
189
+ async saveState() {
190
+ if (!this.stateStore)
191
+ return;
192
+ const tasks = this.queue.getAllTasks().map(t => ({
193
+ id: t.id,
194
+ name: t.name,
195
+ status: t.status,
196
+ agentId: t.agentId,
197
+ attempts: t.attempts,
198
+ error: t.error,
199
+ result: t.result,
200
+ }));
201
+ const state = {
202
+ templateName: this.templateName,
203
+ startedAt: new Date().toISOString(),
204
+ updatedAt: new Date().toISOString(),
205
+ repository: this.options.repository,
206
+ tasks,
207
+ activeAgents: Array.from(this.activeAgents.entries()).map(([agentId, taskId]) => ({ agentId, taskId })),
208
+ };
209
+ await this.stateStore.save(state);
210
+ }
211
+ async stop() {
212
+ this.isRunning = false;
213
+ this.client.stopAllMonitoring();
214
+ this.clearAllTimeouts();
215
+ for (const agentId of this.activeAgents.keys()) {
216
+ try {
217
+ await this.client.stopAgent(agentId);
218
+ }
219
+ catch {
220
+ // Ignore cancellation errors
221
+ }
222
+ }
223
+ this.logger.info('Orchestrator stopped');
224
+ this.emit('stopped', this.queue.getStatus());
225
+ }
226
+ getStatus() {
227
+ return {
228
+ isRunning: this.isRunning,
229
+ queue: this.queue.getStatus(),
230
+ activeAgents: Array.from(this.activeAgents.entries()).map(([agentId, taskId]) => ({ agentId, taskId })),
231
+ };
232
+ }
233
+ async sendFollowUp(taskId, message) {
234
+ const task = this.queue.getTask(taskId);
235
+ if (!task?.agentId)
236
+ throw new Error(`No active agent for task ${taskId}`);
237
+ await this.client.sendFollowUp(task.agentId, message);
238
+ }
239
+ }
240
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { EventEmitter } from 'events';
2
+ export interface Task {
3
+ id: string;
4
+ name: string;
5
+ prompt: string;
6
+ dependsOn: string[];
7
+ priority: number;
8
+ branch?: string;
9
+ files?: string[];
10
+ timeout?: number;
11
+ retries?: number;
12
+ validation?: {
13
+ command: string;
14
+ successPattern: string;
15
+ };
16
+ complete?: boolean;
17
+ status: TaskStatus;
18
+ agentId?: string;
19
+ attempts: number;
20
+ error?: string;
21
+ result?: TaskResult;
22
+ }
23
+ export type TaskStatus = 'pending' | 'ready' | 'running' | 'completed' | 'failed';
24
+ export interface TaskResult {
25
+ branch?: string;
26
+ pullRequestUrl?: string;
27
+ completedAt: string;
28
+ }
29
+ export type TaskInput = Omit<Task, 'status' | 'attempts' | 'agentId' | 'error' | 'result'>;
30
+ export declare class TaskQueue extends EventEmitter {
31
+ private tasks;
32
+ private completed;
33
+ addTask(input: TaskInput): void;
34
+ addTasks(inputs: TaskInput[]): void;
35
+ private updateReadyTasks;
36
+ getReadyTasks(): Task[];
37
+ getTask(id: string): Task | undefined;
38
+ getAllTasks(): Task[];
39
+ markRunning(id: string, agentId: string): void;
40
+ markCompleted(id: string, result?: Partial<TaskResult>, checkComplete?: boolean): void;
41
+ markFailed(id: string, error: string, maxRetries?: number): void;
42
+ private checkAllComplete;
43
+ getResults(): {
44
+ completed: Task[];
45
+ failed: Task[];
46
+ };
47
+ getStatus(): Record<string, number>;
48
+ reset(): void;
49
+ }