Skip to content
Merged
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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ These affect nearly every task:
- **FNM, not NVM**: Node.js managed by FNM (Fast Node Manager). Use `require_fnm()` and `source_fnm()`.
- **Packages**: Brewfile for brew/cask/mas (`brew bundle install`). `.list` files in `packages/` for npm, vscode extensions, and other tools Brewfile doesn't support. See [packages.md](docs/agents/packages.md).
- **Backups**: Dotfile linking backs up originals to `~/.dotfiles_backup/<timestamp>` before replacing.
- **Claude Code**: `install --claude` bootstraps Claude Code native binary, marketplaces, plugins, rules, hooks, settings, and QMD. Config manifests live in `claude/`. See [commands.md](docs/agents/commands.md).

## Detail Docs

Expand Down
2 changes: 2 additions & 0 deletions Brewfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ brew "croc" # Secure file transfer
brew "gnu-sed" # GNU sed
brew "gawk" # GNU awk
brew "grep" # GNU grep
brew "gettext" # GNU i18n tools (envsubst)
brew "jq" # JSON processor
brew "yq" # YAML processor

Expand Down Expand Up @@ -124,6 +125,7 @@ cask "keycastr" # Keystroke visualizer
cask "shottr" # Screenshot tool
cask "topnotch" # Notch hider
cask "flux-app" # Blue light filter
cask "obsidian" # Knowledge base / vault
cask "setapp" # App subscription

