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.
203 lines (174 loc) • 5.9 kB
JavaScript
const fs = require('fs').promises;
const path = require('path');
const os = require('os');
class ConfigManager {
constructor() {
this.configDir = path.join(os.homedir(), '.terminal-mirror');
this.configFile = path.join(this.configDir, 'config.json');
this.envFile = path.join(process.cwd(), '.env');
}
async manage(options = {}) {
if (options.show) {
await this.showConfig();
} else if (options.reset) {
await this.resetConfig();
} else if (options.set) {
await this.setConfig(options.set);
} else {
console.log('Configuration Management');
console.log('─'.repeat(30));
console.log('');
console.log('Usage:');
console.log(' terminal-mirror config --show Show current configuration');
console.log(' terminal-mirror config --reset Reset to defaults');
console.log(' terminal-mirror config --set key=value Set a value');
console.log('');
console.log('Examples:');
console.log(' terminal-mirror config --set port=8080');
console.log(' terminal-mirror config --set baseUrl=https://example.com');
}
}
async showConfig() {
console.log('📋 Current Configuration');
console.log('─'.repeat(30));
console.log('');
// Load environment
require('dotenv').config({ path: this.envFile });
// Show main configuration
console.log('Environment Variables:');
const envVars = [
'BASE_URL',
'PORT',
'HOST',
'NODE_ENV',
'GOOGLE_CLIENT_ID'
];
envVars.forEach(key => {
const value = process.env[key];
if (key === 'GOOGLE_CLIENT_ID' && value) {
// Mask client ID for security
const masked = value.substring(0, 10) + '...' + value.substring(value.length - 10);
console.log(` ${key}: ${masked}`);
} else {
console.log(` ${key}: ${value || 'Not set'}`);
}
});
console.log('');
console.log('Secret Variables:');
console.log(' GOOGLE_CLIENT_SECRET: ' + (process.env.GOOGLE_CLIENT_SECRET ? '[SET]' : '[NOT SET]'));
console.log(' SESSION_SECRET: ' + (process.env.SESSION_SECRET ? '[SET]' : '[NOT SET]'));
// Show user config if exists
try {
const userConfig = JSON.parse(await fs.readFile(this.configFile, 'utf8'));
console.log('');
console.log('User Configuration:');
console.log(` Setup Date: ${userConfig.setupDate || 'Unknown'}`);
console.log(` Environment: ${userConfig.environment || 'Unknown'}`);
} catch (error) {
console.log('');
console.log('User Configuration: Not found');
}
// Show file locations
console.log('');
console.log('Configuration Files:');
console.log(` Environment: ${this.envFile}`);
console.log(` User Config: ${this.configFile}`);
}
async resetConfig() {
console.log('🗑️ Resetting Configuration');
console.log('');
const { confirm } = require('inquirer').prompt([{
type: 'confirm',
name: 'confirm',
message: 'This will delete all configuration. Continue?',
default: false
}]);
if (!(await confirm).confirm) {
console.log('Reset cancelled');
return;
}
try {
// Remove user config
try {
await fs.unlink(this.configFile);
console.log('✅ User configuration removed');
} catch (error) {
console.log('⚠️ User configuration not found');
}
// Remove .env file
try {
await fs.unlink(this.envFile);
console.log('✅ Environment file removed');
} catch (error) {
console.log('⚠️ Environment file not found');
}
// Remove PID and log files
const pidFile = path.join(this.configDir, 'server.pid');
const logFile = path.join(this.configDir, 'server.log');
try {
await fs.unlink(pidFile);
} catch (error) {
// Ignore
}
try {
await fs.unlink(logFile);
} catch (error) {
// Ignore
}
console.log('');
console.log('✅ Configuration reset complete');
console.log('Run "terminal-mirror setup" to reconfigure');
} catch (error) {
console.error('❌ Reset failed:', error.message);
throw error;
}
}
async setConfig(keyValue) {
const [key, value] = keyValue.split('=');
if (!key || !value) {
console.error('❌ Invalid format. Use: key=value');
return;
}
console.log(`🔧 Setting ${key} = ${value}`);
try {
// Read current .env file
let envContent = '';
try {
envContent = await fs.readFile(this.envFile, 'utf8');
} catch (error) {
console.log('⚠️ .env file not found, creating new one');
}
// Update or add the key
const lines = envContent.split('\n');
let found = false;
const updatedLines = lines.map(line => {
if (line.startsWith(`${key}=`)) {
found = true;
return `${key}=${value}`;
}
return line;
});
if (!found) {
updatedLines.push(`${key}=${value}`);
}
// Write back to file
await fs.writeFile(this.envFile, updatedLines.join('\n'));
console.log('✅ Configuration updated');
// Update user config if applicable
if (['port', 'baseUrl'].includes(key)) {
try {
const userConfig = JSON.parse(await fs.readFile(this.configFile, 'utf8'));
userConfig[key] = value;
userConfig.lastModified = new Date().toISOString();
await fs.writeFile(this.configFile, JSON.stringify(userConfig, null, 2));
} catch (error) {
// User config doesn't exist, that's ok
}
}
} catch (error) {
console.error('❌ Failed to update configuration:', error.message);
throw error;
}
}
}
module.exports = new ConfigManager();