diff --git a/skills-sync/SKILL.md b/skills-sync/SKILL.md index 58e77bc..227d12b 100644 --- a/skills-sync/SKILL.md +++ b/skills-sync/SKILL.md @@ -1,154 +1,80 @@ --- name: skills-sync description: > - Manages syncing, updating, and sharing Claude skills via Helloprint's GitLab repositories. Use this - skill whenever a user mentions: syncing skills, updating skills, pulling new skills, pushing skill - changes, git conflicts in skills, sharing a skill, publishing a skill, "my skills are outdated", - "get latest skills", "save my skill changes", "skill sync", "skill update", or any reference to - git operations in the context of Claude skills. Also trigger when users mention skill repos, skill - repositories, or ask how to get new skills that were shared with them. This skill is designed for - non-technical users who should never need to understand git commands directly. + Manages syncing, updating, and sharing Claude skills via Helloprint's Gitea repositories + using the Gitea MCP server. Use this skill whenever a user mentions: syncing skills, updating + skills, pulling new skills, pushing skill changes, sharing a skill, publishing a skill, + "my skills are outdated", "get latest skills", "save my skill changes", "skill sync", + "skill update", or any reference to git operations in the context of Claude skills. + This skill is designed for non-technical users who should never need to understand git commands directly. --- -# Skills Sync +# Skills Sync (Gitea MCP) -A friendly skill that handles all git operations for Claude skills behind the scenes. The user -should never need to type a git command — Claude does everything and explains what happened in -plain language. +A friendly skill that handles all git operations for Claude skills behind the scenes using +the **Gitea MCP server**. The user should never need to type a git command — Claude does +everything via MCP tools and explains what happened in plain language. ## Important Principles 1. **Never show raw git output** to the user unless they ask for it or something goes wrong 2. **Use simple language**: "download latest changes" not "git pull", "save your work" not "commit" 3. **Always confirm before pushing** — the user should approve before changes go to the team -4. **Handle conflicts gracefully** — explain what happened and offer clear choices -5. **Protect secrets** — never commit `.env` files or anything matching secret patterns +4. **Protect secrets** — never commit `.env` files or anything matching secret patterns +5. **Use Gitea MCP tools** — all operations go through the Gitea MCP server (mcp__gitea__*), not git CLI -## GitLab Configuration +## Backend: Gitea MCP -All skill repositories are hosted on Helloprint's GitLab instance. The URL pattern is: +All skill repositories are hosted on Helloprint's self-hosted Gitea instance. The Gitea MCP +server runs locally on the user's machine via stdio, bypassing any VM network restrictions. -``` -git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-{process}.git -``` +**Instance URL**: `https://gitea-6ac7y-u39382.vm.elestio.app` +**Organization**: `claude-skills` ### Helloprint Value Chain Repositories -Repos are organized around Helloprint's core value chain processes, not departments: +Repos are organized around Helloprint's 8 core value chain processes: -| Process | Lead | Repository | -|----------------------------|---------|------------------------| -| (Shared — everyone) | — | skills-shared | -| Source Products | Rick | skills-source-products | -| Add Products | Rick | skills-add-products | -| Sell Products & Services | Niels | skills-sell-products | -| Deliver Products | Rick | skills-deliver-products| -| Get Paid & Be Compliant | Lennart | skills-get-paid | -| Serve Customers | Maarten | skills-serve-customers | +| Process | Lead | Repository | +|--------------------------------|----------------|-------------------------------------| +| (Shared — everyone) | — | claude-skills/skills-shared | +| Sell Products & Services | Niels / Erwin | claude-skills/skills-sell-products | +| Add Products | Rick | claude-skills/skills-add-products | +| Source & Deliver Products | Rick | claude-skills/skills-source-deliver-products | +| Serve Customers | Lennaert | claude-skills/skills-serve-customers| +| Drive Value Through Technology | Dan | claude-skills/skills-drive-value | +| Get Paid & Be Compliant | Sven | claude-skills/skills-get-paid | +| Build the Best Team | Lizzy | claude-skills/skills-build-team | +| Steer the Future | Lennaert | claude-skills/skills-steer-future | -Full SSH URLs: -- `git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-shared.git` -- `git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-source-products.git` -- `git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-add-products.git` -- `git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-sell-products.git` -- `git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-deliver-products.git` -- `git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-get-paid.git` -- `git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-serve-customers.git` - -> **Note**: Some people work across multiple processes (e.g., Rick leads Source, Add, and Deliver). -> During setup, ask the user which process(es) they work in — they may need access to more than one repo. - -### GitLab web interface +### Web Interface To browse skills online: ``` -https://gitlab.it.helloprint.com/ai-and-automation/claude-skills/skills-{process} +https://gitea-6ac7y-u39382.vm.elestio.app/claude-skills/skills-{process} ``` -## Expected Directory Layout +## Configuration -``` -/mnt/skills/user/ -├── .skills-sync.json # Config file this skill creates -├── shared/ # Cloned from skills-shared -│ ├── .git/ -│ └── (shared skills...) -├── source-products/ # Cloned from skills-source-products -│ ├── .git/ -│ └── (process skills...) -├── sell-products/ # Cloned from skills-sell-products -│ ├── .git/ -│ └── (process skills...) -└── my-custom-skill/ # Local skill, not git-managed -``` +The sync config is stored in `.skills-sync.json` in the user's skills folder. It contains: +- Backend type (`gitea-mcp`) +- Gitea instance URL and organization +- List of repos with access levels +- User info (name, email) +- Secret patterns to exclude from commits -### First-time setup - -If `.skills-sync.json` doesn't exist, walk the user through setup: - -1. Ask for their name and email -2. Ask which process(es) they work in — show the list of six processes - - People may work in more than one process (e.g., Rick works in Source, Add, and Deliver) -3. Confirm the repos — everyone gets `skills-shared` plus their process repo(s) -4. Check that SSH access works: `ssh -T git@gitlab.it.helloprint.com` - - If this fails, tell the user: "It looks like your SSH key isn't set up for GitLab yet. Ask IT to help you set up an SSH key." -5. Clone each repo into `/mnt/skills/user/` -6. Configure git user name and email -7. Create `.skills-sync.json` to remember the setup - -```json -{ - "gitlab_host": "gitlab.it.helloprint.com", - "gitlab_group": "ai-and-automation/claude-skills", - "repos": [ - { - "name": "Shared Skills", - "path": "/mnt/skills/user/shared", - "remote_url": "git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-shared.git", - "branch": "main", - "access": "read-only" - }, - { - "name": "Sell Products & Services", - "path": "/mnt/skills/user/sell-products", - "remote_url": "git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-sell-products.git", - "branch": "main", - "access": "read-write" - } - ], - "user": { - "name": "Niels", - "email": "niels@helloprint.com" - }, - "secrets_patterns": [".env", "*.key", "*.pem", "*.secret", "*credentials*"], - "last_sync": "2026-02-27T10:00:00Z" -} -``` - -## Core Operations +## Core Operations (via Gitea MCP Tools) ### 1. Get Latest Skills ("sync" / "update") **Trigger phrases**: "update my skills", "get latest", "sync", "are my skills up to date?" -```bash -# For each repo in config: -cd - -# Stash any local changes first -git stash - -# Pull latest -git pull origin - -# Re-apply local changes if any -git stash pop -``` +Use `mcp__gitea__get_file_content` and `mcp__gitea__get_dir_content` to check for changes +in each configured repo. Compare with local files and download any updates. **Tell the user**: -- "Your skills are up to date! I pulled the latest changes from [N] skill repos." +- "Your skills are up to date!" - If there were updates: "Updated skills: [list skill folder names that changed]" -- If there were conflicts: move to conflict resolution (see below) ### 2. Save & Share Changes ("push" / "share" / "publish") @@ -156,121 +82,59 @@ git stash pop **Steps**: -1. Run `git status` to see what changed -2. Summarize changes in plain language: "You've modified the **order-tracking** skill (changed 2 files) and created a new **supplier-outreach** skill." +1. Compare local files with repo versions using `mcp__gitea__get_file_content` +2. Summarize changes: "You've modified the **order-tracking** skill and created a new **supplier-outreach** skill." 3. **Ask for confirmation**: "Would you like to share these changes with your team?" -4. Check for secrets before committing (see Security section) -5. If confirmed: - -```bash -cd -git add -A -git commit -m "" -git pull origin --rebase -git push origin -``` - +4. Check for secrets before pushing (see Security section) +5. If confirmed, use `mcp__gitea__create_file` (new files) or `mcp__gitea__update_file` (changed files) 6. Tell the user: "Your changes are now shared with the team!" -**Auto-generate commit messages** that are descriptive: -- "Update order-tracking: added carrier integration for DPD" -- "Add new skill: supplier-outreach for automated follow-ups" -- "Fix invoice-processor: corrected VAT calculation logic" - -### 3. Resolve Conflicts - -**When this happens**: Two people edited the same file. Git can't merge automatically. - -**Approach for non-technical users**: - -1. Detect the conflict after a pull -2. Read both versions (theirs and ours) -3. Explain in plain language: "It looks like both you and a colleague changed the **order-tracking** skill. Here's what's different: [summary of differences]" -4. Offer clear choices: - - **"Keep my version"** — uses the user's changes, discards the other - - **"Keep the team's version"** — uses what the team pushed, discards local changes - - **"Merge both"** — Claude intelligently combines both changes and shows the result for approval -5. After the user chooses, resolve the conflict and complete the merge - -```bash -# After resolving: -git add -git commit -m "Resolve conflict in : kept [user's choice]" -git push origin -``` - -### 4. Check Status +### 3. Check Status **Trigger phrases**: "what's changed", "skill status", "any updates available" -Run `git status` and `git log --oneline -5` on each repo. Summarize: +Compare local files against repo contents. Summarize: - Local changes not yet shared -- How many updates are available from the team -- When the last sync happened +- Updates available from the team +- When the last sync happened (from `.skills-sync.json`) -Present as a simple summary, e.g.: -"Here's the status of your skill repos: -- **Shared Skills**: Up to date (last synced 2 hours ago) -- **Sell Products**: You have 2 unsaved changes. The team pushed 3 updates since your last sync." - -### 5. View History +### 4. View History **Trigger phrases**: "who changed this skill", "what changed recently", "skill history" -```bash -git log --oneline --since="2 weeks ago" --pretty=format:"%h %an: %s (%ar)" -``` - -Present as a readable timeline: +Use `mcp__gitea__list_repo_commits` to get recent commits. Present as a readable timeline: "Recent changes to **Sell Products** skills: - Niels updated lead-qualifier (2 days ago) -- Anna added quote-generator (5 days ago) -- Niels fixed email-templates CSV handling (1 week ago)" +- Anna added quote-generator (5 days ago)" -### 6. Create a Merge Request (optional advanced workflow) +### 5. Create New Skill -**Trigger phrases**: "create a merge request", "submit for review", "MR" +**Trigger phrases**: "create a new skill", "add a skill" -If the team uses GitLab merge requests instead of direct pushes: - -1. Create a feature branch: `git checkout -b skill/-update` -2. Commit changes to the branch -3. Push the branch: `git push origin skill/-update` -4. Provide the user with a link to create the MR on GitLab: - `https://gitlab.it.helloprint.com/ai-and-automation/claude-skills/skills-/-/merge_requests/new?merge_request[source_branch]=skill/-update` -5. Tell the user: "I've prepared your changes for review. Click the link to open the merge request in GitLab, then hit 'Create merge request'." +1. Ask which process repo it belongs to +2. Create the skill folder with SKILL.md +3. Use `mcp__gitea__create_file` to push to the appropriate repo +4. Confirm: "Your new skill is now available to the team!" ## Security: Handling Secrets -### Pre-commit Secret Check +### Pre-push Secret Check -**ALWAYS run this before any commit.** Scan staged files for: +**ALWAYS run this before any push.** Scan file contents for: -```python -import re - -SECRET_PATTERNS = [ - r'(?i)(api[_-]?key|apikey)\s*[=:]\s*["\']?[\w-]{20,}', - r'(?i)(secret|password|passwd|pwd)\s*[=:]\s*["\']?[^\s"\']{8,}', - r'(?i)(token)\s*[=:]\s*["\']?[\w-]{20,}', - r'sk-[a-zA-Z0-9]{20,}', # OpenAI-style keys - r'ghp_[a-zA-Z0-9]{36}', # GitHub PATs - r'glpat-[\w-]{20,}', # GitLab personal access tokens - r'xox[bpras]-[\w-]+', # Slack tokens - r'-----BEGIN [\w ]+ KEY-----', # Private keys - r'(?i)bearer\s+[\w-]{20,}', # Bearer tokens -] -``` +- API keys, tokens, passwords +- Private keys (BEGIN ... KEY) +- Bearer tokens +- Service-specific tokens (OpenAI sk-, GitHub ghp_, GitLab glpat-, Slack xox*) **If secrets are found**: -1. **STOP** — do not commit -2. Tell the user: "I found what looks like a secret key in [filename]. I won't share this to protect your security." -3. Suggest: "You should move secrets to a `.env` file (which is git-ignored) or use the company's secret manager." +1. **STOP** — do not push +2. Tell the user: "I found what looks like a secret key in [filename]. I won't share this." +3. Suggest: "Move secrets to a `.env` file (which is git-ignored) or use the company's secret manager." ### .gitignore -Ensure every skills repo has a `.gitignore` with: - +Every skills repo should have: ``` .env .env.* @@ -283,36 +147,19 @@ __pycache__/ .DS_Store ``` -### Recommended Secrets Approach - -**For API keys and tokens used inside skills**, use this pattern: - -1. Skills reference environment variables: `os.environ.get("API_KEY")` -2. Each user has a local `.env` file (git-ignored) with their keys -3. A `.env.example` file IS committed, showing required variables without values: - ``` - # Required API keys for this skill - OPENAI_API_KEY=your-key-here - SLACK_WEBHOOK_URL=your-url-here - ``` -4. When a user clones a skill repo, Claude helps them create their `.env` from the example -5. Actual key values are distributed through a secure channel (password manager, not Slack/email) - ## Error Handling | Error | User-friendly message | |-------|----------------------| -| SSH auth failed | "I can't connect to GitLab. Your SSH key may not be set up yet — ask IT for help." | -| Repo not found | "The skills repo doesn't seem to exist at that address. Can you double-check with your process lead?" | -| Permission denied (push) | "You don't have permission to share changes to this repo. It might be read-only for your role, or you may need to create a merge request instead." | -| Network error | "I can't reach GitLab right now. Check your internet/VPN connection and try again." | -| Merge conflict | Move to conflict resolution flow (Section 3 above) | -| Detached HEAD | Silently fix with `git checkout main` before proceeding | +| MCP tool not available | "The Gitea connection isn't set up. Check that the Gitea MCP server is configured in Claude Desktop." | +| Auth failed | "I can't authenticate with Gitea. Your access token may need refreshing." | +| Repo not found | "The skills repo doesn't seem to exist. Can you double-check with your process lead?" | +| Permission denied | "You don't have permission to share changes to this repo. It might be read-only for your role." | +| File conflict | "Someone else also updated this file. Here's what's different: [summary]. Which version should we keep?" | ## Tone Guide - "I'll download the latest skills from your team" (not "git pull from origin") - "Save and share your changes" (not "commit and push") - "Someone else also edited this file" (not "merge conflict detected") -- "Your skills are up to date!" (not "Already up to date. On branch main.") -- "I'll prepare this for review on GitLab" (not "push to remote branch and open MR") +- "Your skills are up to date!" (not "Already up to date.")