Restore to commit 74e578279624c6045ca440a3459ebfa1f8d54191
This commit is contained in:
275
scripts/verify-builder-message-flow.js
Executable file
275
scripts/verify-builder-message-flow.js
Executable file
@@ -0,0 +1,275 @@
|
||||
#!/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);
|
||||
}
|
||||
Reference in New Issue
Block a user