ClawdHub Publish Helper
by @cdmichaelb
Prepare and publish an OpenClaw skill to ClawHub. Handles PII/secret auditing, generalization, env var extraction, directory scaffolding, git init, and the c...
clawhub install clawdhub-publish-helperπ About This Skill
name: publish-skill version: 1.0.1 description: Prepare and publish an OpenClaw skill to ClawHub. Handles PII/secret auditing, generalization, env var extraction, directory scaffolding, git init, and the clawhub publish command. Use when publishing a new skill or updating an existing one on ClawHub.
Publish Skill
Prepare and publish an OpenClaw skill to ClawHub. This skill codifies the audit β generalize β publish workflow.
When To Use
npx clawhub@latest install)Workflow
Step 1: Audit the Live Skill
Before creating any copy, audit the source skill for secrets and PII:
1. Read every file in the skill directory recursively 2. Check for these categories of sensitive content:
| Category | Examples | Action |
|----------|----------|--------|
| Secrets | API keys, tokens, passwords, private keys | Must remove |
| Paths | Absolute paths (/home/username/..., /Users/...) | Replace with env var or ~ relative |
| Discord IDs | Channel IDs, user IDs, guild IDs, message IDs | Remove or replace with env var |
| Timezones | Hardcoded IANA timezone strings | Replace with env var |
| Personal data | Real names, emails, phone numbers, medication names | Remove or generalize |
| Network info | IP addresses, internal URLs, port numbers | Remove or replace with placeholders |
| Custom identifiers | User-specific labels, internal project names | Generalize |
3. Report findings to the user before proceeding β do not silently modify
Step 2: Create Publishable Copy
Create a separate directory (never modify the live skill):
$CLAWHUB_DEFAULT_DIR/-skill/
Default base: ~/projects/skills (override via CLAWHUB_DEFAULT_DIR env var).
Directory structure:
-skill/
βββ SKILL.md # Manifest (generalized)
βββ README.md # User-facing docs
βββ .gitignore # Standard ignores
βββ scripts/ # Script files (generalized)
βββ references/ # Optional reference docs
βββ ... # Any other skill-specific files
Step 3: Generalize Content
For each file in the skill:
SKILL.md frontmatter:
env: block declaring all extracted env vars with descriptions and required/optionaldescriptionScripts (Python, Shell, etc.):
os.environ.get("VAR", fallback) / env var readsnow()/utc_now() fallbacks that bypass source timestamps β raise errors insteadDocumentation (Markdown):
Shell wrappers:
SCRIPT="$(cd "$(dirname "$0")" && pwd)/tracker.py"Step 4: Verify Clean State
Run a final grep across all files:
grep -rn "hardcoded_pattern1\|hardcoded_pattern2\|..." --include="*.py" --include="*.md" --include="*.sh" .
Verify:
Step 5: Git Init and Commit
git init
git add -A
git commit -m "Initial publishable copy β no PII, no secrets"
Step 6: Publish (with user confirmation)
Always confirm with the user before publishing.
npx clawhub@latest publish --slug --version --name "" /absolute/path/to/skill-dir
Gotchas:
. β cwd may not propagate through exec/shell layers--slug is required β without it, the CLI picks up the directory namepublish-skill, skill-publisher, etc.) is likely taken. Pick something unique or namespaced (e.g. myname-publish-helper)Common version bumps:
1.0.01.0.0 β 1.0.1)1.0.0 β 1.1.0)After publishing, report the slug, version, and install command to the user.
Common Patterns
Extracting env vars from hardcoded values
Before:
TIMEZONE = ZoneInfo("America/Los_Angeles")
WORKSPACE = "/home/user/.openclaw/workspace"
After:
TZ_STR = os.environ.get("MEDICATION_TIMEZONE", "UTC")
TIMEZONE = ZoneInfo(TZ_STR)
WORKSPACE = os.environ.get("WORKSPACE", os.path.expanduser("~/.openclaw/workspace"))
Replacing personal config with user-editable sections
Before:
MORNING_MEDS = ["RealMedA", "RealMedB"]
KNOWN_MEDS = ["RealMedA", "RealMedB", "RealMedC"]
After:
# Edit these lists to match your regimen
MORNING_MEDS: list[str] = [] # e.g. ["MedA", "MedB"]
KNOWN_MEDS: list[str] = [] # e.g. ["MedA", "MedB", "MedC"]
Removing timestamp fallbacks
Before:
dt_utc = datetime.fromisoformat(ts) if ts else datetime.now(timezone.utc)
After:
if not ts:
raise ValueError("timestamp_utc is required β source message timestamp must be provided")
dt_utc = datetime.fromisoformat(ts.replace("Z", "+00:00"))
Changelog
Add --changelog to the publish command for release notes. Example:
npx clawhub@latest publish --slug my-skill --version 1.1.0 --changelog "Added env var support, fixed timestamp handling" .
ClawHub CLI Reference
| Command | Purpose |
|---------|---------|
| npx clawhub@latest login | Authenticate (browser callback) |
| npx clawhub@latest whoami | Verify auth |
| npx clawhub@latest publish --slug X --version Y . | Publish from current dir |
| npx clawhub@latest inspect | View published metadata |
| npx clawhub@latest search | Search registry |
Publish must run from inside the skill directory (requires SKILL.md in cwd).
Required Files
SKILL.md β this filereferences/checklist.md β quick audit checklistNotes
env: frontmatter β that's a registry display issue, not a skill issueβ‘ When to Use
π Tips & Best Practices
env: frontmatter β that's a registry display issue, not a skill issue