Skip to main content

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
}
  • targets selects the tool adapters. Target order matters when adapters share an output path; codexcli is last so it owns the final AGENTS.md.
  • features selects 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: true removes stale files from RuleSync-owned output locations. This is safe only because the generated tool directories are not hand-edited.
  • deriveSubprojectPathFromGlobs: true converts clearly scoped globs into nested AGENTS.md files, keeping unrelated API, web, and contracts instructions out of Codex sessions.
  • global: false keeps the generated configuration in this repository instead of writing user-level files.
  • simulateCommands, simulateSubagents, and simulateSkills remain off because all three targets have native representations for the enabled features.
  • gitignoreTargetsOnly: true limits 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.

warning

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:

FieldMeaning
rootWrites the tool's main project instruction file when true
targetsSelects which tools receive the rule; "*" means every compatible target
descriptionHelps tools with model-selected rules decide when the rule applies
globsCarries file scope for tools that support it and can derive nested AGENTS.md paths
agentsmd.subprojectPathPlaces the rule in a nested directory for AGENTS.md-compatible tools
cursorHolds 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 ruleCursorClaude CodeCodex
root: trueBaseline project ruleRoot project instructionsRoot AGENTS.md
Specific globsAuto-attached when matching files are involvedEmitted as conditional pathsUsed to derive a nested AGENTS.md; globs alone do not activate Codex rules
description without globsAgent Requested: Cursor chooses it by descriptionNo equivalent model-selected rule modeNo equivalent model-selected rule mode
No description and no globsApply Manually through an explicit Cursor mentionBecomes an unscoped ruleBecomes 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.

Further reading​