/ src / cli / exit.ts
exit.ts
 1  /**
 2   * CLI exit helpers for subcommand handlers.
 3   *
 4   * Consolidates the 4-5 line "print + lint-suppress + exit" block that was
 5   * copy-pasted ~60 times across `claude mcp *` / `claude plugin *` handlers.
 6   * The `: never` return type lets TypeScript narrow control flow at call sites
 7   * without a trailing `return`.
 8   */
 9  /* eslint-disable custom-rules/no-process-exit -- centralized CLI exit point */
10  
11  // `return undefined as never` (not a post-exit throw) — tests spy on
12  // process.exit and let it return. Call sites write `return cliError(...)`
13  // where subsequent code would dereference narrowed-away values under mock.
14  // cliError uses console.error (tests spy on console.error); cliOk uses
15  // process.stdout.write (tests spy on process.stdout.write — Bun's console.log
16  // doesn't route through a spied process.stdout.write).
17  
18  /** Write an error message to stderr (if given) and exit with code 1. */
19  export function cliError(msg?: string): never {
20    // biome-ignore lint/suspicious/noConsole: centralized CLI error output
21    if (msg) console.error(msg)
22    process.exit(1)
23    return undefined as never
24  }
25  
26  /** Write a message to stdout (if given) and exit with code 0. */
27  export function cliOk(msg?: string): never {
28    if (msg) process.stdout.write(msg + '\n')
29    process.exit(0)
30    return undefined as never
31  }