Skip to content
cccskills
FreePublished on GitHubEnglish overview

Dotfiles

Manage selected shell, editor, and terminal settings with a private GitHub repository. Compare, pull, sync, restore from timestamped backups, or make a local backup; pushes verify repository privacy and scan for secrets first.

OriginalShow the original description

Manage ~/.zshrc and a chosen set of ~/.config/ directories (you name them in Config.md) against a private GitHub dotfiles repo. Intents: Push (verify private remote, scan secrets), Pull (clone/diff), Sync, Restore (timestamped backup), Status, Backup (local timestamped copy). Security scan blocks .env, secrets, tokens before push. NEVER commits to public repos. USE WHEN dotfiles, push/pull/sync dotfiles, zshrc, restore config, backup config, new machine setup. NOT FOR app configs unrelated to shell/editor/terminal.

danielmiessler/LifeOS19,635 stars(GitHub 19,635 + cccskills 0)
Works withGitHub

Run score Not tested

See how to install

Good for

  • Moving dotfiles to a new machine
  • Checking which tracked settings changed
  • Restoring settings from a backup
  • Pushing shell configuration after edits

Overview

What it does

Manages ~/.zshrc and the directories under ~/.config/ that you specify in Config.md alongside a private GitHub repository. You can push or pull settings, compare local and remote versions, sync in both directions, check status, make a local backup, or restore from a timestamped backup. Before pushing, it verifies that the remote repository is private and scans staged changes and unpushed commits with gitleaks. The operation stops if the scan fails or gitleaks is unavailable.

When it helps

Use it to move shell settings to a new machine or keep them consistent across environments. It can also show which selected settings differ, or help you back them up before restoring. The managed files are shell, editor, and terminal settings.

Example requests

  • “Check the status of my dotfiles.”
  • “Push my changed settings to the private repository.”
  • “Pull the settings onto my new machine.”
  • “Restore the settings from the specified backup.”

Notes

First-time use requires Config.md settings for the repository, backup location, and selected directories. GitHub CLI checks repository privacy, and gitleaks scans for secrets before a push. Restore overwrites local files, so it creates a backup first and requires user confirmation.

This overview was written by AI (OpenAI Codex) from the public SKILL.md. Check the original below for the exact behavior.

Document check

AI checked the SKILL.md for operations that need care and for setup requirements. The score comes only from actually running the skill (hands-on test).

SafetyAre sending data, deleting files, and running commands disclosed?
AGoodPrivacy and gitleaks checks precede pushes; restore requires backup and confirmation.
Easy setupDoes it need few tools or API keys, and are they documented?
BPartly lackingIt needs several Config.md values, GitHub CLI, and gitleaks; setup location is given.

Not counted in the score. Rated by AI (OpenAI Codex) as of Oct 28, 2026. Treat it as a guide and read the original before installing.

Disagree? Request a re-evaluation

Tell us which point is wrong and why. No login needed. We will check it against the SKILL.md, redo the evaluation, and show the result here.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

Files included (9)

  • SKILL.md10.6 KB
  • Intents/Backup.md4.4 KB
  • Intents/Pull.md3.1 KB
  • Intents/Push.md7.6 KB
  • Intents/Restore.md7.4 KB
  • Intents/Status.md4.0 KB
  • Intents/Sync.md4.0 KB
  • Setup.md3.7 KB
  • Tools/Config.ts3.2 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

System Dotfiles Management Skill

Contents: Ideal State · Intent Routing · Data & Config · Tool contract · Gotchas · Examples

Manages ~/.zshrc and ~/.config/ against a private GitHub dotfiles repo; the directories under ~/.config that Backup and Restore copy are the ones you list in Config.md (DOTFILES_CONFIG_DIRS). Push local config up, pull it down, sync two-way, restore from a timestamped backup, or check status — with a gitleaks content scan of the staged diff and of every unpushed commit that stops the push on any secret, or when gitleaks is not installed.

