chore(cli): rename test files from .mts to .ts
This commit is contained in:
@@ -1,53 +1,93 @@
|
||||
import { Command } from 'commander'
|
||||
import chalk from 'chalk'
|
||||
import type { Command } from 'commander'
|
||||
import { connectToDaemon, getDaemonHost } from '../../utils/client.js'
|
||||
import type { CommandOptions, SingleResult, OutputSchema, CommandError } from '../../output/index.js'
|
||||
|
||||
export function stopCommand(): Command {
|
||||
return new Command('stop')
|
||||
.description('Stop the daemon')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action(async (options: { host?: string }) => {
|
||||
await runStop(options)
|
||||
})
|
||||
/** Result of stop command */
|
||||
interface StopResult {
|
||||
action: 'stopped' | 'not_running'
|
||||
host: string
|
||||
message: string
|
||||
}
|
||||
|
||||
async function runStop(options: { host?: string }): Promise<void> {
|
||||
const host = getDaemonHost(options)
|
||||
/** Schema for stop result */
|
||||
const stopResultSchema: OutputSchema<StopResult> = {
|
||||
idField: 'action',
|
||||
columns: [
|
||||
{
|
||||
header: 'STATUS',
|
||||
field: 'action',
|
||||
color: (value) => (value === 'stopped' ? 'green' : 'yellow'),
|
||||
},
|
||||
{ header: 'HOST', field: 'host' },
|
||||
{ header: 'MESSAGE', field: 'message' },
|
||||
],
|
||||
}
|
||||
|
||||
export type StopCommandResult = SingleResult<StopResult>
|
||||
|
||||
export async function runStopCommand(
|
||||
options: CommandOptions,
|
||||
_command: Command
|
||||
): Promise<StopCommandResult> {
|
||||
const connectOptions = { host: options.host as string | undefined }
|
||||
const host = getDaemonHost(connectOptions)
|
||||
|
||||
let client
|
||||
try {
|
||||
client = await connectToDaemon(options)
|
||||
client = await connectToDaemon(connectOptions)
|
||||
} catch {
|
||||
console.log(chalk.yellow('Daemon is not running'))
|
||||
console.log(chalk.dim(`Tried to connect to ${host}`))
|
||||
process.exit(0)
|
||||
// Daemon not running - this is a valid outcome
|
||||
return {
|
||||
type: 'single',
|
||||
data: {
|
||||
action: 'not_running',
|
||||
host,
|
||||
message: 'Daemon was not running',
|
||||
},
|
||||
schema: stopResultSchema,
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(chalk.dim('Stopping daemon...'))
|
||||
|
||||
// Request server restart with "shutdown" reason
|
||||
// This signals the daemon to shut down gracefully
|
||||
await client.restartServer('cli_shutdown')
|
||||
|
||||
// Give the daemon a moment to acknowledge
|
||||
await new Promise(resolve => setTimeout(resolve, 500))
|
||||
|
||||
console.log(chalk.green('Daemon stop requested'))
|
||||
console.log(chalk.dim('The daemon will shut down gracefully'))
|
||||
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||
|
||||
await client.close()
|
||||
|
||||
return {
|
||||
type: 'single',
|
||||
data: {
|
||||
action: 'stopped',
|
||||
host,
|
||||
message: 'Daemon stop requested - shutting down gracefully',
|
||||
},
|
||||
schema: stopResultSchema,
|
||||
}
|
||||
} catch (err) {
|
||||
await client.close().catch(() => {})
|
||||
const message = err instanceof Error ? err.message : String(err)
|
||||
|
||||
// If connection was closed, the daemon is stopping
|
||||
if (message.includes('closed') || message.includes('disconnected')) {
|
||||
console.log(chalk.green('Daemon is stopping'))
|
||||
process.exit(0)
|
||||
return {
|
||||
type: 'single',
|
||||
data: {
|
||||
action: 'stopped',
|
||||
host,
|
||||
message: 'Daemon is stopping',
|
||||
},
|
||||
schema: stopResultSchema,
|
||||
}
|
||||
}
|
||||
|
||||
console.error(chalk.red(`Failed to stop daemon: ${message}`))
|
||||
process.exit(1)
|
||||
const error: CommandError = {
|
||||
code: 'STOP_FAILED',
|
||||
message: `Failed to stop daemon: ${message}`,
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user