lumina-code-agent 1.6.7 → 1.6.9
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/dist/index.js +53 -48
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,38 +34,21 @@ async function onboarding() {
|
|
|
34
34
|
saveConfig({ openrouterKey: apiKey.trim(), userName: name.trim() || 'User' });
|
|
35
35
|
console.log(' ✓ Ready!\n');
|
|
36
36
|
}
|
|
37
|
-
// ── Extract files from complete model output ────────────────────────
|
|
38
37
|
function extractFiles(text) {
|
|
39
38
|
const files = [];
|
|
40
|
-
// Match FILENAME: path\n...content...END FILE
|
|
41
39
|
const fileRegex = /FILENAME:\s*([^\n]+)\n([\s\S]*?)END FILE/g;
|
|
42
40
|
let match;
|
|
43
41
|
while ((match = fileRegex.exec(text)) !== null) {
|
|
44
42
|
const rawPath = match[1].trim();
|
|
45
43
|
const content = match[2].trim();
|
|
46
|
-
// Skip if it's a directory path (no extension or ends with /)
|
|
47
44
|
if (!rawPath || rawPath.endsWith('/') || !extname(rawPath))
|
|
48
45
|
continue;
|
|
49
|
-
// Skip if path contains invalid chars
|
|
50
46
|
if (rawPath.includes('<') || rawPath.includes('>') || rawPath.includes('"'))
|
|
51
47
|
continue;
|
|
52
48
|
files.push({ path: rawPath, content });
|
|
53
49
|
}
|
|
54
|
-
// Also match ```filename ... ``` code blocks
|
|
55
|
-
const blockRegex = /```([\w./\-_]+)\n([\s\S]*?)```/g;
|
|
56
|
-
while ((match = blockRegex.exec(text)) !== null) {
|
|
57
|
-
const rawPath = match[1].trim();
|
|
58
|
-
const content = match[2].trim();
|
|
59
|
-
if (!rawPath || rawPath.endsWith('/') || !extname(rawPath))
|
|
60
|
-
continue;
|
|
61
|
-
// Skip common non-file patterns
|
|
62
|
-
if (rawPath.startsWith('http') || rawPath.includes('node_modules'))
|
|
63
|
-
continue;
|
|
64
|
-
files.push({ path: rawPath, content });
|
|
65
|
-
}
|
|
66
50
|
return files;
|
|
67
51
|
}
|
|
68
|
-
// ── Chat Loop ───────────────────────────────────────────────────────
|
|
69
52
|
async function chat(config) {
|
|
70
53
|
console.log(' Type what you want to build. I\'ll handle the rest.');
|
|
71
54
|
console.log(' Commands: /help /clear /files /exit\n');
|
|
@@ -97,9 +80,9 @@ async function chat(config) {
|
|
|
97
80
|
console.log(' /help /clear /files /exit\n');
|
|
98
81
|
continue;
|
|
99
82
|
}
|
|
100
|
-
const systemPrompt = `You are LUMINA CODE.
|
|
83
|
+
const systemPrompt = `You are LUMINA CODE. Create COMPLETE production-grade websites.
|
|
101
84
|
|
|
102
|
-
|
|
85
|
+
OUTPUT FORMAT — Use this EXACT format for EVERY file:
|
|
103
86
|
|
|
104
87
|
FILENAME: index.html
|
|
105
88
|
<!DOCTYPE html>
|
|
@@ -111,36 +94,37 @@ FILENAME: index.html
|
|
|
111
94
|
<link rel="stylesheet" href="style.css">
|
|
112
95
|
</head>
|
|
113
96
|
<body>
|
|
114
|
-
<!-- Complete HTML -->
|
|
97
|
+
<!-- Complete HTML here -->
|
|
98
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
|
115
99
|
<script src="script.js"></script>
|
|
116
100
|
</body>
|
|
117
101
|
</html>
|
|
118
102
|
END FILE
|
|
119
103
|
|
|
120
104
|
FILENAME: style.css
|
|
121
|
-
/* Complete CSS */
|
|
105
|
+
/* Complete CSS here */
|
|
122
106
|
END FILE
|
|
123
107
|
|
|
124
108
|
FILENAME: script.js
|
|
125
|
-
// Complete JavaScript
|
|
109
|
+
// Complete JavaScript here
|
|
126
110
|
END FILE
|
|
127
111
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
9. No placeholders, no TODOs, no lorem ipsum
|
|
112
|
+
RULES:
|
|
113
|
+
- Start IMMEDIATELY with FILENAME: index.html
|
|
114
|
+
- Output COMPLETE files — every line, no truncation
|
|
115
|
+
- Do NOT describe what you will do — JUST DO IT
|
|
116
|
+
- Do NOT output any text before FILENAME:
|
|
117
|
+
- Do NOT use markdown code blocks
|
|
118
|
+
- Create ALL files needed for a complete working project
|
|
119
|
+
- Use Three.js from CDN for 3D
|
|
120
|
+
- No placeholders, no TODOs, no lorem ipsum
|
|
138
121
|
|
|
139
122
|
Working directory: ${process.cwd()}`;
|
|
140
|
-
console.log('
|
|
123
|
+
console.log('');
|
|
124
|
+
console.log(' ⏳ Generating...');
|
|
141
125
|
try {
|
|
142
126
|
const controller = new AbortController();
|
|
143
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
127
|
+
const timeout = setTimeout(() => controller.abort(), 600000); // 10 min timeout
|
|
144
128
|
const res = await fetch('https://openrouter.ai/api/v1/chat/completions', {
|
|
145
129
|
method: 'POST',
|
|
146
130
|
headers: {
|
|
@@ -156,7 +140,7 @@ Working directory: ${process.cwd()}`;
|
|
|
156
140
|
{ role: 'user', content: trimmed },
|
|
157
141
|
],
|
|
158
142
|
stream: false,
|
|
159
|
-
max_tokens:
|
|
143
|
+
max_tokens: 65000,
|
|
160
144
|
temperature: 0.1,
|
|
161
145
|
}),
|
|
162
146
|
signal: controller.signal,
|
|
@@ -166,26 +150,47 @@ Working directory: ${process.cwd()}`;
|
|
|
166
150
|
const err = await res.text().catch(() => '');
|
|
167
151
|
throw new Error(`API error ${res.status}: ${err.slice(0, 200)}`);
|
|
168
152
|
}
|
|
169
|
-
|
|
153
|
+
// Read response as text first, then parse
|
|
154
|
+
const rawText = await res.text();
|
|
155
|
+
let data;
|
|
156
|
+
try {
|
|
157
|
+
data = JSON.parse(rawText);
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
// If JSON is truncated, try to fix it
|
|
161
|
+
console.log(' ⚠ Response was truncated. Attempting to parse...');
|
|
162
|
+
// Try to find the last complete JSON object
|
|
163
|
+
const lastBrace = rawText.lastIndexOf('}');
|
|
164
|
+
if (lastBrace > 0) {
|
|
165
|
+
try {
|
|
166
|
+
data = JSON.parse(rawText.slice(0, lastBrace + 1));
|
|
167
|
+
}
|
|
168
|
+
catch (e2) {
|
|
169
|
+
throw new Error('Response was truncated and could not be parsed. Try a shorter prompt.');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
throw new Error('Response was truncated. Try a shorter prompt.');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
170
176
|
const content = data.choices?.[0]?.message?.content || '';
|
|
171
177
|
if (!content) {
|
|
172
178
|
console.log(' ⚠ No response from model.\n');
|
|
173
179
|
continue;
|
|
174
180
|
}
|
|
175
|
-
|
|
176
|
-
console.log(' 📝 Model output preview:');
|
|
177
|
-
console.log(' ' + content.slice(0, 200).replace(/\n/g, '\n '));
|
|
178
|
-
console.log('');
|
|
179
|
-
// Extract and create files
|
|
181
|
+
console.log(` ✓ AI responded (${content.length} chars)`);
|
|
180
182
|
const files = extractFiles(content);
|
|
181
183
|
if (files.length === 0) {
|
|
182
|
-
console.log(' ⚠ No files detected in output
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
console.log('');
|
|
184
|
+
console.log(' ⚠ No files detected in output.\n');
|
|
185
|
+
// Show first 50 lines of output
|
|
186
|
+
const lines = content.split('\n').slice(0, 50);
|
|
187
|
+
console.log(' ── Output preview ──');
|
|
188
|
+
for (const line of lines)
|
|
189
|
+
console.log(' ' + line);
|
|
190
|
+
console.log(' ── End ──\n');
|
|
186
191
|
continue;
|
|
187
192
|
}
|
|
188
|
-
console.log(` 📁 Creating ${files.length} file(s)
|
|
193
|
+
console.log(` 📁 Creating ${files.length} file(s):\n`);
|
|
189
194
|
for (const file of files) {
|
|
190
195
|
try {
|
|
191
196
|
const filePath = join(process.cwd(), file.path);
|
|
@@ -194,10 +199,10 @@ Working directory: ${process.cwd()}`;
|
|
|
194
199
|
mkdirSync(dir, { recursive: true });
|
|
195
200
|
writeFileSync(filePath, file.content, 'utf-8');
|
|
196
201
|
createdFiles.add(file.path);
|
|
197
|
-
console.log(`
|
|
202
|
+
console.log(` ✅ ${file.path} (${file.content.length} chars)`);
|
|
198
203
|
}
|
|
199
204
|
catch (e) {
|
|
200
|
-
console.log(`
|
|
205
|
+
console.log(` ❌ ${file.path}: ${e.message}`);
|
|
201
206
|
}
|
|
202
207
|
}
|
|
203
208
|
console.log(`\n 📊 Total files: ${createdFiles.size}\n`);
|