From 0e413ab5653bc96ac40842ee4772719fa19ca3f9 Mon Sep 17 00:00:00 2001 From: Larsen Close Date: Tue, 3 Feb 2026 16:45:08 -0700 Subject: [PATCH] fix: resolve init warnings for research skill and native binary detection - Add 'research' to availableSkills in validation (was in default preset but missing from validator) - Update native binary detection to return available=true (modern Claude Code has built-in Task tool parallel support) - Add regression tests for both fixes Co-Authored-By: Claude Opus 4.5 --- lib/parallel-execution.js | 6 ++++-- lib/presets.js | 2 +- test/unit/parallel-execution.test.js | 14 ++++++++------ test/unit/presets.test.js | 28 ++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/lib/parallel-execution.js b/lib/parallel-execution.js index 69c443c..c226b65 100644 --- a/lib/parallel-execution.js +++ b/lib/parallel-execution.js @@ -48,7 +48,8 @@ export function detectTeammateTool() { } if (isNativeBinary(claudePath)) { - return { available: false, reason: 'Native binary detected - patching not supported', isNative: true }; + // Native Claude Code binaries have built-in parallel execution via Task tool + return { available: true, method: 'native', isNative: true }; } const cliContent = fs.readFileSync(claudePath, 'utf8'); @@ -151,7 +152,8 @@ export function enableTeammateTool() { } if (isNativeBinary(claudePath)) { - return { success: false, error: 'Native binary detected - patching not supported. TeammateTool patching only works with npm-installed Claude Code.' }; + // Native binaries have built-in support, no patching needed + return { success: true, message: 'Native binary has built-in parallel execution support', alreadyEnabled: true }; } // Backup original diff --git a/lib/presets.js b/lib/presets.js index b5a32a1..2cc333b 100644 --- a/lib/presets.js +++ b/lib/presets.js @@ -212,7 +212,7 @@ export function listPresets() { export function validateConfiguration(config) { const errors = []; const availableAgents = ['orchestrator', 'architect', 'backend', 'frontend', 'tester', 'reviewer', 'fixer', 'product-analyzer']; - const availableSkills = ['product-tracking', 'validation', 'testing', 'conversation', 'product-planning', 'deployment']; + const availableSkills = ['product-tracking', 'validation', 'testing', 'conversation', 'product-planning', 'deployment', 'research']; const availableHooks = Object.keys(hookConfigurations); // Always require orchestrator diff --git a/test/unit/parallel-execution.test.js b/test/unit/parallel-execution.test.js index 7838779..e823d98 100644 --- a/test/unit/parallel-execution.test.js +++ b/test/unit/parallel-execution.test.js @@ -39,7 +39,8 @@ describe('Parallel Execution', () => { expect(result.reason).toContain('binary not found'); }); - it('should detect native Mach-O binary and skip patching', () => { + it('should detect native Mach-O binary as having built-in parallel support', () => { + // Native Claude Code binaries have built-in Task tool parallel execution execSync.mockImplementation((cmd) => { if (cmd.includes('npm root -g')) { return '/usr/local/lib/node_modules\n'; @@ -64,8 +65,8 @@ describe('Parallel Execution', () => { const result = detectTeammateTool(); - expect(result.available).toBe(false); - expect(result.reason).toContain('Native binary'); + expect(result.available).toBe(true); + expect(result.method).toBe('native'); expect(result.isNative).toBe(true); }); @@ -157,7 +158,8 @@ describe('Parallel Execution', () => { }); describe('enableTeammateTool', () => { - it('should reject native Mach-O binary', () => { + it('should report native Mach-O binary as already enabled', () => { + // Native binaries have built-in parallel support, no patching needed execSync.mockImplementation((cmd) => { if (cmd.includes('npm root -g')) { return '/usr/local/lib/node_modules\n'; @@ -182,8 +184,8 @@ describe('Parallel Execution', () => { const result = enableTeammateTool(); - expect(result.success).toBe(false); - expect(result.error).toContain('Native binary'); + expect(result.success).toBe(true); + expect(result.alreadyEnabled).toBe(true); }); it('should create backup before patching', () => { diff --git a/test/unit/presets.test.js b/test/unit/presets.test.js index 34c96d6..40c3d7e 100644 --- a/test/unit/presets.test.js +++ b/test/unit/presets.test.js @@ -315,6 +315,34 @@ describe('validateConfiguration', () => { const result = validateConfiguration(config); expect(result.valid).toBe(true); }); + + it('should accept research skill (regression test)', () => { + // Regression test: research skill was in default preset but missing from availableSkills + const config = { + agents: ['orchestrator'], + skills: ['research'], + hooks: [], + gates: [] + }; + + const result = validateConfiguration(config); + expect(result.valid).toBe(true); + expect(result.errors).not.toContain(expect.stringContaining('Invalid skills')); + }); + + it('default preset skills should all be valid', () => { + // Ensure all skills in the default preset pass validation + const config = { + agents: presets.default.agents, + skills: presets.default.skills, + hooks: presets.default.hooks, + gates: presets.default.gates + }; + + const result = validateConfiguration(config); + const skillErrors = result.errors.filter(e => e.includes('Invalid skills')); + expect(skillErrors).toHaveLength(0); + }); }); describe('generateHooksConfig', () => {