276 lines
7.7 KiB
JavaScript
Executable File
276 lines
7.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Verification script for builder message sending to OpenCode
|
|
* This script validates that all components for message sending are correct
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
console.log('╔══════════════════════════════════════════════════════════════╗');
|
|
console.log('║ Builder → OpenCode Message Flow Verification ║');
|
|
console.log('╚══════════════════════════════════════════════════════════════╝\n');
|
|
|
|
const rootDir = path.join(__dirname, '..');
|
|
let allChecks = true;
|
|
let checkCount = 0;
|
|
let passCount = 0;
|
|
|
|
function check(condition, description) {
|
|
checkCount++;
|
|
if (condition) {
|
|
passCount++;
|
|
console.log(`✓ ${description}`);
|
|
return true;
|
|
} else {
|
|
allChecks = false;
|
|
console.log(`✗ ${description}`);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Load files
|
|
console.log('Loading files...\n');
|
|
const builderJsPath = path.join(rootDir, 'chat/public/builder.js');
|
|
const serverJsPath = path.join(rootDir, 'chat/server.js');
|
|
const builderHtmlPath = path.join(rootDir, 'chat/public/builder.html');
|
|
|
|
let builderJs, serverJs, builderHtml;
|
|
|
|
try {
|
|
builderJs = fs.readFileSync(builderJsPath, 'utf8');
|
|
check(true, 'Loaded builder.js');
|
|
} catch (e) {
|
|
check(false, `Failed to load builder.js: ${e.message}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
try {
|
|
serverJs = fs.readFileSync(serverJsPath, 'utf8');
|
|
check(true, 'Loaded server.js');
|
|
} catch (e) {
|
|
check(false, `Failed to load server.js: ${e.message}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
try {
|
|
builderHtml = fs.readFileSync(builderHtmlPath, 'utf8');
|
|
check(true, 'Loaded builder.html');
|
|
} catch (e) {
|
|
check(false, `Failed to load builder.html: ${e.message}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log('\n--- File Syntax Validation ---\n');
|
|
|
|
// Check syntax of JS files
|
|
try {
|
|
new (require('vm').Script)(builderJs, { filename: 'builder.js' });
|
|
check(true, 'builder.js syntax is valid');
|
|
} catch (e) {
|
|
check(false, `builder.js has syntax error: ${e.message}`);
|
|
}
|
|
|
|
try {
|
|
new (require('vm').Script)(serverJs, { filename: 'server.js' });
|
|
check(true, 'server.js syntax is valid');
|
|
} catch (e) {
|
|
check(false, `server.js has syntax error: ${e.message}`);
|
|
}
|
|
|
|
console.log('\n--- Builder.js Message Sending ---\n');
|
|
|
|
// Check executeBuild function
|
|
check(
|
|
builderJs.includes('async function executeBuild(planContent)'),
|
|
'executeBuild function exists'
|
|
);
|
|
|
|
check(
|
|
builderJs.includes('await api(`/api/sessions/${state.currentSessionId}/messages`'),
|
|
'executeBuild sends to correct API endpoint'
|
|
);
|
|
|
|
check(
|
|
builderJs.includes("cli: 'opencode'"),
|
|
'executeBuild sets cli to "opencode"'
|
|
);
|
|
|
|
check(
|
|
builderJs.includes('isProceedWithBuild: true'),
|
|
'executeBuild sets isProceedWithBuild flag'
|
|
);
|
|
|
|
check(
|
|
builderJs.includes('planContent: planContent'),
|
|
'executeBuild includes planContent in payload'
|
|
);
|
|
|
|
check(
|
|
builderJs.includes('streamMessage(state.currentSessionId, response.message.id)'),
|
|
'executeBuild starts streaming after message creation'
|
|
);
|
|
|
|
// Check redoProceedWithBuild function
|
|
check(
|
|
builderJs.includes('async function redoProceedWithBuild(planContent, model)'),
|
|
'redoProceedWithBuild function exists'
|
|
);
|
|
|
|
// Check sendMessage function
|
|
check(
|
|
builderJs.includes('async function sendMessage()'),
|
|
'sendMessage function exists'
|
|
);
|
|
|
|
check(
|
|
builderJs.includes('await api(`/api/sessions/${state.currentSessionId}/messages`'),
|
|
'sendMessage sends to correct API endpoint'
|
|
);
|
|
|
|
console.log('\n--- Server.js Message Handling ---\n');
|
|
|
|
// Check route matching
|
|
check(
|
|
serverJs.includes('const messageMatch = pathname.match') &&
|
|
serverJs.includes('api') && serverJs.includes('sessions') && serverJs.includes('messages'),
|
|
'Server has message route matcher'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('return handleNewMessage(req, res, messageMatch[1], userId)'),
|
|
'Server routes to handleNewMessage'
|
|
);
|
|
|
|
// Check handleNewMessage function
|
|
check(
|
|
serverJs.includes('async function handleNewMessage(req, res, sessionId, userId)'),
|
|
'handleNewMessage function exists'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('const content = sanitizeMessage(body.content'),
|
|
'handleNewMessage extracts and sanitizes content'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('const cli = normalizeCli(body.cli || session.cli)'),
|
|
'handleNewMessage extracts CLI'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('session.messages.push(message)'),
|
|
'handleNewMessage adds message to session'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('queueMessage(sessionId, message)'),
|
|
'handleNewMessage queues message'
|
|
);
|
|
|
|
console.log('\n--- Message Processing ---\n');
|
|
|
|
// Check processMessage function
|
|
check(
|
|
serverJs.includes('async function processMessage(sessionId, message)'),
|
|
'processMessage function exists'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('const opencodeResult = await sendToOpencodeWithFallback'),
|
|
'processMessage calls sendToOpencodeWithFallback'
|
|
);
|
|
|
|
// Check sendToOpencodeWithFallback function
|
|
check(
|
|
serverJs.includes('async function sendToOpencodeWithFallback'),
|
|
'sendToOpencodeWithFallback function exists'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('const result = await sendToOpencode'),
|
|
'sendToOpencodeWithFallback calls sendToOpencode'
|
|
);
|
|
|
|
console.log('\n--- OpenCode Integration ---\n');
|
|
|
|
// Check sendToOpencode function
|
|
check(
|
|
serverJs.includes('async function sendToOpencode({ session, model, content, message, cli, streamCallback, opencodeSessionId })'),
|
|
'sendToOpencode function exists'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('const clean = sanitizeMessage(content)'),
|
|
'sendToOpencode sanitizes content'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes("const args = ['run', '--model', resolvedModel]"),
|
|
'sendToOpencode prepares CLI arguments'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('args.push(clean)'),
|
|
'sendToOpencode adds content as argument'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('const { stdout, stderr } = await runCommand(cliCommand, args'),
|
|
'sendToOpencode executes OpenCode CLI'
|
|
);
|
|
|
|
console.log('\n--- Streaming Support ---\n');
|
|
|
|
// Check streaming functionality
|
|
check(
|
|
builderJs.includes('function streamMessage(sessionId, messageId)'),
|
|
'streamMessage function exists in builder'
|
|
);
|
|
|
|
check(
|
|
builderJs.includes('const url = `/api/sessions/${sessionId}/messages/${messageId}/stream`'),
|
|
'streamMessage connects to correct endpoint'
|
|
);
|
|
|
|
check(
|
|
builderJs.includes('const eventSource = new EventSource(url)'),
|
|
'streamMessage uses EventSource for SSE'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes('async function handleMessageStream(req, res, sessionId, messageId, userId)'),
|
|
'handleMessageStream function exists in server'
|
|
);
|
|
|
|
check(
|
|
serverJs.includes("'Content-Type': 'text/event-stream'"),
|
|
'Server sets correct content type for SSE'
|
|
);
|
|
|
|
console.log('\n--- Summary ---\n');
|
|
|
|
const percentage = ((passCount / checkCount) * 100).toFixed(1);
|
|
console.log(`Checks passed: ${passCount}/${checkCount} (${percentage}%)`);
|
|
|
|
if (allChecks) {
|
|
console.log('\n✅ ALL CHECKS PASSED');
|
|
console.log('\nThe builder message sending flow is correctly implemented.');
|
|
console.log('All files are valid and components are properly connected.');
|
|
console.log('Messages should successfully flow: Builder → Server → OpenCode\n');
|
|
|
|
console.log('If messages are not being sent, check:');
|
|
console.log(' 1. OpenCode CLI is installed and accessible');
|
|
console.log(' 2. Server is running and accessible');
|
|
console.log(' 3. User has a valid session');
|
|
console.log(' 4. Model is properly configured');
|
|
console.log(' 5. Browser console for runtime errors');
|
|
console.log(' 6. Server logs for processing errors');
|
|
process.exit(0);
|
|
} else {
|
|
console.log('\n❌ SOME CHECKS FAILED');
|
|
console.log('\nReview the failed checks above to identify issues.\n');
|
|
process.exit(1);
|
|
}
|