Skip to content

Dotfiles workflow primer

This page is the source of truth for the intended workstation workflow shape.

This repo should feel less like a pile of config files and more like a personal workstation interface. The goal is not to remember every tool. The goal is to have a small set of predictable entrypoints that compose the tools for you.

The short version:

text
p       pick or enter a project
p t     open or attach a tmux session for a project
p e     open a project in the editor
p y     open a project in Yazi
p g     open a project in lazygit
p c     open a project in Codex
cx      run Codex in the current repo
lg      lazygit in the current repo
y       Yazi in the current directory
note    notes index
today   daily note

The exact commands can change. The workflow shape should not.

1. Operating model

The dotfiles have three jobs:

  1. Make a fresh machine usable.
  2. Keep daily tools consistent across WSL, native Linux, and Windows.
  3. Provide a workflow vocabulary so the machine is easy to drive after setup.

Do not treat bootstrap scripts as the main product. Bootstrap gets the machine to the starting line. The workflow layer is what makes the setup worth using.

2. Host lanes

Keep the lanes distinct:

text
WSL/Linux filesystem     active repos, Codex state, Linux shell workflows
CachyOS/Linux            native Linux desktop and dev workflows
Native Windows           PowerShell, Scoop/bootstrap/platform tools, GUI apps

For WSL and Codex work, active repositories, Codex config/cache/auth/session state, and day-to-day development state should live on the Linux filesystem. Windows paths and UNC paths are fine for interop, not as the default working tree location.

3. Tool ownership

Use the simplest ownership rule that survives real use:

text
mise             versioned developer tools and portable CLIs
project config   project-specific tool versions and scripts
Scoop            Windows bootstrap/platform tools and GUI apps
apt/pacman       OS packages and platform dependencies
Fish plugins     Fish-only interactive enhancements
editor managers  editor extensions/packages

When ownership overlaps, document why. “It happened during setup” is not a reason; it is archaeology.

Project-local tooling should win over global tooling. If a JS project declares pnpm, use pnpm. If a Python project has uv config, use uv. If a repo has scripts, prefer those over global guesses.

4. Shell roles

The shells should not all pretend to be the same thing.

text
Fish        primary interactive shell; rich functions, abbreviations, UX
Bash        fallback/recovery shell; small, predictable, compatible
PowerShell  Windows peer shell; native Windows behavior, not a Bash cosplay

Fish should get the good stuff: project launcher, abbreviations, rich functions, fzf selectors, Atuin, zoxide, Starship, Yazi integration, Git helpers, and Codex wrappers.

Bash should be boring. It should have enough aliases and environment behavior to recover, run scripts, and work in minimal environments.

PowerShell should expose the same broad concepts with native syntax: open/edit/clip/paste/reveal, command resolution diagnostics, project helpers, and Windows-specific path behavior.

5. Startup philosophy

Shell startup should be fast and legible.

Separate these concerns:

text
environment     variables safe outside interactive shells
path            duplicate-safe path prepends
login           one-time login/session behavior
interactive     prompt, history, aliases, bindings, completions
functions       reusable shell functions
local           machine-local overrides, sourced last

Generated shell integrations should be cached where practical. It is fine to generate mise, direnv, zoxide, starship, atuin, fzf, and carapace snippets, but normal shell startup should source cached snippets instead of doing expensive discovery every time.

6. Local override contract

Every serious dotfiles repo needs an escape hatch.

Use an ignored directory such as:

text
~/.config/dotfiles/local.d/
  10-env.sh
  10-env.fish
  10-env.ps1
  20-aliases.sh
  20-aliases.fish
  20-aliases.ps1

Source local overrides last. Keep noninteractive-safe files separate from interactive-only files. This gives each machine room for local quirks without polluting templates.

7. Project launcher workflow

The project launcher should be the main command you remember.

Desired behavior:

text
p       choose project and cd
p e     choose project and open editor
p y     choose project and open Yazi
p g     choose project and open lazygit
p t     choose project and attach/create tmux session
p c     choose project and start Codex
p w     choose project worktree

Project discovery can combine:

text
configured roots such as ~/code
zoxide database
recent Git repositories
active tmux sessions
manual pinned projects
worktree directories

This is the highest-leverage workflow layer because it makes everything else easier to reach.

8. Terminal workflow

The terminal layer should manage the interface around the shell:

text
font family and size
theme
shell defaults
WSL launch profiles
starting directory policy
copy/paste behavior
keybindings
scrollback
bell behavior
window opacity, if desired

