Skip to content
Back to skills

Packages

ASecurity

Search, suggest, add, and browse third-party audio packages. Handles "suggest packages", "add a package", "what packages are available", "search for pitch detection", and package browsing.

  • 22 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 11, 2026
developmentpythongoc++bashgitbackend

Works with

  • cli

Security analysis

A100/100

Scanned June 11, 2026

npx -y skills add danielraffel/pulp --skill packages --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Packages?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Packages
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/danielraffel-packages/badge)](https://www.skillsdirectory.com/skills/danielraffel-packages)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: packages
description: Search, suggest, add, and browse third-party audio packages. Handles "suggest packages", "add a package", "what packages are available", "search for pitch detection", and package browsing.
requires:
  scripts:
    - tools/packages/registry.json
    - tools/packages/validate_registry.py
---

# Package Manager Skill

Help users discover, evaluate, and add third-party audio libraries to their Pulp projects.

## When to Use

- User asks about available packages or libraries
- User needs a capability not in Pulp's built-in signal subsystem
- User wants to add a third-party library
- User asks about pitch detection, ML inference, resampling, etc.
- User says "suggest packages", "find a library for X", "what's available for Y"

## Package Discovery

Search the registry for packages matching a need:

```bash
./build/pulp search "<query>"
./build/pulp suggest --description "<what the user needs>"
```

Or read the registry directly for full details:

```bash
cat tools/packages/registry.json | python3 -m json.tool
```

## Package Categories

| Category | Packages | What They Provide |
|----------|----------|-------------------|
| dsp | signalsmith-stretch, signalsmith-dsp, cycfi-q, pffft, daisysp | Pitch/time stretch, filters, FFT, pitch detection, physical modeling |
| audio-io | dr-libs, libsamplerate, r8brain-free-src | File decoding, sample rate conversion |
| ml | rtneural | Real-time neural network inference |
| ui | fontaudio | Audio icon font |

## Adding a Package

```bash
./build/pulp add <package-id>
```

This will:
1. Check license compatibility (reject GPL/LGPL)
2. Check platform support against project targets
3. Warn about overlaps with Pulp built-ins
4. Generate `cmake/pulp-packages.cmake` with FetchContent declarations
5. Update `packages.lock.json`, `DEPENDENCIES.md`, `NOTICE.md`
6. Print usage instructions (target_link_libraries + #include)

## Overlap Awareness

Before suggesting a package, check if Pulp's built-in `core/signal/` already covers the need:

- **Filters**: biquad, SVF, TPT, Linkwitz-Riley, ladder, FIR — built-in
- **FFT/STFT**: built-in (use PFFFT only if benchmarks show it's needed)
- **Delay**: built-in
- **Reverb, compressor, oscillator, ADSR**: built-in
- **Pitch detection**: NOT built-in → suggest cycfi-q
- **Pitch/time stretching**: NOT built-in → suggest signalsmith-stretch
- **Neural network inference**: NOT built-in → suggest rtneural
- **Sample rate conversion**: NOT built-in → suggest libsamplerate or r8brain-free-src
- **Physical modeling**: NOT built-in → suggest daisysp

## Browsing Guides

Each package has a detailed integration guide:

```
docs/guides/packages/index.md          — category overview
docs/guides/packages/<package-id>.md   — per-package guide
```

Read these to answer questions about specific packages.

## License Policy

Only MIT/BSD/Apache/ISC/zlib/BSL/public-domain packages are allowed. The registry enforces this. If a user asks about a GPL library, explain the incompatibility and suggest the MIT-licensed alternative from the registry.

## Attribution Audit (2026-04-22)

`tools/deps/audit.py` now runs **two** invariants under `--strict`:

1. **Consistency** — every `manifest.json` entry must appear in
   `DEPENDENCIES.md`, `NOTICE.md`, and `docs/reference/licensing.md`.
2. **Completeness** — every dep declared in a real manifest source
   (`requirements-docs.txt`, `mkdocs.yml`, root + `bindings/python`
   `FetchContent_Declare`, `external/<dir>/`) must be represented in
   `manifest.json` via name or `external_names` alias.

The completeness check closes the #582 class of miss where MkDocs
Material landed with zero attribution coverage because the audit only
verified cross-file consistency, not that declared deps were present.

When adding a dep, always touch all four attribution files (manifest,
DEPENDENCIES, NOTICE, licensing) plus — if the CMake / pip / vendored
alias differs from the canonical name — add the alias to
`DEFAULT_ALIASES` in `tools/deps/audit.py` or the `external_names`
list on the manifest entry.

## Bundled Toolchain Pins

Some prebuilt toolchains carry bundled third-party components that are not
separate source directories in `external/`. For example, the Skia prebuilt
toolchain used by visual tests bundles Dawn, HarfBuzz, and ICU through Skia's
`DEPS` file. Track those exact nested revisions in the parent manifest entry
with a structured field such as `determinism.bundled_pins`, and mirror the
human-readable version in `DEPENDENCIES.md`, `external/<toolchain>/VERSION.md`,
and any relevant reference doc.

Do not add a separate manifest entry for a nested toolchain component unless
Pulp fetches, vendors, or redistributes it independently. Otherwise the audit
will require standalone NOTICE/licensing rows for something whose license and
distribution boundary are already covered by the parent prebuilt.

The Skia toolchain itself is pinned at `chrome/m149` via the
`danielraffel/skia-builder` fork (see `tools/deps/manifest.json` →
`determinism.skia_builder_fork`). The fork tracks upstream
`olilarkin/skia-builder`'s tag pattern and additionally publishes iOS
device, iOS simulator, visionOS device, visionOS simulator, mac-x86_64,
and `Skia.xcframework` slices upstream does not. While upstream stays on
m144, this fork is the active dependency; revisit when upstream catches up.

iOS-specific layout gotcha (PR #3011): unlike the mac / linux / windows
slices, the iOS zips ship libs under a per-arch subdir
(`build/ios-gpu/lib/Release/{device-arm64,simulator-arm64,simulator-x86_64}/libskia.a`)
because the device and fat-simulator zips would otherwise collide on
identical lib names when unpacked into one tree. `FindSkia.cmake` picks
the right subdir based on `CMAKE_OSX_SYSROOT` + `CMAKE_OSX_ARCHITECTURES`;
`tools/scripts/fetch_skia_for_release.py` keeps the subdir intact for
`ios-device-arm64` and `ios-simulator-arm64-x86_64` matrix slices via
`_IOS_PRESERVE_ARCH_SUBDIR`. Do not extend the flatten step to iOS, and
do not register a single combined iOS slice without per-arch handling.

Multi-arch simulator builds (`-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64`,
the default in `tools/cmake/ios.toolchain.cmake` with
`ONLY_ACTIVE_ARCH=NO`) are intentionally rejected by `FindSkia.cmake`
because each Skia archive is single-arch — silently picking
`simulator-arm64` would arch-mismatch the x86_64 link. The fix is
either to build a single arch (`-DCMAKE_OSX_ARCHITECTURES=arm64`
with `ONLY_ACTIVE_ARCH=YES`) or to pre-fatten the two simulator
archives with `lipo` into a combined `simulator/libskia.a` upstream
of `find_package(Skia)`. The default Pulp iOS smoke (`pulp-ios-sim`,
Apple Silicon dev machines) only needs `arm64`.

The **V8** toolchain follows the same prebuilt-pin pattern (added 2026-06).
It is the optional JS engine backend (`PULP_JS_ENGINE=v8`), a sealed
embeddable `libv8` pinned at tag `v8-15.1.27` via the
`danielraffel/v8-builder` fork (`tools/deps/manifest.json` → V8 entry,
`determinism.release_assets` per-platform URL + sha256). Fetched by
`tools/scripts/fetch_v8_for_release.py` into `external/v8-build/<platform>/`
and resolved by `tools/cmake/FindV8.cmake`. Like Skia, it **bundles**
third-party components internally — ICU, zlib, and Abseil — so it gets one
manifest row for V8 (BSD-3-Clause) plus the bundled-component NOTICE
attribution (ICU/zlib/Abseil), NOT separate manifest rows for the nested
libs (their distribution boundary is the parent `libv8`). Re-verify the
NOTICE list against the v8-builder artifact's own third-party manifest when
the V8 pin bumps. iOS ships a headers-only slice (`library: false`) — V8
needs JIT, forbidden on iOS, so iOS stays JSC. Full rollout/governance:
`planning/2026-06-06-v8-sealed-libv8-provider-migration-plan.md`.

## Bundled Fonts (and similar opt-in compile-time assets)

Bundled fonts under `external/fonts/*.ttf` (`Inter`, `JetBrains Mono`,
`Noto Color Emoji`) are first-class manifest entries with `category: fonts`
and a SHA-256 in the `notes` field. They are NOT the same as the
"bundled-toolchain" pattern above — each font is fetched / vendored
independently and Pulp redistributes it directly.

Add a new bundled font the same way as any other dep:

1. Vendor the file under `external/fonts/<Name>.ttf` (use `git add -f`
   if `.gitignore` covers `/external/*/`).
2. Add a row in `external/fonts/README.md` with the SHA-256, source URL,
   and any gating notes (e.g. `Noto Color Emoji` is gated by
   `PULP_BUNDLE_NOTO_COLOR_EMOJI` and ships in its own
   `pulp_add_binary_data` static lib so macOS/Windows release builds
   can drop the payload).
3. Insert alphabetically into `DEPENDENCIES.md`, `NOTICE.md`, and
   `tools/deps/manifest.json`.
4. Wire CMake: add a `pulp_add_binary_data(...)` block in
   `core/canvas/CMakeLists.txt`, register the resulting target in
   `PULP_SDK_TARGETS` (parent `CMakeLists.txt`), and add the
   accompanying C++ TU that calls
   `pulp::canvas::register_font(...)` or
   `pulp::canvas::register_emoji_fallback(...)` at startup.

Gate large bundles (≥ 1 MB) behind a CMake option that defaults `OFF`
where the platform provides a usable equivalent (e.g. emoji typefaces
on macOS / Windows) and `ON` for headless / CI / Linux / Android.

Synthetic missing-dep test: `tools/deps/test_audit.py::
ManifestSourceScannerTests::test_uncovered_detection_catches_missing_pip_dep`
— don't delete it. If the completeness gate regresses, this is the
regression test that catches it.

## Importer tool-registry fields (pulp import)

`tools/packages/tool-registry.json` `ToolDescriptor` carries optional importer
fields — `frameworks[]`, `spi_min`/`spi_max`, `sdk_min`/`sdk_max`,
`capabilities[]`, `health_check` — for `category: "importer"` tools (the
framework→Pulp project importers resolved by `pulp import`). They're parsed by
`tools/cli/tool_registry.cpp` and ignored for non-importer tools. The importers
themselves install via the tool lane (`pulp tool install <importer>`), never as
project `packages.lock.json` dependencies.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.