diff --git a/.claude/.gitignore b/.claude/.gitignore new file mode 100644 index 00000000..f2a6ba9e --- /dev/null +++ b/.claude/.gitignore @@ -0,0 +1,33 @@ +# Never track Claude Code per-machine state, secrets, or chat data. +# +# settings.json IS tracked (portable user prefs + permissions allowlist). +# Everything else under ~/.claude/ stays per-host: credentials, session +# logs, project memories, file-edit history, telemetry, caches. + +# Auth — must NEVER be tracked +.credentials.json + +# Per-machine settings overrides (by Claude Code convention) +settings.local.json + +# Chat and session data +history.jsonl +sessions/ +projects/ +file-history/ +plans/ + +# Caches and ephemeral state +cache/ +downloads/ +paste-cache/ +shell-snapshots/ +session-env/ +backups/ +telemetry/ +mcp-needs-auth-cache.json + +# Plugin marketplace state — known_marketplaces.json IS portable, but the +# resolved-plugin caches and the local blocklist are per-machine. +plugins/blocklist.json +plugins/marketplaces/ diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 00000000..be9fb41e --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,110 @@ +{ + "permissions": { + "allow": [ + "Bash(tmux source-file:*)", + "Bash(git config:*)", + "Read(//home/mastodon/live/**)", + "Bash(sed -i '/^$/N;/^\\\\n# Facebook Webhook/,/^MASTODON_BOT_ACCESS_TOKEN=.*/{ /# Facebook Webhook/d; /FACEBOOK_VERIFY_TOKEN/d; /FACEBOOK_APP_SECRET/d; /FACEBOOK_PAGE_ACCESS_TOKEN/d; /MASTODON_BOT_ACCESS_TOKEN/d }' .env.production)", + "Bash(head -10 grep -rn \"StatusReactions\\\\|status_reactions\" /home/mastodon/live/app/javascript/mastodon/features/)", + "Bash(ls -lt /home/mastodon/live/public/packs/status_quoted-*.js)", + "Bash(python3:*)", + "Bash(iptables:*)", + "Bash(ip6tables:*)", + "Bash(ufw status:*)", + "Bash(firewall-cmd:*)", + "Bash(systemctl status:*)", + "Bash(sysctl -a)", + "Bash(sysctl:*)", + "Bash(apt list:*)", + "Bash(dpkg:*)", + "Bash(systemctl list-units:*)", + "Bash(fail2ban-client status:*)", + "Bash(aa-status)", + "Bash(getenforce)", + "Bash(crontab:*)", + "Bash(mount)", + "Bash(netstat -tuln)", + "Bash(systemctl is-enabled:*)", + "Bash(usermod -s /usr/sbin/nologin mastodon)", + "Bash(usermod -s /usr/sbin/nologin postgres)", + "Bash(systemctl daemon-reload:*)", + "Bash(systemctl restart:*)", + "Bash(apt-get upgrade:*)", + "Bash(curl -sI https://auto.signers.online/webhook/ -o /dev/null -w \"%{http_code}\")", + "Bash(curl -sI https://auto.signers.online/ -o /dev/null -w \"%{http_code}\")", + "Bash(openssl x509:*)", + "Bash(systemctl list-timers:*)", + "Bash(find:*)", + "Bash(grep -v \"^$\")", + "Bash(du -sh /var/log/*)", + "Bash(lsmod)", + "Bash(xargs ls:*)", + "Bash(last:*)", + "Bash(netstat -tlnp)", + "Bash(systemctl cat:*)", + "Bash(ls:*)", + "Bash(chmod 600 /home/mastodon/live/.env.development /home/mastodon/live/.env.test /home/mastodon/live/.env.vagrant /home/mastodon/live/.env.production)", + "Bash(openssl rand:*)", + "Bash(nginx:*)", + "Bash(redis-cli:*)", + "Bash(curl -sI https://signers.online/ -o /dev/null -w \"%{http_code}\")", + "Bash(systemctl is-active:*)", + "Bash(curl -sI https://auto.signers.online/)", + "Bash(apt-get install:*)", + "Bash(rkhunter --update)", + "Bash(rkhunter --propupd)", + "Bash(rkhunter:*)", + "Bash(journalctl -u mastodon-web --since \"5 min ago\" --no-pager)", + "Bash(journalctl -u mastodon-web --since \"1 min ago\" --no-pager -l)", + "Bash(chown mastodon:mastodon /home/mastodon/live/.env.production /home/mastodon/live/.env.development /home/mastodon/live/.env.test /home/mastodon/live/.env.vagrant)", + "Bash(aideinit)", + "Bash(curl -kI https://signers.online/nonexistent-path)", + "Bash(dig:*)", + "Bash(openssl s_client -connect signers.online:443 -servername signers.online)", + "Bash(ulimit:*)", + "Bash(systemctl:*)", + "Bash(cat:*)", + "Bash(curl -sI https://signers.online/assets/test-nonexistent.js)", + "Bash(npm --version)", + "Bash(ruby --version)", + "Bash(getent passwd:*)", + "Bash(sqlite3:*)", + "Bash(curl -sI https://signers.online/ --connect-timeout 5 -o /dev/null -w \"http_code:%{http_code} time:%{time_total}\")", + "Bash(fail2ban-client set:*)", + "Bash(chmod 755 /usr/local/bin/fail2ban-ignoreip)", + "Bash(/usr/local/bin/fail2ban-ignoreip 76.95.82.63)", + "Bash(git -C /home/mastodon/live status -s)", + "Bash(git -C /home/mastodon/live diff --stat)", + "Bash(git:*)", + "Bash(curl:*)", + "Bash(nslookup signers.live)", + "Bash(journalctl -u n8n --since \"1 min ago\" --no-pager)", + "Bash(journalctl -u n8n --since \"10 sec ago\" --no-pager)", + "Bash(journalctl -u n8n --since \"30 sec ago\" --no-pager)", + "Bash(sudo:*)", + "Bash(journalctl -u mastodon-web --since \"1 hour ago\" --no-pager)", + "Bash(journalctl -u mastodon-streaming --since \"1 hour ago\" --no-pager)", + "Bash(chown mastodon:mastodon *)", + "Bash(journalctl -u mastodon-web -u mastodon-sidekiq --since \"10 minutes ago\")", + "Bash(journalctl -u mastodon-web --since \"10 minutes ago\")", + "Bash(journalctl -u nginx --since \"1 hour ago\")", + "Bash(zcat -f /var/log/nginx/access.log.1 /var/log/nginx/access.log)", + "Bash(zcat -f /var/log/nginx/access.log*)", + "Read(//home/**)", + "Read(//opt/**)", + "Bash(journalctl -u windmill --since \"2 hours ago\")", + "Read(//etc/nginx/sites-enabled/**)", + "Read(//etc/nginx/sites-available/**)", + "Bash(journalctl -u windmill --since \"1 day ago\")", + "Bash(journalctl -u windmill --since \"2026-04-10\" --until \"2026-04-14\")", + "Bash(journalctl -u windmill -n 100000)", + "Bash(/usr/local/bin/windmill --version)", + "Bash(journalctl -u windmill -n 500)", + "Bash(grep -l 'root ' /etc/nginx/sites-available/*)" + ], + "defaultMode": "auto" + }, + "theme": "dark", + "verbose": true, + "skipAutoPermissionPrompt": true +} diff --git a/install.sh b/install.sh index b8c485ee..892a5856 100755 --- a/install.sh +++ b/install.sh @@ -36,7 +36,7 @@ PERSONAL_FILES=( # untouched. This deliberately avoids wholesale-replacing $HOME/.local etc., # which would sweep away unrelated user data (fonts, app state, ...). PERSONAL_DIRS=( - .fonts .irssi .nano .themes .local .mplayer + .fonts .irssi .nano .themes .local .mplayer .claude ) have() { command -v "$1" >/dev/null 2>&1; }