@dewtech/dare-cli 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -6
- package/dist/__tests__/dag-runner/adapters.test.d.ts +2 -0
- package/dist/__tests__/dag-runner/adapters.test.d.ts.map +1 -0
- package/dist/__tests__/dag-runner/adapters.test.js +134 -0
- package/dist/__tests__/dag-runner/adapters.test.js.map +1 -0
- package/dist/__tests__/dag-runner/utils.test.d.ts +2 -0
- package/dist/__tests__/dag-runner/utils.test.d.ts.map +1 -0
- package/dist/__tests__/dag-runner/utils.test.js +75 -0
- package/dist/__tests__/dag-runner/utils.test.js.map +1 -0
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +38 -30
- package/dist/commands/execute.js.map +1 -1
- package/dist/dag-runner/adapters/antigravity.d.ts +6 -0
- package/dist/dag-runner/adapters/antigravity.d.ts.map +1 -0
- package/dist/dag-runner/adapters/antigravity.js +54 -0
- package/dist/dag-runner/adapters/antigravity.js.map +1 -0
- package/dist/dag-runner/adapters/claude.d.ts +6 -0
- package/dist/dag-runner/adapters/claude.d.ts.map +1 -0
- package/dist/dag-runner/adapters/claude.js +48 -0
- package/dist/dag-runner/adapters/claude.js.map +1 -0
- package/dist/dag-runner/adapters/cursor.d.ts +6 -0
- package/dist/dag-runner/adapters/cursor.d.ts.map +1 -0
- package/dist/dag-runner/adapters/cursor.js +58 -0
- package/dist/dag-runner/adapters/cursor.js.map +1 -0
- package/dist/dag-runner/adapters/index.d.ts +46 -0
- package/dist/dag-runner/adapters/index.d.ts.map +1 -0
- package/dist/dag-runner/adapters/index.js +55 -0
- package/dist/dag-runner/adapters/index.js.map +1 -0
- package/dist/dag-runner/run_dag.d.ts +21 -11
- package/dist/dag-runner/run_dag.d.ts.map +1 -1
- package/dist/dag-runner/run_dag.js +199 -124
- package/dist/dag-runner/run_dag.js.map +1 -1
- package/dist/dag-runner/utils/cap-output.d.ts +14 -0
- package/dist/dag-runner/utils/cap-output.d.ts.map +1 -0
- package/dist/dag-runner/utils/cap-output.js +22 -0
- package/dist/dag-runner/utils/cap-output.js.map +1 -0
- package/dist/dag-runner/utils/stitch-context.d.ts +24 -0
- package/dist/dag-runner/utils/stitch-context.d.ts.map +1 -0
- package/dist/dag-runner/utils/stitch-context.js +36 -0
- package/dist/dag-runner/utils/stitch-context.js.map +1 -0
- package/dist/dag-runner/utils/timeout.d.ts +27 -0
- package/dist/dag-runner/utils/timeout.d.ts.map +1 -0
- package/dist/dag-runner/utils/timeout.js +55 -0
- package/dist/dag-runner/utils/timeout.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -88,19 +88,46 @@ dare blueprint
|
|
|
88
88
|
|
|
89
89
|
### `dare execute`
|
|
90
90
|
|
|
91
|
-
Execute
|
|
91
|
+
Execute the DAG using a real SDK adapter (Claude / Cursor / Antigravity).
|
|
92
|
+
The runner orders tasks topologically (Kahn's algorithm), runs each rank in
|
|
93
|
+
parallel, applies per-task `parent_context_chars` / `task_output_chars` /
|
|
94
|
+
`timeout_seconds` limits, and writes a live canvas to `DARE/.canvas.md`.
|
|
92
95
|
|
|
93
96
|
```bash
|
|
94
|
-
#
|
|
97
|
+
# Parallel execution (recommended, default runner = cursor)
|
|
95
98
|
dare execute --parallel --runner cursor
|
|
99
|
+
dare execute --parallel --runner claude
|
|
100
|
+
dare execute --parallel --runner antigravity
|
|
96
101
|
|
|
97
|
-
#
|
|
98
|
-
dare execute
|
|
102
|
+
# Sequential (debug)
|
|
103
|
+
dare execute --runner claude
|
|
99
104
|
|
|
100
|
-
#
|
|
101
|
-
dare execute
|
|
105
|
+
# Single task
|
|
106
|
+
dare execute --task task-003 --runner claude
|
|
107
|
+
|
|
108
|
+
# Resume — only run PENDING/FAILED, keep DONE/SKIPPED
|
|
109
|
+
dare execute --parallel --resume
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Required environment variables
|
|
113
|
+
|
|
114
|
+
| Runner | Env var | Where to get it |
|
|
115
|
+
|--------|---------|-----------------|
|
|
116
|
+
| `claude` | `ANTHROPIC_API_KEY` | https://console.anthropic.com/settings/keys |
|
|
117
|
+
| `cursor` | `CURSOR_API_KEY` | Cursor Settings → API Keys |
|
|
118
|
+
| `antigravity` | `ANTIGRAVITY_API_KEY` (or `GOOGLE_API_KEY`) | https://aistudio.google.com/app/apikey |
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Windows (PowerShell)
|
|
122
|
+
$env:ANTHROPIC_API_KEY = "sk-ant-..."
|
|
123
|
+
|
|
124
|
+
# bash
|
|
125
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
102
126
|
```
|
|
103
127
|
|
|
128
|
+
The runner honors `SIGINT` / `SIGTERM` — Ctrl+C cancels every in-flight task
|
|
129
|
+
cleanly via AbortController.
|
|
130
|
+
|
|
104
131
|
---
|
|
105
132
|
|
|
106
133
|
## Full Workflow
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/dag-runner/adapters.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { getAdapter, MissingApiKeyError, pickModel, } from '../../dag-runner/adapters/index.js';
|
|
3
|
+
const sampleModels = { HIGH: 'big', MED: 'mid', LOW: 'small' };
|
|
4
|
+
// ─── Anthropic SDK mock ──────────────────────────────────────────────────────
|
|
5
|
+
vi.mock('@anthropic-ai/sdk', () => {
|
|
6
|
+
var _a;
|
|
7
|
+
const create = vi.fn(async () => ({
|
|
8
|
+
content: [{ type: 'text', text: 'mocked claude response' }],
|
|
9
|
+
usage: { input_tokens: 10, output_tokens: 20 },
|
|
10
|
+
}));
|
|
11
|
+
// Default export is the client class.
|
|
12
|
+
return {
|
|
13
|
+
default: (_a = class MockAnthropic {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.messages = { create };
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
_a.__spy = create,
|
|
19
|
+
_a),
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
// ─── Cursor SDK mock ─────────────────────────────────────────────────────────
|
|
23
|
+
vi.mock('@cursor/sdk', () => ({
|
|
24
|
+
Agent: {
|
|
25
|
+
create: vi.fn(async () => ({
|
|
26
|
+
send: vi.fn(async () => ({
|
|
27
|
+
cancel: vi.fn(async () => undefined),
|
|
28
|
+
wait: vi.fn(async () => ({ result: 'mocked cursor response' })),
|
|
29
|
+
})),
|
|
30
|
+
close: vi.fn(async () => undefined),
|
|
31
|
+
})),
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
// ─── Google Generative AI mock ───────────────────────────────────────────────
|
|
35
|
+
vi.mock('@google/generative-ai', () => ({
|
|
36
|
+
GoogleGenerativeAI: class {
|
|
37
|
+
getGenerativeModel() {
|
|
38
|
+
return {
|
|
39
|
+
generateContent: async () => ({
|
|
40
|
+
response: {
|
|
41
|
+
text: () => 'mocked antigravity response',
|
|
42
|
+
usageMetadata: { promptTokenCount: 5, candidatesTokenCount: 7 },
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
}));
|
|
49
|
+
describe('pickModel', () => {
|
|
50
|
+
it('returns the model id for the given complexity', () => {
|
|
51
|
+
expect(pickModel(sampleModels, 'HIGH')).toBe('big');
|
|
52
|
+
expect(pickModel(sampleModels, 'MED')).toBe('mid');
|
|
53
|
+
expect(pickModel(sampleModels, 'LOW')).toBe('small');
|
|
54
|
+
});
|
|
55
|
+
it('throws when models block is missing', () => {
|
|
56
|
+
expect(() => pickModel(undefined, 'HIGH')).toThrow();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('Adapters — happy path with mocked SDKs', () => {
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
process.env.ANTHROPIC_API_KEY = 'test-key';
|
|
62
|
+
process.env.CURSOR_API_KEY = 'test-key';
|
|
63
|
+
process.env.ANTIGRAVITY_API_KEY = 'test-key';
|
|
64
|
+
});
|
|
65
|
+
it('claude adapter calls SDK and returns text + tokens', async () => {
|
|
66
|
+
const adapter = await getAdapter('claude');
|
|
67
|
+
const ctrl = new AbortController();
|
|
68
|
+
const res = await adapter.call({
|
|
69
|
+
prompt: 'hi',
|
|
70
|
+
complexity: 'MED',
|
|
71
|
+
models: sampleModels,
|
|
72
|
+
signal: ctrl.signal,
|
|
73
|
+
});
|
|
74
|
+
expect(res.output).toBe('mocked claude response');
|
|
75
|
+
expect(res.tokens).toBe(30);
|
|
76
|
+
});
|
|
77
|
+
it('cursor adapter calls SDK and returns result', async () => {
|
|
78
|
+
const adapter = await getAdapter('cursor');
|
|
79
|
+
const ctrl = new AbortController();
|
|
80
|
+
const res = await adapter.call({
|
|
81
|
+
prompt: 'hi',
|
|
82
|
+
complexity: 'LOW',
|
|
83
|
+
models: sampleModels,
|
|
84
|
+
signal: ctrl.signal,
|
|
85
|
+
});
|
|
86
|
+
expect(res.output).toBe('mocked cursor response');
|
|
87
|
+
});
|
|
88
|
+
it('antigravity adapter calls SDK and returns text + tokens', async () => {
|
|
89
|
+
const adapter = await getAdapter('antigravity');
|
|
90
|
+
const ctrl = new AbortController();
|
|
91
|
+
const res = await adapter.call({
|
|
92
|
+
prompt: 'hi',
|
|
93
|
+
complexity: 'HIGH',
|
|
94
|
+
models: sampleModels,
|
|
95
|
+
signal: ctrl.signal,
|
|
96
|
+
});
|
|
97
|
+
expect(res.output).toBe('mocked antigravity response');
|
|
98
|
+
expect(res.tokens).toBe(12);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('Adapters — missing API keys', () => {
|
|
102
|
+
it('claude adapter throws MissingApiKeyError when ANTHROPIC_API_KEY is unset', async () => {
|
|
103
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
104
|
+
const adapter = await getAdapter('claude');
|
|
105
|
+
await expect(adapter.call({
|
|
106
|
+
prompt: 'hi',
|
|
107
|
+
complexity: 'MED',
|
|
108
|
+
models: sampleModels,
|
|
109
|
+
signal: new AbortController().signal,
|
|
110
|
+
})).rejects.toBeInstanceOf(MissingApiKeyError);
|
|
111
|
+
});
|
|
112
|
+
it('cursor adapter throws MissingApiKeyError when CURSOR_API_KEY is unset', async () => {
|
|
113
|
+
delete process.env.CURSOR_API_KEY;
|
|
114
|
+
const adapter = await getAdapter('cursor');
|
|
115
|
+
await expect(adapter.call({
|
|
116
|
+
prompt: 'hi',
|
|
117
|
+
complexity: 'MED',
|
|
118
|
+
models: sampleModels,
|
|
119
|
+
signal: new AbortController().signal,
|
|
120
|
+
})).rejects.toBeInstanceOf(MissingApiKeyError);
|
|
121
|
+
});
|
|
122
|
+
it('antigravity adapter throws MissingApiKeyError when both env vars are unset', async () => {
|
|
123
|
+
delete process.env.ANTIGRAVITY_API_KEY;
|
|
124
|
+
delete process.env.GOOGLE_API_KEY;
|
|
125
|
+
const adapter = await getAdapter('antigravity');
|
|
126
|
+
await expect(adapter.call({
|
|
127
|
+
prompt: 'hi',
|
|
128
|
+
complexity: 'MED',
|
|
129
|
+
models: sampleModels,
|
|
130
|
+
signal: new AbortController().signal,
|
|
131
|
+
})).rejects.toBeInstanceOf(MissingApiKeyError);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
//# sourceMappingURL=adapters.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.test.js","sourceRoot":"","sources":["../../../src/__tests__/dag-runner/adapters.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/dag-runner/utils.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { capOutput } from '../../dag-runner/utils/cap-output.js';
|
|
3
|
+
import { composePrompt, stitchParentContext, } from '../../dag-runner/utils/stitch-context.js';
|
|
4
|
+
import { TaskAbortedError, TaskTimeoutError, withTimeout, } from '../../dag-runner/utils/timeout.js';
|
|
5
|
+
const makeTask = (over) => ({
|
|
6
|
+
id: 't',
|
|
7
|
+
title: 't',
|
|
8
|
+
depends_on: [],
|
|
9
|
+
complexity: 'MED',
|
|
10
|
+
subtask_prompt: '',
|
|
11
|
+
...over,
|
|
12
|
+
});
|
|
13
|
+
describe('capOutput', () => {
|
|
14
|
+
it('passes through when below the cap', () => {
|
|
15
|
+
expect(capOutput('hello', 100)).toBe('hello');
|
|
16
|
+
});
|
|
17
|
+
it('truncates with notice when above the cap', () => {
|
|
18
|
+
const out = capOutput('a'.repeat(200), 50);
|
|
19
|
+
expect(out.length).toBe(50);
|
|
20
|
+
expect(out).toMatch(/truncated by DARE/);
|
|
21
|
+
});
|
|
22
|
+
it('returns empty when cap is 0', () => {
|
|
23
|
+
expect(capOutput('anything', 0)).toBe('');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe('stitchParentContext / composePrompt', () => {
|
|
27
|
+
it('returns empty string when no parents', () => {
|
|
28
|
+
const task = makeTask({ id: 'child', subtask_prompt: 'do x' });
|
|
29
|
+
expect(stitchParentContext({ task, parents: [], parentContextChars: 2000 })).toBe('');
|
|
30
|
+
});
|
|
31
|
+
it('appends a tail snippet for each parent capped to N chars', () => {
|
|
32
|
+
const parent = makeTask({ id: 'p1', output: 'A'.repeat(5000) });
|
|
33
|
+
const task = makeTask({ id: 'c', subtask_prompt: 'work' });
|
|
34
|
+
const ctx = stitchParentContext({ task, parents: [parent], parentContextChars: 100 });
|
|
35
|
+
expect(ctx).toMatch(/From parent: p1/);
|
|
36
|
+
// Tail-of-output strategy: ellipsis + 99 chars = 100
|
|
37
|
+
expect(ctx).toMatch(/A{50,}/); // contains a long run of As
|
|
38
|
+
const snippetLine = ctx.split('\n').find((l) => l.startsWith('…')) ?? '';
|
|
39
|
+
expect(snippetLine.length).toBe(100);
|
|
40
|
+
});
|
|
41
|
+
it('composePrompt prepends prompt and appends context', () => {
|
|
42
|
+
const parent = makeTask({ id: 'p', output: 'parent says hi' });
|
|
43
|
+
const task = makeTask({ subtask_prompt: 'go' });
|
|
44
|
+
const out = composePrompt({ task, parents: [parent], parentContextChars: 2000 });
|
|
45
|
+
expect(out.startsWith('go')).toBe(true);
|
|
46
|
+
expect(out).toMatch(/Upstream context/);
|
|
47
|
+
expect(out).toMatch(/parent says hi/);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('withTimeout', () => {
|
|
51
|
+
it('resolves when the operation finishes in time', async () => {
|
|
52
|
+
const result = await withTimeout(async () => 42, { timeoutSeconds: 5 });
|
|
53
|
+
expect(result).toBe(42);
|
|
54
|
+
});
|
|
55
|
+
it('rejects with TaskTimeoutError when the operation exceeds the budget', async () => {
|
|
56
|
+
await expect(withTimeout(async ({ signal }) => new Promise((resolve, reject) => {
|
|
57
|
+
const t = setTimeout(() => resolve(1), 500);
|
|
58
|
+
signal.addEventListener('abort', () => {
|
|
59
|
+
clearTimeout(t);
|
|
60
|
+
reject(new Error('ignored — outer rejects first'));
|
|
61
|
+
});
|
|
62
|
+
}),
|
|
63
|
+
// 50ms timeout — way before the 500ms operation finishes
|
|
64
|
+
{ timeoutSeconds: 0.05 })).rejects.toBeInstanceOf(TaskTimeoutError);
|
|
65
|
+
});
|
|
66
|
+
it('rejects with TaskAbortedError when the external signal aborts', async () => {
|
|
67
|
+
const ctrl = new AbortController();
|
|
68
|
+
setTimeout(() => ctrl.abort('user'), 20);
|
|
69
|
+
await expect(withTimeout(async ({ signal }) => new Promise((resolve) => {
|
|
70
|
+
const t = setTimeout(() => resolve(1), 500);
|
|
71
|
+
signal.addEventListener('abort', () => clearTimeout(t));
|
|
72
|
+
}), { timeoutSeconds: 5, externalSignal: ctrl.signal })).rejects.toBeInstanceOf(TaskAbortedError);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=utils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../../src/__tests__/dag-runner/utils.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,eAAO,MAAM,cAAc,SAiEvB,CAAC"}
|
package/dist/commands/execute.js
CHANGED
|
@@ -5,56 +5,64 @@ import path from 'path';
|
|
|
5
5
|
import { runDag } from '../dag-runner/run_dag.js';
|
|
6
6
|
import { convertYamlToDag } from '../utils/dag-converter.js';
|
|
7
7
|
export const executeCommand = new Command('execute')
|
|
8
|
-
.description('Execute tasks using DAG Task Runner')
|
|
9
|
-
.
|
|
10
|
-
.option('--
|
|
11
|
-
.option('--runner <runner>', 'Runner: cursor or antigravity', 'cursor')
|
|
8
|
+
.description('Execute tasks using the DAG Task Runner (real SDK adapters)')
|
|
9
|
+
.option('--parallel', 'Execute independent tasks in parallel by rank', false)
|
|
10
|
+
.option('--runner <runner>', 'Runner: cursor | claude | antigravity', 'cursor')
|
|
12
11
|
.option('--dag <file>', 'Path to dare-dag.yaml', 'DARE/dare-dag.yaml')
|
|
13
|
-
.
|
|
12
|
+
.option('--resume', 'Skip tasks already DONE/SKIPPED', false)
|
|
13
|
+
.option('--task <id>', 'Execute only the task with the given id')
|
|
14
|
+
.action(async (options) => {
|
|
14
15
|
console.log(chalk.blue.bold('\n⚡ DARE Framework - Execute Phase\n'));
|
|
15
16
|
const dagPath = path.resolve(process.cwd(), options.dag);
|
|
16
|
-
if (!await fs.pathExists(dagPath)) {
|
|
17
|
+
if (!(await fs.pathExists(dagPath))) {
|
|
17
18
|
console.error(chalk.red(`❌ dare-dag.yaml not found at ${dagPath}`));
|
|
18
19
|
console.log(chalk.yellow('Run: dare blueprint'));
|
|
19
20
|
process.exit(1);
|
|
20
21
|
}
|
|
22
|
+
if (!isKnownRunner(options.runner)) {
|
|
23
|
+
console.error(chalk.red(`❌ Unknown runner "${options.runner}". Use: cursor | claude | antigravity.`));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
21
26
|
const dagContent = await fs.readFile(dagPath, 'utf-8');
|
|
22
27
|
const dag = convertYamlToDag(dagContent);
|
|
23
|
-
if (
|
|
24
|
-
const task = dag.tasks.find((t) => t.id ===
|
|
28
|
+
if (options.task) {
|
|
29
|
+
const task = dag.tasks.find((t) => t.id === options.task);
|
|
25
30
|
if (!task) {
|
|
26
|
-
console.error(chalk.red(`❌ Task ${
|
|
31
|
+
console.error(chalk.red(`❌ Task "${options.task}" not found in DAG`));
|
|
27
32
|
process.exit(1);
|
|
28
33
|
}
|
|
29
|
-
console.log(chalk.cyan(`🎯 Executing single task: ${task.id}
|
|
34
|
+
console.log(chalk.cyan(`🎯 Executing single task: ${task.id} — ${task.title}`));
|
|
30
35
|
}
|
|
31
36
|
else {
|
|
32
|
-
const
|
|
33
|
-
console.log(chalk.cyan(`📋 Tasks to execute: ${
|
|
34
|
-
console.log(chalk.cyan(`🔀 Mode: ${options.parallel ? 'Parallel (
|
|
35
|
-
console.log(chalk.cyan(`🖥️ Runner: ${options.runner}
|
|
37
|
+
const remaining = dag.tasks.filter((t) => !options.resume || (t.status !== 'DONE' && t.status !== 'SKIPPED'));
|
|
38
|
+
console.log(chalk.cyan(`📋 Tasks to execute: ${remaining.length} of ${dag.tasks.length}`));
|
|
39
|
+
console.log(chalk.cyan(`🔀 Mode: ${options.parallel ? 'Parallel (by rank)' : 'Sequential'}`));
|
|
40
|
+
console.log(chalk.cyan(`🖥️ Runner: ${options.runner}`));
|
|
41
|
+
if (options.resume)
|
|
42
|
+
console.log(chalk.cyan('🔁 Resume: skipping DONE/SKIPPED'));
|
|
43
|
+
console.log();
|
|
36
44
|
}
|
|
37
|
-
|
|
38
|
-
console.log(chalk.yellow('🚀 Starting DAG Task Runner with parallel execution...\n'));
|
|
45
|
+
try {
|
|
39
46
|
await runDag(dag, {
|
|
40
|
-
parallel:
|
|
47
|
+
parallel: options.parallel,
|
|
41
48
|
runner: options.runner,
|
|
42
49
|
canvasPath: path.resolve(process.cwd(), 'DARE/.canvas.md'),
|
|
50
|
+
resume: options.resume,
|
|
51
|
+
onlyTaskId: options.task,
|
|
43
52
|
});
|
|
44
53
|
}
|
|
45
|
-
|
|
46
|
-
console.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// Sequential execution placeholder
|
|
54
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
55
|
-
console.log(chalk.green(`✅ ${task.id} completed`));
|
|
56
|
-
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
console.error(chalk.red(`\n❌ Run failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const failed = dag.tasks.filter((t) => t.status === 'FAILED').length;
|
|
59
|
+
if (failed > 0) {
|
|
60
|
+
console.log(chalk.yellow(`⚠ ${failed} task(s) FAILED. Re-run with --resume after fixing.`));
|
|
61
|
+
process.exit(1);
|
|
57
62
|
}
|
|
58
|
-
console.log(chalk.green.bold('
|
|
63
|
+
console.log(chalk.green.bold('✅ Execution complete!\n'));
|
|
59
64
|
});
|
|
65
|
+
function isKnownRunner(runner) {
|
|
66
|
+
return runner === 'cursor' || runner === 'claude' || runner === 'antigravity';
|
|
67
|
+
}
|
|
60
68
|
//# sourceMappingURL=execute.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AdapterCallInput, type AdapterCallResult, type RunnerAdapter } from './index.js';
|
|
2
|
+
export declare class AntigravityAdapter implements RunnerAdapter {
|
|
3
|
+
readonly name: "antigravity";
|
|
4
|
+
call({ prompt, complexity, models, signal }: AdapterCallInput): Promise<AdapterCallResult>;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=antigravity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antigravity.d.ts","sourceRoot":"","sources":["../../../src/dag-runner/adapters/antigravity.ts"],"names":[],"mappings":"AAWA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAQpB,qBAAa,kBAAmB,YAAW,aAAa;IACtD,QAAQ,CAAC,IAAI,EAAG,aAAa,CAAU;IAEjC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA6BjG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antigravity adapter — uses Google Generative AI (Gemini) to execute a task.
|
|
3
|
+
*
|
|
4
|
+
* Antigravity (Google's IDE) does not expose a public agent SDK at the time
|
|
5
|
+
* of writing, so we drive the underlying Gemini family directly. Models in
|
|
6
|
+
* `dare-dag.yaml`'s `models.antigravity` block (e.g. `gemini-2.5-pro`,
|
|
7
|
+
* `gemini-2.5-flash`) are passed as the model id.
|
|
8
|
+
*
|
|
9
|
+
* Env: ANTIGRAVITY_API_KEY (preferred) or GOOGLE_API_KEY (fallback).
|
|
10
|
+
*/
|
|
11
|
+
import { GoogleGenerativeAI } from '@google/generative-ai';
|
|
12
|
+
import { AdapterCallError, MissingApiKeyError, pickModel, } from './index.js';
|
|
13
|
+
const SYSTEM_INSTRUCTION = 'You are a DARE subagent executing a single task from a DAG. Follow the prompt ' +
|
|
14
|
+
'exactly. When you finish, respond with a concise summary of what you did and the ' +
|
|
15
|
+
'paths of files you created or modified. Keep responses self-contained — your ' +
|
|
16
|
+
'output may be quoted into a downstream task.';
|
|
17
|
+
export class AntigravityAdapter {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.name = 'antigravity';
|
|
20
|
+
}
|
|
21
|
+
async call({ prompt, complexity, models, signal }) {
|
|
22
|
+
const apiKey = process.env.ANTIGRAVITY_API_KEY ?? process.env.GOOGLE_API_KEY;
|
|
23
|
+
if (!apiKey)
|
|
24
|
+
throw new MissingApiKeyError('antigravity', 'ANTIGRAVITY_API_KEY');
|
|
25
|
+
const modelId = pickModel(models, complexity);
|
|
26
|
+
try {
|
|
27
|
+
const client = new GoogleGenerativeAI(apiKey);
|
|
28
|
+
const model = client.getGenerativeModel({
|
|
29
|
+
model: modelId,
|
|
30
|
+
systemInstruction: SYSTEM_INSTRUCTION,
|
|
31
|
+
});
|
|
32
|
+
const res = await model.generateContent({
|
|
33
|
+
contents: [{ role: 'user', parts: [{ text: prompt }] }],
|
|
34
|
+
}, { signal });
|
|
35
|
+
const text = res.response.text();
|
|
36
|
+
const usage = res.response.usageMetadata;
|
|
37
|
+
const tokens = usage
|
|
38
|
+
? (usage.promptTokenCount ?? 0) + (usage.candidatesTokenCount ?? 0)
|
|
39
|
+
: undefined;
|
|
40
|
+
return { output: text, tokens };
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err instanceof MissingApiKeyError)
|
|
44
|
+
throw err;
|
|
45
|
+
throw new AdapterCallError('antigravity', extractErrorMessage(err), err);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function extractErrorMessage(err) {
|
|
50
|
+
if (err instanceof Error)
|
|
51
|
+
return err.message;
|
|
52
|
+
return String(err);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=antigravity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../../../src/dag-runner/adapters/antigravity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,GAIV,MAAM,YAAY,CAAC;AAEpB,MAAM,kBAAkB,GACtB,gFAAgF;IAChF,mFAAmF;IACnF,+EAA+E;IAC/E,8CAA8C,CAAC;AAEjD,MAAM,OAAO,kBAAkB;IAA/B;QACW,SAAI,GAAG,aAAsB,CAAC;IA+BzC,CAAC;IA7BC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAoB;QACjE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC7E,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,kBAAkB,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;QAEhF,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAE9C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,kBAAkB,CAAC;gBACtC,KAAK,EAAE,OAAO;gBACd,iBAAiB,EAAE,kBAAkB;aACtC,CAAC,CAAC;YAEH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC;gBACtC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;aACxD,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAEf,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;YACzC,MAAM,MAAM,GAAG,KAAK;gBAClB,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,IAAI,CAAC,CAAC;gBACnE,CAAC,CAAC,SAAS,CAAC;YAEd,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,kBAAkB;gBAAE,MAAM,GAAG,CAAC;YACjD,MAAM,IAAI,gBAAgB,CAAC,aAAa,EAAE,mBAAmB,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;CACF;AAED,SAAS,mBAAmB,CAAC,GAAY;IACvC,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC7C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AdapterCallInput, type AdapterCallResult, type RunnerAdapter } from './index.js';
|
|
2
|
+
export declare class ClaudeAdapter implements RunnerAdapter {
|
|
3
|
+
readonly name: "claude";
|
|
4
|
+
call({ prompt, complexity, models, signal }: AdapterCallInput): Promise<AdapterCallResult>;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/dag-runner/adapters/claude.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAQpB,qBAAa,aAAc,YAAW,aAAa;IACjD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAE5B,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA+BjG"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude adapter — calls the Anthropic Messages API to execute a task.
|
|
3
|
+
*
|
|
4
|
+
* Env: ANTHROPIC_API_KEY
|
|
5
|
+
*/
|
|
6
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
7
|
+
import { AdapterCallError, MissingApiKeyError, pickModel, } from './index.js';
|
|
8
|
+
const SYSTEM_PROMPT = 'You are a DARE subagent executing a single task from a DAG. Follow the prompt ' +
|
|
9
|
+
'exactly. When you finish, respond with a concise summary of what you did and the ' +
|
|
10
|
+
'paths of files you created or modified. Keep responses self-contained — your ' +
|
|
11
|
+
'output may be quoted into a downstream task.';
|
|
12
|
+
export class ClaudeAdapter {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.name = 'claude';
|
|
15
|
+
}
|
|
16
|
+
async call({ prompt, complexity, models, signal }) {
|
|
17
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
18
|
+
if (!apiKey)
|
|
19
|
+
throw new MissingApiKeyError('claude', 'ANTHROPIC_API_KEY');
|
|
20
|
+
const model = pickModel(models, complexity);
|
|
21
|
+
const client = new Anthropic({ apiKey });
|
|
22
|
+
try {
|
|
23
|
+
const res = await client.messages.create({
|
|
24
|
+
model,
|
|
25
|
+
max_tokens: 4096,
|
|
26
|
+
system: SYSTEM_PROMPT,
|
|
27
|
+
messages: [{ role: 'user', content: prompt }],
|
|
28
|
+
}, { signal });
|
|
29
|
+
const text = res.content
|
|
30
|
+
.filter((b) => b.type === 'text')
|
|
31
|
+
.map((b) => b.text)
|
|
32
|
+
.join('\n');
|
|
33
|
+
const tokens = (res.usage?.input_tokens ?? 0) + (res.usage?.output_tokens ?? 0);
|
|
34
|
+
return { output: text, tokens };
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err instanceof MissingApiKeyError)
|
|
38
|
+
throw err;
|
|
39
|
+
throw new AdapterCallError('claude', extractErrorMessage(err), err);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function extractErrorMessage(err) {
|
|
44
|
+
if (err instanceof Error)
|
|
45
|
+
return err.message;
|
|
46
|
+
return String(err);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/dag-runner/adapters/claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,GAIV,MAAM,YAAY,CAAC;AAEpB,MAAM,aAAa,GACjB,gFAAgF;IAChF,mFAAmF;IACnF,+EAA+E;IAC/E,8CAA8C,CAAC;AAEjD,MAAM,OAAO,aAAa;IAA1B;QACW,SAAI,GAAG,QAAiB,CAAC;IAiCpC,CAAC;IA/BC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAoB;QACjE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC7C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QAEzE,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CACtC;gBACE,KAAK;gBACL,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,aAAa;gBACrB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,EACD,EAAE,MAAM,EAAE,CACX,CAAC;YAEF,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO;iBACrB,MAAM,CAAC,CAAC,CAAC,EAA4B,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;iBAC1D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAClB,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC,CAAC,CAAC;YAEhF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,kBAAkB;gBAAE,MAAM,GAAG,CAAC;YACjD,MAAM,IAAI,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF;AAED,SAAS,mBAAmB,CAAC,GAAY;IACvC,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC7C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AdapterCallInput, type AdapterCallResult, type RunnerAdapter } from './index.js';
|
|
2
|
+
export declare class CursorAdapter implements RunnerAdapter {
|
|
3
|
+
readonly name: "cursor";
|
|
4
|
+
call({ prompt, complexity, models, signal }: AdapterCallInput): Promise<AdapterCallResult>;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/dag-runner/adapters/cursor.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAEpB,qBAAa,aAAc,YAAW,aAAa;IACjD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAE5B,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAoCjG"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor adapter — uses @cursor/sdk to execute a task as a local subagent.
|
|
3
|
+
*
|
|
4
|
+
* Env: CURSOR_API_KEY
|
|
5
|
+
*
|
|
6
|
+
* Compatible with the cookbook DAG Task Runner pattern (Agent.create + send + wait).
|
|
7
|
+
*/
|
|
8
|
+
import { Agent } from '@cursor/sdk';
|
|
9
|
+
import { AdapterCallError, MissingApiKeyError, pickModel, } from './index.js';
|
|
10
|
+
export class CursorAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.name = 'cursor';
|
|
13
|
+
}
|
|
14
|
+
async call({ prompt, complexity, models, signal }) {
|
|
15
|
+
const apiKey = process.env.CURSOR_API_KEY;
|
|
16
|
+
if (!apiKey)
|
|
17
|
+
throw new MissingApiKeyError('cursor', 'CURSOR_API_KEY');
|
|
18
|
+
const model = pickModel(models, complexity);
|
|
19
|
+
let agent;
|
|
20
|
+
try {
|
|
21
|
+
agent = await Agent.create({
|
|
22
|
+
apiKey,
|
|
23
|
+
model: { id: model },
|
|
24
|
+
name: 'DARE DAG Subagent',
|
|
25
|
+
});
|
|
26
|
+
const run = await agent.send(prompt);
|
|
27
|
+
const onAbort = () => {
|
|
28
|
+
// Best-effort cancel; ignore failures.
|
|
29
|
+
run.cancel().catch(() => undefined);
|
|
30
|
+
};
|
|
31
|
+
if (signal.aborted)
|
|
32
|
+
onAbort();
|
|
33
|
+
else
|
|
34
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
35
|
+
const result = await run.wait();
|
|
36
|
+
return { output: result.result ?? '' };
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (err instanceof MissingApiKeyError)
|
|
40
|
+
throw err;
|
|
41
|
+
throw new AdapterCallError('cursor', extractErrorMessage(err), err);
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
try {
|
|
45
|
+
await agent?.close();
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore close failures — task already completed/failed
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function extractErrorMessage(err) {
|
|
54
|
+
if (err instanceof Error)
|
|
55
|
+
return err.message;
|
|
56
|
+
return String(err);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=cursor.js.map
|