This repository stores personal shell/editor/tooling config and Windows setup assets.
Jujutsu user identity (name, email, and scoped overrides) is configured in two locations:
- PowerShell / Command Prompt / native shells:
AppData/Roaming/jj/config.toml(managed by chezmoi) - POSIX shells (Git Bash, WSL, etc.):
~/.config/jj/config.toml(managed by chezmoi)
Both targets are templated with the same profile-aware identity logic (work vs
personal). After chezmoi apply, verify JJ can find your config:
jj config path --user
jj config listBoth commands should show your configured user.name and user.email without
warnings in PowerShell and Command Prompt.
Use windows/backup/export.ps1 to snapshot common Windows app and terminal
config into this repo.
powershell -ExecutionPolicy Bypass -File .\windows\backup\export.ps1The script is safe to re-run. It only copies files that exist and skips missing targets.
Use linux/backup/export-apt-packages.sh to snapshot manual apt packages into
this repo.
bash ./linux/backup/export-apt-packages.shUse linux/backup/install-apt-packages.sh to install from
linux/apt-packages.txt.
Use docs/commit-message-guide.md for commit message conventions in this repo.
After chezmoi apply, the short policy mirrored under ~/.agents/rules/ is in
commit-messages.md (see also global-instructions.md).
Use docs/repo-maintenance.md for branch/bookmark PR hygiene, local
pre-commit hook setup (just repos::pre-commit-install), and the recommended
just repos::pre-commit-verify check before pushes or PRs. Shell QA commands
are available via just -f qa.just ... after mise install.
GitHub Actions runs pre-commit on PRs automatically; that does not install
hooks on your computer until you run just repos::pre-commit-install once in
the chezmoi source directory.
docs/config-matrix.mdcaptures what is shared vs platform-specific vs persona-specific.docs/drift-exceptions.mdtracks intentional differences between systems and why they exist.docs/chezmoi-profiles.mdexplainsworkvspersonalprofile usage.
Oh My Posh themes in dot_config/oh-my-posh/ use Nerd Font glyphs. Install
a Nerd Font on the host OS that owns the terminal window (on Windows + WSL,
that means Windows, not only Linux), then point Windows Terminal / Cursor at
that font. The UI font list may omit installed faces; prefer settings.json
profiles.defaults.font.face. Full steps: docs/prompt-font-setup.md.
Neovim (dot_config/nvim/init.lua) sets vim.g.have_nerd_font so UI icons
match that terminal baseline.
Reusable prompt snippets live in docs/prompts/.
Use scripts/oprompt.ps1 to print or copy one:
powershell -ExecutionPolicy Bypass -File .\scripts\oprompt.ps1 commit
powershell -ExecutionPolicy Bypass -File .\scripts\oprompt.ps1 pr-update -Copyscripts/aprompt.ps1 is kept as a backward-compatible wrapper to
scripts/oprompt.ps1.
powershell -ExecutionPolicy Bypass -File .\scripts\aprompt.ps1 commitFor WSL/macOS/Linux, use scripts/oprompt.sh:
./scripts/oprompt.sh commit
./scripts/oprompt.sh pr-update --copyAfter reloading your shell, you can also call oprompt from anywhere:
oprompt commit
oprompt pr-update --copyaprompt remains as a backward-compatible alias.
Neovim uses a profile-aware terminal command for AI CLI workflows:
workprofile setsAI_TERM_CMD=agentpersonalprofile setsAI_TERM_CMD=opencode
This is defined in dot_bash_profile.tmpl and dot_zshrc.tmpl.
dot_config/nvim/init.luaimportscustom.plugins.dot_config/nvim/lua/custom/plugins/ai_cli.luaconfigurestoggleterm.nvimand the AI terminal commands/keymaps.dot_config/nvim/lua/custom/plugins/ai_assistant.luaconfigurescodecompanion.nvimadapters and keymaps.
<leader>at: toggle AI terminal<leader>al: send current line<leader>as: send visual selection<leader>ah: send context (file path, cursor, diagnostics, nearby code)<leader>af: send current file (line-numbered, capped)<leader>ad: send git diff for current file<leader>aD: send staged git diff for current file<leader>ax: send diagnostics only<leader>ai: show AI command/terminal status<leader>ac: toggle CodeCompanion chat<leader>aa: open CodeCompanion actions<leader>ap: run inline CodeCompanion prompt (normal/visual):AiSend {text}: send ad-hoc text:AiHere [request]: send context with optional request text:AiFile [request]: send current file with optional request:AiDiag [request]: send diagnostics with optional request:AiDiff [request]: send working-tree diff for current file:AiDiffStaged [request]: send staged diff for current file:AiStatus: show configured command and availability
- The default command is
agentifAI_TERM_CMDis not set. toggleterm.nvimmust be installed via Lazy (run:Lazy syncafter config changes).- CodeCompanion can be split by interaction with env vars:
CODECOMPANION_CHAT_ADAPTER(chat)CODECOMPANION_INLINE_ADAPTER(inline)CODECOMPANION_ADAPTER(fallback for both)
- Work profile defaults to Cursor ACP chat (
cursor_acp->agent acp) and Copilot inline. - Personal profile defaults to OpenCode ACP chat (
opencode) andopenaiinline. - Optional Cursor ACP envs:
CURSOR_AGENT_BIN(defaultagent),CURSOR_API_KEY,CURSOR_AUTH_TOKEN. - Visual selection handling normalizes reversed selections to avoid
E5108(start_col must be <= end_col). - Optional tuning env vars:
AI_CONTEXT_LINES(default7)AI_FILE_LINES(default300)AI_DIFF_LINES(default300)
This Neovim config tracks newer APIs and plugins, and may not work with distro
apt packages on some Ubuntu releases.
- Prefer Neovim
0.11+(or current stable/nightly). - If
apt install neovimis too old for this config, build Neovim from source. - Confirm your active binary/version with:
command -v nvim
nvim --version | head -n 1If your distro apt package for mise is outdated, install/update mise via
cargo first:
cargo install miseInstall Rust/Cargo first if needed: https://rust-lang.org/tools/install/
Then use mise to install Zig and follow Neovim's Zig build flow:
mise use -g zig@0.15.2
git clone https://github.com/neovim/neovim.git
cd neovim
zig build
./zig-out/bin/nvim --version | head -n 1
zig build install --prefix ~/.localIf you install Neovim to ~/.local/bin, ensure it comes before /usr/bin in
PATH.
Core code navigation (LSP):
grd: go to definitiongrD: go to declarationgrr: find referencesgri: go to implementationgrt: go to type definitiongrn: rename symbolgra: code actiongO: document symbolsgW: workspace symbols<leader>q: diagnostics list<leader>sd: diagnostics picker
Window/project movement:
Ctrl-h/j/k/l: move between windows<leader>sf: find files<leader>sg: live grep<leader><leader>: find buffers
Kotlin/Gradle helpers:
<leader>kb: gradle build<leader>kt: gradle test<leader>kr: gradle bootRun<leader>kk: prompt for custom gradle task<leader>k?or:KotlinKeys: open in-editor key reference
Dart/Web helpers:
<leader>dr: dart run<leader>dt: dart test<leader>ds: dart run webdev serve --auto=refresh<leader>db: dart run build_runner build --delete-conflicting-outputs<leader>dw: dart run build_runner watch --delete-conflicting-outputs<leader>dd: prompt for custom dart args<leader>d?or:DartKeys: open in-editor key reference
dot_tmux.conf is configured for a modern Neovim-centric workflow:
- Vim-aware pane navigation with
Ctrl-h/j/k/l - Pane splits inherit current working directory
- Vi copy mode bindings with macOS clipboard integration
- Mouse support, larger scrollback, and readable status line
- Pane resize with prefix +
Shift+H/J/K/L, or alternate chords on macOS: prefix +Ctrl+h/j/k/lor prefix +Option+h/j/k/l(requires terminal Meta; see comments indot_tmux.conf) - Auto-tiling: panes retile after split/close/resize; prefix +
tto force tiled layout - Session/window pickers: prefix +
s(sessions), prefix +w(windows)
On macOS, bare Ctrl+h/j/k/l can collide with tty backspace/readline
(Ctrl+l clears the shell line in Emacs-style editing), Secure Keyboard Entry
(password prompts steal all keys), or Mission Control (Ctrl + arrows) if
you bind arrows to tmux elsewhere. Resize with Shift can conflict with IME
or accessibility shortcuts—use the Ctrl or Option resize aliases
described above and in dot_tmux.conf.
Plugins are configured in dot_tmux.conf. TPM is cloned automatically on first
chezmoi apply. Run prefix + I inside tmux to install plugins. Includes
tmux-sensible, tmux-resurrect, tmux-continuum, tmux-fzf.
Use tmuxdev (shell function in dot_bash_profile.tmpl / dot_zshrc.tmpl),
implemented by scripts/tmux-dev-session.sh:
tmuxdev # web layout, session = dir name, path = PWD
tmuxdev my-session # web layout, session my-session, path = PWD
tmuxdev my-session ~/proj # web layout, session my-session, path ~/proj
tmuxdev dev # dev layout (editor + AI CLI, tests, shell), session = dir name
tmuxdev dev work ~/proj # dev layout, session work, path ~/proj- web (default): editor (nvim, git st, ls), runtime, test, ops windows.
Built with plain
tmuxcommands (no tmuxp): tmuxp/libtmux routinely fails while creating multi-pane windows on current tmux (e.g.can't find pane: %1). - dev: editor (Neovim + AI CLI pane), tests, shell.
Path resolution (when you omit an explicit path, or after resolving the path you pass):
- Git: working directory is normalized to
git rev-parse --show-toplevel(correct worktree root). - Jujutsu: if Git does not apply, the directory is normalized with
jj workspace root. - Project-task tasks (
$DEV_ROOT/projects/<project>/<type>/<task-id>/, defaultDEV_ROOT=$HOME/dev): iftask.jsonlists one linked checkout, the session uses that repo; if it lists several, the default session name is the task-id, the primary repo is chosen from your current directory (best prefix match), web adds a repos window for the other checkouts, and dev keeps editor/AI on the primary repo but uses the task directory for the tests/shell windows. See Project/task workspaces.
Environment (optional):
| Variable | Effect |
|---|---|
DEV_ROOT |
Root containing projects/… (default: $HOME/dev). |
TMUXDEV_NO_RESOLVE=1 |
Disable Git, Jujutsu, and task.json handling; use paths as given. |
TMUXDEV_RESOLVE_TASK=0 |
Skip task.json only; Git/Jujutsu normalization still runs (unless NO_RESOLVE). |
The shell config includes a gh wrapper that automatically sets:
GH_CONFIG_DIR=$HOME/.config/gh-personal
...when your current directory is either:
- under
$HOME/dev/repos/github.com/aguil, or - inside your chezmoi source path (
chezmoi source-path).
This lets you keep your default global gh account while always using your
personal profile for those trees.
Overlay profiles can extend the wrapper without replacing it by installing route files in:
~/.config/chezmoi/gh-routes.d/*.sh
Each route file can call:
gh_route "$HOME/.local/share/chezmoi-work" "$HOME/.config/gh-work"Routes are checked before the built-in personal routes, so overlay repositories
can use their own GH_CONFIG_DIR without changing the global active gh
account.
.chezmoiscripts/run_after_21-gh-personal-auth.sh.tmpl bootstraps auth for the
personal gh profile when needed.
It uses:
GH_CONFIG_DIRfromCHEZMOI_GH_CONFIG_DIR(default:$HOME/.config/gh-personal)CHEZMOI_GH_TOKEN_OP_REF/.gh.tokenOpRefto read the token via 1Password CLI (op)
Run:
ghpersonalauthThis logs in gh using the dedicated config dir and validates auth status.