rulesync

repository·main·Indexed 22 days ago

https://github.com/dyoshikawa/rulesync

A Node.js CLI tool and programmatic API for unified AI rules management. It allows users to maintain a single source of truth to automatically generate, import, and convert configuration files for AI development tools such as Cursor, Claude Code, and GitHub Copilot. It supports features including MCP, commands, skills, and open standards like AGENTS.md.

Tokens
80K
Snippets
122
Records
369
Agent score
79%

What's inside rulesync

  1. Overview of Rulesync

    main

    Rulesync is a unified AI rules management system. It allows you to author AI rules once in a single source of truth and then generate configuration files for various AI development tools. This prevents instruction duplication across different AI assistants and ensures team standards are maintained regardless of which tool a developer chooses to use.

    Key benefits include:

    • Single Source of Truth: Author rules once and generate them everywhere.
    • Tool Freedom: Switch between AI assistants without rewriting standards.
    • Clean, Auditable Outputs: Generates plain configuration files that can be committed and reviewed, and which function independently of Rulesync.
    • Consistency: Ensures new team members follow the same conventions and guardrails immediately.
  2. Core benefits of using Rulesync

    main

    Rulesync is designed to solve the problem of rule fragmentation across different AI coding assistants. Instead of manually duplicating instructions for every tool, Rulesync provides a Single Source of Truth.

    Key value propositions include:

    • Tool Freedom: Use any assistant (Copilot, Cursor, Cline, Claude Code, etc.) without rewriting standards.
    • Auditable Outputs: Rulesync generates plain configuration files that are committed to version control. These files remain functional even if Rulesync is uninstalled.
    • Consistency: Ensures all team members use the same conventions and guardrails regardless of their preferred AI tool.
    • Modular Workflows: Allows composing rules, MCP (Model Context Protocol) configs, commands, and subagents for specific scopes (project-level vs. global).
  3. How Rulesync composes and orders rules

    main

    Rulesync follows specific logic to combine multiple rule files into tool-specific outputs:

    1. Root Rules: Files with root: true are used to generate the primary configuration file. Unsafe collisions (multiple root: true rules for the same target) cause failure.
    2. Local Rules: Rules with localRoot: true are ordered lexicographically by source file path and composed before non-overridden .curated/ rules.
    3. Composition Order: Within sets, filename prefixes like 10- and 20- control the composition order.
    4. Modular Rules: Non-root rules are combined in deterministic source-discovery order. If a rule fragment generates its own frontmatter block (e.g., Amp's globs: gate), it is treated as a separate file and not composed.
    5. Collisions: Exact or case-insensitive modular collisions that result in the same output path are kept separate, and a warning is issued stating that the last write wins.
  4. Use watch mode for real-time rule iteration

    main

    Running rulesync generate --watch allows you to iterate on rules, commands, subagents, or skills without manually re-running the command. It watches the .rulesync/ source tree and your configuration files (rulesync.jsonc, rulesync.local.jsonc).

    Key behaviors:

    • Debouncing: File-system event bursts are coalesced into a single regeneration.
    • Error Resilience: If a generation fails (e.g., due to invalid syntax), the watcher stays alive and continues watching.
    • Config Changes: Editing configuration files triggers a regeneration. Note that the set of watched paths is fixed at startup; changing the inputRoot requires a restart.
    • Incompatible Flags: --watch cannot be used with --check, --dry-run, or --json.
    rulesync generate --watch
  5. Implement Agent Skills (agentskills) specification

    main

    Rulesync supports the Agent Skills specification. While it accepts legacy rulesync spellings on input, it always emits the required spec shapes:

    • allowed-tools: Emitted as a space-separated scalar (YAML lists are joined).
    • compatibility: Emitted as a string (objects are flattened to key: value pairs).
    • metadata: Emitted as a string (values are stringified to maintain a string→string map).

    Constraints & Warnings: Rulesync warns (but does not fail) if:

    • name is empty, > 64 chars, or contains invalid characters (only lowercase, digits, and single hyphens allowed).
    • description is empty or > 1024 chars.
    • compatibility > 500 chars.
    • allowed-tools entries contain whitespace.

    Note on Replit and Pi: These tools accept both spec-compliant strings and legacy rulesync forms. On import, allowed-tools is normalized back to a list. For pi, an empty allowed-tools list is dropped from the emitted file.

  6. Choose an install mode for rulesync

    main

    The rulesync install command supports three distinct modes via the --mode <mode> flag. Choosing the correct mode determines which manifest file is read, which lockfile is used, and where the output files are written.

    • rulesync (default): Uses rulesync.jsonc and sources. Writes to .rulesync/rules/.curated/ and .rulesync/skills/.curated/.
    • apm: Uses apm.yml and dependencies.apm. Writes to .github/instructions/ and .github/skills/ (APM v1 layout).
    • gh: Uses rulesync.jsonc and sources. Writes to agent-specific directories (e.g., .agents/skills or .claude/skills) to match gh skill install compatibility.
    | Mode       | Manifest input               | Lockfile                                                     | Output layout                                                                                                      |
    | ---------- | ---------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
    | `rulesync` | `rulesync.jsonc` `sources`   | `rulesync.lock` (+ `rulesync-npm.lock.json` for npm sources) | `.rulesync/rules/.curated/<name>.md`, `.rulesync/skills/.curated/<name>/` (then re-emitted by `rulesync generate`) |
    | `apm`      | `apm.yml` `dependencies.apm` | `rulesync-apm.lock.yaml`                                     | `.github/instructions/`, `.github/skills/` (APM v1 layout)                                                         |
    | `gh`       | `rulesync.jsonc` `sources`   | `rulesync-gh.lock.yaml`                                     | Per-agent / per-scope dirs (matching `gh skill install`) |
  7. Configure Codex CLI permission baselines via `extends`

    main

    The generated [permissions.rulesync] profile in Codex always extends one of Codex's built-in permission profiles using the extends key. The baseline is determined by the codexcli.base_permission_profile setting.

    Available Baselines:

    • ":workspace" (Default): Grants read access to the whole filesystem and write access to the workspace root, /tmp, and $TMPDIR. Rulesync adds specific allow/deny rules on top of this.
    • ":read-only": Keeps command execution read-only.
    • ":danger-full-access": This is a special case. Rulesync does not use the [permissions.rulesync] profile for this. Instead, it emits default_permissions = ":danger-full-access" directly and prunes any managed profile. Canonical read/edit/write/webfetch rules are ignored for Codex CLI in this mode.

    Round-tripping: When importing, the value of extends in the Codex config is mapped back to codexcli.base_permission_profile in Rulesync. If a custom parent profile is used, it is replaced by the managed baseline during regeneration.

  8. Configure per-target features in rulesync.jsonc

    main

    Instead of a global features array, you can use an object format for targets to define specific features for each tool.

    Important: When using the object format for targets, you must omit the top-level features field to avoid configuration errors.

    Target Object Syntax

    • Keys are the target tool names.
    • Values are either an array of features or an object containing feature-specific options.
    • Use "*" within a target's value to enable all features for that specific tool.

    Example

    {
      "targets": {
        "claudecode": ["rules", "commands"],
        "cursor": ["*"],
        "copilot": { "rules": true }
      }
    }
    {
      "targets": {
        "claudecode": ["rules", "commands"],
        "cursor": ["rules", "mcp"],
        "copilot": ["rules", "subagents"],
      },
    }
  9. Understand the rulesync lockfile

    main

    The rulesync.lock file (at the project root) ensures reproducible builds by recording resolved commit SHAs, rule selection metadata, and integrity hashes for every artifact. It is safe and recommended to commit this file to Git.

    For npm transport sources, a separate rulesync-npm.lock.json is used to lock resolved package versions and tarball integrity instead of commit SHAs.

    To update the locked references, run rulesync install --update.

    {
      "lockfileVersion": 1,
      "sources": {
        "owner/skill-repo": {
          "requestedRef": "main",
          "resolvedRef": "abc123def456...",
          "resolvedAt": "2025-01-15T12:00:00.000Z",
          "skills": {
            "my-skill": { "integrity": "sha256-abcdef..." },
            "another-skill": { "integrity": "sha256-123456..." }
          },
          "rules": {
            "testing-guidelines": { "integrity": "sha256-789abc..." }
          },
          "ruleSelection": ["*"],
          "rulesPath": "rules",
          "resolvedRuleNames": ["testing-guidelines"]
        }
      }
    }
  10. Kiro target differences (CLI vs IDE)

    main

    Kiro is split into kiro-cli and kiro-ide due to diverging configuration formats:

    Kiro IDE

    • Subagents: Markdown files in .kiro/agents/*.md.
    • Hooks: Structured JSON in .kiro/hooks/*.json (emitted as a single .kiro/hooks/rulesync.json with { "version": "v1", "hooks": [ ... ] } in project or global scope).
    • Global Configs: ~/.kiro/skills/, ~/.kiro/settings/kiroignore, and ~/.kiro/agents/.

    Kiro CLI

    • Subagents: JSON agent-config in .kiro/agents/*.json.
    • Hooks: Located in .kiro/agents/default.json.
    • Global Configs: Global Kiro CLI commands in ~/.kiro/prompts/ and subagents in ~/.kiro/agents/.

    Note: The legacy kiro target is a deprecated alias with current behavior unchanged.

  11. Scope permissions to specific tools

    main

    While the shared permission block applies to all tools, you can scope rules to a specific tool by adding a tool-scoped block (e.g., claudecode or opencode).

    • Merging Behavior: Categories are merged per category. A tool-scoped category replaces the shared category wholesale for that tool. Shared categories not named in the tool-scoped block still apply.
    • Supported Keys: Any permissions-capable --targets name is accepted. kiro-cli/kiro-ide alias to kiro, and hermesagent aliases to hermes.
    • Tool-Specific Semantics: Tools like OpenCode, Kilo, and Vibe have unique override semantics that are handled by their respective translators.
    {
      "permission": {
        "bash": { "git *": "allow", "*": "ask" },
      },
      "claudecode": {
        "permission": {
          // Replaces the shared `bash` category for Claude Code only.
          "bash": { "git *": "allow", "git push *": "deny", "*": "ask" },
        },
      },
    }
  12. Symlink behavior in Rulesync

    main

    Rulesync follows symbolic links during file discovery. If a symlink inside your .rulesync/ directory points to a file outside that directory, Rulesync will follow it and copy the resolved file content into the generated output. This allows you to centralize shared skills or rules and reference them via symlinks across multiple projects.

    Security Note: Rulesync does not perform realpath-based boundary checks on individual symlinks. It only resolves the --input-root to an absolute path. Only run Rulesync against directory trees that you trust. Directory symlink cycles are handled safely via deduplication by real path.