Skip to content

Repository files navigation

dotfiles

Personal configuration files managed with KCL and dotter.

What's Included

  • Shell: Zsh (Oh My Zsh), Nushell, Fish
  • Terminal: Ghostty
  • Multiplexer: Tmux with theme support
  • Editor: Neovim with LSP, plugins, and profile variants (default/work/personal)
  • CLI Tools: Starship, Atuin, Carapace, Zoxide, Jujutsu, iamb
  • AI Assistants: OpenCode, Claude Code, Kiro (MCP server configs, commands, skills)
  • Window Management: AeroSpace (macOS), Hyprland (Linux)
  • Package Managers: Homebrew (macOS), pnpm, npm

Installation

1. Clone and configure

git clone https://github.com/zenibako/dotfiles.git
cd dotfiles
cp local.toml.example .dotter/local.toml

Edit .dotter/local.toml to set your name, email, profile, platform, and theme.

2. Run init

sh init.sh

This installs dependencies, generates configs from KCL, and deploys via dotter.

Usage

Deploy changes

./deploy.sh        # KCL generation + dotter deploy
./deploy.sh -f     # Force overwrite changed targets

Always use ./deploy.sh rather than bare dotter deploy — KCL must regenerate global.toml before dotter reads it.

Profiles

Select ONE profile, ONE platform, ONE theme in .dotter/local.toml:

packages = ["work", "mac", "monokai"]
  • work / personal — both inherit from default via depends
  • Themes: monokai, nightowl, tokyonight

Secrets

Secret injection is split in two:

  • Seeding (explicit): scripts/secrets/seed-secrets.sh builds a local cache from Proton Pass (pass-cli, parallel fetches) or macOS Keychain. Run it on a fresh machine, after rotating a secret, or when a deploy warns the cache is stale (>72h). --force rebuilds, --status shows freshness.
  • Injection (every deploy): post_deploy.sh consumes whichever cache exists and injects values into deployed configs. It never builds the cache inline — deploys stay fast and never block on vault prompts. (Exception: an interactive deploy with no cache at all seeds once automatically.)

Never commit secrets to local.k/local.toml.

security add-generic-password -s KEY_NAME -a dotfiles -w SECRET_VALUE -U login.keychain

Architecture

src/                    # Source of truth (KCL package root; contains kcl.mod)
├── kcl.mod             # KCL package manifest (makes `import local` resolve to local.k)
├── main.k              # KCL entrypoint — imports every app module and assembles config
├── profiles.k          # Profile/package definitions + dotter file→target mappings
├── local.k             # Per-machine overrides (gitignored; created from local.k.example)
├── local.k.example     # Template for local.k
├── packages.k          # Shared top-level modules live flat at src root:
├── themes.k            #   packages, themes, env, completions, profiles.
├── env.k               #   (Not apps — imported as `import <name> as <name>_mod`.)
├── completions.k       #
├── _shared/            # Reusable KCL schemas, MCP helpers, templates
│
│                       # ── Apps: one folder per tool, each with a config.k ──
├── atuin/config.k      # Every app follows the same shape:
├── ghostty/config.k    #   src/<app>/config.k defines a top-level `<app> = …`
├── jj/config.k         #   binding, and main.k pulls it in with
├── tmux/config.k       #   `import <app> as <app>_mod`. Non-KCL assets for the
├── zsh/config.k        #   app (scripts, READMEs, templates like zsh/zshrc,
├── kiro/config.k       #   ghostty/shaders) sit alongside config.k in the folder.
├── opencode/config.k   #
├── claude/             # Nested app: two sub-apps, each its own config.k
│   ├── code/config.k   #   → `import claude.code as claude_code`
│   └── desktop/config.k#   → `import claude.desktop as claude`
├── nvim/               # Neovim configs (default/work/personal profiles)
├── gnupg/              # GPG agent config (template; no config.k)
└── ...                 # aerospace, iamb, gitlogue, pnpm, starship, gitconfig, …

scripts/                # Deploy pipeline scripts
├── pre_deploy.sh       # KCL generation + validation (dotter hook)
├── post_deploy.sh      # Secret injection + post-deploy checks (dotter hook)
└── dotter/             # Shared helpers and validators
    ├── lib.sh          # Common functions (resolve_python, run_with_timeout, etc.)
    ├── generate_from_kcl.py  # Converts KCL JSON output to dotter global.toml + configs
    ├── validate_*.py   # Config validation scripts
    └── validate_schema.sh

.dotter/                # Generated output (gitignored)
├── global.toml         # Generated by KCL pipeline
├── local.toml          # Per-machine config (user creates)
├── pre_deploy.sh       # Symlink → ../scripts/pre_deploy.sh
└── post_deploy.sh      # Symlink → ../scripts/post_deploy.sh

out/                    # Generated config files (gitignored, written by KCL)
deploy.sh               # Deploy wrapper (creates .dotter/, runs pipeline)
init.sh                 # First-time machine setup

Pipeline

  1. KCL (src/main.k) evaluates profiles, variables, and templates into JSON
  2. Python (scripts/dotter/generate_from_kcl.py) converts JSON into .dotter/global.toml + out/ configs
  3. Dotter reads global.toml + local.toml, deploys files to ~/.config/ etc.
  4. Post-deploy injects secrets from Keychain, validates Lua/LSP/schemas

Platform Support

  • macOS: Full support (Homebrew, AeroSpace, Ghostty)
  • Linux: Fedora (dnf), Arch (pacman), Debian/Ubuntu (apt), openSUSE (zypper), Alpine (apk)

License

Personal configurations — use at your own discretion.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages