| layout | default |
|---|---|
| title | Chapter 2: Skill Format and Loader Architecture |
| nav_order | 2 |
| parent | OpenSkills Tutorial |
Welcome to Chapter 2: Skill Format and Loader Architecture. In this part of OpenSkills Tutorial: Universal Skill Loading for Coding Agents, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.
OpenSkills uses Claude-style SKILL.md and generates an agent-readable skills registry in AGENTS.md.
| Layer | Role |
|---|---|
| skill package | instruction + resources |
| loader | install/read/update lifecycle |
| sync engine | writes <available_skills> manifest |
You now understand how OpenSkills maps skill files into runtime-usable metadata.
Next: Chapter 3: Installation Sources and Trust Model
The isGitUrl function in src/commands/install.ts handles a key part of this chapter's functionality:
* Check if source is a git URL (SSH, git://, or HTTPS)
*/
function isGitUrl(source: string): boolean {
return (
source.startsWith('git@') ||
source.startsWith('git://') ||
source.startsWith('http://') ||
source.startsWith('https://') ||
source.endsWith('.git')
);
}
/**
* Extract repo name from a git URL
*/
function getRepoName(repoUrl: string): string | null {
const cleaned = repoUrl.replace(/\.git$/, '');
const lastPart = cleaned.split('/').pop();
if (!lastPart) return null;
const maybeRepo = lastPart.includes(':') ? lastPart.split(':').pop() : lastPart;
return maybeRepo || null;
}
/**
* Expand ~ to home directory
*/
function expandPath(source: string): string {
if (source.startsWith('~/')) {
return join(homedir(), source.slice(2));
}
return resolve(source);
}This function is important because it defines how OpenSkills Tutorial: Universal Skill Loading for Coding Agents implements the patterns covered in this chapter.
The getRepoName function in src/commands/install.ts handles a key part of this chapter's functionality:
* Extract repo name from a git URL
*/
function getRepoName(repoUrl: string): string | null {
const cleaned = repoUrl.replace(/\.git$/, '');
const lastPart = cleaned.split('/').pop();
if (!lastPart) return null;
const maybeRepo = lastPart.includes(':') ? lastPart.split(':').pop() : lastPart;
return maybeRepo || null;
}
/**
* Expand ~ to home directory
*/
function expandPath(source: string): string {
if (source.startsWith('~/')) {
return join(homedir(), source.slice(2));
}
return resolve(source);
}
/**
* Ensure target path stays within target directory
*/
function isPathInside(targetPath: string, targetDir: string): boolean {
const resolvedTargetPath = resolve(targetPath);
const resolvedTargetDir = resolve(targetDir);
const resolvedTargetDirWithSep = resolvedTargetDir.endsWith(sep)
? resolvedTargetDir
: resolvedTargetDir + sep;
return resolvedTargetPath.startsWith(resolvedTargetDirWithSep);
}This function is important because it defines how OpenSkills Tutorial: Universal Skill Loading for Coding Agents implements the patterns covered in this chapter.
The expandPath function in src/commands/install.ts handles a key part of this chapter's functionality:
* Expand ~ to home directory
*/
function expandPath(source: string): string {
if (source.startsWith('~/')) {
return join(homedir(), source.slice(2));
}
return resolve(source);
}
/**
* Ensure target path stays within target directory
*/
function isPathInside(targetPath: string, targetDir: string): boolean {
const resolvedTargetPath = resolve(targetPath);
const resolvedTargetDir = resolve(targetDir);
const resolvedTargetDirWithSep = resolvedTargetDir.endsWith(sep)
? resolvedTargetDir
: resolvedTargetDir + sep;
return resolvedTargetPath.startsWith(resolvedTargetDirWithSep);
}
/**
* Install skill from local path, GitHub, or Git URL
*/
export async function installSkill(source: string, options: InstallOptions): Promise<void> {
const folder = options.universal ? '.agent/skills' : '.claude/skills';
const isProject = !options.global; // Default to project unless --global specified
const targetDir = isProject
? join(process.cwd(), folder)
: join(homedir(), folder);
const location = isProjectThis function is important because it defines how OpenSkills Tutorial: Universal Skill Loading for Coding Agents implements the patterns covered in this chapter.
The isPathInside function in src/commands/install.ts handles a key part of this chapter's functionality:
* Ensure target path stays within target directory
*/
function isPathInside(targetPath: string, targetDir: string): boolean {
const resolvedTargetPath = resolve(targetPath);
const resolvedTargetDir = resolve(targetDir);
const resolvedTargetDirWithSep = resolvedTargetDir.endsWith(sep)
? resolvedTargetDir
: resolvedTargetDir + sep;
return resolvedTargetPath.startsWith(resolvedTargetDirWithSep);
}
/**
* Install skill from local path, GitHub, or Git URL
*/
export async function installSkill(source: string, options: InstallOptions): Promise<void> {
const folder = options.universal ? '.agent/skills' : '.claude/skills';
const isProject = !options.global; // Default to project unless --global specified
const targetDir = isProject
? join(process.cwd(), folder)
: join(homedir(), folder);
const location = isProject
? chalk.blue(`project (${folder})`)
: chalk.dim(`global (~/${folder})`);
const projectLocation = `./${folder}`;
const globalLocation = `~/${folder}`;
console.log(`Installing from: ${chalk.cyan(source)}`);
console.log(`Location: ${location}`);
if (isProject) {
console.log(This function is important because it defines how OpenSkills Tutorial: Universal Skill Loading for Coding Agents implements the patterns covered in this chapter.
flowchart TD
A[isGitUrl]
B[getRepoName]
C[expandPath]
D[isPathInside]
E[installSkill]
A --> B
B --> C
C --> D
D --> E