git clone https://github.com/Aradotso/trending-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/Aradotso/trending-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/chops-ai-skills-manager" ~/.claude/skills/aradotso-trending-skills-chops-ai-skills-manager && rm -rf "$T"
skills/chops-ai-skills-manager/SKILL.md--- name: chops-ai-skills-manager description: macOS app to browse, edit, and manage AI agent skills across Claude Code, Cursor, Codex, Windsurf, and Amp triggers: - manage my AI agent skills - organize claude code skills - add a new skill to cursor - browse skills across AI tools - edit my agent skills files - set up chops on my mac - create a new skill file - sync skills between AI coding tools --- # Chops — AI Agent Skills Manager > Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection. Chops is a native macOS app (SwiftUI + SwiftData) that discovers, organizes, and edits AI coding agent skill files across Claude Code, Cursor, Codex, Windsurf, Copilot, Aider, and Amp — all in one place, with real-time file watching, full-text search, and a built-in markdown editor. ## Installation ### Download the App ```bash # Direct download curl -L https://github.com/Shpigford/chops/releases/latest/download/Chops.dmg -o Chops.dmg open Chops.dmg
Or visit chops.md and click Download.
Build from Source
Prerequisites:
- macOS 15 (Sequoia) or later
- Xcode with command-line tools
- Homebrew
# Install dependencies xcode-select --install brew install xcodegen # Clone and build git clone https://github.com/Shpigford/chops.git cd chops xcodegen generate # generates Chops.xcodeproj from project.yml open Chops.xcodeproj # then press Cmd+R to build and run
CLI Build (Headless)
xcodebuild -scheme Chops -configuration Debug build
Note: The
is generated from.xcodeproj. Always editproject.ymland re-runproject.yml— never editxcodegen generatedirectly..xcodeproj
Where Skills Live
Chops scans these directories automatically:
| Tool | Scanned Paths |
|---|---|
| Claude Code | , |
| Cursor | , |
| Windsurf | , |
| Codex | |
| Amp | |
Copilot and Aider only detect project-level skills (no global paths). Custom paths can be added per tool in Settings.
Skill File Format
Skills are Markdown files with YAML frontmatter:
--- name: my-skill-name description: One-line description of what this skill does triggers: - phrase users might say - another trigger phrase - add 6-8 total triggers --- # Skill Title Main skill content in Markdown...
Cursor uses
.mdc files with the same frontmatter format. Chops handles both automatically.
Key Features
Multi-Tool Support
Chops reads and writes skills for all major AI coding agents. Skills are deduplicated by resolved symlink path — symlinked files appear once with multiple tool badges.
Built-in Editor
- Monospaced
-based editorNSTextView - Cmd+S to save
- Frontmatter is parsed and displayed as structured metadata
- Changes are written directly to the source
or.md
file.mdc
Collections
Group skills logically without moving or modifying source files. Collections are stored in SwiftData, not on disk.
Real-Time File Watching
FSEvents-based watcher detects disk changes instantly and triggers a re-scan. No manual refresh needed.
Full-Text Search
Search across skill name, description, and full content simultaneously.
Remote Skill Servers
Connect to remote servers (e.g., OpenClaw) to discover, browse, and install community skills.
Project Structure
Chops/ ├── App/ │ ├── ChopsApp.swift # @main — SwiftData ModelContainer + Sparkle updater │ ├── AppState.swift # @Observable singleton — all UI state │ └── ContentView.swift # Three-column NavigationSplitView ├── Models/ │ ├── Skill.swift # @Model — a discovered skill file │ ├── Collection.swift # @Model — user-created groupings │ └── ToolSource.swift # Enum of tools, their paths and icons ├── Services/ │ ├── SkillScanner.swift # Probes directories, upserts skills into SwiftData │ ├── SkillParser.swift # Routes to FrontmatterParser or MDCParser │ ├── FileWatcher.swift # FSEvents listener → triggers re-scan │ └── SearchService.swift # In-memory full-text search ├── Utilities/ │ ├── FrontmatterParser.swift # Extracts YAML frontmatter from .md files │ └── MDCParser.swift # Parses Cursor .mdc files └── Views/ ├── Sidebar/ # Tool filters, collection list ├── Detail/ # Skill editor, metadata display ├── Settings/ # Preferences & Sparkle update UI └── Shared/ # ToolBadge, NewSkillSheet, etc.
Development: Common Tasks
Add a New Tool
Edit
Chops/Models/ToolSource.swift:
enum ToolSource: String, CaseIterable, Codable { // ... existing cases ... case myNewTool var displayName: String { switch self { case .myNewTool: return "My New Tool" // ... } } var globalPaths: [String] { switch self { case .myNewTool: return ["~/.mynewtools/skills"] // ... } } var color: Color { switch self { case .myNewTool: return .purple // ... } } var iconName: String { switch self { case .myNewTool: return "wand.and.stars" // ... } } // Optional: return asset name if you add a logo to the asset catalog var logoAssetName: String? { switch self { case .myNewTool: return "MyNewToolLogo" default: return nil } } }
If the tool uses a non-standard file layout, also update
Chops/Services/SkillScanner.swift.
Add Custom Frontmatter Parsing
Edit
Chops/Utilities/FrontmatterParser.swift:
struct FrontmatterParser { static func parse(_ content: String) -> (metadata: [String: Any], body: String) { // Frontmatter is delimited by --- on its own line // Returns structured metadata dict + remaining markdown body guard content.hasPrefix("---") else { return ([:], content) } // ... parsing logic } }
Support a New File Extension
Edit
Chops/Services/SkillParser.swift to add dispatch logic:
static func parse(fileURL: URL) -> SkillMetadata { switch fileURL.pathExtension { case "mdc": return MDCParser.parse(fileURL: fileURL) case "md", "markdown": return FrontmatterParser.parse(fileURL: fileURL) case "txt": // Add handling for plain text skills return PlainTextParser.parse(fileURL: fileURL) default: return SkillMetadata(name: fileURL.lastPathComponent) } }
Modify the UI Layout
The main layout is a three-column
NavigationSplitView in Chops/App/ContentView.swift:
NavigationSplitView { SidebarView() // Column 1: tool filters + collections } content: { SkillListView() // Column 2: filtered/searched skill list } detail: { SkillDetailView() // Column 3: editor + metadata }
State Management
AppState is the single source of truth for all UI state:
@Observable class AppState { var selectedTool: ToolSource? // current sidebar filter var selectedSkill: Skill? // currently open skill var searchText: String = "" // full-text search query var sidebarMode: SidebarMode // .tools or .collections }
Access it in any view via
@Environment:
struct MyView: View { @Environment(AppState.self) var appState var body: some View { Text("Searching: \(appState.searchText)") } }
Creating a Skill for Your Own Project
If your project is used with Chops-supported AI tools, create a skill file so agents have instant context:
# For Claude Code mkdir -p .claude/skills cat > .claude/skills/setup.md << 'EOF' --- name: my-project-setup description: Architecture and key patterns for MyProject triggers: - how does myproject work - set up myproject - myproject architecture --- # MyProject [Describe your project here for AI agents] EOF
Chops will automatically discover and display this skill.
Troubleshooting
App Can't Find My Skills
- Verify the skill files exist at the expected paths (see table above)
- Check that file extensions are
or.md.mdc - Use File → Rescan or restart the app to force a fresh scan
- Chops disables the macOS sandbox intentionally for unrestricted
access — if you built from source, confirm~/
hasChops.entitlements
set tocom.apple.security.app-sandboxfalse
Skills Not Updating After Edit
- The FSEvents watcher should catch changes automatically
- If it doesn't, save the file again or trigger a rescan
- Ensure the file is in a directory Chops watches (custom paths can be added in Settings)
Frontmatter Not Parsed
- Ensure the file starts with
on the very first line (no leading whitespace or BOM)--- - YAML must be valid — test with a YAML linter
- Cursor
files use the same frontmatter format but a different parser — ensure the extension is correct.mdc
Build Fails After Pulling Changes
# Regenerate the Xcode project after any project.yml changes xcodegen generate
Sparkle Update Issues
Sparkle is pulled automatically via Swift Package Manager. If SPM resolution fails:
# In Xcode: File → Packages → Reset Package Caches # Or from terminal: rm -rf ~/Library/Caches/org.swift.swiftpm xcodebuild -resolvePackageDependencies
Website (Marketing Site)
cd site npm install # first time only npm run dev # local dev server at localhost:4321 npm run build # production build → site/dist/
Built with Astro 6.
Architecture Notes
- No sandbox — Required for reading dotfiles across
. Intentional and documented in~/
.Chops.entitlements - Dedup via symlinks — Skills identified by resolved symlink path; same file in multiple tool dirs = one skill, multiple tool badges.
- No automated tests — Validate manually: build → trigger feature → observe result → test edge cases.
- SwiftData persistence —
andSkill
models are persisted; scanning upserts (never duplicates) discovered skills.SkillCollection