Add aperio-sync skill for keeping local main current#42
Conversation
A self-locating bash script under .factory/skills/aperio-sync/scripts/ that fast-forwards the local main branch to origin/main without touching the working tree or any feature branch. Refuses non-fast-forward updates and clobbers nothing. Ships with macOS (launchd) and Linux (systemd user timer) templates plus a cron fallback so the sync can run hourly without manual intervention. The Factory SKILL.md frontmatter makes Droid invoke this whenever the user asks to pull / refresh / update / sync the Aperio repo. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
|
Droid finished @dcoln25-writer's task —— View job Code ReviewReviewed 4 candidate findings for the new
One cosmetic [P3] about the inaccurate The skill is otherwise well-scoped and non-destructive — fast-forward-only semantics, safe quoting, and |
|
Droid finished @dcoln25-writer's task —— View job Validation complete for PR #42 Reviewed all 3 candidate findings against the full diff and existing PR discussion. Approved and posted 3 inline comments: the "any working directory" invocation is broken, the macOS No approved item duplicated an existing PR comment. |
P1 systemd: ~/.local/state never created. install-systemd.sh now mkdir
-ps it (and ~/.config/systemd/user) before installing the unit files.
P2 sed escape: replace-text wasn't escaped, so paths containing & or |
corrupted the generated plist. install-launchd.sh now generates the
plist programmatically via python3 plistlib instead of sed-templating
XML, which sidesteps both sed-replacement escape and XML entity
encoding (verified with a /tmp/R&D Test/ stress test; xmllint and
plutil -lint both pass and the path round-trips bit-exact through
plistlib.load). install-systemd.sh uses an explicit sed_escape that
handles backslash, & and | for the systemd unit file (which doesn't
need XML escaping).
P2 worktree detection: replace the [[ ! -d "${repo}/.git" ]] check
(false-negative in linked worktrees and submodules where .git is a
file) with git -C ${repo} rev-parse --is-inside-work-tree.
P2 stdout/stderr separation: drop 2>&1 on both git fetch invocations so
git's progress and failure reasons stay on stderr where the launchd
and systemd log routing expects them. The if ! ... check still
detects non-zero exit codes.
P2 worktree-aware main handling: enumerate git worktree list --porcelain
and if main is checked out in any worktree, run git -C <that wt> pull
--ff-only there instead of trying to update a checked-out ref. This
makes the advertised feature-branch-while-updating-main flow work for
the standard multi-worktree setup.
P2 cwd-dependent docs: drop the git rev-parse --show-toplevel snippets
that fail when run from /tmp. SKILL.md now requires an explicit cd
into the clone before any command, and the schedule install path is
reduced to running install-launchd.sh / install-systemd.sh, which
self-locate from $0.
Also: quote __SCRIPT_PATH__ in the systemd service template so clone
paths containing spaces don't get split into multiple ExecStart args.
Drop com.aperio.sync.plist.template (no longer used now that the
installer generates the plist via plistlib).
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
|
Droid finished @dcoln25-writer's task —— View job Validation complete for PR #42 Validated all 3 candidate findings against the full diff and existing PR discussion; all 3 were approved as actionable and non-duplicative, and all 3 were posted in a single batched review. Approved findings:
|
|
Droid finished @dcoln25-writer's task —— View job Validation complete for PR #42 Reviewed all 1 candidate against the full diff and existing PR discussion. Approved and posted 1 non-duplicative inline comment: the Linux systemd installer still mishandles legal clone paths containing a double quote, which can leave the generated unit unloadable. Saved the structured validation result to |
|
Droid finished @dcoln25-writer's task —— View job Validation complete for PR #42 Validated all 2 candidates against the full diff and existing PR discussion. Both findings are actionable and non-duplicative, and both were posted in a single batched review. Saved the structured result to |
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
|
Droid finished @dcoln25-writer's task —— View job Validation complete for PR #42 Validated all 2 candidates against the full diff and existing PR discussion. Both were approved as actionable and non-duplicative enough to post in a single batched review: one catches stale Saved the structured result to |
Add
aperio-syncskill to keep local main in sync withorigin/mainAdds a Factory droid skill under
.factory/skills/aperio-sync/plus a portable, self-locating bash script and scheduler templates for macOS, Linux, and cron.What's included
Behaviour
The script is non-destructive by design:
<repo>/.factory/skills/aperio-sync/scripts/sync.sh→<repo>), so it works from any clone path without hardcoded usernames or directories.git fetch --prune --tags originmainis not the current branch, updates the localmainref directly viagit fetch origin main:main— this refspec refuses non-fast-forward updates, so divergent history surfaces as a clear error instead of being clobbered.mainis the current branch, runsgit pull --ff-only— uncommitted changes and divergence both fail loudly.already up to dateorfast-forwarded abc1234 -> def5678 (N commits).Never force-pushes. Never resets. Never touches your working tree when you're on a feature branch.
Smoke-tested locally
Run from outside the repo (
/tmp):Run on a stale clone (111 commits behind):
Manual usage
Hourly schedule (macOS)
Logs land at
~/Library/Logs/aperio-sync.logand~/Library/Logs/aperio-sync.err.log.Hourly schedule (Linux, systemd user timer)
See the Scheduled invocation section of the SKILL.md for the systemd snippet.
Droid integration
The
descriptionin the SKILL frontmatter is keyword-matched by the Factory droid runtime. Anytime a user says "pull / refresh / update / sync the Aperio repo" — or starts work in this repo with stalemain— Droid will invoke this skill and run the script.