The working clone lives at $DOTFILES_DIR and tracks the private remote $DOTFILES_REPO. Push is the default intent; Pull, Sync and Status only compare, Restore is the one intent that overwrites local files, and Backup makes a local copy that never leaves the machine.

Ideal State

  • Every push lands only in $DOTFILES_REPO, after GitHub reported it private (gh repo view --json isPrivate printed true) both before any other Push step and again just before the push, and after gitleaks exited 0 on the staged diff and on every unpushed commit; any failed check, or gitleaks missing, stopped the run before a commit or push.
  • Only configs enter the repo or a backup: Push copies and stages the files the repo already tracks, a new config enters by name, every local backup (Backup, and Restore's backup before it overwrites) copies the DOTFILES_CONFIG_DIRS directories with secret files excluded, and Restore's also copies every tracked .config file it will overwrite, and the whole ~/.config is never copied or staged.
  • Every comparison of local and repo (Pull, Sync, Status, and Restore's check after it copies) covers .zshrc and the files git ls-files .config lists, so a report names only real dotfile differences and a clean machine reports none.
  • No local file is overwritten before a timestamped backup exists in $DOTFILES_BACKUPS and the user confirmed; Pull, Sync and Status leave every local file unchanged.
  • Every run reports the files it changed, the repository it verified, the security check result, the commit hash when it committed, and the next intent to run.

Intent Routing

IntentTriggerFile
Push"push dotfiles", "update dotfiles" (default)Intents/Push.md
Pull"pull dotfiles", new machine setupIntents/Pull.md
Sync"sync dotfiles", unsure of directionIntents/Sync.md
Restore"restore dotfiles", recover configIntents/Restore.md
Status"check dotfiles status", "dotfiles status"Intents/Status.md
Backup"backup dotfiles", local timestamped copyIntents/Backup.md
FileRead when
Setup.mdfirst-time setup, or Tools/Config.ts stopped on a missing Config.md or key

Data & Config

This skill ships no personal data. All private values live in the USER tree at <configRoot>/LIFEOS/USER/CUSTOMIZATIONS/SKILLS/Dotfiles/Config.md (configRoot is $CLAUDE_CONFIG_DIR when set, else ~/.claude): the keys DOTFILES_DIR, DOTFILES_BACKUPS, DOTFILES_REPO, DOTFILES_REPO_SLUG and DOTFILES_CONFIG_DIRS. Every intent opens with this Config command, which runs Tools/Config.ts, exports those keys and exits non-zero (stopping the intent) when the file or a required key is missing. Nothing has a built-in default. First-time setup: Setup.md.

DOTFILES_ENV="$(bun ~/.claude/skills/Dotfiles/Tools/Config.ts)" || exit 1; eval "$DOTFILES_ENV"   # exports DOTFILES_DIR, DOTFILES_BACKUPS, DOTFILES_REPO, DOTFILES_REPO_SLUG, DOTFILES_CONFIG_DIRS

Tool contract

Recipes two or more intents share. Each runs after the Config command.

Remote check — the remote is the configured repo AND GitHub says it is private

Push runs it before any other step and again before the push. Status runs it inside a subshell, ( … ), so a STOP line becomes the report's remote warning and the rest of the report still runs. In Push, any STOP line ends the intent: no pull, no commit, no push.

cd "$DOTFILES_DIR" || { echo "STOP: no dotfiles clone at $DOTFILES_DIR"; exit 1; }
REMOTE=$(git remote get-url origin) || { echo "STOP: the clone has no origin remote"; exit 1; }
[ "$REMOTE" = "$DOTFILES_REPO" ] || { echo "STOP: origin is $REMOTE, expected $DOTFILES_REPO"; exit 1; }
PRIVATE=$(gh repo view "$REMOTE" --json isPrivate -q .isPrivate) || { echo "STOP: cannot read the repo's visibility from GitHub (gh auth status?)"; exit 1; }
[ "$PRIVATE" = "true" ] || { echo "STOP: $REMOTE is not private (isPrivate=$PRIVATE)"; exit 1; }
echo "OK: origin is $REMOTE, private"

The visibility check is the one that matters: the equality line only proves origin matches the configured URL, not that the repo is private. gh repo view accepts the SSH, HTTPS, or OWNER/REPO form of the remote.

Compare local and repo — tracked files only

Run from $DOTFILES_DIR. Prints one line per .zshrc or tracked .config file that is missing at home or differs from the clone; no output means they match. Never diff -qr ~/.config/ .config/: the repo tracks a subset, so a whole-directory diff lists every app's data and never comes back clean.

{ echo .zshrc; git ls-files .config; } | while IFS= read -r f; do
  if [ ! -e "$HOME/$f" ]; then echo "missing locally: $f"
  elif ! cmp -s "$HOME/$f" "$f"; then echo "differs: $f"; fi
done

Backup copy — Backup, and Restore before it overwrites

Sets $timestamp and $backup_dir, copies ~/.zshrc and the DOTFILES_CONFIG_DIRS directories, and leaves secret files out. It sets $backup_ok to 1 only when every copy succeeded; Restore overwrites nothing unless $backup_ok is 1.

timestamp=$(date +%Y%m%d_%H%M%S)
backup_dir=$DOTFILES_BACKUPS/$timestamp
backup_ok=1
mkdir -p "$backup_dir/.config" || backup_ok=0
if [ -f ~/.zshrc ]; then
    if cp ~/.zshrc "$backup_dir/.zshrc"; then echo "✅ Backed up .zshrc"; else echo "❌ .zshrc backup failed"; backup_ok=0; fi
fi
# Backup the directories named in Config.md (not entire .config to save space).
# $(printf ...) word-splits in zsh and bash alike; a bare $DOTFILES_CONFIG_DIRS is one word in zsh.
for dir in $(printf '%s' "$DOTFILES_CONFIG_DIRS"); do
    if [ -d ~/.config/$dir ]; then
        # No secrets in a backup: a tool's directory can hold its own .env or token
        # files, and every backup would be another plaintext copy.
        rsync -a --exclude='.env' --exclude='.env.*' --exclude='*.oauth' --exclude='*oauth*.json' \
            --exclude='*token*.json' --exclude='client_secret*.json' --exclude='credentials*' \
            --exclude='auth.json' ~/.config/$dir "$backup_dir/.config/" \
            && echo "✅ Backed up .config/$dir" || { echo "❌ .config/$dir backup failed"; backup_ok=0; }
    fi
done
if [ "$backup_ok" = 1 ]; then echo "Backup complete at: $backup_dir"; else echo "❌ Backup INCOMPLETE at: $backup_dir. Do not restore or overwrite anything."; fi

Restore from a backup — rollback

The one rollback recipe; Restore and Backup point here. It overwrites local files, so it follows the same rule as Restore: a fresh backup of the current files first, then the user's yes.

  1. Pick the backup to roll back to, before taking the fresh one (which becomes the newest):
ls -lt "$DOTFILES_BACKUPS"/
backup=$DOTFILES_BACKUPS/YYYYMMDD_HHMMSS   # the chosen timestamp
[ -d "$backup" ] || { echo "STOP: no backup at $backup"; exit 1; }
  1. Run the Backup copy above, so the current files can be recovered from $backup_dir.
  2. Show the user $backup (the source), $backup_dir (the fresh backup) and the files that will be overwritten (.zshrc and each DOTFILES_CONFIG_DIRS directory present under $backup/.config), and wait for their yes.
  3. Only after that yes:
[ "$backup_ok" = 1 ] || { echo "STOP: the fresh backup is incomplete; nothing restored"; exit 1; }
[ -f "$backup/.zshrc" ] && cp "$backup/.zshrc" ~/.zshrc
# Only the configured directories: the fresh backup covers those and nothing else.
for dir in $(printf '%s' "$DOTFILES_CONFIG_DIRS"); do
    [ -d "$backup/.config/$dir" ] && cp -R "$backup/.config/$dir" ~/.config/
done
echo "Rolled back from $backup; previous files saved at $backup_dir"

Reloading in the agent's shell changes nothing for the user. Tell them to run exec zsh (or source ~/.zshrc) in their own terminal.

Gotchas

  • Dotfiles holds configs only, and the repo's tracked list decides what counts. Push copies tracked files and stages tracked files; a new config is added by name. The config directory can also hold application data and credentials, so never stage or copy it whole; ignore data and credential directories in .config/.gitignore.

Examples

Example 1: Push dotfiles after config changes

User: "push dotfiles"
→ Verifies private repo, checks for sensitive files
→ Copies .zshrc and the tracked .config/ files to repo
→ Stages tracked files only, commits, pushes to GitHub

Example 2: Set up a new machine

User: "pull dotfiles"
→ Clones/pulls latest from private repo
→ Shows diff between local and repo versions; local files stay unchanged
→ Then the Restore intent copies them home, after a timestamped backup and the user's yes

Example 3: Check what's changed

User: "check dotfiles status"
→ Compares local .zshrc and .config/ with repo
→ Shows uncommitted changes and sync status
→ Verifies remote is correct private repo

Example 4: Unsure which direction to sync

User: "sync dotfiles"
→ Sync intent: shows the tracked files that differ and which side changed each one, changes nothing
→ Recommends Push or Restore

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

AnnualReports

FreeSummary

Find and fetch vendor cybersecurity reports, then compare their findings on topics such as ransomware, breaches, cloud security, and AI. Analyses identify the reports consulted and cite each figure by vendor, year, and report, including where sources disagree.

  • Find reports in a cybersecurity topic area
  • Fetch a specific vendor report
  • Compare ransomware findings across reports
danielmiessler/LifeOS19.6KUpdated Oct 28, 2026

Compare a component's own design needs with the goals of the larger system through three structured passes. The result identifies conflicts, recommends an appropriate scope, and assesses whether the proposed design fits the whole.

  • Choosing between a service, a library, and inline code
  • Comparing feature requests with product goals
  • Checking how new components fit an existing system
danielmiessler/LifeOS19.6KUpdated Oct 28, 2026

Aphorisms

FreeSummary

Find quotes that fit a text’s themes, with attribution and a short reason for each suggestion. Add sourced quotes, research thinkers, and organize a quote collection by theme and usage history to avoid repetition.

  • Finding a fitting quote for a newsletter
  • Saving sourced quotes without duplicates
  • Researching a thinker’s quotes by theme
danielmiessler/LifeOS19.6KUpdated Oct 28, 2026

Art

FreeSummary

Create blog illustrations, technical diagrams, comparisons, comics, and icons through workflows tailored to each format. The skill guides composition, color, and model selection, then stages generated images for review before they are used in a project.

  • Creating blog header illustrations
  • Explaining a system with a technical diagram
  • Visualizing comparisons and timelines
danielmiessler/LifeOS19.6KUpdated Oct 28, 2026

ArtDirection

FreeSummary

Assess the visual quality of images, films, slides, and site captures against a brief and craft criteria. Two vision judges score the work and rank defects, guiding bounded revision; delivery is gated on a passing critique, with human calibration labels recorded separately.

  • Reviewing a render and listing the most important visual defects
  • Iterating on a film or slide deck until it meets a defined bar
  • Checking whether an image reads as professional
danielmiessler/LifeOS19.6KUpdated Oct 28, 2026

ArXiv

FreeSummary

Find arXiv papers by topic, research category, or paper ID. Retrieve titles, authors, abstracts, and links, check new submissions, and add AlphaXiv's AI-generated overviews when available to help decide which papers to read.

  • Checking new AI and machine learning papers
  • Finding papers on a specific research topic
  • Looking up a paper by its ID or arXiv URL
danielmiessler/LifeOS19.6KUpdated Oct 28, 2026

See all skills by danielmiessler

Report a problem with this skill