mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-09-02 03:25:44 +00:00
feat(cli): rename permission modes to Always Ask, Ask When Needed, and Never Ask (#3403)
TUI copy for the three permission modes (manual/yolo/auto) now uses the new display names and descriptions across the /permission selector, footer badge, toggle notices, goal/swarm start prompts, session replay, and /status. The /yolo and /auto commands are renamed to /ask-when-needed and /never-ask, with the old names kept as aliases.
This commit is contained in:
parent
3b2fc06a91
commit
08a2fb0031
22 changed files with 98 additions and 81 deletions
|
|
@ -48,8 +48,8 @@ export function createProgram(
|
|||
)
|
||||
.option('-c, --continue', 'Continue the previous session for the working directory.', false)
|
||||
.addOption(new Option('-C').hideHelp().default(false))
|
||||
.option('-y, --yolo', 'Auto-approve regular tool calls; the agent may still ask questions.', false)
|
||||
.option('--auto', 'Start in auto permission mode: fully autonomous, the agent will not ask questions.', false)
|
||||
.option('-y, --yolo', 'Start in Ask When Needed mode: routine edits and commands run automatically; risky actions, questions, and plans still ask.', false)
|
||||
.option('--auto', 'Start in Never Ask mode: never interrupts you; everything runs and is decided automatically.', false)
|
||||
.addOption(
|
||||
new Option(
|
||||
'-m, --model <model>',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import type { ThemeName } from '#/tui/theme';
|
|||
import { currentTheme, isBuiltInTheme, lightColors, loadCustomThemeMerged } from '#/tui/theme';
|
||||
import { NO_ACTIVE_SESSION_MESSAGE } from '../constant/kimi-tui';
|
||||
import { formatErrorMessage } from '../utils/event-payload';
|
||||
import { PERMISSION_MODE_DISPLAY_NAMES } from '../utils/permission-mode';
|
||||
import { thinkingEffortToConfig } from '../utils/thinking-config';
|
||||
import { showUsage } from './info';
|
||||
import { setExperimentalFeatures } from './experimental-flags';
|
||||
|
|
@ -139,23 +140,23 @@ export async function handleYoloCommand(host: SlashCommandHost, args: string): P
|
|||
|
||||
if (subcmd === 'on') {
|
||||
if (currentMode === 'yolo') {
|
||||
host.showNotice('YOLO mode is already on');
|
||||
host.showNotice('Ask When Needed mode is already on');
|
||||
return;
|
||||
}
|
||||
await session?.setPermission('yolo');
|
||||
host.setAppState({ permissionMode: 'yolo' });
|
||||
host.showNotice('YOLO mode: ON', 'Tool actions auto-approved; the agent may still ask you questions.');
|
||||
host.showNotice('Ask When Needed mode: ON', 'Routine edits and commands run automatically; risky actions, questions, and plans still ask.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (subcmd === 'off') {
|
||||
if (currentMode !== 'yolo') {
|
||||
host.showNotice('YOLO mode is already off');
|
||||
host.showNotice('Ask When Needed mode is already off');
|
||||
return;
|
||||
}
|
||||
await session?.setPermission('manual');
|
||||
host.setAppState({ permissionMode: 'manual' });
|
||||
host.showNotice('YOLO mode: OFF');
|
||||
host.showNotice('Ask When Needed mode: OFF');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -163,11 +164,11 @@ export async function handleYoloCommand(host: SlashCommandHost, args: string): P
|
|||
if (currentMode === 'yolo') {
|
||||
await session?.setPermission('manual');
|
||||
host.setAppState({ permissionMode: 'manual' });
|
||||
host.showNotice('YOLO mode: OFF');
|
||||
host.showNotice('Ask When Needed mode: OFF');
|
||||
} else {
|
||||
await session?.setPermission('yolo');
|
||||
host.setAppState({ permissionMode: 'yolo' });
|
||||
host.showNotice('YOLO mode: ON', 'Tool actions auto-approved; the agent may still ask you questions.');
|
||||
host.showNotice('Ask When Needed mode: ON', 'Routine edits and commands run automatically; risky actions, questions, and plans still ask.');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,23 +186,23 @@ export async function handleAutoCommand(host: SlashCommandHost, args: string): P
|
|||
|
||||
if (subcmd === 'on') {
|
||||
if (currentMode === 'auto') {
|
||||
host.showNotice('Auto mode is already on');
|
||||
host.showNotice('Never Ask mode is already on');
|
||||
return;
|
||||
}
|
||||
await session?.setPermission('auto');
|
||||
host.setAppState({ permissionMode: 'auto' });
|
||||
host.showNotice('Auto mode: ON', 'All actions auto-approved; the agent will not ask you questions.');
|
||||
host.showNotice('Never Ask mode: ON', 'Never interrupts you; everything runs and is decided automatically.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (subcmd === 'off') {
|
||||
if (currentMode !== 'auto') {
|
||||
host.showNotice('Auto mode is already off');
|
||||
host.showNotice('Never Ask mode is already off');
|
||||
return;
|
||||
}
|
||||
await session?.setPermission('manual');
|
||||
host.setAppState({ permissionMode: 'manual' });
|
||||
host.showNotice('Auto mode: OFF');
|
||||
host.showNotice('Never Ask mode: OFF');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -209,11 +210,11 @@ export async function handleAutoCommand(host: SlashCommandHost, args: string): P
|
|||
if (currentMode === 'auto') {
|
||||
await session?.setPermission('manual');
|
||||
host.setAppState({ permissionMode: 'manual' });
|
||||
host.showNotice('Auto mode: OFF');
|
||||
host.showNotice('Never Ask mode: OFF');
|
||||
} else {
|
||||
await session?.setPermission('auto');
|
||||
host.setAppState({ permissionMode: 'auto' });
|
||||
host.showNotice('Auto mode: ON', 'All actions auto-approved; the agent will not ask you questions.');
|
||||
host.showNotice('Never Ask mode: ON', 'Never interrupts you; everything runs and is decided automatically.');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -878,7 +879,7 @@ export async function applyUpdatePreferenceChoice(
|
|||
|
||||
async function applyPermissionChoice(host: SlashCommandHost, mode: PermissionMode): Promise<void> {
|
||||
if (mode === host.state.appState.permissionMode) {
|
||||
host.showStatus(`Permission mode unchanged: ${mode}.`);
|
||||
host.showStatus(`Permission mode unchanged: ${PERMISSION_MODE_DISPLAY_NAMES[mode]}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -898,7 +899,7 @@ async function applyPermissionChoice(host: SlashCommandHost, mode: PermissionMod
|
|||
}
|
||||
|
||||
host.setAppState({ permissionMode: mode });
|
||||
host.showNotice(`Permission mode: ${mode}`);
|
||||
host.showNotice(`Permission mode: ${PERMISSION_MODE_DISPLAY_NAMES[mode]}`);
|
||||
}
|
||||
|
||||
export function showSettingsSelector(host: SlashCommandHost): void {
|
||||
|
|
|
|||
|
|
@ -565,10 +565,10 @@ async function handleBuiltInSlashCommand(
|
|||
case 'title':
|
||||
await handleTitleCommand(host, args);
|
||||
return;
|
||||
case 'yolo':
|
||||
case 'ask-when-needed':
|
||||
await handleYoloCommand(host, args);
|
||||
return;
|
||||
case 'auto':
|
||||
case 'never-ask':
|
||||
await handleAutoCommand(host, args);
|
||||
return;
|
||||
case 'plan':
|
||||
|
|
|
|||
|
|
@ -146,16 +146,16 @@ function formatDirectoryCompletionValue(argumentPrefix: string, parentInput: str
|
|||
|
||||
export const BUILTIN_SLASH_COMMANDS = [
|
||||
{
|
||||
name: 'yolo',
|
||||
aliases: ['yes'],
|
||||
description: 'Toggle YOLO mode: auto-approve tool actions, but the agent may still ask questions.',
|
||||
name: 'ask-when-needed',
|
||||
aliases: ['yolo', 'yes'],
|
||||
description: 'Toggle Ask When Needed mode: routine edits and commands run automatically; risky actions, questions, and plans still ask.',
|
||||
priority: 101,
|
||||
availability: 'always',
|
||||
},
|
||||
{
|
||||
name: 'auto',
|
||||
aliases: [],
|
||||
description: 'Toggle Auto mode: fully autonomous, but dangerous commands are blocked.',
|
||||
name: 'never-ask',
|
||||
aliases: ['auto'],
|
||||
description: 'Toggle Never Ask mode: never interrupts you; everything runs and is decided automatically.',
|
||||
priority: 99,
|
||||
availability: 'always',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Footer/status bar — multi-line status display at the bottom of the TUI.
|
||||
*
|
||||
* Layout:
|
||||
* Line 1: [yolo] [plan] <model> <cwd> <git-badge> <shortcut hints>
|
||||
* Line 1: [ask-when-needed] [plan] <model> <cwd> <git-badge> <shortcut hints>
|
||||
* Line 2: context: N% (tokens/max)
|
||||
*/
|
||||
|
||||
|
|
@ -16,6 +16,7 @@ import { isRainbowDancing, renderDanceFooterModel } from '#/tui/easter-eggs/danc
|
|||
import { currentTheme } from '#/tui/theme';
|
||||
import type { ColorPalette } from '#/tui/theme/colors';
|
||||
import type { AppState } from '#/tui/types';
|
||||
import { PERMISSION_MODE_DISPLAY_NAMES } from '#/tui/utils/permission-mode';
|
||||
import {
|
||||
StatusLineCommandRunner,
|
||||
type StatusLinePayload,
|
||||
|
|
@ -387,8 +388,8 @@ export class FooterComponent implements Component {
|
|||
}
|
||||
|
||||
const modes: string[] = [];
|
||||
if (state.permissionMode === 'auto') modes.push(chalk.hex(colors.warning).bold('auto'));
|
||||
if (state.permissionMode === 'yolo') modes.push(chalk.hex(colors.warning).bold('yolo'));
|
||||
if (state.permissionMode === 'auto') modes.push(chalk.hex(colors.warning).bold(PERMISSION_MODE_DISPLAY_NAMES.auto));
|
||||
if (state.permissionMode === 'yolo') modes.push(chalk.hex(colors.warning).bold(PERMISSION_MODE_DISPLAY_NAMES.yolo));
|
||||
if (state.planMode) modes.push(chalk.hex(colors.primary).bold('plan'));
|
||||
if (state.swarmMode) modes.push(chalk.hex(colors.accent).bold('swarm'));
|
||||
if (state.towerMode) modes.push(chalk.hex(colors.accent).bold('tower'));
|
||||
|
|
|
|||
|
|
@ -14,19 +14,19 @@ export interface GoalStartPermissionPromptOptions {
|
|||
export const GOAL_START_MANUAL_OPTIONS: readonly StartPermissionOption[] = [
|
||||
{
|
||||
value: 'auto',
|
||||
label: 'Switch to Auto and start',
|
||||
label: 'Switch to Never Ask and start',
|
||||
description:
|
||||
'Best if you want Kimi Code to keep working while you are away. Tools are approved automatically, and questions are skipped.',
|
||||
},
|
||||
{
|
||||
value: 'yolo',
|
||||
label: 'Switch to YOLO and start',
|
||||
label: 'Switch to Ask When Needed and start',
|
||||
description:
|
||||
'Tools and plan changes are approved automatically. Kimi Code may still ask you questions.',
|
||||
},
|
||||
{
|
||||
value: 'manual',
|
||||
label: 'Start in Manual',
|
||||
label: 'Start in Always Ask',
|
||||
description:
|
||||
'Keep approvals on. Kimi Code will ask before risky actions, so the goal may stop and wait for you.',
|
||||
},
|
||||
|
|
@ -40,13 +40,13 @@ export const GOAL_START_MANUAL_OPTIONS: readonly StartPermissionOption[] = [
|
|||
export const GOAL_START_YOLO_OPTIONS: readonly StartPermissionOption[] = [
|
||||
{
|
||||
value: 'auto',
|
||||
label: 'Switch to Auto and start',
|
||||
label: 'Switch to Never Ask and start',
|
||||
description:
|
||||
'Best if you want Kimi Code to keep working while you are away. Tools are approved automatically, and questions are skipped.',
|
||||
},
|
||||
{
|
||||
value: 'yolo',
|
||||
label: 'Keep YOLO and start',
|
||||
label: 'Keep Ask When Needed and start',
|
||||
description:
|
||||
'Tools and plan changes stay approved automatically. Kimi Code may still ask you questions.',
|
||||
},
|
||||
|
|
@ -66,15 +66,15 @@ const MANUAL_OPTIONS = GOAL_START_MANUAL_OPTIONS;
|
|||
const YOLO_OPTIONS = GOAL_START_YOLO_OPTIONS;
|
||||
|
||||
const MANUAL_NOTICE_LINES = [
|
||||
'Manual mode asks you before Kimi Code runs commands, edits files, or takes other risky actions.',
|
||||
'Manual mode is not suitable for unattended goal work.',
|
||||
'Always Ask mode asks you before Kimi Code runs commands, edits files, or takes other risky actions.',
|
||||
'Always Ask mode is not suitable for unattended goal work.',
|
||||
'You can go back without losing your command.',
|
||||
] as const;
|
||||
|
||||
const YOLO_NOTICE_LINES = [
|
||||
'YOLO mode approves tools and plan changes automatically.',
|
||||
'YOLO mode can still stop for questions.',
|
||||
'Switch to Auto if you want questions skipped during goal work.',
|
||||
'Ask When Needed mode approves tools and plan changes automatically.',
|
||||
'Ask When Needed mode can still stop for questions.',
|
||||
'Switch to Never Ask if you want questions skipped during goal work.',
|
||||
] as const;
|
||||
|
||||
export class GoalStartPermissionPromptComponent extends StartPermissionPromptComponent {
|
||||
|
|
@ -82,7 +82,7 @@ export class GoalStartPermissionPromptComponent extends StartPermissionPromptCom
|
|||
super({
|
||||
title:
|
||||
opts.mode === 'yolo'
|
||||
? 'Start a goal in YOLO mode?'
|
||||
? 'Start a goal in Ask When Needed mode?'
|
||||
: 'Start a goal with approvals on?',
|
||||
noticeLines: opts.mode === 'yolo' ? YOLO_NOTICE_LINES : MANUAL_NOTICE_LINES,
|
||||
options: opts.mode === 'yolo' ? YOLO_OPTIONS : MANUAL_OPTIONS,
|
||||
|
|
|
|||
|
|
@ -1,22 +1,25 @@
|
|||
import type { PermissionMode } from '@moonshot-ai/kimi-code-sdk';
|
||||
|
||||
import { PERMISSION_MODE_DISPLAY_NAMES } from '#/tui/utils/permission-mode';
|
||||
|
||||
import { ChoicePickerComponent, type ChoiceOption } from './choice-picker';
|
||||
|
||||
const PERMISSION_OPTIONS: readonly ChoiceOption[] = [
|
||||
{
|
||||
value: 'manual',
|
||||
label: 'Manual',
|
||||
description: 'Approve every action yourself.',
|
||||
label: PERMISSION_MODE_DISPLAY_NAMES.manual,
|
||||
description: 'Auto-read only; everything else needs your approval first.',
|
||||
},
|
||||
{
|
||||
value: 'yolo',
|
||||
label: 'YOLO',
|
||||
description: 'Auto-approve tool actions, but the agent may still ask questions.',
|
||||
label: PERMISSION_MODE_DISPLAY_NAMES.yolo,
|
||||
description:
|
||||
'Routine edits and commands run automatically; risky actions, questions, and plans still ask.',
|
||||
},
|
||||
{
|
||||
value: 'auto',
|
||||
label: 'Auto',
|
||||
description: 'Fully autonomous, but dangerous commands are blocked.',
|
||||
label: PERMISSION_MODE_DISPLAY_NAMES.auto,
|
||||
description: 'Never interrupts you; everything runs and is decided automatically.',
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -99,9 +99,9 @@ function styleLabel(label: string, selected: boolean): string {
|
|||
|
||||
function styleModeNames(text: string, baseToken: 'text' | 'textMuted'): string {
|
||||
return text
|
||||
.split(/(\b(?:Manual|Auto|YOLO)\b)/g)
|
||||
.split(/(\b(?:Always Ask|Ask When Needed|Never Ask)\b)/g)
|
||||
.map((part) => {
|
||||
if (part === 'Manual' || part === 'Auto' || part === 'YOLO') return currentTheme.boldFg('textStrong', part);
|
||||
if (part === 'Always Ask' || part === 'Ask When Needed' || part === 'Never Ask') return currentTheme.boldFg('textStrong', part);
|
||||
return currentTheme.fg(baseToken, part);
|
||||
})
|
||||
.join('');
|
||||
|
|
|
|||
|
|
@ -13,27 +13,27 @@ export interface SwarmStartPermissionPromptOptions {
|
|||
const OPTIONS: readonly StartPermissionOption<SwarmStartPermissionChoice>[] = [
|
||||
{
|
||||
value: 'auto',
|
||||
label: 'Switch to Auto and start',
|
||||
label: 'Switch to Never Ask and start',
|
||||
description:
|
||||
'Best for swarm tasks. Tools are approved automatically, and questions are skipped.',
|
||||
},
|
||||
{
|
||||
value: 'yolo',
|
||||
label: 'Switch to YOLO and start',
|
||||
label: 'Switch to Ask When Needed and start',
|
||||
description:
|
||||
'Tools and plan changes are approved automatically. Kimi Code may still ask you questions.',
|
||||
},
|
||||
{
|
||||
value: 'manual',
|
||||
label: 'Start in Manual',
|
||||
label: 'Start in Always Ask',
|
||||
description:
|
||||
'Keep approvals on. Kimi Code may stop and wait for you during the swarm task.',
|
||||
},
|
||||
];
|
||||
|
||||
const NOTICE_LINES = [
|
||||
'Manual mode asks you before Kimi Code runs commands, edits files, or takes other risky actions.',
|
||||
'Manual mode can block swarm work while agents are running.',
|
||||
'Always Ask mode asks you before Kimi Code runs commands, edits files, or takes other risky actions.',
|
||||
'Always Ask mode can block swarm work while agents are running.',
|
||||
'You can go back without losing your command.',
|
||||
] as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {
|
|||
|
||||
import { PRODUCT_NAME } from '#/constant/app';
|
||||
import { currentTheme } from '#/tui/theme';
|
||||
import { PERMISSION_MODE_DISPLAY_NAMES } from '#/tui/utils/permission-mode';
|
||||
import {
|
||||
formatTokenCount,
|
||||
ratioSeverity,
|
||||
|
|
@ -114,7 +115,7 @@ export function buildStatusReportLines(options: StatusReportOptions): string[] {
|
|||
const rows: FieldRow[] = [
|
||||
{ label: 'Model', value: formatModelStatus(options) },
|
||||
{ label: 'Directory', value: options.workDir },
|
||||
{ label: 'Permissions', value: permission },
|
||||
{ label: 'Permissions', value: PERMISSION_MODE_DISPLAY_NAMES[permission] },
|
||||
{ label: 'Plan mode', value: planMode ? 'on' : 'off' },
|
||||
];
|
||||
if (options.towerAvailable) {
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ export const ALL_TIPS: readonly ToolbarTip[] = [
|
|||
{ text: 'shift+enter: newline' },
|
||||
{ text: 'ctrl+c: cancel' },
|
||||
{ text: '/theme to switch the terminal UI theme' },
|
||||
{ text: '/auto when you want Kimi to handle approvals and keep going unattended' },
|
||||
{ text: '/yolo to skip most approvals for trusted batch work, only use it in repos you trust' },
|
||||
{ text: '/never-ask when you want Kimi to handle approvals and keep going unattended' },
|
||||
{ text: '/ask-when-needed to skip most approvals for trusted batch work, only use it in repos you trust' },
|
||||
{ text: '/help: show commands' },
|
||||
{ text: '/compact compresses context when it gets long', priority: 2 },
|
||||
{ text: 'ctrl-o to hide or reveal tool output switching between a clean chat view and full execution details', priority: 2 },
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import { formatBackgroundAgentTranscript } from '../utils/background-agent-statu
|
|||
import { formatBackgroundTaskTranscript } from '../utils/background-task-status';
|
||||
import { modelDisplayName } from '../components/dialogs/model-selector';
|
||||
import { buildGoalCompletionMessage } from '../utils/goal-completion';
|
||||
import { PERMISSION_MODE_DISPLAY_NAMES } from '../utils/permission-mode';
|
||||
import { formatBashOutputForDisplay } from '../utils/shell-output';
|
||||
import { markTranscriptComponent } from '../utils/transcript-component-metadata';
|
||||
import {
|
||||
|
|
@ -684,8 +685,8 @@ export class SessionReplayRenderer {
|
|||
private renderPermissionUpdate(context: ReplayRenderContext, mode: PermissionMode): void {
|
||||
if (mode === 'yolo') {
|
||||
this.host.appendTranscriptEntry(
|
||||
replayEntry(context, 'status', 'YOLO mode: ON', 'notice', {
|
||||
detail: 'Tool actions auto-approved; the agent may still ask you questions.',
|
||||
replayEntry(context, 'status', 'Ask When Needed mode: ON', 'notice', {
|
||||
detail: 'Routine edits and commands run automatically; risky actions, questions, and plans still ask.',
|
||||
}),
|
||||
);
|
||||
return;
|
||||
|
|
@ -694,7 +695,9 @@ export class SessionReplayRenderer {
|
|||
replayEntry(
|
||||
context,
|
||||
'status',
|
||||
mode === 'manual' ? 'YOLO mode: OFF' : `Permission mode: ${mode}`,
|
||||
mode === 'manual'
|
||||
? 'Ask When Needed mode: OFF'
|
||||
: `Permission mode: ${PERMISSION_MODE_DISPLAY_NAMES[mode]}`,
|
||||
'notice',
|
||||
),
|
||||
);
|
||||
|
|
|
|||
7
apps/kimi-code/src/tui/utils/permission-mode.ts
Normal file
7
apps/kimi-code/src/tui/utils/permission-mode.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import type { PermissionMode } from '@moonshot-ai/kimi-code-sdk';
|
||||
|
||||
export const PERMISSION_MODE_DISPLAY_NAMES: Readonly<Record<PermissionMode, string>> = {
|
||||
manual: 'Always Ask',
|
||||
yolo: 'Ask When Needed',
|
||||
auto: 'Never Ask',
|
||||
};
|
||||
|
|
@ -358,7 +358,7 @@ describe('handleGoalCommand', () => {
|
|||
expect(s.createGoal).not.toHaveBeenCalled();
|
||||
expect(manualHost.sendNormalUserInput).not.toHaveBeenCalled();
|
||||
const text = stripAnsi(mountedPicker(manualHost).render(80).join('\n'));
|
||||
expect(text).toContain('Manual mode is not suitable for unattended goal work');
|
||||
expect(text).toContain('Always Ask mode is not suitable for unattended goal work');
|
||||
expect(text).toContain('Return to the input box with your goal command');
|
||||
});
|
||||
|
||||
|
|
@ -466,9 +466,9 @@ describe('handleGoalCommand', () => {
|
|||
expect(s.createGoal).not.toHaveBeenCalled();
|
||||
expect(yoloHost.sendNormalUserInput).not.toHaveBeenCalled();
|
||||
const text = stripAnsi(mountedPicker(yoloHost).render(80).join('\n'));
|
||||
expect(text).toContain('YOLO mode can still stop for questions');
|
||||
expect(text).toContain('Keep YOLO and start');
|
||||
expect(text).not.toContain('Start in Manual');
|
||||
expect(text).toContain('Ask When Needed mode can still stop for questions');
|
||||
expect(text).toContain('Keep Ask When Needed and start');
|
||||
expect(text).not.toContain('Start in Always Ask');
|
||||
});
|
||||
|
||||
it('defaults to Auto when confirming a YOLO-mode goal start', async () => {
|
||||
|
|
|
|||
|
|
@ -194,7 +194,8 @@ describe('built-in slash command registry', () => {
|
|||
'undo',
|
||||
'usage',
|
||||
'version',
|
||||
'yolo',
|
||||
'ask-when-needed',
|
||||
'never-ask',
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ describe('handleSwarmCommand', () => {
|
|||
expect(session.setPermission).not.toHaveBeenCalled();
|
||||
expect(host.sendNormalUserInput).not.toHaveBeenCalled();
|
||||
const text = stripAnsi(mountedPicker(host).render(80).join('\n'));
|
||||
expect(text).toContain('Manual mode can block swarm work');
|
||||
expect(text).toContain('Always Ask mode can block swarm work');
|
||||
mountedPicker(host).handleInput(ENTER);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
|
|
@ -213,8 +213,8 @@ describe('handleSwarmCommand', () => {
|
|||
expect(session.setPermission).not.toHaveBeenCalled();
|
||||
expect(host.sendNormalUserInput).not.toHaveBeenCalled();
|
||||
const text = stripAnsi(mountedPicker(host).render(80).join('\n'));
|
||||
expect(text).toContain('Manual mode can block swarm work');
|
||||
expect(text).toContain('Switch to YOLO and start');
|
||||
expect(text).toContain('Always Ask mode can block swarm work');
|
||||
expect(text).toContain('Switch to Ask When Needed and start');
|
||||
expect(text).not.toContain('Do not start');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ describe('ApprovalPanelComponent', () => {
|
|||
display: [],
|
||||
choices: [
|
||||
{
|
||||
label: 'Switch to Auto and start',
|
||||
label: 'Switch to Never Ask and start',
|
||||
response: 'approved',
|
||||
selected_label: 'auto',
|
||||
description: 'Tools are approved automatically, and questions are skipped.',
|
||||
|
|
@ -82,7 +82,7 @@ describe('ApprovalPanelComponent', () => {
|
|||
},
|
||||
};
|
||||
const out = strip(new ApprovalPanelComponent(pending, () => {}).render(80).join('\n'));
|
||||
expect(out).toContain('1. Switch to Auto and start');
|
||||
expect(out).toContain('1. Switch to Never Ask and start');
|
||||
expect(out).toContain('Tools are approved automatically, and questions are skipped.');
|
||||
// A choice without a description stays label-only — no stray blank helper line.
|
||||
expect(out).toContain('2. Do not start');
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ describe('ChoicePickerComponent', () => {
|
|||
onSelect,
|
||||
onCancel,
|
||||
});
|
||||
expect(permission.render(120).map(strip)).toContain(' ❯ Manual ← current');
|
||||
expect(permission.render(120).map(strip)).toContain(' ❯ Always Ask ← current');
|
||||
|
||||
const settings = new SettingsSelectorComponent({
|
||||
onSelect,
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ describe('status panel report lines', () => {
|
|||
expect(output).toContain('>_ Kimi Code (v1.2.3)');
|
||||
expect(output).toContain('Model Kimi K2 (thinking high)');
|
||||
expect(output).toContain('Directory /tmp/project');
|
||||
expect(output).toContain('Permissions auto');
|
||||
expect(output).toContain('Permissions Never Ask');
|
||||
expect(output).toContain('Plan mode on');
|
||||
expect(output).toContain('Session ses-1');
|
||||
expect(output).toContain('Title Implement status');
|
||||
|
|
|
|||
|
|
@ -2613,7 +2613,7 @@ command = "vim"
|
|||
expect(driver.state.appState).toMatchObject({
|
||||
permissionMode: 'yolo',
|
||||
});
|
||||
expect(harness.track).toHaveBeenCalledWith('input_command', { command: 'yolo' });
|
||||
expect(harness.track).toHaveBeenCalledWith('input_command', { command: 'ask-when-needed' });
|
||||
expect(harness.track).not.toHaveBeenCalledWith('yolo_toggle', expect.anything());
|
||||
});
|
||||
|
||||
|
|
@ -2835,7 +2835,7 @@ command = "vim"
|
|||
driver.handleUserInput('/auto on');
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(stripSgr(renderTranscript(driver))).toContain('Auto mode: ON');
|
||||
expect(stripSgr(renderTranscript(driver))).toContain('Never Ask mode: ON');
|
||||
});
|
||||
|
||||
driver.handleUserInput('/undo 10');
|
||||
|
|
@ -2855,7 +2855,7 @@ command = "vim"
|
|||
const transcript = stripSgr(renderTranscript(driver));
|
||||
expect(transcript).not.toContain('hello');
|
||||
expect(transcript).not.toContain('Cannot undo 10 prompts');
|
||||
expect(transcript).toContain('Auto mode: ON');
|
||||
expect(transcript).toContain('Never Ask mode: ON');
|
||||
expect(driver.state.appState.permissionMode).toBe('auto');
|
||||
});
|
||||
|
||||
|
|
@ -6778,7 +6778,7 @@ command = "vim"
|
|||
expect(output).toContain('>_ Kimi Code');
|
||||
expect(output).toContain('Model');
|
||||
expect(output).toContain('thinking high');
|
||||
expect(output).toContain('Permissions auto');
|
||||
expect(output).toContain('Permissions Never Ask');
|
||||
expect(output).toContain('Plan mode on');
|
||||
expect(output).toContain('Context window');
|
||||
expect(output).toContain('25%');
|
||||
|
|
|
|||
|
|
@ -1321,9 +1321,9 @@ describe('KimiTUI resume message replay', () => {
|
|||
const transcript = driver.state.transcriptContainer.render(120).join('\n');
|
||||
|
||||
expect(transcript).toContain('Plan mode: ON');
|
||||
expect(transcript).toContain('Permission mode: auto');
|
||||
expect(transcript).toContain('YOLO mode: ON');
|
||||
expect(transcript).toContain('YOLO mode: OFF');
|
||||
expect(transcript).toContain('Permission mode: Never Ask');
|
||||
expect(transcript).toContain('Ask When Needed mode: ON');
|
||||
expect(transcript).toContain('Ask When Needed mode: OFF');
|
||||
expect(transcript).toContain('Approved for session: run command');
|
||||
expect(transcript).toContain('Plan mode: OFF');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -236,21 +236,21 @@ describe('approval adapter', () => {
|
|||
// /goal menu's description.
|
||||
expect(adapted.choices).toEqual([
|
||||
{
|
||||
label: 'Switch to Auto and start',
|
||||
label: 'Switch to Never Ask and start',
|
||||
response: 'approved',
|
||||
selected_label: 'auto',
|
||||
description:
|
||||
'Best if you want Kimi Code to keep working while you are away. Tools are approved automatically, and questions are skipped.',
|
||||
},
|
||||
{
|
||||
label: 'Switch to YOLO and start',
|
||||
label: 'Switch to Ask When Needed and start',
|
||||
response: 'approved',
|
||||
selected_label: 'yolo',
|
||||
description:
|
||||
'Tools and plan changes are approved automatically. Kimi Code may still ask you questions.',
|
||||
},
|
||||
{
|
||||
label: 'Start in Manual',
|
||||
label: 'Start in Always Ask',
|
||||
response: 'approved',
|
||||
selected_label: 'manual',
|
||||
description:
|
||||
|
|
@ -280,14 +280,14 @@ describe('approval adapter', () => {
|
|||
expect(adapted.display).toEqual([{ type: 'brief', text: 'Start goal: Ship the feature' }]);
|
||||
expect(adapted.choices).toEqual([
|
||||
{
|
||||
label: 'Switch to Auto and start',
|
||||
label: 'Switch to Never Ask and start',
|
||||
response: 'approved',
|
||||
selected_label: 'auto',
|
||||
description:
|
||||
'Best if you want Kimi Code to keep working while you are away. Tools are approved automatically, and questions are skipped.',
|
||||
},
|
||||
{
|
||||
label: 'Keep YOLO and start',
|
||||
label: 'Keep Ask When Needed and start',
|
||||
response: 'approved',
|
||||
selected_label: 'yolo',
|
||||
description:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue