armadillo-sync
Use when installing armadillo for the first time, updating an existing installation, or syncing .claude/ with armadillo’s latest. Replaces both onboarding and updating-armadillo. Also use when the user says “sync”, “onboard”, “init”, “setup”, “install armadillo”, “update armadillo”, “upgrade”, “check for updates”, or “doctor”.
| Model | Source | Category |
|---|---|---|
| opus | core | Meta |
Tools: Read, Glob, Grep, Bash, Write, Edit, Task, AskUserQuestion, WebFetch, Skill
Context: fork
Overview
Section titled “Overview”One skill that always converges to the same end state: your .claude/ is a perfect 1:1 replica of armadillo’s latest. For fresh installs, nuke & replace. For existing armadillo installs, Smart Sync — hash-aware selective updating that auto-accepts untouched files and only prompts for files you modified.
Mandatory Announcement — FIRST OUTPUT before anything else:
┏━ 🛡 armadillo-sync ━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓┃ [syncing .claude/ with armadillo's latest] ┃┗━━━━━━━━━━━━━━━━━━━━
- First time installing armadillo (no `.claude/` or no manifest)- Updating an existing armadillo installation (manifest exists, SHA stale)- Migrating a non-armadillo `.claude/` setup to armadillo standard- User says "sync armadillo", "update armadillo", "install armadillo", "onboard", "init", "setup", "upgrade", "check for updates", "doctor"
<details><summary><strong>Full Reference</strong></summary>
# armadillo-sync
## Overview
One skill that always converges to the same end state: your `.claude/` is a perfect 1:1 replica of armadillo's latest. For fresh installs, nuke & replace. For existing armadillo installs, Smart Sync — hash-aware selective updating that auto-accepts untouched files and only prompts for files you modified.
**Mandatory Announcement — FIRST OUTPUT before anything else:**┏━ 🛡 armadillo-sync ━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ [syncing .claude/ with armadillo’s latest] ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Replace the bracket content with the detected context (e.g., "fresh install", "updating v0.5.2 → v0.6.0", "migrating non-armadillo .claude/").
**Model requirement:** This skill involves deep classification, semantic analysis, and contribution pipeline decisions. Use **Opus 4.6** (`claude-opus-4-6`) for any subagent dispatches.
## When to Use
- First time installing armadillo (no `.claude/` or no manifest)- Updating an existing armadillo installation (manifest exists, SHA stale)- Migrating a non-armadillo `.claude/` setup to armadillo standard- User says "sync armadillo", "update armadillo", "install armadillo", "onboard", "init", "setup", "upgrade", "check for updates", "doctor"
## When NOT to Use
- User is mid-task and just wants to use a skill — route to the appropriate skill instead- User wants to create a new skill — use `writing-skills` or `writing-reference-skills`
## Repo Constant
The upstream repo is always:
```bashREPO="Armadillo-Nation/armadillo-main-brains"Never infer the repo slug from local directory names. Never append -cli or any other suffix. This constant is the single source of truth.
The 7-Step Flow
Section titled “The 7-Step Flow”Step 1: PREFLIGHT — gh auth, detect entry stateStep 2: NOTIFY — tell user what's about to happen (destructive warning)Step 3: SCAN — opt-in: check for unique stuff before nukingStep 4: PRESERVE & CLASSIFY — backup sacreds, hash-compare files, classify into bucketsStep 5: SYNC — smart sync for armadillo state, nuke & replace for empty/non-armadilloStep 6: RESTORE — put sacreds back, generate CLAUDE.md, wire hooks, write manifestStep 7: CONTRIBUTE — if scan found unique stuff, auto-PR to master repoSteps 1–6 always run (some are no-ops for certain entry states). Step 7 only runs if Step 3 found unique artifacts.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 1: PREFLIGHT
Section titled “Step 1: PREFLIGHT”Before any GitHub API calls, verify gh CLI is installed and authenticated.
# 1. Check gh CLI is installedcommand -v gh >/dev/null 2>&1 || { echo "gh CLI not found. Install from https://cli.github.com"; exit 1; }
# 2. Check keyring auth (not Claude Code's limited GITHUB_TOKEN)env -u GITHUB_TOKEN gh auth status 2>&1If command -v gh fails:
gh CLI not installed. Install it first: brew install gh # macOS https://cli.github.com # other platformsThen re-invoke this skill.If env -u GITHUB_TOKEN gh auth status exits non-zero:
GitHub CLI not authenticated. Run: gh auth loginThen re-invoke this skill.If both pass: Continue silently to entry state detection.
Entry State Detection
Section titled “Entry State Detection”| State | Detection | Behavior (PLUGIN_DEFAULT=true) |
|---|---|---|
| Empty | No .claude/ directory | Plugin-first install — no file-copy option |
| Non-armadillo | .claude/ exists, no .armadillo-manifest.json | Plugin install — no file-copy |
| Armadillo (stale) | Manifest exists, version differs from latest | ⚠ Deprecation warning → auto-migrate to plugin mode |
| Current | Manifest version matches latest (no marketplace) | Suggest migration to plugin mode |
| plugin-mode | Manifest has mode: "plugin" | Run armadillo-doctor → exit (unchanged) |
| plugin-ready | Manifest version matches latest + marketplace reachable | Auto-migrate — no prompt |
Phase 3 status: PLUGIN_DEFAULT = true — plugin mode is the default path for all new installs and syncs.
Routing logic: scripts/lib/sync-router.js exports routeForState(state, opts) — pass { pluginDefault: false } to restore legacy file-copy behavior.
Deprecation warning (shown on armadillo stale state):
⚠ File-copy sync is deprecated as of vX.Y.0. armadillo now uses Claude Code's plugin system for faster updates and zero-conflict installs. Migrating to plugin mode now...Programmatic detection: scripts/lib/detect-entry-state.js exports detectEntryState(projectDir) — returns one of the 6 state strings above.
Detect entry state: For full detection including plugin states (plugin-mode, plugin-ready), use detectEntryState() from scripts/lib/detect-entry-state.js. Simplified bash example for the 4 base states:
# Check .claude/ existsif [ ! -d ".claude" ]; then STATE="empty"elif [ ! -f ".claude/.armadillo-manifest.json" ]; then STATE="non-armadillo"else # Read current version from manifest CURRENT_SHA=$(cat .claude/.armadillo-manifest.json | python3 -c "import sys,json; print(json.load(sys.stdin).get('version',''))") LATEST_SHA=$(env -u GITHUB_TOKEN gh api repos/Armadillo-Nation/armadillo-main-brains/commits/main --jq '.sha') if [ "$CURRENT_SHA" = "$LATEST_SHA" ]; then STATE="current" else STATE="armadillo" fifiIf state is current: Report “You’re on [SHA] — latest. Nothing to do.” Then run git-setup health check and exit.
Resume detection: If the manifest exists but completed is absent or false, this is an interrupted sync. Read the phase field and resume from there. Inform user: “Found interrupted sync at phase [N]. Resuming.”
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 2: NOTIFY
Section titled “Step 2: NOTIFY”Tell the user exactly what’s about to happen before touching anything.
For Empty state:
armadillo is not installed here.
I'm about to:▪ Fetch the latest armadillo from GitHub (Armadillo-Nation/armadillo-main-brains)▪ Write all core skills, agents, hooks, rules, and lib files to .claude/▪ Install all skill packs▪ Generate CLAUDE.md and wire hooks
This is a fresh install — nothing will be destroyed.For Non-armadillo state:
⚠ You have an existing .claude/ directory without an armadillo manifest.
I'm about to:▪ Optionally scan for anything unique worth keeping (you decide)▪ Delete the entire .claude/ directory▪ Replace it with armadillo's latest
Sacreds (agent-memory, context/, progress/, docs/ with real content) are always preserved.
This is destructive for non-sacred files. No per-file negotiation — armadillo replaces everything it covers.For Armadillo (stale) state:
armadillo is installed but not current.
Current SHA: [current SHA]Latest SHA: [latest SHA]
I'm about to:▪ Optionally scan for unique stuff you've added (you decide)▪ Delete the entire .claude/ directory▪ Replace it with armadillo's latest▪ Restore sacreds and re-generate CLAUDE.md
Sacreds (agent-memory, context/, progress/, docs/ with real content) are always preserved.After presenting the NOTIFY message, proceed to Step 3 (or skip to Step 4 if state is Empty).
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 3: SCAN (Opt-In)
Section titled “Step 3: SCAN (Opt-In)”Skip this step entirely if state is Empty — nothing to scan.
Ask the user:
▸ Want me to scan for anything truly unique in your .claude/ before I nuke it? (custom skills, project-specific agents, codebase-specific stuff)
yes → I'll check what's worth keeping / contributing upstream no → Skip to nuke & replace (fastest path)Use AskUserQuestion to capture yes/no. If no → skip to Step 4.
If yes — Two-Pass Scan
Section titled “If yes — Two-Pass Scan”Pass A: Inventory .claude/
For each file in .claude/, classify as either:
| Bucket | Meaning | Action |
|---|---|---|
| Armadillo | Matches any armadillo skill/agent/hook/rule by name OR semantically (semantic matching) | Will be replaced — no question |
| Unique | Does something armadillo has no equivalent for | Queue for contribution pipeline |
Binary classification only — no per-file walkthrough. Path match is fast. For anything that doesn’t path-match, read the content and compare semantically against armadillo’s known skill descriptions.
Semantic matching rule: If the file’s core purpose is 100% covered by an existing armadillo skill or agent, classify as Armadillo. If it does something armadillo has no equivalent for, classify as Unique.
Pass B: Inventory codebase
Scan the actual project (not .claude/) for patterns suggesting custom artifacts should be created:
| Signal | Creates |
|---|---|
| Framework not covered by existing packs | New pack skill |
| Unique API integrations | Reference skill via writing-reference-skills |
| Complex deploy pipeline | Deploy skill |
| Domain-specific patterns | Domain agent |
| Business data (NAP, brand) | nap-ninja / brand flow recommendation |
Output scan results:
Unique .claude/ artifacts (will be contributed upstream):▪ skills/acuity-booking/ — appointment flow not in armadillo▪ agents/seo-auditor.md — custom SEO reviewer
Codebase-driven recommendations:▪ Detected: Payload CMS + custom collections → recommend payload skill▪ Detected: Cloudflare Workers deploy via wrangler → recommend wrangler-deploy skill
These will be created to armadillo spec and auto-PR'd to the master repo after sync.Proceed?If scan finds nothing unique: “Nothing unique found — nothing to contribute. Proceeding to nuke & replace.”
Store the list of unique artifacts in memory for Step 7.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 4: PRESERVE & CLASSIFY
Section titled “Step 4: PRESERVE & CLASSIFY”4a. Sacred Files — Always Backed Up First
Section titled “4a. Sacred Files — Always Backed Up First”These survive every sync. Back them up before anything else.
| Path | Why Sacred |
|---|---|
agent-memory/*/MEMORY.md | Accumulated agent knowledge — irreplaceable domain expertise |
context/ | Runtime state written by hooks (SWARM-STATE.md, logs, audit snapshots) |
progress/ | Session handoffs, plans, designs, optimization logs |
docs/ with real content (>10 lines, not templates) | Brand guides, architecture docs, research |
.armadillo-manifest.json | Version tracking — restored with updated SHA |
CLAUDE.md content below <!-- armadillo:end --> | User’s project-specific instructions |
Backup procedure:
mkdir -p /tmp/armadillo-sync-preserve[ -d ".claude/agent-memory" ] && cp -r .claude/agent-memory /tmp/armadillo-sync-preserve/[ -d ".claude/context" ] && cp -r .claude/context /tmp/armadillo-sync-preserve/[ -d ".claude/progress" ] && cp -r .claude/progress /tmp/armadillo-sync-preserve/[ -d ".claude/docs" ] && cp -r .claude/docs /tmp/armadillo-sync-preserve/
if [ -f "CLAUDE.md" ]; then python3 -c "content = open('CLAUDE.md').read()marker = '<!-- armadillo:end -->'idx = content.find(marker)if idx != -1: custom = content[idx + len(marker):] if custom.strip(): open('/tmp/armadillo-sync-preserve/claude-md-custom.txt', 'w').write(custom)"fiSkip Steps 4b–4d for Empty and Non-armadillo states — go straight to Step 5 (nuke & replace path).
4b. Hash Every Non-Sacred File (Armadillo state only)
Section titled “4b. Hash Every Non-Sacred File (Armadillo state only)”For each file in .claude/ that is NOT a sacred path, compute a sha256 hash and compare against the manifest:
find .claude -type f \ ! -path '.claude/agent-memory/*' \ ! -path '.claude/context/*' \ ! -path '.claude/progress/*' \ ! -path '.claude/docs/*' \ ! -name '.armadillo-manifest.json' \ | while read f; do shasum -a 256 "$f" | cut -d' ' -f1 doneCompare each file’s current hash against the hash value stored in the manifest’s files map.
4c. Fetch Upstream Changes
Section titled “4c. Fetch Upstream Changes”Use the GitHub Compare API to get which files changed between the installed SHA and the latest:
CURRENT_SHA=$(cat .claude/.armadillo-manifest.json | python3 -c "import sys,json; print(json.load(sys.stdin)['version'])")LATEST_SHA=$(env -u GITHUB_TOKEN gh api repos/Armadillo-Nation/armadillo-main-brains/commits/main --jq '.sha')
env -u GITHUB_TOKEN gh api "repos/Armadillo-Nation/armadillo-main-brains/compare/${CURRENT_SHA}...${LATEST_SHA}" \ --jq '.files[] | {filename: .filename, status: .status}'4d. Classify Into Buckets
Section titled “4d. Classify Into Buckets”For each non-sacred .claude/ file, classify using local hash vs manifest + upstream diff status:
| Local hash == manifest | Upstream changed | Bucket | Action |
|---|---|---|---|
| Yes (untouched) | Yes | untouched | Auto-replace with upstream |
| Yes (untouched) | No | skip | Already current, no action |
| No (modified) | Yes | modified | Prompt user |
| No (modified) | No | user-only | Keep user’s version |
| — | Added upstream | new | Auto-add |
| — | Removed upstream | removed | Auto-delete |
| Sacred path | — | sacred | Already backed up, skip |
Sync Summary — output bucket counts before proceeding:
Sync Summary────────────untouched (auto-replace) 42 filesnew (auto-add) 3 filesremoved (auto-delete) 1 fileuser-only (keeping yours) 5 filesmodified (needs decision) 4 files ← prompt requiredsacred (preserved) 3 paths━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 5: SYNC
Section titled “Step 5: SYNC”Two paths depending on entry state.
Path A — Blind Nuke & Replace (Empty or Non-armadillo states)
Section titled “Path A — Blind Nuke & Replace (Empty or Non-armadillo states)”No manifest = no hash baseline. Delete and start fresh.
rm -rf .claude/Then fetch the full armadillo tree and write everything (see fetch commands in Path B → 5c).
Path B — Smart Sync (Armadillo state — selective)
Section titled “Path B — Smart Sync (Armadillo state — selective)”For existing armadillo installs, SMART SYNC replaces the blind nuke. Only touch what needs touching.
5a. Auto-Process Silent Buckets
Section titled “5a. Auto-Process Silent Buckets”No prompts for these — just execute:
| Bucket | Action |
|---|---|
| untouched | Fetch upstream version, overwrite local |
| new | Fetch upstream file, write to local path |
| removed | Delete local file |
| user-only | Leave untouched — user modified, upstream didn’t |
| sacred | Skip — already backed up in Step 4a |
5b. Prompt for Modified Files
Section titled “5b. Prompt for Modified Files”When the modified bucket is non-empty, ask the user how to handle them as a group via AskUserQuestion:
4 files changed both locally and upstream: skills/armadillo-sync/SKILL.md rules/output-style.md hooks/session-start.sh agents/code-reviewer.md
How do you want to handle these?
1. Accept all upstream — take armadillo's version for all 2. Keep all mine — keep your local version for all 3. Walk through each — decide file by file (with Show diff option) 4. Accept by category — accept by file type (skills, rules, hooks, agents)Option 3 — Walk through each: For each modified file, show filename and prompt:
skills/armadillo-sync/SKILL.md a. Accept upstream b. Keep mine c. Show diff ← renders a unified diff before decidingOption 4 — Accept by category: Group files by type (skills/, rules/, hooks/, agents/) and prompt once per group.
Files the user keeps locally are flagged userKept: true in the manifest (see Step 6d).
5c. Fetch All Packs (always)
Section titled “5c. Fetch All Packs (always)”REPO="Armadillo-Nation/armadillo-main-brains"
# Fetch .claude/ file treeenv -u GITHUB_TOKEN gh api repos/Armadillo-Nation/armadillo-main-brains/git/trees/main --field recursive=1 --jq '.tree[] | select(.path | startswith(".claude/")) | .path'
# Fetch all pack filesenv -u GITHUB_TOKEN gh api repos/Armadillo-Nation/armadillo-main-brains/git/trees/main --field recursive=1 --jq '.tree[] | select(.path | startswith("packs/")) | .path'For each file, fetch content and write locally. Packs install to .claude/skills/<name>/SKILL.md.
Method 1 — GitHub CLI (preferred):
env -u GITHUB_TOKEN gh api repos/Armadillo-Nation/armadillo-main-brains/contents/.claude/skills/brainstorming/SKILL.md --jq '.content' | base64 -dMethod 2 — WebFetch (fallback):
https://raw.githubusercontent.com/Armadillo-Nation/armadillo-main-brains/main/.claude/skills/brainstorming/SKILL.md5d. Create Runtime Directories
Section titled “5d. Create Runtime Directories”mkdir -p .claude/context .claude/agent-memory .claude/progress .claude/docsProgress report during sync:
Syncing armadillo... ✓ untouched (42 auto-replaced) ✓ new (3 added) ✓ removed (1 deleted) ✓ user-only (5 kept) ✓ modified (4 resolved by user) ✓ Packs: frontend (16), backend (4), database (6), ... [all packs]
Total: [N] skills across [N] packsPath C — Migrate to Plugin Mode (plugin-ready state)
Section titled “Path C — Migrate to Plugin Mode (plugin-ready state)”When detectEntryState returns plugin-ready, offer migration:
armadillo detected marketplace connectivity.
▸ Migrate to plugin mode? (skills load from registry, not file copies) yes → run 8-step migration below no → continue with standard file-copy sync8-step migration (powered by scripts/lib/migrate-to-plugin.js):
- BACKUP sacred dirs: agent-memory, context, progress, docs
- CONFIGURE plugin settings: marketplace URL, enabled plugins list
- MARK managed rules with
# armadillo:managedcomment - REMOVE armadillo-managed files: skills/, agents/, hooks/, lib/
- SLIM CLAUDE.md to plugin-mode format via
generate-claude-md.js - RESTORE sacred dirs from backup
- MANIFEST update: set
mode: "plugin", write marketplace URL - DOCTOR run health checks via
scripts/lib/doctor-plugin.js
If state is plugin-mode: Skip sync entirely — run armadillo-doctor skill and exit. Plugin-mode projects are managed by the marketplace, not file-copy sync.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 6: RESTORE
Section titled “Step 6: RESTORE”6a. Restore Sacreds
Section titled “6a. Restore Sacreds”# Restore preserved sacred files[ -d "/tmp/armadillo-sync-preserve/agent-memory" ] && cp -r /tmp/armadillo-sync-preserve/agent-memory .claude/[ -d "/tmp/armadillo-sync-preserve/context" ] && cp -r /tmp/armadillo-sync-preserve/context .claude/[ -d "/tmp/armadillo-sync-preserve/progress" ] && cp -r /tmp/armadillo-sync-preserve/progress .claude/[ -d "/tmp/armadillo-sync-preserve/docs" ] && cp -r /tmp/armadillo-sync-preserve/docs .claude/
# Clean up temp directoryrm -rf /tmp/armadillo-sync-preserve6b. Generate CLAUDE.md
Section titled “6b. Generate CLAUDE.md”-
Write armadillo section between
<!-- armadillo:start -->and<!-- armadillo:end -->markers:- Skills list (organized by category)
- Pack table listing installed packs
- Rules table
- Model selection table
- Permissions section
-
Restore custom section below the markers:
- If user had custom CLAUDE.md content (backed up in Step 4) → place it below
- Add comment:
<!-- Add your project-specific instructions below this line -->
6c. Wire Infrastructure
Section titled “6c. Wire Infrastructure”hooks.json sync:
Fetch the latest .claude/hooks/hooks.json from GitHub (already done in Step 5b). This is already written. No merge needed — it’s a clean install.
settings.json hooks section:
Rebuild from hooks.json — hooks.json is the source of truth for the hooks section.
bypassPermissions:
Offer the permission mode:
armadillo works best with bypassPermissions mode.
▪ Auto-approves all tool calls except the deny-list▪ Deny-list still blocks catastrophic commands (rm -rf /, force push, etc.)
▸ Enable bypassPermissions? (Recommended)Use AskUserQuestion:
- “Yes, enable it (Recommended)” → set
defaultModeto"bypassPermissions"in.claude/settings.json - “No, keep acceptEdits” → leave as-is
Hook scripts (.sh):
All hook scripts are already written in Step 5b. Ensure they’re executable:
chmod +x .claude/hooks/*.shRules sync:
Rules are already written in Step 5b as part of the full .claude/ sync. No additional action needed.
git-setup integration:
Invoke the git-setup skill to detect and configure the project’s git strategy:
Invoke Skill tool with skill="git-setup"This checks for branch protection, git-workflow rule, conventional commits, and version-bump automation. Skips components that are already in place.
6d. Write Manifest
Section titled “6d. Write Manifest”{ "version": "<latest commit SHA from GitHub>", "repoUrl": "https://github.com/Armadillo-Nation/armadillo-main-brains", "installedAt": "<ISO 8601 timestamp>", "updatedAt": "<ISO 8601 timestamp>", "completed": true, "installedPacks": ["frontend", "backend", "database", "...all packs"], "files": { "skills/brainstorming/SKILL.md": { "owner": "armadillo", "hash": "<sha256>" }, "skills/armadillo-sync/SKILL.md": { "owner": "armadillo", "hash": "<sha256>", "userKept": true }, "agent-memory/seo-specialist/MEMORY.md": { "owner": "user", "hash": "<sha256>" } }}userKept: true is set on any file where the user chose “Keep all mine” or “Keep mine” during the modified-file prompt in Step 5b. It signals that on the next sync, this file’s local hash will differ from the manifest hash by design — the comparison logic skips re-flagging it as modified unless upstream changes again after the userKept was recorded.
**Get latest SHA:**```bashenv -u GITHUB_TOKEN gh api repos/Armadillo-Nation/armadillo-main-brains/commits/main --jq '.sha'Compute file hashes:
shasum -a 256 .claude/skills/brainstorming/SKILL.md | cut -d' ' -f1Track ALL files — both armadillo-owned and user-owned sacreds. Write manifest to .claude/.armadillo-manifest.json.
6e. Restore Summary
Section titled “6e. Restore Summary”## Sync Complete
Installed:▪ armadillo core (29 skills)▪ [N] packs, [N] total skills▪ [N] agents▪ Hooks configured (session-start, reinject-after-compact, task-completed)▪ hooks.json wired▪ settings.json updated▪ CLAUDE.md generated▪ Manifest written (SHA: [sha])
Preserved:▪ agent-memory/ (N agents)▪ context/ (runtime state)▪ progress/ (N files)▪ docs/ (N files)▪ CLAUDE.md custom section
● ahh, that felt good didn't it?━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 7: CONTRIBUTE
Section titled “Step 7: CONTRIBUTE”Only runs if Step 3 found unique artifacts.
If the scan was skipped or found nothing unique, skip this step entirely.
Contribution Pipeline
Section titled “Contribution Pipeline”For each unique artifact identified in Step 3, use armadillo-maker to create it to armadillo spec:
Invoke Skill tool with skill="armadillo-maker"args: "Create [artifact type]: [name] — [description from scan]"armadillo-maker runs its full 10-phase pipeline:
- Recon — understand the domain
- Research — gather technical context
- Design — spec the artifact
- TDD — write tests first
- Implement — write the skill/agent/rule
- Register — wire into armadillo.json
- Document — update CLAUDE.md
- Verify — run tests, confirm quality
- Commit — local commit
- Deliver — ready for contribution
Each artifact created locally in .claude/ works immediately — the user doesn’t have to wait for the PR to merge.
Push to Master Repo
Section titled “Push to Master Repo”After artifact creation, push to the master armadillo repo:
# Create a contribution branch on the master repoREPO="Armadillo-Nation/armadillo-main-brains"ARTIFACT_NAME="<kebab-case artifact name>"BRANCH="contrib/${ARTIFACT_NAME}"
# Push the artifact files to the contribution branchenv -u GITHUB_TOKEN git push "https://github.com/${REPO}.git" HEAD:"refs/heads/${BRANCH}"If user lacks push access: Skip gracefully.
No push access to Armadillo-Nation/armadillo-main-brains.Artifact [name] works locally in your .claude/.Submit manually: https://github.com/Armadillo-Nation/armadillo-main-brains/pullsAuto-PR via REST API
Section titled “Auto-PR via REST API”If push succeeded, create a PR:
SLUG="Armadillo-Nation/armadillo-main-brains"
env -u GITHUB_TOKEN gh api "repos/${SLUG}/pulls" \ --method POST \ --field title="feat(pack): add <artifact-name>" \ --field head="contrib/<artifact-name>" \ --field base="main" \ --field body="$(cat <<'EOF'## WhyAuto-contributed from armadillo-sync. User's project had a unique artifact worth sharing.
## Changes▪ Added <artifact-type>: <artifact-name>▪ <description of what it does>
## Test plan▪ Run: node --test tests/<artifact-name>.test.js▪ Verify skill announcement renders correctly▪ Confirm no banned terminology (plugin refs, restart instructions)
Generated with [Claude Code](https://claude.com/claude-code)EOF)"Use writing-prs for full PR description guidance when crafting the contribution PR body.
Branch naming: contrib/<artifact-name>
Contribution flow:
User's project Master armadillo repo───────────── ─────────────────────Scan finds unique stuff ↓armadillo-maker creates artifact ↓Artifact works immediately locally ↓Push branch → contrib/<artifact-name> ↓Auto-PR → feat(pack): add <artifact> ↓Owner reviews + merges ↓Next release includes it → vX.Y.Z ↓All Armadilloers get it on next sync━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Infrastructure Sync Details
Section titled “Infrastructure Sync Details”The NUKE & SYNC (Step 5) + RESTORE (Step 6) together handle complete infrastructure replacement. Key details:
hooks.json
Section titled “hooks.json”The full hooks.json is fetched from the master repo and written directly — it’s a clean replace, not a merge. After restore, any user-added hooks that were in the old hooks.json are lost (they weren’t sacred files). If the user had custom hooks in .claude/hooks/, those scripts would need to be contributed upstream or re-wired manually.
settings.json
Section titled “settings.json”The settings.json is fetched from the master repo. The bypassPermissions preference is re-applied in Step 6c via user prompt — it doesn’t carry over automatically since the file was nuked.
hooks section in settings.json is always rebuilt from hooks.json — hooks.json is the source of truth.
Hook scripts (.sh)
Section titled “Hook scripts (.sh)”All .sh hook scripts are fetched from the master repo and written in Step 5b:
session-start.shreinject-after-compact.shrun-hook.cmdtask-completed.sh
All made executable via chmod +x in Step 6c.
All files under .claude/rules/ are fetched from the master repo and written in Step 5b. User-added rules (not in the master repo) are lost — they should be contributed upstream via the contribution pipeline if worth keeping.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Phase 3: PLUGIN_DEFAULT Deprecation
Section titled “Phase 3: PLUGIN_DEFAULT Deprecation”When the PLUGIN_DEFAULT=true env flag is set:
- New installs use
scripts/lib/plugin-first-install.js— plugin mode from the start, no file copies - Existing armadillo installs get a migration offer on next sync (Step 5C)
- File-copy mode remains available via
PLUGIN_DEFAULT=falseoverride
This flag gates the transition period. When unset (current default), behavior is unchanged — file-copy sync runs as normal.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Edge Cases
Section titled “Edge Cases”| Edge Case | Handling |
|---|---|
| No internet / gh not authed | Preflight catches, clear error with fix instructions |
.claude/ but no git | Sync works — just file operations, no git required |
| Custom CLAUDE.md content | Preserved below armadillo markers in Step 4 → restored in Step 6b |
| Interrupted sync | Manifest tracks completed: false + phase: N, resume next run |
| No push access to armadillo repo | Contribution skipped gracefully, artifact stays local |
| User says no to scan | Skip Step 3, proceed directly to Step 4 |
| Scan finds nothing unique | Report “nothing unique” → proceed to Step 4 |
| Already current (SHA matches) | Report “up to date” → exit after git-setup health check |
| Empty project (greenfield) | Fresh install → after sync, offer fresh-project flow |
Manifest says completed: false | Interrupted sync detected — resume from saved phase |
| Writing-skills needed for codebase artifacts | Use writing-skills for generic skills, writing-reference-skills for API/external tool reference skills |
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Key Rules
Section titled “Key Rules”- One flow for all states — install, update, migrate all follow the same 7 steps
- Sacred files are inviolable — agent-memory, context/, progress/, docs/ (>10 lines) always survive the nuke
- No per-file conflict resolution — the answer is always “use armadillo’s version”; unique things go through Step 3 scan
- All packs installed unconditionally — every Armadilloer gets the complete library
- REPO constant is fixed — always
Armadillo-Nation/armadillo-main-brains, never inferred from local paths - Manifest tracks everything — every file in
.claude/gets an entry with owner and hash - Contribution is the philosophy — unique artifacts don’t stay local-only; if worth keeping, worth sharing
- bypassPermissions is recommended — always offer it; never force it
- git-setup runs after every sync — ensures git hygiene is current
- Resume on interrupt — manifest’s
completedandphasefields enable safe re-entry - Smart Sync for existing installs — when manifest exists, classify files by hash comparison instead of blind nuke. Only prompt for files the user actually modified AND upstream also changed.
Common Mistakes
Section titled “Common Mistakes”| Mistake | Fix |
|---|---|
| Asking per-file keep/replace decisions | No — Smart Sync is the default for existing installs; only modified+upstream-changed files get a prompt |
| Forgetting to backup sacreds before nuke | Step 4 always runs before Step 5 |
| Inferring repo slug from local directory name | Always use the REPO constant — local dir name is irrelevant |
| Interactive pack selection | Gone — all packs always installed |
| Instructing users to open a new Claude Code session | Never — armadillo-sync takes effect immediately, no new session needed |
| Leaving unique artifacts local-only | Step 7 pushes them upstream — nothing stays local-only |
Nuking .claude/ without checking for sacreds | Step 4 explicitly backs them up first |
Missing the manifest completed field | Always write it as true on success; update it to false + phase number on interrupt |
| Not wiring git-setup after sync | Step 6c always invokes git-setup |
| Leaving hook scripts non-executable | Step 6c always runs chmod +x .claude/hooks/*.sh |
| Using plugin or marketplace terminology | armadillo is git-native file copy — no plugin system, no marketplace, no registry files |