diff --git a/.changeset/fix-skill-user-home-dir.md b/.changeset/fix-skill-user-home-dir.md new file mode 100644 index 000000000..80f073191 --- /dev/null +++ b/.changeset/fix-skill-user-home-dir.md @@ -0,0 +1,6 @@ +--- +"@moonshot-ai/agent-core": patch +"@moonshot-ai/kimi-code": patch +--- + +Fix user skills in ~/.agents/ not being loaded. diff --git a/packages/agent-core/src/rpc/core-impl.ts b/packages/agent-core/src/rpc/core-impl.ts index c25a1c759..e79d11a4e 100644 --- a/packages/agent-core/src/rpc/core-impl.ts +++ b/packages/agent-core/src/rpc/core-impl.ts @@ -114,9 +114,8 @@ export class KimiCore implements PromisableMethods { protected readonly rpcClient: CoreRPCClient, options: KimiCoreOptions = {}, ) { - const explicitHomeDir = options.homeDir ?? process.env['KIMI_CODE_HOME']; this.homeDir = resolveKimiHome(options.homeDir); - this.userHomeDir = explicitHomeDir ?? homedir(); + this.userHomeDir = homedir(); this.configPath = resolveConfigPath({ homeDir: this.homeDir, configPath: options.configPath, diff --git a/packages/agent-core/test/harness/skill-session.test.ts b/packages/agent-core/test/harness/skill-session.test.ts index 8cb0c1612..6c20abd75 100644 --- a/packages/agent-core/test/harness/skill-session.test.ts +++ b/packages/agent-core/test/harness/skill-session.test.ts @@ -100,7 +100,7 @@ describe('HarnessAPI session skills', () => { expect(JSON.stringify(skills)).not.toContain('Your tool list contains one synthetic tool'); }); - it('uses the explicit core home as user skill home instead of the process home', async () => { + it('resolves user skills from the OS home directory, not from the kimi home', async () => { const processHome = join(tmp, 'process-home'); vi.stubEnv('HOME', processHome); await writeUserSkill(processHome, 'real-home-only', 'Real home skill'); @@ -110,11 +110,11 @@ describe('HarnessAPI session skills', () => { const names = new Set((await rpc.listSkills({ sessionId: created.id })).map((skill) => skill.name)); - expect(names.has('sandbox-only')).toBe(true); - expect(names.has('real-home-only')).toBe(false); + expect(names.has('real-home-only')).toBe(true); + expect(names.has('sandbox-only')).toBe(false); }); - it('uses KIMI_CODE_HOME as user skill home when core home comes from env', async () => { + it('resolves user skills from the OS home directory even when KIMI_CODE_HOME is set', async () => { const processHome = join(tmp, 'env-process-home'); vi.stubEnv('HOME', processHome); vi.stubEnv('KIMI_CODE_HOME', homeDir); @@ -125,8 +125,8 @@ describe('HarnessAPI session skills', () => { const names = new Set((await rpc.listSkills({ sessionId: created.id })).map((skill) => skill.name)); - expect(names.has('env-sandbox-only')).toBe(true); - expect(names.has('env-real-home-only')).toBe(false); + expect(names.has('env-real-home-only')).toBe(true); + expect(names.has('env-sandbox-only')).toBe(false); }); it('activates an inline skill through core and records display origin metadata', async () => { diff --git a/packages/node-sdk/test/session-skills.test.ts b/packages/node-sdk/test/session-skills.test.ts index 5be7bb2ec..6f785bb40 100644 --- a/packages/node-sdk/test/session-skills.test.ts +++ b/packages/node-sdk/test/session-skills.test.ts @@ -192,7 +192,7 @@ describe('Session skills', () => { } }); - it('uses KIMI_CODE_HOME as the user skill home through the SDK harness', async () => { + it('resolves user skills from the OS home directory, independently of KIMI_CODE_HOME', async () => { const homeDir = await makeTempDir(tempDirs, 'kimi-sdk-skills-home-'); const processHome = await makeTempDir(tempDirs, 'kimi-sdk-skills-process-home-'); const workDir = await makeTempDir(tempDirs, 'kimi-sdk-skills-work-'); @@ -206,8 +206,8 @@ describe('Session skills', () => { const session = await harness.createSession({ id: 'ses_sdk_skill_env_home', workDir }); const names = new Set((await session.listSkills()).map((skill) => skill.name)); - expect(names.has('sdk-sandbox-only')).toBe(true); - expect(names.has('sdk-real-home-only')).toBe(false); + expect(names.has('sdk-real-home-only')).toBe(true); + expect(names.has('sdk-sandbox-only')).toBe(false); } finally { await harness.close(); }