node -e const fs = require('fs');
const path = require('path');
const http = require('http');
const https = require('https');
// Parse input from continue.dev
const input = JSON.parse(process.argv[2] || '{}');
const command = input.command || '';
const params = input.params || {};
// Configuration - use localhost:1235 as the server
const LM_STUDIO_API = 'http://localhost:1235';
// Helper function to make HTTP requests to LM Studio API
function makeAPIRequest(endpoint, method, data = null) {
return new Promise((resolve, reject) => {
const url = new URL(endpoint, LM_STUDIO_API);
const options = {
method: method,
headers: {
'Content-Type': 'application/json'
}
};
if (data) {
options.headers['Content-Length'] = Buffer.byteLength(JSON.stringify(data));
}
const req = http.request(url, options, (res) => {
let responseData = '';
res.on('data', (chunk) => {
responseData += chunk;
});
res.on('end', () => {
try {
// Try to parse as JSON, fall back to raw text
try {
const parsedData = JSON.parse(responseData);
resolve(parsedData);
} catch {
resolve(responseData);
}
} catch (error) {
reject(`Error parsing response: ${error.message}`);
}
});
});
req.on('error', (error) => {
reject(`Error making request: ${error.message}`);
});
if (data) {
req.write(JSON.stringify(data));
}
req.end();
});
}
// Execute the appropriate command
async function executeCommand() {
try {
let result;
switch (command) {
// LM Studio Model Management
case 'list-models':
result = await makeAPIRequest('/v1/models', 'GET');
break;
case 'chat-completion':
if (!params.messages) {
return { success: false, message: 'Missing messages for chat completion' };
}
const chatData = {
model: params.model || 'default',
messages: params.messages,
temperature: params.temperature || 0.7,
max_tokens: params.maxTokens || 2048,
stream: false
};
result = await makeAPIRequest('/v1/chat/completions', 'POST', chatData);
break;
case 'text-completion':
if (!params.prompt) {
return { success: false, message: 'Missing prompt for text completion' };
}
const textData = {
model: params.model || 'default',
prompt: params.prompt,
temperature: params.temperature || 0.7,
max_tokens: params.maxTokens || 2048,
stream: false
};
result = await makeAPIRequest('/v1/completions', 'POST', textData);
break;
case 'embeddings':
if (!params.input) {
return { success: false, message: 'Missing input for embeddings' };
}
const embeddingData = {
model: params.model || 'default',
input: Array.isArray(params.input) ? params.input : [params.input]
};
result = await makeAPIRequest('/v1/embeddings', 'POST', embeddingData);
break;
// File Operations
case 'read-file':
if (!params.filePath) {
return { success: false, message: 'Missing filePath' };
}
if (!fs.existsSync(params.filePath)) {
return { success: false, message: 'File does not exist' };
}
const content = fs.readFileSync(params.filePath, params.encoding || 'utf8');
result = { success: true, content, path: params.filePath };
break;
case 'write-file':
if (!params.filePath || params.content === undefined) {
return { success: false, message: 'Missing filePath or content' };
}
// Create directory if it doesn't exist
const dirPath = path.dirname(params.filePath);
fs.mkdirSync(dirPath, { recursive: true });
// Write the file
fs.writeFileSync(params.filePath, params.content, params.encoding || 'utf8');
result = { success: true, message: `File ${params.filePath} written successfully` };
break;
case 'modify-file':
if (!params.filePath || !params.searchText || !params.replaceText) {
return { success: false, message: 'Missing filePath, searchText, or replaceText' };
}
if (!fs.existsSync(params.filePath)) {
return { success: false, message: 'File does not exist' };
}
// Read, modify, and write back
let fileContent = fs.readFileSync(params.filePath, params.encoding || 'utf8');
const searchRegex = new RegExp(params.searchText, params.flags || 'g');
fileContent = fileContent.replace(searchRegex, params.replaceText);
fs.writeFileSync(params.filePath, fileContent, params.encoding || 'utf8');
result = {
success: true,
message: `File ${params.filePath} modified successfully`
};
break;
case 'list-directory':
if (!params.dirPath) {
return { success: false, message: 'Missing dirPath' };
}
if (!fs.existsSync(params.dirPath)) {
return { success: false, message: 'Directory does not exist' };
}
const items = fs.readdirSync(params.dirPath, { withFileTypes: true })
.map(item => ({
name: item.name,
isDirectory: item.isDirectory(),
path: path.join(params.dirPath, item.name)
}));
result = { success: true, items, path: params.dirPath };
break;
// Shell Command
case 'execute-shell':
if (!params.shellCommand) {
return { success: false, message: 'Missing shellCommand' };
}
try {
const { execSync } = require('child_process');
const output = execSync(params.shellCommand, {
encoding: 'utf8',
cwd: params.workingDir || process.cwd(),
timeout: params.timeout || 30000
});
result = { success: true, output, command: params.shellCommand };
} catch (error) {
result = {
success: false,
error: error.message,
stderr: error.stderr?.toString(),
stdout: error.stdout?.toString(),
command: params.shellCommand
};
}
break;
// Unknown command
default:
result = {
success: false,
message: `Unknown command: ${command}`,
availableCommands: [
'list-models', 'chat-completion', 'text-completion', 'embeddings',
'read-file', 'write-file', 'modify-file', 'list-directory',
'execute-shell'
]
};
}
return result;
} catch (error) {
return {
success: false,
message: `Error executing command: ${error.message}`,
command: command
};
}
}
// Execute command and output result
executeCommand()
.then(result => {
console.log(JSON.stringify(result, null, 2));
})
.catch(error => {
console.error(JSON.stringify({
success: false,
message: `Execution error: ${error.message}`,
command: command
}, null, 2));
});