Merge the dotfiles repo: stow packages for the harnesses, one sources.toml - #70
Merged
Conversation
2. Disable swap files and backups
The old Makefile targeted apt/yum systems and overwrote the global gitconfig with a stale identity; i3/i3status/xrandr configs are X11-only. All content remains recoverable via git history.
zsh config becomes a thin ~/.zshrc sourcing numbered modules under ~/.config/zsh/; interactive pieces move out of .zprofile so they exist in all interactive shells. Git config is copied byte-identical from the live multi-identity setup. Stow runs with --dotfiles --no-folding so ~/.config/<tool> dirs stay real directories (credential safety).
Curated from brew bundle dump cross-checked against brew leaves --installed-on-request; adds jq explicitly (harness-configs prereq previously present only as a dependency). go/npm dump entries are intentionally excluded — those are managed by go install and nvm.
gh package carries config.yml only — hosts.yml (oauth tokens) stays an unmanaged local file, guaranteed by stow --no-folding keeping ~/.config/gh a real directory.
bootstrap.sh is curl-able and idempotent: CLT, Homebrew, clone, brew bundle, stow (adopt on first run with a mandatory diff review), then harness-configs make install as a sibling repo. macos/defaults.sh is the phase-2 landing spot for defaults-write capture behind make macos-apply.
doctor verifies stow version, Brewfile satisfaction, every managed symlink, the --no-folding secret-safety invariants (real ~/.config dirs, hosts.yml not a symlink, no secret-pattern files tracked), and the harness-configs sibling.
- harness-clone falls back to https with GIT_CONFIG_GLOBAL=/dev/null so the gitconfig ssh rewrite cannot defeat it; bootstrap continues past a failed harness step and still prints the credential instructions - bootstrap stow step is deterministic: move pre-existing real files at managed paths to ~/.dotfiles-backup-<ts> and always stow-link, instead of branching on ~/.zshrc alone (auto-adopt removed — adopt is now a deliberate manual target only) - scripts/managed-targets.sh derives the managed path list from packages/ so doctor and bootstrap can never drift from the tree - doctor: content-level secret scan of tracked packages/, numeric stow version compare, realpath instead of bare python3, npx demoted to a warning, all symlinks checked via the derived list - jwtd fails loudly without jq; aliases guard their targets' existence - README: download-then-run bootstrap form, gh-qwiet ssh alias documented, secrets-policy claims match what is actually enforced
…ntracts - atuin config.toml reduced from 272 commented upstream-default lines to the 2 active settings plus a docs pointer (parses identically) - --no-folding rationale and the new-tool recipe each keep one canonical copy (README); Makefile and CLAUDE.md point there - jwtd/pdfunlock/imgcopy share one missing-tool contract (stderr + return 127) and consistent indentation; nvm paths hoisted to a local
Adds mas (+ entries for Numbers, 1Password for Safari, Okta Verify) and casks for the previously direct-download apps, adopted in place with brew install --cask --adopt. MDM-managed work apps stay unmanaged. tailscale-app and openvpn-connect are pkg casks needing interactive sudo: run make cask-adopt once to finish adoption.
manifests/*.txt track curated tool lists (accidental go install ./... artifacts excluded); go-install/npm-install/pipx-install apply them and tools-install joins the install aggregate. cask-adopt takes over apps installed outside brew.
Only deliberately-changed settings are recorded so stock defaults can evolve without this file fighting them; make macos-apply is idempotent.
… exist mas depends on the Spotlight index, which can lag or go stale for /Applications; verify App Store apps on disk before failing.
CLI: fzf, zoxide, eza, bat, fd, git-delta, yq, jless, dust, lazygit. k8s: kubectx, kubecolor, dive, trivy, dyff, viddy, kubeconform. Shell: zsh-autosuggestions, zsh-syntax-highlighting. Cask: raycast.
35-fzf.zsh loads before 40-tools.zsh so atuin keeps Ctrl-R; fzf owns Ctrl-T/Alt-C with fd as the source. zoxide + autosuggestions join 40-tools; syntax highlighting sources last as 95. kubectl aliases to kubecolor (completions preserved); delta becomes the git pager with zdiff3 conflict style.
Compares Brewfile (via normalized brew bundle dump), go/npm/pipx manifests, and macos/defaults.sh recorded values against the live system, printing the reconcile command per finding; exit 1 on drift. mas entries lagged by the Spotlight index stay warnings. doctor gains a broken-symlink sweep (warn-only) of ~ to depth 3.
Raycast stores settings in an encrypted local DB and extension configs can hold API tokens, so backup goes through its own encrypted export to a private location rather than this repo.
Fast key repeat + hold-to-repeat; Finder shows extensions/pathbar/status bar without extension-change warnings and stops writing .DS_Store to network/USB volumes; screenshots land in ~/Screenshots without window shadows; Dock autohides with no recents and stable Spaces order; save and print dialogs open expanded and save locally. drift.sh learns to expand $HOME when comparing recorded values.
coffee [duration] / watch <pid|name> / status / stop, with -d to also keep the display on. Ships as a bin stow package into ~/.local/bin (added to PATH); managed-targets/doctor/drift pick the package up automatically.
Replace the five hasconfig:remote includeIf rules with a plain include of config-personal plus a gitdir:~/qwiet/ override for config-qwiet. Later include wins, so personal is the default everywhere and work identity applies only under ~/qwiet. The url.insteadOf rewrites are unchanged; they rewrite remotes, not identity. Trade-off: a work repo cloned outside ~/qwiet now gets the personal identity and needs a per-repo user.email.
Helium is a Chromium-based browser that will take over from Google Chrome as the daily driver. Install it alongside Chrome for now; the google-chrome cask, the cask-adopt target, and the chrome-doctor alias stay until the cutover.
The new tab page shows Most Visited tiles by default. No enterprise policy covers that, so the setting lives in the profile's Preferences JSON as ntp.shortcust_visible (the typo is Chromium's own key name). Patch it from macos/defaults.sh, guarded three ways: skip when there is no profile, skip while Helium is running because it rewrites the file on exit, and skip when the key is already false. The write goes through a temp file and rename so a failure cannot truncate the profile. macos/defaults.sh is no longer defaults(1)-only, so say "macOS and app settings" in the README layout table.
Helium reads Chromium enterprise policy from its own preferences domain, so `defaults write net.imput.helium ...` reaches it — no administrator rights and no /Library/Managed Preferences file. Verified on helium://policy: the keys come back as source "platform", scope "user", level "recommended". Recommended means the policy sets the default while Settings can still override it, which is the right strength for a personal machine. Set: card and address autofill off, payment-method probing off, omnibox search suggestions off, link prefetch off, and prompt for the download location. PasswordManagerEnabled is deliberately absent. Helium's built-in HOP (Helium Opinionated Policy) provider already forces it and the passkeys policy off, at a higher priority than platform policy, so restating them here would be dead weight. Generalise the JSON patch to a WANTED table so keys without a policy are a one-line addition. It still holds only the new-tab tiles; credentials_enable_autosignin was considered and dropped, because it is a top-level pref rather than a profile.* one and is moot anyway once HOP disables the password manager.
glow renders markdown in the terminal, alongside bat for code and jless for JSON. The md alias pages output through glow -p, guarded by command -v like the other modern-CLI aliases.
Remove six entries that are no longer used: awscli, okta-awscli, dbeaver-community, gcloud-cli, insomnia, postman. dbeaver-community and postman had no app installed on the machine, only orphaned application data. The AWS and gcloud credential stores were removed alongside the CLIs. google-chrome stays until the Helium cutover is complete.
Neither tool is used locally. Removing them cascaded their Python dependency trees, which freed about 235 MB. The improve-codecov-coverage skill reads the Codecov REST API directly, so it does not depend on the codecovcli binary.
The sl CLI and its 2.3 GB toolchain cache under ~/.shiftleft were removed from the machine at the same time. This leaves the qwiet git and SSH identity untouched, because that configuration controls work repository access, not the scanner.
The ~/qwiet work tree and its SSH key no longer exist, so the conditional include and the ShiftLeftSecurity URL rewrite pointed at paths and a host that are gone. Personal identity now applies everywhere.
# Conflicts: # .gitignore # CLAUDE.md # Makefile # README.md
claude/ and pi/ move to packages/claude and packages/pi; the six hand-rolled *-link/*-unlink target pairs collapse into stow-based harness-link/harness-unlink (folding on, unlike the --no-folding invariant that protects the $HOME packages). Each package reaches the shared skills/ tree through a committed relative symlink, and plugins.txt joins the other line-format manifests as manifests/claude-plugins.txt.
doctor checks harness symlink health in-repo instead of a sibling clone; bootstrap links the harness directly; the zsh modules export DOTFILES_DIR and source claude-multi-account.sh from this repo; suite pages and the skills.sh install repo say sanketsudake/dotfiles. The never-committed runtime config dir ~/.config/harness-configs/ keeps its name so live machine configs stay valid.
skills/vendored.json, the committed authored-skill .source.json sidecars, and the agent sidecars collapse into a single sources.toml ([[skill]] and [[agent]] arrays), read and written through the new stdlib-only scripts/toml-manifest.py with a deterministic writer so diffs stay per-entry. resource-manager.sh keeps its jq pipelines but round-trips the full document at the persistence boundary; agents gain first-class manifest support across every verb. The gitignored .source.json inside a vendored skill dir remains, as the materialize marker only. python >= 3.11 (tomllib) becomes a preflight- and doctor-checked dependency, pinned via the Makefile PYTHON variable.
The harness symlink health check resolved ~/.pi/skills through the package symlink to the top-level skills/ tree, outside packages/ — accept any path inside the repo. The deslop bump is the skills-update round-trip check on the new manifest.
agents-update-all exercises the agent-kind manifest write path on the new sources.toml; the deslop description refresh from the previous round-trip lands in the regenerated catalog and suite page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
Merge this with a merge commit — not squash, not rebase.
The branch carries the old
sanketsudake/dotfilesrepo's full historyvia an
--allow-unrelated-historiesmerge;squashing or rebasing would flatten and discard it.
What this does
One repo for the whole machine:
the sibling
dotfilesrepo (stow packages, Brewfile, manifests, bootstrap)merges into this one, histories preserved.
After merging, the plan is to rename this repo to
dotfilesand archive the old one as
dotfiles-legacy.Harnesses become stow packages
claude/→packages/claude/,pi/→packages/pi/.*-link/*-unlinkMakefile target pairs collapse intostow-based
harness-link/harness-unlink(directory folding ON;the
--dotfiles --no-foldingsecurity invariant stays scoped to the$HOMEpackages).skills/treethrough a committed
skills -> ../../skillssymlink.claude/plugins.txtjoins the other line-format manifestsas
manifests/claude-plugins.txt.One sources.toml
skills/vendored.json, the committed authored-skill.source.jsonsidecars,and the agent sidecars consolidate into a single
sources.toml(
[[skill]]+[[agent]]arrays: 72 skills, 6 agents).scripts/toml-manifest.pywith a deterministic writer, so diffs stay per-entry.
resource-manager.shkeeps its jq pipelines;only the persistence boundary changed for skills,
and agents gain first-class manifest support in every verb.
skills/<name>/.source.jsonremains as the materialize marker only.pinned via the Makefile
PYTHONvariable.Verified
make preflightandmake testgreen(the smoke test round-trips fetch → materialize → doctor → delete on sources.toml).
make skills-materialize,make skills-update NAME=deslop,and
make agents-update-allexercised against the new manifest.~/.claude-personal,~/.claude-work,~/.pi)re-linked via
harness-linkand healthy.Until the post-merge cutover (repo renames + local dir swap),
make doctorreports the$HOMEsymlinks as foreign — expected;they self-heal at the swap because the merged repo keeps the identical
packages/layout.