Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ rulesync.local.jsonc
**/.opencode/commands/
**/.pi/prompts/
**/.qwen/commands/
**/.reasonix/commands/
**/.roo/commands/
**/.takt/facets/instructions/
**/.devin/workflows/
Expand Down Expand Up @@ -364,6 +365,7 @@ rulesync.local.jsonc
**/.devin/hooks.v1.json
**/.augment/settings.json
**/.vibe/hooks.toml
**/.reasonix/settings.json
**/.cline/command-permissions.json
**/.cursor/cli.json
**/.junie/allowlist.json
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ The tables below show whether each tool supports a given feature (✅ = supporte
| Takt | ✅ | | ✅ | ✅ | ✅ | ✅ | | ✅ |
| Vibe Code | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |
| Qwen Code | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Reasonix | | | ✅ | | | | | |
| Reasonix | | | ✅ | | | | | |
| Kiro ⚠️ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Kiro CLI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Kiro IDE | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Expand Down
8 changes: 7 additions & 1 deletion docs/reference/file-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ Events present in the shared `hooks` block but unsupported by a given tool are s

> **Note:** Qwen Code hooks are written under the top-level `hooks` key of `.qwen/settings.json` (project) / `~/.qwen/settings.json` (global), using Claude-style PascalCase per-matcher arrays (`{ "EventName": [ { "matcher": "...", "sequential": false, "hooks": [ { "type": "command", "command": "...", "timeout": ... } ] } ] }`). Qwen's supported event set **differs from Gemini CLI's**, so rulesync defines a Qwen-specific mapping. Sixteen lifecycle events are supported — `sessionStart` ⇄ `SessionStart`, `sessionEnd` ⇄ `SessionEnd`, `preToolUse` ⇄ `PreToolUse`, `postToolUse` ⇄ `PostToolUse`, `postToolUseFailure` ⇄ `PostToolUseFailure`, `beforeSubmitPrompt` ⇄ `UserPromptSubmit`, `stop` ⇄ `Stop`, `stopFailure` ⇄ `StopFailure`, `subagentStart` ⇄ `SubagentStart`, `subagentStop` ⇄ `SubagentStop`, `preCompact` ⇄ `PreCompact`, `postCompact` ⇄ `PostCompact`, `permissionRequest` ⇄ `PermissionRequest`, `notification` ⇄ `Notification`, `todoCreated` ⇄ `TodoCreated`, and `todoCompleted` ⇄ `TodoCompleted`. Commands are emitted verbatim (no `$GEMINI_PROJECT_DIR` rewriting). Qwen's four hook types are supported: `command`, `prompt`, `http` (which carries a `url` and POSTs JSON to it; the type and URL round-trip), and `function`. Per-hook fields added in [Qwen Code PR #2827](https://github.com/QwenLM/qwen-code/pull/2827) round-trip as well: command hooks carry `async` (run in the background), `env` (extra subprocess environment variables), and `shell` (`bash`/`powershell`); http hooks carry `headers` (with `${VAR}` interpolation), `allowedEnvVars` (the env-var allowlist), and `once` (single execution per event per session); `statusMessage` (progress text) applies to both. Command-only fields are emitted only on command hooks and http-only fields only on http hooks. The group-level `sequential` flag (parallel by default) and the top-level `disableAllHooks` switch are both round-tripped, and other top-level keys in `settings.json` are preserved. See the [Qwen Code hooks docs](https://github.com/QwenLM/qwen-code/blob/main/docs/users/features/hooks.md).

> **Note:** Reasonix hooks are written to a dedicated `.reasonix/settings.json` (project) / `~/.reasonix/settings.json` (global) — a Claude-Code-style but standalone JSON file, separate from the `[permissions]`/`[[plugins]]` TOML config. Unlike Claude Code, each event key maps directly to a **flat array** of hook objects (no `matcher`/`hooks` wrapper): `{ "EventName": [ { "match": "...", "command": "...", "description": "...", "timeout": ... } ] }`. Only four of Reasonix's documented events are mapped — `preToolUse` ⇄ `PreToolUse`, `postToolUse` ⇄ `PostToolUse`, `beforeSubmitPrompt` ⇄ `UserPromptSubmit`, and `stop` ⇄ `Stop` — since the upstream issue scoped the rest (`SessionStart`, `SessionEnd`, `PostLLMCall`, `SubagentStop`, `Notification`, `PreCompact`) as a separate follow-up. `match` (Reasonix's matcher field name) is honored only on `PreToolUse`/`PostToolUse`; a matcher on any other event is dropped with a warning. The canonical `timeout` field is documented in seconds, while Reasonix's `timeout` is milliseconds, so rulesync converts (`× 1000` on generate, `÷ 1000` on import). Only `command`-type hooks are supported. The `settings.json` file is not documented as holding anything besides hooks today, but rulesync merges non-destructively and never deletes it, in case a future Reasonix version adds other keys. See the [Reasonix Hooks guide](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/docs/DESKTOP_HOOKS.zh-CN.md).

