bindler 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,12 @@ cli for managing multiple projects behind cloudflare tunnel with nginx and pm2.
8
8
  npm install -g bindler
9
9
  ```
10
10
 
11
+ ## update to latest
12
+
13
+ ```bash
14
+ npm update -g bindler
15
+ ```
16
+
11
17
  you'll also need:
12
18
  - node.js 18+
13
19
  - nginx - `brew install nginx` (mac) or `apt install nginx` (linux)
package/dist/cli.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  // src/cli.ts
4
4
  import { Command } from "commander";
5
+ import chalk17 from "chalk";
5
6
 
6
7
  // src/commands/new.ts
7
8
  import { existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
@@ -1757,7 +1758,7 @@ async function infoCommand() {
1757
1758
  `));
1758
1759
  console.log(chalk14.white(" Manage multiple projects behind Cloudflare Tunnel"));
1759
1760
  console.log(chalk14.white(" with Nginx and PM2\n"));
1760
- console.log(chalk14.dim(" Version: ") + chalk14.white("1.0.2"));
1761
+ console.log(chalk14.dim(" Version: ") + chalk14.white("1.0.4"));
1761
1762
  console.log(chalk14.dim(" Author: ") + chalk14.white("alfaoz"));
1762
1763
  console.log(chalk14.dim(" License: ") + chalk14.white("MIT"));
1763
1764
  console.log(chalk14.dim(" GitHub: ") + chalk14.cyan("https://github.com/alfaoz/bindler"));
@@ -2209,24 +2210,76 @@ program.command("status").description("Show detailed status of all projects").ac
2209
2210
  await statusCommand();
2210
2211
  });
2211
2212
  program.command("start [name]").description("Start an npm project with PM2").option("-a, --all", "Start all npm projects").action(async (name, options) => {
2213
+ if (!name && !options.all) {
2214
+ console.log(chalk17.red("Usage: bindler start <name> or bindler start --all"));
2215
+ console.log(chalk17.dim("\nExamples:"));
2216
+ console.log(chalk17.dim(" bindler start myapp"));
2217
+ console.log(chalk17.dim(" bindler start --all # start all npm projects"));
2218
+ process.exit(1);
2219
+ }
2212
2220
  await startCommand(name, options);
2213
2221
  });
2214
2222
  program.command("stop [name]").description("Stop an npm project").option("-a, --all", "Stop all npm projects").action(async (name, options) => {
2223
+ if (!name && !options.all) {
2224
+ console.log(chalk17.red("Usage: bindler stop <name> or bindler stop --all"));
2225
+ console.log(chalk17.dim("\nExamples:"));
2226
+ console.log(chalk17.dim(" bindler stop myapp"));
2227
+ console.log(chalk17.dim(" bindler stop --all # stop all npm projects"));
2228
+ process.exit(1);
2229
+ }
2215
2230
  await stopCommand(name, options);
2216
2231
  });
2217
2232
  program.command("restart [name]").description("Restart an npm project").option("-a, --all", "Restart all npm projects").action(async (name, options) => {
2233
+ if (!name && !options.all) {
2234
+ console.log(chalk17.red("Usage: bindler restart <name> or bindler restart --all"));
2235
+ console.log(chalk17.dim("\nExamples:"));
2236
+ console.log(chalk17.dim(" bindler restart myapp"));
2237
+ console.log(chalk17.dim(" bindler restart --all # restart all npm projects"));
2238
+ process.exit(1);
2239
+ }
2218
2240
  await restartCommand(name, options);
2219
2241
  });
