(
opts: CLIOptions,
version: string,
io: PromptRunIO = {},
)
| 93 | const PROMPT_BLOCK_INDENT = ' '; |
| 94 | |
| 95 | export async function runPrompt( |
| 96 | opts: CLIOptions, |
| 97 | version: string, |
| 98 | io: PromptRunIO = {}, |
| 99 | ): Promise<void> { |
| 100 | const startedAt = Date.now(); |
| 101 | const stdout = io.stdout ?? process.stdout; |
| 102 | const stderr = io.stderr ?? process.stderr; |
| 103 | const promptProcess = io.process ?? process; |
| 104 | const workDir = process.cwd(); |
| 105 | const telemetryBootstrap = createCliTelemetryBootstrap(); |
| 106 | const telemetryClient: TelemetryClient = { |
| 107 | track, |
| 108 | withContext: withTelemetryContext, |
| 109 | setContext: setTelemetryContext, |
| 110 | }; |
| 111 | const harness = createKimiHarness({ |
| 112 | homeDir: telemetryBootstrap.homeDir, |
| 113 | identity: createKimiCodeHostIdentity(version), |
| 114 | uiMode: PROMPT_UI_MODE, |
| 115 | skillDirs: opts.skillsDirs, |
| 116 | telemetry: telemetryClient, |
| 117 | onOAuthRefresh: (outcome) => { |
| 118 | if (outcome.success) { |
| 119 | track('oauth_refresh', { outcome: 'success' }); |
| 120 | return; |
| 121 | } |
| 122 | track('oauth_refresh', { outcome: 'error', reason: outcome.reason }); |
| 123 | }, |
| 124 | sessionStartedProperties: { yolo: false, plan: false, afk: true }, |
| 125 | }); |
| 126 | log.info('kimi-code starting', { |
| 127 | version, |
| 128 | uiMode: PROMPT_UI_MODE, |
| 129 | nodeVersion: process.version, |
| 130 | platform: `${process.platform}/${process.arch}`, |
| 131 | workDir, |
| 132 | }); |
| 133 | let restorePromptSessionPermission = async (): Promise<void> => {}; |
| 134 | let removeTerminationCleanup: (() => void) | undefined; |
| 135 | let cleanupPromise: Promise<void> | undefined; |
| 136 | const cleanupPromptRun = async (): Promise<void> => { |
| 137 | const pending = (cleanupPromise ??= (async () => { |
| 138 | removeTerminationCleanup?.(); |
| 139 | setCrashPhase('shutdown'); |
| 140 | try { |
| 141 | await restorePromptSessionPermission(); |
| 142 | } finally { |
| 143 | await shutdownTelemetry({ timeoutMs: CLI_SHUTDOWN_TIMEOUT_MS }); |
| 144 | await harness.close(); |
| 145 | } |
| 146 | })()); |
| 147 | // Bound cleanup so a wedged shutdown step (e.g. a SessionEnd hook, MCP |
| 148 | // shutdown, or a connection blackholed by a restrictive firewall) cannot |
| 149 | // keep a completed headless run alive forever. The cleanup keeps running in |
| 150 | // the background if it overruns; the caller (`kimi -p`) force-exits shortly |
| 151 | // after, so any straggling work is torn down with the process. |
| 152 | await raceWithTimeout(pending, PROMPT_CLEANUP_TIMEOUT_MS); |
no test coverage detected