Use one primary cross-platform terminal if possible. WezTerm is a good candidate because it can cover Windows and Linux with one config. Windows Terminal, Konsole, Ghostty, and Alacritty can exist as minimal profiles or fallbacks, but avoid curating terminal configs you do not actually use.

9. Theme contract

Theme should be a contract, not a scavenger hunt.

A single theme data file should drive the obvious places:

text
Starship
VS Code
Sublime
terminal emulator
bat
delta
Yazi
tmux
LS_COLORS

A good target:

toml
[font]
mono = "Monaspace Neon"
size = 11

[theme]
flavour = "frappe"
accent = "mauve"

Use vivid if you want one managed source for LS_COLORS rather than scattered color escapes.

10. Yazi workflow

Yazi should become the file workflow bridge.

Useful actions:

text
open selected file in $EDITOR
open selected directory in the project launcher
open lazygit in the current directory
send selected directory to tmux
copy POSIX path
copy Windows path when in WSL
reveal file in OS file manager
extract archive
compress selected files
preview JSON through jless
preview text/code through bat
preview binary through hexyl

Pair Yazi with ouch for archive operations. The file manager should not require remembering seven different compression commands.

11. Git, gh, lazygit, and worktrees

Git should have both CLI helpers and lazygit/gh equivalents.

Useful commands:

text
git recent       recent branches
git root         repo root
git graph        readable graph
git fixup        create fixup commit
git amend        amend without changing message
git undo         soft-reset last commit
git gone         merged/deleted upstream branches
git pr           open current branch PR

Useful gh aliases:

text
mine       my open PRs
pv         view PR in browser
pw         watch PR checks
pc         checkout current PR
prune      careful merged-branch cleanup

Worktrees should be first-class:

text
create worktree from branch
create worktree from PR
switch to worktree
open worktree in tmux/editor/Yazi/lazygit/Codex
remove worktree safely

Worktrees are the sane way to handle parallel PRs. Stashing everything is not a personality trait.

12. Cross-platform wrappers

Expose the same command names across Fish, Bash, and PowerShell where possible:

text
open <path>       open with OS default app
edit <path>       open preferred editor
clip              copy stdin
paste             print clipboard
reveal <path>     reveal in file manager
path-win <path>   POSIX -> Windows path when in WSL
path-posix <path> Windows -> POSIX path when in WSL
trash <path>      move to trash, do not rm

These wrappers are small, but they remove a lot of “which OS am I on?” friction.

13. Project environments

Use this boundary:

text
mise    tool versions and PATH
direnv  project env vars, secret pointers, feature flags, local exports

Do not let direnv and mise both fight over PATH. If a project needs tool versions, put them in mise. If a project needs environment variables, use direnv.

A managed ~/.config/direnv/direnvrc can provide helpers such as:

text
dotenv_if_exists .env.local
source_up_if_exists .envrc.shared
layout_tmp
project_cache_dir

14. Editors

Editor config should cover behavior, not just settings.

The intended roles are:

text
Zed      preferred first-class GUI editor candidate under evaluation
VS Code  compatibility IDE, fallback, and Remote-WSL standard
Sublime  existing fast GUI file opener until Zed is manually validated
Micro    safe fallback terminal editor candidate
Neovim   installed for experimentation only; no managed config yet

Keep terminal editor policy separate from GUI editor policy. Do not delete VS Code or Sublime support just because Zed becomes first-class.

VS Code should have:

text
settings
keybindings
snippets
tasks
extension manifests
host overlays

Sublime should have:

text
preferences
key bindings
snippets
build systems
package manifest

Keep Sublime fast. Its job is to be a sharp editor, not a second IDE.

15. Codex workflow

Codex should be easy to invoke in the right place.

Candidate wrappers:

text
cx      Codex in current repo
cxr     review/read mode
cxi     implementation mode
cxd     deep review mode
cxq     quiet/low-noise mode
cxp     pick project, then start Codex

Codex wrappers should preserve the WSL/Linux-filesystem rule. Do not accidentally start Codex in Windows paths unless that is explicitly intended.

16. Notes, scratch, presentations, and diagrams

The repo already has writing tools. Add a workflow around them.

Candidate commands:

text
note      open notes index
today     open daily note
scratch   open scratch file
mdp       preview Markdown
typ       compile/watch Typst
diagram   render Mermaid

presenterm fits the writing lane for terminal-native Markdown presentations.

