Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ nothing on Linux.
| [`AGENTS.md`](AGENTS.md) | Shared context for every coding agent (branch discipline, secrets). Symlinked to `~/.codex/AGENTS.md`; Claude imports it via `@~/.dotfiles/AGENTS.md`. |
| [`CLAUDE.md`](CLAUDE.md) | Claude Code global instructions (imports `AGENTS.md`). Symlinked to `~/.claude/CLAUDE.md`. |
| [`claude/rules/`](claude/rules) | Claude Code rule files — model routing, Context7 doc lookups. Each is symlinked into `~/.claude/rules/`. |
| [`claude/settings.plugins.json`](claude/settings.plugins.json) | Marketplaces, enabled plugins, skill overrides. **Merged** into `~/.claude/settings.json` so machine-specific keys survive. |
| [`claude/settings.plugins.json`](claude/settings.plugins.json) | Portable Claude settings: marketplaces, enabled plugins, skill overrides, permission allowlist, statusline registration, behaviour flags. **Merged** into `~/.claude/settings.json` so machine-specific keys survive. |
| [`claude/sync-plugins.sh`](claude/sync-plugins.sh) | Applies that fragment and installs the enabled plugins. Run by `install.sh`. |
| [`linux/cloud-init.yaml`](linux/cloud-init.yaml) | Cloud-config for a fresh VPS. Creates the user, joins Tailscale, then hands off to `linux/provision.sh`. |
| [`claude/marketplaces.json`](claude/marketplaces.json) | Every plugin marketplace, source only. `settings.json` records only hand-added ones, so this is the complete list. |
| [`claude/skill-lock.json`](claude/skill-lock.json) | Manifest of the `~/.agents/skills` set (source repo + pinned hash per skill). Reference only — not consumed by `install.sh`. |
| [`install.sh`](install.sh) | Symlinks every dotfile from this repo into the right home location. |
Expand Down
115 changes: 78 additions & 37 deletions claude/settings.plugins.json
Original file line number Diff line number Diff line change
@@ -1,37 +1,10 @@
{
"extraKnownMarketplaces": {
"antigravity-cc": {
"source": {
"source": "github",
"repo": "simplybychris/antigravity-plugin-cc"
}
},
"cloudflare": {
"source": {
"source": "github",
"repo": "cloudflare/skills"
}
},
"expo-plugins": {
"source": {
"source": "github",
"repo": "expo/skills"
}
},
"openai-codex": {
"source": {
"source": "github",
"repo": "openai/codex-plugin-cc"
}
},
"RevenueCat": {
"source": {
"source": "github",
"repo": "RevenueCat/ai-toolkit"
}
}
},
"agentPushNotifEnabled": true,
"autoCompactEnabled": true,
"autoUpdatesChannel": "latest",
"effortLevel": "xhigh",
"enabledPlugins": {
"RevenueCat@RevenueCat": false,
"agy@antigravity-cc": false,
"clangd-lsp@claude-plugins-official": false,
"cloudflare@claude-plugins-official": true,
Expand All @@ -48,7 +21,6 @@
"plugin-dev@claude-plugins-official": false,
"posthog@claude-plugins-official": false,
"revenuecat-play-billing@RevenueCat": false,
"RevenueCat@RevenueCat": false,
"stripe@claude-plugins-official": false,
"supabase@claude-plugins-official": false,
"superpowers@claude-plugins-official": true,
Expand All @@ -57,6 +29,69 @@
"upgrading-expo@expo-plugins": false,
"vercel@claude-plugins-official": false
},
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
"extraKnownMarketplaces": {
"RevenueCat": {
"source": {
"repo": "RevenueCat/ai-toolkit",
"source": "github"
}
},
"antigravity-cc": {
"source": {
"repo": "simplybychris/antigravity-plugin-cc",
"source": "github"
}
},
"cloudflare": {
"source": {
"repo": "cloudflare/skills",
"source": "github"
}
},
"expo-plugins": {
"source": {
"repo": "expo/skills",
"source": "github"
}
},
"openai-codex": {
"source": {
"repo": "openai/codex-plugin-cc",
"source": "github"
}
}
},
"permissions": {
"allow": [
"Bash(cat:*)",
"Bash(cd:*)",
"Bash(curl:*)",
"Bash(do echo -n \" $f: \" ffmpeg -i \"$f\" -af ebur128 -f null -)",
"Bash(do echo -n \"$f: \" ffmpeg -i \"$f\" -af ebur128 -f null -)",
"Bash(ffmpeg:*)",
"Bash(find:*)",
"Bash(npm run build:*)",
"Bash(npm run lint)",
"Bash(swift:*)",
"Bash(swiftlint:*)",
"Bash(wc:*)",
"Bash(xcodebuild:*)",
"WebFetch(domain:github.com)",
"WebSearch",
"mcp__context7__query-docs",
"mcp__context7__resolve-library-id",
"mcp__firecrawl__firecrawl_scrape",
"mcp__firecrawl__firecrawl_search",
"mcp__gemini__consult_gemini",
"mcp__plugin_context7_context7__query-docs",
"mcp__plugin_context7_context7__resolve-library-id"
],
"defaultMode": "auto",
"deny": []
},
"skillOverrides": {
"accessorysetupkit": "off",
"adattributionkit": "off",
Expand Down Expand Up @@ -108,7 +143,13 @@
"workers-best-practices": "off",
"wrangler": "off"
},
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
"skipAutoPermissionPrompt": true,
"skipDangerousModePermissionPrompt": true,
"skipWorkflowUsageWarning": true,
"statusLine": {
"command": "bash ~/.claude/statusline-command.sh",
"type": "command"
},
"theme": "dark-daltonized",
"tui": "fullscreen"
}
75 changes: 75 additions & 0 deletions linux/cloud-init.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#cloud-config
# Hetzner (or any cloud-init host) bootstrap for a Linux dev box.
# Paste into the provider's "Cloud config" field. Substitute HOSTNAME and the
# Tailscale auth key; everything else is generic.
#
# Tick your SSH keys in the provider's creation form as well. `- default`
# below preserves the provider's key injection into root, and runcmd copies
# those same keys to the non-root user — which is the only reliable way to
# get in. Seeding from github.com/<user>.keys instead looks equivalent and is
# not: the keys published there need not be the key your SSH agent offers.

hostname: CHANGE-ME
package_update: true
# NOT package_upgrade: it delays runcmd by several minutes behind a full
# apt upgrade, so Tailscale takes that long to appear. unattended-upgrades
# below applies the backlog shortly after boot instead.

users:
# `- default` is load-bearing. A users: block without it SUPPRESSES the
# provider's SSH key injection entirely, which can leave a box with no keys
# at all and only the web console as a way in.
- default
- name: shridhar
groups: [sudo]
shell: /bin/bash
sudo: ['ALL=(ALL) NOPASSWD:ALL']

ssh_pwauth: false

packages: [git, curl, unzip, ca-certificates, unattended-upgrades]

swap:
filename: /swapfile
size: 4294967296
maxsize: 4294967296

write_files:
# Patch automatically, but never reboot unattended: a surprise restart would
# kill long-running agent sessions and detach tmux work. Reboot by hand when
# /var/run/reboot-required appears.
- path: /etc/apt/apt.conf.d/20auto-upgrades
content: |
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
- path: /etc/apt/apt.conf.d/52unattended-upgrades-local
content: |
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";

runcmd:
# Give the non-root user exactly the keys the provider injected into root.
- install -d -m 700 -o shridhar -g shridhar /home/shridhar/.ssh
- cat /root/.ssh/authorized_keys > /home/shridhar/.ssh/authorized_keys
- chown shridhar:shridhar /home/shridhar/.ssh/authorized_keys
- chmod 600 /home/shridhar/.ssh/authorized_keys

# Tailscale. Use a single-use, ephemeral, short-expiry auth key.
- curl -fsSL https://tailscale.com/install.sh | sh
- tailscale up --hostname=CHANGE-ME --authkey=TAILSCALE_AUTH_KEY_HERE

# Apply the security backlog the base image ships with (typically ~50
# packages including openssh-server and a kernel).
- DEBIAN_FRONTEND=noninteractive unattended-upgrades

# Everything else — toolchain, shell, dotfiles, Claude plugins — is
# provision.sh's job. Kept there so this file and that script cannot drift.
- su - shridhar -c 'curl -fsSL https://raw.githubusercontent.com/sgup/new-mac-setup/master/linux/provision.sh | bash'

final_message: |
Ready. Then, as the non-root user:
claude auth login
gh auth login # choose HTTPS
A kernel update usually lands in the backlog above; reboot when convenient.