| name | skill-maintainer |
| description | Track upstream drift and sync adapted skill libraries |
| version | 1.0.1 |
| author | moonlight-lupin |
| license | MIT |
| platforms | ["linux","macos"] |
Skill Maintainer
Overview
A meta-skill for agents who maintain a library of skills — their own, adapted
from external repos, or published to a shared repo. Covers the full lifecycle:
authoring → curating → tracking → syncing → publishing.
This skill encodes a workflow built and battle-tested across dozens of skills.
It is agent-agnostic: replace tool names (e.g. write_file, terminal,
delegate_task) with your platform's equivalents. The patterns — manifest
tracking, layered sync, parallel diff dispatch, cron-based drift detection —
transfer to any agent runtime.
When to Use
- Creating a new skill from scratch
- Importing/adapting skills from an external repo or collection
- Checking if local skills have drifted from upstream
- Scanning for untracked external tool dependencies
- Publishing a local skill to a shared repo
- Setting up automated monthly sync checks
- Tightening/pruning an accumulated skill library
Don't use for: one-off skill creation with no upstream tracking need (just
use your platform's skill-authoring tool directly). This skill adds value when
you have ≥5 skills or ≥1 external dependency to track.
Core Concepts
The three sync layers
| Layer | Direction | What drifts | Example |
|---|
| 1. External → Local | Upstream repo → your skill | Upstream adds features, fixes bugs, changes API | baoyu-skills v1.56 → v1.117 |
| 2. Local → Published repo | Your skill → your GitHub repo | You improve locally; repo copy goes stale | skill gets new flags locally; repo doesn't |
| 3. Local → Standalone repo | Your skill → a code project repo | Skill documents a workflow; the code evolves | skill describes CLI v1; CLI is now v3 |
All three need tracking. Layer 1 is the most common concern. Layer 2 is the
most commonly forgotten — publish once, keep improving, repo goes stale.
The manifest
A single UPSTREAM_MANIFEST.md file at your skills root tracks every skill
with external provenance. One row per skill, covering all three layers. See
templates/upstream-manifest.md for the file format.
The cron job
An automated script (scripts/upstream_check.py) runs monthly, fetches
upstream versions, and reports drift. See the Cron Setup section.
Skill Authoring Workflow
0. Check for overlap before creating
Before creating a new skill:
- List existing skills in the target category
- Check if any cover the same capability — if so, extend the existing
skill rather than creating a sibling
- Check if any disabled/retired skill covers it — re-enable instead of
duplicating
1. Survey peers
Read 2–3 existing skills in the target category to match tone, structure, and
frontmatter conventions.
2. Frontmatter
Every skill needs:
---
name: my-skill-name
description: >
Use when <trigger>. <one-line behavior>.
version: 1.0.0
author: your-name
license: MIT
platforms: [linux, macos, windows]
---
3. Structure
# <Title>
## Overview — what and why (1-2 paragraphs)
## When to Use — bullet triggers + "Don't use for"
## <Topic sections> — quick-reference tables, exact commands, recipes
## Common Pitfalls — numbered list of mistakes and fixes
## Verification Checklist — checkbox list
4. Size guidelines
- Description: ≤1024 chars
- Total SKILL.md: ≤100k chars (aim for 8–15k)
- Bulky/branch-specific material →
references/*.md, linked from SKILL.md
- Scripts →
scripts/*.py, deterministic, pure stdlib where possible
5. Quality principles
- Optimize for process predictability — if a line doesn't change agent
behavior, cut it
- End steps with completion criteria — "every modified file accounted
for" beats "summarize changes"
- Co-locate rules with the concept they govern — don't scatter one idea
across the file
- Use strong leading words — "tight loop," "tracer bullet," "root cause"
over long explanations
- Prune duplication and no-ops — keep each meaning in one source of truth
- Watch for premature completion — if agents rush a step, sharpen its
completion criterion
Common quality failures: premature completion, duplication, sediment (stale
lines), sprawl (too much always-visible material), no-op prose.
6. Validate
- Frontmatter parses as YAML, starts at byte 0, closes with
\n---\n
name and description present, description ≤1024 chars
- Non-empty body after closing
---
7. Update the manifest
If the skill has external provenance (adapted from upstream, wraps a third-party
tool, or published to a repo), add a row to UPSTREAM_MANIFEST.md. This is
mandatory — an untracked skill is invisible to the monthly sync check. Skip
the manifest only for original skills with zero external dependency.
Skill Curation Workflow
1. Inventory and classify
When porting skills from an external collection, classify each:
| Class | Action |
|---|
| Keep — unique, valuable, no overlap | Adapt to your format |
| Duplicate — you already have an equivalent | Merge unique parts or skip |
| Thin/pointer — just a URL, no real content | Skip |
| Novelty — joke/toy, no practical value | Skip |
| Capability-layer/router — installer + router delegating to upstream CLIs | Evaluate each backend; don't wholesale replace native skills |
2. Assess overlap
Compare each candidate against existing skills. When two overlap, prefer your
native one unless the external one adds clear value. If merging: patch the
existing skill with unique content, discard the external copy.
3. Adapt to your format
Frontmatter: strip all framework-specific fields. Keep name,
description, version (bump for adapted), author (e.g. "Source (adapted)").
Body: full rewrite, not copy-paste:
- Translate all non-English content to English
- Strip framework-specific references, sandbox paths, proprietary tool names
- Restructure into your standard sections (When to use, body, pitfalls, verification)
- Preserve all domain detail — exact hex codes, pixel dimensions, font
names, timing, forbidden patterns — these ARE the skill's value
- Add practical trigger words
4. Quality audit
grep -cP '[\x{4e00}-\x{9fff}]' SKILL.md
grep -c 'framework-specific-term\|upstream-field' SKILL.md
grep '^version:\|^author:' SKILL.md
5. Place in correct category
Use existing categories. Don't invent new top-level categories casually.
6. Update manifest
Add a row to UPSTREAM_MANIFEST.md for every adapted skill. See the
Upstream Tracking section for entry types.
Upstream Tracking Manifest
Maintain UPSTREAM_MANIFEST.md at your skills root. One row per skill with
external provenance. See templates/upstream-manifest.md for the full template.
Entry types — pick the right table
| Type | What it tracks | Audit method |
|---|
| Adapted skill | Skill content adapted from an upstream skill repo | Diff upstream SKILL.md, compare version fields |
| Engine dependency | Skill wraps a third-party CLI/pip tool | tool --version vs GitHub releases |
| Engine-tracking skill | Original skill built around a third-party engine | pip show <pkg> + GitHub releases |
| Third-party skill | Adapted from external repo (not a skill repo per se) | Fetch README/latest, compare concepts |
| Published skill | Local skill pushed to your repo | diff local vs repo copy |
Skip the manifest for original skills with zero external dependency.
The PORT_NOTES pattern (gold standard for complex adaptations)
For skills with significant structural changes, maintain PORT_NOTES.md
inside the skill directory:
# Port Notes — <skill-name>
Ported from <repo-url> v<upstream-version>.
## Changes from upstream
| Change | Upstream | Ours |
### What was preserved
<list of verbatim-copied files>
## Syncing with upstream
<exact curl/diff commands>
<files safe to overwrite vs requiring manual merge>
Sync Audit Workflow
Run monthly or when prompted.
1. Read the manifest
Note last-checked dates. Identify stale rows (last sync >60 days).
2. Layer 1 — External → Local
For each adapted skill:
- Fetch upstream version (raw GitHub URL or GitHub API)
- Compare to pinned version in manifest
- If different, classify the source and apply the right sync strategy:
| Source type | Sync approach |
|---|
| Versioned, verbatim-heavy | Overwrite verbatim files, merge adapted files |
| Unversioned, full rewrite | Keep ours — diff for new domain content only |
| Actively evolving | Content merge — add upstream sections, preserve local wiring |
| Archived/moved | Update URLs only — upstream may have changed format |
| Low activity | One-time check, usually nothing to do |
3. Layer 2 — Local → Published repo
For each published skill, diff local vs repo copy. If local is ahead,
re-publish (debrand, generalize, push).
4. Layer 3 — Local → Standalone repo
For skills tied to code repos, check if the repo's workflow/CLI has changed.
5. Engine dependency scan
for tool in <your-tools>; do
path=$(which $tool 2>/dev/null) && echo "$tool: $path" || echo "$tool: not installed"
done
for pkg in <your-packages>; do
pip show $pkg 2>/dev/null | grep -E '^Version:'
done
curl -s https://api.github.com/repos/<owner>/<repo>/releases/latest | grep tag_name
Cross-reference with manifest — any installed tool that powers a skill but
isn't in the manifest is an untracked dependency. Add it.
6. Update manifest
Record last-checked date, new upstream version, any sync actions taken.
Parallel diff dispatch
When auditing multiple upstream sources simultaneously:
- Fetch all upstream files in one batch
- Dispatch parallel subagents per source to diff and classify
- Handle simple updates (URL fixes, verbatim overwrites) yourself
- Collect structured recommendations (keep/merge/re-port)
- Execute merges based on recommendations
This turns a serial 30-minute audit into a 5-minute parallel one.
Publishing Skills to a Public Repo
Debranding
When publishing a skill derived from a client/org-specific source:
- Grep for brand references across all files
- Remove or genericize: brand names, proprietary palettes, regulatory
references, org-internal file paths, house styles
- Remove brand-specific reference files
- Replace specific dollar amounts with generic terms
- Verify clean with grep
- Bump version for the published version
Generalizing
| Platform-specific term | Replace with |
|---|
Platform tool names (image_generate, etc.) | Generic description |
| Platform metadata fields | Remove from frontmatter |
| Hardcoded paths | Env var with fallback, or <skill_dir>/... |
| Sibling skill dependencies | Env var resolution with fallbacks |
| Platform-specific delivery | Generic "send via the user's channel" |
Testing the published version
- Scripts parse:
python3 -c "import ast; ast.parse(open('scripts/main.py').read())"
- Imports resolve:
python3 -c "from script import main_func"
- Graceful degradation works (simulate missing optional deps)
Mutual exclusivity
In a pick-and-choose repo, each skill must be self-contained and runnable
standalone, even at the cost of code duplication across siblings. Do NOT
extract shared modules — a user who clones only one skill should not need a
file from another.
Cron Setup — Automated Drift Detection
Set up a monthly cron job to automatically check for upstream drift.
1. Copy the manifest template
cp templates/upstream-manifest.md /path/to/your/skills/UPSTREAM_MANIFEST.md
Edit it to list your actual skills, upstream repos, and versions.
2. Copy the check script
cp scripts/upstream_check.py /path/to/your/scripts/
The script reads Layer 1 and Layer 2 tables directly from
UPSTREAM_MANIFEST.md. No hardcoded skill lists — the manifest is the
single source of truth.
Engine dependencies (ENGINE_DEPS) are configured in the script file
itself, not in the manifest. This is a deliberate security boundary:
manifest content is markdown that could be externally edited, so we
don't execute shell commands derived from it. Add entries like:
ENGINE_DEPS = [
{"name": "my-cli-tool", "command": ["my-cli", "--version"], "version_regex": r"(\d+\.\d+\.\d+)"},
{"name": "my-pip-pkg", "command": ["pip", "show", "my-pip-pkg"], "version_regex": r"(\d+\.\d+\.\d+)"},
]
Commands are passed as lists (never shell=True) to prevent shell
injection from untrusted config.
You may also need to set SKILLS_ROOT and LAYER_2_REPO at the top of
the script, or via the SKILLS_ROOT and LAYER_2_REPO env vars.
3. Set up the cron job
Using a generic cron scheduler (adapt to your platform):
# Monthly upstream sync check — 9am on the 1st
0 9 1 * * /path/to/python3 /path/to/scripts/upstream_check.py
Or using an agent platform's cron tool:
{
"name": "Monthly Upstream Sync Check",
"schedule": "0 9 1 * *",
"prompt": "Run the upstream sync check script at /path/to/scripts/upstream_check.py. Report any drift detected. If drift is found, summarize which skills need attention and what changed upstream.",
"no_agent": true
}
The script exits 0 if all in sync, 1 if drift detected. Non-empty stdout is
delivered as the message; empty stdout means silent (nothing to report).
4. What the script checks
- Layer 1: parses manifest table, fetches upstream SKILL.md from GitHub,
compares version fields. For sources without version fields, reports last
commit date via GitHub API. Uses the repo's default branch (falls back to
master). The upstream file location is guessed as
skills/<name>/SKILL.md unless the manifest row carries an optional
Upstream path column — add that column for upstreams with a different
layout, or the check will warn "could not fetch upstream" every run.
- Layer 2: compares local vs published repo using both version
fields and SHA-256 content hashes. Catches version drift (different
version numbers) AND content drift (same version, different content —
e.g. you edited locally but didn't bump the version or re-publish).
- Engine deps: runs configured version-check commands (list-form, no
shell) and extracts version strings.
5. Handling drift reports
When the cron reports drift:
- Read the report — which skills changed, what's the version delta
- Fetch upstream files to a temp directory
- Classify each file as verbatim (overwrite) or adapted (merge)
- For merges: take upstream as base, re-apply local adaptations
- Run jargon check — grep for upstream-specific terms that should be absent
- Update PORT_NOTES.md with sync log
- Update manifest with new version, date, and status
Extending vs Creating New Skills
When a new capability overlaps with an existing skill:
- Does an existing skill cover the core capability? → Extend it with
the missing piece (reference file, script, routing entry)
- Does it need a fundamentally different workflow/toolset? → New skill
may be warranted, but justify it first
- Is it a thin layer on existing infrastructure? → Reference file +
optional script, not a new skill
When a sub-topic grows large enough to warrant a dedicated skill, the
umbrella skill MUST point to the new skill, not keep duplicate content.
Replace inline detail with a pointer: "→ See dedicated <skill-name> skill
for: ..." Duplicate content drifts; a pointer ensures one source of truth.
Pitfalls
- Shallow ports are worthless — a skill with source jargon, missing
triggers, and no restructuring helps no one. Always do a full adaptation pass.
- Skill inflation — don't port 139 skills when 35 are valuable. Ruthlessly
delete thin/pointer/duplicate/novelty skills before adapting.
- Copy-paste trap — the source format is never the target format.
Restructure the body, don't just translate headers.
- Missing domain detail — exact hex codes, pixel sizes, font weights,
forbidden patterns ARE the skill. Stripping them destroys the value.
- Overlap blind spot — always check existing skills before adding. Two
skills doing the same thing is worse than one.
- Reverse-sync blind spot (Layer 2) — after publishing, you keep
improving locally. Without manifest tracking, the repo copy silently goes
stale. Always record push dates.
- "Keep ours" is valid — not every upstream diff requires a merge. When
your version is a superset, record the decision and move on.
- Merge subagents need explicit preserve lists — without listing what
must NOT be removed, a merge subagent may overwrite everything with upstream.
- Engine-tracking skills need different sync — compare installed version
vs latest release, not SKILL.md content. A stale binary breaks the skill
even if the SKILL.md is current.
- Silent auth dependency — a backend that "just works" on a developer's
desktop may require cookies, QR login, or a browser extension impossible
on a server. Surface the auth boundary explicitly.
- Atomic skills principle — keep skills atomic (one capability per
skill). The agent chains skills at runtime, not at design time.
- Mutual exclusivity in portable repos — each skill must be
self-contained. Don't extract shared modules; duplication is the price
of independence.
- Sediment — a skill should get shorter or sharper over time. When
adding a rule, remove the old wording it replaces.
- No-op prose — "be careful," "be thorough" rarely change behavior.
Replace with checkable completion criteria.
Verification Checklist