2220
- program.command("logs <name>").description("Show logs for an npm project").option("-f, --follow", "Follow log output").option("-l, --lines <n>", "Number of lines to show", "200").action(async (name, options) => {
2242
+ program.command("logs [name]").description("Show logs for an npm project").option("-f, --follow", "Follow log output").option("-l, --lines <n>", "Number of lines to show", "200").action(async (name, options) => {
2243
+ if (!name) {
2244
+ console.log(chalk17.red("Usage: bindler logs <name>"));
2245
+ console.log(chalk17.dim("\nExamples:"));
2246
+ console.log(chalk17.dim(" bindler logs myapp"));
2247
+ console.log(chalk17.dim(" bindler logs myapp --follow"));
2248
+ console.log(chalk17.dim(" bindler logs myapp --lines 500"));
2249
+ process.exit(1);
2250
+ }
2221
2251
  await logsCommand(name, { ...options, lines: parseInt(options.lines, 10) });
2222
2252
  });
2223
- program.command("update <name>").description("Update project configuration").option("-h, --hostname <hostname>", "New hostname").option("--port <port>", "New port number").option("-s, --start <command>", "New start command").option("-p, --path <path>", "New project path").option("-e, --env <vars...>", "Environment variables (KEY=value)").option("--enable", "Enable the project").option("--disable", "Disable the project").action(async (name, options) => {
2253
+ program.command("update [name]").description("Update project configuration").option("-h, --hostname <hostname>", "New hostname").option("--port <port>", "New port number").option("-s, --start <command>", "New start command").option("-p, --path <path>", "New project path").option("-e, --env <vars...>", "Environment variables (KEY=value)").option("--enable", "Enable the project").option("--disable", "Disable the project").action(async (name, options) => {
2254
+ if (!name) {
2255
+ console.log(chalk17.red("Usage: bindler update <name> [options]"));
2256
+ console.log(chalk17.dim("\nExamples:"));
2257
+ console.log(chalk17.dim(" bindler update myapp --hostname newapp.example.com"));
2258
+ console.log(chalk17.dim(" bindler update myapp --port 4000"));
2259
+ console.log(chalk17.dim(" bindler update myapp --disable"));
2260
+ process.exit(1);
2261
+ }
2224
2262
  await updateCommand(name, options);
2225
2263
  });
2226
- program.command("edit <name>").description("Edit project configuration in $EDITOR").action(async (name) => {
2264
+ program.command("edit [name]").description("Edit project configuration in $EDITOR").action(async (name) => {
2265
+ if (!name) {
2266
+ console.log(chalk17.red("Usage: bindler edit <name>"));
2267
+ console.log(chalk17.dim("\nOpens the project config in your $EDITOR"));
2268
+ console.log(chalk17.dim("\nExample:"));
2269
+ console.log(chalk17.dim(" bindler edit myapp"));
2270
+ process.exit(1);
2271
+ }
2227
2272
  await editCommand(name);
2228
2273
  });
2229
- program.command("remove <name>").alias("rm").description("Remove a project from registry").option("-f, --force", "Skip confirmation").option("--apply", "Apply nginx config after removing").action(async (name, options) => {
2274
+ program.command("remove [name]").alias("rm").description("Remove a project from registry").option("-f, --force", "Skip confirmation").option("--apply", "Apply nginx config after removing").action(async (name, options) => {
2275
+ if (!name) {
2276
+ console.log(chalk17.red("Usage: bindler remove <name>"));
2277
+ console.log(chalk17.dim("\nExamples:"));
2278
+ console.log(chalk17.dim(" bindler remove myapp"));
2279
+ console.log(chalk17.dim(" bindler remove myapp --force # skip confirmation"));
2280
+ console.log(chalk17.dim(" bindler rm myapp # alias"));
2281
+ process.exit(1);
2282
+ }
2230
2283
  await removeCommand(name, options);
2231
2284
  });
2232
2285
  program.command("apply").description("Generate and apply nginx configuration + Cloudflare DNS routes").option("-d, --dry-run", "Print config without applying").option("--no-reload", "Write config but do not reload nginx").option("--no-cloudflare", "Skip Cloudflare DNS route configuration").option("--no-ssl", "Skip SSL certificate setup (direct mode)").action(async (options) => {
@@ -2241,7 +2294,14 @@ program.command("ports").description("Show allocated ports").action(async () =>
2241
2294
  program.command("info").description("Show bindler information and stats").action(async () => {
2242
2295
  await infoCommand();
2243
2296
  });
2244
- program.command("check <hostname>").description("Check DNS propagation and HTTP accessibility for a hostname").option("-v, --verbose", "Show verbose output").action(async (hostname, options) => {
2297
+ program.command("check [hostname]").description("Check DNS propagation and HTTP accessibility for a hostname").option("-v, --verbose", "Show verbose output").action(async (hostname, options) => {
2298
+ if (!hostname) {
2299
+ console.log(chalk17.red("Usage: bindler check <hostname>"));
2300
+ console.log(chalk17.dim("\nExamples:"));
2301
+ console.log(chalk17.dim(" bindler check myapp.example.com"));
2302
+ console.log(chalk17.dim(" bindler check myapp # uses project name"));
2303
+ process.exit(1);
2304
+ }
2245
2305
  await checkCommand(hostname, options);
2246
2306
  });
2247
2307
  program.command("setup").description("Install missing dependencies (nginx, PM2, cloudflared)").option("--direct", "Direct mode for VPS (no Cloudflare Tunnel, use port 80/443)").action(async (options) => {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/new.ts","../src/lib/config.ts","../src/lib/utils.ts","../src/lib/ports.ts","../src/lib/nginx.ts","../src/lib/pm2.ts","../src/commands/list.ts","../src/commands/status.ts","../src/commands/start.ts","../src/commands/stop.ts","../src/commands/restart.ts","../src/commands/logs.ts","../src/commands/update.ts","../src/commands/edit.ts","../src/commands/remove.ts","../src/commands/apply.ts","../src/lib/cloudflare.ts","../src/commands/doctor.ts","../src/commands/ports.ts","../src/commands/info.ts","../src/commands/check.ts","../src/commands/setup.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport {\n newCommand,\n listCommand,\n statusCommand,\n startCommand,\n stopCommand,\n restartCommand,\n logsCommand,\n updateCommand,\n editCommand,\n removeCommand,\n applyCommand,\n doctorCommand,\n portsCommand,\n infoCommand,\n checkCommand,\n setupCommand,\n} from './commands/index.js';\nimport { initConfig } from './lib/config.js';\n\nconst program = new Command();\n\nprogram\n .name('bindler')\n .description('Manage multiple projects behind Cloudflare Tunnel with Nginx and PM2')\n .version('1.0.0');\n\n// Initialize config on first run\nprogram.hook('preAction', () => {\n try {\n initConfig();\n } catch (error) {\n // Config init may fail if not root - that's okay for some commands\n }\n});\n\n// new - Create a new project\nprogram\n .command('new')\n .description('Create and register a new project')\n .option('-n, --name <name>', 'Project name')\n .option('-t, --type <type>', 'Project type (static or npm)', 'static')\n .option('-p, --path <path>', 'Project directory path')\n .option('-h, --hostname <hostname>', 'Hostname for the project')\n .option('-b, --base-path <path>', 'Base path for path-based routing (e.g., /api)')\n .option('--port <port>', 'Port number (npm projects only)')\n .option('-s, --start <command>', 'Start command (npm projects only)')\n .option('-l, --local', 'Local project (skip Cloudflare, use .local hostname)')\n .option('--apply', 'Apply nginx config after creating')\n .action(async (options) => {\n await newCommand(options);\n });\n\n// list - List all projects\nprogram\n .command('list')\n .alias('ls')\n .description('List all registered projects')\n .action(async () => {\n await listCommand();\n });\n\n// status - Show runtime status\nprogram\n .command('status')\n .description('Show detailed status of all projects')\n .action(async () => {\n await statusCommand();\n });\n\n// start - Start a project\nprogram\n .command('start [name]')\n .description('Start an npm project with PM2')\n .option('-a, --all', 'Start all npm projects')\n .action(async (name, options) => {\n await startCommand(name, options);\n });\n\n// stop - Stop a project\nprogram\n .command('stop [name]')\n .description('Stop an npm project')\n .option('-a, --all', 'Stop all npm projects')\n .action(async (name, options) => {\n await stopCommand(name, options);\n });\n\n// restart - Restart a project\nprogram\n .command('restart [name]')\n .description('Restart an npm project')\n .option('-a, --all', 'Restart all npm projects')\n .action(async (name, options) => {\n await restartCommand(name, options);\n });\n\n// logs - Show project logs\nprogram\n .command('logs <name>')\n .description('Show logs for an npm project')\n .option('-f, --follow', 'Follow log output')\n .option('-l, --lines <n>', 'Number of lines to show', '200')\n .action(async (name, options) => {\n await logsCommand(name, { ...options, lines: parseInt(options.lines, 10) });\n });\n\n// update - Update project configuration\nprogram\n .command('update <name>')\n .description('Update project configuration')\n .option('-h, --hostname <hostname>', 'New hostname')\n .option('--port <port>', 'New port number')\n .option('-s, --start <command>', 'New start command')\n .option('-p, --path <path>', 'New project path')\n .option('-e, --env <vars...>', 'Environment variables (KEY=value)')\n .option('--enable', 'Enable the project')\n .option('--disable', 'Disable the project')\n .action(async (name, options) => {\n await updateCommand(name, options);\n });\n\n// edit - Edit project in $EDITOR\nprogram\n .command('edit <name>')\n .description('Edit project configuration in $EDITOR')\n .action(async (name) => {\n await editCommand(name);\n });\n\n// remove - Remove a project\nprogram\n .command('remove <name>')\n .alias('rm')\n .description('Remove a project from registry')\n .option('-f, --force', 'Skip confirmation')\n .option('--apply', 'Apply nginx config after removing')\n .action(async (name, options) => {\n await removeCommand(name, options);\n });\n\n// apply - Apply configuration\nprogram\n .command('apply')\n .description('Generate and apply nginx configuration + Cloudflare DNS routes')\n .option('-d, --dry-run', 'Print config without applying')\n .option('--no-reload', 'Write config but do not reload nginx')\n .option('--no-cloudflare', 'Skip Cloudflare DNS route configuration')\n .option('--no-ssl', 'Skip SSL certificate setup (direct mode)')\n .action(async (options) => {\n await applyCommand(options);\n });\n\n// doctor - Run diagnostics\nprogram\n .command('doctor')\n .description('Run system diagnostics and check dependencies')\n .action(async () => {\n await doctorCommand();\n });\n\n// ports - Show allocated ports\nprogram\n .command('ports')\n .description('Show allocated ports')\n .action(async () => {\n await portsCommand();\n });\n\n// info - Show project info\nprogram\n .command('info')\n .description('Show bindler information and stats')\n .action(async () => {\n await infoCommand();\n });\n\n// check - Check DNS and HTTP for a hostname\nprogram\n .command('check <hostname>')\n .description('Check DNS propagation and HTTP accessibility for a hostname')\n .option('-v, --verbose', 'Show verbose output')\n .action(async (hostname, options) => {\n await checkCommand(hostname, options);\n });\n\n// setup - Install dependencies\nprogram\n .command('setup')\n .description('Install missing dependencies (nginx, PM2, cloudflared)')\n .option('--direct', 'Direct mode for VPS (no Cloudflare Tunnel, use port 80/443)')\n .action(async (options) => {\n await setupCommand(options);\n });\n\n// Parse arguments\nprogram.parse();\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename } from 'node:path';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport type { Project } from '../types.js';\nimport { addProject, getDefaults } from '../lib/config.js';\nimport { findAvailablePort } from '../lib/ports.js';\nimport {\n detectProjectType,\n getPackageJsonScripts,\n validateHostname,\n validateProjectName,\n validatePort,\n} from '../lib/utils.js';\nimport { isNginxInstalled } from '../lib/nginx.js';\nimport { isPm2Installed } from '../lib/pm2.js';\n\ninterface NewOptions {\n name?: string;\n type?: 'static' | 'npm';\n path?: string;\n hostname?: string;\n basePath?: string;\n port?: number;\n start?: string;\n apply?: boolean;\n local?: boolean;\n}\n\nexport async function newCommand(options: NewOptions): Promise<void> {\n // Run prerequisite checks\n console.log(chalk.dim('Checking prerequisites...\\n'));\n\n const issues: string[] = [];\n\n if (!isNginxInstalled()) {\n issues.push('nginx is not installed. Install: brew install nginx (macOS) or apt install nginx (Linux)');\n }\n\n if (!isPm2Installed()) {\n issues.push('PM2 is not installed. Install: npm install -g pm2');\n }\n\n if (issues.length > 0) {\n console.log(chalk.red('Missing prerequisites:\\n'));\n for (const issue of issues) {\n console.log(chalk.red(` ✗ ${issue}`));\n }\n console.log(chalk.dim('\\nRun `bindler doctor` for full diagnostics.'));\n\n const { proceed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'proceed',\n message: 'Continue anyway?',\n default: false,\n },\n ]);\n\n if (!proceed) {\n process.exit(1);\n }\n console.log('');\n } else {\n console.log(chalk.green('✓ Prerequisites OK\\n'));\n }\n\n const defaults = getDefaults();\n let project: Partial<Project> = {};\n\n // Get current working directory info for defaults\n const cwd = process.cwd();\n const cwdName = basename(cwd);\n\n // Interactive mode if no name provided\n if (!options.name) {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'path',\n message: 'Project path:',\n default: cwd,\n validate: (input: string) => {\n if (!input) {\n return 'Path is required';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'name',\n message: 'Project name:',\n default: cwdName,\n validate: (input: string) => {\n if (!validateProjectName(input)) {\n return 'Invalid project name. Use alphanumeric characters, dashes, and underscores.';\n }\n return true;\n },\n },\n {\n type: 'list',\n name: 'type',\n message: 'Project type:',\n choices: (answers: { path: string }) => {\n const detected = existsSync(answers.path) ? detectProjectType(answers.path) : 'static';\n return [\n { name: `npm (Node.js app)${detected === 'npm' ? ' - detected' : ''}`, value: 'npm' },\n { name: `static (HTML/CSS/JS)${detected === 'static' ? ' - detected' : ''}`, value: 'static' },\n ];\n },\n default: (answers: { path: string }) => {\n return existsSync(answers.path) ? detectProjectType(answers.path) : 'static';\n },\n },\n {\n type: 'input',\n name: 'hostname',\n message: options.local\n ? 'Hostname (e.g., myapp.local):'\n : 'Hostname (e.g., mysite.example.com or example.com):',\n default: options.local ? `${cwdName}.local` : undefined,\n validate: (input: string) => {\n if (!validateHostname(input)) {\n return 'Invalid hostname format';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'basePath',\n message: 'Base path (leave empty for root, or e.g., /api):',\n filter: (input: string) => {\n if (!input || input.trim() === '') return '';\n // Ensure path starts with /\n const trimmed = input.trim();\n return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;\n },\n },\n ]);\n\n project = { ...answers };\n if (!project.basePath) delete project.basePath;\n if (options.local) project.local = true;\n\n // NPM-specific questions\n if (answers.type === 'npm') {\n const scripts = existsSync(answers.path) ? getPackageJsonScripts(answers.path) : [];\n const suggestedPort = findAvailablePort();\n\n const npmAnswers = await inquirer.prompt([\n {\n type: 'input',\n name: 'port',\n message: 'Port number:',\n default: suggestedPort,\n validate: (input: string) => {\n const port = parseInt(input, 10);\n if (!validatePort(port)) {\n return 'Invalid port. Use a number between 1024 and 65535.';\n }\n return true;\n },\n filter: (input: string) => parseInt(input, 10),\n },\n {\n type: scripts.length > 0 ? 'list' : 'input',\n name: 'start',\n message: 'Start command:',\n choices: scripts.length > 0\n ? [\n ...scripts.map((s) => ({ name: `npm run ${s}`, value: `npm run ${s}` })),\n { name: 'Custom command...', value: '__custom__' },\n ]\n : undefined,\n default: scripts.includes('start') ? 'npm run start' : 'npm start',\n },\n ]);\n\n if (npmAnswers.start === '__custom__') {\n const customAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'start',\n message: 'Enter custom start command:',\n },\n ]);\n npmAnswers.start = customAnswer.start;\n }\n\n project.port = npmAnswers.port;\n project.start = npmAnswers.start;\n\n // Ask about PORT env var\n const envAnswer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'setPortEnv',\n message: `Set PORT=${npmAnswers.port} environment variable?`,\n default: true,\n },\n ]);\n\n if (envAnswer.setPortEnv) {\n project.env = { PORT: String(npmAnswers.port) };\n }\n }\n } else {\n // Non-interactive mode - use provided options\n if (!options.hostname) {\n console.error(chalk.red('Error: --hostname is required'));\n process.exit(1);\n }\n\n project.name = options.name;\n project.type = options.type || 'static';\n project.path = options.path || cwd;\n project.hostname = options.hostname;\n\n // Handle base path for path-based routing\n if (options.basePath) {\n project.basePath = options.basePath.startsWith('/') ? options.basePath : `/${options.basePath}`;\n }\n\n // Handle local flag\n if (options.local) {\n project.local = true;\n }\n\n if (project.type === 'npm') {\n project.port = options.port || findAvailablePort();\n project.start = options.start || 'npm start';\n project.env = { PORT: String(project.port) };\n }\n }\n\n // Validate project\n if (!validateProjectName(project.name!)) {\n console.error(chalk.red('Error: Invalid project name'));\n process.exit(1);\n }\n\n if (!validateHostname(project.hostname!)) {\n console.error(chalk.red('Error: Invalid hostname'));\n process.exit(1);\n }\n\n // Create directory if it doesn't exist\n if (!existsSync(project.path!)) {\n const createDir = options.name\n ? true\n : (\n await inquirer.prompt([\n {\n type: 'confirm',\n name: 'create',\n message: `Directory ${project.path} does not exist. Create it?`,\n default: true,\n },\n ])\n ).create;\n\n if (createDir) {\n mkdirSync(project.path!, { recursive: true });\n console.log(chalk.green(`Created directory: ${project.path}`));\n }\n }\n\n // Add project to config\n try {\n addProject(project as Project);\n console.log(chalk.green(`\\nProject \"${project.name}\" added successfully!`));\n\n if (project.local) {\n console.log(chalk.yellow(`\\nLocal project - add to /etc/hosts:`));\n console.log(chalk.cyan(` echo \"127.0.0.1 ${project.hostname}\" | sudo tee -a /etc/hosts`));\n console.log(chalk.dim(`\\nRun ${chalk.cyan('sudo bindler apply')} to update nginx.`));\n console.log(chalk.dim(`Then access at: ${chalk.cyan(`http://${project.hostname}:8080`)}`));\n } else {\n console.log(chalk.dim(`\\nConfiguration saved. Run ${chalk.cyan('sudo bindler apply')} to update nginx and cloudflare.`));\n }\n\n if (project.type === 'npm') {\n console.log(chalk.dim(`Run ${chalk.cyan(`bindler start ${project.name}`)} to start the application.`));\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : error}`));\n process.exit(1);\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { Config, Project } from '../types.js';\n\nconst CONFIG_DIR = join(homedir(), '.config', 'bindler');\nconst CONFIG_PATH = join(CONFIG_DIR, 'config.json');\nconst GENERATED_DIR = join(CONFIG_DIR, 'generated');\nconst BACKUP_DIR = join(CONFIG_DIR, 'backups');\n\nexport function getConfigDir(): string {\n return CONFIG_DIR;\n}\n\nexport function getConfigPath(): string {\n return CONFIG_PATH;\n}\n\nexport function getGeneratedDir(): string {\n return GENERATED_DIR;\n}\n\nexport function getBackupDir(): string {\n return BACKUP_DIR;\n}\n\nfunction getNginxConfigPath(): string {\n const isMac = process.platform === 'darwin';\n\n if (isMac) {\n // Homebrew nginx paths\n if (existsSync('/opt/homebrew/etc/nginx/servers')) {\n return '/opt/homebrew/etc/nginx/servers/bindler.conf';\n }\n if (existsSync('/usr/local/etc/nginx/servers')) {\n return '/usr/local/etc/nginx/servers/bindler.conf';\n }\n }\n\n // Linux default\n return '/etc/nginx/conf.d/bindler.conf';\n}\n\nexport function getDefaultConfig(): Config {\n return {\n version: 1,\n defaults: {\n projectsRoot: join(homedir(), 'projects'),\n nginxManagedPath: getNginxConfigPath(),\n nginxListen: '127.0.0.1:8080',\n tunnelName: 'homelab',\n applyCloudflareDnsRoutes: true,\n mode: 'tunnel',\n },\n projects: [],\n };\n}\n\nexport function ensureConfigDirs(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n if (!existsSync(GENERATED_DIR)) {\n mkdirSync(GENERATED_DIR, { recursive: true });\n }\n if (!existsSync(BACKUP_DIR)) {\n mkdirSync(BACKUP_DIR, { recursive: true });\n }\n}\n\nexport function configExists(): boolean {\n return existsSync(CONFIG_PATH);\n}\n\nexport function readConfig(): Config {\n if (!configExists()) {\n return getDefaultConfig();\n }\n\n try {\n const content = readFileSync(CONFIG_PATH, 'utf-8');\n const config = JSON.parse(content) as Config;\n return config;\n } catch (error) {\n throw new Error(`Failed to read config: ${error instanceof Error ? error.message : error}`);\n }\n}\n\nexport function writeConfig(config: Config): void {\n ensureConfigDirs();\n\n // Create backup if config exists\n if (configExists()) {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const backupPath = join(BACKUP_DIR, `config-${timestamp}.json`);\n copyFileSync(CONFIG_PATH, backupPath);\n }\n\n writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\\n');\n}\n\nexport function initConfig(): Config {\n if (configExists()) {\n return readConfig();\n }\n\n const config = getDefaultConfig();\n writeConfig(config);\n return config;\n}\n\nexport function getProject(name: string): Project | undefined {\n const config = readConfig();\n return config.projects.find((p) => p.name === name);\n}\n\nexport function addProject(project: Project): void {\n const config = readConfig();\n\n if (config.projects.some((p) => p.name === project.name)) {\n throw new Error(`Project \"${project.name}\" already exists`);\n }\n\n if (config.projects.some((p) => p.hostname === project.hostname)) {\n throw new Error(`Hostname \"${project.hostname}\" is already in use`);\n }\n\n config.projects.push(project);\n writeConfig(config);\n}\n\nexport function updateProject(name: string, updates: Partial<Project>): void {\n const config = readConfig();\n const index = config.projects.findIndex((p) => p.name === name);\n\n if (index === -1) {\n throw new Error(`Project \"${name}\" not found`);\n }\n\n // Check hostname uniqueness if changing hostname\n if (updates.hostname && updates.hostname !== config.projects[index].hostname) {\n if (config.projects.some((p) => p.hostname === updates.hostname)) {\n throw new Error(`Hostname \"${updates.hostname}\" is already in use`);\n }\n }\n\n config.projects[index] = { ...config.projects[index], ...updates };\n writeConfig(config);\n}\n\nexport function removeProject(name: string): Project {\n const config = readConfig();\n const index = config.projects.findIndex((p) => p.name === name);\n\n if (index === -1) {\n throw new Error(`Project \"${name}\" not found`);\n }\n\n const [removed] = config.projects.splice(index, 1);\n writeConfig(config);\n return removed;\n}\n\nexport function listProjects(): Project[] {\n const config = readConfig();\n return config.projects;\n}\n\nexport function getDefaults(): Config['defaults'] {\n const config = readConfig();\n return config.defaults;\n}\n\nexport function updateDefaults(updates: Partial<Config['defaults']>): void {\n const config = readConfig();\n config.defaults = { ...config.defaults, ...updates };\n writeConfig(config);\n}\n","import { execSync, spawn, type SpawnOptions } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createConnection } from 'node:net';\n\nexport function execCommand(command: string, options?: { cwd?: string }): string {\n try {\n return execSync(command, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n ...options,\n }).trim();\n } catch (error) {\n if (error instanceof Error && 'stderr' in error) {\n throw new Error((error as { stderr: string }).stderr || error.message);\n }\n throw error;\n }\n}\n\nexport function execCommandSafe(command: string, options?: { cwd?: string }): { success: boolean; output: string; error?: string } {\n try {\n const output = execSync(command, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n ...options,\n }).trim();\n return { success: true, output };\n } catch (error) {\n if (error instanceof Error && 'stderr' in error) {\n return { success: false, output: '', error: (error as { stderr: string }).stderr || error.message };\n }\n return { success: false, output: '', error: String(error) };\n }\n}\n\nexport function spawnCommand(\n command: string,\n args: string[],\n options?: SpawnOptions\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n stdio: ['inherit', 'pipe', 'pipe'],\n ...options,\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (data) => {\n stdout += data.toString();\n });\n\n child.stderr?.on('data', (data) => {\n stderr += data.toString();\n });\n\n child.on('close', (code) => {\n resolve({ code, stdout, stderr });\n });\n });\n}\n\nexport function spawnInteractive(command: string, args: string[], options?: SpawnOptions): Promise<number | null> {\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n stdio: 'inherit',\n ...options,\n });\n\n child.on('close', (code) => {\n resolve(code);\n });\n });\n}\n\nexport function commandExists(command: string): boolean {\n try {\n execSync(`which ${command}`, { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function isPortListening(port: number, host = '127.0.0.1'): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host }, () => {\n socket.destroy();\n resolve(true);\n });\n\n socket.on('error', () => {\n resolve(false);\n });\n\n socket.setTimeout(1000, () => {\n socket.destroy();\n resolve(false);\n });\n });\n}\n\nexport function detectProjectType(path: string): 'npm' | 'static' {\n const packageJsonPath = join(path, 'package.json');\n return existsSync(packageJsonPath) ? 'npm' : 'static';\n}\n\nexport function getPackageJsonScripts(path: string): string[] {\n const packageJsonPath = join(path, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return [];\n }\n\n try {\n const content = readFileSync(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n return Object.keys(pkg.scripts || {});\n } catch {\n return [];\n }\n}\n\nexport function validateHostname(hostname: string): boolean {\n // Basic hostname validation\n const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/;\n return hostnameRegex.test(hostname) && hostname.length <= 253;\n}\n\nexport function validateProjectName(name: string): boolean {\n // Project names should be alphanumeric with dashes/underscores\n const nameRegex = /^[a-zA-Z][a-zA-Z0-9_-]*$/;\n return nameRegex.test(name) && name.length <= 64;\n}\n\nexport function validatePort(port: number): boolean {\n return Number.isInteger(port) && port >= 1024 && port <= 65535;\n}\n\nexport function formatUptime(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) {\n return `${days}d ${hours % 24}h`;\n }\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n }\n if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n}\n\nexport function formatBytes(bytes: number): string {\n const units = ['B', 'KB', 'MB', 'GB'];\n let value = bytes;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n\n return `${value.toFixed(1)}${units[unitIndex]}`;\n}\n\nexport function getPm2ProcessName(projectName: string): string {\n return `bindler:${projectName}`;\n}\n","import { readConfig } from './config.js';\nimport { isPortListening } from './utils.js';\n\nconst PORT_RANGE_START = 3000;\nconst PORT_RANGE_END = 9000;\n\nexport function getUsedPorts(): number[] {\n const config = readConfig();\n return config.projects\n .filter((p) => p.type === 'npm' && p.port)\n .map((p) => p.port as number);\n}\n\nexport function findAvailablePort(startFrom = PORT_RANGE_START): number {\n const usedPorts = new Set(getUsedPorts());\n\n for (let port = startFrom; port <= PORT_RANGE_END; port++) {\n if (!usedPorts.has(port)) {\n return port;\n }\n }\n\n throw new Error(`No available ports in range ${PORT_RANGE_START}-${PORT_RANGE_END}`);\n}\n\nexport async function findAvailablePortWithCheck(startFrom = PORT_RANGE_START): Promise<number> {\n const usedPorts = new Set(getUsedPorts());\n\n for (let port = startFrom; port <= PORT_RANGE_END; port++) {\n if (!usedPorts.has(port)) {\n const listening = await isPortListening(port);\n if (!listening) {\n return port;\n }\n }\n }\n\n throw new Error(`No available ports in range ${PORT_RANGE_START}-${PORT_RANGE_END}`);\n}\n\nexport function isPortAvailable(port: number): boolean {\n const usedPorts = new Set(getUsedPorts());\n return !usedPorts.has(port);\n}\n\nexport function getPortsTable(): Array<{ port: number; project: string; hostname: string }> {\n const config = readConfig();\n return config.projects\n .filter((p) => p.type === 'npm' && p.port)\n .map((p) => ({\n port: p.port as number,\n project: p.name,\n hostname: p.hostname,\n }))\n .sort((a, b) => a.port - b.port);\n}\n","import { existsSync, writeFileSync, copyFileSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { Config, Project } from '../types.js';\nimport { execCommandSafe } from './utils.js';\nimport { getGeneratedDir } from './config.js';\n\nfunction generateLocationBlock(project: Project, indent = ' '): string[] {\n const lines: string[] = [];\n const locationPath = project.basePath || '/';\n const isRootLocation = locationPath === '/';\n\n if (project.type === 'static') {\n lines.push(`${indent}location ${locationPath} {`);\n if (isRootLocation) {\n // Use root for / location\n lines.push(`${indent} root ${project.path};`);\n } else {\n // Use alias for sub-paths\n lines.push(`${indent} alias ${project.path}/;`);\n }\n lines.push(`${indent} index index.html index.htm;`);\n lines.push(`${indent} try_files $uri $uri/ =404;`);\n lines.push(`${indent}}`);\n } else if (project.type === 'npm') {\n lines.push(`${indent}location ${locationPath} {`);\n lines.push(`${indent} proxy_pass http://127.0.0.1:${project.port};`);\n lines.push(`${indent} proxy_http_version 1.1;`);\n lines.push(`${indent} proxy_set_header Upgrade $http_upgrade;`);\n lines.push(`${indent} proxy_set_header Connection 'upgrade';`);\n lines.push(`${indent} proxy_set_header Host $host;`);\n lines.push(`${indent} proxy_set_header X-Real-IP $remote_addr;`);\n lines.push(`${indent} proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;`);\n lines.push(`${indent} proxy_set_header X-Forwarded-Proto $scheme;`);\n lines.push(`${indent} proxy_cache_bypass $http_upgrade;`);\n lines.push(`${indent}}`);\n }\n\n return lines;\n}\n\nexport function generateNginxConfig(config: Config): string {\n const { defaults, projects } = config;\n const listen = defaults.nginxListen;\n\n const lines: string[] = [\n '# Generated by bindler - DO NOT EDIT MANUALLY',\n `# Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n // Group projects by hostname for path-based routing\n const hostGroups = new Map<string, Project[]>();\n\n for (const project of projects) {\n if (project.enabled === false) {\n lines.push(`# Project \"${project.name}\" is disabled`);\n lines.push('');\n continue;\n }\n\n const existing = hostGroups.get(project.hostname) || [];\n existing.push(project);\n hostGroups.set(project.hostname, existing);\n }\n\n // Generate server blocks\n for (const [hostname, hostProjects] of hostGroups) {\n const projectNames = hostProjects.map((p) => p.name).join(', ');\n lines.push(`# Hostname: ${hostname} (${projectNames})`);\n lines.push('server {');\n lines.push(` listen ${listen};`);\n lines.push(` server_name ${hostname};`);\n lines.push('');\n\n // Sort projects by basePath length (longer paths first for nginx matching)\n const sortedProjects = [...hostProjects].sort((a, b) => {\n const pathA = a.basePath || '/';\n const pathB = b.basePath || '/';\n return pathB.length - pathA.length;\n });\n\n for (const project of sortedProjects) {\n lines.push(` # Project: ${project.name} (${project.type})`);\n lines.push(...generateLocationBlock(project));\n lines.push('');\n }\n\n lines.push('}');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nexport function writeNginxConfig(config: Config, dryRun = false): { path: string; content: string } {\n const nginxConfig = generateNginxConfig(config);\n const targetPath = config.defaults.nginxManagedPath;\n\n if (dryRun) {\n return { path: targetPath, content: nginxConfig };\n }\n\n // Ensure directory exists\n const targetDir = dirname(targetPath);\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n\n // Backup existing config\n if (existsSync(targetPath)) {\n const backupDir = join(getGeneratedDir(), 'backups');\n if (!existsSync(backupDir)) {\n mkdirSync(backupDir, { recursive: true });\n }\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const backupPath = join(backupDir, `nginx-${timestamp}.conf`);\n copyFileSync(targetPath, backupPath);\n }\n\n // Also save to generated dir\n const generatedPath = join(getGeneratedDir(), 'nginx.conf');\n writeFileSync(generatedPath, nginxConfig);\n\n // Write to target path\n writeFileSync(targetPath, nginxConfig);\n\n return { path: targetPath, content: nginxConfig };\n}\n\nexport function testNginxConfig(): { success: boolean; output: string } {\n const result = execCommandSafe('nginx -t 2>&1');\n return {\n success: result.success || result.output.includes('syntax is ok'),\n output: result.output || result.error || '',\n };\n}\n\nexport function reloadNginx(): { success: boolean; error?: string } {\n const isMac = process.platform === 'darwin';\n\n if (isMac) {\n // macOS: use brew services or nginx -s reload\n let result = execCommandSafe('brew services reload nginx');\n if (result.success) {\n return { success: true };\n }\n\n result = execCommandSafe('nginx -s reload');\n if (result.success) {\n return { success: true };\n }\n\n return { success: false, error: result.error || 'Failed to reload nginx. Try: brew services restart nginx' };\n }\n\n // Linux: try systemctl first\n let result = execCommandSafe('sudo systemctl reload nginx');\n if (result.success) {\n return { success: true };\n }\n\n // Try service command\n result = execCommandSafe('sudo service nginx reload');\n if (result.success) {\n return { success: true };\n }\n\n // Try nginx -s reload\n result = execCommandSafe('sudo nginx -s reload');\n if (result.success) {\n return { success: true };\n }\n\n return { success: false, error: result.error || 'Failed to reload nginx' };\n}\n\nexport function isNginxInstalled(): boolean {\n const result = execCommandSafe('which nginx');\n return result.success;\n}\n\nexport function isNginxRunning(): boolean {\n const isMac = process.platform === 'darwin';\n\n if (isMac) {\n // macOS: check brew services or pgrep\n let result = execCommandSafe('brew services list | grep nginx');\n if (result.success && result.output.includes('started')) {\n return true;\n }\n } else {\n // Linux: try systemctl\n let result = execCommandSafe('systemctl is-active nginx');\n if (result.success && result.output === 'active') {\n return true;\n }\n }\n\n // Fallback: try pgrep (works on both)\n const result = execCommandSafe('pgrep nginx');\n return result.success;\n}\n\nexport function getNginxVersion(): string | null {\n const result = execCommandSafe('nginx -v 2>&1');\n if (result.success || result.output) {\n const match = (result.output || result.error || '').match(/nginx\\/(\\S+)/);\n return match ? match[1] : null;\n }\n return null;\n}\n","import type { Project, PM2Process } from '../types.js';\nimport { execCommandSafe, spawnInteractive, getPm2ProcessName } from './utils.js';\n\nexport function isPm2Installed(): boolean {\n const result = execCommandSafe('which pm2');\n return result.success;\n}\n\nexport function getPm2List(): PM2Process[] {\n const result = execCommandSafe('pm2 jlist');\n\n if (!result.success) {\n return [];\n }\n\n try {\n const processes = JSON.parse(result.output);\n return processes.map((p: Record<string, unknown>) => ({\n name: p.name as string,\n pm_id: p.pm_id as number,\n status: (p.pm2_env as Record<string, unknown>)?.status as PM2Process['status'],\n cpu: p.monit ? (p.monit as Record<string, number>).cpu : 0,\n memory: p.monit ? (p.monit as Record<string, number>).memory : 0,\n uptime: (p.pm2_env as Record<string, unknown>)?.pm_uptime\n ? Date.now() - ((p.pm2_env as Record<string, unknown>).pm_uptime as number)\n : 0,\n restarts: (p.pm2_env as Record<string, unknown>)?.restart_time as number || 0,\n }));\n } catch {\n return [];\n }\n}\n\nexport function getProcessByName(name: string): PM2Process | undefined {\n const pm2Name = getPm2ProcessName(name);\n const processes = getPm2List();\n return processes.find((p) => p.name === pm2Name);\n}\n\nexport function isProcessRunning(name: string): boolean {\n const process = getProcessByName(name);\n return process?.status === 'online';\n}\n\nexport function startProject(project: Project): { success: boolean; error?: string } {\n if (project.type !== 'npm') {\n return { success: false, error: 'Only npm projects can be started with PM2' };\n }\n\n if (!project.start) {\n return { success: false, error: 'No start command configured' };\n }\n\n const pm2Name = getPm2ProcessName(project.name);\n const existingProcess = getProcessByName(project.name);\n\n // Build environment variables string\n const envVars: string[] = [];\n if (project.env) {\n for (const [key, value] of Object.entries(project.env)) {\n envVars.push(`${key}=${value}`);\n }\n }\n\n let command: string;\n\n if (existingProcess) {\n // Process exists, restart it\n command = `pm2 restart \"${pm2Name}\"`;\n } else {\n // Start new process\n const envFlags = envVars.length > 0 ? envVars.map((e) => `--env ${e}`).join(' ') : '';\n command = `pm2 start --name \"${pm2Name}\" --cwd \"${project.path}\" ${envFlags} -- bash -lc \"${project.start}\"`;\n }\n\n const result = execCommandSafe(command);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n // Save PM2 process list\n execCommandSafe('pm2 save');\n\n return { success: true };\n}\n\nexport function stopProject(name: string): { success: boolean; error?: string } {\n const pm2Name = getPm2ProcessName(name);\n const result = execCommandSafe(`pm2 stop \"${pm2Name}\"`);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n execCommandSafe('pm2 save');\n return { success: true };\n}\n\nexport function restartProject(name: string): { success: boolean; error?: string } {\n const pm2Name = getPm2ProcessName(name);\n const result = execCommandSafe(`pm2 restart \"${pm2Name}\"`);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n execCommandSafe('pm2 save');\n return { success: true };\n}\n\nexport function deleteProject(name: string): { success: boolean; error?: string } {\n const pm2Name = getPm2ProcessName(name);\n const result = execCommandSafe(`pm2 delete \"${pm2Name}\"`);\n\n if (!result.success) {\n // It's okay if the process doesn't exist\n if (result.error?.includes('not found')) {\n return { success: true };\n }\n return { success: false, error: result.error };\n }\n\n execCommandSafe('pm2 save');\n return { success: true };\n}\n\nexport async function showLogs(name: string, follow = false, lines = 200): Promise<number | null> {\n const pm2Name = getPm2ProcessName(name);\n const args = ['logs', pm2Name, '--lines', String(lines)];\n\n if (!follow) {\n args.push('--nostream');\n }\n\n return spawnInteractive('pm2', args);\n}\n\nexport function startAllProjects(projects: Project[]): Array<{ name: string; success: boolean; error?: string }> {\n return projects\n .filter((p) => p.type === 'npm')\n .map((project) => ({\n name: project.name,\n ...startProject(project),\n }));\n}\n\nexport function stopAllProjects(projects: Project[]): Array<{ name: string; success: boolean; error?: string }> {\n return projects\n .filter((p) => p.type === 'npm')\n .map((project) => ({\n name: project.name,\n ...stopProject(project.name),\n }));\n}\n\nexport function restartAllProjects(projects: Project[]): Array<{ name: string; success: boolean; error?: string }> {\n return projects\n .filter((p) => p.type === 'npm')\n .map((project) => ({\n name: project.name,\n ...restartProject(project.name),\n }));\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { listProjects } from '../lib/config.js';\nimport { getProcessByName } from '../lib/pm2.js';\nimport { getPm2ProcessName } from '../lib/utils.js';\n\nexport async function listCommand(): Promise<void> {\n const projects = listProjects();\n\n if (projects.length === 0) {\n console.log(chalk.yellow('No projects registered.'));\n console.log(chalk.dim(`Run ${chalk.cyan('bindler new')} to create one.`));\n return;\n }\n\n const table = new Table({\n head: [\n chalk.cyan('Name'),\n chalk.cyan('Type'),\n chalk.cyan('Hostname'),\n chalk.cyan('Port'),\n chalk.cyan('Path'),\n chalk.cyan('Status'),\n ],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const project of projects) {\n let status = '-';\n\n if (project.type === 'npm') {\n const process = getProcessByName(project.name);\n if (process) {\n status = process.status === 'online'\n ? chalk.green('online')\n : process.status === 'stopped'\n ? chalk.yellow('stopped')\n : chalk.red(process.status);\n } else {\n status = chalk.dim('not started');\n }\n } else {\n status = project.enabled !== false ? chalk.green('serving') : chalk.yellow('disabled');\n }\n\n if (project.enabled === false) {\n status = chalk.yellow('disabled');\n }\n\n table.push([\n project.name,\n project.type,\n project.hostname,\n project.port?.toString() || '-',\n project.path,\n status,\n ]);\n }\n\n console.log(table.toString());\n console.log(chalk.dim(`\\n${projects.length} project(s) registered`));\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { listProjects } from '../lib/config.js';\nimport { getProcessByName, getPm2List } from '../lib/pm2.js';\nimport { isPortListening, formatUptime, formatBytes, getPm2ProcessName } from '../lib/utils.js';\nimport type { ProjectStatus } from '../types.js';\n\nexport async function statusCommand(): Promise<void> {\n const projects = listProjects();\n\n if (projects.length === 0) {\n console.log(chalk.yellow('No projects registered.'));\n return;\n }\n\n const statuses: ProjectStatus[] = [];\n\n for (const project of projects) {\n const status: ProjectStatus = { ...project };\n\n if (project.type === 'npm') {\n const process = getProcessByName(project.name);\n status.pm2Name = getPm2ProcessName(project.name);\n\n if (process) {\n status.pm2Status = process.status;\n } else {\n status.pm2Status = 'not_managed';\n }\n\n if (project.port) {\n status.portListening = await isPortListening(project.port);\n }\n } else {\n status.pm2Status = 'n/a';\n }\n\n statuses.push(status);\n }\n\n const table = new Table({\n head: [\n chalk.cyan('Name'),\n chalk.cyan('Type'),\n chalk.cyan('Hostname'),\n chalk.cyan('Port'),\n chalk.cyan('PM2 Status'),\n chalk.cyan('Port Check'),\n ],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const status of statuses) {\n let pm2StatusStr = '-';\n let portCheckStr = '-';\n\n if (status.type === 'npm') {\n switch (status.pm2Status) {\n case 'online':\n pm2StatusStr = chalk.green('online');\n break;\n case 'stopped':\n pm2StatusStr = chalk.yellow('stopped');\n break;\n case 'errored':\n pm2StatusStr = chalk.red('errored');\n break;\n case 'not_managed':\n pm2StatusStr = chalk.dim('not started');\n break;\n default:\n pm2StatusStr = chalk.dim(status.pm2Status || '-');\n }\n\n portCheckStr = status.portListening\n ? chalk.green('listening')\n : chalk.red('not listening');\n }\n\n if (status.enabled === false) {\n pm2StatusStr = chalk.yellow('disabled');\n portCheckStr = chalk.dim('-');\n }\n\n table.push([\n status.name,\n status.type,\n status.hostname,\n status.port?.toString() || '-',\n pm2StatusStr,\n portCheckStr,\n ]);\n }\n\n console.log(table.toString());\n\n // Show PM2 process details for running apps\n const runningProcesses = getPm2List().filter((p) => p.name.startsWith('bindler:'));\n\n if (runningProcesses.length > 0) {\n console.log(chalk.bold('\\nPM2 Process Details:'));\n\n const detailTable = new Table({\n head: [\n chalk.cyan('Process'),\n chalk.cyan('CPU'),\n chalk.cyan('Memory'),\n chalk.cyan('Uptime'),\n chalk.cyan('Restarts'),\n ],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const proc of runningProcesses) {\n detailTable.push([\n proc.name.replace('bindler:', ''),\n `${proc.cpu}%`,\n formatBytes(proc.memory),\n formatUptime(proc.uptime),\n String(proc.restarts),\n ]);\n }\n\n console.log(detailTable.toString());\n }\n}\n","import chalk from 'chalk';\nimport { getProject, listProjects } from '../lib/config.js';\nimport { startProject, startAllProjects } from '../lib/pm2.js';\n\ninterface StartOptions {\n all?: boolean;\n}\n\nexport async function startCommand(name: string | undefined, options: StartOptions): Promise<void> {\n if (options.all) {\n const projects = listProjects();\n const npmProjects = projects.filter((p) => p.type === 'npm');\n\n if (npmProjects.length === 0) {\n console.log(chalk.yellow('No npm projects to start.'));\n return;\n }\n\n console.log(chalk.blue(`Starting ${npmProjects.length} npm project(s)...`));\n\n const results = startAllProjects(npmProjects);\n\n for (const result of results) {\n if (result.success) {\n console.log(chalk.green(` ✓ ${result.name}`));\n } else {\n console.log(chalk.red(` ✗ ${result.name}: ${result.error}`));\n }\n }\n\n const succeeded = results.filter((r) => r.success).length;\n console.log(chalk.dim(`\\n${succeeded}/${results.length} started successfully`));\n return;\n }\n\n if (!name) {\n console.error(chalk.red('Error: Project name is required. Use --all to start all projects.'));\n process.exit(1);\n }\n\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n if (project.type !== 'npm') {\n console.log(chalk.blue(`Project \"${name}\" is a static site - no process to start.`));\n console.log(chalk.dim('Static sites are served directly by nginx.'));\n return;\n }\n\n console.log(chalk.blue(`Starting ${name}...`));\n\n const result = startProject(project);\n\n if (result.success) {\n console.log(chalk.green(`✓ ${name} started successfully`));\n console.log(chalk.dim(` Port: ${project.port}`));\n console.log(chalk.dim(` URL: https://${project.hostname}`));\n } else {\n console.error(chalk.red(`✗ Failed to start ${name}: ${result.error}`));\n process.exit(1);\n }\n}\n","import chalk from 'chalk';\nimport { getProject, listProjects } from '../lib/config.js';\nimport { stopProject, stopAllProjects } from '../lib/pm2.js';\n\ninterface StopOptions {\n all?: boolean;\n}\n\nexport async function stopCommand(name: string | undefined, options: StopOptions): Promise<void> {\n if (options.all) {\n const projects = listProjects();\n const npmProjects = projects.filter((p) => p.type === 'npm');\n\n if (npmProjects.length === 0) {\n console.log(chalk.yellow('No npm projects to stop.'));\n return;\n }\n\n console.log(chalk.blue(`Stopping ${npmProjects.length} npm project(s)...`));\n\n const results = stopAllProjects(npmProjects);\n\n for (const result of results) {\n if (result.success) {\n console.log(chalk.green(` ✓ ${result.name}`));\n } else {\n console.log(chalk.red(` ✗ ${result.name}: ${result.error}`));\n }\n }\n\n const succeeded = results.filter((r) => r.success).length;\n console.log(chalk.dim(`\\n${succeeded}/${results.length} stopped successfully`));\n return;\n }\n\n if (!name) {\n console.error(chalk.red('Error: Project name is required. Use --all to stop all projects.'));\n process.exit(1);\n }\n\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n if (project.type !== 'npm') {\n console.log(chalk.yellow(`Project \"${name}\" is a static site - no process to stop.`));\n return;\n }\n\n console.log(chalk.blue(`Stopping ${name}...`));\n\n const result = stopProject(name);\n\n if (result.success) {\n console.log(chalk.green(`✓ ${name} stopped successfully`));\n } else {\n console.error(chalk.red(`✗ Failed to stop ${name}: ${result.error}`));\n process.exit(1);\n }\n}\n","import chalk from 'chalk';\nimport { getProject, listProjects } from '../lib/config.js';\nimport { restartProject, restartAllProjects, getProcessByName, startProject } from '../lib/pm2.js';\n\ninterface RestartOptions {\n all?: boolean;\n}\n\nexport async function restartCommand(name: string | undefined, options: RestartOptions): Promise<void> {\n if (options.all) {\n const projects = listProjects();\n const npmProjects = projects.filter((p) => p.type === 'npm');\n\n if (npmProjects.length === 0) {\n console.log(chalk.yellow('No npm projects to restart.'));\n return;\n }\n\n console.log(chalk.blue(`Restarting ${npmProjects.length} npm project(s)...`));\n\n const results = restartAllProjects(npmProjects);\n\n for (const result of results) {\n if (result.success) {\n console.log(chalk.green(` ✓ ${result.name}`));\n } else {\n console.log(chalk.red(` ✗ ${result.name}: ${result.error}`));\n }\n }\n\n const succeeded = results.filter((r) => r.success).length;\n console.log(chalk.dim(`\\n${succeeded}/${results.length} restarted successfully`));\n return;\n }\n\n if (!name) {\n console.error(chalk.red('Error: Project name is required. Use --all to restart all projects.'));\n process.exit(1);\n }\n\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n if (project.type !== 'npm') {\n console.log(chalk.yellow(`Project \"${name}\" is a static site - no process to restart.`));\n return;\n }\n\n console.log(chalk.blue(`Restarting ${name}...`));\n\n // Check if process exists\n const process = getProcessByName(name);\n\n let result;\n if (process) {\n result = restartProject(name);\n } else {\n // Process doesn't exist, start it\n console.log(chalk.dim('Process not running, starting...'));\n result = startProject(project);\n }\n\n if (result.success) {\n console.log(chalk.green(`✓ ${name} restarted successfully`));\n } else {\n console.error(chalk.red(`✗ Failed to restart ${name}: ${result.error}`));\n process.exit(1);\n }\n}\n","import chalk from 'chalk';\nimport { getProject } from '../lib/config.js';\nimport { showLogs, getProcessByName } from '../lib/pm2.js';\n\ninterface LogsOptions {\n follow?: boolean;\n lines?: number;\n}\n\nexport async function logsCommand(name: string, options: LogsOptions): Promise<void> {\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n if (project.type !== 'npm') {\n console.log(chalk.yellow(`Project \"${name}\" is a static site - no logs available.`));\n console.log(chalk.dim('Check nginx access/error logs instead:'));\n console.log(chalk.dim(' /var/log/nginx/access.log'));\n console.log(chalk.dim(' /var/log/nginx/error.log'));\n return;\n }\n\n const process = getProcessByName(name);\n\n if (!process) {\n console.log(chalk.yellow(`Project \"${name}\" has not been started yet.`));\n console.log(chalk.dim(`Run ${chalk.cyan(`bindler start ${name}`)} first.`));\n return;\n }\n\n const lines = options.lines || 200;\n const follow = options.follow || false;\n\n if (follow) {\n console.log(chalk.dim(`Following logs for ${name}... (Ctrl+C to exit)`));\n }\n\n await showLogs(name, follow, lines);\n}\n","import chalk from 'chalk';\nimport { getProject, updateProject } from '../lib/config.js';\nimport { validateHostname, validatePort } from '../lib/utils.js';\nimport { isPortAvailable } from '../lib/ports.js';\nimport type { Project } from '../types.js';\n\ninterface UpdateOptions {\n hostname?: string;\n port?: string;\n start?: string;\n path?: string;\n env?: string[];\n enable?: boolean;\n disable?: boolean;\n}\n\nexport async function updateCommand(name: string, options: UpdateOptions): Promise<void> {\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n const updates: Partial<Project> = {};\n\n // Handle hostname update\n if (options.hostname) {\n if (!validateHostname(options.hostname)) {\n console.error(chalk.red('Error: Invalid hostname format'));\n process.exit(1);\n }\n updates.hostname = options.hostname;\n }\n\n // Handle port update\n if (options.port) {\n const port = parseInt(options.port, 10);\n if (!validatePort(port)) {\n console.error(chalk.red('Error: Invalid port. Use a number between 1024 and 65535.'));\n process.exit(1);\n }\n if (!isPortAvailable(port) && port !== project.port) {\n console.error(chalk.red(`Error: Port ${port} is already in use by another project.`));\n process.exit(1);\n }\n updates.port = port;\n\n // Also update PORT env var if it exists\n if (project.env?.PORT) {\n updates.env = { ...project.env, PORT: String(port) };\n }\n }\n\n // Handle start command update\n if (options.start) {\n if (project.type !== 'npm') {\n console.error(chalk.red('Error: Start command only applies to npm projects'));\n process.exit(1);\n }\n updates.start = options.start;\n }\n\n // Handle path update\n if (options.path) {\n updates.path = options.path;\n }\n\n // Handle env updates\n if (options.env && options.env.length > 0) {\n const env = { ...(project.env || {}) };\n for (const envStr of options.env) {\n const [key, ...valueParts] = envStr.split('=');\n if (!key) {\n console.error(chalk.red(`Error: Invalid env format: ${envStr}. Use KEY=value`));\n process.exit(1);\n }\n env[key] = valueParts.join('=');\n }\n updates.env = env;\n }\n\n // Handle enable/disable\n if (options.enable) {\n updates.enabled = true;\n } else if (options.disable) {\n updates.enabled = false;\n }\n\n if (Object.keys(updates).length === 0) {\n console.log(chalk.yellow('No updates specified.'));\n console.log(chalk.dim('Available options: --hostname, --port, --start, --path, --env, --enable, --disable'));\n return;\n }\n\n try {\n updateProject(name, updates);\n\n console.log(chalk.green(`✓ Project \"${name}\" updated successfully`));\n\n for (const [key, value] of Object.entries(updates)) {\n console.log(chalk.dim(` ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`));\n }\n\n console.log(chalk.dim(`\\nRun ${chalk.cyan('sudo bindler apply')} to apply changes to nginx.`));\n\n if (project.type === 'npm' && (updates.port || updates.start || updates.env)) {\n console.log(chalk.dim(`Run ${chalk.cyan(`bindler restart ${name}`)} to apply changes to the running process.`));\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : error}`));\n process.exit(1);\n }\n}\n","import { writeFileSync, readFileSync, unlinkSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport chalk from 'chalk';\nimport { getProject, updateProject, readConfig, writeConfig } from '../lib/config.js';\nimport { spawnInteractive } from '../lib/utils.js';\nimport type { Project } from '../types.js';\n\nexport async function editCommand(name: string): Promise<void> {\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n const editor = process.env.EDITOR || process.env.VISUAL || 'vi';\n const tmpFile = join(tmpdir(), `bindler-${name}-${Date.now()}.json`);\n\n // Write project config to temp file\n writeFileSync(tmpFile, JSON.stringify(project, null, 2) + '\\n');\n\n console.log(chalk.dim(`Opening ${name} config in ${editor}...`));\n\n // Open editor\n const exitCode = await spawnInteractive(editor, [tmpFile]);\n\n if (exitCode !== 0) {\n console.error(chalk.red('Editor exited with error'));\n unlinkSync(tmpFile);\n process.exit(1);\n }\n\n // Read edited content\n let editedContent: string;\n try {\n editedContent = readFileSync(tmpFile, 'utf-8');\n } catch (error) {\n console.error(chalk.red('Failed to read edited file'));\n process.exit(1);\n } finally {\n unlinkSync(tmpFile);\n }\n\n // Parse edited JSON\n let editedProject: Project;\n try {\n editedProject = JSON.parse(editedContent);\n } catch (error) {\n console.error(chalk.red('Error: Invalid JSON in edited file'));\n process.exit(1);\n }\n\n // Validate that name wasn't changed\n if (editedProject.name !== project.name) {\n console.error(chalk.red('Error: Cannot change project name via edit. Use a new project instead.'));\n process.exit(1);\n }\n\n // Check if anything changed\n const originalStr = JSON.stringify(project);\n const editedStr = JSON.stringify(editedProject);\n\n if (originalStr === editedStr) {\n console.log(chalk.yellow('No changes made.'));\n return;\n }\n\n // Update the project\n try {\n const config = readConfig();\n const index = config.projects.findIndex((p) => p.name === name);\n\n if (index === -1) {\n console.error(chalk.red('Error: Project not found'));\n process.exit(1);\n }\n\n config.projects[index] = editedProject;\n writeConfig(config);\n\n console.log(chalk.green(`✓ Project \"${name}\" updated successfully`));\n console.log(chalk.dim(`\\nRun ${chalk.cyan('sudo bindler apply')} to apply changes to nginx.`));\n } catch (error) {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : error}`));\n process.exit(1);\n }\n}\n","import inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { getProject, removeProject } from '../lib/config.js';\nimport { deleteProject as deletePm2Process, getProcessByName } from '../lib/pm2.js';\n\ninterface RemoveOptions {\n force?: boolean;\n apply?: boolean;\n}\n\nexport async function removeCommand(name: string, options: RemoveOptions): Promise<void> {\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n // Confirm removal unless --force\n if (!options.force) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `Are you sure you want to remove project \"${name}\" (${project.hostname})?`,\n default: false,\n },\n ]);\n\n if (!confirm) {\n console.log(chalk.yellow('Cancelled.'));\n return;\n }\n }\n\n // Stop and delete PM2 process if it exists\n if (project.type === 'npm') {\n const process = getProcessByName(name);\n if (process) {\n console.log(chalk.dim('Stopping PM2 process...'));\n deletePm2Process(name);\n }\n }\n\n // Remove from config\n try {\n removeProject(name);\n console.log(chalk.green(`✓ Project \"${name}\" removed from registry`));\n console.log(chalk.dim(`\\nRun ${chalk.cyan('sudo bindler apply')} to update nginx configuration.`));\n console.log(chalk.yellow('\\nNote: The project files and Cloudflare DNS routes were not removed.'));\n console.log(chalk.dim(` Project path: ${project.path}`));\n console.log(chalk.dim(` To remove DNS route manually: cloudflared tunnel route dns --remove ${project.hostname}`));\n } catch (error) {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : error}`));\n process.exit(1);\n }\n}\n","import chalk from 'chalk';\nimport { readConfig, getDefaults } from '../lib/config.js';\nimport { generateNginxConfig, writeNginxConfig, testNginxConfig, reloadNginx } from '../lib/nginx.js';\nimport { routeDnsForAllProjects, isCloudflaredInstalled } from '../lib/cloudflare.js';\nimport { execCommandSafe } from '../lib/utils.js';\n\ninterface ApplyOptions {\n dryRun?: boolean;\n noReload?: boolean;\n noCloudflare?: boolean;\n ssl?: boolean;\n}\n\nexport async function applyCommand(options: ApplyOptions): Promise<void> {\n const config = readConfig();\n const defaults = getDefaults();\n\n if (config.projects.length === 0) {\n console.log(chalk.yellow('No projects registered. Nothing to apply.'));\n return;\n }\n\n console.log(chalk.blue('Applying configuration...\\n'));\n\n // Step 1: Generate nginx config\n console.log(chalk.dim('Generating nginx configuration...'));\n\n if (options.dryRun) {\n const nginxConfig = generateNginxConfig(config);\n console.log(chalk.cyan('\\n--- Generated nginx config (dry-run) ---\\n'));\n console.log(nginxConfig);\n console.log(chalk.cyan('--- End of config ---\\n'));\n console.log(chalk.yellow('Dry run mode - no changes were made.'));\n return;\n }\n\n // Step 2: Write nginx config\n try {\n const { path, content } = writeNginxConfig(config);\n console.log(chalk.green(` ✓ Wrote nginx config to ${path}`));\n } catch (error) {\n const errMsg = error instanceof Error ? error.message : String(error);\n console.error(chalk.red(` ✗ Failed to write nginx config: ${errMsg}`));\n if (errMsg.includes('EACCES') || errMsg.includes('permission denied')) {\n console.log(chalk.yellow(`\\nTry running with sudo: ${chalk.cyan('sudo bindler apply')}`));\n }\n process.exit(1);\n }\n\n // Step 3: Test nginx config\n console.log(chalk.dim('Testing nginx configuration...'));\n const testResult = testNginxConfig();\n\n if (!testResult.success) {\n console.error(chalk.red(' ✗ Nginx configuration test failed:'));\n console.error(chalk.red(testResult.output));\n console.log(chalk.yellow('\\nConfiguration was written but nginx was NOT reloaded.'));\n console.log(chalk.dim('Fix the configuration and run `sudo bindler apply` again.'));\n process.exit(1);\n }\n\n console.log(chalk.green(' ✓ Nginx configuration test passed'));\n\n // Step 4: Reload nginx\n if (!options.noReload) {\n console.log(chalk.dim('Reloading nginx...'));\n const reloadResult = reloadNginx();\n\n if (!reloadResult.success) {\n console.error(chalk.red(` ✗ Failed to reload nginx: ${reloadResult.error}`));\n console.log(chalk.dim('You may need to reload nginx manually: sudo systemctl reload nginx'));\n process.exit(1);\n }\n\n console.log(chalk.green(' ✓ Nginx reloaded successfully'));\n } else {\n console.log(chalk.yellow(' - Skipped nginx reload (--no-reload)'));\n }\n\n // Step 5: Cloudflare DNS routing (tunnel mode only)\n const isDirectMode = defaults.mode === 'direct';\n\n if (isDirectMode) {\n console.log(chalk.dim('\\n - Direct mode: skipping Cloudflare DNS routes'));\n } else if (!options.noCloudflare && defaults.applyCloudflareDnsRoutes) {\n console.log(chalk.dim('\\nConfiguring Cloudflare DNS routes...'));\n\n if (!isCloudflaredInstalled()) {\n console.log(chalk.yellow(' - cloudflared not installed, skipping DNS routes'));\n } else {\n const dnsResults = routeDnsForAllProjects();\n\n if (dnsResults.length === 0) {\n console.log(chalk.dim(' No hostnames to route'));\n } else {\n for (const result of dnsResults) {\n if (result.skipped) {\n console.log(chalk.dim(` - ${result.hostname} (local - skipped)`));\n } else if (result.success) {\n const msg = result.output?.includes('already exists') ? 'exists' : 'routed';\n console.log(chalk.green(` ✓ ${result.hostname} (${msg})`));\n } else {\n console.log(chalk.red(` ✗ ${result.hostname}: ${result.error}`));\n }\n }\n }\n }\n } else if (options.noCloudflare) {\n console.log(chalk.dim('\\n - Skipped Cloudflare DNS routes (--no-cloudflare)'));\n }\n\n // Step 6: SSL certificate setup (direct mode only)\n if (isDirectMode && defaults.sslEnabled && (options.ssl !== false)) {\n console.log(chalk.dim('\\nSetting up SSL certificates...'));\n\n const hostnames = config.projects\n .filter((p) => p.enabled !== false && !p.local)\n .map((p) => p.hostname);\n\n if (hostnames.length === 0) {\n console.log(chalk.dim(' No hostnames to secure'));\n } else {\n const certbotResult = execCommandSafe('which certbot');\n if (!certbotResult.success) {\n console.log(chalk.yellow(' - certbot not installed, skipping SSL'));\n console.log(chalk.dim(' Run: bindler setup --direct'));\n } else {\n for (const hostname of hostnames) {\n console.log(chalk.dim(` Requesting certificate for ${hostname}...`));\n const email = defaults.sslEmail || 'admin@' + hostname.split('.').slice(-2).join('.');\n const result = execCommandSafe(\n `sudo certbot --nginx -d ${hostname} --non-interactive --agree-tos --email ${email} 2>&1`\n );\n\n if (result.success || result.output?.includes('Certificate not yet due for renewal')) {\n console.log(chalk.green(` ✓ ${hostname} (secured)`));\n } else if (result.output?.includes('already exists')) {\n console.log(chalk.green(` ✓ ${hostname} (exists)`));\n } else {\n console.log(chalk.yellow(` ! ${hostname}: ${result.error || 'failed'}`));\n console.log(chalk.dim(' Run manually: sudo certbot --nginx -d ' + hostname));\n }\n }\n }\n }\n }\n\n // Summary\n console.log(chalk.green('\\n✓ Configuration applied successfully!'));\n console.log(chalk.dim(`\\n${config.projects.length} project(s) configured:`));\n\n for (const project of config.projects) {\n const status = project.enabled !== false ? chalk.green('enabled') : chalk.yellow('disabled');\n console.log(chalk.dim(` - ${project.name} → ${project.hostname} (${status})`));\n }\n}\n","import { execCommandSafe } from './utils.js';\nimport { readConfig } from './config.js';\n\nexport function isCloudflaredInstalled(): boolean {\n const result = execCommandSafe('which cloudflared');\n return result.success;\n}\n\nexport function getCloudflaredVersion(): string | null {\n const result = execCommandSafe('cloudflared --version');\n if (result.success) {\n const match = result.output.match(/cloudflared version (\\S+)/);\n return match ? match[1] : result.output;\n }\n return null;\n}\n\nexport function listTunnels(): Array<{ id: string; name: string; createdAt: string }> {\n const result = execCommandSafe('cloudflared tunnel list --output json');\n\n if (!result.success) {\n return [];\n }\n\n try {\n const tunnels = JSON.parse(result.output);\n return tunnels.map((t: Record<string, unknown>) => ({\n id: t.id as string,\n name: t.name as string,\n createdAt: t.created_at as string,\n }));\n } catch {\n return [];\n }\n}\n\nexport function getTunnelByName(name: string): { id: string; name: string } | null {\n const tunnels = listTunnels();\n const tunnel = tunnels.find((t) => t.name === name);\n return tunnel ? { id: tunnel.id, name: tunnel.name } : null;\n}\n\nexport function routeDns(tunnelName: string, hostname: string): { success: boolean; error?: string; output?: string } {\n const result = execCommandSafe(`cloudflared tunnel route dns \"${tunnelName}\" \"${hostname}\"`);\n\n if (!result.success) {\n // Check if it's just \"already exists\" which is fine\n if (result.error?.includes('already exists') || result.output?.includes('already exists')) {\n return { success: true, output: 'DNS route already exists' };\n }\n return { success: false, error: result.error };\n }\n\n return { success: true, output: result.output };\n}\n\nexport function routeDnsForAllProjects(): Array<{ hostname: string; success: boolean; error?: string; output?: string; skipped?: boolean }> {\n const config = readConfig();\n const { tunnelName, applyCloudflareDnsRoutes } = config.defaults;\n\n if (!applyCloudflareDnsRoutes) {\n return [];\n }\n\n const results: Array<{ hostname: string; success: boolean; error?: string; output?: string; skipped?: boolean }> = [];\n\n for (const project of config.projects) {\n if (project.enabled === false) {\n continue;\n }\n\n // Skip local projects\n if (project.local) {\n results.push({\n hostname: project.hostname,\n success: true,\n skipped: true,\n output: 'Local project - skipped',\n });\n continue;\n }\n\n const result = routeDns(tunnelName, project.hostname);\n results.push({\n hostname: project.hostname,\n ...result,\n });\n }\n\n return results;\n}\n\nexport function isTunnelRunning(tunnelName: string): boolean {\n // Check if cloudflared process is running for this tunnel\n const result = execCommandSafe(`pgrep -f \"cloudflared.*tunnel.*run.*${tunnelName}\"`);\n return result.success;\n}\n\nexport function getTunnelInfo(tunnelName: string): { exists: boolean; running: boolean; id?: string } {\n const tunnel = getTunnelByName(tunnelName);\n\n if (!tunnel) {\n return { exists: false, running: false };\n }\n\n return {\n exists: true,\n running: isTunnelRunning(tunnelName),\n id: tunnel.id,\n };\n}\n","import chalk from 'chalk';\nimport { existsSync } from 'node:fs';\nimport { configExists, getConfigPath, getDefaults, readConfig } from '../lib/config.js';\nimport { isNginxInstalled, isNginxRunning, getNginxVersion } from '../lib/nginx.js';\nimport { isPm2Installed, getPm2List } from '../lib/pm2.js';\nimport { isCloudflaredInstalled, getCloudflaredVersion, getTunnelInfo } from '../lib/cloudflare.js';\nimport { commandExists, execCommandSafe } from '../lib/utils.js';\n\ninterface CheckResult {\n name: string;\n status: 'ok' | 'warning' | 'error';\n message: string;\n fix?: string;\n}\n\nexport async function doctorCommand(): Promise<void> {\n console.log(chalk.blue('Running diagnostics...\\n'));\n\n const checks: CheckResult[] = [];\n\n // Check Node.js version\n const nodeVersion = process.version;\n const nodeMajor = parseInt(nodeVersion.slice(1).split('.')[0], 10);\n checks.push({\n name: 'Node.js',\n status: nodeMajor >= 18 ? 'ok' : 'warning',\n message: `Version ${nodeVersion}`,\n fix: nodeMajor < 18 ? 'Upgrade to Node.js 18 or later' : undefined,\n });\n\n // Check nginx\n if (isNginxInstalled()) {\n const version = getNginxVersion();\n if (isNginxRunning()) {\n checks.push({\n name: 'nginx',\n status: 'ok',\n message: `Installed (${version || 'version unknown'}) and running`,\n });\n\n // macOS: Check if nginx is running as current user (not root/nobody)\n const isMac = process.platform === 'darwin';\n if (isMac) {\n const currentUser = process.env.USER || '';\n const psResult = execCommandSafe('ps aux | grep \"nginx: worker\" | grep -v grep | head -1');\n if (psResult.success && psResult.output) {\n const nginxUser = psResult.output.split(/\\s+/)[0];\n if (nginxUser && nginxUser !== currentUser && (nginxUser === 'nobody' || nginxUser === 'root')) {\n checks.push({\n name: 'nginx user',\n status: 'warning',\n message: `nginx running as \"${nginxUser}\" (should be \"${currentUser}\")`,\n fix: `Fix permissions: sudo chown -R ${currentUser}:staff /opt/homebrew/var/log/nginx /opt/homebrew/var/run && sudo killall nginx && brew services start nginx`,\n });\n } else {\n checks.push({\n name: 'nginx user',\n status: 'ok',\n message: `Running as \"${nginxUser}\"`,\n });\n }\n }\n }\n } else {\n const isMac = process.platform === 'darwin';\n checks.push({\n name: 'nginx',\n status: 'warning',\n message: `Installed (${version || 'version unknown'}) but not running`,\n fix: isMac ? 'Start nginx: brew services start nginx' : 'Start nginx: sudo systemctl start nginx',\n });\n }\n } else {\n checks.push({\n name: 'nginx',\n status: 'error',\n message: 'Not installed',\n fix: 'Run `bindler setup` to install',\n });\n }\n\n // Check PM2\n if (isPm2Installed()) {\n const processes = getPm2List();\n const bindlerProcesses = processes.filter((p) => p.name.startsWith('bindler:'));\n checks.push({\n name: 'PM2',\n status: 'ok',\n message: `Installed, ${bindlerProcesses.length} bindler process(es) managed`,\n });\n } else {\n checks.push({\n name: 'PM2',\n status: 'error',\n message: 'Not installed',\n fix: 'Run `bindler setup` to install',\n });\n }\n\n // Check cloudflared\n if (isCloudflaredInstalled()) {\n const version = getCloudflaredVersion();\n checks.push({\n name: 'cloudflared',\n status: 'ok',\n message: `Installed (${version || 'version unknown'})`,\n });\n\n // Check tunnel configuration\n if (configExists()) {\n const defaults = getDefaults();\n const tunnelInfo = getTunnelInfo(defaults.tunnelName);\n\n if (tunnelInfo.exists) {\n checks.push({\n name: 'Cloudflare Tunnel',\n status: tunnelInfo.running ? 'ok' : 'warning',\n message: tunnelInfo.running\n ? `Tunnel \"${defaults.tunnelName}\" exists and running`\n : `Tunnel \"${defaults.tunnelName}\" exists but not running`,\n fix: !tunnelInfo.running\n ? `Start tunnel: cloudflared tunnel run ${defaults.tunnelName}`\n : undefined,\n });\n } else {\n checks.push({\n name: 'Cloudflare Tunnel',\n status: 'warning',\n message: `Tunnel \"${defaults.tunnelName}\" not found`,\n fix: `Create tunnel: cloudflared tunnel create ${defaults.tunnelName}`,\n });\n }\n }\n } else {\n checks.push({\n name: 'cloudflared',\n status: 'warning',\n message: 'Not installed (optional, for Cloudflare Tunnel)',\n fix: 'Run `bindler setup` or visit https://pkg.cloudflare.com/index.html',\n });\n }\n\n // Check bindler config\n if (configExists()) {\n const config = readConfig();\n checks.push({\n name: 'Bindler config',\n status: 'ok',\n message: `${config.projects.length} project(s) registered`,\n });\n\n // macOS: Check for projects in protected folders\n const isMac = process.platform === 'darwin';\n if (isMac && config.projects.length > 0) {\n const homeDir = process.env.HOME || '';\n const protectedPaths = ['/Desktop/', '/Documents/', '/Downloads/'];\n const protectedProjects = config.projects.filter((p) =>\n protectedPaths.some((pp) => p.path.startsWith(homeDir + pp))\n );\n\n if (protectedProjects.length > 0) {\n const currentUser = process.env.USER || '';\n const psResult = execCommandSafe('ps aux | grep \"nginx: worker\" | grep -v grep | head -1');\n const nginxUser = psResult.success && psResult.output ? psResult.output.split(/\\s+/)[0] : '';\n\n if (nginxUser && nginxUser !== currentUser) {\n checks.push({\n name: 'Protected folders',\n status: 'warning',\n message: `${protectedProjects.length} project(s) in ~/Desktop, ~/Documents, or ~/Downloads`,\n fix: `nginx must run as \"${currentUser}\" to access these folders. Run: sudo chown -R ${currentUser}:staff /opt/homebrew/var/log/nginx /opt/homebrew/var/run && sudo killall nginx && brew services start nginx`,\n });\n }\n }\n }\n\n // Check nginx managed path\n const defaults = getDefaults();\n if (existsSync(defaults.nginxManagedPath)) {\n checks.push({\n name: 'Nginx config file',\n status: 'ok',\n message: `Exists at ${defaults.nginxManagedPath}`,\n });\n } else {\n checks.push({\n name: 'Nginx config file',\n status: 'warning',\n message: `Not found at ${defaults.nginxManagedPath}`,\n fix: 'Run: sudo bindler apply',\n });\n }\n\n // Check projects root\n if (existsSync(defaults.projectsRoot)) {\n checks.push({\n name: 'Projects root',\n status: 'ok',\n message: `Exists at ${defaults.projectsRoot}`,\n });\n } else {\n checks.push({\n name: 'Projects root',\n status: 'warning',\n message: `Not found at ${defaults.projectsRoot}`,\n fix: `Create directory: sudo mkdir -p ${defaults.projectsRoot}`,\n });\n }\n } else {\n checks.push({\n name: 'Bindler config',\n status: 'warning',\n message: 'Not initialized',\n fix: 'Run: bindler new (to create first project)',\n });\n }\n\n // Print results\n let hasErrors = false;\n let hasWarnings = false;\n\n for (const check of checks) {\n let icon: string;\n let color: (s: string) => string;\n\n switch (check.status) {\n case 'ok':\n icon = '✓';\n color = chalk.green;\n break;\n case 'warning':\n icon = '!';\n color = chalk.yellow;\n hasWarnings = true;\n break;\n case 'error':\n icon = '✗';\n color = chalk.red;\n hasErrors = true;\n break;\n }\n\n console.log(`${color(icon)} ${chalk.bold(check.name)}: ${check.message}`);\n if (check.fix) {\n console.log(chalk.dim(` Fix: ${check.fix}`));\n }\n }\n\n // Summary\n console.log('');\n if (hasErrors) {\n console.log(chalk.red('Some checks failed. Please fix the issues above.'));\n process.exit(1);\n } else if (hasWarnings) {\n console.log(chalk.yellow('Some warnings detected. Review the suggestions above.'));\n } else {\n console.log(chalk.green('All checks passed!'));\n }\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { getPortsTable } from '../lib/ports.js';\n\nexport async function portsCommand(): Promise<void> {\n const ports = getPortsTable();\n\n if (ports.length === 0) {\n console.log(chalk.yellow('No ports allocated.'));\n console.log(chalk.dim('npm projects will have ports allocated when created.'));\n return;\n }\n\n const table = new Table({\n head: [chalk.cyan('Port'), chalk.cyan('Project'), chalk.cyan('Hostname')],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const entry of ports) {\n table.push([String(entry.port), entry.project, entry.hostname]);\n }\n\n console.log(table.toString());\n console.log(chalk.dim(`\\n${ports.length} port(s) allocated`));\n}\n","import chalk from 'chalk';\nimport { configExists, readConfig, getConfigPath } from '../lib/config.js';\nimport { getPm2List } from '../lib/pm2.js';\n\ndeclare const __VERSION__: string;\n\nexport async function infoCommand(): Promise<void> {\n console.log(chalk.bold.cyan(String.raw`\n _ _ _ _\n | |_|_|___ _| | |___ ___\n | . | | | . | | -_| _|\n |___|_|_|_|___|_|___|_|\n `));\n\n console.log(chalk.white(' Manage multiple projects behind Cloudflare Tunnel'));\n console.log(chalk.white(' with Nginx and PM2\\n'));\n\n console.log(chalk.dim(' Version: ') + chalk.white(__VERSION__));\n console.log(chalk.dim(' Author: ') + chalk.white('alfaoz'));\n console.log(chalk.dim(' License: ') + chalk.white('MIT'));\n console.log(chalk.dim(' GitHub: ') + chalk.cyan('https://github.com/alfaoz/bindler'));\n console.log('');\n\n if (configExists()) {\n const config = readConfig();\n const pm2Processes = getPm2List().filter((p) => p.name.startsWith('bindler:'));\n const runningCount = pm2Processes.filter((p) => p.status === 'online').length;\n const npmProjects = config.projects.filter((p) => p.type === 'npm').length;\n const staticProjects = config.projects.filter((p) => p.type === 'static').length;\n\n console.log(chalk.dim(' Config: ') + chalk.white(getConfigPath()));\n console.log(chalk.dim(' Nginx: ') + chalk.white(config.defaults.nginxManagedPath));\n console.log(chalk.dim(' Tunnel: ') + chalk.white(config.defaults.tunnelName));\n console.log('');\n console.log(chalk.dim(' Projects: ') + chalk.white(`${config.projects.length} total (${staticProjects} static, ${npmProjects} npm)`));\n if (npmProjects > 0) {\n console.log(chalk.dim(' Running: ') + chalk.green(`${runningCount}/${npmProjects} npm apps online`));\n }\n } else {\n console.log(chalk.dim(' Config: ') + chalk.yellow('Not initialized'));\n console.log(chalk.dim(' ') + chalk.dim('Run `bindler new` to get started'));\n }\n\n console.log('');\n}\n","import chalk from 'chalk';\nimport { resolve4, resolve6, resolveCname } from 'node:dns/promises';\nimport { getProject, listProjects } from '../lib/config.js';\n\ninterface CheckOptions {\n verbose?: boolean;\n}\n\nasync function checkDns(hostname: string): Promise<{\n resolved: boolean;\n ipv4: string[];\n ipv6: string[];\n cname: string[];\n isCloudflare: boolean;\n}> {\n const result = {\n resolved: false,\n ipv4: [] as string[],\n ipv6: [] as string[],\n cname: [] as string[],\n isCloudflare: false,\n };\n\n try {\n result.ipv4 = await resolve4(hostname);\n result.resolved = true;\n } catch {\n // No A records\n }\n\n try {\n result.ipv6 = await resolve6(hostname);\n result.resolved = true;\n } catch {\n // No AAAA records\n }\n\n try {\n result.cname = await resolveCname(hostname);\n result.resolved = true;\n // Check if CNAME points to cloudflare tunnel\n result.isCloudflare = result.cname.some(\n (c) => c.includes('cfargotunnel.com') || c.includes('cloudflare')\n );\n } catch {\n // No CNAME records\n }\n\n return result;\n}\n\nasync function checkHttp(hostname: string, path = '/'): Promise<{\n reachable: boolean;\n statusCode?: number;\n redirectUrl?: string;\n responseTime?: number;\n error?: string;\n}> {\n const url = `https://${hostname}${path}`;\n const startTime = Date.now();\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 10000);\n\n const response = await fetch(url, {\n method: 'HEAD',\n redirect: 'manual',\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n const responseTime = Date.now() - startTime;\n\n return {\n reachable: true,\n statusCode: response.status,\n redirectUrl: response.headers.get('location') || undefined,\n responseTime,\n };\n } catch (error) {\n return {\n reachable: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function checkCommand(hostnameOrName: string, options: CheckOptions): Promise<void> {\n // Check if it's a project name\n const project = getProject(hostnameOrName);\n const hostname = project ? project.hostname : hostnameOrName;\n const basePath = project?.basePath || '/';\n const isLocal = project?.local || hostname.endsWith('.local') || hostname.endsWith('.localhost');\n\n console.log(chalk.blue(`\\nChecking ${hostname}...\\n`));\n\n // DNS Check\n console.log(chalk.bold('DNS Resolution:'));\n const dns = await checkDns(hostname);\n\n if (!dns.resolved) {\n console.log(chalk.red(' ✗ DNS not resolving'));\n if (isLocal) {\n console.log(chalk.dim(' Local hostname - add to /etc/hosts:'));\n console.log(chalk.cyan(` echo \"127.0.0.1 ${hostname}\" | sudo tee -a /etc/hosts`));\n } else {\n console.log(chalk.dim(' No DNS records found for this hostname.'));\n console.log(chalk.dim(' If using Cloudflare Tunnel, run: bindler apply'));\n console.log(chalk.dim(' If using direct mode, add an A record pointing to your server IP.'));\n }\n console.log('');\n return;\n }\n\n if (dns.cname.length > 0) {\n console.log(chalk.green(' ✓ CNAME: ') + dns.cname.join(', '));\n if (dns.isCloudflare) {\n console.log(chalk.green(' ✓ Points to Cloudflare Tunnel'));\n }\n }\n\n if (dns.ipv4.length > 0) {\n console.log(chalk.green(' ✓ A (IPv4): ') + dns.ipv4.join(', '));\n }\n\n if (dns.ipv6.length > 0) {\n console.log(chalk.green(' ✓ AAAA (IPv6): ') + dns.ipv6.join(', '));\n }\n\n console.log('');\n\n // HTTP Check\n console.log(chalk.bold('HTTP Check:'));\n const http = await checkHttp(hostname, basePath);\n\n if (!http.reachable) {\n console.log(chalk.red(' ✗ Not reachable'));\n\n // Provide specific error guidance\n const err = http.error || '';\n if (err.includes('ECONNREFUSED')) {\n console.log(chalk.dim(' Connection refused - server not accepting connections'));\n console.log(chalk.yellow('\\n Check:'));\n console.log(chalk.dim(' - Is nginx running? Run: bindler doctor'));\n if (project?.type === 'npm') {\n console.log(chalk.dim(` - Is the app running? Run: bindler start ${project.name}`));\n }\n } else if (err.includes('ENOTFOUND')) {\n console.log(chalk.dim(' Hostname not found'));\n console.log(chalk.yellow('\\n Check:'));\n console.log(chalk.dim(' - DNS may not be propagated yet (wait a few minutes)'));\n console.log(chalk.dim(' - Verify DNS records are correct'));\n } else if (err.includes('ETIMEDOUT') || err.includes('timeout')) {\n console.log(chalk.dim(' Connection timed out'));\n console.log(chalk.yellow('\\n Check:'));\n if (isLocal) {\n console.log(chalk.dim(' - Is nginx running on port 8080?'));\n } else {\n console.log(chalk.dim(' - Is your server/tunnel reachable from the internet?'));\n console.log(chalk.dim(' - Check firewall rules'));\n }\n } else if (err.includes('CERT') || err.includes('SSL') || err.includes('certificate')) {\n console.log(chalk.dim(' SSL/TLS certificate error'));\n console.log(chalk.yellow('\\n Check:'));\n console.log(chalk.dim(' - Run: sudo bindler apply (to refresh SSL certs)'));\n console.log(chalk.dim(' - Or check certbot: sudo certbot certificates'));\n } else {\n console.log(chalk.dim(` Error: ${err}`));\n console.log(chalk.yellow('\\n Possible issues:'));\n if (!isLocal) {\n console.log(chalk.dim(' - Cloudflare tunnel not running'));\n }\n console.log(chalk.dim(' - Nginx not running or misconfigured'));\n if (project?.type === 'npm') {\n console.log(chalk.dim(' - Project not started'));\n }\n }\n console.log('');\n return;\n }\n\n const statusColor = http.statusCode! < 400 ? chalk.green : chalk.red;\n console.log(statusColor(` ✓ Status: ${http.statusCode}`));\n console.log(chalk.dim(` Response time: ${http.responseTime}ms`));\n\n if (http.redirectUrl) {\n console.log(chalk.dim(` Redirects to: ${http.redirectUrl}`));\n }\n\n console.log('');\n\n // Summary\n if (dns.resolved && http.reachable && http.statusCode! < 400) {\n console.log(chalk.green('✓ All checks passed! Site is accessible.'));\n } else if (dns.resolved && http.reachable) {\n console.log(chalk.yellow('! Site is reachable but returned an error status.'));\n } else {\n console.log(chalk.red('✗ Some checks failed. See details above.'));\n }\n\n if (project) {\n console.log(chalk.dim(`\\nProject: ${project.name} (${project.type})`));\n if (project.type === 'npm') {\n console.log(chalk.dim(`Port: ${project.port}`));\n }\n }\n\n console.log('');\n}\n","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { isNginxInstalled } from '../lib/nginx.js';\nimport { isPm2Installed } from '../lib/pm2.js';\nimport { isCloudflaredInstalled } from '../lib/cloudflare.js';\nimport { execCommandSafe } from '../lib/utils.js';\nimport { readConfig, writeConfig, configExists, initConfig } from '../lib/config.js';\n\ninterface SetupOptions {\n direct?: boolean;\n}\n\ninterface OsInfo {\n platform: 'linux' | 'darwin' | 'win32' | 'unknown';\n distro?: string;\n version?: string;\n codename?: string;\n packageManager?: 'apt' | 'yum' | 'dnf' | 'brew' | 'winget';\n}\n\nfunction detectOs(): OsInfo {\n const platform = process.platform;\n\n if (platform === 'darwin') {\n return { platform: 'darwin', distro: 'macOS', packageManager: 'brew' };\n }\n\n if (platform === 'win32') {\n return { platform: 'win32', distro: 'Windows', packageManager: 'winget' };\n }\n\n if (platform === 'linux') {\n // Try to detect Linux distribution\n try {\n if (existsSync('/etc/os-release')) {\n const osRelease = readFileSync('/etc/os-release', 'utf-8');\n const lines = osRelease.split('\\n');\n const info: Record<string, string> = {};\n\n for (const line of lines) {\n const [key, ...valueParts] = line.split('=');\n if (key && valueParts.length > 0) {\n info[key] = valueParts.join('=').replace(/\"/g, '');\n }\n }\n\n const distro = info['ID'] || 'linux';\n const version = info['VERSION_ID'];\n const codename = info['VERSION_CODENAME'];\n\n // Determine package manager\n let packageManager: 'apt' | 'yum' | 'dnf' | undefined;\n if (['ubuntu', 'debian', 'pop', 'mint', 'elementary'].includes(distro)) {\n packageManager = 'apt';\n } else if (['fedora', 'rhel', 'centos', 'rocky', 'alma'].includes(distro)) {\n packageManager = existsSync('/usr/bin/dnf') ? 'dnf' : 'yum';\n } else if (['amzn'].includes(distro)) {\n packageManager = 'yum';\n }\n\n return { platform: 'linux', distro, version, codename, packageManager };\n }\n } catch {\n // Ignore errors\n }\n\n return { platform: 'linux', distro: 'unknown' };\n }\n\n return { platform: 'unknown' };\n}\n\nfunction runCommand(command: string, description: string): boolean {\n console.log(chalk.dim(` → ${description}...`));\n try {\n execSync(command, { stdio: 'inherit' });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function installNginx(os: OsInfo): Promise<boolean> {\n console.log(chalk.blue('\\nInstalling nginx...\\n'));\n\n if (os.platform === 'darwin') {\n return runCommand('brew install nginx', 'Installing via Homebrew');\n }\n\n if (os.platform === 'linux' && os.packageManager === 'apt') {\n runCommand('sudo apt-get update', 'Updating package list');\n return runCommand('sudo apt-get install -y nginx', 'Installing nginx');\n }\n\n if (os.platform === 'linux' && (os.packageManager === 'yum' || os.packageManager === 'dnf')) {\n return runCommand(`sudo ${os.packageManager} install -y nginx`, 'Installing nginx');\n }\n\n console.log(chalk.yellow(' Automatic installation not supported for your OS.'));\n console.log(chalk.dim(' Please install nginx manually.'));\n return false;\n}\n\nasync function installPm2(): Promise<boolean> {\n console.log(chalk.blue('\\nInstalling PM2...\\n'));\n return runCommand('npm install -g pm2', 'Installing via npm');\n}\n\nasync function installCertbot(os: OsInfo): Promise<boolean> {\n console.log(chalk.blue('\\nInstalling certbot (Let\\'s Encrypt)...\\n'));\n\n if (os.platform === 'darwin') {\n return runCommand('brew install certbot', 'Installing via Homebrew');\n }\n\n if (os.platform === 'linux' && os.packageManager === 'apt') {\n runCommand('sudo apt-get update', 'Updating package list');\n return runCommand('sudo apt-get install -y certbot python3-certbot-nginx', 'Installing certbot');\n }\n\n if (os.platform === 'linux' && (os.packageManager === 'yum' || os.packageManager === 'dnf')) {\n return runCommand(`sudo ${os.packageManager} install -y certbot python3-certbot-nginx`, 'Installing certbot');\n }\n\n console.log(chalk.yellow(' Automatic installation not supported for your OS.'));\n console.log(chalk.dim(' Please install certbot manually.'));\n return false;\n}\n\nfunction isCertbotInstalled(): boolean {\n const result = execCommandSafe('which certbot');\n return result.success;\n}\n\nasync function installCloudflared(os: OsInfo): Promise<boolean> {\n console.log(chalk.blue('\\nInstalling cloudflared...\\n'));\n\n if (os.platform === 'darwin') {\n return runCommand('brew install cloudflared', 'Installing via Homebrew');\n }\n\n if (os.platform === 'win32') {\n return runCommand('winget install --id Cloudflare.cloudflared', 'Installing via winget');\n }\n\n if (os.platform === 'linux' && os.packageManager === 'apt') {\n // Add Cloudflare GPG key and repo\n runCommand(\n 'sudo mkdir -p --mode=0755 /usr/share/keyrings',\n 'Creating keyrings directory'\n );\n\n runCommand(\n 'curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null',\n 'Adding Cloudflare GPG key'\n );\n\n // Determine the right repo based on distro\n let repoLine = 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main';\n\n if (os.codename) {\n // Use specific codename if available (focal, jammy, noble, bookworm, etc.)\n repoLine = `deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared ${os.codename} main`;\n }\n\n runCommand(\n `echo '${repoLine}' | sudo tee /etc/apt/sources.list.d/cloudflared.list`,\n 'Adding Cloudflare repository'\n );\n\n runCommand('sudo apt-get update', 'Updating package list');\n return runCommand('sudo apt-get install -y cloudflared', 'Installing cloudflared');\n }\n\n if (os.platform === 'linux' && (os.packageManager === 'yum' || os.packageManager === 'dnf')) {\n runCommand(\n 'curl -fsSl https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo',\n 'Adding Cloudflare repository'\n );\n\n return runCommand(`sudo ${os.packageManager} install -y cloudflared`, 'Installing cloudflared');\n }\n\n console.log(chalk.yellow(' Automatic installation not supported for your OS.'));\n console.log(chalk.dim(' Visit: https://pkg.cloudflare.com/index.html'));\n return false;\n}\n\nexport async function setupCommand(options: SetupOptions = {}): Promise<void> {\n console.log(chalk.bold.cyan('\\nBindler Setup\\n'));\n\n // Detect OS\n const os = detectOs();\n console.log(chalk.dim(`Detected: ${os.distro || os.platform}${os.version ? ` ${os.version}` : ''}${os.codename ? ` (${os.codename})` : ''}`));\n\n // Handle --direct mode\n const isDirect = options.direct;\n if (isDirect) {\n console.log(chalk.cyan('\\nDirect mode (VPS without Cloudflare Tunnel)'));\n console.log(chalk.dim('nginx will listen on port 80/443 directly\\n'));\n } else {\n console.log(chalk.cyan('\\nTunnel mode (via Cloudflare Tunnel)'));\n console.log(chalk.dim('nginx will listen on 127.0.0.1:8080\\n'));\n }\n\n // Check what's missing\n const missing: Array<{ name: string; install: () => Promise<boolean> }> = [];\n\n if (!isNginxInstalled()) {\n missing.push({ name: 'nginx', install: () => installNginx(os) });\n }\n\n if (!isPm2Installed()) {\n missing.push({ name: 'PM2', install: () => installPm2() });\n }\n\n // In direct mode, we need certbot instead of cloudflared\n if (isDirect) {\n if (!isCertbotInstalled()) {\n missing.push({ name: 'certbot', install: () => installCertbot(os) });\n }\n } else {\n if (!isCloudflaredInstalled()) {\n missing.push({ name: 'cloudflared', install: () => installCloudflared(os) });\n }\n }\n\n if (missing.length === 0) {\n console.log(chalk.green('✓ All dependencies are already installed!\\n'));\n } else {\n // Show what's missing\n console.log(chalk.yellow('Missing dependencies:\\n'));\n for (const dep of missing) {\n console.log(chalk.red(` ✗ ${dep.name}`));\n }\n console.log('');\n\n // Ask what to install\n const { toInstall } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'toInstall',\n message: 'Select dependencies to install:',\n choices: missing.map((dep) => ({\n name: dep.name,\n value: dep.name,\n checked: true,\n })),\n },\n ]);\n\n if (toInstall.length > 0) {\n // Install selected dependencies\n const results: Array<{ name: string; success: boolean }> = [];\n\n for (const depName of toInstall) {\n const dep = missing.find((m) => m.name === depName);\n if (dep) {\n const success = await dep.install();\n results.push({ name: depName, success });\n }\n }\n\n // Summary\n console.log(chalk.bold('\\n\\nInstallation Summary:\\n'));\n for (const result of results) {\n if (result.success) {\n console.log(chalk.green(` ✓ ${result.name} installed`));\n } else {\n console.log(chalk.red(` ✗ ${result.name} failed`));\n }\n }\n console.log('');\n }\n }\n\n // Configure bindler mode\n const config = configExists() ? readConfig() : initConfig();\n\n if (isDirect) {\n config.defaults.mode = 'direct';\n config.defaults.nginxListen = '80';\n config.defaults.applyCloudflareDnsRoutes = false;\n\n // Ask for SSL email\n const { enableSsl } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'enableSsl',\n message: 'Enable SSL with Let\\'s Encrypt?',\n default: true,\n },\n ]);\n\n if (enableSsl) {\n const { email } = await inquirer.prompt([\n {\n type: 'input',\n name: 'email',\n message: 'Email for Let\\'s Encrypt notifications:',\n validate: (input: string) => {\n if (!input || !input.includes('@')) {\n return 'Please enter a valid email address';\n }\n return true;\n },\n },\n ]);\n\n config.defaults.sslEnabled = true;\n config.defaults.sslEmail = email;\n }\n } else {\n config.defaults.mode = 'tunnel';\n config.defaults.nginxListen = '127.0.0.1:8080';\n config.defaults.applyCloudflareDnsRoutes = true;\n }\n\n writeConfig(config);\n\n console.log(chalk.green('\\n✓ Setup complete!\\n'));\n console.log(chalk.dim(`Mode: ${config.defaults.mode}`));\n console.log(chalk.dim(`nginx listen: ${config.defaults.nginxListen}`));\n if (config.defaults.sslEnabled) {\n console.log(chalk.dim(`SSL: enabled (${config.defaults.sslEmail})`));\n }\n console.log(chalk.dim('\\nRun `bindler new` to create your first project.'));\n}\n"],"mappings":"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","names":["existsSync","mkdirSync","existsSync","readFileSync","join","join","existsSync","readFileSync","existsSync","writeFileSync","copyFileSync","mkdirSync","dirname","join","dirname","existsSync","mkdirSync","join","copyFileSync","writeFileSync","result","answers","existsSync","mkdirSync","chalk","chalk","process","chalk","Table","chalk","process","Table","chalk","chalk","result","chalk","chalk","result","chalk","chalk","result","process","chalk","chalk","process","chalk","chalk","writeFileSync","readFileSync","join","chalk","chalk","join","writeFileSync","readFileSync","inquirer","chalk","chalk","inquirer","process","chalk","chalk","chalk","existsSync","chalk","existsSync","chalk","Table","chalk","Table","chalk","chalk","chalk","chalk","chalk","inquirer","execSync","existsSync","readFileSync","existsSync","readFileSync","chalk","execSync","inquirer"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/new.ts","../src/lib/config.ts","../src/lib/utils.ts","../src/lib/ports.ts","../src/lib/nginx.ts","../src/lib/pm2.ts","../src/commands/list.ts","../src/commands/status.ts","../src/commands/start.ts","../src/commands/stop.ts","../src/commands/restart.ts","../src/commands/logs.ts","../src/commands/update.ts","../src/commands/edit.ts","../src/commands/remove.ts","../src/commands/apply.ts","../src/lib/cloudflare.ts","../src/commands/doctor.ts","../src/commands/ports.ts","../src/commands/info.ts","../src/commands/check.ts","../src/commands/setup.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport {\n newCommand,\n listCommand,\n statusCommand,\n startCommand,\n stopCommand,\n restartCommand,\n logsCommand,\n updateCommand,\n editCommand,\n removeCommand,\n applyCommand,\n doctorCommand,\n portsCommand,\n infoCommand,\n checkCommand,\n setupCommand,\n} from './commands/index.js';\nimport { initConfig } from './lib/config.js';\n\nconst program = new Command();\n\nprogram\n .name('bindler')\n .description('Manage multiple projects behind Cloudflare Tunnel with Nginx and PM2')\n .version('1.0.0');\n\n// Initialize config on first run\nprogram.hook('preAction', () => {\n try {\n initConfig();\n } catch (error) {\n // Config init may fail if not root - that's okay for some commands\n }\n});\n\n// new - Create a new project\nprogram\n .command('new')\n .description('Create and register a new project')\n .option('-n, --name <name>', 'Project name')\n .option('-t, --type <type>', 'Project type (static or npm)', 'static')\n .option('-p, --path <path>', 'Project directory path')\n .option('-h, --hostname <hostname>', 'Hostname for the project')\n .option('-b, --base-path <path>', 'Base path for path-based routing (e.g., /api)')\n .option('--port <port>', 'Port number (npm projects only)')\n .option('-s, --start <command>', 'Start command (npm projects only)')\n .option('-l, --local', 'Local project (skip Cloudflare, use .local hostname)')\n .option('--apply', 'Apply nginx config after creating')\n .action(async (options) => {\n await newCommand(options);\n });\n\n// list - List all projects\nprogram\n .command('list')\n .alias('ls')\n .description('List all registered projects')\n .action(async () => {\n await listCommand();\n });\n\n// status - Show runtime status\nprogram\n .command('status')\n .description('Show detailed status of all projects')\n .action(async () => {\n await statusCommand();\n });\n\n// start - Start a project\nprogram\n .command('start [name]')\n .description('Start an npm project with PM2')\n .option('-a, --all', 'Start all npm projects')\n .action(async (name, options) => {\n if (!name && !options.all) {\n console.log(chalk.red('Usage: bindler start <name> or bindler start --all'));\n console.log(chalk.dim('\\nExamples:'));\n console.log(chalk.dim(' bindler start myapp'));\n console.log(chalk.dim(' bindler start --all # start all npm projects'));\n process.exit(1);\n }\n await startCommand(name, options);\n });\n\n// stop - Stop a project\nprogram\n .command('stop [name]')\n .description('Stop an npm project')\n .option('-a, --all', 'Stop all npm projects')\n .action(async (name, options) => {\n if (!name && !options.all) {\n console.log(chalk.red('Usage: bindler stop <name> or bindler stop --all'));\n console.log(chalk.dim('\\nExamples:'));\n console.log(chalk.dim(' bindler stop myapp'));\n console.log(chalk.dim(' bindler stop --all # stop all npm projects'));\n process.exit(1);\n }\n await stopCommand(name, options);\n });\n\n// restart - Restart a project\nprogram\n .command('restart [name]')\n .description('Restart an npm project')\n .option('-a, --all', 'Restart all npm projects')\n .action(async (name, options) => {\n if (!name && !options.all) {\n console.log(chalk.red('Usage: bindler restart <name> or bindler restart --all'));\n console.log(chalk.dim('\\nExamples:'));\n console.log(chalk.dim(' bindler restart myapp'));\n console.log(chalk.dim(' bindler restart --all # restart all npm projects'));\n process.exit(1);\n }\n await restartCommand(name, options);\n });\n\n// logs - Show project logs\nprogram\n .command('logs [name]')\n .description('Show logs for an npm project')\n .option('-f, --follow', 'Follow log output')\n .option('-l, --lines <n>', 'Number of lines to show', '200')\n .action(async (name, options) => {\n if (!name) {\n console.log(chalk.red('Usage: bindler logs <name>'));\n console.log(chalk.dim('\\nExamples:'));\n console.log(chalk.dim(' bindler logs myapp'));\n console.log(chalk.dim(' bindler logs myapp --follow'));\n console.log(chalk.dim(' bindler logs myapp --lines 500'));\n process.exit(1);\n }\n await logsCommand(name, { ...options, lines: parseInt(options.lines, 10) });\n });\n\n// update - Update project configuration\nprogram\n .command('update [name]')\n .description('Update project configuration')\n .option('-h, --hostname <hostname>', 'New hostname')\n .option('--port <port>', 'New port number')\n .option('-s, --start <command>', 'New start command')\n .option('-p, --path <path>', 'New project path')\n .option('-e, --env <vars...>', 'Environment variables (KEY=value)')\n .option('--enable', 'Enable the project')\n .option('--disable', 'Disable the project')\n .action(async (name, options) => {\n if (!name) {\n console.log(chalk.red('Usage: bindler update <name> [options]'));\n console.log(chalk.dim('\\nExamples:'));\n console.log(chalk.dim(' bindler update myapp --hostname newapp.example.com'));\n console.log(chalk.dim(' bindler update myapp --port 4000'));\n console.log(chalk.dim(' bindler update myapp --disable'));\n process.exit(1);\n }\n await updateCommand(name, options);\n });\n\n// edit - Edit project in $EDITOR\nprogram\n .command('edit [name]')\n .description('Edit project configuration in $EDITOR')\n .action(async (name) => {\n if (!name) {\n console.log(chalk.red('Usage: bindler edit <name>'));\n console.log(chalk.dim('\\nOpens the project config in your $EDITOR'));\n console.log(chalk.dim('\\nExample:'));\n console.log(chalk.dim(' bindler edit myapp'));\n process.exit(1);\n }\n await editCommand(name);\n });\n\n// remove - Remove a project\nprogram\n .command('remove [name]')\n .alias('rm')\n .description('Remove a project from registry')\n .option('-f, --force', 'Skip confirmation')\n .option('--apply', 'Apply nginx config after removing')\n .action(async (name, options) => {\n if (!name) {\n console.log(chalk.red('Usage: bindler remove <name>'));\n console.log(chalk.dim('\\nExamples:'));\n console.log(chalk.dim(' bindler remove myapp'));\n console.log(chalk.dim(' bindler remove myapp --force # skip confirmation'));\n console.log(chalk.dim(' bindler rm myapp # alias'));\n process.exit(1);\n }\n await removeCommand(name, options);\n });\n\n// apply - Apply configuration\nprogram\n .command('apply')\n .description('Generate and apply nginx configuration + Cloudflare DNS routes')\n .option('-d, --dry-run', 'Print config without applying')\n .option('--no-reload', 'Write config but do not reload nginx')\n .option('--no-cloudflare', 'Skip Cloudflare DNS route configuration')\n .option('--no-ssl', 'Skip SSL certificate setup (direct mode)')\n .action(async (options) => {\n await applyCommand(options);\n });\n\n// doctor - Run diagnostics\nprogram\n .command('doctor')\n .description('Run system diagnostics and check dependencies')\n .action(async () => {\n await doctorCommand();\n });\n\n// ports - Show allocated ports\nprogram\n .command('ports')\n .description('Show allocated ports')\n .action(async () => {\n await portsCommand();\n });\n\n// info - Show project info\nprogram\n .command('info')\n .description('Show bindler information and stats')\n .action(async () => {\n await infoCommand();\n });\n\n// check - Check DNS and HTTP for a hostname\nprogram\n .command('check [hostname]')\n .description('Check DNS propagation and HTTP accessibility for a hostname')\n .option('-v, --verbose', 'Show verbose output')\n .action(async (hostname, options) => {\n if (!hostname) {\n console.log(chalk.red('Usage: bindler check <hostname>'));\n console.log(chalk.dim('\\nExamples:'));\n console.log(chalk.dim(' bindler check myapp.example.com'));\n console.log(chalk.dim(' bindler check myapp # uses project name'));\n process.exit(1);\n }\n await checkCommand(hostname, options);\n });\n\n// setup - Install dependencies\nprogram\n .command('setup')\n .description('Install missing dependencies (nginx, PM2, cloudflared)')\n .option('--direct', 'Direct mode for VPS (no Cloudflare Tunnel, use port 80/443)')\n .action(async (options) => {\n await setupCommand(options);\n });\n\n// Parse arguments\nprogram.parse();\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename } from 'node:path';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport type { Project } from '../types.js';\nimport { addProject, getDefaults } from '../lib/config.js';\nimport { findAvailablePort } from '../lib/ports.js';\nimport {\n detectProjectType,\n getPackageJsonScripts,\n validateHostname,\n validateProjectName,\n validatePort,\n} from '../lib/utils.js';\nimport { isNginxInstalled } from '../lib/nginx.js';\nimport { isPm2Installed } from '../lib/pm2.js';\n\ninterface NewOptions {\n name?: string;\n type?: 'static' | 'npm';\n path?: string;\n hostname?: string;\n basePath?: string;\n port?: number;\n start?: string;\n apply?: boolean;\n local?: boolean;\n}\n\nexport async function newCommand(options: NewOptions): Promise<void> {\n // Run prerequisite checks\n console.log(chalk.dim('Checking prerequisites...\\n'));\n\n const issues: string[] = [];\n\n if (!isNginxInstalled()) {\n issues.push('nginx is not installed. Install: brew install nginx (macOS) or apt install nginx (Linux)');\n }\n\n if (!isPm2Installed()) {\n issues.push('PM2 is not installed. Install: npm install -g pm2');\n }\n\n if (issues.length > 0) {\n console.log(chalk.red('Missing prerequisites:\\n'));\n for (const issue of issues) {\n console.log(chalk.red(` ✗ ${issue}`));\n }\n console.log(chalk.dim('\\nRun `bindler doctor` for full diagnostics.'));\n\n const { proceed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'proceed',\n message: 'Continue anyway?',\n default: false,\n },\n ]);\n\n if (!proceed) {\n process.exit(1);\n }\n console.log('');\n } else {\n console.log(chalk.green('✓ Prerequisites OK\\n'));\n }\n\n const defaults = getDefaults();\n let project: Partial<Project> = {};\n\n // Get current working directory info for defaults\n const cwd = process.cwd();\n const cwdName = basename(cwd);\n\n // Interactive mode if no name provided\n if (!options.name) {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'path',\n message: 'Project path:',\n default: cwd,\n validate: (input: string) => {\n if (!input) {\n return 'Path is required';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'name',\n message: 'Project name:',\n default: cwdName,\n validate: (input: string) => {\n if (!validateProjectName(input)) {\n return 'Invalid project name. Use alphanumeric characters, dashes, and underscores.';\n }\n return true;\n },\n },\n {\n type: 'list',\n name: 'type',\n message: 'Project type:',\n choices: (answers: { path: string }) => {\n const detected = existsSync(answers.path) ? detectProjectType(answers.path) : 'static';\n return [\n { name: `npm (Node.js app)${detected === 'npm' ? ' - detected' : ''}`, value: 'npm' },\n { name: `static (HTML/CSS/JS)${detected === 'static' ? ' - detected' : ''}`, value: 'static' },\n ];\n },\n default: (answers: { path: string }) => {\n return existsSync(answers.path) ? detectProjectType(answers.path) : 'static';\n },\n },\n {\n type: 'input',\n name: 'hostname',\n message: options.local\n ? 'Hostname (e.g., myapp.local):'\n : 'Hostname (e.g., mysite.example.com or example.com):',\n default: options.local ? `${cwdName}.local` : undefined,\n validate: (input: string) => {\n if (!validateHostname(input)) {\n return 'Invalid hostname format';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'basePath',\n message: 'Base path (leave empty for root, or e.g., /api):',\n filter: (input: string) => {\n if (!input || input.trim() === '') return '';\n // Ensure path starts with /\n const trimmed = input.trim();\n return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;\n },\n },\n ]);\n\n project = { ...answers };\n if (!project.basePath) delete project.basePath;\n if (options.local) project.local = true;\n\n // NPM-specific questions\n if (answers.type === 'npm') {\n const scripts = existsSync(answers.path) ? getPackageJsonScripts(answers.path) : [];\n const suggestedPort = findAvailablePort();\n\n const npmAnswers = await inquirer.prompt([\n {\n type: 'input',\n name: 'port',\n message: 'Port number:',\n default: suggestedPort,\n validate: (input: string) => {\n const port = parseInt(input, 10);\n if (!validatePort(port)) {\n return 'Invalid port. Use a number between 1024 and 65535.';\n }\n return true;\n },\n filter: (input: string) => parseInt(input, 10),\n },\n {\n type: scripts.length > 0 ? 'list' : 'input',\n name: 'start',\n message: 'Start command:',\n choices: scripts.length > 0\n ? [\n ...scripts.map((s) => ({ name: `npm run ${s}`, value: `npm run ${s}` })),\n { name: 'Custom command...', value: '__custom__' },\n ]\n : undefined,\n default: scripts.includes('start') ? 'npm run start' : 'npm start',\n },\n ]);\n\n if (npmAnswers.start === '__custom__') {\n const customAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'start',\n message: 'Enter custom start command:',\n },\n ]);\n npmAnswers.start = customAnswer.start;\n }\n\n project.port = npmAnswers.port;\n project.start = npmAnswers.start;\n\n // Ask about PORT env var\n const envAnswer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'setPortEnv',\n message: `Set PORT=${npmAnswers.port} environment variable?`,\n default: true,\n },\n ]);\n\n if (envAnswer.setPortEnv) {\n project.env = { PORT: String(npmAnswers.port) };\n }\n }\n } else {\n // Non-interactive mode - use provided options\n if (!options.hostname) {\n console.error(chalk.red('Error: --hostname is required'));\n process.exit(1);\n }\n\n project.name = options.name;\n project.type = options.type || 'static';\n project.path = options.path || cwd;\n project.hostname = options.hostname;\n\n // Handle base path for path-based routing\n if (options.basePath) {\n project.basePath = options.basePath.startsWith('/') ? options.basePath : `/${options.basePath}`;\n }\n\n // Handle local flag\n if (options.local) {\n project.local = true;\n }\n\n if (project.type === 'npm') {\n project.port = options.port || findAvailablePort();\n project.start = options.start || 'npm start';\n project.env = { PORT: String(project.port) };\n }\n }\n\n // Validate project\n if (!validateProjectName(project.name!)) {\n console.error(chalk.red('Error: Invalid project name'));\n process.exit(1);\n }\n\n if (!validateHostname(project.hostname!)) {\n console.error(chalk.red('Error: Invalid hostname'));\n process.exit(1);\n }\n\n // Create directory if it doesn't exist\n if (!existsSync(project.path!)) {\n const createDir = options.name\n ? true\n : (\n await inquirer.prompt([\n {\n type: 'confirm',\n name: 'create',\n message: `Directory ${project.path} does not exist. Create it?`,\n default: true,\n },\n ])\n ).create;\n\n if (createDir) {\n mkdirSync(project.path!, { recursive: true });\n console.log(chalk.green(`Created directory: ${project.path}`));\n }\n }\n\n // Add project to config\n try {\n addProject(project as Project);\n console.log(chalk.green(`\\nProject \"${project.name}\" added successfully!`));\n\n if (project.local) {\n console.log(chalk.yellow(`\\nLocal project - add to /etc/hosts:`));\n console.log(chalk.cyan(` echo \"127.0.0.1 ${project.hostname}\" | sudo tee -a /etc/hosts`));\n console.log(chalk.dim(`\\nRun ${chalk.cyan('sudo bindler apply')} to update nginx.`));\n console.log(chalk.dim(`Then access at: ${chalk.cyan(`http://${project.hostname}:8080`)}`));\n } else {\n console.log(chalk.dim(`\\nConfiguration saved. Run ${chalk.cyan('sudo bindler apply')} to update nginx and cloudflare.`));\n }\n\n if (project.type === 'npm') {\n console.log(chalk.dim(`Run ${chalk.cyan(`bindler start ${project.name}`)} to start the application.`));\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : error}`));\n process.exit(1);\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { Config, Project } from '../types.js';\n\nconst CONFIG_DIR = join(homedir(), '.config', 'bindler');\nconst CONFIG_PATH = join(CONFIG_DIR, 'config.json');\nconst GENERATED_DIR = join(CONFIG_DIR, 'generated');\nconst BACKUP_DIR = join(CONFIG_DIR, 'backups');\n\nexport function getConfigDir(): string {\n return CONFIG_DIR;\n}\n\nexport function getConfigPath(): string {\n return CONFIG_PATH;\n}\n\nexport function getGeneratedDir(): string {\n return GENERATED_DIR;\n}\n\nexport function getBackupDir(): string {\n return BACKUP_DIR;\n}\n\nfunction getNginxConfigPath(): string {\n const isMac = process.platform === 'darwin';\n\n if (isMac) {\n // Homebrew nginx paths\n if (existsSync('/opt/homebrew/etc/nginx/servers')) {\n return '/opt/homebrew/etc/nginx/servers/bindler.conf';\n }\n if (existsSync('/usr/local/etc/nginx/servers')) {\n return '/usr/local/etc/nginx/servers/bindler.conf';\n }\n }\n\n // Linux default\n return '/etc/nginx/conf.d/bindler.conf';\n}\n\nexport function getDefaultConfig(): Config {\n return {\n version: 1,\n defaults: {\n projectsRoot: join(homedir(), 'projects'),\n nginxManagedPath: getNginxConfigPath(),\n nginxListen: '127.0.0.1:8080',\n tunnelName: 'homelab',\n applyCloudflareDnsRoutes: true,\n mode: 'tunnel',\n },\n projects: [],\n };\n}\n\nexport function ensureConfigDirs(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n if (!existsSync(GENERATED_DIR)) {\n mkdirSync(GENERATED_DIR, { recursive: true });\n }\n if (!existsSync(BACKUP_DIR)) {\n mkdirSync(BACKUP_DIR, { recursive: true });\n }\n}\n\nexport function configExists(): boolean {\n return existsSync(CONFIG_PATH);\n}\n\nexport function readConfig(): Config {\n if (!configExists()) {\n return getDefaultConfig();\n }\n\n try {\n const content = readFileSync(CONFIG_PATH, 'utf-8');\n const config = JSON.parse(content) as Config;\n return config;\n } catch (error) {\n throw new Error(`Failed to read config: ${error instanceof Error ? error.message : error}`);\n }\n}\n\nexport function writeConfig(config: Config): void {\n ensureConfigDirs();\n\n // Create backup if config exists\n if (configExists()) {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const backupPath = join(BACKUP_DIR, `config-${timestamp}.json`);\n copyFileSync(CONFIG_PATH, backupPath);\n }\n\n writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\\n');\n}\n\nexport function initConfig(): Config {\n if (configExists()) {\n return readConfig();\n }\n\n const config = getDefaultConfig();\n writeConfig(config);\n return config;\n}\n\nexport function getProject(name: string): Project | undefined {\n const config = readConfig();\n return config.projects.find((p) => p.name === name);\n}\n\nexport function addProject(project: Project): void {\n const config = readConfig();\n\n if (config.projects.some((p) => p.name === project.name)) {\n throw new Error(`Project \"${project.name}\" already exists`);\n }\n\n if (config.projects.some((p) => p.hostname === project.hostname)) {\n throw new Error(`Hostname \"${project.hostname}\" is already in use`);\n }\n\n config.projects.push(project);\n writeConfig(config);\n}\n\nexport function updateProject(name: string, updates: Partial<Project>): void {\n const config = readConfig();\n const index = config.projects.findIndex((p) => p.name === name);\n\n if (index === -1) {\n throw new Error(`Project \"${name}\" not found`);\n }\n\n // Check hostname uniqueness if changing hostname\n if (updates.hostname && updates.hostname !== config.projects[index].hostname) {\n if (config.projects.some((p) => p.hostname === updates.hostname)) {\n throw new Error(`Hostname \"${updates.hostname}\" is already in use`);\n }\n }\n\n config.projects[index] = { ...config.projects[index], ...updates };\n writeConfig(config);\n}\n\nexport function removeProject(name: string): Project {\n const config = readConfig();\n const index = config.projects.findIndex((p) => p.name === name);\n\n if (index === -1) {\n throw new Error(`Project \"${name}\" not found`);\n }\n\n const [removed] = config.projects.splice(index, 1);\n writeConfig(config);\n return removed;\n}\n\nexport function listProjects(): Project[] {\n const config = readConfig();\n return config.projects;\n}\n\nexport function getDefaults(): Config['defaults'] {\n const config = readConfig();\n return config.defaults;\n}\n\nexport function updateDefaults(updates: Partial<Config['defaults']>): void {\n const config = readConfig();\n config.defaults = { ...config.defaults, ...updates };\n writeConfig(config);\n}\n","import { execSync, spawn, type SpawnOptions } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createConnection } from 'node:net';\n\nexport function execCommand(command: string, options?: { cwd?: string }): string {\n try {\n return execSync(command, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n ...options,\n }).trim();\n } catch (error) {\n if (error instanceof Error && 'stderr' in error) {\n throw new Error((error as { stderr: string }).stderr || error.message);\n }\n throw error;\n }\n}\n\nexport function execCommandSafe(command: string, options?: { cwd?: string }): { success: boolean; output: string; error?: string } {\n try {\n const output = execSync(command, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n ...options,\n }).trim();\n return { success: true, output };\n } catch (error) {\n if (error instanceof Error && 'stderr' in error) {\n return { success: false, output: '', error: (error as { stderr: string }).stderr || error.message };\n }\n return { success: false, output: '', error: String(error) };\n }\n}\n\nexport function spawnCommand(\n command: string,\n args: string[],\n options?: SpawnOptions\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n stdio: ['inherit', 'pipe', 'pipe'],\n ...options,\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (data) => {\n stdout += data.toString();\n });\n\n child.stderr?.on('data', (data) => {\n stderr += data.toString();\n });\n\n child.on('close', (code) => {\n resolve({ code, stdout, stderr });\n });\n });\n}\n\nexport function spawnInteractive(command: string, args: string[], options?: SpawnOptions): Promise<number | null> {\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n stdio: 'inherit',\n ...options,\n });\n\n child.on('close', (code) => {\n resolve(code);\n });\n });\n}\n\nexport function commandExists(command: string): boolean {\n try {\n execSync(`which ${command}`, { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function isPortListening(port: number, host = '127.0.0.1'): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host }, () => {\n socket.destroy();\n resolve(true);\n });\n\n socket.on('error', () => {\n resolve(false);\n });\n\n socket.setTimeout(1000, () => {\n socket.destroy();\n resolve(false);\n });\n });\n}\n\nexport function detectProjectType(path: string): 'npm' | 'static' {\n const packageJsonPath = join(path, 'package.json');\n return existsSync(packageJsonPath) ? 'npm' : 'static';\n}\n\nexport function getPackageJsonScripts(path: string): string[] {\n const packageJsonPath = join(path, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return [];\n }\n\n try {\n const content = readFileSync(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n return Object.keys(pkg.scripts || {});\n } catch {\n return [];\n }\n}\n\nexport function validateHostname(hostname: string): boolean {\n // Basic hostname validation\n const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/;\n return hostnameRegex.test(hostname) && hostname.length <= 253;\n}\n\nexport function validateProjectName(name: string): boolean {\n // Project names should be alphanumeric with dashes/underscores\n const nameRegex = /^[a-zA-Z][a-zA-Z0-9_-]*$/;\n return nameRegex.test(name) && name.length <= 64;\n}\n\nexport function validatePort(port: number): boolean {\n return Number.isInteger(port) && port >= 1024 && port <= 65535;\n}\n\nexport function formatUptime(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) {\n return `${days}d ${hours % 24}h`;\n }\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n }\n if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n}\n\nexport function formatBytes(bytes: number): string {\n const units = ['B', 'KB', 'MB', 'GB'];\n let value = bytes;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n\n return `${value.toFixed(1)}${units[unitIndex]}`;\n}\n\nexport function getPm2ProcessName(projectName: string): string {\n return `bindler:${projectName}`;\n}\n","import { readConfig } from './config.js';\nimport { isPortListening } from './utils.js';\n\nconst PORT_RANGE_START = 3000;\nconst PORT_RANGE_END = 9000;\n\nexport function getUsedPorts(): number[] {\n const config = readConfig();\n return config.projects\n .filter((p) => p.type === 'npm' && p.port)\n .map((p) => p.port as number);\n}\n\nexport function findAvailablePort(startFrom = PORT_RANGE_START): number {\n const usedPorts = new Set(getUsedPorts());\n\n for (let port = startFrom; port <= PORT_RANGE_END; port++) {\n if (!usedPorts.has(port)) {\n return port;\n }\n }\n\n throw new Error(`No available ports in range ${PORT_RANGE_START}-${PORT_RANGE_END}`);\n}\n\nexport async function findAvailablePortWithCheck(startFrom = PORT_RANGE_START): Promise<number> {\n const usedPorts = new Set(getUsedPorts());\n\n for (let port = startFrom; port <= PORT_RANGE_END; port++) {\n if (!usedPorts.has(port)) {\n const listening = await isPortListening(port);\n if (!listening) {\n return port;\n }\n }\n }\n\n throw new Error(`No available ports in range ${PORT_RANGE_START}-${PORT_RANGE_END}`);\n}\n\nexport function isPortAvailable(port: number): boolean {\n const usedPorts = new Set(getUsedPorts());\n return !usedPorts.has(port);\n}\n\nexport function getPortsTable(): Array<{ port: number; project: string; hostname: string }> {\n const config = readConfig();\n return config.projects\n .filter((p) => p.type === 'npm' && p.port)\n .map((p) => ({\n port: p.port as number,\n project: p.name,\n hostname: p.hostname,\n }))\n .sort((a, b) => a.port - b.port);\n}\n","import { existsSync, writeFileSync, copyFileSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { Config, Project } from '../types.js';\nimport { execCommandSafe } from './utils.js';\nimport { getGeneratedDir } from './config.js';\n\nfunction generateLocationBlock(project: Project, indent = ' '): string[] {\n const lines: string[] = [];\n const locationPath = project.basePath || '/';\n const isRootLocation = locationPath === '/';\n\n if (project.type === 'static') {\n lines.push(`${indent}location ${locationPath} {`);\n if (isRootLocation) {\n // Use root for / location\n lines.push(`${indent} root ${project.path};`);\n } else {\n // Use alias for sub-paths\n lines.push(`${indent} alias ${project.path}/;`);\n }\n lines.push(`${indent} index index.html index.htm;`);\n lines.push(`${indent} try_files $uri $uri/ =404;`);\n lines.push(`${indent}}`);\n } else if (project.type === 'npm') {\n lines.push(`${indent}location ${locationPath} {`);\n lines.push(`${indent} proxy_pass http://127.0.0.1:${project.port};`);\n lines.push(`${indent} proxy_http_version 1.1;`);\n lines.push(`${indent} proxy_set_header Upgrade $http_upgrade;`);\n lines.push(`${indent} proxy_set_header Connection 'upgrade';`);\n lines.push(`${indent} proxy_set_header Host $host;`);\n lines.push(`${indent} proxy_set_header X-Real-IP $remote_addr;`);\n lines.push(`${indent} proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;`);\n lines.push(`${indent} proxy_set_header X-Forwarded-Proto $scheme;`);\n lines.push(`${indent} proxy_cache_bypass $http_upgrade;`);\n lines.push(`${indent}}`);\n }\n\n return lines;\n}\n\nexport function generateNginxConfig(config: Config): string {\n const { defaults, projects } = config;\n const listen = defaults.nginxListen;\n\n const lines: string[] = [\n '# Generated by bindler - DO NOT EDIT MANUALLY',\n `# Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n // Group projects by hostname for path-based routing\n const hostGroups = new Map<string, Project[]>();\n\n for (const project of projects) {\n if (project.enabled === false) {\n lines.push(`# Project \"${project.name}\" is disabled`);\n lines.push('');\n continue;\n }\n\n const existing = hostGroups.get(project.hostname) || [];\n existing.push(project);\n hostGroups.set(project.hostname, existing);\n }\n\n // Generate server blocks\n for (const [hostname, hostProjects] of hostGroups) {\n const projectNames = hostProjects.map((p) => p.name).join(', ');\n lines.push(`# Hostname: ${hostname} (${projectNames})`);\n lines.push('server {');\n lines.push(` listen ${listen};`);\n lines.push(` server_name ${hostname};`);\n lines.push('');\n\n // Sort projects by basePath length (longer paths first for nginx matching)\n const sortedProjects = [...hostProjects].sort((a, b) => {\n const pathA = a.basePath || '/';\n const pathB = b.basePath || '/';\n return pathB.length - pathA.length;\n });\n\n for (const project of sortedProjects) {\n lines.push(` # Project: ${project.name} (${project.type})`);\n lines.push(...generateLocationBlock(project));\n lines.push('');\n }\n\n lines.push('}');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nexport function writeNginxConfig(config: Config, dryRun = false): { path: string; content: string } {\n const nginxConfig = generateNginxConfig(config);\n const targetPath = config.defaults.nginxManagedPath;\n\n if (dryRun) {\n return { path: targetPath, content: nginxConfig };\n }\n\n // Ensure directory exists\n const targetDir = dirname(targetPath);\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n\n // Backup existing config\n if (existsSync(targetPath)) {\n const backupDir = join(getGeneratedDir(), 'backups');\n if (!existsSync(backupDir)) {\n mkdirSync(backupDir, { recursive: true });\n }\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const backupPath = join(backupDir, `nginx-${timestamp}.conf`);\n copyFileSync(targetPath, backupPath);\n }\n\n // Also save to generated dir\n const generatedPath = join(getGeneratedDir(), 'nginx.conf');\n writeFileSync(generatedPath, nginxConfig);\n\n // Write to target path\n writeFileSync(targetPath, nginxConfig);\n\n return { path: targetPath, content: nginxConfig };\n}\n\nexport function testNginxConfig(): { success: boolean; output: string } {\n const result = execCommandSafe('nginx -t 2>&1');\n return {\n success: result.success || result.output.includes('syntax is ok'),\n output: result.output || result.error || '',\n };\n}\n\nexport function reloadNginx(): { success: boolean; error?: string } {\n const isMac = process.platform === 'darwin';\n\n if (isMac) {\n // macOS: use brew services or nginx -s reload\n let result = execCommandSafe('brew services reload nginx');\n if (result.success) {\n return { success: true };\n }\n\n result = execCommandSafe('nginx -s reload');\n if (result.success) {\n return { success: true };\n }\n\n return { success: false, error: result.error || 'Failed to reload nginx. Try: brew services restart nginx' };\n }\n\n // Linux: try systemctl first\n let result = execCommandSafe('sudo systemctl reload nginx');\n if (result.success) {\n return { success: true };\n }\n\n // Try service command\n result = execCommandSafe('sudo service nginx reload');\n if (result.success) {\n return { success: true };\n }\n\n // Try nginx -s reload\n result = execCommandSafe('sudo nginx -s reload');\n if (result.success) {\n return { success: true };\n }\n\n return { success: false, error: result.error || 'Failed to reload nginx' };\n}\n\nexport function isNginxInstalled(): boolean {\n const result = execCommandSafe('which nginx');\n return result.success;\n}\n\nexport function isNginxRunning(): boolean {\n const isMac = process.platform === 'darwin';\n\n if (isMac) {\n // macOS: check brew services or pgrep\n let result = execCommandSafe('brew services list | grep nginx');\n if (result.success && result.output.includes('started')) {\n return true;\n }\n } else {\n // Linux: try systemctl\n let result = execCommandSafe('systemctl is-active nginx');\n if (result.success && result.output === 'active') {\n return true;\n }\n }\n\n // Fallback: try pgrep (works on both)\n const result = execCommandSafe('pgrep nginx');\n return result.success;\n}\n\nexport function getNginxVersion(): string | null {\n const result = execCommandSafe('nginx -v 2>&1');\n if (result.success || result.output) {\n const match = (result.output || result.error || '').match(/nginx\\/(\\S+)/);\n return match ? match[1] : null;\n }\n return null;\n}\n","import type { Project, PM2Process } from '../types.js';\nimport { execCommandSafe, spawnInteractive, getPm2ProcessName } from './utils.js';\n\nexport function isPm2Installed(): boolean {\n const result = execCommandSafe('which pm2');\n return result.success;\n}\n\nexport function getPm2List(): PM2Process[] {\n const result = execCommandSafe('pm2 jlist');\n\n if (!result.success) {\n return [];\n }\n\n try {\n const processes = JSON.parse(result.output);\n return processes.map((p: Record<string, unknown>) => ({\n name: p.name as string,\n pm_id: p.pm_id as number,\n status: (p.pm2_env as Record<string, unknown>)?.status as PM2Process['status'],\n cpu: p.monit ? (p.monit as Record<string, number>).cpu : 0,\n memory: p.monit ? (p.monit as Record<string, number>).memory : 0,\n uptime: (p.pm2_env as Record<string, unknown>)?.pm_uptime\n ? Date.now() - ((p.pm2_env as Record<string, unknown>).pm_uptime as number)\n : 0,\n restarts: (p.pm2_env as Record<string, unknown>)?.restart_time as number || 0,\n }));\n } catch {\n return [];\n }\n}\n\nexport function getProcessByName(name: string): PM2Process | undefined {\n const pm2Name = getPm2ProcessName(name);\n const processes = getPm2List();\n return processes.find((p) => p.name === pm2Name);\n}\n\nexport function isProcessRunning(name: string): boolean {\n const process = getProcessByName(name);\n return process?.status === 'online';\n}\n\nexport function startProject(project: Project): { success: boolean; error?: string } {\n if (project.type !== 'npm') {\n return { success: false, error: 'Only npm projects can be started with PM2' };\n }\n\n if (!project.start) {\n return { success: false, error: 'No start command configured' };\n }\n\n const pm2Name = getPm2ProcessName(project.name);\n const existingProcess = getProcessByName(project.name);\n\n // Build environment variables string\n const envVars: string[] = [];\n if (project.env) {\n for (const [key, value] of Object.entries(project.env)) {\n envVars.push(`${key}=${value}`);\n }\n }\n\n let command: string;\n\n if (existingProcess) {\n // Process exists, restart it\n command = `pm2 restart \"${pm2Name}\"`;\n } else {\n // Start new process\n const envFlags = envVars.length > 0 ? envVars.map((e) => `--env ${e}`).join(' ') : '';\n command = `pm2 start --name \"${pm2Name}\" --cwd \"${project.path}\" ${envFlags} -- bash -lc \"${project.start}\"`;\n }\n\n const result = execCommandSafe(command);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n // Save PM2 process list\n execCommandSafe('pm2 save');\n\n return { success: true };\n}\n\nexport function stopProject(name: string): { success: boolean; error?: string } {\n const pm2Name = getPm2ProcessName(name);\n const result = execCommandSafe(`pm2 stop \"${pm2Name}\"`);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n execCommandSafe('pm2 save');\n return { success: true };\n}\n\nexport function restartProject(name: string): { success: boolean; error?: string } {\n const pm2Name = getPm2ProcessName(name);\n const result = execCommandSafe(`pm2 restart \"${pm2Name}\"`);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n execCommandSafe('pm2 save');\n return { success: true };\n}\n\nexport function deleteProject(name: string): { success: boolean; error?: string } {\n const pm2Name = getPm2ProcessName(name);\n const result = execCommandSafe(`pm2 delete \"${pm2Name}\"`);\n\n if (!result.success) {\n // It's okay if the process doesn't exist\n if (result.error?.includes('not found')) {\n return { success: true };\n }\n return { success: false, error: result.error };\n }\n\n execCommandSafe('pm2 save');\n return { success: true };\n}\n\nexport async function showLogs(name: string, follow = false, lines = 200): Promise<number | null> {\n const pm2Name = getPm2ProcessName(name);\n const args = ['logs', pm2Name, '--lines', String(lines)];\n\n if (!follow) {\n args.push('--nostream');\n }\n\n return spawnInteractive('pm2', args);\n}\n\nexport function startAllProjects(projects: Project[]): Array<{ name: string; success: boolean; error?: string }> {\n return projects\n .filter((p) => p.type === 'npm')\n .map((project) => ({\n name: project.name,\n ...startProject(project),\n }));\n}\n\nexport function stopAllProjects(projects: Project[]): Array<{ name: string; success: boolean; error?: string }> {\n return projects\n .filter((p) => p.type === 'npm')\n .map((project) => ({\n name: project.name,\n ...stopProject(project.name),\n }));\n}\n\nexport function restartAllProjects(projects: Project[]): Array<{ name: string; success: boolean; error?: string }> {\n return projects\n .filter((p) => p.type === 'npm')\n .map((project) => ({\n name: project.name,\n ...restartProject(project.name),\n }));\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { listProjects } from '../lib/config.js';\nimport { getProcessByName } from '../lib/pm2.js';\nimport { getPm2ProcessName } from '../lib/utils.js';\n\nexport async function listCommand(): Promise<void> {\n const projects = listProjects();\n\n if (projects.length === 0) {\n console.log(chalk.yellow('No projects registered.'));\n console.log(chalk.dim(`Run ${chalk.cyan('bindler new')} to create one.`));\n return;\n }\n\n const table = new Table({\n head: [\n chalk.cyan('Name'),\n chalk.cyan('Type'),\n chalk.cyan('Hostname'),\n chalk.cyan('Port'),\n chalk.cyan('Path'),\n chalk.cyan('Status'),\n ],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const project of projects) {\n let status = '-';\n\n if (project.type === 'npm') {\n const process = getProcessByName(project.name);\n if (process) {\n status = process.status === 'online'\n ? chalk.green('online')\n : process.status === 'stopped'\n ? chalk.yellow('stopped')\n : chalk.red(process.status);\n } else {\n status = chalk.dim('not started');\n }\n } else {\n status = project.enabled !== false ? chalk.green('serving') : chalk.yellow('disabled');\n }\n\n if (project.enabled === false) {\n status = chalk.yellow('disabled');\n }\n\n table.push([\n project.name,\n project.type,\n project.hostname,\n project.port?.toString() || '-',\n project.path,\n status,\n ]);\n }\n\n console.log(table.toString());\n console.log(chalk.dim(`\\n${projects.length} project(s) registered`));\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { listProjects } from '../lib/config.js';\nimport { getProcessByName, getPm2List } from '../lib/pm2.js';\nimport { isPortListening, formatUptime, formatBytes, getPm2ProcessName } from '../lib/utils.js';\nimport type { ProjectStatus } from '../types.js';\n\nexport async function statusCommand(): Promise<void> {\n const projects = listProjects();\n\n if (projects.length === 0) {\n console.log(chalk.yellow('No projects registered.'));\n return;\n }\n\n const statuses: ProjectStatus[] = [];\n\n for (const project of projects) {\n const status: ProjectStatus = { ...project };\n\n if (project.type === 'npm') {\n const process = getProcessByName(project.name);\n status.pm2Name = getPm2ProcessName(project.name);\n\n if (process) {\n status.pm2Status = process.status;\n } else {\n status.pm2Status = 'not_managed';\n }\n\n if (project.port) {\n status.portListening = await isPortListening(project.port);\n }\n } else {\n status.pm2Status = 'n/a';\n }\n\n statuses.push(status);\n }\n\n const table = new Table({\n head: [\n chalk.cyan('Name'),\n chalk.cyan('Type'),\n chalk.cyan('Hostname'),\n chalk.cyan('Port'),\n chalk.cyan('PM2 Status'),\n chalk.cyan('Port Check'),\n ],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const status of statuses) {\n let pm2StatusStr = '-';\n let portCheckStr = '-';\n\n if (status.type === 'npm') {\n switch (status.pm2Status) {\n case 'online':\n pm2StatusStr = chalk.green('online');\n break;\n case 'stopped':\n pm2StatusStr = chalk.yellow('stopped');\n break;\n case 'errored':\n pm2StatusStr = chalk.red('errored');\n break;\n case 'not_managed':\n pm2StatusStr = chalk.dim('not started');\n break;\n default:\n pm2StatusStr = chalk.dim(status.pm2Status || '-');\n }\n\n portCheckStr = status.portListening\n ? chalk.green('listening')\n : chalk.red('not listening');\n }\n\n if (status.enabled === false) {\n pm2StatusStr = chalk.yellow('disabled');\n portCheckStr = chalk.dim('-');\n }\n\n table.push([\n status.name,\n status.type,\n status.hostname,\n status.port?.toString() || '-',\n pm2StatusStr,\n portCheckStr,\n ]);\n }\n\n console.log(table.toString());\n\n // Show PM2 process details for running apps\n const runningProcesses = getPm2List().filter((p) => p.name.startsWith('bindler:'));\n\n if (runningProcesses.length > 0) {\n console.log(chalk.bold('\\nPM2 Process Details:'));\n\n const detailTable = new Table({\n head: [\n chalk.cyan('Process'),\n chalk.cyan('CPU'),\n chalk.cyan('Memory'),\n chalk.cyan('Uptime'),\n chalk.cyan('Restarts'),\n ],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const proc of runningProcesses) {\n detailTable.push([\n proc.name.replace('bindler:', ''),\n `${proc.cpu}%`,\n formatBytes(proc.memory),\n formatUptime(proc.uptime),\n String(proc.restarts),\n ]);\n }\n\n console.log(detailTable.toString());\n }\n}\n","import chalk from 'chalk';\nimport { getProject, listProjects } from '../lib/config.js';\nimport { startProject, startAllProjects } from '../lib/pm2.js';\n\ninterface StartOptions {\n all?: boolean;\n}\n\nexport async function startCommand(name: string | undefined, options: StartOptions): Promise<void> {\n if (options.all) {\n const projects = listProjects();\n const npmProjects = projects.filter((p) => p.type === 'npm');\n\n if (npmProjects.length === 0) {\n console.log(chalk.yellow('No npm projects to start.'));\n return;\n }\n\n console.log(chalk.blue(`Starting ${npmProjects.length} npm project(s)...`));\n\n const results = startAllProjects(npmProjects);\n\n for (const result of results) {\n if (result.success) {\n console.log(chalk.green(` ✓ ${result.name}`));\n } else {\n console.log(chalk.red(` ✗ ${result.name}: ${result.error}`));\n }\n }\n\n const succeeded = results.filter((r) => r.success).length;\n console.log(chalk.dim(`\\n${succeeded}/${results.length} started successfully`));\n return;\n }\n\n if (!name) {\n console.error(chalk.red('Error: Project name is required. Use --all to start all projects.'));\n process.exit(1);\n }\n\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n if (project.type !== 'npm') {\n console.log(chalk.blue(`Project \"${name}\" is a static site - no process to start.`));\n console.log(chalk.dim('Static sites are served directly by nginx.'));\n return;\n }\n\n console.log(chalk.blue(`Starting ${name}...`));\n\n const result = startProject(project);\n\n if (result.success) {\n console.log(chalk.green(`✓ ${name} started successfully`));\n console.log(chalk.dim(` Port: ${project.port}`));\n console.log(chalk.dim(` URL: https://${project.hostname}`));\n } else {\n console.error(chalk.red(`✗ Failed to start ${name}: ${result.error}`));\n process.exit(1);\n }\n}\n","import chalk from 'chalk';\nimport { getProject, listProjects } from '../lib/config.js';\nimport { stopProject, stopAllProjects } from '../lib/pm2.js';\n\ninterface StopOptions {\n all?: boolean;\n}\n\nexport async function stopCommand(name: string | undefined, options: StopOptions): Promise<void> {\n if (options.all) {\n const projects = listProjects();\n const npmProjects = projects.filter((p) => p.type === 'npm');\n\n if (npmProjects.length === 0) {\n console.log(chalk.yellow('No npm projects to stop.'));\n return;\n }\n\n console.log(chalk.blue(`Stopping ${npmProjects.length} npm project(s)...`));\n\n const results = stopAllProjects(npmProjects);\n\n for (const result of results) {\n if (result.success) {\n console.log(chalk.green(` ✓ ${result.name}`));\n } else {\n console.log(chalk.red(` ✗ ${result.name}: ${result.error}`));\n }\n }\n\n const succeeded = results.filter((r) => r.success).length;\n console.log(chalk.dim(`\\n${succeeded}/${results.length} stopped successfully`));\n return;\n }\n\n if (!name) {\n console.error(chalk.red('Error: Project name is required. Use --all to stop all projects.'));\n process.exit(1);\n }\n\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n if (project.type !== 'npm') {\n console.log(chalk.yellow(`Project \"${name}\" is a static site - no process to stop.`));\n return;\n }\n\n console.log(chalk.blue(`Stopping ${name}...`));\n\n const result = stopProject(name);\n\n if (result.success) {\n console.log(chalk.green(`✓ ${name} stopped successfully`));\n } else {\n console.error(chalk.red(`✗ Failed to stop ${name}: ${result.error}`));\n process.exit(1);\n }\n}\n","import chalk from 'chalk';\nimport { getProject, listProjects } from '../lib/config.js';\nimport { restartProject, restartAllProjects, getProcessByName, startProject } from '../lib/pm2.js';\n\ninterface RestartOptions {\n all?: boolean;\n}\n\nexport async function restartCommand(name: string | undefined, options: RestartOptions): Promise<void> {\n if (options.all) {\n const projects = listProjects();\n const npmProjects = projects.filter((p) => p.type === 'npm');\n\n if (npmProjects.length === 0) {\n console.log(chalk.yellow('No npm projects to restart.'));\n return;\n }\n\n console.log(chalk.blue(`Restarting ${npmProjects.length} npm project(s)...`));\n\n const results = restartAllProjects(npmProjects);\n\n for (const result of results) {\n if (result.success) {\n console.log(chalk.green(` ✓ ${result.name}`));\n } else {\n console.log(chalk.red(` ✗ ${result.name}: ${result.error}`));\n }\n }\n\n const succeeded = results.filter((r) => r.success).length;\n console.log(chalk.dim(`\\n${succeeded}/${results.length} restarted successfully`));\n return;\n }\n\n if (!name) {\n console.error(chalk.red('Error: Project name is required. Use --all to restart all projects.'));\n process.exit(1);\n }\n\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n if (project.type !== 'npm') {\n console.log(chalk.yellow(`Project \"${name}\" is a static site - no process to restart.`));\n return;\n }\n\n console.log(chalk.blue(`Restarting ${name}...`));\n\n // Check if process exists\n const process = getProcessByName(name);\n\n let result;\n if (process) {\n result = restartProject(name);\n } else {\n // Process doesn't exist, start it\n console.log(chalk.dim('Process not running, starting...'));\n result = startProject(project);\n }\n\n if (result.success) {\n console.log(chalk.green(`✓ ${name} restarted successfully`));\n } else {\n console.error(chalk.red(`✗ Failed to restart ${name}: ${result.error}`));\n process.exit(1);\n }\n}\n","import chalk from 'chalk';\nimport { getProject } from '../lib/config.js';\nimport { showLogs, getProcessByName } from '../lib/pm2.js';\n\ninterface LogsOptions {\n follow?: boolean;\n lines?: number;\n}\n\nexport async function logsCommand(name: string, options: LogsOptions): Promise<void> {\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n if (project.type !== 'npm') {\n console.log(chalk.yellow(`Project \"${name}\" is a static site - no logs available.`));\n console.log(chalk.dim('Check nginx access/error logs instead:'));\n console.log(chalk.dim(' /var/log/nginx/access.log'));\n console.log(chalk.dim(' /var/log/nginx/error.log'));\n return;\n }\n\n const process = getProcessByName(name);\n\n if (!process) {\n console.log(chalk.yellow(`Project \"${name}\" has not been started yet.`));\n console.log(chalk.dim(`Run ${chalk.cyan(`bindler start ${name}`)} first.`));\n return;\n }\n\n const lines = options.lines || 200;\n const follow = options.follow || false;\n\n if (follow) {\n console.log(chalk.dim(`Following logs for ${name}... (Ctrl+C to exit)`));\n }\n\n await showLogs(name, follow, lines);\n}\n","import chalk from 'chalk';\nimport { getProject, updateProject } from '../lib/config.js';\nimport { validateHostname, validatePort } from '../lib/utils.js';\nimport { isPortAvailable } from '../lib/ports.js';\nimport type { Project } from '../types.js';\n\ninterface UpdateOptions {\n hostname?: string;\n port?: string;\n start?: string;\n path?: string;\n env?: string[];\n enable?: boolean;\n disable?: boolean;\n}\n\nexport async function updateCommand(name: string, options: UpdateOptions): Promise<void> {\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n const updates: Partial<Project> = {};\n\n // Handle hostname update\n if (options.hostname) {\n if (!validateHostname(options.hostname)) {\n console.error(chalk.red('Error: Invalid hostname format'));\n process.exit(1);\n }\n updates.hostname = options.hostname;\n }\n\n // Handle port update\n if (options.port) {\n const port = parseInt(options.port, 10);\n if (!validatePort(port)) {\n console.error(chalk.red('Error: Invalid port. Use a number between 1024 and 65535.'));\n process.exit(1);\n }\n if (!isPortAvailable(port) && port !== project.port) {\n console.error(chalk.red(`Error: Port ${port} is already in use by another project.`));\n process.exit(1);\n }\n updates.port = port;\n\n // Also update PORT env var if it exists\n if (project.env?.PORT) {\n updates.env = { ...project.env, PORT: String(port) };\n }\n }\n\n // Handle start command update\n if (options.start) {\n if (project.type !== 'npm') {\n console.error(chalk.red('Error: Start command only applies to npm projects'));\n process.exit(1);\n }\n updates.start = options.start;\n }\n\n // Handle path update\n if (options.path) {\n updates.path = options.path;\n }\n\n // Handle env updates\n if (options.env && options.env.length > 0) {\n const env = { ...(project.env || {}) };\n for (const envStr of options.env) {\n const [key, ...valueParts] = envStr.split('=');\n if (!key) {\n console.error(chalk.red(`Error: Invalid env format: ${envStr}. Use KEY=value`));\n process.exit(1);\n }\n env[key] = valueParts.join('=');\n }\n updates.env = env;\n }\n\n // Handle enable/disable\n if (options.enable) {\n updates.enabled = true;\n } else if (options.disable) {\n updates.enabled = false;\n }\n\n if (Object.keys(updates).length === 0) {\n console.log(chalk.yellow('No updates specified.'));\n console.log(chalk.dim('Available options: --hostname, --port, --start, --path, --env, --enable, --disable'));\n return;\n }\n\n try {\n updateProject(name, updates);\n\n console.log(chalk.green(`✓ Project \"${name}\" updated successfully`));\n\n for (const [key, value] of Object.entries(updates)) {\n console.log(chalk.dim(` ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`));\n }\n\n console.log(chalk.dim(`\\nRun ${chalk.cyan('sudo bindler apply')} to apply changes to nginx.`));\n\n if (project.type === 'npm' && (updates.port || updates.start || updates.env)) {\n console.log(chalk.dim(`Run ${chalk.cyan(`bindler restart ${name}`)} to apply changes to the running process.`));\n }\n } catch (error) {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : error}`));\n process.exit(1);\n }\n}\n","import { writeFileSync, readFileSync, unlinkSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport chalk from 'chalk';\nimport { getProject, updateProject, readConfig, writeConfig } from '../lib/config.js';\nimport { spawnInteractive } from '../lib/utils.js';\nimport type { Project } from '../types.js';\n\nexport async function editCommand(name: string): Promise<void> {\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n const editor = process.env.EDITOR || process.env.VISUAL || 'vi';\n const tmpFile = join(tmpdir(), `bindler-${name}-${Date.now()}.json`);\n\n // Write project config to temp file\n writeFileSync(tmpFile, JSON.stringify(project, null, 2) + '\\n');\n\n console.log(chalk.dim(`Opening ${name} config in ${editor}...`));\n\n // Open editor\n const exitCode = await spawnInteractive(editor, [tmpFile]);\n\n if (exitCode !== 0) {\n console.error(chalk.red('Editor exited with error'));\n unlinkSync(tmpFile);\n process.exit(1);\n }\n\n // Read edited content\n let editedContent: string;\n try {\n editedContent = readFileSync(tmpFile, 'utf-8');\n } catch (error) {\n console.error(chalk.red('Failed to read edited file'));\n process.exit(1);\n } finally {\n unlinkSync(tmpFile);\n }\n\n // Parse edited JSON\n let editedProject: Project;\n try {\n editedProject = JSON.parse(editedContent);\n } catch (error) {\n console.error(chalk.red('Error: Invalid JSON in edited file'));\n process.exit(1);\n }\n\n // Validate that name wasn't changed\n if (editedProject.name !== project.name) {\n console.error(chalk.red('Error: Cannot change project name via edit. Use a new project instead.'));\n process.exit(1);\n }\n\n // Check if anything changed\n const originalStr = JSON.stringify(project);\n const editedStr = JSON.stringify(editedProject);\n\n if (originalStr === editedStr) {\n console.log(chalk.yellow('No changes made.'));\n return;\n }\n\n // Update the project\n try {\n const config = readConfig();\n const index = config.projects.findIndex((p) => p.name === name);\n\n if (index === -1) {\n console.error(chalk.red('Error: Project not found'));\n process.exit(1);\n }\n\n config.projects[index] = editedProject;\n writeConfig(config);\n\n console.log(chalk.green(`✓ Project \"${name}\" updated successfully`));\n console.log(chalk.dim(`\\nRun ${chalk.cyan('sudo bindler apply')} to apply changes to nginx.`));\n } catch (error) {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : error}`));\n process.exit(1);\n }\n}\n","import inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { getProject, removeProject } from '../lib/config.js';\nimport { deleteProject as deletePm2Process, getProcessByName } from '../lib/pm2.js';\n\ninterface RemoveOptions {\n force?: boolean;\n apply?: boolean;\n}\n\nexport async function removeCommand(name: string, options: RemoveOptions): Promise<void> {\n const project = getProject(name);\n\n if (!project) {\n console.error(chalk.red(`Error: Project \"${name}\" not found`));\n process.exit(1);\n }\n\n // Confirm removal unless --force\n if (!options.force) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `Are you sure you want to remove project \"${name}\" (${project.hostname})?`,\n default: false,\n },\n ]);\n\n if (!confirm) {\n console.log(chalk.yellow('Cancelled.'));\n return;\n }\n }\n\n // Stop and delete PM2 process if it exists\n if (project.type === 'npm') {\n const process = getProcessByName(name);\n if (process) {\n console.log(chalk.dim('Stopping PM2 process...'));\n deletePm2Process(name);\n }\n }\n\n // Remove from config\n try {\n removeProject(name);\n console.log(chalk.green(`✓ Project \"${name}\" removed from registry`));\n console.log(chalk.dim(`\\nRun ${chalk.cyan('sudo bindler apply')} to update nginx configuration.`));\n console.log(chalk.yellow('\\nNote: The project files and Cloudflare DNS routes were not removed.'));\n console.log(chalk.dim(` Project path: ${project.path}`));\n console.log(chalk.dim(` To remove DNS route manually: cloudflared tunnel route dns --remove ${project.hostname}`));\n } catch (error) {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : error}`));\n process.exit(1);\n }\n}\n","import chalk from 'chalk';\nimport { readConfig, getDefaults } from '../lib/config.js';\nimport { generateNginxConfig, writeNginxConfig, testNginxConfig, reloadNginx } from '../lib/nginx.js';\nimport { routeDnsForAllProjects, isCloudflaredInstalled } from '../lib/cloudflare.js';\nimport { execCommandSafe } from '../lib/utils.js';\n\ninterface ApplyOptions {\n dryRun?: boolean;\n noReload?: boolean;\n noCloudflare?: boolean;\n ssl?: boolean;\n}\n\nexport async function applyCommand(options: ApplyOptions): Promise<void> {\n const config = readConfig();\n const defaults = getDefaults();\n\n if (config.projects.length === 0) {\n console.log(chalk.yellow('No projects registered. Nothing to apply.'));\n return;\n }\n\n console.log(chalk.blue('Applying configuration...\\n'));\n\n // Step 1: Generate nginx config\n console.log(chalk.dim('Generating nginx configuration...'));\n\n if (options.dryRun) {\n const nginxConfig = generateNginxConfig(config);\n console.log(chalk.cyan('\\n--- Generated nginx config (dry-run) ---\\n'));\n console.log(nginxConfig);\n console.log(chalk.cyan('--- End of config ---\\n'));\n console.log(chalk.yellow('Dry run mode - no changes were made.'));\n return;\n }\n\n // Step 2: Write nginx config\n try {\n const { path, content } = writeNginxConfig(config);\n console.log(chalk.green(` ✓ Wrote nginx config to ${path}`));\n } catch (error) {\n const errMsg = error instanceof Error ? error.message : String(error);\n console.error(chalk.red(` ✗ Failed to write nginx config: ${errMsg}`));\n if (errMsg.includes('EACCES') || errMsg.includes('permission denied')) {\n console.log(chalk.yellow(`\\nTry running with sudo: ${chalk.cyan('sudo bindler apply')}`));\n }\n process.exit(1);\n }\n\n // Step 3: Test nginx config\n console.log(chalk.dim('Testing nginx configuration...'));\n const testResult = testNginxConfig();\n\n if (!testResult.success) {\n console.error(chalk.red(' ✗ Nginx configuration test failed:'));\n console.error(chalk.red(testResult.output));\n console.log(chalk.yellow('\\nConfiguration was written but nginx was NOT reloaded.'));\n console.log(chalk.dim('Fix the configuration and run `sudo bindler apply` again.'));\n process.exit(1);\n }\n\n console.log(chalk.green(' ✓ Nginx configuration test passed'));\n\n // Step 4: Reload nginx\n if (!options.noReload) {\n console.log(chalk.dim('Reloading nginx...'));\n const reloadResult = reloadNginx();\n\n if (!reloadResult.success) {\n console.error(chalk.red(` ✗ Failed to reload nginx: ${reloadResult.error}`));\n console.log(chalk.dim('You may need to reload nginx manually: sudo systemctl reload nginx'));\n process.exit(1);\n }\n\n console.log(chalk.green(' ✓ Nginx reloaded successfully'));\n } else {\n console.log(chalk.yellow(' - Skipped nginx reload (--no-reload)'));\n }\n\n // Step 5: Cloudflare DNS routing (tunnel mode only)\n const isDirectMode = defaults.mode === 'direct';\n\n if (isDirectMode) {\n console.log(chalk.dim('\\n - Direct mode: skipping Cloudflare DNS routes'));\n } else if (!options.noCloudflare && defaults.applyCloudflareDnsRoutes) {\n console.log(chalk.dim('\\nConfiguring Cloudflare DNS routes...'));\n\n if (!isCloudflaredInstalled()) {\n console.log(chalk.yellow(' - cloudflared not installed, skipping DNS routes'));\n } else {\n const dnsResults = routeDnsForAllProjects();\n\n if (dnsResults.length === 0) {\n console.log(chalk.dim(' No hostnames to route'));\n } else {\n for (const result of dnsResults) {\n if (result.skipped) {\n console.log(chalk.dim(` - ${result.hostname} (local - skipped)`));\n } else if (result.success) {\n const msg = result.output?.includes('already exists') ? 'exists' : 'routed';\n console.log(chalk.green(` ✓ ${result.hostname} (${msg})`));\n } else {\n console.log(chalk.red(` ✗ ${result.hostname}: ${result.error}`));\n }\n }\n }\n }\n } else if (options.noCloudflare) {\n console.log(chalk.dim('\\n - Skipped Cloudflare DNS routes (--no-cloudflare)'));\n }\n\n // Step 6: SSL certificate setup (direct mode only)\n if (isDirectMode && defaults.sslEnabled && (options.ssl !== false)) {\n console.log(chalk.dim('\\nSetting up SSL certificates...'));\n\n const hostnames = config.projects\n .filter((p) => p.enabled !== false && !p.local)\n .map((p) => p.hostname);\n\n if (hostnames.length === 0) {\n console.log(chalk.dim(' No hostnames to secure'));\n } else {\n const certbotResult = execCommandSafe('which certbot');\n if (!certbotResult.success) {\n console.log(chalk.yellow(' - certbot not installed, skipping SSL'));\n console.log(chalk.dim(' Run: bindler setup --direct'));\n } else {\n for (const hostname of hostnames) {\n console.log(chalk.dim(` Requesting certificate for ${hostname}...`));\n const email = defaults.sslEmail || 'admin@' + hostname.split('.').slice(-2).join('.');\n const result = execCommandSafe(\n `sudo certbot --nginx -d ${hostname} --non-interactive --agree-tos --email ${email} 2>&1`\n );\n\n if (result.success || result.output?.includes('Certificate not yet due for renewal')) {\n console.log(chalk.green(` ✓ ${hostname} (secured)`));\n } else if (result.output?.includes('already exists')) {\n console.log(chalk.green(` ✓ ${hostname} (exists)`));\n } else {\n console.log(chalk.yellow(` ! ${hostname}: ${result.error || 'failed'}`));\n console.log(chalk.dim(' Run manually: sudo certbot --nginx -d ' + hostname));\n }\n }\n }\n }\n }\n\n // Summary\n console.log(chalk.green('\\n✓ Configuration applied successfully!'));\n console.log(chalk.dim(`\\n${config.projects.length} project(s) configured:`));\n\n for (const project of config.projects) {\n const status = project.enabled !== false ? chalk.green('enabled') : chalk.yellow('disabled');\n console.log(chalk.dim(` - ${project.name} → ${project.hostname} (${status})`));\n }\n}\n","import { execCommandSafe } from './utils.js';\nimport { readConfig } from './config.js';\n\nexport function isCloudflaredInstalled(): boolean {\n const result = execCommandSafe('which cloudflared');\n return result.success;\n}\n\nexport function getCloudflaredVersion(): string | null {\n const result = execCommandSafe('cloudflared --version');\n if (result.success) {\n const match = result.output.match(/cloudflared version (\\S+)/);\n return match ? match[1] : result.output;\n }\n return null;\n}\n\nexport function listTunnels(): Array<{ id: string; name: string; createdAt: string }> {\n const result = execCommandSafe('cloudflared tunnel list --output json');\n\n if (!result.success) {\n return [];\n }\n\n try {\n const tunnels = JSON.parse(result.output);\n return tunnels.map((t: Record<string, unknown>) => ({\n id: t.id as string,\n name: t.name as string,\n createdAt: t.created_at as string,\n }));\n } catch {\n return [];\n }\n}\n\nexport function getTunnelByName(name: string): { id: string; name: string } | null {\n const tunnels = listTunnels();\n const tunnel = tunnels.find((t) => t.name === name);\n return tunnel ? { id: tunnel.id, name: tunnel.name } : null;\n}\n\nexport function routeDns(tunnelName: string, hostname: string): { success: boolean; error?: string; output?: string } {\n const result = execCommandSafe(`cloudflared tunnel route dns \"${tunnelName}\" \"${hostname}\"`);\n\n if (!result.success) {\n // Check if it's just \"already exists\" which is fine\n if (result.error?.includes('already exists') || result.output?.includes('already exists')) {\n return { success: true, output: 'DNS route already exists' };\n }\n return { success: false, error: result.error };\n }\n\n return { success: true, output: result.output };\n}\n\nexport function routeDnsForAllProjects(): Array<{ hostname: string; success: boolean; error?: string; output?: string; skipped?: boolean }> {\n const config = readConfig();\n const { tunnelName, applyCloudflareDnsRoutes } = config.defaults;\n\n if (!applyCloudflareDnsRoutes) {\n return [];\n }\n\n const results: Array<{ hostname: string; success: boolean; error?: string; output?: string; skipped?: boolean }> = [];\n\n for (const project of config.projects) {\n if (project.enabled === false) {\n continue;\n }\n\n // Skip local projects\n if (project.local) {\n results.push({\n hostname: project.hostname,\n success: true,\n skipped: true,\n output: 'Local project - skipped',\n });\n continue;\n }\n\n const result = routeDns(tunnelName, project.hostname);\n results.push({\n hostname: project.hostname,\n ...result,\n });\n }\n\n return results;\n}\n\nexport function isTunnelRunning(tunnelName: string): boolean {\n // Check if cloudflared process is running for this tunnel\n const result = execCommandSafe(`pgrep -f \"cloudflared.*tunnel.*run.*${tunnelName}\"`);\n return result.success;\n}\n\nexport function getTunnelInfo(tunnelName: string): { exists: boolean; running: boolean; id?: string } {\n const tunnel = getTunnelByName(tunnelName);\n\n if (!tunnel) {\n return { exists: false, running: false };\n }\n\n return {\n exists: true,\n running: isTunnelRunning(tunnelName),\n id: tunnel.id,\n };\n}\n","import chalk from 'chalk';\nimport { existsSync } from 'node:fs';\nimport { configExists, getConfigPath, getDefaults, readConfig } from '../lib/config.js';\nimport { isNginxInstalled, isNginxRunning, getNginxVersion } from '../lib/nginx.js';\nimport { isPm2Installed, getPm2List } from '../lib/pm2.js';\nimport { isCloudflaredInstalled, getCloudflaredVersion, getTunnelInfo } from '../lib/cloudflare.js';\nimport { commandExists, execCommandSafe } from '../lib/utils.js';\n\ninterface CheckResult {\n name: string;\n status: 'ok' | 'warning' | 'error';\n message: string;\n fix?: string;\n}\n\nexport async function doctorCommand(): Promise<void> {\n console.log(chalk.blue('Running diagnostics...\\n'));\n\n const checks: CheckResult[] = [];\n\n // Check Node.js version\n const nodeVersion = process.version;\n const nodeMajor = parseInt(nodeVersion.slice(1).split('.')[0], 10);\n checks.push({\n name: 'Node.js',\n status: nodeMajor >= 18 ? 'ok' : 'warning',\n message: `Version ${nodeVersion}`,\n fix: nodeMajor < 18 ? 'Upgrade to Node.js 18 or later' : undefined,\n });\n\n // Check nginx\n if (isNginxInstalled()) {\n const version = getNginxVersion();\n if (isNginxRunning()) {\n checks.push({\n name: 'nginx',\n status: 'ok',\n message: `Installed (${version || 'version unknown'}) and running`,\n });\n\n // macOS: Check if nginx is running as current user (not root/nobody)\n const isMac = process.platform === 'darwin';\n if (isMac) {\n const currentUser = process.env.USER || '';\n const psResult = execCommandSafe('ps aux | grep \"nginx: worker\" | grep -v grep | head -1');\n if (psResult.success && psResult.output) {\n const nginxUser = psResult.output.split(/\\s+/)[0];\n if (nginxUser && nginxUser !== currentUser && (nginxUser === 'nobody' || nginxUser === 'root')) {\n checks.push({\n name: 'nginx user',\n status: 'warning',\n message: `nginx running as \"${nginxUser}\" (should be \"${currentUser}\")`,\n fix: `Fix permissions: sudo chown -R ${currentUser}:staff /opt/homebrew/var/log/nginx /opt/homebrew/var/run && sudo killall nginx && brew services start nginx`,\n });\n } else {\n checks.push({\n name: 'nginx user',\n status: 'ok',\n message: `Running as \"${nginxUser}\"`,\n });\n }\n }\n }\n } else {\n const isMac = process.platform === 'darwin';\n checks.push({\n name: 'nginx',\n status: 'warning',\n message: `Installed (${version || 'version unknown'}) but not running`,\n fix: isMac ? 'Start nginx: brew services start nginx' : 'Start nginx: sudo systemctl start nginx',\n });\n }\n } else {\n checks.push({\n name: 'nginx',\n status: 'error',\n message: 'Not installed',\n fix: 'Run `bindler setup` to install',\n });\n }\n\n // Check PM2\n if (isPm2Installed()) {\n const processes = getPm2List();\n const bindlerProcesses = processes.filter((p) => p.name.startsWith('bindler:'));\n checks.push({\n name: 'PM2',\n status: 'ok',\n message: `Installed, ${bindlerProcesses.length} bindler process(es) managed`,\n });\n } else {\n checks.push({\n name: 'PM2',\n status: 'error',\n message: 'Not installed',\n fix: 'Run `bindler setup` to install',\n });\n }\n\n // Check cloudflared\n if (isCloudflaredInstalled()) {\n const version = getCloudflaredVersion();\n checks.push({\n name: 'cloudflared',\n status: 'ok',\n message: `Installed (${version || 'version unknown'})`,\n });\n\n // Check tunnel configuration\n if (configExists()) {\n const defaults = getDefaults();\n const tunnelInfo = getTunnelInfo(defaults.tunnelName);\n\n if (tunnelInfo.exists) {\n checks.push({\n name: 'Cloudflare Tunnel',\n status: tunnelInfo.running ? 'ok' : 'warning',\n message: tunnelInfo.running\n ? `Tunnel \"${defaults.tunnelName}\" exists and running`\n : `Tunnel \"${defaults.tunnelName}\" exists but not running`,\n fix: !tunnelInfo.running\n ? `Start tunnel: cloudflared tunnel run ${defaults.tunnelName}`\n : undefined,\n });\n } else {\n checks.push({\n name: 'Cloudflare Tunnel',\n status: 'warning',\n message: `Tunnel \"${defaults.tunnelName}\" not found`,\n fix: `Create tunnel: cloudflared tunnel create ${defaults.tunnelName}`,\n });\n }\n }\n } else {\n checks.push({\n name: 'cloudflared',\n status: 'warning',\n message: 'Not installed (optional, for Cloudflare Tunnel)',\n fix: 'Run `bindler setup` or visit https://pkg.cloudflare.com/index.html',\n });\n }\n\n // Check bindler config\n if (configExists()) {\n const config = readConfig();\n checks.push({\n name: 'Bindler config',\n status: 'ok',\n message: `${config.projects.length} project(s) registered`,\n });\n\n // macOS: Check for projects in protected folders\n const isMac = process.platform === 'darwin';\n if (isMac && config.projects.length > 0) {\n const homeDir = process.env.HOME || '';\n const protectedPaths = ['/Desktop/', '/Documents/', '/Downloads/'];\n const protectedProjects = config.projects.filter((p) =>\n protectedPaths.some((pp) => p.path.startsWith(homeDir + pp))\n );\n\n if (protectedProjects.length > 0) {\n const currentUser = process.env.USER || '';\n const psResult = execCommandSafe('ps aux | grep \"nginx: worker\" | grep -v grep | head -1');\n const nginxUser = psResult.success && psResult.output ? psResult.output.split(/\\s+/)[0] : '';\n\n if (nginxUser && nginxUser !== currentUser) {\n checks.push({\n name: 'Protected folders',\n status: 'warning',\n message: `${protectedProjects.length} project(s) in ~/Desktop, ~/Documents, or ~/Downloads`,\n fix: `nginx must run as \"${currentUser}\" to access these folders. Run: sudo chown -R ${currentUser}:staff /opt/homebrew/var/log/nginx /opt/homebrew/var/run && sudo killall nginx && brew services start nginx`,\n });\n }\n }\n }\n\n // Check nginx managed path\n const defaults = getDefaults();\n if (existsSync(defaults.nginxManagedPath)) {\n checks.push({\n name: 'Nginx config file',\n status: 'ok',\n message: `Exists at ${defaults.nginxManagedPath}`,\n });\n } else {\n checks.push({\n name: 'Nginx config file',\n status: 'warning',\n message: `Not found at ${defaults.nginxManagedPath}`,\n fix: 'Run: sudo bindler apply',\n });\n }\n\n // Check projects root\n if (existsSync(defaults.projectsRoot)) {\n checks.push({\n name: 'Projects root',\n status: 'ok',\n message: `Exists at ${defaults.projectsRoot}`,\n });\n } else {\n checks.push({\n name: 'Projects root',\n status: 'warning',\n message: `Not found at ${defaults.projectsRoot}`,\n fix: `Create directory: sudo mkdir -p ${defaults.projectsRoot}`,\n });\n }\n } else {\n checks.push({\n name: 'Bindler config',\n status: 'warning',\n message: 'Not initialized',\n fix: 'Run: bindler new (to create first project)',\n });\n }\n\n // Print results\n let hasErrors = false;\n let hasWarnings = false;\n\n for (const check of checks) {\n let icon: string;\n let color: (s: string) => string;\n\n switch (check.status) {\n case 'ok':\n icon = '✓';\n color = chalk.green;\n break;\n case 'warning':\n icon = '!';\n color = chalk.yellow;\n hasWarnings = true;\n break;\n case 'error':\n icon = '✗';\n color = chalk.red;\n hasErrors = true;\n break;\n }\n\n console.log(`${color(icon)} ${chalk.bold(check.name)}: ${check.message}`);\n if (check.fix) {\n console.log(chalk.dim(` Fix: ${check.fix}`));\n }\n }\n\n // Summary\n console.log('');\n if (hasErrors) {\n console.log(chalk.red('Some checks failed. Please fix the issues above.'));\n process.exit(1);\n } else if (hasWarnings) {\n console.log(chalk.yellow('Some warnings detected. Review the suggestions above.'));\n } else {\n console.log(chalk.green('All checks passed!'));\n }\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { getPortsTable } from '../lib/ports.js';\n\nexport async function portsCommand(): Promise<void> {\n const ports = getPortsTable();\n\n if (ports.length === 0) {\n console.log(chalk.yellow('No ports allocated.'));\n console.log(chalk.dim('npm projects will have ports allocated when created.'));\n return;\n }\n\n const table = new Table({\n head: [chalk.cyan('Port'), chalk.cyan('Project'), chalk.cyan('Hostname')],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const entry of ports) {\n table.push([String(entry.port), entry.project, entry.hostname]);\n }\n\n console.log(table.toString());\n console.log(chalk.dim(`\\n${ports.length} port(s) allocated`));\n}\n","import chalk from 'chalk';\nimport { configExists, readConfig, getConfigPath } from '../lib/config.js';\nimport { getPm2List } from '../lib/pm2.js';\n\ndeclare const __VERSION__: string;\n\nexport async function infoCommand(): Promise<void> {\n console.log(chalk.bold.cyan(String.raw`\n _ _ _ _\n | |_|_|___ _| | |___ ___\n | . | | | . | | -_| _|\n |___|_|_|_|___|_|___|_|\n `));\n\n console.log(chalk.white(' Manage multiple projects behind Cloudflare Tunnel'));\n console.log(chalk.white(' with Nginx and PM2\\n'));\n\n console.log(chalk.dim(' Version: ') + chalk.white(__VERSION__));\n console.log(chalk.dim(' Author: ') + chalk.white('alfaoz'));\n console.log(chalk.dim(' License: ') + chalk.white('MIT'));\n console.log(chalk.dim(' GitHub: ') + chalk.cyan('https://github.com/alfaoz/bindler'));\n console.log('');\n\n if (configExists()) {\n const config = readConfig();\n const pm2Processes = getPm2List().filter((p) => p.name.startsWith('bindler:'));\n const runningCount = pm2Processes.filter((p) => p.status === 'online').length;\n const npmProjects = config.projects.filter((p) => p.type === 'npm').length;\n const staticProjects = config.projects.filter((p) => p.type === 'static').length;\n\n console.log(chalk.dim(' Config: ') + chalk.white(getConfigPath()));\n console.log(chalk.dim(' Nginx: ') + chalk.white(config.defaults.nginxManagedPath));\n console.log(chalk.dim(' Tunnel: ') + chalk.white(config.defaults.tunnelName));\n console.log('');\n console.log(chalk.dim(' Projects: ') + chalk.white(`${config.projects.length} total (${staticProjects} static, ${npmProjects} npm)`));\n if (npmProjects > 0) {\n console.log(chalk.dim(' Running: ') + chalk.green(`${runningCount}/${npmProjects} npm apps online`));\n }\n } else {\n console.log(chalk.dim(' Config: ') + chalk.yellow('Not initialized'));\n console.log(chalk.dim(' ') + chalk.dim('Run `bindler new` to get started'));\n }\n\n console.log('');\n}\n","import chalk from 'chalk';\nimport { resolve4, resolve6, resolveCname } from 'node:dns/promises';\nimport { getProject, listProjects } from '../lib/config.js';\n\ninterface CheckOptions {\n verbose?: boolean;\n}\n\nasync function checkDns(hostname: string): Promise<{\n resolved: boolean;\n ipv4: string[];\n ipv6: string[];\n cname: string[];\n isCloudflare: boolean;\n}> {\n const result = {\n resolved: false,\n ipv4: [] as string[],\n ipv6: [] as string[],\n cname: [] as string[],\n isCloudflare: false,\n };\n\n try {\n result.ipv4 = await resolve4(hostname);\n result.resolved = true;\n } catch {\n // No A records\n }\n\n try {\n result.ipv6 = await resolve6(hostname);\n result.resolved = true;\n } catch {\n // No AAAA records\n }\n\n try {\n result.cname = await resolveCname(hostname);\n result.resolved = true;\n // Check if CNAME points to cloudflare tunnel\n result.isCloudflare = result.cname.some(\n (c) => c.includes('cfargotunnel.com') || c.includes('cloudflare')\n );\n } catch {\n // No CNAME records\n }\n\n return result;\n}\n\nasync function checkHttp(hostname: string, path = '/'): Promise<{\n reachable: boolean;\n statusCode?: number;\n redirectUrl?: string;\n responseTime?: number;\n error?: string;\n}> {\n const url = `https://${hostname}${path}`;\n const startTime = Date.now();\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 10000);\n\n const response = await fetch(url, {\n method: 'HEAD',\n redirect: 'manual',\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n const responseTime = Date.now() - startTime;\n\n return {\n reachable: true,\n statusCode: response.status,\n redirectUrl: response.headers.get('location') || undefined,\n responseTime,\n };\n } catch (error) {\n return {\n reachable: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function checkCommand(hostnameOrName: string, options: CheckOptions): Promise<void> {\n // Check if it's a project name\n const project = getProject(hostnameOrName);\n const hostname = project ? project.hostname : hostnameOrName;\n const basePath = project?.basePath || '/';\n const isLocal = project?.local || hostname.endsWith('.local') || hostname.endsWith('.localhost');\n\n console.log(chalk.blue(`\\nChecking ${hostname}...\\n`));\n\n // DNS Check\n console.log(chalk.bold('DNS Resolution:'));\n const dns = await checkDns(hostname);\n\n if (!dns.resolved) {\n console.log(chalk.red(' ✗ DNS not resolving'));\n if (isLocal) {\n console.log(chalk.dim(' Local hostname - add to /etc/hosts:'));\n console.log(chalk.cyan(` echo \"127.0.0.1 ${hostname}\" | sudo tee -a /etc/hosts`));\n } else {\n console.log(chalk.dim(' No DNS records found for this hostname.'));\n console.log(chalk.dim(' If using Cloudflare Tunnel, run: bindler apply'));\n console.log(chalk.dim(' If using direct mode, add an A record pointing to your server IP.'));\n }\n console.log('');\n return;\n }\n\n if (dns.cname.length > 0) {\n console.log(chalk.green(' ✓ CNAME: ') + dns.cname.join(', '));\n if (dns.isCloudflare) {\n console.log(chalk.green(' ✓ Points to Cloudflare Tunnel'));\n }\n }\n\n if (dns.ipv4.length > 0) {\n console.log(chalk.green(' ✓ A (IPv4): ') + dns.ipv4.join(', '));\n }\n\n if (dns.ipv6.length > 0) {\n console.log(chalk.green(' ✓ AAAA (IPv6): ') + dns.ipv6.join(', '));\n }\n\n console.log('');\n\n // HTTP Check\n console.log(chalk.bold('HTTP Check:'));\n const http = await checkHttp(hostname, basePath);\n\n if (!http.reachable) {\n console.log(chalk.red(' ✗ Not reachable'));\n\n // Provide specific error guidance\n const err = http.error || '';\n if (err.includes('ECONNREFUSED')) {\n console.log(chalk.dim(' Connection refused - server not accepting connections'));\n console.log(chalk.yellow('\\n Check:'));\n console.log(chalk.dim(' - Is nginx running? Run: bindler doctor'));\n if (project?.type === 'npm') {\n console.log(chalk.dim(` - Is the app running? Run: bindler start ${project.name}`));\n }\n } else if (err.includes('ENOTFOUND')) {\n console.log(chalk.dim(' Hostname not found'));\n console.log(chalk.yellow('\\n Check:'));\n console.log(chalk.dim(' - DNS may not be propagated yet (wait a few minutes)'));\n console.log(chalk.dim(' - Verify DNS records are correct'));\n } else if (err.includes('ETIMEDOUT') || err.includes('timeout')) {\n console.log(chalk.dim(' Connection timed out'));\n console.log(chalk.yellow('\\n Check:'));\n if (isLocal) {\n console.log(chalk.dim(' - Is nginx running on port 8080?'));\n } else {\n console.log(chalk.dim(' - Is your server/tunnel reachable from the internet?'));\n console.log(chalk.dim(' - Check firewall rules'));\n }\n } else if (err.includes('CERT') || err.includes('SSL') || err.includes('certificate')) {\n console.log(chalk.dim(' SSL/TLS certificate error'));\n console.log(chalk.yellow('\\n Check:'));\n console.log(chalk.dim(' - Run: sudo bindler apply (to refresh SSL certs)'));\n console.log(chalk.dim(' - Or check certbot: sudo certbot certificates'));\n } else {\n console.log(chalk.dim(` Error: ${err}`));\n console.log(chalk.yellow('\\n Possible issues:'));\n if (!isLocal) {\n console.log(chalk.dim(' - Cloudflare tunnel not running'));\n }\n console.log(chalk.dim(' - Nginx not running or misconfigured'));\n if (project?.type === 'npm') {\n console.log(chalk.dim(' - Project not started'));\n }\n }\n console.log('');\n return;\n }\n\n const statusColor = http.statusCode! < 400 ? chalk.green : chalk.red;\n console.log(statusColor(` ✓ Status: ${http.statusCode}`));\n console.log(chalk.dim(` Response time: ${http.responseTime}ms`));\n\n if (http.redirectUrl) {\n console.log(chalk.dim(` Redirects to: ${http.redirectUrl}`));\n }\n\n console.log('');\n\n // Summary\n if (dns.resolved && http.reachable && http.statusCode! < 400) {\n console.log(chalk.green('✓ All checks passed! Site is accessible.'));\n } else if (dns.resolved && http.reachable) {\n console.log(chalk.yellow('! Site is reachable but returned an error status.'));\n } else {\n console.log(chalk.red('✗ Some checks failed. See details above.'));\n }\n\n if (project) {\n console.log(chalk.dim(`\\nProject: ${project.name} (${project.type})`));\n if (project.type === 'npm') {\n console.log(chalk.dim(`Port: ${project.port}`));\n }\n }\n\n console.log('');\n}\n","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { isNginxInstalled } from '../lib/nginx.js';\nimport { isPm2Installed } from '../lib/pm2.js';\nimport { isCloudflaredInstalled } from '../lib/cloudflare.js';\nimport { execCommandSafe } from '../lib/utils.js';\nimport { readConfig, writeConfig, configExists, initConfig } from '../lib/config.js';\n\ninterface SetupOptions {\n direct?: boolean;\n}\n\ninterface OsInfo {\n platform: 'linux' | 'darwin' | 'win32' | 'unknown';\n distro?: string;\n version?: string;\n codename?: string;\n packageManager?: 'apt' | 'yum' | 'dnf' | 'brew' | 'winget';\n}\n\nfunction detectOs(): OsInfo {\n const platform = process.platform;\n\n if (platform === 'darwin') {\n return { platform: 'darwin', distro: 'macOS', packageManager: 'brew' };\n }\n\n if (platform === 'win32') {\n return { platform: 'win32', distro: 'Windows', packageManager: 'winget' };\n }\n\n if (platform === 'linux') {\n // Try to detect Linux distribution\n try {\n if (existsSync('/etc/os-release')) {\n const osRelease = readFileSync('/etc/os-release', 'utf-8');\n const lines = osRelease.split('\\n');\n const info: Record<string, string> = {};\n\n for (const line of lines) {\n const [key, ...valueParts] = line.split('=');\n if (key && valueParts.length > 0) {\n info[key] = valueParts.join('=').replace(/\"/g, '');\n }\n }\n\n const distro = info['ID'] || 'linux';\n const version = info['VERSION_ID'];\n const codename = info['VERSION_CODENAME'];\n\n // Determine package manager\n let packageManager: 'apt' | 'yum' | 'dnf' | undefined;\n if (['ubuntu', 'debian', 'pop', 'mint', 'elementary'].includes(distro)) {\n packageManager = 'apt';\n } else if (['fedora', 'rhel', 'centos', 'rocky', 'alma'].includes(distro)) {\n packageManager = existsSync('/usr/bin/dnf') ? 'dnf' : 'yum';\n } else if (['amzn'].includes(distro)) {\n packageManager = 'yum';\n }\n\n return { platform: 'linux', distro, version, codename, packageManager };\n }\n } catch {\n // Ignore errors\n }\n\n return { platform: 'linux', distro: 'unknown' };\n }\n\n return { platform: 'unknown' };\n}\n\nfunction runCommand(command: string, description: string): boolean {\n console.log(chalk.dim(` → ${description}...`));\n try {\n execSync(command, { stdio: 'inherit' });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function installNginx(os: OsInfo): Promise<boolean> {\n console.log(chalk.blue('\\nInstalling nginx...\\n'));\n\n if (os.platform === 'darwin') {\n return runCommand('brew install nginx', 'Installing via Homebrew');\n }\n\n if (os.platform === 'linux' && os.packageManager === 'apt') {\n runCommand('sudo apt-get update', 'Updating package list');\n return runCommand('sudo apt-get install -y nginx', 'Installing nginx');\n }\n\n if (os.platform === 'linux' && (os.packageManager === 'yum' || os.packageManager === 'dnf')) {\n return runCommand(`sudo ${os.packageManager} install -y nginx`, 'Installing nginx');\n }\n\n console.log(chalk.yellow(' Automatic installation not supported for your OS.'));\n console.log(chalk.dim(' Please install nginx manually.'));\n return false;\n}\n\nasync function installPm2(): Promise<boolean> {\n console.log(chalk.blue('\\nInstalling PM2...\\n'));\n return runCommand('npm install -g pm2', 'Installing via npm');\n}\n\nasync function installCertbot(os: OsInfo): Promise<boolean> {\n console.log(chalk.blue('\\nInstalling certbot (Let\\'s Encrypt)...\\n'));\n\n if (os.platform === 'darwin') {\n return runCommand('brew install certbot', 'Installing via Homebrew');\n }\n\n if (os.platform === 'linux' && os.packageManager === 'apt') {\n runCommand('sudo apt-get update', 'Updating package list');\n return runCommand('sudo apt-get install -y certbot python3-certbot-nginx', 'Installing certbot');\n }\n\n if (os.platform === 'linux' && (os.packageManager === 'yum' || os.packageManager === 'dnf')) {\n return runCommand(`sudo ${os.packageManager} install -y certbot python3-certbot-nginx`, 'Installing certbot');\n }\n\n console.log(chalk.yellow(' Automatic installation not supported for your OS.'));\n console.log(chalk.dim(' Please install certbot manually.'));\n return false;\n}\n\nfunction isCertbotInstalled(): boolean {\n const result = execCommandSafe('which certbot');\n return result.success;\n}\n\nasync function installCloudflared(os: OsInfo): Promise<boolean> {\n console.log(chalk.blue('\\nInstalling cloudflared...\\n'));\n\n if (os.platform === 'darwin') {\n return runCommand('brew install cloudflared', 'Installing via Homebrew');\n }\n\n if (os.platform === 'win32') {\n return runCommand('winget install --id Cloudflare.cloudflared', 'Installing via winget');\n }\n\n if (os.platform === 'linux' && os.packageManager === 'apt') {\n // Add Cloudflare GPG key and repo\n runCommand(\n 'sudo mkdir -p --mode=0755 /usr/share/keyrings',\n 'Creating keyrings directory'\n );\n\n runCommand(\n 'curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null',\n 'Adding Cloudflare GPG key'\n );\n\n // Determine the right repo based on distro\n let repoLine = 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main';\n\n if (os.codename) {\n // Use specific codename if available (focal, jammy, noble, bookworm, etc.)\n repoLine = `deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared ${os.codename} main`;\n }\n\n runCommand(\n `echo '${repoLine}' | sudo tee /etc/apt/sources.list.d/cloudflared.list`,\n 'Adding Cloudflare repository'\n );\n\n runCommand('sudo apt-get update', 'Updating package list');\n return runCommand('sudo apt-get install -y cloudflared', 'Installing cloudflared');\n }\n\n if (os.platform === 'linux' && (os.packageManager === 'yum' || os.packageManager === 'dnf')) {\n runCommand(\n 'curl -fsSl https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo',\n 'Adding Cloudflare repository'\n );\n\n return runCommand(`sudo ${os.packageManager} install -y cloudflared`, 'Installing cloudflared');\n }\n\n console.log(chalk.yellow(' Automatic installation not supported for your OS.'));\n console.log(chalk.dim(' Visit: https://pkg.cloudflare.com/index.html'));\n return false;\n}\n\nexport async function setupCommand(options: SetupOptions = {}): Promise<void> {\n console.log(chalk.bold.cyan('\\nBindler Setup\\n'));\n\n // Detect OS\n const os = detectOs();\n console.log(chalk.dim(`Detected: ${os.distro || os.platform}${os.version ? ` ${os.version}` : ''}${os.codename ? ` (${os.codename})` : ''}`));\n\n // Handle --direct mode\n const isDirect = options.direct;\n if (isDirect) {\n console.log(chalk.cyan('\\nDirect mode (VPS without Cloudflare Tunnel)'));\n console.log(chalk.dim('nginx will listen on port 80/443 directly\\n'));\n } else {\n console.log(chalk.cyan('\\nTunnel mode (via Cloudflare Tunnel)'));\n console.log(chalk.dim('nginx will listen on 127.0.0.1:8080\\n'));\n }\n\n // Check what's missing\n const missing: Array<{ name: string; install: () => Promise<boolean> }> = [];\n\n if (!isNginxInstalled()) {\n missing.push({ name: 'nginx', install: () => installNginx(os) });\n }\n\n if (!isPm2Installed()) {\n missing.push({ name: 'PM2', install: () => installPm2() });\n }\n\n // In direct mode, we need certbot instead of cloudflared\n if (isDirect) {\n if (!isCertbotInstalled()) {\n missing.push({ name: 'certbot', install: () => installCertbot(os) });\n }\n } else {\n if (!isCloudflaredInstalled()) {\n missing.push({ name: 'cloudflared', install: () => installCloudflared(os) });\n }\n }\n\n if (missing.length === 0) {\n console.log(chalk.green('✓ All dependencies are already installed!\\n'));\n } else {\n // Show what's missing\n console.log(chalk.yellow('Missing dependencies:\\n'));\n for (const dep of missing) {\n console.log(chalk.red(` ✗ ${dep.name}`));\n }\n console.log('');\n\n // Ask what to install\n const { toInstall } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'toInstall',\n message: 'Select dependencies to install:',\n choices: missing.map((dep) => ({\n name: dep.name,\n value: dep.name,\n checked: true,\n })),\n },\n ]);\n\n if (toInstall.length > 0) {\n // Install selected dependencies\n const results: Array<{ name: string; success: boolean }> = [];\n\n for (const depName of toInstall) {\n const dep = missing.find((m) => m.name === depName);\n if (dep) {\n const success = await dep.install();\n results.push({ name: depName, success });\n }\n }\n\n // Summary\n console.log(chalk.bold('\\n\\nInstallation Summary:\\n'));\n for (const result of results) {\n if (result.success) {\n console.log(chalk.green(` ✓ ${result.name} installed`));\n } else {\n console.log(chalk.red(` ✗ ${result.name} failed`));\n }\n }\n console.log('');\n }\n }\n\n // Configure bindler mode\n const config = configExists() ? readConfig() : initConfig();\n\n if (isDirect) {\n config.defaults.mode = 'direct';\n config.defaults.nginxListen = '80';\n config.defaults.applyCloudflareDnsRoutes = false;\n\n // Ask for SSL email\n const { enableSsl } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'enableSsl',\n message: 'Enable SSL with Let\\'s Encrypt?',\n default: true,\n },\n ]);\n\n if (enableSsl) {\n const { email } = await inquirer.prompt([\n {\n type: 'input',\n name: 'email',\n message: 'Email for Let\\'s Encrypt notifications:',\n validate: (input: string) => {\n if (!input || !input.includes('@')) {\n return 'Please enter a valid email address';\n }\n return true;\n },\n },\n ]);\n\n config.defaults.sslEnabled = true;\n config.defaults.sslEmail = email;\n }\n } else {\n config.defaults.mode = 'tunnel';\n config.defaults.nginxListen = '127.0.0.1:8080';\n config.defaults.applyCloudflareDnsRoutes = true;\n }\n\n writeConfig(config);\n\n console.log(chalk.green('\\n✓ Setup complete!\\n'));\n console.log(chalk.dim(`Mode: ${config.defaults.mode}`));\n console.log(chalk.dim(`nginx listen: ${config.defaults.nginxListen}`));\n if (config.defaults.sslEnabled) {\n console.log(chalk.dim(`SSL: enabled (${config.defaults.sslEmail})`));\n }\n console.log(chalk.dim('\\nRun `bindler new` to create your first project.'));\n}\n"],"mappings":"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","names":["chalk","existsSync","mkdirSync","existsSync","readFileSync","join","join","existsSync","readFileSync","existsSync","writeFileSync","copyFileSync","mkdirSync","dirname","join","dirname","existsSync","mkdirSync","join","copyFileSync","writeFileSync","result","answers","existsSync","mkdirSync","chalk","chalk","process","chalk","Table","chalk","process","Table","chalk","chalk","result","chalk","chalk","result","chalk","chalk","result","process","chalk","chalk","process","chalk","chalk","writeFileSync","readFileSync","join","chalk","chalk","join","writeFileSync","readFileSync","inquirer","chalk","chalk","inquirer","process","chalk","chalk","chalk","existsSync","chalk","existsSync","chalk","Table","chalk","Table","chalk","chalk","chalk","chalk","chalk","inquirer","execSync","existsSync","readFileSync","existsSync","readFileSync","chalk","execSync","inquirer","chalk"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bindler",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "CLI for managing multiple projects behind Cloudflare Tunnel with Nginx and PM2",
5
5
  "keywords": [
6
6
  "cloudflare",