RuleSync
Quick start: synchronize skills and rules
Run these commands from the repository root. RuleSync owns the canonical files under .rulesync/ and generates the agent-specific copies.
Add and synchronize a skill
On a skills.sh skill page, use the displayed GitHub repository and skill slug. RuleSync requires the repository source; it does not resolve a skills.sh skill name by itself.
# Add one skill, update rulesync.jsonc and the lockfile, and install its source
npx --no-install rulesync add owner/repository --skills skill-name
# Write the installed skill to every configured target
npx --no-install rulesync generate --features skills
# Verify that generated skill outputs are current
npx --no-install rulesync generate --check --features skills
For example, add Anthropic's skill-creator skill directly through RuleSync:
npx --no-install rulesync add anthropics/skills --skills skill-creator
npx --no-install rulesync generate --features skills
npx --no-install rulesync generate --check --features skills
rulesync add performs the initial source installation, so a separate rulesync install is not needed immediately afterward. On another checkout, restore the locked sources before generating:
npx --no-install rulesync install --frozen
npx --no-install rulesync generate --features skills
If the repository is already listed in rulesync.jsonc, add the new skill name to that source's skills array instead of adding the source again. Then synchronize it with:
npx --no-install rulesync install
npx --no-install rulesync generate --features skills
npx --no-install rulesync generate --check --features skills
Add or change a canonical rule
Create a new canonical rule scaffold and edit the resulting Markdown file:
npx --no-install rulesync add rule --name rule-name
# Edit .rulesync/rules/rule-name.md
To install a named rule from an external RuleSync source instead, use:
npx --no-install rulesync add owner/repository --rules rule-name
After adding or changing any file under .rulesync/rules/, synchronize the configured Cursor, Claude Code, and Codex outputs:
# Preview only the rule changes
npx --no-install rulesync generate --dry-run --features rules
# Write rule outputs to all targets configured in rulesync.jsonc
npx --no-install rulesync generate --features rules
# Verify that the generated rule outputs are current
npx --no-install rulesync generate --check --features rules
OpenSpec workflow files
For the portable OpenSpec flow, pull each complete skill directory into .rulesync/skills/. The required Markdown entry files are:
.rulesync/skills/openspec-explore/SKILL.md
.rulesync/skills/openspec-propose/SKILL.md
.rulesync/skills/openspec-apply-change/SKILL.md
.rulesync/skills/openspec-update-change/SKILL.md
.rulesync/skills/openspec-sync-specs/SKILL.md
.rulesync/skills/openspec-archive-change/SKILL.md
The normal sequence is explore (optional) → propose → apply-change → sync-specs (optional) → archive-change. Use update-change after a proposal when its planning artifacts need revision.
Cursor may also generate these slash-command aliases:
.cursor/commands/opsx-explore.md
.cursor/commands/opsx-propose.md
.cursor/commands/opsx-apply.md
.cursor/commands/opsx-update.md
.cursor/commands/opsx-sync.md
.cursor/commands/opsx-archive.md
Those command files are optional Cursor entry points, not additional portable skills. Keep the six SKILL.md directories as the canonical cross-agent workflow; do not pull both sets into RuleSync as duplicate skill definitions. After changing the canonical OpenSpec skills, synchronize all targets with:
npx --no-install rulesync generate --features skills
npx --no-install rulesync generate --check --features skills
This repository uses RuleSync to maintain AI-agent configuration once and generate the formats expected by Cursor, Claude Code, and Codex.
The installed version is 27.0.0. Run commands from the repository root with the project-local dependency:
npx --no-install rulesync --version
Source of truth
Treat .rulesync/ as authored source and tool-specific files as generated output:
.rulesync/
├── rules/ # Project instructions
├── skills/ # Reusable workflows and supporting files
├── subagents/ # Specialized agent definitions
├── mcp.jsonc # MCP servers
├── hooks.jsonc # Lifecycle hooks
└── permissions.jsonc
Do not make lasting edits directly in generated files such as .cursor/rules/*.mdc, .claude/rules/*.md, AGENTS.md, CLAUDE.md, or .codex/agents/*.toml. A later generation can replace those edits. Using Cursor as the editor does not change the source location: create and edit rules under .rulesync/rules/.
The project targets are configured in rulesync.jsonc. The target identifiers are exact; use codexcli, not codexcl or codex.
Project configuration
The repository generates the same canonical features for Cursor, Claude Code, and Codex:
{
"$schema": "https://github.com/dyoshikawa/rulesync/releases/latest/download/config-schema.json",
"targets": ["cursor", "claudecode", "codexcli"],
"features": [
"rules",
"mcp",
"subagents",
"skills",
"hooks",
"permissions"
],
"outputRoots": ["."],
"delete": true,
"deriveSubprojectPathFromGlobs": true,
"verbose": false,
"silent": false,
"global": false,
"simulateCommands": false,
"simulateSubagents": false,
"simulateSkills": false,
"gitignoreTargetsOnly": true
}
targetsselects the tool adapters. Target order matters when adapters share an output path;codexcliis last so it owns the finalAGENTS.md.featuresselects the configuration families to generate. Commands are omitted because the OpenSpec flow is represented as portable skills; add"commands"only when.rulesync/commands/becomes canonical.outputRoots: ["."]writes one project-level configuration tree. Add roots only when agents are deliberately launched from independent package directories.delete: trueremoves stale files from RuleSync-owned output locations. This is safe only because the generated tool directories are not hand-edited.deriveSubprojectPathFromGlobs: trueconverts clearly scoped globs into nestedAGENTS.mdfiles, keeping unrelated API, web, and contracts instructions out of Codex sessions.global: falsekeeps the generated configuration in this repository instead of writing user-level files.simulateCommands,simulateSubagents, andsimulateSkillsremain off because all three targets have native representations for the enabled features.gitignoreTargetsOnly: truelimits generated ignore entries to configured tools.
:::caution Before the first full generation
With delete: true, RuleSync removes files from generated feature directories when no canonical RuleSync source produces them. Declare every existing skill that should be retained with rulesync add ... --skills ... before running an unfiltered rulesync generate for the first time.
Inspect the plan first:
npx --no-install rulesync generate --dry-run --json
If it proposes deleting a skill that should remain, add that skill to RuleSync before continuing. Feature-scoped rule generation remains safe while skill migration is unfinished:
npx --no-install rulesync generate --delete --features rules
:::
Generate configuration
Preview changes before writing them:
npx --no-install rulesync generate --dry-run
Generate every configured feature and target:
npx --no-install rulesync generate
Verify that committed output matches the canonical sources:
npx --no-install rulesync doctor --strict
npx --no-install rulesync generate --check
During active configuration work, watch the source tree and regenerate after each save:
npx --no-install rulesync generate --watch
Import existing configuration
Import is a one-time migration path from files already maintained for one tool. It writes canonical files under .rulesync/ for review. After migration, edit .rulesync/ and use generate; do not repeatedly import generated target files.
# Import Cursor rules into .rulesync/rules/
npx --no-install rulesync import --targets cursor --features rules
# Import Claude Code rules
npx --no-install rulesync import --targets claudecode --features rules
# Import Codex rules
npx --no-install rulesync import --targets codexcli --features rules
Import one target at a time. Review the resulting frontmatter, remove duplicates, and then use generate for normal maintenance.
import can rewrite canonical feature directories. Commit or stash work before importing into a repository that already has hand-authored .rulesync/ files.
Convert versus generate
convert is a one-time translation between tool formats:
npx --no-install rulesync convert \
--from cursor \
--to codexcli,claudecode \
--features rules,subagents,skills \
--dry-run
The intermediate RuleSync representation exists only in memory. No .rulesync/ source files are created, and later changes to Cursor files are not synchronized automatically.
Use convert for a disposable migration. Use import followed by generate when this repository should keep the tools synchronized.
Always restrict --features when only one feature is needed. Without it, RuleSync attempts every feature supported by the source and may fail on an unrelated file such as malformed .cursor/hooks.json.
Keep Codex context small
Cursor can conditionally activate .mdc rules using globs. Codex does not read .cursor/rules/*.mdc and does not have a modular natural-language .codex/rules directory. Codex automatically loads AGENTS.md files instead.
By default, RuleSync folds non-root Codex rules into the root AGENTS.md. That preserves the instructions but makes every folded rule part of every root-level Codex session.
Generate nested AGENTS.md files
Path derivation is enabled in rulesync.jsonc:
{
"deriveSubprojectPathFromGlobs": true
}
Given these canonical rules:
# .rulesync/rules/architecture-api.md
---
root: false
targets: ["*"]
globs:
- apps/api/**
---
# .rulesync/rules/architecture-web.md
---
root: false
targets: ["*"]
globs:
- apps/web/**
---
RuleSync can generate:
AGENTS.md # Small repository-wide instructions
apps/api/AGENTS.md # API-only instructions
apps/web/AGENTS.md # Web-only instructions
packages/contracts/AGENTS.md # Contracts-only instructions
Run rule generation with deletion once after enabling the option so obsolete generated placements are removed:
npx --no-install rulesync generate --delete --features rules
Codex loads AGENTS.md files from the repository root down to its current working directory. To guarantee that a nested file is injected at session start, launch Codex from that subproject—for example, from apps/api for API work. A session launched at the repository root receives the root instructions but not every nested document.
Rules with universal globs such as **/* have no directory prefix to derive and remain root-level. Keep those rules short.
Use an explicit subproject path
When glob derivation is ambiguous, set the destination on the rule:
---
root: false
targets: ["*"]
globs:
- apps/api/src/**
agentsmd:
subprojectPath: apps/api
---
Use agentsmd.subprojectPath: "auto" to request derivation for one rule, or agentsmd.subprojectPath: "" to opt one rule out of global derivation.
Route to detailed rules on demand
If Codex is normally launched from the monorepo root, keep the root rule as a small routing table and tell the agent which detailed file to read before working in an area:
# Project instructions
- For `apps/api/**`, read `apps/api/AGENTS.md` before editing.
- For `apps/web/**`, read `apps/web/AGENTS.md` before editing.
- For `packages/contracts/**`, read `packages/contracts/AGENTS.md` before editing.
This adds a small constant context cost and loads detailed architecture only when a task needs it.
Rule frontmatter
A typical portable rule looks like this:
---
root: false
targets:
- "*"
description: Fastify API architecture rules
globs:
- apps/api/**
cursor:
alwaysApply: false
---
# API architecture
Write the actual instructions here.
Important fields:
| Field | Meaning |
|---|---|
root | Writes the tool's main project instruction file when true |
targets | Selects which tools receive the rule; "*" means every compatible target |
description | Helps tools with model-selected rules decide when the rule applies |
globs | Carries file scope for tools that support it and can derive nested AGENTS.md paths |
agentsmd.subprojectPath | Places the rule in a nested directory for AGENTS.md-compatible tools |
cursor | Holds Cursor-specific overrides such as alwaysApply |
Tool-specific frontmatter should express a genuine adapter difference. Keep the rule body portable.
Application modes by target
RuleSync translates the canonical fields into each tool's native behavior; the tools do not have identical activation models.
| Canonical rule | Cursor | Claude Code | Codex |
|---|---|---|---|
root: true | Baseline project rule | Root project instructions | Root AGENTS.md |
Specific globs | Auto-attached when matching files are involved | Emitted as conditional paths | Used to derive a nested AGENTS.md; globs alone do not activate Codex rules |
description without globs | Agent Requested: Cursor chooses it by description | No equivalent model-selected rule mode | No equivalent model-selected rule mode |
| No description and no globs | Apply Manually through an explicit Cursor mention | Becomes an unscoped rule | Becomes folded root context unless placed in a nested AGENTS.md |
Use only a small number of universal rules. For a Cursor Always Apply rule, keep the portable universal scope while preventing a conflicting Cursor glob:
---
root: false
targets: ["*"]
globs: ["**/*"]
cursor:
alwaysApply: true
globs: []
---
For portable context isolation, prefer a scoped rule:
---
root: false
targets: ["*"]
description: Fastify API architecture rules
globs:
- apps/api/**
cursor:
alwaysApply: false
---
That becomes a file-matched Cursor rule, a path-scoped Claude rule, and—because path derivation is enabled—apps/api/AGENTS.md for Codex. If instructions should be selected manually or on demand across all three tools, make them a skill instead of a rule.
Names and namespaces
RuleSync has no general rule namespace setting. Use globally distinctive rule filenames, targets for tool selection, globs for file scope, and agentsmd.subprojectPath for explicit Codex directory scope.
Directories under .rulesync/rules/ may help organize source files, but do not rely on them as a portable runtime namespace: some target formats preserve directories while others flatten names. Skills are named by their .rulesync/skills/<skill-name>/ directory, so skill names should also be unique.
Claude Code supports nested command namespaces, while Cursor may need nested command paths flattened. If the commands feature is enabled later, set "flattenedCommandNaming": "path" in rulesync.jsonc to turn a source such as ops/review.md into a collision-resistant flat name such as ops-review.md where necessary.
Skills and subagents
Author reusable workflows in .rulesync/skills/<skill-name>/SKILL.md. Each skill may also contain scripts/, references/, and assets/.
For portable project skills, .agents/skills is the preferred shared output: Codex and Cursor discover it directly. Claude Code uses .claude/skills, which RuleSync can generate for the claudecode target. Avoid maintaining identical hand-written copies under .cursor/skills and .agents/skills.
Author subagents in .rulesync/subagents/*.md. RuleSync adapts them into each target's native format, such as Cursor Markdown agents and Codex TOML agents. Keep file references in subagent instructions portable; prefer canonical or generated cross-tool paths instead of assuming .cursor/rules always exists.
Output ownership
Several tools may write the same shared file, especially AGENTS.md. Target order matters because the last configured owner wins.
After changing targets, inspect the mutation plan:
npx --no-install rulesync generate --dry-run --json
Then run a full generation rather than generating one target in isolation:
npx --no-install rulesync generate
This avoids leaving a shared root file in the format of a temporary, narrowed target run.
Troubleshooting
JSON parse errors
An error such as Expected property name or '}' usually means RuleSync read strict JSON containing comments or a trailing comma. Cursor files such as .cursor/hooks.json must be valid JSON unless that particular file format explicitly supports JSONC.
If only rules are needed, exclude unrelated features:
npx --no-install rulesync convert \
--from cursor \
--to codexcli \
--features rules
Codex has no generated .codex/rules Markdown
This is expected. Codex project instructions are written to root or nested AGENTS.md files. .codex/rules is not the destination for Markdown architecture instructions.
A generated file is missing or stale
Run:
npx --no-install rulesync doctor --strict
npx --no-install rulesync generate --dry-run --verbose
npx --no-install rulesync generate --check
Also confirm that the feature is enabled for the target and that another target is not overwriting a shared output later in the target list.
Generated files dominate pull-request diffs
Keep generated files tracked so agents can read them, but mark their paths as linguist-generated in .gitattributes if they create review noise. GitHub then collapses those diffs by default without hiding the files from tools.