diff --git a/.changeset/tips-banner-toggle.md b/.changeset/tips-banner-toggle.md new file mode 100644 index 000000000..1171bd3a6 --- /dev/null +++ b/.changeset/tips-banner-toggle.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Add a TUI preference to disable the startup tips banner fetch. diff --git a/apps/kimi-code/src/tui/commands/config.ts b/apps/kimi-code/src/tui/commands/config.ts index 9b91d4ba0..d89b9e35a 100644 --- a/apps/kimi-code/src/tui/commands/config.ts +++ b/apps/kimi-code/src/tui/commands/config.ts @@ -274,6 +274,7 @@ async function applyEditorChoice(host: SlashCommandHost, value: string): Promise try { await saveTuiConfig({ theme: host.state.appState.theme, + showTipsBanner: host.state.appState.showTipsBanner, editorCommand, notifications: host.state.appState.notifications, upgrade: host.state.appState.upgrade, @@ -424,6 +425,7 @@ async function applyThemeChoice(host: SlashCommandHost, theme: ThemeName): Promi try { await saveTuiConfig({ theme, + showTipsBanner: host.state.appState.showTipsBanner, editorCommand: host.state.appState.editorCommand, notifications: host.state.appState.notifications, upgrade: host.state.appState.upgrade, @@ -546,7 +548,7 @@ type UpdatePreferenceHost = { readonly state: { readonly appState: Pick< SlashCommandHost['state']['appState'], - 'theme' | 'editorCommand' | 'notifications' | 'upgrade' + 'theme' | 'showTipsBanner' | 'editorCommand' | 'notifications' | 'upgrade' >; }; setAppState(patch: Pick): void; @@ -567,6 +569,7 @@ export async function applyUpdatePreferenceChoice( try { await saveTuiConfig({ theme: host.state.appState.theme, + showTipsBanner: host.state.appState.showTipsBanner, editorCommand: host.state.appState.editorCommand, notifications: host.state.appState.notifications, upgrade, diff --git a/apps/kimi-code/src/tui/commands/reload.ts b/apps/kimi-code/src/tui/commands/reload.ts index a8700d95e..4d5f52669 100644 --- a/apps/kimi-code/src/tui/commands/reload.ts +++ b/apps/kimi-code/src/tui/commands/reload.ts @@ -44,6 +44,7 @@ export async function applyReloadedTuiConfig( await host.applyTheme(config.theme, resolved); host.refreshTerminalThemeTracking(); host.setAppState({ + showTipsBanner: config.showTipsBanner, editorCommand: config.editorCommand, notifications: config.notifications, upgrade: config.upgrade, diff --git a/apps/kimi-code/src/tui/config.ts b/apps/kimi-code/src/tui/config.ts index fdcd8714e..dbb380cba 100644 --- a/apps/kimi-code/src/tui/config.ts +++ b/apps/kimi-code/src/tui/config.ts @@ -32,6 +32,7 @@ export const UpgradePreferencesSchema = z.object({ export const TuiConfigFileSchema = z.object({ theme: TuiThemeSchema.optional(), + show_tips_banner: z.boolean().optional(), editor: z .object({ command: z.string().optional(), @@ -52,6 +53,7 @@ export const TuiConfigFileSchema = z.object({ export const TuiConfigSchema = z.object({ theme: TuiThemeSchema, + showTipsBanner: z.boolean(), editorCommand: z.string().nullable(), notifications: NotificationsConfigSchema, upgrade: UpgradePreferencesSchema, @@ -73,6 +75,7 @@ export const DEFAULT_UPGRADE_PREFERENCES: UpgradePreferences = { export const DEFAULT_TUI_CONFIG: TuiConfig = TuiConfigSchema.parse({ theme: 'auto', + showTipsBanner: true, editorCommand: null, notifications: DEFAULT_NOTIFICATIONS_CONFIG, upgrade: DEFAULT_UPGRADE_PREFERENCES, @@ -132,6 +135,7 @@ export function normalizeTuiConfig(config: TuiConfigFileShape): TuiConfig { const command = config.editor?.command?.trim(); return TuiConfigSchema.parse({ theme: config.theme ?? DEFAULT_TUI_CONFIG.theme, + showTipsBanner: config.show_tips_banner ?? DEFAULT_TUI_CONFIG.showTipsBanner, editorCommand: command === undefined || command.length === 0 ? null : command, notifications: { enabled: config.notifications?.enabled ?? DEFAULT_NOTIFICATIONS_CONFIG.enabled, @@ -150,6 +154,7 @@ export function renderTuiConfig(config: TuiConfig): string { # Agent/runtime settings stay in ~/.kimi-code/config.toml. theme = "${escapeTomlBasicString(config.theme)}" # "auto" | "dark" | "light" | custom theme name +show_tips_banner = ${String(config.showTipsBanner)} # true | false [editor] command = "${escapeTomlBasicString(config.editorCommand ?? '')}" # Empty uses $VISUAL / $EDITOR diff --git a/apps/kimi-code/src/tui/kimi-tui.ts b/apps/kimi-code/src/tui/kimi-tui.ts index b0a2094de..7b2992d98 100644 --- a/apps/kimi-code/src/tui/kimi-tui.ts +++ b/apps/kimi-code/src/tui/kimi-tui.ts @@ -179,6 +179,7 @@ function createInitialAppState(input: KimiTUIStartupInput): AppState { streamingPhase: 'idle', streamingStartTime: 0, theme: input.tuiConfig.theme, + showTipsBanner: input.tuiConfig.showTipsBanner, version: input.version, editorCommand: input.tuiConfig.editorCommand, notifications: input.tuiConfig.notifications, @@ -466,7 +467,11 @@ export class KimiTUI { // Mount only after init() succeeds; see mountFooter(). this.mountFooter(); this.renderWelcome(); - void this.loadBanner(); + if (this.state.appState.showTipsBanner) { + void this.loadBanner(); + } else { + this.state.appState.banner = null; + } this.setupAutocomplete(); void this.loadPersistedInputHistory(); this.state.editorContainer.clear(); diff --git a/apps/kimi-code/src/tui/types.ts b/apps/kimi-code/src/tui/types.ts index 6b407f777..560601790 100644 --- a/apps/kimi-code/src/tui/types.ts +++ b/apps/kimi-code/src/tui/types.ts @@ -39,6 +39,7 @@ export interface AppState { streamingPhase: 'idle' | 'waiting' | 'thinking' | 'composing'; streamingStartTime: number; theme: ThemeName; + showTipsBanner: boolean; version: string; editorCommand: string | null; notifications: NotificationsConfig; diff --git a/apps/kimi-code/test/cli/run-shell.test.ts b/apps/kimi-code/test/cli/run-shell.test.ts index e93fd5db1..056029a72 100644 --- a/apps/kimi-code/test/cli/run-shell.test.ts +++ b/apps/kimi-code/test/cli/run-shell.test.ts @@ -12,8 +12,10 @@ type CreateKimiDeviceId = typeof createKimiDeviceIdFn; const mocks = vi.hoisted(() => { type TuiConfigFallback = { theme: 'dark' | 'light' | 'auto'; + showTipsBanner: boolean; editorCommand: string | null; notifications: { enabled: boolean; condition: 'unfocused' | 'always' }; + upgrade: { autoInstall: boolean }; }; class TuiConfigParseError extends Error { @@ -164,8 +166,10 @@ describe('runShell', () => { it('constructs KimiHarness and KimiTUI with startup input', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.tuiStart.mockResolvedValue(undefined); mocks.tuiGetStartupMcpMs.mockResolvedValue(47); @@ -222,6 +226,7 @@ describe('runShell', () => { cliOptions, tuiConfig: { theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, }, @@ -241,8 +246,10 @@ describe('runShell', () => { it('tracks first launch when device id creation reports first launch', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.tuiStart.mockResolvedValue(undefined); mocks.createKimiDeviceId.mockImplementationOnce((homeDir, options) => { @@ -276,8 +283,10 @@ describe('runShell', () => { it('registers first launch before harness construction can create the device id', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.tuiStart.mockResolvedValue(undefined); mocks.harnessCreatesDeviceIdOnConstruction = true; @@ -323,8 +332,10 @@ describe('runShell', () => { it('binds startup_perf to the session captured before MCP metrics resolve', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.tuiStart.mockResolvedValue(undefined); let currentSessionId = 'ses-startup'; @@ -362,8 +373,10 @@ describe('runShell', () => { it('bridges OAuth refresh outcomes to telemetry', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.tuiStart.mockResolvedValue(undefined); @@ -411,8 +424,10 @@ describe('runShell', () => { mocks.loadTuiConfig.mockRejectedValue( new mocks.TuiConfigParseError({ theme: 'auto', + showTipsBanner: true, editorCommand: 'vim', notifications: { enabled: true, condition: 'always' }, + upgrade: { autoInstall: true }, }), ); mocks.detectTerminalTheme.mockResolvedValue('light'); @@ -439,6 +454,7 @@ describe('runShell', () => { startupNotice: 'Invalid TUI config in ~/.kimi-code/tui.toml; using defaults.', tuiConfig: { theme: 'auto', + showTipsBanner: true, editorCommand: 'vim', notifications: { enabled: true, condition: 'always' }, }, @@ -448,8 +464,10 @@ describe('runShell', () => { it('forwards config.toml diagnostics as startup notices', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.harnessGetConfigDiagnostics.mockResolvedValue({ warnings: ['Ignored invalid config in config.toml: loop_control.'], @@ -480,8 +498,10 @@ describe('runShell', () => { it('closes the harness when TUI startup fails', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.tuiStart.mockRejectedValue(new Error('boom')); @@ -511,8 +531,10 @@ describe('runShell', () => { it('tracks exit and prints resume instructions from the TUI exit handler', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.tuiStart.mockResolvedValue(undefined); mocks.tuiGetCurrentSessionId.mockReturnValue('ses-1'); @@ -565,8 +587,10 @@ describe('runShell', () => { it('prints the opened web URL from the TUI exit handler when set', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.tuiStart.mockResolvedValue(undefined); mocks.tuiGetCurrentSessionId.mockReturnValue('ses-1'); @@ -612,8 +636,10 @@ describe('runShell', () => { it('surfaces an invalid target config as an error for kimi migrate, not silently', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, + upgrade: { autoInstall: true }, }); mocks.detectPendingMigration.mockResolvedValue({ totalSessions: 1 }); mocks.harnessGetConfig.mockRejectedValue( diff --git a/apps/kimi-code/test/cli/update/preflight.test.ts b/apps/kimi-code/test/cli/update/preflight.test.ts index a96d1445b..a03a5ba4a 100644 --- a/apps/kimi-code/test/cli/update/preflight.test.ts +++ b/apps/kimi-code/test/cli/update/preflight.test.ts @@ -161,6 +161,7 @@ function installState(overrides: Partial = {}): UpdateInstal function tuiConfig(overrides: Partial = {}): TuiConfig { return { theme: 'auto', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, diff --git a/apps/kimi-code/test/tui/activity-pane.test.ts b/apps/kimi-code/test/tui/activity-pane.test.ts index b719da163..2495d5a3b 100644 --- a/apps/kimi-code/test/tui/activity-pane.test.ts +++ b/apps/kimi-code/test/tui/activity-pane.test.ts @@ -29,6 +29,7 @@ function makeStartupInput(): KimiTUIStartupInput { }, tuiConfig: { theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, diff --git a/apps/kimi-code/test/tui/commands/reload.test.ts b/apps/kimi-code/test/tui/commands/reload.test.ts index ab54a221b..b2b655253 100644 --- a/apps/kimi-code/test/tui/commands/reload.test.ts +++ b/apps/kimi-code/test/tui/commands/reload.test.ts @@ -34,6 +34,7 @@ describe('reload slash commands', () => { it('reloads tui.toml without touching Core session state', async () => { await writeTuiConfig(` theme = "light" +show_tips_banner = false [editor] command = "vim" @@ -55,6 +56,7 @@ auto_install = false expect(session.reloadSession).not.toHaveBeenCalled(); expect(host.state.appState).toMatchObject({ theme: 'light', + showTipsBanner: false, editorCommand: 'vim', notifications: { enabled: false, condition: 'always' }, upgrade: { autoInstall: false }, @@ -82,6 +84,7 @@ auto_install = false expect(host.refreshSlashCommandAutocomplete).toHaveBeenCalledOnce(); expect(isExperimentalFlagEnabled('micro_compaction')).toBe(true); expect(host.state.appState.theme).toBe('light'); + expect(host.state.appState.showTipsBanner).toBe(true); expect(host.state.appState.availableModels).toEqual({ fresh: { provider: 'test', model: 'fresh-model', maxContextSize: 1000 }, }); @@ -129,6 +132,7 @@ function makeHost({ const state = { appState: { theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, diff --git a/apps/kimi-code/test/tui/commands/update-preferences.test.ts b/apps/kimi-code/test/tui/commands/update-preferences.test.ts index fdb64ce46..495f9f983 100644 --- a/apps/kimi-code/test/tui/commands/update-preferences.test.ts +++ b/apps/kimi-code/test/tui/commands/update-preferences.test.ts @@ -26,6 +26,7 @@ describe('update preference commands', () => { state: { appState: { theme: 'auto' as const, + showTipsBanner: false, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' as const }, upgrade: { autoInstall: true }, @@ -41,6 +42,7 @@ describe('update preference commands', () => { expect(mocks.saveTuiConfig).toHaveBeenCalledWith({ theme: 'auto', + showTipsBanner: false, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: false }, diff --git a/apps/kimi-code/test/tui/components/chrome/footer.test.ts b/apps/kimi-code/test/tui/components/chrome/footer.test.ts index ab0878d6b..8fc7f22d4 100644 --- a/apps/kimi-code/test/tui/components/chrome/footer.test.ts +++ b/apps/kimi-code/test/tui/components/chrome/footer.test.ts @@ -49,6 +49,7 @@ const appState: AppState = { planMode: false, swarmMode: false, theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, diff --git a/apps/kimi-code/test/tui/components/chrome/welcome.test.ts b/apps/kimi-code/test/tui/components/chrome/welcome.test.ts index cc3a2ff21..1c43b607d 100644 --- a/apps/kimi-code/test/tui/components/chrome/welcome.test.ts +++ b/apps/kimi-code/test/tui/components/chrome/welcome.test.ts @@ -27,6 +27,7 @@ const appState: AppState = { planMode: false, swarmMode: false, theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, diff --git a/apps/kimi-code/test/tui/config.test.ts b/apps/kimi-code/test/tui/config.test.ts index 21c4f4b6c..fd042ae57 100644 --- a/apps/kimi-code/test/tui/config.test.ts +++ b/apps/kimi-code/test/tui/config.test.ts @@ -34,6 +34,7 @@ describe('TUI config', () => { const text = readFileSync(filePath, 'utf-8'); expect(text).toContain('Client preferences for kimi-code.'); expect(text).toContain('theme = "auto"'); + expect(text).toContain('show_tips_banner = true'); expect(text).toContain('command = ""'); expect(text).toContain('[upgrade]'); expect(text).toContain('auto_install = true'); @@ -45,6 +46,7 @@ describe('TUI config', () => { it('parses valid TOML', () => { const config = parseTuiConfig(` theme = "light" +show_tips_banner = false [editor] command = "code --wait" @@ -59,6 +61,7 @@ auto_install = false expect(config).toEqual({ theme: 'light', + showTipsBanner: false, editorCommand: 'code --wait', notifications: { enabled: false, condition: 'always' }, upgrade: { autoInstall: false }, @@ -73,6 +76,7 @@ command = " " expect(config).toEqual({ theme: 'auto', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, @@ -104,6 +108,7 @@ command = " " await saveTuiConfig( { theme: 'light', + showTipsBanner: false, editorCommand: 'vim', notifications: { enabled: false, condition: 'always' }, upgrade: { autoInstall: false }, @@ -113,6 +118,7 @@ command = " " expect(await loadTuiConfig(filePath)).toEqual({ theme: 'light', + showTipsBanner: false, editorCommand: 'vim', notifications: { enabled: false, condition: 'always' }, upgrade: { autoInstall: false }, @@ -124,6 +130,7 @@ command = " " await saveTuiConfig( { theme, + showTipsBanner: true, editorCommand: null, notifications: DEFAULT_TUI_CONFIG.notifications, upgrade: DEFAULT_TUI_CONFIG.upgrade, diff --git a/apps/kimi-code/test/tui/create-tui-state.test.ts b/apps/kimi-code/test/tui/create-tui-state.test.ts index 8be57e91c..362db4114 100644 --- a/apps/kimi-code/test/tui/create-tui-state.test.ts +++ b/apps/kimi-code/test/tui/create-tui-state.test.ts @@ -21,6 +21,7 @@ function fakeInitialAppState(): AppState { streamingPhase: 'idle', streamingStartTime: 0, theme: 'dark', + showTipsBanner: true, version: '0.0.0-test', editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, diff --git a/apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts b/apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts index cab1bfeae..0257673be 100644 --- a/apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts +++ b/apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts @@ -102,6 +102,7 @@ function makeStartupInput(): KimiTUIStartupInput { }, tuiConfig: { theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, diff --git a/apps/kimi-code/test/tui/kimi-tui-startup.test.ts b/apps/kimi-code/test/tui/kimi-tui-startup.test.ts index 696024480..998f4a1e8 100644 --- a/apps/kimi-code/test/tui/kimi-tui-startup.test.ts +++ b/apps/kimi-code/test/tui/kimi-tui-startup.test.ts @@ -87,6 +87,7 @@ function makeStartupInput( }, tuiConfig: { theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, @@ -1632,6 +1633,34 @@ describe('KimiTUI startup', () => { loadSpy.mockRestore(); }); + it('does not load the remote tips banner when disabled in TUI config', async () => { + const loadSpy = vi.spyOn(BannerProvider.prototype, 'load').mockResolvedValue({ + key: 'new-banner', + tag: 'New', + mainText: 'Banner main', + subText: null, + display: 'always' as const, + }); + const session = makeSession({ id: 'ses-target' }); + const harness = makeHarness(session, { + listSessions: vi.fn(async () => [{ id: 'ses-target', workDir: '/tmp/proj-a' }]), + }); + const driver = makeDriver( + harness, + makeStartupInput({ session: 'ses-target' }, { showTipsBanner: false }), + ) as unknown as MigrateExitDriver; + + await driver.initMainTui(); + + expect(loadSpy).not.toHaveBeenCalled(); + expect(driver.state.appState.banner).toBeNull(); + expect( + driver.state.transcriptContainer.children.some((child) => child instanceof BannerComponent), + ).toBe(false); + + loadSpy.mockRestore(); + }); + it('writes display state after rendering a once banner', async () => { const originalEnv = { ...process.env }; const dir = mkdtempSync(join(tmpdir(), 'kimi-startup-banner-')); diff --git a/apps/kimi-code/test/tui/message-replay.test.ts b/apps/kimi-code/test/tui/message-replay.test.ts index f54bac27b..71366c012 100644 --- a/apps/kimi-code/test/tui/message-replay.test.ts +++ b/apps/kimi-code/test/tui/message-replay.test.ts @@ -52,6 +52,7 @@ function makeStartupInput(): KimiTUIStartupInput { }, tuiConfig: { theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, diff --git a/apps/kimi-code/test/tui/signal-handlers.test.ts b/apps/kimi-code/test/tui/signal-handlers.test.ts index 9d630a26d..88f856999 100644 --- a/apps/kimi-code/test/tui/signal-handlers.test.ts +++ b/apps/kimi-code/test/tui/signal-handlers.test.ts @@ -25,6 +25,7 @@ function makeStartupInput(): KimiTUIStartupInput { }, tuiConfig: { theme: 'dark', + showTipsBanner: true, editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: true }, diff --git a/docs/en/configuration/config-files.md b/docs/en/configuration/config-files.md index 0d64f5044..bc55f4aeb 100644 --- a/docs/en/configuration/config-files.md +++ b/docs/en/configuration/config-files.md @@ -244,6 +244,7 @@ Alongside `config.toml`, the CLI keeps terminal-UI and client preferences in a c | Field | Type | Default | Description | | --- | --- | --- | --- | | `theme` | `string` | `auto` | Color theme: `auto` (follow the terminal), `dark`, `light`, or the name of a [custom theme](../customization/themes) | +| `show_tips_banner` | `boolean` | `true` | Whether startup fetches and displays the remote tips banner; set to `false` to skip the request | | `[editor].command` | `string` | `""` | External editor command for composing long input; empty falls back to `$VISUAL` / `$EDITOR` | | `[notifications].enabled` | `boolean` | `true` | Whether desktop notifications are sent | | `[notifications].notification_condition` | `string` | `unfocused` | When to notify: `unfocused` (only when the terminal is not focused) or `always` | @@ -252,6 +253,7 @@ Alongside `config.toml`, the CLI keeps terminal-UI and client preferences in a c ```toml # ~/.kimi-code/tui.toml theme = "auto" # "auto" | "dark" | "light" | custom theme name +show_tips_banner = true # true | false [editor] command = "" # empty uses $VISUAL / $EDITOR @@ -264,7 +266,7 @@ notification_condition = "unfocused" # "unfocused" | "always" auto_install = true ``` -Changes apply on the next start, or immediately with `/reload-tui` (which reloads only `tui.toml`); `/reload` reloads both `config.toml` and `tui.toml`. +Most changes apply on the next start, or immediately with `/reload-tui` (which reloads only `tui.toml`); `/reload` reloads both `config.toml` and `tui.toml`. `show_tips_banner` controls the startup fetch, so disabling it takes effect on the next launch. ## Next steps diff --git a/docs/zh/configuration/config-files.md b/docs/zh/configuration/config-files.md index e0a215f56..16f53b6b0 100644 --- a/docs/zh/configuration/config-files.md +++ b/docs/zh/configuration/config-files.md @@ -244,6 +244,7 @@ MCP server 的声明配置写在 `~/.kimi-code/mcp.json` 或项目内 `.kimi-cod | 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | `theme` | `string` | `auto` | 配色主题:`auto`(跟随终端)、`dark`、`light`,或[自定义主题](../customization/themes)的名字 | +| `show_tips_banner` | `boolean` | `true` | 启动时是否拉取并展示远程 tips banner;设为 `false` 会跳过这次请求 | | `[editor].command` | `string` | `""` | 编写长输入用的外部编辑器命令;留空则回退到 `$VISUAL` / `$EDITOR` | | `[notifications].enabled` | `boolean` | `true` | 是否发送桌面通知 | | `[notifications].notification_condition` | `string` | `unfocused` | 何时通知:`unfocused`(仅终端失去焦点时)或 `always`(总是) | @@ -252,6 +253,7 @@ MCP server 的声明配置写在 `~/.kimi-code/mcp.json` 或项目内 `.kimi-cod ```toml # ~/.kimi-code/tui.toml theme = "auto" # "auto" | "dark" | "light" | 自定义主题名 +show_tips_banner = true # true | false [editor] command = "" # 留空则使用 $VISUAL / $EDITOR @@ -264,7 +266,7 @@ notification_condition = "unfocused" # "unfocused" | "always" auto_install = true ``` -修改在下次启动时生效,或用 `/reload-tui` 立即生效(只重载 `tui.toml`);`/reload` 会同时重载 `config.toml` 和 `tui.toml`。 +大多数修改会在下次启动时生效,也可用 `/reload-tui` 立即重载(只重载 `tui.toml`);`/reload` 会同时重载 `config.toml` 和 `tui.toml`。`show_tips_banner` 控制启动时的远程请求,因此关闭后从下一次启动开始生效。 ## 下一步