Install
$ agentstack add skill-pengguanya-claude-toolkit-publish-skill ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Publish Skill
Manage skills between a private skills directory and a public toolkit repo.
Configuration
This skill stores its configuration in a JSON file next to this SKILL.md:
/config.json
The config file contains:
{
"SKILLS_DIR": "~/.claude/skills",
"TOOLKIT_DIR": "~/path/to/your/toolkit",
"TOOLKIT_SKILLS": "~/path/to/your/toolkit/skills"
}
First-run setup
Before executing ANY workflow, check if config.json exists in this skill's directory. If it does NOT exist:
- Tell the user: "This is your first time running publish-skill. I need to know where your toolkit repo and skills directory are."
- Ask for SKILLS_DIR — "Where are your Claude Code skills stored?" (default:
~/.claude/skills) - Ask for TOOLKIT_DIR — "Where is your public toolkit git repo?" (no default — user must provide this)
- Set TOOLKIT_SKILLS to
$TOOLKIT_DIR/skillsand confirm with user - Write the config to
config.jsonnext to this SKILL.md - Continue with the requested workflow
If config.json exists, read it and use those values for all paths below.
All commands below use $SKILLS_DIR, $TOOLKIT_DIR, and $TOOLKIT_SKILLS — substitute the values from config.json.
Arguments
$ARGUMENTS
| Input | Action | |---|---| | promote | Move private skill to public toolkit, replace local with symlink | | fork [--public-name ] | Create generalized public copy, keep private version | | adopt | Install public skill and customize as private | | status | Show which skills are private, public, or symlinked | | diff | For forked skills: show diff between private and public versions | | Empty or help | Explain available modes |
Workflow: Status
Run this first to understand the current state.
# List all skills and their status
for dir in $SKILLS_DIR/*/; do
name=$(basename "$dir")
if [ -L "${dir%/}" ]; then
target=$(readlink -f "${dir%/}")
echo "SYMLINKED $name -> $target"
elif [ -d $TOOLKIT_SKILLS/"$name" ]; then
echo "FORKED $name (private + public versions)"
else
echo "PRIVATE $name"
fi
done
# Show public skills not installed locally
for dir in $TOOLKIT_SKILLS/*/; do
name=$(basename "$dir")
[ -e $SKILLS_DIR/"$name" ] || echo "PUBLIC_ONLY $name (not installed locally)"
done
Present as a table:
| Skill | Status | Notes | |---|---|---| | my-skill | SYMLINKED | -> $TOOLKIT_SKILLS/my-skill | | other-skill | PRIVATE | local only | | ... | ... | ... |
Workflow: Promote
Moves a private skill to the public toolkit and replaces local with a symlink.
Preconditions (check ALL before proceeding)
- Skill exists at
$SKILLS_DIR//and is a directory (not a symlink) $TOOLKIT_DIR/exists and is a git repo- No existing public skill with same name in
$TOOLKIT_SKILLS/
If any precondition fails, report the issue and stop.
Steps
Step 1 — Analyze for personal content
Read ALL files in the skill directory (SKILL.md, scripts, configs) and scan for personal/sensitive content using the generalization rules below.
If no personal/sensitive content is found, show the user a clean review:
- For files under 200 lines: print the content directly to the terminal so the user can review inline.
- For files 200 lines or more: open the file in the user's editor (
$EDITOR, defaultless) so they can review comfortably:${EDITOR:-less} "$filepath"
After showing, confirm: "No personal/sensitive content found. Proceed with publishing as-is?"
If personal content is found, present each finding to the user and ask which to generalize.
Step 1b — Detect companion files
List all files in the skill directory beyond SKILL.md. For each extra file (e.g., LESSONS_LEARNED.md, CHANGELOG.md, notes.md, helper scripts):
- Check if
SKILL.mdreferences the file (grep for the filename in SKILL.md) - Classify the file:
- Referenced by SKILL.md — required for the skill to work, include by default
- Not referenced — companion/documentation file, not needed by the skill
For any non-referenced files, prompt the user with a list:
> The following files are not referenced by SKILL.md and are not required for the skill: > - LESSONS_LEARNED.md (19 KB) > - notes.md (3 KB) > > Include these in the public toolkit? (Select which to include, or skip all)
Files the user excludes should be:
- Kept in their current location if this is a fork
- Moved to
$SKILLS_DIR-local//if this is a promote (since the original directory will become a symlink)
Step 2 — Create generalized copy in toolkit
mkdir -p $TOOLKIT_SKILLS/
# Copy only the files selected for publishing (always includes SKILL.md)
cp $SKILLS_DIR//SKILL.md $TOOLKIT_SKILLS//
# Copy any additional files the user approved
# cp $SKILLS_DIR// $TOOLKIT_SKILLS//
Apply the user-approved generalizations to the public copy. Do NOT modify the private version.
Step 3 — Replace local skill with symlink
If any companion files were excluded from publishing in Step 1b, move them to $SKILLS_DIR-local// before replacing the directory with a symlink:
# Move excluded companion files to local-only storage
mkdir -p $SKILLS_DIR-local/
mv $SKILLS_DIR// $SKILLS_DIR-local//
Then create the symlink:
# Verify the copy is readable
test -f $TOOLKIT_SKILLS//SKILL.md || { echo "ERROR: toolkit copy failed"; exit 1; }
# Safe removal and symlink — use absolute path for symlink target
TOOLKIT_SKILLS_ABS=$(cd $TOOLKIT_SKILLS && pwd)
rm -rf $SKILLS_DIR/
ln -s "$TOOLKIT_SKILLS_ABS/" $SKILLS_DIR/
# Verify the symlink works
test -f $SKILLS_DIR//SKILL.md || { echo "ERROR: symlink broken"; exit 1; }
If companion files were moved, inform the user: > Local-only files preserved at $SKILLS_DIR-local//: > - LESSONS_LEARNED.md
Step 4 — Update toolkit README
Add an entry for the new skill under the Skills section in $TOOLKIT_DIR/README.md. Follow the existing format: heading, description bullets, prerequisites, install command, usage examples.
Step 5 — Commit and push toolkit
cd $TOOLKIT_DIR
git add skills// README.md
git commit -m "Add skill"
Ask the user before pushing: "Push to GitHub now?"
Step 6 — Verify
Run the status check to confirm the skill shows as SYMLINKED. Verify $SKILLS_DIR//SKILL.md is readable through the symlink.
Workflow: Fork
Creates a public version while keeping the private version intact. Use when the private version has content that can't be fully generalized.
Steps
Step 1 — Determine public name
Use --public-name if provided, otherwise ask user. Default: same name. If same name conflicts with an existing toolkit skill, suggest alternatives.
Step 2 — Analyze for personal content (same as promote Step 1 — scan ALL files, present clean review or findings)
Step 2b — Detect companion files (same as promote Step 1b — prompt user which non-referenced files to include)
Step 3 — Create public copy
mkdir -p $TOOLKIT_SKILLS/
# Copy only the files selected for publishing (always includes SKILL.md)
cp $SKILLS_DIR//SKILL.md $TOOLKIT_SKILLS//
# Copy any additional files the user approved
Step 4 — Generalize the public copy
Apply user-approved generalizations. Update the name: field in frontmatter to `` if it differs.
Step 5 — Do NOT create a symlink. Both versions remain independent.
Step 6 — Update toolkit README (same as promote step 4)
Step 7 — Commit and push toolkit (same as promote step 5, ask before push)
Step 8 — Inform user: "Private version at $SKILLS_DIR/ is unchanged. Public version at $TOOLKIT_SKILLS/. These are independent — changes to one don't affect the other."
Workflow: Adopt
Installs a public skill and makes it a private tracked skill.
Steps
Step 1 — Get the skill
If the argument is a skill name that exists in the toolkit:
cp -r $TOOLKIT_SKILLS/ $SKILLS_DIR/
If the argument is a URL, use the install-skill mechanism if available, or manually download and extract.
Step 2 — Inform user they can now customize the local copy freely.
Workflow: Diff
For forked skills (where both private and public versions exist), show the difference.
diff -u $TOOLKIT_SKILLS//SKILL.md $SKILLS_DIR//SKILL.md
If names differ between private and public, check all public skill SKILL.md frontmatter name: fields to find the match. If no public version exists, report that.
Generalization Rules (used by promote and fork)
When analyzing a skill for personal content, scan ALL files in the skill directory (SKILL.md, .sh, .py, configs, etc.) for:
- Hardcoded paths:
/home/username/, specific project paths — replace with~/or$HOME/or make configurable - Internal hostnames:
*.example.com, org-specific gateway names — remove or make generic - Personal identifiers: usernames, email addresses like
user@example.com— remove - Org-specific tools: Internal Jira projects, Confluence spaces, internal tool references — remove
- Personal workflow assumptions: References specific to your personal life or setup — generalize
Present each finding as: > Found personal reference on line N: `` > Suggestion: [remove / replace with X / keep as-is]
Let the user approve each change before applying.
Important Rules
- NEVER auto-push to GitHub without user confirmation
- NEVER delete the private version during a fork operation
- ALWAYS verify the symlink works after promote (check that
$SKILLS_DIR//SKILL.mdis readable) - ALWAYS update the toolkit README when adding a public skill
- ALWAYS check for name conflicts before promote/fork
- If generalization would make the skill useless (too much personal content), recommend fork over promote
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: pengguanya
- Source: pengguanya/claude-toolkit
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.