diff --git a/src/skills/loading/session.ts b/src/skills/loading/session.ts index 106c6b0f4453..a8e04f49ec61 100644 --- a/src/skills/loading/session.ts +++ b/src/skills/loading/session.ts @@ -7,6 +7,7 @@ import type { ResourceDiagnostic } from "../../agents/sessions/diagnostics.js"; import { createSyntheticSourceInfo, type SourceInfo } from "../../agents/sessions/source-info.js"; import { parseFrontmatter } from "../../agents/utils/frontmatter.js"; import { canonicalizePath } from "../../agents/utils/paths.js"; +import { formatSkillsForPrompt as formatSkillContractForPrompt } from "./skill-contract.js"; /** Max name length per spec */ const MAX_NAME_LENGTH = 64; @@ -343,39 +344,7 @@ function loadSkillFromFile( */ export function formatSkillsForPrompt(skills: Skill[]): string { const visibleSkills = skills.filter((s) => !s.disableModelInvocation); - - if (visibleSkills.length === 0) { - return ""; - } - - const lines = [ - "\n\nThe following skills provide specialized instructions for specific tasks.", - "Use the read tool to load a skill's file when the task matches its description.", - "When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.", - "", - "", - ]; - - for (const skill of visibleSkills) { - lines.push(" "); - lines.push(` ${escapeXml(skill.name)}`); - lines.push(` ${escapeXml(skill.description)}`); - lines.push(` ${escapeXml(skill.filePath)}`); - lines.push(" "); - } - - lines.push(""); - - return lines.join("\n"); -} - -function escapeXml(str: string): string { - return str - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'"); + return formatSkillContractForPrompt(visibleSkills); } export interface LoadSkillsOptions {