From 9947ae75dafa7e774bbba1e2ec1c4df644838adc Mon Sep 17 00:00:00 2001 From: YYMa <2942204237@qq.com> Date: Fri, 5 Jun 2026 21:01:02 +0800 Subject: [PATCH] feat: add mode system with 6 AI personality presets (#1255) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update contributors * docs: update contributors * feat: add mode system with 6 AI personality presets Add a /mode command that lets users switch between 6 interaction modes, each with distinct system prompts, UI themes, permission defaults, and response verbosity: - Default (⚡) — balanced, everyday development - Gentle (🌸) — patient explanations for learning - Dr. Sharp (🔍) — strict 3-phase code review workflow - Workhorse (🐴) — auto-execute, minimal confirmations - Token Saver (💰) — minimal replies to save tokens - Super AI (🧠) — deep analysis, proactive suggestions Custom modes can be defined via YAML files in ~/.claude/modes/. New files: - src/modes/types.ts — CCBMode interface - src/modes/defaults.ts — 6 built-in mode presets - src/modes/store.ts — mode state management with useSyncExternalStore - src/commands/mode/index.ts — command registration - src/commands/mode/mode.tsx — mode picker UI Co-Authored-By: Claude Opus 4.7 --------- Co-authored-by: Claude Opus 4.7 --- src/commands.ts | 2 + src/commands/mode/index.ts | 13 +++ src/commands/mode/mode.tsx | 79 ++++++++++++++++ src/modes/defaults.ts | 181 +++++++++++++++++++++++++++++++++++++ src/modes/store.ts | 133 +++++++++++++++++++++++++++ src/modes/types.ts | 21 +++++ 6 files changed, 429 insertions(+) create mode 100644 src/commands/mode/index.ts create mode 100644 src/commands/mode/mode.tsx create mode 100644 src/modes/defaults.ts create mode 100644 src/modes/store.ts create mode 100644 src/modes/types.ts diff --git a/src/commands.ts b/src/commands.ts index 012a6a9bb..508498c27 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -19,6 +19,7 @@ import { context, contextNonInteractive } from './commands/context/index.js' import diff from './commands/diff/index.js' import doctor from './commands/doctor/index.js' import memory from './commands/memory/index.js' +import mode from './commands/mode/index.js' import help from './commands/help/index.js' import ide from './commands/ide/index.js' import init from './commands/init.js' @@ -327,6 +328,7 @@ const COMMANDS = memoize((): Command[] => [ mcp, memory, mobile, + mode, model, outputStyle, remoteEnv, diff --git a/src/commands/mode/index.ts b/src/commands/mode/index.ts new file mode 100644 index 000000000..d9b9e7339 --- /dev/null +++ b/src/commands/mode/index.ts @@ -0,0 +1,13 @@ +import type { Command } from '../../commands.js' + +const mode = { + type: 'local-jsx', + name: 'mode', + description: + 'Switch interaction mode (default, gentle, sharp, workhorse, token-saver, super-ai)', + isEnabled: () => true, + argumentHint: '', + load: () => import('./mode.js'), +} satisfies Command + +export default mode diff --git a/src/commands/mode/mode.tsx b/src/commands/mode/mode.tsx new file mode 100644 index 000000000..2aad5fde8 --- /dev/null +++ b/src/commands/mode/mode.tsx @@ -0,0 +1,79 @@ +import { useMemo } from 'react'; +import { Box, Text } from '@anthropic/ink'; +import { Select } from '../../components/CustomSelect/select.js'; +import type { LocalJSXCommandCall, LocalJSXCommandOnDone } from '../../types/command.js'; +import { getCurrentModeSlug, listModes, setCurrentMode } from '../../modes/store.js'; + +function ModePicker({ onDone }: { onDone: LocalJSXCommandOnDone }) { + const modes = listModes(); + const currentSlug = getCurrentModeSlug(); + + const options = useMemo( + () => + modes.map(m => ({ + label: ( + + {m.icon} {m.name}{' '} + + ({m.slug}) — {m.description} + + + ), + value: m.slug, + })), + [modes], + ); + + function handleSelect(slug: string) { + setCurrentMode(slug); + const target = modes.find(m => m.slug === slug); + onDone(`${target?.icon} Mode switched to: ${target?.name} (${target?.slug}) — ${target?.description}`, { + display: 'system', + }); + } + + function handleCancel() { + onDone('Mode selection cancelled.', { display: 'system' }); + } + + return ( + + + + Select mode + + Arrow keys to navigate, Enter to select, Esc to cancel. + +