From d8b8e5859c53d5094eefa8a9bb7de47ee55e68bd Mon Sep 17 00:00:00 2001 From: liruifengv Date: Thu, 28 May 2026 19:52:35 +0800 Subject: [PATCH] feat(cli): add clickable changelog link to update prompt Render a clickable OSC 8 hyperlink pointing to the release notes page in the update available prompt, so users can easily review changes before deciding to install. --- .../add-changelog-link-to-update-prompt.md | 5 +++ apps/kimi-code/src/cli/update/prompt.ts | 4 ++ apps/kimi-code/test/cli/update/prompt.test.ts | 42 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 .changeset/add-changelog-link-to-update-prompt.md diff --git a/.changeset/add-changelog-link-to-update-prompt.md b/.changeset/add-changelog-link-to-update-prompt.md new file mode 100644 index 0000000000..3b3257e590 --- /dev/null +++ b/.changeset/add-changelog-link-to-update-prompt.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Add a clickable changelog link to the update prompt. diff --git a/apps/kimi-code/src/cli/update/prompt.ts b/apps/kimi-code/src/cli/update/prompt.ts index 4bcd0e3e97..bd3fd93385 100644 --- a/apps/kimi-code/src/cli/update/prompt.ts +++ b/apps/kimi-code/src/cli/update/prompt.ts @@ -14,6 +14,8 @@ import { import { type InstallSource, type UpdateTarget } from './types'; +const CHANGELOG_URL = 'https://moonshotai.github.io/kimi-code/en/release-notes/changelog.html'; + export type InstallPromptChoiceValue = 'install' | 'skip'; export interface InstallPromptChoice { @@ -66,9 +68,11 @@ function renderInstallPrompt( const targetVersion = chalk.hex(UPDATE_PROMPT_SUCCESS).bold(options.target.version); const sourceLabel = chalk.hex(UPDATE_PROMPT_PRIMARY).bold(options.installSource); const command = chalk.hex(UPDATE_PROMPT_PRIMARY)(options.installCommand); + const changelogText = chalk.hex(UPDATE_PROMPT_PRIMARY).underline(`View changelog: ${CHANGELOG_URL}`); const lines = [ chalk.hex(UPDATE_PROMPT_PRIMARY).bold('Kimi Code Update Available'), chalk.hex(UPDATE_PROMPT_MUTED)(`${PRODUCT_NAME} has a newer release ready.`), + `]8;;${CHANGELOG_URL}\\${changelogText}]8;;\\`, '', `${label('Current')} ${currentVersion}`, `${label('Target ')} ${targetVersion}`, diff --git a/apps/kimi-code/test/cli/update/prompt.test.ts b/apps/kimi-code/test/cli/update/prompt.test.ts index b898ab6549..864492689c 100644 --- a/apps/kimi-code/test/cli/update/prompt.test.ts +++ b/apps/kimi-code/test/cli/update/prompt.test.ts @@ -1,9 +1,12 @@ +import { EventEmitter } from 'node:events'; + import { describe, expect, it } from 'vitest'; import { createInstallPromptChoices, getDefaultInstallPromptSelection, moveInstallPromptSelection, + promptForInstallConfirmation, } from '#/cli/update/prompt'; describe('install prompt helpers', () => { @@ -28,3 +31,42 @@ describe('install prompt helpers', () => { expect(moveInstallPromptSelection(1, 'down', 2)).toBe(1); }); }); + +describe('promptForInstallConfirmation', () => { + it('renders changelog hyperlink in the prompt output', async () => { + const CHANGELOG_URL = 'https://moonshotai.github.io/kimi-code/en/release-notes/changelog.html'; + + const input = Object.assign(new EventEmitter(), { + isRaw: false, + setRawMode: () => {}, + resume: () => {}, + off: () => {}, + }) as unknown as NodeJS.ReadStream; + + const outputChunks: string[] = []; + const output = { + write: (chunk: string) => { + outputChunks.push(chunk); + return true; + }, + } as NodeJS.WriteStream; + + const promptPromise = promptForInstallConfirmation({ + currentVersion: '0.4.0', + target: { version: '0.5.0' }, + installCommand: 'npm install -g @moonshot-ai/kimi-code@0.5.0', + installSource: 'npm-global', + input, + output, + }); + + // Emit keypress to trigger initial render then exit + input.emit('keypress', '', { name: 'escape' }); + + await promptPromise; + + const rendered = outputChunks.join(''); + expect(rendered).toContain(CHANGELOG_URL); + expect(rendered).toContain('View changelog'); + }); +});