diff --git a/ccw/src/core/routes/skills-routes.ts b/ccw/src/core/routes/skills-routes.ts index 45055ad7..d2756730 100644 --- a/ccw/src/core/routes/skills-routes.ts +++ b/ccw/src/core/routes/skills-routes.ts @@ -64,19 +64,28 @@ function getDisabledSkillsConfigPath(location: SkillLocation, projectPath: strin /** * Load disabled skills configuration + * Throws on JSON parse errors to surface config corruption */ function loadDisabledSkillsConfig(location: SkillLocation, projectPath: string): DisabledSkillsConfig { const configPath = getDisabledSkillsConfigPath(location, projectPath); - try { - if (existsSync(configPath)) { - const content = readFileSync(configPath, 'utf8'); - const config = JSON.parse(content); - return { skills: config.skills || {} }; - } - } catch (error) { - console.error(`[Skills] Failed to load disabled skills config: ${error}`); + + if (!existsSync(configPath)) { + return { skills: {} }; + } + + try { + const content = readFileSync(configPath, 'utf8'); + const config = JSON.parse(content); + return { skills: config.skills || {} }; + } catch (error) { + // Throw on JSON parse errors to surface config corruption + if (error instanceof SyntaxError) { + throw new Error(`Config file corrupted: ${configPath}`); + } + // Log and return empty for other errors (permission, etc.) + console.error(`[Skills] Failed to load disabled skills config: ${error}`); + return { skills: {} }; } - return { skills: {} }; } /** diff --git a/ccw/src/templates/dashboard-js/views/skills-manager.js b/ccw/src/templates/dashboard-js/views/skills-manager.js index 65a05eec..c13dd2c7 100644 --- a/ccw/src/templates/dashboard-js/views/skills-manager.js +++ b/ccw/src/templates/dashboard-js/views/skills-manager.js @@ -219,6 +219,7 @@ function renderSkillCard(skill, location, isDisabled = false) { ${location}