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.
Files changed (66) hide show
  1. package/bin/vralphy.js +3 -0
  2. package/dist/commands/build.d.ts +9 -0
  3. package/dist/commands/build.d.ts.map +1 -0
  4. package/dist/commands/build.js +85 -0
  5. package/dist/commands/build.js.map +1 -0
  6. package/dist/commands/init.d.ts +8 -0
  7. package/dist/commands/init.d.ts.map +1 -0
  8. package/dist/commands/init.js +34 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/plan.d.ts +9 -0
  11. package/dist/commands/plan.d.ts.map +1 -0
  12. package/dist/commands/plan.js +85 -0
  13. package/dist/commands/plan.js.map +1 -0
  14. package/dist/commands/spec.d.ts +9 -0
  15. package/dist/commands/spec.d.ts.map +1 -0
  16. package/dist/commands/spec.js +109 -0
  17. package/dist/commands/spec.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +114 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/lib/agents.d.ts +32 -0
  23. package/dist/lib/agents.d.ts.map +1 -0
  24. package/dist/lib/agents.js +94 -0
  25. package/dist/lib/agents.js.map +1 -0
  26. package/dist/lib/config.d.ts +38 -0
  27. package/dist/lib/config.d.ts.map +1 -0
  28. package/dist/lib/config.js +96 -0
  29. package/dist/lib/config.js.map +1 -0
  30. package/dist/lib/config.test.d.ts +2 -0
  31. package/dist/lib/config.test.d.ts.map +1 -0
  32. package/dist/lib/config.test.js +45 -0
  33. package/dist/lib/config.test.js.map +1 -0
  34. package/dist/lib/engines/base.d.ts +57 -0
  35. package/dist/lib/engines/base.d.ts.map +1 -0
  36. package/dist/lib/engines/base.js +18 -0
  37. package/dist/lib/engines/base.js.map +1 -0
  38. package/dist/lib/engines/base.test.d.ts +2 -0
  39. package/dist/lib/engines/base.test.d.ts.map +1 -0
  40. package/dist/lib/engines/base.test.js +28 -0
  41. package/dist/lib/engines/base.test.js.map +1 -0
  42. package/dist/lib/engines/claude.d.ts +11 -0
  43. package/dist/lib/engines/claude.d.ts.map +1 -0
  44. package/dist/lib/engines/claude.js +124 -0
  45. package/dist/lib/engines/claude.js.map +1 -0
  46. package/dist/lib/engines/index.d.ts +18 -0
  47. package/dist/lib/engines/index.d.ts.map +1 -0
  48. package/dist/lib/engines/index.js +37 -0
  49. package/dist/lib/engines/index.js.map +1 -0
  50. package/dist/lib/engines/opencode.d.ts +10 -0
  51. package/dist/lib/engines/opencode.d.ts.map +1 -0
  52. package/dist/lib/engines/opencode.js +71 -0
  53. package/dist/lib/engines/opencode.js.map +1 -0
  54. package/dist/lib/init.d.ts +8 -0
  55. package/dist/lib/init.d.ts.map +1 -0
  56. package/dist/lib/init.js +254 -0
  57. package/dist/lib/init.js.map +1 -0
  58. package/dist/lib/prompts.d.ts +34 -0
  59. package/dist/lib/prompts.d.ts.map +1 -0
  60. package/dist/lib/prompts.js +130 -0
  61. package/dist/lib/prompts.js.map +1 -0
  62. package/dist/lib/skills.d.ts +32 -0
  63. package/dist/lib/skills.d.ts.map +1 -0
  64. package/dist/lib/skills.js +119 -0
  65. package/dist/lib/skills.js.map +1 -0
  66. 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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base.test.d.ts.map
@@ -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"}