npx-skills
npx-skills is a uv-installable Python wrapper around the upstream
skills CLI.
This allows you to use skills.sh from within Python projects without a global dependency on Node/npm and impose versioning constraints on npx skills on a project-by-project basis.
It does this by shipping a vendored Node runtime and the published JavaScript CLI payload, then forwards execution to the embedded runtime so users do not need a separate Node install.
Install
uv add npx-skills
skills -h
OR use with uvx
uvx npx-skills
Versioning
The npx-skills package version tracks the upstream skills npm module
version one-to-one. Installing npx-skills==1.4.8 gives you exactly
skills@1.4.8 — the CLI payload is baked into the wheel at build time, so
pinning npx-skills in your pyproject.toml or lockfile pins the underlying
JavaScript CLI too. A new upstream skills release on npm has no effect on an
already-installed npx-skills; you only move when you explicitly bump
npx-skills. Packaging-only republishes of an existing upstream version use
PEP 440 post-releases (e.g. 1.4.8.post1).
How it works
Refresh Vendored Artifacts
The repository includes a vendoring script that copies:
- the published
skillspackage payload (package.json,bin/,dist/,README.md,ThirdPartyNoticeText.txt) - the package's runtime
node_modulesdependencies - the current platform's
nodebinary
By default it will use a built package root if you pass --source, or fall
back to the newest cached ~/.npm/_npx/*/node_modules/skills install.
uv run python scripts/vendor_upstream.py
Or point it at a specific built package root:
uv run python scripts/vendor_upstream.py --source /path/to/node_modules/skills
If you point --source at the upstream git repo, it must already contain
dist/cli.mjs.
To rebuild only the embedded Node runtime from the payload already committed in
this repo, point --source at the vendored package root:
uv run python scripts/vendor_upstream.py --source src/npx_skills/vendor/skills
Build
The wheel is intentionally platform-specific because it includes a native node
binary.
uv build
Release Automation
GitHub Actions builds one wheel per native runner target:
- Linux
x64viamanylinux_2_28 - Linux
arm64viamanylinux_2_28 - macOS
x64 - macOS
arm64 - Windows
x64 - Windows
arm64
The workflow lives at .github/workflows/wheels.yml.
It reuses the committed skills payload, re-vendors the Node runtime for the
current runner architecture, runs the test suite, builds wheels with uv
(cibuildwheel via uvx on Linux), smoke-tests the built wheel, and uploads
wheel artifacts for manual release use.
This project intentionally publishes wheels only. An sdist would not be portable without re-vendoring the embedded Node runtime for the target platform.
Publishing runs through a separate manual workflow at
.github/workflows/publish.yml. It invokes the
wheel builder in the same workflow run, then publishes from GitHub after all
target wheels succeed. The intended entrypoint is the npx-skills-dev helper:
uv run --package npx-skills-dev npx-skills-dev publish-to-pypi
Or via make:
make publish
Use --ref <branch> to dispatch the workflow from a specific branch and
--dry-run to build and validate without publishing.
The GitHub publish job authenticates to PyPI using a project API token stored
as the PYPI_API_TOKEN repository secret and consumed via UV_PUBLISH_TOKEN.
The job runs in the pypi GitHub Actions environment, which can optionally be
gated with required reviewers.
Upstream Sync Automation
A scheduled workflow at
.github/workflows/auto-sync-upstream.yml
runs daily (06:17 UTC) and keeps the vendored payload in lock-step with the
upstream skills npm release. It is the mechanism that preserves the
one-to-one version mapping described in the Versioning section
above.
The job is implemented by the npx-skills-dev auto-sync-upstream command
(packages/npx-skills-dev/src/npx_skills_dev/commands/auto_sync_upstream.py)
and performs the following steps:
- Reads the currently vendored version from
src/npx_skills/vendor/manifest.json(upstream.version). - Fetches
skills@latestfrom the npm registry. - If the versions match (and
--forcewas not passed) the job exits as a no-op. - Otherwise it
npm installsskills@<latest>into a temporary directory and runsscripts/vendor_upstream.py --source ...against it to refresh the vendored payload. - Rewrites the version in
pyproject.tomlandsrc/npx_skills/__init__.pyto match the new upstream version. - Runs the unit test suite.
- Commits
src/npx_skills/vendor,src/npx_skills/__init__.py, andpyproject.tomlwith the messageAuto-sync upstream skills@<version>and pushes tomaster. - Dispatches
publish.ymlagainstmaster, which builds wheels for every target platform and publishes them to PyPI.
The workflow can also be triggered manually via workflow_dispatch, with an
optional force input that re-runs the full flow even when the upstream
version is unchanged.
Layout
The vendored runtime is kept under src/npx_skills/vendor/:
vendor/
manifest.json
node/<platform>/node
skills/
package.json
bin/cli.mjs
dist/
node_modules/
Release files for npx-skills 1.5.20
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| npx_skills-1.5.20-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details |
| npx_skills-1.5.20-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| npx_skills-1.5.20-py3-none-manylinux_2_28_x86_64.whl | Python 3 | none | Linux glibc 2.28+ x86-64 | Details |
| npx_skills-1.5.20-py3-none-manylinux_2_28_aarch64.whl | Python 3 | none | Linux glibc 2.28+ ARM64 | Details |
| npx_skills-1.5.20-py3-none-macosx_10_13_universal2.whl | Python 3 | none | macOS 10.13+ universal2 (ARM64, x86-64) | Details |
Total release size: 193.1 MB
Release files / npx_skills-1.5.20-py3-none-win_arm64.whl
| Download URL | npx_skills-1.5.20-py3-none-win_arm64.whl |
|---|---|
| Size | 30.2 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
acd42489a162da16beac511c3710236868c3777bb51961eb9f076791560a9abf
|
|
BLAKE2b-256 checksum How to use checksums |
d4503bb6b75850907a1e42eb756df4cb556b4380a24fc8c7dcf120735ea8d40c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / npx_skills-1.5.20-py3-none-win_amd64.whl
| Download URL | npx_skills-1.5.20-py3-none-win_amd64.whl |
|---|---|
| Size | 33.7 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
f2234e9dca76d72c02641eccec281788933f6fc147d932df3b5088461e8cebbb
|
|
BLAKE2b-256 checksum How to use checksums |
d0c9f5f53c845cedc6d0514c946cd2652b30bbe669c429b6bb04f30c72518c2f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / npx_skills-1.5.20-py3-none-manylinux_2_28_x86_64.whl
| Download URL | npx_skills-1.5.20-py3-none-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 45.5 MB |
| Tags | Linux glibc 2.28+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
9e2b9a8217854783d7bdb0f666a66d351e248ef5aa46628f08a79b83df3f8dd8
|
|
BLAKE2b-256 checksum How to use checksums |
2380f5fc8a81722e4083d40ac595e2e937321d390c787e209ee150ae0b810877
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / npx_skills-1.5.20-py3-none-manylinux_2_28_aarch64.whl
| Download URL | npx_skills-1.5.20-py3-none-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 44.7 MB |
| Tags | Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
24ad32dffcae8e4eecc7c75ce875e2151d4e0213c3002e14e3afe0e00f366e72
|
|
BLAKE2b-256 checksum How to use checksums |
2fc11792cf71593733805ba582ad90b9291da49e9447f7bcdc1baf38ebd0068c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / npx_skills-1.5.20-py3-none-macosx_10_13_universal2.whl
| Download URL | npx_skills-1.5.20-py3-none-macosx_10_13_universal2.whl |
|---|---|
| Size | 39.1 MB |
| Tags | Python 3 macOS 10.13+ universal2 (ARM64, x86-64) |
|
SHA-256 checksum How to use checksums |
b50dd31916f9a4389d05ec43cbed583110fe3884e9c9c2cb874242e0c5ccd0a9
|
|
BLAKE2b-256 checksum How to use checksums |
ea17d335ae09dd122c84c4fe09ad1c12cb2a3b4a5edad393a70eee0899eff000
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|