From 8e4a179c1e76fa9273c5d4c6158cc0c07122460e Mon Sep 17 00:00:00 2001 From: Hao Ngo Date: Sat, 11 Jul 2026 03:59:07 +0700 Subject: [PATCH] feat: senior-grade dotfiles with chezmoi + sops/age Bootstrap a reproducible, secret-safe macOS dev environment. - chezmoi source = this repo; machine vars via .chezmoi.toml.tmpl - secrets sops-encrypted to age key (never committed); npm auth via template - git identity templated, GitHub token removed (gh credential helper) - migrated: zsh, git, tmux, starship, ghostty, yazi, htop, gh, claude config+rules - reproducible packages: Brewfile (59 brews/3 casks) + devbox global - idempotent run_onchange bootstrap (brew, oh-my-zsh, devbox, nvm, tmux TPM) - quality gates: gitleaks CI + pre-commit, chezmoi apply dry-run, justfile --- .chezmoi.toml.tmpl | 10 + .chezmoiignore | 7 + ...nchange_before_10-install-packages.sh.tmpl | 49 ++++ .github/workflows/ci.yml | 52 ++++ .gitignore | 18 ++ .pre-commit-config.yaml | 23 ++ .sops.yaml | 5 + CLAUDE.md | 62 +++++ PLAN.md | 75 ++++++ README.md | 74 ++++++ dot_claude/CLAUDE.md | 6 + dot_claude/mcp.json | 13 + dot_claude/private_RTK.md | 29 +++ dot_claude/private_settings.json | 153 ++++++++++++ dot_claude/rules/common/agents.md | 49 ++++ dot_claude/rules/common/coding-style.md | 48 ++++ .../rules/common/development-workflow.md | 37 +++ dot_claude/rules/common/git-workflow.md | 24 ++ dot_claude/rules/common/hooks.md | 30 +++ dot_claude/rules/common/patterns.md | 31 +++ dot_claude/rules/common/performance.md | 55 +++++ dot_claude/rules/common/security.md | 29 +++ dot_claude/rules/common/testing.md | 29 +++ dot_claude/rules/golang/coding-style.md | 32 +++ dot_claude/rules/golang/hooks.md | 17 ++ dot_claude/rules/golang/patterns.md | 45 ++++ dot_claude/rules/golang/security.md | 34 +++ dot_claude/rules/golang/testing.md | 31 +++ dot_claude/rules/typescript/coding-style.md | 65 +++++ dot_claude/rules/typescript/hooks.md | 22 ++ dot_claude/rules/typescript/patterns.md | 52 ++++ dot_claude/rules/typescript/security.md | 28 +++ dot_claude/rules/typescript/testing.md | 18 ++ dot_config/gh/private_config.yml | 27 +++ dot_config/ghostty/config | 30 +++ dot_config/private_htop/private_htoprc | 53 +++++ dot_config/private_starship.toml | 41 ++++ .../private_flavor.toml | 225 ++++++++++++++++++ .../private_flavor.toml | 225 ++++++++++++++++++ dot_config/private_yazi/private_keymap.toml | 8 + dot_config/private_yazi/private_theme.toml | 11 + dot_config/private_yazi/private_yazi.toml | 11 + dot_gitconfig.tmpl | 18 ++ dot_npmrc.tmpl | 2 + dot_zprofile | 7 + dot_zshenv | 3 + dot_zshrc | 148 ++++++++++++ justfile | 44 ++++ packages/Brewfile | 184 ++++++++++++++ packages/devbox.global.json | 14 ++ secrets/env.enc.yaml | 23 ++ symlink_dot_tmux.conf | 1 + 52 files changed, 2327 insertions(+) create mode 100644 .chezmoi.toml.tmpl create mode 100644 .chezmoiignore create mode 100644 .chezmoiscripts/run_onchange_before_10-install-packages.sh.tmpl create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 .sops.yaml create mode 100644 CLAUDE.md create mode 100644 PLAN.md create mode 100644 dot_claude/CLAUDE.md create mode 100644 dot_claude/mcp.json create mode 100644 dot_claude/private_RTK.md create mode 100644 dot_claude/private_settings.json create mode 100644 dot_claude/rules/common/agents.md create mode 100644 dot_claude/rules/common/coding-style.md create mode 100644 dot_claude/rules/common/development-workflow.md create mode 100644 dot_claude/rules/common/git-workflow.md create mode 100644 dot_claude/rules/common/hooks.md create mode 100644 dot_claude/rules/common/patterns.md create mode 100644 dot_claude/rules/common/performance.md create mode 100644 dot_claude/rules/common/security.md create mode 100644 dot_claude/rules/common/testing.md create mode 100644 dot_claude/rules/golang/coding-style.md create mode 100644 dot_claude/rules/golang/hooks.md create mode 100644 dot_claude/rules/golang/patterns.md create mode 100644 dot_claude/rules/golang/security.md create mode 100644 dot_claude/rules/golang/testing.md create mode 100644 dot_claude/rules/typescript/coding-style.md create mode 100644 dot_claude/rules/typescript/hooks.md create mode 100644 dot_claude/rules/typescript/patterns.md create mode 100644 dot_claude/rules/typescript/security.md create mode 100644 dot_claude/rules/typescript/testing.md create mode 100644 dot_config/gh/private_config.yml create mode 100644 dot_config/ghostty/config create mode 100644 dot_config/private_htop/private_htoprc create mode 100644 dot_config/private_starship.toml create mode 100644 dot_config/private_yazi/private_flavors/private_kaku-dark.yazi/private_flavor.toml create mode 100644 dot_config/private_yazi/private_flavors/private_kaku-light.yazi/private_flavor.toml create mode 100644 dot_config/private_yazi/private_keymap.toml create mode 100644 dot_config/private_yazi/private_theme.toml create mode 100644 dot_config/private_yazi/private_yazi.toml create mode 100644 dot_gitconfig.tmpl create mode 100644 dot_npmrc.tmpl create mode 100644 dot_zprofile create mode 100644 dot_zshenv create mode 100644 dot_zshrc create mode 100644 justfile create mode 100644 packages/Brewfile create mode 100644 packages/devbox.global.json create mode 100644 secrets/env.enc.yaml create mode 100644 symlink_dot_tmux.conf diff --git a/.chezmoi.toml.tmpl b/.chezmoi.toml.tmpl new file mode 100644 index 0000000..2e58364 --- /dev/null +++ b/.chezmoi.toml.tmpl @@ -0,0 +1,10 @@ +{{- /* Runs on `chezmoi init` on a fresh machine. Prompts once, writes chezmoi.toml. */ -}} +{{- $name := promptStringOnce . "name" "Full name" -}} +{{- $email := promptStringOnce . "email" "Git email" -}} +{{- $isWork := promptBoolOnce . "isWork" "Is this a work machine" -}} +sourceDir = {{ .chezmoi.sourceDir | quote }} + +[data] + name = {{ $name | quote }} + email = {{ $email | quote }} + isWork = {{ $isWork }} diff --git a/.chezmoiignore b/.chezmoiignore new file mode 100644 index 0000000..ecc0e8a --- /dev/null +++ b/.chezmoiignore @@ -0,0 +1,7 @@ +# Repo-meta files that must NOT be deployed into $HOME by `chezmoi apply`. +README.md +PLAN.md +CLAUDE.md +justfile +packages/** +secrets/** diff --git a/.chezmoiscripts/run_onchange_before_10-install-packages.sh.tmpl b/.chezmoiscripts/run_onchange_before_10-install-packages.sh.tmpl new file mode 100644 index 0000000..59fc663 --- /dev/null +++ b/.chezmoiscripts/run_onchange_before_10-install-packages.sh.tmpl @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# Re-runs whenever the package manifests change (hashes below). +# Brewfile hash: {{ include "packages/Brewfile" | sha256sum }} +# devbox hash: {{ include "packages/devbox.global.json" | sha256sum }} +set -euo pipefail + +SRC="{{ .chezmoi.sourceDir }}" + +log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; } + +# --- Homebrew --- +if ! command -v brew >/dev/null 2>&1; then + log "Installing Homebrew" + NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +fi +eval "$(/opt/homebrew/bin/brew shellenv 2>/dev/null || /usr/local/bin/brew shellenv)" + +log "brew bundle (Brewfile)" +brew bundle --file="$SRC/packages/Brewfile" + +# --- oh-my-zsh --- +if [ ! -d "$HOME/.oh-my-zsh" ]; then + log "Installing oh-my-zsh" + RUNZSH=no KEEP_ZSHRC=yes sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" +fi + +# --- devbox global --- +if command -v devbox >/dev/null 2>&1; then + log "Syncing devbox global profile" + mkdir -p "$HOME/.local/share/devbox/global/default" + cp "$SRC/packages/devbox.global.json" "$HOME/.local/share/devbox/global/default/devbox.json" + devbox global install || true +fi + +# --- node via nvm (LTS + repo's pinned version if present) --- +export NVM_DIR="$HOME/.nvm" +if [ -s "$NVM_DIR/nvm.sh" ]; then + # shellcheck disable=SC1091 + . "$NVM_DIR/nvm.sh" + nvm install --lts >/dev/null 2>&1 || true +fi + +# --- tmux plugin manager --- +if [ ! -d "$HOME/.tmux/plugins/tpm" ]; then + log "Installing tmux TPM" + git clone --depth 1 https://github.com/tmux-plugins/tpm "$HOME/.tmux/plugins/tpm" +fi + +log "Package bootstrap complete." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b1546c3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +name: dotfiles-ci + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + secrets-scan: + name: gitleaks (no plaintext secrets) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: gitleaks/gitleaks-action@v2 + + validate: + name: chezmoi apply --dry-run + runs-on: ubuntu-latest + # Full render needs to decrypt sops secrets. Add repo secret SOPS_AGE_KEY + # (contents of ~/.config/sops/age/keys.txt) to enable this job. + if: ${{ secrets.SOPS_AGE_KEY != '' }} + steps: + - uses: actions/checkout@v4 + - name: Install chezmoi, sops, age + run: | + sh -c "$(curl -fsLS get.chezmoi.io)" -- -b "$HOME/.local/bin" + sudo apt-get update && sudo apt-get install -y age + curl -fsSL -o /usr/local/bin/sops https://github.com/getsops/sops/releases/download/v3.8.1/sops-v3.8.1.linux.amd64 + sudo chmod +x /usr/local/bin/sops + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + - name: Restore age key + env: + SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }} + run: | + mkdir -p "$HOME/.config/sops/age" + printf '%s\n' "$SOPS_AGE_KEY" > "$HOME/.config/sops/age/keys.txt" + - name: Write chezmoi config (non-interactive) + run: | + mkdir -p "$HOME/.config/chezmoi" + cat > "$HOME/.config/chezmoi/chezmoi.toml" <20 lines output) +Bash is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands. +For everything else, use: +- `ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call +- `ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context + +### Read (for analysis) +If you are reading a file to **Edit** it → Read is correct (Edit needs content in context). +If you are reading to **analyze, explore, or summarize** → use `ctx_execute_file(path, language, code)` instead. Only your printed summary enters context. The raw file content stays in the sandbox. + +### Grep (large results) +Grep results can flood context. Use `ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context. + +## Tool selection hierarchy + +1. **GATHER**: `ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls. +2. **FOLLOW-UP**: `ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call. +3. **PROCESSING**: `ctx_execute(language, code)` | `ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context. +4. **WEB**: `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context. +5. **INDEX**: `ctx_index(content, source)` — Store content in FTS5 knowledge base for later search. + +## Subagent routing + +When spawning subagents (Agent/Task tool), the routing block is automatically injected into their prompt. Bash-type subagents are upgraded to general-purpose so they have access to MCP tools. You do NOT need to manually instruct subagents about context-mode. + +## Output constraints + +- Keep responses under 500 words. +- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description. +- When indexing content, use descriptive source labels so others can `ctx_search(source: "label")` later. + +## ctx commands + +| Command | Action | +|---------|--------| +| `ctx stats` | Call the `ctx_stats` MCP tool and display the full output verbatim | +| `ctx doctor` | Call the `ctx_doctor` MCP tool, run the returned shell command, display as checklist | +| `ctx upgrade` | Call the `ctx_upgrade` MCP tool, run the returned shell command, display as checklist | diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..3b88192 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,75 @@ +# Senior-Grade Dotfiles — Build Plan + +**Stack:** chezmoi (source dir = this repo) + sops/age for secrets. Target: one-command +bootstrap on a fresh Mac, zero secrets in git, per-machine templating. + +Audited machine state: zsh + oh-my-zsh + starship, nvim, tmux, ghostty/iterm2/wave, +yazi, lazygit; devbox(global) + colima; nvm→node24, bun, pnpm, go(devbox), pyenv/chruby; +~80 brew leaves + casks; heavy `~/.claude`. Repo currently empty. + +--- + +## Phase 0 — Security first (do before ANY commit) +- [ ] **Revoke** the `gho_…` token found in `~/.gitconfig` (GitHub → Settings → Developer settings → revoke). +- [ ] Remove the `url.https://x-access-token:…insteadOf` line from `~/.gitconfig`; keep the `gh` credential helper you already have. +- [ ] Generate age key: `age-keygen -o ~/.config/sops/age/keys.txt` (this file is **never** committed). +- [ ] Add repo-root `.sops.yaml` binding the age recipient; add `.gitignore` for `*.key`, `keys.txt`, `.env`, `*_history`. + +## Phase 1 — Wire chezmoi to THIS repo +- [ ] `chezmoi init --source /Users/antono/workspace/dotfiles` (repo becomes the source tree). +- [ ] Create `.chezmoi.toml.tmpl` with machine vars: `{ email, name, isWork, hostname }` — prompts on first apply. +- [ ] Add `README.md` one-liner bootstrap: + `sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply ` + (⚠️ sandbox blocks curl here — this line is for the fresh-machine README only.) + +## Phase 2 — Migrate configs (managed = `chezmoi add`) +Bring in incrementally, templatize the machine-specific bits: +- [ ] `dot_zshrc.tmpl` — split into `dot_config/zsh/` fragments (aliases, exports, path, tool-init); keep `.zshrc` thin. Guard oh-my-zsh vs starship. +- [ ] `dot_gitconfig.tmpl` — templatize `user.email`/signing per `.isWork`; **no tokens**; personal-vs-work `insteadOf` via includeIf. +- [ ] `private_dot_config/` — starship.toml, ghostty, yazi, htop, lazygit, gh, atlassian-cli. +- [ ] `dot_zshenv`, `dot_zprofile`, `dot_tmux.conf`, nvim (`private_dot_config/nvim` or reference existing). +- [ ] `~/.claude/{settings.json,CLAUDE.md,rules,agents,commands}` — managed; **exclude** `history.jsonl`, `sessions`, `cache`, `*.bak`, `security_warnings_*`, `mcp-needs-auth-cache.json`. + +## Phase 3 — Reproducible packages (idempotent) +- [ ] `run_once_before_10-install-packages.sh.tmpl`: + - `Brewfile` from `brew bundle dump` (leaves + casks) → `brew bundle`. + - devbox global: commit `~/.local/share/devbox/global/default/devbox.json`, `devbox global install`. + - nvm + `.nvmrc` (node 24), bun, pnpm via corepack. +- [ ] `run_once_after_*` for oh-my-zsh install + tmux TPM if missing. + +## Phase 4 — Secrets via sops/age +- [ ] `secrets/env.enc.yaml` (committed, encrypted): github_token, npm authToken, any API keys. +- [ ] Template consumes them at apply: e.g. `~/.npmrc.tmpl`, `dot_config/zsh/secrets.zsh.tmpl` using `{{ (index (fromYaml (decrypt (include "secrets/env.enc.yaml"))) "github_token") }}`. +- [ ] Verify a plaintext secret NEVER appears in `chezmoi cat` diff of a committed file. + +## Phase 5 — Quality gates (the "senior" signal) +- [ ] `.github/workflows/ci.yml`: `shellcheck` all scripts, `chezmoi verify`, dry-run `chezmoi apply --dry-run` on a clean runner. +- [ ] `pre-commit`: gitleaks/trufflehog scan so no secret can be committed even by accident. +- [ ] `Makefile` / `justfile`: `apply`, `diff`, `update`, `edit`, `lint`, `bootstrap`. +- [ ] `README.md`: fresh-machine setup, structure map, how secrets work. +- [ ] Optional: test bootstrap in a throwaway colima/UTM VM before trusting it. + +--- + +## Suggested repo layout +``` +dotfiles/ + .chezmoi.toml.tmpl # machine vars (prompted) + .sops.yaml .gitignore + dot_zshrc.tmpl dot_zshenv dot_zprofile dot_gitconfig.tmpl dot_tmux.conf + private_dot_config/ + zsh/{aliases,exports,path,init,secrets.zsh.tmpl} + starship.toml ghostty/ yazi/ htop/ lazygit/ gh/ nvim/ + private_dot_claude/ # settings, rules, agents, commands (no state) + secrets/env.enc.yaml # sops-encrypted, safe to push + .chezmoiscripts/ + run_once_before_10-install-packages.sh.tmpl + Brewfile devbox.global.json + .github/workflows/ci.yml + justfile README.md +``` + +## Sequencing +Phase 0 today (security). Then 1→2 in small commits (one config group per commit, +`chezmoi diff` before each). 3–4 once shell/git are stable. 5 last. Each phase is +independently verifiable — never a big-bang migration. diff --git a/README.md b/README.md index 96bf7ed..61b7fd1 100644 --- a/README.md +++ b/README.md @@ -1 +1,75 @@ # dotfiles + +Senior-grade, reproducible macOS dev environment managed with +[chezmoi](https://chezmoi.io) + [sops](https://github.com/getsops/sops)/[age](https://github.com/FiloSottile/age). + +For an AI-native fullstack stack: React/TypeScript · Go · Postgres · devbox + colima · Claude Code. + +## Principles + +- **One command** rebuilds a machine from scratch. +- **Zero secrets in git** — everything sensitive is sops-encrypted or gh-helper-injected. +- **Per-machine** differences handled by templates, not forks. +- **Tested** — CI dry-runs `chezmoi apply` and gitleaks-scans every push. + +## Fresh machine + +```sh +# 1. install + apply dotfiles (installs chezmoi, prompts for name/email/work-flag) +sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply + +# 2. restore the age private key (from your password manager / backup) so secrets decrypt +mkdir -p ~/.config/sops/age +cp /path/to/backup/keys.txt ~/.config/sops/age/keys.txt && chmod 600 ~/.config/sops/age/keys.txt + +# 3. re-apply now that secrets can decrypt +chezmoi apply +``` + +The `run_onchange_*` bootstrap script installs Homebrew + the `Brewfile`, oh-my-zsh, +the devbox global profile, node (nvm), and tmux TPM. + +## Daily use + +```sh +just diff # preview changes before applying +just apply # apply source -> $HOME +just edit ~/.zshrc # edit a managed file +just add ~/.config/foo # capture a new dotfile +just secrets # edit the encrypted secret store +just freeze-packages # re-snapshot Brewfile + devbox after installing something +just update # git pull + apply +``` + +## Secrets (sops + age) + +- Encrypted store: `secrets/env.enc.yaml` (safe to commit — values are AES-encrypted). +- Private key: `~/.config/sops/age/keys.txt` — **never** committed; back it up in your password manager. +- Policy: `.sops.yaml`. Templates read secrets at apply time, e.g. `dot_npmrc.tmpl`. + +To enable the CI apply-dry-run, add the age private key as repo secret `SOPS_AGE_KEY`. + +## Layout + +``` +.chezmoi.toml.tmpl machine vars (prompted on init) +.sops.yaml .gitignore .chezmoiignore +dot_zshrc dot_zshenv dot_zprofile shell +dot_gitconfig.tmpl git identity (templated, no tokens) +dot_npmrc.tmpl npm auth (from sops) +dot_config/ starship, ghostty, yazi, htop, gh +dot_claude/ Claude Code settings + rules (go/ts/common) +secrets/env.enc.yaml sops-encrypted secrets +packages/Brewfile devbox.global.json reproducible package sets +.chezmoiscripts/run_onchange_* idempotent bootstrap +.github/workflows/ci.yml gitleaks + apply dry-run +justfile task runner +``` + +## Security note + +If a token ever lands in git history, revoke it immediately — history is permanent. +The gitleaks pre-commit hook + CI job exist to make that near-impossible. +```sh +pre-commit install # enable the local secret gate +``` diff --git a/dot_claude/CLAUDE.md b/dot_claude/CLAUDE.md new file mode 100644 index 0000000..37006e9 --- /dev/null +++ b/dot_claude/CLAUDE.md @@ -0,0 +1,6 @@ +@RTK.md + +# Ruflo Integration (auto-generated by ruflo init) +When working on multi-file tasks or complex features, use ToolSearch to find and invoke ruflo MCP tools. +Key tools: memory_store, memory_search, hooks_route, swarm_init, agent_spawn. +Check system-reminder tags for [INTELLIGENCE] pattern suggestions before starting work. diff --git a/dot_claude/mcp.json b/dot_claude/mcp.json new file mode 100644 index 0000000..555b459 --- /dev/null +++ b/dot_claude/mcp.json @@ -0,0 +1,13 @@ +{ + "mcpServers": { + "tolaria": { + "args": [ + "/Applications/Tolaria.app/Contents/Resources/mcp-server/index.js" + ], + "command": "node", + "env": { + "VAULT_PATH": "/Users/antono/Documents/second_brain" + } + } + } +} \ No newline at end of file diff --git a/dot_claude/private_RTK.md b/dot_claude/private_RTK.md new file mode 100644 index 0000000..0eaf3d5 --- /dev/null +++ b/dot_claude/private_RTK.md @@ -0,0 +1,29 @@ +# RTK - Rust Token Killer + +**Usage**: Token-optimized CLI proxy (60-90% savings on dev operations) + +## Meta Commands (always use rtk directly) + +```bash +rtk gain # Show token savings analytics +rtk gain --history # Show command usage history with savings +rtk discover # Analyze Claude Code history for missed opportunities +rtk proxy # Execute raw command without filtering (for debugging) +``` + +## Installation Verification + +```bash +rtk --version # Should show: rtk X.Y.Z +rtk gain # Should work (not "command not found") +which rtk # Verify correct binary +``` + +⚠️ **Name collision**: If `rtk gain` fails, you may have reachingforthejack/rtk (Rust Type Kit) installed instead. + +## Hook-Based Usage + +All other commands are automatically rewritten by the Claude Code hook. +Example: `git status` → `rtk git status` (transparent, 0 tokens overhead) + +Refer to CLAUDE.md for full command reference. diff --git a/dot_claude/private_settings.json b/dot_claude/private_settings.json new file mode 100644 index 0000000..f21c4b3 --- /dev/null +++ b/dot_claude/private_settings.json @@ -0,0 +1,153 @@ +{ + "$schema": "https://json.schemastore.org/claude-code-settings.json", + "env": { + "MAX_THINKING_TOKENS": "10000", + "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "50" + }, + "permissions": { + "allow": [ + "Bash(dev-browser *)" + ] + }, + "model": "opus", + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "node \"/Users/antono/.claude/hooks/gsd-check-update.js\"" + } + ] + } + ], + "PostToolUse": [ + { + "matcher": "Bash|Edit|Write|MultiEdit|Agent|Task", + "hooks": [ + { + "type": "command", + "command": "node \"/Users/antono/.claude/hooks/gsd-context-monitor.js\"", + "timeout": 10 + } + ] + } + ], + "PreToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "node \"/Users/antono/.claude/hooks/gsd-prompt-guard.js\"", + "timeout": 5 + } + ] + }, + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "rtk hook claude" + } + ] + } + ] + }, + "statusLine": { + "type": "command", + "command": "bash \"$HOME/.claude/statusline.sh\"" + }, + "enabledPlugins": { + "github@claude-plugins-official": false, + "claude-md-management@claude-plugins-official": true, + "figma@claude-plugins-official": true, + "hookify@claude-plugins-official": true, + "gopls-lsp@claude-plugins-official": true, + "typescript-lsp@claude-plugins-official": true, + "commit-commands@claude-plugins-official": true, + "claude-code-setup@claude-plugins-official": true, + "frontend-design@claude-plugins-official": true, + "context-mode@context-mode": true, + "code-review@claude-plugins-official": false, + "superpowers@claude-plugins-official": true, + "feature-dev@claude-plugins-official": false, + "security-guidance@claude-plugins-official": true, + "engineering-advanced-skills@claude-code-skills": false, + "engineering-skills@claude-code-skills": false, + "code-simplifier@claude-plugins-official": false, + "deep-plan@piercelamb-plugins": false, + "context7@claude-plugins-official": true, + "playwright@claude-plugins-official": false, + "skill-creator@claude-plugins-official": true, + "ralph-loop@claude-plugins-official": true, + "pr-review-toolkit@claude-plugins-official": true, + "agent-sdk-dev@claude-plugins-official": true, + "greptile@claude-plugins-official": false, + "chrome-devtools-mcp@claude-plugins-official": false, + "supabase@claude-plugins-official": true, + "claude-mem@thedotmack": true, + "vercel-plugin@vercel": true, + "agent-skills@addy-agent-skills": true, + "vercel@claude-plugins-official": true, + "ponytail@ponytail": true + }, + "extraKnownMarketplaces": { + "everything-claude-code": { + "source": { + "source": "github", + "repo": "affaan-m/everything-claude-code" + } + }, + "edmunds-claude-code": { + "source": { + "source": "github", + "repo": "edmund-io/edmunds-claude-code" + } + }, + "context-mode": { + "source": { + "source": "github", + "repo": "mksglu/context-mode" + } + }, + "claude-code-skills": { + "source": { + "source": "github", + "repo": "alirezarezvani/claude-skills" + } + }, + "piercelamb-plugins": { + "source": { + "source": "github", + "repo": "piercelamb/deep-plan" + } + }, + "thedotmack": { + "source": { + "source": "github", + "repo": "thedotmack/claude-mem" + } + }, + "addy-agent-skills": { + "source": { + "source": "github", + "repo": "addyosmani/agent-skills" + } + }, + "ponytail": { + "source": { + "source": "github", + "repo": "DietrichGebert/ponytail" + } + } + }, + "tui": "fullscreen", + "skipWorkflowUsageWarning": true, + "preferredNotifChannel": "terminal_bell", + "skipAutoPermissionPrompt": true, + "feedbackSurveyState": { + "lastShownTime": 1754474368574 + } +} diff --git a/dot_claude/rules/common/agents.md b/dot_claude/rules/common/agents.md new file mode 100644 index 0000000..e284331 --- /dev/null +++ b/dot_claude/rules/common/agents.md @@ -0,0 +1,49 @@ +# Agent Orchestration + +## Available Agents + +Located in `~/.claude/agents/`: + +| Agent | Purpose | When to Use | +|-------|---------|-------------| +| planner | Implementation planning | Complex features, refactoring | +| architect | System design | Architectural decisions | +| tdd-guide | Test-driven development | New features, bug fixes | +| code-reviewer | Code review | After writing code | +| security-reviewer | Security analysis | Before commits | +| build-error-resolver | Fix build errors | When build fails | +| e2e-runner | E2E testing | Critical user flows | +| refactor-cleaner | Dead code cleanup | Code maintenance | +| doc-updater | Documentation | Updating docs | + +## Immediate Agent Usage + +No user prompt needed: +1. Complex feature requests - Use **planner** agent +2. Code just written/modified - Use **code-reviewer** agent +3. Bug fix or new feature - Use **tdd-guide** agent +4. Architectural decision - Use **architect** agent + +## Parallel Task Execution + +ALWAYS use parallel Task execution for independent operations: + +```markdown +# GOOD: Parallel execution +Launch 3 agents in parallel: +1. Agent 1: Security analysis of auth module +2. Agent 2: Performance review of cache system +3. Agent 3: Type checking of utilities + +# BAD: Sequential when unnecessary +First agent 1, then agent 2, then agent 3 +``` + +## Multi-Perspective Analysis + +For complex problems, use split role sub-agents: +- Factual reviewer +- Senior engineer +- Security expert +- Consistency reviewer +- Redundancy checker diff --git a/dot_claude/rules/common/coding-style.md b/dot_claude/rules/common/coding-style.md new file mode 100644 index 0000000..2ee4fde --- /dev/null +++ b/dot_claude/rules/common/coding-style.md @@ -0,0 +1,48 @@ +# Coding Style + +## Immutability (CRITICAL) + +ALWAYS create new objects, NEVER mutate existing ones: + +``` +// Pseudocode +WRONG: modify(original, field, value) → changes original in-place +CORRECT: update(original, field, value) → returns new copy with change +``` + +Rationale: Immutable data prevents hidden side effects, makes debugging easier, and enables safe concurrency. + +## File Organization + +MANY SMALL FILES > FEW LARGE FILES: +- High cohesion, low coupling +- 200-400 lines typical, 800 max +- Extract utilities from large modules +- Organize by feature/domain, not by type + +## Error Handling + +ALWAYS handle errors comprehensively: +- Handle errors explicitly at every level +- Provide user-friendly error messages in UI-facing code +- Log detailed error context on the server side +- Never silently swallow errors + +## Input Validation + +ALWAYS validate at system boundaries: +- Validate all user input before processing +- Use schema-based validation where available +- Fail fast with clear error messages +- Never trust external data (API responses, user input, file content) + +## Code Quality Checklist + +Before marking work complete: +- [ ] Code is readable and well-named +- [ ] Functions are small (<50 lines) +- [ ] Files are focused (<800 lines) +- [ ] No deep nesting (>4 levels) +- [ ] Proper error handling +- [ ] No hardcoded values (use constants or config) +- [ ] No mutation (immutable patterns used) diff --git a/dot_claude/rules/common/development-workflow.md b/dot_claude/rules/common/development-workflow.md new file mode 100644 index 0000000..8937279 --- /dev/null +++ b/dot_claude/rules/common/development-workflow.md @@ -0,0 +1,37 @@ +# Development Workflow + +> This file extends [common/git-workflow.md](./git-workflow.md) with the full feature development process that happens before git operations. + +The Feature Implementation Workflow describes the development pipeline: research, planning, TDD, code review, and then committing to git. + +## Feature Implementation Workflow + +0. **Research & Reuse** _(mandatory before any new implementation)_ + - **GitHub code search first:** Run `gh search repos` and `gh search code` to find existing implementations, templates, and patterns before writing anything new. + - **Exa MCP for research:** Use `exa-web-search` MCP during the planning phase for broader research, data ingestion, and discovering prior art. + - **Check package registries:** Search npm, PyPI, crates.io, and other registries before writing utility code. Prefer battle-tested libraries over hand-rolled solutions. + - **Search for adaptable implementations:** Look for open-source projects that solve 80%+ of the problem and can be forked, ported, or wrapped. + - Prefer adopting or porting a proven approach over writing net-new code when it meets the requirement. + +1. **Plan First** + - Use **planner** agent to create implementation plan + - Generate planning docs before coding: PRD, architecture, system_design, tech_doc, task_list + - Identify dependencies and risks + - Break down into phases + +2. **TDD Approach** + - Use **tdd-guide** agent + - Write tests first (RED) + - Implement to pass tests (GREEN) + - Refactor (IMPROVE) + - Verify 80%+ coverage + +3. **Code Review** + - Use **code-reviewer** agent immediately after writing code + - Address CRITICAL and HIGH issues + - Fix MEDIUM issues when possible + +4. **Commit & Push** + - Detailed commit messages + - Follow conventional commits format + - See [git-workflow.md](./git-workflow.md) for commit message format and PR process diff --git a/dot_claude/rules/common/git-workflow.md b/dot_claude/rules/common/git-workflow.md new file mode 100644 index 0000000..d57d9e2 --- /dev/null +++ b/dot_claude/rules/common/git-workflow.md @@ -0,0 +1,24 @@ +# Git Workflow + +## Commit Message Format +``` +: + + +``` + +Types: feat, fix, refactor, docs, test, chore, perf, ci + +Note: Attribution disabled globally via ~/.claude/settings.json. + +## Pull Request Workflow + +When creating PRs: +1. Analyze full commit history (not just latest commit) +2. Use `git diff [base-branch]...HEAD` to see all changes +3. Draft comprehensive PR summary +4. Include test plan with TODOs +5. Push with `-u` flag if new branch + +> For the full development process (planning, TDD, code review) before git operations, +> see [development-workflow.md](./development-workflow.md). diff --git a/dot_claude/rules/common/hooks.md b/dot_claude/rules/common/hooks.md new file mode 100644 index 0000000..5439408 --- /dev/null +++ b/dot_claude/rules/common/hooks.md @@ -0,0 +1,30 @@ +# Hooks System + +## Hook Types + +- **PreToolUse**: Before tool execution (validation, parameter modification) +- **PostToolUse**: After tool execution (auto-format, checks) +- **Stop**: When session ends (final verification) + +## Auto-Accept Permissions + +Use with caution: +- Enable for trusted, well-defined plans +- Disable for exploratory work +- Never use dangerously-skip-permissions flag +- Configure `allowedTools` in `~/.claude.json` instead + +## TodoWrite Best Practices + +Use TodoWrite tool to: +- Track progress on multi-step tasks +- Verify understanding of instructions +- Enable real-time steering +- Show granular implementation steps + +Todo list reveals: +- Out of order steps +- Missing items +- Extra unnecessary items +- Wrong granularity +- Misinterpreted requirements diff --git a/dot_claude/rules/common/patterns.md b/dot_claude/rules/common/patterns.md new file mode 100644 index 0000000..959939f --- /dev/null +++ b/dot_claude/rules/common/patterns.md @@ -0,0 +1,31 @@ +# Common Patterns + +## Skeleton Projects + +When implementing new functionality: +1. Search for battle-tested skeleton projects +2. Use parallel agents to evaluate options: + - Security assessment + - Extensibility analysis + - Relevance scoring + - Implementation planning +3. Clone best match as foundation +4. Iterate within proven structure + +## Design Patterns + +### Repository Pattern + +Encapsulate data access behind a consistent interface: +- Define standard operations: findAll, findById, create, update, delete +- Concrete implementations handle storage details (database, API, file, etc.) +- Business logic depends on the abstract interface, not the storage mechanism +- Enables easy swapping of data sources and simplifies testing with mocks + +### API Response Format + +Use a consistent envelope for all API responses: +- Include a success/status indicator +- Include the data payload (nullable on error) +- Include an error message field (nullable on success) +- Include metadata for paginated responses (total, page, limit) diff --git a/dot_claude/rules/common/performance.md b/dot_claude/rules/common/performance.md new file mode 100644 index 0000000..3ffff1b --- /dev/null +++ b/dot_claude/rules/common/performance.md @@ -0,0 +1,55 @@ +# Performance Optimization + +## Model Selection Strategy + +**Haiku 4.5** (90% of Sonnet capability, 3x cost savings): +- Lightweight agents with frequent invocation +- Pair programming and code generation +- Worker agents in multi-agent systems + +**Sonnet 4.6** (Best coding model): +- Main development work +- Orchestrating multi-agent workflows +- Complex coding tasks + +**Opus 4.5** (Deepest reasoning): +- Complex architectural decisions +- Maximum reasoning requirements +- Research and analysis tasks + +## Context Window Management + +Avoid last 20% of context window for: +- Large-scale refactoring +- Feature implementation spanning multiple files +- Debugging complex interactions + +Lower context sensitivity tasks: +- Single-file edits +- Independent utility creation +- Documentation updates +- Simple bug fixes + +## Extended Thinking + Plan Mode + +Extended thinking is enabled by default, reserving up to 31,999 tokens for internal reasoning. + +Control extended thinking via: +- **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux) +- **Config**: Set `alwaysThinkingEnabled` in `~/.claude/settings.json` +- **Budget cap**: `export MAX_THINKING_TOKENS=10000` +- **Verbose mode**: Ctrl+O to see thinking output + +For complex tasks requiring deep reasoning: +1. Ensure extended thinking is enabled (on by default) +2. Enable **Plan Mode** for structured approach +3. Use multiple critique rounds for thorough analysis +4. Use split role sub-agents for diverse perspectives + +## Build Troubleshooting + +If build fails: +1. Use **build-error-resolver** agent +2. Analyze error messages +3. Fix incrementally +4. Verify after each fix diff --git a/dot_claude/rules/common/security.md b/dot_claude/rules/common/security.md new file mode 100644 index 0000000..49624c0 --- /dev/null +++ b/dot_claude/rules/common/security.md @@ -0,0 +1,29 @@ +# Security Guidelines + +## Mandatory Security Checks + +Before ANY commit: +- [ ] No hardcoded secrets (API keys, passwords, tokens) +- [ ] All user inputs validated +- [ ] SQL injection prevention (parameterized queries) +- [ ] XSS prevention (sanitized HTML) +- [ ] CSRF protection enabled +- [ ] Authentication/authorization verified +- [ ] Rate limiting on all endpoints +- [ ] Error messages don't leak sensitive data + +## Secret Management + +- NEVER hardcode secrets in source code +- ALWAYS use environment variables or a secret manager +- Validate that required secrets are present at startup +- Rotate any secrets that may have been exposed + +## Security Response Protocol + +If security issue found: +1. STOP immediately +2. Use **security-reviewer** agent +3. Fix CRITICAL issues before continuing +4. Rotate any exposed secrets +5. Review entire codebase for similar issues diff --git a/dot_claude/rules/common/testing.md b/dot_claude/rules/common/testing.md new file mode 100644 index 0000000..fdcd949 --- /dev/null +++ b/dot_claude/rules/common/testing.md @@ -0,0 +1,29 @@ +# Testing Requirements + +## Minimum Test Coverage: 80% + +Test Types (ALL required): +1. **Unit Tests** - Individual functions, utilities, components +2. **Integration Tests** - API endpoints, database operations +3. **E2E Tests** - Critical user flows (framework chosen per language) + +## Test-Driven Development + +MANDATORY workflow: +1. Write test first (RED) +2. Run test - it should FAIL +3. Write minimal implementation (GREEN) +4. Run test - it should PASS +5. Refactor (IMPROVE) +6. Verify coverage (80%+) + +## Troubleshooting Test Failures + +1. Use **tdd-guide** agent +2. Check test isolation +3. Verify mocks are correct +4. Fix implementation, not tests (unless tests are wrong) + +## Agent Support + +- **tdd-guide** - Use PROACTIVELY for new features, enforces write-tests-first diff --git a/dot_claude/rules/golang/coding-style.md b/dot_claude/rules/golang/coding-style.md new file mode 100644 index 0000000..d7d6c31 --- /dev/null +++ b/dot_claude/rules/golang/coding-style.md @@ -0,0 +1,32 @@ +--- +paths: + - "**/*.go" + - "**/go.mod" + - "**/go.sum" +--- +# Go Coding Style + +> This file extends [common/coding-style.md](../common/coding-style.md) with Go specific content. + +## Formatting + +- **gofmt** and **goimports** are mandatory — no style debates + +## Design Principles + +- Accept interfaces, return structs +- Keep interfaces small (1-3 methods) + +## Error Handling + +Always wrap errors with context: + +```go +if err != nil { + return fmt.Errorf("failed to create user: %w", err) +} +``` + +## Reference + +See skill: `golang-patterns` for comprehensive Go idioms and patterns. diff --git a/dot_claude/rules/golang/hooks.md b/dot_claude/rules/golang/hooks.md new file mode 100644 index 0000000..f05e4ad --- /dev/null +++ b/dot_claude/rules/golang/hooks.md @@ -0,0 +1,17 @@ +--- +paths: + - "**/*.go" + - "**/go.mod" + - "**/go.sum" +--- +# Go Hooks + +> This file extends [common/hooks.md](../common/hooks.md) with Go specific content. + +## PostToolUse Hooks + +Configure in `~/.claude/settings.json`: + +- **gofmt/goimports**: Auto-format `.go` files after edit +- **go vet**: Run static analysis after editing `.go` files +- **staticcheck**: Run extended static checks on modified packages diff --git a/dot_claude/rules/golang/patterns.md b/dot_claude/rules/golang/patterns.md new file mode 100644 index 0000000..ba28dba --- /dev/null +++ b/dot_claude/rules/golang/patterns.md @@ -0,0 +1,45 @@ +--- +paths: + - "**/*.go" + - "**/go.mod" + - "**/go.sum" +--- +# Go Patterns + +> This file extends [common/patterns.md](../common/patterns.md) with Go specific content. + +## Functional Options + +```go +type Option func(*Server) + +func WithPort(port int) Option { + return func(s *Server) { s.port = port } +} + +func NewServer(opts ...Option) *Server { + s := &Server{port: 8080} + for _, opt := range opts { + opt(s) + } + return s +} +``` + +## Small Interfaces + +Define interfaces where they are used, not where they are implemented. + +## Dependency Injection + +Use constructor functions to inject dependencies: + +```go +func NewUserService(repo UserRepository, logger Logger) *UserService { + return &UserService{repo: repo, logger: logger} +} +``` + +## Reference + +See skill: `golang-patterns` for comprehensive Go patterns including concurrency, error handling, and package organization. diff --git a/dot_claude/rules/golang/security.md b/dot_claude/rules/golang/security.md new file mode 100644 index 0000000..372b754 --- /dev/null +++ b/dot_claude/rules/golang/security.md @@ -0,0 +1,34 @@ +--- +paths: + - "**/*.go" + - "**/go.mod" + - "**/go.sum" +--- +# Go Security + +> This file extends [common/security.md](../common/security.md) with Go specific content. + +## Secret Management + +```go +apiKey := os.Getenv("OPENAI_API_KEY") +if apiKey == "" { + log.Fatal("OPENAI_API_KEY not configured") +} +``` + +## Security Scanning + +- Use **gosec** for static security analysis: + ```bash + gosec ./... + ``` + +## Context & Timeouts + +Always use `context.Context` for timeout control: + +```go +ctx, cancel := context.WithTimeout(ctx, 5*time.Second) +defer cancel() +``` diff --git a/dot_claude/rules/golang/testing.md b/dot_claude/rules/golang/testing.md new file mode 100644 index 0000000..6b80022 --- /dev/null +++ b/dot_claude/rules/golang/testing.md @@ -0,0 +1,31 @@ +--- +paths: + - "**/*.go" + - "**/go.mod" + - "**/go.sum" +--- +# Go Testing + +> This file extends [common/testing.md](../common/testing.md) with Go specific content. + +## Framework + +Use the standard `go test` with **table-driven tests**. + +## Race Detection + +Always run with the `-race` flag: + +```bash +go test -race ./... +``` + +## Coverage + +```bash +go test -cover ./... +``` + +## Reference + +See skill: `golang-testing` for detailed Go testing patterns and helpers. diff --git a/dot_claude/rules/typescript/coding-style.md b/dot_claude/rules/typescript/coding-style.md new file mode 100644 index 0000000..db62a9b --- /dev/null +++ b/dot_claude/rules/typescript/coding-style.md @@ -0,0 +1,65 @@ +--- +paths: + - "**/*.ts" + - "**/*.tsx" + - "**/*.js" + - "**/*.jsx" +--- +# TypeScript/JavaScript Coding Style + +> This file extends [common/coding-style.md](../common/coding-style.md) with TypeScript/JavaScript specific content. + +## Immutability + +Use spread operator for immutable updates: + +```typescript +// WRONG: Mutation +function updateUser(user, name) { + user.name = name // MUTATION! + return user +} + +// CORRECT: Immutability +function updateUser(user, name) { + return { + ...user, + name + } +} +``` + +## Error Handling + +Use async/await with try-catch: + +```typescript +try { + const result = await riskyOperation() + return result +} catch (error) { + console.error('Operation failed:', error) + throw new Error('Detailed user-friendly message') +} +``` + +## Input Validation + +Use Zod for schema-based validation: + +```typescript +import { z } from 'zod' + +const schema = z.object({ + email: z.string().email(), + age: z.number().int().min(0).max(150) +}) + +const validated = schema.parse(input) +``` + +## Console.log + +- No `console.log` statements in production code +- Use proper logging libraries instead +- See hooks for automatic detection diff --git a/dot_claude/rules/typescript/hooks.md b/dot_claude/rules/typescript/hooks.md new file mode 100644 index 0000000..cd4754b --- /dev/null +++ b/dot_claude/rules/typescript/hooks.md @@ -0,0 +1,22 @@ +--- +paths: + - "**/*.ts" + - "**/*.tsx" + - "**/*.js" + - "**/*.jsx" +--- +# TypeScript/JavaScript Hooks + +> This file extends [common/hooks.md](../common/hooks.md) with TypeScript/JavaScript specific content. + +## PostToolUse Hooks + +Configure in `~/.claude/settings.json`: + +- **Prettier**: Auto-format JS/TS files after edit +- **TypeScript check**: Run `tsc` after editing `.ts`/`.tsx` files +- **console.log warning**: Warn about `console.log` in edited files + +## Stop Hooks + +- **console.log audit**: Check all modified files for `console.log` before session ends diff --git a/dot_claude/rules/typescript/patterns.md b/dot_claude/rules/typescript/patterns.md new file mode 100644 index 0000000..d50729d --- /dev/null +++ b/dot_claude/rules/typescript/patterns.md @@ -0,0 +1,52 @@ +--- +paths: + - "**/*.ts" + - "**/*.tsx" + - "**/*.js" + - "**/*.jsx" +--- +# TypeScript/JavaScript Patterns + +> This file extends [common/patterns.md](../common/patterns.md) with TypeScript/JavaScript specific content. + +## API Response Format + +```typescript +interface ApiResponse { + success: boolean + data?: T + error?: string + meta?: { + total: number + page: number + limit: number + } +} +``` + +## Custom Hooks Pattern + +```typescript +export function useDebounce(value: T, delay: number): T { + const [debouncedValue, setDebouncedValue] = useState(value) + + useEffect(() => { + const handler = setTimeout(() => setDebouncedValue(value), delay) + return () => clearTimeout(handler) + }, [value, delay]) + + return debouncedValue +} +``` + +## Repository Pattern + +```typescript +interface Repository { + findAll(filters?: Filters): Promise + findById(id: string): Promise + create(data: CreateDto): Promise + update(id: string, data: UpdateDto): Promise + delete(id: string): Promise +} +``` diff --git a/dot_claude/rules/typescript/security.md b/dot_claude/rules/typescript/security.md new file mode 100644 index 0000000..98ba400 --- /dev/null +++ b/dot_claude/rules/typescript/security.md @@ -0,0 +1,28 @@ +--- +paths: + - "**/*.ts" + - "**/*.tsx" + - "**/*.js" + - "**/*.jsx" +--- +# TypeScript/JavaScript Security + +> This file extends [common/security.md](../common/security.md) with TypeScript/JavaScript specific content. + +## Secret Management + +```typescript +// NEVER: Hardcoded secrets +const apiKey = "sk-proj-xxxxx" + +// ALWAYS: Environment variables +const apiKey = process.env.OPENAI_API_KEY + +if (!apiKey) { + throw new Error('OPENAI_API_KEY not configured') +} +``` + +## Agent Support + +- Use **security-reviewer** skill for comprehensive security audits diff --git a/dot_claude/rules/typescript/testing.md b/dot_claude/rules/typescript/testing.md new file mode 100644 index 0000000..6f2f402 --- /dev/null +++ b/dot_claude/rules/typescript/testing.md @@ -0,0 +1,18 @@ +--- +paths: + - "**/*.ts" + - "**/*.tsx" + - "**/*.js" + - "**/*.jsx" +--- +# TypeScript/JavaScript Testing + +> This file extends [common/testing.md](../common/testing.md) with TypeScript/JavaScript specific content. + +## E2E Testing + +Use **Playwright** as the E2E testing framework for critical user flows. + +## Agent Support + +- **e2e-runner** - Playwright E2E testing specialist diff --git a/dot_config/gh/private_config.yml b/dot_config/gh/private_config.yml new file mode 100644 index 0000000..8b25011 --- /dev/null +++ b/dot_config/gh/private_config.yml @@ -0,0 +1,27 @@ +# The current version of the config schema +version: 1 +# What protocol to use when performing git operations. Supported values: ssh, https +git_protocol: https +# What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment. +editor: +# When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled +prompt: enabled +# Preference for editor-based interactive prompting. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled +prefer_editor_prompt: disabled +# A pager program to send command output to, e.g. "less". If blank, will refer to environment. Set the value to "cat" to disable the pager. +pager: +# Aliases allow you to create nicknames for gh commands +aliases: + co: pr checkout +# The path to a unix socket through which to send HTTP connections. If blank, HTTP traffic will be handled by net/http.DefaultTransport. +http_unix_socket: +# What web browser gh should use when opening URLs. If blank, will refer to environment. +browser: +# Whether to display labels using their RGB hex color codes in terminals that support truecolor. Supported values: enabled, disabled +color_labels: disabled +# Whether customizable, 4-bit accessible colors should be used. Supported values: enabled, disabled +accessible_colors: disabled +# Whether an accessible prompter should be used. Supported values: enabled, disabled +accessible_prompter: disabled +# Whether to use a animated spinner as a progress indicator. If disabled, a textual progress indicator is used instead. Supported values: enabled, disabled +spinner: enabled diff --git a/dot_config/ghostty/config b/dot_config/ghostty/config new file mode 100644 index 0000000..85b37fc --- /dev/null +++ b/dot_config/ghostty/config @@ -0,0 +1,30 @@ +font-family = JetBrainsMono Nerd Font +font-size = 16 +font-thicken = true + +# Theme (or use individual colors below) +theme = ayu + +# Default working dir +working-directory = ~/workspace + +# Number of lines to keep in scrollback buffer +scrollback-limit = 10000 + +# Window +macos-titlebar-style = tabs +window-padding-x = 8 +window-padding-y = 4 +background-opacity = 0.6 +background-blur = 10 +unfocused-split-opacity = 0.6 +window-padding-balance = true + +# macOS +macos-option-as-alt = left + +# Mouse +mouse-hide-while-typing = true + +# Cursor +cursor-style = bar diff --git a/dot_config/private_htop/private_htoprc b/dot_config/private_htop/private_htoprc new file mode 100644 index 0000000..4d1d1bc --- /dev/null +++ b/dot_config/private_htop/private_htoprc @@ -0,0 +1,53 @@ +# Beware! This file is rewritten by htop when settings are changed in the interface. +# The parser is also very primitive, and not human-friendly. +htop_version=3.3.0 +config_reader_min_version=3 +fields=0 48 17 18 38 39 2 46 47 49 1 +hide_kernel_threads=1 +hide_userland_threads=0 +hide_running_in_container=0 +shadow_other_users=0 +show_thread_names=0 +show_program_path=1 +highlight_base_name=0 +highlight_deleted_exe=1 +shadow_distribution_path_prefix=0 +highlight_megabytes=1 +highlight_threads=1 +highlight_changes=0 +highlight_changes_delay_secs=5 +find_comm_in_cmdline=1 +strip_exe_from_cmdline=1 +show_merged_command=0 +header_margin=1 +screen_tabs=1 +detailed_cpu_time=0 +cpu_count_from_one=0 +show_cpu_usage=1 +show_cpu_frequency=0 +update_process_names=0 +account_guest_in_cpu_meter=0 +color_scheme=0 +enable_mouse=1 +delay=15 +hide_function_bar=0 +header_layout=two_50_50 +column_meters_0=LeftCPUs Memory Swap +column_meter_modes_0=1 1 1 +column_meters_1=RightCPUs Tasks LoadAverage Uptime +column_meter_modes_1=1 2 2 2 +tree_view=0 +sort_key=1 +tree_sort_key=0 +sort_direction=1 +tree_sort_direction=1 +tree_view_always_by_pid=0 +all_branches_collapsed=0 +screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME Command +.sort_key=Command +.tree_sort_key=PID +.tree_view_always_by_pid=0 +.tree_view=0 +.sort_direction=1 +.tree_sort_direction=1 +.all_branches_collapsed=0 diff --git a/dot_config/private_starship.toml b/dot_config/private_starship.toml new file mode 100644 index 0000000..a8bad5a --- /dev/null +++ b/dot_config/private_starship.toml @@ -0,0 +1,41 @@ +# ~/.config/starship.toml + +add_newline = false +command_timeout = 10000 +format = "$directory$git_branch$python$conda$package$character" + +[directory] +truncate_to_repo = true +truncation_length = 2 +style = "bold blue" +format = "[$path]($style)[$read_only]($read_only_style)" + +[character] +success_symbol = " " +error_symbol = " " +format = "$symbol" + +[git_branch] +format = " [$symbol$branch(:$remote_branch)]($style)" + +[python] +format = ' [\($virtualenv\)]($style)' +style = 'bold green' +python_binary = ['python3', 'python'] +detect_extensions = [] +detect_files = [] +detect_folders = [] +detect_env_vars = ['VIRTUAL_ENV'] + +[conda] +format = ' [\($environment\)]($style)' +style = 'bold green' +ignore_base = false + +[package] +format = " is [$symbol$version]($style)" + +# Avoid prompt width issues caused by emoji variation selectors (e.g. ☁️) +# in some shell/font/wcwidth combinations. +[aws] +disabled = true diff --git a/dot_config/private_yazi/private_flavors/private_kaku-dark.yazi/private_flavor.toml b/dot_config/private_yazi/private_flavors/private_kaku-dark.yazi/private_flavor.toml new file mode 100644 index 0000000..611fe81 --- /dev/null +++ b/dot_config/private_yazi/private_flavors/private_kaku-dark.yazi/private_flavor.toml @@ -0,0 +1,225 @@ +# vim:fileencoding=utf-8:foldmethod=marker + +# : Manager {{{ + +[mgr] +cwd = { fg = "#58d8ad", bold = true } + +find_keyword = { fg = "#daae76", bold = true, italic = true, underline = true } +find_position = { fg = "#d383da", bg = "reset", bold = true, italic = true } +symlink_target = { fg = "#6d6d6d", italic = true } + +marker_copied = { fg = "#58d8ad", bg = "#58d8ad" } +marker_cut = { fg = "#d85d5d", bg = "#d85d5d" } +marker_marked = { fg = "#68afda", bg = "#68afda" } +marker_selected = { fg = "#daae76", bg = "#daae76" } + +count_copied = { fg = "#15141b", bg = "#58d8ad" } +count_cut = { fg = "#15141b", bg = "#d85d5d" } +count_selected = { fg = "#15141b", bg = "#daae76" } + +border_symbol = "│" +border_style = { fg = "#3a3942" } + +# : }}} + + +# : Tabs {{{ + +[tabs] +active = { fg = "#15141b", bg = "#8e6ad9", bold = true } +inactive = { fg = "#d5d4d6", bg = "#29263c" } + +# : }}} + + +# : Mode {{{ + +[mode] +normal_main = { fg = "#15141b", bg = "#8e6ad9", bold = true } +normal_alt = { fg = "#8e6ad9", bg = "#29263c" } + +select_main = { fg = "#15141b", bg = "#58d8ad", bold = true } +select_alt = { fg = "#58d8ad", bg = "#29263c" } + +unset_main = { fg = "#15141b", bg = "#daae76", bold = true } +unset_alt = { fg = "#daae76", bg = "#29263c" } + +# : }}} + + +# : Indicator {{{ + +[indicator] +parent = { fg = "#6d6d6d", bg = "#1f1d28" } +current = { fg = "#d5d4d6", bg = "#8e6ad9", bold = true } +preview = { fg = "#58d8ad", underline = true } +padding = { open = "", close = "" } + +# : }}} + + +# : Status {{{ + +[status] +perm_sep = { fg = "#6d6d6d" } +perm_type = { fg = "#8e6ad9" } +perm_read = { fg = "#58d8ad" } +perm_write = { fg = "#daae76" } +perm_exec = { fg = "#90c9e6" } + +progress_label = { fg = "#d5d4d6", bold = true } +progress_normal = { fg = "#58d8ad", bg = "#29263c" } +progress_error = { fg = "#15141b", bg = "#d85d5d" } + +# : }}} + + +# : Which {{{ + +[which] +mask = { bg = "#1f1d28" } +cand = { fg = "#58d8ad" } +rest = { fg = "#6d6d6d" } +desc = { fg = "#d383da" } +separator = "  " +separator_style = { fg = "#3a3942" } + +# : }}} + + +# : Confirm {{{ + +[confirm] +border = { fg = "#8e6ad9" } +title = { fg = "#8e6ad9" } +btn_yes = { fg = "#15141b", bg = "#58d8ad", bold = true } +btn_no = { fg = "#d5d4d6", bg = "#29263c" } + +# : }}} + + +# : Spot {{{ + +[spot] +border = { fg = "#8e6ad9" } +title = { fg = "#8e6ad9" } +tbl_col = { fg = "#58d8ad" } +tbl_cell = { fg = "#15141b", bg = "#daae76" } + +# : }}} + + +# : Notify {{{ + +[notify] +title_info = { fg = "#58d8ad" } +title_warn = { fg = "#daae76" } +title_error = { fg = "#d85d5d" } + +# : }}} + + +# : Pick {{{ + +[pick] +border = { fg = "#8e6ad9" } +active = { fg = "#d383da", bold = true } + +# : }}} + + +# : Input {{{ + +[input] +border = { fg = "#8e6ad9" } +selected = { fg = "#15141b", bg = "#8e6ad9", bold = true } + +# : }}} + + +# : Completion {{{ + +[cmp] +border = { fg = "#8e6ad9" } +active = { fg = "#15141b", bg = "#8e6ad9", bold = true } + +# : }}} + + +# : Tasks {{{ + +[tasks] +border = { fg = "#8e6ad9" } +hovered = { fg = "#58d8ad", bold = true } + +# : }}} + + +# : Help {{{ + +[help] +on = { fg = "#58d8ad" } +run = { fg = "#d383da" } +hovered = { fg = "#15141b", bg = "#8e6ad9", bold = true } +footer = { fg = "#15141b", bg = "#d5d4d6" } + +# : }}} + + +# : Filetype {{{ + +[filetype] +rules = [ + { mime = "image/*", fg = "#daae76" }, + { mime = "{audio,video}/*", fg = "#d383da" }, + { mime = "application/{pdf,doc,rtf}", fg = "#90c9e6" }, + { mime = "application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", fg = "#d85d5d" }, + { mime = "vfs/{absent,stale}", fg = "#6d6d6d" }, + { url = "*", is = "orphan", bg = "#d85d5d" }, + { url = "*", is = "exec", fg = "#58d8ad" }, + { url = "*", is = "dummy", bg = "#d85d5d" }, + { url = "*/", is = "dummy", bg = "#d85d5d" }, + { url = "*", fg = "#d5d4d6" }, + { url = "*/", fg = "#90c9e6" }, +] + +# : }}} + + +# : Icons {{{ + +[icon] +globs = [] +dirs = [ + { name = ".config", text = "", fg = "#8e6ad9" }, + { name = ".git", text = "", fg = "#d85d5d" }, + { name = ".github", text = "", fg = "#90c9e6" }, + { name = ".npm", text = "", fg = "#d383da" }, + { name = "Desktop", text = "", fg = "#58d8ad" }, + { name = "Development", text = "", fg = "#58d8ad" }, + { name = "Documents", text = "", fg = "#90c9e6" }, + { name = "Downloads", text = "", fg = "#90c9e6" }, + { name = "Library", text = "", fg = "#8e6ad9" }, + { name = "Movies", text = "", fg = "#d383da" }, + { name = "Music", text = "", fg = "#d383da" }, + { name = "Pictures", text = "", fg = "#daae76" }, + { name = "Public", text = "", fg = "#58d8ad" }, + { name = "Videos", text = "", fg = "#d383da" }, +] +conds = [ + { if = "orphan", text = "", fg = "#d85d5d" }, + { if = "link", text = "", fg = "#6d6d6d" }, + { if = "block", text = "", fg = "#daae76" }, + { if = "char", text = "", fg = "#daae76" }, + { if = "fifo", text = "", fg = "#daae76" }, + { if = "sock", text = "", fg = "#daae76" }, + { if = "sticky", text = "", fg = "#daae76" }, + { if = "dummy", text = "", fg = "#d85d5d" }, + { if = "dir & hovered", text = "", fg = "#58d8ad" }, + { if = "dir", text = "", fg = "#90c9e6" }, + { if = "exec", text = "", fg = "#58d8ad" }, + { if = "!dir", text = "", fg = "#d5d4d6" }, +] + +# : }}} diff --git a/dot_config/private_yazi/private_flavors/private_kaku-light.yazi/private_flavor.toml b/dot_config/private_yazi/private_flavors/private_kaku-light.yazi/private_flavor.toml new file mode 100644 index 0000000..05b61e7 --- /dev/null +++ b/dot_config/private_yazi/private_flavors/private_kaku-light.yazi/private_flavor.toml @@ -0,0 +1,225 @@ +# vim:fileencoding=utf-8:foldmethod=marker + +# : Manager {{{ + +[mgr] +cwd = { fg = "#24837b", bold = true } + +find_keyword = { fg = "#9a7400", bold = true, italic = true, underline = true } +find_position = { fg = "#a02f6f", bg = "reset", bold = true, italic = true } +symlink_target = { fg = "#7a7872", italic = true } + +marker_copied = { fg = "#24837b", bg = "#24837b" } +marker_cut = { fg = "#af3029", bg = "#af3029" } +marker_marked = { fg = "#205ea6", bg = "#205ea6" } +marker_selected = { fg = "#9a7400", bg = "#9a7400" } + +count_copied = { fg = "#fffcf0", bg = "#24837b" } +count_cut = { fg = "#fffcf0", bg = "#af3029" } +count_selected = { fg = "#fffcf0", bg = "#9a7400" } + +border_symbol = "│" +border_style = { fg = "#d7d3c7" } + +# : }}} + + +# : Tabs {{{ + +[tabs] +active = { fg = "#fffcf0", bg = "#5e3db3", bold = true } +inactive = { fg = "#403e3c", bg = "#e8e6db" } + +# : }}} + + +# : Mode {{{ + +[mode] +normal_main = { fg = "#fffcf0", bg = "#5e3db3", bold = true } +normal_alt = { fg = "#5e3db3", bg = "#e8e6db" } + +select_main = { fg = "#fffcf0", bg = "#24837b", bold = true } +select_alt = { fg = "#24837b", bg = "#e8e6db" } + +unset_main = { fg = "#fffcf0", bg = "#9a7400", bold = true } +unset_alt = { fg = "#9a7400", bg = "#e8e6db" } + +# : }}} + + +# : Indicator {{{ + +[indicator] +parent = { fg = "#7a7872", bg = "#f2f0e8" } +current = { fg = "#fffcf0", bg = "#5e3db3" } +preview = { fg = "#24837b", underline = true } +padding = { open = "", close = "" } + +# : }}} + + +# : Status {{{ + +[status] +perm_sep = { fg = "#7a7872" } +perm_type = { fg = "#5e3db3" } +perm_read = { fg = "#24837b" } +perm_write = { fg = "#9a7400" } +perm_exec = { fg = "#205ea6" } + +progress_label = { fg = "#100f0f", bold = true } +progress_normal = { fg = "#24837b", bg = "#e8e6db" } +progress_error = { fg = "#fffcf0", bg = "#af3029" } + +# : }}} + + +# : Which {{{ + +[which] +mask = { bg = "#f2f0e8" } +cand = { fg = "#24837b" } +rest = { fg = "#7a7872" } +desc = { fg = "#a02f6f" } +separator = "  " +separator_style = { fg = "#b8b2a3" } + +# : }}} + + +# : Confirm {{{ + +[confirm] +border = { fg = "#5e3db3" } +title = { fg = "#5e3db3" } +btn_yes = { fg = "#fffcf0", bg = "#24837b", bold = true } +btn_no = { fg = "#403e3c", bg = "#e8e6db" } + +# : }}} + + +# : Spot {{{ + +[spot] +border = { fg = "#5e3db3" } +title = { fg = "#5e3db3" } +tbl_col = { fg = "#24837b" } +tbl_cell = { fg = "#fffcf0", bg = "#9a7400" } + +# : }}} + + +# : Notify {{{ + +[notify] +title_info = { fg = "#24837b" } +title_warn = { fg = "#9a7400" } +title_error = { fg = "#af3029" } + +# : }}} + + +# : Pick {{{ + +[pick] +border = { fg = "#5e3db3" } +active = { fg = "#a02f6f", bold = true } + +# : }}} + + +# : Input {{{ + +[input] +border = { fg = "#5e3db3" } +selected = { fg = "#fffcf0", bg = "#5e3db3", bold = true } + +# : }}} + + +# : Completion {{{ + +[cmp] +border = { fg = "#5e3db3" } +active = { fg = "#fffcf0", bg = "#5e3db3", bold = true } + +# : }}} + + +# : Tasks {{{ + +[tasks] +border = { fg = "#5e3db3" } +hovered = { fg = "#24837b", bold = true } + +# : }}} + + +# : Help {{{ + +[help] +on = { fg = "#24837b" } +run = { fg = "#a02f6f" } +hovered = { fg = "#fffcf0", bg = "#5e3db3", bold = true } +footer = { fg = "#fffcf0", bg = "#403e3c" } + +# : }}} + + +# : Filetype {{{ + +[filetype] +rules = [ + { mime = "image/*", fg = "#9a7400" }, + { mime = "{audio,video}/*", fg = "#a02f6f" }, + { mime = "application/{pdf,doc,rtf}", fg = "#24837b" }, + { mime = "application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", fg = "#af3029" }, + { mime = "vfs/{absent,stale}", fg = "#7a7872" }, + { url = "*", is = "orphan", bg = "#af3029" }, + { url = "*", is = "exec", fg = "#66800b" }, + { url = "*", is = "dummy", bg = "#af3029" }, + { url = "*/", is = "dummy", bg = "#af3029" }, + { url = "*", fg = "#100f0f" }, + { url = "*/", fg = "#205ea6" }, +] + +# : }}} + + +# : Icons {{{ + +[icon] +globs = [] +dirs = [ + { name = ".config", text = "", fg = "#5e3db3" }, + { name = ".git", text = "", fg = "#af3029" }, + { name = ".github", text = "", fg = "#205ea6" }, + { name = ".npm", text = "", fg = "#a02f6f" }, + { name = "Desktop", text = "", fg = "#24837b" }, + { name = "Development", text = "", fg = "#24837b" }, + { name = "Documents", text = "", fg = "#205ea6" }, + { name = "Downloads", text = "", fg = "#205ea6" }, + { name = "Library", text = "", fg = "#5e3db3" }, + { name = "Movies", text = "", fg = "#a02f6f" }, + { name = "Music", text = "", fg = "#a02f6f" }, + { name = "Pictures", text = "", fg = "#9a7400" }, + { name = "Public", text = "", fg = "#24837b" }, + { name = "Videos", text = "", fg = "#a02f6f" }, +] +conds = [ + { if = "orphan", text = "", fg = "#af3029" }, + { if = "link", text = "", fg = "#7a7872" }, + { if = "block", text = "", fg = "#9a7400" }, + { if = "char", text = "", fg = "#9a7400" }, + { if = "fifo", text = "", fg = "#9a7400" }, + { if = "sock", text = "", fg = "#9a7400" }, + { if = "sticky", text = "", fg = "#9a7400" }, + { if = "dummy", text = "", fg = "#af3029" }, + { if = "dir & hovered", text = "", fg = "#24837b" }, + { if = "dir", text = "", fg = "#205ea6" }, + { if = "exec", text = "", fg = "#66800b" }, + { if = "!dir", text = "", fg = "#403e3c" }, +] + +# : }}} diff --git a/dot_config/private_yazi/private_keymap.toml b/dot_config/private_yazi/private_keymap.toml new file mode 100644 index 0000000..ce0a682 --- /dev/null +++ b/dot_config/private_yazi/private_keymap.toml @@ -0,0 +1,8 @@ +#:schema https://yazi-rs.github.io/schemas/keymap.json + +[mgr] +prepend_keymap = [ + { on = "e", run = "open", desc = "Edit or open selected files" }, + { on = "o", run = "open", desc = "Edit or open selected files" }, + { on = "", run = "enter", desc = "Enter the child directory" }, +] diff --git a/dot_config/private_yazi/private_theme.toml b/dot_config/private_yazi/private_theme.toml new file mode 100644 index 0000000..7734c3f --- /dev/null +++ b/dot_config/private_yazi/private_theme.toml @@ -0,0 +1,11 @@ +#:schema https://yazi-rs.github.io/schemas/theme.json + +# Kaku manages the [flavor] section below so Yazi matches the current Kaku theme. +# Add your own theme overrides in other sections if needed. + +# ===== Kaku Yazi Flavor (managed) ===== +[flavor] +dark = "kaku-dark" +light = "kaku-dark" +# ===== End Kaku Yazi Flavor (managed) ===== + diff --git a/dot_config/private_yazi/private_yazi.toml b/dot_config/private_yazi/private_yazi.toml new file mode 100644 index 0000000..1421f37 --- /dev/null +++ b/dot_config/private_yazi/private_yazi.toml @@ -0,0 +1,11 @@ +[mgr] +ratio = [3, 3, 10] + +[preview] +max_width = 2000 +max_height = 2400 + +[opener] +edit = [ + { run = "${EDITOR:-vim} %s", desc = "edit", for = "unix", block = true }, +] diff --git a/dot_gitconfig.tmpl b/dot_gitconfig.tmpl new file mode 100644 index 0000000..dd14b2a --- /dev/null +++ b/dot_gitconfig.tmpl @@ -0,0 +1,18 @@ +[url "git@github.com:"] + insteadof = https://github.com/ +[filter "lfs"] + required = true + clean = git-lfs clean -- %f + smudge = git-lfs smudge -- %f + process = git-lfs filter-process +[user] + name = {{ .name }} + email = {{ .email }} +[credential "https://github.com"] + helper = + helper = !/opt/homebrew/bin/gh auth git-credential +[credential "https://gist.github.com"] + helper = + helper = !/opt/homebrew/bin/gh auth git-credential +[url "git@personal:zenlbs/"] + insteadOf = https://github.com/zenlbs/ diff --git a/dot_npmrc.tmpl b/dot_npmrc.tmpl new file mode 100644 index 0000000..12c2414 --- /dev/null +++ b/dot_npmrc.tmpl @@ -0,0 +1,2 @@ +{{- /* npm auth token is decrypted from the sops store at apply time; never stored in git. */ -}} +//registry.npmjs.org/:_authToken={{ (fromYaml (output "sops" "-d" (joinPath .chezmoi.sourceDir "secrets/env.enc.yaml"))).npm_authToken }} diff --git a/dot_zprofile b/dot_zprofile new file mode 100644 index 0000000..8f28ec2 --- /dev/null +++ b/dot_zprofile @@ -0,0 +1,7 @@ + +eval "$(/opt/homebrew/bin/brew shellenv)" + +# Created by `pipx` on 2024-06-22 17:27:03 +export PATH="$PATH:/Users/antono/.local/bin" + +export PATH="/Users/antono/.local/share/solana/install/active_release/bin:$PATH" diff --git a/dot_zshenv b/dot_zshenv new file mode 100644 index 0000000..518cce4 --- /dev/null +++ b/dot_zshenv @@ -0,0 +1,3 @@ +. "$HOME/.cargo/env" + +export PATH="$PATH:/Users/antono/.foundry/bin" diff --git a/dot_zshrc b/dot_zshrc new file mode 100644 index 0000000..c2eb3fe --- /dev/null +++ b/dot_zshrc @@ -0,0 +1,148 @@ +# If you come from bash you might have to change your $PATH. +# export PATH=$HOME/bin:/usr/local/bin:$PATH + +# Path to your oh-my-zsh installation. +export ZSH="$HOME/.oh-my-zsh" + +# Set name of the theme to load --- if set to "random", it will +# load a random theme each time oh-my-zsh is loaded, in which case, +# to know which specific one was loaded, run: echo $RANDOM_THEME +# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes +ZSH_THEME="robbyrussell" + +# Set list of themes to pick from when loading at random +# Setting this variable when ZSH_THEME=random will cause zsh to load +# a theme from this variable instead of looking in $ZSH/themes/ +# If set to an empty array, this variable will have no effect. +# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) + +# Uncomment the following line to use case-sensitive completion. +# CASE_SENSITIVE="true" + +# Uncomment the following line to use hyphen-insensitive completion. +# Case-sensitive completion must be off. _ and - will be interchangeable. +# HYPHEN_INSENSITIVE="true" + +# Uncomment one of the following lines to change the auto-update behavior +# zstyle ':omz:update' mode disabled # disable automatic updates +# zstyle ':omz:update' mode auto # update automatically without asking +# zstyle ':omz:update' mode reminder # just remind me to update when it's time + +# Uncomment the following line to change how often to auto-update (in days). +# zstyle ':omz:update' frequency 13 + +# Uncomment the following line if pasting URLs and other text is messed up. +# DISABLE_MAGIC_FUNCTIONS="true" + +# Uncomment the following line to disable colors in ls. +# DISABLE_LS_COLORS="true" + +# Uncomment the following line to disable auto-setting terminal title. +# DISABLE_AUTO_TITLE="true" + +# Uncomment the following line to enable command auto-correction. +# ENABLE_CORRECTION="true" + +# Uncomment the following line to display red dots whilst waiting for completion. +# You can also set it to another string to have that shown instead of the default red dots. +# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" +# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) +# COMPLETION_WAITING_DOTS="true" + +# Uncomment the following line if you want to disable marking untracked files +# under VCS as dirty. This makes repository status check for large repositories +# much, much faster. +# DISABLE_UNTRACKED_FILES_DIRTY="true" + +# Uncomment the following line if you want to change the command execution time +# stamp shown in the history command output. +# You can set one of the optional three formats: +# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" +# or set a custom format using the strftime function format specifications, +# see 'man strftime' for details. +# HIST_STAMPS="mm/dd/yyyy" + +# Would you like to use another custom folder than $ZSH/custom? +# ZSH_CUSTOM=/path/to/new-custom-folder + +# Which plugins would you like to load? +# Standard plugins can be found in $ZSH/plugins/ +# Custom plugins may be added to $ZSH_CUSTOM/plugins/ +# Example format: plugins=(rails git textmate ruby lighthouse) +# Add wisely, as too many plugins slow down shell startup. +plugins=(git colored-man-pages fzf-tab colorize pip python brew zsh-syntax-highlighting zsh-autosuggestions) + +source $ZSH/oh-my-zsh.sh + +# User configuration + +# export MANPATH="/usr/local/man:$MANPATH" + +# You may need to manually set your language environment +# export LANG=en_US.UTF-8 + +# Preferred editor for local and remote sessions +# if [[ -n $SSH_CONNECTION ]]; then +# export EDITOR='vim' +# else +# export EDITOR='mvim' +# fi + +# Compilation flags +# export ARCHFLAGS="-arch x86_64" + +# Set personal aliases, overriding those provided by oh-my-zsh libs, +# plugins, and themes. Aliases can be placed here, though oh-my-zsh +# users are encouraged to define aliases within the ZSH_CUSTOM folder. +# For a full list of active aliases, run `alias`. +# +# Example aliases +alias namespaces="kubectl get ns" +alias git-add-modified-only="git ls-files --modified | xargs git add" +alias gs="git status" +alias ssh-restart='eval "$(ssh-agent -s)"' + +# Zenlabs aliases +alias zl:start-pf-proxy="kubectl run db-port-forward -n prod --rm -it --image=alpine/socat --restart=Never -- TCP-LISTEN:5432,fork TCP:prod-db.cn4iosmo0e2e.ap-southeast-1.rds.amazonaws.com:5432" +alias zl:start-pf="kubectl port-forward -n prod pod/db-port-forward 5432:5432" + +# alias zshconfig="mate ~/.zshrc" +# alias ohmyzsh="mate ~/.oh-my-zsh" +PATH="/usr/local/bin:$PATH" + +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm +[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion +export PYENV_ROOT="$HOME/.pyenv" +[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" +eval "$(pyenv init -)" +export PATH="/opt/homebrew/opt/openjdk/bin:$PATH" + + +autoload -U compinit +compinit -i +export PATH="/opt/homebrew/opt/openjdk/bin:$PATH" + +# Created by `pipx` on 2024-06-22 17:27:03 +export PATH="$PATH:/Users/antono/.local/bin" + +# Added by Windsurf +export PATH="/Users/antono/.codeium/windsurf/bin:$PATH" +source /opt/homebrew/opt/chruby/share/chruby/chruby.sh +source /opt/homebrew/opt/chruby/share/chruby/auto.sh +chruby ruby-3.4.1 + +# devbox - go +eval "$(devbox global shellenv)" +export PATH="$HOME/.local/share/solana/install/active_release/bin:$PATH" +export PATH="$HOME/.local/share/solana/install/active_release/bin:$PATH" +export PATH="$PATH:${GOPATH:-$HOME/go}/bin" + +# Added by Antigravity +export PATH="/Users/antono/.antigravity/antigravity/bin:$PATH" +export ANTHROPIC_MODEL="claude-sonnet-4-6" + +alias claude-mem='bun "/Users/antono/.claude/plugins/marketplaces/thedotmack/plugin/scripts/worker-service.cjs"' + +[[ ":$PATH:" != *":$HOME/.config/kaku/zsh/bin:"* ]] && export PATH="$HOME/.config/kaku/zsh/bin:$PATH" # Kaku PATH Integration +[[ -f "$HOME/.config/kaku/zsh/kaku.zsh" ]] && source "$HOME/.config/kaku/zsh/kaku.zsh" # Kaku Shell Integration diff --git a/justfile b/justfile new file mode 100644 index 0000000..c2be32f --- /dev/null +++ b/justfile @@ -0,0 +1,44 @@ +# Senior-grade dotfiles — task runner. `just` to list. + +default: + @just --list + +# Preview what `apply` would change (safe, read-only). +diff: + chezmoi diff + +# Apply the source of truth to $HOME. +apply: + chezmoi apply --verbose + +# Pull latest from git, then apply. +update: + chezmoi update --verbose + +# Edit a managed file through chezmoi (keeps source in sync). +edit +files: + chezmoi edit {{files}} + +# Add / re-capture a dotfile into the repo. +add +files: + chezmoi add {{files}} + +# Open the encrypted secret store (decrypts in $EDITOR, re-encrypts on save). +secrets: + sops secrets/env.enc.yaml + +# Refresh package manifests from the current machine. +freeze-packages: + brew bundle dump --file=packages/Brewfile --force --describe + cp ~/.local/share/devbox/global/default/devbox.json packages/devbox.global.json + +# Lint: secret scan + shell + chezmoi source validation. +lint: + gitleaks detect --no-banner || true + chezmoi verify + shellcheck $(git ls-files '*.sh') 2>/dev/null || true + +# One-command bootstrap for a fresh machine (prints the command to run). +bootstrap-help: + @echo 'On a fresh Mac: sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply ' + @echo 'Then restore the age key to ~/.config/sops/age/keys.txt' diff --git a/packages/Brewfile b/packages/Brewfile new file mode 100644 index 0000000..2e714e3 --- /dev/null +++ b/packages/Brewfile @@ -0,0 +1,184 @@ +tap "amir20/dtop" +tap "anomalyco/tap" +tap "atlassian/acli" +tap "duongductrong/snapzy", "https://github.com/duongductrong/Snapzy" +tap "ethereum/ethereum" +tap "homebrew/services" +tap "momenbasel/tap" +tap "mongodb/brew" +tap "oven-sh/bun" +tap "supabase/tap" +tap "tw93/tap" +# Search tool like grep, but optimized for programmers +brew "ack" +# Simple, modern, secure file encryption +brew "age" +# General-purpose data compression with high compression ratio +brew "xz" +# Tool for generating GNU Standards-compliant Makefiles +brew "automake" +# Parser generator +brew "bison" +# Core application library for C +brew "glib", link: false +# Manage your dotfiles across multiple diverse machines, securely +brew "chezmoi" +# Ruby environment tool +brew "chruby" +# Cloudflare Tunnel client (formerly Argo Tunnel) +brew "cloudflared" +# Container runtimes on MacOS (and Linux) with minimal setup +brew "colima", restart_service: :changed +# Tool for exploring each layer in a docker image +brew "dive" +# Pack, ship and run any application as a lightweight container +brew "docker" +# Isolated development environments using Docker +brew "docker-compose" +# Cryptography and SSL/TLS Toolkit +brew "openssl@3" +# Play, record, convert, and stream select audio and video codecs +brew "ffmpeg" +# Command-line tools for fly.io services +brew "flyctl" +# Command-line fuzzy finder written in Go +brew "fzf" +# GitHub command-line tool +brew "gh" +# Interpreter for PostScript and PDF +brew "ghostscript" +# Syntax-highlighting pager for git and diff output +brew "git-delta" +# Quickly rewrite git repository history +brew "git-filter-repo" +# Extensions to follow Vincent Driessen's branching model +brew "git-flow" +# Git extension for versioning large files +brew "git-lfs" +# Agent multiplexer that lives in your terminal +brew "herdr" +# Improved top (interactive process viewer) +brew "htop" +# Lightweight and flexible command-line JSON processor +brew "jq" +# Modern load testing tool, using Go and JavaScript +brew "k6" +# Kubernetes CLI To Manage Your Clusters In Style! +brew "k9s" +# Kubernetes command-line interface +brew "kubernetes-cli" +# Simple terminal UI for git commands +brew "lazygit" +# Portable Foreign Function Interface library +brew "libffi" +# YAML Parser +brew "libyaml" +# Deep clean and optimize your Mac +brew "mole" +# Ambitious Vim-fork focused on extensibility and agility +brew "neovim" +# Manage multiple Node.js versions +brew "nvm" +# Development kit for the Java programming language +brew "openjdk" +# Execute binaries from Python packages in isolated environments +brew "pipx" +# PDF rendering library (based on the xpdf-3.0 code base) +brew "poppler" +# Object-relational database system +brew "postgresql@18", link: true +# Protocol buffers (Google's data interchange format) +brew "protobuf" +# Python version management +brew "pyenv" +# Interpreted, interactive, object-oriented programming language +brew "python@3.12" +# Generic machine emulator and virtualizer +brew "qemu" +# Tools for and transforming and inspecting PDF files +brew "qpdf" +# Reattach process (e.g., tmux) to background +brew "reattach-to-user-namespace" +# Pack repository contents into a single AI-friendly file +brew "repomix" +# CLI proxy to minimize LLM token consumption +brew "rtk" +# Install Ruby, JRuby, Rubinius, TruffleRuby, or mruby +brew "ruby-install" +# Manage multiple Solidity compiler versions +brew "solc-select" +# Contract-oriented programming language +brew "solidity" +# Editor of encrypted files +brew "sops" +# Cross-shell prompt for astronauts +brew "starship" +# Formatting technology for Swift source code +brew "swift-format" +# Modernized, complete, self-contained TeX/LaTeX engine +brew "tectonic" +# Terminal multiplexer +brew "tmux" +# Display directories as trees (with optional color/HTML output) +brew "tree" +# Why is this running? +brew "witr" +# Blazing fast terminal file manager written in Rust, based on async I/O +brew "yazi" +# UNIX shell (command interpreter) +brew "zsh" +# Set of tools to manage resources and applications hosted on Google Cloud +cask "gcloud-cli" +# Smooths scrolling and set mouse scroll directions independently +cask "mos" +# Reverse proxy, secure introspectable tunnels to localhost +cask "ngrok" +vscode "anthropic.claude-code" +vscode "bierner.color-info" +vscode "bradlc.vscode-tailwindcss" +vscode "catppuccin.catppuccin-vsc-icons" +vscode "christian-kohler.npm-intellisense" +vscode "davidanson.vscode-markdownlint" +vscode "eamodio.gitlens" +vscode "ecmel.vscode-html-css" +vscode "expo.vscode-expo-tools" +vscode "golang.go" +vscode "jdinhlife.gruvbox" +vscode "jetpack-io.devbox" +vscode "jonathanharty.gruvbox-material-icon-theme" +vscode "mathematic.vscode-latex" +vscode "mechatroner.rainbow-csv" +vscode "ms-azuretools.vscode-containers" +vscode "ms-azuretools.vscode-docker" +vscode "ms-python.debugpy" +vscode "ms-python.python" +vscode "ms-python.vscode-pylance" +vscode "ms-python.vscode-python-envs" +vscode "ms-vscode.remote-explorer" +vscode "ms-vscode.remote-server" +vscode "pomdtr.excalidraw-editor" +vscode "pranaygp.vscode-css-peek" +vscode "redhat.vscode-yaml" +vscode "vscode-icons-team.vscode-icons" +vscode "wayou.vscode-todo-highlight" +vscode "xabikos.javascriptsnippets" +go "github.com/air-verse/air" +go "github.com/golangci/golangci-lint/v2/cmd/golangci-lint" +go "golang.org/x/tools/gopls" +go "github.com/vektra/mockery/v2" +go "github.com/rubenv/sql-migrate/sql-migrate" +go "honnef.co/go/tools/cmd/staticcheck" +go "github.com/swaggo/swag/cmd/swag" +cargo "avm" +cargo "marginfi-v2-cli" +cargo "solana-verify" +npm "@aisuite/chub" +npm "@langchain/langgraph-cli" +npm "corepack" +npm "dev-browser" +npm "nodemon" +npm "pnpm" +npm "ruflo" +npm "uipro-cli" +npm "vercel" +npm "yarn" diff --git a/packages/devbox.global.json b/packages/devbox.global.json new file mode 100644 index 0000000..530a73a --- /dev/null +++ b/packages/devbox.global.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.6/.schema/devbox.schema.json", + "packages": ["go@latest"], + "shell": { + "init_hook": [ + "echo 'Welcome to devbox!' > /dev/null" + ], + "scripts": { + "test": [ + "echo \"Error: no test specified\" && exit 1" + ] + } + } +} diff --git a/secrets/env.enc.yaml b/secrets/env.enc.yaml new file mode 100644 index 0000000..d0e8007 --- /dev/null +++ b/secrets/env.enc.yaml @@ -0,0 +1,23 @@ +npm_authToken: ENC[AES256_GCM,data:/1FUekbxPH/l7CVdfn9SxVwRZbdu3twaChq7R3hFBMxkU6KGH9Mwzg==,iv:ayQydRNGW6fArdVsXP1a6JmlM5TtTN+JXRdmQw9UgA0=,tag:qGG7CEAJUwaWz+MMRVPedg==,type:str] +#ENC[AES256_GCM,data:0egru8nl0VBu6cXxbQIjmEr7J792HYavbi23H9ahmvLmg3rzw6T69vY0IAUU9GxGXtDmUucTjr9xROC1oFA0H5ZO7bv9O9g/eg==,iv:0zg/afUhd08XyudW9OfaQO8t2fPjqxKe/gwuHdfIsqM=,tag:YmHHEUGWu83eZ6acYfTCLg==,type:comment] +github_token: ENC[AES256_GCM,data:D+7PM6+i2Cn17zOAdpVqOhOuNvusnw==,iv:Jp4JVbxpb5AcaeupWXKK0tt2E4RF+TFCxyIXCxK+Pos=,tag:ym3tvMzgSbBtSw0LJbe5Fg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gn0mpr6klym62q98tzu0et29xyl93mk8ehhp4ueyatgdx7nhx5eqsydpyc + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMMUl0WTZZTGovQ09OYkhs + STMyMTk2eUJPRnBLTTlWRG94T0NkNnBLMDE0CnQzUmt4NERrNnVBeHk2NkxSdXlE + R1p2YlVRcGpZL084aHRjNkxKSTZVeUkKLS0tIFBGUU9NS21uNjJvUDFOZ0piZjBi + NmU0ZEtTUDBva1dsZHVUQ3J5UTcyRmsKnLL5So3C8ra5rHH2owTQE8K2gdRVGYh5 + BE8wCFOlye2BBiTivD6p79DJZcPWljfy6S2X0ji1q3oNlrvfR5Z+dA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-07-10T20:54:08Z" + mac: ENC[AES256_GCM,data:KX/MddXpFwGxCTDOda7Hd51TeZ61YUv2xVzHfVxVJAf8XPly0k6ezkXLS5TCyuJIbxrloE+9EBnrQd24SHyzDbLpXCq6w/xy1HVvxt2VRwVlEjdq+j/0ieKIW9L7xIR3xoKyg3UXGRlynNnx+A0GGNCE+zDzkHfxz1xolb87OrU=,iv:7VR9twdPJIQO6IJL6hdi8c/XCHe9a3mRcENDFn2p5LE=,tag:jEsNMjpIm9Cf5lcYuVfZ1A==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/symlink_dot_tmux.conf b/symlink_dot_tmux.conf new file mode 100644 index 0000000..6a08cee --- /dev/null +++ b/symlink_dot_tmux.conf @@ -0,0 +1 @@ +.tmux/.tmux.conf