feat: skills disable command + sync wizard pre-checks installed skills (#465)
This commit is contained in:
@@ -335,7 +335,7 @@ async function main() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'skills': {
|
case 'skills': {
|
||||||
const { showStatus, runSkillsSync, enableSkill } = await import('./skills/index.js');
|
const { showStatus, runSkillsSync, enableSkill, disableSkill } = await import('./skills/index.js');
|
||||||
switch (subCommand) {
|
switch (subCommand) {
|
||||||
case 'status':
|
case 'status':
|
||||||
await showStatus();
|
await showStatus();
|
||||||
@@ -347,6 +347,13 @@ async function main() {
|
|||||||
}
|
}
|
||||||
enableSkill(args[2]);
|
enableSkill(args[2]);
|
||||||
break;
|
break;
|
||||||
|
case 'disable':
|
||||||
|
if (!args[2]) {
|
||||||
|
console.error('Usage: lettabot skills disable <name>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
disableSkill(args[2]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
await runSkillsSync();
|
await runSkillsSync();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,11 +149,12 @@ export async function runSkillsSync(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start with no skills selected (user must explicitly enable)
|
// Pre-check currently installed skills so the user edits from current state
|
||||||
|
const currentlyInstalled = skills.filter(s => s.installed).map(s => s.name);
|
||||||
const selected = await p.multiselect({
|
const selected = await p.multiselect({
|
||||||
message: 'Enable skills (space=toggle, enter=confirm):',
|
message: 'Enable skills (space=toggle, enter=confirm):',
|
||||||
options,
|
options,
|
||||||
initialValues: [], // Disabled by default
|
initialValues: currentlyInstalled,
|
||||||
required: false,
|
required: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -220,6 +221,24 @@ export async function runSkillsSync(): Promise<void> {
|
|||||||
p.outro(`✨ Added ${toAdd.length}, removed ${toRemove.length} skill(s)`);
|
p.outro(`✨ Added ${toAdd.length}, removed ${toRemove.length} skill(s)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-interactively disable a single skill by name.
|
||||||
|
*/
|
||||||
|
export function disableSkill(name: string): void {
|
||||||
|
const dest = join(TARGET_DIR, name);
|
||||||
|
if (!existsSync(dest)) {
|
||||||
|
console.log(`Skill '${name}' is not enabled.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
rmSync(dest, { recursive: true, force: true });
|
||||||
|
console.log(`Disabled skill '${name}'.`);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Failed to disable '${name}': ${e}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-interactively enable a single skill by name.
|
* Non-interactively enable a single skill by name.
|
||||||
* Searches BUNDLED_SKILLS_DIR, then GLOBAL_SKILLS_DIR, then SKILLS_SH_DIR.
|
* Searches BUNDLED_SKILLS_DIR, then GLOBAL_SKILLS_DIR, then SKILLS_SH_DIR.
|
||||||
|
|||||||
@@ -294,5 +294,6 @@ export async function showStatus(): Promise<void> {
|
|||||||
|
|
||||||
log.info('');
|
log.info('');
|
||||||
log.info(` To enable: lettabot skills enable <name> (or run: lettabot skills)`);
|
log.info(` To enable: lettabot skills enable <name> (or run: lettabot skills)`);
|
||||||
|
log.info(` To disable: lettabot skills disable <name>`);
|
||||||
log.info(` Skills dir: ${WORKING_SKILLS_DIR}`);
|
log.info(` Skills dir: ${WORKING_SKILLS_DIR}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { defineConfig } from 'vitest/config';
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
test: {
|
test: {
|
||||||
exclude: ['dist/**', 'node_modules/**'],
|
exclude: ['dist/**', 'node_modules/**', '.git/**'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user