Audit and optimize for CapableMind development

Brewfile: stripped to essential tools (~600MB freed), removed boost,
cmake, aerc, newsboat, fontforge, starship, and 24 auto-dependencies.
Added caffeine, ollama, fastfetch, ocrmypdf, tea, sshpass, vitetris.
Dropped 1password, iterm2, github-desktop, hazel, swiftbar, oversight.

Shell: fixed all stale references (fzf, zoxide, starship, old paths,
Homebrew node aliases). Updated project paths to ~/_Dev/. Added
CapableMind aliases (cm, bmf, bmf-health, bmf-status, bmf-logs).

Configs: removed iterm2, neofetch, swiftbar configs. Added capablemind
(launchd plists, MCP example, bmf-start script). Updated SSH config
with git.skemantix.com. Added CLAUDE.md to dotfiles.

Scripts: consolidated 3 backup scripts into 1 (backup-all-secrets.sh),
added pass store backup. Added setup-capablemind.sh for full environment
reconstruction. Updated symlinks.sh for new config structure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
David F Glidden
2026-03-20 23:45:33 +01:00
co-authored by Claude Opus 4.6
parent e7bb361bd2
commit 066a47a26b
72 changed files with 785 additions and 2032 deletions
+41 -72
View File
@@ -1,5 +1,5 @@
# Brewfile - Curated list for fresh macOS setup
# Comment out lines for apps you don't want installed
# Brewfile - Optimized for CapableMind development, research, and ARC publishing
# Last updated: 2026-03-20
# Taps
tap "homebrew/cask"
@@ -10,16 +10,13 @@ tap "homebrew/cask-fonts"
# ============================================
brew "antidote" # ZSH plugin manager
brew "powerlevel10k" # ZSH theme
brew "fzf" # Fuzzy finder
brew "zoxide" # Smarter cd command
brew "direnv" # Per-directory environment variables
brew "tmux" # Terminal multiplexer
# ============================================
# ESSENTIAL CLI TOOLS
# ============================================
brew "mas" # Mac App Store CLI
brew "git" # Version control
brew "git-lfs" # Git large file storage
brew "wget" # Download files
brew "tree" # Directory visualization
brew "coreutils" # GNU core utilities
@@ -28,58 +25,55 @@ brew "jq" # JSON processor
brew "ripgrep" # Fast grep alternative (rg)
brew "fd" # Fast find alternative
brew "bat" # Better cat with syntax highlighting
brew "tldr" # Simplified man pages
brew "httpie" # Modern curl alternative
brew "tealdeer" # Simplified man pages (tldr)
# ============================================
# DEVELOPMENT TOOLS
# DEVELOPMENT
# ============================================
# brew "node" # Node.js (you use nvm instead)
brew "python@3.12" # Python (for proselint dependency)
brew "python@3.13" # Python (latest)
brew "pipx" # Install Python apps in isolated envs
# Node.js managed via nvm, not Homebrew
brew "python@3.13" # Python
brew "pandoc" # Document converter
brew "multimarkdown" # Enhanced markdown processor
brew "gh" # GitHub CLI
brew "proselint" # Prose linter
# Future: custom AldineXXI prose linter (replaces proselint)
# Text editors & IDEs
cask "iterm2" # Terminal emulator
# ============================================
# CAPABLEMIND / AI
# ============================================
cask "ollama" # Local LLMs + embedding models
brew "gnupg" # GPG encryption (dependency for pass)
brew "pass" # Password store
# ============================================
# TERMINAL & EDITORS
# ============================================
cask "kitty" # GPU-accelerated terminal
cask "bbedit" # Text editor
# Version control
cask "github" # GitHub Desktop
# ============================================
# PRODUCTIVITY & ESSENTIAL APPS
# PRODUCTIVITY
# ============================================
cask "1password" # Password manager
cask "obsidian" # Knowledge base
cask "marked" # Markdown preview (Marked 2)
cask "launchbar" # Application launcher
# Communication
cask "signal" # Encrypted messaging
# cask "telegram" # Messaging
# ============================================
# UTILITIES
# ============================================
cask "karabiner-elements" # Keyboard customization
cask "hazel" # Automated organization
cask "keka" # Archive utility
cask "appcleaner" # Uninstall apps cleanly
cask "appcleaner" # Uninstall apps cleanly (no background daemon)
cask "bartender" # Menu bar organization
cask "swiftbar" # Menu bar scripts
cask "soundsource" # Audio control
cask "caffeine" # Prevent sleep
cask "vuescan" # Scanner software
# ============================================
# MEDIA & CREATIVE
# MEDIA
# ============================================
brew "ffmpeg" # Media processing
brew "yt-dlp" # YouTube downloader (active fork)
brew "yt-dlp" # YouTube downloader
brew "exiftool" # Read/write EXIF metadata
cask "vlc" # Media player
cask "handbrake" # Video transcoder
@@ -87,87 +81,62 @@ cask "xld" # Audio converter
cask "transmission" # BitTorrent client
# ============================================
# OPTIONAL/SPECIFIC USE
# SECURITY & TRANSFER
# ============================================
# Research & Reading
cask "calibre" # E-book management
# cask "zotero" # Reference management
# cask "anki" # Spaced repetition
# Development & Transfer
# cask "docker" # Containerization
cask "gpg-suite" # GPG keychain and tools
cask "transmit" # FTP/SFTP client
# Security/Privacy
# cask "tunnelblick" # OpenVPN client
cask "gpg-suite" # GPG encryption
# cask "lulu" # Firewall
cask "oversight" # Webcam/mic monitor
# Other tools
brew "neofetch" # System info display
# ============================================
# OTHER TOOLS
# ============================================
brew "fastfetch" # System info display (replaced neofetch)
brew "qrencode" # Generate QR codes
brew "ocrmypdf" # OCR for PDFs
brew "tesseract" # OCR engine (ocrmypdf dependency)
brew "mackup" # Backup/sync app preferences
brew "pass" # Password store (for GPG)
cask "ollama" # Local LLMs
brew "tea" # Gitea CLI
brew "sshpass" # SSH password automation (clasp access)
brew "vitetris" # Tetris
# ============================================
# FONTS
# ============================================
cask "font-hack-nerd-font" # Programming font with icons
# cask "font-fira-code-nerd-font" # Ligatures + icons
# cask "font-jetbrains-mono-nerd-font" # JetBrains + icons
# cask "font-meslo-lg-nerd-font" # Powerline + icons
# cask "font-source-code-pro-nerd-font" # Adobe Source Code Pro + icons
cask "font-hack-nerd-font" # Programming font with icons (powerlevel10k)
# ============================================
# MAC APP STORE APPS
# MAC APP STORE
# ============================================
# Productivity
mas "Drafts", id: 1435957248
mas "iA Writer", id: 775737590
mas "Numbers", id: 409203825
mas "Pages", id: 409201541
mas "PCalc", id: 403504866
# Communication
mas "WhatsApp", id: 1147396723
# Safari Extensions
mas "1Password for Safari", id: 1569813296
mas "AdGuard for Safari", id: 1440147259
mas "Kagi Search", id: 1622835804
mas "Dark Reader for Safari", id: 1438243180
mas "Hush", id: 1544743900
mas "Vinegar", id: 1591303229
mas "StopTheMadness Pro", id: 6471380298
mas "Super Agent", id: 1568262835
# Reading & Research
mas "Reeder.", id: 1529448980
mas "Klib", id: 1196268448
mas "forScore", id: 363738376
mas "Obsidian Web Clipper", id: 6720708363
# Utilities
mas "LocalSend", id: 1661733229
mas "NordVPN", id: 905953485
mas "Table Tool", id: 1122008420
mas "xSearch", id: 1579902068
mas "Exporter", id: 1099120373
mas "Mapper", id: 1589391989
mas "Moon Pro", id: 1528941870
# Privacy/Security
mas "Orbot", id: 1609461599
# Optional (commented out)
# mas "Fantastical", id: 975937182
# mas "Keynote", id: 409183694
# mas "Dark Reader for Safari", id: 1438243180
# ============================================
# APPS TO INSTALL MANUALLY
# ============================================
# These don't have casks or require special handling:
# - Claude
# - ChatGPT
# - Dorico 5 (Steinberg)
# - Some audio production apps
# - Claude (Anthropic)
# - Dorico 5 (Steinberg — music engraving)
+94
View File
@@ -0,0 +1,94 @@
# CLAUDE.md — Global
## Prime Directive
> _Do things once, correctly, with lasting integrity._
> _Choose what is proportionate, fitting, and durable._
> _Build what you will not need to rebuild._
> **μέτρον γὰρ καὶ συμμετρία καὶ τὸ πρόσφορον πανταχοῦ καλόν τε καὶ ἀγαθόν παρέχει**
> "Measure, proportion, and what is fitting give rise to beauty and goodness everywhere."
This is the decision filter for all work. When choosing between approaches: favor durability over expedience, clarity over cleverness, fittingness over uniformity. Every commit should leave the system inhabitable — not dependent on the next step to be meaningful.
---
## Identity & Context
- **David Glidden**: principal violist (Le Concert des Nations / Jordi Savall; Les Musiciens du Louvre / Marc Minkowski), based in Barcelona
- Languages: English (native), French (near-native), Spanish, Catalan
- Founder of **Animal Rationis Capax (ARC)** — a public writing and publishing platform
- Co-founder and principal architect of **CapableMind** — ethically governed AI systems (L1 memory / L2 constitutional governance)
- Father of Lune and Kai. Fatherhood and intergenerational stewardship are central to all domains of work
---
## Collaboration Model
Claude operates as **deliberative partner**, not execution engine. This means:
### Governed Initiative
- **Propose** paths, tools, approaches, and alternatives — do not wait to be asked
- **Flag** tensions, risks, drift, and architectural consequences of choices
- **Surface** findings for human authorization before they become action
- **Hold** open questions as open questions — do not resolve prematurely
- The boundary: initiative surfaces as *proposal*; only the human converts proposal to *action*
### Epistemic Discipline
- Make assumptions visible. State confidence and scope explicitly
- Distinguish between exploration, proposal, and settled decision
- When uncertain, say what is uncertain and why
- Resist premature closure — premature synthesis is a failure mode, not efficiency
- If a maxim or principle becomes decorative rather than load-bearing, flag it
### Communication
- Begin concise; deepen with structure when warranted
- No flattery, motivational padding, or false reassurance
- Preserve necessary ambiguity — do not false-clarify
- Ask clarifying questions only when they materially improve rigor
---
## Working Discipline
### Context Rot Prevention
- **One canonical source of truth** per document. No parallel versions
- **No silent edits** — log what changed and why
- **Integrity links** — when modifying documents, maintain or update cross-references
- **Review cadence** — flag documents that have drifted from their stated review dates
### Session Discipline
- Prefer durable architecture over clever solutions
- When multiple approaches exist, name them with tradeoffs before proceeding
- If a task would benefit from a tool, library, or approach not yet discussed, say so
- Front-load critical context; avoid redundant re-establishment across sessions
- If session state is growing large, flag it early rather than losing coherence silently
### Non-Convergence Principle
- The system should be inhabitable, dignified, and sufficient at any point along the way
- No step should create a dependency on a future step to be meaningful
- Each unit of work should be complete in itself
---
## Decision Heuristics
When evaluating a choice, apply in order:
1. **Fittingness** (τὸ πρόσφορον) — Is this proportionate to circumstance, season, energy, and context?
2. **Durability** — Will this hold under pressure, or does it create hidden costs?
3. **Inheritability** — Could someone else (collaborator, future self, Lune, Kai) follow this thread without confusion?
4. **Correction posture** — If this turns out wrong, how easily can it be corrected? Prefer reversible choices
---
## Active Projects
| Project | Path | Notes |
|---------|------|-------|
| **CapableMind L1/L2** | `~/_Dev/CapableMind-AI` | Constitutional governance system. Read local CLAUDE.md for build state |
| **Animal Rationis Capax** | `~/_Dev/animal-davidglidden-eu` | Hakyll publishing system. Read local CLAUDE.md for technical context |
| **Compass** | `'/Users/davidglidden/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/00. Compass'` | Personal operating system (Obsidian vault). Read-only reference |
| **Dotfiles** | `~/dotfiles` | Dotfiles for easy restore and setup |
When navigating into a project directory, always read its local CLAUDE.md first for current state, build sequences, and terminology.
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# BMF (BetterMemories) launch script for launchd
# Pulls ANTHROPIC_API_KEY from macOS keychain, starts BMF with teacher in API mode.
set -euo pipefail
export HOME="/Users/davidglidden"
export PATH="/Users/davidglidden/.nvm/versions/node/v22.16.0/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
# Pull API key from env file
set -a
source /Users/davidglidden/.capablemind/env
set +a
# BMF config
export BM_PORT="3011"
export BM_TEACHER_TRANSPORT="api"
export BMF_MCP_TOKEN="bm_key_REDACTED"
# Ollama needs to be reachable
export OLLAMA_HOST="${OLLAMA_HOST:-http://127.0.0.1:11434}"
cd /Users/davidglidden/_Dev/BetterMemories.io
exec node dist/index.js
+8
View File
@@ -0,0 +1,8 @@
#!/bin/zsh
# Mirror CapableMind thinking/David/ to Obsidian vault
# Excludes CLAUDE.md (repo-specific, not for vault)
SOURCE="$HOME/_Dev/CapableMind-AI/docs/thinking/David/"
DEST="$HOME/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/00. Compass/00b. Constellations/CapableMind/thinking-mirror/"
rsync -av --delete --exclude='CLAUDE.md' "$SOURCE" "$DEST" > /dev/null 2>&1
+14
View File
@@ -0,0 +1,14 @@
# Git internals (never mirror a .git from anywhere)
.git/
# OS cruft
.DS_Store
Thumbs.db
# Obsidian volatile state
.obsidian/workspace.json
.obsidian/workspace-mobile.json
.obsidian/plugins/obsidian-git/data.json
.obsidian/cache/
# Optional: ignore huge/unneeded subtrees on the mirror
# attachments/raw_video/
# attachments/raw_audio/
# node_modules/ # if you keep code inside the vault
+92
View File
@@ -0,0 +1,92 @@
#!/usr/bin/env bash
set -euo pipefail
########################################
# CONFIG — EDIT THESE 4 LINES
########################################
VAULT_PATH="/Users/davidglidden/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch"
MIRROR_PATH="/Users/davidglidden/_Dev/david-root-and-branch-vault-git"
GIT_REMOTE="https://git.skemantix.com/David/david-root-and-branch-vault-git.git"
GIT_BRANCH="main"
# Optional: set your git identity here (comment out if already global)
# GIT_NAME="David Glidden"
# GIT_EMAIL="you@example.com"
# Excludes file lives alongside this script
EXCLUDES_FILE="$(dirname "$0")/obsidian_rsync_excludes.txt"
LOG_FILE="${HOME}/Library/Logs/vaultsync.log"
########################################
timestamp() { date "+%Y-%m-%d %H:%M:%S"; }
log() { printf "[%s] %s\n" "$(timestamp)" "$*" | tee -a "$LOG_FILE"; }
ensure_paths() {
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$MIRROR_PATH"
}
# Guard: skip if iCloud still downloading placeholders (*.icloud)
icloud_busy() {
# Any placeholder files inside vault?
# NOTE: adjust -prune if you want to skip very large folders from scanning
if find "$VAULT_PATH" -type f -name "*.icloud" -print -quit | grep -q . ; then
return 0
else
return 1
fi
}
init_git_repo() {
if [ ! -d "$MIRROR_PATH/.git" ]; then
log "Initializing git repo in $MIRROR_PATH"
git init "$MIRROR_PATH"
git -C "$MIRROR_PATH" checkout -b "$GIT_BRANCH" || true
git -C "$MIRROR_PATH" remote add origin "$GIT_REMOTE" || true
git -C "$MIRROR_PATH" config user.name "$GIT_NAME" || true
git -C "$MIRROR_PATH" config user.email "$GIT_EMAIL" || true
fi
}
do_rsync() {
log "Syncing from iCloud vault → mirror"
rsync -av --delete \
--exclude-from="$EXCLUDES_FILE" \
"$VAULT_PATH"/ "$MIRROR_PATH"/ | tee -a "$LOG_FILE"
}
do_commit_push() {
log "Checking for changes to commit"
if ! git -C "$MIRROR_PATH" diff --quiet || \
! git -C "$MIRROR_PATH" diff --cached --quiet || \
[ -n "$(git -C "$MIRROR_PATH" ls-files --others --exclude-standard)" ]; then
git -C "$MIRROR_PATH" add -A
git -C "$MIRROR_PATH" commit -m "Mirror sync $(date +%Y-%m-%d_%H-%M-%S)" --no-verify
log "Committed changes"
# Push; if first push, set upstream
if git -C "$MIRROR_PATH" rev-parse --verify "$GIT_BRANCH" >/dev/null 2>&1; then
git -C "$MIRROR_PATH" push origin "$GIT_BRANCH" || log "Push failed (network?). Will retry next run."
else
git -C "$MIRROR_PATH" push -u origin "$GIT_BRANCH" || log "First push failed. Check remote."
fi
else
log "No changes to commit"
fi
}
main() {
ensure_paths
if icloud_busy; then
log "iCloud still downloading placeholders (*.icloud). Skipping this run."
exit 0
fi
init_git_repo
do_rsync
do_commit_push
log "Done."
}
main "$@"
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.capablemind.bettermemories</string>
<key>ProgramArguments</key>
<array>
<string>/Users/davidglidden/.nvm/versions/node/v22.16.0/bin/node</string>
<string>/Users/davidglidden/_Dev/BetterMemories.io/dist/index.js</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/davidglidden/_Dev/BetterMemories.io</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>ThrottleInterval</key>
<integer>10</integer>
<key>StandardOutPath</key>
<string>/Users/davidglidden/.capablemind/logs/bmf.stdout.log</string>
<key>StandardErrorPath</key>
<string>/Users/davidglidden/.capablemind/logs/bmf.stderr.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>BM_PORT</key>
<string>3011</string>
<key>BM_DEPLOYMENT_MODEL</key>
<string>standalone</string>
<key>BMF_MCP_TOKEN</key>
<string>bm_key_7feb421ef8fd45e8</string>
<key>PATH</key>
<string>/Users/davidglidden/.nvm/versions/node/v22.16.0/bin:/usr/local/bin:/usr/bin:/bin</string>
</dict>
</dict>
</plist>
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.capablemind.bmf</string>
<key>ProgramArguments</key>
<array>
<string>/Users/davidglidden/bin/bmf-start.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>10</integer>
<key>StandardOutPath</key>
<string>/Users/davidglidden/.capablemind/logs/bmf.stdout.log</string>
<key>StandardErrorPath</key>
<string>/Users/davidglidden/.capablemind/logs/bmf.stderr.log</string>
<key>WorkingDirectory</key>
<string>/Users/davidglidden/_Dev/BetterMemories.io</string>
</dict>
</plist>
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.dglidden.thinking-mirror</string>
<key>ProgramArguments</key>
<array>
<string>/Users/davidglidden/bin/capablemind-thinking-mirror.sh</string>
</array>
<key>StartInterval</key>
<integer>172800</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/davidglidden/.capablemind/logs/thinking-mirror.log</string>
<key>StandardErrorPath</key>
<string>/Users/davidglidden/.capablemind/logs/thinking-mirror.log</string>
</dict>
</plist>
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.dglidden.vaultsync</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-lc</string>
<string>~/bin/obsidian_vault_sync.sh</string>
</array>
<!-- Run every 30 minutes -->
<key>StartInterval</key>
<integer>1800</integer>
<!-- Also run once shortly after login -->
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/davidglidden/Library/Logs/vaultsync.log</string>
<key>StandardErrorPath</key>
<string>/Users/davidglidden/Library/Logs/vaultsync.log</string>
</dict>
</plist>
+17
View File
@@ -0,0 +1,17 @@
{
"mcpServers": {
"capablemind": {
"command": "node",
"args": ["/Users/davidglidden/_Dev/BetterMemories.io/dist/index.js"],
"cwd": "/Users/davidglidden/_Dev/BetterMemories.io",
"env": {
"BM_MCP_STDIO": "true",
"BM_PORT": "3011",
"BM_TEACHER_TRANSPORT": "api",
"BMF_MCP_TOKEN": "bm_key_REDACTED",
"BM_PYTHON_PATH": "/Users/davidglidden/_Dev/BetterMemories.io/.venv/bin/python3",
"BM_MELD_URL": "http://10.0.1.10:3011"
}
}
}
}
@@ -1,2 +0,0 @@
2f55736572732f6461766964676c696464656e2f4c6962726172792f4170706c69636174696f6e20537570706f72742f695465726d322f456e61626c6541492e73656375726553657474696e67 0975c0e7440a897bbddeb6c6945a2eb9bcdecaaa4840bebc3955dd9a3df359bb
74727565
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
3.5.14
-344
View File
@@ -1,344 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Ansi 0 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.32156863808631897</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.25882354378700256</real>
<key>Red Component</key>
<real>0.23137255012989044</real>
</dict>
<key>Ansi 1 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.41568627953529358</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.38039216399192810</real>
<key>Red Component</key>
<real>0.74901962280273438</real>
</dict>
<key>Ansi 10 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.54901963472366333</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.74509805440902710</real>
<key>Red Component</key>
<real>0.63921570777893066</real>
</dict>
<key>Ansi 11 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.54509806632995605</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.79607844352722168</real>
<key>Red Component</key>
<real>0.92156863212585449</real>
</dict>
<key>Ansi 12 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.75686275959014893</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.63137257099151611</real>
<key>Red Component</key>
<real>0.50588238239288330</real>
</dict>
<key>Ansi 13 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.67843139171600342</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.55686277151107788</real>
<key>Red Component</key>
<real>0.70588237047195435</real>
</dict>
<key>Ansi 14 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.73333334922790527</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.73725491762161255</real>
<key>Red Component</key>
<real>0.56078433990478516</real>
</dict>
<key>Ansi 15 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.95686274766921997</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.93725490570068359</real>
<key>Red Component</key>
<real>0.92549020051956177</real>
</dict>
<key>Ansi 2 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.54901963472366333</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.74509805440902710</real>
<key>Red Component</key>
<real>0.63921570777893066</real>
</dict>
<key>Ansi 3 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.54509806632995605</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.79607844352722168</real>
<key>Red Component</key>
<real>0.92156863212585449</real>
</dict>
<key>Ansi 4 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.75686275959014893</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.63137257099151611</real>
<key>Red Component</key>
<real>0.50588238239288330</real>
</dict>
<key>Ansi 5 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.67843139171600342</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.55686277151107788</real>
<key>Red Component</key>
<real>0.70588237047195435</real>
</dict>
<key>Ansi 6 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.81568628549575806</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.75294119119644165</real>
<key>Red Component</key>
<real>0.53333336114883423</real>
</dict>
<key>Ansi 7 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.94117647409439087</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.91372549533843994</real>
<key>Red Component</key>
<real>0.89803922176361084</real>
</dict>
<key>Ansi 8 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.41568627953529358</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.33725491166114807</real>
<key>Red Component</key>
<real>0.29803922772407532</real>
</dict>
<key>Ansi 9 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.41568627953529358</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.38039216399192810</real>
<key>Red Component</key>
<real>0.74901962280273438</real>
</dict>
<key>Background Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.25098040699958801</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.20392157137393951</real>
<key>Red Component</key>
<real>0.18039216101169586</real>
</dict>
<key>Badge Color</key>
<dict>
<key>Alpha Component</key>
<real>0.5</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.1491314172744751</real>
<key>Red Component</key>
<real>1</real>
</dict>
<key>Bold Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.91372549533843994</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.87058824300765991</real>
<key>Red Component</key>
<real>0.84705883264541626</real>
</dict>
<key>Cursor Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.91372549533843994</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.87058824300765991</real>
<key>Red Component</key>
<real>0.84705883264541626</real>
</dict>
<key>Cursor Guide Color</key>
<dict>
<key>Alpha Component</key>
<real>0.25</real>
<key>Blue Component</key>
<real>1</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.9268307089805603</real>
<key>Red Component</key>
<real>0.70213186740875244</real>
</dict>
<key>Cursor Text Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.25098040699958801</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.20392157137393951</real>
<key>Red Component</key>
<real>0.18039216101169586</real>
</dict>
<key>Foreground Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.91372549533843994</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.87058824300765991</real>
<key>Red Component</key>
<real>0.84705883264541626</real>
</dict>
<key>Link Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.73423302173614502</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.35916060209274292</real>
<key>Red Component</key>
<real>0.0</real>
</dict>
<key>Selected Text Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.25098040699958801</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.20392157137393951</real>
<key>Red Component</key>
<real>0.18039216101169586</real>
</dict>
<key>Selection Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.81568628549575806</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.75294119119644165</real>
<key>Red Component</key>
<real>0.53333336114883423</real>
</dict>
</dict>
</plist>
-99
View File
@@ -1,99 +0,0 @@
# iTerm2 Configuration
This directory contains iTerm2 configuration to match the Kitty terminal setup with Nord theme.
## Quick Setup
1. **Import Nord Color Scheme**:
```bash
# Run the setup script
~/dotfiles/config/iterm2/setup-iterm.sh
```
2. **Manual Color Import**:
- Open iTerm2
- Press `Cmd+,` to open Preferences
- Go to **Profiles → Colors**
- Click **Color Presets...** dropdown
- Select **Import...**
- Navigate to `~/dotfiles/config/iterm2/Nord.itermcolors`
- Select **Nord** from the Color Presets dropdown
## Matching Settings with Kitty
The following settings match your Kitty configuration:
### Font Configuration
- **Font**: Iosevka Term SS08 (or Dank Mono if you prefer)
- **Size**: 16pt
- **Ligatures**: Enabled
- **Non-ASCII Font**: Fira Code Nerd Font (for symbols)
### Window Settings
- **Default Size**: 120 columns × 35 rows
- **Transparency**: 8% (equivalent to Kitty's 0.92 opacity)
- **Blur**: Optional, helps with readability
### Behavior
- **Scrollback**: 10,000 lines
- **Copy on Selection**: Enabled
- **Visual Bell**: Enabled (no audio bell)
- **Cursor**: Block, blinking
## Manual Configuration
If you prefer to configure manually:
1. **Font**:
- Profiles → Text → Font → Change Font
- Select "Iosevka Term SS08" or "Dank Mono", Size 16
2. **Colors**:
- Already handled by importing Nord.itermcolors
3. **Window**:
- Profiles → Window → Settings for New Windows
- Columns: 120, Rows: 35
- Transparency: Drag slider to ~8%
4. **Terminal**:
- Profiles → Terminal → Scrollback Buffer
- Set to 10,000 lines
5. **Keys**:
- Profiles → Keys → Key Mappings
- Add shortcuts as needed to match Kitty
## Keyboard Shortcuts
To match Kitty's shortcuts in iTerm2:
| Action | Kitty | iTerm2 Setup |
|--------|-------|--------------|
| New Tab | `Cmd+T` | Default |
| Close Tab | `Cmd+W` | Default |
| Next Tab | `Cmd+]` | Default |
| Previous Tab | `Cmd+[` | Default |
| Font Size + | `Cmd+Plus` | Preferences → Keys → + |
| Font Size - | `Cmd+Minus` | Preferences → Keys → + |
| Font Size Reset | `Cmd+0` | Preferences → Keys → + |
## Saving Your Configuration
To save your iTerm2 configuration to dotfiles:
1. Open Preferences (`Cmd+,`)
2. Go to **General → Preferences**
3. Click **Load preferences from a custom folder**
4. Select `~/dotfiles/config/iterm2`
5. Check **Save changes to folder when iTerm2 quits**
This ensures your iTerm2 settings are backed up with your dotfiles.
## Nord Theme Benefits
The Nord color scheme is specifically chosen for:
- **Reduced eye strain** with muted colors
- **Excellent contrast** without being harsh
- **Better readability** for users with vision considerations
- **Consistent appearance** across Kitty and iTerm2
-64
View File
@@ -1,64 +0,0 @@
#!/usr/bin/env bash
# Setup iTerm2 with Nord theme and matching Kitty settings
set -euo pipefail
DOTFILES_DIR="$HOME/dotfiles"
ITERM_CONFIG_DIR="$DOTFILES_DIR/config/iterm2"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}Setting up iTerm2 configuration...${NC}"
# 1. Tell iTerm2 to use custom preferences folder
echo -e "${YELLOW}Configuring iTerm2 to use dotfiles preferences...${NC}"
defaults write com.googlecode.iterm2 PrefsCustomFolder -string "$ITERM_CONFIG_DIR"
defaults write com.googlecode.iterm2 LoadPrefsFromCustomFolder -bool true
# 2. Set specific preferences matching Kitty config
echo -e "${YELLOW}Setting iTerm2 preferences to match Kitty...${NC}"
# Font settings (Iosevka Term SS08, 16pt - matching Kitty)
defaults write com.googlecode.iterm2 "Normal Font" -string "IosevkaTermSS08-Regular 16"
defaults write com.googlecode.iterm2 "Non Ascii Font" -string "FiraCodeNerdFontComplete-Regular 16"
# Enable ligatures
defaults write com.googlecode.iterm2 "ASCII Ligatures" -bool true
# Window size (120x35 characters)
defaults write com.googlecode.iterm2 "Columns" -int 120
defaults write com.googlecode.iterm2 "Rows" -int 35
# Transparency (matching Kitty's 0.92 opacity = 8% transparency)
defaults write com.googlecode.iterm2 "Transparency" -float 0.08
# Scrollback lines (10000)
defaults write com.googlecode.iterm2 "Scrollback Lines" -int 10000
# Visual bell instead of audio
defaults write com.googlecode.iterm2 "Silence Bell" -bool false
defaults write com.googlecode.iterm2 "Visual Bell" -bool true
# Copy on selection
defaults write com.googlecode.iterm2 "Copy to Pasteboard on Selection" -bool true
# Cursor settings
defaults write com.googlecode.iterm2 "Cursor Type" -int 0 # Block cursor
defaults write com.googlecode.iterm2 "Blinking Cursor" -bool true
echo -e "${GREEN}✅ iTerm2 preferences configured${NC}"
echo ""
echo -e "${YELLOW}To complete the setup:${NC}"
echo "1. Open iTerm2"
echo "2. Go to Preferences > Profiles > Colors"
echo "3. Click 'Color Presets...' dropdown"
echo "4. Select 'Import...' and choose: $ITERM_CONFIG_DIR/Nord.itermcolors"
echo "5. Select 'Nord' from the Color Presets dropdown"
echo ""
echo "Optional: Export your full iTerm2 config:"
echo " Preferences > General > Preferences"
echo " Click 'Save settings to Folder' and choose: $ITERM_CONFIG_DIR"
-864
View File
@@ -1,864 +0,0 @@
# See this wiki page for more info:
# https://github.com/dylanaraps/neofetch/wiki/Customizing-Info
print_info() {
info title
info underline
info "OS" distro
info "Host" model
info "Kernel" kernel
info "Uptime" uptime
info "Packages" packages
info "Shell" shell
info "Resolution" resolution
info "DE" de
info "WM" wm
info "WM Theme" wm_theme
info "Theme" theme
info "Icons" icons
info "Terminal" term
info "Terminal Font" term_font
info "CPU" cpu
info "GPU" gpu
info "Memory" memory
# info "GPU Driver" gpu_driver # Linux/macOS only
# info "CPU Usage" cpu_usage
# info "Disk" disk
# info "Battery" battery
# info "Font" font
# info "Song" song
# [[ "$player" ]] && prin "Music Player" "$player"
# info "Local IP" local_ip
# info "Public IP" public_ip
# info "Users" users
# info "Locale" locale # This only works on glibc systems.
info cols
}
# Title
# Hide/Show Fully qualified domain name.
#
# Default: 'off'
# Values: 'on', 'off'
# Flag: --title_fqdn
title_fqdn="off"
# Kernel
# Shorten the output of the kernel function.
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --kernel_shorthand
# Supports: Everything except *BSDs (except PacBSD and PC-BSD)
#
# Example:
# on: '4.8.9-1-ARCH'
# off: 'Linux 4.8.9-1-ARCH'
kernel_shorthand="on"
# Distro
# Shorten the output of the distro function
#
# Default: 'off'
# Values: 'on', 'tiny', 'off'
# Flag: --distro_shorthand
# Supports: Everything except Windows and Haiku
distro_shorthand="off"
# Show/Hide OS Architecture.
# Show 'x86_64', 'x86' and etc in 'Distro:' output.
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --os_arch
#
# Example:
# on: 'Arch Linux x86_64'
# off: 'Arch Linux'
os_arch="on"
# Uptime
# Shorten the output of the uptime function
#
# Default: 'on'
# Values: 'on', 'tiny', 'off'
# Flag: --uptime_shorthand
#
# Example:
# on: '2 days, 10 hours, 3 mins'
# tiny: '2d 10h 3m'
# off: '2 days, 10 hours, 3 minutes'
uptime_shorthand="on"
# Memory
# Show memory pecentage in output.
#
# Default: 'off'
# Values: 'on', 'off'
# Flag: --memory_percent
#
# Example:
# on: '1801MiB / 7881MiB (22%)'
# off: '1801MiB / 7881MiB'
memory_percent="off"
# Change memory output unit.
#
# Default: 'mib'
# Values: 'kib', 'mib', 'gib'
# Flag: --memory_unit
#
# Example:
# kib '1020928KiB / 7117824KiB'
# mib '1042MiB / 6951MiB'
# gib: ' 0.98GiB / 6.79GiB'
memory_unit="mib"
# Packages
# Show/Hide Package Manager names.
#
# Default: 'tiny'
# Values: 'on', 'tiny' 'off'
# Flag: --package_managers
#
# Example:
# on: '998 (pacman), 8 (flatpak), 4 (snap)'
# tiny: '908 (pacman, flatpak, snap)'
# off: '908'
package_managers="on"
# Shell
# Show the path to $SHELL
#
# Default: 'off'
# Values: 'on', 'off'
# Flag: --shell_path
#
# Example:
# on: '/bin/bash'
# off: 'bash'
shell_path="off"
# Show $SHELL version
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --shell_version
#
# Example:
# on: 'bash 4.4.5'
# off: 'bash'
shell_version="on"
# CPU
# CPU speed type
#
# Default: 'bios_limit'
# Values: 'scaling_cur_freq', 'scaling_min_freq', 'scaling_max_freq', 'bios_limit'.
# Flag: --speed_type
# Supports: Linux with 'cpufreq'
# NOTE: Any file in '/sys/devices/system/cpu/cpu0/cpufreq' can be used as a value.
speed_type="bios_limit"
# CPU speed shorthand
#
# Default: 'off'
# Values: 'on', 'off'.
# Flag: --speed_shorthand
# NOTE: This flag is not supported in systems with CPU speed less than 1 GHz
#
# Example:
# on: 'i7-6500U (4) @ 3.1GHz'
# off: 'i7-6500U (4) @ 3.100GHz'
speed_shorthand="off"
# Enable/Disable CPU brand in output.
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --cpu_brand
#
# Example:
# on: 'Intel i7-6500U'
# off: 'i7-6500U (4)'
cpu_brand="on"
# CPU Speed
# Hide/Show CPU speed.
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --cpu_speed
#
# Example:
# on: 'Intel i7-6500U (4) @ 3.1GHz'
# off: 'Intel i7-6500U (4)'
cpu_speed="on"
# CPU Cores
# Display CPU cores in output
#
# Default: 'logical'
# Values: 'logical', 'physical', 'off'
# Flag: --cpu_cores
# Support: 'physical' doesn't work on BSD.
#
# Example:
# logical: 'Intel i7-6500U (4) @ 3.1GHz' (All virtual cores)
# physical: 'Intel i7-6500U (2) @ 3.1GHz' (All physical cores)
# off: 'Intel i7-6500U @ 3.1GHz'
cpu_cores="logical"
# CPU Temperature
# Hide/Show CPU temperature.
# Note the temperature is added to the regular CPU function.
#
# Default: 'off'
# Values: 'C', 'F', 'off'
# Flag: --cpu_temp
# Supports: Linux, BSD
# NOTE: For FreeBSD and NetBSD-based systems, you'll need to enable
# coretemp kernel module. This only supports newer Intel processors.
#
# Example:
# C: 'Intel i7-6500U (4) @ 3.1GHz [27.2°C]'
# F: 'Intel i7-6500U (4) @ 3.1GHz [82.0°F]'
# off: 'Intel i7-6500U (4) @ 3.1GHz'
cpu_temp="off"
# GPU
# Enable/Disable GPU Brand
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --gpu_brand
#
# Example:
# on: 'AMD HD 7950'
# off: 'HD 7950'
gpu_brand="on"
# Which GPU to display
#
# Default: 'all'
# Values: 'all', 'dedicated', 'integrated'
# Flag: --gpu_type
# Supports: Linux
#
# Example:
# all:
# GPU1: AMD HD 7950
# GPU2: Intel Integrated Graphics
#
# dedicated:
# GPU1: AMD HD 7950
#
# integrated:
# GPU1: Intel Integrated Graphics
gpu_type="all"
# Resolution
# Display refresh rate next to each monitor
# Default: 'off'
# Values: 'on', 'off'
# Flag: --refresh_rate
# Supports: Doesn't work on Windows.
#
# Example:
# on: '1920x1080 @ 60Hz'
# off: '1920x1080'
refresh_rate="off"
# Gtk Theme / Icons / Font
# Shorten output of GTK Theme / Icons / Font
#
# Default: 'off'
# Values: 'on', 'off'
# Flag: --gtk_shorthand
#
# Example:
# on: 'Numix, Adwaita'
# off: 'Numix [GTK2], Adwaita [GTK3]'
gtk_shorthand="off"
# Enable/Disable gtk2 Theme / Icons / Font
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --gtk2
#
# Example:
# on: 'Numix [GTK2], Adwaita [GTK3]'
# off: 'Adwaita [GTK3]'
gtk2="on"
# Enable/Disable gtk3 Theme / Icons / Font
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --gtk3
#
# Example:
# on: 'Numix [GTK2], Adwaita [GTK3]'
# off: 'Numix [GTK2]'
gtk3="on"
# IP Address
# Website to ping for the public IP
#
# Default: 'http://ident.me'
# Values: 'url'
# Flag: --ip_host
public_ip_host="http://ident.me"
# Public IP timeout.
#
# Default: '2'
# Values: 'int'
# Flag: --ip_timeout
public_ip_timeout=2
# Desktop Environment
# Show Desktop Environment version
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --de_version
de_version="on"
# Disk
# Which disks to display.
# The values can be any /dev/sdXX, mount point or directory.
# NOTE: By default we only show the disk info for '/'.
#
# Default: '/'
# Values: '/', '/dev/sdXX', '/path/to/drive'.
# Flag: --disk_show
#
# Example:
# disk_show=('/' '/dev/sdb1'):
# 'Disk (/): 74G / 118G (66%)'
# 'Disk (/mnt/Videos): 823G / 893G (93%)'
#
# disk_show=('/'):
# 'Disk (/): 74G / 118G (66%)'
#
disk_show=('/')
# Disk subtitle.
# What to append to the Disk subtitle.
#
# Default: 'mount'
# Values: 'mount', 'name', 'dir', 'none'
# Flag: --disk_subtitle
#
# Example:
# name: 'Disk (/dev/sda1): 74G / 118G (66%)'
# 'Disk (/dev/sdb2): 74G / 118G (66%)'
#
# mount: 'Disk (/): 74G / 118G (66%)'
# 'Disk (/mnt/Local Disk): 74G / 118G (66%)'
# 'Disk (/mnt/Videos): 74G / 118G (66%)'
#
# dir: 'Disk (/): 74G / 118G (66%)'
# 'Disk (Local Disk): 74G / 118G (66%)'
# 'Disk (Videos): 74G / 118G (66%)'
#
# none: 'Disk: 74G / 118G (66%)'
# 'Disk: 74G / 118G (66%)'
# 'Disk: 74G / 118G (66%)'
disk_subtitle="mount"
# Disk percent.
# Show/Hide disk percent.
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --disk_percent
#
# Example:
# on: 'Disk (/): 74G / 118G (66%)'
# off: 'Disk (/): 74G / 118G'
disk_percent="on"
# Song
# Manually specify a music player.
#
# Default: 'auto'
# Values: 'auto', 'player-name'
# Flag: --music_player
#
# Available values for 'player-name':
#
# amarok
# audacious
# banshee
# bluemindo
# clementine
# cmus
# deadbeef
# deepin-music
# dragon
# elisa
# exaile
# gnome-music
# gmusicbrowser
# gogglesmm
# guayadeque
# io.elementary.music
# iTunes
# juk
# lollypop
# mocp
# mopidy
# mpd
# muine
# netease-cloud-music
# olivia
# playerctl
# pogo
# pragha
# qmmp
# quodlibet
# rhythmbox
# sayonara
# smplayer
# spotify
# strawberry
# tauonmb
# tomahawk
# vlc
# xmms2d
# xnoise
# yarock
music_player="auto"
# Format to display song information.
#
# Default: '%artist% - %album% - %title%'
# Values: '%artist%', '%album%', '%title%'
# Flag: --song_format
#
# Example:
# default: 'Song: Jet - Get Born - Sgt Major'
song_format="%artist% - %album% - %title%"
# Print the Artist, Album and Title on separate lines
#
# Default: 'off'
# Values: 'on', 'off'
# Flag: --song_shorthand
#
# Example:
# on: 'Artist: The Fratellis'
# 'Album: Costello Music'
# 'Song: Chelsea Dagger'
#
# off: 'Song: The Fratellis - Costello Music - Chelsea Dagger'
song_shorthand="off"
# 'mpc' arguments (specify a host, password etc).
#
# Default: ''
# Example: mpc_args=(-h HOST -P PASSWORD)
mpc_args=()
# Text Colors
# Text Colors
#
# Default: 'distro'
# Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num'
# Flag: --colors
#
# Each number represents a different part of the text in
# this order: 'title', '@', 'underline', 'subtitle', 'colon', 'info'
#
# Example:
# colors=(distro) - Text is colored based on Distro colors.
# colors=(4 6 1 8 8 6) - Text is colored in the order above.
colors=(distro)
# Text Options
# Toggle bold text
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --bold
bold="on"
# Enable/Disable Underline
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --underline
underline_enabled="on"
# Underline character
#
# Default: '-'
# Values: 'string'
# Flag: --underline_char
underline_char="-"
# Info Separator
# Replace the default separator with the specified string.
#
# Default: ':'
# Flag: --separator
#
# Example:
# separator="->": 'Shell-> bash'
# separator=" =": 'WM = dwm'
separator=":"
# Color Blocks
# Color block range
# The range of colors to print.
#
# Default: '0', '15'
# Values: 'num'
# Flag: --block_range
#
# Example:
#
# Display colors 0-7 in the blocks. (8 colors)
# neofetch --block_range 0 7
#
# Display colors 0-15 in the blocks. (16 colors)
# neofetch --block_range 0 15
block_range=(0 15)
# Toggle color blocks
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --color_blocks
color_blocks="on"
# Color block width in spaces
#
# Default: '3'
# Values: 'num'
# Flag: --block_width
block_width=3
# Color block height in lines
#
# Default: '1'
# Values: 'num'
# Flag: --block_height
block_height=1
# Color Alignment
#
# Default: 'auto'
# Values: 'auto', 'num'
# Flag: --col_offset
#
# Number specifies how far from the left side of the terminal (in spaces) to
# begin printing the columns, in case you want to e.g. center them under your
# text.
# Example:
# col_offset="auto" - Default behavior of neofetch
# col_offset=7 - Leave 7 spaces then print the colors
col_offset="auto"
# Progress Bars
# Bar characters
#
# Default: '-', '='
# Values: 'string', 'string'
# Flag: --bar_char
#
# Example:
# neofetch --bar_char 'elapsed' 'total'
# neofetch --bar_char '-' '='
bar_char_elapsed="-"
bar_char_total="="
# Toggle Bar border
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --bar_border
bar_border="on"
# Progress bar length in spaces
# Number of chars long to make the progress bars.
#
# Default: '15'
# Values: 'num'
# Flag: --bar_length
bar_length=15
# Progress bar colors
# When set to distro, uses your distro's logo colors.
#
# Default: 'distro', 'distro'
# Values: 'distro', 'num'
# Flag: --bar_colors
#
# Example:
# neofetch --bar_colors 3 4
# neofetch --bar_colors distro 5
bar_color_elapsed="distro"
bar_color_total="distro"
# Info display
# Display a bar with the info.
#
# Default: 'off'
# Values: 'bar', 'infobar', 'barinfo', 'off'
# Flags: --cpu_display
# --memory_display
# --battery_display
# --disk_display
#
# Example:
# bar: '[---=======]'
# infobar: 'info [---=======]'
# barinfo: '[---=======] info'
# off: 'info'
cpu_display="off"
memory_display="off"
battery_display="off"
disk_display="off"
# Backend Settings
# Image backend.
#
# Default: 'ascii'
# Values: 'ascii', 'caca', 'chafa', 'jp2a', 'iterm2', 'off',
# 'pot', 'termpix', 'pixterm', 'tycat', 'w3m', 'kitty'
# Flag: --backend
image_backend="ascii"
# Image Source
#
# Which image or ascii file to display.
#
# Default: 'auto'
# Values: 'auto', 'ascii', 'wallpaper', '/path/to/img', '/path/to/ascii', '/path/to/dir/'
# 'command output (neofetch --ascii "$(fortune | cowsay -W 30)")'
# Flag: --source
#
# NOTE: 'auto' will pick the best image source for whatever image backend is used.
# In ascii mode, distro ascii art will be used and in an image mode, your
# wallpaper will be used.
image_source="auto"
# Ascii Options
# Ascii distro
# Which distro's ascii art to display.
#
# Default: 'auto'
# Values: 'auto', 'distro_name'
# Flag: --ascii_distro
# NOTE: AIX, Alpine, Anarchy, Android, Antergos, antiX, "AOSC OS",
# "AOSC OS/Retro", Apricity, ArcoLinux, ArchBox, ARCHlabs,
# ArchStrike, XFerience, ArchMerge, Arch, Artix, Arya, Bedrock,
# Bitrig, BlackArch, BLAG, BlankOn, BlueLight, bonsai, BSD,
# BunsenLabs, Calculate, Carbs, CentOS, Chakra, ChaletOS,
# Chapeau, Chrom*, Cleanjaro, ClearOS, Clear_Linux, Clover,
# Condres, Container_Linux, CRUX, Cucumber, Debian, Deepin,
# DesaOS, Devuan, DracOS, DarkOs, DragonFly, Drauger, Elementary,
# EndeavourOS, Endless, EuroLinux, Exherbo, Fedora, Feren, FreeBSD,
# FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, Gentoo, Pentoo,
# gNewSense, GNOME, GNU, GoboLinux, Grombyang, Guix, Haiku, Huayra,
# Hyperbola, janus, Kali, KaOS, KDE_neon, Kibojoe, Kogaion,
# Korora, KSLinux, Kubuntu, LEDE, LFS, Linux_Lite,
# LMDE, Lubuntu, Lunar, macos, Mageia, MagpieOS, Mandriva,
# Manjaro, Maui, Mer, Minix, LinuxMint, MX_Linux, Namib,
# Neptune, NetBSD, Netrunner, Nitrux, NixOS, Nurunner,
# NuTyX, OBRevenge, OpenBSD, openEuler, OpenIndiana, openmamba,
# OpenMandriva, OpenStage, OpenWrt, osmc, Oracle, OS Elbrus, PacBSD,
# Parabola, Pardus, Parrot, Parsix, TrueOS, PCLinuxOS, Peppermint,
# popos, Porteus, PostMarketOS, Proxmox, Puppy, PureOS, Qubes, Radix,
# Raspbian, Reborn_OS, Redstar, Redcore, Redhat, Refracted_Devuan,
# Regata, Rosa, sabotage, Sabayon, Sailfish, SalentOS, Scientific,
# Septor, SereneLinux, SharkLinux, Siduction, Slackware, SliTaz,
# SmartOS, Solus, Source_Mage, Sparky, Star, SteamOS, SunOS,
# openSUSE_Leap, openSUSE_Tumbleweed, openSUSE, SwagArch, Tails,
# Trisquel, Ubuntu-Budgie, Ubuntu-GNOME, Ubuntu-MATE, Ubuntu-Studio,
# Ubuntu, Venom, Void, Obarun, windows10, Windows7, Xubuntu, Zorin,
# and IRIX have ascii logos
# NOTE: Arch, Ubuntu, Redhat, and Dragonfly have 'old' logo variants.
# Use '{distro name}_old' to use the old logos.
# NOTE: Ubuntu has flavor variants.
# Change this to Lubuntu, Kubuntu, Xubuntu, Ubuntu-GNOME,
# Ubuntu-Studio, Ubuntu-Mate or Ubuntu-Budgie to use the flavors.
# NOTE: Arcolinux, Dragonfly, Fedora, Alpine, Arch, Ubuntu,
# CRUX, Debian, Gentoo, FreeBSD, Mac, NixOS, OpenBSD, android,
# Antrix, CentOS, Cleanjaro, ElementaryOS, GUIX, Hyperbola,
# Manjaro, MXLinux, NetBSD, Parabola, POP_OS, PureOS,
# Slackware, SunOS, LinuxLite, OpenSUSE, Raspbian,
# postmarketOS, and Void have a smaller logo variant.
# Use '{distro name}_small' to use the small variants.
ascii_distro="auto"
# Ascii Colors
#
# Default: 'distro'
# Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num'
# Flag: --ascii_colors
#
# Example:
# ascii_colors=(distro) - Ascii is colored based on Distro colors.
# ascii_colors=(4 6 1 8 8 6) - Ascii is colored using these colors.
ascii_colors=(distro)
# Bold ascii logo
# Whether or not to bold the ascii logo.
#
# Default: 'on'
# Values: 'on', 'off'
# Flag: --ascii_bold
ascii_bold="on"
# Image Options
# Image loop
# Setting this to on will make neofetch redraw the image constantly until
# Ctrl+C is pressed. This fixes display issues in some terminal emulators.
#
# Default: 'off'
# Values: 'on', 'off'
# Flag: --loop
image_loop="off"
# Thumbnail directory
#
# Default: '~/.cache/thumbnails/neofetch'
# Values: 'dir'
thumbnail_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/thumbnails/neofetch"
# Crop mode
#
# Default: 'normal'
# Values: 'normal', 'fit', 'fill'
# Flag: --crop_mode
#
# See this wiki page to learn about the fit and fill options.
# https://github.com/dylanaraps/neofetch/wiki/What-is-Waifu-Crop%3F
crop_mode="normal"
# Crop offset
# Note: Only affects 'normal' crop mode.
#
# Default: 'center'
# Values: 'northwest', 'north', 'northeast', 'west', 'center'
# 'east', 'southwest', 'south', 'southeast'
# Flag: --crop_offset
crop_offset="center"
# Image size
# The image is half the terminal width by default.
#
# Default: 'auto'
# Values: 'auto', '00px', '00%', 'none'
# Flags: --image_size
# --size
image_size="auto"
# Gap between image and text
#
# Default: '3'
# Values: 'num', '-num'
# Flag: --gap
gap=3
# Image offsets
# Only works with the w3m backend.
#
# Default: '0'
# Values: 'px'
# Flags: --xoffset
# --yoffset
yoffset=0
xoffset=0
# Image background color
# Only works with the w3m backend.
#
# Default: ''
# Values: 'color', 'blue'
# Flag: --bg_color
background_color=
# Misc Options
# Stdout mode
# Turn off all colors and disables image backend (ASCII/Image).
# Useful for piping into another command.
# Default: 'off'
# Values: 'on', 'off'
stdout="off"
-92
View File
@@ -1,92 +0,0 @@
#!/bin/bash
# 🌙 SwiftBar Plugin: Symbolic Moon Phase Monitor
# Author: GPT + David
# Requires: curl, jq, awk
# Caches data for 6h to reduce API use
API_KEY="6ec71a8170214d828c08ba8bf2ca29e9"
CURL="/usr/bin/curl"
JQ="/usr/bin/jq"
AWK="/usr/bin/awk"
CACHE_FILE="$HOME/.cache/moonphase.json"
STATE_FILE="$HOME/.lunarstate"
MAX_AGE_HOURS=6
mkdir -p "$(dirname "$CACHE_FILE")"
# Check cache freshness
NEEDS_UPDATE=true
if [ -f "$CACHE_FILE" ]; then
MOD_UNIX=$(stat -f "%m" "$CACHE_FILE")
NOW_UNIX=$(date +%s)
AGE_HOURS=$(( (NOW_UNIX - MOD_UNIX) / 3600 ))
[ "$AGE_HOURS" -lt "$MAX_AGE_HOURS" ] && NEEDS_UPDATE=false
fi
# Fetch and cache
if [ "$NEEDS_UPDATE" = true ]; then
MOON_JSON=$($CURL -s "https://api.ipgeolocation.io/astronomy?apiKey=$API_KEY")
echo "$MOON_JSON" > "$CACHE_FILE"
else
MOON_JSON=$(cat "$CACHE_FILE")
fi
# Extract fields
PHASE=$(echo "$MOON_JSON" | $JQ -r '.moon_phase')
ILLUM=$(echo "$MOON_JSON" | $JQ -r '.moon_illumination_percentage' | $AWK '{printf "%.0f", $1}')
MOONRISE=$(echo "$MOON_JSON" | $JQ -r '.moonrise')
MOONSET=$(echo "$MOON_JSON" | $JQ -r '.moonset')
PHASE_LC=$(echo "$PHASE" | tr '[:upper:]' '[:lower:]')
# Ritual glyphs & poetic names
declare -A ICONS=(
["new_moon"]="🌑"
["waxing_crescent"]="🌒"
["first_quarter"]="🌓"
["waxing_gibbous"]="🌔"
["full_moon"]="🌕"
["waning_gibbous"]="🌖"
["last_quarter"]="🌗"
["waning_crescent"]="🌘"
)
declare -A POETIC=(
["new_moon"]="Veiled Mother"
["waxing_crescent"]="Hesitant Flame"
["first_quarter"]="Climbing Eye"
["waxing_gibbous"]="Gathering Tide"
["full_moon"]="Revealed Bride"
["waning_gibbous"]="Harvest Wane"
["last_quarter"]="Parting Mirror"
["waning_crescent"]="Waning Daughter"
)
ICON="${ICONS[$PHASE_LC]:-❓}"
POETIC_NAME="${POETIC[$PHASE_LC]:-Unknown Phase}"
# Direction
ARROW="⬆"
[[ "$PHASE_LC" =~ ^(full_moon|waning_gibbous|last_quarter|waning_crescent)$ ]] && ARROW="⬇"
# Ritual detection
NOTICE=""
if [[ "$PHASE_LC" == "full_moon" ]]; then
NOTICE="☽ FULL RITE ☾"
elif [[ "$PHASE_LC" == "new_moon" ]]; then
NOTICE="☉ NEW SILENCE ☉"
fi
# Output to menubar
echo "$ICON $ARROW ${ILLUM}%"
echo "---"
echo "Phase: $(echo "$PHASE" | tr '_' ' ' | awk '{for (i=1; i<=NF; i++) $i=toupper(substr($i,1,1)) substr($i,2)} 1')"
echo "Poetic: $POETIC_NAME"
echo "Illumination: ${ILLUM}%"
echo "Moonrise: $MOONRISE"
echo "Moonset: $MOONSET"
[ -n "$NOTICE" ] && echo "$NOTICE"
echo "Last updated: $(date -r "$CACHE_FILE" "+%H:%M %Z")"
# Optional: write state file for system rituals
echo "$PHASE_LC,$ILLUM,$POETIC_NAME,$NOTICE" > "$STATE_FILE"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { printf >&2 "\n%s\n\n" "This repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-checkout' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks')."; exit 2; }
git lfs post-checkout "$@"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { printf >&2 "\n%s\n\n" "This repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-commit' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks')."; exit 2; }
git lfs post-commit "$@"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { printf >&2 "\n%s\n\n" "This repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-merge' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks')."; exit 2; }
git lfs post-merge "$@"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { printf >&2 "\n%s\n\n" "This repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks')."; exit 2; }
git lfs pre-push "$@"
+6
View File
@@ -50,6 +50,12 @@ if [[ -f "$HOME/.docker/config.json" ]]; then
cp "$HOME/.docker/config.json" "$TEMP_DIR/secrets/.docker/"
fi
# Password store (pass — software licenses, credentials)
if [[ -d "$HOME/.password-store" ]]; then
echo " 🔑 Password store (pass)"
cp -r "$HOME/.password-store" "$TEMP_DIR/secrets/"
fi
# Any license files or certificates (if found)
if [[ -f "$HOME/.vuescanrc" ]]; then
echo " 📄 VueScan license"
-170
View File
@@ -1,170 +0,0 @@
#!/usr/bin/env bash
# Backup all private keys and sensitive configurations
# Following prime directive: durable, thoughtful backup strategy
set -euo pipefail
BACKUP_DIR="$HOME/dotfiles/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${YELLOW}🔐 Creating encrypted backup of private keys and secrets${NC}"
echo "Timestamp: $TIMESTAMP"
echo ""
# Create backup directory
mkdir -p "$BACKUP_DIR"/{ssh,gpg,docker}
# Function to create encrypted backup
create_encrypted_backup() {
local source_dir="$1"
local backup_name="$2"
local backup_path="$BACKUP_DIR/$backup_name"
if [[ -d "$source_dir" ]] || [[ -f "$source_dir" ]]; then
echo -e "${YELLOW}Backing up: $source_dir${NC}"
# Create tar archive and encrypt in one step
tar -czf - -C "$(dirname "$source_dir")" "$(basename "$source_dir")" | \
gpg --symmetric --cipher-algo AES256 --compress-algo 2 \
--output "${backup_path}/${backup_name}_${TIMESTAMP}.tar.gz.gpg"
# Create restore instructions
cat > "${backup_path}/RESTORE_INSTRUCTIONS.md" << EOF
# ${backup_name^} Restore Instructions
## Decrypting and Restoring ${backup_name^}
To restore from backup: \`${backup_name}_${TIMESTAMP}.tar.gz.gpg\`
### Step 1: Decrypt the backup
\`\`\`bash
gpg --decrypt ${backup_name}_${TIMESTAMP}.tar.gz.gpg > ${backup_name}_${TIMESTAMP}.tar.gz
\`\`\`
### Step 2: Extract the archive
\`\`\`bash
tar -xzf ${backup_name}_${TIMESTAMP}.tar.gz -C ~/
\`\`\`
### Step 3: Set correct permissions
\`\`\`bash
chmod 700 ~/$(basename "$source_dir")
find ~/$(basename "$source_dir") -type f -exec chmod 600 {} \;
\`\`\`
## Security Notes
- Keep this encrypted backup secure
- Contains private keys/sensitive data
- Test restore process periodically
## Backup Contents
This backup includes: $(basename "$source_dir")
Created: $(date)
System: $(sw_vers -productVersion)
EOF
echo -e "${GREEN}✅ Backup created: ${backup_path}/${backup_name}_${TIMESTAMP}.tar.gz.gpg${NC}"
else
echo -e "${RED}⚠️ Source not found: $source_dir${NC}"
fi
}
# Backup GPG private keys and keyring
if [[ -d "$HOME/.gnupg" ]]; then
echo -e "${YELLOW}🔑 Backing up GPG private keys and keyring...${NC}"
# Create temporary directory with essential GPG files
temp_gpg=$(mktemp -d)
mkdir -p "$temp_gpg/.gnupg"
# Copy essential GPG files (not temporary/socket files)
cp -r "$HOME/.gnupg/private-keys-v1.d" "$temp_gpg/.gnupg/" 2>/dev/null || true
cp "$HOME/.gnupg/pubring.kbx" "$temp_gpg/.gnupg/" 2>/dev/null || true
cp "$HOME/.gnupg/trustdb.gpg" "$temp_gpg/.gnupg/" 2>/dev/null || true
cp "$HOME/.gnupg/gpg.conf" "$temp_gpg/.gnupg/" 2>/dev/null || true
cp "$HOME/.gnupg/gpg-agent.conf" "$temp_gpg/.gnupg/" 2>/dev/null || true
cp "$HOME/.gnupg/dirmngr.conf" "$temp_gpg/.gnupg/" 2>/dev/null || true
# Create encrypted backup
tar -czf - -C "$temp_gpg" .gnupg | \
gpg --symmetric --cipher-algo AES256 --compress-algo 2 \
--output "$BACKUP_DIR/gpg/gpg_keyring_${TIMESTAMP}.tar.gz.gpg"
# Cleanup
rm -rf "$temp_gpg"
# Create restore instructions
cat > "$BACKUP_DIR/gpg/RESTORE_INSTRUCTIONS.md" << 'EOF'
# GPG Keyring Restore Instructions
## Decrypting and Restoring GPG Keys
To restore from backup: `gpg_keyring_TIMESTAMP.tar.gz.gpg`
### Step 1: Decrypt the backup
```bash
gpg --decrypt gpg_keyring_TIMESTAMP.tar.gz.gpg > gpg_keyring_TIMESTAMP.tar.gz
```
### Step 2: Extract to home directory
```bash
tar -xzf gpg_keyring_TIMESTAMP.tar.gz -C ~/
```
### Step 3: Set correct permissions
```bash
chmod 700 ~/.gnupg
chmod 600 ~/.gnupg/*
chmod 700 ~/.gnupg/private-keys-v1.d
chmod 600 ~/.gnupg/private-keys-v1.d/*
```
### Step 4: Restart GPG agent
```bash
gpgconf --kill gpg-agent
gpg --list-secret-keys # This will restart the agent
```
## Security Notes
- Contains your GPG private keys - highly sensitive
- Keep encrypted backup in secure location
- Test restore process periodically
## What's Included
- Private keys (private-keys-v1.d/)
- Public keyring (pubring.kbx)
- Trust database (trustdb.gpg)
- GPG configuration files
Created: $(date)
System: $(sw_vers -productVersion)
EOF
echo -e "${GREEN}✅ GPG keyring backup created${NC}"
fi
# Backup Docker configuration
if [[ -f "$HOME/.docker/config.json" ]]; then
create_encrypted_backup "$HOME/.docker" "docker"
fi
# Summary
echo ""
echo -e "${GREEN}🎉 Backup Summary:${NC}"
echo "📁 Backups stored in: $BACKUP_DIR"
echo "🔐 All backups are GPG encrypted with AES256"
echo "📋 Each backup includes restore instructions"
echo ""
echo -e "${YELLOW}💡 Recommended: Store a copy of these backups in a separate secure location${NC}"
echo -e "${YELLOW}📋 Test restore process periodically to ensure backups work${NC}"
-182
View File
@@ -1,182 +0,0 @@
#!/usr/bin/env bash
# Backup and encrypt SSH keys
set -euo pipefail
SSH_DIR="$HOME/.ssh"
BACKUP_DIR="$HOME/dotfiles/backups/ssh"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}SSH Keys Backup & Encryption${NC}"
echo "==============================="
# Check if SSH directory exists
if [ ! -d "$SSH_DIR" ]; then
echo -e "${RED}❌ SSH directory not found: $SSH_DIR${NC}"
exit 1
fi
# Check if GPG is available
if ! command -v gpg >/dev/null 2>&1; then
echo -e "${RED}❌ GPG not found. Please install GPG first.${NC}"
echo "Install with: brew install gnupg"
exit 1
fi
# Create backup directory
mkdir -p "$BACKUP_DIR"
echo -e "${YELLOW}🔍 Scanning SSH directory...${NC}"
# Find private keys (files without .pub extension and not config/known_hosts)
PRIVATE_KEYS=()
while IFS= read -r -d '' file; do
filename=$(basename "$file")
# Skip public keys, config files, and known_hosts
if [[ ! "$filename" =~ \.(pub|ppk)$ ]] && \
[[ "$filename" != "config" ]] && \
[[ "$filename" != "known_hosts" ]] && \
[[ "$filename" != "authorized_keys" ]]; then
PRIVATE_KEYS+=("$file")
fi
done < <(find "$SSH_DIR" -type f -print0)
if [ ${#PRIVATE_KEYS[@]} -eq 0 ]; then
echo -e "${YELLOW}⚠️ No private keys found to backup${NC}"
exit 0
fi
echo -e "${GREEN}Found ${#PRIVATE_KEYS[@]} private key(s):${NC}"
for key in "${PRIVATE_KEYS[@]}"; do
echo " • $(basename "$key")"
done
echo ""
# Ask for confirmation
read -p "Proceed with backup and encryption? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Backup cancelled."
exit 0
fi
# Create tarball of SSH directory
TEMP_TAR="/tmp/ssh_backup_${TIMESTAMP}.tar"
echo -e "${YELLOW}📦 Creating backup archive...${NC}"
# Create tar with only the files we want
tar -cf "$TEMP_TAR" -C "$HOME" .ssh/config 2>/dev/null || true
# Add private keys to tar
for key in "${PRIVATE_KEYS[@]}"; do
relative_path=$(echo "$key" | sed "s|$HOME/||")
tar -rf "$TEMP_TAR" -C "$HOME" "$relative_path" 2>/dev/null || true
echo " ✓ Added: $(basename "$key")"
done
# Add public keys corresponding to private keys
for key in "${PRIVATE_KEYS[@]}"; do
pub_key="${key}.pub"
if [ -f "$pub_key" ]; then
relative_path=$(echo "$pub_key" | sed "s|$HOME/||")
tar -rf "$TEMP_TAR" -C "$HOME" "$relative_path" 2>/dev/null || true
echo " ✓ Added: $(basename "$pub_key")"
fi
done
# Compress the tar
gzip "$TEMP_TAR"
TEMP_TAR="${TEMP_TAR}.gz"
# Encrypt with GPG
ENCRYPTED_FILE="$BACKUP_DIR/ssh_keys_${TIMESTAMP}.tar.gz.gpg"
echo -e "${YELLOW}🔐 Encrypting backup...${NC}"
echo "You will be prompted for a passphrase to encrypt the backup."
if gpg --symmetric --cipher-algo AES256 --compress-algo 1 --s2k-mode 3 \
--s2k-digest-algo SHA512 --s2k-count 65536 \
--output "$ENCRYPTED_FILE" "$TEMP_TAR"; then
# Clean up temporary file
rm "$TEMP_TAR"
echo -e "${GREEN}✅ SSH keys backup completed!${NC}"
echo ""
echo "Backup details:"
echo " 📁 Location: $ENCRYPTED_FILE"
echo " 📏 Size: $(du -h "$ENCRYPTED_FILE" | cut -f1)"
echo " 🔑 Encryption: AES256"
echo ""
# Create restore instructions
cat > "$BACKUP_DIR/RESTORE_INSTRUCTIONS.md" << EOF
# SSH Keys Restore Instructions
## Decrypting and Restoring SSH Keys
To restore from backup: \`ssh_keys_${TIMESTAMP}.tar.gz.gpg\`
### Step 1: Decrypt the backup
\`\`\`bash
gpg --decrypt ssh_keys_${TIMESTAMP}.tar.gz.gpg > ssh_keys_${TIMESTAMP}.tar.gz
\`\`\`
### Step 2: Extract the archive
\`\`\`bash
tar -xzf ssh_keys_${TIMESTAMP}.tar.gz -C ~/
\`\`\`
### Step 3: Set correct permissions
\`\`\`bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/*_key ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
\`\`\`
### Step 4: Add keys to SSH agent (if needed)
\`\`\`bash
ssh-add ~/.ssh/your_key_name
\`\`\`
## Security Notes
- Keep this encrypted backup in a secure location
- The backup contains your private keys - treat it as highly sensitive
- Consider storing a copy in a different location (cloud storage, external drive)
- Test the restore process periodically
## Backup Contents
This backup includes:
- SSH configuration file
- Private keys found in ~/.ssh/
- Corresponding public keys
- Proper directory structure
Created: $(date)
System: $(sw_vers -productVersion)
EOF
echo -e "${YELLOW}📋 Restore instructions created: $BACKUP_DIR/RESTORE_INSTRUCTIONS.md${NC}"
# Clean up old backups (keep last 5)
cd "$BACKUP_DIR"
ls -t ssh_keys_*.tar.gz.gpg 2>/dev/null | tail -n +6 | xargs -r rm
echo -e "${GREEN}🎉 Backup process complete!${NC}"
else
# Clean up on failure
rm -f "$TEMP_TAR"
echo -e "${RED}❌ Encryption failed!${NC}"
exit 1
fi
+173
View File
@@ -0,0 +1,173 @@
#!/usr/bin/env bash
# CapableMind development environment setup
# Run after engage (Brewfile) has installed base packages
#
# Prerequisites: Homebrew, Ollama, GPG, pass
# This script sets up: nvm/Node, Ollama models, BMF, launchd agents
set -euo pipefail
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${YELLOW}Setting up CapableMind development environment${NC}"
echo ""
# ============================================
# 1. NVM + Node.js
# ============================================
echo -e "${YELLOW}1. Node.js via nvm${NC}"
if [ -d "$HOME/.nvm" ]; then
echo -e "${GREEN} ✓ nvm already installed${NC}"
else
echo " Installing nvm..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
fi
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
if command -v node >/dev/null && [[ "$(node -v)" == v22.* ]]; then
echo -e "${GREEN} ✓ Node $(node -v) installed${NC}"
else
echo " Installing Node 22 LTS..."
nvm install 22
nvm alias default 22
fi
# ============================================
# 2. Ollama models
# ============================================
echo ""
echo -e "${YELLOW}2. Ollama models${NC}"
if ! command -v ollama >/dev/null; then
echo -e "${RED} ✗ Ollama not installed. Install via: brew install ollama${NC}"
else
# Required models for CapableMind
MODELS=("mxbai-embed-large" "qwen3.5:4b")
for model in "${MODELS[@]}"; do
if ollama list 2>/dev/null | grep -q "$model"; then
echo -e "${GREEN} ✓ $model already pulled${NC}"
else
echo " Pulling $model..."
ollama pull "$model"
fi
done
echo -e "${YELLOW} Note: cm-david trained models must be imported separately from clasp${NC}"
fi
# ============================================
# 3. Clone repositories
# ============================================
echo ""
echo -e "${YELLOW}3. Repositories${NC}"
DEV_DIR="$HOME/_Dev"
mkdir -p "$DEV_DIR"
declare -A REPOS=(
["BetterMemories.io"]="git@github.com:skemantix/BetterMemories.io.git"
["CapableMind-AI"]="git@github.com:skemantix/CapableMind.ai.git"
["chamber-library"]="git@github.com:skemantix/chamber-library.git"
["animal-davidglidden-eu"]="git@github.com:davidglidden/animal-davidglidden-eu.git"
)
for dir in "${!REPOS[@]}"; do
if [ -d "$DEV_DIR/$dir" ]; then
echo -e "${GREEN} ✓ $dir already cloned${NC}"
else
echo " Cloning $dir..."
git clone "${REPOS[$dir]}" "$DEV_DIR/$dir"
fi
done
# ============================================
# 4. BMF build
# ============================================
echo ""
echo -e "${YELLOW}4. Building BetterMemories (BMF)${NC}"
BMF_DIR="$DEV_DIR/BetterMemories.io"
if [ -d "$BMF_DIR" ]; then
cd "$BMF_DIR"
npm install
npm run build
echo -e "${GREEN} ✓ BMF built${NC}"
else
echo -e "${RED} ✗ BMF directory not found${NC}"
fi
# ============================================
# 5. Environment file
# ============================================
echo ""
echo -e "${YELLOW}5. CapableMind environment${NC}"
CM_DIR="$HOME/.capablemind"
mkdir -p "$CM_DIR"
if [ -f "$CM_DIR/env" ]; then
echo -e "${GREEN} ✓ env file exists${NC}"
else
cat > "$CM_DIR/env" << 'ENVEOF'
# CapableMind environment — add your API key
# ANTHROPIC_API_KEY=sk-ant-...
ENVEOF
echo -e "${YELLOW} ⚠ Created $CM_DIR/env — add your ANTHROPIC_API_KEY${NC}"
fi
# ============================================
# 6. Launchd agents
# ============================================
echo ""
echo -e "${YELLOW}6. Launchd agents${NC}"
AGENTS_DIR="$HOME/Library/LaunchAgents"
DOTFILES_CM="$HOME/dotfiles/config/capablemind"
if [ -d "$DOTFILES_CM" ]; then
for plist in "$DOTFILES_CM"/*.plist; do
name=$(basename "$plist")
if [ -f "$AGENTS_DIR/$name" ]; then
echo -e "${GREEN} ✓ $name already installed${NC}"
else
cp "$plist" "$AGENTS_DIR/"
echo -e "${GREEN} ✓ Installed $name${NC}"
echo -e "${YELLOW} Note: Edit paths in $AGENTS_DIR/$name before loading${NC}"
fi
done
else
echo -e "${YELLOW} ⚠ No capablemind config dir in dotfiles${NC}"
fi
# ============================================
# 7. Obsidian vault git mirror
# ============================================
echo ""
echo -e "${YELLOW}7. Obsidian vault sync${NC}"
VAULT_GIT="$DEV_DIR/david-root-and-branch-vault-git"
if [ -d "$VAULT_GIT" ]; then
echo -e "${GREEN} ✓ Vault git mirror exists${NC}"
else
echo -e "${YELLOW} ⚠ Vault git mirror not set up. Run ~/bin/obsidian_vault_sync.sh manually${NC}"
fi
# ============================================
# Summary
# ============================================
echo ""
echo -e "${GREEN}Setup complete.${NC}"
echo ""
echo -e "${YELLOW}Remaining manual steps:${NC}"
echo " 1. Add ANTHROPIC_API_KEY to ~/.capablemind/env"
echo " 2. Edit launchd plist paths if needed, then: launchctl load ~/Library/LaunchAgents/com.capablemind.*.plist"
echo " 3. Import trained cm-david models from clasp (if available)"
echo " 4. Run: cd ~/_Dev/BetterMemories.io && node dist/index.js (to start BMF)"
echo " 5. Reconnect MCP in Claude Code: /mcp"
+4 -3
View File
@@ -44,8 +44,6 @@ link_file "$DOTFILES_DIR/shell/.zshrc" "$HOME/.zshrc"
link_file "$DOTFILES_DIR/shell/.bashrc" "$HOME/.bashrc"
link_file "$DOTFILES_DIR/shell/.zprofile" "$HOME/.zprofile"
link_file "$DOTFILES_DIR/shell/.p10k.zsh" "$HOME/.p10k.zsh"
link_file "$DOTFILES_DIR/shell/.fzf.bash" "$HOME/.fzf.bash"
link_file "$DOTFILES_DIR/shell/.fzf.zsh" "$HOME/.fzf.zsh"
link_file "$DOTFILES_DIR/.gitconfig" "$HOME/.gitconfig"
link_file "$DOTFILES_DIR/.vimrc" "$HOME/.vimrc"
link_file "$DOTFILES_DIR/.npmrc" "$HOME/.npmrc"
@@ -78,8 +76,11 @@ fi
echo -e "${YELLOW}Linking config directories...${NC}"
mkdir -p "$HOME/.config"
# CLAUDE.md — prime directive for Claude Code
link_file "$DOTFILES_DIR/CLAUDE.md" "$HOME/CLAUDE.md"
# Link config subdirectories if they exist
for config_dir in git iterm2 kitty karabiner neofetch swiftbar; do
for config_dir in git kitty karabiner capablemind; do
if [ -d "$DOTFILES_DIR/config/$config_dir" ]; then
link_file "$DOTFILES_DIR/config/$config_dir" "$HOME/.config/$config_dir"
fi
-1
View File
@@ -1 +0,0 @@
[ -f ~/.fzf.bash ] && source ~/.fzf.bash
-7
View File
@@ -1,7 +0,0 @@
# Setup fzf
# ---------
if [[ ! "$PATH" == */Users/davidglidden/.fzf/bin* ]]; then
PATH="${PATH:+${PATH}:}/Users/davidglidden/.fzf/bin"
fi
eval "$(fzf --bash)"
-7
View File
@@ -1,7 +0,0 @@
# Setup fzf
# ---------
if [[ ! "$PATH" == */Users/davidglidden/.fzf/bin* ]]; then
PATH="${PATH:+${PATH}:}/Users/davidglidden/.fzf/bin"
fi
source <(fzf --zsh)
-2
View File
@@ -12,8 +12,6 @@ chisui/zsh-nix-shell # If using Nix at some point
# Git integration
olivierverdier/zsh-git-prompt # Lightweight git aliases/completions
# FZF integration (optional, only if you use fzf)
unixorn/fzf-zsh-plugin
# Completions (optional, only if you reinstall these tools)
# mullvad/mullvad-zsh-completions
-2
View File
@@ -12,8 +12,6 @@ chisui/zsh-nix-shell # If using Nix at some point
# Git integration
olivierverdier/zsh-git-prompt # Lightweight git aliases/completions
# FZF integration (optional, only if you use fzf)
unixorn/fzf-zsh-plugin
# Completions (optional, only if you reinstall these tools)
# mullvad/mullvad-zsh-completions
+9 -12
View File
@@ -114,20 +114,17 @@ zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'
# TOOL INTEGRATIONS
# ═══════════════════════════════════════════════════════════════════════════════
# FZF integration
if [[ -f ~/.fzf.zsh ]]; then
source ~/.fzf.zsh
elif command -v fzf >/dev/null; then
# Manual key bindings if fzf is available but not set up
eval "$(fzf --zsh)" 2>/dev/null || true
fi
# (fzf and zoxide removed — not installed)
# Zoxide integration (smart cd)
if command -v zoxide >/dev/null; then
eval "$(zoxide init zsh)"
fi
# ═══════════════════════════════════════════════════════════════════════════════
# GNU COREUTILS (interactive-only PATH)
# ═══════════════════════════════════════════════════════════════════════════════
# Add this section to your .zshrc after the tool integrations section
# Prevent GMP and other formulae from breaking by keeping gnubin off build PATH.
# Only activate in interactive shells.
if [[ $- == *i* ]]; then
export PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH"
fi
# ═══════════════════════════════════════════════════════════════════════════════
# NODE VERSION MANAGEMENT
+16 -14
View File
@@ -4,7 +4,7 @@
alias gs='git status'
alias kaicd='cd ~/Vault/08. Notes/Children/Kai'
alias kaicd='cd "$VAULT_PATH/08. Notes/Children/02. Kai"'
## II. File checksum verification ##
alias verify1='openssl sha1'
@@ -76,20 +76,16 @@ alias afk="/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resource
# Access quicklook from terminal
alias ql="qlmanage -p "
## Animal Rationis Capax
# work session
alias arc="cd /Users/davidglidden/Documents/GitHub/davidglidden.github.io && claude 'Context initialization:
Please read these files in order:
1. CLAUDE.md - Project instructions and workflow triggers
2. docs/internal/collaboration-protocol.md - Our working relationship
3. docs/internal/project-memory.md - Complete development history
4. docs/chamber/workflow/MODE-1-UNIFIED.md - Current Chamber operations
5. docs/style-guide.md - Editorial guidelines and notation system
## CapableMind
alias cm="cd ~/_Dev/CapableMind-AI"
alias bmf="cd ~/_Dev/BetterMemories.io"
alias bmf-health="curl -s http://localhost:3011/health | python3 -m json.tool"
alias bmf-status="curl -s http://localhost:3011/health | python3 -c \"import sys,json;d=json.load(sys.stdin);cursors={k:v['cursor_position'] for k,v in d['modules'].items()};errors={k:v['error_count'] for k,v in d['modules'].items() if v['error_count']>0};print(f'Vector: {cursors[\\\"vector\\\"]} errors={d[\\\"modules\\\"][\\\"vector\\\"][\\\"error_count\\\"]}');print(f'Max cursor: {max(cursors.values())}');errors and print(f'Errors: {errors}')\""
alias bmf-logs="tail -50 ~/.capablemind/logs/bmf.stderr.log"
alias bmf-errors="grep -i 'error\|deferred\|circuit\|canary\|phase' ~/.capablemind/logs/bmf.stderr.log | tail -20"
After reading, confirm you understand the current state and are ready for today'\''s work.'"
# glimpse processing
alias glimpse='cd ~/animal-davidglidden-eu/tools/glimpse-processing && source venv/bin/activate && python glimpse_tool.py'
## Animal Rationis Capax
alias arc="cd ~/_Dev/animal-davidglidden-eu"
## Tetris
alias tetris='/opt/homebrew/opt/vitetris/bin/tetris'
@@ -97,3 +93,9 @@ alias tetris='/opt/homebrew/opt/vitetris/bin/tetris'
## Pass license management shortcuts
alias licenses='pass ls licenses/'
alias license='pass show licenses/'
## Obsidian Vault push to Gitea
alias gitvault='~/bin/obsidian_vault_sync.sh'
+7 -3
View File
@@ -25,8 +25,10 @@ export XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
# 📚 Vault and workspace paths
export VAULT_PATH="$HOME/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch"
export CHAMBER_PATH="$HOME/animal-davidglidden-eu"
export WORK_PATH="$HOME/Documents/GitHub/davidglidden.github.io"
export CHAMBER_PATH="$HOME/_Dev/chamber-library"
export ARC_PATH="$HOME/_Dev/animal-davidglidden-eu"
export CAPABLEMIND_PATH="$HOME/_Dev/CapableMind-AI"
export BMF_PATH="$HOME/_Dev/BetterMemories.io"
export DOTFILES_PATH="$HOME/dotfiles"
# 🔧 Tool configurations
@@ -55,7 +57,9 @@ export GPG_TTY=$(tty)
# 🚀 Development context detection
detect_context() {
case "$PWD" in
"$WORK_PATH"*) export CURRENT_CONTEXT="work" ;;
"$BMF_PATH"*) export CURRENT_CONTEXT="capablemind" ;;
"$CAPABLEMIND_PATH"*) export CURRENT_CONTEXT="capablemind" ;;
"$ARC_PATH"*) export CURRENT_CONTEXT="arc" ;;
"$CHAMBER_PATH"*) export CURRENT_CONTEXT="chamber" ;;
"$VAULT_PATH"*) export CURRENT_CONTEXT="vault" ;;
"$DOTFILES_PATH"*) export CURRENT_CONTEXT="dotfiles" ;;
+130 -88
View File
@@ -20,7 +20,7 @@ wttr() {
}
## III. Updates (system, brew, etc) #######################
## Description: Performs system updates, Homebrew cleanup, fzf refresh, moon phase logging, and dotfile sync ###########################
## Description: Performs system updates, Homebrew cleanup, moon phase logging, and dotfile sync ###########################
function sysupdate() {
local start_time=$(date +%s)
@@ -58,10 +58,7 @@ function sysupdate() {
echo "⚠️ mas not installed - install with: brew install mas"
fi
echo "🔄 Refreshing fzf..."
if [ -d ~/.fzf ]; then
cd ~/.fzf && git pull && ./install --all && cd -
fi
# fzf removed — no longer installed
# Fix Zsh completion security warnings
echo "🔒 Checking Zsh completion security..."
@@ -101,11 +98,11 @@ function sysupdate() {
echo "🌙 Moon phase tracking disabled (missing curl or jq)"
fi
if [ -d "$HOME/.dotfiles" ]; then
if [ -d "$HOME/dotfiles" ]; then
echo "📝 Committing dotfile changes..."
cd ~/.dotfiles || return
cd ~/dotfiles || return
git add . && git commit -m "🔧 Auto-commit from sysupdate on $(date '+%Y-%m-%d %H:%M')" && git push
brew bundle dump --force --file="$HOME/.dotfiles/Brewfile"
brew bundle dump --force --file="$HOME/dotfiles/Brewfile"
cd - >/dev/null || return
fi
@@ -129,96 +126,76 @@ function quietupdate() {
sudo -vn 2>/dev/null || sudo -v
sudo softwareupdate -i -a >/dev/null
brew update >/dev/null && brew upgrade >/dev/null && brew cleanup >/dev/null && brew autoremove >/dev/null
[ -d ~/.fzf ] && cd ~/.fzf && git pull >/dev/null && ./install --all >/dev/null && cd - >/dev/null
[ -d "$HOME/.dotfiles" ] && cd ~/.dotfiles && git add . && git commit -m "auto sysupdate" && git push && brew bundle dump --force --file="$HOME/.dotfiles/Brewfile" && cd - >/dev/null
[ -d "$HOME/dotfiles" ] && cd ~/dotfiles && git add . && git commit -m "auto sysupdate" && git push && brew bundle dump --force --file="$HOME/dotfiles/Brewfile" && cd - >/dev/null
if [ -x "$HOME/.zsh/hooks/post-update" ]; then "$HOME/.zsh/hooks/post-update"; fi
osascript -e 'display notification "Quiet update complete!" with title "System Maintenance"'
}
# ═══════════════════════════════════════════════════════════════════════════════
# Man Page side-by-side viewer
# Modern, workspace-aware man page viewer
# - Kitty/tmux/iTerm split panes, syntax highlighting via bat
# - Optional qman integration for interactive TOC/search
# - Order-flexible + apropos search
# ═══════════════════════════════════════════════════════════════════════════════
# Detailed Kitty diagnostic
debug_kitty_launch() {
echo "=== Kitty Launch Debugging ==="
# Check basic remote control
echo "1. Testing basic remote control:"
kitty @ ls
echo " Exit code: $?"
# Test simple launch
echo -e "\n2. Testing simple window launch:"
kitty @ launch --type=window echo "Hello from new window"
echo " Exit code: $?"
# Test with bash -c
echo -e "\n3. Testing bash -c launch:"
kitty @ launch --type=window bash -c "echo 'Hello with bash -c'"
echo " Exit code: $?"
# Test overlay
echo -e "\n4. Testing overlay:"
kitty @ launch --type=overlay bash -c "echo 'Overlay test'; read -p 'Press enter to close'"
echo " Exit code: $?"
# Test with actual man command
echo -e "\n5. Testing with man command:"
kitty @ launch --type=window bash -c "man ls"
echo " Exit code: $?"
}
# Test the absolute simplest case
test_basic_split() {
echo "Testing basic split with sleep..."
kitty @ launch --location=vsplit sleep 5
echo "Exit code: $?"
}
# Beautiful man pages in resizable split pane
man() {
if [[ $# -eq 0 ]]; then
echo "Usage: man <command> [section]"
echo "Opens man page in resizable split pane (kitty/tmux) or new tab (iTerm)"
echo "Usage:"
echo " man <command> [section]"
echo " man [section] <command>"
echo " man ? <search-term> # apropos search"
return 1
fi
local cmd="$1"
local section="${2:-}"
# Verify man page exists
if ! /usr/bin/man -w ${section:+$section} "$cmd" >/dev/null 2>&1; then
echo "❌ No manual entry for '$cmd'${section:+ in section $section}"
return 1
# Apropos mode
if [[ "$1" == "?" ]]; then
shift
/usr/bin/man -k "$@"
return
fi
# Build the display command that stays open and adapts to terminal width
local display_cmd
local bat_path=$(which bat 2>/dev/null)
if [[ -n "$bat_path" ]]; then
# Use bat with terminal width detection and better wrapping
display_cmd="export PATH=\"$PATH\"; export MANWIDTH=\$(tput cols); /usr/bin/man ${section:+$section} '$cmd' 2>/dev/null | col -bx | '$bat_path' --language=man --style=grid --theme=Nord --paging=always --terminal-width=\$(tput cols) --wrap=auto; echo; echo 'Press any key to close...'; read -k1"
# Support both orders: man 2 open OR man open 2
local cmd section
if [[ "$1" =~ ^[0-9]+$ && -n "$2" ]]; then
section="$1"; cmd="$2"
else
# Fallback with responsive width
display_cmd="export MANWIDTH=\$(tput cols); MANPAGER='less -R' /usr/bin/man ${section:+$section} '$cmd'; echo; echo 'Press any key to close...'; read -k1"
cmd="$1"; section="${2:-}"
fi
# Handle different terminals - always use split/resizable approach
# Verify page exists
if ! /usr/bin/man -w ${section:+$section} -- "$cmd" >/dev/null 2>&1; then
echo "❌ No manual entry for '$cmd'${section:+ in section $section}"
echo "💡 Try: man ? $cmd"
return 1
fi
# Choose backend
local display_cmd
if command -v qman >/dev/null 2>&1; then
display_cmd="qman ${section:+$section }-- '$cmd'"
else
local bat_path; bat_path=$(command -v bat 2>/dev/null || true)
if [[ -n "$bat_path" ]]; then
display_cmd="export MANWIDTH=\$(tput cols); /usr/bin/man ${section:+$section} '$cmd' 2>/dev/null \
| col -bx \
| '$bat_path' --language=man --style=grid --theme=\${BAT_THEME:-Nord} \
--paging=always --terminal-width=\$(tput cols) --wrap=auto"
else
display_cmd="export MANWIDTH=\$(tput cols); MANPAGER='less -R' /usr/bin/man ${section:+$section} '$cmd'"
fi
fi
# Handle different terminal environments
if [[ -n "${KITTY_WINDOW_ID:-}" ]]; then
# Kitty: Create optimally-sized vertical split
# Left pane: ~100 chars for code, Right pane: ~64 chars for optimal reading
kitty @ launch \
--location=vsplit \
--title="📖 $cmd${section:+ ($section)}" \
--cwd=current \
--bias=60 \
zsh -c "$display_cmd" >/dev/null
--bias=${KITTY_BIAS:-60} \
zsh -lc "$display_cmd" >/dev/null
elif [[ -n "${TMUX:-}" ]]; then
# TMUX: Create resizable horizontal split (easier to read)
tmux split-window -v -l 40% "$display_cmd"
tmux split-window -v -l ${TMUX_HEIGHT:-40%} "$display_cmd"
elif [[ "${TERM_PROGRAM}" == "iTerm.app" ]]; then
# iTerm: Create new split pane
osascript -e "
tell application \"iTerm\"
tell current window
@@ -230,17 +207,13 @@ man() {
end tell
end tell
end tell
end tell
" >/dev/null 2>&1
end tell" >/dev/null 2>&1
else
# Fallback: run inline
echo "📖 Displaying man page inline:"
eval "$display_cmd"
fi
}
# batman is already aliased to man in aliases.zsh
# ═══════════════════════════════════════════════════════════════════════════════
# DOTFILES MANAGEMENT FUNCTIONS
# ═══════════════════════════════════════════════════════════════════════════════
@@ -297,12 +270,81 @@ backup-configs() {
echo " ✓ GPG configuration"
fi
# AWS credentials (if they exist)
if [[ -d ~/.aws ]]; then
cp -R ~/.aws "$backup_dir/" 2>/dev/null || true
echo " ✓ AWS configuration"
fi
echo "✅ Configs backed up to: $backup_dir"
}
# ═══════════════════════════════════════════════════════════════════════════════
# LICENSE MANAGEMENT FUNCTIONS FOR PASS
# ═══════════════════════════════════════════════════════════════════════════════
# License management: add a license entry with optional attached file
license-add() {
if [ $# -lt 1 ]; then
echo "Usage: license-add <product-name> [license-file-path]"
return 1
fi
local product="$1"
local entry="licenses/$product"
local dir="$HOME/.password-store/${entry}.gpg.d"
echo "→ Paste activation code or license metadata for '$product', then press Ctrl+D:"
pass insert -m "$entry" || return 1
if [ $# -eq 2 ]; then
local filepath="$2"
local filename="$(basename "$filepath")"
mkdir -p "$dir"
gpg -o "$dir/${filename}.gpg" -e -r "$(gpg --list-secret-keys --with-colons | awk -F: '/^uid:/ {print $10; exit}')" "$filepath"
echo "✔️ Encrypted license file saved as: $dir/${filename}.gpg"
else
echo "✔️ Code-only license entry created for '$product'."
fi
}
# Edit a license entry in the pass store
license-edit() {
if [ $# -ne 1 ]; then
echo "Usage: license-edit <product-name>"
return 1
fi
local product="$1"
pass edit "licenses/$product"
}
# List all stored licenses
license-list() {
pass ls licenses/ | sed 's/^licenses\///' | sort
}
# Show license details and attached files for a product
license-info() {
if [ $# -ne 1 ]; then
echo "Usage: license-info <product-name>"
return 1
fi
local product="$1"
local entry="licenses/$product"
local pass_file="$HOME/.password-store/${entry}.gpg"
local attach_dir="$HOME/.password-store/${entry}.gpg.d"
if [ ! -f "$pass_file" ]; then
echo "❌ No license entry found for '$product'"
return 1
fi
echo "🔐 License entry: $product"
echo "----------------------------------------"
pass show "$entry"
echo
if [ -d "$attach_dir" ]; then
echo "📎 Attached encrypted file(s):"
find "$attach_dir" -type f -name '*.gpg' -exec basename {} \;
else
echo "📎 No attached files."
fi
}
-2
View File
@@ -28,8 +28,6 @@ nvm() {
# Aliases for when you need to use nvm
alias nvm-load='unset -f nvm; [ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"'
alias nvm-claude='nvm use 22.16.0'
alias node-homebrew='/opt/homebrew/bin/node'
alias npm-homebrew='/opt/homebrew/bin/npm'
# Quick check if we're in a project with .nvmrc
check_nvmrc() {
-1
View File
@@ -20,7 +20,6 @@ declare -a potential_paths=(
"/usr/local/bin" # Homebrew (Intel)
"/usr/local/sbin" # System binaries
"/opt/homebrew/opt/python@3.13/libexec/bin" # Python 3.13
"/opt/homebrew/opt/python@3.12/libexec/bin" # Python 3.12 (fallback)
"$HOME/.cargo/bin" # Rust binaries
"/opt/homebrew/opt/gnu-sed/libexec/gnubin" # GNU sed
"/opt/homebrew/opt/gnu-tar/libexec/gnubin" # GNU tar
+6
View File
@@ -8,3 +8,9 @@ Host github.com
User git
IdentityFile ~/.ssh/dfg_GH
IdentitiesOnly yes
Host git.skemantix.com
HostName git.skemantix.com
User git
IdentityFile ~/.ssh/chamber-library
IdentitiesOnly yes