vralphy 0.0.1
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/bin/vralphy.js +3 -0
- package/dist/commands/build.d.ts +9 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +85 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +34 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/plan.d.ts +9 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +85 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/spec.d.ts +9 -0
- package/dist/commands/spec.d.ts.map +1 -0
- package/dist/commands/spec.js +109 -0
- package/dist/commands/spec.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +114 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/agents.d.ts +32 -0
- package/dist/lib/agents.d.ts.map +1 -0
- package/dist/lib/agents.js +94 -0
- package/dist/lib/agents.js.map +1 -0
- package/dist/lib/config.d.ts +38 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +96 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/config.test.d.ts +2 -0
- package/dist/lib/config.test.d.ts.map +1 -0
- package/dist/lib/config.test.js +45 -0
- package/dist/lib/config.test.js.map +1 -0
- package/dist/lib/engines/base.d.ts +57 -0
- package/dist/lib/engines/base.d.ts.map +1 -0
- package/dist/lib/engines/base.js +18 -0
- package/dist/lib/engines/base.js.map +1 -0
- package/dist/lib/engines/base.test.d.ts +2 -0
- package/dist/lib/engines/base.test.d.ts.map +1 -0
- package/dist/lib/engines/base.test.js +28 -0
- package/dist/lib/engines/base.test.js.map +1 -0
- package/dist/lib/engines/claude.d.ts +11 -0
- package/dist/lib/engines/claude.d.ts.map +1 -0
- package/dist/lib/engines/claude.js +124 -0
- package/dist/lib/engines/claude.js.map +1 -0
- package/dist/lib/engines/index.d.ts +18 -0
- package/dist/lib/engines/index.d.ts.map +1 -0
- package/dist/lib/engines/index.js +37 -0
- package/dist/lib/engines/index.js.map +1 -0
- package/dist/lib/engines/opencode.d.ts +10 -0
- package/dist/lib/engines/opencode.d.ts.map +1 -0
- package/dist/lib/engines/opencode.js +71 -0
- package/dist/lib/engines/opencode.js.map +1 -0
- package/dist/lib/init.d.ts +8 -0
- package/dist/lib/init.d.ts.map +1 -0
- package/dist/lib/init.js +254 -0
- package/dist/lib/init.js.map +1 -0
- package/dist/lib/prompts.d.ts +34 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +130 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/skills.d.ts +32 -0
- package/dist/lib/skills.d.ts.map +1 -0
- package/dist/lib/skills.js +119 -0
- package/dist/lib/skills.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { readFile, readdir } from 'fs/promises';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { join, basename } from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Parse frontmatter from markdown file
|
|
6
|
+
*/
|
|
7
|
+
function parseFrontmatter(content) {
|
|
8
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
9
|
+
if (!frontmatterMatch) {
|
|
10
|
+
return { metadata: {}, content };
|
|
11
|
+
}
|
|
12
|
+
const [, frontmatter, body] = frontmatterMatch;
|
|
13
|
+
const metadata = {};
|
|
14
|
+
for (const line of frontmatter.split('\n')) {
|
|
15
|
+
const match = line.match(/^(\w+):\s*(.*)$/);
|
|
16
|
+
if (match) {
|
|
17
|
+
const [, key, value] = match;
|
|
18
|
+
metadata[key] = value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return { metadata, content: body };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load a single agent from file
|
|
25
|
+
*/
|
|
26
|
+
async function loadAgent(path) {
|
|
27
|
+
const content = await readFile(path, 'utf-8');
|
|
28
|
+
const { metadata, content: body } = parseFrontmatter(content);
|
|
29
|
+
const name = metadata.name ?? basename(path, '.md');
|
|
30
|
+
return {
|
|
31
|
+
name,
|
|
32
|
+
path,
|
|
33
|
+
metadata: {
|
|
34
|
+
name,
|
|
35
|
+
description: metadata.description,
|
|
36
|
+
model: metadata.model,
|
|
37
|
+
},
|
|
38
|
+
content: body,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load all agents from a directory
|
|
43
|
+
*/
|
|
44
|
+
export async function loadAgents(dir) {
|
|
45
|
+
if (!existsSync(dir)) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
const files = await readdir(dir);
|
|
49
|
+
const mdFiles = files.filter((f) => f.endsWith('.md'));
|
|
50
|
+
const agents = [];
|
|
51
|
+
for (const file of mdFiles) {
|
|
52
|
+
try {
|
|
53
|
+
const agent = await loadAgent(join(dir, file));
|
|
54
|
+
agents.push(agent);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
console.error(`Failed to load agent ${file}:`, e);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return agents;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Format agents for prompt injection
|
|
64
|
+
*/
|
|
65
|
+
export function formatAgentsForPrompt(agents, defaultModel) {
|
|
66
|
+
if (agents.length === 0)
|
|
67
|
+
return '';
|
|
68
|
+
let result = '## Available Specialized Agents\n\n';
|
|
69
|
+
result += 'You may spawn these agents using subagents when their expertise is needed:\n\n';
|
|
70
|
+
for (const agent of agents) {
|
|
71
|
+
const model = agent.metadata.model ?? defaultModel;
|
|
72
|
+
result += `- **${agent.name}**: ${agent.metadata.description ?? 'No description'} (use ${model})\n`;
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* List available agents (for CLI command)
|
|
78
|
+
*/
|
|
79
|
+
export async function listAgents(dir) {
|
|
80
|
+
const agents = await loadAgents(dir);
|
|
81
|
+
return agents.map((a) => ({
|
|
82
|
+
name: a.name,
|
|
83
|
+
description: a.metadata.description,
|
|
84
|
+
model: a.metadata.model,
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get agent by name
|
|
89
|
+
*/
|
|
90
|
+
export async function getAgent(dir, name) {
|
|
91
|
+
const agents = await loadAgents(dir);
|
|
92
|
+
return agents.find((a) => a.name === name);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/lib/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { EngineName } from './engines/index.js';
|
|
2
|
+
export interface VralphyConfig {
|
|
3
|
+
engine: EngineName;
|
|
4
|
+
model: string;
|
|
5
|
+
executor: string;
|
|
6
|
+
skillsDir: string;
|
|
7
|
+
agentsDir: string;
|
|
8
|
+
verbose: boolean;
|
|
9
|
+
dryRun: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ConfigOptions {
|
|
12
|
+
engine?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
executor?: string;
|
|
15
|
+
skills?: string;
|
|
16
|
+
agents?: string;
|
|
17
|
+
config?: string;
|
|
18
|
+
verbose?: boolean;
|
|
19
|
+
dryRun?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve configuration from multiple sources
|
|
23
|
+
* Priority: CLI flags > env vars > config file > defaults
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveConfig(cliOptions: ConfigOptions): Promise<VralphyConfig>;
|
|
26
|
+
/**
|
|
27
|
+
* Determine skills directory based on engine
|
|
28
|
+
*/
|
|
29
|
+
export declare function getSkillsDir(engine: EngineName, customPath?: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Determine agents directory based on engine
|
|
32
|
+
*/
|
|
33
|
+
export declare function getAgentsDir(engine: EngineName, customPath?: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Find project root by looking for common markers
|
|
36
|
+
*/
|
|
37
|
+
export declare function findProjectRoot(startDir?: string): string;
|
|
38
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA4BD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,UAAU,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAerF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAc5E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAc5E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAgBxE"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
const DEFAULT_CONFIG = {
|
|
5
|
+
engine: 'claude',
|
|
6
|
+
model: 'opus',
|
|
7
|
+
executor: 'sonnet',
|
|
8
|
+
skillsDir: '.claude/skills',
|
|
9
|
+
agentsDir: 'agents',
|
|
10
|
+
verbose: false,
|
|
11
|
+
dryRun: false,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Load config from file if it exists
|
|
15
|
+
*/
|
|
16
|
+
async function loadConfigFile(path) {
|
|
17
|
+
if (!existsSync(path)) {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const content = await readFile(path, 'utf-8');
|
|
22
|
+
return JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve configuration from multiple sources
|
|
30
|
+
* Priority: CLI flags > env vars > config file > defaults
|
|
31
|
+
*/
|
|
32
|
+
export async function resolveConfig(cliOptions) {
|
|
33
|
+
const configPath = cliOptions.config ?? 'vralphy.config.json';
|
|
34
|
+
const fileConfig = await loadConfigFile(configPath);
|
|
35
|
+
const config = {
|
|
36
|
+
engine: (cliOptions.engine ?? process.env.VRALPHY_ENGINE ?? fileConfig.engine ?? DEFAULT_CONFIG.engine),
|
|
37
|
+
model: cliOptions.model ?? process.env.VRALPHY_MODEL ?? fileConfig.model ?? DEFAULT_CONFIG.model,
|
|
38
|
+
executor: cliOptions.executor ?? process.env.VRALPHY_EXECUTOR ?? fileConfig.executor ?? DEFAULT_CONFIG.executor,
|
|
39
|
+
skillsDir: cliOptions.skills ?? fileConfig.skillsDir ?? DEFAULT_CONFIG.skillsDir,
|
|
40
|
+
agentsDir: cliOptions.agents ?? fileConfig.agentsDir ?? DEFAULT_CONFIG.agentsDir,
|
|
41
|
+
verbose: cliOptions.verbose ?? fileConfig.verbose ?? DEFAULT_CONFIG.verbose,
|
|
42
|
+
dryRun: cliOptions.dryRun ?? fileConfig.dryRun ?? DEFAULT_CONFIG.dryRun,
|
|
43
|
+
};
|
|
44
|
+
return config;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Determine skills directory based on engine
|
|
48
|
+
*/
|
|
49
|
+
export function getSkillsDir(engine, customPath) {
|
|
50
|
+
if (customPath)
|
|
51
|
+
return customPath;
|
|
52
|
+
const engineDirs = {
|
|
53
|
+
claude: '.claude/skills',
|
|
54
|
+
opencode: '.opencode/skills',
|
|
55
|
+
};
|
|
56
|
+
const engineDir = engineDirs[engine];
|
|
57
|
+
if (existsSync(engineDir))
|
|
58
|
+
return engineDir;
|
|
59
|
+
if (existsSync('skills'))
|
|
60
|
+
return 'skills';
|
|
61
|
+
return engineDir;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Determine agents directory based on engine
|
|
65
|
+
*/
|
|
66
|
+
export function getAgentsDir(engine, customPath) {
|
|
67
|
+
if (customPath)
|
|
68
|
+
return customPath;
|
|
69
|
+
const engineDirs = {
|
|
70
|
+
claude: '.claude/agents',
|
|
71
|
+
opencode: '.opencode/agents',
|
|
72
|
+
};
|
|
73
|
+
const engineDir = engineDirs[engine];
|
|
74
|
+
if (existsSync(engineDir))
|
|
75
|
+
return engineDir;
|
|
76
|
+
if (existsSync('agents'))
|
|
77
|
+
return 'agents';
|
|
78
|
+
return engineDir;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Find project root by looking for common markers
|
|
82
|
+
*/
|
|
83
|
+
export function findProjectRoot(startDir = process.cwd()) {
|
|
84
|
+
let dir = startDir;
|
|
85
|
+
while (dir !== '/') {
|
|
86
|
+
const markers = ['package.json', 'Cargo.toml', 'go.mod', '.git', 'AGENTS.md'];
|
|
87
|
+
for (const marker of markers) {
|
|
88
|
+
if (existsSync(join(dir, marker))) {
|
|
89
|
+
return dir;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
dir = join(dir, '..');
|
|
93
|
+
}
|
|
94
|
+
return startDir;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../src/lib/config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { resolveConfig, getSkillsDir, getAgentsDir } from './config.js';
|
|
3
|
+
describe('resolveConfig', () => {
|
|
4
|
+
it('returns default config when no options provided', async () => {
|
|
5
|
+
const config = await resolveConfig({});
|
|
6
|
+
expect(config.engine).toBe('claude');
|
|
7
|
+
expect(config.model).toBe('opus');
|
|
8
|
+
expect(config.executor).toBe('sonnet');
|
|
9
|
+
expect(config.verbose).toBe(false);
|
|
10
|
+
expect(config.dryRun).toBe(false);
|
|
11
|
+
});
|
|
12
|
+
it('respects CLI options over defaults', async () => {
|
|
13
|
+
const config = await resolveConfig({
|
|
14
|
+
engine: 'opencode',
|
|
15
|
+
model: 'haiku',
|
|
16
|
+
verbose: true,
|
|
17
|
+
});
|
|
18
|
+
expect(config.engine).toBe('opencode');
|
|
19
|
+
expect(config.model).toBe('haiku');
|
|
20
|
+
expect(config.verbose).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('getSkillsDir', () => {
|
|
24
|
+
it('returns custom path if provided', () => {
|
|
25
|
+
expect(getSkillsDir('claude', 'custom/skills')).toBe('custom/skills');
|
|
26
|
+
});
|
|
27
|
+
it('returns engine-specific default for claude', () => {
|
|
28
|
+
expect(getSkillsDir('claude')).toBe('.claude/skills');
|
|
29
|
+
});
|
|
30
|
+
it('returns engine-specific default for opencode', () => {
|
|
31
|
+
expect(getSkillsDir('opencode')).toBe('.opencode/skills');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('getAgentsDir', () => {
|
|
35
|
+
it('returns custom path if provided', () => {
|
|
36
|
+
expect(getAgentsDir('claude', 'custom/agents')).toBe('custom/agents');
|
|
37
|
+
});
|
|
38
|
+
it('returns engine-specific default for claude', () => {
|
|
39
|
+
expect(getAgentsDir('claude')).toBe('.claude/agents');
|
|
40
|
+
});
|
|
41
|
+
it('returns engine-specific default for opencode', () => {
|
|
42
|
+
expect(getAgentsDir('opencode')).toBe('.opencode/agents');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/lib/config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAExE,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;QAEvC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;YACjC,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base engine interface that all engines must implement
|
|
3
|
+
*/
|
|
4
|
+
export interface ExecuteOptions {
|
|
5
|
+
model: string;
|
|
6
|
+
executor: string;
|
|
7
|
+
headless: boolean;
|
|
8
|
+
skipPermissions: boolean;
|
|
9
|
+
outputFormat: 'stream-json' | 'text';
|
|
10
|
+
verbose: boolean;
|
|
11
|
+
skills?: string[];
|
|
12
|
+
agents?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface Chunk {
|
|
15
|
+
type: 'text' | 'tool_use' | 'error' | 'done';
|
|
16
|
+
content?: string;
|
|
17
|
+
tool?: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface EngineFlags {
|
|
21
|
+
model?: string;
|
|
22
|
+
skipPermissions?: boolean;
|
|
23
|
+
outputFormat?: 'stream-json' | 'text';
|
|
24
|
+
verbose?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface Engine {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
/**
|
|
29
|
+
* Execute prompt with streaming output
|
|
30
|
+
*/
|
|
31
|
+
execute(prompt: string, options: ExecuteOptions): AsyncIterable<Chunk>;
|
|
32
|
+
/**
|
|
33
|
+
* Check if engine CLI is available
|
|
34
|
+
*/
|
|
35
|
+
isAvailable(): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Get engine-specific CLI flags
|
|
38
|
+
*/
|
|
39
|
+
getFlags(options: EngineFlags): string[];
|
|
40
|
+
/**
|
|
41
|
+
* Whether engine supports interactive mode (AskUserQuestion)
|
|
42
|
+
*/
|
|
43
|
+
supportsInteractive(): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Get the CLI command name
|
|
46
|
+
*/
|
|
47
|
+
getCommand(): string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Model aliases for friendly names
|
|
51
|
+
*/
|
|
52
|
+
export declare const MODEL_ALIASES: Record<string, string>;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve model alias to full model ID
|
|
55
|
+
*/
|
|
56
|
+
export declare function resolveModel(model: string): string;
|
|
57
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/lib/engines/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,aAAa,GAAG,MAAM,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEvE;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE,CAAC;IAEzC;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAE/B;;OAEG;IACH,UAAU,IAAI,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAIhD,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base engine interface that all engines must implement
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Model aliases for friendly names
|
|
6
|
+
*/
|
|
7
|
+
export const MODEL_ALIASES = {
|
|
8
|
+
opus: 'claude-opus-4-5-20250514',
|
|
9
|
+
sonnet: 'claude-sonnet-4-20250514',
|
|
10
|
+
haiku: 'claude-haiku-3-5-20241022',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Resolve model alias to full model ID
|
|
14
|
+
*/
|
|
15
|
+
export function resolveModel(model) {
|
|
16
|
+
return MODEL_ALIASES[model.toLowerCase()] ?? model;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/lib/engines/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwDH;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,IAAI,EAAE,0BAA0B;IAChC,MAAM,EAAE,0BAA0B;IAClC,KAAK,EAAE,2BAA2B;CACnC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.test.d.ts","sourceRoot":"","sources":["../../../src/lib/engines/base.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { resolveModel, MODEL_ALIASES } from './base.js';
|
|
3
|
+
describe('resolveModel', () => {
|
|
4
|
+
it('resolves opus alias', () => {
|
|
5
|
+
expect(resolveModel('opus')).toBe(MODEL_ALIASES.opus);
|
|
6
|
+
});
|
|
7
|
+
it('resolves sonnet alias', () => {
|
|
8
|
+
expect(resolveModel('sonnet')).toBe(MODEL_ALIASES.sonnet);
|
|
9
|
+
});
|
|
10
|
+
it('resolves haiku alias', () => {
|
|
11
|
+
expect(resolveModel('haiku')).toBe(MODEL_ALIASES.haiku);
|
|
12
|
+
});
|
|
13
|
+
it('returns unknown model as-is', () => {
|
|
14
|
+
expect(resolveModel('custom-model-id')).toBe('custom-model-id');
|
|
15
|
+
});
|
|
16
|
+
it('is case-insensitive', () => {
|
|
17
|
+
expect(resolveModel('OPUS')).toBe(MODEL_ALIASES.opus);
|
|
18
|
+
expect(resolveModel('Sonnet')).toBe(MODEL_ALIASES.sonnet);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('MODEL_ALIASES', () => {
|
|
22
|
+
it('contains expected aliases', () => {
|
|
23
|
+
expect(MODEL_ALIASES).toHaveProperty('opus');
|
|
24
|
+
expect(MODEL_ALIASES).toHaveProperty('sonnet');
|
|
25
|
+
expect(MODEL_ALIASES).toHaveProperty('haiku');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=base.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.test.js","sourceRoot":"","sources":["../../../src/lib/engines/base.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAExD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,aAAa,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,aAAa,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,CAAC,aAAa,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Engine, ExecuteOptions, Chunk, EngineFlags } from './base.js';
|
|
2
|
+
export declare class ClaudeEngine implements Engine {
|
|
3
|
+
readonly name = "claude";
|
|
4
|
+
execute(prompt: string, options: ExecuteOptions): AsyncIterable<Chunk>;
|
|
5
|
+
private parseStreamJson;
|
|
6
|
+
isAvailable(): Promise<boolean>;
|
|
7
|
+
getFlags(options: EngineFlags): string[];
|
|
8
|
+
supportsInteractive(): boolean;
|
|
9
|
+
getCommand(): string;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/lib/engines/claude.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAgB,MAAM,WAAW,CAAC;AAErF,qBAAa,YAAa,YAAW,MAAM;IACzC,QAAQ,CAAC,IAAI,YAAY;IAElB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC;IAwE7E,OAAO,CAAC,eAAe;IAsBjB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBrC,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE;IAsBxC,mBAAmB,IAAI,OAAO;IAI9B,UAAU,IAAI,MAAM;CAGrB"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { resolveModel } from './base.js';
|
|
3
|
+
export class ClaudeEngine {
|
|
4
|
+
name = 'claude';
|
|
5
|
+
async *execute(prompt, options) {
|
|
6
|
+
const flags = this.getFlags({
|
|
7
|
+
model: options.model,
|
|
8
|
+
skipPermissions: options.skipPermissions,
|
|
9
|
+
outputFormat: options.outputFormat,
|
|
10
|
+
verbose: options.verbose,
|
|
11
|
+
});
|
|
12
|
+
const args = ['-p', ...flags];
|
|
13
|
+
const child = spawn('claude', args, {
|
|
14
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
15
|
+
});
|
|
16
|
+
child.stdin.write(prompt);
|
|
17
|
+
child.stdin.end();
|
|
18
|
+
let buffer = '';
|
|
19
|
+
for await (const data of child.stdout) {
|
|
20
|
+
buffer += data.toString();
|
|
21
|
+
if (options.outputFormat === 'stream-json') {
|
|
22
|
+
const lines = buffer.split('\n');
|
|
23
|
+
buffer = lines.pop() ?? '';
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
if (!line.trim())
|
|
26
|
+
continue;
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(line);
|
|
29
|
+
yield this.parseStreamJson(parsed);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
yield { type: 'text', content: line };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
yield { type: 'text', content: data.toString() };
|
|
38
|
+
buffer = '';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (buffer.trim()) {
|
|
42
|
+
if (options.outputFormat === 'stream-json') {
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(buffer);
|
|
45
|
+
yield this.parseStreamJson(parsed);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
yield { type: 'text', content: buffer };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
yield { type: 'text', content: buffer };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
let stderrOutput = '';
|
|
56
|
+
for await (const data of child.stderr) {
|
|
57
|
+
stderrOutput += data.toString();
|
|
58
|
+
}
|
|
59
|
+
await new Promise((resolve, reject) => {
|
|
60
|
+
child.on('close', (code) => {
|
|
61
|
+
if (code !== 0 && stderrOutput) {
|
|
62
|
+
reject(new Error(`Claude exited with code ${code}: ${stderrOutput}`));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
resolve();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
child.on('error', reject);
|
|
69
|
+
});
|
|
70
|
+
yield { type: 'done' };
|
|
71
|
+
}
|
|
72
|
+
parseStreamJson(data) {
|
|
73
|
+
if (typeof data !== 'object' || data === null) {
|
|
74
|
+
return { type: 'text', content: String(data) };
|
|
75
|
+
}
|
|
76
|
+
const obj = data;
|
|
77
|
+
if (obj.type === 'assistant' && typeof obj.message === 'string') {
|
|
78
|
+
return { type: 'text', content: obj.message };
|
|
79
|
+
}
|
|
80
|
+
if (obj.type === 'tool_use') {
|
|
81
|
+
return { type: 'tool_use', tool: String(obj.name ?? 'unknown') };
|
|
82
|
+
}
|
|
83
|
+
if (obj.type === 'error') {
|
|
84
|
+
return { type: 'error', error: String(obj.error ?? 'Unknown error') };
|
|
85
|
+
}
|
|
86
|
+
return { type: 'text', content: JSON.stringify(data) };
|
|
87
|
+
}
|
|
88
|
+
async isAvailable() {
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
const child = spawn('claude', ['--version'], {
|
|
91
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
92
|
+
});
|
|
93
|
+
child.on('close', (code) => {
|
|
94
|
+
resolve(code === 0);
|
|
95
|
+
});
|
|
96
|
+
child.on('error', () => {
|
|
97
|
+
resolve(false);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
getFlags(options) {
|
|
102
|
+
const flags = [];
|
|
103
|
+
if (options.model) {
|
|
104
|
+
flags.push('--model', resolveModel(options.model));
|
|
105
|
+
}
|
|
106
|
+
if (options.skipPermissions) {
|
|
107
|
+
flags.push('--dangerously-skip-permissions');
|
|
108
|
+
}
|
|
109
|
+
if (options.outputFormat) {
|
|
110
|
+
flags.push('--output-format', options.outputFormat);
|
|
111
|
+
}
|
|
112
|
+
if (options.verbose) {
|
|
113
|
+
flags.push('--verbose');
|
|
114
|
+
}
|
|
115
|
+
return flags;
|
|
116
|
+
}
|
|
117
|
+
supportsInteractive() {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
getCommand() {
|
|
121
|
+
return 'claude';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/lib/engines/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { Engine, ExecuteOptions, Chunk, EngineFlags, MODEL_ALIASES, resolveModel } from './base.js';
|
|
2
|
+
export { ClaudeEngine } from './claude.js';
|
|
3
|
+
export { OpenCodeEngine } from './opencode.js';
|
|
4
|
+
import { Engine } from './base.js';
|
|
5
|
+
export type EngineName = 'claude' | 'opencode';
|
|
6
|
+
/**
|
|
7
|
+
* Get engine by name
|
|
8
|
+
*/
|
|
9
|
+
export declare function getEngine(name: EngineName): Engine;
|
|
10
|
+
/**
|
|
11
|
+
* Detect available engines
|
|
12
|
+
*/
|
|
13
|
+
export declare function detectEngines(): Promise<EngineName[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Get default engine (first available)
|
|
16
|
+
*/
|
|
17
|
+
export declare function getDefaultEngine(): Promise<Engine | null>;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAInC,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAO/C;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAElD;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAU3D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAI/D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export { MODEL_ALIASES, resolveModel } from './base.js';
|
|
2
|
+
export { ClaudeEngine } from './claude.js';
|
|
3
|
+
export { OpenCodeEngine } from './opencode.js';
|
|
4
|
+
import { ClaudeEngine } from './claude.js';
|
|
5
|
+
import { OpenCodeEngine } from './opencode.js';
|
|
6
|
+
const engines = {
|
|
7
|
+
claude: new ClaudeEngine(),
|
|
8
|
+
opencode: new OpenCodeEngine(),
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Get engine by name
|
|
12
|
+
*/
|
|
13
|
+
export function getEngine(name) {
|
|
14
|
+
return engines[name];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Detect available engines
|
|
18
|
+
*/
|
|
19
|
+
export async function detectEngines() {
|
|
20
|
+
const available = [];
|
|
21
|
+
for (const [name, engine] of Object.entries(engines)) {
|
|
22
|
+
if (await engine.isAvailable()) {
|
|
23
|
+
available.push(name);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return available;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get default engine (first available)
|
|
30
|
+
*/
|
|
31
|
+
export async function getDefaultEngine() {
|
|
32
|
+
const available = await detectEngines();
|
|
33
|
+
if (available.length === 0)
|
|
34
|
+
return null;
|
|
35
|
+
return engines[available[0]];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8C,aAAa,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C,MAAM,OAAO,GAA+B;IAC1C,MAAM,EAAE,IAAI,YAAY,EAAE;IAC1B,QAAQ,EAAE,IAAI,cAAc,EAAE;CAC/B,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAgB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,SAAS,GAAiB,EAAE,CAAC;IAEnC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,IAAI,MAAM,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,IAAkB,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,SAAS,GAAG,MAAM,aAAa,EAAE,CAAC;IACxC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC"}
|