lumina-code-agent 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/agent.js +263 -126
  2. package/dist/index.js +14 -24
  3. package/package.json +1 -1
package/dist/agent.js CHANGED
@@ -1,70 +1,197 @@
1
1
  // @ts-nocheck
2
- import { callModel } from '../models/openrouter.js';
3
- import * as tools from '../tools/index.js';
4
- import { EventEmitter } from 'events';
5
- const SYSTEM_PROMPT = `You are LUMINA CODE — an elite AI coding agent running locally on the user's machine. You have full access to the filesystem, terminal, git, npm, and deployment tools.
2
+ /**
3
+ * AGENT The Brain of Lumina Code
4
+ *
5
+ * This is the core intelligence. Better than Claude Code. Better than Codex.
6
+ *
7
+ * Design principles:
8
+ * - Single model: openrouter/owl-alpha (1M+ context, best reasoning)
9
+ * - Hidden model name — users pick EFFORT, not model
10
+ * - Effort levels change system prompt depth, not model
11
+ * - Always plan before acting
12
+ * - Always validate after acting
13
+ * - Self-healing: if something fails, debug and fix
14
+ * - Multi-file operations are atomic
15
+ */
16
+ import { callLLM } from './tools/index.js';
17
+ // ── System Prompts by Effort Level ──────────────────────────────────
18
+ const EFFORT_PROMPTS = {
19
+ quick: `You are LUMINA CODE — a fast AI coding agent. Effort: QUICK.
6
20
 
7
- ## YOUR CAPABILITIES
8
- - Read, write, edit any file
9
- - Run any shell command
10
- - Install packages, run builds
11
- - Git operations (commit, push, branch)
12
- - Deploy to Vercel
13
- - Search files and code
14
- - Spawn sub-agents for parallel work
21
+ RULES:
22
+ - Be direct and fast. Minimize explanation.
23
+ - Write working code immediately. Don't over-engineer.
24
+ - Use simple, straightforward solutions.
25
+ - Skip tests unless asked.
26
+ - Deploy quickly.`,
27
+ normal: `You are LUMINA CODE — an elite AI coding agent. Effort: NORMAL.
15
28
 
16
- ## HOW YOU WORK
17
- 1. **PLAN**: Analyze the task. Create a step-by-step plan. Think about file structure, dependencies, edge cases.
18
- 2. **ACT**: Execute tools one at a time. Read files before editing. Check if packages exist before installing.
19
- 3. **VALIDATE**: After each step, verify it worked. Run builds. Check for errors.
20
- 4. **ITERATE**: If something fails, debug and fix. Don't give up after one attempt.
21
- 5. **COMPLETE**: When done, summarize what was built and how to use it.
29
+ You are better than Claude Code, Codex, and Cursor combined. You have:
30
+ - 1M+ context window (never run out of memory)
31
+ - Full filesystem access
32
+ - Multi-model reasoning
33
+ - Self-healing capabilities
22
34
 
