@stan-chen/simple-cli 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -63
- package/dist/anyllm.py +62 -0
- package/dist/builtins.d.ts +726 -0
- package/dist/builtins.js +481 -0
- package/dist/cli.d.ts +0 -4
- package/dist/cli.js +34 -493
- package/dist/engine.d.ts +33 -0
- package/dist/engine.js +138 -0
- package/dist/learnings.d.ts +15 -0
- package/dist/learnings.js +54 -0
- package/dist/llm.d.ts +18 -0
- package/dist/llm.js +66 -0
- package/dist/mcp.d.ts +132 -0
- package/dist/mcp.js +43 -0
- package/dist/skills.d.ts +5 -16
- package/dist/skills.js +91 -253
- package/dist/tui.d.ts +1 -0
- package/dist/tui.js +10 -0
- package/package.json +10 -6
- package/dist/claw/jit.d.ts +0 -5
- package/dist/claw/jit.js +0 -138
- package/dist/claw/management.d.ts +0 -3
- package/dist/claw/management.js +0 -107
- package/dist/commands/add.d.ts +0 -9
- package/dist/commands/add.js +0 -50
- package/dist/commands/git/commit.d.ts +0 -12
- package/dist/commands/git/commit.js +0 -98
- package/dist/commands/git/status.d.ts +0 -6
- package/dist/commands/git/status.js +0 -42
- package/dist/commands/index.d.ts +0 -16
- package/dist/commands/index.js +0 -377
- package/dist/commands/mcp/status.d.ts +0 -6
- package/dist/commands/mcp/status.js +0 -31
- package/dist/commands/swarm.d.ts +0 -36
- package/dist/commands/swarm.js +0 -236
- package/dist/commands.d.ts +0 -32
- package/dist/commands.js +0 -427
- package/dist/context.d.ts +0 -116
- package/dist/context.js +0 -337
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -109
- package/dist/lib/agent.d.ts +0 -99
- package/dist/lib/agent.js +0 -313
- package/dist/lib/editor.d.ts +0 -74
- package/dist/lib/editor.js +0 -441
- package/dist/lib/git.d.ts +0 -164
- package/dist/lib/git.js +0 -356
- package/dist/lib/shim.d.ts +0 -4
- package/dist/lib/shim.js +0 -30
- package/dist/lib/ui.d.ts +0 -159
- package/dist/lib/ui.js +0 -277
- package/dist/mcp/client.d.ts +0 -22
- package/dist/mcp/client.js +0 -81
- package/dist/mcp/manager.d.ts +0 -186
- package/dist/mcp/manager.js +0 -446
- package/dist/prompts/provider.d.ts +0 -22
- package/dist/prompts/provider.js +0 -79
- package/dist/providers/index.d.ts +0 -31
- package/dist/providers/index.js +0 -93
- package/dist/providers/multi.d.ts +0 -12
- package/dist/providers/multi.js +0 -28
- package/dist/registry.d.ts +0 -29
- package/dist/registry.js +0 -443
- package/dist/repoMap.d.ts +0 -5
- package/dist/repoMap.js +0 -79
- package/dist/router.d.ts +0 -41
- package/dist/router.js +0 -118
- package/dist/swarm/coordinator.d.ts +0 -86
- package/dist/swarm/coordinator.js +0 -257
- package/dist/swarm/index.d.ts +0 -28
- package/dist/swarm/index.js +0 -29
- package/dist/swarm/task.d.ts +0 -104
- package/dist/swarm/task.js +0 -221
- package/dist/swarm/types.d.ts +0 -132
- package/dist/swarm/types.js +0 -37
- package/dist/swarm/worker.d.ts +0 -109
- package/dist/swarm/worker.js +0 -369
- package/dist/tools/analyzeFile.d.ts +0 -16
- package/dist/tools/analyzeFile.js +0 -43
- package/dist/tools/analyze_file.d.ts +0 -16
- package/dist/tools/analyze_file.js +0 -43
- package/dist/tools/clawBrain.d.ts +0 -23
- package/dist/tools/clawBrain.js +0 -136
- package/dist/tools/claw_brain.d.ts +0 -23
- package/dist/tools/claw_brain.js +0 -139
- package/dist/tools/deleteFile.d.ts +0 -19
- package/dist/tools/deleteFile.js +0 -36
- package/dist/tools/delete_file.d.ts +0 -19
- package/dist/tools/delete_file.js +0 -36
- package/dist/tools/fileOps.d.ts +0 -22
- package/dist/tools/fileOps.js +0 -43
- package/dist/tools/file_ops.d.ts +0 -22
- package/dist/tools/file_ops.js +0 -43
- package/dist/tools/git.d.ts +0 -40
- package/dist/tools/git.js +0 -236
- package/dist/tools/glob.d.ts +0 -34
- package/dist/tools/glob.js +0 -165
- package/dist/tools/grep.d.ts +0 -53
- package/dist/tools/grep.js +0 -296
- package/dist/tools/linter.d.ts +0 -35
- package/dist/tools/linter.js +0 -407
- package/dist/tools/listDir.d.ts +0 -29
- package/dist/tools/listDir.js +0 -50
- package/dist/tools/list_dir.d.ts +0 -29
- package/dist/tools/list_dir.js +0 -50
- package/dist/tools/memory.d.ts +0 -34
- package/dist/tools/memory.js +0 -215
- package/dist/tools/organizer.d.ts +0 -1
- package/dist/tools/organizer.js +0 -65
- package/dist/tools/readFiles.d.ts +0 -25
- package/dist/tools/readFiles.js +0 -31
- package/dist/tools/read_files.d.ts +0 -25
- package/dist/tools/read_files.js +0 -31
- package/dist/tools/reloadTools.d.ts +0 -11
- package/dist/tools/reloadTools.js +0 -22
- package/dist/tools/reload_tools.d.ts +0 -11
- package/dist/tools/reload_tools.js +0 -22
- package/dist/tools/runCommand.d.ts +0 -32
- package/dist/tools/runCommand.js +0 -79
- package/dist/tools/run_command.d.ts +0 -32
- package/dist/tools/run_command.js +0 -103
- package/dist/tools/scheduler.d.ts +0 -25
- package/dist/tools/scheduler.js +0 -65
- package/dist/tools/scraper.d.ts +0 -31
- package/dist/tools/scraper.js +0 -211
- package/dist/tools/writeFiles.d.ts +0 -63
- package/dist/tools/writeFiles.js +0 -87
- package/dist/tools/write_files.d.ts +0 -84
- package/dist/tools/write_files.js +0 -91
- package/dist/tools/write_to_file.d.ts +0 -15
- package/dist/tools/write_to_file.js +0 -21
- package/dist/ui/server.d.ts +0 -5
- package/dist/ui/server.js +0 -74
- package/dist/watcher.d.ts +0 -35
- package/dist/watcher.js +0 -164
- /package/{docs/assets → assets}/logo.jpeg +0 -0
package/dist/router.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MoE Router: Mix of Experts task routing
|
|
3
|
-
* Routes tasks to appropriate model tiers based on complexity
|
|
4
|
-
*/
|
|
5
|
-
import { jsonrepair } from 'jsonrepair';
|
|
6
|
-
import { z } from 'zod';
|
|
7
|
-
// Schema for Orchestrator's routing response
|
|
8
|
-
export const RoutingResponseSchema = z.object({
|
|
9
|
-
complexity: z.number().min(1).max(10),
|
|
10
|
-
contextRequired: z.enum(['high', 'low']),
|
|
11
|
-
risk: z.enum(['high', 'low']),
|
|
12
|
-
recommendedTier: z.number().min(1).max(5),
|
|
13
|
-
reasoning: z.string()
|
|
14
|
-
});
|
|
15
|
-
// Default tier configurations
|
|
16
|
-
const DEFAULT_TIERS = {
|
|
17
|
-
1: { role: 'Orchestrator / Architect', defaultModel: 'gpt-5.2-pro' },
|
|
18
|
-
2: { role: 'Senior Engineer', defaultModel: 'gpt-5.2-codex' },
|
|
19
|
-
3: { role: 'Junior Engineer', defaultModel: 'gpt-5-mini' },
|
|
20
|
-
4: { role: 'Intern / Linter', defaultModel: 'gpt-5-nano' },
|
|
21
|
-
5: { role: 'Safety / Utility', defaultModel: 'gemini-2.5-flash' }
|
|
22
|
-
};
|
|
23
|
-
// Load tier configuration from environment
|
|
24
|
-
export const loadTierConfig = () => {
|
|
25
|
-
const tiers = new Map();
|
|
26
|
-
for (const tier of [1, 2, 3, 4, 5]) {
|
|
27
|
-
const envModel = process.env[`MOE_TIER_${tier}_MODEL`];
|
|
28
|
-
const model = envModel || DEFAULT_TIERS[tier].defaultModel;
|
|
29
|
-
// Vercel AI SDK supports provider prefixes (e.g., "anthropic:claude-3", "google:gemini-pro")
|
|
30
|
-
// Some tests/tools use slash separators ("anthropic/claude-3-opus"). Accept either.
|
|
31
|
-
const provider = model.includes(':') || model.includes('/') ? model.split(/[:\/]/)[0] : 'openai';
|
|
32
|
-
tiers.set(tier, {
|
|
33
|
-
tier,
|
|
34
|
-
role: DEFAULT_TIERS[tier].role,
|
|
35
|
-
model,
|
|
36
|
-
provider
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return tiers;
|
|
40
|
-
};
|
|
41
|
-
// Routing prompt template
|
|
42
|
-
const ROUTING_PROMPT = `You are a task router for an AI coding assistant. Analyze the following task and determine its complexity.
|
|
43
|
-
|
|
44
|
-
Respond ONLY with valid JSON in this exact format:
|
|
45
|
-
{
|
|
46
|
-
"complexity": <1-10>,
|
|
47
|
-
"contextRequired": "<high|low>",
|
|
48
|
-
"risk": "<high|low>",
|
|
49
|
-
"recommendedTier": <1-5>,
|
|
50
|
-
"reasoning": "<brief explanation>"
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
Tier Guidelines:
|
|
54
|
-
- Tier 1: Complex architecture, critical decisions, multi-system refactoring
|
|
55
|
-
- Tier 2: Feature implementation, significant code changes, debugging complex issues
|
|
56
|
-
- Tier 3: Routine tasks, unit tests, boilerplate code, simple features
|
|
57
|
-
- Tier 4: Typo fixes, formatting, simple imports, trivial changes
|
|
58
|
-
- Tier 5: Basic text operations, summaries
|
|
59
|
-
|
|
60
|
-
Task to analyze:
|
|
61
|
-
`;
|
|
62
|
-
// Determine routing using Tier 1 orchestrator
|
|
63
|
-
export const routeTask = async (task, orchestratorCall) => {
|
|
64
|
-
try {
|
|
65
|
-
const response = await orchestratorCall(ROUTING_PROMPT + task);
|
|
66
|
-
// Extract JSON from response
|
|
67
|
-
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
68
|
-
if (!jsonMatch) {
|
|
69
|
-
return getDefaultRouting(task);
|
|
70
|
-
}
|
|
71
|
-
try {
|
|
72
|
-
const repaired = jsonrepair(jsonMatch[0]);
|
|
73
|
-
const data = JSON.parse(repaired);
|
|
74
|
-
// Fuzzy mapping for recommendedTier
|
|
75
|
-
const tierValue = data.recommendedTier || data.tier || data.recommended_tier || 3;
|
|
76
|
-
const complexityValue = data.complexity || 5;
|
|
77
|
-
return {
|
|
78
|
-
tier: (Math.max(1, Math.min(5, Number(tierValue)))),
|
|
79
|
-
complexity: Number(complexityValue),
|
|
80
|
-
contextRequired: data.contextRequired === 'high' ? 'high' : 'low',
|
|
81
|
-
risk: data.risk === 'high' ? 'high' : 'low',
|
|
82
|
-
reasoning: data.reasoning || 'No reasoning provided'
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
catch (e) {
|
|
86
|
-
return getDefaultRouting(task);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
console.error('Routing error, using default:', error);
|
|
91
|
-
return getDefaultRouting(task);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
// Fallback routing based on simple heuristics
|
|
95
|
-
const getDefaultRouting = (task) => {
|
|
96
|
-
const taskLower = task.toLowerCase();
|
|
97
|
-
// Simple keyword-based routing
|
|
98
|
-
if (taskLower.match(/refactor|architect|design|migrate|security|auth/)) {
|
|
99
|
-
return { tier: 2, complexity: 7, contextRequired: 'high', risk: 'high', reasoning: 'Complex task keywords detected' };
|
|
100
|
-
}
|
|
101
|
-
if (taskLower.match(/implement|feature|add|create|build|debug/)) {
|
|
102
|
-
return { tier: 2, complexity: 6, contextRequired: 'high', risk: 'low', reasoning: 'Implementation task detected' };
|
|
103
|
-
}
|
|
104
|
-
if (taskLower.match(/test|boilerplate|template|simple/)) {
|
|
105
|
-
return { tier: 3, complexity: 4, contextRequired: 'low', risk: 'low', reasoning: 'Routine task detected' };
|
|
106
|
-
}
|
|
107
|
-
if (taskLower.match(/typo|fix|format|import|rename/)) {
|
|
108
|
-
return { tier: 4, complexity: 2, contextRequired: 'low', risk: 'low', reasoning: 'Minor task detected' };
|
|
109
|
-
}
|
|
110
|
-
// Default to Tier 3
|
|
111
|
-
return { tier: 3, complexity: 5, contextRequired: 'low', risk: 'low', reasoning: 'Default routing' };
|
|
112
|
-
};
|
|
113
|
-
// Format routing decision for logging
|
|
114
|
-
export const formatRoutingDecision = (decision, tiers) => {
|
|
115
|
-
const tierConfig = tiers.get(decision.tier);
|
|
116
|
-
return `[Router] Tier ${decision.tier} (${tierConfig?.role}) | Complexity: ${decision.complexity}/10 | Model: ${tierConfig?.model}
|
|
117
|
-
Reasoning: ${decision.reasoning}`;
|
|
118
|
-
};
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Swarm Coordinator - Orchestrates multiple workers executing tasks
|
|
3
|
-
*/
|
|
4
|
-
import { EventEmitter } from 'events';
|
|
5
|
-
import type { SwarmTask, CoordinatorOptions, SwarmResult, SwarmEventMap } from './types.js';
|
|
6
|
-
export declare class SwarmCoordinator extends EventEmitter {
|
|
7
|
-
private options;
|
|
8
|
-
private taskQueue;
|
|
9
|
-
private workerPool;
|
|
10
|
-
private retryPolicy;
|
|
11
|
-
private running;
|
|
12
|
-
private startTime;
|
|
13
|
-
private aborted;
|
|
14
|
-
constructor(options?: CoordinatorOptions);
|
|
15
|
-
/**
|
|
16
|
-
* Add a single task
|
|
17
|
-
*/
|
|
18
|
-
addTask(task: SwarmTask): void;
|
|
19
|
-
/**
|
|
20
|
-
* Add multiple tasks
|
|
21
|
-
*/
|
|
22
|
-
addTasks(tasks: SwarmTask[]): void;
|
|
23
|
-
/**
|
|
24
|
-
* Get next task from queue
|
|
25
|
-
*/
|
|
26
|
-
getTask(): SwarmTask | null;
|
|
27
|
-
/**
|
|
28
|
-
* Peek at next task
|
|
29
|
-
*/
|
|
30
|
-
peekTask(): SwarmTask | null;
|
|
31
|
-
/**
|
|
32
|
-
* Get all workers status
|
|
33
|
-
*/
|
|
34
|
-
getAllWorkers(): import("./types.js").WorkerStatus[];
|
|
35
|
-
/**
|
|
36
|
-
* Get worker status by ID
|
|
37
|
-
*/
|
|
38
|
-
getWorkerStatus(id: string): import("./types.js").WorkerStatus | undefined;
|
|
39
|
-
/**
|
|
40
|
-
* Stop the swarm gracefully
|
|
41
|
-
*/
|
|
42
|
-
stop(): void;
|
|
43
|
-
/**
|
|
44
|
-
* Abort immediately
|
|
45
|
-
*/
|
|
46
|
-
abort(): void;
|
|
47
|
-
/**
|
|
48
|
-
* Run the swarm
|
|
49
|
-
*/
|
|
50
|
-
run(concurrency?: number): Promise<SwarmResult>;
|
|
51
|
-
/**
|
|
52
|
-
* Main processing loop
|
|
53
|
-
*/
|
|
54
|
-
private processLoop;
|
|
55
|
-
/**
|
|
56
|
-
* Execute a single task on a worker
|
|
57
|
-
*/
|
|
58
|
-
private executeTask;
|
|
59
|
-
/**
|
|
60
|
-
* Sleep helper
|
|
61
|
-
*/
|
|
62
|
-
private sleep;
|
|
63
|
-
/**
|
|
64
|
-
* Get queue statistics
|
|
65
|
-
*/
|
|
66
|
-
getStats(): {
|
|
67
|
-
total: number;
|
|
68
|
-
pending: number;
|
|
69
|
-
running: number;
|
|
70
|
-
completed: number;
|
|
71
|
-
failed: number;
|
|
72
|
-
};
|
|
73
|
-
/**
|
|
74
|
-
* Check if swarm is running
|
|
75
|
-
*/
|
|
76
|
-
isRunning(): boolean;
|
|
77
|
-
/**
|
|
78
|
-
* Type-safe event emitter methods
|
|
79
|
-
*/
|
|
80
|
-
on<K extends keyof SwarmEventMap>(event: K, listener: SwarmEventMap[K]): this;
|
|
81
|
-
emit<K extends keyof SwarmEventMap>(event: K, ...args: Parameters<SwarmEventMap[K]>): boolean;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Create a swarm coordinator
|
|
85
|
-
*/
|
|
86
|
-
export declare function createSwarmCoordinator(options?: CoordinatorOptions): SwarmCoordinator;
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Swarm Coordinator - Orchestrates multiple workers executing tasks
|
|
3
|
-
*/
|
|
4
|
-
import { EventEmitter } from 'events';
|
|
5
|
-
import { DEFAULT_COORDINATOR_OPTIONS, DEFAULT_RETRY_POLICY } from './types.js';
|
|
6
|
-
import { TaskQueue } from './task.js';
|
|
7
|
-
import { WorkerPool } from './worker.js';
|
|
8
|
-
export class SwarmCoordinator extends EventEmitter {
|
|
9
|
-
options;
|
|
10
|
-
taskQueue;
|
|
11
|
-
workerPool;
|
|
12
|
-
retryPolicy;
|
|
13
|
-
running = false;
|
|
14
|
-
startTime = 0;
|
|
15
|
-
aborted = false;
|
|
16
|
-
constructor(options = {}) {
|
|
17
|
-
super();
|
|
18
|
-
this.options = {
|
|
19
|
-
...DEFAULT_COORDINATOR_OPTIONS,
|
|
20
|
-
...options,
|
|
21
|
-
retryPolicy: {
|
|
22
|
-
...DEFAULT_RETRY_POLICY,
|
|
23
|
-
...options.retryPolicy,
|
|
24
|
-
},
|
|
25
|
-
};
|
|
26
|
-
this.retryPolicy = this.options.retryPolicy;
|
|
27
|
-
this.taskQueue = new TaskQueue();
|
|
28
|
-
this.workerPool = new WorkerPool(this.options.concurrency, {
|
|
29
|
-
cwd: this.options.cwd,
|
|
30
|
-
yolo: this.options.yolo,
|
|
31
|
-
timeout: this.options.timeout,
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Add a single task
|
|
36
|
-
*/
|
|
37
|
-
addTask(task) {
|
|
38
|
-
this.taskQueue.addTask(task);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Add multiple tasks
|
|
42
|
-
*/
|
|
43
|
-
addTasks(tasks) {
|
|
44
|
-
this.taskQueue.addTasks(tasks);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Get next task from queue
|
|
48
|
-
*/
|
|
49
|
-
getTask() {
|
|
50
|
-
return this.taskQueue.getNextTask();
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Peek at next task
|
|
54
|
-
*/
|
|
55
|
-
peekTask() {
|
|
56
|
-
return this.taskQueue.peekNextTask();
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Get all workers status
|
|
60
|
-
*/
|
|
61
|
-
getAllWorkers() {
|
|
62
|
-
return this.workerPool.getAllWorkers().map(w => w.getStatus());
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Get worker status by ID
|
|
66
|
-
*/
|
|
67
|
-
getWorkerStatus(id) {
|
|
68
|
-
return this.workerPool.getWorkerById(id)?.getStatus();
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Stop the swarm gracefully
|
|
72
|
-
*/
|
|
73
|
-
stop() {
|
|
74
|
-
this.running = false;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Abort immediately
|
|
78
|
-
*/
|
|
79
|
-
abort() {
|
|
80
|
-
this.aborted = true;
|
|
81
|
-
this.running = false;
|
|
82
|
-
this.workerPool.killAll();
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Run the swarm
|
|
86
|
-
*/
|
|
87
|
-
async run(concurrency) {
|
|
88
|
-
if (concurrency !== undefined) {
|
|
89
|
-
this.options.concurrency = concurrency;
|
|
90
|
-
this.workerPool = new WorkerPool(concurrency, {
|
|
91
|
-
cwd: this.options.cwd,
|
|
92
|
-
yolo: this.options.yolo,
|
|
93
|
-
timeout: this.options.timeout,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
this.running = true;
|
|
97
|
-
this.aborted = false;
|
|
98
|
-
this.startTime = Date.now();
|
|
99
|
-
// Skip tasks blocked by failed dependencies
|
|
100
|
-
const skipped = this.taskQueue.skipBlockedTasks();
|
|
101
|
-
for (const taskId of skipped) {
|
|
102
|
-
const task = this.taskQueue.getTask(taskId);
|
|
103
|
-
if (task) {
|
|
104
|
-
this.emit('task:fail', task, new Error('Blocked by failed dependency'));
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Process tasks
|
|
108
|
-
await this.processLoop();
|
|
109
|
-
// Mark as no longer running
|
|
110
|
-
this.running = false;
|
|
111
|
-
// Build result
|
|
112
|
-
const stats = this.taskQueue.getStats();
|
|
113
|
-
const results = this.taskQueue.getResults();
|
|
114
|
-
const failures = this.taskQueue.getFailures();
|
|
115
|
-
const duration = Date.now() - this.startTime;
|
|
116
|
-
const result = {
|
|
117
|
-
total: stats.total,
|
|
118
|
-
completed: stats.completed,
|
|
119
|
-
failed: stats.failed,
|
|
120
|
-
skipped: skipped.length,
|
|
121
|
-
duration,
|
|
122
|
-
successRate: stats.total > 0 ? stats.completed / stats.total : 0,
|
|
123
|
-
results,
|
|
124
|
-
failedTasks: failures,
|
|
125
|
-
};
|
|
126
|
-
this.emit('swarm:complete', result);
|
|
127
|
-
return result;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Main processing loop
|
|
131
|
-
*/
|
|
132
|
-
async processLoop() {
|
|
133
|
-
const activePromises = new Map();
|
|
134
|
-
while (this.running && !this.aborted) {
|
|
135
|
-
// Check if done
|
|
136
|
-
if (this.taskQueue.isDone() && activePromises.size === 0) {
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
// Skip blocked tasks
|
|
140
|
-
const skipped = this.taskQueue.skipBlockedTasks();
|
|
141
|
-
for (const taskId of skipped) {
|
|
142
|
-
const task = this.taskQueue.getTask(taskId);
|
|
143
|
-
if (task) {
|
|
144
|
-
this.emit('task:fail', task, new Error('Blocked by failed dependency'));
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// Try to start new tasks
|
|
148
|
-
while (this.workerPool.getAvailableCount() > 0) {
|
|
149
|
-
const task = this.taskQueue.getNextTask();
|
|
150
|
-
if (!task)
|
|
151
|
-
break;
|
|
152
|
-
const worker = this.workerPool.getWorker();
|
|
153
|
-
if (!worker) {
|
|
154
|
-
// No worker available, put task back
|
|
155
|
-
this.taskQueue.addTask(task);
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
// Start task execution
|
|
159
|
-
const promise = this.executeTask(worker, task);
|
|
160
|
-
activePromises.set(task.id, promise);
|
|
161
|
-
promise.finally(() => {
|
|
162
|
-
activePromises.delete(task.id);
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
// Wait a bit before checking again
|
|
166
|
-
if (activePromises.size > 0) {
|
|
167
|
-
await Promise.race([
|
|
168
|
-
...activePromises.values(),
|
|
169
|
-
this.sleep(100),
|
|
170
|
-
]);
|
|
171
|
-
}
|
|
172
|
-
else if (this.taskQueue.hasWork()) {
|
|
173
|
-
// Have work but no available workers, wait
|
|
174
|
-
await this.sleep(100);
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
// Wait for remaining tasks to complete
|
|
181
|
-
if (activePromises.size > 0) {
|
|
182
|
-
await Promise.all(activePromises.values());
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Execute a single task on a worker
|
|
187
|
-
*/
|
|
188
|
-
async executeTask(worker, task) {
|
|
189
|
-
const attempt = this.taskQueue.getAttempts(task.id) + 1;
|
|
190
|
-
this.emit('task:start', task, worker.id);
|
|
191
|
-
if (attempt > 1) {
|
|
192
|
-
this.emit('task:retry', task, attempt);
|
|
193
|
-
}
|
|
194
|
-
try {
|
|
195
|
-
const result = await worker.execute(task);
|
|
196
|
-
if (result.success) {
|
|
197
|
-
const taskResult = {
|
|
198
|
-
task,
|
|
199
|
-
workerId: worker.id,
|
|
200
|
-
result,
|
|
201
|
-
};
|
|
202
|
-
this.taskQueue.completeTask(task.id, taskResult);
|
|
203
|
-
this.emit('task:complete', task, result);
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
const willRetry = this.taskQueue.failTask(task.id, result.error || 'Unknown error', this.retryPolicy.maxRetries);
|
|
207
|
-
if (!willRetry) {
|
|
208
|
-
this.emit('task:fail', task, new Error(result.error || 'Max retries exceeded'));
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
catch (error) {
|
|
213
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
214
|
-
const willRetry = this.taskQueue.failTask(task.id, errorMsg, this.retryPolicy.maxRetries);
|
|
215
|
-
if (!willRetry) {
|
|
216
|
-
this.emit('task:fail', task, error instanceof Error ? error : new Error(errorMsg));
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
finally {
|
|
220
|
-
// Release worker back to pool
|
|
221
|
-
this.workerPool.releaseWorker(worker);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Sleep helper
|
|
226
|
-
*/
|
|
227
|
-
sleep(ms) {
|
|
228
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Get queue statistics
|
|
232
|
-
*/
|
|
233
|
-
getStats() {
|
|
234
|
-
return this.taskQueue.getStats();
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Check if swarm is running
|
|
238
|
-
*/
|
|
239
|
-
isRunning() {
|
|
240
|
-
return this.running;
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Type-safe event emitter methods
|
|
244
|
-
*/
|
|
245
|
-
on(event, listener) {
|
|
246
|
-
return super.on(event, listener);
|
|
247
|
-
}
|
|
248
|
-
emit(event, ...args) {
|
|
249
|
-
return super.emit(event, ...args);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Create a swarm coordinator
|
|
254
|
-
*/
|
|
255
|
-
export function createSwarmCoordinator(options) {
|
|
256
|
-
return new SwarmCoordinator(options);
|
|
257
|
-
}
|
package/dist/swarm/index.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Swarm Module - Coordinate multiple Simple-CLI agents
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* ```typescript
|
|
6
|
-
* import { SwarmCoordinator } from 'simplecli/swarm';
|
|
7
|
-
*
|
|
8
|
-
* const coordinator = new SwarmCoordinator({
|
|
9
|
-
* cwd: '/path/to/repo',
|
|
10
|
-
* concurrency: 4,
|
|
11
|
-
* yolo: true,
|
|
12
|
-
* });
|
|
13
|
-
*
|
|
14
|
-
* coordinator.addTasks([
|
|
15
|
-
* { id: 'task1', type: 'implement', description: '...', scope: {}, priority: 1, timeout: 300000, retries: 2 },
|
|
16
|
-
* { id: 'task2', type: 'test', description: '...', scope: {}, priority: 2, timeout: 180000, retries: 1 },
|
|
17
|
-
* ]);
|
|
18
|
-
*
|
|
19
|
-
* const result = await coordinator.run();
|
|
20
|
-
* console.log(`Completed: ${result.completed}/${result.total}`);
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export type { SwarmTask, TaskScope, TaskType, Priority, WorkerStatus, WorkerState, WorkerResult, TaskResult, FailedTask, SwarmResult, CoordinatorOptions, RetryPolicy, SwarmEventMap, } from './types.js';
|
|
24
|
-
export { swarmTaskSchema, taskScopeSchema, DEFAULT_RETRY_POLICY, DEFAULT_COORDINATOR_OPTIONS, } from './types.js';
|
|
25
|
-
export { TaskQueue } from './task.js';
|
|
26
|
-
export { Worker, WorkerPool } from './worker.js';
|
|
27
|
-
export type { WorkerOptions } from './worker.js';
|
|
28
|
-
export { SwarmCoordinator, createSwarmCoordinator } from './coordinator.js';
|
package/dist/swarm/index.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Swarm Module - Coordinate multiple Simple-CLI agents
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* ```typescript
|
|
6
|
-
* import { SwarmCoordinator } from 'simplecli/swarm';
|
|
7
|
-
*
|
|
8
|
-
* const coordinator = new SwarmCoordinator({
|
|
9
|
-
* cwd: '/path/to/repo',
|
|
10
|
-
* concurrency: 4,
|
|
11
|
-
* yolo: true,
|
|
12
|
-
* });
|
|
13
|
-
*
|
|
14
|
-
* coordinator.addTasks([
|
|
15
|
-
* { id: 'task1', type: 'implement', description: '...', scope: {}, priority: 1, timeout: 300000, retries: 2 },
|
|
16
|
-
* { id: 'task2', type: 'test', description: '...', scope: {}, priority: 2, timeout: 180000, retries: 1 },
|
|
17
|
-
* ]);
|
|
18
|
-
*
|
|
19
|
-
* const result = await coordinator.run();
|
|
20
|
-
* console.log(`Completed: ${result.completed}/${result.total}`);
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export { swarmTaskSchema, taskScopeSchema, DEFAULT_RETRY_POLICY, DEFAULT_COORDINATOR_OPTIONS, } from './types.js';
|
|
24
|
-
// Task Queue
|
|
25
|
-
export { TaskQueue } from './task.js';
|
|
26
|
-
// Worker
|
|
27
|
-
export { Worker, WorkerPool } from './worker.js';
|
|
28
|
-
// Coordinator
|
|
29
|
-
export { SwarmCoordinator, createSwarmCoordinator } from './coordinator.js';
|
package/dist/swarm/task.d.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Task Queue - Priority-based task queue with dependency tracking
|
|
3
|
-
*/
|
|
4
|
-
import type { SwarmTask, TaskResult, FailedTask } from './types.js';
|
|
5
|
-
export declare class TaskQueue {
|
|
6
|
-
private tasks;
|
|
7
|
-
private pending;
|
|
8
|
-
private running;
|
|
9
|
-
private completed;
|
|
10
|
-
private failed;
|
|
11
|
-
private results;
|
|
12
|
-
private failures;
|
|
13
|
-
private attempts;
|
|
14
|
-
/**
|
|
15
|
-
* Add a task to the queue
|
|
16
|
-
*/
|
|
17
|
-
addTask(task: SwarmTask): void;
|
|
18
|
-
/**
|
|
19
|
-
* Add multiple tasks
|
|
20
|
-
*/
|
|
21
|
-
addTasks(tasks: SwarmTask[]): void;
|
|
22
|
-
/**
|
|
23
|
-
* Get next available task (respects dependencies and priorities)
|
|
24
|
-
*/
|
|
25
|
-
getNextTask(): SwarmTask | null;
|
|
26
|
-
/**
|
|
27
|
-
* Get all tasks that are ready to run
|
|
28
|
-
*/
|
|
29
|
-
getAvailableTasks(): SwarmTask[];
|
|
30
|
-
/**
|
|
31
|
-
* Check if a task's dependencies are all completed
|
|
32
|
-
*/
|
|
33
|
-
areDependenciesMet(task: SwarmTask): boolean;
|
|
34
|
-
/**
|
|
35
|
-
* Mark a task as completed
|
|
36
|
-
*/
|
|
37
|
-
completeTask(taskId: string, result: TaskResult): void;
|
|
38
|
-
/**
|
|
39
|
-
* Mark a task as failed (may retry)
|
|
40
|
-
*/
|
|
41
|
-
failTask(taskId: string, error: string, maxRetries: number): boolean;
|
|
42
|
-
/**
|
|
43
|
-
* Get number of attempts for a task
|
|
44
|
-
*/
|
|
45
|
-
getAttempts(taskId: string): number;
|
|
46
|
-
/**
|
|
47
|
-
* Peek at next task without removing it
|
|
48
|
-
*/
|
|
49
|
-
peekNextTask(): SwarmTask | null;
|
|
50
|
-
/**
|
|
51
|
-
* Check if all tasks are done (completed or failed)
|
|
52
|
-
*/
|
|
53
|
-
isDone(): boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Check if there's any work to do
|
|
56
|
-
*/
|
|
57
|
-
hasWork(): boolean;
|
|
58
|
-
/**
|
|
59
|
-
* Check if any tasks are currently running
|
|
60
|
-
*/
|
|
61
|
-
hasRunning(): boolean;
|
|
62
|
-
/**
|
|
63
|
-
* Get queue statistics
|
|
64
|
-
*/
|
|
65
|
-
getStats(): {
|
|
66
|
-
total: number;
|
|
67
|
-
pending: number;
|
|
68
|
-
running: number;
|
|
69
|
-
completed: number;
|
|
70
|
-
failed: number;
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Get all results
|
|
74
|
-
*/
|
|
75
|
-
getResults(): TaskResult[];
|
|
76
|
-
/**
|
|
77
|
-
* Get all failures
|
|
78
|
-
*/
|
|
79
|
-
getFailures(): FailedTask[];
|
|
80
|
-
/**
|
|
81
|
-
* Get a specific task
|
|
82
|
-
*/
|
|
83
|
-
getTask(taskId: string): SwarmTask | undefined;
|
|
84
|
-
/**
|
|
85
|
-
* Get all tasks
|
|
86
|
-
*/
|
|
87
|
-
getAllTasks(): SwarmTask[];
|
|
88
|
-
/**
|
|
89
|
-
* Clear the queue
|
|
90
|
-
*/
|
|
91
|
-
clear(): void;
|
|
92
|
-
/**
|
|
93
|
-
* Cancel a pending task
|
|
94
|
-
*/
|
|
95
|
-
cancelTask(taskId: string): boolean;
|
|
96
|
-
/**
|
|
97
|
-
* Check if a task is blocked by failed dependencies
|
|
98
|
-
*/
|
|
99
|
-
isBlocked(taskId: string): boolean;
|
|
100
|
-
/**
|
|
101
|
-
* Skip tasks that are blocked by failed dependencies
|
|
102
|
-
*/
|
|
103
|
-
skipBlockedTasks(): string[];
|
|
104
|
-
}
|