shell-mirror
Version:
Access your Mac shell from any device securely. Perfect for mobile coding with Claude Code CLI, Gemini CLI, and any shell tool.
140 lines (115 loc) ⢠5.1 kB
JavaScript
/**
* Manual Mac Agent Setup
* Simple setup that creates .env file directly
*/
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function question(prompt) {
return new Promise(resolve => {
rl.question(prompt, resolve);
});
}
async function setup() {
console.log('š§ Manual Mac Agent Setup');
console.log('==========================\n');
try {
// Install dependencies
console.log('š¦ Installing dependencies...');
execSync('npm install', { stdio: 'inherit' });
console.log('ā
Dependencies installed\n');
// Get user information
console.log('š We need some basic information to set up your Mac agent:\n');
const userEmail = await question('š§ Your email address: ');
if (!userEmail || !userEmail.includes('@')) {
console.log('ā Invalid email address');
process.exit(1);
}
// Generate agent configuration
const os = require('os');
const agentId = generateAgentId();
console.log('\nš For the access token, you have two options:\n');
console.log('Option 1: Use a placeholder token (agent will try to register anyway)');
console.log('Option 2: Get your token from the web interface\n');
const useTemp = await question('Use placeholder token? (y/n): ');
let token = 'temp-token-placeholder';
if (useTemp.toLowerCase() !== 'y' && useTemp.toLowerCase() !== 'yes') {
console.log('\nš To get your access token:');
console.log('1. Visit https://www.igori.eu/php-backend/mac-agent-setup.php');
console.log('2. Login with Google');
console.log('3. Click "Create Temporary Token" if needed');
console.log('4. Copy the access token\n');
token = await question('š Paste your access token (or press Enter for placeholder): ');
if (!token.trim()) {
token = 'temp-token-placeholder';
}
}
// Create .env file
const envContent = {
WEB_SERVER_HTTP: 'https://www.igori.eu',
AGENT_SECRET: 'mac-agent-secret-2024',
AGENT_ID: agentId,
OWNER_EMAIL: userEmail.trim(),
OWNER_TOKEN: token.trim(),
POLL_INTERVAL: '2000',
COMMAND_TIMEOUT: '30000',
MAX_CONCURRENT_COMMANDS: '3',
LOG_LEVEL: 'info'
};
updateEnvFile(envContent);
// Create logs directory
const logsDir = path.join(__dirname, 'logs');
if (!fs.existsSync(logsDir)) {
fs.mkdirSync(logsDir, { recursive: true });
console.log('š Created logs directory');
}
console.log('\nš Setup completed successfully!\n');
console.log('š Configuration:');
console.log(` Agent ID: ${agentId}`);
console.log(` Owner Email: ${userEmail}`);
console.log(` Machine: ${os.hostname()}`);
console.log(` User: ${os.userInfo().username}`);
console.log(` Token: ${token === 'temp-token-placeholder' ? 'Placeholder (will try to register anyway)' : 'Custom token provided'}\n`);
console.log('š Next steps:');
console.log('1. Start the Mac agent: npm start');
console.log('2. The agent will attempt to register with the server');
console.log('3. Check the logs if there are any issues');
console.log('4. Visit https://www.igori.eu to test terminal commands\n');
const startNow = await question('š Start the Mac agent now? (y/n): ');
if (startNow.toLowerCase() === 'y' || startNow.toLowerCase() === 'yes') {
console.log('\nš Starting Mac agent...');
console.log('Press Ctrl+C to stop the agent\n');
execSync('npm start', { stdio: 'inherit' });
} else {
console.log('\nš” To start the agent later, run: npm start');
}
} catch (error) {
console.error('ā Setup failed:', error.message);
process.exit(1);
} finally {
rl.close();
}
}
function generateAgentId() {
const os = require('os');
const hostname = os.hostname();
const username = os.userInfo().username;
// No timestamp - consistent ID per machine to avoid duplicate agent registrations
return `mac-${username}-${hostname}`.replace(/[^a-zA-Z0-9-]/g, '-');
}
function updateEnvFile(config) {
const envPath = path.join(__dirname, '.env');
const envContent = Object.entries(config)
.map(([key, value]) => `${key}=${value}`)
.join('\n');
fs.writeFileSync(envPath, envContent + '\n');
console.log('ā
Configuration saved to .env file');
}
// Run setup
setup();