No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
shk.ai 945c4ff0ff Restore watch_folders automation + shk_chezmoi_cheatsheet, fix 2 bugs
Recovered from files orphaned since before dits-and-dots' registry.yml
integration existed, which had been silently shadowing this repo's own
current functions since ~July (see aperture-dots session log for the full
story of how that surfaced). Reviewed everything in the orphaned files
against current tracked code; almost all of it was already superseded.

Turns out the watch_folders inbox health-check/cleanup automation
(_shk_check_watch_folders, _shk_cleanup_watch_folders,
_shk_run_watch_folders) was already restored in 00_init.sh, just with 2
remaining yq calls missing -r - fixed those instead of the duplicate copy
I nearly committed. Issue #4 tracks moving this off per-shell execution
onto a systemd timer.

shk_chezmoi_cheatsheet - genuinely new, migrated into 50_dev.sh, same
style as the existing shk_git_cheatsheet/shk_acl.

Also fixed two real bugs surfaced while diffing (present in the current
tracked code independent of the orphan cleanup):
- shk_directory_collapse_chains called an undefined collapse_single_dirs
  instead of recursing into itself - single-level chains collapsed fine,
  multi-level chains (a/b/c/d) silently didn't finish.
- shk_chmod_files/shk_chmod_directories used unquoted $1/$2, breaking on
  paths with spaces (the function's own echo admitted as much).

Not migrated (explicit decision): git_commit() (superseded in spirit by
existing repo-specific dotpush-style flows), record_vhs() (superseded by
shk_capture_vhs's more careful device detection, was self-marked TODO).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 12:16:20 +00:00
dotfiles Restore watch_folders automation + shk_chezmoi_cheatsheet, fix 2 bugs 2026-09-23 12:16:20 +00:00
private-registry
.chezmoi.toml.tmpl
.chezmoiroot
.gitattributes
.gitignore
AGENTS.md
install.sh
README.md
registry.yml

dits-and-dots

Personal dotfiles managed with chezmoi. Includes modular bash configs under ~/.config/bash/bashrc.d/.

Install

bash <(curl -fsSL https://hex.wurzelraum.org/shukutils/dits-and-dots/raw/branch/main/install.sh) && source ~/.bashrc

This installs chezmoi (if missing) and applies the dotfiles. The installer itself runs in a subshell (that's what bash <(...) does), so it can't reach back and affect your current shell no matter what it does internally — && source ~/.bashrc runs in your shell, right after, which is why it's chained onto this command rather than being something install.sh does for you.

Editing configs

Never call chezmoi update/apply/re-add directly. Use:

  • dotpull — before you edit anything. Syncs the whole chezmoi source, not just bashrc.d.
  • dotpush [message] — once you're done editing. Commits and pushes everything.
  • bashedit — convenience wrapper: dotpull → open all bashrc.d modules in vim → dotpush.

If dotpull/dotpush ever find that local and origin have diverged (e.g. a previous push failed silently, or you edited on two machines), they don't merge blind or overwrite anything: your local work gets pushed to a local-sync/<host>-<timestamp> branch on origin first, your local branch is reset to match origin, then that temporary branch is deleted again — its job was only to make the reset safe. Worst case a push fails and nothing moves; once it succeeds, the commit SHA is printed so you can git cherry-pick it back if you ever need to, even though it's no longer reachable from a branch name.

Run dits-help for a quick reference (chezmoi_cheatsheet still works as an alias).

Why "never call chezmoi directly" matters: dotpull/dotpush call chezmoi re-add/apply internally, but chezmoi's own git.autoCommit/autoPush config would otherwise fire inside that very call — a naive commit+push with no fetch-first check, racing ahead of the careful divergence handling below. This repo ships .chezmoi.toml.tmpl with both set to false so a fresh chezmoi init never enables them. If your machine was set up before this template existed, check chezmoi cat-config | grep -A2 '\[git\]' — if autoCommit/ autoPush show true, add autoCommit = false and autoPush = false under [git] in ~/.config/chezmoi/chezmoi.toml by hand (re-running chezmoi init won't pick up the template on an already-initialized source repo).

Note: ~/.bashrc itself is never touched by chezmoi and stays yours to customize per-machine. install.sh only makes sure it has one include line pointing at ~/.config/bash/bashrc, which is what chezmoi manages and which sources everything under ~/.config/bash/bashrc.d/. For machine-local additions that shouldn't be synced at all, use ~/.bash_aliases instead.

Additional repos (registry.yml)

Beyond this repo's own bashrc.d modules, registry.yml lists other git repos of bash functions — private or public — that plug into the same loading mechanism as local_source_dirs in ~/.shukonfig/shukonfig.yml: any repo's init.sh gets sourced automatically once it's cloned locally.

  • dits-new — scaffold a brand-new registry repo before it exists anywhere: a local git repo with an init.sh (contract + a demo function) and a README.md. Push it to your forge yourself when it's ready.
  • dits-list — show every registry repo and whether it's installed on this machine.
  • dits-register — add a new repo interactively: prompts for a name, the plain clone URL, and an access token (hidden input), builds the authenticated URL, encrypts it (its own passphrase, typed twice), and appends the entry to registry.yml. Doesn't push — run dotpush yourself once you're happy with it.
  • dits-install <name> — decrypt that repo's clone URL (prompts for its own passphrase) and clone it. Never re-clones if already present.
  • dits-update — dotpull, then syncs every installed registry repo the same way dotpull/dotpush sync dits-and-dots itself: commits any local edits, pulls (fast-forward if behind), and pushes if ahead. On real divergence it snapshots to a local-sync/<host>-<ts> branch, resets to origin, then deletes that branch again (prints the commit SHA for manual recovery) — same as dotpull. If the repo's token can't push at all (read-only), nothing is lost or left blocking the pull either: local work goes on a local-only branch (never pushed — it just doesn't exist upstream), the repo is reset to match origin, and that trade-off is printed plainly. Finishes by reloading the shell functions. No passphrase needed for any of this post-install: the decrypted URL (including any auth token) lives on in that clone's own origin remote, not in this repo.

"Installed" is never tracked in a file — it's just whether the repo's clone_dir exists, checked fresh every time. Nothing about a private repo's host, path, or token is ever in registry.yml itself; that's only ever inside its own private-registry/<name>.age blob, encrypted with a passphrase specific to that one repo. See private-registry/sample-private-repo.age for a working local example (demo passphrase: dits-demo) and the separate sample-private-repo-template repo (~/Repos/shk/sample-private-repo-template on this machine) for the init.sh contract to build a real one from.