Add Makefile for managing Claude Code config symlinks

- Move commands, scripts, settings to repo root
- Add Makefile with install/uninstall/status targets
- Symlinks ~/.claude/* to this repo for version control
- Update documentation with setup instructions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-28 18:43:35 +01:00
parent 8b59b59aad
commit 83a92cd3b7
14 changed files with 228 additions and 8 deletions

View File

@@ -1,3 +0,0 @@
{
"$schema": "https://claude.ai/claude-code/settings.schema.json"
}

View File

@@ -2,13 +2,28 @@
This repository contains configurations, prompts, and tools to improve the Claude Code AI workflow.
## Setup
```bash
# Clone and install symlinks
git clone ssh://git@code.flowmade.one/flowmade-one/ai.git
cd ai
make install
```
## Project Structure
- `.claude/` - Claude Code configuration
- `commands/` - Custom slash commands (skills)
- `prompts/` - Reusable prompt templates
- `scripts/` - Automation scripts
- `hooks/` - Claude Code hooks (pre/post tool execution)
```
ai/
├── commands/ # Slash commands (/work-issue, /dashboard)
├── skills/ # Auto-triggered capabilities
├── agents/ # Subagents with isolated context
├── scripts/ # Hook scripts (pre-commit, token loading)
├── settings.json # Claude Code settings
└── Makefile # Install/uninstall symlinks
```
All files symlink to `~/.claude/` via `make install`.
## Forgejo Integration

54
Makefile Normal file
View File

@@ -0,0 +1,54 @@
.PHONY: install uninstall status
CLAUDE_DIR := $(HOME)/.claude
REPO_DIR := $(shell pwd)
# Items to symlink
ITEMS := commands scripts skills agents settings.json
install:
@echo "Installing Claude Code config symlinks..."
@mkdir -p $(CLAUDE_DIR)
@for item in $(ITEMS); do \
if [ -e "$(REPO_DIR)/$$item" ]; then \
if [ -L "$(CLAUDE_DIR)/$$item" ]; then \
echo " $$item: already symlinked"; \
elif [ -e "$(CLAUDE_DIR)/$$item" ]; then \
echo " $$item: backing up existing to $$item.bak"; \
mv "$(CLAUDE_DIR)/$$item" "$(CLAUDE_DIR)/$$item.bak"; \
ln -s "$(REPO_DIR)/$$item" "$(CLAUDE_DIR)/$$item"; \
echo " $$item: symlinked"; \
else \
ln -s "$(REPO_DIR)/$$item" "$(CLAUDE_DIR)/$$item"; \
echo " $$item: symlinked"; \
fi \
fi \
done
@echo "Done! Restart Claude Code to apply changes."
uninstall:
@echo "Removing Claude Code config symlinks..."
@for item in $(ITEMS); do \
if [ -L "$(CLAUDE_DIR)/$$item" ]; then \
rm "$(CLAUDE_DIR)/$$item"; \
echo " $$item: removed symlink"; \
if [ -e "$(CLAUDE_DIR)/$$item.bak" ]; then \
mv "$(CLAUDE_DIR)/$$item.bak" "$(CLAUDE_DIR)/$$item"; \
echo " $$item: restored backup"; \
fi \
fi \
done
@echo "Done!"
status:
@echo "Claude Code config status:"
@for item in $(ITEMS); do \
if [ -L "$(CLAUDE_DIR)/$$item" ]; then \
target=$$(readlink "$(CLAUDE_DIR)/$$item"); \
echo " $$item: symlink -> $$target"; \
elif [ -e "$(CLAUDE_DIR)/$$item" ]; then \
echo " $$item: exists (not symlinked)"; \
else \
echo " $$item: not found"; \
fi \
done

17
commands/create-issue.md Normal file
View File

@@ -0,0 +1,17 @@
---
description: Create a new Forgejo issue. Can create single issues or batch create from a plan.
argument-hint: [title] or "batch"
---
# Create Issue(s)
## Single Issue (default)
If title provided: `fj issue create "$1" --body "<description>"`
## Batch Mode
If $1 is "batch":
1. Ask user for the plan/direction
2. Generate list of issues with titles and descriptions
3. Show for approval
4. Create each: `fj issue create "<title>" --body "<body>"`
5. Display all created issue numbers

12
commands/dashboard.md Normal file
View File

@@ -0,0 +1,12 @@
---
description: Show dashboard of open issues, PRs awaiting review, and CI status.
---
# Repository Dashboard
Run these commands and present a summary:
1. **Open Issues**: `fj issue search -s open`
2. **Open PRs**: `fj pr search -s open`
Format as tables showing issue/PR number, title, and author.

18
commands/review-pr.md Normal file
View File

@@ -0,0 +1,18 @@
---
description: Review a Forgejo pull request. Fetches PR details, diff, and comments.
argument-hint: <pr-number>
---
# Review PR #$1
1. **View PR details**: `fj pr view $1`
2. **Check status**: `fj pr status $1`
3. **Get the diff**: `fj pr view $1 diff`
Review the changes and provide feedback on:
- Code quality
- Potential bugs
- Test coverage
- Documentation
Ask the user if they want to approve, request changes, or comment.

14
commands/work-issue.md Normal file
View File

@@ -0,0 +1,14 @@
---
description: Work on a Forgejo issue. Fetches issue details and sets up branch for implementation.
argument-hint: <issue-number>
---
# Work on Issue #$1
1. **View the issue**: `fj issue view $1`
2. **Create a branch**: `git checkout -b issue-$1-<short-kebab-title>`
3. **Plan**: Use TodoWrite to break down the work based on acceptance criteria
4. **Implement** the changes
5. **Commit** with message referencing the issue
6. **Push**: `git push -u origin <branch>`
7. **Create PR**: `fj pr create "[Issue #$1] <title>" --body "Closes #$1"`

View File

View File

View File

9
scripts/load-forgejo-token.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
# Load Forgejo token from macOS Keychain into Claude Code session
if [ -n "$CLAUDE_ENV_FILE" ]; then
TOKEN=$(security find-generic-password -a "$USER" -s "forgejo-token" -w 2>/dev/null)
if [ -n "$TOKEN" ]; then
echo "export FORGEJO_TOKEN=\"$TOKEN\"" >> "$CLAUDE_ENV_FILE"
fi
fi
exit 0

50
scripts/pre-commit-checks.sh Executable file
View File

@@ -0,0 +1,50 @@
#!/bin/bash
# Pre-commit validation script for Claude Code
# Validates YAML, checks for secrets, validates K8s manifests
set -e
# Get staged files
STAGED_FILES=$(git diff --cached --name-only 2>/dev/null || echo "")
if [ -z "$STAGED_FILES" ]; then
exit 0
fi
# Check for potential secrets in staged files
echo "Checking for potential secrets..."
SECRET_PATTERN='(password|secret|token|api_key|apikey|private_key).*[=:].{20,}'
if echo "$STAGED_FILES" | xargs grep -l -iE "$SECRET_PATTERN" 2>/dev/null | grep -v '.sops.yaml' | grep -v 'secret.*\.enc\.yaml'; then
echo "WARNING: Potential secrets detected in staged files (excluding SOPS-encrypted files)"
echo "Please verify these are encrypted or not actual secrets."
fi
# Validate YAML syntax
echo "Validating YAML syntax..."
for file in $(echo "$STAGED_FILES" | grep -E '\.ya?ml$'); do
if [ -f "$file" ]; then
if ! python3 -c "import yaml; yaml.safe_load(open('$file'))" 2>/dev/null; then
echo "ERROR: Invalid YAML syntax: $file"
exit 1
fi
fi
done
# Validate Kubernetes manifests (if kubectl available)
if command -v kubectl &>/dev/null; then
echo "Validating Kubernetes manifests..."
for file in $(echo "$STAGED_FILES" | grep -E '\.ya?ml$'); do
if [ -f "$file" ] && grep -q "^kind:" "$file" 2>/dev/null; then
# Skip SOPS-encrypted files and kustomization files
if echo "$file" | grep -qE '(\.sops\.yaml|\.enc\.yaml|kustomization\.yaml)$'; then
continue
fi
if ! kubectl apply --dry-run=client -f "$file" 2>/dev/null; then
echo "WARNING: Kubernetes validation failed: $file (may be expected for partial manifests)"
fi
fi
done
fi
echo "Pre-commit checks passed."
exit 0

34
settings.json Normal file
View File

@@ -0,0 +1,34 @@
{
"model": "opus",
"statusLine": {
"type": "command",
"command": "input=$(cat); current_dir=$(echo \"$input\" | jq -r '.workspace.current_dir'); model=$(echo \"$input\" | jq -r '.model.display_name'); style=$(echo \"$input\" | jq -r '.output_style.name'); git_info=\"\"; if [ -d \"$current_dir/.git\" ]; then cd \"$current_dir\" && branch=$(git branch --show-current 2>/dev/null) && status=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ') && git_info=\" [$branch$([ \"$status\" != \"0\" ] && echo \"*\")]\"; fi; printf \"\\033[2m$(whoami)@$(hostname -s) $(basename \"$current_dir\")$git_info | $model ($style)\\033[0m\""
},
"enabledPlugins": {
"gopls-lsp@claude-plugins-official": true
},
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "~/.claude/scripts/load-forgejo-token.sh"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash(git commit:*)",
"hooks": [
{
"type": "command",
"command": "~/.claude/scripts/pre-commit-checks.sh",
"statusMessage": "Running pre-commit checks..."
}
]
}
]
}
}