Files
cheat/adr/004-recursive-cheat-directory-search.md
Christopher Allen Lane 80e0e0d3ae feat: add --update/-u flag to pull git-backed cheatpaths (#552)
Iterates over configured cheatpaths and runs git pull on each one that
is a git repository with a clean worktree. Supports SSH remotes via key
file discovery and SSH agent fallback. Works with --path filtering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 19:51:40 -05:00

2.7 KiB

ADR-004: Recursive .cheat Directory Search

Date: 2026-02-15

Status

Accepted

Context

Previously, cheat only checked the current working directory for a .cheat subdirectory to use as a directory-scoped cheatpath. If a user was in ~/projects/myapp/src/handlers/ but the .cheat directory lived at ~/projects/myapp/.cheat, it would not be found. Users requested (#602) that cheat walk up the directory hierarchy to find the nearest .cheat directory, mirroring the discovery pattern used by git for .git directories.

Decision

Walk upward from the current working directory to the filesystem root, and stop at the first .cheat directory found. Only directories are matched (a file named .cheat is ignored).

Stop at first .cheat found

Rather than collecting multiple .cheat directories from ancestor directories:

  • Matches .git discovery semantics, which users already understand
  • Fits the existing single-cheatpath-named-"cwd" code without structural changes
  • Avoids precedence and naming complexity when multiple .cheat directories exist in the ancestor chain
  • cheat already supports multiple cheatpaths via conf.yml for users who want that; directory-scoped .cheat serves the project-context use case

Walk to filesystem root (not $HOME)

Rather than stopping the search at $HOME:

  • Simpler implementation with no platform-specific home-directory detection
  • Supports sysadmins working in /etc, /srv, /var, or other paths outside $HOME
  • The boundary only matters on the failure path (no .cheat found anywhere), where the cost is a few extra stat calls
  • Security is not a concern since cheatsheets are display-only text, not executable code

Consequences

Positive

  • Users can place .cheat at their project root and it works from any subdirectory, matching their mental model
  • No configuration changes needed; existing .cheat directories continue to work identically
  • Minimal code change (one small helper function)

Negative

  • A .cheat directory in an unexpected ancestor could be picked up unintentionally, though this is unlikely in practice and matches how .git works

Neutral

  • The cheatpath name remains "cwd" regardless of which ancestor the .cheat was found in

Alternatives Considered

1. Stop at $HOME

Rejected: Adds platform-specific complexity for minimal benefit. The only downside of walking to root is a few extra stat calls on the failure path.

2. Collect multiple .cheat directories

Rejected: Introduces precedence and naming complexity. Users who want multiple cheatpaths can configure them in conf.yml.

References

  • GitHub issue: #602
  • Implementation: findLocalCheatpath() in internal/config/new.go