vibecodingmachine-core 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +13 -13
- package/README.md +28 -28
- package/__tests__/applescript-manager-claude-fix.test.js +286 -286
- package/__tests__/requirement-2-auto-start-looping.test.js +69 -69
- package/__tests__/requirement-3-auto-start-looping.test.js +69 -69
- package/__tests__/requirement-4-auto-start-looping.test.js +69 -69
- package/__tests__/requirement-6-auto-start-looping.test.js +73 -73
- package/__tests__/requirement-7-status-tracking.test.js +332 -332
- package/jest.config.js +18 -18
- package/jest.setup.js +12 -12
- package/package.json +47 -45
- package/src/auth/access-denied.html +119 -119
- package/src/auth/shared-auth-storage.js +230 -230
- package/src/autonomous-mode/feature-implementer.cjs +70 -70
- package/src/autonomous-mode/feature-implementer.js +425 -425
- package/src/chat-management/chat-manager.cjs +71 -71
- package/src/chat-management/chat-manager.js +342 -342
- package/src/ide-integration/__tests__/applescript-manager-thread-closure.test.js +227 -227
- package/src/ide-integration/aider-cli-manager.cjs +850 -850
- package/src/ide-integration/applescript-manager.cjs +1088 -1088
- package/src/ide-integration/applescript-manager.js +2802 -2802
- package/src/ide-integration/applescript-utils.js +306 -306
- package/src/ide-integration/cdp-manager.cjs +221 -221
- package/src/ide-integration/cdp-manager.js +321 -321
- package/src/ide-integration/claude-code-cli-manager.cjs +301 -301
- package/src/ide-integration/cline-cli-manager.cjs +2252 -2252
- package/src/ide-integration/continue-cli-manager.js +431 -431
- package/src/ide-integration/provider-manager.cjs +354 -354
- package/src/ide-integration/quota-detector.cjs +34 -34
- package/src/ide-integration/quota-detector.js +349 -349
- package/src/ide-integration/windows-automation-manager.js +262 -262
- package/src/index.cjs +43 -43
- package/src/index.js +17 -17
- package/src/llm/direct-llm-manager.cjs +609 -609
- package/src/ui/ButtonComponents.js +247 -247
- package/src/ui/ChatInterface.js +499 -499
- package/src/ui/StateManager.js +259 -259
- package/src/utils/audit-logger.cjs +116 -116
- package/src/utils/config-helpers.cjs +94 -94
- package/src/utils/config-helpers.js +94 -94
- package/src/utils/electron-update-checker.js +85 -78
- package/src/utils/gcloud-auth.cjs +394 -394
- package/src/utils/logger.cjs +193 -193
- package/src/utils/logger.js +191 -191
- package/src/utils/repo-helpers.cjs +120 -120
- package/src/utils/repo-helpers.js +120 -120
- package/src/utils/requirement-helpers.js +432 -432
- package/src/utils/update-checker.js +167 -167
|
@@ -1,431 +1,431 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Continue CLI Manager - Handles Continue CLI integration for auto mode
|
|
3
|
-
* Shared between Electron app and CLI package for DRY code
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const os = require('os');
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Run Continue CLI command with PTY support
|
|
11
|
-
* @param {string} repoPath - Repository path
|
|
12
|
-
* @param {string} prompt - Prompt to send to Continue CLI
|
|
13
|
-
* @param {string} reqFilename - Requirements filename (e.g., REQUIREMENTS-hostname.md)
|
|
14
|
-
* @returns {Promise<{success: boolean, output: string, error?: string, hasError?: boolean, exitCode?: number}>}
|
|
15
|
-
*/
|
|
16
|
-
async function runContinueCLICommand(repoPath, prompt, reqFilename) {
|
|
17
|
-
return new Promise((resolve) => {
|
|
18
|
-
// Try to use node-pty for PTY support (required for Continue CLI's Ink UI)
|
|
19
|
-
let pty;
|
|
20
|
-
try {
|
|
21
|
-
pty = require('node-pty');
|
|
22
|
-
} catch (error) {
|
|
23
|
-
// node-pty not available, fall back to regular spawn
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const command = 'cn';
|
|
27
|
-
const configPath = path.join(os.homedir(), '.continue', 'config.yaml');
|
|
28
|
-
|
|
29
|
-
// Prepend working directory context to prompt so Continue CLI knows where to find files
|
|
30
|
-
const promptWithContext = `IMPORTANT: You are working in the repository at: ${repoPath}
|
|
31
|
-
|
|
32
|
-
All file paths should be relative to this directory. The .vibecodingmachine directory is located at: ${path.join(repoPath, '.vibecodingmachine')}
|
|
33
|
-
|
|
34
|
-
The requirements file for this computer is: .vibecodingmachine/${reqFilename}
|
|
35
|
-
|
|
36
|
-
CRITICAL FILE OPERATIONS:
|
|
37
|
-
- Use the "Read" tool to read local files (NOT the Fetch tool - Fetch is only for URLs)
|
|
38
|
-
- Use the "Write" tool to write local files
|
|
39
|
-
- File paths are local filesystem paths, NOT URLs
|
|
40
|
-
- Example: To read the requirements file, use: Read(.vibecodingmachine/${reqFilename})
|
|
41
|
-
- DO NOT use Fetch for local files - Fetch is only for HTTP/HTTPS URLs
|
|
42
|
-
|
|
43
|
-
${prompt}`;
|
|
44
|
-
|
|
45
|
-
// Try headless mode (-p) for better autonomous execution
|
|
46
|
-
// The --auto flag doesn't seem to execute, it just analyzes
|
|
47
|
-
const args = ['-p', promptWithContext, '--config', configPath];
|
|
48
|
-
|
|
49
|
-
let output = '';
|
|
50
|
-
let errorOutput = '';
|
|
51
|
-
|
|
52
|
-
console.log('\n─────────────────────────────────────────────────────────');
|
|
53
|
-
console.log('Continue CLI Output:');
|
|
54
|
-
console.log('─────────────────────────────────────────────────────────');
|
|
55
|
-
console.log('\n⚠️ Note: Do not type in the terminal while Continue CLI is running.');
|
|
56
|
-
console.log(' Your input will be sent to Continue CLI and may interfere with auto mode.\n');
|
|
57
|
-
|
|
58
|
-
let proc;
|
|
59
|
-
|
|
60
|
-
// With -p (headless) mode, we might not need PTY, but let's try PTY first
|
|
61
|
-
// If it fails, we'll fall back to regular spawn
|
|
62
|
-
if (pty) {
|
|
63
|
-
// Use PTY for Continue CLI (may still be needed even in headless mode)
|
|
64
|
-
proc = pty.spawn(command, args, {
|
|
65
|
-
name: 'xterm-color',
|
|
66
|
-
cols: 120,
|
|
67
|
-
rows: 30,
|
|
68
|
-
cwd: repoPath,
|
|
69
|
-
env: process.env
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// Track output to detect if Continue CLI is idle/waiting
|
|
73
|
-
let lastOutputTime = Date.now();
|
|
74
|
-
const maxIdleTime = 30000; // 30 seconds max idle time (reduced from 1 minute)
|
|
75
|
-
let idleCheckInterval;
|
|
76
|
-
let promptDetected = false;
|
|
77
|
-
let promptCheckTimeout;
|
|
78
|
-
|
|
79
|
-
// PTY uses onData instead of stdout.on('data')
|
|
80
|
-
proc.onData((data) => {
|
|
81
|
-
output += data;
|
|
82
|
-
process.stdout.write(data);
|
|
83
|
-
lastOutputTime = Date.now(); // Update last output time
|
|
84
|
-
|
|
85
|
-
// Detect if Continue CLI is showing the interactive prompt
|
|
86
|
-
const dataStr = data.toString();
|
|
87
|
-
if (dataStr.includes('[⏵⏵ auto]') || dataStr.includes('Ask anything') ||
|
|
88
|
-
dataStr.includes('Context:') || (dataStr.includes('auto') && dataStr.includes('Continue CLI'))) {
|
|
89
|
-
if (!promptDetected) {
|
|
90
|
-
promptDetected = true;
|
|
91
|
-
// Wait for prompt to fully render, then send a command to make it proceed
|
|
92
|
-
promptCheckTimeout = setTimeout(() => {
|
|
93
|
-
const timeSinceLastOutput = Date.now() - lastOutputTime;
|
|
94
|
-
// If no output for 3 seconds after prompt, send a command to proceed
|
|
95
|
-
if (timeSinceLastOutput > 3000) {
|
|
96
|
-
console.log('\n📤 Sending command to Continue CLI to proceed with implementation...\n');
|
|
97
|
-
// Send a command to Continue CLI to actually work on the requirement
|
|
98
|
-
try {
|
|
99
|
-
// Send a direct command to proceed with implementation
|
|
100
|
-
const proceedCommand = 'Implement the requirement. Read the REQUIREMENTS file, work through PREPARE → ACT → CLEAN UP → VERIFY → DONE stages, and update the REQUIREMENTS file at each stage using the Write tool.\n';
|
|
101
|
-
proc.write(proceedCommand);
|
|
102
|
-
lastOutputTime = Date.now(); // Reset timer since we sent input
|
|
103
|
-
} catch (error) {
|
|
104
|
-
console.log('\n⚠️ Could not send command to Continue CLI:', error.message);
|
|
105
|
-
console.log(' Stopping Continue CLI process...\n');
|
|
106
|
-
proc.kill();
|
|
107
|
-
if (idleCheckInterval) clearInterval(idleCheckInterval);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}, 3000); // Wait 3 seconds after prompt detection before sending command
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// Set up idle detection - kill if no output for too long
|
|
116
|
-
const checkIdle = () => {
|
|
117
|
-
const timeSinceLastOutput = Date.now() - lastOutputTime;
|
|
118
|
-
if (timeSinceLastOutput > maxIdleTime) {
|
|
119
|
-
console.log('\n⚠️ Continue CLI has been idle for too long. It may be waiting for input.');
|
|
120
|
-
console.log(' Stopping Continue CLI process...\n');
|
|
121
|
-
proc.kill();
|
|
122
|
-
clearInterval(idleCheckInterval);
|
|
123
|
-
if (promptCheckTimeout) clearTimeout(promptCheckTimeout);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
// Start idle checking every 5 seconds (very frequent)
|
|
128
|
-
idleCheckInterval = setInterval(checkIdle, 5000);
|
|
129
|
-
|
|
130
|
-
proc.onExit(({ exitCode }) => {
|
|
131
|
-
// Clean up idle checker and timeout
|
|
132
|
-
if (idleCheckInterval) {
|
|
133
|
-
clearInterval(idleCheckInterval);
|
|
134
|
-
}
|
|
135
|
-
if (promptCheckTimeout) {
|
|
136
|
-
clearTimeout(promptCheckTimeout);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const fullOutput = output;
|
|
140
|
-
console.log('\n─────────────────────────────────────────────────────────\n');
|
|
141
|
-
|
|
142
|
-
// Check for common errors
|
|
143
|
-
const hasAnthropicError = fullOutput.includes('ANTHROPIC_API_KEY') || fullOutput.includes('404');
|
|
144
|
-
const hasAuthError = fullOutput.includes('authentication') && fullOutput.includes('error');
|
|
145
|
-
|
|
146
|
-
if (hasAnthropicError) {
|
|
147
|
-
console.log('\n⚠️ Continue CLI could not find Ollama configuration.');
|
|
148
|
-
console.log(' Please ensure:');
|
|
149
|
-
console.log(' 1. Ollama is running (ollama serve)');
|
|
150
|
-
console.log(' 2. ~/.continue/config.yaml is configured with Ollama models');
|
|
151
|
-
console.log(' 3. Models are downloaded (ollama pull model-name)\n');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
resolve({
|
|
155
|
-
success: !hasAnthropicError && !hasAuthError,
|
|
156
|
-
output: fullOutput,
|
|
157
|
-
exitCode: exitCode,
|
|
158
|
-
hasError: hasAnthropicError || hasAuthError
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
} else {
|
|
162
|
-
// Fallback to regular spawn (without PTY)
|
|
163
|
-
const { spawn } = require('child_process');
|
|
164
|
-
proc = spawn(command, args, {
|
|
165
|
-
cwd: repoPath,
|
|
166
|
-
stdio: ['pipe', 'pipe', 'pipe']
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
// Close stdin immediately since we're not interactive
|
|
170
|
-
proc.stdin.end();
|
|
171
|
-
|
|
172
|
-
proc.stdout.on('data', (data) => {
|
|
173
|
-
output += data.toString();
|
|
174
|
-
process.stdout.write(data);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
proc.stderr.on('data', (data) => {
|
|
178
|
-
errorOutput += data.toString();
|
|
179
|
-
process.stderr.write(data);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
proc.on('close', (code) => {
|
|
183
|
-
console.log('\n─────────────────────────────────────────────────────────\n');
|
|
184
|
-
|
|
185
|
-
// Check for errors
|
|
186
|
-
const fullOutput = output + errorOutput;
|
|
187
|
-
const hasAnthropicError = fullOutput.includes('ANTHROPIC_API_KEY') || fullOutput.includes('404');
|
|
188
|
-
const hasAuthError = fullOutput.includes('authentication') && fullOutput.includes('error');
|
|
189
|
-
const hasRawModeError = fullOutput.includes('Raw mode is not supported');
|
|
190
|
-
|
|
191
|
-
if (hasRawModeError) {
|
|
192
|
-
console.log('\n⚠️ Continue CLI requires PTY support (node-pty package).');
|
|
193
|
-
console.log(' Install with: npm install node-pty\n');
|
|
194
|
-
} else if (hasAnthropicError) {
|
|
195
|
-
console.log('\n⚠️ Continue CLI could not find Ollama configuration.');
|
|
196
|
-
console.log(' Please ensure:');
|
|
197
|
-
console.log(' 1. Ollama is running (ollama serve)');
|
|
198
|
-
console.log(' 2. ~/.continue/config.yaml is configured with Ollama models');
|
|
199
|
-
console.log(' 3. Models are downloaded (ollama pull model-name)\n');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
resolve({
|
|
203
|
-
success: code === 0 && !hasAnthropicError && !hasAuthError && !hasRawModeError,
|
|
204
|
-
output: fullOutput,
|
|
205
|
-
error: code !== 0 ? errorOutput : undefined,
|
|
206
|
-
exitCode: code,
|
|
207
|
-
hasError: hasAnthropicError || hasAuthError || hasRawModeError
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
proc.on('error', (error) => {
|
|
212
|
-
console.log('\n─────────────────────────────────────────────────────────\n');
|
|
213
|
-
console.log(`\n✗ Failed to start Continue CLI: ${error.message}\n`);
|
|
214
|
-
|
|
215
|
-
if (error.code === 'ENOENT') {
|
|
216
|
-
console.log(' Continue CLI (cn command) not found.');
|
|
217
|
-
console.log(' Install with: npm install -g @continuedev/continue-cli\n');
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
resolve({
|
|
221
|
-
success: false,
|
|
222
|
-
output: '',
|
|
223
|
-
error: error.message,
|
|
224
|
-
hasError: true
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Run Continue CLI in auto mode loop
|
|
233
|
-
* @param {string} repoPath - Repository path
|
|
234
|
-
* @param {string} initialPrompt - Initial prompt to send
|
|
235
|
-
* @param {object} config - Auto mode configuration
|
|
236
|
-
* @param {string} config.ide - IDE type ('continue')
|
|
237
|
-
* @param {number|null} config.maxChats - Maximum chats (null for unlimited)
|
|
238
|
-
* @param {boolean} config.neverStop - Never stop flag
|
|
239
|
-
* @param {function} updateAutoModeStatus - Callback to update auto mode status
|
|
240
|
-
* @param {function} isRequirementDone - Callback to check if requirement is done
|
|
241
|
-
* @param {function} moveToNextRequirement - Callback to move to next requirement
|
|
242
|
-
* @returns {Promise<void>}
|
|
243
|
-
*/
|
|
244
|
-
async function runContinueCLIAutoMode(repoPath, initialPrompt, config, callbacks) {
|
|
245
|
-
const { updateAutoModeStatus, isRequirementDone, moveToNextRequirement } = callbacks;
|
|
246
|
-
const { getRequirementsPath } = require('../utils/repo-helpers.cjs');
|
|
247
|
-
const fs = require('fs-extra');
|
|
248
|
-
|
|
249
|
-
let chatCount = 0;
|
|
250
|
-
let currentPrompt = initialPrompt;
|
|
251
|
-
const maxChats = config.maxChats || 100;
|
|
252
|
-
const neverStop = config.neverStop || false;
|
|
253
|
-
let exitReason = 'completed';
|
|
254
|
-
|
|
255
|
-
console.log(' Auto mode will continue until DONE status is reached');
|
|
256
|
-
console.log(` Max chats: ${neverStop ? 'unlimited' : maxChats}`);
|
|
257
|
-
console.log();
|
|
258
|
-
|
|
259
|
-
while (true) {
|
|
260
|
-
// Check max chats
|
|
261
|
-
if (!neverStop && chatCount >= maxChats) {
|
|
262
|
-
console.log(`\n⏹️ Reached max chats limit (${maxChats})`);
|
|
263
|
-
exitReason = 'max-chats';
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
chatCount++;
|
|
268
|
-
console.log(`\n📝 Chat ${chatCount}${neverStop ? '' : `/${maxChats}`}: ${currentPrompt.substring(0, 60)}${currentPrompt.length > 60 ? '...' : ''}`);
|
|
269
|
-
console.log(' Running Continue CLI...\n');
|
|
270
|
-
|
|
271
|
-
// Update auto mode status
|
|
272
|
-
await updateAutoModeStatus(repoPath, { chatCount });
|
|
273
|
-
|
|
274
|
-
// Get the computer-specific requirements filename
|
|
275
|
-
const reqPath = await getRequirementsPath(repoPath);
|
|
276
|
-
const reqFilename = path.basename(reqPath);
|
|
277
|
-
|
|
278
|
-
// Read current requirement and status from REQUIREMENTS file
|
|
279
|
-
let currentRequirementText = '';
|
|
280
|
-
let currentStatus = '';
|
|
281
|
-
try {
|
|
282
|
-
if (await fs.pathExists(reqPath)) {
|
|
283
|
-
const content = await fs.readFile(reqPath, 'utf8');
|
|
284
|
-
const lines = content.split('\n');
|
|
285
|
-
|
|
286
|
-
// Find current in-progress requirement
|
|
287
|
-
let inProgressSection = false;
|
|
288
|
-
for (let i = 0; i < lines.length; i++) {
|
|
289
|
-
if (lines[i].includes('## 🔨 Current In Progress Requirement')) {
|
|
290
|
-
inProgressSection = true;
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
if (inProgressSection && lines[i].trim().startsWith('- ')) {
|
|
294
|
-
currentRequirementText = lines[i].substring(2).trim();
|
|
295
|
-
break;
|
|
296
|
-
}
|
|
297
|
-
if (inProgressSection && lines[i].startsWith('##')) {
|
|
298
|
-
break;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Find current status
|
|
303
|
-
for (let i = 0; i < lines.length; i++) {
|
|
304
|
-
if (lines[i].includes('## 🚦 Current Status')) {
|
|
305
|
-
for (let j = i + 1; j < lines.length; j++) {
|
|
306
|
-
const statusLine = lines[j].trim();
|
|
307
|
-
if (statusLine && !statusLine.startsWith('#')) {
|
|
308
|
-
currentStatus = statusLine;
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
} catch (error) {
|
|
317
|
-
// Continue without current requirement if file read fails
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// Build enhanced prompt with current requirement context
|
|
321
|
-
const enhancedPrompt = currentRequirementText ?
|
|
322
|
-
`${currentPrompt}
|
|
323
|
-
|
|
324
|
-
🚨 FOCUS: You MUST work ONLY on this ONE requirement:
|
|
325
|
-
|
|
326
|
-
"${currentRequirementText}"
|
|
327
|
-
|
|
328
|
-
CURRENT STATUS: ${currentStatus || 'PREPARE'}
|
|
329
|
-
|
|
330
|
-
⚠️ CRITICAL - DO NOT SUMMARIZE OR ANALYZE OTHER REQUIREMENTS:
|
|
331
|
-
- IGNORE all other requirements in the REQUIREMENTS file
|
|
332
|
-
- IGNORE completed requirements, CHANGELOG entries, and other sections
|
|
333
|
-
- FOCUS EXCLUSIVELY on implementing the requirement listed above
|
|
334
|
-
- DO NOT read the entire REQUIREMENTS file and summarize it
|
|
335
|
-
- Read ONLY the specific sections you need to understand the current requirement
|
|
336
|
-
|
|
337
|
-
🚨 STEP-BY-STEP WORKFLOW:
|
|
338
|
-
1. Read INSTRUCTIONS.md (.vibecodingmachine/INSTRUCTIONS.md) to understand the workflow
|
|
339
|
-
2. Read ONLY the "🔨 Current In Progress Requirement" section from REQUIREMENTS file to see the current requirement
|
|
340
|
-
3. Read ONLY the "🚦 Current Status" section to see the current status
|
|
341
|
-
4. Start working on "${currentRequirementText}" based on the current status:
|
|
342
|
-
- If status is PREPARE: Start planning and preparing
|
|
343
|
-
- If status is ACT: Start implementing the code
|
|
344
|
-
- If status is CLEAN UP: Clean up code, remove duplicates, apply DRY
|
|
345
|
-
- If status is VERIFY: Test and verify the implementation
|
|
346
|
-
- If status is DONE: Stop immediately (work is complete)
|
|
347
|
-
5. At EACH stage transition, use the Write tool to UPDATE the REQUIREMENTS file:
|
|
348
|
-
- Set "🚦 Current Status" to the NEXT stage (PREPARE → ACT → CLEAN UP → VERIFY → DONE)
|
|
349
|
-
- Update the "RESPONSE FROM LAST CHAT" section with what you accomplished
|
|
350
|
-
6. Continue until status is DONE
|
|
351
|
-
7. You have FULL WRITE ACCESS - use Write tool to update the REQUIREMENTS file
|
|
352
|
-
|
|
353
|
-
REMEMBER: You are working on ONE requirement: "${currentRequirementText}". Ignore everything else.` :
|
|
354
|
-
currentPrompt;
|
|
355
|
-
|
|
356
|
-
// Run Continue CLI command with enhanced prompt
|
|
357
|
-
const result = await runContinueCLICommand(repoPath, enhancedPrompt, reqFilename);
|
|
358
|
-
|
|
359
|
-
if (result.hasError || (!result.success && result.error)) {
|
|
360
|
-
console.log(`\n✗ Continue CLI encountered an error: ${result.error || 'Unknown error'}`);
|
|
361
|
-
if (result.hasError) {
|
|
362
|
-
console.log('\n⚠️ Please fix the configuration issue and try again.');
|
|
363
|
-
}
|
|
364
|
-
exitReason = 'error';
|
|
365
|
-
break;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
console.log('\n✓ Continue CLI completed');
|
|
369
|
-
|
|
370
|
-
// Wait a moment for file system to sync
|
|
371
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
372
|
-
|
|
373
|
-
// Check if requirement is DONE
|
|
374
|
-
const isDone = await isRequirementDone(repoPath);
|
|
375
|
-
|
|
376
|
-
if (isDone) {
|
|
377
|
-
console.log('\n✅ Requirement marked as DONE!');
|
|
378
|
-
|
|
379
|
-
// Move to next requirement
|
|
380
|
-
const moveResult = await moveToNextRequirement(repoPath);
|
|
381
|
-
|
|
382
|
-
if (!moveResult.success) {
|
|
383
|
-
console.log(`\n⚠️ ${moveResult.error}`);
|
|
384
|
-
console.log(' Auto mode stopping.');
|
|
385
|
-
exitReason = 'error';
|
|
386
|
-
break;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
console.log(`\n🔄 Moving to next requirement: ${moveResult.nextRequirement}`);
|
|
390
|
-
|
|
391
|
-
// Prepare next prompt
|
|
392
|
-
currentPrompt = initialPrompt;
|
|
393
|
-
|
|
394
|
-
// Wait a moment before next iteration
|
|
395
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
396
|
-
} else {
|
|
397
|
-
console.log('\n⚠️ Requirement not yet DONE. Continue CLI may still be working or needs to update status.');
|
|
398
|
-
console.log(' Waiting for DONE status before continuing...');
|
|
399
|
-
|
|
400
|
-
// Wait longer before checking again
|
|
401
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
402
|
-
|
|
403
|
-
// Check again
|
|
404
|
-
const stillNotDone = !(await isRequirementDone(repoPath));
|
|
405
|
-
if (stillNotDone) {
|
|
406
|
-
console.log('\n⚠️ Status still not DONE after waiting. Moving to next iteration.');
|
|
407
|
-
|
|
408
|
-
// Move to next requirement anyway
|
|
409
|
-
const moveResult = await moveToNextRequirement(repoPath);
|
|
410
|
-
|
|
411
|
-
if (!moveResult.success) {
|
|
412
|
-
console.log(`\n⚠️ ${moveResult.error}`);
|
|
413
|
-
console.log(' Auto mode stopping.');
|
|
414
|
-
break;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
console.log(`\n🔄 Moving to next requirement: ${moveResult.nextRequirement}`);
|
|
418
|
-
currentPrompt = initialPrompt;
|
|
419
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
console.log(`\n🏁 Auto mode completed. Processed ${chatCount} chat(s).`);
|
|
425
|
-
return { exitReason, chatCount };
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
module.exports = {
|
|
429
|
-
runContinueCLICommand,
|
|
430
|
-
runContinueCLIAutoMode
|
|
431
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Continue CLI Manager - Handles Continue CLI integration for auto mode
|
|
3
|
+
* Shared between Electron app and CLI package for DRY code
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Run Continue CLI command with PTY support
|
|
11
|
+
* @param {string} repoPath - Repository path
|
|
12
|
+
* @param {string} prompt - Prompt to send to Continue CLI
|
|
13
|
+
* @param {string} reqFilename - Requirements filename (e.g., REQUIREMENTS-hostname.md)
|
|
14
|
+
* @returns {Promise<{success: boolean, output: string, error?: string, hasError?: boolean, exitCode?: number}>}
|
|
15
|
+
*/
|
|
16
|
+
async function runContinueCLICommand(repoPath, prompt, reqFilename) {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
// Try to use node-pty for PTY support (required for Continue CLI's Ink UI)
|
|
19
|
+
let pty;
|
|
20
|
+
try {
|
|
21
|
+
pty = require('node-pty');
|
|
22
|
+
} catch (error) {
|
|
23
|
+
// node-pty not available, fall back to regular spawn
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const command = 'cn';
|
|
27
|
+
const configPath = path.join(os.homedir(), '.continue', 'config.yaml');
|
|
28
|
+
|
|
29
|
+
// Prepend working directory context to prompt so Continue CLI knows where to find files
|
|
30
|
+
const promptWithContext = `IMPORTANT: You are working in the repository at: ${repoPath}
|
|
31
|
+
|
|
32
|
+
All file paths should be relative to this directory. The .vibecodingmachine directory is located at: ${path.join(repoPath, '.vibecodingmachine')}
|
|
33
|
+
|
|
34
|
+
The requirements file for this computer is: .vibecodingmachine/${reqFilename}
|
|
35
|
+
|
|
36
|
+
CRITICAL FILE OPERATIONS:
|
|
37
|
+
- Use the "Read" tool to read local files (NOT the Fetch tool - Fetch is only for URLs)
|
|
38
|
+
- Use the "Write" tool to write local files
|
|
39
|
+
- File paths are local filesystem paths, NOT URLs
|
|
40
|
+
- Example: To read the requirements file, use: Read(.vibecodingmachine/${reqFilename})
|
|
41
|
+
- DO NOT use Fetch for local files - Fetch is only for HTTP/HTTPS URLs
|
|
42
|
+
|
|
43
|
+
${prompt}`;
|
|
44
|
+
|
|
45
|
+
// Try headless mode (-p) for better autonomous execution
|
|
46
|
+
// The --auto flag doesn't seem to execute, it just analyzes
|
|
47
|
+
const args = ['-p', promptWithContext, '--config', configPath];
|
|
48
|
+
|
|
49
|
+
let output = '';
|
|
50
|
+
let errorOutput = '';
|
|
51
|
+
|
|
52
|
+
console.log('\n─────────────────────────────────────────────────────────');
|
|
53
|
+
console.log('Continue CLI Output:');
|
|
54
|
+
console.log('─────────────────────────────────────────────────────────');
|
|
55
|
+
console.log('\n⚠️ Note: Do not type in the terminal while Continue CLI is running.');
|
|
56
|
+
console.log(' Your input will be sent to Continue CLI and may interfere with auto mode.\n');
|
|
57
|
+
|
|
58
|
+
let proc;
|
|
59
|
+
|
|
60
|
+
// With -p (headless) mode, we might not need PTY, but let's try PTY first
|
|
61
|
+
// If it fails, we'll fall back to regular spawn
|
|
62
|
+
if (pty) {
|
|
63
|
+
// Use PTY for Continue CLI (may still be needed even in headless mode)
|
|
64
|
+
proc = pty.spawn(command, args, {
|
|
65
|
+
name: 'xterm-color',
|
|
66
|
+
cols: 120,
|
|
67
|
+
rows: 30,
|
|
68
|
+
cwd: repoPath,
|
|
69
|
+
env: process.env
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Track output to detect if Continue CLI is idle/waiting
|
|
73
|
+
let lastOutputTime = Date.now();
|
|
74
|
+
const maxIdleTime = 30000; // 30 seconds max idle time (reduced from 1 minute)
|
|
75
|
+
let idleCheckInterval;
|
|
76
|
+
let promptDetected = false;
|
|
77
|
+
let promptCheckTimeout;
|
|
78
|
+
|
|
79
|
+
// PTY uses onData instead of stdout.on('data')
|
|
80
|
+
proc.onData((data) => {
|
|
81
|
+
output += data;
|
|
82
|
+
process.stdout.write(data);
|
|
83
|
+
lastOutputTime = Date.now(); // Update last output time
|
|
84
|
+
|
|
85
|
+
// Detect if Continue CLI is showing the interactive prompt
|
|
86
|
+
const dataStr = data.toString();
|
|
87
|
+
if (dataStr.includes('[⏵⏵ auto]') || dataStr.includes('Ask anything') ||
|
|
88
|
+
dataStr.includes('Context:') || (dataStr.includes('auto') && dataStr.includes('Continue CLI'))) {
|
|
89
|
+
if (!promptDetected) {
|
|
90
|
+
promptDetected = true;
|
|
91
|
+
// Wait for prompt to fully render, then send a command to make it proceed
|
|
92
|
+
promptCheckTimeout = setTimeout(() => {
|
|
93
|
+
const timeSinceLastOutput = Date.now() - lastOutputTime;
|
|
94
|
+
// If no output for 3 seconds after prompt, send a command to proceed
|
|
95
|
+
if (timeSinceLastOutput > 3000) {
|
|
96
|
+
console.log('\n📤 Sending command to Continue CLI to proceed with implementation...\n');
|
|
97
|
+
// Send a command to Continue CLI to actually work on the requirement
|
|
98
|
+
try {
|
|
99
|
+
// Send a direct command to proceed with implementation
|
|
100
|
+
const proceedCommand = 'Implement the requirement. Read the REQUIREMENTS file, work through PREPARE → ACT → CLEAN UP → VERIFY → DONE stages, and update the REQUIREMENTS file at each stage using the Write tool.\n';
|
|
101
|
+
proc.write(proceedCommand);
|
|
102
|
+
lastOutputTime = Date.now(); // Reset timer since we sent input
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.log('\n⚠️ Could not send command to Continue CLI:', error.message);
|
|
105
|
+
console.log(' Stopping Continue CLI process...\n');
|
|
106
|
+
proc.kill();
|
|
107
|
+
if (idleCheckInterval) clearInterval(idleCheckInterval);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}, 3000); // Wait 3 seconds after prompt detection before sending command
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Set up idle detection - kill if no output for too long
|
|
116
|
+
const checkIdle = () => {
|
|
117
|
+
const timeSinceLastOutput = Date.now() - lastOutputTime;
|
|
118
|
+
if (timeSinceLastOutput > maxIdleTime) {
|
|
119
|
+
console.log('\n⚠️ Continue CLI has been idle for too long. It may be waiting for input.');
|
|
120
|
+
console.log(' Stopping Continue CLI process...\n');
|
|
121
|
+
proc.kill();
|
|
122
|
+
clearInterval(idleCheckInterval);
|
|
123
|
+
if (promptCheckTimeout) clearTimeout(promptCheckTimeout);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// Start idle checking every 5 seconds (very frequent)
|
|
128
|
+
idleCheckInterval = setInterval(checkIdle, 5000);
|
|
129
|
+
|
|
130
|
+
proc.onExit(({ exitCode }) => {
|
|
131
|
+
// Clean up idle checker and timeout
|
|
132
|
+
if (idleCheckInterval) {
|
|
133
|
+
clearInterval(idleCheckInterval);
|
|
134
|
+
}
|
|
135
|
+
if (promptCheckTimeout) {
|
|
136
|
+
clearTimeout(promptCheckTimeout);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const fullOutput = output;
|
|
140
|
+
console.log('\n─────────────────────────────────────────────────────────\n');
|
|
141
|
+
|
|
142
|
+
// Check for common errors
|
|
143
|
+
const hasAnthropicError = fullOutput.includes('ANTHROPIC_API_KEY') || fullOutput.includes('404');
|
|
144
|
+
const hasAuthError = fullOutput.includes('authentication') && fullOutput.includes('error');
|
|
145
|
+
|
|
146
|
+
if (hasAnthropicError) {
|
|
147
|
+
console.log('\n⚠️ Continue CLI could not find Ollama configuration.');
|
|
148
|
+
console.log(' Please ensure:');
|
|
149
|
+
console.log(' 1. Ollama is running (ollama serve)');
|
|
150
|
+
console.log(' 2. ~/.continue/config.yaml is configured with Ollama models');
|
|
151
|
+
console.log(' 3. Models are downloaded (ollama pull model-name)\n');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
resolve({
|
|
155
|
+
success: !hasAnthropicError && !hasAuthError,
|
|
156
|
+
output: fullOutput,
|
|
157
|
+
exitCode: exitCode,
|
|
158
|
+
hasError: hasAnthropicError || hasAuthError
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
} else {
|
|
162
|
+
// Fallback to regular spawn (without PTY)
|
|
163
|
+
const { spawn } = require('child_process');
|
|
164
|
+
proc = spawn(command, args, {
|
|
165
|
+
cwd: repoPath,
|
|
166
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Close stdin immediately since we're not interactive
|
|
170
|
+
proc.stdin.end();
|
|
171
|
+
|
|
172
|
+
proc.stdout.on('data', (data) => {
|
|
173
|
+
output += data.toString();
|
|
174
|
+
process.stdout.write(data);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
proc.stderr.on('data', (data) => {
|
|
178
|
+
errorOutput += data.toString();
|
|
179
|
+
process.stderr.write(data);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
proc.on('close', (code) => {
|
|
183
|
+
console.log('\n─────────────────────────────────────────────────────────\n');
|
|
184
|
+
|
|
185
|
+
// Check for errors
|
|
186
|
+
const fullOutput = output + errorOutput;
|
|
187
|
+
const hasAnthropicError = fullOutput.includes('ANTHROPIC_API_KEY') || fullOutput.includes('404');
|
|
188
|
+
const hasAuthError = fullOutput.includes('authentication') && fullOutput.includes('error');
|
|
189
|
+
const hasRawModeError = fullOutput.includes('Raw mode is not supported');
|
|
190
|
+
|
|
191
|
+
if (hasRawModeError) {
|
|
192
|
+
console.log('\n⚠️ Continue CLI requires PTY support (node-pty package).');
|
|
193
|
+
console.log(' Install with: npm install node-pty\n');
|
|
194
|
+
} else if (hasAnthropicError) {
|
|
195
|
+
console.log('\n⚠️ Continue CLI could not find Ollama configuration.');
|
|
196
|
+
console.log(' Please ensure:');
|
|
197
|
+
console.log(' 1. Ollama is running (ollama serve)');
|
|
198
|
+
console.log(' 2. ~/.continue/config.yaml is configured with Ollama models');
|
|
199
|
+
console.log(' 3. Models are downloaded (ollama pull model-name)\n');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
resolve({
|
|
203
|
+
success: code === 0 && !hasAnthropicError && !hasAuthError && !hasRawModeError,
|
|
204
|
+
output: fullOutput,
|
|
205
|
+
error: code !== 0 ? errorOutput : undefined,
|
|
206
|
+
exitCode: code,
|
|
207
|
+
hasError: hasAnthropicError || hasAuthError || hasRawModeError
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
proc.on('error', (error) => {
|
|
212
|
+
console.log('\n─────────────────────────────────────────────────────────\n');
|
|
213
|
+
console.log(`\n✗ Failed to start Continue CLI: ${error.message}\n`);
|
|
214
|
+
|
|
215
|
+
if (error.code === 'ENOENT') {
|
|
216
|
+
console.log(' Continue CLI (cn command) not found.');
|
|
217
|
+
console.log(' Install with: npm install -g @continuedev/continue-cli\n');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
resolve({
|
|
221
|
+
success: false,
|
|
222
|
+
output: '',
|
|
223
|
+
error: error.message,
|
|
224
|
+
hasError: true
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Run Continue CLI in auto mode loop
|
|
233
|
+
* @param {string} repoPath - Repository path
|
|
234
|
+
* @param {string} initialPrompt - Initial prompt to send
|
|
235
|
+
* @param {object} config - Auto mode configuration
|
|
236
|
+
* @param {string} config.ide - IDE type ('continue')
|
|
237
|
+
* @param {number|null} config.maxChats - Maximum chats (null for unlimited)
|
|
238
|
+
* @param {boolean} config.neverStop - Never stop flag
|
|
239
|
+
* @param {function} updateAutoModeStatus - Callback to update auto mode status
|
|
240
|
+
* @param {function} isRequirementDone - Callback to check if requirement is done
|
|
241
|
+
* @param {function} moveToNextRequirement - Callback to move to next requirement
|
|
242
|
+
* @returns {Promise<void>}
|
|
243
|
+
*/
|
|
244
|
+
async function runContinueCLIAutoMode(repoPath, initialPrompt, config, callbacks) {
|
|
245
|
+
const { updateAutoModeStatus, isRequirementDone, moveToNextRequirement } = callbacks;
|
|
246
|
+
const { getRequirementsPath } = require('../utils/repo-helpers.cjs');
|
|
247
|
+
const fs = require('fs-extra');
|
|
248
|
+
|
|
249
|
+
let chatCount = 0;
|
|
250
|
+
let currentPrompt = initialPrompt;
|
|
251
|
+
const maxChats = config.maxChats || 100;
|
|
252
|
+
const neverStop = config.neverStop || false;
|
|
253
|
+
let exitReason = 'completed';
|
|
254
|
+
|
|
255
|
+
console.log(' Auto mode will continue until DONE status is reached');
|
|
256
|
+
console.log(` Max chats: ${neverStop ? 'unlimited' : maxChats}`);
|
|
257
|
+
console.log();
|
|
258
|
+
|
|
259
|
+
while (true) {
|
|
260
|
+
// Check max chats
|
|
261
|
+
if (!neverStop && chatCount >= maxChats) {
|
|
262
|
+
console.log(`\n⏹️ Reached max chats limit (${maxChats})`);
|
|
263
|
+
exitReason = 'max-chats';
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
chatCount++;
|
|
268
|
+
console.log(`\n📝 Chat ${chatCount}${neverStop ? '' : `/${maxChats}`}: ${currentPrompt.substring(0, 60)}${currentPrompt.length > 60 ? '...' : ''}`);
|
|
269
|
+
console.log(' Running Continue CLI...\n');
|
|
270
|
+
|
|
271
|
+
// Update auto mode status
|
|
272
|
+
await updateAutoModeStatus(repoPath, { chatCount });
|
|
273
|
+
|
|
274
|
+
// Get the computer-specific requirements filename
|
|
275
|
+
const reqPath = await getRequirementsPath(repoPath);
|
|
276
|
+
const reqFilename = path.basename(reqPath);
|
|
277
|
+
|
|
278
|
+
// Read current requirement and status from REQUIREMENTS file
|
|
279
|
+
let currentRequirementText = '';
|
|
280
|
+
let currentStatus = '';
|
|
281
|
+
try {
|
|
282
|
+
if (await fs.pathExists(reqPath)) {
|
|
283
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
284
|
+
const lines = content.split('\n');
|
|
285
|
+
|
|
286
|
+
// Find current in-progress requirement
|
|
287
|
+
let inProgressSection = false;
|
|
288
|
+
for (let i = 0; i < lines.length; i++) {
|
|
289
|
+
if (lines[i].includes('## 🔨 Current In Progress Requirement')) {
|
|
290
|
+
inProgressSection = true;
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (inProgressSection && lines[i].trim().startsWith('- ')) {
|
|
294
|
+
currentRequirementText = lines[i].substring(2).trim();
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
if (inProgressSection && lines[i].startsWith('##')) {
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Find current status
|
|
303
|
+
for (let i = 0; i < lines.length; i++) {
|
|
304
|
+
if (lines[i].includes('## 🚦 Current Status')) {
|
|
305
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
306
|
+
const statusLine = lines[j].trim();
|
|
307
|
+
if (statusLine && !statusLine.startsWith('#')) {
|
|
308
|
+
currentStatus = statusLine;
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
} catch (error) {
|
|
317
|
+
// Continue without current requirement if file read fails
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Build enhanced prompt with current requirement context
|
|
321
|
+
const enhancedPrompt = currentRequirementText ?
|
|
322
|
+
`${currentPrompt}
|
|
323
|
+
|
|
324
|
+
🚨 FOCUS: You MUST work ONLY on this ONE requirement:
|
|
325
|
+
|
|
326
|
+
"${currentRequirementText}"
|
|
327
|
+
|
|
328
|
+
CURRENT STATUS: ${currentStatus || 'PREPARE'}
|
|
329
|
+
|
|
330
|
+
⚠️ CRITICAL - DO NOT SUMMARIZE OR ANALYZE OTHER REQUIREMENTS:
|
|
331
|
+
- IGNORE all other requirements in the REQUIREMENTS file
|
|
332
|
+
- IGNORE completed requirements, CHANGELOG entries, and other sections
|
|
333
|
+
- FOCUS EXCLUSIVELY on implementing the requirement listed above
|
|
334
|
+
- DO NOT read the entire REQUIREMENTS file and summarize it
|
|
335
|
+
- Read ONLY the specific sections you need to understand the current requirement
|
|
336
|
+
|
|
337
|
+
🚨 STEP-BY-STEP WORKFLOW:
|
|
338
|
+
1. Read INSTRUCTIONS.md (.vibecodingmachine/INSTRUCTIONS.md) to understand the workflow
|
|
339
|
+
2. Read ONLY the "🔨 Current In Progress Requirement" section from REQUIREMENTS file to see the current requirement
|
|
340
|
+
3. Read ONLY the "🚦 Current Status" section to see the current status
|
|
341
|
+
4. Start working on "${currentRequirementText}" based on the current status:
|
|
342
|
+
- If status is PREPARE: Start planning and preparing
|
|
343
|
+
- If status is ACT: Start implementing the code
|
|
344
|
+
- If status is CLEAN UP: Clean up code, remove duplicates, apply DRY
|
|
345
|
+
- If status is VERIFY: Test and verify the implementation
|
|
346
|
+
- If status is DONE: Stop immediately (work is complete)
|
|
347
|
+
5. At EACH stage transition, use the Write tool to UPDATE the REQUIREMENTS file:
|
|
348
|
+
- Set "🚦 Current Status" to the NEXT stage (PREPARE → ACT → CLEAN UP → VERIFY → DONE)
|
|
349
|
+
- Update the "RESPONSE FROM LAST CHAT" section with what you accomplished
|
|
350
|
+
6. Continue until status is DONE
|
|
351
|
+
7. You have FULL WRITE ACCESS - use Write tool to update the REQUIREMENTS file
|
|
352
|
+
|
|
353
|
+
REMEMBER: You are working on ONE requirement: "${currentRequirementText}". Ignore everything else.` :
|
|
354
|
+
currentPrompt;
|
|
355
|
+
|
|
356
|
+
// Run Continue CLI command with enhanced prompt
|
|
357
|
+
const result = await runContinueCLICommand(repoPath, enhancedPrompt, reqFilename);
|
|
358
|
+
|
|
359
|
+
if (result.hasError || (!result.success && result.error)) {
|
|
360
|
+
console.log(`\n✗ Continue CLI encountered an error: ${result.error || 'Unknown error'}`);
|
|
361
|
+
if (result.hasError) {
|
|
362
|
+
console.log('\n⚠️ Please fix the configuration issue and try again.');
|
|
363
|
+
}
|
|
364
|
+
exitReason = 'error';
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
console.log('\n✓ Continue CLI completed');
|
|
369
|
+
|
|
370
|
+
// Wait a moment for file system to sync
|
|
371
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
372
|
+
|
|
373
|
+
// Check if requirement is DONE
|
|
374
|
+
const isDone = await isRequirementDone(repoPath);
|
|
375
|
+
|
|
376
|
+
if (isDone) {
|
|
377
|
+
console.log('\n✅ Requirement marked as DONE!');
|
|
378
|
+
|
|
379
|
+
// Move to next requirement
|
|
380
|
+
const moveResult = await moveToNextRequirement(repoPath);
|
|
381
|
+
|
|
382
|
+
if (!moveResult.success) {
|
|
383
|
+
console.log(`\n⚠️ ${moveResult.error}`);
|
|
384
|
+
console.log(' Auto mode stopping.');
|
|
385
|
+
exitReason = 'error';
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
console.log(`\n🔄 Moving to next requirement: ${moveResult.nextRequirement}`);
|
|
390
|
+
|
|
391
|
+
// Prepare next prompt
|
|
392
|
+
currentPrompt = initialPrompt;
|
|
393
|
+
|
|
394
|
+
// Wait a moment before next iteration
|
|
395
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
396
|
+
} else {
|
|
397
|
+
console.log('\n⚠️ Requirement not yet DONE. Continue CLI may still be working or needs to update status.');
|
|
398
|
+
console.log(' Waiting for DONE status before continuing...');
|
|
399
|
+
|
|
400
|
+
// Wait longer before checking again
|
|
401
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
402
|
+
|
|
403
|
+
// Check again
|
|
404
|
+
const stillNotDone = !(await isRequirementDone(repoPath));
|
|
405
|
+
if (stillNotDone) {
|
|
406
|
+
console.log('\n⚠️ Status still not DONE after waiting. Moving to next iteration.');
|
|
407
|
+
|
|
408
|
+
// Move to next requirement anyway
|
|
409
|
+
const moveResult = await moveToNextRequirement(repoPath);
|
|
410
|
+
|
|
411
|
+
if (!moveResult.success) {
|
|
412
|
+
console.log(`\n⚠️ ${moveResult.error}`);
|
|
413
|
+
console.log(' Auto mode stopping.');
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
console.log(`\n🔄 Moving to next requirement: ${moveResult.nextRequirement}`);
|
|
418
|
+
currentPrompt = initialPrompt;
|
|
419
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
console.log(`\n🏁 Auto mode completed. Processed ${chatCount} chat(s).`);
|
|
425
|
+
return { exitReason, chatCount };
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
module.exports = {
|
|
429
|
+
runContinueCLICommand,
|
|
430
|
+
runContinueCLIAutoMode
|
|
431
|
+
};
|