Skip to content

feat(watcher): S-64 continuous dotfiles watcher#98

Merged
tieubao merged 1 commit into
mainfrom
feat/dotfiles-watcher
May 12, 2026
Merged

feat(watcher): S-64 continuous dotfiles watcher#98
tieubao merged 1 commit into
mainfrom
feat/dotfiles-watcher

Conversation

@tieubao
Copy link
Copy Markdown
Member

@tieubao tieubao commented May 12, 2026

Summary

  • Two LaunchAgents absorb drift into the dotfile repo's working tree as you save (one launchd WatchPaths regenerated from chezmoi managed, one fswatch -r daemon). Both pipe into a mkdir-locked dotfiles-watcher-tick that runs chezmoi re-add on every drifted file.
  • Working-tree only — no auto-commit, no auto-push. New verb dotfiles watch {install|uninstall|status|now|tail}.
  • Distinct from /dotfiles-sync: the watcher only does the "absorb drift on already-managed files" slice, so the skill's drift section stays empty and the operator-decisions stay focused on classification (new brews / new skills / SSH fragments) + commits.

Full design: docs/specs/S-64-dotfiles-watch.md. User-facing docs: docs/guide.md § 4 "The background watcher."

Test plan

  • bash tests/dotfiles-watch.sh -- 9/9 pass on Hans-Air-M4 (shellcheck both wrappers, template render+lint, no-op-when-clean, single-pass absorb, drift-loop iteration, mkdir-lock coalescing, Brewfile entry).
  • After merge + chezmoi apply on the daily driver: dotfiles watch install, edit ~/.claude/skills/<any>/SKILL.md, verify a TICK done (passes=1) line lands in ~/Library/Logs/dotfiles-watcher.log within ~3s and the corresponding source file under home/dot_claude/skills/.../SKILL.md shows as modified in git status.
  • dotfiles watch status shows both com.truonghan.dotfiles-watcher and com.truonghan.dotfiles-watcher-fswatch loaded.
  • dotfiles watch uninstall cleanly boots out both agents.

Naming note

Earlier drafts used autosync / resync. Renamed to watch / watcher-tick because "sync" was too close to /dotfiles-sync and made the boundary unclear (the watcher is one slice of what /dotfiles-sync does, not a different sync). The help text now closes with the disambiguation explicitly.

🤖 Generated with Claude Code

Two LaunchAgents (launchd WatchPaths regenerated from `chezmoi managed`
+ fswatch -r daemon) call a mkdir-locked `dotfiles-watcher-tick` that
runs `chezmoi re-add` on every drifted managed file. Working-tree only:
no auto-commit, no auto-push (operator reviews via `git status` and
commits manually). New verb `dotfiles watch {install|uninstall|status|now|tail}`.

Distinct from /dotfiles-sync: the watcher only absorbs drift on
already-managed files, so /dotfiles-sync's drift section stays empty
and the operator-decisions stay focused on what only a human can do
(classify new brews / new skills, commit, push). WatchPaths covers
direct mtime on every leaf (including in-place ~/.claude/skills/*/SKILL.md
edits); fswatch covers subdirs created since the last apply.

Test runner at tests/dotfiles-watch.sh covers 9 cases (shellcheck,
template render+lint, no-op-when-clean, single-pass absorb, drift-loop
iteration, mkdir-lock coalescing, Brewfile entry). 9/9 pass on
Hans-Air-M4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tieubao tieubao merged commit 9499c8f into main May 12, 2026
2 checks passed
@tieubao tieubao deleted the feat/dotfiles-watcher branch May 12, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant