|
1 | 1 | import { homedir, platform } from 'os'; |
| 2 | +import fs from 'fs/promises'; |
| 3 | +import path from 'path'; |
2 | 4 | import { join } from 'path'; |
3 | 5 | import { readFileSync, writeFileSync, existsSync, appendFileSync, mkdirSync } from 'fs'; |
4 | 6 | import { fileURLToPath } from 'url'; |
|
29 | 31 | let setupSteps = []; // Track setup progress |
30 | 32 | let setupStartTime = Date.now(); |
31 | 33 |
|
| 34 | +/** |
| 35 | + * Initialize configuration - load from disk or create default |
| 36 | + */ |
| 37 | +async function initConfigFile() { |
| 38 | + const USER_HOME = homedir(); |
| 39 | + const CONFIG_DIR = path.join(USER_HOME, '.claude-server-commander'); |
| 40 | + |
| 41 | + // Paths relative to the config directory |
| 42 | + const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json'); |
| 43 | + try { |
| 44 | + // Ensure config directory exists |
| 45 | + const configDir = path.dirname(CONFIG_FILE); |
| 46 | + if (!existsSync(configDir)) { |
| 47 | + await mkdir(configDir, { recursive: true }); |
| 48 | + } |
| 49 | + |
| 50 | + // Check if config file exists |
| 51 | + try { |
| 52 | + await fs.access(CONFIG_FILE); |
| 53 | + // Load existing config |
| 54 | + const configData = await fs.readFile(CONFIG_FILE, 'utf8'); |
| 55 | + } catch (error) { |
| 56 | + const defaultConfig = { |
| 57 | + blockedCommands: [ |
| 58 | + |
| 59 | + // Disk and partition management |
| 60 | + "mkfs", // Create a filesystem on a device |
| 61 | + "format", // Format a storage device (cross-platform) |
| 62 | + "mount", // Mount a filesystem |
| 63 | + "umount", // Unmount a filesystem |
| 64 | + "fdisk", // Manipulate disk partition tables |
| 65 | + "dd", // Convert and copy files, can write directly to disks |
| 66 | + "parted", // Disk partition manipulator |
| 67 | + "diskpart", // Windows disk partitioning utility |
| 68 | + |
| 69 | + // System administration and user management |
| 70 | + "sudo", // Execute command as superuser |
| 71 | + "su", // Substitute user identity |
| 72 | + "passwd", // Change user password |
| 73 | + "adduser", // Add a user to the system |
| 74 | + "useradd", // Create a new user |
| 75 | + "usermod", // Modify user account |
| 76 | + "groupadd", // Create a new group |
| 77 | + "chsh", // Change login shell |
| 78 | + "visudo", // Edit the sudoers file |
| 79 | + |
| 80 | + // System control |
| 81 | + "shutdown", // Shutdown the system |
| 82 | + "reboot", // Restart the system |
| 83 | + "halt", // Stop the system |
| 84 | + "poweroff", // Power off the system |
| 85 | + "init", // Change system runlevel |
| 86 | + |
| 87 | + // Network and security |
| 88 | + "iptables", // Linux firewall administration |
| 89 | + "firewall", // Generic firewall command |
| 90 | + "netsh", // Windows network configuration |
| 91 | + |
| 92 | + // Windows system commands |
| 93 | + "sfc", // System File Checker |
| 94 | + "bcdedit", // Boot Configuration Data editor |
| 95 | + "reg", // Windows registry editor |
| 96 | + "net", // Network/user/service management |
| 97 | + "sc", // Service Control manager |
| 98 | + "runas", // Execute command as another user |
| 99 | + "cipher", // Encrypt/decrypt files or wipe data |
| 100 | + "takeown" // Take ownership of files |
| 101 | + ], |
| 102 | + clientId: uniqueUserId, // Use the generated UUID as client ID |
| 103 | + defaultShell: platform() === 'win32' ? 'powershell.exe' : '/bin/sh', |
| 104 | + allowedDirectories: [], |
| 105 | + telemetryEnabled: true, // Default to opt-out approach (telemetry on by default) |
| 106 | + fileWriteLineLimit: 50, // Default line limit for file write operations (changed from 100) |
| 107 | + fileReadLineLimit: 1000 // Default line limit for file read operations (changed from character-based) |
| 108 | + }; |
| 109 | + logToFile('User id ' + uniqueUserId); |
| 110 | + try { |
| 111 | + await fs.writeFile(CONFIG_FILE, JSON.stringify(defaultConfig, null, 2), 'utf8'); |
| 112 | + } catch (error) { |
| 113 | + console.error('Failed to save config:', error); |
| 114 | + throw error; |
| 115 | + } |
| 116 | + } |
| 117 | + |
| 118 | + } catch (error) { |
| 119 | + console.error('Failed to initialize config:', error); |
| 120 | + } |
| 121 | +} |
| 122 | + |
| 123 | + |
32 | 124 |
|
33 | 125 | // Function to get npm version |
34 | 126 | async function getNpmVersion() { |
@@ -532,6 +624,7 @@ export default async function setup() { |
532 | 624 | } |
533 | 625 |
|
534 | 626 | try { |
| 627 | + await initConfigFile(); |
535 | 628 | // Check if config directory exists and create it if necessary |
536 | 629 | const configDirStep = addSetupStep('check_config_directory'); |
537 | 630 | const configDir = dirname(claudeConfigPath); |
|
0 commit comments