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.
Use docs/repo-maintenance.md for branch/bookmark PR hygiene commands.
Shell QA commands are available via just -f qa.just ... after mise install.
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.
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
...but only when your current directory is inside your chezmoi source path (chezmoi source-path).
This lets you keep your default global gh account while always using your personal profile in the chezmoi repo.
.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.