import { program } from 'commander' import color from 'kleur' import { cleanApp, configShow, diffApp, getApp, infoApp, listApps, logApp, newApp, openApp, pullApp, pushApp, renameApp, restartApp, rmApp, rollbackApp, stashApp, stashListApp, stashPopApp, startApp, statusApp, stopApp, syncApp, versionsApp, } from './commands' program .name('toes') .version('v0.0.4', '-v, --version') .addHelpText('beforeAll', (ctx) => { if (ctx.command === program) { return color.bold().cyan('\n🐾 Toes') + color.gray(' - personal web appliance\n') } return '' }) .configureOutput({ writeOut: (str) => { const colored = str .replace(/^(Usage:)/gm, color.yellow('$1')) .replace(/^(Commands:)/gm, color.yellow('$1')) .replace(/^(Options:)/gm, color.yellow('$1')) .replace(/^(Arguments:)/gm, color.yellow('$1')) process.stdout.write(colored) }, }) program .command('version', { hidden: true }) .action(() => console.log(program.version())) program .command('config') .description('Show current host configuration') .action(configShow) program .command('info') .description('Show info for an app') .argument('[name]', 'app name (uses current directory if omitted)') .action(infoApp) program .command('list') .description('List all apps') .option('-t, --tools', 'show only tools') .option('-a, --all', 'show all apps including tools') .action(listApps) program .command('start') .description('Start an app') .argument('[name]', 'app name (uses current directory if omitted)') .action(startApp) program .command('stop') .description('Stop an app') .argument('[name]', 'app name (uses current directory if omitted)') .action(stopApp) program .command('restart') .description('Restart an app') .argument('[name]', 'app name (uses current directory if omitted)') .action(restartApp) program .command('logs') .description('Show logs for an app') .argument('[name]', 'app name (uses current directory if omitted)') .option('-f, --follow', 'follow log output') .action(logApp) program .command('log', { hidden: true }) .argument('[name]', 'app name (uses current directory if omitted)') .option('-f, --follow', 'follow log output') .action(logApp) program .command('open') .description('Open an app in browser') .argument('[name]', 'app name (uses current directory if omitted)') .action(openApp) program .command('get') .description('Download an app from server') .argument('', 'app name') .action(getApp) program .command('new') .description('Create a new toes app') .argument('[name]', 'app name (uses current directory if omitted)') .option('--ssr', 'SSR template with pages directory (default)') .option('--bare', 'minimal template with no pages') .option('--spa', 'single-page app with client-side rendering') .action(newApp) program .command('push') .description('Push local changes to server') .action(pushApp) program .command('pull') .description('Pull changes from server') .option('-f, --force', 'overwrite local changes') .action(pullApp) program .command('status') .description('Show what would be pushed/pulled') .action(statusApp) program .command('diff') .description('Show diff of changed files') .action(diffApp) program .command('sync') .description('Watch and sync changes bidirectionally') .action(syncApp) program .command('clean') .description('Remove local files not on server') .option('-f, --force', 'skip confirmation') .option('-n, --dry-run', 'show what would be removed') .action(cleanApp) const stash = program .command('stash') .description('Stash local changes') .action(stashApp) stash .command('pop') .description('Restore stashed changes') .action(stashPopApp) stash .command('list') .description('List all stashes') .action(stashListApp) program .command('versions') .description('List deployed versions') .argument('[name]', 'app name (uses current directory if omitted)') .action(versionsApp) program .command('rollback') .description('Rollback to a previous version') .argument('[name]', 'app name (uses current directory if omitted)') .option('-v, --version ', 'version to rollback to (prompts if omitted)') .action((name, options) => rollbackApp(name, options.version)) program .command('rm') .description('Remove an app from the server') .argument('[name]', 'app name (uses current directory if omitted)') .action(rmApp) program .command('rename') .description('Rename an app') .argument('[name]', 'app name (uses current directory if omitted)') .argument('', 'new app name') .action(renameApp) export { program }