17. HTTP/API workflow

Use xh for one-off requests. Use hurl for repeatable request files and API smoke checks.

Useful templates:

text
json.hurl
auth-bearer.hurl
healthcheck.hurl

Do not commit tokens. Keep secrets in local env files, direnv-managed local files, or external secret stores.

18. Command palette and cheatsheets

Once the workflow grows, memory becomes the bottleneck.

Use either:

text
navi          interactive cheatsheets
custom fzf    dotfiles-owned command palette
gum           styled command menu

Good cheatsheet topics:

text
project launcher
Git worktrees
Yazi shortcuts
Codex modes
WSL path conversion
CachyOS maintenance
Scoop/mise diagnostics
notes and writing
HTTP/API requests
docs maintenance

19. Desktop layer

For CachyOS KDE, manage only stable preferences:

text
Konsole profile/color scheme
fontconfig
mimeapps.list
default editor/browser/file associations
a small set of stable KDE shortcuts
intentional autostart entries

Do not bulk-export Plasma config. That tends to fossilize random desktop state.

20. Tool add-ons

Strong candidates:

text
sesh         tmux/project session selection
vivid        LS_COLORS generation
ouch         archive compress/extract
jless        interactive JSON viewer
hurl         repeatable HTTP request files
tealdeer     fast tldr client
presenterm   terminal Markdown presentations

Optional candidates:

text
hexyl        readable hex viewer
numbat       unit-aware calculator
navi         interactive cheatsheets
zellij       optional terminal workspace alternative

Quality/docs helpers that should stay out of shell startup:

text
lychee              docs link checking
bats-core           shell helper tests
zizmor              GitHub Actions static analysis
PSScriptAnalyzer    PowerShell linting

Add a tool only when a workflow uses it. Installed ornaments still need dusting.

21. Non-goals

Do not add these unless the reason changes. See non-goals and anti-patterns for the full policy.

text
Bash-it as a dependency
large Fish plugin stack
prompt plugin frameworks competing with Starship
bulk Plasma config export
default topgrade automation
active WSL/Codex repos under Windows or UNC paths
duplicate package-manager ownership without documentation

Steal ideas from frameworks. Do not make the repo dependent on them unless the dependency earns its keep.

22. Documentation site recommendation

Use VitePress for the dotfiles docs site.

Why:

text
It is Markdown-first.
It fits a pnpm/Node-based repo better than a Python docs stack.
The default theme is enough for workflow docs.
It supports a normal docs sidebar and file-based routing.
It can be deployed as a static site with GitHub Pages.
It does not require React/MDX complexity unless you choose to add components later.

MkDocs Material is still excellent, but it adds a Python/MkDocs toolchain. Docusaurus is strong for product-style docs, React components, blogs, and versioning, but it is more machinery than these dotfiles need. Astro Starlight is also a good docs framework, but it adds the Astro stack; choose it only if you specifically want Astro.

Suggested structure:

text
docs/
  .vitepress/
    config.ts
  index.md
  philosophy/
    workflow-primer.md
    non-goals.md
  setup/
    index.md
    windows.md
    wsl.md
    cachyos.md
  workflows/
    index.md
    project-launcher.md
    shell.md
    terminal.md
    git.md
    yazi.md
    editors.md
    codex.md
    notes.md
    http-api.md
  tools/
    manifest.md
    mise.md
    scoop.md
    fish-plugins.md
    editor-extensions.md
  reference/
    host-lanes.md
    path-policy.md
    local-overrides.md
    troubleshooting.md
  decisions/
    index.md

Suggested scripts:

json
{
  "scripts": {
    "docs:dev": "vitepress dev docs",
    "docs:build": "vitepress build docs",
    "docs:preview": "vitepress preview docs"
  },
  "devDependencies": {
    "vitepress": "latest",
    "vue": "latest"
  }
}

The docs should explain how to use the setup, not just how to install it. Otherwise the repo becomes a very elaborate amnesia machine.

23. First docs pages to write

Start with these pages:

text
philosophy/workflow-primer.md
setup/index.md
workflows/project-launcher.md
workflows/shell.md
workflows/git.md
workflows/yazi.md
workflows/codex.md
tools/manifest.md
reference/host-lanes.md
reference/local-overrides.md
philosophy/non-goals.md

Do not wait for every workflow to be implemented before documenting the intended shape. The docs can say “planned” where needed. The point is to make the target architecture visible.