Custom Output Path
What You'll Learn
- Use the
-oor--outputflag to sync skills to.mdfiles at any location - Understand how the tool automatically creates non-existent files and directories
- Configure different AGENTS.md files for different tools (Windsurf, Cursor, etc.)
- Manage skill lists in multi-file environments
- Skip the default
AGENTS.mdand integrate into existing documentation systems
Prerequisites
This tutorial assumes you have mastered basic skill syncing. If you haven't installed any skills or synced AGENTS.md yet, please complete the prerequisite course first.
Your Current Challenge
You may be accustomed to openskills sync generating AGENTS.md by default, but you might encounter:
- Tools require specific paths: Some AI tools (like Windsurf) expect AGENTS.md in a specific directory (like
.ruler/), not the project root - Multi-tool conflicts: When using multiple coding tools simultaneously, they may expect AGENTS.md in different locations
- Existing documentation integration: You already have a skills list document and want to integrate OpenSkills' skills into it instead of creating a new file
- Directory doesn't exist: You want to output to a nested directory (like
docs/ai-skills.md), but the directory doesn't exist yet
The root cause of these issues: The default output path cannot meet all scenarios. You need more flexible output control.
When to Use This Approach
Custom output path is suitable for these scenarios:
- Multi-tool environments: Configure separate AGENTS.md files for different AI tools (like
.ruler/AGENTS.mdvsAGENTS.md) - Directory structure requirements: Tools expect AGENTS.md in a specific directory (like Windsurf's
.ruler/) - Existing documentation integration: Integrate skill lists into existing documentation systems instead of creating new AGENTS.md
- Organizational management: Store skill lists by project or function category (like
docs/ai-skills.md) - CI/CD environments: Use fixed path output in automated workflows
Recommended Practice
If your project only uses one AI tool and the tool supports AGENTS.md in the project root, using the default path is sufficient. Only use custom output paths when you need multi-file management or have tool-specific path requirements.
🎒 Preparation Before Starting
Before you begin, please confirm:
- [ ] Have completed at least one skill installation
- [ ] Have navigated to your project directory
- [ ] Understand the basic usage of
openskills sync
Prerequisite Check
Confirm you have installed skills:
npx openskills listIf the list is empty, install a skill first:
npx openskills install anthropics/skillsCore Concept: Flexible Output Control
OpenSkills' sync function outputs to AGENTS.md by default, but you can use the -o or --output flag to customize the output path.
[Default Behavior] [Custom Output]
openskills sync → AGENTS.md (project root)
openskills sync -o custom.md → custom.md (project root)
openskills sync -o .ruler/AGENTS.md → .ruler/AGENTS.md (nested directory)Key Features:
- Arbitrary paths: You can specify any
.mdfile path (relative or absolute) - Automatic file creation: If the file doesn't exist, the tool creates it automatically
- Automatic directory creation: If the file's directory doesn't exist, the tool creates it recursively
- Smart titles: When creating files, automatically adds a title based on the filename (like
# AGENTS) - Format validation: Must end with
.md, otherwise an error is reported
Why do you need this feature?
Different AI tools may have different expected paths:
| Tool | Expected Path | Default Path Usable |
|---|---|---|
| Claude Code | AGENTS.md | ✅ Available |
| Cursor | AGENTS.md | ✅ Available |
| Windsurf | .ruler/AGENTS.md | ❌ Not Available |
| Aider | .aider/agents.md | ❌ Not Available |
Using the -o flag, you can configure the correct path for each tool.
Follow Along
Step 1: Basic Usage - Output to Current Directory
First, try syncing skills to a custom file in the current directory:
npx openskills sync -o my-skills.mdWhy
Using -o my-skills.md tells the tool to output to my-skills.md instead of the default AGENTS.md.
You should see:
If my-skills.md doesn't exist, the tool will create it:
Created my-skills.mdThen the interactive selection interface launches:
Found 2 skill(s)
? Select skills to sync to my-skills.md:
❯ ◉ pdf (project) Comprehensive PDF manipulation toolkit...
◉ git-workflow (project) Git workflow: Best practices for commits...
<Space> Select <a> Select All <i> Invert <Enter> ConfirmAfter selecting skills, you'll see:
✅ Synced 2 skill(s) to my-skills.mdCheck Generated File
View the generated file:
cat my-skills.mdYou'll see:
<!-- File title: # my-skills -->
<skills_system priority="1">
## Available Skills
<!-- SKILLS_TABLE_START -->
<usage>
When users ask you to perform tasks, check if any of available skills below can help...
</usage>
<available_skills>
<skill>
<name>pdf</name>
<description>Comprehensive PDF manipulation toolkit...</description>
<location>project</location>
</skill>
</available_skills>
<!-- SKILLS_TABLE_END -->
</skills_system>Note that the first line is # my-skills, which is the automatically generated title based on the filename.
Step 2: Output to Nested Directory
Now, try syncing skills to a non-existent nested directory:
npx openskills sync -o .ruler/AGENTS.mdWhy
Some tools (like Windsurf) expect AGENTS.md in the .ruler/ directory. If the directory doesn't exist, the tool creates it automatically.
You should see:
If the .ruler/ directory doesn't exist, the tool creates the directory and file:
Created .ruler/AGENTS.mdThen the interactive selection interface launches (same as the previous step).
Operation Guide:
┌─────────────────────────────────────────────────────────────┐
│ Automatic Directory Creation Explanation │
│ │
│ Command input: openskills sync -o .ruler/AGENTS.md │
│ │
│ Tool execution: │
│ 1. Check if .ruler directory exists → Doesn't exist │
│ 2. Recursively create .ruler directory → mkdir .ruler │
│ 3. Create .ruler/AGENTS.md → Write # AGENTS title │
│ 4. Sync skill content → Write XML skill list │
│ │
│ Result: .ruler/AGENTS.md file generated, skills synced │
└─────────────────────────────────────────────────────────────┘Recursive Creation
The tool recursively creates all non-existent parent directories. For example:
docs/ai/skills.md- If bothdocsanddocs/aidon't exist, they will be created.config/agents.md- Will create the hidden directory.config
Step 3: Multi-File Management - Configure for Different Tools
Suppose you use both Windsurf and Cursor and need to configure different AGENTS.md files for them:
<!-- Configure for Windsurf (expects .ruler/AGENTS.md) -->
npx openskills sync -o .ruler/AGENTS.md
<!-- Configure for Cursor (use AGENTS.md in project root) -->
npx openskills syncWhy
Different tools may expect AGENTS.md in different locations. Using -o allows you to configure the correct path for each tool, avoiding conflicts.
You should see:
Two files are generated separately:
<!-- View Windsurf's AGENTS.md -->
cat .ruler/AGENTS.md
<!-- View Cursor's AGENTS.md -->
cat AGENTS.mdFile Independence
Each .md file is independent and contains its own skill list. You can choose different skills in different files:
.ruler/AGENTS.md- Skills selected for WindsurfAGENTS.md- Skills selected for Cursordocs/ai-skills.md- Skill list in documentation
Step 4: Non-Interactive Sync to Custom File
In CI/CD environments, you may need to skip interactive selection and directly sync all skills to a custom file:
npx openskills sync -o .ruler/AGENTS.md -yWhy
The -y flag skips interactive selection and syncs all installed skills. Combined with the -o flag, you can output to a custom path in automated workflows.
You should see:
Created .ruler/AGENTS.md
✅ Synced 2 skill(s) to .ruler/AGENTS.mdCI/CD Usage Scenario
Use in CI/CD scripts:
#!/bin/bash
<!-- Install skills -->
npx openskills install anthropics/skills -y
<!-- Sync to custom file (non-interactive) -->
npx openskills sync -o .ruler/AGENTS.md -yStep 5: Verify Output File
Finally, verify that the output file was generated correctly:
<!-- View file content -->
cat .ruler/AGENTS.md
<!-- Check if file exists -->
ls -l .ruler/AGENTS.md
<!-- Confirm skill count -->
grep -c "<name>" .ruler/AGENTS.mdYou should see:
- File contains correct title (like
# AGENTS) - File contains
<skills_system>XML tags - File contains
<available_skills>skill list - Each
<skill>contains<name>,<description>,<location>
Check Output Path
If you're unsure about the current working directory, you can use:
<!-- View current directory -->
pwd
<!-- See where relative path resolves to -->
realpath .ruler/AGENTS.mdCheckpoint ✅
After completing the above steps, please confirm:
- [ ] Successfully used
-oflag to output to custom file - [ ] Tool automatically created non-existent files
- [ ] Tool automatically created non-existent nested directories
- [ ] Generated file contains correct title (based on filename)
- [ ] Generated file contains
<skills_system>XML tags - [ ] Generated file contains complete skill list
- [ ] Can configure different output paths for different tools
- [ ] Can use
-yand-ocombination in CI/CD environment
If all the above checkpoints pass, congratulations! You have mastered the use of custom output paths and can flexibly sync skills to any location.
Common Pitfalls
Issue 1: Output file is not markdown
Phenomenon:
Error: Output file must be a markdown file (.md)Cause:
When using the -o flag, the specified file extension is not .md. The tool enforces output to markdown files to ensure AI tools can parse correctly.
Solution:
Ensure the output file ends with .md:
<!-- ❌ Incorrect -->
npx openskills sync -o skills.txt
<!-- ✅ Correct -->
npx openskills sync -o skills.mdIssue 2: Directory creation permission error
Phenomenon:
Error: EACCES: permission denied, mkdir '.ruler'Cause:
When attempting to create a directory, the current user doesn't have write permission for the parent directory.
Solution:
- Check parent directory permissions:
ls -ld .- If permissions are insufficient, contact your administrator or use a directory with permissions:
<!-- Use project directory -->
cd ~/projects/my-project
npx openskills sync -o .ruler/AGENTS.mdIssue 3: Output path too long
Phenomenon:
The file path is very long, making the command difficult to read and maintain:
npx openskills sync -o docs/ai/skills/v2/internal/agents.mdCause:
Nested directories are too deep, making the path difficult to manage.
Solution:
- Use relative paths (starting from project root)
- Simplify directory structure
- Consider using symbolic links (see Symbolic Link Support)
<!-- Recommended: Flatten directory structure -->
npx openskills sync -o docs/agents.mdIssue 4: Forgot to use -o flag
Phenomenon:
Expecting output to a custom file, but the tool still outputs to the default AGENTS.md.
Cause:
Forgot to use the -o flag, or made a typo.
Solution:
- Check if the command contains
-oor--output:
<!-- ❌ Incorrect: Forgot -o flag -->
npx openskills sync
<!-- ✅ Correct: Use -o flag -->
npx openskills sync -o .ruler/AGENTS.md- Use the complete form
--output(clearer):
npx openskills sync --output .ruler/AGENTS.mdIssue 5: Filename contains special characters
Phenomenon:
Filename contains spaces or special characters, causing path resolution errors:
npx openskills sync -o "my skills.md"Cause:
Some shells handle special characters differently, which may cause path errors.
Solution:
- Avoid using spaces and special characters
- If necessary, wrap in quotes:
<!-- Not recommended -->
npx openskills sync -o "my skills.md"
<!-- Recommended -->
npx openskills sync -o my-skills.mdSummary
In this lesson, you learned:
- Using the
-oor--outputflag to sync skills to custom.mdfiles - Automatic file and directory creation mechanism, no need to manually prepare directory structure
- Configuring different AGENTS.md files for different tools, avoiding multi-tool conflicts
- Multi-file management tips, storing skill lists by tool or function category
- CI/CD environment usage with
-yand-ocombination for automated sync
Core Commands:
| Command | Action |
|---|---|
npx openskills sync -o custom.md | Sync to custom.md in project root |
npx openskills sync -o .ruler/AGENTS.md | Sync to .ruler/AGENTS.md (automatically creates directory) |
npx openskills sync -o path/to/file.md | Sync to any path (automatically creates nested directories) |
| --- | --- |
Key Points:
- Output file must end with
.md - Tool automatically creates non-existent files and directories
- When creating files, automatically adds title based on filename
- Each
.mdfile is independent and contains its own skill list - Suitable for multi-tool environments, directory structure requirements, existing documentation integration, and other scenarios
Next Lesson Preview
Next, we'll learn Symbolic Link Support.
You'll learn:
- How to use symbolic links for git-based skill updates
- Advantages and use cases of symbolic links
- How to manage skills in local development
- Symbolic link detection and handling mechanisms
Custom output paths allow you to flexibly control the location of skill lists, while symbolic links provide a more advanced skill management approach, particularly suitable for local development scenarios.
Appendix: Source Code Reference
Click to expand source code locations
Updated: 2026-01-24
| Function | File Path | Line |
|---|---|---|
| sync command entry | src/commands/sync.ts | 18-109 |
| CLI option definition | src/cli.ts | 66 |
| Output path retrieval | src/commands/sync.ts | 19 |
| Output file validation | src/commands/sync.ts | 22-26 |
| --- | --- | --- |
| Recursively create directory | src/commands/sync.ts | 31-32 |
| Auto-generate title | src/commands/sync.ts | 34 |
| Interactive prompt uses output filename | src/commands/sync.ts | 70 |
Key Functions:
syncAgentsMd(options: SyncOptions)- Sync skills to specified output fileoptions.output- Custom output path (optional, default 'AGENTS.md')
Key Constants:
'AGENTS.md'- Default output filename'.md'- Required file extension
Key Logic:
- Output file must end with
.md, otherwise error and exit (sync.ts:23-26) - If file doesn't exist, automatically create parent directory (recursively) and file (sync.ts:28-36)
- When creating file, write title based on filename:
# ${outputName.replace('.md', '')}(sync.ts:34) - Display output filename in interactive prompt (sync.ts:70)
- Display output filename in sync success messages (sync.ts:105, 107)