Plan each sync before writing, record the plan in .ai-config-transaction.json,
and roll an interrupted destination back from its backups on the next run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Skip the semantic-search skill while semantic retrieval is disabled and remove
a setup-owned copy when it is turned off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Create <destination>/.ai-config.lock exclusively while syncing so parallel
installs or updates fail instead of interleaving writes. A lock left by an
exited process of the same shell on the same host is replaced.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Write config.toml, settings.json, the manifest, and every other managed file to
a temporary sibling and rename it over the target, so an interrupted run
cannot leave a partly written file. Previously only SKILL.md was replaced
this way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Windows PowerShell pipes re-encode text by console code page: under code page
65001 a BOM broke the config.toml merge, and otherwise non-ASCII characters
became question marks. Pass managed and merged content through files, and
decode piped input as utf-8-sig.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Windows PowerShell 5.1's -Encoding UTF8 always prepends a BOM, and
Get-FileHash returns uppercase hex. Bash's manifest reader expects neither,
so a manifest written by this module and later read by the Bash
equivalent (or vice versa) mismatched on every single entry: the BOM
folded into the header's first field, and every hash comparison failed on
case alone. Hashes are now lowercased on read and write, and the manifest
file itself is written UTF-8 without a BOM.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds Sync-ManagedDestination and its manifest helpers: a per-destination
TSV of path -> SHA-256 that makes installation idempotent (unchanged files
are neither rewritten nor backed up), detects files this setup previously
installed that the source no longer ships (removed after backup, unless
changed locally, in which case they are backed up and left in place with
a warning), and never touches a file it never installed. Backups for a
run land together under backups/<stamp>/ instead of one suffix per file.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>