@quickcall/all-configs 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +15 -2
  2. package/bin/all-configs.js +44 -0
  3. package/package.json +20 -4
  4. package/runtime/allconfigs/__init__.py +1 -0
  5. package/runtime/allconfigs/__main__.py +42 -0
  6. package/runtime/allconfigs/__pycache__/__init__.cpython-312.pyc +0 -0
  7. package/runtime/allconfigs/__pycache__/__main__.cpython-312.pyc +0 -0
  8. package/runtime/allconfigs/__pycache__/modules.cpython-312.pyc +0 -0
  9. package/runtime/allconfigs/__pycache__/probe.cpython-312.pyc +0 -0
  10. package/runtime/allconfigs/__pycache__/runner.cpython-312.pyc +0 -0
  11. package/runtime/allconfigs/modules.py +221 -0
  12. package/runtime/allconfigs/probe.py +60 -0
  13. package/runtime/install.sh +74 -0
  14. package/runtime/lib/common.sh +147 -0
  15. package/runtime/lib/uninstall.sh +35 -0
  16. package/runtime/modules/aldente/install.sh +23 -0
  17. package/runtime/modules/aldente/module.toml +11 -0
  18. package/runtime/modules/aliases/aliases.sh +31 -0
  19. package/runtime/modules/aliases/install.sh +36 -0
  20. package/runtime/modules/aliases/module.toml +7 -0
  21. package/runtime/modules/aqua-voice/install.sh +23 -0
  22. package/runtime/modules/aqua-voice/module.toml +11 -0
  23. package/runtime/modules/betterdisplay/install.sh +23 -0
  24. package/runtime/modules/betterdisplay/module.toml +11 -0
  25. package/runtime/modules/bitwarden/install.sh +19 -0
  26. package/runtime/modules/bitwarden/module.toml +11 -0
  27. package/runtime/modules/browsers/install.sh +33 -0
  28. package/runtime/modules/browsers/module.toml +11 -0
  29. package/runtime/modules/bun/install.sh +72 -0
  30. package/runtime/modules/bun/module.toml +7 -0
  31. package/runtime/modules/caveman/install.sh +79 -0
  32. package/runtime/modules/caveman/module.toml +7 -0
  33. package/runtime/modules/claude/install.sh +22 -0
  34. package/runtime/modules/claude/module.toml +7 -0
  35. package/runtime/modules/codex/install.sh +20 -0
  36. package/runtime/modules/codex/module.toml +7 -0
  37. package/runtime/modules/docker/install.sh +19 -0
  38. package/runtime/modules/docker/module.toml +11 -0
  39. package/runtime/modules/external-skills/install.sh +30 -0
  40. package/runtime/modules/external-skills/module.toml +4 -0
  41. package/runtime/modules/ffmpeg/install.sh +13 -0
  42. package/runtime/modules/ffmpeg/module.toml +11 -0
  43. package/runtime/modules/fonts/install.sh +62 -0
  44. package/runtime/modules/fonts/module.toml +8 -0
  45. package/runtime/modules/ghostty/config +44 -0
  46. package/runtime/modules/ghostty/install.sh +64 -0
  47. package/runtime/modules/ghostty/module.toml +9 -0
  48. package/runtime/modules/ghostty/themes/ayu-dark +22 -0
  49. package/runtime/modules/ghostty/themes/catppuccin-frappe +23 -0
  50. package/runtime/modules/ghostty/themes/catppuccin-latte +23 -0
  51. package/runtime/modules/ghostty/themes/catppuccin-latte.conf +23 -0
  52. package/runtime/modules/ghostty/themes/catppuccin-macchiato +23 -0
  53. package/runtime/modules/ghostty/themes/catppuccin-mocha +23 -0
  54. package/runtime/modules/ghostty/themes/visual-studio-light +27 -0
  55. package/runtime/modules/ghostty/themes/vscode-light +24 -0
  56. package/runtime/modules/ghostty/themes/vscode-light-soft +24 -0
  57. package/runtime/modules/ghostty/xterm-ghostty.terminfo +81 -0
  58. package/runtime/modules/github/install.sh +101 -0
  59. package/runtime/modules/github/module.toml +8 -0
  60. package/runtime/modules/hf/install.sh +98 -0
  61. package/runtime/modules/hf/module.toml +7 -0
  62. package/runtime/modules/karabiner/README.md +146 -0
  63. package/runtime/modules/karabiner/agents.md +39 -0
  64. package/runtime/modules/karabiner/app_launchers.json +236 -0
  65. package/runtime/modules/karabiner/custom_delete_mapping.json +13 -0
  66. package/runtime/modules/karabiner/fn_to_control.json +9 -0
  67. package/runtime/modules/karabiner/install.sh +60 -0
  68. package/runtime/modules/karabiner/karabiner.json +866 -0
  69. package/runtime/modules/karabiner/keychron-modifier-swap.sh +80 -0
  70. package/runtime/modules/karabiner/module.toml +8 -0
  71. package/runtime/modules/karabiner/remap_caps_lock_shift_super.json +23 -0
  72. package/runtime/modules/karabiner/remap_escape_to_control.json +49 -0
  73. package/runtime/modules/karabiner/rename_caps_lock_to_super.json +23 -0
  74. package/runtime/modules/karabiner/right_shift_mouse_click.json +44 -0
  75. package/runtime/modules/karabiner/swap_esc_delete.json +10 -0
  76. package/runtime/modules/karabiner/troubleshooting.md +242 -0
  77. package/runtime/modules/karabiner/vim_arrow_keys.json +477 -0
  78. package/runtime/modules/keepingyouawake/install.sh +23 -0
  79. package/runtime/modules/keepingyouawake/module.toml +11 -0
  80. package/runtime/modules/keycastr/install.sh +23 -0
  81. package/runtime/modules/keycastr/module.toml +11 -0
  82. package/runtime/modules/multi-github/install.sh +179 -0
  83. package/runtime/modules/multi-github/module.toml +4 -0
  84. package/runtime/modules/ncdu/install.sh +13 -0
  85. package/runtime/modules/ncdu/module.toml +11 -0
  86. package/runtime/modules/node/install.sh +73 -0
  87. package/runtime/modules/node/module.toml +11 -0
  88. package/runtime/modules/nvim/.neoconf.json +15 -0
  89. package/runtime/modules/nvim/init.lua +2 -0
  90. package/runtime/modules/nvim/install.sh +142 -0
  91. package/runtime/modules/nvim/lazy-lock.json +35 -0
  92. package/runtime/modules/nvim/lazyvim.json +10 -0
  93. package/runtime/modules/nvim/lua/config/autocmds.lua +18 -0
  94. package/runtime/modules/nvim/lua/config/keymaps.lua +10 -0
  95. package/runtime/modules/nvim/lua/config/lazy.lua +53 -0
  96. package/runtime/modules/nvim/lua/config/options.lua +3 -0
  97. package/runtime/modules/nvim/lua/plugins/image.lua +9 -0
  98. package/runtime/modules/nvim/lua/plugins/markdown.lua +56 -0
  99. package/runtime/modules/nvim/lua/plugins/noice.lua +17 -0
  100. package/runtime/modules/nvim/lua/plugins/rose-pine.lua +16 -0
  101. package/runtime/modules/nvim/lua/plugins/snacks.lua +20 -0
  102. package/runtime/modules/nvim/module.toml +8 -0
  103. package/runtime/modules/nvim/stylua.toml +3 -0
  104. package/runtime/modules/p10k/install.sh +46 -0
  105. package/runtime/modules/p10k/module.toml +8 -0
  106. package/runtime/modules/p10k/p10k.zsh +1711 -0
  107. package/runtime/modules/pi/install.sh +77 -0
  108. package/runtime/modules/pi/module.toml +8 -0
  109. package/runtime/modules/pi/packages +5 -0
  110. package/runtime/modules/pi/settings.json +21 -0
  111. package/runtime/modules/presentify/install.sh +25 -0
  112. package/runtime/modules/presentify/module.toml +7 -0
  113. package/runtime/modules/rectangle/RectangleConfig.json +353 -0
  114. package/runtime/modules/rectangle/install.sh +64 -0
  115. package/runtime/modules/rectangle/module.toml +11 -0
  116. package/runtime/modules/shortcat/install.sh +19 -0
  117. package/runtime/modules/shortcat/module.toml +11 -0
  118. package/runtime/modules/skills/install.sh +25 -0
  119. package/runtime/modules/skills/module.toml +4 -0
  120. package/runtime/modules/skills/skills-lock.json +35 -0
  121. package/runtime/modules/slack/install.sh +23 -0
  122. package/runtime/modules/slack/module.toml +11 -0
  123. package/runtime/modules/spotify/install.sh +23 -0
  124. package/runtime/modules/spotify/module.toml +11 -0
  125. package/runtime/modules/ssh-keygen/install.sh +130 -0
  126. package/runtime/modules/ssh-keygen/module.toml +4 -0
  127. package/runtime/modules/statusline/install.sh +69 -0
  128. package/runtime/modules/statusline/module.toml +7 -0
  129. package/runtime/modules/statusline/statusline.sh +168 -0
  130. package/runtime/modules/statusline/turn-counter.sh +11 -0
  131. package/runtime/modules/superfile/cheatsheet.md +127 -0
  132. package/runtime/modules/superfile/config.toml +181 -0
  133. package/runtime/modules/superfile/hotkeys.toml +96 -0
  134. package/runtime/modules/superfile/install.sh +73 -0
  135. package/runtime/modules/superfile/module.toml +7 -0
  136. package/runtime/modules/tailscale/install.sh +29 -0
  137. package/runtime/modules/tailscale/module.toml +11 -0
  138. package/runtime/modules/tinycast/install.sh +68 -0
  139. package/runtime/modules/tinycast/module.toml +7 -0
  140. package/runtime/modules/tinycast/settings.json +226 -0
  141. package/runtime/modules/tmux/.tmux.conf.local +168 -0
  142. package/runtime/modules/tmux/README.md +50 -0
  143. package/runtime/modules/tmux/install.sh +57 -0
  144. package/runtime/modules/tmux/installer.mjs +191 -0
  145. package/runtime/modules/tmux/module.toml +8 -0
  146. package/runtime/modules/tmux/shell-helpers.sh +20 -0
  147. package/runtime/modules/tmux/uninstall.sh +134 -0
  148. package/runtime/modules/uv/install.sh +72 -0
  149. package/runtime/modules/uv/module.toml +7 -0
  150. package/runtime/modules/vlc/install.sh +23 -0
  151. package/runtime/modules/vlc/module.toml +11 -0
  152. package/runtime/modules/vscode/install.sh +33 -0
  153. package/runtime/modules/vscode/keybindings.json +74 -0
  154. package/runtime/modules/vscode/module.toml +8 -0
  155. package/runtime/modules/vscode/settings.json +426 -0
  156. package/runtime/modules/vscode/tasks.json +1 -0
  157. package/runtime/modules/yt-dlp/install.sh +13 -0
  158. package/runtime/modules/yt-dlp/module.toml +11 -0
  159. package/runtime/modules/zed/install.sh +43 -0
  160. package/runtime/modules/zed/module.toml +8 -0
  161. package/runtime/modules/zed/settings.json +208 -0
  162. package/runtime/modules/zoxide/install.sh +41 -0
  163. package/runtime/modules/zoxide/module.toml +11 -0
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env bash
2
+ # Multi-GitHub account setup — never push as the wrong account again.
3
+ #
4
+ # What it does:
5
+ # 1. Generates one ed25519 key per GitHub account (reuses existing keys).
6
+ # 2. Adds SSH host aliases: github.com -> personal, github-<work> -> work.
7
+ # 3. Adds a directory-scoped git identity (includeIf) for the work dir, so
8
+ # commits there are authored as the work account automatically.
9
+ # 4. Rewrites all github.com remote URLs inside the work dir to the work
10
+ # SSH alias — https remotes work too, authenticated as the work account.
11
+ #
12
+ # After running: add each printed public key to its GitHub account at
13
+ # https://github.com/settings/ssh/new (while logged in as that account).
14
+ set -e
15
+
16
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17
+ ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
18
+ source "$ROOT_DIR/lib/common.sh"
19
+
20
+ usage() {
21
+ cat << USAGE
22
+ Usage: ${0##*/} [options]
23
+
24
+ Options: (all required — this script stores no account names or emails)
25
+ -p, --personal <name> Personal GitHub account/login; also the SSH key suffix
26
+ -w, --work <name> Work GitHub account/login; also the SSH key suffix
27
+ -d, --work-dir <path> Directory whose repos use the work account
28
+ -W, --work-email <email> Work commit email (e.g. <id>+<login>@users.noreply.github.com)
29
+ -h, --help Show this help
30
+
31
+ Environment variables: GH_PERSONAL, GH_WORK, GH_WORK_DIR, GH_WORK_EMAIL
32
+
33
+ Examples:
34
+ ${0##*/} -p alice -w alice-corp -d "\$HOME/work" -W "12345+alice-corp@users.noreply.github.com"
35
+ GH_PERSONAL=alice GH_WORK=alice-corp GH_WORK_DIR="\$HOME/work" GH_WORK_EMAIL="12345+alice-corp@users.noreply.github.com" ${0##*/}
36
+ USAGE
37
+ exit 0
38
+ }
39
+
40
+ PERSONAL="${GH_PERSONAL:-}"
41
+ WORK="${GH_WORK:-}"
42
+ WORK_DIR="${GH_WORK_DIR:-}"
43
+ WORK_EMAIL="${GH_WORK_EMAIL:-}"
44
+
45
+ while [[ $# -gt 0 ]]; do
46
+ case "$1" in
47
+ -p|--personal) PERSONAL="$2"; shift 2 ;;
48
+ -w|--work) WORK="$2"; shift 2 ;;
49
+ -d|--work-dir) WORK_DIR="$2"; shift 2 ;;
50
+ -W|--work-email) WORK_EMAIL="$2"; shift 2 ;;
51
+ -h|--help) usage ;;
52
+ *) fail "Unknown option: $1"; exit 1 ;;
53
+ esac
54
+ done
55
+
56
+ # Interactive fallback (terminal or the TUI's pty): prompt for anything not given
57
+ if [[ -t 0 ]]; then
58
+ [[ -n "$PERSONAL" ]] || read -rp " Personal GitHub login: " PERSONAL
59
+ [[ -n "$WORK" ]] || read -rp " Work GitHub login: " WORK
60
+ [[ -n "$WORK_DIR" ]] || read -rp " Directory for work repos (e.g. \$HOME/work): " WORK_DIR
61
+ [[ -n "$WORK_EMAIL" ]] || read -rp " Work commit email: " WORK_EMAIL
62
+ WORK_DIR="${WORK_DIR/#\~/$HOME}"
63
+ fi
64
+
65
+ missing=()
66
+ [[ -z "$PERSONAL" ]] && missing+=("--personal")
67
+ [[ -z "$WORK" ]] && missing+=("--work")
68
+ [[ -z "$WORK_DIR" ]] && missing+=("--work-dir")
69
+ [[ -z "$WORK_EMAIL" ]] && missing+=("--work-email")
70
+ if [[ ${#missing[@]} -gt 0 ]]; then
71
+ fail "Missing required options: ${missing[*]}"
72
+ echo " Run ${0##*/} --help for details. No account names or emails are stored in this script."
73
+ exit 1
74
+ fi
75
+ if [[ "$PERSONAL" == "$WORK" ]]; then
76
+ fail "--personal and --work must be different accounts"
77
+ exit 1
78
+ fi
79
+
80
+ WORK_ALIAS="github-${WORK}"
81
+ SSH_CONFIG="$HOME/.ssh/config"
82
+ WORK_GITCONFIG="$HOME/.gitconfig-${WORK}"
83
+ MARK_BEGIN="# BEGIN multi-github (${PERSONAL} / ${WORK})"
84
+ MARK_END="# END multi-github"
85
+
86
+ # ---------------------------------------------------------------------------
87
+ step "Generating SSH keys (reuses existing)"
88
+ mkdir -p "$HOME/.ssh" && chmod 700 "$HOME/.ssh"
89
+ for acct in "$PERSONAL" "$WORK"; do
90
+ key="$HOME/.ssh/id_ed25519_${acct}"
91
+ if [[ -f "$key" ]]; then
92
+ ok "key exists: $key"
93
+ else
94
+ ssh-keygen -t ed25519 -C "${acct}@$(hostname -s 2>/dev/null || echo mac)" -f "$key" -N "" -q
95
+ ok "generated: $key"
96
+ fi
97
+ done
98
+
99
+ # ---------------------------------------------------------------------------
100
+ step "Writing SSH host aliases"
101
+ touch "$SSH_CONFIG"
102
+ backup_file "$SSH_CONFIG"
103
+ sed -i.bak "/$(echo "$MARK_BEGIN" | sed 's/[][\.*^$/]/\\&/g')/,/$(echo "$MARK_END" | sed 's/[][\.*^$/]/\\&/g')/d" "$SSH_CONFIG" 2>/dev/null || true
104
+ rm -f "$SSH_CONFIG.bak"
105
+ cat >> "$SSH_CONFIG" << EOF
106
+
107
+ $MARK_BEGIN
108
+ # github.com -> $PERSONAL (personal, default everywhere)
109
+ Host github.com
110
+ HostName github.com
111
+ User git
112
+ IdentityFile ~/.ssh/id_ed25519_${PERSONAL}
113
+ IdentitiesOnly yes
114
+
115
+ # ${WORK_ALIAS} -> $WORK (work account — use for work remotes)
116
+ Host ${WORK_ALIAS}
117
+ HostName github.com
118
+ User git
119
+ IdentityFile ~/.ssh/id_ed25519_${WORK}
120
+ IdentitiesOnly yes
121
+ $MARK_END
122
+ EOF
123
+ ok "ssh config → $SSH_CONFIG"
124
+ ok "aliases: github.com=${PERSONAL}, ${WORK_ALIAS}=${WORK}"
125
+
126
+ # ---------------------------------------------------------------------------
127
+ step "Configuring git identities"
128
+ if [[ -z "$(git config --global user.name 2>/dev/null)" ]]; then
129
+ git config --global user.name "$PERSONAL"
130
+ ok "global git user.name → $PERSONAL"
131
+ else
132
+ ok "global git user.name already set ($(git config --global user.name)) — leaving it"
133
+ fi
134
+
135
+ cat > "$WORK_GITCONFIG" << EOF
136
+ # Work identity — applies automatically to every repo under ${WORK_DIR}/
137
+ [user]
138
+ name = ${WORK}
139
+ email = ${WORK_EMAIL}
140
+
141
+ # Any GitHub remote in work dirs authenticates as ${WORK} via SSH,
142
+ # whether the remote URL is https or ssh.
143
+ [url "git@${WORK_ALIAS}:"]
144
+ insteadOf = "git@github.com:"
145
+ insteadOf = "https://github.com/"
146
+ EOF
147
+ ok "work gitconfig → $WORK_GITCONFIG"
148
+
149
+ # Idempotently register the includeIf in ~/.gitconfig
150
+ ABS_WORK_DIR="$(cd "$WORK_DIR" 2>/dev/null && pwd || echo "$WORK_DIR")"
151
+ if git config --global --get-all includeif.gitdir:"${ABS_WORK_DIR}/".path 2>/dev/null | grep -qF "$WORK_GITCONFIG"; then
152
+ ok "includeIf already registered for ${ABS_WORK_DIR}/"
153
+ else
154
+ git config --global includeIf.gitdir:"${ABS_WORK_DIR}/".path "$WORK_GITCONFIG"
155
+ ok "includeIf registered: ${ABS_WORK_DIR}/ → $WORK_GITCONFIG"
156
+ fi
157
+
158
+ # ---------------------------------------------------------------------------
159
+ step "Your public keys — add each while logged in as that account"
160
+ echo ""
161
+ echo -e " ${B}${WORK}${R} → paste at ${CYN}https://github.com/settings/ssh/new${R}:"
162
+ echo " $(cat "$HOME/.ssh/id_ed25519_${WORK}.pub")"
163
+ echo ""
164
+ echo -e " ${B}${PERSONAL}${R} → paste at ${CYN}https://github.com/settings/ssh/new${R}:"
165
+ echo " $(cat "$HOME/.ssh/id_ed25519_${PERSONAL}.pub")"
166
+ echo ""
167
+
168
+ step "Verify (after adding keys to GitHub)"
169
+ echo -e " ssh -T git@github.com ${D}# expect: Hi ${PERSONAL}!${R}"
170
+ echo -e " ssh -T git@${WORK_ALIAS} ${D}# expect: Hi ${WORK}!${R}"
171
+ echo -e " In a work repo: ${CYN}git var GIT_AUTHOR_IDENT${R} ${D}# expect ${WORK} identity${R}"
172
+ echo ""
173
+
174
+ step "Testing authentication (expected to fail until keys are added)"
175
+ ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 -T "git@github.com" 2>&1 | sed 's/^/ /' || true
176
+ ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 -T "git@${WORK_ALIAS}" 2>&1 | sed 's/^/ /' || true
177
+ echo ""
178
+ ok "Done. Work repos under ${ABS_WORK_DIR}/ authenticate + commit as ${WORK}; everything else as ${PERSONAL}."
179
+ echo -e " ${D}gh CLI note: gh commands still use the active account — check with 'gh auth status'.${R}"
@@ -0,0 +1,4 @@
1
+ name = "multi-github"
2
+ description = "Two GitHub accounts on one machine \u2014 per-account SSH aliases, directory-based git identity, and URL rewriting so pushes never use the wrong account"
3
+ platforms = ["mac", "linux"]
4
+ kind = "config"
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
6
+ source "$ROOT_DIR/lib/common.sh"
7
+
8
+ step "Installing ncdu"
9
+ ensure_cmd ncdu
10
+
11
+ echo ""
12
+ echo -e " ${GRN}Done!${R}"
13
+ echo ""
@@ -0,0 +1,11 @@
1
+ name = "ncdu"
2
+ description = "Interactive disk usage analyzer"
3
+ platforms = ["mac", "linux"]
4
+ kind = "cli"
5
+
6
+ [detect]
7
+ commands = ["ncdu"]
8
+
9
+ [uninstall]
10
+ brew = ["ncdu"]
11
+ packages = ["ncdu"]
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
6
+ source "$ROOT_DIR/lib/common.sh"
7
+
8
+ step "Installing Node.js (npm + npx)"
9
+
10
+ # Prefer nvm-managed node when available (e.g. Vast.ai images)
11
+ if [[ -s "/opt/nvm/nvm.sh" ]]; then
12
+ export NVM_DIR="/opt/nvm"
13
+ # shellcheck source=/dev/null
14
+ source "$NVM_DIR/nvm.sh"
15
+ ok "nvm detected ${D}$(nvm --version)${R}"
16
+
17
+ if ! nvm ls "v24" &>/dev/null; then
18
+ warn "nvm node 24 not found — installing latest LTS"
19
+ nvm install --lts
20
+ fi
21
+ nvm alias default "v24" &>/dev/null || true
22
+
23
+ # Ensure node/npm/npx are on PATH for the rest of this shell
24
+ export PATH="$NVM_DIR/versions/node/v24.19.0/bin:$PATH"
25
+ ok "node ${D}$(node --version) → $(command -v node)${R}"
26
+ ok "npm ${D}$(npm --version)${R}"
27
+ ok "npx ${D}$(npx --version)${R}"
28
+
29
+ # Persist nvm load in shell rc files
30
+ for rc in "$HOME/.zshrc" "$HOME/.bashrc"; do
31
+ [[ -f "$rc" ]] || continue
32
+ if ! grep -Fq "[ -s \"/opt/nvm/nvm.sh\" ]" "$rc" 2>/dev/null; then
33
+ printf '\n# nvm\nexport NVM_DIR="/opt/nvm"\n[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"\n' >> "$rc"
34
+ ok "nvm loader added to $(basename "$rc")"
35
+ fi
36
+ done
37
+
38
+ echo ""
39
+ echo -e " ${GRN}Done!${R} node $(node --version) ready (nvm)"
40
+ echo ""
41
+ exit 0
42
+ fi
43
+
44
+ # Fallback install path
45
+ if command -v node &>/dev/null; then
46
+ if [[ "$PLATFORM" == "linux" ]] && ! node -e 'const [maj,min,patch]=process.versions.node.split(".").map(Number); process.exit(maj > 22 || (maj === 22 && (min > 19 || (min === 19 && patch >= 0))) ? 0 : 1)'; then
47
+ warn "node $(node --version) too old for Pi — upgrading to Node 24"
48
+ curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
49
+ sudo apt-get install -y nodejs
50
+ fi
51
+ ok "node ${D}$(node --version) → $(command -v node)${R}"
52
+ else
53
+ warn "node not found — installing"
54
+ if [[ "$PLATFORM" == "linux" ]]; then
55
+ curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
56
+ sudo apt-get install -y nodejs
57
+ else
58
+ pkg_install node
59
+ fi
60
+ ok "node installed ${D}$(node --version)${R}"
61
+ fi
62
+
63
+ if command -v npm &>/dev/null; then
64
+ ok "npm ${D}$(npm --version)${R}"
65
+ fi
66
+
67
+ if command -v npx &>/dev/null; then
68
+ ok "npx ${D}$(npx --version)${R}"
69
+ fi
70
+
71
+ echo ""
72
+ echo -e " ${GRN}Done!${R} node $(node --version) ready"
73
+ echo ""
@@ -0,0 +1,11 @@
1
+ name = "node"
2
+ description = "Node.js, npm, npx via system package manager"
3
+ platforms = ["mac", "linux"]
4
+ kind = "cli"
5
+
6
+ [detect]
7
+ commands = ["node"]
8
+
9
+ [uninstall]
10
+ brew = ["node"]
11
+ packages = ["nodejs"]
@@ -0,0 +1,15 @@
1
+ {
2
+ "neodev": {
3
+ "library": {
4
+ "enabled": true,
5
+ "plugins": true
6
+ }
7
+ },
8
+ "neoconf": {
9
+ "plugins": {
10
+ "lua_ls": {
11
+ "enabled": true
12
+ }
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,2 @@
1
+ -- bootstrap lazy.nvim, LazyVim and your plugins
2
+ require("config.lazy")
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
6
+ source "$ROOT_DIR/lib/common.sh"
7
+
8
+ step "Installing neovim config (LazyVim)"
9
+
10
+ # Ensure build tools for native plugins
11
+ step "Ensuring build tools"
12
+ if ! command -v gcc &> /dev/null || ! command -v make &> /dev/null; then
13
+ warn "gcc/make not found — installing build-essential"
14
+ if [[ "$PLATFORM" == "mac" ]]; then
15
+ brew_install_formula gcc
16
+ brew_install_formula make
17
+ else
18
+ sudo apt-get update -qq && sudo apt-get install -y -qq build-essential
19
+ fi
20
+ ok "build tools installed"
21
+ else
22
+ ok "gcc and make present"
23
+ fi
24
+
25
+ # Ensure nvim is installed
26
+ if ! command -v nvim &>/dev/null; then
27
+ warn "nvim not found — installing"
28
+ if [[ "$PLATFORM" == "mac" ]]; then
29
+ brew_install_formula neovim
30
+ else
31
+ if command -v snap &>/dev/null; then
32
+ sudo snap install nvim --classic
33
+ elif command -v apt-get &>/dev/null; then
34
+ sudo apt-get install -y -qq software-properties-common
35
+ sudo add-apt-repository -y ppa:neovim-ppa/unstable
36
+ sudo apt-get update -qq
37
+ sudo apt-get install -y -qq neovim
38
+ else
39
+ pkg_install neovim
40
+ fi
41
+ fi
42
+ ok "nvim installed"
43
+ else
44
+ ok "nvim ${D}$(nvim --version 2>/dev/null | head -1 | grep -oE '[0-9]+\.[0-9]+[^ ]*' | head -1)${R}"
45
+ fi
46
+
47
+ # fuzzy finder + search tools (picker deps: fzf-lua/telescope, grep, file finding)
48
+ step "Ensuring search tools"
49
+ for tool in fzf fd ripgrep imagemagick; do
50
+ if pkg_check "$tool"; then
51
+ ok "$tool present"
52
+ elif [[ "$PLATFORM" == "mac" ]]; then
53
+ brew_install_formula "$tool" || warn "$tool install failed"
54
+ else
55
+ pkg_install "$tool" && ok "$tool installed" || warn "$tool install failed"
56
+ fi
57
+ done
58
+
59
+ # tree-sitter CLI — NOTE: the brew `tree-sitter` formula is library-only (no
60
+ # binary). The CLI ships in the separate `tree-sitter-cli` formula. Verify the
61
+ # actual binary, not the formula.
62
+ if command -v tree-sitter &>/dev/null && tree-sitter --version &>/dev/null; then
63
+ ok "tree-sitter-cli ${D}$(tree-sitter --version | head -1)${R}"
64
+ else
65
+ if [[ "$PLATFORM" == "mac" ]]; then
66
+ brew_install_formula tree-sitter-cli
67
+ elif command -v npm &>/dev/null; then
68
+ npm install -g tree-sitter-cli
69
+ ok "tree-sitter-cli installed via npm"
70
+ else
71
+ warn "tree-sitter-cli not found (no brew/npm — Mason will provide it)"
72
+ fi
73
+ command -v tree-sitter &>/dev/null && ok "tree-sitter-cli present" || warn "tree-sitter CLI still missing"
74
+ fi
75
+
76
+ # ripgrep — functional check, not just presence. fzf-lua/grug-far shell out to
77
+ # rg with these exact flags; catch broken/shimmed binaries early.
78
+ if command -v rg &>/dev/null && echo "rg smoke test" | rg --column --line-number --no-heading --color=never --smart-case "smoke" &>/dev/null; then
79
+ ok "ripgrep ${D}$(rg --version | head -1)${R}"
80
+ else
81
+ warn "rg missing or broken — installing ripgrep"
82
+ pkg_install ripgrep && ok "ripgrep installed" || warn "ripgrep install failed"
83
+ fi
84
+
85
+ # Install config into Neovim's actual stdpath("config"). Snap builds may use
86
+ # /home/$USER/.config even when $HOME differs.
87
+ NVIM_DIR="$(nvim --headless '+lua io.write(vim.fn.stdpath("config"))' +qa 2>/dev/null || true)"
88
+ [[ -n "$NVIM_DIR" ]] || NVIM_DIR="$HOME/.config/nvim"
89
+ mkdir -p "$NVIM_DIR"
90
+
91
+ backup_file "$NVIM_DIR"
92
+
93
+ # Copy all files
94
+ rsync -a "$SCRIPT_DIR/" "$NVIM_DIR/" \
95
+ --exclude install.sh \
96
+ --exclude README.md \
97
+ --exclude '._*' \
98
+ --exclude '.DS_Store'
99
+ find "$NVIM_DIR" -name '._*' -delete 2>/dev/null || true
100
+ find "$NVIM_DIR" -name '.DS_Store' -delete 2>/dev/null || true
101
+ ok "nvim config ${D}→ $NVIM_DIR/${R}"
102
+
103
+ # Install plugins
104
+ step "Installing nvim plugins"
105
+ plugin_log="$(mktemp)"
106
+ if nvim --headless "+Lazy! restore" +qa >"$plugin_log" 2>&1; then
107
+ if grep -Eq "E492:|Failed to load|Error detected" "$plugin_log"; then
108
+ warn "plugin bootstrap hit config errors — open nvim manually"
109
+ tail -20 "$plugin_log" || true
110
+ elif grep -q "mason.nvim] Neovim exited while the following packages were installing" "$plugin_log"; then
111
+ warn "plugins bootstrapped; some Mason packages continue on first interactive open"
112
+ else
113
+ ok "plugins installed"
114
+ fi
115
+ else
116
+ warn "open nvim manually — plugins will auto-install"
117
+ tail -20 "$plugin_log" || true
118
+ fi
119
+ rm -f "$plugin_log"
120
+
121
+ # Verify the environment nvim actually sees (rg, tree-sitter CLI, node)
122
+ step "Verifying nvim environment"
123
+ health_log="$(mktemp)"
124
+ nvim --headless "+checkhealth lazyvim" "+silent w! $health_log" +qa >/dev/null 2>&1 || true
125
+ for dep in rg "tree-sitter"; do
126
+ if grep -q "✅ OK \`$dep\`" "$health_log" 2>/dev/null; then
127
+ ok "$dep healthy inside nvim"
128
+ else
129
+ warn "$dep reported unhealthy in checkhealth — run :checkhealth lazyvim in nvim"
130
+ fi
131
+ done
132
+ if grep -q "❌ ERROR" "$health_log" 2>/dev/null; then
133
+ warn "checkhealth reports errors — run :checkhealth lazyvim in nvim for details"
134
+ else
135
+ ok "checkhealth clean"
136
+ fi
137
+ rm -f "$health_log"
138
+
139
+ echo ""
140
+ echo -e " ${GRN}Done!${R} Run ${CYN}nvim${R} to start"
141
+ echo -e " ${D}Theme: Rose Pine Dawn | Leader: Space${R}"
142
+ echo ""
@@ -0,0 +1,35 @@
1
+ {
2
+ "LazyVim": { "branch": "main", "commit": "c10948c50b18fae7f256433afdef09e432410480" },
3
+ "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" },
4
+ "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
5
+ "catppuccin": { "branch": "main", "commit": "0303a7208dba448c459767486a38a6ec05c4216b" },
6
+ "conform.nvim": { "branch": "master", "commit": "619363c30309d29ffa631e67c8183f2a72caa373" },
7
+ "flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" },
8
+ "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
9
+ "gitsigns.nvim": { "branch": "main", "commit": "25050e4ed39e628282831d4cbecb1850454ce915" },
10
+ "grug-far.nvim": { "branch": "main", "commit": "c995bbacf8229dc096ec1c3d60f8531059c86c1b" },
11
+ "lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
12
+ "lazydev.nvim": { "branch": "main", "commit": "ff2cbcba459b637ec3fd165a2be59b7bbaeedf0d" },
13
+ "lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" },
14
+ "mason-lspconfig.nvim": { "branch": "main", "commit": "0a695750d747db1e7e70bcf0267ef8951c95fc83" },
15
+ "mason.nvim": { "branch": "main", "commit": "16ba83bfc8a25f52bb545134f5bee082b195c460" },
16
+ "mini.ai": { "branch": "main", "commit": "4511b3481707c1d021485475d34f2ed2a50bf47b" },
17
+ "mini.icons": { "branch": "main", "commit": "520995f1d75da0e4cc901ee95080b1ff2bc46b94" },
18
+ "mini.pairs": { "branch": "main", "commit": "30cf2f01c4aaa2033db67376b9924fa2442c05d6" },
19
+ "noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" },
20
+ "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
21
+ "nvim-lint": { "branch": "master", "commit": "99cbc3ca8a76845fca50e496be7212bebf907dd3" },
22
+ "nvim-lspconfig": { "branch": "master", "commit": "229b79051b380377664edc4cbd534930154921a1" },
23
+ "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
24
+ "nvim-treesitter-textobjects": { "branch": "main", "commit": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e" },
25
+ "nvim-ts-autotag": { "branch": "main", "commit": "88c1453db4ba7dd24131086fe51fdf74e587d275" },
26
+ "persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" },
27
+ "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
28
+ "rose-pine": { "branch": "main", "commit": "ff483051a47e27d84bdef47703538df1ed9f4a47" },
29
+ "snacks.nvim": { "branch": "main", "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" },
30
+ "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
31
+ "tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" },
32
+ "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" },
33
+ "ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" },
34
+ "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
35
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extras": [
3
+
4
+ ],
5
+ "install_version": 8,
6
+ "news": {
7
+ "NEWS.md": "11866"
8
+ },
9
+ "version": 8
10
+ }
@@ -0,0 +1,18 @@
1
+ -- Autocmds are automatically loaded on the VeryLazy event
2
+ -- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua
3
+ --
4
+ -- Add any additional autocmds here
5
+ -- with `vim.api.nvim_create_autocmd`
6
+ --
7
+ -- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults)
8
+ -- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell")
9
+
10
+ -- Image buffers: snacks.image injects render placeholders -> buffer looks "modified"
11
+ -- and nvim nags to save on close. Images are read-only views; never mark modified.
12
+ vim.api.nvim_create_autocmd({ "BufEnter", "TextChanged", "TextChangedI" }, {
13
+ callback = function(e)
14
+ if vim.bo[e.buf].filetype == "image" then
15
+ vim.bo[e.buf].modified = false
16
+ end
17
+ end,
18
+ })
@@ -0,0 +1,10 @@
1
+ -- Keymaps are automatically loaded on the VeryLazy event
2
+ -- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua
3
+ -- Add any additional keymaps here
4
+
5
+ -- Yank absolute path of current file to system clipboard
6
+ vim.keymap.set("n", "<leader>yp", function()
7
+ local path = vim.fn.expand("%:p")
8
+ vim.fn.setreg("+", path)
9
+ vim.notify("Yanked: " .. path, vim.log.levels.INFO, { title = "yank path" })
10
+ end, { desc = "Yank absolute path" })
@@ -0,0 +1,53 @@
1
+ local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
2
+ if not (vim.uv or vim.loop).fs_stat(lazypath) then
3
+ local lazyrepo = "https://github.com/folke/lazy.nvim.git"
4
+ local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
5
+ if vim.v.shell_error ~= 0 then
6
+ vim.api.nvim_echo({
7
+ { "Failed to clone lazy.nvim:\n", "ErrorMsg" },
8
+ { out, "WarningMsg" },
9
+ { "\nPress any key to exit..." },
10
+ }, true, {})
11
+ vim.fn.getchar()
12
+ os.exit(1)
13
+ end
14
+ end
15
+ vim.opt.rtp:prepend(lazypath)
16
+
17
+ require("lazy").setup({
18
+ spec = {
19
+ -- add LazyVim and import its plugins
20
+ { "LazyVim/LazyVim", import = "lazyvim.plugins" },
21
+ -- import/override with your plugins
22
+ { import = "plugins" },
23
+ },
24
+ defaults = {
25
+ -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup.
26
+ -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default.
27
+ lazy = false,
28
+ -- It's recommended to leave version=false for now, since a lot the plugin that support versioning,
29
+ -- have outdated releases, which may break your Neovim install.
30
+ version = false, -- always use the latest git commit
31
+ -- version = "*", -- try installing the latest stable version for plugins that support semver
32
+ },
33
+ install = { colorscheme = { "tokyonight", "habamax" } },
34
+ checker = {
35
+ enabled = true, -- check for plugin updates periodically
36
+ notify = false, -- notify on update
37
+ }, -- automatically check for plugin updates
38
+ performance = {
39
+ rtp = {
40
+ -- disable some rtp plugins
41
+ disabled_plugins = {
42
+ "gzip",
43
+ -- "matchit",
44
+ -- "matchparen",
45
+ -- "netrwPlugin",
46
+ "tarPlugin",
47
+ "tohtml",
48
+ "tutor",
49
+ "zipPlugin",
50
+ },
51
+ },
52
+ },
53
+ })
@@ -0,0 +1,3 @@
1
+ -- Options are automatically loaded before lazy.nvim startup
2
+ -- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua
3
+ -- Add any additional options here
@@ -0,0 +1,9 @@
1
+ -- Inline image viewing (kitty graphics protocol — works in Ghostty, tmux passthrough enabled)
2
+ return {
3
+ {
4
+ "folke/snacks.nvim",
5
+ opts = {
6
+ image = { enabled = true },
7
+ },
8
+ },
9
+ }
@@ -0,0 +1,56 @@
1
+ -- Markdown: formatter (prettier) + in-buffer renderer (visualizer)
2
+ return {
3
+ -- Browser preview: live rendered page, auto-reloads on save/type
4
+ {
5
+ "iamcco/markdown-preview.nvim",
6
+ cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" },
7
+ ft = { "markdown" },
8
+ build = function()
9
+ vim.fn["mkdp#util#install"]()
10
+ end,
11
+ keys = {
12
+ { "<leader>cp", "<cmd>MarkdownPreviewToggle<cr>", ft = "markdown", desc = "Markdown Preview (browser)" },
13
+ },
14
+ config = function()
15
+ vim.cmd([[do FileType]])
16
+ end,
17
+ },
18
+
19
+ -- Visualizer: renders headings, tables, checkboxes, code blocks in buffer
20
+ {
21
+ "MeanderingProgrammer/render-markdown.nvim",
22
+ ft = { "markdown" },
23
+ dependencies = { "nvim-treesitter/nvim-treesitter", "nvim-tree/nvim-web-devicons" },
24
+ keys = {
25
+ { "<leader>um", "<cmd>RenderMarkdown toggle<cr>", ft = "markdown", desc = "Toggle Markdown render (in-buffer)" },
26
+ },
27
+ opts = {
28
+ enabled = false, -- OFF by default. Toggle: <leader>um
29
+ },
30
+ },
31
+
32
+ -- Formatter: prettier for markdown via conform (LazyVim core)
33
+ {
34
+ "stevearc/conform.nvim",
35
+ opts = {
36
+ formatters_by_ft = {
37
+ markdown = { "prettier" },
38
+ ["markdown.mdx"] = { "prettier" },
39
+ },
40
+ },
41
+ },
42
+
43
+ -- Make sure prettier binary + markdown treesitter parsers exist
44
+ {
45
+ "mason-org/mason.nvim",
46
+ opts = {
47
+ ensure_installed = { "prettier", "markdownlint-cli2", "marksman" },
48
+ },
49
+ },
50
+ {
51
+ "nvim-treesitter/nvim-treesitter",
52
+ opts = {
53
+ ensure_installed = { "markdown", "markdown_inline" },
54
+ },
55
+ },
56
+ }