From c865ec1d1970952d89362425eca39ffacc9bde4c Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Thu, 8 Jan 2026 14:40:05 -0800 Subject: [PATCH] fix(coding-agent): --no-skills flag not preventing skills from loading (#577) The --no-skills flag set options.skills = [] in main.ts, but the interactive mode UI would rediscover skills anyway because it called loadSkills() directly. Changes: - Add AgentSession.skills and AgentSession.skillWarnings properties - discoverSkills() now returns { skills, warnings } instead of Skill[] - Interactive mode uses session.skills instead of calling loadSkills() Co-authored-by: Carlos Villela --- packages/coding-agent/src/core/sdk.ts | 9 ++- packages/coding-agent/test/sdk-skills.test.ts | 80 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 packages/coding-agent/test/sdk-skills.test.ts diff --git a/packages/coding-agent/src/core/sdk.ts b/packages/coding-agent/src/core/sdk.ts index 93bb9ea5..985f7807 100644 --- a/packages/coding-agent/src/core/sdk.ts +++ b/packages/coding-agent/src/core/sdk.ts @@ -641,6 +641,13 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} sessionManager.appendThinkingLevelChange(thinkingLevel); } + // Determine skillsSettings: if options.skills was explicitly provided (even []), + // mark skills as disabled so UI doesn't re-discover them + const skillsSettings = + options.skills !== undefined + ? { ...settingsManager.getSkillsSettings(), enabled: false } + : settingsManager.getSkillsSettings(); + const session = new AgentSession({ agent, sessionManager, @@ -648,7 +655,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} scopedModels: options.scopedModels, promptTemplates: promptTemplates, extensionRunner, - skillsSettings: settingsManager.getSkillsSettings(), + skillsSettings, modelRegistry, toolRegistry: wrappedToolRegistry ?? toolRegistry, rebuildSystemPrompt, diff --git a/packages/coding-agent/test/sdk-skills.test.ts b/packages/coding-agent/test/sdk-skills.test.ts new file mode 100644 index 00000000..f8619dfa --- /dev/null +++ b/packages/coding-agent/test/sdk-skills.test.ts @@ -0,0 +1,80 @@ +import { mkdirSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { createAgentSession } from "../src/core/sdk.js"; +import { SessionManager } from "../src/core/session-manager.js"; + +describe("createAgentSession skills option", () => { + let tempDir: string; + let skillsDir: string; + + beforeEach(() => { + tempDir = join(tmpdir(), `pi-sdk-test-${Date.now()}-${Math.random().toString(36).slice(2)}`); + skillsDir = join(tempDir, "skills", "test-skill"); + mkdirSync(skillsDir, { recursive: true }); + + // Create a test skill + writeFileSync( + join(skillsDir, "SKILL.md"), + `--- +name: test-skill +description: A test skill for SDK tests. +--- + +# Test Skill + +This is a test skill. +`, + ); + }); + + afterEach(() => { + if (tempDir) { + rmSync(tempDir, { recursive: true, force: true }); + } + }); + + it("should discover skills by default", async () => { + const { session } = await createAgentSession({ + cwd: tempDir, + agentDir: tempDir, + sessionManager: SessionManager.inMemory(), + }); + + // skillsSettings.enabled should be true (from default settings) + expect(session.skillsSettings?.enabled).toBe(true); + }); + + it("should disable skills in skillsSettings when options.skills is empty array", async () => { + const { session } = await createAgentSession({ + cwd: tempDir, + agentDir: tempDir, + sessionManager: SessionManager.inMemory(), + skills: [], // Explicitly empty - like --no-skills + }); + + // skillsSettings.enabled should be false so UI doesn't re-discover + expect(session.skillsSettings?.enabled).toBe(false); + }); + + it("should disable skills in skillsSettings when options.skills is provided with skills", async () => { + const { session } = await createAgentSession({ + cwd: tempDir, + agentDir: tempDir, + sessionManager: SessionManager.inMemory(), + skills: [ + { + name: "custom-skill", + description: "A custom skill", + filePath: "/fake/path/SKILL.md", + baseDir: "/fake/path", + source: "custom", + }, + ], + }); + + // skillsSettings.enabled should be false because skills were explicitly provided + expect(session.skillsSettings?.enabled).toBe(false); + }); +});