opencastle 0.1.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 +21 -0
- package/README.md +215 -0
- package/bin/cli.mjs +69 -0
- package/dist/cli/adapters/claude-code.d.ts +22 -0
- package/dist/cli/adapters/claude-code.d.ts.map +1 -0
- package/dist/cli/adapters/claude-code.js +237 -0
- package/dist/cli/adapters/claude-code.js.map +1 -0
- package/dist/cli/adapters/cursor.d.ts +20 -0
- package/dist/cli/adapters/cursor.d.ts.map +1 -0
- package/dist/cli/adapters/cursor.js +231 -0
- package/dist/cli/adapters/cursor.js.map +1 -0
- package/dist/cli/adapters/vscode.d.ts +20 -0
- package/dist/cli/adapters/vscode.d.ts.map +1 -0
- package/dist/cli/adapters/vscode.js +132 -0
- package/dist/cli/adapters/vscode.js.map +1 -0
- package/dist/cli/copy.d.ts +14 -0
- package/dist/cli/copy.d.ts.map +1 -0
- package/dist/cli/copy.js +62 -0
- package/dist/cli/copy.js.map +1 -0
- package/dist/cli/dashboard.d.ts +3 -0
- package/dist/cli/dashboard.d.ts.map +1 -0
- package/dist/cli/dashboard.js +183 -0
- package/dist/cli/dashboard.js.map +1 -0
- package/dist/cli/diff.d.ts +3 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +27 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/eject.d.ts +3 -0
- package/dist/cli/eject.d.ts.map +1 -0
- package/dist/cli/eject.js +27 -0
- package/dist/cli/eject.js.map +1 -0
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +92 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/manifest.d.ts +14 -0
- package/dist/cli/manifest.d.ts.map +1 -0
- package/dist/cli/manifest.js +34 -0
- package/dist/cli/manifest.js.map +1 -0
- package/dist/cli/mcp.d.ts +14 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +35 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/prompt.d.ts +12 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +104 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/run/adapters/claude-code.d.ts +16 -0
- package/dist/cli/run/adapters/claude-code.d.ts.map +1 -0
- package/dist/cli/run/adapters/claude-code.js +82 -0
- package/dist/cli/run/adapters/claude-code.js.map +1 -0
- package/dist/cli/run/adapters/copilot.d.ts +16 -0
- package/dist/cli/run/adapters/copilot.d.ts.map +1 -0
- package/dist/cli/run/adapters/copilot.js +84 -0
- package/dist/cli/run/adapters/copilot.js.map +1 -0
- package/dist/cli/run/adapters/cursor.d.ts +16 -0
- package/dist/cli/run/adapters/cursor.d.ts.map +1 -0
- package/dist/cli/run/adapters/cursor.js +81 -0
- package/dist/cli/run/adapters/cursor.js.map +1 -0
- package/dist/cli/run/adapters/index.d.ts +14 -0
- package/dist/cli/run/adapters/index.d.ts.map +1 -0
- package/dist/cli/run/adapters/index.js +35 -0
- package/dist/cli/run/adapters/index.js.map +1 -0
- package/dist/cli/run/executor.d.ts +15 -0
- package/dist/cli/run/executor.d.ts.map +1 -0
- package/dist/cli/run/executor.js +249 -0
- package/dist/cli/run/executor.js.map +1 -0
- package/dist/cli/run/reporter.d.ts +10 -0
- package/dist/cli/run/reporter.d.ts.map +1 -0
- package/dist/cli/run/reporter.js +112 -0
- package/dist/cli/run/reporter.js.map +1 -0
- package/dist/cli/run/schema.d.ts +28 -0
- package/dist/cli/run/schema.d.ts.map +1 -0
- package/dist/cli/run/schema.js +511 -0
- package/dist/cli/run/schema.js.map +1 -0
- package/dist/cli/run.d.ts +6 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +123 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/stack-config.d.ts +12 -0
- package/dist/cli/stack-config.d.ts.map +1 -0
- package/dist/cli/stack-config.js +146 -0
- package/dist/cli/stack-config.js.map +1 -0
- package/dist/cli/types.d.ts +169 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/update.d.ts +3 -0
- package/dist/cli/update.d.ts.map +1 -0
- package/dist/cli/update.js +50 -0
- package/dist/cli/update.js.map +1 -0
- package/package.json +48 -0
- package/src/cli/adapters/claude-code.ts +287 -0
- package/src/cli/adapters/cursor.ts +377 -0
- package/src/cli/adapters/vscode.ts +168 -0
- package/src/cli/copy.ts +79 -0
- package/src/cli/dashboard.ts +225 -0
- package/src/cli/diff.ts +44 -0
- package/src/cli/eject.ts +39 -0
- package/src/cli/init.ts +120 -0
- package/src/cli/manifest.ts +45 -0
- package/src/cli/mcp.ts +49 -0
- package/src/cli/prompt.ts +115 -0
- package/src/cli/run/adapters/claude-code.ts +95 -0
- package/src/cli/run/adapters/copilot.ts +97 -0
- package/src/cli/run/adapters/cursor.ts +94 -0
- package/src/cli/run/adapters/index.ts +40 -0
- package/src/cli/run/executor.ts +292 -0
- package/src/cli/run/reporter.ts +129 -0
- package/src/cli/run/schema.ts +595 -0
- package/src/cli/run.ts +137 -0
- package/src/cli/stack-config.ts +180 -0
- package/src/cli/types.ts +207 -0
- package/src/cli/update.ts +75 -0
- package/src/dashboard/astro.config.mjs +6 -0
- package/src/dashboard/package-lock.json +5455 -0
- package/src/dashboard/package.json +14 -0
- package/src/dashboard/public/data/delegations.ndjson +35 -0
- package/src/dashboard/public/data/panels.ndjson +13 -0
- package/src/dashboard/public/data/sessions.ndjson +50 -0
- package/src/dashboard/public/icon-192.png +0 -0
- package/src/dashboard/scripts/generate-seed-data.ts +355 -0
- package/src/dashboard/src/layouts/Layout.astro +25 -0
- package/src/dashboard/src/pages/index.astro +1070 -0
- package/src/dashboard/src/styles/dashboard.css +1078 -0
- package/src/dashboard/tsconfig.json +6 -0
- package/src/orchestrator/agent-workflows/README.md +22 -0
- package/src/orchestrator/agent-workflows/bug-fix.md +128 -0
- package/src/orchestrator/agent-workflows/data-pipeline.md +145 -0
- package/src/orchestrator/agent-workflows/database-migration.md +159 -0
- package/src/orchestrator/agent-workflows/feature-implementation.md +223 -0
- package/src/orchestrator/agent-workflows/performance-optimization.md +125 -0
- package/src/orchestrator/agent-workflows/refactoring.md +142 -0
- package/src/orchestrator/agent-workflows/schema-changes.md +164 -0
- package/src/orchestrator/agent-workflows/security-audit.md +148 -0
- package/src/orchestrator/agent-workflows/shared-delivery-phase.md +33 -0
- package/src/orchestrator/agents/api-designer.agent.md +68 -0
- package/src/orchestrator/agents/architect.agent.md +129 -0
- package/src/orchestrator/agents/content-engineer.agent.md +57 -0
- package/src/orchestrator/agents/copywriter.agent.md +95 -0
- package/src/orchestrator/agents/data-expert.agent.md +63 -0
- package/src/orchestrator/agents/database-engineer.agent.md +62 -0
- package/src/orchestrator/agents/developer.agent.md +66 -0
- package/src/orchestrator/agents/devops-expert.agent.md +57 -0
- package/src/orchestrator/agents/documentation-writer.agent.md +60 -0
- package/src/orchestrator/agents/performance-expert.agent.md +58 -0
- package/src/orchestrator/agents/release-manager.agent.md +72 -0
- package/src/orchestrator/agents/researcher.agent.md +145 -0
- package/src/orchestrator/agents/reviewer.agent.md +62 -0
- package/src/orchestrator/agents/security-expert.agent.md +64 -0
- package/src/orchestrator/agents/seo-specialist.agent.md +67 -0
- package/src/orchestrator/agents/team-lead.agent.md +644 -0
- package/src/orchestrator/agents/testing-expert.agent.md +85 -0
- package/src/orchestrator/agents/ui-ux-expert.agent.md +63 -0
- package/src/orchestrator/copilot-instructions.md +3 -0
- package/src/orchestrator/customizations/AGENT-EXPERTISE.md +325 -0
- package/src/orchestrator/customizations/AGENT-FAILURES.md +69 -0
- package/src/orchestrator/customizations/AGENT-PERFORMANCE.md +58 -0
- package/src/orchestrator/customizations/DISPUTES.md +162 -0
- package/src/orchestrator/customizations/KNOWLEDGE-GRAPH.md +10 -0
- package/src/orchestrator/customizations/LESSONS-LEARNED.md +70 -0
- package/src/orchestrator/customizations/README.md +59 -0
- package/src/orchestrator/customizations/agents/agent-registry.md +46 -0
- package/src/orchestrator/customizations/agents/skill-matrix.md +142 -0
- package/src/orchestrator/customizations/logs/README.md +181 -0
- package/src/orchestrator/customizations/logs/delegations.ndjson +1 -0
- package/src/orchestrator/customizations/logs/panels.ndjson +1 -0
- package/src/orchestrator/customizations/logs/sessions.ndjson +1 -0
- package/src/orchestrator/customizations/project/docs-structure.md +23 -0
- package/src/orchestrator/customizations/project/tracker-config.md +45 -0
- package/src/orchestrator/customizations/project.instructions.md +64 -0
- package/src/orchestrator/customizations/stack/api-config.md +37 -0
- package/src/orchestrator/customizations/stack/cms-config.md +26 -0
- package/src/orchestrator/customizations/stack/data-pipeline-config.md +41 -0
- package/src/orchestrator/customizations/stack/database-config.md +44 -0
- package/src/orchestrator/customizations/stack/deployment-config.md +45 -0
- package/src/orchestrator/customizations/stack/testing-config.md +56 -0
- package/src/orchestrator/instructions/ai-optimization.instructions.md +143 -0
- package/src/orchestrator/instructions/general.instructions.md +194 -0
- package/src/orchestrator/mcp.json +55 -0
- package/src/orchestrator/prompts/bootstrap-customizations.prompt.md +235 -0
- package/src/orchestrator/prompts/brainstorm.prompt.md +115 -0
- package/src/orchestrator/prompts/bug-fix.prompt.md +141 -0
- package/src/orchestrator/prompts/create-skill.prompt.md +103 -0
- package/src/orchestrator/prompts/generate-task-spec.prompt.md +154 -0
- package/src/orchestrator/prompts/implement-feature.prompt.md +124 -0
- package/src/orchestrator/prompts/metrics-report.prompt.md +142 -0
- package/src/orchestrator/prompts/quick-refinement.prompt.md +137 -0
- package/src/orchestrator/prompts/resolve-pr-comments.prompt.md +100 -0
- package/src/orchestrator/skills/accessibility-standards/SKILL.md +164 -0
- package/src/orchestrator/skills/agent-hooks/SKILL.md +147 -0
- package/src/orchestrator/skills/agent-memory/SKILL.md +144 -0
- package/src/orchestrator/skills/api-patterns/SKILL.md +106 -0
- package/src/orchestrator/skills/browser-testing/SKILL.md +203 -0
- package/src/orchestrator/skills/code-commenting/SKILL.md +133 -0
- package/src/orchestrator/skills/contentful-cms/SKILL.md +43 -0
- package/src/orchestrator/skills/context-map/SKILL.md +135 -0
- package/src/orchestrator/skills/convex-database/SKILL.md +80 -0
- package/src/orchestrator/skills/data-engineering/SKILL.md +99 -0
- package/src/orchestrator/skills/deployment-infrastructure/SKILL.md +49 -0
- package/src/orchestrator/skills/documentation-standards/SKILL.md +85 -0
- package/src/orchestrator/skills/fast-review/SKILL.md +327 -0
- package/src/orchestrator/skills/frontend-design/SKILL.md +42 -0
- package/src/orchestrator/skills/jira-management/SKILL.md +168 -0
- package/src/orchestrator/skills/memory-merger/SKILL.md +123 -0
- package/src/orchestrator/skills/nextjs-patterns/SKILL.md +75 -0
- package/src/orchestrator/skills/nx-workspace/SKILL.md +192 -0
- package/src/orchestrator/skills/panel-majority-vote/SKILL.md +184 -0
- package/src/orchestrator/skills/panel-majority-vote/panel-report.template.md +38 -0
- package/src/orchestrator/skills/performance-optimization/SKILL.md +101 -0
- package/src/orchestrator/skills/react-development/SKILL.md +117 -0
- package/src/orchestrator/skills/sanity-cms/SKILL.md +18 -0
- package/src/orchestrator/skills/security-hardening/SKILL.md +118 -0
- package/src/orchestrator/skills/self-improvement/SKILL.md +137 -0
- package/src/orchestrator/skills/seo-patterns/SKILL.md +40 -0
- package/src/orchestrator/skills/session-checkpoints/SKILL.md +205 -0
- package/src/orchestrator/skills/slack-notifications/SKILL.md +211 -0
- package/src/orchestrator/skills/strapi-cms/SKILL.md +43 -0
- package/src/orchestrator/skills/supabase-database/SKILL.md +24 -0
- package/src/orchestrator/skills/task-management/SKILL.md +143 -0
- package/src/orchestrator/skills/team-lead-reference/SKILL.md +317 -0
- package/src/orchestrator/skills/teams-notifications/SKILL.md +249 -0
- package/src/orchestrator/skills/testing-workflow/SKILL.md +134 -0
- package/src/orchestrator/skills/validation-gates/SKILL.md +100 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Task, ExecuteOptions, ExecuteResult } from '../../types.js';
|
|
2
|
+
/** Adapter name */
|
|
3
|
+
export declare const name = "claude-code";
|
|
4
|
+
/**
|
|
5
|
+
* Check if the `claude` CLI is available on the system PATH.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isAvailable(): Promise<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Execute a task by invoking the Claude Code CLI in print mode.
|
|
10
|
+
*/
|
|
11
|
+
export declare function execute(task: Task, options?: ExecuteOptions): Promise<ExecuteResult>;
|
|
12
|
+
/**
|
|
13
|
+
* Kill the process associated with a task (used by timeout enforcement).
|
|
14
|
+
*/
|
|
15
|
+
export declare function kill(task: Task): void;
|
|
16
|
+
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../../../src/cli/run/adapters/claude-code.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEzE,mBAAmB;AACnB,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAMpD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA4D9F;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CASrC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
/** Adapter name */
|
|
3
|
+
export const name = 'claude-code';
|
|
4
|
+
/**
|
|
5
|
+
* Check if the `claude` CLI is available on the system PATH.
|
|
6
|
+
*/
|
|
7
|
+
export async function isAvailable() {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
const proc = spawn('which', ['claude'], { stdio: 'pipe' });
|
|
10
|
+
proc.on('close', (code) => resolve(code === 0));
|
|
11
|
+
proc.on('error', () => resolve(false));
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Execute a task by invoking the Claude Code CLI in print mode.
|
|
16
|
+
*/
|
|
17
|
+
export async function execute(task, options = {}) {
|
|
18
|
+
let prompt = `You are a ${task.agent}. ${task.prompt}`;
|
|
19
|
+
if (task.files && task.files.length > 0) {
|
|
20
|
+
prompt += `\n\nOnly modify files under: ${task.files.join(', ')}`;
|
|
21
|
+
}
|
|
22
|
+
const args = [
|
|
23
|
+
'-p',
|
|
24
|
+
prompt,
|
|
25
|
+
'--output-format',
|
|
26
|
+
'json',
|
|
27
|
+
'--max-turns',
|
|
28
|
+
'50',
|
|
29
|
+
];
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
const proc = spawn('claude', args, {
|
|
32
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
33
|
+
env: { ...process.env },
|
|
34
|
+
cwd: process.cwd(),
|
|
35
|
+
});
|
|
36
|
+
let stdout = '';
|
|
37
|
+
let stderr = '';
|
|
38
|
+
proc.stdout.on('data', (chunk) => {
|
|
39
|
+
stdout += chunk.toString();
|
|
40
|
+
if (options.verbose) {
|
|
41
|
+
process.stdout.write(chunk);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
proc.stderr.on('data', (chunk) => {
|
|
45
|
+
stderr += chunk.toString();
|
|
46
|
+
if (options.verbose) {
|
|
47
|
+
process.stderr.write(chunk);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
proc.on('close', (code) => {
|
|
51
|
+
const output = [stdout, stderr].filter(Boolean).join('\n');
|
|
52
|
+
resolve({
|
|
53
|
+
success: code === 0,
|
|
54
|
+
output: output.slice(0, 10000), // Cap output size
|
|
55
|
+
exitCode: code ?? -1,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
proc.on('error', (err) => {
|
|
59
|
+
resolve({
|
|
60
|
+
success: false,
|
|
61
|
+
output: `Failed to spawn claude: ${err.message}`,
|
|
62
|
+
exitCode: -1,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
// Store process ref for potential timeout kill
|
|
66
|
+
task._process = proc;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Kill the process associated with a task (used by timeout enforcement).
|
|
71
|
+
*/
|
|
72
|
+
export function kill(task) {
|
|
73
|
+
if (task._process && !task._process.killed) {
|
|
74
|
+
task._process.kill('SIGTERM');
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
if (task._process && !task._process.killed) {
|
|
77
|
+
task._process.kill('SIGKILL');
|
|
78
|
+
}
|
|
79
|
+
}, 5000);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=claude-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../../src/cli/run/adapters/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Task, ExecuteOptions, ExecuteResult } from '../../types.js';
|
|
2
|
+
/** Adapter name */
|
|
3
|
+
export declare const name = "copilot";
|
|
4
|
+
/**
|
|
5
|
+
* Check if the `copilot` CLI is available on the system PATH.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isAvailable(): Promise<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Execute a task by invoking the Copilot CLI in autopilot mode.
|
|
10
|
+
*/
|
|
11
|
+
export declare function execute(task: Task, options?: ExecuteOptions): Promise<ExecuteResult>;
|
|
12
|
+
/**
|
|
13
|
+
* Kill the process associated with a task (used by timeout enforcement).
|
|
14
|
+
*/
|
|
15
|
+
export declare function kill(task: Task): void;
|
|
16
|
+
//# sourceMappingURL=copilot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot.d.ts","sourceRoot":"","sources":["../../../../src/cli/run/adapters/copilot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEzE,mBAAmB;AACnB,eAAO,MAAM,IAAI,YAAY,CAAA;AAE7B;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAMpD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA8D9F;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CASrC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
/** Adapter name */
|
|
3
|
+
export const name = 'copilot';
|
|
4
|
+
/**
|
|
5
|
+
* Check if the `copilot` CLI is available on the system PATH.
|
|
6
|
+
*/
|
|
7
|
+
export async function isAvailable() {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
const proc = spawn('which', ['copilot'], { stdio: 'pipe' });
|
|
10
|
+
proc.on('close', (code) => resolve(code === 0));
|
|
11
|
+
proc.on('error', () => resolve(false));
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Execute a task by invoking the Copilot CLI in autopilot mode.
|
|
16
|
+
*/
|
|
17
|
+
export async function execute(task, options = {}) {
|
|
18
|
+
let prompt = `You are a ${task.agent}. ${task.prompt}`;
|
|
19
|
+
if (task.files && task.files.length > 0) {
|
|
20
|
+
prompt += `\n\nOnly modify files under: ${task.files.join(', ')}`;
|
|
21
|
+
}
|
|
22
|
+
const args = [
|
|
23
|
+
'-p',
|
|
24
|
+
prompt,
|
|
25
|
+
'--autopilot',
|
|
26
|
+
'--allow-all-tools',
|
|
27
|
+
'--no-ask-user',
|
|
28
|
+
'-s',
|
|
29
|
+
'--max-autopilot-continues',
|
|
30
|
+
'50',
|
|
31
|
+
];
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
const proc = spawn('copilot', args, {
|
|
34
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
35
|
+
env: { ...process.env },
|
|
36
|
+
cwd: process.cwd(),
|
|
37
|
+
});
|
|
38
|
+
let stdout = '';
|
|
39
|
+
let stderr = '';
|
|
40
|
+
proc.stdout.on('data', (chunk) => {
|
|
41
|
+
stdout += chunk.toString();
|
|
42
|
+
if (options.verbose) {
|
|
43
|
+
process.stdout.write(chunk);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
proc.stderr.on('data', (chunk) => {
|
|
47
|
+
stderr += chunk.toString();
|
|
48
|
+
if (options.verbose) {
|
|
49
|
+
process.stderr.write(chunk);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
proc.on('close', (code) => {
|
|
53
|
+
const output = [stdout, stderr].filter(Boolean).join('\n');
|
|
54
|
+
resolve({
|
|
55
|
+
success: code === 0,
|
|
56
|
+
output: output.slice(0, 10000), // Cap output size
|
|
57
|
+
exitCode: code ?? -1,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
proc.on('error', (err) => {
|
|
61
|
+
resolve({
|
|
62
|
+
success: false,
|
|
63
|
+
output: `Failed to spawn copilot: ${err.message}`,
|
|
64
|
+
exitCode: -1,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
// Store process ref for potential timeout kill
|
|
68
|
+
task._process = proc;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Kill the process associated with a task (used by timeout enforcement).
|
|
73
|
+
*/
|
|
74
|
+
export function kill(task) {
|
|
75
|
+
if (task._process && !task._process.killed) {
|
|
76
|
+
task._process.kill('SIGTERM');
|
|
77
|
+
setTimeout(() => {
|
|
78
|
+
if (task._process && !task._process.killed) {
|
|
79
|
+
task._process.kill('SIGKILL');
|
|
80
|
+
}
|
|
81
|
+
}, 5000);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=copilot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../../../src/cli/run/adapters/copilot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Task, ExecuteOptions, ExecuteResult } from '../../types.js';
|
|
2
|
+
/** Adapter name */
|
|
3
|
+
export declare const name = "cursor";
|
|
4
|
+
/**
|
|
5
|
+
* Check if the Cursor CLI (`agent`) is available on the system PATH.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isAvailable(): Promise<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Execute a task by invoking the Cursor CLI in non-interactive print mode.
|
|
10
|
+
*/
|
|
11
|
+
export declare function execute(task: Task, options?: ExecuteOptions): Promise<ExecuteResult>;
|
|
12
|
+
/**
|
|
13
|
+
* Kill the process associated with a task (used by timeout enforcement).
|
|
14
|
+
*/
|
|
15
|
+
export declare function kill(task: Task): void;
|
|
16
|
+
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../../src/cli/run/adapters/cursor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEzE,mBAAmB;AACnB,eAAO,MAAM,IAAI,WAAW,CAAA;AAE5B;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAMpD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA2D9F;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CASrC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
/** Adapter name */
|
|
3
|
+
export const name = 'cursor';
|
|
4
|
+
/**
|
|
5
|
+
* Check if the Cursor CLI (`agent`) is available on the system PATH.
|
|
6
|
+
*/
|
|
7
|
+
export async function isAvailable() {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
const proc = spawn('which', ['agent'], { stdio: 'pipe' });
|
|
10
|
+
proc.on('close', (code) => resolve(code === 0));
|
|
11
|
+
proc.on('error', () => resolve(false));
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Execute a task by invoking the Cursor CLI in non-interactive print mode.
|
|
16
|
+
*/
|
|
17
|
+
export async function execute(task, options = {}) {
|
|
18
|
+
let prompt = `You are a ${task.agent}. ${task.prompt}`;
|
|
19
|
+
if (task.files && task.files.length > 0) {
|
|
20
|
+
prompt += `\n\nOnly modify files under: ${task.files.join(', ')}`;
|
|
21
|
+
}
|
|
22
|
+
const args = [
|
|
23
|
+
'-p',
|
|
24
|
+
prompt,
|
|
25
|
+
'--force',
|
|
26
|
+
'--output-format',
|
|
27
|
+
'json',
|
|
28
|
+
];
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
const proc = spawn('agent', args, {
|
|
31
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
32
|
+
env: { ...process.env },
|
|
33
|
+
cwd: process.cwd(),
|
|
34
|
+
});
|
|
35
|
+
let stdout = '';
|
|
36
|
+
let stderr = '';
|
|
37
|
+
proc.stdout.on('data', (chunk) => {
|
|
38
|
+
stdout += chunk.toString();
|
|
39
|
+
if (options.verbose) {
|
|
40
|
+
process.stdout.write(chunk);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
proc.stderr.on('data', (chunk) => {
|
|
44
|
+
stderr += chunk.toString();
|
|
45
|
+
if (options.verbose) {
|
|
46
|
+
process.stderr.write(chunk);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
proc.on('close', (code) => {
|
|
50
|
+
const output = [stdout, stderr].filter(Boolean).join('\n');
|
|
51
|
+
resolve({
|
|
52
|
+
success: code === 0,
|
|
53
|
+
output: output.slice(0, 10000), // Cap output size
|
|
54
|
+
exitCode: code ?? -1,
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
proc.on('error', (err) => {
|
|
58
|
+
resolve({
|
|
59
|
+
success: false,
|
|
60
|
+
output: `Failed to spawn cursor agent CLI: ${err.message}`,
|
|
61
|
+
exitCode: -1,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
// Store process ref for potential timeout kill
|
|
65
|
+
task._process = proc;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Kill the process associated with a task (used by timeout enforcement).
|
|
70
|
+
*/
|
|
71
|
+
export function kill(task) {
|
|
72
|
+
if (task._process && !task._process.killed) {
|
|
73
|
+
task._process.kill('SIGTERM');
|
|
74
|
+
setTimeout(() => {
|
|
75
|
+
if (task._process && !task._process.killed) {
|
|
76
|
+
task._process.kill('SIGKILL');
|
|
77
|
+
}
|
|
78
|
+
}, 5000);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../../src/cli/run/adapters/cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AgentAdapter } from '../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get an adapter module by name.
|
|
4
|
+
* @throws If adapter is not registered
|
|
5
|
+
*/
|
|
6
|
+
export declare function getAdapter(name: string): Promise<AgentAdapter>;
|
|
7
|
+
/**
|
|
8
|
+
* List all registered adapters with their availability status.
|
|
9
|
+
*/
|
|
10
|
+
export declare function listAdapters(): Promise<Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
available: boolean;
|
|
13
|
+
}>>;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/run/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAWlD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CASpE;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAUzF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter registry for agent runtimes.
|
|
3
|
+
*/
|
|
4
|
+
const ADAPTERS = {
|
|
5
|
+
'claude-code': () => import('./claude-code.js'),
|
|
6
|
+
copilot: () => import('./copilot.js'),
|
|
7
|
+
cursor: () => import('./cursor.js'),
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Get an adapter module by name.
|
|
11
|
+
* @throws If adapter is not registered
|
|
12
|
+
*/
|
|
13
|
+
export async function getAdapter(name) {
|
|
14
|
+
const loader = ADAPTERS[name];
|
|
15
|
+
if (!loader) {
|
|
16
|
+
const available = Object.keys(ADAPTERS).join(', ');
|
|
17
|
+
throw new Error(`Unknown adapter "${name}". Available adapters: ${available}`);
|
|
18
|
+
}
|
|
19
|
+
return loader();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* List all registered adapters with their availability status.
|
|
23
|
+
*/
|
|
24
|
+
export async function listAdapters() {
|
|
25
|
+
const result = [];
|
|
26
|
+
for (const [name, loader] of Object.entries(ADAPTERS)) {
|
|
27
|
+
const mod = await loader();
|
|
28
|
+
result.push({
|
|
29
|
+
name,
|
|
30
|
+
available: await mod.isAvailable(),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/run/adapters/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,QAAQ,GAAgD;IAC5D,aAAa,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAA0B;IACxE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAA0B;IAC9D,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAA0B;CAC7D,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClD,MAAM,IAAI,KAAK,CACb,oBAAoB,IAAI,0BAA0B,SAAS,EAAE,CAC9D,CAAA;IACH,CAAC;IACD,OAAO,MAAM,EAAE,CAAA;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAgD,EAAE,CAAA;IAC9D,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,MAAM,EAAE,CAAA;QAC1B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,SAAS,EAAE,MAAM,GAAG,CAAC,WAAW,EAAE;SACnC,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Task, TaskSpec, AgentAdapter, Reporter, Executor } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Topological sort of tasks based on `depends_on` edges.
|
|
4
|
+
* Returns groups (phases) of tasks that can run in parallel.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildPhases(tasks: Task[]): Task[][];
|
|
7
|
+
/**
|
|
8
|
+
* Create a task executor.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createExecutor(spec: TaskSpec, adapter: AgentAdapter, reporter: Reporter): Executor;
|
|
11
|
+
/**
|
|
12
|
+
* Format a duration in ms to a human-readable string.
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatDuration(ms: number): string;
|
|
15
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/cli/run/executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,IAAI,EACJ,QAAQ,EAKR,YAAY,EAEZ,QAAQ,EACR,QAAQ,EAET,MAAM,aAAa,CAAA;AAEpB;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,CA6CnD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,QAAQ,GACjB,QAAQ,CA+LV;AAcD;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUjD"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { parseTimeout } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Topological sort of tasks based on `depends_on` edges.
|
|
4
|
+
* Returns groups (phases) of tasks that can run in parallel.
|
|
5
|
+
*/
|
|
6
|
+
export function buildPhases(tasks) {
|
|
7
|
+
const taskMap = new Map();
|
|
8
|
+
for (const t of tasks)
|
|
9
|
+
taskMap.set(t.id, t);
|
|
10
|
+
const inDegree = new Map();
|
|
11
|
+
const dependents = new Map();
|
|
12
|
+
for (const t of tasks) {
|
|
13
|
+
inDegree.set(t.id, (t.depends_on || []).length);
|
|
14
|
+
dependents.set(t.id, []);
|
|
15
|
+
}
|
|
16
|
+
for (const t of tasks) {
|
|
17
|
+
for (const dep of t.depends_on || []) {
|
|
18
|
+
dependents.get(dep).push(t.id);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const phases = [];
|
|
22
|
+
const remaining = new Set(tasks.map((t) => t.id));
|
|
23
|
+
while (remaining.size > 0) {
|
|
24
|
+
const phase = [];
|
|
25
|
+
for (const id of remaining) {
|
|
26
|
+
if (inDegree.get(id) === 0) {
|
|
27
|
+
phase.push(taskMap.get(id));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (phase.length === 0) {
|
|
31
|
+
// Should not happen if cycle detection passed
|
|
32
|
+
throw new Error('Cannot resolve task order — possible circular dependency');
|
|
33
|
+
}
|
|
34
|
+
phases.push(phase);
|
|
35
|
+
for (const t of phase) {
|
|
36
|
+
remaining.delete(t.id);
|
|
37
|
+
for (const depId of dependents.get(t.id)) {
|
|
38
|
+
inDegree.set(depId, inDegree.get(depId) - 1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return phases;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a task executor.
|
|
46
|
+
*/
|
|
47
|
+
export function createExecutor(spec, adapter, reporter) {
|
|
48
|
+
const phases = buildPhases(spec.tasks);
|
|
49
|
+
const statuses = new Map();
|
|
50
|
+
const results = new Map();
|
|
51
|
+
const startTimes = new Map();
|
|
52
|
+
for (const t of spec.tasks) {
|
|
53
|
+
statuses.set(t.id, 'pending');
|
|
54
|
+
results.set(t.id, null);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Execute a single task with timeout enforcement.
|
|
58
|
+
*/
|
|
59
|
+
async function executeTask(task) {
|
|
60
|
+
const timeoutMs = parseTimeout(task.timeout);
|
|
61
|
+
statuses.set(task.id, 'running');
|
|
62
|
+
startTimes.set(task.id, Date.now());
|
|
63
|
+
reporter.onTaskStart(task);
|
|
64
|
+
try {
|
|
65
|
+
const timeout = timeoutPromise(timeoutMs, task.id);
|
|
66
|
+
const result = await Promise.race([
|
|
67
|
+
adapter.execute(task, { verbose: spec._verbose }),
|
|
68
|
+
timeout.promise,
|
|
69
|
+
]);
|
|
70
|
+
const duration = Date.now() - startTimes.get(task.id);
|
|
71
|
+
if (result._timedOut) {
|
|
72
|
+
// Kill the orphaned child process
|
|
73
|
+
if (typeof adapter.kill === 'function') {
|
|
74
|
+
adapter.kill(task);
|
|
75
|
+
}
|
|
76
|
+
statuses.set(task.id, 'timed-out');
|
|
77
|
+
const taskResult = {
|
|
78
|
+
id: task.id,
|
|
79
|
+
status: 'timed-out',
|
|
80
|
+
duration,
|
|
81
|
+
output: `Task timed out after ${task.timeout}`,
|
|
82
|
+
exitCode: -1,
|
|
83
|
+
};
|
|
84
|
+
results.set(task.id, taskResult);
|
|
85
|
+
reporter.onTaskDone(task, taskResult);
|
|
86
|
+
return taskResult;
|
|
87
|
+
}
|
|
88
|
+
// Task completed normally — cancel the timeout timer
|
|
89
|
+
timeout.clear();
|
|
90
|
+
const status = result.success ? 'done' : 'failed';
|
|
91
|
+
statuses.set(task.id, status);
|
|
92
|
+
const taskResult = {
|
|
93
|
+
id: task.id,
|
|
94
|
+
status,
|
|
95
|
+
duration,
|
|
96
|
+
output: result.output || '',
|
|
97
|
+
exitCode: result.exitCode,
|
|
98
|
+
};
|
|
99
|
+
results.set(task.id, taskResult);
|
|
100
|
+
reporter.onTaskDone(task, taskResult);
|
|
101
|
+
return taskResult;
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
const duration = Date.now() - startTimes.get(task.id);
|
|
105
|
+
statuses.set(task.id, 'failed');
|
|
106
|
+
const taskResult = {
|
|
107
|
+
id: task.id,
|
|
108
|
+
status: 'failed',
|
|
109
|
+
duration,
|
|
110
|
+
output: err.message,
|
|
111
|
+
exitCode: -1,
|
|
112
|
+
};
|
|
113
|
+
results.set(task.id, taskResult);
|
|
114
|
+
reporter.onTaskDone(task, taskResult);
|
|
115
|
+
return taskResult;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Skip a task and all its transitive dependents.
|
|
120
|
+
*/
|
|
121
|
+
function skipTask(taskId, reason) {
|
|
122
|
+
if (statuses.get(taskId) !== 'pending')
|
|
123
|
+
return;
|
|
124
|
+
statuses.set(taskId, 'skipped');
|
|
125
|
+
const task = spec.tasks.find((t) => t.id === taskId);
|
|
126
|
+
results.set(taskId, {
|
|
127
|
+
id: taskId,
|
|
128
|
+
status: 'skipped',
|
|
129
|
+
duration: 0,
|
|
130
|
+
output: reason,
|
|
131
|
+
exitCode: -1,
|
|
132
|
+
});
|
|
133
|
+
reporter.onTaskSkipped(task, reason);
|
|
134
|
+
// Recursively skip dependents
|
|
135
|
+
for (const t of spec.tasks) {
|
|
136
|
+
if ((t.depends_on || []).includes(taskId)) {
|
|
137
|
+
skipTask(t.id, `dependency "${taskId}" was skipped/failed`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Run all tasks respecting phases and concurrency.
|
|
143
|
+
*/
|
|
144
|
+
async function run() {
|
|
145
|
+
const startedAt = new Date();
|
|
146
|
+
let halted = false;
|
|
147
|
+
for (let phaseIdx = 0; phaseIdx < phases.length; phaseIdx++) {
|
|
148
|
+
if (halted)
|
|
149
|
+
break;
|
|
150
|
+
const phase = phases[phaseIdx];
|
|
151
|
+
const eligible = phase.filter((t) => statuses.get(t.id) === 'pending');
|
|
152
|
+
if (eligible.length === 0)
|
|
153
|
+
continue;
|
|
154
|
+
reporter.onPhaseStart(phaseIdx + 1, eligible);
|
|
155
|
+
// Process eligible tasks in batches limited by concurrency
|
|
156
|
+
const concurrency = spec.concurrency;
|
|
157
|
+
for (let i = 0; i < eligible.length; i += concurrency) {
|
|
158
|
+
if (halted)
|
|
159
|
+
break;
|
|
160
|
+
const batch = eligible.slice(i, i + concurrency);
|
|
161
|
+
const batchResults = await Promise.all(batch.map(executeTask));
|
|
162
|
+
for (const r of batchResults) {
|
|
163
|
+
if (r.status === 'failed' || r.status === 'timed-out') {
|
|
164
|
+
if (spec.on_failure === 'stop') {
|
|
165
|
+
halted = true;
|
|
166
|
+
// Skip all remaining tasks
|
|
167
|
+
for (const t of spec.tasks) {
|
|
168
|
+
if (statuses.get(t.id) === 'pending') {
|
|
169
|
+
skipTask(t.id, 'execution halted due to on_failure: stop');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// on_failure: continue — skip dependents of this failed task
|
|
175
|
+
for (const t of spec.tasks) {
|
|
176
|
+
if ((t.depends_on || []).includes(r.id)) {
|
|
177
|
+
skipTask(t.id, `dependency "${r.id}" failed`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const completedAt = new Date();
|
|
186
|
+
const allResults = spec.tasks.map((t) => results.get(t.id) || {
|
|
187
|
+
id: t.id,
|
|
188
|
+
status: statuses.get(t.id),
|
|
189
|
+
duration: 0,
|
|
190
|
+
output: '',
|
|
191
|
+
exitCode: -1,
|
|
192
|
+
});
|
|
193
|
+
const summary = {
|
|
194
|
+
total: spec.tasks.length,
|
|
195
|
+
done: 0,
|
|
196
|
+
failed: 0,
|
|
197
|
+
skipped: 0,
|
|
198
|
+
'timed-out': 0,
|
|
199
|
+
};
|
|
200
|
+
for (const r of allResults) {
|
|
201
|
+
if (r.status in summary) {
|
|
202
|
+
summary[r.status]++;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const finalReport = {
|
|
206
|
+
name: spec.name,
|
|
207
|
+
startedAt: startedAt.toISOString(),
|
|
208
|
+
completedAt: completedAt.toISOString(),
|
|
209
|
+
duration: formatDuration(completedAt.getTime() - startedAt.getTime()),
|
|
210
|
+
summary,
|
|
211
|
+
tasks: allResults,
|
|
212
|
+
};
|
|
213
|
+
await reporter.onComplete(finalReport);
|
|
214
|
+
return finalReport;
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
run,
|
|
218
|
+
getPhases: () => phases,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Create a timeout promise that resolves with a sentinel.
|
|
223
|
+
* Returns { promise, clear } so the timer can be cancelled after normal completion.
|
|
224
|
+
*/
|
|
225
|
+
function timeoutPromise(ms, taskId) {
|
|
226
|
+
let timerId;
|
|
227
|
+
const promise = new Promise((resolve) => {
|
|
228
|
+
timerId = setTimeout(() => resolve({ _timedOut: true, taskId, success: false, output: '', exitCode: -1 }), ms);
|
|
229
|
+
});
|
|
230
|
+
return { promise, clear: () => clearTimeout(timerId) };
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Format a duration in ms to a human-readable string.
|
|
234
|
+
*/
|
|
235
|
+
export function formatDuration(ms) {
|
|
236
|
+
if (ms < 1000)
|
|
237
|
+
return `${ms}ms`;
|
|
238
|
+
const seconds = Math.floor(ms / 1000);
|
|
239
|
+
if (seconds < 60)
|
|
240
|
+
return `${seconds}s`;
|
|
241
|
+
const minutes = Math.floor(seconds / 60);
|
|
242
|
+
const remSec = seconds % 60;
|
|
243
|
+
if (minutes < 60)
|
|
244
|
+
return remSec > 0 ? `${minutes}m ${remSec}s` : `${minutes}m`;
|
|
245
|
+
const hours = Math.floor(minutes / 60);
|
|
246
|
+
const remMin = minutes % 60;
|
|
247
|
+
return remMin > 0 ? `${hours}h ${remMin}m` : `${hours}h`;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=executor.js.map
|