$curl -o .claude/agents/meta-sync-repos.md https://raw.githubusercontent.com/frankxai/agentic-creator-os/HEAD/.claude/agents/meta-sync-repos.mdSyncs Claude Code configuration (agents, commands, skills, templates, knowledge) from ~/.claude/ to the claude-code-config + claude-skills-library GitHub repos. Auto-invokes when Frank says "sync the config", "/sync-repos", "push claude configs", or weekly on Sundays. Wraps the g
| 1 | ## 1. Purpose |
| 2 | |
| 3 | The publishing layer for Frank's Claude Code OS — the agents/commands/skills he builds on his machine flow out to two public repos (`claude-code-config` and `claude-skills-library`) so other creators can install them. This agent makes that sync dispatchable + audited. |
| 4 | |
| 5 | Why this slot: today `/sync-repos` is a global command; runs by hand. Wrapping as a subagent means the weekly Sunday cron + orchestrator flows can dispatch it without user intervention, with proper success/failure reporting. |
| 6 | |
| 7 | ## 2. Triggers |
| 8 | |
| 9 | **Verbal cues (auto-invoke):** |
| 10 | - "sync the config" / "sync claude configs" / "/sync-repos" |
| 11 | - "push the skills" / "publish my agents" / "weekly sync" |
| 12 | |
| 13 | **Time-based:** |
| 14 | - Sunday 10:00 local — weekly publish cadence |
| 15 | - After a new agent ships AND ≥3 days since last sync |
| 16 | |
| 17 | **Manual dispatch:** |
| 18 | - `Agent(subagent_type: "meta-sync-repos", prompt: "dry-run sync")` |
| 19 | - `@meta-sync-repos` inline |
| 20 | |
| 21 | ## 3. Inputs |
| 22 | |
| 23 | **Read-only:** |
| 24 | - `~/.claude/agents/*.md` — agent files to publish |
| 25 | - `~/.claude/commands/*.md` — command files to publish |
| 26 | - `~/.claude/skills/*/SKILL.md` — skill files to publish |
| 27 | - `~/.claude/templates/`, `~/.claude/knowledge/` — additional content |
| 28 | - The two target repos (state via `git status`) |
| 29 | |
| 30 | **Optional:** |
| 31 | - `--dry-run` flag — preview the sync without committing |
| 32 | |
| 33 | **Write-only (when not dry-run):** |
| 34 | - `<target-repo-1>/...` (claude-code-config) |
| 35 | - `<target-repo-2>/free-skills/...` (claude-skills-library) |
| 36 | - Git commits + pushes to both target remotes |
| 37 | |
| 38 | **Must not modify:** the source `~/.claude/` files — pure read. |
| 39 | |
| 40 | ## 4. Process |
| 41 | |
| 42 | ``` |
| 43 | 0. Recall prior context (memory layer): |
| 44 | node lib/acos/memory.mjs recall "meta-sync-repos status" 3 |
| 45 | Surface last sync time + last commit SHAs for trend. |
| 46 | |
| 47 | 1. Verify both target repos exist and have clean working trees: |
| 48 | for repo in claude-code-config claude-skills-library; do |
| 49 | ( cd ~/$repo && git status --short ) |
| 50 | done |
| 51 | If any has uncommitted work, abort with status=target_dirty. |
| 52 | |
| 53 | 2. Diff source vs target: |
| 54 | For each <kind> in (agents, commands, skills): |
| 55 | diff -r ~/.claude/$kind <target>/$kind |
| 56 | Capture added/changed/removed file list. |
| 57 | |
| 58 | 3. If dry-run, print the diff summary and exit. status=dry_run. |
| 59 | |
| 60 | 4. Sync claude-code-config: |
| 61 | rsync (or cp) the agents/commands/skills/templates/knowledge dirs. |
| 62 | cd ~/claude-code-config |
| 63 | git add . && git commit -m "chore: sync from FrankX - $(date +%Y-%m-%d)" |
| 64 | git push origin main |
| 65 | Capture commit SHA. |
| 66 | |
| 67 | 5. Sync claude-skills-library: |
| 68 | for skill in ~/.claude/skills/*/; do |
| 69 | if [ -f "$skill/SKILL.md" ]; then |
| 70 | cp -r "$skill" ~/claude-skills-library/free-skills/ |
| 71 | fi |
| 72 | done |
| 73 | cd ~/claude-skills-library |
| 74 | git add . && git commit -m "chore: sync from FrankX - $(date +%Y-%m-%d)" |
| 75 | git push origin main |
| 76 | Capture commit SHA. |
| 77 | |
| 78 | 6. Verify both pushes succeeded: |
| 79 | gh api repos/<owner>/<repo>/commits/main --jq .sha |
| 80 | Compare to local SHA. If mismatch → status=push_failed for that repo. |
| 81 | |
| 82 | 7. Persist to memory: |
| 83 | node lib/acos/memory.mjs remember '{ |
| 84 | "agent":"meta-sync-repos", |
| 85 | "intent":"meta-sync-repos status", |
| 86 | "approach":"sync <N> files to <K> repos, both push <ok|failed>", |
| 87 | "score":<1.0 if all push ok>, |
| 88 | "tags":["sync","repos","publish"], |
| 89 | "metadata":{"config_sha":"<sha>","skills_sha":"<sha>","files_changed":<n>} |
| 90 | }' |
| 91 | |
| 92 | 8. Return summary + JSON. |
| 93 | ``` |
| 94 | |
| 95 | ## 5. Outputs |
| 96 | |
| 97 | **Human-readable:** |
| 98 | |
| 99 | ``` |
| 100 | Sync <status> |
| 101 | |
| 102 | claude-code-config: |
| 103 | <N> files added, <M> changed, <K> removed |
| 104 | Commit: <sha> |
| 105 | Push: <ok|failed> · https://github.com/<owner>/claude-code-config |
| 106 | |
| 107 | claude-skills-library: |
| 108 | <N> files added, <M> changed, <K> removed |
| 109 | Commit: <sha> |
| 110 | Push: <ok|failed> · https://github.com/<owner>/claude-skills-library |
| 111 | |
| 112 | [if dry-run] No commits made. Re-run without --dry-run to publish. |
| 113 | ``` |
| 114 | |
| 115 | **Structured JSON (last line):** |
| 116 | |
| 117 | ```json |
| 118 | { |
| 119 | "status": "ready|dry_run|target_dirty|push_failed", |
| 120 | "agent": "meta-sync-repos", |
| 121 | "outcome": { |
| 122 | "config": { "sha": "<sha>", "files_changed": 12, "push": "ok" }, |
| 123 | "skills": { "sha": "<sha>", "files_changed": 8, "push": "ok" }, |
| 124 | "dry_run": false |
| 125 | }, |
| 126 | "memory_ids": ["..."] |
| 127 | } |
| 128 | ``` |
| 129 | |
| 130 | ## 6. Integration |
| 131 | |
| 132 | **Upstream:** weekly cron (Sunday 10:00), `/sync-repos` command, manual dispatch |
| 133 | **Memory:** reads/writes intent `"meta-sync-repos status"` |
| 134 | **Downstream:** the two public repos' GitHub Actions (downstream CI on the synced content) |
| 135 | **Luminor Router:** dispatched at publish flows |
| 136 | |
| 137 | ## 7. Smoke eval |
| 138 | |
| 139 | **Functional** (`tests/fixtures/meta-sync-repos/smoke.mjs`): |
| 140 | - Use a tmp fixture for both source + target dirs |
| 141 | - Run ag |