feat: Add installation tool, Claude.ai export, and skill standardization (#1)
## Summary - Add portable installation tool (`install.sh`) for cross-machine setup - Add Claude.ai export files with proper YAML frontmatter - Add multi-agent-guide v2.0 with consolidated framework template - Rename `00-claude-code-setting` → `00-our-settings-audit` (avoid reserved word) - Add YAML frontmatter to 25+ SKILL.md files for Claude Desktop compatibility ## Commits Included - `93f604a` feat: Add portable installation tool for cross-machine setup - `9b84104` feat: Add Claude.ai export for portable skill installation - `f7ab973` fix: Add YAML frontmatter to Claude.ai export files - `3fed49a` feat(multi-agent-guide): Add v2.0 with consolidated framework - `3be26ef` refactor: Rename settings-audit skill and add YAML frontmatter Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
173
custom-skills/00-our-settings-audit/code/scripts/auto_fix.py
Normal file
173
custom-skills/00-our-settings-audit/code/scripts/auto_fix.py
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Auto-Fix Script
|
||||
Applies safe fixes to Claude Code configuration with backup.
|
||||
"""
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
# serverInstructions templates for common MCP servers
|
||||
SERVER_INSTRUCTIONS = {
|
||||
"playwright": "Browser automation for web interaction. Use for: SEO audits, page analysis, screenshots, form testing, Core Web Vitals. Keywords: browser, page, screenshot, click, navigate, DOM, selector",
|
||||
"puppeteer": "Chrome automation for web testing. Use for: SEO audits, page rendering, JavaScript site testing. Keywords: browser, chrome, headless, screenshot, page",
|
||||
"notion": "Notion workspace integration. Use for: saving research, documentation, project notes, knowledge base. Keywords: notion, page, database, wiki, notes, save",
|
||||
"github": "GitHub repository management. Use for: commits, PRs, issues, code review. Keywords: git, github, commit, pull request, issue, repository",
|
||||
"postgres": "PostgreSQL database queries. Use for: data analysis, SQL queries, analytics. Keywords: sql, query, database, table, select, analytics",
|
||||
"postgresql": "PostgreSQL database queries. Use for: data analysis, SQL queries, analytics. Keywords: sql, query, database, table, select, analytics",
|
||||
"bigquery": "Google BigQuery for large-scale analysis. Use for: analytics queries, data warehouse. Keywords: bigquery, sql, analytics, data warehouse",
|
||||
"firecrawl": "Web scraping and crawling. Use for: site crawling, content extraction, competitor analysis. Keywords: crawl, scrape, extract, spider, sitemap",
|
||||
"slack": "Slack workspace integration. Use for: messages, notifications, team communication. Keywords: slack, message, channel, notification",
|
||||
"linear": "Linear issue tracking. Use for: issue management, project tracking. Keywords: linear, issue, task, project, sprint",
|
||||
"memory": "Persistent memory across sessions. Use for: storing preferences, context recall. Keywords: remember, memory, store, recall",
|
||||
"filesystem": "Local file operations. Use for: file reading/writing, directory management. Keywords: file, directory, read, write, path",
|
||||
"chrome-devtools": "Chrome DevTools for debugging. Use for: GTM debugging, network analysis, console logs. Keywords: devtools, chrome, debug, network, console",
|
||||
}
|
||||
|
||||
|
||||
class AutoFixer:
|
||||
def __init__(self, dry_run: bool = True):
|
||||
self.dry_run = dry_run
|
||||
self.fixes = []
|
||||
self.backup_dir = Path.home() / ".claude" / "backups" / datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
|
||||
def backup_file(self, path: Path) -> bool:
|
||||
"""Create backup before modifying."""
|
||||
if not path.exists():
|
||||
return True
|
||||
|
||||
try:
|
||||
backup_path = self.backup_dir / path.relative_to(Path.home())
|
||||
backup_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(path, backup_path)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not backup {path}: {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
def fix_mcp_instructions(self, settings_path: Path) -> list:
|
||||
"""Add serverInstructions to MCP servers."""
|
||||
fixes = []
|
||||
|
||||
try:
|
||||
with open(settings_path) as f:
|
||||
settings = json.load(f)
|
||||
except (json.JSONDecodeError, IOError) as e:
|
||||
return [f"Error reading {settings_path}: {e}"]
|
||||
|
||||
servers = settings.get("mcpServers", {})
|
||||
modified = False
|
||||
|
||||
for name, config in servers.items():
|
||||
if not isinstance(config, dict):
|
||||
continue
|
||||
|
||||
if "serverInstructions" in config:
|
||||
continue
|
||||
|
||||
# Find matching template
|
||||
instructions = None
|
||||
name_lower = name.lower()
|
||||
for key, template in SERVER_INSTRUCTIONS.items():
|
||||
if key in name_lower:
|
||||
instructions = template
|
||||
break
|
||||
|
||||
if not instructions:
|
||||
instructions = f"External tool: {name}. Use when this functionality is needed."
|
||||
|
||||
if self.dry_run:
|
||||
fixes.append(f"[DRY RUN] Would add serverInstructions to '{name}'")
|
||||
else:
|
||||
config["serverInstructions"] = instructions
|
||||
modified = True
|
||||
fixes.append(f"Added serverInstructions to '{name}'")
|
||||
|
||||
if modified and not self.dry_run:
|
||||
self.backup_file(settings_path)
|
||||
with open(settings_path, 'w') as f:
|
||||
json.dump(settings, f, indent=2)
|
||||
|
||||
return fixes
|
||||
|
||||
def fix_command_frontmatter(self, cmd_path: Path) -> str | None:
|
||||
"""Add frontmatter to command missing it."""
|
||||
try:
|
||||
content = cmd_path.read_text()
|
||||
except IOError:
|
||||
return None
|
||||
|
||||
if content.startswith('---'):
|
||||
return None
|
||||
|
||||
new_content = f'''---
|
||||
description: {cmd_path.stem.replace('-', ' ').title()} command
|
||||
---
|
||||
|
||||
{content}'''
|
||||
|
||||
if self.dry_run:
|
||||
return f"[DRY RUN] Would add frontmatter to {cmd_path.name}"
|
||||
|
||||
self.backup_file(cmd_path)
|
||||
cmd_path.write_text(new_content)
|
||||
return f"Added frontmatter to {cmd_path.name}"
|
||||
|
||||
def run(self) -> dict:
|
||||
"""Apply all fixes."""
|
||||
results = {"applied": [], "skipped": [], "errors": []}
|
||||
|
||||
# Fix MCP settings
|
||||
settings_paths = [
|
||||
Path.home() / ".claude" / "settings.json",
|
||||
Path.cwd() / ".claude" / "settings.json"
|
||||
]
|
||||
|
||||
for path in settings_paths:
|
||||
if path.exists():
|
||||
fixes = self.fix_mcp_instructions(path)
|
||||
results["applied"].extend(fixes)
|
||||
|
||||
# Fix commands without frontmatter
|
||||
cmd_dirs = [
|
||||
Path.home() / ".claude" / "commands",
|
||||
Path.cwd() / ".claude" / "commands"
|
||||
]
|
||||
|
||||
for cmd_dir in cmd_dirs:
|
||||
if cmd_dir.exists():
|
||||
for cmd_file in cmd_dir.glob("*.md"):
|
||||
fix = self.fix_command_frontmatter(cmd_file)
|
||||
if fix:
|
||||
results["applied"].append(fix)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Auto-fix Claude Code settings")
|
||||
parser.add_argument("--apply", action="store_true", help="Apply fixes (default is dry-run)")
|
||||
args = parser.parse_args()
|
||||
|
||||
fixer = AutoFixer(dry_run=not args.apply)
|
||||
results = fixer.run()
|
||||
|
||||
print(json.dumps(results, indent=2))
|
||||
|
||||
if fixer.dry_run:
|
||||
print("\n[DRY RUN] No changes applied. Use --apply to apply fixes.", file=sys.stderr)
|
||||
else:
|
||||
print(f"\n[APPLIED] {len(results['applied'])} fixes.", file=sys.stderr)
|
||||
if fixer.backup_dir.exists():
|
||||
print(f"Backups: {fixer.backup_dir}", file=sys.stderr)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user