Skip to content
AI & Agents
Skill

/Dotfiles

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).

From plugin
danielmiessler-lifeos
20k97 skills13 agents34 commands

Claude Code

$ npx -y skills add danielmiessler/lifeos --skill Dotfiles --agent claude-code

SKILL.md

Dotfiles.SKILL.md
metadata:
  short-description: "Back up, restore, and sync shell, editor, and terminal dotfiles with a private repository, with secret scanning before pushes."
name: Dotfiles
version: 1.1.26
evals:
  manual:
    reason: "GitHub's real visibility answer and a restore onto a live home directory need the real private repository and machine; exercising them as a test could overwrite live state."
    falsifier: "The requested file differs after restore, the remote privacy or secret scan fails, or the sync changes an unselected configuration file."
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."

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

| Intent | Trigger | File | |----------|---------|------| | **Push** | "push dotfiles", "update dotfiles" (default) | `Intents/Push.md` | | **Pull** | "pull dotfiles", new machine setup | `Intents/Pull.md` | | **Sync** | "sync dotfiles", unsure of direction | `Intents/Sync.md` | | **Restore** | "restore dotfiles", recover config | `Intents/Restore.md` | | **Status** | "check dotfiles status", "dotfiles status" | `Intents/Status.md` | | **Backup** | "backup dotfiles", local timestamped copy | `Intents/Backup.md` |

| File | Read when | |------|-----------| | `Setup.md` | first-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`](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

Read more
@danielmiessler
Ships withdanielmiessler-lifeos

⛰️ LifeOS — The universal AI Harness designed to move you from Current to Ideal state in both life and work.

20k97 skills13 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
19.7k
Star history of danielmiessler/lifeos on GitHub, a chart by star-history.com

Other skills on danielmiessler-lifeos.

More skills from other plugins.

Questions about Dotfiles.

Which coding agents can use Dotfiles?
Dotfiles installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.