fix: prevent empty mode names from being saved (#5766) (#5794)

This commit is contained in:
Daniel 2025-07-16 16:50:14 -05:00 committed by GitHub
parent a92ee567df
commit 2458751424
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 3 deletions

View file

@ -401,6 +401,14 @@ export class CustomModesManager {
public async updateCustomMode(slug: string, config: ModeConfig): Promise<void> {
try {
// Validate the mode configuration before saving
const validationResult = modeConfigSchema.safeParse(config)
if (!validationResult.success) {
const errors = validationResult.error.errors.map((e) => e.message).join(", ")
logger.error(`Invalid mode configuration for ${slug}`, { errors: validationResult.error.errors })
throw new Error(`Invalid mode configuration: ${errors}`)
}
const isProjectMode = config.source === "project"
let targetPath: string

View file

@ -110,6 +110,10 @@ const ModesView = ({ onDone }: ModesViewProps) => {
const [searchValue, setSearchValue] = useState("")
const searchInputRef = useRef<HTMLInputElement>(null)
// Local state for mode name input to allow visual emptying
const [localModeName, setLocalModeName] = useState<string>("")
const [currentEditingModeSlug, setCurrentEditingModeSlug] = useState<string | null>(null)
// Direct update functions
const updateAgentPrompt = useCallback(
(mode: Mode, promptData: PromptComponent) => {
@ -218,6 +222,14 @@ const ModesView = ({ onDone }: ModesViewProps) => {
}
}, [getCurrentMode, checkRulesDirectory, hasRulesToExport])
// Reset local name state when mode changes
useEffect(() => {
if (currentEditingModeSlug && currentEditingModeSlug !== visualMode) {
setCurrentEditingModeSlug(null)
setLocalModeName("")
}
}, [visualMode, currentEditingModeSlug])
// Helper function to safely access mode properties
const getModeProperty = <T extends keyof ModeConfig>(
mode: ModeConfig | undefined,
@ -725,16 +737,34 @@ const ModesView = ({ onDone }: ModesViewProps) => {
<div className="flex gap-2">
<Input
type="text"
value={getModeProperty(findModeBySlug(visualMode, customModes), "name") ?? ""}
onChange={(e) => {
value={
currentEditingModeSlug === visualMode
? localModeName
: (getModeProperty(findModeBySlug(visualMode, customModes), "name") ??
"")
}
onFocus={() => {
const customMode = findModeBySlug(visualMode, customModes)
if (customMode) {
setCurrentEditingModeSlug(visualMode)
setLocalModeName(customMode.name)
}
}}
onChange={(e) => {
setLocalModeName(e.target.value)
}}
onBlur={() => {
const customMode = findModeBySlug(visualMode, customModes)
if (customMode && localModeName.trim()) {
// Only update if the name is not empty
updateCustomMode(visualMode, {
...customMode,
name: e.target.value,
name: localModeName,
source: customMode.source || "global",
})
}
// Clear the editing state
setCurrentEditingModeSlug(null)
}}
className="w-full"
/>