@it-club/provisor 0.2.0 → 0.2.1
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/dist/cli.js +6 -3
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -396,8 +396,10 @@ var SCRIPTS2 = {
|
|
|
396
396
|
fi
|
|
397
397
|
`,
|
|
398
398
|
// Generate deploy key for private repos
|
|
399
|
-
generateDeployKey: (name, user) =>
|
|
400
|
-
|
|
399
|
+
generateDeployKey: (name, user) => {
|
|
400
|
+
const homeDir = user === "root" ? "/root" : `/home/${user}`;
|
|
401
|
+
return `
|
|
402
|
+
SSH_DIR="${homeDir}/.ssh"
|
|
401
403
|
KEY_FILE="$SSH_DIR/deploy_${name}"
|
|
402
404
|
|
|
403
405
|
mkdir -p "$SSH_DIR"
|
|
@@ -426,7 +428,8 @@ EOF
|
|
|
426
428
|
|
|
427
429
|
# Output the public key
|
|
428
430
|
cat "$KEY_FILE.pub"
|
|
429
|
-
|
|
431
|
+
`;
|
|
432
|
+
},
|
|
430
433
|
// Test SSH connection to git host
|
|
431
434
|
testGitConnection: (host) => `
|
|
432
435
|
ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes -T git@${host} 2>&1 || true
|
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"],"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\nprogram\n .name('provisor')\n .description('Server provisioning and deployment CLI')\n .version('0.2.0');\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 SSH_DIR=\"/home/${user}/.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 // 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'\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 // This will be replaced at build time, but we read from package.json\n return '0.2.0'\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"],"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/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"],"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\nprogram\n .name('provisor')\n .description('Server provisioning and deployment CLI')\n .version('0.2.0');\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'\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 // This will be replaced at build time, but we read from package.json\n return '0.2.0'\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"],"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"]}
|