AgentStack
SKILL verified MIT Self-run

Publish Skill

skill-pengguanya-claude-toolkit-publish-skill · by pengguanya

Promote, fork, or adopt skills between private and public repos

No reviews yet
0 installs
5 views
0.0% view→install

Install

$ agentstack add skill-pengguanya-claude-toolkit-publish-skill

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Publish Skill? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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:

  1. Tell the user: "This is your first time running publish-skill. I need to know where your toolkit repo and skills directory are."
  2. Ask for SKILLS_DIR — "Where are your Claude Code skills stored?" (default: ~/.claude/skills)
  3. Ask for TOOLKIT_DIR — "Where is your public toolkit git repo?" (no default — user must provide this)
  4. Set TOOLKIT_SKILLS to $TOOLKIT_DIR/skills and confirm with user
  5. Write the config to config.json next to this SKILL.md
  6. 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)

  1. Skill exists at $SKILLS_DIR// and is a directory (not a symlink)
  2. $TOOLKIT_DIR/ exists and is a git repo
  3. 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, default less) 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):

  1. Check if SKILL.md references the file (grep for the filename in SKILL.md)
  2. 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:

  1. Hardcoded paths: /home/username/, specific project paths — replace with ~/ or $HOME/ or make configurable
  2. Internal hostnames: *.example.com, org-specific gateway names — remove or make generic
  3. Personal identifiers: usernames, email addresses like user@example.com — remove
  4. Org-specific tools: Internal Jira projects, Confluence spaces, internal tool references — remove
  5. 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.md is 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.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.