## `.github/mcp.json` and `.copilot/mcp-config.json`

Example:
Expand Down Expand Up @@ -283,6 +285,8 @@ The command body itself uses a Claude Code-compatible **universal syntax** (e.g.

> **OpenCode import note:** OpenCode lets commands live both as Markdown files under `.opencode/commands/*.md` **and** inline in `opencode.json`/`opencode.jsonc` under the top-level `command` key. On import, rulesync reads both: each inline entry's `template` becomes the command body and its `description`/`agent`/`model`/`subtask` fields become frontmatter. A Markdown file takes precedence over an inline entry with the same name.

> **Reasonix note:** Custom slash commands are Markdown files under `.reasonix/commands/` (project) / `~/.reasonix/commands/` (global, via `--global`) — directly analogous to Claude Code's `.claude/commands/`, since Reasonix explicitly mirrors Claude Code's conventions. Frontmatter supports `description` and `argument-hint`, and the body uses the same `$ARGUMENTS` / `$1`…`$N` placeholder syntax. Subdirectory namespacing is supported (`git/commit.md` → `/git:commit`). Any extra fields are preserved on round-trip under the `reasonix:` block. See the [Reasonix GUIDE](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/docs/GUIDE.md#slash-commands).

## `rulesync/subagents/*.md`

Example:
Expand Down Expand Up @@ -702,7 +706,7 @@ Subagents live in the `subagents/` subdirectory so the command-recipe and subage

Vibe (mistral-vibe) MCP servers live in `[[mcp_servers]]` arrays of the shared `.vibe/config.toml`. In addition to the flat fields, Rulesync passes through the stdio `cwd` (working directory) and a structured per-server `auth` block (Vibe v2.15.0+). The `auth` table is discriminated on `type`: `static` (`headers`, `api_key_env`, `api_key_header`, `api_key_format`) and `oauth` (`scopes`, `client_id` / `client_metadata_url`, `redirect_port`). Because Vibe rejects mixing legacy top-level static-auth keys with an explicit `[auth]` block, Rulesync suppresses the legacy keys (`headers`/`api_key_env`/`api_key_header`/`api_key_format`) whenever a server carries an `auth` block. See [mistral-vibe](https://github.com/mistralai/mistral-vibe) (`vibe/core/config/_settings.py`).

> **Reasonix note:** MCP servers are written as `[[plugins]]` array-of-tables entries (Reasonix's MCP-compatible external plugins) in `reasonix.toml` (project) / `~/.reasonix/config.toml` (global, via `--global`). Each entry carries a `name` plus the standard transport fields: `type` selects the transport (`stdio` default — `command`/`args`/`env`; `http`, a.k.a. `streamable-http` — `url`/`headers`), and the deprecated `sse` transport is collapsed onto `http`. The file is treated as shared Reasonix config: Rulesync only replaces the `plugins` key and preserves every other table (providers, ui, agent, …) on round-trip, and it is never deleted. Reasonix has no per-server tool allow/deny lists. See the [Reasonix plugins guide](https://github.com/esengine/deepseek-reasonix/blob/main-v2/docs/GUIDE.md#plugins-mcp).
> **Reasonix note:** MCP servers are written as `[[plugins]]` array-of-tables entries (Reasonix's MCP-compatible external plugins) in `reasonix.toml` (project) / `~/.reasonix/config.toml` (global, via `--global`). Each entry carries a `name` plus the standard transport fields: `type` selects the transport (`stdio` default — `command`/`args`/`env`; `http`, a.k.a. `streamable-http` — `url`/`headers`), and the deprecated `sse` transport is collapsed onto `http`. The file is treated as shared Reasonix config: Rulesync only replaces the `plugins` key and preserves every other table (providers, ui, agent, …) on round-trip, and it is never deleted. Reasonix has no per-server tool allow/deny lists, but each plugin entry may carry an optional `trusted_read_only_tools` array (raw MCP tool names pre-seeded as trusted for planner/read-only use); rulesync has no deep canonical mapping for it, so it round-trips as a passthrough field on the canonical MCP server object. See the [Reasonix plugins guide](https://github.com/esengine/deepseek-reasonix/blob/main-v2/docs/GUIDE.md#plugins-mcp) and [SPEC.md](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/docs/SPEC.md) (`[[plugins]]` schema).

## `.rulesync/.aiignore` or `.rulesyncignore`

Expand Down Expand Up @@ -880,4 +884,6 @@ For Amp, this writes to the shared `.amp/settings.json` (project mode) or `~/.co

For JetBrains Junie CLI, this generates the Action Allowlist `rules` object in `.junie/allowlist.json` (project mode) or `~/.junie/allowlist.json` (global mode). Junie evaluates the allowlist top-to-bottom (first match wins) and groups rules into four buckets, onto which rulesync categories map: `bash` → `executables`, `edit`/`write` → `fileEditing`, `read` → `readOutsideProject`, `mcp` → `mcpTools`. Each rule carries an `action` (`allow` | `ask` | `deny`, a 1:1 with rulesync's canonical actions) plus either a literal `prefix` (matches commands that start with it) or a glob `pattern` (`*`, `**`, `?`, `[abc]`, `[!abc]`); rulesync emits `pattern` when the canonical pattern contains a glob metacharacter (`*`, `?`, `[`) and `prefix` otherwise. Categories Junie cannot represent (e.g. `webfetch`, `websearch`) are skipped with a warning when they carry rules. rulesync **owns the `rules` object** (it is replaced from the rulesync output on each generate), while the top-level `defaultBehavior` (defaulting to Junie's documented `ask` when absent) and `allowReadonlyCommands` settings — which have no canonical equivalent — are preserved verbatim on round-trip but not imported back into the rulesync model. Because `edit`/`write` both collapse onto `fileEditing`, importing normalizes back to `edit` (a documented, lossy mapping). The `allowlist.json` file is never deleted. See the [Junie Action Allowlist docs](https://junie.jetbrains.com/docs/action-allowlist-junie-cli.html).

For Reasonix, this generates `permissions.allow`, `permissions.ask`, and `permissions.deny` arrays in the `[permissions]` table of the shared `reasonix.toml` (project mode) or `~/.reasonix/config.toml` (global mode) — the same TOML file the MCP feature's `[[plugins]]` array-of-tables lives in. The rule syntax mirrors Claude Code's: entries are `Bash(<pattern>)`, `Read(<pattern>)`, `Edit(<pattern>)`, `Write(<pattern>)`, `WebFetch(<pattern>)`, `WebSearch(<pattern>)`, `Grep(<pattern>)`, `Glob(<pattern>)`, `NotebookEdit(<pattern>)`, `Agent(<pattern>)`, etc. (Reasonix's SPEC.md documents these as "Claude Code-style" families; `agent` → `Agent` is the one lower-confidence mapping, since Reasonix's own delegation tool is internally named `task`). `[permissions].mode` (the writer fallback: `ask`/`allow`/`deny`) has no canonical rulesync equivalent and is preserved untouched. The TOML file is shared with the MCP feature, so writes only replace the `permissions` table — every other table (`[[plugins]]`, `[agent]`, `[ui]`, …) is preserved on round-trip, and the file is never deleted. See [SPEC.md §3.7 Permissions](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/docs/SPEC.md).

> **Note: Interaction with ignore feature.** Both the ignore feature and the permissions feature can manage `Read` tool deny entries in `.claude/settings.json`. When both features configure the `Read` tool, the **permissions feature takes precedence** and a warning is emitted. If you only need to restrict file reads based on glob patterns, use the ignore feature (`.rulesync/.aiignore`). Use permissions only when you need fine-grained `allow`/`ask`/`deny` control over the `Read` tool.
2 changes: 1 addition & 1 deletion docs/reference/supported-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Rulesync supports both **generation** and **import** for All of the major AI cod
| Takt | takt | ✅ 🌏 | | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | | ✅ 🌏 |
| Vibe Code | vibe | ✅ 🌏 | ✅ | ✅ 🌏 | | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 |
| Qwen Code | qwencode | ✅ 🌏 | ✅ | ✅ 🌏 🔧 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 |
| Reasonix | reasonix | | | ✅ 🌏 | | | | | |
| Reasonix | reasonix | | | ✅ 🌏 | ✅ 🌏 | | | ✅ 🌏 | ✅ 🌏 |
| Kiro ⚠️ | kiro | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Kiro CLI | kiro-cli | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ | ✅ | ✅ 🌏 | ✅ | ✅ |
| Kiro IDE | kiro-ide | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ |
Expand Down
Loading
Loading