Update skills-sync: migrate from GitLab to Gitea MCP with correct 8 processes

This commit is contained in:
2026-03-02 10:16:24 +00:00
parent 93ed5d2f65
commit 50ed03e787
+74 -227
View File
@@ -1,154 +1,80 @@
--- ---
name: skills-sync name: skills-sync
description: > description: >
Manages syncing, updating, and sharing Claude skills via Helloprint's GitLab repositories. Use this Manages syncing, updating, and sharing Claude skills via Helloprint's Gitea repositories
skill whenever a user mentions: syncing skills, updating skills, pulling new skills, pushing skill using the Gitea MCP server. Use this skill whenever a user mentions: syncing skills, updating
changes, git conflicts in skills, sharing a skill, publishing a skill, "my skills are outdated", skills, pulling new skills, pushing skill changes, sharing a skill, publishing a skill,
"get latest skills", "save my skill changes", "skill sync", "skill update", or any reference to "my skills are outdated", "get latest skills", "save my skill changes", "skill sync",
git operations in the context of Claude skills. Also trigger when users mention skill repos, skill "skill update", or any reference to git operations in the context of Claude skills.
repositories, or ask how to get new skills that were shared with them. This skill is designed for This skill is designed for non-technical users who should never need to understand git commands directly.
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 A friendly skill that handles all git operations for Claude skills behind the scenes using
should never need to type a git command — Claude does everything and explains what happened in the **Gitea MCP server**. The user should never need to type a git command — Claude does
plain language. everything via MCP tools and explains what happened in plain language.
## Important Principles ## Important Principles
1. **Never show raw git output** to the user unless they ask for it or something goes wrong 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" 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 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 4. **Protect secrets** — never commit `.env` files or anything matching secret patterns
5. **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.
``` **Instance URL**: `https://gitea-6ac7y-u39382.vm.elestio.app`
git@gitlab.it.helloprint.com:ai-and-automation/claude-skills/skills-{process}.git **Organization**: `claude-skills`
```
### Helloprint Value Chain Repositories ### 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 | | Process | Lead | Repository |
|----------------------------|---------|------------------------| |--------------------------------|----------------|-------------------------------------|
| (Shared — everyone) | — | skills-shared | | (Shared — everyone) | — | claude-skills/skills-shared |
| Source Products | Rick | skills-source-products | | Sell Products & Services | Niels / Erwin | claude-skills/skills-sell-products |
| Add Products | Rick | skills-add-products | | Add Products | Rick | claude-skills/skills-add-products |
| Sell Products & Services | Niels | skills-sell-products | | Source & Deliver Products | Rick | claude-skills/skills-source-deliver-products |
| Deliver Products | Rick | skills-deliver-products| | Serve Customers | Lennaert | claude-skills/skills-serve-customers|
| Get Paid & Be Compliant | Lennart | skills-get-paid | | Drive Value Through Technology | Dan | claude-skills/skills-drive-value |
| Serve Customers | Maarten | skills-serve-customers | | 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: ### Web Interface
- `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
To browse skills online: 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
``` The sync config is stored in `.skills-sync.json` in the user's skills folder. It contains:
/mnt/skills/user/ - Backend type (`gitea-mcp`)
├── .skills-sync.json # Config file this skill creates - Gitea instance URL and organization
├── shared/ # Cloned from skills-shared - List of repos with access levels
│ ├── .git/ - User info (name, email)
│ └── (shared skills...) - Secret patterns to exclude from commits
├── 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
```
### First-time setup ## Core Operations (via Gitea MCP Tools)
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
### 1. Get Latest Skills ("sync" / "update") ### 1. Get Latest Skills ("sync" / "update")
**Trigger phrases**: "update my skills", "get latest", "sync", "are my skills up to date?" **Trigger phrases**: "update my skills", "get latest", "sync", "are my skills up to date?"
```bash Use `mcp__gitea__get_file_content` and `mcp__gitea__get_dir_content` to check for changes
# For each repo in config: in each configured repo. Compare with local files and download any updates.
cd <repo_path>
# Stash any local changes first
git stash
# Pull latest
git pull origin <branch>
# Re-apply local changes if any
git stash pop
```
**Tell the user**: **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 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") ### 2. Save & Share Changes ("push" / "share" / "publish")
@@ -156,121 +82,59 @@ git stash pop
**Steps**: **Steps**:
1. Run `git status` to see what changed 1. Compare local files with repo versions using `mcp__gitea__get_file_content`
2. Summarize changes in plain language: "You've modified the **order-tracking** skill (changed 2 files) and created a new **supplier-outreach** skill." 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?" 3. **Ask for confirmation**: "Would you like to share these changes with your team?"
4. Check for secrets before committing (see Security section) 4. Check for secrets before pushing (see Security section)
5. If confirmed: 5. If confirmed, use `mcp__gitea__create_file` (new files) or `mcp__gitea__update_file` (changed files)
```bash
cd <repo_path>
git add -A
git commit -m "<auto-generated descriptive message>"
git pull origin <branch> --rebase
git push origin <branch>
```
6. Tell the user: "Your changes are now shared with the team!" 6. Tell the user: "Your changes are now shared with the team!"
**Auto-generate commit messages** that are descriptive: ### 3. Check Status
- "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 <resolved_files>
git commit -m "Resolve conflict in <skill-name>: kept [user's choice]"
git push origin <branch>
```
### 4. Check Status
**Trigger phrases**: "what's changed", "skill status", "any updates available" **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 - Local changes not yet shared
- How many updates are available from the team - Updates available from the team
- When the last sync happened - When the last sync happened (from `.skills-sync.json`)
Present as a simple summary, e.g.: ### 4. View History
"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
**Trigger phrases**: "who changed this skill", "what changed recently", "skill history" **Trigger phrases**: "who changed this skill", "what changed recently", "skill history"
```bash Use `mcp__gitea__list_repo_commits` to get recent commits. Present as a readable timeline:
git log --oneline --since="2 weeks ago" --pretty=format:"%h %an: %s (%ar)"
```
Present as a readable timeline:
"Recent changes to **Sell Products** skills: "Recent changes to **Sell Products** skills:
- Niels updated lead-qualifier (2 days ago) - Niels updated lead-qualifier (2 days ago)
- Anna added quote-generator (5 days ago) - Anna added quote-generator (5 days ago)"
- Niels fixed email-templates CSV handling (1 week 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. Ask which process repo it belongs to
2. Create the skill folder with SKILL.md
1. Create a feature branch: `git checkout -b skill/<skill-name>-update` 3. Use `mcp__gitea__create_file` to push to the appropriate repo
2. Commit changes to the branch 4. Confirm: "Your new skill is now available to the team!"
3. Push the branch: `git push origin skill/<skill-name>-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-<process>/-/merge_requests/new?merge_request[source_branch]=skill/<skill-name>-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'."
## Security: Handling Secrets ## 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 - API keys, tokens, passwords
import re - Private keys (BEGIN ... KEY)
- Bearer tokens
SECRET_PATTERNS = [ - Service-specific tokens (OpenAI sk-, GitHub ghp_, GitLab glpat-, Slack xox*)
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
]
```
**If secrets are found**: **If secrets are found**:
1. **STOP** — do not commit 1. **STOP** — do not push
2. Tell the user: "I found what looks like a secret key in [filename]. I won't share this to protect your security." 2. Tell the user: "I found what looks like a secret key in [filename]. I won't share this."
3. Suggest: "You should move secrets to a `.env` file (which is git-ignored) or use the company's secret manager." 3. Suggest: "Move secrets to a `.env` file (which is git-ignored) or use the company's secret manager."
### .gitignore ### .gitignore
Ensure every skills repo has a `.gitignore` with: Every skills repo should have:
``` ```
.env .env
.env.* .env.*
@@ -283,36 +147,19 @@ __pycache__/
.DS_Store .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 Handling
| Error | User-friendly message | | 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." | | MCP tool not available | "The Gitea connection isn't set up. Check that the Gitea MCP server is configured in Claude Desktop." |
| Repo not found | "The skills repo doesn't seem to exist at that address. Can you double-check with your process lead?" | | Auth failed | "I can't authenticate with Gitea. Your access token may need refreshing." |
| 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." | | Repo not found | "The skills repo doesn't seem to exist. Can you double-check with your process lead?" |
| Network error | "I can't reach GitLab right now. Check your internet/VPN connection and try again." | | Permission denied | "You don't have permission to share changes to this repo. It might be read-only for your role." |
| Merge conflict | Move to conflict resolution flow (Section 3 above) | | File conflict | "Someone else also updated this file. Here's what's different: [summary]. Which version should we keep?" |
| Detached HEAD | Silently fix with `git checkout main` before proceeding |
## Tone Guide ## Tone Guide
- "I'll download the latest skills from your team" (not "git pull from origin") - "I'll download the latest skills from your team" (not "git pull from origin")
- "Save and share your changes" (not "commit and push") - "Save and share your changes" (not "commit and push")
- "Someone else also edited this file" (not "merge conflict detected") - "Someone else also edited this file" (not "merge conflict detected")
- "Your skills are up to date!" (not "Already up to date. On branch main.") - "Your skills are up to date!" (not "Already up to date.")
- "I'll prepare this for review on GitLab" (not "push to remote branch and open MR")