# Media
Expand Down
13 changes: 13 additions & 0 deletions bin/dotfiles
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ sub_install_help() {
echo
echo "Commands:"
echo " --all Run all below commands"
echo " --claude Claude Code (binary, plugins, marketplaces, hooks, rules, QMD)"
echo " --fonts Local fonts"
echo " --help This help message"
echo " --hosts Ad-blocking hosts file from StevenBlack project"
Expand Down Expand Up @@ -177,6 +178,7 @@ sub_install_all() {
$0 install --fonts
$0 install --packages
$0 install --launchagents
$0 install --claude
$0 configure
}

Expand Down Expand Up @@ -443,6 +445,17 @@ sub_install_launchagents() {
fi
}

sub_install_claude() {
bot "Claude Code Bootstrap\n"

read -r -p "Install Claude Code (binary, plugins, marketplaces, hooks, rules, QMD)? [y|N] " response
if [[ $response =~ (yes|y|Y) ]]; then
bash "$ROOT_DIR/scripts/install_claude.sh"
else
skip
fi
}

sub_configure() {
read -r -p "Do you want to update the system configurations? [y|N] " response
if [[ $response =~ ^(y|Y) ]]; then
Expand Down
129 changes: 129 additions & 0 deletions bin/dotfiles-test
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ test_bash_syntax() {
"$DOTFILES_DIR/bin/dotfiles"
"$DOTFILES_DIR/scripts/echos.sh"
"$DOTFILES_DIR/scripts/requirers.sh"
"$DOTFILES_DIR/scripts/install_claude.sh"
)

for file in "${files[@]}"; do
Expand Down Expand Up @@ -155,6 +156,7 @@ test_shellcheck() {
"$DOTFILES_DIR/bin/dotfiles"
"$DOTFILES_DIR/scripts/echos.sh"
"$DOTFILES_DIR/scripts/requirers.sh"
"$DOTFILES_DIR/scripts/install_claude.sh"
"$DOTFILES_DIR/macos/defaults.sh"
"$DOTFILES_DIR/macos/dock.sh"
)
Expand Down Expand Up @@ -424,6 +426,132 @@ test_aliases() {
fi
}

#############################################################################
# CLAUDE CODE BOOTSTRAP TESTS
#############################################################################

test_claude_bootstrap() {
section "Claude Code Bootstrap"

# Test install script exists and is executable
if [[ -f "$DOTFILES_DIR/scripts/install_claude.sh" ]]; then
pass "File exists: scripts/install_claude.sh"
if [[ -x "$DOTFILES_DIR/scripts/install_claude.sh" ]]; then
pass "Executable: scripts/install_claude.sh"
else
fail "Not executable: scripts/install_claude.sh"
fi
else
fail "File missing: scripts/install_claude.sh"
fi

# Test install script has valid bash syntax
if bash -n "$DOTFILES_DIR/scripts/install_claude.sh" 2>/dev/null; then
pass "Syntax OK: scripts/install_claude.sh"
else
fail "Syntax error: scripts/install_claude.sh"
fi

# Test manifest files exist
local manifests=("claude/marketplaces.list" "claude/plugins.list" "claude/settings.template.json")
for manifest in "${manifests[@]}"; do
if [[ -f "$DOTFILES_DIR/$manifest" ]]; then
pass "File exists: $manifest"
else
fail "File missing: $manifest"
fi
done

# Test rules exist
local rules=("claude/rules/context7.md" "claude/rules/vault-lookback.md" "claude/rules/gnu-tools.md")
for rule in "${rules[@]}"; do
if [[ -f "$DOTFILES_DIR/$rule" ]]; then
pass "File exists: $rule"
else
fail "File missing: $rule"
fi
done

# Test hooks exist
if [[ -f "$DOTFILES_DIR/claude/hooks/index-sessions.sh" ]]; then
pass "File exists: claude/hooks/index-sessions.sh"
else
fail "File missing: claude/hooks/index-sessions.sh"
fi

# Test settings template is valid JSON
if command -v jq &>/dev/null && jq . "$DOTFILES_DIR/claude/settings.template.json" >/dev/null 2>&1; then
pass "Valid JSON: settings.template.json"
elif python3 -m json.tool "$DOTFILES_DIR/claude/settings.template.json" >/dev/null 2>&1; then
pass "Valid JSON: settings.template.json"
else
fail "Invalid JSON: settings.template.json"
fi

# Test settings template has no hardcoded /Users/ paths (except $HOME patterns)
if grep -q '/Users/' "$DOTFILES_DIR/claude/settings.template.json" 2>/dev/null; then
fail "settings.template.json contains hardcoded /Users/ path (should use \$HOME)"
else
pass "settings.template.json: no hardcoded user paths"
fi

# Test hooks have no hardcoded /Users/ paths
if grep -rq '/Users/' "$DOTFILES_DIR/claude/hooks/" 2>/dev/null; then
fail "claude/hooks/ contains hardcoded /Users/ path (should use \$HOME)"
else
pass "claude/hooks/: no hardcoded user paths"
fi

# Test vault templates directory exists
if [[ -d "$DOTFILES_DIR/claude/vault-templates" ]]; then
pass "Directory exists: claude/vault-templates"
else
fail "Directory missing: claude/vault-templates"
fi

# Test top-of-mind template exists
if [[ -f "$DOTFILES_DIR/claude/vault-templates/top-of-mind.md" ]]; then
pass "File exists: claude/vault-templates/top-of-mind.md"
else
fail "File missing: claude/vault-templates/top-of-mind.md"
fi

# Test install script registers QMD MCP server via 'claude mcp add'
if grep -q 'claude mcp add.*qmd' "$DOTFILES_DIR/scripts/install_claude.sh" 2>/dev/null; then
pass "install_claude.sh: QMD MCP registration via 'claude mcp add'"
else
fail "install_claude.sh: QMD MCP registration missing"
fi

# Test npm.list no longer has claude-code
if grep -q '@anthropic-ai/claude-code' "$DOTFILES_DIR/packages/npm.list" 2>/dev/null; then
fail "npm.list still contains @anthropic-ai/claude-code (should use native binary)"
else
pass "npm.list: claude-code removed (using native binary)"
fi

# Test dotfiles CLI has --claude subcommand
if grep -q 'sub_install_claude' "$DOTFILES_DIR/bin/dotfiles"; then
pass "CLI: install --claude subcommand registered"
else
fail "CLI: install --claude subcommand missing"
fi

# Test install --all includes --claude
if grep -q 'install --claude' "$DOTFILES_DIR/bin/dotfiles"; then
pass "CLI: install --all includes --claude"
else
fail "CLI: install --all missing --claude"
fi

# Test sub_install_claude uses subprocess (bash), not source
if grep -q 'bash.*install_claude' "$DOTFILES_DIR/bin/dotfiles"; then
pass "CLI: sub_install_claude uses subprocess execution"
elif grep -q 'source.*install_claude' "$DOTFILES_DIR/bin/dotfiles"; then
fail "CLI: sub_install_claude uses source (should use bash subprocess)"
fi
}

#############################################################################
# SHELL STARTUP TESTS
#############################################################################
Expand Down Expand Up @@ -864,6 +992,7 @@ main() {
test_performance_optimizations
test_config_modernization
test_dead_code_cleanup
test_claude_bootstrap
test_shell_startup

# Summary
Expand Down
23 changes: 23 additions & 0 deletions claude/hooks/index-sessions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
# Auto-index QMD sessions after Claude Code session ends
# Extracts recent sessions to vault and updates QMD index

VAULT_DIR="${VAULT_DIR:-$HOME/Vault}"
PYTHON="$HOME/.claude/skills/recall/.venv/bin/python3"
EXTRACT_SCRIPT="$HOME/.claude/skills/recall/scripts/extract-sessions.py"
LOG_FILE="$HOME/.claude/hooks/index-sessions.log"

# Rotate log if > 1MB
if [[ -f "$LOG_FILE" ]] && [[ $(stat -f%z "$LOG_FILE" 2>/dev/null || stat -c%s "$LOG_FILE" 2>/dev/null) -gt 1048576 ]]; then
tail -n 500 "$LOG_FILE" > "${LOG_FILE}.tmp" && mv "${LOG_FILE}.tmp" "$LOG_FILE"
fi

# Extract last 3 days of sessions
if [[ -x "$PYTHON" ]] && [[ -f "$EXTRACT_SCRIPT" ]]; then
"$PYTHON" "$EXTRACT_SCRIPT" --days 3 --output "$VAULT_DIR/Claude-Sessions" >> "$LOG_FILE" 2>&1
fi

# Update QMD index (fast — only processes changed files)
if command -v qmd &>/dev/null; then
timeout 60 qmd update >> "$LOG_FILE" 2>&1
fi
26 changes: 26 additions & 0 deletions claude/marketplaces.list
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Claude Code Marketplaces
# Format: github_org/repo (or full git URL for non-standard repos)
# Used by: scripts/install_claude.sh

# Official Anthropic
anthropics/claude-plugins-official
anthropics/skills
anthropics/claude-code

# Power-user
obra/superpowers-marketplace
https://github.com/EveryInc/compound-engineering-plugin.git
ArtemXTech/personal-os-skills

# Dev-focused
steveyegge/beads
kingbootoshi/cartographer
kenryu42/cc-marketplace
affaan-m/everything-claude-code
guinacio/claude-image-gen
CloudAI-X/claude-workflow-v2

# Framework-specific
hopeoverture/worldbuilding-app-skills
davila7/claude-code-templates
jezweb/claude-skills
72 changes: 72 additions & 0 deletions claude/plugins.list
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Claude Code Plugins
# Format: plugin@marketplace
# Used by: scripts/install_claude.sh
# To find available plugins: claude plugin list --available

# Official Anthropic plugins
context7@claude-plugins-official
frontend-design@claude-plugins-official
hookify@claude-plugins-official
vercel@claude-plugins-official
code-simplifier@claude-plugins-official
feature-dev@claude-plugins-official
code-review@claude-plugins-official
security-guidance@claude-plugins-official
typescript-lsp@claude-plugins-official
playwright@claude-plugins-official
gopls-lsp@claude-plugins-official
stripe@claude-plugins-official
figma@claude-plugins-official
playground@claude-plugins-official

# Anthropic skills
document-skills@anthropic-agent-skills

# Superpowers
superpowers@superpowers-marketplace

# Compound Engineering
compound-engineering@every-marketplace

# Personal OS
recall-skill@personal-os-skills
sync-claude-sessions-skill@personal-os-skills

# Dev tools
plugin-dev@claude-code-plugins
beads@beads-marketplace
cartographer@cartographer-marketplace
safety-net@cc-marketplace
everything-claude-code@everything-claude-code
media-pipeline@media-pipeline-marketplace
project-starter@claude-workflow

# Framework templates
nextjs-vercel-pro@claude-code-templates

# Claude skills
auth-skills@claude-skills
backend-skills@claude-skills
cloudflare-skills@claude-skills
database-skills@claude-skills
frontend-skills@claude-skills
tooling-skills@claude-skills

# Worldbuilding app skills
a11y-checker-ci@worldbuilding-app-skills
api-contracts-and-zod-validation@worldbuilding-app-skills
auth-route-protection-checker@worldbuilding-app-skills
csp-config-generator@worldbuilding-app-skills
env-config-validator@worldbuilding-app-skills
feature-flag-manager@worldbuilding-app-skills
form-generator-rhf-zod@worldbuilding-app-skills
nextjs-fullstack-scaffold@worldbuilding-app-skills
playwright-flow-recorder@worldbuilding-app-skills
revalidation-strategy-planner@worldbuilding-app-skills
security-hardening-checklist@worldbuilding-app-skills
server-actions-vs-api-optimizer@worldbuilding-app-skills
skill-reviewer-and-enhancer@worldbuilding-app-skills
supabase-prisma-database-management@worldbuilding-app-skills
tailwind-shadcn-ui-setup@worldbuilding-app-skills
testing-next-stack@worldbuilding-app-skills
ui-library-usage-auditor@worldbuilding-app-skills
12 changes: 12 additions & 0 deletions claude/rules/context7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
alwaysApply: true
---

When working with libraries, frameworks, or APIs — use Context7 MCP to fetch current documentation instead of relying on training data. This includes setup questions, code generation, API references, and anything involving specific packages.

## Steps

1. Call `resolve-library-id` with the library name and the user's question
2. Pick the best match — prefer exact names and version-specific IDs when a version is mentioned
3. Call `query-docs` with the selected library ID and the user's question
4. Answer using the fetched docs — include code examples and cite the version
15 changes: 15 additions & 0 deletions claude/rules/gnu-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
alwaysApply: true
---

This machine has GNU coreutils, GNU sed, GNU grep, GNU find, and GNU awk installed via Homebrew and configured as the default commands in PATH.

Use standard GNU syntax for all shell commands:

- `sed -i 's/old/new/'` (not `sed -i '' 's/old/new/'` which is BSD)
- `grep -P` for PCRE is available
- `find` supports `-printf`, `-regextype`
- `awk` is `gawk` with full GNU extensions
- `date` supports `--date` and `+%s` formatting

Do NOT use workarounds for BSD tool limitations — they are not needed here.
Loading