vralphy 0.8.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 (158) hide show
  1. package/README.md +512 -0
  2. package/bin/vralphy.js +3 -0
  3. package/dist/commands/build.d.ts +9 -0
  4. package/dist/commands/build.d.ts.map +1 -0
  5. package/dist/commands/build.js +176 -0
  6. package/dist/commands/build.js.map +1 -0
  7. package/dist/commands/cleanup.d.ts +19 -0
  8. package/dist/commands/cleanup.d.ts.map +1 -0
  9. package/dist/commands/cleanup.js +159 -0
  10. package/dist/commands/cleanup.js.map +1 -0
  11. package/dist/commands/cleanup.test.d.ts +2 -0
  12. package/dist/commands/cleanup.test.d.ts.map +1 -0
  13. package/dist/commands/cleanup.test.js +389 -0
  14. package/dist/commands/cleanup.test.js.map +1 -0
  15. package/dist/commands/init.d.ts +13 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +120 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/plan.d.ts +9 -0
  20. package/dist/commands/plan.d.ts.map +1 -0
  21. package/dist/commands/plan.js +147 -0
  22. package/dist/commands/plan.js.map +1 -0
  23. package/dist/commands/spec.d.ts +9 -0
  24. package/dist/commands/spec.d.ts.map +1 -0
  25. package/dist/commands/spec.js +111 -0
  26. package/dist/commands/spec.js.map +1 -0
  27. package/dist/index.d.ts +3 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +251 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/lib/agents.d.ts +32 -0
  32. package/dist/lib/agents.d.ts.map +1 -0
  33. package/dist/lib/agents.js +96 -0
  34. package/dist/lib/agents.js.map +1 -0
  35. package/dist/lib/config.d.ts +54 -0
  36. package/dist/lib/config.d.ts.map +1 -0
  37. package/dist/lib/config.js +199 -0
  38. package/dist/lib/config.js.map +1 -0
  39. package/dist/lib/config.test.d.ts +2 -0
  40. package/dist/lib/config.test.d.ts.map +1 -0
  41. package/dist/lib/config.test.js +57 -0
  42. package/dist/lib/config.test.js.map +1 -0
  43. package/dist/lib/context.d.ts +29 -0
  44. package/dist/lib/context.d.ts.map +1 -0
  45. package/dist/lib/context.js +175 -0
  46. package/dist/lib/context.js.map +1 -0
  47. package/dist/lib/engines/base.d.ts +75 -0
  48. package/dist/lib/engines/base.d.ts.map +1 -0
  49. package/dist/lib/engines/base.js +62 -0
  50. package/dist/lib/engines/base.js.map +1 -0
  51. package/dist/lib/engines/base.test.d.ts +2 -0
  52. package/dist/lib/engines/base.test.d.ts.map +1 -0
  53. package/dist/lib/engines/base.test.js +28 -0
  54. package/dist/lib/engines/base.test.js.map +1 -0
  55. package/dist/lib/engines/claude.d.ts +12 -0
  56. package/dist/lib/engines/claude.d.ts.map +1 -0
  57. package/dist/lib/engines/claude.js +156 -0
  58. package/dist/lib/engines/claude.js.map +1 -0
  59. package/dist/lib/engines/codex.d.ts +28 -0
  60. package/dist/lib/engines/codex.d.ts.map +1 -0
  61. package/dist/lib/engines/codex.js +177 -0
  62. package/dist/lib/engines/codex.js.map +1 -0
  63. package/dist/lib/engines/index.d.ts +19 -0
  64. package/dist/lib/engines/index.d.ts.map +1 -0
  65. package/dist/lib/engines/index.js +40 -0
  66. package/dist/lib/engines/index.js.map +1 -0
  67. package/dist/lib/engines/opencode.d.ts +14 -0
  68. package/dist/lib/engines/opencode.d.ts.map +1 -0
  69. package/dist/lib/engines/opencode.js +127 -0
  70. package/dist/lib/engines/opencode.js.map +1 -0
  71. package/dist/lib/events/index.d.ts +6 -0
  72. package/dist/lib/events/index.d.ts.map +1 -0
  73. package/dist/lib/events/index.js +5 -0
  74. package/dist/lib/events/index.js.map +1 -0
  75. package/dist/lib/events/types.d.ts +93 -0
  76. package/dist/lib/events/types.d.ts.map +1 -0
  77. package/dist/lib/events/types.js +7 -0
  78. package/dist/lib/events/types.js.map +1 -0
  79. package/dist/lib/events/writer.d.ts +68 -0
  80. package/dist/lib/events/writer.d.ts.map +1 -0
  81. package/dist/lib/events/writer.js +178 -0
  82. package/dist/lib/events/writer.js.map +1 -0
  83. package/dist/lib/events.d.ts +33 -0
  84. package/dist/lib/events.d.ts.map +1 -0
  85. package/dist/lib/events.js +81 -0
  86. package/dist/lib/events.js.map +1 -0
  87. package/dist/lib/events.test.d.ts +2 -0
  88. package/dist/lib/events.test.d.ts.map +1 -0
  89. package/dist/lib/events.test.js +123 -0
  90. package/dist/lib/events.test.js.map +1 -0
  91. package/dist/lib/file-injection.d.ts +32 -0
  92. package/dist/lib/file-injection.d.ts.map +1 -0
  93. package/dist/lib/file-injection.js +138 -0
  94. package/dist/lib/file-injection.js.map +1 -0
  95. package/dist/lib/file-injection.test.d.ts +2 -0
  96. package/dist/lib/file-injection.test.d.ts.map +1 -0
  97. package/dist/lib/file-injection.test.js +508 -0
  98. package/dist/lib/file-injection.test.js.map +1 -0
  99. package/dist/lib/init.d.ts +27 -0
  100. package/dist/lib/init.d.ts.map +1 -0
  101. package/dist/lib/init.js +363 -0
  102. package/dist/lib/init.js.map +1 -0
  103. package/dist/lib/init.test.d.ts +2 -0
  104. package/dist/lib/init.test.d.ts.map +1 -0
  105. package/dist/lib/init.test.js +315 -0
  106. package/dist/lib/init.test.js.map +1 -0
  107. package/dist/lib/plan.d.ts +11 -0
  108. package/dist/lib/plan.d.ts.map +1 -0
  109. package/dist/lib/plan.js +22 -0
  110. package/dist/lib/plan.js.map +1 -0
  111. package/dist/lib/plan.test.d.ts +2 -0
  112. package/dist/lib/plan.test.d.ts.map +1 -0
  113. package/dist/lib/plan.test.js +70 -0
  114. package/dist/lib/plan.test.js.map +1 -0
  115. package/dist/lib/prompts/codex.d.ts +18 -0
  116. package/dist/lib/prompts/codex.d.ts.map +1 -0
  117. package/dist/lib/prompts/codex.js +82 -0
  118. package/dist/lib/prompts/codex.js.map +1 -0
  119. package/dist/lib/prompts/opencode.d.ts +16 -0
  120. package/dist/lib/prompts/opencode.d.ts.map +1 -0
  121. package/dist/lib/prompts/opencode.js +71 -0
  122. package/dist/lib/prompts/opencode.js.map +1 -0
  123. package/dist/lib/prompts.d.ts +57 -0
  124. package/dist/lib/prompts.d.ts.map +1 -0
  125. package/dist/lib/prompts.js +255 -0
  126. package/dist/lib/prompts.js.map +1 -0
  127. package/dist/lib/prompts.test.d.ts +2 -0
  128. package/dist/lib/prompts.test.d.ts.map +1 -0
  129. package/dist/lib/prompts.test.js +128 -0
  130. package/dist/lib/prompts.test.js.map +1 -0
  131. package/dist/lib/skills.d.ts +36 -0
  132. package/dist/lib/skills.d.ts.map +1 -0
  133. package/dist/lib/skills.js +132 -0
  134. package/dist/lib/skills.js.map +1 -0
  135. package/dist/lib/slack.d.ts +43 -0
  136. package/dist/lib/slack.d.ts.map +1 -0
  137. package/dist/lib/slack.js +130 -0
  138. package/dist/lib/slack.js.map +1 -0
  139. package/dist/lib/slack.test.d.ts +2 -0
  140. package/dist/lib/slack.test.d.ts.map +1 -0
  141. package/dist/lib/slack.test.js +74 -0
  142. package/dist/lib/slack.test.js.map +1 -0
  143. package/dist/lib/templates/injections.d.ts +18 -0
  144. package/dist/lib/templates/injections.d.ts.map +1 -0
  145. package/dist/lib/templates/injections.js +32 -0
  146. package/dist/lib/templates/injections.js.map +1 -0
  147. package/dist/lib/templates/readme.d.ts +6 -0
  148. package/dist/lib/templates/readme.d.ts.map +1 -0
  149. package/dist/lib/templates/readme.js +168 -0
  150. package/dist/lib/templates/readme.js.map +1 -0
  151. package/docs/COMMANDS.md +664 -0
  152. package/docs/DESIGN.md +537 -0
  153. package/docs/EXAMPLES.md +812 -0
  154. package/docs/METHODOLOGY.md +390 -0
  155. package/docs/README.md +110 -0
  156. package/docs/WORKFLOWS.md +808 -0
  157. package/llms.txt +104 -0
  158. package/package.json +58 -0
@@ -0,0 +1,156 @@
1
+ import { spawn } from 'child_process';
2
+ import { createInterface } from 'readline';
3
+ import { resolveModel } from './base.js';
4
+ export class ClaudeEngine {
5
+ name = 'claude';
6
+ async *execute(prompt, options) {
7
+ const flags = this.getFlags({
8
+ planningModel: options.planningModel,
9
+ skipPermissions: options.skipPermissions,
10
+ verbose: true, // Always use verbose for stream-json
11
+ reasoningEffort: options.reasoningEffort,
12
+ });
13
+ // Use stream-json for real-time output during tool execution
14
+ const args = ['-p', '--output-format', 'stream-json', ...flags];
15
+ const child = spawn('claude', args, {
16
+ stdio: ['pipe', 'pipe', 'pipe'],
17
+ });
18
+ child.stdin.write(prompt);
19
+ child.stdin.end();
20
+ // Stream stderr to terminal
21
+ child.stderr.on('data', (data) => {
22
+ process.stderr.write(data);
23
+ });
24
+ // Parse JSON stream line by line
25
+ const rl = createInterface({ input: child.stdout });
26
+ for await (const line of rl) {
27
+ try {
28
+ const event = JSON.parse(line);
29
+ // Handle different event types
30
+ if (event.type === 'assistant' && event.message?.content) {
31
+ for (const content of event.message.content) {
32
+ if (content.type === 'text' && content.text) {
33
+ process.stdout.write(content.text);
34
+ yield { type: 'text', content: content.text };
35
+ }
36
+ else if (content.type === 'tool_use' && content.name) {
37
+ // Show tool usage with key parameters
38
+ let toolInfo = `\n[Tool: ${content.name}`;
39
+ // Add relevant parameters for common tools
40
+ const input = content.input;
41
+ if (input) {
42
+ if (content.name === 'Read' && input.file_path) {
43
+ toolInfo += ` ${input.file_path}`;
44
+ }
45
+ else if (content.name === 'Edit' && input.file_path) {
46
+ toolInfo += ` ${input.file_path}`;
47
+ }
48
+ else if (content.name === 'Write' && input.file_path) {
49
+ toolInfo += ` ${input.file_path}`;
50
+ }
51
+ else if (content.name === 'Bash' && input.command) {
52
+ const cmd = String(input.command).slice(0, 60);
53
+ toolInfo += `: ${cmd}${String(input.command).length > 60 ? '...' : ''}`;
54
+ }
55
+ else if (content.name === 'Grep' && input.pattern) {
56
+ toolInfo += ` pattern="${input.pattern}"`;
57
+ }
58
+ else if (content.name === 'Glob' && input.pattern) {
59
+ toolInfo += ` "${input.pattern}"`;
60
+ }
61
+ else if (content.name === 'Task' && input.prompt) {
62
+ const prompt = String(input.prompt).slice(0, 50);
63
+ toolInfo += `: ${prompt}${String(input.prompt).length > 50 ? '...' : ''}`;
64
+ }
65
+ }
66
+ toolInfo += ']\n';
67
+ process.stdout.write(toolInfo);
68
+ yield { type: 'text', content: toolInfo };
69
+ }
70
+ }
71
+ }
72
+ else if (event.type === 'result') {
73
+ // Result event signals completion - don't output as it duplicates assistant message
74
+ }
75
+ }
76
+ catch {
77
+ // Non-JSON line or parse error - output as-is
78
+ if (line.trim()) {
79
+ process.stdout.write(line + '\n');
80
+ yield { type: 'text', content: line + '\n' };
81
+ }
82
+ }
83
+ }
84
+ await new Promise((resolve, reject) => {
85
+ child.on('close', (code, signal) => {
86
+ if (code === 0 || code === null) {
87
+ resolve();
88
+ }
89
+ else if (signal) {
90
+ reject(new Error(`Claude was killed by signal ${signal}`));
91
+ }
92
+ else {
93
+ reject(new Error(`Claude exited with code ${code}`));
94
+ }
95
+ });
96
+ child.on('error', (err) => {
97
+ reject(err);
98
+ });
99
+ });
100
+ yield { type: 'done' };
101
+ }
102
+ async isAvailable() {
103
+ return new Promise((resolve) => {
104
+ const child = spawn('claude', ['--version'], {
105
+ stdio: ['ignore', 'pipe', 'ignore'],
106
+ });
107
+ child.on('close', (code) => {
108
+ resolve(code === 0);
109
+ });
110
+ child.on('error', () => {
111
+ resolve(false);
112
+ });
113
+ });
114
+ }
115
+ async getAvailableModels() {
116
+ // Claude supports these model aliases
117
+ return ['opus', 'sonnet', 'haiku'];
118
+ }
119
+ async isModelSupported(model) {
120
+ const knownAliases = await this.getAvailableModels();
121
+ const normalized = model.toLowerCase();
122
+ // Check if it's a known alias
123
+ if (knownAliases.includes(normalized)) {
124
+ return true;
125
+ }
126
+ // Allow full model IDs like claude-opus-4-5-20251101
127
+ if (model.startsWith('claude-')) {
128
+ return true;
129
+ }
130
+ return false;
131
+ }
132
+ getFlags(options) {
133
+ const flags = [];
134
+ if (options.planningModel) {
135
+ flags.push('--model', resolveModel(options.planningModel, 'claude'));
136
+ }
137
+ if (options.skipPermissions) {
138
+ flags.push('--dangerously-skip-permissions');
139
+ }
140
+ if (options.verbose) {
141
+ flags.push('--verbose');
142
+ }
143
+ if (options.reasoningEffort) {
144
+ // Claude CLI does not support reasoning-effort parameter yet
145
+ console.warn('Warning: Claude CLI does not support reasoning-effort parameter. Ignoring.');
146
+ }
147
+ return flags;
148
+ }
149
+ supportsInteractive() {
150
+ return true;
151
+ }
152
+ getCommand() {
153
+ return 'claude';
154
+ }
155
+ }
156
+ //# 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,28 @@
1
+ import { Engine, ExecuteOptions, Chunk, EngineFlags } from './base.js';
2
+ export interface CodexPromptConfig {
3
+ maxAgents: number;
4
+ workerTimeout: number;
5
+ }
6
+ export declare class CodexEngine implements Engine {
7
+ readonly name = "codex";
8
+ private maxAgents;
9
+ private workerTimeout;
10
+ /**
11
+ * Configure Codex-specific settings
12
+ */
13
+ configure(config: Partial<CodexPromptConfig>): void;
14
+ /**
15
+ * Get prompt configuration for interpolation
16
+ */
17
+ getPromptConfig(): CodexPromptConfig;
18
+ execute(prompt: string, options: ExecuteOptions): AsyncIterable<Chunk>;
19
+ isAvailable(): Promise<boolean>;
20
+ private modelCache;
21
+ private modelCachePromise;
22
+ getAvailableModels(): Promise<string[]>;
23
+ isModelSupported(model: string): Promise<boolean>;
24
+ getFlags(options: EngineFlags): string[];
25
+ supportsInteractive(): boolean;
26
+ getCommand(): string;
27
+ }
28
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/lib/engines/codex.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAgB,MAAM,WAAW,CAAC;AAGrF,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,WAAY,YAAW,MAAM;IACxC,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,aAAa,CAAwC;IAE7D;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI;IASnD;;OAEG;IACH,eAAe,IAAI,iBAAiB;IAO7B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC;IAgDvE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBrC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,iBAAiB,CAAkC;IAErD,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IA8DvC,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKvD,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE;IAyBxC,mBAAmB,IAAI,OAAO;IAI9B,UAAU,IAAI,MAAM;CAGrB"}
@@ -0,0 +1,177 @@
1
+ import { spawn } from 'child_process';
2
+ import { readFile } from 'fs/promises';
3
+ import { existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
6
+ import { resolveModel } from './base.js';
7
+ import { CODEX_DEFAULT_MAX_AGENTS, CODEX_DEFAULT_WORKER_TIMEOUT } from '../prompts/codex.js';
8
+ export class CodexEngine {
9
+ name = 'codex';
10
+ maxAgents = CODEX_DEFAULT_MAX_AGENTS;
11
+ workerTimeout = CODEX_DEFAULT_WORKER_TIMEOUT;
12
+ /**
13
+ * Configure Codex-specific settings
14
+ */
15
+ configure(config) {
16
+ if (config.maxAgents !== undefined) {
17
+ this.maxAgents = config.maxAgents;
18
+ }
19
+ if (config.workerTimeout !== undefined) {
20
+ this.workerTimeout = config.workerTimeout;
21
+ }
22
+ }
23
+ /**
24
+ * Get prompt configuration for interpolation
25
+ */
26
+ getPromptConfig() {
27
+ return {
28
+ maxAgents: this.maxAgents,
29
+ workerTimeout: this.workerTimeout,
30
+ };
31
+ }
32
+ async *execute(prompt, options) {
33
+ const flags = this.getFlags({
34
+ planningModel: options.planningModel,
35
+ skipPermissions: options.skipPermissions,
36
+ verbose: options.verbose,
37
+ reasoningEffort: options.reasoningEffort,
38
+ maxAgents: this.maxAgents,
39
+ });
40
+ // Use 'codex exec' for non-interactive execution with prompt from stdin
41
+ const args = ['exec', ...flags, '-'];
42
+ const child = spawn('codex', args, {
43
+ stdio: ['pipe', 'pipe', 'pipe'],
44
+ });
45
+ child.stdin.write(prompt);
46
+ child.stdin.end();
47
+ // Stream stderr to terminal
48
+ child.stderr.on('data', (data) => {
49
+ process.stderr.write(data);
50
+ });
51
+ // Stream stdout to terminal and yield chunks
52
+ for await (const data of child.stdout) {
53
+ const text = data.toString();
54
+ process.stdout.write(text);
55
+ yield { type: 'text', content: text };
56
+ }
57
+ await new Promise((resolve, reject) => {
58
+ child.on('close', (code, signal) => {
59
+ if (code === 0 || code === null) {
60
+ resolve();
61
+ }
62
+ else if (signal) {
63
+ reject(new Error(`Codex was killed by signal ${signal}`));
64
+ }
65
+ else {
66
+ reject(new Error(`Codex exited with code ${code}`));
67
+ }
68
+ });
69
+ child.on('error', (err) => {
70
+ reject(err);
71
+ });
72
+ });
73
+ yield { type: 'done' };
74
+ }
75
+ async isAvailable() {
76
+ return new Promise((resolve) => {
77
+ const child = spawn('codex', ['--version'], {
78
+ stdio: ['ignore', 'pipe', 'ignore'],
79
+ });
80
+ child.on('close', (code) => {
81
+ resolve(code === 0);
82
+ });
83
+ child.on('error', () => {
84
+ resolve(false);
85
+ });
86
+ });
87
+ }
88
+ modelCache = null;
89
+ modelCachePromise = null;
90
+ async getAvailableModels() {
91
+ // Return cached models if available
92
+ if (this.modelCache) {
93
+ return this.modelCache;
94
+ }
95
+ // Return ongoing fetch if one is in progress
96
+ if (this.modelCachePromise) {
97
+ return this.modelCachePromise;
98
+ }
99
+ // Create promise for the fetch operation
100
+ this.modelCachePromise = (async () => {
101
+ // Try to read from ~/.codex/models_cache.json
102
+ const cacheFile = join(homedir(), '.codex', 'models_cache.json');
103
+ if (!existsSync(cacheFile)) {
104
+ // Fallback to known models if cache doesn't exist
105
+ const fallbackModels = [
106
+ 'gpt-5',
107
+ 'gpt-5.1',
108
+ 'gpt-5.2',
109
+ 'gpt-5-codex',
110
+ 'gpt-5.1-codex',
111
+ 'gpt-5.2-codex',
112
+ 'gpt-5.1-codex-max',
113
+ 'gpt-5.1-codex-mini',
114
+ 'gpt-5-codex-mini',
115
+ ];
116
+ this.modelCache = fallbackModels;
117
+ this.modelCachePromise = null;
118
+ return fallbackModels;
119
+ }
120
+ try {
121
+ const content = await readFile(cacheFile, 'utf-8');
122
+ const data = JSON.parse(content);
123
+ const models = data.models?.map((m) => m.slug) || [];
124
+ this.modelCache = models;
125
+ this.modelCachePromise = null;
126
+ return models;
127
+ }
128
+ catch {
129
+ // Fallback to known models if parse fails
130
+ const fallbackModels = [
131
+ 'gpt-5',
132
+ 'gpt-5.1',
133
+ 'gpt-5.2',
134
+ 'gpt-5-codex',
135
+ 'gpt-5.1-codex',
136
+ 'gpt-5.2-codex',
137
+ 'gpt-5.1-codex-max',
138
+ 'gpt-5.1-codex-mini',
139
+ 'gpt-5-codex-mini',
140
+ ];
141
+ this.modelCache = fallbackModels;
142
+ this.modelCachePromise = null;
143
+ return fallbackModels;
144
+ }
145
+ })();
146
+ return this.modelCachePromise;
147
+ }
148
+ async isModelSupported(model) {
149
+ const availableModels = await this.getAvailableModels();
150
+ return availableModels.includes(model.toLowerCase());
151
+ }
152
+ getFlags(options) {
153
+ const flags = [];
154
+ if (options.planningModel) {
155
+ flags.push('--model', resolveModel(options.planningModel, 'codex'));
156
+ }
157
+ if (options.skipPermissions) {
158
+ flags.push('--full-auto');
159
+ }
160
+ if (options.verbose) {
161
+ flags.push('--verbose');
162
+ }
163
+ if (options.reasoningEffort) {
164
+ flags.push('-c', `model_reasoning_effort="${options.reasoningEffort}"`);
165
+ }
166
+ // Note: max_agents is only used in MCP server mode, not CLI exec mode
167
+ // Keeping the option for future MCP support
168
+ return flags;
169
+ }
170
+ supportsInteractive() {
171
+ return true;
172
+ }
173
+ getCommand() {
174
+ return 'codex';
175
+ }
176
+ }
177
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/lib/engines/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
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
+ export { CodexEngine } from './codex.js';
5
+ import { Engine } from './base.js';
6
+ export type EngineName = 'claude' | 'opencode' | 'codex';
7
+ /**
8
+ * Get engine by name
9
+ */
10
+ export declare function getEngine(name: EngineName): Engine;
11
+ /**
12
+ * Detect available engines
13
+ */
14
+ export declare function detectEngines(): Promise<EngineName[]>;
15
+ /**
16
+ * Get default engine (first available)
17
+ */
18
+ export declare function getDefaultEngine(): Promise<Engine | null>;
19
+ //# 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;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAKnC,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAQzD;;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,40 @@
1
+ export { MODEL_ALIASES, resolveModel } from './base.js';
2
+ export { ClaudeEngine } from './claude.js';
3
+ export { OpenCodeEngine } from './opencode.js';
4
+ export { CodexEngine } from './codex.js';
5
+ import { ClaudeEngine } from './claude.js';
6
+ import { OpenCodeEngine } from './opencode.js';
7
+ import { CodexEngine } from './codex.js';
8
+ const engines = {
9
+ claude: new ClaudeEngine(),
10
+ opencode: new OpenCodeEngine(),
11
+ codex: new CodexEngine(),
12
+ };
13
+ /**
14
+ * Get engine by name
15
+ */
16
+ export function getEngine(name) {
17
+ return engines[name];
18
+ }
19
+ /**
20
+ * Detect available engines
21
+ */
22
+ export async function detectEngines() {
23
+ const available = [];
24
+ for (const [name, engine] of Object.entries(engines)) {
25
+ if (await engine.isAvailable()) {
26
+ available.push(name);
27
+ }
28
+ }
29
+ return available;
30
+ }
31
+ /**
32
+ * Get default engine (first available)
33
+ */
34
+ export async function getDefaultEngine() {
35
+ const available = await detectEngines();
36
+ if (available.length === 0)
37
+ return null;
38
+ return engines[available[0]];
39
+ }
40
+ //# 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;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAIzC,MAAM,OAAO,GAA+B;IAC1C,MAAM,EAAE,IAAI,YAAY,EAAE;IAC1B,QAAQ,EAAE,IAAI,cAAc,EAAE;IAC9B,KAAK,EAAE,IAAI,WAAW,EAAE;CACzB,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"}
@@ -0,0 +1,14 @@
1
+ import { Engine, ExecuteOptions, Chunk, EngineFlags } from './base.js';
2
+ export declare class OpenCodeEngine implements Engine {
3
+ readonly name = "opencode";
4
+ execute(prompt: string, options: ExecuteOptions): AsyncIterable<Chunk>;
5
+ isAvailable(): Promise<boolean>;
6
+ private modelCache;
7
+ private modelCachePromise;
8
+ getAvailableModels(): Promise<string[]>;
9
+ isModelSupported(model: string): Promise<boolean>;
10
+ getFlags(options: EngineFlags): string[];
11
+ supportsInteractive(): boolean;
12
+ getCommand(): string;
13
+ }
14
+ //# sourceMappingURL=opencode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/lib/engines/opencode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAgB,MAAM,WAAW,CAAC;AAErF,qBAAa,cAAe,YAAW,MAAM;IAC3C,QAAQ,CAAC,IAAI,cAAc;IAEpB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC;IAyCvE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBrC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,iBAAiB,CAAkC;IAErD,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAiDvC,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWvD,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE;IAgBxC,mBAAmB,IAAI,OAAO;IAI9B,UAAU,IAAI,MAAM;CAGrB"}
@@ -0,0 +1,127 @@
1
+ import { spawn } from 'child_process';
2
+ import { resolveModel } from './base.js';
3
+ export class OpenCodeEngine {
4
+ name = 'opencode';
5
+ async *execute(prompt, options) {
6
+ const flags = this.getFlags({
7
+ planningModel: options.planningModel,
8
+ reasoningEffort: options.reasoningEffort,
9
+ });
10
+ const args = ['run', ...flags, prompt];
11
+ const child = spawn('opencode', args, {
12
+ stdio: ['inherit', 'pipe', 'pipe'],
13
+ });
14
+ // Stream stderr to terminal
15
+ child.stderr.on('data', (data) => {
16
+ process.stderr.write(data);
17
+ });
18
+ // Stream stdout to terminal and yield chunks
19
+ for await (const data of child.stdout) {
20
+ const text = data.toString();
21
+ process.stdout.write(text);
22
+ yield { type: 'text', content: text };
23
+ }
24
+ await new Promise((resolve, reject) => {
25
+ child.on('close', (code, signal) => {
26
+ if (code === 0 || code === null) {
27
+ resolve();
28
+ }
29
+ else if (signal) {
30
+ reject(new Error(`OpenCode was killed by signal ${signal}`));
31
+ }
32
+ else {
33
+ reject(new Error(`OpenCode exited with code ${code}`));
34
+ }
35
+ });
36
+ child.on('error', (err) => {
37
+ reject(err);
38
+ });
39
+ });
40
+ yield { type: 'done' };
41
+ }
42
+ async isAvailable() {
43
+ return new Promise((resolve) => {
44
+ const child = spawn('opencode', ['--version'], {
45
+ stdio: ['ignore', 'pipe', 'ignore'],
46
+ });
47
+ child.on('close', (code) => {
48
+ resolve(code === 0);
49
+ });
50
+ child.on('error', () => {
51
+ resolve(false);
52
+ });
53
+ });
54
+ }
55
+ modelCache = null;
56
+ modelCachePromise = null;
57
+ async getAvailableModels() {
58
+ // Return cached models if available
59
+ if (this.modelCache) {
60
+ return this.modelCache;
61
+ }
62
+ // Return ongoing fetch if one is in progress
63
+ if (this.modelCachePromise) {
64
+ return this.modelCachePromise;
65
+ }
66
+ this.modelCachePromise = new Promise((resolve) => {
67
+ const child = spawn('opencode', ['models'], {
68
+ stdio: ['ignore', 'pipe', 'ignore'],
69
+ });
70
+ let output = '';
71
+ child.stdout.on('data', (data) => {
72
+ output += data.toString();
73
+ });
74
+ child.on('close', (code) => {
75
+ if (code === 0) {
76
+ // Parse model list (format: opencode/provider/model)
77
+ const models = output
78
+ .trim()
79
+ .split('\n')
80
+ .map((line) => line.trim())
81
+ .filter((line) => line.length > 0);
82
+ this.modelCache = models;
83
+ this.modelCachePromise = null;
84
+ resolve(models);
85
+ }
86
+ else {
87
+ // Don't cache empty list on failure - allow retry next time
88
+ this.modelCachePromise = null;
89
+ resolve([]);
90
+ }
91
+ });
92
+ child.on('error', () => {
93
+ // Don't cache empty list on error - allow retry next time
94
+ this.modelCachePromise = null;
95
+ resolve([]);
96
+ });
97
+ });
98
+ return this.modelCachePromise;
99
+ }
100
+ async isModelSupported(model) {
101
+ const availableModels = await this.getAvailableModels();
102
+ // Check if model is in the list (exact match or with opencode/ prefix)
103
+ const normalized = model.toLowerCase();
104
+ return availableModels.some((m) => {
105
+ const mLower = m.toLowerCase();
106
+ return mLower === normalized || mLower === `opencode/${normalized}`;
107
+ });
108
+ }
109
+ getFlags(options) {
110
+ const flags = [];
111
+ if (options.planningModel) {
112
+ flags.push('--model', resolveModel(options.planningModel, 'opencode'));
113
+ }
114
+ // OpenCode doesn't have --yes or --verbose flags
115
+ if (options.reasoningEffort) {
116
+ flags.push('--variant', options.reasoningEffort);
117
+ }
118
+ return flags;
119
+ }
120
+ supportsInteractive() {
121
+ return false;
122
+ }
123
+ getCommand() {
124
+ return 'opencode';
125
+ }
126
+ }
127
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/lib/engines/opencode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Event streaming module exports
3
+ */
4
+ export { EventWriter } from './writer.js';
5
+ export type { VralphyEvent, EventType, BaseEvent, IterationStartEvent, IterationEndEvent, ToolEvent, FileEvent, StateChangeEvent, ErrorEvent, SessionStartEvent, SessionEndEvent, } from './types.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/events/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EACV,YAAY,EACZ,SAAS,EACT,SAAS,EACT,mBAAmB,EACnB,iBAAiB,EACjB,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Event streaming module exports
3
+ */
4
+ export { EventWriter } from './writer.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/events/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}