(parent: Command, deps: LifecycleCommandDeps = DEFAULT_DEPS)
| 60 | |
| 61 | /** Mount install/uninstall/start/stop/restart/status under a parent command. */ |
| 62 | export function addLifecycleCommands(parent: Command, deps: LifecycleCommandDeps = DEFAULT_DEPS): void { |
| 63 | parent |
| 64 | .command('install') |
| 65 | .description('Install the Kimi server as an OS-managed service (launchd/systemd/schtasks).') |
| 66 | .option('--port <port>', `Bind port (default ${DEFAULT_SERVER_PORT})`, String(DEFAULT_SERVER_PORT)) |
| 67 | .option( |
| 68 | '--log-level <level>', |
| 69 | `Log level: ${VALID_LOG_LEVELS.join('|')} (default ${DEFAULT_LOG_LEVEL})`, |
| 70 | DEFAULT_LOG_LEVEL, |
| 71 | ) |
| 72 | .option('--force', 'Reinstall and overwrite if already installed', false) |
| 73 | .option('--no-open', 'Do not open the web UI after install.', true) |
| 74 | .option('--json', 'Output JSON', false) |
| 75 | .action(async (opts: InstallCliOptions) => { |
| 76 | await runLifecycle(deps, opts.json === true, async (mgr) => { |
| 77 | const args: InstallArgs = { |
| 78 | host: DEFAULT_SERVER_HOST, |
| 79 | port: parsePort(opts.port, '--port', DEFAULT_SERVER_PORT), |
| 80 | logLevel: parseLogLevel(opts.logLevel), |
| 81 | force: opts.force === true, |
| 82 | }; |
| 83 | const result = await mgr.install(args); |
| 84 | const status = await readStatus(mgr); |
| 85 | const enriched = withStatusDetails({ |
| 86 | ok: true, |
| 87 | action: 'install', |
| 88 | status: result.status, |
| 89 | plistPath: result.plistPath, |
| 90 | unitPath: result.unitPath, |
| 91 | taskName: result.taskName, |
| 92 | message: result.message, |
| 93 | }, status, args); |
| 94 | if (opts.json !== true && opts.open !== false && enriched.running === true && typeof enriched.url === 'string') { |
| 95 | deps.openUrl(enriched.url); |
| 96 | } |
| 97 | return enriched; |
| 98 | }); |
| 99 | }); |
| 100 | |
| 101 | parent |
| 102 | .command('uninstall') |
| 103 | .description('Uninstall the Kimi server service.') |
| 104 | .option('--json', 'Output JSON', false) |
| 105 | .action(async (opts: JsonCliOptions) => { |
| 106 | await runLifecycle(deps, opts.json === true, async (mgr) => { |
| 107 | const result = await mgr.uninstall(); |
| 108 | return { ok: result.ok, action: 'uninstall', message: result.message }; |
| 109 | }); |
| 110 | }); |
| 111 | |
| 112 | parent |
| 113 | .command('start') |
| 114 | .description('Start the Kimi server service.') |
| 115 | .option('--json', 'Output JSON', false) |
| 116 | .action(async (opts: JsonCliOptions) => { |
| 117 | await runLifecycle(deps, opts.json === true, async (mgr) => { |
| 118 | const result = await mgr.start(); |
| 119 | const status = await readStatus(mgr); |
no test coverage detected