From a827e8bfa60ba6f9bca1ff9c8bb7d820e8ff9a50 Mon Sep 17 00:00:00 2001 From: tanzhenxin Date: Thu, 2 Apr 2026 10:24:49 +0800 Subject: [PATCH] fix: hide skills with cron allowedTools when cron is disabled When cron functionality is disabled, skills that require cron tools (like the 'loop' skill) should be hidden from the available commands to avoid confusing users with non-functional commands. Co-authored-by: Qwen-Coder --- .../src/services/BundledSkillLoader.test.ts | 22 +++++++++++++++++++ .../cli/src/services/BundledSkillLoader.ts | 18 ++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/services/BundledSkillLoader.test.ts b/packages/cli/src/services/BundledSkillLoader.test.ts index a3c687a27..e7cc268e7 100644 --- a/packages/cli/src/services/BundledSkillLoader.test.ts +++ b/packages/cli/src/services/BundledSkillLoader.test.ts @@ -33,6 +33,7 @@ describe('BundledSkillLoader', () => { }; mockConfig = { getSkillManager: vi.fn().mockReturnValue(mockSkillManager), + isCronEnabled: vi.fn().mockReturnValue(false), } as unknown as Config; }); @@ -125,4 +126,25 @@ describe('BundledSkillLoader', () => { expect(commands).toHaveLength(2); expect(commands.map((c) => c.name)).toEqual(['review', 'deploy']); }); + + it('should hide skills with cron allowedTools when cron is disabled', async () => { + const skills = [ + makeSkill({ name: 'review', description: 'Review code' }), + makeSkill({ + name: 'loop', + description: 'Loop command', + allowedTools: ['cron_create', 'cron_list', 'cron_delete'], + }), + ]; + mockSkillManager.listSkills.mockResolvedValue(skills); + (mockConfig.isCronEnabled as ReturnType).mockReturnValue( + false, + ); + + const loader = new BundledSkillLoader(mockConfig); + const commands = await loader.loadCommands(signal); + + expect(commands).toHaveLength(1); + expect(commands[0].name).toBe('review'); + }); }); diff --git a/packages/cli/src/services/BundledSkillLoader.ts b/packages/cli/src/services/BundledSkillLoader.ts index 609ddf90e..b0fa68467 100644 --- a/packages/cli/src/services/BundledSkillLoader.ts +++ b/packages/cli/src/services/BundledSkillLoader.ts @@ -33,7 +33,23 @@ export class BundledSkillLoader implements ICommandLoader { } try { - const skills = await skillManager.listSkills({ level: 'bundled' }); + const allSkills = await skillManager.listSkills({ level: 'bundled' }); + + // Hide skills whose allowedTools require cron when cron is disabled + const cronEnabled = this.config?.isCronEnabled() ?? false; + const skills = allSkills.filter((skill) => { + if ( + !cronEnabled && + skill.allowedTools?.some((t) => t.startsWith('cron_')) + ) { + debugLogger.debug( + `Hiding skill "${skill.name}" because cron is not enabled`, + ); + return false; + } + return true; + }); + debugLogger.debug( `Loaded ${skills.length} bundled skill(s) as slash commands`, );