(host: SlashCommandHost)
| 20 | * the consequences and only proceeds when the user presses Enter on Continue. |
| 21 | */ |
| 22 | export async function handleWebCommand(host: SlashCommandHost): Promise<void> { |
| 23 | const session = host.session; |
| 24 | if (session === undefined) { |
| 25 | host.showError(NO_ACTIVE_SESSION_MESSAGE); |
| 26 | return; |
| 27 | } |
| 28 | const sessionId = session.id; |
| 29 | |
| 30 | const confirmed = await new Promise<boolean>((resolve) => { |
| 31 | const picker = new ChoicePickerComponent({ |
| 32 | title: 'Open current session in the Web UI?', |
| 33 | hint: '↑↓ navigate · Enter select · Esc cancel', |
| 34 | options: [ |
| 35 | { |
| 36 | value: WEB_CONFIRM, |
| 37 | label: 'Continue', |
| 38 | description: |
| 39 | 'Start the Kimi server (background daemon if needed), open this session in your default browser, and exit the terminal UI.', |
| 40 | }, |
| 41 | { |
| 42 | value: WEB_CANCEL, |
| 43 | label: 'Cancel', |
| 44 | description: 'Stay in the terminal UI.', |
| 45 | }, |
| 46 | ], |
| 47 | onSelect: (value) => { |
| 48 | resolve(value === WEB_CONFIRM); |
| 49 | }, |
| 50 | onCancel: () => { |
| 51 | resolve(false); |
| 52 | }, |
| 53 | }); |
| 54 | host.mountEditorReplacement(picker); |
| 55 | }); |
| 56 | host.restoreEditor(); |
| 57 | if (!confirmed) return; |
| 58 | |
| 59 | host.showStatus('Starting Kimi server and opening web UI…'); |
| 60 | let origin: string; |
| 61 | try { |
| 62 | ({ origin } = await ensureDaemon({})); |
| 63 | } catch (error) { |
| 64 | host.showError(`Failed to start server: ${formatErrorMessage(error)}`); |
| 65 | return; |
| 66 | } |
| 67 | |
| 68 | // Resolve the persistent token so the opened browser auto-authenticates via |
| 69 | // the `#token=` fragment — matching the `kimi web` subcommand. Show the URL |
| 70 | // and token in green under the status line so they can be copied before the |
| 71 | // terminal exits. Best-effort: an older/never-started server has no token |
| 72 | // file, so we fall back to the plain URL and skip the token line. |
| 73 | const token = tryResolveServerToken(getDataDir()); |
| 74 | const url = webSessionUrl(origin, sessionId, token); |
| 75 | host.showStatus(`open ${url}`, 'success'); |
| 76 | if (token !== undefined) { |
| 77 | host.showStatus(`Token: ${token}`, 'success'); |
| 78 | } |
| 79 | openUrl(url); |
no test coverage detected