import { mkdirSync, symlinkSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import { beforeEach, describe, expect, mock, test } from "bun:test"; const TEST_DIR = process.env.VELLUM_WORKSPACE_DIR!; // Build a mock that covers every export from platform.ts — any function not // explicitly mapped returns a no-op stub so that transitive imports don't fail. mock.module("../util/logger.js", () => ({ getLogger: () => new Proxy({} as Record, { get: () => () => {}, }), truncateForLog: (s: unknown) => String(s), })); // Mock autoInstallFromCatalog — default returns false (not found in catalog). // Tests can override via `mockAutoInstall.mockImplementation(...)`. const mockAutoInstall = mock((_skillId: string) => Promise.resolve(false)); mock.module("../skills/catalog-install.js", () => ({ autoInstallFromCatalog: (skillId: string) => mockAutoInstall(skillId), getRepoSkillsDir: () => undefined, resolveCatalog: (_skillId?: string) => Promise.resolve([]), })); const { skillLoadTool } = await import("../tools/skills/load.js"); function writeSkill( skillId: string, name: string, description: string, body: string, ): void { const skillDir = join(TEST_DIR, "skills", skillId); mkdirSync(skillDir, { recursive: true }); writeFileSync( join(skillDir, "SKILL.md"), `---\nname: "${name}"\ndescription: "${description}"\n---\n\n${body}\n`, ); } function writeSkillWithIncludes( skillId: string, name: string, description: string, body: string, includes: string[], ): void { const skillDir = join(TEST_DIR, "skills", skillId); mkdirSync(skillDir, { recursive: true }); writeFileSync( join(skillDir, "SKILL.md"), `---\nname: "${name}"\ndescription: "${description}"\nmetadata: ${JSON.stringify( { vellum: { includes } }, )}\n---\n\n${body}\n`, ); } function writeToolsJson( skillId: string, tools: Array<{ name: string; description: string; category?: string; risk?: string; input_schema?: Record; executor?: string; execution_target?: string; }>, ): void { const skillDir = join(TEST_DIR, "skills", skillId); mkdirSync(skillDir, { recursive: true }); const manifest = { version: 1, tools: tools.map((t) => ({ name: t.name, description: t.description, category: t.category ?? "general", risk: t.risk ?? "low", input_schema: t.input_schema ?? { type: "object", properties: {} }, executor: t.executor ?? "scripts/run.sh", execution_target: t.execution_target ?? "host", })), }; writeFileSync(join(skillDir, "TOOLS.json"), JSON.stringify(manifest)); } async function executeSkillLoad( input: Record, ): Promise<{ content: string; isError: boolean }> { const tool = skillLoadTool; const result = await tool.execute(input, { workingDir: "/tmp", conversationId: "conversation-1", trustClass: "guardian", }); return { content: result.content, isError: result.isError }; } async function executeSkillLoadCleanup( input: Record, ): Promise<{ content: string; isError: boolean }> { const tool = skillLoadTool; const result = await tool.execute(input, { workingDir: "/tmp", conversationId: "conversation-1", trustClass: "guardian", diskPressureCleanupModeActive: true, }); return { content: result.content, isError: result.isError }; } describe("skill_load tool", () => { beforeEach(() => { mkdirSync(join(TEST_DIR, "skills"), { recursive: true }); mockAutoInstall.mockReset(); mockAutoInstall.mockImplementation((_skillId: string) => Promise.resolve(false), ); }); test("loads a skill by exact id", async () => { writeSkill( "release-checklist", "Release Checklist", "Runs release checks", "1. Run tests", ); const result = await executeSkillLoad({ skill: "release-checklist" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Release Checklist"); expect(result.content).toContain("ID: release-checklist"); expect(result.content).toContain("1. Run tests"); expect(result.content).not.toContain('name: "Release Checklist"'); // Marker must include a version attribute with the v1: format const markerMatch = result.content.match( //, ); expect(markerMatch).not.toBeNull(); }); test("loads a skill by exact name (case-insensitive)", async () => { writeSkill( "oncall", "Oncall Runbook", "Handles incidents", "Page primary responder", ); const result = await executeSkillLoad({ skill: "oncall runbook" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Oncall Runbook"); expect(result.content).toContain("Page primary responder"); const markerMatch = result.content.match( //, ); expect(markerMatch).not.toBeNull(); }); test("loads a skill by unique id prefix", async () => { writeSkill( "incident-response", "Incident Response", "Triage incidents", "Run triage checklist", ); writeSkill( "release-checklist", "Release Checklist", "Release flow", "Run release checklist", ); const result = await executeSkillLoad({ skill: "incident" }); expect(result.isError).toBe(false); expect(result.content).toContain("ID: incident-response"); const markerMatch = result.content.match( //, ); expect(markerMatch).not.toBeNull(); }); test("returns an error when name resolution is ambiguous", async () => { writeSkill("skill-a", "Shared Name", "First", "Body A"); writeSkill("skill-b", "Shared Name", "Second", "Body B"); const result = await executeSkillLoad({ skill: "Shared Name" }); expect(result.isError).toBe(true); expect(result.content).toContain("Ambiguous skill name"); expect(result.content).not.toContain(" { writeSkill( "versioned", "Versioned Skill", "Test versioning", "Original body", ); const result1 = await executeSkillLoad({ skill: "versioned" }); const match1 = result1.content.match( //, ); expect(match1).not.toBeNull(); const hash1 = match1![1]; // Modify the skill body writeSkill( "versioned", "Versioned Skill", "Test versioning", "Updated body", ); const result2 = await executeSkillLoad({ skill: "versioned" }); const match2 = result2.content.match( //, ); expect(match2).not.toBeNull(); const hash2 = match2![1]; expect(hash1).not.toBe(hash2); }); test("returns an error when skill is missing", async () => { writeSkill("existing", "Existing Skill", "Exists", "Body"); const result = await executeSkillLoad({ skill: "does-not-exist" }); expect(result.isError).toBe(true); expect(result.content).toContain("No skill matched"); expect(result.content).not.toContain(" { writeSkill("existing", "Existing Skill", "Exists", "Existing body"); writeSkill( "geo-article-writer", "Geo Article Writer", "Writes local geo articles", "Draft the article.", ); writeFileSync(join(TEST_DIR, "skills", "SKILLS.md"), "- existing\n"); const result = await executeSkillLoad({ skill: "geo-article-writer" }); expect(result.isError).toBe(false); expect(result.content).toContain("ID: geo-article-writer"); const markers = result.content.match(//, ); const missing = await executeSkillLoad({ skill: "does-not-exist" }); expect(missing.isError).toBe(true); expect(missing.content).toContain("No skill matched"); expect(missing.content).not.toContain(" { writeSkill( "standalone", "Standalone Skill", "A skill with no children", "Do the thing", ); const result = await executeSkillLoad({ skill: "standalone" }); expect(result.isError).toBe(false); expect(result.content).toContain("Included Skills (immediate): none"); }); test("successful skill_load emits exactly one loaded_skill marker", async () => { writeSkill( "single-marker", "Single Marker Skill", "Should have one marker", "Step 1", ); const result = await executeSkillLoad({ skill: "single-marker" }); expect(result.isError).toBe(false); const markers = result.content.match(/ { writeSkillWithIncludes("parent", "Parent", "Has missing child", "Body", [ "missing-child", ]); const result = await executeSkillLoad({ skill: "parent" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Parent"); expect(result.content).toContain("Suggested Included Skills (not loaded):"); expect(result.content).toContain("missing-child"); expect(result.content).toContain(' { writeSkillWithIncludes("skill-a", "Skill A", "Cycles", "Body A", [ "skill-b", ]); writeSkillWithIncludes("skill-b", "Skill B", "Cycles", "Body B", [ "skill-a", ]); const result = await executeSkillLoad({ skill: "skill-a" }); expect(result.isError).toBe(true); expect(result.content).toContain("circular"); expect(result.content).not.toContain(" { writeSkillWithIncludes( "valid-parent", "Valid Parent", "Has valid child", "Body", ["valid-child"], ); writeSkill("valid-child", "Valid Child", "A child", "Child body"); const result = await executeSkillLoad({ skill: "valid-parent" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Valid Parent"); expect(result.content).toContain(" { const skillDir = join(TEST_DIR, "skills", "marker-missing"); mkdirSync(skillDir, { recursive: true }); writeFileSync( join(skillDir, "SKILL.md"), '---\nname: "Marker Missing"\ndescription: "test"\nmetadata: {"vellum":{"includes":["nonexistent"]}}\n---\n\nBody.\n', ); const result = await executeSkillLoad({ skill: "marker-missing" }); expect(result.isError).toBe(false); expect(result.content).toContain("Suggested Included Skills (not loaded):"); expect(result.content).toContain("nonexistent"); const markers = result.content.match(/ { const dirA = join(TEST_DIR, "skills", "cycle-a"); const dirB = join(TEST_DIR, "skills", "cycle-b"); mkdirSync(dirA, { recursive: true }); mkdirSync(dirB, { recursive: true }); writeFileSync( join(dirA, "SKILL.md"), '---\nname: "Cycle A"\ndescription: "test"\nmetadata: {"vellum":{"includes":["cycle-b"]}}\n---\n\nBody A.\n', ); writeFileSync( join(dirB, "SKILL.md"), '---\nname: "Cycle B"\ndescription: "test"\nmetadata: {"vellum":{"includes":["cycle-a"]}}\n---\n\nBody B.\n', ); const result = await executeSkillLoad({ skill: "cycle-a" }); expect(result.isError).toBe(true); expect(result.content).not.toContain(" { writeSkill("no-includes", "No Includes", "Plain skill", "Body"); const result = await executeSkillLoad({ skill: "no-includes" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: No Includes"); }); test("bundled app-builder loads without includes", async () => { const result = await executeSkillLoad({ skill: "app-builder" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: App Builder"); expect(result.content).toContain("Included Skills (immediate): none"); expect(result.content).toContain(' { const result = await executeSkillLoad({ skill: "phone-calls" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Phone Calls"); expect(result.content).toContain("Suggested Included Skills (not loaded):"); expect(result.content).toContain("twilio-setup"); expect(result.content).toContain(' { writeSkill("child-skill", "Child Skill", "A child skill", "Child body"); const parentDir = join(TEST_DIR, "skills", "parent-with-children"); mkdirSync(parentDir, { recursive: true }); writeFileSync( join(parentDir, "SKILL.md"), '---\nname: "Parent"\ndescription: "Has children"\nmetadata: {"vellum":{"includes":["child-skill"]}}\n---\n\nParent body.\n', ); const result = await executeSkillLoad({ skill: "parent-with-children" }); expect(result.isError).toBe(false); expect(result.content).toContain("Included Skills (immediate):"); expect(result.content).toContain("child-skill: Child Skill"); expect(result.content).toContain(" { writeSkill("solo-skill", "Solo", "No children", "Body"); const result = await executeSkillLoad({ skill: "solo-skill" }); expect(result.isError).toBe(false); expect(result.content).toContain("Included Skills (immediate): none"); }); test("e2e: load parent with includes shows child metadata and emits markers for parent and included children", async () => { // Set up a parent + child fixture using the helpers writeSkill( "e2e-child", "E2E Child", "Child for e2e test", "Child instructions.", ); writeSkillWithIncludes( "e2e-parent", "E2E Parent", "Parent with includes", "Parent instructions.", ["e2e-child"], ); // Load the parent const result = await executeSkillLoad({ skill: "e2e-parent" }); // Should succeed expect(result.isError).toBe(false); // Output should contain the immediate children metadata section with the child expect(result.content).toContain("Included Skills (immediate):"); expect(result.content).toContain("e2e-child: E2E Child"); // Should emit markers for both parent and included child so child tools get projected const markers = result.content.match(//, ); expect(result.content).toMatch( //, ); }); test("parent skill lists only immediate children, not transitive grandchildren", async () => { // 3-level hierarchy: grandparent -> child -> grandchild writeSkill( "grandchild", "Grandchild Skill", "Leaf skill", "Grandchild body", ); writeSkillWithIncludes("child", "Child Skill", "Mid-level", "Child body", [ "grandchild", ]); writeSkillWithIncludes( "grandparent", "Grandparent Skill", "Top-level", "Grandparent body", ["child"], ); const result = await executeSkillLoad({ skill: "grandparent" }); expect(result.isError).toBe(false); // The immediate children section must list the direct child expect(result.content).toContain("Included Skills (immediate):"); expect(result.content).toContain("child"); // Extract only the "Included Skills (immediate)" section to verify // grandchild is NOT listed there (it's a transitive dependency) const immediateSection = result.content.match( /Included Skills \(immediate\):[\s\S]*?(?=\n\n|/, ); }); test("succeeds with diamond dependency and emits markers for root and immediate children", async () => { // Diamond: root includes A and B, both A and B include shared-leaf writeSkill( "shared-leaf", "Shared Leaf", "Shared dependency", "Shared body", ); writeSkillWithIncludes( "branch-a", "Branch A", "First branch", "Branch A body", ["shared-leaf"], ); writeSkillWithIncludes( "branch-b", "Branch B", "Second branch", "Branch B body", ["shared-leaf"], ); writeSkillWithIncludes( "diamond-root", "Diamond Root", "Top of diamond", "Root body", ["branch-a", "branch-b"], ); const result = await executeSkillLoad({ skill: "diamond-root" }); expect(result.isError).toBe(false); // Immediate children section should list only branch-a and branch-b expect(result.content).toContain("Included Skills (immediate):"); expect(result.content).toContain("branch-a: Branch A"); expect(result.content).toContain("branch-b: Branch B"); // shared-leaf is a transitive dependency — must NOT appear in immediate section const immediateSection = result.content.match( /Included Skills \(immediate\):[\s\S]*?(?=\n\n|/, ); expect(result.content).toMatch( //, ); expect(result.content).toMatch( //, ); }); test("returns error when skill includes itself (self-cycle)", async () => { writeSkillWithIncludes( "self-ref", "Self Referencing", "Includes itself", "Body", ["self-ref"], ); const result = await executeSkillLoad({ skill: "self-ref" }); expect(result.isError).toBe(true); expect(result.content).toContain("circular"); expect(result.content).not.toContain(" { // Create a skill with a references/ subdirectory const skillDir = join(TEST_DIR, "skills", "with-refs"); mkdirSync(skillDir, { recursive: true }); mkdirSync(join(skillDir, "references"), { recursive: true }); writeFileSync( join(skillDir, "SKILL.md"), '---\nname: "With Refs"\ndescription: "Has references"\n---\n\nMain body.\n', ); writeFileSync( join(skillDir, "references", "GUIDE.md"), "# Guide\n\nDetailed guide content.", ); writeFileSync( join(skillDir, "references", "TROUBLESHOOTING.md"), "# Troubleshooting\n\nFix things here.", ); const result = await executeSkillLoad({ skill: "with-refs" }); expect(result.isError).toBe(false); expect(result.content).toContain("Main body."); // Should contain reference listing header expect(result.content).toContain("## Reference Files"); // Should list full paths to reference files expect(result.content).toContain(`${skillDir}/references/GUIDE.md`); expect(result.content).toContain( `${skillDir}/references/TROUBLESHOOTING.md`, ); // Should NOT contain the full file contents expect(result.content).not.toContain("Detailed guide content."); expect(result.content).not.toContain("Fix things here."); // References must be listed in alphabetical order (GUIDE before TROUBLESHOOTING) const guideIdx = result.content.indexOf("GUIDE.md"); const troubleshootIdx = result.content.indexOf("TROUBLESHOOTING.md"); expect(guideIdx).toBeLessThan(troubleshootIdx); }); test("skill without references/ directory loads normally", async () => { writeSkill("no-refs", "No Refs", "No references dir", "Just body."); const result = await executeSkillLoad({ skill: "no-refs" }); expect(result.isError).toBe(false); expect(result.content).toContain("Just body."); expect(result.content).not.toContain("## Reference Files"); }); test("references/ directory skips symlinked markdown files that escape the skill directory", async () => { if (process.platform === "win32") { // Symlink creation is not consistently available in Windows test environments. return; } const skillDir = join(TEST_DIR, "skills", "refs-symlink"); mkdirSync(skillDir, { recursive: true }); mkdirSync(join(skillDir, "references"), { recursive: true }); writeFileSync( join(skillDir, "SKILL.md"), '---\nname: "Refs Symlink"\ndescription: "Skips symlinks"\n---\n\nBody.\n', ); const outsideSecretPath = join(TEST_DIR, "outside-secret.md"); writeFileSync(outsideSecretPath, "TOP_SECRET_DO_NOT_LOAD"); symlinkSync(outsideSecretPath, join(skillDir, "references", "secret.md")); const result = await executeSkillLoad({ skill: "refs-symlink" }); expect(result.isError).toBe(false); expect(result.content).toContain("Body."); expect(result.content).not.toContain("secret.md"); expect(result.content).not.toContain("TOP_SECRET_DO_NOT_LOAD"); }); test("references/ directory ignores non-markdown files", async () => { const skillDir = join(TEST_DIR, "skills", "refs-filter"); mkdirSync(skillDir, { recursive: true }); mkdirSync(join(skillDir, "references"), { recursive: true }); writeFileSync( join(skillDir, "SKILL.md"), '---\nname: "Refs Filter"\ndescription: "Filters non-md"\n---\n\nBody.\n', ); writeFileSync( join(skillDir, "references", "GUIDE.md"), "# Guide\n\nGuide content.", ); writeFileSync( join(skillDir, "references", "data.json"), '{"key": "value"}', ); const result = await executeSkillLoad({ skill: "refs-filter" }); expect(result.isError).toBe(false); expect(result.content).toContain("## Reference Files"); expect(result.content).toContain("GUIDE.md"); expect(result.content).not.toContain("data.json"); expect(result.content).not.toContain('"key"'); }); test('skill with empty includes array loads successfully as "none"', async () => { // Write a skill with `includes: []` directly in frontmatter. // The parser normalizes this to undefined, so it should behave identically // to a skill with no includes field. const skillDir = join(TEST_DIR, "skills", "empty-includes"); mkdirSync(skillDir, { recursive: true }); writeFileSync( join(skillDir, "SKILL.md"), '---\nname: "Empty Includes"\ndescription: "Has empty array"\nmetadata: {"vellum":{"includes":[]}}\n---\n\nBody.\n', ); const result = await executeSkillLoad({ skill: "empty-includes" }); expect(result.isError).toBe(false); expect(result.content).toContain("Included Skills (immediate): none"); expect(result.content).toMatch( //, ); }); test("skill with TOOLS.json includes tool schemas section in output", async () => { writeSkill( "skill-with-tools", "Skill With Tools", "Has tools", "Main body.", ); writeToolsJson("skill-with-tools", [ { name: "deploy_app", description: "Deploy the application to production", input_schema: { type: "object", properties: { environment: { type: "string", description: "Target environment", }, force: { type: "boolean", description: "Force deploy even if checks fail", }, }, required: ["environment"], }, }, { name: "rollback_app", description: "Rollback to previous version", input_schema: { type: "object", properties: { version: { type: "string", description: "Version to rollback to", }, }, required: ["version"], }, }, ]); const result = await executeSkillLoad({ skill: "skill-with-tools" }); expect(result.isError).toBe(false); // Should contain the Available Tools section header expect(result.content).toContain("## Available Tools"); // Should instruct the LLM to use skill_execute expect(result.content).toContain( "Use `skill_execute` to call these tools.", ); // Should contain tool names as headings expect(result.content).toContain("### deploy_app"); expect(result.content).toContain("### rollback_app"); // Should contain tool descriptions expect(result.content).toContain("Deploy the application to production"); expect(result.content).toContain("Rollback to previous version"); // Should list parameters with types and required/optional markers expect(result.content).toContain( "- environment (string, required): Target environment", ); expect(result.content).toContain( "- force (boolean, optional): Force deploy even if checks fail", ); expect(result.content).toContain( "- version (string, required): Version to rollback to", ); }); test("skill without TOOLS.json does not include tool schemas section", async () => { writeSkill("no-tools", "No Tools", "No tools manifest", "Body."); const result = await executeSkillLoad({ skill: "no-tools" }); expect(result.isError).toBe(false); expect(result.content).not.toContain("## Available Tools"); expect(result.content).not.toContain("skill_execute"); }); test("included child skill with TOOLS.json has its tool schemas in output", async () => { writeSkillWithIncludes( "parent-tools", "Parent Tools", "Parent with tooled child", "Parent body.", ["child-tools"], ); writeSkill("child-tools", "Child Tools", "Child with tools", "Child body."); writeToolsJson("child-tools", [ { name: "child_action", description: "A child tool action", input_schema: { type: "object", properties: { target: { type: "string", description: "Action target", }, }, required: ["target"], }, }, ]); const result = await executeSkillLoad({ skill: "parent-tools" }); expect(result.isError).toBe(false); // The child skill's tool schemas should appear (#### level under ### Tools from …) expect(result.content).toContain("#### child_action"); expect(result.content).toContain("A child tool action"); expect(result.content).toContain( "- target (string, required): Action target", ); expect(result.content).toContain( "Use `skill_execute` to call these tools.", ); }); test("auto-installs missing includes from catalog", async () => { // Parent includes "dep-a" which is not initially in the catalog writeSkillWithIncludes( "auto-parent", "Auto Parent", "Has auto-installable dep", "Parent body", ["dep-a"], ); // Mock autoInstallFromCatalog to succeed and write the skill to disk mockAutoInstall.mockImplementation((skillId: string) => { if (skillId === "dep-a") { writeSkill("dep-a", "Dep A", "A dependency", "Dep A body"); return Promise.resolve(true); } return Promise.resolve(false); }); const result = await executeSkillLoad({ skill: "auto-parent" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Auto Parent"); expect(result.content).toContain(" { // Skill A includes B, B includes C. Neither B nor C in initial catalog. writeSkillWithIncludes("trans-a", "Trans A", "Top level", "Body A", [ "trans-b", ]); let round = 0; mockAutoInstall.mockImplementation((skillId: string) => { if (skillId === "trans-b" && round === 0) { // First round: install B (which includes C) writeSkillWithIncludes("trans-b", "Trans B", "Mid level", "Body B", [ "trans-c", ]); round++; return Promise.resolve(true); } if (skillId === "trans-c") { // Second round: install C writeSkill("trans-c", "Trans C", "Leaf", "Body C"); return Promise.resolve(true); } return Promise.resolve(false); }); const result = await executeSkillLoad({ skill: "trans-a" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Trans A"); expect(result.content).toContain(" { writeSkillWithIncludes( "fail-parent", "Fail Parent", "Has failing dep", "Body", ["dep-x"], ); // autoInstallFromCatalog throws an error mockAutoInstall.mockImplementation((skillId: string) => { if (skillId === "dep-x") { return Promise.reject(new Error("Network error")); } return Promise.resolve(false); }); const result = await executeSkillLoad({ skill: "fail-parent" }); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Fail Parent"); expect(result.content).toContain("Suggested Included Skills (not loaded):"); expect(result.content).toContain("dep-x"); expect(result.content).toContain(' { // Pathological case: each install round reveals a new missing dep writeSkillWithIncludes("loop-root", "Loop Root", "Infinite deps", "Body", [ "loop-dep-0", ]); let installCount = 0; mockAutoInstall.mockImplementation((skillId: string) => { const id = skillId; if (id.startsWith("loop-dep-")) { installCount++; const nextDepId = `loop-dep-${installCount}`; // Install the requested dep, but it includes yet another missing dep writeSkillWithIncludes( id, `Loop Dep ${installCount}`, "Generated dep", "Body", [nextDepId], ); return Promise.resolve(true); } return Promise.resolve(false); }); const result = await executeSkillLoad({ skill: "loop-root" }); expect(result.isError).toBe(false); expect(result.content).toContain("Suggested Included Skills (not loaded):"); expect(installCount).toBeLessThanOrEqual(5); }); // During disk-pressure cleanup mode, skill_load is allowed but must not // produce side effects: no catalog auto-install (workspace writes / bun // install) and no inline command execution. Instructions are still returned. test("does not auto-install a missing catalog skill during cleanup mode", async () => { mockAutoInstall.mockImplementation((skillId: string) => { writeSkill(skillId, "Should Not Install", "nope", "body"); return Promise.resolve(true); }); const result = await executeSkillLoadCleanup({ skill: "absent-skill" }); expect(mockAutoInstall).not.toHaveBeenCalled(); expect(result.isError).toBe(true); }); test("does not auto-install missing includes during cleanup mode", async () => { writeSkillWithIncludes( "cleanup-parent", "Cleanup Parent", "Has a missing include", "Parent body", ["cleanup-dep"], ); mockAutoInstall.mockImplementation((skillId: string) => { writeSkill(skillId, "Cleanup Dep", "should not install", "Dep body"); return Promise.resolve(true); }); const result = await executeSkillLoadCleanup({ skill: "cleanup-parent" }); expect(mockAutoInstall).not.toHaveBeenCalled(); expect(result.isError).toBe(false); expect(result.content).toContain("Skill: Cleanup Parent"); expect(result.content).toContain("Suggested Included Skills (not loaded):"); expect(result.content).toContain("cleanup-dep"); }); test("strips inline command tokens instead of executing them during cleanup mode", async () => { writeSkill( "cleanup-inline", "Cleanup Inline", "Has an inline command", "Before !`echo SENTINEL_OUTPUT` after", ); const result = await executeSkillLoadCleanup({ skill: "cleanup-inline" }); expect(result.isError).toBe(false); expect(result.content).toContain( "[inline command skipped: storage cleanup mode]", ); expect(result.content).not.toContain("SENTINEL_OUTPUT"); expect(result.content).not.toContain("!`echo SENTINEL_OUTPUT`"); expect(result.content).toContain("Before"); expect(result.content).toContain("after"); }); });