dotfiles
AGENTS.md11 starsChanged 7 days agoApache-2.0View on GitHub
Repository-specific instructions for coding agents working in this public dotfiles repo. Keep shared cross-project agent behaviour in the global ~/.config/opencode/AGENTS.md. This file should only describe this repo's source layout, stow workflow, repo-local commands, and validation expectations. Don't catalogue skills or commands here: skills self-document via their injected description, commands via their frontmatter and the generated docs reference. Keep only repo facts and routing those don't capture.
We split this AGENTS.md into the rules it gives an agent
16 rules. About 1 is common, 2 are distinctive, and 13 are very specific to this project.
≈1
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
13
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 11
Treat private overlays as optional and separate (~/.config/dotfiles-private).
- Very specific: line 13
When following @ project references, look for the matching checkout under ~/repos before editing.
- Very specific: line 39
Keep Renovate update grouping limited to standard presets except for the coordinated Effect runtime and OpenCode 2 packages in …
- Distinctive: line 44
Prefer UK spelling in human-written command names and prose.
- Very specific: line 50
Only add a command when it must force an agent profile or carry explicit authorisation (/commit, /commit-push).
- Distinctive: line 57
If this layout changes, update this file and the owning skill.
- Very specific: line 64
Keep .stowrc ignore rules in sync when adding root-only files.
- Very specific: line 73
Always apply effect and types-enforce-ts when editing code under dot/.
- Very specific: line 74
All exported functions, classes, interfaces, types, and interface members need JSDoc.
- Very specific: line 76
Use Effect.fn("Name") for effectful functions with arguments, and Effect.gen with Effect.withSpan("Name") for named zero-argument effects.
- Very specific: line 77
Use Clock.currentTimeMillis for testable timestamps.
- Very specific: line 100
When changing a command, alias, or flag: update dot/src/cli/spec.ts, rebuild with mise run dot:build, run dot stow to generate and apply …
- Very specific: line 103
Keep command and flag metadata in dot/src/cli/spec.ts.
- Common: line 119
Prefer explicit CLI flags over environment-variable toggles.
- Very specific: line 128
After changing dot/, tests/, or OpenCode plugins, format first (it writes files), then run the rest in parallel before reporting done:
- Very specific: line 136
Run the changed command's relevant help or behaviour check.
≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
DOTFILES AGENTS
Repository-specific instructions for coding agents working in this public dotfiles repo.
Keep shared cross-project agent behaviour in the global ~/.config/opencode/AGENTS.md. This file should only describe this repo's source layout, stow workflow, repo-local commands, and validation expectations. Don't catalogue skills or commands here: skills self-document via their injected description, commands via their frontmatter and the generated docs reference. Keep only repo facts and routing those don't capture.
Scope
- This repo is the public dotfiles source at
~/.config/dotfiles. - Make changes here (not in
~/.config/*live paths directly). - Treat private overlays as optional and separate (
~/.config/dotfiles-private). ~/.config/dotfiles-privateis for private files and non-public info only: personal machine checks, browser extension checks, private package manifests, and other personal data, read by public logic. Host-specific config that reveals nothing private (GPU settings, host overrides,<package>--<host>packages) stays public.- When following
@project references, look for the matching checkout under~/reposbefore editing. If it exists there, that is the correct source path to change. - The standalone
contextandnotesrepositories are independent products. Dotfiles may install them and consume their public CLI/MCP interfaces, but must not add dotfiles-owned behaviour, analytics, environment variables, or integration contracts to those repositories. Keep observation and orchestration in dotfiles unless a change is independently justified by the standalone product itself.
Private Repositories
- Optional private config drives per-user behaviour; shared code must not hardcode it.
dot-git-presets.ymlholds induction defaults.dot-git.ymlholds repositories, browser selections, opt-inlinks,pull_requestsandissuestracking, andopencode_mcpper-repository MCP andopencode_skillsskill on and off overrides (rendered bydot mcp syncinto Git-ignored.opencode/opencode.jsonc). link-browser.desktopis the default web browser and runsdot link open;dot doctorwarns when it drifts.
Key Paths
- Main entrypoint:
scripts/.local/bin/dot(compiled binary fromdot/src/) - Source:
dot/(Bun + Effect v4 CLI; excluded from stow) - TypeScript tests:
dot/tests/(excluded from stow; usually empty) - Repository tests:
tests/(excluded from stow) - Docs site:
docs/(Blume, bun; excluded from stow; deploys todotfiles.timmo.dev) - Stow config:
.stowrc - Readme:
README.md(slim pointer; links to the docs site, which is the canonical human documentation) - OpenCode config source:
agents/.config/opencode/ - Skills source:
timmo001/skills, cloned bydotto~/.local/share/dot/skills(detached at the latestmain) and linked into~/.agents/skills/
Tooling
- The whole project is driven by mise. The single root
mise.tomlpins the toolchain (node,bun) and defines every dev task, including the rootlinttask and project namespaces (dot:*,docs:*, andtests:*). Prefermise run <task>(for examplemise run lint,mise run dot:build,mise run docs:check, ormise run tests:integration) as the canonical interface;mise taskslists them. mise.tomlis the source of truth for tool versions even without mise: anyone not using mise must still use the pinned versions and the same underlying commands each task wraps (do not substitute other versions or a different toolchain).- The package manager and runtime is bun for every JS/TS package (
dot/anddocs/). Do not use npm, pnpm, or yarn for install, lockfile, or script commands. Usebun install,bun add,bun update,bun run, andbunx(or themise runtask wrappers). - The tracked lockfile is
bun.lockin each package (dot/bun.lock,docs/bun.lock); commit it after any dependency change. CI runsbun install --frozen-lockfileagainst it. - Keep Renovate update grouping limited to standard presets except for the coordinated Effect runtime and OpenCode 2 packages in
renovate.json. Keep Effect compiler tooling outside the runtime group. tooling.ymlrecords the releases of the third-party tools the configuration, custom plugins, Code Modecli-toolsanddotcode were last reviewed against; a newly wrapped third-party CLI gets an entry there; the Tooling drift workflow opens a review pull request when one moves. After the review, move the pin withmise run tooling:update <repo> <tag>, never by hand; thetooling-driftskill has the steps.
OpenCode Assets
- Prefer UK spelling in human-written command names and prose; keep upstream names unchanged.
agents/.config/opencode/is the shared OpenCode config source. Relative plugin imports fromlib/must resolve before publication.- Shared skills come from
timmo001/skillsmain(see Key Paths);dot updaterefreshes and relinks them..agents/skills/holds this repo's own skills (also linked from.claude/skills), anddotfiles-skills/.agents/skills/holds global skills tied to dotfiles paths or commands. PublicSKILL.mdfiles must satisfy the Agent Skills frontmatter rules. herdr/.config/herdr/stows the main Herdr config and selected plugin config; runtime state stays untracked.dot agent syncmirrors the private global AGENTS source into harness instruction files;dot updateanddot initrun it.- Pin private OpenCode packages through the npm regex custom manager in
dotfiles-private/renovate.json. - Only add a command when it must force an agent profile or carry explicit authorisation (
/commit,/commit-push). Everything else is a skill.
Omarchy Host Overrides
- Hyprland config is the stowed
hypr/.config/hypr/package, with host overrides underhosts/$OMARCHY_HOSTselected by the~/.config/hypr/hostsymlink thatdot stowmaintains. Ghostty usesconfig.$OMARCHY_HOSTthe same way, and UWSM overrides live inuwsm/.config/uwsm/env.d/90-dotfiles. dot stowanddot installnever unstowhyprfirst, so its symlinks can't vanish mid-reload and drop Hyprland into emergency mode. Keep that indot/src/commands/{Stow,Install}.ts.- Custom Omarchy shell plugin IDs, directories, QML
moduleNamevalues and IPC targets use thetimmo.prefix.omarchy-shell-quickshellowns validation and restarts. - If this layout changes, update this file and the owning skill.
Stow Rules
- Repo root is a stow package root targeting
~/. - Top-level docs for humans/agents must be ignored by stow.
- The
docs/site directory is ignored by stow (--ignore=^/docs); the repo root stows to~/, so any new root-level directory that should not be symlinked needs a matching.stowrcignore. - Keep
.stowrcignore rules in sync when adding root-only files. - Always run
dot stow(ordot update, which refreshes stow) to apply packages. Do not invoke GNUstowdirectly from the repo root:dotapplies the correct adopt/no-folding flow and public-then-private ordering.
Dot Command
dot/ is the compiled CLI for the dotfiles manager, built with Bun and Effect v4 (bun build --compile to a single binary). It is excluded from stow via --ignore=^/dot; the binary outputs to scripts/.local/bin/dot, stowed to ~/.local/bin/dot.
Skills And Patterns
- Always apply
effectandtypes-enforce-tswhen editing code underdot/. - All exported functions, classes, interfaces, types, and interface members need JSDoc. Use single-line JSDoc for simple members and multi-line for complex behaviour. Effect service tags reference the underlying service interface via
{@link}. - Services use
Context.Servicewith a staticlayerproperty. Domain failures useSchema.TaggedError. - Use
Effect.fn("Name")for effectful functions with arguments, andEffect.genwithEffect.withSpan("Name")for named zero-argument effects. - Use
Clock.currentTimeMillisfor testable timestamps. Top-level execution usesEffect.runPromise. - Logging: section headings in Title Case, uppercase labels (
[INFO],[WARN],[ERROR]), sentence-case messages. - Debug startup logging with
DOT_DEBUG=1 dot 2>/tmp/dot.log; debug lines are prefixed with[dot].
Layout
dot/src/
index.ts - Effect CLI bootstrap and application layers
types.ts - Shared domain types
cli/spec.ts - Executable Effect command tree
commands/ - Native dot command implementations
doctor/ - Health-check runner and checks
git/ - Git and GitHub commands and services
mcp/ - MCP config generation
services/ - Config, CommandExecutor, Launcher, OutputLog and shared services
lib/ - Shared command supportcli/spec.ts defines typed arguments, flags, handlers, aliases, and subcommands; index.ts runs that tree with the shared Effect and Node layers. Bare dot and dot --help print root help. Commands use Launcher, CommandExecutor, and OutputLog for process and output handling.
Command Changes
- When changing a command, alias, or flag: update
dot/src/cli/spec.ts, rebuild withmise run dot:build, rundot stowto generate and apply completions, then regenerate the command reference withmise run docs:gen:cli(docs/src/content/docs/dot/commands.md; thedot-buildworkflow checks it is current). dot updatecompiles to a temporary path and atomically renames the result over the running binary to avoidETXTBSY. Keep that behaviour when changing self-update code.- Bounded external jobs use
ProcessRunnerthroughdot run --timeout <duration> -- <command> [args...]. Keep caller-specific arguments and permissions in the caller; the runner owns the deadline, signals, and process-group cleanup. - Keep command and flag metadata in
dot/src/cli/spec.ts; help and completion generation consume that registry. - Generated
dotandskill-maintenancecompletions are ignored by Git. Publicdot stow,dot install(includingdot init), anddot updategenerate them before stowing. Keep hand-written completions tracked; use package-provided completions for external tools such ascontext. - The Omarchy bar
shell.jsonis generated bydot/src/lib/omarchyShellConfig.ts. Preservedot update's changed-file restart condition;omarchy-shell-quickshellowns lifecycle details. dot deps serviceruns separately fromdot update, through thedot-depsuser service and timer. Its repository list lives in optional privatedot-config/.config/dot/dependency-service.yml; policies must be published before enabling the timer. Dedicateddot-deps-statebranches hold cross-machine ownership and interval state.- Third-party Omarchy plugins managed through
omarchy plugin addare Git submodules underomarchy/.config/omarchy/plugins/;omarchy-plugins.jsonowns their persistent bar placement. Add, update, and remove leave ordinary unstaged changes for review. - A registry
pathdeploys a plugin from a subfolder of its submodule (dot omarchy plugin add --path);onlyHostslimits an entry to the listed hosts in the generated layout. dot stowdeploys those plugin submodules as validated real-file copies because Omarchy rejects symlinks inside plugin directories. Build any required ignored executable in the source first. Changed live directories are backed up under the owning repo'sbackup/omarchy-plugins/; unchanged deployments are left in place.
Documentation
docs/ is the Blume site at dotfiles.timmo.dev: a short reference for what each major part is and why. Default to no docs update; dotfiles-docs owns when a page changes, and docs/AGENTS.md owns generated catalogues. README.md stays a slim pointer.
Script Configuration Policy
- Non-trivial scripting goes in
dot/(TypeScript and Effect), not Python or other languages. Plain shell is fine for simple wrappers. - New config files read by
dotuse YAML (Bun.YAML.parseplus Schema). Leave existing JSON formats alone unless migrating them. - Prefer explicit CLI flags over environment-variable toggles. Use environment variables only for standard process context, secrets, or existing compatibility shims.
Testing
Personal dotfiles: don't aim for coverage. Default to no new tests; validate by building, typing, formatting and running the changed command, plus the regression suite under Validation. Add a narrow test under tests/ only for a durable edge case or cross-cutting invariant that is easy to regress and hard to catch by hand (a known lock race, a ban on legacy syntax, a shared OpenCode contract). Don't grow dot/tests to mirror dot/src or invent happy-path coverage.
Validation
- Run only the checks the change needs, and run them in parallel. Pick the narrowest tasks that cover the touched files and pass them to a single
mise run, separated by:::(for examplemise run lint:yaml ::: lint:actionsafter a workflow edit). Don't run aggregate tasks such ascheckto cover a narrow change. After changing
dot/,tests/, or OpenCode plugins, format first (it writes files), then run the rest in parallel before reporting done:mise run dot:format mise run dot:check ::: tests:integrationtests:integrationbuildsdotitself.dot:checkonly runsdot/tests. The regression tests that importdot/srclive intests/and only run throughtests:integration, the CIregression-testsjob.- Run the changed command's relevant help or behaviour check. When command metadata changes, also add
tests:smoketo the parallel run. hk.pklruns the lint,dot:typecheckanddot:format:checktasks for changed file types on pre-push (hk's global hooks, installed bydot update). Run them by hand withhk check.- Basic health check:
dot doctor.mise taskslists every task; aggregates (check,tests,lint) are for broad changes only. - MCP config sync:
dot mcp syncrenders every harness's MCP config from privatedotfiles-private/mcp.yml;dot updateruns it, and a manual sync needsdot stowafter.
After Committing
- When a change only takes effect on this machine through
dot update(a rebuiltdot, a submodule or plugin bump, agent or MCP sync, or anything elsedot updateregenerates), offer "Rundot update" in the next-steps question alongside commit and push.dot updatepulls from the remote, so it needs the push first; say so when the user picks it without pushing.
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository2 other files it gives its agents.
- docs/AGENTS.mdAGENTS.md
- dotfiles-docsSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