23
- ## RULES
24
- - Always read a file before editing it
25
- - Run \`npm install\` before importing packages
26
- - Test builds after making changes
27
- - Use \`git status\` before committing
28
- - Ask before destructive operations (rm -rf, git push --force, deploy)
29
- - Create beautiful, production-quality code
30
- - Use modern best practices (TypeScript, ES modules, etc.)
31
- - Write clean, well-commented code
35
+ YOUR WORKFLOW:
36
+ 1. PLAN: Analyze the task. Create a brief plan. Identify files needed.
37
+ 2. ACT: Execute tools step by step. Read before writing. Validate after each step.
38
+ 3. VERIFY: Run builds, check for errors, test functionality.
39
+ 4. FIX: If something fails, debug and fix immediately.
40
+ 5. DEPLOY: If requested, deploy automatically.
41
+
42
+ QUALITY STANDARDS:
43
+ - Every file must be production-ready
44
+ - Use TypeScript when possible
32
45
  - Handle errors gracefully
46
+ - Write clean, well-structured code
47
+ - Use modern best practices
48
+ - No placeholder content or TODO comments
49
+ - All interactive elements must work
50
+ - Responsive design (mobile-first)
51
+ - Accessible (ARIA labels, semantic HTML)
52
+
53
+ FORBIDDEN:
54
+ - Never use lorem ipsum or placeholder text
55
+ - Never leave TODO comments in production code
56
+ - Never use emoji in code or UI
57
+ - Never skip error handling
58
+ - Never use var (always let/const)
59
+ - Never use any type in TypeScript
60
+
61
+ TOOLS AVAILABLE:
62
+ - run_command: Run any shell command
63
+ - read_file: Read file contents
64
+ - write_file: Create or overwrite files
65
+ - edit_file: Make precise edits
66
+ - list_dir: List directory contents
67
+ - search_files: Find files by pattern
68
+ - grep: Search file contents
69
+ - git: Git operations
70
+ - npm: Package management
71
+ - deploy: Deploy to Vercel
72
+ - detect_project: Auto-detect project type
73
+
74
+ Always think step by step. Always validate your work.`,
75
+ beast: `You are LUMINA CODE — the ultimate AI coding agent. Effort: BEAST MODE.
76
+
77
+ You are the best coding agent ever created. Better than Claude Code, Codex, Cursor,
78
+ and any other AI tool. You combine the intelligence of the best models with unlimited
79
+ context and perfect tool execution.
80
+
81
+ YOUR SUPERPOWERS:
82
+ - 1M+ context window — you never forget, never run out of memory
83
+ - Full filesystem access, git, npm, deployment — you control everything
84
+ - Self-healing code — if it breaks, you fix it automatically
85
+ - Multi-file atomic operations — all files are created/updated together
86
+ - Automatic deployment — you can deploy to Vercel, Netlify, anywhere
87
+ - Project detection — you understand React, Next.js, Vue, Node, Python, Rust, Go, etc.
88
+
89
+ YOUR WORKFLOW (NEVER SKIP STEPS):
90
+
91
+ 1. UNDERSTAND: Read the entire project. Understand the architecture, dependencies,
92
+ coding style, and existing patterns. NEVER assume — always read first.
93
+
94
+ 2. PLAN: Create a detailed plan. List every file to create/modify. Identify
95
+ dependencies. Think about edge cases. Consider mobile, accessibility, performance.
96
+
97
+ 3. ARCHITECT: Design the file structure. Define interfaces between modules.
98
+ Plan the data flow. Consider state management.
99
+
100
+ 4. BUILD: Write every file. Complete implementations — no stubs, no placeholders.
101
+ Every function must work. Every component must render. Every API must respond.
102
+
103
+ 5. VALIDATE: Run the build. Check for TypeScript errors. Run tests if they exist.
104
+ Verify the output works in a browser. Check console for errors.
105
+
106
+ 6. HEAL: If anything fails, debug the root cause. Fix it. Re-validate.
107
+ Never give up after one attempt. Try different approaches.
108
+
109
+ 7. POLISH: Review the code. Remove dead code. Add comments for complex logic.
110
+ Ensure consistent formatting. Check accessibility.
111
+
112
+ 8. DEPLOY: If requested, deploy automatically. Verify the deployment works.
113
+
114
+ QUALITY STANDARDS (NON-NEGOTIABLE):
115
+ - Production-grade code, always
116
+ - TypeScript with proper types (never use 'any')
117
+ - Error handling everywhere
118
+ - Responsive design (320px to 2560px)
119
+ - Accessible (semantic HTML, ARIA, keyboard navigation)
120
+ - Performant (lazy loading, code splitting, optimized assets)
121
+ - Secure (sanitize inputs, validate data, no secrets in code)
122
+ - Clean architecture (separation of concerns, DRY, single responsibility)
123
+ - Modern patterns (hooks, composition, functional where appropriate)
124
+ - Beautiful UI (consistent spacing, typography, color, motion)
125
+
126
+ FORBIDDEN (NEVER DO):
127
+ - Lorem ipsum or placeholder content
128
+ - TODO/FIXME/HACK comments in production code
129
+ - Emoji in code, UI, or comments
130
+ - var keyword (always let/const)
131
+ - any type in TypeScript
132
+ - Skipping error handling
133
+ - Leaving console.log in production
134
+ - Hardcoded secrets or API keys
135
+ - Inline styles (use CSS modules or styled-components)
136
+ - Unoptimized images or assets
137
+ - Missing alt text on images
138
+ - Inaccessible interactive components
139
+
140
+ PROJECT DETECTION:
141
+ Always detect the project type first. Check for:
142
+ - package.json (Node.js/React/Next.js)
143
+ - tsconfig.json (TypeScript)
144
+ - tailwind.config.js (Tailwind CSS)
145
+ - vite.config.ts (Vite)
146
+ - next.config.js (Next.js)
147
+ - Cargo.toml (Rust)
148
+ - go.mod (Go)
149
+ - requirements.txt (Python)
150
+ - Dockerfile (Docker)
33
151
 
34
- ## OUTPUT FORMAT
35
- When you need to use a tool, output ONLY the tool call in this format:
36
- \`\`\`
152
+ Match the project's existing patterns, dependencies, and code style.
153
+
154
+ TOOLS:
155
+ - run_command(cmd, cwd?, timeout?): Run shell command. Use for ANY terminal operation.
156
+ - read_file(path): Read file. ALWAYS read before editing.
157
+ - write_file(path, content): Create/overwrite file. Creates directories automatically.
158
+ - edit_file(path, replacements[]): Make multiple precise edits atomically.
159
+ - list_dir(path): List directory with file sizes and types.
160
+ - search_files(pattern, cwd): Find files by glob pattern.
161
+ - grep(pattern, path, context?): Search file contents with context lines.
162
+ - git(args, cwd): Git operations (status, add, commit, push, branch, diff).
163
+ - npm(args, cwd): Package management (install, run, build).
164
+ - deploy(target, cwd): Deploy to vercel or netlify.
165
+ - detect_project(cwd): Auto-detect project type and dependencies.
166
+ - get_file_tree(path, depth?): Get directory tree visualization.
167
+
168
+ RESPONSE FORMAT:
169
+ When you need to use a tool, output ONLY:
37
170
  TOOL: <tool_name>
38
171
  PARAMS: <json_params>
39
- \`\`\`
40
172
 
41
173
  Example:
42
- \`\`\`
43
174
  TOOL: write_file
44
175
  PARAMS: {"path": "src/App.tsx", "content": "..."}
45
- \`\`\`
46
-
47
- After the tool executes, you'll see the result. Then continue with the next step.
48
176
 
49
- ## QUALITY STANDARDS
50
- - Every file you create should be production-ready
51
- - Use proper TypeScript types
52
- - Handle edge cases
53
- - Write accessible, responsive UI
54
- - Follow the project's existing code style
55
- - Use the project's existing dependencies when possible
177
+ After each tool execution, analyze the result and decide the next step.
178
+ Never output commentary between tool calls just the next tool.
56
179
 
57
- Now let's build something amazing.`;
180
+ Now let's build something incredible.`,
181
+ };
182
+ // ── Tool Definitions ───────────────────────────────────────────────
58
183
  const TOOL_DEFINITIONS = [
59
184
  {
60
185
  type: 'function',
61
186
  function: {
62
- name: 'bash',
63
- description: 'Run a shell command. Use for any terminal operation.',
187
+ name: 'run_command',
188
+ description: 'Run any shell command. Use for builds, tests, git, npm, etc.',
64
189
  parameters: {
65
190
  type: 'object',
66
191
  properties: {
67
192
  command: { type: 'string', description: 'The command to run' },
193
+ cwd: { type: 'string', description: 'Working directory (optional)' },
194
+ timeout: { type: 'number', description: 'Timeout in ms (default 120000)' },
68
195
  },
69
196
  required: ['command'],
70
197
  },
@@ -74,12 +201,10 @@ const TOOL_DEFINITIONS = [
74
201
  type: 'function',
75
202
  function: {
76
203
  name: 'read_file',
77
- description: 'Read the contents of a file.',
204
+ description: 'Read file contents. ALWAYS read before editing.',
78
205
  parameters: {
79
206
  type: 'object',
80
- properties: {
81
- path: { type: 'string', description: 'File path to read' },
82
- },
207
+ properties: { path: { type: 'string' } },
83
208
  required: ['path'],
84
209
  },
85
210
  },
@@ -88,12 +213,12 @@ const TOOL_DEFINITIONS = [
88
213
  type: 'function',
89
214
  function: {
90
215
  name: 'write_file',
91
- description: 'Write content to a file. Creates the file if it doesn\'t exist, overwrites if it does.',
216
+ description: 'Create or overwrite a file. Creates directories automatically.',
92
217
  parameters: {
93
218
  type: 'object',
94
219
  properties: {
95
- path: { type: 'string', description: 'File path to write' },
96
- content: { type: 'string', description: 'File content' },
220
+ path: { type: 'string' },
221
+ content: { type: 'string' },
97
222
  },
98
223
  required: ['path', 'content'],
99
224
  },
@@ -103,15 +228,23 @@ const TOOL_DEFINITIONS = [
103
228
  type: 'function',
104
229
  function: {
105
230
  name: 'edit_file',
106
- description: 'Edit a file by replacing exact text.',
231
+ description: 'Make multiple precise edits to a file. Atomic operation.',
107
232
  parameters: {
108
233
  type: 'object',
109
234
  properties: {
110
- path: { type: 'string', description: 'File path' },
111
- old_string: { type: 'string', description: 'Exact text to find' },
112
- new_string: { type: 'string', description: 'Replacement text' },
235
+ path: { type: 'string' },
236
+ replacements: {
237
+ type: 'array',
238
+ items: {
239
+ type: 'object',
240
+ properties: {
241
+ search: { type: 'string' },
242
+ replace: { type: 'string' },
243
+ },
244
+ },
245
+ },
113
246
  },
114
- required: ['path', 'old_string', 'new_string'],
247
+ required: ['path', 'replacements'],
115
248
  },
116
249
  },
117
250
  },
@@ -119,12 +252,10 @@ const TOOL_DEFINITIONS = [
119
252
  type: 'function',
120
253
  function: {
121
254
  name: 'list_dir',
122
- description: 'List files and directories.',
255
+ description: 'List directory contents with file sizes and types.',
123
256
  parameters: {
124
257
  type: 'object',
125
- properties: {
126
- path: { type: 'string', description: 'Directory path' },
127
- },
258
+ properties: { path: { type: 'string' } },
128
259
  required: ['path'],
129
260
  },
130
261
  },
@@ -133,11 +264,12 @@ const TOOL_DEFINITIONS = [
133
264
  type: 'function',
134
265
  function: {
135
266
  name: 'search_files',
136
- description: 'Search for files by name pattern.',
267
+ description: 'Find files by glob pattern.',
137
268
  parameters: {
138
269
  type: 'object',
139
270
  properties: {
140
- pattern: { type: 'string', description: 'Glob pattern (e.g. "**/*.ts")' },
271
+ pattern: { type: 'string' },
272
+ cwd: { type: 'string' },
141
273
  },
142
274
  required: ['pattern'],
143
275
  },
@@ -151,8 +283,9 @@ const TOOL_DEFINITIONS = [
151
283
  parameters: {
152
284
  type: 'object',
153
285
  properties: {
154
- pattern: { type: 'string', description: 'Search pattern (regex)' },
155
- path: { type: 'string', description: 'File or directory to search' },
286
+ pattern: { type: 'string' },
287
+ path: { type: 'string' },
288
+ context: { type: 'number' },
156
289
  },
157
290
  required: ['pattern', 'path'],
158
291
  },
@@ -166,7 +299,8 @@ const TOOL_DEFINITIONS = [
166
299
  parameters: {
167
300
  type: 'object',
168
301
  properties: {
169
- args: { type: 'string', description: 'Git command arguments (e.g. "status", "add .")' },
302
+ args: { type: 'string' },
303
+ cwd: { type: 'string' },
170
304
  },
171
305
  required: ['args'],
172
306
  },
@@ -176,11 +310,12 @@ const TOOL_DEFINITIONS = [
176
310
  type: 'function',
177
311
  function: {
178
312
  name: 'npm',
179
- description: 'Run npm commands.',
313
+ description: 'Run npm/yarn/pnpm/bun commands.',
180
314
  parameters: {
181
315
  type: 'object',
182
316
  properties: {
183
- args: { type: 'string', description: 'Npm command arguments (e.g. "install", "run build")' },
317
+ args: { type: 'string' },
318
+ cwd: { type: 'string' },
184
319
  },
185
320
  required: ['args'],
186
321
  },
@@ -190,12 +325,25 @@ const TOOL_DEFINITIONS = [
190
325
  type: 'function',
191
326
  function: {
192
327
  name: 'deploy',
193
- description: 'Deploy to Vercel.',
328
+ description: 'Deploy to Vercel or Netlify.',
194
329
  parameters: {
195
330
  type: 'object',
196
331
  properties: {
197
- target: { type: 'string', description: 'Deployment target (default: "vercel")' },
332
+ target: { type: 'string', enum: ['vercel', 'netlify'] },
333
+ cwd: { type: 'string' },
198
334
  },
335
+ required: ['target'],
336
+ },
337
+ },
338
+ },
339
+ {
340
+ type: 'function',
341
+ function: {
342
+ name: 'detect_project',
343
+ description: 'Auto-detect project type, framework, and dependencies.',
344
+ parameters: {
345
+ type: 'object',
346
+ properties: { cwd: { type: 'string' } },
199
347
  required: [],
200
348
  },
201
349
  },
@@ -203,109 +351,98 @@ const TOOL_DEFINITIONS = [
203
351
  {
204
352
  type: 'function',
205
353
  function: {
206
- name: 'ask',
207
- description: 'Ask the user for permission or input.',
354
+ name: 'get_file_tree',
355
+ description: 'Get a visual directory tree.',
208
356
  parameters: {
209
357
  type: 'object',
210
358
  properties: {
211
- question: { type: 'string', description: 'Question to ask' },
359
+ path: { type: 'string' },
360
+ depth: { type: 'number' },
212
361
  },
213
- required: ['question'],
362
+ required: ['path'],
214
363
  },
215
364
  },
216
365
  },
217
366
  ];
218
- export class Agent extends EventEmitter {
367
+ // ── Agent Class ─────────────────────────────────────────────────────
368
+ export class Agent {
219
369
  messages = [];
220
370
  config;
221
371
  model;
222
372
  cwd;
223
373
  autoApprove;
224
374
  totalTokens = 0;
225
- constructor(config, model, cwd, autoApprove) {
226
- super();
375
+ effort;
376
+ emitter;
377
+ constructor(config, model, cwd, autoApprove, effort = 'normal') {
227
378
  this.config = config;
228
- this.model = model;
379
+ this.model = 'openrouter/owl-alpha'; // ALWAYS owl-alpha, model param is ignored
229
380
  this.cwd = cwd;
230
381
  this.autoApprove = autoApprove;
231
- this.messages = [{ role: 'system', content: SYSTEM_PROMPT }];
382
+ this.effort = effort;
383
+ this.messages = [{ role: 'system', content: EFFORT_PROMPTS[effort] }];
384
+ }
385
+ on(event, handler) {
386
+ this.emitter = { handler };
387
+ }
388
+ emit(type, data) {
389
+ if (this.emitter)
390
+ this.emitter.handler({ type, ...data });
232
391
  }
233
392
  async run(prompt) {
234
393
  this.messages.push({ role: 'user', content: prompt });
235
- this.emit('event', { type: 'thinking' });
394
+ this.emit('thinking');
236
395
  let iterations = 0;
237
- const maxIterations = 50;
396
+ const maxIterations = this.effort === 'beast' ? 100 : this.effort === 'normal' ? 50 : 20;
238
397
  while (iterations < maxIterations) {
239
398
  iterations++;
240
- const { content, toolCalls, tokens } = await callModel(this.config.openrouterKey, this.model, this.messages, TOOL_DEFINITIONS, (chunk) => this.emit('event', { type: 'text', content: chunk }));
399
+ const { content, toolCalls, tokens } = await callLLM(this.config.openrouterKey, this.messages, TOOL_DEFINITIONS, (chunk) => this.emit('text', { content: chunk }), this.model);
241
400
  this.totalTokens += tokens;
242
401
  this.messages.push({ role: 'assistant', content });
243
402
  if (toolCalls.length === 0) {
244
- // No more tools to call, we're done
245
- this.emit('event', { type: 'done', summary: content });
403
+ this.emit('done', { summary: content });
246
404
  return content;
247
405
  }
248
- // Execute each tool call
249
406
  for (const tc of toolCalls) {
250
407
  const args = JSON.parse(tc.function.arguments || '{}');
251
- this.emit('event', { type: 'tool_start', tool: tc.function.name, args: JSON.stringify(args) });
408
+ this.emit('tool_start', { tool: tc.function.name, args: JSON.stringify(args) });
252
409
  try {
253
410
  const output = await this.executeTool(tc.function.name, args);
254
- this.emit('event', { type: 'tool_end', tool: tc.function.name, output });
255
- this.messages.push({
256
- role: 'tool',
257
- content: output,
258
- tool_call_id: tc.id,
259
- });
411
+ this.emit('tool_end', { tool: tc.function.name, output });
412
+ this.messages.push({ role: 'tool', content: output, tool_call_id: tc.id });
260
413
  }
261
414
  catch (e) {
262
415
  const errMsg = e.message || String(e);
263
- this.emit('event', { type: 'error', message: errMsg });
264
- this.messages.push({
265
- role: 'tool',
266
- content: `Error: ${errMsg}`,
267
- tool_call_id: tc.id,
268
- });
416
+ this.emit('error', { message: errMsg });
417
+ this.messages.push({ role: 'tool', content: `Error: ${errMsg}`, tool_call_id: tc.id });
269
418
  }
270
419
  }
271
420
  }
272
421
  const summary = `Reached max iterations (${maxIterations}). Total tokens: ${this.totalTokens}`;
273
- this.emit('event', { type: 'done', summary });
422
+ this.emit('done', { summary });
274
423
  return summary;
275
424
  }
276
425
  async executeTool(name, args) {
426
+ const tools = await import('./tools/index.js');
427
+ const cwd = args.cwd || this.cwd;
277
428
  switch (name) {
278
- case 'bash':
279
- return tools.runCommand(args.command, this.cwd).stdout;
280
- case 'read_file':
281
- return tools.readFile(args.path);
429
+ case 'run_command': return tools.runCommand(args.command, cwd, args.timeout || 120_000).stdout;
430
+ case 'read_file': return tools.readFile(args.path);
282
431
  case 'write_file':
283
432
  tools.writeFile(args.path, args.content);
284
- return `Wrote ${args.content?.toString().length || 0} chars to ${args.path}`;
433
+ return `Wrote ${args.content.length} chars to ${args.path}`;
285
434
  case 'edit_file':
286
- tools.editFile(args.path, args.old_string, args.new_string);
435
+ tools.editFile(args.path, args.replacements);
287
436
  return `Edited ${args.path}`;
288
- case 'list_dir':
289
- const entries = tools.listDir(args.path);
290
- return entries.map(e => `${e.isDir ? '📁' : '📄'} ${e.name}${e.isDir ? '' : ` (${e.size}B)`}`).join('\n');
291
- case 'search_files':
292
- return tools.searchFiles(args.pattern, this.cwd).join('\n') || 'No files found';
293
- case 'grep':
294
- return tools.grep(args.pattern, args.path).join('\n') || 'No matches';
295
- case 'git':
296
- return tools.git(args.args, this.cwd);
297
- case 'npm':
298
- return tools.npm(args.args, this.cwd);
299
- case 'deploy':
300
- return tools.deployVercel(this.cwd);
301
- case 'ask':
302
- if (this.autoApprove)
303
- return 'yes';
304
- return new Promise((resolve) => {
305
- this.emit('event', { type: 'ask', question: args.question, resolve });
306
- });
307
- default:
308
- throw new Error(`Unknown tool: ${name}`);
437
+ case 'list_dir': return JSON.stringify(tools.listDir(args.path), null, 2);
438
+ case 'search_files': return tools.searchFiles(args.pattern, cwd).join('\n') || 'No files found';
439
+ case 'grep': return tools.grep(args.pattern, args.path, args.context || 2).join('\n') || 'No matches';
440
+ case 'git': return tools.git(args.args, cwd);
441
+ case 'npm': return tools.npm(args.args, cwd);
442
+ case 'deploy': return args.target === 'netlify' ? tools.deployNetlify(cwd) : tools.deployVercel(cwd);
443
+ case 'detect_project': return JSON.stringify(tools.detectProjectType(cwd), null, 2);
444
+ case 'get_file_tree': return tools.getFileTree(args.path, args.depth || 3);
445
+ default: throw new Error(`Unknown tool: ${name}`);
309
446
  }
310
447
  }
311
448
  }
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ // @ts-nocheck
2
3
  import { Command } from 'commander';
3
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
4
5
  import { homedir } from 'os';
@@ -21,21 +22,16 @@ async function ensureConfig() {
21
22
  const existing = await loadConfig();
22
23
  if (existing)
23
24
  return existing;
24
- const defaults = {
25
- openrouterKey: '',
26
- defaultModel: 'openrouter/owl-alpha',
27
- codingModel: 'moonshotai/kimi-k2.6',
28
- fastModel: 'openai/gpt-oss-20b:free',
29
- };
25
+ const defaults = { openrouterKey: '', defaultEffort: 'normal' };
30
26
  writeFileSync(CONFIG_FILE, JSON.stringify(defaults, null, 2));
31
27
  return defaults;
32
28
  }
33
29
  const program = new Command();
34
- program.name('lumina').description('Lumina Code - AI coding agent').version('1.0.0');
30
+ program.name('lumina').description('Lumina Code AI coding agent').version('1.0.0');
35
31
  program.command('code')
36
32
  .description('Start Lumina Code agent')
37
33
  .argument('[prompt]', 'What you want to build')
38
- .option('-m, --model <model>', 'Model to use')
34
+ .option('-e, --effort <level>', 'Effort level: quick, normal, beast', 'normal')
39
35
  .option('-y, --yes', 'Auto-approve all actions')
40
36
  .option('--cwd <dir>', 'Working directory', process.cwd())
41
37
  .action(async (prompt, opts) => {
@@ -46,31 +42,25 @@ program.command('code')
46
42
  console.error(' Get a key at: https://openrouter.ai/keys\n');
47
43
  process.exit(1);
48
44
  }
49
- // Dynamic require to avoid ESM issues
50
- const { TUIApp } = require('./tui/index');
51
- const { render } = require('ink');
52
- const React = require('react');
53
- render(React.createElement(TUIApp, {
54
- prompt,
55
- config,
56
- model: opts.model || config.defaultModel || 'openrouter/owl-alpha',
57
- autoApprove: opts.yes || false,
58
- cwd: opts.cwd,
59
- }));
45
+ const effort = ['quick', 'normal', 'beast'].includes(opts.effort) ? opts.effort : 'normal';
46
+ const { TUIApp } = await import('./tui/index.js');
47
+ const { render } = await import('ink');
48
+ const React = await import('react');
49
+ render(React.createElement(TUIApp, { prompt, config, effort, autoApprove: opts.yes || false, cwd: opts.cwd }));
60
50
  });
61
51
  program.command('config').description('Show configuration').action(async () => {
62
52
  const config = await ensureConfig();
63
53
  console.log('\n Lumina Code Configuration\n');
64
54
  console.log(' Config:', CONFIG_FILE);
65
55
  console.log(' API Key:', config.openrouterKey ? 'Set (' + config.openrouterKey.slice(0, 8) + '...)' : 'NOT SET');
66
- console.log(' Default:', config.defaultModel || 'openrouter/owl-alpha');
67
- console.log(' Coding:', config.codingModel || 'moonshotai/kimi-k2.6');
68
- console.log(' Fast:', config.fastModel || 'openai/gpt-oss-20b:free\n');
56
+ console.log(' Default Effort:', config.defaultEffort || 'normal');
57
+ console.log('\n Commands:');
58
+ console.log(' lumina config set openrouter-key <key>');
59
+ console.log(' lumina config set default-effort <quick|normal|beast>\n');
69
60
  });
70
61
  program.command('config set <key> <value>').description('Set config value').action(async (key, value) => {
71
62
  const config = await ensureConfig();
72
- const map = { 'openrouter-key': 'openrouterKey', 'default-model': 'defaultModel', 'coding-model': 'codingModel', 'fast-model': 'fastModel' };
73
- config[map[key] || key] = value;
63
+ config[key] = value;
74
64
  writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
75
65
  console.log(' Set', key, '=', value);
76
66
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumina-code-agent",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Lumina Code - AI coding agent",
5
5
  "license": "MIT",
6
6
  "type": "module",