Skip to content

Package skills as standalone downloadable zips via CI - #21

Merged
jstjoe merged 2 commits into
mainfrom
claude/skyflow-skills-packaging-oibchp
Jul 2, 2026
Merged

Package skills as standalone downloadable zips via CI#21
jstjoe merged 2 commits into
mainfrom
claude/skyflow-skills-packaging-oibchp

Conversation

@jstjoe

@jstjoe jstjoe commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Publishes each Skyflow skill as an individual, portable .zip via GitHub Releases — in addition to the existing plugin/marketplace install. This makes skills easy to download directly from GitHub and drop into another project or any Agent Skills–compatible harness.

The skill directories under skyflow-skills-plugin/skills/ remain the single source of truth. The zips are pure build artifacts: they are not committed (dist/ is gitignored) and nothing in the plugin/marketplace tree changes, so vanilla Claude Code plugin users are completely unaffected.

Why zip (not .skill)

There is no official .skill container in the Agent Skills spec — a skill is a directory with SKILL.md plus resources, and the portable unit understood by Claude Code, claude.ai, and the Agent SDK is a zip of that directory. A custom extension only adds friction, so these ship as plain .zip files that unzip to <skill-name>/SKILL.md.

What's included

  • .github/scripts/validate-skills.py — validates every SKILL.md frontmatter: name matches its directory, is lowercase-hyphen and ≤64 chars; description present and ≤1024 chars.
  • .github/scripts/package-skills.sh — zips each skill (extracting to <skill>/SKILL.md, excluding repo-only cruft like CONTRIBUTING.md/.DS_Store) and emits SHA256SUMS.txt.
  • .github/workflows/validate-skills.yml — PR check: validates skills on any PR that touches them.
  • .github/workflows/package-skills.yml — on a pushed v* tag or manual dispatch: validates, packages, and attaches the zips + checksums to the matching GitHub Release. Defaults the tag to v<plugin.json version> for manual runs.
  • README — new Standalone Skill Downloads section with curl/unzip install steps and the releases/latest/download/... stable URLs.
  • CONTRIBUTING — packaging/release process and local build commands.

Testing

Both scripts were run locally against the current 6 skills:

  • validate-skills.py → all 6 skills valid.
  • package-skills.sh → produced create-vault.zip, call-rest-apis.zip, etc. + SHA256SUMS.txt; verified each archive extracts to <skill>/SKILL.md and that excluded files (e.g. call-rest-apis/CONTRIBUTING.md) are absent.

Release flow

Bump version in skyflow-skills-plugin/.claude-plugin/plugin.json, then git tag vX.Y.Z && git push origin vX.Y.Z — CI builds and publishes the release. (Or run the Package skills workflow manually from the Actions tab.)

🤖 Generated with Claude Code

https://claude.ai/code/session_01XxeXNVRY2tk864Dm65HM9R


Generated by Claude Code

Publish each Skyflow skill as a portable .zip via GitHub Releases, in
addition to the existing plugin/marketplace install. Skill directories
remain the single source of truth; zips are build artifacts and are not
committed, so the plugin install is unaffected.

- validate-skills.py / validate-skills.yml: PR check that every SKILL.md
  has valid frontmatter (name matches dir, lowercase-hyphen, <=64 chars;
  description present, <=1024 chars).
- package-skills.sh / package-skills.yml: on a v* tag or manual dispatch,
  zip each skill (extracts to <skill>/SKILL.md), emit SHA256SUMS.txt, and
  attach to the matching GitHub Release.
- README: Standalone Skill Downloads section with install steps.
- CONTRIBUTING: packaging/release process and local build commands.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XxeXNVRY2tk864Dm65HM9R
@jstjoe

jstjoe commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Hey @claude (in GitHub Actions) could you do a code review?

@jstjoe jstjoe left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Reviewed the diff (scripts + workflows + docs). Overall it's solid and does what it says: skills stay the single source of truth, zips are build-only artifacts published to Releases, and nothing in the plugin/marketplace tree changes so existing /plugin install users are unaffected. Both scripts were run locally against all 6 skills (validate passes; archives extract to <skill>/SKILL.md with CONTRIBUTING.md/.DS_Store excluded).

A few notes, none blocking:

1. Frontmatter parser only handles single-line description (low severity, latent).
.github/scripts/validate-skills.py parses key: value line-by-line. All 6 current skills use single-line name/description, so it's correct today — but a future skill using a YAML block scalar (description: > / | with the text on following indented lines) would parse description as just > and pass validation with an effectively empty description. If we expect multi-line descriptions later, switch to yaml.safe_load on the fenced block (PyYAML is present on ubuntu-latest). Fine to defer until a skill actually needs it.

2. workflow_dispatch with the default tag will create a new git tag.
In package-skills.yml, a manual run falls back to v<plugin.json version>. If that tag doesn't exist yet, gh release create creates it at the checked-out commit (default branch). That's reasonable behavior, just worth being aware of — running dispatch without bumping plugin.json first could tag a version that's already released. The gh release view guard handles the "already exists" case by clobbering assets, so it won't error.

3. Backtick escaping in --notes is correct.
Flagging because it looks risky: the \.zip`sequences inside the double-quoted--notes` are properly escaped, so bash treats them as literal backticks (no command substitution). Verified.

Optional enhancement: an all-in-one skyflow-skills-all.zip bundle for users who want every skill at once — deliberately left out per the packaging decision (per-skill only), easy to add later.

Recommendation: 👍 mergeable as-is. Item 1 is the only thing I'd consider addressing, and only if multi-line descriptions are on the roadmap.


Generated by Claude Code

Parse the SKILL.md frontmatter block with yaml.safe_load instead of a
line-by-line key:value scan, so multi-line values (folded/literal block
scalars, quoted strings spanning lines) are handled correctly. The old
parser would reduce a `description: >` block scalar to just ">" and pass
validation with an effectively empty description.

- validate-skills.py: extract the --- fenced block and yaml.safe_load it;
  type-check name/description are non-empty strings.
- validate-skills.yml / package-skills.yml: pip install pyyaml before
  running the validator (setup-python provides a clean interpreter).

Addresses review feedback on PR #21.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XxeXNVRY2tk864Dm65HM9R
@jstjoe
jstjoe merged commit 7d7b8a2 into main Jul 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants