@some-useful-agents/core 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.
Files changed (69) hide show
  1. package/dist/agent-executor.d.ts +12 -0
  2. package/dist/agent-executor.d.ts.map +1 -0
  3. package/dist/agent-executor.js +121 -0
  4. package/dist/agent-executor.js.map +1 -0
  5. package/dist/agent-loader.d.ts +19 -0
  6. package/dist/agent-loader.d.ts.map +1 -0
  7. package/dist/agent-loader.js +76 -0
  8. package/dist/agent-loader.js.map +1 -0
  9. package/dist/agent-loader.test.d.ts +2 -0
  10. package/dist/agent-loader.test.d.ts.map +1 -0
  11. package/dist/agent-loader.test.js +82 -0
  12. package/dist/agent-loader.test.js.map +1 -0
  13. package/dist/chain-executor.d.ts +16 -0
  14. package/dist/chain-executor.d.ts.map +1 -0
  15. package/dist/chain-executor.js +54 -0
  16. package/dist/chain-executor.js.map +1 -0
  17. package/dist/chain-resolver.d.ts +27 -0
  18. package/dist/chain-resolver.d.ts.map +1 -0
  19. package/dist/chain-resolver.js +82 -0
  20. package/dist/chain-resolver.js.map +1 -0
  21. package/dist/chain-resolver.test.d.ts +2 -0
  22. package/dist/chain-resolver.test.d.ts.map +1 -0
  23. package/dist/chain-resolver.test.js +86 -0
  24. package/dist/chain-resolver.test.js.map +1 -0
  25. package/dist/env-builder.d.ts +16 -0
  26. package/dist/env-builder.d.ts.map +1 -0
  27. package/dist/env-builder.js +59 -0
  28. package/dist/env-builder.js.map +1 -0
  29. package/dist/env-builder.test.d.ts +2 -0
  30. package/dist/env-builder.test.d.ts.map +1 -0
  31. package/dist/env-builder.test.js +167 -0
  32. package/dist/env-builder.test.js.map +1 -0
  33. package/dist/index.d.ts +11 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +11 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/local-provider.d.ts +24 -0
  38. package/dist/local-provider.d.ts.map +1 -0
  39. package/dist/local-provider.js +101 -0
  40. package/dist/local-provider.js.map +1 -0
  41. package/dist/run-store.d.ts +16 -0
  42. package/dist/run-store.d.ts.map +1 -0
  43. package/dist/run-store.js +115 -0
  44. package/dist/run-store.js.map +1 -0
  45. package/dist/run-store.test.d.ts +2 -0
  46. package/dist/run-store.test.d.ts.map +1 -0
  47. package/dist/run-store.test.js +83 -0
  48. package/dist/run-store.test.js.map +1 -0
  49. package/dist/schema.d.ts +104 -0
  50. package/dist/schema.d.ts.map +1 -0
  51. package/dist/schema.js +35 -0
  52. package/dist/schema.js.map +1 -0
  53. package/dist/schema.test.d.ts +2 -0
  54. package/dist/schema.test.d.ts.map +1 -0
  55. package/dist/schema.test.js +108 -0
  56. package/dist/schema.test.js.map +1 -0
  57. package/dist/secrets-store.d.ts +34 -0
  58. package/dist/secrets-store.d.ts.map +1 -0
  59. package/dist/secrets-store.js +116 -0
  60. package/dist/secrets-store.js.map +1 -0
  61. package/dist/secrets-store.test.d.ts +2 -0
  62. package/dist/secrets-store.test.d.ts.map +1 -0
  63. package/dist/secrets-store.test.js +99 -0
  64. package/dist/secrets-store.test.js.map +1 -0
  65. package/dist/types.d.ts +52 -0
  66. package/dist/types.d.ts.map +1 -0
  67. package/dist/types.js +2 -0
  68. package/dist/types.js.map +1 -0
  69. package/package.json +30 -0
@@ -0,0 +1,12 @@
1
+ import type { AgentDefinition } from './types.js';
2
+ export interface ExecutionResult {
3
+ result: string;
4
+ exitCode: number;
5
+ error?: string;
6
+ }
7
+ export interface ExecutionHandle {
8
+ promise: Promise<ExecutionResult>;
9
+ kill: () => void;
10
+ }
11
+ export declare function executeAgent(agent: AgentDefinition, env?: Record<string, string>): ExecutionHandle;
12
+ //# sourceMappingURL=agent-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-executor.d.ts","sourceRoot":"","sources":["../src/agent-executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,eAAe,CAKlG"}
@@ -0,0 +1,121 @@
1
+ import { spawn } from 'node:child_process';
2
+ export function executeAgent(agent, env) {
3
+ if (agent.type === 'shell') {
4
+ return executeShellAgent(agent, env);
5
+ }
6
+ return executeClaudeCodeAgent(agent, env);
7
+ }
8
+ function executeShellAgent(agent, prebuiltEnv) {
9
+ if (!agent.command) {
10
+ throw new Error(`Shell agent "${agent.name}" has no command`);
11
+ }
12
+ let child;
13
+ let killed = false;
14
+ let timer;
15
+ const promise = new Promise((resolve) => {
16
+ const env = prebuiltEnv ?? { ...process.env, ...(agent.env ?? {}) };
17
+ child = spawn('bash', ['-c', agent.command], {
18
+ cwd: agent.workingDirectory ?? process.cwd(),
19
+ env,
20
+ stdio: ['ignore', 'pipe', 'pipe'],
21
+ });
22
+ let stdout = '';
23
+ let stderr = '';
24
+ child.stdout.on('data', (data) => { stdout += data.toString(); });
25
+ child.stderr.on('data', (data) => { stderr += data.toString(); });
26
+ const timeoutMs = (agent.timeout ?? 300) * 1000;
27
+ timer = setTimeout(() => {
28
+ killed = true;
29
+ child.kill('SIGTERM');
30
+ setTimeout(() => { if (!child.killed)
31
+ child.kill('SIGKILL'); }, 5000);
32
+ }, timeoutMs);
33
+ child.on('close', (code) => {
34
+ if (timer)
35
+ clearTimeout(timer);
36
+ if (killed) {
37
+ resolve({ result: stdout, exitCode: 124, error: `Agent timed out after ${agent.timeout ?? 300}s` });
38
+ }
39
+ else {
40
+ resolve({
41
+ result: stdout,
42
+ exitCode: code ?? 1,
43
+ error: code !== 0 ? stderr || `Process exited with code ${code}` : undefined,
44
+ });
45
+ }
46
+ });
47
+ child.on('error', (err) => {
48
+ if (timer)
49
+ clearTimeout(timer);
50
+ resolve({ result: '', exitCode: 127, error: err.message });
51
+ });
52
+ });
53
+ return {
54
+ promise,
55
+ kill: () => { killed = true; child?.kill('SIGTERM'); },
56
+ };
57
+ }
58
+ function executeClaudeCodeAgent(agent, prebuiltEnv) {
59
+ if (!agent.prompt) {
60
+ throw new Error(`Claude-code agent "${agent.name}" has no prompt`);
61
+ }
62
+ let child;
63
+ let killed = false;
64
+ let timer;
65
+ const promise = new Promise((resolve) => {
66
+ const args = ['--print', agent.prompt];
67
+ if (agent.model) {
68
+ args.push('--model', agent.model);
69
+ }
70
+ if (agent.maxTurns) {
71
+ args.push('--max-turns', String(agent.maxTurns));
72
+ }
73
+ if (agent.allowedTools?.length) {
74
+ args.push('--allowedTools', agent.allowedTools.join(','));
75
+ }
76
+ const env = prebuiltEnv ?? { ...process.env, ...(agent.env ?? {}) };
77
+ child = spawn('claude', args, {
78
+ cwd: agent.workingDirectory ?? process.cwd(),
79
+ env,
80
+ stdio: ['ignore', 'pipe', 'pipe'],
81
+ });
82
+ let stdout = '';
83
+ let stderr = '';
84
+ child.stdout.on('data', (data) => { stdout += data.toString(); });
85
+ child.stderr.on('data', (data) => { stderr += data.toString(); });
86
+ const timeoutMs = (agent.timeout ?? 300) * 1000;
87
+ timer = setTimeout(() => {
88
+ killed = true;
89
+ child.kill('SIGTERM');
90
+ }, timeoutMs);
91
+ child.on('close', (code) => {
92
+ if (timer)
93
+ clearTimeout(timer);
94
+ if (killed) {
95
+ resolve({ result: stdout, exitCode: 124, error: `Agent timed out after ${agent.timeout ?? 300}s` });
96
+ }
97
+ else {
98
+ resolve({
99
+ result: stdout,
100
+ exitCode: code ?? 1,
101
+ error: code !== 0 ? stderr || `Claude exited with code ${code}` : undefined,
102
+ });
103
+ }
104
+ });
105
+ child.on('error', (err) => {
106
+ if (timer)
107
+ clearTimeout(timer);
108
+ if (err.message.includes('ENOENT')) {
109
+ resolve({ result: '', exitCode: 127, error: 'Claude Code CLI not found. Install it: https://docs.anthropic.com/en/docs/claude-code' });
110
+ }
111
+ else {
112
+ resolve({ result: '', exitCode: 127, error: err.message });
113
+ }
114
+ });
115
+ });
116
+ return {
117
+ promise,
118
+ kill: () => { killed = true; child?.kill('SIGTERM'); },
119
+ };
120
+ }
121
+ //# sourceMappingURL=agent-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-executor.js","sourceRoot":"","sources":["../src/agent-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { AgentDefinition } from './types.js';
2
+ export type AgentSource = 'examples' | 'local' | 'community';
3
+ export interface AgentDirConfig {
4
+ path: string;
5
+ source: AgentSource;
6
+ }
7
+ export interface LoadAgentsOptions {
8
+ directories: (string | AgentDirConfig)[];
9
+ onWarning?: (file: string, message: string) => void;
10
+ }
11
+ export interface LoadAgentsResult {
12
+ agents: Map<string, AgentDefinition>;
13
+ warnings: Array<{
14
+ file: string;
15
+ message: string;
16
+ }>;
17
+ }
18
+ export declare function loadAgents(options: LoadAgentsOptions): LoadAgentsResult;
19
+ //# sourceMappingURL=agent-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loader.d.ts","sourceRoot":"","sources":["../src/agent-loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,CAAC,MAAM,GAAG,cAAc,CAAC,EAAE,CAAC;IACzC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACrC,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAuEvE"}
@@ -0,0 +1,76 @@
1
+ import { readFileSync, readdirSync, existsSync } from 'node:fs';
2
+ import { join, extname } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import { agentDefinitionSchema } from './schema.js';
5
+ export function loadAgents(options) {
6
+ const agents = new Map();
7
+ const warnings = [];
8
+ const warn = (file, message) => {
9
+ warnings.push({ file, message });
10
+ options.onWarning?.(file, message);
11
+ };
12
+ for (const dirEntry of options.directories) {
13
+ const dir = typeof dirEntry === 'string' ? dirEntry : dirEntry.path;
14
+ const source = typeof dirEntry === 'string' ? inferSource(dir) : dirEntry.source;
15
+ if (!existsSync(dir)) {
16
+ warn(dir, `Directory does not exist: ${dir}`);
17
+ continue;
18
+ }
19
+ let entries;
20
+ try {
21
+ entries = readdirSync(dir);
22
+ }
23
+ catch (err) {
24
+ warn(dir, `Cannot read directory: ${err.message}`);
25
+ continue;
26
+ }
27
+ for (const entry of entries) {
28
+ const ext = extname(entry).toLowerCase();
29
+ if (ext !== '.yaml' && ext !== '.yml')
30
+ continue;
31
+ const filePath = join(dir, entry);
32
+ let raw;
33
+ try {
34
+ raw = readFileSync(filePath, 'utf-8');
35
+ }
36
+ catch (err) {
37
+ warn(filePath, `Cannot read file: ${err.message}`);
38
+ continue;
39
+ }
40
+ if (!raw.trim()) {
41
+ warn(filePath, 'Empty file');
42
+ continue;
43
+ }
44
+ let parsed;
45
+ try {
46
+ parsed = parseYaml(raw);
47
+ }
48
+ catch (err) {
49
+ warn(filePath, `Invalid YAML: ${err.message}`);
50
+ continue;
51
+ }
52
+ const result = agentDefinitionSchema.safeParse(parsed);
53
+ if (!result.success) {
54
+ const issues = result.error.issues.map(i => `${i.path.join('.')}: ${i.message}`).join(', ');
55
+ warn(filePath, `Validation failed: ${issues}`);
56
+ continue;
57
+ }
58
+ const agent = result.data;
59
+ agent.source = source;
60
+ if (agents.has(agent.name)) {
61
+ warn(filePath, `Duplicate agent name "${agent.name}" (overwriting previous)`);
62
+ }
63
+ agents.set(agent.name, agent);
64
+ }
65
+ }
66
+ return { agents, warnings };
67
+ }
68
+ function inferSource(dirPath) {
69
+ const normalized = dirPath.replace(/\\/g, '/');
70
+ if (normalized.includes('/community'))
71
+ return 'community';
72
+ if (normalized.includes('/examples'))
73
+ return 'examples';
74
+ return 'local';
75
+ }
76
+ //# sourceMappingURL=agent-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loader.js","sourceRoot":"","sources":["../src/agent-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-loader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loader.test.d.ts","sourceRoot":"","sources":["../src/agent-loader.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,82 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { mkdirSync, writeFileSync, rmSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { loadAgents } from './agent-loader.js';
5
+ const TEST_DIR = join(import.meta.dirname, '__test-agents__');
6
+ function writeAgent(dir, filename, content) {
7
+ mkdirSync(dir, { recursive: true });
8
+ writeFileSync(join(dir, filename), content);
9
+ }
10
+ beforeEach(() => {
11
+ mkdirSync(TEST_DIR, { recursive: true });
12
+ });
13
+ afterEach(() => {
14
+ rmSync(TEST_DIR, { recursive: true, force: true });
15
+ });
16
+ describe('loadAgents', () => {
17
+ it('loads valid agents from directory', () => {
18
+ writeAgent(TEST_DIR, 'test.yaml', 'name: test\ntype: shell\ncommand: "echo hi"\n');
19
+ const { agents, warnings } = loadAgents({ directories: [TEST_DIR] });
20
+ expect(agents.size).toBe(1);
21
+ expect(agents.get('test')?.command).toBe('echo hi');
22
+ expect(warnings.length).toBe(0);
23
+ });
24
+ it('warns when directory does not exist', () => {
25
+ const { agents, warnings } = loadAgents({ directories: ['/nonexistent'] });
26
+ expect(agents.size).toBe(0);
27
+ expect(warnings.length).toBe(1);
28
+ expect(warnings[0].message).toContain('does not exist');
29
+ });
30
+ it('handles empty directory', () => {
31
+ const { agents, warnings } = loadAgents({ directories: [TEST_DIR] });
32
+ expect(agents.size).toBe(0);
33
+ expect(warnings.length).toBe(0);
34
+ });
35
+ it('skips invalid YAML and loads valid ones', () => {
36
+ writeAgent(TEST_DIR, 'good.yaml', 'name: good\ntype: shell\ncommand: "echo"\n');
37
+ writeAgent(TEST_DIR, 'bad.yaml', 'name: bad\ntype: shell\n'); // missing command
38
+ const { agents, warnings } = loadAgents({ directories: [TEST_DIR] });
39
+ expect(agents.size).toBe(1);
40
+ expect(agents.has('good')).toBe(true);
41
+ expect(warnings.length).toBe(1);
42
+ });
43
+ it('warns on duplicate agent names', () => {
44
+ const dir2 = join(TEST_DIR, 'dir2');
45
+ writeAgent(TEST_DIR, 'a.yaml', 'name: dup\ntype: shell\ncommand: "echo 1"\n');
46
+ writeAgent(dir2, 'b.yaml', 'name: dup\ntype: shell\ncommand: "echo 2"\n');
47
+ const { agents, warnings } = loadAgents({ directories: [TEST_DIR, dir2] });
48
+ expect(agents.size).toBe(1);
49
+ expect(warnings.some(w => w.message.includes('Duplicate'))).toBe(true);
50
+ });
51
+ it('skips non-YAML files', () => {
52
+ writeAgent(TEST_DIR, 'README.md', '# Not an agent');
53
+ writeAgent(TEST_DIR, '.gitkeep', '');
54
+ writeAgent(TEST_DIR, 'test.yaml', 'name: test\ntype: shell\ncommand: "echo"\n');
55
+ const { agents } = loadAgents({ directories: [TEST_DIR] });
56
+ expect(agents.size).toBe(1);
57
+ });
58
+ it('warns on empty YAML files', () => {
59
+ writeAgent(TEST_DIR, 'empty.yaml', '');
60
+ const { warnings } = loadAgents({ directories: [TEST_DIR] });
61
+ expect(warnings.length).toBe(1);
62
+ expect(warnings[0].message).toContain('Empty');
63
+ });
64
+ it('warns on malformed YAML', () => {
65
+ writeAgent(TEST_DIR, 'bad.yaml', '{{{{not yaml');
66
+ const { warnings } = loadAgents({ directories: [TEST_DIR] });
67
+ expect(warnings.length).toBe(1);
68
+ expect(warnings[0].message).toContain('Invalid YAML');
69
+ });
70
+ it('loads .yml files too', () => {
71
+ writeAgent(TEST_DIR, 'test.yml', 'name: test\ntype: shell\ncommand: "echo"\n');
72
+ const { agents } = loadAgents({ directories: [TEST_DIR] });
73
+ expect(agents.size).toBe(1);
74
+ });
75
+ it('calls onWarning callback', () => {
76
+ writeAgent(TEST_DIR, 'bad.yaml', 'name: bad\ntype: shell\n');
77
+ const warned = [];
78
+ loadAgents({ directories: [TEST_DIR], onWarning: (f, m) => warned.push(m) });
79
+ expect(warned.length).toBe(1);
80
+ });
81
+ });
82
+ //# sourceMappingURL=agent-loader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loader.test.js","sourceRoot":"","sources":["../src/agent-loader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { AgentDefinition, Run } from './types.js';
2
+ import type { Provider } from './types.js';
3
+ export interface ChainResult {
4
+ runs: Run[];
5
+ outputs: Map<string, {
6
+ result: string;
7
+ exitCode: number;
8
+ }>;
9
+ skipped: string[];
10
+ }
11
+ /**
12
+ * Execute a chain of agents in dependency order.
13
+ * Stops on first failure, marks downstream agents as skipped.
14
+ */
15
+ export declare function executeChain(agents: Map<string, AgentDefinition>, provider: Provider, triggeredBy: Run['triggeredBy'], pollInterval?: number): Promise<ChainResult>;
16
+ //# sourceMappingURL=chain-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-executor.d.ts","sourceRoot":"","sources":["../src/chain-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACpC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC,EAC/B,YAAY,SAAM,GACjB,OAAO,CAAC,WAAW,CAAC,CAmDtB"}
@@ -0,0 +1,54 @@
1
+ import { resolveExecutionOrder, resolveTemplate } from './chain-resolver.js';
2
+ /**
3
+ * Execute a chain of agents in dependency order.
4
+ * Stops on first failure, marks downstream agents as skipped.
5
+ */
6
+ export async function executeChain(agents, provider, triggeredBy, pollInterval = 250) {
7
+ const order = resolveExecutionOrder(agents);
8
+ const outputs = new Map();
9
+ const runs = [];
10
+ const skipped = [];
11
+ let failed = false;
12
+ for (const agent of order) {
13
+ if (failed) {
14
+ skipped.push(agent.name);
15
+ continue;
16
+ }
17
+ // Resolve input template if present
18
+ let resolvedAgent = agent;
19
+ if (agent.input) {
20
+ const resolvedInput = resolveTemplate(agent.input, outputs);
21
+ // For claude-code agents, append to prompt. For shell agents, set as env var.
22
+ if (agent.type === 'claude-code' && agent.prompt) {
23
+ resolvedAgent = { ...agent, prompt: `${agent.prompt}\n\nInput: ${resolvedInput}` };
24
+ }
25
+ else if (agent.type === 'shell') {
26
+ resolvedAgent = {
27
+ ...agent,
28
+ env: { ...(agent.env ?? {}), SUA_CHAIN_INPUT: resolvedInput },
29
+ };
30
+ }
31
+ }
32
+ const run = await provider.submitRun({ agent: resolvedAgent, triggeredBy });
33
+ // Poll for completion
34
+ let current = run;
35
+ while (current.status === 'running' || current.status === 'pending') {
36
+ await new Promise(r => setTimeout(r, pollInterval));
37
+ const updated = await provider.getRun(run.id);
38
+ if (updated)
39
+ current = updated;
40
+ }
41
+ runs.push(current);
42
+ if (current.status === 'completed') {
43
+ outputs.set(agent.name, {
44
+ result: current.result ?? '',
45
+ exitCode: current.exitCode ?? 0,
46
+ });
47
+ }
48
+ else {
49
+ failed = true;
50
+ }
51
+ }
52
+ return { runs, outputs, skipped };
53
+ }
54
+ //# sourceMappingURL=chain-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-executor.js","sourceRoot":"","sources":["../src/chain-executor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAQ7E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAoC,EACpC,QAAkB,EAClB,WAA+B,EAC/B,YAAY,GAAG,GAAG;IAElB,MAAM,KAAK,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAgD,CAAC;IACxE,MAAM,IAAI,GAAU,EAAE,CAAC;IACvB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QAED,oCAAoC;QACpC,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC5D,8EAA8E;YAC9E,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjD,aAAa,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,cAAc,aAAa,EAAE,EAAE,CAAC;YACrF,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAClC,aAAa,GAAG;oBACd,GAAG,KAAK;oBACR,GAAG,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE;iBAC9D,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC;QAE5E,sBAAsB;QACtB,IAAI,OAAO,GAAG,GAAG,CAAC;QAClB,OAAO,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;YACpD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9C,IAAI,OAAO;gBAAE,OAAO,GAAG,OAAO,CAAC;QACjC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEnB,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;gBACtB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;gBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC;aAChC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { AgentDefinition } from './types.js';
2
+ export declare class CycleError extends Error {
3
+ readonly cycle: string[];
4
+ constructor(cycle: string[]);
5
+ }
6
+ export declare class MissingDependencyError extends Error {
7
+ readonly agent: string;
8
+ readonly missing: string;
9
+ constructor(agent: string, missing: string);
10
+ }
11
+ /**
12
+ * Topological sort of agents based on dependsOn fields.
13
+ * Returns agents in execution order (dependencies first).
14
+ * Throws CycleError if circular dependencies exist.
15
+ * Throws MissingDependencyError if a dependency doesn't exist.
16
+ */
17
+ export declare function resolveExecutionOrder(agents: Map<string, AgentDefinition>): AgentDefinition[];
18
+ /**
19
+ * Resolve template strings like {{outputs.agent-name.result}}
20
+ * against a map of completed agent outputs.
21
+ */
22
+ export declare function resolveTemplate(template: string, outputs: Map<string, {
23
+ result: string;
24
+ exitCode: number;
25
+ }>): string;
26
+ export declare function validateChainDepth(agents: Map<string, AgentDefinition>): void;
27
+ //# sourceMappingURL=chain-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-resolver.d.ts","sourceRoot":"","sources":["../src/chain-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,qBAAa,UAAW,SAAQ,KAAK;aACP,KAAK,EAAE,MAAM,EAAE;gBAAf,KAAK,EAAE,MAAM,EAAE;CAI5C;AAED,qBAAa,sBAAuB,SAAQ,KAAK;aACnB,KAAK,EAAE,MAAM;aAAkB,OAAO,EAAE,MAAM;gBAA9C,KAAK,EAAE,MAAM,EAAkB,OAAO,EAAE,MAAM;CAI3E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,eAAe,EAAE,CAuC7F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,GACzD,MAAM,CAQR;AAID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,IAAI,CAK7E"}
@@ -0,0 +1,82 @@
1
+ export class CycleError extends Error {
2
+ cycle;
3
+ constructor(cycle) {
4
+ super(`Circular dependency detected: ${cycle.join(' -> ')}`);
5
+ this.cycle = cycle;
6
+ this.name = 'CycleError';
7
+ }
8
+ }
9
+ export class MissingDependencyError extends Error {
10
+ agent;
11
+ missing;
12
+ constructor(agent, missing) {
13
+ super(`Agent "${agent}" depends on "${missing}" which does not exist`);
14
+ this.agent = agent;
15
+ this.missing = missing;
16
+ this.name = 'MissingDependencyError';
17
+ }
18
+ }
19
+ /**
20
+ * Topological sort of agents based on dependsOn fields.
21
+ * Returns agents in execution order (dependencies first).
22
+ * Throws CycleError if circular dependencies exist.
23
+ * Throws MissingDependencyError if a dependency doesn't exist.
24
+ */
25
+ export function resolveExecutionOrder(agents) {
26
+ // Validate all dependencies exist
27
+ for (const [name, agent] of agents) {
28
+ for (const dep of agent.dependsOn ?? []) {
29
+ if (!agents.has(dep)) {
30
+ throw new MissingDependencyError(name, dep);
31
+ }
32
+ }
33
+ }
34
+ const sorted = [];
35
+ const visited = new Set();
36
+ const visiting = new Set();
37
+ function visit(name, path) {
38
+ if (visited.has(name))
39
+ return;
40
+ if (visiting.has(name)) {
41
+ const cycleStart = path.indexOf(name);
42
+ throw new CycleError([...path.slice(cycleStart), name]);
43
+ }
44
+ visiting.add(name);
45
+ path.push(name);
46
+ const agent = agents.get(name);
47
+ for (const dep of agent.dependsOn ?? []) {
48
+ visit(dep, [...path]);
49
+ }
50
+ visiting.delete(name);
51
+ visited.add(name);
52
+ sorted.push(agent);
53
+ }
54
+ for (const name of agents.keys()) {
55
+ visit(name, []);
56
+ }
57
+ return sorted;
58
+ }
59
+ /**
60
+ * Resolve template strings like {{outputs.agent-name.result}}
61
+ * against a map of completed agent outputs.
62
+ */
63
+ export function resolveTemplate(template, outputs) {
64
+ return template.replace(/\{\{outputs\.([a-z0-9-]+)\.(result|exitCode)\}\}/g, (_, agentName, field) => {
65
+ const output = outputs.get(agentName);
66
+ if (!output)
67
+ return '';
68
+ if (field === 'result')
69
+ return output.result;
70
+ if (field === 'exitCode')
71
+ return String(output.exitCode);
72
+ return '';
73
+ });
74
+ }
75
+ const MAX_CHAIN_DEPTH = 20;
76
+ export function validateChainDepth(agents) {
77
+ const order = resolveExecutionOrder(agents);
78
+ if (order.length > MAX_CHAIN_DEPTH) {
79
+ throw new Error(`Chain exceeds maximum depth of ${MAX_CHAIN_DEPTH} agents (has ${order.length})`);
80
+ }
81
+ }
82
+ //# sourceMappingURL=chain-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-resolver.js","sourceRoot":"","sources":["../src/chain-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chain-resolver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-resolver.test.d.ts","sourceRoot":"","sources":["../src/chain-resolver.test.ts"],"names":[],"mappings":""}