UNPKG

@xec-sh/cli

Version:

Xec: The Universal Shell for TypeScript

224 lines 7.24 kB
import chalk from 'chalk'; import { $ } from '@xec-sh/core'; import * as clack from '@clack/prompts'; import { parseTimeout } from './time.js'; import { ConfigurationManager } from '../config/configuration-manager.js'; export async function executeDirectCommand(args, options = {}) { const command = args.join(' '); if (!command.trim()) { throw new Error('No command specified'); } const firstArg = args[0]; if (!firstArg) { await executeLocally(command, options); return; } const target = await detectTarget(firstArg); if (target) { await executeOnTarget(target, args.slice(1).join(' '), options); } else { await executeLocally(command, options); } } async function detectTarget(arg) { const configManager = new ConfigurationManager(); const config = await configManager.load(); const targets = config.targets || {}; const hosts = targets.hosts || {}; if (hosts[arg]) { return { type: 'ssh', name: arg, config: { ...hosts[arg], type: 'ssh' }, }; } const containers = targets.containers || {}; if (containers[arg]) { return { type: 'docker', name: arg, config: { ...containers[arg], type: 'docker' }, }; } const pods = targets.pods || {}; if (pods[arg]) { return { type: 'kubernetes', name: arg, config: { ...pods[arg], type: 'k8s' }, }; } try { const dockerResult = await $.local() `docker ps --format "{{.Names}}" | grep -E "^${arg}$"`.quiet().nothrow(); if (dockerResult.ok && dockerResult.stdout.trim()) { return { type: 'docker', name: arg }; } } catch { } try { const k8sResult = await $.local() `kubectl get pod ${arg} -o name`.quiet().nothrow(); if (k8sResult.ok && k8sResult.stdout.trim()) { return { type: 'kubernetes', name: arg }; } } catch { } return null; } async function executeOnTarget(target, command, options) { if (!command.trim()) { throw new Error('No command specified for target'); } const targetDisplay = chalk.cyan(target.name); if (!options.quiet) { clack.log.info(`Executing on ${targetDisplay} (${target.type})...`); } let engine; switch (target.type) { case 'ssh': { const sshConfig = target.config || { host: target.name }; engine = $.ssh({ host: sshConfig.host || target.name, username: sshConfig.username || sshConfig.user || process.env['USER'] || 'root', port: sshConfig.port || 22, privateKey: sshConfig.privateKey || sshConfig.key || sshConfig.identityFile, password: sshConfig.password, passphrase: sshConfig.passphrase, }); break; } case 'docker': { const containerName = target.config?.name || target.name; engine = $.docker({ container: containerName }); break; } case 'kubernetes': { const podConfig = target.config || {}; engine = $.k8s({ pod: podConfig.name || target.name, namespace: podConfig.namespace || 'default', container: podConfig.container, }); break; } } if (options.cwd) { engine = engine.cd(options.cwd); } if (options.env) { engine = engine.env(options.env); } if (options.timeout) { const timeoutMs = parseTimeout(options.timeout); engine = engine.timeout(timeoutMs); } const result = await engine.raw `${command}`; if (result.stdout && !options.quiet) { console.log(result.stdout.trim()); } if (result.stderr && options.verbose) { console.error(chalk.yellow(result.stderr.trim())); } } async function executeLocally(command, options) { let engine = $.local(); if (options.cwd) { engine = engine.cd(options.cwd); } if (options.env) { engine = engine.env(options.env); } if (options.timeout) { const timeoutMs = parseTimeout(options.timeout); engine = engine.timeout(timeoutMs); } const result = await engine.raw `${command}`; if (result.stdout && !options.quiet) { console.log(result.stdout.trim()); } if (result.stderr && options.verbose) { console.error(chalk.yellow(result.stderr.trim())); } } export function isDirectCommand(args, commandRegistry, taskNames) { if (args.length === 0) { return false; } const firstArg = args[0]; if (!firstArg) { return false; } if (firstArg.startsWith('-')) { return false; } if (taskNames && taskNames.includes(firstArg)) { return false; } if (commandRegistry) { if (commandRegistry.includes(firstArg)) { return false; } } else { const knownSubcommands = [ 'exec', 'ssh', 'docker', 'k8s', 'run', 'init', 'config', 'env', 'copy', 'list', 'new', 'version', 'watch', 'on', 'in', 'help', 'cache', 'forward', 'interactive', 'logs', 'release', 'r', 'i', 'v', 'tasks', 'explain' ]; if (knownSubcommands.includes(firstArg)) { return false; } } if (firstArg && (firstArg.includes(' ') || (firstArg.startsWith('"') && firstArg.endsWith('"')))) { return true; } return true; } export async function createTargetEngine(target, options = {}) { const config = target.config; switch (target.type) { case 'local': return $; case 'ssh': return $.ssh({ host: config.host, username: config.user || config.username, port: config.port, privateKey: config.privateKey, password: config.password, passphrase: config.passphrase, keepAlive: config.keepAlive, keepAliveInterval: config.keepAliveInterval, ...options }); case 'docker': return $.docker({ container: config.container || target.name, image: config.image || 'alpine:latest', user: config.user, workingDir: config.workdir, tty: config.tty, ...options }); case 'k8s': case 'kubernetes': return $.k8s({ pod: config.pod || target.name, namespace: config.namespace || 'default', container: config.container, context: config.context, kubeconfig: config.kubeconfig, ...options }); default: throw new Error(`Unsupported target type: ${target.type}`); } } //# sourceMappingURL=direct-execution.js.map