Merge remote-tracking branch 'origin/master'
# Conflicts: # home_config/ghostty/config # home_root/.zshrc
This commit is contained in:
@@ -2,4 +2,8 @@
|
|||||||
.config/btop
|
.config/btop
|
||||||
.config/neofetch
|
.config/neofetch
|
||||||
/.aider*
|
/.aider*
|
||||||
|
home_config/nvim/lazy-lock.json
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
*.bak
|
||||||
|
# zellij web-pilot auth tokens — credentials, never commit
|
||||||
|
home_config/zellij/pilot-tokens/
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# dotfiles
|
||||||
|
|
||||||
|
Personal dotfiles. Configs are organized by where they get linked:
|
||||||
|
|
||||||
|
| Folder | Links into | Examples |
|
||||||
|
| -------------- | ------------ | --------------------------------- |
|
||||||
|
| `home_root` | `~` | `.zshrc`, `.wezterm.lua`, `.nanorc` |
|
||||||
|
| `home_config` | `~/.config` | `nvim`, `zellij`, `ghostty`, `aerospace` |
|
||||||
|
| `windows` | Windows-only | `windows-terminal/settings.json` |
|
||||||
|
| `lk-installers`| n/a | helper scripts to install tooling |
|
||||||
|
|
||||||
|
## Linux / macOS (GNU stow)
|
||||||
|
|
||||||
|
One-shot, host-aware:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./link-dotfiles # link only (installs stow if missing)
|
||||||
|
./link-dotfiles --apps # fresh box: install all CLI tools, then link
|
||||||
|
```
|
||||||
|
|
||||||
|
It detects the host (macOS vs Linux), installs [`stow`](https://www.gnu.org/software/stow/)
|
||||||
|
if missing (Homebrew on macOS; apt/dnf/pacman on Linux), then runs
|
||||||
|
`stow home_root` and `stow --target=$HOME/.config home_config`. Re-running is
|
||||||
|
safe — stow is idempotent.
|
||||||
|
|
||||||
|
### Installing the tools
|
||||||
|
|
||||||
|
The configs assume a handful of CLI tools (`bat`, `fd`, `fzf`, `zoxide`,
|
||||||
|
`zellij`, `nvim`, `btop`, `htop`, `tldr`, `fastfetch`, plus the `fzf-git.sh`
|
||||||
|
helper). One host-aware installer covers them:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./lk-installers/install-apps # macOS -> Homebrew; Linux -> apt + upstream
|
||||||
|
```
|
||||||
|
|
||||||
|
On macOS it bootstraps Homebrew if absent. It's idempotent — re-running only
|
||||||
|
fills gaps. `./link-dotfiles --apps` just runs this first, then links.
|
||||||
|
|
||||||
|
The zsh prompt and plugins (zinit, Powerlevel10k, autosuggestions,
|
||||||
|
syntax-highlighting, completions, vi-mode, fzf-tab) **self-install** from
|
||||||
|
`.zshrc` on first shell start, so they're not part of `install-apps`.
|
||||||
|
|
||||||
|
## Windows (PowerShell)
|
||||||
|
|
||||||
|
`stow` doesn't run natively on Windows, so use the PowerShell equivalent. It
|
||||||
|
mirrors stow by creating **junctions** for directories and **symlinks/hardlinks**
|
||||||
|
for files — none of which require administrator rights:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
pwsh -File .\link-dotfiles.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
- Re-running is safe: already-correct links are skipped.
|
||||||
|
- Any real file/dir that would be overwritten is moved aside to `<name>.bak`.
|
||||||
|
- Preview without changing anything: `pwsh -File .\link-dotfiles.ps1 -DryRun`
|
||||||
|
|
||||||
|
The repo stays the source of truth — edit files under `home_root` /
|
||||||
|
`home_config` and the linked locations update live.
|
||||||
|
|
||||||
|
### Windows Terminal
|
||||||
|
|
||||||
|
`windows/windows-terminal/settings.json` is linked into the Terminal package
|
||||||
|
folder (`...\Microsoft.WindowsTerminal_*\LocalState\settings.json`) by
|
||||||
|
`link-dotfiles.ps1`. Because it's linked, changes you make in the Terminal UI
|
||||||
|
write straight back into this repo. The settings include the **Australis**
|
||||||
|
color scheme and the **VictorMono Nerd Font Mono** profile font; install the
|
||||||
|
font (see below) so glyphs render.
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
**zsh uses [Powerlevel10k](https://github.com/romkatv/powerlevel10k)** — loaded
|
||||||
|
through zinit straight from `.zshrc`, with the instant-prompt preamble near the
|
||||||
|
top for fast startup. The theme config lives at `home_root/.p10k.zsh` (stowed to
|
||||||
|
`~/.p10k.zsh`); there's no separate installer — zinit fetches it on first shell
|
||||||
|
start.
|
||||||
|
|
||||||
|
PowerShell uses [starship](https://starship.rs/) (configured separately).
|
||||||
|
|
||||||
|
Both expect a **Nerd Font v3** (e.g. **VictorMono Nerd Font Mono**) installed and
|
||||||
|
selected in your terminal for glyphs to render.
|
||||||
+45
-30
@@ -1,38 +1,53 @@
|
|||||||
# Font
|
# Ghostty configuration
|
||||||
font-family = VictorMono Nerd Font
|
# Docs: https://ghostty.org/docs/config
|
||||||
font-size = 16
|
# Reload in-app without restarting: Cmd+Shift+,
|
||||||
font-style = Regular
|
|
||||||
font-style-bold = Bold
|
# --- Font ---------------------------------------------------------------
|
||||||
font-style-italic = Italic
|
# VictorMono Nerd Font (installed in ~/Library/Fonts). The "Mono" variant
|
||||||
font-style-bold-italic = Bold Italic
|
# keeps glyphs strictly fixed-width, which is what you want in a terminal.
|
||||||
adjust-cell-height = 5%
|
font-family = VictorMono Nerd Font Mono
|
||||||
|
font-size = 14
|
||||||
|
# Slightly heavier strokes render nicer on macOS Retina displays.
|
||||||
font-thicken = true
|
font-thicken = true
|
||||||
|
|
||||||
# Theme
|
# Victor Mono ships a gorgeous cursive italic — make sure it's used.
|
||||||
|
font-style-italic = Italic
|
||||||
|
|
||||||
|
# --- Theme --------------------------------------------------------------
|
||||||
|
# Australis (Aurora Australis) — a dark theme. Defined in
|
||||||
|
# ~/.config/ghostty/themes/australis (ported from the upstream WezTerm config).
|
||||||
theme = australis
|
theme = australis
|
||||||
|
|
||||||
# Window
|
# --- Cursor -------------------------------------------------------------
|
||||||
window-padding-x = 10
|
cursor-style = block
|
||||||
window-padding-y = 10
|
cursor-style-blink = false
|
||||||
window-padding-balance = true
|
|
||||||
background-opacity = 0.95
|
|
||||||
background-blur-radius = 20
|
|
||||||
macos-titlebar-style = tabs
|
|
||||||
|
|
||||||
# Cursor
|
|
||||||
cursor-style = bar
|
|
||||||
cursor-style-blink = true
|
|
||||||
|
|
||||||
# Behavior
|
|
||||||
scrollback-limit = 10000
|
|
||||||
mouse-hide-while-typing = true
|
mouse-hide-while-typing = true
|
||||||
copy-on-select = false
|
|
||||||
confirm-close-surface = false
|
|
||||||
|
|
||||||
# Shell integration
|
# --- Window -------------------------------------------------------------
|
||||||
|
window-padding-x = 8
|
||||||
|
window-padding-y = 6
|
||||||
|
# Keep padding color matched to the background for a clean look.
|
||||||
|
window-padding-balance = true
|
||||||
|
# Reopen with the same windows/tabs you left.
|
||||||
|
window-save-state = always
|
||||||
|
macos-titlebar-style = tabs
|
||||||
|
background-opacity = 0.97
|
||||||
|
|
||||||
|
# --- Clipboard / selection ---------------------------------------------
|
||||||
|
copy-on-select = clipboard
|
||||||
|
clipboard-trim-trailing-spaces = true
|
||||||
|
|
||||||
|
# --- macOS / shell behavior --------------------------------------------
|
||||||
|
# Let the left Option key send Alt (so Alt+f, Alt+b, etc. work in shells/
|
||||||
|
# editors); keep right Option for composing accented characters.
|
||||||
|
macos-option-as-alt = left
|
||||||
shell-integration = detect
|
shell-integration = detect
|
||||||
shell-integration-features = cursor,sudo,title
|
# ssh-env + ssh-terminfo: on connect, propagate a compatible TERM and
|
||||||
|
# auto-install Ghostty's terminfo entry on the remote host (v1.2.0+), so
|
||||||
|
# remote apps render correctly without "unknown terminal type" errors.
|
||||||
|
shell-integration-features = cursor,sudo,title,ssh-env,ssh-terminfo
|
||||||
|
|
||||||
# Rendering
|
# --- Misc ---------------------------------------------------------------
|
||||||
bold-is-bright = false
|
# Only prompt to close when a process is still running.
|
||||||
minimum-contrast = 1.1
|
confirm-close-surface = true
|
||||||
|
scrollback-limit = 10000000
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
{
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
"LazyVim": { "branch": "main", "commit": "3f034d0a7f58031123300309f2efd3bb0356ee21" },
|
||||||
|
"blink.cmp": { "branch": "main", "commit": "4607923f60029f8cb28e6950a078f93fd33e1288" },
|
||||||
|
=======
|
||||||
"LazyVim": { "branch": "main", "commit": "ec5981dfb1222c3bf246d9bcaa713d5cfa486fbd" },
|
"LazyVim": { "branch": "main", "commit": "ec5981dfb1222c3bf246d9bcaa713d5cfa486fbd" },
|
||||||
"blink.cmp": { "branch": "main", "commit": "49f211fe5d729df53df4c042d7c3464cf47d199e" },
|
"blink.cmp": { "branch": "main", "commit": "49f211fe5d729df53df4c042d7c3464cf47d199e" },
|
||||||
|
>>>>>>> 00717500056db846954b09bcfac4ebb3f1aa84e6
|
||||||
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
|
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
|
||||||
"catppuccin": { "branch": "main", "commit": "5b5e3aef9ad7af84f463d17b5479f06b87d5c429" },
|
"catppuccin": { "branch": "main", "commit": "5b5e3aef9ad7af84f463d17b5479f06b87d5c429" },
|
||||||
"conform.nvim": { "branch": "master", "commit": "f9ef25a7ef00267b7d13bfc00b0dea22d78702d5" },
|
"conform.nvim": { "branch": "master", "commit": "f9ef25a7ef00267b7d13bfc00b0dea22d78702d5" },
|
||||||
"flash.nvim": { "branch": "main", "commit": "3c942666f115e2811e959eabbdd361a025db8b63" },
|
"flash.nvim": { "branch": "main", "commit": "3c942666f115e2811e959eabbdd361a025db8b63" },
|
||||||
"friendly-snippets": { "branch": "main", "commit": "efff286dd74c22f731cdec26a70b46e5b203c619" },
|
"friendly-snippets": { "branch": "main", "commit": "efff286dd74c22f731cdec26a70b46e5b203c619" },
|
||||||
"gitsigns.nvim": { "branch": "main", "commit": "7010000889bfb6c26065e0b0f7f1e6aa9163edd9" },
|
"gitsigns.nvim": { "branch": "main", "commit": "7010000889bfb6c26065e0b0f7f1e6aa9163edd9" },
|
||||||
|
<<<<<<< HEAD
|
||||||
|
"grug-far.nvim": { "branch": "main", "commit": "2c7ef09353714bd4954f5459d9a7e2579a050dc7" },
|
||||||
|
=======
|
||||||
"grug-far.nvim": { "branch": "main", "commit": "5da116bc99a03e14be3b824e319f4e49c676af78" },
|
"grug-far.nvim": { "branch": "main", "commit": "5da116bc99a03e14be3b824e319f4e49c676af78" },
|
||||||
|
>>>>>>> 00717500056db846954b09bcfac4ebb3f1aa84e6
|
||||||
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
|
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
|
||||||
"lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" },
|
"lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" },
|
||||||
"lualine.nvim": { "branch": "master", "commit": "9fef261b53fbe3a2ef01ee9667f6fde064b1ed10" },
|
"lualine.nvim": { "branch": "master", "commit": "9fef261b53fbe3a2ef01ee9667f6fde064b1ed10" },
|
||||||
@@ -15,12 +24,21 @@
|
|||||||
"mason.nvim": { "branch": "main", "commit": "fc98833b6da5de5a9c5b1446ac541577059555be" },
|
"mason.nvim": { "branch": "main", "commit": "fc98833b6da5de5a9c5b1446ac541577059555be" },
|
||||||
"mini.ai": { "branch": "main", "commit": "978ffc65c6b513fde9ef075326d34d89197f1ea5" },
|
"mini.ai": { "branch": "main", "commit": "978ffc65c6b513fde9ef075326d34d89197f1ea5" },
|
||||||
"mini.icons": { "branch": "main", "commit": "ec61af6e606fc89ee3b1d8f2f20166a3ca917a36" },
|
"mini.icons": { "branch": "main", "commit": "ec61af6e606fc89ee3b1d8f2f20166a3ca917a36" },
|
||||||
|
<<<<<<< HEAD
|
||||||
|
"mini.pairs": { "branch": "main", "commit": "cd9d95e33645781f86ca5ffe0a6885a22d59f127" },
|
||||||
|
"noice.nvim": { "branch": "main", "commit": "0427460c2d7f673ad60eb02b35f5e9926cf67c59" },
|
||||||
|
"nui.nvim": { "branch": "main", "commit": "8d3bce9764e627b62b07424e0df77f680d47ffdb" },
|
||||||
|
"nvim-lint": { "branch": "master", "commit": "936197073214c26a347fb933c9459c8766376b23" },
|
||||||
|
"nvim-lspconfig": { "branch": "master", "commit": "fb733ac734249ccf293e5c8018981d4d8f59fa8f" },
|
||||||
|
"nvim-treesitter": { "branch": "master", "commit": "d26ce0126694283cf32bf1f4192ef37ef404c037" },
|
||||||
|
=======
|
||||||
"mini.pairs": { "branch": "main", "commit": "b90e36aa5ca5e0d825e77ad67aac22214a4d9096" },
|
"mini.pairs": { "branch": "main", "commit": "b90e36aa5ca5e0d825e77ad67aac22214a4d9096" },
|
||||||
"noice.nvim": { "branch": "main", "commit": "0427460c2d7f673ad60eb02b35f5e9926cf67c59" },
|
"noice.nvim": { "branch": "main", "commit": "0427460c2d7f673ad60eb02b35f5e9926cf67c59" },
|
||||||
"nui.nvim": { "branch": "main", "commit": "8d3bce9764e627b62b07424e0df77f680d47ffdb" },
|
"nui.nvim": { "branch": "main", "commit": "8d3bce9764e627b62b07424e0df77f680d47ffdb" },
|
||||||
"nvim-lint": { "branch": "master", "commit": "93b8040115c9114dac1047311763bef275e752dc" },
|
"nvim-lint": { "branch": "master", "commit": "93b8040115c9114dac1047311763bef275e752dc" },
|
||||||
"nvim-lspconfig": { "branch": "master", "commit": "401e50fae626c4707af12114b5ddb7bb9f4236a4" },
|
"nvim-lspconfig": { "branch": "master", "commit": "401e50fae626c4707af12114b5ddb7bb9f4236a4" },
|
||||||
"nvim-treesitter": { "branch": "master", "commit": "85168f15808d89b0222313652b9d2777eda3cb08" },
|
"nvim-treesitter": { "branch": "master", "commit": "85168f15808d89b0222313652b9d2777eda3cb08" },
|
||||||
|
>>>>>>> 00717500056db846954b09bcfac4ebb3f1aa84e6
|
||||||
"nvim-treesitter-textobjects": { "branch": "master", "commit": "9937e5e356e5b227ec56d83d0a9d0a0f6bc9cad4" },
|
"nvim-treesitter-textobjects": { "branch": "master", "commit": "9937e5e356e5b227ec56d83d0a9d0a0f6bc9cad4" },
|
||||||
"nvim-ts-autotag": { "branch": "main", "commit": "a1d526af391f6aebb25a8795cbc05351ed3620b5" },
|
"nvim-ts-autotag": { "branch": "main", "commit": "a1d526af391f6aebb25a8795cbc05351ed3620b5" },
|
||||||
"persistence.nvim": { "branch": "main", "commit": "166a79a55bfa7a4db3e26fc031b4d92af71d0b51" },
|
"persistence.nvim": { "branch": "main", "commit": "166a79a55bfa7a4db3e26fc031b4d92af71d0b51" },
|
||||||
|
|||||||
@@ -1,136 +0,0 @@
|
|||||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json
|
|
||||||
|
|
||||||
version: 2
|
|
||||||
final_space: true
|
|
||||||
console_title_template: "{{ .Shell }} in {{ .Folder }}"
|
|
||||||
blocks:
|
|
||||||
- type: prompt
|
|
||||||
alignment: left
|
|
||||||
segments:
|
|
||||||
- type: session
|
|
||||||
style: diamond
|
|
||||||
foreground: p:black
|
|
||||||
background: p:yellow
|
|
||||||
leading_diamond:
|
|
||||||
trailing_diamond:
|
|
||||||
template: " {{ if .SSHSession }}\ueba9 {{ end }}{{ .UserName }} "
|
|
||||||
- type: path
|
|
||||||
style: powerline
|
|
||||||
powerline_symbol:
|
|
||||||
foreground: p:white
|
|
||||||
background: p:orange
|
|
||||||
template: " \uea83 {{ path .Path .Location }} "
|
|
||||||
properties:
|
|
||||||
style: folder
|
|
||||||
- type: git
|
|
||||||
style: powerline
|
|
||||||
powerline_symbol:
|
|
||||||
foreground: p:black
|
|
||||||
foreground_templates:
|
|
||||||
- "{{ if or (.Working.Changed) (.Staging.Changed) }}p:black{{ end }}"
|
|
||||||
- "{{ if and (gt .Ahead 0) (gt .Behind 0) }}p:white{{ end }}"
|
|
||||||
- "{{ if gt .Ahead 0 }}p:white{{ end }}"
|
|
||||||
background: p:green
|
|
||||||
background_templates:
|
|
||||||
- "{{ if or (.Working.Changed) (.Staging.Changed) }}p:yellow{{ end }}"
|
|
||||||
- "{{ if and (gt .Ahead 0) (gt .Behind 0) }}p:red{{ end }}"
|
|
||||||
- "{{ if gt .Ahead 0 }}#49416D{{ end }}"
|
|
||||||
- "{{ if gt .Behind 0 }}#7A306C{{ end }}"
|
|
||||||
template: " {{ if .UpstreamURL }}{{ url .UpstreamIcon .UpstreamURL }} {{ end }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }} \uf044 {{ .Working.String }}{{ end }}{{ if .Staging.Changed }} \uf046 {{ .Staging.String }}{{ end }} "
|
|
||||||
properties:
|
|
||||||
branch_max_length: 25
|
|
||||||
fetch_status: true
|
|
||||||
fetch_upstream_icon: true
|
|
||||||
- type: root
|
|
||||||
style: powerline
|
|
||||||
powerline_symbol:
|
|
||||||
foreground: p:white
|
|
||||||
background: p:yellow
|
|
||||||
template: " \uf0e7 "
|
|
||||||
- type: status
|
|
||||||
style: diamond
|
|
||||||
foreground: p:white
|
|
||||||
background: p:blue
|
|
||||||
background_templates:
|
|
||||||
- "{{ if gt .Code 0 }}p:red{{ end }}"
|
|
||||||
leading_diamond: <transparent,background></>
|
|
||||||
trailing_diamond:
|
|
||||||
template: " {{ if gt .Code 0 }}\uf00d{{ else }}\uf00c{{ end }} "
|
|
||||||
properties:
|
|
||||||
always_enabled: true
|
|
||||||
- type: rprompt
|
|
||||||
segments:
|
|
||||||
- type: node
|
|
||||||
style: plain
|
|
||||||
foreground: p:green
|
|
||||||
background: transparent
|
|
||||||
template: "\ue718 "
|
|
||||||
properties:
|
|
||||||
display_mode: files
|
|
||||||
fetch_package_manager: false
|
|
||||||
home_enabled: false
|
|
||||||
- type: go
|
|
||||||
style: plain
|
|
||||||
foreground: p:blue
|
|
||||||
background: transparent
|
|
||||||
template: "\ue626 "
|
|
||||||
properties:
|
|
||||||
fetch_version: false
|
|
||||||
- type: python
|
|
||||||
style: plain
|
|
||||||
foreground: p:yellow
|
|
||||||
background: transparent
|
|
||||||
template: "\ue235 "
|
|
||||||
properties:
|
|
||||||
display_mode: files
|
|
||||||
fetch_version: false
|
|
||||||
fetch_virtual_env: false
|
|
||||||
- type: shell
|
|
||||||
style: plain
|
|
||||||
foreground: p:white
|
|
||||||
background: transparent
|
|
||||||
template: "in <p:blue><b>{{ .Name }}</b></> "
|
|
||||||
- type: time
|
|
||||||
style: plain
|
|
||||||
foreground: p:white
|
|
||||||
background: transparent
|
|
||||||
template: at <p:blue><b>{{ .CurrentDate | date "15:04:05" }}</b></>
|
|
||||||
tooltips:
|
|
||||||
- type: aws
|
|
||||||
tips:
|
|
||||||
- aws
|
|
||||||
style: diamond
|
|
||||||
foreground: p:white
|
|
||||||
background: p:orange
|
|
||||||
leading_diamond:
|
|
||||||
trailing_diamond:
|
|
||||||
template: " \ue7ad {{ .Profile }}{{ if .Region }}@{{ .Region }}{{ end }} "
|
|
||||||
properties:
|
|
||||||
display_default: true
|
|
||||||
- type: az
|
|
||||||
tips:
|
|
||||||
- az
|
|
||||||
style: diamond
|
|
||||||
foreground: p:white
|
|
||||||
background: p:blue
|
|
||||||
leading_diamond:
|
|
||||||
trailing_diamond:
|
|
||||||
template: " \uebd8 {{ .Name }} "
|
|
||||||
properties:
|
|
||||||
display_default: true
|
|
||||||
transient_prompt:
|
|
||||||
foreground: p:black
|
|
||||||
background: transparent
|
|
||||||
template: "<p:yellow,transparent>\ue0b6</><,p:yellow> {{ .Folder }} </><p:yellow,transparent>\ue0b0</> "
|
|
||||||
secondary_prompt:
|
|
||||||
foreground: p:black
|
|
||||||
background: transparent
|
|
||||||
template: "<p:yellow,transparent>\ue0b6</><,p:yellow> > </><p:yellow,transparent>\ue0b0</> "
|
|
||||||
palette:
|
|
||||||
black: "#262B44"
|
|
||||||
blue: "#4B95E9"
|
|
||||||
green: "#59C9A5"
|
|
||||||
orange: "#F07623"
|
|
||||||
red: "#D81E5B"
|
|
||||||
white: "#E0DEF4"
|
|
||||||
yellow: "#F3AE35"
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#:schema https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json
|
|
||||||
console_title_template = '{{if .Root}}(Admin){{end}} {{.PWD}}'
|
|
||||||
version = 2
|
|
||||||
|
|
||||||
[palette]
|
|
||||||
black = '#222531'
|
|
||||||
bright_black = '#373b46'
|
|
||||||
blue = '#6388D8'
|
|
||||||
bright_blue = '#a4c4ff'
|
|
||||||
cyan = '#00b1a8'
|
|
||||||
bright_cyan = '#42dcd1'
|
|
||||||
green = '#16B866'
|
|
||||||
bright_green = '#51e08a'
|
|
||||||
magenta = '#9d78ff'
|
|
||||||
bright_magenta = '#d8adff'
|
|
||||||
red = '#ff491a'
|
|
||||||
bright_red = '#ff854f'
|
|
||||||
white = '#a9bcc3'
|
|
||||||
bright_white = '#cce7ec'
|
|
||||||
yellow = '#e1c631'
|
|
||||||
bright_yellow = '#FFE14E'
|
|
||||||
dark_30 = '#414751'
|
|
||||||
dark_40 = '#565f69'
|
|
||||||
dark_50 = '#6e7882'
|
|
||||||
dark_60 = '#86929d'
|
|
||||||
bright_70 = '#9daeb6'
|
|
||||||
bright_80 = '#b3cbcf'
|
|
||||||
bright_90 = '#cce7ec'
|
|
||||||
|
|
||||||
[[blocks]]
|
|
||||||
alignment = 'left'
|
|
||||||
type = 'prompt'
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
type = 'os'
|
|
||||||
style = 'plain'
|
|
||||||
foreground = 'p:cyan'
|
|
||||||
template = '{{.Icon}} '
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
foreground = 'p:dark_50'
|
|
||||||
style = 'plain'
|
|
||||||
template = '{{ .Path }} {{ if not .Writable}}<p:bright_red></> {{end}}'
|
|
||||||
type = 'path'
|
|
||||||
|
|
||||||
[blocks.segments.properties]
|
|
||||||
style = 'agnoster'
|
|
||||||
|
|
||||||
[[blocks]]
|
|
||||||
alignment = 'left'
|
|
||||||
type = 'prompt'
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
type = 'python'
|
|
||||||
foreground = 'p:blue'
|
|
||||||
background = "p:bright_black"
|
|
||||||
leading_diamond = ""
|
|
||||||
style = "diamond"
|
|
||||||
trailing_diamond = " "
|
|
||||||
template = " {{ .Venv }} "
|
|
||||||
|
|
||||||
[blocks.segments.properties]
|
|
||||||
display_default = false
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
foreground = 'p:bright_cyan'
|
|
||||||
background = "p:bright_black"
|
|
||||||
leading_diamond = ""
|
|
||||||
style = "diamond"
|
|
||||||
trailing_diamond = ""
|
|
||||||
template = " {{ .UpstreamIcon }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }}<p:yellow> </>{{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .Staging.Changed }} {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0 }} {{ .StashCount }}{{ end }} "
|
|
||||||
type = 'git'
|
|
||||||
|
|
||||||
[blocks.segments.properties]
|
|
||||||
branch_icon = ' '
|
|
||||||
commit_icon = ' '
|
|
||||||
merge_icon = ' '
|
|
||||||
no_commits_icon = ' '
|
|
||||||
rebase_icon = ' '
|
|
||||||
revert_icon = ' '
|
|
||||||
tag_icon = ' '
|
|
||||||
fetch_stash_count = true
|
|
||||||
fetch_status = true
|
|
||||||
fetch_upstream_icon = true
|
|
||||||
|
|
||||||
[[blocks]]
|
|
||||||
type = "prompt"
|
|
||||||
alignment = "right"
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
foreground = 'p:green'
|
|
||||||
style = 'plain'
|
|
||||||
template = '{{ .FormattedMs }}'
|
|
||||||
type = 'executiontime'
|
|
||||||
|
|
||||||
[blocks.segments.properties]
|
|
||||||
style = 'austin'
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
type = "time"
|
|
||||||
style = "plain"
|
|
||||||
foreground = "p:dark_30"
|
|
||||||
|
|
||||||
[blocks.segments.properties]
|
|
||||||
time_format = "3:04:05pm"
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
type = "session"
|
|
||||||
style = "plain"
|
|
||||||
foreground = "p:dark_50"
|
|
||||||
template = "{{.UserName}}"
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
type = "session"
|
|
||||||
style = "plain"
|
|
||||||
foreground = "p:cyan"
|
|
||||||
template = " {{ if .SSHSession }} {{ else }}@{{ end }} "
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
type = "session"
|
|
||||||
style = "plain"
|
|
||||||
foreground = "p:blue"
|
|
||||||
template = "{{.HostName}}"
|
|
||||||
|
|
||||||
[[blocks]]
|
|
||||||
type = 'prompt'
|
|
||||||
alignment = 'left'
|
|
||||||
newline = true
|
|
||||||
|
|
||||||
[[blocks.segments]]
|
|
||||||
type = 'text'
|
|
||||||
style = 'plain'
|
|
||||||
foreground_templates = [
|
|
||||||
"{{if gt .Code 0}}p:red{{end}}",
|
|
||||||
"{{if eq .Code 0}}p:bright_green{{end}}",
|
|
||||||
]
|
|
||||||
background = 'transparent'
|
|
||||||
template = '❯ '
|
|
||||||
|
|
||||||
[transient_prompt]
|
|
||||||
foreground_templates = [
|
|
||||||
"{{if gt .Code 0}}p:red{{end}}",
|
|
||||||
"{{if eq .Code 0}}p:bright_green{{end}}",
|
|
||||||
]
|
|
||||||
background = 'transparent'
|
|
||||||
template = '❯ '
|
|
||||||
|
|
||||||
[secondary_prompt]
|
|
||||||
foreground = 'p:bright_green'
|
|
||||||
background = 'transparent'
|
|
||||||
template = '❯❯ '
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,26 +0,0 @@
|
|||||||
# The Fuck settings file
|
|
||||||
#
|
|
||||||
# The rules are defined as in the example bellow:
|
|
||||||
#
|
|
||||||
# rules = ['cd_parent', 'git_push', 'python_command', 'sudo']
|
|
||||||
#
|
|
||||||
# The default values are as follows. Uncomment and change to fit your needs.
|
|
||||||
# See https://github.com/nvbn/thefuck#settings for more information.
|
|
||||||
#
|
|
||||||
|
|
||||||
# rules = [<const: All rules enabled>]
|
|
||||||
# exclude_rules = []
|
|
||||||
# wait_command = 3
|
|
||||||
# require_confirmation = True
|
|
||||||
# no_colors = False
|
|
||||||
# debug = False
|
|
||||||
# priority = {}
|
|
||||||
# history_limit = None
|
|
||||||
# alter_history = True
|
|
||||||
# wait_slow_command = 15
|
|
||||||
# slow_commands = ['lein', 'react-native', 'gradle', './gradlew', 'vagrant']
|
|
||||||
# repeat = False
|
|
||||||
# instant_mode = False
|
|
||||||
# num_close_matches = 3
|
|
||||||
# env = {'LC_ALL': 'C', 'LANG': 'C', 'GIT_TRACE': '1'}
|
|
||||||
# excluded_search_path_prefixes = []
|
|
||||||
+130
-135
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// THIS FILE WAS AUTOGENERATED BY ZELLIJ, THE PREVIOUS FILE AT THIS LOCATION WAS COPIED TO: /home/lkraven/.config/zellij/config.kdl.bak
|
// THIS FILE WAS AUTOGENERATED BY ZELLIJ, THE PREVIOUS FILE AT THIS LOCATION WAS COPIED TO: /home/lkraven/.config/zellij/config.kdl.bak.1
|
||||||
//
|
//
|
||||||
|
|
||||||
keybinds clear-defaults=true {
|
keybinds clear-defaults=true {
|
||||||
@@ -247,6 +247,126 @@ keybinds clear-defaults=true {
|
|||||||
bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; }
|
bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
themes {
|
||||||
|
australis {
|
||||||
|
text_unselected {
|
||||||
|
base 204 231 236
|
||||||
|
background 65 71 81
|
||||||
|
emphasis_0 164 196 255
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 99 136 216
|
||||||
|
emphasis_3 66 220 209
|
||||||
|
}
|
||||||
|
text_selected {
|
||||||
|
base 230 250 255
|
||||||
|
background 99 136 216
|
||||||
|
emphasis_0 255 225 78
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 99 136 216
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
ribbon_selected {
|
||||||
|
base 65 71 81
|
||||||
|
background 99 136 216
|
||||||
|
emphasis_0 81 224 138
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 225 198 49
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
ribbon_unselected {
|
||||||
|
base 204 231 236
|
||||||
|
background 86 95 105
|
||||||
|
emphasis_0 81 224 138
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 99 136 216
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
table_title {
|
||||||
|
base 169 188 195
|
||||||
|
background 34 37 49
|
||||||
|
emphasis_0 255 133 79
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 99 136 216
|
||||||
|
emphasis_3 255 73 26
|
||||||
|
}
|
||||||
|
table_cell_selected {
|
||||||
|
base 204 231 236
|
||||||
|
background 65 71 81
|
||||||
|
emphasis_0 255 225 78
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 99 136 216
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
table_cell_unselected {
|
||||||
|
base 169 188 195
|
||||||
|
background 34 37 49
|
||||||
|
emphasis_0 255 73 26
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 99 136 216
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
list_selected {
|
||||||
|
base 204 231 236
|
||||||
|
background 65 71 81
|
||||||
|
emphasis_0 255 225 78
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 99 136 216
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
list_unselected {
|
||||||
|
base 169 188 195
|
||||||
|
background 34 37 49
|
||||||
|
emphasis_0 225 198 49
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 99 136 216
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
frame_selected {
|
||||||
|
base 99 136 216
|
||||||
|
background 34 37 49
|
||||||
|
emphasis_0 255 73 26
|
||||||
|
emphasis_1 22 184 102
|
||||||
|
emphasis_2 225 198 49
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
frame_highlight {
|
||||||
|
base 81 224 138
|
||||||
|
background 34 37 49
|
||||||
|
emphasis_0 255 133 79
|
||||||
|
emphasis_1 99 136 216
|
||||||
|
emphasis_2 225 198 49
|
||||||
|
emphasis_3 255 73 26
|
||||||
|
}
|
||||||
|
exit_code_success {
|
||||||
|
base 22 184 102
|
||||||
|
background 0
|
||||||
|
emphasis_0 255 73 26
|
||||||
|
emphasis_1 99 136 216
|
||||||
|
emphasis_2 225 198 49
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
exit_code_error {
|
||||||
|
base 255 73 26
|
||||||
|
background 0
|
||||||
|
emphasis_0 22 184 102
|
||||||
|
emphasis_1 99 136 216
|
||||||
|
emphasis_2 225 198 49
|
||||||
|
emphasis_3 255 133 79
|
||||||
|
}
|
||||||
|
multiplayer_user_colors {
|
||||||
|
player_1 255 73 26
|
||||||
|
player_2 255 133 79
|
||||||
|
player_3 225 198 49
|
||||||
|
player_4 255 225 78
|
||||||
|
player_5 157 120 255
|
||||||
|
player_6 216 173 255
|
||||||
|
player_7 99 136 216
|
||||||
|
player_8 0 177 168
|
||||||
|
player_9 66 220 209
|
||||||
|
player_10 164 196 255
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Plugin aliases - can be used to change the implementation of Zellij
|
// Plugin aliases - can be used to change the implementation of Zellij
|
||||||
// changing these requires a restart to take effect
|
// changing these requires a restart to take effect
|
||||||
@@ -270,138 +390,6 @@ plugins {
|
|||||||
// Plugins to load in the background when a new session starts
|
// Plugins to load in the background when a new session starts
|
||||||
// eg. "file:/path/to/my-plugin.wasm"
|
// eg. "file:/path/to/my-plugin.wasm"
|
||||||
// eg. "https://example.com/my-plugin.wasm"
|
// eg. "https://example.com/my-plugin.wasm"
|
||||||
themes {
|
|
||||||
australis {
|
|
||||||
|
|
||||||
text_unselected {
|
|
||||||
base 204 231 236 // #CCE7EC - Bright text
|
|
||||||
background 65 71 81 // #414751 - Dark 30
|
|
||||||
emphasis_0 164 196 255 // #A4C4FF - Bright blue
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_3 66 220 209 // #42DCD1 - Bright cyan (was 255 133 79 - Bright red)
|
|
||||||
}
|
|
||||||
|
|
||||||
text_selected {
|
|
||||||
base 230 250 255 // #E6FAFF - Brighter white (was 204 231 236)
|
|
||||||
background 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_0 255 225 78 // #FFE14E - Bright yellow
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
ribbon_unselected {
|
|
||||||
base 204 231 236 // #CCE7EC - Bright white
|
|
||||||
background 86 95 105 // #565f69 - Dark 40 (was 65 71 81 - Dark 30)
|
|
||||||
emphasis_0 81 224 138 // #51E08A - Bright green
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
ribbon_selected {
|
|
||||||
base 65 71 81 // #414751 - Dark 30
|
|
||||||
background 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_0 81 224 138 // #51E08A - Bright green
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 225 198 49 // #E1C631 - Yellow
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
table_title {
|
|
||||||
base 169 188 195 // #A9BCC3 - White
|
|
||||||
background 34 37 49 // #222531 - Black
|
|
||||||
emphasis_0 255 133 79 // #FF854F - Bright red
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_3 255 73 26 // #FF491A - Red
|
|
||||||
}
|
|
||||||
|
|
||||||
table_cell_unselected {
|
|
||||||
base 169 188 195 // #A9BCC3 - White
|
|
||||||
background 34 37 49 // #222531 - Black
|
|
||||||
emphasis_0 255 73 26 // #FF491A - Red
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
table_cell_selected {
|
|
||||||
base 204 231 236 // #CCE7EC - Bright white
|
|
||||||
background 65 71 81 // #414751 - Dark 30
|
|
||||||
emphasis_0 255 225 78 // #FFE14E - Bright yellow
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
list_unselected {
|
|
||||||
base 169 188 195 // #A9BCC3 - White
|
|
||||||
background 34 37 49 // #222531 - Black
|
|
||||||
emphasis_0 225 198 49 // #E1C631 - Yellow
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
list_selected {
|
|
||||||
base 204 231 236 // #CCE7EC - Bright white
|
|
||||||
background 65 71 81 // #414751 - Dark 30
|
|
||||||
emphasis_0 255 225 78 // #FFE14E - Bright yellow
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_selected {
|
|
||||||
base 99 136 216 // #6388D8 - Blue
|
|
||||||
background 34 37 49 // #222531 - Black
|
|
||||||
emphasis_0 255 73 26 // #FF491A - Red
|
|
||||||
emphasis_1 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_2 225 198 49 // #E1C631 - Yellow
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_highlight {
|
|
||||||
base 81 224 138 // #51E08A - Bright green
|
|
||||||
background 34 37 49 // #222531 - Black
|
|
||||||
emphasis_0 255 133 79 // #FF854F - Bright red
|
|
||||||
emphasis_1 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_2 225 198 49 // #E1C631 - Yellow
|
|
||||||
emphasis_3 255 73 26 // #FF491A - Red
|
|
||||||
}
|
|
||||||
|
|
||||||
exit_code_success {
|
|
||||||
base 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_0 255 73 26 // #FF491A - Red
|
|
||||||
emphasis_1 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_2 225 198 49 // #E1C631 - Yellow
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
exit_code_error {
|
|
||||||
base 255 73 26 // #FF491A - Red
|
|
||||||
emphasis_0 22 184 102 // #16B866 - Green
|
|
||||||
emphasis_1 99 136 216 // #6388D8 - Blue
|
|
||||||
emphasis_2 225 198 49 // #E1C631 - Yellow
|
|
||||||
emphasis_3 255 133 79 // #FF854F - Bright red
|
|
||||||
}
|
|
||||||
|
|
||||||
multiplayer_user_colors {
|
|
||||||
player_1 255 73 26 // #FF491A - Red
|
|
||||||
player_2 255 133 79 // #FF854F - Bright red
|
|
||||||
player_3 225 198 49 // #E1C631 - Yellow
|
|
||||||
player_4 255 225 78 // #FFE14E - Bright yellow
|
|
||||||
player_5 157 120 255 // #9D78FF - Magenta
|
|
||||||
player_6 216 173 255 // #D8ADFF - Bright magenta
|
|
||||||
player_7 99 136 216 // #6388D8 - Blue
|
|
||||||
player_8 0 177 168 // #00B1A8 - Cyan
|
|
||||||
player_9 66 220 209 // #42DCD1 - Bright cyan
|
|
||||||
player_10 164 196 255 // #A4C4FF - Bright blue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
load_plugins {
|
load_plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +402,7 @@ load_plugins {
|
|||||||
|
|
||||||
// Choose the theme that is specified in the themes section.
|
// Choose the theme that is specified in the themes section.
|
||||||
// Default: default
|
// Default: default
|
||||||
|
//
|
||||||
theme "australis"
|
theme "australis"
|
||||||
|
|
||||||
// Choose the base input mode of zellij.
|
// Choose the base input mode of zellij.
|
||||||
@@ -590,9 +578,16 @@ default_mode "normal"
|
|||||||
// Whether to show tips on startup
|
// Whether to show tips on startup
|
||||||
// Default: true
|
// Default: true
|
||||||
//
|
//
|
||||||
// show_startup_tips false
|
show_startup_tips false
|
||||||
|
|
||||||
// Whether to show release notes on first version run
|
// Whether to show release notes on first version run
|
||||||
// Default: true
|
// Default: true
|
||||||
//
|
//
|
||||||
// show_release_notes false
|
// show_release_notes false
|
||||||
|
|
||||||
|
// Web-client (zellij web pilot) — force VictorMono Nerd Font for ligatures.
|
||||||
|
// NOTE: resolves against the CLIENT device's installed fonts (no @font-face
|
||||||
|
// serving like the ttyd seat); each device needs the font installed.
|
||||||
|
web_client {
|
||||||
|
font "VictorMono Nerd Font"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,452 +0,0 @@
|
|||||||
keybinds clear-defaults=true {
|
|
||||||
locked {
|
|
||||||
bind "Ctrl g" { SwitchToMode "normal"; }
|
|
||||||
}
|
|
||||||
pane {
|
|
||||||
bind "left" { MoveFocus "left"; }
|
|
||||||
bind "down" { MoveFocus "down"; }
|
|
||||||
bind "up" { MoveFocus "up"; }
|
|
||||||
bind "right" { MoveFocus "right"; }
|
|
||||||
bind "c" { SwitchToMode "renamepane"; PaneNameInput 0; }
|
|
||||||
bind "d" { NewPane "down"; SwitchToMode "normal"; }
|
|
||||||
bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "normal"; }
|
|
||||||
bind "f" { ToggleFocusFullscreen; SwitchToMode "normal"; }
|
|
||||||
bind "h" { MoveFocus "left"; }
|
|
||||||
bind "i" { TogglePanePinned; SwitchToMode "normal"; }
|
|
||||||
bind "j" { MoveFocus "down"; }
|
|
||||||
bind "k" { MoveFocus "up"; }
|
|
||||||
bind "l" { MoveFocus "right"; }
|
|
||||||
bind "n" { NewPane; SwitchToMode "normal"; }
|
|
||||||
bind "p" { SwitchFocus; }
|
|
||||||
bind "Ctrl p" { SwitchToMode "normal"; }
|
|
||||||
bind "r" { NewPane "right"; SwitchToMode "normal"; }
|
|
||||||
bind "w" { ToggleFloatingPanes; SwitchToMode "normal"; }
|
|
||||||
bind "z" { TogglePaneFrames; SwitchToMode "normal"; }
|
|
||||||
}
|
|
||||||
tab {
|
|
||||||
bind "left" { GoToPreviousTab; }
|
|
||||||
bind "down" { GoToNextTab; }
|
|
||||||
bind "up" { GoToPreviousTab; }
|
|
||||||
bind "right" { GoToNextTab; }
|
|
||||||
bind "1" { GoToTab 1; SwitchToMode "normal"; }
|
|
||||||
bind "2" { GoToTab 2; SwitchToMode "normal"; }
|
|
||||||
bind "3" { GoToTab 3; SwitchToMode "normal"; }
|
|
||||||
bind "4" { GoToTab 4; SwitchToMode "normal"; }
|
|
||||||
bind "5" { GoToTab 5; SwitchToMode "normal"; }
|
|
||||||
bind "6" { GoToTab 6; SwitchToMode "normal"; }
|
|
||||||
bind "7" { GoToTab 7; SwitchToMode "normal"; }
|
|
||||||
bind "8" { GoToTab 8; SwitchToMode "normal"; }
|
|
||||||
bind "9" { GoToTab 9; SwitchToMode "normal"; }
|
|
||||||
bind "[" { BreakPaneLeft; SwitchToMode "normal"; }
|
|
||||||
bind "]" { BreakPaneRight; SwitchToMode "normal"; }
|
|
||||||
bind "b" { BreakPane; SwitchToMode "normal"; }
|
|
||||||
bind "h" { GoToPreviousTab; }
|
|
||||||
bind "j" { GoToNextTab; }
|
|
||||||
bind "k" { GoToPreviousTab; }
|
|
||||||
bind "l" { GoToNextTab; }
|
|
||||||
bind "n" { NewTab; SwitchToMode "normal"; }
|
|
||||||
bind "r" { SwitchToMode "renametab"; TabNameInput 0; }
|
|
||||||
bind "s" { ToggleActiveSyncTab; SwitchToMode "normal"; }
|
|
||||||
bind "Ctrl t" { SwitchToMode "normal"; }
|
|
||||||
bind "x" { CloseTab; SwitchToMode "normal"; }
|
|
||||||
bind "tab" { ToggleTab; }
|
|
||||||
}
|
|
||||||
resize {
|
|
||||||
bind "left" { Resize "Increase left"; }
|
|
||||||
bind "down" { Resize "Increase down"; }
|
|
||||||
bind "up" { Resize "Increase up"; }
|
|
||||||
bind "right" { Resize "Increase right"; }
|
|
||||||
bind "+" { Resize "Increase"; }
|
|
||||||
bind "-" { Resize "Decrease"; }
|
|
||||||
bind "=" { Resize "Increase"; }
|
|
||||||
bind "H" { Resize "Decrease left"; }
|
|
||||||
bind "J" { Resize "Decrease down"; }
|
|
||||||
bind "K" { Resize "Decrease up"; }
|
|
||||||
bind "L" { Resize "Decrease right"; }
|
|
||||||
bind "h" { Resize "Increase left"; }
|
|
||||||
bind "j" { Resize "Increase down"; }
|
|
||||||
bind "k" { Resize "Increase up"; }
|
|
||||||
bind "l" { Resize "Increase right"; }
|
|
||||||
bind "Ctrl n" { SwitchToMode "normal"; }
|
|
||||||
}
|
|
||||||
move {
|
|
||||||
bind "left" { MovePane "left"; }
|
|
||||||
bind "down" { MovePane "down"; }
|
|
||||||
bind "up" { MovePane "up"; }
|
|
||||||
bind "right" { MovePane "right"; }
|
|
||||||
bind "h" { MovePane "left"; }
|
|
||||||
bind "Ctrl h" { SwitchToMode "normal"; }
|
|
||||||
bind "j" { MovePane "down"; }
|
|
||||||
bind "k" { MovePane "up"; }
|
|
||||||
bind "l" { MovePane "right"; }
|
|
||||||
bind "n" { MovePane; }
|
|
||||||
bind "p" { MovePaneBackwards; }
|
|
||||||
bind "tab" { MovePane; }
|
|
||||||
}
|
|
||||||
scroll {
|
|
||||||
bind "e" { EditScrollback; SwitchToMode "normal"; }
|
|
||||||
bind "s" { SwitchToMode "entersearch"; SearchInput 0; }
|
|
||||||
}
|
|
||||||
search {
|
|
||||||
bind "c" { SearchToggleOption "CaseSensitivity"; }
|
|
||||||
bind "n" { Search "down"; }
|
|
||||||
bind "o" { SearchToggleOption "WholeWord"; }
|
|
||||||
bind "p" { Search "up"; }
|
|
||||||
bind "w" { SearchToggleOption "Wrap"; }
|
|
||||||
}
|
|
||||||
session {
|
|
||||||
bind "a" {
|
|
||||||
LaunchOrFocusPlugin "zellij:about" {
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}
|
|
||||||
SwitchToMode "normal"
|
|
||||||
}
|
|
||||||
bind "c" {
|
|
||||||
LaunchOrFocusPlugin "configuration" {
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}
|
|
||||||
SwitchToMode "normal"
|
|
||||||
}
|
|
||||||
bind "Ctrl o" { SwitchToMode "normal"; }
|
|
||||||
bind "p" {
|
|
||||||
LaunchOrFocusPlugin "plugin-manager" {
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}
|
|
||||||
SwitchToMode "normal"
|
|
||||||
}
|
|
||||||
bind "w" {
|
|
||||||
LaunchOrFocusPlugin "session-manager" {
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}
|
|
||||||
SwitchToMode "normal"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shared_except "locked" {
|
|
||||||
bind "Alt left" { MoveFocusOrTab "left"; }
|
|
||||||
bind "Alt down" { MoveFocus "down"; }
|
|
||||||
bind "Alt up" { MoveFocus "up"; }
|
|
||||||
bind "Alt right" { MoveFocusOrTab "right"; }
|
|
||||||
bind "Alt +" { Resize "Increase"; }
|
|
||||||
bind "Alt -" { Resize "Decrease"; }
|
|
||||||
bind "Alt =" { Resize "Increase"; }
|
|
||||||
bind "Alt [" { PreviousSwapLayout; }
|
|
||||||
bind "Alt ]" { NextSwapLayout; }
|
|
||||||
bind "Alt f" { ToggleFloatingPanes; }
|
|
||||||
bind "Ctrl g" { SwitchToMode "locked"; }
|
|
||||||
bind "Alt h" { MoveFocusOrTab "left"; }
|
|
||||||
bind "Alt i" { MoveTab "left"; }
|
|
||||||
bind "Alt j" { MoveFocus "down"; }
|
|
||||||
bind "Alt k" { MoveFocus "up"; }
|
|
||||||
bind "Alt l" { MoveFocusOrTab "right"; }
|
|
||||||
bind "Alt n" { NewPane; }
|
|
||||||
bind "Alt o" { MoveTab "right"; }
|
|
||||||
bind "Ctrl q" { Quit; }
|
|
||||||
}
|
|
||||||
shared_except "locked" "move" {
|
|
||||||
bind "Ctrl h" { SwitchToMode "move"; }
|
|
||||||
}
|
|
||||||
shared_except "locked" "session" {
|
|
||||||
bind "Ctrl o" { SwitchToMode "session"; }
|
|
||||||
}
|
|
||||||
shared_except "locked" "scroll" "search" "tmux" {
|
|
||||||
bind "Ctrl b" { SwitchToMode "tmux"; }
|
|
||||||
}
|
|
||||||
shared_except "locked" "scroll" "search" {
|
|
||||||
bind "Ctrl s" { SwitchToMode "scroll"; }
|
|
||||||
}
|
|
||||||
shared_except "locked" "tab" {
|
|
||||||
bind "Ctrl t" { SwitchToMode "tab"; }
|
|
||||||
}
|
|
||||||
shared_except "locked" "pane" {
|
|
||||||
bind "Ctrl p" { SwitchToMode "pane"; }
|
|
||||||
}
|
|
||||||
shared_except "locked" "resize" {
|
|
||||||
bind "Ctrl n" { SwitchToMode "resize"; }
|
|
||||||
}
|
|
||||||
shared_except "normal" "locked" "entersearch" {
|
|
||||||
bind "enter" { SwitchToMode "normal"; }
|
|
||||||
}
|
|
||||||
shared_except "normal" "locked" "entersearch" "renametab" "renamepane" {
|
|
||||||
bind "esc" { SwitchToMode "normal"; }
|
|
||||||
}
|
|
||||||
shared_among "pane" "tmux" {
|
|
||||||
bind "x" { CloseFocus; SwitchToMode "normal"; }
|
|
||||||
}
|
|
||||||
shared_among "scroll" "search" {
|
|
||||||
bind "PageDown" { PageScrollDown; }
|
|
||||||
bind "PageUp" { PageScrollUp; }
|
|
||||||
bind "left" { PageScrollUp; }
|
|
||||||
bind "down" { ScrollDown; }
|
|
||||||
bind "up" { ScrollUp; }
|
|
||||||
bind "right" { PageScrollDown; }
|
|
||||||
bind "Ctrl b" { PageScrollUp; }
|
|
||||||
bind "Ctrl c" { ScrollToBottom; SwitchToMode "normal"; }
|
|
||||||
bind "d" { HalfPageScrollDown; }
|
|
||||||
bind "Ctrl f" { PageScrollDown; }
|
|
||||||
bind "h" { PageScrollUp; }
|
|
||||||
bind "j" { ScrollDown; }
|
|
||||||
bind "k" { ScrollUp; }
|
|
||||||
bind "l" { PageScrollDown; }
|
|
||||||
bind "Ctrl s" { SwitchToMode "normal"; }
|
|
||||||
bind "u" { HalfPageScrollUp; }
|
|
||||||
}
|
|
||||||
entersearch {
|
|
||||||
bind "Ctrl c" { SwitchToMode "scroll"; }
|
|
||||||
bind "esc" { SwitchToMode "scroll"; }
|
|
||||||
bind "enter" { SwitchToMode "search"; }
|
|
||||||
}
|
|
||||||
renametab {
|
|
||||||
bind "esc" { UndoRenameTab; SwitchToMode "tab"; }
|
|
||||||
}
|
|
||||||
shared_among "renametab" "renamepane" {
|
|
||||||
bind "Ctrl c" { SwitchToMode "normal"; }
|
|
||||||
}
|
|
||||||
renamepane {
|
|
||||||
bind "esc" { UndoRenamePane; SwitchToMode "pane"; }
|
|
||||||
}
|
|
||||||
shared_among "session" "tmux" {
|
|
||||||
bind "d" { Detach; }
|
|
||||||
}
|
|
||||||
tmux {
|
|
||||||
bind "left" { MoveFocus "left"; SwitchToMode "normal"; }
|
|
||||||
bind "down" { MoveFocus "down"; SwitchToMode "normal"; }
|
|
||||||
bind "up" { MoveFocus "up"; SwitchToMode "normal"; }
|
|
||||||
bind "right" { MoveFocus "right"; SwitchToMode "normal"; }
|
|
||||||
bind "space" { NextSwapLayout; }
|
|
||||||
bind "\"" { NewPane "down"; SwitchToMode "normal"; }
|
|
||||||
bind "%" { NewPane "right"; SwitchToMode "normal"; }
|
|
||||||
bind "," { SwitchToMode "renametab"; }
|
|
||||||
bind "[" { SwitchToMode "scroll"; }
|
|
||||||
bind "Ctrl b" { Write 2; SwitchToMode "normal"; }
|
|
||||||
bind "c" { NewTab; SwitchToMode "normal"; }
|
|
||||||
bind "h" { MoveFocus "left"; SwitchToMode "normal"; }
|
|
||||||
bind "j" { MoveFocus "down"; SwitchToMode "normal"; }
|
|
||||||
bind "k" { MoveFocus "up"; SwitchToMode "normal"; }
|
|
||||||
bind "l" { MoveFocus "right"; SwitchToMode "normal"; }
|
|
||||||
bind "n" { GoToNextTab; SwitchToMode "normal"; }
|
|
||||||
bind "o" { FocusNextPane; }
|
|
||||||
bind "p" { GoToPreviousTab; SwitchToMode "normal"; }
|
|
||||||
bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Plugin aliases - can be used to change the implementation of Zellij
|
|
||||||
// changing these requires a restart to take effect
|
|
||||||
plugins {
|
|
||||||
about location="zellij:about"
|
|
||||||
compact-bar location="zellij:compact-bar"
|
|
||||||
configuration location="zellij:configuration"
|
|
||||||
filepicker location="zellij:strider" {
|
|
||||||
cwd "/"
|
|
||||||
}
|
|
||||||
plugin-manager location="zellij:plugin-manager"
|
|
||||||
session-manager location="zellij:session-manager"
|
|
||||||
status-bar location="zellij:status-bar"
|
|
||||||
strider location="zellij:strider"
|
|
||||||
tab-bar location="zellij:tab-bar"
|
|
||||||
welcome-screen location="zellij:session-manager" {
|
|
||||||
welcome_screen true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Plugins to load in the background when a new session starts
|
|
||||||
// eg. "file:/path/to/my-plugin.wasm"
|
|
||||||
// eg. "https://example.com/my-plugin.wasm"
|
|
||||||
load_plugins {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use a simplified UI without special fonts (arrow glyphs)
|
|
||||||
// Options:
|
|
||||||
// - true
|
|
||||||
// - false (Default)
|
|
||||||
//
|
|
||||||
// simplified_ui true
|
|
||||||
|
|
||||||
// Choose the theme that is specified in the themes section.
|
|
||||||
// Default: default
|
|
||||||
//
|
|
||||||
// theme "dracula"
|
|
||||||
|
|
||||||
// Choose the base input mode of zellij.
|
|
||||||
// Default: normal
|
|
||||||
//
|
|
||||||
// default_mode "locked"
|
|
||||||
|
|
||||||
// Choose the path to the default shell that zellij will use for opening new panes
|
|
||||||
// Default: $SHELL
|
|
||||||
//
|
|
||||||
// default_shell "fish"
|
|
||||||
|
|
||||||
// Choose the path to override cwd that zellij will use for opening new panes
|
|
||||||
//
|
|
||||||
// default_cwd "/tmp"
|
|
||||||
|
|
||||||
// The name of the default layout to load on startup
|
|
||||||
// Default: "default"
|
|
||||||
//
|
|
||||||
// default_layout "compact"
|
|
||||||
|
|
||||||
// The folder in which Zellij will look for layouts
|
|
||||||
// (Requires restart)
|
|
||||||
//
|
|
||||||
// layout_dir "/tmp"
|
|
||||||
|
|
||||||
// The folder in which Zellij will look for themes
|
|
||||||
// (Requires restart)
|
|
||||||
//
|
|
||||||
// theme_dir "/tmp"
|
|
||||||
|
|
||||||
// Toggle enabling the mouse mode.
|
|
||||||
// On certain configurations, or terminals this could
|
|
||||||
// potentially interfere with copying text.
|
|
||||||
// Options:
|
|
||||||
// - true (default)
|
|
||||||
// - false
|
|
||||||
//
|
|
||||||
// mouse_mode false
|
|
||||||
|
|
||||||
// Toggle having pane frames around the panes
|
|
||||||
// Options:
|
|
||||||
// - true (default, enabled)
|
|
||||||
// - false
|
|
||||||
//
|
|
||||||
// pane_frames false
|
|
||||||
|
|
||||||
// When attaching to an existing session with other users,
|
|
||||||
// should the session be mirrored (true)
|
|
||||||
// or should each user have their own cursor (false)
|
|
||||||
// (Requires restart)
|
|
||||||
// Default: false
|
|
||||||
//
|
|
||||||
// mirror_session true
|
|
||||||
|
|
||||||
// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP
|
|
||||||
// eg. when terminal window with an active zellij session is closed
|
|
||||||
// (Requires restart)
|
|
||||||
// Options:
|
|
||||||
// - detach (Default)
|
|
||||||
// - quit
|
|
||||||
//
|
|
||||||
// on_force_close "quit"
|
|
||||||
|
|
||||||
// Configure the scroll back buffer size
|
|
||||||
// This is the number of lines zellij stores for each pane in the scroll back
|
|
||||||
// buffer. Excess number of lines are discarded in a FIFO fashion.
|
|
||||||
// (Requires restart)
|
|
||||||
// Valid values: positive integers
|
|
||||||
// Default value: 10000
|
|
||||||
//
|
|
||||||
// scroll_buffer_size 10000
|
|
||||||
|
|
||||||
// Provide a command to execute when copying text. The text will be piped to
|
|
||||||
// the stdin of the program to perform the copy. This can be used with
|
|
||||||
// terminal emulators which do not support the OSC 52 ANSI control sequence
|
|
||||||
// that will be used by default if this option is not set.
|
|
||||||
// Examples:
|
|
||||||
//
|
|
||||||
// copy_command "xclip -selection clipboard" // x11
|
|
||||||
// copy_command "wl-copy" // wayland
|
|
||||||
// copy_command "pbcopy" // osx
|
|
||||||
//
|
|
||||||
// copy_command "pbcopy"
|
|
||||||
|
|
||||||
// Choose the destination for copied text
|
|
||||||
// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard.
|
|
||||||
// Does not apply when using copy_command.
|
|
||||||
// Options:
|
|
||||||
// - system (default)
|
|
||||||
// - primary
|
|
||||||
//
|
|
||||||
// copy_clipboard "primary"
|
|
||||||
|
|
||||||
// Enable automatic copying (and clearing) of selection when releasing mouse
|
|
||||||
// Default: true
|
|
||||||
//
|
|
||||||
// copy_on_select true
|
|
||||||
|
|
||||||
// Path to the default editor to use to edit pane scrollbuffer
|
|
||||||
// Default: $EDITOR or $VISUAL
|
|
||||||
// scrollback_editor "/usr/bin/vim"
|
|
||||||
|
|
||||||
// A fixed name to always give the Zellij session.
|
|
||||||
// Consider also setting `attach_to_session true,`
|
|
||||||
// otherwise this will error if such a session exists.
|
|
||||||
// Default: <RANDOM>
|
|
||||||
//
|
|
||||||
// session_name "My singleton session"
|
|
||||||
|
|
||||||
// When `session_name` is provided, attaches to that session
|
|
||||||
// if it is already running or creates it otherwise.
|
|
||||||
// Default: false
|
|
||||||
//
|
|
||||||
// attach_to_session true
|
|
||||||
|
|
||||||
// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible
|
|
||||||
// Options:
|
|
||||||
// - true (default)
|
|
||||||
// - false
|
|
||||||
//
|
|
||||||
// auto_layout false
|
|
||||||
|
|
||||||
// Whether sessions should be serialized to the cache folder (including their tabs/panes, cwds and running commands) so that they can later be resurrected
|
|
||||||
// Options:
|
|
||||||
// - true (default)
|
|
||||||
// - false
|
|
||||||
//
|
|
||||||
// session_serialization false
|
|
||||||
|
|
||||||
// Whether pane viewports are serialized along with the session, default is false
|
|
||||||
// Options:
|
|
||||||
// - true
|
|
||||||
// - false (default)
|
|
||||||
//
|
|
||||||
// serialize_pane_viewport false
|
|
||||||
|
|
||||||
// Scrollback lines to serialize along with the pane viewport when serializing sessions, 0
|
|
||||||
// defaults to the scrollback size. If this number is higher than the scrollback size, it will
|
|
||||||
// also default to the scrollback size. This does nothing if `serialize_pane_viewport` is not true.
|
|
||||||
//
|
|
||||||
// scrollback_lines_to_serialize 10000
|
|
||||||
|
|
||||||
// Enable or disable the rendering of styled and colored underlines (undercurl).
|
|
||||||
// May need to be disabled for certain unsupported terminals
|
|
||||||
// (Requires restart)
|
|
||||||
// Default: true
|
|
||||||
//
|
|
||||||
// styled_underlines false
|
|
||||||
|
|
||||||
// How often in seconds sessions are serialized
|
|
||||||
//
|
|
||||||
// serialization_interval 10000
|
|
||||||
|
|
||||||
// Enable or disable writing of session metadata to disk (if disabled, other sessions might not know
|
|
||||||
// metadata info on this session)
|
|
||||||
// (Requires restart)
|
|
||||||
// Default: false
|
|
||||||
//
|
|
||||||
// disable_session_metadata false
|
|
||||||
|
|
||||||
// Enable or disable support for the enhanced Kitty Keyboard Protocol (the host terminal must also support it)
|
|
||||||
// (Requires restart)
|
|
||||||
// Default: true (if the host terminal supports it)
|
|
||||||
//
|
|
||||||
// support_kitty_keyboard_protocol false
|
|
||||||
|
|
||||||
// Whether to stack panes when resizing beyond a certain size
|
|
||||||
// Default: true
|
|
||||||
//
|
|
||||||
// stacked_resize false
|
|
||||||
|
|
||||||
// Whether to show tips on startup
|
|
||||||
// Default: true
|
|
||||||
//
|
|
||||||
// show_startup_tips false
|
|
||||||
|
|
||||||
// Whether to show release notes on first version run
|
|
||||||
// Default: true
|
|
||||||
//
|
|
||||||
// show_release_notes false
|
|
||||||
@@ -0,0 +1,736 @@
|
|||||||
|
# CLAUDE.md — global preferences (lkraven)
|
||||||
|
|
||||||
|
Loaded into every Claude Code session regardless of project. Project-
|
||||||
|
local `CLAUDE.md` files take precedence when they conflict; this file
|
||||||
|
is the baseline.
|
||||||
|
|
||||||
|
## Operator identity
|
||||||
|
|
||||||
|
The operator is **Vuong Hoang** (lkraven@lkraven.com), addressed as
|
||||||
|
"Vuong". Roles across three organizations:
|
||||||
|
|
||||||
|
- **Corviduo AI** — Founder, Principal Developer, Chief Systems Architect.
|
||||||
|
- **PhaseFinal, Inc** — Founder, Principal Developer, Chief Systems Architect.
|
||||||
|
- **VastBlue AI** — Partner, Chief Systems Architect.
|
||||||
|
|
||||||
|
He is the final authority on architectural / material-consequence
|
||||||
|
calls. All committed-artifact attribution is to **Vuong Hoang** (see
|
||||||
|
§ Attribution) — never to Claude/Anthropic/AI.
|
||||||
|
|
||||||
|
## Core principles
|
||||||
|
|
||||||
|
Four principles governing engineering choices across all projects.
|
||||||
|
Common lodestar: fitness-for-purpose. Each rejects a different
|
||||||
|
substitute goal that disguises itself as virtue.
|
||||||
|
|
||||||
|
1. **Excellence over uniqueness.** Pick the shape that's right for
|
||||||
|
the problem, not the shape that's new. If uniqueness is a
|
||||||
|
byproduct of excellence, so be it; do not target it.
|
||||||
|
|
||||||
|
2. **Explicit over implicit.** Make load-bearing assumptions,
|
||||||
|
constraints, and coupling visible. Idiomatic implicitness
|
||||||
|
(language conventions, well-known protocols) is fine — the rule
|
||||||
|
targets *invisible* implicitness, not all of it. Cost of
|
||||||
|
explicitness is verbosity; cost of invisible implicitness is
|
||||||
|
undetectable coupling. Pay the cost where auditability beats
|
||||||
|
the tax.
|
||||||
|
|
||||||
|
3. **Elegance is a byproduct, not a target.** Excellent engineering
|
||||||
|
often produces elegant results; targeting elegance directly tends
|
||||||
|
to produce cleverness, which is a different thing. Review test:
|
||||||
|
"fit-for-purpose, debuggable, consistent" — not "feels nice."
|
||||||
|
|
||||||
|
4. **Action-relevance over thoroughness.** Before investigating,
|
||||||
|
ask whether the answer would change the action. If both outcomes
|
||||||
|
lead to the same default, skip the question.
|
||||||
|
|
||||||
|
## Operator cognitive-load reduction (core mission)
|
||||||
|
|
||||||
|
A core mission: **reduce the operator's cognitive load as he context-
|
||||||
|
shifts across dozens of projects.** He knows the detailed workings of
|
||||||
|
each — the job is not to teach, it is to let him re-enter any project
|
||||||
|
and act without reloading its full context from scratch. Three
|
||||||
|
standing obligations layered on top of normal work:
|
||||||
|
|
||||||
|
1. **Surface every architecture decision that matters to him.**
|
||||||
|
Material-consequence decisions — module boundaries, naming with
|
||||||
|
downstream reach, scope direction, anything hard to reverse — go to
|
||||||
|
him, not a peer, not a silent default. (The operator-owns-
|
||||||
|
architectural-calls rule, restated as a load-reduction duty.) Do
|
||||||
|
**not** dumb the decision down — he wants the real substance.
|
||||||
|
|
||||||
|
2. **Pair every operator-facing decision with an `/elitk` decision
|
||||||
|
tree.** When you surface a decision for him to make, accompany the
|
||||||
|
technical framing with a King-grade (`/elitk`) decision tree:
|
||||||
|
plain-language, jargon-free, the branches and where each leads, so
|
||||||
|
he can decide in seconds without reloading the project's context.
|
||||||
|
The tree is the load-reducer; the technical framing is the
|
||||||
|
substance — give both, every time. Lead with your recommendation.
|
||||||
|
|
||||||
|
3. **Keep a running `/elitk` summary of decisions made on his behalf.**
|
||||||
|
Every call you take autonomously (agent-discretion: patch bumps,
|
||||||
|
tie-breaks, routing, sequencing, implementation-level choices) earns
|
||||||
|
a plain-language line in a decisions summary, so he can audit what
|
||||||
|
happened in his absence without digging through the work. Offer the
|
||||||
|
`/elitk` summary unprompted at natural checkpoints and whenever he
|
||||||
|
asks "what have you decided?"
|
||||||
|
|
||||||
|
4. **Always attach the real technical detail — never make him ask for
|
||||||
|
it.** Every `/elitk` decision tree and every decisions-summary line
|
||||||
|
carries its actual technical specifics alongside the plain-language,
|
||||||
|
clearly delineated (parentheses, brackets, an indented technical
|
||||||
|
note, a `details:` tail — your pick) so it can be read or skipped at
|
||||||
|
a glance. Plain-language is the fast-scan default; the technical
|
||||||
|
version rides *with* it, never behind a follow-up request. **He
|
||||||
|
chooses his own cognitive load by deciding whether to read the
|
||||||
|
bracketed detail** — the job is to make both present, not to
|
||||||
|
pre-decide which he needs. Example: "kept the version cadence
|
||||||
|
conservative `[F03 research work → patch v0.5.4 then v0.5.5; the two
|
||||||
|
docs-only edits → no bump per the SemVer docs-only skip-rule]`."
|
||||||
|
|
||||||
|
This extends the non-technical-breakdown habit (auto-memory
|
||||||
|
`feedback_non_technical_breakdown_on_findings`) from findings to *all*
|
||||||
|
decisions, and sharpens it with the decision-tree-for-pending-calls
|
||||||
|
requirement. `/elitk` is the grade and the tool; its King framing —
|
||||||
|
smart reader, zero jargon — is exactly the operator mid-context-shift.
|
||||||
|
|
||||||
|
## Cross-frontier-model consultation discipline
|
||||||
|
|
||||||
|
Consults to non-Claude peer models (Heid = Codex/gpt-5.x oracle;
|
||||||
|
Eitri-Smithy = Codex-shaped embedded research peer; any future
|
||||||
|
non-Claude reviewer agent) operate under **two complementary
|
||||||
|
anti-failure framings**:
|
||||||
|
|
||||||
|
1. **Authority-frame**: peers provide **fresh perspective**, not
|
||||||
|
**superior reasoning**. Different model families have different
|
||||||
|
priors and different training cutoffs — they catch different
|
||||||
|
blind spots. That is the load-bearing value, not authority.
|
||||||
|
2. **Role-frame**: peers are **peer-reviewers, not operator-level
|
||||||
|
oracles**. Routing operator-level decisions (architectural
|
||||||
|
choices, scope direction, what-to-build calls with material
|
||||||
|
consequence) to a peer for an authoritative answer is misuse —
|
||||||
|
those go to the operator regardless of what the peer says.
|
||||||
|
Peers can pressure-test, paraphrase, surface ambiguity, and
|
||||||
|
recommend implementation-level calls; they don't decide.
|
||||||
|
|
||||||
|
Together: peers are useful reviewers whose value comes from a
|
||||||
|
different angle, not better answers; the operator owns the
|
||||||
|
architectural calls, period.
|
||||||
|
|
||||||
|
**Default skepticism, never auto-adopt.** Every cross-frontier reply
|
||||||
|
gets triaged before any of it lands in a plan, contract, or commit.
|
||||||
|
Five-category triage:
|
||||||
|
|
||||||
|
1. **Genuine add** — peer caught something my framing genuinely
|
||||||
|
missed. Take it.
|
||||||
|
2. **Sharpening** — peer reframed something I already had into a
|
||||||
|
sharper version. Merge into the existing variable; don't
|
||||||
|
double-count as net-new.
|
||||||
|
3. **Restatement of settled prior** — peer flagged as "missed" a
|
||||||
|
thing that is already settled in our findings/contracts/ADRs.
|
||||||
|
Useful as a coverage checklist; **not** a structural addition.
|
||||||
|
4. **Out-of-place** — peer's input is correct but belongs at a
|
||||||
|
different stage (e.g., implementation-stage detail surfaced
|
||||||
|
during frame-stage). Note and defer.
|
||||||
|
5. **Wrong-grounding** — peer reasoned from incomplete context and
|
||||||
|
manufactured a non-issue. Push back; do not adopt.
|
||||||
|
|
||||||
|
**Watch for the ignorance-of-context failure mode.** A peer's "you
|
||||||
|
missed X" claim has two possible sources: (a) genuine fresh insight,
|
||||||
|
or (b) the peer did not read the artifact where X is settled. Before
|
||||||
|
treating an omission claim as new, check what the peer actually
|
||||||
|
read — if your settled artifact wasn't on their reading list, the
|
||||||
|
"miss" is probably category 3 or 5, not category 1.
|
||||||
|
|
||||||
|
**Adoption criterion**: "this improves the outcome on its merits"
|
||||||
|
— never "the peer said so." Treating Codex (or any non-Claude
|
||||||
|
oracle) as an all-knowing authority is a category error; treat it
|
||||||
|
as a wise sounding board whose value is forcing you to defend
|
||||||
|
your framing against a differently-primed reader.
|
||||||
|
|
||||||
|
**Applies hardest to `/heid*` skills.** Those skills' artifact-only
|
||||||
|
discipline protects the EMITTING side (Heid can't be primed by the
|
||||||
|
caller); the CONSUMING side rubber-stamp risk is on whoever invokes
|
||||||
|
the skill. Always triage Heid output before acting on it.
|
||||||
|
|
||||||
|
## Althing async-reply monitoring
|
||||||
|
|
||||||
|
When you ship an althing message that you expect to come back with a
|
||||||
|
reply — a consult (`/heid*`), a question to a peer agent, a request
|
||||||
|
awaiting an answer — and you do **not** already have an althing
|
||||||
|
monitor running for this session, **always start one**
|
||||||
|
(`/althing:monitor`). The dispatch and the monitor are one action: you
|
||||||
|
opened a loop, so arm the thing that closes it.
|
||||||
|
|
||||||
|
Why: in an interactive session the inbox banner (📬) only fires on the
|
||||||
|
*next* user prompt. If the operator steps away after you dispatch an
|
||||||
|
async consult, the reply can sit unseen indefinitely — the loop you
|
||||||
|
opened never closes on its own. A monitor actively pings when the
|
||||||
|
reply lands, so the await-reply promise ("reply will land in your
|
||||||
|
inbox") is backed by a real notification, not by hoping the operator
|
||||||
|
prompts again.
|
||||||
|
|
||||||
|
Scope: only messages where you're waiting on a response. Pure
|
||||||
|
fire-and-forget posts (an FYI ping, a post-1.0 downstream-consumer
|
||||||
|
announcement) don't need a monitor. When the exchange is done, sign
|
||||||
|
off (`/althing:sign-off`) so monitors don't accumulate — stop a stuck
|
||||||
|
one with `althing-light-monitor --stop`, never `pkill` (that kills
|
||||||
|
every agent's monitor, not just yours).
|
||||||
|
|
||||||
|
## Development workflow shapes
|
||||||
|
|
||||||
|
Two end-to-end shapes for taking a unit of work from idea to landed.
|
||||||
|
Pick by whether the work will be implemented by an AFK agent
|
||||||
|
(Sleipnir dispatch) or directly in-session. Both front-load the same
|
||||||
|
deliberation — heid consult → contract → heid contract review →
|
||||||
|
contract fixup — so the spec is sound before any code; they diverge
|
||||||
|
only at the implementation handoff.
|
||||||
|
|
||||||
|
Stages are defaults, not a rigid gate. Skip a stage when it would be
|
||||||
|
ceremony (a trivial bug fix needs no vor pass; a one-liner needs no
|
||||||
|
contract). The heid consult and review stages follow the cross-
|
||||||
|
frontier triage discipline above: never auto-adopt.
|
||||||
|
|
||||||
|
**Contract-skip is a direct-implementation privilege.** In the direct
|
||||||
|
shape, low-effort work — surgical test updates, localized bug fixes,
|
||||||
|
one-liners — runs straight to implementation without a fresh contract,
|
||||||
|
*provided* any existing contract governing the touched behavior is
|
||||||
|
updated in the same commit so it stays canonical (skip *authoring* a
|
||||||
|
contract, never let a live one go stale against the code). This does
|
||||||
|
not extend to AFK dispatch, which always requires a `prd:`-pinned
|
||||||
|
contract per § "Issue → AFK dispatch hygiene (Sleipnir)" (hard policy)
|
||||||
|
— and trivial work is not an AFK candidate in the first place: the
|
||||||
|
scaffold → contract → review → preflight ritual carries real overhead
|
||||||
|
that only pays for itself on higher-effort tasks. When in doubt,
|
||||||
|
low-effort stays direct.
|
||||||
|
|
||||||
|
**Graphify the blast radius BEFORE writing the contract** — for ANY
|
||||||
|
contract that touches existing code (not greenfield). Run a graphify
|
||||||
|
pass over every symbol the contract will change, delete, or rename
|
||||||
|
(`graphify explain <symbol>` for callers/neighbors, `graphify path`
|
||||||
|
for reach) so the contract's scope section enumerates the *true* set
|
||||||
|
of affected files and call-sites — not an under-count that detonates
|
||||||
|
mid-implementation. **Cross-check with grep, always.** Graphify is
|
||||||
|
blind to function-local and DI-injected imports (`from .x import y`
|
||||||
|
inside a function body, store objects passed through constructors) —
|
||||||
|
the exact pattern that hides cross-module callers. Graphify confirms
|
||||||
|
the call structure; grep catches what its AST extraction misses;
|
||||||
|
neither alone is sufficient (graphify-only under-counts, grep-only
|
||||||
|
misses transitive reach). Both, before the contract — the scope
|
||||||
|
section is only as honest as the blast-radius pass behind it. (Lesson:
|
||||||
|
a contract that names 3 files when the rip touches 6 is a scope miss
|
||||||
|
the up-front pass would have caught.)
|
||||||
|
|
||||||
|
### AFK dispatch shape (Sleipnir)
|
||||||
|
|
||||||
|
For work an AFK agent will implement off a contract.
|
||||||
|
|
||||||
|
1. Issue created.
|
||||||
|
2. Heid consult on the issue (`/heid`) — pressure-test the framing.
|
||||||
|
3. Scaffold the issue for AFK dispatch (`/sleipnir-scaffold <N>`) —
|
||||||
|
writes the `prd:`-pinned contract frontmatter.
|
||||||
|
4. Contract generation — the architect writes the contract body.
|
||||||
|
5. Heid contract review (`/heid-contract-review`).
|
||||||
|
6. Fixup the contract per triaged findings.
|
||||||
|
7. Preflight + mark ready-for-agent (`/sleipnir-preflight <N>`) — the
|
||||||
|
irreversible dispatch authorization. See § "Issue → AFK dispatch
|
||||||
|
hygiene (Sleipnir)" for the gate's hard requirements.
|
||||||
|
|
||||||
|
### Direct implementation shape
|
||||||
|
|
||||||
|
For work implemented directly in-session.
|
||||||
|
|
||||||
|
1. Issue created.
|
||||||
|
2. Heid consult on the issue (`/heid`).
|
||||||
|
3. `/vor` — or `/vor-frame` (ask too shapeless to draft a `/vor`
|
||||||
|
questionnaire) or `/vor-cross` (cross-frontier peer in the loop) —
|
||||||
|
if the ask warrants a pre-contract design pass. Skip when the
|
||||||
|
frame is already crisp.
|
||||||
|
4. Write the contract.
|
||||||
|
5. Heid contract review (`/heid-contract-review`).
|
||||||
|
6. Fixup the contract per triaged findings.
|
||||||
|
7. TDD implement (`/tdd`) — red-green-refactor against the contract.
|
||||||
|
8. Heid code review (`/heid-code-review`) — code-vs-contract drift.
|
||||||
|
9. Fixup the code per triaged findings.
|
||||||
|
10. Commit if clean.
|
||||||
|
|
||||||
|
## Tooling preferences
|
||||||
|
|
||||||
|
- **Python: prefer `uv` whenever possible.** Use `uv venv`, `uv pip
|
||||||
|
install`, `uv run`, `uv tool install`, etc. instead of `python -m
|
||||||
|
venv`, `pip`, `pipx`, `poetry`. Exception: if the project clearly
|
||||||
|
uses something else (a `poetry.lock` exists, the README says
|
||||||
|
`pip-tools`, the Dockerfile already pins `pip install`), follow the
|
||||||
|
project's tooling — don't fight it just to use uv.
|
||||||
|
- **Shell: I run interactive `zsh`.** Commands you hand me to paste
|
||||||
|
must be zsh-safe: quote glob-bearing args (`'pkg[extra]'`, not
|
||||||
|
`pkg[extra]` — zsh errors `no matches found` on unquoted brackets)
|
||||||
|
and don't rely on bash-only syntax. Inline `#` comments are fine
|
||||||
|
(`setopt interactive_comments` is set in `~/.zshrc`). Claude Code's
|
||||||
|
Bash tool also runs zsh here (it follows `$SHELL`), so the same
|
||||||
|
applies to tool commands.
|
||||||
|
|
||||||
|
## Global tools available
|
||||||
|
|
||||||
|
Tools standing ready in the working environment — assume present and use
|
||||||
|
them without a setup detour. (Most Claude Code sessions run natively on
|
||||||
|
**nh3-dev** `10.100.10.50`, the dev box; "available" means there unless a
|
||||||
|
note says otherwise. On other boxes, check first.)
|
||||||
|
|
||||||
|
- **Playwright + headless Chromium** — installed **box-wide on nh3-dev**:
|
||||||
|
the system shared-libs (apt, via `playwright install-deps`), the browser
|
||||||
|
binaries in shared **`/opt/ms-playwright`** (chromium + headless-shell,
|
||||||
|
root-owned + world-readable), and
|
||||||
|
`PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright` wired globally
|
||||||
|
(`/etc/environment` + `/etc/profile.d/`). A project only needs the
|
||||||
|
`playwright` module (`npm i playwright` — the browser download is
|
||||||
|
skippable, it resolves the shared binary); **no per-project
|
||||||
|
`playwright install`**. Use for anything that needs a real browser
|
||||||
|
engine: true DOM/SVG layout geometry, screenshots, headless rendering,
|
||||||
|
browser-based tests or scraping. Add a browser / bump via
|
||||||
|
`ssh infra-ops@10.100.10.50 'sudo env PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright npx -y playwright install <browser>'`.
|
||||||
|
|
||||||
|
- **Graphify** — open-source knowledge-graph skill for AI coding assistants
|
||||||
|
(`uv tool install graphifyy`; CLI `graphify`, MCP `graphify-mcp`). Turns a
|
||||||
|
repo into a queryable graph. The **free, deterministic path** is
|
||||||
|
`graphify update <path>`: tree-sitter AST extraction + Leiden clustering,
|
||||||
|
**zero LLM / zero tokens**, ~25s for ~900 files; writes
|
||||||
|
`graphify-out/{graph.json,GRAPH_REPORT.md}`. Highest-value free output is
|
||||||
|
the **God Nodes** list (core-abstraction surfacing) plus `graphify explain
|
||||||
|
<symbol>` / `query` / `affected` / `path` traversals over `EXTRACTED` call
|
||||||
|
edges. The LLM layer (community **labeling** = low-caliber, and **semantic
|
||||||
|
extraction** of docs/INFERRED edges = higher-caliber + noisier) is optional
|
||||||
|
and points at any backend via `~/.graphify/providers.json` — pair labeling
|
||||||
|
with the cheap LiteLLM/Granite endpoint below; leave deep semantic
|
||||||
|
extraction off unless needed (its INFERRED/AMBIGUOUS edges fight the
|
||||||
|
explicit-over-implicit floor). Complements a hand-authored `docs/CODEBASE.md`
|
||||||
|
(curated geography), doesn't replace it. Pilot-validated on Worldtree
|
||||||
|
2026-06-10.
|
||||||
|
|
||||||
|
- **LiteLLM gateway (Granite 4.1 + friends)** — OpenAI-compatible gateway at
|
||||||
|
`http://10.250.50.70:4000/v1` (Logs UI `:4000/ui`) fronting vLLM services.
|
||||||
|
Essentially-**free local compute** for low-caliber, high-volume,
|
||||||
|
parallelizable LLM work. The **always-available summarizer / classifier
|
||||||
|
endpoint** is `granite-4.1-8b` — the go-to for summarization, naming/
|
||||||
|
labeling, classification, and triage (fast, parallelizes well on vLLM):
|
||||||
|
served FP8 on ana-ml2 GPU 1, production-stable, 131k context (rebalanced
|
||||||
|
2026-06-13). Treat it as a standing dependency you can reach for any time.
|
||||||
|
Also behind the gateway: `qwen3.5-9b-fp8` (vision / multimodal — image +
|
||||||
|
text chat, GPU 1), `qwen3-embedding`, `qwen3-reranker`, and `glm-5.1` /
|
||||||
|
`glm-4.7` (via z.ai passthrough). The gateway 401s without a **virtual API
|
||||||
|
key**. **Shared all-agents key** — internal-only gateway, scoped to the *free
|
||||||
|
local* models only (granite + qwen-vision + embed/rerank, NOT the paid GLM):
|
||||||
|
`sk-eA_XOdcs6nIkyYXonohtEQ` (alias `all-agents-local`). Use it directly for
|
||||||
|
the always-available local endpoints — no per-project provisioning needed.
|
||||||
|
Example: `curl http://10.250.50.70:4000/v1/chat/completions -H "Authorization:
|
||||||
|
Bearer sk-eA_XOdcs6nIkyYXonohtEQ" -d '{"model":"granite-4.1-8b","messages":[…]}'`.
|
||||||
|
For the **paid** GLM passthroughs or broader scope, still request a
|
||||||
|
project-scoped key from infra-ops via althing (the shared key deliberately
|
||||||
|
can't spend z.ai cost). Rotatable via infra-ops if it leaks. Reach for
|
||||||
|
this before spending premium API tokens on tasks a small fast local model
|
||||||
|
handles fine (the LLM-last-resort floor still applies — deterministic first).
|
||||||
|
|
||||||
|
## DevOps delegation
|
||||||
|
|
||||||
|
For all DevOps work — deployments, infrastructure provisioning,
|
||||||
|
server administration, credential management, system-level package
|
||||||
|
installs, network/firewall configuration, service uptime — **prefer
|
||||||
|
routing to `infra-ops` via althing** rather than handling directly
|
||||||
|
in a project-dev session.
|
||||||
|
|
||||||
|
When infra-ops needs auth keys or access it doesn't already hold,
|
||||||
|
**it asks the appropriate peer agent directly** rather than blocking
|
||||||
|
on the operator. Examples:
|
||||||
|
|
||||||
|
- Heimdall scopes (Worldtree auth) → ask `worldtree-dev`.
|
||||||
|
- Gitea API tokens / repo permissions → ask the peer that holds
|
||||||
|
admin access for the relevant org.
|
||||||
|
- Vendor / subscription API keys (OpenAI, Anthropic, etc.) → ask
|
||||||
|
the operator or the peer that owns the consuming service.
|
||||||
|
- Cloud / hosting credentials → ask the operator.
|
||||||
|
|
||||||
|
The principle: infra-ops is self-sufficient on the access-gathering
|
||||||
|
front. Exhaust peer-agent paths before escalating to the operator.
|
||||||
|
The operator (Vuong) is the final authority for credentials not in
|
||||||
|
any agent's possession, but the agent network should resolve
|
||||||
|
credential routing among itself when possible.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
All attributions are to **Vuong Hoang**. Never reference Claude,
|
||||||
|
Claude Code, Anthropic, "AI-assisted", "Generated with …", or robot
|
||||||
|
emojis anywhere — git commit messages, PR bodies, README author lines,
|
||||||
|
LICENSE copyright, `pyproject.toml` authors, file headers, HTML
|
||||||
|
footers, or any other byline. The user is the author; the assistant
|
||||||
|
is invisible.
|
||||||
|
|
||||||
|
Specifically, never append:
|
||||||
|
|
||||||
|
- `Co-Authored-By: Claude …`
|
||||||
|
- `🤖 Generated with [Claude Code](…)`
|
||||||
|
- "with help from Claude / an AI assistant / etc."
|
||||||
|
|
||||||
|
…to any committed artifact.
|
||||||
|
|
||||||
|
## SemVer etiquette
|
||||||
|
|
||||||
|
**Canonical policy reference:** the formal versioning policy for ALL
|
||||||
|
projects lives at
|
||||||
|
`~/development/corviduo-project-template/docs/VERSIONING-POLICY.md`
|
||||||
|
(canonical, self-pinned as `versioning-policy-v1`). It governs version
|
||||||
|
format (SemVer 2.0.0), the public-contract declaration each project
|
||||||
|
must make, pre-1.0 semantics, pre-release staging (`-alpha.N` /
|
||||||
|
`-beta.N` / `-rc.N`, the same-commit rc discipline), dev/in-progress
|
||||||
|
labeling per ecosystem, commit conventions, the release process, and
|
||||||
|
special cases (hotfix, deprecation, breaking security fix, build
|
||||||
|
metadata). Consult it for any versioning question this section doesn't
|
||||||
|
answer — especially pre-releases and release staging, which this
|
||||||
|
section doesn't cover.
|
||||||
|
|
||||||
|
This section is Corviduo's **operational cadence layer on top of that
|
||||||
|
policy**: which commits become releases and at what tier (tier-bar
|
||||||
|
test, patch-default, operator approval for non-patch). Where the two
|
||||||
|
differ on cadence or tier choice, this section governs; for format,
|
||||||
|
contract semantics, pre-release staging, and release mechanics, the
|
||||||
|
policy governs. Operator ruling (2026-07-02): pre-1.0 **milestone
|
||||||
|
minors stay legal** — this section's non-breaking milestone-minor
|
||||||
|
examples override the policy's § 4 strict reading (pre-1.0 minor =
|
||||||
|
breaking changes only). Settled; do not re-litigate.
|
||||||
|
|
||||||
|
Each code-bearing or substantive-artifact commit bumps a version in
|
||||||
|
the project's `pyproject.toml` (or equivalent), refreshes the
|
||||||
|
lockfile, gets a `vX.Y.Z` git tag. Establishes a fine-grained
|
||||||
|
changelog and lets any peer pin against a known-good substrate
|
||||||
|
state.
|
||||||
|
|
||||||
|
**Tier-bar test (the decision tool):**
|
||||||
|
|
||||||
|
> *Does this release warrant a release note — or, in the case of a
|
||||||
|
> post-1.0 release, does it rise to the level of requiring a push
|
||||||
|
> notification to subscribed downstream consumers? Does this release
|
||||||
|
> warrant a blog post or a press release?*
|
||||||
|
|
||||||
|
The escalation maps to communication metaphors:
|
||||||
|
|
||||||
|
| Tier | Question | Communication metaphor |
|
||||||
|
|---|---|---|
|
||||||
|
| **Patch** (default) | n/a — patch is the workhorse default | Changelog line |
|
||||||
|
| **Minor** (pre-1.0) | Does this warrant a **release note**? | Subscribers glance at it |
|
||||||
|
| **Minor** (post-1.0) | Does this rise to **push-notification to subscribed downstream consumers**? | We actively reach out |
|
||||||
|
| **Major** | Does this warrant a **blog post or a press release**? | Story worth telling beyond subscribers |
|
||||||
|
|
||||||
|
The crucial implicit calibration: **the bar for minor RISES at v1.0.**
|
||||||
|
Pre-1.0, minor is cheap (would you write a release-note paragraph?);
|
||||||
|
post-1.0, minor is expensive (would you actually interrupt downstream
|
||||||
|
consumers about this?). Pre-1.0 is iterative cheap-minors; post-1.0
|
||||||
|
is stable deliberate-minors. Crossing v1.0 is a discipline-tightening
|
||||||
|
event, not just a number.
|
||||||
|
|
||||||
|
**In Corviduo,** "push notification to subscribed downstream
|
||||||
|
consumers" maps concretely to: **an althing post to peer-dev handles
|
||||||
|
announcing the change**. That's the actual mechanism. Operator or
|
||||||
|
Brokkr pings worldtree-dev / galdrabok-dev / sleipnir-dev / etc.
|
||||||
|
when a post-1.0 minor lands.
|
||||||
|
|
||||||
|
### Operator approval required for any non-patch bump
|
||||||
|
|
||||||
|
**Patch bumps are at agent discretion.** Apply them autonomously as
|
||||||
|
part of the work.
|
||||||
|
|
||||||
|
**Minor and major bumps REQUIRE explicit operator approval** before
|
||||||
|
the bump commit lands. The mechanism:
|
||||||
|
|
||||||
|
1. Identify that the work warrants a non-patch bump per the
|
||||||
|
tier-bar test (release-note / push-notification / blog-post).
|
||||||
|
2. Surface to the operator with a concrete question:
|
||||||
|
*"This work appears minor-worthy because <reason>. Approve the
|
||||||
|
vX.Y.Z → vX.Y+1.0 bump?"*
|
||||||
|
3. **Wait for explicit approval** before applying the bump.
|
||||||
|
4. Apply the bump (edit pyproject.toml, run `uv lock`, commit, tag)
|
||||||
|
only after the operator has said yes.
|
||||||
|
|
||||||
|
This guard exists because non-patch bumps in agent-applied autonomy
|
||||||
|
drifted upward — the operator caught a minor-cadence-too-fast
|
||||||
|
pathology on 2026-05-25 (three bumps in ~60 min, two of them
|
||||||
|
minor; would land at v0.4823.2 territory at sustained pace). The
|
||||||
|
tier-bar test alone wasn't sufficient discipline; explicit
|
||||||
|
operator-in-the-loop is the corrective.
|
||||||
|
|
||||||
|
If the operator pre-authorizes a session-level batch (e.g., "just
|
||||||
|
ship the next minor when you reach the heid-orchestrator milestone"),
|
||||||
|
that constitutes approval — but the pre-authorization should be
|
||||||
|
explicit and bounded to a specific upcoming event, not "all minors
|
||||||
|
going forward."
|
||||||
|
|
||||||
|
This rule applies UNIVERSALLY — even in repos where push is
|
||||||
|
agent-authorized (like Brokkr-Smithy per its project-local
|
||||||
|
CLAUDE.md). Push-discretion and bump-discretion are independent
|
||||||
|
authorizations.
|
||||||
|
|
||||||
|
### Patch (`X.Y.Z` → `X.Y.Z+1`) — workhorse default
|
||||||
|
|
||||||
|
The default for any code-bearing or substantive-artifact commit.
|
||||||
|
Includes:
|
||||||
|
|
||||||
|
- Bug fixes
|
||||||
|
- Internal correctness improvements
|
||||||
|
- Refactors with no public-surface signature change
|
||||||
|
- New artifacts within an existing family (new R-target finding, new
|
||||||
|
spec doc, new feedback memory)
|
||||||
|
- Single-commit features that don't require downstream coordination
|
||||||
|
- Validator additions, security tightenings, drift-against-spec
|
||||||
|
corrections
|
||||||
|
- Skill specs authored (spec drafted; minor fires at implementation
|
||||||
|
ship)
|
||||||
|
|
||||||
|
Patches accumulate routinely. Most commits are patches.
|
||||||
|
|
||||||
|
### Minor (`X.Y.Z` → `X.Y+1.0`) — coordinated-release event
|
||||||
|
|
||||||
|
Reserved for events where the tier-bar test fires: would you write a
|
||||||
|
release note (pre-1.0) or send a push notification to downstream
|
||||||
|
consumers (post-1.0)?
|
||||||
|
|
||||||
|
Pre-1.0, the bar is "release-note-worthy paragraph." Post-1.0, it's
|
||||||
|
the stricter "actually-pinging-consumers." Examples that pass at
|
||||||
|
either bar:
|
||||||
|
|
||||||
|
- **Cross-repo deliverable shipped to a peer agent** (e.g., Brokkr
|
||||||
|
R10 A01 ContextPromotion intelligence package → worldtree-dev).
|
||||||
|
Downstream HAS to react.
|
||||||
|
- **R-target full closure** — multi-finding + action lifecycle
|
||||||
|
complete; the package is the milestone landmark.
|
||||||
|
- **Skill IMPLEMENTATION shipped** at the implementation site
|
||||||
|
(post-spec absorption). Callers must adapt.
|
||||||
|
- **Methodology charter changes** (e.g., adding noise-floor
|
||||||
|
cross-check ambient to Brokkr's preregistration discipline).
|
||||||
|
High-leverage; affects every probe going forward.
|
||||||
|
- **Pre-v1.x breaking change** — under the no-backward-compatibility
|
||||||
|
rule, breaking changes ride in minor until v1.0. Breaking changes
|
||||||
|
are intrinsically release-note-worthy; minor is the right tier.
|
||||||
|
- **API signature change to publicly-callable surface** post-1.0
|
||||||
|
that affects fewer callers than a full major (e.g., new optional
|
||||||
|
parameter, opt-in capability). Still warrants the
|
||||||
|
push-notification.
|
||||||
|
|
||||||
|
Examples that DON'T pass the tier-bar and stay as patches:
|
||||||
|
|
||||||
|
- A single new R-target finding (F-ID) within an active R-target's
|
||||||
|
lifecycle. The closure is the milestone, not each finding.
|
||||||
|
- A new feedback memory written.
|
||||||
|
- A spec doc authored (minor fires at implementation, not at spec).
|
||||||
|
- A new probe artifact added within an existing probe.
|
||||||
|
- A persistent-memory snapshot.
|
||||||
|
|
||||||
|
### Major (`X.Y.Z` → `X+1.0.0`) — blog-post / press-release event
|
||||||
|
|
||||||
|
Reserved for v1.0+ release milestones AND post-1.0 events whose
|
||||||
|
scale warrants telling people beyond your subscriber base.
|
||||||
|
|
||||||
|
Pre-v1.x, the no-backward-compat rule means every minor can carry
|
||||||
|
breakage; major is the milestone-cut signal (v1.0 itself), not a
|
||||||
|
per-PR concern.
|
||||||
|
|
||||||
|
Post-v1.0:
|
||||||
|
|
||||||
|
- v1.0 release itself (the discipline-tightening crossover event).
|
||||||
|
- Substantial breaking changes that would otherwise force most
|
||||||
|
consumers to adapt at once.
|
||||||
|
- Architectural restructurings that downstream documentation,
|
||||||
|
integrations, and conceptual-mental-models depend on.
|
||||||
|
|
||||||
|
### Decision rule when ambiguous
|
||||||
|
|
||||||
|
**Default to patch.** Minor and major require explicit justification.
|
||||||
|
If the answer to "does this warrant a release note?" is "maybe, kind
|
||||||
|
of, I guess?" — that's a patch. Reserve minor for the unambiguous
|
||||||
|
yes-I'd-write-a-paragraph cases.
|
||||||
|
|
||||||
|
**When both minor and patch can be justified, default to patch.**
|
||||||
|
Tie-breaks go to patch, not minor. The "both could apply" situation
|
||||||
|
is itself a signal that minor's mandate isn't strong — if minor were
|
||||||
|
clearly warranted, patch wouldn't also be defensible. Patch is the
|
||||||
|
workhorse default; let it work. This is a sharper statement of the
|
||||||
|
same posture above: the bar for non-patch is "patch is NOT defensible
|
||||||
|
for this commit," not "minor is defensible." Asymmetric default in
|
||||||
|
favor of the cheaper tier.
|
||||||
|
|
||||||
|
The old "two callers react differently" rule remains a useful
|
||||||
|
internal check: if breaking-vs-keep-working applies to current
|
||||||
|
callers, it's at least minor. But the tier-bar is the load-bearing
|
||||||
|
test.
|
||||||
|
|
||||||
|
### SKIP the bump entirely for
|
||||||
|
|
||||||
|
- CI-only edits
|
||||||
|
- True docs-only edits (READMEs, comments, formatting)
|
||||||
|
- ADR commits with no code
|
||||||
|
- `.contract.md` commits with no code
|
||||||
|
- Memory-snapshot commits (`memory: snapshot — …`)
|
||||||
|
- Test-only commits with no production-code change
|
||||||
|
- WIP / TDD-RED commits where the tree is in a known-broken state
|
||||||
|
- Brokkr-side template edits with no runtime effect on Brokkr itself
|
||||||
|
- Worktree-rebuild or env-config changes
|
||||||
|
- `.claude/` configuration edits
|
||||||
|
|
||||||
|
### Cadence
|
||||||
|
|
||||||
|
Most commits should be patches. Minor should be rarer than commits —
|
||||||
|
often 5-15 patches between minors during active development.
|
||||||
|
|
||||||
|
A TDD red/green/refactor cycle bumps once or twice (GREEN as patch,
|
||||||
|
REFACTOR as patch — never three times for the same logical change).
|
||||||
|
A feature shipped as several incremental green commits bumps each as
|
||||||
|
patch; the minor that "publishes" the feature can fire at the end of
|
||||||
|
the arc if it warrants a release-note, OR can be skipped if patches
|
||||||
|
were sufficient.
|
||||||
|
|
||||||
|
If you find yourself bumping minor multiple times per session on the
|
||||||
|
same project, you're likely over-applying minor. Default back to
|
||||||
|
patch and ask: does this *specific* commit warrant a release-note
|
||||||
|
paragraph, or am I just accumulating substantive work?
|
||||||
|
|
||||||
|
### Mechanics every bump
|
||||||
|
|
||||||
|
0. **If non-patch, get operator approval first** per the § *Operator
|
||||||
|
approval required for any non-patch bump* rule above. Do not
|
||||||
|
proceed to step 1 until the operator has explicitly approved the
|
||||||
|
minor or major bump. (Patch bumps skip this step — apply
|
||||||
|
autonomously.)
|
||||||
|
1. Edit `pyproject.toml` (or equivalent project-file) version field.
|
||||||
|
2. Run `uv lock` (Python) or equivalent so the lockfile records the
|
||||||
|
new version. Don't hand-edit the lockfile.
|
||||||
|
3. Stage both files alongside the actual change.
|
||||||
|
4. Commit with the conventional shape (e.g., `feat(#N): …` /
|
||||||
|
`fix(#N): …` / `refactor: …`).
|
||||||
|
5. `git tag vX.Y.Z` after the commit. Lightweight (no `-a`, no
|
||||||
|
message) is deliberate for per-bump tags: the commit object
|
||||||
|
carries the rationale, and the tag is just a ref naming the
|
||||||
|
substrate state.
|
||||||
|
**Exception — milestone releases** (v1.0, v2.0, future major
|
||||||
|
cuts) get annotated tags (`git tag -a -m "…"`, or `git tag -s`
|
||||||
|
when signing). At a milestone the attestation matters separately
|
||||||
|
from the code change: release notes, tagger identity + date, and
|
||||||
|
optional GPG signature live in the tag object itself, where
|
||||||
|
downstream pins and supply-chain verifiers can read them.
|
||||||
|
6. Push is the operator's call — never push automatically.
|
||||||
|
(Project-local `CLAUDE.md` may grant push discretion, e.g.,
|
||||||
|
Brokkr-Smithy; honor those when present.)
|
||||||
|
|
||||||
|
### Calibration examples
|
||||||
|
|
||||||
|
**Brokkr-Smithy 2026-05-25 session (the recalibration trigger):**
|
||||||
|
|
||||||
|
Initially bumped under the pre-amendment rule:
|
||||||
|
|
||||||
|
- `v0.1.0 → v0.2.0` (minor) — F02 R06 v2 taxonomy reduction ship
|
||||||
|
- `v0.2.0 → v0.3.0` (minor) — Heid orchestrator spec set v0.1
|
||||||
|
- `v0.3.0 → v0.3.1` (patch) — migration runbook revision
|
||||||
|
|
||||||
|
Under THIS amended rule:
|
||||||
|
|
||||||
|
- F02 ship would be **patch** — single finding within R06 v2's
|
||||||
|
active lifecycle. R06 v2 closure (multi-finding + action) gets
|
||||||
|
the minor.
|
||||||
|
- Heid orchestrator spec set — **patch** strictly (spec authored,
|
||||||
|
not yet implemented). Galdrabok-dev's skill spec implementation
|
||||||
|
shipping IS minor (callers adapt).
|
||||||
|
- Runbook revision — **patch** (correct under both rules).
|
||||||
|
|
||||||
|
The session would have ended at roughly v0.1.5 (five patches) with
|
||||||
|
maybe a v0.2.0 cut when the heid orchestrator's smoke-tests-pass +
|
||||||
|
galdrabok ship lands as the cohesive milestone.
|
||||||
|
|
||||||
|
**Worldtree #185 (2026-05-21):**
|
||||||
|
|
||||||
|
- `v0.20.0` (minor) — `ChromaLongTermMemory.store/search/retrieve/
|
||||||
|
forget` gained required keyword-only `end_user_id`. Pre-v1.x
|
||||||
|
breaking change; every caller had to be updated. Release-note-
|
||||||
|
worthy in pre-1.0 framing. **Minor** under both old and new
|
||||||
|
rules.
|
||||||
|
- `v0.20.1` (patch) — Heid-flagged drift fixes within the v0.20.0
|
||||||
|
surface. **Patch** under both rules.
|
||||||
|
|
||||||
|
### Retroactive bumps
|
||||||
|
|
||||||
|
Don't retroactively bump past commits to align with a tightened
|
||||||
|
rule. Substrate-state baseline is forward-looking: the bump-cadence
|
||||||
|
from this point forward reflects the discipline; past versions
|
||||||
|
record what happened under the previous rule. The pre/post boundary
|
||||||
|
is the amendment-effective commit, not the rule itself.
|
||||||
|
|
||||||
|
## Roadmap discipline — v1 target + parking lot (anti-creep)
|
||||||
|
|
||||||
|
Projects sprawl at v0 when features land with **no v1 target to gate
|
||||||
|
them against** — every good idea, lacking a home, becomes v0 scope by
|
||||||
|
default, and the project never converges. This is the feature-axis
|
||||||
|
analog of two disciplines already in force: **value-of-information**
|
||||||
|
for probes (don't-measure-what-won't-change-behavior) and
|
||||||
|
**patch-default** for version bumps. Same posture —
|
||||||
|
*asymmetric default toward not-doing* — applied to features.
|
||||||
|
|
||||||
|
**Every project carries a `ROADMAP.md`** (a screenful, not a PRD):
|
||||||
|
|
||||||
|
1. **v1 target** — the small, explicit "what must be true to cut
|
||||||
|
1.0": **3–7 capabilities**. A big v1 is itself the creep; keep it
|
||||||
|
tight. This is the done-definition AND the anchor every feature is
|
||||||
|
gated against.
|
||||||
|
|
||||||
|
2. **Parking lot (post-v1 / vNext / spinout)** — every deferred idea,
|
||||||
|
named, with a home. Creep lands *here* instead of silently
|
||||||
|
becoming v0 scope. A "feature" that's really its own project is a
|
||||||
|
**spinout**, not v1 scope.
|
||||||
|
|
||||||
|
3. **The gate (the anti-creep mechanism):** a proposed feature → *on
|
||||||
|
the v1 path? → in; else → parking lot.* **Default = parking lot.**
|
||||||
|
When both "v1" and "park" are defensible, park it — the same
|
||||||
|
tie-break-to-the-cheaper-tier asymmetry as the SemVer patch-default.
|
||||||
|
Applies regardless of who proposed the feature (operator included);
|
||||||
|
the gate is about v1-path-fit, not provenance.
|
||||||
|
|
||||||
|
4. **Creep-check at checkpoints:** when surfacing progress, ask "is
|
||||||
|
what we're building on the v1 path?" Off-path-but-worth-keeping →
|
||||||
|
parking lot, surfaced to the operator, never silently into v0.
|
||||||
|
|
||||||
|
The per-project `ROADMAP.md` file shape + location is defined in
|
||||||
|
`corviduo-project-template` as a copied-in **skeleton** (like
|
||||||
|
`persistent-memory.md` — new projects copy it, then the content
|
||||||
|
diverges per project), NOT a byte-identical canonical. The skeleton
|
||||||
|
carries the shape; the discipline itself lives in this rule (loaded
|
||||||
|
every session), so no byte-sync of content is needed. This mirrors
|
||||||
|
the SemVer global-rule + per-project-version-file split: the version
|
||||||
|
*field* is conventional, its *value* diverges per project — nobody
|
||||||
|
canonical-syncs version values, and likewise nobody syncs roadmap
|
||||||
|
content. v1.0 is cut when the ROADMAP's v1 target is met — tying
|
||||||
|
directly into the SemVer "v1.0 = discipline-tightening event."
|
||||||
|
|
||||||
|
## Issue → AFK dispatch hygiene (Sleipnir)
|
||||||
|
|
||||||
|
Before marking any issue `ready-for-agent` (the label that gates AFK
|
||||||
|
dispatch via Sleipnir), it MUST have an issue-numbered contract at
|
||||||
|
`docs/contracts/issues/<N>.contract.md` AND that contract MUST carry
|
||||||
|
a `prd:` block in its YAML frontmatter pinning it to:
|
||||||
|
|
||||||
|
- the issue body (SHA-256, first 16 hex chars)
|
||||||
|
- the lock-in comment id + content SHA (or `null` if the issue body
|
||||||
|
alone is the spec)
|
||||||
|
- a `pinned_at` timestamp
|
||||||
|
|
||||||
|
This is hard policy, not a suggestion. Without the contract Sleipnir's
|
||||||
|
gate refuses dispatch with `blocked-needs-contract`. Without the `prd:`
|
||||||
|
block PRD-↔-ship drift becomes invisible — the audit infrastructure
|
||||||
|
that detects it is a no-op.
|
||||||
|
|
||||||
|
Verify before applying the label:
|
||||||
|
|
||||||
|
- contract file exists at the expected path
|
||||||
|
- frontmatter has a populated `prd:` block
|
||||||
|
- `python scripts/contract_drift_check.py --contract <path>` returns
|
||||||
|
clean (i.e., the pinned hashes match the live issue + comment)
|
||||||
|
|
||||||
|
The full convention — frontmatter shape, required fields, reasoning
|
||||||
|
behind the four drift entry points — lives in
|
||||||
|
`docs/contracts/CONTRACT-FORMAT.md` (the project that consumes
|
||||||
|
Sleipnir owns this file). Module-scoped contracts MAY adopt the same
|
||||||
|
`prd:` block when amended in response to a specific issue; for
|
||||||
|
issue-scoped contracts it is required.
|
||||||
+25
-20
@@ -105,12 +105,18 @@
|
|||||||
# Blue current directory.
|
# Blue current directory.
|
||||||
typeset -g POWERLEVEL9K_DIR_FOREGROUND=$lightergrey
|
typeset -g POWERLEVEL9K_DIR_FOREGROUND=$lightergrey
|
||||||
|
|
||||||
# Context format when root: user@host. The first part white, the rest grey.
|
# Context sits just left of the clock and shows the hostname, with the
|
||||||
|
# session type made obvious at a glance:
|
||||||
|
# native (local) -> grey hostname
|
||||||
|
# ssh (remote) -> yellow hostname tagged " ssh"
|
||||||
|
# root -> user@host, username in white
|
||||||
typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE="%F{$white}%n%f%F{$grey}@%m%f"
|
typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE="%F{$white}%n%f%F{$grey}@%m%f"
|
||||||
# Context format when not root: user@host. The whole thing grey.
|
|
||||||
typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE="%F{$grey}%n@%m%f"
|
typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE="%F{$grey}%n@%m%f"
|
||||||
# Don't show context unless root or in SSH.
|
typeset -g POWERLEVEL9K_CONTEXT_DEFAULT_TEMPLATE="%F{$grey}%m%f"
|
||||||
typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_CONTENT_EXPANSION=
|
typeset -g POWERLEVEL9K_CONTEXT_REMOTE_TEMPLATE="%F{$yellow}%m%f%F{$grey} ssh%f"
|
||||||
|
typeset -g POWERLEVEL9K_CONTEXT_REMOTE_SUDO_TEMPLATE="%F{$white}%n%f%F{$yellow}@%m%f%F{$grey} ssh%f"
|
||||||
|
# Keep only the local-sudo state quiet (matches Pure); every other state shows.
|
||||||
|
typeset -g POWERLEVEL9K_CONTEXT_SUDO_CONTENT_EXPANSION=
|
||||||
|
|
||||||
# Show previous command duration only if it's >= 5s.
|
# Show previous command duration only if it's >= 5s.
|
||||||
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=5
|
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=5
|
||||||
@@ -136,22 +142,21 @@
|
|||||||
typeset -g POWERLEVEL9K_VCS_{INCOMING,OUTGOING}_CHANGESFORMAT_FOREGROUND=$cyan
|
typeset -g POWERLEVEL9K_VCS_{INCOMING,OUTGOING}_CHANGESFORMAT_FOREGROUND=$cyan
|
||||||
# Don't show remote branch, current tag or stashes.
|
# Don't show remote branch, current tag or stashes.
|
||||||
typeset -g POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-untracked git-aheadbehind)
|
typeset -g POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-untracked git-aheadbehind)
|
||||||
# Don't show the branch icon.
|
# Nerd Font branch glyph () before the branch name.
|
||||||
typeset -g POWERLEVEL9K_VCS_BRANCH_ICON=
|
typeset -g POWERLEVEL9K_VCS_BRANCH_ICON=$' '
|
||||||
# When in detached HEAD state, show @commit where branch normally goes.
|
# Detached HEAD: git-commit glyph () where the branch name normally goes.
|
||||||
typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@'
|
typeset -g POWERLEVEL9K_VCS_COMMIT_ICON=$' '
|
||||||
# Don't show staged, unstaged, untracked indicators.
|
# Distinct Nerd Font glyphs, each followed by its count, for the working-tree state:
|
||||||
typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED}_ICON=
|
# staged · unstaged (modified, not staged) · untracked.
|
||||||
# Show '*' when there are staged, unstaged or untracked files.
|
# A category only renders when its count is non-zero.
|
||||||
typeset -g POWERLEVEL9K_VCS_DIRTY_ICON='*'
|
typeset -g POWERLEVEL9K_VCS_STAGED_ICON=$' '
|
||||||
# Show '⇣' if local branch is behind remote.
|
typeset -g POWERLEVEL9K_VCS_UNSTAGED_ICON=$' '
|
||||||
typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON=':⇣'
|
typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON=$' '
|
||||||
# Show '⇡' if local branch is ahead of remote.
|
# No separate catch-all dirty marker — the three glyphs above are the breakdown.
|
||||||
typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON=':⇡'
|
typeset -g POWERLEVEL9K_VCS_DIRTY_ICON=
|
||||||
# Don't show the number of commits next to the ahead/behind arrows.
|
# Nerd Font behind/ahead arrows (/), each followed by the commit count.
|
||||||
typeset -g POWERLEVEL9K_VCS_{COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=1
|
typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON=$' '
|
||||||
# Remove space between '⇣' and '⇡' and all trailing spaces.
|
typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON=$' '
|
||||||
typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${${${P9K_CONTENT/⇣* :⇡/⇣⇡}// }//:/ }'
|
|
||||||
|
|
||||||
# Grey current time.
|
# Grey current time.
|
||||||
typeset -g POWERLEVEL9K_TIME_FOREGROUND=$grey
|
typeset -g POWERLEVEL9K_TIME_FOREGROUND=$grey
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
~/.config/tmux/plugins
|
~/.config/tmux/plugins
|
||||||
~/.config/thefuck/__pycache__
|
|
||||||
~/.config/btop
|
~/.config/btop
|
||||||
~/.config/neofetch
|
~/.config/neofetch
|
||||||
~/.config/zinit
|
~/.config/zinit
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ config.colors = {
|
|||||||
config.window_decorations = "RESIZE"
|
config.window_decorations = "RESIZE"
|
||||||
config.default_prog = { 'pwsh' }
|
config.default_prog = { 'pwsh' }
|
||||||
else
|
else
|
||||||
config.window_background_opacity = 0.85
|
config.window_background_opacity = 0.95
|
||||||
config.macos_window_background_blur = 40
|
config.macos_window_background_blur = 40
|
||||||
config.enable_tab_bar = false
|
config.enable_tab_bar = false
|
||||||
config.window_decorations = "RESIZE"
|
config.window_decorations = "RESIZE"
|
||||||
|
|||||||
+33
-15
@@ -3,9 +3,12 @@ path=(~/bin $path)
|
|||||||
path=(~/.local/bin $path)
|
path=(~/.local/bin $path)
|
||||||
path=(~/.cache/lk-tools/fzf/bin $path)
|
path=(~/.cache/lk-tools/fzf/bin $path)
|
||||||
|
|
||||||
|
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
|
||||||
# Init OhMyPosh
|
# Initialization code that may require console input (password prompts, [y/n]
|
||||||
eval "$(oh-my-posh init zsh --config https://333e8677ac54a1845fe68813017ab7e807c87ab2@gitea.phasefinal.com/vh/dotfiles/raw/branch/master/home_config/ohmyposh/lkraven.toml)"
|
# confirmations, etc.) must go above this block; everything else may go below.
|
||||||
|
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
|
||||||
|
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
|
||||||
|
fi
|
||||||
|
|
||||||
# Set ZINIT Home
|
# Set ZINIT Home
|
||||||
ZINIT_HOME="${HOME}/.config/zinit/zinit.git"
|
ZINIT_HOME="${HOME}/.config/zinit/zinit.git"
|
||||||
@@ -20,6 +23,10 @@ fi
|
|||||||
source "${ZINIT_HOME}/zinit.zsh"
|
source "${ZINIT_HOME}/zinit.zsh"
|
||||||
|
|
||||||
# add zinit
|
# add zinit
|
||||||
|
# Powerlevel10k prompt theme (replaces oh-my-posh; instant prompt = fast startup)
|
||||||
|
zinit ice depth=1
|
||||||
|
zinit light romkatv/powerlevel10k
|
||||||
|
|
||||||
zinit light zsh-users/zsh-syntax-highlighting
|
zinit light zsh-users/zsh-syntax-highlighting
|
||||||
zinit light zsh-users/zsh-completions
|
zinit light zsh-users/zsh-completions
|
||||||
zinit light zsh-users/zsh-autosuggestions
|
zinit light zsh-users/zsh-autosuggestions
|
||||||
@@ -53,6 +60,10 @@ setopt hist_ignore_dups
|
|||||||
setopt hist_find_no_dups
|
setopt hist_find_no_dups
|
||||||
setopt hist_verify
|
setopt hist_verify
|
||||||
|
|
||||||
|
# allow inline `#` comments at the interactive prompt (paste-friendly;
|
||||||
|
# matches non-interactive/script behavior so pasted commands don't fail)
|
||||||
|
setopt interactive_comments
|
||||||
|
|
||||||
# completion styling
|
# completion styling
|
||||||
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
|
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
|
||||||
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
|
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
|
||||||
@@ -62,12 +73,10 @@ zstyle ':fzf-tab:complete:__zoxide_z:*' fzf-preview 'ls --color $realpath'
|
|||||||
zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup
|
zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup
|
||||||
|
|
||||||
# aliases
|
# aliases
|
||||||
alias ls='eza'
|
|
||||||
alias cat='bat'
|
alias cat='bat'
|
||||||
alias tree='eza --tree'
|
|
||||||
|
|
||||||
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
|
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
|
||||||
# [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
|
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
|
||||||
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
|
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
|
||||||
|
|
||||||
export FZF_DEFAULT_COMMAND="fd --hidden --strip-cwd-prefix --exclude .git"
|
export FZF_DEFAULT_COMMAND="fd --hidden --strip-cwd-prefix --exclude .git"
|
||||||
@@ -83,13 +92,13 @@ _fzf_compgen_dir() {
|
|||||||
source ~/fzf-git.sh/fzf-git.sh
|
source ~/fzf-git.sh/fzf-git.sh
|
||||||
|
|
||||||
export FZF_CTRL_T_OPTS="--preview 'bat -n --color=always --line-range :500 {}'"
|
export FZF_CTRL_T_OPTS="--preview 'bat -n --color=always --line-range :500 {}'"
|
||||||
export FZF_ALT_C_OPTS="--preview 'eza --tree --color=always {} | head -200'"
|
export FZF_ALT_C_OPTS="--preview 'ls -la {} | head -200'"
|
||||||
|
|
||||||
_fzf_comprun() {
|
_fzf_comprun() {
|
||||||
local command=$1
|
local command=$1
|
||||||
shift
|
shift
|
||||||
case "$command" in
|
case "$command" in
|
||||||
cd) fzf --preview 'eza --tree --color=always {} | head -200' "$@" ;;
|
cd) fzf --preview 'ls -la {} | head -200' "$@" ;;
|
||||||
export|unset) fzf --preview "eval 'echo \$' {}" "$@" ;;
|
export|unset) fzf --preview "eval 'echo \$' {}" "$@" ;;
|
||||||
ssh) fzf --preview 'dig {}' "$@" ;;
|
ssh) fzf --preview 'dig {}' "$@" ;;
|
||||||
*) fzf --preview 'bat -n --color=always --line-range :500 {}' "$@" ;;
|
*) fzf --preview 'bat -n --color=always --line-range :500 {}' "$@" ;;
|
||||||
@@ -99,19 +108,28 @@ export BAT_THEME=Nord
|
|||||||
eval "$(zoxide init zsh)"
|
eval "$(zoxide init zsh)"
|
||||||
alias cd='z'
|
alias cd='z'
|
||||||
|
|
||||||
eval $(thefuck --alias)
|
|
||||||
eval $(thefuck --alias fk)
|
|
||||||
|
|
||||||
zinit light Aloxaf/fzf-tab
|
zinit light Aloxaf/fzf-tab
|
||||||
|
|
||||||
|
|
||||||
if [[ $(uname) == "Darwin" ]]; then
|
# zsh-autosuggestions is already loaded via zinit above; on Linux, also wire
|
||||||
source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh
|
# the terminfo arrow keys to history search.
|
||||||
elif [[ $(uname) == "Linux" ]]; then
|
if [[ $(uname) == "Linux" ]]; then
|
||||||
source /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh
|
|
||||||
bindkey "${terminfo[kcuu1]}" history-search-backward
|
bindkey "${terminfo[kcuu1]}" history-search-backward
|
||||||
bindkey "${terminfo[kcud1]}" history-search-forward
|
bindkey "${terminfo[kcud1]}" history-search-forward
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
export STM32_PRG_PATH=/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app/Contents/MacOs/bin
|
export STM32_PRG_PATH=/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app/Contents/MacOs/bin
|
||||||
|
|
||||||
|
# bun completions
|
||||||
|
[ -s "/home/lkraven/.bun/_bun" ] && source "/home/lkraven/.bun/_bun"
|
||||||
|
|
||||||
|
# bun
|
||||||
|
export BUN_INSTALL="$HOME/.bun"
|
||||||
|
export PATH="$BUN_INSTALL/bin:$PATH"
|
||||||
|
|
||||||
|
# >>> grok installer >>>
|
||||||
|
export PATH="$HOME/.grok/bin:$PATH"
|
||||||
|
fpath=(~/.grok/completions/zsh $fpath)
|
||||||
|
autoload -Uz compinit && compinit -C
|
||||||
|
# <<< grok installer <<<
|
||||||
|
|||||||
+60
-2
@@ -1,3 +1,61 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
# One-shot, host-aware dotfile linker for Linux & macOS.
|
||||||
|
#
|
||||||
|
# home_root/* -> ~/<name> (e.g. ~/.zshrc) via `stow home_root`
|
||||||
|
# home_config/* -> ~/.config/<name> (e.g. ~/.config/nvim) via `stow home_config`
|
||||||
|
#
|
||||||
|
# Ensures GNU stow is present first (Homebrew on macOS; apt/dnf/pacman on Linux),
|
||||||
|
# so a fresh box needs nothing pre-installed. Re-running is safe — stow is
|
||||||
|
# idempotent and refuses to clobber unrelated real files.
|
||||||
|
#
|
||||||
|
# Windows / PowerShell: run ./link-dotfiles.ps1 instead (stow has no native
|
||||||
|
# Windows port; the .ps1 mirrors this with junctions + symlinks).
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
cd "$repo"
|
||||||
|
|
||||||
|
# `--apps`: install all host CLI tools first, then link. Without it, this only
|
||||||
|
# links (fast + idempotent). App install is delegated to the host-aware
|
||||||
|
# lk-installers/install-apps.
|
||||||
|
if [ "${1:-}" = "--apps" ]; then
|
||||||
|
echo "Installing apps first (--apps)…"
|
||||||
|
"$repo/lk-installers/install-apps"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ensure_stow() {
|
||||||
|
command -v stow >/dev/null 2>&1 && return
|
||||||
|
|
||||||
|
echo "GNU stow not found — installing it…"
|
||||||
|
case "$(uname -s)" in
|
||||||
|
Darwin)
|
||||||
|
if ! command -v brew >/dev/null 2>&1; then
|
||||||
|
echo "error: Homebrew is required on macOS. Run ./lk-installers/install-apps (or ./link-dotfiles --apps) first." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
brew install stow
|
||||||
|
;;
|
||||||
|
Linux)
|
||||||
|
if command -v apt >/dev/null 2>&1; then sudo apt update && sudo apt install -y stow
|
||||||
|
elif command -v dnf >/dev/null 2>&1; then sudo dnf install -y stow
|
||||||
|
elif command -v pacman >/dev/null 2>&1; then sudo pacman -S --noconfirm stow
|
||||||
|
else
|
||||||
|
echo "error: no supported package manager (apt/dnf/pacman). Install GNU stow manually." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "error: unsupported OS '$(uname -s)'. On Windows run ./link-dotfiles.ps1 instead." >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_stow
|
||||||
|
|
||||||
|
echo "Linking home_root -> ~"
|
||||||
stow -v home_root
|
stow -v home_root
|
||||||
stow -v --target=$HOME/.config/ home_config
|
echo "Linking home_config -> ~/.config"
|
||||||
|
stow -v --target="$HOME/.config" home_config
|
||||||
|
|
||||||
|
echo "Done."
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Windows equivalent of ./link-dotfiles (the GNU stow script).
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
stow can't run natively on Windows, so this mirrors what it does:
|
||||||
|
home_root/* -> ~\<name> (e.g. ~\.zshrc)
|
||||||
|
home_config/* -> ~\.config\<name> (e.g. ~\.config\nvim)
|
||||||
|
|
||||||
|
Directories are linked with junctions and files with symlinks/hardlinks,
|
||||||
|
none of which need administrator rights (junctions and hardlinks never do;
|
||||||
|
symlinks are attempted first in case Developer Mode is on, then we fall
|
||||||
|
back). Re-running is safe: correct links are skipped, and any real file or
|
||||||
|
directory that would be clobbered is moved aside to <name>.bak first.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
pwsh -File .\link-dotfiles.ps1
|
||||||
|
#>
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
# Print what would happen without changing anything.
|
||||||
|
[switch]$DryRun
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$repo = $PSScriptRoot
|
||||||
|
$home_ = $HOME
|
||||||
|
|
||||||
|
# stow metadata files we must never link into the home tree.
|
||||||
|
$skip = @('.stow-local-ignore', '.stow-global-ignore')
|
||||||
|
|
||||||
|
function Get-LinkTarget {
|
||||||
|
param([string]$Path)
|
||||||
|
$item = Get-Item -LiteralPath $Path -Force -ErrorAction SilentlyContinue
|
||||||
|
if ($item -and $item.LinkType) { return $item.Target }
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Link-Item {
|
||||||
|
param(
|
||||||
|
[string]$Source, # absolute path inside the repo
|
||||||
|
[string]$Dest # absolute path under the home tree
|
||||||
|
)
|
||||||
|
|
||||||
|
$isDir = (Get-Item -LiteralPath $Source -Force).PSIsContainer
|
||||||
|
|
||||||
|
# Already linked to the right place? Nothing to do.
|
||||||
|
$existingTarget = Get-LinkTarget $Dest
|
||||||
|
if ($existingTarget -and ($existingTarget -ieq $Source)) {
|
||||||
|
Write-Host " ok $Dest" -ForegroundColor DarkGray
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path -LiteralPath $Dest) {
|
||||||
|
if ($existingTarget) {
|
||||||
|
# A link, but pointing elsewhere -> replace it.
|
||||||
|
if ($DryRun) { Write-Host " relink $Dest (was -> $existingTarget)" -ForegroundColor Yellow; return }
|
||||||
|
Remove-Item -LiteralPath $Dest -Force -Recurse
|
||||||
|
} else {
|
||||||
|
# A real file/dir -> back it up rather than destroy it.
|
||||||
|
$bak = "$Dest.bak"
|
||||||
|
Write-Host " backup $Dest -> $bak" -ForegroundColor Yellow
|
||||||
|
if (-not $DryRun) { Move-Item -LiteralPath $Dest -Destination $bak -Force }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($DryRun) { Write-Host " link $Dest -> $Source" -ForegroundColor Cyan; return }
|
||||||
|
|
||||||
|
$parent = Split-Path $Dest -Parent
|
||||||
|
if (-not (Test-Path $parent)) { New-Item -ItemType Directory -Path $parent -Force | Out-Null }
|
||||||
|
|
||||||
|
if ($isDir) {
|
||||||
|
New-Item -ItemType Junction -Path $Dest -Target $Source | Out-Null
|
||||||
|
Write-Host " junc $Dest -> $Source" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
# Prefer a real symlink (needs admin or Developer Mode); fall back to a
|
||||||
|
# hardlink (same volume, no admin); finally just copy.
|
||||||
|
try {
|
||||||
|
New-Item -ItemType SymbolicLink -Path $Dest -Target $Source -ErrorAction Stop | Out-Null
|
||||||
|
Write-Host " link $Dest -> $Source" -ForegroundColor Green
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
New-Item -ItemType HardLink -Path $Dest -Target $Source -ErrorAction Stop | Out-Null
|
||||||
|
Write-Host " hard $Dest -> $Source" -ForegroundColor Green
|
||||||
|
} catch {
|
||||||
|
Copy-Item -LiteralPath $Source -Destination $Dest -Force
|
||||||
|
Write-Host " copy $Dest (could not link; copied)" -ForegroundColor Magenta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "home_root -> $home_"
|
||||||
|
Get-ChildItem -LiteralPath (Join-Path $repo 'home_root') -Force |
|
||||||
|
Where-Object { $skip -notcontains $_.Name } |
|
||||||
|
ForEach-Object { Link-Item $_.FullName (Join-Path $home_ $_.Name) }
|
||||||
|
|
||||||
|
$configDir = Join-Path $home_ '.config'
|
||||||
|
Write-Host "home_config -> $configDir"
|
||||||
|
Get-ChildItem -LiteralPath (Join-Path $repo 'home_config') -Force |
|
||||||
|
Where-Object { $skip -notcontains $_.Name } |
|
||||||
|
ForEach-Object { Link-Item $_.FullName (Join-Path $configDir $_.Name) }
|
||||||
|
|
||||||
|
# Windows Terminal lives in a package folder outside the stow tree, so link its
|
||||||
|
# settings.json explicitly. Skipped silently if Terminal isn't installed.
|
||||||
|
$wtPkg = Get-ChildItem (Join-Path $env:LOCALAPPDATA 'Packages') -Filter 'Microsoft.WindowsTerminal_*' -Directory -ErrorAction SilentlyContinue |
|
||||||
|
Select-Object -First 1
|
||||||
|
$wtSrc = Join-Path $repo 'windows\windows-terminal\settings.json'
|
||||||
|
if ($wtPkg -and (Test-Path $wtSrc)) {
|
||||||
|
$wtDest = Join-Path $wtPkg.FullName 'LocalState\settings.json'
|
||||||
|
Write-Host "windows-terminal -> $wtDest"
|
||||||
|
Link-Item $wtSrc $wtDest
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Done." -ForegroundColor Green
|
||||||
Executable
+100
@@ -0,0 +1,100 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Host-aware installer for every CLI tool the dotfiles assume at runtime.
|
||||||
|
#
|
||||||
|
# macOS -> Homebrew (bootstraps Homebrew itself if missing)
|
||||||
|
# Linux -> apt (Debian/Ubuntu) + upstream installers for tools not in apt
|
||||||
|
#
|
||||||
|
# zinit and all zsh plugins (powerlevel10k, zsh-autosuggestions,
|
||||||
|
# zsh-syntax-highlighting, zsh-completions, zsh-vi-mode, fzf-tab) bootstrap
|
||||||
|
# themselves from ~/.zshrc on first shell start — they are NOT installed here.
|
||||||
|
#
|
||||||
|
# Idempotent: re-running only fills gaps. Pairs with ./link-dotfiles, or run
|
||||||
|
# `./link-dotfiles --apps` to install then link in one shot.
|
||||||
|
#
|
||||||
|
# Consolidates the former macinstaller / install-apt-pkgs / install-tools /
|
||||||
|
# install-zellij scripts.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# fzf-git.sh is a sourced helper (not a package) — same on every platform.
|
||||||
|
clone_fzf_git() {
|
||||||
|
if [ -d "$HOME/fzf-git.sh" ]; then
|
||||||
|
echo "fzf-git.sh already cloned — skipping"
|
||||||
|
else
|
||||||
|
git clone --depth 1 https://github.com/junegunn/fzf-git.sh.git "$HOME/fzf-git.sh"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_macos() {
|
||||||
|
if ! command -v brew >/dev/null 2>&1; then
|
||||||
|
echo "Homebrew not found — installing…"
|
||||||
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||||
|
if [ -x /opt/homebrew/bin/brew ]; then eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||||
|
elif [ -x /usr/local/bin/brew ]; then eval "$(/usr/local/bin/brew shellenv)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing CLI tools via Homebrew…"
|
||||||
|
brew install \
|
||||||
|
zsh git curl wget stow \
|
||||||
|
bat fd fzf zoxide \
|
||||||
|
zellij neovim btop htop fastfetch
|
||||||
|
# tldr is deprecated upstream — best-effort so a dead formula can't abort the
|
||||||
|
# run. tlrc is the maintained `tldr` client.
|
||||||
|
brew install tlrc || brew install tldr || echo "tldr unavailable — skipping"
|
||||||
|
|
||||||
|
# fzf key-bindings + completion -> ~/.fzf.zsh (sourced by .zshrc). These flags
|
||||||
|
# make it non-interactive; --no-update-rc stops it editing .zshrc (the repo
|
||||||
|
# owns that file).
|
||||||
|
"$(brew --prefix)/opt/fzf/install" --key-bindings --completion --no-update-rc >/dev/null
|
||||||
|
|
||||||
|
clone_fzf_git
|
||||||
|
}
|
||||||
|
|
||||||
|
install_linux() {
|
||||||
|
if ! command -v apt >/dev/null 2>&1; then
|
||||||
|
echo "error: Linux app install targets Debian/Ubuntu (apt). Install the tools manually on this distro." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing base packages via apt…"
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y --no-install-recommends \
|
||||||
|
neovim vim-nox btop htop curl wget tldr git zip unzip stow zsh cargo \
|
||||||
|
zsh-autosuggestions zsh-syntax-highlighting
|
||||||
|
sudo apt install -y --no-install-recommends rar unrar || true
|
||||||
|
# fastfetch (modern neofetch); falls back to neofetch on older distros.
|
||||||
|
sudo apt install -y fastfetch || sudo apt install -y neofetch || echo "fastfetch/neofetch unavailable — skipping"
|
||||||
|
|
||||||
|
# fzf (vendored under ~/.cache/lk-tools/fzf; .zshrc adds its bin to PATH)
|
||||||
|
if [ ! -d "$HOME/.cache/lk-tools/fzf" ]; then
|
||||||
|
git clone --depth 1 https://github.com/junegunn/fzf.git "$HOME/.cache/lk-tools/fzf"
|
||||||
|
"$HOME/.cache/lk-tools/fzf/install" --key-bindings --completion --no-update-rc
|
||||||
|
fi
|
||||||
|
clone_fzf_git
|
||||||
|
|
||||||
|
# zoxide (upstream installer -> ~/.local/bin, already on PATH)
|
||||||
|
command -v zoxide >/dev/null 2>&1 || \
|
||||||
|
curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh
|
||||||
|
|
||||||
|
# bat + fd: upstream .deb so the binaries are named `bat`/`fd` (Debian ships
|
||||||
|
# them as `batcat`/`fdfind`). amd64 assumed — adjust the URLs on arm64 boxes.
|
||||||
|
if ! command -v bat >/dev/null 2>&1; then
|
||||||
|
wget -qO /tmp/bat.deb https://github.com/sharkdp/bat/releases/download/v0.24.0/bat_0.24.0_amd64.deb
|
||||||
|
sudo apt install -y /tmp/bat.deb
|
||||||
|
fi
|
||||||
|
if ! command -v fd >/dev/null 2>&1; then
|
||||||
|
wget -qO /tmp/fd.deb https://github.com/sharkdp/fd/releases/download/v10.1.0/fd_10.1.0_amd64.deb
|
||||||
|
sudo apt install -y /tmp/fd.deb
|
||||||
|
fi
|
||||||
|
|
||||||
|
# zellij: cargo build, fall back to apt
|
||||||
|
command -v zellij >/dev/null 2>&1 || cargo install zellij || sudo apt install -y zellij
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$(uname -s)" in
|
||||||
|
Darwin) install_macos ;;
|
||||||
|
Linux) install_linux ;;
|
||||||
|
*) echo "error: unsupported OS '$(uname -s)'." >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "Done. Open a new shell (or 'exec zsh') to pick everything up."
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
sudo apt update
|
|
||||||
sudo apt install neovim vim-nox btop htop neofetch curl wget tldr git zip unzip stow zsh zsh-autosuggestions zsh-syntax-highlighting cargo --no-install-recommends
|
|
||||||
sudo apt install rar unrar --no-install-recommends
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check if Eza is installed
|
|
||||||
|
|
||||||
if dpkg-query -Wf'${db:Status-abbrev}' eza; then
|
|
||||||
sudo apt install -y eza
|
|
||||||
else
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install gpg
|
|
||||||
sudo mkdir -p /etc/apt/keyrings
|
|
||||||
wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | sudo gpg --dearmor -o /etc/apt/keyrings/gierens.gpg
|
|
||||||
echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" | sudo tee /etc/apt/sources.list.d/gierens.list
|
|
||||||
sudo chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y eza
|
|
||||||
fi
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
curl -s https://ohmyposh.dev/install.sh | bash -s
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install python3-dev python3-pip python3-setuptools python3-venv
|
|
||||||
python3 -m venv ~/homebase
|
|
||||||
source ~/homebase/bin/activate
|
|
||||||
pip3 install thefuck
|
|
||||||
mv ~/homebase/bin/fuck ~/.local/bin/
|
|
||||||
mv ~/homebase/bin/thefuck ~/.local/bin/
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.cache/lk-tools/fzf
|
|
||||||
~/.cache/lk-tools/fzf/install
|
|
||||||
git clone https://github.com/junegunn/fzf-git.sh.git ~/fzf-git.sh
|
|
||||||
curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh
|
|
||||||
wget -O /tmp/bat.deb https://github.com/sharkdp/bat/releases/download/v0.24.0/bat_0.24.0_amd64.deb
|
|
||||||
sudo apt install /tmp/bat.deb
|
|
||||||
wget -O /tmp/fdfind.deb https://github.com/sharkdp/fd/releases/download/v10.1.0/fd_10.1.0_amd64.deb
|
|
||||||
sudo apt install /tmp/fdfind.deb
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "Installing Zellij via cargo..."
|
|
||||||
cargo install zellij || {
|
|
||||||
echo "Cargo failed - trying apt instead"
|
|
||||||
sudo apt update && sudo apt install -y zellij
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# filepath: /Users/vhpfi/dotfiles/lk-installers/macinstaller
|
|
||||||
|
|
||||||
# Check if Homebrew is installed
|
|
||||||
if command -v brew >/dev/null 2>&1; then
|
|
||||||
echo "Homebrew is already installed. Updating..."
|
|
||||||
brew update
|
|
||||||
else
|
|
||||||
echo "Homebrew not found. Installing Homebrew..."
|
|
||||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
||||||
|
|
||||||
# Add Homebrew to PATH for the current session
|
|
||||||
if [[ -f /opt/homebrew/bin/brew ]]; then
|
|
||||||
# For Apple Silicon Macs
|
|
||||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
|
||||||
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
|
|
||||||
echo "Homebrew has been installed and added to your PATH."
|
|
||||||
elif [[ -f /usr/local/bin/brew ]]; then
|
|
||||||
# For Intel Macs
|
|
||||||
eval "$(/usr/local/bin/brew shellenv)"
|
|
||||||
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile
|
|
||||||
echo "Homebrew has been installed and added to your PATH."
|
|
||||||
else
|
|
||||||
echo "Error: Couldn't find the Homebrew binary after installation."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Installing packages with Homebrew..."
|
|
||||||
brew install neovim btop htop neofetch curl wget git zip unzip zsh tldr
|
|
||||||
brew install zsh-autosuggestions zsh-syntax-highlighting
|
|
||||||
brew install rustup-init
|
|
||||||
rustup-init -y
|
|
||||||
|
|
||||||
echo "Installation complete!"
|
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
{
|
||||||
|
"$help": "https://aka.ms/terminal-documentation",
|
||||||
|
"$schema": "https://aka.ms/terminal-profiles-schema",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"command":
|
||||||
|
{
|
||||||
|
"action": "copy",
|
||||||
|
"singleLine": false
|
||||||
|
},
|
||||||
|
"id": "User.copy.644BA8F2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "paste",
|
||||||
|
"id": "User.paste"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command":
|
||||||
|
{
|
||||||
|
"action": "splitPane",
|
||||||
|
"split": "auto",
|
||||||
|
"splitMode": "duplicate"
|
||||||
|
},
|
||||||
|
"id": "User.splitPane.A6751878"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "find",
|
||||||
|
"id": "User.find"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"copyFormatting": "none",
|
||||||
|
"copyOnSelect": false,
|
||||||
|
"defaultProfile": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
|
||||||
|
"keybindings":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "User.copy.644BA8F2",
|
||||||
|
"keys": "ctrl+c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "User.find",
|
||||||
|
"keys": "ctrl+shift+f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "User.paste",
|
||||||
|
"keys": "ctrl+v"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "User.splitPane.A6751878",
|
||||||
|
"keys": "alt+shift+d"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"newTabMenu":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "remainingProfiles"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"profiles":
|
||||||
|
{
|
||||||
|
"defaults":
|
||||||
|
{
|
||||||
|
"colorScheme": "Australis",
|
||||||
|
"font":
|
||||||
|
{
|
||||||
|
"face": "VictorMono Nerd Font",
|
||||||
|
"size": 11,
|
||||||
|
"features":
|
||||||
|
{
|
||||||
|
"calt": 1,
|
||||||
|
"liga": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"antialiasingMode": "grayscale",
|
||||||
|
"cursorShape": "bar",
|
||||||
|
"intenseTextStyle": "all",
|
||||||
|
"opacity": 95,
|
||||||
|
"padding": "10",
|
||||||
|
"scrollbarState": "visible",
|
||||||
|
"snapOnInput": true,
|
||||||
|
"useAcrylic": false
|
||||||
|
},
|
||||||
|
"list":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
|
||||||
|
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
|
||||||
|
"hidden": false,
|
||||||
|
"name": "Windows PowerShell"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"commandline": "%SystemRoot%\\System32\\cmd.exe",
|
||||||
|
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
|
||||||
|
"hidden": false,
|
||||||
|
"name": "Command Prompt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
|
||||||
|
"hidden": false,
|
||||||
|
"name": "Azure Cloud Shell",
|
||||||
|
"source": "Windows.Terminal.Azure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"elevate": true,
|
||||||
|
"guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
|
||||||
|
"hidden": false,
|
||||||
|
"name": "PowerShell",
|
||||||
|
"opacity": 95,
|
||||||
|
"source": "Windows.Terminal.PowershellCore",
|
||||||
|
"useAcrylic": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"schemes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Australis",
|
||||||
|
"foreground": "#a9bcc3",
|
||||||
|
"background": "#222531",
|
||||||
|
"cursorColor": "#6388d8",
|
||||||
|
"selectionBackground": "#6388d8",
|
||||||
|
"black": "#222531",
|
||||||
|
"red": "#ff491a",
|
||||||
|
"green": "#16b866",
|
||||||
|
"yellow": "#e1c631",
|
||||||
|
"blue": "#6388d8",
|
||||||
|
"purple": "#9d78ff",
|
||||||
|
"cyan": "#00b1a8",
|
||||||
|
"white": "#a9bcc3",
|
||||||
|
"brightBlack": "#373b46",
|
||||||
|
"brightRed": "#ff854f",
|
||||||
|
"brightGreen": "#51e08a",
|
||||||
|
"brightYellow": "#ffe14e",
|
||||||
|
"brightBlue": "#a4c4ff",
|
||||||
|
"brightPurple": "#d8adff",
|
||||||
|
"brightCyan": "#42dcd1",
|
||||||
|
"brightWhite": "#cce7ec"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"themes": [],
|
||||||
|
"windowingBehavior": "useAnyExisting"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user