---
title: Agent Instructions Sync
---

# Agent Instructions Sync

## What it is

A per-project background job that takes the instructions file Claude Code reads on every turn — your `CLAUDE.md` — and **automatically keeps copies of it** at the other filenames that other agents look for: `AGENTS.md` (used by Codex, Gemini, Cursor, Factory, and other "agent-aware" tools that have settled on `AGENTS.md` as the cross-vendor convention), `GEMINI.md` (Gemini CLI), `.cursorrules` (Cursor's legacy file), `.clinerules/base.md` (Cline), `.github/copilot-instructions.md` (GitHub Copilot), and `.windsurfrules` (Windsurf).

The point is that you maintain one source-of-truth file (your `CLAUDE.md`, which we'll call the **canonical** from here on), and every other agent in the project sees the same rules without you having to copy-paste them N times or remember to keep N files in sync. You can also flip the canonical to `AGENTS.md` instead, in which case `CLAUDE.md` becomes a mirror — the direction is your call.

The feature is **off by default**. Default Claude Code users see no behavior change: no new files appear in their projects, nothing gets written, the sidebar looks the same. You opt in once in Settings, pick the file list, and the sync runs from then on.

### Why this exists

The world has not converged on one filename for "instructions that every AI agent in this project should follow." Claude Code reads `CLAUDE.md`. The newer agent-aware tools (Codex, Gemini, Cursor, Factory…) have settled on `AGENTS.md`. Cursor's legacy file is `.cursorrules`. Cline reads `.clinerules/base.md`. GitHub Copilot reads `.github/copilot-instructions.md`. Windsurf reads `.windsurfrules`. Gemini CLI reads `GEMINI.md`. If you work in a project with more than one agent — even just Claude Code + your editor's Copilot — you have either (a) two copies of the same rules to keep in sync by hand, or (b) one of them is stale.

This feature collapses the "by hand" problem into one click in Settings. You write one file; Omniscio keeps the rest in sync; you get an explicit safety dialog when something has drifted instead of a silent overwrite.

Default-off is deliberate: a user whose only agent is Claude Code shouldn't have to look at, learn about, or be surprised by any of these other files. The feature only appears in the sidebar (the "Synced mirrors" subsection) when there's actually a synced mirror to show.

## Where to find it

### Where to turn it on

Settings → Features → **Agent Instructions Sync**. The section has three controls:

1. **Enabled** toggle (off by default). When you flip this on the first time, a one-shot sync runs immediately against every project that has a canonical file present.
2. **Canonical file** — radio between `CLAUDE.md` (default) and `AGENTS.md`. Whichever you pick is the source-of-truth; the other becomes a mirror you can opt into.
3. **Mirrors** — multi-select list of the other filenames. Each entry shows a friendly label after the filename: `AGENTS.md (Codex, Gemini, Cursor, Factory…)`, `GEMINI.md (Gemini CLI)`, `.cursorrules (Cursor legacy)`, etc. Picking a mirror in the list is what tells Omniscio "yes, write this file too."

There is no per-project override. The setting is global — once enabled, every project that has the canonical present gets the same mirror list. Projects that don't have a canonical file are silently skipped (nothing is created from nothing).

### The sidebar surface

Open any project. In the right-hand Dashboard sidebar, expand the **Auto Context (N)** group near the bottom and look at the **System Instructions** sub-group (the first of the three sub-groups, listing `project CLAUDE.md`, `project MEMORY.md`, `global CLAUDE.md`, `global MEMORY.md` — see [claude-files-sidebar.md](claude-files-sidebar.md) for the sub-group itself). Below those four rows, if you've enabled sync and the project has any synced mirrors, you'll see a small **Synced mirrors** subheader (a branch icon + the label, uppercased to match the other Auto Context sub-groups) and one row per mirror with:

- The filename on top (e.g. `AGENTS.md`, `.cursorrules`).
- A second line with `<mtime>` and a small **status chip**: green dot `in sync`, blue dot `out of sync` (stale — see case 5 above; auto-refreshes on the next sync pass), amber dot `edited externally` (drift — case 6, real external edit after a recorded baseline), muted gray dot `still tracked in git` (tracked-in-git — the local-mode git-revert overlay on case 6), muted gray dot `needs first sync` (pending-baseline — case 7, day-zero state with no recorded baseline), muted gray dot `manual file` (case 8, no banner), or no chip if the mirror file is still missing (steady state until the first sync).

Clicking an `in sync`, `out of sync`, or `manual file` row opens the file in Omniscio's peek overlay so you can read it inline — same overlay as the four System Instructions rows above. The blue `out of sync` chip is informational only; no action is required because the watcher (or the next manual sync, or the next session spawn) will auto-refresh it. Clicking the amber `edited externally` chip, the muted `needs first sync` chip, OR the muted `still tracked in git` chip opens the **conflict resolution dialog**. `edited externally` and `needs first sync` share the same three actions and branch only the wording; `still tracked in git` opens a one-action mode whose only button is **Stop tracking in git**.

Synced-mirror rows inherit the System Instructions sub-group's bulk-select exemption: even with the Auto Context panel in multi-select mode, mirror rows render plain (no checkbox slot) and never appear in the selection count. A stray Ctrl+A + Delete that hits Always-inject and On-demand context will not touch a `.cursorrules` or `AGENTS.md` mirror.

### Turning it off without losing files

Flip the **Enabled** toggle off. The watcher stops; no new writes happen; no existing files are deleted. Every mirror file that's already on disk stays exactly where it is, banner and all, with the body it had at the last successful sync. If you turn the toggle back on later, Omniscio re-probes and resumes — files that haven't changed in the interim go straight back to `in sync`, files that have changed externally during the off-period show up as `edited externally` and wait for your decision.

If you want to delete the banner from a mirror so it's a "clean" file again, just edit it (or use Promote, then delete the mirror by hand). Omniscio will see the missing banner on the next sync and treat the file as `manual file` from then on — it won't try to recover the banner.

## How it behaves

### How sync works (one canonical, N mirrors)

When the canonical changes — you edit it in Omniscio, an agent edits it during a session, or you edit it in an external editor — Omniscio notices via a `chokidar` file watcher and runs the sync for that project. A change to a file under `.claude/rules/` counts too, for the reason in step 1. For each mirror in your list, Omniscio:

1. Reads the canonical file's body — **plus, when your project has a `.claude/rules/` directory, every file in it.** That directory is where Claude Code reads one-file-per-topic rule files, and they are loaded on every turn exactly as `CLAUDE.md` is; the other agents never read `.claude/` at all, so a mirror carrying only the canonical would hand Codex or Gemini a table of contents and silently drop every rule kept in a topic file. A project with no `.claude/rules/` directory produces exactly the same mirror body as before.
2. Builds a small **banner** (a short HTML-style comment block at the top) that says "this file is auto-managed by Omniscio, edits will be overwritten."
3. If the mirror file **doesn't exist yet** → writes `<banner>\n\n<canonical body>` atomically (temp file + rename) and the row in the sidebar shows `in sync`.
4. If the mirror file **exists with the same body as the current canonical** (banner stripped, hash matches) → no-op, row shows `in sync`.
5. If the mirror file **exists with a different body but matches the hash Omniscio last wrote into it** → the canonical has moved on while the mirror was left untouched. This is **stale**, not drift. Omniscio auto-overwrites the mirror with the new canonical body — same as case (3) — without prompting. The row briefly shows `out of sync` in blue before flipping back to `in sync`.
6. If the mirror file **exists with a different body, and Omniscio has a recorded baseline hash for it but the body doesn't match that hash either** → the file was edited externally since the last sync. Omniscio does NOT overwrite it. The row shows `edited externally` in amber, and clicking the chip opens the conflict resolver (see below).
7. If the mirror file **exists with a different body, but Omniscio has NO recorded baseline hash for it** → this is the day-zero / first-sync state. Omniscio literally has no way to tell whether the on-disk copy is "what Omniscio wrote before it started tracking baselines" or "what the user edited." It refuses to overwrite either way. The row shows `needs first sync` in muted gray, and clicking the chip opens the same conflict resolver — but the wording is neutral ("first-time sync review" instead of "edited externally") because you have not done anything wrong. This happens on a fresh install with pre-existing mirrors, after a sidecar wipe, or for mirrors that were written before Omniscio started recording baselines.
8. If the mirror file **exists but has no banner** → Omniscio treats this as a manual file you didn't intend for it to manage. The row shows `manual file` in muted gray and Omniscio never touches it. You can still take ownership later by deleting the file and re-running the sync, or by promoting the manual file to canonical.

The banner is what makes the round-trip safe: Omniscio only touches files it has previously stamped. A `.cursorrules` you wrote by hand before enabling sync is never silently overwritten.

The **stale-vs-drift distinction** (cases 5 vs 6) is what stops the "edited externally" chip from getting stuck. Omniscio remembers — in a small sidecar file at `<userData>/agent-instructions-sync-state.json` — the exact hash it last wrote into each mirror. When the canonical changes, every mirror that still equals Omniscio's last write is recognized as stale and auto-refreshed. A user edit, even a single byte, breaks that hash equality and we fall through to drift (case 6) so you get the safety dialog.

The **drift-vs-pending-baseline distinction** (cases 6 vs 7) is the labelling split that stops the "edited externally" chip from being misleading for users who never touched the file. Both cases refuse to overwrite the mirror — that's the load-bearing safety behavior — but they say different things in the UI. `drift` (we have a baseline and the mirror moved away from it) keeps the accusatory amber "edited externally" wording. `pending-baseline` (we have no baseline for this mirror) gets neutral muted "needs first sync" wording. The on-disk decision is identical; only the chip color and the modal copy change.

The **tracked-in-git overlay** (a refinement of case 6) catches the most common cause of a _false_ drift flag: in git mode `local`, if a mirror reads as `drift` but is **still tracked in git**, the "edit" is almost always git itself — a branch merge restoring the old committed copy over Omniscio's fresh write, which the drift guard can't tell apart from a human edit. When `IMPORTANT_FILES_PROBE` sees a `drift` row in local mode whose mirror is in `git ls-files`, it relabels that row `tracked-in-git`: a calm muted "still tracked in git" chip instead of the accusatory amber "edited externally", and clicking it opens the resolver in a one-action mode whose fix is **Stop tracking in git** — not discard/promote, because re-syncing a tracked copy just gets reverted by the next merge. The check is gated to local mode and to rows that are actually drift, so default and in-sync projects never pay the extra git lookup. See the `git-lifecycle contract` (`a-tracked-mirror-in-local-mode-reads-as-tracked-in-git`).

The watcher also runs an **echo guard** — when Omniscio itself writes a mirror, the chokidar event that fires for that write is matched against Omniscio's own outgoing-write fingerprint and discarded, so you don't get a feedback loop where Omniscio re-syncs in response to its own writes.

### How copies are handled in git

The mirrors are **generated** from your canonical file, which makes committing them to version control awkward: a generated file that something keeps rewriting churns on every merge, and you can end up with a stale committed copy that triggers a false "edited externally" flag. Omniscio gives you an explicit choice under Settings → Features → Agent Instructions Sync — **"How copies are handled in git"** — with two modes. Like the rest of the feature the setting is global (no per-project override), and the git work only ever touches folders that are real git repositories — a non-git project folder is left completely alone.

**Local — kept out of git (the default, recommended).** Omniscio maintains a clearly-marked block in your project's `.gitignore` that lists the copy filenames, so git ignores them. The copies live only on your machine and are rebuilt from the canonical; git never tracks them, so a merge can never clobber them and a merge can never produce a false drift flag. If you already committed some copies before switching to (or starting in) this mode, the settings panel shows how many are still tracked and offers a one-click **"Stop tracking copies in git"** button — it runs `git rm --cached` on each, which removes them from git's index while **keeping the file on your disk**. The same one-click fix is also surfaced right on the System Instructions sidebar (next section), so you don't have to hunt through Settings — a copy stuck in this state shows a calm "still tracked in git" chip that opens the fix directly.

**Committed — kept in git (opt-in).** For repositories you share with people who use Codex, Gemini, or other tools _without_ Omniscio running — they need the copy files physically present in the repo. In this mode Omniscio removes the `.gitignore` block and installs a small `post-merge` / `post-rewrite` git hook that **re-derives every copy from the canonical after a merge or rebase**, so a merge can't leave a copy stale. The hook is written as a clearly-marked section that never overwrites an existing hook, and Omniscio skips installing it entirely if your repo manages its own hooks (for example via Husky, which sets `core.hooksPath`) — in that case the copies still stay merge-safe because of the stable banner (below), and you simply commit the regenerated copies alongside your canonical edits.

**The stable banner.** The banner Omniscio stamps at the top of every copy used to include the exact time of the write. That meant two branches that both re-synced a copy produced _different_ files — the timestamps differed — even when the rules were identical, so every merge collided on that line. The banner no longer carries a timestamp: identical rules now produce byte-identical copies, which is what makes both git modes merge-clean. This changes nothing about drift detection — the "did someone hand-edit this?" hash has always been computed with the banner stripped off, so it never depended on the timestamp.

### Drift also raises an inbox alert

The sidebar chip is **passive** — you only see it if you happen to be looking at that project's Dashboard, so a drifted mirror can sit unnoticed for weeks. Since 2026-08-17, Omniscio ALSO surfaces drift in your **inbox**. A small background watchdog (`src/main/services/agent-instructions-sync/drift-watchdog.ts`) checks every project's mirrors on a schedule (a couple of hours apart) and, when a mirror has read `edited externally` (drift) for two consecutive checks, raises **one deduped inbox card** — e.g. "`AGENTS.md` was edited outside Omniscio." The card **clears itself** the moment the mirror is back in sync. It raises only on real `drift` — never the neutral `needs first sync` (pending-baseline), the auto-healing `out of sync` (stale), or a `manual file`.

The card's **Review & fix** button opens the same conflict resolver the sidebar chip opens (next section): view the file, **Sync now** (discard the external edit and re-sync from the canonical), **Stop syncing**, or a **Sync settings** link straight to the feature's settings — so whether you spot the drift on the Dashboard or in your inbox, the one-click fix is identical.

The watchdog is READ-ONLY — it never writes a mirror, it only probes and alerts. It self-gates on the **Enabled** setting (turning the feature off clears the cards it raised), skips headless / test runs (`AMC_INSTANCE_ID`, kill-switch `AMC_DISABLE_INSTRUCTION_DRIFT_WATCHDOG=1`), and caps how many cards it raises per check so a many-project drift can't flood the inbox. Under the hood it is a standard inbox alert (`raiseAgentAlert`, dedupKey `agent-instructions-drift:<mirror>:<projectId>`, with a one-click action registered per `inbox-alert-contract` I20).

### Resolving an "edited externally" or "needs first sync" conflict

When Omniscio refuses to overwrite a mirror, the dialog opens for three different reasons:

- **"edited externally"** — Omniscio had a recorded baseline hash for this mirror and the on-disk body moved away from it. Something edited the file directly (the agent that file drives, a human teammate, an external editor) since the last successful sync.
- **"needs first sync"** — Omniscio has no recorded baseline hash for this mirror. The on-disk body differs from the canonical, but Omniscio literally cannot tell whether you edited it or it's just the day-zero state (fresh install with pre-existing mirrors, sidecar wiped, or mirrors written before Omniscio started tracking baselines). You have not done anything wrong; this is a one-time setup step.
- **"still tracked in git"** — git mode is `local` and the copy is still tracked in git, so a branch merge keeps restoring the old committed copy over Omniscio's write. This is not an edit you made. This mode shows ONE action — **Stop tracking in git** (`git rm --cached`, file kept on disk) — because that is the only durable fix; discard or promote of a tracked copy just gets reverted by the next merge.

The first two reasons surface the same three actions below (only the title and copy differ); "still tracked in git" replaces them with the single untrack action. Default focus is **Cancel** so pressing Enter never writes anything by accident.

1. **Discard edits — restore from `<canonical>`** (red, destructive; reads "Overwrite `<mirror>` with `<canonical>`" in the pending-baseline variant). Force-overwrites the mirror with the current canonical body + a fresh banner. The external edits (or the day-zero content) are gone. Use this when the external edit was a mistake (the agent went off-script), when you've already merged the useful parts back into the canonical by hand, or — for pending-baseline — when you want the canonical to be the source of truth going forward.
2. **Promote to canonical** (amber, warning). Reads the mirror body, **strips the banner from it**, atomic-writes the result over the canonical file. The mirror itself is left alone — but on the next sync pass it'll get a fresh banner re-applied because its body now matches the new canonical. Use this when the external edit was actually good and you want it to become the new source-of-truth.
3. **Stop syncing this mirror** (ghost button). Removes this mirror from your `agentInstructionsSyncMirrors` setting and pushes a `SETTINGS_CHANGED` event so the watcher reconciles its set. The file on disk is untouched — banner and all — but Omniscio will never write it again. Use this when you've decided this particular file should be hand-managed going forward.

The dialog also shows the canonical body and the mirror body as two side-by-side `<pre>` blocks so you can eyeball the divergence. It's not a line-diff view — the question this dialog answers is "which copy do I want to keep?", not "what changed line-by-line?". If you need a real diff, both files are on disk; use your normal diff tool.

**Important non-behavior**: a promote in one mirror does NOT auto-overwrite _other_ mirrors that were in sync with the old canonical. Those mirrors become `drift` conflicts at the next sync pass and each one needs its own explicit user resolution. This is conservative on purpose — silent N-way overwrite from a single promote is the kind of "I lost work" footgun the feature is specifically designed not to have.

### The seven recognized mirror files

| Filename                          | Used by                                                          |
| --------------------------------- | ---------------------------------------------------------------- |
| `AGENTS.md`                       | Codex, Gemini, Cursor (modern), Factory, other agent-aware tools |
| `CLAUDE.md`                       | Claude Code (this is also a valid canonical — pick one)          |
| `GEMINI.md`                       | Gemini CLI                                                       |
| `.cursorrules`                    | Cursor (legacy filename)                                         |
| `.clinerules/base.md`             | Cline                                                            |
| `.github/copilot-instructions.md` | GitHub Copilot                                                   |
| `.windsurfrules`                  | Windsurf                                                         |

This list is closed — adding a new agent's filename requires a code change (it's a TypeScript discriminated union, not a free-form string). The reason it's closed is the path-escape guard: Omniscio validates that every mirror path resolves under the project workdir, so we don't accidentally write `../../etc/passwd` if a settings file is hand-edited maliciously. A free-form list would mean every renderer-supplied mirror gets re-validated on every sync.

## For agents

### How it works under the hood

**Settings** — four fields on `AppSettings` in `src/shared/types.ts`: `agentInstructionsSyncEnabled` (boolean, default `false`), `agentInstructionsSyncCanonical` (`'CLAUDE.md' | 'AGENTS.md'`, default `'CLAUDE.md'`), `agentInstructionsSyncMirrors` (`AgentInstructionsMirror[]`, default `[]`), and `agentInstructionsSyncGitMode` (`'local' | 'committed'`, default `'local'` — see "How copies are handled in git" above). All four are wired through `updateSettingsSchema` so Zod doesn't strip them on save.

**Sync service** — `src/main/services/agent-instructions-sync/sync-service.ts`. Pure function, no IPC and no DB and no electron imports — takes a workdir, a canonical filename, and a mirror list, and returns a `SyncResult` envelope `{ written, skipped, conflicts, errors, canonicalMissing }`. Since 2026-06-12 the per-mirror classify-and-write is delegated to the shared **mirror-sync engine** (`src/main/services/mirror-sync/`, the same machinery the skills sync now uses) — behavior is identical (the same stale-vs-drift decision and atomic banner write), with an `AMC_LEGACY_INSTRUCTIONS_SYNC=1` env kill-switch that reverts to the previous in-line path. Three public functions:

- `syncProjectInstructions(workdir, canonical, mirrors)` — the main one. Per-mirror behavior follows the seven rules in "How sync works" above (the original five plus the stale-detection branch added 2026-05-23). Atomic writes (`.amc-tmp` + rename) so a crash mid-write never leaves a half-file on disk.
- `forceWriteMirror(workdir, canonical, mirror)` — backing call for the conflict dialog's "Discard edits" action. Bypasses the drift / not-amc-managed checks. Records the new hash so the mirror enters the auto-refresh loop next canonical edit.
- `promoteMirrorToCanonical(workdir, canonical, mirror)` — backing call for "Promote." Strips banner from mirror, atomic-writes the body to canonical.

**Sync state store** — `src/main/services/agent-instructions-sync/sync-state-store.ts`. Sidecar file at `<userData>/agent-instructions-sync-state.json` (schema `1`) that remembers, per workdir, the canonical's last-written hash and a map of `mirror → last-written-hash`. This is the memory that lets the sync service distinguish stale (auto-refresh) from drift (ask). ENOENT and malformed JSON degrade to empty state without throwing — a corrupted sidecar can only ever cause a one-off conflict dialog, never silent data loss.

**Banner** — `src/main/services/agent-instructions-sync/banner.ts`. `buildBanner(canonicalFile)` (takes NO timestamp — byte-stable, so identical rules produce byte-identical mirrors; this is the merge-safety fix), `hasBanner`, `stripBanner`, `hashContent`. The hash is computed over the body with the banner stripped, so a freshly-written mirror and the canonical it came from always hash equal even though the mirror has the extra banner line — and a banner change never reads as content drift.

**Watcher** — `src/main/services/agent-instructions-sync/watcher.ts`. One chokidar watcher per project that's enrolled in sync; debounced (1 s) so a burst of saves coalesces to one sync. Echo guard via outgoing-write fingerprint set, so Omniscio's own atomic writes don't re-trigger the watcher. Reconciles its watched-project set on `SETTINGS_CHANGED` and `PROJECTS_CHANGED` push events. Virtual projects (anything with a `folderPath` like `__claude__`) are never watched.

**IPC** — five channels on `src/shared/ipc-channels/index.ts`:

- `AGENT_INSTRUCTIONS_SYNC_NOW` — manual "sync this project now" trigger; surfaced as a button in the Features settings card.
- `AGENT_INSTRUCTIONS_SYNC_PROBE` — read-only state probe used by the sidebar and the conflict dialog.
- `AGENT_INSTRUCTIONS_SYNC_RESOLVE` — discriminated `{ action: 'discard' | 'promote' | 'stop-syncing' }` for the conflict dialog. Routes to `forceWriteMirror`, `promoteMirrorToCanonical`, or a settings-filter + `SETTINGS_CHANGED` emit.
- `AGENT_INSTRUCTIONS_SYNC_UNTRACK` — `git rm --cached` every committed mirror (keeps the file on disk); backs the "Stop tracking copies in git" button in Settings AND the System Instructions panel's `tracked-in-git` resolver mode.
- `AGENT_INSTRUCTIONS_SYNC_GIT_STATUS` — read-only git lifecycle status (how many mirrors are still tracked, whether the `.gitignore` block / regeneration hook is installed) for the settings panel.

**Git lifecycle** — `src/main/services/agent-instructions-sync/git-lifecycle.ts`. Owns the managed `.gitignore` block, the `git rm --cached` untrack, and the committed-mode `post-merge` / `post-rewrite` regeneration hook. Reconciled after every sync (the `SYNC_NOW` handler) and on settings/project changes (the watcher), gated so a feature-OFF install does zero git work. Full invariants + safe-change rules: `agent-instructions-sync-git-lifecycle-contract.md`.

**Sidebar UI** — one renderer, used on both desktop and mobile, rendering the `syncedMirrors` payload from `IMPORTANT_FILES_PROBE`:

- `src/renderer/src/features/dashboard/SystemInstructionsGroup.tsx` — the System Instructions sub-group inside the Auto Context panel (`src/renderer/src/features/dashboard/ProjectDocsSection.tsx`), mounted by `SessionsSidebar` on desktop and `MobileSessionsList` on mobile. The synced-mirrors block renders below its four rows when the probe returns any. (Before 2026-06-03 mobile shipped a separate `ImportantFilesSection`; it was removed when mobile was unified onto the shared panel.)
- Status chip: `src/renderer/src/features/dashboard/agent-instructions-chip.ts`. The renderer calls the `syncStatusChip(status)` helper so the green / blue / amber / gray status chip's dot color and label text live in exactly one file, and TypeScript exhaustiveness on the `SyncStatus` union catches any new state that forgets to add a case.
- Shared routing helpers: `src/renderer/src/features/dashboard/probe-instructions.ts` exports `CONFLICT_MODAL_STATUSES`, `routesToConflictModal(status)`, and `conflictModalStatus(status)` so "which statuses open the resolver, and in which mode" lives in one place (wired once for the single renderer). The `tracked-in-git` relabel itself is the pure `src/main/services/agent-instructions-sync/tracked-in-git.ts` `overlayTrackedInGit`, applied in the `IMPORTANT_FILES_PROBE` handler — which calls `getMirrorGitStatus` only when a `drift` row exists in git mode `local`.

**Conflict dialog** — `src/renderer/src/features/dashboard/AgentSyncConflictModal.tsx`. Lazy-loaded (`React.lazy`) per the heavy-modal rule so it doesn't get hoisted into the entry chunk. Built on `DialogShell`. Default focus is Cancel because every action either writes to disk or changes settings/git with no Omniscio-level undo. Three modes keyed on `syncStatus`: `drift` and `pending-baseline` share the discard / promote / stop-syncing actions and branch only the copy; `tracked-in-git` shows a single **Stop tracking in git** action (the `AGENT_INSTRUCTIONS_SYNC_UNTRACK` IPC) under a calm, non-amber `GitBranch` heading.

## Related

- [claude-files-sidebar.md](claude-files-sidebar.md) — the **System Instructions** sub-group of the Auto Context panel, which hosts the synced-mirrors block as a second section below its four CLAUDE.md / MEMORY.md rows.
- [project-docs-auto-injection.md](project-docs-auto-injection.md) — the parent **Auto Context** feature: search filter, the three sub-groups (System Instructions + Always-inject + On-demand context), and how `.claude/docs/` files reach the agent. Different mechanism from sync — auto-injection is first-message context, not file mirroring.
- [project-docs-selection.md](project-docs-selection.md) — bulk select / copy / delete on the other two Auto Context sub-groups. Synced mirrors inherit System Instructions' bulk-select exemption and never participate.
