eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 6.31 kB
JavaScript
import{join,relative,resolve}from"node:path";import{toErrorMessage}from"#shared/errors.js";import{createDiscoverErrorDiagnostic}from"#discover/diagnostics.js";import{classifySkillPackageEntry,classifySkillsDirectoryEntry,getDirectoryEntryType,getSupportedModuleBaseName,normalizeLogicalPath}from"#discover/filesystem.js";import{createDiskProjectSource}from"#discover/project-source.js";import{createModuleSourceRef,createPathDerivedSourceId,createSkillPackageSourceRef}from"#discover/manifest.js";import{readSortedDirectoryEntries}from"#discover/grammar.js";import{lowerSkillMarkdown}from"#internal/helpers/markdown.js";const DISCOVER_SKILLS_DIRECTORY_INVALID=`discover/skills-directory-invalid`,DISCOVER_SKILL_COLLISION=`discover/skill-collision`,DISCOVER_SKILL_ENTRY_NOT_DIRECTORY=`discover/skill-entry-not-directory`,DISCOVER_SKILL_FRONTMATTER_INVALID=`discover/skill-frontmatter-invalid`,DISCOVER_SKILL_MARKDOWN_MISSING=`discover/skill-markdown-missing`;async function discoverSkills(r){let a=r.source??createDiskProjectSource(),o=resolve(r.agentRoot),c=resolve(r.skillsDirectoryPath??join(o,`skills`)),l=normalizeLogicalPath(r.skillsLogicalPath??relative(o,c)),u=await a.stat(c);if(u===`missing`)return{diagnostics:[],skills:[]};if(u!==`directory`)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_SKILLS_DIRECTORY_INVALID,message:`Expected "${c}" to be a directory of authored skills.`,sourcePath:c})],skills:[]};let d=[],f=new Set,p=new Map,m=await readSortedDirectoryEntries(a,c);for(let t of m){let n=await discoverOneSkill({entryName:t.name,entryType:getDirectoryEntryType(t),skillsDirectoryPath:c,skillsLogicalPath:l,source:a});if(d.push(...n.diagnostics),n.skill===null||n.skillId===null||f.has(n.skillId))continue;let r=p.get(n.skillId);if(r!==void 0){d.push(createDiscoverErrorDiagnostic({code:DISCOVER_SKILL_COLLISION,message:`Found conflicting authored skill sources for "${n.skillId}": "${r.logicalPath}" and "${n.logicalPath}".`,sourcePath:join(c,n.skillId)})),f.add(n.skillId),p.delete(n.skillId);continue}p.set(n.skillId,{logicalPath:n.logicalPath,skill:n.skill})}return{diagnostics:d,skills:[...p.values()].map(e=>e.skill)}}async function discoverOneSkill(t){let n=join(t.skillsDirectoryPath,t.entryName);switch(classifySkillsDirectoryEntry(t.entryName,t.entryType)){case`skill-package-directory`:return discoverPackagedSkill({logicalSkillsPath:t.skillsLogicalPath,skillId:t.entryName,skillRootPath:n,source:t.source});case`flat-skill-markdown`:return discoverFlatMarkdownSkill({logicalSkillsPath:t.skillsLogicalPath,skillFileName:t.entryName,skillFilePath:n,source:t.source});case`flat-skill-module`:return discoverFlatModuleSkill({logicalSkillsPath:t.skillsLogicalPath,skillFileName:t.entryName});case`ignored-declaration`:return{diagnostics:[],logicalPath:normalizeLogicalPath(join(t.skillsLogicalPath,t.entryName)),skill:null,skillId:null};default:return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_SKILL_ENTRY_NOT_DIRECTORY,message:`Expected "${n}" to be a skill directory containing SKILL.md or a flat ".md", ".ts", ".cts", ".mts", ".js", ".cjs", or ".mjs" skill file.`,sourcePath:n})],logicalPath:normalizeLogicalPath(join(t.skillsLogicalPath,t.entryName)),skill:null,skillId:null}}}async function discoverPackagedSkill(t){let n=(await readSortedDirectoryEntries(t.source,t.skillRootPath)).find(e=>e.isFile()&&e.name.toLowerCase()===`skill.md`)?.name,r=join(t.skillRootPath,n??`SKILL.md`),a=normalizeLogicalPath(join(t.logicalSkillsPath,t.skillId,n??`SKILL.md`));if(n===void 0)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_SKILL_MARKDOWN_MISSING,message:`Expected "${r}" to exist for the "${t.skillId}" skill.`,sourcePath:t.skillRootPath})],logicalPath:a,skill:null,skillId:null};let o;try{o=lowerSkillMarkdown(await t.source.readTextFile(r))}catch(e){return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_SKILL_FRONTMATTER_INVALID,message:formatSkillDiscoveryError(r,e),sourcePath:r})],logicalPath:a,skill:null,skillId:null}}let s=await discoverSkillPackagePaths(t.source,t.skillRootPath),c={description:o.description,logicalPath:a,markdown:o.markdown,name:t.skillId,rootPath:t.skillRootPath,skillFilePath:r,skillId:t.skillId,sourceId:createPathDerivedSourceId(a)};return s.assetsPath!==void 0&&(c.assetsPath=s.assetsPath),o.license!==void 0&&(c.license=o.license),o.metadata!==void 0&&(c.metadata=o.metadata),s.referencesPath!==void 0&&(c.referencesPath=s.referencesPath),s.scriptsPath!==void 0&&(c.scriptsPath=s.scriptsPath),{diagnostics:[],logicalPath:a,skill:createSkillPackageSourceRef(c),skillId:t.skillId}}async function discoverFlatMarkdownSkill(t){let n=stripMarkdownExtension(t.skillFileName),r=normalizeLogicalPath(join(t.logicalSkillsPath,t.skillFileName)),a;try{a=lowerSkillMarkdown(await t.source.readTextFile(t.skillFilePath),{slug:n})}catch(e){return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_SKILL_FRONTMATTER_INVALID,message:formatSkillDiscoveryError(t.skillFilePath,e),sourcePath:t.skillFilePath})],logicalPath:r,skill:null,skillId:null}}return{diagnostics:[],logicalPath:r,skill:{definition:a,sourceKind:`markdown`,logicalPath:r,sourceId:createPathDerivedSourceId(r)},skillId:n}}async function discoverFlatModuleSkill(t){let n=getSupportedModuleBaseName(t.skillFileName),r=normalizeLogicalPath(join(t.logicalSkillsPath,t.skillFileName));return n===null?{diagnostics:[],logicalPath:r,skill:null,skillId:null}:{diagnostics:[],logicalPath:r,skill:createModuleSourceRef({logicalPath:r}),skillId:n}}async function discoverSkillPackagePaths(t,n){let r=await t.readDirectory(n),i={};for(let t of r)if(t.isDirectory())switch(classifySkillPackageEntry(t.name,getDirectoryEntryType(t))){case`skill-assets-directory`:i.assetsPath=join(n,t.name);break;case`skill-references-directory`:i.referencesPath=join(n,t.name);break;case`skill-scripts-directory`:i.scriptsPath=join(n,t.name);break;default:break}return i}function formatSkillDiscoveryError(e,t){return`Invalid authored skill frontmatter in "${e}": ${toErrorMessage(t)}`}function stripMarkdownExtension(e){return e.toLowerCase().endsWith(`.md`)?e.slice(0,-3):e}export{DISCOVER_SKILLS_DIRECTORY_INVALID,DISCOVER_SKILL_COLLISION,DISCOVER_SKILL_ENTRY_NOT_DIRECTORY,DISCOVER_SKILL_FRONTMATTER_INVALID,DISCOVER_SKILL_MARKDOWN_MISSING,discoverSkills};