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.
120 lines (101 loc) ⢠3.98 kB
JavaScript
/**
* Terminal Mirror Mac Agent Setup Script
* Installs dependencies and configures the agent
*/
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('š Terminal Mirror 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 email for authorization
const userEmail = await question('š§ Enter your email address (the one you use to log into Terminal Mirror): ');
if (!userEmail || !userEmail.includes('@')) {
console.log('ā Invalid email address');
process.exit(1);
}
// Update authorized users
console.log('š¤ Configuring authorized users...');
updateAuthorizedUsers(userEmail);
console.log('ā
User authorization configured\n');
// 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('š Setup completed successfully!\n');
console.log('š Next steps:');
console.log('1. Deploy the updated backend: npm run deploy (in the main project directory)');
console.log('2. Start the Mac agent: npm start');
console.log('3. Visit https://shellmirror.app and 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...');
execSync('npm start', { stdio: 'inherit' });
}
} catch (error) {
console.error('ā Setup failed:', error.message);
process.exit(1);
} finally {
rl.close();
}
}
function updateAuthorizedUsers(userEmail) {
const authFile = path.join(__dirname, 'authorized-users.json');
let authData;
try {
authData = JSON.parse(fs.readFileSync(authFile, 'utf8'));
} catch (error) {
// Create default structure if file doesn't exist
authData = {
version: "1.0.0",
lastUpdated: new Date().toISOString(),
users: {},
roles: {
admin: {
description: "Full access to terminal and admin functions",
permissions: ["terminal", "admin", "logs", "user-management"],
allowedCommands: "*",
maxSessions: 5
},
user: {
description: "Standard terminal access with command restrictions",
permissions: ["terminal"],
allowedCommands: ["ls", "pwd", "whoami", "echo", "cat", "grep", "find", "ps", "df", "du", "uname", "date", "which"],
maxSessions: 2
}
}
};
}
// Add or update user
authData.users[userEmail] = {
role: "admin",
permissions: ["terminal", "admin", "logs"],
allowedCommands: "*",
maxSessions: 3,
addedDate: new Date().toISOString(),
lastAccess: null,
active: true
};
authData.lastUpdated = new Date().toISOString();
fs.writeFileSync(authFile, JSON.stringify(authData, null, 2));
}
// Run setup
setup();