Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tui-export-debug-zip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": minor
---

Add `/export-debug-zip` slash command to export the current session as a debug ZIP archive directly from the TUI.
18 changes: 1 addition & 17 deletions apps/kimi-code/src/cli/sub/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { CLI_SHUTDOWN_TIMEOUT_MS, CLI_UI_MODE } from '#/constant/app';
import { createCliTelemetryBootstrap, initializeCliTelemetry } from '#/cli/telemetry';
import { detectInstallSource } from '#/cli/update/source';
import { createKimiCodeHostIdentity } from '#/cli/version';
import { detectShellEnvironment } from '#/utils/process/shell-env';

interface WritableLike {
write(chunk: string): boolean;
Expand Down Expand Up @@ -231,23 +232,6 @@ async function confirmPreviousSession(summary: PreviousSessionSummary): Promise<
}
}

function detectMultiplexer(): string | undefined {
if (process.env['TMUX']) return 'tmux';
if (process.env['STY']) return 'screen';
if (process.env['ZELLIJ']) return 'zellij';
return undefined;
}

function detectShellEnvironment(): ShellEnvironment {
return {
term: process.env['TERM'] || undefined,
termProgram: process.env['TERM_PROGRAM'] || undefined,
termProgramVersion: process.env['TERM_PROGRAM_VERSION'] || undefined,
multiplexer: detectMultiplexer(),
shell: process.env['SHELL'] || undefined,
};
}

function errorMessage(error: unknown): string {
return error instanceof Error ? error.message : String(error);
}
6 changes: 6 additions & 0 deletions apps/kimi-code/src/tui/commands/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ export const BUILTIN_SLASH_COMMANDS = [
description: 'Connect a provider from a model catalog',
priority: 40,
},
{
name: 'export-debug-zip',
aliases: [],
description: 'Export current session as a debug ZIP archive',
priority: 40,
},
{
name: 'exit',
aliases: ['quit', 'q'],
Expand Down
6 changes: 2 additions & 4 deletions apps/kimi-code/src/tui/components/messages/plan-box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import type { Component, MarkdownTheme } from '@earendil-works/pi-tui';
import { Markdown, visibleWidth } from '@earendil-works/pi-tui';
import chalk from 'chalk';

import { toTerminalHyperlink } from '#/utils/terminal-hyperlink';

const LEFT_MARGIN = 2; // two-space indent matching other tool call children
const SIDE_PADDING = 1; // space between the │ and the content on each side
const TITLE_PREFIX = ' plan: ';
Expand Down Expand Up @@ -133,7 +135,3 @@ export class PlanBoxComponent implements Component {
return ` · ${chalk.hex(status.colorHex)(status.label)}`;
}
}

function toTerminalHyperlink(text: string, url: string): string {
return `\u001B]8;;${url}\u0007${text}\u001B]8;;\u0007`;
}
33 changes: 33 additions & 0 deletions apps/kimi-code/src/tui/kimi-tui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import { writeFileSync } from 'node:fs';
import { release as osRelease, type as osType } from 'node:os';
import { join } from 'node:path';
import { pathToFileURL } from 'node:url';

import {
Container,
Expand Down Expand Up @@ -98,6 +99,9 @@ import type {
import chalk from 'chalk';

import type { CLIOptions } from '#/cli/options';
import { detectInstallSource } from '#/cli/update/source';
import { detectShellEnvironment } from '#/utils/process/shell-env';
import { toTerminalHyperlink } from '#/utils/terminal-hyperlink';
import { MigrationScreenComponent, type MigrationScreenResult } from '#/migration/index';
import { ClipboardMediaError, readClipboardMedia } from '#/utils/clipboard/clipboard-image';
import type { GitLsFilesCache } from '#/utils/git/git-ls-files';
Expand Down Expand Up @@ -1586,6 +1590,9 @@ export class KimiTUI {
case 'fork':
await this.handleForkCommand(args);
return;
case 'export-debug-zip':
await this.handleExportDebugZipCommand();
return;
case 'login':
await this.handleLoginCommand();
return;
Expand Down Expand Up @@ -5524,6 +5531,32 @@ export class KimiTUI {
}
}

private async handleExportDebugZipCommand(): Promise<void> {
const session = this.session;
if (session === undefined) {
this.showError(NO_ACTIVE_SESSION_MESSAGE);
return;
}

this.showStatus('Exporting session…');
try {
const installSource = await detectInstallSource();
const shellEnv = detectShellEnvironment();
const result = await this.harness.exportSession({
Comment thread
liruifengv marked this conversation as resolved.
id: session.id,
version: this.state.appState.version,
installSource,
shellEnv,
includeGlobalLog: true,
});
const linked = toTerminalHyperlink(result.zipPath, pathToFileURL(result.zipPath).href);
this.showNotice('Export complete', linked);
} catch (error) {
const msg = formatErrorMessage(error);
this.showError(`Failed to export session: ${msg}`);
}
}

private forkSourceTitle(session: Session): string {
const currentTitle = this.state.appState.sessionTitle?.trim();
if (currentTitle !== undefined && currentTitle.length > 0) return currentTitle;
Expand Down
18 changes: 18 additions & 0 deletions apps/kimi-code/src/utils/process/shell-env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { ShellEnvironment } from '@moonshot-ai/kimi-code-sdk';

function detectMultiplexer(): string | undefined {
if (process.env['TMUX']) return 'tmux';
if (process.env['STY']) return 'screen';
if (process.env['ZELLIJ']) return 'zellij';
return undefined;
}

export function detectShellEnvironment(): ShellEnvironment {
return {
term: process.env['TERM'] || undefined,
termProgram: process.env['TERM_PROGRAM'] || undefined,
termProgramVersion: process.env['TERM_PROGRAM_VERSION'] || undefined,
multiplexer: detectMultiplexer(),
shell: process.env['SHELL'] || undefined,
};
}
3 changes: 3 additions & 0 deletions apps/kimi-code/src/utils/terminal-hyperlink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function toTerminalHyperlink(text: string, url: string): string {
return `\u001B]8;;${url}\u0007${text}\u001B]8;;\u0007`;
}
1 change: 1 addition & 0 deletions apps/kimi-code/test/tui/commands/registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe('built-in slash command registry', () => {
'compact',
'editor',
'exit',
'export-debug-zip',
'fork',
'help',
'init',
Expand Down
Loading