skills/sync-skill-to-manager/SKILL.md
Sync a locally-developed OpenCode skill to the skill-manager npm package and (if private) the private-skills GitHub repo. Handles per-skill version bumps, public/private classification, build verification, and conventional-commit-style git push. Auto-publish to npm is handled downstream by nano-step/shared-workflows@v1 when the push to master lands. Use this skill whenever the user says 'sync skill', 'publish skill', 'push skill to manager', '/sync-skill-to-manager <name>', or asks to release/distribute a skill they just edited.
npx skillsauth add nano-step/skill-manager sync-skill-to-managerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Distribute a local OpenCode skill to its publishing channels with one command. Picks up the source skill from the user's project or global config, classifies it as public or private, copies to the right repo(s), bumps per-skill versions, builds, commits, and pushes.
npm publish is NOT this skill's job anymore. The nano-step/shared-workflows@v1 publish-stable reusable workflow on nano-step/skill-manager's master branch handles npm publish automatically when this skill's push lands — including bumping skill-manager's own package.json version, generating CHANGELOG.md, tagging, and creating the GitHub Release. This skill stops at git push.
/sync-skill-to-manager <skill-name> # sync + commit + push (auto-publish takes over on master)
/sync-skill-to-manager <skill-name> --dry-run # preview only
/sync-skill-to-manager <skill-name> --no-push # local commit only (manual push later)
| Var | Value |
|---|---|
| SKILL_MANAGER_REPO | /Users/tamlh/workspaces/self/AI/Tools/skill-manager |
| PRIVATE_SKILLS_REPO | /Users/tamlh/workspaces/self/AI/Tools/private-skills |
| PRIVATE_CATALOG | ${SKILL_MANAGER_REPO}/private-catalog.json |
If those paths don't exist, abort with a clear error — don't try to "find" them.
${PWD}/.opencode/skills/<name>/SKILL.md (if it exists)~/.config/opencode/skills/<name>/SKILL.mdThe "source skill" is the directory that contains SKILL.md. We always copy the whole directory (references/, assets/, scripts/, checklists/, CHANGELOG.md, etc.).
Read ${PRIVATE_CATALOG} once. Then:
| Condition | Classification |
|---|---|
| <name> IS in private-catalog.json | private |
| <name> is NOT in private-catalog.json AND ${SKILL_MANAGER_REPO}/skills/<name>/ exists | public |
| <name> exists in neither place (brand new) | ASK USER: public or private? |
| Source | Destination | What gets bundled in npm |
|---|---|---|
| Public skill | ${SKILL_MANAGER_REPO}/skills/<name>/ | YES — full skill files |
| Private skill | ${PRIVATE_SKILLS_REPO}/skills/<name>/ AND private-catalog.json entry | NO files — only the catalog entry. Users with a token fetch from GitHub at install time. |
Privacy leak fix: skill-manager's installer prefers local skills/ over the GitHub private fetch. If a private skill is physically present in ${SKILL_MANAGER_REPO}/skills/, it will install without auth. The sync MUST detect this and offer to remove the leaked copy:
⚠️ '<name>' is private but a copy exists at ${SKILL_MANAGER_REPO}/skills/<name>/.
This bypasses authentication. Remove it? (yes/no)
Only proceed with the sync after the user decides.
Pre-flight runs the helper script scripts/sync.sh for the heavy lifting. The orchestrator (this skill) handles user prompts, classification decisions, and final summary. The helper handles file mirroring, build verification, and git operations. No npm operations.
Run scripts/preflight.sh <name>. It exits non-zero with a specific message if any check fails:
${SKILL_MANAGER_REPO} and ${PRIVATE_SKILLS_REPO} existSKILL.md exists and has parseable YAML frontmatterskill.json exists and is valid JSON with name, version, descriptiongh auth status shows kokorolx as activegrep -rE 'gho_[A-Za-z0-9]{30,}|ghp_[A-Za-z0-9]{30,}|AKIA[0-9A-Z]{16}' — abort if matches foundgit -C ${SKILL_MANAGER_REPO} status --porcelain is empty (or only matches the files we're about to touch)git -C ${PRIVATE_SKILLS_REPO} status --porcelain is empty (only checked if private)(npm whoami is no longer checked — this skill does not publish to npm. That's handled by the auto-publish workflow on the server side using the org-level NPM_TOKEN.)
If any fails: report the exact failure and stop. Do not auto-fix.
After preflight:
private-catalog.json for <name>${SKILL_MANAGER_REPO}/skills/<name>/ and ${PRIVATE_SKILLS_REPO}/skills/<name>/📦 sync plan for '<name>'
Classification: <public|private>
Source: <resolved-source-path> (v<source-version>)
Targets:
• <target-path-1> (currently v<remote-version>)
• <target-path-2> (catalog entry only)
Version action: <use-as-is | bump-patch | abort-source-behind>
Commits: <count> across <repo-count> repo(s)
Push: <yes|no>
npm publish: (handled by auto-publish workflow on master push)
Proceed? (yes/no)
Source-of-truth for version: source skill's skill.json (skill-manager reads this).
| Source vs remote skill.json version | Action |
|---|---|
| Source > remote | Use source as-is. Copy SKILL.md frontmatter version too. |
| Source == remote | Auto-bump patch in source (and propagate). Print "auto-bumped <name> v<X> → v<Y>". |
| Source < remote | Abort with: "Source v<X> is behind remote v<Y>. Pull or set source version manually." |
If the version is bumped, also update:
SKILL.md YAML frontmatter metadata.versionskill.json versionprivate-catalog.json entry's version (private only)Use scripts/version-bump.sh for the patch bump (semver-aware).
If brand-new:
skill.json name + description (truncated to one line). Insert into ${SKILL_MANAGER_REPO}/README.md's "Public Skills" table, alphabetized. Show diff. Ask confirm.private-catalog.json (alphabetized) AND insert into the "Private Skills" table in README. Show diff. Ask confirm.If user rejects the diff → still copy files but skip the README update (with a printed reminder).
public:
rsync -a --delete <source>/ ${SKILL_MANAGER_REPO}/skills/<name>/
private:
rsync -a --delete <source>/ ${PRIVATE_SKILLS_REPO}/skills/<name>/
# If leak removal confirmed:
rm -rf ${SKILL_MANAGER_REPO}/skills/<name>
--delete ensures removed source files are also removed from target (avoids stale files lingering across syncs).
Do NOT copy: .git/, node_modules/, .checkpoints/, .DS_Store. Use --exclude flags.
cd ${SKILL_MANAGER_REPO}
npm run build
If build fails → abort. Do NOT commit broken state.
This step exists as a local smoke test — it catches TypeScript errors before pushing broken code to master. The auto-publish workflow on master will also build (via prepublishOnly), but failing fast locally is friendlier.
skill-manager's package.json version is NOT touched by this skill. The auto-publish workflow inspects the conventional-commit message and patches/minors/majors the version itself. Adding our own bump here would cause double-bumps.
Use scripts/commit.sh which runs (per repo) with conventional-commit messages:
skill-manager commit message templates:
feat(<name>): add v<X.Y.Z>feat(<name>): sync v<old> → v<new> (or chore(<name>): sync v<X> if patch only)feat(<name>): add to private catalog v<X.Y.Z>chore(<name>): bump catalog to v<X.Y.Z>fix: remove leaked private skill <name> from public bundleThese can be combined into a single commit when they belong together.
Why the conventional-commit type matters now: The auto-publish workflow translates types into semver bumps — feat: → minor bump on skill-manager, fix:/chore:/docs: → patch bump, anything with ! or BREAKING CHANGE → major bump. Pick the type that reflects the impact on @nano-step/skill-manager users.
private-skills commit message:
feat(<name>): add v<X.Y.Z>feat(<name>): sync v<old> → v<new> (or chore if patch)(The private-skills repo does not yet have its own auto-publish workflow — commit type there is informational only.)
NEVER add Co-authored-by, Signed-off-by, or AI attribution trailers (per workspace AGENTS.md).
If --no-push not set:
git -C ${SKILL_MANAGER_REPO} push
git -C ${PRIVATE_SKILLS_REPO} push # only if private
The skill-manager remote is HTTPS+token. The private-skills remote uses both SSH (fetch) and HTTPS+token (push) — git push will use the push URL. Both rely on the embedded token or gh auth setup-git. If push fails on auth → STOP and surface the error verbatim.
As soon as the push to master lands, GitHub Actions fires nano-step/skill-manager's Publish Stable workflow (calls nano-step/shared-workflows@v1). That workflow takes over: it inspects the commit, picks the semver bump, updates package.json, regenerates CHANGELOG.md, commits with [skip ci], tags vX.Y.Z, runs npm publish --tag latest, and creates a GitHub Release. You are done from this skill's perspective.
Print:
✅ sync complete for '<name>'
Classification: <public|private>
Source version: v<X.Y.Z>
Commits:
• skill-manager: <sha-short> <subject>
• private-skills: <sha-short> <subject> (if applicable)
Pushed:
• https://github.com/nano-step/skill-manager/commit/<sha>
• https://github.com/nano-step/private-skills/commit/<sha> (if applicable)
Auto-publish: triggered on push to master.
Watch: https://github.com/nano-step/skill-manager/actions
Once the run completes, install with:
npx @nano-step/skill-manager update <name>
| Flag | Effect |
|---|---|
| --dry-run | Print the full plan and exit. No writes, no git. |
| --no-push | Commit locally but don't push. (Auto-publish doesn't fire until you push.) |
| --force | Skip dirty-state check. Still requires explicit user yes confirmation. |
| --source <path> | Override source skill location (skip resolution). |
| --classify public\|private | Override classification (required for brand-new skills). |
| --remove-leak | Required when syncing a private skill that has a leaked copy in skill-manager/skills/. Removes the leaked copy as part of the commit. |
--no-publish was removed in v2.0.0 — this skill no longer publishes to npm. Auto-publish is now handled by nano-step/shared-workflows@v1 on nano-step/skill-manager's master branch.
| Failure | Message |
|---|---|
| Source not found | Source skill '<name>' not found in .opencode/skills or ~/.config/opencode/skills |
| Both sources exist | (interactive prompt) |
| Source version behind | Source v<X> is behind remote v<Y>. Pull latest or set source version manually. |
| Token leak | Token-like pattern detected in <file>:<line>. Refusing to sync. Remove the secret first. |
| Dirty repo | <repo> has uncommitted changes:\n<status output>\nCommit, stash, or pass --force. |
| gh auth wrong account | Expected gh active account 'kokorolx', got '<user>'. Run: gh auth switch -u kokorolx |
| Build failed | npm run build failed in skill-manager. Output:\n<output>\nNot committing. |
| Push failed | git push to <remote> failed:\n<output>\nManual intervention required. |
| Privacy leak detected | (interactive prompt) |
--no-push overrides)npm publish — that's the auto-publish workflow's job. This skill must never call npm publish, npm version, or modify skill-manager's top-level package.json version field.Co-authored-by to commits${SKILL_MANAGER_REPO}/skills/skills/) major or minor version automatically — only patchgit push --force everThe orchestrator delegates the mechanical work to small bash scripts shipped alongside this skill:
scripts/sync.sh <name> [flags] — main entry point; coordinates the othersscripts/preflight.sh <name> — all pre-flight checks (exits non-zero on failure)scripts/version-bump.sh <type> <skill-json-path> — patch-only semver bumpscripts/commit.sh <repo> <message> — conventional commit with no AI trailersThese are kept short and composable so the orchestrator can call them step-by-step and intercept on failure. See scripts/README.md for invocation details.
tools
Humanization layer for LLM conversation — makes the model sound and respond like a real, thoughtful, embodied human rather than an assistant or chatbot. Use whenever the reply will be read by a human and warmth, presence, or texture matter more than machine-readability. Triggers on any of: "human", "humans", "humanize", "humanization", "be human", "more human", "feel human", "people", "person", "real person", "real human", "friend", "friendly", "like a friend", "respond like a friend", "buddy", "talk", "talking", "talk to me", "talk like a person", "chat", "chatting", "conversation", "converse", "discuss", "discussion", "communication", "communicate", "listen", "just listen", "sit with me", "vent", "venting", "I just want to vent", "company", "presence", "stop being an AI", "stop sounding like a bot", "less corporate", "less robotic", "less formal", "warmer", "warm tone", "empathy", "empathetic", "comfort", "support me", "emotional support", "be honest with me", "be real with me", "real talk", "heart-to-heart", "deep conversation", "casual", "casual chat", "small talk", "chitchat", "say something", "tell me something", and on any emotional / relational / personal-decision / interpersonal context — grief, joy, anger, fear, shame, doubt, loneliness, dating, breakup, conflict, family, parents, sibling, friendship, marriage, divorce, in-laws, kids, parenting, work stress, burnout, career decision, quitting, firing, layoff, anxiety, depression, panic, sleep, dreams, identity, faith, doubt, meaning, mortality, celebration, milestone, achievement, gratitude, apology, forgiveness. Also loads when the user writes in non-English (any language) with emotional weight, when the user's message is shorter than 8 words and affect-laden, when the user types in lowercase fragments, when the user types in ALL CAPS with excitement, or when the user explicitly asks for a friend / mentor / older-sibling / wise-listener voice. Do NOT use for code generation, tool calls, structured data output, SQL, API contracts, or any task where machine-readability matters more than human warmth.
tools
Use this skill whenever the user mentions open-design, od_generate_design, OD daemon, BYOK design generation, generating HTML mockups from a PRD, creating or managing Open Design projects, saving design artifacts, linting generated HTML, or any of the 10 `od_*` MCP tools (od_list_projects, od_get_project, od_create_project, od_update_project, od_delete_project, od_save_artifact, od_save_project_file, od_lint_artifact, od_compose_brief, od_generate_design). Also trigger on phrases like "generate a design", "create a mockup", "make a landing page", "list my OD projects", "the design daemon", "the streaming design tool", and on any 401/404/422 error coming from an `od_*` tool call. Covers env-var setup (`OD_DAEMON_URL`, auth modes, BYOK), the full PRD → generate → save → lint workflow, error diagnosis, and the safety rails (lint before save, never commit BYOK keys). Triggers even if the user doesn't explicitly say "open-design-mcp" — keyword matches on `od_*` tool names or "design generation" workflows are enough.
tools
Use this skill whenever a user wants the **full Open Design experience** — discovery questions asked first, brand-spec extraction from URLs/files, TodoWrite planning with live updates, 5-dimensional self-critique, polished artifact at the end. Trigger phrases include "design with questions first", "OD-style workflow", "full interactive design brief", "make me a complete landing page" (when the user wants quality over speed), "design my pitch deck", "brand-aware multi-page site", "follow the Open Design playbook", or any request where the user is starting a new design project rather than tweaking an existing artifact. Also trigger on any request that mentions wanting brand consistency across multiple pages or that provides a brand URL/spec. Pair with the `open-design-mcp` tool-reference skill — both loaded together give an LLM the full picture (this skill = workflow choreography; that skill = tool catalog + errors). This skill explicitly does NOT trigger for one-off tweaks ("make the nav stickier", "swap slide 3 image") — use od_generate_design directly for those.
testing
--- name: rri-t-testing description: RRI-T QA methodology skill. Execute 5-phase testing: PREPARE, DISCOVER, STRUCTURE, EXECUTE, ANALYZE. Use before release, creating test cases, QA review, or when asked to 'test this feature', 'create test cases for', 'run QA on', 'check coverage for', 'find edge cases in', or 'does this feature work correctly'. Covers 7 dimensions and 5 personas with Vietnamese-specific locale testing built in. --- # RRI-T Testing Skill Execute comprehensive QA testing using