@it-club/provisor 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -175
- package/dist/cli.js +2072 -281
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.tsx","../src/commands/init.tsx","../src/components/Task.tsx","../src/components/Header.tsx","../src/components/Confirm.tsx","../src/utils/ssh.ts","../src/commands/app.tsx","../src/commands/ssh-key.tsx","../src/commands/status.tsx","../src/commands/deploy.tsx","../src/commands/config.tsx","../src/commands/update.tsx","../src/utils/update-checker.ts","../package.json"],"sourcesContent":["import { program } from 'commander';\nimport { render } from 'ink';\nimport React from 'react';\nimport { InitCommand } from './commands/init.js';\nimport { AppCommand } from './commands/app.js';\nimport { SshKeyCommand } from './commands/ssh-key.js';\nimport { StatusCommand } from './commands/status.js';\nimport { DeployCommand } from './commands/deploy.js';\nimport { ConfigCommand } from './commands/config.js';\nimport { UpdateCommand } from './commands/update.js';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\nprogram\n .name('provisor')\n .description('Server provisioning and deployment CLI')\n .version(packageJson.version);\n\nprogram\n .command('init')\n .description('Initialize server with user, SSH, and firewall setup')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to create', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key for root access')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n render(<InitCommand {...options} />);\n });\n\nprogram\n .command('app')\n .description('Provision application (Caddy, Node.js, Git deploy)')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .option('-b, --branch <branch>', 'Deploy branch', 'main')\n .option('-n, --name <name>', 'Application name', 'app')\n .option('-r, --repo <url>', 'Clone from repository URL (GitHub, GitLab, etc.)')\n .action((options) => {\n render(<AppCommand {...options} />);\n });\n\nprogram\n .command('ssh-key')\n .description('Manage SSH keys on the server')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .option('--add <pubkey>', 'Add a new public key')\n .option('--list', 'List authorized keys')\n .action((options) => {\n render(<SshKeyCommand {...options} />);\n });\n\nprogram\n .command('status')\n .description('Check server status and services')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n render(<StatusCommand {...options} />);\n });\n\nprogram\n .command('deploy')\n .description('Trigger deployment for an application')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .requiredOption('-n, --name <name>', 'Application name')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n render(<DeployCommand {...options} />);\n });\n\nprogram\n .command('config')\n .description('Manage application configuration')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .requiredOption('-n, --name <name>', 'Application name')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .option('--show', 'Show current configuration')\n .option('--repo <url>', 'Change repository URL')\n .option('--branch <branch>', 'Change deploy branch')\n .option('--new-key', 'Generate new deploy key')\n .option('--delete-key', 'Delete deploy key')\n .option('--webhook-secret <secret>', 'Update webhook secret')\n .option('--disable-webhook', 'Disable webhook')\n .option('--polling-interval <seconds>', 'Set git polling interval in seconds', parseInt)\n .option('--enable-polling', 'Enable git polling for auto-deploy')\n .option('--disable-polling', 'Disable git polling')\n .action((options) => {\n render(<ConfigCommand {...options} />);\n });\n\nprogram\n .command('update')\n .description('Check for updates and update the CLI')\n .option('--check', 'Only check for updates, do not install')\n .action((options) => {\n render(<UpdateCommand {...options} />);\n });\n\nprogram.parse();\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport { Header, Task, Confirm, type TaskStatus } from '../components/index.js';\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface InitCommandProps extends SSHOptions {\n user: string;\n}\n\ninterface TaskState {\n connect: TaskStatus;\n update: TaskStatus;\n createUser: TaskStatus;\n setupSsh: TaskStatus;\n firewall: TaskStatus;\n hardenSsh: TaskStatus;\n}\n\nconst SCRIPTS = {\n checkUser: (user: string) => `id ${user} &>/dev/null && echo \"exists\" || echo \"not_found\"`,\n\n createUser: (user: string) => `\n adduser --gecos \"\" --disabled-password ${user}\n usermod -aG sudo ${user}\n echo \"${user} ALL=(ALL) NOPASSWD:ALL\" > /etc/sudoers.d/${user}\n chmod 440 /etc/sudoers.d/${user}\n `,\n\n copyRootKeys: (user: string) => `\n mkdir -p /home/${user}/.ssh\n cp /root/.ssh/authorized_keys /home/${user}/.ssh/authorized_keys\n chown -R ${user}:${user} /home/${user}/.ssh\n chmod 700 /home/${user}/.ssh\n chmod 600 /home/${user}/.ssh/authorized_keys\n `,\n\n setupFirewall: () => `\n apt install -y ufw\n ufw allow OpenSSH\n ufw allow 80\n ufw allow 443\n echo \"y\" | ufw enable\n `,\n\n hardenSsh: () => `\n cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak\n sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config\n sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config\n systemctl restart ssh || systemctl restart sshd\n `,\n};\n\nexport function InitCommand(props: InitCommandProps) {\n const { exit } = useApp();\n const [client, setClient] = useState<Client | null>(null);\n const [tasks, setTasks] = useState<TaskState>({\n connect: 'pending',\n update: 'pending',\n createUser: 'pending',\n setupSsh: 'pending',\n firewall: 'pending',\n hardenSsh: 'pending',\n });\n const [error, setError] = useState<string | null>(null);\n const [waitingConfirm, setWaitingConfirm] = useState(false);\n const [summary, setSummary] = useState<string[]>([]);\n\n const updateTask = (task: keyof TaskState, status: TaskStatus) => {\n setTasks((prev) => ({ ...prev, [task]: status }));\n };\n\n const addSummary = (msg: string) => {\n setSummary((prev) => [...prev, msg]);\n };\n\n // Step 1: Connect\n useEffect(() => {\n const run = async () => {\n updateTask('connect', 'running');\n try {\n const sshClient = await connect({ ...props, user: 'root' });\n setClient(sshClient);\n updateTask('connect', 'success');\n } catch (err) {\n updateTask('connect', 'error');\n setError(`Connection failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, []);\n\n // Step 2: Update system\n useEffect(() => {\n if (!client || tasks.connect !== 'success' || tasks.update !== 'pending') return;\n\n const run = async () => {\n updateTask('update', 'running');\n try {\n await exec(client, 'apt update && apt upgrade -y');\n await exec(client, 'apt install -y curl git');\n updateTask('update', 'success');\n } catch (err) {\n updateTask('update', 'error');\n setError(`Update failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.connect]);\n\n // Step 3: Create user\n useEffect(() => {\n if (!client || tasks.update !== 'success' || tasks.createUser !== 'pending') return;\n\n const run = async () => {\n updateTask('createUser', 'running');\n try {\n const result = await exec(client, SCRIPTS.checkUser(props.user));\n if (result.stdout.trim() === 'exists') {\n updateTask('createUser', 'skipped');\n addSummary(`User '${props.user}' already exists`);\n } else {\n await execScript(client, SCRIPTS.createUser(props.user));\n updateTask('createUser', 'success');\n addSummary(`User '${props.user}' created with sudo access`);\n }\n } catch (err) {\n updateTask('createUser', 'error');\n setError(`User creation failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.update]);\n\n // Step 4: Setup SSH keys\n useEffect(() => {\n if (!client || !['success', 'skipped'].includes(tasks.createUser) || tasks.setupSsh !== 'pending') return;\n\n const run = async () => {\n updateTask('setupSsh', 'running');\n try {\n await execScript(client, SCRIPTS.copyRootKeys(props.user));\n updateTask('setupSsh', 'success');\n addSummary(`SSH keys copied to '${props.user}'`);\n } catch (err) {\n updateTask('setupSsh', 'error');\n setError(`SSH setup failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.createUser]);\n\n // Step 5: Firewall\n useEffect(() => {\n if (!client || tasks.setupSsh !== 'success' || tasks.firewall !== 'pending') return;\n\n const run = async () => {\n updateTask('firewall', 'running');\n try {\n await execScript(client, SCRIPTS.setupFirewall());\n updateTask('firewall', 'success');\n addSummary('Firewall configured (SSH, HTTP, HTTPS)');\n } catch (err) {\n updateTask('firewall', 'error');\n setError(`Firewall setup failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.setupSsh]);\n\n // Step 6: Wait for confirmation before hardening\n useEffect(() => {\n if (tasks.firewall !== 'success' || waitingConfirm || tasks.hardenSsh !== 'pending') return;\n setWaitingConfirm(true);\n }, [tasks.firewall]);\n\n const handleConfirm = async (confirmed: boolean) => {\n if (!client) return;\n\n if (!confirmed) {\n updateTask('hardenSsh', 'skipped');\n addSummary('SSH hardening skipped (root login still enabled)');\n disconnect(client);\n setTimeout(() => exit(), 100);\n return;\n }\n\n updateTask('hardenSsh', 'running');\n try {\n await execScript(client, SCRIPTS.hardenSsh());\n updateTask('hardenSsh', 'success');\n addSummary('SSH hardened (root login disabled, password auth disabled)');\n disconnect(client);\n setTimeout(() => exit(), 100);\n } catch (err) {\n updateTask('hardenSsh', 'error');\n setError(`SSH hardening failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n\n // Handle errors\n useEffect(() => {\n if (error && client) {\n disconnect(client);\n setTimeout(() => exit(), 100);\n }\n }, [error]);\n\n const allDone = tasks.hardenSsh === 'success' || tasks.hardenSsh === 'skipped';\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Server Initialization\" subtitle={`Host: ${props.host}`} />\n\n <Task label=\"Connect to server\" status={tasks.connect} />\n <Task label=\"Update system packages\" status={tasks.update} />\n <Task label={`Create user '${props.user}'`} status={tasks.createUser} />\n <Task label=\"Setup SSH keys\" status={tasks.setupSsh} />\n <Task label=\"Configure firewall\" status={tasks.firewall} />\n <Task label=\"Harden SSH\" status={tasks.hardenSsh} />\n\n {waitingConfirm && tasks.hardenSsh === 'pending' && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"yellow\" bold>\n ⚠ Before proceeding, verify SSH access as '{props.user}':\n </Text>\n <Text color=\"gray\"> ssh {props.port !== '22' ? `-p ${props.port} ` : ''}{props.user}@{props.host}</Text>\n <Box marginTop={1}>\n <Confirm\n message=\"Have you verified SSH access works?\"\n onConfirm={handleConfirm}\n />\n </Box>\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n\n {allDone && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"green\" bold>✓ Initialization complete</Text>\n {summary.map((msg, i) => (\n <Text key={i} color=\"gray\"> • {msg}</Text>\n ))}\n <Box marginTop={1}>\n <Text>Next: <Text color=\"cyan\">provisor app -h {props.host}</Text></Text>\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport Spinner from 'ink-spinner';\n\nexport type TaskStatus = 'pending' | 'running' | 'success' | 'error' | 'skipped';\n\ninterface TaskProps {\n label: string;\n status: TaskStatus;\n message?: string;\n}\n\nconst statusIcons: Record<TaskStatus, React.ReactNode> = {\n pending: <Text color=\"gray\">○</Text>,\n running: <Text color=\"cyan\"><Spinner type=\"dots\" /></Text>,\n success: <Text color=\"green\">✓</Text>,\n error: <Text color=\"red\">✗</Text>,\n skipped: <Text color=\"yellow\">-</Text>,\n};\n\nexport function Task({ label, status, message }: TaskProps) {\n return (\n <Box>\n <Box width={3}>{statusIcons[status]}</Box>\n <Text color={status === 'error' ? 'red' : undefined}>\n {label}\n {message && <Text color=\"gray\"> {message}</Text>}\n </Text>\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\n\ninterface HeaderProps {\n title: string;\n subtitle?: string;\n}\n\nexport function Header({ title, subtitle }: HeaderProps) {\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color=\"cyan\">\n ◆ {title}\n </Text>\n {subtitle && <Text color=\"gray\">{subtitle}</Text>}\n </Box>\n );\n}\n","import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface ConfirmProps {\n message: string;\n onConfirm: (confirmed: boolean) => void;\n}\n\nexport function Confirm({ message, onConfirm }: ConfirmProps) {\n const [answered, setAnswered] = useState(false);\n\n useInput((input, key) => {\n if (answered) return;\n\n if (input.toLowerCase() === 'y' || key.return) {\n setAnswered(true);\n onConfirm(true);\n } else if (input.toLowerCase() === 'n' || key.escape) {\n setAnswered(true);\n onConfirm(false);\n }\n });\n\n if (answered) return null;\n\n return (\n <Box>\n <Text color=\"yellow\">{message}</Text>\n <Text color=\"gray\"> (y/n) </Text>\n </Box>\n );\n}\n","import { Client, type ConnectConfig } from 'ssh2';\nimport { readFileSync, existsSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nexport interface SSHOptions {\n host: string;\n port?: string | number;\n user?: string;\n key?: string;\n}\n\nexport interface CommandResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\nfunction findDefaultKey(): string | null {\n const sshDir = join(homedir(), '.ssh');\n const keyNames = ['id_ed25519', 'id_rsa', 'id_ecdsa'];\n\n for (const name of keyNames) {\n const keyPath = join(sshDir, name);\n if (existsSync(keyPath)) {\n return keyPath;\n }\n }\n return null;\n}\n\nexport function createSSHConfig(options: SSHOptions): ConnectConfig {\n const keyPath = options.key || findDefaultKey();\n\n if (!keyPath) {\n throw new Error(\n 'No SSH key found. Specify with --key or ensure ~/.ssh/id_ed25519 exists'\n );\n }\n\n if (!existsSync(keyPath)) {\n throw new Error(`SSH key not found: ${keyPath}`);\n }\n\n return {\n host: options.host,\n port: parseInt(String(options.port || 22), 10),\n username: options.user || 'root',\n privateKey: readFileSync(keyPath),\n };\n}\n\nexport function connect(options: SSHOptions): Promise<Client> {\n return new Promise((resolve, reject) => {\n const client = new Client();\n const config = createSSHConfig(options);\n\n client.on('ready', () => resolve(client));\n client.on('error', reject);\n client.connect(config);\n });\n}\n\nexport function exec(client: Client, command: string): Promise<CommandResult> {\n return new Promise((resolve, reject) => {\n client.exec(command, (err, stream) => {\n if (err) {\n reject(err);\n return;\n }\n\n let stdout = '';\n let stderr = '';\n\n stream.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n stream.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n stream.on('close', (code: number) => {\n resolve({ stdout, stderr, code: code ?? 0 });\n });\n });\n });\n}\n\nexport function execWithSudo(\n client: Client,\n command: string\n): Promise<CommandResult> {\n // For commands that need sudo, we use sudo -S to read password from stdin\n // But since we're using key-based auth with NOPASSWD sudo, we can just prefix\n return exec(client, `sudo ${command}`);\n}\n\nexport async function execScript(\n client: Client,\n script: string,\n useSudo = false\n): Promise<CommandResult> {\n // Escape the script for bash\n const escapedScript = script.replace(/'/g, \"'\\\\''\");\n const command = useSudo\n ? `sudo bash -c '${escapedScript}'`\n : `bash -c '${escapedScript}'`;\n\n return exec(client, command);\n}\n\nexport function disconnect(client: Client): void {\n client.end();\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport Spinner from 'ink-spinner';\nimport TextInput from 'ink-text-input';\nimport crypto from 'crypto';\nimport { Header, Task, type TaskStatus } from '../components/index.js';\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface AppCommandProps extends SSHOptions {\n branch: string;\n name: string;\n repo?: string;\n}\n\ninterface TaskState {\n connect: TaskStatus;\n caddy: TaskStatus;\n node: TaskStatus;\n deployKey: TaskStatus;\n deploy: TaskStatus;\n webhook: TaskStatus;\n caddyConfig: TaskStatus;\n}\n\ntype DeployMethod = 'push' | 'clone-public' | 'clone-private';\ntype ExistingAppAction = 'replace' | 'update' | 'cancel';\ntype TlsChoice = 'ondemand' | 'specific' | 'none';\ntype AutoDeployChoice = 'polling' | 'webhook' | 'none';\n\nconst SCRIPTS = {\n installCaddy: () => `\n if ! command -v caddy &>/dev/null; then\n apt install -y debian-keyring debian-archive-keyring apt-transport-https\n curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg\n curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list\n apt update\n apt install caddy -y\n echo \"installed\"\n else\n echo \"exists\"\n fi\n `,\n\n installNode: () => `\n if ! command -v node &>/dev/null; then\n curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -\n apt install -y nodejs\n echo \"installed\"\n else\n echo \"exists\"\n fi\n if ! command -v pm2 &>/dev/null; then\n npm install -g pm2\n fi\n `,\n\n // Check if app directory exists\n checkAppExists: (name: string) => `\n APP_DIR=\"/var/www/${name}\"\n if [ -d \"$APP_DIR\" ] && [ \"$(ls -A $APP_DIR 2>/dev/null)\" ]; then\n echo \"exists\"\n else\n echo \"empty\"\n fi\n `,\n\n // Generate deploy key for private repos\n generateDeployKey: (name: string, user: string) => {\n const homeDir = user === 'root' ? '/root' : `/home/${user}`;\n return `\n SSH_DIR=\"${homeDir}/.ssh\"\n KEY_FILE=\"$SSH_DIR/deploy_${name}\"\n\n mkdir -p \"$SSH_DIR\"\n\n # Generate key if doesn't exist\n if [ ! -f \"$KEY_FILE\" ]; then\n ssh-keygen -t ed25519 -f \"$KEY_FILE\" -N \"\" -C \"deploy-key-${name}\"\n fi\n\n # Configure SSH to use this key for github.com and gitlab.com\n if ! grep -q \"deploy_${name}\" \"$SSH_DIR/config\" 2>/dev/null; then\n cat >> \"$SSH_DIR/config\" << EOF\n\n# Deploy key for ${name}\nHost github.com gitlab.com bitbucket.org\n IdentityFile $KEY_FILE\n IdentitiesOnly yes\nEOF\n fi\n\n chown -R ${user}:${user} \"$SSH_DIR\"\n chmod 700 \"$SSH_DIR\"\n chmod 600 \"$KEY_FILE\"\n chmod 644 \"$KEY_FILE.pub\"\n chmod 600 \"$SSH_DIR/config\" 2>/dev/null || true\n\n # Output the public key\n cat \"$KEY_FILE.pub\"\n `;\n },\n\n // Test SSH connection to git host\n testGitConnection: (host: string) => `\n ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -T git@${host} 2>&1 || true\n `,\n\n // Push-to-deploy: setup bare repo with hook\n setupPushDeploy: (name: string, branch: string, user: string) => `\n APP_DIR=\"/var/www/${name}\"\n REPO_DIR=\"/var/repo/${name}.git\"\n\n mkdir -p \"$APP_DIR\"\n mkdir -p \"$(dirname \"$REPO_DIR\")\"\n\n if [ ! -d \"$REPO_DIR\" ]; then\n git init --bare \"$REPO_DIR\"\n fi\n\n # Create post-receive hook\n cat << 'HOOK_EOF' > \"$REPO_DIR/hooks/post-receive\"\n#!/bin/bash\nset -e\n\nTARGET=\"/var/www/${name}\"\nGIT_DIR=\"/var/repo/${name}.git\"\nBRANCH=\"${branch}\"\n\necho \"=== Deployment Started ===\"\necho \"Deploying branch '$BRANCH' to $TARGET...\"\n\ngit --work-tree=\"$TARGET\" --git-dir=\"$GIT_DIR\" checkout -f \"$BRANCH\"\n\ncd \"$TARGET\"\n\nif [ -f \"package.json\" ]; then\n echo \"Node.js project detected.\"\n\n NEED_INSTALL=false\n\n if [ ! -d \"node_modules\" ]; then\n NEED_INSTALL=true\n elif [ -f \"package-lock.json\" ]; then\n LOCK_HASH_FILE=\"$GIT_DIR/.package-lock-hash\"\n CURRENT_HASH=$(sha256sum package-lock.json | awk '{print $1}')\n\n if [ -f \"$LOCK_HASH_FILE\" ]; then\n PREV_HASH=$(cat \"$LOCK_HASH_FILE\")\n if [ \"$CURRENT_HASH\" != \"$PREV_HASH\" ]; then\n NEED_INSTALL=true\n fi\n else\n NEED_INSTALL=true\n fi\n\n echo \"$CURRENT_HASH\" > \"$LOCK_HASH_FILE\"\n fi\n\n if [ \"$NEED_INSTALL\" = true ]; then\n echo \"Installing dependencies...\"\n npm ci --production 2>/dev/null || npm install --production\n fi\n\n if grep -q '\"build\"' \"package.json\"; then\n echo \"Building application...\"\n npm run build\n fi\n\n PM2_NAME=\"${name}\"\n if pm2 list 2>/dev/null | grep -q \"$PM2_NAME\"; then\n pm2 restart \"$PM2_NAME\"\n fi\nelse\n echo \"Static site detected.\"\nfi\n\necho \"=== Deployment Complete ===\"\nHOOK_EOF\n\n chmod +x \"$REPO_DIR/hooks/post-receive\"\n chown -R ${user}:${user} \"$REPO_DIR\"\n chown -R ${user}:${user} \"$APP_DIR\"\n echo \"push-deploy-ready\"\n `,\n\n // Clone from repository - fresh clone (replace)\n cloneRepoFresh: (name: string, repoUrl: string, branch: string, user: string) => `\n APP_DIR=\"/var/www/${name}\"\n\n # Remove existing if present\n rm -rf \"$APP_DIR\"\n mkdir -p \"$APP_DIR\"\n chown ${user}:${user} \"$APP_DIR\"\n\n # Clone as the deploy user to use their SSH keys\n sudo -u ${user} git clone --branch ${branch} --single-branch ${repoUrl} \"$APP_DIR\"\n\n cd \"$APP_DIR\"\n\n # Build if Node.js project\n if [ -f \"package.json\" ]; then\n echo \"Node.js project detected.\"\n sudo -u ${user} npm ci --production 2>/dev/null || sudo -u ${user} npm install --production\n\n if grep -q '\"build\"' \"package.json\"; then\n echo \"Building application...\"\n sudo -u ${user} npm run build\n fi\n else\n echo \"Static site detected.\"\n fi\n\n chown -R ${user}:${user} \"$APP_DIR\"\n echo \"clone-complete\"\n `,\n\n // Update existing cloned repo (git pull)\n updateRepo: (name: string, branch: string, user: string) => `\n APP_DIR=\"/var/www/${name}\"\n\n cd \"$APP_DIR\"\n\n # Fetch and reset to latest\n sudo -u ${user} git fetch origin\n sudo -u ${user} git reset --hard origin/${branch}\n\n # Build if Node.js project\n if [ -f \"package.json\" ]; then\n echo \"Node.js project detected.\"\n sudo -u ${user} npm ci --production 2>/dev/null || sudo -u ${user} npm install --production\n\n if grep -q '\"build\"' \"package.json\"; then\n echo \"Building application...\"\n sudo -u ${user} npm run build\n fi\n\n PM2_NAME=\"${name}\"\n if pm2 list 2>/dev/null | grep -q \"$PM2_NAME\"; then\n pm2 restart \"$PM2_NAME\"\n fi\n else\n echo \"Static site detected.\"\n fi\n\n echo \"update-complete\"\n `,\n\n // Create update script for cloned repos\n createUpdateScript: (name: string, branch: string, user: string) => `\n cat << 'SCRIPT_EOF' > /usr/local/bin/update-${name}\n#!/bin/bash\nset -e\n\nAPP_DIR=\"/var/www/${name}\"\nBRANCH=\"${branch}\"\nUSER=\"${user}\"\n\necho \"=== Updating ${name} ===\"\n\ncd \"$APP_DIR\"\n\n# Run git commands as deploy user to use their SSH keys\nsudo -u $USER git fetch origin\nsudo -u $USER git reset --hard origin/$BRANCH\n\nif [ -f \"package.json\" ]; then\n sudo -u $USER npm ci --production 2>/dev/null || sudo -u $USER npm install --production\n\n if grep -q '\"build\"' \"package.json\"; then\n sudo -u $USER npm run build\n fi\n\n PM2_NAME=\"${name}\"\n if pm2 list 2>/dev/null | grep -q \"$PM2_NAME\"; then\n pm2 restart \"$PM2_NAME\"\n fi\nfi\n\necho \"=== Update Complete ===\"\nSCRIPT_EOF\n\n chmod +x /usr/local/bin/update-${name}\n echo \"update-script-created\"\n `,\n\n caddyOnDemand: (appDir: string) => `\ncat << 'EOF' > /etc/caddy/Caddyfile\n{\n on_demand_tls {\n interval 2m\n burst 5\n }\n}\n\nhttps:// {\n tls {\n on_demand\n }\n\n root * ${appDir}\n encode gzip\n try_files {path} /index.html\n file_server\n}\n\nhttp:// {\n redir https://{host}{uri} permanent\n}\nEOF\ncaddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy\n `,\n\n caddySpecific: (appDir: string, domains: string) => `\ncat << EOF > /etc/caddy/Caddyfile\n${domains} {\n root * ${appDir}\n encode gzip\n try_files {path} /index.html\n file_server\n}\nEOF\ncaddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy\n `,\n\n caddyHttp: (appDir: string) => `\ncat << 'EOF' > /etc/caddy/Caddyfile\n:80 {\n root * ${appDir}\n encode gzip\n try_files {path} /index.html\n file_server\n}\nEOF\ncaddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy\n `,\n\n // Setup webhook handler for automatic deployment\n setupWebhook: (name: string, branch: string, port: number, secret: string) => `\n # Create webhook handler script\n cat << 'HANDLER_EOF' > /usr/local/bin/webhook-${name}.js\n#!/usr/bin/env node\n\nconst http = require('http');\nconst crypto = require('crypto');\nconst { spawn } = require('child_process');\n\nconst config = {\n port: ${port},\n secret: '${secret}',\n branch: '${branch}',\n app: '${name}',\n};\n\nconst updateScript = '/usr/local/bin/update-' + config.app;\n\nfunction log(message) {\n const timestamp = new Date().toISOString();\n console.log('[' + timestamp + '] ' + message);\n}\n\nfunction verifySignature(payload, signature, secret) {\n if (!secret) return true;\n if (signature.startsWith('sha256=')) {\n const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(payload).digest('hex');\n return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));\n }\n if (signature.startsWith('sha1=')) {\n const expected = 'sha1=' + crypto.createHmac('sha1', secret).update(payload).digest('hex');\n return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));\n }\n return signature === secret;\n}\n\nfunction getBranchFromPayload(payload) {\n try {\n const data = JSON.parse(payload);\n if (data.ref) return data.ref.replace('refs/heads/', '');\n if (data.object_kind === 'push' && data.ref) return data.ref.replace('refs/heads/', '');\n if (data.push && data.push.changes && data.push.changes[0]) {\n const change = data.push.changes[0];\n if (change.new && change.new.name) return change.new.name;\n }\n return null;\n } catch (e) { return null; }\n}\n\nfunction runUpdate() {\n log('Running update script: ' + updateScript);\n const child = spawn('sudo', [updateScript], { stdio: ['ignore', 'pipe', 'pipe'] });\n child.stdout.on('data', (data) => log('[update] ' + data.toString().trim()));\n child.stderr.on('data', (data) => log('[update:err] ' + data.toString().trim()));\n child.on('close', (code) => log(code === 0 ? 'Update completed' : 'Update failed: ' + code));\n}\n\nconst server = http.createServer((req, res) => {\n if (req.method === 'GET' && req.url === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', app: config.app, branch: config.branch }));\n return;\n }\n if (req.method !== 'POST' || (req.url !== '/webhook' && req.url !== '/')) {\n res.writeHead(404); res.end('Not found'); return;\n }\n let body = '';\n req.on('data', (chunk) => { body += chunk.toString(); });\n req.on('end', () => {\n const signature = req.headers['x-hub-signature-256'] || req.headers['x-hub-signature'] || req.headers['x-gitlab-token'] || '';\n if (config.secret && !verifySignature(body, signature, config.secret)) {\n log('Invalid signature'); res.writeHead(401); res.end('Unauthorized'); return;\n }\n const branch = getBranchFromPayload(body);\n if (!branch) { res.writeHead(400); res.end('Invalid payload'); return; }\n log('Push to branch: ' + branch);\n if (branch !== config.branch) { res.writeHead(200); res.end('OK (ignored)'); return; }\n log('Triggering deployment...');\n runUpdate();\n res.writeHead(200); res.end('Deployment triggered');\n });\n});\n\nserver.listen(config.port, '0.0.0.0', () => {\n log('Webhook handler started for ' + config.app + ' on port ' + config.port);\n});\n\nprocess.on('SIGTERM', () => { server.close(() => process.exit(0)); });\nprocess.on('SIGINT', () => { server.close(() => process.exit(0)); });\nHANDLER_EOF\n\n chmod +x /usr/local/bin/webhook-${name}.js\n\n # Create systemd service\n cat << 'SERVICE_EOF' > /etc/systemd/system/webhook-${name}.service\n[Unit]\nDescription=Webhook handler for ${name}\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/node /usr/local/bin/webhook-${name}.js\nRestart=always\nRestartSec=10\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=webhook-${name}\n\n[Install]\nWantedBy=multi-user.target\nSERVICE_EOF\n\n # Open firewall port\n ufw allow ${port}/tcp comment \"webhook-${name}\"\n\n # Start service\n systemctl daemon-reload\n systemctl enable webhook-${name}\n systemctl start webhook-${name}\n\n echo \"webhook-ready:${port}\"\n `,\n\n // Save app config\n saveConfig: (name: string, config: object) => `\n CONFIG_FILE=\"/var/www/${name}/.provisor.json\"\n mkdir -p \"/var/www/${name}\"\n echo '${JSON.stringify(config)}' > \"$CONFIG_FILE\"\n chmod 600 \"$CONFIG_FILE\"\n `,\n\n // Find available port for webhook\n findAvailablePort: () => `\n for port in $(seq 9000 9100); do\n if ! ss -tuln | grep -q \":$port \"; then\n echo $port\n exit 0\n fi\n done\n echo \"9000\"\n `,\n\n // Setup git polling service for automatic deployment\n setupPolling: (name: string, branch: string, user: string, interval: number) => `\n # Create polling script (single poll)\n cat << 'POLLING_EOF' > /usr/local/bin/poll-${name}.sh\n#!/bin/bash\nset -e\n\nAPP_DIR=\"/var/www/${name}\"\nBRANCH=\"${branch}\"\nUSER=\"${user}\"\nLOCK_FILE=\"/tmp/poll-${name}.lock\"\n\n# Prevent concurrent runs\nexec 200>\"$LOCK_FILE\"\nflock -n 200 || exit 0\n\ncd \"$APP_DIR\"\n\n# Fetch latest changes\nsudo -u $USER git fetch origin \"$BRANCH\" --quiet 2>/dev/null\n\n# Get local and remote hashes\nLOCAL=$(git rev-parse HEAD)\nREMOTE=$(git rev-parse \"origin/$BRANCH\")\n\n# If different, deploy\nif [ \"$LOCAL\" != \"$REMOTE\" ]; then\n echo \"[$(date -Iseconds)] New commit detected: $REMOTE\"\n sudo /usr/local/bin/update-${name}\nelse\n echo \"[$(date -Iseconds)] No changes\"\nfi\nPOLLING_EOF\n\n chmod +x /usr/local/bin/poll-${name}.sh\n\n # Check if systemd is available (PID 1)\n if pidof systemd > /dev/null 2>&1 || [ \"$(cat /proc/1/comm 2>/dev/null)\" = \"systemd\" ]; then\n # SYSTEMD MODE: Use timer\n cat << SERVICE_EOF > /etc/systemd/system/poll-${name}.service\n[Unit]\nDescription=Git polling service for ${name}\nAfter=network.target\n\n[Service]\nType=oneshot\nExecStart=/usr/local/bin/poll-${name}.sh\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=poll-${name}\nSERVICE_EOF\n\n cat << TIMER_EOF > /etc/systemd/system/poll-${name}.timer\n[Unit]\nDescription=Run git polling for ${name} every ${interval} seconds\n\n[Timer]\nOnBootSec=30\nOnUnitActiveSec=${interval}s\nAccuracySec=1s\n\n[Install]\nWantedBy=timers.target\nTIMER_EOF\n\n systemctl daemon-reload\n systemctl enable poll-${name}.timer\n systemctl start poll-${name}.timer\n echo \"polling-ready:${interval}:systemd\"\n else\n # DAEMON MODE: Use background loop (for Docker/non-systemd)\n cat << 'DAEMON_EOF' > /usr/local/bin/poll-${name}-daemon.sh\n#!/bin/bash\nLOG_FILE=\"/var/log/poll-${name}.log\"\nPID_FILE=\"/var/run/poll-${name}.pid\"\nINTERVAL=${interval}\n\n# Write PID\necho $$ > \"$PID_FILE\"\n\necho \"[$(date -Iseconds)] Polling daemon started (every ${interval}s)\" >> \"$LOG_FILE\"\n\nwhile true; do\n /usr/local/bin/poll-${name}.sh >> \"$LOG_FILE\" 2>&1\n sleep $INTERVAL\ndone\nDAEMON_EOF\n\n chmod +x /usr/local/bin/poll-${name}-daemon.sh\n\n # Stop existing daemon if running\n if [ -f /var/run/poll-${name}.pid ]; then\n kill $(cat /var/run/poll-${name}.pid) 2>/dev/null || true\n rm -f /var/run/poll-${name}.pid\n fi\n\n # Start daemon in background\n mkdir -p /var/log\n touch /var/log/poll-${name}.log\n nohup /usr/local/bin/poll-${name}-daemon.sh > /dev/null 2>&1 &\n \n echo \"polling-ready:${interval}:daemon\"\n fi\n `,\n};\n\nconst deployOptions = [\n { label: 'Push-to-deploy (git push to server)', value: 'push' },\n { label: 'Clone from public repository', value: 'clone-public' },\n { label: 'Clone from private repository (with deploy key)', value: 'clone-private' },\n];\n\nconst existingAppOptions = [\n { label: 'Replace (delete and clone fresh)', value: 'replace' },\n { label: 'Update (git pull latest changes)', value: 'update' },\n { label: 'Cancel', value: 'cancel' },\n];\n\nconst tlsOptions = [\n { label: 'On-demand TLS (auto-cert for any domain)', value: 'ondemand' },\n { label: 'Specific domain(s)', value: 'specific' },\n { label: 'No TLS (HTTP only)', value: 'none' },\n];\n\nconst autoDeployOptions = [\n { label: 'Git polling (checks every 10s, simpler setup)', value: 'polling' },\n { label: 'Webhook (instant, requires repo webhook setup)', value: 'webhook' },\n { label: 'Manual only (use provisor deploy command)', value: 'none' },\n];\n\n// Helper to detect git host from URL\nfunction getGitHost(url: string): string {\n if (url.includes('github.com')) return 'github.com';\n if (url.includes('gitlab.com')) return 'gitlab.com';\n if (url.includes('bitbucket.org')) return 'bitbucket.org';\n const match = url.match(/git@([^:]+):/);\n if (match) return match[1];\n return 'github.com';\n}\n\n// Helper to get deploy key instructions\nfunction getDeployKeyInstructions(host: string): { url: string; steps: string[] } {\n switch (host) {\n case 'github.com':\n return {\n url: 'https://github.com/<owner>/<repo>/settings/keys',\n steps: [\n '1. Go to your repository on GitHub',\n '2. Click Settings → Deploy keys → Add deploy key',\n '3. Paste the public key above',\n '4. Give it a title (e.g., \"Server deploy key\")',\n '5. Click \"Add key\" (leave \"Allow write access\" unchecked)',\n ],\n };\n case 'gitlab.com':\n return {\n url: 'https://gitlab.com/<owner>/<repo>/-/settings/repository',\n steps: [\n '1. Go to your repository on GitLab',\n '2. Click Settings → Repository → Deploy keys',\n '3. Paste the public key above',\n '4. Give it a title and click \"Add key\"',\n ],\n };\n case 'bitbucket.org':\n return {\n url: 'https://bitbucket.org/<owner>/<repo>/admin/access-keys/',\n steps: [\n '1. Go to your repository on Bitbucket',\n '2. Click Repository settings → Access keys',\n '3. Click \"Add key\" and paste the public key above',\n ],\n };\n default:\n return {\n url: '',\n steps: [\n '1. Go to your repository settings',\n '2. Find \"Deploy keys\" or \"Access keys\" section',\n '3. Add the public key shown above',\n ],\n };\n }\n}\n\nexport function AppCommand(props: AppCommandProps) {\n const { exit } = useApp();\n const [client, setClient] = useState<Client | null>(null);\n const [tasks, setTasks] = useState<TaskState>({\n connect: 'pending',\n caddy: 'pending',\n node: 'pending',\n deployKey: 'pending',\n deploy: 'pending',\n webhook: 'pending',\n caddyConfig: 'pending',\n });\n const [error, setError] = useState<string | null>(null);\n\n // Selection states\n const [selectingMethod, setSelectingMethod] = useState(false);\n const [deployMethod, setDeployMethod] = useState<DeployMethod | null>(props.repo ? 'clone-public' : null);\n const [enteringRepo, setEnteringRepo] = useState(false);\n const [repoUrl, setRepoUrl] = useState(props.repo || '');\n const [selectingTls, setSelectingTls] = useState(false);\n const [tlsChoice, setTlsChoice] = useState<TlsChoice | null>(null);\n\n // Deploy key states\n const [deployKey, setDeployKey] = useState<string>('');\n const [waitingForKeySetup, setWaitingForKeySetup] = useState(false);\n const [keyConfirmed, setKeyConfirmed] = useState(false);\n const [keyVerifying, setKeyVerifying] = useState(false);\n const [keyVerified, setKeyVerified] = useState(false);\n const [keyVerifyError, setKeyVerifyError] = useState<string | null>(null);\n\n // Existing app states\n const [appExists, setAppExists] = useState<boolean | null>(null);\n const [selectingExistingAction, setSelectingExistingAction] = useState(false);\n const [existingAppAction, setExistingAppAction] = useState<ExistingAppAction | null>(null);\n\n // Auto-deploy states\n const [selectingAutoDeploy, setSelectingAutoDeploy] = useState(false);\n const [autoDeployChoice, setAutoDeployChoice] = useState<AutoDeployChoice | null>(null);\n const [webhookPort, setWebhookPort] = useState<number>(0);\n const [webhookSecret, setWebhookSecret] = useState<string>('');\n const [pollingInterval, setPollingInterval] = useState<number>(10);\n\n const [serverIp, setServerIp] = useState<string>('');\n\n const appDir = `/var/www/${props.name}`;\n const repoDir = `/var/repo/${props.name}.git`;\n const gitHost = getGitHost(repoUrl);\n const keyInstructions = getDeployKeyInstructions(gitHost);\n\n const updateTask = (task: keyof TaskState, status: TaskStatus) => {\n setTasks((prev) => ({ ...prev, [task]: status }));\n };\n\n // Handle key confirmation - trigger verification\n useInput((input, key) => {\n if (waitingForKeySetup && !keyConfirmed && !keyVerifying) {\n if (input.toLowerCase() === 'y' || key.return) {\n setKeyConfirmed(true);\n setKeyVerifying(true);\n setKeyVerifyError(null);\n } else if (input.toLowerCase() === 'n' || key.escape) {\n setError('Deployment cancelled. Please add the deploy key and try again.');\n }\n }\n // Allow retry on 'r' if verification failed\n if (keyVerifyError && !keyVerifying) {\n if (input.toLowerCase() === 'r') {\n setKeyVerifying(true);\n setKeyVerifyError(null);\n } else if (input.toLowerCase() === 'q' || key.escape) {\n setError('Deployment cancelled. Please add the deploy key and try again.');\n }\n }\n });\n\n // Step 1: Connect\n useEffect(() => {\n const run = async () => {\n updateTask('connect', 'running');\n try {\n const sshClient = await connect(props);\n setClient(sshClient);\n\n const ipResult = await exec(sshClient, \"hostname -I | awk '{print $1}'\");\n setServerIp(ipResult.stdout.trim());\n\n updateTask('connect', 'success');\n } catch (err) {\n updateTask('connect', 'error');\n setError(`Connection failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, []);\n\n // Step 2: Install Caddy\n useEffect(() => {\n if (!client || tasks.connect !== 'success' || tasks.caddy !== 'pending') return;\n\n const run = async () => {\n updateTask('caddy', 'running');\n try {\n await execScript(client, SCRIPTS.installCaddy(), true);\n updateTask('caddy', 'success');\n } catch (err) {\n updateTask('caddy', 'error');\n setError(`Caddy installation failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.connect]);\n\n // Step 3: Install Node.js\n useEffect(() => {\n if (!client || tasks.caddy !== 'success' || tasks.node !== 'pending') return;\n\n const run = async () => {\n updateTask('node', 'running');\n try {\n await execScript(client, SCRIPTS.installNode(), true);\n updateTask('node', 'success');\n } catch (err) {\n updateTask('node', 'error');\n setError(`Node.js installation failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.caddy]);\n\n // Step 4: Ask for deploy method (if not provided via --repo)\n useEffect(() => {\n if (tasks.node !== 'success' || selectingMethod || deployMethod !== null) return;\n setSelectingMethod(true);\n }, [tasks.node]);\n\n const handleMethodSelect = (item: { value: string }) => {\n setSelectingMethod(false);\n const method = item.value as DeployMethod;\n setDeployMethod(method);\n\n if ((method === 'clone-public' || method === 'clone-private') && !repoUrl) {\n setEnteringRepo(true);\n }\n };\n\n const handleRepoSubmit = (value: string) => {\n setRepoUrl(value);\n setEnteringRepo(false);\n };\n\n // Step 5: Check if app exists (for clone methods)\n useEffect(() => {\n if (!client || !deployMethod || enteringRepo) return;\n if (deployMethod === 'push') {\n setAppExists(false); // Push-to-deploy handles this differently\n return;\n }\n if (appExists !== null) return;\n\n const run = async () => {\n try {\n const result = await exec(client, SCRIPTS.checkAppExists(props.name));\n setAppExists(result.stdout.trim() === 'exists');\n } catch {\n setAppExists(false);\n }\n };\n run();\n }, [client, deployMethod, enteringRepo, repoUrl]);\n\n // Step 5b: Show existing app options if needed\n useEffect(() => {\n if (appExists === true && !selectingExistingAction && existingAppAction === null) {\n setSelectingExistingAction(true);\n }\n if (appExists === false && existingAppAction === null) {\n setExistingAppAction('replace'); // No existing app, proceed with fresh clone\n }\n }, [appExists]);\n\n const handleExistingAppSelect = (item: { value: string }) => {\n setSelectingExistingAction(false);\n const action = item.value as ExistingAppAction;\n if (action === 'cancel') {\n setError('Deployment cancelled.');\n return;\n }\n setExistingAppAction(action);\n };\n\n // Step 6: Generate deploy key (for private repos)\n useEffect(() => {\n if (!client || deployMethod !== 'clone-private' || !repoUrl || tasks.deployKey !== 'pending') return;\n if (existingAppAction === null) return;\n\n const run = async () => {\n updateTask('deployKey', 'running');\n try {\n const result = await execScript(client, SCRIPTS.generateDeployKey(props.name, props.user || 'deploy'), true);\n setDeployKey(result.stdout.trim());\n updateTask('deployKey', 'success');\n setWaitingForKeySetup(true);\n } catch (err) {\n updateTask('deployKey', 'error');\n setError(`Deploy key generation failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, deployMethod, repoUrl, existingAppAction]);\n\n // Skip deploy key for non-private methods\n useEffect(() => {\n if (deployMethod && deployMethod !== 'clone-private' && tasks.deployKey === 'pending' && existingAppAction !== null) {\n updateTask('deployKey', 'skipped');\n }\n }, [deployMethod, existingAppAction]);\n\n // Step 6b: Verify deploy key works\n useEffect(() => {\n if (!client || !keyVerifying || keyVerified) return;\n\n const run = async () => {\n try {\n // Test SSH connection to git host (run as deploy user, not root)\n const result = await execScript(client, SCRIPTS.testGitConnection(gitHost), false);\n const output = result.stdout.toLowerCase();\n \n // Check for error indicators FIRST (more specific)\n if (output.includes('permission denied') && !output.includes('successfully authenticated')) {\n setKeyVerifyError('Permission denied. The deploy key may not be added correctly or may not have read access.');\n setKeyVerifying(false);\n return;\n }\n \n // Check for success indicators\n // GitHub: \"Hi user/repo! You've successfully authenticated\"\n // GitLab: \"Welcome to GitLab\"\n // Bitbucket: \"logged in as\"\n if (\n output.includes('successfully authenticated') ||\n output.includes('welcome to gitlab') ||\n output.includes('logged in as') ||\n (output.includes('hi ') && output.includes('!')) // GitHub format: \"Hi user/repo!\"\n ) {\n setKeyVerified(true);\n setKeyVerifying(false);\n setWaitingForKeySetup(false);\n } else if (output.includes('could not resolve') || output.includes('connection refused')) {\n setKeyVerifyError(`Could not connect to ${gitHost}. Check your network connection.`);\n setKeyVerifying(false);\n } else {\n // If no clear indicators, show actual output for debugging\n setKeyVerifyError(`Unexpected response from ${gitHost}: ${output.substring(0, 200)}`);\n setKeyVerifying(false);\n }\n } catch (err) {\n setKeyVerifyError(`Connection test failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n setKeyVerifying(false);\n }\n };\n run();\n }, [client, keyVerifying, keyVerified, gitHost]);\n\n // Step 7: Setup deployment\n useEffect(() => {\n if (!client || !deployMethod || tasks.deploy !== 'pending') return;\n if (tasks.deployKey !== 'success' && tasks.deployKey !== 'skipped') return;\n // For private repos, require verified key (not just confirmed)\n if (deployMethod === 'clone-private' && !keyVerified) return;\n if ((deployMethod === 'clone-public' || deployMethod === 'clone-private') && !repoUrl) return;\n if (existingAppAction === null) return;\n\n const run = async () => {\n updateTask('deploy', 'running');\n try {\n if (deployMethod === 'push') {\n await execScript(client, SCRIPTS.setupPushDeploy(props.name, props.branch, props.user || 'deploy'), true);\n } else {\n // For private repos, test connection first\n if (deployMethod === 'clone-private') {\n await execScript(client, SCRIPTS.testGitConnection(gitHost), true);\n }\n\n // Clone fresh or update based on user choice\n if (existingAppAction === 'replace') {\n await execScript(client, SCRIPTS.cloneRepoFresh(props.name, repoUrl, props.branch, props.user || 'deploy'), true);\n } else {\n await execScript(client, SCRIPTS.updateRepo(props.name, props.branch, props.user || 'deploy'), true);\n }\n\n await execScript(client, SCRIPTS.createUpdateScript(props.name, props.branch, props.user || 'deploy'), true);\n }\n updateTask('deploy', 'success');\n } catch (err) {\n updateTask('deploy', 'error');\n setError(`Deployment setup failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, deployMethod, repoUrl, keyVerified, tasks.deployKey, existingAppAction]);\n\n // Step 8: Ask about auto-deploy (only for clone methods)\n useEffect(() => {\n if (tasks.deploy !== 'success' || tasks.webhook !== 'pending') return;\n if (deployMethod === 'push') {\n // Push-to-deploy already has automatic deployment via git hook\n updateTask('webhook', 'skipped');\n return;\n }\n if (!selectingAutoDeploy && autoDeployChoice === null) {\n setSelectingAutoDeploy(true);\n }\n }, [tasks.deploy, deployMethod]);\n\n const handleAutoDeploySelect = async (item: { value: string }) => {\n setSelectingAutoDeploy(false);\n const choice = item.value as AutoDeployChoice;\n setAutoDeployChoice(choice);\n\n if (choice === 'none') {\n updateTask('webhook', 'skipped');\n }\n };\n\n // Step 8b: Setup auto-deploy if chosen\n useEffect(() => {\n if (!client || !autoDeployChoice || autoDeployChoice === 'none' || tasks.webhook !== 'pending') return;\n\n const run = async () => {\n updateTask('webhook', 'running');\n try {\n const user = props.user || 'deploy';\n\n if (autoDeployChoice === 'polling') {\n // Setup polling service\n await execScript(client, SCRIPTS.setupPolling(props.name, props.branch, user, pollingInterval), true);\n\n // Save config\n const config = {\n repo: repoUrl,\n branch: props.branch,\n autoDeployType: 'polling',\n pollingInterval: pollingInterval,\n };\n await execScript(client, SCRIPTS.saveConfig(props.name, config), true);\n } else if (autoDeployChoice === 'webhook') {\n // Find available port\n const portResult = await exec(client, SCRIPTS.findAvailablePort());\n const port = parseInt(portResult.stdout.trim(), 10) || 9000;\n setWebhookPort(port);\n\n // Generate a random secret\n const secret = crypto.randomBytes(32).toString('hex');\n setWebhookSecret(secret);\n\n // Setup webhook handler\n await execScript(client, SCRIPTS.setupWebhook(props.name, props.branch, port, secret), true);\n\n // Save config\n const config = {\n repo: repoUrl,\n branch: props.branch,\n autoDeployType: 'webhook',\n webhookPort: port,\n };\n await execScript(client, SCRIPTS.saveConfig(props.name, config), true);\n }\n\n updateTask('webhook', 'success');\n } catch (err) {\n updateTask('webhook', 'error');\n setError(`Auto-deploy setup failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, autoDeployChoice]);\n\n // Step 9: Wait for TLS choice\n useEffect(() => {\n if (tasks.deploy !== 'success') return;\n if (tasks.webhook !== 'success' && tasks.webhook !== 'skipped') return;\n if (selectingTls || tlsChoice !== null) return;\n setSelectingTls(true);\n }, [tasks.deploy, tasks.webhook]);\n\n // Step 9: Configure Caddy\n useEffect(() => {\n if (!client || !tlsChoice || tasks.caddyConfig !== 'pending') return;\n\n const run = async () => {\n updateTask('caddyConfig', 'running');\n try {\n let script: string;\n switch (tlsChoice) {\n case 'ondemand':\n script = SCRIPTS.caddyOnDemand(appDir);\n break;\n case 'specific':\n script = SCRIPTS.caddyOnDemand(appDir);\n break;\n case 'none':\n script = SCRIPTS.caddyHttp(appDir);\n break;\n }\n await execScript(client, script, true);\n updateTask('caddyConfig', 'success');\n disconnect(client);\n setTimeout(() => exit(), 100);\n } catch (err) {\n updateTask('caddyConfig', 'error');\n setError(`Caddy config failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tlsChoice]);\n\n const handleTlsSelect = (item: { value: string }) => {\n setSelectingTls(false);\n setTlsChoice(item.value as TlsChoice);\n };\n\n // Handle errors\n useEffect(() => {\n if (error && client) {\n disconnect(client);\n setTimeout(() => exit(), 100);\n }\n }, [error]);\n\n const allDone = tasks.caddyConfig === 'success';\n const isClone = deployMethod === 'clone-public' || deployMethod === 'clone-private';\n const deployLabel = isClone\n ? existingAppAction === 'update'\n ? `Update ${props.name}`\n : `Clone from ${repoUrl || 'repository'}`\n : 'Setup push-to-deploy';\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Application Provisioning\" subtitle={`Host: ${props.host}`} />\n\n <Task label=\"Connect to server\" status={tasks.connect} />\n <Task label=\"Install Caddy\" status={tasks.caddy} />\n <Task label=\"Install Node.js & PM2\" status={tasks.node} />\n {deployMethod === 'clone-private' && (\n <Task label=\"Generate deploy key\" status={tasks.deployKey} />\n )}\n <Task label={deployLabel} status={tasks.deploy} />\n {(deployMethod === 'clone-public' || deployMethod === 'clone-private') && autoDeployChoice && autoDeployChoice !== 'none' && (\n <Task label={`Setup ${autoDeployChoice === 'polling' ? 'git polling' : 'webhook'} for auto-deploy`} status={tasks.webhook} />\n )}\n <Task label=\"Configure Caddy\" status={tasks.caddyConfig} />\n\n {selectingMethod && deployMethod === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Select deployment method:</Text>\n <SelectInput items={deployOptions} onSelect={handleMethodSelect} />\n </Box>\n )}\n\n {enteringRepo && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Enter repository URL:</Text>\n <Text color=\"gray\">\n {deployMethod === 'clone-private'\n ? '(Use SSH URL: git@github.com:user/repo.git)'\n : '(e.g., https://github.com/user/repo.git)'}\n </Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={repoUrl} onChange={setRepoUrl} onSubmit={handleRepoSubmit} />\n </Box>\n </Box>\n )}\n\n {selectingExistingAction && existingAppAction === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">⚠ App directory {appDir} already exists</Text>\n <Text color=\"gray\">What would you like to do?</Text>\n <Box marginTop={1}>\n <SelectInput items={existingAppOptions} onSelect={handleExistingAppSelect} />\n </Box>\n </Box>\n )}\n\n {waitingForKeySetup && deployKey && !keyConfirmed && !keyVerifying && !keyVerified && !keyVerifyError && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">━━━ Deploy Key Generated ━━━</Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Public key (copy this):</Text>\n <Box marginY={1} paddingX={1} borderStyle=\"single\" borderColor=\"cyan\">\n <Text color=\"cyan\">{deployKey}</Text>\n </Box>\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Add this key to {gitHost}:</Text>\n {keyInstructions.steps.map((step, i) => (\n <Text key={i} color=\"gray\"> {step}</Text>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text color=\"yellow\">Have you added the deploy key to {gitHost}? </Text>\n <Text color=\"gray\">(y/n) </Text>\n </Box>\n </Box>\n )}\n\n {keyVerifying && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">━━━ Verifying Deploy Key ━━━</Text>\n <Box marginTop={1}>\n <Spinner type=\"dots\" />\n <Text color=\"gray\"> Testing SSH connection to {gitHost}...</Text>\n </Box>\n </Box>\n )}\n\n {keyVerified && !error && (\n <Box marginTop={1}>\n <Text color=\"green\">✓ Deploy key verified successfully!</Text>\n </Box>\n )}\n\n {keyVerifyError && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"red\">━━━ Deploy Key Verification Failed ━━━</Text>\n <Box marginTop={1}>\n <Text color=\"red\">✗ {keyVerifyError}</Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Please check:</Text>\n <Text color=\"gray\"> 1. The deploy key is added to {gitHost}</Text>\n <Text color=\"gray\"> 2. The key has read access to the repository</Text>\n <Text color=\"gray\"> 3. The repository URL is correct</Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Public key to add:</Text>\n <Box marginY={1} paddingX={1} borderStyle=\"single\" borderColor=\"cyan\">\n <Text color=\"cyan\">{deployKey}</Text>\n </Box>\n </Box>\n <Box marginTop={1}>\n <Text color=\"yellow\">Press (r) to retry or (q) to quit</Text>\n </Box>\n </Box>\n )}\n\n {selectingAutoDeploy && autoDeployChoice === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Enable automatic deployment?</Text>\n <Text color=\"gray\">Auto-deploy when you push to {props.branch} branch.</Text>\n <Box marginTop={1}>\n <SelectInput items={autoDeployOptions} onSelect={handleAutoDeploySelect} />\n </Box>\n </Box>\n )}\n\n {selectingTls && tlsChoice === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Select TLS configuration:</Text>\n <SelectInput items={tlsOptions} onSelect={handleTlsSelect} />\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n\n {allDone && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"green\" bold>✓ Application provisioning complete</Text>\n <Box marginTop={1} flexDirection=\"column\">\n {deployMethod === 'push' ? (\n <>\n <Text bold>Git remote (add to local project):</Text>\n <Text color=\"cyan\"> git remote add production ssh://{props.user}@{serverIp}{repoDir}</Text>\n <Box marginTop={1}>\n <Text bold>Deploy with:</Text>\n </Box>\n <Text color=\"cyan\"> git push production {props.branch}</Text>\n </>\n ) : (\n <>\n <Text bold>App {existingAppAction === 'update' ? 'updated' : 'deployed'} from: <Text color=\"cyan\">{repoUrl}</Text></Text>\n <Box marginTop={1}>\n <Text bold>Manual update:</Text>\n </Box>\n <Text color=\"cyan\"> ssh {props.user}@{serverIp} \"sudo update-{props.name}\"</Text>\n\n {autoDeployChoice === 'polling' && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">━━━ Auto-Deploy (Git Polling) ━━━</Text>\n <Text>Polling interval: <Text color=\"cyan\">{pollingInterval} seconds</Text></Text>\n <Text>Branch: <Text color=\"cyan\">{props.branch}</Text></Text>\n <Text color=\"gray\">The server checks for new commits and deploys automatically.</Text>\n <Box marginTop={1}>\n <Text>View logs: <Text color=\"cyan\">journalctl -u poll-{props.name} -f</Text></Text>\n </Box>\n </Box>\n )}\n\n {autoDeployChoice === 'webhook' && webhookPort > 0 && (\n <>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">━━━ Auto-Deploy (Webhook) ━━━</Text>\n <Text>Webhook URL: <Text color=\"cyan\">http://{serverIp}:{webhookPort}/webhook</Text></Text>\n <Text>Secret: <Text color=\"cyan\">{webhookSecret}</Text></Text>\n <Text>Branch: <Text color=\"cyan\">{props.branch}</Text></Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Add webhook to your repository:</Text>\n {gitHost === 'github.com' && (\n <>\n <Text color=\"gray\"> 1. Go to your repo → Settings → Webhooks → Add webhook</Text>\n <Text color=\"gray\"> 2. Payload URL: http://{serverIp}:{webhookPort}/webhook</Text>\n <Text color=\"gray\"> 3. Content type: application/json</Text>\n <Text color=\"gray\"> 4. Secret: {webhookSecret}</Text>\n <Text color=\"gray\"> 5. Select \"Just the push event\"</Text>\n </>\n )}\n {gitHost === 'gitlab.com' && (\n <>\n <Text color=\"gray\"> 1. Go to your repo → Settings → Webhooks</Text>\n <Text color=\"gray\"> 2. URL: http://{serverIp}:{webhookPort}/webhook</Text>\n <Text color=\"gray\"> 3. Secret token: {webhookSecret}</Text>\n <Text color=\"gray\"> 4. Trigger: Push events</Text>\n </>\n )}\n {gitHost === 'bitbucket.org' && (\n <>\n <Text color=\"gray\"> 1. Go to your repo → Repository settings → Webhooks</Text>\n <Text color=\"gray\"> 2. URL: http://{serverIp}:{webhookPort}/webhook</Text>\n <Text color=\"gray\"> 3. Triggers: Repository push</Text>\n </>\n )}\n </Box>\n </>\n )}\n </>\n )}\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport { Header, Task, type TaskStatus } from '../components/index.js';\nimport { connect, exec, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface SshKeyCommandProps extends SSHOptions {\n add?: string;\n list?: boolean;\n}\n\nexport function SshKeyCommand(props: SshKeyCommandProps) {\n const { exit } = useApp();\n const [client, setClient] = useState<Client | null>(null);\n const [status, setStatus] = useState<TaskStatus>('pending');\n const [error, setError] = useState<string | null>(null);\n const [keys, setKeys] = useState<string[]>([]);\n const [message, setMessage] = useState<string>('');\n\n useEffect(() => {\n const run = async () => {\n setStatus('running');\n\n try {\n const sshClient = await connect(props);\n setClient(sshClient);\n\n if (props.list) {\n const result = await exec(sshClient, 'cat ~/.ssh/authorized_keys 2>/dev/null || echo \"\"');\n const keyList = result.stdout\n .trim()\n .split('\\n')\n .filter((k) => k.length > 0)\n .map((k) => {\n // Extract key type and comment\n const parts = k.split(' ');\n const type = parts[0] || 'unknown';\n const comment = parts[2] || 'no comment';\n const keyPreview = parts[1]?.slice(-12) || '';\n return `${type} ...${keyPreview} ${comment}`;\n });\n setKeys(keyList);\n setStatus('success');\n setMessage(`Found ${keyList.length} key(s)`);\n } else if (props.add) {\n // Validate key format\n const keyPattern = /^(ssh-rsa|ssh-ed25519|ssh-dss|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521)\\s+\\S+/;\n if (!keyPattern.test(props.add)) {\n throw new Error('Invalid SSH key format');\n }\n\n // Check for duplicates\n const existing = await exec(sshClient, 'cat ~/.ssh/authorized_keys 2>/dev/null || echo \"\"');\n if (existing.stdout.includes(props.add)) {\n setStatus('success');\n setMessage('Key already exists (skipped)');\n } else {\n // Add key\n const escapedKey = props.add.replace(/'/g, \"'\\\\''\");\n await exec(sshClient, `echo '${escapedKey}' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys`);\n setStatus('success');\n setMessage('Key added successfully');\n }\n } else {\n setStatus('error');\n setError('Specify --add <key> or --list');\n }\n\n disconnect(sshClient);\n setTimeout(() => exit(), 100);\n } catch (err) {\n setStatus('error');\n setError(err instanceof Error ? err.message : String(err));\n if (client) disconnect(client);\n setTimeout(() => exit(), 100);\n }\n };\n\n run();\n }, []);\n\n const operation = props.list ? 'List SSH keys' : 'Add SSH key';\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"SSH Key Management\" subtitle={`Host: ${props.host}`} />\n\n <Task label={operation} status={status} message={message} />\n\n {props.list && keys.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Authorized keys:</Text>\n {keys.map((key, i) => (\n <Text key={i} color=\"gray\"> {i + 1}. {key}</Text>\n ))}\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport { Header, Task, type TaskStatus } from '../components/index.js';\nimport { connect, exec, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface StatusCommandProps extends SSHOptions {}\n\ninterface ServiceStatus {\n name: string;\n running: boolean;\n status: string;\n}\n\ninterface SystemInfo {\n hostname: string;\n uptime: string;\n load: string;\n memory: string;\n disk: string;\n}\n\nexport function StatusCommand(props: StatusCommandProps) {\n const { exit } = useApp();\n const [taskStatus, setTaskStatus] = useState<TaskStatus>('pending');\n const [error, setError] = useState<string | null>(null);\n const [services, setServices] = useState<ServiceStatus[]>([]);\n const [system, setSystem] = useState<SystemInfo | null>(null);\n\n useEffect(() => {\n const run = async () => {\n setTaskStatus('running');\n\n try {\n const client = await connect(props);\n\n // Get system info\n const [hostnameRes, uptimeRes, loadRes, memRes, diskRes] = await Promise.all([\n exec(client, 'hostname'),\n exec(client, \"uptime -p 2>/dev/null || uptime | awk -F'up' '{print $2}' | awk -F',' '{print $1}'\"),\n exec(client, \"cat /proc/loadavg | awk '{print $1, $2, $3}'\"),\n exec(client, \"free -h | awk '/^Mem:/ {print $3 \\\"/\\\" $2}'\"),\n exec(client, \"df -h / | awk 'NR==2 {print $3 \\\"/\\\" $2 \\\" (\\\" $5 \\\")\\\"}'\"),\n ]);\n\n setSystem({\n hostname: hostnameRes.stdout.trim(),\n uptime: uptimeRes.stdout.trim(),\n load: loadRes.stdout.trim(),\n memory: memRes.stdout.trim(),\n disk: diskRes.stdout.trim(),\n });\n\n // Check services\n const serviceChecks = ['caddy', 'ssh', 'ufw'];\n const serviceResults: ServiceStatus[] = [];\n\n for (const svc of serviceChecks) {\n const result = await exec(client, `systemctl is-active ${svc} 2>/dev/null || echo \"not-found\"`);\n const status = result.stdout.trim();\n serviceResults.push({\n name: svc,\n running: status === 'active',\n status,\n });\n }\n\n // Check PM2\n const pm2Result = await exec(client, 'pm2 list 2>/dev/null | grep -E \"online|stopped|errored\" | wc -l || echo \"0\"');\n const pm2Count = parseInt(pm2Result.stdout.trim(), 10);\n serviceResults.push({\n name: 'pm2',\n running: pm2Count > 0,\n status: pm2Count > 0 ? `${pm2Count} process(es)` : 'no processes',\n });\n\n setServices(serviceResults);\n setTaskStatus('success');\n disconnect(client);\n setTimeout(() => exit(), 100);\n } catch (err) {\n setTaskStatus('error');\n setError(err instanceof Error ? err.message : String(err));\n setTimeout(() => exit(), 100);\n }\n };\n\n run();\n }, []);\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Server Status\" subtitle={`Host: ${props.host}`} />\n\n <Task label=\"Checking server status\" status={taskStatus} />\n\n {system && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>System:</Text>\n <Text color=\"gray\"> Hostname: <Text color=\"white\">{system.hostname}</Text></Text>\n <Text color=\"gray\"> Uptime: <Text color=\"white\">{system.uptime}</Text></Text>\n <Text color=\"gray\"> Load: <Text color=\"white\">{system.load}</Text></Text>\n <Text color=\"gray\"> Memory: <Text color=\"white\">{system.memory}</Text></Text>\n <Text color=\"gray\"> Disk: <Text color=\"white\">{system.disk}</Text></Text>\n </Box>\n )}\n\n {services.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Services:</Text>\n {services.map((svc) => (\n <Box key={svc.name}>\n <Text color=\"gray\"> </Text>\n <Text color={svc.running ? 'green' : 'red'}>\n {svc.running ? '●' : '○'}\n </Text>\n <Text> {svc.name}: </Text>\n <Text color={svc.running ? 'green' : 'yellow'}>{svc.status}</Text>\n </Box>\n ))}\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport { Header, Task, type TaskStatus } from '../components/index.js';\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface DeployCommandProps extends SSHOptions {\n name: string;\n}\n\nexport function DeployCommand(props: DeployCommandProps) {\n const { exit } = useApp();\n const [status, setStatus] = useState<TaskStatus>('pending');\n const [output, setOutput] = useState<string[]>([]);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const run = async () => {\n setStatus('running');\n\n try {\n const client = await connect(props);\n\n // Check if update script exists\n const checkResult = await exec(client, `test -f /usr/local/bin/update-${props.name} && echo \"exists\" || echo \"not_found\"`);\n\n if (checkResult.stdout.trim() !== 'exists') {\n throw new Error(`Update script for '${props.name}' not found. Run 'provisor app' first.`);\n }\n\n // Run the update script and capture output\n const result = await exec(client, `sudo /usr/local/bin/update-${props.name} 2>&1`);\n\n setOutput(result.stdout.trim().split('\\n'));\n setStatus('success');\n\n disconnect(client);\n setTimeout(() => exit(), 100);\n } catch (err) {\n setStatus('error');\n setError(err instanceof Error ? err.message : String(err));\n setTimeout(() => exit(), 100);\n }\n };\n\n run();\n }, []);\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Deploy Application\" subtitle={`App: ${props.name} | Host: ${props.host}`} />\n\n <Task label={`Deploying ${props.name}`} status={status} />\n\n {output.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n {output.map((line, i) => (\n <Text key={i} color=\"gray\">{line}</Text>\n ))}\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n\n {status === 'success' && (\n <Box marginTop={1}>\n <Text color=\"green\" bold>✓ Deployment complete</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport TextInput from 'ink-text-input';\nimport { Header, Task, type TaskStatus } from '../components/index.js';\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface ConfigCommandProps extends SSHOptions {\n name: string;\n show?: boolean;\n repo?: string;\n branch?: string;\n newKey?: boolean;\n deleteKey?: boolean;\n webhookSecret?: string;\n disableWebhook?: boolean;\n pollingInterval?: number;\n disablePolling?: boolean;\n enablePolling?: boolean;\n}\n\ntype ConfigAction = 'show' | 'repo' | 'branch' | 'new-key' | 'delete-key' | 'webhook-secret' | 'disable-webhook' | 'polling-interval' | 'enable-polling' | 'disable-polling';\n\ninterface AppConfig {\n repo: string;\n branch: string;\n deployKey: string | null;\n webhookEnabled: boolean;\n webhookPort: number;\n pollingEnabled: boolean;\n pollingInterval: number;\n autoDeployType: 'webhook' | 'polling' | 'none';\n}\n\nconst SCRIPTS = {\n // Read current config\n getConfig: (name: string) => `\n CONFIG_FILE=\"/var/www/${name}/.provisor.json\"\n if [ -f \"$CONFIG_FILE\" ]; then\n sudo cat \"$CONFIG_FILE\"\n else\n # Try to construct from git info\n APP_DIR=\"/var/www/${name}\"\n if [ -d \"$APP_DIR/.git\" ]; then\n cd \"$APP_DIR\"\n REPO=$(git remote get-url origin 2>/dev/null || echo \"\")\n BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\n echo '{\"repo\":\"'\"$REPO\"'\",\"branch\":\"'\"$BRANCH\"'\",\"webhookEnabled\":false,\"webhookPort\":0}'\n else\n echo '{\"error\":\"App not found or not a git repository\"}'\n fi\n fi\n `,\n\n // Save config\n saveConfig: (name: string, config: string) => `\n CONFIG_FILE=\"/var/www/${name}/.provisor.json\"\n echo '${config}' > \"$CONFIG_FILE\"\n chmod 600 \"$CONFIG_FILE\"\n `,\n\n // Update repository URL\n updateRepo: (name: string, repoUrl: string, user: string) => `\n APP_DIR=\"/var/www/${name}\"\n cd \"$APP_DIR\"\n sudo -u ${user} git remote set-url origin \"${repoUrl}\"\n echo \"repo-updated\"\n `,\n\n // Update branch\n updateBranch: (name: string, branch: string, user: string) => `\n APP_DIR=\"/var/www/${name}\"\n cd \"$APP_DIR\"\n\n # Fetch all branches\n sudo -u ${user} git fetch origin\n\n # Switch to new branch\n sudo -u ${user} git checkout ${branch} 2>/dev/null || sudo -u ${user} git checkout -b ${branch} origin/${branch}\n sudo -u ${user} git reset --hard origin/${branch}\n\n # Update the update script with new branch\n UPDATE_SCRIPT=\"/usr/local/bin/update-${name}\"\n if [ -f \"$UPDATE_SCRIPT\" ]; then\n sed -i 's/BRANCH=\".*\"/BRANCH=\"${branch}\"/' \"$UPDATE_SCRIPT\"\n fi\n\n # Update webhook service if exists\n WEBHOOK_SERVICE=\"/etc/systemd/system/webhook-${name}.service\"\n if [ -f \"$WEBHOOK_SERVICE\" ]; then\n sed -i 's/--branch [^ ]*/--branch ${branch}/' \"$WEBHOOK_SERVICE\"\n systemctl daemon-reload\n systemctl restart webhook-${name} 2>/dev/null || true\n fi\n\n echo \"branch-updated\"\n `,\n\n // Generate new deploy key\n generateNewKey: (name: string, user: string) => `\n SSH_DIR=\"/home/${user}/.ssh\"\n KEY_FILE=\"$SSH_DIR/deploy_${name}\"\n\n # Backup old key if exists\n if [ -f \"$KEY_FILE\" ]; then\n mv \"$KEY_FILE\" \"$KEY_FILE.old.$(date +%s)\"\n mv \"$KEY_FILE.pub\" \"$KEY_FILE.pub.old.$(date +%s)\"\n fi\n\n # Generate new key\n ssh-keygen -t ed25519 -f \"$KEY_FILE\" -N \"\" -C \"deploy-key-${name}\"\n\n chown ${user}:${user} \"$KEY_FILE\" \"$KEY_FILE.pub\"\n chmod 600 \"$KEY_FILE\"\n chmod 644 \"$KEY_FILE.pub\"\n\n cat \"$KEY_FILE.pub\"\n `,\n\n // Delete deploy key\n deleteDeployKey: (name: string, user: string) => `\n SSH_DIR=\"/home/${user}/.ssh\"\n KEY_FILE=\"$SSH_DIR/deploy_${name}\"\n\n if [ -f \"$KEY_FILE\" ]; then\n rm -f \"$KEY_FILE\" \"$KEY_FILE.pub\"\n\n # Remove from SSH config\n if [ -f \"$SSH_DIR/config\" ]; then\n sed -i \"/# Deploy key for ${name}/,+4d\" \"$SSH_DIR/config\"\n fi\n\n echo \"key-deleted\"\n else\n echo \"key-not-found\"\n fi\n `,\n\n // Get current deploy key\n getDeployKey: (name: string, user: string) => `\n KEY_FILE=\"/home/${user}/.ssh/deploy_${name}.pub\"\n if [ -f \"$KEY_FILE\" ]; then\n cat \"$KEY_FILE\"\n else\n echo \"\"\n fi\n `,\n\n // Update webhook secret\n updateWebhookSecret: (name: string, secret: string) => `\n WEBHOOK_SERVICE=\"/etc/systemd/system/webhook-${name}.service\"\n if [ -f \"$WEBHOOK_SERVICE\" ]; then\n sed -i \"s/--secret '[^']*'/--secret '${secret}'/\" \"$WEBHOOK_SERVICE\"\n systemctl daemon-reload\n systemctl restart webhook-${name}\n echo \"webhook-secret-updated\"\n else\n echo \"webhook-not-configured\"\n fi\n `,\n\n // Disable webhook\n disableWebhook: (name: string) => `\n systemctl stop webhook-${name} 2>/dev/null || true\n systemctl disable webhook-${name} 2>/dev/null || true\n rm -f /etc/systemd/system/webhook-${name}.service\n systemctl daemon-reload\n echo \"webhook-disabled\"\n `,\n\n // Get webhook status\n getWebhookStatus: (name: string) => `\n if systemctl is-active --quiet webhook-${name} 2>/dev/null; then\n PORT=$(grep -oP '\\\\-\\\\-port \\\\K[0-9]+' /etc/systemd/system/webhook-${name}.service 2>/dev/null || echo \"\")\n echo \"running:$PORT\"\n else\n echo \"stopped\"\n fi\n `,\n\n // Get polling status (supports both systemd and daemon modes)\n getPollingStatus: (name: string) => `\n # Check systemd timer first\n if systemctl is-active --quiet poll-${name}.timer 2>/dev/null; then\n INTERVAL=$(grep -oP 'OnUnitActiveSec=\\\\\\\\K[0-9]+' /etc/systemd/system/poll-${name}.timer 2>/dev/null || echo \"10\")\n echo \"running:$INTERVAL:systemd\"\n # Check daemon mode (PID file) - use ps -p instead of kill -0 (no permission issues)\n elif [ -f /var/run/poll-${name}.pid ] && ps -p $(cat /var/run/poll-${name}.pid) > /dev/null 2>&1; then\n INTERVAL=$(grep -oP 'INTERVAL=\\\\K[0-9]+' /usr/local/bin/poll-${name}-daemon.sh 2>/dev/null || echo \"10\")\n echo \"running:$INTERVAL:daemon\"\n else\n echo \"stopped\"\n fi\n `,\n\n // Update polling interval (supports both systemd and daemon modes)\n updatePollingInterval: (name: string, interval: number) => `\n TIMER_FILE=\"/etc/systemd/system/poll-${name}.timer\"\n DAEMON_FILE=\"/usr/local/bin/poll-${name}-daemon.sh\"\n \n if [ -f \"$TIMER_FILE\" ]; then\n # Systemd mode\n sed -i \"s/OnUnitActiveSec=[0-9]*s/OnUnitActiveSec=${interval}s/\" \"$TIMER_FILE\"\n systemctl daemon-reload\n systemctl restart poll-${name}.timer\n echo \"polling-interval-updated:${interval}:systemd\"\n elif [ -f \"$DAEMON_FILE\" ]; then\n # Daemon mode - update interval and restart (all as root)\n sudo sed -i \"s/INTERVAL=[0-9]*/INTERVAL=${interval}/\" \"$DAEMON_FILE\"\n \n # Restart daemon (use sudo bash -c for proper backgrounding)\n if [ -f /var/run/poll-${name}.pid ]; then\n sudo kill $(cat /var/run/poll-${name}.pid) 2>/dev/null || true\n sleep 1\n fi\n sudo bash -c 'nohup /usr/local/bin/poll-${name}-daemon.sh > /dev/null 2>&1 &'\n echo \"polling-interval-updated:${interval}:daemon\"\n else\n echo \"polling-not-configured\"\n fi\n `,\n\n // Enable polling (supports both systemd and daemon modes)\n enablePolling: (name: string, branch: string, user: string, interval: number) => `\n # Check if systemd is available\n if pidof systemd > /dev/null 2>&1 || [ \"$(cat /proc/1/comm 2>/dev/null)\" = \"systemd\" ]; then\n # SYSTEMD MODE\n if [ -f \"/etc/systemd/system/poll-${name}.timer\" ]; then\n systemctl enable poll-${name}.timer\n systemctl start poll-${name}.timer\n echo \"polling-enabled:systemd\"\n else\n # Create from scratch (same as app.tsx)\n cat << 'POLLING_EOF' > /usr/local/bin/poll-${name}.sh\n#!/bin/bash\nset -e\nAPP_DIR=\"/var/www/${name}\"\nBRANCH=\"${branch}\"\nUSER=\"${user}\"\nLOCK_FILE=\"/tmp/poll-${name}.lock\"\nexec 200>\"$LOCK_FILE\"\nflock -n 200 || exit 0\ncd \"$APP_DIR\"\nsudo -u $USER git fetch origin \"$BRANCH\" --quiet 2>/dev/null\nLOCAL=$(git rev-parse HEAD)\nREMOTE=$(git rev-parse \"origin/$BRANCH\")\nif [ \"$LOCAL\" != \"$REMOTE\" ]; then\n echo \"[$(date -Iseconds)] New commit detected: $REMOTE\"\n sudo /usr/local/bin/update-${name}\nelse\n echo \"[$(date -Iseconds)] No changes\"\nfi\nPOLLING_EOF\n chmod +x /usr/local/bin/poll-${name}.sh\n\n cat << SERVICE_EOF > /etc/systemd/system/poll-${name}.service\n[Unit]\nDescription=Git polling service for ${name}\nAfter=network.target\n[Service]\nType=oneshot\nExecStart=/usr/local/bin/poll-${name}.sh\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=poll-${name}\nSERVICE_EOF\n\n cat << TIMER_EOF > /etc/systemd/system/poll-${name}.timer\n[Unit]\nDescription=Run git polling for ${name} every ${interval} seconds\n[Timer]\nOnBootSec=30\nOnUnitActiveSec=${interval}s\nAccuracySec=1s\n[Install]\nWantedBy=timers.target\nTIMER_EOF\n\n systemctl daemon-reload\n systemctl enable poll-${name}.timer\n systemctl start poll-${name}.timer\n echo \"polling-created:systemd\"\n fi\n else\n # DAEMON MODE (Docker/non-systemd)\n if [ -f /var/run/poll-${name}.pid ] && kill -0 $(cat /var/run/poll-${name}.pid) 2>/dev/null; then\n echo \"polling-already-running:daemon\"\n else\n # Create poll script if not exists\n if [ ! -f /usr/local/bin/poll-${name}.sh ]; then\n cat << 'POLLING_EOF' > /usr/local/bin/poll-${name}.sh\n#!/bin/bash\nset -e\nAPP_DIR=\"/var/www/${name}\"\nBRANCH=\"${branch}\"\nUSER=\"${user}\"\nLOCK_FILE=\"/tmp/poll-${name}.lock\"\nexec 200>\"$LOCK_FILE\"\nflock -n 200 || exit 0\ncd \"$APP_DIR\"\nsudo -u $USER git fetch origin \"$BRANCH\" --quiet 2>/dev/null\nLOCAL=$(git rev-parse HEAD)\nREMOTE=$(git rev-parse \"origin/$BRANCH\")\nif [ \"$LOCAL\" != \"$REMOTE\" ]; then\n echo \"[$(date -Iseconds)] New commit detected: $REMOTE\"\n sudo /usr/local/bin/update-${name}\nelse\n echo \"[$(date -Iseconds)] No changes\"\nfi\nPOLLING_EOF\n chmod +x /usr/local/bin/poll-${name}.sh\n fi\n\n # Create daemon script\n cat << DAEMON_EOF > /usr/local/bin/poll-${name}-daemon.sh\n#!/bin/bash\nLOG_FILE=\"/var/log/poll-${name}.log\"\nPID_FILE=\"/var/run/poll-${name}.pid\"\nINTERVAL=${interval}\necho \\$\\$ > \"\\$PID_FILE\"\necho \"[\\$(date -Iseconds)] Polling daemon started (every ${interval}s)\" >> \"\\$LOG_FILE\"\nwhile true; do\n /usr/local/bin/poll-${name}.sh >> \"\\$LOG_FILE\" 2>&1\n sleep \\$INTERVAL\ndone\nDAEMON_EOF\n chmod +x /usr/local/bin/poll-${name}-daemon.sh\n\n mkdir -p /var/log\n touch /var/log/poll-${name}.log\n nohup /usr/local/bin/poll-${name}-daemon.sh > /dev/null 2>&1 &\n echo \"polling-created:daemon\"\n fi\n fi\n `,\n\n // Disable polling (supports both systemd and daemon modes)\n disablePolling: (name: string) => `\n # Stop systemd timer if exists\n systemctl stop poll-${name}.timer 2>/dev/null || true\n systemctl disable poll-${name}.timer 2>/dev/null || true\n rm -f /etc/systemd/system/poll-${name}.timer\n rm -f /etc/systemd/system/poll-${name}.service\n systemctl daemon-reload 2>/dev/null || true\n \n # Stop daemon if running (use sudo since daemon runs as root)\n if [ -f /var/run/poll-${name}.pid ]; then\n sudo kill $(cat /var/run/poll-${name}.pid) 2>/dev/null || true\n rm -f /var/run/poll-${name}.pid\n fi\n \n # Clean up all polling files\n rm -f /usr/local/bin/poll-${name}.sh\n rm -f /usr/local/bin/poll-${name}-daemon.sh\n \n echo \"polling-disabled\"\n `,\n};\n\nconst configActions = [\n { label: 'Show current configuration', value: 'show' },\n { label: 'Change repository URL', value: 'repo' },\n { label: 'Change deploy branch', value: 'branch' },\n { label: 'Generate new deploy key', value: 'new-key' },\n { label: 'Delete deploy key', value: 'delete-key' },\n { label: 'Update webhook secret', value: 'webhook-secret' },\n { label: 'Disable webhook', value: 'disable-webhook' },\n { label: 'Change polling interval', value: 'polling-interval' },\n { label: 'Enable git polling', value: 'enable-polling' },\n { label: 'Disable git polling', value: 'disable-polling' },\n];\n\nexport function ConfigCommand(props: ConfigCommandProps) {\n const { exit } = useApp();\n const [client, setClient] = useState<Client | null>(null);\n const [status, setStatus] = useState<TaskStatus>('pending');\n const [error, setError] = useState<string | null>(null);\n const [output, setOutput] = useState<string[]>([]);\n\n // Selection states\n const [selectingAction, setSelectingAction] = useState(false);\n const [action, setAction] = useState<ConfigAction | null>(null);\n const [enteringValue, setEnteringValue] = useState(false);\n const [inputValue, setInputValue] = useState('');\n const [inputLabel, setInputLabel] = useState('');\n\n // Config data\n const [config, setConfig] = useState<AppConfig | null>(null);\n const [deployKey, setDeployKey] = useState<string | null>(null);\n const [webhookStatus, setWebhookStatus] = useState<string>('');\n\n // Determine initial action from props\n useEffect(() => {\n if (props.show) setAction('show');\n else if (props.repo) {\n setAction('repo');\n setInputValue(props.repo);\n }\n else if (props.branch) {\n setAction('branch');\n setInputValue(props.branch);\n }\n else if (props.newKey) setAction('new-key');\n else if (props.deleteKey) setAction('delete-key');\n else if (props.webhookSecret) {\n setAction('webhook-secret');\n setInputValue(props.webhookSecret);\n }\n else if (props.disableWebhook) setAction('disable-webhook');\n else if (props.pollingInterval) {\n setAction('polling-interval');\n setInputValue(String(props.pollingInterval));\n }\n else if (props.enablePolling) setAction('enable-polling');\n else if (props.disablePolling) setAction('disable-polling');\n }, []);\n\n // Connect\n useEffect(() => {\n const run = async () => {\n setStatus('running');\n try {\n const sshClient = await connect(props);\n setClient(sshClient);\n setStatus('success');\n } catch (err) {\n setStatus('error');\n setError(`Connection failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, []);\n\n // Show action selection if no action determined\n useEffect(() => {\n if (status === 'success' && action === null && !selectingAction) {\n setSelectingAction(true);\n }\n }, [status, action]);\n\n const handleActionSelect = (item: { value: string }) => {\n setSelectingAction(false);\n const selectedAction = item.value as ConfigAction;\n setAction(selectedAction);\n\n // Some actions need input\n if (selectedAction === 'repo') {\n setInputLabel('Enter new repository URL:');\n setEnteringValue(true);\n } else if (selectedAction === 'branch') {\n setInputLabel('Enter new branch name:');\n setEnteringValue(true);\n } else if (selectedAction === 'webhook-secret') {\n setInputLabel('Enter new webhook secret:');\n setEnteringValue(true);\n } else if (selectedAction === 'polling-interval') {\n setInputLabel('Enter polling interval in seconds (e.g., 10, 30, 60):');\n setEnteringValue(true);\n }\n };\n\n const handleInputSubmit = (value: string) => {\n setInputValue(value);\n setEnteringValue(false);\n };\n\n // Execute action\n useEffect(() => {\n if (!client || action === null || enteringValue) return;\n if ((action === 'repo' || action === 'branch' || action === 'webhook-secret' || action === 'polling-interval') && !inputValue) return;\n\n const run = async () => {\n try {\n const user = props.user || 'deploy';\n const lines: string[] = [];\n\n switch (action) {\n case 'show': {\n const configResult = await exec(client, SCRIPTS.getConfig(props.name));\n const configData = JSON.parse(configResult.stdout.trim());\n\n if (configData.error) {\n setError(configData.error);\n return;\n }\n\n const keyResult = await exec(client, SCRIPTS.getDeployKey(props.name, user));\n const webhookResult = await exec(client, SCRIPTS.getWebhookStatus(props.name));\n const pollingResult = await exec(client, SCRIPTS.getPollingStatus(props.name));\n\n lines.push(`Repository: ${configData.repo || 'Not configured'}`);\n lines.push(`Branch: ${configData.branch || 'main'}`);\n lines.push(`Deploy Key: ${keyResult.stdout.trim() ? 'Configured' : 'Not configured'}`);\n\n const webhookStatusStr = webhookResult.stdout.trim();\n if (webhookStatusStr.startsWith('running:')) {\n const port = webhookStatusStr.split(':')[1];\n lines.push(`Webhook: Running on port ${port}`);\n } else {\n lines.push('Webhook: Not configured');\n }\n\n const pollingStatusStr = pollingResult.stdout.trim();\n if (pollingStatusStr.startsWith('running:')) {\n const parts = pollingStatusStr.split(':');\n const interval = parts[1];\n const mode = parts[2] || 'systemd';\n lines.push(`Git Polling: Running (every ${interval}s, ${mode} mode)`);\n } else {\n lines.push('Git Polling: Not configured');\n }\n\n if (keyResult.stdout.trim()) {\n lines.push('');\n lines.push('Public Key:');\n lines.push(keyResult.stdout.trim());\n }\n break;\n }\n\n case 'repo': {\n await execScript(client, SCRIPTS.updateRepo(props.name, inputValue, user), true);\n lines.push(`Repository updated to: ${inputValue}`);\n break;\n }\n\n case 'branch': {\n await execScript(client, SCRIPTS.updateBranch(props.name, inputValue, user), true);\n lines.push(`Branch updated to: ${inputValue}`);\n lines.push('Run update command to deploy from new branch.');\n break;\n }\n\n case 'new-key': {\n const result = await execScript(client, SCRIPTS.generateNewKey(props.name, user), true);\n lines.push('New deploy key generated:');\n lines.push('');\n lines.push(result.stdout.trim());\n lines.push('');\n lines.push('Add this key to your repository settings.');\n lines.push('Remember to remove the old key if it was configured.');\n break;\n }\n\n case 'delete-key': {\n const result = await execScript(client, SCRIPTS.deleteDeployKey(props.name, user), true);\n if (result.stdout.includes('key-deleted')) {\n lines.push('Deploy key deleted successfully.');\n lines.push('Remember to remove it from your repository settings too.');\n } else {\n lines.push('No deploy key found for this app.');\n }\n break;\n }\n\n case 'webhook-secret': {\n const result = await execScript(client, SCRIPTS.updateWebhookSecret(props.name, inputValue), true);\n if (result.stdout.includes('webhook-secret-updated')) {\n lines.push('Webhook secret updated.');\n lines.push('Update the secret in your repository webhook settings too.');\n } else {\n lines.push('Webhook not configured for this app.');\n }\n break;\n }\n\n case 'disable-webhook': {\n await execScript(client, SCRIPTS.disableWebhook(props.name), true);\n lines.push('Webhook disabled.');\n break;\n }\n\n case 'polling-interval': {\n const interval = parseInt(inputValue, 10);\n if (isNaN(interval) || interval < 1) {\n setError('Invalid interval. Please enter a number >= 1.');\n return;\n }\n const result = await execScript(client, SCRIPTS.updatePollingInterval(props.name, interval), true);\n if (result.stdout.includes('polling-interval-updated')) {\n lines.push(`Polling interval updated to ${interval} seconds.`);\n } else {\n lines.push('Git polling not configured for this app.');\n lines.push('Use \"Enable git polling\" to set it up first.');\n }\n break;\n }\n\n case 'enable-polling': {\n // Get current branch from config\n const configResult = await exec(client, SCRIPTS.getConfig(props.name));\n const configData = JSON.parse(configResult.stdout.trim());\n const branch = configData.branch || 'main';\n const interval = 10; // Default interval\n\n const result = await execScript(client, SCRIPTS.enablePolling(props.name, branch, user, interval), true);\n if (result.stdout.includes('polling-enabled')) {\n lines.push('Git polling re-enabled.');\n lines.push(`Checking for updates every ${interval} seconds.`);\n } else if (result.stdout.includes('polling-created')) {\n lines.push('Git polling enabled.');\n lines.push(`Checking for updates every ${interval} seconds.`);\n }\n lines.push('');\n lines.push(`View logs: journalctl -u poll-${props.name} -f`);\n break;\n }\n\n case 'disable-polling': {\n await execScript(client, SCRIPTS.disablePolling(props.name), true);\n lines.push('Git polling disabled.');\n break;\n }\n }\n\n setOutput(lines);\n disconnect(client);\n setTimeout(() => exit(), 100);\n } catch (err) {\n setError(`Operation failed: ${err instanceof Error ? err.message : err}`);\n if (client) disconnect(client);\n setTimeout(() => exit(), 100);\n }\n };\n run();\n }, [client, action, inputValue, enteringValue]);\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"App Configuration\" subtitle={`App: ${props.name} | Host: ${props.host}`} />\n\n <Task label=\"Connect to server\" status={status} />\n\n {selectingAction && action === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Select action:</Text>\n <SelectInput items={configActions} onSelect={handleActionSelect} />\n </Box>\n )}\n\n {enteringValue && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>{inputLabel}</Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={inputValue} onChange={setInputValue} onSubmit={handleInputSubmit} />\n </Box>\n </Box>\n )}\n\n {output.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n {output.map((line, i) => (\n <Text key={i} color={line.startsWith('ssh-') ? 'cyan' : 'white'}>{line}</Text>\n ))}\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","/**\n * Update Command Component\n * \n * Ink/React component for the `provisor update` command.\n * Checks for updates and allows the user to update the CLI.\n * \n * Status: Active\n */\n\nimport React, { useState, useEffect } from 'react'\nimport { Box, Text } from 'ink'\nimport Spinner from 'ink-spinner'\nimport SelectInput from 'ink-select-input'\nimport { \n checkForUpdate, \n performUpdate, \n type UpdateInfo \n} from '../utils/update-checker.js'\n\ninterface UpdateCommandProps {\n check?: boolean\n}\n\ntype Stage = 'checking' | 'show-result' | 'confirm' | 'updating' | 'done' | 'error'\n\nexport function UpdateCommand({ check = false }: UpdateCommandProps) {\n const [stage, setStage] = useState<Stage>('checking')\n const [updateInfo, setUpdateInfo] = useState<UpdateInfo | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [resultMessage, setResultMessage] = useState<string>('')\n\n // Check for updates on mount\n useEffect(() => {\n async function doCheck() {\n try {\n const info = await checkForUpdate()\n setUpdateInfo(info)\n \n if (check || !info.updateAvailable) {\n // Just show the result, don't prompt\n setStage('show-result')\n } else {\n // Prompt user to confirm update\n setStage('confirm')\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to check for updates')\n setStage('error')\n }\n }\n doCheck()\n }, [check])\n\n // Handle update confirmation\n const handleConfirm = (item: { value: string }) => {\n if (item.value === 'yes') {\n setStage('updating')\n \n // Perform update in next tick to allow UI to update\n setTimeout(() => {\n const result = performUpdate()\n setResultMessage(result.message)\n setStage(result.success ? 'done' : 'error')\n }, 100)\n } else {\n setResultMessage('Update cancelled.')\n setStage('done')\n }\n }\n\n // Render based on stage\n if (stage === 'checking') {\n return (\n <Box>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Checking for updates...</Text>\n </Box>\n )\n }\n\n if (stage === 'error') {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"red\">✗ Error: {error || resultMessage}</Text>\n </Box>\n )\n }\n\n if (stage === 'show-result' && updateInfo) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text>Current version: </Text>\n <Text color=\"cyan\">{updateInfo.currentVersion}</Text>\n </Box>\n <Box>\n <Text>Latest version: </Text>\n <Text color={updateInfo.updateAvailable ? 'green' : 'cyan'}>\n {updateInfo.latestVersion}\n </Text>\n </Box>\n {updateInfo.updateAvailable ? (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"yellow\">⚡ A new version is available!</Text>\n <Text color=\"gray\">Run `provisor update` to install.</Text>\n {updateInfo.releaseUrl && (\n <Text color=\"gray\">Release notes: {updateInfo.releaseUrl}</Text>\n )}\n </Box>\n ) : (\n <Box marginTop={1}>\n <Text color=\"green\">✓ You are using the latest version.</Text>\n </Box>\n )}\n </Box>\n )\n }\n\n if (stage === 'confirm' && updateInfo) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"yellow\">⚡ Update available: </Text>\n <Text>{updateInfo.currentVersion}</Text>\n <Text color=\"gray\"> → </Text>\n <Text color=\"green\">{updateInfo.latestVersion}</Text>\n </Box>\n {updateInfo.releaseUrl && (\n <Text color=\"gray\">Release notes: {updateInfo.releaseUrl}</Text>\n )}\n <Box marginTop={1}>\n <Text>Install update? </Text>\n </Box>\n <SelectInput\n items={[\n { label: 'Yes, update now', value: 'yes' },\n { label: 'No, cancel', value: 'no' }\n ]}\n onSelect={handleConfirm}\n />\n </Box>\n )\n }\n\n if (stage === 'updating') {\n return (\n <Box>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Installing update...</Text>\n </Box>\n )\n }\n\n if (stage === 'done') {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"green\">✓ {resultMessage}</Text>\n {updateInfo?.updateAvailable && resultMessage.includes('successfully') && (\n <Text color=\"gray\">Run `provisor --version` to verify.</Text>\n )}\n </Box>\n )\n }\n\n return null\n}\n","/**\n * Update Checker Utility\n * \n * Checks for new versions of the CLI on npm registry and provides\n * update functionality.\n * \n * Status: Active\n * Usage: Import functions to check/perform updates\n */\n\nimport { execSync } from 'child_process'\nimport packageJson from '../../package.json' with { type: 'json' };\n\nconst PACKAGE_NAME = '@it-club/provisor'\n\nexport interface UpdateInfo {\n currentVersion: string\n latestVersion: string\n updateAvailable: boolean\n releaseUrl?: string\n}\n\n/**\n * Get the current version from the installed package\n */\nexport function getCurrentVersion(): string {\n return packageJson.version\n}\n\n/**\n * Fetch the latest version from npm registry\n */\nexport async function getLatestVersion(): Promise<string> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`)\n if (!response.ok) {\n throw new Error(`Failed to fetch: ${response.status}`)\n }\n const data = await response.json() as { version: string }\n return data.version\n } catch (error) {\n throw new Error(`Failed to check npm registry: ${error instanceof Error ? error.message : 'Unknown error'}`)\n }\n}\n\n/**\n * Compare two semantic versions\n * Returns: 1 if v1 > v2, -1 if v1 < v2, 0 if equal\n */\nexport function compareVersions(v1: string, v2: string): number {\n const parts1 = v1.replace(/^v/, '').split('.').map(Number)\n const parts2 = v2.replace(/^v/, '').split('.').map(Number)\n \n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const p1 = parts1[i] || 0\n const p2 = parts2[i] || 0\n if (p1 > p2) return 1\n if (p1 < p2) return -1\n }\n return 0\n}\n\n/**\n * Check if an update is available\n */\nexport async function checkForUpdate(): Promise<UpdateInfo> {\n const currentVersion = getCurrentVersion()\n const latestVersion = await getLatestVersion()\n const updateAvailable = compareVersions(latestVersion, currentVersion) > 0\n \n return {\n currentVersion,\n latestVersion,\n updateAvailable,\n releaseUrl: updateAvailable \n ? `https://github.com/it-club/provisor/releases/tag/v${latestVersion}`\n : undefined\n }\n}\n\n/**\n * Perform the update via npm\n */\nexport function performUpdate(): { success: boolean; message: string } {\n try {\n // Update globally via npm\n execSync(`npm install -g ${PACKAGE_NAME}@latest`, { \n stdio: 'pipe',\n encoding: 'utf-8'\n })\n return { success: true, message: 'Update completed successfully!' }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n return { success: false, message: `Update failed: ${message}` }\n }\n}\n\n/**\n * Get the currently installed global version (for verification)\n */\nexport function getInstalledGlobalVersion(): string | null {\n try {\n const output = execSync(`npm list -g ${PACKAGE_NAME} --json`, {\n stdio: 'pipe',\n encoding: 'utf-8'\n })\n const data = JSON.parse(output)\n return data.dependencies?.[PACKAGE_NAME]?.version || null\n } catch {\n return null\n }\n}\n","{\n \"name\": \"@it-club/provisor\",\n \"version\": \"0.2.2\",\n \"description\": \"Server provisioning and deployment CLI tool\",\n \"type\": \"module\",\n \"bin\": {\n \"provisor\": \"dist/cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/it-club/provisor.git\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/cli.js\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"keywords\": [\n \"cli\",\n \"server\",\n \"provisioning\",\n \"deployment\",\n \"ssh\"\n ],\n \"author\": \"\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"commander\": \"^14.0.3\",\n \"ink\": \"^6.6.0\",\n \"ink-select-input\": \"^6.2.0\",\n \"ink-spinner\": \"^5.0.0\",\n \"ink-text-input\": \"^6.0.0\",\n \"react\": \"^19.2.4\",\n \"ssh2\": \"^1.17.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.2.0\",\n \"@types/react\": \"^19.2.10\",\n \"@types/ssh2\": \"^1.15.5\",\n \"ink-testing-library\": \"^4.0.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.9.3\"\n }\n}\n"],"mappings":"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","names":["useState","Box","Text","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","jsx","jsxs","useState","Box","Text","useState","useEffect","Box","Text","useApp","useInput","Spinner","jsx","jsxs","SCRIPTS","useApp","useState","useInput","useEffect","Box","Text","Spinner","useState","useEffect","Box","Text","useApp","jsx","jsxs","useApp","useState","useEffect","Box","Text","useState","useEffect","Box","Text","useApp","jsx","jsxs","useApp","useState","useEffect","Box","Text","useState","useEffect","Box","Text","useApp","jsx","jsxs","useApp","useState","useEffect","Box","Text","useState","useEffect","Box","Text","useApp","SelectInput","TextInput","jsx","jsxs","SCRIPTS","useApp","useState","useEffect","Box","Text","SelectInput","TextInput","useState","useEffect","Box","Text","Spinner","SelectInput","jsx","jsxs","useState","useEffect","Box","Text","Spinner","SelectInput","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.tsx","../src/commands/init.tsx","../src/components/Task.tsx","../src/components/Header.tsx","../src/components/Confirm.tsx","../src/components/Layout.tsx","../src/utils/ssh.ts","../src/commands/app.tsx","../src/commands/ssh-key.tsx","../src/commands/status.tsx","../src/commands/deploy.tsx","../src/commands/config.tsx","../src/commands/update.tsx","../src/utils/update-checker.ts","../package.json","../src/commands/logs.tsx","../src/utils/server.ts","../src/commands/servers.tsx","../src/commands/caddy.tsx","../src/commands/main.tsx","../src/commands/appList.tsx","../src/utils/scan.ts","../src/commands/diagnostics.tsx"],"sourcesContent":["import { program } from 'commander';\nimport { render } from 'ink';\nimport React from 'react';\nimport { InitCommand } from './commands/init.js';\nimport { AppCommand } from './commands/app.js';\nimport { SshKeyCommand } from './commands/ssh-key.js';\nimport { StatusCommand } from './commands/status.js';\nimport { DeployCommand } from './commands/deploy.js';\nimport { ConfigCommand } from './commands/config.js';\nimport { UpdateCommand } from './commands/update.js';\nimport { LogsCommand } from './commands/logs.js';\nimport { ServerManager } from './utils/server.js';\nimport { ServerCommand } from './commands/servers.js';\nimport { MainCommand } from './commands/main.js';\nimport { CaddyCommand } from './commands/caddy.js';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\n// Helper to resolve host aliases before command actions\nconst resolveHostAlias = (options: any) => {\n if (options.host) {\n const savedServer = ServerManager.getServer(options.host);\n if (savedServer) {\n options.host = savedServer.host;\n if (!options.user && savedServer.user) options.user = savedServer.user;\n if (!options.key && savedServer.keyPath) options.key = savedServer.keyPath;\n }\n }\n};\n\nprogram\n .name('provisor')\n .description('Server provisioning and deployment CLI')\n .version(packageJson.version);\n\nprogram\n .option('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to create', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key for root access')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n resolveHostAlias(options);\n // If no specific options provided (just 'provisor'), default to Main Menu\n // But commander might match options. We need to check if user intended init or just ran cli.\n // Actually, 'init' was the default before. Now we want 'main'.\n // If command is 'init', it should be explicit? Or can we make it default?\n // Let's separate 'init' into its own command if possible, or just check args.\n \n // Changing default to Main Menu\n render(<MainCommand />);\n });\n\nprogram\n .command('init')\n .description('Initialize a new server')\n .option('-h, --host <host>', 'Server IP address')\n .option('-u, --user <user>', 'SSH user (default: root)')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n resolveHostAlias(options);\n render(<InitCommand {...options} />);\n });\n\nprogram\n .command('app')\n .description('Provision application (Caddy, Node.js, Git deploy)')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .option('-b, --branch <branch>', 'Deploy branch', 'main')\n .option('-n, --name <name>', 'Application name', 'app')\n .option('-r, --repo <url>', 'Clone from repository URL (GitHub, GitLab, etc.)')\n .action((options) => {\n resolveHostAlias(options);\n render(<AppCommand {...options} />);\n });\n\nprogram\n .command('ssh-key')\n .description('Manage SSH keys on the server')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .option('--add <pubkey>', 'Add a new public key')\n .option('--list', 'List authorized keys')\n .action((options) => {\n resolveHostAlias(options);\n render(<SshKeyCommand {...options} />);\n });\n\nprogram\n .command('status')\n .description('Check server status and services')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n resolveHostAlias(options);\n render(<StatusCommand {...options} />);\n });\n\nprogram\n .command('deploy')\n .description('Trigger deployment for an application')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .requiredOption('-n, --name <name>', 'Application name')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n resolveHostAlias(options);\n render(<DeployCommand {...options} />);\n });\n\nprogram\n .command('config')\n .description('Manage application configuration')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .requiredOption('-n, --name <name>', 'Application name')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .option('--show', 'Show current configuration')\n .option('--repo <url>', 'Change repository URL')\n .option('--branch <branch>', 'Change deploy branch')\n .option('--new-key', 'Generate new deploy key')\n .option('--delete-key', 'Delete deploy key')\n .option('--webhook-secret <secret>', 'Update webhook secret')\n .option('--disable-webhook', 'Disable webhook')\n .option('--polling-interval <seconds>', 'Set git polling interval in seconds', parseInt)\n .option('--enable-polling', 'Enable git polling for auto-deploy')\n .option('--disable-polling', 'Disable git polling')\n .action((options) => {\n resolveHostAlias(options);\n render(<ConfigCommand {...options} />);\n });\n\nprogram\n .command('caddy')\n .description('Manage Caddy configuration')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n resolveHostAlias(options);\n render(<CaddyCommand {...options} />);\n });\n\nprogram\n .command('update')\n .description('Check for updates and update the CLI')\n .option('--check', 'Only check for updates, do not install')\n .action((options) => {\n render(<UpdateCommand {...options} />);\n });\n\nprogram\n .command('logs')\n .description('View application and server logs')\n .requiredOption('-h, --host <host>', 'Server hostname or IP')\n .requiredOption('-n, --name <name>', 'Application name')\n .option('-u, --user <user>', 'Username to connect as', 'deploy')\n .option('-k, --key <path>', 'Path to SSH private key')\n .option('-p, --port <port>', 'SSH port', '22')\n .action((options) => {\n resolveHostAlias(options);\n render(<LogsCommand {...options} />);\n });\n\nprogram\n .command('server')\n .description('Manage saved servers')\n .argument('[action]', 'Action to perform: add, list, remove')\n .argument('[alias]', 'Server alias')\n .argument('[host]', 'Server host (IP)')\n .option('-u, --user <user>', 'SSH user')\n .action((action, alias, host, options) => {\n render(\n <ServerCommand \n action={action as any} \n alias={alias} \n host={host} \n user={options.user} \n />\n );\n });\n\nprogram.parse();\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport { Header, Task, Confirm, type TaskStatus } from '../components/index.js';\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface InitCommandProps extends SSHOptions {\n user: string;\n}\n\ninterface TaskState {\n connect: TaskStatus;\n update: TaskStatus;\n createUser: TaskStatus;\n setupSsh: TaskStatus;\n firewall: TaskStatus;\n hardenSsh: TaskStatus;\n}\n\nconst SCRIPTS = {\n checkUser: (user: string) => `id ${user} &>/dev/null && echo \"exists\" || echo \"not_found\"`,\n\n createUser: (user: string) => `\n adduser --gecos \"\" --disabled-password ${user}\n usermod -aG sudo ${user}\n echo \"${user} ALL=(ALL) NOPASSWD:ALL\" > /etc/sudoers.d/${user}\n chmod 440 /etc/sudoers.d/${user}\n `,\n\n copyRootKeys: (user: string) => `\n mkdir -p /home/${user}/.ssh\n cp /root/.ssh/authorized_keys /home/${user}/.ssh/authorized_keys\n chown -R ${user}:${user} /home/${user}/.ssh\n chmod 700 /home/${user}/.ssh\n chmod 600 /home/${user}/.ssh/authorized_keys\n `,\n\n setupFirewall: () => `\n apt install -y ufw\n ufw allow OpenSSH\n ufw allow 80\n ufw allow 443\n echo \"y\" | ufw enable\n `,\n\n hardenSsh: () => `\n cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak\n sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config\n sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config\n systemctl restart ssh || systemctl restart sshd\n `,\n};\n\nexport function InitCommand(props: InitCommandProps) {\n const { exit } = useApp();\n const [client, setClient] = useState<Client | null>(null);\n const [tasks, setTasks] = useState<TaskState>({\n connect: 'pending',\n update: 'pending',\n createUser: 'pending',\n setupSsh: 'pending',\n firewall: 'pending',\n hardenSsh: 'pending',\n });\n const [error, setError] = useState<string | null>(null);\n const [waitingConfirm, setWaitingConfirm] = useState(false);\n const [summary, setSummary] = useState<string[]>([]);\n\n const updateTask = (task: keyof TaskState, status: TaskStatus) => {\n setTasks((prev) => ({ ...prev, [task]: status }));\n };\n\n const addSummary = (msg: string) => {\n setSummary((prev) => [...prev, msg]);\n };\n\n // Step 1: Connect\n useEffect(() => {\n const run = async () => {\n updateTask('connect', 'running');\n try {\n const sshClient = await connect({ ...props, user: 'root' });\n setClient(sshClient);\n updateTask('connect', 'success');\n } catch (err) {\n updateTask('connect', 'error');\n setError(`Connection failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, []);\n\n // Step 2: Update system\n useEffect(() => {\n if (!client || tasks.connect !== 'success' || tasks.update !== 'pending') return;\n\n const run = async () => {\n updateTask('update', 'running');\n try {\n await exec(client, 'apt update && apt upgrade -y');\n await exec(client, 'apt install -y curl git');\n updateTask('update', 'success');\n } catch (err) {\n updateTask('update', 'error');\n setError(`Update failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.connect]);\n\n // Step 3: Create user\n useEffect(() => {\n if (!client || tasks.update !== 'success' || tasks.createUser !== 'pending') return;\n\n const run = async () => {\n updateTask('createUser', 'running');\n try {\n const result = await exec(client, SCRIPTS.checkUser(props.user));\n if (result.stdout.trim() === 'exists') {\n updateTask('createUser', 'skipped');\n addSummary(`User '${props.user}' already exists`);\n } else {\n await execScript(client, SCRIPTS.createUser(props.user));\n updateTask('createUser', 'success');\n addSummary(`User '${props.user}' created with sudo access`);\n }\n } catch (err) {\n updateTask('createUser', 'error');\n setError(`User creation failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.update]);\n\n // Step 4: Setup SSH keys\n useEffect(() => {\n if (!client || !['success', 'skipped'].includes(tasks.createUser) || tasks.setupSsh !== 'pending') return;\n\n const run = async () => {\n updateTask('setupSsh', 'running');\n try {\n await execScript(client, SCRIPTS.copyRootKeys(props.user));\n updateTask('setupSsh', 'success');\n addSummary(`SSH keys copied to '${props.user}'`);\n } catch (err) {\n updateTask('setupSsh', 'error');\n setError(`SSH setup failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.createUser]);\n\n // Step 5: Firewall\n useEffect(() => {\n if (!client || tasks.setupSsh !== 'success' || tasks.firewall !== 'pending') return;\n\n const run = async () => {\n updateTask('firewall', 'running');\n try {\n await execScript(client, SCRIPTS.setupFirewall());\n updateTask('firewall', 'success');\n addSummary('Firewall configured (SSH, HTTP, HTTPS)');\n } catch (err) {\n updateTask('firewall', 'error');\n setError(`Firewall setup failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.setupSsh]);\n\n // Step 6: Wait for confirmation before hardening\n useEffect(() => {\n if (tasks.firewall !== 'success' || waitingConfirm || tasks.hardenSsh !== 'pending') return;\n setWaitingConfirm(true);\n }, [tasks.firewall]);\n\n const handleConfirm = async (confirmed: boolean) => {\n if (!client) return;\n\n if (!confirmed) {\n updateTask('hardenSsh', 'skipped');\n addSummary('SSH hardening skipped (root login still enabled)');\n disconnect(client);\n setTimeout(() => exit(), 100);\n return;\n }\n\n updateTask('hardenSsh', 'running');\n try {\n await execScript(client, SCRIPTS.hardenSsh());\n updateTask('hardenSsh', 'success');\n addSummary('SSH hardened (root login disabled, password auth disabled)');\n disconnect(client);\n setTimeout(() => exit(), 100);\n } catch (err) {\n updateTask('hardenSsh', 'error');\n setError(`SSH hardening failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n\n // Handle errors\n useEffect(() => {\n if (error && client) {\n disconnect(client);\n setTimeout(() => exit(), 100);\n }\n }, [error]);\n\n const allDone = tasks.hardenSsh === 'success' || tasks.hardenSsh === 'skipped';\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Server Initialization\" subtitle={`Host: ${props.host}`} />\n\n <Task label=\"Connect to server\" status={tasks.connect} />\n <Task label=\"Update system packages\" status={tasks.update} />\n <Task label={`Create user '${props.user}'`} status={tasks.createUser} />\n <Task label=\"Setup SSH keys\" status={tasks.setupSsh} />\n <Task label=\"Configure firewall\" status={tasks.firewall} />\n <Task label=\"Harden SSH\" status={tasks.hardenSsh} />\n\n {waitingConfirm && tasks.hardenSsh === 'pending' && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"yellow\" bold>\n ⚠ Before proceeding, verify SSH access as '{props.user}':\n </Text>\n <Text color=\"gray\"> ssh {props.port !== '22' ? `-p ${props.port} ` : ''}{props.user}@{props.host}</Text>\n <Box marginTop={1}>\n <Confirm\n message=\"Have you verified SSH access works?\"\n onConfirm={handleConfirm}\n />\n </Box>\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n\n {allDone && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"green\" bold>✓ Initialization complete</Text>\n {summary.map((msg, i) => (\n <Text key={i} color=\"gray\"> • {msg}</Text>\n ))}\n <Box marginTop={1}>\n <Text>Next: <Text color=\"cyan\">provisor app -h {props.host}</Text></Text>\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport Spinner from 'ink-spinner'\n\nexport type TaskStatus = 'pending' | 'running' | 'success' | 'error' | 'skipped' | 'warning'\n\ninterface TaskProps {\n label: string\n status: TaskStatus\n message?: string\n}\n\nconst statusIcons: Record<TaskStatus, React.ReactNode> = {\n pending: <Text color=\"gray\">○</Text>,\n running: <Text color=\"cyan\"><Spinner type=\"dots\" /></Text>,\n success: <Text color=\"green\">✓</Text>,\n error: <Text color=\"red\">✗</Text>,\n skipped: <Text color=\"yellow\">-</Text>,\n warning: <Text color=\"yellow\">⚠</Text>,\n}\n\nexport function Task({ label, status, message }: TaskProps) {\n return (\n <Box>\n <Box width={3}>{statusIcons[status]}</Box>\n <Text color={status === 'error' ? 'red' : undefined}>\n {label}\n {message && <Text color=\"gray\"> {message}</Text>}\n </Text>\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\n\ninterface HeaderProps {\n title: string;\n subtitle?: string;\n}\n\nexport function Header({ title, subtitle }: HeaderProps) {\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color=\"cyan\">\n ◆ {title}\n </Text>\n {subtitle && <Text color=\"gray\">{subtitle}</Text>}\n </Box>\n );\n}\n","import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface ConfirmProps {\n message: string;\n onConfirm: (confirmed: boolean) => void;\n}\n\nexport function Confirm({ message, onConfirm }: ConfirmProps) {\n const [answered, setAnswered] = useState(false);\n\n useInput((input, key) => {\n if (answered) return;\n\n if (input.toLowerCase() === 'y' || key.return) {\n setAnswered(true);\n onConfirm(true);\n } else if (input.toLowerCase() === 'n' || key.escape) {\n setAnswered(true);\n onConfirm(false);\n }\n });\n\n if (answered) return null;\n\n return (\n <Box>\n <Text color=\"yellow\">{message}</Text>\n <Text color=\"gray\"> (y/n) </Text>\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport { Header } from './Header.js';\n\ninterface LayoutProps {\n title?: string;\n subtitle?: string;\n children: React.ReactNode;\n footerStatus?: string;\n footerTips?: string[];\n}\n\nexport function Layout({ title, subtitle, children, footerStatus, footerTips }: LayoutProps) {\n return (\n <Box flexDirection=\"column\" height=\"100%\">\n {/* Header Section */}\n <Header title={title || ''} subtitle={subtitle || ''} />\n\n {/* Main Content (Flex Grow to fill space) */}\n <Box flexDirection=\"column\" flexGrow={1} paddingX={1}>\n {children}\n </Box>\n\n {/* Footer Section */}\n <Box \n borderStyle=\"single\" \n borderColor=\"gray\" \n flexDirection=\"column\"\n paddingX={1}\n marginTop={1}\n >\n <Box justifyContent=\"space-between\">\n <Text color=\"blue\">{footerStatus || 'Provisor CLI'}</Text>\n <Text color=\"gray\">{new Date().toLocaleTimeString()}</Text>\n </Box>\n {footerTips && footerTips.length > 0 && (\n <Box marginTop={0}>\n <Text color=\"gray\">\n {footerTips.join(' | ')}\n </Text>\n </Box>\n )}\n </Box>\n </Box>\n );\n}\n","import { Client, type ConnectConfig } from 'ssh2';\nimport { readFileSync, existsSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nexport interface SSHOptions {\n host: string;\n port?: string | number;\n user?: string;\n key?: string;\n}\n\nexport interface CommandResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\nfunction findDefaultKey(): string | null {\n const sshDir = join(homedir(), '.ssh');\n const keyNames = ['id_ed25519', 'id_rsa', 'id_ecdsa'];\n\n for (const name of keyNames) {\n const keyPath = join(sshDir, name);\n if (existsSync(keyPath)) {\n return keyPath;\n }\n }\n return null;\n}\n\nexport function createSSHConfig(options: SSHOptions): ConnectConfig {\n const keyPath = options.key || findDefaultKey();\n\n if (!keyPath) {\n throw new Error(\n 'No SSH key found. Specify with --key or ensure ~/.ssh/id_ed25519 exists'\n );\n }\n\n if (!existsSync(keyPath)) {\n throw new Error(`SSH key not found: ${keyPath}`);\n }\n\n return {\n host: options.host,\n port: parseInt(String(options.port || 22), 10),\n username: options.user || 'root',\n\n privateKey: readFileSync(keyPath),\n readyTimeout: 30000,\n keepaliveInterval: 10000,\n tryKeyboard: true,\n };\n}\n\nexport function connect(options: SSHOptions): Promise<Client> {\n return new Promise((resolve, reject) => {\n const client = new Client();\n const config = createSSHConfig(options);\n\n client.on('ready', () => resolve(client));\n client.on('error', reject);\n client.connect(config);\n });\n}\n\nexport function exec(client: Client, command: string): Promise<CommandResult> {\n return new Promise((resolve, reject) => {\n client.exec(command, (err, stream) => {\n if (err) {\n reject(err);\n return;\n }\n\n let stdout = '';\n let stderr = '';\n\n stream.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n stream.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n stream.on('close', (code: number) => {\n resolve({ stdout, stderr, code: code ?? 0 });\n });\n });\n });\n}\n\nexport function execWithSudo(\n client: Client,\n command: string\n): Promise<CommandResult> {\n // For commands that need sudo, we use sudo -S to read password from stdin\n // But since we're using key-based auth with NOPASSWD sudo, we can just prefix\n return exec(client, `sudo ${command}`);\n}\n\n\nexport async function execScript(\n client: Client,\n script: string,\n useSudo = false\n): Promise<CommandResult> {\n // Escape the script for bash\n const escapedScript = script.replace(/'/g, \"'\\\\''\");\n const command = useSudo\n ? `sudo bash -c '${escapedScript}'`\n : `bash -c '${escapedScript}'`;\n\n return exec(client, command);\n}\n\nexport function execStream(\n client: Client,\n command: string,\n onStdout: (data: string) => void,\n onStderr: (data: string) => void\n): Promise<number> {\n return new Promise((resolve, reject) => {\n client.exec(command, (err, stream) => {\n if (err) {\n reject(err);\n return;\n }\n\n stream.on('data', (data: Buffer) => {\n onStdout(data.toString());\n });\n\n stream.stderr.on('data', (data: Buffer) => {\n onStderr(data.toString());\n });\n\n stream.on('close', (code: number) => {\n resolve(code ?? 0);\n });\n });\n });\n}\n\nexport function disconnect(client: Client): void {\n client.end();\n}\n\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport Spinner from 'ink-spinner';\nimport TextInput from 'ink-text-input';\nimport crypto from 'crypto';\nimport { Header, Task, type TaskStatus } from '../components/index.js';\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface AppCommandProps extends SSHOptions {\n branch: string;\n name: string;\n repo?: string;\n}\n\ninterface TaskState {\n connect: TaskStatus;\n caddy: TaskStatus;\n node: TaskStatus;\n deployKey: TaskStatus;\n deploy: TaskStatus;\n webhook: TaskStatus;\n caddyConfig: TaskStatus;\n}\n\ntype DeployMethod = 'push' | 'clone-public' | 'clone-private';\ntype ExistingAppAction = 'replace' | 'update' | 'cancel';\ntype TlsChoice = 'ondemand' | 'specific' | 'none';\ntype AutoDeployChoice = 'polling' | 'webhook' | 'none';\n\nconst SCRIPTS = {\n installCaddy: () => `\n if ! command -v caddy &>/dev/null; then\n apt install -y debian-keyring debian-archive-keyring apt-transport-https\n curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg\n curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list\n apt update\n apt install caddy -y\n echo \"installed\"\n else\n echo \"exists\"\n fi\n `,\n\n installNode: () => `\n if ! command -v node &>/dev/null; then\n curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -\n apt install -y nodejs\n echo \"installed\"\n else\n echo \"exists\"\n fi\n if ! command -v pm2 &>/dev/null; then\n npm install -g pm2\n fi\n `,\n\n // Check if app directory exists\n checkAppExists: (name: string) => `\n APP_DIR=\"/var/www/${name}\"\n if [ -d \"$APP_DIR\" ] && [ \"$(ls -A $APP_DIR 2>/dev/null)\" ]; then\n echo \"exists\"\n else\n echo \"empty\"\n fi\n `,\n\n // Generate deploy key for private repos\n generateDeployKey: (name: string, user: string) => {\n const homeDir = user === 'root' ? '/root' : `/home/${user}`;\n return `\n SSH_DIR=\"${homeDir}/.ssh\"\n KEY_FILE=\"$SSH_DIR/deploy_${name}\"\n\n mkdir -p \"$SSH_DIR\"\n\n # Generate key if doesn't exist\n if [ ! -f \"$KEY_FILE\" ]; then\n ssh-keygen -t ed25519 -f \"$KEY_FILE\" -N \"\" -C \"deploy-key-${name}\"\n fi\n\n # Configure SSH to use this key for github.com and gitlab.com\n if ! grep -q \"deploy_${name}\" \"$SSH_DIR/config\" 2>/dev/null; then\n cat >> \"$SSH_DIR/config\" << EOF\n\n# Deploy key for ${name}\nHost github.com gitlab.com bitbucket.org\n IdentityFile $KEY_FILE\n IdentitiesOnly yes\nEOF\n fi\n\n chown -R ${user}:${user} \"$SSH_DIR\"\n chmod 700 \"$SSH_DIR\"\n chmod 600 \"$KEY_FILE\"\n chmod 644 \"$KEY_FILE.pub\"\n chmod 600 \"$SSH_DIR/config\" 2>/dev/null || true\n\n # Output the public key\n cat \"$KEY_FILE.pub\"\n `;\n },\n\n // Test SSH connection to git host\n testGitConnection: (host: string) => `\n ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -T git@${host} 2>&1 || true\n `,\n\n // Push-to-deploy: setup bare repo with hook\n setupPushDeploy: (name: string, branch: string, user: string, buildCmd: string, startCmd: string) => `\n APP_DIR=\"/var/www/${name}\"\n REPO_DIR=\"/var/repo/${name}.git\"\n\n mkdir -p \"$APP_DIR\"\n mkdir -p \"$(dirname \"$REPO_DIR\")\"\n\n if [ ! -d \"$REPO_DIR\" ]; then\n git init --bare \"$REPO_DIR\"\n fi\n\n # Create post-receive hook\n cat << 'HOOK_EOF' > \"$REPO_DIR/hooks/post-receive\"\n#!/bin/bash\nset -e\n\nTARGET=\"/var/www/${name}\"\nGIT_DIR=\"/var/repo/${name}.git\"\nBRANCH=\"${branch}\"\n\necho \"=== Deployment Started ===\"\necho \"Deploying branch '$BRANCH' to $TARGET...\"\n\ngit --work-tree=\"$TARGET\" --git-dir=\"$GIT_DIR\" checkout -f \"$BRANCH\"\n\ncd \"$TARGET\"\n\nif [ -f \"package.json\" ]; then\n echo \"Node.js project detected.\"\n\n NEED_INSTALL=false\n\n if [ ! -d \"node_modules\" ]; then\n NEED_INSTALL=true\n elif [ -f \"package-lock.json\" ]; then\n LOCK_HASH_FILE=\"$GIT_DIR/.package-lock-hash\"\n CURRENT_HASH=$(sha256sum package-lock.json | awk '{print $1}')\n\n if [ -f \"$LOCK_HASH_FILE\" ]; then\n PREV_HASH=$(cat \"$LOCK_HASH_FILE\")\n if [ \"$CURRENT_HASH\" != \"$PREV_HASH\" ]; then\n NEED_INSTALL=true\n fi\n else\n NEED_INSTALL=true\n fi\n\n echo \"$CURRENT_HASH\" > \"$LOCK_HASH_FILE\"\n fi\n\n if [ \"$NEED_INSTALL\" = true ]; then\n echo \"Installing dependencies...\"\n npm ci --production 2>/dev/null || npm install --production\n fi\n\n if [ -n \"${buildCmd}\" ]; then\n echo \"Building application...\"\n ${buildCmd}\n fi\n\n PM2_NAME=\"${name}\"\n if pm2 list 2>/dev/null | grep -q \"$PM2_NAME\"; then\n pm2 restart \"$PM2_NAME\" --update-env\n else\n echo \"Starting application...\"\n pm2 start \"${startCmd}\" --name \"$PM2_NAME\"\n fi\nelse\n echo \"Static site detected.\"\nfi\n\necho \"=== Deployment Complete ===\"\nHOOK_EOF\n\n chmod +x \"$REPO_DIR/hooks/post-receive\"\n chown -R ${user}:${user} \"$REPO_DIR\"\n chown -R ${user}:${user} \"$APP_DIR\"\n echo \"push-deploy-ready\"\n `,\n\n // Clone from repository - fresh clone (replace)\n cloneRepoFresh: (name: string, repoUrl: string, branch: string, user: string, buildCmd: string, startCmd: string) => `\n APP_DIR=\"/var/www/${name}\"\n\n # Remove existing if present\n rm -rf \"$APP_DIR\"\n mkdir -p \"$APP_DIR\"\n chown ${user}:${user} \"$APP_DIR\"\n\n # Clone as the deploy user to use their SSH keys\n sudo -u ${user} git clone --branch ${branch} --single-branch ${repoUrl} \"$APP_DIR\"\n\n cd \"$APP_DIR\"\n\n # Build if Node.js project\n if [ -f \"package.json\" ]; then\n echo \"Node.js project detected.\"\n sudo -u ${user} npm ci --production 2>/dev/null || sudo -u ${user} npm install --production\n\n if [ -n \"${buildCmd}\" ]; then\n echo \"Building application...\"\n sudo -u ${user} ${buildCmd}\n fi\n\n PM2_NAME=\"${name}\"\n if pm2 list 2>/dev/null | grep -q \"$PM2_NAME\"; then\n pm2 restart \"$PM2_NAME\" --update-env\n else\n echo \"Starting application...\"\n pm2 start \"${startCmd}\" --name \"$PM2_NAME\"\n fi\n pm2 save\n else\n echo \"Static site detected.\"\n fi\n\n chown -R ${user}:${user} \"$APP_DIR\"\n echo \"clone-complete\"\n `,\n\n // Update existing cloned repo (git pull)\n updateRepo: (name: string, branch: string, user: string, buildCmd: string, startCmd: string) => `\n APP_DIR=\"/var/www/${name}\"\n\n cd \"$APP_DIR\"\n\n # Fetch and reset to latest\n sudo -u ${user} git fetch origin\n sudo -u ${user} git reset --hard origin/${branch}\n\n # Build if Node.js project\n if [ -f \"package.json\" ]; then\n echo \"Node.js project detected.\"\n sudo -u ${user} npm ci --production 2>/dev/null || sudo -u ${user} npm install --production\n\n if [ -n \"${buildCmd}\" ]; then\n echo \"Building application...\"\n sudo -u ${user} ${buildCmd}\n fi\n\n PM2_NAME=\"${name}\"\n if pm2 list 2>/dev/null | grep -q \"$PM2_NAME\"; then\n pm2 restart \"$PM2_NAME\" --update-env\n else\n echo \"Starting application...\"\n pm2 start \"${startCmd}\" --name \"$PM2_NAME\"\n fi\n else\n echo \"Static site detected.\"\n fi\n\n echo \"update-complete\"\n `,\n\n // Create update script for cloned repos\n createUpdateScript: (name: string, branch: string, user: string, buildCmd: string, startCmd: string) => `\n cat << 'SCRIPT_EOF' > /usr/local/bin/update-${name}\n#!/bin/bash\nset -e\n\nAPP_DIR=\"/var/www/${name}\"\nBRANCH=\"${branch}\"\nUSER=\"${user}\"\n\necho \"=== Updating ${name} ===\"\n\ncd \"$APP_DIR\"\n\n# Run git commands as deploy user to use their SSH keys\nsudo -u $USER git fetch origin\nsudo -u $USER git reset --hard origin/$BRANCH\n\nif [ -f \"package.json\" ]; then\n sudo -u $USER npm ci --production 2>/dev/null || sudo -u $USER npm install --production\n\n if [ -n \"${buildCmd}\" ]; then\n sudo -u $USER ${buildCmd}\n fi\n\n PM2_NAME=\"${name}\"\n if pm2 list 2>/dev/null | grep -q \"$PM2_NAME\"; then\n pm2 restart \"$PM2_NAME\" --update-env\n else\n echo \"Starting application...\"\n pm2 start \"${startCmd}\" --name \"$PM2_NAME\"\n fi\nfi\n\necho \"=== Update Complete ===\"\nSCRIPT_EOF\n\n chmod +x /usr/local/bin/update-${name}\n echo \"update-script-created\"\n `,\n\n caddyOnDemand: (appDir: string) => `\ncat << 'EOF' > /etc/caddy/Caddyfile\n{\n on_demand_tls {\n ask http://localhost:5555/check\n }\n}\n\n:5555 {\n respond /check 200\n}\n\n:443 {\n tls {\n on_demand\n }\n\n root * ${appDir}\n encode gzip\n try_files {path} /index.html\n file_server\n}\n\n:80 {\n redir https://{host}{uri} permanent\n}\nEOF\ncaddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy\n `,\n\n caddySpecific: (appDir: string, domains: string) => `\ncat << EOF > /etc/caddy/Caddyfile\n${domains} {\n root * ${appDir}\n encode gzip\n try_files {path} /index.html\n file_server\n}\nEOF\ncaddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy\n `,\n\n caddyHttp: (appDir: string) => `\ncat << 'EOF' > /etc/caddy/Caddyfile\n:80 {\n root * ${appDir}\n encode gzip\n try_files {path} /index.html\n file_server\n}\nEOF\ncaddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy\n `,\n\n // Setup webhook handler for automatic deployment\n setupWebhook: (name: string, branch: string, port: number, secret: string) => `\n # Create webhook handler script\n cat << 'HANDLER_EOF' > /usr/local/bin/webhook-${name}.js\n#!/usr/bin/env node\n\nconst http = require('http');\nconst crypto = require('crypto');\nconst { spawn } = require('child_process');\n\nconst config = {\n port: ${port},\n secret: '${secret}',\n branch: '${branch}',\n app: '${name}',\n};\n\nconst updateScript = '/usr/local/bin/update-' + config.app;\n\nfunction log(message) {\n const timestamp = new Date().toISOString();\n console.log('[' + timestamp + '] ' + message);\n}\n\nfunction verifySignature(payload, signature, secret) {\n if (!secret) return true;\n if (signature.startsWith('sha256=')) {\n const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(payload).digest('hex');\n return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));\n }\n if (signature.startsWith('sha1=')) {\n const expected = 'sha1=' + crypto.createHmac('sha1', secret).update(payload).digest('hex');\n return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));\n }\n return signature === secret;\n}\n\nfunction getBranchFromPayload(payload) {\n try {\n const data = JSON.parse(payload);\n if (data.ref) return data.ref.replace('refs/heads/', '');\n if (data.object_kind === 'push' && data.ref) return data.ref.replace('refs/heads/', '');\n if (data.push && data.push.changes && data.push.changes[0]) {\n const change = data.push.changes[0];\n if (change.new && change.new.name) return change.new.name;\n }\n return null;\n } catch (e) { return null; }\n}\n\nfunction runUpdate() {\n log('Running update script: ' + updateScript);\n const child = spawn('sudo', [updateScript], { stdio: ['ignore', 'pipe', 'pipe'] });\n child.stdout.on('data', (data) => log('[update] ' + data.toString().trim()));\n child.stderr.on('data', (data) => log('[update:err] ' + data.toString().trim()));\n child.on('close', (code) => log(code === 0 ? 'Update completed' : 'Update failed: ' + code));\n}\n\nconst server = http.createServer((req, res) => {\n if (req.method === 'GET' && req.url === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', app: config.app, branch: config.branch }));\n return;\n }\n if (req.method !== 'POST' || (req.url !== '/webhook' && req.url !== '/')) {\n res.writeHead(404); res.end('Not found'); return;\n }\n let body = '';\n req.on('data', (chunk) => { body += chunk.toString(); });\n req.on('end', () => {\n const signature = req.headers['x-hub-signature-256'] || req.headers['x-hub-signature'] || req.headers['x-gitlab-token'] || '';\n if (config.secret && !verifySignature(body, signature, config.secret)) {\n log('Invalid signature'); res.writeHead(401); res.end('Unauthorized'); return;\n }\n const branch = getBranchFromPayload(body);\n if (!branch) { res.writeHead(400); res.end('Invalid payload'); return; }\n log('Push to branch: ' + branch);\n if (branch !== config.branch) { res.writeHead(200); res.end('OK (ignored)'); return; }\n log('Triggering deployment...');\n runUpdate();\n res.writeHead(200); res.end('Deployment triggered');\n });\n});\n\nserver.listen(config.port, '0.0.0.0', () => {\n log('Webhook handler started for ' + config.app + ' on port ' + config.port);\n});\n\nprocess.on('SIGTERM', () => { server.close(() => process.exit(0)); });\nprocess.on('SIGINT', () => { server.close(() => process.exit(0)); });\nHANDLER_EOF\n\n chmod +x /usr/local/bin/webhook-${name}.js\n\n # Create systemd service\n cat << 'SERVICE_EOF' > /etc/systemd/system/webhook-${name}.service\n[Unit]\nDescription=Webhook handler for ${name}\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/node /usr/local/bin/webhook-${name}.js\nRestart=always\nRestartSec=10\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=webhook-${name}\n\n[Install]\nWantedBy=multi-user.target\nSERVICE_EOF\n\n # Open firewall port\n ufw allow ${port}/tcp comment \"webhook-${name}\"\n\n # Start service\n systemctl daemon-reload\n systemctl enable webhook-${name}\n systemctl start webhook-${name}\n\n echo \"webhook-ready:${port}\"\n `,\n\n // Save app config\n saveConfig: (name: string, config: object) => `\n CONFIG_FILE=\"/var/www/${name}/.provisor.json\"\n mkdir -p \"/var/www/${name}\"\n echo '${JSON.stringify(config)}' > \"$CONFIG_FILE\"\n chmod 600 \"$CONFIG_FILE\"\n `,\n\n // Find available port for webhook\n findAvailablePort: () => `\n for port in $(seq 9000 9100); do\n if ! ss -tuln | grep -q \":$port \"; then\n echo $port\n exit 0\n fi\n done\n echo \"9000\"\n `,\n\n // Setup git polling service for automatic deployment\n setupPolling: (name: string, branch: string, user: string, interval: number) => `\n # Create polling script (single poll)\n cat << 'POLLING_EOF' > /usr/local/bin/poll-${name}.sh\n#!/bin/bash\nset -e\n\nAPP_DIR=\"/var/www/${name}\"\nBRANCH=\"${branch}\"\nUSER=\"${user}\"\nLOCK_FILE=\"/tmp/poll-${name}.lock\"\n\n# Prevent concurrent runs\nexec 200>\"$LOCK_FILE\"\nflock -n 200 || exit 0\n\ncd \"$APP_DIR\"\n\n# Fetch latest changes\nsudo -u $USER git fetch origin \"$BRANCH\" --quiet 2>/dev/null\n\n# Get local and remote hashes\nLOCAL=$(git rev-parse HEAD)\nREMOTE=$(git rev-parse \"origin/$BRANCH\")\n\n# If different, deploy\nif [ \"$LOCAL\" != \"$REMOTE\" ]; then\n echo \"[$(date -Iseconds)] New commit detected: $REMOTE\"\n sudo /usr/local/bin/update-${name}\nelse\n echo \"[$(date -Iseconds)] No changes\"\nfi\nPOLLING_EOF\n\n chmod +x /usr/local/bin/poll-${name}.sh\n\n # Check if systemd is available (PID 1)\n if pidof systemd > /dev/null 2>&1 || [ \"$(cat /proc/1/comm 2>/dev/null)\" = \"systemd\" ]; then\n # SYSTEMD MODE: Use timer\n cat << SERVICE_EOF > /etc/systemd/system/poll-${name}.service\n[Unit]\nDescription=Git polling service for ${name}\nAfter=network.target\n\n[Service]\nType=oneshot\nExecStart=/usr/local/bin/poll-${name}.sh\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=poll-${name}\nSERVICE_EOF\n\n cat << TIMER_EOF > /etc/systemd/system/poll-${name}.timer\n[Unit]\nDescription=Run git polling for ${name} every ${interval} seconds\n\n[Timer]\nOnBootSec=30\nOnUnitActiveSec=${interval}s\nAccuracySec=1s\n\n[Install]\nWantedBy=timers.target\nTIMER_EOF\n\n systemctl daemon-reload\n systemctl enable poll-${name}.timer\n systemctl start poll-${name}.timer\n echo \"polling-ready:${interval}:systemd\"\n else\n # DAEMON MODE: Use background loop (for Docker/non-systemd)\n cat << 'DAEMON_EOF' > /usr/local/bin/poll-${name}-daemon.sh\n#!/bin/bash\nLOG_FILE=\"/var/log/poll-${name}.log\"\nPID_FILE=\"/var/run/poll-${name}.pid\"\nINTERVAL=${interval}\n\n# Write PID\necho $$ > \"$PID_FILE\"\n\necho \"[$(date -Iseconds)] Polling daemon started (every ${interval}s)\" >> \"$LOG_FILE\"\n\nwhile true; do\n /usr/local/bin/poll-${name}.sh >> \"$LOG_FILE\" 2>&1\n sleep $INTERVAL\ndone\nDAEMON_EOF\n\n chmod +x /usr/local/bin/poll-${name}-daemon.sh\n\n # Stop existing daemon if running\n if [ -f /var/run/poll-${name}.pid ]; then\n kill $(cat /var/run/poll-${name}.pid) 2>/dev/null || true\n rm -f /var/run/poll-${name}.pid\n fi\n\n # Start daemon in background\n mkdir -p /var/log\n touch /var/log/poll-${name}.log\n nohup /usr/local/bin/poll-${name}-daemon.sh > /dev/null 2>&1 &\n \n echo \"polling-ready:${interval}:daemon\"\n fi\n `,\n};\n\nconst deployOptions = [\n { label: 'Push-to-deploy (git push to server)', value: 'push' },\n { label: 'Clone from public repository', value: 'clone-public' },\n { label: 'Clone from private repository (with deploy key)', value: 'clone-private' },\n];\n\nconst existingAppOptions = [\n { label: 'Replace (delete and clone fresh)', value: 'replace' },\n { label: 'Update (git pull latest changes)', value: 'update' },\n { label: 'Cancel', value: 'cancel' },\n];\n\nconst tlsOptions = [\n { label: 'On-demand TLS (auto-cert for any domain)', value: 'ondemand' },\n { label: 'Specific domain(s)', value: 'specific' },\n { label: 'No TLS (HTTP only)', value: 'none' },\n];\n\nconst autoDeployOptions = [\n { label: 'Git polling (checks every 10s, simpler setup)', value: 'polling' },\n { label: 'Webhook (instant, requires repo webhook setup)', value: 'webhook' },\n { label: 'Manual only (use provisor deploy command)', value: 'none' },\n];\n\n// Helper to detect git host from URL\nfunction getGitHost(url: string): string {\n if (url.includes('github.com')) return 'github.com';\n if (url.includes('gitlab.com')) return 'gitlab.com';\n if (url.includes('bitbucket.org')) return 'bitbucket.org';\n const match = url.match(/git@([^:]+):/);\n if (match) return match[1];\n return 'github.com';\n}\n\n// Helper to get deploy key instructions\nfunction getDeployKeyInstructions(host: string): { url: string; steps: string[] } {\n switch (host) {\n case 'github.com':\n return {\n url: 'https://github.com/<owner>/<repo>/settings/keys',\n steps: [\n '1. Go to your repository on GitHub',\n '2. Click Settings → Deploy keys → Add deploy key',\n '3. Paste the public key above',\n '4. Give it a title (e.g., \"Server deploy key\")',\n '5. Click \"Add key\" (leave \"Allow write access\" unchecked)',\n ],\n };\n case 'gitlab.com':\n return {\n url: 'https://gitlab.com/<owner>/<repo>/-/settings/repository',\n steps: [\n '1. Go to your repository on GitLab',\n '2. Click Settings → Repository → Deploy keys',\n '3. Paste the public key above',\n '4. Give it a title and click \"Add key\"',\n ],\n };\n case 'bitbucket.org':\n return {\n url: 'https://bitbucket.org/<owner>/<repo>/admin/access-keys/',\n steps: [\n '1. Go to your repository on Bitbucket',\n '2. Click Repository settings → Access keys',\n '3. Click \"Add key\" and paste the public key above',\n ],\n };\n default:\n return {\n url: '',\n steps: [\n '1. Go to your repository settings',\n '2. Find \"Deploy keys\" or \"Access keys\" section',\n '3. Add the public key shown above',\n ],\n };\n }\n}\n\nexport function AppCommand(props: AppCommandProps) {\n const { exit } = useApp();\n const [client, setClient] = useState<Client | null>(null);\n const [tasks, setTasks] = useState<TaskState>({\n connect: 'pending',\n caddy: 'pending',\n node: 'pending',\n deployKey: 'pending',\n deploy: 'pending',\n webhook: 'pending',\n caddyConfig: 'pending',\n });\n const [error, setError] = useState<string | null>(null);\n\n // Build/Start Config\n const [buildCmd, setBuildCmd] = useState('npm run build');\n const [startCmd, setStartCmd] = useState('npm start');\n const [askingBuild, setAskingBuild] = useState(false);\n const [askingStart, setAskingStart] = useState(false);\n\n // Selection states\n const [selectingMethod, setSelectingMethod] = useState(false);\n const [deployMethod, setDeployMethod] = useState<DeployMethod | null>(props.repo ? 'clone-public' : null);\n const [enteringRepo, setEnteringRepo] = useState(false);\n const [repoUrl, setRepoUrl] = useState(props.repo || '');\n const [selectingTls, setSelectingTls] = useState(false);\n const [tlsChoice, setTlsChoice] = useState<TlsChoice | null>(null);\n\n // Deploy key states\n const [deployKey, setDeployKey] = useState<string>('');\n const [waitingForKeySetup, setWaitingForKeySetup] = useState(false);\n const [keyConfirmed, setKeyConfirmed] = useState(false);\n const [keyVerifying, setKeyVerifying] = useState(false);\n const [keyVerified, setKeyVerified] = useState(false);\n const [keyVerifyError, setKeyVerifyError] = useState<string | null>(null);\n\n // Existing app states\n const [appExists, setAppExists] = useState<boolean | null>(null);\n const [selectingExistingAction, setSelectingExistingAction] = useState(false);\n const [existingAppAction, setExistingAppAction] = useState<ExistingAppAction | null>(null);\n\n // Auto-deploy states\n const [selectingAutoDeploy, setSelectingAutoDeploy] = useState(false);\n const [autoDeployChoice, setAutoDeployChoice] = useState<AutoDeployChoice | null>(null);\n const [webhookPort, setWebhookPort] = useState<number>(0);\n const [webhookSecret, setWebhookSecret] = useState<string>('');\n const [pollingInterval, setPollingInterval] = useState<number>(10);\n\n const [serverIp, setServerIp] = useState<string>('');\n\n const appDir = `/var/www/${props.name}`;\n const repoDir = `/var/repo/${props.name}.git`;\n const gitHost = getGitHost(repoUrl);\n const keyInstructions = getDeployKeyInstructions(gitHost);\n\n const updateTask = (task: keyof TaskState, status: TaskStatus) => {\n setTasks((prev) => ({ ...prev, [task]: status }));\n };\n\n // Handle key confirmation - trigger verification\n useInput((input, key) => {\n if (waitingForKeySetup && !keyConfirmed && !keyVerifying) {\n if (input.toLowerCase() === 'y' || key.return) {\n setKeyConfirmed(true);\n setKeyVerifying(true);\n setKeyVerifyError(null);\n } else if (input.toLowerCase() === 'n' || key.escape) {\n setError('Deployment cancelled. Please add the deploy key and try again.');\n }\n }\n // Allow retry on 'r' if verification failed\n if (keyVerifyError && !keyVerifying) {\n if (input.toLowerCase() === 'r') {\n setKeyVerifying(true);\n setKeyVerifyError(null);\n } else if (input.toLowerCase() === 'q' || key.escape) {\n setError('Deployment cancelled. Please add the deploy key and try again.');\n }\n }\n });\n\n // Step 1: Connect\n useEffect(() => {\n const run = async () => {\n updateTask('connect', 'running');\n try {\n const sshClient = await connect(props);\n setClient(sshClient);\n\n const ipResult = await exec(sshClient, \"hostname -I | awk '{print $1}'\");\n setServerIp(ipResult.stdout.trim());\n\n updateTask('connect', 'success');\n } catch (err) {\n updateTask('connect', 'error');\n setError(`Connection failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, []);\n\n // Step 2: Install Caddy\n useEffect(() => {\n if (!client || tasks.connect !== 'success' || tasks.caddy !== 'pending') return;\n\n const run = async () => {\n updateTask('caddy', 'running');\n try {\n await execScript(client, SCRIPTS.installCaddy(), true);\n updateTask('caddy', 'success');\n } catch (err) {\n updateTask('caddy', 'error');\n setError(`Caddy installation failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.connect]);\n\n // Step 3: Install Node.js\n useEffect(() => {\n if (!client || tasks.caddy !== 'success' || tasks.node !== 'pending') return;\n\n const run = async () => {\n updateTask('node', 'running');\n try {\n await execScript(client, SCRIPTS.installNode(), true);\n updateTask('node', 'success');\n } catch (err) {\n updateTask('node', 'error');\n setError(`Node.js installation failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tasks.caddy]);\n\n // Step 4: Configure Build/Start\n useEffect(() => {\n if (tasks.node !== 'success' || askingBuild || askingStart || selectingMethod || deployMethod !== null) return;\n setAskingBuild(true);\n }, [tasks.node]);\n\n const handleBuildSubmit = (value: string) => {\n setBuildCmd(value);\n setAskingBuild(false);\n setAskingStart(true);\n };\n\n const handleStartSubmit = (value: string) => {\n setStartCmd(value);\n setAskingStart(false);\n setSelectingMethod(true);\n };\n\n // Step 5: Ask for deploy method (if not provided via --repo)\n useEffect(() => {\n // This is now triggered by handleStartSubmit\n }, []);\n\n const handleMethodSelect = (item: { value: string }) => {\n setSelectingMethod(false);\n const method = item.value as DeployMethod;\n setDeployMethod(method);\n\n if ((method === 'clone-public' || method === 'clone-private') && !repoUrl) {\n setEnteringRepo(true);\n }\n };\n\n const handleRepoSubmit = (value: string) => {\n setRepoUrl(value);\n setEnteringRepo(false);\n };\n\n // Step 5: Check if app exists (for clone methods)\n useEffect(() => {\n if (!client || !deployMethod || enteringRepo) return;\n if (deployMethod === 'push') {\n setAppExists(false); // Push-to-deploy handles this differently\n return;\n }\n if (appExists !== null) return;\n\n const run = async () => {\n try {\n const result = await exec(client, SCRIPTS.checkAppExists(props.name));\n setAppExists(result.stdout.trim() === 'exists');\n } catch {\n setAppExists(false);\n }\n };\n run();\n }, [client, deployMethod, enteringRepo, repoUrl]);\n\n // Step 5b: Show existing app options if needed\n useEffect(() => {\n if (appExists === true && !selectingExistingAction && existingAppAction === null) {\n setSelectingExistingAction(true);\n }\n if (appExists === false && existingAppAction === null) {\n setExistingAppAction('replace'); // No existing app, proceed with fresh clone\n }\n }, [appExists]);\n\n const handleExistingAppSelect = (item: { value: string }) => {\n setSelectingExistingAction(false);\n const action = item.value as ExistingAppAction;\n if (action === 'cancel') {\n setError('Deployment cancelled.');\n return;\n }\n setExistingAppAction(action);\n };\n\n // Step 6: Generate deploy key (for private repos)\n useEffect(() => {\n if (!client || deployMethod !== 'clone-private' || !repoUrl || tasks.deployKey !== 'pending') return;\n if (existingAppAction === null) return;\n\n const run = async () => {\n updateTask('deployKey', 'running');\n try {\n const result = await execScript(client, SCRIPTS.generateDeployKey(props.name, props.user || 'deploy'), true);\n setDeployKey(result.stdout.trim());\n updateTask('deployKey', 'success');\n setWaitingForKeySetup(true);\n } catch (err) {\n updateTask('deployKey', 'error');\n setError(`Deploy key generation failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, deployMethod, repoUrl, existingAppAction]);\n\n // Skip deploy key for non-private methods\n useEffect(() => {\n if (deployMethod && deployMethod !== 'clone-private' && tasks.deployKey === 'pending' && existingAppAction !== null) {\n updateTask('deployKey', 'skipped');\n }\n }, [deployMethod, existingAppAction]);\n\n // Step 6b: Verify deploy key works\n useEffect(() => {\n if (!client || !keyVerifying || keyVerified) return;\n\n const run = async () => {\n try {\n // Test SSH connection to git host (run as deploy user, not root)\n const result = await execScript(client, SCRIPTS.testGitConnection(gitHost), false);\n const output = result.stdout.toLowerCase();\n \n // Check for error indicators FIRST (more specific)\n if (output.includes('permission denied') && !output.includes('successfully authenticated')) {\n setKeyVerifyError('Permission denied. The deploy key may not be added correctly or may not have read access.');\n setKeyVerifying(false);\n return;\n }\n \n // Check for success indicators\n // GitHub: \"Hi user/repo! You've successfully authenticated\"\n // GitLab: \"Welcome to GitLab\"\n // Bitbucket: \"logged in as\"\n if (\n output.includes('successfully authenticated') ||\n output.includes('welcome to gitlab') ||\n output.includes('logged in as') ||\n (output.includes('hi ') && output.includes('!')) // GitHub format: \"Hi user/repo!\"\n ) {\n setKeyVerified(true);\n setKeyVerifying(false);\n setWaitingForKeySetup(false);\n } else if (output.includes('could not resolve') || output.includes('connection refused')) {\n setKeyVerifyError(`Could not connect to ${gitHost}. Check your network connection.`);\n setKeyVerifying(false);\n } else {\n // If no clear indicators, show actual output for debugging\n setKeyVerifyError(`Unexpected response from ${gitHost}: ${output.substring(0, 200)}`);\n setKeyVerifying(false);\n }\n } catch (err) {\n setKeyVerifyError(`Connection test failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n setKeyVerifying(false);\n }\n };\n run();\n }, [client, keyVerifying, keyVerified, gitHost]);\n\n // Step 7: Setup deployment\n useEffect(() => {\n if (!client || !deployMethod || tasks.deploy !== 'pending') return;\n if (tasks.deployKey !== 'success' && tasks.deployKey !== 'skipped') return;\n // For private repos, require verified key (not just confirmed)\n if (deployMethod === 'clone-private' && !keyVerified) return;\n if ((deployMethod === 'clone-public' || deployMethod === 'clone-private') && !repoUrl) return;\n if (existingAppAction === null) return;\n\n const run = async () => {\n updateTask('deploy', 'running');\n try {\n if (deployMethod === 'push') {\n await execScript(client, SCRIPTS.setupPushDeploy(props.name, props.branch, props.user || 'deploy', buildCmd, startCmd), true);\n } else {\n // For private repos, test connection first\n if (deployMethod === 'clone-private') {\n await execScript(client, SCRIPTS.testGitConnection(gitHost), true);\n }\n\n // Clone fresh or update based on user choice\n if (existingAppAction === 'replace') {\n await execScript(client, SCRIPTS.cloneRepoFresh(props.name, repoUrl, props.branch, props.user || 'deploy', buildCmd, startCmd), true);\n } else {\n await execScript(client, SCRIPTS.updateRepo(props.name, props.branch, props.user || 'deploy', buildCmd, startCmd), true);\n }\n\n await execScript(client, SCRIPTS.createUpdateScript(props.name, props.branch, props.user || 'deploy', buildCmd, startCmd), true);\n }\n updateTask('deploy', 'success');\n } catch (err) {\n updateTask('deploy', 'error');\n setError(`Deployment setup failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, deployMethod, repoUrl, keyVerified, tasks.deployKey, existingAppAction]);\n\n // Step 8: Ask about auto-deploy (only for clone methods)\n useEffect(() => {\n if (tasks.deploy !== 'success' || tasks.webhook !== 'pending') return;\n if (deployMethod === 'push') {\n // Push-to-deploy already has automatic deployment via git hook\n updateTask('webhook', 'skipped');\n return;\n }\n if (!selectingAutoDeploy && autoDeployChoice === null) {\n setSelectingAutoDeploy(true);\n }\n }, [tasks.deploy, deployMethod]);\n\n const handleAutoDeploySelect = async (item: { value: string }) => {\n setSelectingAutoDeploy(false);\n const choice = item.value as AutoDeployChoice;\n setAutoDeployChoice(choice);\n\n if (choice === 'none') {\n updateTask('webhook', 'skipped');\n }\n };\n\n // Step 8b: Setup auto-deploy if chosen\n useEffect(() => {\n if (!client || !autoDeployChoice || autoDeployChoice === 'none' || tasks.webhook !== 'pending') return;\n\n const run = async () => {\n updateTask('webhook', 'running');\n try {\n const user = props.user || 'deploy';\n\n if (autoDeployChoice === 'polling') {\n // Setup polling service\n await execScript(client, SCRIPTS.setupPolling(props.name, props.branch, user, pollingInterval), true);\n\n // Save config\n const config = {\n repo: repoUrl,\n branch: props.branch,\n buildCmd,\n startCmd,\n autoDeployType: 'polling',\n pollingInterval: pollingInterval,\n };\n await execScript(client, SCRIPTS.saveConfig(props.name, config), true);\n } else if (autoDeployChoice === 'webhook') {\n // Find available port\n const portResult = await exec(client, SCRIPTS.findAvailablePort());\n const port = parseInt(portResult.stdout.trim(), 10) || 9000;\n setWebhookPort(port);\n\n // Generate a random secret\n const secret = crypto.randomBytes(32).toString('hex');\n setWebhookSecret(secret);\n\n // Setup webhook handler\n await execScript(client, SCRIPTS.setupWebhook(props.name, props.branch, port, secret), true);\n\n // Save config\n const config = {\n repo: repoUrl,\n branch: props.branch,\n buildCmd,\n startCmd,\n autoDeployType: 'webhook',\n webhookPort: port,\n };\n await execScript(client, SCRIPTS.saveConfig(props.name, config), true);\n }\n\n updateTask('webhook', 'success');\n } catch (err) {\n updateTask('webhook', 'error');\n setError(`Auto-deploy setup failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, autoDeployChoice]);\n\n // Step 9: Wait for TLS choice\n useEffect(() => {\n if (tasks.deploy !== 'success') return;\n if (tasks.webhook !== 'success' && tasks.webhook !== 'skipped') return;\n if (selectingTls || tlsChoice !== null) return;\n setSelectingTls(true);\n }, [tasks.deploy, tasks.webhook]);\n\n // Step 9: Configure Caddy\n useEffect(() => {\n if (!client || !tlsChoice || tasks.caddyConfig !== 'pending') return;\n\n const run = async () => {\n updateTask('caddyConfig', 'running');\n try {\n let script: string;\n switch (tlsChoice) {\n case 'ondemand':\n script = SCRIPTS.caddyOnDemand(appDir);\n break;\n case 'specific':\n script = SCRIPTS.caddyOnDemand(appDir);\n break;\n case 'none':\n script = SCRIPTS.caddyHttp(appDir);\n break;\n }\n await execScript(client, script, true);\n updateTask('caddyConfig', 'success');\n disconnect(client);\n setTimeout(() => exit(), 100);\n } catch (err) {\n updateTask('caddyConfig', 'error');\n setError(`Caddy config failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, [client, tlsChoice]);\n\n const handleTlsSelect = (item: { value: string }) => {\n setSelectingTls(false);\n setTlsChoice(item.value as TlsChoice);\n };\n\n // Handle errors\n useEffect(() => {\n if (error && client) {\n disconnect(client);\n setTimeout(() => exit(), 100);\n }\n }, [error]);\n\n const allDone = tasks.caddyConfig === 'success';\n const isClone = deployMethod === 'clone-public' || deployMethod === 'clone-private';\n const deployLabel = isClone\n ? existingAppAction === 'update'\n ? `Update ${props.name}`\n : `Clone from ${repoUrl || 'repository'}`\n : 'Setup push-to-deploy';\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Application Provisioning\" subtitle={`Host: ${props.host}`} />\n\n <Task label=\"Connect to server\" status={tasks.connect} />\n <Task label=\"Install Caddy\" status={tasks.caddy} />\n <Task label=\"Install Node.js & PM2\" status={tasks.node} />\n {deployMethod === 'clone-private' && (\n <Task label=\"Generate deploy key\" status={tasks.deployKey} />\n )}\n <Task label={deployLabel} status={tasks.deploy} />\n {(deployMethod === 'clone-public' || deployMethod === 'clone-private') && autoDeployChoice && autoDeployChoice !== 'none' && (\n <Task label={`Setup ${autoDeployChoice === 'polling' ? 'git polling' : 'webhook'} for auto-deploy`} status={tasks.webhook} />\n )}\n <Task label=\"Configure Caddy\" status={tasks.caddyConfig} />\n\n {askingBuild && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Build command (optional, press Enter to skip):</Text>\n <Text color=\"gray\">Command to build the app (e.g. 'npm run build')</Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={buildCmd} onChange={setBuildCmd} onSubmit={handleBuildSubmit} />\n </Box>\n </Box>\n )}\n\n {askingStart && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Start command:</Text>\n <Text color=\"gray\">Command to start the app (e.g. 'npm start' or 'node server.js')</Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={startCmd} onChange={setStartCmd} onSubmit={handleStartSubmit} />\n </Box>\n </Box>\n )}\n\n {selectingMethod && deployMethod === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Select deployment method:</Text>\n <SelectInput items={deployOptions} onSelect={handleMethodSelect} />\n </Box>\n )}\n\n {enteringRepo && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Enter repository URL:</Text>\n <Text color=\"gray\">\n {deployMethod === 'clone-private'\n ? '(Use SSH URL: git@github.com:user/repo.git)'\n : '(e.g., https://github.com/user/repo.git)'}\n </Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={repoUrl} onChange={setRepoUrl} onSubmit={handleRepoSubmit} />\n </Box>\n </Box>\n )}\n\n {selectingExistingAction && existingAppAction === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">⚠ App directory {appDir} already exists</Text>\n <Text color=\"gray\">What would you like to do?</Text>\n <Box marginTop={1}>\n <SelectInput items={existingAppOptions} onSelect={handleExistingAppSelect} />\n </Box>\n </Box>\n )}\n\n {waitingForKeySetup && deployKey && !keyConfirmed && !keyVerifying && !keyVerified && !keyVerifyError && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">━━━ Deploy Key Generated ━━━</Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Public key (copy this):</Text>\n <Box marginY={1} paddingX={1} borderStyle=\"single\" borderColor=\"cyan\">\n <Text color=\"cyan\">{deployKey}</Text>\n </Box>\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Add this key to {gitHost}:</Text>\n {keyInstructions.steps.map((step, i) => (\n <Text key={i} color=\"gray\"> {step}</Text>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text color=\"yellow\">Have you added the deploy key to {gitHost}? </Text>\n <Text color=\"gray\">(y/n) </Text>\n </Box>\n </Box>\n )}\n\n {keyVerifying && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">━━━ Verifying Deploy Key ━━━</Text>\n <Box marginTop={1}>\n <Spinner type=\"dots\" />\n <Text color=\"gray\"> Testing SSH connection to {gitHost}...</Text>\n </Box>\n </Box>\n )}\n\n {keyVerified && !error && (\n <Box marginTop={1}>\n <Text color=\"green\">✓ Deploy key verified successfully!</Text>\n </Box>\n )}\n\n {keyVerifyError && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"red\">━━━ Deploy Key Verification Failed ━━━</Text>\n <Box marginTop={1}>\n <Text color=\"red\">✗ {keyVerifyError}</Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Please check:</Text>\n <Text color=\"gray\"> 1. The deploy key is added to {gitHost}</Text>\n <Text color=\"gray\"> 2. The key has read access to the repository</Text>\n <Text color=\"gray\"> 3. The repository URL is correct</Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Public key to add:</Text>\n <Box marginY={1} paddingX={1} borderStyle=\"single\" borderColor=\"cyan\">\n <Text color=\"cyan\">{deployKey}</Text>\n </Box>\n </Box>\n <Box marginTop={1}>\n <Text color=\"yellow\">Press (r) to retry or (q) to quit</Text>\n </Box>\n </Box>\n )}\n\n {selectingAutoDeploy && autoDeployChoice === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Enable automatic deployment?</Text>\n <Text color=\"gray\">Auto-deploy when you push to {props.branch} branch.</Text>\n <Box marginTop={1}>\n <SelectInput items={autoDeployOptions} onSelect={handleAutoDeploySelect} />\n </Box>\n </Box>\n )}\n\n {selectingTls && tlsChoice === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Select TLS configuration:</Text>\n <SelectInput items={tlsOptions} onSelect={handleTlsSelect} />\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n\n {allDone && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"green\" bold>✓ Application provisioning complete</Text>\n <Box marginTop={1} flexDirection=\"column\">\n {deployMethod === 'push' ? (\n <>\n <Text bold>Git remote (add to local project):</Text>\n <Text color=\"cyan\"> git remote add production ssh://{props.user}@{serverIp}{repoDir}</Text>\n <Box marginTop={1}>\n <Text bold>Deploy with:</Text>\n </Box>\n <Text color=\"cyan\"> git push production {props.branch}</Text>\n </>\n ) : (\n <>\n <Text bold>App {existingAppAction === 'update' ? 'updated' : 'deployed'} from: <Text color=\"cyan\">{repoUrl}</Text></Text>\n <Box marginTop={1}>\n <Text bold>Manual update:</Text>\n </Box>\n <Text color=\"cyan\"> ssh {props.user}@{serverIp} \"sudo update-{props.name}\"</Text>\n\n {autoDeployChoice === 'polling' && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">━━━ Auto-Deploy (Git Polling) ━━━</Text>\n <Text>Polling interval: <Text color=\"cyan\">{pollingInterval} seconds</Text></Text>\n <Text>Branch: <Text color=\"cyan\">{props.branch}</Text></Text>\n <Text color=\"gray\">The server checks for new commits and deploys automatically.</Text>\n <Box marginTop={1}>\n <Text>View logs: <Text color=\"cyan\">journalctl -u poll-{props.name} -f</Text></Text>\n </Box>\n </Box>\n )}\n\n {autoDeployChoice === 'webhook' && webhookPort > 0 && (\n <>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">━━━ Auto-Deploy (Webhook) ━━━</Text>\n <Text>Webhook URL: <Text color=\"cyan\">http://{serverIp}:{webhookPort}/webhook</Text></Text>\n <Text>Secret: <Text color=\"cyan\">{webhookSecret}</Text></Text>\n <Text>Branch: <Text color=\"cyan\">{props.branch}</Text></Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Add webhook to your repository:</Text>\n {gitHost === 'github.com' && (\n <>\n <Text color=\"gray\"> 1. Go to your repo → Settings → Webhooks → Add webhook</Text>\n <Text color=\"gray\"> 2. Payload URL: http://{serverIp}:{webhookPort}/webhook</Text>\n <Text color=\"gray\"> 3. Content type: application/json</Text>\n <Text color=\"gray\"> 4. Secret: {webhookSecret}</Text>\n <Text color=\"gray\"> 5. Select \"Just the push event\"</Text>\n </>\n )}\n {gitHost === 'gitlab.com' && (\n <>\n <Text color=\"gray\"> 1. Go to your repo → Settings → Webhooks</Text>\n <Text color=\"gray\"> 2. URL: http://{serverIp}:{webhookPort}/webhook</Text>\n <Text color=\"gray\"> 3. Secret token: {webhookSecret}</Text>\n <Text color=\"gray\"> 4. Trigger: Push events</Text>\n </>\n )}\n {gitHost === 'bitbucket.org' && (\n <>\n <Text color=\"gray\"> 1. Go to your repo → Repository settings → Webhooks</Text>\n <Text color=\"gray\"> 2. URL: http://{serverIp}:{webhookPort}/webhook</Text>\n <Text color=\"gray\"> 3. Triggers: Repository push</Text>\n </>\n )}\n </Box>\n </>\n )}\n </>\n )}\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useApp, useInput } from 'ink'\nimport { Header, Task, type TaskStatus } from '../components/index.js'\nimport { connect, exec, disconnect, type SSHOptions } from '../utils/ssh.js'\nimport type { Client } from 'ssh2'\n\ninterface SshKeyCommandProps extends SSHOptions {\n add?: string\n list?: boolean\n onBack?: () => void\n}\n\nexport function SshKeyCommand(props: SshKeyCommandProps) {\n const { exit } = useApp()\n const [client, setClient] = useState<Client | null>(null)\n const [status, setStatus] = useState<TaskStatus>('pending')\n const [error, setError] = useState<string | null>(null)\n const [keys, setKeys] = useState<string[]>([])\n const [message, setMessage] = useState<string>('')\n const [done, setDone] = useState(false)\n\n const goBack = () => {\n if (props.onBack) {\n props.onBack()\n } else {\n exit()\n }\n }\n\n useInput((input, key) => {\n if (done && (key.escape || input === 'q')) {\n goBack()\n }\n })\n\n useEffect(() => {\n const run = async () => {\n setStatus('running')\n\n try {\n const sshClient = await connect(props)\n setClient(sshClient)\n\n if (props.list) {\n const result = await exec(sshClient, 'cat ~/.ssh/authorized_keys 2>/dev/null || echo \"\"')\n const keyList = result.stdout\n .trim()\n .split('\\n')\n .filter((k) => k.length > 0)\n .map((k) => {\n // Extract key type and comment\n const parts = k.split(' ')\n const type = parts[0] || 'unknown'\n const comment = parts[2] || 'no comment'\n const keyPreview = parts[1]?.slice(-12) || ''\n return `${type} ...${keyPreview} ${comment}`\n })\n setKeys(keyList)\n setStatus('success')\n setMessage(`Found ${keyList.length} key(s)`)\n } else if (props.add) {\n // Validate key format\n const keyPattern = /^(ssh-rsa|ssh-ed25519|ssh-dss|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521)\\s+\\S+/\n if (!keyPattern.test(props.add)) {\n throw new Error('Invalid SSH key format')\n }\n\n // Check for duplicates\n const existing = await exec(sshClient, 'cat ~/.ssh/authorized_keys 2>/dev/null || echo \"\"')\n if (existing.stdout.includes(props.add)) {\n setStatus('success')\n setMessage('Key already exists (skipped)')\n } else {\n // Add key\n const escapedKey = props.add.replace(/'/g, \"'\\\\''\")\n await exec(sshClient, `echo '${escapedKey}' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys`)\n setStatus('success')\n setMessage('Key added successfully')\n }\n } else {\n setStatus('error')\n setError('Specify --add <key> or --list')\n }\n\n disconnect(sshClient)\n setDone(true)\n } catch (err) {\n setStatus('error')\n setError(err instanceof Error ? err.message : String(err))\n if (client) disconnect(client)\n setDone(true)\n }\n }\n\n run()\n }, [])\n\n const operation = props.list ? 'List SSH keys' : 'Add SSH key'\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"SSH Key Management\" subtitle={`Host: ${props.host}`} />\n\n <Task label={operation} status={status} message={message} />\n\n {props.list && keys.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Authorized keys:</Text>\n {keys.map((key, i) => (\n <Text key={i} color=\"gray\"> {i + 1}. {key}</Text>\n ))}\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n\n {done && (\n <Box marginTop={1}>\n <Text color=\"gray\">Press 'q' or Esc to go back</Text>\n </Box>\n )}\n </Box>\n )\n}\n\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useApp, useInput } from 'ink'\nimport { Header, Task, type TaskStatus } from '../components/index.js'\nimport { connect, exec, disconnect, type SSHOptions } from '../utils/ssh.js'\nimport type { Client } from 'ssh2'\n\ninterface StatusCommandProps extends SSHOptions {\n onBack?: () => void\n}\n\ninterface ServiceStatus {\n name: string\n running: boolean\n status: string\n}\n\ninterface SystemInfo {\n hostname: string\n uptime: string\n load: string\n memory: string\n disk: string\n}\n\nexport function StatusCommand(props: StatusCommandProps) {\n const { exit } = useApp()\n const [taskStatus, setTaskStatus] = useState<TaskStatus>('pending')\n const [error, setError] = useState<string | null>(null)\n const [services, setServices] = useState<ServiceStatus[]>([])\n const [system, setSystem] = useState<SystemInfo | null>(null)\n const [done, setDone] = useState(false)\n\n const goBack = () => {\n if (props.onBack) {\n props.onBack()\n } else {\n exit()\n }\n }\n\n useInput((input, key) => {\n if (done && (key.escape || input === 'q')) {\n goBack()\n }\n })\n\n useEffect(() => {\n const run = async () => {\n setTaskStatus('running')\n\n try {\n const client = await connect(props)\n\n // Get system info\n const [hostnameRes, uptimeRes, loadRes, memRes, diskRes] = await Promise.all([\n exec(client, 'hostname'),\n exec(client, \"uptime -p 2>/dev/null || uptime | awk -F'up' '{print $2}' | awk -F',' '{print $1}'\"),\n exec(client, \"cat /proc/loadavg | awk '{print $1, $2, $3}'\"),\n exec(client, \"free -h | awk '/^Mem:/ {print $3 \\\"/\\\" $2}'\"),\n exec(client, \"df -h / | awk 'NR==2 {print $3 \\\"/\\\" $2 \\\" (\\\" $5 \\\")\\\"}'\"),\n ])\n\n setSystem({\n hostname: hostnameRes.stdout.trim(),\n uptime: uptimeRes.stdout.trim(),\n load: loadRes.stdout.trim(),\n memory: memRes.stdout.trim(),\n disk: diskRes.stdout.trim(),\n })\n\n // Check services\n const serviceChecks = ['caddy', 'ssh', 'ufw']\n const serviceResults: ServiceStatus[] = []\n\n for (const svc of serviceChecks) {\n const result = await exec(client, `systemctl is-active ${svc} 2>/dev/null || echo \"not-found\"`)\n const status = result.stdout.trim()\n serviceResults.push({\n name: svc,\n running: status === 'active',\n status,\n })\n }\n\n // Check PM2\n const pm2Result = await exec(client, 'pm2 list 2>/dev/null | grep -E \"online|stopped|errored\" | wc -l || echo \"0\"')\n const pm2Count = parseInt(pm2Result.stdout.trim(), 10)\n serviceResults.push({\n name: 'pm2',\n running: pm2Count > 0,\n status: pm2Count > 0 ? `${pm2Count} process(es)` : 'no processes',\n })\n\n setServices(serviceResults)\n setTaskStatus('success')\n setDone(true)\n disconnect(client)\n } catch (err) {\n setTaskStatus('error')\n setError(err instanceof Error ? err.message : String(err))\n setDone(true)\n }\n }\n\n run()\n }, [])\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Server Status\" subtitle={`Host: ${props.host}`} />\n\n <Task label=\"Checking server status\" status={taskStatus} />\n\n {system && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>System:</Text>\n <Text color=\"gray\"> Hostname: <Text color=\"white\">{system.hostname}</Text></Text>\n <Text color=\"gray\"> Uptime: <Text color=\"white\">{system.uptime}</Text></Text>\n <Text color=\"gray\"> Load: <Text color=\"white\">{system.load}</Text></Text>\n <Text color=\"gray\"> Memory: <Text color=\"white\">{system.memory}</Text></Text>\n <Text color=\"gray\"> Disk: <Text color=\"white\">{system.disk}</Text></Text>\n </Box>\n )}\n\n {services.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Services:</Text>\n {services.map((svc) => (\n <Box key={svc.name}>\n <Text color=\"gray\"> </Text>\n <Text color={svc.running ? 'green' : 'red'}>\n {svc.running ? '●' : '○'}\n </Text>\n <Text> {svc.name}: </Text>\n <Text color={svc.running ? 'green' : 'yellow'}>{svc.status}</Text>\n </Box>\n ))}\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n\n {done && (\n <Box marginTop={1}>\n <Text color=\"gray\">Press 'q' or Esc to go back</Text>\n </Box>\n )}\n </Box>\n )\n}\n\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport { Header, Task, type TaskStatus } from '../components/index.js';\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface DeployCommandProps extends SSHOptions {\n name: string;\n onBack?: () => void;\n}\n\nexport function DeployCommand(props: DeployCommandProps) {\n const { exit } = useApp();\n const [status, setStatus] = useState<TaskStatus>('pending');\n const [output, setOutput] = useState<string[]>([]);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const run = async () => {\n setStatus('running');\n\n try {\n const client = await connect(props);\n\n // Check if update script exists\n const checkResult = await exec(client, `test -f /usr/local/bin/update-${props.name} && echo \"exists\" || echo \"not_found\"`);\n\n if (checkResult.stdout.trim() !== 'exists') {\n throw new Error(`Update script for '${props.name}' not found. Run 'provisor app' first.`);\n }\n\n // Run the update script and capture output\n const result = await exec(client, `sudo /usr/local/bin/update-${props.name} 2>&1`);\n\n setOutput(result.stdout.trim().split('\\n'));\n setStatus('success');\n\n disconnect(client);\n if (!props.onBack) {\n setTimeout(() => exit(), 100);\n }\n } catch (err) {\n setStatus('error');\n setError(err instanceof Error ? err.message : String(err));\n if (!props.onBack) {\n setTimeout(() => exit(), 100);\n }\n }\n };\n\n run();\n }, []);\n\n useInput((input, key) => {\n if ((status === 'success' || status === 'error') && props.onBack) {\n // Allow any key to back on completion\n props.onBack();\n }\n });\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Deploy Application\" subtitle={`App: ${props.name} | Host: ${props.host}`} />\n\n <Task label={`Deploying ${props.name}`} status={status} />\n\n {output.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n {output.map((line, i) => (\n <Text key={i} color=\"gray\">{line}</Text>\n ))}\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n\n {status === 'success' && (\n <Box marginTop={1}>\n <Text color=\"green\" bold>✓ Deployment complete. Press any key to return.</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport TextInput from 'ink-text-input';\nimport { Header, Task, type TaskStatus } from '../components/index.js';\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface ConfigCommandProps extends SSHOptions {\n name: string;\n show?: boolean;\n repo?: string;\n branch?: string;\n newKey?: boolean;\n deleteKey?: boolean;\n webhookSecret?: string;\n disableWebhook?: boolean;\n pollingInterval?: number;\n disablePolling?: boolean;\n enablePolling?: boolean;\n logSource?: string;\n logPath?: string;\n onBack?: () => void;\n}\n\ntype ConfigAction = 'show' | 'repo' | 'branch' | 'new-key' | 'delete-key' | 'webhook-secret' | 'disable-webhook' | 'polling-interval' | 'enable-polling' | 'disable-polling' | 'log-source' | 'log-path' | '__back__';\n\ninterface AppConfig {\n repo: string;\n branch: string;\n deployKey: string | null;\n webhookEnabled: boolean;\n webhookPort: number;\n pollingEnabled: boolean;\n pollingInterval: number;\n autoDeployType: 'webhook' | 'polling' | 'none';\n buildCmd?: string;\n startCmd?: string;\n logSource?: 'pm2' | 'file' | 'systemd';\n logPath?: string;\n}\n\nconst SCRIPTS = {\n // Read current config\n getConfig: (name: string) => `\n CONFIG_FILE=\"/var/www/${name}/.provisor.json\"\n if [ -f \"$CONFIG_FILE\" ]; then\n sudo cat \"$CONFIG_FILE\"\n else\n # Try to construct from git info\n APP_DIR=\"/var/www/${name}\"\n if [ -d \"$APP_DIR/.git\" ]; then\n cd \"$APP_DIR\"\n REPO=$(git remote get-url origin 2>/dev/null || echo \"\")\n BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\n echo '{\"repo\":\"'\"$REPO\"'\",\"branch\":\"'\"$BRANCH\"'\",\"webhookEnabled\":false,\"webhookPort\":0,\"buildCmd\":\"npm run build\",\"startCmd\":\"npm start\"}'\n else\n echo '{\"error\":\"App not found or not a git repository\"}'\n fi\n fi\n `,\n\n // Get full app footprint\n getAppFootprint: (name: string, user: string) => `\n echo '{'\n \n # Paths\n APP_DIR=\"/var/www/${name}\"\n echo '\"paths\": {'\n echo '\"appDir\": \"'$APP_DIR'\",'\n echo '\"config\": \"'$APP_DIR/.provisor.json'\",'\n echo '\"updateScript\": \"/usr/local/bin/update-'$name'\",'\n echo '\"webhookService\": \"/etc/systemd/system/webhook-'$name'.service\",'\n echo '\"pollScript\": \"/usr/local/bin/poll-'$name'.sh\",'\n echo '\"pollService\": \"/etc/systemd/system/poll-'$name'.service\",'\n echo '\"pollTimer\": \"/etc/systemd/system/poll-'$name'.timer\"'\n echo '},'\n\n # Statuses\n echo '\"status\": {'\n \n # PM2 Status\n # We try to use pm2 jlist. If running as deploy user, we might need sudo -u deploy? \n # Usually pm2 is run by the user. \n PM2_STATUS=\"offline\"\n if command -v pm2 >/dev/null 2>&1; then\n # Try current user first\n if pm2 describe $name > /dev/null 2>&1; then\n PM2_STATUS=$(pm2 jlist | grep -oP '\"name\":\"'$name'\".*?\"status\":\"\\\\K[^\"]+')\n else\n # Try sudo -u user\n PM2_STATUS=$(sudo -u ${user} pm2 jlist 2>/dev/null | grep -oP '\"name\":\"'$name'\".*?\"status\":\"\\\\K[^\"]+' || echo \"offline\")\n fi\n elif sudo -u ${user} command -v pm2 >/dev/null 2>&1; then\n PM2_STATUS=$(sudo -u ${user} pm2 jlist 2>/dev/null | grep -oP '\"name\":\"'$name'\".*?\"status\":\"\\\\K[^\"]+' || echo \"offline\")\n fi\n # Cleanup grep result\n PM2_STATUS=$(echo $PM2_STATUS | tr -d '\\n')\n if [ -z \"$PM2_STATUS\" ]; then PM2_STATUS=\"offline\"; fi\n echo '\"pm2\": \"'$PM2_STATUS'\",'\n\n # Webhook Status\n WEBHOOK=\"inactive\"\n if systemctl is-active --quiet webhook-$name; then WEBHOOK=\"active\"; fi\n echo '\"webhook\": \"'$WEBHOOK'\",'\n\n # Polling Status\n POLL=\"inactive\"\n if systemctl is-active --quiet poll-$name.timer; then POLL=\"active\"; fi\n echo '\"polling\": \"'$POLL'\"'\n \n echo '}'\n echo '}'\n `,\n\n // Save config\n saveConfig: (name: string, config: string) => `\n CONFIG_FILE=\"/var/www/${name}/.provisor.json\"\n echo '${config}' > \"$CONFIG_FILE\"\n chmod 600 \"$CONFIG_FILE\"\n `,\n\n // Update repository URL\n updateRepo: (name: string, repoUrl: string, user: string) => `\n APP_DIR=\"/var/www/${name}\"\n cd \"$APP_DIR\"\n sudo -u ${user} git remote set-url origin \"${repoUrl}\"\n echo \"repo-updated\"\n `,\n\n // Update branch\n updateBranch: (name: string, branch: string, user: string) => `\n APP_DIR=\"/var/www/${name}\"\n cd \"$APP_DIR\"\n\n # Fetch all branches\n sudo -u ${user} git fetch origin\n\n # Switch to new branch\n sudo -u ${user} git checkout ${branch} 2>/dev/null || sudo -u ${user} git checkout -b ${branch} origin/${branch}\n sudo -u ${user} git reset --hard origin/${branch}\n\n # Update the update script with new branch\n UPDATE_SCRIPT=\"/usr/local/bin/update-${name}\"\n if [ -f \"$UPDATE_SCRIPT\" ]; then\n sed -i 's/BRANCH=\".*\"/BRANCH=\"${branch}\"/' \"$UPDATE_SCRIPT\"\n fi\n\n # Update webhook service if exists\n WEBHOOK_SERVICE=\"/etc/systemd/system/webhook-${name}.service\"\n if [ -f \"$WEBHOOK_SERVICE\" ]; then\n sed -i 's/--branch [^ ]*/--branch ${branch}/' \"$WEBHOOK_SERVICE\"\n systemctl daemon-reload\n systemctl restart webhook-${name} 2>/dev/null || true\n fi\n\n echo \"branch-updated\"\n `,\n\n // Generate new deploy key\n generateNewKey: (name: string, user: string) => `\n SSH_DIR=\"/home/${user}/.ssh\"\n KEY_FILE=\"$SSH_DIR/deploy_${name}\"\n\n # Backup old key if exists\n if [ -f \"$KEY_FILE\" ]; then\n mv \"$KEY_FILE\" \"$KEY_FILE.old.$(date +%s)\"\n mv \"$KEY_FILE.pub\" \"$KEY_FILE.pub.old.$(date +%s)\"\n fi\n\n # Generate new key\n ssh-keygen -t ed25519 -f \"$KEY_FILE\" -N \"\" -C \"deploy-key-${name}\"\n\n chown ${user}:${user} \"$KEY_FILE\" \"$KEY_FILE.pub\"\n chmod 600 \"$KEY_FILE\"\n chmod 644 \"$KEY_FILE.pub\"\n\n cat \"$KEY_FILE.pub\"\n `,\n\n // Delete deploy key\n deleteDeployKey: (name: string, user: string) => `\n SSH_DIR=\"/home/${user}/.ssh\"\n KEY_FILE=\"$SSH_DIR/deploy_${name}\"\n\n if [ -f \"$KEY_FILE\" ]; then\n rm -f \"$KEY_FILE\" \"$KEY_FILE.pub\"\n\n # Remove from SSH config\n if [ -f \"$SSH_DIR/config\" ]; then\n sed -i \"/# Deploy key for ${name}/,+4d\" \"$SSH_DIR/config\"\n fi\n\n echo \"key-deleted\"\n else\n echo \"key-not-found\"\n fi\n `,\n\n // Get current deploy key\n getDeployKey: (name: string, user: string) => `\n KEY_FILE=\"/home/${user}/.ssh/deploy_${name}.pub\"\n if [ -f \"$KEY_FILE\" ]; then\n cat \"$KEY_FILE\"\n else\n echo \"\"\n fi\n `,\n\n // Update webhook secret\n updateWebhookSecret: (name: string, secret: string) => `\n WEBHOOK_SERVICE=\"/etc/systemd/system/webhook-${name}.service\"\n if [ -f \"$WEBHOOK_SERVICE\" ]; then\n sed -i \"s/--secret '[^']*'/--secret '${secret}'/\" \"$WEBHOOK_SERVICE\"\n systemctl daemon-reload\n systemctl restart webhook-${name}\n echo \"webhook-secret-updated\"\n else\n echo \"webhook-not-configured\"\n fi\n `,\n\n // Disable webhook\n disableWebhook: (name: string) => `\n systemctl stop webhook-${name} 2>/dev/null || true\n systemctl disable webhook-${name} 2>/dev/null || true\n rm -f /etc/systemd/system/webhook-${name}.service\n systemctl daemon-reload\n echo \"webhook-disabled\"\n `,\n\n // Get webhook status\n getWebhookStatus: (name: string) => `\n if systemctl is-active --quiet webhook-${name} 2>/dev/null; then\n PORT=$(grep -oP '\\\\-\\\\-port \\\\K[0-9]+' /etc/systemd/system/webhook-${name}.service 2>/dev/null || echo \"\")\n echo \"running:$PORT\"\n else\n echo \"stopped\"\n fi\n `,\n\n // Get polling status (supports both systemd and daemon modes)\n getPollingStatus: (name: string) => `\n # Check systemd timer first\n if systemctl is-active --quiet poll-${name}.timer 2>/dev/null; then\n INTERVAL=$(grep -oP 'OnUnitActiveSec=\\\\\\\\K[0-9]+' /etc/systemd/system/poll-${name}.timer 2>/dev/null || echo \"10\")\n echo \"running:$INTERVAL:systemd\"\n # Check daemon mode (PID file) - use ps -p instead of kill -0 (no permission issues)\n elif [ -f /var/run/poll-${name}.pid ] && ps -p $(cat /var/run/poll-${name}.pid) > /dev/null 2>&1; then\n INTERVAL=$(grep -oP 'INTERVAL=\\\\K[0-9]+' /usr/local/bin/poll-${name}-daemon.sh 2>/dev/null || echo \"10\")\n echo \"running:$INTERVAL:daemon\"\n else\n echo \"stopped\"\n fi\n `,\n\n // Update polling interval (supports both systemd and daemon modes)\n updatePollingInterval: (name: string, interval: number) => `\n TIMER_FILE=\"/etc/systemd/system/poll-${name}.timer\"\n DAEMON_FILE=\"/usr/local/bin/poll-${name}-daemon.sh\"\n \n if [ -f \"$TIMER_FILE\" ]; then\n # Systemd mode\n sed -i \"s/OnUnitActiveSec=[0-9]*s/OnUnitActiveSec=${interval}s/\" \"$TIMER_FILE\"\n systemctl daemon-reload\n systemctl restart poll-${name}.timer\n echo \"polling-interval-updated:${interval}:systemd\"\n elif [ -f \"$DAEMON_FILE\" ]; then\n # Daemon mode - update interval and restart (all as root)\n sudo sed -i \"s/INTERVAL=[0-9]*/INTERVAL=${interval}/\" \"$DAEMON_FILE\"\n \n # Restart daemon (use sudo bash -c for proper backgrounding)\n if [ -f /var/run/poll-${name}.pid ]; then\n sudo kill $(cat /var/run/poll-${name}.pid) 2>/dev/null || true\n sleep 1\n fi\n sudo bash -c 'nohup /usr/local/bin/poll-${name}-daemon.sh > /dev/null 2>&1 &'\n echo \"polling-interval-updated:${interval}:daemon\"\n else\n echo \"polling-not-configured\"\n fi\n `,\n\n // Enable polling (supports both systemd and daemon modes)\n enablePolling: (name: string, branch: string, user: string, interval: number) => `\n # Check if systemd is available\n if pidof systemd > /dev/null 2>&1 || [ \"$(cat /proc/1/comm 2>/dev/null)\" = \"systemd\" ]; then\n # SYSTEMD MODE\n if [ -f \"/etc/systemd/system/poll-${name}.timer\" ]; then\n systemctl enable poll-${name}.timer\n systemctl start poll-${name}.timer\n echo \"polling-enabled:systemd\"\n else\n # Create from scratch (same as app.tsx)\n cat << 'POLLING_EOF' > /usr/local/bin/poll-${name}.sh\n#!/bin/bash\nset -e\nAPP_DIR=\"/var/www/${name}\"\nBRANCH=\"${branch}\"\nUSER=\"${user}\"\nLOCK_FILE=\"/tmp/poll-${name}.lock\"\nexec 200>\"$LOCK_FILE\"\nflock -n 200 || exit 0\ncd \"$APP_DIR\"\nsudo -u $USER git fetch origin \"$BRANCH\" --quiet 2>/dev/null\nLOCAL=$(git rev-parse HEAD)\nREMOTE=$(git rev-parse \"origin/$BRANCH\")\nif [ \"$LOCAL\" != \"$REMOTE\" ]; then\n echo \"[$(date -Iseconds)] New commit detected: $REMOTE\"\n sudo /usr/local/bin/update-${name}\nelse\n echo \"[$(date -Iseconds)] No changes\"\nfi\nPOLLING_EOF\n chmod +x /usr/local/bin/poll-${name}.sh\n\n cat << SERVICE_EOF > /etc/systemd/system/poll-${name}.service\n[Unit]\nDescription=Git polling service for ${name}\nAfter=network.target\n[Service]\nType=oneshot\nExecStart=/usr/local/bin/poll-${name}.sh\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=poll-${name}\nSERVICE_EOF\n\n cat << TIMER_EOF > /etc/systemd/system/poll-${name}.timer\n[Unit]\nDescription=Run git polling for ${name} every ${interval} seconds\n[Timer]\nOnBootSec=30\nOnUnitActiveSec=${interval}s\nAccuracySec=1s\n[Install]\nWantedBy=timers.target\nTIMER_EOF\n\n systemctl daemon-reload\n systemctl enable poll-${name}.timer\n systemctl start poll-${name}.timer\n echo \"polling-created:systemd\"\n fi\n else\n # DAEMON MODE (Docker/non-systemd)\n if [ -f /var/run/poll-${name}.pid ] && kill -0 $(cat /var/run/poll-${name}.pid) 2>/dev/null; then\n echo \"polling-already-running:daemon\"\n else\n # Create poll script if not exists\n if [ ! -f /usr/local/bin/poll-${name}.sh ]; then\n cat << 'POLLING_EOF' > /usr/local/bin/poll-${name}.sh\n#!/bin/bash\nset -e\nAPP_DIR=\"/var/www/${name}\"\nBRANCH=\"${branch}\"\nUSER=\"${user}\"\nLOCK_FILE=\"/tmp/poll-${name}.lock\"\nexec 200>\"$LOCK_FILE\"\nflock -n 200 || exit 0\ncd \"$APP_DIR\"\nsudo -u $USER git fetch origin \"$BRANCH\" --quiet 2>/dev/null\nLOCAL=$(git rev-parse HEAD)\nREMOTE=$(git rev-parse \"origin/$BRANCH\")\nif [ \"$LOCAL\" != \"$REMOTE\" ]; then\n echo \"[$(date -Iseconds)] New commit detected: $REMOTE\"\n sudo /usr/local/bin/update-${name}\nelse\n echo \"[$(date -Iseconds)] No changes\"\nfi\nPOLLING_EOF\n chmod +x /usr/local/bin/poll-${name}.sh\n fi\n\n # Create daemon script\n cat << DAEMON_EOF > /usr/local/bin/poll-${name}-daemon.sh\n#!/bin/bash\nLOG_FILE=\"/var/log/poll-${name}.log\"\nPID_FILE=\"/var/run/poll-${name}.pid\"\nINTERVAL=${interval}\necho \\$\\$ > \"\\$PID_FILE\"\necho \"[\\$(date -Iseconds)] Polling daemon started (every ${interval}s)\" >> \"\\$LOG_FILE\"\nwhile true; do\n /usr/local/bin/poll-${name}.sh >> \"\\$LOG_FILE\" 2>&1\n sleep \\$INTERVAL\ndone\nDAEMON_EOF\n chmod +x /usr/local/bin/poll-${name}-daemon.sh\n\n mkdir -p /var/log\n touch /var/log/poll-${name}.log\n nohup /usr/local/bin/poll-${name}-daemon.sh > /dev/null 2>&1 &\n echo \"polling-created:daemon\"\n fi\n fi\n `,\n\n // Disable polling (supports both systemd and daemon modes)\n disablePolling: (name: string) => `\n # Stop systemd timer if exists\n systemctl stop poll-${name}.timer 2>/dev/null || true\n systemctl disable poll-${name}.timer 2>/dev/null || true\n rm -f /etc/systemd/system/poll-${name}.timer\n rm -f /etc/systemd/system/poll-${name}.service\n systemctl daemon-reload 2>/dev/null || true\n \n # Stop daemon if running (use sudo since daemon runs as root)\n if [ -f /var/run/poll-${name}.pid ]; then\n sudo kill $(cat /var/run/poll-${name}.pid) 2>/dev/null || true\n rm -f /var/run/poll-${name}.pid\n fi\n \n # Clean up all polling files\n rm -f /usr/local/bin/poll-${name}.sh\n rm -f /usr/local/bin/poll-${name}-daemon.sh\n \n echo \"polling-disabled\"\n `,\n // Update Log Settings\n updateLogSettings: (name: string, source: string, path: string) => `\n CONFIG_FILE=\"/var/www/${name}/.provisor.json\"\n if [ -f \"$CONFIG_FILE\" ]; then\n TMP_FILE=\"/tmp/.provisor.json.tmp\"\n # Use jq if available for safe editing, otherwise fallback to simple replacement or append\n # Since we don't assume jq, let's read the file in nodejs on the server to be safe\n \n cat << 'NODE_EOF' > /tmp/update-config-${name}.js\nconst fs = require('fs');\nconst config = JSON.parse(fs.readFileSync('$CONFIG_FILE', 'utf8'));\nif ('${source}') config.logSource = '${source}';\nif ('${path}') config.logPath = '${path}';\nfs.writeFileSync('$CONFIG_FILE', JSON.stringify(config));\nNODE_EOF\n\n node /tmp/update-config-${name}.js\n rm /tmp/update-config-${name}.js\n chmod 600 \"$CONFIG_FILE\"\n echo \"log-settings-updated\"\n else\n echo \"config-not-found\"\n fi\n `,\n};\n\nconst configActions = [\n { label: 'Show current configuration', value: 'show' },\n { label: 'Change repository URL', value: 'repo' },\n { label: 'Change deploy branch', value: 'branch' },\n { label: 'Generate new deploy key', value: 'new-key' },\n { label: 'Delete deploy key', value: 'delete-key' },\n { label: 'Update webhook secret', value: 'webhook-secret' },\n { label: 'Disable webhook', value: 'disable-webhook' },\n { label: 'Change polling interval', value: 'polling-interval' },\n { label: 'Enable git polling', value: 'enable-polling' },\n\n { label: 'Disable git polling', value: 'disable-polling' },\n { label: 'Change log source (pm2, file, systemd)', value: 'log-source' },\n { label: 'Set custom log path', value: 'log-path' },\n { label: '< Back', value: '__back__' },\n];\n\nexport function ConfigCommand(props: ConfigCommandProps) {\n const { exit } = useApp();\n const [client, setClient] = useState<Client | null>(null);\n const [status, setStatus] = useState<TaskStatus>('pending');\n const [error, setError] = useState<string | null>(null);\n const [output, setOutput] = useState<string[]>([]);\n\n // Selection states\n const [selectingAction, setSelectingAction] = useState(false);\n const [action, setAction] = useState<ConfigAction | null>(null);\n const [enteringValue, setEnteringValue] = useState(false);\n const [inputValue, setInputValue] = useState('');\n const [inputLabel, setInputLabel] = useState('');\n\n // Config data\n const [config, setConfig] = useState<AppConfig | null>(null);\n const [deployKey, setDeployKey] = useState<string | null>(null);\n const [webhookStatus, setWebhookStatus] = useState<string>('');\n const [pollingStatus, setPollingStatus] = useState<string>('');\n const [configLoaded, setConfigLoaded] = useState(false);\n\n // Determine initial action from props\n useEffect(() => {\n if (props.show) setAction('show');\n else if (props.repo) {\n setAction('repo');\n setInputValue(props.repo);\n }\n else if (props.branch) {\n setAction('branch');\n setInputValue(props.branch);\n }\n else if (props.newKey) setAction('new-key');\n else if (props.deleteKey) setAction('delete-key');\n else if (props.webhookSecret) {\n setAction('webhook-secret');\n setInputValue(props.webhookSecret);\n }\n else if (props.disableWebhook) setAction('disable-webhook');\n else if (props.pollingInterval) {\n setAction('polling-interval');\n setInputValue(String(props.pollingInterval));\n }\n else if (props.enablePolling) setAction('enable-polling');\n else if (props.enablePolling) setAction('enable-polling');\n else if (props.disablePolling) setAction('disable-polling');\n else if (props.logSource) {\n setAction('log-source');\n setInputValue(props.logSource);\n }\n else if (props.logPath) {\n setAction('log-path');\n setInputValue(props.logPath);\n }\n }, []);\n\n // Connect\n useEffect(() => {\n const run = async () => {\n setStatus('running');\n try {\n const sshClient = await connect(props);\n setClient(sshClient);\n setStatus('success');\n } catch (err) {\n setStatus('error');\n setError(`Connection failed: ${err instanceof Error ? err.message : err}`);\n }\n };\n run();\n }, []); // Only run once on mount for connection\n\n // Use a ref to track client for cleanup\n const clientRef = React.useRef<Client | null>(null);\n useEffect(() => {\n clientRef.current = client;\n return () => {\n if (clientRef.current) disconnect(clientRef.current);\n };\n }, [client]);\n\n useInput((input, key) => {\n if (key.escape) {\n if (enteringValue) {\n setEnteringValue(false);\n } else if (action && (output.length > 0 || error)) {\n // Back from Result View to Action List\n setAction(null);\n setOutput([]);\n setError(null);\n setInputValue('');\n setSelectingAction(true); // Explicitly show menu\n } else {\n // Go back to parent\n if (client) disconnect(client);\n if (props.onBack) props.onBack();\n else exit();\n }\n }\n });\n\n // Show action selection if no action determined\n useEffect(() => {\n if (status === 'success' && action === null && !selectingAction) {\n setSelectingAction(true);\n }\n }, [status, action]);\n\n const handleActionSelect = (item: { value: string }) => {\n setSelectingAction(false);\n const selectedAction = item.value as ConfigAction;\n setAction(selectedAction);\n\n // Some actions need input\n if (selectedAction === 'repo') {\n setInputLabel('Enter new repository URL:');\n setEnteringValue(true);\n } else if (selectedAction === 'branch') {\n setInputLabel('Enter new branch name:');\n setEnteringValue(true);\n } else if (selectedAction === 'webhook-secret') {\n setInputLabel('Enter new webhook secret:');\n setEnteringValue(true);\n } else if (selectedAction === 'polling-interval') {\n setInputLabel('Enter polling interval in seconds (e.g., 10, 30, 60):');\n setEnteringValue(true);\n } else if (selectedAction === 'log-source') {\n setInputLabel('Enter log source (pm2, file, or systemd):');\n setEnteringValue(true);\n } else if (selectedAction === 'log-path') {\n setEnteringValue(true);\n } else if (selectedAction === '__back__') {\n if (client) disconnect(client);\n if (props.onBack) props.onBack();\n else exit();\n }\n };\n\n const handleInputSubmit = (value: string) => {\n setInputValue(value);\n setEnteringValue(false);\n };\n\n // Execute action\n useEffect(() => {\n if (!client || action === null || enteringValue) return;\n if ((action === 'repo' || action === 'branch' || action === 'webhook-secret' || action === 'polling-interval' || action === 'log-source' || action === 'log-path') && !inputValue) return;\n\n const run = async () => {\n try {\n const user = props.user || 'deploy';\n const lines: string[] = [];\n\n switch (action) {\n case 'show': {\n const configResult = await exec(client, SCRIPTS.getConfig(props.name));\n const configData = JSON.parse(configResult.stdout.trim());\n\n if (configData.error) {\n setError(configData.error);\n return;\n }\n \n // Get footprint\n const footprintResult = await exec(client, SCRIPTS.getAppFootprint(props.name, user));\n let footprint: any = {};\n try {\n footprint = JSON.parse(footprintResult.stdout.trim());\n } catch (e) {\n console.error(\"Failed to parse footprint JSON\", footprintResult.stdout);\n }\n\n const keyResult = await exec(client, SCRIPTS.getDeployKey(props.name, user));\n const webhookResult = await exec(client, SCRIPTS.getWebhookStatus(props.name));\n const pollingResult = await exec(client, SCRIPTS.getPollingStatus(props.name));\n\n // STATUS SECTION\n lines.push('--- STATUS ---');\n const pm2Status = footprint.status?.pm2 === 'online' ? '🟢 Online' : '🔴 Offline';\n lines.push(`App (PM2): ${pm2Status}`);\n \n const whStatus = footprint.status?.webhook === 'active' ? '🟢 Active' : '⚫ Inactive';\n lines.push(`Webhook: ${whStatus}`);\n \n const plStatus = footprint.status?.polling === 'active' ? '🟢 Active' : '⚫ Inactive';\n lines.push(`Polling: ${plStatus}`);\n lines.push('');\n\n // CONFIG SECTION\n lines.push('--- CONFIGURATION ---');\n lines.push(`Repository: ${configData.repo || 'Not configured'}`);\n lines.push(`Branch: ${configData.branch || 'main'}`);\n lines.push(`Build Cmd: ${configData.buildCmd || 'npm run build'}`);\n lines.push(`Start Cmd: ${configData.startCmd || 'npm start'}`);\n lines.push(`Deploy Key: ${keyResult.stdout.trim() ? 'Configured' : 'Not configured'}`);\n \n lines.push(`Log Source: ${configData.logSource || 'pm2'}`);\n if (configData.logPath) {\n lines.push(`Log Path: ${configData.logPath}`);\n }\n\n // Webhook Details\n const webhookStatusStr = webhookResult.stdout.trim();\n if (webhookStatusStr.startsWith('running:')) {\n const port = webhookStatusStr.split(':')[1];\n lines.push(`Webhook Port: ${port}`);\n }\n\n // Polling Details\n const pollingStatusStr = pollingResult.stdout.trim();\n if (pollingStatusStr.startsWith('running:')) {\n const parts = pollingStatusStr.split(':');\n lines.push(`Polling Interval: ${parts[1]}s (${parts[2] || 'systemd'})`);\n }\n lines.push('');\n\n // FOOTPRINT SECTION\n lines.push('--- FOOTPRINT (Server Paths) ---');\n if (footprint.paths) {\n lines.push(`App Directory: ${footprint.paths.appDir}`);\n lines.push(`Config File: ${footprint.paths.config}`);\n lines.push(`Update Script: ${footprint.paths.updateScript}`);\n if (footprint.status?.webhook === 'active') {\n lines.push(`Webhook Service: ${footprint.paths.webhookService}`);\n }\n if (footprint.status?.polling === 'active') {\n lines.push(`Poll Script: ${footprint.paths.pollScript}`);\n lines.push(`Poll Service: ${footprint.paths.pollService}`);\n lines.push(`Poll Timer: ${footprint.paths.pollTimer}`);\n }\n }\n \n if (keyResult.stdout.trim()) {\n lines.push('');\n lines.push('--- PUBLIC KEY ---');\n lines.push(keyResult.stdout.trim());\n }\n break;\n }\n\n case 'repo': {\n await execScript(client, SCRIPTS.updateRepo(props.name, inputValue, user), true);\n lines.push(`Repository updated to: ${inputValue}`);\n break;\n }\n\n case 'branch': {\n await execScript(client, SCRIPTS.updateBranch(props.name, inputValue, user), true);\n lines.push(`Branch updated to: ${inputValue}`);\n lines.push('Run update command to deploy from new branch.');\n break;\n }\n\n case 'new-key': {\n const result = await execScript(client, SCRIPTS.generateNewKey(props.name, user), true);\n lines.push('New deploy key generated:');\n lines.push('');\n lines.push(result.stdout.trim());\n lines.push('');\n lines.push('Add this key to your repository settings.');\n lines.push('Remember to remove the old key if it was configured.');\n break;\n }\n\n case 'delete-key': {\n const result = await execScript(client, SCRIPTS.deleteDeployKey(props.name, user), true);\n if (result.stdout.includes('key-deleted')) {\n lines.push('Deploy key deleted successfully.');\n lines.push('Remember to remove it from your repository settings too.');\n } else {\n lines.push('No deploy key found for this app.');\n }\n break;\n }\n\n case 'webhook-secret': {\n const result = await execScript(client, SCRIPTS.updateWebhookSecret(props.name, inputValue), true);\n if (result.stdout.includes('webhook-secret-updated')) {\n lines.push('Webhook secret updated.');\n lines.push('Update the secret in your repository webhook settings too.');\n } else {\n lines.push('Webhook not configured for this app.');\n }\n break;\n }\n\n case 'disable-webhook': {\n await execScript(client, SCRIPTS.disableWebhook(props.name), true);\n lines.push('Webhook disabled.');\n break;\n }\n\n case 'polling-interval': {\n const interval = parseInt(inputValue, 10);\n if (isNaN(interval) || interval < 1) {\n setError('Invalid interval. Please enter a number >= 1.');\n return;\n }\n const result = await execScript(client, SCRIPTS.updatePollingInterval(props.name, interval), true);\n if (result.stdout.includes('polling-interval-updated')) {\n lines.push(`Polling interval updated to ${interval} seconds.`);\n } else {\n lines.push('Git polling not configured for this app.');\n lines.push('Use \"Enable git polling\" to set it up first.');\n }\n break;\n }\n\n case 'enable-polling': {\n // Get current branch from config\n const configResult = await exec(client, SCRIPTS.getConfig(props.name));\n const configData = JSON.parse(configResult.stdout.trim());\n const branch = configData.branch || 'main';\n const interval = 10; // Default interval\n\n const result = await execScript(client, SCRIPTS.enablePolling(props.name, branch, user, interval), true);\n if (result.stdout.includes('polling-enabled')) {\n lines.push('Git polling re-enabled.');\n lines.push(`Checking for updates every ${interval} seconds.`);\n } else if (result.stdout.includes('polling-created')) {\n lines.push('Git polling enabled.');\n lines.push(`Checking for updates every ${interval} seconds.`);\n }\n lines.push('');\n lines.push(`View logs: journalctl -u poll-${props.name} -f`);\n break;\n }\n\n case 'disable-polling': {\n await execScript(client, SCRIPTS.disablePolling(props.name), true);\n lines.push('Git polling disabled.');\n break;\n }\n\n case 'log-source': {\n if (!['pm2', 'file', 'systemd'].includes(inputValue)) {\n setError('Invalid source. Must be pm2, file, or systemd.');\n return;\n }\n await execScript(client, SCRIPTS.updateLogSettings(props.name, inputValue, ''), true);\n lines.push(`Log source updated to: ${inputValue}`);\n break;\n }\n\n case 'log-path': {\n await execScript(client, SCRIPTS.updateLogSettings(props.name, '', inputValue), true);\n lines.push(`Log path updated to: ${inputValue}`);\n break;\n }\n }\n \n\n \n setOutput(lines);\n // Do NOT disconnect or exit here to allow further actions\n } catch (err) {\n setError(`Operation failed: ${err instanceof Error ? err.message : err}`);\n // Keep connection alive even on error\n }\n };\n run();\n }, [client, action, inputValue, enteringValue]);\n // Fetch initial config for menu context\n useEffect(() => {\n if (!client || configLoaded) return;\n const fetchConfig = async () => {\n try {\n const user = props.user || 'deploy';\n // Parallel fetch for speed\n const [cfgRes, keyRes, whRes, pollRes] = await Promise.all([\n exec(client, SCRIPTS.getConfig(props.name)),\n exec(client, SCRIPTS.getDeployKey(props.name, user)),\n exec(client, SCRIPTS.getWebhookStatus(props.name)),\n exec(client, SCRIPTS.getPollingStatus(props.name))\n ]);\n \n try {\n const cfgData = JSON.parse(cfgRes.stdout.trim());\n // Even if it returns error, we save it so we know we tried\n setConfig(cfgData);\n } catch (e) {\n // Fallback for parsing error\n setConfig({} as any);\n }\n\n setDeployKey(keyRes.stdout.trim());\n setWebhookStatus(whRes.stdout.trim());\n setPollingStatus(pollRes.stdout.trim());\n setConfigLoaded(true);\n } catch (e) {\n // If fetch fails, we just don't show context in menu\n setConfigLoaded(true);\n }\n };\n fetchConfig();\n }, [client]);\n\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"App Configuration\" subtitle={`App: ${props.name} | Host: ${props.host}`} />\n\n <Task label=\"Connect to server\" status={status} />\n\n {status === 'success' && !configLoaded && (\n <Task label=\"Fetching current configuration\" status=\"running\" />\n )}\n\n {selectingAction && action === null && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>Select action:</Text>\n <SelectInput \n key={configLoaded ? 'loaded' : 'loading'}\n items={configActions.map(item => {\n if (!configLoaded) return item;\n \n let label = item.label;\n const c = config || {} as any;\n\n if (item.value === 'repo' && c.repo) label += ` (current: ${c.repo})`;\n else if (item.value === 'branch' && c.branch) label += ` (current: ${c.branch})`;\n else if (item.value === 'polling-interval' && pollingStatus.startsWith('running:')) {\n const interval = pollingStatus.split(':')[1];\n label += ` (current: ${interval}s)`;\n }\n else if (item.value === 'log-source' && c.logSource) label += ` (current: ${c.logSource})`;\n else if (item.value === 'delete-key' && !deployKey) return null; // Hide if no key\n else if (item.value === 'new-key' && deployKey) label = 'Regenerate deploy key';\n \n return { ...item, label };\n }).filter(Boolean) as any} \n onSelect={handleActionSelect} \n />\n </Box>\n )}\n\n {enteringValue && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold>{inputLabel}</Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={inputValue} onChange={setInputValue} onSubmit={handleInputSubmit} />\n </Box>\n </Box>\n )}\n\n {output.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n {output.map((line, i) => (\n <Text key={i} color={line.startsWith('ssh-') ? 'cyan' : 'white'}>{line}</Text>\n ))}\n <Box marginTop={1}>\n <Text color=\"gray\">Press Esc to go back</Text>\n </Box>\n </Box>\n )}\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","/**\n * Update Command Component\n * \n * Ink/React component for the `provisor update` command.\n * Checks for updates and allows the user to update the CLI.\n * \n * Status: Active\n */\n\nimport React, { useState, useEffect } from 'react'\nimport { Box, Text } from 'ink'\nimport Spinner from 'ink-spinner'\nimport SelectInput from 'ink-select-input'\nimport { \n checkForUpdate, \n performUpdate, \n type UpdateInfo \n} from '../utils/update-checker.js'\n\ninterface UpdateCommandProps {\n check?: boolean\n}\n\ntype Stage = 'checking' | 'show-result' | 'confirm' | 'updating' | 'done' | 'error'\n\nexport function UpdateCommand({ check = false }: UpdateCommandProps) {\n const [stage, setStage] = useState<Stage>('checking')\n const [updateInfo, setUpdateInfo] = useState<UpdateInfo | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [resultMessage, setResultMessage] = useState<string>('')\n\n // Check for updates on mount\n useEffect(() => {\n async function doCheck() {\n try {\n const info = await checkForUpdate()\n setUpdateInfo(info)\n \n if (check || !info.updateAvailable) {\n // Just show the result, don't prompt\n setStage('show-result')\n } else {\n // Prompt user to confirm update\n setStage('confirm')\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to check for updates')\n setStage('error')\n }\n }\n doCheck()\n }, [check])\n\n // Handle update confirmation\n const handleConfirm = (item: { value: string }) => {\n if (item.value === 'yes') {\n setStage('updating')\n \n // Perform update in next tick to allow UI to update\n setTimeout(() => {\n const result = performUpdate()\n setResultMessage(result.message)\n setStage(result.success ? 'done' : 'error')\n }, 100)\n } else {\n setResultMessage('Update cancelled.')\n setStage('done')\n }\n }\n\n // Render based on stage\n if (stage === 'checking') {\n return (\n <Box>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Checking for updates...</Text>\n </Box>\n )\n }\n\n if (stage === 'error') {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"red\">✗ Error: {error || resultMessage}</Text>\n </Box>\n )\n }\n\n if (stage === 'show-result' && updateInfo) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text>Current version: </Text>\n <Text color=\"cyan\">{updateInfo.currentVersion}</Text>\n </Box>\n <Box>\n <Text>Latest version: </Text>\n <Text color={updateInfo.updateAvailable ? 'green' : 'cyan'}>\n {updateInfo.latestVersion}\n </Text>\n </Box>\n {updateInfo.updateAvailable ? (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"yellow\">⚡ A new version is available!</Text>\n <Text color=\"gray\">Run `provisor update` to install.</Text>\n {updateInfo.releaseUrl && (\n <Text color=\"gray\">Release notes: {updateInfo.releaseUrl}</Text>\n )}\n </Box>\n ) : (\n <Box marginTop={1}>\n <Text color=\"green\">✓ You are using the latest version.</Text>\n </Box>\n )}\n </Box>\n )\n }\n\n if (stage === 'confirm' && updateInfo) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"yellow\">⚡ Update available: </Text>\n <Text>{updateInfo.currentVersion}</Text>\n <Text color=\"gray\"> → </Text>\n <Text color=\"green\">{updateInfo.latestVersion}</Text>\n </Box>\n {updateInfo.releaseUrl && (\n <Text color=\"gray\">Release notes: {updateInfo.releaseUrl}</Text>\n )}\n <Box marginTop={1}>\n <Text>Install update? </Text>\n </Box>\n <SelectInput\n items={[\n { label: 'Yes, update now', value: 'yes' },\n { label: 'No, cancel', value: 'no' }\n ]}\n onSelect={handleConfirm}\n />\n </Box>\n )\n }\n\n if (stage === 'updating') {\n return (\n <Box>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Installing update...</Text>\n </Box>\n )\n }\n\n if (stage === 'done') {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"green\">✓ {resultMessage}</Text>\n {updateInfo?.updateAvailable && resultMessage.includes('successfully') && (\n <Text color=\"gray\">Run `provisor --version` to verify.</Text>\n )}\n </Box>\n )\n }\n\n return null\n}\n","/**\n * Update Checker Utility\n * \n * Checks for new versions of the CLI on npm registry and provides\n * update functionality.\n * \n * Status: Active\n * Usage: Import functions to check/perform updates\n */\n\nimport { execSync } from 'child_process'\nimport packageJson from '../../package.json' with { type: 'json' };\n\nconst PACKAGE_NAME = '@it-club/provisor'\n\nexport interface UpdateInfo {\n currentVersion: string\n latestVersion: string\n updateAvailable: boolean\n releaseUrl?: string\n}\n\n/**\n * Get the current version from the installed package\n */\nexport function getCurrentVersion(): string {\n return packageJson.version\n}\n\n/**\n * Fetch the latest version from npm registry\n */\nexport async function getLatestVersion(): Promise<string> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`)\n if (!response.ok) {\n throw new Error(`Failed to fetch: ${response.status}`)\n }\n const data = await response.json() as { version: string }\n return data.version\n } catch (error) {\n throw new Error(`Failed to check npm registry: ${error instanceof Error ? error.message : 'Unknown error'}`)\n }\n}\n\n/**\n * Compare two semantic versions\n * Returns: 1 if v1 > v2, -1 if v1 < v2, 0 if equal\n */\nexport function compareVersions(v1: string, v2: string): number {\n const parts1 = v1.replace(/^v/, '').split('.').map(Number)\n const parts2 = v2.replace(/^v/, '').split('.').map(Number)\n \n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const p1 = parts1[i] || 0\n const p2 = parts2[i] || 0\n if (p1 > p2) return 1\n if (p1 < p2) return -1\n }\n return 0\n}\n\n/**\n * Check if an update is available\n */\nexport async function checkForUpdate(): Promise<UpdateInfo> {\n const currentVersion = getCurrentVersion()\n const latestVersion = await getLatestVersion()\n const updateAvailable = compareVersions(latestVersion, currentVersion) > 0\n \n return {\n currentVersion,\n latestVersion,\n updateAvailable,\n releaseUrl: updateAvailable \n ? `https://github.com/it-club/provisor/releases/tag/v${latestVersion}`\n : undefined\n }\n}\n\n/**\n * Perform the update via npm\n */\nexport function performUpdate(): { success: boolean; message: string } {\n try {\n // Update globally via npm\n execSync(`npm install -g ${PACKAGE_NAME}@latest`, { \n stdio: 'pipe',\n encoding: 'utf-8'\n })\n return { success: true, message: 'Update completed successfully!' }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n return { success: false, message: `Update failed: ${message}` }\n }\n}\n\n/**\n * Get the currently installed global version (for verification)\n */\nexport function getInstalledGlobalVersion(): string | null {\n try {\n const output = execSync(`npm list -g ${PACKAGE_NAME} --json`, {\n stdio: 'pipe',\n encoding: 'utf-8'\n })\n const data = JSON.parse(output)\n return data.dependencies?.[PACKAGE_NAME]?.version || null\n } catch {\n return null\n }\n}\n","{\n \"name\": \"@it-club/provisor\",\n \"version\": \"0.3.0\",\n \"description\": \"Server provisioning and deployment CLI tool\",\n \"type\": \"module\",\n \"bin\": {\n \"provisor\": \"dist/cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/it-club/provisor.git\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/cli.js\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"keywords\": [\n \"cli\",\n \"server\",\n \"provisioning\",\n \"deployment\",\n \"ssh\"\n ],\n \"author\": \"\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"commander\": \"^14.0.3\",\n \"ink\": \"^6.6.0\",\n \"ink-select-input\": \"^6.2.0\",\n \"ink-spinner\": \"^5.0.0\",\n \"ink-text-input\": \"^6.0.0\",\n \"react\": \"^19.2.4\",\n \"ssh2\": \"^1.17.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.2.0\",\n \"@types/react\": \"^19.2.10\",\n \"@types/ssh2\": \"^1.15.5\",\n \"ink-testing-library\": \"^4.0.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.9.3\"\n }\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp, useInput, useStdin } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport Spinner from 'ink-spinner';\nimport { Header } from '../components/index.js';\nimport { connect, execStream, exec, disconnect, type SSHOptions } from '../utils/ssh.js';\nimport type { Client } from 'ssh2';\n\ninterface LogsCommandProps extends SSHOptions {\n name?: string;\n onBack?: () => void;\n}\n\ntype LogType = 'app' | 'caddy' | 'audit' | 'build';\n\nconst LOG_OPTIONS = [\n { label: 'Application Logs (PM2)', value: 'app' },\n { label: 'Build/Deploy Logs', value: 'build' },\n { label: 'Web Server Logs (Caddy)', value: 'caddy' },\n { label: 'Git Polling Audit Logs', value: 'audit' },\n];\n\nexport function LogsCommand(props: LogsCommandProps) {\n const { exit } = useApp();\n const { isRawModeSupported } = useStdin();\n const [client, setClient] = useState<Client | null>(null);\n const [connecting, setConnecting] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [logType, setLogType] = useState<string | null>(null);\n const [logs, setLogs] = useState<string[]>([]);\n\n const [appName, setAppName] = useState(props.name || '');\n const [config, setConfig] = useState<any>(null);\n\n // Handle Ctrl+C to exit streaming\n useInput((input, key) => {\n if (key.escape || (key.ctrl && input === 'c')) {\n if (logType) {\n // Stop streaming\n if (client) disconnect(client);\n // If we were streaming, maybe just go back to log selection?\n // But for now let's go back to main/dashboard\n if (props.onBack) {\n props.onBack();\n } else {\n exit();\n }\n } else {\n if (client) disconnect(client);\n if (props.onBack) {\n props.onBack();\n } else {\n exit();\n }\n }\n }\n });\n\n useEffect(() => {\n const connectSSH = async () => {\n try {\n const sshClient = await connect(props);\n setClient(sshClient);\n\n // Fetch config\n if (props.name) {\n const configCmd = `\n if [ -f \"/var/www/${props.name}/.provisor.json\" ]; then\n cat \"/var/www/${props.name}/.provisor.json\"\n else\n echo \"{}\"\n fi\n `;\n const result = await exec(sshClient, configCmd);\n try {\n setConfig(JSON.parse(result.stdout.trim()));\n } catch (e) {\n setConfig({});\n }\n }\n\n setConnecting(false);\n } catch (err) {\n setError(`Connection failed: ${err instanceof Error ? err.message : err}`);\n setConnecting(false);\n }\n };\n connectSSH();\n\n return () => {\n if (client) disconnect(client);\n };\n }, []);\n\n const handleSelect = (item: { value: string }) => {\n setLogType(item.value);\n startStreaming(item.value);\n };\n\n const startStreaming = async (type: string) => {\n if (!client) return;\n setLogs(['Connecting to log stream...']);\n\n let command = '';\n const user = props.user || 'deploy';\n const home = user === 'root' ? '/root' : `/home/${user}`;\n\n switch (type) {\n case 'app':\n // Check config for log source\n const source = config?.logSource || 'pm2';\n const path = config?.logPath;\n\n if (source === 'file' && path) {\n command = `tail -f ${path}`;\n } else if (source === 'systemd' && path) {\n command = `sudo journalctl -u ${path} -f -n 50`;\n } else {\n // Default to PM2\n // Try to find PM2 logs\n // PM2 logs are usually in ~/.pm2/logs\n // We'll tail both out and error logs\n command = `tail -f ${home}/.pm2/logs/${appName}-out.log ${home}/.pm2/logs/${appName}-error.log`;\n }\n break;\n case 'caddy':\n // journalctl is best for Caddy\n command = 'sudo journalctl -u caddy -f -n 50';\n break;\n case 'audit':\n // Polling logs\n // Could be in /var/log/poll-app.log (daemon) or journalctl (systemd)\n // We'll try both\n command = `\n if [ -f \"/var/log/poll-${appName}.log\" ]; then\n tail -f \"/var/log/poll-${appName}.log\"\n else\n sudo journalctl -u poll-${appName} -f -n 50\n fi\n `;\n break;\n case 'build':\n // No specific build log file yet, but we can check if there's a way to capture it\n // For now, let's just say we don't store build logs persistently yet\n // But maybe we can tail the pm2 logs as they might contain startup info\n setLogs(['Build logs are only available during deployment currently.']);\n return;\n }\n\n try {\n await execStream(\n client,\n command,\n (data) => setLogs((prev) => [...prev, ...data.split('\\n')].slice(-50)), // Keep last 50 lines\n (data) => setLogs((prev) => [...prev, ...data.split('\\n')].slice(-50))\n );\n } catch (err) {\n // Stream ended or error\n // setError(`Log stream ended: ${err}`);\n }\n };\n\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header title=\"Server Logs\" />\n <Text color=\"red\">Error: {error}</Text>\n </Box>\n );\n }\n\n if (connecting) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header title=\"Server Logs\" />\n <Text>\n <Spinner type=\"dots\" /> Connecting to server...\n </Text>\n </Box>\n );\n }\n\n // If no app name provided, we should ask for it or list apps (future improvement)\n // For now we assume if props.name is missing, we can't proceed efficiently without refactor\n // But wait, user passed -n argument usually.\n if (!appName) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header title=\"Server Logs\" />\n <Text color=\"red\">App name is required. Use -n <app></Text>\n </Box>\n )\n }\n\n if (!logType) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header title={`Logs: ${appName}`} />\n <Text>Select log to view:</Text>\n <Box marginTop={1}>\n <SelectInput items={LOG_OPTIONS} onSelect={handleSelect} />\n </Box>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header title={`Logs: ${appName} (${logType})`} />\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n padding={1}\n height={20}\n >\n {logs.map((line, i) => (\n <Text key={i} wrap=\"wrap\">\n {line}\n </Text>\n ))}\n </Box>\n <Text color=\"gray\">Press Ctrl+C to exit</Text>\n </Box>\n );\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport type { SSHOptions } from './ssh.js';\nimport type { DiscoveredApp } from './scan.js';\n\nconst CONFIG_DIR = path.join(os.homedir(), '.provisor');\nconst CONFIG_FILE = path.join(CONFIG_DIR, 'servers.json');\n\nexport interface ServerConfig {\n host: string;\n user: string;\n port?: number;\n keyPath?: string;\n apps?: DiscoveredApp[];\n}\n\ninterface Servers {\n [alias: string]: ServerConfig;\n}\n\nfunction ensureConfigDir() {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nfunction loadServers(): Servers {\n if (!fs.existsSync(CONFIG_FILE)) {\n return {};\n }\n try {\n return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));\n } catch (err) {\n return {};\n }\n}\n\nfunction saveServers(servers: Servers) {\n ensureConfigDir();\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(servers, null, 2));\n}\n\nexport const ServerManager = {\n addServer: (alias: string, config: ServerConfig) => {\n const servers = loadServers();\n servers[alias] = config;\n saveServers(servers);\n },\n\n removeServer: (alias: string) => {\n const servers = loadServers();\n delete servers[alias];\n saveServers(servers);\n },\n\n getServer: (alias: string): ServerConfig | null => {\n const servers = loadServers();\n return servers[alias] || null;\n },\n\n getApps: (alias: string): DiscoveredApp[] | null => {\n const servers = loadServers();\n return servers[alias]?.apps || null;\n },\n\n updateApps: (alias: string, apps: DiscoveredApp[]) => {\n const servers = loadServers();\n if (servers[alias]) {\n servers[alias].apps = apps;\n saveServers(servers);\n }\n },\n\n listServers: (): Servers => {\n return loadServers();\n }\n};\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport TextInput from 'ink-text-input';\nimport { Layout } from '../components/index.js';\nimport { ServerManager, type ServerConfig } from '../utils/server.js';\n\nimport { CaddyCommand } from './caddy.js';\n\ninterface ServerCommandProps {\n action?: 'list' | 'add' | 'remove';\n alias?: string;\n host?: string;\n user?: string;\n}\n\nexport function ServerCommand(props: ServerCommandProps) {\n const { exit } = useApp();\n const [mode, setMode] = useState<'list' | 'add-alias' | 'add-host' | 'add-user' | 'remove' | 'actions' | 'caddy'>(\n props.action === 'add' ? 'add-alias' : props.action === 'remove' ? 'remove' : 'list'\n );\n\n // Selected server for actions\n const [selectedServer, setSelectedServer] = useState<string | null>(null);\n \n // Add State\n const [newAlias, setNewAlias] = useState(props.alias || '');\n const [newHost, setNewHost] = useState(props.host || '');\n const [newUser, setNewUser] = useState(props.user || 'root');\n \n // List State\n const [servers, setServers] = useState<Record<string, ServerConfig>>({});\n \n useEffect(() => {\n setServers(ServerManager.listServers());\n }, []);\n\n useEffect(() => {\n if (props.action === 'add' && props.alias && props.host) {\n // DirectCLI add\n ServerManager.addServer(props.alias, { \n host: props.host, \n user: props.user || 'root' \n });\n console.log(`Server '${props.alias}' added.`);\n exit();\n }\n }, []);\n\n const handleAliasSubmit = (value: string) => {\n if (!value) return;\n setNewAlias(value);\n setMode('add-host');\n };\n\n const handleHostSubmit = (value: string) => {\n if (!value) return;\n setNewHost(value);\n setMode('add-user');\n };\n\n const handleUserSubmit = (value: string) => {\n const user = value || 'root';\n ServerManager.addServer(newAlias, { host: newHost, user });\n setServers(ServerManager.listServers());\n setMode('list');\n };\n\n const handleRemoveSelect = (item: { value: string }) => {\n ServerManager.removeServer(item.value);\n setServers(ServerManager.listServers());\n setMode('list');\n };\n\n if (mode === 'list') {\n const listItems = Object.entries(servers).map(([alias, config]) => ({\n label: `${alias} (${config.user}@${config.host})`,\n value: alias\n }));\n\n const options = [\n { label: '+ Add New Server', value: '__add__' },\n ...(listItems.length > 0 ? [{ label: '- Remove Server', value: '__remove__' }] : []),\n ...listItems\n ];\n\n return (\n <Layout \n title=\"Saved Servers\" \n footerStatus=\"Use Enter to Select, Arrows to Move\"\n footerTips={['Select a server to view options']}\n >\n <Box marginTop={1}>\n <SelectInput \n items={options} \n onSelect={(item) => {\n if (item.value === '__add__') setMode('add-alias');\n else if (item.value === '__remove__') setMode('remove');\n else {\n setSelectedServer(item.value);\n setMode('actions');\n }\n }} \n />\n </Box>\n </Layout>\n );\n }\n\n if (mode === 'actions' && selectedServer) {\n const config = servers[selectedServer];\n \n const actionItems = [\n { label: 'Manage Caddy Configuration', value: 'caddy' },\n { label: '< Back', value: '__back__' }\n ];\n\n return (\n <Layout title={`Server: ${selectedServer}`}>\n <SelectInput\n items={actionItems}\n onSelect={(item) => {\n if (item.value === '__back__') {\n setMode('list');\n setSelectedServer(null);\n }\n if (item.value === 'caddy') {\n setMode('caddy');\n }\n }}\n />\n </Layout>\n );\n }\n \n if (mode === 'caddy' && selectedServer) {\n const config = servers[selectedServer];\n // We render CaddyCommand but we need to intercept exit to go back to menu?\n // CaddyCommand calls exit() which exits the app.\n // Ideally CaddyCommand explicitly accepts an onBack prop, but for now let's just render it.\n // If CaddyCommand exits the app, that's fine for now as per CLI behavior.\n return <CaddyCommand host={config.host} user={config.user} key={config.keyPath} />;\n }\n\n if (mode === 'remove') {\n const listItems = Object.entries(servers).map(([alias, config]) => ({\n label: `Remove ${alias} (${config.host})`,\n value: alias\n }));\n\n return (\n <Layout title=\"Remove Server\" footerStatus=\"Removing Server\">\n <Text>Select server to remove:</Text>\n <Box marginTop={1}>\n <SelectInput \n items={[...listItems, { label: '< Back', value: '__back__' }]} \n onSelect={(item) => {\n if (item.value === '__back__') setMode('list');\n else handleRemoveSelect(item);\n }} \n />\n </Box>\n </Layout>\n );\n }\n\n return (\n <Layout title=\"Add Server\" footerStatus={mode === 'add-alias' ? \"Enter Alias\" : mode === 'add-host' ? \"Enter Host IP\" : \"Enter SSH User\"}>\n \n {mode === 'add-alias' && (\n <Box flexDirection=\"column\">\n <Text>Enter server alias (e.g. production):</Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={newAlias} onChange={setNewAlias} onSubmit={handleAliasSubmit} />\n </Box>\n </Box>\n )}\n\n {mode === 'add-host' && (\n <Box flexDirection=\"column\">\n <Text>Enter IP address or hostname:</Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={newHost} onChange={setNewHost} onSubmit={handleHostSubmit} />\n </Box>\n </Box>\n )}\n\n {mode === 'add-user' && (\n <Box flexDirection=\"column\">\n <Text>Enter SSH user (default: root):</Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput value={newUser} onChange={setNewUser} onSubmit={handleUserSubmit} />\n </Box>\n </Box>\n )}\n </Layout>\n );\n}\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useApp, useInput } from 'ink'\nimport SelectInput from 'ink-select-input'\nimport Spinner from 'ink-spinner'\nimport { Header, Task, type TaskStatus } from '../components/index.js'\nimport { connect, exec, execScript, disconnect, type SSHOptions } from '../utils/ssh.js'\nimport type { Client } from 'ssh2'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { spawn } from 'child_process'\n\ninterface CaddyCommandProps extends SSHOptions {\n onBack?: () => void\n}\n\ntype CaddyMode = 'menu' | 'view' | 'edit' | 'saving' | 'logs' | 'restarting'\n\nexport function CaddyCommand(props: CaddyCommandProps) {\n const { exit } = useApp()\n const [client, setClient] = useState<Client | null>(null)\n const [connectStatus, setConnectStatus] = useState<TaskStatus>('pending')\n const [error, setError] = useState<string | null>(null)\n const [mode, setMode] = useState<CaddyMode>('menu')\n const [caddyContent, setCaddyContent] = useState<string>('')\n const [logsContent, setLogsContent] = useState<string>('')\n const [saveStatus, setSaveStatus] = useState<string>('')\n const [restartStatus, setRestartStatus] = useState<TaskStatus>('pending')\n const [restartMessage, setRestartMessage] = useState<string>('')\n\n const goBack = () => {\n if (client) disconnect(client)\n if (props.onBack) {\n props.onBack()\n } else {\n exit()\n }\n }\n\n // Items for the main menu\n const items = [\n { label: 'View Configuration', value: 'view' },\n { label: 'Edit Configuration', value: 'edit' },\n { label: 'View Logs', value: 'logs' },\n { label: 'Restart Caddy', value: 'restart' },\n { label: '< Back', value: 'cancel' },\n ]\n\n // Connect to server on mount\n useEffect(() => {\n const run = async () => {\n setConnectStatus('running')\n try {\n const sshClient = await connect(props)\n setClient(sshClient)\n setConnectStatus('success')\n } catch (err) {\n setConnectStatus('error')\n setError(`Connection failed: ${err instanceof Error ? err.message : err}`)\n }\n }\n run()\n\n return () => {\n if (client) disconnect(client)\n }\n }, [])\n\n const handleSelect = async (item: { value: string }) => {\n if (item.value === 'cancel') {\n goBack()\n return\n }\n\n if (!client) return\n\n if (item.value === 'view') {\n setMode('view')\n try {\n const result = await exec(client, 'cat /etc/caddy/Caddyfile')\n setCaddyContent(result.stdout)\n } catch (err) {\n setError(`Failed to read Caddyfile: ${err}`)\n }\n }\n\n if (item.value === 'logs') {\n setMode('logs')\n try {\n const result = await exec(client, 'journalctl -u caddy --no-pager -n 50 2>/dev/null || echo \"No logs available\"')\n setLogsContent(result.stdout)\n } catch (err) {\n setError(`Failed to read logs: ${err}`)\n }\n }\n\n if (item.value === 'restart') {\n setMode('restarting')\n setRestartStatus('running')\n setRestartMessage('Restarting Caddy service...')\n try {\n await exec(client, 'sudo systemctl restart caddy')\n setRestartStatus('success')\n setRestartMessage('Caddy restarted successfully!')\n \n // Check port status after restart\n const ports = await exec(client, 'ss -tlnp 2>/dev/null | grep -E \":(80|443)\" || echo \"none\"')\n const output = ports.stdout.trim()\n const has443 = output.includes(':443')\n const has80 = output.includes(':80')\n \n if (has80 && has443) {\n setRestartMessage('Caddy restarted! Ports 80 & 443 now listening.')\n } else if (has80) {\n setRestartMessage('Caddy restarted! Port 80 listening. Port 443 may need a request to activate.')\n } else {\n setRestartMessage('Caddy restarted but no ports detected. Check logs.')\n }\n } catch (err) {\n setRestartStatus('error')\n setRestartMessage(`Failed to restart: ${err instanceof Error ? err.message : err}`)\n }\n }\n\n if (item.value === 'edit') {\n setMode('edit')\n try {\n // 1. Fetch content\n const result = await exec(client, 'cat /etc/caddy/Caddyfile')\n const currentContent = result.stdout\n \n // 2. Write to temp file\n const tempFile = path.join(os.tmpdir(), `Caddyfile-${Date.now()}`)\n fs.writeFileSync(tempFile, currentContent)\n\n const editor = process.env.EDITOR || 'nano'\n \n const child = spawn(editor, [tempFile], {\n stdio: 'inherit'\n })\n\n child.on('exit', async (code) => {\n if (code === 0) {\n setMode('saving')\n setSaveStatus('Reading changes...')\n const newContent = fs.readFileSync(tempFile, 'utf-8')\n \n if (newContent !== currentContent) {\n setSaveStatus('Uploading changes...')\n const b64 = Buffer.from(newContent).toString('base64')\n const writeCmd = `echo \"${b64}\" | base64 -d > /etc/caddy/Caddyfile`\n \n await exec(client, writeCmd)\n \n setSaveStatus('Reloading Caddy...')\n await exec(client, 'caddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy')\n \n setSaveStatus('Success! Caddy reloaded.')\n setTimeout(() => {\n setMode('view')\n setCaddyContent(newContent)\n setSaveStatus('')\n }, 1500)\n } else {\n setSaveStatus('No changes made.')\n setTimeout(() => {\n setMode('view')\n setCaddyContent(currentContent)\n setSaveStatus('')\n }, 1500)\n }\n \n fs.unlinkSync(tempFile)\n } else {\n setError('Editor exited with error code ' + code)\n setMode('menu')\n }\n })\n\n } catch (err) {\n setError(`Failed to edit: ${err}`)\n }\n }\n }\n\n useInput((input, key) => {\n if (mode === 'view' || mode === 'logs' || (mode === 'restarting' && (restartStatus === 'success' || restartStatus === 'error'))) {\n if (key.escape || input === 'q') {\n setMode('menu')\n setCaddyContent('')\n setLogsContent('')\n setRestartStatus('pending')\n setRestartMessage('')\n }\n }\n })\n\n if (error) {\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Caddy Configuration\" />\n <Text color=\"red\">Error: {error}</Text>\n <Box marginTop={1}>\n <Text color=\"gray\">Press 'q' or Esc to go back</Text>\n </Box>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Caddy Configuration\" />\n \n <Task label=\"Connect to server\" status={connectStatus} />\n\n {connectStatus === 'success' && (\n <Box flexDirection=\"column\" marginTop={1}>\n {mode === 'menu' && (\n <>\n <Text>Select an action:</Text>\n <SelectInput items={items} onSelect={handleSelect} />\n </>\n )}\n\n {mode === 'view' && (\n <Box flexDirection=\"column\">\n <Text color=\"green\">Current Configuration (/etc/caddy/Caddyfile):</Text>\n <Box borderStyle=\"single\" padding={1} borderColor=\"gray\">\n {caddyContent ? (\n <Text>{caddyContent}</Text>\n ) : (\n <Box>\n <Text color=\"green\"><Spinner type=\"dots\" /> Loading...</Text>\n </Box>\n )}\n </Box>\n <Text color=\"gray\">Press 'q' or Esc to go back</Text>\n </Box>\n )}\n\n {mode === 'logs' && (\n <Box flexDirection=\"column\">\n <Text color=\"green\">Caddy Logs (last 50 lines):</Text>\n <Box borderStyle=\"single\" padding={1} borderColor=\"gray\" flexDirection=\"column\">\n {logsContent ? (\n <Text>{logsContent}</Text>\n ) : (\n <Box>\n <Text color=\"green\"><Spinner type=\"dots\" /> Loading...</Text>\n </Box>\n )}\n </Box>\n <Text color=\"gray\">Press 'q' or Esc to go back</Text>\n </Box>\n )}\n\n {mode === 'restarting' && (\n <Box flexDirection=\"column\">\n <Task label=\"Restart Caddy\" status={restartStatus} message={restartMessage} />\n {(restartStatus === 'success' || restartStatus === 'error') && (\n <Box marginTop={1}>\n <Text color=\"gray\">Press 'q' or Esc to go back</Text>\n </Box>\n )}\n </Box>\n )}\n \n {mode === 'edit' && (\n <Box>\n <Text color=\"yellow\">Opening external editor...</Text>\n <Text color=\"gray\"> Check your terminal focus.</Text>\n </Box>\n )}\n \n {mode === 'saving' && (\n <Box>\n <Text color=\"green\"><Spinner type=\"dots\" /> {saveStatus}</Text>\n </Box>\n )}\n </Box>\n )}\n </Box>\n )\n}\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useApp, useInput } from 'ink'\nimport SelectInput from 'ink-select-input'\nimport TextInput from 'ink-text-input'\nimport { Layout } from '../components/index.js'\nimport { ServerManager, type ServerConfig } from '../utils/server.js'\nimport { AppListCommand } from './appList.js'\nimport { LogsCommand } from './logs.js'\nimport { ConfigCommand } from './config.js'\nimport { DeployCommand } from './deploy.js'\nimport { ServerCommand } from './servers.js'\nimport { StatusCommand } from './status.js'\nimport { SshKeyCommand } from './ssh-key.js'\nimport { CaddyCommand } from './caddy.js'\nimport { DiagnosticsCommand } from './diagnostics.js'\n\n// Types for our Navigation Stack\ntype ViewName = 'root' | 'server-list' | 'server-dashboard' | 'app-list' | 'app-dashboard' | 'app-logs' | 'app-config' | 'app-deploy' | 'provision-app' | 'delete-server-confirm' | 'server-status' | 'server-ssh-keys' | 'server-caddy' | 'server-diagnostics'\n\ninterface ViewState {\n name: ViewName;\n props?: any;\n}\n\nexport function MainCommand() {\n const { exit } = useApp();\n // Stack of views. Last one is current.\n const [stack, setStack] = useState<ViewState[]>([{ name: 'root' }]);\n // Temporary state for inputs\n const [inputValue, setInputValue] = useState('');\n\n // Helper to push a new view\n const push = (name: ViewName, props?: any) => {\n setInputValue(''); // Reset input on nav\n setStack(prev => [...prev, { name, props }]);\n };\n\n // Helper to pop (go back)\n const pop = () => {\n if (stack.length <= 1) {\n exit(); // Exit if at root\n } else {\n setStack(prev => prev.slice(0, -1));\n }\n };\n\n // Current view\n const current = stack[stack.length - 1];\n\n // Handle global back (Esc) if not handled by child\n // Note: Child components like LogsCommand use useInput too. \n // Ideally, only the active component should handle input.\n // Ink handles this by focus, but simple approach is pass pop to child as onBack.\n\n useInput((input, key) => {\n if (key.escape) {\n const currentView = stack[stack.length - 1].name;\n // We do NOT want to handle Esc if the child component handles it.\n // Child components that handle their own escape key\n if (['app-logs', 'app-config', 'app-deploy', 'server-status', 'server-ssh-keys', 'server-caddy', 'server-diagnostics'].includes(currentView)) {\n return\n }\n \n // Otherwise, pop!\n pop();\n }\n });\n\n /* --- VIEW RENDERERS --- */\n\n // 1. Root Menu\n if (current.name === 'root') {\n const items = [\n { label: 'Servers', value: 'server-list' },\n { label: 'Exit', value: 'exit' },\n ];\n return (\n <Layout \n title=\"Provisor\" \n subtitle=\"Main Menu\" \n footerStatus=\"Main Menu\" \n footerTips={['Select an Option', 'Esc to Exit']}\n >\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>Select category:</Text>\n <Box marginTop={1}>\n <SelectInput \n items={items} \n onSelect={(item) => {\n if (item.value === 'exit') exit();\n else push(item.value as ViewName);\n }} \n />\n </Box>\n </Box>\n </Layout>\n );\n }\n\n // 2. Server List\n if (current.name === 'server-list') {\n // We reuse ServerCommand logic but wrapped to allow selection\n // Actually ServerCommand was built for add/remove. \n // Let's implement a simple list here that pushes 'server-dashboard'.\n // Or we render ServerCommand and modify it to allow \"Select\" action?\n // User wants \"Move up if moved to server\". \n \n // Let's build a custom Server List here using ServerManager\n const servers = ServerManager.listServers();\n const items = Object.entries(servers).map(([alias, conf]) => ({\n label: `${alias} (${conf.user}@${conf.host})`,\n value: alias\n }));\n \n const menuItems = [\n ...items,\n { label: '< Back', value: '__back__' }\n ];\n\n return (\n <Layout title=\"Servers\" footerStatus=\"Select a Server\">\n <Box marginTop={1}>\n <SelectInput \n items={menuItems}\n onSelect={(item) => {\n if (item.value === '__back__') pop();\n else {\n // Selected a server\n push('server-dashboard', { alias: item.value, config: servers[item.value] });\n }\n }}\n />\n </Box>\n </Layout>\n );\n }\n\n // 3. Server Dashboard\n if (current.name === 'server-dashboard') {\n const { alias, config } = current.props\n const items = [\n { label: 'Apps', value: 'app-list' },\n { label: 'Run Diagnostics', value: 'server-diagnostics' },\n { label: 'Server Status', value: 'server-status' },\n { label: 'Manage SSH Keys', value: 'server-ssh-keys' },\n { label: 'Manage Caddy Configuration', value: 'server-caddy' },\n { label: 'Delete Server', value: 'delete' },\n { label: '< Back', value: '__back__' }\n ]\n\n return (\n <Layout \n title={`Server: ${alias}`} \n subtitle={config.host} \n footerStatus=\"Server Dashboard\"\n >\n <Box marginTop={1}>\n <SelectInput \n items={items}\n onSelect={(item) => {\n if (item.value === '__back__') pop()\n else if (item.value === 'app-list') {\n push('app-list', { alias, config })\n } else if (item.value === 'delete') {\n push('delete-server-confirm', { alias })\n } else if (item.value === 'server-status') {\n push('server-status', { alias, config })\n } else if (item.value === 'server-ssh-keys') {\n push('server-ssh-keys', { alias, config })\n } else if (item.value === 'server-caddy') {\n push('server-caddy', { alias, config })\n } else if (item.value === 'server-diagnostics') {\n push('server-diagnostics', { alias, config })\n }\n }}\n />\n </Box>\n </Layout>\n )\n }\n\n // 3.5 App List (Scan & List)\n if (current.name === 'app-list') {\n const { alias, config } = current.props;\n return (\n <AppListCommand\n alias={alias}\n config={config}\n onBack={pop}\n onSelectApp={(appName) => push('app-dashboard', { alias, config, appName })}\n onProvision={() => push('app-dashboard', { alias, config, askingName: true })}\n />\n );\n }\n \n // 3.6 Delete Confirmation\n if (current.name === 'delete-server-confirm') {\n const { alias } = current.props;\n return (\n <Layout title=\"Delete Server\" footerStatus=\"Confirm Deletion\">\n <Box flexDirection=\"column\">\n <Text color=\"red\" bold>Are you sure you want to delete server '{alias}'?</Text>\n <Text>This will only remove it from your local configuration.</Text>\n <Box marginTop={1}>\n <SelectInput\n items={[\n { label: 'No, Cancel', value: 'no' },\n { label: 'Yes, Delete', value: 'yes' }\n ]}\n onSelect={item => {\n if (item.value === 'yes') {\n ServerManager.removeServer(alias);\n // Pop twice to remove dashboard and go back to list\n // Actually, navigating to root and then list might be safer state-wise\n // Or just pop until root?\n // Let's set stack directly to root & list\n setStack([{ name: 'root' }, { name: 'server-list' }]);\n } else {\n pop();\n }\n }}\n />\n </Box>\n </Box>\n </Layout>\n );\n }\n\n // 4. App Dashboard (Needs App Name)\n if (current.name === 'app-dashboard') {\n const { alias, config, askingName, appName } = current.props;\n \n // If asking for name\n if (askingName) {\n return (\n <Layout title=\"Select App\" footerStatus=\"Enter App Name\">\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>Enter Application Name:</Text>\n <Box>\n <Text color=\"cyan\">{'> '}</Text>\n <TextInput \n value={inputValue}\n onChange={setInputValue}\n onSubmit={(val) => {\n // Update current view props to have appName and askingName=false\n // Or just replace stack?\n // Easiest: Pop and Push new view with name\n // But pop() is async logic-wise if using state? No, sync.\n \n // We can modify the stack directly\n setStack(prev => {\n const newStack = [...prev];\n newStack[newStack.length - 1] = {\n name: 'app-dashboard',\n props: { alias, config, appName: val, askingName: false }\n };\n return newStack;\n });\n setInputValue('');\n }}\n /> \n </Box>\n </Box>\n </Layout>\n );\n }\n\n const items = [\n { label: 'View Logs', value: 'logs' },\n { label: 'Configuration', value: 'config' },\n { label: 'Deploy', value: 'deploy' },\n { label: '< Back', value: '__back__' }\n ];\n\n return (\n <Layout title={`App: ${appName}`} subtitle={`Server: ${alias}`} footerStatus=\"App Dashboard\">\n <Box marginTop={1}>\n <SelectInput \n items={items}\n onSelect={(item) => {\n if (item.value === '__back__') pop();\n else if (item.value === 'logs') push('app-logs', { config, appName });\n else if (item.value === 'config') push('app-config', { config, appName });\n else if (item.value === 'deploy') push('app-deploy', { config, appName });\n }}\n />\n </Box>\n </Layout>\n );\n }\n\n // 5. App Logs Wrapper\n if (current.name === 'app-logs') {\n const { config, appName } = current.props;\n return (\n <LogsCommand \n host={config.host} \n user={config.user} \n name={appName}\n onBack={pop} // Pass pop to go back\n />\n );\n }\n \n if (current.name === 'app-config') {\n const { config, appName } = current.props;\n return (\n <ConfigCommand\n host={config.host}\n user={config.user}\n name={appName}\n onBack={pop}\n />\n );\n }\n\n if (current.name === 'app-deploy') {\n const { config, appName } = current.props\n return (\n <DeployCommand\n host={config.host}\n user={config.user}\n name={appName}\n onBack={pop}\n />\n )\n }\n\n // Server Status View\n if (current.name === 'server-status') {\n const { config } = current.props\n return (\n <StatusCommand\n host={config.host}\n user={config.user}\n onBack={pop}\n />\n )\n }\n\n // Server SSH Keys View\n if (current.name === 'server-ssh-keys') {\n const { config } = current.props\n return (\n <SshKeyCommand\n host={config.host}\n user={config.user}\n list={true}\n onBack={pop}\n />\n )\n }\n\n // Server Caddy Configuration View\n if (current.name === 'server-caddy') {\n const { config } = current.props\n return (\n <CaddyCommand\n host={config.host}\n user={config.user}\n onBack={pop}\n />\n )\n }\n\n // Server Diagnostics View\n if (current.name === 'server-diagnostics') {\n const { config } = current.props\n return (\n <DiagnosticsCommand\n host={config.host}\n user={config.user}\n onBack={pop}\n />\n )\n }\n\n return <Text>State Error: Unknown View {current.name}</Text>\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport { Layout } from '../components/index.js';\nimport { scanServer, type DiscoveredApp } from '../utils/scan.js';\nimport { ServerManager } from '../utils/server.js';\nimport type { SSHOptions } from '../utils/ssh.js';\n\ninterface AppListProps {\n alias: string;\n config: SSHOptions;\n onSelectApp: (appName: string) => void;\n onProvision: () => void;\n onBack: () => void;\n}\n\nexport function AppListCommand({ alias, config, onSelectApp, onProvision, onBack }: AppListProps) {\n const [apps, setApps] = useState<DiscoveredApp[] | null>(null);\n const [scanning, setScanning] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Trigger scan or load cache on mount\n useEffect(() => {\n let mounted = true;\n \n const load = async () => {\n // Check cache\n const cached = ServerManager.getApps(alias);\n if (cached && cached.length > 0) {\n if (mounted) setApps(cached);\n return;\n }\n \n // If no cache, scan\n if (mounted) setScanning(true);\n try {\n const found = await scanServer(config);\n if (mounted) {\n setApps(found);\n ServerManager.updateApps(alias, found);\n }\n } catch (err) {\n if (mounted) {\n setError(err instanceof Error ? err.message : String(err));\n setApps([]);\n }\n } finally {\n if (mounted) setScanning(false);\n }\n };\n\n if (apps === null && !scanning && !error) {\n load();\n }\n\n return () => { mounted = false; };\n }, [alias, config]); // Don't depend on apps, only run on alias change (effectively mount)\n\n // Manual Rescan handler\n const handleRescan = async () => {\n setScanning(true);\n setError(null);\n setApps(null); // Clear current view\n \n try {\n const found = await scanServer(config);\n setApps(found);\n ServerManager.updateApps(alias, found);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setApps([]);\n } finally {\n setScanning(false);\n }\n };\n\n if (scanning) {\n return (\n <Layout title={`Scanning ${alias}...`} footerStatus=\"Please wait\">\n <Text>Connecting to server and scanning for apps...</Text>\n </Layout>\n );\n }\n\n if (error) {\n return (\n <Layout title={`Error Scanning ${alias}`} footerStatus=\"Scan Failed\">\n <Text color=\"red\">Failed to scan server: {error}</Text>\n <Box marginTop={1}>\n <SelectInput \n items={[{ label: 'Retry', value: 'retry' }, { label: '< Back', value: 'back' }]}\n onSelect={item => {\n if (item.value === 'retry') { setApps(null); }\n else onBack();\n }}\n />\n </Box>\n </Layout>\n );\n }\n\n const listItems = (apps || []).map(app => ({\n label: app.name,\n value: app.name\n }));\n\n const menuItems = [\n ...listItems,\n { label: '+ Provision New App', value: '__provision__' },\n { label: '↻ Re-scan', value: '__rescan__' },\n { label: '< Back', value: '__back__' }\n ];\n\n return (\n <Layout \n title={`Apps on ${alias}`} \n subtitle={`${(apps || []).length} found`} \n footerStatus=\"Select an App\"\n >\n <Box marginTop={1}>\n <SelectInput \n items={menuItems}\n onSelect={(item) => {\n if (item.value === '__back__') onBack();\n else if (item.value === '__rescan__') {\n handleRescan();\n } else if (item.value === '__provision__') {\n onProvision();\n } else {\n onSelectApp(item.value);\n }\n }}\n />\n </Box>\n </Layout>\n );\n}\n","import { Client } from 'ssh2';\nimport { exec, connect, disconnect, type SSHOptions } from './ssh.js';\n\nexport interface DiscoveredApp {\n name: string;\n path: string;\n config?: any; // strict type could be AppConfig but let's keep it flexible for partials\n gitRemote?: string;\n gitBranch?: string;\n services?: {\n webhook?: boolean;\n poll?: boolean;\n pm2?: boolean;\n }\n}\n\nconst SCAN_SCRIPT = `\n # JSON output array\n echo \"[\"\n\n FIRST=1\n\n # Iterate directories in /var/www\n for DIR in /var/www/*; do\n if [ -d \"$DIR\" ]; then\n NAME=$(basename \"$DIR\")\n if [ \"$NAME\" != \"html\" ]; then\n if [ \"$FIRST\" != \"1\" ]; then echo \",\"; fi\n FIRST=0\n \n echo \"{\"\n echo \"\\\"name\\\": \\\"$NAME\\\",\"\n echo \"\\\"path\\\": \\\"$DIR\\\",\"\n \n # Check .provisor.json\n if [ -f \"$DIR/.provisor.json\" ]; then\n CONTENT=$(cat \"$DIR/.provisor.json\" | tr -d '\\n')\n echo \"\\\"config\\\": $CONTENT,\"\n fi\n\n # Check Git info\n if [ -d \"$DIR/.git\" ]; then\n cd \"$DIR\"\n REMOTE=$(git remote get-url origin 2>/dev/null || echo \"\")\n BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"\")\n echo \"\\\"gitRemote\\\": \\\"$REMOTE\\\",\"\n echo \"\\\"gitBranch\\\": \\\"$BRANCH\\\",\"\n fi\n\n # Check Services\n WEBHOOK=\"false\"\n if systemctl is-active --quiet webhook-$NAME 2>/dev/null; then WEBHOOK=\"true\"; fi\n \n POLL=\"false\"\n if systemctl is-active --quiet poll-$NAME.timer 2>/dev/null; then POLL=\"true\"; fi\n\n # Basic check for PM2 (might need sudo or user switch, assuming running as deploy user generally)\n # This part is tricky if we don't have pm2 in path of the non-interactive shell or different user\n # We'll skip deep pm2 check for now to avoid complexity, or try simple process check\n \n echo \"\\\"services\\\": {\"\n echo \"\\\"webhook\\\": $WEBHOOK,\"\n echo \"\\\"poll\\\": $POLL\"\n echo \"}\"\n \n echo \"}\"\n fi\n fi\n done\n\n echo \"]\"\n`;\n\nexport async function scanServer(options: SSHOptions): Promise<DiscoveredApp[]> {\n let client: Client | null = null;\n try {\n client = await connect(options);\n const result = await exec(client, SCAN_SCRIPT);\n \n // Parse partial JSON or robustly handle parsing errors?\n // The bash script constructs JSON manually, which can be fragile with special chars.\n // Ideally we usage jq or node if available. \n // Let's try to assume clean output or fallback to node script if this fails?\n // Actually, writing a node script to /tmp and running it is safer.\n \n // Let's use Node script approach similar to ConfigCommand for robustness\n const nodeScript = `\n const fs = require('fs');\n const path = require('path');\n const { execSync } = require('child_process');\n\n const apps = [];\n const wwwDir = '/var/www';\n\n try {\n if (fs.existsSync(wwwDir)) {\n const dirs = fs.readdirSync(wwwDir);\n for (const name of dirs) {\n if (name === 'html') continue;\n const dirPath = path.join(wwwDir, name);\n if (fs.statSync(dirPath).isDirectory()) {\n const app = { name, path: dirPath, services: {} };\n \n // Read config\n const configPath = path.join(dirPath, '.provisor.json');\n if (fs.existsSync(configPath)) {\n try {\n app.config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n } catch (e) {}\n }\n\n // Git info\n try {\n const remote = execSync('git -C ' + dirPath + ' remote get-url origin', { stdio: 'pipe' }).toString().trim();\n app.gitRemote = remote;\n const branch = execSync('git -C ' + dirPath + ' rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();\n app.gitBranch = branch;\n } catch (e) {}\n\n // Systemd checks\n try {\n execSync('systemctl is-active webhook-' + name, { stdio: 'ignore' });\n app.services.webhook = true;\n } catch (e) { app.services.webhook = false; }\n\n try {\n execSync('systemctl is-active poll-' + name + '.timer', { stdio: 'ignore' });\n app.services.poll = true;\n } catch (e) { app.services.poll = false; }\n \n apps.push(app);\n }\n }\n }\n } catch (e) {\n // ignore dir errors\n }\n\n console.log(JSON.stringify(apps));\n `;\n\n // Write node script\n await exec(client, `cat << 'EOF' > /tmp/scan-apps.js\\n${nodeScript}\\nEOF`);\n \n // Run node script\n const nodeResult = await exec(client, 'node /tmp/scan-apps.js');\n await exec(client, 'rm /tmp/scan-apps.js');\n\n try {\n const apps = JSON.parse(nodeResult.stdout.trim());\n return apps;\n } catch (e) {\n console.error('Failed to parse scan result:', nodeResult.stdout);\n return [];\n }\n\n } catch (err) {\n console.error('Scan failed:', err);\n throw err;\n } finally {\n if (client) disconnect(client);\n }\n}\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useApp, useInput } from 'ink'\nimport Spinner from 'ink-spinner'\nimport { Header, Task, type TaskStatus } from '../components/index.js'\nimport { connect, exec, disconnect, type SSHOptions } from '../utils/ssh.js'\nimport type { Client } from 'ssh2'\n\ninterface DiagnosticsCommandProps extends SSHOptions {\n onBack?: () => void\n}\n\ninterface DiagnosticCheck {\n name: string\n status: TaskStatus\n result?: string\n details?: string[]\n}\n\nexport function DiagnosticsCommand(props: DiagnosticsCommandProps) {\n const { exit } = useApp()\n const [checks, setChecks] = useState<DiagnosticCheck[]>([\n { name: 'Caddy Service', status: 'pending' },\n { name: 'Firewall (UFW)', status: 'pending' },\n { name: 'Port Listeners', status: 'pending' },\n { name: 'Caddy Logs', status: 'pending' },\n { name: 'HTTP Connectivity', status: 'pending' },\n ])\n const [done, setDone] = useState(false)\n const [overallStatus, setOverallStatus] = useState<'running' | 'success' | 'warning' | 'error'>('running')\n\n const goBack = () => {\n if (props.onBack) {\n props.onBack()\n } else {\n exit()\n }\n }\n\n useInput((input, key) => {\n if (done && (key.escape || input === 'q')) {\n goBack()\n }\n })\n\n const updateCheck = (index: number, update: Partial<DiagnosticCheck>) => {\n setChecks(prev => {\n const newChecks = [...prev]\n newChecks[index] = { ...newChecks[index], ...update }\n return newChecks\n })\n }\n\n useEffect(() => {\n const run = async () => {\n let hasErrors = false\n let hasWarnings = false\n\n try {\n const client = await connect(props)\n\n // 1. Check Caddy service\n updateCheck(0, { status: 'running' })\n try {\n const caddyStatus = await exec(client, 'systemctl is-active caddy 2>/dev/null || echo \"not-found\"')\n const status = caddyStatus.stdout.trim()\n if (status === 'active') {\n updateCheck(0, { status: 'success', result: 'Running' })\n } else if (status === 'inactive') {\n updateCheck(0, { status: 'error', result: 'Stopped - run: sudo systemctl start caddy' })\n hasErrors = true\n } else {\n updateCheck(0, { status: 'error', result: `Status: ${status}` })\n hasErrors = true\n }\n } catch (err) {\n updateCheck(0, { status: 'error', result: 'Failed to check' })\n hasErrors = true\n }\n\n // 2. Check Firewall\n updateCheck(1, { status: 'running' })\n try {\n const ufwStatus = await exec(client, 'ufw status 2>/dev/null || echo \"ufw not installed\"')\n const output = ufwStatus.stdout.trim()\n \n if (output.includes('inactive')) {\n updateCheck(1, { status: 'success', result: 'Disabled (all ports open)' })\n } else if (output.includes('not installed')) {\n updateCheck(1, { status: 'success', result: 'Not installed' })\n } else {\n // Check for 80 and 443\n const has80 = output.includes('80') || output.includes('HTTP')\n const has443 = output.includes('443') || output.includes('HTTPS')\n \n if (has80 && has443) {\n updateCheck(1, { status: 'success', result: 'Ports 80/443 allowed' })\n } else {\n const missing = []\n if (!has80) missing.push('80')\n if (!has443) missing.push('443')\n updateCheck(1, { \n status: 'error', \n result: `Missing ports: ${missing.join(', ')}`,\n details: ['Run: sudo ufw allow 80 && sudo ufw allow 443']\n })\n hasErrors = true\n }\n }\n } catch (err) {\n updateCheck(1, { status: 'warning', result: 'Could not check firewall' })\n hasWarnings = true\n }\n\n // 3. Check port listeners\n updateCheck(2, { status: 'running' })\n try {\n const ports = await exec(client, 'ss -tlnp 2>/dev/null | grep -E \":(80|443)\" || echo \"none\"')\n const output = ports.stdout.trim()\n \n if (output === 'none' || output === '') {\n updateCheck(2, { \n status: 'error', \n result: 'Nothing listening on 80/443',\n details: ['Caddy may not be running or configured correctly']\n })\n hasErrors = true\n } else {\n const lines = output.split('\\n').filter(l => l.trim())\n const has80 = lines.some(l => l.includes(':80 ') || l.includes(':80\\t'))\n const has443 = lines.some(l => l.includes(':443 ') || l.includes(':443\\t'))\n \n if (has80 && has443) {\n updateCheck(2, { status: 'success', result: 'Ports 80 & 443 listening' })\n } else {\n const listening = []\n if (has80) listening.push('80')\n if (has443) listening.push('443')\n updateCheck(2, { \n status: 'warning', \n result: `Only port ${listening.join(', ')} listening` \n })\n hasWarnings = true\n }\n }\n } catch (err) {\n updateCheck(2, { status: 'warning', result: 'Could not check ports' })\n hasWarnings = true\n }\n\n // 4. Check Caddy logs for errors\n updateCheck(3, { status: 'running' })\n try {\n const logs = await exec(client, 'journalctl -u caddy --no-pager -n 10 2>/dev/null | tail -5 || echo \"no logs\"')\n const output = logs.stdout.trim()\n \n if (output.toLowerCase().includes('error') || output.toLowerCase().includes('failed')) {\n const errorLines = output.split('\\n').filter(l => \n l.toLowerCase().includes('error') || l.toLowerCase().includes('failed')\n ).slice(0, 3)\n updateCheck(3, { \n status: 'warning', \n result: 'Recent errors found',\n details: errorLines.map(l => l.slice(0, 80))\n })\n hasWarnings = true\n } else if (output === 'no logs') {\n updateCheck(3, { status: 'success', result: 'No logs available' })\n } else {\n updateCheck(3, { status: 'success', result: 'No recent errors' })\n }\n } catch (err) {\n updateCheck(3, { status: 'warning', result: 'Could not read logs' })\n hasWarnings = true\n }\n\n // 5. Test HTTP connectivity from server\n updateCheck(4, { status: 'running' })\n try {\n const httpTest = await exec(client, 'curl -s -o /dev/null -w \"%{http_code}\" http://localhost:80 2>/dev/null || echo \"failed\"')\n const code = httpTest.stdout.trim()\n \n if (code === 'failed' || code === '000') {\n updateCheck(4, { \n status: 'error', \n result: 'Cannot connect to localhost:80',\n details: ['Web server may not be running']\n })\n hasErrors = true\n } else if (code.startsWith('2') || code.startsWith('3')) {\n updateCheck(4, { status: 'success', result: `HTTP ${code} OK` })\n } else if (code === '404') {\n updateCheck(4, { status: 'warning', result: 'HTTP 404 - Check /var/www/app exists' })\n hasWarnings = true\n } else {\n updateCheck(4, { status: 'warning', result: `HTTP ${code}` })\n hasWarnings = true\n }\n } catch (err) {\n updateCheck(4, { status: 'warning', result: 'Could not test HTTP' })\n hasWarnings = true\n }\n\n disconnect(client)\n\n // Set overall status\n if (hasErrors) {\n setOverallStatus('error')\n } else if (hasWarnings) {\n setOverallStatus('warning')\n } else {\n setOverallStatus('success')\n }\n\n setDone(true)\n } catch (err) {\n // Connection failed\n setChecks(prev => prev.map(c => ({ ...c, status: 'error' as TaskStatus, result: 'Connection failed' })))\n setOverallStatus('error')\n setDone(true)\n }\n }\n\n run()\n }, [])\n\n const getStatusIcon = (status: TaskStatus) => {\n switch (status) {\n case 'pending': return '○'\n case 'running': return '◐'\n case 'success': return '●'\n case 'error': return '✗'\n default: return '○'\n }\n }\n\n const getStatusColor = (status: TaskStatus): string => {\n switch (status) {\n case 'pending': return 'gray'\n case 'running': return 'yellow'\n case 'success': return 'green'\n case 'error': return 'red'\n default: return 'gray'\n }\n }\n\n return (\n <Box flexDirection=\"column\">\n <Header title=\"Server Diagnostics\" subtitle={`Host: ${props.host}`} />\n\n <Box marginTop={1} flexDirection=\"column\">\n {checks.map((check, i) => (\n <Box key={i} flexDirection=\"column\">\n <Box>\n {check.status === 'running' ? (\n <Text color=\"yellow\"><Spinner type=\"dots\" /> </Text>\n ) : (\n <Text color={getStatusColor(check.status)}>{getStatusIcon(check.status)} </Text>\n )}\n <Text>{check.name}: </Text>\n {check.result && (\n <Text color={getStatusColor(check.status)}>{check.result}</Text>\n )}\n </Box>\n {check.details && check.details.map((detail, j) => (\n <Text key={j} color=\"gray\"> → {detail}</Text>\n ))}\n </Box>\n ))}\n </Box>\n\n {done && (\n <Box marginTop={1} flexDirection=\"column\">\n <Box>\n <Text bold>\n Overall: {' '}\n </Text>\n {overallStatus === 'success' && <Text color=\"green\">All checks passed!</Text>}\n {overallStatus === 'warning' && <Text color=\"yellow\">Some warnings - review above</Text>}\n {overallStatus === 'error' && <Text color=\"red\">Issues found - see above for fixes</Text>}\n </Box>\n <Box marginTop={1}>\n <Text color=\"gray\">Press 'q' or Esc to go back</Text>\n </Box>\n </Box>\n )}\n </Box>\n )\n}\n"],"mappings":"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","names":["useState","Box","Text","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","useState","Box","Text","useState","useEffect","Box","Text","useApp","useInput","Spinner","jsx","jsxs","SCRIPTS","useApp","useState","useInput","useEffect","Box","Text","Spinner","useState","useEffect","Box","Text","useApp","useInput","jsx","jsxs","useApp","useState","useInput","useEffect","Box","Text","useState","useEffect","Box","Text","useApp","useInput","jsx","jsxs","useApp","useState","useInput","useEffect","Box","Text","useState","useEffect","Box","Text","useApp","useInput","jsx","jsxs","useApp","useState","useEffect","useInput","Box","Text","React","useState","useEffect","Box","Text","useApp","useInput","SelectInput","TextInput","jsx","jsxs","SCRIPTS","path","useApp","useState","useEffect","React","useInput","Box","Text","SelectInput","TextInput","useState","useEffect","Box","Text","Spinner","SelectInput","jsx","jsxs","useState","useEffect","Box","Text","Spinner","SelectInput","useState","useEffect","Box","Text","useApp","useInput","SelectInput","Spinner","jsx","jsxs","useApp","useState","useInput","useEffect","path","Box","Text","Spinner","SelectInput","useState","useEffect","Box","Text","useApp","SelectInput","TextInput","useState","useEffect","Box","Text","useApp","useInput","SelectInput","Spinner","fs","os","path","Fragment","jsx","jsxs","useApp","useState","useEffect","useInput","Box","Text","SelectInput","Spinner","jsx","jsxs","useApp","useState","useEffect","Box","SelectInput","Text","TextInput","useState","Box","Text","useApp","useInput","SelectInput","TextInput","useState","useEffect","Box","Text","SelectInput","jsx","jsxs","useState","useEffect","Text","Box","SelectInput","useState","useEffect","Box","Text","useApp","useInput","Spinner","jsx","jsxs","useApp","useState","useInput","useEffect","Box","Text","Spinner","jsx","jsxs","useApp","useState","useInput","Box","Text","SelectInput","TextInput","jsx"]}
|